ROS2.0整体架构说明

说明:
- 介绍ROS2.0相关概念,以及与ROS1.0的异同

ros2目标:
- 支持涉及不可靠网络的多机器人系统
- ”bare-metal“ 微控制器
- 支持实时控制器
- 消除原型和最终产品之间的差距
- 多平台支持

ROS2的目标,也是目前存在与ROS1中的问题,至于如何解决,就让我们慢慢探索ROS2.0时代到底带来了哪些改变。

ROS2.0的架构

ROS2.0整体架构说明_第1张图片
上图所示是ROS2与ROS1整体架构的对比

  1. ROS1主要构建于Linux系统

    ROS2支持构建的系统包括Linux、windows、Mac、RTOS,甚至没有操作系统的裸机。

  2. ROS1的通讯系统基于TCPROS/UDPROS,强依赖于master节点的处理(可以想像master一挂,整个系统会面临如何的窘境)。

    ROS2的通讯系统是基于DDS,同时在内部提供了DDS的抽象层实现,用户就可以不去关注底层的DDS使用了哪个商家的API。

  3. ROS中最重要的一个概念就是“节点”,基于发布/订阅模型的节点使用,可以让开发者并行开发低耦合的功能模块,并且便于进行二次复用。

    ROS2得益于DDS的加入,发布/订阅模型也会发生改变。

  4. 两个很重要的独立模块“Nodelet”和“Intra-process”。在ROS1的架构中Nodelet和TCPROS/UDPROS是并列的层次,负责通讯,实际上Nodelet是为同一个进程中的多个节点提供一种更优化的数据传输方式。

    ROS2中保留了这种数据传输方式,只不过换了一个名字,叫“Intra-process”,同样也是独立于DDS。

DDS是什么

DDS(Data Distribution Service)即数据分发服务。它是一个专门为实时系统设计的数据分发/订阅标准,目前已成为分布式实时系统中数据发布/订阅的标准解决方案。

DDS 的技术核心是以数据为核心的发布订阅模型(Data-Centric Publish-Subscribe ,DCPS),DCPS模型创建了一个“全局数据空间“的概念,所有独立的应用都可以去访问。在DDS中,每一个发布者或者订阅者都成为参与者,类似于ROS中节点的概念。每一个参与者都可以使用某种定义好的数据类型来读写全局数据空间。好像和ROS1的发布订阅差不多,那我们来对比一下两个模型

ROS2.0整体架构说明_第2张图片
ROS1中,一个节点想要发布消息,需要在master中注册一下,让master知道你这个节点要干什么。另外一个节点想要订阅消息,就需要去问问master哪里有这个消息,master发现这两个节点相互之间“有意思”,酒吧把IP地址告诉他们,接下来两个节点就开始私聊,也就没有master什么事了,就算两个节点闹矛盾联系不上,master也管不着

DDS中的模型就人性化多了:

  1. 参与者(Domain Participant):一个参与者就是一个容器,对应于一个使用DDS的用户,任何DDS的用户都必须通过Participant来访问全局数据空间。
  2. 发布者(Publisher):数据发布的执行者,支持多种数据类型的发布,可以与多个数据写入器(DataWriter)相联,发布一种或多种主题(Topic)的消息。
  3. 订阅者(Subscriber):数据订阅的执行者,支持多种数据类型的订阅,可以与多个数据读取器(DataReader)相联,订阅一种或多种主题(Topic)的消息。
  4. 数据写入器(DataWriter):应用向发布者更新数据的对象,每个数据写入器对应一个特定的Topic,类似于ROS1中的一个消息发布者。
  5. 数据读取器(DataReader):应用从订阅者读取数据的对象,每个数据读取器对应一个特定的Topic,类似于ROS1中的一个消息订阅者。
  6. 主题(Topic):这个和ROS1中的Topic概念一致
  7. QoS Policy:Quality of Service,质量服务原则,负责数据质量的。QoS是DDS中非常重要的一环,控制了各方面与底层的通讯机制,主要从时间限制、可靠性、持续性、历史记录几个方面,满足用户针对不同场景的数据应用需求。

从上边DDS的几个重要概念中,我们就可以看到ROS2相比于ROS1,在以下方面有所提升:

  • 实时性增强:数据必须在deadline之前完成更新。

  • 持续性增强:ROS1尽管存在数据队列的概念,但是还有很大的局限,订阅者无法接收到加入网络之前的数据;

    ​ DDS可以为ROS提供数据历史的服务,就算新加入的节点,也可以获取发布的所有历史数据。

  • 可靠性增强:通过DDS配置可靠性原则,用户可以根据需求选择性能模式(BEST_EFFORT)或者稳定模式(RELIABLE)。

ROS2实践

ROS2里没有master,那么节点之间是怎么知道彼此存在的呢?

自动发现的机制——Discovery。
简单来说,当一个节点启动后,首先在网络中发条广播,大声告诉这个世界我来了,其他节点听到之后,纷纷反馈各自的信息,这样一来二去也就联系上了

