mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-01 17:10:26 +08:00
Fixed default nearest neighbor approach for the dictionary when the parameter is not set.
rtabmap_gui parameters panel can be opened without rtabmap parameters set on ROS (only GUI parameters can be changed). Rtabmap: added getStatistics() method for convenience Rtabmap/Memory: added deleteLastLocation() method to remove the last location in the STM. git-svn-id: http://rtabmap.googlecode.com/svn/trunk/rtabmap@779 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
@@ -75,6 +75,7 @@ public:
|
|||||||
bool incrementMarginOnLoop = false,
|
bool incrementMarginOnLoop = false,
|
||||||
bool ignoreLoopIds = false,
|
bool ignoreLoopIds = false,
|
||||||
double * dbAccessTime = 0) const;
|
double * dbAccessTime = 0) const;
|
||||||
|
void deleteLastLocation();
|
||||||
|
|
||||||
//getters
|
//getters
|
||||||
const std::set<int> & getWorkingMem() const {return _workingMem;}
|
const std::set<int> & getWorkingMem() const {return _workingMem;}
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ public:
|
|||||||
std::multimap<int, cv::KeyPoint> getWords(int locationId);
|
std::multimap<int, cv::KeyPoint> getWords(int locationId);
|
||||||
std::map<int, int> getNeighbors(int nodeId, int margin, bool lookInLTM = false);
|
std::map<int, int> getNeighbors(int nodeId, int margin, bool lookInLTM = false);
|
||||||
bool isInSTM(int locationId);
|
bool isInSTM(int locationId);
|
||||||
|
Statistics getStatistics();
|
||||||
|
|
||||||
void setTimeThreshold(float maxTimeAllowed); // in ms
|
void setTimeThreshold(float maxTimeAllowed); // in ms
|
||||||
|
|
||||||
@@ -106,6 +107,7 @@ public:
|
|||||||
void dumpData();
|
void dumpData();
|
||||||
void updateParameters(const ParametersMap & parameters);
|
void updateParameters(const ParametersMap & parameters);
|
||||||
void setWorkingDirectory(std::string path);
|
void setWorkingDirectory(std::string path);
|
||||||
|
void deleteLastLocation();
|
||||||
|
|
||||||
void adjustLikelihood(std::map<int, float> & likelihood) const;
|
void adjustLikelihood(std::map<int, float> & likelihood) const;
|
||||||
std::pair<int, float> selectHypothesis(const std::map<int, float> & posterior,
|
std::pair<int, float> selectHypothesis(const std::map<int, float> & posterior,
|
||||||
@@ -173,6 +175,8 @@ private:
|
|||||||
std::list<std::string> _bufferedLogsF;
|
std::list<std::string> _bufferedLogsF;
|
||||||
std::list<std::string> _bufferedLogsI;
|
std::list<std::string> _bufferedLogsI;
|
||||||
|
|
||||||
|
Statistics statistics_;
|
||||||
|
|
||||||
std::string _wDir;
|
std::string _wDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -149,16 +149,16 @@ private:
|
|||||||
class RtabmapEvent : public UEvent
|
class RtabmapEvent : public UEvent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RtabmapEvent(Statistics ** stats) :
|
RtabmapEvent(const Statistics & stats) :
|
||||||
UEvent(0),
|
UEvent(0),
|
||||||
_stats(*stats) {}
|
_stats(stats) {}
|
||||||
|
|
||||||
virtual ~RtabmapEvent() {if(_stats) delete _stats;}
|
virtual ~RtabmapEvent() {}
|
||||||
const Statistics & getStats() const {return *_stats;}
|
const Statistics & getStats() const {return _stats;}
|
||||||
virtual std::string getClassName() const {return std::string("RtabmapEvent");}
|
virtual std::string getClassName() const {return std::string("RtabmapEvent");}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Statistics * _stats;
|
Statistics _stats;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RtabmapEventCmd : public UEvent
|
class RtabmapEventCmd : public UEvent
|
||||||
|
|||||||
@@ -1384,6 +1384,38 @@ const Signature * Memory::getLastSignature() const
|
|||||||
return _lastSignature;
|
return _lastSignature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Memory::deleteLastLocation()
|
||||||
|
{
|
||||||
|
Signature * lastSignature = _lastSignature;
|
||||||
|
if(_lastSignature)
|
||||||
|
{
|
||||||
|
UDEBUG("deleting last location %d", lastSignature->id());
|
||||||
|
const std::set<int> & neighbors = lastSignature->getNeighbors();
|
||||||
|
for(std::set<int>::iterator iter=neighbors.begin(); iter!=neighbors.end(); ++iter)
|
||||||
|
{
|
||||||
|
Signature * s = _getSignature(*iter);
|
||||||
|
if(s)
|
||||||
|
{
|
||||||
|
s->removeNeighbor(lastSignature->id());
|
||||||
|
_lastSignature = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::set<int> & child = lastSignature->getChildLoopClosureIds();
|
||||||
|
for(std::set<int>::iterator iter=child.begin(); iter!=child.end(); ++iter)
|
||||||
|
{
|
||||||
|
Signature * s = _getSignature(*iter);
|
||||||
|
if(s)
|
||||||
|
{
|
||||||
|
s->removeLoopClosureId(lastSignature->id());
|
||||||
|
s->setWeight(s->getWeight() + lastSignature->getWeight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->moveToTrash(lastSignature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Memory::addLoopClosureLink(int oldId, int newId)
|
bool Memory::addLoopClosureLink(int oldId, int newId)
|
||||||
{
|
{
|
||||||
ULOGGER_INFO("old=%d, new=%d", oldId, newId);
|
ULOGGER_INFO("old=%d, new=%d", oldId, newId);
|
||||||
|
|||||||
@@ -533,6 +533,12 @@ bool Rtabmap::isInSTM(int locationId)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Statistics Rtabmap::getStatistics()
|
||||||
|
{
|
||||||
|
UScopeMutex s(&_threadMutex);
|
||||||
|
return statistics_;
|
||||||
|
}
|
||||||
|
|
||||||
void Rtabmap::clearBufferedSensors()
|
void Rtabmap::clearBufferedSensors()
|
||||||
{
|
{
|
||||||
_imageMutex.lock();
|
_imageMutex.lock();
|
||||||
@@ -1146,60 +1152,59 @@ void Rtabmap::process()
|
|||||||
// Posterior is empty if a bad signature is detected
|
// Posterior is empty if a bad signature is detected
|
||||||
float vpHypothesis = posterior.size()?posterior.at(Memory::kIdVirtual):0.0f;
|
float vpHypothesis = posterior.size()?posterior.at(Memory::kIdVirtual):0.0f;
|
||||||
|
|
||||||
// only prepare statistics if required or when there is a loop closure
|
// prepare statistics
|
||||||
Statistics * stat = 0;
|
statistics_ = Statistics(); // reset
|
||||||
if(_lcHypothesisId || _publishStats)
|
if(_lcHypothesisId || _publishStats)
|
||||||
{
|
{
|
||||||
ULOGGER_INFO("sending stats...");
|
ULOGGER_INFO("sending stats...");
|
||||||
stat = new Statistics();
|
statistics_.setRefImageId(refId);
|
||||||
stat->setRefImageId(refId);
|
|
||||||
if(_lcHypothesisId != Memory::kIdInvalid)
|
if(_lcHypothesisId != Memory::kIdInvalid)
|
||||||
{
|
{
|
||||||
stat->setLoopClosureId(_lcHypothesisId);
|
statistics_.setLoopClosureId(_lcHypothesisId);
|
||||||
ULOGGER_INFO("Loop closure detected! With id=%d", _lcHypothesisId);
|
ULOGGER_INFO("Loop closure detected! With id=%d", _lcHypothesisId);
|
||||||
}
|
}
|
||||||
if(_publishStats && refId != Memory::kIdInvalid)
|
if(_publishStats && refId != Memory::kIdInvalid)
|
||||||
{
|
{
|
||||||
ULOGGER_INFO("send all stats...");
|
ULOGGER_INFO("send all stats...");
|
||||||
stat->setExtended(1);
|
statistics_.setExtended(1);
|
||||||
|
|
||||||
stat->addStatistic(Statistics::kLoopHighest_hypothesis_id(), hypothesis.first);
|
statistics_.addStatistic(Statistics::kLoopHighest_hypothesis_id(), hypothesis.first);
|
||||||
stat->addStatistic(Statistics::kLoopHighest_hypothesis_value(), hypothesis.second);
|
statistics_.addStatistic(Statistics::kLoopHighest_hypothesis_value(), hypothesis.second);
|
||||||
stat->addStatistic(Statistics::kHypothesis_reactivated(), lcHypothesisReactivated);
|
statistics_.addStatistic(Statistics::kHypothesis_reactivated(), lcHypothesisReactivated);
|
||||||
stat->addStatistic(Statistics::kLoopVp_hypothesis(), vpHypothesis);
|
statistics_.addStatistic(Statistics::kLoopVp_hypothesis(), vpHypothesis);
|
||||||
stat->addStatistic(Statistics::kLoopReactivateId(), _retrievedId);
|
statistics_.addStatistic(Statistics::kLoopReactivateId(), _retrievedId);
|
||||||
stat->addStatistic(Statistics::kLoopHypothesis_ratio(), hypothesisRatio);
|
statistics_.addStatistic(Statistics::kLoopHypothesis_ratio(), hypothesisRatio);
|
||||||
|
|
||||||
stat->addStatistic(Statistics::kMemoryWorking_memory_size(), _memory->getWorkingMem().size());
|
statistics_.addStatistic(Statistics::kMemoryWorking_memory_size(), _memory->getWorkingMem().size());
|
||||||
stat->addStatistic(Statistics::kMemoryShort_time_memory_size(), _memory->getStMem().size());
|
statistics_.addStatistic(Statistics::kMemoryShort_time_memory_size(), _memory->getStMem().size());
|
||||||
stat->addStatistic(Statistics::kMemorySignatures_retrieved(), (float)signaturesRetrieved.size());
|
statistics_.addStatistic(Statistics::kMemorySignatures_retrieved(), (float)signaturesRetrieved.size());
|
||||||
stat->addStatistic(Statistics::kMemoryImages_buffered(), (float)_imageBuffer.size());
|
statistics_.addStatistic(Statistics::kMemoryImages_buffered(), (float)_imageBuffer.size());
|
||||||
|
|
||||||
// timing...
|
// timing...
|
||||||
stat->addStatistic(Statistics::kTimingMemory_update(), timeMemoryUpdate*1000);
|
statistics_.addStatistic(Statistics::kTimingMemory_update(), timeMemoryUpdate*1000);
|
||||||
stat->addStatistic(Statistics::kTimingReactivation(), timeReactivations*1000);
|
statistics_.addStatistic(Statistics::kTimingReactivation(), timeReactivations*1000);
|
||||||
stat->addStatistic(Statistics::kTimingAdd_loop_closure_link(), timeAddLoopClosureLink*1000);
|
statistics_.addStatistic(Statistics::kTimingAdd_loop_closure_link(), timeAddLoopClosureLink*1000);
|
||||||
stat->addStatistic(Statistics::kTimingLikelihood_computation(), timeLikelihoodCalculation*1000);
|
statistics_.addStatistic(Statistics::kTimingLikelihood_computation(), timeLikelihoodCalculation*1000);
|
||||||
stat->addStatistic(Statistics::kTimingPosterior_computation(), timePosteriorCalculation*1000);
|
statistics_.addStatistic(Statistics::kTimingPosterior_computation(), timePosteriorCalculation*1000);
|
||||||
stat->addStatistic(Statistics::kTimingHypotheses_creation(), timeHypothesesCreation*1000);
|
statistics_.addStatistic(Statistics::kTimingHypotheses_creation(), timeHypothesesCreation*1000);
|
||||||
stat->addStatistic(Statistics::kTimingHypotheses_validation(), timeHypothesesValidation*1000);
|
statistics_.addStatistic(Statistics::kTimingHypotheses_validation(), timeHypothesesValidation*1000);
|
||||||
stat->addStatistic(Statistics::kTimingCleaning_neighbors(), timeCleaningNeighbors*1000);
|
statistics_.addStatistic(Statistics::kTimingCleaning_neighbors(), timeCleaningNeighbors*1000);
|
||||||
|
|
||||||
// memory update timings
|
// memory update timings
|
||||||
for(std::map<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);
|
statistics_.addStatistic(iter->first, iter->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Surf specific parameters
|
// Surf specific parameters
|
||||||
stat->addStatistic(Statistics::kKeypointDictionary_size(), dictionarySize);
|
statistics_.addStatistic(Statistics::kKeypointDictionary_size(), dictionarySize);
|
||||||
|
|
||||||
//Epipolar geometry constraint
|
//Epipolar geometry constraint
|
||||||
stat->addStatistic(Statistics::kLoopRejectedHypothesis(), rejectedHypothesis?1.0f:0);
|
statistics_.addStatistic(Statistics::kLoopRejectedHypothesis(), rejectedHypothesis?1.0f:0);
|
||||||
|
|
||||||
if(_publishImage)
|
if(_publishImage)
|
||||||
{
|
{
|
||||||
stat->setRefImage(image.image()); // raw data
|
statistics_.setRefImage(image.image()); // raw data
|
||||||
if(sLoop)
|
if(sLoop)
|
||||||
{
|
{
|
||||||
UTimer tmpTimer;
|
UTimer tmpTimer;
|
||||||
@@ -1209,33 +1214,33 @@ void Rtabmap::process()
|
|||||||
{
|
{
|
||||||
UWARN("getting image time = %fs", tmpTimer.ticks());
|
UWARN("getting image time = %fs", tmpTimer.ticks());
|
||||||
}
|
}
|
||||||
stat->setLoopImage(im);
|
statistics_.setLoopImage(im);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_publishLikelihood || _publishPdf)
|
if(_publishLikelihood || _publishPdf)
|
||||||
{
|
{
|
||||||
// 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(weights);
|
statistics_.setWeights(weights);
|
||||||
if(_publishPdf)
|
if(_publishPdf)
|
||||||
{
|
{
|
||||||
stat->setPosterior(posterior);
|
statistics_.setPosterior(posterior);
|
||||||
}
|
}
|
||||||
if(_publishLikelihood)
|
if(_publishLikelihood)
|
||||||
{
|
{
|
||||||
stat->setLikelihood(likelihood);
|
statistics_.setLikelihood(likelihood);
|
||||||
stat->setRawLikelihood(rawLikelihood);
|
statistics_.setRawLikelihood(rawLikelihood);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_publishKeypoints)
|
if(_publishKeypoints)
|
||||||
{
|
{
|
||||||
//Copy keypoints
|
//Copy keypoints
|
||||||
stat->setRefWords(signature->getWords());
|
statistics_.setRefWords(signature->getWords());
|
||||||
if(sLoop)
|
if(sLoop)
|
||||||
{
|
{
|
||||||
//Copy keypoints
|
//Copy keypoints
|
||||||
stat->setLoopWords(sLoop->getWords());
|
statistics_.setLoopWords(sLoop->getWords());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1280,21 +1285,18 @@ void Rtabmap::process()
|
|||||||
//==============================================================
|
//==============================================================
|
||||||
// Finalize statistics and log files
|
// Finalize statistics and log files
|
||||||
//==============================================================
|
//==============================================================
|
||||||
if(stat)
|
if(_publishStats)
|
||||||
{
|
{
|
||||||
if(_publishStats)
|
statistics_.addStatistic(Statistics::kTimingStatistics_creation(), timeStatsCreation*1000);
|
||||||
{
|
statistics_.addStatistic(Statistics::kTimingTotal(), totalTime*1000);
|
||||||
stat->addStatistic(Statistics::kTimingStatistics_creation(), timeStatsCreation*1000);
|
statistics_.addStatistic(Statistics::kTimingForgetting(), timeRealTimeLimitReachedProcess*1000);
|
||||||
stat->addStatistic(Statistics::kTimingTotal(), totalTime*1000);
|
statistics_.addStatistic(Statistics::kTimingJoining_trash(), timeJoiningTrash*1000);
|
||||||
stat->addStatistic(Statistics::kTimingForgetting(), timeRealTimeLimitReachedProcess*1000);
|
statistics_.addStatistic(Statistics::kTimingEmptying_trash(), timeEmptyingTrash*1000);
|
||||||
stat->addStatistic(Statistics::kTimingJoining_trash(), timeJoiningTrash*1000);
|
statistics_.addStatistic(Statistics::kTimingMemory_cleanup(), timeMemoryCleanup*1000);
|
||||||
stat->addStatistic(Statistics::kTimingEmptying_trash(), timeEmptyingTrash*1000);
|
statistics_.addStatistic(Statistics::kMemorySignatures_removed(), signaturesRemoved);
|
||||||
stat->addStatistic(Statistics::kTimingMemory_cleanup(), timeMemoryCleanup*1000);
|
|
||||||
stat->addStatistic(Statistics::kMemorySignatures_removed(), signaturesRemoved);
|
|
||||||
}
|
|
||||||
ULOGGER_DEBUG("posting stat event...");
|
|
||||||
this->post(new RtabmapEvent(&stat)); // the stat will be automatically deleted
|
|
||||||
}
|
}
|
||||||
|
ULOGGER_DEBUG("posting statistics_ event...");
|
||||||
|
this->post(new RtabmapEvent(statistics_));
|
||||||
|
|
||||||
std::list<float> nonNulls;
|
std::list<float> nonNulls;
|
||||||
float sumLikelihoods = 0.0f;
|
float sumLikelihoods = 0.0f;
|
||||||
@@ -1497,6 +1499,15 @@ void Rtabmap::setWorkingDirectory(std::string path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Rtabmap::deleteLastLocation()
|
||||||
|
{
|
||||||
|
UScopeMutex s(&_threadMutex);
|
||||||
|
if(_memory)
|
||||||
|
{
|
||||||
|
_memory->deleteLastLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Rtabmap::process(const cv::Mat & image, int id)
|
void Rtabmap::process(const cv::Mat & image, int id)
|
||||||
{
|
{
|
||||||
UScopeMutex s(&_threadMutex);
|
UScopeMutex s(&_threadMutex);
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ VWDictionary::VWDictionary(const ParametersMap & parameters) :
|
|||||||
_lastWordId(0),
|
_lastWordId(0),
|
||||||
_nn(0)
|
_nn(0)
|
||||||
{
|
{
|
||||||
|
this->setNNStrategy((NNStrategy)Parameters::defaultKpNNStrategy(), parameters);
|
||||||
this->parseParameters(parameters);
|
this->parseParameters(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +104,9 @@ void VWDictionary::parseParameters(const ParametersMap & parameters)
|
|||||||
{
|
{
|
||||||
nnStrategy = (NNStrategy)std::atoi((*iter).second.c_str());
|
nnStrategy = (NNStrategy)std::atoi((*iter).second.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
NNStrategy currentNNStrategy = this->nnStrategy();
|
NNStrategy currentNNStrategy = this->nnStrategy();
|
||||||
|
|
||||||
if(!_nn || ( nnStrategy!=kNNUndef && (nnStrategy != currentNNStrategy) ) )
|
if(!_nn || ( nnStrategy!=kNNUndef && (nnStrategy != currentNNStrategy) ) )
|
||||||
{
|
{
|
||||||
this->setNNStrategy(nnStrategy, parameters);
|
this->setNNStrategy(nnStrategy, parameters);
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ void showUsage()
|
|||||||
|
|
||||||
int main(int argc, char * argv[])
|
int main(int argc, char * argv[])
|
||||||
{
|
{
|
||||||
|
// ULogger::setType(ULogger::kTypeConsole);
|
||||||
|
//ULogger::setLevel(ULogger::kDebug);
|
||||||
|
|
||||||
if(argc < 2)
|
if(argc < 2)
|
||||||
{
|
{
|
||||||
showUsage();
|
showUsage();
|
||||||
|
|||||||
@@ -401,7 +401,7 @@ void PreferencesDialog::setupSignals()
|
|||||||
void PreferencesDialog::clicked(const QModelIndex &index)
|
void PreferencesDialog::clicked(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
QStandardItem * item = _indexModel->itemFromIndex(index);
|
QStandardItem * item = _indexModel->itemFromIndex(index);
|
||||||
if(item)
|
if(item && item->isEnabled())
|
||||||
{
|
{
|
||||||
int index = item->data().toInt();
|
int index = item->data().toInt();
|
||||||
if(_ui->radioButton_advanced->isChecked() && index >= 2)
|
if(_ui->radioButton_advanced->isChecked() && index >= 2)
|
||||||
@@ -575,7 +575,32 @@ void PreferencesDialog::readSettings(const QString & filePath)
|
|||||||
{
|
{
|
||||||
_parameters.clear();
|
_parameters.clear();
|
||||||
_obsoletePanels = kPanelDummy;
|
_obsoletePanels = kPanelDummy;
|
||||||
this->reject();
|
|
||||||
|
// only keep GUI settings
|
||||||
|
QStandardItem * parentItem = _indexModel->invisibleRootItem();
|
||||||
|
if(parentItem)
|
||||||
|
{
|
||||||
|
for(int i=1; i<parentItem->rowCount(); ++i)
|
||||||
|
{
|
||||||
|
parentItem->child(i)->setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ui->radioButton_basic->setEnabled(false);
|
||||||
|
_ui->radioButton_advanced->setEnabled(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// enable settings
|
||||||
|
QStandardItem * parentItem = _indexModel->invisibleRootItem();
|
||||||
|
if(parentItem)
|
||||||
|
{
|
||||||
|
for(int i=0; i<parentItem->rowCount(); ++i)
|
||||||
|
{
|
||||||
|
parentItem->child(i)->setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ui->radioButton_basic->setEnabled(true);
|
||||||
|
_ui->radioButton_advanced->setEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user