训练就绪的数据结构

严格对齐 VITRA / LeRobot 数据标准 · 时间戳目录结构 · 4路视频+IMU硬同步 · 训练就绪无需对齐

📁 目录结构示例

20260520_173140_stack_bowls/
├── cam0.mp4               # 左前 1280x720 @ 30fps
├── cam1.mp4               # 右前 1280x720 @ 30fps
├── cam2.mp4               # 左后 1280x720 @ 30fps
├── cam3.mp4               # 右后 1280x720 @ 30fps
├── imu.bin                # 6-DoF + 磁力计 ~200Hz
├── imu.csv                # IMU CSV 格式(可选)
├── intrinsics.json        # 4路相机内参
├── extrinsics.json        # 相机到IMU标定
└── meta.json              # 设备/固件/帧率/分辨率

📋 文件说明

cam0~3.mp4
4路全局快门H.264视频,帧级硬同步,触发相位差<50 µs
imu.bin / imu.csv
加速度+角速度+磁力计,M0协处理器打时间戳
intrinsics.json
焦距/主点/畸变系数,4路相机独立标定
extrinsics.json
相机→IMU外参变换矩阵
meta.json
设备信息/固件版本/镜头ID/帧率/分辨率

⚡ 硬同步时序架构

M0协处理器驱动FSYNC同步信号,3路独立GPIO分别连接CMOS快门触发、IMU中断和磁力计就绪。所有传感器在同一时间基线上锁存,帧到IMU间抖动<10 µs。输出数据直接兼容主流训练框架(OpenRobotLab、VLA等)的数据加载器。

🔄 EGO-DAQ ↔ LeRobot v2.1 字段映射

EGO-DAQ 输出数据可直接映射为 Hugging Face LeRobot v2.1 标准格式字段:

EGO-DAQ 输出LeRobot v2.1 字段说明
cam0.mp4observation.images.cam030fps, H.264, 硬同步
cam1.mp4observation.images.cam130fps, H.264, 硬同步
cam2.mp4observation.images.cam230fps, H.264, 硬同步
cam3.mp4observation.images.cam330fps, H.264, 硬同步
imu.binobservation.state10-DoF: acc(3)+gyro(3)+mag(3)+temp(1)
intrinsics.jsoncamera_infofx/fy/cx/cy + 畸变系数
extrinsics.jsonextrinsics相机→IMU 变换矩阵
meta.jsoninfo.json features设备/固件/帧率/分辨率

技术细节

了解数据采集背后的技术规格与数据索引规范

📹 视频编码参数

编码格式H.264 (avc1), 支持 HEVC/SVT-AV1
分辨率1280 × 720
帧率30 fps, 4路独立MIPI CSI
同步方式FSYNC帧级硬同步,触发相位差<50µs

🧬 IMU 技术规格

自由度6-DoF + 3-DoF 磁力计 = 10-DoF
输出频率≈200 Hz
时间戳精度M0协处理器硬件锁存
帧到IMU抖动<10 µs

📅 时间索引规范

参考 LeRobot v2.1 索引标准,EGO-DAQ 采用以下帧索引约定:

字段类型说明
episode_indexuint32录制序号,从0递增
frame_indexuint32帧在 episode 内序号,从0开始
indexuint64全局帧 ID(跨 episode 唯一)
timestampfloat64episode 偏移时间(秒)
next.donebool是否为 episode 末帧(可选)

🧬 VITRA 数据维度参考

人手状态维度定义(VITRA 论文, Sec.3.2):

人手状态:122D = 51(右手) + 10(MANO β) + 51(左手) + 10(MANO β)
↳ 其中 51D = 3(平移) + 3(全局旋转) + 45(15×3 关节角)

EGO-DAQ 输出:10-DoF = 3(acc) + 3(gyro) + 3(mag) + 1(temp)
↳ 维度扩展由 VITRA pad_state_human() 完成

🔄 时间基线校准

所有传感器数据基于同一硬件时间基线(M0协处理器RTC时钟)锁存。每帧视频的PTS(呈现时间戳)与IMU样本的时间戳均由同一时钟源驱动,确保时间戳的一致性。标定参数文件(intrinsics.json / extrinsics.json)在设备出厂前完成标定,随终端交付。

🐍 Python SDK: EGO-DAQ Raw → LeRobot Dataset

以下代码将 EGO-DAQ 时间戳目录结构转换为 Hugging Face LeRobot v2.1 标准数据集:

# pip install lerobot huggingface_hub opencv-python
from lerobot import LeRobotDataset
from pathlib import Path
import json, numpy as np, cv2

def convert_episode(ego_dir: Path, dataset: LeRobotDataset):
  meta = json.loads((ego_dir / "meta.json").read_text())
  caps = [cv2.VideoCapture(str(ego_dir / f"cam{i}.mp4")) for i in range(4)]
  imu = np.fromfile(ego_dir / "imu.bin", dtype=np.float32).reshape(-1, 10)
  idx = 0
  while True:
    frames = [cap.read()[1] for cap in caps]
    if any(f is None for f in frames): break
    dataset.add_frame({
      f"observation.images.cam{i}": frames[i] for i in range(4),
      "observation.state": imu[idx],
      "action": np.zeros(10),
    })
    idx += 1
  dataset.save_episode()

dataset = LeRobotDataset.create(
  repo_id="gear-lab/ego-daq-demo", fps=30, root="./lerobot/",
  features={
    f"observation.images.cam{i}": {"dtype": "video", "shape": (3, 720, 1280)}
      for i in range(4),
    "observation.state": {"dtype": "float32", "shape": (10,)},
    "action": {"dtype": "float32", "shape": (10,)},
  },
)
for ep in sorted(Path("./recordings/").iterdir()):
  convert_episode(ep, dataset)
dataset.push_to_hub("gear-lab/ego-daq-demo")

📚 参考文献

[1] Li Q, Deng Y, Liang Y, et al. "Scalable Vision-Language-Action Model Pretraining for Robotic Manipulation with Real-Life Human Activity Videos." ICRA 2026. arXiv:2510.21571.

[2] Hugging Face. "LeRobot: Open-Source Robot Learning Library." Documentation | Dataset Format v2.1.