Skip to content
All projects

Robotics & Autonomy

Kalman / EKF from Scratch

A hands-on state-estimation library: KF and EKF implemented from scratch in NumPy, with seven progressive examples from 1D tracking to sensor fusion, EKF radar and a real drone flight-log case study.

My role
Author
Context
Open-source tutorial
Stack
Python · NumPy · SciPy · State estimation

7

worked examples

KF+EKF

from scratch

Real

drone flight log

Why I wrote it

State estimation is the quiet backbone of robotics: every drone, rover and phone fuses noisy sensors into one belief about where it is. I wanted a version I fully understood, so I wrote the filters myself and built seven runnable examples that each add one idea. The same ideas run through my state-estimation internship work and the GPS-denied UAV project.

The library

Two small classes with minimal dependencies (NumPy / SciPy): a linear KalmanFilter with a Joseph-form covariance update for numerical stability, and an ExtendedKalmanFilter that linearises non-linear models through their Jacobians.

kf = KalmanFilter(
    F=np.array([[1, dt], [0, 1]]),   # constant-velocity model
    H=np.array([[1, 0]]),            # we measure position only
    Q=np.diag([0.05, 0.05]),         # process noise
    R=np.array([[9.0]]),             # measurement noise
    x0=[0, 0], P0=np.diag([10, 10]),
)
for z in measurements:
    kf.predict()
    kf.update(z)

Seven examples, one idea at a time

  1. A noisy measurement: the problem statement.
  2. 1D constant velocity: from position alone, the filter also infers velocity. Position RMSE 2.7 → 1.7 m.
  3. Constant acceleration: follows a manoeuvring target.
  4. 2D tracking: a 4-state [x, vx, y, vy] filter along a curved path. Track RMSE 2.2 → 0.9 m.
  5. Sensor fusion: accelerometer drives the prediction, barometer corrects it.
  6. EKF radar: range and bearing are non-linear in position, so the EKF linearises each step.
  7. Real flight log: a real ~45-minute tethered-drone flight.
Altitude estimate from accelerometer-only, barometer-only and fused Kalman filter versus ground truth
Example 05: altitude RMSE is 4.0 m from the barometer, 32 m from the accelerometer alone and 0.8 m fused.
2D object tracking: noisy position fixes scattered around a curved true path, with the Kalman estimate following the path closely
Example 04: 2D tracking along a curved path.

The real-data case study

The last example leaves simulation behind. It fuses the onboard barometer with IMU vertical acceleration, rotated into the world frame with the attitude quaternion, and validates against survey-grade ground truth. The fused estimate stays within 2.7 m of ground truth while raw GPS is 5.5 m off, and the zoom panel shows the filter smoothing real barometer jitter.

Real drone flight: raw GPS, barometer and fused Kalman altitude compared to ground truth over 45 minutes, with a zoomed panel
Example 07: real ~45-minute tethered-drone flight log.

More projects

Robotics & Autonomy

2026Independent research

Teaching Cost Curve: how many demos does a robot need?

Measuring the demonstration-count vs. success-rate curve for SmolVLA, LoRA fine-tuned on unseen LIBERO tasks, on a single 8 GB consumer GPU. Nearly all of the value arrives in the first five demonstrations, and so does catastrophic forgetting.

66.7% · success @ 5 demos

  • SmolVLA
  • LeRobot
  • LoRA / PEFT
  • LIBERO
Read case studyCode
Robotics & Autonomy

2026Independent project · public dataset

GPS-Denied UAV Localization

Neural dead reckoning for a fixed-wing UAV: an LSTM predicts one-second displacements from 19 GPS-free sensor channels. After 4.5 minutes without GPS it is still within ~85 m, about 38× better than classical dead reckoning.

44.4 m · mean error, 4.5 min

  • PyTorch
  • LSTM / GRU / TCN
  • Sensor fusion
  • TorchScript
Read case studyCode
VO
Robotics & Autonomyprivate

2026TEKNOFEST 2026 · Team bugbuster · Finalist

Aerial AI: GPS-Free Visual Odometry

TEKNOFEST 2026 Artificial Intelligence in Aviation. I owned the GPS-free positioning task: RAFT optical flow + homography with a keyframe ladder estimates the aircraft’s displacement from its downward camera. Full rehearsal: 2256/2256 frames, 3.54 m mean error.

3.54 m · mean error, full run

  • RAFT
  • Homography
  • OpenCV
  • PyTorch
Read case studyCode on request