如何根据手机加速度计算距离

时间:2010-12-01 21:08:32

标签: android distance formula acceleration

我想使用Android手机构建类似的内容:http://www.youtube.com/watch?v=WOt9mb5QqRs

我已经构建了一个通过套接字发送传感器信息的应用程序(仍然在为android寻找一个好的websocket实现)。我打算使用该信息与Web应用程序进行交互,例如,我可以根据手机的移动来移动图像。 问题是我试图根据加速度计数据计算距离,但结果非常糟糕。我想知道是否有人可以用正确的方程帮助我,但首先,是否可以这样做?

直到现在我正在使用以下等式:

velocity = acceleration * time;

distance = velocity * time + (acceleration * time^2) / 2;

然后我根据显示器屏幕分辨率将距离从米/秒转换为像素。

每次我收到传感器数据时都会在浏览器中使用javascript计算,每隔约80毫秒。

2 个答案:

答案 0 :(得分:24)

基础知识很简单。在模拟世界中,您使用连续数学:

velocity = integrate(acceleration)
distance = integrate(velocity)

在数字世界中,它更容易,你使用离散数学,其中积分变为求和:

velocity = sum(acceleration)
distance = sum(velocity)

只需将所有加速度值加起来,最终得到距离。

这个问题的一个重要问题是,在地球上,由于重力作用,恒定的加速度大约为10m / s / s。弄清楚你的矢量的哪个部分是重力是困难的部分。

BTW,重力是加速度计可以检测倾斜的方式。所以无论如何,除非你可以独立于加速度计计算倾斜度(例如借助陀螺仪),否则你的代码主要是测量倾斜而不是距离。


HA!我刚才从上次发表的声明中了解到,许多iPhone应用程序无法在太空中运行:-P


补充答案:

基于OP发布的“评论”(作为低于或高于此答案的答案),我看起来需要提供进一步的解释。实现非常简单,不熟悉数学的人会认为它必须比这更复杂。伪代码如下:

// Set distance to zero at start-up:
var distance_X = 0
var velocity_X = 0

function update_acceleration_X (acceleration_X) {
    velocity_X = velocity_X + acceleration_X
    distance_X = distance_X + velocity_X
}

// To use the distance value just read the distance_X variable:
function get_distance_X_and_reset () {
    x = distance_X
    distance_X = 0
    return x
}

除非将距离变量重置为零,否则始终从软件首次启动的位置开始测量距离。必须不断地读取加速度计(优选地以加速度计自身测量力的速率)并且相应地更新速度和距离的值。当你想知道起点的距离时,只需读取距离变量。

有几件事:任何倾斜量,无论多么轻微,都会增加漂移。这意味着除非一直跟踪倾斜角度,否则在一个方向或另一个方向上总是会有少量的恒定加速度。即使是配备高精度加速度计和陀螺仪的核潜艇,因为GPS不能在水下工作,也需要周期性地与GPS同步并校正这种漂移。

其次,加速度计测量力,而不是运动。测量任何类型的力。我提到了重力,但它也测量了由于与桌子摩擦引起的颠簸,你的脉搏作为你的心跳和呼吸导致你的手稍微摇动,任何东西。好消息是,从长远来看,所有这些力量都会平均,而且公式仍然是正确的。但从短期来看,这意味着你的阅读会很吵。人们已经提出了许多技巧来使用Weiner和Kalman滤波器来减少这种噪声。

第三,正如您可能已经注意到的那样,加速度计读数不是恒定的。我不仅仅意味着每次读取它们时值都不同,这很明显,但它也会改变读数之间的值。我们错过的每一个值都会影响我们的准确性,因此尽可能经常读取值非常重要。现在,好消息是,从长远来看,由缺失值引起的所有这些错误应该是平均值,因为它们主要是由不稳定的运动或振动引起的,我们的公式仍然是正确的。但它再次意味着在短期内这会给我们的系统增加噪音。如果您使用像卡尔曼滤波器这样的好的过滤器,那么它应该能够解决这个问题,但较弱的滤波器可能需要一些帮助。这样做的一种方法是将每个加速度读数与先前读数平均。请注意,它必须是之前的“真实”读数,而不是之前的平均读数。

比这更精确地进入惯性测量单位(IMU)和惯性制导领域以及许多相当毛茸茸的矢量和矩阵数学。虽然有不同的开源项目(不到10年前,这些东西是严格的军事,你知道,潜艇和巡航导弹使用它们)。

这些Sparkfun文章底部有一些很好的链接和一些参考代码:

http://www.sparkfun.com/products/9268

http://www.sparkfun.com/products/8454

希望这一切都有所帮助。如果其他人有任何可能有帮助的文章的链接,请发表评论。


实施例

当然,如果你想要真正的单位,你需要缩放采样率。例如,以9m / s / s加速80ms意味着您的速度为(9m/s/s * 0.08s) = 0.72m/s。假设您不关心单位,则简化上述伪代码。最终值仍然将距离表示为数字,只是该数字与任何现实世界的测量单位几乎没有关系。您可以在校准到像素值的末尾应用缩放功能。无论如何,这里有一个真实世界单位的例子,以澄清正在发生的事情:

given the following acceleration readings:
9m/s/s
3m/s/s
0m/s/s
0m/s/s
0m/s/s
-5m/s/s
-7m/s/s

assuming an 80ms sample rate
we can derive the following velocities:
0.72m/s (what you get from accelerating 9m/s for 80ms)
0.96m/s
0.96m/s
0.96m/s
0.96m/s
0.56m/s
0m/s

from that we can derive the following distances:
57.6mm (what you get from moving at 0.72m/s for 80ms)
134.4mm
211.2mm
288mm
364.8mm
409.6mm

现在,如果您按照通常的距离(v = (s2-s1)/ta = (v2-v1)/t)获取导出的距离并进行反向计算,则应该获得加速度读数。

答案 1 :(得分:0)

最大速度=时间*加速度 平均速度=最大速度/ 2.
行驶距离=平均速度*时间。


行驶距离=时间*时间*加速度/ 2.