2012-02-02 91 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檢查你如何實現的方法。