文章目录
- DDS
-
- ROS1架构和ROS2架构之间的关系
- DDS架构
- [QoS(Quality of Service)](#QoS(Quality of Service))
- RMW
- cycloneDDS
- fastDDS
- 比较
DDS
DDS(Data Distribution Service,数据分发服务)为实时分布式系统设计的数据通信标准。
是一个去中心化的、以数据为中心的发布/订阅中间件协议。
- 去中心化
DDS 没有中心代理,所有节点是对等的,通过自动的动态发现机制找到彼此并直接通信。这避免了单点故障和中心节点的性能瓶颈。 - 以数据为中心
发布-订阅导向 - 实时
底层使用零拷贝和共享内存
ROS1架构和ROS2架构之间的关系

DDS架构

QoS(Quality of Service)
配置节点间通信行为的一组策略
发布方(Publisher)和订阅方(Subscriber)的配置必须兼容才能建立连接。
匹配的总原则是:订阅方的"要求"必须比发布方的"承诺"更宽松或相等。
cpp
// 创建一个自定义的 QoS 对象
auto custom_qos = rclcpp::QoS(rclcpp::KeepLast(10)) // 历史记录:保留最近10条
.reliable() // 可靠性:可靠(类似TCP)
.transient_local() // 持久性:为晚加入的订阅者提供历史数据
.deadline(std::chrono::milliseconds(100));// 截止时间:每100ms必须收到一次数据
// 应用到发布者
auto publisher = this->create_publisher<std_msgs::msg::String>("my_topic", custom_qos);
// 应用到订阅者(必须兼容发布者的配置)
auto subscriber = this->create_subscription<std_msgs::msg::String>("my_topic", custom_qos, callback_function);
可靠性 (Reliability)
- RELIABLE 可靠:确保数据送达,丢失会重传。
- BEST_EFFORT 尽力:低延迟,丢失不重传。
历史记录 (History)
- KEEP_LAST (保留最近N条):只为新的订阅者保留队列里最后的 N 条消息。
- KEEP_ALL (保留所有条):为所有新订阅者保留发布过的所有消息。
持久性 (Durability)
- VOLATILE (易变的):新订阅者只能收到连接建立之后发布的消息。
- TRANSIENT_LOCAL (本地瞬态的):新订阅者能收到连接建立之前,发布者已发出的部分历史数据
深度 (Depth)
截止时间 (Deadline)
预期的最大数据发布/接收间隔。如果超时,ROS 2 会触发回调,这对安全关键系统监控数据流是否中断非常重要。
活跃性 (Liveliness)
用于确认发布者是"活着"的。可以配置为当发布者节点还存活、或主动发送心跳信号时,才算活跃。
RMW
什么是RMW?
RMW(ROS Middleware Interface,ROS 中间件接口) 是 ROS 2 架构中的通信抽象层,它让 ROS 2 的核心功能与底层的通信协议解耦
可以使用如下命令查看使用的是哪个中间件
bash
ros2 doctor --report
cycloneDDS
接口:rmw_cyclonedds_cpp
优势:资源占用低
配置方式
使用方式1:
bash
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
export CYCLONEDDS_URI=file://从根目录开始的路径
使用方式2:
bash
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
export CYCLONEDDS_URI='xml格式扩展内容'
配置模板
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Eclipse Cyclone DDS 配置模板
适用版本:ROS 2 Humble (rmw_cyclonedds_cpp)
使用方式1:export CYCLONEDDS_URI=file://从根目录开始的路径
或者
使用方式2:export CYCLONEDDS_URI='xml格式扩展内容'
说明:手动指定网卡和单播对等体,适合需要精细控制网络路径的场景。
-->
<CycloneDDS xmlns="https://cdds.io/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://cdds.io/config
https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/master/etc/cyclonedds.xsd">
<Domain Id="any">
<!-- =============================================================================== -->
<!-- 1. 通用网络设置 (General) -->
<!-- =============================================================================== -->
<General>
<Interfaces>
<!--
!!!关键:将 "wlp2s0" 替换成你实际使用的网卡名字 !!!
使用命令 `ip a` 或 `ifconfig` 来查看你本机用于通信的网卡名。
autodetermine="false" 表示禁用自动选择,强制使用指定的网卡。
-->
<NetworkInterface autodetermine="false" name="wlp2s0" />
</Interfaces>
<!--
禁用组播。在 WiFi 或受限网络中,组播容易引起数据包丢失。
Cyclone DDS 默认情况下 AllowMulticast 是开启的。
-->
<AllowMulticast>false</AllowMulticast>
<!--
最大消息大小,默认 65500B。如果传输超大的点云或图像,可以适当调大。
例如:<MaxMessageSize>65500B</MaxMessageSize>
-->
</General>
<!-- =============================================================================== -->
<!-- 2. 发现配置 (Discovery) -->
<!-- =============================================================================== -->
<Discovery>
<!--
单播对等体列表。当组播被禁用后,完全依赖这个列表里的地址来寻找其他节点。
-->
<Peers>
<!-- !!!关键:添加所有你需要通信的远程主机的 IP 地址 !!! -->
<!-- 本地回环地址,保证本机节点间通信 -->
<Peer Address="127.0.0.1"/>
<!-- 远程主机1的IP -->
<Peer Address="192.168.1.100"/>
<!-- 可以继续添加更多远程主机 -->
</Peers>
</Discovery>
<!-- =============================================================================== -->
<!-- 3. 内部性能调优 (Internal) - 可选,高级场景才需要 -->
<!-- =============================================================================== -->
<!--
<Internal>
<Watermarks>
<WhcHigh>500kB</WhcHigh>
</Watermarks>
</Internal>
-->
</Domain>
</CycloneDDS>
当节点数量增加,需要更多内存运行节点时,直接在终端当中使用命令行
bash
export CYCLONEDDS_URI='
<CycloneDDS>
<Domain id="any">
<Discovery>
<ParticipantIndex>auto</ParticipantIndex>
<MaxAutoParticipantIndex>220</MaxAutoParticipantIndex>
</Discovery>
</Domain>
</CycloneDDS>'
或者在launch文件当中添加
python
# 提高 CYCLONEDDS_URI 自动参与者索引上限,避免多节点同时启动时域创建失败
SetEnvironmentVariable(
name='CYCLONEDDS_URI',
value='<CycloneDDS><Domain id="any"><Discovery><ParticipantIndex>auto</ParticipantIndex><MaxAutoParticipantIndex>120</MaxAutoParticipantIndex></Discovery></Domain></CycloneDDS>'
),
fastDDS
接口:rmw_fastrtps_cpp
优势:功能完整丰富
- 自带零拷贝功能实现(Cyclone DDS需要通过iceoryx实现)
- 多机、大规模、受限网络环境部署时的发现服务器(Discovery Server) 模式,可以大幅降低大规模系统中的网络发现流量
- 发布话题可以设置同步、异步模式;
- 异步模式:不阻塞主线程,适合多数场景----publish() 立即返回,数据被放入内部队列,由独立的后台线程负责发送。
- 同步模式:更高的吞吐量和更低的延迟,适合对实时性要求极高时使用----publish() 会阻塞当前线程,直到数据真正被写入网络后才返回。
xml
<publisher profile_name="async_publisher">
<qos>
<publishMode>
异步<kind>ASYNCHRONOUS_PUBLISH_MODE</kind>
同步<kind>SYNCHRONOUS_PUBLISH_MODE</kind>
</publishMode>
</qos>
</publisher>
- Statistics 模块与fastdds monitor 可视化工具:实时报告网络延迟、吞吐量、丢包数等详细通信指标,快速定位通信瓶颈(Cyclone DDS不能做到)
配置方式
bash
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
export FASTRTPS_DEFAULT_PROFILES_FILE=file://从根目录开始的路径
(只能指定文件路径来实现)
配置模板
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Fast DDS 高级配置模板
适用版本:ROS 2 Humble (rmw_fastrtps_cpp)
使用方式:export FASTRTPS_DEFAULT_PROFILES_FILE=file://从根目录开始的路径
(只能指定文件路径来实现)
说明:此模板关闭了组播,使用单播进行发现,适用于 WiFi 等组播不稳定的网络环境。
-->
<profiles>
<!-- =============================================================================== -->
<!-- 1. 传输层配置 (Transport Descriptors) -->
<!-- 让 Fast DDS 知道有哪些通道可以用来发送数据。 -->
<!-- =============================================================================== -->
<transport_descriptors>
<!-- 定义一个名为 "UDP_Transport" 的传输方式 -->
<transport_descriptor>
<transport_id>UDP_Transport</transport_id> <!-- 这个ID会在后面被引用 -->
<type>UDPv4</type>
<!-- 为了多机通信的稳定,通常关闭组播 -->
<interfaceWhiteList>
<!-- !!!关键:将 "wlp2s0" 替换成你实际使用的网卡名字 !!! -->
<!-- 使用命令 `ip a` 或 `ifconfig` 来查看你本机用于通信的网卡名 -->
<address>192.168.1.101</address>
</interfaceWhiteList>
</transport_descriptor>
</transport_descriptors>
<!-- =============================================================================== -->
<!-- 2. 参与者配置 (Participant Profiles) -->
<!-- 配置 ROS 2 节点(DDS 参与者)的通用行为。 -->
<!-- =============================================================================== -->
<participant profile_name="fastdds_custom_profile" is_default_profile="true">
<!-- 引用上面定义的传输方式 -->
<rtps>
<userTransports>
<transport_id>UDP_Transport</transport_id> <!-- 引用上面定义的传输ID -->
</userTransports>
<!-- 关闭默认的内置组播发现 -->
<builtin>
<!--
简单发现协议 (Simple Discovery Protocol) 配置。
默认使用 Multicast (组播),这里改为不使用。
-->
<initialPeersList>
<!-- !!!关键:添加所有你需要通信的远程主机的 IP 地址 !!! -->
<!-- 本地回环地址,保证本机节点间通信 -->
<locator>
<udpv4>
<address>127.0.0.1</address>
</udpv4>
</locator>
<!-- 远程主机1的IP -->
<locator>
<udpv4>
<address>192.168.1.100</address>
</udpv4>
</locator>
<!-- 可以继续添加更多远程主机 -->
</initialPeersList>
</builtin>
</rtps>
</participant>
</profiles>
比较
| DDS | Cyclone DDS | Fast DDS |
|---|---|---|
| 中间件名称 | rmw_cyclonedds_cpp | rmw_fastrtps_cpp |
| 设计理念 | 简洁、稳定和高性能 | 功能丰富和高可配置性 |
| 网络通信性能 | 跨主机通信延迟抖动更小,CPU 占用通常更低 | 在高吞吐场景下 CPU 占用相对更高 |
| 进程内通信性能 | 主要优势在网络通信,进程内也具备良好表现 | 在单机共享内存场景下延迟更低,零拷贝优化更成熟 |
| 环境变量(指定文件) | CYCLONEDDS_URI 环境变量 |
FASTRTPS_DEFAULT_PROFILES_FILE 环境变量 |
| 配置风格 | 配置项精简 | 配置项丰富 |
| 资源占用 | 内存和 CPU 占用通常更低,适合资源受限平台 | 功能全面,基准资源占用相对略高 |
| 适用场景 | 多机通信、嵌入式平台、对稳定性要求高的系统 | 单机大数据量通信、需要完整 DDS 功能覆盖或商业工具链支持的场景 |