Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
slamEkf.hpp
00001 /* $Id$ */
00002 
00003 #ifndef SLAM_SLAM_EKF_HPP
00004 #define SLAM_SLAM_EKF_HPP
00005 
00006 #include <string>
00007 #include <vector>
00008 #include <map>
00009 
00010 #include "kernel/jafarException.hpp"
00011 #include "kernel/timingTools.hpp"
00012 #include "kernel/dataLog.hpp"
00013 
00014 #include "jmath/jblas.hpp"
00015 
00016 #include "geom/t3dEuler.hpp"
00017 
00018 #include "filter/kalmanFilter.hpp"
00019 
00020 #include "slam/baseSlam.hpp"
00021 #include "slam/slamException.hpp"
00022 #include "slam/mapManager.hpp"
00023 #include "slam/feature.hpp"
00024 #include "slam/pointFeature.hpp"
00025 #include "slam/segmentFeature.hpp"
00026 #include "slam/segmentAnchorPluckerFeature.hpp"
00027 #include "slam/segmentInvDepthFeature.hpp"
00028 #include "slam/slamEvents.hpp"
00029 #include "slam/poseCopy.hpp"
00030 #include "slam/robot.hpp"
00031 
00032 namespace jafar {
00033   namespace slam {
00034     class BaseRobot;
00044     class SlamEkf : public BaseSlam, public jafar::kernel::DataLoggable {
00045 
00046     private:
00047 
00050       void initFeatureState(BaseFeature& feature, 
00051              FeatureObserveModel& observeModel,       
00052              Observation const& obs);
00053 
00054     protected:
00055       bool m_deleteSensors;
00056 
00057       unsigned int currentFrameIndex;
00058       unsigned int prevFrameIndex;
00059 
00060       jafar::filter::BlockExtendedKalmanFilter filter;      
00061 
00062       double mahalanobisDistanceToRemoveLandmark;
00063 
00064       std::size_t m_sizeRobotState;
00065       std::size_t m_sizeRobotPose;
00066 
00067 //       jblas::vec_range m_refPose;
00068 //       jblas::sym_mat_range m_refPoseCov;
00069 
00070       AbstractMapManager* mapManager;
00071 
00072       typedef std::list<SlamEventListener*> SlamEventListenersList;
00073       SlamEventListenersList slamEventListeners;
00074 
00076       bool enableInitCoordinateFrame; 
00077       
00078       typedef std::map<unsigned int, FeatureObserveModel*> FeatureObserveModelsContType;
00080       FeatureObserveModelsContType featureObserveModels;
00081 
00082       class Stats
00083       {
00084        public:
00085         double poseUncertaintyVolume;
00086         double mapUncertaintyLevel;
00087         int prevNbFoundLandmarks;
00088         int nbFoundLandmarks; // nbObservedLandmarks + nbInconsistentUpdates + nbNewLandmarks
00089         int nbLostLandmarks; // prevNbFoundLandmarks - (nbObservedLandmarks + nbInconsistentUpdates)
00090         int nbInconsistentLandmarks; // nbInconsistentUpdates
00091         int nbObservedLandmarks; // nbObservedLandmarks
00092         int nframes;
00093 
00094         Stats(): poseUncertaintyVolume(0), mapUncertaintyLevel(0), prevNbFoundLandmarks(0),
00095           nbFoundLandmarks(0), nbLostLandmarks(0), nbInconsistentLandmarks(0), nbObservedLandmarks(0),
00096           nframes(0) {}
00097       } stats;
00098 
00103       virtual void observeNewFeature(Observation* obs_);
00104       
00107       virtual void observeKnownFeature(Observation* obs_);
00108 
00111       void observeKnownFeature(Observation const& obs, BaseFeature& feature, BaseFeatureObserveModel& model);
00112 
00114       void applyConstraints(BaseFeature& feature);
00115 
00117       void fixFeature(BaseFeature& feature);
00118 
00119       //       void applyAllConstraints();
00120 
00122       void copyCurrentPoseAt(std::size_t index, int _robotId = 0);
00123 
00125       geom::T3D* m_refToRobot;
00126       geom::T3D* m_robotToRef;
00127 
00128       static BaseFeature* featureFactory(unsigned int id,
00129            BaseFeatureObserveModel& model);
00130       static BaseFeature* featureFactory(unsigned int id,
00131              FeatureModel& model, std::size_t sizeObs, Observation::ObservationType typeObs );
00132 
00133       void writePoseCopyToFile(PoseCopy const& pc, std::string const& dir);
00134 
00135       // for data logging
00136       unsigned short int nbInconsistentUpdates;
00137       unsigned short int nbNewLandmarks;
00138       unsigned short int nbObservedLandmarks;
00139       long updateElapsedTime;      
00140 
00141       virtual void writeLogHeader(jafar::kernel::DataLogger& log) const;
00142       virtual void writeLogData(jafar::kernel::DataLogger& log) const;
00143       virtual void writeLogStats(jafar::kernel::DataLogger& log) const;
00144 
00145       jafar::kernel::DataLogger* p_masterLogger;
00146 
00147       void logFeature(BaseFeature& f);
00148 
00149     public:
00150 
00151       typedef std::map<unsigned int, BaseFeature*> FeaturesMapType;
00153       FeaturesMapType featuresMap;
00154 
00155       typedef std::map<unsigned int, PoseCopy*> PoseCopyContType;
00157       PoseCopyContType poseCopyCont;
00158       
00159       typedef std::map<unsigned int, BaseRobot*> RobotsMapType;
00161       RobotsMapType robotsMap;
00162 
00164       SlamEkf(std::size_t sizeMax_, std::size_t sizeRobotState_, std::size_t sizeRobotPose_);
00165     private:
00166       SlamEkf(const SlamEkf& ) : filter(0,0) { JFR_ASSERT(false, "Copying SlamEkf is not legal."); }
00167       SlamEkf& operator=(const SlamEkf& ) { JFR_ASSERT(false, "Copying SlamEkf is not legal."); }
00168     public:
00170       virtual ~SlamEkf();
00171 
00173       virtual void init(boost::posix_time::time_duration const& curTime);
00174 
00176       std::size_t sizeRobotPose() const {return m_sizeRobotPose;}
00177     
00179       std::size_t sizeRobotState() const {return m_sizeRobotState;}
00180 
00182       jblas::vec_range const& refPose(int _robotId = 0) const;
00183     
00185       jblas::sym_mat_range const& refPoseCov(int _robotId = 0) const;
00186 
00187       void enableAutoLogFeatures(jafar::kernel::DataLogger& masterLogger) {p_masterLogger = &masterLogger;}
00188 
00190       jafar::filter::BlockExtendedKalmanFilter& getFilter() {return filter;};
00191     
00193       jafar::filter::BlockExtendedKalmanFilter const& getFilter() const {return filter;};
00194 
00196       FeaturesMapType const& getMap() const {return featuresMap;}
00197 
00198       jafar::geom::T3D const& refToRobot() const {return *m_refToRobot;}
00199       jafar::geom::T3D const& robotToRef() const {return *m_robotToRef ;}
00200       void setRefToRobot(jafar::geom::T3DEuler const& refToRobot_);
00201 
00202       void setRobotPose(jblas::vec const& robotPose, int _robotId = 0);
00203       void setRobotPoseCov(jblas::vec const& robotPose, jblas::sym_mat const& robotPoseCov, int _robotId = 0);
00204 
00205 //       BaseFeatureObserveModel& getBaseFeatureObserveModel(int sensorId) {
00206 //  BaseFeatureObserveModelsContType::iterator it = baseFeatureObserveModels.find(sensorId);
00207 //  JFR_PRED_ERROR(it != baseFeatureObserveModels.end(),
00208 //           SlamException,
00209 //           SlamException::UNKNOWN_SENSOR,
00210 //           "Unknown sensor: " << sensorId);
00211 //  return *(it->second);
00212 //       }
00213 
00214       FeatureObserveModel& getFeatureObserveModel(unsigned int sensorId = 0) const {
00215   FeatureObserveModelsContType::const_iterator it = featureObserveModels.find(sensorId);
00216     JFR_PRED_ERROR(it != featureObserveModels.end(),
00217            SlamException,
00218            SlamException::UNKNOWN_SENSOR,
00219            "Unknown sensor: " << sensorId);
00220   return *(it->second);
00221       }
00222 
00223        unsigned int getCurrentFrameIndex() const {return currentFrameIndex;}
00224        unsigned int getPrevFrameIndex() const {return prevFrameIndex;}
00225 
00226       void setMapManager(AbstractMapManager* mapManager_);
00227 
00232       void setDeleteSensors( bool );
00236       void setSensor(FeatureObserveModel* model, int sensorId = 0);
00237 
00238 //       void setRobotState(jblas::vec const& state_);
00239 
00240 //       void setRobotState(jblas::vec const& state_, jblas::vec const& stateCov_);
00241 
00242       void setRobotZ(double z, double zStdDev, int _robotId = 0);
00243 
00244       void setRobotPitch(double pitch, double pitchStdDev, int _robotId = 0);
00245 
00246       void setRobotRoll(double roll, double rollStdDev, int _robotId = 0);
00247 
00251       virtual void setRobotToSensor(jblas::vec const& robotToSensor, int sensorId = 0);
00252       const jblas::vec& robotToSensor( int sensorId = 0) const;
00253 
00257       virtual void setRobotToSensor(jblas::vec const& robotToSensor, jblas::vec const& robotToSensorStdDev, 
00258             int sensorId = 0);
00259 
00260       virtual void addEventListener(SlamEventListener& listener) {
00261         JFR_ASSERT( &listener != 0, "Can't add null listener");
00262   slamEventListeners.push_back(&listener);
00263   //JFR_DEBUG("SlamEkf::addEventListener: " << slamEventListeners.size() << " listeners");
00264       }
00265       
00266       virtual void removeEventListener(SlamEventListener& listener) {
00267         slamEventListeners.remove(&listener);
00268       }
00269 
00270       bool hasFeature(unsigned int id, unsigned int _robotId = 0) const {
00271         return featuresMap.find(id) != featuresMap.end();
00272       };
00273 
00274       virtual bool isFeatureKnown(unsigned int id) const {
00275         //JFR_DEBUG("id :" << id);
00276       return hasFeature(id);
00277       };
00278 
00279       //       virtual void addLandmarkManually(AbstractMapObject::IdType id_, Observation::ObservationType featureType_, 
00280       //               jblas::vec const& featureState_, jblas::sym_mat const& stateCov_);
00281 
00282       BaseFeature& getFeature(unsigned int id) {
00283   FeaturesMapType::const_iterator feature_it = featuresMap.find(id);
00284   if (feature_it != featuresMap.end())
00285     return *(feature_it->second);
00286   else
00287   {
00288     JFR_DEBUG( "SlamEkf::getFeature: unknown feature " << id );
00289     JFR_ERROR(SlamException, SlamException::UNKNOWN_FEATURE,
00290         "SlamEkf::getFeature: unknown feature " << id);
00291   }
00292       }
00293 
00294       BaseFeature const& getFeature(unsigned int id) const {
00295   FeaturesMapType::const_iterator feature_it = featuresMap.find(id);
00296   if (feature_it != featuresMap.end())
00297     return *(feature_it->second);
00298   else
00299     JFR_ERROR(SlamException, SlamException::UNKNOWN_FEATURE,
00300         "SlamEkf::getFeature: unknown feature " << id);
00301       }
00302 
00304       virtual void removeFeature(unsigned int id);
00305 
00309       PoseCopy const& copyCurrentRefPoseToMap(unsigned int id);
00310 
00313       PoseCopy const& getPoseCopy(unsigned int id) const {
00314   PoseCopyContType::const_iterator poseIt = poseCopyCont.find(id);
00315   if (poseIt != poseCopyCont.end())
00316     return *(poseIt->second);
00317   else
00318     JFR_ERROR(SlamException, SlamException::UNKNOWN_POSE_COPY,
00319         "SlamEkf::getPoseCopy: unknown pose copy " << id);
00320       }
00321 
00323       void removePoseCopy(unsigned int id);
00324 
00328       void writePoseCopyToFile(unsigned int id, std::string const& dir);
00329       void writeAllPoseCopyToFile(std::string const& dir);
00330 
00331       double getRobotPoseUncertaintyLevel(unsigned int robotId_ = 0) const;
00332 
00333       void getRobotPose(jafar::geom::T3DEuler& pose, unsigned int _robotId = 0) const {
00334   if (refToRobot().isIdentity()) {
00335     pose.set(refPose(_robotId), refPoseCov(_robotId));
00336   }
00337   else {
00338     geom::T3DEuler worldToRef(refPose(_robotId), refPoseCov(_robotId));
00339     geom::T3D::compose(worldToRef, refToRobot(), pose);
00340   }
00341       }
00342       
00347       void transform( const geom::T3DEuler& _transform );
00348 
00349 //       jblas::vec_range const& getRobotState() const {return robotState;}
00350 
00354       std::size_t sizeMap() const {return featuresMap.size();}
00355       double getMapUncertaintyLevel() const;
00356 
00357       // easy to use with swig/tcl
00358       FeaturesMapType::iterator browseFeaturesIt;
00359       void beginBrowseFeatures();
00360       bool hasNextFeature();
00361       BaseFeature* nextFeature();
00365       BaseFeature* feature( unsigned int id );
00366 
00372       virtual void predict(unsigned int _robotId, jblas::vec const& u);
00373       
00377       BaseRobot* robot( unsigned int _id );
00381       const BaseRobot* robot( unsigned int ) const;
00382       
00387       virtual void addRobot( BaseRobot* );
00388       virtual void addRobot( BaseRobot*, const jblas::vec& _robotState, const jblas::sym_mat& _robotStateCov );
00389     private:
00390       template<class SequenceType1, class SequenceType2>
00391       void processObservationsImpl(unsigned int frameIndex_,
00392               SequenceType1 const& knownObs,
00393               SequenceType2 const& newObs, unsigned int robotId_, int events_ ) 
00394       {
00395         nbInconsistentUpdates = 0;
00396         nbNewLandmarks = 0;
00397         nbObservedLandmarks = 0;
00398 
00399         if( frameIndex_ != currentFrameIndex )
00400         {
00401           prevFrameIndex = currentFrameIndex;
00402           currentFrameIndex = frameIndex_;
00403         }
00404         //JFR_DEBUG("RobotId:" << robotId_);
00405         if( (events_ & SlamEventListener::BEGIN_PROCESS_OBSERVATIONS) == SlamEventListener::BEGIN_PROCESS_OBSERVATIONS )
00406         {
00407           for(SlamEventListenersList::iterator it = slamEventListeners.begin() ; it != slamEventListeners.end() ; ++it) {
00408             (*it)->beginProcessObservations(robotId_);
00409           }
00410         }
00411 
00412         kernel::Chrono chrono;
00413 
00414         for (typename SequenceType1::const_iterator it = knownObs.begin() ; it != knownObs.end() ; ++it) {
00415           observeKnownFeature(*it);
00416         }
00417 
00418         for (typename SequenceType2::const_iterator it = newObs.begin() ; it != newObs.end() ; ++it) {
00419           observeNewFeature(*it);
00420         }
00421 
00422         //  applyAllConstraints();
00423 
00424         updateElapsedTime = chrono.elapsed();
00425 
00426         if( (events_ & SlamEventListener::END_PROCESS_OBSERVATIONS) == SlamEventListener::END_PROCESS_OBSERVATIONS )
00427         {
00428           for(SlamEventListenersList::iterator it = slamEventListeners.begin() ; it != slamEventListeners.end() ; ++it) {
00429             (**it).endProcessObservations(robotId_);
00430           }
00431         }
00432       }
00433     public:
00434         virtual void processObservations(unsigned int frameIndex_,
00435              std::list<Observation*> const& knownObs,
00436              std::list<Observation*> const& newObs, unsigned int robotId_ = 0, int events_ = SlamEventListener::ALL )
00437         {
00438           processObservationsImpl( frameIndex_, knownObs, newObs, robotId_, events_ );
00439         }
00440         virtual void processObservations(unsigned int frameIndex_,
00441              std::vector<Observation*> const& knownObs,
00442              std::vector<Observation*> const& newObs, unsigned int robotId_ = 0, int events_ = SlamEventListener::ALL )
00443         {
00444           processObservationsImpl( frameIndex_, knownObs, newObs, robotId_ , events_);
00445         }
00446 
00447       template<class SequenceType>
00448       void processObservations(unsigned int frameIndex_,
00449              SequenceType const& allObs, unsigned int robotId_ = 0, int events_ = SlamEventListener::ALL ) 
00450       {
00451 
00452       SequenceType knownObs;
00453       SequenceType newObs;
00454     
00455       for (typename SequenceType::const_iterator it = allObs.begin() ; it != allObs.end() ; ++it) {
00456       if ( isFeatureKnown((**it).id) )
00457           knownObs.push_back(*it);
00458       else
00459           newObs.push_back(*it);
00460       }
00461     
00462       processObservations(frameIndex_, knownObs, newObs, robotId_, events_);
00463 
00464       }
00465       
00471 
00628 
00631 
00636 
00644 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:28 for Jafar by doxygen 1.7.6.1
LAAS-CNRS