mirror of
https://github.com/introlab/rtabmap_ros.git
synced 2026-10-03 16:27:46 +08:00
Added a quality odometry threshold, turning the background yellow when the mapping area has too low features
git-svn-id: http://rtabmap.googlecode.com/svn/trunk/rtabmap@1334 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
@@ -34,7 +34,7 @@ class RTABMAP_EXP Odometry
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Odometry() {}
|
virtual ~Odometry() {}
|
||||||
Transform process(Image & image);
|
Transform process(Image & image, int * quality = 0);
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
|
|
||||||
bool isLargeEnoughTransform(const Transform & transform);
|
bool isLargeEnoughTransform(const Transform & transform);
|
||||||
@@ -44,18 +44,20 @@ public:
|
|||||||
int getMinInliers() const {return _minInliers;}
|
int getMinInliers() const {return _minInliers;}
|
||||||
float getInlierDistance() const {return _inlierDistance;}
|
float getInlierDistance() const {return _inlierDistance;}
|
||||||
int getIterations() const {return _iterations;}
|
int getIterations() const {return _iterations;}
|
||||||
|
float getWordsRatio() const {return _wordsRatio;}
|
||||||
float getMaxDepth() const {return _maxDepth;}
|
float getMaxDepth() const {return _maxDepth;}
|
||||||
float geLinearUpdate() const {return _linearUpdate;}
|
float geLinearUpdate() const {return _linearUpdate;}
|
||||||
float getAngularUpdate() const {return _angularUpdate;}
|
float getAngularUpdate() const {return _angularUpdate;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual Transform computeTransform(Image & image) = 0;
|
virtual Transform computeTransform(Image & image, int * quality = 0) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _maxFeatures;
|
int _maxFeatures;
|
||||||
int _minInliers;
|
int _minInliers;
|
||||||
float _inlierDistance;
|
float _inlierDistance;
|
||||||
int _iterations;
|
int _iterations;
|
||||||
|
float _wordsRatio;
|
||||||
float _maxDepth;
|
float _maxDepth;
|
||||||
float _linearUpdate;
|
float _linearUpdate;
|
||||||
float _angularUpdate;
|
float _angularUpdate;
|
||||||
@@ -68,6 +70,7 @@ protected:
|
|||||||
int maxWords = Parameters::defaultOdomMaxWords(),
|
int maxWords = Parameters::defaultOdomMaxWords(),
|
||||||
int minInliers = Parameters::defaultOdomMinInliers(),
|
int minInliers = Parameters::defaultOdomMinInliers(),
|
||||||
int iterations = Parameters::defaultOdomIterations(),
|
int iterations = Parameters::defaultOdomIterations(),
|
||||||
|
float wordsRatio = Parameters::defaultOdomWordsRatio(),
|
||||||
float maxDepth = Parameters::defaultOdomMaxDepth(),
|
float maxDepth = Parameters::defaultOdomMaxDepth(),
|
||||||
float linearUpdate = Parameters::defaultOdomLinearUpdate(),
|
float linearUpdate = Parameters::defaultOdomLinearUpdate(),
|
||||||
float angularUpdate = Parameters::defaultOdomAngularUpdate(),
|
float angularUpdate = Parameters::defaultOdomAngularUpdate(),
|
||||||
@@ -83,6 +86,7 @@ public:
|
|||||||
int maxWords = Parameters::defaultOdomMaxWords(),
|
int maxWords = Parameters::defaultOdomMaxWords(),
|
||||||
int minInliers = Parameters::defaultOdomMinInliers(),
|
int minInliers = Parameters::defaultOdomMinInliers(),
|
||||||
int iterations = Parameters::defaultOdomIterations(),
|
int iterations = Parameters::defaultOdomIterations(),
|
||||||
|
float wordsRatio = Parameters::defaultOdomWordsRatio(),
|
||||||
float maxDepth = Parameters::defaultOdomMaxDepth(),
|
float maxDepth = Parameters::defaultOdomMaxDepth(),
|
||||||
float linearUpdate = Parameters::defaultOdomLinearUpdate(),
|
float linearUpdate = Parameters::defaultOdomLinearUpdate(),
|
||||||
float angularUpdate = Parameters::defaultOdomAngularUpdate(),
|
float angularUpdate = Parameters::defaultOdomAngularUpdate(),
|
||||||
@@ -96,7 +100,7 @@ public:
|
|||||||
virtual void reset();
|
virtual void reset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual Transform computeTransform(Image & image);
|
virtual Transform computeTransform(Image & image, int * quality = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _briefBytes;
|
int _briefBytes;
|
||||||
@@ -120,6 +124,7 @@ public:
|
|||||||
int maxWords = Parameters::defaultOdomMaxWords(),
|
int maxWords = Parameters::defaultOdomMaxWords(),
|
||||||
int minInliers = Parameters::defaultOdomMinInliers(),
|
int minInliers = Parameters::defaultOdomMinInliers(),
|
||||||
int iterations = Parameters::defaultOdomIterations(),
|
int iterations = Parameters::defaultOdomIterations(),
|
||||||
|
float wordsRatio = Parameters::defaultOdomWordsRatio(),
|
||||||
float maxDepth = Parameters::defaultOdomMaxDepth(),
|
float maxDepth = Parameters::defaultOdomMaxDepth(),
|
||||||
float linearUpdate = Parameters::defaultOdomLinearUpdate(),
|
float linearUpdate = Parameters::defaultOdomLinearUpdate(),
|
||||||
float angularUpdate = Parameters::defaultOdomAngularUpdate(),
|
float angularUpdate = Parameters::defaultOdomAngularUpdate(),
|
||||||
@@ -132,7 +137,7 @@ public:
|
|||||||
virtual void reset();
|
virtual void reset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual Transform computeTransform(Image & image);
|
virtual Transform computeTransform(Image & image, int * quality = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Memory * _memory;
|
Memory * _memory;
|
||||||
@@ -156,7 +161,7 @@ public:
|
|||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual Transform computeTransform(Image & image);
|
virtual Transform computeTransform(Image & image, int * quality = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _decimation;
|
int _decimation;
|
||||||
|
|||||||
@@ -17,16 +17,19 @@ class OdometryEvent : public UEvent
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OdometryEvent(
|
OdometryEvent(
|
||||||
const Image & data) :
|
const Image & data, int quality = 0) :
|
||||||
_data(data) {}
|
_data(data),
|
||||||
|
_quality(quality) {}
|
||||||
virtual ~OdometryEvent() {}
|
virtual ~OdometryEvent() {}
|
||||||
virtual std::string getClassName() const {return "OdometryEvent";}
|
virtual std::string getClassName() const {return "OdometryEvent";}
|
||||||
|
|
||||||
bool isValid() const {return !_data.pose().isNull();}
|
bool isValid() const {return !_data.pose().isNull();}
|
||||||
const Image & data() const {return _data;}
|
const Image & data() const {return _data;}
|
||||||
|
int quality() const {return _quality;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Image _data;
|
Image _data;
|
||||||
|
int _quality;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OdometryResetEvent : public UEvent
|
class OdometryResetEvent : public UEvent
|
||||||
|
|||||||
@@ -224,6 +224,7 @@ class RTABMAP_EXP Parameters
|
|||||||
RTABMAP_PARAM(Odom, MinInliers, int, 10, "Minimum visual word correspondences to compute geometry transform.");
|
RTABMAP_PARAM(Odom, MinInliers, int, 10, "Minimum visual word correspondences to compute geometry transform.");
|
||||||
RTABMAP_PARAM(Odom, Iterations, int, 100, "Maximum iterations to compute the transform from visual words.");
|
RTABMAP_PARAM(Odom, Iterations, int, 100, "Maximum iterations to compute the transform from visual words.");
|
||||||
RTABMAP_PARAM(Odom, MaxDepth, float, 5.0, "Max depth of the words (0 means no limit).");
|
RTABMAP_PARAM(Odom, MaxDepth, float, 5.0, "Max depth of the words (0 means no limit).");
|
||||||
|
RTABMAP_PARAM(Odom, WordsRatio, float, 0.5, "Minmum ratio of keypoints between the current image and the last image to compute odometry.");
|
||||||
RTABMAP_PARAM(Odom, ResetCountdown, int, 0, "Automatically reset odometry after X consecutive images on which odometry cannot be computed (value=0 disables auto-reset).")
|
RTABMAP_PARAM(Odom, ResetCountdown, int, 0, "Automatically reset odometry after X consecutive images on which odometry cannot be computed (value=0 disables auto-reset).")
|
||||||
|
|
||||||
RTABMAP_PARAM(OdomBin, BriefBytes, int, 32, "");
|
RTABMAP_PARAM(OdomBin, BriefBytes, int, 32, "");
|
||||||
|
|||||||
+36
-19
@@ -36,6 +36,7 @@ Odometry::Odometry(
|
|||||||
int maxWords,
|
int maxWords,
|
||||||
int minInliers,
|
int minInliers,
|
||||||
int iterations,
|
int iterations,
|
||||||
|
float wordsRatio,
|
||||||
float maxDepth,
|
float maxDepth,
|
||||||
float linearUpdate,
|
float linearUpdate,
|
||||||
float angularUpdate,
|
float angularUpdate,
|
||||||
@@ -44,6 +45,7 @@ Odometry::Odometry(
|
|||||||
_minInliers(minInliers),
|
_minInliers(minInliers),
|
||||||
_inlierDistance(inlierDistance),
|
_inlierDistance(inlierDistance),
|
||||||
_iterations(iterations),
|
_iterations(iterations),
|
||||||
|
_wordsRatio(wordsRatio),
|
||||||
_maxDepth(maxDepth),
|
_maxDepth(maxDepth),
|
||||||
_linearUpdate(linearUpdate),
|
_linearUpdate(linearUpdate),
|
||||||
_angularUpdate(angularUpdate),
|
_angularUpdate(angularUpdate),
|
||||||
@@ -59,6 +61,7 @@ Odometry::Odometry(const rtabmap::ParametersMap & parameters) :
|
|||||||
_minInliers(Parameters::defaultOdomMinInliers()),
|
_minInliers(Parameters::defaultOdomMinInliers()),
|
||||||
_inlierDistance(Parameters::defaultOdomInlierDistance()),
|
_inlierDistance(Parameters::defaultOdomInlierDistance()),
|
||||||
_iterations(Parameters::defaultOdomIterations()),
|
_iterations(Parameters::defaultOdomIterations()),
|
||||||
|
_wordsRatio(Parameters::defaultOdomWordsRatio()),
|
||||||
_maxDepth(Parameters::defaultOdomMaxDepth()),
|
_maxDepth(Parameters::defaultOdomMaxDepth()),
|
||||||
_linearUpdate(Parameters::defaultOdomLinearUpdate()),
|
_linearUpdate(Parameters::defaultOdomLinearUpdate()),
|
||||||
_angularUpdate(Parameters::defaultOdomAngularUpdate()),
|
_angularUpdate(Parameters::defaultOdomAngularUpdate()),
|
||||||
@@ -72,6 +75,7 @@ Odometry::Odometry(const rtabmap::ParametersMap & parameters) :
|
|||||||
Parameters::parse(parameters, Parameters::kOdomMinInliers(), _minInliers);
|
Parameters::parse(parameters, Parameters::kOdomMinInliers(), _minInliers);
|
||||||
Parameters::parse(parameters, Parameters::kOdomInlierDistance(), _inlierDistance);
|
Parameters::parse(parameters, Parameters::kOdomInlierDistance(), _inlierDistance);
|
||||||
Parameters::parse(parameters, Parameters::kOdomIterations(), _iterations);
|
Parameters::parse(parameters, Parameters::kOdomIterations(), _iterations);
|
||||||
|
Parameters::parse(parameters, Parameters::kOdomWordsRatio(), _wordsRatio);
|
||||||
Parameters::parse(parameters, Parameters::kOdomMaxDepth(), _maxDepth);
|
Parameters::parse(parameters, Parameters::kOdomMaxDepth(), _maxDepth);
|
||||||
Parameters::parse(parameters, Parameters::kOdomMaxWords(), _maxFeatures);
|
Parameters::parse(parameters, Parameters::kOdomMaxWords(), _maxFeatures);
|
||||||
}
|
}
|
||||||
@@ -89,9 +93,9 @@ bool Odometry::isLargeEnoughTransform(const Transform & transform)
|
|||||||
fabs(transform.z()) > _linearUpdate;
|
fabs(transform.z()) > _linearUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform Odometry::process(Image & image)
|
Transform Odometry::process(Image & image, int * quality)
|
||||||
{
|
{
|
||||||
Transform t = this->computeTransform(image);
|
Transform t = this->computeTransform(image, quality);
|
||||||
if(!t.isNull())
|
if(!t.isNull())
|
||||||
{
|
{
|
||||||
_resetCurrentCount = _resetCountdown;
|
_resetCurrentCount = _resetCountdown;
|
||||||
@@ -117,6 +121,7 @@ OdometryBinary::OdometryBinary(
|
|||||||
int maxWords,
|
int maxWords,
|
||||||
int minInliers,
|
int minInliers,
|
||||||
int iterations,
|
int iterations,
|
||||||
|
float wordsRatio,
|
||||||
float maxDepth,
|
float maxDepth,
|
||||||
float linearUpdate,
|
float linearUpdate,
|
||||||
float angularUpdate,
|
float angularUpdate,
|
||||||
@@ -125,7 +130,7 @@ OdometryBinary::OdometryBinary(
|
|||||||
int fastThreshold,
|
int fastThreshold,
|
||||||
bool fastNonmaxSuppression,
|
bool fastNonmaxSuppression,
|
||||||
bool bruteForceMatching) :
|
bool bruteForceMatching) :
|
||||||
Odometry(inlierDistance, maxWords, minInliers, iterations, maxDepth, linearUpdate, angularUpdate, resetCoutdown),
|
Odometry(inlierDistance, maxWords, minInliers, iterations, wordsRatio, maxDepth, linearUpdate, angularUpdate, resetCoutdown),
|
||||||
_briefBytes(briefBytes),
|
_briefBytes(briefBytes),
|
||||||
_fastThreshold(fastThreshold),
|
_fastThreshold(fastThreshold),
|
||||||
_fastNonmaxSuppression(fastNonmaxSuppression),
|
_fastNonmaxSuppression(fastNonmaxSuppression),
|
||||||
@@ -156,8 +161,8 @@ void OdometryBinary::reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// return true if odometry is correctly computed
|
// return not null transform if odometry is correctly computed
|
||||||
Transform OdometryBinary::computeTransform(Image & image)
|
Transform OdometryBinary::computeTransform(Image & image, int * quality)
|
||||||
{
|
{
|
||||||
UTimer timer;
|
UTimer timer;
|
||||||
cv::Mat imageMono;
|
cv::Mat imageMono;
|
||||||
@@ -187,7 +192,7 @@ Transform OdometryBinary::computeTransform(Image & image)
|
|||||||
|
|
||||||
if(_lastKeypoints.size())
|
if(_lastKeypoints.size())
|
||||||
{
|
{
|
||||||
if(newDescriptors.rows && newDescriptors.rows > (int)_lastKeypoints.size()/2) // at least 50% keypoints
|
if(newDescriptors.rows && newDescriptors.rows > (int)(getWordsRatio() * float(_lastKeypoints.size()))) // at least 50% keypoints
|
||||||
{
|
{
|
||||||
cv::Mat results;
|
cv::Mat results;
|
||||||
cv::Mat dists;
|
cv::Mat dists;
|
||||||
@@ -308,6 +313,11 @@ Transform OdometryBinary::computeTransform(Image & image)
|
|||||||
float x,y,z, roll,pitch,yaw;
|
float x,y,z, roll,pitch,yaw;
|
||||||
pcl::getTranslationAndEulerAngles(util3d::transformToEigen3f(t), x,y,z, roll,pitch,yaw);
|
pcl::getTranslationAndEulerAngles(util3d::transformToEigen3f(t), x,y,z, roll,pitch,yaw);
|
||||||
|
|
||||||
|
if(quality)
|
||||||
|
{
|
||||||
|
*quality = inliers;
|
||||||
|
}
|
||||||
|
|
||||||
// Large transforms may be erroneous computed transforms, so keep under 1 m
|
// Large transforms may be erroneous computed transforms, so keep under 1 m
|
||||||
if(inliers >= this->getMinInliers())
|
if(inliers >= this->getMinInliers())
|
||||||
{
|
{
|
||||||
@@ -335,8 +345,8 @@ Transform OdometryBinary::computeTransform(Image & image)
|
|||||||
}
|
}
|
||||||
else if(newDescriptors.rows)
|
else if(newDescriptors.rows)
|
||||||
{
|
{
|
||||||
UWARN("At least 50%% keypoints of the last image required. New=%d last=%d",
|
UWARN("At least %f%% keypoints of the last image required. New=%d last=%d",
|
||||||
newDescriptors.rows, _lastKeypoints.size());
|
getWordsRatio()*100.0f, newDescriptors.rows, _lastKeypoints.size());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -368,13 +378,14 @@ OdometryBOW::OdometryBOW(
|
|||||||
int maxWords,
|
int maxWords,
|
||||||
int minInliers,
|
int minInliers,
|
||||||
int iterations,
|
int iterations,
|
||||||
|
float wordsRatio,
|
||||||
float maxDepth,
|
float maxDepth,
|
||||||
float linearUpdate,
|
float linearUpdate,
|
||||||
float angularUpdate,
|
float angularUpdate,
|
||||||
int resetCoutdown,
|
int resetCoutdown,
|
||||||
float surfHessianThreshold,
|
float surfHessianThreshold,
|
||||||
float nndr) : // nearest neighbor distance ratio
|
float nndr) : // nearest neighbor distance ratio
|
||||||
Odometry(inlierDistance, maxWords, minInliers, iterations, maxDepth, linearUpdate, angularUpdate, resetCoutdown),
|
Odometry(inlierDistance, maxWords, minInliers, iterations, wordsRatio, maxDepth, linearUpdate, angularUpdate, resetCoutdown),
|
||||||
_memory(new Memory())
|
_memory(new Memory())
|
||||||
{
|
{
|
||||||
ParametersMap customParameters;
|
ParametersMap customParameters;
|
||||||
@@ -421,8 +432,8 @@ void OdometryBOW::reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// return true if odometry is correctly computed
|
// return not null transform if odometry is correctly computed
|
||||||
Transform OdometryBOW::computeTransform(Image & image)
|
Transform OdometryBOW::computeTransform(Image & image, int * quality)
|
||||||
{
|
{
|
||||||
UTimer timer;
|
UTimer timer;
|
||||||
Transform output;
|
Transform output;
|
||||||
@@ -444,10 +455,10 @@ Transform OdometryBOW::computeTransform(Image & image)
|
|||||||
if(previousSignature && newSignature)
|
if(previousSignature && newSignature)
|
||||||
{
|
{
|
||||||
Transform transform;
|
Transform transform;
|
||||||
if(newSignature->getWords3().size() < previousSignature->getWords3().size()/2)
|
if(newSignature->getWords3().size() < (unsigned int)(getWordsRatio() * float(previousSignature->getWords3().size())))
|
||||||
{
|
{
|
||||||
UWARN("At least 50%% keypoints of the last image required. New=%d last=%d",
|
UWARN("At least %f%% keypoints of the last image required. New=%d last=%d",
|
||||||
newSignature->getWords3().size(), previousSignature->getWords3().size());
|
getWordsRatio()*100.0f, newSignature->getWords3().size(), previousSignature->getWords3().size());
|
||||||
}
|
}
|
||||||
else if(!previousSignature->getWords3().empty() && !newSignature->getWords3().empty())
|
else if(!previousSignature->getWords3().empty() && !newSignature->getWords3().empty())
|
||||||
{
|
{
|
||||||
@@ -472,6 +483,11 @@ Transform OdometryBOW::computeTransform(Image & image)
|
|||||||
this->getIterations(),
|
this->getIterations(),
|
||||||
&inliers);
|
&inliers);
|
||||||
|
|
||||||
|
if(quality)
|
||||||
|
{
|
||||||
|
*quality = inliers;
|
||||||
|
}
|
||||||
|
|
||||||
if(inliers < this->getMinInliers())
|
if(inliers < this->getMinInliers())
|
||||||
{
|
{
|
||||||
transform.setNull();
|
transform.setNull();
|
||||||
@@ -527,7 +543,7 @@ OdometryICP::OdometryICP(
|
|||||||
float linearUpdate,
|
float linearUpdate,
|
||||||
float angularUpdate,
|
float angularUpdate,
|
||||||
int resetCoutdown) :
|
int resetCoutdown) :
|
||||||
Odometry(0, 0, 0, 0, maxDepth, linearUpdate, angularUpdate, resetCoutdown),
|
Odometry(0, 0, 0, 0, 0, maxDepth, linearUpdate, angularUpdate, resetCoutdown),
|
||||||
_decimation(decimation),
|
_decimation(decimation),
|
||||||
_voxelSize(voxelSize),
|
_voxelSize(voxelSize),
|
||||||
_samples(samples),
|
_samples(samples),
|
||||||
@@ -563,8 +579,8 @@ void OdometryICP::reset()
|
|||||||
_previousCloud.reset(new pcl::PointCloud<pcl::PointNormal>);
|
_previousCloud.reset(new pcl::PointCloud<pcl::PointNormal>);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return not null if odometry is correctly computed
|
// return not null transform if odometry is correctly computed
|
||||||
Transform OdometryICP::computeTransform(Image & image)
|
Transform OdometryICP::computeTransform(Image & image, int * quality)
|
||||||
{
|
{
|
||||||
UTimer timer;
|
UTimer timer;
|
||||||
Transform output;
|
Transform output;
|
||||||
@@ -698,9 +714,10 @@ void OdometryThread::mainLoop()
|
|||||||
getImage(image);
|
getImage(image);
|
||||||
if(!image.empty())
|
if(!image.empty())
|
||||||
{
|
{
|
||||||
Transform pose = _odometry->process(image);
|
int quality = 0;
|
||||||
|
Transform pose = _odometry->process(image, &quality);
|
||||||
image.setPose(pose); // a null pose notify that odometry could not be computed
|
image.setPose(pose); // a null pose notify that odometry could not be computed
|
||||||
this->post(new OdometryEvent(image));
|
this->post(new OdometryEvent(image, quality));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ private slots:
|
|||||||
void selectScreenCaptureFormat(bool checked);
|
void selectScreenCaptureFormat(bool checked);
|
||||||
void takeScreenshot();
|
void takeScreenshot();
|
||||||
void updateElapsedTime();
|
void updateElapsedTime();
|
||||||
void processOdometry(const rtabmap::Image & data);
|
void processOdometry(const rtabmap::Image & data, int quality);
|
||||||
void applyAllPrefSettings();
|
void applyAllPrefSettings();
|
||||||
void applyPrefSettings(PreferencesDialog::PANEL_FLAGS flags);
|
void applyPrefSettings(PreferencesDialog::PANEL_FLAGS flags);
|
||||||
void applyPrefSettings(const rtabmap::ParametersMap & parameters);
|
void applyPrefSettings(const rtabmap::ParametersMap & parameters);
|
||||||
@@ -156,7 +156,7 @@ private slots:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void statsReceived(const rtabmap::Statistics &);
|
void statsReceived(const rtabmap::Statistics &);
|
||||||
void odometryReceived(const rtabmap::Image &);
|
void odometryReceived(const rtabmap::Image &, int);
|
||||||
void thresholdsChanged(int, int);
|
void thresholdsChanged(int, int);
|
||||||
void stateChanged(MainWindow::State);
|
void stateChanged(MainWindow::State);
|
||||||
void rtabmapEventInitReceived(int status, const QString & info);
|
void rtabmapEventInitReceived(int status, const QString & info);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class RTABMAPGUI_EXP OdometryViewer : public CloudViewer, public UEventsHandler
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OdometryViewer(int maxClouds = 10, int decimation = 2, float voxelSize = 0.0f, QWidget * parent = 0);
|
OdometryViewer(int maxClouds = 10, int decimation = 2, float voxelSize = 0.0f, int qualityWarningThr=0, QWidget * parent = 0);
|
||||||
virtual ~OdometryViewer() {}
|
virtual ~OdometryViewer() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -35,11 +35,13 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
UMutex dataMutex_;
|
UMutex dataMutex_;
|
||||||
std::list<rtabmap::Image> buffer_;
|
std::list<rtabmap::Image> data_;
|
||||||
|
int dataQuality_;
|
||||||
UTimer timer_;
|
UTimer timer_;
|
||||||
int maxClouds_;
|
int maxClouds_;
|
||||||
float voxelSize_;
|
float voxelSize_;
|
||||||
int decimation_;
|
int decimation_;
|
||||||
|
int qualityWarningThr_;
|
||||||
int id_;
|
int id_;
|
||||||
std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr > clouds_;
|
std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr > clouds_;
|
||||||
QAction * _aSetVoxelSize;
|
QAction * _aSetVoxelSize;
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ public:
|
|||||||
bool imageHighestHypShown() const;
|
bool imageHighestHypShown() const;
|
||||||
bool beepOnPause() const;
|
bool beepOnPause() const;
|
||||||
int getKeypointsOpacity() const;
|
int getKeypointsOpacity() const;
|
||||||
|
int getOdomQualityWarnThr() const;
|
||||||
|
|
||||||
bool isCloudMeshing(int index) const; // 0=map
|
bool isCloudMeshing(int index) const; // 0=map
|
||||||
bool isCloudsShown(int index) const; // 0=map, 1=odom, 2=save
|
bool isCloudsShown(int index) const; // 0=map, 1=odom, 2=save
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
|
|||||||
connect(this, SIGNAL(statsReceived(rtabmap::Statistics)), this, SLOT(processStats(rtabmap::Statistics)));
|
connect(this, SIGNAL(statsReceived(rtabmap::Statistics)), this, SLOT(processStats(rtabmap::Statistics)));
|
||||||
|
|
||||||
qRegisterMetaType<rtabmap::Image>("rtabmap::Image");
|
qRegisterMetaType<rtabmap::Image>("rtabmap::Image");
|
||||||
connect(this, SIGNAL(odometryReceived(rtabmap::Image)), this, SLOT(processOdometry(rtabmap::Image)));
|
connect(this, SIGNAL(odometryReceived(rtabmap::Image, int)), this, SLOT(processOdometry(rtabmap::Image, int)));
|
||||||
|
|
||||||
connect(this, SIGNAL(noMoreImagesReceived()), this, SLOT(stopDetection()));
|
connect(this, SIGNAL(noMoreImagesReceived()), this, SLOT(stopDetection()));
|
||||||
|
|
||||||
@@ -527,7 +527,7 @@ void MainWindow::handleEvent(UEvent* anEvent)
|
|||||||
!_processingStatistics)
|
!_processingStatistics)
|
||||||
{
|
{
|
||||||
_lastOdometryProcessed = false; // if we receive too many odometry events!
|
_lastOdometryProcessed = false; // if we receive too many odometry events!
|
||||||
emit odometryReceived(odomEvent->data());
|
emit odometryReceived(odomEvent->data(), odomEvent->quality());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(anEvent->getClassName().compare("ULogEvent") == 0)
|
else if(anEvent->getClassName().compare("ULogEvent") == 0)
|
||||||
@@ -550,7 +550,7 @@ void MainWindow::handleEvent(UEvent* anEvent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::processOdometry(const rtabmap::Image & data)
|
void MainWindow::processOdometry(const rtabmap::Image & data, int quality)
|
||||||
{
|
{
|
||||||
Transform pose = data.pose();
|
Transform pose = data.pose();
|
||||||
if(pose.isNull())
|
if(pose.isNull())
|
||||||
@@ -560,11 +560,19 @@ void MainWindow::processOdometry(const rtabmap::Image & data)
|
|||||||
|
|
||||||
pose = _lastOdomPose;
|
pose = _lastOdomPose;
|
||||||
}
|
}
|
||||||
|
else if(quality &&
|
||||||
|
_preferencesDialog->getOdomQualityWarnThr() &&
|
||||||
|
quality < _preferencesDialog->getOdomQualityWarnThr())
|
||||||
|
{
|
||||||
|
UDEBUG("odom warn, quality=%d thr=%d", quality, _preferencesDialog->getOdomQualityWarnThr());
|
||||||
|
_ui->widget_cloudViewer->setBackgroundColor(Qt::darkYellow);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UDEBUG("odom ok");
|
UDEBUG("odom ok");
|
||||||
_ui->widget_cloudViewer->setBackgroundColor(Qt::black);
|
_ui->widget_cloudViewer->setBackgroundColor(Qt::black);
|
||||||
}
|
}
|
||||||
|
_ui->statsToolBox->updateStat("/Odom inliers/", (float)data.id(), (float)quality);
|
||||||
if(!pose.isNull())
|
if(!pose.isNull())
|
||||||
{
|
{
|
||||||
_lastOdomPose = pose;
|
_lastOdomPose = pose;
|
||||||
|
|||||||
@@ -21,11 +21,12 @@
|
|||||||
namespace rtabmap {
|
namespace rtabmap {
|
||||||
|
|
||||||
|
|
||||||
OdometryViewer::OdometryViewer(int maxClouds, int decimation, float voxelSize, QWidget * parent) :
|
OdometryViewer::OdometryViewer(int maxClouds, int decimation, float voxelSize, int qualityWarningThr, QWidget * parent) :
|
||||||
CloudViewer(parent),
|
CloudViewer(parent),
|
||||||
maxClouds_(maxClouds),
|
maxClouds_(maxClouds),
|
||||||
voxelSize_(voxelSize),
|
voxelSize_(voxelSize),
|
||||||
decimation_(decimation),
|
decimation_(decimation),
|
||||||
|
qualityWarningThr_(qualityWarningThr),
|
||||||
id_(0),
|
id_(0),
|
||||||
_aSetVoxelSize(0),
|
_aSetVoxelSize(0),
|
||||||
_aSetDecimation(0),
|
_aSetDecimation(0),
|
||||||
@@ -48,11 +49,14 @@ OdometryViewer::OdometryViewer(int maxClouds, int decimation, float voxelSize, Q
|
|||||||
void OdometryViewer::processData()
|
void OdometryViewer::processData()
|
||||||
{
|
{
|
||||||
rtabmap::Image data;
|
rtabmap::Image data;
|
||||||
|
int quality;
|
||||||
dataMutex_.lock();
|
dataMutex_.lock();
|
||||||
if(buffer_.size())
|
if(data_.size())
|
||||||
{
|
{
|
||||||
data = buffer_.back();
|
data = data_.back();
|
||||||
buffer_.clear();
|
data_.clear();
|
||||||
|
quality = dataQuality_;
|
||||||
|
dataQuality_ = 0;
|
||||||
}
|
}
|
||||||
dataMutex_.unlock();
|
dataMutex_.unlock();
|
||||||
|
|
||||||
@@ -96,7 +100,14 @@ void OdometryViewer::processData()
|
|||||||
|
|
||||||
this->updateCameraPosition(data.pose());
|
this->updateCameraPosition(data.pose());
|
||||||
|
|
||||||
this->setBackgroundColor(Qt::black);
|
if(qualityWarningThr_ && quality && quality < qualityWarningThr_)
|
||||||
|
{
|
||||||
|
this->setBackgroundColor(Qt::darkYellow);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->setBackgroundColor(Qt::black);
|
||||||
|
}
|
||||||
|
|
||||||
this->render();
|
this->render();
|
||||||
}
|
}
|
||||||
@@ -114,15 +125,16 @@ void OdometryViewer::handleEvent(UEvent * event)
|
|||||||
{
|
{
|
||||||
bool empty = false;
|
bool empty = false;
|
||||||
dataMutex_.lock();
|
dataMutex_.lock();
|
||||||
if(buffer_.empty())
|
if(data_.empty())
|
||||||
{
|
{
|
||||||
buffer_.push_back(odomEvent->data());
|
data_.push_back(odomEvent->data());
|
||||||
empty= true;
|
empty= true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buffer_.back() = odomEvent->data();
|
data_.back() = odomEvent->data();
|
||||||
}
|
}
|
||||||
|
dataQuality_ = odomEvent->quality();
|
||||||
dataMutex_.unlock();
|
dataMutex_.unlock();
|
||||||
if(empty)
|
if(empty)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -394,6 +394,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
_ui->odom_iterations->setObjectName(Parameters::kOdomIterations().c_str());
|
_ui->odom_iterations->setObjectName(Parameters::kOdomIterations().c_str());
|
||||||
_ui->odom_maxDepth->setObjectName(Parameters::kOdomMaxDepth().c_str());
|
_ui->odom_maxDepth->setObjectName(Parameters::kOdomMaxDepth().c_str());
|
||||||
_ui->odom_minInliers->setObjectName(Parameters::kOdomMinInliers().c_str());
|
_ui->odom_minInliers->setObjectName(Parameters::kOdomMinInliers().c_str());
|
||||||
|
_ui->odom_ratio->setObjectName(Parameters::kOdomWordsRatio().c_str());
|
||||||
_ui->stackedWidget_odom->setCurrentIndex(_ui->odom_type->currentIndex());
|
_ui->stackedWidget_odom->setCurrentIndex(_ui->odom_type->currentIndex());
|
||||||
connect(_ui->odom_type, SIGNAL(currentIndexChanged(int)), _ui->stackedWidget_odom, SLOT(setCurrentIndex(int)));
|
connect(_ui->odom_type, SIGNAL(currentIndexChanged(int)), _ui->stackedWidget_odom, SLOT(setCurrentIndex(int)));
|
||||||
|
|
||||||
@@ -705,6 +706,7 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
|
|||||||
_ui->checkBox_imageRejectedShown->setChecked(true);
|
_ui->checkBox_imageRejectedShown->setChecked(true);
|
||||||
_ui->checkBox_imageHighestHypShown->setChecked(false);
|
_ui->checkBox_imageHighestHypShown->setChecked(false);
|
||||||
_ui->horizontalSlider_keypointsOpacity->setSliderPosition(20);
|
_ui->horizontalSlider_keypointsOpacity->setSliderPosition(20);
|
||||||
|
_ui->spinBox_odomQualityWarnThr->setValue(50);
|
||||||
}
|
}
|
||||||
else if(groupBox->objectName() == _ui->groupBox_cloudRendering1->objectName())
|
else if(groupBox->objectName() == _ui->groupBox_cloudRendering1->objectName())
|
||||||
{
|
{
|
||||||
@@ -718,7 +720,7 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
|
|||||||
|
|
||||||
if(i<2)
|
if(i<2)
|
||||||
{
|
{
|
||||||
_3dRenderingOpacity[i]->setValue(i==0?0.6:1.0);
|
_3dRenderingOpacity[i]->setValue(1.0);
|
||||||
_3dRenderingPtSize[i]->setValue(i==0?1:2);
|
_3dRenderingPtSize[i]->setValue(i==0?1:2);
|
||||||
_3dRenderingOpacityScan[i]->setValue(1.0);
|
_3dRenderingOpacityScan[i]->setValue(1.0);
|
||||||
_3dRenderingPtSizeScan[i]->setValue(1);
|
_3dRenderingPtSizeScan[i]->setValue(1);
|
||||||
@@ -2330,6 +2332,10 @@ int PreferencesDialog::getKeypointsOpacity() const
|
|||||||
{
|
{
|
||||||
return _ui->horizontalSlider_keypointsOpacity->value();
|
return _ui->horizontalSlider_keypointsOpacity->value();
|
||||||
}
|
}
|
||||||
|
int PreferencesDialog::getOdomQualityWarnThr() const
|
||||||
|
{
|
||||||
|
return _ui->spinBox_odomQualityWarnThr->value();
|
||||||
|
}
|
||||||
|
|
||||||
bool PreferencesDialog::isCloudsShown(int index) const
|
bool PreferencesDialog::isCloudsShown(int index) const
|
||||||
{
|
{
|
||||||
@@ -2767,7 +2773,7 @@ void PreferencesDialog::testOdometry(OdomType type)
|
|||||||
window->setMinimumHeight(600);
|
window->setMinimumHeight(600);
|
||||||
connect( window, SIGNAL(destroyed(QObject*)), this, SLOT(cleanOdometryTest()) );
|
connect( window, SIGNAL(destroyed(QObject*)), this, SLOT(cleanOdometryTest()) );
|
||||||
|
|
||||||
OdometryViewer * odomViewer = new OdometryViewer(10, 2, 0.0, window);
|
OdometryViewer * odomViewer = new OdometryViewer(10, 2, 0.0, this->getOdomQualityWarnThr(), window);
|
||||||
|
|
||||||
QVBoxLayout *layout = new QVBoxLayout();
|
QVBoxLayout *layout = new QVBoxLayout();
|
||||||
layout->addWidget(odomViewer);
|
layout->addWidget(odomViewer);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1027</width>
|
<width>1027</width>
|
||||||
<height>494</height>
|
<height>659</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@@ -64,8 +64,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>724</width>
|
<width>729</width>
|
||||||
<height>1076</height>
|
<height>823</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||||
@@ -86,7 +86,7 @@
|
|||||||
<enum>QFrame::Raised</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>15</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="page_22">
|
<widget class="QWidget" name="page_22">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_29">
|
<layout class="QVBoxLayout" name="verticalLayout_29">
|
||||||
@@ -143,12 +143,9 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_5">
|
<widget class="QGroupBox" name="groupBox_5">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Image view</string>
|
<string>Loop closure detection view</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QFormLayout" name="formLayout_12">
|
<layout class="QFormLayout" name="formLayout_12">
|
||||||
<property name="fieldGrowthPolicy">
|
|
||||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
|
||||||
</property>
|
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QCheckBox" name="checkBox_imageFlipped">
|
<widget class="QCheckBox" name="checkBox_imageFlipped">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -235,7 +232,7 @@
|
|||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLabel" name="label_70">
|
<widget class="QLabel" name="label_70">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Vertical layout used for the loop closure detection window.</string>
|
<string>Vertical layout.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
@@ -255,6 +252,36 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>3D Map view</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout_23">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QSpinBox" name="spinBox_odomQualityWarnThr">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>9999</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>50</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLabel" name="label_86">
|
||||||
|
<property name="text">
|
||||||
|
<string>Odometry warning theshold:
|
||||||
|
Show a yellow background when the number of odometry inliers goes under this threshold. If 0, it is ignored. You can see the current odometry inliers count under Statistics view -> General -> Odom inliers.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@@ -598,7 +625,7 @@ High-res view</string>
|
|||||||
<double>0.100000000000000</double>
|
<double>0.100000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
<property name="value">
|
<property name="value">
|
||||||
<double>0.600000000000000</double>
|
<double>1.000000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -4963,7 +4990,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="1">
|
<item row="10" column="1">
|
||||||
<widget class="QLabel" name="label_104">
|
<widget class="QLabel" name="label_104">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Max feature depth. For ICP, it is the max cloud depth.</string>
|
<string>Max feature depth. For ICP, it is the max cloud depth.</string>
|
||||||
@@ -4973,7 +5000,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="0">
|
<item row="10" column="0">
|
||||||
<widget class="QDoubleSpinBox" name="odom_maxDepth">
|
<widget class="QDoubleSpinBox" name="odom_maxDepth">
|
||||||
<property name="suffix">
|
<property name="suffix">
|
||||||
<string> m</string>
|
<string> m</string>
|
||||||
@@ -5009,6 +5036,38 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="9" column="1">
|
||||||
|
<widget class="QLabel" name="label_90">
|
||||||
|
<property name="text">
|
||||||
|
<string>Minmum ratio of keypoints between the current image and the last image to compute odometry.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="odom_ratio">
|
||||||
|
<property name="suffix">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.010000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.500000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ void showUsage()
|
|||||||
" -min # Minimum inliers to accept the transform (default 20)\n"
|
" -min # Minimum inliers to accept the transform (default 20)\n"
|
||||||
" -depth #.# Maximum features depth (default 5.0 m)\n"
|
" -depth #.# Maximum features depth (default 5.0 m)\n"
|
||||||
" -i # RANSAC/ICP iterations (default 100)\n"
|
" -i # RANSAC/ICP iterations (default 100)\n"
|
||||||
|
" -r #.# Words ratio (default 0.5)\n"
|
||||||
" -lu # Linear update (default 0.0 m)\n"
|
" -lu # Linear update (default 0.0 m)\n"
|
||||||
" -au # Angular update (default 0.0 radian)\n"
|
" -au # Angular update (default 0.0 radian)\n"
|
||||||
" -reset # Reset countdown (default 0 = disabled)\n"
|
" -reset # Reset countdown (default 0 = disabled)\n"
|
||||||
@@ -63,6 +64,7 @@ int main (int argc, char * argv[])
|
|||||||
float distance = 0.005;
|
float distance = 0.005;
|
||||||
int maxWords = 0;
|
int maxWords = 0;
|
||||||
int minInliers = 20;
|
int minInliers = 20;
|
||||||
|
float wordsRatio = 0.5;
|
||||||
float maxDepth = 5.0f;
|
float maxDepth = 5.0f;
|
||||||
int iterations = 100;
|
int iterations = 100;
|
||||||
float linearUpdate = 0.0f;
|
float linearUpdate = 0.0f;
|
||||||
@@ -252,6 +254,23 @@ int main (int argc, char * argv[])
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if(strcmp(argv[i], "-r") == 0)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
if(i < argc)
|
||||||
|
{
|
||||||
|
wordsRatio = std::atof(argv[i]);
|
||||||
|
if(wordsRatio < 0.0f || wordsRatio > 1.0f)
|
||||||
|
{
|
||||||
|
showUsage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
showUsage();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if(strcmp(argv[i], "-lu") == 0)
|
if(strcmp(argv[i], "-lu") == 0)
|
||||||
{
|
{
|
||||||
++i;
|
++i;
|
||||||
@@ -446,6 +465,7 @@ int main (int argc, char * argv[])
|
|||||||
UINFO("Max features = %d", maxWords);
|
UINFO("Max features = %d", maxWords);
|
||||||
UINFO("Min inliers = %d", minInliers);
|
UINFO("Min inliers = %d", minInliers);
|
||||||
UINFO("RANSAC/ICP iterations = %d", iterations);
|
UINFO("RANSAC/ICP iterations = %d", iterations);
|
||||||
|
UINFO("Words ratio = %f", wordsRatio);
|
||||||
UINFO("Max depth = %f", maxDepth);
|
UINFO("Max depth = %f", maxDepth);
|
||||||
UINFO("Linear update = %f", linearUpdate);
|
UINFO("Linear update = %f", linearUpdate);
|
||||||
UINFO("Angular update = %f", angularUpdate);
|
UINFO("Angular update = %f", angularUpdate);
|
||||||
@@ -470,6 +490,7 @@ int main (int argc, char * argv[])
|
|||||||
maxWords,
|
maxWords,
|
||||||
minInliers,
|
minInliers,
|
||||||
iterations,
|
iterations,
|
||||||
|
wordsRatio,
|
||||||
maxDepth,
|
maxDepth,
|
||||||
linearUpdate,
|
linearUpdate,
|
||||||
angularUpdate,
|
angularUpdate,
|
||||||
@@ -482,6 +503,7 @@ int main (int argc, char * argv[])
|
|||||||
maxWords,
|
maxWords,
|
||||||
minInliers,
|
minInliers,
|
||||||
iterations,
|
iterations,
|
||||||
|
wordsRatio,
|
||||||
maxDepth,
|
maxDepth,
|
||||||
linearUpdate,
|
linearUpdate,
|
||||||
angularUpdate,
|
angularUpdate,
|
||||||
|
|||||||
Reference in New Issue
Block a user