IMA5 2018/2019 P21 : Pilotage automatique d'un drone

De Wiki de Projets IMA
(Redirigé depuis IMA5 2018/2019 P21)


Présentation générale

Drone Parrot Bebop 2

Description

Pour réaliser ce projet, nous avons à notre disposition le drone Parrot Bebop 2. Nous ferons donc initialement des essais de vols du drone de manière à le maitriser à l'aide de la manette de pilotage ou alors tout simplement de notre smartphone avec l'application FreeFlight Pro.

Notre projet portera principalement sur l'aspect détection d'objets et analyse de l'environnement en utilisant le traitement d'images. Le développement des applications pourra se faire sur MATLAB en passant par ROS (Robot Operating System) sous Linux, et/ou via une interface homme machine implémenté sur Python.

Une démarche de prospection et recherche bibliographique doit être nécessairement entreprise sur tous ces outils en début de projet.

Pour mener au mieux ce projet, nous avons mis en place une réunion hebdomadaire avec nos encadrants, où nous leur présenterons nos avancées, et choisirons par la suite ce qu'il y a à faire.

Nous travaillerons la plupart du temps en C006 ou C008, mais aussi en C305, car la salle sera équipée prochainement de filet afin de manipuler et faire des tests avec le drone en tout sécurité.

Objectifs

L'objectif de ce projet est double :

  • Analyse de l'environnement à l'aide des différents capteurs disponibles, notamment le capteur image
  • Pilotage automatique du drone développé spécifiquement par les étudiants

Préparation du projet

Choix techniques : matériel et logiciel

Drone Parrot Bebop 2

Environnement Linux

ROS : Robot Operating System

Parrot SDK

Matlab Simulink avec en particulier, la boîte à outils Robotics System

Python pour créer une IHM (Interface Homme/Machine)

Liste des tâches à effectuer

  • Découverte, prise en main et pilotage du drone
  • Recherche/Documentation sur les différents composants du drone
  • Réalisation d'un schéma bloc pour identifier les différents organes du drone et connaitre les différentes interactions qu'il peut y avoir entre eux
  • Recherche/Documentation pour définir quels outils nous allons choisir
  • Stabilisation du drone
  • Gérer le traitement d'images
  • Réalisation d'un rapport final exploitable afin que les personnes souhaitant travailler sur ce projet puissent ajouter eux même ce qu'ils souhaitent, et mettre en avant leurs connaissances et compétences

Calendrier prévisionnel

En cours

Réalisation du Projet

Semaine 1

Durant la première semaine, nous nous sommes entretenues avec nos encadrants de manière à mieux définir le contexte du projet et leurs attentes quant à ce projet. Nous avons ensuite effectuer des recherches générales sur le drone pour connaître ses capacités et être plus familier avec les différents capteurs qu'il possède ainsi que des recherches un peu plus approfondies sur les différentes technologies utilisables avec le drone pour préparer le développement futur.

Cette première semaine a aussi été l'occasion de commencer à prendre en main le drone en effectuant des premiers vols en utilisant l'application Android proposée par Parrot.

Recherches sur le drone :

Inventaire des composants/capteurs

Une caméra verticale pour la stabilisation du drone qui prend une photo du sol toutes les 16 millisecondes et la compare avec la précédente pour déterminer la vitesse du drone.

Un capteur ultrason qui analyse l'altitude de vol jusqu'à 5 mètres.

Un capteur de pression qui mesure la pression de l'air et analyse l'altitude de vol au-delà de 5 mètres.

Un gyroscope 3 axes qui mesure l'angle d'inclinaison du drone.

Un accéléromètre qui mesure la position du drone sur 3 axes et sa vitesse linéaire.

Un magnétomètre 3 axes qui aide à définir la position d'un drone comme une boussole.

