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_commandarrives,hardware_interfacedoes not send Booster Zenoh RPC motion requests. - Mode changes send one Booster Zenoh RPC
change_moderequest when the locally desired motion mode changes. Dampingcommands request Booster Zenoh RPCDampingmode.Prepareand stand-up commands request Booster Zenoh RPCPreparemode.Stand,Walk,WalkWithVelocity, andKickcommands request Booster Zenoh RPCSoccermode, not Booster Zenoh RPCWalkingmode.- Walking commands produce periodic Booster Zenoh RPC
move_robotcalls at about50 Hzwhile locally assumingSoccer. Standcommands produce periodic zero-velocity Booster Zenoh RPCmove_robotcalls at about50 Hzwhile locally assumingSoccer.- Stand-up commands produce one Booster Zenoh RPC
get_uprequest on entry while locally assumingPrepare. - Visual kick commands publish
rt/kick_balland send one Booster Zenoh RPCvisual_kick(true)request on visual-kick entry while locally assumingSoccer. - Visual kick commands keep publishing fresh
rt/kick_ballat about50 Hzwhile active. - Leaving visual kick for
Stand,Walk, orWalkWithVelocitysends one Booster Zenoh RPCvisual_kick(false)request while staying in locally assumedSoccermode. - Robot logs contain behavior input, button input, primary-state, RPC action schedule, and RPC action completion entries for transition debugging.