硬件环境
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中了。请问这个是为什么?