簡體   English   中英

線性加速度方向跟蹤手機的上下運動

[英]Linear acceleration direction to track upward and downward movement of phone

我試圖僅在垂直方向上跟蹤設備的移動,即向上和向下移動。 這應該與設備的方向無關。 我已經知道或嘗試過的事情是這些

  1. 線性加速度是由傳感器TYPE_LINEAR_ACCELERATION給出的,並且軸是電話軸,因此跟蹤任何特定的軸都沒有區別。

  2. 我嘗試應用旋轉矢量的轉置或逆轉(旋轉矢量的逆轉或轉置相同),然后嘗試跟蹤線性加速度矢量的z方向。 似乎沒有幫助。

  3. 我正在嘗試使用重力值(TYPE_GRAVITY)進行點積運算以獲取加速度的方向,但似乎容易出錯。 即使我將設備快速向上移動,它也表示向下移動。

我將在這里概述此方法

dotProduct = vectorA[0]*vectorB[0]+vectorA[1]*vectorB[1] + vectorA[2]*vectorB[2];    
cosineVal = dotProduct/(|vectorA|*|vectorB|)    
if(cosineVal > 0 ) down else Up.

該方法的缺點是什么? 請幫助,我已經堅持了一段時間。

如我所見,在第三種方法中,您試圖找到兩個向量(重力向量和加速度向量)之間的角度cos。 想法是,如果角度接近180度,則您可以向上移動;如果角度接近0度,則您可以向下移動。 余弦是當角度為-90至90度時具有正值的函數。 因此,當您的cosineVal值為正時,表示電話正在關閉,即使cosineVal接近1的運動也將直接向下。 反之亦然。 當余弦為負(從90度到270度)時,您將向上運動。

可能您可以從https://developer.android.com/reference/android/hardware/SensorEvent.html#valuesSensor.TYPE_ACCELEROMETER獲得矢量,那里有重力矢量和加速度矢量。
我在下面做了一個代碼片段,您可以嘗試。

public class MainActivity extends AppCompatActivity implements SensorEventListener {
    private float[] gravity = new float[3];
    private float[] linear_acceleration = new float[3];

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SensorManager mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        Sensor mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        // alpha is calculated as t / (t + dT)
        // with t, the low-pass filter's time-constant
        // and dT, the event delivery rate

        final float alpha = 0.8f;

        gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
        gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
        gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];

        linear_acceleration[0] = event.values[0] - gravity[0];
        linear_acceleration[1] = event.values[1] - gravity[1];
        linear_acceleration[2] = event.values[2] - gravity[2];

        float scalarProduct = gravity[0] * linear_acceleration[0] +
                gravity[1] * linear_acceleration[1] +
                gravity[2] * linear_acceleration[2];
        float gravityVectorLength = (float) Math.sqrt(gravity[0] * gravity[0] +
                gravity[1] * gravity[1] + gravity[2] * gravity[2]);
        float lianearAccVectorLength = (float) Math.sqrt(linear_acceleration[0] * linear_acceleration[0] +
                linear_acceleration[1] * linear_acceleration[1] + linear_acceleration[2] * linear_acceleration[2]);

        float cosVectorAngle = scalarProduct / (gravityVectorLength * lianearAccVectorLength);

        TextView tv = (TextView) findViewById(R.id.tv);
        if (lianearAccVectorLength > 2) {//increase to detect only bigger accelerations, decrease to make detection more sensitive but noisy
            if (cosVectorAngle > 0.5) {
                tv.setText("Down");
            } else if (cosVectorAngle < -0.5) {
                tv.setText("Up");
            }
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {

    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM