【问题标题】:Linear acceleration direction to track upward and downward movement of phone直线加速方向跟踪手机的上下运动
【发布时间】:2014-11-27 03:16:07
【问题描述】:

我试图仅在垂直方向上跟踪设备的运动,即向上和向下运动。这应该与设备的方向无关。我已经知道或尝试过的就是这些

  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.

该方法有什么缺陷?请帮忙,我已经坚持了一段时间了。

【问题讨论】:

    标签: android vector android-sensors motion-detection


    【解决方案1】:

    在我看来,在第三种方法中,您试图找到两个向量(重力向量和加速度向量)之间的角度余弦。这个想法是,如果角度接近 180 度,您就有向上运动,如果角度接近 0 度,您就有向下运动。余弦是角度在 -90 到 90 度时具有正值的函数。因此,当您的 cosineVal 值为正时,这意味着手机正在下降,即使 cosineVal 接近 1 运动也是直线下降。所以反之亦然。当余弦为负时(从 90 度到 270 度),您将向上移动。

    也许你可以从Sensor.TYPE_ACCELEROMETERhttps://developer.android.com/reference/android/hardware/SensorEvent.html#values 获得矢量,那里有重力矢量和加速度矢量。
    我在下面做了一个代码sn-p你可以试试。

    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) {
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-20
      • 1970-01-01
      • 2011-09-11
      • 1970-01-01
      • 2012-02-13
      相关资源
      最近更新 更多