🤖 Cinématique robotique · sur automate (PLC)

Chapitre 04
MDH & autres paramétrisations

Objectifs du chapitre

1. Pourquoi d'autres conventions ?

Au chapitre 3, nous avons paramétré la chaîne cinématique avec la convention de Denavit-Hartenberg classique (dite distale : le repère i est attaché à l'extrémité distale — côté effecteur — de la liaison i). Quatre paramètres par liaison — θi, di, ai, αi — et la transformation i-1Ti = Rotzi)·Transz(di)·Transx(ai)·Rotxi). C'est minimal (4 paramètres au lieu de 6) et universellement tabulé par les constructeurs. Alors pourquoi aller plus loin ?

Deux limites structurelles apparaissent dès qu'on sort de l'enseignement :

Ces deux défauts ont motivé plusieurs paramétrisations alternatives : la DH modifiée de Craig (autre placement des repères, très répandue en calibration), le paramètre de Hayati (qui répare spécifiquement le cas des axes parallèles), le produit d'exponentielles (géométrique, sans singularité), et le format URDF de ROS (arborescent, issu de la CAO). Ce chapitre les présente et vous aide à choisir.

Aucune de ces conventions ne change la physique. Un robot donné a une cinématique directe unique ; les paramétrisations ne sont que des langages pour la décrire. On peut toujours convertir de l'une à l'autre. Ce qui change, c'est la commodité selon l'usage : lisibilité, minimalité, robustesse numérique, outillage disponible.

2. La DH modifiée (MDH, convention de Craig)

La convention DH modifiée — popularisée par John J. Craig dans son Introduction to Robotics — utilise les mêmes quatre paramètres (θ, d, a, α) mais les place différemment. C'est la source d'innombrables confusions : une table DH « brute » est inexploitable si l'on ignore de quelle convention elle relève.

2.1 Placement du repère : proximal au lieu de distal

Différence fondamentale : en MDH, le repère Ri est attaché à l'extrémité proximale de la liaison i (côté base), c'est-à-dire sur l'axe de la liaison i elle-même. En DH classique, il était sur l'axe de la liaison i+1 (extrémité distale). Conséquence directe sur l'indexation : les paramètres géométriques du segment portent désormais l'indice i-1.

2.2 Ordre du produit

Parce que le repère est placé « en amont », l'ordre des quatre transformations élémentaires est inversé et regroupé différemment de la DH classique. On commence par la partie indexée i-1 (rotation puis translation en x), puis la partie indexée i (rotation puis translation en z) :

i-1Ti = Rotxi-1) · Transx(ai-1) · Rotzi) · Transz(di)

À comparer avec la DH classique : i-1Ti = Rotzi)·Transz(di)·Transx(ai)·Rotxi). Les briques sont les mêmes ; leur ordre et l'indice de a, α diffèrent — d'où une matrice finale de forme distincte.

2.3 La matrice 4×4 MDH explicite

En développant le produit ci-dessus (avec cθ = cos θi, sθ = sin θi, cα = cos αi-1, sα = sin αi-1), on obtient :

i-1Ti = [  cθ        −sθ       0        ai-1  ;
  sθ·cα   cθ·cα   −sα   −di·sα  ;
  sθ·sα   cθ·sα    cα    di·cα  ;
  0         0        0        1  ]

Notez la colonne de translation : ai-1 apparaît « en haut » (sur x), tandis que di se projette sur y et z via sα, cα. C'est exactement l'inverse de l'agencement classique — d'où l'importance de ne jamais mélanger les deux formes.

