集成 Android 加速计来查找速度和位置

Joh*_*nnB 5 java android accelerometer

我正在尝试使用 Android 设备上的加速度计计算位移 ( Sensor.TYPE_LINEAR_ACCELERATION)。这是我的OnSensorChanged()方法:

public void onSensorChanged(SensorEvent event) {
    accelX = event.values[0];
    accelY = event.values[1];
    accelZ = event.values[2];

    long currentTime = System.currentTimeMillis() / 1000;

    if(prevTime == 0) prevTime = currentTime;

    long interval = currentTime - prevTime;
    prevTime = currentTime;     

    velX += accelX * interval;
    velY += accelY * interval;
    velZ += accelZ * interval;

    distX += prevVelX + velX * interval;
    distY += prevVelY + velY * interval;
    distZ += prevVelZ + velZ * interval;

    prevAccelX = accelX;        
    prevAccelY = accelY;        
    prevAccelZ = accelZ;

    prevVelX = velX;
    prevVelY = velY;
    prevVelZ = velZ;
}
Run Code Online (Sandbox Code Playgroud)

然而,在任何类型的移动之后,速度都不会返回到 0。除非减速非常突然,否则减速影响不大。这会导致一些非常不准确的距离值。

加速度计也很吵,所以我添加了这个:

accelX = (accelX * accelKFactor) + prevAccelX * (1 - accelKFactor);
accelY = (accelY * accelKFactor) + prevAccelY * (1 - accelKFactor);
accelY = (accelX * accelKFactor) + prevAccelY * (1 - accelKFactor);
Run Code Online (Sandbox Code Playgroud)

其中accelKFactor= .01

我错过了一些明显的东西吗?

我的最终目标只是能够判断设备是否移动了约 10 英尺,但现在,我的数据几乎毫无用处。

编辑:

我发现了部分问题。currentTime很长,但我将系统时间(以毫秒为单位)除以 1000 以获得秒数。所以速度实际上只能每 1 秒更新一次。更改currentTime为 double 有帮助,但并不能完全解决问题。

ble*_*ezy 1

SensorEvent 有一个时间戳字段,它是以纳秒为单位的时间。使用它代替 System.currentTimeMillis()。这是文档中的示例:

private static final float NS2S = 1.0f / 1000000000.0f;
 private float timestamp;

 public void onSensorChanged(SensorEvent event) {
      // This timestep's delta rotation to be multiplied by the current rotation
      // after computing it from the gyro sample data.
      if (timestamp != 0) {
          final float dT = (event.timestamp - timestamp) * NS2S;
Run Code Online (Sandbox Code Playgroud)

以这种方式跟踪位移对初始条件极其敏感,因此这应该有所帮助。

另外,使用 Location.getSpeed() 可能会有更好的运气。如果您无法收到信号,请考虑仅将加速度计用作备用。