3. 磁力计与GPS基础

各位同学,今天我们来聊聊传感器融合里两个绕不开的基础模块——磁力计和GPS。说实话,这两个传感器单独拿出来都不算复杂,但把它们用好,尤其是在地面站里融合起来,这里面的门道可不少。

我最早接触磁力计是在做一款四旋翼的航向估计。当时图省事,直接拿原始数据就用,结果飞机在天上转圈圈,差点炸机。后来才明白,磁力计不校准,那就是个玩具。好,咱们一步步来。

3.1 磁力计工作原理

磁力计,说白了就是测量磁场强度的传感器。它内部有个微小的结构,磁场变化会引起电阻或电压变化,我们读出这个变化,就能知道当前方向的磁场强度。

常用的磁力计芯片有HMC5883L、MAG3110、IST8310等。它们输出的是三轴数据:X、Y、Z,单位通常是微特斯拉(μT)。

地球磁场本身很弱,大约在25到65 μT之间,而且方向是从南指向北(磁北)。所以理论上,磁力计可以告诉我们“北”在哪。但现实很骨感——

⚠ 注意: 磁力计对铁磁性物质极其敏感。你口袋里的一串钥匙,就能让读数偏掉十几度。我见过一个项目,无人机飞控装在碳纤维机架上,结果磁力计读数乱跳,最后发现是机架上的螺丝钉带磁性。

3.2 磁力计校准

为什么要校准?因为磁力计有三大误差源:

  • 硬铁误差: 传感器附近的永久磁铁或带磁金属,造成固定偏移
  • 软铁误差: 铁磁性材料对磁力线的扭曲,造成各向异性
  • 零偏误差: 传感器本身的制造偏差

我个人的习惯是,每次上电后先做一次快速校准。方法很简单:

  1. 把设备水平旋转360度,记录X、Y轴的最大最小值
  2. 再竖直旋转360度,记录Z轴的最大最小值
  3. 计算偏移量:offset = (max + min) / 2
  4. 计算缩放因子:scale = (max - min) / 2

校准后的数据:

calibrated_x = (raw_x - offset_x) / scale_x
calibrated_y = (raw_y - offset_y) / scale_y
calibrated_z = (raw_z - offset_z) / scale_z

嗯,这里要注意:如果你在室内校准,然后拿到室外用,结果可能不准。因为室内有钢筋、管道等干扰。我建议在目标使用环境中校准。

💡 小技巧: 可以用椭球拟合算法做自动校准。采集足够多的点(至少覆盖球面),然后用最小二乘法拟合出椭球参数。我曾经用这个方法,把航向精度从±15度提升到了±3度。

3.3 GPS数据格式(NMEA)解析

GPS模块输出的数据,绝大多数遵循NMEA 0183协议。这是一种纯文本协议,每行以$开头,以回车换行结束。

常用的NMEA语句有:

语句 含义 关键字段
$GPGGA 定位信息 时间、纬度、经度、海拔、卫星数
$GPRMC 推荐最小定位信息 时间、日期、速度、航向
$GPGSA 精度因子与卫星编号 PDOP、HDOP、VDOP
$GPGSV 可见卫星信息 卫星编号、仰角、方位角、信噪比

举个例子,一条真实的$GPGGA语句:

$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47

解析起来其实不复杂。我一般用Python的pynmea2库,几行代码搞定:

import pynmea2

line = "$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47"
msg = pynmea2.parse(line)
print(f"纬度: {msg.latitude}, 经度: {msg.longitude}")
print(f"海拔: {msg.altitude} 米")
print(f"卫星数: {msg.num_sats}")

但如果你像我一样,喜欢自己动手,也可以手写解析器。核心就是按逗号分割,然后根据字段位置取值。注意纬度格式是DDMM.MMMM,需要转换成十进制度数。

🔑 关键点: 纬度转换公式:十进制度数 = 度 + 分/60。例如4807.038表示48度07.038分,即48 + 7.038/60 = 48.1173度。

3.4 GPS定位误差分析

GPS定位误差,说白了就是“卫星告诉你的位置”和“你实际的位置”之间的差距。这个差距有多大?

我实测过,普通民用GPS(单频、无差分)在开阔天空下,水平误差大约2-5米。但一旦有遮挡,误差能飙到10米以上。为什么会这样?

主要误差来源有:

  • 卫星钟差: 卫星上的原子钟也有漂移,虽然很小,但累积起来不可忽略
  • 电离层延迟: 信号穿过电离层时速度变化,这是最大的误差源之一
  • 对流层延迟: 大气中的水汽和温度变化引起
  • 多径效应: 信号反射后到达接收机,造成伪距测量偏差
  • 几何精度因子(DOP): 卫星分布越差,定位误差越大

我记得有一次做地面站测试,GPS定位突然跳了20米。排查了半天,发现是旁边停了一辆大卡车,金属车身造成了严重的多径效应。从那以后,我每次测试都会先确认周围环境。

衡量定位质量,常用HDOP(水平精度因子)。HDOP越小越好:

HDOP值 定位质量
< 1 优秀
1 - 2 良好
2 - 5 中等
> 5 差,不建议使用

在实际项目中,我通常会在代码里加一个HDOP阈值判断。如果HDOP大于3,就降低GPS的权重,或者干脆不用这个数据。

3.5 磁力计与GPS的融合思路

好了,现在我们有磁力计给的航向,有GPS给的位置和速度。怎么把它们结合起来?

一个简单的思路是:用GPS的航向(地面航迹角)来校正磁力计的航向。因为GPS航向在直线运动时很准,但静止或低速时噪声很大。而磁力计航向在静态时稳定,但容易受干扰。

我常用的方法是:

  • 当速度 > 1 m/s 时,用GPS航向作为参考,对磁力计航向做低通滤波
  • 当速度 < 0.5 m/s 时,完全信任磁力计航向
  • 中间速度做加权融合

下面这张图展示了磁力计与GPS融合的基本流程:

磁力计 GPS 磁力计校准 椭球拟合/偏移补偿 NMEA解析 位置/速度/航向提取 误差分析 HDOP/多径/电离层 传感器融合 加权/卡尔曼滤波 磁力计与GPS融合流程

这张图把本章的核心逻辑串起来了。磁力计和GPS各自经过预处理后,进入融合模块。误差分析作为反馈,帮助我们动态调整融合权重。

💡 实战建议: 如果你刚开始做融合,建议先用简单的加权平均。等跑通了,再上卡尔曼滤波。我见过太多人一上来就搞卡尔曼,结果调参调到崩溃。

好了,这一章的内容就到这里。磁力计和GPS是传感器融合的“眼睛”和“耳朵”,把它们的脾气摸透了,后面的融合工作才能事半功倍。


可可精品资料库