34 votes

Gyroscope sur iPhone

J'ai besoin d'aide en utilisant le gyroscope de l'iPhone. Je ne peux pas comprendre les lectures de CMAttitude concernant le tangage, le roulis et le lacet dans une situation particulière.

C'est mon code

- (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);
}

Supposons que l'iPhone est posé sur un plan comme dans la figure suivante:

enter image description here

de tangage, de roulis et de lacet sont (presque) 0 degrés et tout en tournant autour d'un axe renvoie compréhensible lectures. Par exemple, en tournant le dispositif de droit, le Lacet diminue et le Tangage et le Roulis reste à 0.

Maintenant que l'iPhone est dans la position suivante:

enter image description here

et la mesure est démarré à nouveau.

Les lectures sont: Lacet = 0, Hauteur = 90, Rouleau = 0

Depuis les dispositifs mis en rotation autour de cet axe, la Hauteur augmente.

Déplacement de l'iPhone dans cette position:

enter image description here

les lectures sont: Lacet = 30, Hauteur = 90, Rouleau = 0

Une fois de plus, puisque l'appareil pivote autour de l'axe de Lacet, cette valeur change et les autres ne sont pas.

Déplacement de l'appareil autour de l'axe de Roulis:

enter image description here

les lectures sont: Lacet = 0, Hauteur = 90, Rouleau = -20.

Maintenant, ce que je ne comprends pas. Déplacement de l'iPhone autour d'un cercle de rayon R (R > 0), comme sur la figure suivante:

enter image description here

Lacet change en attendant de Tangage et de Roulis n'est pas.

Je me serais attendu à Lacet est resté inchangé et Rouler avait changé.

Comment peut compenser ce depuis que je m'intéresse exclusivement à des rotations autour de l'axe de Lacet faite par l'utilisateur ?

Un autre problème que j'ai est à la dérive. L'iPhone est dans la position décrite dans la deuxième figure, pris dans ma main au repos pendant une longue période (1 minute ou plus). Le Lacet en constante augmentation. Une idée de comment compenser la dérive ?

Je vous remercie à l'avance

Mise à JOUR J'ai suivi Kay suggestions, mais rien ne change. Plus de détails sur mon code. Je voudrais utiliser un mouvement de Lacet de rotation d'une UIImage uniquement lorsque l'utilisateur de faire tourner l'appareil autour de l'axe de Lacet. Cela fonctionne, mais lorsque l'utilisateur tourne autour de son propre axe vertical le Lacet change. Je suppose que c'est pas correcte, car lorsque l'utilisateur se déplace autour de son axe vertical, les appareils ne tourne pas autour de son axe de Lacet. Peut-être que je me trompe. C'est mon code d'origine:

- (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);
}

C'est le code après Kay suggestion:

- (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);
}

Je commence appareil de contrôle de mouvement avec

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

                                                               [self performSelectorOnMainThread:@selector(handleDeviceMotion:) withObject:motion waitUntilDone:YES];
                                                           }];

6voto

Kay Points 6742

[Complètement révisée]

(1) Étrange Angles

Au premier regard, j'ai pris la situation en cours d'exécution dans certains problèmes typiques liés à des Angles d'Euler. Parce qu'ils sont près à cette problématique et de vraiment important de garder à l'esprit, je laisse cette partie de la réponse originale à cette question. Euler Angle problèmes sont:

  • L'ambiguïté, comme la relation entre la rotation de l'etat et des Angles d'Euler de la représentation n'est pas bijective c'est à dire un ensemble d'angles décrit une rotation, mais une rotation peut être représenté par plus d'un ensemble d'Angles d'Euler. Dans votre question, la Fig. 3 vous pouvez réaliser la même rotation soit en 1: Yaw=30°, 2: Pitch=90° ou 1: Pitch=90°, 2: Roll=30°
  • Gimbal Lock problème: Vous risquez de perdre un degré de liberté et le périphérique ne peut pas tourner autour de l'un des axes plus longtemps. La solution est d'utiliser les quaternions ou matrices de rotation.

Mais comme vous l'avez indiqué dans votre commentaire le vrai coupable semble être le cadre de référence. À partir de l'iOS 5.0 Apple a amélioré le capteur algorithme de fusion et considère que le champ magnétique de données pour calculer CMAttitude. Bien qu'il y a encore la vieille méthode startDeviceMotionUpdates, il utilise maintenant une référence par défaut CMAttitudeReferenceFrameXArbitraryzvertical de sorte que toutes les mesures est liée à "l'axe Z est vertical et l'axe des X points dans une direction arbitraire dans le plan horizontal".

Afin d'obtenir vos données dans le respect de la référence de départ (ou de tout autre rotation) vous avez besoin de stocker l' CMAttitude exemple vous souhaitez que la référence et ensuite utiliser CMAttitudes' multiplyByInverseOfAttitude méthode pour transformer chaque nouvelle attitude c'est à dire au début de votre handleDeviceMotion méthode.

(2) Un Mouvement De Lacet À La Dérive

Je pense que c'est lié à un bug dans iOS 6, comme celle que j'ai décrite dans la Dérive angle de lacet après le déplacement rapide que d'habitude pour bien fonctionner dans la version précédente. J'ai déposé un bug - nous allons voir si ils vont le réparer.


Mise à JOUR 2

Les commentaires et chat ont montré l'objectif était de contrôler un robot simplement en inclinant l'appareil. Dans ce cas, sachant que la rotation complète de l'état de l'appareil est gâcher de contrôle lors de la modification de la direction de la marche. Ainsi un pur accéléromètre approche fondée sur l'aide de CMDeviceMotion.la gravité est beaucoup plus pratique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X