Skip to content

Comment régler son asserv ?

jguyonneau edited this page Sep 22, 2020 · 14 revisions

Avant propos

Pour commencer à régler, il faut avoir un robot minimal. A savoir, vos moteurs avec la carte de puissance qui va bien, des roues codeuses et une source d'énergie ( de préférence la batterie que vous allez utiliser dans le robot). Le tout doit être relié correctement et fonctionnel ( via l'interface Encoders on récupere des ticks si on bouge une roue codeuse, et une consigne via l'inteface MotorController doit faire bouger les moteurs ). Par ailleurs, vous devez avoir une compréhension minimale du fonctionnement de l'asservissement en polaire d'un robot.

Si tout ce qui est mentionné dans le paragraphe précédent vous est inconnu..... Passez votre chemin :)

Ensuite, on commence par définir un sens pour le robot. Simplement, définir où est l'avant ( et donc à fortiori, où est à la droite et la gauche )

Réglage du sens des encodeurs

Information dans plotjuggler : raw_encoder/left & raw_encodeur_right

Tout d'abord, régler les inversions dans votre classe encodeur pour que le codeur droit bouge dans plotjuggler lorsque vous faites tourner le codeur droit (respectivement pour le gauche). Ensuite, vérifiez que lorsque vous faites avancer le robot vers l'avant, les ticks des codeurs sont positifs.

Exemple: Ici, les 2 codeurs sont dans le mauvais sens.

Ici le codeur gauche est dans le mauvais sens.

Ici c'est ok !

Réglage du sens des moteurs

Tout d'abord, surélevez votre robot pour qu'il ne s'enfuie pas :) Ensuite, on va désactiver la sortie de la boucle d'asservissement aux moteurs avec la commande:

asserv enablemotor 0

Puis, on demande au moteur droit d'avancer avec la commande:

asserv motorspeed r 10

Si c'est le mauvais moteur qui tourne, on si le sens est mauvais, on fait les modifications nécessaires.

Réglage des constances physiques

Il vous faut simplement spécifier :

  • ENCODERS_WHEELS_RADIUS_MM : le rayon de vos roues codeuses
  • ENCODERS_WHEELS_DISTANCE_MM : distance entre les 2 roues codeuses
  • ENCODERS_TICKS_BY_TURN : nombre de ticks par tour de vos encodeurs.

Par ailleurs, la valeur MAX_SPEED_MM_PER_SEC permet de donner la vitesse maximale atteignable pour votre robot. Cette vitesse s'applique pour les 2 régulateurs de vitesses, vous pouvez donc donner la vitesse max réelle de votre robot ( vous pouvez le déterminer en envoyant la commande de vitesse max aux 2 moteurs et regarder le résultat dans plotjuggler. Mais faites gaffes :) ). Surtout, la valeur de MAX_SPEED_MM_PER_SEC doit être une vitesse atteignable !

Réglage grossier des limiteurs d'accélération

Il y a une limite d'accélération appliqué à la sortie des régulateurs de cap et de distance, mais pour mettre au point le réglage des régulateur de vitesse, on essaye de se mettre dans un cas de figure vaguement réaliste, c'est à dire avec une consigne de vitesse limité en vitesse. Les consignes utilisés pour régler les régulateurs en vitesse réutilisent les 2 limiteurs d'accélération ( le limiteur d'accélération en distance pour la roue gauche, et le limiteur d'accélération en cap pour la roue droite). A cette étape, on se contente de mettre une limite d'accélération réaliste. Par exemple pour un robot dont la vitesse max est de 1m/s, une limite d'accélération de 0.66m/s^2 semble réaliste ( ie: 1.5s pour atteindre la Vmax ). Ne pas hésiter à l'étape suivante, au augmenter/diminuer cette limite !

Réglage des régulateurs en vitesses

Chaque roue est asservie en vitesse via des PI et peuvent être réglé à peut-prêt indépendamment. Pour cela, on utilise le clickodrome dans plotjuggler pour régler les coeffs PI, envoyer des consignes de vitesses et visualiser les résultats sur les courbes.

Notez bien que :

  • Testez que vos réglages fonctionnent pour toutes les vitesses possibles. Ie: a vitesse max, a 80%, a 50%, a 20% et aussi à une vitesse basse raisonnable.
  • Envoyez une consigne de vitesse sur une durée assez longue pour être sur que vos réglages arrivent à tenir la vitesse (1500ms ~ 2000ms c'est bien)
  • Pour régler votre PI, vous pouvez d'abord régler Kp pour avoir un comportement grosse masse puis régler Ki pour minimiser le temps de réponse et l'erreur statique. Cette méthode entraine un Kp grand et un Ki faible. Mais des fois, un Ki grand et un Kp faible marche mieux, il faut tester !

Une fois les 2 Pi réglés, on demande la même consigne de vitesse aux 2 PI pour voir comment ils se comportent. Si les 2 boucles d'asserv semblent se comporter de manière à peu prêt similaire ( temps de réponse à un échelon de vitesse + tenu de la consigne en régime stabilisé ) et que le robot avance vaguement droit, c'est pas mal !

Réglage des régulateur de cap et de distance

Les régulateurs en cap et distance sont de simples régulateurs proportionnels, ils sont donc facile à régler. Si le robot dérape un peu au démarrage, ce n'est pas grave (le limiteur d'accélération règlera ça), mais il doit atteindre sa position sans oscillation.

