SLAM+语音机器人DIY系列:(二)ROS入门——2.ROS系统整体架构

摘要

ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便。我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS基础知识进行详细的讲解,给不熟悉ROS的朋友起到一个抛砖引玉的作用。本章节主要内容:

1.ROS是什么

2.ROS系统整体架构

3.在ubuntu16.04中安装ROS kinetic

4.如何编写ROS的第一个程序hello_world

5.编写简单的消息发布器和订阅器

6.编写简单的service和client

7.理解tf的原理

8.理解roslaunch在大型项目中的作用

9.熟练使用rviz

10.在实际机器人上运行ROS高级功能预览



2.ROS系统整体架构

由于ROS系统的组织架构比较复杂,简单从一个方面来说明很难说清楚。按照ROS官方的说法,我们可以从3个方面来理解ROS系统整体架构,这3个方面分别是文件系统级、计算图级、开源社区级。

2.1.从文件系统级理解ROS架构

如果你是刚刚接手ROS方面的开发或项目,你肯定会觉得ROS中的各种概念非常奇怪,但是当你对ROS的使用熟练之后,你就觉得这些概念很好理解了。与其他操作系统相似,一个ROS程序的不同组件要被放在不同的文件夹下,这些文件夹是根据不同的功能来对文件进行组织的,如图3。

SLAM+语音机器人DIY系列:(二)ROS入门——2.ROS系统整体架构

(图3)文件系统级理解ROS架构

(1)工作空间

工作空间是一个包含功能包、可编辑源文件和编译包的文件夹,当你想同时编译不同的功能包时非常有用,并且可以保存本地开发包。当然,用户可以根据自己的需要创建多个工作空间,在每个工作空间中开发不同用途的功能包。不过作为学习,我们先以一个工作空间为例。如图3,我们创建了一个名为catkin_ws的工作空间,该工作空间下会有3个文件夹:src、build、devel。

src源文件空间:这个文件夹放置各个功能包和一个用于这些功能包的CMake配置文件CMakeLists.txt。这里做一下说明,由于ROS中的源码采用catkin工具进行编译,而catkin工具又是基于cmake技术的,所以我们会在src源文件空间和各个功能包中都会见到一个文件CMakeLists.txt,这个文件就是起编译配置的作用。

build编译空间:这个文件夹放置CMake和catkin编译功能包时产生的缓存、配置、中间文件等。

devel开发空间:这个文件夹放置编译好的可执行程序,这些可执行程序是不需要安装就能直接运行的。一旦功能包源码编译和测试通过后,可以将这些编译好的可执行文件直接导出与其他开发人员分享。

(2)功能包

功能包是ROS中软件组织的基本形式,一个功能包具有用于创建ROS程序的最小结构和最少内容,它可以包含ROS运行的进程(节点)、配置文件等。如图3,一个功能包中主要包含这几个文件:

CMakeLists.txt功能包配置文件:用于这个功能包cmake编译时的配置文件。

package.xml功能包清单文件:用xml的标签格式标记这个功能包的各类相关信息,比如包的名称、依赖关系等。主要作用是为了更容易的安装和分发功能包。

include/<package_name>功能包头文件目录:你可以把你的功能包程序包含的*.h头文件放在这里,include下之所以还要加一级路径<package_name>是为了更好的区分自己定义的头文件和系统标准头文件,<package_name>用实际功能包的名称替代。不过这个文件夹不是必要项,比如有些程序没有头文件的情况。

msg非标准消息定义目录:消息是ROS中一个进程(节点)发送到其他进程(节点)的信息,消息类型是消息的数据结构,ROS系统提供了很多标准类型的消息可以直接使用,如果你要使用一些非标准类型的消息,就需要自己来定义该类型的消息,并把定义的文件放在这里。不过这个文件夹不是必要项,比如程序中只使用标准类型的消息的情况。

srv服务类型定义目录:服务是ROS中进程(节点)间的请求/响应通信过程,服务类型是服务请求/响应的数据结构,服务类型的定义放在这里。如果要调用此服务,你需要使用该功能包名称和服务名称。不过这个文件夹不是必要项,比如程序中不使用服务的情况。

