Pixhawk--uORB深入學習

注:本文轉載自  博主: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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章