学习两种从bag文件指定topic中读取message的方式,包括使用ros_readbagfile脚本的方式。
下载或者记录bag文件
首先,我们需要一个bag文件。可以从上一个博客:ROS学习-记录和回放数据中生成,或者从webviz中下载一个demo
也可以通过下述命令:
wget https://open-source-webviz-ui.s3.amazonaws.com/demo.bag
上述rosbag record命令中–duration=30代表记录30s的数据,–output-name=/tmp/mybagfile.bag代表生成的bag文件名称,后续/topic1 /topic2 /topic3代表我们感兴趣的topic。
注意:后续命令中都使用了time作为前置,能够让我们了解每一个命令执行所花费的时间。如果不需要,可以直接删除time前缀。
方案1:立即回放message,并在多个terminal窗口查看输出
首先,我们使用rosbag info查看bag文件中具体的topic名称:
$ time rosbag info demo.bag
返回值应该为如下形式:
path: demo.bag version: 2.0 duration: 20.0s start: Mar 21 2017 19:37:58.00 (1490150278.00) end: Mar 21 2017 19:38:17.00 (1490150298.00) size: 696.2 MB messages: 5390 compression: none [600/600 chunks] types: bond/Status [eacc84bf5d65b6777d4c50f463dfb9c8] diagnostic_msgs/DiagnosticArray [60810da900de1dd6ddd437c3503511da] diagnostic_msgs/DiagnosticStatus [d0ce08bc6e5ba34c7754f563a9cabaf1] nav_msgs/Odometry [cd5e73d190d741a2f92e81eda573aca7] radar_driver/RadarTracks [6a2de2f790cb8bb0e149d45d297462f8] sensor_msgs/Image [060021388200f6f0f447d0fcd9c64743] sensor_msgs/NavSatFix [2d3a8cd499b9b4a0249fb98fd05cfa48] sensor_msgs/PointCloud2 [1158d486dd51d683ce2f1be655c3c181] sensor_msgs/Range [c005c34273dc426c67a020a87bc24148] sensor_msgs/TimeReference [fded64a0265108ba86c3d38fb11c0c16] tf2_msgs/TFMessage [94810edda583a504dfda3829e70d7eec] velodyne_msgs/VelodyneScan [50804fc9533a0e579e6322c04ae70566] topics: /diagnostics 140 msgs : diagnostic_msgs/DiagnosticArray /diagnostics_agg 40 msgs : diagnostic_msgs/DiagnosticArray /diagnostics_toplevel_state 40 msgs : diagnostic_msgs/DiagnosticStatus /gps/fix 146 msgs : sensor_msgs/NavSatFix /gps/rtkfix 200 msgs : nav_msgs/Odometry /gps/time 192 msgs : sensor_msgs/TimeReference /image_raw 600 msgs : sensor_msgs/Image /obs1/gps/fix 30 msgs : sensor_msgs/NavSatFix /obs1/gps/rtkfix 200 msgs : nav_msgs/Odometry /obs1/gps/time 136 msgs : sensor_msgs/TimeReference /radar/points 400 msgs : sensor_msgs/PointCloud2 /radar/range 400 msgs : sensor_msgs/Range /radar/tracks 400 msgs : radar_driver/RadarTracks /tf 1986 msgs : tf2_msgs/TFMessage /velodyne_nodelet_manager/bond 80 msgs : bond/Status /velodyne_packets 200 msgs : velodyne_msgs/VelodyneScan /velodyne_points 200 msgs : sensor_msgs/PointCloud2 real 0m1.003s user 0m0.620s sys 0m0.283s
由上述结果中我们可以注意到在/obs1/gps/fix中有30个messages,在/diagnostics_agg中有40个messages。
我们就来提取这些信息:
1、 打开一个新的terminal,启动ros core
$ roscore
2、Ctrl + Alt + T 打开一个新的terminal或者在当前的terminal窗口使用Ctrl + Shift + T打开一个新的tab,订阅前述所说的/obs1/gps/fix,echo该topic的所有输出同时将其记录到一个指定的yaml文件中,以便日后查看。使用命令如下:
rostopic echo /obs1/gps/fix | tee topic1.yaml
我们可以看到提示还没有发布/obs1/gps/fix这个话题:
WARNING: topic [/obsl/gps/fix] does not appear to be published yet
3、打开另外一个新的Terminal,订阅另外一个话题:/diagnostics_agg。
rostopic echo /diagnostics_agg | tee topic2.yaml
同时,我们也可以看到这个提示:
WARNING: topic [/diagnostics_agg] does not appear to be published yet
4、针对你所感兴趣的topic,重复上述操作,注意每个topic需要在其自己的terminal中进行操作。
5、打开一个新的terminal,使用rosbag play进行播放已有的bag文件,使用 --immediate 参数,尽可能快的发布bag文件中的topic。命令用法如下:
time rosbag play --immediate demo.bag --topics /topic1 /topic2 /topic3 /topicN
因此,针对我们所感兴趣的/obs1/gps/fix话题和/diagnostics_agg话题。命令变为如下形式:
time rosbag play --immediate demo.bag --topics /obs1/gps/fix /diagnostics_agg
返回结果类似于下述形式:
[ INFO] [1591916465.758724557]: Opening demo.bag Waiting 0.2 seconds after advertising topics... done. Hit space to toggle paused, or 's' to step. [RUNNING] Bag Time: 1490150297.770734 Duration: 19.703405 / 19.703405 Done. real 0m1.570s user 0m0.663s sys 0m0.394s
6、现在我们就完成了对所感兴趣的/obs1/gps/fix话题和/diagnostics_agg话题中message的记录。从而得到了两个YAML类型文件,在YAML文件中,通过—线进行分割相邻的message,打开刚才生成的topic1.yaml文件,内容类似于下述形式:
--- header: seq: 4027 stamp: secs: 1490150296 nsecs: 66947432 frame_id: "gps" status: status: 0 service: 1 latitude: 37.4008017844 longitude: -122.108119889 altitude: -6.4380177824 position_covariance: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] position_covariance_type: 0 --- header: seq: 4028 stamp: secs: 1490150297 nsecs: 744347249 frame_id: "gps" status: status: 0 service: 1 latitude: 37.4007565466 longitude: -122.108159482 altitude: -6.35130467023 position_covariance: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] position_covariance_type: 0 ---
如果,我们的一个rostopic进程错过了消息,则只需使用Ctrl+C终止它的进程,重新启动它,然后再次调用rosbag play命令。
方案2:使用ros_readbagfile脚本来简单的提取感兴趣的topic
1、使用下述命令下载一个ros_readbag.py`文件:
# Download the file wget https://raw.githubusercontent.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/master/useful_scripts/ros_readbagfile.py
给下载好的ros_readbagfile.py文件增加可执行权限:
chmod +x ros_readbagfile.py
创建一个bin文件夹,存放个人生成的二进制文件。
mkdir -p ~/bin
把ros_readbagfile.py文件移动到bin文件夹下,并将名称修改为ros_readbagfile
mv ros_readbagfile.py ~/bin/ros_readbagfile
重新激活一下~/.bashrc文件,保证当前bin文件在PATH中。之后我们就可以使用ros_readbagfile命令了。(就像安装了它一样)
. ~/.bashrc
安装所需要的依赖:
pip install bagpy pip3 install bagpy
2、类似于方案1中所述的方法,使用rosbag info查看bag文件中所包含的topic。
3、针对bag文件中所感兴趣的topic,使用ros_readbagfile命令进行记录。命令使用方法如下:
# read these topics and print them to stdout time ros_readbagfile <mybagfile.bag> [topic1] [topic2] [topic3] [...] # Write to the topics.yaml file withOUT also printing to stdout time ros_readbagfile <mybagfile.bag> [topic1] [topic2] [topic3] [...] > topics.yaml # OR (preferred, so you can easily see it is still running): write to the # topics.yaml file AND print to stdout time ros_readbagfile <mybagfile.bag> [topic1] [topic2] [topic3] [...] | tee topics.yaml
比如,对于我们在方案1中所读取的/obs1/gps/fix话题和/diagnostics_agg话题:
# (preferred, so you can easily see it is still running): write to the # topics.yaml file AND print to stdout time ros_readbagfile demo.bag /obs1/gps/fix /diagnostics_agg | tee topics.yaml