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

查看:34
本文介绍了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

由于设备围绕此轴旋转,因此 Pitch 增加.

Since the devices rotated around this axis, Pitch increases.

将 iPhone 移动到这个位置:

Moving the iPhone into this position:

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

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

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

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

围绕滚动轴移动设备:

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

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

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

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

偏航改变,而俯仰和滚转不改变.

Yaw changes meanwhile Pitch and Roll don't.

我原以为偏航保持不变,而滚动发生了变化.

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

因为我只对用户围绕偏航轴的旋转感兴趣,所以如何补偿?

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 ?

提前致谢

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

这是凯建议后的代码:

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

推荐答案

[已完全修改]

乍一看,我误以为遇到了一些与欧拉角.因为它们接近这个问题区域并且牢记这一点非常重要,所以我保留了原始答案的这一部分.欧拉角问题是:

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:

  • 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 实例,然后使用 CMAttitudemultiplyByInverseOfAttitude 方法来转换每一个新的姿态,即在你的 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.

更新 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天全站免登陆