Bring Your Own Robot#
Overview#
This guide walks you through integrating a custom robot arm into Isaac ROS Manipulation.
Each robot family is pluggable: you add a robot description package, a driver utilities
package (Python launch stack and helpers), and point your workflow YAML at your driver
launch through robot_launch_file_path. The bringup stack routes to your code without
editing drivers.launch.py or workflows.launch.py.
At a glance you will:
Add URDF, SRDF, MoveIt, and
ros2_controlconfigurations (withTopicBasedSystemfor Isaac Sim).Implement driver utilities (
DriverConfigsubclass, launch file, parameters, optional sim nodes).Set
robot_launch_file_pathin workflow YAML and declare your package in bringuppackage.xml.Add a launch test and wire cuMotion URDF or XRDF paths.
Use Universal Robots (UR) or Flexiv Rizon in the tree as references.
Package structure#
Most robots use two packages: a robot description package (URDF, SRDF, configurations) and a
driver utilities package (launch, Python helpers), with both typically living under
isaac_ros_manipulation_robots/.
isaac_ros_manipulation_robots/
├── isaac_ros_manipulation_robot_utils/ # RobotControllerBase
├── isaac_ros_manipulation_<robot>_robot_description/ # URDF, SRDF, configurations
├── isaac_ros_manipulation_<robot>_driver_utils/ # Driver launch, config, utilities
└── ... # Additional <robot>_* packages
Two shared base packages define the contract every robot must satisfy:
isaac_ros_manipulation_ros_python_utils–DriverConfigbase class (extended by every robot-specific config such asUrRobotiqDriverConfigandFlexivRizonDriverConfig).isaac_ros_manipulation_robot_utils–RobotControllerBaseabstract class (extended by every robot-specific driver-utilities class such asURDriverUtilsandFlexivDriverUtils) that declares the three abstract methods a custom robot must implement.
Step 1: Create the robot description package#
This package holds all model and configuration files needed by MoveIt, ros2_control,
and robot_state_publisher.
Required contents:
URDF (
urdf/): Xacro file for your robot. For simulation, include aTopicBasedSystemros2_controlhardware interface that maps to Isaac Sim joint command and state topics.SRDF (
srdf/): MoveIt semantic description defining planning groups, home states, passive joints, and collision disable rules.Config files (
config/):initial_positions.yaml– starting joint positionsjoint_limits.yaml– velocity and acceleration limits for MoveItkinematics_sim.yaml– KDL kinematics solver configmoveit_sim_controllers.yaml– MoveIt controller manager configros2_control_controllers_sim.yaml–ros2_controlcontroller definitions (for exampleJointTrajectoryController,JointStateBroadcaster)
Standard ament packaging (
package.xml,setup.pyor CMake) that installs the above into the package share directory.
Note
For simulation with Isaac Sim, the TopicBasedSystem plugin bridges ros2_control
to Isaac Sim through ROS 2 topics. Set the joint_commands_topic and
joint_states_topic parameters to match the topic names configured in your
Isaac Sim Action Graph.
Step 2: Create the driver utilities package#
This package provides the Python launch logic and configuration class for your robot.
Required contents:
- Config class (
config.py): Extend
DriverConfigfromisaac_ros_manipulation_ros_python_utils.config. The base class reads therobot_typelaunch argument (URorFLEXIVtoday, matchingRobotTypenames) and uses it to derive the TF frame prefix (tf_prefixfor UR,robot_snfor Flexiv), arm joint names, and gripper-derived fields (action name, open/close positions, settle time, collision links). Your subclass should callsuper().__init__(context)and optionally assertself.robot_typematches the expected family. Make sure your workflow YAML and driverlaunchfile declare arobot_typelaunch argument (seeur_robotiq_driver.launch.pyorflexiv_rizon_sim_driver.launch.pyfor examples). Parse any additional robot-specific launch arguments (for example robot type, log level) and set up joint state topic remapping for simulation.- Robot description helper (
robot_description.py): A function that processes your URDF xacro with the correct mappings and returns the robot description XML string.
- Driver utilities (
<robot>_driver_utils.py): A class extending
RobotControllerBasefromisaac_ros_manipulation_robot_utils.robot_controller_basethat implements the three abstract methods the framework expects. Each method takes no arguments – everything comes fromself.driver_config:get_robot_state_publisher()– returns therobot_state_publishernode that publishes TF androbot_description.get_moveit_group_node()– returns the MoveItmove_groupnode (plus the matchingMoveItConfigsBuilderbundle) with cuMotion registered as the default planner.get_robot_control_nodes()– returns theros2_control_nodeand controller spawners (joint trajectory controller, joint state broadcaster, gripper controller, …).
Driver launch files instantiate the utility class once and call the methods directly, e.g.
URDriverUtils(driver_config).get_robot_state_publisher(). SeeURDriverUtilsandFlexivDriverUtilsfor reference implementations.Optional sim-only helpers (not part of the abstract contract):
get_isaac_sim_joint_parser_node()– filters Isaac Sim joint states to only the arm joints needed by MoveIt androbot_state_publisher.
- Launch file (
launch/<robot>_driver.launch.py): Declares robot-specific launch arguments, instantiates the config and utility functions, and returns the combined list of nodes.
- Parameters (
params/<robot>.yaml): Default parameter values pointing to files in the robot description package (URDF, SRDF, kinematics, controller configurations).
- Joint parser node (
src/isaac_sim_joint_parser_node.py): A lightweight ROS 2 node that subscribes to the raw Isaac Sim joint states topic, filters out gripper mimic and passive joints, and republishes only the arm joints on a parsed topic.
Step 3: Wire up the bringup routing#
Isaac ROS Manipulation uses a robot_launch_file_path parameter to route to the correct
robot driver at launch time.
The routing flow:
workflows.launch.py
└── drivers.launch.py
└── (reads robot_launch_file_path from config YAML)
└── <robot>_driver.launch.py
To add your robot:
Set
robot_launch_file_pathin your workflow config YAML to point to your driver launch file, typically$(ros2 pkg prefix --share <your_driver_utils_pkg>)/launch/<robot>_driver.launch.py.Add your driver utilities package as a dependency in
isaac_ros_manipulation_bringup/package.xml.
No changes to drivers.launch.py or workflows.launch.py are needed.
drivers.launch.py includes your launch with IncludeLaunchDescription and forwards
the full parameter map from the workflow YAML. Your driver launch should declare launch
arguments for every key your DriverConfig and CoreConfig read from context (see
existing YAML under isaac_ros_manipulation_bringup/params/ and the UR or Flexiv driver
parameter files).
Step 4: Add a test#
Create a launch test that verifies the driver stack starts correctly. A minimal test can:
Launch the driver stack with parameters loaded from workflow-style YAML (for example
isaac_ros_manipulation_bringup/params/sim_launch_params.yaml) overlaid with your robot-specific defaults, or from a small parameter file shipped in your driver utilities package if tests must run whenisaac_ros_manipulation_bringupis not on the path.Subscribe to the
ros2_controlcommand topic (or another stable topic your stack always publishes) and verify messages use the expected joint names.
This validates the full pipeline: URDF processing, ros2_control with
TopicBasedSystem, controller spawning, and MoveIt startup.
Hardware-heavy or long-running launch tests are often skipped unless
ENABLE_MANIPULATOR_TESTING is set appropriately; see
Isaac for Manipulation Testing Guide
for environment variables used across manipulation tests.
Step 5: Create a cuMotion XRDF file#
cuMotion requires an XRDF (Extended Robot Description Format) file for GPU-accelerated motion planning. This file defines collision spheres for each link, configuration space limits (acceleration, jerk), self-collision ignore rules, and tool frames.
Store the XRDF in your robot description package or in
isaac_ros_cumotion_robot_description/xrdf/.
The XRDF file must define:
modifiers: Base frame and attached object frame definitions
default_joint_positions: Default and home joint configuration
cspace: Joint names with acceleration and jerk limits
tool_frames: End-effector frames used for planning
collision: Per-link collision sphere geometry and buffer distances for environment collision avoidance
self_collision: Ignore rules between adjacent or non-colliding link pairs, with per-link buffer distances
Wire the XRDF into your workflow config YAML. Many arms use XRDF files under
isaac_ros_cumotion_robot_description/xrdf/ even when the URDF comes from your own
description package:
cumotion_xrdf_file_path: $(ros2 pkg prefix --share isaac_ros_cumotion_robot_description)/xrdf/<robot>_gripper.xrdf
Set cumotion_urdf_file_path in the same YAML so the planner matches your arm. Ensure
your driver config reads these keys from the launch context so the cuMotion planner plugin
can load them at runtime.
See existing XRDF files in isaac_ros_cumotion_robot_description/xrdf/ for UR and Flexiv
examples.
Reference implementations#
Universal Robots (UR + Robotiq)#
Driver utilities:
isaac_ros_manipulation_robots/isaac_ros_manipulation_ur_driver_utils/Launch:launch/ur_robotiq_driver.launch.py. Defaults:params/ur_robotiq_gripper.yaml.Robot description:
isaac_ros_manipulation_robots/isaac_ros_manipulation_ur_robot_description/(shared UR + Robotiq meshes and configurations).Pattern: Upstream URDF comes from the
ur_descriptionpackage; Isaac-side xacro and sim controllers are layered in the description package. Simulation usesisaac_sim_joint_parser_nodeand gripper helper scripts from driver utilities. Real hardware uses the upstream UR ROS 2 stack.
Flexiv Rizon (Grav gripper)#
Robot description:
isaac_ros_manipulation_robots/isaac_ros_manipulation_flexiv_robot_description/Rizon + Grav xacro, SRDF, MoveIt andros2_controlsim YAML.Driver utilities:
isaac_ros_manipulation_robots/isaac_ros_manipulation_flexiv_driver_utils/Simulation:launch/flexiv_rizon_sim_driver.launch.pywithparams/flexiv_rizon_grav.yaml. Real hardware:launch/flexiv_rizon_real_driver.launch.pycomposes third-partyflexiv_bringup,flexiv_moveit_config, and cuMotion (see package docstring).Pattern: Simulation uses the same TopicBasedSystem and joint parser pattern as UR. On hardware, the Isaac launch file wraps Flexiv ROS 2 packages instead of re-implementing drivers.
Other pointers#
Config base class:
isaac_ros_manipulation_ros_python_utils/–DriverConfigController base class:
isaac_ros_manipulation_robot_utils/–RobotControllerBaseDriver routing:
isaac_ros_manipulation_bringup/launch/drivers.launch.py