Lazy loaded image
🛩️ APM源码分析
一、简介
Words 2367Read Time 6 min
2024-8-19
2025-4-16
type
date
slug
category
icon
password
📃
本节主要介绍 MAVLink 协议发展历史、常见概念、主要功能和特点、协议格式和常用报文、以及参考资料。

参考资料

  1. Choose a language · MAVLink Developer Guide(官方详细文档)
  1. Messages (common) · MAVLink Developer Guide(Message Content)
  1. MAVLink Interface — Dev documentation (ardupilot.org)(ArduPilot MAVLink接口说明)
  1. LorenzMeier (Lorenz Meier) (github.com) (Lorenz Meier Github链接)
  1. MAVLink - Wikipedia(维基百科,需科学上网)
  1. Getting Started — MAVProxy documentation (ardupilot.org)(MAVProxy 地面控制站)

简介

MAVLink 是一种非常轻量级的消息传输协议, 用于地面控制终端(地面站)与无人机之间 (以及机载无人机组件之间) 进行通信。MAVLink于2009年初由Lorenz Meier首次发布, 目前为止,已拥有数量可观的贡献者
💡
Lorenz Meier 是 Pixhawk 创造者,他在2008 年~2011年期间,于苏黎世联邦理工学院攻读研究生,着手开发基于视觉的自主无人机。认识到项目规模庞大,招聘了14名学生组建团队,研究无人机控制软硬件,该团队命名为”Pixhawk“。后团队将研究成果开源,其中MAVLink 通讯协议逐渐为AutoQuad和 Ardupilot自驾仪采用。参考The history of Pixhawk | AuterionLorenz MEIER | MSc Visual Computing (ETH) | ETH Zurich, Zürich | ETH Zürich | Department of Computer Science | Research profile (researchgate.net) 作进一步了解。
Mavlink 遵循现代混合发布-订阅和点对点设计模式: 数据流作为 topics 发送/发布的, 而配置子协议 (如 路径点协议 或 参数协议)是基于重传机制的点对点模式。
因此在数据传输方面更加灵活可拓展,发布和订阅系统解耦,数据可被不同系统多个客户端同时订阅使用;在配置方面,基于重传机制的点对点模式,接收方未应答会持续重传,提高通讯系统可靠性,保证消息传输的正确性。

主要特性

  • 高效性。 MAVLink 1每个数据包只有8个字节的开销, 包括起始标志和数据包丢弃检测。 MAVLink 2只有14个字节的开销 (但它是一个更安全且可扩展的协议)。 因为MAVLink不需要任何额外的帧, 所以它非常适合通信带宽非常有限的应用程序。
  • 可靠性。 自2009年以来, MAVLink一直被用于多种载具、地面站 (和其他节点) 之间的通信,而这些通信信道中,不乏各种挑战性(如高延迟、噪声) 。 同时,Mavlink也具备检测数据包丢失、损坏和数据包身份验证的功能。
  • 广泛支持不同编程语言,可运行于大量微控制器/操作系统(包括ARM7, ATMega, dsPic, STM32 and Windows, Linux, MacOS, Android and iOS)。另外源码中还提供pymavlink工具,可用于生成不同语言的源代码,执行协议操作。
  • 单个网络上最多可容纳255个并行系统 (载具、地面站等)。
  • 支持offboard和 onboard通信 (例如,地面站和无人机之间的通信(offboard), 以及无人机自动驾驶仪与启用MAVLink的无人机摄像头之间的通信(onboard))。

协议格式 Serialization

介绍MAVLink数据包序列化细节,主要包括 MAVLink v1/v2 数据包传输格式,消息负载字段顺序,以及CRC校验信息细节。
MAVLink消息报格式受 CAN 和 SAE AS-4 标准启发 ,下面我们介绍一下MAVLink v1/v2数据包传输格式,负载字段以及CRC校验信息细节。可以结合数据包字段和主要特性,加深对特性实现机制的理解
⚠️
多字节字段以小端格式进行序列化,并且MAVLink库默认配置为在小端硬件上运行。

MAVLink 2 的数据包格式

