Interactieve simulatorGevorderd

Mecanum-aandrijfsimulatie: zijwaarts rijden, slip en drift

Bestuur een holonome robot zijwaarts rond een vierkant, neem de grip weg en zie hoe zijn encoders volhouden dat het lukte. Monteer daarna een wiel omgekeerd.

Categorie
Autonome robots
Tijd
20–40 min
Platform
Browser · Arduino · ESP32
Technisch schema: Mecanum-aandrijfsimulatie: zijwaarts rijden, slip en driftBASE_LINKVxVyωzFOUR WHEELS · THREE DEGREES OF FREEDOMROLLERS AT 45° MAKE AN X

01 / Begin hier

Inleiding

Een Mecanum-wiel kan alleen onder 45° drukken; daardoor kan het zijwaarts bewegen, en daardoor laat het los. Dit lab lost de werkelijke krachtenbalans op tegen een wrijvingsgrens, zodat slip iets is wat de fysica doet en niet iets wat het lab tekent — en het integreert de encoders los van de vloer, zodat je ziet hoe de schatting van de robot van de waarheid afdwaalt zonder dat iets aan boord dat kan merken.

Live lab / Holonomic motion

Mecanum drive simulator

Drive a square sideways without ever turning, then take the grip away and watch the encoders keep insisting it worked. Fit one wheel backwards and the same code drives a spiral.

Browser native
This lab drives a four-wheel mecanum robot through a manoeuvre and draws three paths: the one commanded, the one the floor actually saw, and the one the wheel encoders reported. Beside it, the four wheel rim speeds against time with the motor's free speed marked. Use the controls below to change the command, the floor and how the wheels are fitted.

Left: a top-down view of the floor. The dashed outline is the manoeuvre as commanded, the solid line is where the robot actually went, and the dotted line is where its own encoders believe it went. The robot is drawn at its final pose, with each wheel's roller hand hatched — on a correctly built base those hatches point at the centre and make an X. Right: the four wheel rim speeds against time, with the motor's free speed marked. A trace sitting flat on that line is a wheel that has run out of motor; slip shows up on the left instead, as the gap between the solid line and the dotted one.

  • Commanded manoeuvre
  • Where the robot went
  • Where the encoders say
  • Motor free speed
Try it

There is nothing to start — the whole manoeuvre is re-run as you drag any control. Step through the five presets to see the four ways a holonomic base stops doing what it was told.

The command
The robot and the floor

The robot drives the square sideways and comes home.

Missed home by
0 mm
Odometry drift
0 mm
Heading change
0.0°
Ground lost to slip
0 mm
Command clipped
0%
Encoder disagreement
0.000

Every action has a button above. If you prefer the keyboard, focus the plots and press P for the next preset, M for the next manoeuvre, O to switch between robot- and field-oriented, W to fit the front-left wheel backwards and back, R to reset and F for full screen; sliders respond to the arrow keys.

Bediening

Elke bediening speelt de hele manoeuvre opnieuw af zodra je iets aanraakt, dus de paden volgen een schuifregelaar terwijl je die sleept. Je hoeft niets te starten.

Bediening Wat het verandert
Voorinstelling Vijf uitgewerkte situaties: één die werkt, en vier manieren waarop het misgaat
Manoeuvre Wat de bestuurder vraagt — een vierkant door zijwaarts te rijden, een vierkant door te draaien, een diagonale sprint, of rijden terwijl hij draait
Sticksnelheid / Stickdraaiing Hoe hard het commando wordt gestuurd
Stickframe Robotgericht, of veldgericht met een IMU
Boven de grens Schaal het hele commando met het slechtste wiel, of begrens elk wiel op zichzelf
Topsnelheid wielen De vrije snelheid van de motoren aan de velgrens — een harde bovengrens, met of zonder slip
Vloergrijping μ Gepolierd beton ligt rond 0,8; een stoffige sportzaalvloer of gemorst smeermiddel is 0,25
Wielmontage Alle vier correct, of het voorste linkerwiel verkeerd om gemonteerd

