Raspcopter - Première vidéo
par Florent Revest

Maintenant que le Raspcopter contrôle ses moteurs, connait sa position angulaire et sait relier les deux, il y a enfin de quoi filmer quelque chose d'intéressant !

Raspcopter - Motors control

Commentaires

Raspcopter - Contrôle des moteurs
par Florent Revest

Le dernier article a doté le système de vol du Raspcopter d'un algorithme puissant d'autorégulation angulaire. Pourtant, un détail a été passé sous silence et non des moindres: le "Feedback" représenté en bas du schéma du contrôleur PID assurant la fonction de boucle fermée. Ce retour sur erreur est bien sûr la gestion des vitesses des moteurs, l'objet de l'article d'aujourd'hui.

Ce que l'on veut

Comme tout objet volant, notre petit drone doit bénéficier d'une force de poussée verticale suffisamment grande pour le libérer de la gravité. Cette force c'est notre vieil ami Newton qui nous la donne dans sa troisième loi des actions réciproques. Les hélices du quadcopter poussent l'air vers le bas et par réaction, le drone est poussé vers le haut c'est aussi simple que ça.

Mais le drone introduit une contrainte : ces hélices doivent être entraînées à une vitesse assez conséquente et par des moteurs assez légers. Un type de moteur répond à cette problématique, les moteurs "sans balais" ou plus couramment appelés brushless.

Leur principe de fonctionnement est assez simple, ci dessus vous pouvez observer trois bobines (légendées coils) alimentées électriquement les unes après les autres pour créer un champ magnétique qui mettra en mouvement l'aiment du centre, portant l'axe tenant l'hélice. Les moteurs du Raspcopter utilisent 12 bobines mais le principe reste fondé sur l'alternance de trois d'entre elles, c'est d'ailleurs pour cette raison qu'il suffit d'inverser deux fils au hasard pour modifier le sens de rotation du moteur.

Ce que l'on a

On souhaite contrôler ces moteurs depuis le Raspberry Pi avec le minimum de latence possible. Le Raspberry Pi dispose de plusieurs interfaces, principalement les GPIOs et l'USB. La première idée semblant la plus naturelle serait de contrôler les moteurs depuis les pins GPIOs mais c'est en fait impossible car la fréquence de changement de bobines ne serait jamais suffisante et l'énergie délivrée serait elle aussi bien trop faible.

Comment passer de l'un à l'autre ?

