2013年2月28日 星期四

iOS-Accelerometer

之前一直蠻好奇如何使用iPhone上的加速度計和陀螺儀,看了一下資料,寫了一隻簡單的程式來練習

在剛開始練習使用加速度計的時候遇到個問題就是,以前加速度計的使用都是用UIAccelerometer
然後在實作UIAccelerometerDelegate中的
- (void) accelerometer:(UIAccelerometer *) meter 
         didAccelerate: (UIAcceleration *) accel 
但是此delegate在iOS5之後就被拋棄惹QQ(蠻多教學都用此方法的)
在網路上搜尋了一下,官方是建議使用CoreMotion.framework來使用
不過我目前對iOS的Design pattern還不算太熟(使用Apple設計的framework完全都是design pattern!)
目前只能大概瞭解使用的方法,對於背後的設計理念還是不太懂QQ
先來看看官網的敘述:
1. Core Motion is a system framework that obtains motion data from sensors on a device and presents that data to applications for processing.
可以瞭解到,Core Motion的framework主要是讀取sensor data然後送給應用程式去做適當的處理
例如:賽車遊戲,轉動手機去改變加速度計的資料傳給賽車遊戲,來控制遊戲裡車子的方向盤

2. Core Motion defines a manager class, CMMotionManager, and three classes whose instances encapsulate measurements of motion data of various types
從官網的文件得知Core Motion定義了一個manager class稱為CMMotionManager和三個sensor的class
a. CMAccelerometerData
b. CMGyroData
c. CMDeviceMotion
(其實這部分已經包含了Design pattern的概念!)


3. the CMMotionManager class offers two approaches for obtaining motion data, a push approach and a pull approach
上面的敘述提到要獲得sensor的data可以利用CMMotionManager提供的兩種approaches
a. push(用block的方式,網路上查到的方法也用此法)
b. pull
來得到,這次是要筆記加速度計,所以其他的core motion就沒有查得很清楚~囧
要獲得加速度計的資料主要分成兩個步驟:
a. 先create CMMotionManager的object
b. 再call startAccelerometerUpdatesToQueue:withHandler:
(在官方文件寫道可以call兩個function來處理sensor data,一個是b的method另一個是startAccelerometerUpdates)

看起來蠻簡單的,不過沒有code example實在還是有點不知道怎麼用

步驟a:(create CMMotionManager的object)
- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //先create CMMotionManager的物件
    motionManager = [[CMMotionManager alloc]init];
    UIImage *image = [UIImage imageNamed:@"images.jpeg"];
    self.batImage.image = image;
    
    //開始獲得Accelerometer的data
    [self startMyMotionDetect];
        
}
步驟b:(call startAccelerometerUpdatesToQueue:withHandler:)
- (void)startMyMotionDetect{
    
    //使用startAccelerometerUpdatesToQueue:withHandler:這個method
    [motionManager startAccelerometerUpdatesToQueue:[[NSOperationQueue alloc]init] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
        //裡用dispatch_async把block裡面的程式碼加入到main_queue用非同步的方式來處理
        //(表示有兩條thread)
        dispatch_async(dispatch_get_main_queue(), ^{
            float x = accelerometerData.acceleration.x;
            float y = accelerometerData.acceleration.y;
            float z = accelerometerData.acceleration.z;
            //用setTransform來讓圖片位移
            [self.batImage setTransform:CGAffineTransformMakeTranslation(-y*100, -x*100)];
            NSLog(@"%f %f %f",x,y,z);
        });
    }];
}
停止更新Accelerometer的data
- (void)viewDidDisappear:(BOOL)animated{
    [motionManager stopAccelerometerUpdates];
}
myCode
run 的結果:

左右搖晃可以控制蝙蝠標誌的移動XD

沒有留言:

張貼留言