10. Leader and Follower Calibration and Teleoperation
Chapter 10 of the SO-ARM Physical AI Beginner's Course — calibrate the SO-ARM leader and follower arms with lerobot-calibrate, understand joint mapping and calibration files, then run your first master-slave teleoperation.
Clear valuable items and unrelated people within 1 meter of the robotic arm workspace. Make sure the arm is firmly mounted and that power and cables are connected properly before running this chapter.
10.1 Why Full-Arm Calibration Matters
10.1 Why Full-Arm Calibration Matters
Chapter 6 flashed IDs and baud rates; Chapter 7 verified neutrals. Full-arm calibration is the last step: it learns, for every joint, the mapping between the servo's raw position reading and a physical angle, so that the leader and follower report identical values when they physically match.
This calibration is essential for a deeper reason: it allows a neural network trained on one SO-ARM to work on another. Because every calibrated SO-ARM agrees on what "0 degrees" and "the middle of the range" mean, a dataset recorded on your follower is valid on mine.
Power rules recap: on the SO101 Standard edition all power supplies are 5V. On the SO101 Pro edition, calibrate and operate the Leader with the 5V supply and the Follower with the 12V supply at every step.
10.2 Calibrating the Follower Arm
10.2 Calibrating the Follower Arm
Connect all 6 robot servos via their 3-pin cables and the control board, grant serial permissions, then run:
sudo chmod 666 /dev/ttyACM*
lerobot-calibrate \
--robot.type=so101_follower \
--robot.port=/dev/ttyACM0 \
--robot.id=my_awesome_follower_arm # <- give the robot a unique name
The procedure (shown in the video below):
- Middle position: move the arm so every joint sits in the middle of its range (roughly the "straight-up" posture), then press Enter.
- Full range: move each joint through its full range of motion, one at a time, as the tool samples the min/max.
Due to updates of the LeRobot repository, it is normal for the terminal to receive no signal from servo 5 while calibrating the leader arm. You can continue with the operation.
10.3 Calibrating the Leader Arm
10.3 Calibrating the Leader Arm
The same two steps (middle position, then full range per joint), with the teleoperator keys:
lerobot-calibrate \
--teleop.type=so101_leader \
--teleop.port=/dev/ttyACM1 \
--teleop.id=my_awesome_leader_arm # <- give the leader a unique name
If you see Could not connect on port '/dev/ttyACM0'. Make sure you are using the correct port. Try running lerobot-find-port, grant permissions again with sudo chmod 666 /dev/ttyACM*.
Where Calibration Lives (and How to Redo It)
Calibration files are saved as JSON under ~/.cache/huggingface/lerobot/calibration/robots/ and ~/.cache/huggingface/lerobot/calibration/teleoperators/. To recalibrate, either:
- Option 1 — delete the files for a clean start:
rm -rf ~/.cache/huggingface/lerobot/calibration/robots
rm -rf ~/.cache/huggingface/lerobot/calibration/teleoperators
- Option 2 — answer the prompt. Re-running the calibration command on a calibrated arm asks:
Press ENTER to use provided calibration file associated with the id my_awesome_leader_arm, or type 'c' and press ENTER to run calibration:
Type c + Enter to recalibrate; press Enter to keep the existing data.
When Calibration Fails: Magnitude ... exceeds 2047
If calibration or teleoperation throws Magnitude 30841 exceeds 2047 (max for sign_bit_index=11), a servo's zero offset is abnormal. Power off and restart the arm and try again; if it persists, do a middle-position calibration first — either with the Chapter 7 tool, or with the scripts in Seeed_RoboController:
git clone https://github.com/Seeed-Projects/Seeed_RoboController.git
cd Seeed_RoboController
pip install -r requirements.txt
python -m src.tools.servo_disable # (optional) disable torque to move joints by hand
python -m src.tools.servo_middle_calibration # write current position as 2048
python -m src.tools.servo_center_test # move to 2048 to verify
Then return to lerobot-calibrate and redo the full-arm calibration.
10.4 Joint Mapping: Direction, Range, and Gripper
10.4 Joint Mapping: Direction, Range, and Gripper
After calibration, verify by hand:
- Direction: rotating leader joint 1 clockwise must rotate follower joint 1 clockwise. If any joint moves the wrong way, calibration was done with the arm in a mirrored posture — redo that joint.
- Range: move each leader joint to both stops; the follower should reach its corresponding stops without straining against the printed parts.
- Gripper: fully close the leader gripper handle — the follower gripper should fully close; fully open maps to fully open.
Remember from Chapter 9: the --robot.id / --teleop.id you chose here is stored with the calibration file. Use exactly the same ids when teleoperating, recording, and evaluating later.
10.5 Starting Master-Slave Teleoperation
10.5 Starting Master-Slave Teleoperation
Now the moment the two arms become one system. Grant port permissions and start teleoperation:
sudo chmod 666 /dev/ttyACM*
lerobot-teleoperate \
--robot.type=so101_follower \
--robot.port=/dev/ttyACM0 \
--robot.id=my_awesome_follower_arm \
--teleop.type=so101_leader \
--teleop.port=/dev/ttyACM1 \
--teleop.id=my_awesome_leader_arm
The teleoperate command automatically:
- Detects any missing calibration and starts the calibration procedure;
- Connects the robot and teleoperator and begins teleoperation.
Teleoperation Safety Guidelines
- Support the follower by hand the first time torque enables — it snaps to its calibrated pose.
- Move the leader slowly; the follower follows at full torque.
- Keep fingers out of the follower's gripper and pinch points.
- If the follower lags, jitters, or a joint stops responding: stop, power off, and check that servo's bus cable (a servo LED going dark means the cable before it is loose).
10.6 Control Frequency and Latency
10.6 Control Frequency and Latency
Where Does Latency Come From? Why Is It Inevitable?
Every control cycle reads the leader, sends targets to the follower, and (later) reads cameras. USB cameras in particular deliver frames on their own schedule. The loop is fast — tens of milliseconds — but not zero, so fast leader motions always look slightly smoothed on the follower. That's normal.
What Is the Control Frequency? Can It Be Configured?
LeRobot runs the loop at a configured fps (default 30 for SO-ARM workflows; the dataset --dataset.fps used later must match). If teleoperation stutters:
- Avoid USB hubs — connect arms and cameras directly to the computer.
- Check that no other process holds the serial ports.
- Verify with
lerobot-find-portthat no other device shares the bus.
10.7 Hands-On Practice
10.7 Hands-On Practice
- Calibrate follower and leader; find both JSON files under
~/.cache/huggingface/lerobot/calibration/. - Teleoperate for 5 minutes: touch each corner of the mouse mat with the gripper, then pick up a small object.
- Deliberately test the failure path: run teleoperate with a wrong
--robot.idand read the error — you will recognize it forever after. - Practice recalibration via the
cprompt.
With the control chain verified, the next chapter designs the data your first policy will learn from.