日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

pixhawk自学笔记之uorb学习总结

發布時間:2024/4/18 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pixhawk自学笔记之uorb学习总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


注:這是看過好多文章總結出來的,轉載了較多人的博客,希望有知道原出處的人把地址留下,我貼上來。在此謝謝各位前輩的總結。(我會在后續筆記中貼出在我自己的程序中對于uorb的使用)


進程與應用程序(傳感器應用程序發送傳感器數據到姿態過濾應用程序)之間的通訊是pixhawk軟件架構的重要組成部分,進程(即所謂的節點)通過命名的總線交換消息稱之為“主題”,在pixhawk中,一個主題僅包含一種消息類型,例如:vehicle_attitude主題傳輸包含姿態結構(翻滾,俯仰和偏航估算)。節點可以在總線,主題上發布一跳消息或者訂閱總線,主題。通訊雙方之間并不知道在與誰通訊,可以存在多個發布或一條消息有多個訂閱者。這種設計模式可以防止鎖定的問題。

pixhawk的發布訂閱機制是通過“微對象請求代理”(uORB)來實現的。

快速入門:

在深入細節之前,以下是一對簡單,完整的發布/訂閱模型。發布者發布一條名為“random——integer”的主題并用隨機整數更新該主題。訂閱者檢查并打印這些更新。


