IMA5 2018/2019 P44
Sommaire
Présentation du projet
Ce wiki est mis à jour régulièrement par le binôme Erwan Dufresne et Eloi Zalczer, lors des différentes évolutions du projet
Dans un premier temps, il nous semble nécessaire de préciser que nous étions chacun en semestre à l'étranger. Ainsi nous pouvions chacun choisir des cours "à la carte" et façonner une formation un peu différente que celle proposer à polytech Lille. Ce pourquoi nous avons tous deux choisi des cours ayant un rapport de près ou de loin avec l'intelligence artificielle. Forts de ces différentes expériences plus ou moins approfonfies dans ce domaine, nous jugions judicieux de les mettre en pratique lors du PFE de 5ème année. Suite à différentes propositions jugées non adéquates par les professeurs, monsieur Vantroys nous a finalement proposé un projet, original, qui nous permettrait de mettre à bien les nouvelles connaissances aquises dans le domaine de l'IA lors du semestre d'échange,
Le projet consiste à réaliser une voiture autonome miniature capable de s'orienter via de l'intelligence artificielle. Cette voiture ainsi réalisée devrait pouvoir être conforme aux différentes normes lui permettant de participer à la compétition IRONCAR. Cette compétiton regroupe les véhicules minaturisés de différentes équipes et permet de les confronter entre eux.
Description
rappel sur la compet
Objectifs
truc fctionnel , compet organisé, comprend ruc sur ia et manipuler faire un tableau des objectifs chaque semaine
Analyse du projet
analyse des concurents
analyse des premiers concurents
Bien sûr les premiers concurants directs seront les autres participants à la course de l'ironcar. Ces différents concurents peuvent chacun déployer le dispositif qu'ils souhaitent, selon leur moyen et leur envie. Sous réserve que le prototype final soit respecte les conditions reqises pour participer à la compétiton, bien évidemment.
photo des differentes voiture de la compet
analyse des seconds concurents
D'autres parts, il y aussi d'autre type de concurents , notamment des grandes entreprises comme google, uber ou tesla qui conceptualisent et déploient des voitures autonomes depuis plusieurs années.
parler des concurents de la compet mais aussi des concurents type google etc avec es voitures autonomes
parler du projet de organiser la compet à lille par TV
Préparation
Cahier des charges
fixer obj
Choix matériels et technologiques
expliquer le matos, et celui impossé/interdit par la compet
Réalisation du projet
Avancement préalable
expliqué ce qu'on a fait avant de retourner à popo
planning du taff comme en 4A avec le temps passé sur les différentes etapes
Semaine 1 (7-11 janvier)
Cette première semaine nous a permis d'établir les bases qui nous permettront de nous attaquer au vif du projet. Nous avons commencé par installer Raspbian sur la Raspberry Pi 3B+, et par installer les librairies et paquets nécessaires. Pour Python, nous avons utilisé le gestionnaire de paquets Conda. Il nous permet d'installer et de gérer facilement les versions des librairies scientifiques que nous utiliserons (numpy, scipy, scikit-learn...). Ce gestionnaire de paquets est compatible avec l'architecture ARMv7 de la Raspberry Pi. L'installation de ces packages n'a donc pas posé de problèmes. Le plus difficile à été de mettre en place Pytorch, la librairie de machine learning sur laquelle sera basé notre projet. Cette librairie n'est en effet pas compilée pour Raspberry Pi par défaut, nous avons donc du le faire nous-mêmes. Après avoir récupéré le code depuis le dépôt GitHub du projet, nous avons du initialiser les bonnes variables d'environnement pour paramétrer la compilation. La compilation sur Raspberry Pi implique de se passer de certains fonctionnalités comme CUDA. Nous avons utilisé ce guide pour nous aider. Il a également été nécessaire d'augmenter la taille de la partition de swap pour que la compilation puisse se finir. La compilation a pris plusieurs heures, et nous l'avons étalée sur une nuit. Cette étape a été la plus difficile du setup. Certaines autres librairies, comme engineio pour les websockets, ont demandé des démarches d'installation un peu différentes car les versions disponibles sur anaconda n'étaient pas les bonnes. Nous avons donc du construire l'arbre des dépendances séparément.
Le deuxième jour, nous avons commencé à établir l'architecture du projet et à développer. Le plus urgent était d'établir un système de contrôle de la voiture qui nous permettra de capturer d'entraîner le réseau. Nous avons donc développé une petite application web et un serveur websockets en Node.js afin de faire communiquer la Raspberry Pi avec une interface de contrôle en HTML. Nous avons d'abord envisagé d'utiliser la Raspberry Pi comme serveur, mais par souci de légèreté nous avons choisi d'héberger le serveur sur un PC portable. La voiture et l'application client se connectent tous les deux en tant que clients sur le serveur, qui se charge de rediriger les messages reçus depuis l'appli web. Dans un premier temps, nous avons supposé que les angles de rotation de la voiture ne seraient pas supérieurs à 30°. Nous avons également normalisé la vitesse entre 0 et 30 sur le système de contrôle. La première version de ce dernier était très simple et consistait en un cercle sur un canvas qui suit les déplacements de la souris. Si le cercle est lâché, il retourne à sa position d'origine et arrête donc la voiture. L'interface ressemblait alors à l'image à droite.L'application a fonctionné sans problème majeur, cependant il nous a fallu un certain temps pour déterminer la façon optimale d'utiliser la librairie python-socketio. La réception des commandes est en event-based, ce qui n'est pas habituel en Python et nous a demandé quelques recherches. Nous avions commencé par mettre la réception des commandes dans un thread séparé, puis nous nous sommes aperçus que ce n'était pas nécessaire. Le jeudi, nous avons essayé pour la première fois la voiture. Après quelques courses dans les couloirs et le hall, nous avons démonté une partie du capot pour observer les branchements à l'intérieur. La documentation est pratiquement introuvable sur internet, donc cela nous a permis de nous faire une idée du fonctionnement du système et du protocole à utiliser. Suite à une discussion avec le tuteur de projet, nous avons décidé d'utiliser une Arduino pour générer les PWM car elle sera plus stable que sur un Raspberry Pi.
Une autre partie du travail a été de préparer la partie Machine Learning qui se fera dans quelques semaines. Nous avons modifié le code principal du projet pour enregistrer les images capturées par la caméra et les commandes correspondantes pendant la course. Pour cela, nous avons également ajouté un bouton Lancer/Arrêter l'enregistrement sur l'application Web. L'enregistrement pourra ainsi être contrôlé et arrêté si la voiture sort des traces. Lorsque la voiture est arrêtée définitivement, les données sont enregistrées dans un fichier horodaté au format hdf5 qui est optimisé pour le stockage de datasets. Les images et les commandes sont enregistrées sous forme de tableaux numpy qui sont facilement lisibles et re-convertibles en images. Nous avons écrit un petit code pour vérifier que les images n'étaient pas corrompues et que les commandes étaient correctement enregistrées, ce qui nous a permis de détecter un bug.
En effectuant ce travail, nous avons pris certains risques concernant l’entraînement futur du réseau. Nous avons en effet décidé de travailler avec des valeurs de vitesse et de direction continues, alors que tous les projets trouvables en ligne utilisent un set de valeurs discrètes. Notre approche peut nous permettre d'obtenir une voiture plus précise, mais demandera également plus de données pour l'entraîner efficacement. De plus, la qualité des données dépendra de la qualité de notre pilotage. Il est possible que cette décision doive être modifiée à l'avenir si les performances obtenues ne sont pas satisfaisantes.
Bien que les premiers tests sur la voiture concernaient l’orientation et la vitesse de pointe max, il fallait tester la télécommande dans son intégralité. Nous nous sommes donc longuement référés à la notice de la voiture. Finalement, voici l fonctionnalité des différentes commandes de ma télécommande.
Photo telecommande
La gâchette sert à accélérer ou reculer et à jauger la vitesse. La molette latérale droite sert à orienter les roues avant. La molette centrale sert à régler l’angle du servo moteurs contrôlant les roues avant (nous les mettront par défaut à 30 degrés, quitte à remodifier cette valeur par la suite) Le bouton en haut à droite inverse le sens de rotation des moteurs (inverser la tête et la queue de la voiture) Le bouton en haut à gauche permet ??????????????????????????????????????????? Celui d’en bas à droite, change le sens de d’orientation des roues directrices (tourner à droite fais désormais tourner la voiture à gauche) Celui en bas à gauche permet de re-calibrer la tension de la voiture, si celle-ci n’est pas totalement à l’arrêt losqu’on ne lui donne aucune indications. Enfin le bouton power sert à alimenter la télécommande (pas trop compliqué celui-là)
Ensuite il était essentiel de prévoir un support pour les différents composants que nous allions ajouter à la voiture. Effectivement, il faut pouvoir fixer les différents contrôleurs pour remplacer la télécommande. L’utilisation d’une raspberry était évidente. Pour ce qui est du contrôleur des moteurs, notre tuteur nous a fait remarquer qu’il s’agissait d’une simple PWM. Ainsi, une arduino serait judicieuse afin d’avoir une PWM de bonne qualité. Pour alimenter le tout une batterie est également essentielle. Le choix des iles à était rapidement écarté puisque nous avons à notre disposition des batteries externe.
Le but est donc de faire tenir l’ensemble de ces composants, finalement assez volumineux, dans la voiture. Il était évident que la « carcasse » en plastique original ne suffirait pas à contenir l’ensemble des éléments. Il sera donc nécessaire d’en modéliser une plus tard, sans doute imprimé en 3D (mais nous y reviendront plus tard).
Pour ce qui est du maintien des différents composants, il fallait quelque chose de précis pour être fixer correctement sur l’emplacement confiné du châssis, rapide (nous ne pouvions pas risqué de perdre trop de temps via l’impression 3D par exemple), et surtout résistant au choc et stable face aux différentes vibrations engendrées par la voiture. Le choix d’utiliser la découpe laser était donc presque évident. Il est vrai que nous aurions pu choisir un bois résistant ou divers couche de contreplaqué. Finalement nous avons choisi par simplicité, de faire ce support en plexiglas épais de 6mm.
Pour cela, on reprend les bonnes habitudes de Onshape pour modéliser les fichiers .dxf nécessaires à la découpe ! Le travail n’était pas très dur, mais assez fastidieux, et il fallait surtout être très rigoureux dans les mesures. Nous obtenu donc finalement un plaque aux mesures de la voiture, perforé pour recevoir l’arduino et la raspberry. La plaque possède également une encoche pour laisser passer éventuellement la nappe de la caméra de la raspi. Nous y avons ajouté quelques perforations pour laisser passer quelques câbles par la suite si nécessaire. Finalement, certains trous n’étant pas placés parfaitement ou étant oubliés, nous avons corrigés certaines perforations manuellement, à l’aide de la perceuse et d’un foret.
Photo schema plaque
Nous avions fait le choix de fixer les deux cartes arduino et raspi via un système classique de vis et d’écrous. Cela nous permettait d’utiliser les perforations déjà faites aux préalables sur les deux cartes. En revanche la batterie externe ne pouvant pas être percée, il nous fallait un système d’accroche plus proche de celui de l’encastrement. L’idée était donc de modéliser et d’imprimer en 3D, des sorte de « cache » dans lesquelles ont placerait les quatre coins de la batterie externes. Ces caches seraient quant à eux percés et fixés directement sur la plaque de plexi. Nous obtenions ainsi cette version finale à imprimer en quatre exemplaires.
Photo cache batterie 3d
Malheureusement après une première impression test, nous nous sommes aperçus que le la précision de l’impression laissait à désirer. Ce qui n’était pas acceptable dans notre cas. En effet, le fait de devoir imprimer une sorte de « boite », nécessitait soit l’impressions d’un support de non affaissement qui venait alors créer certaines bavures sur l’intérieur de la pièce, et donc laisser un certain jeu de battement, pouvant laisser s’échapper la batterie, ou même la rayer. Cependant sans ce support, la pièce était inclinée et donc pas exploitable non plus.
Photo piece 3D foirée et expliquer que fin semaine
Semaine 2 (14-18 janvier)
L'objectif principal de cette semaine était de réussir à faire rouler et contrôler la voiture via notre propre système. Nous avons donc essayé de connecter une Arduino et de faire fonctionner la voiture avec une PWM que nous générons, mais sans succès. Nous avons donc décidé d'observer la sortie du récepteur à l'oscilloscope pour déterminer la différence. Nos observations ne correspondaient pas du tout à nos attentes, car la sortie du récepteur de la voiture ne ressemblait pas à une PWM. En attendant de pouvoir discuter avec le tuteur du projet, nous avons fait une nouvelle version de l'application sur une autre branche dans laquelle les commandes sont des valeurs discrètes. Nous avons ainsi deux versions fonctionnelles, ce qui nous permettra de choisir l'architecture de réseau donnant les meilleurs résultats. Nous avons décidé d'utiliser 5 valeurs de direction et 2 valeurs de vitesse différentes, ce qui était également les choix faits par l'équipe gagnante de l'an dernier. Nous avons également modifié le script de vérification du fichier h5 pour l'adapter à ces modifications.
Le mercredi, nous avons enfin réglé les problèmes qui nous empêchaient de faire avancer la voiture. Le premier problème était la fréquence de la PWM, qui était beaucoup trop élevée sur l'Arduino (500Hz au lieu des 50~60Hz pour un servomoteur). Nous avons découvert ce problème après avoir contacté un technicien chez T2M et avoir discuté avec les tuteurs de projet. Pour corriger ce problème, nous avons simplement utilisé la librairie Servo de Arduino qui est conçue exprès pour notre cas. Après cette première correction, la voiture ne fonctionnait toujours pas et nous avons supposé que l'alimentation de l'Arduino n'était pas suffisante. Une mesure au voltmètre nous a permis de déterminer que l'alimentation était en 6.5V soit au-dessus et ce que peut fournir l'Arduino. Nous avons testé avec une alimentation 7.5V et avons pour la première fois réussi à faire bouger les servomoteurs. Enfin, nous avons établi un petit circuit pour réutiliser l'alimentation fournie par le récepteur et remplacer le signal par celui en sortie de l'Arduino. Le dernier dysfonctionnement était du aux masses qui n'étaient pas connectées, ce que nous avons corrigé rapidement. Une fois que les servomoteurs bougeaient, nous avons entrepris de calibrer les valeurs pour les contrôler. Comme nous l'attendions, les angles de rotation pour les servomoteurs sont compris entre -30° et 30°. La valeur moyenne étant 90, la plage de valeurs va de 60 à 120. Une fois cette première étape finie, nous avons répété la procédure pour le moteur brushless principal. Le système a rapidement fonctionné, et nous avons pu déterminer que le moteur commençait à tourner pour une valeur de 100. Nous avons supposé que la valeur maximale était 180 mais nous n'avons pas testé jusque là car la voiture était en position instable.
Une fois ces problèmes réglés, le reste a été assez rapide. Nous avons réalisé un code Arduino pour contrôler la voiture en fonction des instructions reçues sur le port série, et nous avons refait une partie de mécanique pour améliorer le chassis et la gestion des câbles. Le vendredi, nous avons pu faire rouler la voiture pour la première fois sans aucun lien extérieur. Cela nous a permis de faire les premiers tests de caméra et d'apprécier certaines caractéristiques, notamment le rayon de braquage qui est assez élevé. L'orientation de la caméra sera essentielle, d'autant plus que nous n'avons pas un modèle grand angle. Parmi les prochaines étapes, nous allons devoir trouver un système d'attache de la caméra (peut-être imprimé en 3D), construire une piste de test et éventuellement adapter le code de capture d'images. Une fois que nous aurons conduit la voiture suffisamment pour obtenir des données conséquentes, nous passerons à la partie Deep Learning du projet. Pour finir la semaine, nous avons construit un tronçon de piste à taille réelle pour apprécier la vision que la caméra aurait. Nous avons remarqué que la voiture ne voyait la piste qu'environ 1.50m devant elle, ce que nous avons jugé trop lointain. Nous avons donc décidé de commander une caméra grand angle pour remplacer le Camera Module V2. Nous avons également commandé une nouvelle nappe de connexion de 30 centimètres pour avoir plus de liberté au niveau du placement de la caméra.
Il nous fallait donc une nouvelle idée de fixation. Finalement, l’idée d’accumuler les découpe de plexiglas pour un faire une pièce volumineuse en 3D nous paraissait être une bien meilleure idée. Le hasard a en effet bien fait les choses puisque l’épaisseur de la batterie (15mm) était pile un multiple de l’épaisseur du plexi (3mm). De plus le tout parait bien plus propre et esthétique.
Nous avons juste pris soin de découper certaines branches pour pouvoir faciliter l’accès aux ports USB de la batterie. Nous avons donc un squelette global permettant de fixer nos trois pièces maitresses c’est-à-dire l’alim, l’arduino et la raspi. Le montage final ressemble à ceci.
Photo montage final
Les pièces sont correctement maintenues et la plaque est fixable facilement sur la voiture sans encombrer les flans. De puis elle ne demande pas beaucoup d’espace nécessaire supplémentaire en comparaison à l’ancienne configuration.
Finalement nous avons eu quelques soucis avec l’alimentation, que nous n’avons su expliquer. A chaque branchement, s’effectuait un reboot de la raspi mais s’en suivait rapidement une mise en arrêt. Nous n’arrivons toujours pas à comprendre l’origine du problème puisque le lendemain tout cela fonctionnait correctement. Nous soupçonnons un câble USB défectueux à l’origine de cet incident jumelé à un faux contact lors du branchement, et peut être aussi une batterie trop peu chargée. Cependant ce détail nous a fait perdre un peu de temps sur notre expérimentation. Le problème est cependant résolu, n’en parlons plus.
Nous arrivions facilement à alimenter la raspberry avec le port mini usb. Cependant notre câble était trop long. S’ajoute à ceci, le fait que le port mini usb est sur le flanc de la carte et donc élargit l’espace nécessaire latérale (car on le peut pas plier un câble usb à 90 degrés sans l’endommager sérieusement. De plus, le câble reliant la raspi à l’arduino (lui permettant par ailleurs de l’alimenter) prend déjà beaucoup d’espace. Aussi le volume disponible dans la carcasse de la voiture est assez limité. Pour gagner de la place et limité l’encombrement filaire, nous avons décidé de couper un de nos câbles USB de téléphone afin de pouvoir en dénuder le fil « plus » et la « masse ». Les câbles de transfert de données ne nous intéressent pas dans le cas d’une simple alimentation. Nous envisageons alors d’alimenter la raspi via les pins 2 et 6. Après avoir minutieusement dénudé les câbles concernés et soudé des pins à leurs extrémités, nous avions un système fonctionnel. Cependant le tout étant assez fragile, il nous fallait un système permettant de solidifier le tout. Pour cela nous avons suivi les conseils de Thierry qui nous a conseillé d’utiliser la gaine thermique qu’il avait à disposition. Le résultat final est plus que satisfaisant : propre et solide, parfait !
Pour ce qui est d’une éventuelle carte électronique, nous nous interrogeons sur la nécessité et le coté judicieux de cette dernière. En effet, reliant des pins très proches, nous ne savons pas si nous avons réellement besoin d’une faire notre propre circuit imprimé. Des soudures renforcées pour les pins devraient être suffisante. Nous reviendrons éventuellement sur la conception d’une carte électronique si il nous reste du temps en fin de projet, dans un souci de perfections de prototype final. Enfin, nous avons commencé une conception d’une coque profilé pour la voiture. L’ancienne n’est en effet plus fixable suite aux rajouts de la plaque de plexi. Et puis il faut avouer aussi que ça nous amuse de le faire ! Bon… cette première version est plus dans un but d’apprentissage des différentes fonctionnalités que nous offre onshape à vrai dire… Bien que le résultats ne soit pas rebutant, il ne constitue rien d’existant pour autant.
Photo coque voiture oshape
Nous reprendrons la conception d’une nouvelle coque lorsque nous en auront le temps et lorsque nous auront un idée précise de ce que nous souhaitons concevoir. Ce n’est pas la priorité du projet pour le moment.
Semaine 3 (21-25 janvier)
En attendant de recevoir la nouvelle caméra qui nous permettra de passer au Deep Learning, l'objectif de cette semaine sera de faire en sorte que tout soit prêt pour cette seconde étape. Nous devons donc finir la partie mécanique (support de la caméra, ajustements divers) et tenter d'optimiser la partie informatique pour s'assurer qu'elle fonctionne bien le moment venu. Nous allons utiliser un simulateur déjà existant ici pour générer des images d'entraînement avant de pouvoir créer les nôtres. Ces images nous permettront de tester et éventuellement d'adapter notre réseau de neurones. Le simulateur génère une série d'images au format jpg et les commandes associées sont encodées dans le nom du fichier (format frame_<nb_frame>_gas_<vitesse>_dir_<direction>.jpg). L'inconvénient de ce simulateur est que la seule vitesse possible est de 0.5, ce paramètre n'est donc pas pertinent. Les directions fournies sont globalement comprises entre -2 et 2, nous devons donc également normaliser ces valeurs pour matcher nos paramètres. Enfin, nous devons transformer le dossier d'images jpeg en un fichier h5 que nous utilisons dans notre cas.
L’idée en début de semaine était de créer un support pour la caméra. Seulement après quelques essais sur une piste improvisée, nous avons constaté que la caméra offrait une vision trop étroite et restreinte de la piste. Il nous fallait donc une caméra grand angle. De plus la nappe à disposition est trop courte pour permettent une aisance des mouvements et des tests. Il nous en faudrait donc une un peu plus longue. Ces différents imprévus ont donc faits que nous devions prendre en considération une éventuelle marge d’erreur. Nous avons donc cherché de l’inspiration sur les différents sites de partage communautaire de fichiers .stl imprimables par une imprimante 3D.
Nous étions donc partis pour s’inspirer des modèles suivants :
Photo des support de caméra
Nous avions ensuite songé à éventuellement faire un prolongement de support via du pleglis découpé au laser. Mais cela était très vite limité par l’incapicité de cette méthode de créer des pièces complexes en 3D (le cumul des différentes couches d’épaisseur est rapidement insuffisant). Surtout que cette partie doit être la partie la plus fixe de la voiture, on ne peut pas se permettre que la caméra tremble lors de la mise en mouvement de la voiture.
Pourtant, après avoir longuement observé la voiture, nous avons remarqué un « trou » (volontaire de la part des designers de la voiture bien entendu) juste derrière le par-buffle, qui permettait de fixer la caméra très facilement. Ceci nous faciliterait vraiment le travail et rendrait en plus la caméra très discrète, tout en la protégeant de tout éventuel choc.
Photo trou buffle caméra
Cependant, nous craignons que l’angle soit trop incliné et filme trop près de la piste, sans avoir une vision en profondeur correcte sur le reste de la piste.
Nous n’avons actuellement aucun moyen de savoir si cette configuration sera fonctionnelle avec une caméra grande angle et une nappe plus longue. Nous décidons tout de même de supposer que cela sera suffisant. Si ce n’est pas le cas, nous modéliseront et imprimeront rapidement un nouveau support pour la caméra.
En attendant, nous avons décidé de reprendre un nouveau jet de la conception de la « coque » finale de la voiture. Après avoir regardé différents modèle existant dans la vraie vie, nous sommes tombés sur l’image d’un bus scolaire américain version 4x4. Comme cela n’avait aucun rapport avec quoi que ce soit dans notre projet mais nous a bien fait rire, nous avons décidé d’essayer de le reproduire.
Photo bus 4x4
Nous n’avons pas encore terminé cette étape car elle demande beaucoup de précisions, de rigueur et de maitrise de Onshape. Ce que nous n’avons pas encore forcément. Cependant, notre création s’approche peu à peu du modèle original.
Photo bus 4x4 modelisé
Enfin nous avons profité de ce léger temps d’ « attente de composants » pour mettre à jour notre wiki.
notes
wiki néon bus, 4x4, piece cassé a réparé collé cable bleu corps de la voiture missile ? peau banane ? https://www.amazon.fr/Revoltec-RM128-N%C3%A9on-Twin-Set-Boitier/dp/B006W9U29M/ref=pd_sbs_147_1?_encoding=UTF8&pd_rd_i=B006W9U29M&pd_rd_r=812e66c3-1a48-11e9-a12a-4b13213faf1c&pd_rd_w=eTKZW&pd_rd_wg=th5nN&pf_rd_p=5d361e0c-9e85-4b01-8261-3ff932bec9c8&pf_rd_r=A6YME0CC1RQQCEC5ESZW&psc=1&refRID=A6YME0CC1RQQCEC5ESZW conception mecaniques et soudures a expliquer faire toute lintro et tt