Simulateur interactifIntermédiaire

Simulateur mecanum : ripage, patinage et dérive

Pilotez un holonome de côté autour d'un carré, retirez l'adhérence, et regardez ses codeurs jurer que cela a marché. Puis montez une roue à l'envers.

Catégorie
Robots autonomes
Durée
20–40 min
Plateforme
Navigateur · Arduino · ESP32
Schéma technique : Simulateur mecanum : ripage, patinage et dériveBASE_LINKVxVyωzFOUR WHEELS · THREE DEGREES OF FREEDOMROLLERS AT 45° MAKE AN X

01 / Commencez ici

Introduction

Une roue mecanum ne pousse qu'à 45 degrés : c'est ce qui lui permet d'aller de côté, et ce qui la fait lâcher. Ce labo résout le vrai bilan des forces face à une limite de frottement, si bien que le patinage vient de la physique au lieu d'être dessiné — et il intègre les codeurs séparément du sol, pour que vous voyiez l'estimation du robot s'éloigner de la vérité sans que rien à bord ne puisse le détecter.

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.

Commandes

Chaque commande rejoue toute la manœuvre à la saisie, donc les parcours suivent le curseur pendant que vous le tirez. Il n’y a rien à démarrer.

Commande Ce qu’elle modifie
Preset Cinq situations traitées : une qui fonctionne, et quatre façons de cesser de fonctionner
Manoeuvre Ce que demande le pilote — un carré en ripage, un carré en tournant, un sprint en diagonale, ou rouler en tournant
Stick speed / Stick spin À quel point la commande est poussée
Stick frame Orienté robot, ou orienté terrain avec une centrale inertielle
Over the limit Met à l’échelle toute la commande par la pire roue, ou sature chaque roue séparément
Wheel top speed La vitesse libre des moteurs à la jante — un plafond dur, avec ou sans patinage
Floor grip μ Le béton poli vaut environ 0,8 ; un sol de gymnase poussiéreux ou du lubrifiant répandu vaut 0,25
Wheel fit Les quatre correctes, ou l’avant-gauche montée à l’envers

Le panneau de gauche est le sol. En pointillés la manœuvre commandée, en continu l’endroit où le robot est réellement allé, en pointillés fins l’endroit où ses propres codeurs croient qu’il est allé. Le panneau de droite montre les quatre vitesses de jantes des roues en fonction du temps, avec le plafond du moteur marqué. Une trace plate sur cette ligne est une roue à court de moteur ; le patinage apparaît dans le panneau de gauche, comme l’écart entre la ligne continue et la ligne en pointillés.

Théorie

Une roue mecanum ne peut transmettre de force au sol que le long des axes de ses rouleaux. Dans toute autre direction, le rouleau tourne simplement et rien n’est transmis. Ces axes sont à 45° de la roue, donc la force au sol d’une roue est clouée sur une seule droite au sol et aucun couple moteur ne la déplace.

Quatre de ces droites, en mains alternées, totalisent n’importe quoi. Écrivez la vitesse de jante de la roue face à la torsion du châssis ξ = (vx, vy, ω) et vous obtenez une ligne par roue :

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

Empilez les quatre lignes en une matrice A et toute la transmission est v = A·ξ. Trois conséquences, et le labo existe pour rendre chacune visible :

Quatre équations, trois inconnues. Un châssis rigide dont les roues accrochent toutes ne peut pas produire des vitesses de jantes arbitraires — l’équation supplémentaire dit FL + FR = RL + RR, toujours. Le résidu de ce contrôle est un détecteur de patinage gratuit calculable à partir des seuls codeurs. Il se déclenche sur un patinage asymétrique — une roue décollée, une roue sur une flaque, une roue au mauvais coin — et est complètement aveugle quand les quatre patinent ensemble, c’est pourquoi l’odométrie mecanum se dégrade silencieusement.

L’adhérence coûte 1/√2. La force motrice utile du moteur court dans la direction de roulement, mais la force au sol réelle vaut √2 fois cela, pointée le long de l’axe du rouleau — et le frottement plafonne tout le vecteur. La limite par roue est donc μN/√2 et le plafond d’accélération du robot est :

