486 lines
18 KiB
Python
486 lines
18 KiB
Python
import omni
|
||
from omni.isaac.core.robots import Robot
|
||
import omni.timeline
|
||
import carb
|
||
import asyncio
|
||
|
||
def print_robot_actions_info(robot_prim_path="/World/piper_description"):
|
||
"""打印机器人的所有动作和关节信息"""
|
||
print("\n========== 机器人动作和关节信息 ==========")
|
||
|
||
# 获取机器人对象
|
||
try:
|
||
robot = Robot(prim_path=robot_prim_path)
|
||
robot.initialize()
|
||
print(f"成功加载机器人: {robot_prim_path}")
|
||
except Exception as e:
|
||
print(f"无法加载机器人: {e}")
|
||
return
|
||
|
||
# 1. 打印关节数量
|
||
num_joints = robot.num_dof
|
||
print(f"\n关节数量: {num_joints}")
|
||
|
||
# 2. 打印关节名称
|
||
joint_names = robot.dof_names
|
||
print("\n关节名称:")
|
||
for i, name in enumerate(joint_names):
|
||
print(f" [{i}] {name}")
|
||
|
||
# 3. 打印关节类型
|
||
print("\n关节类型:")
|
||
for i, name in enumerate(joint_names):
|
||
# 大多数机器人关节是旋转关节
|
||
if "prismatic" in name.lower():
|
||
joint_type_str = "PRISMATIC"
|
||
else:
|
||
joint_type_str = "REVOLUTE"
|
||
print(f" [{i}] {name}: {joint_type_str}")
|
||
|
||
# 4. 打印关节位置信息
|
||
positions = robot.get_joint_positions()
|
||
print("\n当前关节位置:")
|
||
for i, pos in enumerate(positions):
|
||
print(f" [{i}] {joint_names[i]}: {pos:.4f}")
|
||
|
||
# 5. 打印关节速度
|
||
velocities = robot.get_joint_velocities()
|
||
print("\n当前关节速度:")
|
||
for i, vel in enumerate(velocities):
|
||
print(f" [{i}] {joint_names[i]}: {vel:.4f}")
|
||
|
||
# 6. 打印关节力矩
|
||
efforts = robot.get_applied_joint_efforts()
|
||
print("\n当前关节力矩:")
|
||
for i, eff in enumerate(efforts):
|
||
print(f" [{i}] {joint_names[i]}: {eff:.4f}")
|
||
|
||
# 使用Isaac Sim 4.2的API获取关节限制
|
||
print("\n关节限制 (使用Isaac Sim 4.2 API):")
|
||
try:
|
||
from omni.isaac.core.articulations import Articulation
|
||
from pxr import UsdPhysics
|
||
|
||
# 创建一个Articulation对象
|
||
articulation = Articulation(prim_path=robot_prim_path)
|
||
articulation.initialize()
|
||
|
||
# 通过USD接口获取关节限制
|
||
from pxr import Usd, UsdPhysics
|
||
stage = omni.usd.get_context().get_stage()
|
||
|
||
for i, joint_name in enumerate(joint_names):
|
||
# 尝试从名称推断关节路径
|
||
# 注意:这里假设关节路径格式为 robotPath/jointName
|
||
joint_path = f"{robot_prim_path}/{joint_name}"
|
||
joint_prim = stage.GetPrimAtPath(joint_path)
|
||
|
||
if not joint_prim:
|
||
# 尝试其他可能的路径格式
|
||
possible_paths = [
|
||
f"{robot_prim_path}/joints/{joint_name}",
|
||
f"{robot_prim_path}/{joint_name}_joint"
|
||
]
|
||
|
||
for path in possible_paths:
|
||
joint_prim = stage.GetPrimAtPath(path)
|
||
if joint_prim:
|
||
joint_path = path
|
||
break
|
||
|
||
if joint_prim:
|
||
joint_api = UsdPhysics.RevoluteJoint(joint_prim)
|
||
if joint_api:
|
||
lower_attr = joint_api.GetLowerAttr()
|
||
upper_attr = joint_api.GetUpperAttr()
|
||
|
||
if lower_attr and upper_attr:
|
||
lower = lower_attr.Get() if lower_attr.HasValue() else float('-inf')
|
||
upper = upper_attr.Get() if upper_attr.HasValue() else float('inf')
|
||
print(f" [{i}] {joint_name}: 下限={lower:.4f}, 上限={upper:.4f}")
|
||
continue
|
||
|
||
# 如果无法找到关节或获取限制,使用默认值
|
||
print(f" [{i}] {joint_name}: 下限=-π, 上限=π (默认值)")
|
||
|
||
except Exception as e:
|
||
print(f" 无法通过USD接口获取关节限制: {e}")
|
||
print(" 使用默认值: 下限=-π, 上限=π")
|
||
|
||
# 8. 驱动类型和控制器参数
|
||
print("\n驱动类型和控制器参数 (使用Action Graph节点获取):")
|
||
print(" 请使用下面的方法获取Action Graph中的控制器信息")
|
||
|
||
print("\n========================================")
|
||
|
||
|
||
# 使用兼容的方式获取Action Graph信息
|
||
def print_action_graph_info_compatible():
|
||
"""使用兼容Isaac Sim 4.2的方式打印Action Graph信息"""
|
||
print("\n========== Action Graph节点信息 (兼容方式) ==========")
|
||
|
||
try:
|
||
# 在Isaac Sim 4.2中,我们需要使用不同的API获取Action Graph
|
||
import omni.kit
|
||
from omni.kit.viewport.utility import get_viewport_from_window_name
|
||
viewport = get_viewport_from_window_name("Viewport")
|
||
|
||
# 打印Action Graph信息 - 方法1:使用USD查询
|
||
import omni.usd
|
||
from pxr import Usd, Sdf
|
||
|
||
# 获取当前舞台
|
||
stage = omni.usd.get_context().get_stage()
|
||
|
||
# 查找所有ActionGraph节点
|
||
print("\nAction Graph节点查找方法1 - USD路径查询:")
|
||
action_graph_paths = []
|
||
|
||
# 查找可能的Action Graph节点路径
|
||
possible_paths = ["/World/ActionGraph", "/ActionGraph"]
|
||
for path in possible_paths:
|
||
prim = stage.GetPrimAtPath(path)
|
||
if prim:
|
||
action_graph_paths.append(path)
|
||
print(f" 找到Action Graph路径: {path}")
|
||
|
||
# 打印子节点
|
||
children = prim.GetChildren()
|
||
if children:
|
||
print(" 子节点:")
|
||
for child in children:
|
||
print(f" - {child.GetPath()}")
|
||
|
||
# 尝试获取更多信息
|
||
attrs = child.GetAttributes()
|
||
if attrs:
|
||
print(f" 属性数量: {len(attrs)}")
|
||
# 打印前10个属性
|
||
for i, attr in enumerate(attrs):
|
||
if i >= 10:
|
||
break
|
||
print(f" {attr.GetName()}: {attr.Get() if attr.IsValid() else 'N/A'}")
|
||
|
||
if not action_graph_paths:
|
||
print(" 无法在常见路径找到Action Graph节点")
|
||
|
||
# 尝试搜索整个场景
|
||
print("\n 尝试搜索整个场景中的ActionGraph相关节点:")
|
||
|
||
def traverse_stage(prim):
|
||
paths = []
|
||
if "ActionGraph" in prim.GetName() or "articulation_controller" in prim.GetName().lower():
|
||
paths.append(prim.GetPath())
|
||
|
||
for child in prim.GetChildren():
|
||
paths.extend(traverse_stage(child))
|
||
return paths
|
||
|
||
root = stage.GetPseudoRoot()
|
||
all_action_paths = traverse_stage(root)
|
||
|
||
if all_action_paths:
|
||
print(f" 找到 {len(all_action_paths)} 个可能的Action Graph相关节点:")
|
||
for path in all_action_paths:
|
||
print(f" - {path}")
|
||
else:
|
||
print(" 未找到任何ActionGraph相关节点")
|
||
|
||
# 尝试查找ArticulationController节点
|
||
print("\n尝试找到ArticulationController节点:")
|
||
controller_found = False
|
||
|
||
for prim in Usd.PrimRange(stage.GetPseudoRoot()):
|
||
prim_type = prim.GetTypeName()
|
||
prim_name = prim.GetName()
|
||
|
||
if "ArticulationController" in str(prim_type) or "ArticulationController" in prim_name:
|
||
print(f" 找到控制器: {prim.GetPath()}")
|
||
controller_found = True
|
||
|
||
# 打印属性
|
||
attrs = prim.GetAttributes()
|
||
if attrs:
|
||
print(" 控制器属性:")
|
||
for attr in attrs:
|
||
if attr.IsValid():
|
||
print(f" - {attr.GetName()}: {attr.Get() if attr.HasValue() else 'N/A'}")
|
||
|
||
if not controller_found:
|
||
print(" 未找到ArticulationController节点")
|
||
|
||
except Exception as e:
|
||
print(f"获取Action Graph信息时出错: {e}")
|
||
|
||
print("\n========================================")
|
||
|
||
|
||
# 使用视觉脚本检查Action Graph
|
||
def print_action_graph_visual_info():
|
||
"""通过NVIDIA Omniverse视觉脚本API获取Action Graph信息"""
|
||
print("\n========== Action Graph信息 (视觉脚本API) ==========")
|
||
|
||
try:
|
||
# 尝试使用视觉脚本API
|
||
try:
|
||
import omni.kit.visual_scripting as vs
|
||
print("成功导入视觉脚本API")
|
||
|
||
# 尝试获取视觉脚本图表
|
||
graphs = vs.get_all_graphs()
|
||
if graphs:
|
||
print(f"找到 {len(graphs)} 个视觉脚本图表")
|
||
for i, graph in enumerate(graphs):
|
||
print(f"\n图表 {i+1}:")
|
||
print(f" 路径: {graph.get_path()}")
|
||
|
||
# 获取节点
|
||
nodes = graph.get_nodes()
|
||
print(f" 节点数量: {len(nodes)}")
|
||
for node in nodes:
|
||
print(f" - {node.get_title()} ({node.get_type_name()})")
|
||
|
||
# 获取节点参数
|
||
params = node.get_parameters()
|
||
if params:
|
||
print(" 参数:")
|
||
for param_name, param_value in params.items():
|
||
print(f" {param_name}: {param_value}")
|
||
else:
|
||
print("没有找到视觉脚本图表")
|
||
|
||
except ImportError:
|
||
print("视觉脚本API不可用")
|
||
|
||
# 尝试使用新版的图表API
|
||
try:
|
||
import omni.graph.core as og
|
||
print("\n尝试使用omni.graph.core API")
|
||
|
||
# 在Isaac Sim 4.2中,API可能发生了变化
|
||
# 尝试使用可能的替代方法
|
||
if hasattr(og, "get_graph_keys"):
|
||
keys = og.get_graph_keys()
|
||
print(f"找到 {len(keys)} 个图表键")
|
||
|
||
for key in keys:
|
||
print(f" 图表键: {key}")
|
||
graph = og.get_graph(key)
|
||
if graph:
|
||
print(" 成功获取图表")
|
||
# 处理图表...
|
||
else:
|
||
print(" get_graph_keys 方法不可用")
|
||
|
||
# 尝试其他可能的方法
|
||
if hasattr(og, "get_registered_graphs"):
|
||
graphs = og.get_registered_graphs()
|
||
print(f"找到 {len(graphs)} 个注册的图表")
|
||
# 处理图表...
|
||
else:
|
||
print(" get_registered_graphs 方法不可用")
|
||
|
||
except Exception as e:
|
||
print(f"使用omni.graph.core时出错: {e}")
|
||
|
||
except Exception as e:
|
||
print(f"获取视觉脚本信息时出错: {e}")
|
||
|
||
print("\n========================================")
|
||
|
||
|
||
# 使用USD直接查询机器人关节
|
||
def print_robot_joints_via_usd(robot_prim_path="/World/piper_description"):
|
||
"""使用USD API直接查询机器人关节信息"""
|
||
print("\n========== USD API查询机器人关节信息 ==========")
|
||
|
||
try:
|
||
from pxr import Usd, UsdPhysics, UsdGeom, Gf
|
||
|
||
# 获取当前舞台
|
||
stage = omni.usd.get_context().get_stage()
|
||
|
||
# 获取机器人根节点
|
||
robot_prim = stage.GetPrimAtPath(robot_prim_path)
|
||
if not robot_prim:
|
||
print(f"找不到机器人: {robot_prim_path}")
|
||
return
|
||
|
||
print(f"找到机器人: {robot_prim_path}")
|
||
|
||
# 查找关节
|
||
joints = []
|
||
|
||
# 方法1: 直接查找关节类型
|
||
for prim in Usd.PrimRange(robot_prim):
|
||
if prim.IsA(UsdPhysics.Joint) or prim.IsA(UsdPhysics.RevoluteJoint) or prim.IsA(UsdPhysics.PrismaticJoint):
|
||
joints.append(prim)
|
||
|
||
print(f"\n找到 {len(joints)} 个关节")
|
||
|
||
if joints:
|
||
for i, joint in enumerate(joints):
|
||
joint_path = joint.GetPath()
|
||
joint_name = joint.GetName()
|
||
|
||
print(f"\n关节 {i+1}:")
|
||
print(f" 路径: {joint_path}")
|
||
print(f" 名称: {joint_name}")
|
||
|
||
# 获取关节类型
|
||
joint_type = "未知"
|
||
if joint.IsA(UsdPhysics.RevoluteJoint):
|
||
joint_type = "旋转关节"
|
||
elif joint.IsA(UsdPhysics.PrismaticJoint):
|
||
joint_type = "平移关节"
|
||
elif joint.IsA(UsdPhysics.Joint):
|
||
joint_type = "通用关节"
|
||
|
||
print(f" 类型: {joint_type}")
|
||
|
||
# 获取关节限制
|
||
if joint.IsA(UsdPhysics.RevoluteJoint):
|
||
joint_api = UsdPhysics.RevoluteJoint(joint)
|
||
lower = joint_api.GetLowerAttr().Get() if joint_api.GetLowerAttr().HasValue() else float('-inf')
|
||
upper = joint_api.GetUpperAttr().Get() if joint_api.GetUpperAttr().HasValue() else float('inf')
|
||
print(f" 限制范围: [{lower:.4f}, {upper:.4f}]")
|
||
|
||
# 获取关节属性
|
||
attrs = joint.GetAttributes()
|
||
if attrs:
|
||
print(" 属性:")
|
||
for attr in attrs:
|
||
if attr.HasValue() and attr.IsValid():
|
||
print(f" - {attr.GetName()}: {attr.Get()}")
|
||
|
||
else:
|
||
print("未找到任何关节,尝试查找所有可能的关节...")
|
||
|
||
# 方法2: 查找包含'joint'的节点
|
||
possible_joints = []
|
||
|
||
for prim in Usd.PrimRange(robot_prim):
|
||
if "joint" in prim.GetName().lower():
|
||
possible_joints.append(prim)
|
||
|
||
print(f"\n找到 {len(possible_joints)} 个可能的关节")
|
||
|
||
for i, joint in enumerate(possible_joints[:5]): # 只显示前5个
|
||
print(f" {i+1}. {joint.GetPath()}")
|
||
|
||
if len(possible_joints) > 5:
|
||
print(f" ...以及 {len(possible_joints) - 5} 个其他关节")
|
||
|
||
except Exception as e:
|
||
print(f"使用USD API查询关节信息时出错: {e}")
|
||
|
||
print("\n========================================")
|
||
|
||
|
||
# 综合打印物理模拟状态
|
||
def print_physics_status():
|
||
"""打印物理模拟状态"""
|
||
print("\n========== 物理模拟状态检查 ==========")
|
||
|
||
# 检查物理模拟状态
|
||
timeline = omni.timeline.get_timeline_interface()
|
||
is_playing = timeline.is_playing()
|
||
print(f"物理模拟状态: {'运行中' if is_playing else '已停止'}")
|
||
|
||
# 获取PhysX版本信息
|
||
try:
|
||
import omni.physx
|
||
print("成功导入omni.physx")
|
||
|
||
# 尝试获取PhysX接口
|
||
physx_interface = omni.physx.get_physx_interface()
|
||
if physx_interface:
|
||
print("成功获取PhysX接口")
|
||
|
||
# 尝试获取PhysX属性
|
||
try:
|
||
physx_props = {}
|
||
|
||
# 测试可能的方法
|
||
if hasattr(physx_interface, "get_scene_count"):
|
||
physx_props["场景数量"] = physx_interface.get_scene_count()
|
||
|
||
if hasattr(physx_interface, "is_simulating"):
|
||
physx_props["正在模拟"] = physx_interface.is_simulating()
|
||
|
||
if hasattr(physx_interface, "get_active_stage_id"):
|
||
physx_props["活动场景ID"] = physx_interface.get_active_stage_id()
|
||
|
||
if hasattr(physx_interface, "get_gravitational_acceleration"):
|
||
physx_props["重力加速度"] = physx_interface.get_gravitational_acceleration()
|
||
|
||
if physx_props:
|
||
print("\nPhysX属性:")
|
||
for prop, value in physx_props.items():
|
||
print(f" {prop}: {value}")
|
||
else:
|
||
print("未找到可查询的PhysX属性")
|
||
except Exception as e:
|
||
print(f"获取PhysX属性时出错: {e}")
|
||
|
||
except Exception as e:
|
||
print(f"获取PhysX接口时出错: {e}")
|
||
|
||
print("\n通过USD API查询物理属性:")
|
||
try:
|
||
from pxr import Usd, UsdPhysics
|
||
|
||
# 获取当前舞台
|
||
stage = omni.usd.get_context().get_stage()
|
||
|
||
# 查找物理场景
|
||
scene = UsdPhysics.Scene.Get(stage)
|
||
if scene:
|
||
scene_prim = scene.GetPrim()
|
||
print(f"找到物理场景: {scene_prim.GetPath()}")
|
||
|
||
# 获取重力
|
||
gravity_attr = scene.GetGravityDirectionAttr()
|
||
gravity_mag_attr = scene.GetGravityMagnitudeAttr()
|
||
|
||
if gravity_attr and gravity_attr.HasValue():
|
||
gravity_dir = gravity_attr.Get()
|
||
print(f" 重力方向: {gravity_dir}")
|
||
|
||
if gravity_mag_attr and gravity_mag_attr.HasValue():
|
||
gravity_mag = gravity_mag_attr.Get()
|
||
print(f" 重力大小: {gravity_mag}")
|
||
else:
|
||
print("未找到物理场景")
|
||
|
||
except Exception as e:
|
||
print(f"查询USD物理属性时出错: {e}")
|
||
|
||
print("========================================")
|
||
|
||
|
||
# 执行所有函数
|
||
try:
|
||
# 确保物理模拟已启动
|
||
timeline = omni.timeline.get_timeline_interface()
|
||
if not timeline.is_playing():
|
||
timeline.play()
|
||
print("已启动物理模拟")
|
||
|
||
# 打印机器人信息
|
||
print_robot_actions_info("/World/piper_description")
|
||
|
||
# 使用兼容方式打印Action Graph信息
|
||
print_action_graph_info_compatible()
|
||
|
||
# 使用视觉脚本API获取信息
|
||
print_action_graph_visual_info()
|
||
|
||
# 使用USD API查询关节信息
|
||
print_robot_joints_via_usd("/World/piper_description")
|
||
|
||
# 打印物理模拟状态
|
||
print_physics_status()
|
||
|
||
except Exception as e:
|
||
print(f"执行过程中出现错误: {e}") |