質問
加速度計の動きを検出するコードスニペットがあります。わずかな動きを適切に検出することで機能することもありますが、デバイスをアイドル状態にしたときに動きを検出することもあります。 Androidの組み込みの加速度センサーの検出に問題はありますか?
HTC G-1デバイスを使用しています。私のコードスニペットは以下です。小さなデバイスの動きは検出できるが、デバイスがアイドル状態のときは何も検出できないように解決するにはどうすればよいですか?
private static final int SHAKE_THRESHOLD = 50;
public void onSensorChanged(int sensor, float[] values) {
if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
long curTime = System.currentTimeMillis();
// only allow one update every 100ms.
if ((curTime - lastUpdate) > 100) {
long diffTime = (curTime - lastUpdate);
lastUpdate = curTime;
x = values[SensorManager.DATA_X];
y = values[SensorManager.DATA_Y];
z = values[SensorManager.DATA_Z];
float speed = Math.abs(x+y+z - last_x - last_y - last_z) / diffTime * 10000;
if (speed > SHAKE_THRESHOLD) {
long curTime = System.currentTimeMillis();
long diff = (curTime - shakeTime);
shakeTime = curTime;
if (myFlagIgnoreShakeDetection==true) //Caused unneccessary accelerometer
//notification looping when device is idle
return;
// Doing something...
}
last_x = x;
last_y = y;
last_z = z;
}
}
}
解決
いくつかのコードの不一致があります...
-
last_x
、last_y
、およびlast_z
の更新に関して問題がある可能性があります。if((curTime-lastUpdate)> 100){
ステートメントに 含める必要があると思います。つまり、100ミリ秒ごとではなく、onSensorChanged
が呼び出されるたびに更新されます。おそらく、これらの3つの変数の更新をそれらの上の中括弧に移動する必要があります。 -
speed
を計算する行で、式は... / diffTime * 10000;で終わります。
だけを乗算しますか? diffTime
で10000倍、または結果全体ですか?通常、/
と*
の演算子の優先順位は同じです。 私が知っているほとんどの言語( Java )、方程式は左から右に評価され、まずdiffTime
then で除算され、その結果に10000を掛けます。単に
diffTime
に10000を掛けることを意味すると思います。したがって、その量で最終結果を除算します。これは、10000で除算するか、10000で乗算するかの違いです。つまり、おそらくspeed
の値が必要以上に10 ^ 8大きくなり、デバイスがアイドル状態でもしきい値をトリップすることになります。... /(diffTime * 10000);
のように、乗算を括弧で囲む必要があります。これは、除算が行われる前に実行されることを確認するためです。さらに、
diffTime
をミリ秒から秒にスケーリングする場合、スケール係数は1000である必要があります。
他のヒント
個人的に、拡張現実ライブラリでは、更新にローリング平均を使用します:
float kFilteringFactor = (float)0.05;
rollingZ = (float) ((rawZValue * kFilteringFactor) + (rollingZ * (1.0 - kFilteringFactor)));
これにより、データが非常にスムーズになり、フィルター係数を調整して、必要な応答性を得ることができます。
rawZValueは、加速度計から入力される生の値です。