Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 #ifndef KFCORE_HPP_
00035 #define KFCORE_HPP_
00036 #include <labust/navigation/KFBase.hpp>
00037 
00038 #include <vector>
00039 #include <cassert>
00040 
00042 #include <iostream>
00043 #include <ros/ros.h>
00044 
00045 namespace labust
00046 {
00047         namespace navigation
00048         {
00053                 template <class Model>
00054                 class KFCore : public KFBase< Model >
00055                 {
00056                         typedef KFBase< Model > Base;
00057                 public:
00061                         KFCore(){};
00062 
00068                         void predict(typename Base::inputref u = typename Model::input_type())
00069                         {
00070                                 assert((this->Ts) && "KFCore: Sampling time set to zero." );
00075                                 this->step(u);
00080                                 this->P = this->A*this->P*this->A.transpose() +
00081                                                 
00082                                                 this->W*this->Q*this->W.transpose();
00083                         }
00091                         typename Base::vectorref correct(typename Base::outputref y_meas)
00092                         {
00093                                 
00099                                 typename Base::matrix PH = this->P*this->H.transpose();
00100                                 this->innovationCov = this->H*PH;
00101                                 typename Base::matrix VR = this->V*this->R;
00102                                 
00103                                 this->innovationCov += VR*this->V.transpose();
00104                                 
00105                                 
00106                                 this->K = PH*this->innovationCov.ldlt().solve(
00107                                                                 Base::matrix::Identity(this->innovationCov.rows(),
00108                                                                                                 this->innovationCov.cols()));
00109                                 
00110 
00111 
00112 
00113 
00114                                 typename Base::output_type y;
00115                                 this->estimate_y(y);
00116                                 this->innovation = y_meas - y;
00117                                 this->x += this->K*this->innovation;
00122                                 typename Base::matrix IKH = Base::matrix::Identity(this->P.rows(), this->P.cols());
00123                                 IKH -= this->K*this->H;
00124                                 this->P = IKH*this->P;
00125 
00126                                 
00127 
00128                                 
00129 
00130                                 return this->xk_1 = this->x;
00131                         }
00132 
00140                         template <class NewMeasVector>
00141                         typename Base::vectorref correct(
00142                                         typename Base::outputref measurements,
00143                                         NewMeasVector& newMeas,
00144                                         bool reject_outliers = true)
00145                         {
00146                                 
00147                                 assert(measurements.size() == Model::stateNum &&
00148                                                 newMeas.size() == Model::stateNum);
00149 
00150                                 std::vector<size_t> arrived;
00151                                 std::vector<typename Model::numericprecission> dataVec;
00152 
00153                                 for (size_t i=0; i<newMeas.size(); ++i)
00154                                 {
00155                                         
00156                                         if (newMeas(i) && reject_outliers)
00157                                         {
00158                                                 double dist=fabs(this->x(i) - measurements(i));
00159                                                 newMeas(i) = (dist <= sqrt(this->P(i,i)) + sqrt(this->R0(i,i)));
00160 
00162                                                 if (!newMeas(i))
00163                                                 {
00164                                                         std::cerr<<"Outlier rejected: x(i)="<<this->x(i);
00165                                                         std::cerr<<", m(i)="<<measurements(i);
00166                                                         std::cerr<<", r(i)="<<sqrt(this->P(i,i)) + sqrt(this->R0(i,i));
00167                                                 }
00168                                         }
00169 
00170                                         if (newMeas(i))
00171                                         {
00172                                                 arrived.push_back(i);
00173                                                 dataVec.push_back(measurements(i));
00174                                                 newMeas(i) = 0;
00175                                         }
00176                                 }
00177 
00178                                 typename Base::output_type y_meas(arrived.size());
00179                                 this->H = Model::matrix::Zero(arrived.size(),Model::stateNum);
00180                                 this->V = Model::matrix::Zero(arrived.size(),Model::stateNum);
00181 
00182                                 for (size_t i=0; i<arrived.size();++i)
00183                                 {
00184                                         y_meas(i) = dataVec[i];
00185                                         this->H.row(i) = this->H0.row(arrived[i]);
00186                                         this->V.row(i) = this->V0.row(arrived[i]);
00187                                 }
00188 
00189                                 return this->correct(y_meas);
00190                         }
00191                 };
00192         };
00193 }
00194 
00195 #endif