iPhone上的陀螺仪

Fab*_*Fab 34 iphone accelerometer ipad ios gyroscope

在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);
}
Run Code Online (Sandbox Code Playgroud)

我们假设iPhone正在平面上,如下图所示:

在此输入图像描述

俯仰,滚转和偏航是(几乎)0度,绕轴的任何转弯都会返回可理解的读数.例如,向右转动设备,Yaw减小,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)的圆周,如下图所示:

在此输入图像描述

Yaw改变同时Pitch and Roll没有.

我原以为Yaw保持不变而Roll已经改变了.

如何补偿这一点,因为我对用户制作的偏航轴周围的旋转感兴趣?

我遇到的另一个问题是漂移.iPhone处于第二个图中描述的位置,长时间(1分钟或更长时间)在我的手中拍摄.偏航不断增加.知道如何补偿漂流吗?

先感谢您

更新 我跟随凯的建议,但没有任何改变.关于我的代码的更多细节.我想仅在用户围绕偏航轴旋转设备时使用Yaw旋转UIImage.这是有效的,但是当用户围绕其自己的垂直轴旋转时,偏转会发生变化.我认为这是不正确的,因为当用户围绕其垂直轴移动时,设备不会围绕其自己的偏航轴旋转.可能是我错了.这是我的原始代码:

- (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);
}
Run Code Online (Sandbox Code Playgroud)

这是凯建议之后的代码:

- (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);
}
Run Code Online (Sandbox Code Playgroud)

我启动设备运动监控

 [motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryZVertical toQueue:[NSOperationQueue currentQueue]
                                                           withHandler: ^(CMDeviceMotion *motion, NSError *error){

                                                               [self performSelectorOnMainThread:@selector(handleDeviceMotion:) withObject:motion waitUntilDone:YES];
                                                           }];
Run Code Online (Sandbox Code Playgroud)

Kay*_*Kay 6

[完全修订]

(1)奇怪的角度

乍一看,我把这种情况误认为是与Euler Angles有关的一些典型问题.因为他们离这个问题很近并且非常重要,所以我留下原始答案的这一部分.欧拉角问题是:

  • 模糊性,因为旋转状态和欧拉角表示之间的关系不是双射的,即一组角度描述一个旋转但旋转可以由多于一组欧拉角表示.在你的问题的图3,你可以通过实现相同的旋转1: Yaw=30°, 2: Pitch=90°1: Pitch=90°, 2: Roll=30°
  • 万向节锁定问题:您可能会失去一个自由度,并且设备不能再绕其中一个轴旋转.解决方案是使用四元数或旋转矩阵.

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

为了让您的数据就在开始引用(或任何其他旋转),你需要存储的CMAttitude要用作参考实例,然后使用CMAttitudemultiplyByInverseOfAttitude方法进行改造,即在你的每一个开始崭新的姿态handleDeviceMotion方法.

(2)偏航漂移

我认为这与iOS 6中的一个错误相关,就像我在快速移动中描述的漂移偏航角度一样,因为它在以前的版本中工作得很好.我提交了一个错误 - 让我们看看他们什么时候修复它.


更新2

正如评论和聊天所示,目标是通过倾斜设备来控制机器人.在这种情况下,知道设备的完全旋转状态是在改变行走方向时弄乱控制.因此,使用CMDeviceMotion.gravity的纯加速度计方法更加方便.