Un système mondial de navigation par satellite qui combine un GPS et un GLONASS (système de positionnement par satellite d'origine soviétique) pour la géolocalisation du drone et aide à mesurer la vitesse de drone pour plus de stabilité à haute altitude.


Boîte à outils MATLAB

Nous allons devoir utiliser MATLAB dans le cadre de ce projet pour communiquer avec ROS, mais nous ne savions pas s'il fallait une boîte à outils en particulier ou non. Après plusieurs recherches nous avons trouvé qu'il ne fallait pas de boîte à outils propre au drone à notre disposition. De ce fait, la seule boîte à outils dont nous aurons besoin est : Robotics System Toolbox™

Celle-ci fournit une interface entre MATLAB et Simulink et le système d'exploitation robotique (ROS) qui vous permet de communiquer avec un réseau ROS, d'explorer de manière interactive les capacités des robots et de visualiser les données des capteurs. Il permet de développer, tester et vérifier des algorithmes et applications robotiques. Robotics System Toolbox permet également de créer un réseau ROS autonome directement dans MATLAB et Simulink et importer des fichiers journaux ROS (rosbags) pour visualiser, analyser et post-traiter les données consignées. Ces fonctionnalités vont nous permettre de développer des algorithmes de robotique dans MATLAB et Simulink, tout en nous permettant d'échanger des messages avec d'autres nœuds du réseau ROS. Avec Embedded Coder, nous allons pouvoir générer du code C ++ à partir d'un modèle Simulink pour une application ROS autonome pouvant s'exécuter sur toute plate-forme Linux sur laquelle ROS est installé.

Semaine 2

Lors de la deuxième semaine, nous avons effectué des premiers tests de connexion du drone à un ordinateur. Pour cela, nous avons utilisé le SDK fourni par Parrot ARDroneSDK3 qui possède un code d'exemple permettant de contrôler le Bebop2. Une fois l'ordinateur connecté au wifi du drone, on peut exécuter le programme d'exemple pour faire décoller le drone.

Contrôle du drone avec SDK

Tutoriel d'utilisation de SDK : Fichier:Parrot pour développeurs.pdf

Une fois cette partie réalisée, nous intéressons à la manière de connecter le drone à Matlab. Pour cela nous avons besoin d'utiliser ROS qui est un ensemble d'outils informatique permettant de réaliser des logiciels pour la robotique. ROS permet de faire la passerelle entre Matlab et le drone.

SDK

Le SDK offre une couche d'abstraction sur le bas niveau du drone ainsi peu d'informations issues des capteurs et des actionneurs sont accessibles et il n'est pas possible de piloter directement les moteurs. Néanmoins, Parrot fournit une grande quantité de messages permettant de réaliser des actions complexes (déplacement d'un point A à un point B, retour à la maison, ...) ou des figures acrobatiques (parabole, flip, ...).

Liste des entrées accessibles :

• latitude (double): Position en latitude (en degré)

• longitude (double): Position en longitude (en degré)

• altitude (double): Altitude (en mètre)

• speedX (float): Vitesse relative au nord (en m/s)

• speedY (float): Vitesse relative à l'est (en m/s)

• speedZ (float): Vitesse selon l'axe z (en m/s)

• longitude_accuracy (i8): Erreur de localisation en longitude (en mètre)

• latitude_accuracy (i8): Erreur de localisation en latitude (en mètre)

• altitude_accuracy (i8): Erreur de localisation pour l'altitude (en mètre)

• picture (caméra avant)

• Etat de la batterie : Battery state => percent (u8): Pourcentage de batterie

Liste des commandes offertes par le SDK :

• flip: Le drone fait un flip

• horizontal_panorama: Le drone tourne horizontalement sur lui-même

• dronie: Le drone vole sur une distance donnée avec un angle calculé

• horizontal_reveal: Le drone commence à regarder vers le bas, puis avance tout en regardant lentement à l'horizon

• vertical_reveal: Le drone commence à regarder vers le bas, puis se déplace vers le haut tout en regardant lentement à l'horizon

• parabola: Le drone fait une parabole au-dessus de sa cible et se termine de l'autre côté de celui-ci.

• candle: Le drone vole horizontalement en direction de la cible puis s'envole.

• take off : Décollage

• land : Atterrissage

Le détail sur tous les états et toutes les commandes se trouve ici : https://developer.parrot.com/docs/reference/bebop_2/index.html#bebop-2-

Semaine 3

Pour cette semaine, nous venons d'avoir l'accès au git d'un groupe de chercheurs travaillant également sur le bebop 2, ce qui nous permet d'avoir des informations supplémentaires sur le drone, notamment de la documentation.

Sur ce git, il y a notamment un prototype d'une IHM (Interface Homme/Machine) que nous allons étudier afin de trouver comment nous pouvons récupérer les données du drone en temps réel. Malheureusement, après étude de l'IHM, nous nous sommes rendus compte que la personne n'avait réaliser que l'interface "visuelle" et donc, là où nous pensions trouver des commandes pour récupérer des données, ce n'est qu'en réalité une zone de texte, où la personne a mis des valeurs aléatoires.

Nous sommes donc toujours à la recherche de commandes afin de récupérer des données, notamment via SDK.

ROS

De plus, nous avons profité de cette semaine pour nous intéresser à un autre moyen de communiquer avec le drone: ROS. ROS est une plateforme de développement logicielle pour les robots qui est compatible avec les drones Bebop 2 de Parrot. Nous voulons utiliser cette plateforme pour faire la passerelle wifi entre le drone et Matlab ou un autre langage de programmation.

La prise en main de ROS n'est pas forcément très évidente ce pourquoi nous avons commencé à suivre les tutoriels pour débutant proposés sur le site de ROS.

Qu’est ce que ROS?

