Failed to query Articulation in python script

Note: For any Isaac Lab topics, please submit your topic to its GitHub repo ( GitHub - isaac-sim/IsaacLab: Unified framework for robot learning built on NVIDIA Isaac Sim ) following the instructions provided on Isaac Lab’s Contributing Guidelines ( Contribution Guidelines — Isaac Lab Documentation ).

Please provide all relevant details below before submitting your post. This will help the community provide more accurate and timely assistance. After submitting, you can check the appropriate boxes. Remember, you can always edit your post later to include additional information if needed.

Isaac Sim Version

4.5.0
4.2.0
4.1.0
4.0.0
4.5.0
2023.1.1
2023.1.0-hotfix.1
x Other (please specify):5.0.0

Operating System

x Ubuntu 22.04
Ubuntu 20.04
Windows 11
Windows 10
Other (please specify):

GPU Information

  • Model: RTX5880ada
  • Driver Version: 550.144.03

Topic Description

Detailed Description

(Describe the issue in detail, including what you were trying to do, what you expected to happen, and what actually happened)

I imported three robot arms in format of urdf, and I want to set the joint values of the robot arm.

I can use the Physics Inspector in the Tool Panel to manipulate the robot, but when I followed the instruction of Robot Simulation Snippets — Isaac Sim Documentation to complete the same task in python script, it failed.

Here is part of my code :

async def set_scene():
    import omni
    import omni.kit.commands
    import omni.usd
    from isaacsim.core.api.world import World
    from isaacsim.core.prims import RigidPrim
    from isaacsim.core.api.objects import DynamicCuboid

    if World.instance():
        World.instance().clear_instance()
    world=World()
    await world.initialize_simulation_context_async()
    world.scene.add_default_ground_plane(z_position=-1.0)

    # Retrieve the path of the URDF file
    ......
        
    # create a physical scene
    stage = omni.usd.get_context().get_stage()    
    import omni
    omni.timeline.get_timeline_interface().play()
    
    ......

    # dymical control/ robot articulation
    from omni.isaac.dynamic_control import _dynamic_control
    dc = _dynamic_control.acquire_dynamic_control_interface()

    # Print the state of each degree of freedom in the articulation
    art = dc.get_articulation("/RMBF_8_G3_0")
    if art == _dynamic_control.INVALID_HANDLE:
        print("Error: Articulation not found!")
    dof_states = dc.get_articulation_dof_states(art, _dynamic_control.STATE_ALL)
    print("RMBF state", dof_states)

    # Get state for a specific degree of freedom
    dof_ptr = dc.find_articulation_dof(art, "rlnd_A3_2")
    dof_state = dc.get_dof_state(dof_ptr, _dynamic_control.STATE_ALL)
    # print position for the degree of freedom
    print("rlnd_A3_2 pos", dof_state.pos)
    num_joints = dc.get_articulation_joint_count(art)
    print("number of joints", num_joints)

    world.reset()

    ......


asyncio.ensure_future(set_scene())

Steps to Reproduce

(Add more steps as needed)

Error Messages

(If applicable, copy and paste any error messages you received)

2025-08-07T09:29:57Z [13,811,466ms] [Warning] [omni.isaac.dynamic_control.plugin] Failed to find articulation at '/RMBF_8_G3_0'
Error: Articulation not found!
RMBF state None
2025-08-07T09:29:57Z [13,811,466ms] [Warning] [omni.isaac.dynamic_control.plugin] DcFindArticulationDof: Function called while not simulating
2025-08-07T09:29:57Z [13,811,466ms] [Warning] [omni.isaac.dynamic_control.plugin] DcGetDofState: Function called while not simulating
rlnd_A3_2 pos 0.0
2025-08-07T09:29:57Z [13,811,466ms] [Warning] [omni.isaac.dynamic_control.plugin] DcGetArticulationJointCount: Function called while not simulating
number of joints 0

Screenshots or Videos

(If applicable, add screenshots or links to videos that demonstrate the issue)

