Utiliser la classe MeEncoderOnBoard¶
Les principales méthodes de la classe¶
Voici un tableau avec la description des principales méthodes pour utiliser la classe MeEncoderOnBoard.
| Méthode | Description |
|---|---|
int getPortA(), getPortB() |
Retourne l'état du port |
long getPulsePos() |
Retourne la valeur du compteur de pulsation. Cette valeur incrémente ou décrémente continuellement jusqu'à la remise à zéro. |
void setPulsePos(long pulse_pos) |
Sert à régler la position du compteur. Généralement pour remettre à la zéro le compteur. |
void pulsePosPlus(), void pulsePosMinus() |
Incrémente ou décrémente le compteur. |
void setCurrentSpeed(float speed), float getCurrentSpeed() |
Configure et retourne la vitesse du moteur. |
int getCurPwm() |
Retourne le PWM actuel |
void setTarPwm(int pwm) |
Configure le PWM ciblé |
void setMotorPwm(int pwm) |
Configure le PWM au moteur. Il s'agit de la seule méthode qui contrôle directement les broches du moteur. |
long getCurPos() |
Retourne la position actuelle en degrés. |
void runSpeed(float speed) |
Indique la vitesse ciblée pour le moteur. La vitesse est en rpm. Utilise le mode PID. |
void move(long position,float speed = 100) |
Le moteur se déplace à la position relative.
speed] : Vitesse à laquelle effectuer le mouvement. |
void moveTo(long position,float speed = 100) |
Le moteur se déplace à la position absolue. C'est-à-dire par rapport au zéro initial. L'unité est en degré. |
long distanceToGo() |
Distance en degrés à parcourir avant d'atteindre la cible. 360° = 1 rotation. |
void setSpeedPid(float p,float i,float d); |
Configure les paramètres PID de la vitesse de l'encodeur |
void setPosPid(float p,float i,float d); |
Configure les paramètres PID de la position de l'encodeur |
void setPulse(int16_t pulseValue); |
Configure le nombre de pulsation par rotation de l'encodeur. Doit être 9. |
void setRatio(float ratio); |
Configure le ratio de la boîte de motoréduction. Doit être 39.267. |
void setMotionMode(PID_MODE\|PWM_MODE) |
Configure le mode de déplacement. Les valeurs possibles sont PID_MODE ou PWM_MODE. |
void loop() |
Fonction qui doit être appelée sans blocage dans la boucle principale. |
bool isTarPosReached() |
Fonction qui retourne vrai ou faux si la cible de position est atteinte. |
Comprendre l'erreur¶
Avant de plonger dans les boucles d'asservissement et les régulateurs PID, il est essentiel de comprendre le concept fondamental de l'erreur dans un système de contrôle.
Qu'est-ce que l'erreur?¶
L'erreur est la différence entre ce que nous voulons obtenir (la consigne ou valeur cible) et ce que nous obtenons réellement (la valeur mesurée).
Formule de base : $\(erreur = consigne - valeur\_mesurée\)$
Exemples concrets d'erreur :¶
-
Vitesse d'un moteur :
- Consigne : 100 RPM
- Vitesse mesurée : 95 RPM
- Erreur = 100 - 95 = +5 RPM
-
Position d'un robot :
- Consigne : avancer de 50 cm
- Distance parcourue : 48 cm
- Erreur = 50 - 48 = +2 cm
-
Angle de rotation :
- Consigne : tourner de 90°
- Angle mesuré : 92°
- Erreur = 90 - 92 = -2°
Interprétation du signe :
- Erreur positive (+) : Le système est en dessous de la consigne (il faut augmenter)
- Erreur négative (-) : Le système est au-dessus de la consigne (il faut diminuer)
Comment mesurer l'erreur?¶
Pour mesurer l'erreur, nous avons besoin de capteurs qui nous donnent la valeur réelle du système :
- Encodeurs : mesurent la position et la vitesse des moteurs
- Gyroscope : mesure l'orientation et la rotation
- Capteurs de distance : mesurent la position du robot
- Accéléromètre : mesure l'accélération et l'inclinaison
Exemple avec un encodeur :¶
Exemple de correction simple¶
Une fois que nous connaissons l'erreur, nous pouvons tenter une correction basique. Voici un exemple simple de correction proportionnelle :
Correction proportionnelle de base :¶
Exemple concret :¶
Situation initiale :
- Vitesse cible : 100 RPM
- Vitesse mesurée : 95 RPM
- PWM actuel : 150
- Erreur = 100 - 95 = +5 RPM
Correction :
- Correction = 5 × 2 = +10
- Nouveau PWM = 150 + 10 = 160
Résultat espéré : Le moteur devrait maintenant tourner plus vite et se rapprocher de 100 RPM.
Problèmes de la correction simple :¶
- Surcorrection : Si le facteur est trop grand, le système peut osciller
- Sous-correction : Si le facteur est trop petit, le système sera lent à corriger
- Pas de prévision : La correction ne tient pas compte de la tendance (si l'erreur augmente ou diminue)
C'est pourquoi nous utilisons des régulateurs PID plus sophistiqués, que nous verrons dans la prochaine section.
La précision avec une boucle d'asservissement¶
Une boucle d'asservissement est une fonction dont l'objectif est d'atteindre le plus rapidement possible une consigne et de la maintenir, et ce, peu importe les perturbations externes. Le principe général est de comparer la consigne et l'état du système de manière à le corriger efficacement. (Wikipédia)
Principe¶
Le principe de base d'un asservissement est de mesurer, en permanence, l'écart entre la valeur réelle et la valeur de consigne que l'on désire atteindre (l'erreur que nous avons vue précédemment), et de calculer la commande appropriée à appliquer de manière à réduire cet écart le plus rapidement possible.
Régulateur PID¶
- Lorsque l'on donne une consigne à un moteur, on ne peut garantir que celui-ci atteindra vraiment la valeur ciblée.
- Ceci est dû à plusieurs facteurs externes tels que la friction, l'inertie, les imperfections, etc.
- C'est pour ces raisons que les robots ne font pas une belle ligne droite lorsque l'on programme directement les moteurs sans prendre en considération l'encodeur.
Il y a une méthode éprouvée qui permet à un mécanisme d'atteindre sa cible rapidement et avec précision. Cette méthode est un régulateur PID.
- Le principe est de lire l'erreur (comme nous l'avons vu dans la section précédente) et d'effectuer des opérations mathématiques spécifiques avec cette erreur pour calculer une correction optimale.
- PID signifie Proportionnelle, Intégrale et Dérivée (différentielle).
- Dans notre contexte, nous utiliserons principalement un système PD (Proportionnel-Dérivé), c'est-à-dire que nous laisserons de côté le terme intégral pour simplifier.
La fonction complète pour calculer est la suivante:
- \(k_x\) sont des coefficients arbitraires que l'on obtient en faisant des tests.
- \(e\) est l'erreur
- Le \(t\) est le temps
- L'intégrale est la somme des erreurs.
- La différentielle est le taux de variation (pente) depuis la dernière erreur.
L'effet de la modification des coefficients peut donner le résultat suivant:

Pour ceux qui ont vu cette fonction mathématique complexe, ne vous inquiétez pas! Les fonctions PID sont déjà implémentées dans la classe MeEncoderOnBoard.
Simplifions la compréhension avec un exemple concret :
- Fréquence de lecture : L'encodeur est lu toutes les 20 ms
- Consigne : Le moteur doit tourner à 100 RPM
- Valeur mesurée : L'encodeur indique 98 RPM
- Erreur : \(100-98 = +2\) RPM
- Problème de la correction simple : Si on ajoute simplement 2 au PWM, on ne peut pas prédire l'erreur à la prochaine lecture. Le robot pourrait monter une pente, descendre, avoir plus de friction, etc.
- Ce que l'on fait c'est que l'on multiplie l'erreur par un facteur et on l'additionne à la consigne actuelle. Soit le \(k_\text{p} e\).
- En code ça donnerait
prop = kp * error;
- En code ça donnerait
- Ensuite pour la partie dérivée, on soustrait l'erreur actuelle de l'erreur précédente et on multiplie par le facteur \(k_d\).
- En code :
diff = kd * (error - errorPrevious);
- En code :
- Pour calculer le correctif, on ne fait qu'additionner la proportionnelle avec la différentielle.
- En code :
correction = prop + diff;
- En code :
- Pour combler le tout, on additionne la correction à la valeur actuelle. Par exemple :
- Comme mentionné plus tôt, nous utilisons principalement les termes proportionnel et dérivé pour nos besoins. Si un terme n'est pas nécessaire (comme l'intégral), on met
0comme argument dans les fonctions.
Si on regarde le tableau des méthodes, on remarque la présence des méthodes setPosPid et setSpeedPid. Elles représentent l'implémentation d'un PID. Il suffit d'ajuster les coefficients au besoin. Pour calibrer ces paramètres, il faut faire des essais, car cela dépendra de chaque système (poids du robot, friction des roues, etc.).
Les valeurs par défaut qui sont dans les exemples répondent bien pour nos besoins. Ainsi nous allons utiliser celles-ci.
Extra
Si vous avez de l'intérêt pour fouiller un peu, regardez les fonctions PID_angle_compute et PID_speed_compute dans l'exemple Firmware_for_Auriga. Essayez de trouver les éléments vus dans la théorie précédente.
Faire rouler le robot droit¶
Maintenant que nous avons compris les concepts d'erreur et de régulation PID, nous pouvons apprécier les fonctions de précision comme runSpeed() qui utilisent ces principes.
Pour s'assurer que le robot suit une ligne droite, nous devons :
- Configurer les paramètres : PID, encodeur et ratio du motoréducteur
- Utiliser les bonnes fonctions : Les méthodes qui intègrent le contrôle PID
- Surveiller et ajuster : Observer le comportement et ajuster au besoin
Dans le cas présent, il faut utiliser les méthodes runSpeed avec les valeurs désirées.
Par exemple, on pourrait créer et utiliser la fonction suivante :
Vous pouvez tester avec le projet ranger_encoder_ligne_droite qui est dans mes exemples.
Mais ça ne marche pas!!!¶
En effet, certains robots tendent vers la droite ou la gauche. C'est dû à plusieurs facteurs. Voici quelques-uns :
- Le poids du robot n'est pas équilibré.
- Les roues ne sont pas bien alignées.
- Les roues ne sont pas bien fixées.
- Les roues ne sont pas bien calibrées.
- Etc.
Vous constatez qu'il y a plusieurs facteurs possibles. Cela est principalement dû à la qualité des pièces et aux tolérances de fabrication. Il faut donc faire des ajustements logiciels pour compenser ces imperfections mécaniques.
Nous pouvons utiliser le gyroscope pour compenser. Il suffit de lire la valeur du gyroscope et de faire une correction en conséquence.
Le projet ranger_straight est un exemple qui utilise le gyroscope pour corriger la trajectoire du robot.
Voici la principale fonction qui permet au robot d'aller droit :
Pivoter le robot à un angle précis¶
Pour faire pivoter le robot avec précision, nous devons utiliser la géométrie du robot et les encodeurs. Voici une image avec les différentes mesures importantes :

