加速度センサーと地磁気センサーを使うには(AndroidMode編)

◆PROCESSING 逆引きリファレンス

 カテゴリー:スマホ(AndroidMode)

加速度センサーと地磁気センサーを使うには(AndroidMode編)

【概要】

PROCESSINGにAndroidMode を導入する事で、PROCESSINGで開発したプログラムをAndroid端末上で動かす事ができるようになります。

AndroidModeの導入については「PROCESSINGをAndroid端末で動かすには(4.0版)」記事を参照してください。

スマホの魅力は様々なアプリケーションを動かすことができるだけでなく、いろいろなセンサーを手軽に利用できるところにもあるのではないでしょうか?。

Androidでセンサーを扱うには、まずはセンサー管理オブジェクトを取得します。

その後センサー管理オブジェクトから、読み取りたいセンサーを制御するオブジェクトを取得し、目標となるセンサーの値が変化したらイベントを通知するリスナーを登録します。

センサーの値が変化すると、指定したリスナーに専用のイベントが飛んできますので、イベント関数の中でセンサーから値を取得するわけです。

センサー管理オブジェクトとセンサー制御オブジェクトの取得については「利用可能なセンサーを知るには(AndroidMode編)」記事を参照してください。

以下では、スマホの代表的なセンサーである加速度センサーと地磁気センサーから値を取得する方法を紹介します。

 

【詳細】

全般的な注意

センサー管理オブジェクト、センサー制御オブジェクトの取得と、読み取りたいセンサーへのリスナー登録は、Androidの画面が準備完了となり画面が表示される直前に行うべきです。

なぜなら、Androidでは画面が回転したり電話がかかってきたりすると、表示中の画面が破棄され、再作成される事があるためです。

またセンサーを適時読み取る処理はバッテリーを消費するため、必要がなくなった場合(例えば画面が隠れるような状況になった場合)は、これを即座に停止すべきでしょう。

とくにPROCESSINGでセンサーを使うなら、リスナーの登録処理はsetup関数ではなく onResumeメソッドをオーバライドして行うべきです。

またセンサーの開放処理は、onPauseメソッドをオーバライドして行うのが良いでしょう。

このあたりの話題は「PROCESSINGとライフサイクル(AndroidMode編)」記事も参考としてください。

Androidでのセンサー座標軸は、X軸が水平で右側が+、Y軸が垂直で上側が+、Z軸は画面正面の外側が+を指しています。座標軸は画面が回転しても入れ替わることはありません。

(画像URL:illust-AC 様:kaeru-yaさん)

加速度は m//s² で、1秒(s)あたりの移動距離(m)が検知されます。

ただし加速度には重力が加味されているため、例えばスマホを上向き(画面を上)にして水平な机に置いた場合、Z軸に +9.8m/s² の(重力とは反対方向の)加速度が検知されます。

同じようにスマホを右に傾けるとX軸にマイナスの、頭側を下に(奥に)傾けるとY軸にマイナスの加速度が検知されます。

加速度については以下のサイト様が参考となりました。ありがとうございます。

地磁気は磁束密度(マイクロテスラ:μT)で、それぞれX、Y、Z方向の磁束密度が検知されます。

地磁気については以下のサイト様が参考となりました。ありがとうございます。

 

センサー制御オブジェクト取得

センサー制御オブジェクト取得Sensor sensor = mng . getDefaultSensor(int Type) ;
sensor : センサー制御オブジェクト。利用できない場合は nullが戻る
mng : センサー管理オブジェクト
Type : 取り出すセンサーの種類

Typeに取り出したいセンサーの種類を与えることで、センサー制御用のオブジェクトを取得できます。

加速度センサー用の制御オブジェクトを取り出したいなら、TypeにはSensorクラスがもつTYPE_ACCELEROMETER定数(Sensor.TYPE_ACCELEROMETER)を指定します。

また地磁気センサーを取得するには、TYPE_MAGNETIC_FIELD定数(Sensor.TYPE_MAGNETIC_FIELD)を指定します。

 

