00001
00008 #ifndef __ObservationAbstract_H__
00009 #define __ObservationAbstract_H__
00010
00011
00012
00013
00014
00015 #include <jmath/jblas.hpp>
00016 #include <boost/smart_ptr.hpp>
00017
00018 #include "rtslam/rtSlam.hpp"
00019
00020 #include "rtslam/parents.hpp"
00021 #include "rtslam/objectAbstract.hpp"
00022 #include "rtslam/sensorAbstract.hpp"
00023 #include "rtslam/landmarkAbstract.hpp"
00024 #include "rtslam/appearanceAbstract.hpp"
00025
00026 #include "rtslam/gaussian.hpp"
00027 #include "rtslam/innovation.hpp"
00028 #include "rtslam/dataManagerAbstract.hpp"
00029
00030 namespace jafar {
00031 namespace rtslam {
00032 using namespace jblas;
00033
00039 class ObservationModelAbstract
00040 {
00041 public:
00042 typedef boost::weak_ptr<SensorAbstract> sensor_wptr_t;
00043 protected:
00044 sensor_wptr_t sensorWPtr;
00045 public:
00046 void linkToSensor( sensor_ptr_t ptr )
00047 {
00048 sensorWPtr = ptr;
00049 }
00050 sensor_ptr_t sensorPtr( void )
00051 {
00052 sensor_ptr_t sptr = sensorWPtr.lock();
00053 if (!sptr) {
00054 std::cerr << __FILE__ << ":" << __LINE__ << " ObsSpec::sensor threw weak" << std::endl;
00055 throw "WEAK";
00056 }
00057 return sptr;
00058 }
00059
00060 virtual void linkToSensorSpecific( sensor_ptr_t ptr ) = 0;
00061 public:
00071 virtual void
00072 project_func(const vec7 & sg, const vec & lmk, vec & meas, vec & nobs) = 0;
00073
00086 virtual void
00087 project_func(const vec7 & sg, const vec & lmk, vec & exp, vec & nobs, mat & EXP_sg, mat & EXP_lmk) = 0;
00088
00089 virtual void
00090 project_func(const vec7 & sg, const vec & lmk, vec & exp, vec & nobs, mat & EXP_sg, mat & EXP_lmk, const vec lmk_fej)
00091 { project_func(sg, lmk, exp, nobs, EXP_sg, EXP_lmk); }
00092
00096 virtual void backProject_func(const vec7 & sg, const vec & meas, const vec & nobs, vec & lmk) = 0;
00097
00101 virtual void backProject_func(const vec7 & sg, const vec & meas, const vec & nobs, vec & lmk, mat & LMK_sg,
00102 mat & LMK_meas, mat & LMK_nobs) = 0;
00103
00104 virtual bool predictVisibility_func(jblas::vec x, jblas::vec nobs) = 0;
00105 };
00106
00107
00123 class ObservationAbstract: public ObjectAbstract,
00124 public ChildOf<LandmarkAbstract> ,
00125 public boost::enable_shared_from_this<ObservationAbstract>,
00126 public ChildOf<DataManagerAbstract> {
00127
00128 friend std::ostream& operator <<(std::ostream & s, ObservationAbstract const & obs);
00129 friend image::oimstream& operator <<(image::oimstream & s, ObservationAbstract const & obs);
00130
00131
00132 ENABLE_LINK_TO_PARENT(LandmarkAbstract,Landmark,ObservationAbstract)
00133 ;
00134
00135 ENABLE_ACCESS_TO_PARENT(LandmarkAbstract,landmark)
00136 ;
00137
00138 ENABLE_LINK_TO_PARENT(DataManagerAbstract,DataManager,ObservationAbstract)
00139 ;
00140
00141 ENABLE_ACCESS_TO_PARENT(DataManagerAbstract,dataManager)
00142 ;
00143
00144 void linkToSensor( sensor_ptr_t ptr ) { model->linkToSensor(ptr); }
00145 sensor_ptr_t sensorPtr( void ) { return model->sensorPtr(); }
00146 const sensor_ptr_t sensorPtr( void ) const { return model->sensorPtr(); }
00147 void linkToSensorSpecific( sensor_ptr_t ptr ) { model->linkToSensorSpecific(ptr); }
00148
00149 public:
00150
00151 boost::shared_ptr<ObservationModelAbstract> model;
00152
00153 enum type_enum {
00154 PNT_PH_EUC,
00155 PNT_PH_AH,
00156 PNT_PH_AHPL
00157 };
00158
00159
00164 ObservationAbstract(const sensor_ptr_t & _senPtr, const landmark_ptr_t & _lmkPtr, const size_t _size,
00165 const size_t size_nonobs = 0);
00166
00170 ObservationAbstract(const sensor_ptr_t & _senPtr, const landmark_ptr_t & _lmkPtr, const size_t _size_meas,
00171 const size_t _size_exp, const size_t _size_inn, const size_t _size_nonobs = 0);
00172
00173 virtual ~ObservationAbstract();
00174
00175 void setPrior(const Gaussian & _prior);
00176
00177
00178 static const unsigned max_hypotheses;
00179 bool use_hypotheses;
00180 struct Hypothesis
00181 {
00182 Gaussian nobs;
00183 Expectation expectation;
00184 mat EXP_l;
00185 mat EXP_sg;
00186 Hypothesis(unsigned lmk_size, unsigned exp_size, unsigned nobs_size):
00187 nobs(nobs_size), expectation(exp_size, nobs_size), EXP_l(exp_size, lmk_size), EXP_sg(exp_size, 7) {}
00188 };
00189 jblas::mat hyp_EXP_rsl;
00190 jblas::sym_mat hyp_rslP;
00191 std::vector<Hypothesis> hypotheses;
00192 bool clear_hypotheses;
00196 bool findBounds(jblas::vec & lmk, unsigned iid, jblas::vec7 const & sg, jblas::vec & ids);
00200 bool checkExtremities(jblas::vec & lmk, unsigned iid, double id_sig, Expectation const & hypexp, jblas::vec & id_bounds, jblas::vec & ids, jblas::vec7 const & sg, jblas::vec & exp, jblas::sym_mat & expP, jblas::vec & nobs, double k);
00201 void projectHypothesis(Hypothesis & hyp, jblas::vec & lmk, unsigned iid, jblas::vec7 const & sg, jblas::vec & exp, jblas::vec & nobs);
00205 void linearizeUncertainty();
00206
00207
00208 Expectation expectation;
00209 Measurement measurement;
00210 Innovation innovation;
00211 Gaussian prior;
00212 appearance_ptr_t predictedAppearance;
00213 appearance_ptr_t observedAppearance;
00214 jblas::sym_mat noiseCovariance;
00215
00216
00217 ind_array ia_rsl;
00218
00219 public:
00220
00221 mat SG_rs;
00222 mat EXP_sg;
00223 mat EXP_l;
00224 mat EXP_rsl;
00225 mat INN_meas;
00226 mat INN_exp;
00227 mat INN_rsl;
00228 mat LMK_sg;
00229 mat LMK_meas;
00230 mat LMK_prior;
00231 mat LMK_rs;
00232
00233 public:
00237 struct Counters {
00238 int nSearch;
00239 int nMatch;
00240 int nInlier;
00241 int nSearchSinceLastInlier;
00242 int nFrameSinceLastVisible;
00243 } counters;
00244
00248 struct Events {
00249 bool predicted;
00250 bool visible;
00251 bool measured;
00252 bool matched;
00253 bool updated;
00254 bool killed;
00255 } events;
00256 bool updatable;
00257
00258 void markUpdated() { events.updated = true; clear_hypotheses = true; }
00259
00263 struct Tasks {
00264 bool predictedApp;
00265 } tasks;
00266
00267 int searchSize;
00268
00269 type_enum type;
00270
00271 void setId(){
00272 id(landmarkPtr()->id());
00273 }
00274
00275 virtual std::string typeName() const {return "Abstract";}
00276 std::string categoryName() const {
00277 return "OBSERVATION";
00278 }
00279
00283 void project(bool multi_hyp = true);
00284
00288 void projectMean();
00289
00294 virtual bool isVisible() {
00295 return events.visible;
00296 }
00297
00301 void backProject();
00302
00309 virtual void computeInnovation();
00310 virtual void computeInnovationMean(vec &inn, const vec &meas, const vec &exp) const;
00311 virtual double computeRelevance();
00312
00319 virtual void predictInfoGain();
00320
00354 virtual bool compatibilityTest(const double mahaDist);
00355
00356 static bool compatibilityTest(Measurement const & meas, Expectation const & exp, double mahaDist);
00357
00361 void clearFlags();
00362 void clearCounters();
00363
00364
00374 virtual bool predictVisibility()
00375 {
00376 events.visible = model->predictVisibility_func(expectation.x(), expectation.nonObs);
00377 return events.visible;
00378 }
00379
00380
00384 virtual bool predictAppearance(bool force = false)
00385 {
00386 if (force || !tasks.predictedApp)
00387 {
00388
00389 if (predictAppearance_func())
00390 {
00391 tasks.predictedApp = true;
00392 return true;
00393 }
00394 return false;
00395 }
00396 return true;
00397 }
00398
00399 virtual bool updateDescriptor()
00400 {
00401 return landmarkPtr()->descriptorPtr->addObservation(this->shared_from_this());
00402 }
00403 virtual void updateVisibilityMap()
00404 {
00405 landmarkPtr()->visibilityMap.addObservation(this->shared_from_this());
00406 }
00407
00408 virtual bool isDescriptorValid()
00409 {
00410 return landmarkPtr()->descriptorPtr->isPredictionValid(this->shared_from_this());
00411 }
00412
00413 virtual bool predictAppearance_func() = 0;
00414
00415 double getMatchScore() {
00416 return measurement.matchScore;
00417 }
00418
00419 void update(bool correct_P = true) ;
00420 #if 0
00421 virtual bool voteForKillingLandmark();
00422 #endif
00423
00424 virtual double computeLinearityScore() = 0;
00425
00426 virtual void transferInfoObs(observation_ptr_t & obs);
00427
00428 virtual void desc_image(image::oimstream& os) const {}
00429
00430 };
00431
00432 }
00433
00434 }
00435
00436
00437 #define ENABLE_LINK_TO_SENSOR_SPEC(className) \
00438 protected:\
00439 sensor_spec_wptr_t sensorSpecWPtr;\
00440 public:\
00441 void linkTo##className( sensor_spec_ptr_t ptr )\
00442 {\
00443 sensorSpecWPtr = ptr;\
00444 ObservationAbstract::linkToSensor(ptr);\
00445 }
00446
00447
00448 #define ENABLE_ACCESS_TO_SENSOR_SPEC(accessName) \
00449 sensor_spec_ptr_t accessName##Ptr( void )\
00450 {\
00451 sensor_spec_ptr_t sptr = sensorSpecWPtr.lock();\
00452 if (!sptr) {\
00453 std::cerr << __FILE__ << ":" << __LINE__\
00454 << " ObsSpec::sensor threw weak" << std::endl;\
00455 throw "WEAK";\
00456 }\
00457 return sptr;\
00458 }
00459
00460
00461
00462 #endif // #ifndef __ObservationAbstract_H__
00463
00464
00465
00466
00467
00468
00469
00470