Additional Information

What I’ve Tried

(Describe any troubleshooting steps you’ve already taken)

    import omni
    omni.timeline.get_timeline_interface().play()

    # dymical control/ robot articulation
    from omni.isaac.dynamic_control import _dynamic_control
    dc = _dynamic_control.acquire_dynamic_control_interface()

    # new api
    from isaacsim.core.utils.prims import get_articulation_root_api_prim_path
    root_api_prim_path = get_articulation_root_api_prim_path("/RMBF_8_G3_0")
    print("root_api_prim_path is", root_api_prim_path)

    # find
    from isaacsim.core.utils.articulations import find_all_articulation_base_paths
    rootpath = find_all_articulation_base_paths()
    print("find_all_articulation_base_paths", rootpath)

    stage = omni.usd.get_context().get_stage()
    for prim in stage.Traverse():
        from pxr import Gf, Sdf, Usd, UsdGeom, UsdPhysics
        if prim.HasAPI(UsdPhysics.ArticulationRootAPI):
            print(prim.GetPath(), " is articulation")
        elif prim.IsA(UsdPhysics.PrismaticJoint) or prim.IsA(UsdPhysics.RevoluteJoint) or prim.IsA(UsdPhysics.SphericalJoint):
            print(prim.GetPath(), " is joint")


############################below is log###############################
root_api_prim_path is /RMBF_8_G3_0/root_joint
find_all_articulation_base_paths ['/SetupArmG2_2', '/RMBF_8_G3_0', '/RLND_8_G3_0']
/RMBF_8_G3_0/joints/fixed_base  is joint
/RMBF_8_G3_0/joints/arm_joint_1  is joint
/RMBF_8_G3_0/joints/arm_joint_2  is joint
/RMBF_8_G3_0/joints/arm_joint_3  is joint
/RMBF_8_G3_0/joints/arm_joint_4  is joint
/RMBF_8_G3_0/joints/arm_joint_5  is joint
/RMBF_8_G3_0/joints/arm_joint_6  is joint
/RMBF_8_G3_0/joints/arm_joint_7  is joint
/RMBF_8_G3_0/joints/arm_joint_8  is joint
/RMBF_8_G3_0/joints/arm_joint_9  is joint
/RMBF_8_G3_0/joints/rmbf_A1  is joint
/RMBF_8_G3_0/joints/rmbf_A2  is joint
/RMBF_8_G3_0/joints/rmbf_A3_1  is joint
/RMBF_8_G3_0/joints/rmbf_A3_2  is joint
/RMBF_8_G3_0/joints/rmbf_linkA1_to_shell  is joint
/RMBF_8_G3_0/root_joint  is articulation
/RLND_8_G3_0/joints/fixed_base  is joint
/RLND_8_G3_0/joints/arm_joint_1  is joint
/RLND_8_G3_0/joints/arm_joint_2  is joint
/RLND_8_G3_0/joints/arm_joint_3  is joint
/RLND_8_G3_0/joints/arm_joint_4  is joint
/RLND_8_G3_0/joints/arm_joint_5  is joint
/RLND_8_G3_0/joints/arm_joint_6  is joint
/RLND_8_G3_0/joints/arm_joint_7  is joint
/RLND_8_G3_0/joints/arm_joint_8  is joint
/RLND_8_G3_0/joints/arm_joint_9  is joint
/RLND_8_G3_0/joints/rlnd_A1  is joint
/RLND_8_G3_0/joints/rlnd_A2  is joint
/RLND_8_G3_0/joints/rlnd_A3_1  is joint
/RLND_8_G3_0/joints/rlnd_A3_2  is joint
/RLND_8_G3_0/joints/rlnd_linkA1_to_shell  is joint
/RLND_8_G3_0/root_joint  is articulation
/SetupArmG2_2/joints/arm_joint_1  is joint
/SetupArmG2_2/joints/arm_joint_2  is joint
/SetupArmG2_2/joints/arm_joint_3  is joint
/SetupArmG2_2/joints/arm_joint_4  is joint
/SetupArmG2_2/joints/arm_joint_5  is joint
/SetupArmG2_2/joints/arm_joint_6  is joint
/SetupArmG2_2/joints/arm_joint_7  is joint
/SetupArmG2_2/joints/arm_joint_8  is joint
/SetupArmG2_2/joints/arm_joint_9  is joint
/SetupArmG2_2/joints/A1234  is joint
/SetupArmG2_2/joints/A5  is joint
/SetupArmG2_2/root_joint  is articulation
from isaacsim.asset.importer.urdf._urdf import UrdfJointTargetType
import_config.default_drive_type = UrdfJointTargetType.JOINT_DRIVE_POSITION
world.step(render=True)

