在iPhone上的陀螺仪

我需要使用iPhone上的陀螺仪一些帮助。 在特定的情况下,我无法理解CMAttitude关于俯仰,滚转和偏航的读数。

这是我的代码

- (void)handleDeviceMotion:(CMDeviceMotion*)motion { NSLog(@"Yaw %f ",attitude.yaw * 180 / M_PI); NSLog(@"Pitch %f ",attitude.pitch * 180 / M_PI); NSLog(@"Roll %f ",attitude.roll * 180 / M_PI); } 

假设iPhone正坐在飞机上,如下图所示:

在这里输入图像说明

俯仰,滚转和偏航(几乎)0度,任何绕轴旋转都会返回可理解的读数。 例如,向右转动设备,偏航减小并且Pitch and Roll保持在0。

现在iPhone处于以下位置:

在这里输入图像说明

并重新开始测量。

读数是:Yaw = 0,Pitch = 90,Roll = 0

由于设备围绕此轴旋转,音高增加。

把iPhone移到这个位置:

在这里输入图像说明

读数是:Yaw = 30,Pitch = 90,Roll = 0

再一次,由于设备围绕横摆轴旋转,所以这个值改变而其他值不改变。

围绕Roll轴移动设备:

在这里输入图像说明

读数是:Yaw = 0,Pitch = 90,Roll = -20。

现在我无法理解。 将iPhone围绕半径为R的圆(R> 0)移动,如下图所示:

在这里输入图像说明

偏航变化同时Pitch和Roll不。

我本来预计偏航保持不变,Roll已经改变了。

如何补偿这一点,因为我只是感兴趣的旋转用户所做的偏航轴?

另一个问题是漂stream。 iPhone处于第二张图所描述的位置,长时间停留在我的手中(1分钟或更长时间)。 偏航不断增加。 任何想法如何弥补漂stream?

先谢谢你

更新我遵循凯的build议,但没有改变。 一些关于我的代码的更多细节。 我只想用Yaw旋转一个UIImage,只是当用户围绕Yaw轴旋转设备时。 这是有效的,但是当用户围绕自己的垂直轴旋转时,偏航改变。 我想这是不正确的,因为当用户绕其垂直轴移动时,设备不会围绕自己的偏航轴旋转。 可能是我错了。 这是我的原始代码:

 - (void)handleDeviceMotion:(CMDeviceMotion*)motion { CMAttitude *attitude = motion.attitude; NSLog(@"Yaw %f ",attitude.yaw * 180 / M_PI); NSLog(@"Pitch %f ",attitude.pitch * 180 / M_PI); NSLog(@"Roll %f ",attitude.roll * 180 / M_PI); image.transform = CGAffineTransformMakeRotation(-attitude.yaw); } 

这是凯build议之后的代码:

 - (void)handleDeviceMotion:(CMDeviceMotion*)motion { CMAttitude *attitude = motion.attitude; if (startAttitude == 0) { startAttitude = attitude; } [attitude multiplyByInverseOfAttitude:startAttitude]; NSLog(@"Yaw %f ",attitude.yaw * 180 / M_PI); NSLog(@"Pitch %f ",attitude.pitch * 180 / M_PI); NSLog(@"Roll %f ",attitude.roll * 180 / M_PI); image.transform = CGAffineTransformMakeRotation(-attitude.yaw); } 

我开始设备运动监控

  [motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryZVertical toQueue:[NSOperationQueue currentQueue] withHandler: ^(CMDeviceMotion *motion, NSError *error){ [self performSelectorOnMainThread:@selector(handleDeviceMotion:) withObject:motion waitUntilDone:YES]; }]; 

[完全修改]

(1)奇怪的angular度

乍看之下,我把这种情况误认为与欧拉angular有关的典型问题。 因为他们接近这个问题领域,而且要记住这一点非常重要,所以我留下了原来答案的这一部分。 欧拉angular问题是:

  • 由于旋转状态和欧拉angular表示之间的关系不是双射的,即一组angular度描述一次旋转,但是一次旋转可以由一组以上的欧拉angular表示。 在你的问题的图3中,你可以通过1: Yaw=30°, 2: Pitch=90°或者1: Pitch=90°, 2: Roll=30°
  • 万向节locking问题:您可能会松动一个自由度,并且设备无法再围绕其中一个轴旋转。 解决scheme是使用四元数或旋转matrix。

但正如你在你的评论中所说,真正的罪魁祸首似乎是参照系。 从iOS 5.0开始,Apple增强了传感器融合algorithm,并考虑了磁场数据以计算CMAttitude。 尽pipe仍有旧方法startDeviceMotionUpdates ,但它现在使用默认参考CMAttitudeReferenceFrameXArbitraryZVertical,以便所有测量都与“ Z轴是垂直的,X轴指向水平面中的任意方向 ”有关。

为了在开始(或任何其他旋转)中获取有关参考的数据,您需要存储您想要的CMAttitude实例作为参考,然后使用CMAttitude的multiplyByInverseOfAttitude方法来转换每个新的态度,即在handleDeviceMotion方法。

(2)偏航漂stream

我认为这与iOS 6中的一个错误有关,就像在漂移后的偏航angular度中描述的一样,因为它在以前的版本中工作得很好。 我提出了一个错误 – 让我们看看他们什么时候修复它。


更新2

评论和聊天显示,目标是通过倾斜设备来控制机器人。 在这种情况下,当改变行走方向时,知道设备的完全旋转状态会搞乱控制。 因此,使用CMDeviceMotion.gravity的纯粹基于加速度计的方法要方便得多。