00001
00002
00003 #ifndef SLAM_BEARING_ONLY_SLAM_HPP
00004 #define SLAM_BEARING_ONLY_SLAM_HPP
00005
00006 #include <string>
00007 #include <map>
00008 #include <vector>
00009 #include <list>
00010 #include <set>
00011
00012 #include "kernel/jafarException.hpp"
00013
00014 #include "jmath/jblas.hpp"
00015
00016 #include "slam/slamEkf.hpp"
00017 #include "slam/bearingOnlyFeature.hpp"
00018 #include "slam/slamEvents.hpp"
00019
00020 namespace jafar {
00021 namespace slam {
00022
00023 class KarmaManager;
00024
00029 class TrajectoryPoseRecord {
00030 public:
00031
00032 TrajectoryPoseRecord(unsigned int frameIndex_, unsigned int robotId_, std::size_t trajIndex_) :
00033 frameIndex(frameIndex_),
00034 robotId(robotId_),
00035 trajIndex(trajIndex_),
00036 initFeatures(),
00037 obsFeatures()
00038 {}
00039
00040 unsigned int frameIndex;
00041
00042 unsigned int robotId;
00043
00044 std::size_t trajIndex;
00045
00046 typedef std::set<unsigned int> FeaturesIdType;
00047
00048 FeaturesIdType initFeatures;
00049 FeaturesIdType obsFeatures;
00050
00051 unsigned int distanceToPrevious;
00052
00053 };
00054
00055 std::ostream& operator <<(std::ostream& s, TrajectoryPoseRecord const& tpr);
00056
00062 bool operator< (TrajectoryPoseRecord const& p1, TrajectoryPoseRecord const& p2);
00063
00064 struct TrajectoryPoseRecordKey {
00065 TrajectoryPoseRecordKey(unsigned int frameIndex_, unsigned int robotId_) :
00066 frameIndex(frameIndex_), robotId(robotId_)
00067 {
00068 }
00069 unsigned int frameIndex;
00070 unsigned int robotId;
00071 };
00072 bool operator< (TrajectoryPoseRecordKey const& k1, TrajectoryPoseRecordKey const& k2);
00073 bool operator== (TrajectoryPoseRecordKey const& k1, TrajectoryPoseRecordKey const& k2);
00074 std::ostream& operator <<(std::ostream& s, TrajectoryPoseRecordKey const& tpr);
00075
00082 class BearingOnlySlam : public SlamEkf, public SlamEventAdapter {
00083 private:
00084 std::size_t m_sizeTrajectory;
00085 public:
00086 typedef std::map<TrajectoryPoseRecordKey, TrajectoryPoseRecord> TrajectoryPoseRecordsType;
00087
00088 protected:
00089
00090 std::vector<jblas::vec_range> trajectory;
00091 std::vector<jblas::sym_mat_range> trajectoryCov;
00092
00093 std::vector<std::size_t> trajectoryStateIndex;
00094 std::vector<bool> trajectoryIsRobot;
00095
00096 std::list<std::size_t> trajectoryEmptyIndexes;
00097
00098 std::map< unsigned int, std::size_t> robotIdToTrajectoryIndex;
00099
00100 TrajectoryPoseRecordsType trajectoryPoseRecords;
00101
00102 bool hasTrajectoryPoseRecord(unsigned int frameIndex, unsigned int robotId_ = 0 ) const;
00103 TrajectoryPoseRecord const& getTrajectoryPoseRecord(unsigned int frameIndex, unsigned int robotId_ = 0) const;
00104 TrajectoryPoseRecord& getTrajectoryPoseRecord(unsigned int frameIndex, unsigned int robotId_ = 0);
00105
00106 void eraseTrajectoryPoseRecord(unsigned int frameIndex, unsigned int robotId_ = 0);
00107 void eraseTrajectoryPoseRecord(TrajectoryPoseRecordsType::iterator it);
00108
00109 void updateTrajectoryWithRemovedFeature(InitFeature const& f );
00110
00111 typedef std::map<int, BearingOnlyFeatureObserveModel*> BoFeatureObserveModelsContType;
00112
00114 BoFeatureObserveModelsContType boFeatureObserveModels;
00115
00116 typedef std::map<int, InfFeatureObserveModel*> InfFeatureObserveModelsContType;
00117
00119 InfFeatureObserveModelsContType infFeatureObserveModels;
00120
00122 double dMin;
00124 double dMax;
00125
00127 double sprtAlphaFA;
00129 double sprtAlphaMD;
00130
00132 double logA;
00134 double logB;
00135
00136 typedef std::list<BoSlamEventListener*> BoSlamEventListenersList;
00137 BoSlamEventListenersList boSlamEventListeners;
00138
00139 void manageTrajectory(unsigned int robotId_ = 0);
00140 void backupCurrentPose(std::size_t index, unsigned int _robotPose = 0);
00141
00142 void observeNewFeature(Observation* obs_);
00143
00144 void observeKnownFeature(Observation* obs_);
00145
00146 void observeInitFeature(InitFeature& feature, Observation* obs);
00147
00148 virtual void beginProcessObservations(unsigned int robotId_ ) {
00149
00150 TrajectoryPoseRecord tpr(currentFrameIndex, robotId_, robotIdToTrajectoryIndex[ robotId_ ] );
00151 trajectoryPoseRecords.insert(std::make_pair(TrajectoryPoseRecordKey(currentFrameIndex, robotId_),tpr));
00152 JFR_DEBUG("BearingOnlySlam::beginProcessObservations: add: " << tpr);
00153 JFR_DEBUG(getTrajectoryPoseRecord(currentFrameIndex, robotId_));
00154 }
00155
00156 virtual void endProcessObservations(unsigned int robotId_ ) {
00157 cleanInitFeatures();
00158 manageTrajectory(robotId_);
00159 }
00160
00162 void initState(InitFeature& feature, Observation const& obs);
00163
00165 void updateInitState(InitFeature& feature, Observation const& obs);
00166
00167
00169 static double computeInitStateHypothesisLogLikelihood(InitStateMember& ism,
00170 InitFeature& feature,
00171 BaseFeatureObserveModel& obsModel,
00172 double eraseHypothesisTh,
00173 Observation const& obs,
00174 jblas::sym_mat const& R,
00175 double m2PiN,
00176 jblas::vec_range const& xi, jblas::sym_mat_range const& Pi,
00177 jblas::vec_range const& xt, jblas::sym_mat_range const& Pt,
00178 jblas::sym_mat_range const& Pti,
00179 jblas::vec_range& xf_m_r,
00180 jblas::sym_mat& S_inv,
00181 jblas::mat_range& Jxt,
00182 jblas::mat& Jxi,
00183 jblas::mat& Jxf);
00184
00186 void cleanInitFeatures();
00187
00191 bool manageInitState(InitFeature& iFeature);
00192
00194 void fullStateInit(InitFeature& iFeature,
00195 InitStateMember const& state);
00196
00197 void fullStateInit(InitFeature& iFeature,
00198 jblas::vec const& x,
00199 jblas::sym_mat const& P,
00200 bool atInfinity = false);
00201
00203 unsigned int nbInitFeaturesLost;
00204
00205 virtual void writeLogHeader(jafar::kernel::DataLogger& log) const;
00206 virtual void writeLogData(jafar::kernel::DataLogger& log) const;
00207
00208
00209
00210 public:
00211
00212 typedef std::map<unsigned int, InitFeature*> InitFeaturesMapType;
00213
00214 InitFeaturesMapType initFeatures;
00215
00216 BearingOnlySlam(std::size_t sizeMax_,
00217 std::size_t sizeRobotState_,
00218 std::size_t sizeRobotPose_,
00219 std::size_t sizeTrajectory_);
00220
00221 ~BearingOnlySlam();
00222
00224 virtual void init(boost::posix_time::time_duration const& curTime);
00225 virtual void addRobot( BaseRobot* );
00226
00228 std::size_t sizeTrajectory() const {return trajectory.size();}
00229
00230 jblas::vec_range const& getTrajectoryPose(unsigned int frameIndex, unsigned int robotId_ = 0) const;
00231
00233 void setBoSensor(BearingOnlyFeatureObserveModel* model, int sensorId = 0);
00234
00236 void setBoSensor(BearingOnlyFeatureObserveModel* model, InfFeatureObserveModel* modelInf, int sensorId = 0);
00237
00241 virtual void setRobotToSensor(jblas::vec const& robotToSensor, int sensorId = 0);
00242
00246 virtual void setRobotToSensor(jblas::vec const& robotToSensor, jblas::vec const& robotToSensorStdDev,
00247 int sensorId = 0);
00248
00249
00250 bool hasBoFeatureObserveModel(int sensorId) {
00251 return boFeatureObserveModels.find(sensorId) != boFeatureObserveModels.end();
00252 }
00253
00254 BearingOnlyFeatureObserveModel& getBoFeatureObserveModel(int sensorId = 0) {
00255 BoFeatureObserveModelsContType::iterator it = boFeatureObserveModels.find(sensorId);
00256 JFR_PRED_ERROR(it != boFeatureObserveModels.end(),
00257 SlamException,
00258 SlamException::UNKNOWN_SENSOR,
00259 "BearingOnlySlam::getBoFeatureObserveModel: Unknown sensor: " << sensorId);
00260 return *(it->second);
00261 }
00262
00263 bool hasInfFeatureObserveModel(int sensorId) {
00264 return infFeatureObserveModels.find(sensorId) != infFeatureObserveModels.end();
00265 }
00266
00267 InfFeatureObserveModel& getInfFeatureObserveModel(int sensorId) {
00268 InfFeatureObserveModelsContType::iterator it = infFeatureObserveModels.find(sensorId);
00269 JFR_PRED_ERROR(it != infFeatureObserveModels.end(),
00270 SlamException,
00271 SlamException::UNKNOWN_SENSOR,
00272 "BearingOnlySlam::getInfFeatureObserveModel: Unknown sensor: " << sensorId);
00273 return *(it->second);
00274 }
00275
00276 BaseFeatureObserveModel& getBoInfFeatureObserveModel(int sensorId, bool infinity) {
00277 if (infinity)
00278 return getInfFeatureObserveModel(sensorId);
00279 else
00280 return getBoFeatureObserveModel(sensorId);
00281 }
00282
00283 TrajectoryPoseRecordsType const& getTrajectoryPoseRecords() const {return trajectoryPoseRecords;}
00284
00285 void addBoEventListener(BoSlamEventListener& listener) {
00286 addEventListener(listener);
00287 boSlamEventListeners.push_back(&listener);
00288 JFR_DEBUG("BearingOnlySlam::addBoSlamEventListener: " << boSlamEventListeners.size() << " listeners");
00289 }
00290
00291 bool hasInitFeature(unsigned int id_) const {
00292 return (initFeatures.find(id_) != initFeatures.end());
00293 };
00294
00295 virtual bool isFeatureKnown(unsigned int id) const {
00296 return hasInitFeature(id) || hasFeature(id);
00297 };
00298
00299
00300
00301
00302
00303 InitFeature& getInitFeature(unsigned int id) const {
00304 InitFeaturesMapType::const_iterator feature_it = initFeatures.find(id);
00305 if (feature_it != initFeatures.end())
00306 return *(feature_it->second);
00307 else
00308 JFR_ERROR(SlamException, SlamException::UNKNOWN_FEATURE,
00309 "BearingOnlySlam::getInitFeature: unknown feature " << id);
00310 }
00311
00312 virtual void removeFeature(unsigned int id);
00313 void removeInitFeature(unsigned int id);
00314 void removeInitFeature(InitFeaturesMapType::iterator featureIt);
00315
00316
00317 InitFeaturesMapType::iterator browseInitFeaturesIt;
00318 void beginBrowseInitFeatures();
00319 bool hasNextInitFeature();
00320 InitFeature* nextInitFeature();
00321
00322 void setBoParam(double dMin_=0.5, double dMax_=100, double sprtAlphaFA_=0.01, double sprtAlphaMD_=0.05);
00323
00324 void predict(unsigned int id,
00325 jblas::vec const& u);
00326
00327 friend std::ostream& operator <<(std::ostream& s, const BearingOnlySlam& slam_);
00328 friend class KarmaManager;
00329
00330 friend std::string boSlamTrajectory(BearingOnlySlam const& slam);
00331 };
00332
00333 std::ostream& operator <<(std::ostream& s, const BearingOnlySlam& slam_);
00334
00335 }
00336 }
00337 #endif // SLAM_BEARING_ONLY_SLAM_HPP