ROS (Robot Operating System) est un système open source permettant à un utilisateur de contrôler un robot à partir d’un PC. Il n’a pas de langage de programmation défini et peut être programmé via plusieurs langages. Un système ROS comprend un certain nombres de noeuds indépendants qui communiquent avec les autres noeuds via une messagerie de type publication/abonnement. Par exemple, le driver d’un capteur peut être implémenté comme un noeud qui publie les valeurs du capteur dans un flux de messages. Ces messages pourraient être utilisés par n'importe quel nombre d’autres noeuds, comme des filtres, des collecteurs de données ou des systèmes haut niveau comme des systèmes de guidage ou de recherche de chemin.

Pourquoi utiliser ROS?

Sans ROS, lire/écrire des ressources rapidement est compliqué avec un grand système multi-threadé. Il y a d’autre moyens de résoudre ce problème mais ROS simplifie le processus en s’assurant que les différents threads n’essaient pas de lire ou d’écrire des ressources partagées mais plutôt qu’il publie et s’abonnent à des messages.

ROS nous permettra d'accéder facilement et rapidement aux valeurs des différents capteurs du drone que ce soit directement avec ROS ou en passant par des programmes en Python ou C++ pour pouvoir traiter les données. Et de contrôler le drone de la même manière.

Comment fonctionne ROS?

Le calcul dans ROS est effectué à l'aide d'un réseau de processus appelé nœuds ROS. Ce réseau d'exécution peut être appelé graphe de calcul. Les principaux concepts du graphe sont les nodes ROS, le master, le parameter server, les messages, les topics, les services et les bags. Chaque concept du graphique contribue au réseau d'une manière qui lui est propre.


Graphique de calcul on de ROS
  • Nodes: Les nodes sont les processus qui effectuent les calculs. Chaque node ROS est écrit à l'aide d'une bibliothèque pour ROS tel que roscpp (pour le C++) et rospy (pour le python). Dans un robot, il peut y avoir plusieurs nodes pour exécuter différents types de tâches. En utilisant la méthode de communication de ROS, les nodes peuvent communiquer entre eux et échanger des données. Un des buts des nodes ROS est de découper un grand processus avec toutes les fonctionnalités en plusieurs petit processus avec une fonctionnalité.

  • Master: Le Master ROS fournit un registre des noms des nodes activés et surveille les changements au niveau des nodes. Les nodes ne sont pas capables de trouver les autres nodes, d'échanger des messages ou d'invoquer des services sans Master.

  • Parameter Server: Le parameter server permet à l'utilisateur de sauvegarder les données dans un endroit centralisé. Tous les nodes peuvent accéder à ses valeurs et les modifier.

  • Messages: Les nodes communiquent entre eux en utilisant des messages. Les messages sont de simples structures de données contenant des champs typés qui peuvent contenir un ensemble de données qui peuvent être envoyé à un autre node. Il y a des types standards de données (integer, floating point, boolean ...) et ces types sont supportés par les messages ROS. Il est aussi possible de créer des types personnalisés de messages à partir de ces types.

  • Topics: Chaque message dans ROS est transporté à l'aide de bus nommé appelé topics. Quand un node envoie un message au travers d'un topic, on dit qu'il publie (publish) un topic. Quand un node reçoit un message au travers d'un topic, on dit qu'il s'abonne (subscribe) à un topic. Le node qui envoie et celui qui s'abonne ne sont pas au courant de l’existence l'un de l'autre. Chaque topic à un nom unique et n'importe quel node y a accès et peut envoyer des données au travers de ce dernier tant qu'ils utilisent le bon type de message.

  • Services: Pour certains cas d’application, un modèle de communication publish/subscribe n'est pas suffisant il est alors nécessaire d'utiliser une interaction requête/réponse. Les services ROS permettent de mettre en place une interaction bi-directionnelle de type requête/réponse. On peut définir un service comme contenant deux parties: une pour la requête et l'autre pour la réponse. En utilisant les services ROS, il est possible de créer un node serveur et un node client. Le node serveur fournit le service sous un nom et le client envoie des message de requêtes à ce serveur qui répondra en envoyant le résultat au client.

  • Bags: Le Bag est un format de fichier permettant de sauvegarder et rejouer les données des messages ROS. Le fichier Bag est un mécanisme important pour la sauvegarde de données telles que les données provenant des capteurs qui peuvent être difficiles à acquérir mais qui sont nécessaires pour développer et tester les algorithmes.

source: Mastering ROS for Robotics Proramming de Lentin Joseph

Le schéma suivant décrit le comportement de communication d'un Master et de deux nodes sous ROS.

Schéma du fonctionnement de ROS

Semaine 4

Au fil de nos recherches, nous avons pu remarquer que les technologies que nous souhaitons utiliser sont assez différentes. Nous avons d'un côté ROS, qui est très ouvert, où l'on peut trouver beaucoup d'informations, mais ça reste néanmoins un outil très généraliste dans la robotique.

