Основы просты.В аналоговом мире вы используете непрерывную математику:
velocity = integrate(acceleration)
distance = integrate(velocity)
, а в цифровом мире это еще проще, вы используете дискретную математику, где интеграция становится суммированием:
velocity = sum(acceleration)
distance = sum(velocity)
Просто продолжайтескладывая все значения ускорения, которые вы прочитали, вы в конечном итоге получаете расстояние.
Большая проблема с этим заключается в том, что на планете Земля происходит постоянное ускорение вниз примерно до 10 м / с / с из-за силы тяжести.Выяснить, какая часть вашего вектора является гравитацией, является сложной частью.
Кстати, гравитация - это то, как акселерометры могут определять наклон.Поэтому, как бы вы это ни делали, если вы не можете рассчитать наклон независимо от акселерометров (например, с помощью гироскопов), ваш код будет в основном измерять наклон вместо расстояния.
HA!Я только что понял из своего последнего заявления, что многие приложения для iPhone не будут работать в космосе: -P
Дополнительный ответ:
На основании «комментария», опубликованного ОП(как ответ ниже или выше этого ответа) похоже, что мне нужно дать дальнейшие объяснения.Реализация действительно очень проста, так что люди, не знакомые с математикой, подумают, что она должна быть более сложной, чем эта.Псевдокод имеет следующий вид:
// 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, чтобы исправить этот дрейф.
Во-вторых, акселерометр измеряет силу, а не движение.Любая сила измеряется.Я упомянул гравитацию, но он также измеряет удары, вызванные трением о стол, ваш пульс, как ваше сердцебиение, и дыхание заставляет вашу руку слегка дрожать, что угодно.Хорошая новость заключается в том, что в конечном итоге все эти силы будут усреднены, и формула все еще будет верна.Но в краткосрочной перспективе это означает, что ваше чтение будет шумным.Есть много хитростей, которые люди придумали, чтобы минимизировать этот шум, используя такие вещи, как фильтры Вейнера и Калмана.
В-третьих, как вы могли заметить, показания акселерометра не постоянны.Я не просто имею в виду, что значения различаются каждый раз, когда вы их читаете, это очевидно, но это также меняет значения между чтениями.Каждое пропущенное нами значение влияет на нашу точность, поэтому важно читать значения как можно чаще.Хорошая новость заключается в том, что в конечном итоге все эти ошибки, вызванные отсутствием значений, должны усредняться, поскольку они в основном вызваны резкими движениями или вибрациями, и наша формула снова остается верной.Но это снова означает, что в краткосрочной перспективе это добавляет шум в нашу систему.Если вы используете хороший проникающий фильтр, такой как фильтр Калмана, он должен быть в состоянии учесть это, но более слабые фильтры могут нуждаться в некоторой помощи.Один из способов сделать это - усреднить каждое ускоренное чтение с предыдущим чтением.Обратите внимание, что это должно быть предыдущее «реальное» чтение, а не предыдущее усредненное чтение.
Больше точности, чем это, относится к области единиц измерения инерции (IMU) и инерциального наведения, а также к множеству довольно волосатых векторов иМатематическая математика.Хотя есть проекты с открытым исходным кодом, которые делают это (менее 10 лет назад эти вещи носили исключительно военный характер, поскольку, как вы знаете, их используют подводные лодки и крылатые ракеты).
В этих статьях Sparkfun есть несколько хороших ссылок внизу и некоторый ссылочный код:
http://www.sparkfun.com/products/9268
http://www.sparkfun.com/products/8454
Надеюсь, все это поможет. И если у кого-то есть ссылки на какую-либо статью, которая может помочь, пожалуйста, прокомментируйте.
* * Пример тысячи сорок четыре * * 1045
Конечно, если вам нужны реальные единицы, вам нужно масштабировать частоту дискретизации. Например, ускорение со скоростью 9 м / с / с в течение 80 мс означает, что ваша скорость равна (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
), вы должны получить показания ускорения обратно.