Skip to content

7 KB

Machine-translated by Robotheca from the original in Chinese (opens in a new tab). License: MIT (opens in a new tab).

ROS 2/C++ Sim2Real v3 Competition Deployment Guide

This workspace contains the final competition ROS 2 Humble/C++ deployment main body. The Odin 1hao.bin used in the competition was not included in the backup archive, and the TensorRT engine is bound to the competition machine environment. Therefore, the default relocal closed-loop mode is not ready to use out of the box; when a real map is missing, use the pure odometry mode as described in the main README.

1. Prerequisites and Environment

Hardware

  • Target Computer: Jetson Orin Nano / Orin NX / AGX Orin running Ubuntu 22.04 LTS.
  • IMU Sensor: Odin integrated IMU, published to /odin1/imu.
  • CAN Bus Adapter: Peak CAN, USB-to-CAN, or onboard SocketCAN interface, using CAN0 and CAN1.

Host Dependencies

  • Operating System: Ubuntu 22.04 LTS (Jammy Jellyfish).
  • ROS 2 Distribution: ROS 2 Humble (Desktop-Base or ROS-Base).
  • C++ Compiler: GCC/G++ 9.0+ with C++17 support.
  • Libraries and ROS 2 Packages:
    • libyaml-cpp-dev
    • libeigen3-dev
    • libusb-1.0-0-dev (Odin USB sensor communication)
    • libpcl-dev and libopencv-dev (3D point cloud and camera processing)
    • ros-humble-navigation2 and ros-humble-nav2-bringup (Nav2 planner/controller servers)
    • ros-humble-pointcloud-to-laserscan (Point cloud to laser scan conversion for AMCL)
    • ros-humble-cv-bridge and ros-humble-pcl-conversions (Image and point cloud processing for Odin sensor drivers)
    • can-utils (SocketCAN validation tools)

2. Local Compilation and Deployment

Follow the steps below to compile and run the entire stack on the host system:

Step 1: Install System Dependencies

sudo apt-get update
sudo apt-get install -y build-essential cmake can-utils libyaml-cpp-dev libeigen3-dev \
    libusb-1.0-0-dev libpcl-dev libopencv-dev ros-humble-navigation2 \
    ros-humble-nav2-bringup ros-humble-pointcloud-to-laserscan \
    ros-humble-cv-bridge ros-humble-pcl-conversions

Step 2: Download ONNXRuntime C++ SDK

The strategy requires the ONNXRuntime library to run inference. It must be downloaded and extracted to a known directory:

# Create directory
sudo mkdir -p /opt/onnxruntime
cd /opt

# For Jetson Orin (ARM64 / aarch64):
sudo wget https://github.com/microsoft/onnxruntime/releases/download/v1.16.3/onnxruntime-linux-aarch64-1.16.3.tgz
sudo tar -zxvf onnxruntime-linux-aarch64-1.16.3.tgz --strip-components=1 -C /opt/onnxruntime

# Or for standard desktop simulation (x86_64 / amd64):
# sudo wget https://github.com/microsoft/onnxruntime/releases/download/v1.16.3/onnxruntime-linux-x64-1.16.3.tgz
# sudo tar -zxvf onnxruntime-linux-x64-1.16.3.tgz --strip-components=1 -C /opt/onnxruntime

Export CMake helper variables:

export ONNXRUNTIME_DIR=/opt/onnxruntime

Step 3: Build the Workspace

Navigate to the package root directory containing src/ and run colcon:

colcon build --merge-install --cmake-args -DCMAKE_BUILD_TYPE=Release

Step 4: Configure SocketCAN Interface

Before starting, activate the CAN interface with a baud rate of 1 Mbps:

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

Verify that the interface is up using ifconfig or ip link.

Step 5: Start the Node

Make the launch script executable and run it:

chmod +x start_sim2real.sh
./start_sim2real.sh

3. Docker Deployment (Recommended)

It is strongly recommended to use Docker to isolate dependencies and avoid library version conflicts on the Jetson Orin.

Step 1: Build the Image