a_max = μ·g / √2

À μ = 0,85 cela fait 5,9 m/s² contre 8,3 m/s² pour le même robot sur roues lisses. La masse s’élimine des deux, donc lester ne change rien — l’inverse d’un robot qui pousse, où le poids est toute la stratégie.

Les diagonales coûtent aussi 1/√2. Une commande à 45° met vx + vy sur deux roues et zéro sur les deux autres, donc la paire active sature pendant que le robot ne roule qu’à V_MAX / √2. Des moteurs plus rapides déplacent ce plafond ; rien ne le supprime.

La démonstration complète, y compris l’inverse odométrique, est dans cinématique des roues mecanum.

Algorithme

Chaque pas de 5 ms, dans cet ordre. Les deux intégrations de pose à la fin sont volontairement séparées — cette séparation est la leçon d’odométrie.

  1. Lisez le manche pour ce point de la manœuvre.
  2. Tournez dans le repère du robot si orienté terrain : vx' = vx·cos θ + vy·sin θ, vy' = −vx·sin θ + vy·cos θ. L’orienté robot saute entièrement cela.
  3. Cinématique inverse — v = A·ξ, avec la matrice à laquelle le micrologiciel croit, qui est toujours la correcte. Une roue mal montée n’est pas quelque chose que le micrologiciel peut connaître.
  4. Limitez — mettez à l’échelle tout le vecteur par la pire roue, ou saturez chaque roue séparément.
  5. Retard des roues — chaque jante poursuit sa cible avec une réponse du premier ordre de 0,1 s, car une boucle de vitesse est bonne, pas instantanée.
  6. Ce que demandent les roues — cinématique avant aux moindres carrés sur les vitesses de jantes, avec la matrice du robot qui a été réellement construit.
  7. Résolvez les forces qui feraient correspondre le châssis, puis appliquez deux plafonds dans l’ordre : celui du moteur (il n’y a jamais eu qu’un couple limité) et celui du sol (μN/√2 par roue).
  8. Ce que le sol refuse fait patiner la jante à la place. Ce surplus accélère la roue hors de sa vitesse commandée, c’est le patinage, et c’est le seul symptôme de patinage qu’un codeur puisse jamais rapporter.
  9. Intégrez la vérité à partir des forces réellement appliquées.
  10. Intégrez l’odométrie à partir des vitesses de jantes, via la matrice du micrologiciel — car le codeur est boulonné à la roue, pas au sol.

Rien là-dedans ne cherche le patinage ni ne l’insère. Le patinage est l’étape 7 qui refuse une force, et la dérive que vous voyez est l’étape 10 qui ne l’apprend jamais.

Expériences guidées

Chacune isole une seule variable. Faites-les dans l’ordre ; elles s’enchaînent.

1. Ce pour quoi vous avez acheté des roues mecanum

Chargez A square that closes. Le robot avance d’un mètre, ripe d’un mètre à droite, recule et repart à gauche, et revient à 17 mm de son départ avec l’affichage de cap qui ne quitte jamais 0,0°. Basculez maintenant la manœuvre sur square, turning at the corners — le même carré, roulé comme un robot à propulsion différentielle le doit. Il se referme aussi, à 4 mm. Retenez que les deux fonctionnent ici.

Ce qu’il faut observer : le carré en ripage translate sur deux axes et ne dépense aucun cap pour le faire. Aucune propulsion différentielle ne peut tenter cela.

2. Retirez le sol

Tirez floor grip de 0,85 à 0,25, en gardant le carré en ripage. Faites pareil au carré en tournant.

Manœuvre Cap à μ = 0,85 Cap à μ = 0,25
Carré en ripage 0,0° 0,0°
Carré en tournant 0,2° des dizaines de degrés, et parfois une inversion complète

Ce qu’il faut observer : regardez le cap, pas la distance. Les deux robots glissent et les deux manquent leur point de départ ; celui en ripage manque tout en pointant exactement là où il a commencé, car il n’a jamais commandé de rotation. Celui qui tourne perd son cap puis roule sa jambe suivante dans la mauvaise direction, et c’est ainsi qu’un petit patinage devient une grande erreur. Chaque rotation est une nouvelle chance de perdre le fil, et la base holonome ne les prend tout simplement pas.