Related Issues

(If you’re aware of any related issues or forum posts, please link them here)

Additional Context

(Add any other context about the problem here)

hi crystalzhouzijun,

Seems art = dc.get_articulation(“/RMBF_8_G3_0”) failed in your script? If true make sure our Simulation Snippets can run correctly from your side. then just replace your assets path of Franka for testing dc.get_articulation API.

Hi, I already tested the Franka and it can run successfully.

Here is the code

import asyncio
import numpy as np
from isaacsim.core.api.world import World
from isaacsim.core.prims import Articulation
from isaacsim.core.utils.nucleus import get_assets_root_path
from isaacsim.core.utils.stage import add_reference_to_stage

async def example():
    if World.instance():
        World.instance().clear_instance()
    world=World()
    await world.initialize_simulation_context_async()
    world.scene.add_default_ground_plane()

    # add franka articulations

    asset_path = get_assets_root_path() + "/Isaac/Robots/FrankaRobotics/FrankaPanda/franka.usd"
    robot = add_reference_to_stage(usd_path=asset_path, prim_path="/Franka")

    # batch process articulations via an Articulation
    frankas_view = Articulation(prim_paths_expr="/Franka", name="frankas_view")
    world.scene.add(frankas_view)
    await world.reset_async()
    # set root body poses
    new_positions = np.array([[-1.0, 1.0, 0]])
    frankas_view.set_world_poses(positions=new_positions)
    # set the joint positions for each articulation
    frankas_view.set_joint_positions(np.array([[1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5]]))
    
    import omni
    stage = omni.usd.get_context().get_stage()
    for prim in stage.Traverse():
        print(prim.GetPath())

    import omni
    omni.timeline.get_timeline_interface().play()

    from omni.isaac.dynamic_control import _dynamic_control
    dc = _dynamic_control.acquire_dynamic_control_interface()

    # Print the state of each degree of freedom in the articulation
    art = dc.get_articulation("/Franka")
    dof_states = dc.get_articulation_dof_states(art, _dynamic_control.STATE_ALL)
    print("dof_states are ", dof_states)

    # Get state for a specific degree of freedom
    dof_ptr = dc.find_articulation_dof(art, "panda_joint2")
    dof_state = dc.get_dof_state(dof_ptr, _dynamic_control.STATE_ALL)
    # print position for the degree of freedom
    print("dof state is ", dof_state.pos)

asyncio.ensure_future(example())

But when I replace the robot with our urdf, or replace the generated usd file with code:

import asyncio
import numpy as np
from isaacsim.core.api.world import World
from isaacsim.core.prims import Articulation
from isaacsim.core.utils.nucleus import get_assets_root_path
from isaacsim.core.utils.stage import add_reference_to_stage

