0%

ros2与dds

在探索ROS下一代通信系统的选项时,最初的选择是改进ROS 1的传输,或者使用ZeroMQ、Protocol Buffers和zeroconf(Bonjour/Avahi)等组件库构建一个新的中间件。然而,除了这些选项(这两个选项都涉及到我们从头开始构建一个中间件),ROS项目组还考虑了其他端到端的中间件。在研究中,一个中间件脱颖而出,那就是DDS。

使用端到端中间件(如DDS)的好处是,需要维护的代码要少得多,而且中间件的行为和确切规格已经被提炼成文档。有了这种具体的规范,第三方可以审查、审计和实施具有不同程度的互操作性的中间件。此外,如果要从现有的库中构建一个新的中间件,无论如何都需要创建这种类型的规范。

什么是DDS

DDS提供了一个发布-订阅的传输(publish-subscribe transport ),这与ROS1的发布-订阅的传输非常相似。DDS使用OMG定义的接口描述语言进行消息定义和序列化。

类似于ROS的服务系统,DDS有一个请求-响应式的传输(request-response style transport)。

DDS提供的发现系统是一个分布式发现系统,这允许任何两个DDS程序进行通信,而不需要像ROS1 master那样的工具。这使得系统的容错性和灵活性更高。同时,DDS不需要使用动态发现机制,多个DDS供应商提供了静态发现的选项。

技术上的可行性

DDSI-RTPS非常灵活,允许它用于可靠的、高水平的系统集成以及嵌入式设备上的实时应用。由于DDS默认是在UDP上实现的,它不依赖于可靠的传输或硬件进行通信。这意味着DDS必须重新发明可靠性轮子(基本上是TCP加上或减去一些功能),但作为交换,DDS获得了便携性和对行为的控制。通过对几个可靠性参数的控制,即DDS所说的服务质量(QoS),为控制通信行为提供了最大的灵活性。

尽管DDS的默认实现是通过UDP,并且只要求传输的功能水平,但有供应商支持通过TCP实现的DDS。

实现

eProsima的FastRTPS实现可在GitHub上获得,并获得LGPL许可。

https://github.com/eProsima/Fast-RTPS

构建在DDS上的ROS

ROS 2将在DDS之上提供一个类似于ROS 1的接口,为大多数ROS用户隐藏了DDS的复杂性,但又为那些有极端用例或需要与其他现有DDS系统集成的用户单独提供对底层DDS实现的访问。

DDS and ROS API Layout

发现

DDS将完全取代ROS1基于主控的发现系统。ROS需要利用DDS的API来获取信息,如所有节点的列表,所有主题的列表,以及它们是如何连接的。对这些信息的访问将被隐藏在ROS定义的API后面,防止用户直接调用DDS。

DDS发现系统的优点是,在默认情况下,它是完全分布式的,不会出现中央故障点。DDS还允许用户在其发现系统中定义元数据,这将使ROS能够在发布-订阅上附加更高级别的概念。

发布-订阅传输

DDSI-RTPS协议取代ROS的TCPROS和UDPROS线协议,用于发布/订阅。DDS API为ROS的典型发布/订阅模式提供了更多的参与者。

DDS的主题(Topic)与ROS中的主题概念相似。

DDS中的参与者(Participant)ROS的节点(Node)概念相似。但在DDS中,节点会被表示为独立的代码对象,既不是订阅者也不是发布者。

../../_images/dds_domain.svg

高效的传输方式

在ROS 1中,没有一个标准的共享内存传输,如果有任务需要比本地主机TCP更快的速度时,可以使用Nodelets。Nodelets允许发布者和订阅者通过传递boost::shared_ptrs到消息中来共享数据。这种进程内的通信几乎比任何进程间的通信选项更快,而且与网络发布-订阅实现向兼容。

大多数DDS供应商会以透明的方式使用共享内存来优化消息流量(甚至在进程之间),只在离开Localhost时使用有线协议和UDP套接字,这为DDS提供了相当大的性能提升。

消息

目前的ROS消息定义有很大的价值。格式很简单,而且消息本身已经在机器人社区的多年使用中得到了发展。当前ROS代码的大部分语义内容都是由这些消息的结构和内容驱动的,因此保留消息的格式和内存表示法具有很大的价值。为了达到这个目标,ROS 2保留ROS 1那样的消息定义和内存表示

因此,ROS 1的.msg文件将继续使用,.msg文件会被转换为.idl文件,以便它们可以被DDS使用。ROS 2 API将专门处理内存中的.msg风格的消息对象,并在发布前将其转换为.idl对象。

Message Generation Diagram

在每次调用发布时将消息逐字段转换为另一种对象类型的似乎是一个巨大的性能问题,但实验表明,与序列化的成本相比,这种转换的成本是微不足道的。

语言支持

DDS供应商通常至少提供C、C++和Java的实现,因为这些语言的API是由DDS规范明确定义的。ROS 2系统的其中一个目标是提供功能完整的C语言API,开发人员可以将C语言的API包装成一个像Python、Ruby和Lisp这样的语言。

DDS实现的依赖

ROS 2的目标之一是要尽量减少依赖的数量,以提高可移植性并保持精简的依赖列表。

DDS的一个亮点,就是依赖的精简。DDS的C语言实现只依赖于系统库,C++实现只依赖于C++03编译器,而Java实现只需要JVM和Java标准库。在Ubuntu和OS X上,OpenSplice(其中一种实现)的C、C++、Java和C#实现加在一起,其大小不到3兆字节,并且没有其他依赖性。就依赖的精简性而言,DDS非常有吸引力。