Club robotique de Sophia-Antipolis

Accueil > POBOTpedia > Capteurs > Capteurs Wii > Utilisation d’un axe du gyroscope du Wii Motion Plus

Utilisation d’un axe du gyroscope du Wii Motion Plus

samedi 4 septembre 2010, par Keuronde

Le but est de récupérer les valeurs d’un axe du Wii Motion Plus pour connaître l’orientation d’un robot. Pour nos premiers tests, nous nous servirons d’un Nunchuk (autre élément de la manette Wii). Équipé de boutons et d’un joystick, il nous permettra de vérifier facilement la cohérence des données. Par la suite, nous nous servirons d’un Wii Motion Plus

Introduction

Le Wii Motion Plus peut prétendre être le gyroscope 3 axes I2C le moins cher du marché. Je souhaite connaître l’orientation de mon robot, et comme j’ai un Motion Plus sous la main, je vous propose ma démarche pour l’apprivoiser.

J’utilise un micro-contrôleur PIC qui communique avec l’ordinateur en USB. Cependant, il n’y a aucune raison pour qu’il faille changer quoique ce soit si vous vous servez d’un autre micro-contrôleur ou que vous communiquez avec le PC via une liaison série.

Réaliser la connectique

Le connecteur du Nunchuk ou du Motion Plus est particulier. Il existe une carte qui se glisse au milieu du connecteur et qui permet de récupérer les 4 contacts nécessaires.
Pour ceux qui sont pressés ou qui, simplement, ne veulent pas acheter une telle carte, j’ai essayé les deux solutions suivantes :
 Étamer les fils et les glisser dans le connecteur. Cette solution marche plus ou moins bien, suivant la forme que prend l’étain sur le fil.
 Souder un élément de barrette sécable mâle au bout de chaque fil. Je recommande cette solution, les éléments de barrettes sécables tiennent particulièrement bien dans le connecteur.

Connecteur fait maison
Connecteur pour le Wii Motion Plus et le Nunchuk

Communication micro-contrôleur <=> PC

Pour la communication avec le PC, il ne s’agit que d’une simple vérification de routine.

J’utilise une connexion USB et mon PIC se déclare comme étant un périphérique CDC (le code est fourni par Microchip). L’ordinateur le voit normalement et créer une liaison série pour communiquer avec. Sous Windows, il me crée un port COM5 ou COM6. Sous Linux, j’y accède via /dev/ttyACM0.

La première des choses à faire est de vérifier que le périphérique peut envoyer et recevoir des données. Un petit code qui envoie une réponse lorsqu’il reçoit un caractère particulier fait parfaitement l’affaire. On teste le code avec l’hyperterminal sous Windows. Sous Linux, soit on installe un programme similaire tel que Minicom ou Cutecom, soit en lançant deux consoles. L’une lit le port série : cat /dev/ttyACM0, l’autre envoie les données vers le micro-contrôleur avec ! echo "mon envoi" > /dev/tty/ACM0

Communication micro-contrôleur <=> Manette Wii

Introduction à L’I2C

Même si votre contrôleur gère la communication I2C, il est utile de savoir comment ce protocole de communication fonctionne.

Physiquement, il s’agit d’un protocole se reposant sur deux fils (plus la masse). Les deux fils sont maintenus à l’état haut par des résistances de Pull-up (que vous ne devez pas oublier sur votre circuit). Chaque composant peut modifier le potentiel du fils en le reliant à la masse via un transistor. De fait, seul l’état bas peut-être imposé par un composant, l’état haut étant l’état de repos. Sur les deux fils, l’un sert d’horloge, l’autre sert pour les données.

Fonctionnellement, le protocole utilise un système de maître-esclave. Le protocole autorise plusieurs maîtres dans un même réseau, mais nous ne nous en servirons pas. Chaque message est démarré par le maître et commence par l’adresse de l’esclave. Par convention, le bit après l’adresse détermine si l’esclave doit envoyer ou recevoir des données.

