RTIMUlib是如何实现地磁计校准的代码解析
在RTimu.cpp中实现了地磁计的校准,包括偏置和比例系数。偏置量为静态下的零点漂移,比例系数让地磁数据有椭圆变得更圆。
     正常情况下,将地磁计绕某轴旋转一轴,产生的地磁数据是一个圆形,上图中左侧为绕z轴一轴,由x.y的数据围成的圆形,并且圆心在(0,0)的位置,而左侧为引入强磁干扰后,发生了变化。修正的输出可以根据下面的方法来计算:
正常情况下,将地磁计绕某轴旋转一轴,产生的地磁数据是一个圆形,上图中左侧为绕z轴一轴,由x.y的数据围成的圆形,并且圆心在(0,0)的位置,而左侧为引入强磁干扰后,发生了变化。修正的输出可以根据下面的方法来计算:
       1)在磁场干扰的条件下进行,收集数据,设备被旋转360°。
       2)数据进行分析,产生偏差的偏移offset和灵敏度的比例因子scale,以补偿所述干扰。
void RTIMU::setCalibrationData()
{
    float maxDelta = -1;
    float delta;
    if (m_settings->m_compassCalValid) {
        //  find biggest range
        for (int i = 0; i < 3; i++) {
            if ((m_settings->m_compassCalMax.data(i) - m_settings->m_compassCalMin.data(i)) > maxDelta)
                maxDelta = m_settings->m_compassCalMax.data(i) - m_settings->m_compassCalMin.data(i);
        }
        if (maxDelta < 0) {
            HAL_ERROR("Error in compass calibration data\n");
            return;
        }
        maxDelta /= 2.0f;                                       // this is the max +/- range
        for (int i = 0; i < 3; i++) {
            delta = (m_settings->m_compassCalMax.data(i) - m_settings->m_compassCalMin.data(i)) / 2.0f;
            m_compassCalScale[i] = maxDelta / delta;            // makes everything the same range
            m_compassCalOffset[i] = (m_settings->m_compassCalMax.data(i) + m_settings->m_compassCalMin.data(i)) / 2.0f;
        }
    }
    if (m_settings->m_compassCalValid) {
        HAL_INFO("Using min/max compass calibration\n");
    } else {
        HAL_INFO("min/max compass calibration not in use\n");
    }
    if (m_settings->m_compassCalEllipsoidValid) {
        HAL_INFO("Using ellipsoid compass calibration\n");
    } else {
        HAL_INFO("Ellipsoid compass calibration not in use\n");
    }
    if (m_settings->m_accelCalValid) {
        HAL_INFO("Using accel calibration\n");
    } else {
        HAL_INFO("Accel calibration not in use\n");
    }
}
调用:
    if (getCompassCalibrationValid() || getRuntimeCompassCalibrationValid()) {
        m_imuData.compass.setX((m_imuData.compass.x() - m_compassCalOffset[0]) * m_compassCalScale[0]);
        m_imuData.compass.setY((m_imuData.compass.y() - m_compassCalOffset[1]) * m_compassCalScale[1]);
        m_imuData.compass.setZ((m_imuData.compass.z() - m_compassCalOffset[2]) * m_compassCalScale[2]);
}
举例
 从数据中发现的X和Y磁强计的最大输出:
                 Xmin = -0.284gauss Xmax = +0.402gauss
                 Ymin = -0.322gauss Ymax = +0.246gauss
       从中可以看出X轴的数据,X具有更大的反应,我们设置其比例系数为1
                     Xs = 1
       再计算其他比例系数:
                                     (Xmax - Xmin)
                              Ys =   ————————
                                     (Ymax - Ymin)
   
                                      (Xmax - Xmin)
                              Zs =   ————————
                                      (Zmax - Zmin)
偏置量:
    Xoffset = (Xmax + Xmin)/2
     Yoffset = (Ymax + Ymin)/2 
      Zoffset = (Zmax + Zmin)/2 
    
输出:
y =(y-offset_y)*Ys
水平测试,得到的方位角 = arctanYH/XH
 非水平测试,需要使用加速计进行倾角补偿,先计算出翻滚角Roll和俯仰角Pitch,然后计算Heading值:
                      XH = xcos(P)+Ysin(R)sin(P)-Zcos(R)sin(p)
                      YH = Ycos(R)+Z*sin(R)
 





