【问题标题】:Finding a Quaternion from Gyroscope Data?从陀螺仪数据中找到四元数?
【发布时间】:2011-10-15 16:54:22
【问题描述】:

我一直在尝试构建一个过滤器,该过滤器可以成功地结合指南针、地磁和陀螺仪数据,以产生流畅的增强现实体验。在阅读了this 的帖子以及大量讨论之后,我终于找到了一个很好的算法来纠正我的传感器数据。我读过的大多数例子都展示了如何用陀螺仪校正加速度计,但不能用陀螺仪校正罗盘+加速度计数据。这是我已经确定的算法,它工作得很好,除了如果我不面向北方时尝试看场景会遇到万向节锁定。这个算法是Balance Filter,只是而不是只在3D中实现

初始化步骤:

  • 使用(嘈杂的)加速度计和指南针传感器数据初始化世界旋转矩阵(Android 已经提供)

更新步骤:

  • 整合每个轴(x、y、z)的陀螺仪读数(time_delta * 读数)

  • 使用积分提供的欧拉角旋转世界旋转矩阵

  • 从新旋转的矩阵中找到四元数

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

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

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

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

我的问题是,当我面向北方然后尝试向南看时,整个事情都爆炸了,而且似乎是万向节锁定。经过几次云台锁定后,整个过滤器处于未定义状态。环顾四周,我听到每个人都在说“只需使用四元数”,但恐怕它不是那么简单(至少对我来说不是)而且我知道我只是缺少一些东西。任何帮助将不胜感激。

【问题讨论】:

  • 您的问题实在是太笼统和模糊,无法以这种格式很好地回答。如果您想了解不同方法的优缺点,请使用 Goggle、Wikipedia 或优秀的游戏开发者论坛来获取许多可用文章的指针。否则,请尝试提出更具体的问题。
  • 是的,同意。但是我很犹豫是否要发布代码:(但是我确实找到了解决方案:D
  • 你最后怎么样了?你只是使用欧拉角吗?您是否遭受云台锁的困扰?

标签: linear-algebra


【解决方案1】:

使用四元数的最大原因是为了避免欧拉角的奇异性问题。您可以使用陀螺仪数据直接旋转四元数。

【讨论】:

    【解决方案2】:

    如果信息被延迟或不是特别有用,但可能对其他人有用,因为我在一些研究后发现它可能对其他人有用:::

    一个。使用卡尔曼(线性或非线性)过滤器执行以下操作 ::

    陀螺仪积分三角角,而加速度计告诉您外部极限。

    b.欧拉率不同于陀螺角变化率,因此您需要四元数或欧拉表示::

    四元数很重要,但两个主要步骤是----

    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]);
    

    当你遍历代码时,它会被更新,所以只有四元数是全局变量,其余的不是

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

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

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

    【讨论】:

    • roll,pitch,yaw 四元数乘法的顺序如何,因为roll x pitch 不等于pitch x roll
    猜你喜欢
    • 1970-01-01
    • 2014-06-23
    • 2015-09-15
    • 2017-12-20
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多