Les distances de cette expérience varient entre les essais à différents réglages, et c’est la réponse honnête plutôt qu’un bogue : un robot qui glisse sur ses quatre roues est un système à adhérence-glissement et n’atterrit jamais deux fois au même endroit. Le cap n’a pas ce problème.

3. Regardez les codeurs mentir

Chargez Same square, greasy floor et regardez les deux lignes sur le panneau de gauche. La ligne d’odométrie en pointillés roule un carré net ; la ligne continue non. Le robot finit à 225 mm de son point de départ pendant que ses propres codeurs le placent 133 mm ailleurs, après que 1,27 m de sol sont passés sous les roues sans déplacer le robot du tout.

Observez maintenant l’affichage Encoder disagreement. Il reste à 0,000 pendant tout ce temps.

Ce qu’il faut observer : le contrôle de résidu gratuit — FL + FR devrait égaler RL + RR sur tout châssis rigide — détecte une roue qui patine et est complètement aveugle aux quatre qui patinent ensemble. Cet aveuglement est exactement pourquoi l’odométrie mecanum échoue silencieusement. Mettez-y une centrale inertielle, ou des roues mortes, et cessez de faire confiance aux codeurs de propulsion pour la position.

4. Le plafond en √2

Chargez Diagonal dash. La vitesse du manche est de 0,60 m/s et la vitesse maximale des roues aussi, donc la commande devrait être réalisable. Elle ne l’est pas : la commande est saturée pendant 91 % de l’essai et le robot plafonne à 0,424 m/s — soit 0,60/√2 à trois décimales, atteint exactement.

Ce qu’il faut observer : sur le panneau de droite, deux traces restent plates à zéro pendant que deux sont clouées au plafond. Une commande à 45° met vx + vy sur deux roues et rien sur les deux autres, donc la paire active sature à V_MAX / √2. Augmentez la vitesse maximale des roues et le plafond bouge avec — les 71 % ne changent jamais.

5. Mise à l’échelle contre saturation

Basculez la manœuvre sur drive while spinning, poussez stick spin à 240 °/s, et alternez Over the limit entre les deux réglages. Le parcours change de forme.

Ce qu’il faut observer : la mise à l’échelle abandonne de la vitesse sur chaque axe et garde la direction. La saturation garde la vitesse avant et perd 27 % de la rotation — le robot tourne de 127° sur l’essai au lieu de 92° — donc il s’incurve différemment de ce qui était demandé. Revenez ensuite au sprint en diagonale et essayez le même basculement : rien ne se passe, car les roues au repos étaient déjà dans la limite. C’est ainsi que ce bogue survit aux tests.

6. Montez une roue à l’envers

Chargez One wheel fitted backwards, ou appuyez sur W sur les tracés. Rien n’a changé dans le code.

Les quatre correctes Avant-gauche miroir
Manqué de 17 mm plus d’un mètre
Variation de cap 0,0° des dizaines de degrés
Sol perdu en patinage 15 mm plusieurs mètres
Désaccord des codeurs 0,000 ≈ 0,28

Ce qu’il faut observer : le robot ne fait plus rien comme ce qui lui a été dit, et cette fois l’affichage de résidu se déclenche — fort et stable plutôt que par à-coups. Notez quelle colonne a des nombres exacts et laquelle n’en a pas : avec une roue qui lutte contre les trois autres, le robot glisse en continu, donc sa pose finale est chaotique. Le résidu est le nombre qui survit, c’est exactement pourquoi c’est celui à mettre sur une ligne de télémétrie. C’est le seul symptôme lisible sur un vrai robot sans centrale inertielle ni référence externe. Regardez aussi le robot dessiné : les hachures du coin miroir pointent du mauvais côté, et les quatre lignes de rouleaux ne font plus un X.

7. Orienté terrain, en une touche

Chargez Field-oriented while spinning, puis appuyez sur O pour repasser en orienté robot et sur O à nouveau pour revenir.

