4、MAVLink通信模式:主从模式与广播模式、心跳包机制、系统ID与组件ID

好,咱们今天聊点实在的。MAVLink 的通信模式,说白了就是无人机和地面站之间怎么「说话」的问题。我刚开始接触这个协议的时候,也被一堆概念绕晕过。什么主从、广播、心跳……其实捋清楚了,就那么几件事。

4.1 两种通信模式:主从 vs 广播

MAVLink 支持两种基本的通信模式。你选哪种,取决于你的系统架构和硬件能力。

核心区别一句话:主从模式是一对一精准对话,广播模式是一对多喊话。

4.1.1 主从模式(Master-Slave)

这种模式下,通信由主设备(通常是地面站 GCS)发起。从设备(比如飞控)只能回应,不能主动发消息。嗯,这里要注意,MAVLink 1.0 时代这个模式用得比较多,因为那时候链路带宽窄,CPU 也弱。

  • 主设备:发送请求命令,比如请求参数、发送航点。
  • 从设备:收到请求后,回复对应的数据包。
  • 优点:通信秩序好,不会冲突,适合点对点串口链路。
  • 缺点:效率低,从设备不能主动上报紧急状态。

我在一个早期的测绘无人机项目里用过这种模式。当时用的是 433MHz 数传,带宽只有 9600bps。主从模式确实稳定,但有个问题——飞机突然触发返航,地面站要等下一个轮询周期才能知道。这个延迟有时候挺要命的。

4.1.2 广播模式(Broadcast)

广播模式就灵活多了。任何设备都可以随时向总线上发送消息,不需要等待谁批准。现在的 MAVLink 2.0 基本都跑这个模式。

  • 谁都可以说话:飞控主动发心跳、姿态、GPS 数据。
  • 谁都可以听:地面站、机载电脑、其他无人机都能接收。
  • 优点:实时性好,适合多设备协同。
  • 缺点:总线冲突风险,需要做好消息频率规划。

我的建议:新项目直接用广播模式。除非你的链路真的窄到不行,或者硬件不支持全双工。广播模式配合消息频率控制,基本能覆盖 99% 的场景。

4.2 心跳包机制——系统的「脉搏」

心跳包(HEARTBEAT)是 MAVLink 里最重要的消息,没有之一。它的消息 ID 是 0,优先级最高。

为什么重要?你想想看,地面站怎么知道飞机还活着?就是靠心跳。如果连续几个心跳没收到,地面站就该报警了。

4.2.1 心跳包的结构

心跳包的内容不多,但每个字段都关键:

字段 说明 典型值
type 飞行器类型 MAV_TYPE_QUADROTOR (2)
autopilot 飞控固件类型 MAV_AUTOPILOT_ARDUPILOTMEGA (3)
base_mode 系统状态标志位 0x81 (已上锁 + 已就绪)
custom_mode 自定义模式(如定高、悬停) 4 (GUIDED)
system_status 系统状态 MAV_STATE_ACTIVE (4)
mavlink_version 协议版本 2

我曾经踩过的坑:有一次调试,地面站一直显示「连接已断开」。查了半天,发现是心跳包的 base_mode 字段写错了。我写成了 0x80,结果地面站认为系统未就绪,直接断连。记住,base_mode 的 bit 0 是「已就绪」标志,必须置 1。

4.2.2 心跳的发送频率

MAVLink 规范建议心跳包以 1Hz 的频率发送。也就是每秒一次。

为什么是 1Hz?

  • 太快了浪费带宽,尤其在高延迟链路上。
  • 太慢了无法及时检测掉线。
  • 1Hz 是个平衡点,地面站通常允许 3-5 秒的心跳超时。

我个人习惯在机载电脑( companion computer )上把心跳频率提到 5Hz,因为机载电脑和飞控之间的链路是本地串口,带宽充裕。但往数传链路上发的时候,还是老老实实 1Hz。

4.3 系统ID与组件ID——设备的「身份证」

在一个 MAVLink 网络里,可能有多个无人机、多个地面站、多个摄像头、多个传感器。怎么区分谁是谁?靠的就是系统 ID 和组件 ID。

4.3.1 系统ID(System ID)

系统 ID 是一个 uint8_t 类型的数字,范围 1-255。它标识一个独立的系统。比如:

  • 系统 ID = 1:无人机 A
  • 系统 ID = 2:无人机 B
  • 系统 ID = 255:地面站

每个系统内部,可以有多个组件。

4.3.2 组件ID(Component ID)

组件 ID 标识系统内的具体模块。常用的组件 ID 有:

组件ID 名称 说明
1 MAV_COMP_ID_AUTOPILOT1 主飞控
0 MAV_COMP_ID_ALL 广播给所有组件
154 MAV_COMP_ID_CAMERA 相机
100 MAV_COMP_ID_MISSIONPLANNER 地面站

举个例子:系统 ID=1 的无人机,它的飞控组件 ID=1,挂载的相机组件 ID=154。地面站收到一条消息,看到 sysid=1, compid=1,就知道这是 1 号机的飞控发来的。

避坑指南:我曾经在一个多机协同项目里,两台无人机都用了系统 ID=1。结果地面站收到的心跳包互相覆盖,一会儿显示飞机 A 在线,一会儿显示飞机 B 在线。排查了半天才发现是 ID 冲突。记住,同一网络内系统 ID 必须唯一。

4.4 整体通信架构图

下面这张图展示了 MAVLink 通信的核心架构。你可以看到系统 ID、组件 ID、心跳包和通信模式之间的关系。

MAVLink 通信架构图 地面站 (GCS) SysID=255, CompID=100 主模式 / 广播模式 无人机 A SysID=1 心跳 1Hz 无人机 B SysID=2 心跳 1Hz 飞控 CompID=1 相机 CompID=154 飞控 CompID=1 激光雷达 CompID=180 心跳包 (MsgID=0) 广播模式:所有设备可收可发 主从模式:GCS 发起,设备回应 关键说明: 1. 每个系统(无人机/地面站)有唯一的 System ID(1-255) 2. 每个系统内的模块有唯一的 Component ID 3. 心跳包以 1Hz 频率广播,包含系统状态和模式信息 4. 广播模式适合多设备实时通信,主从模式适合窄带宽链路

4.5 实际开发中的选择建议

说了这么多理论,咱们落地到实际开发。你该怎么选?

  1. 单无人机 + 地面站:广播模式就够了。飞控发心跳,地面站收,简单直接。
  2. 多无人机编队:必须广播模式。每架飞机用不同的系统 ID,地面站通过 sysid 区分。
  3. 机载电脑 + 飞控:推荐广播模式。机载电脑可以主动发指令,飞控也能主动上报数据。
  4. 超低带宽链路(< 9600bps):可以考虑主从模式,但说实话,现在很少见了。我建议还是广播模式,但把消息频率降到 0.5Hz。

我的经验之谈:别在通信模式上纠结太久。默认用广播模式,把系统 ID 和组件 ID 规划好,心跳包按规范发。这三点做好了,你的 MAVLink 通信就稳了八成。剩下的两成,是消息频率规划和链路质量的问题,咱们后面章节再聊。