传感器获取到的信息,有时我们可能需要实时处理,有时可能只是采集数据,事后分析,比如:
机器人导航实现中,可能需要绘制导航所需的全局地图,地图绘制实现,有两种方式
方式1
:可以控制机器人运动,将机器人传感器感知到的数据时时处理,生成地图信息。方式2
:同样是控制机器人运动,将机器人传感器感知到的数据留存,事后,再重新读取数据,生成地图信息。两种方式比较,显然方式2使用上更为灵活方便。在ROS中关于数据的留存以及读取实现,提供了专门的工具: rosbag。rosbag本质也是ros的节点,当录制时,rosbag是一个订阅节点,可以订阅话题消息(这是ROS核心的数据通讯,ros开发每天都会打交道的话题通讯机制
)并将订阅到的数据写入磁盘文件;当重放时,rosbag是一个发布节点,可以读取磁盘文件,发布文件中的话题消息。这就有助于我们基于离线数据快速重现曾经的实际场景,进行可重复、低成本的分析和调试。如果有ROS基础,下面的内容将很好理解,否则并不能快速学会使用:
录制所有话题数据(此时会在当前路径下生成名称为当前时间的bag包):
rosbag record -a
录制指定话题数据:
rosbag record <topic_name1> <topic_name2> <topic_name3> ...
指定指定话题数据并指定保存bag的路径名称:
rosbag record -O <bagname> <topic_name1> <topic_name2> <topic_name3> ...
rosbag info指令可以数据包中包含的话题名称,话题数量,话题消息类型等信息:
rosbag info <bagname>
通过rqt_bag命令将bag进行(数据流)可视化
rqt_bag <bagname>
bag的回放就像放视频一样,可以再现数据录制时的实时数据流,但是有一些命令可以控制播放时间、速率、话题等功能:
回放指定bag(一般最常用)
rosbag play <bagname>
回放当前目录下所有bag
rosbag play *
从指定时间(n = 指定时间s)开始回放bag
rosbag play -s n <bagname>
延时指定时间(n = 延时时间s)开始回放bag
rosbag play -d n <bagname>
播放指定结束时间(n = 指定秒数)的bag
rosbag play -u n <bagname>
从指定时间(n = 开始时间s)开始播放到指定时间(m = 指定播放时间s)的bag
rosbag play -s n -u m <bagname>
按指定倍率(n = 倍率)回放bag
rosbag play -r n <bagname>
只播放感兴趣的 topic
rosbag play <bagname> --topic /topic1 /topic2 ...
播放bag的 topic重命名:
rosbag play <bagname> /topic1:=/topic1
回放包时,其他节点可以接受实时的话题数据,进行SLAM或者显示等处理,播放例如我们利用可视化工具rviz查看小车的点云和图像话题:
A-LOAM是一个纯激光SALM,订阅一个激光消息进行SLAM处理,因此首先我们要获取点云话题,即需要知道其话题名以及消息类型,通过rosbag info查看即可:
通过rostopic
可以在命令行订阅消息,查看其内容(每个话题都一定包含header
消息,其中有消息的时间戳stamp
和其对应的坐标系frame_id
,--noarr
参数是把点云原始数据data
折叠起来了,否则满屏显示"
看不到消息其他内容):
知道bag中的点云话题/point_raw
后,在代码中订阅点云消息
ros::Subscriber subLaserCloud = nh.subscribe<sensor_msgs::PointCloud2>(/point_raw, 100, laserCloudHandler);
其中sensor_msgs::PointCloud2
是点云消息类型,一些特殊的数据例如点云、IMU和图像等,ROS中有定义好的消息类型,我们还可以定义自己的消息(底层就是一个C++类);/point_raw
就是要订阅的话题名称;100是缓存队列的长度,防止处理时间跟不上bag播放速度而丢失数据;laserCloudHandler
是回调函数,用于保存或者处理接收的数据。
接下来同时播放包和运行SLAM节点,SLAM算法即可实时接收点云数据并实时处理:
# 分别打开两个终端,输入命令
roslaunch aloam_velodyne aloam_velodyne_VLP_16.launch
rosbag play autoware-20230608161607.bag