Chaque message est structuré suivant une trame bien précise :

    • 1 bit de début
    • 7 bits d’adresse
    • 1 bit de lecture-écriture
    • 1 bit d’accusé réception
  • Séquence pouvant se répéter :
    • 8 bits de données
    • 1 bit d’accusé réception (ACK ou NACK)
  • Fin de la séquence pouvant se répéter.
    • 1 bit de fin de communication.

En fonction du bit de lecture-écriture, les bits de données sont envoyés soit par le maître, soit par l’esclave. C’est celui qui reçoit les données qui positionne le bit d’accusé réception. Lorsque le bit de lecture-écriture vaut 1, le maître annonce qu’il attend les données de la part de l’esclave.

Lorsque le maître lit les données d’un esclave, celui-ci est censé envoyer des données tant qu’il ne reçoit pas un accusé de réception négatif.

Lorsqu’on utilise les fonctions bas niveau d’un PIC il faut arriver à :
 Envoyer un bit de début
 Envoyer un octet

 Lire un accusé de réception
 Recevoir un octet
 Envoyer un accusé de réception
 Envoyer un bit d’arrêt

A l’exception des bits de début et de fin, le PIC ne permet d’envoyer que des octets et non des bits isolés. Il faut donc créer un octet avec les 7 bits d’adresse et le bit de lecture écriture.

Octet = (adresse << 1) + Bit_lecture_écriture

Caractéristique du Nunchuk

Le Nunchuk et le Motion Plus communiquent en I2C. Ils supportent une fréquence qui peut monter jusqu’à 400kHz.

Bit
Octet 7 6 5 4 3 2 1 0
0 Jx<7:0>
1 Jy<7:0>
2 Ax<9:2>
3 Ay<9:2>
4 Az<9:2>
5 Az<1:0> Ay<1:0> Ax<1:0> BC BZ

Jx et Jy sont les deux axes du Joystick, Ax, Ay et Az sont les valeurs des accéléromètres et BC et BZ sont les valeurs des boutons C et Z. BZ vaut 1 lorsque le bouton Z n’est pas enfoncé. Idem pour BC.

Nunchuk
2 boutons, un joystick et un accéléromètre 3 axes

Ce tableau, ainsi qu’une partie des informations contenues dans cet article provient de Wiibrew

Les données envoyées par le Nunchuk sont cryptées. Elles se décryptent de la manière suivante :
decode[i] = (crypte[i] XOR 0x17) + 0x17

En branchant le Nunchuk, on commence par un code simple qui teste la présence du Nunchuk. Pour cela, on envoie l’adresse du Nunchuk et on lit l’accusé de réception. En fonction de l’accusé de réception, on envoie un message différent au PC. L’adresse du Nunchuk est 0x52. L’octet à envoyer est donc soit 0xA4 (écriture), soit 0xA5 (lecture). Les bibliothèques Arduino semblent plutôt bien faites et seule l’adresse est à indiquer, le bit de lecture-écriture est positionné par les fonctions beginTransmission et requestFrom.

Montage Wii Motion plus e PIC
La plus grande partie de la carte sert à piloter un moteur pas-à-pas. Sans aucun lien avec notre sujet.

Si le test précédent s’est bien passé, on peut envoyer la séquence d’initialisation complète et vérifier les bits d’accusé-réception. La séquence d’initialisation, en comptant l’octet d’adresse, est la suivante : [0xA4, 0x40, 0x00].

Une fois le nunchuk initialisé, il faut lui envoyer la séquence suivante avant chaque lecture de données : [0xA4, 0x00]. Une fois la séquence envoyée, on récupère les données en envoyant 0xA5 et en lisant 6 octets. Une fois les octets décodés, on récupère les deux derniers bits et on envoie un message pour indiquer quels sont les boutons enfoncés.

Valider la méthode d’acquisition

