Skip to main content

Quick reference

Dense, scannable lookup for the most common commands, topics, and parameters. The cheat sheet you print or pin to a second monitor. Every link points at the page with the full details.

All commands below assume you've entered the workspace env (e.g. cd bar_ws && pixi shell) so ros2, colcon, and the BAR console scripts are on PATH. Looking for one-line aliases (pixi run launch-mujoco, pixi run build, …)? See How-to → Workspace shortcuts with pixi.

Launch invocations

Grouped by which machine they run on. See Concepts → Architecture → Deployment topology for the split rationale. Launches come from two repos:

  • bar_ros2 ships the Lite + Prime bringups (bar_bringup_lite, bar_bringup_prime), the description viewer (bar_description_lite), and the generic ONNX policy runner (bar_policy).
  • pianist_ros2 ships the piano-task launches (pianist_bringup composes a Lite + piano MuJoCo scene; pianist_policy runs the piano policy and the USB-MIDI driver).

Single-machine sim / dev (no robot, no tether)

# Drag joints in RViz — no controllers, no physics
ros2 launch bar_description_lite view_lite.launch.py

# MuJoCo sim — full controller stack, /clock from sim time
ros2 launch bar_bringup_lite mujoco.launch.py

# Lite + piano in MuJoCo (pianist_bringup composes the scene, spawns piano_state_bridge)
ros2 launch pianist_bringup mujoco.launch.py

# Calibrate the zero pose (writes ./calibration.yaml on Ctrl+C)
ros2 launch bar_bringup_lite calibrate.launch.py

Robot onboard computer (real bringup)

# Real Lite — both buses, two ros2_control blocks, gamepad + mode_manager
ros2 launch bar_bringup_lite real.launch.py

# Real Lite, no gamepad attached (drive the FSM via /bar/mode/* services)
ros2 launch bar_bringup_lite real.launch.py enable_gamepad:=false

# Gamepad enumerated as js1 (multiple controllers plugged into the Jetson)
ros2 launch bar_bringup_lite real.launch.py joy_dev:=/dev/input/js1

# Real Lite, no FSM (raw debug / calibration)
ros2 launch bar_bringup_lite real.launch.py enable_mode_manager:=false

real.launch.py boots the real-time control plane only — visualisers and policy runners live on the operator workstation below.

Operator workstation (host side of the tether)

# Live URDF + /lite/joint_states viewer (bar_bringup_lite)
ros2 launch bar_bringup_lite viz.launch.py # viser, http://0.0.0.0:8080
ros2 launch bar_bringup_lite viz.launch.py viewer:=rerun # native rerun window

# Generic tracking-family policy (bar_ros2 → bar_policy)
ros2 launch bar_policy lite_policy.launch.py task:=tracking \
wandb_run_path:=… wandb_checkpoint_name:=model.onnx

# Piano policy (pianist_ros2 → pianist_policy)
ros2 launch pianist_policy piano_policy.launch.py \
wandb_run_path:=… motion_file:=/path/to/song

# USB-MIDI keyboard driver (pianist_ros2 → pianist_policy)
ros2 launch pianist_policy midi_keyboard_driver.launch.py

Both machines must share ROS_DOMAIN_ID. Full surface: Launch args.

CAN bus setup

# One-time, after USB-to-CAN adapters plug in
sudo ip link set can0 down 2>/dev/null
sudo ip link set can0 up type can bitrate 1000000
sudo ip link set can1 down 2>/dev/null
sudo ip link set can1 up type can bitrate 1000000

# Check state (look for "UP" and "ERROR-ACTIVE")
ip -d link show can0
ip -d link show can1

Diagnostic CLIs

These are the bar (bar_cli) verbs — equivalent ros2 run bar_robstride … invocations are listed in CLI tools.

# Scan an ID range; read-only, no Enable
bar bus discover --iface can0 --scan-to 32
bar bus discover --iface can1 --scan-to 32

# One-shot GetDeviceId / OperationStatus probe
bar bus ping --iface can0 --id 11

# Per-joint slider window (forward_command_controller frontend)
bar motor slider

# Live URDF + /lite/joint_states viewers (single-machine sim/dev shortcuts;
# on the tethered host, prefer `ros2 launch bar_bringup_lite viz.launch.py`)
bar viz viser # browser at :8080
bar viz rerun # native rerun window

Mode-FSM gamepad bindings (Xbox layout)

ButtonsIntentAllowed fromActivates
XDAMPany statedamping_controller
L1 + A or L1 + BLOADDAMPINGstandby_controller
R1 + ASTART_REMOTESTANDBY (gated on is_finished)remote_policy_controller
R1 + BSTART_LOCOMOTIONSTANDBY (gated on is_finished)rl_policy_controller
BACKQUITZERO_TORQUE or DAMPING onlyrclcpp::shutdown()

Pair conventionally: L1+A → R1+A for remote-policy, L1+B → R1+B for locomotion. Combos are identical functionally; the operator's thumb just stays on one column. See Concepts → Five-mode FSM.

Manual controller switching (no FSM)

