Pixhawk--uORB深入学习

来源:互联网 发布:淘宝信用等级怎么看 编辑:程序博客网 时间:2024/05/18 18:43

注:本文转载自  博主:FreeApe   博客:《PX4/Pixhawk---uORB深入理解和应用

The Instructions of uORB

『PX4/Pixhawk』   『软件体系结构』『uORB』『主题发布』『主题订阅』

1 简介

1.1 PX4/Pixhawk的软件体系结构

 PX4/Pixhawk的软件体系结构主要被分为四个层次,这可以让我们更好的理解PX4/Pixhawk的软件架构和运作:

  • 应用程序的API:这个接口提供给应用程序开发人员,此API旨在尽可能的精简、扁平及隐藏其复杂性。
  • 应用程序框架: 这是为操作基础飞行控制的默认程序集(节点)。
  • 库: 这一层包含了所有的系统库和基本交通控制的函数。
  • 操作系统: 最后一层提供硬件驱动程序,网络,UAVCAN和故障安全系统。

PX4/Pixhawk软件体系结构 
  uORB(Micro Object Request Broker,微对象请求代理器)是PX4/Pixhawk系统中非常重要且关键的一个模块,它肩负了整个系统的数据传输任务,所有的传感器数据、GPS、PPM信号等都要从芯片获取后通过uORB进行传输到各个模块进行计算处理。实际上uORB是一套跨「进程」 的IPC通讯模块。在Pixhawk中, 所有的功能被独立以进程模块为单位进行实现并工作。而进程间的数据交互就由为重要,必须要能够符合实时、有序的特点。 
  Pixhawk使用的是NuttX实时ARM系统,uORB实际上是多个进程打开同一个设备文件,进程间通过此文件节点进行数据交互和共享。进程通过命名的「总线」交换的消息称之为「主题」(topic),在Pixhawk 中,一个主题仅包含一种消息类型,通俗点就是数据类型。每个进程可以「订阅」或者「发布」主题,可以存在多个发布者,或者一个进程可以订阅多个主题,但是一条总线上始终只有一条消息。

1.2 PX4/Pixhawk应用程序框架

PX4应用程序框架

  应用层中操作基础飞行的应用之间都是隔离的,这样提供了一种安保模式,以确保基础操作独立的高级别系统状态的稳定性。而沟通它们的就是uORB。

2 uORB文件夹说明

2.1 uORB文件夹结构

uORB文件夹结构

2.2 文件/目录说明

topics : 系统通用接口定义的标准主题,比如电池电量转态、GPS的位置参数等 
module.mk : uORB模块makefile文件 
objects_common.cpp: 通用接口标准主题定义集合,如添加新主题在这里定义 
ORBMap.hpp : 对象请求器节点链表管理(驱动节点) 
ORBSet.hpp : 对象请求器节点管理(非驱动节点) 
Publication.cpp : 在不同的发布中遍历使用 
Publication.hpp : 在不同的发布中遍历使用 
Subscription.cpp : 在不同的订阅中遍历使用 
Subscription.hpp : 在不同的订阅中遍历使用 
uORB.cpp : uORB的实现 
uORB.h : uORB头文件 
uORBCommon.hpp : uORB公共部分变量定义实现 
uORBCommunicator.hpp : 远程订阅的接口实现,实现了对不同的通信通道管理,如添加/移除订阅者,可以基于TCP/IP或fastRPC;传递给通信链路的实现,以提供在信道上接收消息的回调。 
uORBDevices.hpp : 
uORBDevices_nuttx.cpp : 节点操作,close,open,read,write 
uORBDevices_nuttx.hpp : 
uORBDevices_posix.cpp : 
uORBDevices_posix.hpp : 
uORBMain.cpp : uORB入口 
uORBManager.hpp : uORB功能函数实现头文件 
uORBManager_nuttx.cpp : uORB功能函数实现(Nuttx) 
uORBManager_posix.cpp : uORB功能函数实现(Posix) 
uORBTest_UnitTest.cpp : uORB测试 
uORBTest_UnitTest.hpp : uORB测试头文件,包括主题定义和声明等 
uORBUtiles.cpp : 
uORBUtiles.hpp :

3 常用函数功能解析

int poll(struct pollfd fds[], nfds_t nfds, int timeout)

