简体   繁体   English

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

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

I am trying to track the movement of the device only on the vertical direction, ie upward and downward movement. 我试图仅在垂直方向上跟踪设备的移动,即向上和向下移动。 This should be irrespective of the orientation of the device. 这应该与设备的方向无关。 Things that i already know or have tried are these 我已经知道或尝试过的事情是这些

  1. Linear acceleration is given by sensor TYPE_LINEAR_ACCELERATION and the axes is the phone axes and hence tracking any particular axes does not make a difference. 线性加速度是由传感器TYPE_LINEAR_ACCELERATION给出的,并且轴是电话轴,因此跟踪任何特定的轴都没有区别。

  2. I tried applying transpose or inverse of rotation vector( inverse or transpose for the rotation vector are same) and then tried tracking the z direction of the linear acceleration vector. 我尝试应用旋转矢量的转置或逆转(旋转矢量的逆转或转置相同),然后尝试跟踪线性加速度矢量的z方向。 Does not seem to help. 似乎没有帮助。

  3. I am trying to do a dot product with gravity values (TYPE_GRAVITY) to get the direction of the acceleration but it seems to be error prone. 我正在尝试使用重力值(TYPE_GRAVITY)进行点积运算以获取加速度的方向,但似乎容易出错。 Even when i move my device swiftly up, it says going down. 即使我将设备快速向上移动,它也表示向下移动。

I will outline this method here 我将在这里概述此方法

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

What is the flaw with the method ? 该方法的缺点是什么? Please help, I have been stuck on this for some time now. 请帮助,我已经坚持了一段时间。

As I see it, in the 3rd method you trying to find the cos of angle between two vectors (gravity vector and acceleration vector). 如我所见,在第三种方法中,您试图找到两个向量(重力向量和加速度向量)之间的角度cos。 And the idea is if the angle is close to 180 degrees you have up movement, if angle is close to 0 degrees you have down movement. 想法是,如果角度接近180度,则您可以向上移动;如果角度接近0度,则您可以向下移动。 Cosine is function that has positive value when angle is from -90 to 90 degrees. 余弦是当角度为-90至90度时具有正值的函数。 So when your cosineVal value is positive it means phone is going down and even if cosineVal closer to 1 movement is straight down. 因此,当您的cosineVal值为正时,表示电话正在关闭,即使cosineVal接近1的运动也将直接向下。 So it is true vice versa. 反之亦然。 When cosine is negative ( from 90 degrees to 270) you have up movement. 当余弦为负(从90度到270度)时,您将向上运动。

Probably you can get vectors from Sensor.TYPE_ACCELEROMETER from https://developer.android.com/reference/android/hardware/SensorEvent.html#values there you have gravity vector and acceleration vector. 可能您可以从https://developer.android.com/reference/android/hardware/SensorEvent.html#valuesSensor.TYPE_ACCELEROMETER获得矢量,那里有重力矢量和加速度矢量。
I made a code snippet below you can try. 我在下面做了一个代码片段,您可以尝试。

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