首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在安卓系统中利用AcceleroMeter正确计算直线加速度

如何在安卓系统中利用AcceleroMeter正确计算直线加速度
EN

Stack Overflow用户
提问于 2014-01-05 15:51:15
回答 3查看 17.9K关注 0票数 8

令我惊讶的是,在Android 4.0+中,他们决定将线性加速度传感器从可用的软件传感器中移除,并将其放入硬件传感器中,这是在普通手机中很少可用的陀螺仪。我不知道他们为什么这么做,但想象一下,当我交付了在一部廉价的2.3手机上测试过的软件,而在2个月前的手机上,它显示无法实例化直线加速度传感器,这让我感到惊讶。他们为什么要这么做?

为了挽救我的生命,我检查了手机里是否有加速度计,而且确实有。基于this article,我应该能够用加速度计的数据来计算直线加速度。我检查了代码,并看到一个没有可用声明的变量。

代码语言:javascript
复制
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];
}

重力数组在第一次运行时包含什么?我是不是应该把它加上去

代码语言:javascript
复制
float[] gravity=new float[]{0.0f,0.0f,0.0f};

或者它应该包含真正的重力数据,这些数据可以通过重力传感器获得(在常规设备中也没有)?

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

EN

回答 3

Stack Overflow用户

发布于 2016-04-29 08:48:54

实际上,文档中提供的代码片段所做的是从加速度计(包含重力和线性加速度)中获取数据并过滤它。所以它基本上是如何工作的,我们取原始数据,假设重力矢量是常数,不能很快改变,与直线加速度相反,直线加速度变化非常快。假设我们取80%的过去计算的重力矢量,再加上20%的原始数据,我们过滤快速线性加速度峰值,得到重力矢量。如果我们从原始数据中删除重力矢量,我们就可以得到没有重力的直线加速度。谷歌指数过滤器获得更多信息。在这里你可以玩它,http://copterpilot.ru/custom-app/exponential/。因此,您可以轻松地用零初始化全局重力浮点数数组,并等待过滤后的数据。下面是代码片段

代码语言:javascript
复制
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];
}  
}
票数 5
EN

Stack Overflow用户

发布于 2014-01-05 16:13:30

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

事实上,当他们谈论重力时,你不需要重力传感器,因为加速度计实际上就是重力传感器。它测量每个轴的重力值,从0到1。

票数 1
EN

Stack Overflow用户

发布于 2014-04-19 04:34:28

你需要计算重力矢量。基本上,你的加速度计测量的是gravity+acceleration,所以你需要去掉重力。在您提供的同一篇文章中,有关于如何使用重力传感器的信息。所以,听这个传感器,并更新你的重力矢量全局变量从它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20935587

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档