2014-04-26 70 views
0

我对CMMotionManager有一种奇怪的行为。我尝试校准我的设备的位置,以使我的应用程序支持多种设备方向。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; 
} 

回答

0

我已经找到了解决办法。该问题是由于调试和非调试模式之间的不同时序行为造成的。 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] 
} 
相关问题