使用rosbag采集数据
对于第一个问题,我们用之前的写的程序来讲解。还记得在第三讲,我们写过一个pub_poseStamped.cpp的程序,什么?你是直接跳到这儿来的?那简单解释一下那个程序就是模仿我们有一个传感器,能每隔100ms获取机器人的位置和方向,并放到poseStamped这个消息类型中发布出来。那么接下来我们就使用rosbag来采集这个假的传感器所发布出来的数据。 rosbag在采集数据时自身相当于一个subscriber程序 最开始几讲你写一个publisher文件,就要写有一个subscriber文件,他们总是成双成对地出入。那么当你用rosbag采集数据时,你有publisher就行了,不需要再写subscriber文件了。 那么具体怎么实施呢? 首先启动roscore,rosbag才能记录数据。 然后建立一个叫dataset的文件夹专门来储存这些数据,cd到那个文件夹去 然后在terminal中,写入下面内容
rosbag record /chatter -O record_poseStamped
这行命令第一个是表示我们要使用rosbag相关命令了,第二个record表示我们想要采集(记录)数据。 第三个,由于我们之前说了,rosbag在采集数据时自身相当于一个subscirber程序,既然要subscribe,那么我们肯定需要指定subscriber哪个topic了,观察我们在pub_poseStamped.cpp中,定义topic那一行我们定义的topic的名字是chatter,于是我们就在第三个参数写入/chatter
表示记录这个topic发布出来的信息。rosbag可以同时记录多个topic的信息,你只需要在record后接/topicA /topicB /topicC....
即可。 命令行中-O及其后面的参数,是用来给bag文件命名的。我们在记录结束之后,rosbag的名字就会是record_poseStamped.bag
,(如果参数是-o,那么记录名字会自动加上年月日时间,比如上面的例子如果用rosbag record /chatter -o record_poseStamped
,输出会是record_poseStamped-2019-09-08-15-24-05.bag
)。按下确认键后,你会看到下面的消息
[ INFO] [1551144307.272157111]: Subscribing to /chatter
[ INFO] [1551144307.274766644]: Recording to record_poseStamped.bag.
表示已经在开始记录chatter发布的消息了,消息会存储到record_poseStamped.bag里。如果topic没有消息发布,那么自然不会有任何东西会储存到这个rosbag文件里,这个文件会一直处于检测是否有消息发布的状态。你如果去看dataset文件夹里的图标,会发现一个叫record_poseStamped.bag.active的文件,表示这个bag文件目前正在处于记录的状态。 之后我们打开另一个terminal,输入下面的命令
cd ~/catkin_ws
source devel/setup.bash
rosrun pub_sub_test pub_poseStamped
把pub_poseStamped跑起来。你应该看到print出很多信息,这时候你观察跑rosbag那个terminal,什么也没有输出。 你可能会担心,到底是不是在记录发布出来的消息。rosbag里的topic名字和你publisher的名字是在对应上的,就一定在记录。极少数情况rosbag会拒绝记录新的消息,比如你的磁盘空间小于一个G了,rosbag会自动停止记录,如果你的磁盘空间小于5个G了,会出现warning但是不影响记录。 有些时候写程序的人并不会把publisher发布的消息print出来,你如果有成千上万条消息发布都print出来确实很烦。这时候你publisher的terminal中没什么信息print出来,rosbag的terminal中没什么信息print出来,你可能慌得一匹,不知道消息有没有被发布出来。你可以用下面的方式检查一下你的topic有没有发布消息。 打开另一个terminal,输入
rostopic echo /chatter
这行命令会把你chatter这个topic发布的命令print到terminal中。按下确认之后你会安心地看到下面的内容。
上面那行命令其实也相当于你跑了一个subscriber并且把收到的消息print出来。并且格式固定。可以看到每一则消息由---
分开。然后显示出你消息的header(我们第三讲讲过header这个包含的成员由seq,stamp,frame_id,他们分别对应uint32,time,string类型的变量,没有印象了可以再回去回顾)。同时print出来了pose的内容,即position和orientation。 当你觉得记录到足够的数据之后,点击rosbag在运行的那个terminal并按下ctrl+c
,rosbag就会停止记录并被保存下来了。每次记录完数据,我们都要马上检查一下是否记录成功。这时候我们在terminal中使用下面的命令可以看到rosbag的信息
rosbag info record_poseStamped.bag
运行这行命令,我们可以看到下面的信息。
其中我们可以看到这个bag文件记录了多少消息,记录的是哪个topic的消息,消息的类型是什么等。读者自行研究了。 至此利用rosbag采集(记录)数据工作就完成了。
重新使用储存在rosbag内的数据
当你采集完成数据之后,要拿回去分析,这时你就需要重新把储存在bag里的消息发布出来。 首先确保roscore已经运行,cd到你rosbag所在的文件夹,然后执行下面的命令
rosbag play record_poseStamped.bag
这时你会看到下面的内容
表示bag已经在发布消息了。上面的操作是什么意思呢? 当你重新使用rosbag的数据(即使用rosbag play bag_name.bag)的时候,你的rosbag自身相当于一个publisher程序。 你的消息会在rosbag记录的topic的名字下重新发布出来。如果你打开一个terminal,重新运行我们之前的sub_poseStamped.cpp对用的那个node,即在新的terminal中source之后运行
rosrun pub_sub_test sub_poseStamped
你应该会看到和第三讲里面同事运行pub和sub程序时一样的内容。只不过这时候我们的rosbag取代了那个pub程序而已。 这儿稍微值得注意的一点是,我们上面print出来的Bag Time
是这个rosbag收到每一则消息时的时间,并不是我们poseStamped里那个stamp储存的时间。
总结
这么快就总结了,我是不是越来越懒了,飘了…不是滴,主要是关于rosbag最主要的作用就是两个:作为subscriber接收信息并储存,作为publisher重新发布信息,没有太多需要解释的。虽然其实rosbag ...
后面还可以跟许多命令。详情可以见 http://wiki.ros.org/rosbag/Commandline 比如网页中在rosbag record部分,你可以在rosbag record后接–duration命令指定最长记录多少时间; rosbag play部分,你可以在rosbag play 后接–pause命令,这样你开始运行bag时不发布数据,直到你按下空格键它才开始发布,同样你再按空格键rosbag又会暂停发布。 rosbag filter部分,你可以使用rosbag filter 命令拆分一个rosbag。正如filter部分中的例子所说
rosbag filter input.bag output.bag "t.to_sec() <= 1284703931.86"
上面的命令需要你有inputbag,然后它会把Bag Time<=1284703931.86的部分提取出来,重新放到一个新的ouput.bag里。这个命令在你bag文件很大你只需要其中一部分时还是很管用的。记录图片的rosbag动不动就几十个G. 总是记住它最基础的作用然后你根据你的需要去慢慢研究使用更高级的命令。 前面七讲我们说了发布接收了那么多数据,是时候把数据可视化一下了。下一讲我们学习一下rviz的基础,这是ros自带的强大的可视化程序。