Simulateur interactifIntermédiaire

Simulateur de robot auto-équilibré : pendule inversé PID

Équilibrez un robot à deux roues dans le navigateur. Écartez-le de la verticale, poussez-le et désaccordez les gains PID en cascade : un équilibreur tombe.

Catégorie
Systèmes de commande
Durée
2–4 heures
Plateforme
Navigateur · Arduino
Schéma technique : Simulateur de robot auto-équilibré : pendule inversé PIDθTILT → PID → DRIVE UNDER IT

01 / Commencez ici

Introduction

Un robot auto-équilibré est un pendule inversé : sa masse se trouve au-dessus de l'axe, donc l'immobilité est un équilibre instable que seule une boucle active peut tenir. Tirez le corps sur le côté et lâchez-le, poussez-le, ou mettez le gain dérivé à zéro et regardez l'oscillation croître jusqu'au sol. Les tracés montrent l'inclinaison face à l'angle au-delà duquel aucun couple moteur ne peut le sauver.

Live lab / Inverted pendulum & cascaded PID

Self-balancing robot simulator

A two-wheeled robot with its centre of mass above the axle — an inverted pendulum that falls the moment the loop stops. Drag the body over and let go, shove it, or detune the gains and watch exactly how it fails.

Browser native
A self-balancing robot lab. A two-wheeled robot stands on a floor with its mass above the axle. The control loop reads the tilt angle and drives the wheels to stay under the body. A rolling chart above the robot plots tilt over the last few seconds against the fall threshold. Use the controls below to shove it, drag it off balance, change the PID gains, or switch the loop off and watch it fall.

Drag the robot to lean it over and let go — the loop takes it from wherever you leave it. The dashed line is the tilt target the outer loop is asking for; the bar at the axle is the motor command. The trace above plots tilt against the ±35° fall threshold.

  • Measured tilt
  • Tilt target (outer loop)
  • Motor command
  • Fall threshold
Simulation

Ready. Press Start, then drag the robot over and let go.

Inner loop — tilt to motors
Outer loop & hardware
Tilt
0.0°
Tilt target
0.0°
Motor
0%
Position
0 cm
Upright for
0.0 s
Worst tilt
0.0°

Keyboard: focus the robot, then use Space to run/pause, S to shove it, L to switch the loop on or off, R to reset, and F for full screen.

Commandes

Start, Pause et Reset pilotent la boucle. Shove applique une impulsion comme le ferait un doigt, et Loop on/off désactive les deux contrôleurs pour que vous puissiez voir le système nu tomber.

La commande la plus directe est le robot lui-même : tirez le corps jusqu’à n’importe quel angle et lâchez-le. Quelle que soit la pose où vous le laissez, le contrôleur prend le relais — il n’y a pas d’étape de réarmement, et les curseurs de gains s’appliquent immédiatement à la simulation en cours. Mettez le gain dérivé à zéro pendant qu’il s’équilibre et il commence à osciller dans la même seconde.

Le menu Tuning charge quatre préréglages : un qui fonctionne, et trois qui échouent des trois façons dont les vrais robots d’équilibre échouent.

Placez le focus sur le canevas et utilisez Espace, S, L, R et F pour les mêmes commandes au clavier.

Théorie

Tenir un robot debout sur deux roues signifie maintenir un pendule inversé à la verticale. Le centre de masse se trouve au-dessus de l’axe, donc la verticale est un équilibre au même sens qu’un crayon en équilibre sur sa pointe : mathématiquement réel, physiquement sans espoir sans correction permanente. Inclinez-le d’un angle quelconque et la gravité produit un couple qui l’incline davantage. Plus il s’écarte, plus il s’écarte vite.

Le robot n’a qu’un seul moyen de combattre ce couple — il peut déplacer l’axe. Accélérer les roues vers l’avant repousse la base sous le centre de masse, ce qui ramène le corps vers la verticale. C’est pourquoi la correction semble inversée au premier abord : pour cesser de tomber vers l’avant, il faut avancer, comme lorsque vous déplacez votre main sous un balai en équilibre plutôt qu’à l’opposé.