功能:监控文件描述符(多个);说明:timemout=0,poll()函数立即返回而不阻塞;timeout=INFTIM(-1),poll()会一直阻塞下去,直到检测到return > 0;参数:    fds:struct pollfd结构类型的数组;    nfds:用于标记数组fds中的结构体元素的总数量;    timeout:是poll函数调用阻塞的时间,单位:毫秒;返回值:    >0:数组fds中准备好读、写或出错状态的那些socket描述符的总数量;    ==0:poll()函数会阻塞timeout所指定的毫秒时间长度之后返回;    -1:poll函数调用失败;同时会自动设置全局变量errno;

int orb_subscribe(const struct orb_metadata *meta)

功能:订阅主题(topic);说明:即使订阅的主题没有被公告,但是也能订阅成功;但是在这种情况下,却得不到数据,直到主题被公告;参数:    meta:uORB元对象,可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;返回值:    错误则返回ERROR;成功则返回一个可以读取数据、更新话题的句柄;如果待订阅的主题没有定义或声明则会返回-1,然后会将errno赋值为ENOENT;eg:    int fd = orb_subscribe(ORB_ID(topicName));

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_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);

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);

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_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);

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);

int orb_unsubscribe(int handle)

功能:取消订阅主题;参数:    handle:主题句柄;返回值:    OK表示成功;错误返回ERROR;否则则有根据的去设置errno;eg:    ret = orb_unsubscribe(handle);

int orb_check(int handle, bool *updated)

功能:订阅者可以用来检查一个主题在发布者上一次更新数据后,有没有订阅者调用过ob_copy来接收、处理过;说明:如果主题在在被公告前就有人订阅,那么这个API将返回“not-updated”直到主题被公告。可以不用poll,只用这个函数实现数据的获取。参数:    handle:主题句柄;    updated:如果当最后一次更新的数据被获取了,检测到并设置updated为ture;返回值:    OK表示检测成功;错误返回ERROR;否则则有根据的去设置errno;eg:    if (PX4_OK != orb_check(sfd, &updated)) {        return printf("check(1) failed");    }    if (updated) {        return printf("spurious updated flag");    }    //or    bool updated;    struct random_integer_data rd;    /* check to see whether the topic has updated since the last time we read it */    orb_check(topic_handle, &updated);    if (updated) {        /* make a local copy of the updated data structure */        orb_copy(ORB_ID(random_integer), topic_handle, &rd);        printf("Random integer is now %d\n", rd.r);    }

int orb_stat(int handle, uint64_t *time)

功能:订阅者可以用来检查一个主题最后的发布时间;参数:    handle:主题句柄;    time:存放主题最后发布的时间;0表示该主题没有发布或公告;返回值:    OK表示检测成功;错误返回ERROR;否则则有根据的去设置errno;eg:    ret = orb_stat(handle,time);

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);

int orb_priority(int handle, int *priority)

功能:获取主题优先级别;参数:    handle:主题句柄;    priority:存放获取的优先级别;返回值:    OK表示检测成功;错误返回ERROR;否则则有根据的去设置errno;eg:    ret = orb_priority(handle,&priority);

4 例程

4.1 例程前准备工作
  • archives已编译完成(注:2015/10/6号后改为cmake编译系统,不再需要编译archives了);

  • 添加一个新的模块

    • 在Firmware/src/modules中添加一个新的文件夹,命名为px4_simple_app
    • 在px4_simple_app文件夹中创建module.mk文件,并输入以下内容: 
      • MODULE_COMMAND = px4_simple_app
      • SRCS = px4_simple_app.c
    • 在px4_simple_app文件夹中创建px4_simple_app.c文件
<code class="language-c++ hljs java has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @file</span> px4_simple_app.c * Minimal application example for PX4 autopilot. */</span>#include <nuttx/config.h>#include <stdio.h>#include <errno.h>__EXPORT <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> px4_simple_app_main(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> argc, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *argv[]);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> px4_simple_app_main(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> argc, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *argv[]){    printf(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Hello Sky!\n"</span>);    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> OK;}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; opacity: 0.0701001;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>
  • 注册新添加的应用到NuttShell中,并编译上传 
    • Firmware/makefiles/config_px4fmu-v2_default.mk文件中添加如下内容: 
      • MODULES += modules/px4_simple_app
    • 编译 
      • make clean
      • make px4fmu-v2_default
    • 上传到板子中 
      • make upload px4fmu-v2_default
  • 在QGC 中的Terminal(终端)中运行新应用 
    • nsh > px4_simple_app

 接下来的代码修改均是基于此应用。

