uorb實際上是一種設計模式中的觀察者模式,用於實現一種一對多的依賴關係,讓多個觀察者(observer)同時監聽某一主題物件(subject)。當這個主題物件(subject)的狀態發生變化時,會通知觀察者物件(observer),讓他們能夠自動更新自己。
利用uorb實現資料在不同程序中的通訊主要包括三個部分,分別是公告資料(orb_advertise函式)、發布資料(orb_publish函式)以及訂閱接收收據(orb_copy函式)。
在下面講解示範的例程功能是在乙個執行緒任務中獲取系統執行的時間戳並公告和發布出去,在另外的乙個執行緒任務中將這個資料讀取出來,並列印。程式包含兩個c檔案,分別是:receivedata.c(位於receivedata_uorb檔案下)和senddata.c(位於senddata_uorb檔案下)。
函式和執行緒任務函式 senddata_thread_main
在senddata_thread_main
函式的功能是完成時間戳資料的公告和發布,是任務的核心內容。對於所要發布的資訊首先要在src/modules/uorb/topic中新增發布資料的宣告檔案,例如本例中新增的檔案為datatrans_testvalue.h,內部包括的宣告有發布主題的結構體的宣告structdatatrans_testvalue_s和對發布主題的宣告orb_declare(datatrans_testvalue),內部還包括如下的標頭檔案引用:
#ifndeftopic_datatrans_testvalue_h_
(需要根據發布的主題進行對應的名稱修改)
#definetopic_datatrans_testvalue_h_
(需要根據發布的主題進行對應的名稱修改)
#include
#include
#include"../uorb.h"
宣告主題之後,在src/modules/uorb/objects_common_cpp檔案中加入:
#include"topics/offboard_control_setpoint.h"
orb_define(offboard_control_setpoint,structoffboard_control_setpoint_s);
語句,完成主題的定義。
定義好主題之後就可以在senddata_thread_main函式中呼叫這個主題,首先建立對應主題的結構體用於資料傳送,本例名稱為pttv:
structdatatrans_testvalue_s pttv;
//建立傳送資料結構體
然後對結構體內的資料進行初始化,元素賦值為0。
memset(&pttv, 0,sizeof(pttv));
//資料清零
對發布主題進行公告,同時獲得公告主題的控制代碼
orb_advert_t
pttv_pub = orb_advertise(orb_id(datatrans_testvalue), &pttv);
最後用orb_publish函式結合之前獲得的主題id和控制代碼資訊以及結構體完成資料發布。
orb_publish(orb_id(datatrans_testvalue), pttv_pub, &pttv);
至此,資料發布完畢。為了滿足編譯的條件,我們要分別在receivedata_uorb檔案和senddata_uorb檔案下建立module.mk檔案。寫入:
module_command
srcs
= senddata.c
在senddata_thread_main函式的功能是完成資料的訂閱。首先獲得訂閱主題控制代碼:
intdatarec_sub_fd = orb_subscribe(orb_id(datatrans_testvalue));
然後設定訂閱查詢的時間間隔:
orb_set_interval(datarec_sub_fd, 1000);
//時間單位為毫秒
建立poolfd結構體,用於查詢裝置狀態:
structpollfd fds[1] = }; 設定
pool
函式呼叫的阻塞時間為5秒
receive_pool_ret=poll(fds, 1, 5000);
//返回值:
0 表示未更新資料,<
0表示資料更新錯誤
,其他表示主題的狀態發生了改變
用if(fds[0].
revents
& pollin)
語句判斷訂閱主題產生了更新。
最後建立主題結構體用於存放訂閱資料:
structdatatrans_testvalue_s ttv;
然後對結構體資料初始化,賦值0:
memset(&ttv, 0,sizeof(ttv)); 利用
orb_copy
函式接受的訂閱的主題:
orb_copy
(orb_id(datatrans_testvalue), datarec_sub_fd , &ttv);
列印更新的主題:
printf
("[receivedata] timestap is :\%llu\n"
,ttv.
timestamp);
至此,接收主題
完畢。為了滿足編譯的條件,我們要分別在receivedata_uorb檔案下建立module.mk檔案。寫入:
module_command
srcs
= receivedata.c
最後,在
makefiles/config_px4fmu_deafult.mk
檔案中加入:
modules +
= examples/receivedata_uorb_test
modules +
= examples/senddata_uorb_test
編譯,燒寫。
開啟tera term控制台。執行如下語句後,
時間戳主題開始傳送:
senddata
執行如下語句後,開始訂閱時間戳主題,並列印資訊:
receivedata
利用反射機制實現工廠模式
細節 命名規則類,介面名稱都得大寫 寫完 記得格式化,就算是測試 貼出來也是給人看的。不能太水。inte ce fruit public void eat class orange implements fruit class factory catch exception e return f c...
利用Remoting實現非同步佇列機制
很多需要提高應用效能 提高立即響應速度 但不立即處理 提高吞吐能力 提公升使用者體驗 的場景,都採用非同步處理的機制,net 中可能用 msmq 的實現樣例不少,其實自行實現非同步佇列並不複雜。最近有兩個專案組的同事向我要了類似的關於實現非同步佇列的方法,於是翻出了兩年以前寫的實現 sp 與運營商簡...
Qt利用反射機制實現函式呼叫
qt本身就帶有強大的反射功能,如果想通過函式名稱字串呼叫函式,需要在被呼叫的函式前新增巨集 q invokable定義乙個基類 pragma once include class qtinvoke public qobject include qtinvoke.h include qtinvoke ...