2. MAVLink协议基础

MAVLink(Micro Air Vehicle Link)是无人机领域应用最广泛的轻量级通信协议之一。它最初由 Lorenz Meier 等人于 2009 年前后为 PIXHAWK 项目设计,目标是在低带宽、高延迟、易丢包的无线链路上,实现飞控、地面站、机载计算机与云平台之间的可靠消息交换。理解 MAVLink 的帧结构、寻址机制与编解码流程,是后续学习安全与鉴权的前提。

一、协议起源与设计取向

MAVLink 诞生于开源飞控生态,早期版本为 v0.9,随后演进到 v1.0 与 v2.0。它的设计取向非常明确:

  • 轻量:帧头开销小,适合串口、数传电台等窄带链路。
  • 自描述:消息由 XML 定义,工具链可自动生成各语言编解码代码。
  • 可扩展:通过 CRC 种子与扩展字段,兼顾兼容性与演进能力。
  • 面向多组件:同一链路可承载多个系统、多个组件之间的消息。

MAVLink v2 相比 v1 增加了 24 位消息 ID、载荷截断、签名等能力,其中签名机制正是后续鉴权章节的重要基础。

二、消息帧结构

MAVLink v2 帧由帧头、载荷、校验和与可选签名组成。帧头以起始标志 0xFD 开头,包含载荷长度、不兼容标志、兼容标志、序列号、系统 ID、组件 ID 以及 24 位消息 ID。载荷之后是 16 位 CRC,若启用签名,还会附加 13 字节签名块。

MAVLink v2 帧结构(简化)
+------+------+------+------+------+------+------+------+---------+------+--------+
| STX  | LEN  | INC  | CMP  | SEQ  | SYS  | COMP | MSGID(3B) | PAYLOAD | CRC  | SIG(13B) |
| 0xFD | 1B   | 1B   | 1B   | 1B   | 1B   | 1B   | 3B        | 0~255B  | 2B   | 可选     |
+------+------+------+------+------+------+------+------+---------+------+--------+

其中 SEQ 用于检测丢包,SYS 与 COMP 用于寻址,MSGID 决定消息类型。CRC 计算时还会混入消息 ID 对应的 CRC 种子,从而避免不同消息因载荷相同而误判。

三、心跳包、系统 ID 与组件 ID

心跳包(HEARTBEAT,消息 ID 0)是 MAVLink 网络中的“存在声明”。飞控、地面站、云台、相机等节点会周期性发送心跳,携带类型、自动驾驶仪类型、系统状态与 MAVLink 版本。接收方通过心跳判断对端是否在线、是否可通信。

系统 ID(System ID)标识一个独立的无人机系统,例如一架飞机或一个地面站;组件 ID(Component ID)标识系统内部的子模块,例如飞控、云台、相机、避障计算机。二者组合形成 (sysid, compid) 寻址对。常见约定中,飞控常为 1/1,地面站常为 255/190。

心跳包不仅是“在线探测”,也是安全策略的入口:后续鉴权可基于心跳中的系统 ID、组件 ID 与签名状态判断是否允许接入。

四、消息编解码流程

MAVLink 消息的编解码通常由生成代码完成,流程可概括为:定义 XML → 生成代码 → 填充字段 → 序列化 → 发送 → 接收 → 校验 → 反序列化 → 分发处理。

  1. 根据消息定义生成各语言库,得到消息结构体与打包函数。
  2. 应用层填充字段,例如命令、参数、姿态或位置。
  3. 编码器按字段顺序写入载荷,计算 CRC,必要时附加签名。
  4. 接收端解析帧头,校验 CRC 与签名,再按消息 ID 分发。
  5. 业务逻辑处理消息,或回复 ACK、COMMAND_ACK 等确认消息。

下面是一个使用 Python 发送心跳包的简化示例:

from pymavlink import mavutil

master = mavutil.mavlink_connection('udp:127.0.0.1:14550')
master.mav.heartbeat_send(
    mavutil.mavlink.MAV_TYPE_QUADROTOR,
    mavutil.mavlink.MAV_AUTOPILOT_ARDUPILOTMEGA,
    mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED,
    mavutil.mavlink.MAV_STATE_ACTIVE,
    3
)
print("heartbeat sent")

五、常见消息类型与场景

MAVLink 消息数量众多,工程中高频使用的类型如下表所示。理解这些消息的用途,有助于在安全策略中区分“控制类”“状态类”“配置类”消息,并施加不同级别的鉴权与审计。

消息ID用途典型场景
HEARTBEAT0节点在线与状态声明飞控、地面站周期广播
SYS_STATUS1系统传感器与电池状态地面站监控
PING4链路时延探测通信质量评估
COMMAND_LONG76长命令控制解锁、起飞、返航
COMMAND_ACK77命令确认命令执行结果反馈
SET_MODE11切换飞行模式手动/自动模式切换
PARAM_SET23设置参数调参与配置
MISSION_ITEM_INT73上传航点任务规划
ATTITUDE30姿态信息姿态显示与日志
GLOBAL_POSITION_INT33全局位置地图定位

六、案例与误区复盘

在一个典型的巡检场景中,地面站通过 UDP 连接飞控,飞控以 1 Hz 发送 HEARTBEAT,地面站以 2 Hz 发送 GLOBAL_POSITION_INT 请求,飞控回复位置消息。若地面站未收到心跳,通常先检查系统 ID 与组件 ID 是否匹配、链路是否被防火墙阻断、CRC 种子是否一致。

常见误区:一是认为“收到心跳就等于链路安全”,实际上心跳可被伪造;二是忽略系统 ID 与组件 ID 的规划,导致多机场景下消息串扰;三是只校验 CRC 而不校验签名,无法抵御篡改与重放。

因此,掌握 MAVLink 的帧结构、寻址方式与编解码流程,不仅是通信调试的基础,也是后续设计鉴权、签名与访问控制策略的起点。

MAVLink v2 帧结构与编解码流程 帧结构(从左到右) STX 0xFD LEN 载荷长度 INC 不兼容标志 CMP 兼容标志 SEQ 序列号 SYS 系统 ID COMP 组件 ID MSGID 24 位消息 ID PAYLOAD 0~255 字节 CRC 2 字节 SIG 可选 13B 编解码流程 XML 定义 消息与字段 生成代码 结构体/打包函数 填充字段 命令/参数/姿态 序列化 CRC + 可选签名 发送/接收 串口/UDP/电台 校验 CRC 与签名 反序列化 还原字段 按 MSGID 分发 业务处理 心跳与寻址要点 • HEARTBEAT(ID 0)周期广播,声明节点在线与类型 • (SYS, COMP) 组合寻址:飞控常见 1/1,地面站常见 255/190 • CRC 混入消息 ID 种子;v2 可选签名用于完整性与来源鉴别