rmw_connextdds 源码详细分析

rmw_connextdds 源码详细分析

工作区路径:/home/cp/work2/ros2Learn/ros2_humble/src/ros2/rmw_connextdds
版本:0.11.6(Humble),子包 4 个,构建类型 ament_cmake,语言 C/C++,许可证 Apache 2.0

rmw_connextdds 是 RTI 提供的 ROS 2 RMW 实现,将标准 rmw_* C API 映射到 RTI Connext DDS Professionalrmw_connextdds)或 RTI Connext DDS Micrormw_connextddsmicro)。它替代旧版 rmw_connext_cpp,在性能与跨厂商互操作方面做了大量改进。

外部依赖:本仓库 不包含 Connext DDS 本体。构建与运行需安装 RTI Connext,并通过 CONNEXTDDS_DIR / NDDSHOME(Professional)或 RTIMEHOME(Micro)指向安装路径;未检测到安装时对应包会被 跳过编译

上游 README:rmw_connextdds


1. 总体认识

1.1 核心职责

能力 说明
RMW 符号实现 导出全部 rmw_* 函数(经薄封装层)
DDS 实体管理 DomainParticipant、Publisher/Subscriber、DataWriter/DataReader
类型系统 基于 Fast-CDR + rosidl typesupport 注册 DDS 类型(Pro 用 TypePlugin/TypeCode)
Graph 发现 集成 rmw_dds_common,维护 ROS 2 图缓存
Service/Client DDS-RPC basic/extended 映射,可配置跨厂商互操作
QoS 策略 ROS QoS ↔ Connext QoS,支持 XML profile 与运行时环境变量
双后端共享 rmw_connextdds_common 承载 ~16K 行公共 C++ 逻辑

1.2 在 ROS 2 栈中的位置

上层rmw_connextdds 仓库ROS 共享RTI 产品RMW_CONNEXT_DDS_API_PRORMW_CONNEXT_DDS_API_MICROrclrmw_connextdds\n薄 API 层rmw_connextddsmicro\n薄 API 层rmw_connextdds_common\n核心实现rti_connext_dds_cmake_modulermw 头文件/类型rmw_dds_commonrosidl typesupportConnext DDS ProfessionalConnext DDS Micro
对比项 rmw_connextdds rmw_cyclonedds_cpp rmw_fastrtps_cpp
DDS 产品 RTI Connext Pro/Micro Eclipse CycloneDDS eProsima Fast-DDS
实现语言 C++ C++ C++
Graph 共享 rmw_dds_common rmw_dds_common 自有 + 部分 common
序列化 Fast-CDR typesupport 自有 CDR Fast-CDR
默认 Humble RMW 否(需显式选择) 可选

1.3 分层设计(读源码入口)

1
2
3
4
5
rmw.h 符号
└── rmw_connextdds/src/rmw_api_impl_ndds.cpp ← 仅转发,~977 行
└── rmw_api_connextdds_*() ← 参数校验 + 日志
└── RMW_Connext_* 类 / 自由函数 ← rmw_impl.hpp / rmw_impl.cpp
└── DDS C API ← dds_api_ndds.hpp 或 dds_api_rtime.hpp

Micro 版将第一层替换为 rmw_connextddsmicro/src/rmw_api_impl_rtime.cpp,链接 rmw_connextdds_common_micro 而非 _pro


2. 子包结构

1
2
3
4
5
6
7
8
9
10
11
12
rmw_connextdds/
├── rti_connext_dds_cmake_module/ # 查找 Connext 安装、env hook
├── rmw_connextdds_common/ # 共享实现 ★ (~16K 行)
│ ├── include/rmw_connextdds/ # 18 个头文件
│ └── src/
│ ├── common/ # 19 个 .cpp(RMW 逻辑)
│ ├── ndds/ # Professional 专用(TypePlugin、CFT)
│ └── rtime/ # Micro 专用 + rtime_ext.c
├── rmw_connextdds/ # Pro RMW 注册包
│ └── src/rmw_api_impl_ndds.cpp
└── rmw_connextddsmicro/ # Micro RMW 注册包
└── src/rmw_api_impl_rtime.cpp
版本 产出 职责
rti_connext_dds_cmake_module CMake 模块 rti_find_connextpro()rti_find_connextmicro()
rmw_connextdds_common 0.11.6 librmw_connextdds_common_pro / _micro 全部 RMW 逻辑(编译宏区分后端)
rmw_connextdds 0.11.6 librmw_connextdds.so 导出 rmw_*,identifier="rmw_connextdds"
rmw_connextddsmicro 0.11.6 librmw_connextddsmicro.so 同上,identifier="rmw_connextddsmicro"

