Как обнаружить перемещение iPhone в пространстве с помощью акселерометра?

Я пытаюсь подать заявку, которая обнаружила бы, какую форму Вы сделали со своим iPhone с помощью акселерометра. Как пример, если бы Вы рисуете круг рукой, содержащей iPhone, приложение смогло бы перерисовать его на экране. Это могло также работать с квадратами или еще более сложными формами. Единственным примером приложения, я видел выполнение такой вещи, является AirPaint (http://vimeo.com/2276713), но это не делает, кажется, может сделать это в режиме реального времени.

Моя первая попытка состоит в том, чтобы применить фильтр низких частот на параметры X и Y от акселерометра, и заставить указатель переместиться к этим значениям, пропорционально к размеру экрана. Но это ясно не достаточно, у меня есть очень низкая точность, и если я встряхиваю устройство, оно также заставляет указатель переместиться...

Какие-либо идеи об этом? Вы думаете, что данных акселерометра достаточно, чтобы сделать это? Или я должен рассмотреть использование других данных, таких как компас?

Заранее спасибо!

13
задан Thomas Desert 20 April 2010 в 11:43
поделиться

4 ответа

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

Просто помните, что акселерометры не идеальны и не опрашиваются достаточно быстро. На самом деле резкие движения не так хорошо улавливаются. Но для мягкого рисования в воздухе он должен работать нормально.

2
ответ дан 1 December 2019 в 22:38
поделиться

Проблема в том, что вы не можете дважды интегрировать ускорение, чтобы получить положение. Не зная начального положения и скорости. Помните термин + C, который вы добавляли в школе, когда изучали интеграцию? К тому времени, когда вы доберетесь до позиции, это будет термин CT + K. И это знаменательно. Это до того, как вы подумаете, что получаемые вами данные об ускорении квантованы и усреднены, так что вы фактически не интегрируете фактическое ускорение устройства. Эти ошибки в конечном итоге станут большими, если интегрировать их дважды.

Внимательно посмотрите демонстрацию AirPaint, и вы увидите, что именно это и происходит: визуализируемые формы значительно отличаются от перемещаемых.

Даже устройства с определенным датчиком положения и скорости (например, Wiimote) не могут распознавать жесты. Это сложная проблема, которую люди платят хорошие деньги (например, таким компаниям, как AILive), чтобы решить ее.

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

Будет намного сложнее отличить круг от квадрата.

7
ответ дан 1 December 2019 в 22:38
поделиться

Хорошо, я нашел кое-что, что, похоже, работает, но у меня все еще есть проблемы. Вот как я продолжаю (признавая, что устройство удерживается вертикально):

1 - У меня есть x по умолчанию, y и z значения.
2 - Я извлекаю вектор гравитации из этих данных с помощью фильтра нижних частот.
3 - Я вычитаю нормализованный вектор гравитации из каждых x, y и z и получаю ускорение движения.
4 - Затем я интегрирую это значение ускорения по времени, чтобы получить скорость.
5 - Я снова интегрирую эту скорость по времени и нахожу положение.

Весь приведенный ниже код находится в акселерометре: didAccelerate: делегат моего контроллера. Я пытаюсь заставить мяч двигаться в соответствии с найденной мной позицией. Вот мой код:

NSTimeInterval interval = 0;
NSDate *now = [NSDate date];
if (previousDate != nil)
{
    interval = [now timeIntervalSinceDate:previousDate];
}
previousDate = now;

//Isolating gravity vector
gravity.x = currentAcceleration.x * kFileringFactor + gravity.x * (1.0 - kFileringFactor);
gravity.y = currentAcceleration.y * kFileringFactor + gravity.y * (1.0 - kFileringFactor);
gravity.z = currentAcceleration.z * kFileringFactor + gravity.z * (1.0 - kFileringFactor);
float gravityNorm = sqrt(gravity.x * gravity.x + gravity.y * gravity.y + gravity.z * gravity.z);

//Removing gravity vector from initial acceleration
filteredAcceleration.x = acceleration.x - gravity.x / gravityNorm;
filteredAcceleration.y = acceleration.y - gravity.y / gravityNorm;
filteredAcceleration.z = acceleration.z - gravity.z / gravityNorm;

//Calculating velocity related to time interval
velocity.x = velocity.x + filteredAcceleration.x * interval;
velocity.y = velocity.y + filteredAcceleration.y * interval;
velocity.z = velocity.z + filteredAcceleration.z * interval;

//Finding position
position.x = position.x + velocity.x * interval * 160;
position.y = position.y + velocity.y * interval * 230;

Если я выполню это, я получу неплохие значения, то есть я могу видеть, как ускорение принимает положительные или отрицательные значения в зависимости от моих движений. Но когда я пытаюсь применить это положение к своему мячу вид, я вижу, что он движется, но со склонностью идти больше в одном направлении, чем в другом. Это означает, например, что если я нарисую круги с помощью своего устройства, я увижу шар, описывающий кривые в верхнем левом углу экрана. Что-то вроде этого: http: //img685.imageshack .us / i / capturecran20100422133.png /

Есть ли у вас какие-нибудь идеи о том, что происходит? Заранее спасибо!

10
ответ дан 1 December 2019 в 22:38
поделиться

Похоже, что вы нормализуете вектор гравитации перед вычитанием с мгновенным ускорением. Это сохранит относительную ориентацию, но удалит любой относительный масштаб. Последнее устройство, которое я тестировал (по общему признанию, не Idevice), вернуло гравитацию примерно на -9.8, что, вероятно, калибруется в м/с. Предполагая отсутствие других ускорений, если бы вы нормализовали это, а затем вычли его из отфильтрованного прохода, то в итоге получили бы текущее ускорение -8.8 вместо 0.0f;

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

Также стоит помнить о необходимости учитывать ориентацию устройства.

2
ответ дан 1 December 2019 в 22:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: