filter_base.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2014, 2015, 2016, Charles River Analytics, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * 1. Redistributions of source code must retain the above copyright
00010  * notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above
00012  * copyright notice, this list of conditions and the following
00013  * disclaimer in the documentation and/or other materials provided
00014  * with the distribution.
00015  * 3. Neither the name of the copyright holder nor the names of its
00016  * contributors may be used to endorse or promote products derived
00017  * from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00022  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00023  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00024  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00025  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00026  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00027  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00028  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00029  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00030  * POSSIBILITY OF SUCH DAMAGE.
00031  */
00032 
00033 #ifndef ROBOT_LOCALIZATION_FILTER_BASE_H
00034 #define ROBOT_LOCALIZATION_FILTER_BASE_H
00035 
00036 #include "robot_localization/filter_utilities.h"
00037 #include "robot_localization/filter_common.h"
00038 
00039 #include <Eigen/Dense>
00040 
00041 #include <algorithm>
00042 #include <limits>
00043 #include <map>
00044 #include <ostream>
00045 #include <queue>
00046 #include <set>
00047 #include <string>
00048 #include <vector>
00049 
00050 #include <boost/shared_ptr.hpp>
00051 
00052 namespace RobotLocalization
00053 {
00054 
00061 struct Measurement
00062 {
00063   // The topic name for this measurement. Needed
00064   // for capturing previous state values for new
00065   // measurements.
00066   std::string topicName_;
00067 
00068   // The measurement and its associated covariance
00069   Eigen::VectorXd measurement_;
00070   Eigen::MatrixXd covariance_;
00071 
00072   // This defines which variables within this measurement
00073   // actually get passed into the filter. std::vector<bool>
00074   // is generally frowned upon, so we use ints.
00075   std::vector<int> updateVector_;
00076 
00077   // The real-valued time, in seconds, since some epoch
00078   // (presumably the start of execution, but any will do)
00079   double time_;
00080 
00081   // The Mahalanobis distance threshold in number of sigmas
00082   double mahalanobisThresh_;
00083 
00084   // The most recent control vector (needed for lagged data)
00085   Eigen::VectorXd latestControl_;
00086 
00087   // The time stamp of the most recent control term (needed for lagged data)
00088   double latestControlTime_;
00089 
00090   // We want earlier times to have greater priority
00091   bool operator()(const boost::shared_ptr<Measurement> &a, const boost::shared_ptr<Measurement> &b)
00092   {
00093     return (*this)(*(a.get()), *(b.get()));
00094   }
00095 
00096   bool operator()(const Measurement &a, const Measurement &b)
00097   {
00098     return a.time_ > b.time_;
00099   }
00100 
00101   Measurement() :
00102     topicName_(""),
00103     latestControl_(),
00104     latestControlTime_(0.0),
00105     time_(0.0),
00106     mahalanobisThresh_(std::numeric_limits<double>::max())
00107   {
00108   }
00109 };
00110 typedef boost::shared_ptr<Measurement> MeasurementPtr;
00111 
00118 struct FilterState
00119 {
00120   // The filter state vector
00121   Eigen::VectorXd state_;
00122 
00123   // The filter error covariance matrix
00124   Eigen::MatrixXd estimateErrorCovariance_;
00125 
00126   // The most recent control vector
00127   Eigen::VectorXd latestControl_;
00128 
00129   // The time stamp of the most recent measurement for the filter
00130   double lastMeasurementTime_;
00131 
00132   // The time stamp of the most recent control term
00133   double latestControlTime_;
00134 
00135   // We want the queue to be sorted from latest to earliest timestamps.
00136   bool operator()(const FilterState &a, const FilterState &b)
00137   {
00138     return a.lastMeasurementTime_ < b.lastMeasurementTime_;
00139   }
00140 
00141   FilterState() :
00142     state_(),
00143     estimateErrorCovariance_(),
00144     latestControl_(),
00145     lastMeasurementTime_(0.0),
00146     latestControlTime_(0.0)
00147   {}
00148 };
00149 typedef boost::shared_ptr<FilterState> FilterStatePtr;
00150 
00151 class FilterBase
00152 {
00153   public:
00156     FilterBase();
00157 
00160     virtual ~FilterBase();
00161 
00164     void reset();
00165 
00172     void computeDynamicProcessNoiseCovariance(const Eigen::VectorXd &state, const double delta);
00173 
00179     virtual void correct(const Measurement &measurement) = 0;
00180 
00185     const Eigen::VectorXd& getControl();
00186 
00191     double getControlTime();
00192 
00197     bool getDebug();
00198 
00203     const Eigen::MatrixXd& getEstimateErrorCovariance();
00204 
00209     bool getInitializedStatus();
00210 
00215     double getLastMeasurementTime();
00216 
00222     double getLastUpdateTime();
00223 
00229     const Eigen::VectorXd& getPredictedState();
00230 
00235     const Eigen::MatrixXd& getProcessNoiseCovariance();
00236 
00241     double getSensorTimeout();
00242 
00247     const Eigen::VectorXd& getState();
00248 
00256     virtual void predict(const double referenceTime, const double delta) = 0;
00257 
00262     virtual void processMeasurement(const Measurement &measurement);
00263 
00269     void setControl(const Eigen::VectorXd &control, const double controlTime);
00270 
00280     void setControlParams(const std::vector<int> &updateVector, const double controlTimeout,
00281       const std::vector<double> &accelerationLimits, const std::vector<double> &accelerationGains,
00282       const std::vector<double> &decelerationLimits, const std::vector<double> &decelerationGains);
00283 
00294     void setDebug(const bool debug, std::ostream *outStream = NULL);
00295 
00300     void setUseDynamicProcessNoiseCovariance(const bool dynamicProcessNoiseCovariance);
00301 
00306     void setEstimateErrorCovariance(const Eigen::MatrixXd &estimateErrorCovariance);
00307 
00312     void setLastMeasurementTime(const double lastMeasurementTime);
00313 
00321     void setLastUpdateTime(const double lastUpdateTime);
00322 
00331     void setProcessNoiseCovariance(const Eigen::MatrixXd &processNoiseCovariance);
00332 
00338     void setSensorTimeout(const double sensorTimeout);
00339 
00344     void setState(const Eigen::VectorXd &state);
00345 
00350     void validateDelta(double &delta);
00351 
00352   protected:
00362     inline double computeControlAcceleration(const double state, const double control, const double accelerationLimit,
00363       const double accelerationGain, const double decelerationLimit, const double decelerationGain)
00364     {
00365       FB_DEBUG("---------- FilterBase::computeControlAcceleration ----------\n");
00366 
00367       const double error = control - state;
00368       const bool sameSign = (::fabs(error) <= ::fabs(control) + 0.01);
00369       const double setPoint = (sameSign ? control : 0.0);
00370       const bool decelerating = ::fabs(setPoint) < ::fabs(state);
00371       double limit = accelerationLimit;
00372       double gain = accelerationGain;
00373 
00374       if (decelerating)
00375       {
00376         limit = decelerationLimit;
00377         gain = decelerationGain;
00378       }
00379 
00380       const double finalAccel = std::min(std::max(gain * error, -limit), limit);
00381 
00382       FB_DEBUG("Control value: " << control << "\n" <<
00383                "State value: " << state << "\n" <<
00384                "Error: " << error << "\n" <<
00385                "Same sign: " << (sameSign ? "true" : "false") << "\n" <<
00386                "Set point: " << setPoint << "\n" <<
00387                "Decelerating: " << (decelerating ? "true" : "false") << "\n" <<
00388                "Limit: " << limit << "\n" <<
00389                "Gain: " << gain << "\n" <<
00390                "Final is " << finalAccel << "\n");
00391 
00392       return finalAccel;
00393     }
00394 
00397     virtual void wrapStateAngles();
00398 
00404     virtual bool checkMahalanobisThreshold(const Eigen::VectorXd &innovation,
00405                                            const Eigen::MatrixXd &invCovariance,
00406                                            const double nsigmas);
00407 
00412     void prepareControl(const double referenceTime, const double predictionDelta);
00413 
00416     std::vector<double> accelerationGains_;
00417 
00420     std::vector<double> accelerationLimits_;
00421 
00424     Eigen::VectorXd controlAcceleration_;
00425 
00428     std::vector<double> decelerationGains_;
00429 
00432     std::vector<double> decelerationLimits_;
00433 
00436     Eigen::VectorXd latestControl_;
00437 
00440     std::vector<int> controlUpdateVector_;
00441 
00444     double controlTimeout_;
00445 
00450     Eigen::MatrixXd covarianceEpsilon_;
00451 
00454     std::ostream *debugStream_;
00455 
00458     Eigen::MatrixXd dynamicProcessNoiseCovariance_;
00459 
00463     Eigen::MatrixXd estimateErrorCovariance_;
00464 
00467     Eigen::MatrixXd identity_;
00468 
00471     bool initialized_;
00472 
00478     double lastMeasurementTime_;
00479 
00489     double lastUpdateTime_;
00490 
00493     double latestControlTime_;
00494 
00497     Eigen::VectorXd predictedState_;
00498 
00509     Eigen::MatrixXd processNoiseCovariance_;
00510 
00516     double sensorTimeout_;
00517 
00521     Eigen::VectorXd state_;
00522 
00536     Eigen::MatrixXd transferFunction_;
00537 
00546     Eigen::MatrixXd transferFunctionJacobian_;
00547 
00550     bool useControl_;
00551 
00555     bool useDynamicProcessNoiseCovariance_;
00556 
00557   private:
00560     bool debug_;
00561 };
00562 
00563 }  // namespace RobotLocalization
00564 
00565 #endif  // ROBOT_LOCALIZATION_FILTER_BASE_H


robot_localization
Author(s): Tom Moore
autogenerated on Thu Jun 6 2019 21:01:48