Получение смещения из данных акселерометра с Core Motion
Я разрабатываю приложение с дополненной реальностью, которое (на данный момент) хочет отобразить простой куб поверх поверхности и иметь возможность перемещаться в пространстве (как вращающемся, так и смещающемся), чтобы смотреть на куб под разными углами. Проблема калибровки камеры здесь не применима, так как я прошу пользователя поместить iPhone на поверхность, на которую он хочет поместить куб, а затем нажать кнопку, чтобы сбросить ориентацию. Узнать вращение камеры очень просто с помощью гироскопа и Core Motion. Я делаю это так:
if (referenceAttitude != nil) {
[attitude multiplyByInverseOfAttitude:referenceAttitude];
}
CMRotationMatrix mat = attitude.rotationMatrix;
GLfloat rotMat[] = {
mat.m11, mat.m21, mat.m31, 0,
mat.m12, mat.m22, mat.m32, 0,
mat.m13, mat.m23, mat.m33, 0,
0, 0, 0, 1
};
glMultMatrixf(rotMat);
Это работает очень хорошо. В любом случае, возникает больше проблем, когда я пытаюсь найти смещение в пространстве во время ускорения. Пример Apple Teapot с Core Motion просто добавляет значения x, y и z вектора ускорения к вектору положения. Это (помимо небольшого смысла) приводит к возврату объекта в исходное положение после ускорения. (Так как ускорение переходит от положительного к отрицательному или наоборот). Они сделали это так:
translation.x += userAcceleration.x;
translation.y += userAcceleration.y;
translation.z += userAcceleration.z;
Что я должен сделать, чтобы узнать смещение от ускорения в какой-то момент? (с известной разницей во времени). Глядя на некоторые другие ответы, мне кажется, что мне нужно дважды интегрировать, чтобы получить скорость от ускорения, а затем положение от скорости. Но в коде нет никакого примера, и я не думаю, что это действительно необходимо. Кроме того, существует проблема, заключающаяся в том, что, когда iPhone все еще находится в плоскости, значения акселерометра не равны нулю (я думаю, что есть некоторый шум). Сколько я должен фильтровать эти значения? Я должен отфильтровать их вообще?
4 ответа
Круто, есть люди, которые борются с той же проблемой, так что стоит потратить некоторое время:-)
Я согласен с утверждением Вестсайдера, так как я провел несколько недель, экспериментируя с различными подходами, и в итоге получил плохие результаты. Я уверен, что не будет приемлемого решения ни для больших расстояний, ни для медленных движений, длящихся более 1 или 2 секунд. Если вы можете жить с некоторыми ограничениями, такими как небольшие расстояния (< 10 см) и заданная минимальная скорость для ваших движений, то я считаю, что может быть шанс найти решение - вообще никаких гарантий. Если это так, то вам понадобится довольно трудное время для исследований и много разочарований, но если вы их получите, это будет очень и очень круто:-) Возможно, вы найдете эти советы полезными:
Прежде всего, чтобы упростить задачу, просто посмотрите на одну ось, например, на x, но рассмотрите как левый (-x), так и правый (+x), чтобы представить ситуацию.
Да, вы правы, вы должны интегрироваться дважды, чтобы получить позицию как функцию времени. А для дальнейшей обработки вы должны сохранить результат первой интеграции (== скорость), потому что он понадобится вам на более позднем этапе для оптимизации. Делайте это очень осторожно, потому что каждая крошечная ошибка приведет к огромным ошибкам через короткий промежуток времени.
Всегда имейте в виду, что даже очень маленькая ошибка (например, <0,1%) будет быстро расти после выполнения интеграции дважды. Ситуация станет еще хуже через одну секунду, если вы настроите акселерометр, скажем, с частотой 50 Гц, то есть обработано 50 тиков, и незначительная ошибка пренебрегает "истинным" значением. Я настоятельно рекомендую не полагаться на трапециевидное правило, а использовать хотя бы формулу Симпсона или Ньютона-Котса более высокой степени.
Если вам это удалось, вам придется следить за настройкой правильной фильтрации низких частот. Я не могу дать общую оценку, но, как правило, эксперименты с коэффициентами фильтрации между 0,2 и 0,8 будут хорошей отправной точкой. Правильное значение зависит от бизнес-ситуации, в которой вы нуждаетесь, например, какая игра, как быстро реагировать на события,...
Теперь у вас будет решение, которое работает довольно хорошо при определенных обстоятельствах и в течение короткого периода времени. Но через несколько секунд вы столкнетесь с неприятностями, потому что ваш объект уходит. Теперь вы войдете в сложную часть решения, с которой мне не удалось справиться в течение заданного промежутка времени:-(
Одним из многообещающих подходов является введение того, что я называю "синтетическими силами" или "виртуальными силами". Это некоторая стратегия реагирования на несколько плохих ситуаций, приводящих к смещению объекта, хотя устройство остается неподвижным (нет динамика, я имею в виду без движения) в ваших руках. Наиболее тревожной является скорость выше 0 без какого-либо ускорения. Это неизбежный результат распространения ошибок и может быть обработан путем искусственного замедления, что означает введение виртуального замедления, даже если нет реального аналога. Очень упрощенный пример:
if (vX > 0 && lastAccelerationXTimeStamp > 0.3sec) {
vX *= 0.9;
}
`
Вам понадобится комбинация таких условий, чтобы приручить зверя. Требуется много попыток и ошибок, чтобы почувствовать правильный путь, и это будет трудной частью проблемы.
Если вам когда-нибудь удалось взломать код, пожалуйста, дайте мне знать, мне очень интересно узнать, возможно ли это вообще или нет:-)
Ура Кей
Когда iPhone 4 был совсем новым, я потратил много-много часов, пытаясь получить точное смещение с помощью акселерометров и гироскопа. Не должно быть особой озабоченности по поводу постепенного смещения, поскольку устройство должно перемещаться не более пары метров, а сбор данных обычно длится не более нескольких минут. Мы испробовали всевозможные подходы и даже получили помощь от нескольких инженеров Apple. В конце концов, казалось, что гироскоп не справился с поставленной задачей. Это было хорошо для трехмерной ориентации, но это было... опять же, по словам очень знающих инженеров.
Я хотел бы услышать, что кто-то противоречит этому - потому что приложение никогда не получалось так, как мы надеялись, и т. Д.
Я также пытаюсь получить смещение на iPhone. Вместо использования интегрирования я использовал базовую физическую формулу d = .5a * t^2, предполагая начальную скорость 0 (не похоже, что вы можете принять начальную скорость 0). Пока что, похоже, все работает хорошо.
Моя проблема в том, что я использую deviceMotion. И значения не верны. deviceMotion.gravity читать около 0. Есть идеи? - OK Исправлено, по-видимому, deviceMotion.gravity имеет значения a x, y и z. Если вы не указываете, что вы хотите, вы получите обратно х (который должен быть около 0).
Найти этот вопрос два года спустя, я просто нахожу проект AR на iOS 6 с именем docset, который обеспечивает непосредственный захват и вычисление смещения с помощью Gyroscope, иначе CoreMotion.Framework.
Я только начинаю опираться на код.
продолжение следует...