Intelligence embarque IMA5 2022/2023 G5
Sommaire
Contrôle gestuel pour la domotique
Présentation
L'idée consiste à développer une IA embarquée sur un microcontrôleur STM32 capable de reconnaître des gestes fixes sans mouvements de main, dans le but de contrôler certrain des systèmes domotiques.
En effet, dans le contexte sanitaire actuel (Covid), il serait intéressant de développer des systèmes de contrôle sans contact, pour éviter la propagation du virus. Par exemple, ouverture de porte, allumage des lumières, commander un ascenseur dans un environnement public ou hospitalier.
On pourrait aussi imaginer une application plus domestique à destination du grand public, qui controlerait une ampoule à variateur d'intensité, où notre système permettrait d'allumer, d'éteindre et de faire varier l'intensité de l'ampoule.
Gestes à implémenter
Pour l'environnement hospitalier
- Main ouverte pour allumer l'ampoule
- Poing fermé pour éteindre l'ampoule
- Signe OK avec le pouce et l'index pour l'ouverture/fermeture de porte
- Numérotation de l'étage souhaité avec les doigts pour l'ascenseur
Pour la domotique (ampoule à variateur)
- Main ouverte pour allumer l'ampoule
- Poing fermé pour éteindre l'ampoule
- Pouce vers le haut pour augmenter l'intensité
- Pouce vers le bas pour diminuer l'intensité
PoC
Pour la démonstration, l'idée pour le moment serait à minima de pouvoir contrôler l'allumage et l'extinction d'une LED.
Si c'est possible, nous afficherons dans un terminal le geste detecté pour pouvoir tester l'implémentation de plusieurs gestes.
Réalisation
Prise en main des outils logiciel
La première étape a été de prendre en main le kit STM32 Nucleo+Expansion board (capteurs ToF 8x8). Sous STM32Cube IDE, nous avons donc récupéré le code fourni, l'avons compilé puis nous avons téléversé l'exécutable sur le microcontrôleur.
Une fois l'exécutable fonctionnel sur la board, nous scrutons grâce à l'utilitaire minicom la liaison série, les données récupérées par les capteurs. Ces données
sont affichées sous la formes d'une matrice 8x8, où les valeurs sont séparées par le caractère suivant : |
.
Dans un second temps, nous nous sommes penchés sur la préparation des données pour notre application, où nous avons choisi de les classer sur un axe de taille 64 (0 à 63), puisque la forme matricielle n'est pas utile dans notre cas.
Pour cela, nous avons modifié la fonction print_result dans le fichier app_x-cube-tof.c de manière à ce que les délimiteurs soient le caractère ;
.
La modification du code est faite sous STM32Cube IDE.
Sous NanoEdge, nous avons vérifié la bonne réception des signaux (des valeurs des capteurs) juste après le lancement de l'enregistrement d'un dataset, ces derniers respectaient bien le formalisme attendu.
Expérimentation
Dans un second temps, nous avons choisi d'enregistrer 3 signaux : le signe OK, le signe main ouverte, et le signe poing fermé. Après l'optimisation du dataset durant la phase de benchmarking, l'objectif était de vérifier si notre librairie ainsi construite remplissait son rôle, c'est à dire réussir à identifier les 3 gestes choisis.
Nous avons à ce stade rencontré plusieurs problèmes et pu identifier certaines erreurs à éviter :
- Tout d'abord, lors de la phase d'émulation de la librairie pour vérifier la pertinence du dataset, il ne nous était pas possible de traiter des données récupérées en temps réel par le port USB, à cause d'une erreur de formattage des données. Nous avons pour cela dû changer le séparateur (le point virgule posait problème), et modifier quelque peu la fonction de print série
- Il faut avant calculer l'angle d'ouverture de notre matrice de capteurs pour se placer ni trop prêt ni trop loin. Nous avions dans un premier temps fait notre dataset avec noter main à moins de 15cm du capteur. Le modèle une fois construit ne savait alors pas différencier le poing de la main étant donné qu'il ne captait pas l'intégralité de la main
- Ensuite, nous avons remarqué l'intérêt de prendre à minima une centaine de valeur pour avoir un modèle fiable et efficace
- Il n'est pas pertinent de vouloir ajouter trop d variations pendant l'enregistrement du dataset (variations de distance, d'angle de la main etc) car cela induit un modèle confus et de nombreuses imprécisions pour la détection ensuite. Il serait plus judicieux d'enregistrer chaque variations en différents gestes, mais qui auront ensuite le même traitement dans le software.
- L'arrière plan pendant l'enregistrement du dataset est important. Il faut éviter les mouvements comme le passage de camarades, ou un changement de décor entre le dataset, et l'utilisation embarquée par la suite
A ce stade, nous avons donc du expérimenter plusieurs méthodes de relevés, et nous avons donc réenregistré plusieurs dataset prenant en compte toutes ces remarques. C'est évidemment l'étape la plus importante du projet, puisque c'est la pertinence du modèle qui déterminera la fiabilité et le bon fonctionnement de notre application par la suite. Il est donc normal d'y consacrer une part importante de notre temps.
Voici quelques images prises lors de la construction de nos modèles :
Test du modèle
Une fois que nous avons construit nos différents dataset (variations ou non de distance, arrière plan complexe ou totalement plat ...) nous avons réalisé plusieurs essais en émulation sous NanoEdge pour chaque modèle dans le but de savoir si ils répondaient bien à nos attentes, et ainsi pouvoir les comparer entre eux et identifier LE modèle le plus efficace parmis les 4 que nous avions pu construire pendant notre phase d'expérimentation. Sous NanoEdge, nous testions donc simplement chaque geste les uns après les autres et relevions le comportement du modèle. Il s'est avéré que sur nos 4 modèles, seul un permettait d'identifier clairement les gestes avec une précision acceptable. Néanmoins, le signe OK était rarement détecté correctement et nous avons donc décider de l'écarter pour la suite de notre travail.
Librairie et implémentation sur STM32
Après avoir testé le modèle, on déploie maintenant la librairie générée par NanoEdge sur la carte de développement STM32, librairie qui contient donc notre modèle de machine learning le plus aproprié à notre exemple, ainsi qu'une API permettant l'implémentation rapide de l'utilisation du modèle en langage C. Par ailleurs, étant donné le but de notre projet (réalisation), nous avons decidé de nous restreindre à allumer une LED, si le signe FIVE est fait, et de l'éttiendre si on lui présente le signe POING. Pour cela nous avons choisi la LED2 présente sur la Nucleo comme cible. Il a donc fallu à ce moment comprendre le fonctionnement de l'API et réfléchir à un moyen de l'adapter à notre application. Pour avoir un comportement acceptable de notre LD et au vu de l'instabilité de détection de nos gestes (changement de signe parfois plusieurs fois en quelques secondes), nous avons décidé de définir 2 seuils :
- un seuil SEUIL de confiance correspondant au pourcentage de confiance minimum à partir duquel on peut considérer que le geste identifié par le modèle est correcte (80% dans notre cas après tests)
- un seuil T de temps minimum à partir duquel on éteint ou allume le LED si le geste identifié était toujours le même. Cela permet d'avoir une certaine stabilité et de ne pas avoir de changement inopportun de la LED. Dans les faits, ce seuil de temps est implémenté un nombre minimum de cycle de notre algorithme, fixé à 4 ce qui correspond environ à 2s selon nos estimations.
Une fois l'algorithme implémenté, nous avons pu tester notre modèle en condition réelle, et ainsi validé le fonctionnement de notre système final.
Résultats et améliorations
Voici un lien vers la vidéo qui montre le fonctionnement du système : Média:demo_g5.mp4
Plusieurs améliorations de notre système pourrait être possibles :
- Enregistrements d'autres signaux dans notre datasets NanoEdge, correspondants toujours à nos deux signes FIVE et POING mais dans des configurations légèrement différentes (distance, angle de la main, doigts plus ou moins ouverts ou tout simplement d'autres personnes ...). Cela permettrait d'avoir une plus grande flexibilité et rapidité de notre modèle, qui n'imposerait pas à l'utilisateur d'être à la distance et la position parfaite
- Pour éviter les erreurs d'identification de nos gestes dûs à l'arrière plan pouvant présenter de grande variabilités et au fait que nous utilisons des capteurs de distance, nous pourrions définir un seuil de distance à partir duquel toute donnée qui dépasse ce seuil dans la matrice ne serait pas pris en compte. Cela permettrait d'avoir un modèle qui se construit uniquement sur les mesures de la main de l'utilisateur proche de du capteur sans se soucier du corps de la personne ou de l'arrière plan et ce qu'il s'y passe. En résulterait un modèle beaucoup plus robuste.
Soutenance du travail
- Slides IE : Fichier:IE Slides LACROIX KHALAF.pdf