Alors que SDK de son côté, c'est un peu l'inverse, c'est-à-dire qu'il est très fermé, car nous avons du mal à trouver certaines informations, mais pour autant, c'est l'outil le plus proche du drone.

Cette semaine, nous avons donc focalisé nos recherches sur la récupération de données via SDK, car pour l'instant il n'y a qu'avec cet outil que nous avons réussi à le manipuler (hors smartphone et télécommande).

ROS

De plus, nous avons continué notre exploration de ROS en recherchant comment interagir avec cet outil avec un langage de programmation comme le Python par exemple.

Pourquoi utiliser un langage de programmation avec ROS?

Comme on l'a vu la semaine précédente, on utilise ROS avec des langages de programmation pour pouvoir programmer les comportements des différents nodes du réseau. Il y a trois langages de programmation officiel pour ROS:

  • Python avec la bibliothèque rospy qui favorise la vitesse d’implémentation plutôt que la performance d’exécution de manière à ce que les algorithmes puissent être prototypés et testés rapidement sous ROS.

  • C++ avec la bibliothèque roscpp qui permet aux programmeurs de rapidement interfacer avec les topics, services et parameters en C++. roscpp a été réalisé pour être une bibliothèque ROS très performante.

  • Lisp avec la bibliothèque roslisp qui permet d’écrire des nodes ROS en Common Lisp. La bibliothèque permet de réaliser des nodes rapidement et facilement et permet un débogage interactif.

Comment ça fonctionne?

Ainsi, il existe deux moyens de communication au sein d'un réseau ROS : un fonctionnement publisher/subsciber au travers de topics et un fonctionnement Service/Client. Nous avons donc la possibilité de créer 4 types de nodes pour décrire les différentes actions nécessaires au fonctionnement du système. Il sera possible, par exemple, de programmer un node pour qu'il récupère les données du capteur d'altitude qui publiera les valeurs sur le réseau et de créer des nodes pour les différents moteurs du drone qui s'abonneront à cette publication pour pouvoir réguler l'altitude du drone.

Exemple de Python:

Nous avons donc décidé d’explorer la programmation de nodes avec Python car c’est un langage assez simple à utiliser et proposant de nombreux outils pour le traitement d’images qui nous seront utiles pour la suite du projet.

Dans un premier temps, nous avons réalisé un node publisher qui enverra un message en continu sur un topic et un node subscriber qui s'abonnera à ce topic pour écouter le message publié.

Publisher:

  • Initialisation : dans un premier temps, il est nécessaire d'initialiser le node en mode publisher. Pour cela, la fonction nécessite le nom du topic sur lequel les messages vont être envoyés, le type du message ainsi que la taille de la queue pour les messages envoyés.

pub = rospy.Publisher(topic_name, msg_class, queue_size)
  • Envoi d'un message: une fois le publisher correctement initialisé il est possible d'envoyer des messages en utilisant la fonction puvblish qui prend en paramètre le message à envoyer.

pub.publish(std_msgs.msg.String("hello world"))

Subscriber:

  • Initialisation : de la même manière que pour le publisher il est nécessaire d'initialiser le node en mode subscriber. Cette fois ci, la fonction prend en paramètre le topic auquel on s'abonne, le type du message et la fonction a appelé lorsque le message est reçu.

rospy.Subscriber(topic_name, msg_class, callback)

Ensuite, nous avons réalisé un serveur qui réalise une fonction d'addition de deux entiers et un client qui en se connectant au service enverra deux entiers au serveur pour qu'il effectue l'addition.

Service:

  • Initialisation : pour initialiser un service il faut lui donner un nom, le type du service et la fonction qu'il doit exécuter.

s = rospy.Service(service_name, service_type, function)

Client:

  • Connexion au service : dans un premier temps le client doit attendre que le service soit disponible pour pouvoir s'y connecter.

rospy.wait_for_service('service_name')
  • Déclaration de la fonction : une fois que la connexion est établie on peut déclarer la fonction que l'on veut utiliser sur le service.

function = rospy.ServiceProxy('service_name', service_type) 
  • Envoie de requêtes : et enfin lui envoyer des requêtes.

answer = function(arguments)

Semaine 5

SDK

Concernant le SDK, nous avons profité de cette semaine pour chercher un moyen de récupérer les données des capteurs. Pour cela, nous avons repris l'exemple de programme proposé par Parrot pour le Bebop: dans ce programme on reçoit les valeurs des capteurs lorsqu'il y a un changement d'état cependant ces valeurs ne sont jamais affiché ou sauvegardé. Nous avons donc ajouté l'écriture de ces valeurs dans un fichier. Cependant, lors de la lecture du fichier les données ne sont pas cohérentes: toutes les valeurs proviennent du même capteur et elles ne changent jamais. De plus, les capteurs sont identifiés par un nombre et non par un nom on ne peut donc pas identifier quel capteur envoie des données.

ROS

Durant cette semaine, nous avons commencé à explorer la toolbox Matlab Robotics System qui permet d'interagir avec un environnement ROS déjà existant de manière à communiquer avec des systèmes robotiques ou de créer un environnement ROS sous Matlab. Cependant, pour pouvoir utiliser ROS avec Matlab il nous faudrait passer plus de temps à apprendre des commandes ROS que ce soit pour ROS en lui même ou pour Matlab et nous ne sommes pas sûres que Matlab ait des avantages sur Python pour l'application qu'on veut en faire.

Semaine 6

Le but de cette semaine est de se connecter au drone via ROS pour cela il est nécessaire d'installer le driver du bebop pour ROS. Nous avons donc installé bebop_autonomy qui est le driver pour les nouveaux drones Parrot pour ROS basé sur le SDk de Parrot ARDroneSDK3.

Installation de bebop_autonomy

Architecture d'un workspace catkin

Dans un premier temps, il est nécessaire de créer un workspace catkin qui permet d'organiser les différents packages nécessaires au fonctionnement du projet ROS. Il suffit ensuite de récupérer le projet git du driver et de construire le projet ROS.

Pour cela, il faut d'abord installer les 3 packages d'Ubuntu suivants : build-esstential, python-rosdep, python-catkin-tool. En ligne de commande cela donne :

sudo apt-get install build-essential python-rosdep python-catkin-tools

Pour compiler à partir de la source, il faut cloner le code source dans un espace de travail catkin nouveau ou existant, puis utiliser rosdep pour installer des dépendances et enfin compiler l'espace de travail à l'aide de catkin. Les commandes suivantes illustrent cette procédure dans un nouvel espace de travail Catkin.

mkdir -p ~/bebop_ws/src && cd ~/bebop_ws
catkin init
git clone https://github.com/AutonomyLab/bebop_autonomy.git src/bebop_autonomy
rosdep update
rosdep install --from-paths src -i
catkin build

Utilisation de bebop_autonomy

Une fois le driver installé, il est possible de le lancer en tant que node autonome ou que nodelet, cependant, seul le nodelet est conseillé dans le cas ou l'on veut effectuer un traitement sur le flux vidéo provenant du bebop. Une fois le projet ROS correctement, il est possible d'envoyer des commandes basiques au drone pour le contrôler en publiant des messages du on type sur le topic correspondant. Par exemple, pour faire décoller le drone il faut envoyer des messages de type std_msgs/Empty au topic takeoff de la manière suivante:

$ rostopic pub --once [namespace]/takeoff std_msgs/Empty

Cependant, il faut faire attention lorsque l'on contrôle le drone de cette manière car lors de la réception d'une commande pour faire avancer, reculer ou tourner le drone il l'effectue jusqu'à la réception d'une nouvelle commande.

Semaine 7

Récupération de données avec Python

Notre projet se basant sur le traitement d'images, il pourrait être avantageux de travailler avec du Python car la bibliothèque de traitement d'images OpenCV est performante avec Python.

PyParrot

PyParrot a été conçu afin de programmer différents drones Parrot, dont le Bebop2, en utilisant Python. Initialement, cette interface a été développée pour enseigner aux enfants de tous âges les concepts STEM (programmation, mathématiques, etc.) en leur permettant de programmer un drone pour qu'il vole de manière autonome. Toutes les informations liés à cette bibliothèque se trouve ici.

  • Installation

Au préalable, il faut vérifier que nous avons bien Python 3 car la bibliothèque ne fonctionne qu'avec cette version, ce qui était bien notre cas. Ensuite, pour analyser les fichiers XML dans le SDK de Parrot nous utilisons la commande suivante :

pip install untangle

Une fois ceci fait, il suffit de cloner et installer le git correspondant au projet (à retrouver ici).

  • Études et application

Dans un premier temps, notre but est de réussir à récupérer des données du drone, peu importe laquelle exactement. Sur ce projet nous pouvons trouver un dossier contenant plusieurs exemples de code Python afin de contrôler le drone. En étudiant plusieurs d'entre eux, notamment demoBebopIndoors.py et demoBebopTricks.py, nous avons pu trouver les fonctions essentielles pour contrôler le drone : le connecter par exemple. En s'inspirant de ces 2 fichiers, nous avons créé un programme Python, dans le but de récupérer l'état du drone. En effet, dans le code demoBebopTricks, on peut remarquer qu'il est demandé de retourner l'état du drone. En allant chercher plus d'explications dans la documentation, plus précisément au niveau des Bebop sensors, nous avons pu apprendre que le paramètre utilisé dans le code exemple correspondait à la position du drone et pouvait prendre comme "valeur" : "landed", "takingoff", "hovering", "flying", "landing", "emergency", "usertakeoff", "motor_ramping", "emergency_landing". A la suite de cette étude, nous avons créé le programme suivant :

Code Python pour récupérer l'état du drone


En le testant sur le drone nous avons obtenu le résultat suivant :

Résultat du test

Nous pouvons remarquer tout d'abord que nous récupérons des données dont nous ne savons pas à quoi elles correspondent (dû à l'appel de la fonction bebop.ask_for_state_update()). Mais sur la suite nous récupérons bien la position du drone "landed", ce qui est cohérent car le drone est resté au sol pour ce test afin d'éviter tous risques de dommages. Nous pouvons également récupérer le pourcentage de la batterie, et nous pouvons voir qu'à la fin du test le drone se déconnecte correctement.

Pour cette semaine, nous n'avons pas encore trouvé comment récupérer d'autres données, cela sera à approfondir par la suite.

Nous avons donc essayé de nous connecter au drone pour le contrôler et pour récupérer les valeurs des différents capteurs. Nous avons testé plusieurs bibliothèques Python fonctionnant avec les drones Parrot mais certaines se basent sur le SDK de Parrot et ont donc les mêmes limites que le SDK.


Récupération des données avec ROS

La semaine dernière, nous avons réussi à nous connecter au drone avec ROS et à le contrôler, cependant, nous n'étions pas parvenues à récupérer les valeurs des différents capteurs nous avons donc cherché à obtenir la vidéo du drone et les valeurs des capteurs en temps réel.

Dans un premier temps, nous avons cherché à afficher la liste de tous les topics sur lesquels le drone publie des valeurs pour savoir ce qu'il est possible de récupérer.

rostopic list

Une fois la liste des topics connue, nous avons cherché à afficher la vidéo provenant du drone. Pour cela, ROS propose l'outil rqt qui peut s'abonner aux topics sur lesquels des vidéos sont publiées. Nous avons donc utilisé cet outil pour visualiser la vidéo du drone, on constate un léger délai lors de la visualisation de cette vidéo.

Utilisation de rqt pour visualiser la vidéo

Après avoir réussi à récupérer la vidéo, nous nous sommes intéressées aux valeurs publiées par les différents capteurs et à comment les afficher. Pour cela, nous avons tout d'abord afficher l'état de la batterie.

Affichage de l'état de la batterie avec ROS

On reçoit une nouvelle valeur dès qu'il y a changement d'état de la batterie. Cette valeur est accompagnée d'un numéro de séquence ainsi que du timestamp du moment où le message a été envoyé. En plus de récupérer la valeur de la vitesse du drone, de son altitude et de sa position. Nous avons réalisé une acquisition de l'altitude du drone en vol, cette fois ci, on ne reçoit pas un paquet à chaque changement de valeur mais à une certaine fréquence. Encore une fois, l'entête du message est composé du timestamp et d'un numéro de séquence puis nous avons la valeur de l'altitude. Sur l'image ci-dessous on peut voir deux paquets reçus après avoir donné au drone l'instruction d'atterrir.

Paquets reçu pour l'altitude

Après avoir récupéré nos données en ligne de commande, nous avons utilisé un subscriber en Python qui s'abonne au topic d'odométrie, récupère les valeurs de position linéaire en x et y du drone ainsi que son angle d'inclinaison et les affichent dans le terminal. Il nous faut maintenant travailler sur la manière de traiter les données que l'on reçoit et comment transmettre les données au drone en fonction de ce qu'on a reçu.

Semaine 8

Récupération des valeurs avec ROS

Nous avons, dans un premier temps, cherché à utiliser des fichiers pour stocker les données que l'on reçoit du drone pour pouvoir les traiter. Cependant, étant donné l'architecture des programmes sous ROS, il serait idéal d'avoir un programme qui lit les données (Subscriber) et un autre qui traite les données et envoie les instructions (Publisher) nous aurons donc un problème avec l'aspect temps réel du projet si on conserve un fonctionnement avec des fichiers. Il faut donc que l'on réfléchisse à la mise en place d'une file de message pour échanger les données entre les deux programmes.


Traitement de la vidéo

Nous avons commencé à nous intéresser au traitement des images pour détecter des objets dans le flux vidéo provenant du drone. Pour réaliser ceci, il est nécessaire de convertir le format de la vidéo publié sur le topic image_raw qui est propre à ROS et n'est pas compréhensible par la bibliothèque de traitement d'images OpenCV en un format vidéo propre à OpenCV pour pouvoir traiter la vidéo. Nous avons donc réalisé un premier programme qui s'abonne au topic image_raw, convertit la vidéo et dessine un cercle dans le coin supérieur gauche, nous affichons ensuite la vidéo obtenue pour s'assurer que tout s'est bien passé. Une fois que nous savons que le programme précédent fonctionne, nous avons réalisé un deuxième programme nous permettant de détecter un cercle dans la vidéo et de dessiner un cercle autour de celui-ci, ainsi qu'un point en son centre. Pour cela, nous utilisons une fonction proposée par ROS : la transformée de Hough. Nous avons remarqué que le traitement de la vidéo par cette fonction est très long et ne pourrait donc pas être utilisé si on veut conserver un aspect temps réel.

