bag文件包含tf信息和话题消息,没有rosparam参数和node。 /clock
是由ROS的录包回放系统rosbag发布的主题,主要是提供一个仿真时间
rosbag
本质也是个ROS节点,whereis rosbag
的结果: /opt/ros/kinetic/bin/rosbag
,运行rosbag play会出现一个play开头的节点,后面是当前的utc时间
rosbag record
基本使用:rosbag record topic
,可以有多个话题:rosbag record topic1 topic2 topic3
,话题可以用shell脚本列出来,例如: rosbag record rostopic list | grep plan
常用方法:1
2
3
4
5
6
7
8
9
10
11
12
13
14-o: 在文件名之前加指定的字符串, rosbag record -o test topic ,结果生成文件test_2019-06-24-14-32-08.bag
-node: 记录某节点订阅的所有话题,` rosbag record --node=/joy_teleop
-l: 只记录指定数量的消息, rosbag record -l 1000 /chatter,只记录1000条
--duration: 保持一定时间记录话题, rosbag record ---duration=30 /chatter, 即记录30秒,还可以有5m, 2h
rosbag record --split --duration=30 /chatter #持续时间到30s后分文件存储
-O: 大写O,指定完整文件名 rosbag record -O sess.bag /topic
--size: 指定文件大小,rosbag record --split --size=1024 /chatter #空间达到1024M后分文件存储
-e, -x: 用于正则表达式
我最常用的是rosbag record topic -o filename
rosbag info
显示指定bag文件的详细信息,rosbag info session*.bag
rosbag play
rosplay其实是重现话题数据传输的效果,比如向话题cmd_vel
发数据的过程
rosbag回放过程中按空格暂停。默认模式下,rosbag play
命令在公告每条消息后会等待0.2秒才真正开始发布bag文件中的消息。如果rosbag play在公告消息后立即发布,订阅器可能会接收不到几条最先发布的消息
如果同时回放两个单独的bag文件,则根据时间戳的间隔来播放。比如我先录制一个bag1,等待一个小时,然后录制另一个 bag2,在一起回放 bag1 和 bag2 时,实际是先回放bag1,然后等待1个小时才回放bag2
等待时间可以通过-d
选项来指定,比如等待10秒再播放bag: rosbag play -d 10 realsense.bag
以暂停的方式启动,防止跑掉数据:1
rosbag play --pause record.bag
设置以0.5倍速回放,也就是以录制频率的一半回放。可以加倍播放,但会增大CPU占用。1
rosbag play -r 0.5 record.bag
循环播放:1
rosbag play -l record.bag
use_sim_time的问题
播放bag时,运行算法程序,结果报警:1
2
3Warning: TF_OLD_DATA ignoring data from the past for frame base_footprint at time 1.59524e+09 according to authority unknown_publisher
Possible reasons are listed at http://wiki.ros.org/tf/Errors%20explained
at line 277 in /tmp/binarydeb/ros-kinetic-tf2-0.5.20/src/buffer_core.cpp
在其他节点之前运行rosbag play --clock ...
,会设置好use_sim_time
--clock
选项会让 rosbag play
发布和订阅bag文件中的消息到/clock
话题,这样会让你的其他节点运行在消息发布的时候。 如果use_sim_time
是 true, /clock
需要消息
这样一来launch文件里加入rosparam set use_sim_time true
就不合适了,launch里常常不加入 rosbag play
,即使加入了,也不一定先设置了use_sim_time
,合适的执行顺序如下:
- 启动ROS,但是不包含你需要启动的节点
- rosparam set use_sim_time true
- 启动你需要的节点
- rosbag play —clock
有的资料说不用--clock
才能正常,我估计这是数据集的问题,一般还是要有的
filter
可以实现对已有rosbag文件中的某些topic去除或者保留1
rosbag filter input.bag output.bag 'topic == "/camera/image_raw/compressed" or topic == "/scan" or topic == "/timetag" or topic == "/tf" and m.transforms[0].header.frame_id != "/odom" and m.transforms[0].child_frame_id != "/odom"'
结果是保留话题/camera/image_raw/compressed
, /scan
, /timetag
, /tf
。但是tf变换的frame_id
和 child_frame_id
不是odom
,这样的tf消息会被过滤
参考: How to remove a TF from a ROS bag
bag文件转txt csv
将file_name.bag文件中topic_name话题的消息转换到 file.txt文件中:1
rostopic echo -b file.bag -p /topic_name > file.txt
-p
只能指定一个话题
rosbag可以直接转csv文件,用excel打开,跟转txt一样的
rosbag compress
如果录制的bag很大,我们可以压缩它,默认的压缩格式是bz2:1
2
3
4
5
6
7
8rosbag compress xxx.bag
# 可以添加`-j`手动指定压缩格式为bz2
rosbag compress -j xxx.bag
# 也可以使用LZ4来压缩数据
rosbag compress --lz4 xxx.bag
# 解压缩
rosbag decompress xxx.bag
实例
我们常常使用rosbag record
命令录制机器人的建图或行走过程,一般先运行record命令,然后开始机器人的路径规划和行走,到达目标点后,在record命令的终端直接ctrl+C
就可以保存bag文件.
这里涉及到一个时间戳的问题, bag文件的时间而非本机时间,在默认情况下,ROS使用ubuntu系统的时间,也就是wall clock time.但bag文件中记录的是历史时间,所以play之前要告诉ROS启用simulated time1
rosparam set use_sim_time true
然后使用rosbag play --clock test.bag
命令播放,当然要先打开rviz,添加对应的topic:
play结束之后,还要把参数还原:1
rosparam set use_sim_time false
这样可以在rviz中离线分析问题了, 大大提升了效率
问题
我之前根据make_plan
服务生成了路径,存放在bag文件里,在我使用rosbag play
这些文件时,出现了报错:
不管怎么检查,文件命名也没有问题,不得其解。
使用rosbag info
查看其信息,发现起始和终止时间相同,只有1个message。因为make_plan
服务生成路径只是运行了一次回调函数,所以只有一个message,即使能在rviz显示,也只有几微妙的一瞬间,没什么意义
读取bag的大小不一致
录制bag包后可能没有正确结束掉程序,回放出现错误:1
2[ INFO] [1603677455.288200829]: Opening fuse_2020-10-24-18-01-07.bag
[FATAL] [1603677455.288476478]: Error reading from file: wanted 4 bytes, read 0 bytes
可使用如下命令修复:rosbag reindex xxx-xxx-xxx.bag
play时error reading version line
rosbag可能已损坏,你可以使用rosbag info XX.bag
查看你想要读取的rosbag包的信息,如果无法读取到有效信息,说明该rosbag确实已损坏。