Interactieve simulatorGevorderd

Simulatie: zelfbalancerende robot met PID op een slinger

Balanceer een tweewielige robot in je browser. Sleep hem uit de verticale stand, duw hem en stel de gekoppelde PID-versterkingen verkeerd af om de val te zien.

Categorie
Regeltechniek
Tijd
2–4 uur
Platform
Browser · Arduino
Technisch schema: Simulatie: zelfbalancerende robot met PID op een slingerθTILT → PID → DRIVE UNDER IT

01 / Begin hier

Inleiding

Een zelfbalancerende robot is een omgekeerde slinger: de massa zit boven de as, dus stilstaan is een instabiel evenwicht dat alleen een actieve lus kan vasthouden. Sleep de romp naar de zijkant en laat los, duw hem, of zet de differentiaalversterking op nul en zie de oscillatie groeien tot hij op de grond slaat. De grafiek zet de kanteling uit tegen de hoek voorbij welke geen motorkoppel meer redding kan brengen.

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.

Bediening

Starten, Pauzeren en Resetten laten de lus draaien. Duwen levert een impuls zoals een vinger dat zou doen, en Lus aan/uit schakelt beide regelaars uit zodat je het kale proces kunt zien vallen.

De meest directe bediening is de robot zelf: sleep de romp naar een willekeurige hoek en laat los. In welke stand je hem achterlaat, daarin neemt de regelaar het over — er is geen herinschakelstap, en de versterkingschuifregelaars werken onmiddellijk op de draaiende simulatie. Zet de differentiaalversterking op nul terwijl hij aan het balanceren is en hij begint in diezelfde seconde te slingeren.

Het menu Afstellen laadt vier voorinstellingen: één die werkt, en drie die op de drie manieren falen waarop echte balancers falen.

Focus het canvas en gebruik spatie, S, L, R en F voor dezelfde bediening vanaf het toetsenbord.

Theorie

Een robot op twee wielen overeind houden betekent een omgekeerde slinger overeind houden. Het zwaartepunt zit boven de as, dus verticaal is een evenwicht in dezelfde zin als een potlood dat op zijn punt balanceert: wiskundig reëel, fysiek hopeloos zonder constante correctie. Kantel hem met een willekeurige hoek en de zwaartekracht levert een koppel dat hem verder kantelt. Hoe verder hij gaat, hoe sneller het gaat.

De robot heeft precies één manier om dat koppel te bestrijden — hij kan de as verplaatsen. De wielen vooruit versnellen duwt de basis terug onder het zwaartepunt, waardoor de romp terug naar verticaal draait. Daarom voelt de correctie eerst omgekeerd: om voorover vallen te stoppen moet je vooruit rijden, op dezelfde manier als je je hand beweegt onder een bezem die je in balans houdt in plaats van ervandaan.

Een diagram met twee panelen. Links kantelt een tweewielige robot met een hoek theta vooruit vanuit de verticale stand, met een pijl die laat zien dat de zwaartekracht hem verder kantelt. Rechts hetzelfde robotje, met een pijl die laat zien dat de wielen vooruit rijden in dezelfde richting als de helling, en een gebogen pijl die laat zien dat de romp terug zwaait naar rechtop vanuit de vorige gehelde stand.
Vallen is de invoer, niet de storing: θ is wat de regelaar afleest, en de wielen onder de helling rijden is de enige manier om die op te heffen. SVG downloaden

Dat geeft de robot een harde grens. Voorbij ongeveer 35° is de benodigde horizontale versnelling groter dan de wielen kunnen leveren voordat de romp de vloer raakt, en geen enkele versterking helpt. De stippellijnen in de grafiek markeren die grens.

Algoritme

De regelaar is gekoppeld — twee PID-lussen, de een voedt de ander.

Een blokdiagram. Een buitenste PID-blok met het label position to lean voert een kanteldoel in een binnenste PID-blok met het label tilt to motors, dat PWM stuurt naar een blok met het label robot. De gemeten kanteling komt terug van de robot naar de binnenste lus op 200 hertz, en de wielpositie komt op 20 hertz terug naar de buitenste lus.
Twee lussen, niet één. De buitenste bepaalt hoe ver hij overhellt; de binnenste laat die helling gebeuren. De binnenste eerst afstellen is de enige volgorde die werkt. SVG downloaden

De binnenste lus draait snel en houdt een kantelhoek vast. Hij vergelijkt de gemeten hoek met een doel en beveelt motorkoppel:

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