async def example():
    if World.instance():
        World.instance().clear_instance()
    world=World()
    await world.initialize_simulation_context_async()
    world.scene.add_default_ground_plane()

    # add franka articulations

    asset_path = "/home/oem/xxx/isaacsim/urdf_5_0_0/example_description/robot_arm/robot_arm.usd"
    robot = add_reference_to_stage(usd_path=asset_path, prim_path="/SetupArmG2_2")

    # batch process articulations via an Articulation
    robot_view = Articulation(prim_paths_expr="/SetupArmG2_2", name="robot_view")
    world.scene.add(robot_view)
    await world.reset_async()
    # # set root body poses
    # new_positions = np.array([[-1.0, 1.0, 0]])
    # frankas_view.set_world_poses(positions=new_positions)
    # # set the joint positions for each articulation
    # frankas_view.set_joint_positions(np.array([[1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5]]))
    
    import omni
    from pxr import UsdGeom, UsdPhysics
    stage = omni.usd.get_context().get_stage()
    for prim in stage.Traverse():
        # print(prim.GetPath())
        if prim.HasAPI(UsdPhysics.ArticulationRootAPI):
            print(f"articulation root found at {prim.GetPath()}")
        else:
            print(f"not found at {prim.GetPath()}")

    import omni
    omni.timeline.get_timeline_interface().play()

    from omni.isaac.dynamic_control import _dynamic_control
    dc = _dynamic_control.acquire_dynamic_control_interface()

    # Print the state of each degree of freedom in the articulation
    art = dc.get_articulation("/SetupArmG2_2")
    dof_states = dc.get_articulation_dof_states(art, _dynamic_control.STATE_ALL)
    print("dof_states are ", dof_states)

    # Get state for a specific degree of freedom
    dof_ptr = dc.find_articulation_dof(art, "arm_joint_9")
    dof_state = dc.get_dof_state(dof_ptr, _dynamic_control.STATE_ALL)
    # print position for the degree of freedom
    print("dof state is ", dof_state.pos)

asyncio.ensure_future(example())

It still failed when get articulation.

The log is:

