4. GPS数据解析:从日志中提取GPS_RAW_INT消息

GPS数据是定位漂移诊断的起点。说白了,如果GPS本身就不靠谱,后面再怎么调EKF、调磁力计都是白费功夫。我个人习惯,拿到一份日志后,第一件事就是看GPS_RAW_INT这条消息。

为什么是它?因为这条消息包含了GPS最原始的状态信息——经纬度、海拔、精度因子、卫星数、定位类型。这些参数能直接告诉你:当前GPS到底能不能用。

4.1 GPS_RAW_INT消息结构

先看消息定义。MAVLink协议里,GPS_RAW_INT的消息ID是24。它的核心字段如下:

字段名 类型 单位 说明
lat int32_t degE7 纬度,放大了1e7倍
lon int32_t degE7 经度,放大了1e7倍
alt int32_t mm 海拔高度,单位毫米
hdop uint16_t 0.1 水平精度因子,实际值需除以10
vdop uint16_t 0.1 垂直精度因子,实际值需除以10
satellites_visible uint8_t - 可见卫星数
fix_type uint8_t - 定位类型:0=无定位,1=无定位,2=2D,3=3D,4=RTK浮点,5=RTK固定

这里有个坑,我刚开始做飞控时踩过——lat和lon是int32_t,但单位是degE7。什么意思?就是实际经纬度 = 原始值 / 1e7。比如日志里lat=373345000,实际纬度就是37.3345000°。如果你直接拿原始值去算距离,那结果会差一千万倍。

注意:alt的单位是毫米,不是厘米。很多日志分析工具默认显示米,但原始数据是mm。如果你自己写解析脚本,记得除以1000。

4.2 如何从日志中提取GPS_RAW_INT

我一般用两种方式提取:一是用现成的工具如MAVLink Inspector或Mission Planner的日志分析功能;二是自己写Python脚本。这里我重点讲脚本方式,因为遇到奇怪问题时,自己动手最踏实。

用pymavlink库,几行代码就能搞定:

from pymavlink import mavutil

# 打开日志文件
mlog = mavutil.mavlink_connection('flight_log.bin')

# 提取所有GPS_RAW_INT消息
gps_msgs = []
while True:
    msg = mlog.recv_match(type='GPS_RAW_INT', blocking=False)
    if msg is None:
        break
    gps_msgs.append(msg)

# 解析第一条
msg = gps_msgs[0]
lat = msg.lat / 1e7
lon = msg.lon / 1e7
alt = msg.alt / 1000.0
hdop = msg.hdop / 10.0
vdop = msg.vdop / 10.0
sats = msg.satellites_visible
fix = msg.fix_type

print(f"纬度: {lat:.7f}, 经度: {lon:.7f}")
print(f"海拔: {alt:.2f} m, HDOP: {hdop:.1f}, VDOP: {vdop:.1f}")
print(f"卫星数: {sats}, 定位类型: {fix}")

嗯,这里要注意一点:recv_match的blocking参数。如果设为True,读到文件末尾会卡住。我习惯用False,然后自己判断None退出。

4.3 关键参数解读:什么才算"好"的GPS?

拿到数据后,怎么判断GPS质量?我列个经验表:

参数 优秀 可用 警告 不可用
fix_type 4或5 (RTK) 3 (3D) 2 (2D) 0或1
卫星数 > 16 10 - 16 6 - 9 < 6
HDOP < 0.8 0.8 - 1.5 1.5 - 3.0 > 3.0
VDOP < 1.2 1.2 - 2.5 2.5 - 4.5 > 4.5

我曾经遇到一个案例:日志里fix_type一直是3,卫星数12颗,看起来没问题。但飞机在空中疯狂画圈。后来仔细一看,HDOP从1.2突然跳到了4.8,持续了3秒又恢复。就是这3秒,EKF被带偏了,位置估计直接漂了十几米。

所以我的建议是:不要只看平均值,要看时间序列上的突变。一个稳定的HDOP 1.5,比忽高忽低的HDOP 0.8更可靠。

