DDS 协议详解
目录
- [DDS 概述](#DDS 概述)
- [DDS 核心特点](#DDS 核心特点)
- [DDS 架构与核心组件](#DDS 架构与核心组件)
- [DDS 通信流程](#DDS 通信流程)
- [QoS 策略详解](#QoS 策略详解)(含 [机器人场景 QoS 实践](#机器人场景 QoS 实践))
- 传输层与发现机制(含 端口与多机部署)
- 应用领域与协议对比(含 [ROS 2 与 DDS](#ROS 2 与 DDS))
- [DDS 与 RTPS 的关系](#DDS 与 RTPS 的关系)
- [RTPS 协议栈与消息结构](#RTPS 协议栈与消息结构)
- [关键 Submessage 与交互过程](#关键 Submessage 与交互过程)
- [DDS 实现选型与 Fast DDS 开发](#DDS 实现选型与 Fast DDS 开发)(含 常见问题与排查)
- 术语与速查
- 规范与延伸阅读
文档总览
DDS(Data Distribution Service,数据分发服务) 是由 OMG(Object Management Group)制定的工业级通信中间件标准,用于分布式实时系统中的高效、可靠数据交换。可将其理解为一种「数据邮局」:自动把数据从发布者送到订阅者,并保证准时、不丢、不乱序。
订阅端
DDS网络
发布端
Publisher
DataWriter
Topic
DataReader
Subscriber
| 维度 | 说明 |
|---|---|
| 标准组织 | OMG |
| 模型 | 发布/订阅(去中心化) |
| 核心 | QoS 可配置、实时性、跨平台 |
| 有线协议 | 常用 DDSI-RTPS(Real-Time Publish-Subscribe) |
一、DDS 概述
DDS 是一种数据分发服务规范,定义分布式实时系统中节点之间如何发现、匹配、传输数据。上层提供 DCPS(Data-Centric Publish-Subscribe)API 与 QoS,底层可通过 RTPS 等有线协议在 UDP/TCP/共享内存上传输。
二、DDS 核心特点
| 特性 | 说明 |
|---|---|
| 发布/订阅模型 | 发送者(Publisher)发布数据到 Topic,接收者(Subscriber)订阅感兴趣的 Topic |
| 去中心化 | 无中央服务器,节点之间直接通信 |
| QoS(服务质量) | 可精细配置可靠性、时效性、优先级、历史、持久性等 |
| 实时性 | 为低延迟、高吞吐场景设计 |
| 跨平台 | 支持 C/C++/Java 等与多种操作系统 |
三、DDS 架构与核心组件
3.1 组件关系概览
DomainParticipant
Topic
Publisher
Subscriber
DataWriter
DataReader
3.2 各组件说明
| 组件 | 作用 |
|---|---|
| DomainParticipant | 应用接入 DDS 网络的入口,属于某个 Domain ID(类似局域网编号) |
| Topic | 数据的抽象标识,定义数据类型(Topic Type),如 Temperature 主题、类型 Float |
| Publisher / Subscriber | Publisher 负责发送,Subscriber 负责接收 |
| DataWriter / DataReader | DataWriter 绑定到 Topic 并执行发布;DataReader 绑定到 Topic 并执行接收 |
| QoS | 控制可靠性(Reliability)、截止时间(Deadline)、历史(History)、所有权(Ownership)、持久性(Durability)、存活(Liveliness)等 |
四、DDS 通信流程
- 初始化 :创建
DomainParticipant→Topic→Publisher/Subscriber→DataWriter/DataReader - 发现:通过组播/单播自动发现域内其他节点及其 Topic、QoS
- 发布 :
DataWriter.write(data)发送数据 - 匹配:按 Topic 名称、类型、QoS 将 DataReader 与 DataWriter 关联
- 接收:Subscriber 通过 Listener 或 WaitSet 接收数据
应用B DDS 中间件 应用A 应用B DDS 中间件 应用A 创建 Participant/Topic/Writer 创建 Participant/Topic/Reader SPDP/SEDP 发现与匹配 write(sample) on_data_available / take
五、QoS 策略详解
QoS 是 DDS 的核心,使通信行为可预测、可配置。
| QoS 策略 | 作用 | 常见选项 |
|---|---|---|
| Reliability | 数据是否必须可靠到达 | BEST_EFFORT(尽力而为)/ RELIABLE(可靠) |
| Durability | 新订阅者能否收到历史数据 | VOLATILE / TRANSIENT_LOCAL / PERSISTENT |
| Deadline | 数据发布周期最大允许值,超时触发回调 | 时间间隔 |
| LatencyBudget | 允许的最大传输延迟 | 影响路由选择 |
| History | 保留多少条历史数据 | KEEP_LAST_N / KEEP_ALL |
| Ownership | 多发布者时的数据覆盖规则 | SHARED / EXCLUSIVE |
| Liveliness | 检测发布者是否存活 | 超时则通知应用 |
5.1 机器人场景下的 QoS 实践
机器人系统中不同数据对实时性、可靠性的要求不同,可按下表选择 QoS,与 ROS 2 默认行为一致。
| 数据类型 / Topic 示例 | 推荐 Reliability | 推荐 Durability | 说明 |
|---|---|---|---|
| 传感器(激光、相机、IMU) | BEST_EFFORT | VOLATILE | 宁可丢帧也要低延迟,新订阅者不需要历史 |
| 控制指令(cmd_vel、关节目标) | 视场景:BEST_EFFORT 或 RELIABLE | VOLATILE | 运动控制常选 BEST_EFFORT 降低延迟 |
| 静态/慢变(地图、参数、tf) | RELIABLE | TRANSIENT_LOCAL | 后加入的节点需拿到最新一份,避免「空窗」 |
| 诊断/日志 | RELIABLE | VOLATILE 或 TRANSIENT_LOCAL | 保证不丢或允许新节点读最近状态 |
- BEST_EFFORT:适合高频、可容忍丢包的传感器与控制流。
- TRANSIENT_LOCAL :Writer 端保留若干历史,新 Reader 连接后可收到「最后一条」或最近 N 条,常用于
/tf、地图、全局参数。
六、传输层与发现机制
- 传输层:UDP、TCP、共享内存、TLS 等
- 发现机制 :
- SPDP(Simple Participant Discovery Protocol):发现域内 Participant
- SEDP(Simple Endpoint Discovery Protocol):发现 Topic、Publisher、Subscriber、DataWriter、DataReader 及 QoS
- 支持静态(预配置)与动态(自动识别)发现。
6.1 端口、组播与多机部署
| 项目 | 典型值 | 说明 |
|---|---|---|
| RTPS 默认端口 | 7400(及 7401、7402...) | 每个 Participant 可占一个端口,多机需放行 UDP |
| 组播地址(IPv4) | 239.255.0.1 等 | SPDP/SEDP 发现用组播,多机/跨网段需组播可达或配静态发现 |
| Domain ID | 0~232−1 | 同一域内才能发现;ROS 2 中 ROS_DOMAIN_ID 对应 DDS Domain ID |
多机/容器部署注意:
- Domain ID 一致 :所有节点使用相同 Domain ID(如 ROS 2 设相同
ROS_DOMAIN_ID),否则无法发现。 - 防火墙:放行 RTPS 所用 UDP 端口(默认 7400 及后续端口)及组播。
- 多网卡:若主机多网卡,需在 DDS 配置中指定使用的接口或地址,避免发现走错网卡。
七、应用领域与协议对比
7.1 典型应用领域
工业自动化(机器人、PLC)、航空航天(飞控、卫星)、汽车电子(车载以太网、ADAS)、医疗(实时影像)、能源电力(智能电网)、军事(C4ISR)等。
7.2 与其他通信协议对比
| 协议 | 模型 | 实时性 | 适用场景 |
|---|---|---|---|
| DDS | 发布/订阅 | 高 | 实时分布式系统 |
| MQTT | 发布/订阅 | 中 | IoT、低带宽 |
| AMQP | 消息队列 | 中 | 企业级消息系统 |
| HTTP/REST | 请求/响应 | 低 | Web 服务 |
| gRPC | RPC | 中高 | 微服务通信 |
7.3 ROS 2 与 DDS
在机器人领域,ROS 2 默认采用 DDS 作为底层通信中间件。应用层通过 rclcpp/rclpy 发布/订阅 Topic、调用 Service,RMW(ROS Middleware)层将请求转给具体 DDS 实现(如 Fast DDS、Cyclone DDS、RTI Connext),再由 RTPS 在 UDP/共享内存上传输。这样既保留 DDS 的实时性与 QoS 能力,又让 ROS 2 节点可跨进程、跨机、跨厂商互通。
DDS 实现
RMW 接口层
ROS 2 应用层
节点 rclcpp / rclpy
Topic / Service / Action
rmw 抽象
Fast DDS
Cyclone DDS
Connext DDS
RTPS / UDP·SHM
- 为何 ROS 2 选 DDS:去中心化、内置发现、QoS 可配、适合实时与多机协作,与工业/车载等既有 DDS 生态兼容。
- 常用 RMW :
rmw_fastrtps_cpp(默认)、rmw_cyclone_cpp、rmw_connextdds等,可通过环境变量或 launch 选择。
八、DDS 与 RTPS 的关系
- DDS:上层规范,定义 API、QoS、数据模型(DCPS)。
- RTPS :DDS 的有线协议(wire protocol),由 OMG DDSI-RTPS 2.x 定义,实现不同厂商 DDS 的互联互通。
- 可理解为:DDS 是「应用层+中间件层」,RTPS 是「传输/会话层」的具体实现;讲 DDS 协议体,实际是在讲 RTPS 消息结构 与发现/数据交换过程。
传输层
有线协议层
应用层
DDS Application / DCPS API
DDSI-RTPS
UDP/TCP/SHM
8.1 DDS 规范层次与传输实现
DDS 规范分层:应用与 DCPS 与底层传输解耦;DDSI 定义互操作与有线协议;RTPS 是 DDSI 的常见实现,但非唯一(可用自定义 UDP、共享内存等替代,仅影响互操作性)。
DDS 应用 / 业务层
DDS DCPS 核心规范
DDSI 互操作 / 有线协议
RTPS 或 其他协议
传输层: UDP/TCP/SHM/TLS
传输实现选项对比:
| 实现方式 | 是否标准 (OMG) | 跨厂商互通 | 实时性 | 适用场景 |
|---|---|---|---|---|
| RTPS (DDSI-RTPS 2.5) | 是 | 是 | 高 | 工业、汽车、航空、多厂商 |
| 自定义 UDP | 否 | 否 | 高 | 资源受限嵌入式 |
| 共享内存 (SHM) | 否 | 同主机 | 极高 | 单机多进程 |
| WebSocket/MQTT 适配 | 否 | 否 | 低 | IoT 云对接、非实时 |
结论:需要跨平台、跨厂商、实时性高时推荐 DDSI-RTPS;单机或资源极度受限时可选用非 RTPS 传输,但会失去标准互操作。
九、RTPS 协议栈与消息结构
9.1 协议分层
+------------------------------------+
| DDS Application (IDL Types, QoS) |
+------------------------------------+
| DDSI-RTPS (Discovery & Data) |
| - Message Layer |
| - Submessage Layer |
| - CDR Serialization |
+------------------------------------+
| Transport: UDP / TCP / SHM |
+------------------------------------+
- Message:最外层,包含多个 Submessage。
- Submessage :固定头部 + 内容,类型如
DATA、HEARTBEAT、ACKNACK、INFO_TS。 - CDR:OMG 的序列化方式,用于编码 DDS 数据类型。
9.2 RTPS Message Header(概念)
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
| 0 | 4 | Magic | 'R''T''P''S' (0x52545053) |
| 4 | 2 | Version | 主/次版本(如 2.5) |
| 6 | 1 | VendorId | 厂商 ID |
| 7 | 12 | GuidPrefix | Participant GUID 前缀 |
| 后续 | 2/4 | Message Length | 消息体长度 |
9.3 Submessage 通用头
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
| +0 | 1 | SubmessageId | DATA=0x15, HEARTBEAT=0x07, ACKNACK=0x06 等 |
| +1 | 1 | Flags | Endianness、InlineQos 等 |
| +2 | 2 | SubmessageLength | 本 Submessage 内容长度 |
十、关键 Submessage 与交互过程
10.1 DATA / HEARTBEAT / ACKNACK
- DATA:承载实际数据,含 ReaderId、WriterId、WriterSN、可选 InlineQos、CDR 序列化负载。
- HEARTBEAT:可靠模式下告知 Reader 当前 Writer 的 firstSN~lastSN,用于检测丢包/请求重传。
- ACKNACK:Reader 回传已收/未收序列号(bitmap),Writer 据此重传。
10.2 交互阶段概览
- SPDP:Participant 周期向元多播地址(如 239.255.0.1:7400)发送 SPDP 数据,交换 Participant GUID、Builtin Endpoints、QoS。
- SEDP:通过 Builtin Writers/Readers 交换 Topic、DataWriter、DataReader 元数据(Topic 名、类型、QoS),完成匹配。
- 数据与可靠传输:Writer 发 DATA;可靠模式下发 HEARTBEAT,Reader 回 ACKNACK,Writer 重传缺失。
- 保活:Liveliness 通过 HEARTBEAT 与 lease_duration 检测节点存活。
Reader Writer Reader Writer DATA(sample) HEARTBEAT(firstSN, lastSN) ACKNACK(bitmap) DATA(重传)
10.3 数据序列化(CDR)
DDS 使用 OMG CDR 编码,与 CORBA GIOP 类似:按 IDL 类型进行 1/4 字节对齐序列化,支持基本类型、数组、序列、嵌套结构。
十一、DDS 实现选型与 Fast DDS 开发
11.1 主流实现对比
| 维度 | RTI Connext DDS | eProsima Fast DDS | OpenDDS |
|---|---|---|---|
| 实时性 | 高,工业级 | 高 | 中等 |
| 互操作性 | 全 DDSI-RTPS | 全 DDSI-RTPS | 需 RTPS 插件 |
| 资源占用 | 较大 | 轻量、可裁剪 | 最轻、可高度定制 |
| 易用性 | 工具与文档完善 | 上手快 | 配置较复杂 |
| 成本 | 商业授权 | 核心开源,有商业版 | 完全开源 |
11.2 典型场景推荐
- 高安全/高可靠(航空、医疗、国防):RTI Connext DDS(认证、TSN、商业支持)。
- 汽车/自动驾驶/机器人、ROS 2:Fast DDS(默认 rmw、轻量、生态好)。
- 资源受限/科研/定制:OpenDDS(开源、可替换传输层)。
- 跨厂商互通:Connext 或 Fast DDS,均支持 DDSI-RTPS 2.5。
11.3 Fast DDS 开发流程概要
- 环境:安装 Fast DDS(源码编译或包管理),依赖 CMake、C++ 编译器、可选 Python(Fast DDS-Gen)。
- 定义类型 :用 IDL 定义数据结构(如
HelloWorld.idl)。 - 生成代码 :使用
fastddsgen生成 C++ 类型与序列化代码。 - Publisher :创建 DomainParticipant → 注册类型 → 创建 Topic → Publisher → DataWriter →
write()。 - Subscriber :创建 Subscriber → DataReader,设置 Listener 的
on_data_available或 WaitSet 接收数据。 - QoS:在创建 Writer/Reader 时设置 Reliability、Durability 等。
IDL
fastddsgen
C++ 类型
Participant/Topic
Writer/Reader
write / Listener
11.4 Fast DDS 资源与工程结构
- 仓库:eProsima Fast DDS 开源项目,Apache 2.0 许可,核心 C++,提供 Fast DDS-Gen(IDL→C++/Python)、示例与文档。
- 典型工程结构 :
CMakeLists.txt+*.idl+src/publisher_main.cpp、src/subscriber_main.cpp;构建时链接fastrtps,运行前先启动 Subscriber 再启动 Publisher 即可验证收发。 - 调试:可配合 Wireshark 的 RTPS 插件抓包(如 UDP 7400),观察 SPDP、SEDP、DATA/HEARTBEAT/ACKNACK。
11.5 常见问题与排查
| 现象 | 可能原因 | 建议排查 |
|---|---|---|
| 发现不到其他节点 | Domain ID 不一致 | 确认所有进程使用相同 Domain ID(ROS 2:ROS_DOMAIN_ID) |
| 发现不到其他节点 | 组播/防火墙 | 放行 UDP 7400 及组播;多机时确认网络/防火墙允许组播或改用静态发现 |
| 发现不到其他节点 | 多网卡 | 在 DDS 配置中指定正确网卡或地址 |
| 订阅了但收不到数据 | QoS 不匹配 | 检查 Reliability、Durability、History 等是否与发布端兼容(如一方 RELIABLE 一方 BEST_EFFORT 可能不匹配) |
| 订阅了但收不到数据 | Topic 名/类型不一致 | 确认 Topic 名称与消息类型与发布端一致 |
| 延迟大或丢包多 | 可靠模式 + 高频率 | 评估是否可改用 BEST_EFFORT 或调大 History/资源 |
| 延迟大或丢包多 | 未用共享内存 | 单机多进程时启用 SHM 传输可显著降低延迟与拷贝 |
术语与速查
| 术语 | 英文 | 含义 |
|---|---|---|
| DDS | Data Distribution Service | 数据分发服务,OMG 标准 |
| RTPS | Real-Time Publish-Subscribe | DDS 有线协议,DDSI-RTPS |
| DCPS | Data-Centric Publish-Subscribe | 以数据为中心的发布/订阅 API |
| SPDP | Simple Participant Discovery Protocol | 参与者发现 |
| SEDP | Simple Endpoint Discovery Protocol | 端点(Topic/Writer/Reader)发现 |
| QoS | Quality of Service | 服务质量策略 |
| CDR | Common Data Representation | OMG 序列化格式 |
| GUID | Global Unique Identifier | Participant + EntityId 唯一标识 |
RTPS 常用 SubmessageId
| Id | 名称 | 用途 |
|---|---|---|
| 0x15 | DATA | 用户数据 |
| 0x07 | HEARTBEAT | 可靠传输心跳/范围 |
| 0x06 | ACKNACK | 确认/请求重传 |
| 0x09 | INFO_TS | 时间戳 |
规范与延伸阅读
- OMG 规范:DDS 1.4(Data Distribution Service)、DDSI-RTPS 2.5(Real-Time Publish-Subscribe Protocol),可从 OMG 官网获取正式规范文档。
- ROS 2 :ROS 2 文档中与 DDS 与 RMW 相关的章节,以及各 RMW 实现(Fast DDS、Cyclone DDS、Connext)的配置与调优说明。