These are interactive ros2 control calls:

# ZERO_TORQUE → DAMPING
ros2 control switch_controllers \
--deactivate zero_torque_controller \
--activate damping_controller

# DAMPING → STANDBY (motors will move to piano-ready over ~4 s)
ros2 control switch_controllers \
--deactivate damping_controller \
--activate standby_controller

# Back to safe
ros2 control switch_controllers \
--deactivate <whatever>_controller \
--activate zero_torque_controller

Always end a session with zero_torque_controller active before Ctrl+C-ing the launch.

Topics you actually echo

TopicTypeRateWhen
/lite/joint_statessensor_msgs/JointState50 Hz real / 200 Hz simalways (joint_state_broadcaster, remapped at bringup)
/imu/datasensor_msgs/Imusensor-ratealways; RELIABLE
/control_modebar_msgs/ControlMode50 Hzalways (mode_manager)
/safety_statusbar_msgs/SafetyStatuson-change, latchedTRANSIENT_LOCAL; source field per bus
/standby_controller/statebar_msgs/StandbyStateactive-onlyTRANSIENT_LOCAL; watch for is_finished:true before R1+A
/remote_policy_controller/commandbar_msgs/MITCommandpolicy_dtwhen bar_policy or pianist_policy runner is up
/piano/key_statepianist_msgs/PianoKeyStatesensor / sim ratepiano runs only (RELIABLE + KEEP_LAST(1))
/piano/target_keyspianist_msgs/PianoKeyStatepolicy_dtpiano runs only; song goal frame for bag-based metrics
/joysensor_msgs/Joysensor-ratewhen enable_gamepad:=true (default)

Common one-liners

# Live controller state
ros2 control list_controllers

# Rate of /lite/joint_states (50 Hz real, 200 Hz MuJoCo)
ros2 topic hz /lite/joint_states

# Read the current pose (post-calibration, joint frame)
ros2 topic echo --once /lite/joint_states

# Safety status of every active bus
ros2 topic echo --once /safety_status

# Drive an FSM transition without a gamepad
ros2 service call /bar/mode/damp std_srvs/srv/Trigger
ros2 service call /bar/mode/load std_srvs/srv/Trigger

# Fake an MITCommand publish (when remote_policy_controller is active in MuJoCo)
ros2 topic pub --once /remote_policy_controller/command \
bar_msgs/msg/MITCommand "{header: {stamp: now}, joint_names: [...], ...}"

Services for FSM transitions

std_srvs/Trigger services on /bar/mode/* mirror the gamepad intents — useful when there's no joystick attached.

ServiceEffect
/bar/mode/damp→ DAMPING from any state
/bar/mode/loadDAMPING → STANDBY
/bar/mode/start_remoteSTANDBY → REMOTE (gated on is_finished)
/bar/mode/start_locomotionSTANDBY → LOCOMOTION (gated on is_finished)
/bar/mode/quitexit (only from ZERO_TORQUE or DAMPING)

The Lite joint table

14 actuated DOFs across two buses. Order is canonical (see Concepts → Frozen schemas).

IdxJointCAN idBusModel
0left_shoulder_pitch11can0rs-02
1left_shoulder_roll12can0rs-00
2left_shoulder_yaw13can0rs-00
3left_elbow_pitch14can0rs-00
4left_wrist_yaw15can0rs-05
5left_wrist_roll16can0rs-05
6left_wrist_pitch17can0rs-05
7right_shoulder_pitch21can1rs-02
8right_shoulder_roll22can1rs-00
9right_shoulder_yaw23can1rs-00
10right_elbow_pitch24can1rs-00
11right_wrist_yaw25can1rs-05
12right_wrist_roll26can1rs-05
13right_wrist_pitch27can1rs-05

Full table (effort / current limits / per-joint K/D) in Hardware specs → Joint table.

MIT-mode command convention

Every plugin (Robstride, Sito, MujocoSystem) computes torque as:

τ = K_p · (q_cmd − q) + K_d · (q̇_cmd − q̇) + τ_ff

Five command interfaces per joint: position, velocity, effort, stiffness, damping. Three state interfaces: position, velocity, effort. See Concepts → MIT command surface.

Frequent failure modes (one-liners)

SymptomFirst thing to check
ENOBUFS / Network is down warningsMotor power off → frames don't ACK → qdisc fills. Power the motors.
/lite/joint_states shows exactly 0.0 for every jointMotors un-Enabled (no power, or Enable frame dropped). Check /safety_status flags.
Launch dies with "joy_dev:=/dev/input/jsN does not exist"enable_gamepad:=true is the default and the bringup hard-fails when the resolved joystick path is missing. Plug a gamepad in, pass joy_dev:=<actual path> (the error message lists any other /dev/input/js* it found), or pass enable_gamepad:=false.
mode_manager rejects LOAD from anywhere other than DAMPINGSend DAMP (X) first. See FSM table above.
ros2 topic echo /safety_status reports flags ≠ 0Check Concepts → Safety pipeline for the bit definitions.

Full guidance: Troubleshooting.