2012-02-02 2 views
5

Я пробовал этот проект на Android и ios с небольшим успехом. Есть хороший шанс, что этот материал просто над моей головой. Однако я решил, что поставил бы свой вопрос здесь в качестве последнего усилия.
Я пытаюсь выяснить, когда устройство повернуто или перевернуто. Мое приложение должно знать, когда он сделал 180, 360 или если устройство было перевернуто вертикально.
В попытке понять, как его предполагают работать, я попытался загрузить два примера проектов: AccelerometerGraph и CoreMotionTeapot. С этими и смесью других вещей, я понял, что я пытался это:датчик движения, считывание оборотов

motionManager = [[CMMotionManager alloc] init]; 
motionManager.accelerometerUpdateInterval = 0.01; 
motionManager.deviceMotionUpdateInterval = 0.01; 
[motionManager startDeviceMotionUpdates]; 

if (motionManager.gyroAvailable) { 
    motionManager.gyroUpdateInterval = 1.0/60.0; 
     motionManager.deviceMotionUpdateInterval = 0.01; 
    [motionManager startGyroUpdatesToQueue:[NSOperationQueue currentQueue] 
           withHandler: ^(CMGyroData *gyroData, NSError *error) 
    { 
     CMRotationRate rotate = gyroData.rotationRate; 
     NSLog(@"rotation rate = [%f, %f, %f]", rotate.x, rotate.y, rotate.z); 
    }]; 
} else { 
    NSLog(@"No gyroscope on device."); 
} 

Но я не знаю, как собрать требуемую информацию (по горизонтали и по вертикали вращения) из этих трех значений (х, у, г).

+0

Точно, какую ротацию вы ищете? Например, самая легкая ситуация заключается в том, что телефон кладет экран вверх на стол, а когда вы кладете его с экрана вниз, он поворачивается на 180 градусов (вокруг любой оси). Но что представляет собой поворот на 90 градусов? Это на его стороне? Стоит ли стоять прямо? Или вы ищете решение, в котором вы держите свое устройство в случайной ориентации, и вы хотите знать, когда он поворачивается на 180 градусов в любом направлении внутри, скажем, за 2 секунды? То есть очень общее решение, но очень интересно :) – Desmond

+3

Отнюдь не было, я пытаюсь поднять вашу идею от вас. :) Я сожалею о том, что. Но теперь я понимаю вашу проблему. Это можно сделать, но это сложно сделать, и вряд ли будет «простой» ответ на stackoverflow.com. Вы заинтриговали меня, хотя, кажется, очень весело строить! – Desmond

+0

попытаемся преобразовать эти числа в градусы и посмотреть, помогает ли это: http://stackoverflow.com/questions/4576493/how-can-i-use-sensormanager-getorientation-for-tilt-controls-like-my- paper-plan –

ответ

0

из документации Apple: CMMotionManager Class Reference (пардон много читать, я уже выделены жирным шрифтом некоторые предложения для быстрого чрезмерного чтения)

После создания экземпляра CMMotionManager, приложение может использовать его, чтобы получить четыре типа движения: данные о сыром акселерометре, данные сырого гироскопа, данные сырого магнитометра и обработанные данные о движении устройства (включая акселерометр, скорость вращения и измерения ориентации). Обработанные данные о движении устройства, предоставленные алгоритмами слияния датчиков ядра Motion, дают отношение устройства, скорость вращения, калиброванные магнитные поля, направление силы тяжести и ускорение, которое пользователь передает устройству.

Важное замечание Приложение должно создать только один экземпляр класса CMMotionManager. Несколько экземпляров этого класса могут повлиять на скорость получения данных от акселерометра и гироскопа. Приложение может принимать один из двух подходов при получении данных движения, , обрабатывая его с указанными интервалами обновления или периодически сэмплируя данные движения. При обоих этих подходах приложение должно вызывать соответствующий метод остановки (stopAccelerometerUpdates, stopGyroUpdates, stopMagnetometerUpdates и stopDeviceMotionUpdates), когда он закончил обработку акселерометра, скорости вращения, магнитометра или данных движения устройства.

Передав обновления Motion через заданные интервалы Для того, чтобы получить данные о движении через определенные промежутки времени, приложение вызывает метод «старт», который принимает очередь операции (экземпляр NSOperationQueue) и блок-обработчик определенного типа для обработки тех, обновления. Данные движения передаются в обработчик блоков. Частота обновлений определяется значением свойства «интервал».

Акселерометр. Задайте для свойства accelometerUpdateInterval значение интервала обновления. Вызовите startAccelerometerUpdatesToQueue: withHandler: метод, проходящий в блоке типа CMAccelerometerHandler. Данные акселерометра передаются в блок как объекты CMAccelerometerData. Гироскоп. Задайте для свойства gyroUpdateInterval заданный интервал обновления. Вызвать startGyroUpdatesToQueue: withHandler: метод, проходящий в блоке typeCMGyroHandler. Данные скорости вращения передаются в блок как объекты CMGyroData. Магнитометр.Установите для свойства magnetometerUpdateInterval значение интервала обновления. Вызовите startMagnetometerUpdatesToQueue: withHandler: метод, передающий блок типа CMMagnetometerHandler. Данные магнитного поля передаются в блок как объекты CMMagnetometerData. Движение устройства. Задайте для свойства deviceMotionUpdateInterval заданный интервал обновления. Вызов или startDeviceMotionUpdatesUsingReferenceFrame: toQueue: withHandler: или startDeviceMotionUpdatesToQueue: withHandler: метод, передающий в блоке типа CMDeviceMotionHandler. С помощью первого метода (нового в iOS 5.0) вы можете указать опорный кадр, который будет использоваться для оценок отношения. Данные скорости вращения передаются в блок как объекты CMDeviceMotion. Периодическая выборка данных движения Для обработки данных движения с помощью периодической выборки приложение вызывает метод «старт», не принимающий никаких аргументов, и периодически обращается к данным движения, хранящимся в качестве свойства для данных типа движения. Этот подход является рекомендуемым подходом для таких приложений, как игры. Обработка данных акселерометра в блоке приводит к дополнительным накладным расходам, и большинство игровых приложений интересует только последний образец данных движения при рендеринге кадра.