4.2 订阅主题

sensor_combined主题是官方提供的通用接口标准主题。

<code class="language-c++ hljs cpp has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * @file px4_simple_app.c * Minimal application example for PX4 autopilot */</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <nuttx/config.h></span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <unistd.h></span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <stdio.h></span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <poll.h></span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <uORB/uORB.h></span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <uORB/topics/sensor_combined.h></span>__EXPORT <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> px4_simple_app_main(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> argc, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *argv[]);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> px4_simple_app_main(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> argc, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *argv[]){    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Hello Sky!\n"</span>);    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*订阅sensor_combined 主题*/</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined));     <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*一个应用可以等待多个主题,在这里只等待一个主题*/</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> pollfd fds[] = {        { .fd = sensor_sub_fd,   .events = POLLIN },        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 这里可以添加更多的文件描述符;         * { .fd = other_sub_fd,   .events = POLLIN },         */</span>    };    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> error_counter = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>) {        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*poll函数调用阻塞的时间为1s*/</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> poll_ret = poll(fds, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1000</span>);        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*处理poll返回的结果 */</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (poll_ret == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 这表示时间溢出了,在1s内没有获取到发布者的数据 */</span>            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"[px4_simple_app] Got no data within a second\n"</span>);        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (poll_ret < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 出现问题 */</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (error_counter < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> || error_counter % <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">50</span> == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* use a counter to prevent flooding (and slowing us down) */</span>                <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"[px4_simple_app] ERROR return value from poll(): %d\n"</span>                    , poll_ret);            }            error_counter++;        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (fds[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>].revents & POLLIN) {                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*从文件描述符中获取订阅的数据*/</span>                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> sensor_combined_s raw;                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* copy sensors raw data into local buffer */</span>                orb_copy(ORB_ID(sensor_combined), sensor_sub_fd, &raw);                <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"[px4_simple_app] Accelerometer:\t%8.4f\t%8.4f\t%8.4f\n"</span>,                    (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">double</span>)raw.accelerometer_m_s2[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>],                    (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">double</span>)raw.accelerometer_m_s2[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>],                    (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">double</span>)raw.accelerometer_m_s2[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>]);            }            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 如果有更多的文件描述符,可以这样:             * if (fds[1..n].revents & POLLIN) {}             */</span>        }    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; opacity: 0.0701001;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li></ul>
测试需要在QGC终端启动uORB和初始化该传感器,最后运行应用:    nsh > uorb start    nsh > sh /etc/init.d/rc.sensors    nsh > px4_simple_app &
4.3 订阅和发布主题

sensor_combined主题是官方提供的通用接口标准主题。 
vehicle_attitude主题是官方提供的通用接口标准主题。

 程序流程图如下:

pub_sub_test

