目前你要知道的一點(diǎn)是,ROS說到底就是一個接收和發(fā)送的過程,這里就先對發(fā)送的信息來一個打包了。
這里需要看一下無人機(jī)的SDK來構(gòu)建這個東西。
?
- ?
https://dl.djicdn.com/downloads/RoboMaster%20TT/Tello_SDK_3.0_User_Guide_cn.pdf
?
官網(wǎng)有,自取
?
?
目前先了解這個就行
?
?
視頻流也是需要的
?
?
我們先建立一個這樣的文件夾
?
?
把我們需要得信息來封裝一下,ROS得Msg是固定的幾種
?
?
WIFI的配置也有
?
?
在Cmake里面寫好我們要編譯的信息
?
ROS終歸就是個軟件的框架,最終的還是需要一個語言去落實(shí),這里就編譯成C++的。
?
?
XML文件呢,就是這個包的身份證,編譯的時候依賴誰,包的作用等等
?
?
對一個機(jī)器人來說,我們需要控制的對吧?
?
顯示無人機(jī)圖像并提供鍵盤控制。
?T 用于起飛,L 用于降落無人機(jī),F(xiàn) 用于向前翻轉(zhuǎn),E 用于緊急停止,WASD 和箭頭用于控制無人機(jī)運(yùn)動。
?
?
SDK中獲得我們的控制命令
?
?
在具體的寫以前,我想讓大家這里這個控制文件的一個宏觀的設(shè)計(jì)
?
?
頭寫上
?
?
我們需要C++的ROS2控制庫
?
?
附有完整的API,使用的時候記得多查
?
假如你不查,我覺得就是欠揍,你咋個那么厲害喲~
關(guān)ROS中常用的消息。包括動作消息 (actionlib_msgs)、診斷 (diagnostic_msgs)、幾何圖元 (geometry_msgs)、機(jī)器人導(dǎo)航 (nav_msgs) 和常見傳感器 (sensor_msgs),例如激光測距儀、相機(jī)、點(diǎn)云。
?
?
這里有用這個
?
這表示自由空間中的速度,分為線性部分和角度部分。你等我寫完這些就閱讀ROS的源碼。
?
這個消息包的作用是:隔離消息以在共享依賴關(guān)系中的堆棧之間進(jìn)行通信允許依賴堆棧中的節(jié)點(diǎn)進(jìn)行通信,而無需相互依賴。該堆棧被設(shè)計(jì)為包含多個堆棧之間使用的最常見消息,以提供共享依賴關(guān)系,從而消除有問題的循環(huán)依賴關(guān)系。
?
?下面的代碼是:ROS 主題發(fā)布,你別問為什么這么寫,因?yàn)閯e人也是這樣寫的。
?
這里是ROS2的寫法
ROS1到ROS2的很多消息定義類似,大部分一樣只是多了一個msg域
我自己說的(夸我)
- ?
?
這也是變化
?
?
才學(xué)兩天模板就出來搞這了
?
ROS1的定時器使用的是while,二代就牛逼了一些。
?
每個節(jié)點(diǎn)都有一個句柄列表(與計(jì)時器、訂閱者、客戶端、服務(wù)、等待對象相關(guān)),這些句柄被放入等待集中。每當(dāng)節(jié)點(diǎn)旋轉(zhuǎn)(執(zhí)行周期)時,都會檢查此等待集以查看是否準(zhǔn)備好執(zhí)行任何操作。
?
對于計(jì)時器,這僅僅意味著檢查計(jì)時器是否“過期”-> 如果是,則執(zhí)行回調(diào)。
對于訂閱,可以將其想象成 rcl 層詢問 rmw 是否在 DDS 級別發(fā)生了任何事情,例如接收消息。
?
但基本上,節(jié)點(diǎn)只是檢查是否為正確類型的回調(diào)觸發(fā)了正確的事件?;卣{(diào)中的內(nèi)容無關(guān)緊要。你可以在里面放任何東西。
?
?
這個函數(shù)的原型
?
?
看參數(shù)就行
?
?
接著我們就可以寫出這樣的代碼,媽的,這就好像我教你1+1,但是留作業(yè)是微積分的樣子,但是寫程序就是這樣。事實(shí)上還有一段回調(diào)沒有寫,開始~
還是先解釋一下這個東西,我們設(shè)計(jì)了一個節(jié)點(diǎn),這個節(jié)點(diǎn)不停的發(fā)送SDK里面的指令。里面的命令在外部被訂閱,收到就會執(zhí)行任務(wù)。
?
之后里面搞了一個定時器。1ms看看有沒有東西發(fā)生,或者這樣說吧,1ms就看看回調(diào)函數(shù)有沒有活干,我想回調(diào)函數(shù)是罵罵咧咧的。
回調(diào)函數(shù)摸頭,定時器你禮貌嗎?
我之前是個土狗,沒有用過回調(diào)函數(shù),曾經(jīng)看過很多的文章,正經(jīng)的不正經(jīng)的都有,但是拋開一切?;卣{(diào)函數(shù)無非就是個等候調(diào)用的小老弟。說大白話有點(diǎn)不裝逼,來一段拽一些的:顧名思義,回調(diào)函數(shù)就是回頭再調(diào)用它?;卣{(diào)函數(shù)其實(shí)就是一個參數(shù),將這個函數(shù)作為參數(shù)傳到另一個函數(shù)里面,當(dāng)那個函數(shù)執(zhí)行完之后,再執(zhí)行傳進(jìn)去的這個函數(shù)。這個過程就叫做回調(diào)。
這里我也決定把我的筆記分享給大家:
?
?
?
看懂了嗎?
?
?
在你假裝看懂的基礎(chǔ)上繼續(xù)看這個回調(diào)函數(shù):
?
?
先看個大的
?
?
這些是OpenCV的東西,就是先搞個控制的照片,填充窗口,然后就是創(chuàng)建,顯示啥的。15ms看看有沒有按鍵按下,還記得我前面的東西嗎?
?
?
就看一個,如果按鍵按下
?
?
就把信息發(fā)出去
?
?
如果都沒有就調(diào)用手動的函數(shù),媽的,老母豬戴胸罩,一套又一套,再寫個函數(shù)。
?
?
沒啥好說的,把來自鍵盤的信息發(fā)出去
?
?
發(fā)給這個
?
?
最后這個信息發(fā)的時候注意組裝
?
?
最后收尾,漂亮~
?
?
添加的編譯文件
?
?
在上面寫一下關(guān)于OpenCV的依賴項(xiàng)
?
內(nèi)容準(zhǔn)備的有點(diǎn)多的了。。。接下來一個Node,用于控制DJI Tello無人機(jī)的軟件包,根據(jù)DJI提供的官方SDK提供數(shù)據(jù)和對無人機(jī)的控制。
?
?
還是先看看組織的樣子
?
這個東西有點(diǎn)復(fù)雜,我怕我寫不下去。
?
?
先導(dǎo)入庫
?
?
代碼有點(diǎn)長,倒著看,就是一個節(jié)點(diǎn)的啟動
?
?
四元到歐拉
?
?
歐拉到四元
?
我不講這個,因?yàn)槲覀兪茿PP不是算法文章,下次講,而且這兩個函數(shù)是可以復(fù)用的。
?
?
節(jié)點(diǎn)里面有這些函數(shù)
?
?
節(jié)點(diǎn)一開始內(nèi)置的參數(shù),不要改動。主要是連接的信息
?
?
把內(nèi)部的參數(shù)獲取,進(jìn)行類型的轉(zhuǎn)換
?
?
這里看這個,因?yàn)橹黝}是單目的SLAM,所以鏡頭的參數(shù)就很重要了
?
?
相機(jī)的參數(shù)是可以從外部獲取的
?
?
這些參數(shù)是哪里來的額?是使用關(guān)于標(biāo)定的ROS包搞來的
?
?
這里就會把外部標(biāo)定的數(shù)據(jù)傳給變量。
?
?
這個是外部的Tello控制包,下次我給你解讀
?
?
和日志功能連用,來告訴操作者(就是我,連接情況)
?
?
一個節(jié)點(diǎn)的收發(fā)功能也啟動到位
?
?
三大線程也啟動
?
?
無人機(jī)準(zhǔn)備起飛!
?
?
發(fā)布的節(jié)點(diǎn)是這樣的,應(yīng)該可以看的明白把。有圖像,鏡頭標(biāo)定信息,Tello的狀態(tài),ID,IMU的數(shù)據(jù),電池,溫度,里程計(jì)等,后面還有坐標(biāo)的廣播。
?
?
訂閱的是外部的信息,起飛?迫降,控制啥的,翻跟頭
?
?
就是ROS之間,信息的傳輸都是標(biāo)準(zhǔn)的信息,所以這里需要進(jìn)行一個信息的轉(zhuǎn)換,對于CV來說,思路就是按照順序,追蹤著視頻流走就好,這里就是一個信息的捕獲,轉(zhuǎn)換,發(fā)送,而且是作為線程處理的一個函數(shù)。
?
?
另外一個是無人機(jī)的信息線程
?
?
死鎖發(fā)送
?
?
一個電源的節(jié)點(diǎn),其實(shí)有很多的信息,有不變的,有變的,大家都會發(fā)出來,但是你具體的使用,都要去選擇的訂閱, 不然我怎么知道你要啥信息,信息是從tello搞來的
?
?
tello的狀態(tài)是這樣的,注意看我選擇的關(guān)鍵詞,tello都是外部獲得的。感興趣的姿態(tài)信息都有了,
?
?
相機(jī)的信息是yaml里面存的,就像外掛一樣,也一起發(fā)送了。
?
?
剩下就是里程計(jì)的發(fā)送線程了
?
?
里程計(jì)說到底就是距離和角度,自己看要啥
?
?
這個相當(dāng)于Util函數(shù),寫幾個和機(jī)器本身相關(guān)的函數(shù)
?
?
可以通過這樣的信息,搭配RC指令來精確的控制俺們的小機(jī)機(jī)
?
本來應(yīng)該上機(jī)給大家展示一下編譯過程的,但是我好累,明天文章的開頭展示,這里放上編譯的腳本:
?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
cd ../workspace
rm -rf build install log
rosdep install -i --from-path src
colcon build --symlink-install --packages-select tello tello_control tello_msg
# 表示編譯時如果 install 中文件已經(jīng)存在于 src 或者 build 文件夾中,
#?就用超鏈接指向該文件,避免浪費(fèi)空間,也可以實(shí)現(xiàn)同步更新
評論
查看更多