En créant un mode interactif, on peut facilement tester les fonctions une à une et trouver les éventuels problèmes que nous n’aurions pas détectés. Voici les commandes que j’ai utilisées :
 Initialisation du Nunchuk sur la réception d’un "i"
 Lecture et envoi des états des boutons du nunchuk sur réception d’un "r"
 Lecture et envoie des états des boutons en boucle sur réception d’un "l"

Pour la lecture en boucle, j’utilise un timer (ou compteur relié à la base de temps du pic) qui incrémente un drapeau toutes les 3 millisecondes. Lorsque l’USB est libre, si le mode lecture en boucle est activé et que le drapeau est différent de 0, le programme envoie une demande de lecture et récupère les informations du Nunchuk avant d’émettre un message en fonction de la position des boutons.

L’observation sur l’écran du PC de la position des boutons du Nunchuk en temps réel doit permettre de valider tout ce qui est lié à l’I2C et à la communication micro-ordinateur <=> PC

Traitement des données

Le but est de trouver un traitement performant des données du Wii Motion Plus. Pour cela, il est plus facile de modifier un code sur le PC qu’un code sur le micro-contrôleur.

La création d’une interface Java permettra d’effectuer les traitements et de les afficher facilement.

Configuration de l’environnement de développement

Je ne tenais pas à installer un environnement de développement lourd et dont je ne saurais pas me servir. Une compilation du java à la main est bien plus simple dans notre cas. Pour cela, deux répertoires sont nécessaires dans la variable d’environnement CLASSPATH :
 Le répertoire avec les classes java
 Notre répertoire de travail "."

La compilation s’effectue ainsi :

javac ma_classe.java

L’exécution se lance ainsi :

java ma_classe

J’utilise une DLL qui permet d’accéder au port série sous Windows, il s’agit de fichiers récupérés d’une interface pour la CMUcam.

Pour commencer, créer une fenêtre qui affiche le dernier message reçu par la liaison série. Je conseil l’utilisation d’un JLabel. Cette interface permet d’afficher les états des boutons du Nunchuk.

Ensuite, modifier le code du micro-contrôleur pour envoyer simplement les 6 octets du Nunchuk et modifier l’affichage pour afficher les 6 derniers octets reçus du Nunchuk. Valider l’acquisition en faisant bouger le joystick sur les deux axes et en vérifiant que les deux premiers octets reflètent bien les valeurs du joystick.

Recevoir les données du Motion Plus

Une fois que tout semble marcher avec le Nunchuk, obtenir la même chose de la part du Wii Motion Plus n’est pas compliqué.

Il suffit de changer la séquence d’initialisation. L’adresse du Wii Motion Plus avant son initialisation est 0x53. La séquence pour l’initialiser est : [0xA6 0xFE 0x04].

La séquence de lecture est strictement la même. Par contre, les données ne sont pas cryptées. Vérifier que la réception se fait bien (java ou hyperterminal).

Afficher les vitesses du WM+

Il faut modifier l’interface graphique, ne garder que 3 champs. Il faut recomposer les valeurs des trois axes. Les données arrivent sous la forme suivante :

Bit
Octet 7 6 5 4 3 2 1 0
0 V Lacet<7:0>
1 V Roulis<7:0>
2 V Tangage<7:0>
3 V Lacet<13:8> Tangage mode lent Lacet mode lent
4 V Roulis<13:8> Roulis mode lent Extension connectée
5 V Tangage<13:8> X X

On récupère les valeurs ainsi :

Valeur[i] = Octet[i] + ( (Octet[i+3] & 0xFC) << 6)

Calculer les rotations

Le Wii Motion Plus n’est pas un vrai gyroscope, il ne donne pas une position angulaire, mais une vitesse angulaire. Une étape d’intégration sera donc à notre charge. La première étape est de trouver le zéro pour les vitesses des trois axes. En effet, au repos, le Motion Plus renvoie des valeurs de l’ordre de 8000. La manière la plus simple est de faire une moyenne des valeurs reçues alors que le Motion Plus est immobile. Une fois cette moyenne faite, on peut soustraire ce zéro aux valeurs acquises.

