Giroscopio en iPhone

Necesito ayuda con el giroscopio en iPhone. No puedo entender las lecturas de la actitud de CMA con respecto al lanzamiento, giro y giro en una situación particular.

Este es mi codigo

- (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á tendido en un avión como en la siguiente figura:

el tono, la rotación y la guiñada son (casi) 0 grados y cualquier giro alrededor de un eje devuelve lecturas comprensibles. Por ejemplo, al girar el dispositivo hacia la derecha, la guiñada disminuye y el tono y el rollo permanecen en 0.

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

y la medición se inicia de nuevo.

Las lecturas son: Yaw = 0, Pitch = 90, Roll = 0

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

Mover el iPhone a esta posición:

Las lecturas son: Yaw = 30, Pitch = 90, Roll = 0

Una vez más, dado que el dispositivo gira alrededor del eje Yaw, este valor cambia y los otros no.

Moviendo el dispositivo alrededor del eje Roll:

Las lecturas son: Yaw = 0, Pitch = 90, Roll = -20.

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

Los cambios de guiñada mientras tanto, Pitch and Roll no.

Habría esperado que Yaw se hubiera mantenido sin cambios y que Roll hubiera cambiado.

¿Cómo puedo compensar esto, ya que me interesan exclusivamente las rotaciones alrededor del eje de Yaw realizadas por el usuario?

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

Gracias de antemano

ACTUALIZAR He seguido las sugerencias de Kay pero nada cambia. Un poco más de detalle en mi código. Me gustaría usar Yaw para rotar un UIImage solo cuando el usuario gira el dispositivo alrededor del eje de Yaw. Esto funciona, pero cuando el usuario gira alrededor de su propio eje vertical, la Yaw 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 Yaw. Tal vez yo estoy equivocado. 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];
                                                           }];

Respuestas a la pregunta(1)

Su respuesta a la pregunta