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