在自动驾驶中,有时在测试过程中无法对运行过程中的各个环节进行判断,这时则需要使用ros中的录包功能对运行中各个topic进行录制,如果向一股脑的将所有topic进行录制只需要运用一下命令对其录制。rosbag record -a
rosbag record有很多具体的命令,这里不做详细记录,有兴趣的可以自行百度,在获得录制后的bag后如何对其录制的数据进行解析或者保存呢?这里有两种方法:
一:使用命令rosbag paly
对数据包进行回放,然后通过自己手写订阅某个topic的程序或者ros中已有的工具对bag包中的数据进行解析或者获取数据后保存。
这种方法往往有一个缺点就是不能将bag包中所有的数据全部进行进行解析或者保存。所以通常不用,这里重点介绍下第二种方法。
二、通过创建view类将数据逐帧读取出来,然后按照topic对对应的数据进行处理或者保存。代码模板如下:
#include <rosbag/bag.h>
#include <rosbag/view.h>
// 此处为include相关消息类的头文件,如果有自定义的头文件,请将其包含在内
#include <std_msgs/Int32.h>
#include <std_msgs/String.h>
#include <sensor_msgs/PointCloud2.h>
//
#include <ros/ros.h>
int main(int argc, char** argv)
{
// 初始化ROS
ros::init (argc, argv, "exe_name");
//打开bag文件
rosbag::Bag bag;
bag.open("xxx.bag", rosbag::bagmode::Read);
//设置需要遍历的topic
std::vector<std::string> topics;
topics.push_back(std::string("/topicname1"));
topics.push_back(std::string("//topicname2"));
topics.push_back(std::string("//topicname3"));
//创建view,用于读取bag中的topic
rosbag::View view(bag, rosbag::TopicQuery(topics));
//rosbag::View view_all(view); //读取全部topic
//使用迭代器的方式遍历,注意:每一个迭代器为一帧数据
rosbag::View::iterator it = view.begin();
for(; it != view.end(); ++it)
{
//获取一帧数据内容,运用auto使其自动满足对应类型
auto m = *it;
//得到该帧数据的topic
std::string topic = m.getTopic();
if(topic == "/topicname1")
{
//此处为消息头文件中的ConstPtr
packagename::msgname::ConstPtr msgPtr = m.instantiate<packagename::msgname>();
if(msgPtr != NULL)
{
packagename::msgname::msg msg = *msgPtr;
...
process code
...
}
else
{
std::cout << "the null message<<std::endl;
continue;
}
}
if(topic == "/topicname2")
{
...
}
}
bag.close();
}
来源:oschina
链接:https://my.oschina.net/u/4264470/blog/4705717