iphone - iPhone 上的陀螺仪

标签 iphone ios ipad accelerometer 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);
}

假设 iPhone 平放在平面上,如下图所示:

enter image description here

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

现在 iPhone 处于以下位置:

enter image description here

然后重新开始测量。

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

由于设备绕着这个轴旋转,Pitch 增加。

将 iPhone 移动到这个位置:

enter image description here

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

再一次,由于设备围绕 Yaw 轴旋转,因此该值发生变化而其他值不变。

围绕 Roll 轴移动设备:

enter image description here

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

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

enter image description here

偏航改变,同时俯仰和滚转不改变。

我原以为 Yaw 保持不变而 Roll 发生了变化。

既然我只对用户绕 Yaw 轴的旋转感兴趣,该如何补偿呢?

我遇到的另一个问题是漂移。 iPhone在第二张图所描述的位置,手拿在手上静置了很长时间(1分钟以上)。偏航不断增加。知道如何补偿漂移吗?

提前致谢

更新 我遵循了凯的建议,但没有任何改变。关于我的代码的更多细节。我只想在用户绕 Yaw 轴旋转设备时使用 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);
}

这是 Kay 建议后的代码:

- (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) 奇怪的角度

乍一看,我误以为遇到了与 Euler Angles 相关的一些典型问题。 .因为它们接近这个问题区域并且非常重要,所以我保留了原始答案的这一部分。欧拉角问题有:

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

但正如您在评论中所述,真正的罪魁祸首似乎是引用框架。从 iOS 5.0 开始,Apple 增强了传感器融合算法并考虑了磁场数据来计算 CMAttitude。虽然还是老办法startDeviceMotionUpdates , 它现在使用默认引用 CMAttitudeReferenceFrameXArbitraryZVertical这样所有的测量都与“Z 轴是垂直的,X 轴指向水平面中的任意方向”有关。

为了在开始(或任何其他旋转)时获取与引用相关的数据,您需要存储您想要作为引用的 CMAttitude 实例,然后使用 CMAttitudemultiplyByInverseOfAttitude转换每个新态度的方法,即在 handleDeviceMotion 方法的开头。

(2) 偏航漂移

我认为这与 iOS 6 中的一个错误有关,就像我在 Drifting yaw angle after moving fast 中描述的那样。因为它在以前的版本中工作得很好。我提交了一个错误 - 让我们看看他们什么时候会修复它。


更新 2

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

关于iphone - iPhone 上的陀螺仪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14528156/

相关文章:

iphone - 目标 iPhone 模拟器宏不工作

ios - 子类化 AFHTTPSessionManager 并使其成为 swift 中的单例

iphone - 如何使导航栏随我的网页一起滚动?

iphone - 如何在 Xcode 模板中包含静态库依赖项?

iphone - 是否可以在iOS 6中自定义FaceBook PostView?

iphone - 在 iOS 上应用带通滤波器

iphone - ld : library not found for -liPhone-lib

ios - 添加一个事件指示器以显示应用程序何时在 jquery mobile、phonegap/cordova 中忙碌

objective-c - iphone uipickerview : image and text

iphone - UIPopoverController:为什么我的弹出窗口没有出现在我想要的地方?