Sommaire
Je ferme les yeux et je tends le bras : je sais où est ma main sans la voir, parce que mon cerveau connaît l’angle de mon épaule et de mon coude. La cinématique directe est la notion de robotique qui permet à un robot de faire de même : connaître la position de sa main (son outil, également appelé l’organe terminal ou effecteur) à partir des angles de ses articulations. Pour un bras plan à deux articulations, deux formules suffisent, parce que dans un plan la position se résume à deux nombres, x et y.
Le point de départ
Mon objectif, à travers ces articles, est de comprendre le fonctionnement des robots. Pour y parvenir, je mets chaque concept en application par la programmation, en Python et en C++, puis je le simule sous ROS2. Si vous voulez savoir qui écrit ces lignes et d’où je viens, la page À propos vous le dira.
L’objectif de cet article est de comprendre où se trouve l’outil lorsque l’on connaît les angles du bras. C’est le sens direct. La question inverse, dans quelle posture placer le bras pour atteindre un point donné, fera l’objet du prochain article.
Ces deux questions relèvent d’une même discipline : la cinématique. Elle décrit le mouvement sans tenir compte des forces. Couple moteur et masse n’interviennent donc pas. Seuls comptent les positions, les angles et les longueurs.
On commence par le cas le plus simple : un bras plan, c’est-à-dire qui se déplace dans un seul plan, avec deux articulations. On l’appelle un 2R : deux articulations rotoïdes, c’est-à-dire qui tournent autour d’un axe. Le principe reste le même pour un bras à six axes. Deux choses changent : la quantité de calcul, et la difficulté du sens inverse. Je les explique l’une après l’autre, parce qu’elles justifient la suite de l’article.
Commençons par la quantité de calcul. Pour trouver la position de l’outil, on fait un calcul par articulation, dans l’ordre, de la base vers l’outil. Sur le bras 2R, le premier calcul utilise l’angle de l’épaule pour trouver la position du coude. Le second utilise l’angle du coude, en plus de celui de l’épaule, pour trouver la direction du second segment, c’est-à-dire de la partie rigide qui suit le coude. Il ajoute ensuite le déplacement de ce segment à la position du coude : on obtient la position de l’outil. Chacun de ces calculs s’appelle une transformation. La section 3 en donne un exemple chiffré, et la section 4 la définit précisément. Un bras à six axes demande six calculs de même nature : seul leur nombre augmente.
Reste la seconde différence. Pourquoi le sens inverse devient-il difficile ? Dans le sens direct, les angles sont connus. On les remplace dans les formules et on obtient la position. Dans le sens inverse, on part de la position, et ce sont les angles qui deviennent les inconnues. Or ils sont enfermés dans des cosinus et des sinus, et θ₁, l’angle de l’épaule, apparaît dans plusieurs termes à la fois. On ne peut donc pas les isoler par un simple calcul. Il faut résoudre un système d’équations non linéaires. Conséquence : un même point peut s’atteindre de plusieurs façons, ou pas du tout. Pour le bras 2R, un même point s’atteint en général avec deux postures différentes (section 5).
Avec six articulations, le système est bien plus grand : il peut avoir jusqu’à 16 solutions dans le cas général (Wampler et Morgan, 1991). On ne connaît de formules explicites que pour certaines géométries, par exemple lorsque trois axes consécutifs se coupent en un point (cas traité par Pieper). C’est pourquoi cet article se limite au sens direct : le sens inverse mérite le sien.

Figure 1. Le principe. Des angles mesurés en entrée, une position calculée en sortie. Le sens inverse est plus difficile : il fera l’objet du prochain article.
À la fin de cet article, on saura :
- calculer la position de l’outil à partir de deux angles ;
- vérifier le résultat par une méthode indépendante ;
- lire dans les formules la portée du robot, sa zone morte et ses postures dangereuses ;
- programmer ce calcul en Python et le tester sur l’exemple.
1. L’intuition : l’outil n’est pas mesuré, il est calculé
Je pars d’un bras fixé au mur d’un poste de travail. Deux segments rigides. Deux articulations. Chacune tourne autour d’un axe perpendiculaire au plan de la figure. Les ingénieurs appellent ce bras un 2R : deux articulations rotoïdes (R pour rotoïde).
Prenons les mots un par un. Un bras de robot, comme le mien, est une suite de segments rigides. Une articulation est l’endroit où un segment peut tourner par rapport au précédent : l’épaule et le coude chez moi, deux moteurs chez le robot. L’angle d’une articulation indique de combien elle a tourné.

Figure 2. Le robot lit ses deux angles. La position de l’outil, il la calcule.
Sur un robot industriel classique, chaque articulation possède un codeur : un capteur qui mesure l’angle de cette articulation. Ces capteurs sont déjà intégrés aux articulations. Mesurer directement la position de l’outil demanderait en plus un équipement extérieur au robot, par exemple une caméra ou un système de mesure laser. La position de l’outil n’est donc pas mesurée : elle est calculée à partir des angles.
Le corps humain fait la même chose. Un test simple : on ferme les yeux et on touche son nez. Sans la vue, aucun capteur ne donne directement la position de la main. Ce sont des capteurs situés dans les muscles, les tendons et les articulations qui renseignent le cerveau sur l’angle de l’épaule et du coude. C’est la proprioception. Le cerveau en déduit où se trouve la main. Et c’est ça, la cinématique directe, réalisée par un système nerveux.
Pour la suite, on garde un seul exemple et une seule notation.
| Symbole | Signification | Valeur dans l’exemple |
|---|---|---|
| L₁ | longueur du premier segment, de la base au coude | 0,5 m |
| L₂ | longueur du second segment, du coude à l’outil | 0,3 m |
| θ₁ | angle du premier segment par rapport à l’horizontale | 30° |
| θ₂ | angle du second segment par rapport au prolongement du premier | 45° |
| x, y | position de l’outil dans le repère de la base | à calculer |
| φ | orientation de l’outil par rapport à l’horizontale | à calculer |
Le raisonnement tient en trois idées :
- Le coude se trouve à la distance L₁ de la base, dans la direction θ₁.
- L’outil se trouve à la distance L₂ du coude. Sa direction est θ₁ + θ₂, parce que θ₂ est mesuré depuis le premier segment et non depuis le sol.
- La position de l’outil est donc la somme de ces deux déplacements.

