mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 01:20:25 +08:00
Added path immunization between the nearest local location and the current pose. New parameter: "RGBD/LocalImmunizationRatio"
This commit is contained in:
@@ -160,7 +160,7 @@ public:
|
|||||||
|
|
||||||
// RGB-D stuff
|
// RGB-D stuff
|
||||||
void getMetricConstraints(
|
void getMetricConstraints(
|
||||||
const std::vector<int> & ids,
|
const std::set<int> & ids,
|
||||||
std::map<int, Transform> & poses,
|
std::map<int, Transform> & poses,
|
||||||
std::multimap<int, Link> & links,
|
std::multimap<int, Link> & links,
|
||||||
bool lookInDatabase = false);
|
bool lookInDatabase = false);
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ class RTABMAP_EXP Parameters
|
|||||||
RTABMAP_PARAM(Mem, RecentWmRatio, float, 0.2, "Ratio of locations after the last loop closure in WM that cannot be transferred.");
|
RTABMAP_PARAM(Mem, RecentWmRatio, float, 0.2, "Ratio of locations after the last loop closure in WM that cannot be transferred.");
|
||||||
RTABMAP_PARAM(Mem, TransferSortingByWeightId, bool, false, "On transfer, signatures are sorted by weight->ID only (i.e. the oldest of the lowest weighted signatures are transferred first). If false, the signatures are sorted by weight->Age->ID (i.e. the oldest inserted in WM of the lowest weighted signatures are transferred first). Note that retrieval updates the age, not the ID.");
|
RTABMAP_PARAM(Mem, TransferSortingByWeightId, bool, false, "On transfer, signatures are sorted by weight->ID only (i.e. the oldest of the lowest weighted signatures are transferred first). If false, the signatures are sorted by weight->Age->ID (i.e. the oldest inserted in WM of the lowest weighted signatures are transferred first). Note that retrieval updates the age, not the ID.");
|
||||||
RTABMAP_PARAM(Mem, RehearsalIdUpdatedToNewOne, bool, false, "On merge, update to new id. When false, no copy.");
|
RTABMAP_PARAM(Mem, RehearsalIdUpdatedToNewOne, bool, false, "On merge, update to new id. When false, no copy.");
|
||||||
RTABMAP_PARAM(Mem, RehearsalWeightIgnoredWhileMoving, bool, true, "When the robot is moving, weights are not updated on rehearsal.");
|
RTABMAP_PARAM(Mem, RehearsalWeightIgnoredWhileMoving, bool, false, "When the robot is moving, weights are not updated on rehearsal.");
|
||||||
RTABMAP_PARAM(Mem, GenerateIds, bool, true, "True=Generate location IDs, False=use input image IDs.");
|
RTABMAP_PARAM(Mem, GenerateIds, bool, true, "True=Generate location IDs, False=use input image IDs.");
|
||||||
RTABMAP_PARAM(Mem, BadSignaturesIgnored, bool, false, "Bad signatures are ignored.");
|
RTABMAP_PARAM(Mem, BadSignaturesIgnored, bool, false, "Bad signatures are ignored.");
|
||||||
RTABMAP_PARAM(Mem, InitWMWithAllNodes, bool, false, "Initialize the Working Memory with all nodes in Long-Term Memory. When false, it is initialized with nodes of the previous session.");
|
RTABMAP_PARAM(Mem, InitWMWithAllNodes, bool, false, "Initialize the Working Memory with all nodes in Long-Term Memory. When false, it is initialized with nodes of the previous session.");
|
||||||
@@ -290,15 +290,15 @@ class RTABMAP_EXP Parameters
|
|||||||
RTABMAP_PARAM(RGBD, OptimizeFromGraphEnd, bool, false, "Optimize graph from the newest node. If false, the graph is optimized from the oldest node of the current graph (this adds an overhead computation to detect to oldest mode of the current graph, but it can be useful to preserve the map referential from the oldest node). Warning when set to false: when some nodes are transferred, the first referential of the local map may change, resulting in momentary changes in robot/map position (which are annoying in teleoperation).");
|
RTABMAP_PARAM(RGBD, OptimizeFromGraphEnd, bool, false, "Optimize graph from the newest node. If false, the graph is optimized from the oldest node of the current graph (this adds an overhead computation to detect to oldest mode of the current graph, but it can be useful to preserve the map referential from the oldest node). Warning when set to false: when some nodes are transferred, the first referential of the local map may change, resulting in momentary changes in robot/map position (which are annoying in teleoperation).");
|
||||||
RTABMAP_PARAM(RGBD, GoalReachedRadius, float, 0.5, "Goal reached radius (m).");
|
RTABMAP_PARAM(RGBD, GoalReachedRadius, float, 0.5, "Goal reached radius (m).");
|
||||||
RTABMAP_PARAM(RGBD, PlanVirtualLinks, bool, true, "Before planning in the graph, close nodes are linked together. Radius is defined by \"RGBD/GoalReachedRadius\" parameter.");
|
RTABMAP_PARAM(RGBD, PlanVirtualLinks, bool, true, "Before planning in the graph, close nodes are linked together. Radius is defined by \"RGBD/GoalReachedRadius\" parameter.");
|
||||||
RTABMAP_PARAM(RGBD, PlanVirtualLinksMaxDiffID, int, 50, "Max difference ID to add virtual links before planning.");
|
|
||||||
RTABMAP_PARAM(RGBD, GoalsSavedInUserData, bool, true, "When a goal is received and processed with success, it is saved in user data of the location with this format: \"GOAL:#\".");
|
RTABMAP_PARAM(RGBD, GoalsSavedInUserData, bool, true, "When a goal is received and processed with success, it is saved in user data of the location with this format: \"GOAL:#\".");
|
||||||
RTABMAP_PARAM(RGBD, MaxLocalRetrieved, unsigned int, 2, "Maximum local locations retrieved (0=disabled) near the current pose in the local map or on the current planned path (those on the planned path have priority).");
|
RTABMAP_PARAM(RGBD, MaxLocalRetrieved, unsigned int, 2, "Maximum local locations retrieved (0=disabled) near the current pose in the local map or on the current planned path (those on the planned path have priority).");
|
||||||
RTABMAP_PARAM(RGBD, LocalRadius, float, 10, "Local radius (m) for nodes selection in the local map. This parameter is used in some approaches about the local map management.");
|
RTABMAP_PARAM(RGBD, LocalRadius, float, 10, "Local radius (m) for nodes selection in the local map. This parameter is used in some approaches about the local map management.");
|
||||||
|
RTABMAP_PARAM(RGBD, LocalImmunizationRatio, float, 0.25, "Ratio of working memory for which local nodes are immunized from transfer.");
|
||||||
|
|
||||||
// Local loop closure detection
|
// Local loop closure detection
|
||||||
RTABMAP_PARAM(RGBD, LocalLoopDetectionTime, bool, false, "Detection over all locations in STM.");
|
RTABMAP_PARAM(RGBD, LocalLoopDetectionTime, bool, false, "Detection over all locations in STM.");
|
||||||
RTABMAP_PARAM(RGBD, LocalLoopDetectionSpace, bool, false, "Detection over locations (in Working Memory or STM) near in space.");
|
RTABMAP_PARAM(RGBD, LocalLoopDetectionSpace, bool, false, "Detection over locations (in Working Memory or STM) near in space.");
|
||||||
RTABMAP_PARAM(RGBD, LocalLoopDetectionMaxGraphDepth, int, 20, "Maximum depth from the current/last loop closure location and the local loop closure hypotheses. Set 0 to ignore.");
|
RTABMAP_PARAM(RGBD, LocalLoopDetectionMaxGraphDepth, int, 50, "Maximum depth from the current/last loop closure location and the local loop closure hypotheses. Set 0 to ignore.");
|
||||||
RTABMAP_PARAM(RGBD, LocalLoopDetectionPathFilteringRadius, float, 0.5, "Path filtering radius.");
|
RTABMAP_PARAM(RGBD, LocalLoopDetectionPathFilteringRadius, float, 0.5, "Path filtering radius.");
|
||||||
RTABMAP_PARAM(RGBD, LocalLoopDetectionPathOdomPosesUsed, bool, true, "When comparing to a local path, merge the scan using the odometry poses instead of the ones in the optimized local graph.");
|
RTABMAP_PARAM(RGBD, LocalLoopDetectionPathOdomPosesUsed, bool, true, "When comparing to a local path, merge the scan using the odometry poses instead of the ones in the optimized local graph.");
|
||||||
|
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ private:
|
|||||||
std::multimap<int, Link> * constraints = 0) const;
|
std::multimap<int, Link> * constraints = 0) const;
|
||||||
std::map<int, Transform> optimizeGraph(
|
std::map<int, Transform> optimizeGraph(
|
||||||
int fromId,
|
int fromId,
|
||||||
const std::vector<int> & ids,
|
const std::set<int> & ids,
|
||||||
bool lookInDatabase,
|
bool lookInDatabase,
|
||||||
std::multimap<int, Link> * constraints = 0) const;
|
std::multimap<int, Link> * constraints = 0) const;
|
||||||
void updateGoalIndex();
|
void updateGoalIndex();
|
||||||
@@ -184,6 +184,7 @@ private:
|
|||||||
bool _localLoopClosureDetectionTime;
|
bool _localLoopClosureDetectionTime;
|
||||||
bool _localLoopClosureDetectionSpace;
|
bool _localLoopClosureDetectionSpace;
|
||||||
float _localRadius;
|
float _localRadius;
|
||||||
|
float _localImmunizationRatio;
|
||||||
int _localDetectMaxGraphDepth;
|
int _localDetectMaxGraphDepth;
|
||||||
float _localPathFilteringRadius;
|
float _localPathFilteringRadius;
|
||||||
bool _localPathOdomPosesUsed;
|
bool _localPathOdomPosesUsed;
|
||||||
@@ -197,7 +198,6 @@ private:
|
|||||||
bool _startNewMapOnLoopClosure;
|
bool _startNewMapOnLoopClosure;
|
||||||
float _goalReachedRadius; // meters
|
float _goalReachedRadius; // meters
|
||||||
bool _planVirtualLinks;
|
bool _planVirtualLinks;
|
||||||
int _planVirtualLinksMaxDiffID;
|
|
||||||
bool _goalsSavedInUserData;
|
bool _goalsSavedInUserData;
|
||||||
|
|
||||||
std::pair<int, float> _loopClosureHypothesis;
|
std::pair<int, float> _loopClosureHypothesis;
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ class RTABMAP_EXP Statistics
|
|||||||
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,);
|
||||||
RTABMAP_STATS(Memory, Signatures_removed,);
|
RTABMAP_STATS(Memory, Signatures_removed,);
|
||||||
|
RTABMAP_STATS(Memory, Immunized_globally,);
|
||||||
|
RTABMAP_STATS(Memory, Immunized_locally,);
|
||||||
|
RTABMAP_STATS(Memory, Immunized_locally_max,);
|
||||||
RTABMAP_STATS(Memory, Signatures_retrieved,);
|
RTABMAP_STATS(Memory, Signatures_retrieved,);
|
||||||
RTABMAP_STATS(Memory, Images_buffered,);
|
RTABMAP_STATS(Memory, Images_buffered,);
|
||||||
RTABMAP_STATS(Memory, Rehearsal_sim,);
|
RTABMAP_STATS(Memory, Rehearsal_sim,);
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "rtabmap/core/util3d.h"
|
#include "rtabmap/core/util3d.h"
|
||||||
#include "rtabmap/core/Statistics.h"
|
#include "rtabmap/core/Statistics.h"
|
||||||
#include "rtabmap/core/Compression.h"
|
#include "rtabmap/core/Compression.h"
|
||||||
|
#include "rtabmap/core/Graph.h"
|
||||||
|
|
||||||
#include <pcl/io/pcd_io.h>
|
#include <pcl/io/pcd_io.h>
|
||||||
#include <pcl/common/common.h>
|
#include <pcl/common/common.h>
|
||||||
@@ -4256,56 +4257,47 @@ std::set<int> Memory::reactivateSignatures(const std::list<int> & ids, unsigned
|
|||||||
return std::set<int>(idsToLoad.begin(), idsToLoad.end());
|
return std::set<int>(idsToLoad.begin(), idsToLoad.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return all non-null poses
|
||||||
|
// return unique links between nodes (for neighbors: old->new, for loops: parent->child)
|
||||||
void Memory::getMetricConstraints(
|
void Memory::getMetricConstraints(
|
||||||
const std::vector<int> & ids,
|
const std::set<int> & ids,
|
||||||
std::map<int, Transform> & poses,
|
std::map<int, Transform> & poses,
|
||||||
std::multimap<int, Link> & links,
|
std::multimap<int, Link> & links,
|
||||||
bool lookInDatabase)
|
bool lookInDatabase)
|
||||||
{
|
{
|
||||||
UDEBUG("");
|
UDEBUG("");
|
||||||
for(unsigned int i=0; i<ids.size(); ++i)
|
for(std::set<int>::const_iterator iter=ids.begin(); iter!=ids.end(); ++iter)
|
||||||
{
|
{
|
||||||
Transform pose = getOdomPose(ids[i], lookInDatabase);
|
Transform pose = getOdomPose(*iter, lookInDatabase);
|
||||||
if(!pose.isNull())
|
if(!pose.isNull())
|
||||||
{
|
{
|
||||||
poses.insert(std::make_pair(ids[i], pose));
|
poses.insert(std::make_pair(*iter, pose));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(unsigned int i=0; i<ids.size(); ++i)
|
for(std::set<int>::const_iterator iter=ids.begin(); iter!=ids.end(); ++iter)
|
||||||
{
|
{
|
||||||
if(uContains(poses, ids[i]))
|
if(uContains(poses, *iter))
|
||||||
{
|
{
|
||||||
std::map<int, Link> neighbors = this->getNeighborLinks(ids[i], lookInDatabase); // only direct neighbors
|
std::map<int, Link> neighbors = this->getNeighborLinks(*iter, lookInDatabase); // only direct neighbors
|
||||||
for(std::map<int, Link>::iterator jter=neighbors.begin(); jter!=neighbors.end(); ++jter)
|
for(std::map<int, Link>::iterator jter=neighbors.begin(); jter!=neighbors.end(); ++jter)
|
||||||
{
|
{
|
||||||
if(uContains(poses, jter->first) && jter->second.isValid())
|
if( jter->second.isValid() &&
|
||||||
|
uContains(poses, jter->first) &&
|
||||||
|
graph::findLink(links, *iter, jter->first) == links.end())
|
||||||
{
|
{
|
||||||
bool edgeAlreadyAdded = false;
|
links.insert(std::make_pair(*iter, jter->second));
|
||||||
for(std::multimap<int, Link>::iterator iter = links.lower_bound(jter->first);
|
|
||||||
iter != links.end() && iter->first == jter->first;
|
|
||||||
++iter)
|
|
||||||
{
|
|
||||||
if(iter->second.to() == ids[i])
|
|
||||||
{
|
|
||||||
edgeAlreadyAdded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!edgeAlreadyAdded)
|
|
||||||
{
|
|
||||||
links.insert(std::make_pair(ids[i], jter->second));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<int, Link> loops = this->getLoopClosureLinks(ids[i], lookInDatabase);
|
std::map<int, Link> loops = this->getLoopClosureLinks(*iter, lookInDatabase);
|
||||||
for(std::map<int, Link>::iterator jter=loops.begin(); jter!=loops.end(); ++jter)
|
for(std::map<int, Link>::iterator jter=loops.begin(); jter!=loops.end(); ++jter)
|
||||||
{
|
{
|
||||||
if(jter->first < ids[i] &&
|
if( jter->second.isValid() && // null transform means a rehearsed location
|
||||||
uContains(poses, jter->first) &&
|
jter->first < *iter && // Loop parent to child
|
||||||
jter->second.isValid()) // null transform means a child (rehearsed location)
|
uContains(poses, jter->first))
|
||||||
{
|
{
|
||||||
links.insert(std::make_pair(ids[i],jter->second));
|
links.insert(std::make_pair(*iter, jter->second));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ Rtabmap::Rtabmap() :
|
|||||||
_localLoopClosureDetectionTime(Parameters::defaultRGBDLocalLoopDetectionTime()),
|
_localLoopClosureDetectionTime(Parameters::defaultRGBDLocalLoopDetectionTime()),
|
||||||
_localLoopClosureDetectionSpace(Parameters::defaultRGBDLocalLoopDetectionSpace()),
|
_localLoopClosureDetectionSpace(Parameters::defaultRGBDLocalLoopDetectionSpace()),
|
||||||
_localRadius(Parameters::defaultRGBDLocalRadius()),
|
_localRadius(Parameters::defaultRGBDLocalRadius()),
|
||||||
|
_localImmunizationRatio(Parameters::defaultRGBDLocalImmunizationRatio()),
|
||||||
_localDetectMaxGraphDepth(Parameters::defaultRGBDLocalLoopDetectionMaxGraphDepth()),
|
_localDetectMaxGraphDepth(Parameters::defaultRGBDLocalLoopDetectionMaxGraphDepth()),
|
||||||
_localPathFilteringRadius(Parameters::defaultRGBDLocalLoopDetectionPathFilteringRadius()),
|
_localPathFilteringRadius(Parameters::defaultRGBDLocalLoopDetectionPathFilteringRadius()),
|
||||||
_localPathOdomPosesUsed(Parameters::defaultRGBDLocalLoopDetectionPathOdomPosesUsed()),
|
_localPathOdomPosesUsed(Parameters::defaultRGBDLocalLoopDetectionPathOdomPosesUsed()),
|
||||||
@@ -109,7 +110,6 @@ Rtabmap::Rtabmap() :
|
|||||||
_startNewMapOnLoopClosure(Parameters::defaultRtabmapStartNewMapOnLoopClosure()),
|
_startNewMapOnLoopClosure(Parameters::defaultRtabmapStartNewMapOnLoopClosure()),
|
||||||
_goalReachedRadius(Parameters::defaultRGBDGoalReachedRadius()),
|
_goalReachedRadius(Parameters::defaultRGBDGoalReachedRadius()),
|
||||||
_planVirtualLinks(Parameters::defaultRGBDPlanVirtualLinks()),
|
_planVirtualLinks(Parameters::defaultRGBDPlanVirtualLinks()),
|
||||||
_planVirtualLinksMaxDiffID(Parameters::defaultRGBDPlanVirtualLinksMaxDiffID()),
|
|
||||||
_goalsSavedInUserData(Parameters::defaultRGBDGoalsSavedInUserData()),
|
_goalsSavedInUserData(Parameters::defaultRGBDGoalsSavedInUserData()),
|
||||||
_loopClosureHypothesis(0,0.0f),
|
_loopClosureHypothesis(0,0.0f),
|
||||||
_highestHypothesis(0,0.0f),
|
_highestHypothesis(0,0.0f),
|
||||||
@@ -385,6 +385,7 @@ void Rtabmap::parseParameters(const ParametersMap & parameters)
|
|||||||
Parameters::parse(parameters, Parameters::kRGBDLocalLoopDetectionTime(), _localLoopClosureDetectionTime);
|
Parameters::parse(parameters, Parameters::kRGBDLocalLoopDetectionTime(), _localLoopClosureDetectionTime);
|
||||||
Parameters::parse(parameters, Parameters::kRGBDLocalLoopDetectionSpace(), _localLoopClosureDetectionSpace);
|
Parameters::parse(parameters, Parameters::kRGBDLocalLoopDetectionSpace(), _localLoopClosureDetectionSpace);
|
||||||
Parameters::parse(parameters, Parameters::kRGBDLocalRadius(), _localRadius);
|
Parameters::parse(parameters, Parameters::kRGBDLocalRadius(), _localRadius);
|
||||||
|
Parameters::parse(parameters, Parameters::kRGBDLocalImmunizationRatio(), _localImmunizationRatio);
|
||||||
Parameters::parse(parameters, Parameters::kRGBDLocalLoopDetectionMaxGraphDepth(), _localDetectMaxGraphDepth);
|
Parameters::parse(parameters, Parameters::kRGBDLocalLoopDetectionMaxGraphDepth(), _localDetectMaxGraphDepth);
|
||||||
Parameters::parse(parameters, Parameters::kRGBDLocalLoopDetectionPathFilteringRadius(), _localPathFilteringRadius);
|
Parameters::parse(parameters, Parameters::kRGBDLocalLoopDetectionPathFilteringRadius(), _localPathFilteringRadius);
|
||||||
Parameters::parse(parameters, Parameters::kRGBDLocalLoopDetectionPathOdomPosesUsed(), _localPathOdomPosesUsed);
|
Parameters::parse(parameters, Parameters::kRGBDLocalLoopDetectionPathOdomPosesUsed(), _localPathOdomPosesUsed);
|
||||||
@@ -397,7 +398,6 @@ void Rtabmap::parseParameters(const ParametersMap & parameters)
|
|||||||
Parameters::parse(parameters, Parameters::kRtabmapStartNewMapOnLoopClosure(), _startNewMapOnLoopClosure);
|
Parameters::parse(parameters, Parameters::kRtabmapStartNewMapOnLoopClosure(), _startNewMapOnLoopClosure);
|
||||||
Parameters::parse(parameters, Parameters::kRGBDGoalReachedRadius(), _goalReachedRadius);
|
Parameters::parse(parameters, Parameters::kRGBDGoalReachedRadius(), _goalReachedRadius);
|
||||||
Parameters::parse(parameters, Parameters::kRGBDPlanVirtualLinks(), _planVirtualLinks);
|
Parameters::parse(parameters, Parameters::kRGBDPlanVirtualLinks(), _planVirtualLinks);
|
||||||
Parameters::parse(parameters, Parameters::kRGBDPlanVirtualLinksMaxDiffID(), _planVirtualLinksMaxDiffID);
|
|
||||||
Parameters::parse(parameters, Parameters::kRGBDGoalsSavedInUserData(), _goalsSavedInUserData);
|
Parameters::parse(parameters, Parameters::kRGBDGoalsSavedInUserData(), _goalsSavedInUserData);
|
||||||
|
|
||||||
// RGB-D SLAM stuff
|
// RGB-D SLAM stuff
|
||||||
@@ -723,7 +723,7 @@ void Rtabmap::generateTOROGraph(const std::string & path, bool optimized, bool g
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::map<int, int> ids = _memory->getNeighborsId(_memory->getLastWorkingSignature()->id(), 0, global?-1:0, true);
|
std::map<int, int> ids = _memory->getNeighborsId(_memory->getLastWorkingSignature()->id(), 0, global?-1:0, true);
|
||||||
_memory->getMetricConstraints(uKeys(ids), poses, constraints, global);
|
_memory->getMetricConstraints(uKeysSet(ids), poses, constraints, global);
|
||||||
}
|
}
|
||||||
|
|
||||||
graph::TOROOptimizer::saveGraph(path, poses, constraints);
|
graph::TOROOptimizer::saveGraph(path, poses, constraints);
|
||||||
@@ -981,7 +981,19 @@ bool Rtabmap::process(const SensorData & data)
|
|||||||
|
|
||||||
if(signature->getLinks().size() == 1)
|
if(signature->getLinks().size() == 1)
|
||||||
{
|
{
|
||||||
_constraints.insert(std::make_pair(signature->id(), signature->getLinks().begin()->second));
|
// link should be old to new
|
||||||
|
if(signature->id() > signature->getLinks().begin()->second.to())
|
||||||
|
{
|
||||||
|
Link tmp = signature->getLinks().begin()->second;
|
||||||
|
tmp.setFrom(tmp.to());
|
||||||
|
tmp.setTo(signature->id());
|
||||||
|
tmp.setTransform(tmp.transform().inverse());
|
||||||
|
_constraints.insert(std::make_pair(tmp.from(), tmp));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_constraints.insert(std::make_pair(signature->id(), signature->getLinks().begin()->second));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================
|
//============================================================
|
||||||
@@ -1171,35 +1183,36 @@ bool Rtabmap::process(const SensorData & data)
|
|||||||
std::list<int> reactivatedIds;
|
std::list<int> reactivatedIds;
|
||||||
double timeGetNeighborsTimeDb = 0.0;
|
double timeGetNeighborsTimeDb = 0.0;
|
||||||
double timeGetNeighborsSpaceDb = 0.0;
|
double timeGetNeighborsSpaceDb = 0.0;
|
||||||
|
int immunizedGlobally = 0;
|
||||||
|
int immunizedLocally = 0;
|
||||||
if(retrievalId > 0 )
|
if(retrievalId > 0 )
|
||||||
{
|
{
|
||||||
//Load neighbors
|
//Load neighbors
|
||||||
ULOGGER_INFO("Retrieving locations... around id=%d", retrievalId);
|
ULOGGER_INFO("Retrieving locations... around id=%d", retrievalId);
|
||||||
int neighborhoodSize = (int)_bayesFilter->getPredictionLC().size()-1;
|
int neighborhoodSize = (int)_bayesFilter->getPredictionLC().size()-1;
|
||||||
UASSERT(neighborhoodSize >= 0);
|
UASSERT(neighborhoodSize >= 0);
|
||||||
int margin = neighborhoodSize;
|
ULOGGER_DEBUG("margin=%d maxRetieved=%d", neighborhoodSize, _maxRetrieved);
|
||||||
ULOGGER_DEBUG("margin=%d maxRetieved=%d", margin, _maxRetrieved);
|
|
||||||
|
|
||||||
UTimer timeGetN;
|
UTimer timeGetN;
|
||||||
unsigned int nbLoadedFromDb = 0;
|
unsigned int nbLoadedFromDb = 0;
|
||||||
std::set<int> reactivatedIdsSet;
|
std::set<int> reactivatedIdsSet;
|
||||||
std::map<int, int> neighbors;
|
std::map<int, int> neighbors;
|
||||||
bool firstPassDone = false;
|
|
||||||
int m = 0;
|
|
||||||
int nbDirectNeighborsInDb = 0;
|
int nbDirectNeighborsInDb = 0;
|
||||||
|
|
||||||
// priority in time
|
// priority in time
|
||||||
// Direct neighbors TIME
|
// Direct neighbors TIME
|
||||||
ULOGGER_DEBUG("In TIME");
|
ULOGGER_DEBUG("In TIME");
|
||||||
neighbors = _memory->getNeighborsId(retrievalId,
|
neighbors = _memory->getNeighborsId(retrievalId,
|
||||||
margin,
|
neighborhoodSize,
|
||||||
_maxRetrieved,
|
_maxRetrieved,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
&timeGetNeighborsTimeDb);
|
&timeGetNeighborsTimeDb);
|
||||||
ULOGGER_DEBUG("neighbors of %d in time = %d", retrievalId, (int)neighbors.size());
|
ULOGGER_DEBUG("neighbors of %d in time = %d", retrievalId, (int)neighbors.size());
|
||||||
//Priority to locations near in time (direct neighbor) then by space (loop closure)
|
//Priority to locations near in time (direct neighbor) then by space (loop closure)
|
||||||
while(m < margin)
|
bool firstPassDone = false; // just to avoid checking to STM after the first pass
|
||||||
|
int m = 0;
|
||||||
|
while(m < neighborhoodSize)
|
||||||
{
|
{
|
||||||
std::set<int> idsSorted;
|
std::set<int> idsSorted;
|
||||||
for(std::map<int, int>::iterator iter=neighbors.begin(); iter!=neighbors.end();)
|
for(std::map<int, int>::iterator iter=neighbors.begin(); iter!=neighbors.end();)
|
||||||
@@ -1220,15 +1233,15 @@ bool Rtabmap::process(const SensorData & data)
|
|||||||
++nbDirectNeighborsInDb;
|
++nbDirectNeighborsInDb;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m<neighborhoodSize)
|
//immunized locations in the neighborhood from being transferred
|
||||||
|
if(immunizedLocations.insert(iter->first).second)
|
||||||
{
|
{
|
||||||
//immunized locations in the neighborhood from being transferred
|
++immunizedGlobally;
|
||||||
immunizedLocations.insert(iter->first);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UDEBUG("nt=%d m=%d immunized=1", iter->first, iter->second);
|
UDEBUG("nt=%d m=%d immunized=1", iter->first, iter->second);
|
||||||
}
|
}
|
||||||
std::map<int, int>::iterator tmp = iter++;
|
neighbors.erase(iter++);
|
||||||
neighbors.erase(tmp);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1243,15 +1256,15 @@ bool Rtabmap::process(const SensorData & data)
|
|||||||
// neighbors SPACE, already added direct neighbors will be ignored
|
// neighbors SPACE, already added direct neighbors will be ignored
|
||||||
ULOGGER_DEBUG("In SPACE");
|
ULOGGER_DEBUG("In SPACE");
|
||||||
neighbors = _memory->getNeighborsId(retrievalId,
|
neighbors = _memory->getNeighborsId(retrievalId,
|
||||||
margin,
|
neighborhoodSize,
|
||||||
_maxRetrieved,
|
_maxRetrieved,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
&timeGetNeighborsSpaceDb);
|
&timeGetNeighborsSpaceDb);
|
||||||
ULOGGER_DEBUG("neighbors of %d in space = %d", retrievalId, (int)neighbors.size());
|
ULOGGER_DEBUG("neighbors of %d in space = %d", retrievalId, (int)neighbors.size());
|
||||||
m = 0;
|
|
||||||
firstPassDone = false;
|
firstPassDone = false;
|
||||||
while(m < margin)
|
m = 0;
|
||||||
|
while(m < neighborhoodSize)
|
||||||
{
|
{
|
||||||
std::set<int> idsSorted;
|
std::set<int> idsSorted;
|
||||||
for(std::map<int, int>::iterator iter=neighbors.begin(); iter!=neighbors.end();)
|
for(std::map<int, int>::iterator iter=neighbors.begin(); iter!=neighbors.end();)
|
||||||
@@ -1273,8 +1286,7 @@ bool Rtabmap::process(const SensorData & data)
|
|||||||
}
|
}
|
||||||
UDEBUG("nt=%d m=%d", iter->first, iter->second);
|
UDEBUG("nt=%d m=%d", iter->first, iter->second);
|
||||||
}
|
}
|
||||||
std::map<int, int>::iterator tmp = iter++;
|
neighbors.erase(iter++);
|
||||||
neighbors.erase(tmp);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1285,13 +1297,11 @@ bool Rtabmap::process(const SensorData & data)
|
|||||||
reactivatedIds.insert(reactivatedIds.end(), idsSorted.rbegin(), idsSorted.rend());
|
reactivatedIds.insert(reactivatedIds.end(), idsSorted.rbegin(), idsSorted.rend());
|
||||||
++m;
|
++m;
|
||||||
}
|
}
|
||||||
ULOGGER_INFO("margin=%d, "
|
ULOGGER_INFO("neighborhoodSize=%d, "
|
||||||
"neighborhoodSize=%d, "
|
|
||||||
"reactivatedIds.size=%d, "
|
"reactivatedIds.size=%d, "
|
||||||
"nbLoadedFromDb=%d, "
|
"nbLoadedFromDb=%d, "
|
||||||
"nbDirectNeighborsInDb=%d, "
|
"nbDirectNeighborsInDb=%d, "
|
||||||
"time=%fs (%fs %fs)",
|
"time=%fs (%fs %fs)",
|
||||||
margin,
|
|
||||||
neighborhoodSize,
|
neighborhoodSize,
|
||||||
reactivatedIds.size(),
|
reactivatedIds.size(),
|
||||||
(int)nbLoadedFromDb,
|
(int)nbLoadedFromDb,
|
||||||
@@ -1306,6 +1316,7 @@ bool Rtabmap::process(const SensorData & data)
|
|||||||
// RETRIEVAL 2/3 : Update planned path and get next nodes to retrieve
|
// RETRIEVAL 2/3 : Update planned path and get next nodes to retrieve
|
||||||
//============================================================
|
//============================================================
|
||||||
std::list<int> retrievalLocalIds;
|
std::list<int> retrievalLocalIds;
|
||||||
|
int maxLocalLocationsImmunized = _localImmunizationRatio * float(_memory->getWorkingMem().size());
|
||||||
if(_rgbdSlamMode)
|
if(_rgbdSlamMode)
|
||||||
{
|
{
|
||||||
// Priority on locations on the planned path
|
// Priority on locations on the planned path
|
||||||
@@ -1327,7 +1338,10 @@ bool Rtabmap::process(const SensorData & data)
|
|||||||
{
|
{
|
||||||
if(_memory->getSignature(_path[i].first) != 0)
|
if(_memory->getSignature(_path[i].first) != 0)
|
||||||
{
|
{
|
||||||
immunizedLocations.insert(_path[i].first);
|
if(immunizedLocations.insert(_path[i].first).second)
|
||||||
|
{
|
||||||
|
++immunizedLocally;
|
||||||
|
}
|
||||||
UDEBUG("Path immunization: node %d (dist=%fm)", _path[i].first, distanceSoFar);
|
UDEBUG("Path immunization: node %d (dist=%fm)", _path[i].first, distanceSoFar);
|
||||||
}
|
}
|
||||||
else if(retrievalLocalIds.size() < _maxLocalRetrieved)
|
else if(retrievalLocalIds.size() < _maxLocalRetrieved)
|
||||||
@@ -1345,65 +1359,144 @@ bool Rtabmap::process(const SensorData & data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(retrievalLocalIds.size() < _maxLocalRetrieved)
|
|
||||||
|
// immunize the path from the nearest local location to the current location
|
||||||
|
if(immunizedLocally < maxLocalLocationsImmunized)
|
||||||
{
|
{
|
||||||
// retrieval based on the nodes near the current pose
|
std::map<int ,Transform> poses;
|
||||||
std::map<int, float> nearNodes = graph::getNodesInRadius(signature->id(), _optimizedPoses, _localRadius);
|
// remove poses from STM
|
||||||
// sort by distance
|
for(std::map<int, Transform>::iterator iter=_optimizedPoses.begin(); iter!=_optimizedPoses.end(); ++iter)
|
||||||
std::multimap<float, int> nearNodesByDist;
|
|
||||||
for(std::map<int, float>::iterator iter=nearNodes.begin(); iter!=nearNodes.end(); ++iter)
|
|
||||||
{
|
{
|
||||||
nearNodesByDist.insert(std::make_pair(iter->second, iter->first));
|
if(!_memory->isInSTM(iter->first))
|
||||||
}
|
|
||||||
for(std::multimap<float, int>::iterator iter=nearNodesByDist.begin();
|
|
||||||
iter!=nearNodesByDist.end() && retrievalLocalIds.size() < _maxLocalRetrieved;
|
|
||||||
++iter)
|
|
||||||
{
|
|
||||||
const Signature * s = _memory->getSignature(iter->second);
|
|
||||||
UASSERT(s!=0);
|
|
||||||
// If there is a change of direction, better to be retrieving
|
|
||||||
// ALL nearest signatures than only newest neighbors
|
|
||||||
const std::map<int, Link> & links = s->getLinks();
|
|
||||||
for(std::map<int, Link>::const_reverse_iterator jter=links.rbegin();
|
|
||||||
jter!=links.rend() && retrievalLocalIds.size() < _maxLocalRetrieved;
|
|
||||||
++jter)
|
|
||||||
{
|
{
|
||||||
if(_memory->getSignature(jter->first) == 0)
|
poses.insert(*iter);
|
||||||
{
|
|
||||||
UINFO("retrieval of node %d on local map", jter->first);
|
|
||||||
retrievalLocalIds.push_back(jter->first);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// well, if the maximum retrieved is not reached, look for neighbors in database
|
int nearestId = graph::findNearestNode(poses, _optimizedPoses.at(signature->id()));
|
||||||
if(retrievalLocalIds.size() < _maxLocalRetrieved)
|
|
||||||
|
if(nearestId > 0 &&
|
||||||
|
(_localRadius==0 ||
|
||||||
|
_optimizedPoses.at(signature->id()).getDistance(_optimizedPoses.at(nearestId)) < _localRadius))
|
||||||
{
|
{
|
||||||
std::set<int> retrievalLocalIdsSet(retrievalLocalIds.begin(), retrievalLocalIds.end());
|
std::multimap<int, int> links;
|
||||||
for(std::list<int>::iterator iter=retrievalLocalIds.begin();
|
for(std::multimap<int, Link>::iterator iter=_constraints.begin(); iter!=_constraints.end(); ++iter)
|
||||||
iter!=retrievalLocalIds.end() && retrievalLocalIds.size() < _maxLocalRetrieved;
|
|
||||||
++iter)
|
|
||||||
{
|
{
|
||||||
std::map<int, int> ids = _memory->getNeighborsId(*iter, 2, _maxLocalRetrieved - retrievalLocalIds.size() + 1, true, false);
|
if(uContains(_optimizedPoses, iter->second.from()) && uContains(_optimizedPoses, iter->second.to()))
|
||||||
for(std::map<int, int>::reverse_iterator jter=ids.rbegin();
|
|
||||||
jter!=ids.rend() && retrievalLocalIds.size() < _maxLocalRetrieved;
|
|
||||||
++jter)
|
|
||||||
{
|
{
|
||||||
if(_memory->getSignature(jter->first) == 0 &&
|
links.insert(std::make_pair(iter->second.from(), iter->second.to()));
|
||||||
retrievalLocalIdsSet.find(jter->first) == retrievalLocalIdsSet.end())
|
links.insert(std::make_pair(iter->second.to(), iter->second.from())); // <->
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<std::pair<int, Transform> > path = graph::computePath(_optimizedPoses, links, nearestId, signature->id());
|
||||||
|
if(path.size() == 0)
|
||||||
|
{
|
||||||
|
UWARN("Could not compute a path between %d and %d", nearestId, signature->id());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(std::list<std::pair<int, Transform> >::iterator iter=path.begin();
|
||||||
|
iter!=path.end();
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
if(immunizedLocally >= maxLocalLocationsImmunized)
|
||||||
{
|
{
|
||||||
UINFO("retrieval of node %d on local map", jter->first);
|
UWARN("Could not immunize the whole local path (%d) between "
|
||||||
retrievalLocalIds.push_back(jter->first);
|
"%d and %d (max location immunized=%d). You may want "
|
||||||
retrievalLocalIdsSet.insert(jter->first);
|
"to increase RGBD/LocalImmunizationRatio (current=%f (%d of WM=%d)) "
|
||||||
|
"to be able to immunize longer paths.",
|
||||||
|
(int)path.size(),
|
||||||
|
nearestId,
|
||||||
|
signature->id(),
|
||||||
|
maxLocalLocationsImmunized,
|
||||||
|
_localImmunizationRatio,
|
||||||
|
maxLocalLocationsImmunized,
|
||||||
|
(int)_memory->getWorkingMem().size());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(!_memory->isInSTM(iter->first))
|
||||||
|
{
|
||||||
|
if(immunizedLocations.insert(iter->first).second)
|
||||||
|
{
|
||||||
|
++immunizedLocally;
|
||||||
|
}
|
||||||
|
UDEBUG("local node %d on path immunized=1", iter->first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// update Age of the close signatures (oldest the farthest)
|
// retrieval based on the nodes close the the nearest pose in WM
|
||||||
for(std::multimap<float, int>::reverse_iterator iter=nearNodesByDist.rbegin(); iter!=nearNodesByDist.rend(); ++iter)
|
// immunize closest nodes
|
||||||
|
std::map<int, float> nearNodes = graph::getNodesInRadius(signature->id(), _optimizedPoses, _localRadius);
|
||||||
|
// sort by distance
|
||||||
|
std::multimap<float, int> nearNodesByDist;
|
||||||
|
for(std::map<int, float>::iterator iter=nearNodes.begin(); iter!=nearNodes.end(); ++iter)
|
||||||
|
{
|
||||||
|
nearNodesByDist.insert(std::make_pair(iter->second, iter->first));
|
||||||
|
}
|
||||||
|
UINFO("near nodes=%d, max local immunized=%d, ratio=%f WM=%d",
|
||||||
|
(int)nearNodesByDist.size(),
|
||||||
|
maxLocalLocationsImmunized,
|
||||||
|
_localImmunizationRatio,
|
||||||
|
(int)_memory->getWorkingMem().size());
|
||||||
|
for(std::multimap<float, int>::iterator iter=nearNodesByDist.begin();
|
||||||
|
iter!=nearNodesByDist.end() && (retrievalLocalIds.size() < _maxLocalRetrieved || immunizedLocally < maxLocalLocationsImmunized);
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
const Signature * s = _memory->getSignature(iter->second);
|
||||||
|
UASSERT(s!=0);
|
||||||
|
// If there is a change of direction, better to be retrieving
|
||||||
|
// ALL nearest signatures than only newest neighbors
|
||||||
|
const std::map<int, Link> & links = s->getLinks();
|
||||||
|
for(std::map<int, Link>::const_reverse_iterator jter=links.rbegin();
|
||||||
|
jter!=links.rend() && retrievalLocalIds.size() < _maxLocalRetrieved;
|
||||||
|
++jter)
|
||||||
{
|
{
|
||||||
_memory->updateAge(iter->second);
|
if(_memory->getSignature(jter->first) == 0)
|
||||||
|
{
|
||||||
|
UINFO("retrieval of node %d on local map", jter->first);
|
||||||
|
retrievalLocalIds.push_back(jter->first);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if(!_memory->isInSTM(s->id()) && immunizedLocally < maxLocalLocationsImmunized)
|
||||||
|
{
|
||||||
|
if(immunizedLocations.insert(s->id()).second)
|
||||||
|
{
|
||||||
|
++immunizedLocally;
|
||||||
|
}
|
||||||
|
UDEBUG("local node %d (%f m) immunized=1", iter->second, iter->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// well, if the maximum retrieved is not reached, look for neighbors in database
|
||||||
|
if(retrievalLocalIds.size() < _maxLocalRetrieved)
|
||||||
|
{
|
||||||
|
std::set<int> retrievalLocalIdsSet(retrievalLocalIds.begin(), retrievalLocalIds.end());
|
||||||
|
for(std::list<int>::iterator iter=retrievalLocalIds.begin();
|
||||||
|
iter!=retrievalLocalIds.end() && retrievalLocalIds.size() < _maxLocalRetrieved;
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
std::map<int, int> ids = _memory->getNeighborsId(*iter, 2, _maxLocalRetrieved - retrievalLocalIds.size() + 1, true, false);
|
||||||
|
for(std::map<int, int>::reverse_iterator jter=ids.rbegin();
|
||||||
|
jter!=ids.rend() && retrievalLocalIds.size() < _maxLocalRetrieved;
|
||||||
|
++jter)
|
||||||
|
{
|
||||||
|
if(_memory->getSignature(jter->first) == 0 &&
|
||||||
|
retrievalLocalIdsSet.find(jter->first) == retrievalLocalIdsSet.end())
|
||||||
|
{
|
||||||
|
UINFO("retrieval of node %d on local map", jter->first);
|
||||||
|
retrievalLocalIds.push_back(jter->first);
|
||||||
|
retrievalLocalIdsSet.insert(jter->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update Age of the close signatures (oldest the farthest)
|
||||||
|
for(std::multimap<float, int>::reverse_iterator iter=nearNodesByDist.rbegin(); iter!=nearNodesByDist.rend(); ++iter)
|
||||||
|
{
|
||||||
|
_memory->updateAge(iter->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert them first to make sure they are loaded.
|
// insert them first to make sure they are loaded.
|
||||||
@@ -1703,7 +1796,7 @@ bool Rtabmap::process(const SensorData & data)
|
|||||||
if(_localPathOdomPosesUsed)
|
if(_localPathOdomPosesUsed)
|
||||||
{
|
{
|
||||||
//optimize the path's poses locally
|
//optimize the path's poses locally
|
||||||
path = optimizeGraph(nearestId, uKeys(path), false);
|
path = optimizeGraph(nearestId, uKeysSet(path), false);
|
||||||
// transform local poses in optimized graph referential
|
// transform local poses in optimized graph referential
|
||||||
Transform t = _optimizedPoses.at(nearestId) * path.at(nearestId).inverse();
|
Transform t = _optimizedPoses.at(nearestId) * path.at(nearestId).inverse();
|
||||||
for(std::map<int, Transform>::iterator jter=path.begin(); jter!=path.end(); ++jter)
|
for(std::map<int, Transform>::iterator jter=path.begin(); jter!=path.end(); ++jter)
|
||||||
@@ -1904,7 +1997,7 @@ bool Rtabmap::process(const SensorData & data)
|
|||||||
std::map<int, double> stamps;
|
std::map<int, double> stamps;
|
||||||
std::map<int, std::vector<unsigned char> > userDatas;
|
std::map<int, std::vector<unsigned char> > userDatas;
|
||||||
std::multimap<int, Link> constraints;
|
std::multimap<int, Link> constraints;
|
||||||
_memory->getMetricConstraints(uKeys(ids), poses, constraints, false);
|
_memory->getMetricConstraints(uKeysSet(ids), poses, constraints, false);
|
||||||
for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
|
for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
|
||||||
{
|
{
|
||||||
Transform odomPose;
|
Transform odomPose;
|
||||||
@@ -2090,7 +2183,12 @@ bool Rtabmap::process(const SensorData & data)
|
|||||||
statistics_.addStatistic(Statistics::kTimingJoining_trash(), timeJoiningTrash*1000);
|
statistics_.addStatistic(Statistics::kTimingJoining_trash(), timeJoiningTrash*1000);
|
||||||
statistics_.addStatistic(Statistics::kTimingEmptying_trash(), timeEmptyingTrash*1000);
|
statistics_.addStatistic(Statistics::kTimingEmptying_trash(), timeEmptyingTrash*1000);
|
||||||
statistics_.addStatistic(Statistics::kTimingMemory_cleanup(), timeMemoryCleanup*1000);
|
statistics_.addStatistic(Statistics::kTimingMemory_cleanup(), timeMemoryCleanup*1000);
|
||||||
|
|
||||||
|
// Transfer
|
||||||
statistics_.addStatistic(Statistics::kMemorySignatures_removed(), signaturesRemoved.size());
|
statistics_.addStatistic(Statistics::kMemorySignatures_removed(), signaturesRemoved.size());
|
||||||
|
statistics_.addStatistic(Statistics::kMemoryImmunized_globally(), immunizedGlobally);
|
||||||
|
statistics_.addStatistic(Statistics::kMemoryImmunized_locally(), immunizedLocally);
|
||||||
|
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->getWorkingMem().size());
|
||||||
@@ -2433,7 +2531,7 @@ void Rtabmap::optimizeCurrentMap(
|
|||||||
}
|
}
|
||||||
UINFO("get ids time %f s", timer.ticks());
|
UINFO("get ids time %f s", timer.ticks());
|
||||||
|
|
||||||
optimizedPoses = Rtabmap::optimizeGraph(id, uKeys(ids), lookInDatabase, constraints);
|
optimizedPoses = Rtabmap::optimizeGraph(id, uKeysSet(ids), lookInDatabase, constraints);
|
||||||
|
|
||||||
if(_memory->getSignature(id) && uContains(optimizedPoses, id))
|
if(_memory->getSignature(id) && uContains(optimizedPoses, id))
|
||||||
{
|
{
|
||||||
@@ -2446,7 +2544,7 @@ void Rtabmap::optimizeCurrentMap(
|
|||||||
|
|
||||||
std::map<int, Transform> Rtabmap::optimizeGraph(
|
std::map<int, Transform> Rtabmap::optimizeGraph(
|
||||||
int fromId,
|
int fromId,
|
||||||
const std::vector<int> & ids,
|
const std::set<int> & ids,
|
||||||
bool lookInDatabase,
|
bool lookInDatabase,
|
||||||
std::multimap<int, Link> * constraints) const
|
std::multimap<int, Link> * constraints) const
|
||||||
{
|
{
|
||||||
@@ -2603,14 +2701,14 @@ void Rtabmap::get3DMap(std::map<int, Signature> & signatures,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::map<int, int> ids = _memory->getNeighborsId(_memory->getLastWorkingSignature()->id(), 0, global?-1:0, true);
|
std::map<int, int> ids = _memory->getNeighborsId(_memory->getLastWorkingSignature()->id(), 0, global?-1:0, true);
|
||||||
_memory->getMetricConstraints(uKeys(ids), poses, constraints, global);
|
_memory->getMetricConstraints(uKeysSet(ids), poses, constraints, global);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// no optimization on appearance-only mode
|
// no optimization on appearance-only mode
|
||||||
std::map<int, int> ids = _memory->getNeighborsId(_memory->getLastWorkingSignature()->id(), 0, global?-1:0, true);
|
std::map<int, int> ids = _memory->getNeighborsId(_memory->getLastWorkingSignature()->id(), 0, global?-1:0, true);
|
||||||
_memory->getMetricConstraints(uKeys(ids), poses, constraints, global);
|
_memory->getMetricConstraints(uKeysSet(ids), poses, constraints, global);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
|
for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
|
||||||
@@ -2681,14 +2779,14 @@ void Rtabmap::getGraph(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::map<int, int> ids = _memory->getNeighborsId(_memory->getLastWorkingSignature()->id(), 0, global?-1:0, true);
|
std::map<int, int> ids = _memory->getNeighborsId(_memory->getLastWorkingSignature()->id(), 0, global?-1:0, true);
|
||||||
_memory->getMetricConstraints(uKeys(ids), poses, constraints, global);
|
_memory->getMetricConstraints(uKeysSet(ids), poses, constraints, global);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// no optimization on appearance-only mode
|
// no optimization on appearance-only mode
|
||||||
std::map<int, int> ids = _memory->getNeighborsId(_memory->getLastWorkingSignature()->id(), 0, global?-1:0, true);
|
std::map<int, int> ids = _memory->getNeighborsId(_memory->getLastWorkingSignature()->id(), 0, global?-1:0, true);
|
||||||
_memory->getMetricConstraints(uKeys(ids), poses, constraints, global);
|
_memory->getMetricConstraints(uKeysSet(ids), poses, constraints, global);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
|
for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
|
||||||
@@ -2766,13 +2864,10 @@ bool Rtabmap::computePath(
|
|||||||
std::multimap<int, int> clusters = rtabmap::graph::radiusPosesClustering(nodes, _goalReachedRadius, CV_PI);
|
std::multimap<int, int> clusters = rtabmap::graph::radiusPosesClustering(nodes, _goalReachedRadius, CV_PI);
|
||||||
for(std::multimap<int, int>::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
|
for(std::multimap<int, int>::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
|
||||||
{
|
{
|
||||||
if(graph::findLink(links, iter->first, iter->second) != links.end())
|
if(graph::findLink(links, iter->first, iter->second) == links.end())
|
||||||
{
|
{
|
||||||
if(_planVirtualLinksMaxDiffID <= 0 ||
|
links.insert(*iter);
|
||||||
abs(iter->first - iter->second) < _planVirtualLinksMaxDiffID)
|
links.insert(std::make_pair(iter->second, iter->first)); // <->
|
||||||
{
|
|
||||||
links.insert(*iter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -808,7 +808,7 @@ void DatabaseViewer::updateIds()
|
|||||||
{
|
{
|
||||||
//get constraints only for parent links
|
//get constraints only for parent links
|
||||||
|
|
||||||
memory_->getMetricConstraints(std::vector<int>(ids.begin(), ids.end()), poses_, links_, true);
|
memory_->getMetricConstraints(ids, poses_, links_, true);
|
||||||
|
|
||||||
if(poses_.size())
|
if(poses_.size())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -484,7 +484,6 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
|
|
||||||
_ui->graphPlan_goalReachedRadius->setObjectName(Parameters::kRGBDGoalReachedRadius().c_str());
|
_ui->graphPlan_goalReachedRadius->setObjectName(Parameters::kRGBDGoalReachedRadius().c_str());
|
||||||
_ui->graphPlan_planWithNearNodesLinked->setObjectName(Parameters::kRGBDPlanVirtualLinks().c_str());
|
_ui->graphPlan_planWithNearNodesLinked->setObjectName(Parameters::kRGBDPlanVirtualLinks().c_str());
|
||||||
_ui->graphPlan_maxDiffID->setObjectName(Parameters::kRGBDPlanVirtualLinksMaxDiffID().c_str());
|
|
||||||
_ui->graphPlan_goalsSavedInUserData->setObjectName(Parameters::kRGBDGoalsSavedInUserData().c_str());
|
_ui->graphPlan_goalsSavedInUserData->setObjectName(Parameters::kRGBDGoalsSavedInUserData().c_str());
|
||||||
|
|
||||||
_ui->groupBox_localDetection_time->setObjectName(Parameters::kRGBDLocalLoopDetectionTime().c_str());
|
_ui->groupBox_localDetection_time->setObjectName(Parameters::kRGBDLocalLoopDetectionTime().c_str());
|
||||||
@@ -493,6 +492,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
_ui->localDetection_maxDiffID->setObjectName(Parameters::kRGBDLocalLoopDetectionMaxGraphDepth().c_str());
|
_ui->localDetection_maxDiffID->setObjectName(Parameters::kRGBDLocalLoopDetectionMaxGraphDepth().c_str());
|
||||||
_ui->localDetection_pathFilteringRadius->setObjectName(Parameters::kRGBDLocalLoopDetectionPathFilteringRadius().c_str());
|
_ui->localDetection_pathFilteringRadius->setObjectName(Parameters::kRGBDLocalLoopDetectionPathFilteringRadius().c_str());
|
||||||
_ui->checkBox_localSpacePathOdomPosesUsed->setObjectName(Parameters::kRGBDLocalLoopDetectionPathOdomPosesUsed().c_str());
|
_ui->checkBox_localSpacePathOdomPosesUsed->setObjectName(Parameters::kRGBDLocalLoopDetectionPathOdomPosesUsed().c_str());
|
||||||
|
_ui->rgdb_localImmunizationRatio->setObjectName(Parameters::kRGBDLocalImmunizationRatio().c_str());
|
||||||
|
|
||||||
_ui->loopClosure_bowMinInliers->setObjectName(Parameters::kLccBowMinInliers().c_str());
|
_ui->loopClosure_bowMinInliers->setObjectName(Parameters::kLccBowMinInliers().c_str());
|
||||||
_ui->loopClosure_bowInlierDistance->setObjectName(Parameters::kLccBowInlierDistance().c_str());
|
_ui->loopClosure_bowInlierDistance->setObjectName(Parameters::kLccBowInlierDistance().c_str());
|
||||||
@@ -742,7 +742,7 @@ void PreferencesDialog::setupSignals()
|
|||||||
if(obj)
|
if(obj)
|
||||||
{
|
{
|
||||||
// set tooltip as the parameter name
|
// set tooltip as the parameter name
|
||||||
obj->setToolTip(iter->first.c_str());
|
obj->setToolTip(tr("%1 (Default=\"%2\")").arg(iter->first.c_str()).arg(iter->second.c_str()));
|
||||||
|
|
||||||
QSpinBox * spin = qobject_cast<QSpinBox *>(obj);
|
QSpinBox * spin = qobject_cast<QSpinBox *>(obj);
|
||||||
QDoubleSpinBox * doubleSpin = qobject_cast<QDoubleSpinBox *>(obj);
|
QDoubleSpinBox * doubleSpin = qobject_cast<QDoubleSpinBox *>(obj);
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>760</width>
|
<width>760</width>
|
||||||
<height>1542</height>
|
<height>1502</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||||
@@ -2993,6 +2993,13 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
<string>Rehearsal / Weight Update</string>
|
<string>Rehearsal / Weight Update</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_12" columnstretch="0,1">
|
<layout class="QGridLayout" name="gridLayout_12" columnstretch="0,1">
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QCheckBox" name="general_checkBox_RehearsalIdUpdatedToNewOne">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLabel" name="label_similarity">
|
<widget class="QLabel" name="label_similarity">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -3023,8 +3030,18 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="3" column="1">
|
||||||
<widget class="QCheckBox" name="general_checkBox_RehearsalIdUpdatedToNewOne">
|
<widget class="QLabel" name="label_rehearsalIdUpdate_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Ignore Weight Update when the robot is moving.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QCheckBox" name="rgdb_rehearsalWeightIgnoredWhileMoving">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@@ -4972,7 +4989,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QDoubleSpinBox" name="rgdb_newMapOdomChange">
|
<widget class="QDoubleSpinBox" name="rgdb_newMapOdomChange">
|
||||||
<property name="suffix">
|
<property name="suffix">
|
||||||
<string> m</string>
|
<string> m</string>
|
||||||
@@ -4991,7 +5008,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QLabel" name="label_163">
|
<widget class="QLabel" name="label_163">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Odometry change detected that triggers a new map (0 means whatever the odometry change, the detector will still link the new pose in the current map). Also by default, when an odometry with Identity transformation is detected, a new map is automatically created. </string>
|
<string>Odometry change detected that triggers a new map (0 means whatever the odometry change, the detector will still link the new pose in the current map). Also by default, when an odometry with Identity transformation is detected, a new map is automatically created. </string>
|
||||||
@@ -5001,14 +5018,14 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QCheckBox" name="odomScanHistory">
|
<widget class="QCheckBox" name="odomScanHistory">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QLabel" name="label_scanMatching">
|
<widget class="QLabel" name="label_scanMatching">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Pose scan matching: odometry pose correction using laser scan matching. ICP 2D only is used here.</string>
|
<string>Pose scan matching: odometry pose correction using laser scan matching. ICP 2D only is used here.</string>
|
||||||
@@ -5018,7 +5035,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="1">
|
<item row="5" column="1">
|
||||||
<widget class="QLabel" name="label_scanMatching_3">
|
<widget class="QLabel" name="label_scanMatching_3">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Maximum local locations retrieved (0=disabled) near the current pose in the local map or on the current planned path (those on the planned path have priority).</string>
|
<string>Maximum local locations retrieved (0=disabled) near the current pose in the local map or on the current planned path (those on the planned path have priority).</string>
|
||||||
@@ -5028,7 +5045,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0">
|
<item row="5" column="0">
|
||||||
<widget class="QSpinBox" name="spinBox_maxLocalLocationsRetrieved"/>
|
<widget class="QSpinBox" name="spinBox_maxLocalLocationsRetrieved"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="0">
|
<item row="7" column="0">
|
||||||
@@ -5051,23 +5068,35 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="6" column="1">
|
||||||
<widget class="QCheckBox" name="rgdb_rehearsalWeightIgnoredWhileMoving">
|
<widget class="QLabel" name="label_scanMatching_5">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string>Ratio of working memory for which local nodes are immunized from transfer.</string>
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLabel" name="label_165">
|
|
||||||
<property name="text">
|
|
||||||
<string>Ignore weight update when the robot is moving (over linear and angular update values above).</string>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="rgdb_localImmunizationRatio">
|
||||||
|
<property name="suffix">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.100000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.100000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -5382,7 +5411,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QLabel" name="label_space3_5">
|
<widget class="QLabel" name="label_space3_5">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>When a goal is received and processed with success, it is saved in user data of the location with this format: "GOAL:#".</string>
|
<string>When a goal is received and processed with success, it is saved in user data of the location with this format: "GOAL:#".</string>
|
||||||
@@ -5392,33 +5421,13 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QCheckBox" name="graphPlan_goalsSavedInUserData">
|
<widget class="QCheckBox" name="graphPlan_goalsSavedInUserData">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLabel" name="label_space3_6">
|
|
||||||
<property name="text">
|
|
||||||
<string>Maximum ID difference between close nodes to add virtual links. Set 0 to ignore.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QSpinBox" name="graphPlan_maxDiffID">
|
|
||||||
<property name="maximum">
|
|
||||||
<number>999</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>50</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
Reference in New Issue
Block a user