Schéma en deux panneaux. À gauche, un robot à deux roues penche vers l'avant d'un angle thêta par rapport à la verticale, avec une flèche montrant la gravité qui l'incline davantage. À droite, le même robot, avec une flèche montrant les roues avançant dans le même sens que l'inclinaison, et une flèche courbe montrant le corps qui se redresse depuis sa position penchée précédente.
La chute est l'entrée, pas l'échec : θ est ce que lit le contrôleur, et piloter les roues sous l'inclinaison est la seule façon de l'annuler. Télécharger le SVG

Cela impose au robot une limite stricte. Au-delà d’environ 35°, l’accélération horizontale nécessaire dépasse ce que les roues peuvent fournir avant que le corps ne touche le sol, et aucun gain n’y change rien. Les lignes en pointillés sur le tracé marquent cette frontière.

Algorithme

Le contrôleur est en cascade — deux boucles PID, l’une alimentant l’autre.

Schéma fonctionnel. Un bloc PID externe nommé position vers inclinaison fournit une cible d'inclinaison à un bloc PID interne nommé inclinaison vers moteurs, qui envoie du PWM à un bloc nommé robot. L'inclinaison mesurée revient du robot vers la boucle interne à 200 hertz, et la position des roues revient vers la boucle externe à 20 hertz.
Deux boucles, pas une. L'externe décide de combien pencher ; l'interne réalise cette inclinaison. Régler l'interne en premier est le seul ordre qui fonctionne. Télécharger le SVG

La boucle interne fonctionne vite et maintient un angle d’inclinaison. Elle compare l’angle mesuré à une cible et commande le couple des moteurs :

error   = measured_angle − target_angle
motor   = Kp·error + Ki·∫error + Kd·d(measured)/dt

Notez que l’erreur est la mesure moins la cible, et non la classique cible moins mesure. Rattraper une chute vers l’avant signifie piloter les roues vers l’avant, donc une inclinaison positive doit produire une commande moteur positive. Ce signe est la raison la plus fréquente pour laquelle un premier robot d’équilibre se plaque au sol dès sa mise sous tension.

La boucle externe fonctionne plus lentement et maintient une position. Elle ne peut pas commander les moteurs — ils sont déjà pris — elle commande donc une cible d’inclinaison pour la boucle interne :

target_angle = Kp_pos·(desired_position − position) − Kd_pos·velocity

En arrière de l’endroit où il veut être, elle demande une légère inclinaison vers l’avant ; la boucle interne pilote alors les roues pour tenir cette inclinaison, et le robot avance. L’inclinaison est volontairement limitée à quelques degrés. Une boucle externe autorisée à demander un grand angle confierait à la boucle interne une cible intenable, et les deux boucles perdraient ensemble.

Le terme intégral compte plus ici que dans la plupart des boucles, car c’est lui qui absorbe l’écart entre l’endroit où la centrale inertielle croit que se trouve la verticale et l’endroit où elle se trouve réellement. C’est aussi pourquoi l’intégrale doit cesser d’accumuler pendant que les moteurs sont saturés — sinon elle s’emballe pendant une chute qu’elle n’a pas la puissance d’empêcher, puis s’oppose à la récupération.

Code source

// Inner loop: tilt → motors. Runs every 5 ms off a timer, not in loop().
float angleError = angle - tiltTarget;          // measured minus target
angleIntegral   = constrain(angleIntegral + angleError * dt, -3, 3);
float command   = Kp * angleError
                + Ki * angleIntegral
                + Kd * gyroRate;                // rate straight from the gyro

command = constrain(command, -255, 255);
if (fabs(angle) > FALL_ANGLE) command = 0;      // past saving; cut the motors
driveMotors(command, command);

// Outer loop: position → tilt target. Runs ten times slower, and may only
// ever ask for a small lean.
if (++slowTick >= 10) {
  slowTick = 0;
  float positionError = 0 - wheelPosition;
  tiltTarget = constrain(KpPos * positionError - KdPos * wheelVelocity,
                         -0.12, 0.12);          // radians, about ±7°
}

