从陀螺仪数据中找到四元数?

时间:2011-10-15 16:54:22

标签: linear-algebra

我一直在尝试构建一个可以成功组合罗盘,地磁和陀螺仪数据的滤镜,以产生平滑的增强现实体验。在阅读this帖子以及大量讨论之后,我终于找到了一个很好的算法来纠正我的传感器数据。我读过的大多数例子都展示了如何使用陀螺仪校正加速度计,但不能使用陀螺仪校正罗盘+加速度计数据。这是我已经确定的算法,如果我试着看看场景,如果我没有面向北方,那么我会遇到万向锁。此算法为Balance Filter,而不是仅在3D

中实现

初始化步骤:

  • 使用(嘈杂)加速度计和罗盘传感器数据初始化世界旋转矩阵(这已由Android提供)

更新步骤:

  • 为每个轴(x,y,z)积分陀螺仪读数(time_delta *读数)

  • 使用积分

  • 提供的欧拉角旋转世界旋转矩阵
  • 从新旋转的矩阵中找到四元数

  • 从未过滤的加速度计+罗盘数据中找到旋转矩阵(使用OS提供的功能,我认为它使用角度/轴计算)

  • 从上一步生成的矩阵中获取四元数。

  • 在步骤2中生成的四元数(来自陀螺仪)和使用基于某些实验魔法的系数的加速度计数据之间的Sler

  • 转换回矩阵并使用它来绘制场景。

我的问题是,当我面向北方,然后试图向南看时,整个事情都会爆炸,似乎是万向节锁定。在几个万向节锁之后,整个过滤器处于未定义状态。四处搜索我听到每个人都说“只使用四元数”,但我担心这不是那么简单(至少不是我),而且我知道有些东西我只是缺少了。任何帮助将不胜感激。

2 个答案:

答案 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.. 

我只想概述四元数实现的一般步骤。可能会有一些小错误,但我自己尝试了这个并且它有效。请注意,当改为欧拉角时,你会得到奇点,也称为“万向节锁”

这里的一个重要注意事项是,这不是我的工作,但我在互联网上找到了它并且想要感谢谁曾经做过这个无价的代码...干杯