ROS 2 是基于匿名发布/订阅(publish/subscribe)机制的中间件(middleware),该机制允许消息(message)在不同的 ROS 进程之间传递。ROS graph 是所有 ROS 2 系统的核心。ROS graph 是指 ROS 系统中节点的网络(network)以及它们之间进行通信(communicate)的连接(connection)。
1 基本概念
1.1 Quick Overview of Graph Concepts¶
- Nodes: 节点是使用 ROS 与其他节点进行通信的实体。
- Messages: 订阅或发布主题时使用的 ROS 数据类型。
- Topics: 节点可以将消息发布到主题,也可以订阅主题以接收消息。
- Discovery: 节点决定如何互相 talk 的自动过程。
1.2 Nodes¶
节点是 ROS graph 的参与者(participant)。ROS 节点使用 ROS 客户端库(client library)与其他节点进行通信。节点可以发布或订阅主题。节点还可以提供或使用 Service 和 Action。还有与节点关联的可配置参数(configurable Parameter)。
节点之间的连接是通过分布式发现过程(a distributed discovery process)建立的。节点可以位于同一进程,不同进程或不同机器上。
1.3 Client Libraries¶
ROS 客户端库(client libraries)允许使用不同编程语言编写的节点进行通信。有一个核心 ROS 客户端库(core ROS client library,简写 RCL),可实现不同语言的 ROS API 所需的通用功能。这样一来,特定语言的客户端库就更易于编写,并且行为上更加一致。
ROS 2 团队维护以下客户端库:
- rclcpp = C++ client library
- rclpy = Python client library
此外,ROS 社区还开发了其他客户端库。有关更多详细信息,请参见 ROS 2 Client Libraries 文章。
1.4 Discovery¶
节点的发现是通过 ROS 2 的基础中间件自动发生的。可以总结如下:
- 启动节点后,它会将其存在状态通告给具有相同 ROS domain(使用
ROS_DOMAIN_ID
环境变量设置)的网络上的其他节点。节点使用有关自身的信息来响应此通告,以便可以建立适当的连接并且节点可以进行通信。 - 节点定期通告其存在,以便即使在初始发现期之后也可以与新发现的实体建立连接。
- 当节点下线时,它们会向其他节点通告。
如果节点具有兼容的服务质量(Quality of Service)设置,则它们将仅与其他节点建立连接。
以 talker-listener demo 为例。在一个终端中运行 C++ talker 节点将发布有关主题的消息,而在另一终端中运行的 Python listener 节点将订阅有关同一主题的消息。
您会看到这些节点自动发现彼此,并开始交换消息。
2 About different ROS 2 DDS/RTPS vendors¶
ROS2 基于 DDS/RTPS 作为其中间件而构建,该中间件提供发现(discovery),序列化(serialization)和传输(transportation)。总而言之,DDS 是一种端到端中间件,它提供与 ROS 系统相关的功能,例如分布式发现,并控制传输的不同 “Quality of Service” 选项。
DDS 是一种行业标准,由许多供应商实现,例如 RTI 的实现 Connext,ADLINK 的实现 OpenSplice 或 Eclipse 的 Cyclone DDS。RTPS(也称为 DDSI-RTPS)是 DDS 用于通过网络进行通信的有线协议。有些实现不能满足完整的 DDS API,但是可以为 ROS 2 提供足够的功能,例如 eProsima 的实现 Fast RTPS。
ROS 2 支持多种 DDS/RTPS 实现,因为在选择供应商/实现时不一定是 “one size fits all”。选择中间件实现时,您可能会考虑许多因素:诸如许可证等 logistical 考虑,或诸如平台可用性或计算占用空间之类的技术考虑。供应商可以提供多个 DDS 或 RTPS 实现来满足不同的需求。例如,RTI 的 Connext 实现有一些目的不同的变化,例如一个专门针对微控制器,另一个针对需要特殊安全认证的应用(我们目前仅支持其标准台式机版本)。
为了将 DDS/RTPS 实现与 ROS2 结合使用,需要创建一个 “ROS Middleware interface”(又名 rmw
接口或仅 rmw
)包,该包使用 DDS 或 RTPS 实现的 API 和工具来实现抽象的 ROS 中间件接口。实现和维护 RMW 软件包以支持 DDS 实现是一项艰巨的工作,但是至少要支持一些实现对于确保 ROS2 代码库不与任何一种特定实现绑定都很重要,因为用户可能希望根据具体情况切换出实现他们的项目需求。
有关使用多个 RMW 实现的实用信息,请参见 "Working with multiple RMW implementations" 教程。
3 About Quality of Service settings¶
ROS2 提供了多种 Quality of Service(QoS)策略,使您可以调整节点之间的通信。有了正确的服务质量策略集,ROS 2可以像 TCP 一样可靠,也可以像 UDP 一样尽力而为,并且介于两者之间有很多可能的状态。与仅主要支持 TCP 的 ROS 1 不同, ROS 2 受益于在有损无线网络的环境中底层 DDS 传输的灵活性,在这种环境中“尽力而为”策略更适合,或者在实时计算系统中具有适当的质量,需要提供服务档案以符合截止日期。
一组 QoS “policies” 组合形成 QoS “profile”。考虑到为给定场景选择正确的 QoS 策略的复杂性,ROS2 为常见用例(例如传感器数据)提供了一组预定义的 QoS 配置文件(profiles)。同时,开发人员可以灵活地控制 QoS 配置文件的特定策略。
可以为 publishers, subscriptions, service servers 和 clients 指定 QoS 配置文件。可以将 QoS 配置文件独立应用于上述实体的每个实例,但是如果使用不同的配置文件,则它们可能无法连接。
3.1 QoS policies¶
基本 QoS 配置文件(profile)当前包括以下策略的设置:
- History
- Keep last: 最多只能存储 N 个样本,可通过“队列深度”选项进行配置。
- Keep all: 根据基础中间件的配置资源限制存储所有样本。
....
4 About ROS 2 interfaces
5 About topic statistics
ROS2 为任何订阅收到的消息提供了统计的集成度量。允许用户收集订阅统计信息,使他们能够表征系统的性能或帮助诊断任何当前问题。
提供的度量是接收到的消息寿命和接收到的消息周期。对于每次测量,提供的统计信息是平均值,最大值,最小值,标准差和样本数。这些统计信息是在移动窗口(moving window)中计算的。
5.1 How statistics are calculated¶
通过使用 软件包中实现的实用 libstatistics_collector 程序,可以在恒定的时间和恒定的内存中计算每个统计信息集。订阅收到新消息时,这是用于在当前测量窗口中进行计算的新示例。 计算出的平均值仅仅是 moving average。收到每个新样品后,最大,最小和样品数量都会更新,而标准差是使用 Welford’s online algorithm 计算的。
5.2 Types of statistics calculated¶
- Received message period
- Units: milliseconds(毫秒)
- 使用系统时钟来测量接收到的消息之间的时间间隔
- Received message age
- Units: milliseconds
- 要求消息在 header field 中填充时间戳,以便计算从 publisher 发送的消息的使用期限。
5.3 Behavior¶
默认情况下,不启用 Topic Statistics 测量。通过订阅配置选项为特定节点启用此功能后,将为该特定订阅启用 received message age 和 received message period 度量。
数据以可配置的时间段(默认为1秒)作为 statistics_msg/msg/MetricsMessage 发布到可配置的主题(默认为 /statistics
)。注意,发布期也用作样本收集窗口期。
由于收到的消息周期要求在 header field 中添加消息时间戳,因此将发布空数据。也就是说,如果未找到时间戳记,则所有统计信息值均为 NaN
。发布 NaN
值而不是根本不发布将避免不存在信号问题,并且旨在明确显示无法进行测量。
接收到的消息周期统计信息的每个窗口的第一个样本不会产生度量。这是因为计算此统计信息需要知道前一条消息到达的时间,因此窗口中的后续样本会产生测量值。
5.4 Support¶
ROS 2 Foxy 仅限于 C++(rclcpp
)当前支持此功能。可以在 here 找到将来的工作和改进,例如 Python 支持。