Deux détails se transposent directement depuis ce simulateur. Prenez le terme dérivé de la vitesse du gyroscope plutôt qu’en différenciant l’angle : le gyroscope mesure cette vitesse directement et sans le bruit qu’amplifie la différentiation. Et coupez les moteurs au-delà de l’angle de récupération plutôt que de laisser le contrôleur forcer — cela épargne les réducteurs et rend l’échec net au lieu d’être violent.

Matériel

Le capteur est un MPU6050, qui contient à la fois un accéléromètre et un gyroscope, car aucun des deux n’est utilisable seul. L’accéléromètre sait où se trouve le bas mais est noyé par les propres mouvements du robot ; le gyroscope suit proprement la rotation mais dérive en quelques secondes. Un filtre complémentaire les fusionne en un angle à la fois stable et rapide.

Les moteurs doivent être assez démultipliés pour le couple et assez rapides pour rattraper une chute — des moto-réducteurs N20 autour de 200 tr/min sont un choix courant, pilotés par un TB6612FNG, dont la faible chute de tension compte lorsque la boucle demande de petites corrections des milliers de fois par seconde.

Construisez-le pour de vrai dans le projet de robot auto-équilibré, ou commencez par le tutoriel de lecture d’inclinaison si la centrale inertielle est nouvelle pour vous.

Hypothèses et différences avec le matériel

Le modèle est un pendule inversé 2D avec un seul axe d’inclinaison, des liaisons rigides, aucun patinage des roues et une centrale inertielle qui rend compte de l’angle et de la vitesse vrais avec seulement la dérive et le bruit que vous réglez. Un vrai robot d’équilibre subit un couple moteur qui varie avec la tension de la batterie, la quantification des codeurs, l’écart de montage de la centrale et la dérive en température, et il peut aussi tomber sur le côté — un degré de liberté que ce labo supprime entièrement. La structure PID en cascade et la dérivée issue du gyroscope présentées ici se transfèrent directement, mais l’écart de montage, le réglage du filtre et le seuil d’angle de chute doivent être retrouvés sur le châssis physique.

Schéma de câblage

Schéma fonctionnel de câblage. Un Arduino Nano se connecte en haut à une centrale inertielle MPU6050 en I2C sur SDA A4 et SCL A5, et à droite à un double pont TB6612FNG avec des signaux PWM et de direction. Le pont se connecte à un moteur N20 avec codeur. La voie A du codeur revient à l'Arduino sur la broche d'interruption D2, et une batterie étiquetée moteurs seuls alimente la broche VM du pont.
Un bus I²C vers le haut jusqu'à la centrale inertielle, quatre signaux vers le pont, et une alimentation moteur tenue à l'écart du rail logique. Télécharger le SVG

Deux règles de câblage décident si ce robot fonctionne.

La batterie des moteurs atteint la broche VM du pont et rien d’autre. Le courant des moteurs ne doit jamais traverser l’Arduino, et toutes les masses — carte, pont, centrale inertielle, moins de la batterie — doivent être reliées entre elles, sinon les signaux de commande n’ont aucune référence commune et la panne est silencieuse plutôt qu’évidente.

Le codeur est alimenté depuis la logique, pas depuis le rail des moteurs. Alimenter un codeur par l’alimentation des moteurs le détruit ou remplit les comptages de bruit de commutation. Placez aussi la voie A du codeur sur une broche compatible interruption ; l’interroger depuis loop() fait perdre des impulsions, et des impulsions perdues signifient que la boucle externe perd lentement la trace de l’endroit où se trouve le robot.

Montez la centrale inertielle près de l’axe. La monter en hauteur multiplie l’accélération linéaire qu’elle voit à chaque correction, ce qui complique le problème de fusion sans aucun bénéfice.

Liste de vérification du matériel

Composants

  • Arduino Nano ou Uno
  • Accéléromètre et gyroscope MPU6050
  • Double pont de puissance TB6612FNG
  • Deux moto-réducteurs N20 avec codeurs
  • Bloc de batterie au lithium 2S

