mirror of
https://github.com/introlab/rtabmap.git
synced 2026-10-04 00:57:46 +08:00
Merge branch 'master' of github.com:introlab/rtabmap into reduce_graph_orphan_nodes
This commit is contained in:
@@ -204,7 +204,7 @@ rtabmap::ParametersMap RTABMapApp::getRtabmapParameters()
|
|||||||
uInsert(parameters, rtabmap::ParametersPair(rtabmap::Parameters::kRtabmapMaxRetrieved(), "0")); // deactivate global retrieval
|
uInsert(parameters, rtabmap::ParametersPair(rtabmap::Parameters::kRtabmapMaxRetrieved(), "0")); // deactivate global retrieval
|
||||||
uInsert(parameters, rtabmap::ParametersPair(rtabmap::Parameters::kRGBDMaxLocalRetrieved(), "0")); // deactivate local retrieval
|
uInsert(parameters, rtabmap::ParametersPair(rtabmap::Parameters::kRGBDMaxLocalRetrieved(), "0")); // deactivate local retrieval
|
||||||
uInsert(parameters, rtabmap::ParametersPair(rtabmap::Parameters::kMemMapLabelsAdded(), "false")); // don't create map labels
|
uInsert(parameters, rtabmap::ParametersPair(rtabmap::Parameters::kMemMapLabelsAdded(), "false")); // don't create map labels
|
||||||
uInsert(parameters, rtabmap::ParametersPair(rtabmap::Parameters::kRtabmapMemoryThr(), "2")); // keep the WM empty
|
uInsert(parameters, rtabmap::ParametersPair(rtabmap::Parameters::kRtabmapMemoryThr(), "1")); // keep the WM empty
|
||||||
uInsert(parameters, rtabmap::ParametersPair(rtabmap::Parameters::kMemSTMSize(), "1")); // STM=1 -->
|
uInsert(parameters, rtabmap::ParametersPair(rtabmap::Parameters::kMemSTMSize(), "1")); // STM=1 -->
|
||||||
uInsert(parameters, rtabmap::ParametersPair(rtabmap::Parameters::kRGBDProximityBySpace(), "false"));
|
uInsert(parameters, rtabmap::ParametersPair(rtabmap::Parameters::kRGBDProximityBySpace(), "false"));
|
||||||
uInsert(parameters, rtabmap::ParametersPair(rtabmap::Parameters::kRGBDLinearUpdate(), "0"));
|
uInsert(parameters, rtabmap::ParametersPair(rtabmap::Parameters::kRGBDLinearUpdate(), "0"));
|
||||||
|
|||||||
@@ -149,6 +149,9 @@ public:
|
|||||||
|
|
||||||
//getters
|
//getters
|
||||||
const std::map<int, double> & getWorkingMem() const {return _workingMem;}
|
const std::map<int, double> & getWorkingMem() const {return _workingMem;}
|
||||||
|
size_t getWorkingMemSize(bool ignoreIntermediateNodes = false) const;
|
||||||
|
int getWorkingMemIntermediateNodesCount() const {return _workingMemIntermediateNodesCount;}
|
||||||
|
int getStMemIntermediateNodesCount() const {return _stMemIntermediateNodesCount;}
|
||||||
const std::set<int> & getStMem() const {return _stMem;}
|
const std::set<int> & getStMem() const {return _stMem;}
|
||||||
int getMaxStMemSize() const {return _maxStMemSize;}
|
int getMaxStMemSize() const {return _maxStMemSize;}
|
||||||
std::multimap<int, Link> getNeighborLinks(int signatureId,
|
std::multimap<int, Link> getNeighborLinks(int signatureId,
|
||||||
@@ -360,6 +363,8 @@ private:
|
|||||||
bool _memoryChanged; // False by default, become true only when Memory::update() is called.
|
bool _memoryChanged; // False by default, become true only when Memory::update() is called.
|
||||||
bool _linksChanged; // False by default, become true when links are modified.
|
bool _linksChanged; // False by default, become true when links are modified.
|
||||||
int _signaturesAdded;
|
int _signaturesAdded;
|
||||||
|
int _workingMemIntermediateNodesCount; // number of nodes with weight==-1 currently in _workingMem
|
||||||
|
int _stMemIntermediateNodesCount; // number of nodes with weight==-1 currently in _stMem
|
||||||
bool _allNodesInWM;
|
bool _allNodesInWM;
|
||||||
bool _receivingOdometryFeatures;
|
bool _receivingOdometryFeatures;
|
||||||
GPS _gpsOrigin;
|
GPS _gpsOrigin;
|
||||||
|
|||||||
@@ -137,7 +137,9 @@ class RTABMAP_CORE_EXPORT Statistics
|
|||||||
RTABMAP_STATS(NeighborLinkRefining, Pts,);
|
RTABMAP_STATS(NeighborLinkRefining, Pts,);
|
||||||
|
|
||||||
RTABMAP_STATS(Memory, Working_memory_size,);
|
RTABMAP_STATS(Memory, Working_memory_size,);
|
||||||
|
RTABMAP_STATS(Memory, Working_memory_inter_size,);
|
||||||
RTABMAP_STATS(Memory, Short_time_memory_size,);
|
RTABMAP_STATS(Memory, Short_time_memory_size,);
|
||||||
|
RTABMAP_STATS(Memory, Short_time_memory_inter_size,);
|
||||||
RTABMAP_STATS(Memory, Database_memory_used, MB);
|
RTABMAP_STATS(Memory, Database_memory_used, MB);
|
||||||
RTABMAP_STATS(Memory, Signatures_removed,);
|
RTABMAP_STATS(Memory, Signatures_removed,);
|
||||||
RTABMAP_STATS(Memory, Immunized_globally,);
|
RTABMAP_STATS(Memory, Immunized_globally,);
|
||||||
|
|||||||
+89
-18
@@ -131,6 +131,8 @@ Memory::Memory(const ParametersMap & parameters) :
|
|||||||
_memoryChanged(false),
|
_memoryChanged(false),
|
||||||
_linksChanged(false),
|
_linksChanged(false),
|
||||||
_signaturesAdded(0),
|
_signaturesAdded(0),
|
||||||
|
_workingMemIntermediateNodesCount(0),
|
||||||
|
_stMemIntermediateNodesCount(0),
|
||||||
_allNodesInWM(true),
|
_allNodesInWM(true),
|
||||||
_receivingOdometryFeatures(false),
|
_receivingOdometryFeatures(false),
|
||||||
_badSignRatio(Parameters::defaultKpBadSignRatio()),
|
_badSignRatio(Parameters::defaultKpBadSignRatio()),
|
||||||
@@ -267,6 +269,10 @@ void Memory::loadDataFromDb(bool postInitClosingEvents)
|
|||||||
// global loop closures.
|
// global loop closures.
|
||||||
_signatures.insert(std::pair<int, Signature *>((*iter)->id(), *iter));
|
_signatures.insert(std::pair<int, Signature *>((*iter)->id(), *iter));
|
||||||
_workingMem.insert(std::make_pair((*iter)->id(), UTimer::now()));
|
_workingMem.insert(std::make_pair((*iter)->id(), UTimer::now()));
|
||||||
|
if((*iter)->getWeight() == -1)
|
||||||
|
{
|
||||||
|
++_workingMemIntermediateNodesCount;
|
||||||
|
}
|
||||||
if(!(*iter)->getGroundTruthPose().isNull()) {
|
if(!(*iter)->getGroundTruthPose().isNull()) {
|
||||||
_groundTruths.insert(std::make_pair((*iter)->id(), (*iter)->getGroundTruthPose()));
|
_groundTruths.insert(std::make_pair((*iter)->id(), (*iter)->getGroundTruthPose()));
|
||||||
}
|
}
|
||||||
@@ -1079,7 +1085,7 @@ bool Memory::update(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(_workingMem.size() <= 1)
|
if(this->getWorkingMemSize(true) == 0)
|
||||||
{
|
{
|
||||||
UWARN("The working memory is empty and the memory is not "
|
UWARN("The working memory is empty and the memory is not "
|
||||||
"incremental (Mem/IncrementalMemory=False), no loop closure "
|
"incremental (Mem/IncrementalMemory=False), no loop closure "
|
||||||
@@ -1255,6 +1261,10 @@ void Memory::addSignatureToStm(Signature * signature, const cv::Mat & covariance
|
|||||||
|
|
||||||
_signatures.insert(_signatures.end(), std::pair<int, Signature *>(signature->id(), signature));
|
_signatures.insert(_signatures.end(), std::pair<int, Signature *>(signature->id(), signature));
|
||||||
_stMem.insert(_stMem.end(), signature->id());
|
_stMem.insert(_stMem.end(), signature->id());
|
||||||
|
if(signature->getWeight() == -1)
|
||||||
|
{
|
||||||
|
++_stMemIntermediateNodesCount;
|
||||||
|
}
|
||||||
if(!signature->getGroundTruthPose().isNull()) {
|
if(!signature->getGroundTruthPose().isNull()) {
|
||||||
_groundTruths.insert(std::make_pair(signature->id(), signature->getGroundTruthPose()));
|
_groundTruths.insert(std::make_pair(signature->id(), signature->getGroundTruthPose()));
|
||||||
}
|
}
|
||||||
@@ -1276,6 +1286,10 @@ void Memory::addSignatureToWmFromLTM(Signature * signature)
|
|||||||
{
|
{
|
||||||
UDEBUG("Inserting node %d in WM...", signature->id());
|
UDEBUG("Inserting node %d in WM...", signature->id());
|
||||||
_workingMem.insert(std::make_pair(signature->id(), UTimer::now()));
|
_workingMem.insert(std::make_pair(signature->id(), UTimer::now()));
|
||||||
|
if(signature->getWeight() == -1)
|
||||||
|
{
|
||||||
|
++_workingMemIntermediateNodesCount;
|
||||||
|
}
|
||||||
_signatures.insert(std::pair<int, Signature*>(signature->id(), signature));
|
_signatures.insert(std::pair<int, Signature*>(signature->id(), signature));
|
||||||
if(!signature->getGroundTruthPose().isNull()) {
|
if(!signature->getGroundTruthPose().isNull()) {
|
||||||
_groundTruths.insert(std::make_pair(signature->id(), signature->getGroundTruthPose()));
|
_groundTruths.insert(std::make_pair(signature->id(), signature->getGroundTruthPose()));
|
||||||
@@ -1466,6 +1480,11 @@ void Memory::moveSignatureToWMFromSTM(int id, int * reducedToOut)
|
|||||||
if(reducedId == 0)
|
if(reducedId == 0)
|
||||||
{
|
{
|
||||||
_workingMem.insert(_workingMem.end(), std::make_pair(*_stMem.begin(), UTimer::now()));
|
_workingMem.insert(_workingMem.end(), std::make_pair(*_stMem.begin(), UTimer::now()));
|
||||||
|
if(this->_getSignature(*_stMem.begin())->getWeight() == -1)
|
||||||
|
{
|
||||||
|
++_workingMemIntermediateNodesCount;
|
||||||
|
--_stMemIntermediateNodesCount;
|
||||||
|
}
|
||||||
_stMem.erase(*_stMem.begin());
|
_stMem.erase(*_stMem.begin());
|
||||||
}
|
}
|
||||||
// else already removed from STM/WM in reduceNode()
|
// else already removed from STM/WM in reduceNode()
|
||||||
@@ -1486,6 +1505,19 @@ const VWDictionary * Memory::getVWDictionary() const
|
|||||||
return _vwd;
|
return _vwd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t Memory::getWorkingMemSize(bool ignoreIntermediateNodes) const
|
||||||
|
{
|
||||||
|
// -1 removes the virtual place
|
||||||
|
if(!ignoreIntermediateNodes)
|
||||||
|
{
|
||||||
|
return _workingMem.size() - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return _workingMem.size() - 1 - _workingMemIntermediateNodesCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::multimap<int, Link> Memory::getNeighborLinks(
|
std::multimap<int, Link> Memory::getNeighborLinks(
|
||||||
int signatureId,
|
int signatureId,
|
||||||
bool lookInDatabase) const
|
bool lookInDatabase) const
|
||||||
@@ -2022,6 +2054,7 @@ void Memory::clear()
|
|||||||
ULOGGER_ERROR("_stMem must be empty here, size=%d", _stMem.size());
|
ULOGGER_ERROR("_stMem must be empty here, size=%d", _stMem.size());
|
||||||
}
|
}
|
||||||
_stMem.clear();
|
_stMem.clear();
|
||||||
|
_stMemIntermediateNodesCount = 0;
|
||||||
|
|
||||||
this->cleanUnusedWords();
|
this->cleanUnusedWords();
|
||||||
|
|
||||||
@@ -2038,18 +2071,15 @@ void Memory::clear()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save some stats to the db, save only when the mem is not empty
|
// Save some stats to the db, save only when the mem is not empty
|
||||||
if(_dbDriver && (_stMem.size() || _workingMem.size()))
|
size_t workingMemSize = this->getWorkingMemSize(false);
|
||||||
|
if(_dbDriver && (_stMem.size() || workingMemSize))
|
||||||
{
|
{
|
||||||
unsigned int memSize = (unsigned int)(_workingMem.size() + _stMem.size());
|
unsigned int memSize = workingMemSize + _stMem.size();
|
||||||
if(_workingMem.size() && _workingMem.begin()->first < 0)
|
|
||||||
{
|
|
||||||
--memSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is only a safe check...not supposed to occur.
|
// this is only a safe check...not supposed to occur.
|
||||||
UASSERT_MSG(memSize == _signatures.size(),
|
UASSERT_MSG(memSize == _signatures.size(),
|
||||||
uFormat("The number of signatures don't match! _workingMem=%d, _stMem=%d, _signatures=%d",
|
uFormat("The number of signatures don't match! _workingMem=%d, _stMem=%d, _signatures=%d",
|
||||||
_workingMem.size(), _stMem.size(), _signatures.size()).c_str());
|
workingMemSize, _stMem.size(), _signatures.size()).c_str());
|
||||||
|
|
||||||
UDEBUG("Adding statistics after run...");
|
UDEBUG("Adding statistics after run...");
|
||||||
if(_memoryChanged)
|
if(_memoryChanged)
|
||||||
@@ -2096,6 +2126,7 @@ void Memory::clear()
|
|||||||
ULOGGER_ERROR("_workingMem must be empty here, size=%d", _workingMem.size());
|
ULOGGER_ERROR("_workingMem must be empty here, size=%d", _workingMem.size());
|
||||||
}
|
}
|
||||||
_workingMem.clear();
|
_workingMem.clear();
|
||||||
|
_workingMemIntermediateNodesCount = 0;
|
||||||
if(_signatures.size()!=0)
|
if(_signatures.size()!=0)
|
||||||
{
|
{
|
||||||
ULOGGER_ERROR("_signatures must be empty here, size=%d", _signatures.size());
|
ULOGGER_ERROR("_signatures must be empty here, size=%d", _signatures.size());
|
||||||
@@ -2482,7 +2513,7 @@ std::map<int, Transform> Memory::loadOptimizedPoses(Transform * lastlocalization
|
|||||||
"poses to force re-update. If you want to use the "
|
"poses to force re-update. If you want to use the "
|
||||||
"saved optimized poses, set %s to true",
|
"saved optimized poses, set %s to true",
|
||||||
(int)poses.size(),
|
(int)poses.size(),
|
||||||
(int)_workingMem.size()-1, // less virtual place
|
(int)this->getWorkingMemSize(false),
|
||||||
Parameters::kMemInitWMWithAllNodes().c_str());
|
Parameters::kMemInitWMWithAllNodes().c_str());
|
||||||
return std::map<int, Transform>();
|
return std::map<int, Transform>();
|
||||||
}
|
}
|
||||||
@@ -2590,18 +2621,21 @@ public:
|
|||||||
}
|
}
|
||||||
int weight, age, id;
|
int weight, age, id;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::list<Signature *> Memory::getRemovableSignatures(int count, const std::set<int> & ignoredIds)
|
std::list<Signature *> Memory::getRemovableSignatures(int count, const std::set<int> & ignoredIds)
|
||||||
{
|
{
|
||||||
//UDEBUG("");
|
//UDEBUG("");
|
||||||
std::list<Signature *> removableSignatures;
|
std::list<Signature *> removableSignatures;
|
||||||
std::map<WeightAgeIdKey, Signature *> weightAgeIdMap;
|
std::map<WeightAgeIdKey, Signature *> weightAgeIdMap;
|
||||||
|
|
||||||
// Find the last index to check...
|
size_t workingMemSize = this->getWorkingMemSize(true);
|
||||||
UDEBUG("mem.size()=%d, ignoredIds.size()=%d", (int)_workingMem.size(), (int)ignoredIds.size());
|
|
||||||
|
|
||||||
if(_workingMem.size())
|
// Find the last index to check...
|
||||||
|
UDEBUG("mem.size()=%d, ignoredIds.size()=%d", (int)workingMemSize, (int)ignoredIds.size());
|
||||||
|
|
||||||
|
if(workingMemSize > 0)
|
||||||
{
|
{
|
||||||
int recentWmMaxSize = _recentWmRatio * float(_workingMem.size());
|
int recentWmMaxSize = _recentWmRatio * float(workingMemSize);
|
||||||
bool recentWmImmunized = false;
|
bool recentWmImmunized = false;
|
||||||
// look for the position of the lastLoopClosureId in WM
|
// look for the position of the lastLoopClosureId in WM
|
||||||
int currentRecentWmSize = 0;
|
int currentRecentWmSize = 0;
|
||||||
@@ -2618,7 +2652,7 @@ std::list<Signature *> Memory::getRemovableSignatures(int count, const std::set<
|
|||||||
{
|
{
|
||||||
recentWmImmunized = true;
|
recentWmImmunized = true;
|
||||||
}
|
}
|
||||||
else if(currentRecentWmSize == 0 && _workingMem.size() > 1)
|
else if(currentRecentWmSize == 0)
|
||||||
{
|
{
|
||||||
UERROR("Last loop closure id not found in WM (%d)", _lastGlobalLoopClosureId);
|
UERROR("Last loop closure id not found in WM (%d)", _lastGlobalLoopClosureId);
|
||||||
}
|
}
|
||||||
@@ -2727,6 +2761,20 @@ void Memory::moveToTrash(Signature * s, bool keepLinkedToGraph, std::list<int> *
|
|||||||
//UDEBUG("id=%d", s?s->id():0);
|
//UDEBUG("id=%d", s?s->id():0);
|
||||||
if(s)
|
if(s)
|
||||||
{
|
{
|
||||||
|
// Keep the WM/STM intermediate-node counters in sync now, before the weight
|
||||||
|
// may be set to -9 below.
|
||||||
|
if(s->getWeight() == -1)
|
||||||
|
{
|
||||||
|
if(this->isInWM(s->id()))
|
||||||
|
{
|
||||||
|
--_workingMemIntermediateNodesCount;
|
||||||
|
}
|
||||||
|
else if(this->isInSTM(s->id()))
|
||||||
|
{
|
||||||
|
--_stMemIntermediateNodesCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Cleanup landmark indexes
|
// Cleanup landmark indexes
|
||||||
if(!s->getLandmarks().empty())
|
if(!s->getLandmarks().empty())
|
||||||
{
|
{
|
||||||
@@ -3054,6 +3102,19 @@ void Memory::convertToIntermediate(int locationId)
|
|||||||
Signature * location = _getSignature(locationId);
|
Signature * location = _getSignature(locationId);
|
||||||
if(location)
|
if(location)
|
||||||
{
|
{
|
||||||
|
// Keep the WM/STM intermediate-node counters in sync if the node is
|
||||||
|
// converted while already resident in memory.
|
||||||
|
if(location->getWeight() >= 0)
|
||||||
|
{
|
||||||
|
if(this->isInWM(locationId))
|
||||||
|
{
|
||||||
|
++_workingMemIntermediateNodesCount;
|
||||||
|
}
|
||||||
|
else if(this->isInSTM(locationId))
|
||||||
|
{
|
||||||
|
++_stMemIntermediateNodesCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
location->setWeight(-1);
|
location->setWeight(-1);
|
||||||
location->sensorData().setFeatures(std::vector<cv::KeyPoint>(), std::vector<cv::Point3f>(), cv::Mat());
|
location->sensorData().setFeatures(std::vector<cv::KeyPoint>(), std::vector<cv::Point3f>(), cv::Mat());
|
||||||
this->disableWordsRef(locationId); // won't be used for loop closure detection anymore
|
this->disableWordsRef(locationId); // won't be used for loop closure detection anymore
|
||||||
@@ -5196,11 +5257,21 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
|
|||||||
UDEBUG("time rectification = %fs", t);
|
UDEBUG("time rectification = %fs", t);
|
||||||
}
|
}
|
||||||
|
|
||||||
int treeSize= int(_workingMem.size() + _stMem.size());
|
int notIntermediateNodesCount = 0;
|
||||||
int meanWordsPerLocation = _feature2D->getMaxFeatures()>0?_feature2D->getMaxFeatures():0;
|
for(std::set<int>::iterator iter=_stMem.begin(); iter!=_stMem.end(); ++iter)
|
||||||
if(meanWordsPerLocation==0 && treeSize > 1)
|
|
||||||
{
|
{
|
||||||
meanWordsPerLocation = _vwd->getTotalActiveReferences() / (treeSize-1); // ignore virtual signature
|
const Signature * s = this->getSignature(*iter);
|
||||||
|
UASSERT(s != 0);
|
||||||
|
if(s->getWeight() >= 0)
|
||||||
|
{
|
||||||
|
++notIntermediateNodesCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int treeSize= int(this->getWorkingMemSize(true) + notIntermediateNodesCount);
|
||||||
|
int meanWordsPerLocation = _feature2D->getMaxFeatures()>0?_feature2D->getMaxFeatures():0;
|
||||||
|
if(meanWordsPerLocation==0 && treeSize > 0)
|
||||||
|
{
|
||||||
|
meanWordsPerLocation = _vwd->getTotalActiveReferences() / treeSize;
|
||||||
}
|
}
|
||||||
else if(_useOdometryFeatures) {
|
else if(_useOdometryFeatures) {
|
||||||
// To not detect first image as bad signature if odometry
|
// To not detect first image as bad signature if odometry
|
||||||
|
|||||||
+64
-43
@@ -378,9 +378,7 @@ void Rtabmap::init(const ParametersMap & parameters, const std::string & databas
|
|||||||
_optimizedPoses = _memory->loadOptimizedPoses(&lastPose);
|
_optimizedPoses = _memory->loadOptimizedPoses(&lastPose);
|
||||||
if(!_memory->isIncremental())
|
if(!_memory->isIncremental())
|
||||||
{
|
{
|
||||||
if(_optimizedPoses.empty() &&
|
if(_optimizedPoses.empty() && _memory->getWorkingMemSize(true) > 0)
|
||||||
_memory->getWorkingMem().size()>1 &&
|
|
||||||
_memory->getWorkingMem().lower_bound(1)!=_memory->getWorkingMem().end())
|
|
||||||
{
|
{
|
||||||
cv::Mat cov;
|
cv::Mat cov;
|
||||||
this->optimizeCurrentMap(
|
this->optimizeCurrentMap(
|
||||||
@@ -810,7 +808,7 @@ int Rtabmap::getWMSize() const
|
|||||||
{
|
{
|
||||||
if(_memory)
|
if(_memory)
|
||||||
{
|
{
|
||||||
return (int)_memory->getWorkingMem().size()-1; // remove virtual place
|
return (int)_memory->getWorkingMemSize(false);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1998,7 +1996,7 @@ bool Rtabmap::process(
|
|||||||
// If the working memory is empty, don't do the detection. It happens when it
|
// If the working memory is empty, don't do the detection. It happens when it
|
||||||
// is the first time the detector is started (there needs some images to
|
// is the first time the detector is started (there needs some images to
|
||||||
// fill the short-time memory before a signature is added to the working memory).
|
// fill the short-time memory before a signature is added to the working memory).
|
||||||
if(_memory->getWorkingMem().size())
|
if(_memory->getWorkingMemSize(true))
|
||||||
{
|
{
|
||||||
//============================================================
|
//============================================================
|
||||||
// Likelihood computation
|
// Likelihood computation
|
||||||
@@ -2174,7 +2172,7 @@ bool Rtabmap::process(
|
|||||||
}
|
}
|
||||||
if( (( _memory->isIncremental() && !uContains(_optimizedPoses, _highestHypothesis.first)) || // not linked to previous map of that hypothesis
|
if( (( _memory->isIncremental() && !uContains(_optimizedPoses, _highestHypothesis.first)) || // not linked to previous map of that hypothesis
|
||||||
(!_memory->isIncremental() && !hasLoopClosureConstraints)) && // not yet localized to any previous sessions
|
(!_memory->isIncremental() && !hasLoopClosureConstraints)) && // not yet localized to any previous sessions
|
||||||
_memory->getWorkingMem().size()>1 && // should have an old map (beside virtual signature)
|
_memory->getWorkingMemSize(true)>0 && // should have an old map
|
||||||
_rgbdSlamMode &&
|
_rgbdSlamMode &&
|
||||||
loopThr > _aggressiveLoopThr)
|
loopThr > _aggressiveLoopThr)
|
||||||
{
|
{
|
||||||
@@ -2227,7 +2225,7 @@ bool Rtabmap::process(
|
|||||||
hypothesisRatio = _loopClosureHypothesis.second>0?_highestHypothesis.second/_loopClosureHypothesis.second:0;
|
hypothesisRatio = _loopClosureHypothesis.second>0?_highestHypothesis.second/_loopClosureHypothesis.second:0;
|
||||||
}
|
}
|
||||||
} // if(_memory->getWorkingMemSize())
|
} // if(_memory->getWorkingMemSize())
|
||||||
}// !isBadSignature
|
} // !isBadSignature
|
||||||
else if(!signature->isBadSignature() && signature->getWeight()>=0 && (smallDisplacement || tooFastMovement))
|
else if(!signature->isBadSignature() && signature->getWeight()>=0 && (smallDisplacement || tooFastMovement))
|
||||||
{
|
{
|
||||||
_highestHypothesis = lastHighestHypothesis;
|
_highestHypothesis = lastHighestHypothesis;
|
||||||
@@ -2259,12 +2257,12 @@ bool Rtabmap::process(
|
|||||||
if(_maxTimeAllowed != 0 || _maxMemoryAllowed != 0)
|
if(_maxTimeAllowed != 0 || _maxMemoryAllowed != 0)
|
||||||
{
|
{
|
||||||
// with memory management, we have to immunize some nodes
|
// with memory management, we have to immunize some nodes
|
||||||
maxLocalLocationsImmunized = _localImmunizationRatio * float(_memory->getWorkingMem().size());
|
maxLocalLocationsImmunized = _localImmunizationRatio * float(_memory->getWorkingMemSize(true));
|
||||||
}
|
}
|
||||||
// no need to do retrieval or immunization of locations if memory management
|
// no need to do retrieval or immunization of locations if memory management
|
||||||
// is disabled and all nodes are in WM.
|
// is disabled and all nodes are in WM.
|
||||||
// Also skip memory mangement on intermediate nodes
|
// Also skip memory mangement on intermediate nodes
|
||||||
if(!(_memory->allNodesInWM() && maxLocalLocationsImmunized == 0) && signature->getWeight()>=0)
|
if(!((_memory->allNodesInWM() || _maxRetrieved==0) && maxLocalLocationsImmunized==0) && signature->getWeight()>=0)
|
||||||
{
|
{
|
||||||
if(retrievalId > 0)
|
if(retrievalId > 0)
|
||||||
{
|
{
|
||||||
@@ -2320,7 +2318,13 @@ bool Rtabmap::process(
|
|||||||
//immunized locations in the neighborhood from being transferred
|
//immunized locations in the neighborhood from being transferred
|
||||||
if(immunizedLocations.insert(iter->first).second)
|
if(immunizedLocations.insert(iter->first).second)
|
||||||
{
|
{
|
||||||
++immunizedGlobally;
|
// Count only non-intermediate nodes (intermediate nodes are still
|
||||||
|
// immunized but don't consume the immunization budget/statistic).
|
||||||
|
const Signature * sImmunized = _memory->getSignature(iter->first);
|
||||||
|
if(sImmunized == 0 || sImmunized->getWeight() >= 0)
|
||||||
|
{
|
||||||
|
++immunizedGlobally;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//UDEBUG("nt=%d m=%d immunized=1", iter->first, iter->second);
|
//UDEBUG("nt=%d m=%d immunized=1", iter->first, iter->second);
|
||||||
@@ -2423,9 +2427,12 @@ bool Rtabmap::process(
|
|||||||
distanceSoFar += _path[i-1].second.getDistance(_path[i].second);
|
distanceSoFar += _path[i-1].second.getDistance(_path[i].second);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_memory->getSignature(_path[i].first) != 0)
|
const Signature * sPath = _memory->getSignature(_path[i].first);
|
||||||
|
if(sPath != 0)
|
||||||
{
|
{
|
||||||
if(immunizedLocations.insert(_path[i].first).second)
|
// Count only non-intermediate nodes (intermediate nodes are still
|
||||||
|
// immunized but don't consume the immunization budget/statistic).
|
||||||
|
if(immunizedLocations.insert(_path[i].first).second && sPath->getWeight() >= 0)
|
||||||
{
|
{
|
||||||
++immunizedLocally;
|
++immunizedLocally;
|
||||||
}
|
}
|
||||||
@@ -2447,7 +2454,7 @@ bool Rtabmap::process(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(_memory->allNodesInWM() && maxLocalLocationsImmunized == 0))
|
if(!(_memory->allNodesInWM() && maxLocalLocationsImmunized==0))
|
||||||
{
|
{
|
||||||
// immunize the path from the nearest local location to the current location
|
// immunize the path from the nearest local location to the current location
|
||||||
if(immunizedLocally < maxLocalLocationsImmunized &&
|
if(immunizedLocally < maxLocalLocationsImmunized &&
|
||||||
@@ -2498,15 +2505,16 @@ bool Rtabmap::process(
|
|||||||
{
|
{
|
||||||
UWARN("Could not immunize the whole local path (%d) between "
|
UWARN("Could not immunize the whole local path (%d) between "
|
||||||
"%d and %d (max location immunized=%d). You may want "
|
"%d and %d (max location immunized=%d). You may want "
|
||||||
"to increase RGBD/LocalImmunizationRatio (current=%f (%d of WM=%d)) "
|
"to increase %s (current=%f (%d of WM=%d)) "
|
||||||
"to be able to immunize longer paths.",
|
"to be able to immunize longer paths.",
|
||||||
(int)path.size(),
|
(int)path.size(),
|
||||||
nearestId,
|
nearestId,
|
||||||
signature->id(),
|
signature->id(),
|
||||||
maxLocalLocationsImmunized,
|
maxLocalLocationsImmunized,
|
||||||
|
Parameters::kRGBDLocalImmunizationRatio().c_str(),
|
||||||
_localImmunizationRatio,
|
_localImmunizationRatio,
|
||||||
maxLocalLocationsImmunized,
|
maxLocalLocationsImmunized,
|
||||||
(int)_memory->getWorkingMem().size());
|
(int)_memory->getWorkingMemSize(true));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2514,7 +2522,13 @@ bool Rtabmap::process(
|
|||||||
{
|
{
|
||||||
if(immunizedLocations.insert(iter->first).second)
|
if(immunizedLocations.insert(iter->first).second)
|
||||||
{
|
{
|
||||||
++immunizedLocally;
|
// Count only non-intermediate nodes (intermediate nodes are still
|
||||||
|
// immunized but don't consume the immunization budget/statistic).
|
||||||
|
const Signature * sLocal = _memory->getSignature(iter->first);
|
||||||
|
if(sLocal == 0 || sLocal->getWeight() >= 0)
|
||||||
|
{
|
||||||
|
++immunizedLocally;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//UDEBUG("local node %d on path immunized=1", iter->first);
|
//UDEBUG("local node %d on path immunized=1", iter->first);
|
||||||
}
|
}
|
||||||
@@ -2538,7 +2552,7 @@ bool Rtabmap::process(
|
|||||||
maxLocalLocationsImmunized,
|
maxLocalLocationsImmunized,
|
||||||
immunizedLocally,
|
immunizedLocally,
|
||||||
_localImmunizationRatio,
|
_localImmunizationRatio,
|
||||||
(int)_memory->getWorkingMem().size());
|
(int)_memory->getWorkingMemSize(true));
|
||||||
std::list<int> retrievalLocalIdsIntermediate;
|
std::list<int> retrievalLocalIdsIntermediate;
|
||||||
for(std::multimap<float, int>::iterator iter=nearNodesByDist.begin();
|
for(std::multimap<float, int>::iterator iter=nearNodesByDist.begin();
|
||||||
iter!=nearNodesByDist.end() && (retrievalLocalIds.size() < _maxLocalRetrieved || immunizedLocally < maxLocalLocationsImmunized);
|
iter!=nearNodesByDist.end() && (retrievalLocalIds.size() < _maxLocalRetrieved || immunizedLocally < maxLocalLocationsImmunized);
|
||||||
@@ -2574,7 +2588,9 @@ bool Rtabmap::process(
|
|||||||
}
|
}
|
||||||
if(!_memory->isInSTM(s->id()) && immunizedLocally < maxLocalLocationsImmunized)
|
if(!_memory->isInSTM(s->id()) && immunizedLocally < maxLocalLocationsImmunized)
|
||||||
{
|
{
|
||||||
if(immunizedLocations.insert(s->id()).second)
|
// Count only non-intermediate nodes (intermediate nodes are still
|
||||||
|
// immunized but don't consume the immunization budget/statistic).
|
||||||
|
if(immunizedLocations.insert(s->id()).second && s->getWeight() >= 0)
|
||||||
{
|
{
|
||||||
++immunizedLocally;
|
++immunizedLocally;
|
||||||
}
|
}
|
||||||
@@ -2685,7 +2701,7 @@ bool Rtabmap::process(
|
|||||||
signature->getWeight() >= 0) // not an intermediate node
|
signature->getWeight() >= 0) // not an intermediate node
|
||||||
{
|
{
|
||||||
if(_startNewMapOnLoopClosure &&
|
if(_startNewMapOnLoopClosure &&
|
||||||
_memory->getWorkingMem().size()>=2 && // must have an old map (+1 virtual place)
|
_memory->getWorkingMemSize(true)>0 && // must have an old map
|
||||||
_localizationCovariance.empty() && // if we didn't localize yet
|
_localizationCovariance.empty() && // if we didn't localize yet
|
||||||
graph::filterLinks(signature->getLinks(), Link::kSelfRefLink).size() == 0) // alone in new session
|
graph::filterLinks(signature->getLinks(), Link::kSelfRefLink).size() == 0) // alone in new session
|
||||||
{
|
{
|
||||||
@@ -4451,7 +4467,7 @@ bool Rtabmap::process(
|
|||||||
_memory->isIncremental() && // only in mapping mode
|
_memory->isIncremental() && // only in mapping mode
|
||||||
graph::filterLinks(signature->getLinks(), Link::kSelfRefLink).size() == 0 && // alone in the current map
|
graph::filterLinks(signature->getLinks(), Link::kSelfRefLink).size() == 0 && // alone in the current map
|
||||||
(landmarksDetected.empty() || rejectedLoopClosure) && // if we re not seeing a landmark from a previous map
|
(landmarksDetected.empty() || rejectedLoopClosure) && // if we re not seeing a landmark from a previous map
|
||||||
_memory->getWorkingMem().size()>=2) // The working memory should not be empty (beside virtual signature)
|
_memory->getWorkingMemSize(true)>0) // The working memory should not be empty
|
||||||
{
|
{
|
||||||
UWARN("Ignoring location %d because a global loop closure is required before starting a new map!",
|
UWARN("Ignoring location %d because a global loop closure is required before starting a new map!",
|
||||||
signature->id());
|
signature->id());
|
||||||
@@ -4538,26 +4554,29 @@ bool Rtabmap::process(
|
|||||||
//============================================================
|
//============================================================
|
||||||
double totalTime = timerTotal.ticks();
|
double totalTime = timerTotal.ticks();
|
||||||
ULOGGER_INFO("Total time processing = %fs...", totalTime);
|
ULOGGER_INFO("Total time processing = %fs...", totalTime);
|
||||||
if(!lastSignatureWasIntermediateNode && // skip memory management on intermediate nodes
|
if(!lastSignatureWasIntermediateNode) // skip memory management on intermediate nodes
|
||||||
((_maxTimeAllowed != 0 && totalTime*1000>_maxTimeAllowed) ||
|
|
||||||
(_maxMemoryAllowed != 0 && _memory->getWorkingMem().size() > _maxMemoryAllowed)))
|
|
||||||
{
|
{
|
||||||
if(_maxTimeAllowed!=0 && totalTime*1000>_maxTimeAllowed)
|
size_t workingMemSize = _memory->getWorkingMemSize(true);
|
||||||
|
if((_maxTimeAllowed != 0 && totalTime*1000 > _maxTimeAllowed) ||
|
||||||
|
(_maxMemoryAllowed != 0 && workingMemSize > _maxMemoryAllowed))
|
||||||
{
|
{
|
||||||
ULOGGER_INFO("Removing old signatures because time limit is reached %f ms > %f ms...",
|
if(_maxTimeAllowed!=0 && totalTime*1000 > _maxTimeAllowed)
|
||||||
totalTime*1000, _maxTimeAllowed);
|
{
|
||||||
}
|
ULOGGER_INFO("Removing old signatures because time limit is reached %f ms > %f ms...",
|
||||||
if(_maxMemoryAllowed != 0 && _memory->getWorkingMem().size() > _maxMemoryAllowed)
|
totalTime*1000, _maxTimeAllowed);
|
||||||
{
|
}
|
||||||
ULOGGER_INFO("Removing old signatures because memory limit is reached %d > %d...",
|
if(_maxMemoryAllowed != 0 && workingMemSize > _maxMemoryAllowed)
|
||||||
_memory->getWorkingMem().size(), _maxMemoryAllowed);
|
{
|
||||||
}
|
ULOGGER_INFO("Removing old signatures because memory limit is reached %d > %d...",
|
||||||
immunizedLocations.insert(_lastLocalizationNodeId); // keep the latest localization in working memory
|
workingMemSize, _maxMemoryAllowed);
|
||||||
std::list<int> transferred = _memory->forget(immunizedLocations);
|
}
|
||||||
signaturesRemoved.insert(signaturesRemoved.end(), transferred.begin(), transferred.end());
|
immunizedLocations.insert(_lastLocalizationNodeId); // keep the latest localization in working memory
|
||||||
if(!_someNodesHaveBeenTransferred && transferred.size())
|
std::list<int> transferred = _memory->forget(immunizedLocations);
|
||||||
{
|
signaturesRemoved.insert(signaturesRemoved.end(), transferred.begin(), transferred.end());
|
||||||
_someNodesHaveBeenTransferred = true; // only used to hide a warning on close nodes immunization
|
if(!_someNodesHaveBeenTransferred && transferred.size())
|
||||||
|
{
|
||||||
|
_someNodesHaveBeenTransferred = true; // only used to hide a warning on close nodes immunization
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_lastProcessTime = totalTime;
|
_lastProcessTime = totalTime;
|
||||||
@@ -4709,8 +4728,10 @@ bool Rtabmap::process(
|
|||||||
statistics_.addStatistic(Statistics::kMemoryImmunized_locally_max(), maxLocalLocationsImmunized);
|
statistics_.addStatistic(Statistics::kMemoryImmunized_locally_max(), maxLocalLocationsImmunized);
|
||||||
|
|
||||||
// place after transfer because the memory/local graph may have changed
|
// place after transfer because the memory/local graph may have changed
|
||||||
statistics_.addStatistic(Statistics::kMemoryWorking_memory_size(), _memory->getWorkingMem().size());
|
statistics_.addStatistic(Statistics::kMemoryWorking_memory_size(), _memory->getWorkingMemSize(true));
|
||||||
statistics_.addStatistic(Statistics::kMemoryShort_time_memory_size(), _memory->getStMem().size());
|
statistics_.addStatistic(Statistics::kMemoryWorking_memory_inter_size(), _memory->getWorkingMemIntermediateNodesCount());
|
||||||
|
statistics_.addStatistic(Statistics::kMemoryShort_time_memory_size(), _memory->getStMem().size()-_memory->getStMemIntermediateNodesCount());
|
||||||
|
statistics_.addStatistic(Statistics::kMemoryShort_time_memory_inter_size(), _memory->getStMemIntermediateNodesCount());
|
||||||
statistics_.addStatistic(Statistics::kMemoryDatabase_memory_used(), _memory->getDatabaseMemoryUsed());
|
statistics_.addStatistic(Statistics::kMemoryDatabase_memory_used(), _memory->getDatabaseMemoryUsed());
|
||||||
|
|
||||||
// Set local graph
|
// Set local graph
|
||||||
@@ -4859,7 +4880,7 @@ bool Rtabmap::process(
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> ids;
|
std::vector<int> ids;
|
||||||
ids.reserve(_memory->getWorkingMem().size() + _memory->getStMem().size());
|
ids.reserve(_memory->getWorkingMemSize(false) + _memory->getStMem().size());
|
||||||
for(std::set<int>::const_iterator iter=_memory->getStMem().begin(); iter!=_memory->getStMem().end(); ++iter)
|
for(std::set<int>::const_iterator iter=_memory->getStMem().begin(); iter!=_memory->getStMem().end(); ++iter)
|
||||||
{
|
{
|
||||||
ids.push_back(*iter);
|
ids.push_back(*iter);
|
||||||
@@ -4921,7 +4942,7 @@ bool Rtabmap::process(
|
|||||||
0,
|
0,
|
||||||
refWordsCount,
|
refWordsCount,
|
||||||
dictionarySize,
|
dictionarySize,
|
||||||
int(_memory->getWorkingMem().size()),
|
int(_memory->getWorkingMemSize(false)),
|
||||||
rejectedLoopClosure?1:0,
|
rejectedLoopClosure?1:0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -5948,7 +5969,7 @@ void Rtabmap::getGraph(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(_memory && (_memory->getStMem().size() || _memory->getWorkingMem().size() > 1))
|
else if(_memory && (_memory->getStMem().size() || _memory->getWorkingMemSize(!global) > 0))
|
||||||
{
|
{
|
||||||
UERROR("Last working signature is null!?");
|
UERROR("Last working signature is null!?");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user