ROS2探索总结-目录 说明： 介绍ROS2的相关概念，构架，安装，测试，开发等相关内容。 作者： 本系列文档来自古月居授权转载 http://www.guyuehome.com 目录： ROS2探索总结-目录 ROS2探索总结-1.ROS成长记 ROS2探索总结-2.走近ROS2.0时代 ROS2探索总结-3.小试牛刀 ROS2探索总结-4.ament编译系统 ROS2探索总结-5.ROS1与ROS2之间的桥梁 ROS2探索总结-6.迎接ROS2.0时代的到来 ROS2探索总结-7.Why ROS2.0？ ROS2探索总结-8.What is ROS2.0 ？ ROS2探索总结-9.ROS2发布第三个正式版Crystal Clemmys ROS2探索总结-10.ROS2基础工具使用入门 ROS2探索总结-11.ROS2gazebo仿真入门 ROS2探索总结-12.ROS2 Python编程基础 ROS2探索总结-13.话题与服务接口定义 参考： 古月居网站 古月居ros2专栏
ROS2探索总结-1.ROS成长记 说明： 介绍ROS来世今生 介绍： ROS刚刚度过了9岁生日，这九年以来，无论国外还是国内，越来越多机器人开发者或者机构选择ROS，同时也为社区贡献了更多更优秀的代码，从下边这张图我们可以看到，这种成长几乎是指数级的。 2007年11月，Willow Garage公司孕育许久的一个宝宝终于诞生了，并且取名叫做ROS，Willow Garage 专门为他设计了一个机器人玩具——PR2，没想到，ROS宝宝悟性极强，很快就学会了怎么玩这个PR2，Willow Garage 发现ROS宝宝潜力很大，就继续教ROS宝宝学习更多通用机器人软件包的知识，让他学会了怎么去玩更多的机器人，就算遇到一个新的机器人，也可以将以前学到的知识运用到上边，继续愉快的玩起来。但是那个时代，毕竟ROS宝宝可以玩、会玩的机器人少，主要就是玩PR2，于是迫于局限，也存在一些性格上的不足： 只能同时玩一个机器人，多机器人就不会玩了。 脑力有限，只能依靠自身的资源做心算，如果要玩的功能太复杂，就心有余而力不足了。 脑子转的慢，没有实时性，有的时候会算不过来。 神经系统不发达 ，自身的各个关节部分都需要保持良好的连接，各部分通讯数据量有点大。 还只能在实验室或者研究机构里托管，不能让他带着机器人和大众玩。 但是 Willow Garage相信自己的孩子，并且把该上小学的ROS放到了社区这个学校里，接收世界各地开发者老师的培养和教育，这也让ROS接触到了众多资源，激发了他内心强大的学习欲望，并且一路从小学到初中到高中，成绩越来越好，最后以名列前茅的成绩考入了理想的大学。 在这段成长最重要的时光里，我们确实可以看到，ROS已经不是当年的宝宝，也不仅仅会玩PR2、TurtleBot等机器人，在轮式机器人、类人机器人、工业机械臂、自动驾驶汽车、探索飞船、救援车辆等领域，都已经可以看到这位ROS小朋友勤奋努力的身影。而且他已经不是当年那个会打碎花瓶的熊孩子，他逐渐成长为一个教养有佳的翩翩少年，他带着不少服务机器人走进了人类的日常生活，同时和农业机器人、工业机器人一起，为人类的生产生活贡献着力量，最酷的是，NASA的叔叔阿姨还让他搭乘 Robonaut 2去了国际空间站，曾经那些欺负他的小朋友（ MSRDS等），不仅没有打倒他，还让他学会了吸星大法的内功，现在在机器人领域，几乎无人能敌。 但是ROS并没有骄傲，在上大学里，他发现了一个全新的世界。那里有很多课程需要他去学习，他第一次接触到那么多从来没听说过的新技术，而这些技术都是他的基础课程： Zeroconf： 零配置网络服务规范， 用于自动生成可用IP地址的网络技术，不需要额外的手动配置 和专属的配置服务器。 Protocol Buffers： Google公司开发的一种数据描述语言，类似于XML能够将结构化数据序列化，可用于数据存储、通信协议等方面， 它不依赖于语言和平台并且可扩展性极强。 ZeroMQ (and the other MQs)： 一个简单好用的传输层，像框架一样的一个socket library，他使得Socket编程更加简单、简洁和性能更高。 Redis： 一个高性能的key-value数据库。 WebSockets：HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。 DDS (Data Distribution Service)： 新一代分布式实时通信中间件技术规范，DDS采用发布/订阅体系架构，强调以数据为中心，提供丰富的QoS服务质量策略，能保障数据进行实时、高效、灵活地分发，可满足各种分布式实时通信应用需求。 在学习以上这些基础技术课程的基础上，ROS需要灵活应用这些技能，并且在高年级的学习中修炼综合能力： 多机器人控制。这个能力厉害了，以后可以同时驾驭多个机器人，别提多炫酷了，必须好好修炼，说不定还能靠此技能吸引异性呢。 多平台应用支持。这个能力要求ROS要学会大丈夫能屈能伸，不仅要能在性能强劲的计算机上跑，还要能在资源有限的嵌入式平台上跑。 实时应用支持。这个需要好好修炼内功，让自己完善时间管理能力，说几点起就几点起，说几时完成任务就几时完成任务。 增强网络通信能力。这个能力正是ROS所需要的，原来上100楼，走到50楼还得缓冲一下，这门课就是教ROS如何上100楼大气不喘的，就算楼要倒，还能飞起来。 产品应用。这个能力要求ROS具备更强的可靠性，以后就可以带着更多机器人去到更多普通人的家里玩了。 灵活构建。这是个学习能力，要求ROS学习更多的新特性，无论面对多么复杂的机器人系统，都可以轻松应对。 这么多的课程需要学习，这么多的能力需要修炼，这个大学生涯对于ROS可不轻松了。 ROS就像一个孩子，在加速成长的过程中，也需要不断适应外部坏境的发展，吸收更多与时俱进的技术，从而使自己更加优秀强壮。相信等到他毕业之时，必将是一个全新的自我，我们可以使用全新的API与他交流，他也会变得更加优秀，不仅依然会玩曾经的机器人，还可以玩好更多机器人，甚至可以玩机器人领域之外的东东。他并不会在原有基础上查漏补缺，而是脱胎换骨的涅磐重生，从少年成长为青年，更加蓬勃也更加好强，带着多年所学，立志闯出大好未来 。 所以，他也应该有一个全新的名字——ROS 2.0。 注： ROS探索总结系列的文章从2013年开始发表，时过境迁，也要跟上技术进步的步伐。2016年12月19日，ROS2.0第一个beta版本正式发布，给ROS开发者又来了一剂强心针，我们就从此开始，从这篇文章开始，走近ROS2.0的时代，继续探索总结，至于什么时候能够“走进”，就让我们一起拭目以待吧
ROS2探索总结-2.走近ROS2.0时代 说明： 介绍ROS2.0相关概念，以及与ROS1.0的异同 介绍： ROS已经走过九个年头，伴随着机器人技术的大发展，ROS也得到了极大的推广和应用。尽管ROS还存在不少的局限性，但是ROS社区内的功能包还是逐年呈指数级上涨，为机器人开发者带来了巨大的便利。不少开发者和研究机构还针对ROS的局限性进行了改良，这些局部功能的改善往往很难带来整体性能的提升，机器人开发者对新一代ROS的呼声越来越大，ROS2.0的消息也不绝于耳，终于在ROSCon 2014上，ROS正式发布了新一代ROS的设计架构（Next-generation ROS: Building on DDS），2015年8月第一个ROS2.0的alpha版本落地，在经过一年多的开发，2016年12月19日，ROS2.0的beta版本正式发布。众多新技术和新概念应用到了新一代的ROS之中，不仅带来了整体架构的颠覆，更是增强了ROS2.0的综合性能。 上图是ROS2的目标，也是目前存在与ROS1中的问题，至于如何解决，就让我们慢慢探索ROS2.0时代到底带来了哪些改变。 一、ROS2.0的架构 上图所示是ROS2与ROS1整体架构的对比，我们来一左一右找不同： ROS1主要构建于Linux系统之上，一定有很多同学希望在windows或者RTOS上应用ROS开发机器人，原来这个期望是很难实现的，但是ROS2带来了改变，支持构建的系统包括Linux、windows、Mac、RTOS，甚至没有操作系统的裸机。 ROS1的通讯系统基于TCPROS/UDPROS，强依赖于master节点的处理，可以想像master一挂，整个系统会面临如何的窘境。但是从右边ROS2的架构中我们可以发现，之前让人耿耿于怀的master终于消失了，ROS2的通讯系统是基于DDS的（至于什么是DDS，下节详解），同时在ROS2内部提供了DDS的抽象层实现，有了这个抽象层，用户就可以不去关注底层的DDS使用了哪个商家的API。 ROS中最重要的一个概念就是“节点”，基于发布/订阅模型的节点使用，可以让开发者并行开发低耦合的功能模块，并且便于进行二次复用。得益于DDS的加入，ROS2的发布/订阅模型也会发生改变，具体下节再讲。 你肯定还关注到了两个很重要的独立模块，那就是“Nodelet”和“Intra-process”。在ROS1的架构中Nodelet和TCPROS/UDPROS是并列的层次，当然也是负责通讯的，实际上Nodelet是为同一个进程中的多个节点提供一种更优化的数据传输方式。ROS2中也保留了这种数据传输方式，只不过换了一个名字，叫“Intra-process”，同样也是独立于DDS。 可以看到，架构的大部分不同都是应为DDS的引入，那么到底什么是DDS？DDS又有什么超能力可以改变ROS呢？ 二、DDS是何方神圣 DDS的全称是Data Distribution Service，即数据分发服务。这个DDS也并不是一个很新鲜的东东，大概在十几年前就已经出生了，应该属于00后。它是对象管理组织OMG（Object Management Group）在2004年正式发布的一个专门为实时系统设计的数据分发/订阅标准，最早应用于美国海军， 解决舰船复杂网络环境中大量软件升级的兼容性问题，目前已经成为美国国防部的强制标准，同时广泛应用于国防、民航、工业控制等领域， 成为分布式实时系统中数据发布/订阅的标准解决方案。 DDS 的技术核心是以数据为核心的发布订阅模型（Data-Centric Publish-Subscribe ，DCPS），这种DCPS模型创建了一个“全局数据空间”（global data space）的概念，所有独立的应用都可以去访问。在DDS中，每一个发布者或者订阅者都成为参与者（participant），类似于ROS中节点的概念。每一个参与者都可以使用某种定义好的数据类型来读写全局数据空间。看到这里，你是不是想起来了ROS1中的订阅发布/模拟模型，是不是感觉好像和DDS也差不了多少。那就让我们来对比一下两者的模型，看看到底差多少？ 上图左边是ROS1的订阅/发布模型，右边是ROS2使用的DDS的订阅/发布模型，乍一眼看上去，感觉就是DDS增加了更多的框框，那么这些框框是干什么的呢？ 参与者（DomainParticipant）：一个参与者Participant就是一个容器，对应于一个使用DDS的用户，任何DDS的用户都必须通过Participant来访问全局数据空间。 发布者（Publisher）：数据发布的执行者，支持多种数据类型的发布，可以与多个数据写入器（DataWriter）相联，发布一种或多种主题（Topic）的消息。 订阅者（Subscriber）：数据订阅的执行者，支持多种数据类型的订阅，可以与多个数据读取器（DataReader）相联，订阅一种或多种主题（Topic）的消息。 数据写入器（DataWriter）：应用向发布者更新数据的对象，每个数据写入器对应一个特定的Topic，类似于ROS1中的一个消息发布者。 数据读取器（DataReader）：应用从订阅者读取数据的对象，每个数据读取器对应一个特定的Topic，类似于ROS1中的一个消息订阅者。 主题（Topic）：这个和ROS1中的Topic概念一致，一个Topic包含一个名称和一种数据结构。 QoS Policy：Quality of Service，质量服务原则，这个模块在ROS1中可从没见过，看名称就猜测应该是负责数据质量的。QoS是DDS中非常重要的一环，控制了各方面与底层的通讯机制，主要从时间限制、可靠性、持续性、历史记录几个方面，满足用户针对不同场景的数据应用需求，可以参考下边的图片和表格，看一下这几个原则可以哪些配置。 从上边DDS的几个重要概念中，我们就可以看到ROS2相比于ROS1，在以下方面有所提升： 实时性增强：数据必须在deadline之前完成更新。 持续性增强：ROS1尽管存在数据队列的概念，但是还有很大的局限，订阅者无法接收到加入网络之前的数据；DDS可以为ROS提供数据历史的服务，就算新加入的节点，也可以获取发布的所有历史数据。 可靠性增强：通过DDS配置可靠性原则，用户可以根据需求选择性能模式（BEST_EFFORT）或者稳定模式（RELIABLE）。 到此为止，我们应该已经对ROS2有一个大概的认知了，具体的很多技术细节今后再慢慢探索。 三、ROS2 vs ROS1 框架看来终觉浅，本文的最后一节，我们来看看目前ROS2与ROS1相比，性能到底如何？这里的所有对比数据和图片来自于论文《Exploring the Performance of ROS2》。 在这篇论文中，作者针对ROS1和ROS2在延时、吞吐量、线程数、内存消耗等几个方面的性能进行了量化对比，数据量从256byte到4M，实验条件覆盖了ROS分布式的多种使用场景，具有一定的参考价值，也是目前对ROS2性能方面量化分析的唯一论文，不过需要注意的是论文使用的ROS2是Alpha版本。 一些对比结果： 如果对这个比较感兴趣的同学，可以下载这篇论文仔细看一下，其中还有作者的对比解释，我就不在这里赘述了（啃了两个多小时，看完即忘完），只说一下我的几点感想： 根据作者的对比数据，我们可以发现ROS2的性能在不同数据量的场景下，表现呈指数级变化，应该是大数据在底层传输的一些处理时间导致的。 不同厂商的DDS产品性能表现，相差巨大，应该根据不同的应用场景选用最佳的DDS产品。 QoS提供了多种配置选项，同样需要根据不同的应用场景，选择最适合自己的配置。 ROS1会丢失初始数据，这一点我只前还没有发现，ROS2看上去在这一点上好了不少。 ROS2目前的整体性能（论文中使用的Alpha版本）并不如ROS1，毕竟还处于开发阶段，而且对DDS的特性支持有限，但是毕竟潜力在那里。 OK，本文洋洋洒洒就到这里，路漫漫其修远兮，吾将上下而求索。最后再来一张图片，Why should I want to use ROS2?
ROS2探索总结-3.小试牛刀 说明 安装ROS2框架 看了之前ROS2的框架设计，是不是对ROS2产生了很多好奇。相比ROS1，ROS2中融入了很多新的东西，但是很多核心的概念并没有改变。 一、ROS中的Graph 还记不记得ROS1中Graph的几个概念？（可以出门左转复习《ROS探索总结（二）——ROS总体框架》）节点、消息、主题、服务，在ROS2里边又新加入了一个“发现（Discovery）”的概念。节点、消息、主题、服务这几个概念这里就不赘述了，在ROS2和ROS1里是相同的，我们来看一下什么叫Discovery。 我们从前边的框架中已经看到了，ROS2里是没有master的，那么节点之间是怎么知道彼此存在的呢？这就全靠一种自动发现的机制——Discovery。什么意思呢？简单来说，当一个节点启动后，首先在网络中发条广播，大声告诉这个世界我来了（忽然想到三体里人类向宇宙发送广播，招来了外星人。。。），其他节点听到之后，也纷纷反馈各自的信息，这样一来二去也就联系上了。当然，万一哪个节点掉线了怎们办？没关系，每个节点都会周期性的发布广播，告诉其他节点他还在线，就算要下线，他也会广播告诉其他节点他要走了，下次再聊。 二、小试牛刀 看了这么多概念，一时不一定消化得了，让我们小试牛刀，加强一下印象。从哪里下手呢？还记不记得ROS wiki上最初的talker and listener，ROS2还是继续从这里出发。 安装ROS2 目前ROS2还处于开发阶段，提供两种安装方法：二进制包和源码编译。我们还是偷偷懒，直接使用编译好的二进制包。打开网站 https://github.com/ros2/ros2/releases ，找到最新发布的ROS版本，目前最新版是Beta1，看看下载列表，是不是很激动的可以看到linux、osx、windows三个版本的二进制包，支持的平台确实比ROS1多了吧。不过我们还是从熟悉的Linux环境开始，需要Ubuntu16.04，从列表中下载ros2-beta1-package-linux-fastrtps.tar.bz2。 安装一些依赖包 $ sudo apt-get update && sudo apt-get install -q -y libopencv-core2.4v5 libhighgui2.4 libopencv-imgproc2.4v5 wget 解压刚才下载的ros2-beta1-package-linux-fastrtps.tar.bz2到你需要的目录下。 解压后如图所示： 设置环境变量 由于我们下载的是已经编译好的二进制包，不需要编译安装的过程（包括里边的示例代码，talker和listener都已经是编译好的），直接就可以使用了。当然运行前还是要设置一下环境变量（每个终端都需要，或者直接在.bashrc文件里添加）： $ source setup.bash 执行程序 在两个终端中分别执行“talker”和“listener”命令(使用apt-get install解决出现的错误) 两个节点成功连接上的界面 源码剖析 talker和listener的源码：https://github.com/ros2/tutorials talker #include <iostream> #include <memory> #include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" int main(int argc, char * argv[]) { //ros::init(argc, argv, "talker"); rclcpp::init(argc, argv); //ros::NodeHandle n; auto node = rclcpp::node::Node::make_shared("talker"); rmw_qos_profile_t custom_qos_profile = rmw_qos_profile_default; custom_qos_profile.depth = 7; //ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000); auto chatter_pub = node->create_publisher<std_msgs::msg::String>("chatter", custom_qos_profile); //ros::Rate loop_rate(10); rclcpp::WallRate loop_rate(2); auto msg = std::make_shared<std_msgs::msg::String>(); auto i = 1; //while (ros::ok()) while (rclcpp::ok()) { msg->data = "Hello World: " + std::to_string(i++); std::cout << "Publishing: '" << msg->data << "'" << std::endl; //chatter_pub.publish(msg); chatter_pub->publish(msg); //ros::spinOnce(); rclcpp::spin_some(node); //loop_rate.sleep(); loop_rate.sleep(); } return 0; } listener #include <iostream> #include <memory> #include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" //void chatterCallback(const std_msgs::String::ConstPtr& msg) void chatterCallback(const std_msgs::msg::String::SharedPtr msg) { std::cout << "I heard: [" << msg->data << "]" << std::endl; } int main(int argc, char * argv[]) { //ros::init(argc, argv, "listener"); rclcpp::init(argc, argv); //ros::NodeHandle n; auto node = rclcpp::Node::make_shared("listener"); //ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback); auto sub = node->create_subscription<std_msgs::msg::String>( "chatter", chatterCallback, rmw_qos_profile_default); //ros::spin(); rclcpp::spin(node); return 0; } 每句的代码上用注释标注了对应于ROS1中的代码，仔细阅读上边的代码，我们可以从以下几点做出对比分析： ROS2中的API相比ROS1中发生了较大的变化，这和ROS2设计文档中描述的一致，ROS2并不是在ROS1的基础上查漏补缺，而是完全从新设计。关于ROS2的API说明，可以参考API文档：http://docs.ros2.org/beta1/api/rclcpp/index.html 使用了更多C++的特性，比如auto、make_shared等。 加入了QoS配置，从上边的代码中，我们可以看到QoS有默认的配置rmw_qos_profile_default，而且talker将QoS的depth配置设置为“7”。 代码的总体架构还是与ROS1极为相似的。 参考资料： Overview of ROS 2 concepts ： https://github.com/ros2/ros2/wiki/Overview-of-ROS-2-concepts C++ ROS Client Library API：http://docs.ros2.org/beta1/api/rclcpp/index.html
ROS2探索总结-4.ament编译系统 说明 介绍和安装ament编译系统 上一篇我们小试牛刀，初步尝试了一下ROS2中的节点通信，这一篇我们来看一下ROS2中“全新”的编译系统——Ament。ROS编译系统从初期使用的rosbuild，到groovy版本之后的catkin，再到ROS2中的Ament，可谓是一波三者，虽然编译系统并不是ROS框架中的核心部分，但却是开发者最常接触的一个重要功能，了解其基本使用方法，常常可以发挥事半功倍的效果。 众所周知，ROS是一种分布式的框架，我们使用的软件都以相互独立的软件包的形式存在，用起来确实方便，但是对于编译系统来讲，还是有相当的挑战的，它不仅需要正确、快速地完成自动化构建过程，还需要解决每个软件包之间的相互依赖关系。虽然ROS中的编译系统一直采用标准的构建工具，比如CMake、Python setuptools，但是这些工具并没有办法完全满足ROS的需求，都需要添加一些额外的功能。 ament的前世今生 ament是一种元编译系统，用来构建组成应用程序的多个独立功能包，它并不是一个全新的东西，而是catkin编译系统进一步演化的版本，这两个单词也是近义词。 ament主要分为两个部分： 编译系统：配置、编译、安装独立的功能包 构建工具：将多个独立的功能包按照一定的拓扑结构进行链接 关于独立功能包之间的依赖关系，和ROS1相同，也需要在清单文件——package.xml中进行声明，如果有兴趣可以查看这个文件的定义标准 （[REP 140][2]）。 ament的命令行工具 ament_tools是ament为用户提供的一种命令行工具，可以让用户完成功能包的编译、测试、安装、卸载，而且它本身也是一个Python的功能包。从功能上来看，ament_tools和cantkin系统中的catkin_tools类似，目前并不提供并行构建的能力，将来应该会加入。 ament vs catkin 相比ROS最初使用的rosbuild，catkin在很多方面还是先进很多的，比如支持外部构建，CMake配置文件的自动生成等等。但是catkin也并不完美，针对开发者对catkin缺陷提交的反馈，催生了新一代的编译系统。这些缺陷包括： CMake centric 在catkin系统构建完成后，会在工作目录下生成一个devel文件夹，里边是编译好的功能包，以及环境变量的设置等等，基本上等同于ROS安装完成后的目录结构和作用。但是相信很多初学者因为devel中的环境变量而苦恼过，这确实为用户带来了一些不必要的麻烦。 Devel space 在catkin系统构建完成后，会在工作目录下生成一个devel文件夹，里边是编译好的功能包，以及环境变量的设置等等，基本上等同于ROS安装完成后的目录结构和作用。但是相信很多初学者因为devel中的环境变量而苦恼过，这确实为用户带来了一些不必要的麻烦。 CMAKE_PREFIX_PATH catkin会将编译多个工作区的前缀存储到环境变量CMAKE_PREFIX_PATH 中，但是这种方法会干扰变量中的其他值，在ament中，不同工作区的前缀会放到不同的环境变量中。 catkin_simple catkin_simple是一个用于改善用户catkin体验的工具包，可以减少复杂的CMake代码，但是会存在不稳定的情况。ament也是实现了类似的功能，但是可靠性更强。 Building within a single CMake context 使用catkin_make命令可以一次性编译工作空间中的所有功能包，虽然方便，但如果存在相同命名的功能包时，会编译失败，ament在这方面也进行了改善。 安装ament 创建目录 创建一个工作空间： $ mkdir -p ~/ros2_ws/src $ cd ~/ros2_ws 下载代码 这里需要用到一个版本控制的工具——vcs，可以参考https://github.com/dirk-thomas/vcstool进行安装 $ sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' $ sudo apt-key adv --keyserver hkp://pool.sks-keyservers.net --recv-key 0xB01FA116 $ sudo apt-get update $ sudo apt-get install python-vcstool 然后需要安装一些列依赖的软件包，可参考一下https://github.com/ros2/ros2/wiki/Linux-Development-Setup里边需要安装的软件包，最好全装上，以免后面编译出现错误。 $ sudo apt-get update $ sudo apt-get install git wget $ sudo apt-get install build-essential cppcheck cmake libopencv-dev libpoco-dev libpocofoundation9v5 libpocofoundation9v5-dbg python-empy python3-dev python3-empy python3-nose python3-pip python3-setuptools python3-vcstool # dependencies for testing $ sudo apt-get install clang-format pydocstyle pyflakes python3-coverage python3-mock python3-pep8 uncrustify # dependencies for fastrtps $ sudo apt-get install libboost-chrono-dev libboost-date-time-dev libboost-program-options-dev libboost-regex-dev libboost-system-dev libboost-thread-dev $ sudo apt-get install libboost-all-dev libpcre3-dev zlib1g-dev python-empy python-pkg-resources 下载ament的代码（需时较长） $ vcs import ~/ros2_ws/src < ros2.repos 开始编译 $ src/ament/ament_tools/scripts/ament.py build --build-tests --symlink-install 这时，可能会报错： ament build: Circular dependency within the following packages: rmw_implementation, rmw_opensplice_cpp 这是一个bug，解决的办法是删掉rmw_opensplice这个包，参考https://github.com/ros2/ros2/issues/303 继续编译 编译测试程序 $ src/ament/ament_tools/scripts/ament.py test 设置环境变量 ament编译完成后，所有声称的文件都放到了ros_ws工作目录下的install文件夹里： 生成的命令在bin文件夹下，如果我们需要在终端中调用这些命令，需设置环境变量： $ . install/local_setup.bash 运行例程 打开两个终端，运行talker和listener例程 编译自己的功能包 可以在ros_ws的src里边创建自己的功能包，但是目前的工作区里边都是ros2相关的代码，需重新创建一个工作区 $ mkdir -p ~/ros2_overlay_ws/srccd ~/ros2_overlay_ws/src 由于我们目前还没有写过ros2的功能包，那就还是先用ros2的example $ git clone https://github.com/ros2/examples.git 下载完成后，就可以编译这个新的工作区了（注意：之前编译好的ament的环境变量设置，可以写到.bashrc文件里）： $ cd ~/ros2_overlay_wsament build --cmake-args -DCMAKE_BUILD_TYPE=Debug 编译的过程和catkin差不多，编译完成后也会在工作区产生一个install文件，里边的目录结构和我们之前编译ament所生成的一样，example里边也包含talker和listener，运行的方法一样，先设置环境变量，然后运行，但是这次运行的程序是overlay工作区里边的。 参考资料 The meta build system “ament”：http://design.ros2.org/articles/ament.html Ament Tutorial：https://github.com/ros2/ros2/wiki/Ament-Tutorial
ROS2探索总结-5.ROS1与ROS2之间的桥梁 说明 建立ROS1与ROS2之间的通讯 ROS2虽然重新设计了架构实现，但是也考虑到了与ROS1的兼容，专门开发了一个功能包——ros1_bridge，来完成ROS2与ROS1之间的通讯。但是目前ros1_bridge这个包的功能有限，还不提供python实现，而且仅支持ros2/common_interfaces repository中列出的通讯类型，如果要支持自己定义的接口，还需要自己编译ros1_bridge包。 前提条件 在使用ros1_bridge包之前，需要先确定以下几点： 你已经安装了ROS2，可以参考ROS2探索总结（三）使用预编译好的ROS2二进制文件，或者参考wiki进行源码编译。本文使用的前者。 既然要让ROS2与ROS1通讯，当然也要保证你的电脑里已经安装了ROS1，并且设置了相关的环境变量，本文使用的环境是Ubuntu16.04+ROS Kinetic。 示例1：talker和listener 还是这个经典的案例，在前边几篇的探索中，我们都是在ROS2中运行的talker和listener，这次，我们将两个节点分别运行在ROS1和ROS2上。 首先打开第一个终端，运行ROS1的roscore。 然后打开第二个终端，进入到预编译好的ROS2目录下，设置环境变量，启动ros1_bridge。 $ . <install-space-with-bridge>/setup.bash $ dynamic_bridge 接着打开第三个终端，在ROS1中运行talker节点。 $ rosrun rospy_tutorials talker 最后打开第四个终端，在ROS2中运行listener节点。 $ . <install-space-with-bridge>/setup.bash $ listener 此时，你应该可以在第二个运行着ros1_bridge的终端中看到一句话： created 1to2 bridge for topic 'chatter' with ROS 1 type'std_msgs/String' and ROS 2 type 'std_msgs/String' 并且，伴随着talker与listener直接的通信，ros1_bridge也会显示“Passing message from ROS 1 to ROS 2”，当终止talker或者listener时，会显示“removed 1to2 bridge for topic 'chatter'”。 ros1_bridge类似于一个桥梁，一直在监听ROS2/ROS1中发布/订阅的消息/服务，当找到需要在ROS1和ROS2之间传递的信息后，就将这些信息从“桥上”运过去，类似的概念在ROS1还有不少，比如arduino_bridge等。 当然，我们也可以在ROS1中运行listener，在ROS2中运行talker，方法和效果与上文类似，不再赘述。 示例2：图像传输 方法和示例1类似，可以直接看下边图片中所输入的命令。可以看到，即便是传输图像数据，ros1_bridge也是可以胜任，而且依然可以使用rqt_image_view中的命令保存图片。 示例三：AddTwoInts 试过了主题消息的传输，那么服务消息是不是也可以通过ros1_bridge来传输呢？答案当然是肯定的。还记不记得ROS wiki教程中的讲解服务时使用的示例AddTwoInts，我们再用这个示例来测试一下。 方法类似，命令和测试结果如下图所示： ros1_bridge我们就测试到这里。通过ros1_bridge，我们可以方便的将系统中ROS1与ROS2的节点连接，实现消息的无障碍传输，但是ros1_bridge和ROS2一样，还处于开发阶段，功能还不是很完善，只是为我们提供了一种功能的预览，期待ROS2成熟后，会有更方便、稳定的集成方案。 参考资料 ros1_bridge ：https://github.com/ros2/ros1_bridge
ROS2探索总结-6.迎接ROS2.0时代的到来 概要： ROS起源于2007年11月，2017年11月刚好满10岁。ROS的最初目标是在机器人领域提高代码的复用率，谁都没有想到，ROS社区中的功能包会呈指数级发展，目前已经成为机器人领域的事实标准。 ROS最初设计的目标机器人是PR2，这款机器人搭载了当时最先进的移动计算平台，而且网络性能优异，不需要考虑实时性方面的问题，主要应用于科研领域。如今ROS应用的机器人领域越来越广：轮式机器人、人形机器人、工业机械手、室外机器人（如无人驾驶汽车）、无人飞行器、救援机器人等等，美国NASA甚至考虑使用ROS开发火星探测器；而且机器人开始从科研领域走向人们的日常生活。ROS虽然仍是机器人领域的开发利器，但介于最初设计时的局限性，也逐渐暴露出不少问题。 一、 什么是ROS2.0 ROS已经走过十个年头，伴随着机器人技术的大发展，ROS也得到了极大的推广和应用。尽管还存在不少局限性，但无法掩盖ROS的锋芒，社区内的功能包还是呈指数级逐年上涨，为机器人开发带来了巨大的便利。不少开发者和研究机构还针对ROS的局限性进行了改良，但这些局部功能的改善往往很难带来整体性能的提升，机器人开发者对新一代ROS的呼声越来越大，ROS2.0的消息也不绝于耳。 终于在ROSCon 2014上，新一代ROS的设计架构（Next-generation ROS: Building on DDS）正式公布；2015年8月第一个ROS2.0的alpha版本落地；2016年12月19日，ROS2.0的beta版本正式发布；2017年12月8日，万众瞩目的ROS2.0终于发布了第一个正式版——Ardent Apalone。众多新技术和新概念应用到了新一代的ROS之中，不仅带来了整体架构的颠覆，更是增强了ROS2.0的综合性能。 1.1 ROS2的目标 相比ROS1，ROS2的设计目标更加丰富： 支持多机器人系统 ROS2增加了对多机器人系统的支持，提高了多机器人之间通讯的网络性能，更多多机器人系统及应用将出现在ROS社区中。 铲除原型与产品之间的鸿沟 ROS2不仅针对科研领域，还关注机器人从研究到应用之间的过渡，可以让更多机器人直接搭载ROS2系统走向市场。 支持微控制器 ROS2不仅可以运行在现有的X86和ARM系统上，还将支持MCU等嵌入式微控制器，比如常用的ARM-M4、M7内核。 支持实时控制 ROS2还加入了实时控制的支持，可以提高控制的时效性和整体机器人的性能。 跨系统平台支持 ROS2不止能运行在Linux系统之上，还增加了对Windows和MACOS等系统的支持，让开发者的选择更加自由。 1.2 ROS2的架构 ROS2重新设计了整体架构，可以从下图中看到两代ROS之间架构的变化。 OS层 ROS1主要构建于Linux系统之上，ROS2带来了改变，支持构建的系统包括Linux、Windows、Mac、RTOS，甚至没有操作系统的裸机。 中间件 ROS中最重要的一个概念就是基于发布/订阅模型的“节点”，可以让开发者并行开发低耦合的功能模块，并且便于二次复用。ROS1的通讯系统基于TCPROS/UDPROS，而ROS2的通讯系统基于DDS。DDS是一种分布式实时系统中数据发布/订阅的标准解决方案，下一小节会具体讲解。ROS2内部提供了DDS的抽象层实现，用户不需要关注底层DDS的提供厂家。 在ROS1的架构中Nodelet和TCPROS/UDPROS是并列的层次，为同一个进程中的多个节点提供一种更优化的数据传输方式。ROS2中也保留了这种数据传输方式，只不过换了一个名字，叫做“Intra-process”，同样也是独立于DDS。 应用层 ROS1强依赖于ROS Master，可以想像一旦Master宕机，整个系统会面临如何的窘境。但是从右边ROS2的架构中我们可以发现，之前让人耿耿于怀的Master终于消失了，节点之间使用一种称为“Discovery”的发现机制来获取彼此的信息。 1.3 ROS2的核心——DDS DDS，Data Distribution Service，即数据分发服务，2004年由对象管理组织OMG（Object Management Group）发布，是一种专门为实时系统设计的数据分发/订阅标准。 DDS最早应用于美国海军， 解决舰船复杂网络环境中大量软件升级的兼容性问题，目前已经成为美国国防部的强制标准，同时广泛应用于国防、民航、工业控制等领域，成为分布式实时系统中数据发布/订阅的标准解决方案。其技术核心是以数据为核心的发布/订阅模型（Data-Centric Publish-Subscribe ，DCPS），这种DCPS模型创建了一个“全局数据空间”（global data space）的概念，所有独立的应用都可以访问。 在DDS中，每一个发布者或者订阅者都称为参与者（participant），类似于ROS中节点的概念。每一个参与者都可以使用某种定义好的数据类型来读写全局数据空间。 1.4 ROS2的通讯模型 相信你一定还记得前边所学习的ROS1通讯模型，也就是Topic、Service等通讯机制。ROS2的通讯模型会稍显复杂，因为需要依赖于DDS，所以包含很多DDS的机制。基于DDS的ROS2通讯模型如下图所示： ROS2的通讯模型有以下几个关键概念： 参与者（Domain Participant） 一个参与者Participant就是一个容器，对应于一个使用DDS的用户，任何DDS的用户都必须通过Participant来访问全局数据空间。 发布者（Publisher） 数据发布的执行者，支持多种数据类型的发布，可以与多个数据写入器（DataWriter）相联，发布一种或多种主题（Topic）的消息。 订阅者（Subscriber） 数据订阅的执行者，支持多种数据类型的订阅，可以与多个数据读取器（DataReader）相联，订阅一种或多种主题（Topic）的消息。 数据写入器（DataWriter） 应用向发布者更新数据的对象，每个数据写入器对应一个特定的Topic，类似于ROS1中的一个消息发布者。 数据读取器（DataReader） 应用从订阅者读取数据的对象，每个数据读取器对应一个特定的Topic，类似于ROS1中的一个消息订阅者。 主题（Topic） 这个和ROS1中的Topic概念一致，一个Topic包含一个名称和一种数据结构。 Quality of Service 质量服务原则，简称QoS Policy，这是ROS2中新增的、也是非常重要的一个原则，控制各方面与底层的通讯机制，主要从时间限制、可靠性、持续性、历史记录这几个方面，满足用户针对不同场景的数据需求。 二、安装ROS2 2017年12月8日，第一个ROS2的正式版Ardent Apalone发布，这里就以该版本的ROS2为例，介绍ROS2的安装与使用方法。 2.1 安装ROS2 ROS2支持Ubuntu16.04系统，安装方法和ROS1类似，可以按照以下步骤进行安装： 添加软件源 $ sudo apt update && sudo apt install curl $ curl http://repo.ros2.org/repos.key | sudo apt-key add - $ sudo sh -c 'echo "deb [arch=amd64,arm64] http://repo.ros2.org/ubuntu/main xenial main" > /etc/apt/sources.list.d/ros2-latest.list' 安装ROS2 $ sudo apt-get update $ sudo apt install `apt list ros-ardent-* 2> /dev/null | grep "/" | awk -F/ '{print $1}' | grep -v -e ros-ardent-ros1-bridge -e ros-ardent-turtlebot2- | tr "\n" " "` 以上安装命令排除了ros-ardent-ros1-bridge和ros-ardent-turtlebot2-*等功能包，这些功能包需要依赖ROS1，可以在后续单独安装。 设置环境变量 $ source /opt/ros/ardent/setup.bash 如果安装了Python包——argcomplete，还需要设置以下环境变量： $ source /opt/ros/ardent/share/ros2cli/environment/ros2-argcomplete.bash 配置ROS Middleware（RMW） DDS是ROS2中的重要部分，ROS2默认使用的RMW是FastRPTS，我们也可以通过以下环境变量将默认RMW修改为OpenSplice： RMW_IMPLEMENTATION=rmw_opensplice_cpp 安装依赖ROS1的功能包 ROS2在很长一段时间会和ROS1并存，所以目前很多ROS2中的功能包需要依赖ROS1中的功能包，ROS2也提供了与ROS1之间通信的桥梁——ros1_bridge。在安装这些与ROS1有依赖关系的功能包之前，需要系统已经成功安装有ROS1，然后才能通过以下命令安装ROS2的功能包： $ sudo apt update $ sudo apt install ros-ardent-ros1-bridge ros-ardent-turtlebot2-* 按照以上方法安装完成后，就可以使用ROS2的命令了。ROS2的默认安装路径依然是在Ubuntu系统的/opt/ros路径下： 使用如下命令查看ROS2命令行工具相关的帮助信息： $ ros2 --help 2.2 运行talker和listener ROS2安装完成后，默认带有部分例程，为了验证ROS2是否安装成功，可以使用如下命令进行测试： $ ros2 run demo_nodes_cpp talker $ ros2 run demo_nodes_cpp listener 运行成功后，效果与我们在ROS1中实现的效果类似，如下图所示： 通过这个例程可以看到，在ROS2中运行节点时，并不需要启动ROS Master，两个节点之间建立的通讯连接完全依靠节点自身的“Discovery”机制。 三、在ROS2中实现talker与listener 接下来，我们尝试在ROS2中创建两个节点进行如上节的通讯。 3.1 创建工作目录和功能包 与ROS1相同，我们需要创建一个工作目录，作为代码管理的项目目录。ROS2中创建工作目录的方法与ROS1类似。 首先使用Linux命令创建一个工作目录文件夹： $ mkdir -p ~/ros2_ws/src 然后在src文件夹下创建功能包文件： $ cd ~/ros2_ws/src $ mkdir -p ros2_demo ROS2的功能包结构与ROS1中的功能包相同，需要CMakeLists.txt和package.xml文件，这里我们可以手动创建这两个文件。package.xml文件的内容如下： <?xml version="1.0"?> <package format="2"> <name>ros2_demo</name> <version>0.0.0</version> <description>Package containing examples of how to use the rcl API.</description> <maintainer email="huchunxu@hust.edu.cn">Hu Chunxu</maintainer> <license>Apache License 2.0</license> <buildtool_depend>ament_cmake</buildtool_depend> <buildtool_depend>rosidl_default_generators</buildtool_depend> <build_depend>example_interfaces</build_depend> <build_depend>rcl</build_depend> <build_depend>rmw_implementation</build_depend> <exec_depend>example_interfaces</exec_depend> <exec_depend>rcl</exec_depend> <exec_depend>rmw_implementation</exec_depend> <exec_depend>rosidl_default_runtime</exec_depend> <export> <build_type>ament_cmake</build_type> </export> </package> CMakeLists.txt文件的内容如下： cmake_minimum_required(VERSION 3.5) project(ros2_demo) # Default to C++14 if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 14) endif() if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wall -Wextra -Wpedantic) endif() find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) find_package(std_msgs REQUIRED) ament_package() 然后就可以回到工作目录的根路径下，使用如下命令进行编译了： $ ament build 编译完成后，在工作空间的根路径下会产生两个文件夹：build和install。 build文件夹放置了很多编译过程中的中间文件，而install文件夹里边是最终编译生成的可执行文件、库文件、环境变量等，和ROS1中的devel文件夹相对应，而devel文件夹在ROS2中已经不复存在了。 现在就可以在功能包中创建节点代码了，由于ROS2重新设计了API，我们以话题通讯的talker和listener为例，学习一下ROS2中基础API的使用方法。 3.2 创建talker 首先需要创建一个talker，发布指定的字符串消息，实现源码ros2_talker.cpp的详细内容如下： #include <iostream> #include <memory> #include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" int main(int argc, char * argv[]) { //ros::init(argc, argv, "talker"); rclcpp::init(argc, argv); //ros::NodeHandle n; auto node = rclcpp::Node::make_shared("talker"); // Set the QoS. ROS 2 will provide QoS profiles based on the following use cases: // Default QoS settings for publishers and subscriptions (rmw_qos_profile_default). // Services (rmw_qos_profile_services_default). // Sensor data (rmw_qos_profile_sensor_data). rmw_qos_profile_t custom_qos_profile = rmw_qos_profile_default; // set the depth to the QoS profile custom_qos_profile.depth = 7; //ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000); auto chatter_pub = node->create_publisher<std_msgs::msg::String>("chatter", custom_qos_profile); //ros::Rate loop_rate(10); rclcpp::WallRate loop_rate(2); auto msg = std::make_shared<std_msgs::msg::String>(); auto i = 1; //while (ros::ok()) while (rclcpp::ok()) { msg->data = "Hello World: " + std::to_string(i++); std::cout << "Publishing: '" << msg->data << "'" << std::endl; //chatter_pub.publish(msg); chatter_pub->publish(msg); //ros::spinOnce(); rclcpp::spin_some(node); //loop_rate.sleep(); loop_rate.sleep(); } return 0; } 在上边talker节点的实现里，注释中的内容对应于该语句在ROS1中的实现，从代码API的调用上可以看到，虽然API的名称变化较大，但是API接口参数的变化并不是很大。 需要注意的是，ROS2中加入了DDS的QoS机制，所以在代码中需要配置质量服务原则。ROS2所使用的DDS厂商也为我们提供了默认的配置选项，可以直接使用rmw_qos_profile_default。 3.3 创建listener 接下来创建listener节点，实现代码ros2_listerner.cpp的详细内容如下： #include <iostream> #include <memory> #include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" //void chatterCallback(const std_msgs::String::ConstPtr& msg) void chatterCallback(const std_msgs::msg::String::SharedPtr msg) { std::cout << "I heard: [" << msg->data << "]" << std::endl; } int main(int argc, char * argv[]) { //ros::init(argc, argv, "listener"); rclcpp::init(argc, argv); //ros::NodeHandle n; auto node = rclcpp::Node::make_shared("listener"); //ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback); auto sub = node->create_subscription<std_msgs::msg::String>( "chatter", chatterCallback, rmw_qos_profile_default); //ros::spin(); rclcpp::spin(node); return 0; } listener节点的代码实现变化不大，可以参考注释对应于ROS1中的语句，需要注意的仍然是QoS的配置。 3.4 修改CMakeLists.txt 编译之前，还需要修改CMakeLists.txt，加入对应源码文件的编译规则： add_executable(ros2_talker src/ros2_talker.cpp) ament_target_dependencies(ros2_talker rclcpp std_msgs) add_executable(ros2_listerner src/ros2_listerner.cpp) ament_target_dependencies(ros2_listerner rclcpp std_msgs) install(TARGETS ros2_talker ros2_listerner DESTINATION lib/${PROJECT_NAME} ) ROS2仍然使用CMakeLists.txt管理编译规则，内容上与ROS1相比没有太大变化。 3.5 编译并运行节点 接下来就可以回到工作空间的根目录下，使用“ament build”命令进行编译了。编译完成后，可以在install文件夹下找到生成的可执行文件： 运行后的效果和之前的例程类似，如下图所示： 从以上ROS2中talker和listerner节点代码的实现上，我们可以看到: ROS2中的API相比ROS1中发生了较大的变化。ROS2并不是在ROS1的基础上查漏补缺，而是完全从新设计。关于ROS2的API说明，可以参考API文档： http://docs.ros2.org/ardent/api/rclcpp/index.html 使用了更多C++的特性，比如auto、make_shared等； 加入了QoS配置。从上边的代码中，可以看到QoS有默认的配置rmw_qos_profile_default，而且talker将QoS的depth设置为“7”； 代码的总体架构还是与ROS1极为相似的。
ROS2探索总结-7.Why ROS2.0？ ROS已经走过11个年头，伴随机器人技术的大发展，ROS也得到了极大的推广和应用。尽管还存在不少局限性，但依然无法掩盖ROS的锋芒，社区内的功能包还是呈指数级逐年上涨，为机器人开发带来了巨大的便利。 ROS最初设计的目标机器人是PR2，这款机器人搭载了当时最先进的移动计算平台，而且网络性能优异，不需要考虑实时性方面的问题，主要应用于科研领域。 如今ROS应用的机器人领域越来越广：轮式机器人、人形机器人、工业机械手、室外机器人（如无人驾驶汽车）、无人飞行器、救援机器人等等，美国NASA甚至考虑使用ROS开发火星探测器；越来越多的机器人开始从科研领域走向人们的日常生活。 ROS 1虽然仍是机器人领域的开发利器，但介于最初设计时的局限性，也逐渐暴露出不少问题。 目前的ROS 1主要存在以下问题： 1.多机器人系统 多机器人系统是机器人领域研究的一个重点问题，可以解决单机器人性能不足、无法应用等问题，但是ROS 1中并没有构建多机器人系统的标准方法。 2.跨平台 ROS 1基于Linux系统，在Windows、MacOS、RTOS等系统上无法应用或者功能有限，这对机器人开发者和开发工具提出了较高要求，也有很大的局限性。 3.实时性 很多应用场景下的机器人对实时性有较高要求，尤其是工业领域，系统需要做到硬实时的性能指标，但是ROS 1缺少实时性方面的设计，所以在很多应用中捉襟见肘。 4.网络连接 ROS 1的分布式机制需要良好的网络环境保证数据的完整性，而且网络没有数据加密、安全防护等功能，网络中的任意主机都可获得节点发布或接收的消息数据。 5.产品化 ROS 1的稳定性欠佳，ROS Master、节点等重要环节在很多情况下会莫名宕机，这就导致很多机器人从研究开发到消费产品的过渡非常艰难。 虽然不少开发者和研究机构针对以上部分问题进行了改良，但这些局部功能的改善往往很难带来整体性能的提升，机器人开发者对新一代ROS的呼声越来越大，ROS 2.0的消息也不绝于耳。 ROSCon 2014上，新一代ROS的设计架构（Next-generation ROS: Building on DDS）正式公布。2015年8月第一个ROS 2.0的alpha版本落地；2016年12月19日，ROS 2.0的beta版本正式发布； 2017年12月8日，万众瞩目的ROS 2.0终于发布了第一个正式版——Ardent Apalone。2018年7月2日，第二个正式版——Bouncy Bolson发布，保持半年更新一个版本的节奏。2018年12月，第三个正式版——Crystal Clemmys也将发布。 众多新技术和新概念应用到了新一代的ROS之中，不仅带来了整体架构的颠覆，更是增强了ROS 2.0的综合性能。 ROS 2诞生的目标并不是取代ROS 1，也不可能立刻取代ROS 1，众多功能包迁移到ROS 2将会是一个漫长的过程，ROS 2自身功能的完善也还需要迭代多个版本，所以在很长一段时间内，ROS 2和ROS 1将会并存。 最后，用一张图来总结ROS 2和ROS 1的主要特性：
ROS2探索总结-8.What is ROS2.0 ？ 说明： 上篇“Why ROS 2.0”之后，这篇我们继续“What is ROS .0”。 一、ROS 2的设计目标 相比ROS 1，ROS 2的设计目标更加丰富： 支持多机器人系统 ROS 2增加了对多机器人系统的支持，提高了多机器人之间通信的网络性能，更多多机器人系统及应用将出现在ROS社区中。 铲除原型与产品之间的鸿沟 ROS 2不仅针对科研领域，还关注机器人从研究到应用之间的过渡，可以让更多机器人直接搭载ROS 2系统走向市场。 支持微控制器 ROS 2不仅可以运行在现有的X86和ARM系统上，还将支持MCU等嵌入式微控制器，比如常用的ARM-M4、M7内核。 支持实时控制 ROS 2还加入了实时控制的支持，可以提高控制的时效性和整体机器人的性能。 跨系统平台支持 ROS 2不止能运行在Linux系统之上，还增加了对Windows、MacOS、RTOS等系统的支持，让开发者的选择更加自由。 二、ROS 2的系统架构 ROS 2重新设计了系统架构，可以从下图中看到两代ROS之间架构的变化： OS层 ROS 1主要构建于Linux系统之上；ROS 2带来了改变，支持构建的系统包括Linux、Windows、Mac、RTOS，甚至没有操作系统的裸机。 中间层 ROS中最重要的一个概念就是计算图中的“节点”，可以让开发者并行开发低耦合的功能模块，并且便于二次复用。ROS 1的通信系统基于TCPROS/UDPROS，而ROS 2的通信系统基于DDS。DDS是一种分布式实时系统中数据发布/订阅的标准解决方案。ROS 2内部提供了DDS的抽象层实现，用户不需要关注底层DDS的提供厂家。在ROS 1的架构中，Nodelet和TCPROS/UDPROS是并列的层次，可以为同一个进程中的多个节点提供一种更优化的数据传输方式。ROS 2中也保留了类似的数据传输方式，叫做“Intra-process”，同样独立于DDS。 应用层 ROS 1强依赖于ROS Master，可以想象一旦Master宕机，整个系统会面临如何的窘境。但是在右边ROS 2的架构中，让人耿耿于怀的Master终于消失了，节点之间使用一种称为“Discovery”的发现机制来帮助彼此建立连接。 三、ROS 2的关键中间件——DDS DDS（Data Distribution Service），即数据分发服务，2004年由对象管理组织OMG（Object Management Group）发布，是一种专门为实时系统设计的数据分发/订阅标准。 DDS最早应用于美国海军，解决舰船复杂网络环境中大量软件升级的兼容性问题，目前已经成为美国国防部的强制标准，同时广泛应用于国防、民航、工业控制等领域，成为分布式实时系统中数据发布/订阅的标准解决方案。 其技术关键是以数据为核心的发布/订阅模型（Data-Centric Publish-Subscribe ，DCPS），这种DCPS模型创建了一个“全局数据空间”（global data space）的概念，所有独立的应用都可以访问。 目前已经有多家DDS厂商可以提供相关技术，包括可供ROS使用的开源版本和商业版本。 四、ROS 2的通信模型 ROS 1的通信模型主要包含话题、服务等通信机制，ROS 2的通信模型会稍显复杂，加入了很多DDS的通信机制。 基于DDS的ROS 2通信模型包含以下几个关键概念： 参与者（Participant） 在DDS中，每一个发布者或者订阅者都称为参与者，对应于一个使用DDS的用户，可以使用某种定义好的数据类型来读写全局数据空间。 发布者（Publisher） 数据发布的执行者，支持多种数据类型的发布，可以与多个数据写入器（DataWriter）相联，发布一种或多种主题（Topic）的消息。 订阅者（Subscriber） 数据订阅的执行者，支持多种数据类型的订阅，可以与多个数据读取器（DataReader）相联，订阅一种或多种主题（Topic）的消息。 数据写入器（DataWriter） 上层应用向发布者更新数据的对象，每个数据写入器对应一个特定的Topic，类似于ROS 1中的一个消息发布者。 数据读取器（DataReader） 上层应用从订阅者读取数据的对象，每个数据读取器对应一个特定的Topic，类似于ROS 1中的一个消息订阅者。 话题（Topic） 和ROS 1中的概念类似，话题需要定义一个名称和一种数据结构，但ROS 2中的每个话题都是一个实例，可以存储该话题中的历史消息数据。 质量服务原则（Quality of Service） 简称QoS Policy，这是ROS 2中新增的、也是非常重要的一个概念，控制各方面与底层的通信机制，主要从时间限制、可靠性、持续性、历史记录这几个方面，满足用户针对不同场景的数据需求。 实时性增强：数据必须在deadline之前完成更新； 持续性增强：DDS可以为ROS 2提供数据历史服务，新加入的节点也可以获取发布者发布的所有历史数据； 可靠性增强：配置可靠性原则，用户可以根据需求选择性能模式（BEST_EFFORT）或者稳定模式（RELIABLE）。
ROS2探索总结-8.What is ROS2.0 ？ 说明： 上篇“Why ROS 2.0”之后，这篇我们继续“What is ROS 2.0”。 一、ROS 2的设计目标 相比ROS 1，ROS 2的设计目标更加丰富： 支持多机器人系统 ROS 2增加了对多机器人系统的支持，提高了多机器人之间通信的网络性能，更多多机器人系统及应用将出现在ROS社区中。 铲除原型与产品之间的鸿沟 ROS 2不仅针对科研领域，还关注机器人从研究到应用之间的过渡，可以让更多机器人直接搭载ROS 2系统走向市场。 支持微控制器 ROS 2不仅可以运行在现有的X86和ARM系统上，还将支持MCU等嵌入式微控制器，比如常用的ARM-M4、M7内核。 支持实时控制 ROS 2还加入了实时控制的支持，可以提高控制的时效性和整体机器人的性能。 跨系统平台支持 ROS 2不止能运行在Linux系统之上，还增加了对Windows、MacOS、RTOS等系统的支持，让开发者的选择更加自由。 二、ROS 2的系统架构 ROS 2重新设计了系统架构，可以从下图中看到两代ROS之间架构的变化： OS层 ROS 1主要构建于Linux系统之上；ROS 2带来了改变，支持构建的系统包括Linux、Windows、Mac、RTOS，甚至没有操作系统的裸机。 中间层 ROS中最重要的一个概念就是计算图中的“节点”，可以让开发者并行开发低耦合的功能模块，并且便于二次复用。ROS 1的通信系统基于TCPROS/UDPROS，而ROS 2的通信系统基于DDS。DDS是一种分布式实时系统中数据发布/订阅的标准解决方案。ROS 2内部提供了DDS的抽象层实现，用户不需要关注底层DDS的提供厂家。在ROS 1的架构中，Nodelet和TCPROS/UDPROS是并列的层次，可以为同一个进程中的多个节点提供一种更优化的数据传输方式。ROS 2中也保留了类似的数据传输方式，叫做“Intra-process”，同样独立于DDS。 应用层 ROS 1强依赖于ROS Master，可以想象一旦Master宕机，整个系统会面临如何的窘境。但是在右边ROS 2的架构中，让人耿耿于怀的Master终于消失了，节点之间使用一种称为“Discovery”的发现机制来帮助彼此建立连接。 三、ROS 2的关键中间件——DDS DDS（Data Distribution Service），即数据分发服务，2004年由对象管理组织OMG（Object Management Group）发布，是一种专门为实时系统设计的数据分发/订阅标准。 DDS最早应用于美国海军，解决舰船复杂网络环境中大量软件升级的兼容性问题，目前已经成为美国国防部的强制标准，同时广泛应用于国防、民航、工业控制等领域，成为分布式实时系统中数据发布/订阅的标准解决方案。 其技术关键是以数据为核心的发布/订阅模型（Data-Centric Publish-Subscribe ，DCPS），这种DCPS模型创建了一个“全局数据空间”（global data space）的概念，所有独立的应用都可以访问。 目前已经有多家DDS厂商可以提供相关技术，包括可供ROS使用的开源版本和商业版本。 四、ROS 2的通信模型 ROS 1的通信模型主要包含话题、服务等通信机制，ROS 2的通信模型会稍显复杂，加入了很多DDS的通信机制。 基于DDS的ROS 2通信模型包含以下几个关键概念： 参与者（Participant） 在DDS中，每一个发布者或者订阅者都称为参与者，对应于一个使用DDS的用户，可以使用某种定义好的数据类型来读写全局数据空间。 发布者（Publisher） 数据发布的执行者，支持多种数据类型的发布，可以与多个数据写入器（DataWriter）相联，发布一种或多种主题（Topic）的消息。 订阅者（Subscriber） 数据订阅的执行者，支持多种数据类型的订阅，可以与多个数据读取器（DataReader）相联，订阅一种或多种主题（Topic）的消息。 数据写入器（DataWriter） 上层应用向发布者更新数据的对象，每个数据写入器对应一个特定的Topic，类似于ROS 1中的一个消息发布者。 数据读取器（DataReader） 上层应用从订阅者读取数据的对象，每个数据读取器对应一个特定的Topic，类似于ROS 1中的一个消息订阅者。 话题（Topic） 和ROS 1中的概念类似，话题需要定义一个名称和一种数据结构，但ROS 2中的每个话题都是一个实例，可以存储该话题中的历史消息数据。 质量服务原则（Quality of Service） 简称QoS Policy，这是ROS 2中新增的、也是非常重要的一个概念，控制各方面与底层的通信机制，主要从时间限制、可靠性、持续性、历史记录这几个方面，满足用户针对不同场景的数据需求。 实时性增强：数据必须在deadline之前完成更新； 持续性增强：DDS可以为ROS 2提供数据历史服务，新加入的节点也可以获取发布者发布的所有历史数据； 可靠性增强：配置可靠性原则，用户可以根据需求选择性能模式（BEST_EFFORT）或者稳定模式（RELIABLE）。