ROS系列实践1.3-ROS的通信机制(上)

ROS系列实践

第一部分:机器人环境感知与路径规划( Turtlebot 机器人)

(三)ROS的通信机制(上)

在上一节中我们窥视了ROS的工程文件架构,知道了catkin workspace以及package的概念。本节我们介绍ROS最核心的内容:其通信机制,以及用仿真实例观察这些通信机制的运行。

ROS工作的基本单位是Node节点,相当于操作系统中的进程,在工程文件中可以理解为可执行文件,这些Node由Master统一管理,通过Master相互通信。ROS主要为用户提供了以下几种通信机制:

  • Topic
  • Service
  • Parameter Server
  • Action

本节将对Master与Node,以及这些通信机制作逐一介绍,辅以仿真实例观察这些通信机制的运行。

1.3.1 Master、Node与launch文件

正如前文所述,如果将ROS看做操作系统,其中的Node就相当于操作系统中运行的进程,而Master相当于操作系统内核,完成了进程调度和进程间通信的工作。就像启动一台电脑一样,我们启动ROS的第一步就是启动操作系统内核,所用的命令我们在1.1测试环节已经使用过了:

roscore

在这里插入图片描述
这条指令启动了Master,同时也启动了rosout这个节点以及parameter server,我们可以通过上图的PARAMETERS下面的信息看到,Master启动的时候parameter server初始化了一些参数;而rosout节点是用于输出所有节点日志信息的,其他节点的报错或其他反馈信息都会通过rosout节点输出。

在启动了操作系统内核之后我们就可以启动一些进程进行工作了。节点和可执行文件的关系也相当于进程和代码的关系,我们上一节提到package里存放的代码,其python脚本或c++编译生成的二进制可执行文件,每一个文件运行起来就是一个节点。因此我们使用命令格式:rosrun <package名> <节点名>,即可启动一个节点的运行,例如我们在1.1使用过的:

rosrun rviz rviz

这个命令让ROS启动了rviz节点,这个节点指挥了可视化程序RViz启动。在使用rosrun之前必须先启动Master,否则ROS会报错,节点启动失败。

以下列出有关Node节点的常用操作:

在这里插入图片描述
在上一节的工程架构中我们提到了,某些复杂的功能需要启动很多节点,我们在命令行里一个一个输入非常繁琐,ROS为我们设计了launch文件机制,可以通过编写launch文件一次启动包里的多个节点。这些launch文件一般存放在package下的launch文件夹中,我们通过命令格式:roslaunch <package名> <launch文件名> 来运行它。

roslaunch turtlebot_gazebo turtlebot_world.launch

这也是我们在1.1使用过的命令,它启动了turtlebot机器人的gazebo仿真launch文件,该文件启动了很多节点,也配置了一系列初始参数,我们可以通过该命令的反馈信息看到,也可以单独使用rosnode list查看:

在这里插入图片描述
值得一提的是,launch文件启动节点之前,ROS会自动检测Master有没有启动,如果没有启动它会自动启动Master。因此使用launch文件启动节点的时候是无需手动使用roscore的。launch文件也是一种xml文件,主要书写格式如下,无需记背,有需要时查阅即可:

在这里插入图片描述
在这里我们发现launch文件是可以include其他launch文件的,这样就实现了跨包调用。

1.3.2 Topic与Message

Topic是ROS最常用的通信方式。简单来说,Topic可以看做是公告栏,由发布者不断向其中张贴公告,接收者不断从中获取,公告栏里公告的写作格式由Message格式(.msg文件)所定义,一条一条的公告本身称作Message。

Topic是一种异步通信方式,这里的异步可以理解为“宽松”的公告发布模式。公告的发布者唯一要做的就是不断地向公告栏发布通知,但他们并不关心有没有接收者收到这些通知,即无需“收到回复”的通知,因此发布者并不根据消息被接收的情况进行阻塞等待。公告的接收者甚至也不需要关心发布者本身的详细信息,他们唯一要做的就是从公告栏获取信息进行处理。

同一个Topic允许多个接收者同时接受信息,甚至允许多个发布者同时发布。

实际上Topic通信机制的实现就在于定义Message格式,以及操纵节点收发Message。有关.msg文件和Message消息,二者的关系可以理解为前者是静态的、定义好的类,而后者是节点将类实例化出的对象。ROS规定了如下的.msg文件基本类型:

在这里插入图片描述
这些类型的含义都可以顾名思义,很好理解。.msg文件的书写方式也非常简洁,我们可以通过以下的命令来查看sensor_msg包中的Image格式是如何书写的:

roscd sensor_msgs
cd msg
gedit Image.msg

在这里插入图片描述
这是ROS官方代码包定义的图像信息格式,整个.msg文件非常类似于C语言的结构体,通过官方注释我们也能清晰地理解其每个变量的含义。与Node类似,ROS有一系列命令可以查看或操作正在运行的Topic或正在传递的Message,如下记录:

在这里插入图片描述
接下来我们通过仿真体会Topic的通信。使用如下命令启动turtlebot仿真:

roslaunch turtlebot_gazebo turtlebot_world.launch

看到仿真界面弹出后我们打开另一个终端,使用rostopic list可以看到正在运行的所有Topic:

rostopic list

可以看到有非常多的topic在运行,此时我们可以查看具体某一个topic的详细信息,使用rostopic info <Topic名>例如turtlebot仿真的kinect相机,其发布的Topic均以/camera开头,包括了深度信息和rgb信息。我们可以查看rgb信息所在Topic的运行情况:

rostopic info /camera/rgb/image_raw

在这里插入图片描述
可以看出,这个图像信息是由/gazebo节点发布的,目前暂时没有接收者。Topic的特点在于,该节点会持续不断地实时更新所发布的Message,而并不理会消息的接收情况。想要为这个Topic指定一个接收者也是容易的,ROS有专门的image_view包用来显示目前接收到的图像信息。其用法用到了上文提到的rosrun,格式为:rosrun image_view image_view image:=<发布Image的Topic名>

rosrun image_view image_view image:=/camera/rgb/image_raw

在这里插入图片描述
这样就可以看到仿真环境中的kinect摄像头传回的实时画面了。此时如果再次运行rostopic info,就可以看到原本的/camera/rgb/image_raw这个Topic多了接收者:

rostopic info /camera/rgb/image_raw

在这里插入图片描述
此时我们打开前面介绍过的遥控节点teleop,用键盘控制机器人移动,同时观察image_view的窗口,我们可以看到实时变化的图像画面,这是由一帧一帧的Image信息通过Topic传递给image_view这个节点的:

roslaunch turtlebot_teleop keyboard_teleop.launch
# 通过键盘操控机器人在仿真界面中移动,同时调出刚才打开的image_view画面进行观察
# 注意打开teleop的终端必须在最上层才可以控制移动

在这里插入图片描述
通过这种方式我们不难想象,当我们想要写代码对机器人kinect相机传回图像进行图像分析,将视觉的技术赋予这台机器人时,只需要从相应的Topic接收Image信息,就获得了kinect相机的图像信息。在此我们初步体验了ROS平台如何通过其Topic通信机制来让嵌入式开发变得更加便捷。

发布了12 篇原创文章 · 获赞 2 · 访问量 500

猜你喜欢

转载自blog.csdn.net/JeremyZhao1998/article/details/104470104