Isaac Sim Version
4.5.0
Operating System
Ubuntu 22.04
Windows 11
GPU Information
- Model: GeForce 4090
- Driver Version: 570.133
Topic Description
Detailed Description
Trying to read the body0 and body1 prim names of a joint from Omnigraph, they are not exposed as valid attributes.
Steps to Reproduce
- Create two bodies, connect them with a joint (any type)
- Create a new Omnigraph, drag and drop the joint into it, then select
Read Attribute
- Go through the list of
Attribute Names. physics:body0 and physics:body1 are not there.
Error Messages
Attempting to use a constant token to select the bodies is not permitted either, showing the following error:
Hi @christianbarcelo, thanks for your question! I was able to repro this on my end, and was also unable to see the physics:body0 and physics:body1 in the attribute list. Could I get some more context on what your use case is for accessing the prim names in this way?
It’s a little hard to understand and it’s a particular use case, but I have the need to query all the joints in the scene and do something with a custom extension on the connected bodies of all those joints.
Given I have a HUGE amount of joints, I need to be able to iterate through them all and consume the bodies.
I have a tick connected to a get prims and a for loop to get each joint in the scene. Is there any other way I can consume the bodies?
Thanks for giving it a try!
Hi , here is a sample script for getting the joint bodies for a Franka robot
#!/usr/bin/env python3
"""
Sample Isaac Sim script to iterate through joints in a scene and get body names.
This script demonstrates multiple approaches to inspect joints and their associated bodies.
"""
import numpy as np
from isaacsim import SimulationApp
# Create simulation app
simulation_app = SimulationApp({"headless": False})
from isaacsim.core.api import World
from isaacsim.robot.manipulators.examples.franka import Franka
from pxr import UsdPhysics
from omni.isaac.core.utils.stage import get_current_stage
def get_all_joints_in_scene():
stage = get_current_stage()
# Find all joint prims in the scene
joint_prims = []
for prim in stage.Traverse():
if prim.IsA(UsdPhysics.Joint):
joint_prims.append(prim)
print(f"Found {len(joint_prims)} joints in the scene:")
for i, joint_prim in enumerate(joint_prims):
joint_path = joint_prim.GetPath()
joint_name = joint_prim.GetName()
# Get joint type
joint_type = "Unknown"
if joint_prim.IsA(UsdPhysics.RevoluteJoint):
joint_type = "Revolute"
elif joint_prim.IsA(UsdPhysics.PrismaticJoint):
joint_type = "Prismatic"
elif joint_prim.IsA(UsdPhysics.SphericalJoint):
joint_type = "Spherical"
elif joint_prim.IsA(UsdPhysics.FixedJoint):
joint_type = "Fixed"
elif joint_prim.IsA(UsdPhysics.DistanceJoint):
joint_type = "Distance"
# Get connected bodies
joint_api = UsdPhysics.Joint(joint_prim)
body0_rel = joint_api.GetBody0Rel()
body1_rel = joint_api.GetBody1Rel()
body0_path = "None"
body1_path = "None"
body0_name = "None"
body1_name = "None"
if body0_rel:
targets = body0_rel.GetTargets()
if targets:
body0_path = str(targets[0])
body0_prim = stage.GetPrimAtPath(targets[0])
if body0_prim:
body0_name = body0_prim.GetName()
if body1_rel:
targets = body1_rel.GetTargets()
if targets:
body1_path = str(targets[0])
body1_prim = stage.GetPrimAtPath(targets[0])
if body1_prim:
body1_name = body1_prim.GetName()
print(f"\n Joint {i+1}:")
print(f" Name: {joint_name}")
print(f" Type: {joint_type}")
print(f" Path: {joint_path}")
print(f" Body 0: {body0_name} ({body0_path})")
print(f" Body 1: {body1_name} ({body1_path})")
def main():
print("Isaac Sim Joint and Body Inspector")
print("=" * 60)
# Create world
world = World(stage_units_in_meters=1.0)
# Add default ground plane
world.scene.add_default_ground_plane()
# Add a Franka robot for demonstration
print("Adding Franka robot to scene...")
franka = world.scene.add(
Franka(
prim_path="/World/Franka",
name="franka_robot",
gripper_dof_names=["panda_finger_joint1", "panda_finger_joint2"],
end_effector_prim_name="panda_rightfinger",
)
)
# Reset world to initialize everything
world.reset()
# Find all joints using USD traversal
get_all_joints_in_scene()
# Cleanup
simulation_app.close()
if __name__ == "__main__":
main()
Thanks for looking into it @shalinj !
I agree that code-wise your suggestion may be what makes the most sense, but my question was mostly related on how to capture that information from an Omnigraph.
I’m much more comfortable writing custom code rather than using Omnigraphs, but this was a special use case that required being able to consume that data from a pre-existing Omnigraph.
Is this a bug or an expected (weird) behavior? I can report it in the Isaac Sim 5.0 repo if there’s no internal ticket yet.
Thanks!