在我目前的项目中,我遇到了Core Motion的CMAttitude提供的四元数问题。我把iPhone 5(iOS 6.0.1)放在一个定义良好的起始位置。然后我开始快速移动设备,就像在快速起搏游戏中一样。当我在10-30秒后返回起始位置时,报告的偏航角与起始位置相差10-20度(大部分时间≈11°)。
我使用旧的(可悲的是不再可用的)Core Motion Teapot样本来验证效果。用于记录的欧拉角直接从CMAttitude:
读取
NSLog(@"pitch: %f, roll: %f, yaw: %f", attitude.pitch * 180 / M_PI, attitude.roll * 180 / M_PI, attitude.yaw * 180 / M_PI);
我在不同工厂的不同时间制造的两台不同的iPhone 5设备上发现了这一点。但真的很奇怪的是,运行iOS 5.1.1的 iPhone 4正在按预期工作。在我看来,这是一个iOS错误,我已经提交了一个错误报告,但另一方面,我很难想象没有人偶然发现它。我怀疑它可能与重新设计的Core Motion API有关。从版本5开始,磁力计(罗盘)也被考虑用于传感器融合。控制台显示来自位置的偏差估计被提供给CoreMotion:
locationd[41] <Notice>: GYTT inserted: bias,-0.196419,1.749323,-1.828088,variance,0.002644,0.004651,0.002527,temperature,31.554688
我的问题:使用Device Motion时是否有机会阻止磁力计读数?我尝试停用位置服务,但它不会影响Core Motion。如果不可能,替代/解决方法是什么,基于加速度计的重力估算?
PS:由于我们正在处理基于四元数的模型,因此 与Gimbal Lock相关
修改
在做了一些更多的测量后,似乎很明显只有偏航受到影响。无论起始位置如何,俯仰和滚转都显示在偏差(<= 1°)内的偏差,同时偏航是漂移的。 CMDeviceMotion.gravity
似乎也很干净。
编辑(2): 我可以使用附加到最新XCode版本的MotionGraphs示例重现该问题。偏航图可以重复地远离原点。
答案 0 :(得分:4)
不是最终的解决方案,但至少是我自己的问题的解决方法(我将其作为未答复的邀请你)。事实证明,至少DeviceMotion.gravity
不会受到bug的影响。所以我决定重新设计这个非常简单的运动检测部分,并在倾斜设备时使用arcsin (gravity.x/||gravity||)
将主要玩家角色移到侧面。
这绝对是第二个最佳解决方案,因为它会破坏有关四元数中包含的完整旋转状态的信息。我决定以这种方式进行战略考虑:
CMAttitude.quaternion
,因为大多数人对四元数数学并不感兴趣;-)因此,任何与重力矢量相关的未来错误都可能会在由于用户数量较多,因此处于测试阶段。答案 1 :(得分:1)
我在自己的代码中做了类似的事情,发现了相同的z轴旋转漂移(偏航)。我已经应用了平衡滤波器。在每个运动管理器时间间隔,我获取当前的四元数(z分量),然后在计算之后将其保存为oldZ,以用于下一组计算。我的过滤器只是将NEW z值与紧接在它之前的z值进行平衡,防止它过快地移动太多。根据您的硬件和程序中的精确公差,您可以通过这种方式很好地管理漂移。你会看到陀螺稍微漂移,但随着过滤器继续动作,然后开始纠正。我的过滤器看起来像这样,并防止超过0.5度的“迷路”:
filtZ = 0.65 * oldZ + 0.35 * z;
0.65和0.35的数值是通过实验确定的,我会建议你在有时间的情况下玩这些。输出仍将按比例缩放0-1,然后可以像您一样使用(或者如果必须保留所有4个维度,则重新引入四元数)。