Figure 3. Deux vecteurs mis bout à bout. En projetant chacun sur les axes, on lit directement x et y.
Une fois les angles connus, il n’existe qu’une seule position de l’outil. Ici, « position » désigne le triplet (x, y, φ) : le point où se trouve l’outil dans le plan, et la direction dans laquelle il pointe. Pourquoi une seule ? Parce que x, y et φ sont donnés par des formules explicites : pour des valeurs données de θ₁ et θ₂, une formule ne renvoie qu’un seul résultat. Il suffit donc de remplacer les angles par leurs valeurs et de calculer, sans résoudre aucune équation. Exemple : θ₁ = 30° et θ₂ = 45° donnent toujours le même point, (0,511 ; 0,540) m (section 3), quel que soit celui qui fait le calcul. C’est ce qui rend le problème direct simple, et ce qui le distingue du problème inverse (section 5), où l’on cherche les angles à partir de la position.
2. Les formules
Pour passer de l’idée aux formules, je décompose chaque déplacement en une part horizontale et une part verticale. Cette opération s’appelle projeter un vecteur sur les axes. Je la fais en quatre étapes, avec la figure 4 sous les yeux.
- Le principe, sur un seul vecteur. Un vecteur de longueur L, incliné de l’angle α par rapport à l’axe x, forme avec ses deux projections un triangle rectangle (figure 4, à gauche). Sa longueur L est l’hypoténuse. Par définition du cosinus et du sinus dans un triangle rectangle, la projection sur x (côté adjacent) vaut L cos α, et la projection sur y (côté opposé) vaut L sin α.
- Premier segment (en bleu). Il a pour longueur L₁ et il est incliné de θ₁ par rapport à l’horizontale. On applique le principe avec L = L₁ et α = θ₁ : il avance de L₁ cos θ₁ vers la droite et de L₁ sin θ₁ vers le haut. C’est le déplacement de la base au coude.
- Second segment (en rouge). Il a pour longueur L₂. Son angle par rapport à l’horizontale vaut θ₁ + θ₂, parce que θ₂ est mesuré depuis le prolongement du premier segment (section 1). On applique le même principe avec L = L₂ et α = θ₁ + θ₂ : il avance de L₂ cos(θ₁ + θ₂) vers la droite et de L₂ sin(θ₁ + θ₂) vers le haut. C’est le déplacement du coude à l’outil.
- La somme. Les deux segments sont mis bout à bout : le point d’arrivée du premier est le point de départ du second. Sur l’axe x, on parcourt donc d’abord la bande bleue (de la base au coude), puis la bande rouge (du coude à l’outil), et la position de l’outil est la somme des deux longueurs. Même raisonnement sur l’axe y. Si une projection pointe vers la gauche ou vers le bas, sa valeur est négative et elle se retranche : le signe du cosinus ou du sinus s’en charge.

Figure 4. À gauche, un vecteur et ses deux projections forment un triangle rectangle. À droite, chaque segment du bras est projeté sur les axes : les bandes bleues (premier segment) et rouges (second segment) s’ajoutent pour donner x et y.
Il ne reste qu’à écrire ces deux sommes. La position de l’outil dans le repère de la base est :
Il reste l’orientation de l’outil. C’est la somme des deux angles, pour la raison vue à l’étape 3 :
Où :
- x : position horizontale de l’outil, en mètres, mesurée depuis la base ;
- y : position verticale de l’outil, en mètres, mesurée depuis la base ;
- φ : orientation de l’outil, c’est-à-dire l’angle du second segment par rapport à l’horizontale ;
- L₁, L₂ : longueurs des deux segments, en mètres ;
- θ₁, θ₂ : angles des articulations, mesurés comme dans la figure 3 ;
- cos, sin : fonctions qui projettent une longueur sur l’axe horizontal (cos) et sur l’axe vertical (sin).
Deux de ces équations donnent la position (x et y), comme annoncé en introduction, et la troisième l’orientation. Ensemble, elles forment le modèle géométrique direct (MGD) du bras. Elles envoient l’espace des articulations (θ₁, θ₂) vers l’espace de travail (x, y, φ).
Reprenons chaque terme, pour vérifier qu’il correspond bien à une bande de la figure 4.
| Terme | Ce qu’il représente |
|---|---|
| L₁ cos θ₁ | déplacement horizontal du coude par rapport à la base |
| L₁ sin θ₁ | déplacement vertical du coude par rapport à la base |
| L₂ cos(θ₁ + θ₂) | déplacement horizontal de l’outil par rapport au coude |
| L₂ sin(θ₁ + θ₂) | déplacement vertical de l’outil par rapport au coude |
| θ₁ + θ₂ | direction du second segment, donc orientation φ de l’outil |
Pourquoi θ₁ + θ₂ et pas θ₂ seul ? Parce que chaque articulation fait tourner tout ce qui se trouve après elle. Quand l’épaule tourne de θ₁, le second segment tourne avec le premier. Le coude ajoute ensuite θ₂. Les angles s’additionnent le long de la chaîne.
Je retiens la structure : une addition, premier segment puis second segment. Elle reste aussi simple parce que le bras est plan : les angles s’additionnent et les projections s’additionnent. Avec plus d’articulations dans l’espace, ce ne sera plus aussi direct, et c’est là que la section 4 interviendra.
3. Exemples chiffrés
L’exemple de référence
Appliquons les formules de la section 2 à des valeurs concrètes. Données : L₁ = 0,5 m, L₂ = 0,3 m, θ₁ = 30°, θ₂ = 45°. On en déduit φ = θ₁ + θ₂ = 75°.
Je lis maintenant ce résultat sur la figure 5, dans l’ordre du bras, de la base vers l’outil. Chaque terme calculé plus haut est un déplacement, représenté par un trait en pointillés sur la figure.

