06Bring-up & calibration
Mechanically complete is not commissioned. The robot comes up limp, one bus at a time, is read before it is written, and earns torque one module at a time. Then five calibration routines turn a pile of motors into a robot that matches its digital twin.
First power-on
Every actuator torque-disabled. No exceptions, on any bus. Use a
current-limited supply for the first energization of each bus. This is the
launcher's default behavior — launching never energizes anything — but
verify it, don't trust it.
- Power on limp and start the stack:
Watch the preflight: it reports which Teensys answer, which hand adapters are on USB, which cameras enumerate../server/real_run.sh - Enumerate each bus separately and confirm the count matches what you built: 6 on the base CAN, torso + neck yaw on the body CAN, 7 per arm, 17 per hand, 2 neck servos on TTL.
- Read state before writing any. Every joint reports a plausible
position with the robot standing still — in the cockpit's joints panel, or:
source mabel_ws/scripts/mabel_env.sh ros2 topic echo /arms/joint_states --once ros2 topic echo /left_hand/joint_states --once ros2 topic echo /body/joint_states --once - Home the lift empty-handed — before the first loaded cycle, confirm both end stops and the closed loop with nothing mounted (why this matters).
- Enable torque one module at a time, lowest first, with the robot supported — base, then lift, then torso, then arms, then hands. Torque enables come from a client (studio, app, or cockpit), never automatically.
The status watchdog
The launcher prints a per-bus liveness line every 10 s (also parsed into the
cockpit's status panel): odom · arms · neck-dxl · neck-damiao · torso ·
lift · handL/R · wristL/R · scan · audio · map · mesh. A tick means
live data from a physical device, not merely an advertised topic —
the honest signal during bring-up. Hot-plugged devices reconnect within ~2 s
without a relaunch.
Calibration — five routines
| Routine | What it fixes | How |
|---|---|---|
| Swerve steer offsets | each module's steer zero | align wheels, capture offsets (setup studio / calibration tools) |
| Arm zeros + system-ID | joint zeros at the shared reference pose; torque-fit dynamics residuals | calibration/ arm sysid routine |
| Motor friction / inertia | per-motor feed-forward quality | calibration GUI (sine sweeps, fits) |
| ORCA hand end-stops | per-joint range after tendon tensioning | orca_core calibrate routine per hand; stored in the shared calibration store |
| Whole-body CoM check | the tip-over model matches YOUR build | see below — do not skip |
The CoM check
python3 controller/experiments/wbc_stability.py # E4 reports fixed-vs-true CoM error
Run this after any mass change — a different battery, an added sensor,
heavier covers. If E4 shows >1 cm of CoM bias, update the constants in
controller/mabel/motion_model/tip_over.py to the values the
script prints. This model is what keeps a 62 kg robot with a 2.23 m reach
from tipping; it must describe your robot, not the reference one.
Commissioning checklist
- Bus counts match the build on every chain (6 / 2 / 7+7 / 17+17 / 2)
- All joints read plausible positions while limp
- Lift homed empty; both end stops confirmed in software
- Arms back-drive with torque off; hold pose with torque on, supported
- Steer offsets captured; robot drives straight when commanded straight
- Hand end-stops calibrated after final tendon tension
- E4 CoM error < 1 cm; tip-over constants match your build
- E-stop verified from every client you intend to operate with
Commissioned. Continue to 07 · Operate.