uORB_发布-订阅消息通信框架

uORB 通信机制详解

uORB(micro Object Request Broker)是 PX4 系统中的发布-订阅消息通信框架,负责在系统模块之间传递结构化的数据。


uORB 是什么

  • 是 PX4 内部模块间通信的“消息总线”。
  • 实现模块之间解耦通信:发送者和接收者不需要彼此知道对方是谁。
  • 每个通信数据结构叫做一个“Topic”。

基本概念

术语 含义
Topic 定义好的数据结构,用于在模块之间传输数据
Publisher 向某个 Topic 写数据的模块
Subscriber 从某个 Topic 读取数据的模块
ORB Object Request Broker,对 topic 的注册和通信管理器
uORB::Manager uORB 中的单例,用于 topic 的创建、查找、广播

工作流程图

[Publisher Module]
     |
     |  publish()
     ↓
[uORB::Manager] -- Topic Instance
     ↑
     |  subscribe()
[Subscriber Module]
  • Publisher 调用 orb_advertise() 注册并发布数据;
  • Subscriber 调用 orb_subscribe() 订阅 topic;
  • 使用 orb_check() 查询是否有新数据;
  • orb_copy() 读取数据。

关键 API

// 注册并发布 topic 数据
orb_advert_t orb_advertise(const struct orb_metadata *meta, const void *data);

// 发布新数据
int orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void *data);

// 订阅 topic
int orb_subscribe(const struct orb_metadata *meta);

// 查询是否有新数据
int orb_check(int handle, bool *updated);

// 读取数据
int orb_copy(const struct orb_metadata *meta, int handle, void *buffer);

示例:发布和订阅

Topic 示例定义(在 msg/vehicle_status.msg

uint64 timestamp
bool armed
bool failsafe

生成的代码在 build/px4_fmu-gen/msg/vehicle_status.h


发布者模块(如:控制模块)

#include 
#include 

void publish_status()
{
    struct vehicle_status_s status = {};
    status.timestamp = hrt_absolute_time();
    status.armed = true;
    status.failsafe = false;

    orb_advert_t pub_handle = orb_advertise(ORB_ID(vehicle_status), &status);

    // 更新发布
    status.armed = false;
    orb_publish(ORB_ID(vehicle_status), pub_handle, &status);
}

订阅者模块(如:日志模块)

#include 
#include 

void listen_status()
{
    int sub_handle = orb_subscribe(ORB_ID(vehicle_status));
    bool updated = false;

    while (true) {
        orb_check(sub_handle, &updated);
        if (updated) {
            struct vehicle_status_s status;
            orb_copy(ORB_ID(vehicle_status), sub_handle, &status);

            PX4_INFO("Status: armed=%d, failsafe=%d", status.armed, status.failsafe);
        }

        usleep(100000); // 100ms
    }
}

多实例 topic 支持(如 actuator_outputs)

某些 topic(如 actuator_controls)支持多个实例:

int instance;
orb_advert_t adv = orb_advertise_multi(ORB_ID(actuator_controls), &controls, &instance, ORB_PRIO_DEFAULT);

订阅时:

int sub = orb_subscribe_multi(ORB_ID(actuator_controls), 1); // 订阅第2路

⚠️ 常见问题

问题 原因
数据不更新 没有调用 orb_check()orb_copy()
orb_advertise 多次失败 不应重复调用,应该使用 orb_publish
订阅收不到数据 发布者未成功注册 / 实例号不匹配

参考资料

  • PX4 官方文档 uORB
  • [PX4 源码:src/modules/uORB/]
  • uORB/examples 中的 uorb_test 示例模块

你可能感兴趣的:(uORB)