2012-02-02 88 views
5

我已经试过这个项目在android和ios上都没有成功。这个东西很有可能会超出我的想象。不过,我想我会在这里发表我的问题作为最后的努力。
我想弄清楚什么时候设备旋转或翻转。我的应用程序应该知道它何时执行180,360或设备是否被垂直翻转。
为了试图理解它假设的工作方式,我尝试下载两个示例项目:AccelerometerGraph和CoreMotionTeapot。有了这些和其他的东西混合我已经想通了,我是想这样的:运动传感器,读取旋转

motionManager = [[CMMotionManager alloc] init]; 
motionManager.accelerometerUpdateInterval = 0.01; 
motionManager.deviceMotionUpdateInterval = 0.01; 
[motionManager startDeviceMotionUpdates]; 

if (motionManager.gyroAvailable) { 
    motionManager.gyroUpdateInterval = 1.0/60.0; 
     motionManager.deviceMotionUpdateInterval = 0.01; 
    [motionManager startGyroUpdatesToQueue:[NSOperationQueue currentQueue] 
           withHandler: ^(CMGyroData *gyroData, NSError *error) 
    { 
     CMRotationRate rotate = gyroData.rotationRate; 
     NSLog(@"rotation rate = [%f, %f, %f]", rotate.x, rotate.y, rotate.z); 
    }]; 
} else { 
    NSLog(@"No gyroscope on device."); 
} 

但我不知道如何来收集来自这三个值所要求的信息(水平和垂直旋转)(X,Y, Z)。

+0

您正在寻找什么样的旋转?例如,最简单的情况是手机在屏幕上向上放置屏幕,当您将屏幕放在屏幕上时,屏幕会旋转180度(围绕任何轴)。但是什么构成了90度旋转?它在一边吗?它直立吗?或者您是否正在寻找一种解决方案,让您以随机方向握住设备,并且想知道何时在任何方向旋转了180度,例如2秒?即一个非常普遍的解决方案,但非常有趣:) – Desmond 2012-02-02 15:18:43

+3

绝不是我试图从你的撬你的想法。 :)我很抱歉。但我现在明白你的问题。它可以完成,但是这是一个棘手的问题,并且值得怀疑的是,stackoverflow.com上的一个'简单'答案会做。你虽然对我很感兴趣,听起来很有趣! – Desmond 2012-02-02 15:30:15

+0

去尝试并将这些数字转换为度数并查看是否有帮助:http://stackoverflow.com/questions/4576493/how-can-i-use-sensormanager-getorientation-for-tilt-controls-like-my-纸计划 – 2012-02-02 16:48:10

回答

0

从苹果的文档:CMMotionManager类参考(对不起,大量的阅读,我已经加粗快速过阅读一些句子)

创建CMMotionManager的一个实例后,应用程序可以使用它来接收四种类型的运动:原始加速计数据,原始陀螺仪数据,原始磁力计数据和处理后的设备运动数据(包括加速度计,旋转速率和姿态测量)。由Core Motion的传感器融合算法提供的处理过的设备运动数据给出设备的姿态,旋转速率,校准磁场,重力方向以及用户赋予设备的加速度。

重要应用程序应该只创建一个CMMotionManager类的实例。该类的多个实例可能会影响从加速计和陀螺仪接收数据的速率。 应用程序可以在接收运动数据时采取两种方法之一,通过以指定的更新间隔处理它或定期采样运动数据。使用这两种方法时,应用程序应在完成处理加速度计,旋转速率,磁力计或设备运动数据时调用适当的停止方法(stopAccelerometerUpdates,stopGyroUpdates,stopMagnetometerUpdates和stopDeviceMotionUpdates)。

汉鼎运动更新以指定的间隔 要接收在特定时间间隔的运动数据,应用程序调用,它接受一个操作队列(NSOperationQueue的实例)和特定类型的用于处理那些块处理“开始”方法更新。运动数据被传递到块处理程序。更新的频率由“间隔”属性的值决定。

加速度计。设置accelerometerUpdateInterval属性以指定更新时间间隔。调用startAccelerometerUpdatesToQueue:withHandler:方法,传递一个类型为CMAccelerometerHandler的块。加速度计数据作为CMAccelerometerData对象传递到块中。 陀螺仪。设置gyroUpdateInterval属性以指定更新间隔。调用startGyroUpdatesToQueue:withHandler:方法,传递一个类型为CMGyroHandler的块。旋转速率数据作为CMGyroData对象传递到块中。 磁力计。设置magnetometerUpdateInterval属性以指定更新间隔。调用startMagnetometerUpdatesToQueue:withHandler:方法,传入CMMagnetometerHandler类型的块。磁场数据作为CMMagnetometerData对象传递到块中。设备运动。设置deviceMotionUpdateInterval属性以指定更新时间间隔。调用or startDeviceMotionUpdatesUsingReferenceFrame:toQueue:withHandler:或startDeviceMotionUpdatesToQueue:withHandler:方法,传递CMDeviceMotionHandler类型的块。使用前一种方法(iOS 5.0中的新增功能),您可以指定用于姿态估计的参考框架。旋转速率数据作为CMDeviceMotion对象传递到块中。 运动数据的周期性采样 要通过定期采样处理运动数据,应用程序会调用不带参数的“开始”方法,并定期访问由属性为给定类型的运动数据保存的运动数据。这种方法是游戏等应用的推荐方法。处理块中的加速度计数据会带来额外的开销,并且大多数游戏应用程序在渲染帧时只对最新的运动数据样本感兴趣。

