IMA4 2018/2019 P14

De Wiki de Projets IMA


Présentation générale

  • Nom du projet : Voiture autonome en modèle réduit
  • Résumé : Le but du projet est de réaliser une voiture de taille réduite, capable de se déplacer en autonomie sur un circuit
  • Etudiants : Hugo DEJAEGHER et Brandon ELEMVA

Description

Notre projet consiste à réaliser une voiture modèle réduit, capable de réaliser des tours de piste en autonomie sur un circuit tracé au sol. Ce projet s'inspire du concours IronCar France, qui a vu le jour très récemment et auquel nous pourrions par ailleurs participer. Notre véhicule autonome sera réalisé à partir d'une voiture radio-commandée à l’échelle 1:16 ou 1:8, modifiée de façon à être contrôlée par une Raspberry pi 3 (et éventuellement une Arduino), connectée à une webcam et à un ordinateur sur lequel le code sera exécuté. Il est à noter qu'aucun capteur ne doit être utilisé, la webcam seule sera utilisée pour identifier le tracé du circuit.

Objectifs

Dans le but de réaliser notre projet nous devrons remplir les objectifs suivants que nous pouvons répartir en 3 parties.

Partie mécanique :

  • Réaliser un support pour la webcam qui permette de l'élever à au moins 10 cm du sol (en prenant en compte la taille du châssis)

Partie électronique :

  • Les moteurs seront commandés par une carte Arduino
  • La partie Deep Learning et l'analyse des images de la webcam seront traitées par un ordinateur connecté à une RaspBerry pi 3

Partie informatique :

  • Faire apprendre au robot un parcours en le pilotant manuellement via une manette
  • Concevoir un programme permettant au véhicule de mémoriser le parcours préenregistré
  • Produire un véhicule prenant des décisions de façon autonome via plusieurs réseaux de neurones : méthode du Deep Learning (ou apprentissage approfondi)

Analyse du projet

Positionnement par rapport à l'existant

Les principaux concurrents de notre projet ne sont autres que les différents participants du concours IronCar, en particulier les gagnants des sessions précédentes, qui partagent par ailleurs leurs codes et liste de matériel sur le site du concours. Ces gagnants s’élèvent au nombre de 2 équipes, qui se partagent le sommet du podium à tour de rôle.

Analyse du premier concurrent

Il s'agit de l'équipe patate 42, gagnante de la course officielle de février 2018 ainsi que des courses d'entraînement de mai et octobre 2018. Les membres de cette équipe sont issus de l'école 42, un établissement supérieur d'autoformation, non reconnu par l’État et dont l'objectif est de former des développeurs. Leur meilleur temps pour un tour est de 25 secondes.

Analyse du second concurrent

Le deuxième concurrent est l'équipe Axionable, composée de membres issus de l'entreprise du même nom, spécialisée en Data Science et Data consulting, basée à Paris. Selon eux, leur force réside dans la qualité des données qu'ils utilisent pour la reconnaissance du circuit (qualité, diversité et labellisation semi-manuelle des photos). Ils ont gagné la course officielle de juin 2018 ainsi que les entraînements de mars et septembre 2018. Leur meilleur temps en un tour est de 29 secondes.

Scénario d'usage du produit ou du concept envisagé

La première étape consiste à poser la voiture sur la ligne départ puis à la piloter manuellement à l'aide d'une manette Xbox. Plusieurs tours de piste sont alors effectués pendant que la caméra de la raspberry prend une photo toutes les 0.1 secondes afin de constituer une base de données. À chaque photo correspond alors un label correspondant à une instruction : "droite", "gauche", "tout droit", "droite serrée" ... . Le but est de prendre un maximum d'images correctement labellisées afin d'affiner la précision de l'analyse du trajet.

