MAVLink筆記 #02# MAVLink絕對傻瓜教程(譯)

本文譯自Shyam Balasubramanian所寫的MavLink Tutorial for Absolute Dummies (Part –I) , 2013。僅供學習交流。
linux

MavLink是什麼鬼?它是一種通訊協議。當看到這個概念後,大夥就開始畏懼它。這個教程將迫使你深入地領悟它,並通俗易懂地闡述它到底是什麼,它是如何工做的,最重要的是它究竟是如何工做的!!我將試着解釋Mission Planner如何與APM/ PX4通訊,反之亦然。這將有助於你的擴展,並激發你潛在的天才程序員天賦,若是你還沒激發的話!!git

PS. Mission Planner是一款開源的無人機地面站軟件,APM/ PX4則分別爲兩種飛控固件(相似於windows和linux的關係)。而pixhawk是飛控硬件,它能夠安裝上述兩種固件中的任何一個。程序員

本教程假定:github

  1. 你是個小白☹我曾經也是,但如今再也不是了!編程

  2. 你至少在C語言方面具有必定的編程技能(例如,在C/C++/C#/Java中編寫過簡單的switch cases)。若是你已是專業級,那麼return 0;windows

  3. 你很嚴肅地打算去學習知識,由於你將爲此失去一些睡眠!安全

但無論怎樣,請始終保持學習的意願,我衷心但願你永遠不會忘記這一點🙂我能夠開始了嗎?數據結構

我爲你而來,MavLink

Mavlink消息基本上是由Mission Planner(MP)編碼,並經過USB串行或遙測發送到APM的一串字節(二者不能同時使用。若是同時插入,則優先選擇USB,而忽略遙測)。這裏的編碼並無什麼特別之處,只是把數據包放入一個數據結構中,而後經過信道以字節的形式發送出去,同時加上一些錯誤糾正。函數

MavLink消息的結構:

每一個MavLink數據包的長度爲17字節,結構以下:工具

消息長度 = 17 (6 bytes header + 9 bytes payload + 2 bytes checksum)
長度爲6個字節的首部 header 0. message header, 永遠爲 0xFE
1. message length (9) 2. sequence number -- 在 2550 之間輪轉(0x4e,前一個是 0x4d) 3. System ID - 什麼系統在發送這個消息 (1) 4. Component ID- 系統的哪一個組件正在發送消息 (1) 5. Message ID (例如 0 = heartbeat 等等! 別害羞,你也能夠添加..) 可變長的有效負載 Payload (由八位組構成, 範圍是 0..255) ** Payload (咱們感興趣的實際數據) 校驗和 Checksum: 用於錯誤檢測

PS. 「由八位組構成」在原文中是specified in octet 1

(APM以及地面站)軟件所作的事情是,檢查它是否爲一個有效的消息(經過檢查Checksum判斷消息是否已損壞,丟棄已經損壞的消息)。這是遙測的波特率爲何設置爲57,600而不是115,200 bps的緣由之一。該數值越低,軟件容易發生的錯誤就越少,雖然消息更新到地面站的速度會慢一些。若是你想在採用MavLink協議的同時取得更遠點的距離,進一步下降波特率多是一個好主意。然而,須要注意的是,通過測試,57,600bps在理論上能夠經過3DR遙測無線電提供大約一英里半徑的覆蓋範圍。還記得高中時的信噪比(SNIR)的概念嗎?

如今,根據上面的內容,咱們感興趣的東西是:

  • System ID(亦稱消息的來源):這是指經過無線遙測或USB端口向APM發送消息的發送源(也就是MP),軟件會按期進行檢查,以確認消息是發送給它的。

  • Component ID (亦稱系統中的子系統):主系統中的任何子系統。目前,這裏並無子系統,咱們也沒有真正利用這個字段。

  • Message ID:標識這是條關於什麼的信息。在本教程中,咱們將其稱爲「主消息(main message)」。

  • Payload(實際數據):這就是肉!這就是你想要的!!

MavLink究竟是如何工做的

MavLink啥也不是就是一條消息。MavLink也能夠用於地面機器人,因此微型飛行器鏈路(Micro Aerial Vehicle Link,也就是MavLink) 並非一個十分貼切的名字。之因此採起這種方式命名呢,是由於它起始於直升機(若是我沒猜錯的話)。

「消息」是一個包含「常量字節數」(如前所述,即17字節)的數據包。APM(從空中)獲取流字節,將其傳輸到硬件接口(例如,經過UART或遙測),並在軟件中對消息進行解碼。注意,消息包含着咱們即將提取的有效負載(payload)

咱們對有效負載很感興趣,可是,嘿,和有效負載在一塊兒的是Message ID(見上面),咱們能夠經過它瞭解有效負載表明着什麼。在這以前,先看看程序解釋一切MavLink消息的幾個步驟:

  1. 咱們有一個名爲handlemessage (msg)的方法。這個就是你須要學習和了解的方法!在GCS_MavLink.pde中找到它(在Arducopter/ ArduPlane裏)。

    PS. 該方法隸屬APM固件的源代碼。GCS_MavLink.pde如今彷佛是這個https://github.com/ArduPilot/ardupilot/blob/8f550ffdd48a3165c115ca24d6ce5227a5f826d1/ArduCopter/GCS_Mavlink.cpp

    它基本上是在問信息包:嘿,你是誰?你是爲我而來仍是試圖侵入個人系統?在我給予你許可以前,讓我先讀一下你的系統ID和組件ID任何使用MavLink的系統都有一個系統ID和組件ID。例如,你的MP和正在飛行的四軸飛行器將具備相同的系統ID。組件ID則用於附加到APM/PX4的「子系統」。

    注意:當前,系統ID和組件ID被硬編碼爲相同的。

    如今,你僅有一個遙測和一架安裝了APM的直升機,就是這樣,去愉快地飛行吧-不用再考慮其它的!這些東西對多直升機有幫助(在將來),將來將會有不一樣的系統ID🙂

  2. 咱們從消息中提取有效負載並放入一個包(packet)中。包是基於一種「信息類型」的數據結構。咱們將再也不使用「消息」一詞,那玩意兒到這裏就結束了。咱們基本上只對由「原始數據」打包而成的包感興趣。

  3. 包被放入一個「適當的數據結構」中。有許多數據結構 ,例如用來存放姿態(俯仰,橫搖,偏航方向)的、GPS的、無線電控制信道的,等等,也就是,把類似的東西組合在一塊兒,造成易於理解的模塊。這些數據結構在發送端和接收端(即在MP端和APM端)「100%徹底相同」。 若是不同的話,你的直升機就會在奇怪的時間墜毀!

PS. 無線電控制信道原文中爲RC channel

此外,這也是MavLink GUI生成器大展身手的地方。爲了生成這些數據結構,咱們不須要編寫任何代碼!!嗯,也不徹底是,但只有一點點。

到目前爲止很簡單對不對?若是以爲困難請重讀一遍!!當個笨蛋不要緊的🙂

好了,如今說正事。咱們使用MavLink發送雙向消息。

從地面控制站(GCS)到APM/PX4或從APM/PX4到地面控制站(GCS)。注意,我說的GCS是指Mission Planner(MP)或者QGroundControl(QGC)、DroidPlanner(DP)或者你自定義的與直升機通訊的工具。

地面控制站(GCS)到四軸飛行器:

到目前爲止,咱們知道每一個消息(咱們叫一個包,裏面有對咱們有用的信息)都有一個消息ID和有效負載,並將其放入適當類型的數據結構中。咱們根據主消息(或MAVLINK_MSG_ID_)進行選擇,一旦檢測到特定類型的消息,就會執行一些神奇的操做,好比將接收到的信息存儲到永久內存中,或者執行咱們但願對其執行的任何操做。

截至2013年11月,在Arducopter最新的3.0.1 RC5(候選版本)中,如下是你可能看到的參數。我已經試着列出全部可能的MavLink消息的「主消息」ID。

請注意,在每一個「主消息」類別中(如粗體部分下面的東西)你會找到屬於那個類別的「子消息」,它們基本上與有效負載信息(真正的肉)及其處理方式密切相關。就像「自行車」類別有雅馬哈,鈴木,哈雷戴維森等。我列出了全部的主要信息類別,但只指定了一些子類別。你能夠本身查一下細節🙂由於若是你明白我到目前爲止的意思,你就再也不是個傻瓜了。明白個人意思嗎?

PS. 由於下面的部分,準確含義並不太清楚,因此只選了若干個翻譯。欲看每一個條目的詳情可查看原文:https://diydrones.com/forum/topics/mavlink-tutorial-for-absolute-dummies-part-i?groupUrl=arducopterusergroup

MAVLINK_MSG_ID(主消息塊):

  1. MAVLINK_MSG_ID_HEARTBEAT://0

    這是最重要的信息。GCS不斷地向APM/PX4發送信息,以肯定它是否與之相連(每1秒一次)。這是爲了確保在更新某些參數時MP與APM是同步的。若是錯過了許多心跳信號,則會觸發故障保護(可能),接着直升機可能着陸、繼續執行任務或返回發射(Returns to launch,也稱爲RTL)。在MP的「配置/設置故障保護選項」下,能夠啓用/禁用故障保護選項。但你不能中止心跳,對嗎?這個名字頗有道理!!

  2. MAVLINK_MSG_ID_REQUEST_DATA_STREAM://66

    請求傳感器,無線電控制信道,GPS位置,狀態,Extra 1/2/3 等數據

  3. MAVLINK_MSG_ID_COMMAND_LONG://76

    無限制懸停(Loiter unlimited),RTL,着陸,任務開始(Mission start),飛控解鎖/鎖定(Arm/Disarm ),從新啓動(Reboot)。

    PS. 例如在航前檢查未經過時是禁止直接用commander arm對飛控解鎖的。

  4. SET_MODE: //11

    E.g. set_mode(packet.custom_mode);

  5. MAVLINK_MSG_ID_MISSION_REQUEST_LIST: //43

  6. MAVLINK_MSG_ID_MISSION_REQUEST: //40

  7. MAVLINK_MSG_ID_MISSION_ACK: //47

  8. MAVLINK_MSG_ID_PARAM_REQUEST_LIST: //21

  9. MAVLINK_MSG_ID_PARAM_REQUEST_READ: //20

  10. MAVLINK_MSG_ID_MISSION_CLEAR_ALL: //45

  11. MAVLINK_MSG_ID_MISSION_SET_CURRENT: //41

  12. MAVLINK_MSG_ID_MISSION_COUNT: // 44

  13. MAVLINK_MSG_ID_MISSION_WRITE_PARTIAL_LIST: //

  14. MAVLINK_MSG_ID_SET_MAG_OFFSETS: //151

  15. MAVLINK_MSG_ID_MISSION_ITEM: //39

  16. MAVLINK_MSG_ID_PARAM_SET: //23

  17. MAVLINK_MSG_ID_RC_CHANNELS_OVERRIDE: //70

  18. MAVLINK_MSG_ID_HIL_STATE: //90

  19. MAVLINK_MSG_ID_DIGICAM_CONFIGURE: //

  20. MAVLINK_MSG_ID_MOUNT_CONFIGURE: //

  21. MAVLINK_MSG_ID_MOUNT_CONTROL: //

  22. MAVLINK_MSG_ID_MOUNT_STATUS://

  23. MAVLINK_MSG_ID_RADIO, MAVLINK_MSG_ID_RADIO_STATUS: //

四軸飛行器到地面控制站(GCS)到四軸飛行器:

好吧,我認可,這變得更有趣了。但這其實容易得多。事實上,GCS系統只是你和直升機之間的中介物,它反過來從直升機獲取數據,並顯示在GCS系統上。

若是你打開了Arducopter.pde文件,請查看代碼的這一部分:

PS. Arducopter.pde如今彷佛是這個https://github.com/ArduPilot/ardupilot/blob/master/ArduCopter/Copter.cpp

static const AP_Scheduler::Task scheduler_tasks[] PROGMEM = { . . . . . . { gcs_send_heartbeat, 100, 150 }, { update_notify, 2, 100 }, { one_hz_loop, 100, 420 }, { gcs_check_input, 2, 550 }, { gcs_send_heartbeat, 100, 150 }, { gcs_send_deferred, 2, 720 }, { gcs_data_stream_send, 2, 950 }, . . . . . . . . .

別懼怕。這比呼吸還容易。這就是實時系統概念發揮做用的地方。咱們但願肯定的任務花費肯定的時間,若是到了規定的時間任務仍沒完成,就再也不繼續執行它們了。

第一個參數是函數名,

第二個是「它應該花費的時間」(以10毫秒爲單位,例如2表示20毫秒執行一次,即50赫茲,即該功能每秒運行50次)。

PS. 1s = 1000ms 故 1000 / 20 = 50 ms/次 = 50Hz

第三個參數是「最長執行時間,超出該時間函數就不該繼續運行」。

我以爲這很簡單!你在這裏看到的每個函數,它的將來都是肯定的,運行時間都是一成不變的。這就是爲何咱們在這些討厭的機器上採用實時系統,這能夠保證它的安全,讓其變得可預測而不是不可預測!!

全部這些函數都是爲你精心挑選的,以便讓你知道它們與GCS系統的更新相關。簡單地說,進入每個函數的定義,這些函數將始終能夠在GCS_Mavlink.pde中找到,在那裏GCS系統通訊的實際操做發生了!!

最有趣(也是最重要)的是:

/* * send data streams in the given rate range on both links */
static void gcs_data_stream_send(void) { gcs0.data_stream_send(); if (gcs3.initialised) { gcs3.data_stream_send(); } }

上面所作的事情是,經過鏈路發送數據(gcs0表示經過USB,gcs3表示經過遙測)。若是你再深刻一點,你就會知道,咱們會把這些數據結構發送回GCS系統顯示。

例如,當你用手移動你的直升機時,瞧瞧MP的HUD屏幕發生了什麼?你將看到直升機在屏幕上移動。而且,咱們獲得了每一個時間單位的飛行姿態數據(俯仰、橫搖和偏航)。一樣,咱們還能夠看到IMU數據、GPS數據、電池數據等。

相關文章
相關標籤/搜索