Added statistics : Rehearsal value, retrieval margin

Updated the way how the retrieval margin is increased/reset
Posterior ignoring the last added location to WM
Auto save figure, removed the "-" in the generated date name


git-svn-id: http://rtabmap.googlecode.com/svn/trunk/rtabmap@294 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
matlabbe
2011-07-18 17:59:57 +00:00
parent e75f0bff66
commit 73a2d589ab
9 changed files with 115 additions and 78 deletions
+5 -2
View File
@@ -47,6 +47,7 @@ LogF = importfile([PathPrefix '/' 'LogF.txt']);
% 15 stddev likelihood % 15 stddev likelihood
% 16 vp hypothesis % 16 vp hypothesis
% 17 timeEmtyingTrash % 17 timeEmtyingTrash
% 18 rehearsalValue
LogI = importfile([PathPrefix '/' 'LogI.txt']); LogI = importfile([PathPrefix '/' 'LogI.txt']);
% COLUMN HEADERS : % COLUMN HEADERS :
@@ -63,8 +64,10 @@ LogI = importfile([PathPrefix '/' 'LogI.txt']);
% 11 signaturesReactivated % 11 signaturesReactivated
% 12 lcHypothesisReactivated % 12 lcHypothesisReactivated
% 13 refUniqueWordsCount % 13 refUniqueWordsCount
% 14 reactivateId % 14 _reactivateId
% 15 non nulls count % 15 nonNulls.size()
% 16 directNeighborsNotReactivated
% 17 _spreadMargin
if isempty(LogI) || isempty(LogF) if isempty(LogI) || isempty(LogF)
error('Log files are empty') error('Log files are empty')
@@ -52,6 +52,7 @@ class RTABMAP_EXP Statistics
RTABMAP_STATS(Loop, Vp_likelihood,); RTABMAP_STATS(Loop, Vp_likelihood,);
RTABMAP_STATS(Loop, ReactivateId,); RTABMAP_STATS(Loop, ReactivateId,);
RTABMAP_STATS(Loop, Hypothesis_ratio,); RTABMAP_STATS(Loop, Hypothesis_ratio,);
RTABMAP_STATS(Loop, Retrieval_margin,)
RTABMAP_STATS(Memory, Working_memory_size,); RTABMAP_STATS(Memory, Working_memory_size,);
RTABMAP_STATS(Memory, Short_time_memory_size,); RTABMAP_STATS(Memory, Short_time_memory_size,);
+18 -14
View File
@@ -454,26 +454,30 @@ std::map<int, float> KeypointMemory::computeLikelihood(const Signature * signatu
const std::map<int, int> & wm = this->getWorkingMem(); const std::map<int, int> & wm = this->getWorkingMem();
for(std::map<int, int>::const_iterator iter = wm.begin(); iter!=wm.end(); ++iter) for(std::map<int, int>::const_iterator iter = wm.begin(); iter!=wm.end(); ++iter)
{ {
likelihood.insert(likelihood.end(), std::pair<int, float>(iter->first, 0)); //ignore the last in WM
if(_tfIdfNormalized) if(iter->first != wm.rbegin()->first)
{ {
const KeypointSignature * s = dynamic_cast<const KeypointSignature *>(this->getSignature(iter->first)); likelihood.insert(likelihood.end(), std::pair<int, float>(iter->first, 0));
float wordsCountRatio = -1; // default invalid if(_tfIdfNormalized)
if(s)
{ {
if(s->getWords().size() > newSurf->getWords().size()) const KeypointSignature * s = dynamic_cast<const KeypointSignature *>(this->getSignature(iter->first));
float wordsCountRatio = -1; // default invalid
if(s)
{ {
wordsCountRatio = float(newSurf->getWords().size()) / float(s->getWords().size()); if(s->getWords().size() > newSurf->getWords().size())
{
wordsCountRatio = float(newSurf->getWords().size()) / float(s->getWords().size());
}
else if(newSurf->getWords().size())
{
wordsCountRatio = float(s->getWords().size()) / float(newSurf->getWords().size());
}
calculatedWordsRatio.insert(std::pair<int, float>(iter->first, wordsCountRatio));
} }
else if(newSurf->getWords().size()) else
{ {
wordsCountRatio = float(s->getWords().size()) / float(newSurf->getWords().size()); calculatedWordsRatio.insert(std::pair<int, float>(iter->first, wordsCountRatio));
} }
calculatedWordsRatio.insert(std::pair<int, float>(iter->first, wordsCountRatio));
}
else
{
calculatedWordsRatio.insert(std::pair<int, float>(iter->first, wordsCountRatio));
} }
} }
} }
+50 -27
View File
@@ -236,20 +236,22 @@ void Memory::preUpdate()
} }
} }
bool Memory::update(const SMState * smState, std::list<std::pair<std::string, float> > & stats) bool Memory::update(const SMState * smState, std::map<std::string, float> & stats)
{ {
ULOGGER_DEBUG(""); ULOGGER_DEBUG("");
UTimer timer; UTimer timer;
UTimer totalTimer; UTimer totalTimer;
timer.start(); timer.start();
float t;
//============================================================ //============================================================
// Pre update... // Pre update...
//============================================================ //============================================================
ULOGGER_DEBUG("pre-updating..."); ULOGGER_DEBUG("pre-updating...");
this->preUpdate(); this->preUpdate();
stats.push_back(std::pair<std::string, float>(std::string("TimingMem/Pre-update/ms"), timer.ticks()*1000)); t=timer.ticks()*1000;
ULOGGER_DEBUG("time preUpdate=%f ms", stats.back().second); stats.insert(std::pair<std::string, float>(std::string("TimingMem/Pre-update/ms"), t));
ULOGGER_DEBUG("time preUpdate=%f ms", t);
//============================================================ //============================================================
// Create a signature with the image received. // Create a signature with the image received.
@@ -279,8 +281,9 @@ bool Memory::update(const SMState * smState, std::list<std::pair<std::string, fl
_lastLoopClosureId = signature->id(); _lastLoopClosureId = signature->id();
} }
stats.push_back(std::pair<std::string, float>(std::string("TimingMem/Signature creation/ms"), timer.ticks()*1000)); t=timer.ticks()*1000;
ULOGGER_DEBUG("time creating signature=%f ms", stats.back().second); stats.insert(std::pair<std::string, float>(std::string("TimingMem/Signature creation/ms"), t));
ULOGGER_DEBUG("time creating signature=%f ms", t);
//============================================================ //============================================================
// Comparison step... // Comparison step...
@@ -295,8 +298,8 @@ bool Memory::update(const SMState * smState, std::list<std::pair<std::string, fl
UTimer t; UTimer t;
maxId = rehearsal(signature, _similarityOnlyLast, maxValue); maxId = rehearsal(signature, _similarityOnlyLast, maxValue);
UDEBUG("t=%fs", t.ticks()); UDEBUG("t=%fs", t.ticks());
stats.push_back(std::pair<std::string, float>(std::string("Memory/Rehearsal Max Id/"), maxId)); stats.insert(std::pair<std::string, float>(std::string("Memory/Rehearsal Max Id/"), maxId));
stats.push_back(std::pair<std::string, float>(std::string("Memory/Rehearsal Value/"), maxValue)); stats.insert(std::pair<std::string, float>(std::string("Memory/Rehearsal Value/"), maxValue));
if(maxId > 0 && maxValue >= _similarityThreshold) if(maxId > 0 && maxValue >= _similarityThreshold)
{ {
if(_incrementalMemory) if(_incrementalMemory)
@@ -320,8 +323,10 @@ bool Memory::update(const SMState * smState, std::list<std::pair<std::string, fl
} }
UDEBUG("t=%fs", t.ticks()); UDEBUG("t=%fs", t.ticks());
} }
stats.push_back(std::pair<std::string, float>(std::string("TimingMem/Rehearsal/ms"), timer.ticks()*1000));
ULOGGER_DEBUG("time rehearsal=%f ms", stats.back().second); t=timer.ticks()*1000;
stats.insert(std::pair<std::string, float>(std::string("TimingMem/Rehearsal/ms"), t));
ULOGGER_DEBUG("time rehearsal=%f ms", t);
//============================================================ //============================================================
// Update the common signature // Update the common signature
@@ -354,7 +359,7 @@ bool Memory::update(const SMState * smState, std::list<std::pair<std::string, fl
UDEBUG("totalTimer = %fs", totalTimer.ticks()); UDEBUG("totalTimer = %fs", totalTimer.ticks());
stats.push_back(std::pair<std::string, float>(std::string("Memory/Last loop closure/"), _lastLoopClosureId)); stats.insert(std::pair<std::string, float>(std::string("Memory/Last loop closure/"), _lastLoopClosureId));
return true; return true;
} }
@@ -630,7 +635,7 @@ void Memory::clear()
/** /**
* Compute the likelihood of the signature with some others in the memory. If * Compute the likelihood of the signature with some others in the memory. If
* the signature ids list is empty, the likelihood will be calculated * the signature ids list is empty, the likelihood will be calculated
* for all signatures in the working time memory. * for all signatures in the working memory.
* If an error occurs, the result is empty. * If an error occurs, the result is empty.
*/ */
std::map<int, float> Memory::computeLikelihood(const Signature * signature, const std::set<int> & signatureIds) const std::map<int, float> Memory::computeLikelihood(const Signature * signature, const std::set<int> & signatureIds) const
@@ -655,21 +660,25 @@ std::map<int, float> Memory::computeLikelihood(const Signature * signature, cons
std::map<int, int>::const_iterator iter = wm.begin(); std::map<int, int>::const_iterator iter = wm.begin();
for(; iter!=wm.end(); ++iter) for(; iter!=wm.end(); ++iter)
{ {
float sim = signature->compareTo(this->getSignature(iter->first)); //ignore the last in WM
likelihood.insert(likelihood.end(), std::pair<int, float>(iter->first, sim)); if(iter->first != wm.rbegin()->first)
sumSimilarity += sim;
UDEBUG("sim %d with %d = %f", signature->id(), iter->first, sim);
if(sim>maxSim)
{ {
maxSim = sim; float sim = signature->compareTo(this->getSignature(iter->first));
} likelihood.insert(likelihood.end(), std::pair<int, float>(iter->first, sim));
if(sim) sumSimilarity += sim;
{ UDEBUG("sim %d with %d = %f", signature->id(), iter->first, sim);
++nonNulls; if(sim>maxSim)
} {
else maxSim = sim;
{ }
++nulls; if(sim)
{
++nonNulls;
}
else
{
++nulls;
}
} }
} }
ULOGGER_DEBUG("sumSimilarity=%f, maxSim=%f, nonNulls=%d, nulls=%d)", sumSimilarity, maxSim, nonNulls, nulls); ULOGGER_DEBUG("sumSimilarity=%f, maxSim=%f, nonNulls=%d, nulls=%d)", sumSimilarity, maxSim, nonNulls, nulls);
@@ -829,13 +838,23 @@ Signature * Memory::getRemovableSignature(const std::list<int> & ignoredIds, boo
if(_lastLoopClosureId > 0 && _stMem.find(_lastLoopClosureId) == _stMem.end()) if(_lastLoopClosureId > 0 && _stMem.find(_lastLoopClosureId) == _stMem.end())
{ {
// If set, it must be in WM // If set, it must be in WM
bool nullWeightFound = false;
std::map<int, int>::const_iterator iter = _workingMem.find(_lastLoopClosureId); std::map<int, int>::const_iterator iter = _workingMem.find(_lastLoopClosureId);
while(iter != _workingMem.end()) while(iter != _workingMem.end())
{ {
++currentRecentWmSize; ++currentRecentWmSize;
Signature * s = uValue(_signatures, iter->first, (Signature*)0);
if(s && s->getWeight() == 0)
{
nullWeightFound = true;
}
else if(!s)
{
UERROR("Signature not found ?!?");
}
++iter; ++iter;
} }
if(currentRecentWmSize && currentRecentWmSize < recentWmMaxSize) if(currentRecentWmSize>1 && !nullWeightFound && currentRecentWmSize < recentWmMaxSize)
{ {
recentWmImmunized = true; recentWmImmunized = true;
} }
@@ -1022,6 +1041,9 @@ void Memory::addLoopClosureLink(int oldId, int newId, bool rehearsal)
{ {
_lastLoopClosureId = newS->id(); _lastLoopClosureId = newS->id();
} }
// update weight
newS->setWeight(newS->getWeight() + 1 + oldS->getWeight());
} }
else else
{ {
@@ -1030,9 +1052,10 @@ void Memory::addLoopClosureLink(int oldId, int newId, bool rehearsal)
//this->merge(oldS, newS, kFullMerging); //this->merge(oldS, newS, kFullMerging);
_lastLoopClosureId = newS->id(); _lastLoopClosureId = newS->id();
newS->setWeight(newS->getWeight() + oldS->getWeight());
} }
newS->setWeight(newS->getWeight() + 1 + oldS->getWeight());
oldS->setLoopClosureId(newS->id()); oldS->setLoopClosureId(newS->id());
// keep actions from the old // keep actions from the old
+1 -1
View File
@@ -53,7 +53,7 @@ public:
virtual ~Memory(); virtual ~Memory();
virtual void parseParameters(const ParametersMap & parameters); virtual void parseParameters(const ParametersMap & parameters);
bool update(const SMState * rawData, std::list<std::pair<std::string, float> > & stats); bool update(const SMState * rawData, std::map<std::string, float> & stats);
virtual bool init(const std::string & dbDriverName, const std::string & dbUrl, bool dbOverwritten = false, const ParametersMap & parameters = ParametersMap()); virtual bool init(const std::string & dbDriverName, const std::string & dbUrl, bool dbOverwritten = false, const ParametersMap & parameters = ParametersMap());
virtual std::map<int, float> computeLikelihood(const Signature * signature, const std::set<int> & signatureIds = std::set<int>()) const; virtual std::map<int, float> computeLikelihood(const Signature * signature, const std::set<int> & signatureIds = std::set<int>()) const;
virtual int forget(const std::list<int> & ignoredIds = std::list<int>()); virtual int forget(const std::list<int> & ignoredIds = std::list<int>());
+37 -31
View File
@@ -612,7 +612,7 @@ void Rtabmap::process()
double timeMemoryCleanup = 0; double timeMemoryCleanup = 0;
double timeEmptyingMemoryTrash = 0; double timeEmptyingMemoryTrash = 0;
double timeStatsCreation = 0; double timeStatsCreation = 0;
std::list<std::pair<std::string, float> > memUpdateStats; std::map<std::string, float> memUpdateStats;
int refId = Memory::kIdInvalid; int refId = Memory::kIdInvalid;
float hypothesisRatio = 0.0f; // Only used for statistics float hypothesisRatio = 0.0f; // Only used for statistics
@@ -781,7 +781,7 @@ void Rtabmap::process()
//============================================================ //============================================================
// Likelihood computation // Likelihood computation
// Get the likelihood of the new signature // Get the likelihood of the new signature
// with all images contained in the working time memory + reactivated. // with all images contained in the working memory + reactivated.
//============================================================ //============================================================
ULOGGER_INFO("computing likelihood..."); ULOGGER_INFO("computing likelihood...");
likelihood = _memory->computeLikelihood(signature); likelihood = _memory->computeLikelihood(signature);
@@ -854,26 +854,40 @@ void Rtabmap::process()
timeHypothesesValidation = timer.ticks(); timeHypothesesValidation = timer.ticks();
ULOGGER_INFO("timeHypothesesValidation=%f",timeHypothesesValidation); ULOGGER_INFO("timeHypothesesValidation=%f",timeHypothesesValidation);
// We are tracking the next loop closures,
// reset the retrieval margin
_spreadMargin = 0;
} }
//============================================================ //============================================================
// Retrieval id update // Retrieval id update
//============================================================ //============================================================
int lastReactivatedId = _reactivateId;
std::list<std::pair<int, float> > hyp; std::list<std::pair<int, float> > hyp;
this->selectHypotheses(posterior, hyp, false); // using likelihood (only if in reactivated ids)
if(likelihood.at(hyp.front().first) > _remThr) this->selectHypotheses(likelihood, hyp, false);
if(std::find(reactivatedIds.begin(),reactivatedIds.end(), hyp.front().first) != reactivatedIds.end())
{ {
_reactivateId = hyp.front().first; _reactivateId = hyp.front().first;
} }
else
if(hypotheses.front().second < _loopRatio*_highestHypothesisValue)
{ {
if(std::find(reactivatedIds.begin(),reactivatedIds.end(), hypotheses.front().first) != reactivatedIds.end()) //using highest hypothesis
this->selectHypotheses(posterior, hyp, false);
if(likelihood.at(hyp.front().first) > _remThr)
{
_reactivateId = hyp.front().first;
}
// else don't change the reactivateId
}
// Spreading margin...
if(hypotheses.front().second >= _loopThr && !rejectedHypothesis)
{
// We are tracking the next loop closures,
// reset the retrieval margin
_spreadMargin = 0;
UDEBUG("Margin=0");
}
else if(std::find(reactivatedIds.begin(),reactivatedIds.end(), hypotheses.front().first) != reactivatedIds.end())
{
if(signaturesReactivated<2 || hypotheses.front().second < _loopRatio*_highestHypothesisValue)
{ {
// We are loosing the next loop closures (it // We are loosing the next loop closures (it
// can be temporary occlusions/bad images), // can be temporary occlusions/bad images),
@@ -881,21 +895,9 @@ void Rtabmap::process()
++_spreadMargin; ++_spreadMargin;
UDEBUG("Margin++"); UDEBUG("Margin++");
} }
else //else don't change the margin
{
// We lost the next loop closures (a new path is taken),
// reset the retrieval margin
_spreadMargin = 0;
UDEBUG("Margin=0");
}
} }
else if(signaturesReactivated < 2 && _reactivateId == lastReactivatedId) else
{
// If we are still, spread margin if no signatures were loaded...
++_spreadMargin;
UDEBUG("Margin++");
}
else if(signaturesReactivated >= 2)
{ {
// We lost the next loop closures (a new path is taken), // We lost the next loop closures (a new path is taken),
// reset the retrieval margin // reset the retrieval margin
@@ -982,6 +984,7 @@ void Rtabmap::process()
const KeypointSignature * ssRef = 0; const KeypointSignature * ssRef = 0;
const KeypointSignature * ssLoop = 0; const KeypointSignature * ssLoop = 0;
int lcHypothesisReactivated = 0; int lcHypothesisReactivated = 0;
float rehearsalValue = uValue(memUpdateStats, std::string("Memory/Rehearsal Value/"), 0.0f);
KeypointMemory * kpMem = dynamic_cast<KeypointMemory *>(_memory); KeypointMemory * kpMem = dynamic_cast<KeypointMemory *>(_memory);
if(kpMem) if(kpMem)
{ {
@@ -1061,6 +1064,7 @@ void Rtabmap::process()
stat->addStatistic(Statistics::kLoopVp_likelihood(), vpLikelihood); stat->addStatistic(Statistics::kLoopVp_likelihood(), vpLikelihood);
stat->addStatistic(Statistics::kLoopReactivateId(), _reactivateId); stat->addStatistic(Statistics::kLoopReactivateId(), _reactivateId);
stat->addStatistic(Statistics::kLoopHypothesis_ratio(), hypothesisRatio); stat->addStatistic(Statistics::kLoopHypothesis_ratio(), hypothesisRatio);
stat->addStatistic(Statistics::kLoopRetrieval_margin(), _spreadMargin);
// Child count by parent signature on the root of the memory ... for statistics // Child count by parent signature on the root of the memory ... for statistics
stat->setWeights(_memory->getWeights()); stat->setWeights(_memory->getWeights());
@@ -1082,7 +1086,7 @@ void Rtabmap::process()
stat->addStatistic(Statistics::kTimingCleaning_neighbors(), timeCleaningNeighbors*1000); stat->addStatistic(Statistics::kTimingCleaning_neighbors(), timeCleaningNeighbors*1000);
// memory update timings // memory update timings
for(std::list<std::pair<std::string, float> >::iterator iter = memUpdateStats.begin(); iter!=memUpdateStats.end(); ++iter) for(std::map<std::string, float>::iterator iter = memUpdateStats.begin(); iter!=memUpdateStats.end(); ++iter)
{ {
stat->addStatistic(iter->first, iter->second); stat->addStatistic(iter->first, iter->second);
} }
@@ -1203,7 +1207,7 @@ void Rtabmap::process()
if(_foutFloat) if(_foutFloat)
{ {
fprintf(_foutFloat, "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n", fprintf(_foutFloat, "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n",
totalTime, totalTime,
timeMemoryUpdate, timeMemoryUpdate,
timeReactivations, timeReactivations,
@@ -1220,12 +1224,13 @@ void Rtabmap::process()
mean, mean,
stddev, stddev,
vpHypothesis, vpHypothesis,
timeEmptyingMemoryTrash); timeEmptyingMemoryTrash,
rehearsalValue);
} }
if(_foutInt) if(_foutInt)
{ {
fprintf(_foutInt, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %lu %d\n", fprintf(_foutInt, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %lu %d %d\n",
_lcHypothesisId, _lcHypothesisId,
highestHypothesisId, highestHypothesisId,
signaturesRemoved, signaturesRemoved,
@@ -1241,7 +1246,8 @@ void Rtabmap::process()
refUniqueWordsCount, refUniqueWordsCount,
_reactivateId, _reactivateId,
nonNulls.size(), nonNulls.size(),
directNeighborsNotReactivated); directNeighborsNotReactivated,
_spreadMargin);
} }
ULOGGER_INFO("Time logging = %f...", timer.ticks()); ULOGGER_INFO("Time logging = %f...", timer.ticks());
//ULogger::flush(); //ULogger::flush();
+1 -1
View File
@@ -287,7 +287,7 @@ void Tests::testBayesFilter()
for(int i=1; i<11; ++i) for(int i=1; i<11; ++i)
{ {
//ULOGGER_DEBUG("--- %d ---", i); //ULOGGER_DEBUG("--- %d ---", i);
std::list<std::pair<std::string, float> > memStats; std::map<std::string, float> memStats;
mem.update(0, memStats); mem.update(0, memStats);
posterior = bayes.computePosterior(&mem, likelihood); posterior = bayes.computePosterior(&mem, likelihood);
likelihood.insert(std::pair<int, float>(i, 1)); likelihood.insert(std::pair<int, float>(i, 1));
+1 -1
View File
@@ -888,7 +888,7 @@ void MainWindow::captureScreen()
dir.mkdir(targetDir); dir.mkdir(targetDir);
} }
targetDir += "/"; targetDir += "/";
QString name = QDateTime::currentDateTime().toString("yyMMdd-hhmmsszzz") + ".png"; QString name = QDateTime::currentDateTime().toString("yyMMddhhmmsszzz") + ".png";
_ui->statusbar->clearMessage(); _ui->statusbar->clearMessage();
QPixmap figure = QPixmap::grabWidget(this); QPixmap figure = QPixmap::grabWidget(this);
figure.save(targetDir + name); figure.save(targetDir + name);
+1 -1
View File
@@ -2047,7 +2047,7 @@ void Plot::captureScreen()
dir.mkdir(targetDir); dir.mkdir(targetDir);
} }
targetDir += "/"; targetDir += "/";
QString name = QDateTime::currentDateTime().toString("yyMMdd-hhmmsszzz") + ".png"; QString name = QDateTime::currentDateTime().toString("yyMMddhhmmsszzz") + ".png";
QPixmap figure = QPixmap::grabWidget(this); QPixmap figure = QPixmap::grabWidget(this);
figure.save(targetDir + name); figure.save(targetDir + name);
} }