Let op dat de fout gemeten min doel is, niet het klassieke doel min gemeten. Een voorwaartse val opvangen betekent de wielen vooruit rijden, dus een positieve kanteling moet een positieve motorsturing opleveren. Dit teken is de meest voorkomende reden dat een eerste balancerende robot zich de seconde dat hij aangaat op de grond stort.

De buitenste lus draait langzamer en houdt een positie vast. Hij kan de motoren niet aansturen — die zijn al bezet — dus stuurt hij in plaats daarvan een kanteldoel voor de binnenste lus:

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

Achter de plek waar hij wil zijn vraagt hij om een kleine voorwaartse helling; de binnenste lus rijdt dan de wielen aan om die helling vast te houden, en de robot rijdt vooruit. De helling wordt bewust begrensd tot een paar graden. Een buitenste lus die een grote hoek mag eisen geeft de binnenste lus een doel dat hij niet kan vasthouden, en beide lussen verliezen tegelijk.

De integratorterm is hier belangrijker dan in de meeste lussen, omdat hij het verschil opvangt tussen waar de IMU denkt dat verticaal ligt en waar verticaal werkelijk is. Hij is ook de reden dat de integrator moet stoppen met accumuleren terwijl de motoren verzadigd zijn — anders loopt hij op tijdens een val die hij geen macht heeft te voorkomen, en vecht hij daarna tegen het herstel.

Broncode

// 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°
}

Twee details neem je rechtstreeks over uit deze simulator. Neem de differentiaalterm van de gyroscoopsnelheid in plaats van de hoek te differentiëren: de gyroscoop meet die snelheid rechtstreeks en zonder de ruis die differentiëren versterkt. En schakel de motoren af voorbij de herstelhoek in plaats van de regelaar te laten blijven trekken — dat spaart de versnellingsbakken en maakt de storing duidelijk in plaats van heftig.

Hardware

De sensor is een MPU6050, die zowel een versneller als een gyroscoop bevat, omdat geen van beide op zichzelf bruikbaar is. De versneller weet waar omlaag is maar wordt overspoeld door de beweging van de robot zelf; de gyroscoop volgt rotatie zuiver maar loopt binnen seconden weg. Een complementair filter voegt ze samen tot een hoek die zowel stabiel als snel is.

Motoren moeten laag genoeg verkleed zijn voor koppel en snel genoeg om een val op te vangen — N20-kastmotoren rond 200 rpm zijn een gangbare keuze, aangestuurd door een TB6612FNG, waarvan de lage spanningsval telt wanneer de lus duizenden keren per seconde om kleine correcties vraagt.

Bouw hem echt in het project zelfbalancerende robot, of begin met de tutorial kanteling lezen als de IMU nieuw voor je is.

Aannames en hardwareverschillen

Het model is een tweedimensionale omgekeerde slinger met één kantelas, starre koppels, geen wielslip en een IMU die de werkelijke hoek en snelheid meldt met alleen de drift en ruis die je zelf instelt. Een echte balancerende robot voelt motorkoppel dat meebeweegt met de accuspanning, encoderkwantisatie, IMU-montageoffset en temperatuurdrift, en hij kan ook opzij vallen — een vrijheidsgraad die dit lab volledig weglat. De gekoppelde PID-structuur en de differentiaalterm op de gyroscoopsnelheid die hier getoond worden gaan rechtstreeks over, maar de montage-trim, de filterafstelling en de grenshoek voor vallen moeten op het fysieke chassis opnieuw worden gevonden.

Schakelschema

Een bedradingsblokdiagram. Een Arduino Nano verbindt omhoog met een MPU6050-IMU via I2C op SDA A4 en SCL A5, en naar rechts met een TB6612FNG dubbele besturing met PWM- en richtingsignalen. De besturing verbindt met een N20-motor met encoder. Encoderkanaal A gaat terug naar de Arduino op interruptpin D2, en een accu met het label motors only voedt de VM-pin van de besturing.
Eén I²C-bus omhoog naar de IMU, vier signalen over naar de besturing, en een motorvoeding die los staat van de logische rail. SVG downloaden

Twee bedradingsregels bepalen of deze robot werkt.

De motoraccu bereikt de VM-pin van de besturing en niets anders. Motorstroom mag nooit door de Arduino lopen, en alle massa’s — bord, besturing, IMU, accuminus — moeten met elkaar verbonden zijn, anders hebben de regelsignalen geen gemeenschappelijke referentie en is de storing stil in plaats van duidelijk.

