estkit is header-only: add include/ to your include path and
#include the estimator you want. Everything below is on this one page.
Build the benchmark, the tests and the examples with CMake:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build -j ctest --test-dir build # unit tests + examples ./build/example_drone # EKF/UKF/PF on a drone range model ./build/example_battery combined # SOC estimation on a hard scenario ./build/bench_cell --list # every cell-level estimator
Single-precision build for a microcontroller:
cmake -S . -B build_f -DESTKIT_FLOAT=ON. The library also cross-compiles for a
Cortex-M7 with arm-none-eabi-g++ -mcpu=cortex-m7 -mfpu=fpv5-d16 -fno-exceptions -fno-rtti
— see examples/embedded_cortex_m7.cpp.
An estimator is a template over a model: any class that provides a state transition, a measurement and the two noise covariances. Jacobians, constraints and tunable parameters are optional and supplied numerically when absent.
struct MyModel { static constexpr int NX = 4, NU = 1, NY = 2; Vec<NX> f(const Vec<NX>& x, const Vec<NU>& u) const; // x_{k+1} Vec<NY> h(const Vec<NX>& x, const Vec<NU>& u) const; // y_k Mat<NX,NX> Q(const Vec<NX>&, const Vec<NU>&) const; Mat<NY,NY> R(const Vec<NX>&, const Vec<NU>&) const; // optional: F(x,u), H(x,u), B(x,u), constrain(x), NP/params()/set_params() };
Every filter and observer is a template over such a model, so the same
Ekf<M>, Ukf<M> or Mhe<M,N> that estimates the
state of charge of a cell estimates the position of a drone or the attitude of an airframe:
#include "estkit/filters/ukf.hpp" using namespace estkit; Ukf<MyModel> ukf{MyModel{}}; ukf.init(x0, P0); for (...) { ukf.predict(u_prev); // time update with the previous input ukf.update(y, u); // measurement update auto x = ukf.x(); // state estimate; ukf.P() its covariance }
The interface is the same four calls for every estimator in the library — from a
Luenberger observer to a 500-particle filter. Offline smoothers add a run() over the
whole record.
One header under the family directory, templated on the model, with the primary
reference in the header comment; no heap, no exceptions, warning-free in double and float; register
it in benchmarks/registry_<family>.cpp, add a unit test and a chapter. The full
contract is in docs/ESTIMATOR_API.md and
CONTRIBUTING.md.
No estimator in the library needs double precision on this problem — the single-precision build agrees with the double build to within the seed-to-seed spread — but the factorised forms are there for larger state vectors. Below 2 µs per step the cost of an estimator is irrelevant on any flight processor.
The numerics chapter →The Kalman-type filters are cross-checked against FilterPy, the electrochemical plant against PyBaMM, and the attitude filters against ahrs — each an independent reference implementation, run on the exported benchmark data:
These libraries are used only as references and are not part of estkit; see THIRD_PARTY_NOTICES. The checks run in CI.