Pour cette raison, on fait toujours appel à des "ESCs" (electronic speed controlers) placés en amont de chaque moteur, ces circuits électroniques sont alimentés par deux câbles provenant de la batterie LiPo et reçoivent des données PWM (pulse width modulation, c'est à dire codées sur des longueurs de pulsations électriques) depuis trois fils, exactement de la même manière qu'un servomoteur. En sortie de ces contrôleurs, trois câbles sont soudés au moteur brushless et alternent l'alimentation des bobines comme vu précédement. L'ESC choisi est un modèle 20A UBEC de HobbyKing.

On simplifie déjà le problème, car envoyer un signal PWM depuis les GPIOs du Raspberry Pi n'est plus chose impossible, mais en générer quatre est déjà chose plus ardue. Certains projets utilisent directement les GPIOs mais n'y faisant pas totalement confiance j'ai préféré acheter un circuit externe de gestion de servomoteurs, le Pololu Micro Maestro qui déchargera la framboise d'une lourde tâche. Le choix du maestro s'est fait grace à sa connectique USB, mais Adafruit propose d'excellent circuits i2c faisant la même chose.

Le code gérant le Pololu Maestro est situé dans la classe Motors du code du système de vol hébergé sur GitHub et utilise la libusb pour gérer la vitesse de chaque moteur comme prévu par les spécifications de Pololu.

Sources

Commentaires

Raspcopter - Régulateur PID (Proportionnel Intégral Dérivé)
par Florent Revest

Au cours de l'article précédent nous avons entamé l'étude du système de vol d'un quadcopter. La première étape consistait à récupérer l'attitude c'est-à-dire la position angulaire du drone dans l'air. Il s'agit aujourd'hui d'exploiter ces mesures d'angles dans la perspective de stabiliser le quadcopter autour de valeurs spécifiées par la station de contrôle au sol.

Ce que l'on veut

S'il est vrai que le drone doit savoir rester parallèle au sol lorsqu'aucune commande du sol n'est reçue, il se doit également de savoir pivoter sur ses axes pour pouvoir se déplacer. Ces rotations sont spécifiées par la "station de contrôle au sol", un logiciel tournant sur un ordinateur portable et traitant les données d'un joystick. La position du joystick traduit un angle voulu qui est ensuite transportée par wifi et interprété par le Raspberry Pi.

On souhaiterait avoir un vol fluide malgré les changements brutaux de position du joystick, tout en gardant un contrôle sur la réponse des moteurs plus ou moins aggressive.

Ce que l'on a

Lorsque le quadcopter confronte les trois angles d'euler mesurés par l'accéléromètre comme vu dans l'article précédent et les angles voulus envoyés par la station au sol la différence entre ces deux données produit une erreur soudaine. Si les vitesses des moteurs sont changées en même temps que l'apparition de l'erreur, comme selon le signal carré du graphique ci-dessous. L'impulsion puissante et soudaine risque: au mieux de dépasser l'angle souhaité et de revenir en arrière indéfiniment créant une instabilité, au pire de renverser immédiatement le quadcopter. On comprend donc bien qu'il est nécessaire d'avoir un algorithme "lissant" cette transition.

Comment passer de l'un à l'autre ?

Ce problème est omniprésent en ingénieurie et nécessite l'utilisation d'un "régulateur", nous allons évoquer et utiliser le régulateur PID (pour Proportionnel, Intégral, Dérivé).

Dans le cadre de notre quadcopter, les mesures se faisant sur trois angles il est nécessaire d'utiliser trois régulateurs PID différents. Cet algorithme prend pour entrée la différence entre l'angle voulu et l'angle mesuré, par exemple lorsque la télécommande au sol n'envoie rien cette erreur correspond au défaut de parallélisme au sol. Des opérations mathématiques sont appliquées à ces trois erreurs et déterminent les vitesses à envoyer aux quatre moteurs.

Le régulateur PID est un algorithme qui prend en entrée une erreur. Il fait la somme d'une multiplication de cette erreur, d'une intégrale de cette erreur et d'une dérivée de cette erreur, puis renvoie une nouvelle valeur. C'est tout.

On perçoit vite les avantages de cet algorithme: tout d'abord il est très simple à comprendre et à implémenter. Mais il faut également savoir qu'il est extrêmement fiable, ce régulateur est le plus utilisé au monde et on le retrouve partout... jusque dans la chasse de vos toilettes !

Ce système est dit "en boucle fermée" car il s'auto régule : lorsque l'erreur d'angle est grande les moteurs concernés accélèrent et l'erreur se réduit. La sortie de l'algorithme influe donc sur son entrée.

Proportionnel

Le terme proportionnel s'obtient très simplement par la multiplication de l'erreur par une constante nommée "gain proportionnel". Plus le gain est grand plus la vitesse de réponse est rapide et risque d'être instable. Plus le gain est faible plus la vitesse de réponse est "molle" et risque d'être inefficace. Il s'agit de trouver une bonne valeur intermédiaire entre ces deux extrêmes.

Ici on voit qu'un gain proportionnel (Kp) trop grand résulte en un dépassement significatif de l'angle recherché (le signal de référence bleu).

Intégral

Contrairement à un simple système de contrôle proportionnel, le régulateur PID tient compte de l'historique des erreurs angulaires. Pour cela le terme intégral est introduit, il représente la somme de toutes les erreurs accumulées dans le temps multiplié par une constante "gain intégral" Ki.

Le gain intégral influe directement sur la hauteur (et par conséquent le nombre) de dépassement de la valeur cible. Un trop faible gain est problématique dans certaines situations comme lorsque le vent est trop fort. En revanche un gain trop grand provoque une oscillation autour de l'angle voulu.

Dérivé

Le terme dérivé est parfois nommé "l'accélérateur" puisqu'il permet de compresser dans le temps la réponse. Il s'obtient par la soustraction de l'erreur actuelle et de l'erreur précédente multipliée par le gain dérivé. Ce terme est cependant à prendre avec des pincettes, car il est très sensible au bruit de données.

Une fois n'est pas coutume, un graphique nous permet de mieux comprendre l'impact du gain.

Et après ?

Une fois le code du régulateur PID implémenté (la très simple classe PID disponible sur le code github) il s'agit de déterminer les trois gains de chaque régulateur. Comme chaque quadcopter a des caractéristiques particulières il n'existe pas de constantes PID universelles, cependant la détermination de ces valeurs ne relève pas non plus du hasard.

Tout d'abord, il faut noter qu'une méthode de détermination rapide, nommée "méthode de Ziegler et Nichols" existe et permet d'obtenir des Ki et Kd corrects à partir de la seule valeur de Kp. Les gains peuvent ensuite être ajustés en fonction des paramètres vus ci-dessus.

Par ailleurs, un quadcopter (contrairement à un tricopter ou hexacopter) est à peu de choses près symétrique, les constantes des PIDs pitch et roll sont donc similaires ce qui fait gagner du temps.

Pour finir, il est important de noter que pour des raisons de sécurité évidentes l'expérimentation de ces PIDs ne se fait jamais en conditions réelles en exterieur. En accrochant solidement le quadcopter à une barre parallèle à un axe de rotation on est en mesure de bloquer la rotation des autres angles et de travailler sur un seul PID à la fois.

Sources

Commentaires

Raspcopter - Réception de l'attitude
par Florent Revest

J'inaugure aujourd'hui la lignée d'articles techniques sur mon projet de Raspcopter en commençant comme promis par : l'attitude.

Ce que l'on veut

Si cela peut sembler naïf c'est pourtant vrai: la première mission d'un quadcopter est de ne pas tomber... Même lorsque les quatre moteurs tournent à vitesse égale et constante, le drone fini par vriller et tomber seul. Cette rotation naturelle est causée par l'imperfection du drone (centre de gravité déplacé par exemple) mais aussi et surtout par les diverses contraintes physiques du milieu (typiquement : le vent).

Il est donc indispensable de créer un système de vol dépendant de l'attitude du quadcopter, c'est-à-dire de sa position angulaire dans l'espace. Une citation Wikipedia vaut mieux qu'un long discours "L'attitude ou l'orientation, dans le domaine de l'astronautique, est la direction des axes d'un engin spatial par rapport à un trièdre de référence. Pendant le déplacement du véhicule spatial, il s'agit de contrôler les mouvements d'avant en arrière (tangage), de gauche à droite (roulis) et autour d'un axe vertical (lacet)."

On a donc besoin de trois angles d'Euler que l'on nomme en anglais : yaw, pitch et roll.

Ce que l'on a

De nombreux capteurs permettent d'obtenir l'attitude du système :

  • Les accéléromètres, mesurant l'accélération linéaire sur trois axes.
  • Les gyroscopes, fournissant une position angulaire relative sur les mêmes axes.
  • Les magnétomètres, mesurant le champ magnétique et permettant de déduire la position du nord à la manière d'une boussole.
  • Les récepteurs GPS, dont les satellites fournissent des coordonnées absolues en latitude et longitude et permettent d'obtenir une rotation.

Tous ont leurs avantages et inconvénients. Ils ne sont donc jamais utilisés seuls, toujours combinés. De par des contraintes d'argent et de temps, mon projet de Raspcopter ne fera usage dans un premier temps que des deux premiers capteurs. Le MPU6050 de Invensense les réunit en une seule puce, on parle alors d'IMU (Unité de mesure inertielle) à six degrés de liberté. Le MPU6050 est par ailleurs très peu cher et souvent utilisé par des quadcopters.

Cette puce se connecte via la norme i2c par quatre fils (SDA, SCL, Masse et 3.3v) aux pins GPIOs dédiés du Raspberry Pi. Il est donc premièrement nécessaire de lever les drivers i2c de la blacklist Raspbian de modprobe.

L'utilisation de ce capteur est relativement bien documentée et rendue aisée par le travail de Jeff Rowberg sur I2CDevLib. Il est donc facile de récupérer des valeurs d'accélération et de rotation.

Comment passer de l'un à l'autre ?

Le coeur du problème se trouve dans le passage des valeurs brutes du MPU6050 à des angles habituels. En effet les valeurs brutes ont trois problèmes :

  • premièrement, elles comportent du bruit c'est-à-dire que le signal n'est pas stable
  • deuxièmement, elles n'ont pas d'unité, ce sont des valeurs qui ne correspondent à rien de concret
  • pour finir, ces données d'accélération et de rotation ne sont pas combinées en trois angles comme nous le souhaitons.

Un filtre de Kalman est souvent utilisé pour stabiliser les valeurs, mais son implémentation est extrêmement complexe et couteuse en temps processeur.

Une solution bien plus légère et rapide serait de créer un filtre complémentaire, selon la formule:

Appliqué sur des angles roll (phi) et pitch (rhô) calculés par

Cette formule accorde beaucoup plus de poids aux valeurs du gyroscope qu'à celles de l'accéléromètre car elle tiend en compte le fait que les mesures du gyroscope sont stables sur le court terme mais ont un "drift" (un décalage qui se produit avec le temps) sur le long terme (c'est-à-dire qu'en retournant deux fois d'affilé un gyroscope il ne reviendra pas à la même valeur) et que les valeurs de l'accéléromètre qui mesurent énormément de forces en plus de la gravité ont beaucoup de bruit mais sont bien plus stables sur le long terme. Cette formule n'est pas totalement efficace non plus.

Le choix d'un filtre IMU de quadcopter doit souvent se faire entre ces deux dernières techniques. Mais la bonne nouvelle c'est que le MPU6050 possède une puce "DMP" (Digital Motion Processing) qui permet de filtrer ces valeurs hors du Raspberry Pi, donc en temps réel et de manière bien plus efficace que par un algorithme implémenté à la main. La mauvaise nouvelle c'est qu'Invensense protège jalousement le fonctionnement de cette puce au nom du secret industriel et refuse de documenter son fonctionnement.

C'est ici qu'intervient Noah Zerkin, un entrepreneur en réalité augmenté qui a obtenu des dumps mémoires par retroingénierie de la puce en fonctionnement DMP à partir de démos du constructeur. C'est sur son excellent travail, intégré à I2CDevLib que se base mon code.

Mon implémentation est située dans la classe Accelerometer du code du serveur L'initialisation du MPU6050 se fait dans le constructeur et les angles d'Euler s'obtiennent par la méthode getYawPitchRoll().

Problème des angles d'Euler

Un dernier problème reste présent : si les angles d'Euler décrivent toutes les possibilités de positions angulaires, ils ne sont pas à l'abri pour autant d'un "blocage de cardan" ou Gimbal Lock. Ce problème arrive lorsque deux axes du gyroscope pointent dans la même direction, le système perd alors un degré de liberté et poursuit un mouvement imprédictible. Ce problème qui semble anodin aurait pu faire tourner court la mission Apollo 11, mais on n'en retiendra qu'une citation de Michael Collins "Que diriez-vous de m'envoyer un quatrième cardan pour Noël ?"

La solution, lorsque l'on ne croit pas au père Noël, serait d'utiliser des Quaternions, des nombres hypercomplexes fait d'une combinaison linéaire de quatre paramètres, dont trois définissent un axe et le dernier définit une rotation autour de cet axe. La manipulation de cet ensemble dépassant mes compétences de terminal S je me contenterai de les convertir en angles d'Euler.

Et après ?

La première phase du système de contrôle, l'acquisition de données, est donc achevée avec succès. Les angles d'Euler : yaw pitch et roll doivent maintenant passer par un contrôleur PID afin de sortir des vitesses de moteurs. Ce sera l'objet du prochain article.

Sources

Commentaires

Raspcopter - Construction du cadre
par Florent Revest

Après deux mois d'attente insoutenable, le collis des pièces du quadcopter commandées chez HobbyKing a fini par être livré. J'ai commencé à monter le cadre X525 v3 avec les moteurs Brushless FC 28-22 Outrunner 1200kv. Je flasherai peut être les ESC 20A UBEC HobbyKing avec le célèbre firmware SimonK avant de les souder aux moteurs (cependant la procédure s'annonce délicate donc incertaine). Toute cette phase de montage qui est commune à tous les quadcopters et déjà amplement documentée, je ne la détaillerai donc pas sur ce blog.

En revanche, mon travail de programmation et de documentation concernera la conception du système de contrôle de vol intégré au Raspberry Pi. À commencer par la réception de "l'attitude" (la rotation dans l'espcace) du quadcopter en angles d'euler filtrés puis le contrôleur PID et la régulation des vitesses via le Pololu Maestro.

En attendant, voici la première photo du montage :

La plaque de plastique à droite sera directement fixée au X525 et servira de support au Raspberry Pi, au MPU6050 (l'acceleromètre) et au Pololu Maestro (interface avec les ESCs).

Pour toutes informations supplémentaires n'hésitez pas à me contacter ou à commenter.

P.S: La liste complète du matériel est entretenue au côté du code sur github: https://github.com/FlorentRevest/Raspcopter

Commentaires

Création du blog
par Florent Revest

Ça y'est, cette fois je me suis décidé, j'ai ajouté un blog à ce site jekyll !

Sans grande prétention c'est vrai, je compte y publier de petits tutoriels et conseils concernant l'informatique et la photographie.

À venir très bientôt: des indications sur la construction de mon Raspcopter (un drone contrôlé par un Raspberry-Pi).

Commentaires