Les méthodes d’intégrations utilisées consistent à multiplier la vitesse obtenue par le temps écoulé entre deux mesures. Cette méthode d’intégration porte parfois le nom de méthodes des rectangles.

Intégration par rectangles
Document original par Cdang (Wikipédia) - Licence Cc-by-sa-3.0

Pour estimer le temps écoulé, la première solution fut de mesurer avec le PC le temps entre deux messages reçus. Cela fonctionnerait peut-être avec une vraie liaison série, mais avec une liaison USB, les informations arrivent par paquets. Le résultat fut médiocre.

La seconde solution envisagée fut de numéroter les messages et supposer que chaque acquisition était séparée de 3 millisecondes. On a un quartz qui sert de base de temps, et on sait si on rate un message ou pas. Les résultats obtenus furent bien meilleurs.

Le Wii Motion Plus propose deux échelles de valeurs en fonction de la vitesse de rotation. La première, vérifiée expérimentalement, est de un bit pour 0.05 degré.

Valeur renvoyée par le Motion Plus immobile
Acquisition de 200 valeurs sur un seul axe pendant 2 secondes.

Qualité des résultats

Il n’est pas facile de juger de la qualité des résultats. Il faudrait connaître l’angle précis duquel le Motion Plus à bouger. Le premier critère de qualité retenu fut une faible dérive lorsque le Motion Plus est immobile. Seuls des tests statiques ont été faits. Des tests en mouvements seront bientôt réalisés, notamment en montant le Motion Plus sur un servomoteur et en demandant au servomoteur de pointer toujours la même direction.

L’augmentation du nombre de valeurs pour la calibration du zéro du Wii Motion Plus a un effet très fort sur la dérive.

Sources d’erreurs

La première source d’erreurs repérée en statique provient de l’écart entre la valeur calculé du zéro et sa valeur réelle. En supposant que cette source d’erreur est prédominante, on peut évaluer l’erreur finale en degré avec la formule suivante :

Erreur = Ecart_zero * res * temps

Il reste a estimer l’écart entre le zéro vrai et le zéro estimé.

Problèmes rencontrés jusqu’à présent

Tout d’abord je croyais ne pas recevoir d’accusé réception de la part du Nunchuk. En fait, le bit du registre PIC testé n’était pas le bon.

Lors de la réception des données, réception en double des 3 premières valeurs lors de la première lecture et valeurs mauvaise lors des autres lectures. La communication entre le PIC et le Nunchuk ne se faisait pas dans les règles, le PIC n’attendait pas la fin de la réception des valeurs avant d’émettre un accusé de réception

Les premières moyennes avec le Wii Motion Plus étaient mauvaises, ceci est dû au temps nécessaire au WM+ pour s’initialiser. Si une lecture des données lui est demandée avant la fin de son initialisation, le Wii Motion Plus renvoie des valeurs fausses, dont certaines sont parfois nulles.

La documentation n’est pas toujours très complète ou précise. Le temps entre deux acquisitions doit être affiné, de nombreuses paires de valeurs successives sont identiques, signe que le Motion Plus n’avait pas eut le temps de réactualiser ses données.

La résolution des gyroscopes en mode rapide ne sera pas facile à vérifier. Le test n’étant pas évident à mettre en place.

Sources

En plus des articles déjà existant de Pobot, les deux sites suivants m’ont particulièrement aidés à obtenir les caractéristiques du Nunchuk et du Wii Motion Plus :
 WiiBrew
 Random Hacks Of Boredom/Genuis

Portfolio

Un message, un commentaire ?

modération a priori

Attention, votre message n’apparaîtra qu’après avoir été relu et approuvé.

Qui êtes-vous ?

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.