Ensuite, ceci étant fait, une analyse de la base de données (les images et leur label) est hautement conseillée afin de corriger d’éventuelles erreurs de labellisation (une image correspondant à un virage nommée "tout droit" par exemple). Ces premières étapes sont primordiales et, associées à un bon code, réduiront considérablement les chances de sortie de piste. Le but étant d'arriver à un résultat égal ou proche de zéro.

Enfin, on peut alors positionner la voiture sur la ligne de départ et lancer le programme de pilotage automatique ainsi qu'un chronomètre pour mesurer sa performance. Le but est de réaliser 3 tours de pistes en moins de temps possible, avec une pénalité de 5 secondes à chaque sortie de piste.

Voyons cela sous un autre angle :

Judith, étudiante en IMA4 à Polytech Lille est une amatrice de course de mini voitures. Elle a participé à certaines de ces compétitions et a souvent fini très bien classée (sans pour autant en gagner). Judith s'intéresse également à l'univers de l'électronique et de l'informatique et souhaiterait pouvoir rendre sa voiture plus autonome car elle trouve répétitif et lassant de devoir piloter son véhicule sur un circuit. En effectuant des recherches, elle entend parler de la compétition IronCar et se dit que ça serait une excellente opportunité pour elle de réaliser son projet de voiture autonome. Alors, elle décide de prendre son ancienne voiture et de remplacer le circuit électrique s'y trouvant par une Arduino, une Raspberry et une webcam. Avec l'aide de ses enseignants et des documents obtenus lors de ses recherches, elle parvient à établir un programme permettant d'effectuer du Deep Learning. Grâce à ce programme, elle parvient à faire apprendre à sa voiture le parcours et l'optimise afin de permettre à son véhicule d'effectuer ce même parcours le plus rapidement possible. Elle espère bien gagner la compétition IronCar cette année.

Réponse à la question difficile

  • Est-il possible de faire les traitements sur la Rpi ou faut-il faire un pré-traitement off line sur un PC ? (quels soft, quels réseaux de neurones ?)

La Raspberry a une mémoire vive de 256Mo. Pour pouvoir réaliser du deep learning, Il faudrait disposer d'un ordinateur avec une mémoire vive suffisamment grande (32 Go sont fortement recommandés). De ce fait un traitement offline sur pc est requis avant de laisser la raspberry prendre le relais. Le langage utilisé sera le Python (langage par défaut de la Raspberry). Dans notre cas, nous utiliserons les réseaux de neurones convolutifs dits CNN (Convolutionnal Neural Network) ou plus précisément de Transfer Learning.

Les CNN sont, les modèles les plus performants pour classer les images. À son entrée, une image sous forme de matrice de pixels à laquelle elle attribue 2 dimensions pour les niveaux de gris et une 3e pour les couleurs RGB. Ils se décomposent en 2 parties :

  • Une partie convolutive : c'est une sorte d'extracteur de caractéristiques des images. En d'autres termes, une image est passée à travers plusieurs filtres d'affilé créant ainsi de nouvelles images appelées cartes de convolutions. Certains filtres intermédiaires réduisent la résolution de l’image par une opération de maximum local. Ainsi, les cartes de convolutions sont mises à plat et concaténées en un vecteur de caractéristiques, appelé code CNN;
  • Une partie perceptron multicouche à laquelle est connecté le code CNN: c'est un type de réseau neuronal formel organisé en plusieurs couches au sein desquelles une information circule de la couche d'entrée vers la couche de sortie uniquement, les couches sont entièrement connectées entre elles : c'est un réseau de propagation (chaque couche est constituée d'un nombre variable de neurones, les neurones de la dernière couche étant les sorties du système global). Les valeurs numériques obtenues sont généralement normalisées entre 0 et 1.
Convolutionnal Neuronal Network

De cette façon une image qui a une profondeur de 3 couches (le nombre 3 correspondant aux 3 canaux RGB) pourra ainsi résulter en une matrice d’une profondeur de 5, si le réseau convolutif est constitué de 5 filtres. Avec la technique du transfert learning, on réduit la complexité du CNN en utilisant des réseaux pré-entraînés (on exploite la connaissance acquise sur un problème de classification général pour l’appliquer de nouveau à un problème particulier).


  • Comment faire pour piloter efficacement les moteurs ?

