1.  Introduction

linmctool est un utilitaire en ligne de commande qui gère la communication Bluetooth avec plusieurs modèles de périphériques à détection de mouvement, et affiche les données des capteurs sous forme textuelle. Il est conçu comme un outil simple et portable pour l'enseignement et la recherche autour de sujets tels que les systèmes de coordonnées 3D, la mécanique des solides, la robotique, l'estimation multi-capteurs, la capture de mouvements et les interfaces utilisateur novatrices. Un joystick à détection de mouvement est un bon outil pour aborder avec des enfants et des étudiants une large palette de sujets techniques, de la notion élémentaire de force d'inertie jusqu'au filtre de Kalman.

Les périphériques supportés sont :

  • Wiimote (y compris le capteur infrarouge et les gyros)

  • SIXAXIS

  • DS3

  • PS Move (sans la camera PS Eye)

Voici un exemple du résultat :

0 00:25:xx:xx:xx:xx WIIMOTE aX=-11 aY=-10 aZ=14  ir0x=966 ir0y=406 ir1x=747 ir1y=419  \
  ir2x=554 ir2y=430 ir3x=467 ir3y=389  gX=209 gY=-298 gZ=232
1 00:19:xx:xx:xx:xx SIXAXIS aX=-3 aY=-21 aZ=-111  gZ=-21 
2 00:06:xx:xx:xx:xx PSMOVE  seq=0 aX=-2613 aY=-329 aZ=3271  gX=5 gY=8 gZ=8  mX=-197 mY=-157 mZ=-58

2.  Avertissement

