Получение смещения данных акселерометра с помощью Core Motion

Я разрабатываю приложение дополненной реальности, которое (на данный момент) хочет отобразить простой куб поверх поверхности и сможет перемещаться в пространстве (как вращающемся, так и перемещающемся), чтобы смотреть на куб во всех разных углы. Проблема калибровки камеры здесь не применяется, так как я прошу пользователя поместить iPhone на поверхность, на которую он хочет поместить куб, а затем нажать кнопку на reset. Чтобы узнать, что вращение камеры очень просто с помощью гироскопа и основного движения. Я делаю это так:

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 все еще находится на плоскости, значения акселерометра не равны нулю (есть некоторые шумы, которые я думаю). Сколько нужно фильтровать эти значения? Должен ли я фильтровать их вообще?

Ответ 1

Прохладно, есть люди, борющиеся с одной и той же проблемой, поэтому стоит потратить некоторое время: -)

Я согласен с выражением westsider, поскольку я провел несколько недель экспериментов с разными подходами и оказался плохим. Я уверен, что не будет приемлемого решения для больших расстояний или медленных движений, продолжающихся более 1 или 2 секунд. Если вы можете жить с некоторыми ограничениями, такими как небольшие расстояния (< 10 см) и заданная минимальная скорость для ваших движений, я полагаю, что есть возможность найти решение - никакой гарантии вообще. Если это так, вам будет очень сложно провести исследование и много разочарований, но если вы его получите, это будет очень круто:-) Возможно, вы найдете эти подсказки полезными:

Прежде всего, попробуйте просто взглянуть на одну ось, например x, но рассмотрите как левые (-x), так и правые (+ x), чтобы иметь представимую ситуацию.

Да, вы правы, вам нужно дважды интегрировать, чтобы получить позицию как функцию времени. И для дальнейшей обработки вы должны сохранить первый результат интеграции (== velocity), потому что вам понадобится его на более позднем этапе для оптимизации. Сделайте это очень осторожно, потому что каждая крошечная ошибка приведет к огромным ошибкам через короткий промежуток времени.

Всегда помните, что даже небольшая ошибка (например, < 0,1%) будет быстро расти после двойной интеграции. Ситуация станет еще хуже после одной секунды, если вы сконфигурируете акселерометр, скажем, 50 Гц, то есть 50 тиков обрабатываются, а крошечная небрежная ошибка будет превышать "истинное" значение. Я бы настоятельно рекомендовал не полагаться на трапецеидальное правило, но использовать по крайней мере Симпсона или формулу Ньютона-Котса более высокой степени.

Если вам это удалось, вам нужно будет следить за настройкой правильной фильтрации нижних частот. Я не могу дать общее значение, но, как правило, эксперимент с фильтрационными факторами между 0,2 и 0,8 будет хорошей отправной точкой. Правильное значение зависит от вашего бизнес-кейса, например, какой игры, как быстро реагировать на события,...

Теперь у вас будет решение, которое работает довольно хорошо при определенных обстоятельствах и в течение короткого периода времени. Но чем через несколько секунд у вас возникнут проблемы, потому что ваш объект дрейфует. Теперь вы войдете в сложную часть решения, с которой я не смог обработать в конечном итоге в пределах данного временного диапазона: - (

Одним из перспективных подходов является введение того, что я называю "синтетические силы" или "виртуальные силы". Это некоторая стратегия реагирования на несколько плохих ситуаций, вызывающих уклонение объекта, хотя устройство остается фиксированным ( "нет родного говорящего, я имею в виду без движения" ) в ваших руках. Наиболее тревожным является скорость, превышающая 0 без какого-либо ускорения. Это неизбежный результат распространения ошибки и может быть обработан искусственным замедлением, что означает введение виртуального замедления, даже если нет реального аналога. Очень упрощенный пример:

if (vX > 0 && lastAccelerationXTimeStamp > 0.3sec) {

     vX *= 0.9;
}

`

Вам понадобится сочетание таких условий, чтобы приручить зверя. Требуется много попыток и ошибок, чтобы получить представление о правильном пути, и это будет трудной частью проблемы.

Если вам когда-нибудь удалось взломать код, пожалуйста, сообщите мне, мне очень любопытно узнать, возможно ли вообще или нет: -)

Cheers Kay

Ответ 2

Когда iPhone 4 был очень новым, я потратил много и много часов, пытаясь добиться точного перемещения с помощью акселерометров и гироскопа. Не должно было быть большой озабоченности по поводу инкрементного дрейфа, так как устройству нужно было всего лишь перемещаться на пару метров максимум, а сбор данных обычно длился не более нескольких минут. Мы пробовали всевозможные подходы и даже получали помощь от нескольких инженеров Apple. В конечном счете, казалось, что гироскоп не справился с задачей. Это было хорошо для 3D-ориентации, но это было... опять же, по мнению очень знающих инженеров.

Мне бы хотелось услышать, что кто-то противоречит этому, потому что приложение никогда не получилось так, как мы надеялись, и т.д.

Ответ 3

Я также пытаюсь получить перемещение на iPhone. Вместо использования интеграции я использовал основную физическую формулу d =.5a * t ^ 2, предполагая начальную скорость 0 (не звучит так, как вы можете предположить начальную скорость 0). Пока это работает очень хорошо.

Моя проблема в том, что я использую deviceMotion.and значения неправильные. deviceMotion.gravity читать около 0. Любые идеи? - ОК Исправлено, очевидно, deviceMotion.gravity имеет значения x, y и z. Если вы не указали, что хотите, вы вернетесь x (который должен быть около 0).

Ответ 4

Найдите этот вопрос два года спустя, Я просто нахожу проект AR на docset iOS 6 с именем pARk, он обеспечивает захват и вычисление смещения смещения используя гироскоп, а также CoreMotion.Framework.

Я только начинаю отказываться от кода.

чтобы продолжить...