You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MPU9250磁力计航向计算偏差问题求助

ICM20948磁力计航向计算偏差排查

传感器与校准说明

使用Adafruit的ICM20948(对应MPU9250)传感器,输出磁力计原始数据。采用以下方式校准:

  • 以3D"8"字形移动传感器采集数据,待偏移量稳定后停止
  • 偏移量计算方式:
x offset = (max_x+min_x)/2
y offset = (max_y+min_y)/2
z offset = (max_z+min_z)/2
  • 原始数据减去对应偏移量,得到校准后数据

航向计算方法

参考磁力计航向计算文档,使用以下公式:

Direction (y>0) = 90 - [arcTAN(x/y)]*180/PI
Direction (y<0) = 270 - [arcTAN(x/y)]*180/PI
Direction (y=0, x<0) = 180.0
Direction (y=0, x>0) = 0.0

测试偏差数据

实际测试中,航向计算结果存在明显偏差,具体数据如下:

  • 朝向正北(预期0°)时,校准后数据:
x  15.749999999999998
y  -0.9749999999999996
z  47.4

计算结果:40.44°

  • 朝向正东(预期90°)时,校准后数据:
x  4.049999999999999
y  -14.475
z  46.949999999999996

计算结果:84.906°

  • 朝向正西(预期270°)时,校准后数据:
x  1.3499999999999996
y  7.125
z  45.0

计算结果:75.774°

  • 朝向正南(预期180°)时,校准后数据:
x  -11.55
y  -2.9250000000000007
z  46.5

计算结果:128.99°

代码实现

校准数据采集代码

def calibrationDataCollection():
    i2c = board.I2C()  # uses board.SCL and board.SDA
    icm = adafruit_icm20x.ICM20948(i2c)
    
    lx = kbhit.lxTerm()
    lx.start()
    x=[]
    y=[]
    z=[]
    while True:
        if lx.kbhit(): 
            c = lx.getch()
            c_ord = ord(c)
            if c_ord == 32: # Spacebar
                print("\nStop")
                break
        x.append(icm.magnetic[0])
        y.append(icm.magnetic[1])
        z.append(icm.magnetic[2])

        print((max(x)+min(x))/2)
        print((max(y)+min(y))/2)
        print((max(z)+min(z))/2)
        print()
        time.sleep(0.1)
    
    comp_df = pd.DataFrame({"x": x, "y": y, "z": z})
    comp_df["offset_x"] = (comp_df.x.max()+comp_df.x.min())/2
    comp_df["offset_y"] = (comp_df.y.max()+comp_df.y.min())/2
    comp_df["offset_z"] = (comp_df.z.max()+comp_df.z.min())/2
    toCSV(analysisPath, "Calibration_2.csv", comp_df)

校准后数据获取与航向计算代码

def Compass_2():
    i2c = board.I2C()  # uses board.SCL and board.SDA
    icm = adafruit_icm20x.ICM20948(i2c)

    while True:
        x = icm.magnetic[0]- 12.15 #(these are my calibration offsets)
        y = -icm.magnetic[1]+ 6.225
        z = icm.magnetic[2]+ 14.4
        print("x ", x)
        print("y ", y)
        print("z ", z)

        heading = magToHeading2([x,y,z])
        
        print("heading: ", heading)
        time.sleep(0.5)

航向计算函数

def magToHeading2(magnetic):
    heading = -1

    if magnetic[1] > 0:
        heading = 90-math.atan(magnetic[0]/magnetic[1]) * 180 / math.pi
    elif magnetic[1] < 0:
        heading = 270-math.atan(magnetic[0]/magnetic[1]) * 180 / math.pi
    elif magnetic[1] == 0:
        if magnetic[0] < 0:
            heading = 180.0
        else:
            heading = 0.0
    
    return round(heading,3)

疑问

当前计算出的航向始终存在偏差,请问是航向计算方法有误,还是校准步骤需要补充?


内容的提问来源于stack exchange,提问作者Park Bo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 04:57:07