Skip to main content
Version: 2.0

OpenArm Description Package

Overview​

This OpenArm description package contains URDF/xacro description files for the OpenArm robot system, supporting both v1.0 and v2.0 hardware in bimanual configuration.

Table of Contents​


Supported Robot Versions​

Versionarm_type valuesConfiguration style
OpenArm v1.0v10, v1.0, v1_0, openarm_v10, openarm_v1.0Per-argument (ee_type, ...)
OpenArm v2.0v20, v2.0, v2_0, openarm_v20, openarm_v2.0, openarm_v2_0Preset-based (robot_preset)

Both versions share the same launch file and entry point. The arm_type argument determines which hardware and xacro files are loaded.


Xacro Structure​

Assets are organized per robot version under assets/robot/:

assets/
├── robot/
│ ├── openarm_v1.0/
│ │ ├── config/ # Kinematics, joint limits, inertials
│ │ ├── mesh/ # STL and DAE mesh files
│ │ └── urdf/
│ │ ├── openarm_v10.urdf.xacro # Entry point for v1.0
│ │ ├── arm/
│ │ ├── body/
│ │ ├── ee/
│ │ └── ros2_control/
│ └── openarm_v2.0/
│ ├── config/
│ │ ├── arm/ # Joint limits, inertials, kinematics
│ │ ├── body/ # Body link parameters
│ │ └── robot_presets/ # Preset YAML files
│ ├── meshes/ # STL and DAE mesh files
│ └── urdf/
│ ├── openarm_v20.urdf.xacro # Entry point for v2.0
│ ├── ros2_control/
│ └── utils/
└── end_effector/
├── parallel_link/ # Used in v1.0
└── pinch_gripper/ # Used in v2.0

v2.0 Robot Presets​

v2.0 uses a preset-based system. A single robot_preset argument selects the full robot configuration:

PresetDescription
default_bimanualBody, both left and right arms, and a pinch gripper on each arm (default)
right_armRight arm only, without a gripper
left_armLeft arm only, without a gripper
right_arm_with_pinch_gripperRight arm with pinch gripper
left_arm_with_pinch_gripperLeft arm with pinch gripper

Each preset is a YAML file in assets/robot/openarm_v2.0/config/robot_presets/. A preset lists the components of the robot (body, primary_arm, secondary_arm, and an end effector for each arm), and each component has:

KeyDescription
enabledWhether the component is included in the URDF.
productThe product of the component, such as openarm_v2.0 or pinch_gripper.
prefixThe prefix of the link and joint names, such as openarm_left_.
connectionWhere the component is attached, such as attach_to: body and parent_reference_point: left_arm_mount_point.
reflectMirroring of the component. The left arm is the mirrored right arm.

To use your own configuration, add a new YAML file to the robot_presets directory based on an existing preset, and pass its file name without .yaml as robot_preset.

The URDF generated with default_bimanual has the following links and joints. <side> is left or right.

NameTypeDescription
worldlinkRoot frame
openarm_body_link0linkBody
openarm_<side>_base_linklinkBase of the arm
openarm_<side>_link1 … openarm_<side>_link6linkArm links
openarm_<side>_joint1 … openarm_<side>_joint7revolute jointArm joints
openarm_<side>_ee_base_linklinkBase of the pinch gripper. openarm_<side>_joint7 connects openarm_<side>_link6 to this link, because the empty link7 is collapsed by collapse_internal_empty_links
openarm_<side>_ee_link1, openarm_<side>_ee_link2linkFingers of the pinch gripper
openarm_<side>_finger_joint1revolute jointGripper joint
openarm_<side>_finger_joint2revolute jointMimics openarm_<side>_finger_joint1
openarm_<side>_grasp_framelinkGrasp frame. Only with emit_grasp_frame:=true

Installation​

To use this package, make sure you have ROS2 installed. Then set up the workspace:

# Set up environment variables if you haven't already (customize as needed)
export ROS_DISTRO=humble # Change to your ROS2 distro (humble, iron, jazzy, etc.)
export ROS_WS=~/ros2_ws # Customize workspace path

# Head to the workspace
cd $ROS_WS/src

# Source your ros2 distro
source /opt/ros/$ROS_DISTRO/setup.bash

# Clone the package
git clone https://github.com/enactic/openarm_description.git

# Build the workspace
cd $ROS_WS
colcon build

# Source the workspace
source $ROS_WS/install/setup.bash

Universal Robot Description Files (URDF)​

The coordinate transforms of each link and joint constraints of OpenArm are defined in the URDF. ROS2 uses an XML macro language called xacro to generate these files.

Visualization​

To display the robot in RViz with a simple joint state GUI:

tip

If you're receiving errors regarding the .dae files, try changing mesh formats to .stl or .obj.

OpenArm v2.0​

# Bimanual (default)
ros2 launch openarm_description display_openarm.launch.py arm_type:=v2.0

# Right arm only
ros2 launch openarm_description display_openarm.launch.py arm_type:=v2.0 robot_preset:=right_arm

# Left arm only
ros2 launch openarm_description display_openarm.launch.py arm_type:=v2.0 robot_preset:=left_arm

# Right arm with pinch gripper
ros2 launch openarm_description display_openarm.launch.py arm_type:=v2.0 robot_preset:=right_arm_with_pinch_gripper

# Left arm with pinch gripper
ros2 launch openarm_description display_openarm.launch.py arm_type:=v2.0 robot_preset:=left_arm_with_pinch_gripper

