Objet connecté, C# et tir à l’arc…
La découverte du bracelet Myo par Michael (pour rentrer dans le détail le produit, je vous invite à consulter son post de blog) m’a donné envie de mettre en pratique son usage sur un tout petit projet de R&D appliqué à un contexte concret : l’entrainement à la pratique du tir à l’arc.
Une notion de tir à l’arc…
Concrètement, en tir à l’arc, la main qui tient l’arc doit être considérée comme « morte » pendant toute la séquence de tir. Ceci permet d’obtenir un départ de flèche naturel et sans contrainte. Il est donc impératif de ne pas tenir la poignée avec la main. L’arc reste droit uniquement grâce à la contre-pression exercée par l’action de tirer sur la corde. Quand l’archer lâche sa corde et relâche la pression, l’arc doit normalement tomber vu qu’il n’est pas tenu par la main.
La vidéo suivante, trouvée sur un groupe Facebook, illustre bien ce relachement : https://www.facebook.com/video.php?v=740634036023366
Ceci est la théorie, en pratique, un archer débutant (moi), peut avoir un peu de mal à appliquer ce concept (fâcheuse tendance à vouloir « rattraper » l’arc au lâcher, et tout simplement le tenir).
Le bracelet Myo dans tout ça
Le braclet Myo est un concentré de technologie, il est composé de plusieurs capteurs tels qu’un gyroscope, d’un accéléromètre, d’un compas et d’un récepteur de signaux électriques.
Dans mon contexte, c’est clairement ce dernier point qui est intéressant : un main tendue, crispée, fermée active les muscles du poignet et génère donc une activité électrique dans l’avant-bras. Une main relâchée, détendue, « morte », ne fais transiter aucun signal électrique.
Et un peu de C# pour mettre en œuvre !
Mon objectif est donc de notifier l’archer, d’une manière ou d’une autre, lorsque sa main d’arc est activée pendant la séquence de tir.
Le fabriquant Thalmic propose un SDK en C qui s’occupe de récupérer les données en Bluetooth Low Energy (BLE) auprès du bracelet. J’ai pour ma part utilisé un Wrapper C# proposé par la communauté. (MyoSharp : https://github.com/tayfuzun/MyoSharp). Ce wrapper est complet, il fait bien un mapping 1/1 sur le SDK natif.
Premier soucis rencontré :
- Autant pour les capteurs de position, le Myo remonte énormément de données brutes pouvant être calculées
- Autant pour l’activité électrique, quasiment rien n’est transmis par API. En effet, un des savoir-faire de Thalmic est de traduire les signaux électriques en mouvement. Le SDK ne remonte ainsi pas une intensité électrique, mais directement la traduction en position de main : FingersSpreads (main tendue), Fist (poing fermé), ThimbToPinky (pouce et auriculaire qui se touchent), WaveIn (doigts tendus vers l’intérieur), WaveOut (vers l’extérieur), Rest (repos).
La logique veut que dans mon contexte, la position rest / repos soit le plus intéressant, car elle représente théoriquement une non activité.
Le code suivante manipule le SDK C# pour écouter les évènements de pose :
// Connexion au bracelet pour écouter les évènements using (var hub = Hub.Create()) { // Si le bracelet est detectée hub.MyoConnected += (sender, e) => { Console.WriteLine("Bracelet {0} connecté!", e.Myo.Handle); // liste des gestes que l'on veut écouter. var pose = HeldPose.Create(e.Myo, Pose.FingersSpread, Pose.Fist, Pose.ThumbToPinky, Pose.WaveIn, Pose.WaveOut, Pose.Rest); // intervale de temps entre chaque notification de pose pose.Interval = TimeSpan.FromSeconds(0.5); pose.Start(); pose.Triggered += Pose_Triggered; }; ConsoleHelper.UserInputLoop(hub); }
Me voila donc avec un trigger, capable de me donner deux valeurs : repos ou non repos (= n’importe quelle autre position / !rest).
private static void Pose_Triggered(object sender, PoseEventArgs e) { if (e.Pose == Pose.Rest) { Console.WriteLine("repos"); } else { Console.WriteLine("!repos :" + e.Pose.ToString()); s.Play(); } }
Pour prévenir l’archer que sa main n’est pas bonne, j’ai opté pour deux types de notifications :
- Un son bip remonté par l’application
- Ou une vibration envoyée directement dans le bracelet. Celui-ci va ainsi émettre une très courte vibration toutes les 0,5 secondes jusqu’à ce que la position soit bonne.
SoundPlayer s = new SoundPlayer(@"D:\DL\MyoSDK\beep-07.wav"); e.Myo.Vibrate(VibrationType.Short);
Et voilà !
Et cela marche, il ne reste plus qu’à faire un peu de WPF pour disposer d’une interface représentant la séquence de tir. C’est ma prochaine étape.
Commentaires