High Level Command — C++ Example
Source: rbq_sdk/cpp/example/src/rbq_high_level.cpp
Publishes HighLevelCommand messages at 50 Hz over DDS.
Gait selection is done from the terminal; velocity setpoints come from a joystick.
Overview
Three concurrent actors run together:
| Actor | Rate | Role |
|---|---|---|
| Control loop thread | 50 Hz | Publishes HighLevelCommand with the current gait + velocity |
| Joystick loop thread | 100 Hz | Polls the joystick and updates atomic velocity globals |
| Main thread (terminal) | blocking | Reads gait names/IDs from stdin and updates the target gait |
At startup the control loop also publishes switchControlMode = true once, which enables EXT_JOY mode on the robot stack — without this the HighLevelCommand topic is ignored.
Prerequisites
- RBQ SDK built and installed — see C++ SDK Overview.
- A Linux joystick device at
/dev/input/js*(the joystick is required to start the program). - Robot stack running (simulation or hardware).
Build
From rbq_sdk/cpp/example/:
bash scripts/setup.bash
bash scripts/build.bashBinary: bin/rbq_high_level
Run
./bin/rbq_high_level <networkInterface> [joystickPath]
# e.g.
./bin/rbq_high_level eth0
./bin/rbq_high_level eth0 /dev/input/js1The joystick auto-detection follows the same logic as the Sport Client (Joystick) example.
Terminal commands
At the > prompt type either a gait name or a numeric gait ID.
list # print all available gaits
standing # switch to STANDING by name
3 # switch to TROTTING by ID
rl_trot # switch to RL_TROT by nameAvailable gaits
| Name | ID | Description |
|---|---|---|
sitting | 0 | Robot sits on the ground |
standing | 1 | Neutral standing posture (default at startup) |
aiming | 2 | Aiming posture |
trotting | 3 | MPC trot gait |
trot_stairs | 4 | Stair-adaptive trot |
waving | 5 | Slow walk gait |
trot_running | 6 | High-speed trot |
docking | 10 | Auto-docking sequence |
rl_trot | 30 | RL-based trot |
rl_front_walk | 31 | RL forward walk |
rl_left_walk | 33 | RL lateral left walk |
rl_right_walk | 34 | RL lateral right walk |
rl_bound | 35 | RL bound gait |
rl_pace | 36 | RL pace gait |
rl_pronk | 37 | RL pronk gait |
rl_3leg_hr | 38 | RL 3-leg (hind-right lifted) |
rl_3leg_hl | 39 | RL 3-leg (hind-left lifted) |
rl_3leg_fl | 41 | RL 3-leg (front-left lifted) |
rl_trot_vision | 42 | RL trot with vision |
rl_trot_run | 45 | RL trot run |
rl_silent | 46 | RL silent gait |
rl_stairs | 47 | RL stair climbing |
rl_walk_vision | 48 | RL walk w/ terrain height feedback (height/pitch adjustable) |
rl_walk | 49 | RL walk (height/pitch adjustable) |
rl_end | 80 | RL end state |
Joystick velocity controls
| Axis | Maps to | Max value |
|---|---|---|
| Left stick Y (forward) | vel_x | ±1.2 m/s |
| Left stick X (lateral) | vel_y | ±0.5 m/s |
| Right stick X (yaw) | omega_z | ±60 deg/s |
A deadzone of 0.12 is applied before scaling.
Note on
omega_zunits:HighLevelCommand.omega_zis sent in degrees per second.
The on-robot QuadWalk multiplies by D2R internally, so the SDK side sends raw deg/s values (e.g. 60 deg/s ≈ 1.05 rad/s of yaw).
DDS topics used
| Direction | Topic | Message type |
|---|---|---|
| Publish | rt/rbq/cmd/highLevel | rbq_msgs::msg::dds_::HighLevelCommand_ |
| Publish | rt/rbq/cmd/switchControlMode | std_msgs::msg::dds_::Bool_ |
Key implementation notes
gait_transitionflag: Set totrueonly on the single tick immediately following a gait change, usingstd::atomic<bool>::exchange(). This ensures the QuadWalkgaitTimeris triggered exactly once rather than continuously.switchControlMode: Published once at startup (after a 200 ms delay to let DDS subscribers connect). If not published, the robot ignoresHighLevelCommandand stays in joystick mode.- Timing: The control loop uses
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, ...)for precise 20 ms scheduling. If the loop runs late, it resetstimeNextto the current time rather than chasing a drifting target.