Figure 5. Lecture pas à pas de l’exemple. Étape 1 : de la base au coude (en bleu). Étape 2 : du coude à l’outil (en rouge).
| Étape | Déplacement en x | Déplacement en y | Point atteint |
|---|---|---|---|
| Départ | — | — | base (0 ; 0) |
| 1. Base vers coude | L₁ cos θ₁ = +0,433 m | L₁ sin θ₁ = +0,250 m | coude (0,433 ; 0,250) m |
| 2. Coude vers outil | L₂ cos 75° = +0,078 m | L₂ sin 75° = +0,290 m | outil (0,511 ; 0,540) m |
Où se trouve le coude, concrètement ? Le point (0,433 ; 0,250) m est l’articulation entre les deux segments : le cercle blanc au bout du premier segment sur la figure 5. Il est à 0,433 m à droite de la base et à 0,250 m au-dessus, ce que donne un premier segment de 0,5 m incliné de 30° (le triangle bleu en pointillés).
Depuis ce coude, le second segment ajoute 0,078 m en x et 0,290 m en y (le triangle rouge en pointillés). Le déplacement en x est faible parce que ce segment est incliné de 75° : il pointe presque à la verticale, donc sa projection horizontale cos 75° ≈ 0,26 est petite, alors que sa projection verticale sin 75° ≈ 0,97 est grande. L’outil s’obtient en additionnant : x = 0,433 + 0,078 = 0,511 m et y = 0,250 + 0,290 = 0,540 m. Enfin, l’orientation φ = 75° est l’angle du second segment par rapport à l’horizontale, c’est-à-dire 30° + 45° (arc rouge de la figure).
Reste à savoir si ce résultat est juste. Un calcul de cinématique contient facilement une erreur de signe ou de convention d’angle (voir la section 6). Un contrôle par une méthode indépendante la détecte. Voici celui de la loi des cosinus, dans le triangle formé par la base, le coude et l’outil :
Où r est la distance entre la base et l’outil. Le terme L₁² + L₂² serait le carré de l’hypoténuse si le coude formait un angle droit. Le terme 2 L₁ L₂ cos θ₂ corrige cet écart selon la pliure du coude. Le signe plus vient de l’angle intérieur du triangle, 180° − θ₂, dont le cosinus vaut −cos θ₂.
On trouve r ≈ 0,743 m. Avec les coordonnées du calcul précédent : √(0,511² + 0,540²) ≈ 0,743 m. Les deux méthodes concordent.
Trois postures pour sentir les formules
Un seul exemple ne suffit pas pour sentir les formules. Je fais donc varier les angles sur trois postures remarquables.

Figure 6. Trois postures du même bras, calculées avec les mêmes formules.
| Posture | θ₁ | θ₂ | x (m) | y (m) | r (m) |
|---|---|---|---|---|---|
| A. Bras tendu | 45° | 0° | 0,566 | 0,566 | 0,800 |
| B. Bras en L | 90° | −90° | 0,300 | 0,500 | 0,583 |
| C. Bras replié | 0° | 150° | 0,240 | 0,150 | 0,283 |
Que lit-on dans ces trois résultats ?
- A : les deux segments sont alignés. La distance atteint son maximum, r = L₁ + L₂ = 0,8 m.
- B : θ₂ est négatif. Le coude plie dans l’autre sens. Le premier segment est vertical, le second horizontal. On lit x = L₂ = 0,3 m et y = L₁ = 0,5 m sans aucun calcul.
- C : le second segment revient vers la base. L’outil se rapproche. Il est à 0,283 m, proche de la limite basse de 0,2 m.
À nous de jouer
Entraînons-nous sur un coude plié dans l’autre sens : calculons la position de l’outil pour θ₁ = 120° et θ₂ = −60°. On commence par φ.
Réponse. φ = 120° − 60° = 60°. Puis x = 0,5 cos 120° + 0,3 cos 60° = −0,250 + 0,150 = −0,100 m. Et y = 0,5 sin 120° + 0,3 sin 60° = 0,433 + 0,260 = 0,693 m. L’outil est à 10 cm à gauche de la base, à 0,693 m de hauteur. Contrôle : r = √(0,100² + 0,693²) = 0,700 m, et la loi des cosinus donne 0,25 + 0,09 + 0,30 × cos(−60°) = 0,49 m², soit r = 0,7 m.
4. La méthode générale : repères et convention de Denavit-Hartenberg
Les formules de la section 2 fonctionnent, mais elles reposent sur une géométrie propre au plan. La géométrie suffit pour deux segments, parce que tous les axes de rotation sont parallèles : tout se passe dans un plan et les angles s’additionnent. Avec six articulations dans l’espace, ce n’est plus vrai. Les axes pointent dans des directions différentes, il faut projeter sur trois axes, et les rotations dans l’espace ne s’additionnent plus par simple somme d’angles : l’ordre dans lequel on les applique change le résultat. Écrire ces enchaînements à la main devient long et source d’erreurs. Il faut une méthode qui marche toujours, de façon mécanique. En 1955, Jacques Denavit et Richard Hartenberg en ont proposé une. L’idée : attacher un repère à chaque segment, puis décrire le passage d’un repère au suivant avec quatre paramètres seulement.

