3

加速度計の動きを検出するコード スニペットがあります。わずかな動きを適切に検出することで機能することもありますが、デバイスをアイドル状態にしておくと動きを検出することもあります。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;
        }

    }

}
4

2 に答える 2

1

ここにいくつかのコードの不一致があります...

  • last_xlast_y、およびの更新に関して問題がある可能性がありますlast_z。それらは声明のに含めるべきだと思います。つまり、 100 ミリ秒ごとではなく、呼び出されるif ((curTime - lastUpdate) > 100) {たびに更新されます。onSensorChangedおそらく、これら 3 つの変数の更新をそれらの上の中括弧に移動する必要があります。

  • を計算する行でspeed、式は次で終わり... / diffTime * 10000;ますdiffTime/*通常、私が知っているほとんどの言語 ( Javaなど) で同じ演算子の優先順位があるため、方程式は左から右に評価され、最初に除算してから、その結果に 10000掛けます。diffTime

    私はあなたdiffTimeが 10000 だけを掛けることを意味していると推測しているので、最終結果をその量で割っています。これは、10000 で割るか 10000 を掛けるかの差です。つまりspeed、必要以上に 10^8 大きい値が得られる可能性があり、デバイスがアイドル状態の場合でもしきい値がトリップします。除算が行われる前に... / (diffTime * 10000);確実に実行されるように、 のように乗算を括弧で囲む必要があります。

    さらに、diffTimeミリ秒から秒にスケーリングする場合は、スケール ファクターを 1000 にする必要があります。

于 2009-10-27T14:12:46.163 に答える
0

個人的には、拡張現実ライブラリで、更新にローリング平均を使用しています。

float kFilteringFactor = (float)0.05;    
rollingZ = (float) ((rawZValue * kFilteringFactor) + (rollingZ * (1.0 - kFilteringFactor)));

これにより、データがかなりスムーズになる傾向があり、フィルタリング係数を微調整して、必要な応答性を得ることができます.

rawZValue は、加速度計からの生の値です。

于 2009-10-27T21:51:52.063 に答える