Как обнаружить движение iPhone в космосе с помощью акселерометра? - PullRequest
13 голосов
/ 20 апреля 2010

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

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

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

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

Ответы [ 4 ]

10 голосов
/ 22 апреля 2010

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

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/capturedcran20100422133.png/

У вас есть идеи о том, что происходит?Заранее спасибо!

7 голосов
/ 24 апреля 2010

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

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

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

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

Узнать разницу между кругом и квадратом будет гораздо сложнее.

2 голосов
/ 07 июля 2010

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

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

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

2 голосов
/ 20 апреля 2010

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

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

...