notion image
字节索引
C 版本
内容
说明
0
uint8_t magic
数据包启动标记
0xFD
特定于协议的文本启动 (stx) 标记, 用于指示新数据包的开始。 任何不识别协议版本的系统都将跳过数据包。
1
uint8_t len
载荷长度
0 - 255
显示 有效载荷部分的长度。 这可能会受到 payload truncation 的影响。
2
uint8_t incompat_flags
必须理解为 MAVLink 兼容性的标志 (如果不理解标志, 则实现丢弃数据包)。
3
uint8_t compat_flags
如果不识别, 则可以忽略的标志 (即使不识别标志, 实现仍然可以处理数据包)。
4
uint8_t seq
数据包序列号
0 - 255
用于检测数据包丢失。 组件为发送的每封消息递增值。
5
uint8_t sysid
系统 ID (发送者)
1 - 255
发送消息的 system (飞机) 的 ID。 用于区分网络上的系统。 Note that the broadcast address 0 may not be used in this field as it is an invalid source address.
6
uint8_t compid
组件ID (发送者)
1 - 255
component 发送消息ID。 Used to differentiate components in a system (e.g. autopilot and a camera). Use appropriate values in MAV_COMPONENT. Note that the broadcast address MAV_COMP_ID_ALL may not be used in this field as it is an invalid source address.
7至9
uint32_t msgid:24
消息 ID (低、中、高字节)
0 - 16777215
有效载荷中的 message type 的 id。 用于将数据解码回消息对象。
n=0: NA,  n=1: 10,  n>=2: 10 to (9+n)
uint8_t payload[max 255]
有效负载数据
消息数据。 内容取决于消息类型(即消息ID)
(n+10) to (n+11)
uint16_t checksum
Checksum(低字节, 高字节)
CRC-16/MCRF4XX for message (excluding magic byte). 包括 CRC_EXTERA 字节。
(n+12) to (n+25)
uint8_t signature[13]
(可选) 签名以确保链接不受篡改。
  • The minimum packet length is 12 bytes for acknowledgment packets without payload.
  • The maximum packet length is 280 bytes for a signed message that uses the whole payload.
 
MAV_COMPONENT 含义表
Component ids (values) for the different types and instances of onboard hardware/software that might make up a MAVLink system (autopilot, cameras, servos, GPS systems, avoidance systems etc.). Components must use the appropriate ID in their source address when sending messages. Components can also use IDs to determine if they are the intended recipient of an incoming message. The MAV_COMP_ID_ALL value is used to indicate messages that must be processed by all components. When creating new entries, components that can have multiple instances (e.g. cameras, servos etc.) should be allocated sequential values. An appropriate number of values should be left free after these components to allow the number of instances to be expanded.
Value
Field Name
Description
0
Target id (target_component) used to broadcast messages to all components of the receiving system. Components should attempt to process messages with this component ID and forward to components on any other interfaces. Note: This is not a valid *source* component id for a message.
1
System flight controller component ("autopilot"). Only one autopilot is expected in a particular system.
25
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
26
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
27
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
28
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
29
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
30
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
31
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
32
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
33
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
34
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
35
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
36
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
37
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
38
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
39
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
40
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
41
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
42
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
43
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
44
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
45
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
46
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
47
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
48
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
49
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
50
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
51
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
52
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
53
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
54
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
55
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
56
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
57
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
58
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
59
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
60
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
61
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
62
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
63
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
64
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
65
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
66
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
67
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
68
Telemetry radio (e.g. SiK radio, or other component that emits RADIO_STATUS messages).
69
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
70
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
71
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
72
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
73
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
74
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
75
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
76
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
77
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
78
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
79
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
80
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
81
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
82
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
83
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
84
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
85
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
86
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
87
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
88
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
89
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
90
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
91
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
92
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
93
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
94
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
95
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
96
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
97
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
98
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
99
Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.
100
Camera #1.
101
Camera #2.
102
Camera #3.
103
Camera #4.
104
Camera #5.
105
Camera #6.
140
Servo #1.
141
Servo #2.
142
Servo #3.
143
Servo #4.
144
Servo #5.
145
Servo #6.
146
Servo #7.
147
Servo #8.
148
Servo #9.
149
Servo #10.
150
Servo #11.
151
Servo #12.
152
Servo #13.
153
Servo #14.
154
Gimbal #1.
155
Logging component.
156
Automatic Dependent Surveillance-Broadcast (ADS-B) component.
157
On Screen Display (OSD) devices for video links.
158
Generic autopilot peripheral component ID. Meant for devices that do not implement the parameter microservice.
159
MAV_COMP_ID_QX1_GIMBAL DEPRECATED: Replaced by MAV_COMP_ID_GIMBAL (2018-11). All gimbals should use MAV_COMP_ID_GIMBAL.
Gimbal ID for QX1.
160
FLARM collision alert component.
161
Parachute component.
171
Gimbal #2.
172
Gimbal #3.
173
Gimbal #4
174
Gimbal #5.
175
Gimbal #6.
180
Battery #1.
181
Battery #2.
189
CAN over MAVLink client.
190
Component that can generate/supply a mission flight plan (e.g. GCS or developer API).
191
Component that lives on the onboard computer (companion computer) and has some generic functionalities, such as settings system parameters and monitoring the status of some processes that don't directly speak mavlink and so on.
192
Component that lives on the onboard computer (companion computer) and has some generic functionalities, such as settings system parameters and monitoring the status of some processes that don't directly speak mavlink and so on.
193
Component that lives on the onboard computer (companion computer) and has some generic functionalities, such as settings system parameters and monitoring the status of some processes that don't directly speak mavlink and so on.
194
Component that lives on the onboard computer (companion computer) and has some generic functionalities, such as settings system parameters and monitoring the status of some processes that don't directly speak mavlink and so on.
195
Component that finds an optimal path between points based on a certain constraint (e.g. minimum snap, shortest path, cost, etc.).
196
Component that plans a collision free path between two points.
197
Component that provides position estimates using VIO techniques.
198
Component that manages pairing of vehicle and GCS.
200
Inertial Measurement Unit (IMU) #1.
201
Inertial Measurement Unit (IMU) #2.
202
Inertial Measurement Unit (IMU) #3.
220
GPS #1.
221
GPS #2.
236
Open Drone ID transmitter/receiver (Bluetooth/WiFi/Internet).
237
Open Drone ID transmitter/receiver (Bluetooth/WiFi/Internet).
238
Open Drone ID transmitter/receiver (Bluetooth/WiFi/Internet).
240
Component to bridge MAVLink to UDP (i.e. from a UART).
241
Component to bridge to UART (i.e. from UDP).
242
Component handling TUNNEL messages (e.g. vendor specific GUI of a component).
250
MAV_COMP_ID_SYSTEM_CONTROL DEPRECATED: Replaced by MAV_COMP_ID_ALL (2018-11). System control does not require a separate component ID. Instead, system commands should be sent with target_component=MAV_COMP_ID_ALL allowing the target component to use any appropriate component id.
Deprecated, don't use. Component for handling system messages (e.g. to ARM, takeoff, etc.).

