[Android] 加速度センサー:Accelerometer

Android7

スマホに搭載されている加速度センサーを使うと、スマホを傾けると球が転がるようなアプリを作ることができます。これはMEMSと呼ばれる半導体を使っているのですね

Sensors coordinate-system diagram.

Sensors Coordinate system

Android Studio 2.2.3
Android 7.1.1

 


Accelerometer

 
加速度センサーは端末のx,y,z軸方向の加速度を計測します。単位[m/s²]

実際(?)にその動きをAndroid Studioのemulatorから加速度センサーの動きを見てみたいと思います。
emulatorを立ち上げて右バーのmore「…」をクリックするとExtended controlsダイアログが表れます。
 

 
「Virtual sensors」を選択、右サイドに端末が現れ、その上にある「Accelerometer」をセットして、画面のスマホをマウスでドラッグすると「Rotation」によって「Resulting values」にx,y,z方向のセンサー出力が表示されます。
 
加速度なので動かす速度の変化で値が変わるのが分かります。
こちらはGoogleのSensorで説明されているTest with the Android Emulatorの動画です。
 


 
codingに移ります。実装方法を簡単に説明すると

  • SensorEventListener の設定
  • SensorManager のインスタンス生成
  • registerListener の登録
  • onSensorChanged でセンサー値の受け取り

となります。以下のコードはAndroid Studioから取り出せるSampleの中の「Accelemrometer Play」から切り出して簡単にしたものです。

センサー情報を取得する部分はセンサーのデバイス名やメーカー名などでアプリを作る時にはあまり関係ないので省いてもいいでしょう。
 
MainActivity.java

 

activity_main.xml

 
Nexus 5X での結果です。

 

スマホをディスクの上に置くと、Z値が10近い値となりますがこれは重力のGのせいです。
 
この加速度データはMEMSからの生データなのでノイズに反応しすぎて使いづらいかもしれません。使う用途によってフィルターを入れるのがいいでしょう。
また、getReportingMode()はそれによって返ってくるタイミングが変わるので実装上は気を付ける必要があると思います。
 

samplingPeriodUs

 
センサーのサンプリング期間はスペックでは
 

 
とあるのでこの samplingPeriodUs にusecオーダーで値を設定すればいいのかと思ったのですがそうではないようでした。Nuxus 5Xでのテストでは

input 10 100 1,000 5,000 8,000 10,000 15,000 20,000 50,000 100,000
period[ms] 2.5 2.5 2.5 5.0 5.0 10.0 10.0 20.0 20.0 20.0

となりましたこれは階段状に変化するもので設定値に対して比例しているのではないですね
 
結局これらを使えということでしょうか

SENSOR_DELAY_FASTEST 最速通知頻度(デバイスのスペック次第)
SENSOR_DELAY_NORMAL 通常のサンプリング
SENSOR_DELAY_GAME ゲームに適した間隔
SENSOR_DELAY_UI ゲームではないアプリ向け

Nexus 5Xで使っているAccelerometerはBosche BMI10でしたので
あくまでこの端末でこのデバイスでのケースです。
因みにこのdatasheet二よれば最小遅れは2.5msecのようなので実験と合っています。

 
次はこれを使って球ころがしをしてみます。
 
 
Reference:
Sensor
SensorEvent
SensorManager