Figure 7. Un repère par articulation. L’axe x de chaque repère suit son segment. L’axe z sort du plan.
Les quatre paramètres, et leur valeur pour le bras 2R :
| Paramètre | Définition | Bras 2R |
|---|---|---|
| aᵢ | distance entre les axes zᵢ₋₁ et zᵢ, mesurée le long de xᵢ | Lᵢ |
| αᵢ | angle entre zᵢ₋₁ et zᵢ, mesuré autour de xᵢ | 0° |
| dᵢ | déplacement le long de zᵢ₋₁ | 0 |
| θᵢ | rotation autour de zᵢ₋₁, de xᵢ₋₁ vers xᵢ | θ₁, θ₂ (variables) |
Les deux axes de rotation sont parallèles : α = 0. Les deux segments sont dans le même plan : d = 0. Seuls les angles θ varient, puisque les deux articulations sont rotoïdes.
La matrice qui fait passer du repère i−1 au repère i s’écrit :
Où :
- Aᵢ : matrice 4 × 4 qui décrit la position et l’orientation du repère i dans le repère i−1 ;
- le bloc 3 × 3 en haut à gauche : la rotation du repère i par rapport au repère i−1 ;
- la dernière colonne (aᵢ cos θᵢ, aᵢ sin θᵢ, dᵢ) : la position de l’origine du repère i, vue depuis le repère i−1 ;
- la dernière ligne (0, 0, 0, 1) : la convention des coordonnées homogènes, qui range rotation et translation dans une seule matrice.
Avec α = 0 et d = 0, la matrice se simplifie. Il reste une rotation d’angle θᵢ suivie d’une translation de Lᵢ le long du segment :
La pose de l’outil est le produit des deux matrices. On note c₁ = cos θ₁, s₁ = sin θ₁, c₁₂ = cos(θ₁ + θ₂) et s₁₂ = sin(θ₁ + θ₂) :
Où T₀² est la pose du repère de l’outil (repère 2) dans le repère de la base (repère 0). Une pose rassemble une position et une orientation. Sa dernière colonne contient x, y et z = 0, puisque tout reste dans le plan. Son bloc de rotation est une rotation d’angle θ₁ + θ₂, donc φ.
Pour comprendre ce que fait ce produit, je le calcule avec les valeurs de l’exemple (L₁ = 0,5 m, θ₁ = 30°, L₂ = 0,3 m, θ₂ = 45°) :
La dernière colonne de A₁, (0,433 ; 0,250), est la position du coude : (L₁ cos θ₁, L₁ sin θ₁). Celle de A₂, (0,212 ; 0,212), est le segment 2 exprimé dans le repère du coude : (L₂ cos 45°, L₂ sin 45°). Dans le produit, ce vecteur est d’abord tourné de 30° par A₁, pour le remettre dans le repère de la base, puis ajouté à la position du coude : (0,866 × 0,212 − 0,500 × 0,212 + 0,433 ; 0,500 × 0,212 + 0,866 × 0,212 + 0,250) = (0,511 ; 0,540). La multiplication fait donc exactement le trajet de la figure 8 : on arrive au coude, puis on avance le long du second segment.

Figure 8. Le produit lu comme un trajet. A₁ amène du repère 0 au repère 1, A₂ du repère 1 au repère 2, et T₀² = A₁A₂ va directement du repère 0 au repère 2.
L’ordre des matrices compte. On lit T₀² = A₁A₂ dans l’ordre de la chaîne : d’abord le premier segment, puis le second. Inverser l’ordre donne un autre point : A₂A₁ placerait l’outil en (0,342 ; 0,695) m, à environ 23 cm du bon résultat.
La dernière colonne redonne exactement les formules de la section 2. Avec les valeurs de l’exemple, elle vaut (0,511 ; 0,540 ; 0) m : les deux méthodes concordent. Ici, DH ne produit rien de nouveau, puisque la géométrie suffisait. Son intérêt est ailleurs : elle se généralise. Pour six articulations, on multiplie six matrices au lieu de deux (figure 9) :
Où T₀⁶ est la pose de l’outil (repère 6) dans le repère de la base (repère 0), et chaque Aᵢ est construite avec les quatre paramètres du tableau ci-dessus. Ces matrices sont plus remplies que dans le cas plan, puisque α et d ne sont plus nuls, mais le principe est identique : une matrice par articulation, multipliées dans l’ordre de la chaîne. C’est ce que programme le script de la section 7.

Figure 9. Le même principe avec deux ou six articulations : une matrice par articulation, multipliées dans l’ordre de la chaîne.
5. Ce que les formules disent du robot
Le calcul est établi et vérifié. Reste à savoir ce que les formules disent du robot. Elles ne servent pas seulement à calculer un point. Elles décrivent le robot. Trois choses s’y lisent : sa portée, ses postures dangereuses, et l’ambiguïté du chemin inverse.
La portée : une couronne
La distance r entre la base et l’outil ne dépend que de θ₂ (formule du contrôle, section 3). Elle est maximale bras tendu, minimale bras replié :
Où r est la distance base-outil, L₁ + L₂ la portée maximale (bras tendu, θ₂ = 0°) et |L₁ − L₂| la distance minimale (bras replié, θ₂ = 180°).

