iPhone指南针倾斜补偿

发布于 2024-08-27 07:41:17 字数 451 浏览 8 评论 0原文

有人已经编写了 iPhone 罗盘航向倾斜补偿程序吗?

我有一些方法,但一些帮助或更好的解决方案会很酷!

第一的 我定义一个向量 Ev,由 Gv 和 Hv 的叉积计算得出。 Gv 是根据加速度计值构建的重力矢量,Hv 是根据磁力计值构建的航向矢量。 Ev 与 Gv 和 Hv 垂直,因此它正在向水平方向的东方移动。

第二 我定义一个向量 Rv,由 Bv 和 Gv 的叉积计算得出。 Bv 是我的观察向量,它被定义为 [0,0,-1]。 Rv 垂直于 Gv 和 Bv,并且始终显示在右侧。

第三 这两个向量 Ev 和 Rv 之间的角度应该是我修正后的航向。为了计算角度,我构建了点积及其arcos。

phi = arcos ( Ev * Rv / |Ev| * |Rv| )

理论上它应该有效,但也许我必须标准化向量?!

有人对此有解决方案吗?

谢谢,m01d

has anybody already programmed a iphone compass heading tilt compensation?

i have got some approaches, but some help or a better solution would be cool!

FIRST
i define a vector Ev, calculated out of the cross product of Gv and Hv. Gv is a gravity vector i build out of the accelerometer values and Hv is an heading vector built out the magnetometer values.
Ev stands perpendicular on Gv and Hv, so it is heading to horizonatl East.

SECOND
i define a vector Rv, calculated out of the cross product Bv and Gv. Bv is my looking vector and it is defined as [0,0,-1]. Rv is perpendicular to Gv and Bv and shows always to the right.

THIRD
the angle between these two vectors, Ev and Rv, should be my corrected heading. to calculate the angle i build the dot product and thereof the arcos.

phi = arcos ( Ev * Rv / |Ev| * |Rv| )

Theoretically it should work, but maybe i have to normalize the vectors?!

Has anybody got a solution for this?

Thanks, m01d

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绾颜 2024-09-03 07:41:18

是的。你绝对必须正常化。
这是来自我用来提取设备方向的代码。
重力通过加速度计的 x、y、z 获得
的x,y,z获得的

指南针是从航向函数gravity.normalize() ;
指南针.normalize();
compassEast=gravity.cross(compass);
compassEast.normalize();
罗盘北=罗盘东.cross(重力);
compassNorth.normalize();

如果您需要完整的代码,请告诉我。
另外,对于那些还没有见过 iphone 4s 陀螺仪运转的人来说:太神奇了!我将上面的重力和指南针输入替换为陀螺仪的等效输入,结果稳定、流畅、很棒:) Go Apple。

Yep. You DEFINITELY have to normalize.
This is from my code that I use to extract the orientation of the device.
Gravity is obtained as the x,y,z of the accelerometer
and compass is obtained from the x,y,z of the heading function

gravity.normalize();
compass.normalize();
compassEast=gravity.cross(compass);
compassEast.normalize();
compassNorth=compassEast.cross(gravity);
compassNorth.normalize();

Let me know if you need the full code.
Also, for those who havnt yet seen the iphone 4s gyroscope in action: its amazing! I swapped the above input to gravity and compass for the equivalents from the gyro and the result is stable and smooth and awesome :) Go Apple.

无法回应 2024-09-03 07:41:18

我没有收到源代码,但我设置了自己的示例。您可以在此处查看项目和代码: http ://www.sundh.com/blog/2011/09/stabalize-compass-of-iphone-with-gyrscope/

I didn't receive the source code but I set up my own example. You can see the project and code here: http://www.sundh.com/blog/2011/09/stabalize-compass-of-iphone-with-gyroscope/

满地尘埃落定 2024-09-03 07:41:18

是的,我按照上面的描述做了。但结果不是很准确。我认为如果加速度计值更平滑,它应该以这种方式工作。因此,我选择通过将相应轴的加速度值与罗盘值相加/减去来进行倾斜补偿。

这是我的上述解决方案的代码,但它不是最终的工作解决方案:

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading{
if (newHeading != nil) {
float Ax = accelerationValueX;
float Ay = accelerationValueY;
float Az = accelerationValueZ;
float filterFactor = 0.2;
Mx = [newHeading x] * filterFactor + (Mx * (1.0 - filterFactor));
My = [newHeading y] * filterFactor + (My * (1.0 - filterFactor));
Mz = [newHeading z] * filterFactor + (Mz * (1.0 - filterFactor));

float counter = (  -pow(Ax, 2)*Mz + Ax*Az*Mx - pow(Ay, 2)*Mz + Ay*Az*My );
float denominator = ( sqrt( pow((My*Az-Mz*Ay), 2) + pow((Mz*Ax-Mx*Az), 2) + pow((Mx*Ay-My*Ax), 2) ) * sqrt(pow(Ay, 2)+pow(-Ax, 2)) );
headingCorrected = (acos(counter/denominator)* (180.0 / M_PI)) * filterFactor + (headingCorrected * (1.0 - filterFactor));
}
...
}

yes, i did it like described above. but the result is not very accurate. i think with smoother accelerometer values it should work that way. because of this i have choosen to do the tilt compensation by adding/subtracting the accelermoter values of the corresponding axis to/from the compass values.

Here iss my code for the solution above, but its not a final working solution:

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading{
if (newHeading != nil) {
float Ax = accelerationValueX;
float Ay = accelerationValueY;
float Az = accelerationValueZ;
float filterFactor = 0.2;
Mx = [newHeading x] * filterFactor + (Mx * (1.0 - filterFactor));
My = [newHeading y] * filterFactor + (My * (1.0 - filterFactor));
Mz = [newHeading z] * filterFactor + (Mz * (1.0 - filterFactor));

float counter = (  -pow(Ax, 2)*Mz + Ax*Az*Mx - pow(Ay, 2)*Mz + Ay*Az*My );
float denominator = ( sqrt( pow((My*Az-Mz*Ay), 2) + pow((Mz*Ax-Mx*Az), 2) + pow((Mx*Ay-My*Ax), 2) ) * sqrt(pow(Ay, 2)+pow(-Ax, 2)) );
headingCorrected = (acos(counter/denominator)* (180.0 / M_PI)) * filterFactor + (headingCorrected * (1.0 - filterFactor));
}
...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文