EKFCore is a modular and high-performance C++17 implementation of a templated Extended Kalman Filter (EKF) for state estimation. It provides a generic, reusable, and dimension-safe framework for fusing noisy sensor data to obtain accurate and reliable state estimates in uncertain environments — a cornerstone of robotics and autonomous systems.
The library serves as both a learning resource and a practical foundation for implementing sensor fusion pipelines in real-world systems such as robots, drones, and autonomous vehicles.
Modern autonomous systems rely on accurate estimates of their internal state (position, velocity, orientation, etc.) to navigate safely. However, real-world sensors — GPS, IMU, wheel encoders — are inherently noisy and often inconsistent. The challenge is to combine multiple imperfect measurements into a consistent and smooth estimate of the true system state.
The Extended Kalman Filter (EKF) provides an elegant and powerful solution by operating in two alternating steps:
- Prediction: Use the motion model to predict the system’s next state.
- Update: Correct that prediction using sensor measurements.
By linearizing nonlinear system dynamics through Jacobian matrices, the EKF maintains both computational efficiency and robustness, making it one of the most widely used estimators in robotics, aerospace, and control systems.
-
🔢 Templated C++ EKF Implementation A from-scratch EKF built using templates and the Eigen library, ensuring compile-time dimensional safety, flexibility, and high performance.
-
🧮 Correlated Noise Generation Includes
generateCorrelatedNoise, which uses Cholesky decomposition to generate statistically valid noise vectors based on user-defined covariance matrices. -
🧠 Robust Sensor Fusion Framework Designed to fuse data from multiple heterogeneous sensors (e.g., GPS, IMU, wheel odometry) with independent measurement models.
-
🧰 Simulation Environment A configurable simulator for ground truth generation and realistic noise injection to model real-world disturbances.
-
📊 Comprehensive Data Output Outputs ground truth, noisy sensor data, and EKF estimates (with covariance matrices) to CSV files for post-processing and analysis.
-
📈 Visualization Tools (Python) Python scripts using
matplotlib,numpy, andpandasvisualize:- Ground truth trajectory
- Noisy sensor data
- Filtered EKF estimates
- Covariance ellipses representing uncertainty
For a planar robot:
where
The motion model evolves the state according to control inputs (velocity
where
Multiple sensor models are supported, such as:
-
GPS / IMU:
$$ Z_{gps} = h_{gps}(X_k) + v_{gps} = X_k + v_{gps} $$
-
Wheel Odometry:
$$ Z_{odom} = h_{odom}(X_k) + v_{odom} $$
where
$(v_{odom}, v_{gps}) \sim \mathcal{N}(0, R_k)$ represent measurement noise.
Each sensor has its own measurement Jacobian:
This Jacobian linearizes the measurement model around the current state estimate and is used during the update step to correct the predicted state.
Ensure you have the following installed:
-
C++17 or newer
-
CMake ≥ 3.10
-
Eigen 3 (automatically fetched by CMake or installed manually)
-
Python 3.x with:
pip install matplotlib numpy pandas
# Clone repository
git clone https://github.com/0xphen/EKFCore.git
cd EKFCore
# Configure build
mkdir build && cd build
cmake ..
# Build executable
makeAfter building, an executable ekfcore_sim will be generated in the build directory:
./ekfcore_simThis will produce:
- Ground truth and noisy sensor data
- Filtered EKF estimates
- Covariance matrices
All results are exported as CSV files for visualization.
Run the provided Python script to visualize results:
python3 scripts/plot_results.pyThis will plot:
- Ground Truth Path
- Noisy Sensor Data
- EKF Estimated Path
- Covariance Ellipses
- Integrate IMU bias estimation
- Add Unscented Kalman Filter (UKF) variant
- Provide ROS2 integration example
- Add unit tests for measurement model consistency
- Probabilistic Robotics — Thrun, Burgard & Fox
- State Estimation for Robotics — Tim Barfoot
- Estimation and Control of Dynamic Systems — Goodwin & Sin
- Kalman Filter Tutorial — Simon D. (IEEE)