【Android Pgm】正月:スマホ加速度Logger出来た<作り方備忘録>

Processing android modeのプログラム、BASICインタープリタ感覚で作れて気楽でいいです。たぶんスマホのプログラム環境の中では、最もシンプルでインタラクティブな言語と環境ではないでしょうか。<インストールで苦労しましたが嘘のようになってます
夕べから初めて、数時間でいくつかの機能をWEBで検索しながら埋め込んで、1月1日には、加速度ログプログラムが完成して、実験データ解析に入れました。
加速度ロガーならアプリが山ほどあるのですが、私の目的は
スキー万歩計ですので、加速度データの統計処理アルゴリズムを追加して万歩計にするのが目標ですので、このLoggerをベースに開発していきます。

●プログラムの備忘録
(MSLABO様から頂いた加速表示pgmに追加していきました)
①タップしたら座標値を取得
タップの認識は、MSLABO様のサンプルをより簡単にしてマウス座標をグローバル変数のpx、pyに代入するだけの関数にしました。
void mousePressed(){
//タッチされた座標を覚える
px_1=px;//1個前の座標
py_1=py;
px=mouseX;
py=mouseY;
}

②ある領域をタップしたらプログラムを停止
これは、上記px、pyの範囲を決めてそこをタップした時に
プログラムを停止します。画面右下隅をプログラム停止領域としました。下記をDraw()ループ内にいれておきます。
if (px>900 && py>1800){
output.flush(); // Writes the remaining data to the file
output.close(); // Finishes the file
this.getActivity().finish();
}
通常、Processingでは、exit()でプログラムを停止しますが、これは、android modeではエラーとなりますので、調べてみたら
processingのFORUMに記事がありました。
https://forum.processing.org/two/discussion/24019/#Comment_105188
 this.getActivity().finish();
詳細は分かりませんがこの1行だけでプログラムは止まってます。

③ファイル書き込み保存
これが結構手間取ったのですが、androidでファイル読み書きするにはpermissionが必須でした。
これのやり方もprocessing Forumにありました。
プログラムのフォルダに自動で発生しているAndroidManifest.xmlファイルをテキストエディタで開いて、permissionの1行を加えます。私は<application の直上にいれました。
<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE”/>

これでファイル書き込みは、processingのPC版と同様な使い方ができます。私は、PrintWriterで、printlnで書き込むのが好きなので使ってます。
ファイル名は、日時秒で作る関数を使ってます。
こちらのブログからソースいただきました。
http://takawo.hatenablog.com/entry/2017/08/20/082907
● ファイル書き込み部分だけ抜粋すると
PrintWriter output;
float sensorX, sensorY, sensorZ; //
float px,py,px_1,py_1;
void setup() {
fullScreen();
String fileName = createFileName();
output = createWriter(fileName);

void  draw(){ output.println(nf(tim,10,0)+”,”+nf(sensorX,1,2)+”,”+nf(sensorY,1,2)+”,”+nf(sensorZ,1,2)+”,”+nf(kakudo_yz,3,1));
}
//ファイル名を生成する関数、sdcardのDCIMにcsv保存してます
String createFileName() {
String fileName=”//sdcard/DCIM/”+ nf(year(), 2) + nf(month(), 2) + nf(day(), 2) +”-“+ nf(hour(), 2) + nf(minute(), 2) + nf(second(), 2);
fileName += “.csv”;
return fileName;
}

●Loggerを作ってみて
androidは、マルチタスクOSなので、割り込みが多数あって
サンプリング周期が相当ばらつきます。100msec周期目標でも30msecくらいばらつきます。

ブログからコピーすると見えない改行がたくさんはいってますので注意してください。MSLABO様が作っていただいた部分をずいぶん変更してしまったので、あくまで閲覧参考用です。
Processingをきちんと学習するには、MSLABO様のブログで
学習していただくのが最も早いと思います。

PROCESSING 逆引きリファレンス

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.util.Log;
Context context; //
SensorManager manager; //
Sensor sensor; //
AccelerometerListener listener; //
PrintWriter output;
float sensorX, sensorY, sensorZ; //
float px,py,px_1,py_1;

/**
* Android Mode Sample
* @author MSLABO
* @version 1.0
*/
ArrayList<PVector> touchP;//Pvector型のtouchP配列変数定義
void setup() {
fullScreen();
touchP = new ArrayList<PVector>();
// Create a new file in the sketch directory
String fileName = createFileName();
output = createWriter(fileName);
//
context = getActivity();
manager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
sensor = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

//
listener = new AccelerometerListener();
manager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_GAME);

//
textSize( 70 );
textAlign(CENTER, CENTER);
}

void draw() {
background(0);
fill(255);
int tim=0;
int tim_1=0;
float kakudo_yz;
kakudo_yz=degrees(atan2(sensorY,sensorZ));
text(“x: ” + nf(sensorX, 1, 2) + “\n” +
“y: ” + nf(sensorY, 1, 2) + “\n” +
“z: ” + nf(sensorZ, 1, 2)+”\n” +
“atan y/z:”+nf(kakudo_yz,3,3)
,0, 0, width, height);
text(“TouchX=”+nf(px,4,0)+”TouchY=”+nf(py,4,0)+”\n”,500,100);

tim=millis();
if (tim-tim_1>100){
tim_1=tim;
output.println(nf(tim,10,0)+”,”+nf(sensorX,1,2)+”,”+nf(sensorY,1,2)+”,”+nf(sensorZ,1,2)+”,”+nf(kakudo_yz,3,1)); // Write the coordinate to the file
}
if (px>900 && py>1800){
output.flush(); // Writes the remaining data to the file
output.close(); // Finishes the file
this.getActivity().finish();
}
}

//
class AccelerometerListener implements SensorEventListener {

//
public void onSensorChanged(SensorEvent event) {

//
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
//
sensorX = event.values[0];
sensorY = event.values[1];
sensorZ = event.values[2];
}
}

//
public void onAccuracyChanged(Sensor sensor, int accuracy) {

println(“onAccuracyChanged”);
}
}
void mousePressed(){
//タッチされた座標を覚える
px_1=px;
py_1=py;
px=mouseX;
py=mouseY;

}

void mouseDragged (){
//スワイプ中の座標を覚える
//touchP.add( new PVector( mouseX, mouseY ));
//Log.d( TAG, “swipe” );
}

void mouseReleased(){
//指が離れたら座標記録を初期化する
//touchP.clear();
//Log.d( TAG, “release” );
}

String createFileName() {
String fileName=”//sdcard/DCIM/”+ nf(year(), 2) + nf(month(), 2) + nf(day(), 2) +”-“+ nf(hour(), 2) + nf(minute(), 2) + nf(second(), 2);
fileName += “.csv”;
return fileName;
}

ログしたデータは、ES File ExplorerからGoogleDriveへ転送してPCのEXCELで処理して解析します。

●データを取ってみた。
■階段昇降では階段段数は数えられそうです。

■テレマーク姿勢前後10回ずつ
ピーク角度がばらつくので、屈曲動作をとらえるには何か工夫が必要です。実際のスキー波形もログして、解析を繰り返して万歩計プログラムを作っていきます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です