IMA5 2018/2019 P36

De Wiki de Projets IMA
Révision datée du 26 février 2019 à 18:12 par Aayoub (discussion | contributions) (Documents Rendus)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)


Présentation générale

Description

Dans le cadre de ce projet, le drone Parrot Bebop 2 est mis à disposition à des fins expérimentaux. Nous ferons initialement des essais de vols de drones de manière à le maitriser à l’aide de la manette de pilotage ou de l'application smartphone FreeFlight Pro. Nous avons décidé de nous focaliser sur l’aspect suivant : Le maintien en équilibre en hauteur du drone, avec rejet de perturbations, en le pilotant de manière autonome (sans l’utilisation des manettes ou d'une application smartphone).

Le développement des applications pourra se faire sous Linux en passant par ROS, Robot Operating System, grâce à Matlab Simulink ou une application sous le langage Python. Une démarche de prospection et recherche bibliographique est nécessairement entreprise afin de se renseigner le plus possible sur les outils utilisables.


Composants drone Parrot Bebop 2

Objectifs

L'objectif est de pouvoir rendre autonome un drone afin qu'il puisse se maintenir en hauteur et se stabiliser automatiquement lors de perturbations. Nous devons pour cela prendre en main le drone au niveau de tous les aspects afin de pouvoir implémenter le programme que l'on souhaite.

L'application qui sera mise en place se fera en principe sous Linux grâce à ROS et Simulink ou par une application Python.

Des réunions hebdomadaires se tiendront avec les encadrants afin de s’échanger sur les avancées du projet.

Préparation du projet

Cahier des charges

- Découvrir, prendre en main et piloter le drone

- Réaliser un schéma bloc pour desceller les différents organes et voir les différentes interactions

- Aspect stabilisation en hauteur et compensation des perturbations

- Utilisation possible de la caméra frontale afin de dicter une commande (facultatif)

- Prises en mains des outils utilisables et faire un choix sur lequel utiliser

- Rendre exploitable le travail final afin que les personnes souhaitant travailler sur ce projet puissent rajouter et mettre en avant leurs connaissances et compétences

Choix techniques : matériel et logiciel

- Drone Parrot Bebop 2

- Environnement Linux

- ROS : Robot Operating System

- Matlab Simulink avec Toolbox Robotic system

Calendrier prévisionnel

Calendrier prévisionnel

Réalisation du Projet

Semaine 1

Lors de la première semaine, nous avons convenu un rendez-vous avec nos encadrants, Mme Lecocq et Mr Nakrachi, afin de discuter et de fixer les attentes concernant ce projet. Nous avons évoqué les sujets suivants :

- L'organisation des rencontres étudiants-encadrants

- Ce que l'on attend du projet

- Ce qu'ils attendent du projet

- Les informations actuellement à leurs dispositions pour la réalisation du projet

- La gestion du projet

Nous avons par la même occasion fixé donc les objectifs de ce projet.

De ce fait afin de se lancer, nous avons tout d'abord effectuer des recherches sur l'appareil que nous utilisons pour connaitre plus en détail son fonctionnement mais également user de toutes ces capacités.

Ce drone est composé des éléments suivants :

- Caractéristiques techniques :

   Poids : 500 g
   Autonomie : 25 min
   Nombre de moteurs : 4
   Capacité de la batterie : 2700 mAh
   Altitude maximale de vol : 150 m
   Vitesse max : 60 km/h

- Une caméra verticale : Elle permet le maintien d’un point fixe. Une fréquence de comparaison d'une image du sol à la précédente de 62,5Hz soit 16ms.

- Un capteur à ultrason : Ce capteur permet de calculer l’altitude de vol jusqu’à 5 mètres.

- Un baromètre (capteur de pression) : Il permet de mesurer la pression et de calculer l'altitude de vol lorsque celle-ci dépasse les 5 mètres.

- Un gyroscope 3 axes : Il permet de calculer l’angle d’inclinaison de l’appareil.

- Un accéléromètre : Il permet de mesurer l’orientation du drone sur 3 axes et sa vitesse linéaire.

- Un magnétomètre 3 axes : Il donne la possibilité de définir la position du drone, à l’image d’une boussole.

- Une puce GNSS (GPS + GLONASS): Cette puce permet la géolocalisation du drone avec précision et aide à mesurer la vitesse au sol de façon très fine pour optimiser la tenue du point fixe en vol stationnaire.


