web-dev-qa-db-ja.com

加速度計を使用して移動方向を取得するにはどうすればよいですか?

Androidアプリケーションを開発していますが、1つの軸を固定して移動方向を検出できるかどうかを知りたいのですが、たとえば、スマートフォンをテーブルに置いて方向を検出したい動かすとき(左、右、上下)距離は必要ありません。正確な方向を知りたいだけです。

16
Marcos Passos

はい。

SensorEventListener.onSensorChanged(SensorEvent event)を使用して、X軸とY軸に沿って提供される値を決定できます。これらの値を記録してから、その後のonSensorChangedメソッドの呼び出しで受け取る新しい値と比較して、デルタ値を取得する必要があります。 1つの軸のデルタ値が正の場合、デバイスは一方向に移動し、負の場合は反対方向に移動します。

おそらく、加速度計イベントを受信する速度と、方向の変化を示すためにデルタ値を考慮するしきい値の両方を微調整する必要があります。

これが私が話していることの簡単なコード例です:

public class AccelerometerExample extends Activity implements SensorEventListener {
    TextView textView;
    StringBuilder builder = new StringBuilder();

    float [] history = new float[2];
    String [] direction = {"NONE","NONE"};

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        textView = new TextView(this);
        setContentView(textView);

        SensorManager manager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        Sensor accelerometer = manager.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
        manager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {

        float xChange = history[0] - event.values[0];
        float yChange = history[1] - event.values[1];

        history[0] = event.values[0];
        history[1] = event.values[1];

        if (xChange > 2){
          direction[0] = "LEFT";
        }
        else if (xChange < -2){
          direction[0] = "RIGHT";
        }

        if (yChange > 2){
          direction[1] = "DOWN";
        }
        else if (yChange < -2){
          direction[1] = "UP";
        }

        builder.setLength(0);
        builder.append("x: ");
        builder.append(direction[0]);
        builder.append(" y: ");
        builder.append(direction[1]);

        textView.setText(builder.toString());
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // nothing to do here
    }
}

このコードは、電話が移動したX軸とY軸の一般的な方向のみを提供します。方向のよりきめ細かい決定を提供するために(たとえば、コンピューターのマウスの動きを模倣しようとするため)、電話の加速度計は目的に適合していません。

これを試みるには、最初にセンサー遅延をSensorManager.SENSOR_DELAY_FASTに設定し、複数の履歴イベントのリストを作成して、時間の経過に伴う動きを検出し、加速度計を使用するときによく発生する反対方向のわずかな動きの影響を受けないようにします。そのような細かいレベルでの測定。コメントで提案されているように、動きの正確な測定値を計算するために、経過した時間を測定する必要もあります。

25
Louth

私が読んだことから、センサーでは加速度と電話の向きしか検出できません。そのため、速度が変化して加速度が発生するため(加速度の停止が速度方向に反する場合)、移動の開始(およびどの方向)と移動の停止を簡単に検出できます。

電話が一定の速度で動いている場合、加速度計はゼロ値(重力を差し引く線形加速度)を示します。したがって、電話が動いているかどうかを知るには、次のようにして、各瞬間の速度を計算する必要があります。

_V(t)=V(t0)+a*dt
_

その中で:

  • V(t0)は、前の瞬間の既知の速度です。
  • V(t)は、現時点での速度です。
  • aは加速度です(前の瞬間の加速度、または前の瞬間と現在の瞬間の間の平均加速度を考慮してください)。

問題は、センサー値の不確実性のために、各瞬間に小さなエラーを合計することになり、誤った速度値につながる可能性があることです。おそらく、ローパスフィルターを値に調整する必要があります。

0
renatogsousa