使用Core Motion从加速度计数据获取位移

21
我正在开发一款增强现实应用程序,目前它想在表面上显示一个简单的立方体,并能够在空间中移动(旋转和位移)以便从所有不同角度查看立方体。由于我要求用户将iPhone放在想要放置立方体的表面上,然后按下按钮重置姿态,所以这里不需要校准相机的问题。
使用陀螺仪和Core Motion非常简单地找出相机的旋转情况。我是这样做的:
if (referenceAttitude != nil) {
    [attitude multiplyByInverseOfAttitude:referenceAttitude];
}

CMRotationMatrix mat = attitude.rotationMatrix;

GLfloat rotMat[] = {
    mat.m11, mat.m21, mat.m31, 0,
    mat.m12, mat.m22, mat.m32, 0,
    mat.m13, mat.m23, mat.m33, 0,
    0, 0, 0, 1
};

glMultMatrixf(rotMat);

这个方法非常有效。 但是,当我尝试在加速过程中找到空间位移时,会出现更多问题。 使用Core Motion的Apple Teapot示例只是将加速度向量的x、y和z值添加到位置向量中。这样做(除了没有太多意义之外)会导致在加速后将对象返回到原始位置。(因为加速度从正变为负,或者反之) 他们是这样做的:

translation.x += userAcceleration.x;
translation.y += userAcceleration.y;
translation.z += userAcceleration.z;

我应该怎么样通过加速度(已知时间差)来找到位移?从其他答案中看来,似乎我需要进行两次积分,从加速度得出速度,再从速度得出位置。但是并没有任何代码示例,我认为这并不是必须的。此外,当iPhone还在平面上时,加速计值不为零(我认为存在一些噪声)。我应该过滤这些值多少?我是否应该过滤它们?

4个回答

23
很棒,有人跟我一样遇到了同样的问题,所以值得花些时间研究 :-)
我同意westsider的观点,因为我尝试了几周不同的方法,最终结果非常糟糕。我确信对于更大的距离或超过1到2秒的缓慢运动,都不会有可接受的解决方案。如果你可以接受一些限制,例如小距离(<10厘米)和运动的给定最小速度,那么我相信可能会有找到解决方案的机会 - 完全没有保证。如果是这样,你需要投入很多时间和精力进行研究,而且可能会感到非常沮丧,但是如果成功了,那将非常非常酷 :-) 也许你会发现以下提示有用:
首先,为了简化问题,只看一个轴,例如x轴,但要考虑到左(-x)和右(+x)都有可表示的情况。
是的,你说得对,你必须进行两次积分才能得到位置关于时间的函数。而且在进一步处理之前,应该存储第一次积分的结果(==速度),因为后面的优化需要用到它。要非常小心,因为即使一个微小的错误(例如<0.1%),在做两次积分后也会迅速增长。如果你将加速度计配置为50 Hz,即处理了50个刻度,那么微小的可忽略误差将比“真实”值更快地增加,情况在一秒后会变得更糟。我强烈建议不要依赖梯形法则,而是至少使用辛普森或更高阶的牛顿科茨公式。
如果你成功了,你需要注意设置正确的低通滤波器。我无法给出一般的值,但经验法则是在0.2和0.8之间尝试过滤因子将是一个好的起点。正确的值取决于你的业务需求,例如什么样的游戏,如何快速响应事件等等。
现在你将有一个在某些情况下和短时间内工作得相当好的解决方案。但是过了几秒钟后,你的物体就会漂移出去。现在你将进入解决方案中困难的部分,而这正是我未能在规定的时间范围内处理好的部分 :-(
一个有前途的方法是引入我所谓的“合成力”或“虚拟力”。这是一些策略,用于对多种触发物体漂移的不良情况做出反应,尽管设备在你的手中保持固定(?没有移动)。最麻烦的是速度大于0但没有任何加速度。这是误差传播不可避免的结果,可以通过人为减速来处理,即使没有真正的对应物,也要引入虚拟减速。以下是一个非常简单的例子:
if (vX > 0 && lastAccelerationXTimeStamp > 0.3sec) {

     vX *= 0.9;
}

你需要使用一系列条件来驯服这个野兽。需要尝试多次才能找到正确的方法,这将是问题的难点。

如果您成功破解了代码,请务必告诉我,我非常想知道它是否通用 :-)

祝好 Kay


7
当iPhone 4刚推出时,我花费了很多时间尝试使用加速度计和陀螺仪获取准确的位移。由于设备只需移动几米,并且数据采集通常最多运行几分钟,因此 incremental drift 应该没有太大的担忧。我们尝试了各种方法,甚至得到了几位苹果工程师的帮助。最终,似乎陀螺仪无法胜任这项任务。它对于3D定位非常好,但仅此而已......这是根据非常有见地的工程师所说的。
我很想听到有人反驳这一点——因为应用程序并没有像我们希望的那样成功,等等。

5
我也想在iPhone上获取位移。我没有使用积分,而是使用基本物理公式d = .5a * t ^ 2,并假设初始速度为0(不能假设初始速度为0)。到目前为止,它似乎工作得非常好。
我的问题是我正在使用deviceMotion,但值不正确。deviceMotion.gravity读取接近于0。有任何想法吗?- 好了,解决了,显然deviceMotion.gravity有x、y和z值。如果您不指定需要哪一个,您会得到x(应该接近于0)。

1
d=0.5at^2的问题在于,它需要像http://en.wikipedia.org/wiki/Acceleration中描述的恒定加速度。 - Kay
1
假设v(0) == 0是至关重要的,但我们需要一个起点并且应该接受这一点。在我看来,更关键的部分出现在几秒钟后,当a==0且v!=0时(如我的答案所解释的那样)。 - Kay

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接