我一直在尝试构建一个可以成功组合罗盘,地磁和陀螺仪数据的滤镜,以产生平滑的增强现实体验。在阅读this帖子以及大量讨论之后,我终于找到了一个很好的算法来纠正我的传感器数据。我读过的大多数例子都展示了如何使用陀螺仪校正加速度计,但不能使用陀螺仪校正罗盘+加速度计数据。这是我已经确定的算法,如果我试着看看场景,如果我没有面向北方,那么我会遇到万向锁。此算法为Balance Filter,而不是仅在3D
中实现初始化步骤:
更新步骤:
为每个轴(x,y,z)积分陀螺仪读数(time_delta *读数)
使用积分
从新旋转的矩阵中找到四元数
从未过滤的加速度计+罗盘数据中找到旋转矩阵(使用OS提供的功能,我认为它使用角度/轴计算)
从上一步生成的矩阵中获取四元数。
在步骤2中生成的四元数(来自陀螺仪)和使用基于某些实验魔法的系数的加速度计数据之间的Sler
转换回矩阵并使用它来绘制场景。
我的问题是,当我面向北方,然后试图向南看时,整个事情都会爆炸,似乎是万向节锁定。在几个万向节锁之后,整个过滤器处于未定义状态。四处搜索我听到每个人都说“只使用四元数”,但我担心这不是那么简单(至少不是我),而且我知道有些东西我只是缺少了。任何帮助将不胜感激。
答案 0 :(得分:4)
使用四元数的最大原因是避免欧拉角的奇点问题。您可以使用陀螺仪数据直接旋转四元数。
答案 1 :(得分:2)
如果信息被延迟或没有特别用处,但可能对其他人有用,就像我在一些研究后发现的那样:
一个。使用kalman(线性或非线性)过滤器,您可以执行以下操作:
湾欧拉率与角度变化的陀螺率不同,因此您需要四元数或欧拉表示::
Quaternion非常重要,但有两个主要步骤----
1. For Roll, pitch,yaw you get three quaternions as cos(w) +sin(v) where w is scalar part and v is vector part (or when coding just another variable)
Then simply multiply all 3 quat. to get a delta quaternion
i.e quatDelta[0] =c1c2*c3 - s1s2*s3;
quatDelta[1] =c1c2*s3 + s1s2*c3;
quatDelta[2] =s1*c2*c3 + c1*s2*s3;
quatDelta[3] =c1*s2*c3 - s1*c2*s3;
where c1,c2,c3 are cos of roll,pitch,yaw and s stands for sin of the same actually half of those gyro pre integrated angles.
2. Then just multiply by old quaternion you had
newQuat[0]=(quaternion[0]*quatDelta[0] - quaternion[1]*quatDelta[1] - quaternion[2]*quatDelta[2] - quaternion[3]*quatDelta[3]);
newQuat[1]=(quaternion[0]*quatDelta[1] + quaternion[1]*quatDelta[0] + quaternion[2]*quatDelta[3] - quaternion[3]*quatDelta[2]);
newQuat[2]=(quaternion[0]*quatDelta[2] - quaternion[1]*quatDelta[3] + quaternion[2]*quatDelta[0] + quaternion[3]*quatDelta[1]);
newQuat[3]=(quaternion[0]*quatDelta[3] + quaternion[1]*quatDelta[2] - quaternion[2]*quatDelta[1] + quaternion[3]*quatDelta[0]);
当您遍历代码时,它会更新,因此只有quatenion是全局变量而不是其余的
3. Lastly if you want Euler angles from them then do the following:
`euler[2]=atan2(2.0*(quaternion[0]*quaternion[1]+quaternion[2]*quaternion[3]), 1-2.0*(quaternion[1]*quaternion[1]+quaternion[2]*quaternion[2]))euler[1]=safe_asin(2.0*(quaternion[0]*quaternion[2] - quaternion[3]*quaternion[1]))euler[0]=atan2(2.0*(quaternion[0]*quaternion[3]+quaternion[1]*quaternion[2]), 1-2.0*(quaternion[2] *quaternion[2]+quaternion[3]*quaternion[3]))`
euler[1] is pitch and so on..
我只想概述四元数实现的一般步骤。可能会有一些小错误,但我自己尝试了这个并且它有效。请注意,当改为欧拉角时,你会得到奇点,也称为“万向节锁”
这里的一个重要注意事项是,这不是我的工作,但我在互联网上找到了它并且想要感谢谁曾经做过这个无价的代码...干杯