2013-09-01 47 views
0

我正在從Apple的Event Handling Guide for iOS工作。我使用startAccelerometerUpdates附近描述的拉方法。由於我只需要從傳感器讀取一次,拉法對我來說是很好的。CCMotionManager,accelerometerData,gyroData,magnetometerData return nil

在iPhone 4,iPad Mini和iPad Retina中,我在以下代碼中撥打accelerometerDatagyroDatamagnetometerData的電話爲零。 isAccelerometerAvailable, isGyroAvailable , and isMagnetometerAvailable each return YES`。兩個問題:

如何確定startAccelerometerUpdatesstartGyroUpdates的結果?他們是void職能,所以我可以假設它永遠不會失敗? (否則,它會拋出或返回一個BOOL)。

如何獲得電話的最後一個錯誤accelerometerData,gyroDatamagnetometerData

編輯:我不得不打電話[NSThread sleepForTimeInterval:0.150f]從傳感器中獲取數據。少一點,傳感器不會產生有效數據。

睡眠增加了第三個問題:需要多長時間才能確保數據在硬件出現時到達?

在此先感謝。

static CryptoPP::RandomPool pool; 
static dispatch_once_t once = 0; 

dispatch_once(&once, ^{ 
    CryptoPP::SecByteBlock seed(32); 
    CryptoPP::OS_GenerateRandomBlock(true, seed.data(), seed.size()); 
    pool.IncorporateEntropy(seed.data(), seed.size()); 
}); 

// First, send in all the uninitialized data. Then: 
// sesnors[0,1,2] use accelerometer, if available 
// sesnors[3,4,5] use gyroscope, if available 
// sesnors[6,7,8] use magnetometer, if available 
CryptoPP::SecBlock<double> sensors(3 * 3); 
pool.IncorporateEntropy(sensors.BytePtr(), sensors.SizeInBytes()); 

CMMotionManager* mgr = [[CMMotionManager alloc] init]; 
if(mgr) { 

    [mgr startAccelerometerUpdates]; 
    [mgr startGyroUpdates]; 
    [mgr startMagnetometerUpdates]; 

    [NSThread sleepForTimeInterval:0.150f]; 

    if([mgr isAccelerometerAvailable]) { 
     CMAccelerometerData* accelData = [mgr accelerometerData]; 
     if(accelData) { 
      sensors[0] = [accelData acceleration].x; 
      sensors[1] = [accelData acceleration].y; 
      sensors[2] = [accelData acceleration].z; 
     } 
    } 

    if([mgr isGyroAvailable]) { 
     CMGyroData* gyroData = [mgr gyroData]; 
     if(gyroData) { 
      sensors[3] = [gyroData rotationRate].x; 
      sensors[4] = [gyroData rotationRate].y; 
      sensors[5] = [gyroData rotationRate].z; 
     } 
    } 

    if([mgr isMagnetometerAvailable]) { 
     CMMagnetometerData* magnetData = [mgr magnetometerData]; 
     if(magnetData) { 
      sensors[6] = [magnetData magneticField].x; 
      sensors[7] = [magnetData magneticField].y; 
      sensors[8] = [magnetData magneticField].z; 
     } 
    } 

    pool.IncorporateEntropy(sensors.BytePtr(), sensors.SizeInBytes()); 

    [mgr stopMagnetometerUpdates]; 
    [mgr stopGyroUpdates]; 
    [mgr stopAccelerometerUpdates]; 
    [mgr release], mgr = nil; 
} 

回答

1

當你這樣做:

mgr startAccelerometerUpdates]; 
[mgr setAccelerometerUpdateInterval:0.01f]; 

這意味着你將無法開始接收信息,直到0.01秒後,即使這樣,如果主線程空閒你只接收更新。

在檢查數據之前,您並不是等待0.01秒,而是等待約0.00000000001秒。我不確定,但我認爲即使您等待更長時間,您的主線程也可能需要閒置。

我想你應該回到the documentation並看看你應該如何從傳感器中讀取信息。

我建議使用塊來處理運動數據:

[mManager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) { 
    // process data 
}]; 

你可以告訴加速度計接收的第一個值後立即停止,如果你只是想一次。

+0

非常感謝Abhi。我嘗試了'setAccelerometerUpdateInterval'和朋友。一個人如何立即開始接收信息(沒有這些設置,我無法從傳感器中獲取任何信息)。如何獲取錯誤信息? – jww

+0

再次感謝阿比。我不相信這是正確的:「你實際上等待了大約0.00000000001秒」。根據文檔,「間隔單位以秒爲單位」。 – jww

+0

再次感謝阿比。你有沒有這方面的參考資料:「如果主線程空閒,你只會收到更新」?我工作的文檔沒有提及閒置要求。 (我的參考文獻在第一段中)。 – jww

相關問題