线性加速度方向用于跟踪手机的上下运动。

9
我正在尝试仅跟踪设备在垂直方向上的移动,即向上和向下的运动。这应该与设备的方向无关。我已经知道或尝试过的事情是:
  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.

这种方法有什么缺陷?请帮帮我,我已经卡在这里很长时间了。

1个回答

2
据我所见,第三种方法是尝试找到两个向量之间的角度余弦(重力向量和加速度向量)。而且,如果角度接近于180度,你上升;如果角度接近于0度,则下降。余弦函数在角度从-90度到90度之间具有正值。因此,当您的cosineVal值为正时,意味着手机正在向下移动,即使cosineVal接近1,运动也是直线向下的。反之亦然。当余弦为负数(从90度到270)时,你在往上移动。
可能可以从“Sensor.TYPE_ACCELEROMETER”中获取向量,从https://developer.android.com/reference/android/hardware/SensorEvent.html#values那里获取重力向量和加速度向量。
我编写了下面的代码片段供您尝试。
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) {

    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接