Controlling Robots with ROS Bridge
This page uses ROS2 Bridge. Similar actions can be also be easily find for ROS Bridge.
Action Graph for Robot Joint States / Commands
This piece of code creates an action graph at GRAPH_PATH
for robot at ROBOT_PRIM_PATH
. It publishes joint states to /joint_states
and subscribe goal state commands from /joint_commands
via ROS2 Bridge.
Note that the action graph should be under the prim of the robot it aims to control.
You need to first obtain the current stage (you can get it by calling self.get_stage()
in derive classes of BaseSample
) as stage
. You also need to import:
import omni.graph.core as og
To create the graph:
ROBOT_PRIM_PATH = "/robot"
GRAPH_PATH = "/robot/JointGraph"
(moveit_graphkeys = og.Controller.Keys
_, _, _) = og.Controller.edit(
{"graph_path": GRAPH_PATH, "evaluator_name": "execution"},
{
og.Controller.Keys.CREATE_NODES: [
("OnImpulseEvent", "omni.graph.action.OnImpulseEvent"),
("ReadSimTime", "omni.isaac.core_nodes.IsaacReadSimulationTime"),
("Context", "omni.isaac.ros2_bridge.ROS2Context"),
("PublishClock", "omni.isaac.ros2_bridge.ROS2PublishClock"),
("PublishJointState", "omni.isaac.ros2_bridge.ROS2PublishJointState"),
("SubscribeJointState", "omni.isaac.ros2_bridge.ROS2SubscribeJointState"),
("ArticulationController", "omni.isaac.core_nodes.IsaacArticulationController"),
("PublishTF", "omni.isaac.ros2_bridge.ROS2PublishTransformTree"),
],
og.Controller.Keys.CONNECT: [
("OnImpulseEvent.outputs:execOut", "PublishJointState.inputs:execIn"),
("OnImpulseEvent.outputs:execOut", "SubscribeJointState.inputs:execIn"),
("OnImpulseEvent.outputs:execOut", "PublishTF.inputs:execIn"),
("OnImpulseEvent.outputs:execOut", "PublishClock.inputs:execIn"),
("OnImpulseEvent.outputs:execOut", "ArticulationController.inputs:execIn"),
("Context.outputs:context", "PublishJointState.inputs:context"),
("Context.outputs:context", "SubscribeJointState.inputs:context"),
("Context.outputs:context", "PublishTF.inputs:context"),
("Context.outputs:context", "PublishClock.inputs:context"),
("ReadSimTime.outputs:simulationTime", "PublishJointState.inputs:timeStamp"),
("ReadSimTime.outputs:simulationTime", "PublishTF.inputs:timeStamp"),
("ReadSimTime.outputs:simulationTime", "PublishClock.inputs:timeStamp"),
("SubscribeJointState.outputs:jointNames", "ArticulationController.inputs:jointNames"),
("SubscribeJointState.outputs:positionCommand", "ArticulationController.inputs:positionCommand"),
("SubscribeJointState.outputs:velocityCommand", "ArticulationController.inputs:velocityCommand"),
("SubscribeJointState.outputs:effortCommand", "ArticulationController.inputs:effortCommand"),
],
og.Controller.Keys.SET_VALUES: [
("ArticulationController.inputs:usePath", True),
("ArticulationController.inputs:robotPath", ROBOT_PRIM_PATH),
("PublishJointState.inputs:topicName", "joint_states"),
("SubscribeJointState.inputs:topicName", "joint_commands"),
],
},
)
set_targets(
prim=stage.GetPrimAtPath(f"{GRAPH_PATH}/PublishJointState"),
attribute="inputs:targetPrim",
target_prim_paths=[ROBOT_PRIM_PATH],
)
You also need this in your physics step function to set off the impulse:
og.Controller.set(og.Controller.attribute(f"{GRAPH_PATH}/OnImpulseEvent.state:enableImpulse"), True)