Het linker paneel is de vloer. Gestreept is de manoeuvre zoals gevraagd, doorgetrokken is waar de robot werkelijk heen ging, en gestippeld is waar zijn eigen encoders denken dat hij heen ging. Het rechter paneel toont de vier snelheden aan de velgrens tegen de tijd, met de grens van de motor gemarkeerd. Een lijn die plat op die grens ligt is een wiel waar de motor op is; slip toont zich juist in het linker paneel, als de kloof tussen de doorgetrokken en de gestippelde lijn.

Theorie

Een Mecanum-wiel kan alleen kracht op de vloer zetten langs de assen van zijn rollen. In elke andere richting draait de rol simpelweg door en wordt er niets overgedragen. Die assen staan op 45° ten opzichte van het wiel, dus de grondkracht van één wiel is vastgepind aan één lijn op de vloer en geen hoeveelheid motorkoppel verplaatst die.

Vier van die lijnen, met afwisselende handigheid, kunnen samen alles opleveren. Schrijf de snelheid aan de velgrens van een wiel uit tegen de torsie van het chassis ξ = (vx, vy, ω) en je krijgt één rij per wiel:

vᵢ = vx + sᵢ·vy + (sᵢ·xᵢ − yᵢ)·ω        sᵢ = ±1, the roller hand

Stapel de vier rijen in een matrix A en de hele aandrijving is v = A·ξ. Drie gevolgen, en het lab bestaat om ze elk zichtbaar te maken:

Vier vergelijkingen, drie onbekenden. Een star chassis waarvan alle wielen grippen kan geen willekeurige snelheden aan de velgrens voortbrengen — de extra vergelijking zegt altijd FL + FR = RL + RR. Het residu van die controle is een gratis slipdetector die je alleen uit encoders kunt berekenen. Die slaat aan bij asymmetrische slip — één wiel van de grond, één wiel op een natte plek, één wiel in de verkeerde hoek — en is volledig blind wanneer alle vier tegelijk slippen, en daarom degradeert Mecanum-odometrie stilletjes.

Tractie kost 1/√2. De bruikbare aandrijfkracht van de motor loopt langs de rolrichting, maar de werkelijke grondkracht is √2 maal zo groot en wijst langs de rolas — en wrijving begrenst die hele vector. De grens per wiel is dus μN/√2 en de versnellingsgrens van de robot is:

a_max = μ·g / √2

Bij μ = 0,85 is dat 5,9 m/s² tegenover 8,3 m/s² voor dezelfde robot op gewone wielen. De massa valt er in beide gevallen weg, dus ballast verandert niets — het omgekeerde van een duwrobot, waar gewicht de hele strategie is.

Diagonalen kosten ook 1/√2. Een commando van 45° legt vx + vy op twee wielen en nul op de andere twee, dus het drukke paar verzadigt terwijl de robot slechts beweegt met V_MAX / √2. Snellere motoren verschuiven die grens; niets haalt die weg.

De volledige afleiding, inclusief de inverse van de odometrie, staat in kinematica van Mecanum-wielen.

Algoritme

Elke stap van 5 ms, in deze volgorde. De twee pose-integraties aan het einde zijn bewust gescheiden — die scheiding is de les van de odometrie.

  1. Lees de stick op dit punt in de manoeuvre.
  2. Roteer naar het robotframe als het veldgericht is: vx' = vx·cos θ + vy·sin θ, vy' = −vx·sin θ + vy·cos θ. Robotgericht slaat dit volledig over.
  3. Inverse kinematica — v = A·ξ, met de matrix die de firmware aanneemt, en dat is altijd de juiste. Een verkeerd gemonteerd wiel is iets wat firmware niet kan weten.
  4. Begrens — schaal de hele vector met het slechtste wiel, of begrens elk wiel op zichzelf.
  5. Wiellatentie — elke velgrens volgt zijn doel met een eerste-ordere respons van 0,1 s, want een snelheidslus is goed, niet instant.
  6. Wat de wielen vragen — kleinste-kwadraten-kinematica op de snelheden aan de velgrens, met de matrix van de robot die er werkelijk gebouwd is.
  7. Bereken de krachten waarmee het chassis zou overeenkomen, en pas dan twee grenzen in volgorde toe: die van de motor (er was altijd maar zoveel koppel) en die van de vloer (μN/√2 per wiel).
  8. Wat de vloer weigert, laat de velgrens draaien. Dat overschot versnelt het wiel weg van zijn gevraagde snelheid, en dat is wielslip; het is het enige symptoom van slip dat een encoder ooit kan melden.
  9. Integreer de waarheid vanaf de krachten die werkelijk zijn toegepast.
  10. Integreer de odometrie vanaf de snelheden aan de velgrens, via de matrix van de firmware — want de encoder zit op het wiel vastgeschroefd, niet op de vloer.

