Nothing moves
The follower applies nothing until a leader holds control. Check, in order:claim_control()returnedtrue. It returnsfalseon a denial and on a timeout.- The deadman is held.
- The follower is
ACTIVE, notHOLDING. Watchon_safe_state.
HOLDING while commands arrive, resume_requires_reclaim is set
and something tripped a failsafe. Call Follower.arm() to clear it.
Control is denied
claim_control() returned false and on_control_denied fired with a message
like this:
units= on each side.
The session joins, then silence
Both ends joined and neither sees the other. Almost always two different rooms. SetVIDEOSDK_MEETING_ID on both machines and confirm they match. Without it
each side creates its own room, and joining an empty room succeeds.
Holding, active, holding
Commands stopped arriving for longer thanwatchdog_timeout_s. In order of
likelihood: a slow tick on the leader, network jitter, or an overrunning tick on
the follower. Check stats() for overruns.
Calibration
The arm moves, but wrongly. Almost always the wrong calibration file. The two arms are identical hardware, so loading the leader’s file against the follower’s bus gives plausible numbers and wrong motion. The schema check does not catch it, because both arms have the same joint names. Runso101_calibration.verify_against_bus() and check the id= you passed
LeRobot.
Both arms move, on different scales. The two machines are running
different use_degrees values. Nothing raises, because each side declares the
same joints either way. Print the first read_joints() on both and compare the
magnitudes.
no calibration for robot_id ... means the file is not where the lookup
expects it. Calibration lives under ~/.cache/huggingface/lerobot/calibration/,
with robots and teleoperators in separate directories, and each host reads only
its own arm’s file. The error lists every path it tried, so read that first.
Two causes beyond a missing file:
-
The id does not match.
robot_idis theid=you passedlerobot-calibrate, and followers and teleoperators are filed separately, so the same name in both is two different files. -
LeRobot’s cache is somewhere else. The lookup uses the default path
directly. LeRobot resolves its own in three steps, and any of them moves the
file out of reach:
HF_HOMEis the one that catches people out. It is set routinely in Docker images, in CI and on shared machines, often by someone who has never heard of LeRobot, and it moves the calibration cache with it. Work out the same path LeRobot uses, and pass the result:With none of the three set, or one set to an empty value, this returns the default, so it works whether or not the cache was moved.load_for()searches both directory layouts, so there is no path to spell out. On ROS 2, setcalibration_fileinstead ofrobot_id.
'LEROBOT_HOME' is deprecated, please use 'HF_LEROBOT_HOME' instead is a
ValueError raised by LeRobot while it imports, before any Torq code runs.
Unset LEROBOT_HOME and set HF_LEROBOT_HOME in its place.
Gain feels wrong near the end stops. Each host normalises against its own
arm’s travel. Copying joint_min and joint_max from one machine to the other
produces an arm that tracks but with the wrong gain at the extremes.
Errors
Related
Safety
What to get right before a session touches hardware.
Errors
Every exception, what raises it, and what to catch.
Still stuck?
Community
Ask other developers, and us.
GitHub
Report a bug or open an issue.
Talk to an Expert
Contact support or speak with our team.