LeRobot SO-101 机械臂从底层控制到 VLA 视觉语言动作模型完整实操复盘
Task4:SO-101 实机数据采集与 LeRobot Dataset 上传
一、任务介绍
本次任务使用 SO-101 领臂遥操作从臂,采集机械臂抓取瓶子并将其放到国旗旁边的演示数据。
(Task3是关于搭建相机与机械臂系统(Eye-in-Hand 或 Eye-to-Hand)略过了)
任务名称:
Place the bottle next to the national flag
采集的数据包括:
- 机械臂六个关节状态;
- 领臂下发的动作;
wrist摄像头图像;- 时间戳及 episode、frame、task 索引。
数据最终保存为 LeRobot Dataset v3 格式,并上传至 Hugging Face。
二、遥操作测试
正式录制前,先测试领臂、从臂和摄像头能否正常工作。
lerobot-teleoperate \
--robot.type=so101_follower \
--robot.port=/dev/tty.usbmodem5B3D0458541 \
--robot.id=monica_follower_arm \
--robot.cameras='{wrist: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}}' \
--teleop.type=so101_leader \
--teleop.port=/dev/tty.usbmodem5B3D0457201 \
--teleop.id=monica_leader_arm \
--display_data=true
测试通过后,可以通过领臂控制从臂,同时查看 wrist 摄像头画面。
三、采集数据
使用以下命令录制数据:
lerobot-record \
--robot.type=so101_follower \
--robot.port=/dev/tty.usbmodem5B3D0458541 \
--robot.id=monica_follower_arm \
--robot.cameras='{wrist: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}}' \
--teleop.type=so101_leader \
--teleop.port=/dev/tty.usbmodem5B3D0457201 \
--teleop.id=monica_leader_arm \
--display_data=true \
--dataset.repo_id=feng0724821/so101_test_record \
--dataset.root=/Users/cx330/.cache/huggingface/lerobot/feng0724821/so101_test_record_20260721_165456 \
--dataset.push_to_hub=false \
--dataset.single_task="Place the bottle next to the national flag" \
--resume=true \
--dataset.num_episodes=20 \
--dataset.episode_time_s=30 \
--dataset.reset_time_s=5
其中:
--resume=true:继续向已有数据集追加轨迹;--dataset.num_episodes=20:本次录制20条;--dataset.episode_time_s=30:单条轨迹最长30秒;--dataset.reset_time_s=5:两条轨迹之间预留5秒复位。
录制时的按键如下:
→:保存当前 episode,进入下一条
←:取消当前 episode,重新录制
ESC:停止录制并完成视频编码
失败、掉落或动作不完整的轨迹直接按左方向键取消。
四、双摄像头问题
原计划同时使用 wrist 和 front 两个摄像头,但在 MacBook Air 上无法稳定运行。
实际现象:
- 两个摄像头单独测试都能出图;
- 只打开
wrist时可以正常遥操作; - 同时打开两路摄像头时,第二路持续出现
read failed; - 调整分辨率、warmup 和 MJPG 后仍然失败。
由于 MacBook Air 接口较少,机械臂和摄像头需要通过扩展坞连接。当前 USB 连接条件下,两路视频无法稳定并发读取,因此最终只使用:
wrist:640×480,30 fps
另外,将摄像头设置为15 fps时出现:
OpenCVCamera(0) failed to set fps=15
actual_fps=30
说明该摄像头在当前模式下实际只能稳定运行在30 fps,因此不能强制设置为15 fps。
五、读取数据集
录制完成后,使用 LeRobotDataset 检查数据:
from pathlib import Path
from lerobot.datasets.lerobot_dataset import LeRobotDataset
root = Path(
"~/.cache/huggingface/lerobot/"
"feng0724821/so101_test_record_20260721_165456"
).expanduser()
ds = LeRobotDataset(
"feng0724821/so101_test_record",
root=root,
)
print("episodes:", ds.num_episodes)
print("frames:", ds.num_frames)
print("fps:", ds.fps)
frame = ds[0]
print(frame.keys())
print("state:", frame["observation.state"].shape)
print("action:", frame["action"].shape)
print("image:", frame["observation.images.wrist"].shape)
正式数据中的主要字段为:
observation.state
observation.images.wrist
action
timestamp
episode_index
frame_index
task_index
observation.state 和 action 都是六维,对应 SO-101 的五个关节和夹爪。项目中的验证脚本也采用 LeRobotDataset 检查数据集帧数、episode 数和字段结构。
六、上传至 Hugging Face
确认数据集读取正常后,执行:
hf upload feng0724821/so101_test_record \
<最终数据集本地目录> \
--repo-type dataset
例如:
hf upload feng0724821/so101_test_record \
~/.cache/huggingface/lerobot/feng0724821/so101_test_record_20260721_165456 \
--repo-type dataset
上传时要确保该目录与录制命令中的 --dataset.root 完全一致,避免误上传旧版本数据。
七、结果
最终完成了以下工作:
- SO-101 领臂与从臂遥操作;
- 单路
wrist摄像头数据采集; - 使用
--resume=true分批追加 episode; - 数据保存为 LeRobot Dataset v3;
- 使用
LeRobotDataset成功读取; - 将数据集上传到 Hugging Face。
数据集:
feng0724821/so101_test_record
代码仓库:
LongtermFcq/lerobot-so101-vla-end2end-demo
LeRobot 官方文档也提供了 SO-101 的连接、遥操作和数据采集流程,可用于核对设备配置。(huggingface.co)
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)