3. 磁力计工作原理:地磁场模型、磁力计输出模型(硬铁/软铁干扰)

各位同学,欢迎来到第三章。

前两章我们把陀螺仪和加速度计聊透了。但有个问题一直悬着——偏航角(Yaw)的漂移。陀螺仪积分出来的航向,时间一长就不知道偏到哪去了。加速度计也帮不上忙,它测不了水平旋转。

怎么办?

得请磁力计出场了。

3.1 地磁场模型——地球本身就是个大磁铁

先说说地磁场。说白了,地球内部有一个类似条形磁铁的结构,磁力线从南极附近出来,弯向北极附近进去。注意,我说的「磁北极」其实在地理南极附近,这个细节很多人搞混。

地磁场有几个关键参数:

  • 总强度 F:大约 25-65 μT,看你在地球哪个位置
  • 磁偏角 D:磁北与真北之间的夹角。这个值随地点变化,北京大概是 6° 左右偏西
  • 磁倾角 I:磁力线与水平面的夹角。赤道附近接近 0°,两极接近 90°

我当年在做一个户外导航项目时,直接拿磁力计读数当航向用,结果在北方地区偏了十几度。查了半天才发现——忘了补偿磁偏角。嗯,这个坑我先替你们踩了。

地磁场模型可以用一个简单的偶极子模型近似:

// 地磁场近似模型(单位:nT)
// 位置:北京(北纬39.9°,东经116.4°)
// 使用IGRF模型简化计算
double B_north = 29400;  // 北向分量
double B_east  = -1200;  // 东向分量(负值表示偏西)
double B_down  = 46200;  // 垂直向下分量

// 总强度
double B_total = sqrt(B_north*B_north + B_east*B_east + B_down*B_down);
// 结果约 54800 nT = 54.8 μT

你想想看,这个磁场强度其实很弱。比你家冰箱门上的磁铁弱了上百倍。所以磁力计对环境干扰极其敏感——这也是我们接下来要重点解决的问题。

3.2 磁力计输出模型——理想情况 vs 现实世界

理想情况下,磁力计三轴输出应该是一个以原点为中心的球体。你旋转传感器,读数在三维空间里画出一个完美的球面。

但现实呢?

我做了这么多年惯性导航,还没见过哪个磁力计直接输出就是完美球面的。干扰无处不在。

磁力计的输出模型可以写成:

B_measured = S * C * (B_earth + B_hard) + B_soft + n

其中:

  • B_measured:磁力计实际读出的值
  • S:比例因子矩阵(三轴灵敏度不一致)
  • C:非正交误差矩阵(三轴不是严格90°)
  • B_earth:真实地磁场向量
  • B_hard:硬铁干扰(后面细说)
  • B_soft:软铁干扰(后面细说)
  • n:测量噪声

看着复杂是吧?别急,我们拆开来看。

3.3 硬铁干扰——固定偏移,像个直流偏置

硬铁干扰,说白了就是传感器附近有永磁体或者被磁化的金属。比如:

  • 扬声器的磁铁
  • 电机里的永磁体
  • PCB上的螺丝、铁壳
  • 电池本身(有些电池带有磁性)

这些干扰的特点是:大小和方向固定,不随传感器旋转而改变。在三维空间里,它就是把整个球体平移了一个固定的向量。

硬铁干扰的数学表达:

B_measured = B_earth + B_hard

其中 B_hard 是一个常向量 [hx, hy, hz]^T

我曾经调试一个无人机飞控,发现磁力计读数总是偏向东北方向。拆开外壳一看,GPS模块的陶瓷天线下面贴了一块铁氧体磁片——嗯,就是它搞的鬼。

校准方法: 硬铁干扰可以通过旋转传感器,采集多组数据,然后找球心偏移来消除。说白了就是找到那个被平移了的球体的球心坐标。

// 硬铁校准:找球心偏移
// 采集N组数据,求平均值就是硬铁偏移
float hard_iron[3] = {0};
for(int i = 0; i < N; i++) {
    hard_iron[0] += mag_data[i].x;
    hard_iron[1] += mag_data[i].y;
    hard_iron[2] += mag_data[i].z;
}
hard_iron[0] /= N;
hard_iron[1] /= N;
hard_iron[2] /= N;

