PX4/Pixhawk uORB
PX4/Pixhawk的软件体系结构主要被分为四个层次
应用程序的API:这个接口提供给应用程序开发人员,此API旨在尽可能的精简、扁平及隐藏其复杂性
应用程序框架:这是为操作基础飞行控制的默认程序集(节点)
库:这一层包含了所有的系统库和基本交通控制的函数
操作系统:提供硬件驱动程序、网络、UAVCAN和故障安全系统
uORB(Micro Object Request Broker,微对象请求代理器)是PX4/Pixhawk系统中非常重要且关键的一个模块,它肩负了整个系统的数据传输任务,所有的传感器数据、GPS、PPM信号等都要从芯片获取后通过uORB进行传输到各个模块进行计算处理。实际上uORB是一套跨「进程」 的IPC通讯模块。在Pixhawk中, 所有的功能被独立以进程模块为单位进行实现并工作。而进程间的数据交互就由为重要,必须要能够符合实时、有序的特点
Pixhawk使用的是NuttX实时ARM系统,uORB实际上是多个进程打开同一个设备文件,进程间通过此文件节点进行数据交互和共享。进程通过命名的「总线」交换的消息称之为「主题」(topic),在Pixhawk 中,一个主题仅包含一种消息类型,通俗点就是数据类型。每个进程可以「订阅」或者「发布」主题,可以存在多个发布者,或者一个进程可以订阅多个主题,但是一条总线上始终只有一条消息
PX4/Pixhawk应用程序框架
uORB文件夹
文件/目录说明
topics:系统通用接口定义的标准主题,比如电池电量转态、GPS的位置参数等
objects_common.cpp:通用接口标准主题定义集合,如添加新主题在这里定义
Publication.cpp:在不同的发布中遍历使用
Subscription.cpp:在不同的订阅中遍历使用
uORB.cpp:uORB的实现
uORBCommon.hpp:uORB公共部分变量定义实现
uORBCommunicator.hpp:远程订阅的接口实现,实现了对不同的通信通道管理,如添加/移除订阅者,可以基于TCP/IP或fastRPC;传递给通信链路的实现,以提供在信道上接收消息的回调
uORBDevices_nuttx.cpp:节点操作,close,open,read,write
uORBMain.cpp:uORB入口
uORBManager.hpp:uORB功能函数实现头文件
uORBManager_nuttx.cpp:uORB功能函数实现(Nuttx)
uORBManager_posix.cpp:uORB功能函数实现(Posix)
uORBTest_UnitTest.cpp:uORB测试
函数功能解析
//orb_subscribe
int orb_subscribe(const struct orb_metadata *meta)
功能:订阅主题
说明:即使订阅的主题没有被公告,但是也能订阅成功;但是在这种情况下,却得不到数据,直到主题被公告;
参数:
meta:uORB元对象,可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;
返回值:
错误则返回ERROR;成功则返回一个可以读取数据、更新话题的句柄;如果待订阅的主题没有定义或声明则会返回-1,然后会将errno赋值为ENOENT;
eg:
int fd = orb_subscribe(ORB_ID(topicName));
//orb_copy
int orb_copy(const struct orb_metadata *meta, int handle, void *buffer)
功能:从订阅的主题中获取数据并将数据保存到buffer中;
参数:
meta:uORB元对象,可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;
handle:订阅主题返回的句柄;
buffer:从主题中获取的数据;
返回值:
返回OK表示获取数据成功,错误返回ERROR;否则则有根据的去设置errno;
eg:
struct sensor_combined_s raw;
orb_copy(ORB_ID(sensor_combined), sensor_sub_fd, &raw);
//orb_advertise
orb_advert_t orb_advertise(const struct orb_metadata *meta, const void *data)
功能:公告发布者的主题;
说明:在发布主题之前是必须的;否则订阅者虽然能订阅,但是得不到数据;
参数:
meta:uORB元对象,可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;
data:指向一个已被初始化,发布者要发布的数据存储变量的指针;
返回值:错误则返回ERROR;成功则返回一个可以发布主题的句柄;如果待发布的主题没有定义或声明则会返回-1,然后会将errno赋值为ENOENT;
eg:
struct vehicle_attitude_s att;
memset(&att, 0, sizeof(att));
int att_pub_fd = orb_advertise(ORB_ID(vehicle_attitude), &att);
//orb_publish
int orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void *data)
功能:发布新数据到主题;
参数:
meta:uORB元对象,可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;
handle:orb_advertise函数返回的句柄;
data:指向待发布数据的指针;
返回值:OK表示成功;错误返回ERROR;否则则有根据的去设置errno;
eg:
orb_publish(ORB_ID(vehicle_attitude), att_pub_fd, &att);
//orb_set_interval
int orb_set_interval(int handle, unsigned interval)
功能:设置订阅的最小时间间隔;
说明:如果设置了,则在这间隔内发布的数据将订阅不到;需要注意的是,设置后,第一次的数据订阅还是由起初设置的频率来获取,
参数:
handle:orb_subscribe函数返回的句柄;
interval:间隔时间,单位ms;
返回值:OK表示成功;错误返回ERROR;否则则有根据的去设置errno;
eg:
orb_set_interval(sensor_sub_fd, 1000);
//orb_advertise_multi
orb_advert_t orb_advertise_multi(const struct orb_metadata *meta, const void *data, int *instance, int priority)
功能:设备/驱动器的多个实例实现公告,利用此函数可以注册多个类似的驱动程序;
说明:例如在飞行器中有多个相同的传感器,那他们的数据类型则类似,不必要注册几个不同的话题;
参数:
meta:uORB元对象,可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;
data:指向一个已被初始化,发布者要发布的数据存储变量的指针;
instance:整型指针,指向实例的ID(从0开始);
priority:实例的优先级。如果用户订阅多个实例,优先级的设定可以使用户使用优先级高的最优数据源;
返回值:
错误则返回ERROR;成功则返回一个可以发布主题的句柄;如果待发布的主题没有定义或声明则会返回-1,然后会将errno赋值为ENOENT;
eg:
struct orb_test t;
t.val = 0;
int instance0;
orb_advert_t pfd0 = orb_advertise_multi(ORB_ID(orb_multitest), &t, &instance0, ORB_PRIO_MAX);
//orb_subscribe_multi
int orb_subscribe_multi(const struct orb_metadata *meta, unsigned instance)
功能:订阅主题(topic);
说明:通过实例的ID索引来确定是主题的哪个实例;
参数:
meta:uORB元对象,可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;
instance:主题实例ID;实例ID=0与orb_subscribe()实现相同;
返回值:
错误则返回ERROR;成功则返回一个可以读取数据、更新话题的句柄;如果待订阅的主题没有定义或声明则会返回-1,然后会将errno赋值为ENOENT;
eg:
int sfd1 = orb_subscribe_multi(ORB_ID(orb_multitest), 1);
//orb_unsubscribe
int orb_unsubscribe(int handle)
功能:取消订阅主题;
参数:
handle:主题句柄;
返回值:
OK表示成功;错误返回ERROR;否则则有根据的去设置errno;
eg:
ret = orb_unsubscribe(handle);
//orb_check
int orb_check(int handle, bool *updated)
功能:订阅者可以用来检查一个主题在发布者上一次更新数据后,有没有订阅者调用过ob_copy来接收、处理过;
说明:如果主题在在被公告前就有人订阅,那么这个API将返回“not-updated”直到主题被公告。可以不用poll,只用这个函数实现数据的获取。
参数:
handle:主题句柄;
updated:如果当最后一次更新的数据被获取了,检测到并设置updated为ture;
返回值:
OK表示检测成功;错误返回ERROR;否则则有根据的去设置errno;
//orb_stat
int orb_stat(int handle, uint64_t *time)
功能:订阅者可以用来检查一个主题最后的发布时间;
参数:
handle:主题句柄;
time:存放主题最后发布的时间;0表示该主题没有发布或公告;
返回值:
OK表示检测成功;错误返回ERROR;否则则有根据的去设置errno;
eg:
ret = orb_stat(handle,time);
//orb_exists
int orb_exists(const struct orb_metadata *meta, int instance)
功能:检测一个主题是否存在;
参数:
meta:uORB元对象,可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;
instance:ORB 实例ID;
返回值:
OK表示检测成功;错误返回ERROR;否则则有根据的去设置errno;
eg:
ret = orb_exists(ORB_ID(vehicle_attitude), 0);
//orb_priority
int orb_priority(int handle, int32_t *priority)
功能:获取主题优先级别;
参数:
handle:主题句柄;
priority:存放获取的优先级别;
返回值:
OK表示检测成功;错误返回ERROR;否则则有根据的去设置errno;
eg:
ret = orb_priority(handle, &priority);
举例
发布方
orb_advert_t _report_pub;
auto report; //自定义数据
ORB_DECLARE(vehicle_gps_position);
if (_report_pub != nullptr) {
//发布新数据到主题
orb_publish(ORB_ID(vehicle_gps_position), _report_pub, &report);
} else {
//如果还没有公告主题,首先公布
_report_pub = orb_advertise(ORB_ID(vehicle_gps_position), &report);
}
订阅方
int _gps_sub;
bool updated = false;
_gps_sub = orb_subscribe(ORB_ID(vehicle_gps_position));
orb_check(_gps_sub, &updated);
struct vehicle_gps_position_s _gps_pos; //vehicle_gps_position_s自定义类型
if (updated) {
if (OK == orb_copy(ORB_ID(vehicle_gps_position), _gps_sub, &_gps_pos)) {
;
}
PX4/Pixhawk uORB的更多相关文章
- PX4/PixHawk无人机飞控应用开发
最近做的一个国防背景的field UAV项目,细节不能多谈,简单写点技术体会. 1.PX4/Pixhawk飞控软件架构简介 PX4是目前最流行的开源飞控板之一.PX4的软件系统实际上就是一个firmw ...
- 在linux使用make编译ArduPilot for Pixhawk/PX4 ArduPilot 编译环境搭建
Building ArduPilot for Pixhawk/PX4 on Linux with Make 使用Make编译 ArduPilot for Pixhawk 2, Pixhawk and ...
- PX4学习之-uORB简单体验
一.前言 最近项目使用到 CPU2 与 CPU0 之间的通信, 使用定时器传递消息到 CPU0 后, CPU0 需要将消息分发到不同的应用程序里面. PX4 里面使用的是 uORB 多线程/进程通信机 ...
- PX4学习之-uORB msg 自动生成模板解读
最后更新日期 2019-06-22 一.前言 在 PX4学习之-uORB简单体验 中指出, 使用 uORB 进行通信的第一步是新建 msg.在实际编译过程中,新建的 msg 会转换成对应的 .h..c ...
- [pixhawk笔记]11-Windows下PX4代码查看
由于项目需要做基于Simulink的PX4二次开发,在Windows下面做,所以需要在Windows下查看PX4的代码,故写该文档,记录环境安装和配置过程.按照该网页安装工具链:Windows Ins ...
- [pixhawk笔记]5-uORB消息传递
本文主要内容翻译自官方文档:https://dev.px4.io/en/middleware/uorb.html 在前一篇笔记中使用uORB完成消息传递,实现了一个简单示例程序,本文将对uORB进行系 ...
- [pixhawk笔记]4-如何写一个简单的应用程序
本文主要内容来自于:https://dev.px4.io/en/tutorials/tutorial_hello_sky.html,并对文档中的部分问题进行更正. 本文假设已经建立好开发环境并能正确编 ...
- [pixhawk笔记]7-MAVLink添加自定义消息
前一篇学习了uORB,用于px4中各个模块的进程间通信,下来学习MAVLink,用于飞控和地面站之间的通信.教程中主要给出了使用MAVLink的发送和接收消息的方法.完整的MAVLink消息列表见该网 ...
- [pixhawk笔记]6-uORB流程及关键函数解析
本文中将结合代码.文档及注释,给出uORB执行流程及关键函数的解析,由于uORB的机制实现较为复杂,所以本文主要学习如何使用uORB的接口来实现通信.回到上一篇笔记中的代码: #include < ...
随机推荐
- 记一次haproxy反向代理配置
首先借用一下前辈的话,解释下反向代理是什么? 反向代理:以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客 ...
- dapperHelper
public class DapperHelper { /// 数据库连接名 private static string _connection = string.Empty; /// 获取连接名 p ...
- winform使用委托和事件在窗体之间传值
定义委托和事件,并且触发这个事件 //定义委托 public delegate void ShowOutStockDelegate(List<OutStockResultDto> outS ...
- PHP IE9 AJAX success 返回 undefined 问题解决
jquery的AJAX返回结果为undefined,并且有“由于出现错误c00ce56e”的错误提示.这个问题是由于IE9不能解析其他编码而产生的.解决这个问题之需要按照W3C规范,声明一下编码为ut ...
- hadoop记录-flink测试
1.启动集群 bin/start-cluster.sh 2.jps查看进程 3.打开网页端(192.168.66.128:8081) 4.造数据:nc -lk 9000 5.执行./bin/flink ...
- Laya的图文混排
参考: Laya图文混排 Laya的图文混排教程 编辑模式F9,增加laya.html.js库 在层级窗口右键,添加一个HtmlDivElement组件 大致的原理: 1. 例如输入框的字符串是 &q ...
- 如何关闭phpstrom的更新提醒?
在file-----setting-------搜索updates 把检测版本更新的对勾点掉就可以了, 自己破解后的版本就别更新了,更新后就不能再用了,目前用代理服务器激活可以用版本3.3,升级到3. ...
- C++ 宏和模板简介
参考<21天学通C++>第14章节,对C++中的宏和模板进行了学习,总结起来其主要内容如下: (1) 预处理器简介 (2) 关键字#define与宏 (3) 模板简介 (4) 如何编写函数 ...
- LeetCode 206. 反转链表(Reverse Linked List) 16
206. 反转链表 206. Reverse Linked List 题目描述 反转一个单链表. 每日一算法2019/5/19Day 16LeetCode206. Reverse Linked Lis ...
- 如何将生产环境的服务Docker镜像拉取到本地进行调试
背景 很多时候我们在将开发环境的代码推送到GitLab上面以后,我们在测试的时候发现了问题后无法通过现有的日志输出级别来定位问题,比如我们需要看EFCore生成的SQL语句,在生产环境我们是不可能输出 ...