成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

解析iOS4中Core Motion框架使用方法

移動開發 iOS
Core Motion框架包含有一個專門的Manager類,CMMotionManager,然后由這個manager去管理三種和運動相關的數據封裝類,而 且,這些類都是CMLogItem類的子類,具體來考看本文詳解。

iOS4Core Motion框架使用方法是本文要介紹的內容,主要是來學習IOS4框架的內容。在iOS4之前,加速度計由UIAccelerometer類來負責采集工作,而電子羅盤則由Core Location接管。

而iPhone4的推出,由于加速度計的升級(有消息說使用的是這款芯片) 和陀螺儀的引入,與motion相關的編程成為重頭戲,所以,蘋果在iOS4中增加一個一個專門負責該方面處理的框架,就是Core Motion Framework。這個Core Motion有什么好處呢?簡單來說,它不僅僅提供給你獲得實時的加速度值和旋轉速度值,更重要的是,蘋果在其中集成了很多算法,可以直接給你輸出把重力 加速度分量剝離的加速度,省去你的高通濾波操作,以及提供給你一個專門的設備的三維attitude信息,如圖:

解析iOS4中Core Motion框架使用方法

有這么一個好東西,我們自然就要好好利用了。下面就介紹一下,如何利用Core Motion Framework,來獲得對應的motion信息。

Core Motion在iOS4.0主要負責三種數據:加速度值,陀螺儀值,設備motion值。實際上,這個設備motion值就是通過加速度和旋轉速度進行 fusing變換算出來的,基本原理后面會介紹。Core Motion在系統中以單獨的后臺線程的方式去獲得原始數據,并同時執行一些motion算法來提取更多的信息,然后呈獻給應用層做進一步處理。Core Motion框架包含有一個專門的Manager類,CMMotionManager,然后由這個manager去管理三種和運動相關的數據封裝類,而 且,這些類都是CMLogItem類的子類,所以相關的motion數據都可以和發生的時間信息一起保存到對應文件中,有了時間戳,兩個相鄰數據之間的實 際更新時間就很容易得到了。這個東西是非常有用的,比如有些時候,你得到的是50Hz的采樣數據,但希望知道的是每一秒加速度的平均值。

從Core Motion中獲取數據主要是兩種方式,一種是Push,就是你提供一個線程管理器NSOperationQueue,再提供一個Block(有點像C中 的回調函數),這樣,Core Motion自動在每一個采樣數據到來的時候回調這個Block,進行處理。在這中情況下,block中的操作會在你自己的主線程內執行。另一種方式叫做 Pull,在這個方式里,你必須主動去像Core Motion Manager要數據,這個數據就是最近一次的采樣數據。你不去要,Core Motion Manager就不會給你。當然,在這種情況下,Core Motion所有的操作都在自己的后臺線程中進行,不會有任何干擾你當前線程的行為。

那接下來的問題就是,我在什么時候選擇什么方式呢?蘋果官方推薦了一個使用指南,比較了兩種方式的優劣,并做出了使用場景的推薦。如下圖所示。應該說,兩種方式各自的優缺點還是很鮮明的,使用場景也大不一樣,很好區分,如圖:

解析iOS4中Core Motion框架使用方法

Core Motion的大體介紹就是這些。下面說說Core Motion具體負責的采集,計算和處理。Core Motion的使用就是一三部曲:初始化,獲取數據,處理后事。

在初始化階段,不管你要獲取的是什么數據,首先需要做的就是

  1. motionManager = [[CMMotionManager alloc] init]; 

所有的操作都會由這個manager接管。后面的初始化操作相當直觀,以加速度的pull方式為例

  1. if (!motionManager.accelerometerAvailable) {  
  2. // fail code // 檢查傳感器到底在設備上是否可用  
  3. }  
  4. motionManager.accelerometerUpdateInterval = 0.01; // 告訴manager,更新頻率是100Hz  
  5. [motionManager startAccelerometerUpdates]; // 開始更新,后臺線程開始運行。這是pull方式。 

如果是push方式,更新的代碼可以寫成這樣

  1. [motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMAccelerometerData *latestAcc, NSError *error)  
  2. {  
  3. // Your code here  
  4. }]; 

