2012-02-02 16 views
5

He intentado este proyecto tanto en Android como en iOS con poco éxito. Hay una buena posibilidad de que esto esté por encima de mi cabeza. Sin embargo, pensé que publicaría mi pregunta aquí como último esfuerzo.
Estoy tratando de averiguar cuándo un dispositivo se gira o voltea. Mi aplicación debería saber cuándo hizo un 180, 360 o si el dispositivo se volteó verticalmente.
En un intento por comprender la forma en que debería funcionar, traté de descargar dos proyectos de ejemplo: AccelerometerGraph y CoreMotionTeapot. Con estas y una mezcla de otras cosas que he descubierto que estaba tratando esto:sensor de movimiento, rotaciones de lectura

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."); 
} 

Pero no sé cómo reunir la información solicitada (horizontal y rotaciones verticales) a partir de estos tres valores (x, y, z).

+0

Exactamente qué tipo de rotación estás buscando? Por ejemplo, la situación más fácil sería que el teléfono esté tendido con la pantalla hacia arriba sobre la mesa y cuando lo coloque con la pantalla hacia abajo, haya girado 180 grados (alrededor de cualquier eje). Pero, ¿qué constituye una rotación de 90 grados? ¿Está de su lado? ¿Está de pie en posición vertical? ¿O está buscando una solución mediante la cual sostenga su dispositivo en una orientación aleatoria y desee saber cuándo ha girado 180 grados en cualquier dirección dentro de, digamos, 2 segundos? Es decir. una solución muy general, pero muy interesante :) – Desmond

+3

De ninguna manera estaba tratando de sacar tu idea de ti. :) Lamento eso. Pero entiendo tu problema ahora. Se puede hacer, pero esta es una tarea complicada y es dudoso que una respuesta 'simple' en stackoverflow.com sirva. Aunque me has intrigado, parece muy divertido de construir. – Desmond

+0

va a tratar de convertir estos números a grados y ver si esto ayuda: http://stackoverflow.com/questions/4576493/how-can-i-use-sensormanager-getorientation-for-tilt-controls-like-my- plan de papel –

Respuesta

0

de la documentación de la manzana: CMMotionManager Referencia de la Clase (triste suerte de la lectura, he en negrita algunas frases para una rápida sobre-lectura)

Después de crear una instancia de CMMotionManager, una aplicación puede utilizar para recibir cuatro tipos de movimiento: datos del acelerómetro sin procesar, datos del giroscopio sin procesar, datos del magnetómetro en bruto y datos procesados ​​de movimiento del dispositivo (que incluyen mediciones de acelerómetro, velocidad de rotación y actitud). Los datos de movimiento del dispositivo procesados ​​proporcionados por los algoritmos de fusión de sensores de Core Motion le dan a la actitud del dispositivo, velocidad de rotación, campos magnéticos calibrados, la dirección de la gravedad y la aceleración que el usuario está impartiendo al dispositivo.

Importante Una aplicación debe crear solo una instancia única de la clase CMMotionManager. Varias instancias de esta clase pueden afectar la velocidad a la que se reciben los datos del acelerómetro y el giroscopio. Una aplicación puede tomar uno de dos enfoques cuando se reciben datos de movimiento, , manejándolo en intervalos de actualización específicos o muestreando periódicamente los datos de movimiento. Con ambos enfoques, la aplicación debe llamar al método de detención apropiado (stopAccelerometerUpdates, stopGyroUpdates, stopMagnetometerUpdates y stopDeviceMotionUpdates) cuando haya terminado de procesar el acelerómetro, la velocidad de rotación, el magnetómetro o los datos de movimiento del dispositivo.

el dar Motion actualizaciones a intervalos especificados Para recibir los datos de movimiento a intervalos específicos, la aplicación llama a un método de “arranque” que tiene una cola de operación (ejemplo de NSOperationQueue) y un manipulador de bloques de un tipo específico para el procesamiento de las actualizaciones. Los datos de movimiento se pasan al controlador de bloques. La frecuencia de las actualizaciones está determinada por el valor de una propiedad de "intervalo".