DH ≠ MDH : la même table donne un robot différent. Si vous saisissez une table établie en MDH dans une fonction écrite pour la DH classique (ou l'inverse), vous obtenez une géométrie fausse — souvent avec un décalage d'un cran des paramètres a, α. Vérifiez toujours la convention de la source (constructeur, article, fichier de calibration) avant de coder. Une bonne discipline : nommer explicitement vos fonctions DhTransform (distale) et MdhTransform (proximale), jamais un vague Dh.

2.4 Tableau comparatif DH classique vs MDH

AspectDH classique (distale)DH modifiée (MDH, Craig)
Placement du repère Riextrémité distale de la liaison i (sur l'axe i+1)extrémité proximale de la liaison i (sur l'axe i)
Indice de a, αai, αiai-1, αi-1
Ordre du produitRotz·Transz·Transx·RotxRotx·Transx·Rotz·Transz
Position de a dans la matriceprojeté par cθ, sθ (ligne 1-2)directement sur x (élément [0][3])
Contexte d'usage typiqueenseignement, tables constructeur, code « legacy »calibration, beaucoup d'outils académiques et industriels (Craig)

2.5 La fonction ST

On la construit sur le même modèle que DhTransform du chapitre 3 (mêmes types T_MAT4, passage par VAR_IN_OUT). Ici on passe explicitement les paramètres, la variable articulaire étant supposée déjà ajoutée à theta (rotoïde) ou à d (prismatique) par l'appelant.

// Transformation homogène i-1 -> i selon la convention DH MODIFIÉE (Craig).
//   T := Rot_x(alpha_prev) * Trans_x(a_prev) * Rot_z(theta) * Trans_z(d)
// alpha_prev, a_prev : paramètres géométriques indexés i-1
// theta, d           : incluent déjà l'éventuelle variable articulaire.
FUNCTION MdhTransform : BOOL
VAR_INPUT
    alpha_prev : LREAL;   // rad — alpha_{i-1}
    a_prev     : LREAL;   // m   — a_{i-1}
    theta      : LREAL;   // rad — theta_i (offset + q si rotoïde)
    d          : LREAL;   // m   — d_i    (offset + q si prismatique)
END_VAR
VAR_IN_OUT
    T : T_MAT4;           // résultat
END_VAR
VAR
    ct, st, ca, sa : LREAL;
END_VAR
    ct := COS(theta);
    st := SIN(theta);
    ca := COS(alpha_prev);
    sa := SIN(alpha_prev);

    // Ligne 0
    T[0,0] := ct;        T[0,1] := -st;       T[0,2] := 0.0;   T[0,3] := a_prev;
    // Ligne 1
    T[1,0] := st * ca;   T[1,1] := ct * ca;   T[1,2] := -sa;   T[1,3] := -d * sa;
    // Ligne 2
    T[2,0] := st * sa;   T[2,1] := ct * sa;   T[2,2] := ca;    T[2,3] := d * ca;
    // Ligne 3 (homogène)
    T[3,0] := 0.0;       T[3,1] := 0.0;       T[3,2] := 0.0;   T[3,3] := 1.0;

    MdhTransform := TRUE;
END_FUNCTION

La cinématique directe complète s'obtient ensuite comme au chapitre 3, en chaînant les i-1Ti par Mat4Mul : 0Tn = 0T1·1T2·…·n-1Tn. Seul le bloc élémentaire change entre DH et MDH ; l'ossature de chaînage est identique.

3. Le paramètre de Hayati (axes parallèles)

La MDH règle l'ambiguïté de placement, mais pas le problème des axes parallèles : c'est un défaut de la famille DH tout entière, quelle que soit sa variante. Le modèle Hayati-Roberson (1983) le corrige en remplaçant le paramètre d, pour les liaisons concernées, par un petit angle de rotation β autour de l'axe y.

liaison « normale » :  (θ, d, a, α)     ⟶      liaison « parallèle » (Hayati) :  (θ, β, a, α)

Autrement dit, on ajoute un facteur Roty(β) et on supprime Transz(d) uniquement là où deux axes sont nominalement parallèles.

3.1 Pourquoi ça marche

L'intuition tient en une phrase : on paramètre l'erreur qui peut réellement se produire. Quand deux axes sont parallèles :

En troquant un paramètre non identifiable (d) contre un paramètre identifiable (β), le modèle redevient continu et bien conditionné : petit défaut réel ⟶ petite variation de paramètre. C'est le standard de fait pour la calibration de bras à poignet ou à épaule dont les axes sont coplanaires/parallèles.

Règle mnémotechnique. Axes non parallèles ⟶ garder d. Axes (nominalement) parallèles ⟶ remplacer d par β (Hayati). On ne mélange pas : chaque liaison est soit « normale » soit « Hayati », selon la géométrie du robot réel. Le nombre total de paramètres reste 4 par liaison — la paramétrisation demeure minimale, elle change juste de nature localement.

4. Le produit d'exponentielles (POE, screw theory)

Le produit d'exponentielles (POE) adopte un point de vue radicalement différent, issu de la théorie des torseurs (screw theory, Brockett, Murray-Li-Sastry). Au lieu de placer des repères intermédiaires liaison par liaison, on décrit le mouvement de chaque axe comme un vissage (rotation + translation combinées autour d'une ligne de l'espace), exprimé une fois pour toutes dans la base.

4.1 La formule

0Tn(q) = e[S1]q1 · e[S2]q2 · … · e[Sn]qn · M

où :

Un torseur est un couple S = (ω ∈ ℝ³, v ∈ ℝ³) : ω est la direction de l'axe (unitaire pour une liaison rotoïde, nul pour une prismatique) et v le moment (v = −ω × p, où p est un point de l'axe). Six nombres au total. On lui associe la matrice [S] ∈ se(3) de l'algèbre de Lie (4×4) :