接下來就是獲取數據了。Again,很簡單的代碼

  1. CMAccelerometerData *newestAccel = motionManager.accelerometerData;  
  2. filteredAcceleration[0] = newestAccel.acceleration.x;  
  3. filteredAcceleration[1] = newestAccel.acceleration.y;  
  4. filteredAcceleration[2] = newestAccel.acceleration.z; 

通過定義的CMAccelerometerData變量,獲取CMAcceleration信息。和以前的UIAccelerometer類的使用方式一樣,CMAcceleration在Core Motion中是以結構體形式定義的

  1. typedef struct {  
  2. double x;  
  3. double y;  
  4. double z;  

對應的motion信息,比如加速度或者旋轉速度,就可以直接從這三個成員變量中得到。

最后是處理后事,就是在你不需要Core Motion進行處理的時候,釋放資源

  1. [motionManager stopAccelerometerUpdates];  
  2. //[motionManager stopGyroUpdates];  
  3. //[motionManager stopDeviceMotionUpdates];  
  4. [motionManager release]; 

你看,就是這么簡單。當然,如果這么Core Motion這么簡單,就太無趣了。實際上,Core Motion最好玩的地方,既不是加速度,也不是角速度,而是經過sensor fusing算法處理的Device Motion信息的提供。Core Motion里面提供了一個叫做CMDeviceMotion的類,用來把下圖所示的這些數據封裝成Device Motion信息,如圖:

解析iOS4中Core Motion框架使用方法

我們來看看這些被封裝數據的介紹。

第一個attitude,就是剛才說到的三維attitude,通俗來講,就是告訴你手機在當前空間的位置和姿勢。

第二個是重力信息,其本質是重力加速度矢量在當前設備的參考坐標系中的表達,開發不再需要通過濾波來提取這個信息了,因為Core Motion已經給你了。

第三個是加速度信息。同樣,濾波在這里不再需要(根據程序需求而加的濾波算法自然是可以保留的)。

第四個是即時的旋轉速率,也就是rotation rate,是陀螺儀的輸出。

下面就來詳細介紹一下這四種數據。

1. Attitude。在CMDeviceMotion對象中,attitude是以

  1. @property (readonly, nonatomic) CMAttitude *attitude; 

屬性定義的。一個CMAttitude的實例,封裝了關于當前設備在空間中的姿態信息。這個信息是由下面集中數學表達式定義的:

一個四元數。

一個變換rotation矩陣

三個歐拉角 (roll, pitch, 和yaw)。關于歐拉角,again,請參考我上一篇文章。

四元數是一種Attitude Determination System經常使用的數據保存形式,我不是很清楚。而歐拉角和變換矩陣則是相輔相成的,兩者之間可以相互推導。所以這里主要介紹一下對虛擬現實或者游戲都大有幫助的變換矩陣。

這個rotation變換矩陣究竟有什么用呢?我們來看看下面這張圖:

解析iOS4中Core Motion框架使用方法

本質上講,變換矩陣給我們闡述了從一個向量空間到另一個向量空間的映射關系。舉個例子,在很多應用中都需要對加速度信息進行判斷,但是,用戶在使用 手機的過程中,姿勢是不斷變換的,我們可以采集到某個設備在t1時間點的加速度以及重力信息,也可以采集到t2時間點的信息,我們卻不能直接拿他們做運 算。為什么?因為由于手機各個軸方向的變化,加速度和重力信息在t1時間點屬于一個向量空間,在t2時間點,就屬于另一個向量空間了,如果你硬拿 acc.x1和acc.x2求設備的運動模式,自然不可能準的。

所以,現在的問題是,我們要找到兩個三維空間的線性變換T,讓這個變換關系幫我們把某個空間的值變換到另一個空間去,這樣就可以在同一個空間做比較 或者任何計算了。Core Motion如何解決這個問題呢?它首先讓你可以在程序開始的初始時間點t1(比如你畫第一禎的時候)采集一個attitude的值作為參照坐標系,我們 假定這個向量是v_ref。在任何時間點,比如t2,采集一個attitude的值,假定這個向量是v_dev,位于當前設備的坐標系,那么我們有以下關 系,如圖:

解析iOS4中Core Motion框架使用方法

其中R就是rotation matrix。由于v_ref是正交基向量,所以,如圖:

解析iOS4中Core Motion框架使用方法

剛才說到了,v_ref和v_dev都是其對應向量空間的正交基,而這個R矩陣正好是正交矩陣,所有的列向量線性獨立。所以,R所對應的變換,正是我們要找的這兩個空間的線性變換,而且這是一對一變換。

好,上面這個結論告訴我們什么呢?你在當前時刻t2采集的當前坐標系下的加速度信息,不僅在t1時刻的參照坐標系下有對應的向量,而且僅有一個對應 向量!如果我們定義a_dev是當前的加速度向量,那么它在參照坐標系里面對應的加速度向量只有一個,而且肯定可以由下面式子求出,如圖:

解析iOS4中Core Motion框架使用方法

這個式子不存在無解的情況,因為正交矩陣永遠都是有逆矩陣的。經此變換,你就可以隨意比較和計算不同時間點的加速度和重力信息,從而得出精確的用戶運動模式了。

比較有趣的一點是,R變換矩陣的表達形式,正好表明了R和rotation rate的關系: 當前時間點的坐標系和參照坐標系的變換矩陣,是由陀螺儀提供的yaw, pitch和roll三個軸上角度信息推斷的。于是,再一次,我們感受到了新加的陀螺儀強大的地方。更強大的地方在于,Core Motion直接就把R矩陣提供給開發者了,省去了開發者很多易錯而繁瑣的工作。

說了這么多鋪墊,還是簡單介紹一下獲得當前時間點的R矩陣信息的步驟吧:

首先,獲得參考矩陣信息

  1. if (motionManager != nil) {  
  2. CMDeviceMotion *deviceMotion = motionManager.deviceMotion;  
  3. referenceAttitude = [deviceMotion.attitude retain];  

然后在希望得到R矩陣的時候,執行下列操作:

  1. CMRotationMatrix rotation;  
  2. CMDeviceMotion *deviceMotion = motionManager.deviceMotion;  
  3. CMAttitude *attitude = deviceMotion.attitude;  
  4. if (referenceAttitude != nil) {  
  5. [attitude multiplyByInverseOfAttitude:referenceAttitude];  
  6. }  
  7. rotation = attitude.rotationMatrix; 

很簡單,也很直觀,一個multiplyByInverseOfAttitude的調用,正好反應了我們剛才推導的矩陣運算關系。至此,rotationMatrix被我們拿到,接下來的事情就只有想不到,沒有做不到了。

2、Gravity和UserAcceleration。之所以把他們放在一起講,是因為他們本質上比較類似,而且原始的加速度(就是通過 [motionManager startAccelerometerUpdates]獲得的那個值)本來就是他們的疊加和,換句話說,將原始加速度分解就得到了他們倆,只不過現在蘋果 幫你把這個濾波分解給做了。他倆在Core Motion中的屬性定義是

  1. @property (readonly, nonatomic) CMAcceleration gravity;  
  2. @property (readonly, nonatomic) CMAcceleration UserAcceleration; 

都是CMAcceleration所包裝的結構體。而且,兩者的參考坐標系都是一樣的,以設備的外框架為準,如圖:

解析iOS4中Core Motion框架使用方法

得到這兩種數據的方式比較簡單,就是直接通過讀取motionManager.deviceMotion.userAcceleration/gravity的三個成員變量即可。

3、Rotation rate。旋轉速率是通過叫CMRotationRate的結構體封裝的,其內部變量定義和CMAcceleration一模一樣。正負的確定,由右手法 則判斷。看到這里,不少朋友可能會有問題:這個數據,和之前介紹的直接通過motionManager獲得的CMGyroData有什么區別呢?通過 Device Motion封裝處理后的Rotation rate,去掉了原始的CMGyroData所有的bias。舉個例子,如果我們把設備放在桌上靜止不動,理想情況下,陀螺儀的輸出應該是0。問題在于, 你直接從陀螺儀獲得的原始數據并不是0,而是由很多不確定因素導致的非0值,這其中就包括了很多的漂移誤差等等,比如陀螺儀溫漂,就會影響到我們的讀數。 Core Motion經過一些算法的處理,幫開發者消除了這種bias,極大方便了motion相關的開發工作。

說到Rotation rate,要講一下這個輸出數值的特點。如果你寫一個簡單的測試程序,把三個軸的數值都輸出到屏幕上來看,會發現一個很有意思的現象:pitch和 roll的值,和你讀數時候的手機的attitude完全對應,而yaw的值,則是從0開始顯示,手機的attitude在之后變了的話,yaw的值才有 對應的變化。這是因為,對于pitch和roll來講,他們都有明確的參照面,就是水平面,而且這個值肯定是在出廠之前就校正過。但yaw呢?沒有,用戶 在剛打開app的時候,可能會朝向任何不同的方向。所以此時,Core Motion干脆就給你輸出相對的初始值0,之后你再根據yaw方向上的相對變化來判斷設備的位置變化。

另外一點要補充的是,對于設備的旋轉,如果三個軸上都有變化,那么默認角度計算的順序是先roll,再pitch,最后yaw。

小結:iOS4Core Motion框架使用方法,講到現在,基本的Core Motion知識就都總結完了。在智能手機出現之前,我們都說,手機就是用來打電話的。智能手機改變了這一切。用戶總是有各種各樣的需求等待開發者滿足, 而關鍵就在于,開發者能不能理解用戶,認識用戶,做好個人化。Gyroscope的集成和Core Motion的推出,讓很多以前在智能手機上無法實現或者難以實現的應用成為了可能。這是機遇,想象力的機遇,也是挑戰,執行能力的挑戰。最后希望本文能對你有所幫助。

責任編輯:zhaolei 來源: starming社區
相關推薦

2023-11-16 08:34:23

.NETORM框架

2010-10-08 14:27:25

JavascriptSplit

2011-06-14 10:18:58

QThread Qt 線程

2011-08-01 10:48:06

iOS4 SDK XCode

2024-11-12 07:28:39

2011-08-18 11:10:49

Core Plot框架IOS開發

2013-06-08 17:09:35

Android開發移動開發XML解析

2024-01-02 09:21:18

SqlSugar數據庫ORM框架

2018-06-20 10:34:56

堆棧iOSswift

2012-01-18 14:14:29

iOS教程iOS5

2011-08-11 17:00:33

iPhone數據庫SQLite

2011-08-29 15:58:51

Lua函數

2011-06-01 15:54:41

log4net

2011-06-01 16:08:29

log4Net

2010-08-09 10:16:01

FlexBuilder

2011-06-30 16:53:18

QT Creator TableWidge

2024-01-04 08:43:50

Autofac容器.NET

2013-07-25 14:12:53

iOS開發學習UITableView

2011-08-23 09:44:28

LUA腳本

2009-11-25 10:02:27

PHP會話Sessio
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产一级一片免费播放 | 中文亚洲视频 | 欧美成人一区二区 | 亚洲免费av一区 | 亚洲精品自在在线观看 | www..com18午夜观看| 国产精品18久久久久久白浆动漫 | 欧美日一区二区 | 欧美性久久 | 国产在线1| 午夜视频免费在线 | 中国一级特黄真人毛片免费观看 | 日批免费在线观看 | 久久久噜噜噜www成人网 | 婷婷丁香在线视频 | 牛牛热在线视频 | 亚洲一区二区 | 91麻豆精品一区二区三区 | 一级在线免费观看 | 日韩福利片| 日韩欧美网 | 免费视频二区 | 国产高清在线精品一区二区三区 | 色综合视频 | 国产精品99久久久久久久久久久久 | 最新日韩在线视频 | 九九热在线免费视频 | 精品国产乱码久久久久久蜜柚 | 综合九九 | 久久国产视频网 | 国产大毛片| 国内精品视频免费观看 | 免费一区二区在线观看 | 中国一级特黄视频 | 成人一区二区电影 | 狠狠久久久 | 99国产精品99久久久久久粉嫩 | 欧美高清性xxxxhdvideosex | 噜久寡妇噜噜久久寡妇 | 日韩欧美精品在线播放 | 久久免费视频在线 |