Software — Setup, SocketCAN, ROS2 & Controls

Complete software documentation: Ubuntu setup, robot description files (URDF/xacro), the SocketCAN CAN library, ROS2 installation and configuration, and advanced control algorithms.

Ubuntu 22.04 ROS2 Humble SocketCAN URDF MoveIt2 C++ Python
Source: docs.openarm.dev/software/ Last updated: Apr 11, 2026

1. Software Overview

Welcome to the OpenArm software ecosystem! The toolkit is being built for bridging the bimanual robot, and contributions are welcomed.

The software ecosystem provides:

  • Modularized XACRO files for URDF robot models
  • Low-level control APIs for high-frequency motor interaction via SocketCAN
  • ROS2 integration (in active development) with control interfaces and MoveIt2 configurations
  • Control algorithms for system identification, gravity compensation, and Cartesian space control

New users should begin with the Setup Guide. Contributors can find improvement opportunities throughout each section.

Software Repositories

RepositoryDescription
openarm_descriptionURDF/XACRO files for single-arm and bimanual configurations
openarm_canC++ CAN library for Linux-based motor control with Python bindings
openarm_ros2ROS2 middleware integration packages

2. Installing Ubuntu

OpenArm software requires Ubuntu Linux with SocketCAN support. Ubuntu 22.04 LTS (Jammy Jellyfish) is the recommended version.

  1. Download Ubuntu 22.04 LTS. Visit the official Ubuntu download page: ubuntu.com/download/desktop. Download Ubuntu 22.04 LTS.
  2. Create a bootable USB drive.
    • Windows: Download Rufus, select your USB device and the Ubuntu ISO, then write.
    • macOS: Use Balena Etcher or terminal commands.
    • Linux: Use the dd command with your ISO path and USB device identifier.
  3. Boot from USB and install. Insert the bootable USB, restart your system, access BIOS/UEFI settings, and set USB as the primary boot device. Follow the graphical installer to select timezone, username, and password.
    Warning Standard installation will erase all data on the selected drive. Double-check device identifiers before proceeding.
  4. Post-installation: run system updates and install dev tools.
    sudo apt update && sudo apt upgrade -y
    sudo apt install -y curl git build-essential gnome-tweaks
Docker Alternative For development-only scenarios without a dedicated Ubuntu machine, a Docker setup can be used. However, for hardware control with SocketCAN, a native Ubuntu installation is required.

3. OpenArm Setup Guide

This guide walks you through setting up your OpenArm from hardware connections to software testing. Follow each step in order for a successful setup.

Prerequisites

Hardware Requirements

  • OpenArm robotic arm with DAMIAO motors
  • 24 V power supply with appropriate current capacity
  • Cables (those included with the motor package are sufficient)

Communication Device Requirements

PurposeRequired DeviceOS
Motor ID setupDAMIAO USB CAN DebuggerWindows
Motor control & further setupSocketCAN-compatible interfaceUbuntu 22.04 / 24.04 or other Linux with SocketCAN support

Step 1: Motor ID Configuration

Configure each DAMIAO motor with the correct CAN ID before assembly. See the Hardware > Motor ID Configuration section for the full step-by-step procedure.

Use the table below as a quick reference for the transmitter/receiver CAN ID pair assigned to each joint:

JointTransmitter IDReceiver ID
J10x010x11
J20x020x12
J30x030x13
J40x040x14
J50x050x15
J60x060x16
J70x070x17
J80x080x18
Damiao Debugging Tool (Windows) Download the Damiao motor debugging tool to set and verify motor IDs over USB-CAN: Debugging_Tools_v.1.6.8.8.exe. Always test one motor at a time before combining them on the bus.

Step 2: Setup CAN Interface

After hardware assembly, configure the SocketCAN interface on your Ubuntu machine. First install the required packages from the official OpenArm PPA:

