我想用Arduino和QMC5883制作指南针。现在,磁力计只向我输出 X Y Z 值,我必须自己计算其余的值。到目前为止,我已经用过这个:
float azimuth = atan2(x, y) * 180.0/PI;
但它有很多缺陷,而且很容易向任何方向倾斜。是否有更好的算法(例如手机制造商使用的算法)?如果需要的话,我可以使用加速度计来寻求帮助。
BBC micro:bit 的设备抽象层 (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);
}
我无法让上述内容为我工作,它缺少几个 -ve 标志。以下编辑版本;
float sinRoll = sin(roll_rads);
float cosRoll = cos(roll_rads);
float sinPitch = sin(pitch_rads);
float cosPitch = cos(pitch_rads);
float LHS = -x*cosPitch + y*sinPitch*sinRoll + z*sinPitch*cosRoll;
float RHS = z*sinRoll - y*cosRoll;
float bearing = atan2(-LHS, RHS) * 57.3;
bearing += 90;
if(bearing < 0) bearing += 360;
现在返回倾斜补偿。