如何从磁力计的X Y Z值计算方位角?

时间:2019-07-19 23:05:36

标签: arduino compass-geolocation magnetometer

我想用Arduino和QMC5883作指南针。现在,磁力计仅向我输出X Y Z值,我必须自己计算其余的值。到目前为止,我已经使用了:

float azimuth = atan2(x, y) * 180.0/PI;

但是它很容易出错,并且容易向任何方向倾斜。有没有更好的算法,例如电话制造商使用的算法?如果需要的话,我可以使用加速度计来寻求帮助。

1 个答案:

答案 0 :(得分:1)

BBC micro:bit的device abstraction layer (DAL)包含此代码,用于根据从加速度计数据得出的角度进行倾斜调整。来自https://github.com/lancaster-university/microbit-dal/blob/master/source/drivers/MicroBitCompass.cpp

/**
 * Calculates a tilt compensated bearing of the device, using the accelerometer.
 */
int MicroBitCompass::tiltCompensatedBearing()
{
    // Precompute the tilt compensation parameters to improve readability.
    float phi = accelerometer->getRollRadians();
    float theta = accelerometer->getPitchRadians();

    // Convert to floating point to reduce rounding errors
    Sample3D cs = this->getSample(NORTH_EAST_DOWN);
    float x = (float) cs.x;
    float y = (float) cs.y;
    float z = (float) cs.z;

    // Precompute cos and sin of pitch and roll angles to make the calculation a little more efficient.
    float sinPhi = sin(phi);
    float cosPhi = cos(phi);
    float sinTheta = sin(theta);
    float cosTheta = cos(theta);

    // Calculate the tilt compensated bearing, and convert to degrees.
    float bearing = (360*atan2(x*cosTheta + y*sinTheta*sinPhi + z*sinTheta*cosPhi, z*sinPhi - y*cosPhi)) / (2*PI);

    // Handle the 90 degree offset caused by the NORTH_EAST_DOWN based calculation.
    bearing = 90 - bearing;

    // Ensure the calculated bearing is in the 0..359 degree range.
    if (bearing < 0)
        bearing += 360.0f;

    return (int) (bearing);
}