一、DDS(Data Distribution Service)详解
1. 什么是 DDS?
DDS 是一种中间件协议 和 API 标准 ,用于分布式系统中的实时数据通信,由 OMG(Object Management Group)制定标准。
核心定位:以数据为中心的发布-订阅(DCPS)通信中间件
2. DDS 核心架构
┌─────────────────────────────────────────┐
│ Application Layer │
│ ┌─────────┐ ┌─────────┐ │
│ │ Publisher │ │ Subscriber │ │
│ │ (发布者) │ │ (订阅者) │ │
│ └────┬────┘ └────┬────┘ │
│ │ │ │
│ ┌────▼──────────────────▼────┐ │
│ │ DDS Global Data │ │
│ │ Space (GDS) │ │
│ │ ┌──────────────────┐ │ │
│ │ │ Topic (话题) │ │ │
│ │ │ - 数据类型定义 │ │ │
│ │ │ - QoS 策略 │ │ │
│ │ └──────────────────┘ │ │
│ └─────────────────────────────┘ │
│ │ │
│ ┌─────────────▼─────────────┐ │
│ │ DDS Implementation │ │
│ │ (Fast DDS/Cyclone/RTI) │ │
│ └─────────────┬─────────────┘ │
│ │ │
│ ┌─────────────▼─────────────┐ │
│ │ Transport Layer │ │
│ │ UDP/TCP/SHM/Zero Copy │ │
│ └───────────────────────────┘ │
└─────────────────────────────────────────┘
3. DDS 核心特性
| 特性 | 说明 |
|---|---|
| 去中心化 | 无 Broker,点对点通信 |
| 发现机制 | 自动发现节点,无需配置 IP |
| QoS 策略 | 23+ 种服务质量策略(可靠性、实时性、持久性等) |
| 动态组网 | 节点随时加入/离开不影响系统 |
| 多传输协议 | UDP、TCP、共享内存、零拷贝 |
4. DDS 发现机制详解
阶段 1:Participant Discovery (PDP)
├── 新节点加入,发送 SPDP(Simple Participant Discovery Protocol)报文
├── 使用 UDP 组播到 239.255.0.1:7400(默认)
└── 宣告:我是谁,我在哪个 Domain,我的元数据
阶段 2:Endpoint Discovery (EDP)
├── 交换 Topic 信息:我发布什么,我订阅什么
├── 匹配相同 Topic 的发布者和订阅者
└── 建立通信通道
阶段 3:数据传输
├── 匹配成功后,切换到单播或共享内存传输
└── 不再使用组播发送实际数据
5. 常用 DDS 实现
| 实现 | 开发商 | 特点 | ROS 2 默认 |
|---|---|---|---|
| Fast DDS | eProsima | 开源,性能优秀,功能全 | Foxy/Galactic 默认 |
| Cyclone DDS | Eclipse | 轻量,稳定,易配置 | Humble/Iron 默认 |
| RTI Connext | RTI | 商业版,工业级 | 需授权 |
| Iceoryx | Eclipse | 零拷贝,极致性能 | 配合 ROS 2 使用 |
二、广播(Broadcast)vs 组播(Multicast)详解
1. 核心区别对比
| 维度 | 广播(Broadcast) | 组播(Multicast) |
|---|---|---|
| 目标 | 网络中所有设备 | 特定组的成员 |
| IP 地址 | 255.255.255.255 或子网广播 |
224.0.0.0 - 239.255.255.255 |
| 范围 | 本地子网(被路由器阻断) | 可跨子网(需 IGMP/路由配置) |
| 效率 | 低,所有设备必须处理 | 高,仅组成员接收 |
| 应用场景 | ARP 请求、DHCP 发现 | 视频会议、在线直播、DDS 发现 |
2. 形象比喻
广播(Broadcast):
📢 公司大喇叭广播:"所有人来会议室开会!"
→ 不管想不想听,全公司都听到
组播(Multicast):
📧 邮件组发送:"@技术部 组,来会议室开会"
→ 只有技术部的人收到,其他部门不打扰
3. 网络层行为对比
广播帧结构
以太网帧:
┌──────────────┬──────────────┬────────────────┐
│ 目的 MAC │ 源 MAC │ 类型 │
│ FF:FF:FF:FF │ xx:xx:xx:xx │ 0x0800 (IP) │
└──────────────┴──────────────┴────────────────┘
IP 包:
┌─────────────────┬─────────────────┐
│ 目的 IP │ 源 IP │
│ 255.255.255.255 │ 192.168.1.10 │
└─────────────────┴─────────────────┘
→ 交换机泛洪到所有端口(除入口)
→ 所有网卡必须中断 CPU 处理
组播帧结构
以太网帧:
┌──────────────┬──────────────┬────────────────┐
│ 目的 MAC │ 源 MAC │ 类型 │
│ 01:00:5E:xx │ xx:xx:xx:xx │ 0x0800 (IP) │
└──────────────┴──────────────┴────────────────┘
↑
└─ 由组播 IP 映射而来(23 位)
IP 包:
┌─────────────────┬─────────────────┐
│ 目的 IP │ 源 IP │
│ 239.255.0.1 │ 192.168.1.10 │
└─────────────────┴─────────────────┘
→ 交换机通过 IGMP Snooping 只发给注册的端口
→ 非组成员网卡直接丢弃(硬件过滤)
4. 关键差异详解
效率差异
场景:1000 台设备的网络,10 个 DDS 节点
广播方式:
- 发现报文到达 1000 台设备
- 990 台无关设备被迫中断处理
- CPU 浪费严重
组播方式:
- 交换机维护 IGMP 表,知道哪几个端口要组播
- 只发给 10 个 DDS 节点所在端口
- 其他 990 台设备无感知
跨网段能力
广播:
[子网 A] → 路由器阻断 → [子网 B] ❌ 无法到达
组播:
[子网 A] → 路由器(配置 IGMP/PIM)→ [子网 B] ✅ 可以到达
5. DDS 为什么选择组播?
| 原因 | 说明 |
|---|---|
| 可扩展性 | 大规模系统下,广播会导致广播风暴 |
| 精准投递 | 只有运行 DDS 的节点处理发现报文 |
| 网络友好 | 交换机可优化组播流量,不泛洪 |
| 工业标准 | DDS 规范明确要求使用组播 |
三、ROS 2 + DDS 的实际通信流程
┌─────────────┐ ┌─────────────┐
│ Talker │ │ Listener │
│ (发布者) │ │ (订阅者) │
└──────┬──────┘ └──────┬──────┘
│ │
│ 1. SPDP 组播发现 │
│─────→ 239.255.0.1:7400 ─────────→│
│ "我是 Domain 0 的节点 A" │
│ │
│←──── 2. SPDP 组播响应 ────────────│
│ "我是 Domain 0 的节点 B" │
│ │
│ 3. EDP 单播交换 Topic 信息 │
│←════════════════════════════════→│
│ "我发布 /chatter (String)" │
│ "我订阅 /chatter" │
│ │
│ 4. 匹配成功,建立连接 │
│ │
│ 5. 数据传输(UDP 单播/SHM) │
│══════════"hello"════════════════→│
│ │
│ 6. 持续心跳(单播) │
│←──────── keepalive ─────────────→│
四、总结
| 问题 | 答案 |
|---|---|
| DDS 发现用什么? | 组播(Multicast),地址 239.255.x.x |
| DDS 数据传输用什么? | 单播(Unicast) 或 共享内存(SHM) |
| 为什么不用广播? | 效率低、不可扩展、会被路由器阻断 |
| 组播 vs 广播核心区别? | 组播是"发给特定组",广播是"发给所有人" |
ROS 2 的 DDS 实现严格遵循标准,使用组播进行发现,单播进行数据传输,既保证了自动组网的便利性,又确保了高效的网络通信。