Skip to content

Overview

Note

This structure in three steps is only conceptionally, in the code, there is no differentiation between these steps, and all nodes are automatically sorted during compile time depending on their inputs and outputs.

Motion Selection

Motion starts in the motion_selector with the motion command from behavior. Here the current motion is chosen based on the previous motion, if it is finished or if it can be aborted.

Motion Execution

In the next step, all nodes for all motions are executed. The nodes, whose motion is not selected, may exit early.

Command Sending

Motion finishes by collecting and optimizing all motor commands in the motor_commands_collector, then writes them to the hardware interface in the commands_sender.

ROS-Z Booster Path

CPU isolation

--motion-cpus 4,5 runs motion, low-state input, fall/pose checks, and operator-input/state nodes on a separate Tokio runtime. The general runtime and shared transport exclude those CPUs. Behavior, including Voronoi and planning, stays on the general runtime; safety command selection still depends on it. Without the flag, all nodes share one runtime.

Threads are individually pinned across the selected CPUs, which remain shared with vendor processes. Tokio scheduler handoffs can leave both async workers on one CPU without breaking isolation; preserving their distribution is a future improvement.

Deploy both the binary and /usr/bin/launch-hulk, which supplies the flag. Verify Cpus_allowed_list is 4 or 5 for each hulk-motion thread in /proc/<pid>/task/<tid>/status, and measure timing and stop-response latency under perception load.

Command path

The ROS-Z Booster stack bypasses the legacy commands_sender path. Behavior publishes behavior/motion_command, and hardware_interface owns Booster Zenoh RPC mode changes, walking commands, head rotation, stand-up requests, LED forwarding, and rt/kick_ball publishing.

Head motion runs in crates/nodes/head_motion. The launcher starts its services/head_motion service, which accepts a HeadMotion request and returns HeadJoints<MotorCommand>. Connecting the service caller in central motion remains pending.

hardware_interface reads its runtime parameters from etc/parameters/base/hardware_interface.json5. The removed split ROS-Z nodes no longer consume commands/high_level_command, services/get_robot_mode, or command_sender parameters. Robot mode is now managed internally from behavior/motion_command without waiting for SDK mode feedback.

Manual validation on a Booster robot should check these behaviors:

  • Before the first behavior/motion_command arrives, hardware_interface does not send Booster Zenoh RPC motion requests.
  • Mode changes send one Booster Zenoh RPC change_mode request when the locally desired motion mode changes.
  • Damping commands request Booster Zenoh RPC Damping mode.
  • Prepare and stand-up commands request Booster Zenoh RPC Prepare mode.
  • Stand, Walk, WalkWithVelocity, and Kick commands request Booster Zenoh RPC Soccer mode, not Booster Zenoh RPC Walking mode.
  • Walking commands produce periodic Booster Zenoh RPC move_robot calls at about 50 Hz while locally assuming Soccer.
  • Stand commands produce periodic zero-velocity Booster Zenoh RPC move_robot calls at about 50 Hz while locally assuming Soccer.
  • Stand-up commands produce one Booster Zenoh RPC get_up request on entry while locally assuming Prepare.
  • Visual kick commands publish rt/kick_ball and send one Booster Zenoh RPC visual_kick(true) request on visual-kick entry while locally assuming Soccer.
  • Visual kick commands keep publishing fresh rt/kick_ball at about 50 Hz while active.
  • Leaving visual kick for Stand, Walk, or WalkWithVelocity sends one Booster Zenoh RPC visual_kick(false) request while staying in locally assumed Soccer mode.
  • Robot logs contain behavior input, button input, primary-state, RPC action schedule, and RPC action completion entries for transition debugging.