#pragma once #include #include #include #include #include #include #include "opencv_contrib.h" namespace ukf_cv { using namespace cvcontrib; template using SigmaPoints = std::array,dim*2+1>; // Ported from // https://filterpy.readthedocs.io/en/latest/_modules/filterpy/kalman/sigma_points.html // Excerpt from the original docu: // " // Generates sigma points and weights according to Van der Merwe's // 2004 dissertation[1] for the UnscentedKalmanFilter class.. It // parametizes the sigma points using alpha, beta, kappa terms, and // is the version seen in most publications. // Unless you know better, this should be your default choice. // alpha : float // Determins the spread of the sigma points around the mean. // Usually a small positive value (1e-3) according to [3]. // beta : float // Incorporates prior knowledge of the distribution of the mean. For // Gaussian x beta=2 is optimal, according to [3]. // kappa : float, default=0.0 // Secondary scaling parameter usually set to 0 according to [4], // or to 3-n according to [5]. // Reference // .. [1] R. Van der Merwe "Sigma-Point Kalman Filters for Probabilitic // Inference in Dynamic State-Space Models" (Doctoral dissertation) // " template class MerweScaledSigmaPoints { public: static constexpr int num_sigmas = 2*dim+1; using Vector = cv::Vec; using Matrix = cv::Matx; MerweScaledSigmaPoints(float alpha = 0.01, float beta = 2., int kappa = 3-dim) { lambda = alpha*alpha * (dim + kappa) - dim; const float c = .5 / (dim + lambda); Wc_i = c; Wm_i = c; Wm_0 = lambda / (dim+lambda); Wc_0 = Wm_0 + (1.-alpha*alpha + beta); } SigmaPoints compute_sigmas(const Vector &mu, const Matrix &mat, bool is_tril_factor) const { const Matrix triu_factor = is_tril_factor ? mat.t() : cholesky(mat).t(); const Matrix U = triu_factor*std::sqrt(lambda+dim); SigmaPoints sigmas; sigmas[0] = mu; for (int k=0; k std::tuple , cv::Matx> compute_statistics(const SigmaPoints &sigmas) const { cv::Vec mu{}; // Zero initializes for (size_t i=0; i cov{}; for (size_t i=0; i cv::Matx compute_cov(const SigmaPoints &sigmas, const SigmaPoints &othersigmas) const { cv::Vec mu{}; // Zero initializes cv::Vec mu_other{}; // Zero initializes for (size_t i=0; i cov{}; for (size_t i=0; i