ROS 2 编程中 DDS 基础入门
首先说明不要被DDS的概念吓到,DDS是非常好用的中间件,但是在ROS2中只使用了一小部分DDS的功能,而且ROS2只是应用层面的调用,不涉及底层的内容,实际使用起来非常简单
关于DDS内容简单看一下即可
1. 什么是 DDS?
DDS(Data Distribution Service,数据分发服务)是一种用于实时系统的通信中间件,它为分布式应用程序提供可靠、高效的数据传输。ROS 2 使用 DDS 作为其底层通信机制,因此理解 DDS 的基本概念对于 ROS 2 编程至关重要。
2. DDS 的核心概念
- Domain(域): 一个逻辑上的通信空间,参与通信的节点必须属于同一个域。
- Participant(参与者): 代表一个应用程序或节点,参与域内的通信。
- Topic(主题): 数据的分类,类似于 ROS 1 中的 topic。
- Publisher(发布者): 向特定 topic 发布数据的参与者。
- Subscriber(订阅者): 从特定 topic 订阅数据的参与者。
- DataWriter(数据写入器): Publisher 用于向 topic 写入数据的对象。
- DataReader(数据读取器): Subscriber 用于从 topic 读取数据的对象。
- QoS(服务质量): 用于控制数据传输的各种参数,例如可靠性、持久性、截止时间等。
3. DDS 在 ROS 2 中的应用
- ROS 2 节点相当于 DDS 的 Participant。
- ROS 2 的 topic 和 service 都基于 DDS 的 Topic 和 DataWriter/DataReader 实现。
- ROS 2 提供了多种 QoS 配置选项,可以根据应用需求调整通信行为。
4. 学习 DDS 的资源
- DDS 官方文档: https://www.omg.org/spec/DDS/
- ROS 2 DDS 相关文档: https://docs.ros.org/en/rolling/Concepts/About-DDS-implementations.html
- DDS 入门教程: https://github.com/eProsima/DDS-Tutorial
5. 给 ROS 2 小白的建议
- 先掌握 ROS 2 的基本概念和编程方法,再深入学习 DDS。
- 从简单的例子开始,逐步理解 DDS 的工作原理。
- 利用 ROS 2 提供的工具和资源,例如
ros2 topic list
、ros2 topic echo
等,观察和分析 DDS 通信过程。
总结:
DDS 是 ROS 2 的核心通信机制,理解 DDS 的基本概念对于 ROS 2 编程至关重要。通过学习 DDS,你可以更好地理解 ROS 2 的通信机制,并编写出更高效、可靠的 ROS 2 应用程序。
是的,ROS 2 只使用了 DDS 的一部分功能。DDS 是一个功能非常丰富的通信中间件,提供了许多高级特性,但 ROS 2 的设计目标是保持轻量化和易用性,因此它只使用了 DDS 的核心功能来满足机器人应用的需求。
接下里介绍ROS2,下面内容详细看一下
ROS 2 使用的 DDS 核心功能
以下是 ROS 2 主要使用的 DDS 功能:
-
发布-订阅模型 (Publish-Subscribe)
- ROS 2 的通信模型基于 DDS 的发布-订阅机制。
- ROS 2 的
Publisher
和Subscriber
分别对应 DDS 的DataWriter
和DataReader
。 - ROS 2 的
Topic
直接映射到 DDS 的Topic
。
-
服务质量 (QoS, Quality of Service)
- ROS 2 使用了 DDS 的 QoS 策略来配置通信行为,例如:
- 可靠性(Reliability):确保消息不丢失(可靠)或允许丢失(尽力而为)。
- 持久性(Durability):确保新订阅者可以接收到发布者之前发送的消息。
- 历史深度(History Depth):控制消息队列的大小。
- 截止时间(Deadline):确保消息在指定时间内被传递。
- ROS 2 提供了一些预定义的 QoS 配置(如
reliable
、best_effort
等),同时也允许用户自定义 QoS。
- ROS 2 使用了 DDS 的 QoS 策略来配置通信行为,例如:
-
发现机制 (Discovery)
- DDS 提供了自动发现机制,ROS 2 利用这一功能实现节点的自动发现和连接。
- 当一个节点加入网络时,DDS 会自动发现其他节点并建立通信连接,无需手动配置。
-
数据类型支持
- ROS 2 使用 DDS 的数据类型系统来定义消息(
msg
)和服务(srv
)。 - ROS 2 的消息类型会被转换为 DDS 的数据类型(通过 IDL 或 RTPS 标准)。
- ROS 2 使用 DDS 的数据类型系统来定义消息(
-
传输协议
- DDS 支持多种传输协议(如 UDP、TCP、共享内存等),ROS 2 利用这些协议来实现跨网络的通信。
为什么 ROS 2 只使用 DDS 的一部分?
-
简化设计
- ROS 2 的目标是提供一个易于使用的机器人开发框架,因此它屏蔽了 DDS 的复杂性,只暴露了必要的功能。
-
性能优化
- DDS 的许多高级功能会增加系统开销,而 ROS 2 需要保持高效的实时通信性能。
-
跨 DDS 实现的兼容性
- ROS 2 支持多种 DDS 实现(如 Fast DDS、Cyclone DDS、Connext DDS 等),因此它只使用了 DDS 的核心功能,以确保在不同实现之间的兼容性。
-
专注于机器人应用
- ROS 2 的设计目标是满足机器人应用的需求,而 DDS 的许多高级功能(如复杂的数据持久化、内容过滤等)在机器人应用中并不常用。
重点内容(开发中会用到)
DDS的核心是发布订阅,这里与ros的topic发布订阅通信机制不一样,只是名字一样,在 ROS 2 中,DDS 的通信调优不仅限于 Topic,而是可以应用于所有基于 DDS 的通信机制,包括 Topic、Service 和 Action。这是因为 ROS 2 的通信层完全基于 DDS 实现,无论是 Topic、Service 还是 Action,底层都依赖于 DDS 的 DataWriter
和 DataReader
进行数据传输。
下面是关于各个通信类型的调优参数(在实际开发中作为参数传递给各个通信类型的对象)
1. Topic 的通信调优
Topic 是 ROS 2 中最常用的通信机制,也是最容易进行调优的部分。通过调整 DDS 的 QoS(Quality of Service,服务质量) 参数,可以优化 Topic 的通信性能。常见的 QoS 参数包括:
- 可靠性(Reliability):
RELIABLE
: 确保消息不丢失(适用于关键数据)。BEST_EFFORT
: 允许消息丢失(适用于对实时性要求高的场景)。
- 持久性(Durability):
VOLATILE
: 新订阅者无法接收到发布者之前发送的消息。TRANSIENT_LOCAL
: 新订阅者可以接收到发布者之前发送的消息。
- 历史深度(History Depth):
- 控制消息队列的大小,避免内存溢出。
- 截止时间(Deadline):
- 确保消息在指定时间内被传递。
- 生命周期(Lifespan):
- 设置消息的有效期,过期消息会被丢弃。
2. Service 的通信调优
Service 的底层通信也基于 DDS,因此可以通过调整 QoS 参数来优化其性能。Service 的 QoS 调优主要集中在以下几个方面:
- 可靠性(Reliability):
- 通常设置为
RELIABLE
,以确保请求和响应的可靠性。
- 通常设置为
- 超时时间(Timeout):
- 客户端可以设置等待响应的超时时间,避免无限等待。
- 队列大小(Queue Size):
- 控制服务端处理请求的队列大小,避免请求堆积。
3. Action 的通信调优
Action 是 Service 的扩展,支持长时间运行的任务和进度反馈。Action 的通信调优可以通过以下方式实现:
- Goal QoS:
- 设置目标请求的可靠性、持久性等参数。
- Feedback QoS:
- 调整反馈消息的传输频率和可靠性。
- Result QoS:
- 确保任务结果的可靠传递。
- Deadline:
- 设置任务的截止时间,确保任务在规定时间内完成。
4. 全局通信调优
除了针对特定通信类型的调优,还可以通过以下方式全局优化 ROS 2 的通信性能:
- 选择合适的 DDS 实现:
- ROS 2 支持多种 DDS 实现(如 Fast DDS、Cyclone DDS、Connext DDS 等),不同实现的性能和特性可能有所不同。
- 调整 DDS 的配置文件:
- 通过修改 DDS 的 XML 配置文件,可以更精细地控制通信行为(如线程数量、缓冲区大小等)。
- 优化网络配置:
- 确保网络带宽和延迟满足实时通信的需求。
- 使用共享内存:
- 对于同一台机器上的节点通信,可以启用 DDS 的共享内存传输,减少网络开销。
5. 调优工具
ROS 2 提供了一些工具来帮助调试和优化通信性能:
ros2 topic
命令:- 查看 Topic 的通信状态(如带宽、消息频率等)。
ros2 param
命令:- 动态调整节点的参数(如 QoS 配置)。
ros2 doctor
命令:- 检查系统的通信状态和潜在问题。
- DDS 自带的工具:
- 不同 DDS 实现通常提供自己的监控和调试工具(如 Fast DDS 的
fastddsmonitor
)。
- 不同 DDS 实现通常提供自己的监控和调试工具(如 Fast DDS 的
调优的本质是平衡与取舍,在资源有限的情况下获取最优解,以下是实际开发中调所要考虑的因素
在 ROS 2 中,DDS 通信调优需要同时兼顾通信类型的特性(如 Topic、Service、Action 的差异)和具体业务场景的需求。两者不可分割,因为不同通信类型的设计目标不同,而不同业务场景对通信性能的要求也各异。调优的本质是在通信类型的底层机制和业务逻辑的实际需求之间找到最佳平衡。
1. 通信类型的特性影响调优方式
不同通信类型(Topic、Service、Action)的底层实现和设计目标不同,调优时需要针对其特点进行调整:
(1) Topic(主题)
- 特性:单向异步、持续数据流(如传感器数据)。
- 调优重点:
- 可靠性(Reliability):传感器数据是否需要严格不丢失(如激光雷达数据用
RELIABLE
,摄像头流用BEST_EFFORT
)。 - 历史深度(History Depth):控制队列大小,避免内存溢出(如高频 IMU 数据可能需要限制历史深度)。
- 截止时间(Deadline):确保数据按时到达(如控制指令需要严格实时性)。
- 持久性(Durability):是否需要新订阅者获取历史数据(如地图数据可能需要
TRANSIENT_LOCAL
)。
- 可靠性(Reliability):传感器数据是否需要严格不丢失(如激光雷达数据用
- 示例:
- 自动驾驶中,激光雷达数据需要高可靠性和低延迟(
RELIABLE
+ 小历史深度)。 - 视频流传输可以接受偶尔丢帧(
BEST_EFFORT
+ 大历史深度)。
- 自动驾驶中,激光雷达数据需要高可靠性和低延迟(
(2) Service(服务)
- 特性:双向同步、短时任务(如调用一次算法)。
- 调优重点:
- 可靠性:必须为
RELIABLE
(请求和响应不能丢失)。 - 超时时间(Timeout):避免客户端无限等待(如设置 1 秒超时)。
- 队列大小:服务端处理请求的并发能力(如限制队列大小防止过载)。
- 可靠性:必须为
- 示例:
- 机器人运动控制服务需要严格实时性(小超时时间 + 高优先级)。
- 后台计算服务可以容忍稍长延迟(大超时时间 + 低优先级)。
(3) Action(动作)
- 特性:双向异步、长时间任务(如导航任务)。
- 调优重点:
- Goal QoS:目标传递的可靠性(如
RELIABLE
)。 - Feedback QoS:反馈频率和可靠性(如高频反馈用
BEST_EFFORT
)。 - Deadline:任务整体完成时间限制(如导航任务需在 30 秒内完成)。
- Goal QoS:目标传递的可靠性(如
- 示例:
- 机械臂抓取任务需要实时反馈(高频反馈 +
BEST_EFFORT
)。 - 导航任务需要确保结果可靠(Goal 和 Result 用
RELIABLE
)。
- 机械臂抓取任务需要实时反馈(高频反馈 +
2. 业务场景需求决定调优方向
不同业务场景对通信性能的要求差异巨大,调优需紧密结合实际需求:
(1) 实时性要求
- 场景:机器人控制、工业自动化。
- 调优方向:
- 使用
BEST_EFFORT
减少延迟。 - 启用 DDS 的共享内存传输(同一机器内通信)。
- 限制历史深度和队列大小,避免积压。
- 使用
(2) 可靠性要求
- 场景:关键状态更新(如紧急停止信号)。
- 调优方向:
- 强制使用
RELIABLE
和TRANSIENT_LOCAL
。 - 增加重试机制和冗余传输。
- 强制使用
(3) 大数据量传输
- 场景:点云、图像传输。
- 调优方向:
- 使用零拷贝(Zero-Copy)减少内存复制开销。
- 调整 DDS 的传输缓冲区大小。
- 选择支持大消息分片的 DDS 实现(如 Fast DDS)。
(4) 资源受限环境
- 场景:嵌入式设备、低功耗机器人。
- 调优方向:
- 降低 QoS 配置复杂度(如减少历史深度)。
- 选择轻量级 DDS 实现(如 Cyclone DDS)。
- 限制网络带宽占用。
3. 调优的综合策略
实际调优需要结合通信类型和业务场景,通常遵循以下步骤:
-
明确业务需求:
- 确定实时性、可靠性、数据量、资源限制等核心指标。
- 例如:自动驾驶中,激光雷达数据需要高可靠性和低延迟,而调试日志可以容忍延迟。
-
选择通信类型:
- 根据任务性质选择 Topic、Service 或 Action。
- 例如:连续数据流用 Topic,短时计算用 Service,导航任务用 Action。
-
配置 QoS 参数:
- Topic:调整可靠性、持久性、历史深度。
- Service:设置超时时间和队列大小。
- Action:分离 Goal、Feedback、Result 的 QoS。
- 示例:
# Topic 的 QoS 配置示例(Python) from rclpy.qos import QoSProfile, QoSReliabilityPolicy, QoSDurabilityPolicy # 高可靠性 + 持久化 qos_reliable = QoSProfile( reliability=QoSReliabilityPolicy.RELIABLE, durability=QoSDurabilityPolicy.TRANSIENT_LOCAL, depth=10 ) # 低延迟 + 允许丢包 qos_best_effort = QoSProfile( reliability=QoSReliabilityPolicy.BEST_EFFORT, depth=1 )
-
选择 DDS 实现和配置:
- 根据场景选择 Fast DDS(高性能)、Cyclone DDS(轻量级)或 Connext DDS(企业级)。
- 修改 DDS 的 XML 配置文件(如线程优先级、传输协议)。
-
监控和动态调整:
- 使用
ros2 topic bw
、ros2 topic delay
等工具监控通信性能。 - 根据运行时状态动态调整 QoS(如网络拥塞时降低可靠性)。
- 使用
4. 经典调优案例
(1) 案例 1:机器人导航系统
- 需求:实时性(控制指令) + 可靠性(目标传递) + 反馈频率(进度更新)。
- 调优:
- 控制指令(Topic):
BEST_EFFORT
+ 小历史深度。 - 导航目标(Action Goal):
RELIABLE
+ 持久化。 - 反馈(Action Feedback):
BEST_EFFORT
+ 高频发送。
- 控制指令(Topic):
(2) 案例 2:工业物联网(IIoT)
- 需求:高可靠性(设备状态) + 大数据量(传感器数据)。
- 调优:
- 设备状态(Service):
RELIABLE
+ 冗余超时。 - 传感器数据(Topic):零拷贝 + 大缓冲区。
- 设备状态(Service):
总结
DDS 通信调优需要同时考虑:
- 通信类型的特性(Topic/Service/Action 的机制差异)。
- 业务场景的需求(实时性、可靠性、资源限制等)。
调优的本质是在通信机制的底层能力(由 DDS 提供)和业务逻辑的高层需求之间找到最佳匹配。实际开发中,通常需要多次迭代测试,结合 ROS 2 工具链和 DDS 的监控功能,逐步逼近最优配置。
下一篇会给出详细的代码实例