// 校准后的数据
float calibrated_x = raw_x - hard_iron[0];
float calibrated_y = raw_y - hard_iron[1];
float calibrated_z = raw_z - hard_iron[2];

3.4 软铁干扰——各向异性,像个变形器

软铁干扰就麻烦多了。它来自铁磁性材料(比如纯铁、硅钢片)对磁力线的扭曲。这些材料本身不带磁性,但它们会改变磁场的分布。

举个例子:你把一块铁板放在磁力计旁边,地磁场穿过铁板时,磁力线会被「吸引」过去。结果就是,磁力计在不同方向上测到的磁场强度不一样。

软铁干扰的特点是:与方向有关。在三维空间里,它把球体变成了椭球体。

软铁干扰的数学表达:

B_measured = S * C * B_earth + B_hard

其中 S*C 是一个 3x3 的矩阵,包含了比例因子、非正交和软铁效应

你想想看,硬铁干扰只是平移,软铁干扰却是拉伸和旋转。校准起来自然更费劲。

⚠️ 重要提醒:

软铁干扰会随着电路板布局、外壳材料、甚至电池位置的变化而改变。同一个磁力计,装在不同的设备上,软铁参数完全不同。所以——每台设备都需要单独校准。

3.5 硬铁 + 软铁联合校准——椭球拟合

实际项目中,硬铁和软铁干扰是同时存在的。我们需要把两者一起校准。

校准的思路是这样的:

  1. 旋转传感器,采集足够多的数据(至少覆盖各个方向)
  2. 这些数据在三维空间里形成一个椭球
  3. 用椭球拟合算法求出:球心偏移(硬铁)和椭球形状(软铁)
  4. 用求出的参数反向补偿原始数据

我习惯用最小二乘法做椭球拟合。代码实现大概长这样:

// 椭球拟合校准(简化版)
// 输入:原始磁力计数据数组
// 输出:校准矩阵 A (3x3) 和 偏移向量 b (3x1)

// 1. 构建椭球方程:ax² + by² + cz² + 2fyz + 2gxz + 2hxy + 2px + 2qy + 2rz + d = 0
// 2. 用最小二乘法求解系数
// 3. 从系数中提取 A 和 b

// 校准后的数据
// B_calibrated = A * (B_raw - b)

// 实际项目中建议使用成熟的椭球拟合库
// 比如:Magneto 或 MotionCal

💡 我的经验:

采集数据时,别只在一个平面里转。要像画「8」字一样,让传感器在三维空间里各个方向都走一遍。我见过有人只水平转了一圈就做校准,结果俯仰角一变化,航向就飘了。

3.6 本章知识体系

下面这张图总结了磁力计从原理到校准的完整链路:

磁力计工作原理与校准知识体系 地磁场模型 总强度 F 磁偏角 D · 磁倾角 I 输出模型 比例因子 S 非正交误差 C 干扰类型 硬铁干扰(平移) 软铁干扰(拉伸) 校准方法 硬铁校准:求球心偏移 软铁校准:椭球拟合(3x3矩阵) 校准后输出 B_calibrated = A · (B_raw - b) 图:磁力计从地磁场模型到校准输出的完整链路

3.7 避坑指南

最后,分享几个我这些年踩过的坑:

  • 别在通电瞬间校准——电流变化会产生瞬态磁场,等系统稳定了再采集数据
  • 远离大电流导线——10A以上的电流产生的磁场,足以让磁力计读数偏好几度
  • 注意温度变化——磁力计的零偏会随温度漂移,要求高的场合要做温度补偿
  • 校准后验证——转一圈看看航向是否平滑,有没有突变点

我曾经在一个机器人项目里,磁力计怎么校准都不对。折腾了两天,最后发现是底盘电机驱动板上的大电容——充放电时产生的磁场干扰。后来把磁力计用排线拉高了5厘米,问题就解决了。有时候,物理隔离比算法补偿更管用。

好了,磁力计的原理和干扰模型就聊到这里。下一章我们把这些知识串起来,开始写真正的融合代码。


公众号:蓝海资料掘金营,微信deep3321