00001
00002
00003 #ifndef _MULTI_MAPS_MANAGER_HPP_
00004 #define _MULTI_MAPS_MANAGER_HPP_
00005
00006 #include <kernel/dataLog.hpp>
00007 #include <geom/t3dEuler.hpp>
00008 #include <slam/slamEkf.hpp>
00009 #include <slam/robot.hpp>
00010 #include <slam/baseSlam.hpp>
00011 #include <slam/MapManagerFactory.hpp>
00012
00013 #include "slammm/StartNewMapStrategy.hpp"
00014 #include "slammm/MergeMapsStrategy.hpp"
00015
00016 namespace jafar {
00017 namespace slammm {
00018 class StartNewMapStrategy;
00019 class MultiMapsSlam;
00020 class MapsPoseManager;
00021 class MultiMapEventListener;
00022
00026 class MultiMapsSlam : public slam::BaseSlam, public kernel::DataLoggable {
00027 typedef std::map<unsigned int, slam::FeatureObserveModel*> FeatureObserveModelsContType;
00028 public:
00032 MultiMapsSlam(std::size_t sizeMax_, MapsPoseManager* _mapsPoseManager, StartNewMapStrategy* _startNewMapStrategy, MergeMapsStrategy* _mergeMapsStrategy, slam::MapManagerFactory* mapManagerFactory = 0, int firstMapId = 0 );
00033 ~MultiMapsSlam();
00034 private:
00038 template<class SequenceType1, class SequenceType2>
00039 void processObservationsImpl(unsigned int frameIndex_,
00040 SequenceType1 const& knownObs,
00041 SequenceType2 const& newObs, unsigned int _robotId, int events_ );
00042 public:
00046 void mergeMap( unsigned int _map1Id, unsigned int _map2Id, const geom::T3DEuler& transfo );
00050 slam::SlamEkf* getCurrentMap( unsigned int _robotId = 0 );
00051 const slam::SlamEkf* getCurrentMap( unsigned int _robotId = 0 ) const;
00055 slam::SlamEkf* getMap( unsigned int _mapId, unsigned int _robotId = 0 );
00056
00060 unsigned int mapId( slam::SlamEkf* ) const;
00061
00065 void getWorldRobotPose(jafar::geom::T3DEuler& pose, unsigned int _robotId = 0 ) const;
00066 jafar::geom::T3DEuler getWorldRobotPose( unsigned int _robotId = 0 ) const;
00067
00071 void getWorldFeatureState(jblas::vec& _result , unsigned int _featureId, unsigned int _currentMapId ) const;
00075 void getWorldFeatureState(jblas::vec& _result, jblas::sym_mat& _resultCov, unsigned int _featureId, unsigned int _currentMapId ) const;
00079 jafar::geom::T3DEuler getWorldToCurrentMapTransformation( unsigned int _robotId = 0 ) const;
00084 jafar::geom::T3DEuler getWorldToMapTransformation( unsigned int _mapId ) const;
00085
00086 void beginBrowseMaps();
00087 bool hasNextMap();
00088 slam::SlamEkf* nextMap();
00089
00090 const std::map< unsigned int, slam::SlamEkf*> getMaps() const;
00091
00096 slam::SlamEkf* getGlobalMap( ) const;
00097 void addRobot( slam::BaseRobot* );
00098 void addRobot( slam::BaseRobot*, const jblas::vec& _robotState, const jblas::sym_mat& _robotStateCov );
00099 void setSensor(slam::FeatureObserveModel* model, unsigned int sensorId, unsigned int _robotId );
00100 void setRobotToSensor(jblas::vec const& robotToSensor, int sensorId, unsigned int _robotId );
00101
00102 virtual void predict(unsigned int _robotId, jblas::vec const& u);
00103 virtual bool hasFeature(unsigned int id, unsigned int _robotId = 0) const;
00104 virtual void getRobotPose(jafar::geom::T3DEuler& pose, unsigned int _robotId = 0) const;
00105 virtual void removeFeature(unsigned int id);
00106 virtual void addEventListener(slam::SlamEventListener& listener);
00107 virtual void removeEventListener(slam::SlamEventListener& listener);
00108 virtual void processObservations(unsigned int frameIndex_,
00109 std::list<slam::Observation*> const& knownObs,
00110 std::list<slam::Observation*> const& newObs, unsigned int robotId_ = 0, int events_ = slam::SlamEventListener::ALL );
00111 virtual void processObservations(unsigned int frameIndex_,
00112 std::vector<slam::Observation*> const& knownObs,
00113 std::vector<slam::Observation*> const& newObs, unsigned int robotId_ = 0, int events_ = slam::SlamEventListener::ALL );
00114 template<typename SequenceType>
00115 void processObservations(unsigned int frameIndex_,
00116 SequenceType const& allObs, unsigned int robotId_ = 0, int events_ = slam::SlamEventListener::ALL );
00117 public:
00118
00125 void rendezVous( unsigned int _firstRobotId, unsigned int _secondRobotId, const geom::T3DEuler& firstToSecond );
00131 void gpsFix( const std::map<unsigned int, geom::T3DEuler>& worldToRobots );
00137 void gpsFix( unsigned int _robotId, const geom::T3DEuler& worldToRobot );
00141 void closeLoop( unsigned int _firstMapId, unsigned int _secondMapId, const geom::T3DEuler& firstToSecond );
00142 bool canCloseLoop( unsigned int _firstMapId, unsigned int _secondMapId) const;
00143 public:
00144 virtual void writeLogHeader(kernel::DataLogger& log) const;
00145 virtual void writeLogData(kernel::DataLogger& log) const;
00146 virtual void addMembersToLog(kernel::DataLogger& log) const;
00150 void setEventsDataLogger( kernel::DataLogger* log );
00151 public:
00152 void addEventListener( MultiMapEventListener* listener );
00153 void removeEventListener( MultiMapEventListener* listener );
00154 public:
00158 void printInfo();
00159 private:
00160 struct RobotMaps;
00161 void initNewMap( unsigned int _robotId);
00162 void startNewMap( RobotMaps& );
00163 public:
00167 void startNewMap( unsigned int _robotId);
00168 private:
00172 void updateCacheWorldToCurrentMap();
00173 private:
00174 struct RobotMaps {
00175 RobotMaps( ) : currentMapId(-1), currentMap(0), baseRobot(0)
00176 {
00177 }
00178 unsigned int currentMapId;
00179 slam::SlamEkf* currentMap;
00180 std::map< unsigned int, slam::SlamEkf*> maps;
00181 jafar::geom::T3DEuler worldToCurrentMap;
00182 slam::BaseRobot* baseRobot;
00184 FeatureObserveModelsContType featureObserveModels;
00185 std::map<int, jblas::vec> robotToSensors;
00186 };
00187 int nextMapId;
00189 struct SlamEkfInfo {
00190 slam::SlamEkf* slamEkf;
00195 std::map< unsigned int, unsigned int > robotPositionAge;
00196 };
00197 std::map< unsigned int, SlamEkfInfo> m_maps;
00198 std::map<unsigned int, RobotMaps> m_robotMaps;
00199 MapsPoseManager* m_mapsPoseManager;
00200 StartNewMapStrategy* m_startNewMapStrategy;
00201 MergeMapsStrategy* m_mergeMapsStrategy;
00202 slam::MapManagerFactory* m_mapManagerFactory;
00203 std::size_t m_sizeMax;
00204 std::list<unsigned int > m_sensorsIds;
00205 std::list<slam::SlamEventListener*> m_listeners;
00206 std::map< unsigned int, SlamEkfInfo>::iterator browseFeaturesIt;
00207 kernel::DataLogger* m_eventsLogger;
00208 unsigned int m_frameIndex;
00209 std::list<MultiMapEventListener*> m_eventListners;
00210 };
00211 template<class SequenceType1, class SequenceType2>
00212 void MultiMapsSlam::processObservationsImpl(unsigned int frameIndex_,
00213 SequenceType1 const& knownObs,
00214 SequenceType2 const& newObs, unsigned int _robotId, int events_ )
00215 {
00216
00217 std::map<unsigned int, RobotMaps>::iterator it = m_robotMaps.find( _robotId );
00218 JFR_ASSERT( it != m_robotMaps.end(), "No robot " << _robotId );
00219 bool newmap = m_startNewMapStrategy->startNewMap( *it->second.currentMap, _robotId, newObs.size() );
00220 if(newmap)
00221 {
00222 m_mergeMapsStrategy->decideMergeMap( it->second.currentMapId, it->second.currentMap );
00223 startNewMap( it->second );
00224 SequenceType2 obses;
00225 for(typename SequenceType1::const_iterator it2 = knownObs.begin(); it2 != knownObs.end(); ++it2)
00226 {
00227 obses.push_back(*it2);
00228 }
00229 for(typename SequenceType2::const_iterator it2 = newObs.begin(); it2 != newObs.end(); ++it2)
00230 {
00231 obses.push_back(*it2);
00232 }
00233 it->second.currentMap->processObservations( frameIndex_, SequenceType1(), obses, _robotId, events_ );
00234 } else {
00235
00236 it->second.currentMap->processObservations( frameIndex_, knownObs, newObs, _robotId, events_ );
00237 }
00238
00239 JFR_DEBUG( "================================== Nb of features = " << it->second.currentMap->featuresMap.size() << " new obs = " << newObs.size());
00240 }
00241
00242 template<class SequenceType>
00243 void MultiMapsSlam::processObservations(unsigned int frameIndex_, SequenceType const& allObs, unsigned int _robotId, int events_ )
00244 {
00245 m_frameIndex = frameIndex_;
00246
00247 std::map<unsigned int, RobotMaps>::iterator itRobot = m_robotMaps.find( _robotId );
00248 JFR_ASSERT( itRobot != m_robotMaps.end(), "No robot " << _robotId );
00249
00250 SequenceType knownObs;
00251 SequenceType newObs;
00252
00253 for (typename SequenceType::const_iterator it = allObs.begin() ; it != allObs.end() ; ++it) {
00254 if ( itRobot->second.currentMap->isFeatureKnown((**it).id) )
00255 knownObs.push_back(*it);
00256 else
00257 newObs.push_back(*it);
00258 }
00259
00260 processObservations(frameIndex_, knownObs, newObs, _robotId, events_);
00261
00262 }
00263 }
00264 }
00265
00266 #endif