mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-10 21:40:19 +08:00
Fixed graph deformation check without landmark's orientation optimized. Added parameter Marker/VarianceOrientationIgnored to be able to tune correctly GTSAM's bearing/range factor variance.
This commit is contained in:
+1
-1
@@ -20,7 +20,7 @@ SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
|
||||
#######################
|
||||
SET(RTABMAP_MAJOR_VERSION 0)
|
||||
SET(RTABMAP_MINOR_VERSION 21)
|
||||
SET(RTABMAP_PATCH_VERSION 11)
|
||||
SET(RTABMAP_PATCH_VERSION 12)
|
||||
SET(RTABMAP_VERSION
|
||||
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
|
||||
|
||||
|
||||
@@ -343,6 +343,7 @@ private:
|
||||
bool _detectMarkers;
|
||||
float _markerLinVariance;
|
||||
float _markerAngVariance;
|
||||
bool _markerOrientationIgnored;
|
||||
|
||||
int _idCount;
|
||||
int _idMapCount;
|
||||
|
||||
@@ -883,8 +883,9 @@ class RTABMAP_CORE_EXPORT Parameters
|
||||
RTABMAP_PARAM(Marker, Dictionary, int, 0, "Dictionary to use: DICT_ARUCO_4X4_50=0, DICT_ARUCO_4X4_100=1, DICT_ARUCO_4X4_250=2, DICT_ARUCO_4X4_1000=3, DICT_ARUCO_5X5_50=4, DICT_ARUCO_5X5_100=5, DICT_ARUCO_5X5_250=6, DICT_ARUCO_5X5_1000=7, DICT_ARUCO_6X6_50=8, DICT_ARUCO_6X6_100=9, DICT_ARUCO_6X6_250=10, DICT_ARUCO_6X6_1000=11, DICT_ARUCO_7X7_50=12, DICT_ARUCO_7X7_100=13, DICT_ARUCO_7X7_250=14, DICT_ARUCO_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16, DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20");
|
||||
RTABMAP_PARAM(Marker, Length, float, 0, "The length (m) of the markers' side. 0 means automatic marker length estimation using the depth image (the camera should look at the marker perpendicularly for initialization).");
|
||||
RTABMAP_PARAM(Marker, MaxDepthError, float, 0.01, uFormat("Maximum depth error between all corners of a marker when estimating the marker length (when %s is 0). The smaller it is, the more perpendicular the camera should be toward the marker to initialize the length.", kMarkerLength().c_str()));
|
||||
RTABMAP_PARAM(Marker, VarianceLinear, float, 0.001, "Linear variance to set on marker detections.");
|
||||
RTABMAP_PARAM(Marker, VarianceAngular, float, 0.01, "Angular variance to set on marker detections. Set to >=9999 to use only position (xyz) constraint in graph optimization.");
|
||||
RTABMAP_PARAM(Marker, VarianceLinear, float, 0.001, uFormat("Linear variance to set on marker detections. If %s is enabled and %s=2 (GTSAM): it is the variance of the range factor, with 9999 to disable range factor and to do only bearing.", kMarkerVarianceOrientationIgnored().c_str(), kOptimizerStrategy().c_str()));
|
||||
RTABMAP_PARAM(Marker, VarianceAngular, float, 0.01, uFormat("Angular variance to set on marker detections. If %s is enabled, it is ignored with %s=1 (g2o) and it corresponds to bearing variance with %s=2 (GTSAM).", kMarkerVarianceOrientationIgnored().c_str(), kOptimizerStrategy().c_str(), kOptimizerStrategy().c_str()));
|
||||
RTABMAP_PARAM(Marker, VarianceOrientationIgnored, bool, false, uFormat("When this setting is false, the landmark's orientation is optimized during graph optimization. When this setting is true, only the position of the landmark is optimized. This can be useful when the landmark's orientation estimation is not reliable. Note that for %s=1 (g2o), only %s needs be set if we ignore orientation. For %s=2 (GTSAM), instead of optimizing the landmark's position directly, a bearing/range factor is used, with %s as the variance of the range factor (with 9999 to optimize the position with only a bearing factor) and %s as the variance of the bearing factor (pitch/yaw).", kOptimizerStrategy().c_str(), kMarkerVarianceLinear().c_str(), kOptimizerStrategy().c_str(), kMarkerVarianceLinear().c_str(), kMarkerVarianceAngular().c_str()));
|
||||
RTABMAP_PARAM(Marker, CornerRefinementMethod, int, 0, "Corner refinement method (0: None, 1: Subpixel, 2:contour, 3: AprilTag2). For OpenCV <3.3.0, this is \"doCornerRefinement\" parameter: set 0 for false and 1 for true.");
|
||||
RTABMAP_PARAM(Marker, MaxRange, float, 0.0, "Maximum range in which markers will be detected. <=0 for unlimited range.");
|
||||
RTABMAP_PARAM(Marker, MinRange, float, 0.0, "Miniminum range in which markers will be detected. <=0 for unlimited range.");
|
||||
|
||||
+17
-5
@@ -958,12 +958,24 @@ void computeMaxGraphErrors(
|
||||
return;
|
||||
}
|
||||
|
||||
Transform t = t1.inverse()*t2;
|
||||
Transform t;
|
||||
Transform linkT;
|
||||
if(iter->second.from() < 0)
|
||||
{
|
||||
// For landmarks, compare from node to landmark, in case we optimized only marker's position
|
||||
t = t2.inverse()*t1;
|
||||
linkT = iter->second.transform().inverse();
|
||||
}
|
||||
else
|
||||
{
|
||||
t = t1.inverse()*t2;
|
||||
linkT = iter->second.transform();
|
||||
}
|
||||
|
||||
float linearError = uMax3(
|
||||
fabs(iter->second.transform().x() - t.x()),
|
||||
fabs(iter->second.transform().y() - t.y()),
|
||||
force3DoF?0:fabs(iter->second.transform().z() - t.z()));
|
||||
fabs(linkT.x() - t.x()),
|
||||
fabs(linkT.y() - t.y()),
|
||||
force3DoF?0:fabs(linkT.z() - t.z()));
|
||||
UASSERT(iter->second.transVariance(false)>0.0);
|
||||
float stddevLinear = sqrt(iter->second.transVariance(false));
|
||||
float linearErrorRatio = linearError/stddevLinear;
|
||||
@@ -984,7 +996,7 @@ void computeMaxGraphErrors(
|
||||
float opt_roll,opt_pitch,opt_yaw;
|
||||
float link_roll,link_pitch,link_yaw;
|
||||
t.getEulerAngles(opt_roll, opt_pitch, opt_yaw);
|
||||
iter->second.transform().getEulerAngles(link_roll, link_pitch, link_yaw);
|
||||
linkT.getEulerAngles(link_roll, link_pitch, link_yaw);
|
||||
float angularError = uMax3(
|
||||
force3DoF?0:fabs(opt_roll - link_roll),
|
||||
force3DoF?0:fabs(opt_pitch - link_pitch),
|
||||
|
||||
+43
-2
@@ -120,6 +120,7 @@ Memory::Memory(const ParametersMap & parameters) :
|
||||
_detectMarkers(Parameters::defaultRGBDMarkerDetection()),
|
||||
_markerLinVariance(Parameters::defaultMarkerVarianceLinear()),
|
||||
_markerAngVariance(Parameters::defaultMarkerVarianceAngular()),
|
||||
_markerOrientationIgnored(Parameters::defaultMarkerVarianceOrientationIgnored()),
|
||||
_idCount(kIdStart),
|
||||
_idMapCount(kIdStart),
|
||||
_lastSignature(0),
|
||||
@@ -615,8 +616,24 @@ void Memory::parseParameters(const ParametersMap & parameters)
|
||||
Parameters::parse(params, Parameters::kRGBDMarkerDetection(), _detectMarkers);
|
||||
Parameters::parse(params, Parameters::kMarkerVarianceLinear(), _markerLinVariance);
|
||||
Parameters::parse(params, Parameters::kMarkerVarianceAngular(), _markerAngVariance);
|
||||
Parameters::parse(params, Parameters::kMarkerVarianceOrientationIgnored(), _markerOrientationIgnored);
|
||||
Parameters::parse(params, Parameters::kMemLocalizationDataSaved(), _localizationDataSaved);
|
||||
|
||||
if(_markerAngVariance>=9999)
|
||||
{
|
||||
UWARN("Using directly %s>=9999 to ignore marker orientation is deprecated. Use %s instead and "
|
||||
"read correctly the description of the new parameter. We will enable %s and set %s to "
|
||||
"same value than %s (%f) for backward compatibility.",
|
||||
Parameters::kMarkerVarianceAngular().c_str(),
|
||||
Parameters::kMarkerVarianceOrientationIgnored().c_str(),
|
||||
Parameters::kMarkerVarianceOrientationIgnored().c_str(),
|
||||
Parameters::kMarkerVarianceAngular().c_str(),
|
||||
Parameters::kMarkerVarianceLinear().c_str(),
|
||||
_markerLinVariance);
|
||||
_markerAngVariance = _markerLinVariance;
|
||||
_markerOrientationIgnored = true;
|
||||
}
|
||||
|
||||
UASSERT_MSG(_maxStMemSize >= 0, uFormat("value=%d", _maxStMemSize).c_str());
|
||||
UASSERT_MSG(_similarityThreshold >= 0.0f && _similarityThreshold <= 1.0f, uFormat("value=%f", _similarityThreshold).c_str());
|
||||
UASSERT_MSG(_recentWmRatio >= 0.0f && _recentWmRatio <= 1.0f, uFormat("value=%f", _recentWmRatio).c_str());
|
||||
@@ -5593,8 +5610,32 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
|
||||
continue;
|
||||
}
|
||||
cv::Mat covariance = cv::Mat::eye(6,6,CV_64FC1);
|
||||
covariance(cv::Range(0,3), cv::Range(0,3)) *= _markerLinVariance;
|
||||
covariance(cv::Range(3,6), cv::Range(3,6)) *= _markerAngVariance;
|
||||
if(_markerOrientationIgnored)
|
||||
{
|
||||
covariance(cv::Range(3,6), cv::Range(3,6)) *= 9999; // disable orientation estimation
|
||||
bool isGTSAM = uStr2Int(uValue(parameters_, Parameters::kOptimizerStrategy(), uNumber2Str(Parameters::defaultOptimizerStrategy()))) == Optimizer::kTypeGTSAM;
|
||||
if(!isGTSAM)
|
||||
{
|
||||
covariance(cv::Range(0,3), cv::Range(0,3)) *= _markerLinVariance;
|
||||
}
|
||||
else if(_registrationPipeline->force3DoF())
|
||||
{
|
||||
// Bearing/Range in 2D, set X as bearing and Y as range (see OptimizerGTSAM)
|
||||
covariance(cv::Range(0,1), cv::Range(0,1)) *= _markerAngVariance;
|
||||
covariance(cv::Range(1,3), cv::Range(1,3)) *= _markerLinVariance;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bearing/Range in 3D, set X and Y as bearing and Z as range (see OptimizerGTSAM)
|
||||
covariance(cv::Range(0,2), cv::Range(0,2)) *= _markerAngVariance;
|
||||
covariance(cv::Range(2,3), cv::Range(2,3)) *= _markerLinVariance;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
covariance(cv::Range(0,3), cv::Range(0,3)) *= _markerLinVariance;
|
||||
covariance(cv::Range(3,6), cv::Range(3,6)) *= _markerAngVariance;
|
||||
}
|
||||
landmarks.insert(std::make_pair(iter->first, Landmark(iter->first, iter->second.length(), iter->second.pose(), covariance)));
|
||||
}
|
||||
UDEBUG("Markers detected = %d", (int)markers.size());
|
||||
|
||||
+21
-25
@@ -1241,7 +1241,7 @@ bool Rtabmap::process(
|
||||
double timeStatsCreation = 0;
|
||||
|
||||
float hypothesisRatio = 0.0f; // Only used for statistics
|
||||
bool rejectedGlobalLoopClosure = false;
|
||||
bool rejectedLoopClosure = false;
|
||||
|
||||
std::map<int, float> rawLikelihood;
|
||||
std::map<int, float> adjustedLikelihood;
|
||||
@@ -2159,7 +2159,7 @@ bool Rtabmap::process(
|
||||
// Loop closure Threshold
|
||||
if(_highestHypothesis.second >= loopThr)
|
||||
{
|
||||
rejectedGlobalLoopClosure = true;
|
||||
rejectedLoopClosure = true;
|
||||
if(posterior.size() <= 2 && loopThr>0.0f)
|
||||
{
|
||||
// Ignore loop closure if there is only one loop closure hypothesis
|
||||
@@ -2181,7 +2181,7 @@ bool Rtabmap::process(
|
||||
else
|
||||
{
|
||||
_loopClosureHypothesis = _highestHypothesis;
|
||||
rejectedGlobalLoopClosure = false;
|
||||
rejectedLoopClosure = false;
|
||||
}
|
||||
|
||||
timeHypothesesValidation = timer.ticks();
|
||||
@@ -2192,7 +2192,7 @@ bool Rtabmap::process(
|
||||
// Used for Precision-Recall computation.
|
||||
// When analyzing logs, it's convenient to know
|
||||
// if the hypothesis would be rejected if T_loop would be lower.
|
||||
rejectedGlobalLoopClosure = true;
|
||||
rejectedLoopClosure = true;
|
||||
UDEBUG("rejected hypothesis: under loop ratio %f < %f", _highestHypothesis.second, _loopRatio*lastHighestHypothesis.second);
|
||||
}
|
||||
|
||||
@@ -3061,15 +3061,15 @@ bool Rtabmap::process(
|
||||
loopClosureVisualInliers = info.inliers;
|
||||
loopClosureVisualInliersRatio = info.inliersRatio;
|
||||
loopClosureVisualMatches = info.matches;
|
||||
rejectedGlobalLoopClosure = transform.isNull();
|
||||
if(rejectedGlobalLoopClosure)
|
||||
rejectedLoopClosure = transform.isNull();
|
||||
if(rejectedLoopClosure)
|
||||
{
|
||||
UWARN("Rejected loop closure %d -> %d: %s",
|
||||
_loopClosureHypothesis.first, signature->id(), info.rejectedMsg.c_str());
|
||||
}
|
||||
else if(_maxLoopClosureDistance>0.0f && transform.getNorm() > _maxLoopClosureDistance)
|
||||
{
|
||||
rejectedGlobalLoopClosure = true;
|
||||
rejectedLoopClosure = true;
|
||||
UWARN("Rejected localization %d -> %d because distance to map (%fm) is over %s=%fm.",
|
||||
_loopClosureHypothesis.first, signature->id(), transform.getNorm(), Parameters::kRGBDMaxLoopClosureDistance().c_str(), _maxLoopClosureDistance);
|
||||
}
|
||||
@@ -3078,7 +3078,7 @@ bool Rtabmap::process(
|
||||
transform = transform.inverse();
|
||||
}
|
||||
}
|
||||
if(!rejectedGlobalLoopClosure)
|
||||
if(!rejectedLoopClosure)
|
||||
{
|
||||
// Make the new one the parent of the old one
|
||||
UASSERT(info.covariance.at<double>(0,0) > 0.0 && info.covariance.at<double>(5,5) > 0.0);
|
||||
@@ -3086,14 +3086,14 @@ bool Rtabmap::process(
|
||||
loopClosureLinearVariance = uMax3(info.covariance.at<double>(0,0), info.covariance.at<double>(1,1)>=9999?0:info.covariance.at<double>(1,1), info.covariance.at<double>(2,2)>=9999?0:info.covariance.at<double>(2,2));
|
||||
loopClosureAngularVariance = uMax3(info.covariance.at<double>(3,3)>=9999?0:info.covariance.at<double>(3,3), info.covariance.at<double>(4,4)>=9999?0:info.covariance.at<double>(4,4), info.covariance.at<double>(5,5));
|
||||
cv::Mat information = getInformation(info.covariance);
|
||||
rejectedGlobalLoopClosure = !_memory->addLink(Link(signature->id(), _loopClosureHypothesis.first, Link::kGlobalClosure, transform, information));
|
||||
if(!rejectedGlobalLoopClosure)
|
||||
rejectedLoopClosure = !_memory->addLink(Link(signature->id(), _loopClosureHypothesis.first, Link::kGlobalClosure, transform, information));
|
||||
if(!rejectedLoopClosure)
|
||||
{
|
||||
loopClosureLinksAdded.push_back(std::make_pair(signature->id(), _loopClosureHypothesis.first));
|
||||
}
|
||||
}
|
||||
|
||||
if(rejectedGlobalLoopClosure)
|
||||
if(rejectedLoopClosure)
|
||||
{
|
||||
_loopClosureHypothesis.first = 0;
|
||||
}
|
||||
@@ -3137,7 +3137,7 @@ bool Rtabmap::process(
|
||||
{
|
||||
UINFO("Landmark %d observed again! Seen the first time by node %d.", -iter->first, *_memory->getLandmarksIndex().find(iter->first)->second.begin());
|
||||
landmarksDetected.insert(std::make_pair(iter->first, _memory->getLandmarksIndex().find(iter->first)->second));
|
||||
rejectedGlobalLoopClosure = false; // If it was true, it will be set back to false if landmarks are rejected on graph optimization
|
||||
rejectedLoopClosure = false; // If it was true, it will be set back to false if landmarks are rejected on graph optimization
|
||||
loopClosureLinksAdded.push_back(std::make_pair(signature->id(), iter->first));
|
||||
}
|
||||
}
|
||||
@@ -3180,7 +3180,6 @@ bool Rtabmap::process(
|
||||
double optimizationError = 0.0;
|
||||
int optimizationIterations = 0;
|
||||
Transform previousMapCorrection;
|
||||
bool rejectedLandmark = false;
|
||||
bool delayedLocalization = false;
|
||||
UDEBUG("RGB-D SLAM mode: %d", _rgbdSlamMode?1:0);
|
||||
UDEBUG("Incremental: %d", _memory->isIncremental());
|
||||
@@ -3768,8 +3767,7 @@ bool Rtabmap::process(
|
||||
{
|
||||
_loopClosureHypothesis.first = 0;
|
||||
lastProximitySpaceClosureId = 0;
|
||||
rejectedGlobalLoopClosure = true;
|
||||
rejectedLandmark = true;
|
||||
rejectedLoopClosure = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -3804,8 +3802,7 @@ bool Rtabmap::process(
|
||||
updateConstraints = false;
|
||||
_loopClosureHypothesis.first = 0;
|
||||
lastProximitySpaceClosureId = 0;
|
||||
rejectedGlobalLoopClosure = true;
|
||||
rejectedLandmark = true;
|
||||
rejectedLoopClosure = true;
|
||||
}
|
||||
else if(_memory->isIncremental() &&
|
||||
loopClosureLinksAdded.size() &&
|
||||
@@ -3915,8 +3912,7 @@ bool Rtabmap::process(
|
||||
updateConstraints = false;
|
||||
_loopClosureHypothesis.first = 0;
|
||||
lastProximitySpaceClosureId = 0;
|
||||
rejectedGlobalLoopClosure = true;
|
||||
rejectedLandmark = true;
|
||||
rejectedLoopClosure = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4077,7 +4073,7 @@ bool Rtabmap::process(
|
||||
statistics_.addStatistic(Statistics::kLoopDistance_since_last_loc(), _distanceTravelledSinceLastLocalization);
|
||||
|
||||
float x,y,z,roll,pitch,yaw;
|
||||
if(_loopClosureHypothesis.first || lastProximitySpaceClosureId || (!rejectedLandmark && !landmarksDetected.empty()))
|
||||
if(_loopClosureHypothesis.first || lastProximitySpaceClosureId || (!rejectedLoopClosure && !landmarksDetected.empty()))
|
||||
{
|
||||
if(_loopClosureHypothesis.first || lastProximitySpaceClosureId)
|
||||
{
|
||||
@@ -4179,7 +4175,7 @@ bool Rtabmap::process(
|
||||
statistics_.addStatistic(Statistics::kKeypointIndex_memory_usage(), _memory->getVWDictionary()->getIndexMemoryUsed());
|
||||
|
||||
//Epipolar geometry constraint
|
||||
statistics_.addStatistic(Statistics::kLoopRejectedHypothesis(), rejectedGlobalLoopClosure?1.0f:0);
|
||||
statistics_.addStatistic(Statistics::kLoopRejectedHypothesis(), rejectedLoopClosure?1.0f:0);
|
||||
|
||||
statistics_.addStatistic(Statistics::kMemorySmall_movement(), smallDisplacement?1.0f:0);
|
||||
statistics_.addStatistic(Statistics::kMemoryDistance_travelled(), _distanceTravelled);
|
||||
@@ -4274,7 +4270,7 @@ bool Rtabmap::process(
|
||||
if(_startNewMapOnLoopClosure &&
|
||||
_memory->isIncremental() && // only in mapping mode
|
||||
graph::filterLinks(signature->getLinks(), Link::kSelfRefLink).size() == 0 && // alone in the current map
|
||||
(landmarksDetected.empty() || rejectedLandmark) && // 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)
|
||||
{
|
||||
UWARN("Ignoring location %d because a global loop closure is required before starting a new map!",
|
||||
@@ -4294,7 +4290,7 @@ bool Rtabmap::process(
|
||||
else if((smallDisplacement || tooFastMovement) &&
|
||||
_loopClosureHypothesis.first == 0 &&
|
||||
lastProximitySpaceClosureId == 0 &&
|
||||
(rejectedLandmark || landmarksDetected.empty()) &&
|
||||
(rejectedLoopClosure || landmarksDetected.empty()) &&
|
||||
!addedNewLandmark)
|
||||
{
|
||||
// Don't delete the location if a loop closure is detected
|
||||
@@ -4314,7 +4310,7 @@ bool Rtabmap::process(
|
||||
_loopClosureHypothesis.first == 0 &&
|
||||
lastProximitySpaceClosureId == 0 &&
|
||||
!delayedLocalization &&
|
||||
(rejectedLandmark || landmarksDetected.empty()))
|
||||
(rejectedLoopClosure || landmarksDetected.empty()))
|
||||
{
|
||||
_odomCachePoses.erase(signatureRemoved);
|
||||
for(std::multimap<int, Link>::iterator iter=_odomCacheConstraints.begin(); iter!=_odomCacheConstraints.end();)
|
||||
@@ -4722,7 +4718,7 @@ bool Rtabmap::process(
|
||||
refWordsCount,
|
||||
dictionarySize,
|
||||
int(_memory->getWorkingMem().size()),
|
||||
rejectedGlobalLoopClosure?1:0,
|
||||
rejectedLoopClosure?1:0,
|
||||
0,
|
||||
0,
|
||||
int(signaturesRetrieved.size()),
|
||||
|
||||
@@ -1669,6 +1669,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
_ui->ArucoMaxDepthError->setObjectName(Parameters::kMarkerMaxDepthError().c_str());
|
||||
_ui->ArucoVarianceLinear->setObjectName(Parameters::kMarkerVarianceLinear().c_str());
|
||||
_ui->ArucoVarianceAngular->setObjectName(Parameters::kMarkerVarianceAngular().c_str());
|
||||
_ui->ArucoVarianceOrientationIgnored->setObjectName(Parameters::kMarkerVarianceOrientationIgnored().c_str());
|
||||
_ui->ArucoMarkerRangeMin->setObjectName(Parameters::kMarkerMinRange().c_str());
|
||||
_ui->ArucoMarkerRangeMax->setObjectName(Parameters::kMarkerMaxRange().c_str());
|
||||
_ui->ArucoMarkerPriors->setObjectName(Parameters::kMarkerPriors().c_str());
|
||||
|
||||
+173
-150
@@ -63,7 +63,7 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-989</y>
|
||||
<y>0</y>
|
||||
<width>713</width>
|
||||
<height>4705</height>
|
||||
</rect>
|
||||
@@ -95,7 +95,7 @@
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>19</number>
|
||||
<number>18</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_22">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,0">
|
||||
@@ -14891,16 +14891,25 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<layout class="QVBoxLayout" name="verticalLayout_136">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_63" columnstretch="0,1">
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="label_space2_13">
|
||||
<property name="text">
|
||||
<string>Minimum detection range (0=disabled).</string>
|
||||
<item row="7" column="0">
|
||||
<widget class="QDoubleSpinBox" name="ArucoMarkerRangeMax">
|
||||
<property name="suffix">
|
||||
<string> m</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -14926,7 +14935,26 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<item row="1" column="0">
|
||||
<widget class="QDoubleSpinBox" name="ArucoMarkerLength">
|
||||
<property name="suffix">
|
||||
<string> m</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="label_space2_15">
|
||||
<property name="text">
|
||||
<string>World prior locations of the markers. The map will be transformed in marker's world frame when a tag is detected. Format is the marker's ID followed by its position (angles in rad), markers are separated by a vertical line ("id1 x y z roll pitch yaw|id2 x y z roll pitch yaw"). Example: "1 0 0 1 0 0 0|2 1 0 1 0 0 1.57" (marker 2 is 1 meter forward than marker 1 with 90 deg yaw rotation).</string>
|
||||
@@ -14939,11 +14967,65 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLineEdit" name="ArucoMarkerPriors">
|
||||
<property name="placeholderText">
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="label_space2_13">
|
||||
<property name="text">
|
||||
<string>Minimum detection range (0=disabled).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QDoubleSpinBox" name="ArucoPriorsVarianceAngular">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000001000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>9999.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLabel" name="label_space2_16">
|
||||
<property name="text">
|
||||
<string>Linear variance to set on marker priors.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QLabel" name="label_space2_17">
|
||||
<property name="text">
|
||||
<string>Angular variance to set on marker priors.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
@@ -14953,51 +15035,22 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QDoubleSpinBox" name="ArucoMarkerRangeMax">
|
||||
<item row="3" column="0">
|
||||
<widget class="QDoubleSpinBox" name="ArucoVarianceLinear">
|
||||
<property name="suffix">
|
||||
<string> m</string>
|
||||
<string/>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999.000000000000000</double>
|
||||
<double>0.000001000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.000000000000000</double>
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_space2_6">
|
||||
<property name="text">
|
||||
<string>Linear variance to set on marker detections.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_space2_9">
|
||||
<property name="text">
|
||||
<string>Angular variance to set on marker detections. Set to >=9999 to use only position (xyz) constraint in graph optimization.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -15020,39 +15073,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QDoubleSpinBox" name="ArucoMarkerLength">
|
||||
<property name="suffix">
|
||||
<string> m</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="label_space2_16">
|
||||
<property name="text">
|
||||
<string>Linear variance to set on marker priors.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="6" column="0">
|
||||
<widget class="QDoubleSpinBox" name="ArucoMarkerRangeMin">
|
||||
<property name="suffix">
|
||||
<string> m</string>
|
||||
@@ -15087,10 +15108,10 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="label_space2_14">
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_space2_6">
|
||||
<property name="text">
|
||||
<string>Maximum detection range (0=unlimited).</string>
|
||||
<string>Linear variance to set on marker detections. If variance is adjusted to ignore orientation (see below) and Optimizer/Strategy=2 (GTSAM): it is the variance of the range factor, with 9999 to disable range factor and to do only bearing.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
@@ -15100,29 +15121,10 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QDoubleSpinBox" name="ArucoVarianceLinear">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000001000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_markerDetection">
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_space2_9">
|
||||
<property name="text">
|
||||
<string>Detect static markers to be added as landmarks for graph optimization. If input data have already landmarks, this will be ignored.</string>
|
||||
<string>Angular variance to set on marker detections. If variance is adjusted to ignore orientation (see below), the angular variance is ignored with Optimizer/Strategy=1 (g2o) and it corresponds to bearing variance with Optimizer/Strategy=2 (GTSAM).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
@@ -15132,33 +15134,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_space2_7">
|
||||
<property name="text">
|
||||
<string>Marker length. The length (m) of the markers' side. 0 means automatic marker length estimation using the depth image (the camera should look at the marker perpendicularly for initialization).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLabel" name="label_space2_17">
|
||||
<property name="text">
|
||||
<string>Angular variance to set on marker priors.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<item row="9" column="0">
|
||||
<widget class="QDoubleSpinBox" name="ArucoPriorsVarianceLinear">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
@@ -15177,25 +15153,72 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QDoubleSpinBox" name="ArucoPriorsVarianceAngular">
|
||||
<property name="suffix">
|
||||
<item row="7" column="1">
|
||||
<widget class="QLabel" name="label_space2_14">
|
||||
<property name="text">
|
||||
<string>Maximum detection range (0=unlimited).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLineEdit" name="ArucoMarkerPriors">
|
||||
<property name="placeholderText">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>6</number>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_space2_7">
|
||||
<property name="text">
|
||||
<string>Marker length. The length (m) of the markers' side. 0 means automatic marker length estimation using the depth image (the camera should look at the marker perpendicularly for initialization).</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000001000000000</double>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>9999.000000000000000</double>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.001000000000000</double>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_markerDetection">
|
||||
<property name="text">
|
||||
<string>Detect static markers to be added as landmarks for graph optimization. If input data have already landmarks, this will be ignored.</string>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.001000000000000</double>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="label_space2_20">
|
||||
<property name="toolTip">
|
||||
<string>When this setting is false, the landmark's orientation is optimized during graph optimization. When this setting is true, only the position of the landmark is optimized. This can be useful when the landmark's orientation estimation is not reliable. Note that for Optimizer/Strategy=1 (g2o), only Marker/VarianceLinear needs be set if we ignore orientation. For Optimizer/Strategy=2 (GTSAM), instead of optimizing the landmark's position directly, a bearing/range factor is used, with Marker/VarianceLinear as the variance of the range factor (with 9999 to optimize the position with only a bearing factor) and Marker/VarianceAngular as the variance of the bearing factor (pitch/yaw).</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Adjust variance to ignore orientation during optimization. Mouseover for more details.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="ArucoVarianceOrientationIgnored">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -16182,7 +16205,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_764">
|
||||
<widget class="QLabel" name="label_7641">
|
||||
<property name="text">
|
||||
<string>[Visual] Floor threshold. Only track features in 3D feature map that are over this threshold (height in base frame). Can be useful to ignore reflections on the floor. 0 means disabled.</string>
|
||||
</property>
|
||||
@@ -16234,7 +16257,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<widget class="QLabel" name="label_763">
|
||||
<widget class="QLabel" name="label_7631">
|
||||
<property name="text">
|
||||
<string>[Visual] Update 3D local feature map on every frames with bundle adjustment. Recommended if Vis/DepthAsMask=false and Mem/UseOdomFeatures=true so that features without depth are better triangulated on every frame (not only on keyframes). If disabled, the feature map is updated only when a new keyframe is added (legacy approach).</string>
|
||||
</property>
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<package format="2">
|
||||
<name>rtabmap</name>
|
||||
<version>0.21.11</version>
|
||||
<version>0.21.12</version>
|
||||
<description>RTAB-Map's standalone library. RTAB-Map is a RGB-D SLAM approach with real-time constraints.</description>
|
||||
<maintainer email="matlabbe@gmail.com">Mathieu Labbe</maintainer>
|
||||
<author>Mathieu Labbe</author>
|
||||
|
||||
@@ -1037,8 +1037,9 @@ int main(int argc, char * argv[])
|
||||
|
||||
const rtabmap::Statistics & stats = rtabmap.getStatistics();
|
||||
int refId = stats.refImageId();
|
||||
bool rejected = uValue(stats.data(), rtabmap::Statistics::kLoopRejectedHypothesis(), 0.0f) != 0.0f;
|
||||
int loopId = stats.loopClosureId() > 0? stats.loopClosureId(): stats.proximityDetectionId() > 0?stats.proximityDetectionId() :0;
|
||||
int landmarkId = (int)uValue(stats.data(), rtabmap::Statistics::kLoopLandmark_detected(), 0.0f);
|
||||
int landmarkId = rejected?0:(int)uValue(stats.data(), rtabmap::Statistics::kLoopLandmark_detected(), 0.0f);
|
||||
int refMapId = stats.refImageMapId();
|
||||
++totalFrames;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user