rmw 源码详细分析

rmw 源码详细分析

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

rmw(ROS Middleware Interface)是 ROS 2 中间件抽象层:在 RCL 与具体 DDS 实现之间定义统一的 C API 契约rcl / rclcpp / rclpy 只依赖 rmw.h 中的符号名,运行时通过 rmw_implementation 代理库链接到 rmw_cyclonedds_cpprmw_fastrtps_cpp 等后端。

本仓库的关键定位rmw 包提供 头文件 API 声明 + 与实现无关的公共工具实现(校验、QoS 字符串、init 零初始化、graph 辅助结构体等)。rmw_create_publisherrmw_waitrmw_init核心中间件操作在本仓库仅声明,实现在各 rmw_*_cpp 包中

设计文档参考:ROS Middleware Interface


1. 总体认识

1.1 核心职责

能力 说明
API 契约 rmw.h 及 50+ 头文件定义 init/node/pub/sub/service/client/wait/graph 等全部 C 接口
公共类型 rmw_*_t 句柄、QoS 枚举/结构、GID、message_info、wait 容器
共享实现 20 个 .c 源文件:命名校验、QoS 字符串、init_options 默认值、topic_endpoint_info 等
构建辅助 rmw_implementation_cmake 提供 CMake 宏,选择/枚举 RMW 实现
实现注册 register_rmw_implementation() 向 ament index 注册 typesupport 资源

1.2 在 ROS 2 栈中的位置

语言客户端RCL 层rmw 仓库独立仓库 - 实际 DDS 调用DDS 厂商rclcpprclpyrclrmw 包\n(API + 公共工具)rmw_implementation_cmakermw_implementation\n符号转发代理rmw_cyclonedds_cpprmw_fastrtps_cpprmw_connextddsrmw_dds_commonCycloneDDSFast-DDSConnext
层级 职责边界
rcl ROS 语义:namespace 展开、remap、timer、wait_set 组装、参数 CLI
rmw(本仓库) 中间件无关的类型与 API 签名;部分校验/工具函数
rmw_implementation 编译期链接所选后端;运行时 dlopen 或直接链接
rmw_*_cpp rmw_* 映射到 DDS Participant/DataWriter/DataReader 等

1.3 API 声明 vs 实现分离

这是阅读 rmw 源码时最容易混淆的一点:

