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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

pixhawk自学笔记之uorb学习总结

發(fā)布時(shí)間:2024/4/18 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pixhawk自学笔记之uorb学习总结 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.


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


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

pixhawk的發(fā)布訂閱機(jī)制是通過(guò)“微對(duì)象請(qǐng)求代理”(uORB)來(lái)實(shí)現(xiàn)的。

快速入門:

在深入細(xì)節(jié)之前,以下是一對(duì)簡(jiǎn)單,完整的發(fā)布/訂閱模型。發(fā)布者發(fā)布一條名為“random——integer”的主題并用隨機(jī)整數(shù)更新該主題。訂閱者檢查并打印這些更新。


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

    發(fā)布:

    ? ? 發(fā)布分為三個(gè)獨(dú)立但又相關(guān)的行為;確定主題,公告主題和發(fā)布主題更新。

    ?

    確定主題:

    ? ? pixhawk系統(tǒng)為提供部件之前的通用接口定義了許多標(biāo)準(zhǔn)主題,如果發(fā)布者想使用標(biāo)準(zhǔn)主題和相關(guān)的數(shù)據(jù)結(jié)構(gòu)不需要做額外的工作。

    ?

    自定義主題

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

    ? ??? ? 1.用主題的名稱做作為參數(shù)調(diào)用ORB_DECLARE()宏來(lái)定義一個(gè)實(shí)例

    ? ??? ? 2.定義一個(gè)結(jié)構(gòu)體,用來(lái)描述將要用來(lái)發(fā)布的數(shù)據(jù)結(jié)構(gòu)

    主題的名稱應(yīng)該要具有描述性,pixhawk的管理使用下劃線來(lái)分割主題名稱為獨(dú)立的部分并且首選更通用的術(shù)語(yǔ)表示元件的名稱。

    ? ? 例如:raw sensor data發(fā)布在sensors_raw主題

    ?

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

    可選主題:

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

    ?

    公告主題:

    ? ??? ? 在數(shù)據(jù)被發(fā)布到一個(gè)主題前,它必須被公告,發(fā)布者可以使用下面的API來(lái)公告一個(gè)新的主題。

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

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

    多個(gè)發(fā)布:

    ? ??? ? 只有一個(gè)發(fā)布者可以具有發(fā)布一次一個(gè)主題,但是該主題手柄可以被關(guān)閉,因?yàn)槭俏募枋龇?#xff0c;可以通過(guò)close()函數(shù)關(guān)閉。?

    發(fā)布更新:

    ? ??? ? 一旦公告了一個(gè)主題,公告主題后返回的句柄可使用下面的API來(lái)發(fā)布主題更新。

    [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不換沖多個(gè)更新,當(dāng)用戶檢查一個(gè)主題,他們將只能看到最新的更新。

    訂閱者:

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

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

    ? ??? ??? ??? ? 2.發(fā)布到主題的數(shù)據(jù)結(jié)構(gòu)定義(通常與發(fā)布者使用同一頭文件)

    ? ??? ? 如果滿足上面的條件后,訂閱者可以使用下面的api來(lái)訂閱一個(gè)主題:

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


    ?如果可選主題不存在于固件之中,訂閱到可選的主題將會(huì)失敗,但其他主題即便發(fā)布者沒(méi)有進(jìn)行公告也會(huì)訂閱成功,這樣可大大降低系統(tǒng)對(duì)啟動(dòng)順序的安排。

    ? ??? ? 這里沒(méi)有專門來(lái)限制一個(gè)任務(wù)的最大訂閱數(shù)。

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

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

    拷貝數(shù)據(jù)到主題:

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

    ? ??? ? 當(dāng)訂閱者想要把主題中的最新數(shù)據(jù)拷貝一份全新的副本,可以使用:

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

    ?拷貝是以原子操作進(jìn)行的,所以可以保證獲取到發(fā)布者最新的數(shù)據(jù)。

    檢查更新:

    ? ??? ? 訂閱者可以使用下面的API來(lái)檢查一個(gè)主題在發(fā)布者最后更新后,有沒(méi)有人調(diào)用過(guò)orb_copy來(lái)接收,處理:

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

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

    發(fā)布時(shí)間戳:

    ? ??? ? 訂閱者可以使用下面的API來(lái)檢查一個(gè)主題最后發(fā)布的時(shí)間。

    [cpp] view plain copy print?
  • extern?int?orb_stat(int?handle,?uint64_t?*time);??
  • extern int orb_stat(int handle, uint64_t *time);
    需要注意的是,要小心的使用這個(gè)調(diào)用,因?yàn)椴荒鼙WC再調(diào)用返回后不久主題就不會(huì)被發(fā)布(調(diào)用返回后不久,主題可能馬上又被發(fā)布,導(dǎo)致最后更新時(shí)間錯(cuò)誤)



    uORB的管理羅輯是通過(guò)創(chuàng)建線程后臺(tái)運(yùn)行方式實(shí)現(xiàn)。

    uORB深入探索

    ? ??? ? uORB是pixhawk系統(tǒng)中非常重要的一個(gè)模塊,它肩負(fù)了整個(gè)系統(tǒng)的數(shù)據(jù)傳輸任務(wù),所有的傳感器數(shù)據(jù),GPS,ppm信號(hào)等都要從芯片獲取后通過(guò)uORB進(jìn)行傳輸?shù)礁鱾€(gè)模塊進(jìn)行計(jì)算處理。

    ? ??? ? 1.uORB的架構(gòu)簡(jiǎn)述:

    ? ??? ???uORB是一套跨進(jìn)程的IPC通訊模塊。在pixhawk中,所有的功能被獨(dú)立以進(jìn)程模塊為單位進(jìn)行實(shí)現(xiàn)并工作。而進(jìn)城間的數(shù)據(jù)交互尤為重要,必須要能夠符號(hào)實(shí)時(shí),有序的特點(diǎn)。

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

    ?

    ? ??? ? 2.uORB的實(shí)現(xiàn)位于固件源碼的src/modules/uORB/uORB.cpp文件,它通過(guò)重載CDev基類來(lái)組織一個(gè)uORB的設(shè)備實(shí)例。并且完成Read/Write等功能的重載。uORB的入口點(diǎn)是uorb_main函數(shù),在這里它檢查uORB的啟動(dòng)參數(shù)來(lái)完成對(duì)應(yīng)的功能,uORB支持start/test/status這3條啟動(dòng)參數(shù),在pixhawk的rcS啟動(dòng)腳本中,使用start參數(shù)來(lái)進(jìn)行初始化,其他2個(gè)參數(shù)分別用來(lái)進(jìn)行uORB功能的自檢和列出uORB的當(dāng)前狀態(tài)。

    ? ??? ? 在rcS中使用start參數(shù)啟動(dòng)后,uORB會(huì)創(chuàng)建并初始化它的設(shè)備實(shí)例,其中的實(shí)現(xiàn)大部分都在CDev基類完成。這個(gè)過(guò)程類似于Linux設(shè)備驅(qū)動(dòng)中的Probe函數(shù),通過(guò)init調(diào)用完成設(shè)備的創(chuàng)建,節(jié)點(diǎn)注冊(cè)以及派遣例程的設(shè)置等。

    ?

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

    ? ??? ? uORB文件夾說(shuō)明

    ? ??? ? 1.uORB文件夾結(jié)構(gòu)

    2.文件/目錄說(shuō)明

    ? ??? ??? ? objects_common.cpp:通用接口標(biāo)準(zhǔn)主題定義集合,如添加新主題就在這里定義。

    ? ??? ??? ? uORBMap.hpp:對(duì)象請(qǐng)求節(jié)點(diǎn)鏈表管理(驅(qū)動(dòng)節(jié)點(diǎn))

    ? ??? ??? ? uORBSet.hpp:對(duì)象請(qǐng)求節(jié)點(diǎn)鏈表管理(非驅(qū)動(dòng)節(jié)點(diǎn))

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

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

    ? ??? ??? ? uORB.cpp:uORB的實(shí)現(xiàn)

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

    ? ??? ??? ? uORBCommon.hpp:uORB公共部分變量定義實(shí)現(xiàn)

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

    ? ??? ??? ? uORBDevices_nuttx.cpp:節(jié)點(diǎn)操作,close,open,read,write等

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

    ? ??? ??? ? uORBManager.hpp:uORB功能函數(shù)實(shí)現(xiàn)的頭文件

    ? ??? ??????uORBManager_nuttx.cpp:uORB功能函數(shù)的實(shí)現(xiàn)(Nuttx)

    ? ??? ??? ?uORBManager_posix.cpp:uORB功能函數(shù)的實(shí)現(xiàn)(Posix)

    ? ??? ??? ?uORBTest_UnitTest.cpp:uORB測(cè)試

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

    總結(jié)

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

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。