Suites aux recherches effectuées sur le drone, nous nous sommes tournés sur les boites à outils essentielles à Matlab pour mener à bien les objectifs. La principale toolbox que nous allons utiliser est Robotic System. Cette Toolbox fournit des algorithmes de robotique communs et inclut une interface entre MATLAB et Simulink et le Robot Operating System (ROS). Avec cette boîte à outils, on peut explorer des données du robot en mode interactif, le design(la conception, tester des algorithmes avec un simulateur et un robot physique, générer du code en C ++ et analyser des données du journal du robot.

Grâce aux recherches effectuées, nous avons remarqué que nous devions contrôler le drône en wifi et qu'il était préférable de gerer la communication avec le drône avec ROS (Robotics Operating System). ROS est un ensemble d'outils informatiques open source permettant de développer des logiciels ou programmes pour la robotique. Nous allons donc dans ce projet, creer un programme Matlab-Simulink, l'envoyer sur ROS grâce a la Toolbox Robotic System puis gerer la connexion jusqu'au drône via ROS.

Semaine 2

Lors de cette semaine, une réunion avec les encadrants a été mise en place le 26/09 afin de communiquer ce qui a été fait jusqu'ici. Une demande auprès des encadrants concernant la référence et la datasheet des composants du drone Parrot Bebop 2 a été sollicité. Un travail approfondi sur les différentes commandes ROS, la toolbox Robotic System et les différents moyens de communication avec le Bebop 2 via le SDK.

Nous nous sommes concentrés tout d'abord sur le SDK

Afin d'installer le SDK, nous procédons de la façon suivante :

  • Installation du SDK
  • Compilation de l'éxecutable
  • Utilisation de l'exemple

Pour l'étape d'installation nous devons aller chercher le fichier d'installation sur Git. Pour réaliser ceci nous utilisons la commande repo qui va définir exactement où trouver les repositories, quelles branches récupérer, où créer les dossiers, etc. La commande est la suivante

     repo init -u https://github.com/Parrot-Developers/arsdk_manifests.git -m release.xml

Une fois le fichier télechargé, on synchronise ensuite tous les repositories :

     repo sync

Maintenant que les repositories sont bien synchronisés, nous pouvons compiler l'exécutable crée lors du téléchargement du fichier. Pour ce faire, nous faisons :

     ./build.sh -p arsdk-native -t build-sdk -j

Nous avons donc crée des fichiers présents dans /out/Unix-base/staging/usr

Build arsdk





Nous avons rencontrés quelques soucis lors de ces commandes car pour pouvoir les réaliser, nus avons du telecharger un système d'exploitation (ici Debian 9). Mais, une fois ce dernier mi, nous devions installer manuellement tous les packages nécéssaires (comme man, python3, c++...) ce qui a donné lieu a de nombreuses erreurs.

Une fois le SDK pret a être utilisé, nous avons donc essayer de lancer un executable d'exemple pour pouvoir manipuler le drone. Cet executable se nomme BebopSample et nous le compilons en utilisant :

     ./build.sh -p arsdk-native -t build-sample-BebopSample -j

Nous retrouvons donc l'executable ci dessous :

executable BebopSample




L'éxécutable a donc été crée a partir d'un fichier .C présent en ~/packages/Samples/Unix/BebopSample

Code BebopSample


Nous pouvons donc, en utilisant la commande vi, voir quelles sont les commandes nécessaires pour contrôler le robot.

ROS est un outil ouvert mais assez généraliste quant à son utilisation dans certains programmes. SDK quant à lui est un outil fermé où seules des instructions pré-faites de Parrot peuvent être utilisées.


Caractéristiques clefs de la toolbox : ( A FINIR )

Semaine 3

Nous avons eu accès au dossier du projet de Cristal qui porte également sur le Bebop2. Leur projet consiste principalement à récupérer des données de vols mais également de pouvoir le contrôler et d'intégrer des programmes. Suite à quelques recherches, nous sommes arrivées aux conclusions suivantes pour accéder aux entrées sorties du drone. :

- Par défaut, le Bebop2 est pilotable via le SDK de Parrot

- Possible d'utiliser d'autres outils comme ROS ou Robompap3

Le SDK permet de connecter, de piloter, recevoir un directe de la caméra, sauvegarder et télécharger des médias (photo ou vidéo), envoyer des plans de vol, de piloter automatiquement et de mettre à jour le drone. FreeFlight3 utilise le SDK. Peu d'informations issues des capteurs et des actionneurs sont accessibles avec le SDK et il n'est pas possible de piloter directement les moteurs. Néanmoins, Parrot met à dispositions des commandes permettant de réaliser des figures ou des tâches complexes tel que des flips ou le trajet d'un point A à un point B. ( Lien d'utilisation SDK : https://developer.parrot.com/docs/SDK3/#general-information )

Liste des entrées accessibles avec le SDK :

- latitude (double): Position en latitude au dixième de degrés

- longitude (double): Position en longitude au dixième de degrés

- altitude (double): Altitude en mètres

- speedX (float): Vitesse relative au Nord en m/s (Quand le drone se deplace vers le Nord, vitesse > 0)

- speedY (float): Vitesse relative à l'EST en m/s (Quand le drone se deplace vers l'Est, une vitesse > 0)

- speedZ (float): Vitesse sur l'axe Z (Quand le drone passe d'une position haute à une position basse, vitesse > 0) (in m/s)

- roll (float): Valeur du mouvement en roulade (en radian)

- pitch (float): Valeur de tangage (en radian)

- yaw (float): Valeur de lacet (en radian)

- 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 grâce à la caméra avant

- Vidéo, accès en directe de la caméra si un écran est connecté

- État de la batterie : Pourcentage de batterie