[S] = [  [ω]    v  ;   0    0  ]           avec  [ω] = [  0   −ωz   ωy  ;   ωz   0   −ωx  ;   −ωy   ωx   0  ]

et e[S]q est l'exponentielle matricielle de [S]q — une transformation homogène 4×4. Sa partie rotation se calcule par la formule de Rodrigues (pour ω unitaire) :

e[ω]θ = I + sin θ · [ω] + (1 − cos θ) · [ω]²

La partie translation fait intervenir un terme intégral analogue ; on retient surtout que tout se ramène à une matrice 4×4 une fois q connu.

4.2 Avantages et inconvénients

AvantagesInconvénients
Aucun placement de repères intermédiaire imposé : on décrit directement les axes réels. 6 paramètres par liaison (le torseur) : paramétrisation non minimale.
Paramétrisation sans singularité : résout nativement le problème des axes parallèles. Requiert l'exponentielle matricielle : plus lourd qu'une matrice DH.
Très adaptée à la calibration robuste (travaux de Chen, Okamura, He…). Formule moins « scolaire » ; sur PLC on précalcule ou on convertit en matrices.
Formulation géométrique et globale élégante (une seule vue dans la base). Les tables constructeur sont rarement fournies sous cette forme.

Le POE et la DH décrivent le même robot. En pratique, on développe et on calibre en POE (robuste), puis on convertit le résultat en une suite de matrices constantes ou en une table DH/MDH équivalente pour l'exécution embarquée. On profite ainsi du meilleur des deux mondes : robustesse hors-ligne, légèreté en ligne.

5. URDF / format xyz-rpy (écosystème ROS)

Dans l'écosystème ROS (Robot Operating System), les robots sont décrits en URDF (Unified Robot Description Format), un XML arborescent. Chaque joint relie un repère parent à un repère enfant par :

La transformation parent→enfant vaut donc Trans(xyz)·Rot(rpy)·Mouvement(q), où Rot(rpy) = Rotz(yaw)·Roty(pitch)·Rotx(roll) (convention ROS). C'est très proche d'une matrice 4×4 : facile à convertir.