Figure 10. L’outil atteint toute la couronne entre 0,2 m et 0,8 m. Il n’atteint rien à l’intérieur du disque central, ni au-delà du cercle extérieur. Articulations supposées sans butée.
Le disque central n’est pas un défaut de réglage : c’est une contrainte géométrique. Pourquoi ? Quand le bras est entièrement replié (θ₂ = 180°), le second segment revient sur le premier. L’outil se trouve alors à la distance |L₁ − L₂| = |0,5 − 0,3| = 0,2 m de la base. Il ne peut pas se rapprocher davantage : les deux segments et la droite base-outil forment un triangle, et un côté d’un triangle ne peut pas être plus petit que la différence des deux autres (inégalité triangulaire). Pour la même raison, il ne peut pas s’éloigner au-delà de L₁ + L₂ = 0,8 m.
Cela donne un test très simple, à faire avant de chercher une posture. Je calcule la distance r = √(x² + y²) entre la base et le point visé (x et y sont les coordonnées du point dans le repère de la base), puis je la compare à 0,2 m et à 0,8 m. Exemple : le point (0,10 ; 0,12) m est à r ≈ 0,156 m, soit moins de 0,2 m : aucune combinaison d’angles ne l’atteint, il est inutile de chercher. Le point (0,60 ; 0,40) m est à r ≈ 0,721 m, entre 0,2 m et 0,8 m : il peut être atteint. Ce test ne coûte qu’un calcul de distance, alors que chercher les angles est un calcul bien plus long, qui échouerait de toute façon pour le premier point.
Sur un vrai robot, la zone atteignable est encore plus petite que la couronne : les butées des articulations interdisent une partie des angles.
Les singularités : là où le robot perd la main
Après la portée, passons aux vitesses. La cinématique ne donne pas que des positions. Elle relie aussi les vitesses :
Où :
- ẋ, ẏ : vitesses de l’outil selon x et y, en m/s ;
- θ̇₁, θ̇₂ : vitesses de rotation des deux articulations, en rad/s ;
- J : la jacobienne, matrice 2 × 2 qui convertit des vitesses articulaires en vitesse d’outil ;
- sa première colonne : l’effet d’une rotation de l’épaule seule sur l’outil ;
- sa seconde colonne : l’effet d’une rotation du coude seul sur l’outil.
Le déterminant de J se simplifie beaucoup :
Où det J mesure « l’épaisseur » de la correspondance entre vitesses articulaires et vitesses d’outil. Quand il tombe à zéro, la correspondance s’écrase : des mouvements de l’outil deviennent impossibles.

Figure 11. |det J| en fonction de θ₂. Il s’annule à 0° (bras tendu) et à ±180° (bras replié). Il est maximal à ±90°.
Lecture physique. Tendons le bras à l’horizontale. On essaie d’allonger la main sans changer de posture : c’est impossible, parce que les deux segments sont déjà alignés et que la distance base-outil vaut déjà son maximum, L₁ + L₂. L’outil ne peut plus s’éloigner de la base, quoi que fassent les moteurs, puisque le bras ne peut pas s’allonger. Le robot a perdu un degré de liberté dans cette direction : c’est ce que traduit det J = 0. Bras replié, c’est l’inverse : l’outil ne peut plus se rapprocher de la base. Dans les deux cas, c’est une singularité.
Les chiffres montrent le danger avant même d’y arriver. Pour θ₂ = 45°, det J = 0,106 m². Pour θ₂ = 90°, 0,150 m². Pour θ₂ = 5°, seulement 0,013 m².
Pourquoi est-ce un problème ? Pour imposer une vitesse à l’outil, le contrôleur doit calculer les vitesses des articulations avec la relation inverse :
Où θ̇₁, θ̇₂, ẋ et ẏ sont définis comme plus haut, J⁻¹ est la matrice inverse de J, et 1/det J est le facteur commun à tous ses termes. Quand le det J tend vers 0, ce facteur tend vers l’infini, tandis que les autres termes restent bornés (ils ne dépassent pas L₁ + L₂). À θ₂ = 5°, 1/det J vaut environ 76 m⁻², contre 9,4 m⁻² à θ₂ = 45° : ce facteur est huit fois plus grand. Pour la même vitesse d’outil, les moteurs doivent donc tourner beaucoup plus vite près de la singularité. D’où l’intérêt de planifier les trajectoires loin de ces postures.
Direct contre inverse : pourquoi le sens inverse est plus délicat
Dans le sens direct, un jeu d’angles donne une seule position. Le sens inverse n’a pas cette propriété. C’est ce que j’annonçais en introduction : dans ce sens, les angles sont les inconnues.

Figure 12. Un même point, deux postures. Le bras plie le coude vers le bas ou vers le haut.
Pour atteindre (0,511 ; 0,540) m, deux postures conviennent : θ₁ = 30,0° et θ₂ = +45,0° (coude bas), ou θ₁ = 63,2° et θ₂ = −45,0° (coude haut).
Pourquoi deux ? La loi des cosinus de la section 3 donne déjà une piste. Elle relie la distance r au seul angle θ₂, et on peut la retourner :
Où r est la distance base-outil, L₁ et L₂ les longueurs des segments, et θ₂ l’angle du coude. Avec r² = 0,552 m², L₁² = 0,25 m², L₂² = 0,09 m² et 2 L₁ L₂ = 0,30 m², on trouve cos θ₂ = (0,552 − 0,34) / 0,30 ≈ 0,707. Or deux angles ont le même cosinus : +45° et −45°. Ce « plus ou moins » est l’origine des deux postures. Le coude peut se placer de part et d’autre de la droite qui joint la base à l’outil, et les deux triangles obtenus sont symétriques. Une fois θ₂ choisi, θ₁ s’en déduit.
Pourquoi aucune solution hors de la couronne ? Parce que la formule demanderait un cosinus supérieur à 1 (si r > L₁ + L₂) ou inférieur à −1 (si r < |L₁ − L₂|), ce qu’aucun angle ne produit. Exemple : pour r = 0,9 m, cos θ₂ = (0,81 − 0,34) / 0,30 ≈ 1,57.
Pourquoi une seule solution sur le cercle extérieur ou intérieur ? Parce que cos θ₂ vaut alors +1 ou −1, et que +θ₂ et −θ₂ sont le même angle (0° ou 180°) : les deux positions du coude se confondent. Le calcul complet de θ₁ et θ₂ est le sujet du prochain article.
6. Les erreurs classiques
Le calcul lui-même est court : quelques lignes de trigonométrie, sans étape cachée. Les erreurs ne viennent donc pas de la difficulté du calcul, mais de choix que les formules ne montrent pas : depuis où on mesure un angle, dans quelle unité, avec quelle convention de repères. Pourquoi ces choix piègent-ils ? Parce qu’ils restent implicites : une formule recopiée sans ses conventions a l’air juste, et donne pourtant un autre point. Voici trois pièges, chiffrés avec l’exemple de référence.
1. Angle relatif ou angle absolu
Le θ₂ de cet article est relatif : il se mesure depuis le prolongement du premier segment. Si on le lit depuis l’horizontale, la formule donne un autre point.