scripts可执行脚本文件存放目录:这里用于存放bash、python或其他脚本的可执行文件。不过这个文件夹不是必要项,比如程序中不使用可执行脚本的情况。

launch文件目录:这里用于存放*.launch文件,*.launch文件用于启动ROS功能包中的一个或多个节点,在含有多个节点启动的大型项目中很有用。不过这个文件夹不是必要项,节点也可以不通过launch文件启动。

src功能包中节点源文件存放目录:一个功能包中可以有多个进程(节点)程序来完成不同的功能,每个进程(节点)程序都是可以单独运行的,这里用于存放这些进程(节点)程序的源文件,你可以在这里再创建文件夹和文件来按你的需求组织源文件,源文件可以用c++、python等来书写。

为了创建、修改、使用功能包,ROS给我们提供了一些实用的工具,常用的有下面这些工具。

rospack:用于获取信息或在系统中查找工作空间。

catkin_create_pkg:用于在工作空间的src源空间下创建一个新的功能包。

catkin_make:用于编译工作空间中的功能包。

rosdep:用于安装功能包的系统依赖项。

rqt_dep:用于查看功能包的依赖关系图。

关于这些工具命令的具体使用方法,会在后面的章节中结合实例进行具体的讲解。这里只是先介绍给大家,让大家有个概念上的了解,感兴趣的朋友也可以自己上网了解这些命令的具体用法。

(3)消息

消息是ROS中一个进程(节点)发送到其他进程(节点)的信息,消息类型是消息的数据结构,ROS系统提供了很多标准类型的消息可以直接使用,如果你要使用一些非标准类型的消息,就需要自己来定义该类型的消息。

ROS使用了一种精简的消息类型描述语言来描述ROS进程(节点)发布的数据值。通过这种描述语言对消息类型的定义,ROS可以在不同的编程语言(如c++、python等)书写的程序中使用此消息。不管是ROS系统提供的标准类型消息,还是用户自定义的非标准类型消息,定义文件都是以*.msg作为扩展名。消息类型的定义分为两个主要部分:字段的数据类型和字段的名称,简单点说就是结构体中的变量类型和变量名称。比如下面的一个示例消息定义文件example.msg的内容,如图4,int32、float32、string就是字段的数据类型,id、vel、name就是字段的名称。

SLAM+语音机器人DIY系列:(二)ROS入门——2.ROS系统整体架构

(图4)一个示例消息定义文件

在大多数情况下,我们都可以使用ROS系统提供的标准类型的消息来完成任务,这得益于ROS系统提供了丰富的标准类型的消息。经常用到的类型包括:基本类型(std_msgs)、通用类型(sensor_msgs、geometry_msgs、nav_msgs、actionlib_msgs),如图5。

SLAM+语音机器人DIY系列:(二)ROS入门——2.ROS系统整体架构

(图5)ROS系统提供的常用标准类型的消息

不难发现std_msgs下面定义的是经ROS封装后的最基本的数据类型,比如Bool、Char、Int16等;sensor_msgs下面定义的是跟传感器数据相关的数据类型,比如Image对应的就是摄像头的数据类型,Imu对应的就是IMU传感器的数据类型,LaserScan对应的就是激光雷达的数据类型,PointCloud对应的就是点云扫描传感器(如深度相机)的数据类型,Range对应的就是距离测量传感器(如超声波、红外测距)的数据类型;geometry_msgs下定义的是跟几何有关的数据类型,比如Pose用来描述机器人在空间的位姿,Quaternion用四元数描述空间方向,Transform用来描述不同坐标系之间的转移关系,Twist用来描述机器人运动时的位姿、速度等状态信息;nav_msgs下定义的是跟机器人导航相关的数据类型,比如OccupancyGrid是栅格地图的数据类型,Odometry是机器人通过轮式码盘或其他方式融合得到的里程计的数据类型,Path是路径规划算法计算得到的导航路劲的数据类型;actionlib_msgs下定义的是actionlib控制过程相关的数据类型,比如GoalID描述发送出去的导航目标的ID号,GoalStatus描述执行导航目标过程的过程状态信息。如果想了解更多ROS系统的消息类型的细节,最好的方式是去ROS wiki看官方的文档,链接如下:

http://wiki.ros.org/std_msgs/

http://wiki.ros.org/common_msgs/

