🎯 Filtre de Kalman · fondements théoriques

Chapitre 15 · Application
Caméra lente + cinématique robot : choisir le repère d'état

Le choix qui compte le plus. Une caméra eye-in-hand (montée sur l'effecteur) envoie la pose d'une cible — de loin en loin, sans se caler sur l'OB de régulation. On dispose en revanche, à chaque cycle, de la pose et de la vitesse cartésiennes de l'effecteur (cinématique directe + Jacobien, calibrés). But : sortir une estimation de la cible à chaque cycle. Avant tout code, une décision domine toutes les autres : dans quel repère mettre l'état ?

Objectifs du chapitre

1. Le faux réflexe : filtrer le relatif

La caméra sort une pose relative (cible vue depuis l'effecteur). Le réflexe est de filtrer cette pose relative directement. C'est le piège. Cette pose relative varie vite — mais son mouvement rapide vient à 99 % de l'effecteur lui-même, dont on connaît exactement le déplacement (CD + Jacobien). Filtrer le relatif, c'est demander au filtre d'absorber, via un gros Q, un mouvement qu'on connaît déjà parfaitement : filtre nerveux, en retard, et bruité pour rien.

Règle d'or de la fusion : ne filtre jamais ce que tu connais déjà. Le mouvement de l'effecteur est connu — il doit sortir du filtre et devenir une transformation déterministe. Ce qui reste à estimer, c'est seulement la partie inconnue : où est la cible.

2. Le principe : estimer là où l'inconnu est lent

La même cible a deux dynamiques opposées selon le repère où on la regarde.

Position X de la cible en fonction du temps, deux courbes. En vert, la cible exprimée en repère base : une ligne quasi horizontale, lente et lisse (autour de 1,6 m). En bleu, la même cible exprimée en repère effecteur (ce que voit la caméra) : une oscillation rapide de grande amplitude entre 0,7 et 2,1 m, dominée par le mouvement du robot.
Figure 15.1. Une seule cible, deux dynamiques. En repère base (vert), elle est lente (elle bouge peu) → bruit de process Q minuscule. En repère effecteur (bleu, ce que voit la caméra), elle est rapide — dominée par le mouvement du robot. On veut estimer là où l'inconnu est lent : le repère base.

D'où la décision : l'état est la pose de la cible dans le repère base (stabilisé, fixe). Comme la cible y est lente — c'est votre hypothèse « dynamique cible faible devant celle du système » — un modèle à vitesse constante avec un tout petit Q suffit, et le filtre reste serré même entre deux images éloignées.

x = [ X , Y , Z , ψ , Vx , Vy , Vz ]ᵀ   (pose cible + vitesse lente, repère base)

3. La structure : la cinématique en transformation déterministe

La cinématique effecteur (connue chaque cycle) intervient à deux endroits, en entrée et en sortie du filtre — jamais dedans.

Schéma. Dans un OB cyclique rapide, un KF linéaire dont l'état est la pose cible en repère base. En entrée, la caméra asynchrone passe par un bloc déprojection z_base avant de corriger le KF. Le bloc CD+Jacobien fournit p_eff, v_eff, θ, ω chaque cycle : la pose à l'instant de capture alimente la déprojection, et la pose courante alimente un bloc recomposition en sortie qui produit p_rel et v_rel (avec le terme −ω×p_rel) pour la régulation. Un buffer horodaté des poses effecteur permet d'associer chaque image à la pose à l'instant de capture malgré la latence.
Figure 15.2. La cinématique effecteur (CD + Jacobien) n'est pas filtrée : elle sert de transformation connue. En entrée, la déprojection ramène l'image dans le repère base avec la pose effecteur à l'instant de capture. En sortie, la recomposition renvoie la pose relative (et sa vitesse) à la régulation, à chaque cycle. Le KF, au milieu, ne fait qu'estimer une cible lente.

Point capital : comme la pose de l'effecteur (y compris son orientation R_eff) est connue et calibrée, ces transformations sont linéaires. La mesure caméra, ramenée en base, devient une mesure directe de la pose cible (H = I). Pas besoin d'EKF ici — un filtre de Kalman linéaire suffit (contrairement au chapitre 14, où l'angle inconnu était dans l'état).

4. Déprojection & latence : le buffer horodaté

À l'arrivée d'une image, on ramène la mesure relative z_rel dans le repère base en la composant avec la pose effecteur à l'instant de la prise de vue t_c :

z_base = p_eff(t_c) + R_eff(t_c) · z_rel
R_base = R_eff(t_c) · R_cam · R_eff(t_c)ᵀ   (covariance transportée — le « sandwich », chapitre 2)

La caméra n'étant pas synchrone et présentant une latence, t_c n'est pas « maintenant ». On garde donc un buffer horodaté des poses effecteur (on les a à chaque cycle) et on y relit p_eff(t_c), R_eff(t_c). Comme la cible est lente en base, appliquer cette correction (légèrement datée) sur l'estimé courant n'introduit qu'une erreur bornée par vitesse_cible × latence — négligeable ici. Le pas de temps entre corrections étant irrégulier, on recalcule Q(dt) à chaque prédiction (chapitre 13, §6.1) : c'est un filtre complet, pas un gain constant.

// SCL — à l'arrivée d'une image caméra (drapeau availCam).
IF #availCam THEN
    // 1) pose effecteur à l'instant de capture (relue dans le buffer horodaté)
    ReadPoseBuffer(t := #tCapture, pEff => #pEff_c, Reff => #Reff_c);
    // 2) déprojection : z_base = p_eff + R_eff · z_rel
    #zbX := #pEff_c[0] + #Reff_c[0,0]*#zRelX + #Reff_c[0,1]*#zRelY;
    #zbY := #pEff_c[1] + #Reff_c[1,0]*#zRelX + #Reff_c[1,1]*#zRelY;
    // 3) mesure directe de la pose cible base : deux updates scalaires (H=I)
    kf_update(z := #zbX, R := #Rcam, h := X);
    kf_update(z := #zbY, R := #Rcam, h := Y);   // (idem Z, ψ)
    #availCam := FALSE;
END_IF;

5. Une sortie lisse à chaque cycle

À chaque cycle, on recompose l'estimé base avec la pose effecteur courante pour rendre à la régulation la pose relative dont elle a besoin :

p_rel(t) = R_eff(t)ᵀ · ( X̂_base − p_eff(t) )

Le résultat est lisse — il combine un estimé base lisse (petit Q) et une cinématique effecteur lisse par cycle. La gigue et la rareté de la caméra ne traversent pas.

Position relative X (ce que reçoit la régulation) sur la fenêtre 1,5 à 4,5 secondes. La vérité relative est en tirets. Les images caméra sont des points ambre rares et légèrement dispersés. La sortie filtrée est une courbe verte lisse qui suit fidèlement la vérité à chaque cycle, malgré la rareté des images.
Figure 15.3. La sortie relative filtrée (vert), produite à chaque cycle, suit fidèlement la vérité (tirets) tout en absorbant la rareté et la gigue des images caméra (points ambre). La régulation reçoit un signal propre et cadencé, alors même que la caméra est lente et asynchrone.

6. Le piège du repère tournant : −ω×p_rel

La régulation veut souvent aussi la vitesse relative. Attention : comme la caméra tourne avec l'effecteur, la vitesse relative n'est pas simplement R_effᵀ(V − v_eff). En dérivant p_rel = R_effᵀ(X_base − p_eff), la rotation du repère fait apparaître un terme de transport :

v_rel = R_effᵀ · ( V̂_base − v_eff )  − ω_eff × p_rel

ω_eff (vitesse angulaire de l'effecteur) vient du Jacobien. Oublier le terme −ω_eff × p_rel — le « Coriolis de repère » — est l'erreur la plus fréquente de ce montage : même cible immobile, si l'effecteur tourne, la cible « défile » dans l'image, et une vitesse relative sans ce terme est fausse.

Vitesse relative Vx en fonction du temps. La vraie vitesse (tirets) est parfaitement recouverte par la courbe verte 'correcte (avec −ω×p_rel)'. La courbe ambre 'naïve (sans le terme)' s'en écarte fortement, avec une amplitude et une phase très différentes, se trompant de plusieurs m/s.
Figure 15.4. La vitesse relative avec et sans le terme de repère tournant. La version correcte (vert, avec −ω_eff×p_rel) se superpose à la vérité (tirets). La version naïve (ambre) se trompe massivement — ici d'un facteur ~80 en erreur quadratique. Le terme de transport n'est pas un détail : c'est l'essentiel du signal dès que l'effecteur tourne.
// SCL — recomposition en sortie, CHAQUE cycle. (2D ; Z, ψ analogues)
// p_rel = R_effᵀ · (X_base − p_eff)
dx := #Xbase - #pEff[0];   dy := #Ybase - #pEff[1];
#pRelX :=  #Reff[0,0]*dx + #Reff[1,0]*dy;   // Rᵀ = transposée
#pRelY :=  #Reff[0,1]*dx + #Reff[1,1]*dy;
// v_rel = R_effᵀ·(V_base − v_eff) − ω_eff × p_rel
dvx := #Vxbase - #vEff[0]; dvy := #Vybase - #vEff[1];
vbx :=  #Reff[0,0]*dvx + #Reff[1,0]*dvy;
vby :=  #Reff[0,1]*dvx + #Reff[1,1]*dvy;
#vRelX := vbx - #omEff*(-#pRelY);    // − ω×p_rel  (en 2D : ω×p = ω·[−py, px])
#vRelY := vby - #omEff*( #pRelX);

7. Robustesse & implémentation

8. Quand ce choix bascule

Le KF linéaire en repère base tient tant que deux hypothèses tiennent :

Exercices

Exercice 1 — Pourquoi Q est-il si petit ?

On estime la cible en repère base avec un modèle à vitesse constante. La cible peut dériver de ≈ 2 cm/s au plus, avec des changements très progressifs. Quel ordre de grandeur pour σα (bruit d'accélération), et pourquoi le repère base rend-il ce réglage facile ?

Voir la solution

Les changements de vitesse de la cible sont lents : une accélération de quelques cm/s² tout au plus. On prend donc σα de cet ordre (petit). En repère base, tout le mouvement rapide (celui du robot) a disparu de l'état — il est porté par les transformations déterministes. Le Q ne couvre plus que la vraie incertitude de la cible, qui est minuscule. En repère relatif, au contraire, σα aurait dû couvrir les accélérations du robot (des m/s²) — un Q des milliers de fois plus grand, donc un filtre bien pire.

Exercice 2 — Cible immobile, effecteur qui tourne

La cible est parfaitement immobile (V_base = 0) et l'effecteur ne fait que tourner sur place (v_eff = 0, ω_eff ≠ 0). Quelle est la vraie vitesse relative v_rel ? Que donnerait la formule naïve ?

Voir la solution

Formule complète : v_rel = R_effᵀ(0 − 0) − ω_eff × p_rel = −ω_eff × p_rel. Non nulle ! La cible défile dans l'image parce que le champ tourne, alors qu'elle ne bouge pas dans le monde. La formule naïve donnerait v_rel = 0 — complètement faux. C'est exactement l'écart massif de la figure 15.4, et la raison pour laquelle une régulation en vitesse alimentée par la formule naïve serait instable dès que l'effecteur tourne.

Récapitulatif

La leçon transversale. Ce chapitre ne parle presque pas de Kalman — il parle de modélisation : choisir l'état dans le repère où l'inconnu est le plus simple, et repousser tout le connu dans des transformations déterministes. C'est le geste qui distingue un filtre qui marche d'un filtre qu'on n'arrive jamais à régler. Les chapitres suivants (UKF, fusion IMU) reposeront sur ce même réflexe.