头文件1
2
3
4
5
6
读写bag文件
open
函数默认是读模式。
写bag文件:1
2
3
4
5
6
7
8
9
10rosbag::Bag bag;
try{
bag.open("/home/user/plan.bag", rosbag::bagmode::Write);
}
catch (const rosbag::BagException& ex) {
ROS_ERROR("open rosbag error: %s", ex.what() );
return;
}
bag.write("record_plan",ros::Time::now(), coverage_plan);
bag.close();
打开文件的模式有:enum rosbag::bagmode::BagMode
1
2
3Write
Read
Append
读bag文件一定要用try
和catch
下面的例子,bag文件只有一个话题/move_base/transformed_plan
,一堆nav_msgs/Path
消息1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30rosbag::Bag bag;
try{
bag.open("/home/user/plan.bag", rosbag::bagmode::Read);
}
catch (const rosbag::BagException& ex) {
ROS_ERROR("open rosbag error: %s", ex.what() );
return;
}
std::vector<std::string> topics;
bool bag_read_once = false;
topics.push_back(std::string("record_plan") );
rosbag::View view(bag, rosbag::TopicQuery(topics) );
BOOST_FOREACH(rosbag::MessageInstance const m, view)
{
nav_msgs::Path::ConstPtr i = m.instantiate<nav_msgs::Path>();
plan_from_bag.header.frame_id = i->header.frame_id;
plan_from_bag.header.stamp = i->header.stamp;
plan_from_bag.header.seq = i->header.seq;
unsigned int path_size = i->poses.size();
ROS_INFO("plan from bag size: %zu",i->poses.size() );
plan_from_bag.poses.reserve(path_size);
if(bag_read_once) break;
plan_from_bag.poses = i->poses;
bag_read_once = true;
}
bag.close();
注意读的时候,topics容器的元素必须还是number
,与写文件时一致。如果不一致,读文件会不执行foreach
用到的类如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21/* Create a view and add a query
* param bag The bag file on which to run this query
* param query The actual query to evaluate which connections to include
* param start_time The beginning of the time range for the query
* param end_time The end of the time range for the query
* param reduce_overlap If multiple views return the same messages, reduce them to a single message
*/
View(Bag const& bag, boost::function<bool(ConnectionInfo const*)> query,
ros::Time const& start_time = ros::TIME_MIN, ros::Time const& end_time = ros::TIME_MAX, bool const& reduce_overlap = false);
class ROSBAG_DECL TopicQuery
{
public:
TopicQuery(std::string const& topic);
TopicQuery(std::vector<std::string> const& topics);
bool operator()(ConnectionInfo const*) const;
private:
std::vector<std::string> topics_;
};
rosbag::View
的常用函数
iterator begin()
Simply copy the merge_queue state into the iterator.iterator end()
Default constructed iterator signifies end.ros::Time getBeginTime()
ros::Time getEndTime()
uint32_t size ()
获得bag文件中所含消息的个数,不是文件大小
其他常用函数1
2
3
4
5
6
7// Get the filename of the bag
std::string getFileName () const
// Get the current size of the bag file (a lower bound) More...
uint64_t getSize () const
bool isOpen () const
问题
bag文件 unindexed
这种情况下如果没有用try
和catch
就会出错
我查来查去,没发现C++ API里有类似rosbag reindex
命令的函数,只能不处理。似乎python里有,没有深入研究,
参考:
rosbag API