3. MAVLink数据抓取:使用mavlink-router抓包、Wireshark过滤规则

数据抓取,说白了就是给飞控和地面站之间的对话装个窃听器。你想想看,SITL仿真跑起来了,飞机在天上飞,但你根本不知道它和地面站到底在聊什么。这时候就需要一个工具,把所有的MAVLink报文原封不动地截下来。

我个人习惯用mavlink-router来做这件事。它本身是个UDP路由工具,但附带了一个特别好用的抓包功能。嗯,这里要注意,它不是像tcpdump那样抓网卡原始包,而是从MAVLink协议层面把报文结构解析好再存下来。

3.1 为什么不用tcpdump直接抓?

很多新手会问:我直接用tcpdump抓UDP端口不行吗?行,但你会后悔的。

对比项 tcpdump mavlink-router抓包
数据粒度 UDP报文,包含IP/UDP头部 纯MAVLink报文,无网络层开销
解析程度 需要自己解析MAVLink帧 自动解析MSG ID、CRC、序列号
文件大小 大,包含大量冗余信息 小,只保留有效载荷
回放兼容性 需要额外转换 直接用于mavproxy回放

我在项目中遇到过好几次,用tcpdump抓了几个G的pcap文件,结果90%都是IP头部和UDP校验和,真正有用的MAVLink数据反而要写脚本去提取。后来我彻底改用mavlink-router,省心太多了。

3.2 mavlink-router抓包实战

先说说怎么启动。假设你的SITL已经跑在本地,地面站连接的是udp:127.0.0.1:14550。我们启动一个mavlink-router实例,同时开启抓包:

# 启动mavlink-router,开启抓包
mavlink-routerd \
    -e 127.0.0.1:14550 \
    -l /tmp/mavlink_logs \
    --log-file my_flight_$(date +%Y%m%d_%H%M%S).tlog

这里几个参数我解释一下:

  • -e:指定地面站端点,可以多个
  • -l:日志存放目录
  • --log-file:日志文件名,我习惯加时间戳避免覆盖

抓出来的.tlog文件,本质上就是MAVLink报文的二进制序列。你可以用mavproxy直接回放:

mavproxy.py --master=/tmp/mavlink_logs/my_flight_20250321_143022.tlog

我曾经有一次在野外测试,飞机飞着飞着突然掉线。回来一看.tlog文件,发现是某个传感器报文CRC连续出错。要是没有这个抓包文件,我根本没法复现那个问题。

小技巧:抓包文件不要放在/tmp目录下,系统重启就没了。我一般放在/var/log/mavlink/,并配置logrotate自动轮转。

3.3 用Wireshark做深度分析

mavlink-router抓的.tlog文件虽然方便回放,但要做精细的协议分析,还是得靠Wireshark。不过Wireshark默认不认识MAVLink协议,需要装插件。

安装方法很简单:

# 下载MAVLink Wireshark插件
git clone https://github.com/ArduPilot/wireshark_mavlink.git
cd wireshark_mavlink
# 复制到Wireshark插件目录
cp mavlink.lua ~/.local/lib/wireshark/plugins/

重启Wireshark之后,打开抓到的pcap文件(如果你用tcpdump抓的),或者直接打开.tlog文件(Wireshark 3.4以上版本支持)。

这时候你会看到每个UDP报文都被解析成了MAVLink帧。点开一个,能看到MSG ID、系统ID、组件ID、序列号、CRC校验结果。嗯,这里要注意,Wireshark的MAVLink解析器默认只支持MAVLink 1.0,如果你用的是MAVLink 2.0,需要手动开启:

  • 在Wireshark里选择 Edit → Preferences → Protocols → MAVLink
  • 勾选 Use MAVLink 2 protocol

3.4 Wireshark过滤规则实战

抓包文件一大,你就得学会过滤。我总结了几个最常用的过滤规则,你直接复制就能用:

过滤目标 Wireshark过滤表达式 说明
特定MSG ID mavlink.msgid == 0 只显示HEARTBEAT报文
特定系统ID mavlink.sysid == 1 只看飞控发出的报文
特定组件ID mavlink.compid == 1 只看自动驾驶仪组件
CRC错误 mavlink.crc_error == 1 找出所有校验失败的报文
组合过滤 mavlink.msgid == 33 && mavlink.sysid == 1 只看飞控发出的GLOBAL_POSITION_INT

我个人最常用的是mavlink.crc_error == 1。为什么?因为CRC错误往往意味着链路质量差或者协议版本不匹配。有一次客户说他们的无人机经常丢数据,我远程抓了个包,一过滤发现CRC错误率高达15%。后来发现是他们的数传模块波特率设置错了,导致数据在传输过程中被截断。

避坑指南:我曾经在Wireshark里过滤mavlink.msgid == 0,结果发现HEARTBEAT报文每秒钟只出现1次,但实际飞控是1Hz发送的。后来才意识到,Wireshark的MAVLink解析器默认只显示第一个匹配的报文,需要关闭Enable strict MAVLink 2 validation才能看到全部。

3.5 抓包分析的整体流程

说了这么多,我把整个流程画成一张图,方便你理解:

MAVLink数据抓取与分析流程 SITL仿真环境 mavlink-router抓包 生成.tlog文件 mavproxy回放 Wireshark深度分析 过滤规则应用 定位问题 / 协议分析 / 性能评估 说明:.tlog文件可直接回放,也可导入Wireshark做协议级分析

这张图把整个流程串起来了。你从SITL仿真开始,经过mavlink-router抓包生成.tlog文件,然后有两个选择:要么直接用mavproxy回放看飞行数据,要么导入Wireshark做深度分析。Wireshark里再用过滤规则精确定位你关心的报文。

核心要点:
  • mavlink-router抓包生成.tlog文件,比tcpdump更高效
  • Wireshark需要安装MAVLink插件才能解析
  • 过滤规则是分析大文件的利器,尤其是mavlink.crc_error == 1
  • MAVLink 2.0需要手动开启Wireshark解析器设置

好了,这一章的内容就这些。你先把mavlink-router装好,抓一个SITL飞行的.tlog文件,然后用Wireshark打开,试着用我给的过滤规则筛一筛。等你真正上手抓过一次,就会发现这些工具比想象中好用得多。