Niets daarin zoekt naar slip of voegt die toe. Slip is stap 7 die een kracht weigert, en de drift die je ziet is stap 10 die er nooit achter komt.

Begeleide experimenten

Elk experiment isoleert één variabele. Voer ze in volgorde uit; ze bouwen op elkaar voort.

1. Waar je Mecanum-wielen voor kocht

Laad Een vierkant dat sluit. De robot rijdt een meter vooruit, een meter naar rechts, terug en naar links en komt 17 mm bij zijn startpunt terug, terwijl de koersaflezing nooit van 0,0° afwijkt. Zet de manoeuvre nu op vierkant, draaiend in de hoeken — hetzelfde vierkant, gereden zoals een differentiaalaandrijving het moet rijden. Ook dat sluit, tot 4 mm. Onthoud dat ze hier allebei werken.

Wat je moet observeren: het zijwaartse vierkant verschuift over twee assen en geeft daar helemaal geen koers voor uit. Geen differentiaalaandrijving kan dat proberen.

2. Neem de vloer weg

Sleep vloergrijping van 0,85 naar 0,25, met het zijwaartse vierkant. Doe dat vervolgens hetzelfde met het draaiende vierkant.

Manoeuvre Koers bij μ = 0,85 Koers bij μ = 0,25
Vierkant door zijwaarts rijden 0,0° 0,0°
Vierkant door draaien 0,2° tientallen graden, en soms een volledige omkering

Wat je moet observeren: kijk naar de koers, niet naar de afstand. Beide robots slippen en beide missen huis; de zijwaartse mist terwijl hij nog precies wijst waar hij begon, omdat hij nooit om een draaiing heeft gevraagd. De draaiende verliest zijn koers en rijdt daarna zijn volgende etappe in de verkeerde richting, en zo wordt een kleine slip een grote fout. Elke draaiing is een nieuwe kans om de koers te kwijtzijn, en het holonome onderstel neemt ze simpelweg niet.

De afstanden in dit experiment schuiven tussen uitvoeringen met verschillende instellingen, en dat is het eerlijke antwoord in plaats van een fout: een robot die op alle vier de wielen slipt is een stick-slip-systeem en komt niet twee keer op dezelfde plek terecht. De koers heeft dat probleem niet.

3. Laat de encoders liegen

Laad Hetzelfde vierkant, glimmende vloer en kijk naar de twee lijnen in het linker paneel. De stippellijn van de odometrie tekent een net vierkant; de doorgetrokken lijn niet. De robot eindigt 225 mm van huis terwijl zijn eigen encoders hem 133 mm ergens anders plaatsen, nadat er 1,27 m grond onder de wielen door is gegaan zonder de robot ook maar te verplaatsen.

Kijk nu naar de aflezing encodermening. Hij blijft de hele tijd op 0,000 staan.

Wat je moet observeren: de gratis residucontrole — FL + FR zou op elk star chassis gelijk moeten zijn aan RL + RR — vangt één slippend wiel en is volledig blind voor alle vier die samen slippen. Die blindheid is precies waarom Mecanum-odometrie stilletjes faalt. Zet er een IMU op, of dode wielen, en vertrouw de aandrijfencoders niet meer voor de positie.

4. De √2-grens

Laad Diagonale sprint. De sticksnelheid is 0,60 m/s en dat is ook de topsnelheid van het wiel, dus het commando zou haalbaar moeten zijn. Dat is het niet: het commando wordt 91% van de run begrensd en de robot haalt 0,424 m/s — en dat is 0,60/√2 tot drie decimalen, exact bereikt.

Wat je moet observeren: in het rechter paneel liggen twee lijnen plat op nul terwijl er twee tegen de grens aan zitten. Een commando van 45° legt vx + vy op twee wielen en niets op de andere twee, dus het drukke paar verzadigt op V_MAX / √2. Verhoog de topsnelheid van het wiel en de grens schuift mee — de 71% verandert nooit.

