我坚持使用arduino成功倾斜补偿我的9DOF IMU。我知道这不是通常的语法问题,而是一种数学本质,但任何人都可以帮忙吗?
问题是当我在保持相同的偏航方向的同时以滚动和/或俯仰方式移动传感器时,偏航角不会保持恒定。
float Ax; float Ay; float Az // these are raw accelerometer readings
float Magx; float Magy; float Magz // these are raw magnetometer readings
float RollAngle; float PitchAngle; float YawAngle; // these are calculated angles from raw readings
RollAngle = atan2(Ay,Az);
PitchAngle = atan2((-Ax),((Ay*sin(RollAngle)) + Az*cos(RollAngle)));
YawAngle = atan2( (Magz*sin(RollAngle)-Magy*cos(RollAngle)) , ((Magx*cos(PitchAngle))+(Magy*sin(PitchAngle)*sin(RollAngle))+Magz*sin(PitchAngle)*cos(RollAngle)) );
有人有任何想法吗?
答案 0 :(得分:0)
我有一些不同的计算,我最近基于我之前做过的ruby实现实现了。我手边没有细节,我可以尝试找到它们并稍后添加它们,但我认为你的问题可能是使用atan2作为音高。 我认为您的计算基于您链接到的数据表中的以下公式。
tan(φ) = (Gpy/Gpx) // eq 13 tan(θ) = (-Gpx / (Gpy sin(φ) + Gpz cos(φ)) // eq 15
doc说的那些。
由于等式13,15和22具有无穷多个解 360°的倍数,限制解决方案是标准惯例 用于横向,俯仰和偏航,范围为-180°至180°。再进一步 对桨距角施加约束以将其限制在-90°的范围内 到90°。这确保了罗盘只有一种独特的解决方案, 任何手机方向的俯仰和滚转角度。方程 13 和22 因此,使用软件 ATAN2 功能(带输出)进行计算 角度范围 -180°至180°)和方程 15 用软件计算 ATAN功能(输出角度范围 -90°至90°)。
如果您有兴趣,这是我的计算。 (正如我所说,我没有关于如何提出这些内容的文档。
float xM = magCurrent[0] - magOffsets[0];
float yM = magCurrent[1] - magOffsets[1];
float zM = magCurrent[2] - magOffsets[2];
float heading = (atan2(yM, xM) * 180) / Pi;
if (heading < 0) {
heading = 360 + heading;
}
logger.infoln("Compass Heading: %f", heading);
float g = 9.8;
float xG = (accelCurrent[0] - accelOffsets[0]) / g;
float yG = (accelCurrent[1] - accelOffsets[1]) / g;
float zG = (accelCurrent[2] - accelOffsets[2]) / g;
float pitch = atan2(-xG, sqrt(yG * yG + zG * zG));
float roll = atan2(yG, zG);
logger.infoln("pitch: %f", pitch * 180 / Pi);
logger.infoln("roll: %f", roll * 180 / Pi);
float xM2 = xM * cos(pitch) + zM * sin(pitch);
float yM2 = xM * sin(roll) * sin(pitch) + yM * cos(roll) - zM * sin(roll) * cos(pitch);
float compHeading = (atan2(yM2, xM2) * 180 / Pi);
if (compHeading < 0) {
compHeading = 360 + compHeading;
}
logger.infoln("tilt compensated Compass Heading: %f", compHeading);
答案 1 :(得分:0)
尝试对您的代码进行以下更改:
float pitch = atan2(-xG, zG);
float roll = atan2(yG, zG);
...
float xM2 = xM * cos(pitch) + zM * sin(pitch);
float yM2 = yM * cos(roll) - zM * sin(roll);
答案 2 :(得分:0)
有时加速度计和磁力计不在同一坐标内,因此您首先应定义一个转换坐标,以将磁力计坐标映射到加速度计坐标。就像是: modeling and control mark W.spong 那么您应该考虑上面的变换坐标来计算倾斜变换: R = R1(坐标变换)* R2(倾斜变换) 但通常情况下,您可以在倾斜转换中随意添加负项:
double xhorizental = (-/+)x*cos(pitch) (-/+)y*sin(pitch)*sin(roll)
(-/+)z*sin(pitch)*cos(roll);
double yhorizental = (-/+)y*cos(roll) (-/+)z*sin(roll);
heading = atan2(yhorizental,xhorizantal) (+PI)