De encoder krijgt voeding uit de logica, niet uit de motorrail. Een encoder op de motorvoeding spannen vernietigt hem of vult de tellingen met schakelruis. Zet encoderkanaal A ook op een pin die interrupts kan verwerken; hem uit loop() pollen kost tellingen, en verloren tellingen betekenen dat de buitenste lus langzaam kwijtraakt waar de robot is.

Monteer de IMU dicht bij de as. Hoog monteren vermenigvuldigt de lineaire versnelling die hij bij elke correctie ziet, wat het fusieprobleem moeilijker maakt zonder enig voordeel.

Hardwarechecklist

Componenten

  • Arduino Nano of Uno
  • MPU6050-versneller en gyroscoop
  • TB6612FNG dubbele motorbesturing
  • Twee N20-encoderkastmotoren
  • 2S-lithiumaccupakket

Verken de graaf

Waar deze simulator wordt gebruikt

De projecten, leerroutes en tutorials die op dit lab voortbouwen.

Verder bouwen

Hulpmiddelen downloaden

Gebruik deze naslag op de pagina terwijl je het project doorwerkt. Downloadbare projectpakketten komen er pas bij nadat hun broncode en versie zijn gepubliceerd.

Veelgestelde vragen

Veelgestelde vragen

Waarom heeft een balancerende robot twee PID-lussen nodig in plaats van één?

Omdat het ding dat je wilt regelen en het ding dat je kunt regelen verschillend zijn. De motoren veranderen de wielsnelheid, maar wat de robot in leven houdt is de kantelhoek, en de enige manier om die hoek te veranderen is de wielen onder de romp te bewegen. De binnenste lus houdt dus een kantelhoek vast door de motoren aan te sturen, en de buitenste lus vraagt om een kleine kantelhoek om de robot daar te krijgen waar je hem hebben wilt. Eén lus kan niet allebei: als je de motoren rechtstreeks op de positiefout aanstuurt, versnelt de robot weg van zijn eigen zwaartepunt en valt hij meteen.

Waarom rijdt mijn robot langzaam weg terwijl hij er waterpas uitziet?

Bijna altijd de montage-trim. Als de IMU een à twee graden uit de werkelijke verticale lijn staat, houdt de lus die verkeerde hoek getrouw vast, en een constante helling betekent constante versnelling in die richting tot je geen ruimte meer hebt. Stel de trim-schuifregelaar in dit lab in en je kunt het zien gebeuren. De oplossing op echte hardware is om de offset te meten met de robot werkelijk rechtop en die af te trekken, en de integrator de resterende drift te laten opvangen.

Kan ik balanceren zonder integratorterm?

Ja, en de simulator laat je zien dat het werkt — tot het moment dat er iets de meting bevoordeelt. P en D alleen kunnen de robot overeind houden, omdat D de demping levert die voorkomt dat de oscillatie groeit. Wat ze niet kunnen is een constante offset verwijderen: bij elke trimfout komt de robot tot stilstand in een kleine blijvende helling en kruipt hij weg. De integrator drijft dat laatste beetje fout naar nul.

Waarom valt de robot als ik de differentiaalversterking op nul zet?

Omdat er dan niets overblijft om hem te dempen. De proportionale versterking reageert op hoe ver de robot al gevallen is, maar tegen de tijd dat hij gecorrigeerd heeft, zwaait de romp al met vaart door de verticale stand. Zonder een term die reageert op hoe snel de hoek verandert, schiet elke zwaai verder door dan de vorige tot er een de herstelhoek overschrijdt. Zet D op nul in dit lab en je kunt de zwaaien tellen.

Waarom rijden de wielen vooruit als de robot voorover kantelt?

Dat is de hele truc, en het is het teken dat de meeste mensen in de eerste poging omdraaien. Om een bezem op je handpalm te houden beweeg je je hand onder het vallende uiteinde, niet ervandaan. De robot doet hetzelfde: voorover kantelen betekent vooruit rijden om de wielen weer onder het zwaartepunt te krijgen. Draai dat teken om en de regelaar duwt de robot actief omver, wat eruitziet als een onmiddellijke, heftige val.

Hoe verschilt dit van de simulator van de PID-regelaar?

Het PID-lab regelt een stabiel proces: laat het met rust en het zit er gewoon, dus de lus verbetert alleen hoe snel en hoe netjes het zijn doel bereikt. Dit proces is instabiel — laat het met rust en het valt om, elke keer. Dat verandert afstellen van een optimalisatie in een eis, en daarom heeft balanceren de tweede, buitenste lus nodig die het lab met één lus nooit hoeft te introduceren.

Verder lezen

Bronnen

Gezaghebbende bronnen om dieper te gaan dan het afgebakende leermodel van deze simulator.