文章封面

欢迎关注QQ频道:电赛工坊

文章目录

  • 1. 磁力计:MPU6050的“导航仪”
    • 1.1 为什么MPU6050独木难支?
    • 1.2 磁力计如何化身“指南针”?
  • 2. 方向认知避坑指南
    • 2.1 磁北 vs 真北:地球的“双重人格”
    • 2.2 磁偏角 vs 航向角:导航界的“相对论”
  • 3. 磁力计 航向角计算四部曲(附参考代码)
  • 4. 磁力计校准:从“变形金刚”到“完美球体”的蜕变
    • 4.1 硬铁干扰:传感器的“偏执症”
    • 4.2 软铁干扰:磁场的“哈哈镜效应”
  • 5. 终极验证:你的磁力计准不准?笔者の检验指南

1. 磁力计:MPU6050的“导航仪”

大家都说MPU6050配磁力计更好,从六轴升级到九轴听起来很厉害,但这个磁力计到底有什么魔法?让我们揭开它的神秘面纱。

1.1 为什么MPU6050独木难支?

MPU6050就像个“半盲的体操运动员”:

  • 加速度计:能通过重力感应完美表演前滚翻(pitch)和侧手翻(roll),但在水平转圈(Z轴旋转)时完全找不到北。
  • 陀螺仪:可以精确测量转圈速度,但就像蒙眼转圈——转着转着就晕了(积分误差)。即使只有0.1°/s的微小偏差,1分钟后误差就会累积到6度!

1.2 磁力计如何化身“指南针”?

QMC5883L磁力计就像给MPU6050装上了“电子罗盘”:

  • 直接感知地球磁场,提供绝对航向坐标(就像GPS的固定锚点)。
  • 定期给陀螺仪“矫正记忆”:当陀螺仪说“我转了30度”,磁力计可以验证“不对,实际是28度”。

举个生动例子:就像蒙眼走路:

  • 纯陀螺仪方案:只能通过数步数估算走了多远,误差会逐步累积而且会越来越大。
  • 融合磁力计方案:相当于每走10步就看一眼路牌,会重置累积误差。

2. 方向认知避坑指南

刚开始鼓弄磁力计时,笔者举着模块对着手机指南针校准,结果发现根本对不上——这可不是模块坏了,而是被这几个概念坑了!今天就带大家避开这些坑。

2.1 磁北 vs 真北:地球的“双重人格”

磁北方向指的是地球磁场北极的方向,这是由地核熔融金属流动产生的磁场决定的,随时间缓慢移动(年变化约10~50公里)。2023年我国几个主要城市的磁偏角如下

城市 磁偏角
哈尔滨 -10.3°
北京 -5.8°
上海 -4.5°
广州 -2.1°
笔者所在城市 -7.3°

列这个表并不是废话,后面要考的!

真北方向是地球地理北极的方向,即经线汇聚点,是由由地球自转轴决定,固定不变。

2.2 磁偏角 vs 航向角:导航界的“相对论”

磁偏角指的是磁北与真北偏差的角度,由 地球磁场分布 决定,同一地理位置基本固定(年变化极小,约0.1°~0.3°/年)。

磁航向角指的是磁力计当前朝向与 磁北(Magnetic North) 的夹角。

3. 磁力计 航向角计算四部曲(附参考代码)

笔者这里使用的是QMC5883L(HMC5883L的国产替代),QMC5883L中有几个寄存器,里面存储着设备检测的地磁场在X、Y、Z三个方向的分量。

#define QMC5883L_REG_DATA_OUT_X_LSB  0x00
#define QMC5883L_REG_DATA_OUT_X_MSB  0x01
#define QMC5883L_REG_DATA_OUT_Y_LSB  0x02
#define QMC5883L_REG_DATA_OUT_Y_MSB  0x03
#define QMC5883L_REG_DATA_OUT_Z_LSB  0x04
#define QMC5883L_REG_DATA_OUT_Z_MSB  0x05

(一)读取原始磁场数据

QMC5883L_RawData raw;
Med_Qmc5883l_ReadRawData(&raw);  // 获取XYZ三轴原始值

(二)将原始值转换为高斯单位

// ±8G量程下的转换公式(32768=2^15)
float gauss[3];
gauss[0] = raw.x * (8.0f / 32768.0f);  // X轴(East-West方向)
gauss[1] = raw.y * (8.0f / 32768.0f);  // Y轴(North-South方向) 
gauss[2] = raw.z * (8.0f / 32768.0f);  // Z轴(垂直方向,水平时可忽略)

(三)计算航向角(核心算法)

磁航向角计算公式

#include <math.h>

// 使用atan2计算方位角(自动处理象限问题)
float heading_rad = atan2(gauss[1], gauss[0]);  // Y/X的反正切(弧度)

(四)角度转换与归一化

// 弧度转角度(180°/π≈57.2958)
float heading_deg = heading_rad * 57.2958f;

// 角度归一化到0-360°
if(heading_deg < 0) heading_deg += 360.0f;
if(heading_deg >= 360.0f) heading_deg -= 360.0f;

4. 磁力计校准:从“变形金刚”到“完美球体”的蜕变

磁力计的校准主要是为了补偿两种主要干扰——硬铁干扰和软铁干扰。

4.1 硬铁干扰:传感器的“偏执症”

硬铁干扰通常是由于磁力计内部永磁体或固定磁场的干扰,导致传感器输出存在固定偏移,我们采用偏移校正法来解决。在校准时我们需缓慢旋转设备至少2圈,尽量覆盖所有方向,在这个过程中记录下各轴数据的最大值(gMaxValue)和最小值(gMinValue)并计算偏移量

offset = (gMaxValue[i] + gMinValue[i]) / 2.0f;  // 各轴的零偏

4.2 软铁干扰:磁场的“哈哈镜效应”

软铁干扰通常是由于金属外壳或导磁材料的影响,导致磁力计各轴灵敏度不一致,磁场响应呈椭圆形,这就像手机镜头派出的畸变照片。软铁干扰的校准主要分如下步骤

// 1.计算各轴动态半径
float avgDelta[3];
for(int i=0; i<3; i++) {
    avgDelta[i] = (gMaxValue[i] - gMinValue[i]) * 0.5f;
}

// 2.求理想球体半径(三轴平均)
float avgRadius = (avgDelta[0] + avgDelta[1] + avgDelta[2]) / 3.0f;

// 3.计算比例因子(椭圆变圆)
float scale[3];
for(int i=0; i<3; i++) {
    scale[i] = avgRadius / avgDelta[i];  // 归一化处理
}

整个校准过程实际就是将椭球分布的数据归一化为球形分布。

5. 终极验证:你的磁力计准不准?笔者の检验指南

介绍了这么多,我们总归是要验证一下我们测得的数据到底是不是正确的,下面是笔者的验证思路。

之前我们介绍了几个概念,其中磁偏角在地球上的相同位置位置是几乎不变的,而根据磁偏角和磁航向角的概念我们可以知道

磁力计与真北方向的偏角 = 磁偏航角 + 所在位置的磁偏角(带符号)

我们可以使用手机的指南针(记得校正)来测出一个真北方向,之后将设备朝向这个真北方向(一定注意设备水平放置,X轴朝向测出的真北方向),最后我们会得到一个角度值,这个角度之应该就是我们所在位置的磁偏角!没错,经过测试,笔者测得的磁偏角和2023年的官方测量结果基本吻合,足以证明我们数据的正确性!

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