Giroscopio en iPhone


Necesito ayuda con el giroscopio en el iPhone. No puedo entender las lecturas de CMAttitude con respecto al tono, el balanceo y el guiñado en una situación particular.

Este es mi código

- (void)handleDeviceMotion:(CMDeviceMotion*)motion {

   NSLog(@"Yaw   %f ",attitude.yaw * 180 / M_PI);
   NSLog(@"Pitch %f ",attitude.pitch * 180 / M_PI);
   NSLog(@"Roll  %f ",attitude.roll * 180 / M_PI);
}

Supongamos que el iPhone está acostado en un plano como en la siguiente figura:

introduzca la descripción de la imagen aquí

Pitch, roll y yaw son (casi) 0 grados y cualquier giro alrededor de un eje devuelve lecturas comprensibles. Por ejemplo, al girar el dispositivo a la derecha, el Guiñado disminuye y el cabeceo y el balanceo permanecen en 0.

Ahora el iPhone está en la siguiente posición:

introduzca la descripción de la imagen aquí

Y la medición se inicia de nuevo.

Las lecturas son: Guiñada = 0, Pitch = 90, Roll = 0

Dado que los dispositivos giran alrededor de este eje, el tono aumenta.

Moviendo el iPhone a esta posición:

introduzca la descripción de la imagen aquí

Las lecturas son: Guiñada = 30, Pitch = 90, Roll = 0

Una vez más, dado que el dispositivo gira alrededor del eje de guiñada, este valor cambia y los demás no.

En movimiento el dispositivo alrededor del eje del rodillo:

introduzca la descripción de la imagen aquí

Las lecturas son: Guiñada = 0, Pitch = 90, Roll = -20.

Ahora lo que no puedo entender. Mover el iPhone alrededor de un círculo de radio R ( R > 0), como en esta figura:

introduzca la descripción de la imagen aquí

El guiñado cambia mientras que el tono y el balanceo no lo hacen.

Hubiera esperado que el Guiñado se hubiera mantenido sin cambios y que el Balanceo hubiera cambiado.

¿Cómo puedo compensar esto ya que estoy interesado exclusivamente en las rotaciones alrededor del eje de guiñada realizadas por el usuario ?

Otro problema que tengo es la deriva. El iPhone está en la posición descrita en la segunda figura, tomada en mi mano en reposo durante mucho tiempo (1 minuto o más). El Guiño aumenta constantemente. Alguna idea de cómo compensar la deriva ?

Gracias de antemano

ACTUALIZACIÓN He seguido las sugerencias de Kay, pero nada cambia. Más detalles sobre mi código. Me gustaría usar Guiñada para rotar una UIImage solo cuando el usuario gire el dispositivo alrededor del eje de guiñada. Esto funciona, pero cuando el usuario gira alrededor de su propio eje vertical, el guiñado cambia. Supongo que eso no es correcto ya que cuando el usuario se mueve alrededor de su eje vertical, los dispositivos no giran alrededor de su propio eje de guiñada. Puede que me equivoque. Este es mi código original:

- (void)handleDeviceMotion:(CMDeviceMotion*)motion { 

   CMAttitude      *attitude = motion.attitude;

   NSLog(@"Yaw   %f ",attitude.yaw * 180 / M_PI);
   NSLog(@"Pitch %f ",attitude.pitch * 180 / M_PI);
   NSLog(@"Roll  %f ",attitude.roll * 180 / M_PI);

   image.transform = CGAffineTransformMakeRotation(-attitude.yaw);
}

Este es el código después de la sugerencia de Kay:

- (void)handleDeviceMotion:(CMDeviceMotion*)motion { 

   CMAttitude      *attitude = motion.attitude;        

   if (startAttitude == 0) {

      startAttitude = attitude;
   }

   [attitude multiplyByInverseOfAttitude:startAttitude];

   NSLog(@"Yaw   %f ",attitude.yaw * 180 / M_PI);
   NSLog(@"Pitch %f ",attitude.pitch * 180 / M_PI);
   NSLog(@"Roll  %f ",attitude.roll * 180 / M_PI);


   image.transform = CGAffineTransformMakeRotation(-attitude.yaw);
}

Comienzo el monitoreo de movimiento del dispositivo con

 [motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryZVertical toQueue:[NSOperationQueue currentQueue]
                                                           withHandler: ^(CMDeviceMotion *motion, NSError *error){

                                                               [self performSelectorOnMainThread:@selector(handleDeviceMotion:) withObject:motion waitUntilDone:YES];
                                                           }];
Author: Fab, 2013-01-25

1 answers

[Completamente revisado]

(1) Ángulos extraños

A primera vista, confundí la situación con algunos problemas típicos relacionados con Los ángulos de Euler. Debido a que están cerca de esta área problemática y son muy importantes de tener en cuenta, les dejo esta parte de la respuesta original. Los problemas del ángulo de Euler son:

  • Ambigüedad, ya que la relación entre el estado de rotación y la representación de ángulos de Euler no es biyectiva, es decir, un conjunto de ángulos describe una rotación pero una rotación puede ser representada por más de un conjunto de ángulos de Euler. En la Fig. 3 puede lograr la misma rotación por 1: Yaw=30°, 2: Pitch=90° o por 1: Pitch=90°, 2: Roll=30°
  • Gimbal Lock problema: Puede perder un grado de libertad y el dispositivo no puede girar alrededor de uno de los ejes por más tiempo. La solución es utilizar cuaterniones o matrices de rotación.

Pero como usted declaró en su comentario el verdadero culpable parece ser el marco de referencia. A partir de iOS 5.0, Apple mejoró el algoritmo de fusión del sensor y también considera los datos del campo magnético para calcular CMAttitude. Aunque todavía existe el antiguo método startDeviceMotionUpdates, ahora utiliza una referencia predeterminada CMAttitudeReferenceFrameXArbitraryZVertical para que toda la medición esté relacionada con "El eje Z es vertical y el eje X apunta en una dirección arbitraria en el plano horizontal".

Con el fin de obtener sus datos con respecto a la referencia al inicio (o cualquier otra rotación) necesita almacenar la instancia CMAttitude que desea como referencia y luego usar el método CMAttitude's multiplyByInverseOfAttitude para transformar cada nueva actitud, es decir, al comienzo de su método handleDeviceMotion.

(2) Guiñada a la deriva

Creo que esto está relacionado con un error en iOS 6 como el que describí en Drifting yaw angle después de moverse rápido ya que solía funcionar bien en la versión anterior. Presenté un error-vamos a ver cuando van a arreglar se.


ACTUALIZACIÓN 2

Como los comentarios y el chat mostraron, el objetivo era controlar un robot simplemente inclinando el dispositivo. En este caso, conocer el estado de rotación completa del dispositivo está estropeando el control al cambiar la dirección de la marcha. Por lo tanto, un enfoque basado en acelerómetro puro utilizando CMDeviceMotion.la gravedad es mucho más conveniente.

 6
Author: Kay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:29:46