使用rosbag录制数据的功能将txt转成bag
将txt文件读出来并发布到topic上,
比如:读取imu数据,发布到topic /imu_info上
#include <ros/ros.h>
#include <sensor_msgs/Imu.h>
#include <std_msgs/Float64.h>
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <fstream>
#include <cassert>
#include <time.h>
#include <std_msgs/Time.h>
// #include <conio.h>
using namespace std;
ros::Time timesamp2rostime(int64_t timesamp){
std::string suanz = std::to_string(timesamp);
std::string sec_string = suanz.substr(0,10);
std::string nsec_string = suanz.substr(10,9);
while(nsec_string.length() < 9){
nsec_string += "0";
}
return ros::Time(std::stoi(sec_string),std::stoi(nsec_string));
}
string replace(string original, char o, char n){
string res = original;
for(int i = 0; i < res.length(); i ++){
if(res[i] == o)res[i] = n;
}
return res;
}
int main(int argc, char **argv){
ros::init(argc, argv, "talker2");
ros::NodeHandle nh;
sensor_msgs::Imu msg;
ros::Publisher pub = nh.advertise<sensor_msgs::Imu>("imu_info", 1);
ros::Rate loop_rate(200);
// while(1){
// if(_kbhit()){
// int ch = _getch();
// if(ch == 27){
// break;
// }
// }
// }
// bool ros::Duration::sleep();
ros::Duration(5).sleep(); // sleep for half a second
vector<sensor_msgs::Imu> imu_vector;
// for(int i = 0; i < 3; i ++){
// msg.header.stamp = static_cast<ros::Time>(1234);
// msg.angular_velocity.x = 10;
// msg.angular_velocity.y = 12;
// msg.angular_velocity.z = i;
// imu_vector.push_back(msg);
// }
string pathname = "/home/efan/Downloads/imu_raw.txt";
ifstream infile;
infile.open(pathname.data());
assert(infile.is_open());
string pre_s = "";
string s;
while (getline(infile, s)) {
if(s[0] == '#')continue;
if(s == pre_s)continue;
pre_s = s;
s = replace(s,',',' ');
istringstream is(s);
sensor_msgs::Imu suanz;
int64_t time_imu;
// cout << s << endl;
s.clear();
is >> time_imu;
// ros::Time begin = ros::Time::now();
// cout << begin.sec << " "<<begin.nsec << endl;
is >> suanz.linear_acceleration.x;
is >> suanz.linear_acceleration.y;
is >> suanz.linear_acceleration.z;
is >> suanz.angular_velocity.x;
is >> suanz.angular_velocity.y;
is >> suanz.angular_velocity.z;
suanz.header.stamp = timesamp2rostime(time_imu);
msg = suanz;
ROS_INFO_STREAM(msg);
pub.publish(msg);
loop_rate.sleep();
}
infile.close();
return 0;
}
之后运行该节点后运行下述代码即可将固定topics的数据录制到filename.bag中
rosrun rosbag record -O filename.bag topic-names
# or rosrun all topic that includes "info"
rosrun rosbag record -O imu_Rpose.bag -e "(.*)info(.*)"
而且必须先运行起topic-names所在的节点后,运行上述代码才有效,因此在具体的读取txt的代码中设置暂停时间
详细代码见https://github.com/Efanplus/make_bag_from_txt
注:rosbag 可以支持自动排序,即不同sensor的数据录制后,其可以根据自带的time排序,存储起来
有时没有进行指针close,会导致bag的index有问题而不可用,可使用reindex修正
rosbag reindex name.bag
rosbag → \rightarrow → txt
使用指令将rosbag转换为txt, 如:将imu_info 的数据转为t,后缀名自定, 第一行会以'%'为首给出各列含义
rostopic echo -b imu_encoder.bag -p /imu_info >t
挑选出rosbag中某些topic或者满足某些条件的数据
利用 rosbag
rosbag filter input.bag output.bag 'topic == "/camera/image_raw/compressed" or topic == "/scan" or topic == "/timetag" or topic == "/tf" and m.transforms[0].header.frame_id != "/odom" and m.transforms[0].child_frame_id != "/odom"'
merge two rosbag into one
使用第三方文本bag_merge.py github地址
bag_merge.py --help
usage: bagmerge.py [-h] [-o output_file] [-t topics] [-i] main_bagfile bagfile
Merges two bagfiles.
positional arguments:
main_bagfile path to a bagfile, which will be the main bagfile
bagfile path to a bagfile which should be merged to the main bagfile
optional arguments:
-h, --help show this help message and exit
-o output_file name of the output file
-t topics topics which should be merged to the main bag
-i reindex bagfile