Figure 13. Le même chiffre, 45°, lu de deux façons. L’outil se retrouve en (0,645 ; 0,462) m au lieu de (0,511 ; 0,540) m.
Écart : 15,5 cm, soit plus de la moitié de L₂ (0,3 m). À cette distance, l’outil ne touche pas la cible visée. Avant tout calcul, je note donc comment chaque angle est mesuré.
2. Degrés ou radians
Une calculatrice réglée en radians lit cos(30) comme cos(30 rad). Or 30 rad valent environ 1 719°, soit un angle équivalent à 279° : le cosinus vaut alors 0,154, au lieu de cos(30°) = 0,866. Avec θ₁ = 30 et θ₂ = 45 lus comme des radians, l’outil se retrouve en (0,354 ; −0,610) m au lieu de (0,511 ; 0,540) m. Le signe de y est faux : le bras est censé monter, il descend. Un signe aberrant se repère d’un coup d’œil, sans refaire le calcul : c’est un bon test de vraisemblance. Je vérifie donc le mode de la calculatrice avant le premier calcul.
3. Deux conventions DH
Deux conventions coexistent. La convention standard, celle de Denavit et Hartenberg, est utilisée ici. La convention modifiée est dite de Craig. Elles ne placent pas les repères intermédiaires au même endroit : les tableaux de paramètres diffèrent donc, et les matrices aussi. La pose de l’outil, elle, est la même si la convention est appliquée correctement, car les deux décrivent le même robot physique. Le piège : comparer deux tableaux issus de conventions différentes et croire à une erreur. Je vérifie donc laquelle utilise le document que je lis.
Trois contrôles pour s’en protéger
- La loi des cosinus : r² = L₁² + L₂² + 2 L₁ L₂ cos θ₂ doit redonner x² + y².
- La couronne : r doit rester entre |L₁ − L₂| et L₁ + L₂.
- Les cas limites : bras tendu (θ₂ = 0°), la position doit valoir (L₁ + L₂) dans la direction θ₁.
7. Passer au code : le modèle géométrique direct en Python
Comprendre une formule et la programmer sont deux choses différentes. Programmer oblige à trancher tout ce que la formule laisse implicite : l’unité des angles, l’ordre des opérations, le format du résultat. C’est aussi la suite logique des sections précédentes, puisque l’objectif de ces articles est de mettre les concepts en application. Je transcris donc le calcul dans un script Python et je le fais vérifier de plusieurs façons : par la loi des cosinus, par la méthode DH, puis sur les trois postures.
Pourquoi NumPy ? Parce que ses fonctions cos et sin, et son produit de matrices (l’opérateur @), correspondent directement aux formules de l’article. Il faut Python 3 et NumPy (pip install numpy). Pour exécuter le script : l’enregistrer sous Windows : python mgd_2r.py, puis lancer python3 mgd_2r.py dans un terminal.
"""Modèle géométrique direct (MGD) du bras plan 2R.
Article MathaScience :
« Où est la main du robot ? La cinématique directe d'un bras plan 2R ».
Exécution : python3 mgd_2r.py (nécessite NumPy : pip install numpy)
"""
import numpy as np
L1, L2 = 0.5, 0.3 # longueurs des segments, en mètres
def mgd(theta1_deg, theta2_deg, l1=L1, l2=L2):
"""MGD par projection (section 2).
Retourne coude, outil et phi (en degrés)."""
t1 = np.radians(theta1_deg) # NumPy calcule en radians : on convertit
t2 = np.radians(theta2_deg)
coude = np.array([l1 * np.cos(t1), l1 * np.sin(t1)])
outil = coude + np.array([l2 * np.cos(t1 + t2), l2 * np.sin(t1 + t2)])
return coude, outil, theta1_deg + theta2_deg
def matrice_dh(theta_deg, longueur):
"""Matrice A_i (4x4) du bras plan : alpha = 0 et d = 0 (section 4)."""
t = np.radians(theta_deg)
c, s = np.cos(t), np.sin(t)
return np.array([[c, -s, 0, longueur * c],
[s, c, 0, longueur * s],
[0, 0, 1, 0],
[0, 0, 0, 1]])
def mgd_dh(angles_deg, longueurs):
"""Produit A1 A2 ... An.
Le même code vaut pour 2 ou pour n articulations planes."""
T = np.eye(4)
for theta, longueur in zip(angles_deg, longueurs):
T = T @ matrice_dh(theta, longueur)
return T
def det_jacobienne(theta2_deg, l1=L1, l2=L2):
"""det J = L1 L2 sin(theta2) : s'annule aux singularités (section 5)."""
return l1 * l2 * np.sin(np.radians(theta2_deg))
def main():
print("1. Exemple de référence : theta1 = 30°, theta2 = 45°")
coude, outil, phi = mgd(30, 45)
print(f" coude = ({coude[0]:.3f} ; {coude[1]:.3f}) m")
print(f" outil = ({outil[0]:.3f} ; {outil[1]:.3f}) m, phi = {phi:.0f}°")
print("\n2. Contrôle par la loi des cosinus")
r2_cosinus = L1**2 + L2**2 + 2 * L1 * L2 * np.cos(np.radians(45))
r2_coord = outil @ outil # x² + y²
print(f" r² (loi des cosinus) = {r2_cosinus:.4f} m²")
print(f" r² (x² + y²) = {r2_coord:.4f} m²")
assert np.isclose(r2_cosinus, r2_coord)
print("\n3. Même calcul par Denavit-Hartenberg (produit de matrices)")
T = mgd_dh([30, 45], [L1, L2])
x, y, z = T[0, 3], T[1, 3], T[2, 3]
print(f" dernière colonne de T = ({x:.3f} ; {y:.3f} ; {z:.0f}) m")
assert np.allclose(T[:2, 3], outil)
print("\n4. Trois postures")
postures = (("A. tendu", 45, 0), ("B. en L", 90, -90),
("C. replié", 0, 150))
for nom, t1, t2 in postures:
_, p, _ = mgd(t1, t2)
r = np.hypot(*p)
print(f" {nom:<10} theta = ({t1:>3}°, {t2:>4}°) -> "
f"x = {p[0]:.3f}, y = {p[1]:.3f}, r = {r:.3f} m")
print("\n5. Piège n°2 : degrés lus comme des radians")
x_faux = L1 * np.cos(30) + L2 * np.cos(30 + 45)
y_faux = L1 * np.sin(30) + L2 * np.sin(30 + 45)
print(f" outil faux = ({x_faux:.3f} ; {y_faux:.3f}) m "
f"au lieu de ({outil[0]:.3f} ; {outil[1]:.3f}) m")
print("\n6. Singularités : det J = L1 L2 sin(theta2)")
for t2 in (5, 45, 90):
print(f" theta2 = {t2:>2}° -> det J = {det_jacobienne(t2):.3f} m²")
print("\n7. Ordre des matrices : A1 A2 n'est pas A2 A1")
T_a2a1 = matrice_dh(45, L2) @ matrice_dh(30, L1)
print(f" A2 A1 donnerait ({T_a2a1[0, 3]:.3f} ; {T_a2a1[1, 3]:.3f}) m "
": un autre point")
print("\nTous les contrôles sont passés.")
if __name__ == "__main__":
main()
Le code exécuté donne :

