ROS-现代机器人的脊梁
注意 本文中出现的观点仅代表个人而非任何与作者现实中产生交集的人或组织。
引子
每个机器人和自动化的学生在毕业之前都会或多或少学点ROS
自从差不多10年前开源机器人基金会 正式成立以来,他们所贡献的机器人操作系统(ROS) 就是现代机器人舞台上的明星。 不可否认在ROS之前肯定存在过其他也很成功的机器人平台,但是在ROS出现之后他们都黯然失色。易用性,扩展性,还有拓展性,让整个框架飞速成长,甚至可以说间接的帮助了先进机器人产业的磅礴发展。 毕竟小到昆虫大小的仿生虫群,大到十几米高的人形机甲;从深海的无人深潜器,到太空中ISS里的机器人实验器材;他们都是由ROS驱动的。这样一套统一泛用的框架无可否认必定是优秀的。
必然的成功
现在,然我们以更细节的视角来观察一下为什么ROS会如此成功。当然,这里的讨论会主要着重于ROS2,因为ROS1毕竟已经EOL了。最主要的讨论会围绕之前提到过的易用性,扩展性和拓展性。在开始详细讨论之前,我们先来看一下ROS2的总体结构。
整体架构:层叠抽象
ROS2总体架构 https://design.ros2.org/articles/ros_on_dds.html
如上图所示,ROS的本身总体分为3部分。即最下层的DDS通信组件,在其之上的用于统一不同DDS接口的RMW层(当然,只要胆子大,你甚至可以用邮件来驱动ROS)和暴露给用户的API。其中API层提供了便捷的抽象和数量众多的功能,为用户体提供了大量简单易用的方法。而RMW层拥有一个统一稳定的对下层通信的接口,当然一般来说这里真正对接更下层通信组件的代码是由提供者编写的。再然后则是DDS通信组件,在这里他们起到了服务发现和信息传输的功能。
一切看起来都很美好不是吗,当然不是,这套体系中确实提供了最大化的抽象和易用性,但是同时也带来了一些缺点。对这些缺点的讨论会在后文提及,现在我们先专注于解释这个架构。 首先需要明确一点,ROS2的诞生是由新的,超出原本预期的使用场景推动的。在ROS2的设计说明里也明确了这一点,同时ROS2在设计之初就希望能最大限度的利用已有组件并专注于提供机器人相关的功能。所以整套系统的设计中更多的考虑了功能的易开发易扩展,而对性能以及存在的可能资源问题则放到了不那么重要的位置上。 对于OSRF以及整个开源机器人宇宙里的用户来说无疑是正确的决定,依靠牺牲一点点中间组件的性能可以换来更完善的生态和第三方的支持。不过在有些场景下,这些性能损耗也能成为影响整个系统的阿克琉斯之踵。当然对大多数场景来说用户完全可以感谢这些设计上的取舍,没有他们就没有ROS的那些方便易用可扩展的优点。
易使用
可能对ROS2易用性最有力阐述的例子来源于ROS2中的action。简单来说就是一个service,但是在server计算结果的时候可以向client提供状态更新。在ROS1里这个功能是以独立package的形式提供的,但是ROS2对这种通信模式提供了原生的支持。 我们暂且把这个改变的原因放到一边,单看这个功能本身。
ROS Action内部细节 https://design.ros2.org/articles/actions.html
从图片上来看也不是很复杂不是吗,只需要3个ROS service和2个ROS topic就能得到一个action了。但是让我们再深入一点,每个service的节点都会包含6个parameter service(server/client对),这些parameter提供给外部观察和设置某个节点的对应状态的能力。除此之外,节点内同时还有数量不定的用户service实现。假如站在中间件的角度来看,那么同一时刻每个node都存在至少12个通信节点,同时还不包括用户所定义的那些使用节点本身。这样简单计算一下则每个action都会有至少60个通信节点,这些节点需要互相发现对方,然后判断是否需要收发包然后再考虑什么时候要停止收发。光是想想这些东西的复杂程度就能让我晚上睡觉做噩梦!哦等一下,我根本不需要关心这些细节,伟大的OSRF和那些(或多或少有些不幸的)中间件的服务商已经把这些东西都关照好了。我只需要从rcl里创建一个action,然后写几个回调函数就好,真是让人安心。
我想从这个例子里ROS的易用性已经被完美的展示了。前文提到的层叠抽象架构非常良好的把下层事项与上层应用分隔了开来,让用户只需要专注于他们所关心的业务本身。当然,ROS2里还有其他许许多多类似的例子,比如moveit2和rviz2等等。他们共同构建起了一个完全可以称之为独一无二的生态体系。我认为这也是ROS最大最宝贵的财富。
可扩展
在ROS2设计之初就考虑到了系统本身的扩展性(Scalability)。毕竟按照其官方设计说明的介绍,ROS2诞生的第一大推动(假如它的顺序代表着重要性的话)就是多终端多机器人的使用场景原来越多。不过在ROS2的代码里其实对这种扩展性的并没有与其重要性相搭配的体现,大多数代码都没有对这种理念展示出过多的关心。这是因为绝大部分的工作都由底层的DDS通信中间件完成了,而ROS原生的基于node的通信体系也决定了整套系统不需要再这里过多考虑。当然,这并不代表ROS在这方面已经完美了,对确定性的追求始终在是一个绕不开的点。个人认为只有当这一点得到解决的时候ROS的地位才真正的不可撼动。
现在我们用一个例子来简单了解一下,著名的酒保-服务员问题可以很好的展现出ROS的扩展性。在由不同种类的机器人组成的异构体系(heterogeneous system)内用户几乎不需要关心任何由系统差异造成的内在区别,而只需要聚焦于不同机器人带来的使用不同而已。这些机器人的所有控制与感知都可以在一个相通的体系内无感的解决。想象一下如果ROS没有考虑扩展性,那么每个机器人都要考虑如何与其他可能产生交互的同伴进行通信,更不用说完全不同的机器人之间要怎么才能传输信息了。
扩展性的体现并不仅仅局限于一套稳定系统内的交互,ROS2的去中心化代表着整套体系是可热插拔的。例如你的机器人小酒馆来了很多客人,那么你只需要简单的派出一个新的酒保机器人即可而不用重新设计一整套通信体系。这种灵活性也为ROS带来了更多的可能应用场景使得这套系统在Federated Learning和Distributed Method愈发流行的当下更具吸引力。
高拓展
拓展性(Extensibility)在这里指的是对系统应用面上的扩展。在一开始ROS是为了机器人所设计的平台系统,但是现在,几乎所有涉及到高级自动化和需要进行环境交互的系统里都有了ROS的身影。不可否认这样的成就是由ROS的易用性和扩展性带来的,不过可以肯定的是,没有ROS天生的的高拓展性那么这一切都不可能发生。
在我看来,这里描述的拓展性中有关技术的很大的一部分已经在前文说明过了,所以在这里主要是谈谈非技术性的部分。互联网是有梦想的,无论资本与现实怎么践踏这一点,依然会有人在成为比尔盖茨和成为Linus Torvalds之间选择后者。而对机器人社区来说,我们做的白日梦更多一点(笑)。假如不是为了有朝一日把孩提时代的梦想变为现实,很多人都不会在这个行业里工作。也正因为这些梦想,我们才有OSRF而非MicroBots之类的公司。对ROS来说,拓展性最好的表现就是它的开源。假如你觉得某些方面有问题那一个PR,一个issue可能就能优化掉它。而一个个这样的PR慢慢得将ROS的存在扩展到了各种各样的应用场景里。我敢说现在ROS一半的使用场景都是最开始所不支持的。
除此之外,ROS的高拓展性还要感谢生态中的那些开源库,例如前文提到过的moveit2。它们既是拓展性的一环也是拓展性的一种体现。ROS本身的拓展性使得这些包的存在成为可能而它们的存在又反过来支撑了ROS继续拓展适用场景。
缺憾的存在
正如之前所说的,ROS并不完美,甚至在很多方面上做的不如在它之前的系统优秀。例如运算速度与时延,资源消耗,和可靠性上ROS都存在着或多或少的问题。 例如ROS中广受诟病的executors,他们在某些程度上已经成为了ROS中运算的瓶颈。还有就是由于层叠抽象所带来的时延问题,一层接一层的抽象中包含的拷贝等等在轻而易举的加大了ROS中消息的延迟的同时还进一步的吞食了系统中的资源。 同时也如前文在action的例子中提到的,良好的抽象并不代表着高效。ROS中存在着大量的非用户所关注的资源消耗,甚至说,很可能ROS自带的各种机制所消耗的资源都比用户所真正用到的资源要多。 更重要的是ROS的可靠性并没有得到验证,至少就初始状态的ROS来说它并没有真正把可靠性放在一个很高的位置去考虑。理论上来说ROS的架构保证了它至少不是不可靠的,但是当用户真正需要高可靠的平台的时候(合作机器人,车辆等),没有人能真正站出来确保ROS不会失效或是它的失效不会带来严重后果。
未来的ROS
我认为未来的ROS会着力于继续发扬前文提到的几点优势而着力改进之前说到的劣势。其实在某种程度上来说ROS从不曾改变,它定义的这一套“标准”从规范的角度出发几乎完美的做到了设计上所期望的一切事情。 但是时代在变,这几年里新技术和新思路的不断推出使得ROS并不能完美的承接最新的使用场景。当然这种场景目前还很少见,同时不完美也不代表不能用不是吗。不过终有一天ROS会迎来自己的进化,而对它进化路线的一些畅想,我会在之后的文章中给出。
“Hail the Omnissiah! He is the God in the Machine, the Source of All Knowledge.”
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.