3、通信架构设计:MAVLink协议简介、广播与点对点通信、通信延迟与丢包处理
好,我们进入第三章。通信架构,说白了就是无人机编队的“神经系统”。
编队飞行,不是各飞各的。飞机之间要交换位置、速度、航向,还要知道队友下一步想干嘛。如果通信断了,或者消息传错了,那后果……嗯,我在项目里见过编队直接撞上的。
这一章,我们重点聊三个东西:MAVLink协议、两种通信模式、以及怎么处理延迟和丢包。
3.1 MAVLink协议简介
MAVLink,全称Micro Air Vehicle Link。说白了,它就是无人机界的“普通话”。
我个人习惯用v2.0版本。为什么?因为v1.0的包太小了,编队里要传的信息一多,就得拆包,麻烦得很。
3.1.1 协议结构
一个MAVLink消息,长这样:
| 起始标志 | 负载长度 | 包序列号 | 系统ID | 组件ID | 消息ID | 负载数据 | 校验和 |
| 0xFE | 1字节 | 1字节 | 1字节 | 1字节 | 2字节 | 0-255B | 2字节 |
注意看系统ID和组件ID。编队里,每架飞机有自己的系统ID(比如1号机、2号机),组件ID用来区分飞控、摄像头、数传模块。
我在项目中遇到过一个问题:两台飞机系统ID都设成了1,结果地面站收到的数据全乱了。后来我强制要求:编队内系统ID必须唯一,从1开始编号。
3.1.2 常用消息类型
编队飞行,你至少需要这几个消息:
| 消息ID | 名称 | 用途 |
|---|---|---|
| #0 | HEARTBEAT | 心跳包,告诉队友“我还活着” |
| #32 | LOCAL_POSITION_NED | 本地位置(东北天坐标系) |
| #33 | GLOBAL_POSITION_INT | GPS经纬度+高度 |
| #74 | VFR_HUD | 空速、地速、航向 |
我个人建议,编队里至少每秒发10次LOCAL_POSITION_NED。为什么?因为位置更新慢了,控制算法算出来的轨迹就是错的。
3.2 广播与点对点通信
通信模式,说白了就两种:广播和点对点。
3.2.1 广播模式
广播,就是“一喊全听见”。一架飞机发消息,编队里所有飞机都能收到。
什么时候用广播?
- 编队起飞前:广播“准备起飞”,所有飞机同时响应。
- 紧急情况:比如某架飞机失联了,广播“紧急悬停”,大家立刻停住。
- 队形同步:广播“切换为三角队形”,所有飞机同时执行。
但广播有个坑:信道拥堵。你想想看,如果10架飞机同时广播位置信息,信道里全是包,丢包率直线上升。我曾经在测试时遇到过,广播频率一高,地面站直接卡死。
我的建议是:广播只用于控制指令,不用于高频数据。位置信息用点对点传。
3.2.2 点对点通信
点对点,就是“一对一私聊”。1号机只跟2号机说话,3号机听不见。
什么时候用点对点?
- 位置交换:长机给僚机发自己的位置,僚机只收长机的。
- 任务分配:地面站给某架飞机单独发任务。
- 状态查询:查某架飞机的电池电压、GPS状态。
在MAVLink里,点对点靠系统ID实现。发消息时指定目标系统ID,其他飞机收到后一看不是自己的ID,直接丢弃。
嗯,这里要注意:点对点通信的延迟比广播低。因为广播要等所有飞机都处理完,点对点只处理一个目标。我在项目中实测过,广播延迟约5ms,点对点只有1-2ms。
3.3 通信延迟与丢包处理
这是编队飞行里最头疼的问题。没有之一。
你想想看,1号机发了个位置消息,2号机收到时已经过了100ms。这100ms里,1号机飞了2米远。2号机拿到的位置是“历史位置”,不是“当前位置”。
怎么办?
3.3.1 延迟补偿
我的做法是:给每个消息打时间戳。
在MAVLink里,可以用TIMESYNC消息或者自定义字段。收到消息后,计算时间差:
# 伪代码示例
current_time = get_current_time()
msg_time = extract_timestamp(msg)
delay = current_time - msg_time
# 补偿位置
compensated_x = msg.x + msg.vx * delay
compensated_y = msg.y + msg.vy * delay
说白了,就是用速度乘以延迟,估算出飞机在这段时间里飞了多远。
我曾经在项目中遇到过一个问题:GPS更新频率只有5Hz,延迟高达200ms。如果不做补偿,编队队形误差能到半米。加上补偿后,误差降到10cm以内。
3.3.2 丢包处理
丢包,说白了就是消息没收到。原因很多:信号遮挡、信道干扰、缓冲区溢出。
我的处理策略分三级:
- 轻度丢包(<5%):直接忽略。用上一帧的数据继续控制。
- 中度丢包(5%-20%):用卡尔曼滤波预测位置。说白了,就是根据历史轨迹猜当前位置。
- 重度丢包(>20%):触发安全机制。僚机自动切换到悬停模式,等待长机重新建立通信。
这里有个避坑指南:不要用“重传”机制。我曾经试过,丢包后让飞机重发消息。结果呢?信道更堵了,丢包率反而更高。后来我改用“预测+超时”策略,效果好了很多。
3.3.3 实际测试数据
我在一次编队测试中,记录了通信质量:
| 距离(米) | 延迟(ms) | 丢包率(%) | 处理策略 |
|---|---|---|---|
| 50 | 2-5 | 0.5 | 直接使用 |
| 200 | 10-20 | 3 | 时间戳补偿 |
| 500 | 30-50 | 8 | 卡尔曼预测 |
| 800 | 80-120 | 15 | 预测+限速飞行 |
你看,距离一远,延迟和丢包都上来了。所以我的建议是:编队飞行时,飞机间距不要超过500米。超过这个距离,通信质量就很难保证了。
核心总结:
- MAVLink v2.0是编队通信的首选,系统ID必须唯一。
- 广播用于指令,点对点用于高频数据。
- 延迟用时间戳补偿,丢包用预测+超时处理。
- 编队间距建议控制在500米以内。
个人小技巧:
在ROS里,我习惯用mavros包来收发MAVLink消息。它自带时间戳和延迟计算,省了很多事。你可以在launch文件里设置system_id和component_id,非常方便。
警告:
千万不要在编队飞行时使用“确认-重传”机制。我曾经吃过这个亏,导致整个编队失控。记住:无人机编队通信,宁可丢包,不可拥堵。
好,这一章就到这里。下一章我们聊编队控制算法,到时候会用到今天讲的通信知识。你先把MAVLink的收发代码跑通,有问题随时问我。