5. Schalen tegenover begrenzen

Zet de manoeuvre op rijden terwijl draaien, duw stickdraaiing naar 240 °/s en schakel Boven de grens tussen de twee instellingen. Het pad verandert van vorm.

Wat je moet observeren: schalen geeft snelheid op elke as op en houdt de richting. Begrenzen houdt de voorwaartse snelheid en verliest 27% van de draaiing — de robot draait over de hele run 127° in plaats van 92° — en buigt daardoor anders dan gevraagd. Ga daarna terug naar de diagonale sprint en probeer dezelfde schakelaar: er gebeurt niets, want de inactieve wielen zaten al binnen de grens. Zo overleeft deze fout elke test.

6. Monteer een wiel omgekeerd

Laad Eén wiel omgekeerd gemonteerd, of druk op W in de grafieken. Er is niets aan de code veranderd.

Alle vier correct Voorste links gespiegeld
Afwijking van huis 17 mm meer dan een meter
Koersverandering 0,0° tientallen graden
Grond die aan slip verloren gaat 15 mm meerdere meters
encodermening 0,000 ≈ 0,28

Wat je moet observeren: de robot doet allang niet meer wat hem is opgedragen, en nu slaat de residuaflezing wél aan — groot en constant in plaats van schokmatig. Let op welke kolom exacte getallen heeft en welke niet: als één wiel tegen de andere drie vecht, slipt de robot continu en is zijn eindpose chaotisch. Het residu is het getal dat overblijft, en juist daarom is het de moeite waard hem op een telemetrielijn te zetten. Dat is het enige symptoom dat je op een echte robot kunt aflezen zonder IMU en zonder externe referentie. Kijk ook naar de getekende robot: de arcering van de gespiegelde hoek wijst de verkeerde kant op, en de vier rollijnen vormen geen X meer.

7. Veldgericht, met één toetsaanslag

Laad Veldgericht terwijl draaiend, druk dan op O om terug te schakelen naar robotgericht en nogmaals op O om terug te keren.

Wat je moet observeren: in robotgerichte stand tekent een vooruit gehouden stick tijdens het draaien een rozet: de robot legt 2,34 m pad af en eindigt 0,30 m van zijn startpunt — 13% van zijn inspanning komt ergens terecht. In veldgerichte stand legt dezelfde stick 2,03 m af en eindigt 2,03 m verderop: een rechte lijn, 100%, terwijl het chassis voortdurend blijft draaien. Zes regels trigonometrie scheiden de twee, en dat is het verschil tussen een robot die een mens kan besturen en een die niemand kan.

Wat je moet zien

De zeven samengevat:

  • Vooruit is gratis; zijwaarts en diagonaal niet. Elk wiel draagt volledig bij aan de voorwaartse beweging. Een diagonale beweging gebruikt er de helft van.
  • Twee √2-penalities, uit dezelfde 45°. Snelheid op een diagonaal, en tractie in elke richting. Geen van beide koop je weg met grotere motoren.
  • Massa valt weg. De versnellingsgrens is μg/√2, wat de robot ook weegt, en dat is het omgekeerde van een duwrobot.
  • Holonisch wint van differentieel als de vloer slecht is, want de draaiingen zijn de bron van de fout.
  • Odometrie is de prijs. Geen afstemmingsprobleem, geen probleem van betere encoders — het slippen van de wielen is hoe de aandrijving werkt.

Naar de hardware

In dit browserlab Op een echte robot
Een schuifregelaar voor grip Eén vloer, en een getal dat je vindt door de robot met een bagageweegschaal te duwen
Wielen halen hun gevraagde snelheid met 0,1 s vertraging Alleen als je een snelheidslus hebt gebouwd. Zonder terugkoppeling lopen de verhoudingen weg met de batterij
Perfecte, instantane odometrie-integratie 50–100 Hz, met kwantisatie van de encoders en een micros()-overloop die op je wacht
Identieke motoren 3–8% uit elkaar uit de doos, en nog verder uiteen bij warmte
Eén schone μ voor de hele vloer Stof, een voeg in het zeil, een kabel — lokale grip varieert meer dan je verwacht
Wielmontage is een keuzelijst Wielmontage is vier bouten en de X-controle, en je zet de wielmontage één keer verkeerd in

