Skip to main content
模块 3 · 第 9 章 · Get Your Own VLA Model

9. 真实环境数据采集

测试相机,用 lerobot-record 录制双相机同步的 episode,并在训练之前 校验 LeRobot v3 数据集。

9.1 测试相机​

录制之前

9.1 测试相机

第 8 章已经装好并预览过双相机;现在再查一遍——重新插拔或重启后 /dev/video* 编号会变:

lerobot-find-cameras opencv

把预览图对应到编号(文件名含设备号),重新导出:

export CAMERA_GRIPPER=4
export CAMERA_EXTERNAL=6

同时确认第 7 章的臂变量在当前终端里仍然有效:

echo "$TELEOP_PORT $TELEOP_ID $ROBOT_PORT $ROBOT_ID"

9.2 录制 episode​

lerobot-record

9.2 录制 episode

双臂校准完毕、摄影棚就绪后运行:

export HF_USER=local   # 或你的 Hugging Face 用户名

lerobot-record \
--robot.type=so101_follower \
--robot.port=$ROBOT_PORT \
--robot.id=$ROBOT_ID \
--robot.cameras="{
front: {type: opencv, index_or_path: $CAMERA_GRIPPER, width: 640, height: 480, fps: 30},
external: {type: opencv, index_or_path: $CAMERA_EXTERNAL, width: 640, height: 480, fps: 30}
}" \
--teleop.type=so101_leader \
--teleop.port=$TELEOP_PORT \
--teleop.id=$TELEOP_ID \
--dataset.repo_id=so101_vials_real \
--dataset.root=$HOME/rebot-arm-dli-isaacsim/datasets/so101_vials_real \
--dataset.single_task="Put the three vials into the vial rack" \
--dataset.num_episodes=10 \
--dataset.push_to_hub=false \
--display_data=false \
--play_sounds=false

按终端提示完成每个 episode:用主臂抓起一支试管放进机架,松爪,让场景稳定。

关键参数:

参数为什么是这个值
--robot.cameras 键名 front 与 external与仿真数据集特征名完全一致(第 12 章协同训练)
--dataset.single_task所有地方都必须用这句原文——训练提示词和 episode 标签都依赖它
--dataset.num_episodes先录 10 条;NVIDIA workshop 最低 5 条,50 条是可用的策略
--dataset.push_to_hub=false数据留在本地;需要备份再上传
--display_data=false避免录制机渲染每一帧
用缓慢、完整的演示开始

中途放弃的 episode 会教会策略中途放弃。完成放置后再按右方向键。五条干净 轨迹胜过二十条被打断的。

9.3 录制控制与安全​

键盘

9.3 录制控制与安全

按键动作
右方向键提前结束当前 episode 并进入下一条
左方向键丢弃当前 episode 并重录
Esc结束会话、编码视频并完成数据集

如果从臂出现意外动作:

  1. 先按 Ctrl+C;
  2. 若仍在运动,切断从臂 12 V 电源;
  3. 手动把臂扳回中位;
  4. 重启前复查校准和主臂 ID。
键盘无响应

部分 Ubuntu 上需要固定 pynput 版本。在 LeRobot 环境里:

pip install pynput==1.6.8

9.4 数据存储、断点与续录​

数据在哪里

9.4 数据存储、断点与续录

  • 数据以 LeRobotDataset 格式在录制时写盘,路径由 --dataset.root 指定;
  • --dataset.push_to_hub=false 时不做任何上传;
  • 录制过程自动创建检查点。中断后想续录,用同一命令加 --resume=true;
  • 想从零重录,删除数据集目录。
关于续录

续录时 --dataset.num_episodes 是追加的条数,不是目标总数。

如果臂在会话中卡死,调大 episode 时长 --dataset.episode_time_s=90 (默认 60)后重录。

9.5 校验数据集​

训练前检查

9.5 校验数据集

检查元数据:

python3 -c "
import json
info = json.load(open('$HOME/rebot-arm-dli-isaacsim/datasets/so101_vials_real/meta/info.json'))
print('fps:', info['fps'], 'episodes:', info['total_episodes'], 'frames:', info['total_frames'])
print({k: v['shape'] for k, v in info['features'].items()})
"

预期输出:

fps: 30 episodes: 10 frames: ...
{'observation.state': [6], 'observation.images.front': [480, 640, 3],
'observation.images.external': [480, 640, 3], 'action': [6], ...}

两路相机流和六维关节是流水线的契约。形状不对就删掉数据集目录,用相同参数 重录。

数一下视频:

find $HOME/rebot-arm-dli-isaacsim/datasets/so101_vials_real/videos -name "*.mp4" | wc -l

10 个 episode × 2 相机 = 20 个文件。快速目检:

lerobot-dataset-viz \
--repo-id so101_vials_real \
--root $HOME/rebot-arm-dli-isaacsim/datasets/so101_vials_real \
--episode-index 0 \
--display-compressed-images true

9.6 数据质量清单​

注意这些

9.6 数据质量清单

进入训练前,完整回看几条 episode:

  • 每条 episode 完成任务——试管落入机架后松爪;
  • 动作顺滑;没有长停顿、没有粗暴修正;
  • 各 episode 的试管起始位置有变化,不是每次都同一处;
  • 腕部画面能看到爪子和被抓试管;外部画面能看到机架;
  • 没有丢帧(视频卡顿)和对焦拉风箱;
  • 每条 episode 的任务句完全一致。

任何一条不达标,训练出的策略都会在部署时以恼人的具体方式失败。现在修数据; 训练不会替你修。

下一章:第 10 章 —— 训练 GR00T N1.7 策略。

Loading Comments...