Fast-DDS 源码详细分析
工作区路径:/home/cp/work2/ros2Learn/ros2_humble/src/eProsima/Fast-DDS
版本:2.6.11(CMakeLists.txt / package.xml),CMake 工程名 fastrtps(历史命名),语言 C++11+,许可证 Apache 2.0。
eProsima Fast-DDS(原 Fast RTPS)是 OMG DDS 规范的 C++ 实现,底层协议为 RTPS(Real-Time Publish-Subscribe)。在 ROS 2 Humble 中,它是默认 RMW 实现 rmw_fastrtps_cpp 所依赖的中间件;所有 ros2 topic pub/echo、节点间通信最终都经由 Fast-DDS 的 RTPS 栈在网络上收发数据。
1. 总体认识
1.1 核心职责
| 能力 | 说明 |
|---|---|
| DDS API | Participant / Publisher / Subscriber / DataWriter / DataReader / Topic / QoS |
| RTPS 协议栈 | SPDP/SEDP 发现、Reader/Writer 状态机、Heartbeat/AckNack/Gap/Data 子消息 |
| 传输层 | UDP、TCP(可选 TLS)、共享内存(SHM)、链式传输 |
| 序列化 | 依赖 Fast-CDR 做 CDR payload 编码 |
| XTypes | 动态类型、TypeLookup、TypeObject |
| 安全(可选) | DDS Security:PKI-DH 认证、Permissions、AES-GCM-GMAC 加密 |
| 零拷贝 | DataSharing(进程内共享内存 payload pool) |
1.2 在 ROS 2 栈中的位置
| 组件 | 关系 |
|---|---|
| Fast-CDR | 序列化引擎(见 Fast-CDR 源码详细分析) |
| foonathan_memory | 自定义内存分配器,减少 RTPS 热路径堆分配 |
| rmw_fastrtps_shared_cpp | 封装 DomainParticipant、DataWriter、DataReader |
| rosidl_typesupport_fastrtps | 为每个 msg 生成 TopicDataType + CDR serialize/deserialize |
ROS 2 中 Publisher/Subscription 对应 DDS 的 DataWriter/DataReader,而非 DDS Publisher/Subscriber。RMW 为每个 Participant 创建一个 DDS Publisher 和一个 DDS Subscriber 作为容器。
2. 三层 API 架构
Fast-DDS 在同一个 libfastrtps 库中并存三套 API:
| 层级 | 命名空间 | 头文件路径 | 实现目录 | 状态 |
|---|---|---|---|---|
| 现代 DDS API | eprosima::fastdds::dds |
include/fastdds/dds/ |
src/cpp/fastdds/ |
主路径 / ROS 2 使用 |
| RTPS 直连 API | eprosima::fastrtps::rtps |
include/fastdds/rtps/ |
src/cpp/rtps/ |
底层协议访问 |
| Legacy Fast RTPS | eprosima::fastrtps |
include/fastrtps/ |
src/cpp/fastrtps_deprecated/ |
已弃用 |
| OMG PSM 包装 | dds:: |
include/dds/ |
src/cpp/dds/ |
ISO C++ DDS 薄封装 |
CMake 工程名仍为 fastrtps,ROS package 名也是 fastrtps,与产品名 Fast-DDS 并存——这是历史兼容设计。
2.1 分层调用关系
3. 目录结构
1 | Fast-DDS/ |
3.1 src/cpp/rtps/ 子模块
| 子目录 | 文件数 | 职责 |
|---|---|---|
builtin/ |
60 | PDP/EDP 发现、WLP、Discovery Server 数据库 |
transport/ |
55 | UDP/TCP/SHM 传输实现 |
history/ |
25 | CacheChange、Reader/Writer History、Payload Pool |
messages/ |
12 | RTPS 报文组装/解析、子消息 |
DataSharing/ |
11 | 进程内零拷贝共享内存 |
reader/ / writer/ |
各 10 | Stateful/Stateless Reader/Writer |
participant/ |
— | RTPSParticipantImpl |
security/ |
— | SecurityManager 框架 |
network/ |
— | NetworkFactory、收发资源 |
persistence/ |
— | SQLite3 持久化 Writer/Reader |
4. DDS 层 — 现代 API
路径:include/fastdds/dds/、src/cpp/fastdds/
4.1 核心实体
| 实体 | 公开头文件 | 实现 |
|---|---|---|
| DomainParticipantFactory | dds/domain/DomainParticipantFactory.hpp |
domain/DomainParticipantFactory.cpp |
| DomainParticipant | dds/domain/DomainParticipant.hpp |
domain/DomainParticipant.cpp + DomainParticipantImpl.cpp |
| Publisher | dds/publisher/Publisher.hpp |
publisher/PublisherImpl.cpp |
| DataWriter | dds/publisher/DataWriter.hpp |
publisher/DataWriterImpl.cpp + DataWriterHistory.cpp |
| Subscriber | dds/subscriber/Subscriber.hpp |
subscriber/SubscriberImpl.cpp |
| DataReader | dds/subscriber/DataReader.hpp |
subscriber/DataReaderImpl.cpp + history/DataReaderHistory.cpp |
| Topic | dds/topic/Topic.hpp |
topic/TopicImpl.cpp |
| TypeSupport | dds/topic/TypeSupport.hpp |
topic/TypeSupport.cpp |
设计模式:公开类(Entity 子类)+ Impl 类。公开类仅转发调用,Impl 持有 RTPS 对象和业务逻辑。
4.2 Participant 启用流程
DomainParticipantImpl::enable() 是 DDS 与 RTPS 的衔接点:
1 | ReturnCode_t DomainParticipantImpl::enable() |
流程概要:
- 从
DomainParticipantQos映射出RTPSParticipantAttributes - 调用
RTPSDomain::createParticipant()创建底层 RTPS 参与者 - 若
autoenable_created_entities,依次 enable 已创建的 Topic/Publisher/Subscriber - 调用
rtps_participant_->enable()启动发现与传输
4.3 DataWriter 写数据路径
1 | bool DataWriterImpl::write( |
完整链路:
1 | DataWriter::write(data) |
4.4 DataReader 读数据路径
1 | Transport 接收 UDP/SHM 报文 |
4.5 其他 DDS 能力
| 模块 | 路径 | 说明 |
|---|---|---|
| ContentFilteredTopic | topic/ContentFilteredTopic*.cpp |
内容过滤主题 |
| DDSSQLFilter | topic/DDSSQLFilter/ |
SQL-like 过滤表达式解析(pegtl) |
| TypeLookup | fastdds/builtin/typelookup/ |
XTypes 远程类型查询 |
| WaitSet / Condition | fastdds/core/condition/ |
同步等待机制 |
| Log | fastdds/log/ |
可配置日志消费者 |
5. RTPS 层 — 协议核心
路径:include/fastdds/rtps/、src/cpp/rtps/
5.1 RTPSParticipant
| 组件 | 路径 |
|---|---|
| 公开 API | include/fastdds/rtps/participant/RTPSParticipant.h |
| 实现 | src/cpp/rtps/participant/RTPSParticipantImpl.cpp/.h |
| 工厂 | include/fastdds/rtps/RTPSDomain.h → src/cpp/rtps/RTPSDomain.cpp |
RTPSParticipantImpl 是 RTPS 层的中心对象,持有:
BuiltinProtocols— 发现与存活NetworkFactory— 传输注册与 locator 选择MessageReceiver— 入站报文分发SecurityManager(可选)— 安全插件编排- Reader/Writer 集合
5.2 发现协议(BuiltinProtocols)
路径:src/cpp/rtps/builtin/BuiltinProtocols.cpp
1 | bool BuiltinProtocols::initBuiltinProtocols( |
PDP — Participant Discovery Protocol
| 模式 | 类 | 用途 |
|---|---|---|
| SIMPLE | PDPSimple |
默认:Multicast SPDP + 单播互发现 |
| CLIENT | PDPClient |
Discovery Server 客户端 |
| SERVER | PDPServer |
Discovery Server 服务端 |
| SUPER_CLIENT | PDPClient(..., true) |
超级客户端 |
| BACKUP | PDPServer(..., TRANSIENT) |
持久化 Discovery Server(需 SQLite3) |
SPDP 通过内置 Writer/Reader 交换 ParticipantProxyData(GUID、locator、UserData 等)。
EDP — Endpoint Discovery Protocol
| 实现 | 路径 | 说明 |
|---|---|---|
| EDPSimple | rtps/builtin/discovery/endpoint/EDPSimple.cpp |
动态端点发现(默认) |
| EDPStatic | EDPStatic.cpp |
静态端点配置(XML) |
| EDPClient/Server | 配合 Discovery Server | 中心化端点信息 |
EDP 在发现远端 Writer/Reader 的 WriterProxyData/ReaderProxyData 后,按 Topic 名 + QoS 兼容性做匹配,调用 matched_writer_add / matched_reader_add 建立通信关系:
1 | publications_reader_.first->matched_writer_add(*temp_writer_proxy_data); |
WLP — Writer Liveliness Protocol
管理 DataWriter 存活断言(Automatic / Manual-by-Participant / Manual-by-Topic),超时后通知 DataReader。
5.3 Reader / Writer 类型
| 类型 | 可靠性 | 典型场景 |
|---|---|---|
| StatelessWriter | Best-Effort | 不需 ACK 的发送 |
| StatefulWriter | Reliable | 需 Heartbeat/AckNack 确认 |
| StatelessReader | Best-Effort | 接收 BE 数据 |
| StatefulReader | Reliable | 接收 REL 数据,回复 AckNack |
StatefulWriter(~2100 行)维护 ReaderProxy 列表,负责:
- 向每个 matched reader 发送 Heartbeat
- 处理 AckNack,重传丢失的 CacheChange
- 发送 Gap 通知不可用序列号
- 与 FlowController 协作限流
5.4 History 与 CacheChange
路径:include/fastdds/rtps/common/CacheChange.h、src/cpp/rtps/history/
1 | CacheChange |
5.5 报文处理
| 组件 | 路径 | 职责 |
|---|---|---|
| MessageReceiver | rtps/messages/MessageReceiver.cpp (~1500 行) |
解析入站 RTPS 报文,分发 Data/Heartbeat/AckNack/Gap 子消息 |
| RTPSMessageGroup | RTPSMessageGroup.cpp |
组装出站 RTPS 报文 |
| RTPSMessageCreator | RTPSMessageCreator.cpp |
创建 RTPS 报文头 |
| 子消息模板 | messages/submessages/ |
DataMsg、HeartbeatMsg、AckNackMsg、GapMsg |
MessageReceiver 构造时根据是否启用安全选择不同的处理函数:
1 | MessageReceiver::MessageReceiver( |
6. 传输层
路径:src/cpp/rtps/transport/、include/fastdds/rtps/transport/
NetworkFactory(rtps/network/NetworkFactory.cpp)根据 RTPSParticipantAttributes 注册传输、选择 locator、创建收发资源。
| 传输 | Descriptor 头文件 | 实现 |
|---|---|---|
| UDPv4/v6 | UDPv4TransportDescriptor.h |
UDPv4Transport.cpp、UDPTransportInterface.cpp |
| TCPv4/v6 | TCPv4TransportDescriptor.h |
TCPv4Transport.cpp、TCPTransportInterface.cpp |
| TLS | — | TCPChannelResourceSecure.cpp(SECURITY + OpenSSL) |
| Shared Memory | shared_mem/SharedMemTransportDescriptor.h |
shared_mem/SharedMemTransport.cpp |
| Chaining | ChainingTransportDescriptor.h |
包装其他传输,做过滤/统计 |
6.1 默认传输配置
ROS 2 Humble 中 RMW 默认配置 UDP + SHM:
- UDP:跨进程/跨主机通信
- SHM:同主机进程间高效通信(
SHM_TRANSPORT_DEFAULT=ON)
SHM 实现基于 MultiProducerConsumerRingBuffer 无锁环形缓冲区。
6.2 DataSharing(零拷贝)
路径:src/cpp/rtps/DataSharing/
与 SHM 传输不同,DataSharing 是 payload 级别的共享内存池:
- Writer 将 serialized payload 写入共享 segment
- Reader 直接读取,避免 memcpy
- 适用于同进程或配置了 DataSharing 的 Writer/Reader 对
7. 序列化与类型系统
7.1 Fast-CDR 集成
- DDS 层通过
TopicDataType接口定义serialize()/deserialize()/getSerializedSizeProvider() - ROS 2 的
rosidl_typesupport_fastrtps_cpp生成这些方法的实现,内部使用eprosima::fastcdr::Cdr - RTPS 层只处理
SerializedPayload_t(原始字节 + length)
7.2 动态类型(XTypes)
路径:src/cpp/dynamic-types/、include/fastrtps/types/
| 类 | 说明 |
|---|---|
DynamicTypeBuilderFactory |
运行时构建类型 |
DynamicData |
运行时数据实例 |
DynamicPubSubType |
动态类型的 TopicDataType |
TypeObjectFactory |
TypeObject 注册与查询 |
TypeLookupManager |
远程类型发现服务 |
8. 安全模块(可选)
构建选项:option(SECURITY "Activate security" OFF),需 OpenSSL。
8.1 两层结构
RTPS 框架(
src/cpp/rtps/security/)SecurityManager.cpp(~4300 行)— 编排认证、授权、加密- 插件接口:
Authentication.h、AccessControl.h、Cryptography.h
内置插件(
src/cpp/security/)
| 子模块 | 实现 | 功能 |
|---|---|---|
authentication/ |
PKIDH.cpp |
PKI-DH 参与者认证 |
accesscontrol/ |
Permissions.cpp |
Governance/Permissions XML 解析与校验 |
cryptography/ |
AESGCMGMAC*.cpp |
AES-GCM 加密 + GMAC 完整性 |
artifact_providers/ |
FileProvider.cpp |
证书/密钥文件加载 |
ROS 2 安全启用时,RMW 通过 rmw_dds_common 配置 Security 属性,Fast-DDS 加载对应插件。
9. 其他模块
9.1 Statistics(可选)
option(FASTDDS_STATISTICS "Enable Fast DDS Statistics Module" OFF)
路径:src/cpp/statistics/
提供 DDS 级统计 topic(如网络流量、延迟、丢包),通过 hook RTPS 层 StatisticsBase 收集数据。
9.2 持久化
option(SQLITE3_SUPPORT "Activate SQLITE3 support" ON)
路径:src/cpp/rtps/persistence/
SQLite3PersistenceService— 将 Writer/Reader 历史持久化到 SQLite- 用于 TRANSIENT/PERSISTENT durability 和 Discovery Server BACKUP 模式
9.3 XML 配置
路径:src/cpp/rtps/xmlparser/
XMLProfileManager— 加载DEFAULT_FASTRTPS_PROFILES.xml等配置文件- 可覆盖 Participant/Writer/Reader 的 QoS 和传输设置
- ROS 2 可通过
FASTRTPS_DEFAULT_PROFILES_FILE环境变量指定
9.4 工具
| 工具 | 路径 | 说明 |
|---|---|---|
| fastdds | tools/fastdds/ |
Python CLI:discovery、shm clean 等 |
| fast-discovery-server | tools/fds/ |
Discovery Server 独立进程 |
10. 构建与依赖
10.1 产物
| 项 | 值 |
|---|---|
| CMake target | fastrtps |
| 库文件 | libfastrtps.so |
| 版本 | 2.6.11 |
10.2 依赖
| 依赖 | 用途 |
|---|---|
| fastcdr | CDR 序列化 |
| foonathan_memory | 内存分配器 |
| Asio(bundled) | 异步 I/O(TCP/UDP) |
| TinyXML2(bundled) | XML 配置解析 |
| OpenSSL(可选) | SECURITY / TLS |
| SQLite3(可选,默认 ON) | 持久化 |
10.3 重要 CMake 选项
| 选项 | 默认 | 说明 |
|---|---|---|
SECURITY |
OFF | DDS Security 插件 |
SHM_TRANSPORT_DEFAULT |
ON | 默认传输含 SHM |
SQLITE3_SUPPORT |
ON | SQLite 持久化 |
FASTDDS_STATISTICS |
OFF | 统计模块 |
COMPILE_TOOLS |
ON | 构建 fastdds CLI |
BUILD_SHARED_LIBS |
ON | 动态库 |
STRICT_REALTIME |
OFF | 实时 API 行为 |
10.4 ROS / colcon 集成
1 | <!-- package.xml --> |
colcon.pkg 声明依赖:fastcdr、FOONATHAN_MEMORY、foonathan_memory_vendor。
11. ROS 2 RMW 集成
路径:ros2_humble/src/ros2/rmw_fastrtps/rmw_fastrtps_shared_cpp/
11.1 核心包装结构
1 | typedef struct CustomParticipantInfo |
| RMW 结构 | 封装的 Fast-DDS 类型 |
|---|---|
CustomParticipantInfo |
DomainParticipant + 容器 Publisher/Subscriber |
CustomPublisherInfo |
DataWriter + TypeSupport + Listener |
CustomSubscriberInfo |
DataReader + Listener + ContentFilteredTopic |
11.2 Participant 创建
rmw_fastrtps_shared_cpp/src/participant.cpp:
- 构造
DomainParticipantQos(含 enclave、security 属性) - 注册 UDPv4 + SharedMem 传输 descriptor
DomainParticipantFactory::create_participant(domain_id, qos, listener)- 创建容器
Publisher和Subscriber ParticipantListener监听on_participant_discovery更新 ROS graph
11.3 发布 / 订阅
| RMW 操作 | Fast-DDS 调用 |
|---|---|
rmw_publish |
CustomPublisherInfo::data_writer_->write(data) |
rmw_take |
CustomSubscriberInfo::data_reader_->take(...) |
| QoS 映射 | rmw_fastrtps_shared_cpp/qos.cpp ↔ DataWriterQos/DataReaderQos |
| 类型支持 | TypeSupport.hpp 桥接 rosidl → TopicDataType |
11.4 完整 ROS 2 通信链路
1 | rclcpp::Publisher::publish(msg) |
12. 测试
1 | test/ |
核心 API 覆盖:test/unittest/rtps/、test/blackbox/。
13. 设计特点小结
| 特点 | 说明 |
|---|---|
| 双 API 共存 | 现代 fastdds::dds + Legacy fastrtps + 底层 rtps |
| Impl 模式 | 所有 DDS Entity 均有对应 *Impl 类 |
| RTPS 为核心 | DDS 层是 RTPS 的薄封装;~50% 代码在 rtps/ |
| 插件化安全 | Authentication/AccessControl/Cryptography 可替换 |
| 多传输并存 | 同一 Participant 可同时使用 UDP + SHM + TCP |
| Discovery 可扩展 | Simple / Client-Server / Static EDP |
| 内存优化 | foonathan_memory + CacheChangePool + PayloadPool + DataSharing |
| ROS 2 QL1 | 声明 Quality Level 1(见 QUALITY.md) |
14. 与 Fast-CDR 的分工
| 层次 | 库 | 职责 |
|---|---|---|
| 应用语义 | Fast-DDS DDS API | Topic、QoS、匹配、History |
| Wire 协议 | Fast-DDS RTPS | 发现、可靠传输、子消息 |
| Payload 编码 | Fast-CDR | CDR serialize/deserialize |
Fast-DDS 不做序列化,只搬运 SerializedPayload_t;类型编码全部由 Fast-CDR + 生成的 TopicDataType 完成。
15. 推荐阅读顺序
- DDS 入口:
DomainParticipantImpl::enable()— 理解 DDS→RTPS 衔接 - 发现机制:
BuiltinProtocols::initBuiltinProtocols()→PDPSimple→EDPSimple - 发送路径:
DataWriterImpl::write()→StatefulWriter→RTPSMessageGroup - 接收路径:
MessageReceiver→StatefulReader→DataReaderImpl - 传输选择:
NetworkFactory+UDPv4Transport/SharedMemTransport - ROS 2 集成:
rmw_fastrtps_shared_cpp/src/participant.cpp+custom_participant_info.hpp - 序列化:
rosidl_typesupport_fastrtps_cpp生成代码 + Fast-CDR 分析 - 配置:
DEFAULT_FASTRTPS_PROFILES.xml+XMLProfileManager
16. API 速查
16.1 最小 DDS 发布示例
1 |
|
16.2 关键类一览
| 类 | 命名空间 | 层级 |
|---|---|---|
DomainParticipant |
fastdds::dds |
DDS |
DataWriter / DataReader |
fastdds::dds |
DDS |
RTPSParticipant |
fastrtps::rtps |
RTPS |
StatefulWriter / StatefulReader |
fastrtps::rtps |
RTPS |
PDPSimple / EDPSimple |
fastrtps::rtps |
发现 |
NetworkFactory |
fastrtps::rtps |
传输 |
MessageReceiver |
fastrtps::rtps |
报文 |
CacheChange |
fastrtps::rtps |
历史 |
SecurityManager |
fastrtps::rtps |
安全 |
文档基于 ROS 2 Humble 工作区中的 Fast-DDS 2.6.11 源码分析生成。
正在加载留言…