Pour le contrôle des moteurs, nous utiliserons un shield contrôleur de servos PWM 16 canaux pour Raspberry Pi car elle n'est pas vraiment en mesure de contrôler des servos moteurs continu, ces moteurs nécessitant une impulsion répétitive très spécifique (avec un synchronisation précise) pour leur indiquer la position (l'angle).

Préparation du projet

Cahier des charges

Le véhicule modèle réduit devra entre autre répondre aux critères suivant:

Phase d'apprentissage

  • Pouvoir être conduit par le biais d'une manette sans fil.
  • Capturer une image toute les 0.1 seconde grâce à la camera implantée.
  • Stocker dans une base de données les images capturées et leur assigner un label (un titre faisant référence à une action à effectuer)
  • Appliquer des effets aléatoires aux images (ombres, miroir, luminosité par exemple) pour diversifier la base de données sans allonger la durée d'apprentissage.

Phase de conduite autonome

  • Etre capable de rouler en autonomie sur la même piste que celle où il a réalisé son apprentissage.
  • Reconnaître des virages et des lignes droites plus ou moins grandes et adapter sa vitesse en conséquence.
  • Détecter une sortie de piste sans avoir recours à des capteurs autres que la caméra.
  • Pouvoir faire exécuter le code de réseau de neurones par l'ordinateur suffisamment rapidement pour pouvoir réagir le plus rapidement possible (proche du temps réel).

De manière générale

  • Prévoir un support solide afin que la caméra ne bouge et ne tombe pas suite à une secousse.
  • Etre capable de communiquer sans fil avec un ordinateur, de manière fiable par le biais de la raspberry.

Choix techniques : matériel et logiciel

Logiciel

Contrôle des moteurs :

Nous avons choisi de ne pas utiliser d'arduino en complément du raspberry puisque celui-ci prendrait de la place et nous obligerait à rajouter des câbles et à nous doter d'une meilleure alimentation externe.

De plus, il ne présente pas d'avantages particuliers en comparaison avec un raspberry pi 3 doté d'un module pour le contrôle des servomoteurs.

En effet comme nous l'avons dit dans la réponse à la question difficile, un raspberry seul ne permet pas un bon contrôle de plusieurs servomoteurs mais l'utilisation d'un Hat PWM permet de régler efficacement le problème.

Partie informatique :

Le choix du python comme langage de programmation semble le plus indiqué dans le cadre d'un réseau de neurones. En effet même s'il est loin d'être "le plus rapide", la bibliothèque Numpy lui permet de rester compétitif.

Mais c'est surtout sa syntaxe facile et concise qui nous permettra de progresser plus rapidement et aisément que dans d'autres langages. C'est d'ailleurs un langages très utilisé dans les applications relatives à l'intelligence artificielle.

En outre, en utilisant Python, nous sommes certains de trouver de nombreuses librairies qualitatives et de la documentation. On peut aussi souligner qu'il s'agit du langage de base de la Raspberry et que des bibliothèques Python sont fournies avec le Hat PWM pour le contrôle des moteurs.

