写在前面,本系列笔记参考的是AutoLabor的教程,具体项目地址在 这里
机器人传感器获取到的信息,有时我们可能需要时时处理,有时可能只是采集数据,事后分析,比如:
机器人导航实现中,可能需要绘制导航所需的全局地图,地图绘制实现,有两种方式,方式1:可以控制机器人运动,将机器人传感器感知到的数据时时处理,生成地图信息。方式2:同样是控制机器人运动,将机器人传感器感知到的数据留存,事后,再重新读取数据,生成地图信息。两种方式比较,显然方式2使用上更为灵活方便。
在ROS中关于数据的留存以及读取实现,提供了专门的工具: rosbag。
概念
是用于录制和回放 ROS 主题的一个工具集。
作用
实现了数据的复用,方便调试、测试。
本质
rosbag本质也是ros的节点,当录制时,rosbag是一个订阅节点,可以订阅话题消息并将订阅到的数据写入磁盘文件;当重放时,rosbag是一个发布节点,可以读取磁盘文件,发布文件中的话题消息。
需求:
ROS 内置的乌龟案例并操作,操作过程中使用 rosbag 录制,录制结束后,实现重放
实现:
1.准备
创建目录保存录制的文件
mkdir ./xxx
cd xxx
2.开始录制
rosbag record -a -O 目标文件
操作小乌龟一段时间,结束录制使用 ctrl + c,在创建的目录中会生成bag文件。
3.查看文件
rosbag info 文件名
4.回放文件
rosbag play 文件名
重启乌龟节点,会发现,乌龟按照录制时的轨迹运动。
示例结果:
命令实现不够灵活,可以使用编码的方式,增强录制与回放的灵活性,本节将通过简单的读写实现演示rosbag的编码实现。
方案A:C++实现
1.写 bag
#include "ros/ros.h"
#include "rosbag/bag.h"
#include "std_msgs/String.h"int main(int argc, char *argv[])
{ros::init(argc,argv,"bag_write");ros::NodeHandle nh;//创建bag对象rosbag::Bag bag;//打开bag.open("/home/rosdemo/demo/test.bag",rosbag::BagMode::Write);//写std_msgs::String msg;msg.data = "hello world";bag.write("/chatter",ros::Time::now(),msg);bag.write("/chatter",ros::Time::now(),msg);bag.write("/chatter",ros::Time::now(),msg);bag.write("/chatter",ros::Time::now(),msg);//关闭bag.close();return 0;
}
2.读bag
/* 读取 bag 文件:*/
#include "ros/ros.h"
#include "rosbag/bag.h"
#include "rosbag/view.h"
#include "std_msgs/String.h"
#include "std_msgs/Int32.h"int main(int argc, char *argv[])
{setlocale(LC_ALL,"");ros::init(argc,argv,"bag_read");ros::NodeHandle nh;//创建 bag 对象rosbag::Bag bag;//打开 bag 文件bag.open("/home/rosdemo/demo/test.bag",rosbag::BagMode::Read);//读数据for (rosbag::MessageInstance const m : rosbag::View(bag)){std_msgs::String::ConstPtr p = m.instantiate();if(p != nullptr){ROS_INFO("读取的数据:%s",p->data.c_str());}}//关闭文件流bag.close();return 0;
}
示例效果:
方案B:Python实现
1.写 bag
#! /usr/bin/env python
import rospy
import rosbag
from std_msgs.msg import Stringif __name__ == "__main__":#初始化节点 rospy.init_node("w_bag_p")# 创建 rosbag 对象bag = rosbag.Bag("/home/rosdemo/demo/test.bag",'w')# 写数据s = String()s.data= "hahahaha"bag.write("chatter",s)bag.write("chatter",s)bag.write("chatter",s)# 关闭流bag.close()
2.读bag
#! /usr/bin/env python
import rospy
import rosbag
from std_msgs.msg import Stringif __name__ == "__main__":#初始化节点 rospy.init_node("w_bag_p")# 创建 rosbag 对象bag = rosbag.Bag("/home/rosdemo/demo/test.bag",'r')# 读数据bagMessage = bag.read_messages("chatter")for topic,msg,t in bagMessage:rospy.loginfo("%s,%s,%s",topic,msg,t)# 关闭流bag.close()
示例结果:
之前,在 ROS 中使用了一些实用的工具,比如: ros_bag 用于录制与回放、tf2_tools 可以生成 TF 树 … 这些工具大大提高了开发的便利性,但是也存在一些问题: 这些工具的启动和使用过程中涉及到一些命令操作,应用起来不够方便,在ROS中,提供了rqt工具箱,在调用工具时以图形化操作代替了命令操作,应用更便利,提高了操作效率,优化了用户体验。
概念
ROS基于 QT 框架,针对机器人开发提供了一系列可视化的工具,这些工具的集合就是rqt
作用
可以方便的实现 ROS 可视化调试,并且在同一窗口中打开多个部件,提高开发效率,优化用户体验。
组成
rqt 工具箱组成有三大部分
1.安装
一般只要你安装的是desktop-full版本就会自带工具箱
如果需要安装可以以如下方式安装
$ sudo apt-get install ros-noetic-rqt
$ sudo apt-get install ros-noetic-rqt-common-plugins
2.启动
rqt
的启动方式有两种:
rqt
rosrun rqt_gui rqt_gui
基本使用示例:使用rqt发布消息让小乌龟做圆周运动,示例结果:
rqt有一个常用插件rqt_graph
,可以以可视化的方式显示计算图,可以直接使用
rqt_graph
启动。
使用示例:
其中圆圈是节点,方框是话题。
**简介:**rqt_console 是 ROS 中用于显示和过滤日志的图形化插件
**准备:**编写 Node 节点输出各个级别的日志信息
/* ROS 节点:输出各种级别的日志信息*/
#include "ros/ros.h"int main(int argc, char *argv[])
{ros::init(argc,argv,"log_demo");ros::NodeHandle nh;ros::Rate r(0.3);while (ros::ok()){ROS_DEBUG("Debug message d");ROS_INFO("Info message oooooooooooooo");ROS_WARN("Warn message wwwww");ROS_ERROR("Erroe message EEEEEEEEEEEEEEEEEEEE");ROS_FATAL("Fatal message FFFFFFFFFFFFFFFFFFFFFFFFFFFFF");r.sleep();}return 0;
}
启动:
可以在 rqt 的 plugins 中添加,或者使用rqt_console
启动
**简介:**图形绘制插件,可以以 2D 绘图的方式绘制发布在 topic 上的数据
**准备:**启动 turtlesim 乌龟节点与键盘控制节点,通过 rqt_plot 获取乌龟位姿
**启动:**可以在 rqt 的 plugins 中添加,或者使用rqt_plot
启动
使用示例:
**简介:**录制和重放 bag 文件的图形化插件
**准备:**启动 turtlesim 乌龟节点与键盘控制节点
**启动:**可以在 rqt 的 plugins 中添加,或者使用rqt_bag
启动
录制:
重放:
使用示例:
http://www.autolabor.com.cn/book/ROSTutorials/di-2-zhang-ros-jia-gou-she-ji/23-fu-wu-tong-xin/224-fu-wu-tong-xin-zi-ding-yi-srv-diao-yong-b-python.html