2011-05-22 126 views
10

仅使用内置在加速计中的手机(Android),我将如何去寻找其速度?如何仅使用加速度计查找速度?

我一直在修补这个数学,但无论我提出的函数往往会导致速度的指数增长。我的工作原理是在应用程序启动时,手机处于停滞状态。这肯定会使速度(至少粗略地)成为可能。

我在物理学和数学方面也有不错的背景,所以我不应该对这里的任何概念有任何困难。

我应该怎么做?

+0

@Ignacio什么?恒定加速度意味着速度线性增加。 – Imran 2011-05-22 02:40:52

+0

你有任何工作解决方案,你可以指向我或分享代码。 – VenomVendor 2013-03-17 15:44:41

+0

嗨,你有没有考虑过关闭这个问题? – 2016-05-09 19:28:21

回答

1

v =积分(a)?

但是总的来说,我觉得在加速度计的不准确性将使这相当强悍

+0

取决于不准确的类型。你可以校准线性误差,不是吗? – 2013-06-11 05:11:53

-2

如果手机是在standstil,你有零加速度,所以你的速度是0。也许你应该找到位置数据GPS并获取关联的时间样本并计算随时间推移的速度距离。

+0

是的,在应用程序启动时,速度为0“。我从这个角度对它进行校准。 – 2011-05-22 02:07:52

+0

“静止不动”实际上应该很容易察觉。如果来自加速度计的输入(使用TYPE_LINEAR_ACCELERATION)非常稳定,则手机可能未被处理。 – 2016-06-14 15:24:10

7

首先,您必须从加速计数据中移除因重力引起的加速度。那么这只是一个整合加速度来获得速度的问题。不要忘记,加速度和速度是正确的矢量,而不是标量,并且您还必须跟踪空间中手机的旋转,以正确确定加速度矢量相对于计算速度矢量的方向。

+0

你可以从编码的角度来解释或指向一个链接,我可以得到这方面的更多细节。 – VenomVendor 2013-03-17 15:43:00

+3

TYPE_LINEAR_ACCELERATION传感器会为您提供经过滤的重力加速度,所以很好。 TYPE_ROTATION_VECTOR将为您提供设备方向作为四元数,它可以很容易地转换为3x3旋转矩阵。在每个时间片上,使用旋转矩阵将加速度转换为3维空间中的矢量。积分随着时间的推移获得加速度(另一个向量)并将* *整合到相对于开始位置的位置。 (这一切都假定初始速度为零)。然后去酒吧喝一杯,因为这对廉价的传感器来说都是无望的。 – 2016-06-14 15:13:22

7

这将取决于加速度和持续时间。一个温和的,长时间的加速度可以测量,但是加速度的任何突然增加,然后是一个恒定的速度,将使您的测量非常困难,并容易出错。

假设加速度恒定,公式非常简单:a =(V1-V0)/ t。因此,知道时间和加速度,并假设V0 = 0,则V1 = a * t在更现实的世界中,您可能不会有恒定的加速度,因此您应该计算每个测量的Delta V ,并添加所有速度变化以获得最终速度。始终认为你不会有连续的加速度数据,所以这是最可行的方法(即实数据与积分数学理论)。

无论如何,即使在最好的情况下,您也会得到非常高的误差,所以我不建议这种方法适用于任何真正依赖实际速度的应用程序。

+5

如果没有人注意到,V1 = a * t! – erdomester 2011-09-13 20:58:29

2

积分加速度以获得速度是一个不稳定的问题,你的错误会在几秒钟左右发生分歧。手机加速度计也不是很准确,这没有帮助,有些手机不能很容易地区分倾斜和平移,在这种情况下,您确实遇到了麻烦。

2

手机中的加速度计对于这样的任务几乎没有用处。您需要非常精确的加速度计,漂移极低 - 这远远超出了您在手机中所能找到的范围。充其量,你可能会在几秒钟内得到有用的结果,或者如果运气好一两分钟后结果变得毫无意义,那么结果就会很好。

此外,您需要有一个三轴陀螺仪,您可以使用它来将速度整合到正确的方向。有些手机具有陀螺仪,但就漂移和精度而言,它们甚至比加速度计更差。

一种可能有用的应用程序虽然是使用加速度计与陀螺仪或磁罗盘结合,以填补在用于从所述GPS缺失数据。每次GPS给出了一个很好的修复方法,就会重置位置,速度和方向的初始条件,加速度计将提供数据直到下一次有效的GPS修复。