Pour la suite, il nous faudrait poser proprement ce qu'on cherche à détecter dans l'image et quelle démarche à mettre en place pour détecter ces objets.


Récupération de la vidéo avec Python (suite)

Pour notre projet, nous allons devoir utiliser la vidéo pour lui appliquer différents traitements d'images. C'est donc une des données principales que nous devons essayer de récupérer. Pour ceci, nous passons toujours par la bibliothèque PyParrot. En effet, celle-ci comporte un fichier exemple concernant la vision et donc la vidéo du drone. Nous allons de ce fait, travailler sur cet exemple afin d'essayer de récupérer la vidéo de la caméra du drone en passant uniquement par Python.


Code Python exemple pour récupérer la vidéo du drone


On peut remarquer que ce programme utilise notamment OpenCV2, mais aussi un programme inclut dans la bibliothèque PyParrot : DroneVision, celui-ci utilise notamment ffmpeg qui est une collection de logiciels libres destinés au traitement de flux audio ou vidéo. En termes simples, ce programme vise à :

  • Se connecter au drone
  • Si la connexion s'est déroulée correctement, de commencer à enregistrer la vidéo de la caméra
  • Si la vidéo a bien commencé, un message pour confirmer ceci, et après pour éviter de faire voler le drone, il sera demandé de bouger le drone manuellement
  • On a alors au total 30 sec pour bouger le drone, avant qu'il n'arrête la vidéo
  • Une fois ceci terminé, on déconnecte le drone

Avant de tester tel quel cet exemple, nous avons dû installer dans un premier temps OpenCV2, puis ffmpeg. Ces deux logiciels installés, nous pouvons passer au test de ce programme directement sur le drone. La première partie concernant la connexion se passe normalement. Par contre, le programme ne va pas plus loin et cela nous sort une erreur concernant ffmpeg. Après diverses recherches sur les forums, nous nous rendons compte que cela vient sûrement de notre version de ffmpeg qui n'est pas la plus récente. Il faudra donc mettre à jour le logiciel et tester à nouveau le programme.

Semaine 9

Traitement de la vidéo

Décomposition des composantes de l'image RGB

Pour cette semaine nous avons défini que nous allions travailler avec 4 flèches de couleurs différentes en définissant que chaque couleur correspond à un déplacement différent. Pour reconnaître les différentes flèches, nous allons donc travailler en décomposant les différentes composantes couleurs de l'image de manière à ne conserver que les flèches de la couleur de la composante et les flèches grises. Les flèches de couleur de la composante sont en blanc et les flèches grises sont du même gris dans chaque composante.

Une fois les composantes isolées, on peut travailler avec l'histogramme de l'image pour déterminer la couleur des objets présents dans l'image.

Récupération de la vidéo avec Python (suite)

Il nous faut cette semaine mettre à jour ffmpeg afin de voir si c'est la cause de notre erreur lors du lancement de notre programme exemple. Après mise à jour du logiciel ffmpeg, il n'y a plus d'erreur, le programme se déroule correctement et va jusqu'au bout. Notre programme crée alors un fichier bebop.sdp, nous ne savions pas au départ ce que cela était, et pensions alors que c'était la vidéo sortante du drone car l'ordinateur essayait de la lire comme une vidéo. Mais la lecture de ce fichier était impossible avec un lecteur vidéo (Vidéos, VLC, ...). Nous nous sommes alors renseignées sur ce qu'était un fichier sdp et voici ce que l'on a retenu :

SDP est l’abréviation de Session Description Protocol. Le Session Description Protocol définit un standard qui décrit les paramètres pour l’échange de média (souvent média en streaming) entre deux (normalement) points. En termes simples, le protocole SDP est une déclaration par un terminal habilité a transmettre des données média de ses capacités de réception. Une déclaration type devrait nous donner les informations suivantes :

  • Quelle adresse IP est préparée pour recevoir le flux média entrant
  • Quel numéro de port attend le flux média entrant
  • Quel type de média le terminal s’attend à recevoir (typiquement audio)
  • Quel protocole le terminal attend pour échanger l’information (typiquement RTP)
  • Quel codage de compression le terminal est capable de décoder (codec)

Le SDP ne transmet pas lui-même de média, mais se limite à la négociation de paramètres d’échange de média compatibles. Le flux média lui même est géré par un autre canal et protocole. On s'est donc rendu compte que ce fichier n'allait pas être notre vidéo mais seulement les paramètres d'échange de celle-ci. En ouvrant maintenant ce fichier avec un bloc notes (ou autres applis de traitement de texte), nous avons connaissances de ces paramètres qui sont les suivants :


