3、数据回放基础:ROS2 Bag文件格式解析、ros2 bag命令行工具使用、bag文件录制与回放的基本流程

3.1 为什么数据回放这么重要?

做自动驾驶系统调试,说白了就是跟数据打交道。你想想看,实车测试一次成本多高?场地、车辆、安全员,跑一圈下来可能就为了复现一个偶发bug。我刚开始做Autoware那会儿,就吃过这个亏——路测时发现规划模块偶尔抽风,但车一停下来就复现不了,急得我直挠头。

后来老工程师告诉我:「把数据录下来,回实验室慢慢盘它」。这就是bag文件的价值所在。它能把传感器数据、算法输出、控制指令全部打包存下来,让你在办公桌上就能复现路测场景。

核心思想: Bag文件 = 自动驾驶系统的「黑匣子」。它记录了每一毫秒发生了什么,是排查问题的第一手证据。

3.2 ROS2 Bag文件格式解析

ROS2的bag文件,其实就是一个数据库。它用的是SQLite3格式,这点跟ROS1不一样。ROS1用的是自定义的二进制格式,而ROS2选择了标准数据库,好处是——你可以直接用SQLite工具打开它,查数据、做分析。

我习惯用sqlitebrowser这个图形化工具直接打开bag文件,看看里面到底存了啥。结构其实很简单:

表名 作用
topics 记录了所有话题的名称、类型、序列化格式
messages 存储了每条消息的原始数据(二进制)
schema 消息类型的定义,也就是.msg文件的序列化描述

说白了,bag文件就是一张大表:什么时间、哪个话题、发了什么数据。你回放的时候,就是按时间顺序把这些数据重新发出来。

小技巧: 你可以用ros2 bag info命令快速查看bag文件的元信息,比如总时长、话题列表、消息数量。我每次拿到一个新bag文件,第一件事就是跑这个命令,心里先有个底。

3.3 ros2 bag命令行工具使用

ROS2提供了ros2 bag这个命令行工具,功能很全。常用的子命令就这几个:

  • record — 录制数据
  • play — 回放数据
  • info — 查看bag文件信息
  • filter — 过滤话题,生成新的bag文件
  • convert — 转换格式(比如从ROS1 bag转成ROS2 bag)

嗯,这里要注意:ros2 bag是ROS2自带的工具,不需要额外安装。但如果你用的是Autoware,它可能还依赖rosbag2这个包,确保你环境里装了就行。

3.3.1 录制数据

录数据是最基本的操作。我一般这样用:

# 录制所有话题
ros2 bag record -a

# 录制指定话题
ros2 bag record /lidar/points /camera/image /vehicle/steering

# 指定输出文件名
ros2 bag record -o my_drive_data /lidar/points /camera/image

这里有个坑:千万别不加限制地录所有话题。我曾经有一次录了半小时,结果bag文件占了20多个G,因为我把/diagnostics这种高频话题也录进去了。你想想看,诊断信息每秒几百条,全是重复的,浪费空间。

避坑指南: 录制前先想清楚你要排查什么问题。如果是定位问题,就录/lidar/points、/imu、/gps;如果是规划问题,就录/planning/trajectory、/vehicle/state。别贪多,够用就行。

3.3.2 回放数据

回放是排查问题的核心操作。基本命令:

# 按原始速度回放
ros2 bag play my_drive_data

# 以0.5倍速回放(方便观察细节)
ros2 bag play my_drive_data --rate 0.5

# 循环回放(反复看同一段)
ros2 bag play my_drive_data --loop

# 只回放指定话题
ros2 bag play my_drive_data --topics /lidar/points /camera/image

我个人习惯用--rate 0.3来慢放,尤其是排查感知问题时。你想啊,点云和图像数据量很大,正常速度回放时,可视化窗口刷得飞快,根本看不清细节。慢放下来,每一帧都能仔细看。

3.4 Bag文件录制与回放的基本流程

整个流程其实就三步:录 → 查 → 放。我画了个流程图,帮你理清思路:

Bag文件录制与回放流程 步骤1:录制数据 ros2 bag record -a 步骤2:查看信息 ros2 bag info 步骤3:回放数据 ros2 bag play 常见分支场景 🔹 场景A:排查偶发bug → 循环回放 + 慢放 🔹 场景B:对比不同算法 → 同时回放多个bag文件 🔹 场景C:提取特定数据 → 使用filter命令过滤话题

这个流程看起来简单,但实际用起来有很多细节。我举个例子:

有一次,我发现车辆在某个路口会突然急刹车。路测时只录了/planning/trajectory和/vehicle/control。回放时发现,轨迹规划模块输出的轨迹是正常的,但控制模块的刹车指令突然跳变。后来我补录了/perception/obstacles,才发现是感知模块在那个路口误检了一个「幽灵障碍物」。

你看,这就是数据回放的价值——把问题拆解到每个模块,逐层排查。

3.5 实用技巧与避坑指南

  • 录制前检查磁盘空间:我吃过这个亏,录到一半磁盘满了,bag文件损坏,白忙活一场。建议预留至少10GB空间。
  • 回放时注意时间戳:ROS2回放默认使用bag文件里的时间戳,但如果你用--clock参数,它会发布/clock话题,让所有节点都按bag时间走。这个在调试时很有用。
  • 不要同时回放多个bag文件:除非你用了ros2 bag play --merge,否则多个回放进程会抢占话题,导致数据混乱。
  • 善用filter命令:比如你只想要某个时间段的数据,可以用ros2 bag filter按时间戳裁剪。

我的习惯: 每次路测前,我都会写一个简单的录制脚本,把需要的话题列好。这样上车后一键启动,不用手忙脚乱地敲命令。脚本里还会加个磁盘空间检查,低于5GB就自动报警。

好了,数据回放的基础就这些。说白了,bag文件就是你的「时光机」,让你能反复审视自动驾驶系统在某个时刻的表现。下一节我们会深入讲如何用bag文件做模块级调试,到时候再聊。

可可精品资料库