<code class="language-c++ hljs cpp has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * @file px4_simple_app.c * Minimal application example for PX4 autopilot */</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <nuttx/config.h></span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <unistd.h></span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <stdio.h></span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <poll.h></span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <uORB/uORB.h></span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <uORB/topics/sensor_combined.h></span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <uORB/topics/vehicle_attitude.h></span>__EXPORT <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> px4_simple_app_main(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> argc, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *argv[]);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> px4_simple_app_main(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> argc, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *argv[]){    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Hello Sky!\n"</span>);    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 订阅 sensor_combined 主题 */</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined));    orb_set_interval(sensor_sub_fd, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1000</span>);    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 公告 attitude 主题 */</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> vehicle_attitude_s att;    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">memset</span>(&att, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(att));    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> att_pub_fd = orb_advertise(ORB_ID(vehicle_attitude), &att);    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*一个应用可以等待多个主题,在这里只等待一个主题*/</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> pollfd fds[] = {        { .fd = sensor_sub_fd,   .events = POLLIN },        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* there could be more file descriptors here, in the form like:         * { .fd = other_sub_fd,   .events = POLLIN },         */</span>    };    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> error_counter = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>) {        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* wait for sensor update of 1 file descriptor for 1000 ms (1 second) */</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> poll_ret = poll(fds, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1000</span>);        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* handle the poll result */</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (poll_ret == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* this means none of our providers is giving us data */</span>            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"[px4_simple_app] Got no data within a second\n"</span>);        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (poll_ret < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* this is seriously bad - should be an emergency */</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (error_counter < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> || error_counter % <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">50</span> == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* use a counter to prevent flooding (and slowing us down) */</span>                <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"[px4_simple_app] ERROR return value from poll(): %d\n"</span>                    , poll_ret);            }            error_counter++;        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (fds[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>].revents & POLLIN) {                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* obtained data for the first file descriptor */</span>                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> sensor_combined_s raw;                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* copy sensors raw data into local buffer */</span>                orb_copy(ORB_ID(sensor_combined), sensor_sub_fd, &raw);                <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"[px4_simple_app] Accelerometer:\t%8.4f\t%8.4f\t%8.4f\n"</span>,                    (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">double</span>)raw.accelerometer_m_s2[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>],                    (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">double</span>)raw.accelerometer_m_s2[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>],                    (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">double</span>)raw.accelerometer_m_s2[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>]);                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 赋值 att 并且发布这些数据给其他的应用 */</span>                att.roll = raw.accelerometer_m_s2[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];                att.pitch = raw.accelerometer_m_s2[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];                att.yaw = raw.accelerometer_m_s2[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>];                orb_publish(ORB_ID(vehicle_attitude), att_pub_fd, &att);            }            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* there could be more file descriptors here, in the form like:             * if (fds[1..n].revents & POLLIN) {}             */</span>        }    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; opacity: 0.0701001;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li></ul>
4.4 创建自己的主题

  官方提供的通用接口标准主题都放在了topics文件夹下了。如果要定义我们自己的主题,比如我们新添加了超声波传感器,为了将超声波传感器的数据发布出去给其他需要的应用订阅,那么久需要创建我们的主题了。

  • 主题头文件(mytopic.h) 
    • ORB_DECLARE(myTopicName);//声明一个主题
    • 定义一个存放发布数据的结构体;
  • 主题源文件(mytopic.c) 
    • ORB_DEFINE(myTopicName);//定义一个主题
    • 初始化发布数据
    • 公告主题
    • 发布主题数据

mytopic.h

<code class="language-c++ hljs cs has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 声明自定义主题,名字可以自定义,不过最好具有一定的意义,如下为随机产生整数数据 */</span>ORB_DECLARE(random_integer);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 定义要发布的数据结构体 */</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> random_integer_data {    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> r;};</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; opacity: 0.0701001;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

mytopic_publish.c

<code class="language-c++ hljs vala has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <topic.h></span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 定义主题 */</span>ORB_DEFINE(random_integer);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 待发布的主题句柄 */</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> topic_handle;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> init(){    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 随机产生一个数初始化数据结构体 */</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> random_integer_data rd = { .r = random(), };    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 公告主题 */</span>    topic_handle = orb_advertise(ORB_ID(random_integer), &rd);}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> update_topic(){    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 产生新的数据 */</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> random_integer_data rd = { .r = random(), };    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 发布主题,更新数据 */</span>    orb_publish(ORB_ID(random_integer), topic_handle, &rd);}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; opacity: 0.0701001;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>

  对于订阅者来说,就可以参考主题「4.2 订阅例程」了。不过这里还是提供下简单处理例程:

mytopic_subscriber.c

<code class="language-c++ hljs applescript has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#include <topic.h></span>/* 订阅主题的句柄*/static int topic_handle;int init(){    /* 订阅主题 */    topic_handle = orb_subscribe(ORB_ID(random_integer));}void check_topic(){    bool updated;    struct random_integer_data rd;    /* check <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">to</span> see whether <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">the</span> topic has updated <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">since</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">the</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">last</span> <span class="hljs-property" style="box-sizing: border-box;">time</span> we <span class="hljs-command" style="box-sizing: border-box;">read</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">it</span> */    orb_check(topic_handle, &updated);    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (updated) {        /* make a <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">local</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">copy</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">of</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">the</span> updated data structure */        orb_copy(ORB_ID(random_integer), topic_handle, &rd);        printf(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Random integer is now %d\n"</span>, rd.r);    }}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; opacity: 0.0701001;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>

5 参考资料

  http://www.pixhawk.com/start?id=zh/dev/px4_simple_app 
  http://www.pixhawk.com/dev/shared_object_communication 
  http://blog.arm.so/armteg/pixhawk/183-0503.html 
  http://pixhawk.org/start?id=dev/software_architecture 
  http://www.pixhawk.com/dev/add_uorb_topic?s[]=objects&s[]=common

1 0
原创粉丝点击