类别 位置 示例
仅声明(实现在后端) include/rmw/rmw.hinit.hinit_options.hevent.h rmw_initrmw_create_publisherrmw_waitrmw_take
本仓库实现 src/*.c(20 文件) rmw_validate_full_topic_namermw_qos_reliability_policy_to_strrmw_get_zero_initialized_init_options
头文件 + 零/辅助实现 types.h + src/types.c rmw_get_zero_initialized_message_info

CMakeLists.txtadd_library(rmw ...) 只编译 20 个 .c 文件,不包含任何 DDS 调用。链接 librmw.so 的应用若直接调用 rmw_init 会得到 undefined symbol,必须通过 rmw_implementation 或具体后端包提供实现。


2. 子包结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
rmw/
├── rmw/ # 核心 API 包 ★
│ ├── include/rmw/ # 51 个头文件
│ │ ├── rmw.h # 主 API(~3214 行)
│ │ ├── types.h # 核心句柄与 QoS 类型
│ │ ├── init.h / init_options.h # 生命周期
│ │ ├── get_*.h # Graph introspection
│ │ ├── events_statuses/ # QoS/存活事件状态结构
│ │ └── impl/cpp/ # C++ 辅助(demangle 等)
│ ├── src/ # 20 个 .c(~10K 行含注释)
│ └── cmake/ # configure_rmw_library、register_rmw_implementation
└── rmw_implementation_cmake/ # CMake 宏包
└── cmake/
├── get_available_rmw_implementations.cmake
└── get_default_rmw_implementation.cmake
版本 职责
rmw 6.1.2 API 头文件 + 公共 C 工具库
rmw_implementation_cmake 构建时枚举/选择 RMW 实现

2.1 依赖关系(rmw/package.xml

1
2
3
rmw
├── rcutils # 错误链、分配器、日志级别映射、字符校验
└── rosidl_runtime_c # typesupport 相关类型(build_export)

运行时 依赖任何 DDS 库;DDS 依赖在各 rmw_*_cpp 包中。


3. 句柄设计模式

几乎所有 RMW 实体采用相同的 type-erased handle 模式:

1
2
3
4
5
6
7
typedef struct rmw_publisher_s {
const char * implementation_identifier; // 如 "rmw_cyclonedds_cpp"
void * data; // 后端私有结构指针
const char * topic_name; // ROS 图可见名
rmw_publisher_options_t options;
bool can_loan_messages;
} rmw_publisher_t;
字段 作用
implementation_identifier 防止混用不同后端的句柄;不匹配时返回 RMW_RET_INCORRECT_RMW_IMPLEMENTATION
data 指向后端内部对象(如 CycloneDDS 的 dds_entity_t 封装)
其余字段 ROS/RMW 层可见的元数据,由创建函数填充

同类结构:rmw_node_trmw_subscription_trmw_service_trmw_client_trmw_guard_condition_trmw_wait_set_trmw_event_t

3.1 分配器辅助(src/allocators.c

后端实现创建实体时可复用本仓库提供的 句柄内存分配

  • rmw_node_allocate() / rmw_node_free()
  • rmw_publisher_allocate() / rmw_publisher_free()
  • 以及 subscription、service、client、guard_condition、wait_set 的对称函数

底层使用 rcutils 默认分配器,保证各实现一致的句柄布局。


4. 生命周期:init / context / shutdown

4.1 核心类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// init_options.h — 传入 rmw_init() 的配置
typedef struct rmw_init_options_s {
uint64_t instance_id;
const char * implementation_identifier;
size_t domain_id; // RMW_DEFAULT_DOMAIN_ID = 0
rmw_security_options_t security_options;
rmw_localhost_only_t localhost_only;
char * enclave; // SROS2 密钥库路径名
rmw_init_options_impl_t * impl; // 后端私有
rcutils_allocator_t allocator;
} rmw_init_options_t;

// init.h — rmw_init() 成功后持有
typedef struct rmw_context_s {
uint64_t instance_id;
const char * implementation_identifier;
rmw_init_options_t options;
size_t actual_domain_id;
rmw_context_impl_t * impl;
} rmw_context_t;

4.2 本仓库提供的零初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// src/init.c
rmw_context_t rmw_get_zero_initialized_context(void) {
return (const rmw_context_t){ .instance_id = 0, .impl = NULL };
}

// src/init_options.c
rmw_init_options_t rmw_get_zero_initialized_init_options(void) {
return (const rmw_init_options_t){
.domain_id = RMW_DEFAULT_DOMAIN_ID,
.localhost_only = RMW_LOCALHOST_ONLY_DEFAULT,
.security_options = rmw_get_default_security_options(),
// ...
};
}

4.3 实现侧必须提供的函数(仅声明)

函数 说明
rmw_init_options_init / fini / copy / set_domain_id / set_enclave 配置 init 选项
rmw_init 初始化 DDS participant 工厂等
rmw_shutdown 关闭 context,释放 impl
rmw_context_fini 销毁 context 结构

rcl_init() 调用链:rcl_initrmw_init_options_init → 设置 enclave/domain → rmw_init → 保存 rmw_context_trcl_context_t


5. rmw.h 主 API 分组

rmw/include/rmw/rmw.h 是单一入口,按功能可划分为:

分组 主要 API 说明
标识 rmw_get_implementation_identifierrmw_get_serialization_format 返回后端名字与序列化格式(如 "cdr"
Node rmw_create_nodermw_destroy_nodermw_node_get_graph_guard_condition DDS participant 上的逻辑节点
Publisher create/destroyrmw_publishrmw_publish_loaned_messagermw_publish_serialized_message 发布路径
Subscription create/destroyrmw_take* 系列、rmw_take_sequence 订阅与批量 take
Loaned message rmw_borrow_loaned_messagermw_return_loaned_message_from_* 零拷贝(实现可选)
Serialize rmw_serializermw_deserializermw_get_serialized_message_size 与 rosidl typesupport 配合
Service/Client create/destroyrmw_take_requestrmw_send_responsermw_send_requestrmw_take_response DDS RPC 映射
Wait rmw_create_wait_setrmw_waitrmw_destroy_wait_set 多路复用等待
Guard condition rmw_create_guard_conditionrmw_trigger_guard_condition 唤醒 wait(timer、graph 等)
Graph rmw_get_node_namesrmw_count_publishers/subscribersrmw_get_gid_for_publisher 发现与 introspection
QoS 查询 rmw_publisher_get_actual_qosrmw_subscription_get_actual_qos 协商后的实际 QoS
Liveliness rmw_node_assert_livelinessrmw_publisher_assert_liveliness 手动断言存活
Callback rmw_subscription_set_on_new_message_callback 替代 wait 的异步通知(可选)
Event rmw_event_set_callback QoS 不兼容、deadline 等事件
其他 rmw_compare_gids_equalrmw_service_server_is_availablermw_set_log_severity 工具与日志

Graph 相关 API 还分散在独立头文件中(见第 8 节)。


6. QoS 体系

6.1 rmw_qos_profile_t

1
2
3
4
5
6
7
8
9
10
11
typedef struct rmw_qos_profile_s {
enum rmw_qos_history_policy_e history; // KEEP_LAST / KEEP_ALL
size_t depth;
enum rmw_qos_reliability_policy_e reliability; // RELIABLE / BEST_EFFORT
enum rmw_qos_durability_policy_e durability; // VOLATILE / TRANSIENT_LOCAL
struct rmw_time_s deadline;
struct rmw_time_s lifespan;
enum rmw_qos_liveliness_policy_e liveliness;
struct rmw_time_s liveliness_lease_duration;
bool avoid_ros_namespace_conventions; // 跳过 rt 前缀
} rmw_qos_profile_t;

时间字段使用 RMW_DURATION_UNSPECIFIED / RMW_DURATION_INFINITE 表示“用实现默认”或“无限”。

6.2 预设 Profile(qos_profiles.h

常量 典型用途
rmw_qos_profile_sensor_data 传感器:BEST_EFFORT,depth=5
rmw_qos_profile_default 普通 topic:RELIABLE,depth=10
rmw_qos_profile_parameters 参数服务:RELIABLE,depth=1000
rmw_qos_profile_services_default Service:RELIABLE
rmw_qos_profile_parameter_events 参数事件
rmw_qos_profile_system_default 全部 SYSTEM_DEFAULT
rmw_qos_profile_unknown 未知/未设置

rcl 层将这些 profile 映射到 rcl_qos_profile_t,再传给 rmw_create_publisher

6.3 QoS 字符串转换(src/qos_string_conversions.c

本仓库 完整实现 policy 枚举 ↔ 字符串互转,供 CLI、日志、测试使用:

  • rmw_qos_reliability_policy_to_str / _from_str
  • rmw_qos_durability_policy_to_str / _from_str
  • rmw_qos_history_policy_to_str / _from_str
  • rmw_qos_liveliness_policy_to_str / _from_str
  • rmw_qos_policy_kind_to_str / rmw_qos_policy_kind_from_str

7. Wait Set 与 rmw_wait 契约

7.1 相关类型

1
2
3
4
5
6
7
8
9
10
typedef struct rmw_subscriptions_s {
size_t subscriber_count;
void ** subscribers; // 指向 rmw_subscription_t->data
} rmw_subscriptions_t;

typedef struct rmw_wait_set_s {
const char * implementation_identifier;
rmw_guard_conditions_t * guard_conditions;
void * data;
} rmw_wait_set_t;

还有对称的 rmw_services_trmw_clients_trmw_events_trmw_guard_conditions_t

7.2 rmw_wait 语义(实现在后端)

1
2
3
4
5
6
7
8
rmw_ret_t rmw_wait(
rmw_subscriptions_t * subscriptions,
rmw_guard_conditions_t * guard_conditions,
rmw_services_t * services,
rmw_clients_t * clients,
rmw_events_t * events,
rmw_wait_set_t * wait_set,
const rmw_time_t * wait_timeout);

契约要点(摘自 rmw.h 文档):

  1. 调用前:数组中非 NULL 条目表示要等待的实体;NULL 条目无效。
  2. 调用后:未触发的实体对应数组项被设为 NULL;触发的保留原指针。
  3. 返回值:RMW_RET_OK(有就绪)、RMW_RET_TIMEOUT(超时)、RMW_RET_INVALID_ARGUMENT
  4. 线程安全:同一 wait_set 不可并发 wait;同一实体不可被多个 wait_set 并发 wait。
  5. 所有实体须属于与 wait_set 相同的 rmw_context

7.3 rcl 层如何使用

1
2
3
4
5
6
7
8
rcl_wait_set_t
├── rmw_subscriptions_t ← 从 rcl_subscription_t 收集
├── rmw_guard_conditions_t ← timer、graph、用户 guard
├── rmw_services_t / rmw_clients_t
└── rmw_events_t

rcl_wait() → rmw_wait() → 后端 DDS WaitSet / waitset
返回后 rcl 扫描 NULL 位,标记哪些 subscription/timer 就绪

8. Graph Introspection API

rmw.h 中的 rmw_get_node_namesrmw_count_publishers 外,专用头文件定义更丰富的图 API:

头文件 API 用途
get_topic_names_and_types.h rmw_get_topic_names_and_types 全局 topic 列表
get_service_names_and_types.h rmw_get_service_names_and_types 全局 service 列表
get_node_info_and_types.h rmw_get_*_names_and_types_by_node 按节点查 pub/sub/service/client
get_topic_endpoint_info.h rmw_get_publishers_info_by_topicrmw_get_subscriptions_info_by_topic endpoint 级 QoS/GID
get_network_flow_endpoints.h rmw_publisher_get_network_flow_endpoints 网络流信息(调试用)

辅助数据结构在本仓库实现:

  • rmw_names_and_types_tsrc/names_and_types.c(init/fini/check_zero)
  • rmw_topic_endpoint_info_tsrc/topic_endpoint_info.c(set topic_type、gid、qos 等)
  • rmw_topic_endpoint_info_array_tsrc/topic_endpoint_info_array.c

9. 命名校验(本仓库完整实现)

ROS 2 图命名规则在 RMW 层统一校验,供 rcl 与后端共用:

模块 文件 规则摘要
Topic validate_full_topic_name.c 必须以 / 开头、不以 / 结尾、仅 [a-zA-Z0-9_/]
Namespace validate_namespace.c 类似 topic,允许空 namespace
Node name validate_node_name.c 不含 /,字母数字与 _

每个校验函数返回 RMW_RET_OK + validation_result 枚举(非错误码),并提供 *_validation_result_string() 人类可读描述。

示例(topic 校验入口):

1
2
3
4
rmw_ret_t rmw_validate_full_topic_name(
const char * topic_name,
int * validation_result,
size_t * invalid_index);

10. 事件(Events)

10.1 事件类型(event.h

枚举 方向 含义
RMW_EVENT_REQUESTED_QOS_INCOMPATIBLE Subscription 请求 QoS 与 offer 不兼容
RMW_EVENT_OFFERED_QOS_INCOMPATIBLE Publisher 提供 QoS 与 request 不兼容
RMW_EVENT_LIVELINESS_CHANGED / LOST Sub / Pub 存活策略变化
RMW_EVENT_*_DEADLINE_MISSED Sub / Pub 错过 deadline
RMW_EVENT_MESSAGE_LOST Subscription 消息丢失(实现相关)

10.2 状态结构(events_statuses/

incompatible_qos.hliveliness_changed.h 等定义 DDS 事件计数的 C 结构,与 rmw_take_event(后端实现)配合。

10.3 本仓库实现

  • rmw_get_zero_initialized_event()src/event.c
  • rmw_event_fini() — 重置为零结构(不释放 impl,impl 由后端管理)

rmw_publisher_event_initrmw_subscription_event_initrmw_take_event仅声明


11. 安全与网络选项

11.1 Security(src/security_options.c

1
2
3
4
rmw_security_options_t rmw_get_default_security_options(void);
rmw_ret_t rmw_security_options_set_root_path(...);
rmw_ret_t rmw_security_options_copy(...);
rmw_ret_t rmw_security_options_fini(...);

与 SROS2 集成:enclave + security_root_path 指向密钥库。具体 DDS Security 插件加载在各后端。

11.2 Localhost / Domain

  • domain_id.hRMW_DEFAULT_DOMAIN_ID(0),隔离不同 ROS 域
  • localhost.hRMW_LOCALHOST_ONLY_DEFAULT 等,限制仅本机通信

12. 消息路径辅助类型

类型 文件 说明
rmw_serialized_message_t serialized_message.h 字节缓冲区 + 分配器
rmw_message_info_t types.h source_timestamp、publication_handle、sequence_number
rmw_message_sequence_t message_sequence.c 批量 take 的消息数组
rmw_request_id_t types.h Service 关联 writer_guid + sequence_number

rmw_get_zero_initialized_message_info()src/types.c 实现。

12.1 Loaned Message

API 在 rmw.h 中声明;can_loan_messages 标志由 rmw_create_publisher/subscription 设置。是否支持取决于后端与 typesupport(Fast-DDS 支持较好)。

12.2 Serialize / Deserialize

1
2
3
4
5
6
7
8
9
rmw_ret_t rmw_serialize(
const void * ros_message,
const rosidl_message_type_support_t * type_support,
rmw_serialized_message_t * serialized_message);

rmw_ret_t rmw_deserialize(
const rmw_serialized_message_t * serialized_message,
const rosidl_message_type_support_t * type_support,
void * ros_message);

实现通常委托给 rosidl_typesupport_* 的 CDR 序列化,再经 DDS 发送。


13. 错误处理

error_handling.h 薄封装 rcutils 线程局部错误链:

1
2
3
4
5
6
#define RMW_SET_ERROR_MSG(msg) RCUTILS_SET_ERROR_MSG(msg)
#define RMW_SET_ERROR_MSG_WITH_FORMAT_STRING(...) \
RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING(__VA_ARGS__)
rmw_error_string_t rmw_get_error_string(void);
bool rmw_error_is_set(void);
void rmw_reset_error(void);

13.1 返回码(ret_types.h

含义
RMW_RET_OK 0 成功
RMW_RET_ERROR 1 通用错误(查 error string)
RMW_RET_TIMEOUT 2 wait 超时
RMW_RET_UNSUPPORTED 3 不支持的操作
RMW_RET_BAD_ALLOC 10 内存分配失败
RMW_RET_INVALID_ARGUMENT 11 无效参数
RMW_RET_INCORRECT_RMW_IMPLEMENTATION 12 句柄与当前后端不匹配

src/convert_rcutils_ret_to_rmw_ret.c 提供 rmw_convert_rcutils_ret_to_rmw_ret(),供后端统一转换 rcutils 返回值。

13.2 断言宏(sanity_checks.c / macros.h

RMW_CHECK_ARGUMENT_FOR_NULLRMW_CHECK_TYPE_IDENTIFIERS_MATCH 等在后端实现中广泛使用,保证跨实现一致的错误报告。


14. 特性查询(features.h

1
2
3
4
5
6
typedef enum rmw_feature_e {
RMW_FEATURE_MESSAGE_INFO_PUBLICATION_SEQUENCE_NUMBER,
RMW_FEATURE_MESSAGE_INFO_RECEPTION_SEQUENCE_NUMBER,
} rmw_feature_t;

bool rmw_feature_supported(rmw_feature_t feature); // 后端实现

用于上层判断 rmw_message_info_t 中 sequence number 字段是否可靠填充。


15. src/ 模块一览

源文件 实现的公开 API
allocators.c rmw_*_allocate/freermw_allocate/free
convert_rcutils_ret_to_rmw_ret.c rcutils → rmw 返回码映射
event.c event 零初始化、fini
init.c rmw_get_zero_initialized_context
init_options.c rmw_get_zero_initialized_init_options
message_sequence.c message / message_info sequence init/fini
names_and_types.c rmw_names_and_types_*
network_flow_endpoint.c 网络 endpoint 零初始化、set address
network_flow_endpoint_array.c endpoint 数组管理
publisher_options.c rmw_get_default_publisher_options
subscription_options.c rmw_get_default_subscription_options
subscription_content_filter_options.c Content Filter Topic 选项
qos_string_conversions.c QoS 枚举 ↔ 字符串
sanity_checks.c string array 零检查
security_options.c security options 生命周期
time.c rmw_time_equalrmw_time_from_nsec
topic_endpoint_info.c endpoint info 字段设置
topic_endpoint_info_array.c endpoint 数组
types.c rmw_get_zero_initialized_message_info
validate_*.c topic/namespace/node 名校验

16. rmw_implementation_cmake

16.1 枚举可用实现

get_available_rmw_implementations(var)

  1. 从 ament index 读取 rmw_typesupport 资源(排除 rmw_implementation 代理包本身)
  2. 可通过环境变量 RMW_IMPLEMENTATIONS 或 CMake 变量过滤
  3. 结果写入 ${var} 列表

16.2 选择默认实现

get_default_rmw_implementation(var)

  1. 若未设置 RMW_IMPLEMENTATION(CMake 或环境变量):
    • 优先 rmw_fastrtps_cpp
    • 否则取字母序第一个
  2. 若已设置:验证其在可用列表中,find_package 该包
  3. Humble 上默认编译链接 Fast-DDS不是 CycloneDDS(除非显式设置 RMW_IMPLEMENTATION=rmw_cyclonedds_cpp

16.3 注册实现(register_rmw_implementation.cmake

各后端 CMakeLists.txt 调用:

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

向 ament index 写入:

  • rmw_typesupport — 所有 typesupport 包名
  • rmw_typesupport_c / rmw_typesupport_cpp — 分语言列表

17. 构建与导出

cmake/configure_rmw_library.cmake 设置:

  • RMW_BUILDING_DLL(Windows 导出)
  • 默认 symbol visibility hidden,仅 RMW_PUBLIC 导出

rmw-extras.cmake + ament_export_* 导出 librmw 与 include 路径。


18. 数据路径(端到端)

18.1 发布

DDS DataWriterrmw_implementationrcl用户代码DDS DataWriterrmw_implementationrcl用户代码typesupport 序列化(若需要)rcl_publish(msg)rmw_publish(pub, msg, alloc)dds_write / write

18.2 订阅

1
2
3
4
rmw_take(sub, msg, &taken, alloc)
→ 后端 DataReader take
→ rosidl 反序列化到 ros_message
→ 填充 rmw_message_info_t(时间戳、GID 等)

变体:rmw_take_with_informw_take_serialized_messagermw_take_loaned_messagermw_take_sequence

18.3 等待

1
2
3
4
5
6
rcl_wait(wait_set, timeout)
→ 组装 rmw_subscriptions_t / guard_conditions / services / clients / events
→ rmw_wait(...)
→ 后端 waitset wait
→ 未就绪句柄置 NULL
→ rcl 标记对应实体 ready

18.4 Service

1
2
3
Client: rmw_send_request  → DDS request writer
Server: rmw_take_request → 处理 → rmw_send_response
Client: rmw_take_response

19. 与 rcl 的职责对比

主题 rcl rmw
Namespace / remap ✅ 展开 ~/foo → 绝对名 接收最终字符串
QoS 默认值 rcl_qos_profile_* rmw_qos_profile_*
Wait set 组装 ✅ timer → guard_condition 执行底层 wait
参数 / YAML ✅ CLI 解析
日志 ✅ rcl_logging rmw_set_log_severity 转发 DDS 日志
命名校验 调用 rmw_validate_* ✅ 实现校验逻辑
DDS 实体 ✅ 后端实现

20. 相关仓库

仓库/包 关系
rmw_implementation 代理库;RMW_IMPLEMENTATION 环境变量在运行时切换(若构建支持)
rmw_cyclonedds_cpp CycloneDDS 后端
rmw_fastrtps_cpp Fast-DDS 后端;Humble 默认
rmw_connextdds RTI Connext 后端
rmw_dds_common 多后端共享:graph 缓存、GID、demangle
rosidl_typesupport_* 消息序列化;与 rmw_serialize 配合
rcl RMW 主要调用方

21. 推荐阅读顺序

  1. rmw/types.h — 掌握所有句柄与 QoS 类型(~650 行)
  2. rmw/init.h + init_options.h — 理解 context 生命周期契约
  3. rmw/rmw.h — 按 pub/sub/wait/graph 分段阅读(不必一次读完 3200 行)
  4. rmw/src/validate_full_topic_name.c — 看本仓库“有实现”代码的风格
  5. rmw_implementation_cmake/get_default_rmw_implementation.cmake — 理解构建默认后端
  6. rmw_implementation 仓库 — 符号如何转发到具体后端
  7. 任选一后端 — 如 rmw_cyclonedds_cpprmw_create_publisher / rmw_wait 实现
  8. rmw_dds_common — graph 与 GID 共享逻辑

22. 小结

rmw 仓库是 ROS 2 可插拔中间件契约层 + 公共工具库

  • 对上:为 rcl 提供稳定 C ABI 与一致的类型定义;
  • 对下:不绑定任何 DDS,具体通信由 rmw_*_cpp 实现;
  • 本仓库源码价值:理解 ROS 2 中间件 接口设计(句柄、wait 语义、QoS、graph API)以及 跨实现共享逻辑(命名校验、QoS 字符串、init 默认值);
  • 调试通信问题:沿 rcl_ret_trmw_ret_trmw_get_error_string() 向下追至具体后端。

换 DDS 只需安装并选择对应 rmw_*_cpp 实现,rcl / rclcpp / rclpy 无需修改。

文章互动

阅读 --

留言

0 条留言

正在加载留言…