スマホに搭載されている加速度センサーを使うと、スマホを傾けると球が転がるようなアプリを作ることができます。これはMEMSと呼ばれる半導体を使っているのですね
2021.2.1
Accelerometer
加速度センサーは端末のx, y, z軸方向の加速度を計測します。単位[m/s²]
実際(?)にその動きをAndroid Studioのemulatorから加速度センサーの動きを見てみたいと思います。
Virtuial Sensors
emulatorを立ち上げて右バーのmore「…」をクリックするとExtended controlsダイアログが表れます。
「Virtual sensors」を選択、右サイドに端末が現れ、その上にある「Device Pose」をセットして、画面のスマホをマウスでドラッグすると「Rotation」によって「Resulting values」にx,y,z方向のセンサー出力が表示されます。
加速度なので動かす速度の変化で値が変わるのが分かります。
こちらはGoogleのSensorで説明されているTest with the Android Emulatorの動画です。
Coding
codingに移ります。実装方法を簡単に説明すると
- SensorEventListener の設定
- SensorManager のインスタンス生成
- registerListener の登録
- onSensorChanged でセンサー値の受け取り
となります。以下のコードはAndroid Studioから取り出せるSampleの中の「Accelemrometer Play」から切り出して簡単にしたものです。
センサー情報を取得する部分はセンサーのデバイス名やメーカー名などでアプリを作る時にはあまり関係ないので省いてもいいでしょう。
MainActivity.java
activity_main.xml
ちなみに、加速度センサーを試すとどうしても傾けたりしますが、そうすると画面が回転してしまうことがあります。
android:screenOrientation=”portrait”
を使うと画面の回転を「portrait」に固定できます。
AndroidManifest.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のようなので実験と合っています。
次はこれを使って球ころがしをしてみます。
関連ページ:
Sensor 一覧を取得する
加速度センサー:Accelerometer
加速度センサーで球ころがし
Gyroscope ジャイロセンサー
Reference:
Sensor
SensorEvent
SensorManager