(4)服务

服务是ROS中进程(节点)间的请求/响应通信过程,服务类型是服务请求/响应的数据结构。服务类型的定义借鉴了消息类型的定义方式,所以这里就不在赘述了。区别在于,消息数据是ROS进程(节点)间多对多广播式通信过程中传递的信息;服务数据是ROS进程(节点)间点对点的请求/响应通信过程传递的信息。

2.2.从计算图级理解ROS架构

ROS会创建一个连接所有进程(节点)的网络,其中的任何进程(节点)都可以访问此网络,并通过该网络与其他进程(节点)交互,获取其他进程(节点)发布的信息,并将自身数据发布到网络上,这个计算图网络中的节点(node)、主题(topic)、服务(server)等都要有唯一的名称做标识,如图6。

SLAM+语音机器人DIY系列:(二)ROS入门——2.ROS系统整体架构

(图6)计算图级理解ROS架构

(1)节点

节点是主要的计算执行进程,功能包中创建的每个可执行程序在被启动加载到系统进程中后,该进程就是一个ROS节点,如图6中的node1、node2、node3等都是节点(node)。节点都是各自独立的可执行文件,能够通过主题(topic)、服务(server)或参数服务器(parameter server)与其他节点通信。ROS通过使用节点将代码和功能解耦,提高了系统的容错力和可维护性。所以你最好让每一个节点都具有特定的单一的功能,而不是创建一个包罗万象的大节点。节点如果用c++进行编写,需要用到ROS提供的库roscpp;节点如果用python进行编写,需要用到ROS提供的库rospy。

ROS提供了处理节点的工具,用于节点信息、状态、可用性等的查询操作,例如可以用下面的命令对正在运行的节点进行操作。

rosnode info <node_name>:用于输出当前节点信息。

rosnode kill <node_name>:用于杀死正在运行节点进程来结束节点的运行。

rosnode list:用于列出当前活动的节点。

rosnode machine <hostname>:用于列出指定计算机上运行的节点。

rosnode ping <node_name>:用于测试节点间的网络连通性。

rosnode cleanup:用于将无法访问节点的注册信息清除。

关于这些工具命令的具体使用方法,会在后面的章节中结合实例进行具体的讲解。这里只是先介绍给大家,让大家有个概念上的了解,感兴趣的朋友也可以自己上网了解这些命令的具体用法。

(2)消息

节点通过消息(message)完成彼此的沟通。消息包含一个节点发送给其他节点的信息数据。关于消息类型的知识在前面已经讲述了,这里就不再展开。

ROS提供了获取消息相关信息的命令工具,这里列举出一些常用的命令,来具体看看吧。

rosmsg show <message_type>:用于显示一条消息的字段。

rosmsg list:用于列出所有消息。

rosmsg package <package _name>:用于列出功能包的所有消息。

rosmsg packages:用于列出所有具有该消息的功能包。

rosmsg users <message_type>:用于搜索使用该消息类型的代码文件。

rosmsg md5 <message_type>:用于显示一条消息的MD5求和结果。

关于这些工具命令的具体使用方法,会在后面的章节中结合实例进行具体的讲解。这里只是先介绍给大家,让大家有个概念上的了解,感兴趣的朋友也可以自己上网了解这些命令的具体用法。

(3)主题

每个消息都必须发布到相应的主题(topic),通过主题来实现在ROS计算图网络中的路由转发。当一个节点发送数据时,我们就说该节点正在向主题发布消息;节点可以通过订阅某个主题,接收来自其他节点的消息。通过主题进行消息路由不需要节点之间直接连接,这就意味着发布者节点和订阅者节点之间不需要知道彼此是否存在,这样就保证了发布者节点与订阅者节点之间的解耦合。同一个主题可以有多个订阅者也可以有多个发布者,不过要注意必须使用不同的节点发布同一个主题。每个主题都是强类型的,不管是发布消息到主题还是从主题中订阅消息,发布者和订阅者定义的消息类型必须与主题的消息类型相匹配。

ROS提供了操作主题的命令工具,这里列举出一些常用的命令,来具体看看吧。

rostopic bw </topic_name>:用于显示主题所使用的带宽。

rostopic echo </topic_name>:用于将主题中的消息数据输出到屏幕。