# Enable the OpenArm PPA and install all required packages
sudo apt install -y software-properties-common
sudo add-apt-repository -y ppa:openarm/main
sudo apt update
sudo apt install -y \
  can-utils \
  iproute2 \
  libeigen3-dev \
  libopenarm-can-dev \
  liborocos-kdl-dev \
  liburdfdom-dev \
  liburdfdom-headers-dev \
  libyaml-cpp-dev \
  openarm-can-utils

Then bring up the CAN interface using the OpenArm helper (recommended) or manually:

# Recommended — CAN FD 1M nominal / 5M data baud
openarm-can-configure-socketcan can0 -fd -b 1000000 -d 5000000

# CAN 2.0 (1M baud, no FD)
openarm-can-configure-socketcan can0

# For a 4-arm setup (can0 through can3)
openarm-can-configure-socketcan-4-arms -fd

# Verify the interface is UP
ip link show can0
One CAN Port Per Arm Each arm requires a dedicated CAN interface. A single-arm setup uses can0. A bimanual setup uses can0 (right leader) + can1 (left leader) + can2 (right follower) + can3 (left follower).

CAN FD vs CAN 2.0

OpenArm motors support both CAN 2.0 (classic CAN, 8-byte payload) and CAN FD (Flexible Data-rate, up to 64-byte payload at higher data rates). CAN FD is recommended for the full 5 Mbit/s data bandwidth used by Damiao motors.

ModeNominal BaudData BaudPayload
CAN 2.01 Mbit/s8 bytes
CAN FD1 Mbit/s5 Mbit/sup to 64 bytes

Manual ip link commands (CAN 2.0):

sudo ip link set can0 down
sudo ip link set can0 type can bitrate 1000000
sudo ip link set can0 up

Manual ip link commands (CAN FD — 1M / 5M):

sudo ip link set can0 down
sudo ip link set can0 type can bitrate 1000000 dbitrate 5000000 fd on
sudo ip link set can0 up

Manual Motor Control Commands

Use these commands for low-level debugging and to verify motor communication before running higher-level code. Always monitor the bus first:

# Monitor all CAN frames on the bus
candump -x can0

# Change motor baudrate (replace --canid with target motor ID)
openarm-can-change-baudrate --baudrate 5000000 --canid 1 --socketcan can0
# Add --flash to persist across power cycles (max ~10,000 flash writes per motor)
openarm-can-change-baudrate --baudrate 5000000 --canid 1 --socketcan can0 --flash