AvantagesInconvénients
Format lisible et arborescent (gère les arbres, pas seulement les chaînes).Non minimal : 6 paramètres fixes par joint.
Outillage ROS massif (RViz, MoveIt, TF, simulateurs).Moins standard pour la calibration analytique que MDH/POE.
Génération directe depuis la CAO (SolidWorks, Fusion…).Le rpy peut souffrir de blocage de cardan près des pôles.

On peut convertir une ligne DH en offset xyz-rpy (et réciproquement) : il suffit de développer le produit DH en une matrice 4×4, d'en extraire la translation (xyz) et d'en déduire les angles de Cardan (rpy) par les formules d'extraction usuelles.

6. Tableau comparatif de toutes les paramétrisations

Paramétrisation Param. / liaison Axes parallèles Calibration Outillage / écosystème Coût de calcul
DH classique 4 (minimal) ❌ discontinu / mal conditionné correcte hors axes parallèles universel (tables constructeur, cours) faible (1 matrice 4×4)
MDH (Craig) 4 (minimal) ❌ même limite que DH ✅ référence académique/industrielle très répandu en calibration faible (1 matrice 4×4)
Hayati (DH/MDH + β) 4 (minimal, local) ✅ continu & bien conditionné ✅✅ pensée pour ça outils de calibration faible (1 matrice 4×4)
POE (torseurs) 6 (non minimal) ✅ sans singularité ✅✅ robuste (recherche) bibliothèques screw theory plus élevé (exp. matricielle)
URDF (xyz-rpy) 6 (non minimal) ✅ pas de perpendiculaire commune moins standard analytiquement ROS (RViz, MoveIt, CAO) faible (1 matrice 4×4)

7. Recommandation pratique

Il n'y a pas de « meilleure » convention dans l'absolu — seulement une convention adaptée à votre contexte. Une grille de décision simple :

Sur automate, tout finit en matrices 4×4. Quelle que soit la convention en amont (DH, MDH, Hayati, POE, URDF), le calcul cyclique du PLC ne manipule que des matrices homogènes i-1Ti chaînées par Mat4Mul. On réduit donc la paramétrisation amont à une suite de blocs 4×4 hors ligne (à la mise en service), puis on n'exécute en ligne que des produits de matrices — bornés et déterministes. Pour le POE, on précalcule l'exponentielle matricielle ou on convertit carrément en table DH/MDH équivalente : jamais d'exponentielle matricielle dans la tâche temps réel.

Exercices

Exercice 1 — Coder et vérifier MdhTransform

