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连续出错。要是没有这个抓包文件,我根本没法复现那个问题。
/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%。后来发现是他们的数传模块波特率设置错了,导致数据在传输过程中被截断。
mavlink.msgid == 0,结果发现HEARTBEAT报文每秒钟只出现1次,但实际飞控是1Hz发送的。后来才意识到,Wireshark的MAVLink解析器默认只显示第一个匹配的报文,需要关闭Enable strict MAVLink 2 validation才能看到全部。
3.5 抓包分析的整体流程
说了这么多,我把整个流程画成一张图,方便你理解:
这张图把整个流程串起来了。你从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打开,试着用我给的过滤规则筛一筛。等你真正上手抓过一次,就会发现这些工具比想象中好用得多。