IMA3/IMA4 2018/2020 P3 : Différence entre versions
(→Semaine 6:) |
(→Présentation générale) |
||
(230 révisions intermédiaires par 7 utilisateurs non affichées) | |||
Ligne 6 : | Ligne 6 : | ||
==Description== | ==Description== | ||
− | Ce | + | Aujourd’hui la qualité de l’air et plus globalement la pollution atmosphérique est un enjeu environnemental majeur, notamment dans le cadre du travail. Ce danger fait l’objet de préoccupations depuis plusieurs années et apparaît aujourd’hui comme un problème majeur de santé publique. Notre projet à pour objectif de répondre à cette problématique en proposant une analyse en temps réel de la qualité de l’air des locaux de Polytech. En effet, l’amélioration de la qualité de l’air passe en premier lieu par l’étude de celle-ci, il est primordial de connaître notre environnement avec précision. |
==Objectifs== | ==Objectifs== | ||
− | |||
=Analyse du projet= | =Analyse du projet= | ||
Ligne 414 : | Ligne 413 : | ||
De nombreuses inquiétudes envers la capacité du robot à rouler et les nouveaux contrôleurs moteurs achetés. | De nombreuses inquiétudes envers la capacité du robot à rouler et les nouveaux contrôleurs moteurs achetés. | ||
− | Le groupe doit se recentrer sur l'aspect hardware du robot avant de s'aventurer sur les outils softwares, qui sont inutiles si le robot ne roule pas. | + | Le groupe doit se recentrer sur l'aspect hardware du robot avant de s'aventurer sur les outils softwares, qui sont inutiles si le robot ne roule pas. |
− | Les choix entrepris doivent également être mieux | + | Les choix entrepris doivent également être mieux justifiés avec des motivations claires (par exemple le choix du matériau pour la boite, le choix d'utiliser des QR Codes au lieu de formes géométriques qui peuvent être plus simples ou encore notre choix concernant nos capteurs de distance qui fonctionnent en infrarouge). |
− | D'autres propositions ont été faites telle que rajouter un bumper (pare-choc) autour du robot en guise de sécurité. | + | D'autres propositions ont été faites telle que rajouter un bumper (pare-choc) autour du robot en guise de sécurité. |
− | |||
===Début du S8:=== | ===Début du S8:=== | ||
− | Le groupe se recentre donc sur l'objectif principal de faire rouler le robot. La Kinect est laissée en suspens pour permettre un avancement plus rapide de la partie hard. | + | Le groupe se recentre donc sur l'objectif principal de faire rouler le robot. |
− | Cependant, la partie serveur web est maintenue, afin de ne pas accumuler trop de retard et pouvoir | + | La Kinect est laissée en suspens pour permettre un avancement plus rapide de la partie hard. |
+ | Cependant, la partie serveur web est maintenue, afin de ne pas accumuler trop de retard et pouvoir enchaîner sur le programme Arduino pour le contrôle des moteurs dès que la partie câblage sera achevée. | ||
Pour mieux gérer notre organisation ce semestre nous choisissons de tout de suite réaliser un diagramme de Gantt. | Pour mieux gérer notre organisation ce semestre nous choisissons de tout de suite réaliser un diagramme de Gantt. | ||
+ | |||
[[Fichier:Gantt_s8.png|"Gantt_s8"]] | [[Fichier:Gantt_s8.png|"Gantt_s8"]] | ||
Ligne 429 : | Ligne 429 : | ||
'''Partie Hard :''' | '''Partie Hard :''' | ||
− | Les nouveaux variateurs ont été reçu, on les | + | Les nouveaux variateurs ont été reçu, on les teste alors. |
− | En outre, nous ne parvenons pas à réguler la tension de sortie des variateurs malgré l'envoi d'une pwm variable en entrée. | + | Plusieurs problèmes de compréhension de leurs fonctionnements, dus à une datasheet peu exhaustive. |
− | De plus, les | + | En outre, nous ne parvenons pas à réguler la tension de sortie des variateurs malgré l'envoi d'une pwm variable en entrée. |
+ | De plus, les tests en charge semblent demander trop de courant pour les variateurs qui se mettent en défaut. | ||
'''Partie Soft : ''' | '''Partie Soft : ''' | ||
− | Le serveur est relancé et nous modifions les différents envois de données sur la console du serveur et sur la liaison série. Nous avons décidé qu’un message typique envoyé par le serveur aurait la forme suivante : X+xxxY-yyy. Le X et Y en majuscule servent à vérifier que le message reçu est bien le bon. Le + ou - servent à indiquer si la valeur X/Y est positive ou négative et la valeur envoyée ira ensuite au maximum jusqu’à 500, trois caractères pour la valeur seront donc suffisants (représentée par "xxx" et "yyy"). Des premiers tests sont effectués et les valeurs reçues sur la console du PC correspondent avec les valeurs envoyées du joystick sur le serveur. La prochaine étape est la vérification de ces envois sur le port série. | + | |
+ | Le serveur est relancé et nous modifions les différents envois de données sur la console du serveur et sur la liaison série. | ||
+ | Nous avons décidé qu’un message typique envoyé par le serveur aurait la forme suivante : X+xxxY-yyy. | ||
+ | Le X et Y en majuscule servent à vérifier que le message reçu est bien le bon. | ||
+ | Le + ou - servent à indiquer si la valeur X/Y est positive ou négative et la valeur envoyée ira ensuite au maximum jusqu’à 500, trois caractères pour la valeur seront donc suffisants (représentée par "xxx" et "yyy"). | ||
+ | Des premiers tests sont effectués et les valeurs reçues sur la console du PC correspondent avec les valeurs envoyées du joystick sur le serveur. | ||
+ | La prochaine étape est la vérification de ces envois sur le port série. | ||
===Semaine 3 :=== | ===Semaine 3 :=== | ||
− | '''Partie Hard :''' La caractérisation des moteurs nous | + | '''Partie Hard :''' |
+ | |||
+ | La caractérisation des moteurs nous a permis de constater que nous ne pourrons malheureusement pas utiliser les nouveaux contrôleurs moteurs. | ||
+ | Pour ne pas perdre de temps nous choisissons de réutiliser les anciens, nous avons un peu de mal à les allumer car ils sont capricieux. | ||
'''Partie Soft : ''' | '''Partie Soft : ''' | ||
− | La mise en forme du serveur n'a pas été une priorité puisque ce dernier ne nous sert au final qu'à utiliser un joystick virtuel. Un codage plus propre sera mis en oeuvre dès que ce dernier sera totalement fonctionnel et répondra à nos attentes. | + | |
− | Pour tester nos envois nous avons utilisé une carte Arduino MEGA afin de lire ce que nous envoyons sur la liaison série. Celle-ci est réglée sur une vitesse de communication égale à 115 200 bauds. Lorsque nous récupérons l'ensemble de nos caractères dans une variable char et que nous l'affichons directement, nous remarquons que des "?" sont envoyés lorsque nous bougeons rapidement le joystick. Pour pallier | + | La mise en forme du serveur n'a pas été une priorité puisque ce dernier ne nous sert au final qu'à utiliser un joystick virtuel. Un codage plus propre sera mis en oeuvre dès que ce dernier sera totalement fonctionnel et répondra à nos attentes. |
+ | Pour tester nos envois nous avons utilisé une carte Arduino MEGA afin de lire ce que nous envoyons sur la liaison série. | ||
+ | Celle-ci est réglée sur une vitesse de communication égale à 115 200 bauds. | ||
+ | Lorsque nous récupérons l'ensemble de nos caractères dans une variable char et que nous l'affichons directement, nous remarquons que des "?" sont envoyés lorsque nous bougeons rapidement le joystick. | ||
+ | Pour pallier ce problème, nous stockons ce qui est envoyé sur la liaison série dans un tableau contenant l'ensemble de la trame. | ||
+ | Nous rappelons que cette trame est de la forme X+255Y-500. Les caractères "X" et "Y" nous permettent d'identifier qu'un nouveau message est reçu, si ce dernier est correctement reçu, c'est à dire de la forme attendue, il est affiché. | ||
+ | Lorsque nous bougeons le joystick trop rapidement des valeurs sont perdues car mal reçues mais il nous suffira de manipuler le joystick en douceur pour recevoir l'ensemble des valeurs. | ||
+ | |||
Nous avons pris du retard sur la partie de gestion des moteurs à cause de notre erreur dans les commandes. | Nous avons pris du retard sur la partie de gestion des moteurs à cause de notre erreur dans les commandes. | ||
+ | |||
[[Fichier:Gantt_01_02.png|"Gantt_01_02"]] | [[Fichier:Gantt_01_02.png|"Gantt_01_02"]] | ||
Ligne 450 : | Ligne 468 : | ||
'''Partie Hard :''' | '''Partie Hard :''' | ||
− | |||
− | |||
− | Plans SVG des plaques intérieures : [[Fichier: | + | Nous recommençons l'entièreté du châssis du robot pour nous permettre de déplacer les différents éléments qui le compose. |
+ | Comme expliqué lors de la soutenance, nous déplaçons principalement les éléments de l'étage du bas. Nous déplaçons le bouton de démarrage et le bouton d'arrêt d'urgence à ce qui est désormais l'avant du robot. | ||
+ | En effet, nous avons aussi pris la décision de placer la roue folle à l'arrière du robot. | ||
+ | Nous rendons l'accès aux fusibles plus facile en le mettant à côté de la porte. | ||
+ | Pour découper ces plaques, nous nous rendons au Fablab de Centrale. | ||
+ | En effet, la découpeuse laser du Fabricarium était indisponible car ils n'avaient plus de lentille. | ||
+ | Clément étant Fabmanager au Fabricarium, nous avons eu l'autorisation d'aller utiliser la découpeuse laser de Centrale. | ||
+ | |||
+ | Plans SVG des plaques intérieures : | ||
+ | |||
+ | [[Fichier:Centaure_Decoupe_86x60.svg|400px|center|"Eléments intérieurs"]] | ||
+ | |||
+ | Plans SVG des parois extérieures : | ||
+ | [[Fichier:Centaure_Decoupe_100x60.svg|400px|center|"Eléments extérieurs + pilier + support Variateur"]] | ||
− | Nous avons | + | Nous avons réussi à démarrer les anciens variateurs des moteurs avec ce schéma de câblage : |
[[Fichier:Câblage_contrôle_variateur.png|"Câblage_contrôleur_moteur"]] | [[Fichier:Câblage_contrôle_variateur.png|"Câblage_contrôleur_moteur"]] | ||
− | Pour démarrer les | + | Pour démarrer les contrôleurs moteurs, il faut : |
− | + | * 24V sur la pin 1 (clé d'anti-démarrage) | |
− | + | * Rien sur les pins 3,4,8 | |
− | + | * Une résistance d'au moins 5kohms entre les pins 5 et 7 | |
− | + | * Une tension entre 40mV et 170mV sur la pin 6 | |
− | Pour ce faire nous avons donc branché une résistance de 10kohms entre les pins 5 et 7. Nous envoyons la tension de 130mV grâce à des DAC. | + | Pour ce faire nous avons donc branché une résistance de 10kohms entre les pins 5 et 7. Nous envoyons la tension de 130mV grâce à des DAC. Nous redirigeons la tension de sortie de la pin 2 vers une carte de relais, celle-ci nous permet de choisir le sens de rotation des moteurs en activant l'un ou l'autre des relais. Le contrôleur moteur est équipé de sécurité au cas ou les deux seraient activés en même temps. |
− | [[Fichier:TomorrowLandCentaure.png|thumb|center||alt=texte alternatif|Le Robot au sommet de son art, ROULE !]] | + | [[Fichier:TomorrowLandCentaure.png|thumb|400px|center||alt=texte alternatif|Le Robot au sommet de son art, ROULE !]] |
'''Partie Soft :''' | '''Partie Soft :''' | ||
− | Le format de nos trames et les valeurs envoyées par notre joystick sont modifiés. | + | Le format de nos trames et les valeurs envoyées par notre joystick sont modifiés. |
− | En effet, envoyer un octet pour chaque valeur de consigne X et Y au lieu de 10 caractère ASCII (ce qui constitue une trame de 10 octets) nous parait être une bien meilleure solution, moins volumineuse et plus rapide d’envoi mais également plus simple pour le traitement sur l’Arduino MEGA. | + | En effet, envoyer un octet pour chaque valeur de consigne X et Y au lieu de 10 caractère ASCII (ce qui constitue une trame de 10 octets) nous parait être une bien meilleure solution, moins volumineuse et plus rapide d’envoi mais également plus simple pour le traitement sur l’Arduino MEGA. |
− | Pour ne pas avoir de problème avec le signe des valeurs X et Y, les valeurs de ces derniers varieront entre 0 et 127 (afin d’utiliser 7 bits sur les 8 bits qui constitue l’octet). | + | Ce problème nous a d'ailleurs été souligné dans les commentaires au milieu du semestre. |
+ | Pour ne pas avoir de problème avec le signe des valeurs X et Y, les valeurs de ces derniers varieront entre 0 et 127 (afin d’utiliser 7 bits sur les 8 bits qui constitue l’octet), la position au repos du joystick sera X = 63 et Y = 63. | ||
La distinction entre X et Y se fera à l’aide du bit de poids fort. | La distinction entre X et Y se fera à l’aide du bit de poids fort. | ||
− | Un octet représentant la valeur de X sera la forme 1xxx xxxx et un octet pour la valeur de Y sera de la forme 0yyy yyyy. | + | Un octet représentant la valeur de X sera la forme 1xxx xxxx et un octet pour la valeur de Y sera de la forme 0yyy yyyy. |
− | Ces trames envoyées sur la liaison série seront également de la même forme pour la Kinect ce qui permettra | + | Ces trames envoyées sur la liaison série seront également de la même forme pour la partie Kinect ce qui permettra de mettre en place une duplication de code sur l’Arduino MEGA pour le traitement. |
− | [[Fichier:Cercle.png|thumb|center||alt=texte alternatif|Valeurs en X et Y]] | + | [[Fichier:Cercle.png|thumb|center||alt=texte alternatif|400px|Valeurs en X et Y]] |
===Semaine 5 :=== | ===Semaine 5 :=== | ||
Ligne 486 : | Ligne 516 : | ||
'''Partie Hard''' | '''Partie Hard''' | ||
− | Nous commençons le câblage du robot. Toutes les pièces ont été découpées et s'assemblent. Nous commençons par tirer des morceaux de ruban pour simuler les câbles. | + | Nous commençons le câblage du robot. |
− | + | Toutes les pièces ont été découpées et s'assemblent. | |
+ | Nous commençons par tirer des morceaux de ruban pour simuler les câbles. | ||
+ | De cette manière, nous pouvons estimer à moindre coût l'encombrement général des câbles, leurs longueurs, leurs agencements les uns vis-à-vis des autres. L'intérêt est de limiter la coupe de câbles trop court. | ||
+ | |||
+ | Nous pouvons ensuite passer au câblage réel de l'étage de puissance, '''remarque importante : la convention de couleur des câbles est inversée (Noir pour le + et Bleu pour le -).''' Le respect des couleurs a été impossible. En effet, les câbles de puissance des batteries étant de grosse section et étant donné l'absence de matériel pour sertir ces câbles, nous avions pas d'autres choix que d'utiliser ceux déjà sertis. | ||
+ | Leurs longueurs nous imposé de les utiliser en inversant la convention des couleurs. | ||
+ | L'emploi de goulottes nous permet une meilleure organisation de l'étage. | ||
+ | |||
+ | L'ajout d'étiquettes sur les câbles nous permet un repérage plus simple, et donc un montage ou démontage facilité. | ||
+ | |||
+ | Les remarques vis-à-vis d'un deuxième bouton d'Arrêt d'Urgence et de longueur de câbles suffisamment grande pour permettre le retrait de l'étage de commande, ont été prise en compte. Nous avons prévu un câble pour ajouter un bouton d'arrêt d'urgence sur la plaque supérieures du robot. Lorsque nous recevront le nouveau bouton, nous irons découper la plaque pour fixer le bouton. | ||
'''Partie Soft''' | '''Partie Soft''' | ||
+ | |||
+ | Les différentes parties Soft se finalisent, les derniers tests sont effectués afin de valider la partie Serveur et la partie Kinect. | ||
+ | Une hiérarchie de priorité est également mise en place dans le code de l'Arduino MEGA. | ||
+ | En effet, pour le contrôle du robot, 3 modes sont mis en place : | ||
+ | * Un mode automatique : Géré par la Kinect. | ||
+ | * Deux modes manuels : Géré par le joystick physique et le joystick virtuel. | ||
+ | |||
+ | Ces différents modes de contrôle peuvent changer au cours du fonctionnement du robot, pour autant si plusieurs modes de contrôle essayent de contrôler le robot au même instant il semble évident que l'un d'entre eux doit être prioritaire et devenir bloquant pour les autres. | ||
+ | |||
+ | *Priorité 1 : (Maximale) La priorité la plus élevée est celle des capteurs situés autour du robot. Ces derniers sont constamment vérifiés peu importe le mode de contrôle du robot afin d'éviter toute collision. | ||
+ | *Priorité 2 : La deuxième priorité la plus élevée est celle du contrôle du robot grâce au joystick physique connecté à l'Arduino via un port RJ11. | ||
+ | *Priorité 3 : La troisième et avant dernière priorité est celle du contrôle grâce au joystick virtuel mis en place sur le Serveur Web en NodeJS. | ||
+ | *Priorité 4 : (Minimale) La priorité la plus faible est celle qui est constituée de la partie Kinect ce qui correspond au fonctionnement du robot en mode autonome. | ||
+ | |||
+ | === Bilan de mi-semestre === | ||
+ | |||
+ | En ce milieu de semestre, nous effectuons un bilan avec les encadrants sur l'avancement du projet. Le robot a maintenant de nouvelles parois. Nous avons fait le choix d'encocher la plaque du milieu pour éviter que l'étage supérieur ne repose sur les batteries. Cela soulève des inquiétudes concernant la maintenance du robot. Il est vrai que nous n'avions pas pris en compte dans notre cahier des charges le fait que le robot soit facilement démontable pour des éventuelles modifications. Il faudrait donc que la plaque du milieu soit facilement démontable. En fait, nous pouvons la retirer facilement. Il suffit pour cela: | ||
+ | |||
+ | *D'enlever le profilé supérieur du côté | ||
+ | *Desserrer les deux profilés du côté | ||
+ | |||
+ | Cela permet d'enlever la plaque. Cependant, de nombreux câbles relient l'étage supérieur à l'étage intérieur. Il faudrait donc débrancher tous ces câbles si l'on veut réellement intervenir sur l'étage inférieur. Cependant, nous réfléchissons à une solution pour effectuer de petites modifications sans devoir tout débrancher. Pour cela, nous réarrangeons le câblage. En effet, nous gardons un peu de marge au niveau des câbles de l'étage supérieur pour pouvoir déboîter la plaque du milieu et accéder à l'étage inférieur en gardant l'étage supérieur câblé. | ||
+ | |||
+ | Nous avons aussi eu des inquiétudes concernant l'emplacement du bouton d'arrêt d'urgence qui avait été au préalable validé par Mr Redon. Nous allons donc modifier notre câblage pour permettre d'ajouter un bouton d'arrêt d'urgence qui sera placé sur le dessus du robot. | ||
+ | |||
+ | Concernant la partie soft : | ||
=== Semaine 6: (04/03) === | === Semaine 6: (04/03) === | ||
'''Partie Hard''' | '''Partie Hard''' | ||
+ | |||
+ | Voici l'état actuel du robot : | ||
+ | |||
+ | [[Fichier:haut_centaure.jpg|700px|center]] | ||
+ | |||
+ | *Toute la partie alimentation est câblée | ||
+ | *Les variateurs sont alimentés mais il nous manque les connecteurs MOLEX pour les contrôler. Nous réalisons un branchement temporaire pour nous permettre de tester la partie soft | ||
+ | |||
+ | [[Fichier:branchement_temp.jpg|center|400px]] | ||
+ | |||
+ | *Le PC ne semble pas s'allumer malgré l'alimentation 12V | ||
+ | * L'écran ne reste pas allumé. Il est bien alimenté en 13V à la sortie du convertisseur, puis sa tension chute à 8V. Puis, lorsque l'écran est éteint, la tension de sortie du convertisseur repasse à 13V. | ||
+ | |||
+ | Nous avons aussi replacé le mat avec l'écran et la kinect. | ||
+ | |||
+ | [[Fichier:mat_centaure.jpg|center|300px]] | ||
+ | |||
+ | Nous avons inversé le sens du mat, et donc le sens de marche du robot pour deux raisons : | ||
+ | |||
+ | *Permettre d'avoir une distance minimale entre les personnes et la kinect pour empêcher tout problème de détection si la personne se trouvait trop près du robot | ||
+ | *Améliorer le déplacement du robot en mettant la roue folle à l'arrière et non plus à l'avant | ||
+ | |||
+ | Enfin, voici la nouvelle disposition des boutons : | ||
+ | |||
+ | [[Fichier:bouton_centaure.jpg|center|500px]] | ||
+ | |||
+ | Ils sont tous présents à l'avant du robot, avec le coupe batteries, le bouton de démarrage et le bouton d'arrêt d'urgence. | ||
+ | Comme discuté avec les encadrants, nous avons rajouté deux câbles avec un domino pour permettre l'ajout d'un autre bouton d'arrêt d'urgence, lui placé sur le dessus du robot. | ||
+ | |||
+ | En parallèle, réalisation d'un livret explicatif du câblage et du fonctionnement du robot. Réalisation sur Onshape des nouveaux supports pour les 6 capteurs que l'on peut voir ci-dessous : | ||
+ | |||
+ | [[Fichier:Capteur centaure.PNG|400px]] | ||
'''Partie Soft''' | '''Partie Soft''' | ||
− | === Semaine 7: ( | + | Nous testons donc la partie soft avec le câblage temporaire. Lorsque le serveur envoie l'ordre d'aller vers l'avant, les deux moteurs tournent bien dans le même sens. |
+ | Cependant, lorsqu'on lui demande d'aller vers l'arrière, nous n'avons qu'une seule roue qui tourne. Nous remarquons que sur les relais, une des Leds ne s'allume pas. Nous avons donc plusieurs hypothèses pour ce problème : | ||
+ | |||
+ | * Problème au niveau du code | ||
+ | * Problème au niveau du shield | ||
+ | * Problème au niveau de l'arduino | ||
+ | |||
+ | Nous enlevons le shield pour tester l'arduino et le code. On réalise un code pour envoyer 5V sur la pin 47, qui correspond à la pin du moteur gauche pour aller en marche arrière. | ||
+ | On reçoit bien 5V sur cette pin. Le problème ne vient pas de l'arduino. Nous testons donc le code. Nous recevons bien des données. Le problème viendrait donc du shield. | ||
+ | On vérifie d'abord que sur le shield, le bornier est bien reliée à la pin qui s'enfiche dans la pin 47 de l'arduino. | ||
+ | Il n'y a pas de problème de ce niveau là. En regardant le shield, on remarque que les soudures sont assez grosses et pourraient empêcher le shield de bien s'emboîter dans l'arduino. | ||
+ | En nettoyant les soudures, on rebranche tout. Nous recevons bien les 5V sur le bornier, il s'agissait donc uniquement d'un faux contact. | ||
+ | Nous avons encore des modifications à réaliser sur le code pour gérer les cas spécifiques. | ||
+ | |||
+ | Coté serveur ce dernier est achevé et fonctionnel, les derniers tests sont concluants et cette partie est maintenant finalisée. | ||
+ | • Archive ZIP contenant ce qui a été réalisé pour le serveur : [[Fichier:Serveur Joystick.zip]] | ||
+ | |||
+ | === Semaine 7: (11/03)=== | ||
'''Partie Hard''' | '''Partie Hard''' | ||
− | + | Finalisation du câblage : | |
+ | |||
+ | Après réception des connecteurs Molex, nous avons, avec l'aide de Thierry, confectionné des câbles permettant de relier les variateurs de vitesse au shield arduino de façon propre. | ||
+ | |||
+ | Voici le câblage : | ||
+ | |||
+ | [[Fichier:cable_var.jpg|300px|center]] | ||
+ | |||
+ | De plus, le câblage entre les commutateurs et le shield a également était revu. Il est maintenant composé de câbles ayant une longueur adapté, maintenus par des borniers. | ||
+ | Nous finissons d'imprimer les capteurs : | ||
+ | |||
+ | [[Fichier:impression.jpg|200px|center]] | ||
+ | |||
+ | |||
+ | Intégration des capteurs : | ||
+ | |||
+ | [[Fichier:cap_centaure.jpg|300px|center]] | ||
+ | |||
+ | Nous quittons donc le robot pour une période indéterminée. | ||
+ | |||
+ | [[Fichier:Salle.jpg|500px|center]] | ||
+ | |||
+ | |||
'''Partie Soft''' | '''Partie Soft''' | ||
+ | |||
+ | Le code Arduino a été revu afin d'offrir une meilleure mobilité au robot. La stratégie est la suivante : | ||
+ | |||
+ | Une vitesse initiale identique est attribuée aux deux moteurs en fonctions de l'axe y lorsque le robot est contrôlé par le joystick. Cette vitesse est ensuite modifiée en fonction de l'axe x, en tournant à gauche, on va ainsi ralentir le moteur gauche et accélérer le moteur droit | ||
+ | |||
+ | vit_motD = val_y + ((63 - val_x)/2); | ||
+ | vit_motG = val_y + ((val_x- 63)/2); | ||
+ | Pour rappel, la position (63;63) correspond à la position centrale du joystick | ||
+ | |||
+ | |||
+ | Lors du déplacement en autonomie le calcul est le même, la Kinect envoie alors une valeur 'val_y' en lien avec la distance de l'obstacle le plus proche et une 'val_x' en lien avec la localisation de l'obstacle (à gauche ou à droite du robot) | ||
+ | Les fonctions qui calculent val_y et val_x sont linéaires, ce qui permet un évitement progressif des différents obstacles. | ||
+ | |||
+ | |||
+ | '''Bilan du projet avant le début du confinement''' | ||
+ | [[Fichier:Gantt_25_03.png|"Câblage_contrôleur_moteur"]] | ||
+ | La réorganisation de l'intérieur du robot a été entièrement réalisé. | ||
+ | Les moteurs sont contrôlés grâce aux variateurs. | ||
+ | Le robot est entièrement ré-assemblé et il ne manque qu'à relier les capteurs pour finir le câblage. | ||
+ | Nous arrivons à le faire rouler grâce a un joystick virtuel et le PCB du joystick physique et en cours de validation. | ||
+ | Le serveur et la kinect sont synchronisés grâce à la gestion de priorité. | ||
+ | Le contrôle du robot grâce à la kinect n'a pas encore pu être testé mais le programme est fonctionnel, seul des ajustements de variables seront à effectuer. | ||
+ | |||
+ | === Semaine 8: (18/03)=== | ||
+ | |||
+ | Pour palier notre absence due au confinement, nous avons de nouveaux axes à traiter qui se concentrent sur la partie soft du robot. | ||
+ | |||
+ | Avant de partir, toute la partie câblage était finie, à l'exception des capteurs qu'il faut encore brancher à l'arduino. Le code prenait déjà en compte les capteurs et nous ferons les tests quand nous aurons accès au robot. | ||
+ | |||
+ | Nous nous concentrons donc sur 3 axes : | ||
+ | |||
+ | * OpenCV : Suivre une piste au sol en détectant les murs et les escaliers. Ceci est une solution à court terme pour le robot. (Pierre et Samuel) | ||
+ | * Interaction Homme-Machine : Créer un visage pour le robot, proposer des services aux utilisateurs (Loïc et Théo) | ||
+ | * Intelligence artificielle : Réaliser un réseau de neurones (apprentissage de circuit) permettant de donner la direction au robot. Ceci est la solution sur le long terme. (Valériane et Clément) | ||
+ | |||
+ | Deux pistes principales pour l'IA sont : | ||
+ | https://atsushisakai.github.io/PythonRobotics/ | ||
+ | https://blog.floydhub.com/teaching-my-robot-with-tensorflow/ : pytorch / tensorflow qui est du deep learning | ||
+ | |||
+ | === Semaine 9: 25/03 === | ||
+ | |||
+ | '''Point Kinect :''' | ||
+ | |||
+ | Nous sommes capable, avec la Kinect, de récupérer le flux vidéo et d'en extraire des informations tels que l'abscisse, l'ordonnée et la profondeur d'un point dans l'espace. | ||
+ | |||
+ | L'enjeu est donc, à partir de ce flux vidéo, de déduire une consigne de direction à transmettre à l'Arduino, à savoir une consigne de la forme {val_y ; val_x} | ||
+ | |||
+ | |||
+ | Pour se faire, à chaque nouvelle image fournie par le capteur, on scanne chaque pixel pour localiser le pixel le plus proche. Celui-ci est donc considéré comme l'obstacle le plus urgent à éviter : | ||
+ | |||
+ | * La distance de ce pixel est utilisée pour établir une 'val_y' entre 0 et 127. Plus l'obstacle est proche, plus la valeur se rapproche de 0. | ||
+ | * L'abscisse de ce pixel est utilisée pour déterminer une 'val_x' entre 0 et 127. La consigne 'val_x' s'adapte afin d'éviter de façon progressive les obstacles, plus celui-ci est centrée par rapport au robot, plus la consigne de changement de direction sera importante. | ||
+ | |||
+ | '''Problème :''' | ||
+ | Un des problèmes rencontré fut les ombres. En effet le capteur infrarouge de la Kinect est sensible aux infrarouges et s'avère très peu fiable dans des environnements fort lumineux (près d'une fenêtre par exemple). | ||
+ | Le capteur retourne donc, pour tous les pixels sur-exposés, une distance par défaut de 2 mètres. Ce comportement est dangereux car il peut amener le robot à percuter un obstacle en pleine lumière. | ||
+ | |||
+ | '''Solution :''' | ||
+ | On implémente donc un algorithme de gestion des ombres, on se sert des pixels adjacents aux ombres dans le but d'attribuer une valeur arbitraire de profondeur à chaque pixel, qui correspond à son environnement proche (cf image) : | ||
+ | |||
+ | [[Fichier:Ombres.png | 500px | center]] | ||
+ | |||
+ | |||
+ | '''Intelligence artificielle ''' | ||
+ | |||
+ | Nous faisons des recherches pour nous former au développement d'un réseau de neurones, pour pouvoir, sur le long terme, avoir un robot autonome qui arrive à conduire des personnes à différents endroits de Polytech. | ||
+ | De nos premières recherches, nous avons différents outils pour réaliser ce réseau de neurones : | ||
+ | |||
+ | * Pytorch | ||
+ | * Tensorflow | ||
+ | * Mathlab | ||
+ | |||
+ | Les deux premiers utilisent Python alors que le dernier utilise C++. Nous étudions ces différentes possibilités car nous avions remarqué que le PC du Centaure ralentissait significativement lorsqu'on lui a demandé de faire du traitement d'image avec Python. En utilisant OpenCV, nous n'avons plus ce problème de ralentissement. Aussi, nous ne sommes pas sûrs d'avoir accès à toutes les fonctionnalités de Mathlab avec la version gratuite mise à disposition pendant le confinement. | ||
+ | |||
+ | Voici les grandes étapes à suivre pour réaliser un réseau de neurones : | ||
+ | |||
+ | * 1. Accès et préparation de nos données | ||
+ | * 2. Création du réseau de neurones | ||
+ | * 3. Configuration des entrées et sorties du réseau | ||
+ | * 4. Réglage des paramètres du réseau (poids et biais) afin d'optimiser les performances | ||
+ | * 5. Apprentissage du réseau | ||
+ | * 6. Validation des résultats du réseau | ||
+ | * 7. Intégration du réseau dans notre système | ||
+ | |||
+ | '''Open CV :''' | ||
+ | Pour nous permettre de nous déplacer dans les bâtiments de Polytech, nous choisissons d’implémenter une partie « temporaire » (remplaçable par l’IA par la suite). Ce travail à réaliser grâce à la librairie Open CV devrait nous permettre de reconnaître une forme au sol pour pouvoir savoir où nous sommes et où nous guider vers notre cible. Dans un premier temps, nous avons commencé par installer une version stable d’Open CV, la version 2.4 et nous commençons à nous familiariser avec cette bibliothèque et au langage C++ grâce a des programmes simples de détection de visage. | ||
+ | |||
+ | |||
+ | === Semaine 10 : 01/04 === | ||
+ | |||
+ | ''' Intelligence artificielle ''' | ||
+ | |||
+ | Nous nous renseignons sur l'algorithme de Dijkstra. Cet algorithme permet de trouver le chemin le plus court pour aller d'un point A à un point B. Pour pouvoir l'utiliser dans l'enceinte de Polytech, il faudrait au préalable remplir un tableau avec toutes les destinations possibles depuis le hall. | ||
+ | |||
+ | [[Fichier:Algo_dji.PNG|700px|center|thumb|"Image Wikipédia expliquant l'algorithme de Dijkstra]] | ||
+ | |||
+ | Un autre algorithme, qui se base sur celui de Dijkstra, est l'algorithme A*. Il a été utilisé sur le premier robot capable de raisonner sur ses actions, le robot Shakey. | ||
+ | [[Fichier:Shakey.png|150px|center|thumb|"Image Wikipédia du robot Shakey"]] | ||
+ | |||
+ | Cet algorithme utilise une méthode heuristique pour déterminer le meilleur chemin, à partir de nœud. Il ne nécessite pas de prétraitement et consomme peu de mémoire. Cela pourrait donc nous permettre de ne pas avoir de ralentissement en utilisant cet algorithme sur le Centaure. | ||
+ | |||
+ | Après discussion avec les encadrants, nous nous recentrons vers l'utilisation du deep learning pour l'apprentissage de circuits. | ||
+ | |||
+ | N'ayant pas accès à Polytech, nous ferons d'abord des tests chez nous. Voici la méthode que nous devons suivre pour réaliser un réseau de neurones capable de se déplacer de manière autonome sur un circuit qu'il a appris : | ||
+ | |||
+ | *Faire circuler le robot d'un point A à un point B en prenant de nombreuses captures d'images | ||
+ | *Utiliser un algorithme d'augmentation des données (ombre, luminosité..) pour travailler les images avant de les labelliser | ||
+ | Cela correspond au pré-traitement du réseau de neurones. Pour traiter ces données, nous pouvons utiliser Tensorflow et Google Colab. | ||
+ | Une fois l'architecture globales des algorithmes déterminées, il nous suffira de remplacer nos données par un circuit à Polytech. | ||
+ | |||
+ | TensorFlow est une librairie entièrement programmée en Python qui fournit une API pour les utilisateurs qui souhaiteraient utiliser des techniques de machine learning. Il s'agit en réalité d'un ensemble de fonctions mathématiques et de méthodes de calcul qui permettent de développer des fonctions d'apprentissage par la machine à adapter à chaque cas de figure.<br> | ||
+ | |||
+ | ''' Interaction Homme-Machine ''' | ||
+ | |||
+ | Il est maintenant temps de mettre à profit l'écran mis à disposition sur le véhicule. Celui-ci doit remplir les missions suivantes : | ||
+ | * Etre clair | ||
+ | * Susciter l'intérêt des passants | ||
+ | * Etre acceptable esthétiquement | ||
+ | Par l'intermédiaire de cet affichage, les personnes de passages devraient être capables de communiquer rapidement avec le robot. | ||
+ | On s’attelle donc à lui donner un visage qui sera affiché lors des déplacements du robot et lorsqu'il communique avec des utilisateurs. | ||
+ | |||
+ | Plusieurs designs furent proposés et testés, pour finalement s'orienter vers un visage sobre et épuré (et bien moins terrifiant): | ||
+ | [[Fichier:Visage.png|center]] | ||
+ | |||
+ | |||
+ | Concrètement, l'interface visible à l'écran est gérée par un fichier source multithreadé "display.c" et fait appel à la libSDL (utilisée pour la création d'applications multimédias). On décompose le visage en différentes sous images : | ||
+ | * œil | ||
+ | * iris | ||
+ | * bouche | ||
+ | |||
+ | De cette manière il est possible d'animer notre personnage à l'écran. Une fonction est dédiée au mouvement des yeux et est lancée au sein d'un thread (l'utilisation des threads est d’ailleurs encapsulée dans une bibliothèque libthread). | ||
+ | De plus, le programme communique en IPC avec le programme de détection faciale, ainsi, lorsque qu'aucun visage n'est détecté par le robot, les yeux présentent un mouvement aléatoire, à l'inverse, lorsqu'un visage est détecté, ses coordonnées sont transmises et le robot suit la personne du regard. | ||
+ | |||
+ | On note cependant la lenteur du traitement des images en C++ à l'aide d'openCV. En étant le plus minimaliste possible, le programme traite péniblement 1 image par seconde sur un PC récent...Difficile alors de savoir si le programme sera supporté par le PC embarqué du robot. | ||
+ | |||
+ | L'utilisation de threads a pour but final de pouvoir mouvoir indépendamment différentes parties du visage et de pouvoir par exemple lancer des fichiers sonores en parallèle de l'animation du visage. | ||
+ | |||
+ | L'ensemble du code de l'interface et disponible sur ce dépôt git : https://archives.plil.fr/lringot/Centaure_IHM.git<br> | ||
+ | |||
+ | |||
+ | '''Reconnaissance Vocale ''' | ||
+ | |||
+ | Une solution de reconnaissance vocale et de synthèse vocale développée en C est également recherchée. | ||
+ | Il est vrai que nous avions développé une reconnaissance vocale et faciale ainsi qu'une synthèse vocale l'année dernière pour autant cela avait été développé en Python. | ||
+ | Après nos différents tests et après nous être documenté il s'avère que le Python est un langage beaucoup plus "lourd" que le C/C++ et jusqu'a 100 fois plus lent que le C. | ||
+ | |||
+ | Plusieurs solutions sont à notre disposition : | ||
+ | * HTK : Application cross-plateforme mais non open source et qui ne supporte que l'Anglais, programmation en C. | ||
+ | * RWTH ASR : Idem que HTK, cross-plateforme, non open source et ne supporte que l'Anglais, programmation en C++. | ||
+ | * Julius : Application qui pourrait tout à fait convenir à notre utilisation mais cette dernière ne supporte que l'Anglais. Elle est open source et supporte le C. | ||
+ | * Kaldi : Idem que Julius, application qui pourrait tout à fait convenir à notre application mais ne supporte que l'Anglais et le C++. | ||
+ | * CMU Sphinx : Application qui semble être la plus adaptée à notre utilisation. Cette dernière supporte de nombreux langage et notamment le français, elle est open source et cross plateforme et supporte le Java et C. | ||
+ | |||
+ | Au final nous nous orientons vers une utilisation de CMU Sphinx qui est un ensemble de logiciels pour différentes applications et tâches. Dans cet ensemble nous retrouvons PocketSphinx et Sphinx4. | ||
+ | Dans notre application nous utiliserons PocketSphinx qui est une librairie écrite en C pour de la reconnaissance vocale. | ||
+ | |||
+ | Des premiers test sont effectués en Anglais, ces derniers ne sont pas précis et le passage pour une reconnaissance de la voix en française se fait difficilement. | ||
+ | |||
+ | '''Open CV ''' | ||
+ | |||
+ | Nous avons profité de cette semaine pour en apprendre plus sur la librairie Open CV et sur son fonctionnement, grâce à un programme de détection de visage, celui-ci sera par la suite réutilisé quand le robot sera en attente d’interaction avec quelqu’un. | ||
+ | Pour détecter des formes la librairies Open CV se sert de fichiers « xml » qui sont en fait des modèles, par exemple le fichier « haarcascade_frontalface_alt.xml » est un modèle de détection de visage, un certains nombres de photos contenant un visage ont était envoyées à un programme pour obtenir un fichier qui sait reconnaître les attributs d’un visage et donc les détecter. | ||
+ | Dans le programme de détection de visage que nous avons récupéré, nous remarquons que les images par secondes sont très faibles, 1 à 3 maximum. Nous décidons donc de nous plonger en profondeur dans le traitement des images. | ||
+ | Le programme se sert de la fonction « detectMultiScale » pour détecter une forme. Grâce a des recherches sur cette fonction, nous avons appris qu’elle fonctionnait de la manière suivante : elle prend en paramètre une image et une forme à chercher, elle va parcourir cette image jusqu’à la fin, puis va réduire l’échelle de cette image et recommencer. | ||
+ | Deux paramètres sont donc à bien ajuster dans l’utilisation de cette fonction, « scaleFactor » qui est le paramètre de réduction des images (d’après nos recherches à choisir entre 1,1 et 1,5), plus ce paramètre est petit, plus on est précis mais plus on augmente le temps de traitement. | ||
+ | Le deuxième paramètre est « minNeighbors » ce paramètre est également essentiels pour ne pas avoir de faux positifs, il nous permet de choisir à partir de combien de détection de l’objet à un endroit sur des couches successives on considère que c’est l’objet que l’on recherche (celui-ci est généralement compris entre 3 et 5), plus il est élevé plus la précision est élevée mais plus le temps de traitement est long. | ||
+ | Un troisième paramètre rentre en jeu dans notre détection de visage « minSize », celui-ci permet d’indiquer une taille minimale à l’objet recherché, plus il est faible et plus le temps de calcul sera long, dans le cas d’une détection de visage c’est ce paramètre qu’il faut augmenter pour améliorer le temps de traitement. | ||
+ | |||
+ | ===Semaine 11: 08/04=== | ||
+ | |||
+ | '''Intelligence artificielle ''' | ||
+ | |||
+ | Nous étudions donc la possibilité de réaliser un réseau de neurones capables d'apprendre des circuits, pour ensuite l'utiliser sur le Centaure et qu'il puisse se déplacer de manière autonome et intelligente dans Polytech (le long des circuits qu'il connaîtra). | ||
+ | Nous partons du principe que nous devons avoir de nombreuses images de ce circuit, que nous allons ensuite donner à notre réseau de neurones pour les analyser. Nous choisissons le logiciel Tensorflow recommandé par Mr Dequidt ainsi que l'outil Google Colaboratory. | ||
+ | En effet, ce dernier permet d'utiliser Tensorflow sans installation préalable. | ||
+ | Nous prenons donc nos marques avec ces nouveaux outils. Pour cela, nous commençons le cours de Machine Learning disponible sur Google Colaboratory pour voir ces différentes notions : | ||
+ | |||
+ | [[Fichier:Cours_tensor.png|center|200px]] | ||
+ | |||
+ | |||
+ | Nous nous posons aussi des questions concernant le déplacement du robot. | ||
+ | À partir de quelles informations le robot va t-il décider de se déplacer vers la gauche ou vers la droite. | ||
+ | Nous allons prendre des images du circuit qu'il va faire. Va t-il ensuite, lorsqu'il devra à nouveau parcourir ce circuit, comparer l'image qu'il voit à l'ensemble des images connues, pour savoir s'il dévie à gauche ou à droite ? | ||
+ | Lui imposer par exemple qu'un pourcentage de sa vision doit contenir un mur, pour lui permettre de suivre le mur et d'agir en fonction du pourcentage de mur qu'il voit dans son champ de vision. | ||
+ | S'il se tourne vers le mur, donc qu'il voit de plus en plus de mur dans sa vision à gauche, alors il doit aller vers la droite, et inversement. | ||
+ | Pour cela, il faudra que notre réseau de neurone sache reconnaître certains éléments comme un mur, une porte, un escalier. Nous pouvons utiliser un réseau pré-entraîner pour cela. | ||
+ | Nous avons par exemple trouvé le modèle ResNet 50 pour Keras (API de Tensorflow) qui est utilisé pour la reconnaissance d'image. | ||
+ | Finalement, peut-être qu'en prenant assez d'images de notre circuit et en les labellisant correctement (présence du mur ou non), nous n'aurions pas besoin d'un modèle. | ||
+ | Il devra donc ressortir deux informations, un x et un y (qui correspondent à la direction qu'il devra prendre) qui seront ensuite envoyés à l'arduino et ensuite aux moteurs. | ||
+ | |||
+ | Une autre solution que nous avons est de labelliser chaque image en lui donnait une valeur x et y. | ||
+ | Ces valeurs correspondent à la direction que le robot devra prendre pour suivre le circuit s'il se trouve dans cette position. Avec un assez grand nombre d'images, nous pourrons peut être sortir un modèle qui nous renvoie un x et un y en fonction de ce qu'il voit. | ||
+ | |||
+ | Nous commençons donc par tester cette dernière solution. | ||
+ | |||
+ | Nous nous renseignons sur ce qui a déjà été fait. Nous trouvons le wiki de Brandon et Hugo qui ont utilisé le deep learning pour leur voiture (p14 : Ironcar). Nous comprenons mieux la démarche à suivre et à appliquer pour le Centaure. | ||
+ | |||
+ | Nous devons donc : | ||
+ | |||
+ | *Prendre en photos un parcours | ||
+ | *Labelliser ces photos, en fonction de la direction que doit prendre le robot s'il se trouve dans cette situation | ||
+ | *Récupérer les photos et les labels | ||
+ | *Pré-traiter les données | ||
+ | *Construire le modèle avec les différentes couches | ||
+ | *Entraîner le réseau avec ces données | ||
+ | *Valider le modèle avec des photos choisies pour la validation | ||
+ | *Modifier le réseau pour avoir un meilleur taux de bonnes réponses | ||
+ | *Evaluer notre réseau avec d'autres photos de ce circuit | ||
+ | |||
+ | |||
+ | Nous validons notre modèle avec des photos différentes de celles pour l'évaluation pour éviter le surapprentissage. | ||
+ | En effet, à force de modifier notre modèle pour avoir un meilleur taux de réussite, on risque de trop coller notre modèle à notre échantillon, et non à l'ensemble des valeurs possibles. | ||
+ | Nous aurions donc un bon modèle pour nos échantillons, mais pas un bon modèle pour l'ensemble. | ||
+ | |||
+ | Nous visualisons les images que l'on a récupérées et converties en tableau Numpy. Nous commençons les tests de traitement des images avec des images ne concernant pas le circuit. Nous obtenons : | ||
+ | |||
+ | [[Fichier:Photo_avant.PNG|600px]] | ||
+ | |||
+ | Lorsque l'on pré traite ces images, on obtient : | ||
+ | |||
+ | [[Fichier:Photo_apres.PNG|150px]] | ||
+ | |||
+ | Nous avons passé l'échelle qui allait de 0 à 255 à une échelle allant de 0 à 1. | ||
+ | |||
+ | |||
+ | ''' Interaction Homme-Machine ''' | ||
+ | |||
+ | Ajout d'une fonction vocale au robot, reposant sur la libSDL-mixer. Nous sommes ainsi capable de charger des mp3 et de les lancer à différents moments afin d'interagir avec le robot (lors du lancement ou de la détection d'un visage par exemple). Pour plus de réalisme nous créons une animation de la bouche à l'aide d'un sprite (comme dans les jeu vidéo). | ||
+ | |||
+ | [[Fichier:SpriteExemple.png|center]] | ||
+ | |||
+ | Il est donc nécessaire de savoir durant combien de temps nous devons animer la bouche. Une relation mathématiques entre la taille d'un mp3 et sa durée nous permet d'établir ce temps : | ||
+ | |||
+ | $biterate = $kilobitrate*1024; | ||
+ | $taille = filesize("a.mp3")*8; | ||
+ | $seconde = $taille/$biterate; | ||
+ | |||
+ | Lors du lancement d'un mp3, une durée est calculée à partir de sa taille, durant ce laps de temps, un booléen 'mp3' passe à 1 et permet ainsi l'animation de la bouche dans le thread dédié | ||
+ | |||
+ | [[Fichier:CentaureIHM.mp4|center|500px]] | ||
+ | |||
+ | '''Reconnaissance Vocale ''' | ||
+ | |||
+ | Après différents tests effectués, le passage de la reconnaissance vocale en Français est plus compliqué que prévue. | ||
+ | |||
+ | Parallèlement nous avons trouvé un autre projet gitHub "Jarvis", projet créé par un français dont la dernière mise à jour date d'il y a 2 ans. | ||
+ | Jarvis est un assistant vocal ultra-léger et multilingue (notamment Français). Il a été imaginé pour la domotique et peut notamment tourner sur des systèmes très léger (ex: Raspberry Pi). Il dispose d’une reconnaissance et d’une synthèse vocale. | ||
+ | |||
+ | Un autre point fort de ce projet est qu'il dispose d'une interface qui est utilisée pour mettre à jour le projet, installer les différents prérequis, ajouter de nouvelles commandes ou encore entraîner la reconnaissance de nouveaux mots. | ||
+ | |||
+ | Ce projet est parfait pour notre application car il est tout d'abord très facile à utiliser et à prendre en main et est extrêmement personnalisable via l'ajout de commande à exécuter ou l’entraînement de nouveaux mots à reconnaître. | ||
+ | |||
+ | De nombreux tutos sont disponibles et le créateur de ce projet en propose quelques-uns ce qui nous permettra de comprendre rapidement le projet. | ||
+ | De plus ce projet nous laisse le choix sur le moteur de reconnaissance (google, bing, snowboy et pocketsphinx) mais aussi sur le moteur de synthèse vocale (Speech engine et OSX voice). | ||
+ | |||
+ | L'assistant vocal Jarvis fonctionne sur un principe de "mot magique". | ||
+ | Tant que le mot magique (dans notre cas "Centaure") n'a pas clairement été entendu le programme ne peut effectuer des actions à la suite de commande vocale et reste dans l'attente du mot magique. | ||
+ | |||
+ | Ces commandes sont situées dans le fichier jarvis-commands, ce fichier est très facile à modifier et peut notamment être consulté depuis l'application. | ||
+ | Depuis l'application nous pouvons également entraîner la reconnaissance vocale des ordres. | ||
+ | |||
+ | Voici un premier exemple de l'utilisation de l'assistant vocal : | ||
+ | |||
+ | [[Fichier:Centaure_V1.mp4|center|500px]] | ||
+ | |||
+ | ''' OpenCV Kinect ''' | ||
+ | |||
+ | Une version du code d'analyse d'image est importée sur l'archive 'CentaureIHM' afin de tester le bon fonctionnement de la liaison IPC entre le processus d'affichage du robot (./Centaure) et le processus d'analyse d'image (./VideoAnalysis). Nous rencontrons cependant des problèmes avec notre liaison IPC qui semble se figer sous certaines conditions pour des raisons inconnues. Cela met à mal le suivi du regard par le robot. Nous cherchons la source du problème. | ||
+ | |||
+ | La libfreenect et le code correspondant sont rapatriés dans l'archive 'CentaureIHM'. Le format vidéo de la kinect ne correspond pas au format vidéo attendu par la libOpenCV, il est donc nécessaire d'implémenter une fonction de conversion de la matrice image au sein du code de la kinect. L'idée est ensuite d'envoyer un pointeur de cette matrice en IPC au code d'analyse d'image sous openCV pour y détecter des visages ou des formes. | ||
+ | |||
+ | |||
+ | '''Open CV :''' | ||
+ | |||
+ | Après ces semaines de tests sur la librairie Open CV, nous avons remarqué qu’en fonction de la luminosité et l’inclinaison d’une caméra, la détection d’une forme variait énormément. Nous pensons donc que la détection d’une forme au sol à longue distance sera très difficile. Nous avons donc décidé de plutôt détecter une couleur (une couleur pourra être attribuée à chaque bâtiment) pour savoir dans quelle direction nous devons aller. Notre travail de cette semaine sera d’implémenter un programme et de le tester afin d’en vérifier la légitimité et de prendre une décision à la suite de cela. | ||
+ | |||
+ | Nous avons voulu commencer par écrire un programme pouvant repérer les objets de couleurs rouges, pour ce faire nous avons fait des recherches sur les fonctions nous permettant de filtrer les couleurs non désirées. Nous avons découvert que la fonction « inRange » pouvait ne garder que les objets étant dans une certaine plage de couleurs sélectionnée sur une image. Après l’utilisation de cette fonction, nous utilisons la fonction « GaussianBlur » qui réalise un flou gaussien sur notre image pour réduire les perturbations. Une fois cela effectué, nous utilisons la fonction « findContours » pour détourer tous nos objets et stocker leurs paramètres dans un tableau, cela nous permet de récupérer les coordonnées de tous les objets rouges détectés. | ||
+ | |||
+ | |||
+ | <gallery width=500px> | ||
+ | File:Exemple_detect_rouge_1.png|Détection des objets rouges | ||
+ | File:Exemple_detect_rouge_2.png|On ne garde que les contours de ces objets | ||
+ | </gallery> | ||
+ | |||
+ | Nous avons ensuite implémenté la partie permettant de déterminer un point central à tous les objets trouvés. Pour vérifier que nos coordonnées sont bonnes, nous traçons un cercle au centre de tous les objets trouvés. Nous avons ensuite trouvé les coordonnées du centre de la somme des objets trouvés mais après réflexion il ne faudrait garder que les objets proches et non tous les objets de l’image, cela nous permettra de trier si une couleur similaire est présente dûs aux étudiants, meubles, etc. | ||
+ | |||
+ | <gallery width=500px> | ||
+ | File:Exemple_detect_rouge_3.png|On affiche un cercle au centre des objets rouges | ||
+ | File:Exemple_detect_rouge_4.png|On affiche un cercle au centre de la somme des objets rouges | ||
+ | </gallery> | ||
+ | |||
+ | |||
+ | Une fois une couleur détectée, nous pouvons partir du principe qu’elle peut nous guider vers un bâtiment spécifique mais le robot ne sera pas toujours positionné au même point (Hall de Polytech), nous avons décidé de placer une deuxième couleur à coté de la première permettant donc de savoir dans quel bâtiment nous sommes, et vers quel bâtiment nous nous dirigeons. | ||
+ | [[Fichier:Exemple_detect_couleur.png|center|500px]] | ||
+ | |||
+ | Par exemple, comme vous pouvez le voir sur l'image au dessus, la couleur bleu pourrait nous servir à nous diriger vers le hall de polytech, la rouge vers le bâtiment A, la verte vers le bâtiment B et la jaune vers le bâtiment C. | ||
+ | |||
+ | |||
+ | |||
+ | DepotGit : https://archives.plil.fr/lringot/Centaure_IHM.git | ||
+ | |||
+ | === Interruption pédagogique === | ||
+ | |||
+ | ''' Intelligence artificielle ''' | ||
+ | |||
+ | Le circuit sur lequel nous allons entraîner notre réseau est le suivant : | ||
+ | *Aller du bout du couloir vers la chambre au fond à droite | ||
+ | |||
+ | Pour cela, nous prenons des photos du circuit dans 5 directions : | ||
+ | |||
+ | *Gauche | ||
+ | *Diagonale gauche | ||
+ | *Tout droit | ||
+ | *Diagonale droite | ||
+ | *Droite | ||
+ | |||
+ | Pour attribuer un label à chaque image, nous les renommons en fonction des coordonnées du joystick virtuel pour chacune des directions. Par exemple, pour aller à gauche, la position du joystick est (0,63). Pour ces 5 directions, nous avons 5 x différents. Nous utilisons donc uniquement la valeur de x pour labelliser les images. Nous pourrons ensuite lui associer la valeur de y correspondant. | ||
+ | |||
+ | Lorsque nous chargeons les 365 images dans google colab, cela prend énormément de temps (environ 2 heures). À chaque fois que l'on quitte la page, il faut à nouveau importer les fichiers. Aussi, lorsque l'on ajoute ces images converties en numpy array dans le tableau, nous dépassons la RAM autorisée par google colab qui est de 25 Go. Notre sessiosn crash donc. Nous cherchons un moyen de redimensionner les images. | ||
+ | |||
+ | Une fois les images redimensionnées, et traitées, nous pouvons commencer la construction du modèle. | ||
+ | Nous essayons deux modèles. Nous trouvons le premier sur le site tensorflow.org. Nous trouvons sur ce sites de nombreux tutoriels, dont un qui explique comment réaliser un réseau de neurones dans la classification d'images. L'exemple utilisé est la reconnaissance de la catégorie d'un vêtement (robe, pull, etc..). | ||
+ | |||
+ | Voici le modèle utilisé : | ||
+ | |||
+ | model = keras.Sequential([ | ||
+ | keras.layers.Flatten(input_shape=(1356,1017,3)), # reformate les données (d'un tableau à 3 dimensions en un tableau à 1 dimension, nos images étant de dimension 1356x1017x3) | ||
+ | keras.layers.Dense(128, activation='relu'), | ||
+ | keras.layers.Dense(128) | ||
+ | ]) | ||
+ | |||
+ | Nous compilons ensuite le modèle : | ||
+ | |||
+ | model.compile(optimizer='adam', | ||
+ | loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), | ||
+ | metrics=['accuracy']) | ||
+ | |||
+ | |||
+ | [[Fichier:Modele_fit.PNG|600px]] | ||
+ | |||
+ | [[Fichier:Precision.PNG|500px]] | ||
+ | |||
+ | |||
+ | Une fois le modèle entraîné une première fois, nous obtenons un taux de précision de 81% | ||
+ | |||
+ | Les difficultés rencontrées pour arriver à entraîner ce premier réseau sont : | ||
+ | *La mise en forme des images, sous le bon type | ||
+ | *La bonne dimension des images | ||
+ | *Le bon nombre de nœuds en sortie. Nous avons 5 valeurs possibles mais qui se trouvent dans l'intervalle [0,127]. Pour le modèle finale, nous réfléchirons à un moyen d'avoir 5 valeurs dans un intervalle de [0,5] et d'en restituer la valeur initiale de x. | ||
+ | |||
+ | L'étape suivante est de vérifier les prédictions de ce modèle (évalué à 81% de prédiction). | ||
+ | |||
+ | Pour cela, nous prenons de nouvelles photos de ce circuit. Nous les labellisons aussi pour pouvoir vérifier plus facilement les prédictions. Ensuite, nous demandons à notre modèle de nous donner la direction à prendre en fonction de l'image reçue (contenues dans tab_img_val). | ||
+ | |||
+ | probability_model = tf.keras.Sequential([model, | ||
+ | tf.keras.layers.Softmax()]) | ||
+ | |||
+ | predictions = probability_model.predict(tab_img_val) | ||
+ | |||
+ | Voici un échantillon des prédictions que nous obtenons : | ||
+ | |||
+ | [[Fichier:Predictions.PNG|1000px]] | ||
+ | |||
+ | La légende correspond à : direction choisie par le modèle, précision de cette prédiction, direction qu'il devait choisir. | ||
+ | En bleu, les bonnes prédictions et en rouge, les mauvaises. | ||
+ | |||
+ | Pour avoir une meilleure précision, nous pouvons essayer un autre modèle, ou augmenter le nombre d'images utilisées pour entraîner le modèle (ici, 365 images). | ||
+ | |||
+ | |||
+ | ''' Détection de couleurs pour guider le robot : ''' | ||
+ | |||
+ | Nous continuons notre avancé en implémentant une fonction permettant de détecter une deuxième couleur en partant de la même base que la détection de la couleur rouge. | ||
+ | |||
+ | On améliore notre fonction de détection de couleurs en ne prenant en compte que les objets ayant un certains nombres de points (donc une surface minimale) qui composent son contour pour réduire les perturbations. | ||
+ | |||
+ | On implémente ensuite un algorithme permettant de diriger le robot en fonction du sens des couleurs. On compare le barycentre des couleurs détectées et en comparant les deux on obtient un angle. Ce qui nous | ||
+ | |||
+ | permet de déterminer un sens de déplacement pour le robot. | ||
+ | |||
+ | [[Fichier:detect_couleur_2.mp4|center|500px]] | ||
+ | |||
+ | Nous améliorons ensuite le programme en n'utilisant qu'une seul fonction pouvons détecter n'importe quel plage de couleur passé en paramètre. | ||
+ | |||
+ | === Semaine 14 === | ||
+ | |||
+ | '''Intelligence artificielle ''' | ||
+ | |||
+ | Maintenant que nous avons un modèle fonctionnel, nous devons l'intégrer dans le Centaure. | ||
+ | Pour cela, nous devons enregistrer le modèle. Ainsi, on pourra utiliser ce modèle sans avoir à l'entraîner de nouveau avec les 365 images. Pour cela, nous enregistrons le modèle sous le format HDF5. Voici les commandes à faire : | ||
+ | |||
+ | pip install -q pyyaml h5py # Required to save models in HDF5 format | ||
+ | model.save('circuit1.h5') | ||
+ | from google.colab import files | ||
+ | files.download('circuit1.h5') | ||
+ | |||
+ | Nous pourrons donc copier ce circuit dans un dossier sur le PC du Centaure. Ainsi, notre code pourra aller cherche le bon circuit en fonction de la destination demandée. | ||
+ | Ensuite, nous devons récupérer les images de la kinect, préalablement convertie avec OpenCV. On enregistrera une image sur 10 ou sur 20 pour laisser le temps au programme de fonctionner tout en permettant un déplacement fluide. Il faudra prendre en compte les paramètres de conversion utilisé pour construire le modèle. En effet, les images utilisées pour construire le modèle et celles que nous utilisons pour les prédictions doivent être de dimensions similaires. | ||
+ | |||
+ | Enfin, il faut envoyer la direction que le robot doit prendre suite à la prédiction du modèle. Pour cela, nous communiquons entre le PC et l'arduino via liaison série. Ainsi, nous enverrons des trames de la forme 1xxx xxx pour indiquer la coordonnée X, et 0xxx xxx pour indiquer la coordonnée Y. | ||
+ | |||
+ | Dans ce modèle, nous ne prenons pas en compte la vitesse du robot. En effet, les valeurs de X et Y choisies correspondent à la vitesse maximale du robot. Il faudrait très certainement choisir d'autres labels pour les vrais circuit au sein de Polytech, ou de convertir ces coordonnées pour qu'elles correspondent à la même direction mais avec une vitesse inférieure pour éviter un déplacement trop brutal. | ||
+ | |||
+ | Nous ne pourrons malheureusement pas tester cette solution sur le Centaure. | ||
+ | |||
+ | |||
+ | ''' Interaction Homme-Machine ''' | ||
+ | |||
+ | Pour une interaction plus "réaliste" et plus immersive, on améliore l'interface graphique en implémentant différentes humeurs pour le robot (Souriant, triste, colérique). Ces éléments servent surtout à poser les bases dans le but de créer une interface plus ludique. Une variable "humeur" est donc ajoutée dans le programme. En la modifiant, on modifie l'humeur de notre robot à l'écran. | ||
+ | Les sprites utilisé pour l'animation du robot sont donc adaptés, on passe de sprite 1D à des sprites 2D. Ainsi, chaque ligne correspond à une humeur. | ||
+ | |||
+ | [[Fichier:Spriteschem.png|300px|center]] | ||
+ | |||
+ | Des sprites pour les yeux sont également crées. | ||
+ | |||
+ | On peut donc ainsi obtenir des animations de ce type : | ||
+ | |||
+ | [[Fichier:HumeurCentaure.mp4|400px|center]] | ||
+ | |||
+ | |||
+ | ''' Demonstration du Centaure qui roule ''' | ||
+ | |||
+ | [[Fichier:CentaureRoule.mp4|400px|center]] | ||
===Documents Rendus=== | ===Documents Rendus=== | ||
+ | |||
+ | Présentation PowerPoint : [[:Fichier:Presentation_Projet_Centaure.pdf|Presentation_Projet_Centaure]] | ||
+ | |||
+ | Rapport final : [[:File:Rapport_Centaure.pdf|Rapport_Centaure.pdf]] | ||
+ | |||
+ | Guide de démontage Robot Centaure : [[:File:Guide_Pratique_-_Demontage_Centaure.pdf|Guide_Pratique_-_Demontage_Centaure.pdf]] | ||
+ | |||
+ | Guide des composants du robot : [[:File:Guide_Composants_Centaure.pdf|Guide_Composants_Centaure.pdf]] | ||
+ | |||
+ | Dépôt git regroupant la partie deep learning : https://github.com/ValerianeSlge/Centaure.git | ||
+ | |||
+ | Dépôt git regroupant le reste du software (+ le code arduino) : https://archives.plil.fr/lringot/Centaure_IHM.git |
Version actuelle datée du 21 septembre 2020 à 13:55
Sommaire
- 1 Présentation générale
- 2 Analyse du projet
- 3 Préparation du projet
- 4 Réalisation du Projet
- 4.1 Projet S6
- 4.2 Projet S7
- 4.3 Projet S8
- 4.3.1 Bilan de la soutenance du S7 :
- 4.3.2 Début du S8:
- 4.3.3 Semaine 2 :
- 4.3.4 Semaine 3 :
- 4.3.5 Semaine 4 :
- 4.3.6 Semaine 5 :
- 4.3.7 Bilan de mi-semestre
- 4.3.8 Semaine 6: (04/03)
- 4.3.9 Semaine 7: (11/03)
- 4.3.10 Semaine 8: (18/03)
- 4.3.11 Semaine 9: 25/03
- 4.3.12 Semaine 10 : 01/04
- 4.3.13 Semaine 11: 08/04
- 4.3.14 Interruption pédagogique
- 4.3.15 Semaine 14
- 4.3.16 Documents Rendus
Présentation générale
Description
Aujourd’hui la qualité de l’air et plus globalement la pollution atmosphérique est un enjeu environnemental majeur, notamment dans le cadre du travail. Ce danger fait l’objet de préoccupations depuis plusieurs années et apparaît aujourd’hui comme un problème majeur de santé publique. Notre projet à pour objectif de répondre à cette problématique en proposant une analyse en temps réel de la qualité de l’air des locaux de Polytech. En effet, l’amélioration de la qualité de l’air passe en premier lieu par l’étude de celle-ci, il est primordial de connaître notre environnement avec précision.
Objectifs
Analyse du projet
Positionnement par rapport à l'existant
Analyse du premier concurrent : Pepper
SoftBank Robotics est une société de robotique japonaise parmi les leaders mondiaux dans le domaine de la robotique humanoïde. Ils ont de nombreux clients comme par exemple Renault, BMW, Carrefour... Son affiliation avec une banque lui permet de bénéficier de gros apports financiers pour la conception de leurs robots. En 2014, le robot Pepper est lancé. Il doté d'un écran et de caméras pour intéragir avec son entourgae. Par exemple, il reconnait les visages et les émotions. Il peut communiquer grâce à son écran tactile et la parole grâce à la synthèse vocale.
Points forts | Points faibles |
---|---|
|
|
Caractéristiques techniques:
- Dimensions (en cm): 120 x 42.5 x 48.5
- Poids: 28 kg
- Charge utile: 500g à bout de bras
- Automonie: environ 12h
- Vitesse max: 5km/h
https://www.softbankrobotics.com/emea/fr/pepper
Analyse du second concurrent : Heasy
Notre deuxième concurrent est la compagnie HEASE Robotics créée en 2016, qui se situe à Villeurbanne, près de Lyon. Cette compagnie s’attache particulièrement au marché des robots de service professionnel dans les domaines du retail et de la relation client avec son robot HEASY. Ce robot est présent dans des environnements tels que des centres commerciaux, des aéroports, des gares ou encore des entreprises. Il est capable de divertir, de guider, d'accueillir et de donner des informations simples aux clients, pour des informations plus complexes il met directement le client en relation avec un agent d'accueil. Avec la possibilité d’une mise en place d’un ensemble de robot HEASY dans un de ces lieux, l’agent d'accueil pourrait alors voir ses capacités démultipliées.
Points forts | Points faibles |
---|---|
|
|
https://heaserobotics.com/heasy-for-retail/
Analyse du troisième concurrent : Keylo
Wycas Robotics est une start up toulousaine lancée en octobre 2015,qui développe des solutions d'accueil et d'assistance physique du client à distance. La start up commercialise Keylo, un robot d'accueil à navigation autonome qui accompagne le visiteur dans les centres de stockage et le met en relation avec des téléopérateurs par visioconférence. Après avoir fait une levée de fonds de 350 000 euros auprès de ses actionnaires, la société à décidée d'exporter son robot Keylo dans le milieu médical. Dans cette situation le robot sera destinée à l'accueil et au service du patient en milieu hospitalier. Dressé sur roues, Keylo se déplace grâce à un laser complété par une caméra 3D et un odomètre.
Points forts | Points faibles |
---|---|
|
|
Scénario d'usage du produit ou du concept envisagé
Le robot envisagé se présenterait à l'accueil de l'école. Comme souvent, des intervenants extérieurs viennent faire des présentations. Il peut être difficile de trouver certaines salles quand on ne connaît pas l'école. C'est à ce moment là que le robot Centaure intervient. Le visiteur se dirige vers le robot. Ce-dernier va le repérer et lui proposer ses services (indiquer le chemin ou guider la personne jusqu'à la salle). Le visiteur sélectionne le service souhaité (directement sur l'écran ou vocalement).
- Dans le premier cas, il affiche le plan de l'école et décrit l'itinéraire.
- Dans le second cas, il accompagne la personne jusqu'à la destination souhaitée en empruntant le chemin le plus adapté (prendre l'ascenseur, éviter les couloirs bondés).
Une fois la mission accomplie, il retourne à l'accueil, prêt à accueillir une nouvelle personne. Il peut aussi recevoir une requête d'une personne perdue dans Polytech via le site internet du robot.
Réponse à la question difficile
Questions difficiles :
Comment le robot gère t-il l'ascenseur?
Dans l'idéal, pour accompagner au mieux les personnes, c'est le robot qui appuie lui même sur le bouton de l'étage où la personne veut aller. Pour cela, il lui faudrait un bras robotisé muni de moteurs et de capteurs pour appuyer sur les boutons. Il faudrait donc pouvoir repérer les boutons des ascenseurs à l'aide d'une caméra et savoir s'il est bien déclenché. Cela représente trop de complications et ce n'est pas le but principal du robot. La fonction principale du robot est de guider la personne jusqu'à la salle demandée. La robot demandera donc simplement à la personne d'appuyer sur le bon bouton. Cependant, il se peut que la personne comprenne mal le robot ou appuie sur le mauvais bouton. Le robot doit donc vérifier qu'il est bien au bon endroit. Pour cela, nous allons utiliser des QR codes qui seront présents à la sortie de chaque ascenseur en indiquant l'étage et le bâtiment. On utilisera ce même système pour s'assurer que le robot est arrivé à la bonne salle.
Bibliographie et webographie
Site robot Pepper : https://www.softbankrobotics.com/emea/fr/pepper
Site robot Heasy : https://heaserobotics.com/heasy-for-retail/
Site robot Keylo : http://www.wyca-robotics.com/
Préparation du projet
Cahier des charges du groupe
La mission du robot Centaure est de guider une personne dans Polytech jusqu'à la salle requise. Pour cela, le robot doit prendre contact avec la personne. Il repère la personne ou cette dernière interagit avec lui à l'aide de l'application/site Web et lui donne sa requête (le conduire à telle salle ou lui indiquer le chemin à prendre pour rejoindre telle salle). Soit le robot affiche la carte de l'école sur l'écran, soit il conduit la personne à la salle. Pour cette dernière mission, le robot va se déplacer de manière autonome dans Polytech jusqu’à la salle. Il va se repérer dans l'espace grâce à des capteurs et des qr code disposés dans l'école. Il pourra ainsi prendre l'ascenseur et s'assurer qu'il est au bon endroit.
Objectif du semestre 6:
Nous devons faire le bilan technique du robot et analyser les améliorations que nous pouvons apporter comme par exemple réorganiser la partie mécanique. Nous devons aussi pouvoir utiliser la kinect pour lire des QR codes et faire en sorte que le robot se déplace de manière autonome à l'aide de ses capteurs.
- Repérage dans l'espace
- Utiliser différents capteurs: Ne pas heurter les utilisateurs
- Cartographier l'école avec les différentes positions des salles (QR code ascenseur, triangularisation pour la position)
- Effectuer le déplacement vers les salles
- Communication extérieure
- Gestion de la synthèse vocale
- Créer une interface Homme/Machine
Cahier des charges des équipes
Equipe 1 : Théo et Valériane: Communication extérieure
Notre équipe s'occupe de la communication du robot avec les personnes qui l'entourent. Nous allons gérer la partie interaction du robot en réalisant une reconnaissance vocale et une synthèse vocale. On s'occupera aussi de l'affichage sur l'écran intégré au robot. On affichera des informations diverses sur les services qu'il propose (affichage d'une carte interactive, choix de la salle à atteindre).
Equipe 2 : Corentain et Loïc
Notre équipe s'occupant du traitement des images renvoyées par la Kinect nous devront apprendre à utiliser la librairie C libfreenect ce qui nous permettra d'analyser les informations reçues par la Kinect.
Nous devrons donc réussir à repérer un visage qui se trouvera devant la Kinect mais aussi repérer les différents QR code disposés dans l'école par l'équipe 3 et utiliser les informations qu'ils donneront.
Equipe 3 : Thibault et Pierre
- Savoir se repérer dans l'espace à l'aide d'une triangulation par le Wi-Fi de Polytech et un système odométrique.
- Savoir recalibrer sa position en lisant des balises placées dans Polytech.
- Eviter les obstacles ou s'arrêter en cas d'urgence.
- Calculer un itinéraire afin de trouver le chemin le plus court.
Choix techniques : matériel et logiciel
Equipe 1
- Ecran:
- Ecran actuel non tactile (à changer ?)
- Synthèse vocale:
- Haut parleur
- Logiciel :
- Reconnaissance vocale:
- Utilisation de la reconnaissance vocale de la Kinect
Equipe 2 : Loïc et Corentain
Matériel :
- D'une Kinect
Logiciel :
- Nous utiliseront seulement de la programmation en C ainsi que la librairie libfreenect pour l’analyse et le traitement d’image.
Equipe 3
Logiciel : https://www.indooratlas.com/
QR code
Kinect
Liste des tâches à effectuer
Equipe 1: Communication extérieure
Notre équipe s'occupe de la communication entre le robot et l'utilisateur. Cela se fera par l'intermédiaire de l'écran, d'un site internet ou application et d'une synthèse vocale.
- Ecran:
- Affichage d'un visage, animation de celui-ci
- Affichage du texte
- Affichage de la carte de l'école
- Synthèse vocale:
- Prise de contacte avec l'humain
- Donner des indications de parcours
- Plusieurs langues disponibles
- Reconnaissance vocale:
- Micro pour entendre la requête de l'humain
- Plusieurs langues reconnues
- Site internet / application
- Soumettre des requêtes au robot
Equipe 2 : Loïc et Corentain
Notre équipe s'occupant du traitement des images renvoyées par la Kinect nous devront mettre en place :
- Le repérage d'une ou de plusieurs personnes se situant devant l'écran.
- Le scan des QR codes présent dans Polytech
Equipe 3
Notre équipe s'occupera de la partie déplacement du robot :
- Cartographier l'école Polytech
- Définir des zones de tags
- Effectuer un déplacement vers un endroit précis
Calendrier prévisionnel
Le calendrier prévisionnel peut se concrétiser sous la forme d'un diagramme de GANTT.
Réalisation du Projet
Projet S6
Eventuellement créer des sous-pages par équipe avec le compte-rendu des réunions de groupe sur cette page principale.
Semaine 4
Lors de cette séance, nous avons établi le cahier des charges par équipe pour nous répartir le travail. Nous avons ensuite rédigé le calendrier prévisionnel complet pour le projet.
Semaine 5
Nous avons profité de cette séance pour prendre connaissance de l'avancement des IMA 5 sur le projet. Nous avons discuté avec eux des différentes spécificités du robot (allumage du robot, présence du bouton d'urgence, problème avec l'écran..). Nous avons aussi récupéré les différents documents présentant le robot (rapport de PFE, codes du robot et du site) pour être complètement autonome lors du départ des IMA5.
Semaine 6
Le projet IMA5 étant terminé, nous allons pouvoir commencer à prendre en main le robot. Nous avons tout d'abord essayé de l'allumer. Cependant, lors de la démonstration des IMA5, ils avaient modifié le code pour commander le robot avec le site web. N'ayant pas encore les bonnes configurations pour utiliser le site web, nous avons modifié le code pour remettre par défaut la liaison série. Lors du démarrage, nous avons remarqué un dysfonctionnement au niveau de la roue droite. Après vérification des branchements, nous avons remarqué un faux contact au niveau du variateur de vitesse. Après avoir resserré le câble, la roue tournait. Il ne restera plus qu'à gonfler les pneus et améliorer la direction. En effet, il ne suit pas exactement les directions qu'on lui donne.
Semaine 7
Prise en main du projet. Nous avons remplacé l'écran de base qui s'éteignait au bout de 10 secondes par un autre. Mais le problème persiste. On pense à un problème d'alimentation car lorsque l'on branche un écran alimenté sur secteur, tout fonctionne. Ensuite, nous avons décidé d'installer l'IDE Arduino directement sur le robot pour simplifier la programmation de ce dernier.
Semaine 8
Comme le problème de l'écran n'était pas encore résolu, nous nous sommes concentrés sur celui-ci. Durant la séance, nous avons remarqué que l'écran ne s'éteignait pas, mais c'était le rétroéclairage de l'écran qui diminuait considérablement après quelques secondes. Nous avons donc mesuré la tension d'entrée de l'écran et nous nous sommes rendu compte que cette tension était égale à 11,7V. Nous avons donc testé l'écran sur secteur et nous avions bien une tension de 12,4V. L'écran était donc sous alimenté, ce qui explique la diminution du rétroéclairage de l'écran. Après avoir lu la datasheet du convertisseur DC/DC RSD-150-B-12, nous avons décidé de l'utiliser pour le robot, car celui là délivre une tension modulable. En parallèle, nous avons remarqué que le câblage interne n'était pas assez organisé pour pouvoir manipuler l'intérieur du robot avec aisance. En effet, les câbles prenaient beaucoup de place dans le robot, ce qui fait que nous ne pouvions pas accéder correctement aux différents ports du PC. Nous avons donc décidé de réorganiser le câblage interne.
Semaine 9
Nous avons commencé par réaliser des schémas de câblage et étiqueter les câbles que nous allons réutiliser lors du nouveau câblage. Nous avons aussi commencé à prendre en main la kinect et à se renseigner sur son fonctionnement.
Semaine 10
Nous avons lancé la commande du convertisseur DC DC pour l'alimentation de l'écran. Nous avons divisé le groupe pour s'occuper des deux enjeux majeurs: refaire une carte PCB sur Altium dans le but d'améliorer le câblage et réaliser la synthèse et la reconnaissance vocale. Pour la carte PCB, nous voulons utiliser des borniers pour les pins pour que le câblage soit plus propre et plus solide.
Semaine 11
HARDWARE:
Nous avons reçu le nouveau convertisseur DC DC. Nous avons procédé à des test de celui-ci. Il semble chauffer un peu trop (Pierre a dit: "On a dead ça")
Le nouveau convertisseur alimente l'écran correctement, en un peu plus de 13V, cela corrige le problème de luminosité de l'écran, cependant après quelques minutes de la fumée semble se dégager du robot. A la vue de l'inquiètante fumée se dégageant du robot, nous décidons de procèder au décablage complet dans le but d'identifier les éventuels éléments ayant brûlés. De plus le décablage complet du robot nous permettra de mieux comprendre le fonctionnement de celui-ci et de procéder à un recâblage plus propre.
SOFTWARE:
Des recherches sont effectuées dans le but de trouver et comprendre le fonctionnement d'une synthèse vocale. Le système MaryTTS semble être un bon candidat, cependant nous ne parvenons pas à l'installer. Nos recherches continuent donc dans le but de trouver une synthèse vocale si possible codée en C.
Semaine 12
HARDWARE Finition de la dissection du robot, cette manipulation nous prend du temps, en effet chaque câble retiré est retranscrit sur un schéma de câblage, dans l'espoir d'être capable de remonter le robot. Les couleurs correspondent aux vraies couleurs des câbles et ne respectent pas les couleurs conventionnelles.
En parallèle on commence la conception d'un nouveau shield sur le logiciel Altium. L'objectif de ce nouveau shield est de permettre l'utilisation de borniers pour maintenir les différents câbles et ainsi obtenir un câblage plus propre et plus sécurisé. Cependant notre méconnaissance du logiciel Altium complique cette tâche. Découverte du site snapeda pour télécharger les empreintes des borniers que nous allons utiliser car ils ne sont pas présents dans la bibliothèque de base.
SOFTWARE Les recherches d'une synthèse vocale continuent.
https://community.gladysassistant.com/t/tutoriel-gladys-et-la-reconnaissance-vocale/1419
Semaine 13
Nous avons entièrement démonté la partie supérieure du robot pour s'assurer qu'il n'y avait pas de câbles défecteux qui auraient pu causer la fumée. Dans un même temps, nous faisons des tests avec la Kinect pour comprendre le fonctionnement et réussir à utiliser la caméra pour la future reconnaissance faciale et le micro pour la future reconnaissance vocale. Cependant, après quelques échecs, on se demande s'il ne faudrait pas plutôt utiliser une simple webcam à la place de la kinect.
Semaine 14
Nous travaillons sur la nouvelle carte PCB, cependant, nous avons uniquement pu récupérer le fichier .PCBdoc des IMA5 sans leur schematic. Cela ralentit notre progression car cela nous impose l'utilisation du logiciel Altium que nous ne maitrisons pas. Aussi, nous n'arrivons pas à relier le nouveau bornier aux autres composants avec des pistes. Nous demandons l'aide d'Alexandre Boé pour nous expliquer. Le problème venait des noms des pistes qui n'étaient pas les mêmes, donc le logiciel refusait de les relier. Une fois les pistes renommées, nous avons pu relier les anciennes pistes aux nouveaux borniers. Dans un même temps, nous avons réussi à faire fonctionner la caméra de la kinect à l'aide du logiciel freenect. Cependant, nous n'arrivons pas à récupérer le flux vidéo. Nous décidons d'essayer avec une simple webcam et d'OpenCV. Nous n'avons pas réussi à installer complètement sur Linux. En réessayant sur le PC de Théo qui fonctionne sous Windows, on a pu vérifier qu'OpenCV fonctionnait et qu'on arrivait à avoir une reconnaissance faciale qui fonctionne approximativement.
En parallèle, nous nous occupons de la structure du robot. Après avoir démonté l'étage supérieur du robot, nous avons analysé ce qui aurait pu entraîner la création de fumée dans le robot. Comme la fumée semblait venir de l'espace entre les variateurs de vitesse, nous nous sommes dit que cela venait d'un des variateurs. Cependant, en aucun cas le nouveau convertisseur n'était relié aux variateurs et les variateurs n'avaient pas d'anomalies lorsque nous étions avec l'ancien convertisseur DC/DC. La fumée ne venait donc pas des variateurs. Ensuite, nous avons cherché des endroits où il y aurait pu avoir des court-circuits ou des câbles en mauvais état pouvant entraîner une surchauffe de la gaine protectrice des fils électriques. Mais là encore, les câbles n'avaient pas de défauts en particulier. Les seuls câbles étant en mauvais état ont été retirés et changés lorsque nous avons commencé à refaire le câblage de la partie supérieure de l'intérieur du robot.
Semaine 15
En démontant le robot, nous avons remarqué que la kinect était restée branchée. Elle ne doit pas être alimenté en plus de 12V. Cependant, nous lui avons donné du 13,3. Après vérification, la kinect n'est pas endommagé mais le transformateur de l'alimentation ne fonctionne plus. D'après nos observations, il se trouvait à l'endroit d'où venait la fumée. On pense donc que la fumée venait de là. Il faudra analyser le transformateur pour savoir si on peut en faire un nous même.
En parallèle, nous avons programmé la reconnaissance vocale et la reconnaissance faciale que nous voulons utiliser pour le robot. Pour le moment, la reconnaissance vocale fonctionne mais n'est pas assez précise et pour la reconnaissance faciale, la caméra détecte bien les visages. Cependant, elle ne peut pas différencier un visage d'un autre, c'est-à-dire que le logiciel sait qu'il y a un visage en face de lui, mais il ne connait pas l'identité de celui-ci. De plus, il nous reste maintenant à utiliser cette reconnaissance faciale dans un programme qui permette ensuite de faire une interaction avec l'utilisateur.
Nous avons aussi commencé à modifier le programme Arduino du robot. Ce dernier fonctionnait pour une utilisation avec une manette ou via le site Web. Nous avons modifié le code pour qu'il prenne en compte les obstacles dans ces deux cas, mais aussi pour qu'il sache directement si on le commande via la manette ou via le site Web (précédemment, il fallait modifier une variable manuellement dans le code Arduino pour faire le changement de mode). Maintenant, il écoute le port série et s'il ne reçoit rien c'est qu'on le commande via le joystick. Nous allons aussi modifier le code pour intégrer un mode de déplacement autonome. Nous étudions la possibilité de faire aller le robot dans l'autre sens, pour avoir la roue folle à l'arrière et qu'il soit donc plus stable lors de ses mouvements.
Nous avons également fini le nouveau PCB qui nous facilitera grandement les branchements et réduira les risques de faux-contact du à des câbles mal branchées ou autres. Celui-ci reste encore à faire vérifier par M.Boé avant son impression :
Concernant le serveur, pour effectuer des tests sur celui-ci nous avons choisi d'ajouter deux boutons à la page internet, ainsi que de modifier le code en Node.js pour envoyer des caractères sur la liaison série à l'appuie sur ces deux boutons. Nous avons également réaliser un programme simple sur Arduino pour qu'à la réception de ces messages sur son port série il allume ou éteigne une led. Cependant nous rencontrons des difficultés à démarrer le serveur, nous avons donc contacté les IMA5 pour avoir plus d'explications sur son démarrage, nous sommes dans l'attente d'une réponse.
Pour permettre un rendu plus propre, nous avons conçu une boîte à l'aide du logiciel On shape qui intègre le PC et l'arduino.
Bilan
À la fin du semestre, nous pouvons poser un bilan de notre avancement par rapport aux objectifs initiaux. Nous devions réaliser la commande autonome du robot, la reconnaissance et la synthèse vocale et faire en sorte que le robot se repère dans Polytech. En récupérant le robot, ces objectifs ont été modifiés. Nous devions en priorité modifier le câblage de ce robot. Nous avons donc à l'heure actuelle un robot réorganisé et qui contient une reconnaissance vocale et faciale et une synthèse vocale. Un nouveau shield a été réalisé et n'attend que la validation et la disponibilité de la machine pour être fait. Un prototype d'une boîte à été réalisé pour ranger le PC ainsi qui l'arduino, le relai et le disque dur du PC.
Pour l'année prochaine, les objectifs sont d'imprimer le nouveau PCB, rendre autonome le robot et le faire se repérer dans Polytech.
Documents Rendus
Le software: https://we.tl/t-taSvegTQXq
Le rapport : Fichier:Rapport Projet IMA3.pdf
Projet S7
Etat des lieux au début du semestre 7
Nous reprenons le projet Centaure avec des modifications dans l'équipe. Nous accueillons Clément et Samuel. Nous devrons donc premièrement réorganiser les sous équipes. Suite à l'état des lieux, des priorités ont été établies. Les objectifs du semestre 7 pour le projet était principalement d'avoir une base solide sur les différentes parties du robot pour être efficace au semestre 8. Nous devons tout d'abord nous réapproprier le robot et son matériel. Nous récupérons la caisse avec notre matériel que nous devrons trier. Nous devrons ensuite nous concentrer sur la partie mécanique du robot et refaire tout son câblage et finir le shield Arduino pour permettre au robot de rouler à la fin du semestre. Cela nous permettra de réaliser la suite des tâches au semestre suivant. Le câblage fait, nous pourrons travailler sur le déplacement du robot et son repérage dans l'espace. Pour cela, il faudra récupérer des informations grâce à la kinect et relancer le serveur réalisé par le dernier groupe à avoir travaillé sur le projet.
Nous avons choisi d'organiser notre équipe sous 3 pôles : la partie câblage du robot, la partie Arduino/serveur et la partie kinect. En effet, nous ne pouvons pas être 6 à travailler sur le câblage du robot car cela ne serait pas optimal et nous ferait prendre du retard pour le semestre suivant. Voici donc les différentes avancées de ces 3 pôles.
Partie câblage du robot
Au début du semestre, nous récupérons le robot avec le câblage de la fin du semestre 6.
Le premier constat est le manque de schéma de fonctionnement clair. Après avoir parcouru les différents wiki concernant le robot Centaure, nous nous sommes rendu compte qu'il fallait le redéfinir complètement.
En effet, si l'on prend par exemple le schéma électrique de l'année 2017/2018 (Projet P50), nous nous apercevons de la présence d'un étage dédié à la recharge des batteries sur le secteur. Or dans le robot, aucun équipement ne permet cette fonction. De plus, nous utilisons deux convertisseurs de tension (1 pour la Kinect et 1 pour la carte Arduino) ce qui n'est pas le cas sur ce schéma. De par sa caducité, il nous est impossible de l'exploiter. Etant donné les différentes modifications matérielles qui ont été réalisées les dernières années, nous nous basons sur le schéma de l'an dernier pour réaliser le nôtre.
Un deuxième constat s'est fait vis-à-vis du cablâge en place sur le robot.
Nous avons remarqués plusieurs problèmes de fond au câblage :
- fusibles non utilisés,
- gaines des câbles entaillées et "réparées" avec du scotch,
- câbles volants.
Nous pouvons noter le choix peu judicieux de conducteurs rigides, alors qu'il est conseillé d'employer des conducteurs multibrins étant donné l'utilisation visé (Robot mobile).
Enfin, le dernier constat concerne la disposition des éléments dans le robot, certains équipements de sécurité, comme le porte fusible ou le bouton d'arrêt d'urgence n'étaient pas (ou peu) accessibles.
Nous réalisons que nous ne devons pas juste réorganiser le câblage mais bien tout recommencer dès le départ. Nous étudions la manière de réorganiser l'intérieur même du robot. Nous avons pu récupérer les fichier SVG de la plaque de plexiglas qui maintenait les batteries en place. Nous modifions cette plaque pour correspondre à notre nouvelle organisation. Aussi, lorsque nous pourrons réserver un créneau au Fab et que nous aurons reçu le plexiglas, nous découperons cette plaque ainsi que la nouvelle boîte, elle aussi en plexiglas.
Nous sommes aussi en attente de notre commande chez RS pour réaliser le câblage. Nous avons commandé de nouveau variateurs qui prendront beaucoup moins de place dans le robot, ainsi que des goulottes pour passer les câbles plus proprement. Nous sommes donc à la fin du semestre 7 bloqués par les délais de livraison pour finir le câblage.
Partie Arduino/Serveur
Durant ce semestre notre objectif était de reprogrammer la carte Arduino et de remettre en route le serveur pour pouvoir faire rouler le robot. Nous nous sommes donc réparti les tâches : l'un s'occupant de la carte Arduino et l'autre du serveur.
Shield Arduino
Le shield Arduino réalisé en fin d'année passée a été modifié afin de correspondre a nos nouvelles attentes, une fois vérifié il a été imprimé puis brasé. L'impression, le brasage, ainsi que le test de cette nouvelle carte nous aura pris un grand nombre de séance de projet du semestre 7, mais elle est entièrement fonctionnelle.
Carte Arduino
Pour pouvoir programmer la carte Arduino, nous devions savoir comment utiliser les nouveaux contrôleurs moteurs, malheureusement nous ne les avons pas reçu à temps pour commencer à travailler dessus. Mais nous avons commencé le programme en y ajoutant les valeurs reçues par le joystick et les capteurs de distance qui sont d'ailleurs très similaires aux anciens. En effet, nous avons fait le choix de remplacer les anciens capteurs de distance par des nouveaux captant des distances plus faibles et donc plus raisonnable pour éviter les obstacles.
Serveur
Côté serveur nous avons eu beaucoup de mal à remettre en route celui effectué par les IMA5, leurs indications n'étaient pas assez claires et nous avons donc dû faire du débogage. Nous sommes finalement parvenus à le lancer en apprenant à programmer en nodejs . A ce jour nous sommes capables de pouvoir contrôler une carte Arduino en envoyant des données sur le port série grâce au serveur et au client.
Partie Kinect
A la fin du semestre 6, l'équipe avait eu des difficultés à utiliser la kinect et s'était donc rabattu sur une reconnaissance vidéo grâce à une webcam. Cependant nous pensons que l'utilisation d'une kinect est bien plus appropriée à l'utilisation du robot. La kinect nous permettant de reconnaître la présence d'un humain et de déterminer la distance puisqu'elle est dotée de 2 lentilles ainsi que d'un capteur infrarouge. Nous avons donc utilisé le kit de développement logiciel fourni par Microsoft pour adapter les fonctions de la kinect à notre programme. Nous sommes parvenus à avoir un programme qui fonctionne (i.e. reconnaissance de personnes dans le champ de vision, détection d'un obstacle et de la distance à laquelle il se situe). A noter que le robot n'étant pas encore opérationnel, tous ces tests ont été réalisés à partir d'une kinect fixe (donc pas en conditions réelles).
L'objectif est maintenant double:
- Savoir quand un humain souhaite inter-agir avec le Centaure
- Détecter et éviter des obstacles tout en maintenant une trajectoire définie
La kinect étant les yeux de notre robot (les capteurs infrarouges servent eux à avoir une redondance d'information), c'est elle qui doit envoyer des consignes de déplacement à l'arduino.
L'idée est la suivante:
- La kinect envoie un octet au serveur, l'arduino interroge le serveur pour obtenir l'octet envoyé. Cet octet contient une consigne de vitesse ainsi qu'une consigne de direction
Détection/Esquive d'obstacles:
On conçoit un algorithme ayant pour objectif d'éviter les obstacles de façon douce et progressive. Plus l'obstacle est près et centré, plus la consigne de déviation sera importante.
Documents Rendus
Projet S8
Bilan de la soutenance du S7 :
De nombreuses inquiétudes envers la capacité du robot à rouler et les nouveaux contrôleurs moteurs achetés. Le groupe doit se recentrer sur l'aspect hardware du robot avant de s'aventurer sur les outils softwares, qui sont inutiles si le robot ne roule pas. Les choix entrepris doivent également être mieux justifiés avec des motivations claires (par exemple le choix du matériau pour la boite, le choix d'utiliser des QR Codes au lieu de formes géométriques qui peuvent être plus simples ou encore notre choix concernant nos capteurs de distance qui fonctionnent en infrarouge). D'autres propositions ont été faites telle que rajouter un bumper (pare-choc) autour du robot en guise de sécurité.
Début du S8:
Le groupe se recentre donc sur l'objectif principal de faire rouler le robot. La Kinect est laissée en suspens pour permettre un avancement plus rapide de la partie hard. Cependant, la partie serveur web est maintenue, afin de ne pas accumuler trop de retard et pouvoir enchaîner sur le programme Arduino pour le contrôle des moteurs dès que la partie câblage sera achevée. Pour mieux gérer notre organisation ce semestre nous choisissons de tout de suite réaliser un diagramme de Gantt.
Semaine 2 :
Partie Hard : Les nouveaux variateurs ont été reçu, on les teste alors. Plusieurs problèmes de compréhension de leurs fonctionnements, dus à une datasheet peu exhaustive. En outre, nous ne parvenons pas à réguler la tension de sortie des variateurs malgré l'envoi d'une pwm variable en entrée. De plus, les tests en charge semblent demander trop de courant pour les variateurs qui se mettent en défaut.
Partie Soft :
Le serveur est relancé et nous modifions les différents envois de données sur la console du serveur et sur la liaison série. Nous avons décidé qu’un message typique envoyé par le serveur aurait la forme suivante : X+xxxY-yyy. Le X et Y en majuscule servent à vérifier que le message reçu est bien le bon. Le + ou - servent à indiquer si la valeur X/Y est positive ou négative et la valeur envoyée ira ensuite au maximum jusqu’à 500, trois caractères pour la valeur seront donc suffisants (représentée par "xxx" et "yyy"). Des premiers tests sont effectués et les valeurs reçues sur la console du PC correspondent avec les valeurs envoyées du joystick sur le serveur. La prochaine étape est la vérification de ces envois sur le port série.
Semaine 3 :
Partie Hard :
La caractérisation des moteurs nous a permis de constater que nous ne pourrons malheureusement pas utiliser les nouveaux contrôleurs moteurs. Pour ne pas perdre de temps nous choisissons de réutiliser les anciens, nous avons un peu de mal à les allumer car ils sont capricieux.
Partie Soft :
La mise en forme du serveur n'a pas été une priorité puisque ce dernier ne nous sert au final qu'à utiliser un joystick virtuel. Un codage plus propre sera mis en oeuvre dès que ce dernier sera totalement fonctionnel et répondra à nos attentes. Pour tester nos envois nous avons utilisé une carte Arduino MEGA afin de lire ce que nous envoyons sur la liaison série. Celle-ci est réglée sur une vitesse de communication égale à 115 200 bauds. Lorsque nous récupérons l'ensemble de nos caractères dans une variable char et que nous l'affichons directement, nous remarquons que des "?" sont envoyés lorsque nous bougeons rapidement le joystick. Pour pallier ce problème, nous stockons ce qui est envoyé sur la liaison série dans un tableau contenant l'ensemble de la trame. Nous rappelons que cette trame est de la forme X+255Y-500. Les caractères "X" et "Y" nous permettent d'identifier qu'un nouveau message est reçu, si ce dernier est correctement reçu, c'est à dire de la forme attendue, il est affiché. Lorsque nous bougeons le joystick trop rapidement des valeurs sont perdues car mal reçues mais il nous suffira de manipuler le joystick en douceur pour recevoir l'ensemble des valeurs.
Nous avons pris du retard sur la partie de gestion des moteurs à cause de notre erreur dans les commandes.
Semaine 4 :
Partie Hard :
Nous recommençons l'entièreté du châssis du robot pour nous permettre de déplacer les différents éléments qui le compose. Comme expliqué lors de la soutenance, nous déplaçons principalement les éléments de l'étage du bas. Nous déplaçons le bouton de démarrage et le bouton d'arrêt d'urgence à ce qui est désormais l'avant du robot. En effet, nous avons aussi pris la décision de placer la roue folle à l'arrière du robot. Nous rendons l'accès aux fusibles plus facile en le mettant à côté de la porte. Pour découper ces plaques, nous nous rendons au Fablab de Centrale. En effet, la découpeuse laser du Fabricarium était indisponible car ils n'avaient plus de lentille. Clément étant Fabmanager au Fabricarium, nous avons eu l'autorisation d'aller utiliser la découpeuse laser de Centrale.
Plans SVG des plaques intérieures :
Plans SVG des parois extérieures :
Nous avons réussi à démarrer les anciens variateurs des moteurs avec ce schéma de câblage :
Pour démarrer les contrôleurs moteurs, il faut :
- 24V sur la pin 1 (clé d'anti-démarrage)
- Rien sur les pins 3,4,8
- Une résistance d'au moins 5kohms entre les pins 5 et 7
- Une tension entre 40mV et 170mV sur la pin 6
Pour ce faire nous avons donc branché une résistance de 10kohms entre les pins 5 et 7. Nous envoyons la tension de 130mV grâce à des DAC. Nous redirigeons la tension de sortie de la pin 2 vers une carte de relais, celle-ci nous permet de choisir le sens de rotation des moteurs en activant l'un ou l'autre des relais. Le contrôleur moteur est équipé de sécurité au cas ou les deux seraient activés en même temps.
Partie Soft :
Le format de nos trames et les valeurs envoyées par notre joystick sont modifiés. En effet, envoyer un octet pour chaque valeur de consigne X et Y au lieu de 10 caractère ASCII (ce qui constitue une trame de 10 octets) nous parait être une bien meilleure solution, moins volumineuse et plus rapide d’envoi mais également plus simple pour le traitement sur l’Arduino MEGA. Ce problème nous a d'ailleurs été souligné dans les commentaires au milieu du semestre. Pour ne pas avoir de problème avec le signe des valeurs X et Y, les valeurs de ces derniers varieront entre 0 et 127 (afin d’utiliser 7 bits sur les 8 bits qui constitue l’octet), la position au repos du joystick sera X = 63 et Y = 63. La distinction entre X et Y se fera à l’aide du bit de poids fort. Un octet représentant la valeur de X sera la forme 1xxx xxxx et un octet pour la valeur de Y sera de la forme 0yyy yyyy. Ces trames envoyées sur la liaison série seront également de la même forme pour la partie Kinect ce qui permettra de mettre en place une duplication de code sur l’Arduino MEGA pour le traitement.
Semaine 5 :
Partie Hard
Nous commençons le câblage du robot. Toutes les pièces ont été découpées et s'assemblent. Nous commençons par tirer des morceaux de ruban pour simuler les câbles. De cette manière, nous pouvons estimer à moindre coût l'encombrement général des câbles, leurs longueurs, leurs agencements les uns vis-à-vis des autres. L'intérêt est de limiter la coupe de câbles trop court.
Nous pouvons ensuite passer au câblage réel de l'étage de puissance, remarque importante : la convention de couleur des câbles est inversée (Noir pour le + et Bleu pour le -). Le respect des couleurs a été impossible. En effet, les câbles de puissance des batteries étant de grosse section et étant donné l'absence de matériel pour sertir ces câbles, nous avions pas d'autres choix que d'utiliser ceux déjà sertis. Leurs longueurs nous imposé de les utiliser en inversant la convention des couleurs. L'emploi de goulottes nous permet une meilleure organisation de l'étage.
L'ajout d'étiquettes sur les câbles nous permet un repérage plus simple, et donc un montage ou démontage facilité.
Les remarques vis-à-vis d'un deuxième bouton d'Arrêt d'Urgence et de longueur de câbles suffisamment grande pour permettre le retrait de l'étage de commande, ont été prise en compte. Nous avons prévu un câble pour ajouter un bouton d'arrêt d'urgence sur la plaque supérieures du robot. Lorsque nous recevront le nouveau bouton, nous irons découper la plaque pour fixer le bouton.
Partie Soft
Les différentes parties Soft se finalisent, les derniers tests sont effectués afin de valider la partie Serveur et la partie Kinect. Une hiérarchie de priorité est également mise en place dans le code de l'Arduino MEGA. En effet, pour le contrôle du robot, 3 modes sont mis en place :
- Un mode automatique : Géré par la Kinect.
- Deux modes manuels : Géré par le joystick physique et le joystick virtuel.
Ces différents modes de contrôle peuvent changer au cours du fonctionnement du robot, pour autant si plusieurs modes de contrôle essayent de contrôler le robot au même instant il semble évident que l'un d'entre eux doit être prioritaire et devenir bloquant pour les autres.
- Priorité 1 : (Maximale) La priorité la plus élevée est celle des capteurs situés autour du robot. Ces derniers sont constamment vérifiés peu importe le mode de contrôle du robot afin d'éviter toute collision.
- Priorité 2 : La deuxième priorité la plus élevée est celle du contrôle du robot grâce au joystick physique connecté à l'Arduino via un port RJ11.
- Priorité 3 : La troisième et avant dernière priorité est celle du contrôle grâce au joystick virtuel mis en place sur le Serveur Web en NodeJS.
- Priorité 4 : (Minimale) La priorité la plus faible est celle qui est constituée de la partie Kinect ce qui correspond au fonctionnement du robot en mode autonome.
Bilan de mi-semestre
En ce milieu de semestre, nous effectuons un bilan avec les encadrants sur l'avancement du projet. Le robot a maintenant de nouvelles parois. Nous avons fait le choix d'encocher la plaque du milieu pour éviter que l'étage supérieur ne repose sur les batteries. Cela soulève des inquiétudes concernant la maintenance du robot. Il est vrai que nous n'avions pas pris en compte dans notre cahier des charges le fait que le robot soit facilement démontable pour des éventuelles modifications. Il faudrait donc que la plaque du milieu soit facilement démontable. En fait, nous pouvons la retirer facilement. Il suffit pour cela:
- D'enlever le profilé supérieur du côté
- Desserrer les deux profilés du côté
Cela permet d'enlever la plaque. Cependant, de nombreux câbles relient l'étage supérieur à l'étage intérieur. Il faudrait donc débrancher tous ces câbles si l'on veut réellement intervenir sur l'étage inférieur. Cependant, nous réfléchissons à une solution pour effectuer de petites modifications sans devoir tout débrancher. Pour cela, nous réarrangeons le câblage. En effet, nous gardons un peu de marge au niveau des câbles de l'étage supérieur pour pouvoir déboîter la plaque du milieu et accéder à l'étage inférieur en gardant l'étage supérieur câblé.
Nous avons aussi eu des inquiétudes concernant l'emplacement du bouton d'arrêt d'urgence qui avait été au préalable validé par Mr Redon. Nous allons donc modifier notre câblage pour permettre d'ajouter un bouton d'arrêt d'urgence qui sera placé sur le dessus du robot.
Concernant la partie soft :
Semaine 6: (04/03)
Partie Hard
Voici l'état actuel du robot :
- Toute la partie alimentation est câblée
- Les variateurs sont alimentés mais il nous manque les connecteurs MOLEX pour les contrôler. Nous réalisons un branchement temporaire pour nous permettre de tester la partie soft
- Le PC ne semble pas s'allumer malgré l'alimentation 12V
- L'écran ne reste pas allumé. Il est bien alimenté en 13V à la sortie du convertisseur, puis sa tension chute à 8V. Puis, lorsque l'écran est éteint, la tension de sortie du convertisseur repasse à 13V.
Nous avons aussi replacé le mat avec l'écran et la kinect.
Nous avons inversé le sens du mat, et donc le sens de marche du robot pour deux raisons :
- Permettre d'avoir une distance minimale entre les personnes et la kinect pour empêcher tout problème de détection si la personne se trouvait trop près du robot
- Améliorer le déplacement du robot en mettant la roue folle à l'arrière et non plus à l'avant
Enfin, voici la nouvelle disposition des boutons :
Ils sont tous présents à l'avant du robot, avec le coupe batteries, le bouton de démarrage et le bouton d'arrêt d'urgence. Comme discuté avec les encadrants, nous avons rajouté deux câbles avec un domino pour permettre l'ajout d'un autre bouton d'arrêt d'urgence, lui placé sur le dessus du robot.
En parallèle, réalisation d'un livret explicatif du câblage et du fonctionnement du robot. Réalisation sur Onshape des nouveaux supports pour les 6 capteurs que l'on peut voir ci-dessous :
Partie Soft
Nous testons donc la partie soft avec le câblage temporaire. Lorsque le serveur envoie l'ordre d'aller vers l'avant, les deux moteurs tournent bien dans le même sens. Cependant, lorsqu'on lui demande d'aller vers l'arrière, nous n'avons qu'une seule roue qui tourne. Nous remarquons que sur les relais, une des Leds ne s'allume pas. Nous avons donc plusieurs hypothèses pour ce problème :
- Problème au niveau du code
- Problème au niveau du shield
- Problème au niveau de l'arduino
Nous enlevons le shield pour tester l'arduino et le code. On réalise un code pour envoyer 5V sur la pin 47, qui correspond à la pin du moteur gauche pour aller en marche arrière. On reçoit bien 5V sur cette pin. Le problème ne vient pas de l'arduino. Nous testons donc le code. Nous recevons bien des données. Le problème viendrait donc du shield. On vérifie d'abord que sur le shield, le bornier est bien reliée à la pin qui s'enfiche dans la pin 47 de l'arduino. Il n'y a pas de problème de ce niveau là. En regardant le shield, on remarque que les soudures sont assez grosses et pourraient empêcher le shield de bien s'emboîter dans l'arduino. En nettoyant les soudures, on rebranche tout. Nous recevons bien les 5V sur le bornier, il s'agissait donc uniquement d'un faux contact. Nous avons encore des modifications à réaliser sur le code pour gérer les cas spécifiques.
Coté serveur ce dernier est achevé et fonctionnel, les derniers tests sont concluants et cette partie est maintenant finalisée. • Archive ZIP contenant ce qui a été réalisé pour le serveur : Fichier:Serveur Joystick.zip
Semaine 7: (11/03)
Partie Hard
Finalisation du câblage :
Après réception des connecteurs Molex, nous avons, avec l'aide de Thierry, confectionné des câbles permettant de relier les variateurs de vitesse au shield arduino de façon propre.
Voici le câblage :
De plus, le câblage entre les commutateurs et le shield a également était revu. Il est maintenant composé de câbles ayant une longueur adapté, maintenus par des borniers. Nous finissons d'imprimer les capteurs :
Intégration des capteurs :
Nous quittons donc le robot pour une période indéterminée.
Partie Soft
Le code Arduino a été revu afin d'offrir une meilleure mobilité au robot. La stratégie est la suivante :
Une vitesse initiale identique est attribuée aux deux moteurs en fonctions de l'axe y lorsque le robot est contrôlé par le joystick. Cette vitesse est ensuite modifiée en fonction de l'axe x, en tournant à gauche, on va ainsi ralentir le moteur gauche et accélérer le moteur droit
vit_motD = val_y + ((63 - val_x)/2); vit_motG = val_y + ((val_x- 63)/2); Pour rappel, la position (63;63) correspond à la position centrale du joystick
Lors du déplacement en autonomie le calcul est le même, la Kinect envoie alors une valeur 'val_y' en lien avec la distance de l'obstacle le plus proche et une 'val_x' en lien avec la localisation de l'obstacle (à gauche ou à droite du robot)
Les fonctions qui calculent val_y et val_x sont linéaires, ce qui permet un évitement progressif des différents obstacles.
Bilan du projet avant le début du confinement
La réorganisation de l'intérieur du robot a été entièrement réalisé.
Les moteurs sont contrôlés grâce aux variateurs.
Le robot est entièrement ré-assemblé et il ne manque qu'à relier les capteurs pour finir le câblage.
Nous arrivons à le faire rouler grâce a un joystick virtuel et le PCB du joystick physique et en cours de validation.
Le serveur et la kinect sont synchronisés grâce à la gestion de priorité.
Le contrôle du robot grâce à la kinect n'a pas encore pu être testé mais le programme est fonctionnel, seul des ajustements de variables seront à effectuer.
Semaine 8: (18/03)
Pour palier notre absence due au confinement, nous avons de nouveaux axes à traiter qui se concentrent sur la partie soft du robot.
Avant de partir, toute la partie câblage était finie, à l'exception des capteurs qu'il faut encore brancher à l'arduino. Le code prenait déjà en compte les capteurs et nous ferons les tests quand nous aurons accès au robot.
Nous nous concentrons donc sur 3 axes :
- OpenCV : Suivre une piste au sol en détectant les murs et les escaliers. Ceci est une solution à court terme pour le robot. (Pierre et Samuel)
- Interaction Homme-Machine : Créer un visage pour le robot, proposer des services aux utilisateurs (Loïc et Théo)
- Intelligence artificielle : Réaliser un réseau de neurones (apprentissage de circuit) permettant de donner la direction au robot. Ceci est la solution sur le long terme. (Valériane et Clément)
Deux pistes principales pour l'IA sont : https://atsushisakai.github.io/PythonRobotics/ https://blog.floydhub.com/teaching-my-robot-with-tensorflow/ : pytorch / tensorflow qui est du deep learning
Semaine 9: 25/03
Point Kinect :
Nous sommes capable, avec la Kinect, de récupérer le flux vidéo et d'en extraire des informations tels que l'abscisse, l'ordonnée et la profondeur d'un point dans l'espace.
L'enjeu est donc, à partir de ce flux vidéo, de déduire une consigne de direction à transmettre à l'Arduino, à savoir une consigne de la forme {val_y ; val_x}
Pour se faire, à chaque nouvelle image fournie par le capteur, on scanne chaque pixel pour localiser le pixel le plus proche. Celui-ci est donc considéré comme l'obstacle le plus urgent à éviter :
- La distance de ce pixel est utilisée pour établir une 'val_y' entre 0 et 127. Plus l'obstacle est proche, plus la valeur se rapproche de 0.
- L'abscisse de ce pixel est utilisée pour déterminer une 'val_x' entre 0 et 127. La consigne 'val_x' s'adapte afin d'éviter de façon progressive les obstacles, plus celui-ci est centrée par rapport au robot, plus la consigne de changement de direction sera importante.
Problème : Un des problèmes rencontré fut les ombres. En effet le capteur infrarouge de la Kinect est sensible aux infrarouges et s'avère très peu fiable dans des environnements fort lumineux (près d'une fenêtre par exemple). Le capteur retourne donc, pour tous les pixels sur-exposés, une distance par défaut de 2 mètres. Ce comportement est dangereux car il peut amener le robot à percuter un obstacle en pleine lumière.
Solution : On implémente donc un algorithme de gestion des ombres, on se sert des pixels adjacents aux ombres dans le but d'attribuer une valeur arbitraire de profondeur à chaque pixel, qui correspond à son environnement proche (cf image) :
Intelligence artificielle
Nous faisons des recherches pour nous former au développement d'un réseau de neurones, pour pouvoir, sur le long terme, avoir un robot autonome qui arrive à conduire des personnes à différents endroits de Polytech. De nos premières recherches, nous avons différents outils pour réaliser ce réseau de neurones :
- Pytorch
- Tensorflow
- Mathlab
Les deux premiers utilisent Python alors que le dernier utilise C++. Nous étudions ces différentes possibilités car nous avions remarqué que le PC du Centaure ralentissait significativement lorsqu'on lui a demandé de faire du traitement d'image avec Python. En utilisant OpenCV, nous n'avons plus ce problème de ralentissement. Aussi, nous ne sommes pas sûrs d'avoir accès à toutes les fonctionnalités de Mathlab avec la version gratuite mise à disposition pendant le confinement.
Voici les grandes étapes à suivre pour réaliser un réseau de neurones :
- 1. Accès et préparation de nos données
- 2. Création du réseau de neurones
- 3. Configuration des entrées et sorties du réseau
- 4. Réglage des paramètres du réseau (poids et biais) afin d'optimiser les performances
- 5. Apprentissage du réseau
- 6. Validation des résultats du réseau
- 7. Intégration du réseau dans notre système
Open CV : Pour nous permettre de nous déplacer dans les bâtiments de Polytech, nous choisissons d’implémenter une partie « temporaire » (remplaçable par l’IA par la suite). Ce travail à réaliser grâce à la librairie Open CV devrait nous permettre de reconnaître une forme au sol pour pouvoir savoir où nous sommes et où nous guider vers notre cible. Dans un premier temps, nous avons commencé par installer une version stable d’Open CV, la version 2.4 et nous commençons à nous familiariser avec cette bibliothèque et au langage C++ grâce a des programmes simples de détection de visage.
Semaine 10 : 01/04
Intelligence artificielle
Nous nous renseignons sur l'algorithme de Dijkstra. Cet algorithme permet de trouver le chemin le plus court pour aller d'un point A à un point B. Pour pouvoir l'utiliser dans l'enceinte de Polytech, il faudrait au préalable remplir un tableau avec toutes les destinations possibles depuis le hall.
Un autre algorithme, qui se base sur celui de Dijkstra, est l'algorithme A*. Il a été utilisé sur le premier robot capable de raisonner sur ses actions, le robot Shakey.
Cet algorithme utilise une méthode heuristique pour déterminer le meilleur chemin, à partir de nœud. Il ne nécessite pas de prétraitement et consomme peu de mémoire. Cela pourrait donc nous permettre de ne pas avoir de ralentissement en utilisant cet algorithme sur le Centaure.
Après discussion avec les encadrants, nous nous recentrons vers l'utilisation du deep learning pour l'apprentissage de circuits.
N'ayant pas accès à Polytech, nous ferons d'abord des tests chez nous. Voici la méthode que nous devons suivre pour réaliser un réseau de neurones capable de se déplacer de manière autonome sur un circuit qu'il a appris :
- Faire circuler le robot d'un point A à un point B en prenant de nombreuses captures d'images
- Utiliser un algorithme d'augmentation des données (ombre, luminosité..) pour travailler les images avant de les labelliser
Cela correspond au pré-traitement du réseau de neurones. Pour traiter ces données, nous pouvons utiliser Tensorflow et Google Colab. Une fois l'architecture globales des algorithmes déterminées, il nous suffira de remplacer nos données par un circuit à Polytech.
TensorFlow est une librairie entièrement programmée en Python qui fournit une API pour les utilisateurs qui souhaiteraient utiliser des techniques de machine learning. Il s'agit en réalité d'un ensemble de fonctions mathématiques et de méthodes de calcul qui permettent de développer des fonctions d'apprentissage par la machine à adapter à chaque cas de figure.
Interaction Homme-Machine
Il est maintenant temps de mettre à profit l'écran mis à disposition sur le véhicule. Celui-ci doit remplir les missions suivantes :
- Etre clair
- Susciter l'intérêt des passants
- Etre acceptable esthétiquement
Par l'intermédiaire de cet affichage, les personnes de passages devraient être capables de communiquer rapidement avec le robot. On s’attelle donc à lui donner un visage qui sera affiché lors des déplacements du robot et lorsqu'il communique avec des utilisateurs.
Plusieurs designs furent proposés et testés, pour finalement s'orienter vers un visage sobre et épuré (et bien moins terrifiant):
Concrètement, l'interface visible à l'écran est gérée par un fichier source multithreadé "display.c" et fait appel à la libSDL (utilisée pour la création d'applications multimédias). On décompose le visage en différentes sous images :
- œil
- iris
- bouche
De cette manière il est possible d'animer notre personnage à l'écran. Une fonction est dédiée au mouvement des yeux et est lancée au sein d'un thread (l'utilisation des threads est d’ailleurs encapsulée dans une bibliothèque libthread). De plus, le programme communique en IPC avec le programme de détection faciale, ainsi, lorsque qu'aucun visage n'est détecté par le robot, les yeux présentent un mouvement aléatoire, à l'inverse, lorsqu'un visage est détecté, ses coordonnées sont transmises et le robot suit la personne du regard.
On note cependant la lenteur du traitement des images en C++ à l'aide d'openCV. En étant le plus minimaliste possible, le programme traite péniblement 1 image par seconde sur un PC récent...Difficile alors de savoir si le programme sera supporté par le PC embarqué du robot.
L'utilisation de threads a pour but final de pouvoir mouvoir indépendamment différentes parties du visage et de pouvoir par exemple lancer des fichiers sonores en parallèle de l'animation du visage.
L'ensemble du code de l'interface et disponible sur ce dépôt git : https://archives.plil.fr/lringot/Centaure_IHM.git
Reconnaissance Vocale
Une solution de reconnaissance vocale et de synthèse vocale développée en C est également recherchée. Il est vrai que nous avions développé une reconnaissance vocale et faciale ainsi qu'une synthèse vocale l'année dernière pour autant cela avait été développé en Python. Après nos différents tests et après nous être documenté il s'avère que le Python est un langage beaucoup plus "lourd" que le C/C++ et jusqu'a 100 fois plus lent que le C.
Plusieurs solutions sont à notre disposition :
- HTK : Application cross-plateforme mais non open source et qui ne supporte que l'Anglais, programmation en C.
- RWTH ASR : Idem que HTK, cross-plateforme, non open source et ne supporte que l'Anglais, programmation en C++.
- Julius : Application qui pourrait tout à fait convenir à notre utilisation mais cette dernière ne supporte que l'Anglais. Elle est open source et supporte le C.
- Kaldi : Idem que Julius, application qui pourrait tout à fait convenir à notre application mais ne supporte que l'Anglais et le C++.
- CMU Sphinx : Application qui semble être la plus adaptée à notre utilisation. Cette dernière supporte de nombreux langage et notamment le français, elle est open source et cross plateforme et supporte le Java et C.
Au final nous nous orientons vers une utilisation de CMU Sphinx qui est un ensemble de logiciels pour différentes applications et tâches. Dans cet ensemble nous retrouvons PocketSphinx et Sphinx4. Dans notre application nous utiliserons PocketSphinx qui est une librairie écrite en C pour de la reconnaissance vocale.
Des premiers test sont effectués en Anglais, ces derniers ne sont pas précis et le passage pour une reconnaissance de la voix en française se fait difficilement.
Open CV
Nous avons profité de cette semaine pour en apprendre plus sur la librairie Open CV et sur son fonctionnement, grâce à un programme de détection de visage, celui-ci sera par la suite réutilisé quand le robot sera en attente d’interaction avec quelqu’un. Pour détecter des formes la librairies Open CV se sert de fichiers « xml » qui sont en fait des modèles, par exemple le fichier « haarcascade_frontalface_alt.xml » est un modèle de détection de visage, un certains nombres de photos contenant un visage ont était envoyées à un programme pour obtenir un fichier qui sait reconnaître les attributs d’un visage et donc les détecter. Dans le programme de détection de visage que nous avons récupéré, nous remarquons que les images par secondes sont très faibles, 1 à 3 maximum. Nous décidons donc de nous plonger en profondeur dans le traitement des images. Le programme se sert de la fonction « detectMultiScale » pour détecter une forme. Grâce a des recherches sur cette fonction, nous avons appris qu’elle fonctionnait de la manière suivante : elle prend en paramètre une image et une forme à chercher, elle va parcourir cette image jusqu’à la fin, puis va réduire l’échelle de cette image et recommencer. Deux paramètres sont donc à bien ajuster dans l’utilisation de cette fonction, « scaleFactor » qui est le paramètre de réduction des images (d’après nos recherches à choisir entre 1,1 et 1,5), plus ce paramètre est petit, plus on est précis mais plus on augmente le temps de traitement. Le deuxième paramètre est « minNeighbors » ce paramètre est également essentiels pour ne pas avoir de faux positifs, il nous permet de choisir à partir de combien de détection de l’objet à un endroit sur des couches successives on considère que c’est l’objet que l’on recherche (celui-ci est généralement compris entre 3 et 5), plus il est élevé plus la précision est élevée mais plus le temps de traitement est long. Un troisième paramètre rentre en jeu dans notre détection de visage « minSize », celui-ci permet d’indiquer une taille minimale à l’objet recherché, plus il est faible et plus le temps de calcul sera long, dans le cas d’une détection de visage c’est ce paramètre qu’il faut augmenter pour améliorer le temps de traitement.
Semaine 11: 08/04
Intelligence artificielle
Nous étudions donc la possibilité de réaliser un réseau de neurones capables d'apprendre des circuits, pour ensuite l'utiliser sur le Centaure et qu'il puisse se déplacer de manière autonome et intelligente dans Polytech (le long des circuits qu'il connaîtra). Nous partons du principe que nous devons avoir de nombreuses images de ce circuit, que nous allons ensuite donner à notre réseau de neurones pour les analyser. Nous choisissons le logiciel Tensorflow recommandé par Mr Dequidt ainsi que l'outil Google Colaboratory. En effet, ce dernier permet d'utiliser Tensorflow sans installation préalable. Nous prenons donc nos marques avec ces nouveaux outils. Pour cela, nous commençons le cours de Machine Learning disponible sur Google Colaboratory pour voir ces différentes notions :
Nous nous posons aussi des questions concernant le déplacement du robot.
À partir de quelles informations le robot va t-il décider de se déplacer vers la gauche ou vers la droite.
Nous allons prendre des images du circuit qu'il va faire. Va t-il ensuite, lorsqu'il devra à nouveau parcourir ce circuit, comparer l'image qu'il voit à l'ensemble des images connues, pour savoir s'il dévie à gauche ou à droite ?
Lui imposer par exemple qu'un pourcentage de sa vision doit contenir un mur, pour lui permettre de suivre le mur et d'agir en fonction du pourcentage de mur qu'il voit dans son champ de vision.
S'il se tourne vers le mur, donc qu'il voit de plus en plus de mur dans sa vision à gauche, alors il doit aller vers la droite, et inversement.
Pour cela, il faudra que notre réseau de neurone sache reconnaître certains éléments comme un mur, une porte, un escalier. Nous pouvons utiliser un réseau pré-entraîner pour cela.
Nous avons par exemple trouvé le modèle ResNet 50 pour Keras (API de Tensorflow) qui est utilisé pour la reconnaissance d'image.
Finalement, peut-être qu'en prenant assez d'images de notre circuit et en les labellisant correctement (présence du mur ou non), nous n'aurions pas besoin d'un modèle.
Il devra donc ressortir deux informations, un x et un y (qui correspondent à la direction qu'il devra prendre) qui seront ensuite envoyés à l'arduino et ensuite aux moteurs.
Une autre solution que nous avons est de labelliser chaque image en lui donnait une valeur x et y. Ces valeurs correspondent à la direction que le robot devra prendre pour suivre le circuit s'il se trouve dans cette position. Avec un assez grand nombre d'images, nous pourrons peut être sortir un modèle qui nous renvoie un x et un y en fonction de ce qu'il voit.
Nous commençons donc par tester cette dernière solution.
Nous nous renseignons sur ce qui a déjà été fait. Nous trouvons le wiki de Brandon et Hugo qui ont utilisé le deep learning pour leur voiture (p14 : Ironcar). Nous comprenons mieux la démarche à suivre et à appliquer pour le Centaure.
Nous devons donc :
- Prendre en photos un parcours
- Labelliser ces photos, en fonction de la direction que doit prendre le robot s'il se trouve dans cette situation
- Récupérer les photos et les labels
- Pré-traiter les données
- Construire le modèle avec les différentes couches
- Entraîner le réseau avec ces données
- Valider le modèle avec des photos choisies pour la validation
- Modifier le réseau pour avoir un meilleur taux de bonnes réponses
- Evaluer notre réseau avec d'autres photos de ce circuit
Nous validons notre modèle avec des photos différentes de celles pour l'évaluation pour éviter le surapprentissage.
En effet, à force de modifier notre modèle pour avoir un meilleur taux de réussite, on risque de trop coller notre modèle à notre échantillon, et non à l'ensemble des valeurs possibles.
Nous aurions donc un bon modèle pour nos échantillons, mais pas un bon modèle pour l'ensemble.
Nous visualisons les images que l'on a récupérées et converties en tableau Numpy. Nous commençons les tests de traitement des images avec des images ne concernant pas le circuit. Nous obtenons :
Lorsque l'on pré traite ces images, on obtient :
Nous avons passé l'échelle qui allait de 0 à 255 à une échelle allant de 0 à 1.
Interaction Homme-Machine
Ajout d'une fonction vocale au robot, reposant sur la libSDL-mixer. Nous sommes ainsi capable de charger des mp3 et de les lancer à différents moments afin d'interagir avec le robot (lors du lancement ou de la détection d'un visage par exemple). Pour plus de réalisme nous créons une animation de la bouche à l'aide d'un sprite (comme dans les jeu vidéo).
Il est donc nécessaire de savoir durant combien de temps nous devons animer la bouche. Une relation mathématiques entre la taille d'un mp3 et sa durée nous permet d'établir ce temps :
$biterate = $kilobitrate*1024; $taille = filesize("a.mp3")*8; $seconde = $taille/$biterate;
Lors du lancement d'un mp3, une durée est calculée à partir de sa taille, durant ce laps de temps, un booléen 'mp3' passe à 1 et permet ainsi l'animation de la bouche dans le thread dédié
Reconnaissance Vocale
Après différents tests effectués, le passage de la reconnaissance vocale en Français est plus compliqué que prévue.
Parallèlement nous avons trouvé un autre projet gitHub "Jarvis", projet créé par un français dont la dernière mise à jour date d'il y a 2 ans. Jarvis est un assistant vocal ultra-léger et multilingue (notamment Français). Il a été imaginé pour la domotique et peut notamment tourner sur des systèmes très léger (ex: Raspberry Pi). Il dispose d’une reconnaissance et d’une synthèse vocale.
Un autre point fort de ce projet est qu'il dispose d'une interface qui est utilisée pour mettre à jour le projet, installer les différents prérequis, ajouter de nouvelles commandes ou encore entraîner la reconnaissance de nouveaux mots.
Ce projet est parfait pour notre application car il est tout d'abord très facile à utiliser et à prendre en main et est extrêmement personnalisable via l'ajout de commande à exécuter ou l’entraînement de nouveaux mots à reconnaître.
De nombreux tutos sont disponibles et le créateur de ce projet en propose quelques-uns ce qui nous permettra de comprendre rapidement le projet. De plus ce projet nous laisse le choix sur le moteur de reconnaissance (google, bing, snowboy et pocketsphinx) mais aussi sur le moteur de synthèse vocale (Speech engine et OSX voice).
L'assistant vocal Jarvis fonctionne sur un principe de "mot magique". Tant que le mot magique (dans notre cas "Centaure") n'a pas clairement été entendu le programme ne peut effectuer des actions à la suite de commande vocale et reste dans l'attente du mot magique.
Ces commandes sont situées dans le fichier jarvis-commands, ce fichier est très facile à modifier et peut notamment être consulté depuis l'application. Depuis l'application nous pouvons également entraîner la reconnaissance vocale des ordres.
Voici un premier exemple de l'utilisation de l'assistant vocal :
OpenCV Kinect
Une version du code d'analyse d'image est importée sur l'archive 'CentaureIHM' afin de tester le bon fonctionnement de la liaison IPC entre le processus d'affichage du robot (./Centaure) et le processus d'analyse d'image (./VideoAnalysis). Nous rencontrons cependant des problèmes avec notre liaison IPC qui semble se figer sous certaines conditions pour des raisons inconnues. Cela met à mal le suivi du regard par le robot. Nous cherchons la source du problème.
La libfreenect et le code correspondant sont rapatriés dans l'archive 'CentaureIHM'. Le format vidéo de la kinect ne correspond pas au format vidéo attendu par la libOpenCV, il est donc nécessaire d'implémenter une fonction de conversion de la matrice image au sein du code de la kinect. L'idée est ensuite d'envoyer un pointeur de cette matrice en IPC au code d'analyse d'image sous openCV pour y détecter des visages ou des formes.
Open CV :
Après ces semaines de tests sur la librairie Open CV, nous avons remarqué qu’en fonction de la luminosité et l’inclinaison d’une caméra, la détection d’une forme variait énormément. Nous pensons donc que la détection d’une forme au sol à longue distance sera très difficile. Nous avons donc décidé de plutôt détecter une couleur (une couleur pourra être attribuée à chaque bâtiment) pour savoir dans quelle direction nous devons aller. Notre travail de cette semaine sera d’implémenter un programme et de le tester afin d’en vérifier la légitimité et de prendre une décision à la suite de cela.
Nous avons voulu commencer par écrire un programme pouvant repérer les objets de couleurs rouges, pour ce faire nous avons fait des recherches sur les fonctions nous permettant de filtrer les couleurs non désirées. Nous avons découvert que la fonction « inRange » pouvait ne garder que les objets étant dans une certaine plage de couleurs sélectionnée sur une image. Après l’utilisation de cette fonction, nous utilisons la fonction « GaussianBlur » qui réalise un flou gaussien sur notre image pour réduire les perturbations. Une fois cela effectué, nous utilisons la fonction « findContours » pour détourer tous nos objets et stocker leurs paramètres dans un tableau, cela nous permet de récupérer les coordonnées de tous les objets rouges détectés.
Nous avons ensuite implémenté la partie permettant de déterminer un point central à tous les objets trouvés. Pour vérifier que nos coordonnées sont bonnes, nous traçons un cercle au centre de tous les objets trouvés. Nous avons ensuite trouvé les coordonnées du centre de la somme des objets trouvés mais après réflexion il ne faudrait garder que les objets proches et non tous les objets de l’image, cela nous permettra de trier si une couleur similaire est présente dûs aux étudiants, meubles, etc.
Une fois une couleur détectée, nous pouvons partir du principe qu’elle peut nous guider vers un bâtiment spécifique mais le robot ne sera pas toujours positionné au même point (Hall de Polytech), nous avons décidé de placer une deuxième couleur à coté de la première permettant donc de savoir dans quel bâtiment nous sommes, et vers quel bâtiment nous nous dirigeons.
Par exemple, comme vous pouvez le voir sur l'image au dessus, la couleur bleu pourrait nous servir à nous diriger vers le hall de polytech, la rouge vers le bâtiment A, la verte vers le bâtiment B et la jaune vers le bâtiment C.
DepotGit : https://archives.plil.fr/lringot/Centaure_IHM.git
Interruption pédagogique
Intelligence artificielle
Le circuit sur lequel nous allons entraîner notre réseau est le suivant :
- Aller du bout du couloir vers la chambre au fond à droite
Pour cela, nous prenons des photos du circuit dans 5 directions :
- Gauche
- Diagonale gauche
- Tout droit
- Diagonale droite
- Droite
Pour attribuer un label à chaque image, nous les renommons en fonction des coordonnées du joystick virtuel pour chacune des directions. Par exemple, pour aller à gauche, la position du joystick est (0,63). Pour ces 5 directions, nous avons 5 x différents. Nous utilisons donc uniquement la valeur de x pour labelliser les images. Nous pourrons ensuite lui associer la valeur de y correspondant.
Lorsque nous chargeons les 365 images dans google colab, cela prend énormément de temps (environ 2 heures). À chaque fois que l'on quitte la page, il faut à nouveau importer les fichiers. Aussi, lorsque l'on ajoute ces images converties en numpy array dans le tableau, nous dépassons la RAM autorisée par google colab qui est de 25 Go. Notre sessiosn crash donc. Nous cherchons un moyen de redimensionner les images.
Une fois les images redimensionnées, et traitées, nous pouvons commencer la construction du modèle. Nous essayons deux modèles. Nous trouvons le premier sur le site tensorflow.org. Nous trouvons sur ce sites de nombreux tutoriels, dont un qui explique comment réaliser un réseau de neurones dans la classification d'images. L'exemple utilisé est la reconnaissance de la catégorie d'un vêtement (robe, pull, etc..).
Voici le modèle utilisé :
model = keras.Sequential([ keras.layers.Flatten(input_shape=(1356,1017,3)), # reformate les données (d'un tableau à 3 dimensions en un tableau à 1 dimension, nos images étant de dimension 1356x1017x3) keras.layers.Dense(128, activation='relu'), keras.layers.Dense(128) ])
Nous compilons ensuite le modèle :
model.compile(optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'])
Une fois le modèle entraîné une première fois, nous obtenons un taux de précision de 81%
Les difficultés rencontrées pour arriver à entraîner ce premier réseau sont :
- La mise en forme des images, sous le bon type
- La bonne dimension des images
- Le bon nombre de nœuds en sortie. Nous avons 5 valeurs possibles mais qui se trouvent dans l'intervalle [0,127]. Pour le modèle finale, nous réfléchirons à un moyen d'avoir 5 valeurs dans un intervalle de [0,5] et d'en restituer la valeur initiale de x.
L'étape suivante est de vérifier les prédictions de ce modèle (évalué à 81% de prédiction).
Pour cela, nous prenons de nouvelles photos de ce circuit. Nous les labellisons aussi pour pouvoir vérifier plus facilement les prédictions. Ensuite, nous demandons à notre modèle de nous donner la direction à prendre en fonction de l'image reçue (contenues dans tab_img_val).
probability_model = tf.keras.Sequential([model, tf.keras.layers.Softmax()])
predictions = probability_model.predict(tab_img_val)
Voici un échantillon des prédictions que nous obtenons :
La légende correspond à : direction choisie par le modèle, précision de cette prédiction, direction qu'il devait choisir. En bleu, les bonnes prédictions et en rouge, les mauvaises.
Pour avoir une meilleure précision, nous pouvons essayer un autre modèle, ou augmenter le nombre d'images utilisées pour entraîner le modèle (ici, 365 images).
Détection de couleurs pour guider le robot :
Nous continuons notre avancé en implémentant une fonction permettant de détecter une deuxième couleur en partant de la même base que la détection de la couleur rouge.
On améliore notre fonction de détection de couleurs en ne prenant en compte que les objets ayant un certains nombres de points (donc une surface minimale) qui composent son contour pour réduire les perturbations.
On implémente ensuite un algorithme permettant de diriger le robot en fonction du sens des couleurs. On compare le barycentre des couleurs détectées et en comparant les deux on obtient un angle. Ce qui nous
permet de déterminer un sens de déplacement pour le robot.
Nous améliorons ensuite le programme en n'utilisant qu'une seul fonction pouvons détecter n'importe quel plage de couleur passé en paramètre.
Semaine 14
Intelligence artificielle
Maintenant que nous avons un modèle fonctionnel, nous devons l'intégrer dans le Centaure. Pour cela, nous devons enregistrer le modèle. Ainsi, on pourra utiliser ce modèle sans avoir à l'entraîner de nouveau avec les 365 images. Pour cela, nous enregistrons le modèle sous le format HDF5. Voici les commandes à faire :
pip install -q pyyaml h5py # Required to save models in HDF5 format model.save('circuit1.h5') from google.colab import files files.download('circuit1.h5')
Nous pourrons donc copier ce circuit dans un dossier sur le PC du Centaure. Ainsi, notre code pourra aller cherche le bon circuit en fonction de la destination demandée. Ensuite, nous devons récupérer les images de la kinect, préalablement convertie avec OpenCV. On enregistrera une image sur 10 ou sur 20 pour laisser le temps au programme de fonctionner tout en permettant un déplacement fluide. Il faudra prendre en compte les paramètres de conversion utilisé pour construire le modèle. En effet, les images utilisées pour construire le modèle et celles que nous utilisons pour les prédictions doivent être de dimensions similaires.
Enfin, il faut envoyer la direction que le robot doit prendre suite à la prédiction du modèle. Pour cela, nous communiquons entre le PC et l'arduino via liaison série. Ainsi, nous enverrons des trames de la forme 1xxx xxx pour indiquer la coordonnée X, et 0xxx xxx pour indiquer la coordonnée Y.
Dans ce modèle, nous ne prenons pas en compte la vitesse du robot. En effet, les valeurs de X et Y choisies correspondent à la vitesse maximale du robot. Il faudrait très certainement choisir d'autres labels pour les vrais circuit au sein de Polytech, ou de convertir ces coordonnées pour qu'elles correspondent à la même direction mais avec une vitesse inférieure pour éviter un déplacement trop brutal.
Nous ne pourrons malheureusement pas tester cette solution sur le Centaure.
Interaction Homme-Machine
Pour une interaction plus "réaliste" et plus immersive, on améliore l'interface graphique en implémentant différentes humeurs pour le robot (Souriant, triste, colérique). Ces éléments servent surtout à poser les bases dans le but de créer une interface plus ludique. Une variable "humeur" est donc ajoutée dans le programme. En la modifiant, on modifie l'humeur de notre robot à l'écran. Les sprites utilisé pour l'animation du robot sont donc adaptés, on passe de sprite 1D à des sprites 2D. Ainsi, chaque ligne correspond à une humeur.
Des sprites pour les yeux sont également crées.
On peut donc ainsi obtenir des animations de ce type :
Demonstration du Centaure qui roule
Documents Rendus
Présentation PowerPoint : Presentation_Projet_Centaure
Rapport final : Rapport_Centaure.pdf
Guide de démontage Robot Centaure : Guide_Pratique_-_Demontage_Centaure.pdf
Guide des composants du robot : Guide_Composants_Centaure.pdf
Dépôt git regroupant la partie deep learning : https://github.com/ValerianeSlge/Centaure.git
Dépôt git regroupant le reste du software (+ le code arduino) : https://archives.plil.fr/lringot/Centaure_IHM.git