2025-08-13T07:00:55Z [13,867,217ms] [Warning] [isaacsim.core.api.simulation_context.simulation_context] A new stage was opened, World or Simulation Object are invalidated and you would need to initialize them again before using them.
not found at /World
not found at /World/defaultGroundPlane
not found at /World/defaultGroundPlane/Looks
not found at /World/defaultGroundPlane/Looks/theGrid
not found at /World/defaultGroundPlane/Looks/theGrid/Shader
not found at /World/defaultGroundPlane/GroundPlane
not found at /World/defaultGroundPlane/GroundPlane/CollisionPlane
not found at /World/defaultGroundPlane/SphereLight
not found at /World/defaultGroundPlane/Environment
not found at /World/defaultGroundPlane/Environment/Geometry
not found at /World/Physics_Materials
not found at /World/Physics_Materials/physics_material
not found at /Environment
not found at /Environment/defaultLight
not found at /Render
not found at /Render/OmniverseKit
not found at /Render/OmniverseKit/HydraTextures
not found at /Render/OmniverseKit/HydraTextures/omni_kit_widget_viewport_ViewportTexture_0
not found at /Render/OmniverseGlobalRenderSettings
not found at /Render/Vars
not found at /Render/Vars/LdrColor
not found at /physicsScene
not found at /SetupArmG2_2
not found at /SetupArmG2_2/arm_base_link
not found at /SetupArmG2_2/arm_base_link/visuals
not found at /SetupArmG2_2/arm_base_link/collisions
not found at /SetupArmG2_2/arm_link_1
not found at /SetupArmG2_2/arm_link_1/visuals
not found at /SetupArmG2_2/arm_link_1/collisions
not found at /SetupArmG2_2/joints
not found at /SetupArmG2_2/joints/arm_joint_1
not found at /SetupArmG2_2/joints/arm_joint_2
not found at /SetupArmG2_2/joints/arm_joint_3
not found at /SetupArmG2_2/joints/arm_joint_4
not found at /SetupArmG2_2/joints/arm_joint_5
not found at /SetupArmG2_2/joints/arm_joint_6
not found at /SetupArmG2_2/joints/arm_joint_7
not found at /SetupArmG2_2/joints/arm_joint_8
not found at /SetupArmG2_2/joints/arm_joint_9
not found at /SetupArmG2_2/arm_link_2
not found at /SetupArmG2_2/arm_link_2/visuals
not found at /SetupArmG2_2/arm_link_2/collisions
not found at /SetupArmG2_2/arm_link_3
not found at /SetupArmG2_2/arm_link_3/visuals
not found at /SetupArmG2_2/arm_link_3/collisions
not found at /SetupArmG2_2/arm_link_4
not found at /SetupArmG2_2/arm_link_4/visuals
not found at /SetupArmG2_2/arm_link_4/collisions
not found at /SetupArmG2_2/arm_link_5
not found at /SetupArmG2_2/arm_link_5/visuals
not found at /SetupArmG2_2/arm_link_5/collisions
not found at /SetupArmG2_2/arm_link_6
not found at /SetupArmG2_2/arm_link_6/visuals
not found at /SetupArmG2_2/arm_link_6/collisions
not found at /SetupArmG2_2/arm_link_7
not found at /SetupArmG2_2/arm_link_7/visuals
not found at /SetupArmG2_2/arm_link_7/collisions
not found at /SetupArmG2_2/arm_link_8
not found at /SetupArmG2_2/arm_link_8/visuals
not found at /SetupArmG2_2/arm_link_8/collisions
not found at /SetupArmG2_2/arm_link_9
not found at /SetupArmG2_2/arm_link_9/visuals
not found at /SetupArmG2_2/arm_link_9/collisions
not found at /SetupArmG2_2/Looks
not found at /SetupArmG2_2/Looks/material_Aluminum
not found at /SetupArmG2_2/Looks/material_Aluminum/Shader
not found at /SetupArmG2_2/Looks/material_FleshColor
not found at /SetupArmG2_2/Looks/material_FleshColor/Shader
not found at /SetupArmG2_2/Looks/material_PlasticBlack
not found at /SetupArmG2_2/Looks/material_PlasticBlack/Shader
not found at /SetupArmG2_2/Looks/material_black1
not found at /SetupArmG2_2/Looks/material_black1/Shader
not found at /SetupArmG2_2/Looks/material_black2
not found at /SetupArmG2_2/Looks/material_black2/Shader
not found at /SetupArmG2_2/Looks/material_blue
not found at /SetupArmG2_2/Looks/material_blue/Shader
not found at /SetupArmG2_2/Looks/material_green
not found at /SetupArmG2_2/Looks/material_green/Shader
not found at /SetupArmG2_2/Looks/material_orange
not found at /SetupArmG2_2/Looks/material_orange/Shader
not found at /SetupArmG2_2/Looks/material_red
not found at /SetupArmG2_2/Looks/material_red/Shader
not found at /SetupArmG2_2/Looks/material_white
not found at /SetupArmG2_2/Looks/material_white/Shader
not found at /SetupArmG2_2/Looks/material_yellow
not found at /SetupArmG2_2/Looks/material_yellow/Shader
articulation root found at /SetupArmG2_2/root_joint
not found at /OmniverseKit_Persp
not found at /OmniverseKit_Front
not found at /OmniverseKit_Top
not found at /OmniverseKit_Right
2025-08-13T07:00:59Z [13,871,680ms] [Warning] [omni.isaac.dynamic_control.plugin] Failed to find articulation at '/SetupArmG2_2'
2025-08-13T07:00:59Z [13,871,680ms] [Error] [omni.isaac.dynamic_control.plugin] DcGetArticulationDofCount: Invalid or expired articulation handle
dof_states are  None
2025-08-13T07:00:59Z [13,871,680ms] [Error] [omni.isaac.dynamic_control.plugin] DcFindArticulationDof: Invalid or expired articulation handle
2025-08-13T07:00:59Z [13,871,680ms] [Error] [omni.isaac.dynamic_control.plugin] DcGetDofState: Invalid or expired dof handle
dof state is  0.0

your prim missed articulation root regarding to errors printed, make sure add it in usd before test

But the log shows:

