MCAP数据格式指南:机器人数据采集

MCAP 学习指南:从机器人采集到模型训练
MCAP 是机器人数据的原始事实层,而不是所有下游数据形态的替代品。ROS bag 解决“怎样录制与回放”,LeRobot Dataset 解决“怎样把数据组织成训练样本”,它们可以同时存在于一条数据链路里。
目录
MCAP 基础概念
MCAP 与 ROS bag
MCAP 与 LeRobot Dataset
MCAP 采集后的典型应用
推荐的数据架构
格式选型方法
落地原则
快速自测
一、MCAP 基础概念
1.1 MCAP 是什么
MCAP 是面向机器人、自动驾驶和其他发布—订阅系统的时序消息容器。它可以把以下内容放进一个可追加写入的文件:
消息定义 Schema
数据通道 Channel
带时间戳的 Message
压缩数据块 Chunk
时间与消息索引
Metadata 元数据
Attachment 附件
完整性校验信息
简单来说,MCAP 可以理解为机器人的“原始数据母带”或“黑匣子”:相机、雷达、IMU、关节状态、控制指令、规划结果和系统事件,都可以按照各自的频率进入同一条时间线。
MCAP 的主要特点包括:
自描述:Schema 可以随文件保存,降低对原始软件环境的依赖。
序列化无关:容器不限定只能保存 ROS 消息,也可以保存 CDR、Protobuf、JSON 等编码。
追加式写入:适合机器人运行过程中持续记录。
多频率数据:不同 Channel 可以保留各自的原始采样频率。
按时间随机读取:通过 Chunk Index 和 Message Index 跳转到指定时间范围。
压缩与完整性检查:支持 Chunk 级 LZ4、Zstd 压缩以及多层 CRC。
附件与元数据:可同时保存标定文件、机器人配置、任务信息和诊断文件。
1.2 MCAP 不是什么
MCAP 本身不是:
训练数据集规范
Parquet 的替代品
LeRobot Dataset 的替代品
只能由 ROS 使用的格式
强制定义 Episode、Task 或统一 FPS 的数据模型
MCAP 优先保留现场实际发生过什么。Episode、Task、统一训练帧和模型特征等语义,通常在后续数据加工环节产生。
1.3 MCAP 文件内部结构
run_001.mcap
├── [Header]
├── [Schema]
├── [Channel]
│ ├── /camera/front 30 Hz
│ ├── /joint_states 100 Hz
│ ├── /imu 400 Hz
│ └── /action_cmd 50 Hz
├── [Chunk]
│ └── Timestamped Messages
├── [Attachment]
│ ├── calibration.yaml
│ └── robot_config.json
├── [Metadata]
├── [Message Index / Chunk Index]
├── [Data End]
├── [Summary]
└── [Footer]
各部分的作用如下:
结构 | 作用 |
|---|---|
Header | 标识文件起始位置和 Profile 等基本信息 |
Schema | 描述消息怎样解码 |
Channel | 描述 Topic、消息编码以及引用的 Schema |
Message | 保存时间戳和序列化后的实际数据 |
Chunk | 聚合一组消息,便于压缩和批量读写 |
Message Index | 按 Channel 和时间定位消息 |
Chunk Index | 定位数据块及其时间范围 |
Metadata | 保存任务、机器人、地点、软件版本等键值信息 |
Attachment | 保存标定、配置、日志、Core Dump 等文件 |
Summary | 汇总 Schema、Channel、Statistics 和索引 |
Footer | 指向 Summary,并标记文件结束 |
二、MCAP 与 ROS bag
2.1 先分清框架与存储格式
“ROS bag”有两种常见含义:
ROS 1 的经典
.bag文件格式。泛指 ROS 2
ros-bag2的录制结果。
在 ROS 2 中,ros-bag2 是录制和回放框架,而 MCAP、SQLite3 是它可以选择的存储后端。
ROS 2 Topic
│
▼
ros2 bag record
│
├── MCAP 存储插件 → run.mcap
└── SQLite3 存储插件 → metadata.yaml + run_0.db3
因此,“用 ros-bag2 录制”和“得到 MCAP 文件”并不矛盾。ROS 2 Iron 开始,MCAP 成为 ros-bag2 的默认存储格式;SQLite3 后端仍然可以显式选择。
2.2 三个需要区分的对象
MCAP
跨框架的时序消息容器,支持 ROS 1、ROS 2、Protobuf 等数据,具备 Chunk、索引、CRC、Metadata 和 Attachment。
ROS 1 Bag 2.0
面向 ROS 1 Topic 和消息序列化设计的经典容器,主要包含 Connection、Chunk、Index Data 和 Chunk Info。
ROS 2 ros-bag2 SQLite3
ros-bag2 的数据库存储后端,将 Topic、时间戳和 CDR 消息保存到 .db3 数据库,并通过 metadata.yaml保存 Bag 摘要。
2.3 核心对比
维度 | MCAP | ROS 1 | ROS 2 SQLite3 |
|---|---|---|---|
核心定位 | 跨框架时序消息容器 | ROS 1 专用日志容器 | ros-bag2 数据库存储后端 |
典型布局 | 通常为单个 | 单个 |
|
序列化 | 容器层无关,可保存 CDR、Protobuf 等 | 主要面向 ROS 1 序列化 | 通常保存 ROS 2 CDR BLOB |
消息定义 | Schema 是一等记录,可嵌入文件 | Connection Header 通常包含类型和定义 | 新版本可以写入定义;早期数据可能依赖原工作空间 |
写入模型 | 追加式、按 Chunk 顺序写入 | 追加式 Chunk 写入 | 数据库事务与 BLOB 插入 |
压缩 | Chunk 级 LZ4 或 Zstd | Chunk 级 BZ2 或 LZ4 | SQLite 后端本身不定义 Chunk 压缩 |
索引 | Chunk Index、Message Index、Summary Offset | Index Data、Chunk Info | SQLite B-tree 和时间查询 |
远程读取 | 适合对象存储和 Range Read | 工具通常面向本地文件 | 通常需要先下载数据库 |
完整性 | 可选 Chunk、Data、Summary、Attachment CRC | 没有等价的标准多层 CRC | 依赖 SQLite 一致性和同步设置 |
附件 | 原生 Attachment | 通常写成 Topic 或 Sidecar | 通常使用 Sidecar 或自定义 Topic |
ROS 版本 | 支持 ROS 1、ROS 2,也可以完全非 ROS | ROS 1 原生 | ROS 2 原生 |
推荐场景 | 新系统、ROS/非 ROS 混合栈、云端归档 | ROS 1 遗留兼容 | 旧 ROS 2 链路和本地 SQL 工具链 |
2.4 ROS 2 常用命令
录制为 MCAP:
BASH复制
ros2 bag record -s mcap --all
录制为 SQLite3:
BASH复制
ros2 bag record -s sqlite3 --all
将旧 ros-bag2 数据转换为 MCAP:
BASH复制
ros2 bag convert -i old_bag -o convert.yaml
转换配置中需要将目标 storage_id 设置为 mcap。
2.5 工程选型建议
ROS 2 新项目:优先使用
ros-bag2 + MCAP。ROS 1 遗留项目:现场继续使用
.bag保证兼容,在归档或数据平台侧转换为 MCAP。旧 ROS 2
.db3:不必立即废弃,可根据云端读取、跨语言和工具链需求逐步迁移。ROS 与非 ROS 混合系统:可以使用 MCAP 统一不同序列化协议和数据来源。
三、MCAP 与 LeRobot Dataset
3.1 两者不是一回事
MCAP 和 LeRobot Dataset 位于数据链路的不同层:
MCAP:保存机器人运行时的原始时序事实。
LeRobot Dataset:把原始数据整理成模型可以直接学习的 Frame、Episode 和 Task。
推荐的数据链路是:
MCAP 原始采集
↓
时间同步、质量过滤、重采样、Episode 切分、任务标注
↓
LeRobot Dataset
↓
PyTorch DataLoader / 策略模型 / VLA 训练
3.2 文件结构对比
MCAP 通常是单个自包含容器:
run_001.mcap
├── Schema / Channel
├── Timestamped Messages
├── Chunk / Index
├── Attachment / Metadata
├── Summary
└── Footer
LeRobot Dataset 是由多个文件类型共同组成的数据集目录:
lerobot_dataset/
├── data/
│ └── chunk-000/
│ └── file-000.parquet
│ ├── timestamp
│ ├── episode_index
│ ├── observation.state
│ └── action
├── videos/
│ ├── observation.images.front/
│ │ └── chunk-000/file-000.mp4
│ └── observation.images.wrist/
│ └── chunk-000/file-000.mp4
└── meta/
├── info.json
├── stats.json
├── tasks.jsonl
└── episodes/
└── chunk-000/file-000.parquet
LeRobot 与 Parquet 也不是一码事。Parquet 只是 LeRobot Dataset 用来保存状态、动作和其他低维表格数据的存储格式之一;视频通常使用 MP4,Episode 和 Task 还需要额外元数据进行组织。
3.3 时间模型不同
MCAP 保留不同传感器的原始异步节奏,例如:
Channel | 原始频率示例 |
|---|---|
| 30 Hz |
| 100 Hz |
| 400 Hz |
| 50 Hz |
LeRobot Dataset 通常会把它们投影到统一训练帧,例如 30 Hz:
Frame 100 = 图像帧 + 对齐后的状态 + Action + Episode ID + Task ID
Frame 101 = 图像帧 + 对齐后的状态 + Action + Episode ID + Task ID
Frame 102 = 图像帧 + 对齐后的状态 + Action + Episode ID + Task ID
这一步通常涉及:
时间同步
最近邻采样或插值
相机帧选择
动作与观测时延处理
Episode 边界定义
无效片段过滤
这些规则需要进入数据集版本记录,否则同一份 MCAP 可能被不一致地转换成不同训练样本。
3.4 核心对比
维度 | MCAP | LeRobot Dataset |
|---|---|---|
定位 | 原始时序日志容器 | 机器人学习数据集规范 |
组织方式 | Channel + Timestamped Message | Frame + Episode + Task |
主要载体 | 通常为单个 | Parquet + MP4 + JSON/JSONL 目录 |
时间模型 | 每条消息拥有独立时间戳 | 通常按统一 FPS 形成 Frame |
多频率数据 | 原生保留 | 通常采样或插值到训练频率 |
Episode | 不是规范的核心结构,可自定义表达 | 核心结构 |
Task | 通过 Metadata 或自定义消息表达 | 原生维护 Task 与自然语言任务 |
图像 | 可保存原始图像、压缩图像或视频消息 | 通常保存为按相机分片的 MP4 |
随机访问 | 按时间、Channel、Chunk 和索引 | 按 Parquet 行、Episode Offset 和视频时间戳 |
系统回放 | 强,适合故障复现和时间线重建 | 主要回放训练所需的 Observation 和 Action |
训练接口 | 需要解码、同步和格式转换 | 可以进入 LeRobot 或 PyTorch DataLoader |
作为唯一原始数据 | 较适合,能最大限度保留现场信息 | 通常不建议,可能舍弃暂时不用的信号 |
3.5 推荐策略
保留 MCAP,派生 LeRobot Dataset。
对于成本高、难以复现的真机数据:
机器人端用 MCAP 记录尽可能完整的原始数据和系统事件。
数据平台进行同步、过滤、切片、标注和版本管理。
训练侧生成可追溯的 LeRobot Dataset。
每个训练数据集版本记录源 MCAP、时间范围、转换代码和参数。
训练格式可以重新生成,丢失的原始信号通常无法找回。
四、MCAP 采集后的典型应用

