本文針對 MAVLink v1.0版本,協議版本:3。
MAVLink是爲微型飛行器MAV(Micro Air Vehicle)設計的(LGPL)開源的通訊協議。是無人飛行器和地面站(Ground Control Station ,GCS)之間,以及無人飛行器之間通訊常用的協議。APM、PIXHAWK飛控,Mission Planner、QGroundControl地面站均使用了MAVLink協議進行通訊。
MAVLink源碼下載地址(現已更新至v2.0):https://github.com/mavlink/qgroundcontrol
用戶手冊:https://docs.qgroundcontrol.com/en/
MAVLink源文件結構
1、 common文件夾:原始的MAVLink消息,包括各種消息的頭文件
common.h:定義MAVLink各個消息包中用到的枚舉類型,各個消息包對應的CRC—EXTRA值、LENGTH值,包含(include)各個消息包的頭文件
各個消息的頭文件:1)定義消息內容對應的數據結構,2)打包、發送消息的便捷函數,3)消息包解析並獲取各個參數
2、 autopilotmega,ASLUAV,pixhawk等文件夾:這些文件夾包含各個飛控自定義的MAVLink消息類型
3、 checksum.h:計算校驗碼的代碼
4、 mavlink_conversions.h:dcm,歐拉角,四元數之間的轉換
5、 mavlink_helper.h:提供各種便捷函數:
1)將各個消息包補充完整併發送。將數據載荷加上消息幀的頭部,如sysid和compid等,計算校驗碼,補充成爲完整的mavlink消息包後發送;
2)MAVLink消息包解析。
6、 mavlink_types.h:定義用到的各種基本結構體(如mavlink_message_t)、枚舉類型(如 mavlink_param_union_t)
MAVLink消息包結構
MAVLink傳輸時,以消息包作爲基本單位,數據長度爲8~263字節。消息數據包的結構如下:
|
字節索引 |
內容 |
值 |
解釋 |
STX |
0 |
包起始標誌 |
v1.0:0xFE |
包的起始標誌,在v1.0中以“FE”作爲起始標誌(FE=254) |
LEN |
1 |
有效載荷長度 |
0~255 |
有效載荷數據的字節長度(N) |
SEQ |
2 |
包的序列號 |
0~255 |
每發送完一個消息,內容加1。用以檢測丟包情況 |
SYS |
3 |
系統ID編號 |
1~255 |
發送本條消息包的系統/飛行器的編號。用於消息接收端在同一網絡中識別不同的MAV系統 |
COMP |
4 |
部件ID編號 |
0~255 |
發送本條消息包的部件的編號。用於消息接收端在同一系統中區分不同的組件,如IMU和飛控 |
MSG |
5 |
消息包ID編號 |
0~255 |
有效載荷中消息包的編號。該id定義了有效載荷內放的是什麼類型的消息,以便消息接收端正確地解碼消息包 |
PAYLOAD |
6~N+6 |
有效載荷數據 |
0~255字節 |
要用的數據放在有效載荷裏。內容取決於message id。 |
CKA |
N+7 |
校驗和低字節 |
|
16位校驗碼; ITU X.25/SAE AS-4哈希校驗(CRC-16-CCITT),不包括數據包起始位,從第一個字節到有效載荷(字節1 ..(N+6))進行crc16計算(還要額外加上一個MAVLINK_CRC_EXTRA字節),得到一個16位校驗碼 |
CKB |
N+8 |
校驗和高字節 |
注:校驗(checksum)功能。加入MAVLINK_CRC_EXTRA,當兩個通訊終端之間(飛行器和地面站,或飛行器和飛行器)使用不同版本的MAVLink協議時,雙方計算得到的校驗碼會不同,則不同版本的MAVLink協議之間將無法通訊。MAVLINK_MESSAGE_CRCS中存儲了每種消息包對應的MAVLINK_CRC_EXTRA。這個 MAVLINK_CRC_EXTRA在用python生成MAVLink代碼時在common.h頭文件中自動生成。
MAVLink數據包的結構在mavlink_types.h中用mavlink_message_t結構體定義:
1 typedef struct __mavlink_message {
2 uint16_t checksum; /// CRC
3 uint8_t magic; /// STX
4 uint8_t len; /// LEN
5 uint8_t seq; /// SEQ
6 uint8_t sysid; /// SYS
7 uint8_t compid; /// COMP
8 uint8_t msgid; /// MSG
9 uint64_t payload64[(MAVLINK_MAX_PAYLOAD_LEN+MAVLINK_NUM_CHECKSUM_BYTES+7)/8];
10 } mavlink_message_t;
MAVLINK Common Message Set
MAVLink通用消息集可以在《MAVLLINK Common Message set specifications》文檔中查看。這些消息定義了通用消息集,這是大多數地面控制站和自動駕駛儀實現的參考消息集,頭文件包含在common文件夾中。
分爲兩部分:MAVLink Type Enumerations(MAVLink類型枚舉 )和MAVLink Messages(MAVLink消息包)。
MAVLink Type Enumerations
MAVLink Type Enumerations在common.h文件中定義。如下,枚舉變量定義了飛行器的類型MAV_AUTOPILOT。
1 typedef enum MAV_AUTOPILOT
2 {
3 MAV_AUTOPILOT_GENERIC=0, /* Generic autopilot, full support for everything | */
4 MAV_AUTOPILOT_RESERVED=1, /* Reserved for future use. | */
5 MAV_AUTOPILOT_SLUGS=2, /* SLUGS autopilot, http://slugsuav.soe.ucsc.edu | */
6 MAV_AUTOPILOT_ARDUPILOTMEGA=3, /* ArduPilotMega / ArduCopter, http://diydrones.com | */
7 MAV_AUTOPILOT_OPENPILOT=4, /* OpenPilot, http://openpilot.org | */
8 MAV_AUTOPILOT_GENERIC_WAYPOINTS_ONLY=5, /* Generic autopilot only supporting simple waypoints | */
9 MAV_AUTOPILOT_GENERIC_WAYPOINTS_AND_SIMPLE_NAVIGATION_ONLY=6, /* Generic autopilot supporting waypoints and other simple navigation commands | */
10 MAV_AUTOPILOT_GENERIC_MISSION_FULL=7, /* Generic autopilot supporting the full mission command set | */
11 MAV_AUTOPILOT_INVALID=8, /* No valid autopilot, e.g. a GCS or other MAVLink component | */
12 MAV_AUTOPILOT_PPZ=9, /* PPZ UAV - http://nongnu.org/paparazzi | */
13 MAV_AUTOPILOT_UDB=10, /* UAV Dev Board | */
14 MAV_AUTOPILOT_FP=11, /* FlexiPilot | */
15 MAV_AUTOPILOT_PX4=12, /* PX4 Autopilot - http://pixhawk.ethz.ch/px4/ | */
16 MAV_AUTOPILOT_SMACCMPILOT=13, /* SMACCMPilot - http://smaccmpilot.org | */
17 MAV_AUTOPILOT_AUTOQUAD=14, /* AutoQuad -- http://autoquad.org | */
18 MAV_AUTOPILOT_ARMAZILA=15, /* Armazila -- http://armazila.com | */
19 MAV_AUTOPILOT_AEROB=16, /* Aerob -- http://aerob.ru | */
20 MAV_AUTOPILOT_ASLUAV=17, /* ASLUAV autopilot -- http://www.asl.ethz.ch | */
21 MAV_AUTOPILOT_ENUM_END=18, /* | */
22 } MAV_AUTOPILOT;
MAVLink Messages
MAVLink Messages在common文件夾內每個消息包的頭文件中定義。在文檔中msgid以藍色的“#”加數字的方式來表示,如心跳包的“#0”,在心跳包的頭文件mavlink_msg_heartbeat.h中,MAVLINK_MSG_ID_HEARTBEAT對應心跳包的message ID,爲0。
#define MAVLINK_MSG_ID_HEARTBEAT 0
心跳包的內容存放在payload數據載荷中。以心跳包爲例,
typedef struct __mavlink_heartbeat_t
{
uint32_t custom_mode; /*< A bitfield for use for autopilot-specific flags.*/
uint8_t type; /*< Type of the MAV (quadrotor, helicopter, etc., up to 15 types, defined in MAV_TYPE ENUM)*/
uint8_t autopilot; /*< Autopilot type / class. defined in MAV_AUTOPILOT ENUM*/
uint8_t base_mode; /*< System mode bitfield, see MAV_MODE_FLAG ENUM in mavlink/include/mavlink_types.h*/
uint8_t system_status; /*< System status flag, see MAV_STATE ENUM*/
uint8_t mavlink_version; /*< MAVLink version, not writable by user, gets added by protocol because of magic data type: uint8_t_mavlink_version*/
} mavlink_heartbeat_t;
心跳包一般用來表明發出該消息的設備是否活躍(一般以1Hz發送),消息接收端會根據是否及時收到了心跳包來判斷是否和消息發送端失去了聯繫。
心跳包由6個數據成員組成,佔用9個字節。
1、 type:飛行器類型,表示了當前發消息的是什麼飛行器,如四旋翼,直升機等。type的取值對應枚舉類型MAV_TYPE(如四旋翼,對應數值2)。
2、autopilot:飛控類型,如apm,Pixhawk等,發送心跳包的飛行器的飛控類型。autopilot的取枚舉類型MAV_AUTOPILOT。
3、base mode(基本模式):飛控現在所處的飛行模式,這個參數要看各個飛控自己的定義方式,會有不同的組合、計算方式。
4、custom mode(用戶模式):飛控現在所處的飛行模式,這個參數要看各個飛控自己的定義方式,會有不同的組合、計算方式。
5、system status:系統狀態,見MAV_STATE枚舉變量。
6、mavlink version:消息發送端的MAVLink版本。
其餘的消息也是類似的結構,基本消息的定義可以查看官方網頁的說明(具體說明以各個飛控爲準),也可查看各個消息包頭文件的定義。
Mavlink 2.0協議:
MAVLink協議:
MavLink協議目前網上可以找到的中文版資料只有1.0的。現在開發使用的固件版本號是1.7.3.串口抓的的包全部與1.0版本都不一致。爬到官方去看了下。有2.0的包結構。
uint8_t magic; ///< protocol magic marker
uint8_t len; ///< Length of payload
uint8_t incompat_flags; ///< flags that must be understood
uint8_t compat_flags; ///< flags that can be ignored if not understood
uint8_t seq; ///< Sequence of packet
uint8_t sysid; ///< ID of message sender system/aircraft
uint8_t compid; ///< ID of the message sender component
uint8_t msgid 0:7; ///< first 8 bits of the ID of the message
uint8_t msgid 8:15; ///< middle 8 bits of the ID of the message
uint8_t msgid 16:23; ///< last 8 bits of the ID of the message
uint8_t target_sysid; ///< Optional field for point-to-point messages, used for payload else
uint8_t target_compid; ///< Optional field for point-to-point messages, used for payload else
uint8_t payload[max 253]; ///< A maximum of 253 payload bytes
uint16_t checksum; ///< X.25 CRC
uint8_t signature[13]; ///< Signature which allows ensuring that the link is tamper-proof
包結構大致如下:
部分 | 長度 | 內容 |
---|---|---|
n1 STX | 1B | 幀頭部分,2.0版本爲 0xFD |
n2 LEN | 1B | PLAYLOAD數據長度 |
n3 | 1B | incompat_flags |
n4 | 1B | compat_flags |
n5 SEQ | 1B | 消息幀序號 |
n6 SYS | 1B | 消息系統編號 |
n7 COMP | 1B | 羅盤編號 |
n8 MSG | 3B | msgid,消息標號,MavlinkMessage |
n9 | 1B | target_sysid可選 |
n10 | 1B | target_compid可選 |
n11 PLAYLOAD | 2B | 消息內容 |
n12 | 2B | CRC校驗 |
n13 | 1B | 簽名 |
2.0包的總長爲10+n+3(+2),其中括號的2爲可選內容。抓包未發現。
抓包獲得來自飛控的Msgind如下。
0,36,74,105,30,31,32,140,1,147,65,70,141,230,241,111,83,69,24
這些都是飛控無請求時主動發送過來的數據。
根據msgid:
HEX | DEC | TYPE |
---|---|---|
00 | 0 | HEARTBEAT |
01 | 1 | SYS_STATUS |
18 | 24 | GPS_RAW_INT |
1E | 30 | ATTITUDE |
1F | 31 | ATTITUDE_QUATERNION |
20 | 32 | LOCAL_POSITION_NED |
24 | 36 | SERVO_OUTPUT_RAW |
41 | 65 | RC_CHANNELS |
45 | 69 | MANUAL_CONTROL |
46 | 70 | RC_CHANNELS_OVERRIDE |
4A | 74 | VFR_HUD |
53 | 83 | ATTITUDE_TARGET |
69 | 105 | HIGHRES_IMU |
6F | 111 | TIMESYNC |
8C | 140 | ACTUATOR_CONTROL_TARGET |
8D | 141 | ALTITUDE |
93 | 147 | BATTERY_STATUS |
E6 | 230 | ESTIMATOR_STATUS |
E7 | 231 | WIND_COV |
F1 | 241 | VIBRATION |
F5 | 245 | EXTENDED_SYS_STATE |