# Bimanual with grasp frame
ros2 launch openarm_description display_openarm.launch.py arm_type:=v2.0 emit_grasp_frame:=true
OpenArm v2.0 Bimanual URDF RViz

OpenArm v1.0​

ros2 launch openarm_description display_openarm.launch.py arm_type:=v1.0
OpenArm v1.0 Bimanual URDF RViz

Generate URDF Files​

OpenArm v2.0​

# Bimanual
xacro $(ros2 pkg prefix openarm_description)/share/openarm_description/assets/robot/openarm_v2.0/urdf/openarm_v20.urdf.xacro \
robot_preset:=default_bimanual > openarm_v20_bimanual.urdf

# Right arm only
xacro $(ros2 pkg prefix openarm_description)/share/openarm_description/assets/robot/openarm_v2.0/urdf/openarm_v20.urdf.xacro \
robot_preset:=right_arm > openarm_v20_right_arm.urdf

# Right arm with pinch gripper
xacro $(ros2 pkg prefix openarm_description)/share/openarm_description/assets/robot/openarm_v2.0/urdf/openarm_v20.urdf.xacro \
robot_preset:=right_arm_with_pinch_gripper > openarm_v20_right_arm_pinch.urdf

# Bimanual for the real hardware
xacro $(ros2 pkg prefix openarm_description)/share/openarm_description/assets/robot/openarm_v2.0/urdf/openarm_v20.urdf.xacro \
use_fake_hardware:=false right_can_interface:=can0 left_can_interface:=can1 can_fd:=true > openarm_v20_bimanual_hw.urdf
note

The v2.0 URDF always includes the ros2_control section for both arms. By default (use_fake_hardware:=true), it uses mock_components/GenericSystem. To control the real hardware, pass use_fake_hardware:=false, which uses openarm_hardware/OpenArmHW with the CAN interfaces and the control gains in config/arm/control/control_gains.yaml. openarm_bringup in openarm_ros2 passes these arguments for you.

OpenArm v1.0​

# Bimanual
xacro $(ros2 pkg prefix openarm_description)/share/openarm_description/assets/robot/openarm_v1.0/urdf/openarm_v10.urdf.xacro \
arm_type:=v10 > openarm_v10_bimanual.urdf

# Bimanual with ROS2 control
xacro $(ros2 pkg prefix openarm_description)/share/openarm_description/assets/robot/openarm_v1.0/urdf/openarm_v10.urdf.xacro \
arm_type:=v10 ros2_control:=true left_can_interface:=can1 right_can_interface:=can0 > openarm_v10_bimanual_control.urdf

# Bimanual with fake hardware for simulation
xacro $(ros2 pkg prefix openarm_description)/share/openarm_description/assets/robot/openarm_v1.0/urdf/openarm_v10.urdf.xacro \
arm_type:=v10 ros2_control:=true use_fake_hardware:=true > openarm_v10_bimanual_sim.urdf

Available Arguments​

Below are some configurable variables for the OpenArm robot description that allow customization when generating URDFs with xacro.

Common Arguments​

ArgumentDefaultDescription
arm_typev20Robot version. See Supported Robot Versions for accepted values.
rviz_configbimanual.rvizRViz config file to load

v2.0 Arguments​

ArgumentDefaultDescription
robot_presetdefault_bimanualRobot configuration preset (see preset table above)
collapse_internal_empty_linkstrueCollapse empty intermediate links in the URDF
emit_grasp_framefalseAdd a grasp frame link (openarm_<side>_grasp_frame) to each end-effector
use_fake_hardwaretrueUse mock_components/GenericSystem instead of the real hardware interface in the ros2_control section
left_can_interfacecan1CAN interface for the left arm
right_can_interfacecan0CAN interface for the right arm
can_fdtrueUse CAN FD. Set to false for a classic CAN interface

display_openarm.launch.py passes only arm_type, robot_preset, collapse_internal_empty_links and emit_grasp_frame to the v2.0 xacro. Pass the other arguments to xacro directly.

v1.0 Arguments​

ArgumentDefaultDescription
ros2_controlfalseEnable ROS2 control hardware interface
use_fake_hardwarefalseUse fake hardware for simulation
fake_sensor_commandsfalseEnable fake sensor commands
left_can_interfacecan1CAN interface for left arm
right_can_interfacecan0CAN interface for right arm

v1.0 Positioning Arguments​

ArgumentDefaultDescription
parentworldParent frame
xyz0 0 0Position offset
rpy0 0 0Orientation offset
left_arm_base_xyz0.0 0.031 0.698Left arm base position
left_arm_base_rpy-1.5708 0 0Left arm base orientation
right_arm_base_xyz0.0 -0.031 0.698Right arm base position
right_arm_base_rpy1.5708 0 0Right arm base orientation

Running Multiple Robots with ROS Namespaces and ROS_DOMAIN_ID​

When running multiple instances of OpenArm, one option is to namespace arms to control multiple sets of arms with one device.

For example, when running multiple instances of bimanual, it is possible to namespace packages with:

ros2 launch openarm_bringup openarm.bimanual.launch.py arm_type:=v2.0 arm_prefix:=leader right_can_interface:=can0 left_can_interface:=can1

and

ros2 launch openarm_bringup openarm.bimanual.launch.py arm_type:=v2.0 arm_prefix:=follower right_can_interface:=can2 left_can_interface:=can3

If network isolation is required (e.g. multiple sets of OpenArm teleoperation), the ROS_DOMAIN_ID environment variable can be set.