6

X、Y、Z の 3 次元すべてで加速度の読み取り値があるとします。読み取り値を使用して、電話が左または右に傾いているとどのように推測しますか? 読み取り値は 20ms ごとに生成されます。

実際には、読み取り値から傾きを推測するロジックが必要です。傾きは滑らかである必要があります。

4

4 に答える 4

23

傾きは、さまざまな方法で検出できます。1 軸、2 軸、または 3 軸を考慮することができます。あなたがどれだけ正確にそれを望んでいるか、そしてあなたがどれだけ数学と戦いたいと思っているかによって異なります.

軸を1つだけ使用する場合は、非常に簡単です。モバイルが完全に水平であると考えて、次のように動かします。

ここに画像の説明を入力

1 つの軸、たとえば x 軸を使用するだけで十分です。これは、小さな動きでも軸が変化するため、その軸位置の変化を正確に検出できるためです。ただし、アプリケーションがその軸のみを読み取り、ユーザーが電話をほぼ垂直に持っている場合、電話を大きな角度で回転させても x 軸の差は非常に小さくなります。とにかく、粗い分解能のみが必要なアプリケーションでは、単軸を使用できます。

基本的な三角法を参照すると、x 軸に重力ベクトルを投影すると、加速度計の x 軸と水平線の間の角度のサインに等しい出力加速度が生成されます。つまり、軸の値 (加速度の値) があれば、デバイスの角度を計算できます。

ここに画像の説明を入力

これは、センサーによって与えられた値が 9.8 * 角度のサインであることを意味するため、実際の角度を計算することができます。

しかし、心配しないでください。これを行う必要さえありません。下の表でわかるように、値は多かれ少なかれ比例しているため、正確である必要がない場合は、角度が何を表しているかをあまり気にせずに、センサーの値を直接操作できます。その値の変化は角度の比例した変化を意味するので、いくつかのテストで、あなたに関連するためにどれくらいの大きさの変化が必要かがわかります.

ここに画像の説明を入力

したがって、時間の経過とともに値を取得し、互いに比較すると、回転がどれだけ大きかったかがわかります。このため、

  1. 1 つの軸のみを考慮します。これが X 軸になります。
  2. ある関数呼び出しと次の関数呼び出しの間のその軸のセンサー値の差を取得する関数を作成します。
  3. 有効な動きと見なす最大時間と最小センサー差を決定します (たとえば、大きな回転は適切ですが、それが十分に速い場合に限られ、高速な動きは角度の差が十分に大きい場合にのみ適切です)。
  4. これらの条件を達成する 2 つの測定値を検出した場合は、完了したハーフ チルトを記録し (ブール値などで)、再度測定を開始しますが、新しい基準値は、ハーフ チルトと見なされた値になります。
  5. 最後の差が正の場合は負の差が必要になり、最後の差が負の場合は正の差が必要になります。これは、戻ってくることです。そのため、新しい基準値とセンサーからの新しい値を比較して値を取得し始め、ポイント 3 で決定したことを達成できるかどうかを確認します。
  6. 有効な値が見つかった場合 (値の差と時間の条件を満たしている場合)、傾きがあります。しかし、良い値が得られず、時間がかかる場合は、すべてをリセットします。基準値を最後の値にし、タイマーをリセットし、ハーフチルト完了ブール値を false にリセットし、測定を続けます。

これで十分だと思います。確かに、これに役立ついくつかのライブラリまたはコードスニペットを見つけることができますが、あなたが言うように、読み取り値から傾斜を推測するロジックを知ることは良いことだと思います

写真はこの記事から取得したものです。精度を向上させたい場合は、この記事を読むことをお勧めします。傾斜には 2 ~ 3 軸を考慮してください。

于 2013-12-09T11:44:29.447 に答える
-1

これはあなたが探しているものですか?

public class AccelerometerHandler implements SensorEventListener
{
    float accelX;
    float accelY;
    float accelZ;

    public AccelerometerHandler(Context paramContext)
    {
        SensorManager localSensorManager = (SensorManager)paramContext.getSystemService("sensor");

        if (localSensorManager.getSensorList(1).size() != 0)
            localSensorManager.registerListener(this, (Sensor)localSensorManager.getSensorList(1).get(0), 1);
    }

    public float getAccelX()
    {
        return this.accelX;
    }

    public float getAccelY()
    {
        return this.accelY;
    }

    public float getAccelZ()
    {
        return this.accelZ;
    }

    public void onAccuracyChanged(Sensor paramSensor, int paramInt)
    {
    }

    public void onSensorChanged(SensorEvent paramSensorEvent)
    {
        this.accelX = paramSensorEvent.values[0];
        this.accelY = paramSensorEvent.values[1];
        this.accelZ = paramSensorEvent.values[2];
    }
}
于 2013-12-11T01:10:51.607 に答える