1. Exemple de référence : theta1 = 30°, theta2 = 45°
coude = (0.433 ; 0.250) m
outil = (0.511 ; 0.540) m, phi = 75°
2. Contrôle par la loi des cosinus
r² (loi des cosinus) = 0.5521 m²
r² (x² + y²) = 0.5521 m²
3. Même calcul par Denavit-Hartenberg (produit de matrices)
dernière colonne de T = (0.511 ; 0.540 ; 0) m
4. Trois postures
A. tendu theta = ( 45°, 0°) -> x = 0.566, y = 0.566, r = 0.800 m
B. en L theta = ( 90°, -90°) -> x = 0.300, y = 0.500, r = 0.583 m
C. replié theta = ( 0°, 150°) -> x = 0.240, y = 0.150, r = 0.283 m
5. Piège n°2 : degrés lus comme des radians
outil faux = (0.354 ; -0.610) m au lieu de (0.511 ; 0.540) m
6. Singularités : det J = L1 L2 sin(theta2)
theta2 = 5° -> det J = 0.013 m²
theta2 = 45° -> det J = 0.106 m²
theta2 = 90° -> det J = 0.150 m²
7. Ordre des matrices : A1 A2 n'est pas A2 A1
A2 A1 donnerait (0.342 ; 0.695) m : un autre point
Tous les contrôles sont passés.
Comment lire le script
- mgd transcrit les formules de la section 2. L’appel np.radians convertit les degrés en radians, parce que NumPy attend des radians : c’est exactement le piège n°2 de la section 6, que le bloc 5 du script reproduit volontairement.
- matrice_dh et mgd_dh appliquent la méthode DH de la section 4. La boucle de mgd_dh multiplie les matrices dans l’ordre de la chaîne : le même code vaut pour deux ou pour six articulations planes, ce qui illustre la généralisation de la figure 9.
- det_jacobienne calcule le déterminant de la section 5.
- main enchaîne sept vérifications. Les lignes assert arrêtent le script avec une erreur si deux méthodes ne concordent pas : le script se contrôle lui-même.
Ce que le terminal doit afficher
Python affiche des points décimaux là où l’article écrit des virgules. Les valeurs, elles, doivent être identiques à celles des sections précédentes.
| Bloc du script | Valeur attendue | Où la retrouver |
|---|---|---|
| 1. Exemple de référence | coude (0,433 ; 0,250) m, outil (0,511 ; 0,540) m, φ = 75° | section 3 |
| 2. Loi des cosinus | r² = 0,5521 m² des deux côtés | section 3 |
| 3. Denavit-Hartenberg | dernière colonne (0,511 ; 0,540 ; 0) m | section 4 |
| 4. Trois postures | A (0,566 ; 0,566), B (0,300 ; 0,500), C (0,240 ; 0,150) | section 3 |
| 5. Degrés lus comme radians | (0,354 ; −0,610) m, faux | section 6 |
| 6. Singularités | det J = 0,013 ; 0,106 ; 0,150 m² | section 5 |
| 7. Ordre des matrices | (0,342 ; 0,695) m avec A₂A₁, à environ 23 cm du bon point | section 4 |
Le script se termine par la ligne « Tous les contrôles sont passés. ». S’il affiche une erreur AssertionError à la place, c’est qu’une des deux méthodes ne concorde plus avec l’autre : le bug est dans la partie modifiée en dernier.
Ce script est la base de la suite : le même modèle sera réécrit en C++, puis simulé sous ROS2, comme annoncé dans l’introduction.
À retenir et à faire soi-même
À retenir
- Un robot mesure des angles. La position de l’outil se calcule.
- Pour le bras 2R : x = L₁ cos θ₁ + L₂ cos(θ₁ + θ₂), y = L₁ sin θ₁ + L₂ sin(θ₁ + θ₂), φ = θ₁ + θ₂.
- Les angles s’additionnent le long de la chaîne.
- Les formules révèlent la portée (ici de 0,2 m à 0,8 m) et les singularités (θ₂ = 0° ou 180°).
- Le sens direct donne une seule réponse. Le sens inverse en donne zéro, une ou deux.
- Je contrôle toujours : loi des cosinus, couronne, mode degrés ou radians.
- Un script Python de quelques lignes reproduit ce calcul, et ses assert le vérifient automatiquement (section 7).
Pourquoi la précision des angles compte
Ce que le robot exécute, ce sont des consignes d’angles. Chaque articulation reçoit un angle à atteindre, et ses moteurs l’amènent là en s’appuyant sur le codeur qui mesure l’angle réel. Même quand on programme une position de l’outil, le contrôleur la convertit d’abord en angles (c’est la cinématique inverse, prochain article). Le robot ne cherche pas à deviner l’intention de celui qui a écrit la consigne. La position de l’outil n’est qu’une conséquence géométrique de ces angles, celle que donnent les formules de la section 2.
Deux conséquences, chiffrées avec l’exemple de référence (outil à r = 0,743 m de la base).
- Une erreur de consigne est exécutée telle quelle. Reprenons la figure 13. Supposons que j’attende l’outil en (0,645 ; 0,462) m parce que j’ai lu θ₂ depuis l’horizontale. Le robot applique 45° relatifs : l’outil arrive en (0,511 ; 0,540) m, à 15,5 cm de mon attente. Aucun message d’erreur, puisque la consigne a été exécutée correctement.
- Une même erreur angulaire n’a pas le même effet selon l’articulation. Un petit angle Δθ, en radians, déplace un point situé à la distance ρ du centre de rotation d’une longueur ρ × Δθ. Une erreur de 1° vaut Δθ = π/180 ≈ 0,01745 rad. Si θ₁ est faux de 1°, tout le bras tourne autour de la base : ρ = r = 0,743 m, d’où un déplacement de l’outil d’environ 1,30 cm. Si θ₂ est faux de 1°, seul le second segment tourne autour du coude : ρ = L₂ = 0,3 m, d’où environ 0,52 cm. Plus le bras de levier est long, plus l’erreur angulaire est amplifiée.
La cinématique directe permet donc de savoir, avant d’envoyer la consigne, où l’outil va réellement arriver, et avec quelle sensibilité aux erreurs d’angle.
Et si on refaisait l’exemple sur papier ? (30 minutes)
Prenons une feuille, une règle et un rapporteur. L’idée est de retrouver à la main ce que le script de la section 7 calcule.
- Dessinons le bras à l’échelle 1:10 : un segment de 5 cm, un segment de 3 cm.
- Avec un rapporteur, plaçons θ₁ = 30°, puis θ₂ = 45° depuis le prolongement du premier segment.
- Mesurons x et y à la règle. On doit trouver environ 5,1 cm et 5,4 cm, soit 0,511 m et 0,540 m à l’échelle réelle.
- Recommençons en mesurant θ₂ depuis l’horizontale, puis mesurons l’écart entre les deux outils : environ 1,55 cm, soit les 15,5 cm de la figure 13.
Pourquoi cet exercice ? Mesurer à la règle oblige à décider où se place l’angle θ₂, ce qui est exactement l’ambiguïté de l’erreur n° 1. Pour juger notre mesure, prévoyons une tolérance : une erreur de lecture d’un degré au rapporteur sur θ₁ déplace l’outil de 1,3 mm sur le dessin (1,3 cm à l’échelle réelle, comme calculé plus haut). Si nos mesures concordent avec 5,1 cm et 5,4 cm à 2 ou 3 mm près, la convention d’angle est acquise.
La suite
Prochain article : la cinématique inverse du bras 2R. Même bras, question inversée. Quels angles pour atteindre ce point ? Deux solutions, une zone morte au centre, et une première rencontre concrète avec les singularités. Côté programmation, le même calcul sera ensuite écrit en C++, puis simulé sous ROS2, comme annoncé dans l’introduction.
Sources
- J. Denavit, R. S. Hartenberg, « A Kinematic Notation for Lower-Pair Mechanisms Based on Matrices », Journal of Applied Mechanics, vol. 22, n° 2, 1955, p. 215-221, DOI 10.1115/1.4011045. Notice relevée sur la page de Jacques Denavit.
- K. M. Lynch, F. C. Park, Modern Robotics: Mechanics, Planning, and Control, Cambridge University Press, 2017. Prépublication gratuite sur la page Modern Robotics de Northwestern.
- M. W. Spong, S. Hutchinson, M. Vidyasagar, Robot Modeling and Control, 2e éd., Wiley, 2020, ISBN 978-1-119-52399-4. Fiche Wiley.
- J. J. Craig, Introduction to Robotics: Mechanics and Control, 4e éd., Pearson. Ouvrage de référence pour la convention DH modifiée. Fiche Pearson.
- C. W. Wampler, A. P. Morgan, « Solving the 6R inverse position problem using a generic-case solution methodology », Mechanism and Machine Theory, vol. 26, n° 1, 1991, p. 91-106. Préversion. Cité pour le nombre maximal de solutions de la cinématique inverse d’un bras à six articulations.