lundi 10 mars 2014

Interface Homme Machine : joystick

Lors des essais de l'été dernier, j'ai d'abord utilisé un simple potard comme interface de contrôle. D'un côté, j'allais dans un sens, de l'autre dans l'autre sens. J'ai ensuite rajouté une boucle fermée mais toujours avec un contrôle par un potard.
Cela posait quelques problèmes car la plage de rotation du potard est trop grande pour être couverte facilement. De plus, le potard était monté sur une boîte contenant les circuits électroniques, donc il était posé au niveau du sol. Finalement le potard a fini par casser (au niveau de la connectique).

N'ayant pas de potard de rechange sous la main, j'ai ensuite utilisé mon téléphone portable. L'inclinaison du téléphone était utilisée pour contrôler la vitesse des moteurs. Cela avait l'avantage de permettre de contrôler sans fil (via wifi) et donc par exemple de pouvoir faire les tests seul en joystick manuel (je lançais le cerf-volant et essayais de le piloter à distance). Le problème est que sans information de retour sur la position de la barre, le contrôle était trop difficile. De plus la portée du wifi du téléphone portable étant limitée, il y avait souvent des coupures. Enfin dès que je voulais poser le téléphone, ou que je faisais une erreur, cela envoyait des ordres non désirés.

J'ai ensuite utilisé une radiocommande (récupérée de mon voilier radiocommandé). C'était assez pratique, notamment grâce au ressort permettant un retour à la position neutre. La portée radio était suffisante (mais l'antenne un peu gênante). Le trim est aussi une fonctionnalité que j'ai utilisée pour le contrôle de la barre en boucle fermé. Je n'avais pas testé le décodage par la carte arduino des commandes envoyées au servo, mais cela semble possible (pour pouvoir avoir un enregistrement des commandes).

Souvent, j'ai également directement utilisé une interface graphique avec des "sliders". C'est assez pratique car cela ne demande pas de matériel. Par contre, il est difficile à la souris d'aller cliquer sur le slider, puis de savoir où il est rendu sans avoir les yeux rivés sur l'écran. Pour régler cela, la gestion des sliders était également possible aux flèches du clavier, mais cela n'est pas très réactif, le retour à zéro est difficile (une solution aurait été d'utiliser par exemple la flèche du bas pour le retour au neutre, mais cela n'est pas prévu de base avec les sliders de html5), et on ne sait pas quand on arrive en butée non plus.

Une solution souvent utilisée est le joystick. Le joystick a l'avantage de pouvoir être utilisé à une main s'il est bien fixé. Mais lors des tests pour le pilotage du cerf-volant, cela se passe plutôt en extérieur, et j'essaie d'avoir le moins de matériel possible (pas de table). Une manette de jeu dotée d'un joystick me semblait donc plus pratique, car pouvant se tenir d'une main, le joystick ne bougeant qu'avec le pouce. Cela permet de passer d'un pilotage manuel d'une main (grâce à la barre), à un pilotage joystick de l'autre main par une personne seule. Une alternative serait d'avoir un petit joystick directement fixé sur la barre.

J'ai récemment acheté une manette de jeu ("gamepad") : la rumble pad 2 de Logitech (9 euros chez Happy Cash!).
J'ai pu tester son bon fonctionnement avec le programme jstest-gtk

J'ai ensuite réalisé un programme de test avec le module python pygame (à partir d'un cours sur openclassrooms). Le code est ici.

J'arrive bien à récupérer les informations du joystick (axes) et des boutons. Par contre, cela me paraissait difficile de combiner la gestion des événements de pygame et de tornado.

J'ai donc cherché à capter les signaux du joystick directement au niveau de l'interface graphique (dans un navigateur web). 

Cela est possible grâce à l'API gamepad en cours de définition par le W3C  http://www.w3.org/TR/2014/WD-gamepad-20140225/.Une implémentation fonctionne sous chrome(ium) pour l'instant. Elle peut-être testée sur html5rocks.

A partir du site http://videlais.com/2013/12/24/html5-using-gamepads-as-input/, j'ai réussi à réaliser un programme de test.



function runAnimation()
{
    window.requestAnimationFrame(runAnimation);

    var gamepads = (navigator.webkitGetGamepads && navigator.webkitGetGamepads()) ||
          !!navigator.webkitGamepads || !!navigator.mozGamepads ||
          !!navigator.msGamepads || !!navigator.gamepads;

    for (var i = 0; i < gamepads.length; ++i)
    {
        var pad = gamepads[i];
        console.log(pad.axes);
    }
}

window.requestAnimationFrame(runAnimation);
 

Un code plus complet est disponible ici. Une (petite) difficulté a été de permettre à la fois le contrôle par le joystick, ou par les sliders de l'interface graphique. Une bonne chose est que les informations peuvent être récupérées en même temps par python et javascript. Ce qui peut permettre d'utiliser le joystick même si aucune interface graphique n'est lancée.

Il reste encore à ajouter un trim.

J'ai également testé sur mon téléphone mobile android, en connectant la manette en USB On The Go. Cela permettrait d'avoir un joystick mobile.
Pour cela j'ai servi les fichiers statiques avec :
python -m SimpleHTTPServer

Malheureusement, cela ne fonctionne pas pour l'instant, mais les développements sont en cours.

Cahier des charges (a posteriori) :
  • Au moins 2 axes (droite-gauche, bordé-choqué)
  • Utilisable d'une seule main
  • Ergonomie (amplitude du mouvement)
  • Utilisable en tenant la barre
  • Données récupérables sur un PC
  • Progressif
  • Feedback sensoriel non visuel de la position du joystick + butée + neutre (tactile ou auditif?)
  • Trim (avec protection contre le déréglage)  
  • Détrompeur pour limiter le risque de tenir le joystick à l'envers (voir à ce propos mes mésaventures sur mon blog perso, 2ème paragraphe )

Options :
  • Retour d'effort
  • Solide, étanche
  • Retour au neutre ou maintien en position

Aucun commentaire:

Enregistrer un commentaire