Acelerómetro. Establezca la propiedad accelerometerUpdateInterval para especificar un intervalo de actualización. Llame al método startAccelerometerUpdatesToQueue: withHandler: pase un bloque de tipo CMAccelerometerHandler. Los datos del acelerómetro se pasan al bloque como objetos CMAccelerometerData. Giroscopio. Establezca la propiedad gyroUpdateInterval para especificar un intervalo de actualización. Llame al método startGyroUpdatesToQueue: withHandler: pase un bloque de typeCMGyroHandler. Los datos de velocidad de rotación se pasan al bloque como objetos CMGyroData. Magnetómetro.Establezca la propiedad magnetometerUpdateInterval para especificar un intervalo de actualización. Llame al método startMagnetometerUpdatesToQueue: withHandler: pase un bloque de tipo CMMagnetometerHandler. Los datos del campo magnético se pasan al bloque como objetos CMMagnetometerData. Movimiento del dispositivo. Establezca la propiedad deviceMotionUpdateInterval para especificar un intervalo de actualización. Llame al método o startDeviceMotionUpdatesUsingReferenceFrame: toQueue: withHandler: o startDeviceMotionUpdatesToQueue: withHandler: pasando un bloque de tipo CMDeviceMotionHandler. Con el método anterior (nuevo en iOS 5.0), puede especificar un marco de referencia que se utilizará para las estimaciones de actitud. Los datos de velocidad de rotación se pasan al bloque como objetos CMDeviceMotion. Muestreo periódico de datos de movimiento Para manejar los datos de movimiento por muestreo periódico, la aplicación llama a un método de "inicio" sin argumentos y accede periódicamente a los datos de movimiento mantenidos por una propiedad para un tipo dado de datos de movimiento. Este enfoque es el enfoque recomendado para aplicaciones como juegos. El manejo de los datos del acelerómetro en un bloque introduce una sobrecarga adicional, y la mayoría de las aplicaciones de juegos solo están interesadas en la última muestra de datos de movimiento cuando procesan un marco.

Acelerómetro. Llame a startAccelerometerUpdates para comenzar las actualizaciones y acceder periódicamente a los objetos CMAccelerometerData leyendo la propiedad acelerómetroData. Giroscopio. Llame a startGyroUpdates para comenzar las actualizaciones y acceder periódicamente a los objetos CMGyroData leyendo la propiedad gyroData. Magnetómetro. Llame a startMagnetometerUpdates para comenzar las actualizaciones y acceder periódicamente a los objetos CMMagnetometerData leyendo la propiedad magnetometerData. Movimiento del dispositivo. Llame al método startDeviceMotionUpdatesUsingReferenceFrame: o startDeviceMotionUpdates para comenzar las actualizaciones y acceder periódicamente a los objetos CMDeviceMotion leyendo la propiedad deviceMotion. El método startDeviceMotionUpdatesUsingReferenceFrame: (nuevo en iOS 5.0) le permite especificar un marco de referencia que se utilizará para las estimaciones de actitud.

Acerca de la recopilación de los datos:

@property(readonly) CMGyroData *gyroData 

Discusión Si no hay datos giroscopio está disponible, el valor de esta propiedad es nula. Una aplicación que está recibiendo datos de giroscopio después de llamar a startGyroUpdates comprueba periódicamente el valor de esta propiedad y procesa los datos del giroscopio.

Por lo que debe tener algo como

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

almacenándolos y comparándolos periódicamente debe ser capaz de ver si el dispositivo volcó alrededor de un eje, etc.

+0

ya he leído la documentación, y la muestra que ha dado es la misma que publiqué. mi pregunta es la misma, cómo obtener información de rotación de estos valores x y z. –