articulation root found at /SetupArmG2_2/root_joint

sorry missed this information. you should set the articulation root schema on the parent prim(SetupArmG2-2) of the root joint rather than directly on the root_joint itself

I tried this but still not working. I am not sure if I used the correct API or I missed something:

    # Ensure physics properties are set on the robot
    prim_root = stage.GetPrimAtPath("/SetupArmG2_2")
    if not UsdPhysics.ArticulationRootAPI(prim_root):
        UsdPhysics.ArticulationRootAPI.Apply(prim_root)

And I did nothing to the root_joint and only the /SetupArmG2_2/root_joint has directly prim.HasAPI(UsdPhysics.ArticulationRootAPI)

What I have tried:

  1. condition
    1.     import omni
          omni.timeline.get_timeline_interface().play()
      
          from omni.isaac.core.articulations import Articulation
          robot = Articulation(prim_path="/SetupArmG2_2")  
          world.reset()
          robot.initialize()  
      
          # dymical control/ robot articulation
          from omni.isaac.dynamic_control import _dynamic_control
          dc = _dynamic_control.acquire_dynamic_control_interface()
      
  2. API: get_articulation_root_api_prim_path
    1.     from isaacsim.core.utils.prims import get_articulation_root_api_prim_path
          root_api_prim_path = get_articulation_root_api_prim_path("/SetupArmG2_2")
          print("root_api_prim_path is", root_api_prim_path)
      
    2. Printed Result: root_api_prim_path is /SetupArmG2_2/root_joint
  3. API: find_all_articulation_base_paths
    1.     from isaacsim.core.utils.articulations import find_all_articulation_base_paths
          rootpath = find_all_articulation_base_paths()
          print("find_all_articulation_base_paths", rootpath)
      
    2. Printed Result: find_all_articulation_base_paths [‘/SetupArmG2_2’]
  4. API: prim.HasAPI(UsdPhysics.ArticulationRootAPI):
    1.     stage = omni.usd.get_context().get_stage()
          for prim in stage.Traverse():
              from pxr import Gf, Sdf, Usd, UsdGeom, UsdPhysics
              if prim.HasAPI(UsdPhysics.ArticulationRootAPI):
                  print(prim.GetPath(), " is articulation")
      
    2. Printed Result: /SetupArmG2_2/root_joint is articulation
  5. API:UsdPhysics.ArticulationRootAPI.Apply
    1.     prim_root = stage.GetPrimAtPath("/SetupArmG2_2")
          if not UsdPhysics.ArticulationRootAPI(prim_root):
              UsdPhysics.ArticulationRootAPI.Apply(prim_root)
      
    2. No Error Log shows up
  6. API:dc.get_articulation
    1.     art = dc.get_articulation("/SetupArmG2_2")
          if art == _dynamic_control.INVALID_HANDLE:
              print("*** '%s' is not an articulation" % "/SetupArmG2_2")
      
    2. Log Warning: 2025-08-20T09:19:40Z [2,626,258ms] [Warning] [omni.isaac.dynamic_control.plugin] Failed to find articulation at ‘/SetupArmG2_2’
    3. Printed Result: *** ‘/SetupArmG2_2’ is not an articulation
  7. API: dc.get_articulation_dof_states
    1.     dof_states = dc.get_articulation_dof_states(art, _dynamic_control.STATE_ALL)
          print("/SetupArmG2_2 state", dof_states)
      
    2. Log Error: 2025-08-20T09:19:40Z [2,626,259ms] [Error] [omni.isaac.dynamic_control.plugin] DcGetArticulationDofCount: Invalid or expired articulation handle
    3. Printed Result: /SetupArmG2_2 state None

Hi ZZJzhou,
Sorry for so late response! Have you resolved it or not ? Since /World has not found yet, have you tried to add articulate root to /World directly?

If still blocked you ,I will assist you at highest priority .

Hi it has not yet been solved

solved by add “basic link” instead of a robot as an articulation root

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.