Écrivez MdhTransform (si ce n'est pas déjà fait) et vérifiez-la sur une liaison simple : αi-1 = 0, ai-1 = 0,5, θ = π/2, d = 0,2. Prédisez la matrice attendue à la main, puis comparez au résultat de la fonction.

Voir la solution

Avec α = 0 : cα = 1, sα = 0. Avec θ = π/2 : cθ = 0, sθ = 1. La matrice MDH se simplifie en :

[  0  −1   0   0,5  ;   1   0   0   0  ;   0   0   1   0,2  ;   0   0   0   1  ]
PROGRAM P_TestMdh
VAR
    T       : T_MAT4;
    ok      : BOOL := TRUE;
    PI      : LREAL := 3.14159265358979;
END_VAR

MdhTransform(alpha_prev := 0.0, a_prev := 0.5,
             theta := PI / 2.0, d := 0.2, T := T);

// Contrôles clés (tolérance sur flottants)
IF ABS(T[0,0] - 0.0)  > 1E-9 THEN ok := FALSE; END_IF
IF ABS(T[0,1] + 1.0)  > 1E-9 THEN ok := FALSE; END_IF   // -sin = -1
IF ABS(T[0,3] - 0.5)  > 1E-9 THEN ok := FALSE; END_IF   // a_prev
IF ABS(T[1,0] - 1.0)  > 1E-9 THEN ok := FALSE; END_IF   // sin = 1
IF ABS(T[2,3] - 0.2)  > 1E-9 THEN ok := FALSE; END_IF   // d * cos(alpha)
// ok = TRUE si la matrice correspond à la prédiction

En comparant à DhTransform (chapitre 3) sur les mêmes valeurs numériques, on obtient une matrice différente : la translation a n'est pas placée au même endroit. C'est la démonstration concrète que les deux conventions ne sont pas interchangeables sans reconversion de la table.

Exercice 2 — Pourquoi d n'est pas identifiable sur axes parallèles

Expliquez, sans calcul lourd, pourquoi le paramètre d devient non identifiable lorsque deux axes consécutifs sont exactement parallèles, et pourquoi le paramètre de Hayati β résout le problème.

Voir la solution

Non-identifiabilité de d. Le paramètre d fait glisser le repère le long de l'axe z. Si les axes zi-1 et zi sont exactement parallèles, la position de l'origine du repère le long de z n'est plus contrainte par la géométrie : on peut la déplacer sans que la pose de l'effecteur change. Deux valeurs de d différentes donnent donc exactement la même cinématique observable ⟶ l'identification ne peut pas trancher, la colonne correspondante du Jacobien d'identification est nulle, la matrice normale est singulière.

Pourquoi β marche. Dans la réalité, les axes ne sont jamais parfaitement parallèles : il subsiste un petit défaut d'orientation. Ce défaut, lui, est observable — il fait diverger les axes et modifie la pose de l'effecteur de façon mesurable. Le paramètre de Hayati β (petite rotation autour de y) capture précisément ce défaut. En remplaçant un paramètre non identifiable (d) par un paramètre identifiable (β), on rétablit le bon conditionnement : petit défaut réel ⟶ petite variation de paramètre, de façon continue.

Exercice 3 — Compter les paramètres POE d'un bras 6 axes

Combien de paramètres géométriques comporte le modèle POE complet d'un robot à 6 liaisons rotoïdes ? Comparez au décompte DH/MDH. Que représente le « surplus » ?

Voir la solution

POE. Chaque torseur Si compte 6 nombres (ω ∈ ℝ³ et v ∈ ℝ³). Pour 6 liaisons : 6 × 6 = 36 paramètres, plus la pose de référence M ∈ SE(3) qui en compte 6. Soit 42 nombres au total (avec des contraintes : ω unitaire pour les axes rotoïdes, v = −ω × p).

DH/MDH. 4 × 6 = 24 paramètres (minimal).

Le surplus du POE (36 vs 24, avant contraintes) tient à sa non-minimalité : les 6 nombres d'un torseur ne sont pas tous indépendants (contrainte ||ω|| = 1, moment orthogonal…). Cette redondance est le prix de la robustesse : c'est justement de ne pas forcer une paramétrisation minimale qui évite les singularités de la famille DH.

Exercice 4 — Convertir une ligne DH en offset xyz-rpy

On donne une liaison DH classique (θ = 0, d = 0,3, a = 0, α = π/2) (variable articulaire nulle, cas « au repos »). Donnez l'offset xyz et les angles rpy (roll-pitch-yaw) URDF équivalents.

Voir la solution

On développe la matrice DH classique Rotz(0)·Transz(0,3)·Transx(0)·Rotx(π/2). Avec θ = 0 : pas de rotation en z. Avec a = 0 : pas de translation en x. Il reste une translation de 0,3 le long de z et une rotation de π/2 autour de x. La matrice vaut :

[  1   0    0   0  ;   0   0  −1   0  ;   0   1    0   0,3  ;   0   0    0   1  ]

Offset xyz = colonne de translation = (0, 0, 0,3).

rpy : la rotation est Rotx(π/2), donc roll = π/2, pitch = 0, yaw = 0. En URDF : <origin xyz="0 0 0.3" rpy="1.5708 0 0"/>. Le cas général se traite en extrayant les angles de Cardan de la sous-matrice de rotation 3×3 (formules atan2 usuelles), en prenant garde au blocage de cardan quand pitch = ±π/2.

Récapitulatif