iPhone上的陀螺仪 [英] Gyroscope on iPhone

查看:926
本文介绍了iPhone上的陀螺仪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need some help using gyroscope on iPhone. I can't understand readings from CMAttitude regarding pitch, roll and yaw in a particular situation.

这是我的代码

- (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正在飞机上,如下图所示:

Let's suppose that iPhone is laying down on a plane as in the following figure:

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

pitch, roll and yaw are (almost) 0 degrees and any turn around an axis returns understandable readings. For example, turning the device right, the Yaw decreases and Pitch and Roll remains at 0.

现在iPhone处于以下位置:

Now the iPhone is in the following position:

并再次开始测量。

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

Readings are: Yaw = 0, Pitch = 90, Roll = 0

由于设备围绕此轴旋转,间距增加。

Since the devices rotated around this axis, Pitch increases.

将iPhone移动到此位置:

Moving the iPhone into this position:

读数为:偏航= 30,Pitch = 90,Roll = 0

readings are: Yaw = 30, Pitch = 90, Roll = 0

再次,由于设备围绕Yaw轴旋转,此值会更改,而其他值则不会。

Once again, since the device rotates around the Yaw axis, this value changes and the others not.

围绕Roll轴移动设备:

Moving the device around the Roll axis:

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

readings are: Yaw = 0, Pitch = 90, Roll = -20.

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

Now what I can't understand. Moving the iPhone around a circle of radius R (R > 0), like in this figure:

偏转变化同时Pitch and Roll不会。

Yaw changes meanwhile Pitch and Roll don't.

我原本预计Yaw会保持不变而Roll已经改变了。

I would have expected Yaw had remained unchanged and Roll had changed.

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

How can compensate this since I am interested exclusively to rotations around Yaw axis made by the user ?

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

Another problem I have is drifting. The iPhone is in the position described in the second figure, taken in my hand at rest for a long time (1 minute or more). The Yaw constantly increase. Any idea how to compensate the drifting ?

提前谢谢

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

UPDATE I have followed Kay suggestions but nothing changes. Some more detail on my code. I would like to use Yaw to rotated an UIImage only when user rotate the device around the Yaw axis. This works, but when the user rotates around its own vertical axis the Yaw changes. I suppose that is not correct since when the user moves around its vertical axis, the devices doesn't rotate around its own Yaw axis. May be I am wrong. This is my original code:

- (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建议后的代码:

This is the code after Kay suggestion:

- (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];
                                                           }];


推荐答案

[完全修订]

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

At a first glance I mistook the situation as running into some typical problems related to Euler Angles. Because they are close to this problem area and really important to bear in mind, I leave this part of the original answer. Euler Angle problems are:


  • 模糊,因为旋转状态和欧拉角表示之间的关系不是双射的,即一组角度描述一次旋转,但旋转可以由多组欧拉角表示。在您的问题图3中,您可以通过 1:Yaw = 30°,2:Pitch = 90° 1来实现相同的旋转:间距= 90°,2:Roll = 30°

  • 万向节锁定问题:您可能会失去一个自由度,并且设备无法再绕其中一个轴旋转。解决方案是使用四元数或旋转矩阵。

  • Ambiguity, as the relationship between rotation state and Euler Angles representation is not bijective i.e. a set of angles describes one rotation but a rotation can be represented by more than one set of Euler Angles. In your question's Fig. 3 you can achieve the same rotation by either 1: Yaw=30°, 2: Pitch=90° or by 1: Pitch=90°, 2: Roll=30°
  • Gimbal Lock problem: You may loose one degree of freedom and the device cannot rotate around one of the axes any longer. The solution is to use quaternions or rotation matrices.

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

But as you stated in your comment the true culprit seems to be the reference frame. Starting with iOS 5.0 Apple enhanced the sensor fusion algorithm and considers magnetic field data as well to calculate CMAttitude. Although there is still the old method startDeviceMotionUpdates, it now uses a default reference CMAttitudeReferenceFrameXArbitraryZVertical so that all measurement is related to "Z axis is vertical and the X axis points in an arbitrary direction in the horizontal plane".

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

In order to get your data in respect to the reference at start (or any other rotation) you need to store the CMAttitude instance you want as reference and then use CMAttitude's multiplyByInverseOfAttitude method to transform every new attitude i.e. at the beginning of your handleDeviceMotion method.

我认为这是与iOS 6中的一个错误有关,就像我在快速移动后的偏航角度因为它曾在以前的版本中正常工作。我提交了一个错误 - 让我们看看他们什么时候修复它。

I think this is related to a bug in iOS 6 like the one I described in Drifting yaw angle after moving fast as it used to work fine in previous version. I filed a bug - let's see when they gonna fix it.

UPDATE 2

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

As comments and chat showed the goal was to control a robot by just tilting the device. In this case knowing the full rotation state of the device is messing up control when changing the walking direction. Thus a pure accelerometer based approach using CMDeviceMotion.gravity is far more convenient.

这篇关于iPhone上的陀螺仪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