Ce qu’il faut observer : en orienté robot, un manche avant maintenu pendant la rotation dessine une rosace : le robot parcourt 2,34 m de trajectoire et finit à 0,30 m de son départ — 13 % de son effort est allé quelque part. En orienté terrain, le même manche parcourt 2,03 m et finit à 2,03 m : une ligne droite parfaite, 100 %, avec le corps qui tourne tout le long. Six lignes de trigonométrie séparent les deux, et c’est la différence entre un robot qu’un humain peut piloter et un que personne ne peut.

Ce que vous devriez observer

En rassemblant les sept :

  • L’avant est gratuit ; le latéral et la diagonale non. Chaque roue contribue pleinement à la marche avant. Une diagonale n’en utilise que la moitié.
  • Deux pénalités en racine de deux, issues du même 45°. La vitesse en diagonale, et l’adhérence dans toutes les directions. Ni l’une ni l’autre ne s’achète avec de plus gros moteurs.
  • La masse s’élimine. Le plafond d’accélération vaut μg/√2 quel que soit le poids du robot, ce qui est l’inverse d’un robot qui pousse.
  • L’holonome bat la propulsion différentielle quand le sol est mauvais, car les rotations sont d’où vient l’erreur.
  • L’odométrie est le prix. Pas un problème de réglage, pas un problème de meilleurs codeurs — le patinage des roues est le fonctionnement même de la transmission.

Transposition au matériel

Dans ce labo Sur un vrai robot
Un curseur d’adhérence Un sol, et un nombre découvert en poussant le robot avec un pèse-bagage
Les roues atteignent leur vitesse commandée avec un retard de 0,1 s Uniquement si vous avez construit une boucle de vitesse. En boucle ouverte, les rapports dérivent avec la batterie
Intégration odométrique parfaite et instantanée 50–100 Hz, avec quantification des codeurs et un débordement de micros() qui vous attend
Moteurs identiques Écartés de 3–8 % à la sortie de boîte, et davantage à chaud
Un μ propre pour tout le sol Poussière, joint dans le vinyle, câble — l’adhérence locale varie plus que prévu
Le montage des roues est une liste déroulante Le montage des roues, ce sont quatre vis et le contrôle du X, et vous vous tromperez une fois

Le labo vaut les vingt minutes surtout pour l’expérience 6. Monter une roue à l’envers ne coûte rien ici et une demi-journée sur l’établi, et c’est la panne que vous avez le plus de chances de construire.

Code source

Toute la transmission tient dans ces deux fonctions. La géométrie vit à exactement un endroit.

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]);
}

La démonstration de ces quatre lignes, et pourquoi le résidu fonctionne, est dans cinématique des roues mecanum. Faire en sorte que wheelLoop[i].target signifie quelque chose, c’est la commande de vitesse de roue en boucle fermée. Construire l’engin, c’est le robot omnidirectionnel mecanum.

Liste de vérification du matériel

Composants

  • Quatre roues mecanum, deux de chaque main — jamais quatre identiques
  • Quatre moto-réducteurs, un par roue, chacun réversible indépendamment
  • Quatre codeurs en quadrature, si vous voulez que les roues tiennent leurs rapports
  • Un sol plat, dur et propre, ce qui n'est pas négociable

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 mon robot mecanum tourne-t-il quand je lui demande de riper ?

Presque toujours parce qu'une roue est au mauvais coin. Un train mecanum comporte deux roues à gauche et deux roues à droite, et la main doit alterner autour du châssis. Mettez-en une au mauvais endroit et son vecteur de force pointe en travers du ripage au lieu de s'y joindre, donc une commande latérale devient une courbe lente avec une rotation dedans. La marche avant semble toujours correcte, ce qui rend cela si déroutant. Chargez le préréglage une roue montée à l'envers : un carré qui se refermait à 17 mm finit à plus d'un mètre avec des dizaines de degrés de rotation, sans aucun changement de code. Le nombre auquel se fier est le désaccord des codeurs, qui passe de 0,000 à environ 0,28 — un robot qui glisse sur chaque roue est un système à adhérence-glissement, donc l'endroit exact où il s'arrête n'est pas une prédiction, sur l'établi comme ici. Le contrôle de cinq secondes sur un vrai robot : tenez-vous au-dessus, regardez droit vers le bas, suivez les rouleaux visibles en haut de chaque roue — ces quatre lignes doivent viser le milieu et dessiner un X.