Ces appareils sont commercialisés comme des périphériques compatibles avec Bluetooth (une norme ouverte qui encourage l'interopérabilité entre les ordinateurs et les périphériques sans fil) et linmctool communique avec leurs interfaces ouvertes par le protocole normalisé Bluetooth HID. Il n'est pas nécessaire de modifier les appareils ou de contourner une quelconque mesure de protection. Mais comme ce logiciel a été développé sans le concours des fabricants, nous ne pouvons pas garantir qu'il s'interface avec le matériel exactement comme prévu. Il y a toujours un risque d'invalider la garantie, d'endommager le matériel en le faisant fonctionner dans des conditions pour lesquelles il n'a pas été conçu, ou pire encore. À vos risques et périls !

Par exemple, on ignore si le PS Move régule tout seul la puissance de ses LEDs RVB ou si l'hôte Bluetooth est censé le faire en utilisant le capteur de température. Par précaution, linmctool limite la luminosité à 25 %.

3.  Limitations

  • linmctool n'est pas un driver générique pour périphériques HID. Il ne gère pas les boutons. Il ne fournit pas une API binaire efficace pour les applications.

  • En l'absence de documentation pour ces périphériques, linmctool n'exploite probablement pas toutes leurs fonctionnalités ou toute leur précision.

  • Afin de ne pas subir les limitations de l'interface hidraw sur certains noyaux, linmctool contourne complètement la couche Bluetooth HID de Linux. Il doit être exécuté sous root pour prendre le contrôle des PSMs L2CAP HID 17 et 19. Il n'est pas possible d'utiliser d'autres périphériques Bluetooth HID (tels que claviers et souris) en même temps. En cas d'exécution sans privilèges root, seule la Wiimote est supportée.

  • linmctool n'utilise pas les mécanismes d'authentification et de chiffrement de Bluetooth.

  • linmctool permet l'utilisation simultanée d'un nombre illimité de périphériques, sous les contraintes de resources imposées par le système et par le matériel. Avec certaines configurations, il peut s'avérer difficile d'atteindre la limite Bluetooth de 7 périphériques par adaptateur. Par ailleurs, lorsque plusieurs périphériques transmettent simultanément, on peut observer des pertes de paquets.

  • Il est possible que linmctool ne distingue pas correctement un SIXAXIS d'un DS3. Si votre DS3 vibre en permanence, utilisez linmctool --force-ds3 ; si le gyro de votre SIXAXIS ne fonctionne pas, utilisez linmctool --force-sixaxis ; et envoyez le résultat de linmctool --dump-readable à l'auteur.

4.  Compilation

Contrairement à d'autres approches qui rencontrent des problèmes de compatibilité et d'intégration, linmctool est conçu pour compiler et s'exécuter facilement sur n'importe quelle distribution Linux, avec quasiment aucune dépendance.

# wget http://www.pabr.org/linmctool/linmctool-20110304.c
# gcc --std=gnu99 -Wall linmctool-20110304.c -lusb -o linmctool 

Pour les systèmes sans libusb, compiler avec -DWITHOUT_USB. L'éventuel appariement par USB devra être effectué sur une autre machine (voir Appariement ).

# gcc --std=gnu99 -Wall -DWITHOUT_USB linmctool-20110304.c -o linmctool 

5.  Mise en œuvre

5.1.  Wiimote

La Wiimote est capable de s'allumer et d'établir une connexion Bluetooth sur simple pression de n'importe quel bouton, mais cette fonctionnalité n'est pas compatible avec tous les modèles d'adaptateurs Bluetooth. C'est pourquoi linmctool requiert une procédure plus complexe.

  • Obtenir l'adresse Bluetooth de la Wiimote .  Mettre la manette en mode "découvrable" en pressant simultanément les boutons 1 et 2, puis exécuter hcitool scan pendant que les LEDs bleues clignotent. Noter l'adresse Bluetooth au format xx:xx:xx:xx:xx:xx.

  • Établir la connexion Bluetooth .  Indiquer la ou les adresses Bluetooth à linmctool sur la ligne de commande. Juste avant de lancer linmctool, mettre à nouveau la ou les Wiimotes en mode "découvrable" en pressant simultanément les boutons 1 et 2.

    # ./linmctool --ir --wmp 00:25:xx:xx:xx:xx
    Waiting for Bluetooth connections.
    Connecting to 00:25:xx:xx:xx:xx
    New device 0 00:25:xx:xx:xx:xx is a Wiimote
    0 00:25:xx:xx:xx:xx WIIMOTE aX=-11 aY=-10 aZ=14  ir0x=966 ir0y=406 ir1x=747 ir1y=419  \
      ir2x=554 ir2y=430 ir3x=467 ir3y=389  gX=209 gY=-298 gZ=232
    

5.2.  SIXAXIS, DS3, PS Move

  • Désactivation de la couche Bluetooth HID - cas des distributions Linux anciennes utilisant hidd .  Il suffit d'arrêter hidd :

    # killall hidd 

  • Désactivation de la couche Bluetooth HID - cas des distributions Linux récentes utilisant bluetoothd .  Ajouter input à la directive DisablePlugins de /etc/bluetooth/main.conf :

    [General]
    # List of plugins that should not be loaded on bluetoothd startup
    DisablePlugins = network,input
    

    Puis redémarrer bluetoothd:

    # service bluetooth restart 

  • Appariement .  Ces périphériques doivent être appariés avec un adaptateur Bluetooth de la machine Linux. Ils ne semblent pas supporter la procédure standard d'appariement Bluetooth ; en remplacement, l'appariement est réalisé par une connexion USB, ce qui peut être considéré comme plus simple et plus sûr. L'appariement est permanent : il n'est pas nécessaire de répéter cette procédure, sauf si le périphérique a été apparié avec une autre machine.

    • Connecter le périphérique avec un cordon USB.

    • Exécuter linmctool :

      # ./linmctool
      Waiting for Bluetooth connections.
      USB: PS MOVE
        Changing master from xx:xx:xx:xx:xx to yy:yy:yy:yy:yy:yy
        Now press the PS button.
      

    • Déconnecter le cordon USB. (Le PS Move peut être utilisé en mode Bluetooth sans être débranché, mais ce n'est évidemment pas recommandé.)

    Les périphériques seront appariés avec le premier adaptateur Bluetooth actif, tel qu'identifié par `hcitool dev`. Pour apparier avec un autre adaptateur, ou avec un adaptateur sur une autre machine, il suffit d'obtenir son adresse Bluetooth en exécutant hcitool dev, et de l'indiquer comme suit :

    # ./linmctool --master xx:xx:xx:xx:xx:xx 

  • Établir la connexion Bluetooth .  Presser le bouton PS à n'importe quel moment pendant que linmctool s'exécute et que le cordon USB est débranché.

    # ./linmctool
    Waiting for Bluetooth connections.
    Incoming connection...
    New device 0 00:06:xx:xx:xx:xx is a PS Move
    0 00:06:xx:xx:xx:xx PSMOVE  seq=0  aX=4232 aY=-135 aZ=652  gX=4 gY=-9 gZ=-7  \
      mX=-94 mY=50 mZ=-91  
    

  • Contrôle de la sphère du PS Move .  Les composantes R,V,B peuvent être définies sur la ligne de commande et modifiées périphérique par périphérique en saisissant des commandes sur l'entrée standard. Les changements sont transmis à l'appareil sous 3 secondes.

    # ./linmctool --rgb 0,10,0
    Waiting for Bluetooth connections.
    Incoming connection...
    New device 0 00:06:xx:xx:xx:xx is a PS Move
    0 rgb 10,0,0
    ...
    


6.  Analyse des problèmes

Voici quelques techniques qui permettent d'améliorer la prise en charge de ces périphériques.

  • lsusb -v permet de voir les descripteurs HID d'un périphérique USB. Il faut préalablement exécuter linmctool ; sinon lsusb affiche "Report Descriptors: ** UNAVAILABLE **".

  • binhistogram affiche un histogramme de chaque bit et de chaque octet des input reports.

    # wget http://www.pabr.org/linmctool/binhistogram.c
    # gcc --std=gnu99 -Wall binhistogram.c -o binhistogram
    # ./linmctool --binary  |  ./binhistogram 

    Avec le PS Move, cet outil révèle notamment qu'en enfonçant lentement la gâchette, on obtient des valeurs analogiques régulièrement espacées, mais en alternance dans deux champs :

      6  41 29 00###### #_________#__________#______#____#____#__#_____________________
      7  43 2b 00###### #__#_____________#_______#_____#___#___#___#___________________
    

    Ceci suggère que deux échantillons sont transmis dans chaque input report. Un effet similaire peut être observé sur les accéléromètres et les gyros (mais pas sur les magnétomètres). La fréquence d'échantillonnage est d'environ 175 Hz.

  • linmctool --dump-readable affiche les 1024 reports HID du premier périphérique détecté (USB ou Bluetooth).

    linmctool --dump-readable --repeat-dump 5 détecte les reports dont le contenu varie.

    linmctool --dump-writable détecte les reports modifiables (en essayant d'écrire 16 octets nuls, ce qui est potentiellement dangereux).

    Avec le PS Move connecté par USB, ces outils révèlent que le feature report 0x04 contient des adresses Bluetooth. Le report 0x04 n'est pas modifiable, mais ses voisins 0x03 et 0x05 le sont. Par ailleurs, le premier octet de la plupart (mais pas la totalité) des reports est son numéro.

  • hcidump -t -V -x permet de diagnostiquer les échecs des connexions Bluetooth.

  • La norme HID est décrite dans [USBHID] et [HIDP].

7.  mccalibrate - Outil de calibration

mccalibrate transforme les données brutes de linmctool en grandeurs physiques.

L'implémentation actuelle applique une simple transformation affine. Pour chaque axe, deux valeurs de référence (±1 g, ±1 rad/s) sont enregistrées dans le répertoire courant.

# wget http://www.pabr.org/linmctool/mccalibrate-20110304.c
# gcc --std=gnu99 -Wall mccalibrate-20110304.c -lm -o mccalibrate 

7.1.  Calibration interactive

mccalibrate --static calibre les capteurs statiques du PS Move (accéléromètres et magnétomètres). L'appareil doit être positionné manuellement dans six orientations différentes (par exemple : normal, à l'envers, roulis à gauche, roulis à droite, tangage vers le haut, tangage vers le bas). mccalibrate détermine les valeurs de référence par régression elliptique.

# ./linmctool --nostdin  |  ./mccalibrate --static
Incoming connection...
New device 0 00:06:xx:xx:xx:xx is a PS Move
Read calibration from 00:06:xx:xx:xx:xx.cal
Put PS MOVE in at least 6 orientations.
Press RETURN to sample when it is stationary.
Please wait 1s... Got 1 samples, please continue.
Please wait 1s... Got 2 samples, please continue.
Please wait 1s... Got 3 samples, please continue.
Please wait 1s... Got 4 samples, please continue.
Please wait 1s... Got 5 samples, please continue.
Please wait 1s... Computing...
ACC: 6 samples, coverage 99% 99% 99%, err 19.792511
MAG: 6 samples, coverage 98% 95% 99%, err 0.741071
A0   min   +656 ppm   max  +1339 ppm
A1   min  -2325 ppm   max   +204 ppm
A2   min   -496 ppm   max  -2189 ppm
G0   min     +0 ppm   max     +0 ppm
G1   min     +0 ppm   max     +0 ppm
G2   min     +0 ppm   max     +0 ppm
M0   min -101515 ppm   max +78074 ppm
M1   min -72260 ppm   max +102799 ppm
M2   min -98625 ppm   max +91781 ppm
Wrote 00:06:xx:xx:xx:xx.cal

Problèmes identifiés :

  • c'est la distance algébrique qui est minimisée, pas la distance euclidienne ;

  • la minimisation est effectuée par exploration aléatoire, sans garantie de convergence ;

  • les axes sont supposés parfaitement orthogonaux ;

  • la gravité locale est supposée de 9.81 m/s² (à ajuster en altitude ; inutilisable à bord de l'ISS).

7.2.  Application de la calibration à un flux de données

# ./linmctool  |  ./mccalibrate
Waiting for Bluetooth connections.
Incoming connection...
New device 0 00:06:xx:xx:xx:xx is a PS Move
Read calibration from 00:06:xx:xx:xx:xx.cal
0 00:06:xx:xx:xx:xx PSMOVE seq=12  aX=-0.10400 aY=9.82060 aZ=-0.00367  \
  gX=0.00000 gY=0.00500 gZ=0.03833  mX=0.1890 mY=0.9726 mZ=-0.3458 

8.  mctrack - Démonstration de suivi de mouvement

mctrack estime et représente graphiquement la position et l'orientation de un à quatre périphériques. Cette version ne fonctionne qu'avec le PS Move.

# wget http://www.pabr.org/linmctool/mctrack-20110304.c
# gcc --std=gnu99 -Wall mctrack-20110304.c -lX11 -lm -o mctrack
# ./linmctool  |  ./mccalibrate  |  ./mctrack 

On trouvera dans la littérature scientifique nombre de publications sur l'estimation de mouvement par accéléromètres, gyros et magnétomètres. mctrack implémente la technique la plus élémentaire : intégration naïve par la méthode d'Euler de la rotation et de l'accélération instantanées, avec recalage à long terme sur une position de référence et une orientation absolue définie par la gravité et le champ magnétique. Les constantes de filtrage sont figées dans le code source.

9.  Remerciements

L'implémentation de HID sur des sockets L2CAP s'inspire du daemon hidd de Bluez. Cette approche, compatible avec toutes les distributions Linux, a déjà été proposée par Jim Paris.

Le support de la Wiimote est basé sur les informations techniques publiées par le projet Wiibrew.

Le support du SIXAXIS/DS3 vient de [SIXLINUX], avec en plus la prise en charge des LEDs, du gyro et du vibrateur.

Le projet MoveOnPC a été le premier à contribuer au support open-source du PS Move, principalement sous Windows, y compris la localisation optique avec la caméra PS Eye.

Merci à Sony et Nintendo d'avoir adopté Bluetooth, une norme ouverte, pour leurs consoles de jeux vidéo. On leur reproche parfois ne pas respecter les spécifications HID à la lettre, mais leurs protocoles restent compréhensibles et ouverts. Les choses auraient été bien pires si les concepteurs avaient choisi d'entraver délibérément le développement de projets tiers comme celui-ci.

Bibliographie

[SIXLINUX] Utilisation du joystick de la PlayStation 3 en mode Bluetooth avec Linux . http://www.pabr.org/sixlinux/sixlinux.fr.html .

[USBHID] Universal Serial Bus. Device Class Definition for Human Interface Devices (HID). http://www.usb.org/developers/devclass_docs/HID1_11.pdf.

[HIDP] Bluetooth Specification. Human Interface Device (HID) Profile. http://www.bluetooth.com/Specification%20Documents/HID_SPEC_V10.pdf.