ROS系列:第五章常用组件rosbag

五、ROS常用组件

2.rosbag

在ROS中关于数据的留存以及读取实现,提供了一个专门的工具:rosbag;

概念:

用于录制和回放ROS主题的一个工具集。

作用:

实现了数据的复用,方便调试、测试

本质:

rosbag本质也是ros的节点,当录制时,rosbag是一个订阅节点,可以订阅话题消息并将订阅的数据写入磁盘文件;当回放时,rosbag是一个发布节点,可以读取磁盘文件,发布文件中的话题消息;

2.1 rosbag使用——命令行


需求:ROS内置的乌龟,操作过程使用rosbag录制,录制结束后,实现重放。

实现:

1、创建目录保存录制的文件

mkdir ./bags
cd bags

2、开始录制

roscore 
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key

启动乌龟GUI以及键盘控制节点;

rosbag record -a -o bags/hello

操作小乌龟运行一段时间,结束录制使用ctrl+c,,在创建的目录中会生成bag后缀文件;

3、查看文件

rosbag info bags/hello_2022-11-16-21-32-41.bag 
path:        bags/hello_2022-11-16-21-32-41.bag
version:     2.0
duration:    21.3s
start:       Nov 16 2022 21:32:41.60 (1668605561.60)
end:         Nov 16 2022 21:33:02.89 (1668605582.89)
size:        216.7 KB
messages:    2902
compression: none [1/1 chunks]
types:       geometry_msgs/Twist [9f195f881246fdfa2798d1d3eebca84a]
             rosgraph_msgs/Log   [acffd30cd6b6de30f120938c17c593fb]
             turtlesim/Color     [353891e354491c51aabe32df673fb446]
             turtlesim/Pose      [863b248d5016ca62ea2e895ae5265cf9]
topics:      /rosout                    3 msgs    : rosgraph_msgs/Log  
             /turtle1/cmd_vel         265 msgs    : geometry_msgs/Twist
             /turtle1/color_sensor   1317 msgs    : turtlesim/Color    
             /turtle1/pose           1317 msgs    : turtlesim/Pose

4、回放文件

rosbag play bags/hello_2022-11-16-21-32-41.bag 

重启乌龟节点,此时可以看见乌龟按照bag文件录制的轨迹运行

注:rosbag也是一个节点,因此也可使用rosrun操作。

2.2 rosbag使用——编码

命令行不够灵活,,因此使用编码的模式加强灵活性

1、写bag

实现流程:

初始化;
创建rosbag对象;
打开文件流;
写数据;
关闭文件流;

代码:

#include "ros/ros.h"
#include "rosbag/bag.h"
#include "std_msgs/String.h"
/*
    需求:使用rosbag 向磁盘文件写入数据(话题+消息)
    流程:
        1、导包
        2、初始化;
        3、创建rosbag对象
        4、打开文件流
        5、写数据
        6、关闭文件流
*/

int main(int argc, char  *argv[])
{
    
    
    // 2、初始化;
    setlocale(LC_ALL,"");
    ros::init(argc,argv,"bag_write");
    ros::NodeHandle nh;
    // 3、创建rosbag对象
    rosbag::Bag bag;

    // 4、打开文件流
    bag.open("hello.bag",rosbag::BagMode::Write);
    // 5、写数据
    std_msgs::String msg;
    msg.data="hello  xxxx";

    bag.write("", ros::Time::now(), msg);
    bag.write("", ros::Time::now(), msg);
    bag.write("", ros::Time::now(), msg);
    bag.write("", ros::Time::now(), msg);

    // 6、关闭文件流
    bag.close();
    return 0;
}

2、读bag

实现流程:

类似,本质操作磁盘文件

代码:

#include "ros/ros.h"
#include "rosbag/bag.h"
#include "rosbag/view.h"
#include "std_msgs/String.h"

/*
    需求:使用rosbag 读取磁盘上的bag文件
    流程:
        1、导包
        2、初始化;
        3、创建rosbag对象
        4、打开文件流(以读的方式打开)
        5、读数据
        6、关闭文件流
*/

int main(int argc, char *argv[])
{
    
    
    // 2、初始化;
    setlocale(LC_ALL,"");
    ros::init(argc,argv,"bag_read");
    ros::NodeHandle nh;
    // 3、创建rosbag对象
    rosbag::Bag bag;
    // 4、打开文件流(以读的方式打开)
    bag.open("hello.bag", rosbag::BagMode::Read);
    // 5、读数据
    //因为磁盘文件保存数据类型读也要读出来
    //取出时间戳,话题和消息内容
    //先获取消息的集合,再迭代取出消息的字段具体

    for (auto &&m : rosbag::View(bag))
    {
    
    
        //解析
        std::string topic = m.getTopic();
        ros::Time time = m.getTime();
        std_msgs::StringPtr p = m.instantiate<std_msgs::String>();
        ROS_INFO("解析的内容,话题:%s,时间戳:%.2f,消息值:%s",topic.c_str(),time.toSec(),p->data.c_str());
    }

    // 6、关闭文件流
    bag.close();
    return 0;
}

出现错误:

terminate called after throwing an instance of 'ros::InvalidNameException'
  what():  Character [ ] at element [7] is not valid in Graph Resource Name [dwadawd 1].  Valid characters are a-z, A-Z, 0-9, / and _.
已放弃 (核心已转储)

原因分析:cpp文件存在命名错误,删去空格或者改为下划线

解决问题:经检查发现初始化的过程中,话题的名称随意打成dwadawd 1出现空格,修改为bag_read 后重新编译运行通过;

猜你喜欢

转载自blog.csdn.net/TianHW103/article/details/127895682