Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
kalmanFilter.hpp
00001 /* $Id$ */
00002 
00003 #ifndef FILTER_KALMAN_FILTER_HPP
00004 #define FILTER_KALMAN_FILTER_HPP
00005 
00006 #include <iostream>
00007 
00008 #include "boost/date_time/posix_time/posix_time_types.hpp"
00009 
00010 #include "kernel/jafarDebug.hpp"
00011 #include "kernel/dataLog.hpp"
00012 
00013 #include "jmath/jblas.hpp"
00014 #include "jmath/gaussianVector.hpp"
00015 
00016 #include "filter/filterException.hpp"
00017 #include "filter/predictModel.hpp"
00018 #include "filter/observeModel.hpp"
00019 #include "filter/constraintModel.hpp"
00020 
00021 namespace jafar {
00022   namespace filter {
00023 
00029     class BaseKalmanFilter : public jafar::kernel::DataLoggable {
00030 
00031     public:
00032 
00034       enum CovUpdateType {SIMPLE,   
00035                           STANDARD, 
00036                           JOSEPH    
00041       };
00042 
00044       enum ConsistencyCheckLevel {CONSISTENCY_NONE,     
00045           CONSISTENCY_WARNING,  
00046           CONSISTENCY_EXCEPTION 
00047       };
00048 
00049     protected:
00050 
00052       CovUpdateType covUpdateType;
00053 
00055       jblas::vec x;
00056 
00058       jblas::sym_mat P;
00059 
00061       boost::posix_time::time_duration p_curTime;
00062 
00064       jblas::mat K;
00065 
00067       jblas::mat KH_tmp;
00068 
00070       ConsistencyCheckLevel consistencyCheckLevel;
00072       double chi2Threshold;
00073 
00077       template<class Vec>
00078       void checkConsistency(Vec const& y, jblas::sym_mat const& Sinv) 
00079       {
00080   if (consistencyCheckLevel == CONSISTENCY_NONE)
00081     return;
00082 
00083   JFR_PRECOND(Sinv.size1() == y.size() && Sinv.size2() == y.size(),
00084         "BaseKalmanFilter::checkConsistency: invalid size of S");
00085 
00086   using namespace ublas;
00087   double ySiy = inner_prod(y, prod(Sinv, y) );
00088   checkConsistency(y, Sinv, ySiy);
00089       }
00090 
00091       void checkConsistency(double y, double Sinv) {
00092   if (consistencyCheckLevel == CONSISTENCY_NONE)
00093     return;
00094   
00095   double ySiy = y * Sinv * y;
00096   checkConsistency(y, Sinv, ySiy);
00097       }
00098 
00099       template<typename YType, typename SinvType> 
00100       void checkConsistency(YType y, SinvType Sinv, double ySiy) {
00101   if (ySiy > chi2Threshold) {
00102     switch(consistencyCheckLevel) {
00103     case CONSISTENCY_NONE:
00104       // shut up gcc warning
00105       break;
00106     case CONSISTENCY_WARNING:
00107       JFR_WARNING("ySiy=" << ySiy << " threshold=" << chi2Threshold
00108       << " y=" << y << " Sinv=" << Sinv  << ")");
00109       break;
00110     case CONSISTENCY_EXCEPTION:
00111       std::ostringstream s;
00112       s << "ySiy=" << ySiy << " threshold=" << chi2Threshold
00113         << " y=" << y << " Sinv=" << Sinv  << ")";
00114       throw InconsistentUpdateException(ySiy, chi2Threshold, s.str(), __FILE__, __LINE__);
00115       break;
00116     }
00117   }
00118       }
00119 
00120       // logging method
00121       void writeLogHeader(jafar::kernel::DataLogger& log) const;
00122       void writeLogData(jafar::kernel::DataLogger& log) const;
00123 
00124     public:
00125 
00129       BaseKalmanFilter(std::size_t size_);
00130 
00131       virtual ~BaseKalmanFilter();
00132 
00133       jblas::vec const& getX() const {return x;};
00134       jblas::vec& getX() {return x;};
00135       jblas::sym_mat const& getP() const {return P;};
00136       jblas::sym_mat& getP() {return P;};
00137 
00139       void clear();
00140 
00141       boost::posix_time::time_duration const& getCurrentTime() const {return p_curTime;}
00142       
00143       void setCovUpdateType(CovUpdateType covUpdateType_);
00144       CovUpdateType getCovUpdateType() const;
00145 
00146       void setupConsistencyCheck(ConsistencyCheckLevel level_, 
00147          double chi2Threshold_)
00148       {
00149   consistencyCheckLevel = level_; chi2Threshold = chi2Threshold_;
00150       }
00151 
00152       ConsistencyCheckLevel getConsistencyCheckLevel() const
00153       {
00154         return consistencyCheckLevel;
00155       }
00156       
00157       double getChi2Threshold() const
00158       {
00159         return chi2Threshold;
00160       }
00161 
00162       
00165       void init(const jblas::vec& state_, const jblas::sym_mat& cov_, 
00166     boost::posix_time::time_duration const& curTime);
00167 
00171       void init(const jblas::vec& state_, const jblas::sym_mat& cov_);
00172 
00175       void init(boost::posix_time::time_duration const& curTime);
00176 
00179       virtual std::size_t sizeState() const {return x.size();};
00180 
00181       //      void resize(std::size_t size_);
00182 
00183     }; // class BaseKalmanFilter
00184 
00189     class KalmanFilter : public BaseKalmanFilter {
00190 
00191     public :
00192 
00196       KalmanFilter(std::size_t size_);
00197 
00198       virtual ~KalmanFilter();
00199 
00204       void predict(const LinearPredictModel& m_);
00205 
00206 #ifndef SWIG
00207 
00211       void predict(LinearCommandPredictModel& m_, jblas::vec const& u_);
00212 #endif // SWIG
00213 
00218       void update(LinearObserveModel& m_, jblas::vec& z_);
00219 
00220     protected :
00221 
00227       void updateLinear(const jblas::mat_range& H_, 
00228                         const jblas::vec_range& z_, double R_);
00229 
00230     }; // class KalmanFilter
00231 
00232 #ifndef SWIG
00233     
00238     class ExtendedKalmanFilter : public KalmanFilter {
00239 
00240     public :
00241   
00242       ExtendedKalmanFilter(std::size_t n_);
00243 
00244       virtual ~ExtendedKalmanFilter();
00245 
00250       void predict(JacobianPredictModel& m_);
00251 
00256       void predict(JacobianCommandPredictModel& m_, jblas::vec const& u_);
00257       
00263       void update(JacobianObserveModel& m_, const jblas::vec& z_);
00264 
00265     protected:
00266 
00273       void updateExtended(const jblas::mat_range& H_, 
00274                           double y_, double R_);
00275 
00276     }; // class ExtendedKalmanFilter
00277 
00278     //======================================================
00279 
00290     class ExtendedKalmanFilterImplicit : public ExtendedKalmanFilter
00291     {
00292     public :
00293   
00294       ExtendedKalmanFilterImplicit(std::size_t n_);
00295 
00296       virtual ~ExtendedKalmanFilterImplicit();      
00297 
00298 
00305       void update(JacobianImplicitObserveModel& m_, 
00306       const jblas::vec& z_);
00307 
00308     }; // class ExtendedKalmanFilterImplicit
00309 
00310 
00311     //======================================================
00312 
00325     class BlockExtendedKalmanFilter : public BaseKalmanFilter {
00326 
00327     public:
00328 
00329       jblas::vec_range* x_r;
00330       jblas::sym_mat_range* P_r;
00331   
00332       BlockExtendedKalmanFilter(std::size_t sizeMax_, std::size_t size_);
00333 
00334       virtual ~BlockExtendedKalmanFilter();
00335 
00336       inline std::size_t sizeStateMax() const {return x.size();};
00337       virtual inline std::size_t sizeState() const {return x_r->size();};
00338 
00339       void softResize(std::size_t size_);
00340   
00345       void predict(std::size_t index1_, std::size_t index2_,
00346        LinearPredictModel const& m_);
00347 
00352       void predict(std::size_t index1_, std::size_t index2_,
00353        JacobianBlockPredictModel& m_);
00354 
00359       void predict(std::size_t index1_, std::size_t index2_,
00360        JacobianBlockCommandPredictModel& m_, 
00361        jblas::vec const& u_);
00362 
00363       void update(LinearObserveModel& m_, std::size_t index, const jblas::vec& z_);
00364 
00369       void update(JacobianObserveModel& m_,  std::size_t index, jblas::vec const& z_);
00370 
00371       void update(JacobianObserveModel& m_,  
00372       std::size_t index_, 
00373       jblas::vec_range& x_,
00374       jblas::sym_mat_range& P_,
00375       jblas::vec const& z_);
00376 
00377 //       void update(BlockObserveModel& m_,
00378 //                   std::size_t index1_, std::size_t index2_,
00379 //                   const jblas::vec& z_);
00380 
00381       void update(BlockObserveModel& m_,
00382                   std::size_t index1_, std::size_t index2_,
00383                   jblas::vec_range& x1_,
00384                   jblas::vec_range& x2_,
00385                   jblas::sym_mat_range& P1_,
00386                   jblas::sym_mat_range& P2_,
00387                   const jblas::vec& z_,
00388       jmath::GaussianVector& zPred);
00389 
00390       void applyConstraint(JacobianStrongConstraintModel& model,
00391          std::size_t index_);
00392 
00393       void applyConstraint(JacobianStrongConstraintModel& model,
00394          std::size_t index_,
00395          jblas::vec_range& x_,
00396          jblas::sym_mat_range& P_);
00397 
00416       double computeMahalanobisDistance(LinearObserveModel& m_,
00417                                         std::size_t index_,
00418                                         const jblas::vec& z_);
00419 
00420       double computeMahalanobisDistance(LinearObserveModel& m_,
00421                                         const jblas::vec_range& x_,
00422                                         const jblas::sym_mat_range& P_,
00423                                         const jblas::vec& z_);
00424 
00425       double computeMahalanobisDistance(BlockObserveModel& m_,
00426                                         std::size_t index1_, 
00427           std::size_t index2_,
00428                                         const jblas::vec_range& x1_,
00429                                         const jblas::vec_range& x2_,
00430                                         const jblas::sym_mat_range& P1_,
00431                                         const jblas::sym_mat_range& P2_,
00432                                         const jblas::vec& z_);
00433     protected:
00434 
00435       jblas::mat_range* K_r;
00436       jblas::mat_range* KH_tmp_r;
00437 
00440       void updateBlockExtended(std::size_t index_,
00441              const jblas::sym_mat_range& P_,
00442              const jblas::sym_mat_range& Pcol_,
00443              const jblas::mat_range& H_,
00444              double y_, double R_);
00445 
00446       void updateBlockExtended(std::size_t index_,
00447              const jblas::sym_mat_range& P_,
00448              const jblas::sym_mat_range& Pcol_,
00449              const jblas::mat& H_,
00450              jblas::vec const& y, 
00451              jblas::sym_mat const& R_);
00452 
00455       void updateBlockExtended(std::size_t index1_, std::size_t index2_,
00456              const jblas::sym_mat_range& P1_, 
00457              const jblas::sym_mat_range& P2_,
00458              const jblas::sym_mat_range& P12_, 
00459              const jblas::sym_mat_range& P21_,
00460              const jblas::sym_mat_range& Pcol1_, 
00461              const jblas::sym_mat_range& Pcol2_,
00462              const jblas::mat_range& H1_, 
00463              const jblas::mat_range& H2_,
00464              double y_, double R_);
00465 
00466       void updateBlockExtended(std::size_t index1_,
00467              std::size_t index2_,
00468              const jblas::sym_mat_range& P1_, 
00469              const jblas::sym_mat_range& P2_,
00470              const jblas::sym_mat_range& P12_, 
00471              const jblas::sym_mat_range& P21_,
00472              const jblas::sym_mat_range& Pcol1_, 
00473              const jblas::sym_mat_range& Pcol2_,
00474              const jblas::mat& H1_, 
00475              const jblas::mat& H2_,
00476              jblas::vec const& y_, 
00477              jblas::sym_mat const& R_);
00478 
00479 
00480       friend std::ostream& operator <<(std::ostream& s, 
00481                const BlockExtendedKalmanFilter& f_);
00482 
00483     }; // class BlockExtendedKalmanFilter
00484 
00485     std::ostream& operator <<(std::ostream& s, 
00486             const BlockExtendedKalmanFilter& f_);
00487 
00488 #else // SWIG
00489     
00490     // we dont want to wrap those classes with swig, but we want swig
00491     // to be aware of the heritage relationship.
00492 
00493     class ExtendedKalmanFilter : public BaseKalmanFilter {};
00494 
00495     class ExtendedKalmanFilterImplicit : public ExtendedKalmanFilter {};
00496 
00497     class BlockExtendedKalmanFilter : public ExtendedKalmanFilter {};
00498 
00499 #endif // SWIG
00500 
00501   } // namespace filter
00502 } // namespace jafar
00503 
00504 #endif // FILTER_KALMAN_FILTER_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:19 for Jafar by doxygen 1.7.6.1
LAAS-CNRS