4.4 定位漂移的GPS层面诊断流程

下面这张图是我自己总结的GPS诊断流程,每次分析漂移问题我都会走一遍:

GPS定位漂移诊断流程 提取GPS_RAW_INT 检查 fix_type fix_type < 3 ? 是 定位不可靠 否 继续检查卫星数 检查 HDOP / VDOP 综合判断漂移原因 提示:HDOP突变比绝对值更重要,建议绘制HDOP时间序列曲线

这个流程我用了很多次。有一次在山区测试,fix_type一直是3,卫星数也有11颗,但飞机就是飘。我按流程检查HDOP,发现VDOP高达5.2——垂直精度太差,导致高度估计震荡,进而影响了水平位置。后来换了双频GPS模块,VDOP降到1.8,问题解决。

4.5 实战:从日志中定位GPS漂移

假设你拿到一份日志,飞机在悬停时位置漂了5米。怎么用GPS_RAW_INT定位问题?

我一般按这个步骤来:

  1. 提取整段日志的GPS_RAW_INT,按时间排序。
  2. 绘制HDOP时间曲线。看有没有超过2.0的尖峰。
  3. 检查fix_type是否稳定。如果频繁在2和3之间跳变,说明GPS信号不稳定。
  4. 看卫星数变化。如果卫星数突然从14掉到7,大概率是遮挡或干扰。
  5. 对比漂移发生的时间点。在日志里找到位置开始漂移的时刻,看那个时刻的GPS参数是否异常。
小技巧:我习惯把HDOP和位置误差画在同一张图上。如果HDOP尖峰和位置漂移在时间上吻合,那基本可以确定是GPS问题。如果不吻合,那就要怀疑EKF或者传感器融合了。

举个例子。有一次我分析一份日志,发现飞机在2分30秒时开始漂移。我提取了GPS_RAW_INT,发现那个时刻的HDOP从1.2跳到了3.8,持续了2秒。卫星数从14掉到了8。fix_type从3降到了2。三个指标同时恶化,GPS定位肯定不可靠。后来查实是飞到了高压线塔附近,电磁干扰导致GPS信号质量下降。

4.6 常见GPS数据问题及修复建议

根据我的经验,GPS_RAW_INT里常见的问题有这几类:

现象 可能原因 修复建议
fix_type长期为0或1 GPS模块故障、天线损坏、信号被屏蔽 检查天线连接、更换GPS模块、检查安装位置
卫星数少(<8) 遮挡严重、GPS天线位置不佳、干扰 将天线移至机身上方、远离碳纤维和金属
HDOP突然跳变 多路径效应、电磁干扰、卫星几何分布变化 使用双频GPS、增加地面站、避开强电磁环境
经纬度出现"跳点" GPS解算异常、数据丢包后插值错误 检查日志中是否有数据中断、增加GPS故障检测逻辑
海拔剧烈波动 VDOP过大、气压计与GPS高度融合异常 检查VDOP、校准气压计、考虑使用RTK

嗯,这里要特别说一下"跳点"问题。我遇到过最离谱的一次,GPS经纬度在1秒内跳了200米,然后又跳回来。日志里看HDOP和卫星数都正常,但就是跳了。后来发现是GPS模块的固件有bug,在特定卫星几何分布下会输出错误解算结果。换了固件版本就好了。

所以我的经验是:不要只看单个参数,要综合判断。有时候所有指标都正常,但GPS就是不准。这时候就要怀疑GPS模块本身或者固件问题了。

核心要点回顾:

  • GPS_RAW_INT的lat/lon需要除以1e7,alt需要除以1000
  • HDOP和VDOP是判断GPS精度的关键,注意看突变
  • fix_type=3是3D定位的最低要求,RTK(4/5)才是高精度
  • 卫星数少于10颗时要警惕,少于6颗基本不可用
  • 定位漂移诊断要结合时间序列,不能只看平均值