2.1 依赖关系(rmw_connextdds_common/package.xml

1
2
3
4
5
6
7
8
9
rmw_connextdds_common
├── rmw # API 契约
├── rmw_dds_common # Graph 缓存、ParticipantEntitiesInfo
├── rcutils / rcpputils # 日志、错误、scope_exit
├── fastcdr # CDR 序列化
├── rosidl_runtime_c/cpp
├── rosidl_typesupport_fastrtps_c/cpp
├── rosidl_typesupport_introspection_c/cpp
└── rti_connext_dds_cmake_module

Typesupport 注册(rmw_connextdds/CMakeLists.txt):

1
2
3
register_rmw_implementation(
"c:rosidl_typesupport_fastrtps_c:rosidl_typesupport_introspection_c"
"cpp:rosidl_typesupport_fastrtps_cpp:rosidl_typesupport_introspection_cpp")

与 Cyclone/FastRTPS 后端一样,同时支持 fastrtpsintrospection 两套 typesupport。


3. 构建系统

3.1 条件编译与跳过

rmw_connextdds_common/CMakeLists.txt 通过 rti_find_connextpro() / rti_find_connextmicro() 探测安装:

  • 找到 Pro → 构建 rmw_connextdds_common_pro(链 RTIConnextDDS::c_api
  • 找到 Micro → 构建 rmw_connextdds_common_micro + 辅助库 rti_connextdds_micro_ext
  • 两者皆无 → 仅 ament_package(),不产出 RMW 库

rmw_connextdds 包额外检查 TARGET rmw_connextdds_common::rmw_connextdds_common_pro,不存在则跳过。

3.2 编译宏区分后端

Pro Micro
RMW_CONNEXT_DDS_API RMW_CONNEXT_DDS_API_PRO RMW_CONNEXT_DDS_API_MICRO
RMW_CONNEXTDDS_ID "rmw_connextdds" "rmw_connextddsmicro"
默认 RPC 映射 Extended Basic
Security 默认启用编译选项 可选 RMW_CONNEXT_ENABLE_SECURITY
大对象优化 默认开 同 common 逻辑

dds_api.hpp 根据宏 include 不同头文件:

1
2
3
4
5
#if RMW_CONNEXT_DDS_API == RMW_CONNEXT_DDS_API_MICRO
#include "rmw_connextdds/dds_api_rtime.hpp"
#elif RMW_CONNEXT_DDS_API == RMW_CONNEXT_DDS_API_PRO
#include "rmw_connextdds/dds_api_ndds.hpp"
#endif

3.3 Connext 路径变量

变量 用途
CONNEXTDDS_DIR Pro 安装路径(优先于 NDDSHOME
NDDSHOME Pro 传统变量;apt 版 rmw_connext_cpp 可能硬编码
RTIMEHOME Micro 安装路径;Pro 6.x 可自动猜测 bundled Micro

rti_connext_dds_cmake_module 还提供 env_hook/rti_connext_dds.sh.in 等脚本,在 source install/setup.bash 时注入库路径。


4. 核心数据结构

4.1 rmw_context_impl_t

context.hpp 中定义(对应 rmw/init.h 中的不透明 rmw_context_impl_t):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct rmw_context_impl_s {
rmw_dds_common::Context common; // graph 缓存、discovery pub/sub
rmw_context_t * base;

DDS_DomainParticipantFactory * factory;
DDS_DomainId_t domain_id;
DDS_DomainParticipant * participant;
DDS_Publisher * dds_pub; // ROS publisher 共用
DDS_Subscriber * dds_sub; // ROS subscription 共用

/* Built-in Discovery Readers (DCPSParticipant/Publication/Subscription) */
DDS_DataReader * dr_participants;
DDS_DataReader * dr_publications;
DDS_DataReader * dr_subscriptions;

bool localhost_only;
RMW_Connext_RequestReplyMapping request_reply_mapping;
bool cyclone_compatible;
// participant/endpoint QoS override 策略、initial_peers、类型注册表...
std::map<std::string, RMW_Connext_MessageTypeSupport *> registered_types;
size_t node_count;
std::mutex initialization_mutex;
bool is_shutdown;
};

设计要点

  • 延迟创建 Participant:第一个 rmw_create_node 时才真正创建并 enable DomainParticipant(node_count 从 0→1)。
  • 同一 context 内所有 node 必须 localhost_only 一致,否则 initialize_node 失败。
  • rmw_dds_common::Context 嵌入 graph 状态,与 Cyclone/FastRTPS 新实现路径一致。

4.2 实体实现类(rmw_impl.hpp

C++ 类 对应 rmw 句柄 DDS 实体
RMW_Connext_Node rmw_node_t 逻辑节点(无独立 Participant)
RMW_Connext_Publisher rmw_publisher_t Topic + DataWriter
RMW_Connext_Subscriber rmw_subscription_t Topic + DataReader
RMW_Connext_Service rmw_service_t 请求 Subscription + 响应 Publisher
RMW_Connext_Client rmw_client_t 请求 Publisher + 响应 Subscription
RMW_Connext_GuardCondition rmw_guard_condition_t DDS GuardCondition
RMW_Connext_StdWaitSet rmw_wait_set_t DDS WaitSet + 条件 attach 管理

每个 rmw_*_t->data 指向对应 C++ 对象;implementation_identifierRMW_CONNEXTDDS_ID

4.3 全局工厂引用

1
2
DDS_DomainParticipantFactory * RMW_Connext_gv_DomainParticipantFactory = nullptr;
size_t RMW_Connext_gv_ContextCount = 0;

首个 context init 时设置工厂 QoS(autoenable_created_entities = false);最后一个 context fini 且所有 node 销毁后重置。注释指出 context 创建非线程安全(与 rcl 层假设一致)。


5. 生命周期

5.1 rmw_init 流程(rmw_context.cpp

1
2
3
4
5
6
7
rmw_api_connextdds_init()
├── 解析环境变量(QoS override、RPC 映射、Cyclone 兼容等)
├── rmw_dds_common::Context 初始化
├── 创建/复用 DomainParticipantFactory
├── rmw_connextdds_graph_initialize() // discovery pub/sub
├── 启动 discovery 线程(DCPS + ParticipantEntitiesInfo)
└── 填充 rmw_context_t(implementation_identifier、domain_id)

rmw_shutdown / rmw_context_fini 逆序:停止 discovery 线程 → 销毁 graph 实体 → finalize participant → 递减全局计数。

5.2 Node 与 Participant 关系

与 CycloneDDS RMW 类似,多个 ROS node 共享一个 DomainParticipant(同一 rmw_context_t):

  • RMW_Connext_Node::create 仅增加 node_count 并注册 graph
  • Participant 在首个 node 创建时 initialize_participant + enable_participant
  • 最后一个 node destroy 且 count 归零时 tear down participant

6. Topic 命名与 Demangle

6.1 ROS → DDS Topic 映射

前缀常量(demangle.cpp / rmw_impl.cpp):

ROS 语义 前缀 示例
Topic rt /foort/foo
Service 请求 rq + Request 后缀 /addrq/addRequest
Service 响应 rr + Response 后缀 /addrr/addResponse

RMW_Connext_Publisher::create 中:

  • 若 topic 已含 rq/rr/ 前缀,直接使用(service 内部 topic)
  • 否则调用 rmw_connextdds_create_topic_name(ROS_TOPIC_PREFIX, topic_name, ...)

avoid_ros_namespace_conventions=true 时跳过 rt 前缀,用于直连原生 DDS topic。

6.2 Demangle(demangle.cpp

  • _demangle_if_ros_topic:去掉 rt/rq/rr/ 恢复 ROS 图名
  • _demangle_if_ros_type:将 pkg::msg::dds_::Type_ 还原为 ROS 类型名
  • 供 graph introspection、ros2 topic list 等使用

6.3 内部 Discovery Topic

rmw_graph.cpp 创建内部 publisher/subscription:

  • Topic 名:ros_discovery_infoavoid_ros_namespace_conventions=true
  • 消息类型:rmw_dds_common::msg::ParticipantEntitiesInfo
  • QoS:TRANSIENT_LOCAL + RELIABLE(pub depth=1,sub KEEP_ALL)

7. 类型支持与序列化

7.1 RMW_Connext_MessageTypeSupport

核心类(type_support.hpp),使用 Connext 代码生成器,而是:

  1. rosidl_message_type_support_tfastrtps typesupportmessage_type_support_callbacks_t
  2. 用 introspection 计算 _serialized_size_max、是否 unbounded
  3. Pro 版:构建 PRESTypePlugin + DDS TypeCode(rmw_type_support_ndds.cpp
  4. Micro 版:简化类型注册(rmw_type_support_rtime.cpp

消息类别枚举:

1
2
3
4
5
enum RMW_Connext_MessageType {
RMW_CONNEXT_MESSAGE_USERDATA, // 普通 pub/sub
RMW_CONNEXT_MESSAGE_REQUEST, // service/client 请求
RMW_CONNEXT_MESSAGE_REPLY // service/client 响应
};

Service 的 request/reply 在 CDR 前附加 RequestReply 头RMW_Connext_RequestReplyMessage:gid + sequence number),映射方式由 request_reply_mapping 控制。

7.2 序列化格式

1
2
// ndds/dds_api_ndds.cpp
const char * const RMW_CONNEXTDDS_SERIALIZATION_FORMAT = "cdr";

rmw_serialize / rmw_deserializermw_serde.cpp)临时构造 RMW_Connext_MessageTypeSupport,调用 Fast-CDR 回调写入 rmw_serialized_message_t

rmw_get_serialized_message_size 当前返回 RMW_RET_UNSUPPORTED

7.3 Professional 特有:Content Filter Topic

custom_sql_filter.cpp + rmw_connextdds_create_contentfilteredtopic 实现 Content Filtered Topic(订阅端内容过滤),对应 rmw_subscription_set_content_filter。Micro 版部分 CFT API 返回 unsupported。

7.4 大消息优化

_serialized_size_max >= 1MBRMW_CONNEXT_LARGE_DATA_MIN_SERIALIZED_SIZE)且未禁用优化时:

  • 调整 RTPS reliability 协议参数(heartbeat 周期、send window)
  • Pro 版默认 DDS_ASYNCHRONOUS_PUBLISH_MODE_QOS(可用 RMW_CONNEXT_USE_DEFAULT_PUBLISH_MODE 关闭)

8. 发布与订阅数据路径

8.1 发布

1
2
3
4
rmw_api_connextdds_publish()
→ RMW_Connext_Publisher::write(ros_message, serialized=false)
→ MessageTypeSupport::serialize() // Fast-CDR
→ DDS_DataWriter_write()

rmw_publish_serialized_message 传入已序列化 buffer,跳过 ros 消息序列化步骤。

8.2 订阅

1
2
3
4
5
rmw_api_connextdds_take() / take_with_info()
→ RMW_Connext_Subscriber::take()
→ DDS_DataReader_take()
→ deserialize → ros_message
→ 填充 rmw_message_info_t(source_timestamp、publication_handle 等)

还支持 take_serialized_messagetake_sequenceloaned message 系列 API 返回 RMW_RET_UNSUPPORTED

8.3 Graph 钩子

创建/销毁 pub/sub/service/client 时调用 graph_cache.hpp 中:

  • rmw_connextdds_graph_on_publisher_created/deleted
  • 更新 rmw_dds_common::GraphCachermw_connextdds_graph_publish_update 广播

9. Service / Client 与 RPC 映射

9.1 DDS-RPC 两种 Profile

Profile 机制 默认
Basic 请求头(GUID+SN)inline 序列化在 payload 前 Micro
Extended 使用 DDS SampleIdentity 等元数据 Pro

环境变量 RMW_CONNEXT_REQUEST_REPLY_MAPPING=basic|extended 覆盖默认。

9.2 跨 RMW 互操作

目标 配置
rmw_fastrtps_cpp Pro + extended(默认)
rmw_connextddsmicro 两侧 basic
rmw_cyclonedds_cpp RMW_CONNEXT_CYCLONE_COMPATIBILITY_MODE=y(非标准 basic 变体)

Cyclone 默认 pub/sub 可互通,但 service/client 不互通(除非开兼容模式)。

9.3 实现类方法

  • RMW_Connext_Client::send_request / take_response
  • RMW_Connext_Service::take_request / send_response
  • client_service_id 在 context 内递增,用于构造唯一 GUID 后缀

10. Graph 与 Discovery

10.1 双通道发现

ROS Graph 通道DDS Built-in 通道ParticipantEntitiesInfo\nros_discovery_informw_dds_common::GraphCacheDCPSParticipantDCPSPublicationDCPSSubscription
  1. ParticipantEntitiesInfo(与 Cyclone/FastRTPS 共用设计):节点/endpoint 增删时发布更新。
  2. Builtin topic readersdr_participants 等):监听远端 DDS 参与者与 endpoint,填充 graph。

10.2 Discovery 线程(rmw_discovery.cpp

独立线程 rmw_connextdds_discovery_thread

  • 创建 DDS_WaitSet,attach DCPS reader 的 DATA_AVAILABLE 条件
  • attach ros_discovery_info subscriber 与退出 GuardCondition
  • 循环 DDS_WaitSet_wait,分发到 graph_cache 更新函数
  • context shutdown 时 trigger exit guard,join 线程

10.3 Graph API

rmw_info.cpprmw_graph.cpp 实现:

  • rmw_get_node_names / with_enclaves
  • rmw_get_topic_names_and_types
  • rmw_get_publishers_info_by_topic

底层读取 ctx->common.graph_cachermw_dds_common),demangle topic/type 名后返回。


11. Wait Set 实现

11.1 RMW_Connext_StdWaitSetrmw_waitset_std.hpp + rmw_impl_waitset_std.cpp

rmw_wait 流程:

  1. 遍历 rmw_subscriptions_t 等数组,将每个有效 RMW_Connext_SubscriberStatusConditionReadCondition attach 到 WaitSet
  2. Service/Client 的 request/response reader 同理
  3. GuardCondition、Event 条件一并 attach
  4. DDS_WaitSet_wait(wait_timeout)
  5. 未触发的条目在数组中置 NULL(符合 rmw 契约)

11.2 事件与 Listener

QoS 事件(rmw_event.cpp)通过 RMW_Connext_SubscriberStatusCondition / PublisherStatusCondition 映射 DDS status:

rmw_event_type DDS Status
RMW_EVENT_REQUESTED_QOS_INCOMPATIBLE REQUESTED_INCOMPATIBLE_QOS_STATUS
RMW_EVENT_LIVELINESS_CHANGED LIVELINESS_CHANGED_STATUS
RMW_EVENT_MESSAGE_LOST SAMPLE_LOST_STATUS(若支持)

DataReader listener 回调更新 condition 计数,供 rmw_take_event 读取。


12. QoS 处理

12.1 默认 XML Profile

编译期默认 QoS 库名:RMW_CONNEXT_DEFAULT_QOS_LIBRARY = "ros2"static_config.hpp)。

rmw_connextdds_get_datawriter_qos / get_datareader_qosdds_api_*.cpp):

  1. 从 Connext QoS Profile 加载 topic 默认值(支持 topic filter)
  2. 根据 endpoint_qos_override_policy 决定是否叠加 ROS rmw_qos_profile_t
  3. 应用大消息优化、异步 publish 等 RMW 策略

12.2 Override 策略

环境变量 行为
RMW_CONNEXT_PARTICIPANT_QOS_OVERRIDE_POLICY all / basic / never 控制 Participant QoS 修改幅度
RMW_CONNEXT_ENDPOINT_QOS_OVERRIDE_POLICY always / never / dds_topics: <regex> 控制 DataWriter/Reader QoS

rmw_api_connextdds_qos_profile_check_compatible 直接委托 rmw_dds_common::qos_profile_check_compatiblermw_qos.cpp)。


13. 运行时环境变量

(详见仓库 README.md,此处汇总与源码对应关系)

环境变量 作用
RMW_IMPLEMENTATION 选择 rmw_connextddsrmw_connextddsmicro
RMW_CONNEXT_CYCLONE_COMPATIBILITY_MODE Service 与 Cyclone 互操作
RMW_CONNEXT_REQUEST_REPLY_MAPPING basic / extended
RMW_CONNEXT_LEGACY_RMW_COMPATIBILITY_MODE 与旧 rmw_connext_cpp 类型名兼容(_ 后缀)
RMW_CONNEXT_DISABLE_LARGE_DATA_OPTIMIZATIONS 关闭 ≥1MB 类型自动调优
RMW_CONNEXT_DISABLE_FAST_ENDPOINT_DISCOVERY 关闭 Fast endpoint discovery snippet
RMW_CONNEXT_USE_DEFAULT_PUBLISH_MODE 不强制异步 publish(Pro)
RMW_CONNEXT_INITIAL_PEERS 覆盖 discovery initial_peers(Micro 常用)
RMW_CONNEXT_UDP_INTERFACE Micro UDP 网卡(默认 lo
RMW_CONNEXT_ENDPOINT_QOS_OVERRIDE_POLICY Endpoint QoS 覆盖策略
RMW_CONNEXT_PARTICIPANT_QOS_OVERRIDE_POLICY Participant QoS 覆盖策略

14. 模块与源文件对照

14.1 src/common/(双后端共享)

文件 职责
rmw_context.cpp init/shutdown、Participant 生命周期、环境变量解析
rmw_impl.cpp Publisher/Subscriber/Client/Service 类实现、topic 创建
rmw_publication.cpp rmw_publish* API 层
rmw_subscription.cpp rmw_create_subscriptionrmw_take*
rmw_service.cpp Service/Client CRUD 与 request/response
rmw_waitset.cpp guard condition、waitset CRUD API
rmw_impl_waitset_std.cpp WaitSet attach/wait 核心逻辑
rmw_graph.cpp Graph 初始化、DCPS 回调、entity 增删
rmw_discovery.cpp Discovery 后台线程
rmw_info.cpp Graph introspection API
rmw_event.cpp QoS 事件 init/take/callback
rmw_listener.cpp DataReader/DataWriter listener 桥接
rmw_qos.cpp QoS 兼容性检查(委托 dds_common)
rmw_serde.cpp serialize/deserialize
rmw_type_support.cpp 类型注册公共逻辑
demangle.cpp Topic/类型 demangle
rmw_security_log.cpp SROS2 安全日志转发
rmw_network_flow_endpoints.cpp 未实现(返回 UNSUPPORTED)

14.2 src/ndds/(Professional)

文件 职责
dds_api_ndds.cpp Pro 专用 QoS、Participant 配置、CFT
rmw_type_support_ndds.cpp PRESTypePlugin、TypeCode、样本池
rmw_typecode.cpp TypeCode 构建与缓存
custom_sql_filter.cpp Content Filter SQL 表达式

14.3 src/rtime/(Micro)

文件 职责
dds_api_rtime.cpp Micro Participant/Transport 配置
rmw_type_support_rtime.cpp 简化类型注册
rtime_ext.c Micro API 扩展 shim

15. 尚未实现或受限的功能

通过 RMW_CONNEXT_LOG_NOT_IMPLEMENTED / RMW_RET_UNSUPPORTED 标记:

API / 能力 状态
rmw_borrow_loaned_message / rmw_take_loaned_message* 不支持
rmw_publish_loaned_message 不支持
rmw_*_allocation(pub/sub 预分配) 不支持
rmw_get_serialized_message_size 不支持
rmw_publisher_wait_for_all_acked 需查具体版本(部分 stub)
rmw_publisher_get_network_flow_endpoints 不支持
Strict unique network flow endpoints 创建 subscription 时拒绝
Micro 部分 Security / Extended RPC 受限

查阅具体 API 时可在 rmw_connextdds_common/src/common/ 内 grep NOT_IMPLEMENTED


16. Pro vs Micro 差异摘要

维度 rmw_connextdds (Pro) rmw_connextddsmicro
RTI 产品 Connext DDS Professional 5.3.1+ / 6.x Connext DDS Micro 3.x+
类型插件 完整 PRESTypePlugin + TypeObject 轻量注册
默认 RPC Extended(SampleIdentity) Basic(inline header)
Publish 模式 默认异步 不强制覆盖
UDP 接口 自动 默认 lo,需 RMW_CONNEXT_UDP_INTERFACE
Content Filter 支持(SQL) 有限/不支持
互操作 Fast-DDS extended RPC 与 Pro basic 模式互通

17. 与 rmw_dds_common 的协作

本实现 重度依赖 rmw_dds_common(参见 rmw_dds_common 源码详细分析):

rmw_dds_common 组件 在 Connext RMW 中的用法
rmw_dds_common::Context 嵌入 rmw_context_impl_t::common
GraphCache 存储节点/endpoint 图
ParticipantEntitiesInfo discovery topic 消息类型
qos_profile_check_compatible QoS 兼容性 API
security.hpp init 时安全配置

Connext 特有逻辑主要在 DDS API 层(QoS snippet、TypePlugin)和 discovery 线程,graph 语义与 Cyclone 后端对齐。


18. 调试建议

  1. 确认 RMW 已加载rmw_get_implementation_identifier()"rmw_connextdds""rmw_connextddsmicro"
  2. Connext 日志rmw_set_log_severity → 内部 rmw_connextdds_set_log_verbosity;Debug 构建定义 RMW_CONNEXT_DEBUG=1
  3. Graph 问题:检查 ros_discovery_info 是否有数据;对比 DCPS built-in reader 是否触发。
  4. QoS 不匹配:开 RMW_CONNEXT_ENDPOINT_QOS_OVERRIDE_POLICY=never 排查是否 RMW 覆盖导致。
  5. 跨机通信(Micro):必设 RMW_CONNEXT_UDP_INTERFACERMW_CONNEXT_INITIAL_PEERS
  6. Service 不通:核对 RPC mapping 与对端 RMW 是否匹配(见第 9.2 节)。

19. 推荐阅读顺序

  1. rmw_connextdds/src/rmw_api_impl_ndds.cpp — 全部 RMW 入口一览
  2. include/rmw_connextdds/context.hpp — context 状态机
  3. src/common/rmw_context.cpp — init/participant 流程
  4. include/rmw_connextdds/rmw_impl.hpp — 实体类接口
  5. src/common/rmw_impl.cpp — Publisher/Subscriber 创建与 topic 映射
  6. src/common/rmw_graph.cpp + rmw_discovery.cpp — Graph 双通道
  7. include/rmw_connextdds/type_support.hpp + src/ndds/rmw_type_support_ndds.cpp — 类型与 CDR
  8. src/common/rmw_impl_waitset_std.cpprmw_wait 行为
  9. include/rmw_connextdds/static_config.hpp — 编译期常量与环境变量名
  10. rti_connext_dds_cmake_module/cmake/rti_build_helper.cmake — 构建探测逻辑

20. 小结

rmw_connextdds 仓库采用 「薄 RMW 注册层 + 厚 common 库 + 双 DDS 后端适配」 架构:

  • 对上:完整实现 Humble rmw.h 契约(除 loaned message 等可选特性);
  • 对下:封装 RTI Connext Pro/Micro C API,Pro 版使用 TypePlugin 深度集成;
  • 横向:通过 rmw_dds_common 与 Cyclone/FastRTPS 共享 ROS Graph 协议;
  • 互操作:Pub/Sub 默认可跨厂商;Service 需按 RPC profile 与环境变量配置。

替换旧 rmw_connext_cpp 时需注意 类型 discovery 后缀RPC 映射 差异;生产环境应显式固定 RMW_IMPLEMENTATION 与相关 RMW_CONNEXT_* 环境变量。

文章互动

阅读 --

留言

0 条留言

正在加载留言…