Акселерометр. Call startAccelerometerUpdates для начала обновления и периодического доступа к объектам CMAccelerometerData, читая свойство accelometerData. Гироскоп. Вызовите startGyroUpdates, чтобы начать обновления и периодически получать доступ к объектам CMGyroData, читая свойство gyroData. Магнитометр. Call startMagnetometerUpdates для начала обновления и периодического доступа к объектам CMMagnetometerData, считывая свойство magnetometerData. Движение устройства. Вызовите метод startDeviceMotionUpdatesUsingReferenceFrame: или startDeviceMotionUpdates, чтобы начать обновления и периодически получать доступ к объектам CMDeviceMotion, читая свойство deviceMotion. Метод startDeviceMotionUpdatesUsingReferenceFrame: (новый в iOS 5.0) позволяет указать опорный кадр, который будет использоваться для оценок отношения.

О сборе данных:

@property(readonly) CMGyroData *gyroData 

Обсуждение Если данные гироскоп не доступен, то значение этого свойства равно нулю. Приложение, получающее данные гироскопа после вызова startGyroUpdates, периодически проверяет значение этого свойства и обрабатывает данные гироскопа.

Таким образом, вы должны иметь что-то вроде

gyroData.rotationRate.x 
gyroData.rotationRate.y 
gyroData.rotationRate.z 

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

+0

Я прочитал документацию, и образец u дал то же самое, что я опубликовал. мой вопрос тот же, как получить информацию о ротации из этих значений x y z. –

+0

в документации, которую я цитировал, говорится, что вам нужно сохранить значения x, y, z, а затем сравнить их часто, чтобы увидеть, изменились ли они. в соответствии с этим изменением вы видите, было ли вращение или нет. – moxy

+0

например: при запуске приложения вы имели x = 20, y = 3, z = 40. Вы храните их в переменных referenceX, referenceY и referenceZ, затем вы отслеживаете gyroData.rotationRate.x, y и z с частыми обновлениями, вы, вероятно, узнаете, небольшие вариации, а затем что-то вроде x = 30, y = 170, z = 10, поэтому вы можете сделать вывод о том, что iPhone был перевернут на оси y (лучше поставить некоторый запас ошибки, а не только на 180 градусов.x, y и z - трехмерная ось, и, глядя, как они меняются (мониторинг и обновление их периодически) – moxy

1

То, что вы пытаетесь, не является тривиальным, но, безусловно, возможно. Это видео должно быть очень полезно для понимания возможностей устройства и того, как приблизиться к вашей цели: http://www.youtube.com/watch?v=C7JQ7Rpwn2k

В то время как он говорит об Android, те же понятия применимы к iPhone.

+0

определенно некоторая хорошая информация в этом видео, но все же далека от ответа. но я думаю, что мой ответ может состоять в том, что эта цитата подводит итог тому, что я имею в виду: «Разработчики приложений, которые хотят осмыслить вращательное движение, должны осваивать углы Эйлера, матрицы вращения и кватернионы. Под капотом должны использоваться алгоритмы слияния датчиков, чтобы для создания отзывчивых, точных и малошумных описаний движения ». –

+0

Вы должны понимать возможности устройства и способы его использования. Некоторые аспекты CoreMotion уже используют слияние датчиков для обеспечения высокой точности данных, это не проблема. Как использовать данные, предоставляемые устройством для описания движения в трех измерениях, это то, что вам нужно решить. То, что вы пытаетесь реализовать, является эквивалентом единицы измерения инерции, которая не является тривиальной на устройстве. Вы должны решить, насколько близко к IMU/INS «достаточно хорошо» для ваших целей. На видео он говорит об этом. Калманская фильтрация может помочь, но может не соответствовать вашим потребностям. – quellish

0

Это все зависит от iPhone должность. Скажем, если телефон перевернет 360 вокруг оси y, компас не изменится, потому что он все равно будет указывать одинаково во время флип. И дело не только в этом. Мой намек заключается в том, что вы регистрируете акселерометр и сравниваете данные, которые вы собрали с сделанным движением, а затем определяете этапы трюка и составляете список этапов для каждого трюка.

+0

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

0

Тогда, возможно, то, что вы ищете, - это только ориентация устройства. Вы должны посмотреть на UIDevice Class Reference. В частности,

– beginGeneratingDeviceOrientationNotifications 
– endGeneratingDeviceOrientationNotifications 

методы.

и использовать его как это:

[UIDevice currentDevice].orientation 

Вы получите взамен эти возможные значения:

typedef enum { 
    UIDeviceOrientationUnknown, 
    UIDeviceOrientationPortrait, 
    UIDeviceOrientationPortraitUpsideDown, 
    UIDeviceOrientationLandscapeLeft, 
    UIDeviceOrientationLandscapeRight, 
    UIDeviceOrientationFaceUp, 
    UIDeviceOrientationFaceDown 
} UIDeviceOrientation; 

Таким образом, вы будете иметь возможность проверить, если это в портретной (вверх или вниз) или пейзаж (слева или справа), и если он был перевернут.

Вы сможете реализовать следующие методы:

- willRotateToInterfaceOrientation 
- didRotateToInterfaceOrientation 

Вы можете посмотреть в this link, чтобы проверить, как вы можете реализовать методы.

Смежные вопросы