Principe : Pour faire tourner le robot sur lui-même de 90°, chaque roue doit parcourir 1/4 de la circonférence du cercle formé par la trajectoire du robot.
Calculs nécessaires :
- Trouver la distance pour 1/4 tour.
- \(quartTour = circRobot / 4\)
- Trouver le nombre de tours de roue
- \(nbTours = quartTour / circRoue\)
- Trouver le nombre de pulsation pour effectuer 1/4 tour.
- \(nbPulsations = nbTours * 9 * 39.267\)
- Faire avancer/reculer le moteur de
nbPulsations
Faire tourner le robot¶

Pour faire tourner le robot en courbe, il faudra faire un peu de géométrie et d'algèbre.
- Trouver l'arc de cercle à parcourir en prenant le centre du robot. (
float arc)- \(arc = \frac{degre}{360}* 2\pi R\)
- Trouver les arcs des cercles externes et internes
- \(arcExt = \frac{degre}{360}* 2\pi (R + \frac{w2w}{2})\)
- \(arcInt = \frac{degre}{360}* 2\pi (R - \frac{w2w}{2})\)
Où :
- \(w2w\) = distance entre les 2 roues
- \(R\) = rayon de courbure à partir du centre du robot
-
\(degre\) = Nombre de degrés à pivoter
-
Trouver la distance pour les roues gauches et droites selon les arcs intérieurs et extérieurs.
IMPORTANT!!!
Ceci est la théorie où on ne prend pas en considération le niveau de la pile, le frottement, le glissement, etc. On pourra compenser avec le gyroscope.
Exercices¶
Objectifs : Mettre en pratique les concepts d'encodeurs et de précision vus dans ce cours.
-
Déplacement précis : Programmer le robot pour qu'il avance exactement de 1 mètre avec une précision de ±5%.
- Utiliser les encodeurs pour mesurer la distance parcourue
- Implémenter une correction si nécessaire
-
Aller-retour précis : Faire avancer le robot à 1 mètre ±5% puis le faire revenir exactement à son point de départ.
- Tester la répétabilité du système
- Observer l'accumulation des erreurs
Conseils :
- Calibrer les valeurs PID avant de commencer
- Mesurer physiquement la distance pour valider vos résultats
- Noter les facteurs qui affectent la précision (surface, batterie, etc.)
Questions¶
Questions de compréhension¶
- Définition de base :
- Qu'est-ce que l'erreur dans un système de contrôle? Donnez la formule.
- Quelle est la différence entre une erreur positive et une erreur négative?
- Calculs d'erreur :
- Si un moteur doit tourner à 120 RPM et qu'il tourne actuellement à 115 RPM, quelle est l'erreur?
- Interprétez le signe de cette erreur : que doit faire le système?
- Régulateur PID :
- Que signifient les lettres P, I et D dans "PID"?
- Pourquoi utilise-t-on principalement PD (sans l'intégrale) dans nos applications?
- Quel est le rôle du terme dérivé (D) dans le contrôle?
- Applications pratiques :
- Pourquoi un robot ne roule-t-il pas droit même si on donne la même vitesse aux deux moteurs?
- Comment le gyroscope peut-il aider à corriger la trajectoire d'un robot?
Questions de calcul¶
- Géométrie du robot :
- Un robot a un diamètre de roue de 6 cm et une distance entre roues de 15 cm. Combien de degrés chaque moteur doit-il tourner pour faire pivoter le robot de 90°?
- Montrez vos calculs étape par étape.
- Paramètres d'encodeur :
- Avec 9 pulsations par tour et un ratio de 39.267, combien de pulsations représente une rotation complète de la roue?
- Si la roue a une circonférence de 18.8 cm, quelle distance représente une pulsation?
Questions d'analyse¶
- Problèmes de précision :
- Listez 5 facteurs qui peuvent affecter la précision du déplacement d'un robot.
- Pour chaque facteur, proposez une solution ou compensation possible.
- Réglage PID :
- Si un système oscille beaucoup autour de sa cible, quel paramètre PID devriez-vous ajuster et comment?
- Si un système met trop de temps à atteindre sa cible, quel paramètre ajusteriez-vous?
- Capteurs et erreur :
- Quel capteur utiliseriez-vous pour mesurer l'erreur de vitesse d'un moteur? Pourquoi?
- Quel capteur utiliseriez-vous pour mesurer l'erreur d'orientation du robot? Pourquoi?
Questions de programmation¶
- Code pratique :
- Écrivez une fonction qui calcule l'erreur entre une consigne et une valeur mesurée.
- Écrivez une fonction simple qui applique une correction proportionnelle basée sur cette erreur.
- Configuration :
- Quel code utiliseriez-vous pour configurer les paramètres PID d'un encodeur avec kp=1.5, ki=0, kd=1.0?
- Comment faire pour que le robot avance en ligne droite à 80 RPM?