您的位置:首页 > 编程语言

PX4代码学习系列博客(4)——uORB相关

2017-08-27 13:42 507 查看

uORB简介

px4使用的是NuttX实时操作系统,而这个操作系统没有在应用程序间通信的功能。为了满足飞控消息传递的实时性,uORB才被开发出来。

uORB(Micro Object Request Broker,微对象请求代理器)是px4系统中特殊的一个模块(应用程序),它负责在不同的模块(应用程序)之间传递数据。从传感器采集到的数据,从地面站发送的控制指令,位置和姿态的解算结果等,都是通过uORB来传递的。

在px4中,各个模块通过命名的“总线”交换的消息称之为“主题”(topic),一个主题仅包含一种消息类型,通俗点就是数据类型。每个进程可以“订阅”(subscribe)或者“发布”(publish)主题,可以存在多个发布者,或者一个进程可以订阅多个主题,但是一条总线上始终只有一条消息。

uORB目录结构

在目录Firmware\src\modules\uORB下:



图中的“topics”文件夹在Firmware\build_px4fmu-v2_default\src\modules\uORB中。这个文件夹需要在程序编译后才有。topics文件夹下是px4飞控内部uORB上传输的所有消息。

文件功能介绍

topics文件夹: 系统通用接口定义的标准主题,比如电池电量转态、GPS的位置参数等

uORB_tests文件夹: uORB测试

CMakeLists.txt: uORB模块makefile文件

ORBMap.hpp : 对象请求器节点链表管理(驱动节点)

ORBSet.hpp : 对象请求器节点管理(非驱动节点)

Publication.cpp和Publication.hpp : 在不同的发布中遍历使用。

Subscription.cpp和Subscription.hpp: 在不同的订阅中遍历使用。

uORB.cpp和uORB.h : uORB的c语言实现,其实它是调用了c++中类的方法。这样简化了编程接口。

uORBCommon.hpp : uORB公共部分变量定义实现。

uORBCommunicator.hpp : 远程订阅的接口实现,实现了对不同的通信通道管理,如添加/移除订阅者,可以基于TCP/IP或fastRPC;传递给通信链路的实现,以提供在信道上接收消息的回调。

uORBDevices.cpp和uORBDevices.hpp : 节点操作,close,open,read,write

uORBMain.cpp : uORB应用程序的定义。

uORBManager.cpp和uORBManager.hpp : uORB函数实现,被uORB.cpp和uORB.h调用,一般在其他模块调用的函数具体实现都在这个文件。

uORBTopics.h:两个函数的外部申明。

uORBUtiles.cpp和uORBUtiles.hpp: 好像没有被调用到。

uORBManager.cpp中函数解析

orb_advert_t orb_advertise(const struct orb_metadata *meta, const void *data, unsigned int queue_size = 1);
//申明orb消息并发送初始数据。返回用来发布消息的句柄


int orb_unadvertise(orb_advert_t handle);
//与上一条功能相反


int orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void *data);
//发布一条消息,第二个参数是orb_advertise的返回值


int orb_subscribe(const struct orb_metadata *meta);
//订阅一条消息


int orb_unsubscribe(int handle);
//取消订阅一条消息


int orb_copy(const struct orb_metadata *meta, int handle, void *buffer);
//从主题中获取数据,在调用之前一般会调用orb_check来检查主题是否被更新


int orb_check(int handle, bool *updated);
//检查主题是否被更新


int orb_stat(int handle, uint64_t *time);
//返回主题最近被更新的时间


int orb_priority(int handle, int32_t *priority);
//返回一个主题的优先级


int orb_set_interval(int handle, unsigned interval);
//设置为订阅者更新数据的最小时间间隔


int orb_get_interval(int handle, unsigned *interval);
//获得为订阅者更新数据的最小时间间隔


一个简单的订阅流程

(以attitude_estimator_q模块为例)

_sensors_sub = orb_subscribe(ORB_ID(sensor_combined));
px4_pollfd_struct_t fds[1] = {};
fds[0].fd = _sensors_sub;
fds[0].events = POLLIN;
while(px4_poll(fds, 1, 1000)<=0);//直到收到订阅的主题。
sensor_combined_s sensors;
orb_copy(ORB_ID(sensor_combined), _sensors_sub, &sensors)
//此时数据已经保存到结构体sensors中。


一个简单的发布流程

(以attitude_estimator_q模块为例)

struct control_state_s ctrl_state = {};
//准备ctrl_state中的数据。
orb_advert_t    _ctrl_state_pub = nullptr;
int ctrl_inst;//该变量没有被用到。
if (_ctrl_state_pub == nullptr)
{
//如果没有申明过要发布control_state,那么需要调用orb_advertise_multi
_ctrl_state_pub = orb_advertise_multi(ORB_ID(control_state), &ctrl_state, &ctrl_inst, ORB_PRIO_HIGH);

if (_ctrl_state_pub!= nullptr)
{
return 0;
}
}
else
{
//否则,可以直接发送申明过的主题。
return orb_publish(ORB_ID(control_state), _ctrl_state_pub, &ctrl_state);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  px4 飞控 uORB