00001
00008 #include "kernel/misc.hpp"
00009
00010 #include "jmath/randomIntTmplt.hpp"
00011 #include "jmath/misc.hpp"
00012
00013
00014 #include "rtslam/dataManagerOnePointRansac.hpp"
00015 #include "rtslam/kalmanTools.hpp"
00016
00017 #include "rtslam/rtSlam.hpp"
00018 #include "rtslam/observationAbstract.hpp"
00019
00020 #include "rtslam/imageTools.hpp"
00021
00022 #include <algorithm>
00023
00024
00025
00026
00027
00028
00029 #define BUFFERED_UPDATE 1
00030
00031
00032
00033
00034
00035
00036
00037
00038 #define PROJECT_MEAN_VISIBILITY 1
00039
00040
00041
00042
00043
00044 #define APPLY_CONSTRAINTS 0
00045
00046 #if RELEVANCE_TEST && RELEVANCE_TEST_P
00047 #error "RELEVANCE_TEST and RELEVANCE_TEST_P are incompatible!"
00048 #endif
00049
00050 namespace jafar {
00051 namespace rtslam {
00052
00053 bool compare_lmk_uncertainty(landmark_ptr_t const & lmkPtr1, landmark_ptr_t const & lmkPtr2)
00054 {
00055 double uncert1 = lmkPtr1->uncertainty();
00056 double uncert2 = lmkPtr2->uncertainty();
00057 if (uncert1 < uncert2) return true; else
00058 if (uncert1 == uncert2) return (lmkPtr1->countObserved() > lmkPtr2->countObserved()); else
00059 return false;
00060 }
00061
00062 bool compare_obs_uncertainty(observation_ptr_t const & obsPtr1, observation_ptr_t const & obsPtr2)
00063 {
00064 return compare_lmk_uncertainty(obsPtr1->landmarkPtr(), obsPtr2->landmarkPtr());
00065 }
00066
00067 template<class RawSpec,class SensorSpec, class FeatureSpec, class RoiSpec, class FeatureManagerSpec, class DetectorSpec, class MatcherSpec>
00068 void DataManagerOnePointRansac<RawSpec,SensorSpec,FeatureSpec,RoiSpec,FeatureManagerSpec,DetectorSpec,MatcherSpec>::
00069 processKnown(raw_ptr_t data, double date_limit)
00070 {
00071 const unsigned min_as_update = 2;
00072 int n_updates_ransac = algorithmParams.n_updates_ransac;
00073
00074 double date_begin = kernel::Clock::getTime();
00075 double time_available = date_limit - date_begin;
00076 if (date_limit > 0)
00077 {
00078 if (prev_average_as_update_time < prev_average_ransac_update_time) prev_average_ransac_update_time = prev_average_as_update_time;
00079 if (prev_average_ransac_update_time > 0 && prev_average_as_update_time > 0)
00080 n_updates_ransac = (time_available - min_as_update*prev_average_as_update_time) / prev_average_ransac_update_time;
00081 else if (prev_average_ransac_update_time > 0)
00082 n_updates_ransac = (time_available / prev_average_ransac_update_time) - min_as_update;
00083 if (n_updates_ransac <= 0) n_updates_ransac = (time_available / prev_average_ransac_update_time);
00084 if (n_updates_ransac <= 0) n_updates_ransac = 1;
00085 if ((unsigned)n_updates_ransac > algorithmParams.n_updates_ransac) n_updates_ransac = algorithmParams.n_updates_ransac;
00086 }
00087 double average_ransac_update_time = kernel::Clock::getTime();
00088
00089 boost::shared_ptr<RawSpec> rawData = SPTR_CAST<RawSpec>(data);
00090
00091
00092
00093 map_ptr_t mapPtr = sensorPtr()->robotPtr()->mapPtr();
00094 unsigned numObs = 0, numObsRansac = 0;
00095
00096 projectAndCollectVisibleObs();
00097 if (n_updates_ransac <= 0) return;
00098
00099 unsigned n_tries = algorithmParams.n_tries;
00100 if (obsVisibleList.size() < n_tries) n_tries = obsVisibleList.size();
00101
00102
00103
00104
00105
00106 unsigned current_try = 0;
00107 if (n_tries >= 2)
00108 while (current_try < n_tries)
00109 {
00110
00111 observation_ptr_t obsBasePtr;
00112 getOneMatchedBaseObs(obsBasePtr, rawData);
00113 if (!obsBasePtr) break;
00114
00115
00116 ransac_set_ptr_t ransacSetPtr(new RansacSet);
00117 ransacSetList.push_back(ransacSetPtr);
00118 ransacSetPtr->obsBasePtr = obsBasePtr;
00119 ransacSetPtr->add_inlier(obsBasePtr);
00120
00121 current_try ++;
00122 vec x_copy = updateMean(obsBasePtr);
00123
00124 JFR_VVDEBUG("Ransac try " << current_try << " with base obs " << obsBasePtr->id());
00125
00126
00127 for(ObsList::iterator obsIter = obsVisibleList.begin(); obsIter != obsVisibleList.end(); obsIter++)
00128 {
00129 observation_ptr_t obsCurrentPtr = *obsIter;
00130 if (obsCurrentPtr == obsBasePtr) continue;
00131
00132
00133 ransac_exp.resize(obsCurrentPtr->expectation.size(), false);
00134 projectFromMean(ransac_exp, obsCurrentPtr, x_copy);
00135
00136 bool inlier = obsCurrentPtr->events.matched &&
00137 isLowInnovationInlier(obsCurrentPtr, ransac_exp, matcher->params.lowInnov);
00138
00139 if (!inlier)
00140 {
00141 matchWithExpectedInnovation(rawData, obsCurrentPtr, true);
00142
00143 inlier = obsCurrentPtr->events.matched &&
00144 isLowInnovationInlier(obsCurrentPtr, ransac_exp, matcher->params.lowInnov);
00145 }
00146
00147 if (inlier)
00148 {
00149
00150 ransacSetPtr->add_inlier(obsCurrentPtr);
00151 JFR_VVDEBUG("Obs " << obsCurrentPtr->id() << " is inlier (@" << obsCurrentPtr->measurement.x() << " exp " << obsCurrentPtr->expectation.x() << ")");
00152 }
00153 else{
00154
00155 ransacSetPtr->pendingObs.push_back(obsCurrentPtr);
00156 JFR_VVDEBUG("Obs " << obsCurrentPtr->id() << " is pending (@" << (obsCurrentPtr->events.matched ? (jblas::vec)obsCurrentPtr->measurement.x() : (jblas::vec)jblas::zero_vec(2) ) << " exp " << obsCurrentPtr->expectation.x() << ")");
00157 }
00158 }
00159 }
00160
00161
00162
00163
00164
00165
00166
00167 ransac_set_ptr_t best_set;
00168 bool pending_buffered_update = false;
00169 if (ransacSetList.size() != 0)
00170 {
00171
00172 for(RansacSetList::iterator rsIter = ransacSetList.begin(); rsIter != ransacSetList.end(); ++rsIter)
00173 if (!best_set || (*rsIter)->size() > best_set->size()) best_set = *rsIter;
00174
00175
00176
00177 while (best_set->size() > 1 && best_set->size() > (unsigned)n_updates_ransac)
00178 {
00179 int n = (rtslam::rand() % (best_set->size() - 1)) + 1;
00180 best_set->pendingObs.push_back(best_set->inlierObs[n]);
00181 kernel::fastErase(best_set->inlierObs, n);
00182 }
00183
00184 if (best_set->size() > 1)
00185 {
00186
00187 JFR_DEBUG_BEGIN(); JFR_DEBUG_SEND("Updating with Ransac:");
00188 #if RELEVANCE_TEST || RELEVANCE_TEST_P
00189 double innovation_relevance = 0.0;
00190 #endif
00191 for(ObsList::iterator obsIter = best_set->inlierObs.begin(); obsIter != best_set->inlierObs.end(); ++obsIter)
00192 {
00193 observation_ptr_t obsPtr = *obsIter;
00194
00195
00196 obsPtr->measurement = best_set->inlierMeasurements.at(obsPtr->id());
00197 obsPtr->computeInnovation();
00198
00199
00200 #if BUFFERED_UPDATE
00201 mapPtr->filterPtr->stackCorrection(obsPtr->innovation, obsPtr->INN_rsl, obsPtr->ia_rsl);
00202 #if RELEVANCE_TEST || RELEVANCE_TEST_P
00203 innovation_relevance += obsPtr->computeRelevance();
00204 #endif
00205 #else
00206 obsPtr->project(multi_hyps_);
00207 obsPtr->computeInnovation();
00208 #if RELEVANCE_TEST
00209 if (obsPtr->computeRelevance() > jmath::sqr(matcher->params.relevanceTh))
00210 #endif
00211 {
00212 #if RELEVANCE_TEST_P
00213 obsPtr->update(obsPtr->computeRelevance() > jmath::sqr(matcher->params.relevanceTh));
00214 #else
00215 obsPtr->update();
00216 #endif
00217 obsPtr->events.updated = true;
00218 #if APPLY_CONSTRAINTS
00219 sensorPtr()->robotPtr()->applyConstraints();
00220 #endif
00221 }
00222 #endif
00223 }
00224 bool do_update = false;
00225 #if BUFFERED_UPDATE
00226
00227 #if RELEVANCE_TEST || RELEVANCE_TEST_P
00228 innovation_relevance /= best_set->inlierObs.size();
00229 #endif
00230 #if RELEVANCE_TEST
00231 if (innovation_relevance > jmath::sqr(matcher->params.relevanceTh))
00232 #endif
00233 {
00234 #if RELEVANCE_TEST_P
00235 mapPtr->filterPtr->correctAllStacked(mapPtr->ia_used_states(), innovation_relevance > jmath::sqr(matcher->params.relevanceTh));
00236 #else
00237 mapPtr->filterPtr->correctAllStacked(mapPtr->ia_used_states());
00238 #endif
00239 #if APPLY_CONSTRAINTS
00240 sensorPtr()->robotPtr()->applyConstraints();
00241 #endif
00242 do_update = true;
00243 }
00244 #if RELEVANCE_TEST
00245 else pending_buffered_update = true;
00246 #endif
00247
00248 #endif
00249
00250 for(ObsList::iterator obsIter = best_set->inlierObs.begin(); obsIter != best_set->inlierObs.end(); ++obsIter)
00251 if (do_update || (*obsIter)->events.updated)
00252 {
00253
00254
00255 numObs++; numObsRansac++;
00256 (*obsIter)->events.updated = true;
00257 JFR_DEBUG_SEND(" " << (*obsIter)->id());
00258
00259 } else
00260 {
00261
00262 (*obsIter)->events.measured = false;
00263 (*obsIter)->events.matched = false;
00264 }
00265 JFR_DEBUG_END();
00266 }
00267 }
00268
00269 double date_now = kernel::Clock::getTime(), date_prev, time_update;
00270 average_ransac_update_time = date_now - average_ransac_update_time;
00271 if (numObsRansac > 0) prev_average_ransac_update_time = average_ransac_update_time / numObsRansac;
00272 double average_as_update_time = date_now;
00273 bool stop_no_time = false;
00274
00275
00276
00277
00278 ObsList activeSearchList = ((ransacSetList.size() == 0) || (best_set->size() <= 1) ? obsVisibleList : best_set->pendingObs);
00279
00280
00281 JFR_DEBUG_BEGIN(); JFR_DEBUG_SEND("Updating with ActiveSearch:");
00282 for (unsigned i = 0; i < algorithmParams.n_recomp_gains && !stop_no_time; ++i)
00283 {
00284
00285 for(ObsList::iterator obsIter = activeSearchList.begin(); obsIter != activeSearchList.end(); ++obsIter)
00286 {
00287 observation_ptr_t obsPtr = *obsIter;
00288
00289 obsPtr->clearFlags();
00290 obsPtr->measurement.matchScore = 0;
00291
00292
00293 obsPtr->project(multi_hyps_);
00294
00295
00296 obsPtr->predictVisibility();
00297
00298 if (obsPtr->isVisible()) {
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 bool valid = true;
00310 for (unsigned i = 0; i < obsPtr->expectation.P().size1(); ++i)
00311 if (obsPtr->expectation.P()(i,i) < 0.0) { valid = false; break; }
00312
00313 if (valid)
00314 {
00315
00316 obsPtr->predictInfoGain();
00317
00318
00319 obsListSorted[obsPtr->expectation.infoGain] = obsIter;
00320 }
00321 }
00322 }
00323
00324
00325 for (ObservationListSorted::reverse_iterator obsIter = obsListSorted.rbegin();
00326 obsIter != obsListSorted.rend() && !stop_no_time; ++obsIter)
00327 {
00328 if (i != algorithmParams.n_recomp_gains-1 && obsIter != obsListSorted.rbegin()) break;
00329 date_prev = kernel::Clock::getTime();
00330 observation_ptr_t obsPtr = *(obsIter->second);
00331
00332
00333 if (obsIter != obsListSorted.rbegin()) obsPtr->project(multi_hyps_);
00334
00335
00336 obsPtr->predictVisibility();
00337 if (obsPtr->isVisible())
00338 {
00339 if (numObs < algorithmParams.n_updates_total)
00340 {
00341 matchWithExpectedInnovation(rawData, obsPtr, false);
00342 if (obsPtr->events.matched
00343 #if RELEVANCE_TEST
00344 && obsPtr->computeRelevance() > jmath::sqr(matcher->params.relevanceTh)
00345 #endif
00346 ) {
00347 #if RELEVANCE_TEST
00348 if (pending_buffered_update)
00349 {
00350 mapPtr->filterPtr->correctAllStacked(mapPtr->ia_used_states());
00351 pending_buffered_update = false;
00352 #if APPLY_CONSTRAINTS
00353 sensorPtr()->robotPtr()->applyConstraints();
00354 #endif
00355
00356 }
00357 #endif
00358 obsPtr->markUpdated();
00359 numObs++;
00360 JFR_DEBUG_SEND(" " << obsPtr->id());
00361
00362
00363 #if RELEVANCE_TEST_P
00364 obsPtr->update(obsPtr->computeRelevance() > jmath::sqr(matcher->params.relevanceTh));
00365 #else
00366 obsPtr->update();
00367 #endif
00368 #if APPLY_CONSTRAINTS
00369 sensorPtr()->robotPtr()->applyConstraints();
00370 #endif
00371
00372 }
00373 }
00374 }
00375
00376
00377
00378 if (obsPtr->events.updated && date_limit > 0)
00379 {
00380 date_now = kernel::Clock::getTime();
00381 time_update = date_now - date_prev;
00382 if (date_now+time_update > date_limit) { stop_no_time = true; break; }
00383 }
00384
00385 }
00386
00387 if (i+1 != algorithmParams.n_recomp_gains && obsListSorted.rbegin() != obsListSorted.rend())
00388 kernel::fastErase(activeSearchList, obsListSorted.rbegin()->second);
00389 obsListSorted.clear();
00390 }
00391 JFR_DEBUG_END();
00392
00393 if (pending_buffered_update) mapPtr->filterPtr->clearStack();
00394
00395 average_as_update_time = kernel::Clock::getTime() - average_as_update_time;
00396 if (numObs > numObsRansac) prev_average_as_update_time = average_as_update_time / (numObs-numObsRansac);
00397
00398
00399 updateVisibleObs();
00400 for(size_t i = 0; i < featMan->projections.size(); ++i)
00401 {
00402 int nkilled = 0;
00403 for(size_t j1 = 0; j1 < featMan->projections[i].size(); ++j1)
00404 if (featMan->projections[i][j1]->events.updated)
00405 for(size_t j2 = j1+1; j2 < featMan->projections[i].size(); ++j2)
00406 if (featMan->projections[i][j2]->events.updated)
00407 if (ublasExtra::prod_xt_P_x(featMan->projections[i][j1]->measurement.P() + featMan->projections[i][j2]->measurement.P(),
00408 featMan->projections[i][j1]->measurement.x() - featMan->projections[i][j2]->measurement.x()) <= 3)
00409 {
00410 if (featMan->projections[i][j1]->landmarkPtr()->killed != LandmarkAbstract::kNo) break;
00411 if (featMan->projections[i][j2]->landmarkPtr()->killed != LandmarkAbstract::kNo) continue;
00412 nkilled++;
00413 if (compare_obs_uncertainty(featMan->projections[i][j2], featMan->projections[i][j1]))
00414 { featMan->projections[i][j1]->landmarkPtr()->killed = LandmarkAbstract::kDuplicate; break; } else
00415 { featMan->projections[i][j2]->landmarkPtr()->killed = LandmarkAbstract::kDuplicate; continue; }
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 }
00432
00433
00434
00435
00436
00437 clearCounters();
00438 for(ObservationList::iterator obsIter = observationList().begin(); obsIter != observationList().end();obsIter++)
00439 {
00440 observation_ptr_t obs = *obsIter;
00441 if (obs->events.visible) JFR_ASSERT(obs->events.predicted, "obs visible without previous steps");
00442 if (obs->events.measured) JFR_ASSERT(obs->events.visible && obs->events.predicted, "obs measured without previous steps");
00443 if (obs->events.matched) JFR_ASSERT(obs->events.measured && obs->events.visible && obs->events.predicted, "obs matched without previous steps");
00444 if (obs->events.updated) JFR_ASSERT(obs->events.matched && obs->events.measured && obs->events.visible && obs->events.predicted, "obs updated without previous steps");
00445
00446 obs->updateDescriptor();
00447 #if VISIBILITY_MAP
00448 obs->updateVisibilityMap();
00449 #endif
00450
00451 if (obs->events.measured) obs->updatable = obs->events.updated;
00452 if (not (obs->events.measured && !obs->events.matched && !obs->isDescriptorValid()))
00453 {
00454 if (obs->events.measured) { obs->counters.nSearch++; counters.measured++; }
00455 if (obs->events.matched) { obs->counters.nMatch++; counters.matched++; }
00456 if (obs->events.updated) { obs->counters.nInlier++; counters.updated++; }
00457 }
00458
00459 if (obs->events.measured) obs->counters.nSearchSinceLastInlier++;
00460 if (obs->events.visible) { obs->counters.nFrameSinceLastVisible = 0; counters.visible++; }
00461 if (obs->events.updated) obs->counters.nSearchSinceLastInlier = 0;
00462 }
00463
00464
00465 ransacSetList.clear();
00466 obsBaseList.clear();
00467 obsFailedList.clear();
00468 }
00469
00470
00471 template<class RawSpec,class SensorSpec, class FeatureSpec, class RoiSpec, class FeatureManagerSpec, class DetectorSpec, class MatcherSpec>
00472 void DataManagerOnePointRansac<RawSpec,SensorSpec,FeatureSpec,RoiSpec,FeatureManagerSpec,DetectorSpec,MatcherSpec>::
00473 detectNew(raw_ptr_t data)
00474 {
00475 boost::shared_ptr<RawSpec> rawData = SPTR_CAST<RawSpec>(data);
00476 updateVisibleObs();
00477 obsVisibleList.clear();
00478 for(unsigned i = 0; i < algorithmParams.n_init; )
00479 if (mapManagerPtr()->mapSpaceForInit()) {
00480
00481 RoiSpec roi;
00482 if (featMan->getRoi(roi)) {
00483
00484
00485
00486 boost::shared_ptr<FeatureSpec> featPtr;
00487 if (detector->detect(rawData, roi, featPtr))
00488 {
00489
00490 observation_ptr_t obsPtr =
00491 mapManagerPtr()->createNewLandmark(shared_from_this());
00492
00493
00494 obsPtr->counters.nSearch = 1;
00495 obsPtr->counters.nMatch = 1;
00496 obsPtr->counters.nInlier = 1;
00497 obsPtr->events.visible = true;
00498 obsPtr->events.predicted = false;
00499 obsPtr->events.measured = true;
00500 obsPtr->events.matched = false;
00501 obsPtr->markUpdated();
00502 obsPtr->measurement = featPtr->measurement;
00503
00504
00505 obsPtr->backProject();
00506
00507
00508 detector->fillDataObs(featPtr, obsPtr);
00509
00510
00511
00512 if (obsPtr->updateDescriptor())
00513 {
00514 #if VISIBILITY_MAP
00515 obsPtr->updateVisibilityMap();
00516 #endif
00517 featMan->addObs(obsPtr->measurement.x(), obsPtr);
00518 counters.created++;
00519
00520
00521 #if 0
00522
00523 obsPtr->project(multi_hyps_);
00524 if (obsPtr->predictAppearance())
00525 {
00526 jblas::sym_mat P = jblas::identity_mat(obsPtr->expectation.size())*jmath::sqr(4.0);
00527 RoiSpec roi(obsPtr->expectation.x(), P, 1.0);
00528 obsPtr->searchSize = roi.count();
00529 matcher->match(rawData, obsPtr->predictedAppearance, roi, obsPtr->measurement, obsPtr->observedAppearance);
00530 JFR_ASSERT(ublas::norm_2(obsPtr->measurement.x()-obsPtr->expectation.x()) <= 0.01);
00531 }
00532 #endif
00533
00534 ++i;
00535 } else
00536 {
00537 obsPtr->landmarkPtr()->mapManagerPtr()->unregisterLandmark(obsPtr->landmarkPtr());
00538 featMan->setFailed(roi);
00539 }
00540 } else
00541 {
00542 featMan->setFailed(roi);
00543 }
00544 } else break;
00545 } else break;
00546 }
00547
00548 #if 0
00549 template<class RawSpec,class SensorSpec, class FeatureSpec, class RoiSpec, class FeatureManagerSpec, class DetectorSpec, class MatcherSpec>
00550 void DataManagerOnePointRansac<RawSpec,SensorSpec,FeatureSpec,RoiSpec,FeatureManagerSpec,DetectorSpec,MatcherSpec>::
00551 process( boost::shared_ptr<RawAbstract> data )
00552 {
00553 boost::shared_ptr<RawSpec> dataSpec = SPTR_CAST<RawSpec>(data);
00554
00555 processKnownObs(dataSpec);
00556
00557 detectNewObs(dataSpec);
00558 }
00559 #endif
00560
00561 template<class RawSpec,class SensorSpec, class FeatureSpec, class RoiSpec, class FeatureManagerSpec, class DetectorSpec, class MatcherSpec>
00562 void DataManagerOnePointRansac<RawSpec,SensorSpec,FeatureSpec,RoiSpec,FeatureManagerSpec,DetectorSpec,MatcherSpec>::
00563 projectAndCollectVisibleObs()
00564 {
00565 obsVisibleList.clear();
00566
00567 for(ObservationList::iterator obsIter = observationList().begin(); obsIter != observationList().end();obsIter++)
00568 {
00569 observation_ptr_t obsPtr = *obsIter;
00570
00571 obsPtr->clearFlags();
00572 obsPtr->counters.nFrameSinceLastVisible++;
00573 obsPtr->measurement.matchScore = 0;
00574
00575 #if PROJECT_MEAN_VISIBILITY
00576 obsPtr->projectMean();
00577 #else
00578 obsPtr->project(multi_hyps_);
00579 #endif
00580
00581 if (obsPtr->predictVisibility())
00582 {
00583 bool add;
00584 #if VISIBILITY_MAP
00585 double visibility, viscertainty;
00586 obsPtr->landmark().visibilityMap.estimateVisibility(obsPtr, visibility, viscertainty);
00587 add = false;
00588 if (visibility > 0.75 && viscertainty > 0.75) add = true; else
00589 if (!obsPtr->landmark().converged)
00590 { if (visibility < 0.25) visibility = 0.25; }
00591 else
00592 { if (visibility < 0.1) visibility = 0.1; }
00593 if (viscertainty < 0.25) visibility = 0.25;
00594 if (rtslam::rand()%1024 < visibility*1024) add = true;
00595 #else
00596 add = true;
00597 #endif
00598
00599 if (add)
00600 obsVisibleList.push_back(obsPtr);
00601
00602 }
00603 }
00604 remainingObsCount = obsVisibleList.size();
00605 }
00606
00607 template<class RawSpec,class SensorSpec, class FeatureSpec, class RoiSpec, class FeatureManagerSpec, class DetectorSpec, class MatcherSpec>
00608 void DataManagerOnePointRansac<RawSpec,SensorSpec,FeatureSpec,RoiSpec,FeatureManagerSpec,DetectorSpec,MatcherSpec>::
00609 updateVisibleObs()
00610 {
00611 featMan->renew();
00612
00613 for(ObsList::iterator obsIter = obsVisibleList.begin(); obsIter != obsVisibleList.end();obsIter++)
00614 {
00615 observation_ptr_t obsPtr = *obsIter;
00616 bool add = false;
00617
00618 if (obsPtr->events.updated) add = true; else
00619 if (mapManagerPtr()->isExclusive(obsPtr)) add = true;
00620
00621
00622 if (add && !obsPtr->events.killed)
00623 featMan->addObs(obsPtr->expectation.x(), obsPtr);
00624 }
00625 }
00626
00627
00628 template<class RawSpec,class SensorSpec, class FeatureSpec, class RoiSpec, class FeatureManagerSpec, class DetectorSpec, class MatcherSpec>
00629 void DataManagerOnePointRansac<RawSpec,SensorSpec,FeatureSpec,RoiSpec,FeatureManagerSpec,DetectorSpec,MatcherSpec>::
00630 getOneMatchedBaseObs(observation_ptr_t & obsBasePtr, boost::shared_ptr<RawSpec> rawData)
00631 {
00632 bool matchedBase = false;
00633 while (!matchedBase) {
00634
00635
00636 if (remainingObsCount <= 0) { obsBasePtr.reset(); return; }
00637 int n = rtslam::rand()%remainingObsCount;
00638 obsBasePtr = obsVisibleList[n];
00639
00640
00641
00642 if (!obsBasePtr->events.matched)
00643 {
00644 obsBasePtr->events.measured = true;
00645
00646 #if PROJECT_MEAN_VISIBILITY
00647 obsBasePtr->project(multi_hyps_);
00648 #endif
00649
00650 if (!matchWithExpectedInnovation(rawData, obsBasePtr))
00651 obsFailedList.push_back(obsBasePtr);
00652
00653
00654 }
00655 if (obsBasePtr->events.matched && obsBasePtr->hypotheses.size() == 0)
00656 {
00657 obsBasePtr->computeInnovation();
00658 obsBaseList.push_back(obsBasePtr);
00659 matchedBase = true;
00660 }
00661
00662 --remainingObsCount;
00663 obsVisibleList[n] = obsVisibleList[remainingObsCount];
00664 obsVisibleList[remainingObsCount] = obsBasePtr;
00665 }
00666 }
00667
00668
00669 template<class RawSpec,class SensorSpec, class FeatureSpec, class RoiSpec, class FeatureManagerSpec, class DetectorSpec, class MatcherSpec>
00670 vec DataManagerOnePointRansac<RawSpec,SensorSpec,FeatureSpec,RoiSpec,FeatureManagerSpec,DetectorSpec,MatcherSpec>::
00671 updateMean(const observation_ptr_t & obsPtr)
00672 {
00673
00674 vec x_copy = mapManagerPtr()->mapPtr()->x();
00675 ind_array ia_x = mapManagerPtr()->mapPtr()->ia_used_states();
00676 sym_mat &P = mapManagerPtr()->mapPtr()->P();
00677
00678
00679 mat K(ia_x.size(), obsPtr->innovation.size());
00680 kalman::computeKalmanGain(P, ia_x, obsPtr->innovation, obsPtr->INN_rsl, obsPtr->ia_rsl, K);
00681
00682
00683 ublas::project(x_copy, ia_x) += ublas::prod(K, obsPtr->innovation.x());
00684
00685 return x_copy;
00686 }
00687
00688
00689 template<class RawSpec,class SensorSpec, class FeatureSpec, class RoiSpec, class FeatureManagerSpec, class DetectorSpec, class MatcherSpec>
00690 void DataManagerOnePointRansac<RawSpec,SensorSpec,FeatureSpec,RoiSpec,FeatureManagerSpec,DetectorSpec,MatcherSpec>::
00691 projectFromMean(vec & exp, const observation_ptr_t & obsPtr, const vec & x)
00692 {
00693 vec nobs;
00694
00695
00696 vec7 robPose = ublas::project(x, obsPtr->sensorPtr()->robotPtr()->pose.ia());
00697 vec7 senPose = obsPtr->sensorPtr()->pose.x();
00698 vec7 senGlobPose = quaternion::composeFrames(robPose, senPose);
00699
00700
00701 vec lmk = ublas::project(x, obsPtr->landmarkPtr()->state.ia());
00702 obsPtr->model->project_func(senGlobPose, lmk, exp, nobs);
00703
00704
00705 }
00706
00707
00708 template<class RawSpec,class SensorSpec, class FeatureSpec, class RoiSpec, class FeatureManagerSpec, class DetectorSpec, class MatcherSpec>
00709 bool DataManagerOnePointRansac<RawSpec,SensorSpec,FeatureSpec,RoiSpec,FeatureManagerSpec,DetectorSpec,MatcherSpec>::
00710 isLowInnovationInlier(const observation_ptr_t & obsPtr, const vec & exp, double lowInnTh)
00711 {
00712 vec inn;
00713 obsPtr->computeInnovationMean(inn, obsPtr->measurement.x(), exp);
00714 return (ublas::norm_2(inn) < lowInnTh);
00715 }
00716
00717
00718 template<class RawSpec,class SensorSpec, class FeatureSpec, class RoiSpec, class FeatureManagerSpec, class DetectorSpec, class MatcherSpec>
00719 bool DataManagerOnePointRansac<RawSpec,SensorSpec,FeatureSpec,RoiSpec,FeatureManagerSpec,DetectorSpec,MatcherSpec>::
00720 matchWithExpectedInnovation(boost::shared_ptr<RawSpec> rawData, observation_ptr_t obsPtr, bool lowInnov)
00721 {
00722 if (obsPtr->predictAppearance())
00723 {
00724 RoiSpec roi;
00725
00726 bool global_matched = false;
00727 double global_score = 0.0;
00728 bool use_hypotheses = (obsPtr->hypotheses.size() != 0 && !lowInnov);
00729 int count = (use_hypotheses ? obsPtr->hypotheses.size() : 1);
00730 for(int i = 0; i < count; ++i)
00731 {
00732
00733 Expectation &exp = (use_hypotheses ? obsPtr->hypotheses[i].expectation : obsPtr->expectation);
00734 if (exp.x().size() == 2)
00735 {
00736 if (lowInnov)
00737 {
00738 jblas::sym_mat P = jblas::identity_mat(obsPtr->expectation.size())*jmath::sqr(matcher->params.lowInnov);
00739 roi = RoiSpec(ransac_exp, P, 2.0);
00740 } else
00741 {
00742 if (ublasExtra::det(exp.P()) > 5*jmath::sqr(matcher->params.maxSearchSize/jmath::sqr(matcher->params.mahalanobisTh)))
00743 return false;
00744 obsPtr->measurement.searchP = matcher->params.measVar*identity_mat(2);
00745 roi = RoiSpec(exp.x(), exp.P() + obsPtr->measurement.searchP, matcher->params.mahalanobisTh);
00746 }
00747 obsPtr->searchSize = roi.count();
00748 if (obsPtr->searchSize > matcher->params.maxSearchSize) roi.scale(sqrt(matcher->params.maxSearchSize/(double)obsPtr->searchSize));
00749 }
00750 else
00751 {
00752
00753 vec2 p1, p2;
00754 vec2 var1, var2;
00755 p1[0] = exp.x()[0]; p1[1] = exp.x()[1];
00756 p2[0] = exp.x()[2]; p2[1] = exp.x()[3];
00757 obsPtr->measurement.searchP = matcher->params.measVar*identity_mat(4);
00758 var1[0] = (exp.P()(0,0) + matcher->params.measVar) * matcher->params.mahalanobisTh;
00759 var1[1] = (exp.P()(1,1) + matcher->params.measVar) * matcher->params.mahalanobisTh;
00760 var2[0] = (exp.P()(2,2) + matcher->params.measVar) * matcher->params.mahalanobisTh;
00761 var2[1] = (exp.P()(3,3) + matcher->params.measVar) * matcher->params.mahalanobisTh;
00762
00763 int basex = min(p1[0]-var1[0],p2[0]-var2[0]);
00764 int basey = min(p1[1]-var1[1],p2[1]-var2[1]);
00765 cv::Rect rect(
00766 basex, basey,
00767 max(p1[0]+var1[0],p2[0]+var2[0]) - basex,
00768 max(p1[1]+var1[1],p2[1]+var2[1]) - basey
00769 );
00770 roi = RoiSpec(rect);
00771 }
00772
00773
00774 Measurement measurement(obsPtr->measurement.size());
00775 matcher->match(rawData, obsPtr->predictedAppearance, roi, measurement, obsPtr->observedAppearance);
00776 obsPtr->events.measured = true;
00777
00778
00779 double threshold = (lowInnov || obsPtr->landmark().converged || sqrt(jmath::sqr(roi.w()) + jmath::sqr(roi.h())) < matcher->params.hi_limit)*count ?
00780 matcher->params.threshold : matcher->params.hi_threshold;
00781
00782 bool matched = false;
00783 if (obsPtr->events.matched && lowInnov)
00784 { if (measurement.matchScore >= obsPtr->getMatchScore()-1e-6) matched = true; } else
00785 { if (measurement.matchScore >= threshold) matched = true; }
00786 if (use_hypotheses && measurement.matchScore < global_score-1e-6) matched = false;
00787
00788 if (matched)
00789 {
00790 #if PROJECT_MEAN_VISIBILITY
00791 if (lowInnov && !obsPtr->events.predicted) obsPtr->project(false);
00792 #endif
00793
00794 if (use_hypotheses)
00795 matched = ObservationAbstract::compatibilityTest(measurement, exp, matcher->params.mahalanobisTh);
00796 else
00797 matched = ObservationAbstract::compatibilityTest(measurement, obsPtr->expectation, matcher->params.mahalanobisTh);
00798 }
00799
00800 if (matched)
00801 {
00802 obsPtr->measurement = measurement;
00803 global_matched = true;
00804 global_score = measurement.matchScore;
00805 }
00806 }
00807 if (global_matched) obsPtr->events.matched = true;
00808 return global_matched;
00809 } else
00810 return false;
00811 }
00812
00813
00814 template<class RawSpec,class SensorSpec, class FeatureSpec, class RoiSpec, class FeatureManagerSpec, class DetectorSpec, class MatcherSpec>
00815 void DataManagerOnePointRansac<RawSpec,SensorSpec,FeatureSpec,RoiSpec,FeatureManagerSpec,DetectorSpec,MatcherSpec>::
00816 dump(raw_ptr_t data)
00817 {
00818 LoggableMatchings *lm = new LoggableMatchings(data->name() + ".obs");
00819 for(ObservationList::iterator obsIter = observationList().begin(); obsIter != observationList().end();obsIter++)
00820 {
00821 observation_ptr_t obsPtr = *obsIter;
00822 if (obsPtr->events.updated) lm->addMatching(obsPtr->id(), obsPtr->measurement.x(0), obsPtr->measurement.x(1));
00823 }
00824 if (loggerTask) loggerTask->push(lm);
00825 }
00826
00827
00828 template<class RawSpec,class SensorSpec, class FeatureSpec, class RoiSpec, class FeatureManagerSpec, class DetectorSpec, class MatcherSpec>
00829 void DataManagerOnePointRansac<RawSpec,SensorSpec,FeatureSpec,RoiSpec,FeatureManagerSpec,DetectorSpec,MatcherSpec>::
00830 writeLogHeader(kernel::DataLogger& log) const
00831 {
00832 log.writeComment("DataManager");
00833 log.writeLegendTokens("visible measured matched updated created killed");
00834 }
00835
00836 template<class RawSpec,class SensorSpec, class FeatureSpec, class RoiSpec, class FeatureManagerSpec, class DetectorSpec, class MatcherSpec>
00837 void DataManagerOnePointRansac<RawSpec,SensorSpec,FeatureSpec,RoiSpec,FeatureManagerSpec,DetectorSpec,MatcherSpec>::
00838 writeLogData(kernel::DataLogger& log) const
00839 {
00840 log.writeData(counters.visible);
00841 log.writeData(counters.measured);
00842 log.writeData(counters.matched);
00843 log.writeData(counters.updated);
00844 log.writeData(counters.created);
00845 log.writeData(counters.killed);
00846 }
00847
00848
00849
00850 }
00851 }
00852