Bring-up

Hang the robot, legs straight, for this whole chapter. Power the 48 V bus from a current-limited bench supply until the acceptance tests say otherwise. Each test adds energy; on a failure, fix the cause and re-run from that test.

Rules. Robot on the hoist. Bench supply, not packs, until test A6. Someone's hand on the E-stop whenever a motor is enabled. Never stand in the swing plane of a leg. Torque limits start at 5 % and rise only when a test passes.

Robot computer setup

  1. Install Ubuntu 24.04 (or 22.04) on the mini PC. Disable sleep and automatic updates; set it to power on when 12 V arrives (BIOS: Restore on AC power loss).
  2. Flash each CANable with the candleLight firmware so it appears as a SocketCAN interface (gs_usb), and pin the interface names to the adapters' serial numbers:
# /etc/udev/rules.d/80-foh-can.rules  (one line per adapter; read serials with `udevadm info`)
SUBSYSTEM=="net", ACTION=="add", ATTRS{serial}=="00XXXXXX", NAME="can0"   # left leg
SUBSYSTEM=="net", ACTION=="add", ATTRS{serial}=="00YYYYYY", NAME="can1"   # right leg
SUBSYSTEM=="net", ACTION=="add", ATTRS{serial}=="00ZZZZZZ", NAME="can2"   # waist + left arm
SUBSYSTEM=="net", ACTION=="add", ATTRS{serial}=="00WWWWWW", NAME="can3"   # right arm

# bring the buses up (put this in a systemd unit once it works by hand)
for c in can0 can1 can2 can3; do sudo ip link set $c type can bitrate 1000000; sudo ip link set $c up; done
ip -details link show can0 | grep -o "can state [A-Z-]*"    # expect ERROR-ACTIVE
  1. Install Python 3.11+, python-can, onnxruntime, numpy, and the FOH control package once it exists (Software). Until then, candump and cansend from can-utils do every check on this page.
  2. Confirm the IMU enumerates on USB and streams at 200 Hz or more with its vendor tool.

First power-on

Prove that every device answers, with no motor enabled.

1

Power up on the bench supply

Bench supply at 48 V, current limit 1.5 A, on the distribution block's pack terminals. Breaker on, E-stop released: the contactor closes and the actuators' LEDs come on. A supply current that climbs to the limit is a short: cut power, back to Pre-power checks.

Check: idle bus current under 1 A for 23 actuators plus the computer.
2

Inventory

lsusb                      # four gs_usb devices, the IMU, the hub
ip link show type can      # can0..can3
for c in can0 can1 can2 can3; do timeout 2 candump $c; done   # silence: no actuator talks unprompted
3

Read every actuator

Poll each ID on each bus with the RobStride tool or the control package's read-only status command; nothing moves.

Check: 23 answers; each ID on the bus the actuator map says; bus voltage equals the supply on every one; temperatures near ambient.
4

Power down

Buses down, computer shut down, then the supply.

Motor ID and config

PropertySet withNotes
CAN IDRobStride vendor tool over its USB-CAN module, or the control package's set-id, one actuator at a time on the bench, before it goes into a limbActuators ship at ID 127. The ID is editable in standby only. Label the actuator the moment the ID is written.
Current limitWritten per model: 60 % of the default, capped at 40 A (Duke V2's rule)RS03 26 A, RS06 34 A, RS02 14 A, RS05 7 A. Saved to the drive.
Torque limitA ratio on every run, 0.05 to 0.80.05 for smoke tests, 0.3 for joint sweeps, 0.6 for standing.
ZeroJoint zeroing
BusJointIDModelJointIDModel

Positive direction: the URDF's joint axis is the truth. Set every actuator's direction flag so that a positive command produces the URDF's positive rotation, checked joint by joint at 5 % torque. Do not rely on mounting orientation alone.

Joint zeroing

The zero pose is the URDF at all joint angles zero: standing straight, arms hanging, palms inward. The control stack assumes encoder zero is that pose.

1

Set the zeros

Motors unpowered for movement but on the bus. Hold each joint at zero with a square or a spirit level against the printed reference faces (every adapter has a flat), then write the current position as zero on every actuator and save it to the drive. Do not use the vendor tool's temporary mechanical zero: it is lost at power-off.

2

Verify

Ramp every joint to zero at 10 % torque, robot hanging; stay clear.

Check: the robot hangs straight; both soles level; both shoulder flanges level; encoder readings within ±1° of zero after a power cycle.

Acceptance tests

TestProcedurePass
A1 Bus integrityCold power-up three times; read every actuator each timeFour buses ERROR-ACTIVE and 23 answers every time; zero error frames in ip -s link
A2 CAN latencyCommand-response round trip on each bus at 1 % torque, 1000 samples99th percentile under 1 ms per actuator; a 6-actuator bus completes a cycle inside the 2 ms loop
A3 Harness wiggleLog all actuators while flexing every connector, loom and limb entryZero dropouts
A4 Per-joint motion0.1 rad sine on each joint alone, 5 % torqueOnly the commanded joint moves, in the URDF's positive direction; no grinding or knocking
A5 Zero and modelHold each arm joint at 30 % torque with gravity compensation from the URDF massesResidual torque within ±0.5 N·m of zero at every arm joint; adjust the URDF masses to the weighed parts if not
A6 PacksSwap the bench supply for the packs; repeat A1 and A4Same results; pack voltage sag under 2 V during the sine
A7 PostureHanging, PD hold of the zero pose then a crouch, 60 % torquePoses reached smoothly; no joint exceeds 60 °C in five minutes
A8 StandingFeet on the floor, hoist slack, the standing policy from simulation, E-stop in handBalances for two minutes; recovers from a 20 N push at the shoulders (stiff joints alone survive 8 N·s in simulation; the policy must do better)
A9 First stepWalking policy, one velocity step of 0.2 m/s and stop, hoist attached and slackRobot steps and stops; the stop command zeroes the gait within one stride

Before A8, confirm the software stop layers: the control process zeroes commands on Ctrl-C; the watchdog zeroes them 200 ms after a lost command stream; the gamepad's stop button pre-empts everything. The E-stop is the last stop, and the hoist catches what the E-stop drops.