4. 软件配置故障排查:mavlink-router配置错误、QGroundControl连接设置、MAVSDK初始化参数
软件配置出问题,其实比硬件还让人头疼。硬件坏了你换一个就行,配置错了你得一行一行找。我这些年排查过的通信故障里,至少有一半是配置问题。说白了,MAVLink通信链路上任何一个节点的参数没对齐,数据就传不过去。
这一节我们聚焦三个最常见的软件配置坑:mavlink-router、QGroundControl 和 MAVSDK。这三个东西你肯定都用过,但配置细节你真的吃透了吗?
核心原则:MAVLink通信链路上所有节点的 system_id、component_id、通信端口、波特率、协议版本必须一致。任何一个不匹配,数据就会丢失或错乱。
4.1 mavlink-router配置错误
mavlink-router是PX4生态里最常用的MAVLink路由工具。它的作用说白了就是:把飞控的串口数据转发到多个UDP/TCP终端。配置错了,地面站就收不到数据。
我遇到过最典型的场景:客户说QGC连不上飞机,但飞控的LED灯明明在闪。我一查,mavlink-router的配置文件里UART端口写错了。嗯,这种低级错误其实很常见。
4.1.1 配置文件结构
mavlink-router的配置文件通常叫 mavlink-router.conf,放在 /etc/ 目录下。它的结构其实很简单:
[General]
MavlinkDialect = auto
DebugLogLevel = info
[UartEndpoint to_fc]
Device = /dev/ttyAMA0
Baud = 921600
[UdpEndpoint to_gcs]
Mode = normal
Address = 0.0.0.0
Port = 14550
这里最容易出问题的三个地方:
- Device路径:
/dev/ttyAMA0还是/dev/ttyS0?不同板子不一样。我建议你先用ls -l /dev/tty*确认一下。 - 波特率:飞控端和mavlink-router端必须一致。PX4默认是921600,但有些老固件是57600。
- UDP端口:14550是QGC默认端口,但如果你改了,两边都要改。
注意:mavlink-router默认只监听 0.0.0.0,如果你改成 127.0.0.1,其他设备就连接不上。我曾经帮一个客户排查了整整两天,最后发现就是这个原因。
4.1.2 路由表配置
mavlink-router支持多个Endpoint。你可以同时连接QGC、MAVSDK和日志记录器。但路由表配置不对,数据就会乱窜。
举个例子:
[UdpEndpoint to_gcs]
Mode = normal
Address = 192.168.1.100
Port = 14550
[UdpEndpoint to_sdk]
Mode = normal
Address = 192.168.1.101
Port = 14540
这里有个坑:两个Endpoint的端口不能一样。我见过有人把两个都设成14550,结果QGC和SDK互相抢数据。
我的习惯:给每个Endpoint分配不同的端口。QGC用14550,SDK用14540,日志记录用14530。这样排查问题的时候一眼就能看出来是哪个链路出了问题。
4.1.3 日志级别
mavlink-router的日志级别默认是 info。排查问题时,我建议先调到 debug:
[General]
DebugLogLevel = debug
然后看 /var/log/mavlink-router.log。你会看到类似这样的输出:
[2024-01-15 10:23:45] [debug] UART: received 256 bytes from /dev/ttyAMA0
[2024-01-15 10:23:45] [debug] UDP: sent 256 bytes to 192.168.1.100:14550
如果只有接收没有发送,说明路由表有问题。如果什么都没有,说明串口根本没通。
4.2 QGroundControl连接设置
QGC是大家最常用的地面站。它的连接设置看起来简单,但坑也不少。
4.2.1 通信链路选择
QGC支持三种连接方式:
| 连接方式 | 适用场景 | 常见问题 |
|---|---|---|
| 串口 | 直接连接飞控 | 波特率不匹配、串口被占用 |
| UDP | 通过mavlink-router或WiFi数传 | 端口冲突、防火墙拦截 |
| TCP | 远程连接或仿真环境 | IP地址错误、连接超时 |
我个人最常用的是UDP方式。但要注意:QGC的UDP监听端口默认是14550,如果你改了mavlink-router的端口,QGC这边也要改。
4.2.2 波特率设置
串口连接时,波特率必须和飞控一致。PX4默认是921600,但有些数传模块只支持57600或115200。
我记得有一次,客户说QGC能连上但数据断断续续。我一看,飞控设的是921600,数传模块设的是57600。数据能通才怪。
排查步骤:
- 在QGC的「应用设置」→「通信链路」中确认波特率
- 在飞控的
param show SER_BAUD*中确认实际波特率 - 两者必须完全一致
4.2.3 MAVLink版本
QGC默认使用MAVLink 2.0。但有些老飞控或第三方设备只支持1.0。版本不匹配时,QGC会显示「连接中」但永远连不上。
解决办法:在QGC的「应用设置」→「MAVLink」中,把版本改成1.0试试。如果连上了,说明是版本问题。
注意:MAVLink 2.0向下兼容1.0,但反过来不行。如果你的飞控只支持1.0,QGC必须手动切到1.0模式。
4.2.4 串口别名
Linux下串口设备名会变。今天插上是 /dev/ttyUSB0,明天可能就变成 /dev/ttyUSB1。我建议用udev规则固定别名:
# /etc/udev/rules.d/99-usb-serial.rules
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="ttyFC"
这样不管插哪个USB口,设备名都是 /dev/ttyFC。QGC里直接填这个别名就行。
4.3 MAVSDK初始化参数
MAVSDK是开发者的好帮手。但初始化参数设错了,程序跑起来就是各种诡异问题。
4.3.1 连接URL格式
MAVSDK的连接URL格式很严格。写错一个字符就连不上:
| 连接方式 | URL格式 | 示例 |
|---|---|---|
| 串口 | serial://<设备路径>:<波特率> |
serial:///dev/ttyAMA0:921600 |
| UDP | udp://<IP>:<端口> |
udp://192.168.1.100:14550 |
| TCP | tcp://<IP>:<端口> |
tcp://192.168.1.100:5760 |
注意串口URL的写法:serial:///dev/... 是三个斜杠。我见过有人写成两个斜杠,结果程序一直报连接失败。
4.3.2 超时时间
MAVSDK默认的超时时间是1秒。在WiFi或4G链路上,这个时间可能不够。我建议根据实际网络延迟调整:
#include <mavsdk/mavsdk.h>
mavsdk::Mavsdk mavsdk;
mavsdk::Mavsdk::Configuration config(1, 1); // system_id=1, component_id=1
config.set_timeout_s(3.0); // 超时设为3秒
mavsdk.set_configuration(config);
为什么要调大?因为有些数传模块的延迟能达到500ms以上。1秒超时的话,稍微丢一个包就断连了。
我的经验:在WiFi链路上,超时设2秒;在4G链路上,设5秒。太短容易误判断连,太长又影响响应速度。你可以在实际环境中测试一下,找到最合适的值。
4.3.3 回调注册
MAVSDK的很多功能是通过回调实现的。回调没注册好,数据就收不到。比如:
// 错误写法:回调注册在连接之前
auto telemetry = mavsdk.telemetry();
telemetry->subscribe_position([](mavsdk::Telemetry::Position position) {
std::cout << "Lat: " << position.latitude_deg << std::endl;
});
// 正确写法:先连接,再注册回调
auto result = mavsdk.add_udp_connection("192.168.1.100:14550");
if (result == mavsdk::ConnectionResult::Success) {
auto telemetry = mavsdk.telemetry();
telemetry->subscribe_position(callback);
}
我遇到过有人把回调写在连接之前,结果程序跑起来什么数据都没有。嗯,这个顺序问题其实很隐蔽。
4.3.4 系统ID冲突
MAVSDK默认的system_id是1。如果同一网络里有多个设备都用ID 1,数据就会混乱。我建议给每个设备分配唯一的ID:
mavsdk::Mavsdk::Configuration config(42, 1); // system_id=42, component_id=1
mavsdk.set_configuration(config);
这样在QGC里就能区分不同设备。排查问题时,看一眼system_id就知道数据是从哪个设备来的。
总结一下:软件配置故障排查的核心是「对齐」。端口要对齐、波特率要对齐、版本要对齐、ID要对齐。任何一个环节没对齐,通信就会出问题。我的建议是:每次改配置后,先跑一个简单的ping测试,确认链路通了再往下走。