From-scratch implementations of the three classic Bayesian state estimators in Python, presented as runnable Jupyter notebooks with the math derived inline.
| Filter | Notebook | Use case |
|---|---|---|
| Kalman Filter | src/KalmanFilter.ipynb | Linear systems, Gaussian noise |
| Extended Kalman Filter | src/ExtendedKalmanFilter.ipynb | Nonlinear systems, Gaussian noise |
| Error-State EKF (VIO) | src/ErrorStateEKF_VIO.ipynb | State on a manifold (e.g. rotation), IMU + camera fusion |
| Particle Filter | src/ParticleFilter.ipynb | Nonlinear, non-Gaussian, multi-modal |
conda create -n filters python=3.11 -y
conda activate filters
pip install -r requirements.txt
jupyter lab src/Then open one of the three notebooks listed above.
A linear filter — propagates a Gaussian belief through a linear motion model and updates it with linear observations. Optimal under those assumptions.
Predict
Update
The notebook tracks a moving point in 2D from noisy position measurements
and cross-checks against cv2.KalmanFilter.
→ open notebook
Same recursion as the linear Kalman filter, but the linear
The notebook uses a Constant Turn Rate and Acceleration vehicle model
(state: sympy and shown in
the notebook.
→ open notebook
When the state contains a quantity that lives on a manifold — most
commonly a rotation in
-
Nominal state
$\hat{\mathbf{x}}$ — stored exactly (position, velocity, rotation matrix, IMU biases). Propagated by the full nonlinear IMU integration. -
Error state
$\delta\mathbf{x} \in \mathbb{R}^{15}$ — a small additive perturbation around the nominal. Lives in a vector space, so the EKF can track a Gaussian over it.
The Kalman update runs on
The notebook walks through one complete 15-state ESKF step with full numeric values — IMU propagation, monocular-VO measurement, Kalman update, manifold injection, and Joseph-form covariance update — and verifies every intermediate result against the hand-computed reference. It's also where bias estimation falls out automatically: the gyro/accel biases are corrected through cross-covariances even though the measurement Jacobian has no bias columns. → open notebook
For nonlinear, non-Gaussian, or multi-modal beliefs. Instead of a
mean+covariance, the posterior is represented by
Predict — push each particle through the (noisy) motion model:
Weight — for range measurements
Resample — systematic resampling when the effective sample size
The notebook drives a robot along a synthetic circular trajectory and watches the particle cloud collapse onto the truth as range measurements to six known landmarks accumulate. → open notebook




