character_graph = ag.get_character(str(character_skel_root.GetPrimPath()) 一直是None的问题

硬件环境
A6000

软件版本
Isaac Sim 5.1

系统
Ubuntu 22.04

代码:

    
from isaacsim import SimulationApp
import time 
# simulation_app = SimulationApp({"headless": False})
simulation_app = SimulationApp({
    "headless": False
 
})

import numpy as np
from isaacsim.core.api import World
from isaacsim.storage.native import get_assets_root_path
from isaacsim.core.utils.extensions import enable_extension
import omni

ADDITIONAL_EXTENSIONS_PEOPLE = [
    "omni.isaac.core",
    "omni.anim.people",
    "omni.anim.navigation.bundle",
    "omni.anim.timeline",
    "omni.anim.graph.bundle",
    "omni.anim.graph.core",
    "omni.anim.graph.ui",
    "omni.anim.retarget.bundle",
    "omni.anim.retarget.core",
    "omni.anim.retarget.ui",
    "omni.kit.scripting",
    "isaacsim.replicator.agent.core"
]
for e in ADDITIONAL_EXTENSIONS_PEOPLE:
    enable_extension(e)
    simulation_app.update()

from isaacsim.core.utils import prims
from pxr import Sdf
try:
    import omni.anim.graph.core as ag
    print("成功导入 Animation Graph 核心库!")
except ImportError:
    print("扩展加载失败,请检查扩展名称是否正确。")

from isaacsim.replicator.agent.core.stage_util import CharacterUtil
from isaacsim.replicator.agent.core.settings import PrimPaths
print("成功导入 Replicator Agent (isaacsim 命名空间)!")
from omni.usd import get_stage_next_free_path
import carb

def find_skel_root(stage, root_path):
    prim = stage.GetPrimAtPath(root_path)
    if prim.GetTypeName() == "SkelRoot":
        return prim, root_path
    for child in prim.GetChildren():
        prim_child, path_child = find_skel_root(stage, root_path + "/" + child.GetName())
        if prim_child is not None:
            return prim_child, path_child
    return None, None

def transverse_prim(stage, stage_prefix):

        # Check if the prim is the one we are looking for
        prim = stage.GetPrimAtPath(stage_prefix)
        print("prim --- ",prim,prim.GetTypeName() )

        # If the prim is the one we are looking for, return it
        if prim.GetTypeName() == "SkelRoot":
            return prim, stage_prefix

        # Otherwise, get all the children of the prim and keep transversing until we find the SkelRoot
        children = prim.GetAllChildren()

        # If there are no children, return
        if not children or len(children) == 0:
            return None, None
        
        # Recursively look through the children to get the SkelRoot
        for child in children:
            prim_child, child_stage_prefix = transverse_prim(stage, stage_prefix + "/" + child.GetName())

            if prim_child is not None:
                return prim_child, child_stage_prefix
            
        return None, None
world_settings = {"physics_dt": 1.0 / 500.0, "stage_units_in_meters": 1.0, "rendering_dt": 1.0 / 60.0}
my_world = World(**world_settings)
root_path = get_assets_root_path()
character_root_prim_path = PrimPaths.characters_parent_path()
current_stage = my_world.stage



stage_prefix="person1"
agent_name="original_male_adult_construction_02"
assets_root_path  = "{}/Isaac/People/Characters".format(root_path)
stage_prefix = get_stage_next_free_path(current_stage, character_root_prim_path + '/' + stage_prefix, False)

agent_folder = "{}/{}".format(assets_root_path, agent_name)
result, properties = omni.client.stat(agent_folder)
character_folder = "{}/{}".format(assets_root_path, agent_name)
result, folder_list = omni.client.list(character_folder)
character_usd=""
for item in folder_list:
    if item.relative_path.endswith(".usd"):
        character_usd=item.relative_path
char_usd_file= "{}/{}".format(character_folder, character_usd)
character_name =stage_prefix.split("/")[-1]

init_yaw=0.0
init_pos=[0.0, 0.0, 0.0]
CharacterUtil.load_character_usd_to_stage(char_usd_file, init_pos, init_yaw, character_name)
character_skel_root, character_skel_root_stage_path=transverse_prim(current_stage, stage_prefix)
if character_skel_root is None:
    print(">>> 没有找到 SkelRoot,请确认 USD 文件内是否有骨架!")
else:
    print(">>> 找到 SkelRoot:",character_skel_root)
                                   
if not current_stage.GetPrimAtPath(character_root_prim_path + "/Biped_Setup"):
            prim = prims.create_prim(character_root_prim_path + "/Biped_Setup", "Xform", usd_path=assets_root_path + "/Biped_Setup.usd")
            prim.GetAttribute("visibility").Set("invisible")

animation_graph = current_stage.GetPrimAtPath(character_root_prim_path + "/Biped_Setup/CharacterAnimation/AnimationGraph")
animation_graph_path = Sdf.Path(animation_graph.GetPath())




import omni.kit.commands
from pxr import Sdf, Usd

def apply_anim_graph_safe(prim_path, graph_path):
    stage = my_world.stage
    
    # 1. 核心关键:显式获取 Root Layer 并设置为当前的编辑目标
    root_layer = stage.GetRootLayer()
    # 强制切换,防止被隐形的 UnitsAdjust 层干扰
    stage.SetEditTarget(Usd.EditTarget(root_layer))
    
    print(f">>> 正在尝试为 {prim_path} 应用动画图层...")
    
    # 2. 在 Root Layer 选中的情况下执行官方命令
    # 这样命令会把数据写在主层,而不是临时的单位转换层
    try:
        omni.kit.commands.execute(
            "ApplyAnimationGraphAPICommand",
            paths=[Sdf.Path(prim_path)],
            animation_graph_path=Sdf.Path(graph_path)
        )
        print(">>> [成功] 命令执行完成。")
    except Exception as e:
        print(f">>> [失败] 执行命令时出错: {e}")

# --- 调用逻辑 ---
# 先给系统时间处理资产加载和单位转换
# for _ in range(200):
#     simulation_app.update()

char_path = str(character_skel_root.GetPrimPath())
anim_graph_path = str(animation_graph.GetPath())

# 执行安全应用
apply_anim_graph_safe(char_path, anim_graph_path)

# 必须更新,让动画系统识别到新加入的 API


for _ in range(200):
    simulation_app.update()

# 再次验证 API 是否生效
prim = my_world.stage.GetPrimAtPath(char_path)
if prim.HasAPI("AnimationGraphAPI"):
    print(">>> 验证成功: AnimationGraphAPI 已激活")
else:
    print(">>> 验证失败: API 仍未挂载")





if prim.HasAPI("AnimationGraphAPI"):
    print(character_skel_root.GetPrimPath(),"  >>> SkelRoot 已经应用 AnimationGraphAPI")
else:
    print(">>> SkelRoot 尚未应用 AnimationGraphAPI")
prim = my_world.stage.GetPrimAtPath(character_skel_root.GetPrimPath())
print(f"DEBUG: Prim Path: {prim.GetPath()}, Type: {prim.GetTypeName()}")

# 如果 Type 不是 'SkelRoot',即使应用了 API,AnimGraph 也会拒绝执行
if character_skel_root.GetTypeName() != "SkelRoot":
    print("错误:该路径不是 SkelRoot 类型,动画图层无法生效!")

print("str(character_skel_root.GetPrimPath())   --",str(character_skel_root.GetPrimPath()))

my_world.reset()

while simulation_app.is_running():
 if  my_world.is_playing():
    my_world.step(render=True)
    character_graph = ag.get_character(str(character_skel_root.GetPrimPath()))
    if character_graph is None :
        #   print(" --- ", " 66666 ")
          pass
# omni.usd.get_context().save_as_stage("./caiji.usd", None)
simulation_app.close()

问题描述:

    代码在运行的时候character_graph = ag.get_character(str(character_skel_root.GetPrimPath()))  一直输出是None,但是输出显示已经将graph应用到了SklrRoot中了。请问这个是为什么?