Explorer le graphe

Où ce simulateur est utilisé

Les projets, parcours d'apprentissage et tutoriels qui s'appuient sur ce labo.

Continuer la construction

Ressources à télécharger

Utilisez ces références sur la page pendant que vous avancez dans le projet. Les archives de projet téléchargeables ne seront ajoutées qu'une fois leur source et leur version publiées.

Questions courantes

Questions fréquentes

Pourquoi un robot d'équilibre a-t-il besoin de deux boucles PID au lieu d'une ?

Parce que ce que vous voulez commander et ce que vous pouvez commander sont différents. Les moteurs modifient la vitesse des roues, mais ce qui maintient le robot en vie, c'est l'angle d'inclinaison, et la seule façon de modifier l'inclinaison est de déplacer les roues sous le corps. La boucle interne maintient donc un angle d'inclinaison en pilotant les moteurs, et la boucle externe demande un petit angle d'inclinaison pour amener le robot là où vous le voulez. Une seule boucle ne peut pas faire les deux : si vous pilotez les moteurs directement à partir de l'erreur de position, le robot accélère hors de son propre centre de masse et tombe immédiatement.

Pourquoi mon robot s'éloigne-t-il lentement alors qu'il semble à l'horizontale ?

Presque toujours un écart de montage. Si la centrale inertielle est montée à un ou deux degrés de la vraie verticale, la boucle maintient fidèlement ce mauvais angle, et maintenir une inclinaison constante signifie accélérer constamment dans cette direction jusqu'à manquer de place. Réglez le curseur d'écart dans ce labo et vous pouvez l'observer. Sur le matériel réel, la correction consiste à mesurer l'écart avec le robot tenu parfaitement droit et à le soustraire, puis à laisser le terme intégral absorber la dérive restante.

Peut-on équilibrer sans terme intégral ?

Oui, et le simulateur vous montrera que cela fonctionne — jusqu'à ce qu'un biais fausse la mesure. P et D seuls peuvent tenir le robot debout, car D fournit l'amortissement qui empêche l'oscillation de croître. Ce qu'ils ne peuvent pas faire, c'est supprimer un écart permanent : avec une erreur d'écart, le robot se stabilise avec une légère inclinaison permanente et dérive. L'intégrale est ce qui ramène ce dernier résidu d'erreur à zéro.

Pourquoi le robot tombe-t-il quand je mets le gain dérivé à zéro ?

Parce qu'il ne reste plus rien pour l'amortir. Le gain proportionnel réagit à la distance de chute du robot, mais au moment où il a corrigé, le corps traverse déjà la verticale avec de la vitesse. Sans un terme qui répond à la vitesse de variation de l'angle, chaque oscillation dépasse la précédente jusqu'à ce que l'une franchisse l'angle de récupération. Mettez D à zéro dans ce labo et vous pouvez compter les oscillations.

Pourquoi les roues avancent-elles quand le robot penche vers l'avant ?

C'est toute l'astuce, et c'est le signe que la plupart des gens inversent au premier essai. Pour tenir un balai en équilibre sur votre paume, vous déplacez votre main sous l'extrémité qui tombe, pas à l'opposé. Le robot fait pareil : pencher vers l'avant signifie avancer pour remettre les roues sous le centre de masse. Inversez ce signe et le contrôleur pousse activement le robot vers le sol, ce qui ressemble à une chute instantanée et violente.

En quoi est-ce différent du simulateur de contrôleur PID ?

Le labo PID commande un système stable : laissez-le tranquille et il reste simplement là, la boucle ne fait qu'améliorer la rapidité et la propreté avec lesquelles il atteint une cible. Ce système est instable — laissez-le tranquille et il tombe, à chaque fois. Cela change le réglage d'une optimisation en une exigence, et c'est pourquoi l'équilibrage a besoin de la seconde boucle externe que le labo à boucle unique n'a jamais besoin d'introduire.

Pour aller plus loin

Références

Des sources faisant autorité pour aller plus loin que le modèle pédagogique, borné, de ce simulateur.