万一哪个节点掉线了怎们办?

没关系,每个节点都会周期性的发布广播,告诉其他节点他还在线,就算要下线,他也会广播告诉其他节点他要走了。

ROS2安装

参考ROS2安装使用教程,这里不再详细说明
1. ROS2的API并不是在ROS1的基础上查漏补缺,而是完全从新设计。关于ROS2的API说明,可以参考API文档:http://docs.ros2.org/beta1/api/rclcpp/index.html
2. 使用了更多C++的特性,比如auto、make_shared等。
3. 加入了QoS配置,QoS有默认的配置rmw_qos_profile_default 。
4. 代码的总体架构还是与ROS1极为相似的。

ament编译系统

ament是一种元编译系统,用来构建组成应用程序的多个独立功能包,是catkin编译系统进一步演化的版本
主要分为两个部分:
1. 编译系统:配置、编译、安装独立的功能包
2. 构建工具:将多个独立的功能包按照一定的拓扑结构进行链接

关于独立功能包之间的依赖关系,和ROS1相同,也需要在清单文件——package.xml中进行声明

ament的命令行工具

ament_tools是ament为用户提供的一种命令行工具,可以让用户完成功能包的编译、测试、安装、卸载,它本身也是一个Python的功能包。

从功能上来看,ament_tools和cantkin系统中的catkin_tools类似,目前并不提供并行构建的能力,将来应该会加入。

ament vs catkin
cantkin缺陷
1. CMake centric
catkin系统以 CMake为中心,所以只包含python代码的功能包也需要由CMake进行处理,但是CMake并不支持Python setuptools中的所有功能,而且也很难在Window上进行移植。

  1. Devel space
    在catkin系统构建完成后,会在工作目录下生成一个devel文件夹,里边是编译好的功能包,以及环境变量的设置等等,基本上等同于ROS安装完成后的目录结构和作用。但是相信很多初学者因为devel中的环境变量而苦恼过,这确实为用户带来了一些不必要的麻烦。

  2. CMAKE_PREFIX_PATH
    catkin会将编译多个工作区的前缀存储到环境变量CMAKE_PREFIX_PATH 中,但是这种方法会干扰变量中的其他值,在ament中,不同工作区的前缀会放到不同的环境变量中。

  3. catkin_simple
    catkin_simple是一个用于改善用户catkin体验的工具包,可以减少复杂的CMake代码,但是会存在不稳定的情况。ament也是实现了类似的功能,但是可靠性更强。

  4. Building within a single CMake context
    使用catkin_make命令可以一次性编译工作空间中的所有功能包,虽然方便,但如果存在相同命名的功能包时,会编译失败,ament在这方面也进行了改善。

针对以上缺陷,ament都进行了优化

安装ament
1. 参考官方wiki
2. 安装好就可以编译了

  src/ament/ament_tools/scripts/ament.py build --build-tests --symlink-install
  1. ament编译完成后,所有声称的文件都放到了ros_ws工作目录下的install文件夹里
  2. 生成的命令在bin文件夹下,如果我们需要在终端中调用这些命令,当然还是老办法,先设置环境变量,在运行

如何在ros2中开发自己的功能包
创建一个工作区吧:
mkdir -p ~/ros2_overlay_ws/srccd ~/ros2_overlay_ws/src
放入自己的功能包,这里使用ros2的exampl代替:
git clone https://github.com/ros2/examples.git
我们就可以编译这个新的工作区了(注意:之前编译好的ament的环境变量设置,可以写到.bashrc文件里):
cd ~/ros2_overlay_ws
ament build –cmake-args -DCMAKE_BUILD_TYPE=Debug
编译的过程和catkin差不多,编译完成后也会在工作区产生一个install文件,里边的目录结构和我们之前编译ament所生成的一样

ROS1与ROS2之间的桥梁

ROS2虽然重新设计了架构实现,但是也考虑到了与ROS1的兼容,专门开发了一个功能包——ros1_bridge,来完成ROS2与ROS1之间的通讯。但是目前ros1_bridge这个包的功能有限,还不提供python实现,而且仅支持ros2/common_interfaces repository中列出的通讯类型,如果要支持自己定义的接口,还需要自己编译ros1_bridge包。
示例1:talker和listener

# Shell A:
source /opt/ros/kinetic/setup.bash
roscore

# Shell B:
source /opt/ros/kinetic/setup.bash
source ~/ros2_ws/install/setup.bash
export ROS_MASTER_URI=http://localhost:11311
ros2 run ros1_bridge dynamic_bridge

# Shell C:
source /opt/ros/kinetic/setup.bash
rosrun rospy_tutorials talker

# Shell D:
source ~/ros2_ws/install/setup.bash
ros2 run demo_nodes_cpp listener

当查看shell B中的输出时,将会有一行指出已经创建了该主题的桥梁:
该屏幕截图显示了所有的shell窗口及其预期内容:
ROS2.0整体架构说明_第3张图片

编辑整理自古月居

你可能感兴趣的:(ROS2.0探索总结)