近些年無人機編隊很火熱,大家也熱衷于低成本的實現,大家看也在尋求著各種方案,很不幸,這個東西不是普通人可以玩轉的東西。當DJI 推出了可以編程的Tello以后大家都覺得看到了希望,大量的人來涌入研究這個東西,但比較遺憾,由于無人機本身在設計上面對場景的不適配,效果不好,聽見最多的聲音就是定位不準。不過無所謂,它本身已經足夠優秀了。
我去年的時候,發現了一個關于PX4+ROS設計的無人機,是一個俄羅斯的廠商。
由于都是通用器件,所以這個體積就很大。。。
不過無傷大雅,在基礎構件提供的情況下,我發現還有一個編隊的庫,哇哦,這不就是正合我意了?
簡單講下編隊的原理,有了圖案,接著將這個東西離散化,相當于線變點,這些工作都不重要,很簡單。最大的問題是,如何保持這個圖像,我們繪畫,因為是靜態的坐標,所以我們都不關注這個問題,但是無人機不是會靜止在一個地方的,而是有偏移的,也就是編隊最大的問題,相對定位的問題。
?沒辦法,想要編的過去只能解決這些問題,對于定位那是一個多傳感器融合的問題了,這里使用ROS解決。可能不是最優的,但是是暫且可以使用的。
這里使用的是,第十三個發行版,念力忍者,針對的是Ubuntu 20.04 (Focal) 版本。然后ROS運行在樹莓派上面,提供高層的服務。
在里面我也提過issue,詢問是不是可以自己做這個包,這里說可以
就像這樣
有一個web的工具
在這里
SSH的IP在這里可以設置
這里是自定義固件時候的腳本位置
這個是檢查無人機的正確性的工具
就好像這樣使用
rosrun 在啟動節點時,也可以設置參數:
語法: rosrun 包名 節點名稱 _參數名:=參數值
哥們兒今天領你看看什么叫ROS開發。rospy,你一直以為是個包,它確實是個包(放屁?)
rospy 是 ROS 的純 Python 客戶端庫。rospy 客戶端 API 使 Python 程序員能夠快速與 ROS主題、服務和參數交互。rospy 的設計有利于實現速度(即開發人員時間)而不是運行時性能,以便算法可以在 ROS 中快速原型化和測試。它也是非關鍵路徑代碼的理想選擇,例如配置和初始化代碼。許多 ROS 工具都是用 rospy 編寫的,以利用類型自省功能。
注意看,在這里被定義,源文件去ROS的Github上面找
這個是上層的安裝包,這個就是使用的catkin安裝的。
你看這個元消息,rospy是ROS的python客戶端的原生實現
里面重要的東西有話題,服務,和參數服務器,走,去看看。
主題被命名為節點交換消息的總線。主題具有匿名發布/訂閱語義,將信息的生產與消費分離。一般來說,節點不知道他們正在與誰通信。相反,對數據感興趣的節點訂閱相關主題;生成數據的節點發布到相關主題。一個主題可以有多個發布者和訂閱者。
大概就是,哥們兒我就是發消息,你愛看不看。高傲!
太狂這也
主題旨在用于單向流式通信。需要執行遠程過程調用(即接收對請求的響應)的節點應該使用服務來代替。還有用于維護少量狀態的參數服務器。
主題類型
每個主題都由用于向其發布的 ROS消息類型強類型化,節點只能接收具有匹配類型的消息。Master不強制發布者之間的類型一致性,但訂閱者不會建立消息傳輸,除非類型匹配。此外,所有 ROS 客戶端都會檢查以確保從msg 文件計算的 MD5匹配。此檢查確保 ROS 節點是從一致的代碼庫編譯的。
主題傳輸
ROS 目前支持基于 TCP/IP 和 UDP 的消息傳輸。基于 TCP/IP 的傳輸稱為TCPROS,它通過持久的 TCP/IP 連接流式傳輸消息數據。TCPROS 是 ROS 中使用的默認傳輸,并且是客戶端庫需要支持的唯一傳輸。基于 UDP 的傳輸,稱為UDPROS,目前僅在roscpp中支持,它將消息分離為 UDP 數據包。UDPROS 是一種低延遲、有損傳輸,因此最適合遠程操作等任務。
ROS 節點在運行時協商所需的傳輸。例如,如果一個節點更喜歡 UDPROS 傳輸,但另一個節點不支持它,它可以回退到 TCPROS 傳輸。隨著引人注目的用例的出現,這種協商模型可以隨著時間的推移添加新的傳輸。
rostopic list
關于現在的節點情況,你可以使用這個命令看。
實現就是這么的樸實無華,Python一擼到底
這個std_msgs是一個測試使用的東西
std_msgs 包含 ROS 原始類型的包裝器,這些包裝器記錄在msg 規范中。它還包含Empty類型,這對于發送空信號很有用。然而,這些類型并沒有傳達關于其內容的語義含義:每條消息都只是有一個名為“數據”的字段。因此,雖然此包中的消息可用于快速原型設計,但它們不適合“長期”使用。為了便于記錄和協作,我們建議使用現有消息或創建新消息,以提供有意義的字段名稱。
先看一個bool
雖然不愛英語,但是現在習慣看英語了
你看這個一個bool的定義
但是它實現起來是個宏,我也看不大懂下面的內容,參數倒是懂
大概就這樣。接下來看看服務是什么?
發布/訂閱模型是一種非常靈活的通信范式,但它的多對多單向傳輸不適用于分布式系統中經常需要的 RPC 請求/回復交互。請求/回復是通過服務完成的,該服務由一對消息定義:一個用于請求,一個用于回復。提供 ROS節點以字符串name提供服務,客戶端通過發送請求消息并等待回復來調用服務。客戶端庫通常將這種交互呈現給程序員,就好像它是一個遠程過程調用一樣。
服務是使用srv文件定義的,這些文件由 ROS 客戶端庫編譯成源代碼。
客戶端可以與服務建立持久連接,從而以降低對服務提供者更改的魯棒性為代價實現更高的性能。
服務類型
與topic一樣,服務具有關聯的服務類型,即 .srv 文件的包資源名稱。與其他基于 ROS 文件系統的類型一樣,服務類型是包名稱 + .srv文件的名稱。例如,my_srvs/srv/PolledImage.srv具有服務類型my_srvs/PolledImage。
除了服務類型之外,服務還通過.srv文件的 MD5 和進行版本控制。只有當服務類型和 MD5 和都匹配時,節點才能進行服務調用。這確保了客戶端和服務器代碼是從一致的代碼庫構建的。
接下來是參數服務器:
參數服務器是一個共享的多變量字典,可通過網絡 API 訪問。節點使用此服務器在運行時存儲和檢索參數。由于它不是為高性能而設計的,因此最好用于靜態、非二進制數據,例如配置參數。它旨在全局可見,以便工具可以輕松檢查系統的配置狀態并在必要時進行修改。
參數服務器使用 XMLRPC 實現并在 ROS Master內部運行,這意味著它的 API 可以通過普通的 XMLRPC 庫訪問。
在rospy的目錄下有兩個測試
在 rospy 程序中執行的第一個調用是對rospy.init_node()的調用,它為進程初始化 ROS 節點。rospy 進程中只能有一個節點,因此只能調用rospy.init_node()一次。
rospy.init_node('my_node_name')
rospy.init_node('my_node_name', 匿名=True)
?
在這里
在這里被定義
具體的以后有機會再看,繼續看tf2的庫的作用:
tf已經被棄用,取而代之的是tf2。tf2是轉換庫的第二代,它允許用戶隨時間跟蹤多個坐標幀。tf2在時間緩沖的樹結構中維護坐標幀之間的關系,并允許用戶在任何所需的時間點在任意兩個坐標幀之間轉換點、向量等。
機器人系統通常具有許多隨時間變化的三維坐標系,例如世界坐標系、基礎坐標系、夾具坐標系、頭部坐標系等。tf2隨時間跟蹤所有的這些坐標系,并可以解答下列問題:
①在5秒之前,頭部坐標系相對于世界坐標系在哪;
②我抓手中的物體相對于我的底座的姿態是什么;
③地圖坐標系中的基礎坐標系當前位姿是什么。
tf2 可以在分布式系統中運行。這意味著有關機器人坐標系的所有信息都可用于系統中任何計算機上的所有 ROS 組件。?tf2 可以與包含所有轉換信息的中央服務器一起運行,或者您可以讓分布式系統中的每個組件構建自己的轉換信息數據庫。
tf2_geometry_msgs
下面這些是各種的消息
這里是要check的參數
這里是寫明了一個從開機就執行的視覺任務
這個是攝像頭的參數
from clover import srvfrom std_srvs.srv import Trigger
飛行之前要導入這些的消息。
這是一個基礎的遙感消息
get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)navigate = rospy.ServiceProxy('navigate', srv.Navigate)navigate_global = rospy.ServiceProxy('navigate_global', srv.NavigateGlobal)set_position = rospy.ServiceProxy('set_position', srv.SetPosition)set_velocity = rospy.ServiceProxy('set_velocity', srv.SetVelocity)set_attitude = rospy.ServiceProxy('set_attitude', srv.SetAttitude)set_rates = rospy.ServiceProxy('set_rates', srv.SetRates)land = rospy.ServiceProxy('land', Trigger)
打印起來很簡單
print('Take off and hover 1 m above the ground')navigate(x=0, y=0, z=1, frame_id='body', auto_arm=True)
控制飛行,就是這樣的輸入參數就行。
找到了實現的CPP函數
這是一些標志位
如果是busy,那就觸發一個運行時的錯誤,接著把標志位重置,檢查狀態
又檢查一個標志位
寫了好多了,下篇繼續
cat /proc/device-tree/model
樹莓派的版本
打印一下內核
可能最快樂的事情就是catkin的logo這么好看
https://github.com/CopterExpress/clever-show
https://github.com/CopterExpress/clover
https://github.com/ros/ros
https://github.com/ros/ros_comm
https://www.ros.org/
?
編輯:黃飛
?
評論
查看更多