移动快速后漂移偏航角问题

5
在我目前的项目中,我遇到了与Core Motion的CMAttitude提供的四元数有关的问题。我将iPhone 5(iOS 6.0.1)放置在一个明确定义的起始位置。然后我开始快速移动设备,就像在快节奏游戏中一样。当我在10-30秒后返回起始位置时,报告的偏航角与起始位置相差10-20度(大多数时间约为11°)。
我使用了旧版(可惜现在不再提供)的Core Motion Teapot示例来验证这种影响。记录欧拉角直接从CMAttitude读取: 起始位置 15秒后回到同一位置
        NSLog(@"pitch: %f, roll: %f, yaw: %f",  attitude.pitch * 180 / M_PI, attitude.roll * 180 / M_PI, attitude.yaw * 180 / M_PI);

我在两个不同时间、不同工厂生产的 iPhone 5 设备上发现了这个问题。但真正奇怪的是,我的 iPhone 4 运行 iOS 5.1.1,它的功能却如预期一般正常。我认为这可能是 iOS 的一个 bug,并已经提交了错误报告,但另一方面,我几乎想象不到还没有人遇到过这个问题。我怀疑这可能与重新设计的 Core Motion API 有关。从版本 5 开始,磁力计(指南针)也被视为传感器融合的一部分。控制台显示 locationd 提供的偏差估计值给 CoreMotion:
locationd[41] <Notice>: GYTT inserted: bias,-0.196419,1.749323,-1.828088,variance,0.002644,0.004651,0.002527,temperature,31.554688

我的问题是:使用设备运动时是否有阻止磁力计读数的可能?我尝试关闭位置服务,但没有影响Core Motion。如果不可能,是否有其他选择/解决方法,例如基于加速度计的重力估算?
PS:由于我们处理四元数模型,这与万向锁无关。
编辑:经过更多测量,似乎仅偏航受到影响。俯仰和横滚在容差范围内(<=1°)显示偏差,而偏航则会漂移,无论起始位置如何。CMDeviceMotion.gravity似乎也很干净。
编辑(2):我可以使用附加到最新XCode版本的MotionGraphs示例复制问题。偏航图可重现地从原点漂移。

1
点赞,一个有趣的问题!是的,我也曾经遇到过磁力计的不良体验:它会滞后(导致偏差!)并且非常嘈杂。我还注意到,很容易使陀螺仪饱和,尤其是在快速运动时。有没有办法将饱和排除在嫌疑人之外? - Ali
@Ali 我不知道有什么办法。但另一方面,我的iPhone 4配备iOS 5.1.1也像之前安装的iOS 4.3一样完美运行。这只是猜测,但我认为iOS 6应该是罪魁祸首。 - Kay
希望有人知道答案,很抱歉我无法提供帮助 :( - Ali
现在是2015年9月,我的iPhone 5(2014年购买)和iOS 8.1仍然存在问题。我猜测传感器融合算法没有正确过滤陀螺仪,或者陀螺仪本身不如其他iPhone好。你的错误报告怎么了? - Konstantinos Gaitanis
提交漏洞报告后2个月,他们回答说:“如果设备正在移动,则无法进行陀螺仪偏置估计。如果设备的偏置校准不正确,则其航向在设备运动时会漂移。”我认为这与传感器融合算法中的磁力计部分有关,因为这是校准偏航角的唯一方法。 - Kay
2个回答

5

这不是最终解决方案,但至少是针对我的问题的一种解决方法(我将其保留为未解答状态以邀请您)。结果表明,至少DeviceMotion.gravity没有受到该错误的影响。因此,我决定重新设计这个相当简单的运动检测部分,并使用arcsin (gravity.x/||gravity||)来移动主玩家角色在倾斜设备时侧面转移。

这绝对是第二好的解决方案,因为它破坏了四元数中包含的完整旋转状态的信息。出于战略考虑,我决定以这种方式处理:

  1. 我认为大多数开发者使用重力向量而不是CMAttitude.quaternion进行倾斜运动检测,因为大多数人对四元数数学不是很感兴趣 ;-)因此,与重力向量相关的任何未来错误可能会因更多用户而在测试阶段得到修复。
  2. 如果这是软件漏洞而不是硬件问题(我假设是),并且如果错误将尽快得到修复,则仍有一些设备可能由于某种原因无法更新。因此,潜在未来客户遇到麻烦的风险虽小但是存在。因此,次优解决方案有时可能是最好的选择。

1
我在自己的代码中做了类似的事情,并发现了相同的Z轴旋转漂移(偏航)。 我应用了一个平衡滤波器。 在每个运动管理器时间间隔,我获取当前四元数(z分量),然后将其保存为oldZ,以便在下一组计算中使用。 我的过滤器简单地将NEW z值与紧接在其前面的z值平衡,防止其过快移动。 根据您的硬件和程序的精确公差,您可以通过这种方式很好地管理漂移。 您会看到陀螺仪略微漂移,但随着过滤器继续作用,开始得到纠正。 我的滤波器看起来像这样,并防止超过0.5度的“偏离”:

filtZ = 0.65 * oldZ + 0.35 * z;

0.65和0.35的值是经过实验确定的,建议您在有时间时进行调整。 输出仍将缩放为0-1,然后可以以与您一直在做的相同方式使用(或重新引入四元数,如果必须在整个过程中保留所有4个维度)。


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