Het lab is de twintig minuten vooral waard voor experiment 6. Een wiel omgekeerd monteren kost hier niets en een halve dag op de werkbank, en het is de fout die je het vaakst bouwt.

Broncode

De hele aandrijving is deze twee functies. De geometrie staat op precies één plek.

const float LX = 0.075f;      // half the wheelbase, m (wheel centre to wheel centre / 2)
const float LY = 0.085f;      // half the track, m
const float K  = LX + LY;
const float R  = 0.0485f;     // wheel radius, m
const float V_MAX = 0.60f;    // rim speed the motors can actually hold, m/s

// Inverse kinematics + saturation. vx forward, vy LEFT, omega counter-clockwise.
void driveMecanum(float vx, float vy, float omega) {
  float w[4] = {
    vx - vy - K * omega,      // front left
    vx + vy + K * omega,      // front right
    vx + vy - K * omega,      // rear left
    vx - vy + K * omega,      // rear right
  };

  float peak = 0;
  for (int i = 0; i < 4; i++) peak = max(peak, fabsf(w[i]));
  if (peak > V_MAX) {                    // SCALE, never clip
    float s = V_MAX / peak;
    for (int i = 0; i < 4; i++) w[i] *= s;
  }

  for (int i = 0; i < 4; i++) wheelLoop[i].target = w[i];   // hand to the velocity loops
}

// Forward kinematics for odometry, and the free diagnostic.
float updateOdometry(const float rim[4], float dt) {
  float vx    = ( rim[0] + rim[1] + rim[2] + rim[3]) * 0.25f;
  float vy    = (-rim[0] + rim[1] + rim[2] - rim[3]) * 0.25f;
  float omega = (-rim[0] + rim[1] - rim[2] + rim[3]) * 0.25f / K;

  theta += omega * dt;
  poseX += (vx * cosf(theta) - vy * sinf(theta)) * dt;
  poseY += (vx * sinf(theta) + vy * cosf(theta)) * dt;

  // Four equations, three unknowns. On any rigid, gripping chassis this is zero.
  // Large and steady => a wheel is in the wrong corner. Bursty => something slipped.
  return (rim[0] + rim[1]) - (rim[2] + rim[3]);
}

De afleiding van die vier rijen, en waarom het residu werkt, staat in kinematica van Mecanum-wielen. Aan wheelLoop[i].target betekenis geven is gesloten wielsnelheidsregeling. Het bouwen is de Mecanum-omnidirectionele robot.

Hardwarechecklist

Componenten

  • Vier Mecanum-wielen, twee van elke handigheid — nooit vier dezelfde
  • Vier tandwielmotoren, één per wiel, elk afzonderlijk omkeerbaar
  • Vier kwadratuurencoders, als je wilt dat de wielen hun verhoudingen vasthouden
  • Een vlakke, harde, schone vloer, en dat is niet onderhandelbaar

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 draait mijn Mecanum-robot als ik hem laat zijwaarts rijden?

Bijna altijd staat er één wiel in de verkeerde hoek. Een Mecanum-set heeft twee linkshandige en twee rechtshandige wielen, en die handigheid moet rond het chassis afwisselen. Zet je er één op de verkeerde plek, dan wijst zijn krachtvector dwars over de zijwaartse beweging heen in plaats van erin, en wordt een zijwaarts commando een trage boog met een draaiing erin. Vooruit ziet het er nog steeds prima uit, en juist dat maakt het zo verwarrend. Laad de voorinstelling met één omgekeerd gemonteerd wiel: een vierkant dat tot 17 mm sloot, eindigt meer dan een meter verderop en tientallen graden gedraaid, zonder dat er één regel code verandert. Het getal dat je hier kunt vertrouwen is de encodermening, dat van 0,000 naar ongeveer 0,28 gaat — een robot die op elk wiel slipt is een stick-slip-systeem, dus waar hij precies stilhoudt is geen voorspelling, op de werkbank noch hier. De controle van vijf seconden op een echte robot: ga erboven staan, kijk recht naar beneden, volg de rollen die je bovenop elk wiel ziet — die vier lijnen moeten naar het midden wijzen en samen een X vormen.