rostopic find <message_type>:用于按照消息类型查找主题。

rostopic hz </topic_name>:用于显示主题的发布频率。

rostopic info </topic_name>:用于输出活动主题、发布的主题、主题订阅者和服务的信息。

rostopic list:用于列出当前活动主题的列表。

rostopic pub </topic_name> <message_type> <args>:用于通过命令行将数据发布到主题。

rostopic type </topic_name>:用于输出主题中发布的消息类型。

关于这些工具命令的具体使用方法,会在后面的章节中结合实例进行具体的讲解。这里只是先介绍给大家,让大家有个概念上的了解,感兴趣的朋友也可以自己上网了解这些命令的具体用法。

(4)服务

在一些特殊的场合,节点间需要点对点的高效率通信并及时获取应答,这个时候就需要用服务的方式进行交互。提供服务的节点叫服务端,向服务端发起请求并等待响应的节点叫客户端,客户端发起一次请求并得到服务端的一次响应,这样就完成了一次服务通信过程,例如图6中,node1向node3发起一次请求,并得到node3返回给node1的响应。服务通信过程中服务的数据类型需要用户自己定义,与消息不同,节点并不提供标准服务类型。服务类型的定义文件都是以*.srv为扩展名,并且被放在功能包的srv/文件夹下。

ROS提供了操作服务的命令工具,这里列举出一些常用的命令,来具体看看吧。

rosservice call </service_name> <args>:用于通过命令行参数调用服务。

rosservice find <service_type>:用于根据服务类型查询服务。

rosservice info </service_name>:用于输出服务信息。

rosservice list:用于列出活动服务清单。

rosservice type </service_name>:用于输出服务类型。

rosservice uri </service_name>:用于输出服务的ROSRPC URI。

关于这些工具命令的具体使用方法,会在后面的章节中结合实例进行具体的讲解。这里只是先介绍给大家,让大家有个概念上的了解,感兴趣的朋友也可以自己上网了解这些命令的具体用法。

(5)节点管理器

节点管理器(master)用于节点的名称注册和查找等,也负责设置节点间的通信。如果在你的整个ROS系统中没有节点管理器,就不会有节点、消息、服务之间的通信。由于ROS本身就是一个分布式的网络系统,所以你可以在某台计算机上运行节点管理器,在这台计算机和其他台计算机上运行节点。

ROS中提供了跟节点管理器相关的命令行工具,就是roscre。

roscore:用于启动节点管理器,这个命令会加载ROS节点管理器和其他ROS核心组件。

关于这些工具命令的具体使用方法,会在后面的章节中结合实例进行具体的讲解。这里只是先介绍给大家,让大家有个概念上的了解,感兴趣的朋友也可以自己上网了解这些命令的具体用法。

(6)参数服务器

参数服务器(parameter server)能够使数据通过关键词存储在一个系统的核心位置。通过使用参数,就能够在节点运行时动态配置节点或改变节点的工作任务。参数服务器是可通过网络访问的共享的多变量字典,节点使用此服务器来存储和检索运行时的参数。

ROS中关于参数服务器的命令行工具,请看下面的常用命令。

rosparam list:用于列出参数服务器中的所有参数。

rosparam get <parameter_name>:用于获取参数服务器中的参数值。

rosparam set <parameter_name> <value>:用于设置参数服务器中参数的值。

rosparam delete <parameter_name>:用于将参数从参数服务器中删除。

rosparam dump <file>:用于将参数服务器的参数保存到一个文件。

rosparam load <file>:用于从文件将参数加载到参数服务器。

关于这些工具命令的具体使用方法,会在后面的章节中结合实例进行具体的讲解。这里只是先介绍给大家,让大家有个概念上的了解,感兴趣的朋友也可以自己上网了解这些命令的具体用法。

(7)消息记录包

消息记录包(bag)是一种用于保存和回放ROS消息数据的文件格式。消息记录包是一种用于存储数据的重要机制,它可以帮助记录一些难以收集的传感器数据,然后通过反复回放数据进行算法的性能开发和测试。ROS创建的消息记录包文件以*.bag为扩展名,通过播放、停止、后退操作该文件,可以像实时会话一样在ROS中再现情景,便于算法的反复调试。

