TP — Filtrage de Kalman
Auteur
- Stéphane Derrode, Centrale Lyon, Dpt Mathématiques & Informatique
Cadre — MSO 3.7, Apprentissage bayésien, séance #7 (4h en présentiel, CR 2 noté, déposé en fin de séance).
Objectifs
L’objectif de ce TP est de programmer le filtre et le lisseur de Kalman, puis de les étendre au cas non linéaire via l’EKF (Extended Kalman Filter). On applique enfin l’ensemble à un cas de suivi 2D d’une trajectoire bruitée.
Ce TP étend le TP HMC (séance #5) : un système dynamique linéaire-gaussien \(x_{t+1} = F x_t + w_t,\ y_t = H x_t + v_t\) est une chaîne de Markov cachée à états continus. Le filtre de Kalman est exactement l’analogue continu des équations forward (
getAlpha) du TP HMC, et le lisseur RTS l’analogue du forward-backward. L’EKF ajoute la linéarisation locale quand \(f\) ou \(h\) ne sont pas linéaires.
Format et pré-requis
Projet multi-fichiers .py à exécuter dans VS Code ou un terminal Python. Dépendances : numpy, scipy, matplotlib.
Table des matières
- Introduction
- 1. Simulation d’un systeme dynamique lineaire-gaussien
- 2. Filtre de Kalman
- 3. Lisseur RTS
- 4. EKF — Extended Kalman Filter
- 5. Application : suivi 2D (partie reportee dans votre CR)
Introduction¶
Téléchargez et décompressez Kalman_Skeleton.zip. Vous disposez ainsi de 4 fichiers Python :
func.py: algorithmes de Kalman et EKF. Quatre fonctions sont à programmer :kalman_predict,kalman_update,rts_smoother_step,ekf_update. Les autres (kalman_filter_pass,rts_smoother_pass,ekf_predict,ekf_filter_pass,mse,plot_*) sont déjà fournies.SimulDLG.py: simule un système dynamique linéaire-gaussien 2D (vitesse-constante) et sauvegarde la trajectoire danssources/XY.npz.KalmanFiltering.py: applique le filtre et le lisseur à la simulation DLG, affiche les plots et les MSE.EKF_pendulum.py: applique l’EKF à un pendule simple (non linéaire).
Bon à savoir. Le squelette tourne sans crasher même si vous n’avez encore rien codé : les TODO renvoient les entrées inchangées. Les résultats sont alors triviaux (pas d’estimation), mais cela vous permet de vérifier le pipeline dès le début.
1. Simulation d’un systeme dynamique lineaire-gaussien¶
Fichier principal :
SimulDLG.py
- Lisez le code et vérifiez que vous comprenez bien : la matrice de transition \(F\) (vitesse-constante), la matrice d’observation \(H\) (on n’observe que la position), les covariances \(Q\) et \(R\).
- Lancez
python SimulDLG.py. Observez la figureresults/SimulDLG.png: trajectoire vraie 2D + observations bruitées.
np.random.seed(42)est fixé en début de programme pour la reproductibilité.
2. Filtre de Kalman¶
Fichier principal :
KalmanFiltering.py. Code à compléter dansfunc.py.
- Programmez
kalman_predict(x, P, F, Q)(TODO 1) — prédiction \(x_\text{pred} = F\,x\), \(P_\text{pred} = F\,P\,F^T + Q\). - Programmez
kalman_update(x, P, y, H, R)(TODO 2) — correction par l’observation \(y\). - Lancez
python KalmanFiltering.py. Vous devriez obtenir des MSE de l’ordre de :
3. Lisseur RTS¶
Code à compléter dans
func.py. Pour visualiser, c’est toujoursKalmanFiltering.py.
- Programmez
rts_smoother_step(...)(TODO 3) — une étape backward du lisseur Rauch-Tung-Striebel. - Relancez
python KalmanFiltering.py. Le lisseur doit avoir une MSE inférieure à celle du filtre (~30 à 50 % de gain selon les paramètres).
4. EKF — Extended Kalman Filter¶
Fichier principal :
EKF_pendulum.py. Code à compléter dansfunc.py.
On modélise un pendule simple par $\(\theta_{t+1} = \theta_t + \Delta t\, \omega_t,\quad \omega_{t+1} = \omega_t - \Delta t\, \tfrac{g}{L}\sin(\theta_t).\)$ L’observation est \(y_t = \sin(\theta_t) + \text{bruit}\) — non linéaire en \(\theta\).
- Programmez
ekf_update(x, P, y, h, H_jac, R)(TODO 4) — identique àkalman_update, mais on remplace \(H\) par sa jacobienne évaluée en \(x_\text{pred}\), et on calcule l’innovation \(y - h(x_\text{pred})\) avec \(h\) non linéaire. - (La prédiction
ekf_predictest fournie, car structurellement très proche dekalman_predict.) - Lancez
python EKF_pendulum.py. Observez : l’EKF parvient à reconstituer \(\theta_t\) à partir des seules observations \(\sin(\theta_t)\) bruitées.
5. Application : suivi 2D (partie reportee dans votre CR)¶
Écrivez votre propre programme principal — proposé :
SI_Tracking.py.
Choisissez une trajectoire 2D synthétique intéressante (figure-en-8, spirale d’Archimède, trajectoire avec changements de direction, etc.). Vous devez :
- Simuler la trajectoire vraie et les observations bruitées, en partant des matrices \(F, H, Q, R\) du modèle vitesse-constante (ou autre — à vous de choisir/justifier).
- Optionnel mais recommandé : introduire des observations manquantes sur un intervalle (occlusion). Pour le filtre on peut « répéter la dernière observation valide » comme baseline, ou sauter l’update sur les pas manquants — proposez votre choix.
- Appliquer le filtre et le lisseur (en utilisant
kalman_filter_passetrts_smoother_passdefunc.py). - Tracer : trajectoire vraie, observations, filtre, lisseur — sur le même plot 2D.
- Étudier la sensibilité aux paramètres : faites varier \(Q\) et \(R\) d’un facteur ×10 dans les deux sens (4 régimes), et commentez l’effet sur le filtre.
Consignes pour le compte-rendu (CR 2, noté)¶
Le CR est individuel, déposé sur Pedagogie3 avant la fin de séance, sous forme d’un fichier compressé contenant :
- les sources :
SI_Tracking.py(+ tout autre code écrit ou modifié) ; - un mini-rapport (
.pdfou.md; pas de.doc/.docx), avec page de garde (noms, prénoms, date, titre du TP, module, encadrant).
Le rapport doit contenir :
- Trajectoire choisie : équations / type, paramètres du modèle DLG (\(F, H, Q, R\)), justification.
- Plot 2D : trajectoire vraie · observations · filtre · lisseur.
- Tableau des MSE : observation / filtre / lisseur. Commenter (gain du filtre, gain du lissage).
- Étude paramétrique \(Q\) et \(R\) (4 régimes) : plots et / ou tableau, et interprétation physique (que se passe-t-il quand on fait trop confiance aux observations ? au modèle ?).
- (Optionnel) gestion des observations manquantes : comparer la stratégie « répéter » et la stratégie « sauter l’update ».
- Commentaire qualitatif final : où Kalman gagne, où il échoue (transitions brusques non modélisées, biais dans \(F\), …).