Main MRPT website > C++ reference
MRPT logo
CRangeBearingKFSLAM2D.h
Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                       http://www.mrpt.org/                                |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 #ifndef CRangeBearingKFSLAM2D_H
00029 #define CRangeBearingKFSLAM2D_H
00030 
00031 #include <mrpt/utils/CDebugOutputCapable.h>
00032 #include <mrpt/math/CMatrixTemplateNumeric.h>
00033 #include <mrpt/math/CVectorTemplate.h>
00034 #include <mrpt/utils/CConfigFileBase.h>
00035 #include <mrpt/utils/CLoadableOptions.h>
00036 #include <mrpt/opengl.h>
00037 #include <mrpt/bayes/CKalmanFilterCapable.h>
00038 
00039 #include <mrpt/utils/safe_pointers.h>
00040 #include <mrpt/utils/bimap.h>
00041 
00042 #include <mrpt/slam/CSensoryFrame.h>
00043 #include <mrpt/slam/CActionCollection.h>
00044 #include <mrpt/slam/CObservationBearingRange.h>
00045 #include <mrpt/poses/CPoint2D.h>
00046 #include <mrpt/poses/CPosePDFGaussian.h>
00047 #include <mrpt/slam/CLandmark.h>
00048 #include <mrpt/slam/CSimpleMap.h>
00049 #include <mrpt/slam/CIncrementalMapPartitioner.h>
00050 #include <mrpt/slam/data_association.h>
00051 
00052 #include <mrpt/slam/link_pragmas.h>
00053 
00054 namespace mrpt
00055 {
00056         namespace slam
00057         {
00058                 using namespace mrpt::bayes;
00059                 using namespace mrpt::poses;
00060 
00061                 /** An implementation of EKF-based SLAM with range-bearing sensors, odometry, and a 2D (+heading) robot pose, and 2D landmarks.
00062                   *  The main method is "processActionObservation" which processes pairs of action/observation.
00063                   *
00064                   *   The following pages describe front-end applications based on this class:
00065                   *             - http://www.mrpt.org/Application:2d-slam-demo
00066                   *             - http://www.mrpt.org/Application:kf-slam
00067                   *
00068                   * \sa CRangeBearingKFSLAM  \ingroup metric_slam_grp
00069                   */
00070                 class SLAM_IMPEXP  CRangeBearingKFSLAM2D :
00071                         public bayes::CKalmanFilterCapable<3 /* x y yaw */, 2 /* range yaw */, 2 /* x y */,      3 /* Ax Ay Ayaw */>
00072                                                        // <size_t VEH_SIZE, size_t OBS_SIZE,   size_t FEAT_SIZE, size_t ACT_SIZE, size typename kftype = double>
00073                 {
00074                  public:
00075                          CRangeBearingKFSLAM2D( ); //!< Default constructor
00076                          virtual ~CRangeBearingKFSLAM2D();      //!< Destructor
00077                          void reset(); //!< Reset the state of the SLAM filter: The map is emptied and the robot put back to (0,0,0).
00078 
00079                         /** Process one new action and observations to update the map and robot pose estimate. See the description of the class at the top of this page.
00080                          *  \param action May contain odometry
00081                          *      \param SF The set of observations, must contain at least one CObservationBearingRange
00082                          */
00083                         void  processActionObservation(
00084                                 CActionCollectionPtr &action,
00085                                 CSensoryFramePtr     &SF );
00086 
00087                         /** Returns the complete mean and cov.
00088                           *  \param out_robotPose The mean & 3x3 covariance matrix of the robot 2D pose
00089                           *  \param out_landmarksPositions One entry for each of the M landmark positions (2D).
00090                           *  \param out_landmarkIDs Each element[index] (for indices of out_landmarksPositions) gives the corresponding landmark ID.
00091                           *  \param out_fullState The complete state vector (3+2M).
00092                           *  \param out_fullCovariance The full (3+2M)x(3+2M) covariance matrix of the filter.
00093                           * \sa getCurrentRobotPose
00094                           */
00095                         void  getCurrentState(
00096                                 CPosePDFGaussian &out_robotPose,
00097                                 std::vector<TPoint2D>  &out_landmarksPositions,
00098                                 std::map<unsigned int,CLandmark::TLandmarkID> &out_landmarkIDs,
00099                                 CVectorDouble      &out_fullState,
00100                                 CMatrixDouble      &out_fullCovariance
00101                                 ) const;
00102 
00103                         /** Returns the mean & 3x3 covariance matrix of the robot 2D pose.
00104                           * \sa getCurrentState
00105                           */
00106                         void  getCurrentRobotPose(
00107                                 CPosePDFGaussian &out_robotPose ) const;
00108 
00109                         /** Returns a 3D representation of the landmarks in the map and the robot 3D position according to the current filter state.
00110                           *  \param out_objects
00111                           */
00112                         void  getAs3DObject( mrpt::opengl::CSetOfObjectsPtr     &outObj ) const;
00113 
00114                         /** Load options from a ini-like file/text
00115                           */
00116                         void loadOptions( const mrpt::utils::CConfigFileBase &ini );
00117 
00118                         /** The options for the algorithm
00119                           */
00120                         struct SLAM_IMPEXP TOptions : utils::CLoadableOptions
00121                         {
00122                                 /** Default values
00123                                   */
00124                                 TOptions();
00125 
00126                                 /** Load from a config file/text
00127                                   */
00128                                 void loadFromConfigFile(
00129                                         const mrpt::utils::CConfigFileBase      &source,
00130                                         const std::string               &section);
00131 
00132                                 /** This method must display clearly all the contents of the structure in textual form, sending it to a CStream.
00133                                 */
00134                                 void  dumpToTextStream(CStream  &out) const;
00135 
00136 
00137                                 vector_float    stds_Q_no_odo;  //!< A 3-length vector with the std. deviation of the transition model in (x,y,phi) used only when there is no odometry (if there is odo, its uncertainty values will be used instead); x y: In meters, phi: radians (but in degrees when loading from a configuration ini-file!)
00138                                 float                   std_sensor_range, std_sensor_yaw;       //!< The std. deviation of the sensor (for the matrix R in the kalman filters), in meters and radians.
00139                                 float                   quantiles_3D_representation;    //!< Default = 3
00140                                 bool                    create_simplemap; //!< Whether to fill m_SFs (default=false)
00141 
00142                                 // Data association:
00143                                 TDataAssociationMethod  data_assoc_method;
00144                                 TDataAssociationMetric  data_assoc_metric;
00145                                 double                                  data_assoc_IC_chi2_thres;  //!< Threshold in [0,1] for the chi2square test for individual compatibility between predictions and observations (default: 0.99)
00146                                 TDataAssociationMetric  data_assoc_IC_metric;      //!< Whether to use mahalanobis (->chi2 criterion) vs. Matching likelihood.
00147                                 double                                  data_assoc_IC_ml_threshold;//!< Only if data_assoc_IC_metric==ML, the log-ML threshold (Default=0.0)
00148 
00149                         };
00150 
00151                         TOptions options; //!< The options for the algorithm
00152 
00153 
00154                         /** Save the current state of the filter (robot pose & map) to a MATLAB script which displays all the elements in 2D
00155                           */
00156                         void saveMapAndPath2DRepresentationAsMATLABFile(
00157                                 const std::string &fil,
00158                                 float              stdCount=3.0f,
00159                                 const std::string &styleLandmarks = std::string("b"),
00160                                 const std::string &stylePath = std::string("r"),
00161                                 const std::string &styleRobot = std::string("r") ) const;
00162 
00163 
00164                         /** Information for data-association:
00165                           * \sa getLastDataAssociation
00166                           */
00167                         struct SLAM_IMPEXP TDataAssocInfo
00168                         {
00169                                 TDataAssocInfo() :
00170                                         Y_pred_means(0,0),
00171                                         Y_pred_covs(0,0)
00172                                 {
00173                                 }
00174 
00175                                 void clear() {
00176                                         results.clear();
00177                                         predictions_IDs.clear();
00178                                         newly_inserted_landmarks.clear();
00179                                 }
00180 
00181                                 // Predictions from the map:
00182                                 CMatrixTemplateNumeric<kftype>  Y_pred_means,Y_pred_covs;
00183                                 mrpt::vector_size_t                             predictions_IDs;
00184 
00185                                 /** Map from the 0-based index within the last observation and the landmark 0-based index in the map (the robot-map state vector)
00186                                     Only used for stats and so. */
00187                                 std::map<size_t,size_t>  newly_inserted_landmarks;
00188 
00189                                 // DA results:
00190                                 TDataAssociationResults                 results;
00191                         };
00192 
00193                         /** Returns a read-only reference to the information on the last data-association */
00194                         const TDataAssocInfo & getLastDataAssociation() const {
00195                                 return m_last_data_association;
00196                         }
00197 
00198                  protected:
00199 
00200                         /** @name Virtual methods for Kalman Filter implementation
00201                                 @{
00202                          */
00203 
00204                         /** Must return the action vector u.
00205                           * \param out_u The action vector which will be passed to OnTransitionModel
00206                           */
00207                         void OnGetAction( KFArray_ACT &out_u ) const;
00208 
00209                         /** Implements the transition model \f$ \hat{x}_{k|k-1} = f( \hat{x}_{k-1|k-1}, u_k ) \f$
00210                           * \param in_u The vector returned by OnGetAction.
00211                           * \param inout_x At input has \f[ \hat{x}_{k-1|k-1} \f] , at output must have \f$ \hat{x}_{k|k-1} \f$ .
00212                           * \param out_skip Set this to true if for some reason you want to skip the prediction step (to do not modify either the vector or the covariance). Default:false
00213                           */
00214                         void OnTransitionModel(
00215                                 const KFArray_ACT &in_u,
00216                                 KFArray_VEH       &inout_x,
00217                                 bool &out_skipPrediction
00218                                 ) const;
00219 
00220                         /** Implements the transition Jacobian \f$ \frac{\partial f}{\partial x} \f$
00221                           * \param out_F Must return the Jacobian.
00222                           *  The returned matrix must be \f$V \times V\f$ with V being either the size of the whole state vector (for non-SLAM problems) or VEH_SIZE (for SLAM problems).
00223                           */
00224                         void OnTransitionJacobian( KFMatrix_VxV  &out_F ) const;
00225 
00226                         /** Only called if using a numeric approximation of the transition Jacobian, this method must return the increments in each dimension of the vehicle state vector while estimating the Jacobian.
00227                           */
00228                         void OnTransitionJacobianNumericGetIncrements(KFArray_VEH &out_increments) const;
00229 
00230 
00231                         /** Implements the transition noise covariance \f$ Q_k \f$
00232                           * \param out_Q Must return the covariance matrix.
00233                           *  The returned matrix must be of the same size than the jacobian from OnTransitionJacobian
00234                           */
00235                         void OnTransitionNoise( KFMatrix_VxV &out_Q ) const;
00236 
00237                         /** This is called between the KF prediction step and the update step, and the application must return the observations and, when applicable, the data association between these observations and the current map.
00238                           *
00239                           * \param out_z N vectors, each for one "observation" of length OBS_SIZE, N being the number of "observations": how many observed landmarks for a map, or just one if not applicable.
00240                           * \param out_data_association An empty vector or, where applicable, a vector where the i'th element corresponds to the position of the observation in the i'th row of out_z within the system state vector (in the range [0,getNumberOfLandmarksInTheMap()-1]), or -1 if it is a new map element and we want to insert it at the end of this KF iteration.
00241                           * \param in_S The full covariance matrix of the observation predictions (i.e. the "innovation covariance matrix"). This is a M·O x M·O matrix with M=length of "in_lm_indices_in_S".
00242                           * \param in_lm_indices_in_S The indices of the map landmarks (range [0,getNumberOfLandmarksInTheMap()-1]) that can be found in the matrix in_S.
00243                           *
00244                           *  This method will be called just once for each complete KF iteration.
00245                           * \note It is assumed that the observations are independent, i.e. there are NO cross-covariances between them.
00246                           */
00247                         void OnGetObservationsAndDataAssociation(
00248                                 vector_KFArray_OBS    &out_z,
00249                                 vector_int                  &out_data_association,
00250                                 const vector_KFArray_OBS   &in_all_predictions,
00251                                 const KFMatrix              &in_S,
00252                                 const vector_size_t         &in_lm_indices_in_S,
00253                                 const KFMatrix_OxO          &in_R
00254                                 );
00255 
00256                         void OnObservationModel(
00257                                 const vector_size_t       &idx_landmarks_to_predict,
00258                                 vector_KFArray_OBS  &out_predictions
00259                                 ) const;
00260 
00261                         /** Implements the observation Jacobians \f$ \frac{\partial h_i}{\partial x} \f$ and (when applicable) \f$ \frac{\partial h_i}{\partial y_i} \f$.
00262                           * \param idx_landmark_to_predict The index of the landmark in the map whose prediction is expected as output. For non SLAM-like problems, this will be zero and the expected output is for the whole state vector.
00263                           * \param Hx  The output Jacobian \f$ \frac{\partial h_i}{\partial x} \f$.
00264                           * \param Hy  The output Jacobian \f$ \frac{\partial h_i}{\partial y_i} \f$.
00265                           */
00266                         void OnObservationJacobians(
00267                                 const size_t &idx_landmark_to_predict,
00268                                 KFMatrix_OxV &Hx,
00269                                 KFMatrix_OxF &Hy
00270                                 ) const;
00271 
00272                         /** Only called if using a numeric approximation of the observation Jacobians, this method must return the increments in each dimension of the vehicle state vector while estimating the Jacobian.
00273                           */
00274                         void OnObservationJacobiansNumericGetIncrements(
00275                                         KFArray_VEH  &out_veh_increments,
00276                                         KFArray_FEAT &out_feat_increments ) const;
00277 
00278 
00279                         /** Computes A=A-B, which may need to be re-implemented depending on the topology of the individual scalar components (eg, angles).
00280                           */
00281                         void OnSubstractObservationVectors(KFArray_OBS &A, const KFArray_OBS &B) const;
00282 
00283                         /** Return the observation NOISE covariance matrix, that is, the model of the Gaussian additive noise of the sensor.
00284                           * \param out_R The noise covariance matrix. It might be non diagonal, but it'll usually be.
00285                           */
00286                         void OnGetObservationNoise(KFMatrix_OxO &out_R) const;
00287 
00288                         /** This will be called before OnGetObservationsAndDataAssociation to allow the application to reduce the number of covariance landmark predictions to be made.
00289                           *  For example, features which are known to be "out of sight" shouldn't be added to the output list to speed up the calculations.
00290                           * \param in_all_prediction_means The mean of each landmark predictions; the computation or not of the corresponding covariances is what we're trying to determined with this method.
00291                           * \param out_LM_indices_to_predict The list of landmark indices in the map [0,getNumberOfLandmarksInTheMap()-1] that should be predicted.
00292                           * \note This is not a pure virtual method, so it should be implemented only if desired. The default implementation returns a vector with all the landmarks in the map.
00293                           * \sa OnGetObservations, OnDataAssociation
00294                           */
00295                         void OnPreComputingPredictions(
00296                                 const vector_KFArray_OBS        &in_all_prediction_means,
00297                                 vector_size_t                           &out_LM_indices_to_predict ) const;
00298 
00299                         /** If applicable to the given problem, this method implements the inverse observation model needed to extend the "map" with a new "element".
00300                           * \param in_z The observation vector whose inverse sensor model is to be computed. This is actually one of the vector<> returned by OnGetObservations().
00301                           * \param out_yn The F-length vector with the inverse observation model \f$ y_n=y(x,z_n) \f$.
00302                           * \param out_dyn_dxv The \f$F \times V\f$ Jacobian of the inv. sensor model wrt the robot pose \f$ \frac{\partial y_n}{\partial x_v} \f$.
00303                           * \param out_dyn_dhn The \f$F \times O\f$ Jacobian of the inv. sensor model wrt the observation vector \f$ \frac{\partial y_n}{\partial h_n} \f$.
00304                           *
00305                           *  - O: OBS_SIZE
00306                           *  - V: VEH_SIZE
00307                           *  - F: FEAT_SIZE
00308                           *
00309                           * \note OnNewLandmarkAddedToMap will be also called after calling this method if a landmark is actually being added to the map.
00310                           */
00311                         void  OnInverseObservationModel(
00312                                 const KFArray_OBS & in_z,
00313                                 KFArray_FEAT  & out_yn,
00314                                 KFMatrix_FxV  & out_dyn_dxv,
00315                                 KFMatrix_FxO  & out_dyn_dhn ) const;
00316 
00317                         /** If applicable to the given problem, do here any special handling of adding a new landmark to the map.
00318                           * \param in_obsIndex The index of the observation whose inverse sensor is to be computed. It corresponds to the row in in_z where the observation can be found.
00319                           * \param in_idxNewFeat The index that this new feature will have in the state vector (0:just after the vehicle state, 1: after that,...). Save this number so data association can be done according to these indices.
00320                           * \sa OnInverseObservationModel
00321                           */
00322                         void OnNewLandmarkAddedToMap(
00323                                 const size_t    in_obsIdx,
00324                                 const size_t    in_idxNewFeat );
00325 
00326 
00327                         /** This method is called after the prediction and after the update, to give the user an opportunity to normalize the state vector (eg, keep angles within -pi,pi range) if the application requires it.
00328                           */
00329                         void OnNormalizeStateVector();
00330 
00331                         /** @}
00332                          */
00333 
00334 
00335                         void getLandmarkIDsFromIndexInStateVector(std::map<unsigned int,CLandmark::TLandmarkID>  &out_id2index) const
00336                         {
00337                                 out_id2index = m_IDs.getInverseMap();
00338                         }
00339 
00340                 protected:
00341 
00342                         /** Set up by processActionObservation
00343                           */
00344                         CActionCollectionPtr    m_action;
00345 
00346                         /** Set up by processActionObservation
00347                           */
00348                         CSensoryFramePtr                m_SF;
00349 
00350                         /** The mapping between landmark IDs and indexes in the Pkk cov. matrix:
00351                           */
00352                         mrpt::utils::bimap<CLandmark::TLandmarkID,unsigned int> m_IDs;
00353 
00354                         /** The sequence of all the observations and the robot path (kept for debugging, statistics,etc)
00355                           */
00356                         CSimpleMap      m_SFs;
00357 
00358                         TDataAssocInfo m_last_data_association; //!< Last data association
00359 
00360 
00361                 }; // end class
00362         } // End of namespace
00363 } // End of namespace
00364 
00365 #endif



Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011