# LeRobot 从零到真机抓取实战：环境配置、SO-101 标定、遥操作采数、ACT/Diffusion 训练与真机推理排障

> 原文链接：https://robotics.hellobike.com/tutorials/lerobot-from-zero-to-real-robot
> 频道：tutorials | 更新日期：2026-10-14 | 标签：LeRobot, SO-101, ACT, Diffusion
> 核心摘要：按当前 LeRobot 文档把 SO-101 从标定走到 ACT 或 Diffusion 真机推理。命令行名称随版本变，以你安装的 --help 为准。

# 环境

用独立虚拟环境，Python 版本以 LeRobot 仓库当前说明为准。CUDA 要和你准备训练的 PyTorch 轮子一致。只做遥操作时可以先不装 GPU 版。

```bash
python -m venv .venv
source .venv/bin/activate
pip install -U lerobot
lerobot-calibrate --help
```

`--help` 能出来，再往下做。0.3 和 0.4 之间子命令改过名，旧教程里的 `control_robot.py` 不要和 `lerobot-record` 混在一条命令里。

登录模型仓库用官方 CLI，把凭证放在用户目录。不要把密钥写进数据集卡片或 shell 历史之外的仓库文件。

串口权限：把当前用户加入能访问 `/dev/ttyACM*` 的组，重新登录。端口名每次插拔可能变，用 `ls /dev/ttyACM*` 看，不要把示例里的 `usbmodem` 编号抄进脚本。

## SO-101 标定

文档把从臂叫 `so101_follower`，主臂叫 `so101_leader`。先给从臂上电并只接从臂。

```bash
lerobot-setup-motors \
  --robot.type=so101_follower \
  --robot.port=/dev/ttyACM0

lerobot-calibrate \
  --robot.type=so101_follower \
  --robot.port=/dev/ttyACM0
```

标定过程把每个关节转到行程中部，再按提示转到两端。中位偏了，回放会在某一侧提前顶死。主臂用另一条 USB，重复上述两步，`--robot.type` 换成 `so101_leader`，端口换成主臂那条。

两台设备同时插上时，用 `ls -l /dev/serial/by-id/` 区分，把稳定的 by-id 路径写进命令，不要用会变的 `ttyACM0`。

## 遥操作和采数

```bash
lerobot-teleoperate \
  --robot.type=so101_follower \
  --robot.port=/dev/serial/by-id/usb-follower \
  --teleop.type=so101_leader \
  --teleop.port=/dev/serial/by-id/usb-leader
```

路径换成上一步看到的 by-id。主臂动、从臂跟，再开始录。

```bash
lerobot-record \
  --robot.type=so101_follower \
  --robot.port=/dev/serial/by-id/usb-follower \
  --teleop.type=so101_leader \
  --teleop.port=/dev/serial/by-id/usb-leader \
  --robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30} }" \
  --dataset.repo_id=YOUR_NAME/so101_pick \
  --dataset.single_task="Pick up the cube and place it in the bowl" \
  --dataset.num_episodes=50 \
  --dataset.episode_time_s=30 \
  --dataset.reset_time_s=10
```

相机序号用 `video4linux` 或文档里的枚举确认。腕部相机和全局相机都要固定在臂上，不要用扎带临时绑。

50 条只够一个物体、一个固定桌面。语言指令从第一条开始就写进 `single_task`，不要录完再在表格里补。失败的回合删掉再训；OpenVLA-OFT 的 LIBERO 表专门区分过「过滤失败演示」和原始数据，真机同样适用。

目录里已有社区数据 `lerobot-svla-so101-pickplace`，可以用来对格式，不要把它和你自己的关节方向假设成一样。

## 训练

ACT 适合 50 条左右的单任务，chunk 默认就比单步回归稳。Diffusion 对多解动作更好，采样步数会把推理频率打下来。

```bash
lerobot-train \
  --dataset.repo_id=YOUR_NAME/so101_pick \
  --policy.type=act \
  --output_dir=outputs/train/act_so101 \
  --job_name=act_so101 \
  --policy.device=cuda \
  --wandb.enable=false
```

改成 Diffusion 时把 `--policy.type=diffusion`。`lerobot-diffusion-pusht` 是 PushT 上的示例权重，不能载入 SO-101。`lerobot-act-aloha-sim-transfer-cube-human` 是双臂仿真 ACT，动作维数和 SO-101 不同。

显存不够就减 batch。不要改数据集里的动作归一化统计量，除非你准备把推理端一起改。

## 真机推理

新版本用训练输出目录里的 `pretrained_model` 做策略路径，子命令可能是 `lerobot-record` 的策略模式，也可能是单独的 eval 命令。以 `--help` 为准。频率先设得比采集时低，确认夹爪方向正确再拉高。

推理时人的手离开主臂。主臂仍接在总线上会抢位置命令。

## 排障

| 现象 | 先查 |
| --- | --- |
| 找不到电机 | 端口、供电、是不是主从接反。一次只接一台做 setup |
| 标定后某一轴反转 | 重做该轴标定，不要在策略里取负号掩盖 |
| 遥操作抖动 | USB 延长线、供电不足、两个相机挤在同一个总线 |
| 录出来的图是黑的 | 相机序号被笔记本内置摄像头占用 |
| 训练 loss 很低，真机不动 | 动作是主臂还是从臂。标签要用从臂实际执行的关节 |
| 夹爪在仿真里合上、真机张开 | 开合方向和标定端点反了 |
| ACT 到目标附近来回晃 | chunk 太长且没有用新的观测覆盖旧 chunk。缩短 chunk 或加快推理 |
| Diffusion 频率到不了采集时的 fps | 减少去噪步数，或换 ACT |
| 第二次采集全部失败 | 相机被碰过，或光照变了。固定相机后重采，不要只加 epoch |

抓取本身仍然依赖物体不滑、桌面摩擦和夹爪行程。模型只学习你录进去的那一类场景。

## 原始参考来源 (Sources)

- [LeRobot SO-101](https://huggingface.co/docs/lerobot/so101)
- [LeRobot 模仿学习机器人](https://huggingface.co/docs/lerobot/il_robots)
- [LeRobot](https://github.com/huggingface/lerobot)