Skip to content

舵机 ID 设置、校准与遥操作 ​

4.1 确认端口 ​

从臂、主臂各插一个 USB,先查清谁是谁。

bash
lerobot-find-port

4.2 分配舵机 ID ​

每次只把一个舵机接到驱动板上,按提示设成 1~6;从臂用 --robot.,主臂用 --teleop.。

bash
# 从臂
lerobot-setup-motors \
  --robot.type=so101_follower \
  --robot.port=/dev/tty.usbmodem5B8E1136841
bash
# 主臂
lerobot-setup-motors \
  --teleop.type=so101_leader \
  --teleop.port=/dev/tty.usbmodem5B790188161

4.3 校准两臂 ​

生成缺失的那个 .json 校准文件;从臂用 --robot.,主臂用 --teleop.。

bash
# 从臂
lerobot-calibrate \
  --robot.type=so101_follower \
  --robot.port=/dev/tty.usbmodem5B8E1136841 \
  --robot.id=my_awesome_follower_arm
bash
# 主臂
lerobot-calibrate \
  --teleop.type=so101_leader \
  --teleop.port=/dev/tty.usbmodem5B790188161 \
  --teleop.id=my_awesome_leader_arm

校准不是自动跑完的,它要你手动把机械臂摆两轮。以从臂为例,运行上面的校准命令后,终端会依次给出提示:

  1. 先摆中位。把每个关节都推到它活动范围的正中间,然后按回车。这一步在记录每个关节的零点。
  2. 再走满行程。终端提示 Move all joints sequentially through their entire ranges of motion. Recording positions. Press ENTER to stop...,此时手动把每个关节从一端推到另一端,尽量走满。
  3. **按回车结束。**程序把行程写入校准文件,屏幕上会实时滚动每个关节的 MIN / POS / MAX,方便你确认有没有哪个关节没动到位。
text
Move my_awesome_follower_arm to the middle of its range of motion and press ENTER....
Move all joints sequentially through their entire ranges of motion.
Recording positions. Press ENTER to stop...

NAME                   |    MIN |    POS |    MAX
shoulder_pan           |   1284 |   2048 |   2812
...
Gripper range adjusted: original min=... -> adjusted min=... (offset=...)

校准日志里的 Gripper range adjusted…、以及收不到 5 号舵机信号,都是正常现象,不必处理;若某个关节 MIN 和 MAX 相等,说明那一轮没推动它,需要重来。

4.4 重新校准 ​

  • 在已有的校准上重跑:命令执行后会问 Press ENTER to use provided calibration file…, or type 'c' and press ENTER to run calibration,输入 c 再回车就是重新校准。
  • 或者直接删掉缓存里的校准文件,让它当作新设备重跑:~/.cache/huggingface/lerobot/calibration/ 下对应的 robots/so101_follower/ 与 teleoperators/so101_leader/ 目录。

4.5 校准文件存在哪 ​

校准的结果就是一个 JSON 文件**,文件名就是那步用的 id**。不指定路径时落在 HuggingFace 缓存里:

text
~/.cache/huggingface/lerobot/calibration/
├── robots/so101_follower/my_awesome_follower_arm.json
└── teleoperators/so101_leader/my_awesome_leader_arm.json

想把它固定在项目里(方便备份、换电脑直接带走),就加 --robot.calibration_dir / --teleop.calibration_dir:

bash
lerobot-calibrate \
  --robot.type=so101_follower \
  --robot.port=/dev/tty.usbmodem5B8E1136841 \
  --robot.id=my_awesome_follower_arm \
  --robot.calibration_dir=./data/calibration

三个必须配套的点:

  • calibration_dir 给的是目录本身,不是文件路径;文件名由 id 决定,所以两个臂可以共用一个目录,靠 id 区分。
  • **同一个 calibration_dir + 同一个 id 必须在校准、遥操作、录制、评测里一路保持一致。**某一处漏写或写错,程序会去默认目录找,找不到就认为「这台臂还没校准过」,于是又走一遍校准流程——看起来像"开机就要求重新校准"。
  • 想整体改默认位置的根目录,用环境变量 HF_LEROBOT_CALIBRATION,比每条命令都带参数省事。

一条省事的经验:校准是针对这一台机械臂的,把 .json 备份下来,重装系统、换电脑、甚至重装 LeRobot 之后拷回去就能直接用,不必重做校准。相当于给机械臂留了一份"出厂身份证",建议连同 id 一起记在笔记里。

4.6 校准 JSON 里每个字段是什么意思 ​

打开那个 .json 会看到这样的结构,键名就是关节名(和 J1–J6 一一对应):

json
{
  "shoulder_pan":  { "id": 1, "drive_mode": 0, "homing_offset": 56, "range_min": 829, "range_max": 2866 },
  "shoulder_lift": { "id": 2, "drive_mode": 0, "homing_offset": -1024, "range_min": 1024, "range_max": 3071 },
  "elbow_flex":    { "id": 3, "drive_mode": 0, "homing_offset": 0, "range_min": 2048, "range_max": 3071 },
  "wrist_flex":    { "id": 4, "drive_mode": 0, "homing_offset": 0, "range_min": 1024, "range_max": 3071 },
  "wrist_roll":    { "id": 5, "drive_mode": 0, "homing_offset": 0, "range_min": 0, "range_max": 4095 },
  "gripper":       { "id": 6, "drive_mode": 0, "homing_offset": 0, "range_min": 2048, "range_max": 3071 }
}
字段含义数值不对会怎样
id舵机在总线上的编号 1–6编号与关节错位 → 主臂推 J1、从臂动的是别的关节
drive_mode驱动方向,0 正常、1 取反;用于该关节装反了的场合方向没取反 → 该关节朝反方向顶限位(正是第 1 篇说的烧舵机场景)
homing_offset物理零位到编码器零点的偏移,校准第一轮「摆中位」测的就是它偏了 → 所有关节角度整体带固定偏差,遥操作时从臂姿态与主臂对不上
range_min / range_max软件限位,来自校准第二轮「走满行程」的两个端点范围偏小 → 动作被截断;MIN == MAX → 说明那一轮根本没推动这个关节,必须重校准

这两个数组值同时会被写进舵机自己的 Min/Max_Position_Limit 寄存器,所以校准文件与舵机内部状态是成对的:换了一份 .json 却还是同一台臂,软件限位就可能和实际行程对不上。这也是为什么「换电脑直接拷 JSON」可行、但「把别人的 JSON 拷给自己」不行。

4.7 遥操作 ​

两臂都就绪后,主臂的动作才会带动从臂。

bash
lerobot-teleoperate \
  --robot.type=so101_follower \
  --robot.port=/dev/tty.usbmodem5B8E1136841 \
  --robot.id=my_awesome_follower_arm \
  --teleop.type=so101_leader \
  --teleop.port=/dev/tty.usbmodem5B790188161 \
  --teleop.id=my_awesome_leader_arm

--robot.id / --teleop.id 在校准和遥操作两步里必须写同一个名字,否则找不到对应的校准文件。从臂就绪后,裸命令即可连上:

text
my_awesome_leader_arm SO101Leader connected.
my_awesome_follower_arm SO101Follower connected.
Teleop loop time: 16.67ms (60 Hz)