Dynamic Control

About

The Dynamic Control Extension is used in Isaac Sim as a core, high-level interface to PhysX for different physics objects in a scene. The extension provides opaque handles that remain valid between PhysX scene resets. This means the handles are persistent, even even when the simulation starts / stops when the PLAY and STOP buttons are pressed.

API Documentation

See the API Documentation for complete usage information.

Code Snippets

To run the following code snippets:

  1. The following code snippets assume that the Stage contains a Franka robot at the /Franka prim path. Go to the top menu bar and click Create > Isaac > Robots > From Library > Manipulators > Franka to add a Franka to the scene.

  2. At least one frame of simulation must occur before the Dynamic Control APIs work correctly. To start the simulation:

    1. (Option #1) Press the PLAY button to begin simulating.

    2. (Option #2) Use the following code snippet to start the simulation using the Python API before running any of the snippets below.

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

We recommend using the built-in Script Editor to test these snippets. For deeper development, please see the Isaac Sim Workflows tutorial.

To access the Script Editor, go to the top menu bar and click Window > Script Editor.

Note

The snippets are disparate examples, running them out of order may have unintended consequences.

Note

The snippets are for demonstrative purposes, the resulting movements may not respect the robot’s kinematic limitations.

Position Control

1
2
3
4
5
6
7
8
from omni.isaac.dynamic_control import _dynamic_control
import numpy as np
dc = _dynamic_control.acquire_dynamic_control_interface()
articulation = dc.get_articulation("/Franka")
# Call this each frame of simulation step if the state of the articulation is changing.
dc.wake_up_articulation(articulation)
joint_angles = [np.random.rand(9) * 2 - 1]
dc.set_articulation_dof_position_targets(articulation, joint_angles)

Single DOF Position Control

1
2
3
4
5
6
7
from omni.isaac.dynamic_control import _dynamic_control
import numpy as np
dc = _dynamic_control.acquire_dynamic_control_interface()
articulation = dc.get_articulation("/Franka")
dc.wake_up_articulation(articulation)
dof_ptr = dc.find_articulation_dof(articulation, "panda_joint2")
dc.set_dof_position_target(dof_ptr, -1.5)

Velocity Control

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from pxr import UsdPhysics
stage = omni.usd.get_context().get_stage()
for prim in stage.TraverseAll():
    prim_type = prim.GetTypeName()
    if prim_type in ["PhysicsRevoluteJoint" , "PhysicsPrismaticJoint"]:
        if prim_type == "PhysicsRevoluteJoint":
            drive = UsdPhysics.DriveAPI.Get(prim, "angular")
        else:
            drive = UsdPhysics.DriveAPI.Get(prim, "linear")
        drive.GetStiffnessAttr().Set(0)
from omni.isaac.dynamic_control import _dynamic_control
import numpy as np
dc = _dynamic_control.acquire_dynamic_control_interface()
#Note: getting the articulation has to happen after changing the drive stiffness
articulation = dc.get_articulation("/Franka")
dc.wake_up_articulation(articulation)
joint_vels = [-np.random.rand(9)*10]
dc.set_articulation_dof_velocity_targets(articulation, joint_vels)

Single DOF Velocity Control

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from pxr import UsdPhysics
stage = omni.usd.get_context().get_stage()
panda_joint2_drive = UsdPhysics.DriveAPI.Get(stage.GetPrimAtPath("/Franka/panda_link1/panda_joint2"), "angular")
panda_joint2_drive.GetStiffnessAttr().Set(0)
from omni.isaac.dynamic_control import _dynamic_control
import numpy as np
dc = _dynamic_control.acquire_dynamic_control_interface()
#Note: getting the articulation has to happen after changing the drive stiffness
articulation = dc.get_articulation("/Franka")
dc.wake_up_articulation(articulation)
dof_ptr = dc.find_articulation_dof(articulation, "panda_joint2")
dc.set_dof_velocity_target(dof_ptr, 0.2)

Torque Control

1
2
3
4
5
6
7
from omni.isaac.dynamic_control import _dynamic_control
import numpy as np
dc = _dynamic_control.acquire_dynamic_control_interface()
articulation = dc.get_articulation("/Franka")
dc.wake_up_articulation(articulation)
joint_efforts = [-np.random.rand(9) * 1000]
dc.set_articulation_dof_efforts(articulation, joint_efforts)

Check Object Type

1
2
3
4
5
6
7
from omni.isaac.dynamic_control import _dynamic_control
dc = _dynamic_control.acquire_dynamic_control_interface()

# Check to see what type of object the target prim is
obj_type = dc.peek_object_type("/Franka")
# This print statement should print ObjectType.OBJECT_ARTICULATION
print(obj_type)

Query Articulation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from omni.isaac.dynamic_control import _dynamic_control
dc = _dynamic_control.acquire_dynamic_control_interface()

# Get a handle to the Franka articulation
# This handle will automatically update if simulation is stopped and restarted
art = dc.get_articulation("/Franka")

# Get information about the structure of the articulation
num_joints = dc.get_articulation_joint_count(art)
num_dofs = dc.get_articulation_dof_count(art)
num_bodies = dc.get_articulation_body_count(art)

# Get a specific degree of freedom on an articulation
dof_ptr = dc.find_articulation_dof(art, "panda_joint2")

Read Joint State

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
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)

# 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.pos)