首页 文章

如何使用Android中的AcceleroMeter正确计算线性加速度

提问于
浏览
7

令我极为惊讶的是,在Android 4.0中,他们决定从可用的软件传感器中移除LINEAR ACCELERATION传感器,并将其放入硬件传感器中,这是普通手机中很少使用的陀螺仪 . 我不知道他们为什么这么做,但想象一下,当我交付在便宜的2.3手机上测试的软件时,我感到惊讶,在2个月大的手机上显示无法实例化线性加速度传感器 . 他们为什么要这样做?

为了保存我的皮肤,我检查了手机中是否有可用的加速度计,确实如此 . 基于this article,我应该能够使用加速度计的数据计算线性加速度 . 我检查了代码,我看到一个没有可用声明的变量 .

public void onSensorChanged(SensorEvent event){
  // In this example, alpha is calculated as t / (t + dT),
  // where t is the low-pass filter's time-constant and
  // dT is the event delivery rate.

  final float alpha = 0.8;
  float[] gravity=new float[]{0.0f,0.0f,0.0f}; //should it be here???

  // Isolate the force of gravity with the low-pass filter.
  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];

  // Remove the gravity contribution with the high-pass filter.
  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[] gravity=new float[]{0.0f,0.0f,0.0f};

或者它是否应包含通过重力传感器提供的真实重力数据(在常规设备中也不可用)?

计算结果是否适当的线性加速度数据?是否可以通过从传入的传感器数据中减去一个数字来计算?

3 回答

  • 1

    实际上,在文档中提供的代码片段是,他们从加速度计(包含重力和线性加速度)获取数据并对其进行过滤 . 那么它基本上是如何工作的,我们采用原始数据并假设重力矢量是常数并且不能很快地改变,与线性加速度相反,线性加速度变化非常快 . 因此,假设我们采用80%的过去计数重力矢量并添加20%的原始数据,我们过滤快速线性加速度峰值并获得重力矢量 . 如果我们从原始数据中移除重力矢量,我们将获得无重力的线性加速谷歌的指数过滤器更多信息 . 在这里你可以玩它http://copterpilot.ru/custom-app/exponential/ . 因此,您可以使用零轻松初始化浮点数的全局重力数组,并等待一些过滤数据 . 这是代码片段

    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];
    }  
    }
    
  • 2

    我没有经典的答案,但我知道的是,acelerometer的实际初始读数几乎不会是(0,0,0),因为当设备不移动时它不是0,因为值取决于3轴的位置,而不是在运动中(与位置的差异,我们可以推断出运动) . 因此,要获得任何相关数据,您必须比较不同的读数 . 为此,我更喜欢在开始时读取acelerometer值(在第一次调用 onsensorchanged 时),然后开始计算你在第二次调用函数时需要启动的内容

    实际上,当他们谈论引力时,你不需要重力传感器,因为实际上是那个 . 它测量每个轴的重力值,从0到1

  • 1

    你需要计算重力矢量 . 基本上你的加速度计测量总重力加速度,所以你需要从中移除重力 . 在您提供的同一篇文章中,有关于如何使用重力传感器的信息 . 所以听听那个传感器并从中更新你的重力矢量全局变量 .

相关问题