基本は簡単です。アナログの世界では、次のような連続数学を使用します。
velocity = integrate(acceleration)
distance = integrate(velocity)
デジタルの世界ではさらに簡単です。積分が総和になる離散数学を使用します。
velocity = sum(acceleration)
distance = sum(velocity)
読み取った加速度のすべての値を合計し続けるだけで、最終的に距離が得られます。
これに伴う大きな問題は、地球上で重力のために約10m / s/sの一定の加速度が下向きにあることです。ベクトルのどの部分が重力であるかを理解するのは難しい部分です。
ところで、重力は加速度計が傾きを検出する方法です。したがって、どのように実行しても、加速度計とは独立して傾斜を計算できない限り(たとえば、ジャイロを使用して)、コードはほとんどの場合、距離ではなく傾斜を測定します。
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と同期する必要があります。
第二に、加速度計は動きではなく力を測定します。あらゆる種類の力が測定されます。重力について触れましたが、テーブルとの摩擦によって引き起こされる隆起も測定します。心拍や呼吸によって手がわずかに揺れるなど、脈拍も測定されます。良いニュースは、長期的にはこれらすべての力が平均化され、公式は依然として正しいということです。しかし、短期的には、それはあなたの読書が騒々しくなることを意味します。ワイナーフィルターやカルマンフィルターなどを使用してこのノイズを最小限に抑えるために、人々が思いついたトリックはたくさんあります。
第三に、お気づきかもしれませんが、加速度計の読み取り値は一定ではありません。読むたびに値が異なるという意味ではありませんが、それは明らかですが、読み取りの合間に値も変化します。見逃した値はすべて精度に影響するため、できるだけ頻繁に値を読み取ることが重要です。さて、良いニュースは、長期的には、値の欠落によって引き起こされるこれらのエラーはすべて平均化されるはずです。これらのエラーは主にぎくしゃくした動きや振動によって引き起こされ、私たちの式はまだ正しいからです。しかし、これは短期的にはシステムにノイズを追加することを意味します。カルマンフィルターのような優れた予測フィルターを使用する場合、これを説明できるはずですが、弱いフィルターには何らかの助けが必要な場合があります。これを行う1つの方法は、各加速度の読み取り値を前の読み取り値と平均化することです。
これよりも高い精度は、慣性計測装置(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
)のように逆の計算を行うと、加速度の読み取り値が返されるはずです。