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、心跳包和通信模式之间的关系。
4.5 实际开发中的选择建议
说了这么多理论,咱们落地到实际开发。你该怎么选?
- 单无人机 + 地面站:广播模式就够了。飞控发心跳,地面站收,简单直接。
- 多无人机编队:必须广播模式。每架飞机用不同的系统 ID,地面站通过 sysid 区分。
- 机载电脑 + 飞控:推荐广播模式。机载电脑可以主动发指令,飞控也能主动上报数据。
- 超低带宽链路(< 9600bps):可以考虑主从模式,但说实话,现在很少见了。我建议还是广播模式,但把消息频率降到 0.5Hz。
我的经验之谈:别在通信模式上纠结太久。默认用广播模式,把系统 ID 和组件 ID 规划好,心跳包按规范发。这三点做好了,你的 MAVLink 通信就稳了八成。剩下的两成,是消息频率规划和链路质量的问题,咱们后面章节再聊。