rosbag简介
rosbag 既可以指命令行中数据包相关命令,也可以指 c++/python 的 rosbag 库。这里的 rosbag 是指前者。
rosbag 主要用于记录、回放、分析 rostopic 中的数据。它可以将指定 rostopic 中的数据记录到 .bag
后缀的数据包中,便于对其中的数据进行离线分析和处理。
对于 subscribe 某个 topic 的节点来说,它无法区分这个 topic 中的数据到底是实时获取的数据还是从 rosbag 中回放的数据。这就有助于我们基于离线数据快速重现曾经的实际场景,进行可重复、低成本的分析和调试。
本文以简单的 turtlesim 为例,介绍如何用 rosbag 相关命令记录和回放 rostopic 。
录制数据
启动与 turtlesim 相关的两个 ros node
roscore
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key
前者打开 turtle simulation 的平面仿真环境,后者是一个键盘操作节点。
在开始记录 rostopic 之前,放了方便起见,先创建一个专门的文件夹,存放数据包
mkdir ~/bagfiles
然后进入该文件夹,开始录制数据包:
cd ~/bagfiles
rosbag record -a
其中-a
选项表示将当前发布的所有 topic 数据都录制保存到一个 rosbag 文件中。
也可以只记录某些感兴趣的 topic,命令如下:
rosbag record /topic_name1 /topic_name2 /topic_name3
上述命令录制的数据包名字为日期加时间。如果要指定生成数据包的名字,则用-O /-o
参数,如下:
rosbag record -O filename.bag /topic_name1
其中 -O
(大写的 O) 后跟录制数据包的名字。如果用 -o
(小写的 o),则只是给数据包的名字加前缀。
如果在 launch 文件中使用 rosbag record 命令,如下
默认存放路径是 ~/.ros 中。
上边命令开启了数据记录,然后回到turtle_teleop
节点所在的终端窗口,控制 turtle 随处移动10秒钟左右。
在运行rosbag record
命令的窗口中按Ctrl-C
退出该命令,即结束数据记录。
现在在~/bagfiles
目录中应该会看到一个以日期和时间命名并以.bag
作为后缀的 rosbag 文件,它包含rosbag record
运行期间发布的 topic。
检查和回放
rosbag info
指令可以显示数据包中的信息:
rosbag info filename.bag
显示类似下边的信息:
bag: 2009-12-04-15-02-56.bag
version: 1.2
start_time: 1259967777871383000
end_time: 1259967797238692999
length: 19367309999
topics:
- name: /rosout
count: 2
datatype: roslib/Log
md5sum: acffd30cd6b6de30f120938c17c593fb
- name: /turtle1/color_sensor
count: 1122
datatype: turtlesim/Color
md5sum: 353891e354491c51aabe32df673fb446
- name: /turtle1/command_velocity
count: 23
datatype: turtlesim/Velocity
md5sum: 9d5c2dcd348ac8f76ce2a4307bd63a13
- name: /turtle1/pose
count: 1121
datatype: turtlesim/Pose
md5sum: 863b248d5016ca62ea2e895ae5265cf9
这些信息包括 topic 的名称、类型和 message 数量。
接下来回放数据包中的 topic。
首先在turtle_teleop_key
所在的终端窗口中按Ctrl+C
退出该键盘控制节点。保留turtlesim
节点继续运行。在终端中bag
文件所在目录下运行以下命令:
rosbag play
就能够回放出 bag 中包含的 topic 内容了。
如果想改变消息的发布速率,可以用下面的命令
rosbag play -r 2
这时的轨迹相当于以两倍的速度通过按键发布控制命令时产生的轨迹。 -r
后面的数字对应播放速率。
如果希望 rosbag 循环播放,可以用命令
rosbag play -l # -l == --loop
如果只播放感兴趣的 topic ,则用命令
rosbag play --topic /topic1
如果在启动 rosbag play 之后还有一些其他设置要做,比如在 rviz 中配置可视化选项等。这里有个小小的困难,如果不播放 rosbag,而是先设置 rviz 选项,可能有些 topic 还没有生成,设置的时候没有办法选择,ros graph 里面也不存在对应的 topic;如果先播放 rosbag,然后再做其他设置,则可能错过了 rosbag 最开始的一部分信息。解决方案是在播放 rosbag 时选择“暂停”功能,这样既可以得到相应的 topic,又避免错过开头的信息
rosbag play --pause
空格键可以恢复/暂停播放。
rosbag的命令
rosbag 常用命令列表如下:
命令 | 作用 |
---|---|
check | 确定一个包是否可以在当前系统中进行,或者是否可以迁移。 |
decompress | 压缩一个或多个包文件。 |
filter | 解压一个或多个包文件。 |
fix | 在包文件中修复消息,以便在当前系统中播放。 |
help | 获取相关命令指示帮助信息 |
info | 总结一个或多个包文件的内容。 |
play | 以一种时间同步的方式回放一个或多个包文件的内容。 |
record | 用指定主题的内容记录一个包文件。 |
reindex | 重新索引一个或多个包文件。 |
与例子无关的题外话
回放数据包时,如果想用 Rviz 可视化数据,可能会遇到时间不匹配的问题,出现如下错误信息:
... Message removed because it is too old (frame=..., stamp=...)
这是由于 ROS tf 的发布时间晚于 topic 的时间,Rviz 在做 msg 的 tf 变换时,默认把过时的 msg 丢掉。为了解决这一问题,可以让系统以 msg 对应的 simulated time 运行,而不是实际的 wall-clock time. 步骤如下:
- 启动 ROS master
roscore
- 指定系统以 simulated time 运行
rosparam set /use_sim_time true
官方的解释如下:
This basically tells nodes on startup to use simulated time (ticked here by rosbag) instead of wall-clock time (as in a live system). It avoids confusing time-dependent components like tf, which otherwise would wonder why messages are arriving with timestamps far in the past.
- 进行其他操作,例如 launch tf 文件,启动 Rviz 等
- 回放 rosbag 并发布 simulated time
rosbag play --clock
Written by SH
Revised by QP