不兼容标记 (MAVLink 2)

标志MAVLink 库必须支持该特性,以便能够正确处理数据包。

兼容性标记 (MAVLink 2)

标志不影响数据包处理的特性,比如优先级。即使不理解compat_flags 字段,可以安全忽略该标志。

有效负载格式

MAVLink 协议为了降低通讯开支,负载本身的不包含消息结构说明。替代地,通讯双方需对消息字段含义、顺序和大小形成共识(实际使用中,通过代码自动生成,在头文件中做了规定,需要做的就是包含一致的MAVLink库文件)。
  • len:包含有效负载的长度
  • payload 字段包含消息数据。
  • msgid(消息id) 字段确定了在数据包中编码的具体消息。
  1. 字段重新排序
      • 字段本身长度排序(double→ float → int16_t→ int8_t)。
      • 字段长度相同,保留原始顺序。
      • 数组类型,根据元素大小,而非总数组大小。
      • CRC字段在重新排序后计算
  1. 空字节有效负载截断 (MAVLink 2)
      • 提供两种方法,一种是不做调整,另一种截端末尾0值(中间为0不截断)
      • 负载第一个字节即使为0也不被截断。
      • 由于字段重新排序,截断的一般都是最小大小的字段。
  1. CRC_EXTERA 计算(CRC-16/MCRF4XX 格式)
      • 接收方计算CRC_EXTRA,与接收到的匹配
      • 重排序错误,或者 word / halfword对齐问题,会导致计算不一致。

MAVLink 1 的数据包格式

notion image

MAVLink 版本

MAVLink 已部署在若干版本中:
  • MAVLink 2.0:当前/推荐的主要版本。 2017年初被主要用户采用。
  • MAVLink v1.0 : 2013年前后广泛采用。 仍被许多传统的外围设备使用。
MAVLink 2.0 C/C++ 和 Python 库向后兼容的 MAVLink 1.0 (支持这两个协议)。 Version Handshaking 和 Negotiating Version 解释了如何选择使用哪种版本。