Waarom is mijn Mecanum-robot langzamer in de diagonaal?

Omdat een commando van 45° twee wielen om alles vraagt en de andere twee om niets. Zet de manoeuvre op diagonale sprint en kijk naar de grafiek van de wielsnelheid: twee lijnen liggen plat op nul terwijl er twee tegen de grens aan zitten. Je maximale diagonale snelheid is dus de maximale wielsnelheid gedeeld door wortel twee, ongeveer 71 procent van je rechte snelheid, en snellere motoren verschuiven die grens zonder hem weg te halen. Het is geometrie, geen afstemmingsprobleem.

Waarom is Mecanum-odometrie zo slecht?

Omdat de encoder aan het wiel vastgeschroefd zit en het wiel niet de vloer is. Op een Mecanum-onderstel slippen de rollen met opzet — zo werkt zijwaartse beweging — dus elke millimeter die de vloer weigert gaat alsnog als afgelegde afstand de encoder in, terwijl de robot die nooit maakte. Laad de glimmende voorinstelling en rijd het zijwaartse vierkant: de robot eindigt 225 mm van huis, zijn eigen dode berekening zit 133 mm ernaast, en 1,27 m grond ging onder de wielen door zonder de robot te verplaatsen. Niets aan boord kan dat merken. Erger nog: de residucontrole die één slippend wiel opmerkt, valt stil wanneer alle vier tegelijk slippen, dus de fout stapelt zich volledig stil op. Daarom voegen serieuze Mecanum-builds een IMU toe voor de koers en ongedreven dode wielen voor de positie.

Moet ik het hele commando schalen of elk wiel apart begrenzen?

Schalen. Elk motor begrenzen met constrain() houdt de snelheid en gooit de richting weg. Zet de manoeuvre op rijden terwijl draaien, duw de stickdraaiing naar 240 graden per seconde en schakel de begrenzer: schalen houdt de gevraagde koers vast en vertraagt elke as tegelijk, begrenzen houdt de voorwaartse snelheid en geeft stilletjes meer dan een kwart van de draaiing op. De valkuil is dat beide begrenzers bij een zuivere diagonaal identieke getallen opleveren, omdat de inactieve wielen al binnen de grens zitten — dus de fout slaagt voor de test die iedereen doet en duikt pas later op als een robot die uit de bochten lekt.

Krijgt een zwaardere robot betere tractie op Mecanum-wielen?

Niet voor de versnelling. Meer massa koopt evenredig meer wrijving en evenredig meer traagheid, en die heffen elkaar exact op: de versnellingsgrens is mu maal g over wortel twee, ongeacht wat de robot weegt. Dat is het omgekeerde van een sumorobot, waar gewicht de hele strategie is, omdat daar de belasting die geduwd wordt extern is. Ballast op een Mecanum-onderstel koopt je niets dan een tragere motorrespons en een vlakkere batterij.

Doet een echte Mecanum-robot dit ook?

De kinematica is exact — dezelfde vierrijige matrix die elke echte implementatie gebruikt, en de odometrie is de kleinste-kwadraten-inverse ervan. De dynamica lost bij elke stap een echte krachtenbalans op met twee grenzen in volgorde, die van de motor en die van de vloer, en slip is het overschot dat wordt geweigerd in plaats van iets dat gescript is. Wat hij niet modelleert is rol-voor-rolcontact terwijl elke rol de grond opkomt en weer verlaat, de kleine verticale rimpeling die dat veroorzaakt, of gewichtsverplaatsing onder versnelling. Dus de technische antwoorden kloppen — de √2-penalities, waar de odometrie naartoe dwaalt, wat een omgekeerd gemonteerd wiel doet — en hij loopt iets soepeler dan een echte robot op een echte vloer. Eén eerlijke kanttekening: zodra elk wiel slipt, is het model een Coulomb-stick-slip-systeem en is de exacte eindpose geen reproduceerbaar getal meer, ook al is het lab zelf volledig deterministisch. De slipafstand, het encoderresidu en alle gevallen waarin de wielen grip hebben zijn solide; een volledig slippende rit vertelt je hoe groot het probleem is, niet waar de robot zal stoppen.

Verder lezen

Bronnen

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