CAN 2.0 motor control (replace 001 with target motor's transmitter ID):

# Clear motor error
cansend can0 001#FFFFFFFFFFFFFFFB
# Enable motor
cansend can0 001#FFFFFFFFFFFFFFFC
# Disable motor
cansend can0 001#FFFFFFFFFFFFFFFD

CAN FD motor control (note the extra #1 after ## indicating BRS flag):

# Clear motor error
cansend can0 001##1FFFFFFFFFFFFFFFB
# Enable motor
cansend can0 001##1FFFFFFFFFFFFFFFC
# Disable motor
cansend can0 001##1FFFFFFFFFFFFFFFD
Test One Motor at a Time When first commissioning motors, connect and test each motor individually before daisy-chaining multiple motors on the same CAN bus. This makes it easier to identify ID conflicts or wiring faults.

Motor LED Status

Each Damiao motor has an onboard LED that indicates its current state:

LED PatternMeaning
Green (steady)Motor enabled and ready
Red (steady)Motor disabled
Red (flashing)Motor error state — send Clear Error command before re-enabling

CAN Troubleshooting Resources

Step 3: Motor Test

After configuring the CAN interface, test motor communication by running the test utilities from the openarm_can repository. Verify that all 8 joints respond to position commands and return encoder feedback.

Setup Pathway Summary

StepDescription
0Prerequisites — hardware, cables, CAN adapter
1Motor ID Configuration (Windows + Damiao Tools)
2Setup CAN Interface (openarm-can-configure-socketcan)
3Motor Test — verify joint communication
4Motor Configuration — tune control parameters
5Hands-On: Demo Run

4. Robot Description (URDF/xacro)

The openarm_description package contains URDF/xacro files for single-arm and bimanual robot configurations, used in simulation and motion planning.

Directory Structure

  • robot/openarm_robot.xacro — Main robot file
  • robot/v10.urdf.xacro — Version-specific URDF
  • Separate directories for arm kinematics, body assembly, end-effectors, and ROS2 control
  • config/ — Version-specific parameter files

Installation

# Ensure ROS2 is installed (see Section 6)
# Set environment variables
export ROS_DISTRO=humble
export COLCON_WS=~/ros2_ws

# Clone the repository
git clone https://github.com/enactic/openarm_description.git \
  $COLCON_WS/src/openarm_description

# Build
cd $COLCON_WS
colcon build --packages-select openarm_description

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

URDF Generation Examples

# Single arm with hand
xacro robot/openarm_robot.xacro arm_type:=right end_effector:=hand

# Single arm without end-effector
xacro robot/openarm_robot.xacro arm_type:=right end_effector:=none

# Bimanual setup with ROS2 control
xacro robot/openarm_robot.xacro bimanual:=true ros2_control:=true

# Simulation version with fake hardware
xacro robot/openarm_robot.xacro simulation:=true

RViz Visualization

The package includes launch files for RViz visualization for both single-arm and bimanual configurations:

# Launch single-arm visualization
ros2 launch openarm_description display.launch.py

# Launch bimanual visualization
ros2 launch openarm_description display_bimanual.launch.py

Configuration Arguments

Customizable parameters include: arm/body types, end-effector selection, bimanual mode, CAN interfaces, positioning offsets, and ROS2 control settings.

Multi-Robot Setup

Multiple instances can run using ROS namespacing and ROS_DOMAIN_ID environment variables for network isolation:

# Right arm on domain 0
export ROS_DOMAIN_ID=0
ros2 launch openarm_description display.launch.py namespace:=/right_arm

# Left arm on domain 1 (separate terminal)
export ROS_DOMAIN_ID=1
ros2 launch openarm_description display.launch.py namespace:=/left_arm

5. CAN Library (openarm_can)

The OpenArm CAN library is the primary communication bridge between high-level OpenArm control applications and low-level motor protocols. It leverages Linux's SocketCAN interface for motor control and state monitoring.

Architecture

The library uses a three-layer structure:

  • can/socket — High-level components: OpenArm, ArmComponent, GripperComponent
  • damiao_motor — Motor protocol layer (Damiao MIT mode)
  • canbus — Low-level CAN communication (Linux SocketCAN)

Key Classes

ClassDescription
OpenArmManages the CAN socket and all motor components globally
ArmComponentCoordinates multiple arm motors as an integrated system
GripperComponentManages single motor operations with gripper-specific functions: open(), close(), set_position()
DMDeviceCollectionProvides shared motor operations including bulk control and parameter queries

Motor Control Method

Motors use the Damiao Motor protocol with MIT control mode using MITParam parameters:

// MITParam structure: {kp, kd, q, dq, tau}
// kp  - position gain
// kd  - velocity gain
// q   - desired position (rad)
// dq  - desired velocity (rad/s)
// tau - feedforward torque (Nm)

MITParam params;
params.kp = 10.0;
params.kd = 0.5;
params.q = target_position;
params.dq = 0.0;
params.tau = 0.0;

arm.send_mit_control(joint_id, params);

Implementation Workflow

  1. Initialize OpenArm with CAN interface. Create an OpenArm instance pointing to your CAN interface (e.g., can0).
  2. Register motor devices with type and CAN IDs. Specify sender ID, receiver ID, and motor model for each joint.
  3. Enable motors and configure callback mode. Use STATE callback mode for control responses; PARAM for parameter queries.
  4. Execute control via MIT parameters. Send position/velocity/torque commands at up to 1000 Hz.
  5. Monitor feedback frames. Read back joint states at your desired frequency.

Configuration Notes

  • Vector lengths for motor types, send IDs, and receive IDs must match exactly
  • Timeout values: 1000–2000 microseconds for slow operations; 300–500 for fast control loops
  • Control cycle frequency should not exceed 1000 Hz for 8-motor setups
  • Use STATE callback mode for control; PARAM for parameter queries

6. ROS2 Integration

OpenArm has native ROS2 support including URDF/XACRO models, ros2_controllers integration, gravity compensation, impedance control, and a complete MoveIt2 planning group configuration.

Installing ROS2 Humble (Recommended)

# Install ROS2 Humble desktop package
sudo apt install -y ros-humble-desktop

# Install OpenArm-specific controller packages
sudo apt install -y \
  ros-humble-ros2-control \
  ros-humble-ros2-controllers \
  ros-humble-controller-manager \
  ros-humble-gripper-controllers \
  ros-humble-hardware-interface

# MoveIt2 users — install additional packages
sudo apt install -y \
  ros-humble-moveit \
  ros-humble-forward-command-controller

# Source the ROS2 environment (add to ~/.bashrc for persistence)
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc

# Verify installation
ros2 -h
ros2 topic list

Installing ROS2 Jazzy (Alternative)

# For Ubuntu 24.04 or Jazzy users
sudo apt install -y ros-jazzy-desktop

# Install controller packages (jazzy-specific names)
sudo apt install -y \
  ros-jazzy-ros2-control \
  ros-jazzy-ros2-controllers \
  ros-jazzy-controller-manager

# Source
echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc
source ~/.bashrc
Jazzy Status The Jazzy distribution is under development and may have stability issues with OpenArm packages. Humble is recommended for production use.

openarm_ros2 Repository Setup

# Create workspace and clone
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/enactic/openarm_ros2.git

# Install dependencies
cd ~/ros2_ws
rosdep install --from-paths src --ignore-src -r -y

# Build
colcon build --symlink-install

# Source workspace
source install/setup.bash

ROS2 Features

  • Control interfaces for joint position, velocity, and effort
  • MoveIt2 planning group configuration for single-arm and bimanual setups
  • Gravity compensation out of the box
  • Impedance control
  • Hardware interface plugin for ros2_control

7. Advanced Controls

The advanced controls section is an actively developed area for control guides and algorithms.

Coming Soon Detailed documentation for each control mode is being prepared. Contributions are welcomed — see the Contribution Guide.

System Identification

Procedures for characterizing the OpenArm's dynamics including joint friction, inertia, and damping parameters. Documentation coming soon.

Gravity Compensation

Gravity compensation keeps the arm weightless (compliant) by computing and canceling gravity torques at each joint in real time. This is essential for safe teleoperation. Implementation documentation coming soon.

Cartesian Space Control

Control the arm's end-effector in Cartesian space (XYZ position + orientation) rather than joint space. Uses inverse kinematics (IK) to convert Cartesian commands to joint commands. Documentation coming soon.

Friction Compensation Model

The teleoperation stack uses a tanh-based friction compensation model applied per joint:

# Friction compensation formula
# tau_f = Fc * tanh(k * dq) + Fv * dq + Fo
#
# Fc  - static friction level
# k   - friction transition sharpness
# Fv  - viscous friction coefficient
# Fo  - friction offset
# dq  - joint velocity

tau_f = Fc * tanh(k * dq) + Fv * dq + Fo

Per-joint parameters (Kp, Kd, Fc, k, Fv, Fo) are configurable in the control configuration files.

Attribution Content on this page is based on the official OpenArm documentation at docs.openarm.dev, copyright © 2025–2026 Enactic, Inc.
← Hardware Teleoperation →