2012年5月15日火曜日

モーションイベントサンプル2 - UIAccelerometerを使った傾き検知

今回もまた、前回の「モーションイベントサンプル1 - シェイクと回転検知」に引き続き、iOS Developer Libraryの「iOSイベント処理ガイド」(英語版はEvent Handling Guide for iOS)に沿って、サンプルを公開します。
今回は、「UIAccelerometerを介した加速度センサーイベントへのアクセス」です。

UIAccelerometerDelegate【iOS 2.0以降】【Deprecated in iOS 5.0

前回は、デバイスの傾きを6方向で取得するだけでしたが、今回の「UIAccelerometer」を使うと任意の方向への傾きを計測することができます。文字通り加速度計です。しかし、残念ながら今回紹介するUIAccelerometerDelegateのメソッド「accelerometer:didAccelerate:」は「Deprecated in iOS 5.0」です。まだ使うことはできますが、次回説明予定の、iOS 4から導入された「Core Motion」を使うように推奨されています。(「モーションイベントサンプル3 - CoreMotionを使った各種センサーの利用」)

Core Motionの使い方は次に回して、今回はこのままUIAccelerometerによる加速度センサーの利用方法です。
  1. <project_name>-Info.plistファイルにキー「accelerometer」を追加する。(UIRequiredDeviceCapabilitiesについての詳細は「iOSデバイス間の互換性まとめ」をご覧下さい。)
  2. UIAccelerometerDelegateプロトコルを指定する
    @interface ViewController : UIViewController <UIAccelerometerDelegate>
    @end
    
  3. 加速度センサーからの情報を受け取る間隔を設定し、デリゲータに代入
    //Hz:取得する間隔
    const float accelerometerFrequency = 60.0;
    
    // シングルトンでインスタンスを取得
    UIAccelerometer* theAccelerometer = [UIAccelerometer sharedAccelerometer];
    
    // 間隔を秒に変換
    theAccelerometer.updateInterval = 1 / accelerometerFrequency;
    
    // デリゲータに代入することですぐに加速度センサーからの情報が取得できる
    theAccelerometer.delegate = self;
  4. メソッドを実装
    -(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
    {
        // 加速度センサーからの入力を受け取り処理する
        UIAccelerationValue x = acceleration.x;
        UIAccelerationValue y = acceleration.y;
        UIAccelerationValue z = acceleration.z;
    
        // x, y, zの値を利用する
    }
  5. (情報が不必要になったら)加速度センサーからの情報の受け取りを停止する
    [UIAccelerometer sharedAccelerometer].delegate = nil;
    

UIAccelerationValueはtypedefされているだけなのでdouble型です。
- UIAccelerometer.h
typedef double UIAccelerationValue;
そして、得られる数値は傾ける方向により「+」と「-」で表され、以下のような値になっています。静止している場合は「-1.0〜1.0」の範囲に収まります。

イメージXYZイメージXYZ
0.0-1.00.0
0.01.00.0
-1.00.00.0
1.00.00.0
画面が表(上)
0.00.0-1.0
画面が裏(下)
0.00.01.0

適切な更新間隔

上の例では、1秒間に60回の情報を取得するようにしていましたが、多いほど良いというわけではなく、電池のことも考えなければなりません。ドキュメント内では以下のように推奨されています。30fps,60fpsのゲームの場合はそれに合わせてそれぞれの30Hz,60Hzにすれば良いはずです。
イベント頻度(Hz)使用方法
10–20デバイスの現在の向きを表すベクトルを確認するのに適しています。
30-60ゲーム、またはリアルタイムユーザ入力用に加速度センサーを使用するその他のアプリケーションに適しています。
70-100高い頻度でモーションを検出する必要があるアプリケーションに適しています。たとえば、この間隔を使って、ユーザがデバイスをたたいたり高速でゆすったりすることを検出する場合が考えられます。

サンプル

ソースコードはGitHubで公開しています。
iOS-SampleCodes/UIAccelerometerSample - GitHub

何もフィルタをかけていない情報と、重力による影響のみを残したローパスフィルタと、その反対に重力による影響を取り除いたハイパスフィルタの動作を確認できます。

傾けるとUILabelが移動します。


注意点としては、移動可能な範囲を判定していないためどこままでも移動します。見失ってしまった場合はアプリを再起動することをおすすめします。


次回

最初にも書きましたが、UIAccelerometerDelegateの代わりに使用が推奨されている「Core Motion」を使い、「モーションイベントサンプル3 - CoreMoionを使った各種センサーの利用」を説明します。

0 コメント:

コメントを投稿