+0

假设我想获得控制游戏的倾斜信息。在这种情况下,我将能够做出很多假设。例如,我可以假设用户以某种方式持有该设备。那么,是否有可能以突发变化突出并变得对输入有用的方式来平滑数据? – 2013-04-06 23:27:49

4

没有别的可以做,但与合理的参数在上述所有伟大的答案提出的同意,但是如果你是务实型和我一样,我需要拿出的作品在某种程度上的解决方案。

我遭遇了类似的问题和你,我决定把我自己的解决方案没有发现任何上线之后。我只需要一个简单的“倾斜”输入来控制游戏,所以这个解决方案可能不适用于更复杂的需求,但是我决定分享它以防其他人寻找类似的东西。

注:I have pasted my entire code here,并且它是免费的,可以用于任何目的。

基本上我在我的代码做的是寻找加速度传感器。如果没有找到,倾斜反馈将被禁用。如果加速度传感器存在,我寻找磁场传感器,如果存在,我通过结合加速度计和磁场数据得到我的倾斜角度是推荐的方式。

public TiltSensor(Context c) { 
    man = (SensorManager) c.getSystemService(Context.SENSOR_SERVICE); 
    mag_sensor = man.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); 
    acc_sensor = man.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
    has_mag = man.registerListener(this, mag_sensor, delay); 
    has_acc = man.registerListener(this, acc_sensor, delay); 
    if (has_acc) { 
     tiltAvailble = true; 
     if (has_mag) { 
      Log.d("TiltCalc", "Using accelerometer + compass."); 
     } 
     else { 
      Log.d("TiltCalc", "Using only accelerometer."); 
     } 
    } 
    else { 
     tiltAvailble = false; 
     Log.d("TiltCalc", "No acceptable hardware found, tilt not available."); 
     //No use in having listeners registered 
     pause(); 
    } 
} 

然而,如果只有加速度传感器存在,我回落到累加的加速度,被连续衰减(乘以0.99)以除去任何漂移。对于我的简单倾斜需求,这很有用。

@Override 
public void onSensorChanged(SensorEvent e) { 
    final float[] vals = e.values; 
    final int type = e.sensor.getType(); 
    switch (type) { 
     case (Sensor.TYPE_ACCELEROMETER): { 
      needsRecalc = true; 
      if (!has_mag) { 
       System.arraycopy(accelerometer, 0, old_acc, 0, 3); 
      } 
      System.arraycopy(vals, 0, accelerometer, 0, 3); 
      if (!has_mag) { 
       for (int i = 0; i < 3; i++) { 
        //Accumulate changes 
        final float sensitivity = 0.08f; 
        dampened_acc[i] += (accelerometer[i] - old_acc[i]) * sensitivity; 
        //Even out drift over time 
        dampened_acc[i] *= 0.99; 
       } 
      } 
     } 
      break; 
     case (Sensor.TYPE_MAGNETIC_FIELD): { 
      needsRecalc = true; 
      System.arraycopy(vals, 0, magnetic_field, 0, 3); 
     } 
      break; 
    } 
} 

最后,我只会重复这可能是不以任何方式“正确”的,它只是可以作为一个简单的输入到游戏中。要使用此代码,我只需执行类似以下操作(是的魔术常数是不好的mkay):

Ship ship = mShipLayer.getShip(); 
mTiltSensor.getTilt(vals); 
float deltaY = -vals[1] * 2;//1 is the index of the axis we are after 
float offset = ((deltaY - (deltaY/1.5f))); 
if (null != ship) { 
    ship.setOffset(offset); 
} 

Enjoi!

2

重力会破坏你所有的测量。处于静止状态的手机正在经历一个很高的持续向上(是,向上)加速。加速度计无法区分加速度和重力(技术上它们是相同的),所以在几秒钟后它会达到极高的速度。 如果你永远不会倾斜你的加速度计,那么你可以简单地从z轴减去常量重力拉(或任一轴向上/向下),但那是不太可能的。

基本上,你必须使用陀螺仪/ magnetometor的一个复杂的系统和加速计来计算重力方向精确然后减去加速度。

+0

传感器融合可以为您过滤。只需使用TYPE_LINEAR_ACCELERATION传感器。 – 2016-06-14 15:22:49