CMMotionManager:设备校准在真实设备上不起作用
Posted
技术标签:
【中文标题】CMMotionManager:设备校准在真实设备上不起作用【英文标题】:CMMotionManager: Device Calibration does not work on a real device 【发布时间】:2014-04-26 22:10:48 【问题描述】:我对 CMMotionManager 有一个奇怪的行为。我尝试校准设备的位置,以使我的应用支持多种设备方向。
当我在真实设备上(不是在模拟器中)调试我的应用程序时,一切正常。 当我在没有调试的情况下运行同一个应用程序时,校准不起作用。
这是我的代码:
static CMMotionManager* _motionManager;
static CMAttitude* _referenceAttitude;
// Returns a vector with the current orientation values
// At the first call a reference orientation is saved to ensure the motion detection works for multiple device positions
+(GLKVector3)getMotionVectorWithLowPass
// Motion
CMAttitude *attitude = self.getMotionManager.deviceMotion.attitude;
if (_referenceAttitude==nil)
// Cache Start Orientation
_referenceAttitude = [_motionManager.deviceMotion.attitude copy];
else
// Use start orientation to calibrate
[attitude multiplyByInverseOfAttitude:_referenceAttitude];
NSLog(@"roll: %f", attitude.roll);
return [self lowPassWithVector: GLKVector3Make(attitude.pitch,attitude.roll,attitude.yaw)];
+(CMMotionManager*)getMotionManager
if (_motionManager==nil)
_motionManager=[[CMMotionManager alloc]init];
_motionManager.deviceMotionUpdateInterval=0.25;
[_motionManager startDeviceMotionUpdates];
return _motionManager;
【问题讨论】:
【参考方案1】:我找到了解决方案。该问题是由于调试和非调试模式之间的不同时序行为引起的。 CMMotionManager 在返回正确值之前需要一点时间进行初始化。解决方案是将校准推迟 0.25 秒。
此代码有效:
+(GLKVector3)getMotionVectorWithLowPass
// Motion
CMAttitude *attitude = self.getMotionManager.deviceMotion.attitude;
if (_referenceAttitude==nil)
// Cache Start Orientation
// NEW:
[self performSelector:@selector(calibrate) withObject:nil afterDelay:0.25];
else
// Use start orientation to calibrate
[attitude multiplyByInverseOfAttitude:_referenceAttitude];
NSLog(@"roll: %f", attitude.roll);
return [self lowPassWithVector: GLKVector3Make(attitude.pitch,attitude.roll,attitude.yaw)];
// NEW:
+(void)calibrate
_referenceAttitude = [self.getMotionManager.deviceMotion.attitude copy]
【讨论】:
以上是关于CMMotionManager:设备校准在真实设备上不起作用的主要内容,如果未能解决你的问题,请参考以下文章