Liste des commandes offertes par le SDK : ( Lien sur les différentes commandes et comment les implémenter https://developer.parrot.com/docs/reference/bebop_2/index.html#bebop-2-commands )

- flip: Drône effectue un flip

- horizontal_panorama: Rotation horizontale du drone

- dronie: Vol du drône sur une distance donnée avec un angle calculé

- horizontal_reveal: Inclinaison du drône vers le bas, puis avance en stablisant la caméra vers l'avant.

- vertical_reveal: Inclinaison du drône vers le bas, puis monte en hauteur en stablisant la caméra vers l'avant.

- parabola: Le drone esquive une cible en effectuant un mouvement en parabole.

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

- take off : Décollage

- land : Atterrissage

Nous savons qu'à travers SDK , nous pouvons effectuer ces tâches avec le drône, le travail est donc de pouvoir lié ces tâches avec ROS afin de pouvoir récupérer les données mais également pouvoir implémenter des tâches effectuées automatiquement .

Semaine 4

Apres ce début de recherche sur ROS et le SDK de Parro, nous avons donc commencé a installer, dans un premier temps le SDK afin de pouvoir nous connecter au drone et lancer l'une des commandes de base. Afin d'installer le SDK, nous avons donc tout d'abord décidé de l'installer sur le sous-système Ubuntu present sur Windows 10 afin de pouvoir utiliser matlab en meme temps et donc de récuperer les fichiers Simulink que l'on créera. Ce sous-système va nous permettre d'avoir un Shell sur Windows et donc de pouvoir installer SDK et ROS avec de simples lignes de commande (ce qui n'est pas possible avec l'invite de commande Windows). Nous avons fait ce choix car pour le moment, nous ne possèdons pas Matlab sur Linux. Les lignes de commande pour installer le SDK sont donc identiques.


Le prochaine objectif est de connecter le drone avec ROS et de pouvoir juger de l'utilité de matlab sur le drone bebop2.

Nous avons tout d’abord commencé notre porjet avec la version 18.0 de ubuntu. Nous avons réalisé le controle du drone avec SDK avec succés. Nous passons alors à l’installation de ROS. Ayant choisi la version kinetic qui est la plus complète et la plus stable, nous nous sommes rendus compte que celle-ci n’était compatible qu’avec la version 14.0 et 16.0 de ubuntu. Nous nous sommes tournés en premier lieu sur la version melodic qui est la seule compatible avec la version 18.0. Suite à cela, des erreurs de compilation pour des fichiers inexistants et des dependances, nous avons opté de downgrade à ubuntu 16.0 pour pouvoir utiliser ros kinetic. Après le downgrade, nous avons installé à nouveaux les différents outils extern afin de pouvoir compiler le SDK et ROS. Les outils externes pour compiler le SDK sont les suivants :

 git 
 build-essential
 autoconf 
 libtool 
 python 
 python3   
 libavahi-client-dev
 libavcodec-dev
 libavformat-dev
 libswscale-dev
 libncurses5-dev
 mplayer

Semaine 5

Une fois le SDK de Parrot installé et testé, nous avons installé le système d’exploitation Robotique ROS. (Robotic Operating System). Ce dernier est considéré comme un système d’exploitation pour robot pour l’ensemble des services qu’il peut fournir comme par exemple la gestion de bases de données, la gestion de la concurrence, la gestion des processus ou ensemble le paramétrage de robot.

Pourquoi utiliser un OS et pas directement un logiciel adapté ?

Nous avons décidé d’utilisé un OS pour faciliter l’exécution et la gestion des programmes. En effet, dans notre cas précis, nous souhaitons commander en temps réel notre robot et donc recevoir de nombreuses données des capteurs pour pouvoir le commander. Le fait d’utiliser un OS nous permettra d’éviter de perdre du temps sur la gestion de la mémoire, la gestion des processus et d’avoir un accès simple aux différentes données.


Nous avons fait le choix d’utiliser ROS pour plusieurs raisons. La première est la comptabilité vaec notre drone. Notre drone est en effet ouvert, ce qui nous permet de pouvoir travailler dessus mais il n’est pas compatible avec tous les OS. Nous nous sommes rendu compte que nous pouvions utiliser ROS ainsi que Microsoft Robotics Developper Studio pour pouvoir le contrôler.

Nous avons décidé de ne pas utiliser Microsoft Robotic Developper Studio pour la simple et bonne raison que les programmes sont créés avec un langage managé et de préférence C#. Or ROS nous permet de faire de la programmation en C++, en Python, en Lisb ainsi qu’en Java ce qui est plus simple pour nous. La seconde raison est que ROS commence à être très utilisés dans de nombreux laboratoires de recherche et que nous pouvons donc trouver beaucoup d’information et d’aides d’utilisation.

Comment est structuré ROS ?

ROS est structuré de la manière suivante :

Structuration ROS

ROS propose une architecture souple permettant la communication entre les processus et entre les machines. Ces processus sont appellés « nodes » ou « nœuds ». Un nœud peut etre par exemple un capteur, un moteur ou encore un algorithme. Chaque node peut être appélle d’une façon ou d’une autre en fonction de l’action qu’il est train de réaliser. En effet, un node qui publie des données est un « publisher ».

A contrario, un node quisouscrit à des données est un « subscriber ». La communication entre chaque node se fait via des topics. Un topic est un système de transport de l’information basé, comme dit précédemment, sur le système de publisher/subscriber. Un topic est standardisé (le type d’informations qui est publié sur le topic est toujours formé de la même manière) et sert entre guillemet de bus d’informations. Cette communication entre 2 nœuds est gérée par un Master.

Un master est une sorte de base de données permettant aux différents nœuds de s’enregistrer et donc de se connaitre entre eux. La communication d’un message se fait comme ceci :

• Le premier nœud avertit le master qu’il a une donnée a publier • Le deuxième nœud avertit le master quil souhaite souscrire a une donnée • La connexion entre les 2 nœuds est créés

Un nœud peut etre à la fois publisher et subscriber.

Le topic est donc un mode de communication asynchrones permettant la communication entre plusieurs nœuds. Il existe néanmoins un autre mode de communication qui est le Service. Le service est un mode de communication qui permet la communication synchrone entre 2 nœuds.

Communication ROS

Quelles sont les différents fichiers utilisables ?

Concernant l’utilisation de fichier ROS, il existe 2 concepts : celui de package et celui de stack.

Le plus courramment utilisé est le package. Un package est un répertoire de nœuds (décrit précédemment). Il possède également les librairies externes, les données…

Quant à lui, le stack est une collection de package permettant des fonctions plus complexe comme la localisation… L’un des interet de ces fichiers c’est que ce sont tous des éxécutables. Cela signifie que le non-fonctionnement de l’un d’entre eux pour une quelconque raison n’entraine pas de problèmes sur les autres vu qu’ils sont tous indépendants les uns des autres.

Installation de ROS

Concernant son installation, l’idéal est d’installer ROS Kinétic pour sa stabilité et ses ressources disponibles. Durant les premières semaines de projet, nous utilisions Ubunto 18 et Debian 9 ce qui nous a contraint d'utiliser ROS Kinetic. Afin de procéder a l’installation (de ROS kinetic), nous avons du crée un workspace Catkin (Déjà fait) et configurer les « repositories » de permettre « non-free » et « contrib » . Pour ceci, nous allons dans le fichier /etc/apt/sources.list et nous ajoutons les 4 lignes suivantes :


    deb http://deb.debian.org/debian-security/ stretch/updates main
    deb-src http://deb.debian.org/debian-security/ stretch/updates main
    deb http://deb.debian.org/debian stretch-updates main
    deb-src http://deb.debian.org/debian stretch-updates main

Concernant l'installation de ROS Kinetic, nous avons également du configurer les "repositories" de permettre « restricted » et « universe » et "multiverse".

Une fois enregistré, nous faisons l’installation comme ceci :

    sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'

Puis :

    sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116

Nous pouvons donc installer ROS :

    sudo apt-get install ros-kinetic-desktop-full

Initialisation de Rosdep

    sudo rosdep init
    rosdep update

Configuration de l’environnement

    echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc
    source ~/.bashrc

Dependances pour « build » les packages

    sudo apt-get install python-rosinstall python-rosinstall-generator python-wstool build-essential

Concernant ROS, afin de le faire fonctionner, nous devons installer un environnement de travail adéquat. Cet environnement de travail est Catkin. Catkin va nous permettre ici d'utiliser ROS mais aussi de compiler les divers programmes.

Pour pouvoir installer sur Linux, notre environnement de travail, nous utilisons les commandes ci-après.

   $ mkdir -p ~/catkin_ws_<votre_nom>/src 
   $ cd ~/catkin_ws_<votre_nom>/src 
   $ catkin_init_workspace

Ici, la ligne de commande catkin_init_workspace permet la création d’un lien CMakeLists.txt vers /opt/ros/kinetic/share/catkin/cmake/toplevel.cmake

Suite à ça, nous devons construire notre espace de travail. Pour ceci nous allons utiliser la commande catkin_make qui est un outil qui facilite le travail avec les catkin workspaces. Cette commande va également créer des repertoires "devel" et "build". Le repertoire est l’emplacement par défaut de l’espace de développement « devel space », qui est l’endroit où nos exécutables et les bibliothèques de nos packages vont être installés. Le repertoire "build", quant à lui, est l’emplacement par défaut de l’espace de construction « build space » et c’est dans ce répertoire que « cmake » et « make » sont appelés à configurer et construire nos packages.

Afin de contruire notre espace de travail, nous avons donc utilisé les commandes :

   $ mkdir -p ~/catkin_ws/src
   $ cd ~/catkin_ws_<votre_nom>/ 
   $ catkin_make

Après avoir crée les 2 répertoires, nous avons sourcé le fichier setup présent dans le "devel" puis nous avons commencé à installer les packages de ROS

   $ source devel/setup.bash

Semaine 6

Bebop autonomy est un driver ROS pour parrot bebop 1.0 et 2.0 basé sur le SDK officiel de parrot. Celui ci est compatible uniquement avec les versions suivantes de ROS : Indigo, Jade or Kinetic.

Ce driver permettra alors via des commandes ROS d’envoyer des instructions aux matériels PARROT. Pour l’utilisation de ROS sur le matériel parrot nous avons besoins des 3 packages suivants : build-esstential, python-rosdep, python-catkin-tools

ligne de commande :

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

–Création et initialisation, installation Bebop autonomy dans le workspace :

mkdir -p ~/catkin_ws/src && cd ~/catkin_ws

catkin init

git clone https://github.com/AutonomyLab/bebop_autonomy.git src/bebop_autonomy

–mise à jour de la base de donnée rosdep et installation des dépendances

$ rosdep update
$ rosdep install --from-paths src -i

–Compilation du workspace

$ catkin build

Comme on compile le driver à partir de la source il faut sourcer le Catkin Worksapce

$ source ~/catkin_ws/devel/setup.bash

roscore est une collection de noeuds et le lancer est un prérequis pour l’utilisation d’un système basé ROS. Il est nécessaire d’avoir roscore de lancé afin d’avoir une communication entre les noeuds ROS. On le lance dans le terminal avec la commande roscore.

Si on utilise la commande roslaunch, il lance automatiquement roscore s’il détecte qu’il n’est pas déjà en cours d’execution.

Roscore met alors en place :

-un ROS Master -un serveur de parametre ros -un noeud d’identification ROS.

Après cela il faut lancer le driver bebop autonomy en tant que noeud. L’exécutable du noeud se nomme bebop_driver_node et se situe dans bebop_driver. Il est recommandé d’executer le noeud dans son son espace avec sa configuration par défaut. Le driver est accompagné d’un fichier executable bebop_driver/launch/bebop_node.launch La procédure d’execution est la suivante :

$ roslaunch bebop_driver bebop_node.launch

Le roscore utilise un terminal pour la mise en place des différents paramètres. Le bebop_node.launch utilise également un terminal pour la communication entre les différents noeuds. On ouvre alors un troisième terminal où on tapera direcrement les instructions de commande.


lignes de commandes :

rostopic pub --once /bebop/land std_msgs/Empty ( atterissage )

rostopic pub --once /bebop/takeoff std_msgs/Empty ( decollage)

rostopic pub --once /bebop/reset std_msgs/Empty ( arrêt d’urgence)

Semaine 7

Nous avons pu lors de la dernière semaine envoyer des commandes de décollage et d’atterrissage. Pour des mesures de sécurité, nous n'avons pas envoyé des instructions pouvant modifier les valeurs de variables de vitesse, d'accélération, de rotation ou d'inclinaison du drone. Entre chaque instruction, il existe un temps d'attente de 3 sec avant d'envoyer une autre.

En premier lieu, nous avons tenté de récupérer la vidéo en direct affiché par le drone via une instruction utilisant la même fonction que celle d’atterrissage ou de décollage mais sans succès.

 rostopic echo /bebop/image_raw


Pour récupérer la vidéo en direct, on utilise un outil de ROS , rqt , qui permet de s'abonner à un topic et de récupérer et de traiter les données présentes. On retrouve les données du direct de la camera dans le package situé dans /bebop/image_raw

Récupération de la vidéo en direct lors du vol du drône

Après récupération de la vidéo, on tente alors de récupérer des données brutes du drone issus de ses capteurs.

Récupération des arguments de l'odométrie

Le but désormais est de pouvoir travailler avec ses données issues de capteurs afin de les utiliser dans des boucles de conditions. L'utilisation de commande sur

A la suite de cela, nous avons entamé des recherches sur l'utilisation directement de python3 pour envoyer des fichiers python au drône et de pyparrot pour le contrôle et la récupération de données de capteurs ou d'informations de vol du Bebop.

Semaine 8

Concernant cette semaine de travaille, nous nous sommes rendu compte, en faisant des recherches complémentaires sur ROS, qu'il était également probablement possible de realiser le contrôle (ou du moins, communiquer avec le drône) avec de simples programmes Python et via un module disponible sur GIT et se nommant PyParrot. Commençant un projet tout nouveau, nous avons la volonté de réaliser un état de l'art assez développé et pouvant être utile aux futurs étudiants qui devront travailler sur le Bebop. Nous avons donc décidé d'explorer Pyparrot en même temps que la récupération de données avec ROS afin de voir les différentes possibilités qui s'offrent à nous. Nous auront ensuite la possibilité de réaliser des comparaison entre toutes les possibilités et se concentrer sur la plus performante et plus complète.

Utilisation de PyParrot

Le projet entamé sur PyParrot se trouve ici

Après avoir cloné et installé le projet git, nous nous sommes mis dans le fichier .git afin de pouvoir initialiser et update les sous-modules du projet. Ceci a été fait grâce à cette commande :

   git submodule init; git submodule update

Après avoir initialisé et mis à jour le sous-module, nous sommes donc allé voir ce que contenait le projet. Nous avons donc installé un fichier PyParrot qui contient ceci :

Projet PyParrot

Nous pouvons donc constater que le projet possède un fichier "Examples" contenant un certains nombre de fichier .py permettant de faire des tests avec le drone (expliqué après). Ce projet contient aussi un dossier "Docs" qui contient de nombreux fichier .RST.

Fichiers Docs

Nous constatons donc que nous avons accès un fichier bebopcommands.rst. En allant dans ce fichier, nous remarquons que nous pouvons voir toutes les fonctions existantes que nous pouvons utiliser simplement pour le contrôle du drône.

Parmi les fonctions existantes, nous retrouvons des fonctions de bases comme le décollage, l'attérissage mais aussi la fixation d'inclinaison ou de vitesse max :

Fonctions pyparrot

Néanmoins, le problème reste le même. Que ce soit avec le SDK de Parrot, ROS ou encore Pyparrot, nous arrivons facilement à communiquer avec le drone, lui envoyer des fonctions précises mais nous n'arrivons pas à récupérer, en temps réels, les données pour pouvoir faire l'asservissement ensuite.

Dans le fichier bebopcommands.rst, nous avons remarqué qu'il existait la fonction suivante :

Fonctions contrôle sensor pyparrot

En effet, il existe donc une fonction "bebop.set_user_sensor_callback()" qui nous permettrait de recevoir à une fréquence de 10 Hz, l'état d'un capteur. Recevoir une valeur toutes les 0.1 sec étant correct, il est donc nécessaire maintenant de comprendre comment utiliser cette fonction et de savoir quelles sont les arguments que nous devons spécifier.

Après avoir constaté ceci, nous avons décidé de faire un test d'une fonction donnée, nous sommes donc allés dans le dossier "Examples" et exécute le fichier demoBebopIndoors.py Ce fichier fait donc décoller le drône à sa hauteur habituel, le fait avancer d'un mètre environs et se repose.

Nous avons donc ensuite regardé le code présent dans ce fichier. Le code est le suivant :

demoBebopIndoors.py

Nous remarquons, en analysant le code, qu'on utilise bien les fonctions que nous avons trouvé précédemment et que ce programme utilise la fonction bebop.ask_for_state_update() mais malheureusement, nous pouvons pas comprendre pour le moment l'intéret de cette fonction.

Semaine 9

Suite et fin de Pyparrot

Au cours de cette semaine de travail, nous nous sommes encore une fois divisé les tâches. Une personne du binôme à continuer de travailler sur Pyparrot pendant que l'autre continua les recherches et les tests pour récupérer les données avec ROS.

Concernant Pyparrot, nous avons continué de travailler sur les 2 fonctions étudiées la semaine précédente c'est à dire bebop.ask_for_state_update() et bebop.set_user_sensor_callback().

Ne sachant pas comment ces fonctions étaient faites et les différents arguments que nous devons y intégrer, nous sommes donc allé dans le fichier Bebop.py (fichier où sont écrites toutes les fonctions) afin d'avoir plus d'informations.

Nous avons donc remarqué ceci :

Fonction 1


Fonction 2

Nous constatons donc que les deux fonctions ne retournent aucune données et nous pouvons donc rien faire avec ces fonctions. Néanmoins, nous nous sommes tout de même attardé sur ce fichier et le fichier DroneSensorParser.py afin de voir s'il existait une autre fonction nous permettant de recuperer des données odométriques. Dans le fichier DroneSensorParser.py, nous avons découvert cette fonction :

Fonction 3

On remarque donc que nous pouvons, en théorie, récupérer les données provenant du paquet BLE. Nous avons donc testé cette fonction avec comme argument battery_states afin de récupérer le taux de charge de la batterie mais sans succès. Nous n'obtenons aucun résultat même en changeans l'argument.

Mais nous avons tout de même une explication à ce problème. Pyparrot utilisant le SDK de Parrot (utilisé lors des premières semaines), il était donc logique de rencontrer le même problème que nous avons eu quelques semaines plus tôt. Nous avons donc décidé de laisser tomber Pyparrot et de nous concentrer intégralement à ROS.

Semaine 10

Concernant le travail effectué lors de cette semaine, nous sommes donc, comme prévu, concentré sur ROS. Le but de cette semaine était de réussir non pas de récupérer des données du drone avec des commandes ROS mais de les récupérer en exécutant un programme python. L’intérêt de cette mission est donc de pouvoir exécuter un code quelconque et d'utiliser ROS comme moyen de connexion. Comme nous l'avons expliqué lors des premières semaines, ROS fonctionne d'une manière très particulière. En effet, pour envoyer les commandes, il crée un Publisher pour pouvoir envoyer des commandes sur les topics et inversement il crée un Subscriber pour récupérer des informations de ces topics. L'objectif est donc de créer un programme Python qui va créer un Subscriber pour pouvoir récupérer les données d'un topic bien précis.

Pour ce faire, nous nous rendons dans le workspace que nous avons créé au début du projet et nous créons un nouveau package pour pouvoir y mettre nos programmes

     catkin_create_pkg NOM DEPENDENCIES

Il est ici très important d'inclure toutes les dépendances adéquates. Nous avons donc mis les dépendances suivante :

  • rospy
  • roslib
  • nav_msgs
  • std_msgs
  • sensor_msgs

Nous pouvons donc maintenant réaliser des programmes python qui seront reconnus par ROS.

Suite à ça nous avons chercher le nom du topic sur lequel nous pouvons récupérer les informations. Pour cela nous avons lancé roslaunch et dans un second terminal nous avons lancé la commande :

    rostopic list 


Nous avons reçu ceci :


ROS topic list

Comme on peut voir ici, nous avons bien un topic transmettant les données odométriques (/bebop/odom). Nous allons donc essayer de souscrire à ce topic. Avant ça nous devons savoir quel type de données transitent dans ce topic. Pour ceci nous faisons la commande :

    rostopic info /bebop/odom 

qui nous retourne ceci :


ROS topic infos

Nous constatons ici que nous le type de message qui est envoyé et Odometry. Nous pouvons donc éxecuter la commande :

    rosmsg show Odometry


ROS msg Odometry

Grâce à cette commande nous avons pu constater que nos données (x,y,z,w) sont du type float64.

Après ceci nous avons donc pu commencer à écrire notre code python pour récupérer les données. Afin de le réaliser, nous nous sommes inspiré de ce code :


Exemple de code


Ce code provient de cette page

Notre code est donc le suivant :

Code odometrie

En executant ce programme, nous recuperons ceci :

Données odometrie

Les valeurs du topic Odometry qui sont récupérées appartiennent à l'intervalle [-1;1]. Si l'on caricature, le drône est le point d'origine de cet axe. Il n'est pas possible alors de donner des instructions de déplacement au drone d'un point à un autre avec ces informations.

Semaine 11

La semaine dernière nous avons récupéré des infos sur l'odometry que nous pensons être exploitable pour l'asservissement en position.

Nous sommes arrivés à la conclusion que les infos récupérés ne pouvaient pas aider à déplacer le drone d'un point à un autre. Durant ces recherches et l'exploitation des données, nous avons soumis le drône à des perturbations légères. Il se trouve que le drône se stabilise et s'asservit automatiquement à la position à laquelle il décolle.

Il possède alors instinctivement un programme pour s'asservir en position. Nous n'avons pas réussi à désactiver ou contourner ce programme d'asservissement afin de pouvoir soumettre des perturbations.

Nous avons donc décidé de passer par les coordonnées GPS afin de localiser le drône avec la longitude et la latitude.

Suite aux données récupérées, nous avons localisé ces coordonnées sur le google maps afin de s'assurer de la véracité de l'information. Il s'avère que celle ci est correcte.

A compter de cet instant, nous savons qu'il est possible de récupérer les coordonnées GPS. Nous allons maintenant tenter de commander les moteurs du drône.

Il est possible de commander le drone en jouant sur les variables linéaires x, y, z mais aussi la variable angulaire z.

-linear.x: Deplacer en arrière

+linear.x: Deplacer en avant

-linear.y: Deplacer à droite

+linear.y: Deplacer à gauche

-linear.z: Deplacer vers le bas

+linear.z: Deplacer le haut

-angular.z: rotation vers droite

+angular.z: rotation vers gauche

Pour piloter le drone après le décollage, on publie un message de type géométry_msgs::Twist au topic cmd_vel.

Semaine 12

Cette semaine est consacrée principalement à la rédaction du rapport de mi projet et la présentation de la soutenance.

Semaine 13

Après les vacances, nous avons rencontré monsieur Nakrachi qui nous a dit de contacter Monsieur Dherbomez qui pourrait nous donner quelques informations sur les prochaines étapes du projet. Monsieur Dherbomez est un chercheur en automatique qui a deja travailler sur le drone. En effet, il a eu comme idée de projet, de faire un essaim de drone et de les contrôler avec un unique ordinateur. Pour pouvoir presenter son projet, il a réaliser quelques cherches et réalisé quelques manipulations avec le drone. Ses recherches sont mises sur ce lien : [1]

Monsieur Nakrachi nous a donc mis en contact avec afin de discuter de l'asservissement en vitesse. Durant cette réunion, monsieur Dherbomez nous a tout d'abord expliqué son travail. Il a réaliser une interface graphique permettant d'envoyer des instruction de mouvements avec de simples boutons. Suite à ça, il a essayé de contrôler 2 drones mais il n'a pas réussi pour le moment.

Nous avons ensuite discuté de l'asservissement en vitesse. Concernant cela, il nous a proposé de réaliser une interface graphique nous permettant de voir notre position GPS en temps réel et de pouvoir, dans un autre champs, imposer la position GPS de destination (Latitude, Longitude, Altitude). Une fois que l'utilisateur aura mis la position GPS finale, l'algorithme calculera donc la distance entre le point A et le point B. L'asservissement en vitesse se ferrai donc dans ce calcul de distance. En effet, une fois la distance calculée, nous allons ordonner au drone d'avancer d'un point. Nous changerons donc de position GPS et devrons recalculer une nouvelle fois la distance. Nous pourrons donc jouer sur la vitesse du drone en fonction de la distance restante à parcourir.

L'interface graphique n'étant pas une priorité dans le projet pour le moment, nous nous sommes donc interessé sur la récupération des données GPS mais sans utiliser la ligne de commande "echo", comme utilisé précédemment. Pour récupérer ces données GPS, nous avons utilisé la même méthode que précédemment c'est à dire, dans un programme python, de souscrire au topic s'occupant du GPS (/bebop/fix) et de récupérer les données en temps réel de latitude, longitude et altitude.

Une fois les données GPS récupérés, nous avons programmé le calcul de distance entre 2 points GPS. Pour ceci, nous avons utilisé la formule suivante :

La distance (A, B) = R * arccos (sin (lata) sin * (LATB) + cos (lata) cos * (LATB) cos * (Lona-lonB))

où lata est latitude du point A, LATB celle du point B, Lona la longitude du point A, lonB celle du point B et R le rayon de la terre en km = 6372.

Cette formule nous retourne une distance en kilomètre que nous avons donc pu convertir en mètre pour avoir des résultats plus agréable à lire.

PHOTO DONNEE EN M

Semaine 14

Lors de cette quatorzième semaine, nous avons rencontré monsieur Nakrachi afin de lui faire un compte-rendu de notre réunion avec monsieur Dherbomez et lui montrer ce que nous avions fait.

Ce qui est sorti de cette réunion est que nous devons maintenant réussir à identifier le système c'est à dire pouvoir représenter le système par une fonction de transfert. Pour ce faire nous allons récupérer des tableaux de données de position. Nous allons donc jouer sur le topic /bebop/cmd_vel afin d'imposer une vitesse comprise en -1 et 1 sur l'axe x, y et z et pour chacune des commandes nous allons récupérer l'évolution de la position du drone grâce aux données GPS. Ceci nous permettra ensuite de trouver un lien entre l'évolution de la position est la commande.

Nous avons donc déduit le schéma du système suivant :

Schéma possible du système

Comme on peut le voir, nous imposons donc une consigne comprise entre - et et nous avons les coordonnées GPS en sortie. Nous avons une première fonction de transfert qui nous donne la vitesse en m/s en fonction de la consigne qui est à déterminer. Une fois la vitesse sur les différents axes obtenues, nous savons que le lien qui la lie avec a position du drone est un intégrateur, nous pourrons établir le lien entre ces positions et les coordonnées GPS

Nous pourrons ensuite identifier le système, représenter au mieux le drone en mouvement et donc réaliser une commande de ce système.

Nous avons donc commencé à récupérer les données de position du drone. Nous avons décidé d'imposer une commande de déplacement et grâce à la commande "rostopic echo" de transférer les données directement sur un excel. Nous avons donc décidé de récupérer les données de latitude, longitude et altitude pour chaque consigne et de les comparer. Les résultats sont les suivants :

Latitude avec commande en x Latitude avec commande en y


Longitude avec commande en x Longitude avec commande en y


Altitude avec commande en x Altitude avec commande en y

Le fait d'avoir récupéré ses mesures nous a permis de remarquer que le lien entre la vitesse et le déplacement est bien un intégrateur car nous avons une zone transitoire qui est une droite.

Semaine 15

Durant cette semaine, nous avons tout d'abord déterminé la fonction de transfert qui lie la consigne à la vitesse sur les différents axes. Pour ceci, nous avons récupéré les données de vitesses en souscrivant au topic /bebop/states/ardrone3/PilotingState/SpeedChanged/SpeedX

Une fois les vitesses récupérées, nous avons tracés les courbes suivantes :

Réponse impulsionnelle avec commande de 0.15 Réponse impulsionnelle avec commande de 0.2


Nous avons donc pu déterminé la fonction de transfert de la manière suivante :

  • K = gain statique = gain au régime permanent/impulsion d'entrée
  • tau 𝜏 = Temps de reponse = 0.63* temps que met le système a atteindre le régime permanent

En faisant ces étapes sur les différentes courbes, nous avons pu conclure que la fonction de transfert est :\frac{K}{1+tau * p} = \frac{9}{1+3.1p}

Nous voulions ensuite vérifier que notre fonction de transfert était correct. Nous sommes donc allés sur Matlab Simulink afin d'injecter un échelon de 0.2 sur notre fonction de transfert et nous avons obtenu le résultat suivant :

Réponse impulsionnelle avec commande de 0.2 matlab

Comme on peut constater, notre fonction de transfert est donc correct.

Après cela, nous avons commencé à publier sur le drone des commandes de mouvements sans passer par le terminal, chose que nous faisions pas avant, dans le but ensuite de faire aller le drone à une position decidé par l'utilisateur.

Pour pouvoir faire avancer le drone, nous devons donc publier sur le topic /bebop/cmd_vel. L'information que nous allons envoyer est de type Twist. La particularité de cette publication est que nous devons imposer une valeur à linear.x, linear.y, linear.z, angular.x, angular.y et angular.z. Nous avons donc fait comme ceci :

publisher cmd_vel

Comme pour la ligne de commande, nous devons mettre une valeur comprise entre 0 et 1 pour le faire avancer sur un axe précis et une valeur entre -1 et 0 pour le faire reculer.

Une fois ceci fait, nous avons pu commencer à créer le déplacement entre 2 points GPS de manière automatique.

Afin de créer un déplacement entre point GPS, nous devions réaliser une comparaison entre la position finale désirée et la position du drone en temps réel. Le traitement de cette comparaison nous permet de réaliser l'asservissement suivant :

systeme matlab final

Comme on peut constater dans cet asservissement, nous récupérons les coordonnées GPS (latitude, longitude en degrés) que nous convertissons grâce à la formule suivante :

formule

Cette conversion nous permet de transposer ces coordonnées GPS sur un axe X, Y et Z où l'origine est le centre de la tête. Cette conversion nous permet également de mieux jouer sur les axe du drone pour contrôler les déplacements. Une fois ceci fait, nous faisons donc la différence entre les 2 points convertir sur le même repère afin de savoir exactement quelle distance il nous reste à parcourir sur x sur y et sur z. Une fois ces données collectées, nous comparons les valeurs absolues de x et y afin de determiner sur quel axe nous devons parcourir la plus grande distance. L'étape d'après est donc de faire le ratio entre le plus grand et le plus petit afin d'influer sur la vitesse de l'axe sur lequel nous devons parcourir une plus petite distance. Ceci nous permet donc, dans un premier temps d'imposer la consigne max du système afin de ne pas aller trop vite et d'adapter l'autre consigne pour aller dans la bonne direction. Afin de permettre au drone d'aller dans n'importe quelle direction, nous avons adapté cette solution pour les 8 cas possibles. A la sortie de notre programme, nous avons les différentes commandes de consigne sur les différents axes du drone que nous envoyer dans notre fonction de transfert afin de la transformer en vitesse en m/s. Nous faisons donc bien un bouclage car nous faisons ceci constamment afin de régler le drone en cas de perturbation.

L'un des détails que nous avons dû gérer est que notre drone possède son propre repère et donc une évolution du drone sur son axe x ne correspond pas à une évolution sur le x de la terre. Nous avons donc fait une série d'essai afin de déterminer les différentes influences des mouvements du drone sur notre repère. Pour pouvoir donc avoir un programme valable dans toutes les circonstances nous avons donc choisi d'avoir l'axe y orienté vers le Nord. Nous devons donc avant de lancer le programme, orienter le drone vers le nord pour ne pas avoir de déplacements incohérents.

Nous avons donc pu commencer les déplacements du drone. Avant toute chose, nous avons remarqué en observant le topic /bebop/fix que nous recevions une donnée GPS toutes les secondes. Etant donné que nous ne pouvons pas améliorer cette fréquence de réception, nous avons donc du adapté notre programme afin d'être le plus performant possible. Pour cela, nous avons décidé de fixer la vitesse max du drone. En fixant cette vitesse max, nous nous assurons que le drone n'aille pas trop vite pour les tests et que nous puissions recevoir une donnée suffisamment souvent sans que le drone parcourt une grande distance. Dans un premier temps, nous avons donc décidé de fixer la consigne de vitesse à 0.2.

Pour ensuite réaliser le déplacement, nous avons réaliser une pondération des axes x et y c'est à dire que dans un premier temps, nous faisons la différence entre le point GPS de destination et la position du drone. Ceci nous donne donc la distance restante à effectuer sur les différents axes. En faisant la valeur absolue de ces valeurs, nous savons donc sur quel axe nous devons réaliser la plus grande distance. C'est donc sur cet axe que nous allons appliquer notre consigne max de 0.2. Pour définir la consigne de vitesse de l'autre axe, nous faisons donc le ration entre le plus grand et le plus petit, nous obtenons donc ensuite une consigne plus petite que 0.1. Afin de créer le bouclage, nous récupérons constamment la donnée GPS du drone et nous faisons donc ces étapes en boucle.

Semaine 16

Il était possible de rentrer manuellement le point de destination. Après validation de cette tâche et consultation avec le tuteur Mr Nakrachi, nous en avons conclus de mettre le drone en attente sur place pour lui insérer une nouvelle destination GPS. Suite à la validation de ces deux tâches nous avons opté pour le partage de la position GPS du premier point par partage Bluetooth à partir du mobile. Pour le second point de destination, on demande à l'utilisateur de rentrer ses valeurs manuellement.

Le PC que nous utilisons ne possède pas de carte Bluetooth. Nous utilisons alors une clef Bluetooth afin de pouvoir communiquer entre le portable et l'ordinateur. Le fichier envoyé par Bluetooth au PC est un fichier HTML. Dans ce fichier HTML, nous retrouvons la longitude et la latitude que nous extrayions à partir de la fonction suivante qui nous retournera les valeurs et que nous insérons dans des variables. On envoi la position GPS par le mobile avec l'application AndLocation. On doit réceptionner le fichier avant d’exécuter le programme. On effectue une recherche de caractère dans le fichier et on ne garde que les caractères à succession de chiffre et séparé ou non par une virgule. La suite de caractère est enregistré dans une variable.

extraction GPS1
extraction GPS2








Nous avons remarqué qu'à certains moments le drone venait à atterrir à des endroits pas sécurisés et où il pouvait subir des dégâts matériels à la fin de son parcours. Nous demandons alors à l'utilisateur l'autorisation d’atterrir, dans le cas négatif, il est possible alors pour l'utilisateur de contrôler le drone manuellement avec les touches du clavier pour avancer, reculer, aller à gaucher ou à droite. Avec une fonction getch(), on récupère la touche appuyée par l'utilisateur. La touche s détermine l'arrêt de la commande manuelle, elle lui donnera l'autorisation d’atterrir à ce moment

Commande manuelle
Get char


On effectue une lecture de variable pour la vitesse de déplacement. Cette variable est utilisé ensuite dans les fonctions de déplacement. On joue sur les déplacements en x (avancer reculer) et y ( droite gauche) du drone. En théorie, on effectue asservissement de la vitesse par une fonction affine décroissante, la vitesse en fonction de la distance. En pratique, on se retrouve avec des paliers dû à la limite des 1 secondes qui est du à la fréquence à laquelle on reçoit nos données GPS. On mesure la distance initiale entre les 2 points. Et on effectue ensuite une différence entre cette distance et la distance restante pour avoir la distance parcouru. On se retrouve avec une fonction de la forme F(x) = b - ax . Nous faisons donc évoluer la vitesse en fonction de la distance qui reste à parcourir

Asservissement vitesse


Nous remarquons en faisant les différents tests que la vitesse du drone est bien asservie mais étant donnée que nous fixons la vitesse max du drone à 0.2, les ralentissements du drone ne sont pas très visible à l'oeil nu. Nous avons donc fais un rostopic echo des différentes vitesses pour en être sur.

Conclusion

Pour conclure sur ce projet de fin d'études, nous pouvons dire que nous sommes très satisfait du travail que nous avons réalisé car cela nous a permis de nous familiarisé avec différents outils. En effet, lors de ce projet, nous avons dû, dans un premier temps, nous adapter aux outils comme ROS, PyParrot ou SDK qui nous "été imposé". Pour la suite du projet, nous avons décidé d'utiliser principalement ROS et python. Ceci nous a donc permis de monter en compétence dans ses 2 outils qui sont encore omniprésents dans la recherche et l'industrie.

De plus, nous avons eu la chance de pouvoir travailler sur un projet concret avec du matériel de très bonne qualité. Les drones étant en très grosse évolution, nous étions ravis de pouvoir faire un projet avec l'un d'entre eux.

Ce projet nous à également permis d'améliorer nos compétences de gestion de projet, de communication, d'auto-critique entre nous, avec l'autre binome et nos tuteurs de projet.

La finalité du projet étant fonctionnelle, nous en sommes d'autant plus satisfait. En effet, nous sommes parvenus à réaliser 2 bouclages (pour le déplacement automatique et pour l'asservissement en vitesse) et ajouter des fonctions pour améliorer le projet global comme la sécurité ou encore la communication Bluetooth.

Documents Rendus

Rapport et diapo de la présentation intermédiaire

Fichier:Rapport P36 Viscogliosi Ayoub.pdf

Fichier:Presentation P36 Viscogliosi Ayoub.pdf

Fichier:Rapport final P36 Viscogliosi Ayoub.pdf

Fichier:Programme python.zip