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

令我非常惊讶的是,在Android 4.0+版本中,他们决定从可用的软件传感器中移除LINEAR ACCELERATION传感器,并将其放入硬件传感器中,这是传统手机中很少使用的陀螺仪。 我不知道他们为什么这么做,但想象一下,当我交付使用廉价2.3手机测试过的软件时,出乎意料的是,在2个月的手机上显示无法实例化线性加速度传感器。 他们为什么要这样做?

为了保存我的皮肤,我检查了手机中是否有加速度计,并且确实如此。 基于这篇文章,我应该能够使用来自加速度计的数据计算线性加速度。 我检查了代码,发现一个没有声明的变量。

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};

还是应该包含通过重力传感器可用的真实重力数据(在常规设备中也不可用)?

计算结果是否为正确的线性加速度数据? 是否可以通过减少传入传感器数据中的数字来计算?


实际上,在文档中提供的代码片段是,它们从加速度计(包含重力和线性加速度)中获取数据并对其进行过滤。 因此,它如何基本工作,我们采取原始数据,并假设重力矢量是恒定的,不能很快改变,与线性加速度相反,而线性加速度的变化非常快。 因此,让我们假设如果我们使用过去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];
}  
}

我没有一个可靠的答案,但是我知道的是,acelerometer的实际初始读数很难(0,0,0),因为当设备不移动时它不是0,因为值取决于3轴的位置,而不是在运动中(随着位置的不同,我们可以推断出运动)。 因此,要获取任何相关数据,您必须比较不同的读数。 为此,我希望在开始时读取acelerometer的值(在第一次调用onsensorchanged ),然后开始计算第二次调用函数时需要的值

实际上,当他们谈论重力时,你不需要重力传感器,因为acelerometer实际上就是这样。 它正在测量每个轴的重力值,从0到1


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

链接地址: http://www.djcxy.com/p/76669.html

上一篇: How to properly calculate linear acceleration using AcceleroMeter in Android

下一篇: include's?