リスナー登録・解除

リスナー登録boolean ret = mng . registerListener (SensorEventListener listener,Sensor sensor,int samplingPeriodUs) ;

mng : センサー管理オブジェクト
sensor : センサー制御オブジェクト
listener : リスナーオブジェクト
samplingPeriodUs : 読み取り頻度
ret : 戻り値(true:成功)

リスナーオブジェクトには、SensorEventListenerインタフェースを実装している必要があります。

PROCESSINGで使うなら、Sketchクラスに上記インタフェースを実装するか、専用のクラスを定義するのが良いでしょう。

samplingPeriodUsには、SensorManagerクラスが持つ以下の何れかの定数を与えます。

定数 意味
SENSOR_DELAY_NORMAL 通常のレート。デフォルト値
SENSOR_DELAY_UI 画面表示やUIを伴うレート
SENSOR_DELAY_GAME GAMEに適したレート
SENSOR_DELAY_FASTEST できるだけ早くデータを取得するレート

データをすばやく引き取ろうとすればするほどバッテリーを食いますので、そこは注意してください。

バッテリー消費を最小限に抑え、できるだけゆっくりとイベントを通知すれば良いのであれば、samplingPeriodUsの後ろにmaxReportLatencyUs引数を追加する事が可能です。

maxReportLatencyUsには、イベントをアプリケーションに報告する前に遅延させる最大時間(マイクロ秒)を指定します。

maxReportLatencyUs引数がない場合(上記で紹介した例)は、maxReportLatencyUsに0を指定した場合と等価になります。

 

リスナー解除void mng . unregisterListener (SensorEventListener listener) ;

mng : センサー管理オブジェクト
listener : リスナーオブジェクト

センサーの値を読み取る必要がなくなったら、速やかにリスナーを解除し、データの通知を停止します。

 

データの取得

データの取得void onSensorChanged( SensorEvent event) ;

event : センサーイベント

センサから新しい値を取得した場合に呼び出されるメソッドです。SendorEventについては 公式サイト を参照してください。

どのセンサーからのデータであるかは、SensorEventのsensorで知ることが可能です。

またSendorEventからデータ(values)を取得する際には、できるだけ速やかに取得する必要があります。

加速度はm//s² で、event.values[0]からはX軸、event.values[1]からはY軸、event.values[2]からはZ軸の加速度が取得できます。

地磁気はマイクロテスラ(μT)で、おなじくevent.values[0]からはX軸、event.values[1]からはY軸、event.values[2]からはZ軸の周囲磁場が測定できます。

この他に、SensorEventListener にはセンサーの精度が変化した際にイベントの通知が行われるonAccuracyChangedメソッドがありますが、こちらの使い所はよくわかりませんでした(汗)。

センサーの精度を細かく変更しながら処理を行う、特殊なアプリケーションを作成する際には活躍するのかもしれません。

 

【関連記事】

 


サンプルプログラム

加速度と地磁気を取得する例:

加速度と地磁気のセンサー値を画面に表示します。

地磁気に関しては以下の計算式で、大きさを求めて表示しています。この式、たぶん・・・あっていると思います。間違えていたらゴメンなさい(汗)。

<出力サンプル>

 

電子コンパスの例:

加速度センサーと地磁気センサーを用いると、こんな事もできるよという例です。

難しい計算の理屈は良くわかりませんが(汗)、両方のセンサーから得た値をもとに方位角の計算を行い、電子コンパスを描きます。

なお検出される方位は磁北になります。真北ではありません。磁北と真北が違うのだということは、このサンプルを作成している中で初めて知りました(お恥ずかしい・・・)。

上記サンプルの作成に、以下のページを参考とさせていただきました。ありがとうございます。

<出力サンプル>


(画像URL:illust-AC 様:ニッキー さん)


PROCESSING逆引きリファレンス一覧 へ戻る

本ページで利用しているアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。