[cpp] view plain copy print?
  • topic.h??
  • /*?declare?the?topic?*/??
  • ORB_DECLARE(random_integer);/*?define?the?data?structure?that?will?be?published?where?subscribers?can?see?it?*/??
  • struct?random_integer_data?{int?r;};??
  • ??
  • publisher.c??
  • #include?<topic.h>/*?create?topic?metadata?*/??
  • ORB_DEFINE(random_integer);/*?file?handle?that?will?be?used?for?publishing?*/??
  • static?int?topic_handle;??
  • int?init(){/*?generate?the?initial?data?for?first?publication?*/??
  • ????struct?random_integer_data?rd?=?{?.r?=?random(),?};/*?advertise?the?topic?and?make?the?initial?publication?*/??
  • ????topic_handle?=?orb_advertise(ORB_ID(random_integer),?&rd);??
  • }??
  • int?update_topic(){/*?generate?a?new?random?number?for?publication?*/??
  • ????struct?random_integer_data?rd?=?{?.r?=?random(),?};/*?publish?the?new?data?structure?*/??
  • ????orb_publish(ORB_ID(random_integer),?topic_handle,?&rd);??
  • }??
  • ??
  • subscriber.c??
  • #include?<topic.h>/*?file?handle?that?will?be?used?for?subscribing?*/??
  • static?int?topic_handle;??
  • int?init(){/*?subscribe?to?the?topic?*/??
  • ????topic_handle?=?orb_subscribe(ORB_ID(random_integer));??
  • }??
  • void?check_topic(){??
  • ????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);??
  • ????????}??
  • }??
  • topic.h /* declare the topic */ ORB_DECLARE(random_integer);/* define the data structure that will be published where subscribers can see it */ struct random_integer_data {int r;};publisher.c #include <topic.h>/* create topic metadata */ ORB_DEFINE(random_integer);/* file handle that will be used for publishing */ static int topic_handle; int init(){/* generate the initial data for first publication */struct random_integer_data rd = { .r = random(), };/* advertise the topic and make the initial publication */topic_handle = orb_advertise(ORB_ID(random_integer), &rd); } int update_topic(){/* generate a new random number for publication */struct random_integer_data rd = { .r = random(), };/* publish the new data structure */orb_publish(ORB_ID(random_integer), topic_handle, &rd); }subscriber.c #include <topic.h>/* file handle that will be used for subscribing */ static int topic_handle; int init(){/* subscribe to the topic */topic_handle = orb_subscribe(ORB_ID(random_integer)); } void check_topic(){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);} }

    發布:

    ? ? 發布分為三個獨立但又相關的行為;確定主題,公告主題和發布主題更新。

    ?

    確定主題:

    ? ? pixhawk系統為提供部件之前的通用接口定義了許多標準主題,如果發布者想使用標準主題和相關的數據結構不需要做額外的工作。

    ?

    自定義主題

    ? ? 要定義一個自定義主題,發布者需要提供給訂閱者一個頭文件(參考上面的topic.h),在這個頭文件中必須有:

    ? ??? ? 1.用主題的名稱做作為參數調用ORB_DECLARE()宏來定義一個實例

    ? ??? ? 2.定義一個結構體,用來描述將要用來發布的數據結構

    主題的名稱應該要具有描述性,pixhawk的管理使用下劃線來分割主題名稱為獨立的部分并且首選更通用的術語表示元件的名稱。

    ? ? 例如:raw sensor data發布在sensors_raw主題

    ?

    除了頭文件,發布者必須要具有使用ORB_DEFINE()宏在源碼中定義一個實例,當固件被構建時,他將被編譯并且鏈接到固件。

    可選主題:

    ? ??? ? 如果一個主題通過一個軟件組件來發布,那么它屬于可選主題,并且可能不會存在于發布后的固件,這種情況下,頭文件也可以改用ORB_DECLARE_OPTIONAL()宏來替代,以這種方式聲明主題,發布者不需要專門來處理什么。但在下面討論的也有額外要處理的情況,當處理可選主題時訂閱者必須要注意。

    ?

    公告主題:

    ? ??? ? 在數據被發布到一個主題前,它必須被公告,發布者可以使用下面的API來公告一個新的主題。

    [cpp] view plain copy print?
  • extern?int?orb_advertise(const?struct?orb_metadata?*meta,?const?void?*data);??
  • extern int orb_advertise(const struct orb_metadata *meta, const void *data);

    ? ? 公告也可以發布初始化數據到主題,meta參數是傳遞給API的一個指針,指向由ORB_DEFINE()宏定義好的數據,通常使用ORB_ID()宏來根據主題名稱獲取該指針。請注意,雖然主題更新可以從中斷處理函數發布,公告主題必須在常規的線程上下文中執行。

    多個發布:

    ? ??? ? 只有一個發布者可以具有發布一次一個主題,但是該主題手柄可以被關閉,因為是文件描述符,可以通過close()函數關閉。?

    發布更新:

    ? ??? ? 一旦公告了一個主題,公告主題后返回的句柄可使用下面的API來發布主題更新。

    [cpp] view plain copy print?
  • extern?int?orb_publish(const?struct?orb_metadata?*meta,?int?handle,?const?void?*data);??
  • extern int orb_publish(const struct orb_metadata *meta, int handle, const void *data); ?U ORB不換沖多個更新,當用戶檢查一個主題,他們將只能看到最新的更新。

    訂閱者:

    ? ??? ? 訂閱主題的要求如下:

    ? ??? ??? ??? ? 1.調用ORB_DEFINE()或ORB_DEFINE_OPTIONAL()宏(在訂閱者的頭文件中包含他們)

    ? ??? ??? ??? ? 2.發布到主題的數據結構定義(通常與發布者使用同一頭文件)

    ? ??? ? 如果滿足上面的條件后,訂閱者可以使用下面的api來訂閱一個主題:

    [cpp] view plain copy print?
  • extern?int?orb_subscribe(const?struct?orb_metadata?*meta);??
  • extern int orb_subscribe(const struct orb_metadata *meta);


    ?如果可選主題不存在于固件之中,訂閱到可選的主題將會失敗,但其他主題即便發布者沒有進行公告也會訂閱成功,這樣可大大降低系統對啟動順序的安排。

    ? ??? ? 這里沒有專門來限制一個任務的最大訂閱數。

    ? ??? ? 要取消訂閱一個主題,可以用下面的API:

    [cpp] view plain copy print?
  • extern?int?orb_unsubscribe(int?handle);??
  • extern int orb_unsubscribe(int handle);

    拷貝數據到主題:

    ? ??? ? 訂閱者不能引用ORB中存儲的數據或其他訂閱共享的數據,而是在訂閱者請求時從ORB拷貝數據到訂閱者的臨時緩沖區。副本拷貝的方式可以避免鎖定ORB的問題,并保持兩者之間(發布者,訂閱者)的API接口簡單。它也允許訂閱者在必要的時候直接修改拷貝副本的數據供自己使用。

    ? ??? ? 當訂閱者想要把主題中的最新數據拷貝一份全新的副本,可以使用:

    [cpp] view plain copy print?
  • extern?int?orb_copy(const?struct?orb_metadata?*meta,?int?handle,?void?*buffer);????
  • extern int orb_copy(const struct orb_metadata *meta, int handle, void *buffer);

    ?拷貝是以原子操作進行的,所以可以保證獲取到發布者最新的數據。

    檢查更新:

    ? ??? ? 訂閱者可以使用下面的API來檢查一個主題在發布者最后更新后,有沒有人調用過orb_copy來接收,處理:

    [cpp] view plain copy print?
  • extern?int?orb_check(int?handle,?bool?*updated);????????
  • extern int orb_check(int handle, bool *updated);

    ? ?如果主題在被公告前就有人訂閱,那么這個API將返回“not-updated”直到主題被公告。

    發布時間戳:

    ? ??? ? 訂閱者可以使用下面的API來檢查一個主題最后發布的時間。

    [cpp] view plain copy print?
  • extern?int?orb_stat(int?handle,?uint64_t?*time);??
  • extern int orb_stat(int handle, uint64_t *time);
    需要注意的是,要小心的使用這個調用,因為不能保證再調用返回后不久主題就不會被發布(調用返回后不久,主題可能馬上又被發布,導致最后更新時間錯誤)



    uORB的管理羅輯是通過創建線程后臺運行方式實現。

    uORB深入探索

    ? ??? ? uORB是pixhawk系統中非常重要的一個模塊,它肩負了整個系統的數據傳輸任務,所有的傳感器數據,GPS,ppm信號等都要從芯片獲取后通過uORB進行傳輸到各個模塊進行計算處理。

    ? ??? ? 1.uORB的架構簡述:

    ? ??? ???uORB是一套跨進程的IPC通訊模塊。在pixhawk中,所有的功能被獨立以進程模塊為單位進行實現并工作。而進城間的數據交互尤為重要,必須要能夠符號實時,有序的特點。

    ? ??? ? pixhawk使用nuttx實時ARM系統,而uORB對于nuttx而言,它僅僅是一個普通的文件設備對象,這個設備支持open,close,read,write,ioctl以及poll機制。通過這些接口的實現,uORB提供了一套“點對多”的跨進程廣播通訊機制。“點”指的是通訊消息的“源”,“多”指的是一個源可以有多個用戶來接受,處理。而源和用戶的關系在于,源不需要去考慮用戶是否課余i收到某條被廣播的消息或什么時候收到這條消息。它只是需要單純的把要廣播的數據推送到uORB的消息總線上,對于用戶而言,源推送了多少次的小心也不重要,重要的是取回最新的這條消息。

    ?

    ? ??? ? 2.uORB的實現位于固件源碼的src/modules/uORB/uORB.cpp文件,它通過重載CDev基類來組織一個uORB的設備實例。并且完成Read/Write等功能的重載。uORB的入口點是uorb_main函數,在這里它檢查uORB的啟動參數來完成對應的功能,uORB支持start/test/status這3條啟動參數,在pixhawk的rcS啟動腳本中,使用start參數來進行初始化,其他2個參數分別用來進行uORB功能的自檢和列出uORB的當前狀態。

    ? ??? ? 在rcS中使用start參數啟動后,uORB會創建并初始化它的設備實例,其中的實現大部分都在CDev基類完成。這個過程類似于Linux設備驅動中的Probe函數,通過init調用完成設備的創建,節點注冊以及派遣例程的設置等。

    ?

    ? ??? ? 源碼解讀:(最新版本的uORB)

    ? ??? ? uORB文件夾說明

    ? ??? ? 1.uORB文件夾結構

    2.文件/目錄說明

    ? ??? ??? ? objects_common.cpp:通用接口標準主題定義集合,如添加新主題就在這里定義。

    ? ??? ??? ? uORBMap.hpp:對象請求節點鏈表管理(驅動節點)

    ? ??? ??? ? uORBSet.hpp:對象請求節點鏈表管理(非驅動節點)

    ? ??? ??? ?Publication.cpp/?Publication.hpp:在不同的發布中遍歷使用

    ? ??? ??? ?Subscription.cpp/?Subscription.hpp:在不同的發布中遍歷使用

    ? ??? ??? ? uORB.cpp:uORB的實現

    ? ??? ??? ? uORB.h:uORB的頭文件

    ? ??? ??? ? uORBCommon.hpp:uORB公共部分變量定義實現

    ? ??? ??? ? uORBCommunicator.hpp:遠程訂閱的接口實現,實現了對不同的通信通道管理,如添加、移除訂閱者,可以基于TCP/IP或者fastRPC;傳遞給通信鏈路的實現,以提供在信道上接收信息的回調。

    ? ??? ??? ? uORBDevices_nuttx.cpp:節點操作,close,open,read,write等

    ? ??? ??? ? uORbMain.cpp:uORB入口

    ? ??? ??? ? uORBManager.hpp:uORB功能函數實現的頭文件

    ? ??? ??????uORBManager_nuttx.cpp:uORB功能函數的實現(Nuttx)

    ? ??? ??? ?uORBManager_posix.cpp:uORB功能函數的實現(Posix)

    ? ??? ??? ?uORBTest_UnitTest.cpp:uORB測試

    ? ??? ??? ??uORBTest_UnitTest.hpp:uORB測試頭文件,包括主題定義和聲明等

    總結

    以上是生活随笔為你收集整理的pixhawk自学笔记之uorb学习总结的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。