+0

en la documentación que he citado, se dice que debe almacenar los valores x, y, z y luego compararlos con frecuencia para ver si cambian. de acuerdo con este cambio, puedes ver si hubo una rotación o no. – moxy

+0

por ejemplo: cuando se lanzó la aplicación, tenía x = 20, y = 3, z = 40. Los almacena en las variables referenceX, referenceY y referenceZ, luego supervisa gyroData.rotationRate.x, y y z con actualizaciones frecuentes, probablemente descubra pequeñas variaciones y luego algo como x = 30, y = 170, z = 10, por lo que puede deducir que el iPhone se ha volteado en el eje Y (mejor poner un margen de error, no solo 180 grados).x, yyz son el eje tridimensional y es mirando cómo cambian (controlándolos y actualizándolos periódicamente) – moxy

1

Lo que estás intentando no es trivial, pero es ciertamente posible. Este video debe ser muy útil para comprender las capacidades del dispositivo y cómo acercarse a su objetivo: http://www.youtube.com/watch?v=C7JQ7Rpwn2k

Mientras habla de Android, los mismos conceptos se aplican al iPhone.

+0

definitivamente buena información en ese video, pero todavía lejos de una respuesta. pero creo que mi respuesta podría ser mucho, esta cita resume lo que quiero decir "Los desarrolladores de aplicaciones que deseen dar sentido al movimiento rotativo deben dominar los ángulos, matrices de rotación y cuaterniones de Euler. Debajo del capó, los algoritmos de fusión de sensores deben usarse en orden para crear descripciones de movimiento sensibles, precisas y de bajo nivel de ruido ". –

+0

Debe comprender las capacidades del dispositivo y cómo usarlas. Algunos aspectos de CoreMotion ya usan fusión de sensores para proporcionar datos de alta fidelidad, ese no es el problema. Cómo usar los datos provistos por el dispositivo para describir el movimiento en 3 dimensiones, eso es lo que necesita resolver. Lo que intentas implementar es el equivalente de una unidad de medida inercial, que no es trivial en el dispositivo. Debes decidir qué tan cerca de un IMU/INS es "lo suficientemente bueno" para tus propósitos. En el video, él habla sobre esto. El filtrado de Kalman puede ayudar, pero puede no satisfacer sus necesidades. – quellish

0

Todo depende en el iPhone posición. Supongamos que si el teléfono gira 360 en torno al eje y, la brújula no cambiará porque seguirá apuntándose de la misma manera durante el lanzamiento. Y eso no es solo eso. Mi sugerencia es que inicie sesión en el acelerómetro y compare los datos que ha recopilado con el movimiento realizado, y luego, identifique las etapas del truco y haga una lista de etapas para cada truco.

+0

aunque su clasificación es bastante aproximada todos estos valores que se actualizan con tanta frecuencia. además, no lo consigo porque, como mi ejemplo muestra, consulto el giroscopio, pero parece que hay una fuerza G aplicada que no entiendo. lo que significa que voltear el teléfono rápido o lento tiene una lectura diferente, lo que no debería ser el caso si es solo un giroscopio –

0

Entonces tal vez lo que está buscando es solo la orientación del dispositivo. Debería mirar el UIDevice Class Reference. En particular, el

– beginGeneratingDeviceOrientationNotifications 
– endGeneratingDeviceOrientationNotifications 

métodos.

y utilizar de esta manera:

[UIDevice currentDevice].orientation 

Usted obtendrá a cambio de estos valores posibles:

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

por lo que será capaz de comprobar si está en vertical (arriba o hacia abajo) o paisaje (izquierda o derecha) y si se ha volteado.

Usted será capaz de aplicar los métodos siguientes:

- willRotateToInterfaceOrientation 
- didRotateToInterfaceOrientation 

Usted puede mirar en this link para comprobar cómo se puede implementar los métodos.

Cuestiones relacionadas