This project implements a discrete-time 1D dynamic system in C++ consisting of a simulated plant, noisy sensor measurements, a covariance-based Kalman state estimator, and a PD controller.
Measurements are generated by adding Gaussian noise to the true state while keeping the internal ground-truth state separate.
Two estimator configurations are implemented:
- Nominal Mode (2-state KF) — estimates position and velocity
- Bias Mode (3-state KF) — estimates position, velocity, and acceleration bias
CSV logging allows comparison between the nominal and bias-aware estimators.
The architecture mirrors a realistic robotics signal pipeline:
- Plant → Measurement → Estimator → Controller → Plant
Strict separation between ground truth, sensed data, estimation, and control logic is enforced throughout the system.
- Many robotics systems must estimate vehicle state from noisy and incomplete sensor measurements before control decisions can be made.
- This project was built to explore how estimator design affects closed-loop control performance by comparing a standard Kalman filter against a bias-aware state estimator under identical operating conditions.
- Implemented a modular C++ estimation-control framework comparing nominal and bias-aware Kalman estimators.
- Results demonstrate that bias augmentation reduces systematic drift, improves state consistency, and produces more stable closed-loop behavior.
-
Plant
- Simulates true position and velocity dynamics
- Generates noisy measurements
-
Estimator
- Nominal 2-state Kalman filter
- Bias-aware 3-state Kalman filter
- Explicit covariance propagation without external libraries
-
Controller
- PD controller operating on estimated state
Plant
│
▼
Measurement
│
▼
Kalman Filter
│
▼
PD Controller
│
└─────────────► Plant
-
Prerequisites
- A C++ compiler such as g++
- Python 3
- Python packages listed in requirements.txt
- Install the Python dependencies with:
pip install -r requirements.txt
-
Build
-
From the root, compile:
- Windows PowerShell
g++ .\src\*.cpp -I.\include -std=c++17 -O2 -o estimation_control.exe
- Linux / macOS / WSL
g++ src/*.cpp -Iinclude -std=c++17 -O2 -o estimation_control
-
-
Run
-
For nominal filter simulation:
- Windows PowerShell
.\estimation_control.exe --nominal- Linux / macOS / WSL
./estimation_control --nominal
-
For bias-aware filter simulation:
- Windows PowerShell
.\estimation_control.exe --bias- Linux / macOS / WSL
./estimation_control --bias
-
-
Plot
-
For nominal filter simulation:
- Windows PowerShell
py .\tools\plot_log.py log_nominal.csv
- Linux / macOS / WSL
python3 tools/plot_log.py log_nominal.csv
-
For bias considered filter simulation:
- Windows PowerShell
python3 tools/plot_log.py log_bias.csv
- Linux / macOS / WSL
python3 tools/plot_log.py log_bias.csv
-
Estimator structure fundamentally shapes closed-loop performance.
- Transitioning from:
- Fixed-gain alpha-beta filter → Covariance-driven Kalman filter → Bias-augmented state estimator demonstrates how model fidelity improves state consistency, removes systematic drift, and stabilizes control behavior.
Bias modeling transforms persistent steady-state error into an identifiable and correctable state.
-
Nominal:
-
Velocity exhibits steady-state error when plant contains acceleration bias
-
Estimator cannot explain persistent drift
-
Position Tracking
-
Velocity Estimation
-
Control Input
-
-
Bias Mode (3-state KF + position-only update):
-
Bias Convergence
-
Position Tracking
-
Velocity Estimation
-
Control Input
-
- Constant-velocity state model
- Covariance-based Kalman filtering
- Bias-augmented estimator variant
- PD control operating on estimated state
- Explicit covariance propagation without external matrix libraries
- C++
- Object-Oriented Design
- Kalman Filtering
- State Estimation
- PD Control
- CSV Logging
- Python Visualization
- Implement Joseph form covariance update for improved numerical stability
- Introduce bias random-walk modeling in the plant
- Extend from 1D motion to 2D planar dynamics
- Incorporate actuator delay modeling
- Integrate into ROS-based modular architecture
- Add runtime-configurable noise parameters
- Compare position-only vs full-state measurement observability