ROS提供消息记录包相关的命令行工具,请看下面的常用命令。

rosbag <args>:用来录制、播放和执行操作。

关于这些工具命令的具体使用方法,会在后面的章节中结合实例进行具体的讲解。这里只是先介绍给大家,让大家有个概念上的了解,感兴趣的朋友也可以自己上网了解这些命令的具体用法。

2.3.从开源社区级理解ROS架构

ROS开源社区级的概念主要是ROS资源,即通过各个独立的网络社区分享ROS方面的软件和知识。

(1)ROS发行版

ROS发行版跟Linux发行版起类似的作用,ROS发行版是内置了一系列常用功能包的ROS系统安装包,可以被直接安装到我们的操作系统中。如图7,是ROS的各个发行版。

SLAM+语音机器人DIY系列:(二)ROS入门——2.ROS系统整体架构

(图7)ROS的各个发行版

(2)ROS软件代码库

ROS依赖于开源或共享软件的源代码,这些代码由不同的机构共享与发布,比如github源码共享,ubuntu软件仓库等等。如图8,是ROS软件代码库的社区组织形式。

SLAM+语音机器人DIY系列:(二)ROS入门——2.ROS系统整体架构

(图8)ROS软件代码库的社区组织形式

(3)ROS文档社区

ROS wiki是记录有关ROS系统各种文档的主要论坛社区,任何人都可以注册账户、贡献自己的文件、提供更正或更新、编写教程及其他行为。感兴趣可以进入ROS wiki的主页面瞧瞧http://wiki.ros.org/

(4)ROS问答社区

ROS开发者可以通过这个资源去提问和寻找ROS相关的答案,ROS Answer主页面

https://answers.ros.org/

后记

------SLAM+语音机器人DIY系列【目录】快速导览------

第1章:Linux基础

1.Linux简介

2.安装Linux发行版ubuntu系统

3.Linux命令行基础操作

第2章:ROS入门

1.ROS是什么

2.ROS系统整体架构

3.在ubuntu16.04中安装ROS kinetic

4.如何编写ROS的第一个程序hello_world

5.编写简单的消息发布器和订阅器

6.编写简单的service和client

7.理解tf的原理

8.理解roslaunch在大型项目中的作用

9.熟练使用rviz

10.在实际机器人上运行ROS高级功能预览

第3章:感知与大脑

1.ydlidar-x4激光雷达

2.带自校准九轴数据融合IMU惯性传感器

3.轮式里程计与运动控制

4.音响麦克风与摄像头

5.机器人大脑嵌入式主板性能对比

6.做一个能走路和对话的机器人

第4章:差分底盘设计

1.stm32主控硬件设计

2.stm32主控软件设计

3.底盘通信协议

4.底盘ROS驱动开发

5.底盘PID控制参数整定

6.底盘里程计标

第5章:树莓派3开发环境搭建

1.安装系统ubuntu_mate_16.04

2.安装ros-kinetic

3.装机后一些实用软件安装和系统设置

4.PC端与robot端ROS网络通信

5.Android手机端与robot端ROS网络通信

6.树莓派USB与tty串口号绑定

7.开机自启动ROS节点

第6章:SLAM建图与自主避障导航

1.在机器人上使用传感器

2.google-cartographer机器人SLAM建图

3.ros-navigation机器人自主避障导航

4.多目标点导航及任务调度

5.机器人巡航与现场监控

第7章:语音交互与自然语言处理

1.语音交互相关技术

2.机器人语音交互实现

3.自然语言处理云计算引擎

第8章:高阶拓展

1.miiboo机器人安卓手机APP开发

2.centos7下部署Django(nginx+uwsgi+django+python3)

----------------文章将持续更新,敬请关注-----------------

如果大家对博文的相关类容感兴趣,或有什么技术疑问,欢迎加入下面的《SLAM+语音机器人DIY》QQ技术交流群,一起讨论学习^_^

SLAM+语音机器人DIY系列:(二)ROS入门——2.ROS系统整体架构

上一篇:SLAM+语音机器人DIY系列:(二)ROS入门——1.ROS是什么


下一篇:SLAM+语音机器人DIY系列:(一)Linux基础——2.安装Linux发行版ubuntu系统