⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unscentedkalmanfilter.hpp

📁 dysii is a C++ library for distributed probabilistic inference and learning in large-scale dynamical
💻 HPP
字号:
#ifndef INDII_ML_ESTIMATOR_UNSCENTEDKALMANFILTER_HPP#define INDII_ML_ESTIMATOR_UNSCENTEDKALMANFILTER_HPP#include "../aux/vector.hpp"#include "../aux/matrix.hpp"#include "../aux/GaussianPdf.hpp"#include "Filter.hpp"#include "UnscentedTransformation.hpp"namespace indii {  namespace ml {    namespace filter {      template <class T> class UnscentedKalmanFilterModel;      template <class T> class UnscentedKalmanFilterTransitionAdaptor;      template <class T> class UnscentedKalmanFilterMeasurementAdaptor;/** * Unscented Kalman %filter. *  * @author Lawrence Murray <lawrence@indii.org> * @version $Rev: 544 $ * @date $Date: 2008-09-01 15:04:39 +0100 (Mon, 01 Sep 2008) $ * * @param T The type of time. * * UnscentedKalmanFilter is suitable for systems with nonlinear * transition and measurement functions, approximating state and noise * with indii::ml::aux::GaussianPdf distributions. * * @see UnscentedTransformation * @see indii::ml::filter for general usage guidelines. */template<class T = unsigned int>class UnscentedKalmanFilter : public Filter<T> {  friend class UnscentedKalmanFilterTransitionAdaptor<T>;  friend class UnscentedKalmanFilterMeasurementAdaptor<T>;public:  /**   * Create new unscented Kalman %filter.   *   * @param model Model to estimate.   * @param p_x0 \f$p(\mathbf{x}_0)\f$; prior over the   * initial state \f$\mathbf{x}(0)\f$.   */  UnscentedKalmanFilter(UnscentedKalmanFilterModel<T>* model,      const indii::ml::aux::GaussianPdf& p_x0);  /**   * Destructor.   */  virtual ~UnscentedKalmanFilter();  /**   * Get the unscented transformation used for the transition   * function. This allows its parameters to be adjusted.   */  UnscentedTransformation<T>* getTransitionTransformation();  /**   * Get the unscented transformation used for the measurement   * function. This allows its parameters to be adjusted.   */  UnscentedTransformation<T>* getMeasurementTransformation();  virtual void filter(const T tnp1, const indii::ml::aux::vector& ytnp1);  virtual indii::ml::aux::GaussianPdf measure();protected:  /**   * Size of the state space.   */  const unsigned int N;  /**   * Size of the system noise space.   */  const unsigned int W;  /**   * Size of the measurement noise space.   */  const unsigned int V;  /**   * \f$p(\mathcal{X}_n\,|\,\mathbf{y}_{1:n})\f$; filter density over   * augmented state.   */  indii::ml::aux::GaussianPdf p_Xtn_ytn;  /**   * Model.   */  UnscentedKalmanFilterModel<T>* model;  /**   * Unscented transformation for transition function.   */  UnscentedTransformationModel<T>* transitionModel;  /**   * Unscented transformation for measurement function.   */  UnscentedTransformationModel<T>* measurementModel;  /**   * Unscented transformation for transition function.   */  UnscentedTransformation<T>* transitionTransform;  /**   * Unscented transformation for measurement function.   */  UnscentedTransformation<T>* measurementTransform;};    }  }}#include "UnscentedKalmanFilterTransitionAdaptor.hpp"#include "UnscentedKalmanFilterMeasurementAdaptor.hpp"#include "UnscentedKalmanFilterModel.hpp"#include "boost/numeric/bindings/traits/ublas_matrix.hpp"#include "boost/numeric/bindings/traits/ublas_vector.hpp"#include "boost/numeric/bindings/traits/ublas_symmetric.hpp"#include "boost/numeric/bindings/lapack/lapack.hpp"template <class T>indii::ml::filter::UnscentedKalmanFilter<T>::UnscentedKalmanFilter(    indii::ml::filter::UnscentedKalmanFilterModel<T>* model,    const indii::ml::aux::GaussianPdf& p_x0) :    Filter<T>(p_x0),    N(model->getStateSize()),    W(model->getSystemNoise().getDimensions()),    V(model->getMeasurementNoise().getDimensions()),    p_Xtn_ytn(N+W+V),    model(model) {  namespace aux = indii::ml::aux;  namespace ublas = boost::numeric::ublas;  /* pre-condition */  assert (p_x0.getDimensions() == model->getStateSize());      /* unscented transformations */  transitionModel = new UnscentedKalmanFilterTransitionAdaptor<T>(model);  transitionTransform = new UnscentedTransformation<T>(*transitionModel);  measurementModel = new UnscentedKalmanFilterMeasurementAdaptor<T>(model);  measurementTransform = new UnscentedTransformation<T>(*measurementModel);  /* ranges for subvectors and submatrices */  ublas::range xRange(0,N);  ublas::range wRange(N,N+W);  ublas::range vRange(N+W,N+W+V);  /* initialise augmented state */  aux::vector mu(N+W+V);  aux::symmetric_matrix sigma(N+W+V);  aux::GaussianPdf& w = model->getSystemNoise();  aux::GaussianPdf& v = model->getMeasurementNoise();  noalias(project(mu, xRange)) = p_x0.getExpectation();  noalias(project(mu, wRange)) = w.getExpectation();  noalias(project(mu, vRange)) = v.getExpectation();  noalias(project(sigma, xRange, xRange)) = p_x0.getCovariance();  noalias(project(sigma, wRange, xRange)) = aux::zero_matrix(W, N);  noalias(project(sigma, wRange, wRange)) = w.getCovariance();  noalias(project(sigma, vRange, xRange)) = aux::zero_matrix(V, N);  noalias(project(sigma, vRange, wRange)) = aux::zero_matrix(V, W);  noalias(project(sigma, vRange, vRange)) = v.getCovariance();  p_Xtn_ytn.setExpectation(mu);  p_Xtn_ytn.setCovariance(sigma);}template <class T>indii::ml::filter::UnscentedKalmanFilter<T>::~UnscentedKalmanFilter() {  delete transitionTransform;  delete measurementTransform;  delete transitionModel;  delete measurementModel;}template <class T>void indii::ml::filter::UnscentedKalmanFilter<T>::filter(const T tnp1,    const indii::ml::aux::vector& ytnp1) {  namespace aux = indii::ml::aux;  namespace ublas = boost::numeric::ublas;  namespace lapack = boost::numeric::bindings::lapack;  /* pre-condition */  assert (tnp1 > this->tn);  assert (ytnp1.size() % V == 0);  const T delta = tnp1 - this->tn;  this->tn = tnp1;  /* ranges for subvectors and submatrices */  ublas::range xRange(0,N);  ublas::range wRange(N,N+W);  ublas::range vRange(N+W,N+W+V);  /* unscented transformation of augmented state through transition     function */  aux::GaussianPdf p_xtnp1_ytn(transitionTransform->transform(p_Xtn_ytn,      delta));  /* prepare augmented state for measurement function */  aux::vector mu(p_Xtn_ytn.getExpectation());  aux::symmetric_matrix sigma(p_Xtn_ytn.getCovariance());  noalias(project(mu, xRange)) = p_xtnp1_ytn.getExpectation();  noalias(project(sigma, xRange, xRange)) = p_xtnp1_ytn.getCovariance();  aux::GaussianPdf p_Xtnp1_ytn(mu, sigma);  /* unscented transformation of augmented state through measurement     function */  aux::matrix P_xy(N+W+V,V); // cross-correlation matrix  aux::GaussianPdf p_ytnp1_Xtnp1(measurementTransform->transform(p_Xtnp1_ytn,      delta, &P_xy));  /* update p_xtn_ytn based on measurement */  const aux::vector &y_ytnp1_Xtnp1 = p_ytnp1_Xtnp1.getExpectation();  const aux::symmetric_matrix &P_ytnp1_Xtnp1 = p_ytnp1_Xtnp1.getCovariance();  const aux::vector &x_Xtnp1_ytn = p_Xtnp1_ytn.getExpectation();  const aux::symmetric_matrix &P_Xtnp1_ytn = p_Xtnp1_ytn.getCovariance();  /*    * Calculate Kalman gain directly without intermediate calculation   * of inverse, improves performance marginally.   *   * Calculate Kalman gain. <tt>K = P_xy *   * inv(P_ytnp1_Xtnp1)</tt>. Calculate as <tt>trans(K) =   * inv(P_ytnp1_Xtnp1) * trans(P_xy), so that LAPACK gesv function   * can be used, noting that <tt>trans(P_ytnp1_Xtnp1) ==   * P_ytnp1_Xtnp1</tt> as <tt>P_ytnp1_Xtnp1</tt> is symmetric.   *   * Note that Kalman gain applies only to state variables, not noise   * variables, so means and covariances can be projected down to only   * state variables for the update.   */  aux::matrix X(P_ytnp1_Xtnp1);  aux::matrix KT(trans(project(P_xy,xRange,ublas::range(0,V))));  int err;  err = lapack::gesv(X,KT);  assert (err == 0);  aux::matrix K(trans(KT));  noalias(project(mu,xRange)) = project(x_Xtnp1_ytn,xRange) +      prod(K, ytnp1 - y_ytnp1_Xtnp1);  X.resize(P_ytnp1_Xtnp1.size1(), KT.size2(), false);  noalias(X) = prod(P_ytnp1_Xtnp1, KT);  noalias(project(sigma,xRange,xRange)) = project(P_Xtnp1_ytn,xRange,xRange)      - prod(K, X);  p_Xtn_ytn.setExpectation(mu);  p_Xtn_ytn.setCovariance(sigma);  this->p_xtn_ytn.setExpectation(project(mu, xRange));  this->p_xtn_ytn.setCovariance(project(sigma, xRange, xRange));  /* post-condition */  assert (this->tn == tnp1);}template <class T>indii::ml::aux::GaussianPdf    indii::ml::filter::UnscentedKalmanFilter<T>::measure() {  return measurementTransform->transform(p_Xtn_ytn);}template <class T>indii::ml::filter::UnscentedTransformation<T>*    indii::ml::filter::UnscentedKalmanFilter<T>::getTransitionTransformation() {  return transitionTransform;}template <class T>indii::ml::filter::UnscentedTransformation<T>*    indii::ml::filter::UnscentedKalmanFilter<T>::getMeasurementTransformation() {  return measurementTransform;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -