4. 软件配置故障排查:mavlink-router配置错误、QGroundControl连接设置、MAVSDK初始化参数

软件配置出问题,其实比硬件还让人头疼。硬件坏了你换一个就行,配置错了你得一行一行找。我这些年排查过的通信故障里,至少有一半是配置问题。说白了,MAVLink通信链路上任何一个节点的参数没对齐,数据就传不过去。

这一节我们聚焦三个最常见的软件配置坑:mavlink-router、QGroundControl 和 MAVSDK。这三个东西你肯定都用过,但配置细节你真的吃透了吗?

核心原则:MAVLink通信链路上所有节点的 system_id、component_id、通信端口、波特率、协议版本必须一致。任何一个不匹配,数据就会丢失或错乱。

软件配置故障排查知识体系 MAVLink通信链路 mavlink-router QGroundControl MAVSDK UART配置 TCP/UDP端口 路由表 日志级别 通信链路 波特率 MAVLink版本 串口别名 连接URL 超时时间 回调注册 系统ID 排查思路:从物理层 → 数据链路层 → 应用层逐层检查 先确认端口通不通,再检查协议版本,最后看路由和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。数据能通才怪。

排查步骤:

  1. 在QGC的「应用设置」→「通信链路」中确认波特率
  2. 在飞控的 param show SER_BAUD* 中确认实际波特率
  3. 两者必须完全一致

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测试,确认链路通了再往下走。