ROS 2 Topic Reference
Complete reference of the ROS 2 topics exposed by the robot's onboard software over CycloneDDS.
There is no separate driver node to run. The core software (Network / DdsBridge) speaks ROS 2-compatible DDS directly, so ros2 topic, rviz2, and rqt interoperate with the robot without launching any bridge process. (The legacy rbq_driver node and start_ros_driver.bash are removed — the script is now a deprecated no-op.)
- Pub — robot publishes, your node subscribes
- Sub — your node publishes, robot subscribes
Custom message types (rbq_msgs/*, api/*) require sourcing the built workspace:
source rbq_sdk/ros2/install/setup.bashTopics whose name contains a token starting with
_(e.g./rbq/_sim,/rbq/_user_command,/rbq/ref/motion/_0) are hidden —ros2 topic listshows them only with--include-hidden-topics.
Publish rate —
Network/DdsBridgerepublishes every Pub state topic in one ~500 Hz loop, so theHzbelow is that publish rate (measured withros2 topic hz), not the underlying sensor/value update rate.
Motion Commands
/rbq/cmd/auto_start
| Field | Value |
|---|---|
| Type | std_msgs/Bool |
| Direction | Sub |
| Description | Full initialization sequence: CAN check → Find Home → Control Start. Robot must be in the correct initial pose. Monitor progress via /rbq/robot_status (can_check, find_home, con_start flags). |
/rbq/cmd/switch_gait
| Field | Value |
|---|---|
| Type | std_msgs/Int8 |
| Direction | Sub |
| Description | Switch to the target gait by gait_id. See Gait State Reference below. |
/rbq/cmd/switch_control_mode
| Field | Value |
|---|---|
| Type | std_msgs/Bool |
| Direction | Sub |
| Description | true → HighLevel Command mode (accepts /rbq/cmd/high_level). false → Joystick mode (default). |
/rbq/cmd/emergency
| Field | Value |
|---|---|
| Type | std_msgs/Bool |
| Direction | Sub |
| Description | Immediately set all joints to high-damping mode. Robot collapses instantly. Sit the robot down first if testing. |
/rbq/cmd/dock
| Field | Value |
|---|---|
| Type | std_msgs/Int8MultiArray |
| Direction | Sub |
| Description | Start the auto-docking sequence. data[0]: walk mode — 0 = wave (default), 1 = trot. data[1]: vision mode — 0 = blind (default), 1 = vision height feedback (trot only). Robot must be in Standing mode and the rear camera must see the ArUco marker (≤ 5 m). Monitor via robot_status.docking_state. |
/rbq/ref/payload_params
| Field | Value |
|---|---|
| Type | std_msgs/Float64MultiArray |
| Direction | Sub |
| Description | Set external payload parameters for CoM compensation. data: [mass_kg, com_x, com_y, com_z] (meters). Used when carrying additional loads. |
Gait State Reference
One gait enum is used in both directions: send it on HighLevelCommand.gait_state (also used by switch_gait), and read the same value back on robot_status.gait_id.
gait_id | Name | Description |
|---|---|---|
-2 | Fall Mode | Triggered by unexpected loss of balance |
-1 | Control Off | All actuators disabled |
0 | Sitting | Low posture, resting on ground |
1 | Standing | Neutral posture, ready to walk |
2 | Aim Mode | Aiming posture for targeting |
3 | Walk (Trot) | Walking trot gait |
4 | Stairs | Stair-adaptive gait (uses camera) |
5 | Wave | Walking wave gait |
6 | Run | High-speed gait (if supported) |
30 | RL Trot | Reinforcement Learning trot |
31 | RL Front Walk | RL forward walking |
33 | RL Left Walk | RL left-side walking |
34 | RL Right Walk | RL right-side walking |
35 | RL Bound | RL bounding gait |
36 | RL Pace | RL pace gait |
37 | RL Pronk | RL pronk gait |
38–41 | RL 3-Leg | RL 3-legged gaits (HR, HL, FR, FL) |
42 | RL Trot Vision | RL trot with vision integration |
45 | RL Trot Run | RL high-speed trot |
46 | RL Silent | RL silent gait |
47 | RL Stairs | RL stair gait |

High-Level Control
/rbq/cmd/high_level
| Field | Value |
|---|---|
| Type | rbq_msgs/HighLevelCommand |
| Direction | Sub |
| Description | Velocity and posture command. Behavior and valid ranges depend on the current gait. Requires HighLevel mode (switch_control_mode: true). |
Fields:
| Field | Type | Unit | Description |
|---|---|---|---|
header | std_msgs/Header | — | ROS header with timestamp |
identifier | string | — | Optional label for logging/tracking |
roll | float32 | deg | Body roll. Standing [-25, +25] |
pitch | float32 | deg | Body pitch. Standing [-20, +20], Walk (body tilt angle), RL Walk [-25, +25] |
yaw | float32 | deg | Body yaw twist. Standing [-25, +25] |
vel_x | float32 | m/s | Forward speed. Walk [-1.0, +1.2] / Run [-1.0, +1.8] / RL Trot [-1.5, +2.0] / RL Walk [-1.5, +2.5] / Stairs [-1.0, +1.0] |
vel_y | float32 | m/s | Lateral speed. Walk [-0.4, +0.4] / Run [-0.6, +0.6] / RL Trot [-1.0, +1.0] / RL Walk [-1.0, +1.0] / Stairs [-0.4, +0.4] |
omega_z | float32 | deg/s | Yaw rate. Walk [-75, +75] / Stairs [-17, +17] / Wave [-20, +20] / RL Walk [-86, +86] |
delta_body_h | float32 | m | Body height offset from default. Standing/Walk [-0.15, +0.05] / RL Walk [-0.25, +0.10] |
delta_foot_h | float32 | m | Swing foot lift offset. [-0.06, +0.04] |
gait_state | int8 | — | Target gait ID (see Gait State Reference) |
gait_transition | bool | — | true = transition to gait_state first, then apply command |
Example commands:
# Walk forward at 0.5 m/s (gait_state: 3 = Walk/Trot)
ros2 topic pub --once /rbq/cmd/high_level rbq_msgs/msg/HighLevelCommand \
'{header: {stamp: {sec: 0, nanosec: 0}, frame_id: "base"},
identifier: "walk_fwd", roll: 0.0, pitch: 0.0, yaw: 0.0,
vel_x: 0.5, vel_y: 0.0, omega_z: 0.0,
delta_body_h: 0.0, delta_foot_h: 0.0,
gait_state: 3, gait_transition: false}'
# Rotate in place at 30°/s
ros2 topic pub --once /rbq/cmd/high_level rbq_msgs/msg/HighLevelCommand \
'{header: {stamp: {sec: 0, nanosec: 0}, frame_id: "base"},
identifier: "turn", roll: 0.0, pitch: 0.0, yaw: 0.0,
vel_x: 0.0, vel_y: 0.0, omega_z: 30.0,
delta_body_h: 0.0, delta_foot_h: 0.0,
gait_state: 3, gait_transition: false}'
# Stop (zero velocity)
ros2 topic pub --once /rbq/cmd/high_level rbq_msgs/msg/HighLevelCommand \
'{header: {stamp: {sec: 0, nanosec: 0}, frame_id: "base"},
identifier: "stop", roll: 0.0, pitch: 0.0, yaw: 0.0,
vel_x: 0.0, vel_y: 0.0, omega_z: 0.0,
delta_body_h: 0.0, delta_foot_h: 0.0,
gait_state: 3, gait_transition: false}'
# Custom standing posture (roll: 15°, pitch: 30°, yaw: 20°)
ros2 topic pub --once /rbq/cmd/high_level rbq_msgs/msg/HighLevelCommand \
'{header: {stamp: {sec: 0, nanosec: 0}, frame_id: "base"},
identifier: "standing_pose", roll: 15.0, pitch: 30.0, yaw: 20.0,
vel_x: 0.0, vel_y: 0.0, omega_z: 0.0,
delta_body_h: 0.0, delta_foot_h: 0.0,
gait_state: 1, gait_transition: true}'/rbq/cmd/navigate_to
| Field | Value |
|---|---|
| Type | geometry_msgs/Pose2D |
| Direction | Sub |
| Description | Move to an absolute world-frame pose. x, y set the target position in meters; theta sets the target yaw in radians. Available in Standing and Wave modes. |
/rbq/cmd/target_go
| Field | Value |
|---|---|
| Type | rbq_msgs/TargetGo |
| Direction | Sub |
| Description | Relative "go to target" navigation command (gait, mode, x/y/theta, offsets, and slow/wide/vision flags). See the Target-Go example. |
Robot Status
/rbq/robot_status
| Field | Value |
|---|---|
| Type | rbq_msgs/RobotStatus |
| Direction | Pub |
| Hz | 500 |
| Description | Overall robot status flags, gait state, and docking progress. |
Fields:
| Field | Type | Description |
|---|---|---|
header | std_msgs/Header | ROS header |
con_start | bool | Motor control enabled |
ready_pos | bool | Robot is in ready position |
ground_pos | bool | Robot is in ground/sitting position |
force_con | bool | Force control mode active |
ext_joy | bool | External joystick connected |
is_standing | bool | Robot is physically standing |
can_check | bool | CAN communication verified |
find_home | bool | Encoder homing complete |
gait_id | int8 | Current gait. See Gait State Reference. |
is_fall | bool | Fall detected |
docking_state | int8 | Docking progress (see table below) |
imu_success | bool | IMU connected and operational |
Docking State Values:
| Value | Constant | Description |
|---|---|---|
-6 | DOCKING_MAX_FAIL_CNT_REACHED | Max retry count (10×) reached — aborted |
-5 | DOCKING_MARKER_POS_INVALID_ROTATION | Marker rotation > ±40° — aborted |
-4 | DOCKING_MARKER_POS_INVALID_TOO_FAR | Marker > 5 m — aborted |
-3 | DOCKING_MARKER_POS_INVALID_WRONG_DIR | Marker detected on front side — aborted |
-2 | DOCKING_MARKER_NOT_FOUND | Marker not found — aborted |
-1 | DOCKING_FAILED | Docking failed — auto retry |
0 | DOCKING_OPERATION_MODE | Normal operation (not docking) |
1 | DOCKING_APPROACH_OFFSET | Stage 1: offset approach |
2 | DOCKING_APPROACH | Stage 2: direct approach |
3 | DOCKING_APPROACH_WIDE | Stage 3: wide-stance approach |
4 | DOCKING_SIT_DOWN | Sitting down to connect |
5 | DOCKING_SUCCESS | Docked — charger physically connected |
6 | DOCKING_SUCCESS_CHARGING | Docked and charging |
7 | DOCKING_SUCCESS_NO_CHARGING | Docked but not charging |
/rbq/system_log
| Field | Value |
|---|---|
| Type | rbq_msgs/SystemLog |
| Direction | Pub |
| Description | Robot-side log stream. Fields: header, string log_level, string log_msg. |
State Estimation
/rbq/odometry
| Field | Value |
|---|---|
| Type | nav_msgs/Odometry |
| Direction | Pub |
| Hz | 500 |
| Description | Body pose and velocity in the world frame. Origin resets at startup. Fused from IMU and leg odometry. |
/rbq/foot_states
| Field | Value |
|---|---|
| Type | rbq_msgs/FootStates |
| Direction | Pub |
| Hz | 500 |
| Description | Foot positions, velocities, and contact states for all 4 legs relative to the body center frame. |
Fields:
| Field | Type | Description |
|---|---|---|
header | std_msgs/Header | ROS header |
foot_position_rt_body | geometry_msgs/Point[4] | Foot position relative to body center. +X=forward, +Y=left, +Z=up |
foot_velocity_rt_body | geometry_msgs/Point[4] | Foot velocity relative to body frame |
foot_contact_est | uint8[4] | Contact state per foot: 0 = CONTACT_LOST, 1 = CONTACT_MADE |
foot_force_est | float32[4] | Estimated contact force [N] |
Leg order: [0] = Front-Left, [1] = Front-Right, [2] = Rear-Left, [3] = Rear-Right
Sensor Feedback
/rbq/imu
| Field | Value |
|---|---|
| Type | sensor_msgs/Imu |
| Direction | Pub |
| Hz | 500 |
| Description | Raw IMU data. Sensor offset from body center: (0.00665, 0.0, -0.0404) m. Frame: +X = forward, +Y = left, +Z = up. Angular velocity range ±2000 °/s, acceleration range ±16 g. |
/rbq/joint_states
| Field | Value |
|---|---|
| Type | sensor_msgs/JointState |
| Direction | Pub |
| Hz | 500 |
| Description | Joint positions [rad], velocities [rad/s], and efforts [Nm] for all 12 leg joints in standard ROS format. |
/rbq/leg_joint
| Field | Value |
|---|---|
| Type | rbq_msgs/LegJointInfo |
| Direction | Pub |
| Hz | 500 |
| Description | Detailed per-joint status for all 12 leg joints. LegJointInfo wraps JointInfo[12] joint — one JointInfo per joint (there is no JointStatus message). |
Joint order (conventional): [0]HRR [1]HRP [2]HRK [3]HLR [4]HLP [5]HLK [6]FRR [7]FRP [8]FRK [9]FLR [10]FLP [11]FLK — but each joint[i] carries its own 3-letter name, which is the authoritative identifier.
JointInfo fields (each element of joint[12]):
| Field | Type | Unit | Description |
|---|---|---|---|
pos | float32 | rad | Measured position |
vel | float32 | rad/s | Angular velocity |
acc | float32 | rad/s² | Angular acceleration |
torque | float32 | N·m | Measured torque |
kp | float32 | Nm/rad | Position gain |
kd | float32 | Nm·s/rad | Damping gain |
owner | int8 | — | Process owning the joint (0–40) |
ref_ff_torque | float32 | N·m | Reference feed-forward torque |
ref_position | float32 | rad | Reference (target) position |
ref_vel | float32 | rad/s | Reference velocity |
current | float32 | A | Motor current |
temperature_board | int8 | °C | Control board temperature |
temperature_coil | int8 | °C | Motor coil temperature |
name | string≤3 | — | 3-letter joint name, e.g. "HRR" |
status | string≤3 | — | 3-letter lifecycle: NON/CON/HOM/RUN |
error_msg | string≤3 | — | 3-letter error code, e.g. "JAM", "OK" |
Torque limits: Roll/Pitch ±104 Nm — Knee −70 / +140 Nm
Power Control
/rbq/cmd/switch_power
| Field | Value |
|---|---|
| Type | std_msgs/Int8MultiArray |
| Direction | Sub |
| Description | Toggle a PDU power port. data: [port_id, state] — state: 1=ON, 0=OFF. |
Port ID Reference:
port_id | Port |
|---|---|
0 (0x00) | 48 V — Leg actuators |
1 (0x01) | 48 V — Add-on device (top) |
2 (0x02) | 48 V — External port (top) |
16 (0x10) | 12 V — Vision PC (internal) |
17 (0x11) | 12 V — LAN comm port (top) |
18 (0x12) | 12 V — LiDAR port (top) |
19 (0x13) | 12 V — CCTV port (top) |
20 (0x14) | 12 V — Thermal cam port (top) |
21 (0x15) | 12 V — IR LED (front/rear panel) |
22 (0x16) | 12 V — Speaker amplifier |
32 (0x20) | 5 V — Camera USB hub |
33 (0x21) | 5 V — Audio / side-cam USB hub |
// PDU port ID enum (used as data[0] in switch_power)
enum PDU_PORT_IDs_e : unsigned char {
PDU_PORT_48V_LEG = 0x00, // Leg actuators
PDU_PORT_48V_ADD = 0x01, // Add-on device
PDU_PORT_48V_EXT = 0x02, // External port
PDU_PORT_12V_VisionPC = 0x10, // Vision PC
PDU_PORT_12V_COMM = 0x11, // LAN comm port
PDU_PORT_12V_Lidar = 0x12, // LiDAR port
PDU_PORT_12V_CCTV = 0x13, // CCTV port
PDU_PORT_12V_THER = 0x14, // Thermal camera
PDU_PORT_12V_IRLed = 0x15, // IR LED
PDU_PORT_12V_Speaker = 0x16, // Speaker amplifier
PDU_PORT_5V_CAMERAS = 0x20, // Camera USB hub
PDU_PORT_5V_AUDIO_SIDE_CAM_USBHUB = 0x21, // Audio/side-cam USB hub
};Example: turn on 12V LiDAR port (PDU_PORT_12V_Lidar = 0x12 → decimal 18)
ros2 topic pub --once /rbq/cmd/switch_power std_msgs/msg/Int8MultiArray "{data: [18, 1]}"/rbq/battery
| Field | Value |
|---|---|
| Type | rbq_msgs/BatteryState |
| Direction | Pub |
| Hz | 500 |
| Description | Battery status for the dual battery pack. Every field is a 2-element array ([0] = pack 0, [1] = pack 1). |
Fields:
| Field | Type | Description |
|---|---|---|
header | std_msgs/Header | ROS header |
identifier | uint32[2] | Per-pack identifier |
status | uint8[2] | 0=Unknown 1=Missing 2=Charging 3=Discharging |
charge_percentage | uint8[2] | State of charge [0, 100] % |
temperature | int8[2] | Pack temperature [°C] |
current | float32[2] | Load current [A] |
voltage | float32[2] | Pack voltage [V] |
Vision — Camera Sensors
All camera topics are published by the robot (Pub). Sensors are identified by numeric id — sensor_0–sensor_5 (the old name-based sensor_bottom_N / sensor_front / sensor_rear topics are gone). Each stream has /compressed, /camera_info, and a per-stream /tf (geometry_msgs/PoseStamped).
| Sensor id | Location | Streams |
|---|---|---|
sensor_0–sensor_3 | Bottom/body depth sensors | depth, ir |
sensor_4 | Front RGB-D | depth, rgb |
sensor_5 | Rear RGB-D (also ArUco docking) | depth, rgb |
Topic pattern: /rbq/vision/sensor_{N}/{stream}/{sub}
| Topic | Type | Description |
|---|---|---|
/rbq/vision/sensor_{N}/{stream}/compressed | sensor_msgs/CompressedImage | Compressed frame (depth = PNG, ir/rgb = JPEG) |
/rbq/vision/sensor_{N}/{stream}/camera_info | sensor_msgs/CameraInfo | Intrinsics + distortion |
/rbq/vision/sensor_{N}/{stream}/tf | geometry_msgs/PoseStamped | Sensor pose relative to the body |
{stream} is depth/ir for sensor_0–sensor_3, and depth/rgb for sensor_4/sensor_5.
Camera threads publish only while a subscriber is attached (
hasSubscribersgate) — subscribe first, then read.
TF
/tf
| Field | Value |
|---|---|
| Type | tf2_msgs/TFMessage |
| Direction | Pub |
| Description | Dynamic transforms broadcast at runtime: odom → base_link, body → leg links, body → sensor frames. |
/tf_static(URDF fixed transforms) is published by therbq_descriptionrobot_state_publisher, i.e. only when you runros2 launch rbq_description description.launch.py— it is not emitted by the robot's core software.
/rbq/joy
| Field | Value |
|---|---|
| Type | sensor_msgs/Joy |
| Direction | Pub |
| Description | The robot's current joystick input state (passthrough). Axes [0–5]: left-X, left-Y, right-X, right-Y, L2, R2. Buttons [0–15]. |
Topic Subscription Examples
# Robot status (50 Hz)
ros2 topic echo --once /rbq/robot_status
# Per-joint leg status (50 Hz)
ros2 topic echo --once /rbq/leg_joint
# IMU data (200 Hz)
ros2 topic echo --once /rbq/imu
# Battery state (10 Hz)
ros2 topic echo --once /rbq/battery
# Foot contact states (50 Hz)
ros2 topic echo --once /rbq/foot_states
# Odometry (50 Hz)
ros2 topic echo --once /rbq/odometry