4.1 数据闭环
数据回流
机器人端采集
Raw MCAP 原始日志
上传、归档与自动质检
完整性 · Topic · 频率 · 时间戳
发现与使用
可视化诊断 · KPI · Episode · 回放 · 标定
场景切分、同步与标注
生成可追溯的派生数据
转换训练数据集
LeRobot · RLDS · Parquet + MP4
策略 / VLA / 奖励模型训练
离线评测与难例挖掘
补标、补采与新数据集版本
4.2 十二类典型应用
1. 故障复现与可视化诊断
把传感器、控制和系统状态放到同一时间轴上,复盘抖动、碰撞、感知误检、规划异常或控制延迟。
典型产物:诊断会话、事件书签、故障片段。
2. 自动化数据质量检查
检测丢帧、频率漂移、时间戳倒退、Topic 缺失、图像损坏、关节越界和传感器静默。
典型产物:质量分、告警、数据可用性标签。
3. 任务 KPI 与运营分析
统计任务成功率、任务时长、人工接管率、碰撞率、路径效率、能耗以及不同机器人和软件版本的表现。
典型产物:指标表、Parquet、运营看板。
4. Episode 切分与事件标注
按照任务开始与结束、状态机、操作阶段或异常窗口,把长时间日志转成可管理、可检索的数据单元。
典型产物:Episode 索引、事件标签、裁剪 MCAP。
5. 训练数据集生产
同步 Observation 与 Action,进行重采样、特征计算和质量过滤,再转换为 LeRobot、RLDS、robomimic 或内部训练格式。
典型产物:Parquet、MP4、JSON、Dataset Version。
6. 策略与 VLA 模型训练
使用真实轨迹进行行为克隆、ACT、Diffusion Policy、VLA 或奖励模型训练。
典型产物:模型权重、训练日志、评测结果。
7. 难例挖掘与数据飞轮
按照失败、低置信度、人工接管或策略分歧,筛选长尾样本并集中补标、重放和再训练。
典型产物:Hard-case 池、增量训练数据集。
8. 算法离线回放与回归测试
让新版感知、定位、规划和控制算法消费历史输入,比较输出差异,并构建可重复的发布门禁。
典型产物:Golden Set、输出 Diff、回归测试报告。
9. 仿真重建与数字孪生
利用轨迹、场景和传感器记录还原真实环境,支持 Log Replay、场景复现以及 Sim2Real 对照。
典型产物:仿真场景、回放输入、场景参数。
10. 标定与系统辨识
利用多传感器同步数据估计内外参、时间偏差、动力学参数、摩擦和执行器响应特性。
典型产物:标定参数、系统模型、误差报告。
11. 预测性维护与车队管理
分析电流、温度、振动、错误码和性能退化趋势,识别个体异常与批次共性问题。
典型产物:设备健康度、维护告警、车队画像。
12. 事故取证与安全审计
保留事故发生前后的完整上下文、软件版本和操作链路,支持责任分析、合规审查与安全改进。
典型产物:证据包、事件时间线、安全复盘报告。
五、推荐的数据架构
按照“事实、发现、场景、训练”进行分层。
第 1 层:原始事实层
目标:完整保存机器人实际发生过什么。
Raw MCAP
Schema、Attachment 和 Metadata
对象存储与生命周期策略
文件完整性和采集质量信息
第 2 层:索引与指标层
目标:让海量文件可查、可筛选、可汇总,而不必每次扫描全部 MCAP。
机器人、任务、地点、时间和软件版本索引
Topic、频率和质量指标
事件索引
Parquet、关系数据库或搜索引擎
车队 KPI
第 3 层:场景与 Episode 层
目标:围绕研发、算法和标注问题组织可复用的数据片段。
Episode Manifest
任务阶段与事件标签
裁剪 MCAP 或时间窗口引用
标注版本
源文件与时间范围血缘
第 4 层:训练与评测层
目标:针对模型读取效率和训练框架生成派生资产。
LeRobot Dataset
RLDS
Parquet + MP4
训练集、验证集、测试集和回归集
数据集统计信息与版本 Manifest
分层架构的核心价值
数据层 | 主要问题 | 推荐载体 |
|---|---|---|
原始事实层 | 当时发生了什么 | MCAP |
索引与指标层 | 数据在哪里、是否可用、总体趋势如何 | 数据库、搜索索引、Parquet |
场景与 Episode 层 | 哪些片段属于目标任务或故障 | Manifest、标签、裁剪 MCAP |
训练与评测层 | 怎样让模型高效读取和学习 | LeRobot、RLDS、Parquet + MP4 |
六、格式选型方法
格式选型不应该只问“哪个格式更先进”,而应该先问谁在消费数据、需要怎样的访问模式。
需求 | 推荐数据形态 |
|---|---|
复盘“当时发生了什么” | MCAP |
按时间和 Topic 回放原始消息 | MCAP |
统计“发生了多少次、平均多少、趋势如何” | 数据库或 Parquet |
搜索机器人、任务、地点和事件 | 元数据目录或搜索索引 |
复用某一类任务或故障窗口 | Episode Manifest 或裁剪 MCAP |
高效训练机器人策略 | LeRobot、RLDS 或训练专用格式 |
在 ROS 2 新项目中录制 | ros-bag2 + MCAP |
保持 ROS 1 原生工具兼容 | ROS 1 |
保持旧 ROS 2 SQL 工具链 | SQLite3 |
最简判断方法:
要复盘事实,读 MCAP;要做统计,读 Parquet;要复用场景,建 Episode;要训练策略,生成 LeRobot 等训练格式。
七、落地原则
1. 原始 MCAP 尽量不可变
不要在原文件上反复“清洗覆盖”。所有派生数据都通过版本化流水线生成,并能追溯到源文件和时间区间。
2. 统一时钟与时间语义
明确采集时间、消息时间、控制周期、时区和同步误差。训练前采用的对齐与插值方法也要进入版本记录。
3. Schema 与软件版本同行
记录消息定义、机器人配置、固件、算法、模型和参数版本,否则历史数据可能变成“可以读取但无法正确解释”。
4. 先建数据目录,再做大规模转换
先让数据可搜索、可检查质量,再只转换真正进入分析或训练的数据,避免无效计算和存储膨胀。
5. Episode 是一种视图,不是唯一真相
同一段原始时间线可以按照任务、故障或训练需求切成不同 Episode,因此切分规则和标签需要版本化。
6. 训练数据集必须能够重建
保存源 MCAP、转换代码、转换参数、同步规则、标注版本和 Manifest,使每个模型权重都能回答“它使用过哪些数据”。
八、Q&A
1. ros-bag2 和 MCAP 是竞争关系吗?
不是。ros-bag2 是 ROS 2 的录制和回放框架,MCAP 是它可以使用的存储后端。
2. LeRobot 和 Parquet 是一码事吗?
不是。LeRobot Dataset 是训练数据集规范;Parquet 只是它用来保存状态、动作等低维数据的文件格式之一。
3. 为什么不只保存 LeRobot Dataset?
训练视图可能舍弃诊断、标定、系统事件或暂时不用的信号。真机数据成本高且难以复现,保留原始 MCAP 可以支持未来重新加工。
4. 为什么分析平台通常还需要 Parquet?
MCAP 适合按时间和 Channel 读取消息,Parquet 适合按列过滤、聚合和批量分析。KPI、质量指标和训练特征通常更适合列式存储。
5. 最重要的数据治理原则是什么?
原始 MCAP 尽量不可变,所有同步、切片、标注和训练数据集都应该记录源文件、时间范围、处理代码与参数,保证可追溯、可重建。