确定协议/消息版本

库的 MAVLink 支持可以通过多种方式来确定:
  • HEARTBEAT.mavlink_version 字段包含次要版本号。 这是 Message Definitions  (version 在 common.xml 中定义的 <version> 字段, 用于依赖于通用消息集的语支)。
  • 主要版本可以从数据包起始标记字节中确定:
    • MAVLink 1: 0xFE
    • MAVLink 2: 0xFD

版本握手

notion image

MAVLink 2的关键新功能

  • 24 位消息 ID:允许 16 000多万枚独特的信息定义(MAVLink 1 仅限256)
  • 数据包签名:验证消息是由信任系统发送的。
  • 消息扩展 :在现有的 MAVLink 消息定义中添加新的字段,但不打破未更新的接收器的二进制兼容性。
  • 空字节截断:发送之前,删除负载末尾的空(填充为零)字节(在MAVLink 1中,无论内容如何,所有字节都被发送)。
  • 兼容性标志/不兼容性标志:通过指示必须以特殊/非标准方式处理的帧,允许协议的向后兼容演进(带有兼容性标志的数据包仍然可以以标准方式处理,而带有不兼容性标志的数据包如果不支持该标志必须被丢弃)。
以上所列内容将在高级话题详细讨论。

常用消息

Type
Defined
Included
221
2
135
6
164
0
下面解释常用消息,消息内容即是上节MAVLink数据包有效负载Payload数据。

HEARTBEAT

The heartbeat message shows that a system or component is present and responding. The type and autopilot fields (along with the message component id), allow the receiving system to treat further messages from this system appropriately (e.g. by laying out the user interface based on the autopilot). This microservice is documented at https://mavlink.io/en/services/heartbeat.html
Field Name
Type
Values
Description
type
uint8_t
Vehicle or component type. For a flight controller component the vehicle type (quadrotor, helicopter, etc.). For other components the component type (e.g. camera, gimbal, etc.). This should be used in preference to component id for identifying the component type.
autopilot
uint8_t
Autopilot type / class. Use MAV_AUTOPILOT_INVALID for components that are not flight controllers.
base_mode
uint8_t
System mode bitmap.
custom_mode
uint32_t
A bitfield for use for autopilot-specific flags
system_status
uint8_t
System status flag.
mavlink_version
uint8_t_mavlink_version
MAVLink version, not writable by user, gets added by protocol because of magic data type: uint8_t_mavlink_version
  • FD: 启动包
  • LEN: 09
  • INC Flags: 00
  • CMP Flags: 00
  • SEQ: DD
  • SYS ID: 01
  • COMP ID: 01
  • MSG ID: 0 (心跳包)
  • PAYLOAD: 13 00 00 00 0C 03 51 05 03
    • 13:
    • 00
    • 00
    • 00 0C 03 51
    • 05 :MAV_STATE_CRITICAL System is in a non-normal flight mode (failsafe). It can however still navigate.
    • 03
 

ARM/DISARM

Attempt to arm or disarm the vehicle by sending a COMMAND_LONG with the command, param1 and param2 fields set as specified for the MAV_CMD_COMPONENT_ARM_DISARM command.
Command Field
Type
Description
target_system
uint8_t
System ID
target_component
uint8_t
Component ID of flight controller or just 0
command
uint16_t
MAV_CMD_COMPONENT_ARM_DISARM=400
confirmation
uint8_t
0
param1
float
0:disarm, 1:arm
param2
float
0: arm-disarm unless prevented by safety checks, 21196: force arming or disarming
param3
float
not used
param4
float
not used
param5
float
not used
param6
float
not used
param7
float
not used
The example commands below can be copy-pasted into MAVProxy (aka SITL) to test this command. Before running these commands enter, “module load message”
Example MAVProxy/SITL Command
Description
message COMMAND_LONG 0 0 400 0 1 0 0 0 0 0 0
arm the vehicle (may fail because of arming checks)
message COMMAND_LONG 0 0 400 0 1 21196 0 0 0 0 0
force arm the vehicle (try to bypass arming checks)
message COMMAND_LONG 0 0 400 0 0 0 0 0 0 0 0
disarm the vehicle (may fail if not landed)
message COMMAND_LONG 0 0 400 0 0 21196 0 0 0 0 0
force disarm the vehicle even if flying
 
 
 
上一篇
模板设计模式:让你的代码结构更清晰
下一篇
Guide to Linux System

Comments
Loading...