CodeZine(コードジン)

特集ページ一覧

Delphiでデバイス機能をこってり使いつつマルチデバイス対応してみる

iOS/Android向けにコンポーネントでGPSや加速度センサーを簡単に使う

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加
2016/09/15 14:00

目次

モーションセンサーを使う

加速度センサーを使って水平器を作る

 最後の機能は少し違った用途かもしれませんが、スマートフォンに搭載された加速度センサーの情報を取得する例です。最近のスマートフォンでは日々の歩数や運動量を自動的に記録してくれたりしますが、それらの機能では加速度センサーの値に基づいてデータの記録を行っています。

 加速度センサーではX軸、Y軸、Z軸の加速度を取得できますが、X軸、Y軸はスマートフォンの横方向、縦方向ですが、Z軸は液晶面に対して手前側、背中側の向きを意味しています。それぞれの軸の値が0ならば、その向きへの動きはないことを意味します。

 ここではこの変化を利用して水平器を作ってみることにします。よくある水平器は色のついた液体を満たした容器の中に気泡があり、傾き具合によって気泡の位置が変わることで水平状態を確認します。今回作る処理ではアプリ画面上に円を表示して、X軸、Y軸の値に応じて表示位置を変えることにします。

TPlotGrid と TCircle で水平器の外観を作る

 UIに関しては、あらかじめ用意されたコンポーネントを使って、簡単に構築してしまうことにします。

 役立ちそうなのがTPlotGridとTCircleです。TPlotGridは方眼紙状のグリッドを表示するコンポーネントです。TPlotGridを配置したら、Frequncyプロパティを適切な値(この場合は20に設定しました)を指定し、方眼のマス目を調整します。そして、この上に円を表示するTCircleを配置すれば、水平器の基本デザインの完成です。簡単ですね。

図7 水平器のUI設計

加速度を取得する

 加速度はTMotionSensorで取得できます。ただしTMotionSensorでは、値が変化したときにイベント通知を受け取るという動作ができません。そこで、TTimerを使ってで定期的に値の読み取りを行うようにします。

 TTimerのOnTimerイベントハンドラに、以下のコードを記述します。このコードは、TTimerのIntervalプロパティに指定したミリ秒ごとに呼び出されます。今回は、この値を100(=0.1秒)にしてみました。

procedure TForm1.Timer1Timer(Sender: TObject);
var
  // 加速度。
  syntheticAccel: double;

  // X,Y,Z軸の加速度。
  AccelX: double;
  AccelY: double;
  AccelZ: double;
begin
  // x,y,z軸の加速度を取得して値を100倍にする。
  // (値の変化を誇張するため)
  AccelX := MotionSensor1.Sensor.AccelerationX * 100;
  AccelY := MotionSensor1.Sensor.AccelerationY * 100;
  AccelZ := MotionSensor1.Sensor.AccelerationZ * 100;

  // 3軸の合成加速度を算出する。
  // これは加速度ベクトルの大きさ(スカラー成分)だけを取り出す処理。
  // 3軸の加速度が変化しても合成加速度に変化がなければ、
  // 物体の運動は変化していないと判断できる。
  syntheticAccel := 
    sqrt( power(AccelX,2) + power(AccelY,2) + power(AccelZ,2) );

  // 取得した値をラベルに出力する。
  Label1.Text := Format( 'X: %3.2f', [ AccelX ] );
  Label2.Text := Format( 'Y: %3.2f', [ AccelY ] );
  Label3.Text := Format( 'Z: %3.2f', [ AccelZ ] );
  Label4.Text := Format( 'accel: %3.2f', [ syntheticAccel ] );

  // Circle を x, y 軸の加速度の値に合わせて Grid に重ねて表示する。
  Circle1.Position.X :=
    ((PlotGrid1.Width  - Circle1.Width )/2.0) - (AccelX*10.0);
  Circle1.Position.Y :=
    ((PlotGrid1.Height - Circle1.Height)/2.0) + (AccelY*10.0);
end;

 取得した加速度の値で円の位置を動かす処理は、TCircleのPosition.XとPosition.Yを書き換えるだけです。X軸とY軸の加速度が0のときにTPlotGridの中心に円の位置が定まるような計算式を作り、その計算式でPosition.XとPosition.Yを求めるようにしています。

アプリの完成

 アプリには、X、Y、Z軸の加速度、3軸合成値(加速度のスカラー値)などの数値情報なども表示されるようにしてみました。

図8 水平器の表示

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • EDN編集部(イーディーエヌ編集部)

    エンバカデロ・デベロッパーネットワーク(EDN)は、ソフトウェア開発者とデータベース技術者のための技術情報サイトです。Delphi、C++Builderをはじめとする開発ツールやER/Studioなどのデータベースツールに関連する技術記事、ビデオなどを提供しています。EDN編集部は、EDN記事と連携...

バックナンバー

連載:EDN CodeZine出張所

もっと読む

All contents copyright © 2005-2020 Shoeisha Co., Ltd. All rights reserved. ver.1.5