加速度计。调用startAccelerometerUpdates以开始更新,并通过读取accelerometerData属性定期访问CMAccelerometerData对象。 陀螺仪。调用startGyroUpdates以开始更新并通过读取gyroData属性定期访问CMGyroData对象。 磁力计。调用startMagnetometerUpdates以开始更新并通过读取magnetometerData属性定期访问CMMagnetometerData对象。设备运动。调用startDeviceMotionUpdatesUsingReferenceFrame:或startDeviceMotionUpdates方法开始更新,并通过读取deviceMotion属性定期访问CMDeviceMotion对象。 startDeviceMotionUpdatesUsingReferenceFrame:方法(iOS 5.0中的新增功能)可让您指定用于姿态估计的参考框架。

关于收集数据:

@property(readonly) CMGyroData *gyroData 

讨论 如果没有陀螺仪数据可用,则此属性的值是零。调用startGyroUpdates之后正在接收陀螺仪数据的应用程序将定期检查此属性的值并处理陀螺仪数据。

所以,你应该有类似

gyroData.rotationRate.x 
gyroData.rotationRate.y 
gyroData.rotationRate.z 

通过存储它们,并将它们定期进行比较,你应该能够看到,如果设备绕轴翻转等

+0

你已阅读文件,你给的样本和我发布的一样。我的问题是一样的,如何从这些x y z值获取旋转信息。 – 2012-02-15 01:49:06

+0

在我引用的文档中,据说您必须存储x,y,z值,然后经常比较它们以查看它们是否更改。根据这种变化,你会看到是否有轮换。例如: – moxy 2012-02-15 06:21:46

+0

:启动应用程序时,您有x = 20,y = 3,z = 40。您将它们存储在referenceX,referenceY和referenceZ变量中,然后通过频繁更新来监视gyroData.rotationRate.x,y和z,您可能会发现小的变化,然后像x = 30,y = 170,z = 10,所以你推断iPhone已经在y轴上翻转(更好地放置一些误差,而不是纯粹的180度。x,y和z是三维坐标轴,它是通过查看它们如何更改(定期监视和更新它们) – moxy 2012-02-15 06:28:46

1

你正在尝试的不是微不足道的,但肯定是可能的。这段视频对于理解设备的功能以及如何更加接近您的目标应该非常有帮助: http://www.youtube.com/watch?v=C7JQ7Rpwn2k

虽然他在谈论Android,但同样的概念也适用于iPhone。

+0

绝对是该视频中的一些很好的信息,但离答案还很远。但我认为我的答案可能是这个引用总结了我的意思。“希望理解旋转运动的应用程序开发人员必须掌握欧拉角,旋转矩阵和四元数。在引擎盖下,必须按顺序使用传感器融合算法为运动创造敏感,准确和低噪音的描述。“ – 2012-02-15 01:48:23

+0

您必须了解设备的功能以及如何使用它们。 CoreMotion的某些方面已经使用传感器融合来提供高保真数据,这不是问题。如何使用设备提供的数据来描述三维运动,这就是你需要解决的问题。你试图实现的是相当于一个惯性测量单位,这对设备来说并不重要。你必须决定IMU/INS与你的目的有多么接近。在视频中他谈到了这一点。卡尔曼滤波可以提供帮助,但可能无法满足您的需求。 – quellish 2012-02-15 02:38:52

0

这一切都依赖于iPhone位置。比方说,如果手机在y轴周围360度翻转,指南针不会改变,因为在翻转过程中指南针仍然指向相同的方向。这不仅仅是它。我的提示是,您记录加速度计并将您收集的数据与所做的动作进行比较,然后确定技巧的各个阶段并为每个技巧制作一个阶段列表。

+0

雅它很粗糙的排序虽然所有这些更新频繁的值。加上我没有得到它,因为我的例子显示即时查询陀螺仪,但它似乎有应用我不明白的g力。这意味着快速或慢速地翻动手机具有不同的读数,如果它只是陀螺仪就不应该是这种情况 – 2012-02-15 01:51:14

0

然后,也许你正在寻找的只是设备的方向。你应该看看UIDevice Class Reference。尤其是

​​

方法。

,并使用它像这样:

[UIDevice currentDevice].orientation 

你会得到回报这些可能的值:

typedef enum { 
    UIDeviceOrientationUnknown, 
    UIDeviceOrientationPortrait, 
    UIDeviceOrientationPortraitUpsideDown, 
    UIDeviceOrientationLandscapeLeft, 
    UIDeviceOrientationLandscapeRight, 
    UIDeviceOrientationFaceUp, 
    UIDeviceOrientationFaceDown 
} UIDeviceOrientation; 

所以,你就可以检查它是否在纵向(向上或向下)或风景(左或右)以及是否已翻转。

您就可以实现以下方法:

- willRotateToInterfaceOrientation 
- didRotateToInterfaceOrientation 

你可以看看在this link检查你如何实现的方法。