L’objectif de notre projet est de mettre au point un robot qui d’une part est capable de se mouvoir dans son environnement de manière autonome, mais aussi de pointer une cible à l’aide du canon laser qu’il porte sur sa tourelle. La base de travail est une voiture télécommandée sur laquelle nous avons implémenter les éléments nécessaires à la réalisation de notre projet. Le projet intègre des technologies de traitement d’image en particulier des cartes de disparités à partir de l’acquisition vidéo de la caméra
Elle est maintenant équipée d’une caméra et d’un laser, et est capable de se déplacer toute seule. En utilisant des cartes de disparité, elle planifie son prochain mouvement, évite les obstacles et pointe son laser vers des cibles prédéfinies.
Matériel supplémentaire utilisé
- 1x Raspberry Pi, elle commande l’ensemble des autres composants
- 1x caméra 5Mp, pour l’acquisition de l’environnement dans lequel le robot se mouvoit
- 2x micro Servo Moteur, pour la mobilité du laser sur les 2 axes nécessaires
- 1x H-brige, pour le contrôle du moteur initialement présent sur la voiture
- 1x châssis secondaire, pour accueillir le matériel ajouté
- 1 batterie externe, pour fournir de l’énergie à la Raspberry Pi et au moteur
Contenus de la page
Modélisation
La voiture d’origine fournit certes un premier châssis, mais celui-ci est ouvertement inexploitable tant l’ensemble des éléments initialement présents (moteur, servo-moteur de direction, …) entraîne un relief important ne permettant pas d’ajouter facilement de nouveaux éléments dessus. Pour contourner ce problème, nous avons mis au point un nouveau châssis afin de pouvoir ajouter nos éléments facilement. Ainsi le modèle suivant a été mis au point, en prenant en compte manuellement toutes les mesures à exploiter sur la voiture afin de produire un châssis secondaire qui s’adapte convenablement à l’existant.
A cela s’ajoute quelques pièces secondaires qui vont notamment servir à constituer la tourelle mais aussi une pièce permettant une meilleure stabilité sur le châssis existant.
Rendu
Après impression 3D des éléments évoqués, montage des éléments, et une fois les branchements effectués, le robot s’apparente à cela :
On y aperçoit bien la caméra à l’avant, la Raspberry en arrière plan, le H-bridge sur la partie droite, et la tourelle avec le canon laser sur la partie haute de la voiture.
Réalisation du code
Dans ce projet, une étape cruciale a été la mise en œuvre du code pour traiter les images transmises par la caméra et créer des cartes de disparité. Ces cartes, largement utilisées dans les véhicules autonomes, servent à éviter les obstacles en représentant la profondeur de l’environnement observé, à travers colorimétrie donnée à chaque pixel de l’image. Elles peuvent également aider à reconnaître des formes et à déduire des actions, comme c’est le cas pour notre laser dans ce projet.
Pour générer ces cartes de disparité, nous avons d’abord tenté d’utiliser des algorithmes de traitement d’image disponibles dans des bibliothèques comme OpenCV. Cependant, cette approche n’a pas donné de bons résultats car les paramètres pouvaient varier sensiblement et notre système ne dispose que d’une seule caméra. Cela nous empêchait de générer des images stéréoscopiques, généralement utilisées pour créer des cartes de disparité.
Nous avons donc opté pour l’utilisation de modèles d’intelligence artificielle pré-entraînés, capables de calculer des cartes de disparité à partir d’une image unique. La difficulté résidait dans la recherche d’un modèle adapté à notre projet, qui devait tenir compte de la qualité de la caméra, de la performance de notre Raspberry Pi et du temps d’exécution qui ne devait pas être trop important pour ne pas engendrer une latence trop importante quant à la réaction du robot en aval. Nous avons testé de nombreux modèles, comme Midas et Monodepth2, mais c’est finalement DenseDepth qui a retenu notre attention. Ce modèle génère des cartes de disparité très pertinentes pour notre projet.
Un autre défi a été l’implémentation de ce code sur notre Raspberry Pi. Nous nous sommes rapidement rendu compte que la version de Python disponible sur notre Raspberry Pi 2.0 n’était pas suffisamment récente pour exécuter TensorFlow, la bibliothèque d’apprentissage automatique que nous utilisions. Nous avons donc décidé de déporter le calcul des cartes de disparité sur un ordinateur distant.
Cela a nécessité la création d’un serveur pour envoyer les images de la Raspberry Pi à l’ordinateur, puis renvoyer les données traitées à la Raspberry Pi. Nous avons d’abord utilisé Flask, une bibliothèque Python, pour créer ce serveur, mais les performances étaient insuffisantes. Nous avons donc décidé d’utiliser la bibliothèque C++ Boost pour créer notre serveur, ce qui a grandement amélioré les performances.
Ensuite, nous avons créé le programme qui calcule et traite la carte de disparité pour déterminer quels inputs envoyer à la Raspberry Pi. Ce fut une tâche complexe, car le calcul de la carte de disparité est une opération gourmande en ressources et prend environ une seconde, même sur un ordinateur relativement puissant.
Enfin, le programme renvoie les inputs à la Raspberry Pi, qui les traite à l’aide d’un programme Python. Ce dernier envoie ensuite des informations aux moteurs via un signal PWM (Pulse Width Modulation), ce qui permet de contrôler la vitesse et la direction de la voiture.
Ainsi, malgré les nombreux défis techniques, nous avons réussi à créer un système de traitement d’images fonctionnel pour notre projet
Voici donc le rendu en condition réelle de notre modèle :
On peut voir ici que notre modèle détecte un obstacle sur la gauche, et indique alors à la Raspberry de tourner à droite (ce qu’indique la flèche verte), pour l’éviter et poursuivre son chemin.
Lorsque le robot se retrouve face à un obstacle qu’il ne peut pas contourner, la Raspberry reçoit pour ordre de reculer.
Enfin dans le cas où le robot ne rencontre pas d’obstacles, en particulier, le comportement par défaut envoyé à la Raspberry est de continuer tout droit.
Optimisation et améliorations
Après avoir réussi à mettre en place le système de traitement d’image, nous nous sommes concentrés sur l’optimisation et les améliorations possibles.
Nous avons commencé par optimiser le modèle de DenseDepth que nous avions choisi. En ajustant certains paramètres, nous avons réussi à améliorer la qualité des cartes de disparité générées, ce qui a permis à notre robot de mieux détecter les obstacles afin de naviguer plus efficacement.
Nous avons également travaillé sur l’amélioration de la communication entre la Raspberry Pi et l’ordinateur distant. En peaufinant le code du serveur, avec notamment de la compression d’image, nous avons réussi à augmenter la vitesse de transmission des données, ce qui a permis d’obtenir une meilleure réactivité de notre robot.
Difficultés rencontrées
La première difficulté et non des moindres fut de s’adapter à une structure complexe et mal adaptée à l’ajout d’éléments complémentaires.
Cependant la difficulté majeure fut le contrôle de la direction. En effet, à l’origine la voiture était prévue pour être contrôlée par une télécommande, or nous ne souhaitions pas que le mouvement soit contrôlé par celle-ci. Ainsi il nous fallait pouvoir prendre la main sur ce servo-moteur, or il s’est avéré que ce servo-moteur était HS. Nous devions donc le remplacer. Cela fut une tâche assez laborieuse, car aucun servo-moteur n’avait une roue crantée de sortie identique au servo-moteur d’origine, or cela était indispensable pour pouvoir s’adapter au système en aval du servo-moteur. Pour cela, nous avons récupéré un micro servo-moteur que nous avons démonté, et dont il a fallu échanger la roue crantée de sortie par celle du servo-moteur HS d’origine. Cependant les dimensions de cette roue n’étant pas les mêmes que celle présente initialement sur le servo-moteur modifié, il a fallu réusiner le plastique de la partie supérieur du servo-moteur afin que la nouvelle roue ne vienne pas frotter et même se bloquer contre la structure. Et cela fut particulièrement compliqué à réaliser sur un composant d’une si mauvaise qualité.
Bien que cela fut finalement réalisé, le système de transmission de la commande de direction étant composé de 2 liaisons sphériques à doigt, nous n’avons pour le moment pas réussi à faire fonctionner cette direction.