DDS RTPS
1 发现阶段
1.1 基础概念
1.1.1 RTPS 的层级结构
Domain(域)
└── Participant(参与者)
├── DataWriter(写端点)
├── DataWriter
├── DataReader(读端点)
└── DataReader
三层,各司其职:
Domain(域)
- 逻辑隔离单元,用一个整数 domainId 标识(比如 0、1、2)
- 相同 domainId 的 Participant 才能互相通信,不同域完全隔离
- 它本身不是实体,只是一个分组规则
Participant(参与者)
- 一个应用进程里的 DDS 实体容器,是网络上可寻址的单位
- 拥有全局唯一的 GuidPrefix(GUID 的前 12 字节)
- 持有自己的单播/多播地址(Locator)
- 管理它下面所有的 Endpoint
Endpoint(端点)= DataWriter / DataReader
- 真正收发用户数据的实体
- 每个 Endpoint 有自己的 EntityId(GUID 的后 4 字节)
- 完整 GUID = Participant 的 GuidPrefix + Endpoint 的 EntityId
GUID = GuidPrefix + EntityId
- Writer 和 Reader 通过 Topic + 类型 + QoS 进行匹配
1.1.2 发现阶段:谁在哪一步做什么
注意:内置端点EntityID完全相同(规范硬编码),靠GUID Prefix区分。
| 端点名称 | EntityId | Participant APublisher 端 | Participant BSubscriber 端 |
|---|---|---|---|
| SPDP Writer | 00 01 00 c2 | ✅ 存在 | ✅ 存在 |
| SPDP Reader | 00 01 00 c7 | ✅ 存在 | ✅ 存在 |
| SEDPPub Writer | 00 00 03 c2 | ✅ 存在 | ✅ 存在 |
| SEDPPub Reader | 00 00 03 c7 | ✅ 存在 | ✅ 存在 |
| SEDPSub Writer | 00 00 04 c2 | ✅ 存在 | ✅ 存在 |
| SEDPSub Reader | 00 00 04 c7 | ✅ 存在 | ✅ 存在 |
| PartMsg Writer | 00 02 00 c2 | ✅ 存在 | ✅ 存在 |
| PartMsg Reader | 00 02 00 c7 | ✅ 存在 | ✅ 存在 |
| User DataWriter | 01 00 00 03 | ✅ 存在 | — |
| User DataReader | 00 00 01 04 | — | ✅ 存在 |
发现分两个阶段,严格有先后顺序:
阶段一:SPDP — 发现 Participant
Participant A Participant B
| |
|-- DATA(p) --> 多播地址 (周期性) --------->|
|<------------- 多播地址 (周期性) -- DATA(p)-|
| |
| 双方各自记录:对方的 GuidPrefix、 |
| 单播地址、租约时长等 |
| |
- 谁发: Participant
- 发什么: DATA(p),内容是 SPDPdiscoveredParticipantData
- 发给谁: 预定义的多播地址(同一 Domain 内所有 Participant 都监听)
- 怎么发: 周期性发送,间隔可配置
- 目的: 让大家知道"网络上有哪些 Participant,它们的地址在哪"
- 使用的内置端点: SPDPbuiltinParticipantWriter / SPDPbuiltinParticipantReader
阶段二:SEDP — 发现 Endpoint
Participant A Participant B
|--- DATA(w) --> 单播给 B: 我有 Writer1 -->|
|--- DATA(r) --> 单播给 B: 我有 Reader1 -->|
| |
|<-- DATA(w) --- 单播给 A: 我有 Writer2 ---|
|<-- DATA(r) --- 单播给 A: 我有 Reader3 ---|
| |
| 双方各自比对 Topic、类型、QoS |
| → Writer1 和 Reader3 匹配成功! |
| |
- 谁发: 还是 Participant,但代表的是它下面的各个 Endpoint
- 发什么: DATA(w) 通告 Writer,DATA(r) 通告 Reader
- 发给谁: SPDP 阶段已发现的 Participant 的单播地址(不再是多播)
- 什么时候发: SPDP 发现新 Participant 后触发;之后每次本地新增/删除 Endpoint 也会发
- 目的: 交换端点信息,让双方知道对面有哪些 Writer/Reader,进而做匹配
- 使用的内置端点:
- SEDPbuiltinPublicationsWriter/Reader — 交换 Writer 信息
- SEDPbuiltinSubscriptionsWriter/Reader — 交换 Reader 信息
三、总结对照
层级 发现协议 发的消息 传输方式 做的事
─────────────────────────────────────────────────────────
Domain 无 无 无 只是隔离边界
Participant SPDP DATA(p) 多播 "我在这里,地址是xxx"
Endpoint SEDP DATA(w/r) 单播 "我有这些读写端点,Topic和QoS是xxx"
─────────────────────────────────────────────────────────
↓
匹配成功 → 建立通信
- 为什么要分两阶段? 因为多播开销大。SPDP用多播只解决"谁在网上"这一个问题,剩下的端点细节全走单播,减少网络负担。
- SPDP 是持续的: 即使发现完成,DATA(p) 也会周期性发送,用来维持租约(lease)。如果超过leaseDuration 没收到对方的 DATA(p),就认为对方掉线。
- SEDP 是事件驱动的: 发现新 Participant 时触发一次全量交换,之后只在 Endpoint 增删时增量通告。
- 在 RTPS 协议中,DATA(p) 是一种特殊的 DATA 子消息(Submessage),其中 (p) 代表 Participant。
1.1.3 DATA子消息
1.1.3.1
| 子消息 | 含义 | 用途 |
| DATA(p) | Participant Data | SPDP(简单参与者发现协议)中广播参与者信息 |
| DATA(w) | Writer Data | SEDP(简单端点发现协议)中通告 DataWriter 端点 |
| DATA(r) | Reader Data | SEDP 中通告 DataReader 端点 |
| DATA | User Data | 传输用户层的实际业务数据 |
1.1.3.2 DATA(p)
- 是 SPDPbuiltinParticipantWriter 发的,对端由 SPDPbuiltinParticipantReader 接收。
- 每个 DDS Participant 启动后,会通过 SPDP 周期性地向预定义的多播地址发送 DATA(p) 消息
- 内容是 SPDPdiscoveredParticipantData,包含:参与者的 GUID、协议版本、Vendor ID、默认单播/多播
- Locator、租约时长(leaseDuration)等
- 其他参与者收到后就能"发现"该参与者的存在,进而触发 SEDP 阶段的端点匹配
一、 步骤:
1. 每个 Participant 上线后,周期性组播 SPDP DATA(p)
- 初始阶段: 短间隔快发 (尽快被发现)
- 之后: 长间隔慢发 (维护存在 + 供后来者发现)
- 切换依据: 时间,与匹配无关
- 持续整个生命周期,直到退出
2. 收到新的远端 DATA(p) 后:
- 单播回发自己的 DATA(p) (快速完成双向发现)
- 从对端 DATA(p) 中提取: locator + builtinEndpointSet
3. 双方互知后,无条件进入 SEDP:
- 交换各自的 DataWriter / DataReader 端点信息
- 通过 HEARTBEAT / ACKNACK / DATA 可靠传输
4. SEDP 信息收齐后,本地执行匹配 (Matching):
- Topic 名称相同?
- Type 名称兼容?
- QoS 策略兼容?(如 Reliability, Durability 等)
- 三者全部满足 → 建立 Writer↔Reader 关联
- 任一不满足 → 不关联,但 SEDP 信息仍保留
5. 匹配成功后,用户数据传输开始
二、 简单理解整个发现流程:
Participant A Participant B
|--- DATA(p) 多播广播 --------->| (SPDP: 我在这里!)
|<-------- DATA(p) 多播广播 ----| (SPDP: 我也在这里!)
|--- DATA(w) / DATA(r) ------->| (SEDP: 我有这些端点)
|<-- DATA(w) / DATA(r) --------| (SEDP: 我也有这些端点)
|====== 匹配成功,开始通信 ======| (DATA: 业务数据交换)
三、例子
组播
一上线快速发几包,然后进入周期发送
INFO_TS: Timestampt


子消息:时间戳0x09 DATA0x15
现在分析DATA的内容:
【RTPS消息头】

【子消息①】

【子消息②】





单播
【单播差距】

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)