Réglage fin des limiteurs d'accélération

Pour éviter de déraper on limite l'accélération à la sortie des 2 régulateurs (avant le mélange des consignes). La limite s'applique uniquement sur l'accélération, et pas sur la décélération! La décélération est géré directement par le régulateur proportionnel. Il est important que les consignes de vitesses limités en accélération soient atteignables !

La limite d'accélération en sortie du régulateur de cap est simple et est exprimé directement en mm/s^2 ( ou delta_max_par_tour_de_boucle/frequence_asserv ).

La limite d'accélération en sortie du régulateur de distance est un poil plus complexe. On peut accélérer assez fort une fois le robot en mouvement, mais beaucoup moins quand il est à l'arrêt ou presque! Donc on va régler 3 valeurs :

  • l'accélération minimale (acc_max) qui va être appliqué quand le robot est à l'arrêt
  • l'accélération maximale (acc_min) qui va être appliqué quand le robot avancera assez vite
  • la vitesse (V_seuil) à partir de laquelle on considèrera que le robot avance assez vite pour appliquer l'accélération maximale.

Si la vitesse courante est supérieure à V_seuil, alors l'accélération sera limité à acc_max Sinon, l'accélération sera limité à acc_min + |V_courante| / V_seuil * (acc_max-acc_min)

Réglage du CommandManager

Le commandManager est la classe qui prend en entrée les commandes externes de haut niveau reçu ( va à tel point sur la table, avance de x mm, tourne de y radian, .... ) et les transforme en consignes pour les régulateurs de cap et de distance. Voir la page de présentation de l'archi : https://github.com/EsialRobotik/asserv_nucleo/wiki/Architecture

Réglage liée aux commandes basiques

Pour les commandes basiques ( avance, tourne, fait face à un point), il n'y a que 2 paramètres à régler qui servent à décider si la consigne a été atteinte ou non :

  • m_arrivalAngleThreshold_rad l'erreur sur le régulateur d'angle en dessous du quel on considère être arrivé
  • arrivalDistanceThreshold_mm l'erreur sur le régulateur de distance en dessous du quel on considère être arrivé

Réglage liée au goto non enchainé

Pour les commandes de types goto non enchainé, on utilise les paramètres précédents pour savoir si on est arrivé sur la cible. En plus, on défini un angle minimale gotoAngleThreshold_rad en dessous du quel, on se contente de tourner sans avancer. Par exemple, si une commande goto demande d'aller derrière la position actuelle du robot, on se tourne d'abord pour y faire face, puis on avance.

Réglage liée au goto enchainé

Le goto enchainé se base sur les réglages précédents. La 1ière version naïve de cet algorithme était de définir un cercle de rayon r_enchaine autour du robot. Si la cible n'est pas dans le cercle, on génère une consigne vers l'intersection de la ligne du centre du robot vers la cible et le cercle de rayon r_enchaine. Si la cible est dans le cercle, on génère une consigne vers la cible, ou on change de cible si la prochaine commande est enchainable.

screenshot avec géogebra ou version simplifié <<<

Le soucis étant que le rayon r_enchaine donne une vitesse constante au robot ( cela génère une erreur de distance constante et le régulateur de distance est un simple proportionnel ) qui est potentiellement en dessous de la vitesse max du robot. Si on augmente le rayon de r_enchaine pour aller plus vite, on va passer à la consigne suivante plus tôt et passer plus loin des cibles. De plus, même si r_enchaine permet d'atteindre la vitesse max, le régulateur de vitesse tenterai d'aller à vitesse max même lors de virages serrés, ce qui n'est pas forcement une bonne chose ( si le robot glisse sur le côté pendant un virage, on se décale, mais les roues codeuses ne peuvent pas le capter !).

Pour cela, une 2nd version de cet algorithme est en test. On défini 3 éléments:

  • Un cercle centré sur le robot de rayon r_vMax = VitesseMax/Kp_distance permettant de générer une erreur de distance qui va entrainer une vitesse max en sortie de régulateur d'angle.
  • Un cercle centré sur le robot de rayon r_next inférieur à r_vMax qui permet de décider de passer à la commande suivante si elle est enchainable.
  • Un angle ang_enchaine qui permet de passer à la commande suivante si elle est enchainable tout en restant à vitesse max.

L'algorithme fonctionne de la même manière que précédemment avec r_enchaine = r_vMax. La principale différence tient dans les conditions d'enchainement de la cible. On utilise la prochaine commande enchainable si une de ces condition est vérifié :

  • Si la prochaine commande est dans le cercle de rayon r_vMax et que l'erreur de cap ( aka deltaTheta) est inférieur à ang_enchaine
  • Si la prochaine commande est dans le cercle de rayon r_next

Autrement dit, on enchaine la prochaine commande au loin si c'est presque tout droit, sinon on ralenti pour tourner.

schéma <<