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。
四、消息编解码流程
MAVLink 消息的编解码通常由生成代码完成,流程可概括为:定义 XML → 生成代码 → 填充字段 → 序列化 → 发送 → 接收 → 校验 → 反序列化 → 分发处理。
- 根据消息定义生成各语言库,得到消息结构体与打包函数。
- 应用层填充字段,例如命令、参数、姿态或位置。
- 编码器按字段顺序写入载荷,计算 CRC,必要时附加签名。
- 接收端解析帧头,校验 CRC 与签名,再按消息 ID 分发。
- 业务逻辑处理消息,或回复 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 | 用途 | 典型场景 |
|---|---|---|---|
| HEARTBEAT | 0 | 节点在线与状态声明 | 飞控、地面站周期广播 |
| SYS_STATUS | 1 | 系统传感器与电池状态 | 地面站监控 |
| PING | 4 | 链路时延探测 | 通信质量评估 |
| COMMAND_LONG | 76 | 长命令控制 | 解锁、起飞、返航 |
| COMMAND_ACK | 77 | 命令确认 | 命令执行结果反馈 |
| SET_MODE | 11 | 切换飞行模式 | 手动/自动模式切换 |
| PARAM_SET | 23 | 设置参数 | 调参与配置 |
| MISSION_ITEM_INT | 73 | 上传航点 | 任务规划 |
| ATTITUDE | 30 | 姿态信息 | 姿态显示与日志 |
| GLOBAL_POSITION_INT | 33 | 全局位置 | 地图定位 |
六、案例与误区复盘
在一个典型的巡检场景中,地面站通过 UDP 连接飞控,飞控以 1 Hz 发送 HEARTBEAT,地面站以 2 Hz 发送 GLOBAL_POSITION_INT 请求,飞控回复位置消息。若地面站未收到心跳,通常先检查系统 ID 与组件 ID 是否匹配、链路是否被防火墙阻断、CRC 种子是否一致。
因此,掌握 MAVLink 的帧结构、寻址方式与编解码流程,不仅是通信调试的基础,也是后续设计鉴权、签名与访问控制策略的起点。