Parametres video.png


• Le paramètre c correspond à l'adresse IP du drone

• Le paramètre m correspond au port

• Le paramètre a correspond au protocole rtp

Semaine 10

Traitement de la vidéo

Nous avons imprimé les flèches utilisées la semaine dernière pour tester la reconnaissance de couleurs puis nous avons enregistré des images contenant les flèches provenant du drone. Après avoir passé les images ainsi obtenues au même traitement que celui utilisé la semaine dernière, nous nous sommes rendues compte que l'intensité des flèches de couleurs est beaucoup moins nette que sur le test réalisé précédemment et nous ne pourrons donc pas utiliser uniquement cette méthode pour identifier nos flèches.

Résultat obtenu pour la composante verte

Nous nous sommes donc intéressées à la détection de features dans l'image pour nous aider à trouver les flèches. Dans un premier temps, nous avons utilisé la détection de corners à l'aide de l'algorithme de détection de Harris. Un corner est un point dont les voisins sont dans au moins deux directions de bordures différentes. Ils peuvent être interprétés comme la jonction de deux bordures où une bordure est un soudain changement de luminosité dans l'image.

Résultat de l'algorithme de Harris

En réglant le seuil d'ouverture de la fonction on est capable de détecter les coins de toutes les flèches.

Nous nous sommes ensuite intéressées à la détections des edges de l'image en utilisant l'algorithme de Canny qui nous permet d'extraire la structure des objets présents dans l'image pour réduire le montant de données à traiter.

Résultat de l'algorithme de Canny

Sur l'image ci-dessus,on voit que les contours des flèches sont bien formés. On pourrait essayer de nettoyer les contours du reste de l'image pour ne garder que la flèche ou sélectionner une région d'intérêt correspondant à la feuille sur laquelle est imprimée la flèche pour réduire la zone à traiter et ne conserver que la partie de l'image qui nous intéresse.

Semaine 11

Cette semaine, Mme. Lecocq nous a donné un cours de traitement d'images de manières à nous informer des différentes techniques utilisables pour trouver une forme précise dns une image. Il nous faut maintenant déterminer quelles sont les caractéristiques qui définissent une flèche tout en gardant en tête que les images proviendront du drone et qu'on ne sera pas tout le temps à la même distance de la flèche qui ne sera donc pas toujours de la même tille. Il faut donc trouver des caractéristiques qui ne dépendent pas de la taille de la flèche.

Semaine 12

Isolement des objets bleu, vert et rouge

Durant cette semaine, nous avons continuer à explorer les options proposées par OpenCV pour extraire les caractéristiques des flèches. Nous avons donc commencé à réaliser une application permettant à l'utilisateur d'effectuer le traitement voulu sur l'image qu'il a spécifié (ou une image par défaut). A la fin de la semaine, l'application permettait de réaliser les traitements suivants :

  *Détecter un objet bleu/rouge/vert et possibilité de combiner les images obtenus
  *Détecter et dessiner les contours des objets présents dans l'image
  *Trouver et dessiner les centres de gravité des objets présents dans l'image
  *Trouver et remplir les surfaces des objets dans l'image
  *Dessiner le plus petit rectangle possible permettant d'entourer les objets de l'images
  *Dessiner le plus petit cercle possible permettant d'entourer les objets de l'images
  *Réaliser la squelettisation des objets


Contours et centres de gravité
Bounding Boxes

Il nous reste à ajouter d'autres fonctions que nous avons déjà testés à l'application ainsi que la possibilité de sauvegarder les images suite aux traitements effectués.








Semaine 13

Liste des fonctionnalités de l'application

Durant cette semaine, nous avons continuer notre application en ajoutant les différents traitements que nous avions déjà utilisés au cours du projet mais qui n'étaient pas encore inclus dans l'application. De plus, nous avons ajouté une fonctionnalité nous permettant de détecter des formes basiques au sein d'une image en recherchant les contours des objets puis en les approximant à des polygones. Une fois les contours approximés, on compte le nombre de côtés du polygone pour déterminer la forme dont il s’agit. Ainsi, nous avons défini que les polygones à trois côtés sont des triangles, ceux à quatre côtés sont des carrés, ceux à cinq côtés sont des pentagones, ceux à sept côtés sont des flèches et ceux à plus de 19 côtés sont des cercles. Cette fonctions ne nous permet donc pas de différencier les carrés des rectangles ou des losanges et on considère que tous les heptagones sont des flèches.

Détection de formes simples

Sur l'image ci-dessus, on a colorié en rose les flèches, en bleu les cercles, en blanc les carrés, en vert les pentagones et en cyan.

Documents Rendus

Fichier:Soutenance intermédiaire P21.pdf