Pourquoi mon robot mecanum est-il plus lent en diagonale ?

Parce qu'une commande à 45 degrés demande tout à deux roues et rien aux deux autres. Réglez la manœuvre sur diagonal dash et regardez le tracé des vitesses de roues : deux traces restent plates à zéro pendant que deux sont clouées au plafond. Votre vitesse maximale en diagonale est donc la vitesse maximale des roues divisée par racine de deux, environ 71 pour cent de votre vitesse en ligne droite, et des moteurs plus rapides déplacent ce plafond sans le supprimer. C'est de la géométrie, pas un problème de réglage.

Pourquoi l'odométrie mecanum est-elle si mauvaise ?

Parce que le codeur est boulonné à la roue et que la roue n'est pas le sol. Sur une base mecanum, les rouleaux glissent par conception — c'est ainsi que fonctionne le mouvement latéral — donc chaque millimètre refusé par le sol entre dans le codeur comme un déplacement que le robot n'a jamais effectué. Chargez le préréglage gras et roulez le carré en ripage : le robot finit à 225 mm de son point de départ, sa propre estime à l'estime est à 133 mm ailleurs, et 1,27 m de sol sont passés sous les roues sans déplacer le robot. Rien à bord ne peut le dire. Pire, le contrôle de résidu qui détecte une roue qui patine devient muet quand les quatre patinent ensemble, donc l'erreur s'accumule en silence complet. C'est pourquoi les montages mecanum sérieux ajoutent une centrale inertielle pour le cap et des roues folles non motrices pour la position.

Faut-il mettre à l'échelle toute la commande ou saturer chaque roue ?

Mettez à l'échelle. Saturer chaque moteur avec un constrain() garde la vitesse et jette la direction. Réglez la manœuvre sur drive while spinning, poussez le lacet du manche à 240 degrés par seconde et basculez le limiteur : la mise à l'échelle conserve le cap commandé et ralentit tous les axes ensemble, la saturation garde la vitesse avant et abandonne silencieusement plus d'un quart de la rotation. Le piège est que sur une pure diagonale, les deux limiteurs produisent des nombres identiques, car les roues au repos sont déjà dans la limite — le bogue passe donc le test que tout le monde fait et apparaît plus tard comme un robot qui s'écarte dans les virages.

Un robot plus lourd a-t-il une meilleure adhérence sur roues mecanum ?

Pas pour l'accélération. Plus de masse achète proportionnellement plus de frottement et proportionnellement plus d'inertie, et les deux s'annulent exactement : le plafond d'accélération vaut mu fois g sur racine de deux quel que soit le poids du robot. C'est l'inverse d'un robot sumo, où le poids est toute la stratégie, car là la charge poussée est externe. Lester une base mecanum n'achète rien d'autre qu'une réponse moteur plus lente et une batterie plus plate.

Est-ce ce que fait un vrai robot mecanum ?

La cinématique est exacte — la même matrice à quatre lignes que toute implémentation réelle utilise, et l'odométrie est son inverse aux moindres carrés. La dynamique résout à chaque pas un vrai bilan des forces avec deux plafonds dans l'ordre, celui du moteur et celui du sol, et le patinage est le surplus refusé plutôt que quoi que ce soit de scénarisé. Ce qu'elle ne modélise pas, c'est le contact rouleau par rouleau à chaque entrée et sortie de rouleau au sol, la petite ondulation verticale qui en résulte, ni le transfert de masse sous accélération. Elle donne donc les bonnes réponses d'ingénierie — les pénalités en racine de deux, où va l'odométrie, ce que fait une roue à l'envers — et fonctionne un peu plus doucement qu'un vrai robot sur un vrai sol. Une réserve honnête : une fois que chaque roue glisse, le modèle est un système à adhérence-glissement de Coulomb, et la pose finale exacte cesse d'être un nombre répétable même si le labo lui-même est parfaitement déterministe. La distance de glissement, le résidu des codeurs et tous les cas adhérents sont solides ; un essai entièrement en glissement donne l'ordre du problème, pas l'endroit où le robot s'arrêtera.

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.