Part III: Running a trained policy · §33 of 43
33.1 Timeline with the log lines you should see
Knowing the order matters: everything before step 4 can fail without the arms moving. The lines below are the INFO messages printed by LeRobot v0.6.2 (prefixes and timestamps omitted).
The ten steps of a run, numbered as in the table below, and what the arms are doing at each one. Everything before step 5 can fail without the arms moving.
| # | Log line(s) | What is happening | Arms |
|---|---|---|---|
| 1 | Loading policy from '…/pretrained_model'... → Policy loaded: type=act, device=cuda | Weights loaded onto the GPU. A wrong path or a broken checkpoint stops here. | Not touched |
| 2 | Connecting robot (bi_openarm_follower)... | Opens can0 and can1, checks motors, opens the cameras. | Not yet powered |
| — | (should NOT appear) Position the arm … hanging straight down | No calibration file for this --robot.id. Ctrl+C now (§21). | — |
| 3 | Robot connected: … → Captured initial robot position (16 keys) | Torque is switched on for all 16 motors. The current joint angles are stored as the “initial position”. | Energised ⚠ verify how firmly they hold before the first command |
| 4 | Creating inference engine (type=sync)... → Rollout strategy: base → Robot: bi_openarm_follower | FPS: 30 | Duration: 30.0s | Last checks. A camera-name mismatch fails here with Visual feature mismatch between policy and robot hardware. This check runs after torque is on, and the program then exits without its normal shutdown, so the motors may stay energised ⚠ verify. If they do: support the arms, then openarm-can-cli -i can0 disable and -i can1 disable. | Held |
| 5 | Rollout setup complete, starting rollout... → Base strategy control loop started | The policy is in control from this line on. | Moving |
| 6 | (possibly) Relative goal position magnitude had to be clamped … warnings | A target was more than max_relative_target away. Occasional ones are normal; a constant stream on one joint is not (§41). | Moving |
| 7 | Duration limit reached (30s) (or nothing, on Ctrl+C) → Base strategy control loop ended | Policy stops. | Hold their last target |
| 8 | Cadence summary block | How fast the loop really ran (§36.6). | Held |
| 9 | Stopping inference engine... → Returning robot to initial position before shutdown... | Straight-line move back to the pose of step 3, over 3 s. | Moving |
| 10 | Disconnecting robot... → Base strategy teardown complete → Rollout finished | Torque off. | Limp: they fall from wherever they are |
The first run also takes a few extra seconds at step 1 (CUDA initialisation).
33.2 When the arms move, and how
- At connect (step 3): torque on. No motion is commanded yet. ⚠ verify whether the arms hold firmly or sag a little between connect and the first command.
- First action (step 5): there is no soft start. The first target goes to the motors at full stiffness. If the arms are at the training start pose, the first target is close to where they are and nothing dramatic happens. If they are far from it, they snap toward it, limited only by
max_relative_targetper tick. Starting in the training start pose is the main safety measure. - During the run: each tick sends one target per joint at kp 240 (big joints). Targets are clipped to the
sidelimits and to ±max_relative_targetfrom the current position. There is no collision checking, no force limit and no gravity compensation. The policy can drive the arm into the table, the other arm or the torso. - Every
n_action_stepsticks (ACT default: every 3.3 s) a new chunk starts. A small visible “hitch” at chunk boundaries is normal (§36.2). - At the end (step 9): a straight joint-space line back to the start pose over 3 s, also without collision checking. If the gripper is holding something or an arm is under an object, the return drags through it. Clear the path, or stop with the power switch if it’s about to hit something.
- After the end (step 10): the arms go limp. Because they’re back at the start pose, starting from the hanging pose means they’re already hanging and barely move. That’s another reason to start there.
33.3 All the ways a run ends
| How | What the arms do |
|---|---|
--duration expires | Policy stops → return to start pose (3 s) → torque off |
| Ctrl+C once | Same as above. The normal way to stop early. |
| Ctrl+C twice | Forces the program to exit immediately. The return move may be cut short and the arms may drop from where they are. Don’t, unless the return itself is dangerous. |
/reset (interactive mode) | Policy stops → return to start pose → torque stays on, ready for /start |
/stop (interactive mode) | Return to start pose → torque off → program ends |
| Esc (episodic, DAgger) | Ends the session → return to start pose → torque off. Needs the keyboard listener (§37.3). |
| A Python error during the run | Teardown still runs (return + torque off) where it can ⚠ verify |
| Motor power switch | Motors unpowered instantly: arms fall wherever they are. LeRobot then reports motors not answering. The emergency stop. |
--return_to_initial_position=false + any of the above | No return move: the arms go limp in place |
| Ctrl+Z | Not a stop. Suspends the program with the buses open; it resumes commanding on fg. Clean up with kill -9 <pid> (§26 item 10). |