Liste du matériel

  • 1 Monster Truck radiocommandé électrique à l’échelle 1/10 de la marque T2M (commande passée en avance par les enseignants référents).
  • 1 manette de Xbox(one ou 360) sans fil (pour la phase d'apprentissage).
  • 1 Raspberry pi 3 [1].
  • 1 ordinateur/PC doté de suffisamment de RAM pour exécuter le code du réseau de neurones.
  • 1 camera pour raspberry à objectif "fisheye" et 10 fps grand minimum [2].


  • 1 set de jumpers mâle/femelle pour breadboard (pour relier les moteurs au shield du raspberry)[3].
  • 1 batterie externe capable de fournir 5V et au moins 2A pour l'alimentation de la raspberry[4].
  • 1 cable USB/micro USB pour relier la raspberry au pc.

Liste des tâches à effectuer

Partie mécanique :

  • Réaliser un support par impression 3D pour la webcam qui permette de l'élever à au moins 10 cm du sol mais également de la protéger. Fixer ce support sur la partie avant de la voiture.

Partie électronique :

  • Raccorder les moteurs à la Raspberry pi en les connectant au shield qui sera posé sur celle-ci.
  • Connecter une batterie auxiliaire de 5V et 2A à la Raspberry pour l'alimenter (la puissance délivrée par la batterie du véhicule n'étant pas assez grande pour garantir que les moteurs tourneront bien à pleine puissance tout en alimentant la carte).

Partie informatique :

  • Configurer la Raspberry Pi (installation des librairies, configuration des ports de carte pour le shield, paramétrage de la caméra).
  • Apprentissage préalable du parcours par le robot : grâce à une manette de type Xbox 360, effectuer un tour du circuit en pilotant le robot. Durant ce tour, la caméra placée sur le robot prendra plusieurs captures d'image (1 image toutes les 100 millisecondes). La manette ne sera utile que pour le tour d'apprentissage. Pour la suite du travail, nous ferons sans elle.
  • Stocker les images capturées et les différentes positions prises par le joystick de la manette lors de ce tour d'apprentissage que nous associeront à l'image qui leur correspond dans une base de données ou un tableau labellisé.
  • Établir un programme de Deep Learning nous permettant d'analyser chaque image, ou plus précisément la position de la ligne du parcours sur l'image, vérifier la position du joystick à cet instant, et y associer une position du servomoteur servant à la direction des roues avant.
  • Effectuer une série de plusieurs test sur circuit (sans manette) en vue de valider ou non notre modèle. Si valide, l'optimiser pour le rendre plus précis.

Calendrier prévisionnel

Réalisation du Projet

Feuille d'heures

