基础很简单。在模拟世界中,您使用连续数学,即:
velocity = integrate(acceleration)
distance = integrate(velocity)
在数字世界中更容易使用离散数学,其中积分变为求和:
velocity = sum(acceleration)
distance = sum(velocity)
只要不断地把你读到的所有加速度值加起来,你最终就会得到距离。
最大的问题是,在地球上,由于重力的原因,有一个恒定的向下加速度,大约为 10m/s/s。找出矢量的哪一部分是重力是困难的部分。
顺便说一句,重力是加速度计检测倾斜的方式。所以不管你怎么做,除非你可以独立于加速度计计算倾斜(例如在陀螺仪的帮助下)你的代码将主要是测量倾斜而不是距离。
哈!我刚刚从我上次的声明中意识到很多 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)/t
和a = (v2-v1)/t
)获取导出的距离并进行反向计算,您应该得到加速度读数。