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 #include "robot_localization/filter_base.h"
00034 #include "robot_localization/filter_common.h"
00035
00036 #include <iomanip>
00037 #include <iostream>
00038 #include <limits>
00039 #include <sstream>
00040 #include <vector>
00041
00042 namespace RobotLocalization
00043 {
00044 FilterBase::FilterBase() :
00045 accelerationGains_(TWIST_SIZE, 0.0),
00046 accelerationLimits_(TWIST_SIZE, 0.0),
00047 decelerationGains_(TWIST_SIZE, 0.0),
00048 decelerationLimits_(TWIST_SIZE, 0.0),
00049 controlAcceleration_(TWIST_SIZE),
00050 controlTimeout_(0.0),
00051 controlUpdateVector_(TWIST_SIZE, 0),
00052 dynamicProcessNoiseCovariance_(STATE_SIZE, STATE_SIZE),
00053 latestControlTime_(0.0),
00054 state_(STATE_SIZE),
00055 predictedState_(STATE_SIZE),
00056 transferFunction_(STATE_SIZE, STATE_SIZE),
00057 transferFunctionJacobian_(STATE_SIZE, STATE_SIZE),
00058 estimateErrorCovariance_(STATE_SIZE, STATE_SIZE),
00059 covarianceEpsilon_(STATE_SIZE, STATE_SIZE),
00060 processNoiseCovariance_(STATE_SIZE, STATE_SIZE),
00061 identity_(STATE_SIZE, STATE_SIZE),
00062 debug_(false),
00063 debugStream_(NULL),
00064 useControl_(false),
00065 useDynamicProcessNoiseCovariance_(false)
00066 {
00067 reset();
00068 }
00069
00070 FilterBase::~FilterBase()
00071 {
00072 }
00073
00074 void FilterBase::reset()
00075 {
00076 initialized_ = false;
00077
00078
00079 state_.setZero();
00080 predictedState_.setZero();
00081 controlAcceleration_.setZero();
00082
00083
00084
00085 transferFunction_.setIdentity();
00086
00087
00088 transferFunctionJacobian_.setZero();
00089
00090
00091
00092
00093 estimateErrorCovariance_.setIdentity();
00094 estimateErrorCovariance_ *= 1e-9;
00095
00096
00097 identity_.setIdentity();
00098
00099
00100
00101 covarianceEpsilon_.setIdentity();
00102 covarianceEpsilon_ *= 0.001;
00103
00104
00105 sensorTimeout_ = 0.033333333;
00106
00107
00108 lastUpdateTime_ = 0;
00109 lastMeasurementTime_ = 0;
00110
00111
00112
00113 processNoiseCovariance_.setZero();
00114 processNoiseCovariance_(StateMemberX, StateMemberX) = 0.05;
00115 processNoiseCovariance_(StateMemberY, StateMemberY) = 0.05;
00116 processNoiseCovariance_(StateMemberZ, StateMemberZ) = 0.06;
00117 processNoiseCovariance_(StateMemberRoll, StateMemberRoll) = 0.03;
00118 processNoiseCovariance_(StateMemberPitch, StateMemberPitch) = 0.03;
00119 processNoiseCovariance_(StateMemberYaw, StateMemberYaw) = 0.06;
00120 processNoiseCovariance_(StateMemberVx, StateMemberVx) = 0.025;
00121 processNoiseCovariance_(StateMemberVy, StateMemberVy) = 0.025;
00122 processNoiseCovariance_(StateMemberVz, StateMemberVz) = 0.04;
00123 processNoiseCovariance_(StateMemberVroll, StateMemberVroll) = 0.01;
00124 processNoiseCovariance_(StateMemberVpitch, StateMemberVpitch) = 0.01;
00125 processNoiseCovariance_(StateMemberVyaw, StateMemberVyaw) = 0.02;
00126 processNoiseCovariance_(StateMemberAx, StateMemberAx) = 0.01;
00127 processNoiseCovariance_(StateMemberAy, StateMemberAy) = 0.01;
00128 processNoiseCovariance_(StateMemberAz, StateMemberAz) = 0.015;
00129
00130 dynamicProcessNoiseCovariance_ = processNoiseCovariance_;
00131 }
00132
00133 void FilterBase::computeDynamicProcessNoiseCovariance(const Eigen::VectorXd &state, const double delta)
00134 {
00135
00136
00137
00138
00139
00140
00141
00142 Eigen::MatrixXd velocityMatrix(TWIST_SIZE, TWIST_SIZE);
00143 velocityMatrix.setIdentity();
00144 velocityMatrix.diagonal() *= state.segment(POSITION_V_OFFSET, TWIST_SIZE).norm();
00145
00146 dynamicProcessNoiseCovariance_.block<TWIST_SIZE, TWIST_SIZE>(POSITION_OFFSET, POSITION_OFFSET) =
00147 velocityMatrix *
00148 processNoiseCovariance_.block<TWIST_SIZE, TWIST_SIZE>(POSITION_OFFSET, POSITION_OFFSET) *
00149 velocityMatrix.transpose();
00150 }
00151
00152 const Eigen::VectorXd& FilterBase::getControl()
00153 {
00154 return latestControl_;
00155 }
00156
00157 double FilterBase::getControlTime()
00158 {
00159 return latestControlTime_;
00160 }
00161
00162 bool FilterBase::getDebug()
00163 {
00164 return debug_;
00165 }
00166
00167 const Eigen::MatrixXd& FilterBase::getEstimateErrorCovariance()
00168 {
00169 return estimateErrorCovariance_;
00170 }
00171
00172 bool FilterBase::getInitializedStatus()
00173 {
00174 return initialized_;
00175 }
00176
00177 double FilterBase::getLastMeasurementTime()
00178 {
00179 return lastMeasurementTime_;
00180 }
00181
00182 double FilterBase::getLastUpdateTime()
00183 {
00184 return lastUpdateTime_;
00185 }
00186
00187 const Eigen::VectorXd& FilterBase::getPredictedState()
00188 {
00189 return predictedState_;
00190 }
00191
00192 const Eigen::MatrixXd& FilterBase::getProcessNoiseCovariance()
00193 {
00194 return processNoiseCovariance_;
00195 }
00196
00197 double FilterBase::getSensorTimeout()
00198 {
00199 return sensorTimeout_;
00200 }
00201
00202 const Eigen::VectorXd& FilterBase::getState()
00203 {
00204 return state_;
00205 }
00206
00207 void FilterBase::processMeasurement(const Measurement &measurement)
00208 {
00209 FB_DEBUG("------ FilterBase::processMeasurement (" << measurement.topicName_ << ") ------\n");
00210
00211 double delta = 0.0;
00212
00213
00214
00215
00216 if (initialized_)
00217 {
00218
00219 delta = measurement.time_ - lastMeasurementTime_;
00220
00221 FB_DEBUG("Filter is already initialized. Carrying out predict/correct loop...\n"
00222 "Measurement time is " << std::setprecision(20) << measurement.time_ <<
00223 ", last measurement time is " << lastMeasurementTime_ << ", delta is " << delta << "\n");
00224
00225
00226
00227 if (delta > 0)
00228 {
00229 validateDelta(delta);
00230 predict(measurement.time_, delta);
00231
00232
00233 predictedState_ = state_;
00234 }
00235
00236 correct(measurement);
00237 }
00238 else
00239 {
00240 FB_DEBUG("First measurement. Initializing filter.\n");
00241
00242
00243 size_t measurementLength = measurement.updateVector_.size();
00244 for (size_t i = 0; i < measurementLength; ++i)
00245 {
00246 state_[i] = (measurement.updateVector_[i] ? measurement.measurement_[i] : state_[i]);
00247 }
00248
00249
00250 for (size_t i = 0; i < measurementLength; ++i)
00251 {
00252 for (size_t j = 0; j < measurementLength; ++j)
00253 {
00254 estimateErrorCovariance_(i, j) = (measurement.updateVector_[i] && measurement.updateVector_[j] ?
00255 measurement.covariance_(i, j) :
00256 estimateErrorCovariance_(i, j));
00257 }
00258 }
00259
00260 initialized_ = true;
00261 }
00262
00263 if (delta >= 0.0)
00264 {
00265
00266
00267
00268
00269
00270
00271
00272 lastMeasurementTime_ = measurement.time_;
00273 }
00274
00275 FB_DEBUG("------ /FilterBase::processMeasurement (" << measurement.topicName_ << ") ------\n");
00276 }
00277
00278 void FilterBase::setControl(const Eigen::VectorXd &control, const double controlTime)
00279 {
00280 latestControl_ = control;
00281 latestControlTime_ = controlTime;
00282 }
00283
00284 void FilterBase::setControlParams(const std::vector<int> &updateVector, const double controlTimeout,
00285 const std::vector<double> &accelerationLimits, const std::vector<double> &accelerationGains,
00286 const std::vector<double> &decelerationLimits, const std::vector<double> &decelerationGains)
00287 {
00288 useControl_ = true;
00289 controlUpdateVector_ = updateVector;
00290 controlTimeout_ = controlTimeout;
00291 accelerationLimits_ = accelerationLimits;
00292 accelerationGains_ = accelerationGains;
00293 decelerationLimits_ = decelerationLimits;
00294 decelerationGains_ = decelerationGains;
00295 }
00296
00297 void FilterBase::setDebug(const bool debug, std::ostream *outStream)
00298 {
00299 if (debug)
00300 {
00301 if (outStream != NULL)
00302 {
00303 debugStream_ = outStream;
00304 debug_ = true;
00305 }
00306 else
00307 {
00308 debug_ = false;
00309 }
00310 }
00311 else
00312 {
00313 debug_ = false;
00314 }
00315 }
00316
00317 void FilterBase::setUseDynamicProcessNoiseCovariance(const bool useDynamicProcessNoiseCovariance)
00318 {
00319 useDynamicProcessNoiseCovariance_ = useDynamicProcessNoiseCovariance;
00320 }
00321
00322 void FilterBase::setEstimateErrorCovariance(const Eigen::MatrixXd &estimateErrorCovariance)
00323 {
00324 estimateErrorCovariance_ = estimateErrorCovariance;
00325 }
00326
00327 void FilterBase::setLastMeasurementTime(const double lastMeasurementTime)
00328 {
00329 lastMeasurementTime_ = lastMeasurementTime;
00330 }
00331
00332 void FilterBase::setLastUpdateTime(const double lastUpdateTime)
00333 {
00334 lastUpdateTime_ = lastUpdateTime;
00335 }
00336
00337 void FilterBase::setProcessNoiseCovariance(const Eigen::MatrixXd &processNoiseCovariance)
00338 {
00339 processNoiseCovariance_ = processNoiseCovariance;
00340 dynamicProcessNoiseCovariance_ = processNoiseCovariance_;
00341 }
00342
00343 void FilterBase::setSensorTimeout(const double sensorTimeout)
00344 {
00345 sensorTimeout_ = sensorTimeout;
00346 }
00347
00348 void FilterBase::setState(const Eigen::VectorXd &state)
00349 {
00350 state_ = state;
00351 }
00352
00353 void FilterBase::validateDelta(double &delta)
00354 {
00355
00356 if (delta > 100000.0)
00357 {
00358 FB_DEBUG("Delta was very large. Suspect playing from bag file. Setting to 0.01\n");
00359
00360 delta = 0.01;
00361 }
00362 }
00363
00364
00365 void FilterBase::prepareControl(const double referenceTime, const double predictionDelta)
00366 {
00367 controlAcceleration_.setZero();
00368
00369 if (useControl_)
00370 {
00371 bool timedOut = ::fabs(referenceTime - latestControlTime_) >= controlTimeout_;
00372
00373 if (timedOut)
00374 {
00375 FB_DEBUG("Control timed out. Reference time was " << referenceTime << ", latest control time was " <<
00376 latestControlTime_ << ", control timeout was " << controlTimeout_ << "\n");
00377 }
00378
00379 for (size_t controlInd = 0; controlInd < TWIST_SIZE; ++controlInd)
00380 {
00381 if (controlUpdateVector_[controlInd])
00382 {
00383 controlAcceleration_(controlInd) = computeControlAcceleration(state_(controlInd + POSITION_V_OFFSET),
00384 (timedOut ? 0.0 : latestControl_(controlInd)), accelerationLimits_[controlInd],
00385 accelerationGains_[controlInd], decelerationLimits_[controlInd], decelerationGains_[controlInd]);
00386 }
00387 }
00388 }
00389 }
00390
00391 void FilterBase::wrapStateAngles()
00392 {
00393 state_(StateMemberRoll) = FilterUtilities::clampRotation(state_(StateMemberRoll));
00394 state_(StateMemberPitch) = FilterUtilities::clampRotation(state_(StateMemberPitch));
00395 state_(StateMemberYaw) = FilterUtilities::clampRotation(state_(StateMemberYaw));
00396 }
00397
00398 bool FilterBase::checkMahalanobisThreshold(const Eigen::VectorXd &innovation,
00399 const Eigen::MatrixXd &invCovariance,
00400 const double nsigmas)
00401 {
00402 double sqMahalanobis = innovation.dot(invCovariance * innovation);
00403 double threshold = nsigmas * nsigmas;
00404
00405 if (sqMahalanobis >= threshold)
00406 {
00407 FB_DEBUG("Innovation mahalanobis distance test failed. Squared Mahalanobis is: " << sqMahalanobis << "\n" <<
00408 "Threshold is: " << threshold << "\n" <<
00409 "Innovation is: " << innovation << "\n" <<
00410 "Innovation covariance is:\n" << invCovariance << "\n");
00411
00412 return false;
00413 }
00414
00415 return true;
00416 }
00417 }