4. MAVLink通信链路组成
通信链路是飞控系统的血管。数据流不通,再好的算法也白搭。这一章我们聚焦链路建立的核心环节——串口怎么配、UDP/TCP端点怎么设、MAVLink路由器怎么用。我见过太多开发者在这上面栽跟头,明明代码逻辑没问题,就是连不上。说白了,链路配置的细节决定了调试效率。
4.1 串口配置:波特率与流控
串口是飞控与地面站、机载计算机之间最常用的物理层接口。配置串口时,两个参数必须搞对:波特率和流控。
4.1.1 波特率的选择
波特率决定了串口通信的速度。常见的飞控波特率有:
| 波特率 (bps) | 适用场景 | 注意事项 |
|---|---|---|
| 57600 | 早期Pixhawk、低带宽遥测 | 数据量小,适合简单状态监控 |
| 115200 | 大多数飞控默认遥测速率 | 平衡速度与稳定性,推荐首选 |
| 921600 | 高速日志下载、机载计算机通信 | 线缆质量差时容易丢包 |
| 1500000 | 高速传感器数据流(如激光雷达) | 需要短距离、高质量连接 |
我个人习惯,调试阶段先用115200。为什么?因为这个速率下,大多数USB转串口芯片(如FT232、CP2102)工作最稳定。我曾经在项目里一上来就设921600,结果地面站频繁断连,折腾了半天才发现是USB延长线太长导致信号衰减。
4.1.2 硬件流控(RTS/CTS)
流控这东西,很多人直接忽略。但实际项目中,它往往是隐形的坑。
硬件流控使用RTS和CTS两根信号线,让接收方告诉发送方“我准备好了,你可以发了”或者“我忙不过来,你先停一下”。在高速通信时,如果没有流控,接收缓冲区溢出会导致数据丢失。
什么时候必须开流控?
- 高速率(≥921600):接收端处理速度跟不上发送速度时
- 长距离传输:信号干扰导致重传频繁时
- 多设备共享总线:需要协调发送时序时
什么时候可以关掉?
- 低速(≤115200)且短距离:CPU处理能力足够,不会溢出
- 只有TX/RX两根线:硬件不支持流控,只能关
4.2 UDP/TCP端点设置
当通信从串口转到网络层(比如机载计算机通过WiFi或以太网与地面站通信),UDP和TCP就成了主角。很多人分不清什么时候用UDP、什么时候用TCP。我简单说说我的理解。
4.2.1 UDP vs TCP:选哪个?
| 特性 | UDP | TCP |
|---|---|---|
| 连接方式 | 无连接,直接发 | 面向连接,先握手 |
| 可靠性 | 不保证送达,可能丢包 | 保证送达,自动重传 |
| 延迟 | 低,实时性好 | 高,重传导致抖动 |
| 适用场景 | 实时控制、遥测数据流 | 日志下载、参数上传 |
说白了,MAVLink这种实时性要求高的协议,UDP是首选。你想想看,飞控每秒发50次姿态数据,丢一两包根本无所谓,下一包马上补上。但如果是下载飞行日志,丢一包就得重传整个文件,这时候TCP更靠谱。
4.2.2 端点配置实战
以MAVSDK或MAVROS为例,配置UDP端点通常需要指定:
- 本地IP和端口:本机监听地址,通常设为0.0.0.0:14550
- 远程IP和端口:目标设备地址,如地面站PC的IP:14550
配置示例(MAVSDK C++):
// UDP客户端模式
mavsdk::Mavsdk mavsdk;
mavsdk::ConnectionResult result = mavsdk.add_udp_connection("192.168.1.100:14550");
// UDP服务器模式(监听)
mavsdk::ConnectionResult result = mavsdk.add_udp_connection("0.0.0.0:14550");
配置示例(MAVROS launch文件):
<launch>
<node pkg="mavros" type="mavros_node" name="mavros">
<param name="fcu_url" value="udp://:14550@192.168.1.100:14550"/>
</node>
</launch>
4.3 MAVLink路由器模式
当系统中不止一个MAVLink设备时(比如飞控、机载计算机、摄像头、地面站同时存在),就需要一个路由器来管理数据流向。MAVLink路由器本质上是一个软件中间件,负责转发、过滤、路由MAVLink消息。
4.3.1 为什么需要路由器?
你想想看,飞控通过串口连到机载计算机,机载计算机又通过WiFi连到地面站。如果机载计算机上跑着多个MAVLink应用(比如一个做视觉处理,一个做路径规划),它们都需要从飞控获取数据。没有路由器的话,每个应用都得单独开一个串口——这不现实。
路由器的核心作用:
- 消息转发:从一个端口收到的消息,转发到其他所有端口
- 消息过滤:只转发特定ID的消息,减少带宽浪费
- 协议转换:串口转UDP、UDP转TCP等
- 系统ID管理:确保不同设备的系统ID不冲突
4.3.2 常用路由器工具
我常用的MAVLink路由器有这几个:
| 工具 | 特点 | 适用场景 |
|---|---|---|
| mavlink-router | 轻量级,C语言实现,资源占用低 | 嵌入式平台(如Raspberry Pi) |
| MAVSDK | 功能丰富,支持多语言 | 机载计算机应用开发 |
| QGroundControl | 内置路由器功能 | 地面站端调试 |
| mavproxy | Python实现,扩展性强 | 快速原型验证 |
4.3.3 mavlink-router配置示例
mavlink-router是我在嵌入式平台上用得最多的。它的配置文件很直观:
[General]
MavlinkDialect = "ardupilotmega"
[UdpEndpoint ground_station]
Mode = Normal
Address = 192.168.1.100
Port = 14550
[UdpEndpoint vision_processor]
Mode = Normal
Address = 127.0.0.1
Port = 14560
[SerialEndpoint telem]
Device = /dev/ttyAMA0
Baud = 921600
这个配置的意思是:从串口/dev/ttyAMA0收到的MAVLink消息,同时转发给地面站(192.168.1.100:14550)和本机的视觉处理程序(127.0.0.1:14560)。反过来,地面站或视觉程序发往飞控的消息,也会通过串口送出去。
4.4 链路建立的整体流程
说了这么多,我们来画一张图,把整个链路建立的逻辑串起来。这张图展示了从飞控到地面站的典型通信链路,以及路由器在其中扮演的角色。
这张图展示了一个典型的链路结构。飞控通过串口连到路由器,路由器再通过UDP把数据分发给地面站和视觉处理模块。你想想看,如果没有路由器,视觉模块和地面站都得直接连飞控的串口——但飞控通常只有两三个串口,根本不够用。
4.5 常见链路故障与排查
链路建立不起来,问题通常出在以下几个地方。我按排查优先级列出来:
- 物理连接:线缆是否松动?TX/RX是否接反?GND是否共地?
- 波特率匹配:飞控端和接收端的波特率是否一致?
- 流控设置:硬件流控是否开启但实际未接线?
- IP/端口冲突:UDP端口是否被其他程序占用?
- 防火墙拦截:Windows/Linux防火墙是否放行了UDP端口?
- 系统ID重复:多个设备是否使用了相同的系统ID?
链路建立是MAVLink通信的基础。串口配不好,数据传不过去;UDP/TCP设不对,网络不通;路由器配错了,消息乱飞。把这些基础打牢,后面的故障排查才能事半功倍。