PX4 uORB

本文最后更新于 2025年4月17日 下午

uORB 是 PX4 中的一个多发布-多订阅(publish-subscribe)消息传递系统,它允许不同模块之间进行异步通信。

核心架构

核心组件:

  • uORB.h/cpp - uORB 的主要接口和实现。uORB.h对外提供c风格使用接口,封装自uORBManager.hpp中Manager类接口
  • uORBManager.hpp/cpp - uORB 系统的管理器
  • uORBDeviceMaster.hpp/cpp - 设备主控制器
  • uORBDeviceNode.hpp/cpp - 设备节点的实现

发布订阅机制:

  • Publication.hpp - 消息发布相关
  • PublicationMulti.hpp - 多重发布支持。封装自uORB.h和uORBManager.hpp的接口
  • Subscription.hpp/cpp - 订阅相关实现
  • SubscriptionCallback.hpp - 订阅回调机制
  • SubscriptionInterval.hpp - 基于时间间隔的订阅
  • SubscriptionBlocking.hpp - 阻塞式订阅
  • SubscriptionMultiArray.hpp - 多重订阅数组,目的是为了高效管理同一 uORB 主题的多个实例订阅。

工具和辅助类:

  • uORBUtils.hpp/cpp - 工具函数
  • uORBCommon.hpp - 通用定义
  • uORBTopics.h - 主题定义
  • uORBMessageFields.hpp/cpp - 消息字段处理
  • ORBSet.hpp - ORB 集合实现

测试相关:

  • uORB_tests/ - 测试目录
  • uORBMessageFieldsTest.cpp - 消息字段测试

uORB系统中的主要类及其关系:

1
2
3
4
5
6
7
Manager "1" --> "1" DeviceMaster : manages
DeviceMaster "1" --> "*" DeviceNode : creates/manages
DeviceNode "1" --> "1" orb_metadata : references
Publication --> orb_metadata : references
Subscription --> orb_metadata : references
Publication --> DeviceNode : publishes to
Subscription --> DeviceNode : subscribes to
  1. Manager(管理器)
  • 单例模式实现
  • 管理整个uORB系统
  • 提供主要的发布/订阅接口
  • 管理DeviceMaster实例。作为DeviceMaster友元类,可以使用私有的构造接口创建实例
  1. DeviceMaster(设备主控)
  • 管理所有DeviceNode实例
  • 管理主题实例。通过advertise接口,可以支持发布者、订阅者任意的启动顺序
  • 维护统计信息
  1. DeviceNode(设备节点)
  • 代表一个具体的主题实例
  • 处理数据的发布和订阅。
  • 管理数据队列。存储该主题实例的对应的所有订阅回调。
  • 与具体的orb_metadata关联
  1. Publication(发布类)
  • 提供发布者接口
  • 管理发布句柄
  • 简化发布操作
  1. Subscription(订阅类)
  • 提供订阅者接口
  • 管理订阅句柄
  • 简化订阅操作
  1. SubscriptionCallback和SubscriptionCallbackWorkItem
  • 异步处理机制:

    • 将 uORB 订阅与工作队列系统集成
    • 实现数据的异步处理
    • 避免阻塞主线程
  • 事件驱动架构:

    • 当新数据到达时自动触发处理
    • 实现响应式编程模式
    • 提高系统实时性
  • 资源管理:

    • 统一管理订阅和工作项
    • 自动处理资源分配和释放
    • 简化内存管理
  1. orb_metadata(元数据)
  • 定义主题的基本信息
  • 包含主题名称、大小等属性
  • 用于主题的标识和验证

主要关系:
Manager是整个系统的入口点,管理DeviceMaster
DeviceMaster创建和管理多个DeviceNode
DeviceNode与具体的主题元数据(orb_metadata)关联
Publication和Subscription通过DeviceNode进行数据交互
所有组件都依赖orb_metadata进行主题识别和验证

这种设计实现了一个高效的发布-订阅系统,支持:
多发布者-多订阅者模式(注:同一个topic的多发布者分别有自己一个实例,每个发布者使用不同的实例,通过实例ID来区分)
主题实例化
数据队列管理
统计信息收集
线程安全的数据交换

topic 头文件自动生成机制

如何将将topic msg生成对应头文件

这个过程是在构建阶段完成,核心处理逻辑位于msg/CMakeLists.txt,其最终通过Tools/msg/中的 Python 脚本处理,生成的uORB头文件和源文件文件位于build目录下。

核心cmake代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
add_custom_command(
OUTPUT
${uorb_headers}
${msg_out_path}/uORBTopics.hpp
COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/Tools/msg/px_generate_uorb_topic_files.py
--headers
-f ${msg_files}
-i ${CMAKE_CURRENT_SOURCE_DIR}
-o ${msg_out_path}
-e ${PX4_SOURCE_DIR}/Tools/msg/templates/uorb
DEPENDS
${msg_files}
${PX4_SOURCE_DIR}/Tools/msg/templates/uorb/msg.h.em
${PX4_SOURCE_DIR}/Tools/msg/templates/uorb/uORBTopics.hpp.em
${PX4_SOURCE_DIR}/Tools/msg/px_generate_uorb_topic_files.py
${PX4_SOURCE_DIR}/Tools/msg/px_generate_uorb_topic_helper.py
COMMENT "Generating uORB topic headers"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
VERBATIM
)

.em 文件通常是指使用 empy(Embedded Python)模板引擎编写的模板文件。empy 是一种基于 Python 的模板系统,允许在文本文件中嵌入 Python 代码,以便动态生成内容。

px_generate_uorb_topic_files.py 核心为根据给定的模板文件和预定义的配置项来 调用empy解释器生成头文件和源文件。

生成的头文件和源文件最终会构成静态库uorb_msgs。

与px4_work_queue集成

platform/common/work_queue是一个跨平台(posix和nuttx平台)的抽象层,为上层应用提供了统一的工作队列接口。nuttx平台是直接使用nuttx内置的工作队列,而posix则是对接口进行了重新实现。

px4_work_queue是一个c++实现的工作队列模块,是否有使用os提供的队列 有待确认


PX4 uORB
https://leelewin.github.io/p/dce3e059d3314266a113059c71f5ceba/
作者
liminglei
发布于
2025年2月25日
许可协议
BY_NC_SA