將 TXD, RXD 短路:
操作:
-n
用於提示使用 TCP/IP 連線
-v
用於是否印出訊息提示接收到的封包。
-s
後接 USB-TTL 裝置的路徑
-b
後接序列埠的 Baudrate
-i
後接 IP 位址
-b
後接網路 Port number (埠號)
由於 MAVLink 使用 XML 定義並以 Codegen 產生程式碼,因此各個飛控專案/廠商可以逕行擴充。在產生程式碼前必須先取得目標平台的 XML 檔。基本上大型的 Open-source 專案皆可在 MAVLink 官方 GitHub 頁面找到。
以下給出 Codegen 產生程式碼的操作流程:
這裡我們指定了 common.xml
,即 PX4 的封包定義。而 pymavlink 中的 mavgen.py
即是 Codegen 程式本體。另外這裡也提供預先產生好的結果。
註: 下述的範例程式已包含了 MAVLink 程式碼,不需要再額外產生。
在 MAVLink 中無論是發送或是接收,都僅是操作以下的資料結構:
以下幾個部分值得注意:
Remark: 透過檢查 SYS ID 和 COMP ID 可以確定封包的來源。
詳細說明可見: Packet Serialization
範例程式使用了兩個執行緒處理 MAVLink 封包 (Message) 的收發。
mavlink_parse_char()
函式進行解碼recvd_msg
透過 Message queue 傳至 mavlink_tx_thread()
中做出回應MSG_SCHEDULER_INIT()
和 MSG_SEND_HZ()
巨集函式控制)mavlink_rx_thread
接收到 (解出) 的封包並進行回應。
parse_mavlink_msg()
是用於根據接收到的 Message ID 觸發對應的 MAVLink Handler,若是跟 Microservice 有關則必須再改變對應的狀態機狀態。mavlink_tx_thread()
每 10ms 僅能觸發一次,用以限制 CPU 資源使用 (經驗上來說 100Hz 以足夠充分使用)mavlink_parser.c
中新增 MAVLink handler function 用於回應接收到的封包
mav_heartbeat()
處理我們以 mavlink_send_play_tune()
說明封包的發送過程:
以下拆成三個步驟說明:
play_tune
封包所需參數。mavlink_msg_play_tune_v2_pack()
將參數設定至 mavlink_message_t msg
並在進行了諸如設定 Message ID、計算 Checksu 等工作。mavlink_send_msg()
發送至目標裝置。而 mavlink_send_msg()
則是透過 mavlink_msg_to_send_buffer()
將 mavlink_message_t msg
序列化 (Serialization) 轉為 Byte array 後以 write()
送出資料:
另外 mavlink_send_play_tune()
將 format
設定為 TUNE_FORMAT_MML_MODERN (1)
, 因此 tune 的字串必須以 Music Macro Language 格式表達。
繁中維基百科的條目給出了詳細易懂的說明:
CDEFGAB
: 依序表示 Do Re Mi Fa So La Si,後接 #
或 +
為升記號、-
為降記號。R
: 休止符。O
: 指定在哪個八度演奏,影響音調高低。>
、<
: 控制樂譜高八度(>
)或低八度(<
)。L
: 音符時值 (四分音符等)。V
: 指定音量大小,後接的數字指定演奏樂器之音量大小。T
: 指定樂器的速度。例如「T120」表示以120BPM來演奏。最後,關於封包的詳細定義請見: PLAY_TUNE_V2 (#400)。
MAVLink 定義了許多 Microservice (即需要時序控制的通訊)。本章節錄並以 Gimbal Protocol (v2) 為例說明開發一個 Microservice 程式的大致流程。
基本術語:
雲台的連接有三種可能的拓樸結構:
1. 飛控直連雲台 架構:
2. 獨立式雲台 (Standalone Integrated Camera / Gimbal) 架構:
3. 飛控 - 協同電腦 - 雲台裝置 架構:
其中:
Gimbal Manager Message
是給 Gimbal 管理/控制程式之指令封包Gimbal Device Message
是給 Gimbal 裝置本體之指令封包以下第三種拓樸結構 (飛控 - 協同電腦 - 雲台裝置) 作為說明。
如上所述,考慮第三種拓樸,假設要設計協同電腦上的 MAVLink 程式:
Gimbal Manager Message
協議交換資訊。Gimbal Device Message
通訊以下為 Gimbal Protocol (v2) 定義的四種流程 (Sequence):
1. 裝置探索 (Discovery):
2. 一般手動操作 (Normal Manual Control):
指的是透過操作者透過地面站或是遙控器 (RC, Remote Controller) 控制雲台。
3. 透過地面站設定感興趣區間 (ROI, Region of Interest)
4. 透過自動飛行任務排程的姿態設定 (Attitude Set During Mission):
Caveat: 官方給的圖應該有誤: 沒有 CMD_DO_GIMBAL_MANAGER_ATTITUDE
,只有 CMD_DO_GIMBAL_MANAGER_PITCHYAW
。
不過根據圖的繪製來說,此封包的發送應可不用實作出來。
MAVLink 的 Command 有分 COMMAND_LONG (#76) 和 COMMAND_INT (#75)。前者的7個參數欄位都是 float
型態,後者的第1, 2, 3, 4, 7欄是float,5和6是 int32_t
型態。
COMMAND_INT (#75) 主要用於 GPS 相關的指令,因為在儲存經緯度上,int32_t
較 float
有更高的精度優勢。除此之外絕大多數的功能都是使用 COMMAND_LONG (#76)。
COMMAND_LONG 的接收處理程式如下:
實際上就是經 3-4 章介紹之 parse_mavlink_msg()
函式觸發 mav_command_long()
後再根據mav_cmd_long.command
的數值選擇對應的處理函式。
我們以上述 透過地面站設定感興趣區間 (ROI, Region of Interest) 的協議進行說明
首先根據圖示可知 mavlink_parser.c
中必須先增加以下幾個封包的處理函式:
COMMAND_LONG (#76)
→ MAV_CMD_DO_SET_ROI_LOCATION (195)
GIMBAL_DEVICE_ATTITUDE_STATUS (#285)
COMMAND_LONG (#76)
→ MAV_CMD_DO_SET_ROI_NONE (197)
接著便可採 Event-driven 架構撰寫程式並做出適當的回應 (如發送封包回應)。
但實做上可能還須考量:
COMMAND_ACK (#77)
時的處理情況1 須根據開發者自行斟酌,以下說明 情況2:
由於 COMMAND_ACK (#77)
的回傳值包含 ACCEPTED
、DENIED
等 (見MAV_RESULT),而目標程式可能因資料遺失等重新要求,因此會需要保存特定資料。
顯然的,在此處 Gimbal 的案例中 COMMAND_ACK (#77)
的結果是依據GIMBAL_DEVICE_ATTITUDE_STATUS (#285)
而定的:
即使 MAV_CMD_DO_SET_ROI_NONE (197)
被多次觸發,Gimbal Manager 也應該有辦法正確回應 COMMAND_ACK (#77)
封包。