Tâche Prélude Heures S1 Heures S2 Heures S3 Heures S4 Heures S5 Heures S6 Heures S7 Heures S8 Heures S9 Heures S10 Total
Analyse du projet (recherche des concurrents, descriptions des objectifs, scénario d'usage, matériel) 2h30 1h
Préparation de l'oral 2h
Remplissage du wiki (réponse à la question difficile, préparation du projet, choix techniques et matériels) 1h30 30 min 30 min 1h 30 min 1h 1h 30 min 30 min
Installation de l'OS sur la Rapberry / établissement de la communication entre la Rpi et une Wiimote 2h
Capture vidéo et prise d'image avec la Rpi 1h 2h
Réception et traitement des données provenant de la manette (adresses des boutons) 2h 3h
Gestion des moteurs du véhicule 3h30
Initiation au Deep Learning 4h 3h 3h30
Prise en main de Keras/Tensorflow, création et test des datasets 4h 4h 4h 4h
Modélisation 3D 2h
Mise en marche et pilotage du véhicule via la manette Xbox 2h
Test de la phase de prétraitement des données via la platforme Google Colab 3h 2h
Test et évaluation du temps de calcul lors du traitement des datasets via un PC 1h

Prologue

Semaine 1

Nous avons débuté par une phase de recherche autour de la communication entre la Raspberry Pi et la manette Xbox : nous nous sommes penchés sur le programme qui nous permettra de récupérer les données des différents actionneurs (boutons et joysticks) de la manette. Pour le choix de la manette, nous avons pris une Wiimote car elle dispose d'un module Bluetooth intégré facilitant la communication avec la Rpi 3 qui dispose aussi, par défaut, d'une interface Bluetooth.

Mais avant cela, nous avons commencé par configurer (installation de l'OS) la Rp1. Pour connecter en série une Raspberry Pi à un PC, il faut connecter le fil noir (la masse) à la pin 6 (GND), le jaune (TX) à la pin 8 (RX Raspberry) et le orange (RX) à la 10 (TX Raspberry).

Une autre option consiste à connecter la Raspberry sur un écran afin d'accéder directement à son interface graphique, choix que nous avons fait afin de gagner du temps. Une fois la configuration effectuée, via le le terminal de la Rpi, nous avons établi la communication entre la Rpi et la Wiimote. La Rpi étant une interface "maître" et la Wiimote une interface "esclave", la communication est possible. Un smartphone étant une interface "maître", la connexion est impossible avec la Rpi, donc inutile d'effectuer des test avec un smartphone.

Suites aux essais effectués par nos collègues en 5A, nous avons découvert que le contrôleur moteur n'est pas une PWM comme prévu mais un modulateur de fréquence. Cela nous a ramené à la question de l'utilité du shield moteur commandé pour la Rpi qui, lui, est un shield PWM. Nous maintenons cependant ce choix.

Prochaine étape, récupérer et stocker les données concernant les boutons de la Wiimote (s'ils sont pressés ou non) sur la Rpi.

Semaine 2

Missions effectuées

  • Récupération des adresses de chaque bouton sur la Raspberry (en pressant un bouton nous sommes en mesure de récupérer son adresse, de la stocker dans une variable dont le nom correspond à celui du bouton et ranger cette variable dans un fichier.txt pour le moment.
  • Activation de la caméra de la Raspberry et capture vidéo puis prises d'images toutes les 10ms. Pour l'instant ces images sont rangées dans un dossier.
  • Initiation au Deep learning. Suivre le lien [5] pour avoir accès à des cours et des travaux pratiques centrés sur l'apprentissage approfondi.
  • Pour installer Anaconda : [6]
  • Pour installer PyTorch : [7]


Semaine 3

Nous avons reçu le shield raspberry pour le contrôle des servomoteurs ( Adafruit 16-Channel 12-bit PWM/Servo HAT ). Les différents headers (2x20 pour le raspberry et 4 3x4 pour les câbles PWM) n'étant pas montés, nous les avons soudés.

Missions effectuées

  • Analyse de la bibliothèque python fournie par Adafruit.
  • Test du Shield PWM à l'aide d'un simple programme python et d'un servomoteur.
  • Test sur le servomoteur de direction et le controlleur de vitesse de la voiture RC (SCHEMA !!!!)

Après avoir effectué les différents tests, nous nous sommes rendu compte que, bien que l'on contrôle la direction parfaitement, on arrive seulement à faire tourner le moteur principal en plein régime, et seulement en marche avant. Le problème semblant venir de la fréquence d'envoie du signal par le shield, nous décidons d'observer les signaux PWM en sortie du récepteur fm de la voiture, afin de comprendre l'allure des signaux supposés être reçu par le contrôleur de vitesse. Nous sommes alors en mesure de faire tourner le moteur à vitesse réduite. Cependant nous comprenons à la suite de plusieurs test qu'il ne s'agit pas du seul paramètre à prendre en compte pour faire rouler la voiture à faible vitesse : il faut également "lancer" le moteur. C'est à dire qu'en le faisant tourner à rapidement puis en diminuant la vitesse ensuite, on peut le faire tourner plus lentement.

Semaine 4

Missions effectuées

  • Réalisation d'un code combinant le contrôle des moteurs et la lecture de l’état des boutons de la manette Xbox, nous sommes alors en mesure de contrôler la voiture avec la manette Xbox, par l’intermédiaire du raspberry avec le PWM hat.
  • Réalisation d'un code gérant simultanément la fonction caméra (prenant des images touts les 0.1 secondes) et le code du contrôle de la voiture par utilisation de la manette.
  • Suite de l'entraînement sur les réseaux de neurones : création d'un réseau test. Ce réseau avait pour objectif de classer des séries de 4 images dans 10 catégories prédéfinies selon le contenu de celles-ci (chien, chat, avion, voiture...) et d'estimer le pourcentage de précision du réseau ainsi que le temps de traitement approximatif (4 min environ pour une série de 4 images).


Semaine 5

  • Élaboration d'un dataset d'images (on a utilisé des images aléatoires sur internet) et test du programme python créé avec ce set d'images : test peu concluant, le problème vient de l'outil utilisé à savoir Tensorflow. Bien que très pratique en terme de traitement d'image, Keras semble être une bonne alternative en terme de facilité de prise en main et de rapidité de traitement de calcul. Nous allons donc nous tourner vers Keras.
  • Test de la caméra avec pour objectif de prendre 1 photos toutes les 0.1 secondes : test positif, nous sommes en mesure de prendre des photos avec la caméra de la Rpi tout en pilotant le véhicule. La Rpi est donc en mesure de gérer les tâches de prise de photos et mouvement du véhicule en parallèle.


Semaine 6

  • Création et impression du support 3D de la Rpi que l'on fixera sur le véhicule.
Rpi avec son shield moteur et le support voiture
  • Suite aux difficultés rencontrées lors des précédents essais, on a décidé de passer par l'outil Keras. L'outil est assez pratique à utiliser mais un peu plus complexe à prendre en main (sans trop de difficulté). Conception du code et test de lecture d'un dataset. Quelques erreurs apparentes au niveau de la compilation à résoudre.







Semaine 7

Voiture sans carrosserie + Rpi
  • Cette semaine, les IMA5 ayants fini leur projet, nous avons pu accéder à la voiture radiocommandée. De plus, nous avons obtenue une batterie externe de 20000 mAh. Nous avons donc pu réaliser les mesures du châssis de la voiture afin de pouvoir réaliser la structure pour fixer la raspberry et la batterie.
Le support en Lego + Rpi
  • Une fois les mesures réalisées, nous avons décidé de réaliser cette structure en Lego, en nous inspirant des boîtiers de raspberry Lego disponibles à Polytech. Ainsi, en utilisant les bonnes pièces, nous avons été en mesure de réaliser une structure solide, ne nécessitant aucune vis ou points de colle et où il est possible d'ajuster la position de la camera à volonté.








Semaine 8

Voiture et son support batterie + Rpi
  • Nous avons finalisé la réalisation de la structure supportant la batterie, le raspberry et la camera, en y perçant des trous de manière à ce qu'elle puisse se fixer directement sur le châssis de la voiture à l'aide des clips métalliques, de la même manière que la carrosserie fournie avec la voiture.
  • Nous avons ensuite adapté de code du contrôle manuel de la voiture à l'aide de la manette Xbox, puisque les moteurs différent de ceux de notre voiture personnelle, que nous avons utilisé jusqu'à présent pour pouvoir avancer malgré la non-disponibilité de la voiture RC de polytech dédiée aux projets.
  • Nous avons ensuite testé le bon fonctionnement de tout cela avec un test de conduite à la manette de Xbox.
Entrainement de notre réseau



  • Coté réseau de neurones : nous avons établi un programme permettant d'effectuer la phase de prétraitement des images en leur affectant un label à chacune. Le programme semble fonctionnel et prêt à l'emploi. Nous étant basé sur un set existant, il ne reste plus qu'à l'appliquer sur notre datasets.
  • Suite aux résultats peu satisfaisants obtenus lors de la précédente séance, nous avons effectué un nouvel entraînement sur notre réseau de neurones en nous inspirant d'un modèle existant. Le but de la manoeuvre était de voir le temps mis par le PC pour entraîner notre réseau de neurones en vue d'une possible optimisation de ce modèle. Pour cela, nous avons effectué une série de 10 entraînements à la suite et, globalement, nous avons observé un temps de calcul d'à peu près 5 min pour chaque entraînement ce qui est assez long.

Documents Rendus