Ensure you are in the sim2real_ros2_v3 directory (which contains the Dockerfile):

# Build using standard docker build:
docker build -t sim2real_ros2:latest .

# Or use Docker Compose:
docker compose build

Step 2: Running the Container

For real hardware deployment, the container must share the host's network stack (for ROS2 DDS and SocketCAN) and have thread priority capabilities for real-time scheduling:

# Option A: Run manually
docker run -it \
  --network host \
  --privileged \
  --cap-add=sys_nice \
  --volume=/dev:/dev \
  --shm-size=2g \
  --name sim2real_ros2_run \
  sim2real_ros2:latest

# Option B: Run via Docker Compose (easiest)
docker compose up -d

4. System Topology and Topics

The control node interacts with sensor drivers and the navigation stack via standard ROS 2 DDS messages:

  • IMU Input: Subscribes to /odin1/imu (sensor_msgs/msg/Imu). The hardware node automatically performs inverse axis rotation (x_raw = -y_ros, y_raw = x_ros) to reconstruct the original coordinate system expected by the RL policy.
  • Control Commands: Subscribes to /cmd_vel and /cmd_vel_stamped (geometry_msgs/msg/Twist / TwistStamped), published by the navigation stack or manual keyboard node.
  • Odometry Input: Subscribes to /odom (nav_msgs/msg/Odometry), relayed and remapped by the odom_relay_node from /odin1/odometry.
  • Emergency Stop: Subscribes to /safety/estop (std_msgs/msg/Bool). Publishing true triggers a software emergency stop, causing the robot to enter a low-stiffness damping brake.
  • Runtime Telemetry: Publishes runtime/state (sim2real_interfaces/msg/RuntimeState), containing current joint velocities, temperatures, IMU outputs, and diagnostic information.
  • Policy Target: Publishes runtime/target (sim2real_interfaces/msg/RuntimeTarget), containing the target joint positions output by the policy inference.

TF Tree

odom ──→ base_link    (broadcast by odom_relay_node)
map  ──→ odom         (published by AMCL / Odin SLAM, depending on the running mode)

5. Integrating ROS 2 Navigation with Sensor Drivers

USB Device Permissions (Odin Sensor)

To run the physical Odin sensor driver (odin_ros_driver), the target computer must have read and write permissions for the sensor's USB interface. Add the following udev rules on the host system:

# 1. Add udev rules
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="2207", ATTR{idProduct}=="0019", MODE="0666", GROUP="plugdev"' | sudo tee /etc/udev/rules.d/99-odin-usb.rules

# 2. Reload udev rules and replug the sensor
sudo udevadm control --reload
sudo udevadm trigger

Integrated Launch Parameters

The unified launch file sim2real_system.launch.py supports modular activation of sensor drivers and the Nav2 navigation stack:

  • launch_driver (default: true): Starts the odin_ros_driver node to obtain IMU and point cloud telemetry.
  • launch_nav2 (default: false): Starts the ROS2 Navigation2 stack on demand; competitions typically use simple_nav_node.py for path tracking.
1. Complete real hardware closed loop (default)

Start the motion control runtime, physical CAN bridge, Odin sensor driver, and Nav2 navigation:

ros2 launch sim2real_bringup sim2real_system.launch.py dry_run:=false launch_driver:=true launch_nav2:=true
2. Dry-Run / Simulation Waypoint Test

Run the strategy executor and Nav2 navigation in dry-run mode (without accessing the CAN bus or physical USB sensors. Suitable for testing navigation topic routing):

ros2 launch sim2real_bringup sim2real_system.launch.py dry_run:=true launch_driver:=false launch_nav2:=true
3. Motion Control Only (No Navigation)

Disable sensor drivers and Nav2, allowing the motion strategy to wait for manual velocity input (e.g., keyboard teleoperation) on /cmd_vel:

ros2 launch sim2real_bringup sim2real_system.launch.py launch_driver:=false launch_nav2:=false

Files by @zeitvex, at commit 1bc9aa5, read from GitHub in your browser. Hardware license: MIT; software license: MIT. Robotheca doesn't review code: read it before running it.