COLLECT
COLLECT 把遥操作 episode 录制为标准机器人学习数据集,并在同一标签页内做 PASS/FAIL 审查。
概览
COLLECT 是控制台七个标签页(DEBUG·MANUAL·COLLECT·REPLAY·RL·EVAL·RESULT)的第三个。它不跑策略:每段 episode 同时记录机械臂的观测状态和操作者下达的动作,得到的数据集可直接回放与训练。
collection 段,COLLECT 才会启用(见下文)。无独立进程。前置条件
eva在 PATH 中(见安装)。- 机器人上电,且一种遥操作源已运行:普通主从装置,或 基于 PICO 的 WebXR VR 节点。
- 数据源正在发布——ROS 下即驱动与相机节点已起(如
roscore加机械臂/相机节点)。 - 面向该机器人的采集配置(见下文)。
先用 MANUAL 确认机械臂运动与相机推流正常。
为什么 COLLECT 可能是灰的
- 无采集配置 → COLLECT 禁用(DEBUG、MANUAL、REPLAY 仍可用)。
- 带采集配置 → COLLECT 启用。
工作流
| # | 步骤 | 动作 |
|---|---|---|
| 1 | TASK | 从 collection.tasks 选择数据集集合与任务/提示词;任务随 episode 保存。 |
| 2 | RECORD | 对 EVA 门控的控制路径,先把 MOTION 从 LOCKED 切到启用,再按 START RECORD;再次按下结束并保存。CANCEL 丢弃当前段,HOME 请求配置的回零动作。 |
| 3 | CONVERT QUEUE | 观察 pending episode 在后台保存与校验完成后变为 usable 或 rejected。 |
| 4 | QUALITY CHECK | 回放并标记 PASS/FAIL;可填写并保存备注。 |
| 5 | QUALITY EXPORT | 选择 LeRobot v2.1/v3.0、HDF5 或 MCAP,同时导出两组数据,再按需上传当前 accepted 导出。 |
录制期间
- START RECORD——活动控制路径就绪后开始录制。保存与图像编码在后台 worker 上运行,采集不阻塞。
- 积压——主机跟不上时队列增长并打印警告,录制继续。
- 预热帧丢弃——主臂尚未跟上时的开头几帧不带动作,会被跳过。
- STOP RECORD——episode 校验、打包、入队保存,可立即开始下一段。0 帧的空 episode 不保存。
- 取消——丢弃当前已采集的全部数据。
状态行:COLLECTING / SAVING / QUEUE_FULL / IDLE,附帧数、队列深度与 ETA。
成功与常见故障
| 现象 | 原因 / 处理 |
|---|---|
| 帧数停在 0 | 无数据到达。核对驱动与配置话题名是否与发布端一致。 |
MOTION 一直是 LOCKED | 遥操作客户端离线/过期,或安全状态尚未就绪。检查输入节点、心跳与设备侧授权后重试。 |
| 相机黑屏或缺失 | 未推流或相机名不匹配。先在 MANUAL 验证。 |
QUEUE_FULL | 保存跟不上。等回到 IDLE;若反复出现,降低 fps 或提高 save_queue_max。 |
| 审查时被标红 | 某项自动检查命中——见质量控制。 |
质量控制
STOP 后回放并标记 PASS/FAIL。同时每段 episode 还会运行自动检查;任一项不通过即标红,原因随数据一同持久化。
| 标记 | 触发条件 | 处理 |
|---|---|---|
episode_too_short | 帧数少于 min_episode_frames。 | 重录更长段,或降低阈值。 |
non_monotonic_timestamp | 某帧时间戳未越过前一帧。 | 重录。反复出现则检查发布端时钟。 |
missing_camera · invalid_image_shape | 配置相机缺失,或图像不是 H×W×3。 | 核对推流与配置中的相机名。 |
missing_configured_column · invalid_vector_dim | 配置字段缺失或长度不符。 | 核对话题是否发布、手臂数是否一致。 |
non_finite_value | 录值出现 NaN/Inf。 | 自动置零;频繁则重录。 |
frame_count_mismatch | 相机视频帧数与数据表行数不符。 | 重录;通常是相机掉帧或卡住。 |
需要更细审查并为每段补写指令文本,使用 REPLAY。
质量导出
实时采集始终写入 LeRobot v2.1 原始数据集。EXPORT DATASET 先根据质检结果生成 accepted 与 rejected 两组 episode,再把两组同时转换为所选格式。任务异步执行,并显示已完成/总 episode 数。
- 切换格式会让上一份“可上传”结果失效,必须重新导出。
- accepted 与 rejected 目标成对发布;转换失败不会把一组新结果与另一组旧结果拼在一起。
- 仅当当前所选格式的最新导出完成、且配置了上传端时,UPLOAD ACCEPTED 才可用。
精确输出路径、各格式结构、原子替换与失败检查见数据格式。
编写采集配置
一份配置在声明要录哪些列的那一刻即成为采集配置——这一点正是 COLLECT 的启用条件。采集配置通过 _base_ 继承一份按机器人区分的部署文件,并叠加一个 collection 段(见配置)。
设置项
| 设置项 | 作用 |
|---|---|
storage.log_dir | 输出根目录,按任务分子目录。留空 → 以本配置命名的默认目录。 |
storage.fps | 目标帧率。 |
storage.save_queue_max | 同时排队保存的最大 episode 数。排满 → QUEUE_FULL。 |
schema.robot_type | 机器人 id,如 agilex_piper。 |
schema.min_episode_frames | episode_too_short 的阈值。 |
schema.arms | 要录的手臂,每只一条。 |
schema.cameras | 要录的相机,至少一个。 |
schema.columns | 四个必填数据集字段:qpos、eef、action_qpos、action_eef。 |
teleop.control_source | transport 表示指令已在机器人传输层中;client 表示使用 WebXR 等 EVA 输入客户端。 |
tasks | 数据集集合键到提示词/目标组合的映射,供 TASK 选择器使用。 |
复制机器人自带的采集配置(如 configs/02_collection/dual_agilex_piper.py)并改其中标出的值。标 ← 改成… 的行必须与你的机器人对应。
_base_ = ['<你机器人的部署 _base.py 路径>'] # ← 指向你机器人的部署配置。 collection = dict( storage=dict( log_dir='', # ← 存到哪里(留空=用以本配置命名的默认文件夹)。 fps=30, # 合理默认值,机器人不是这个帧率时再改。 save_queue_max=15, # 合理默认值。 ), schema=dict( robot_type='<你的机器人类型>', # ← 如 'agilex_piper'。 min_episode_frames=10, # 合理默认值。 arms=dict(left_arm='left', right_arm='right'), # ← 每只手臂一条。 cameras=dict( cam_high='observation.images.cam_high', # ← 列出你的相机(名字 → 数据集字段)。 ), columns=dict( # 这四个键保留不动,值是标准数据集字段名。 qpos='observations.state.qpos', eef='observations.state.eef', action_qpos='action.qpos', action_eef='action.eef', ), ), teleop=dict(control_source='transport'), # ← VR 用 'client',见 VR 预设。 tasks=dict( pick_up_the_apple=[('拿起苹果', -1)], # ← 数据集集合 → 提示词/目标组合。 ), )
存到 configs/02_collection/ 下并启动。加载器强制校验:
columns四个键齐全——qpos、eef、action_qpos、action_eef。cameras至少一个相机。arms至少一只手臂。
启动
eva --config configs/02_collection/my_robot.py
在浏览器打开 http://localhost:8080(可用 --web-port 覆盖,见命令行参考)。episode 可通过 dataset 传输回放,并在 REPLAY 中审查。