Hardware:
Software:
Développement:
Gallerie:
|
BOB4 - Drone hélicoptere autonome d'intérieur
Algorithmes - 2/2 :
2) Asservissement:
2.1) Contrôleurs PID (Proportionnel Intégral Derivé)
Pour un tel hélicoptère, il y a 4 commandes à construire, vu qu’il y a 4 voies sur l’émetteur radio. Ce sont ces 4 voies qu’il faut contrôler par asservissement. J’utilise 4 PID différents, indépendants les uns des autres. Le PID (Proportionnel Intégral Dérivé) est l'un des contrôleurs les plus utilisés en automatique.
|
|
Pour les avancements longitudinal et latéral, il faut encore un peu de trigonométrie pour recalculer l’erreur dans le repère du drone (erreur longitudinale et latérale), à partir de l’erreur dans le repère absolu (erreur en X et erreur en Y). Tous ces changements de repère peuvent paraître compliqués, et nécessitent pas mal de ressource (temps de calcul). Mais c’est un choix délibéré : je peux directement travailler dans le repère absolu, envoyer des consignes de position en 3D dans le repère absolu. Tout le reste suit « naturellement ». L’algorithme s’adapte automatiquement à l’orientation du drone, au capteur utilisé. C’est très appréciable, car ça fait un algorithme très souple, qui s’adapte facilement à un nouveau scénario.
Pour le lacet, le contrôleur moteur (du commerce) est déjà équipé d’un gyroscope qui réalise une correction en fonction de l’erreur sur la vitesse de lacet. Donc je dois spécifiquement supprimer le terme dérivé de l’asservissement pour le lacet, qui serait redondant. L’asservissement pour le lacet est donc un simple PI (Proportionnel Intégral). Ce contrôleur moteur réalise également le « mixage » entre les 2 moteurs, ce qui explique que j’envoie directement des commandes de gaz et de lacet, et non moteur haut et moteur bas.
Ci dessous un exemple de log d'asservissement en altitude:
|
|
2.2) Lissage des consignes :
Pour obtenir un déplacement propre, et permettre à l’asservissement de suivre, on ne peut pas changer la consigne (entrée du contrôleur PID) instantanément de plusieurs mètres par exemple. Il faut décomposer la position 3D et l'orientation pour aller progressivement d’un point A (la consigne actuelle) à un point B (la cible). La décomposition est simplement un déplacement à vitesse constante.
Cette décomposition est réalisée en « temps réel ». C'est-à-dire que si la cible change en cours de route (devient le point C), la décomposition repart naturellement de la consigne actuelle (entre A et B) vers le point C.
J’avais initialement programmé un profil de vitesse « trapézoidal », mais cela n’apporte rien, car le suivi de la vitesse par le PID est beaucoup trop mauvais.
|
3) Haut niveau - superviseur:
Cette partie appelée « superviseur » consiste à mettre à jour les consignes en entrée du contrôleur PID. Vu que les consignes sont directement exprimées en terme de position 3D et d’orientation (lacet seulement), la mise à jour est très simple et est complètement indépendante des capteurs utilisés pour estimer la position. Ainsi, lors d’un déplacement, on peut en théorie changer de capteur (passer de la caméra à un sonar) sans que cela ait d’influence sur la manière d’exprimer la consigne.
Le superviseur est informé et appelé à chaque fois qu’un événement important intervient :
- passage en mode automatique à partir du mode manuel
- reprise manuelle à partir du mode automatique
- position et orientation cible atteintes
- estimation de position impossible
|
4) Séquenceur des tâches:
J’appelle « séquenceur » la partie du logicielle qui permet d’exécuter les différentes tâches à des fréquences différentes. Je n’utilise pas le « threading » du .Net Micro Framework, car il dépense trop de temps de calcul inutilement. Cette partie est finalement assez simple, car quasiment toutes les tâches sont appelées à une période fixe, et systématiquement appelées (sauf le superviseur).
Voici la répartition des tâches de calcul :
|
|
5) transitions manuel / pilote automatique :
Ces transitions sont gérées par le séquenceur et le superviseur. Un push dédié à la radiocommande permet d’envoyer des ordres simples, sans lâcher les joysticks. L’action sur ce push a des effets différents selon la situation :
- moteurs à l’arrêt, on effectue une réinitialisation du drone: les variables sont remises à leur valeur initiale. Ca évite d'avoir à réinitialiser toute la carte mère, ce qui est long (15 secondes)
- Moteurs en marche, mais posé au sol (moteurs à puissance faible), on ordonne un décollage, et une fois décollé, on enchaine avec le programme prévu par le superviseur.
- En vol, on déclenche le programme prévu par le superviseur
Pour revenir en mode manuel, il n’est pas nécessaire d’appuyer sur un bouton. Il suffit de bouger un des 2 joysticks. En effet, pour rester en « pilotage automatique », il faut que les 2 joysticks restent proches de la position initiale, c'est-à-dire celle pour laquelle on est rentré en mode automatique. La reprise manuelle peut alors être violente, surtout si la position joystick nécessaire pour stabiliser le drone est très différente de la position initiale (surtout pour les gaz). Il faut que le pilote (moi en l'occurrence) sache anticiper l’action.
Sécurité:
Si une information capteur vient à manquer (défaillance du capteur, connecteur qui se débranche), le logiciel choisi de désactiver IMMEDIATEMENT le pilotage automatique, et de repasser en 100% manuel. Ca n’arrive que très rarement, mais ça surprend !
J’ai vécu une seule situation sans cette sécurité qui m’a fait suffisamment peur : suite à un atterrissage violent, les 2 cartes se sont désolidarisées. La carte mère n'avait plus aucune information capteur valide. L’asservissement est alors passé instantanément à : Gaz à FOND, lacet à droite toute. Le drone est parti en toupie montante (du plus bel effet), et j’ai eu tout juste le temps de le rattraper. Suite à ça, j’ai programmé cette sécurité.
|
|
|