Refactoring Registration: added RegistrationInfo class, pipeline registration. Camera source: create laser scan from depth image. Removed OdometryICP as the same behavior can be achieved with OdometryF2F and "Reg/Strategy" = 1 (ICP) or 2 (Vis+ICP).

This commit is contained in:
matlabbe
2016-01-06 17:26:55 -05:00
parent 1c66ad1db2
commit 28d9bbb85d
35 changed files with 1209 additions and 1362 deletions
+3 -3
View File
@@ -48,7 +48,7 @@ public:
UEvent(kCodeData), UEvent(kCodeData),
data_(image, seq, stamp) data_(image, seq, stamp)
{ {
cameraInfo_.cameraName_ = cameraName; cameraInfo_.cameraName = cameraName;
} }
CameraEvent() : CameraEvent() :
@@ -66,7 +66,7 @@ public:
UEvent(kCodeData), UEvent(kCodeData),
data_(data) data_(data)
{ {
cameraInfo_.cameraName_ = cameraName; cameraInfo_.cameraName = cameraName;
} }
CameraEvent(const SensorData & data, const CameraInfo & cameraInfo) : CameraEvent(const SensorData & data, const CameraInfo & cameraInfo) :
UEvent(kCodeData), UEvent(kCodeData),
@@ -77,7 +77,7 @@ public:
// Image or descriptors // Image or descriptors
const SensorData & data() const {return data_;} const SensorData & data() const {return data_;}
const std::string & cameraName() const {return cameraInfo_.cameraName_;} const std::string & cameraName() const {return cameraInfo_.cameraName;}
const CameraInfo & info() const {return cameraInfo_;} const CameraInfo & info() const {return cameraInfo_;}
virtual ~CameraEvent() {} virtual ~CameraEvent() {}
+12 -10
View File
@@ -37,20 +37,22 @@ class CameraInfo
public: public:
CameraInfo() : CameraInfo() :
cameraName_(""), cameraName(""),
id_(0), id(0),
timeCapture_(0.0), timeCapture(0.0f),
timeDisparity_(0.0), timeDisparity(0.0f),
timeMirroring_(0.0) timeMirroring(0.0f),
timeScanFromDepth(0.0f)
{ {
} }
virtual ~CameraInfo() {} virtual ~CameraInfo() {}
std::string cameraName_; std::string cameraName;
int id_; int id;
float timeCapture_; float timeCapture;
float timeDisparity_; float timeDisparity;
float timeMirroring_; float timeMirroring;
float timeScanFromDepth;
}; };
} // namespace rtabmap } // namespace rtabmap
@@ -55,6 +55,8 @@ public:
void setMirroringEnabled(bool enabled) {_mirroring = enabled;} void setMirroringEnabled(bool enabled) {_mirroring = enabled;}
void setColorOnly(bool colorOnly) {_colorOnly = colorOnly;} void setColorOnly(bool colorOnly) {_colorOnly = colorOnly;}
void setStereoToDepth(bool enabled) {_stereoToDepth = enabled;} void setStereoToDepth(bool enabled) {_stereoToDepth = enabled;}
void setScanFromDepth(bool enabled, int decimation=4, float maxDepth=4.0f)
{_scanFromDepth = enabled; _scanDecimation=decimation; _scanMaxDepth = maxDepth;}
//getters //getters
bool isPaused() const {return !this->isRunning();} bool isPaused() const {return !this->isRunning();}
@@ -72,6 +74,9 @@ private:
bool _mirroring; bool _mirroring;
bool _colorOnly; bool _colorOnly;
bool _stereoToDepth; bool _stereoToDepth;
bool _scanFromDepth;
int _scanDecimation;
float _scanMaxDepth;
StereoDense * _stereoDense; StereoDense * _stereoDense;
}; };
+6 -7
View File
@@ -51,7 +51,8 @@ class VWDictionary;
class VisualWord; class VisualWord;
class Feature2D; class Feature2D;
class Statistics; class Statistics;
class RegistrationVis; class Registration;
class RegistrationInfo;
class RegistrationIcp; class RegistrationIcp;
class Stereo; class Stereo;
@@ -178,15 +179,13 @@ public:
std::multimap<int, Link> & links, std::multimap<int, Link> & links,
bool lookInDatabase = false); bool lookInDatabase = false);
Transform computeVisualTransform(int fromId, int toId, std::string * rejectedMsg = 0, int * inliers = 0, float * variance = 0); Transform computeTransform(int fromId, int toId, RegistrationInfo * info = 0);
Transform computeIcpTransform(int fromId, int toId, Transform guess, std::string * rejectedMsg = 0, int * correspondences = 0, float * variance = 0, float * correspondencesRatio = 0); Transform computeIcpTransform(int fromId, int toId, Transform guess, RegistrationInfo * info = 0);
Transform computeIcpTransformMulti( Transform computeIcpTransformMulti(
int newId, int newId,
int oldId, int oldId,
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
std::string * rejectedMsg = 0, RegistrationInfo * info = 0);
int * inliers = 0,
float * variance = 0);
private: private:
void preUpdate(); void preUpdate();
@@ -264,7 +263,7 @@ private:
bool _tfIdfLikelihoodUsed; bool _tfIdfLikelihoodUsed;
bool _parallelized; bool _parallelized;
RegistrationVis * _registrationVis; Registration * _registrationPipeline;
RegistrationIcp * _registrationIcp; RegistrationIcp * _registrationIcp;
}; };
+1 -1
View File
@@ -50,7 +50,7 @@ public:
public: public:
static Odometry * create(const ParametersMap & parameters); static Odometry * create(const ParametersMap & parameters);
static Odometry * create(Type & type, const ParametersMap & parameters); static Odometry * create(Type & type, const ParametersMap & parameters = ParametersMap());
public: public:
virtual ~Odometry(); virtual ~Odometry();
+4 -2
View File
@@ -29,10 +29,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define ODOMETRYF2F_H_ #define ODOMETRYF2F_H_
#include <rtabmap/core/Odometry.h> #include <rtabmap/core/Odometry.h>
#include <rtabmap/core/RegistrationVis.h> #include <rtabmap/core/Signature.h>
namespace rtabmap { namespace rtabmap {
class Registration;
class RTABMAP_EXP OdometryF2F : public Odometry class RTABMAP_EXP OdometryF2F : public Odometry
{ {
public: public:
@@ -51,7 +53,7 @@ private:
int keyFrameThr_; int keyFrameThr_;
bool guessFromMotion_; bool guessFromMotion_;
RegistrationVis registration_; Registration * registrationPipeline_;
Signature refFrame_; Signature refFrame_;
Transform motionSinceLastKeyFrame_; Transform motionSinceLastKeyFrame_;
}; };
@@ -1,68 +0,0 @@
/*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ODOMETRYICP_H_
#define ODOMETRYICP_H_
#include <rtabmap/core/Odometry.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
namespace rtabmap {
class RTABMAP_EXP OdometryICP : public Odometry
{
public:
OdometryICP(int decimation = 4,
float voxelSize = 0.005f,
int samples = 0,
float maxCorrespondenceDistance = 0.05f,
int maxIterations = 30,
float correspondenceRatio = 0.7f,
bool pointToPlane = true,
const ParametersMap & odometryParameter = rtabmap::ParametersMap());
virtual void reset(const Transform & initialPose = Transform::getIdentity());
private:
virtual Transform computeTransform(const SensorData & image, OdometryInfo * info = 0);
private:
int _decimation;
float _voxelSize;
float _samples;
float _maxCorrespondenceDistance;
int _maxIterations;
float _correspondenceRatio;
bool _pointToPlane;
pcl::PointCloud<pcl::PointNormal>::Ptr _previousCloudNormal; // for point ot plane
pcl::PointCloud<pcl::PointXYZ>::Ptr _previousCloud; // for point to point
};
}
#endif /* ODOMETRYICP_H_ */
+2 -3
View File
@@ -311,7 +311,6 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(RGBD, LocalImmunizationRatio, float, 0.25, "Ratio of working memory for which local nodes are immunized from transfer."); RTABMAP_PARAM(RGBD, LocalImmunizationRatio, float, 0.25, "Ratio of working memory for which local nodes are immunized from transfer.");
RTABMAP_PARAM(RGBD, ScanMatchingIdsSavedInLinks, bool, true, "Save scan matching IDs in link's user data."); RTABMAP_PARAM(RGBD, ScanMatchingIdsSavedInLinks, bool, true, "Save scan matching IDs in link's user data.");
RTABMAP_PARAM(RGBD, NeighborLinkRefining, bool, false, "When a new node is added to the graph, the transformation of its neighbor link to the previous node is refined using ICP (laser scans required!)."); RTABMAP_PARAM(RGBD, NeighborLinkRefining, bool, false, "When a new node is added to the graph, the transformation of its neighbor link to the previous node is refined using ICP (laser scans required!).");
RTABMAP_PARAM(RGBD, LoopClosureLinkRefining, bool, false, "If the estimated loop closure transformation is refined using ICP (laser scans required!).");
RTABMAP_PARAM(RGBD, LoopClosureReextractFeatures, bool, true, "Extract features even if there are some already in the nodes."); RTABMAP_PARAM(RGBD, LoopClosureReextractFeatures, bool, true, "Extract features even if there are some already in the nodes.");
// Local/Proximity loop closure detection // Local/Proximity loop closure detection
@@ -361,6 +360,8 @@ class RTABMAP_EXP Parameters
// Common registration parameters // Common registration parameters
RTABMAP_PARAM(Reg, VarianceFromInliersCount, bool, false, "Set variance as the inverse of the number of inliers. Otherwise, the variance is computed as the average 3D position error of the inliers."); RTABMAP_PARAM(Reg, VarianceFromInliersCount, bool, false, "Set variance as the inverse of the number of inliers. Otherwise, the variance is computed as the average 3D position error of the inliers.");
RTABMAP_PARAM(Reg, Strategy, int, 0, "0=Vis, 1=Icp, 2=VisIcp");
RTABMAP_PARAM(Reg, Force3DoF, bool, false, "Force 3 degrees-of-freedom transform (3Dof: x,y and yaw). Parameters z, roll and pitch will be set to 0.");
// Visual registration parameters // Visual registration parameters
RTABMAP_PARAM(Vis, EstimationType, int, 0, "Motion estimation approach: 0:3D->3D, 1:3D->2D (PnP), 2:2D->2D (Epipolar Geometry)"); RTABMAP_PARAM(Vis, EstimationType, int, 0, "Motion estimation approach: 0:3D->3D, 1:3D->2D (PnP), 2:2D->2D (Epipolar Geometry)");
@@ -373,7 +374,6 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(Vis, EpipolarGeometryVar, float, 0.02, "[Vis/EstimationType = 2] Epipolar geometry maximum variance to accept the transformation."); RTABMAP_PARAM(Vis, EpipolarGeometryVar, float, 0.02, "[Vis/EstimationType = 2] Epipolar geometry maximum variance to accept the transformation.");
RTABMAP_PARAM(Vis, MinInliers, int, 10, "Minimum feature correspondences to compute/accept the transformation."); RTABMAP_PARAM(Vis, MinInliers, int, 10, "Minimum feature correspondences to compute/accept the transformation.");
RTABMAP_PARAM(Vis, Iterations, int, 100, "Maximum iterations to compute the transform."); RTABMAP_PARAM(Vis, Iterations, int, 100, "Maximum iterations to compute the transform.");
RTABMAP_PARAM(Vis, Force2D, bool, false, "Force 2D transform (3Dof: x,y and yaw). Parameters z, roll and pitch will be set to 0.");
RTABMAP_PARAM(Vis, FeatureType, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK."); RTABMAP_PARAM(Vis, FeatureType, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK.");
RTABMAP_PARAM(Vis, MaxFeatures, int, 1000, "0 no limits."); RTABMAP_PARAM(Vis, MaxFeatures, int, 1000, "0 no limits.");
RTABMAP_PARAM(Vis, MaxDepth, float, 0.0, "Max depth of the features (0 means no limit)."); RTABMAP_PARAM(Vis, MaxDepth, float, 0.0, "Max depth of the features (0 means no limit).");
@@ -394,7 +394,6 @@ class RTABMAP_EXP Parameters
// ICP registration parameters // ICP registration parameters
RTABMAP_PARAM(Icp, MaxTranslation, float, 0.2, "Maximum ICP translation correction accepted (m)."); RTABMAP_PARAM(Icp, MaxTranslation, float, 0.2, "Maximum ICP translation correction accepted (m).");
RTABMAP_PARAM(Icp, MaxRotation, float, 0.78, "Maximum ICP rotation correction accepted (rad)."); RTABMAP_PARAM(Icp, MaxRotation, float, 0.78, "Maximum ICP rotation correction accepted (rad).");
RTABMAP_PARAM(Icp, 2D, bool, true, "If 2D ICP is done (only 3Dof -> x,y,yaw).");
RTABMAP_PARAM(Icp, VoxelSize, float, 0.025, "Uniform sampling voxel size (0=disabled)."); RTABMAP_PARAM(Icp, VoxelSize, float, 0.025, "Uniform sampling voxel size (0=disabled).");
RTABMAP_PARAM(Icp, DownsamplingStep, int, 1, "Downsampling step size (1=no sampling). This is done before uniform sampling."); RTABMAP_PARAM(Icp, DownsamplingStep, int, 1, "Downsampling step size (1=no sampling). This is done before uniform sampling.");
RTABMAP_PARAM(Icp, MaxCorrespondenceDistance, float, 0.05, "Max distance for point correspondences."); RTABMAP_PARAM(Icp, MaxCorrespondenceDistance, float, 0.05, "Max distance for point correspondences.");
+51 -26
View File
@@ -32,50 +32,75 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/core/Parameters.h> #include <rtabmap/core/Parameters.h>
#include <rtabmap/core/Signature.h> #include <rtabmap/core/Signature.h>
#include <rtabmap/core/RegistrationInfo.h>
namespace rtabmap { namespace rtabmap {
class RTABMAP_EXP Registration class RTABMAP_EXP Registration
{ {
public: public:
virtual ~Registration() {} enum Type {
virtual void parseParameters(const ParametersMap & parameters) kTypeUndef = -1,
{ kTypeVis = 0,
Parameters::parse(parameters, Parameters::kRegVarianceFromInliersCount(), _varianceFromInliersCount); kTypeIcp = 1,
} kTypeVisIcp = 2
};
public:
static Registration * create(const ParametersMap & parameters);
static Registration * create(Type & type, const ParametersMap & parameters = ParametersMap());
public:
virtual ~Registration();
virtual void parseParameters(const ParametersMap & parameters);
bool isImageRequired() const;
bool isScanRequired() const;
bool isUserDataRequired() const;
bool varianceFromInliersCount() const {return varianceFromInliersCount_;}
bool force3DoF() const {return force3DoF_;}
// take ownership!
void setChildRegistration(Registration * child);
Transform computeTransformation( Transform computeTransformation(
const Signature & from, const Signature & from,
const Signature & to, const Signature & to,
Transform guess = Transform::getIdentity(), Transform guess = Transform::getIdentity(),
std::string * rejectedMsg = 0, RegistrationInfo * info = 0) const;
std::vector<int> * inliersOut = 0, Transform computeTransformation(
float * varianceOut = 0, const SensorData & from,
float * inliersRatioOut = 0) const const SensorData & to,
{ Transform SensorData = Transform::getIdentity(),
Signature fromCopy(from); RegistrationInfo * info = 0) const;
Signature toCopy(to);
return computeTransformationMod(fromCopy, toCopy, guess, rejectedMsg, inliersOut, varianceOut, inliersRatioOut);
}
virtual Transform computeTransformationMod( Transform computeTransformationMod(
Signature & from, Signature & from,
Signature & to, Signature & to,
Transform guess = Transform::getIdentity(), Transform guess = Transform::getIdentity(),
std::string * rejectedMsg = 0, RegistrationInfo * info = 0) const;
std::vector<int> * inliersOut = 0,
float * varianceOut = 0,
float * inliersRatioOut = 0) const = 0;
protected: protected:
Registration(const ParametersMap & parameters = ParametersMap()) : // take ownership of child
_varianceFromInliersCount(Parameters::defaultRegVarianceFromInliersCount()) Registration(const ParametersMap & parameters = ParametersMap(), Registration * child = 0);
{
this->parseParameters(parameters);
}
protected: // It is safe to modify the signatures in the implementation, if so, the
bool _varianceFromInliersCount; // child registration will use these modifications.
virtual Transform computeTransformationImpl(
Signature & from,
Signature & to,
Transform guess,
RegistrationInfo & info) const = 0;
virtual bool isImageRequiredImpl() const = 0;
virtual bool isScanRequiredImpl() const = 0;
virtual bool isUserDataRequiredImpl() const = 0;
private:
bool varianceFromInliersCount_;
bool force3DoF_;
Registration * child_;
}; };
+9 -17
View File
@@ -39,33 +39,25 @@ namespace rtabmap {
class RTABMAP_EXP RegistrationIcp : public Registration class RTABMAP_EXP RegistrationIcp : public Registration
{ {
public: public:
RegistrationIcp(const ParametersMap & parameters = ParametersMap()); // take ownership of child
RegistrationIcp(const ParametersMap & parameters = ParametersMap(), Registration * child = 0);
virtual ~RegistrationIcp() {} virtual ~RegistrationIcp() {}
virtual void parseParameters(const ParametersMap & parameters); virtual void parseParameters(const ParametersMap & parameters);
virtual Transform computeTransformationMod( protected:
virtual Transform computeTransformationImpl(
Signature & from, Signature & from,
Signature & to, Signature & to,
Transform guess = Transform::getIdentity(), Transform guess,
std::string * rejectedMsg = 0, RegistrationInfo & info) const;
std::vector<int> * inliersOut = 0, virtual bool isImageRequiredImpl() const {return false;}
float * varianceOut = 0, virtual bool isScanRequiredImpl() const {return true;}
float * inliersRatioOut = 0) const; virtual bool isUserDataRequiredImpl() const {return false;}
Transform computeTransformation(
const SensorData & from,
const SensorData & to,
Transform guess = Transform::getIdentity(),
std::string * rejectedMsg = 0,
std::vector<int> * inliersOut = 0,
float * varianceOut = 0,
float * inliersRatioOut = 0) const;
private: private:
float _maxTranslation; float _maxTranslation;
float _maxRotation; float _maxRotation;
bool _icp2D;
float _voxelSize; float _voxelSize;
int _downsamplingStep; int _downsamplingStep;
float _maxCorrespondenceDistance; float _maxCorrespondenceDistance;
@@ -0,0 +1,33 @@
/*
* RegistrationInfo.h
*
* Created on: Jan 5, 2016
* Author: mathieu
*/
#ifndef REGISTRATIONINFO_H_
#define REGISTRATIONINFO_H_
namespace rtabmap {
class RegistrationInfo
{
public:
RegistrationInfo() :
variance(0),
inliers(0),
inliersRatio(0)
{
}
float variance;
int inliers;
float inliersRatio;
std::vector<int> inliersIndexes_;
std::string rejectedMsg_;
};
}
#endif /* REGISTRATIONINFO_H_ */
+13 -12
View File
@@ -39,31 +39,32 @@ namespace rtabmap {
class RTABMAP_EXP RegistrationVis : public Registration class RTABMAP_EXP RegistrationVis : public Registration
{ {
public: public:
RegistrationVis(const ParametersMap & parameters = ParametersMap()); // take ownership of child
RegistrationVis(const ParametersMap & parameters = ParametersMap(), Registration * child = 0);
virtual ~RegistrationVis(); virtual ~RegistrationVis();
virtual void parseParameters(const ParametersMap & parameters); virtual void parseParameters(const ParametersMap & parameters);
virtual Transform computeTransformationMod(
Signature & from,
Signature & to,
Transform guess = Transform::getIdentity(), // guess is ignored for RegistrationVis
std::string * rejectedMsg = 0,
std::vector<int> * inliersOut = 0,
float * varianceOut = 0,
float * inliersRatioOut = 0) const;
float getBowInlierDistance() const {return _inlierDistance;} float getBowInlierDistance() const {return _inlierDistance;}
int getBowIterations() const {return _iterations;} int getBowIterations() const {return _iterations;}
int getBowMinInliers() const {return _minInliers;} int getBowMinInliers() const {return _minInliers;}
bool getBowForce2D() const {return _force2D;}
protected:
virtual Transform computeTransformationImpl(
Signature & from,
Signature & to,
Transform guess,
RegistrationInfo & info) const;
virtual bool isImageRequiredImpl() const {return true;}
virtual bool isScanRequiredImpl() const {return false;}
virtual bool isUserDataRequiredImpl() const {return false;}
private: private:
int _minInliers; int _minInliers;
float _inlierDistance; float _inlierDistance;
int _iterations; int _iterations;
int _refineIterations; int _refineIterations;
bool _force2D;
float _epipolarGeometryVar; float _epipolarGeometryVar;
int _estimationType; int _estimationType;
bool _forwardEstimateOnly; bool _forwardEstimateOnly;
-1
View File
@@ -184,7 +184,6 @@ private:
float _rgbdLinearUpdate; float _rgbdLinearUpdate;
float _rgbdAngularUpdate; float _rgbdAngularUpdate;
float _newMapOdomChangeDistance; float _newMapOdomChangeDistance;
bool _loopClosureRefining;
bool _neighborLinkRefining; bool _neighborLinkRefining;
bool _proximityByTime; bool _proximityByTime;
bool _proximityBySpace; bool _proximityBySpace;
+1
View File
@@ -97,6 +97,7 @@ public:
Transform inverse() const; Transform inverse() const;
Transform rotation() const; Transform rotation() const;
Transform translation() const; Transform translation() const;
Transform to3DoF() const;
void getTranslationAndEulerAngles(float & x, float & y, float & z, float & roll, float & pitch, float & yaw) const; void getTranslationAndEulerAngles(float & x, float & y, float & z, float & roll, float & pitch, float & yaw) const;
void getEulerAngles(float & roll, float & pitch, float & yaw) const; void getEulerAngles(float & roll, float & pitch, float & yaw) const;
+1 -1
View File
@@ -50,6 +50,7 @@ SET(SRC_FILES
OptimizerGTSAM.cpp OptimizerGTSAM.cpp
OptimizerCVSBA.cpp OptimizerCVSBA.cpp
Registration.cpp
RegistrationIcp.cpp RegistrationIcp.cpp
RegistrationVis.cpp RegistrationVis.cpp
@@ -57,7 +58,6 @@ SET(SRC_FILES
OdometryThread.cpp OdometryThread.cpp
OdometryLocalMap.cpp OdometryLocalMap.cpp
OdometryMono.cpp OdometryMono.cpp
OdometryICP.cpp
OdometryF2F.cpp OdometryF2F.cpp
Stereo.cpp Stereo.cpp
+2 -2
View File
@@ -102,8 +102,8 @@ SensorData Camera::takeImage(CameraInfo * info)
} }
if(info) if(info)
{ {
info->id_ = data.id(); info->id = data.id();
info->timeCapture_ = captureTime; info->timeCapture = captureTime;
} }
return data; return data;
} }
+28 -4
View File
@@ -45,6 +45,9 @@ CameraThread::CameraThread(Camera * camera, const ParametersMap & parameters) :
_mirroring(false), _mirroring(false),
_colorOnly(false), _colorOnly(false),
_stereoToDepth(false), _stereoToDepth(false),
_scanFromDepth(false),
_scanDecimation(4),
_scanMaxDepth(4.0f),
_stereoDense(new StereoBM(parameters)) _stereoDense(new StereoBM(parameters))
{ {
UASSERT(_camera != 0); UASSERT(_camera != 0);
@@ -103,7 +106,7 @@ void CameraThread::mainLoop()
cv::flip(data.depthRaw(), tmpDepth, 1); cv::flip(data.depthRaw(), tmpDepth, 1);
data.setDepthOrRightRaw(tmpDepth); data.setDepthOrRightRaw(tmpDepth);
} }
info.timeMirroring_ = timer.ticks(); info.timeMirroring = timer.ticks();
} }
if(_stereoToDepth && data.stereoCameraModel().isValid() && !data.rightRaw().empty()) if(_stereoToDepth && data.stereoCameraModel().isValid() && !data.rightRaw().empty())
{ {
@@ -115,10 +118,31 @@ void CameraThread::mainLoop()
data.setCameraModel(data.stereoCameraModel().left()); data.setCameraModel(data.stereoCameraModel().left());
data.setDepthOrRightRaw(depth); data.setDepthOrRightRaw(depth);
data.setStereoCameraModel(StereoCameraModel()); data.setStereoCameraModel(StereoCameraModel());
info.timeDisparity_ = timer.ticks(); info.timeDisparity = timer.ticks();
UINFO("Computing disparity = %f s", info.timeDisparity_); UINFO("Computing disparity = %f s", info.timeDisparity);
} }
info.cameraName_ = _camera->getSerial(); if(_scanFromDepth &&
data.cameraModels().size() &&
data.cameraModels().at(0).isValid() &&
!data.depthRaw().empty())
{
if(data.laserScanRaw().empty())
{
UASSERT(_scanDecimation >= 1);
UTimer timer;
cv::Mat scan = util3d::laserScanFromPointCloud(*util3d::cloudFromSensorData(data, _scanDecimation, _scanMaxDepth));
data.setLaserScanRaw(scan, (data.depthRaw().rows/_scanDecimation)*(data.depthRaw().cols/_scanDecimation), _scanMaxDepth);
info.timeScanFromDepth = timer.ticks();
UINFO("Computing scan from depth = %f s", info.timeScanFromDepth);
}
else
{
UWARN("Option to create laser scan from depth image is enabled, but "
"there is already a laser scan in the captured sensor data. Scan from "
"depth will not be created.");
}
}
info.cameraName = _camera->getSerial();
this->post(new CameraEvent(data, info)); this->post(new CameraEvent(data, info));
} }
else if(!this->isKilled()) else if(!this->isKilled())
+61 -46
View File
@@ -41,6 +41,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/core/VisualWord.h" #include "rtabmap/core/VisualWord.h"
#include "rtabmap/core/Features2d.h" #include "rtabmap/core/Features2d.h"
#include "rtabmap/core/RegistrationIcp.h" #include "rtabmap/core/RegistrationIcp.h"
#include "rtabmap/core/Registration.h"
#include "rtabmap/core/RegistrationVis.h" #include "rtabmap/core/RegistrationVis.h"
#include "rtabmap/core/DBDriver.h" #include "rtabmap/core/DBDriver.h"
#include "rtabmap/core/util3d_features.h" #include "rtabmap/core/util3d_features.h"
@@ -102,7 +103,7 @@ Memory::Memory(const ParametersMap & parameters) :
{ {
_feature2D = Feature2D::create(parameters); _feature2D = Feature2D::create(parameters);
_vwd = new VWDictionary(parameters); _vwd = new VWDictionary(parameters);
_registrationVis = new RegistrationVis(parameters); _registrationPipeline = Registration::create(parameters);
_registrationIcp = new RegistrationIcp(parameters); _registrationIcp = new RegistrationIcp(parameters);
this->parseParameters(parameters); this->parseParameters(parameters);
} }
@@ -365,9 +366,9 @@ Memory::~Memory()
{ {
delete _vwd; delete _vwd;
} }
if(_registrationVis) if(_registrationPipeline)
{ {
delete _registrationVis; delete _registrationPipeline;
} }
if(_registrationIcp) if(_registrationIcp)
{ {
@@ -447,10 +448,27 @@ void Memory::parseParameters(const ParametersMap & parameters)
_feature2D->parseParameters(parameters); _feature2D->parseParameters(parameters);
} }
if(_registrationVis) Registration::Type regStrategy = Registration::kTypeUndef;
if((iter=parameters.find(Parameters::kRegStrategy())) != parameters.end())
{ {
_registrationVis->parseParameters(parameters); regStrategy = (Registration::Type)std::atoi((*iter).second.c_str());
} }
if(regStrategy!=Registration::kTypeUndef)
{
UDEBUG("new registration strategy %d", int(regStrategy));
if(_registrationPipeline)
{
delete _registrationPipeline;
_registrationPipeline = 0;
}
_registrationPipeline = Registration::create(regStrategy, parameters_);
}
else if(_registrationPipeline)
{
_registrationPipeline->parseParameters(parameters);
}
if(_registrationIcp) if(_registrationIcp)
{ {
_registrationIcp->parseParameters(parameters); _registrationIcp->parseParameters(parameters);
@@ -2012,12 +2030,10 @@ void Memory::removeLink(int oldId, int newId)
} }
// compute transform fromId -> toId // compute transform fromId -> toId
Transform Memory::computeVisualTransform( Transform Memory::computeTransform(
int fromId, int fromId,
int toId, int toId,
std::string * rejectedMsg, RegistrationInfo * info)
int * inliers,
float * variance)
{ {
const Signature * fromS = this->getSignature(fromId); const Signature * fromS = this->getSignature(fromId);
const Signature * toS = this->getSignature(toId); const Signature * toS = this->getSignature(toId);
@@ -2026,37 +2042,49 @@ Transform Memory::computeVisualTransform(
if(fromS && toS) if(fromS && toS)
{ {
// compute transform fromId -> toId // make sure we have all data needed
std::vector<int> inliersV; if((_reextractLoopClosureFeatures && _registrationPipeline->isImageRequired()) ||
if(_reextractLoopClosureFeatures) _registrationPipeline->isScanRequired() ||
_registrationPipeline->isUserDataRequired())
{ {
getNodeData(fromS->id(), true); getNodeData(fromS->id(), true);
getNodeData(toS->id(), true); getNodeData(toS->id(), true);
}
// compute transform fromId -> toId
std::vector<int> inliersV;
if(_reextractLoopClosureFeatures || (fromS->getWords().size() && toS->getWords().size()))
{
Signature tmpFrom = *fromS; Signature tmpFrom = *fromS;
Signature tmpTo = *toS; Signature tmpTo = *toS;
tmpFrom.setWords(std::multimap<int, cv::KeyPoint>()); if(_reextractLoopClosureFeatures)
tmpFrom.setWords3(std::multimap<int, cv::Point3f>()); {
tmpTo.setWords(std::multimap<int, cv::KeyPoint>()); tmpFrom.setWords(std::multimap<int, cv::KeyPoint>());
tmpTo.setWords3(std::multimap<int, cv::Point3f>()); tmpFrom.setWords3(std::multimap<int, cv::Point3f>());
transform = _registrationVis->computeTransformation(tmpFrom, tmpTo, Transform::getIdentity(), rejectedMsg, &inliersV, variance); tmpTo.setWords(std::multimap<int, cv::KeyPoint>());
} tmpTo.setWords3(std::multimap<int, cv::Point3f>());
else if(fromS->getWords().size() && toS->getWords().size()) }
{
transform = _registrationVis->computeTransformation(*fromS, *toS, Transform::getIdentity(), rejectedMsg, &inliersV, variance); Transform guess = Transform::getIdentity();
} if(!_registrationPipeline->isImageRequired())
if(inliers) {
{ // no visual in the pipeline, make visual registration for guess
*inliers = (int)inliersV.size(); RegistrationVis regVis(parameters_);
guess = regVis.computeTransformation(tmpFrom, tmpTo, guess, info);
}
if(!guess.isNull())
{
transform = _registrationPipeline->computeTransformation(tmpFrom, tmpTo, guess, info);
}
} }
} }
else else
{ {
std::string msg = uFormat("Did not find nodes %d and/or %d", fromId, toId); std::string msg = uFormat("Did not find nodes %d and/or %d", fromId, toId);
if(rejectedMsg) if(info)
{ {
*rejectedMsg = msg; info->rejectedMsg_ = msg;
} }
UWARN(msg.c_str()); UWARN(msg.c_str());
} }
@@ -2068,10 +2096,7 @@ Transform Memory::computeIcpTransform(
int fromId, int fromId,
int toId, int toId,
Transform guess, Transform guess,
std::string * rejectedMsg, RegistrationInfo * info)
int * inliers,
float * variance,
float * inliersRatio)
{ {
Signature * fromS = this->_getSignature(fromId); Signature * fromS = this->_getSignature(fromId);
Signature * toS = this->_getSignature(toId); Signature * toS = this->_getSignature(toId);
@@ -2107,18 +2132,14 @@ Transform Memory::computeIcpTransform(
// compute transform fromId -> toId // compute transform fromId -> toId
std::vector<int> inliersV; std::vector<int> inliersV;
t = _registrationIcp->computeTransformation(fromS->sensorData(), toS->sensorData(), guess, rejectedMsg, &inliersV, variance, inliersRatio); t = _registrationIcp->computeTransformation(fromS->sensorData(), toS->sensorData(), guess, info);
if(inliers)
{
*inliers = (int)inliersV.size();
}
} }
else else
{ {
std::string msg = uFormat("Did not find nodes %d and/or %d", fromId, toId); std::string msg = uFormat("Did not find nodes %d and/or %d", fromId, toId);
if(rejectedMsg) if(info)
{ {
*rejectedMsg = msg; info->rejectedMsg_ = msg;
} }
UWARN(msg.c_str()); UWARN(msg.c_str());
} }
@@ -2130,9 +2151,7 @@ Transform Memory::computeIcpTransformMulti(
int fromId, int fromId,
int toId, int toId,
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
std::string * rejectedMsg, RegistrationInfo * info)
int * inliers,
float * variance)
{ {
UASSERT(uContains(poses, fromId) && uContains(_signatures, fromId)); UASSERT(uContains(poses, fromId) && uContains(_signatures, fromId));
UASSERT(uContains(poses, toId) && uContains(_signatures, toId)); UASSERT(uContains(poses, toId) && uContains(_signatures, toId));
@@ -2192,11 +2211,7 @@ Transform Memory::computeIcpTransformMulti(
Transform guess = poses.at(fromId).inverse() * poses.at(toId); Transform guess = poses.at(fromId).inverse() * poses.at(toId);
std::vector<int> inliersV; std::vector<int> inliersV;
t = _registrationIcp->computeTransformation(fromS->sensorData(), assembledData, guess, rejectedMsg, &inliersV, variance); t = _registrationIcp->computeTransformation(fromS->sensorData(), assembledData, guess, info);
if(inliers)
{
*inliers = (int)inliersV.size();
}
} }
return t; return t;
+2 -2
View File
@@ -70,7 +70,7 @@ Odometry::Odometry(const rtabmap::ParametersMap & parameters) :
_minDepth(Parameters::defaultVisMinDepth()), _minDepth(Parameters::defaultVisMinDepth()),
_maxDepth(Parameters::defaultVisMaxDepth()), _maxDepth(Parameters::defaultVisMaxDepth()),
_resetCountdown(Parameters::defaultOdomResetCountdown()), _resetCountdown(Parameters::defaultOdomResetCountdown()),
_force2D(Parameters::defaultVisForce2D()), _force2D(Parameters::defaultRegForce3DoF()),
_holonomic(Parameters::defaultOdomHolonomic()), _holonomic(Parameters::defaultOdomHolonomic()),
_filteringStrategy(Parameters::defaultOdomFilteringStrategy()), _filteringStrategy(Parameters::defaultOdomFilteringStrategy()),
_particleSize(Parameters::defaultOdomParticleSize()), _particleSize(Parameters::defaultOdomParticleSize()),
@@ -100,7 +100,7 @@ Odometry::Odometry(const rtabmap::ParametersMap & parameters) :
Parameters::parse(parameters, Parameters::kVisMinDepth(), _minDepth); Parameters::parse(parameters, Parameters::kVisMinDepth(), _minDepth);
Parameters::parse(parameters, Parameters::kVisMaxDepth(), _maxDepth); Parameters::parse(parameters, Parameters::kVisMaxDepth(), _maxDepth);
Parameters::parse(parameters, Parameters::kVisRoiRatios(), _roiRatios); Parameters::parse(parameters, Parameters::kVisRoiRatios(), _roiRatios);
Parameters::parse(parameters, Parameters::kVisForce2D(), _force2D); Parameters::parse(parameters, Parameters::kRegForce3DoF(), _force2D);
Parameters::parse(parameters, Parameters::kOdomHolonomic(), _holonomic); Parameters::parse(parameters, Parameters::kOdomHolonomic(), _holonomic);
Parameters::parse(parameters, Parameters::kOdomFillInfoData(), _fillInfoData); Parameters::parse(parameters, Parameters::kOdomFillInfoData(), _fillInfoData);
Parameters::parse(parameters, Parameters::kVisEstimationType(), _estimationType); Parameters::parse(parameters, Parameters::kVisEstimationType(), _estimationType);
+39 -24
View File
@@ -27,6 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/core/OdometryF2F.h" #include "rtabmap/core/OdometryF2F.h"
#include "rtabmap/core/OdometryInfo.h" #include "rtabmap/core/OdometryInfo.h"
#include "rtabmap/core/Registration.h"
#include "rtabmap/core/EpipolarGeometry.h" #include "rtabmap/core/EpipolarGeometry.h"
#include "rtabmap/utilite/ULogger.h" #include "rtabmap/utilite/ULogger.h"
#include "rtabmap/utilite/UTimer.h" #include "rtabmap/utilite/UTimer.h"
@@ -37,15 +38,16 @@ OdometryF2F::OdometryF2F(const ParametersMap & parameters) :
Odometry(parameters), Odometry(parameters),
keyFrameThr_(Parameters::defaultOdomFlowKeyFrameThr()), keyFrameThr_(Parameters::defaultOdomFlowKeyFrameThr()),
guessFromMotion_(Parameters::defaultOdomFlowGuessMotion()), guessFromMotion_(Parameters::defaultOdomFlowGuessMotion()),
registration_(parameters),
motionSinceLastKeyFrame_(Transform::getIdentity()) motionSinceLastKeyFrame_(Transform::getIdentity())
{ {
registrationPipeline_ = Registration::create(parameters);
Parameters::parse(parameters, Parameters::kOdomFlowKeyFrameThr(), keyFrameThr_); Parameters::parse(parameters, Parameters::kOdomFlowKeyFrameThr(), keyFrameThr_);
Parameters::parse(parameters, Parameters::kOdomFlowGuessMotion(), guessFromMotion_); Parameters::parse(parameters, Parameters::kOdomFlowGuessMotion(), guessFromMotion_);
} }
OdometryF2F::~OdometryF2F() OdometryF2F::~OdometryF2F()
{ {
delete registrationPipeline_;
} }
void OdometryF2F::reset(const Transform & initialPose) void OdometryF2F::reset(const Transform & initialPose)
@@ -74,20 +76,16 @@ Transform OdometryF2F::computeTransform(
return output; return output;
} }
float variance = 0; RegistrationInfo regInfo;
std::vector<int> inliers;
Signature newFrame(data); Signature newFrame(data);
if(refFrame_.getWords().size()) if(refFrame_.sensorData().isValid())
{ {
std::string rejectedMsg; output = registrationPipeline_->computeTransformationMod(
output = registration_.computeTransformationMod(
refFrame_, refFrame_,
newFrame, newFrame,
guessFromMotion_?motionSinceLastKeyFrame_*this->previousTransform():Transform(), guessFromMotion_?motionSinceLastKeyFrame_*this->previousTransform():Transform(),
&rejectedMsg, &regInfo);
&inliers,
&variance);
if(info && this->isInfoDataFilled()) if(info && this->isInfoDataFilled())
{ {
@@ -106,11 +104,11 @@ Transform OdometryF2F::computeTransform(
idToIndex.insert(std::make_pair(iter->first, i)); idToIndex.insert(std::make_pair(iter->first, i));
++i; ++i;
} }
info->cornerInliers.resize(inliers.size(), 1); info->cornerInliers.resize(regInfo.inliersIndexes_.size(), 1);
i=0; i=0;
for(; i<(int)inliers.size(); ++i) for(; i<(int)regInfo.inliersIndexes_.size(); ++i)
{ {
info->cornerInliers[i] = idToIndex.at(inliers[i]); info->cornerInliers[i] = idToIndex.at(regInfo.inliersIndexes_[i]);
} }
} }
@@ -127,17 +125,24 @@ Transform OdometryF2F::computeTransform(
motionSinceLastKeyFrame_ *= output; motionSinceLastKeyFrame_ *= output;
// new key-frame? // new key-frame?
if(keyFrameThr_ <= 0 || (int)inliers.size() <= keyFrameThr_) if(keyFrameThr_ <= 0 || (int)regInfo.inliers <= keyFrameThr_)
{ {
UDEBUG("Update key frame"); UDEBUG("Update key frame");
// only generate features for the first frame
Signature newRefFrame(data); Signature newRefFrame(data);
Signature dummy;
registration_.computeTransformationMod(
newRefFrame,
dummy);
if((int)newRefFrame.getWords().size() >= this->getMinInliers()) int features = -1;
if(registrationPipeline_->isImageRequired())
{
// this will generate features only for the first frame
Signature dummy;
registrationPipeline_->computeTransformationMod(
newRefFrame,
dummy);
features = (int)newRefFrame.getWords().size();
}
if((features < 0 || features >= this->getMinInliers()) &&
(!registrationPipeline_->isScanRequired() || newRefFrame.sensorData().laserScanRaw().cols))
{ {
refFrame_ = newRefFrame; refFrame_ = newRefFrame;
@@ -146,23 +151,33 @@ Transform OdometryF2F::computeTransform(
} }
else else
{ {
UWARN("Too low 2D corners (%d), keeping last key frame...", if(features >= 0 && features < this->getMinInliers())
(int)newRefFrame.getWords().size()); {
UWARN("Too low 2D features (%d), keeping last key frame...", features);
}
if(registrationPipeline_->isScanRequired() && newRefFrame.sensorData().laserScanRaw().cols==0)
{
UWARN("Too low scan points (%d), keeping last key frame...", newRefFrame.sensorData().laserScanRaw().cols);
}
} }
} }
} }
else if(!regInfo.rejectedMsg_.empty())
{
UWARN("Registration failed: \"%s\"", regInfo.rejectedMsg_.c_str());
}
if(info) if(info)
{ {
info->type = 1; info->type = 1;
info->variance = variance; info->variance = regInfo.variance;
info->inliers = (int)inliers.size(); info->inliers = regInfo.inliers;
} }
UINFO("Odom update time = %fs lost=%s inliers=%d, ref frame corners=%d, transform accepted=%s", UINFO("Odom update time = %fs lost=%s inliers=%d, ref frame corners=%d, transform accepted=%s",
timer.elapsed(), timer.elapsed(),
output.isNull()?"true":"false", output.isNull()?"true":"false",
(int)inliers.size(), (int)regInfo.inliers,
(int)refFrame_.getWords().size(), (int)refFrame_.getWords().size(),
!output.isNull()?"true":"false"); !output.isNull()?"true":"false");
-216
View File
@@ -1,216 +0,0 @@
/*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "rtabmap/core/OdometryICP.h"
#include "rtabmap/core/util3d_registration.h"
#include "rtabmap/core/util3d_filtering.h"
#include "rtabmap/core/util3d_surface.h"
#include "rtabmap/core/OdometryInfo.h"
#include "rtabmap/utilite/ULogger.h"
#include "rtabmap/utilite/UTimer.h"
namespace rtabmap {
OdometryICP::OdometryICP(int decimation,
float voxelSize,
int samples,
float maxCorrespondenceDistance,
int maxIterations,
float correspondenceRatio,
bool pointToPlane,
const ParametersMap & odometryParameter) :
Odometry(odometryParameter),
_decimation(decimation),
_voxelSize(voxelSize),
_samples(samples),
_maxCorrespondenceDistance(maxCorrespondenceDistance),
_maxIterations(maxIterations),
_correspondenceRatio(correspondenceRatio),
_pointToPlane(pointToPlane),
_previousCloudNormal(new pcl::PointCloud<pcl::PointNormal>),
_previousCloud(new pcl::PointCloud<pcl::PointXYZ>)
{
}
void OdometryICP::reset(const Transform & initialPose)
{
Odometry::reset(initialPose);
_previousCloudNormal.reset(new pcl::PointCloud<pcl::PointNormal>);
_previousCloud.reset(new pcl::PointCloud<pcl::PointXYZ>);
}
// return not null transform if odometry is correctly computed
Transform OdometryICP::computeTransform(const SensorData & data, OdometryInfo * info)
{
UTimer timer;
Transform output;
bool hasConverged = false;
double variance = 0;
unsigned int minPoints = 100;
int correspondences = 0;
if(!data.depthOrRightRaw().empty())
{
if(data.depthOrRightRaw().type() == CV_8UC1)
{
UERROR("ICP 3D cannot be done on stereo images!");
return output;
}
if(!(data.cameraModels().size() == 1 && data.cameraModels()[0].isValid()))
{
UERROR("ICP 3D cannot be done without calibration or on multi-camera!");
return output;
}
const CameraModel & cameraModel = data.cameraModels()[0];
pcl::PointCloud<pcl::PointXYZ>::Ptr newCloudXYZ = util3d::getICPReadyCloud(
data.depthOrRightRaw(),
cameraModel.fx(),
cameraModel.fy(),
cameraModel.cx(),
cameraModel.cy(),
_decimation,
this->getMaxDepth(),
_voxelSize,
_samples,
cameraModel.localTransform());
if(_pointToPlane)
{
pcl::PointCloud<pcl::PointNormal>::Ptr newCloud = util3d::computeNormals(newCloudXYZ);
std::vector<int> indices;
newCloud = util3d::removeNaNNormalsFromPointCloud(newCloud);
if(newCloudXYZ->size() != newCloud->size())
{
UWARN("removed nan normals...");
}
if(_previousCloudNormal->size() > minPoints && newCloud->size() > minPoints)
{
pcl::PointCloud<pcl::PointNormal>::Ptr newCloudRegistered(new pcl::PointCloud<pcl::PointNormal>);
Transform transform = util3d::icpPointToPlane(
newCloud,
_previousCloudNormal,
_maxCorrespondenceDistance,
_maxIterations,
hasConverged,
*newCloudRegistered);
util3d::computeVarianceAndCorrespondences(
newCloudRegistered,
_previousCloudNormal,
_maxCorrespondenceDistance,
variance,
correspondences);
// verify if there are enough correspondences
float correspondencesRatio = float(correspondences)/float(_previousCloudNormal->size()>newCloud->size()?_previousCloudNormal->size():newCloud->size());
if(!transform.isNull() && hasConverged &&
correspondencesRatio >= _correspondenceRatio)
{
output = transform;
_previousCloudNormal = newCloud;
}
else
{
UWARN("Transform not valid (hasConverged=%s variance = %f)",
hasConverged?"true":"false", variance);
}
}
else if(newCloud->size() > minPoints)
{
output.setIdentity();
_previousCloudNormal = newCloud;
}
}
else
{
//point to point
if(_previousCloud->size() > minPoints && newCloudXYZ->size() > minPoints)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr newCloudRegistered(new pcl::PointCloud<pcl::PointXYZ>);
Transform transform = util3d::icp(
newCloudXYZ,
_previousCloud,
_maxCorrespondenceDistance,
_maxIterations,
hasConverged,
*newCloudRegistered);
util3d::computeVarianceAndCorrespondences(
newCloudRegistered,
_previousCloud,
_maxCorrespondenceDistance,
variance,
correspondences);
// verify if there are enough correspondences
float correspondencesRatio = float(correspondences)/float(_previousCloud->size()>newCloudXYZ->size()?_previousCloud->size():newCloudXYZ->size());
if(!transform.isNull() && hasConverged &&
correspondencesRatio >= _correspondenceRatio)
{
output = transform;
_previousCloud = newCloudXYZ;
}
else
{
UWARN("Transform not valid (hasConverged=%s variance = %f)",
hasConverged?"true":"false", variance);
}
}
else if(newCloudXYZ->size() > minPoints)
{
output.setIdentity();
_previousCloud = newCloudXYZ;
}
}
}
else
{
UERROR("Depth is empty?!?");
}
if(info)
{
info->variance = variance;
info->inliers = correspondences;
}
UINFO("Odom update time = %fs hasConverged=%s variance=%f cloud=%d",
timer.elapsed(),
hasConverged?"true":"false",
variance,
(int)(_pointToPlane?_previousCloudNormal->size():_previousCloud->size()));
return output;
}
} // namespace rtabmap
+3 -3
View File
@@ -158,7 +158,7 @@ const std::map<std::string, std::pair<bool, std::string> > & Parameters::getRemo
removedParameters_.insert(std::make_pair("Odom/RefineIterations", std::make_pair(true, Parameters::kVisRefineIterations()))); removedParameters_.insert(std::make_pair("Odom/RefineIterations", std::make_pair(true, Parameters::kVisRefineIterations())));
removedParameters_.insert(std::make_pair("Odom/MaxDepth", std::make_pair(true, Parameters::kVisMaxDepth()))); removedParameters_.insert(std::make_pair("Odom/MaxDepth", std::make_pair(true, Parameters::kVisMaxDepth())));
removedParameters_.insert(std::make_pair("Odom/RoiRatios", std::make_pair(true, Parameters::kVisRoiRatios()))); removedParameters_.insert(std::make_pair("Odom/RoiRatios", std::make_pair(true, Parameters::kVisRoiRatios())));
removedParameters_.insert(std::make_pair("Odom/Force2D", std::make_pair(true, Parameters::kVisForce2D()))); removedParameters_.insert(std::make_pair("Odom/Force2D", std::make_pair(true, Parameters::kRegForce3DoF())));
removedParameters_.insert(std::make_pair("Odom/VarianceFromInliersCount", std::make_pair(true, Parameters::kRegVarianceFromInliersCount()))); removedParameters_.insert(std::make_pair("Odom/VarianceFromInliersCount", std::make_pair(true, Parameters::kRegVarianceFromInliersCount())));
removedParameters_.insert(std::make_pair("Odom/PnPReprojError", std::make_pair(true, Parameters::kVisPnPReprojError()))); removedParameters_.insert(std::make_pair("Odom/PnPReprojError", std::make_pair(true, Parameters::kVisPnPReprojError())));
removedParameters_.insert(std::make_pair("Odom/PnPFlags", std::make_pair(true, Parameters::kVisPnPFlags()))); removedParameters_.insert(std::make_pair("Odom/PnPFlags", std::make_pair(true, Parameters::kVisPnPFlags())));
@@ -188,13 +188,13 @@ const std::map<std::string, std::pair<bool, std::string> > & Parameters::getRemo
removedParameters_.insert(std::make_pair("LccBow/MinInliers", std::make_pair(false, Parameters::kVisMinInliers()))); removedParameters_.insert(std::make_pair("LccBow/MinInliers", std::make_pair(false, Parameters::kVisMinInliers())));
removedParameters_.insert(std::make_pair("LccBow/Iterations", std::make_pair(false, Parameters::kVisIterations()))); removedParameters_.insert(std::make_pair("LccBow/Iterations", std::make_pair(false, Parameters::kVisIterations())));
removedParameters_.insert(std::make_pair("LccBow/RefineIterations", std::make_pair(false, Parameters::kVisRefineIterations()))); removedParameters_.insert(std::make_pair("LccBow/RefineIterations", std::make_pair(false, Parameters::kVisRefineIterations())));
removedParameters_.insert(std::make_pair("LccBow/Force2D", std::make_pair(false, Parameters::kVisForce2D()))); removedParameters_.insert(std::make_pair("LccBow/Force2D", std::make_pair(false, Parameters::kRegForce3DoF())));
removedParameters_.insert(std::make_pair("LccBow/VarianceFromInliersCount", std::make_pair(false, Parameters::kRegVarianceFromInliersCount()))); removedParameters_.insert(std::make_pair("LccBow/VarianceFromInliersCount", std::make_pair(false, Parameters::kRegVarianceFromInliersCount())));
removedParameters_.insert(std::make_pair("LccBow/PnPReprojError", std::make_pair(false, Parameters::kVisPnPReprojError()))); removedParameters_.insert(std::make_pair("LccBow/PnPReprojError", std::make_pair(false, Parameters::kVisPnPReprojError())));
removedParameters_.insert(std::make_pair("LccBow/PnPFlags", std::make_pair(false, Parameters::kVisPnPFlags()))); removedParameters_.insert(std::make_pair("LccBow/PnPFlags", std::make_pair(false, Parameters::kVisPnPFlags())));
removedParameters_.insert(std::make_pair("LccBow/EpipolarGeometryVar", std::make_pair(true, Parameters::kVisEpipolarGeometryVar()))); removedParameters_.insert(std::make_pair("LccBow/EpipolarGeometryVar", std::make_pair(true, Parameters::kVisEpipolarGeometryVar())));
removedParameters_.insert(std::make_pair("LccIcp/Type", std::make_pair(true, Parameters::kRGBDLoopClosureLinkRefining()))); removedParameters_.insert(std::make_pair("LccIcp/Type", std::make_pair(false, Parameters::kRegStrategy())));
removedParameters_.insert(std::make_pair("LccIcp3/Decimation", std::make_pair(false, ""))); removedParameters_.insert(std::make_pair("LccIcp3/Decimation", std::make_pair(false, "")));
removedParameters_.insert(std::make_pair("LccIcp3/MaxDepth", std::make_pair(false, ""))); removedParameters_.insert(std::make_pair("LccIcp3/MaxDepth", std::make_pair(false, "")));
+190
View File
@@ -0,0 +1,190 @@
/*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <rtabmap/core/RegistrationVis.h>
#include <rtabmap/core/RegistrationIcp.h>
#include <rtabmap/utilite/ULogger.h>
namespace rtabmap {
Registration * Registration::create(const ParametersMap & parameters)
{
int regTypeInt = Parameters::defaultRegStrategy();
Parameters::parse(parameters, Parameters::kRegStrategy(), regTypeInt);
Registration::Type type = (Registration::Type)regTypeInt;
return create(type, parameters);
}
Registration * Registration::create(Registration::Type & type, const ParametersMap & parameters)
{
UDEBUG("type=%d", (int)type);
Registration * reg = 0;
switch(type)
{
case Registration::kTypeIcp:
reg = new RegistrationIcp(parameters);
break;
case Registration::kTypeVisIcp:
reg = new RegistrationVis(parameters, new RegistrationIcp(parameters));
break;
default: // kTypeVis
reg = new RegistrationVis(parameters);
type = Registration::kTypeVis;
break;
}
return reg;
}
Registration::Registration(const ParametersMap & parameters, Registration * child) :
varianceFromInliersCount_(Parameters::defaultRegVarianceFromInliersCount()),
force3DoF_(Parameters::defaultRegForce3DoF()),
child_(child)
{
this->parseParameters(parameters);
}
Registration::~Registration()
{
if(child_)
{
delete child_;
}
}
void Registration::parseParameters(const ParametersMap & parameters)
{
Parameters::parse(parameters, Parameters::kRegVarianceFromInliersCount(), varianceFromInliersCount_);
Parameters::parse(parameters, Parameters::kRegForce3DoF(), force3DoF_);
if(child_)
{
child_->parseParameters(parameters);
}
}
bool Registration::isImageRequired() const
{
bool val = isImageRequiredImpl();
if(!val && child_)
{
val = child_->isImageRequired();
}
return val;
}
bool Registration::isScanRequired() const
{
bool val = isScanRequiredImpl();
if(!val && child_)
{
val = child_->isScanRequired();
}
return val;
}
bool Registration::isUserDataRequired() const
{
bool val = isUserDataRequiredImpl();
if(!val && child_)
{
val = child_->isUserDataRequired();
}
return val;
}
void Registration::setChildRegistration(Registration * child)
{
if(child_)
{
delete child_;
}
child_ = child;
}
Transform Registration::computeTransformation(
const Signature & from,
const Signature & to,
Transform guess,
RegistrationInfo * infoOut) const
{
Signature fromCopy(from);
Signature toCopy(to);
return computeTransformationMod(fromCopy, toCopy, guess, infoOut);
}
Transform Registration::computeTransformation(
const SensorData & from,
const SensorData & to,
Transform guess,
RegistrationInfo * infoOut) const
{
Signature fromCopy(from);
Signature toCopy(to);
return computeTransformationMod(fromCopy, toCopy, guess, infoOut);
}
Transform Registration::computeTransformationMod(
Signature & from,
Signature & to,
Transform guess,
RegistrationInfo * infoOut) const
{
RegistrationInfo info;
Transform t = computeTransformationImpl(from, to, guess, info);
if(child_)
{
if(!t.isNull())
{
t = child_->computeTransformationMod(from, to, force3DoF_?t.to3DoF():t, &info);
}
}
else if(!t.isNull() && force3DoF_)
{
t = t.to3DoF();
}
if(varianceFromInliersCount_)
{
if(info.inliersRatio)
{
info.variance = info.inliersRatio > 0?1.0/double(info.inliersRatio):1.0;
}
else
{
info.variance = info.inliers > 0?1.0f/float(info.inliers):1.0f;
}
info.variance = info.variance>0.0f?info.variance:0.0001f; // epsilon if exact transform
}
if(infoOut)
{
*infoOut = info;
}
return t;
}
}
+12 -51
View File
@@ -39,10 +39,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace rtabmap { namespace rtabmap {
RegistrationIcp::RegistrationIcp(const ParametersMap & parameters) : RegistrationIcp::RegistrationIcp(const ParametersMap & parameters, Registration * child) :
Registration(parameters, child),
_maxTranslation(Parameters::defaultIcpMaxTranslation()), _maxTranslation(Parameters::defaultIcpMaxTranslation()),
_maxRotation(Parameters::defaultIcpMaxRotation()), _maxRotation(Parameters::defaultIcpMaxRotation()),
_icp2D(Parameters::defaultIcp2D()),
_voxelSize(Parameters::defaultIcpVoxelSize()), _voxelSize(Parameters::defaultIcpVoxelSize()),
_downsamplingStep(Parameters::defaultIcpDownsamplingStep()), _downsamplingStep(Parameters::defaultIcpDownsamplingStep()),
_maxCorrespondenceDistance(Parameters::defaultIcpMaxCorrespondenceDistance()), _maxCorrespondenceDistance(Parameters::defaultIcpMaxCorrespondenceDistance()),
@@ -60,7 +60,6 @@ void RegistrationIcp::parseParameters(const ParametersMap & parameters)
Parameters::parse(parameters, Parameters::kIcpMaxTranslation(), _maxTranslation); Parameters::parse(parameters, Parameters::kIcpMaxTranslation(), _maxTranslation);
Parameters::parse(parameters, Parameters::kIcpMaxRotation(), _maxRotation); Parameters::parse(parameters, Parameters::kIcpMaxRotation(), _maxRotation);
Parameters::parse(parameters, Parameters::kIcp2D(), _icp2D);
Parameters::parse(parameters, Parameters::kIcpVoxelSize(), _voxelSize); Parameters::parse(parameters, Parameters::kIcpVoxelSize(), _voxelSize);
Parameters::parse(parameters, Parameters::kIcpDownsamplingStep(), _downsamplingStep); Parameters::parse(parameters, Parameters::kIcpDownsamplingStep(), _downsamplingStep);
Parameters::parse(parameters, Parameters::kIcpMaxCorrespondenceDistance(), _maxCorrespondenceDistance); Parameters::parse(parameters, Parameters::kIcpMaxCorrespondenceDistance(), _maxCorrespondenceDistance);
@@ -77,42 +76,18 @@ void RegistrationIcp::parseParameters(const ParametersMap & parameters)
UASSERT_MSG(_pointToPlaneNormalNeighbors > 0, uFormat("value=%d", _pointToPlaneNormalNeighbors).c_str()); UASSERT_MSG(_pointToPlaneNormalNeighbors > 0, uFormat("value=%d", _pointToPlaneNormalNeighbors).c_str());
} }
Transform RegistrationIcp::computeTransformationMod( Transform RegistrationIcp::computeTransformationImpl(
Signature & fromSignature, Signature & fromSignature,
Signature & toSignature, Signature & toSignature,
Transform guess, Transform guess,
std::string * rejectedMsg, RegistrationInfo & info) const
std::vector<int> * inliersOut,
float * varianceOut,
float * inliersRatioOut) const
{
return computeTransformation(
fromSignature.sensorData(),
toSignature.sensorData(),
guess,
rejectedMsg,
inliersOut,
varianceOut,
inliersRatioOut);
}
Transform RegistrationIcp::computeTransformation(
const SensorData & dataFrom,
const SensorData & dataTo,
Transform guess,
std::string * rejectedMsg,
std::vector<int> * inliersOut,
float * varianceOut,
float * inliersRatioOut) const
{ {
UDEBUG("Guess transform = %s", guess.prettyPrint().c_str()); UDEBUG("Guess transform = %s", guess.prettyPrint().c_str());
UDEBUG("Voxel size=%f", _voxelSize); UDEBUG("Voxel size=%f", _voxelSize);
UDEBUG("2D=%d", _icp2D?1:0);
UDEBUG("PointToPlane=%d", _pointToPlane?1:0); UDEBUG("PointToPlane=%d", _pointToPlane?1:0);
UDEBUG("Normal neighborhood=%d", _pointToPlaneNormalNeighbors); UDEBUG("Normal neighborhood=%d", _pointToPlaneNormalNeighbors);
UDEBUG("Max corrrespondence distance=%f", _maxCorrespondenceDistance); UDEBUG("Max corrrespondence distance=%f", _maxCorrespondenceDistance);
UDEBUG("Max Iterations=%d", _maxIterations); UDEBUG("Max Iterations=%d", _maxIterations);
UDEBUG("Variance from inliers count=%d", _varianceFromInliersCount?1:0);
UDEBUG("Correspondence Ratio=%f", _correspondenceRatio); UDEBUG("Correspondence Ratio=%f", _correspondenceRatio);
UDEBUG("Max translation=%f", _maxTranslation); UDEBUG("Max translation=%f", _maxTranslation);
UDEBUG("Max rotation=%f", _maxRotation); UDEBUG("Max rotation=%f", _maxRotation);
@@ -121,6 +96,9 @@ Transform RegistrationIcp::computeTransformation(
std::string msg; std::string msg;
Transform transform; Transform transform;
SensorData & dataFrom = fromSignature.sensorData();
SensorData & dataTo = toSignature.sensorData();
// ICP with guess transform // ICP with guess transform
if(!dataFrom.laserScanRaw().empty() && !dataTo.laserScanRaw().empty()) if(!dataFrom.laserScanRaw().empty() && !dataTo.laserScanRaw().empty())
{ {
@@ -157,7 +135,7 @@ Transform RegistrationIcp::computeTransformation(
double variance = 1.0; double variance = 1.0;
bool correspondencesComputed = false; bool correspondencesComputed = false;
pcl::PointCloud<pcl::PointXYZ>::Ptr fromCloudRegistered(new pcl::PointCloud<pcl::PointXYZ>()); pcl::PointCloud<pcl::PointXYZ>::Ptr fromCloudRegistered(new pcl::PointCloud<pcl::PointXYZ>());
if(!_icp2D) // 3D ICP if(!force3DoF()) // 3D ICP
{ {
if(_pointToPlane) if(_pointToPlane)
{ {
@@ -287,23 +265,9 @@ Transform RegistrationIcp::computeTransformation(
maxLaserScans>0?maxLaserScans:dataTo.laserScanMaxPts()?dataTo.laserScanMaxPts():(int)(toCloud->size()>fromCloud->size()?toCloud->size():fromCloud->size()), maxLaserScans>0?maxLaserScans:dataTo.laserScanMaxPts()?dataTo.laserScanMaxPts():(int)(toCloud->size()>fromCloud->size()?toCloud->size():fromCloud->size()),
correspondencesRatio*100.0f); correspondencesRatio*100.0f);
if(_varianceFromInliersCount) info.variance = variance>0.0f?variance:0.0001; // epsilon if exact transform
{ info.inliers = correspondences;
variance = correspondencesRatio > 0?1.0/double(correspondencesRatio):1.0; info.inliersRatio = correspondencesRatio;
}
if(varianceOut)
{
*varianceOut = variance>0.0f?variance:0.0001; // epsilon if exact transform
}
if(inliersOut)
{
inliersOut->push_back(correspondences);
}
if(inliersRatioOut)
{
*inliersRatioOut = correspondencesRatio;
}
if(correspondencesRatio < _correspondenceRatio) if(correspondencesRatio < _correspondenceRatio)
{ {
@@ -354,10 +318,7 @@ Transform RegistrationIcp::computeTransformation(
} }
if(rejectedMsg) info.rejectedMsg_ = msg;
{
*rejectedMsg = msg;
}
UDEBUG("New transform = %s", transform.prettyPrint().c_str()); UDEBUG("New transform = %s", transform.prettyPrint().c_str());
return transform; return transform;
+20 -74
View File
@@ -41,12 +41,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace rtabmap { namespace rtabmap {
RegistrationVis::RegistrationVis(const ParametersMap & parameters) : RegistrationVis::RegistrationVis(const ParametersMap & parameters, Registration * child) :
Registration(parameters, child),
_minInliers(Parameters::defaultVisMinInliers()), _minInliers(Parameters::defaultVisMinInliers()),
_inlierDistance(Parameters::defaultVisInlierDistance()), _inlierDistance(Parameters::defaultVisInlierDistance()),
_iterations(Parameters::defaultVisIterations()), _iterations(Parameters::defaultVisIterations()),
_refineIterations(Parameters::defaultVisRefineIterations()), _refineIterations(Parameters::defaultVisRefineIterations()),
_force2D(Parameters::defaultVisForce2D()),
_epipolarGeometryVar(Parameters::defaultVisEpipolarGeometryVar()), _epipolarGeometryVar(Parameters::defaultVisEpipolarGeometryVar()),
_estimationType(Parameters::defaultVisEstimationType()), _estimationType(Parameters::defaultVisEstimationType()),
_forwardEstimateOnly(Parameters::defaultVisForwardEstOnly()), _forwardEstimateOnly(Parameters::defaultVisForwardEstOnly()),
@@ -82,7 +82,6 @@ void RegistrationVis::parseParameters(const ParametersMap & parameters)
Parameters::parse(parameters, Parameters::kVisInlierDistance(), _inlierDistance); Parameters::parse(parameters, Parameters::kVisInlierDistance(), _inlierDistance);
Parameters::parse(parameters, Parameters::kVisIterations(), _iterations); Parameters::parse(parameters, Parameters::kVisIterations(), _iterations);
Parameters::parse(parameters, Parameters::kVisRefineIterations(), _refineIterations); Parameters::parse(parameters, Parameters::kVisRefineIterations(), _refineIterations);
Parameters::parse(parameters, Parameters::kVisForce2D(), _force2D);
Parameters::parse(parameters, Parameters::kVisEstimationType(), _estimationType); Parameters::parse(parameters, Parameters::kVisEstimationType(), _estimationType);
Parameters::parse(parameters, Parameters::kVisEpipolarGeometryVar(), _epipolarGeometryVar); Parameters::parse(parameters, Parameters::kVisEpipolarGeometryVar(), _epipolarGeometryVar);
Parameters::parse(parameters, Parameters::kVisPnPReprojError(), _PnPReprojError); Parameters::parse(parameters, Parameters::kVisPnPReprojError(), _PnPReprojError);
@@ -154,19 +153,15 @@ RegistrationVis::~RegistrationVis()
{ {
} }
Transform RegistrationVis::computeTransformationMod( Transform RegistrationVis::computeTransformationImpl(
Signature & fromSignature, Signature & fromSignature,
Signature & toSignature, Signature & toSignature,
Transform guess, // guess is only used by Optical Flow correspondences (flowMaxLevel is set to 0 when guess is used) Transform guess, // guess is only used by Optical Flow correspondences (flowMaxLevel is set to 0 when guess is used)
std::string * rejectedMsg, RegistrationInfo & info) const
std::vector<int> * inliersOut,
float * varianceOut,
float * inliersRatioOut) const
{ {
UDEBUG("%s=%d", Parameters::kVisMinInliers().c_str(), _minInliers); UDEBUG("%s=%d", Parameters::kVisMinInliers().c_str(), _minInliers);
UDEBUG("%s=%f", Parameters::kVisInlierDistance().c_str(), _inlierDistance); UDEBUG("%s=%f", Parameters::kVisInlierDistance().c_str(), _inlierDistance);
UDEBUG("%s=%d", Parameters::kVisIterations().c_str(), _iterations); UDEBUG("%s=%d", Parameters::kVisIterations().c_str(), _iterations);
UDEBUG("%s=%d", Parameters::kVisForce2D().c_str(), _force2D?1:0);
UDEBUG("%s=%d", Parameters::kVisEstimationType().c_str(), _estimationType); UDEBUG("%s=%d", Parameters::kVisEstimationType().c_str(), _estimationType);
UDEBUG("%s=%d", Parameters::kVisForwardEstOnly().c_str(), _forwardEstimateOnly); UDEBUG("%s=%d", Parameters::kVisForwardEstOnly().c_str(), _forwardEstimateOnly);
UDEBUG("%s=%f", Parameters::kVisEpipolarGeometryVar().c_str(), _epipolarGeometryVar); UDEBUG("%s=%f", Parameters::kVisEpipolarGeometryVar().c_str(), _epipolarGeometryVar);
@@ -337,7 +332,7 @@ Transform RegistrationVis::computeTransformationMod(
kptsFrom3DKept.resize(ki); kptsFrom3DKept.resize(ki);
std::vector<cv::Point3f> kptsTo3D; std::vector<cv::Point3f> kptsTo3D;
if(_estimationType == 0 || (_estimationType == 1 && !_varianceFromInliersCount) || !_forwardEstimateOnly) if(_estimationType == 0 || (_estimationType == 1 && !varianceFromInliersCount()) || !_forwardEstimateOnly)
{ {
kptsTo3D = detector->generateKeypoints3D(toSignature.sensorData(), kptsTo); kptsTo3D = detector->generateKeypoints3D(toSignature.sensorData(), kptsTo);
} }
@@ -433,7 +428,7 @@ Transform RegistrationVis::computeTransformationMod(
{ {
kptsFrom3D = uValues(fromSignature.getWords3()); kptsFrom3D = uValues(fromSignature.getWords3());
} }
if((_estimationType == 0 || (_estimationType == 1 && !_varianceFromInliersCount) || !_forwardEstimateOnly) && if((_estimationType == 0 || (_estimationType == 1 && !varianceFromInliersCount()) || !_forwardEstimateOnly) &&
toSignature.getWords3().empty() && toSignature.getWords3().empty() &&
!toSignature.sensorData().imageRaw().empty()) !toSignature.sensorData().imageRaw().empty())
{ {
@@ -503,6 +498,7 @@ Transform RegistrationVis::computeTransformationMod(
///////////////////// /////////////////////
Transform transform; Transform transform;
float variance = 1.0f; float variance = 1.0f;
int inliersCount = 0;
if(toSignature.getWords().size() || !toSignature.sensorData().imageRaw().empty()) if(toSignature.getWords().size() || !toSignature.sensorData().imageRaw().empty())
{ {
Transform transforms[2]; Transform transforms[2];
@@ -629,7 +625,7 @@ Transform RegistrationVis::computeTransformationMod(
_PnPRefineIterations, _PnPRefineIterations,
dir==0?(!guess.isNull()?guess:Transform::getIdentity()):!transforms[0].isNull()?transforms[0].inverse():(!guess.isNull()?guess.inverse():Transform::getIdentity()), dir==0?(!guess.isNull()?guess:Transform::getIdentity()):!transforms[0].isNull()?transforms[0].inverse():(!guess.isNull()?guess.inverse():Transform::getIdentity()),
uMultimapToMapUnique(signatureA->getWords3()), uMultimapToMapUnique(signatureA->getWords3()),
_varianceFromInliersCount?0:&variances[dir], varianceFromInliersCount()?0:&variances[dir],
0, 0,
&inliersV); &inliersV);
inliers[dir] = inliersV; inliers[dir] = inliersV;
@@ -696,68 +692,27 @@ Transform RegistrationVis::computeTransformationMod(
if(transforms[0].isNull()) if(transforms[0].isNull())
{ {
transform = transforms[1]; transform = transforms[1];
if(inliersOut) info.inliersIndexes_ = inliers[1];
{
*inliersOut = inliers[1];
}
variance = variances[1]; variance = variances[1];
if(_varianceFromInliersCount) inliersCount = (int)inliers[1].size();
{
variance = inliers[1].size() > 0?1.0f/float(inliers[1].size()):1.0f;
}
} }
else else
{ {
/*if(!guess.isNull()) transform = transforms[0].interpolate(0.5f, transforms[1]);
{ info.inliersIndexes_ = inliers[0];
// use the transform nearest of the guess
int index = 0;
if(transforms[0].getDistance(guess) > transforms[1].getDistance(guess))
{
index = 1;
}
transform = transforms[index];
if(inliersOut)
{
*inliersOut = inliers[index];
}
variance = variances[index]; variance = (variances[0]+variances[1])/2.0f;
if(_varianceFromInliersCount) inliersCount = (int)(inliers[0].size()+inliers[1].size())/2;
{
variance = inliers[index].size() > 0?1.0f/float(inliers[index].size()):1.0f;
}
}
else*/
{
transform = transforms[0].interpolate(0.5f, transforms[1]);
if(inliersOut)
{
*inliersOut = inliers[0];
}
variance = (variances[0]+variances[1])/2.0f;
if(_varianceFromInliersCount)
{
int avg = (inliers[0].size()+inliers[1].size())/2;
variance = avg>0?1.0f/float(avg):1.0f;
}
}
} }
} }
else else
{ {
transform = transforms[0]; transform = transforms[0];
if(inliersOut) info.inliersIndexes_ = inliers[0];
{
*inliersOut = inliers[0];
}
variance = variances[0]; variance = variances[0];
if(_varianceFromInliersCount) inliersCount = (int)inliers[0].size();
{
variance = inliers[0].size() > 0?1.0f/float(inliers[0].size()):1.0f;
}
} }
} }
@@ -776,21 +731,12 @@ Transform RegistrationVis::computeTransformationMod(
roll, pitch, yaw); roll, pitch, yaw);
UWARN(msg.c_str()); UWARN(msg.c_str());
} }
else if(_force2D)
{
UDEBUG("Forcing 2D...");
transform = Transform(x,y,0, 0, 0, yaw);
}
} }
if(rejectedMsg) info.inliers = inliersCount;
{ info.rejectedMsg_ = msg;
*rejectedMsg = msg; info.variance = variance>0.0f?variance:0.0001f; // epsilon if exact transform
}
if(varianceOut)
{
*varianceOut = variance>0.0f?variance:0.0001; // epsilon if exact transform
}
UDEBUG("transform=%s", transform.prettyPrint().c_str()); UDEBUG("transform=%s", transform.prettyPrint().c_str());
return transform; return transform;
} }
+29 -46
View File
@@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/core/VWDictionary.h" #include "rtabmap/core/VWDictionary.h"
#include "rtabmap/core/BayesFilter.h" #include "rtabmap/core/BayesFilter.h"
#include "rtabmap/core/Compression.h" #include "rtabmap/core/Compression.h"
#include "rtabmap/core/RegistrationInfo.h"
#include <rtabmap/utilite/ULogger.h> #include <rtabmap/utilite/ULogger.h>
#include <rtabmap/utilite/UFile.h> #include <rtabmap/utilite/UFile.h>
@@ -89,7 +90,6 @@ Rtabmap::Rtabmap() :
_rgbdLinearUpdate(Parameters::defaultRGBDLinearUpdate()), _rgbdLinearUpdate(Parameters::defaultRGBDLinearUpdate()),
_rgbdAngularUpdate(Parameters::defaultRGBDAngularUpdate()), _rgbdAngularUpdate(Parameters::defaultRGBDAngularUpdate()),
_newMapOdomChangeDistance(Parameters::defaultRGBDNewMapOdomChangeDistance()), _newMapOdomChangeDistance(Parameters::defaultRGBDNewMapOdomChangeDistance()),
_loopClosureRefining(Parameters::defaultRGBDLoopClosureLinkRefining()),
_neighborLinkRefining(Parameters::defaultRGBDNeighborLinkRefining()), _neighborLinkRefining(Parameters::defaultRGBDNeighborLinkRefining()),
_proximityByTime(Parameters::defaultRGBDProximityByTime()), _proximityByTime(Parameters::defaultRGBDProximityByTime()),
_proximityBySpace(Parameters::defaultRGBDProximityBySpace()), _proximityBySpace(Parameters::defaultRGBDProximityBySpace()),
@@ -411,7 +411,6 @@ void Rtabmap::parseParameters(const ParametersMap & parameters)
Parameters::parse(parameters, Parameters::kRGBDPlanStuckIterations(), _pathStuckIterations); Parameters::parse(parameters, Parameters::kRGBDPlanStuckIterations(), _pathStuckIterations);
Parameters::parse(parameters, Parameters::kRGBDPlanLinearVelocity(), _pathLinearVelocity); Parameters::parse(parameters, Parameters::kRGBDPlanLinearVelocity(), _pathLinearVelocity);
Parameters::parse(parameters, Parameters::kRGBDPlanAngularVelocity(), _pathAngularVelocity); Parameters::parse(parameters, Parameters::kRGBDPlanAngularVelocity(), _pathAngularVelocity);
Parameters::parse(parameters, Parameters::kRGBDLoopClosureLinkRefining(), _loopClosureRefining);
UASSERT(_rgbdLinearUpdate >= 0.0f); UASSERT(_rgbdLinearUpdate >= 0.0f);
UASSERT(_rgbdAngularUpdate >= 0.0f); UASSERT(_rgbdAngularUpdate >= 0.0f);
@@ -1009,21 +1008,18 @@ bool Rtabmap::process(
{ {
UINFO("Odometry correction by scan matching"); UINFO("Odometry correction by scan matching");
Transform guess = signature->getLinks().begin()->second.transform().inverse(); Transform guess = signature->getLinks().begin()->second.transform().inverse();
float variance = 1.0f; RegistrationInfo info;
int inliers = 0; Transform t = _memory->computeIcpTransform(oldId, signature->id(), guess, &info);
float inliersRatio = 0;
std::string rejectedMsg;
Transform t = _memory->computeIcpTransform(oldId, signature->id(), guess, &rejectedMsg, &inliers, &variance, &inliersRatio);
if(!t.isNull()) if(!t.isNull())
{ {
UINFO("Scan matching: update neighbor link (%d->%d, variance=%f) from %s to %s", UINFO("Scan matching: update neighbor link (%d->%d, variance=%f) from %s to %s",
signature->id(), signature->id(),
oldId, oldId,
variance, info.variance,
signature->getLinks().at(oldId).transform().prettyPrint().c_str(), signature->getLinks().at(oldId).transform().prettyPrint().c_str(),
t.prettyPrint().c_str()); t.prettyPrint().c_str());
UASSERT(variance > 0.0); UASSERT(info.variance > 0.0);
_memory->updateLink(oldId, signature->id(), t, variance, variance); _memory->updateLink(oldId, signature->id(), t, info.variance, info.variance);
if(_optimizeFromGraphEnd) if(_optimizeFromGraphEnd)
{ {
@@ -1043,17 +1039,17 @@ bool Rtabmap::process(
} }
else else
{ {
UINFO("Scan matching rejected: %s", rejectedMsg.c_str()); UINFO("Scan matching rejected: %s", info.rejectedMsg_.c_str());
if(variance > 0) if(info.variance > 0)
{ {
double sqrtVar = sqrt(variance); double sqrtVar = sqrt(info.variance);
_memory->updateLink(signature->id(), oldId, guess, sqrtVar, sqrtVar); _memory->updateLink(signature->id(), oldId, guess, sqrtVar, sqrtVar);
} }
} }
statistics_.addStatistic(Statistics::kNeighborLinkRefiningAccepted(), !t.isNull()?1.0f:0); statistics_.addStatistic(Statistics::kNeighborLinkRefiningAccepted(), !t.isNull()?1.0f:0);
statistics_.addStatistic(Statistics::kNeighborLinkRefiningInliers(), inliers); statistics_.addStatistic(Statistics::kNeighborLinkRefiningInliers(), info.inliers);
statistics_.addStatistic(Statistics::kNeighborLinkRefiningInliers_ratio(), inliersRatio); statistics_.addStatistic(Statistics::kNeighborLinkRefiningInliers_ratio(), info.inliersRatio);
statistics_.addStatistic(Statistics::kNeighborLinkRefiningVariance(), variance); statistics_.addStatistic(Statistics::kNeighborLinkRefiningVariance(), info.variance);
statistics_.addStatistic(Statistics::kNeighborLinkRefiningPts(), signature->sensorData().laserScanRaw().cols); statistics_.addStatistic(Statistics::kNeighborLinkRefiningPts(), signature->sensorData().laserScanRaw().cols);
} }
} }
@@ -1161,13 +1157,9 @@ bool Rtabmap::process(
{ {
std::string rejectedMsg; std::string rejectedMsg;
UDEBUG("Check local transform between %d and %d", signature->id(), *iter); UDEBUG("Check local transform between %d and %d", signature->id(), *iter);
float variance = 1.0f; RegistrationInfo info;
int inliers = -1; Transform transform = _memory->computeTransform(signature->id(), *iter, &info);
Transform transform = _memory->computeVisualTransform(signature->id(), *iter, &rejectedMsg, &inliers, &variance);
if(!transform.isNull() && _loopClosureRefining)
{
transform = _memory->computeIcpTransform(signature->id(), *iter, transform, &rejectedMsg, 0, &variance);
}
if(!transform.isNull()) if(!transform.isNull())
{ {
UDEBUG("Add local loop closure in TIME (%d->%d) %s", UDEBUG("Add local loop closure in TIME (%d->%d) %s",
@@ -1175,8 +1167,8 @@ bool Rtabmap::process(
*iter, *iter,
transform.prettyPrint().c_str()); transform.prettyPrint().c_str());
// Add a loop constraint // Add a loop constraint
UASSERT(variance > 0.0); UASSERT(info.variance > 0.0);
if(_memory->addLink(Link(signature->id(), *iter, Link::kLocalTimeClosure, transform, variance, variance))) if(_memory->addLink(Link(signature->id(), *iter, Link::kLocalTimeClosure, transform, info.variance, info.variance)))
{ {
++localLoopClosuresInTimeFound; ++localLoopClosuresInTimeFound;
UINFO("Local loop closure found between %d and %d with t=%s", UINFO("Local loop closure found between %d and %d with t=%s",
@@ -1718,19 +1710,14 @@ bool Rtabmap::process(
float variance = 1.0f; float variance = 1.0f;
if(_rgbdSlamMode) if(_rgbdSlamMode)
{ {
std::string rejectedMsg; RegistrationInfo info;
transform = _memory->computeTransform(signature->id(), _loopClosureHypothesis.first, &info);
transform = _memory->computeVisualTransform(signature->id(), _loopClosureHypothesis.first, &rejectedMsg, &loopClosureVisualInliers, &variance); loopClosureVisualInliers = info.inliers;
if(!transform.isNull() && _loopClosureRefining)
{
transform = _memory->computeIcpTransform(signature->id(), _loopClosureHypothesis.first, transform, &rejectedMsg, 0, &variance);
}
rejectedHypothesis = transform.isNull(); rejectedHypothesis = transform.isNull();
if(rejectedHypothesis) if(rejectedHypothesis)
{ {
UWARN("Rejected loop closure %d -> %d: %s", UWARN("Rejected loop closure %d -> %d: %s",
_loopClosureHypothesis.first, signature->id(), rejectedMsg.c_str()); _loopClosureHypothesis.first, signature->id(), info.rejectedMsg_.c_str());
} }
} }
if(!rejectedHypothesis) if(!rejectedHypothesis)
@@ -1822,12 +1809,8 @@ bool Rtabmap::process(
(_proximityFilteringRadius <= 0.0f || (_proximityFilteringRadius <= 0.0f ||
_optimizedPoses.at(signature->id()).getDistanceSquared(_optimizedPoses.at(nearestId)) < _proximityFilteringRadius*_proximityFilteringRadius)) _optimizedPoses.at(signature->id()).getDistanceSquared(_optimizedPoses.at(nearestId)) < _proximityFilteringRadius*_proximityFilteringRadius))
{ {
float variance = 1.0f; RegistrationInfo info;
Transform transform = _memory->computeVisualTransform(signature->id(), nearestId, 0, 0, &variance); Transform transform = _memory->computeTransform(signature->id(), nearestId, &info);
if(!transform.isNull() && _loopClosureRefining)
{
transform = _memory->computeIcpTransform(signature->id(), nearestId, transform, 0, 0, &variance);
}
if(!transform.isNull()) if(!transform.isNull())
{ {
if(_proximityFilteringRadius <= 0 || transform.getNormSquared() <= _proximityFilteringRadius*_proximityFilteringRadius) if(_proximityFilteringRadius <= 0 || transform.getNormSquared() <= _proximityFilteringRadius*_proximityFilteringRadius)
@@ -1836,8 +1819,8 @@ bool Rtabmap::process(
signature->id(), signature->id(),
nearestId, nearestId,
transform.prettyPrint().c_str()); transform.prettyPrint().c_str());
UASSERT(variance > 0.0); UASSERT(info.variance > 0.0);
_memory->addLink(Link(signature->id(), nearestId, Link::kLocalSpaceClosure, transform, variance, variance)); _memory->addLink(Link(signature->id(), nearestId, Link::kLocalSpaceClosure, transform, info.variance, info.variance));
loopClosureLinksAdded.push_back(std::make_pair(signature->id(), nearestId)); loopClosureLinksAdded.push_back(std::make_pair(signature->id(), nearestId));
if(_loopClosureHypothesis.first == 0) if(_loopClosureHypothesis.first == 0)
@@ -1927,8 +1910,8 @@ bool Rtabmap::process(
//The nearest will be the reference for a loop closure transform //The nearest will be the reference for a loop closure transform
if(signature->getLinks().find(nearestId) == signature->getLinks().end()) if(signature->getLinks().find(nearestId) == signature->getLinks().end())
{ {
float variance = 1.0f; RegistrationInfo info;
Transform transform = _memory->computeIcpTransformMulti(signature->id(), nearestId, path, 0, 0, &variance); Transform transform = _memory->computeIcpTransformMulti(signature->id(), nearestId, path, &info);
if(!transform.isNull()) if(!transform.isNull())
{ {
if(_proximityFilteringRadius <= 0 || transform.getNormSquared() <= _proximityFilteringRadius*_proximityFilteringRadius) if(_proximityFilteringRadius <= 0 || transform.getNormSquared() <= _proximityFilteringRadius*_proximityFilteringRadius)
@@ -1960,8 +1943,8 @@ bool Rtabmap::process(
} }
// set Identify covariance for laser scan matching only // set Identify covariance for laser scan matching only
UASSERT(variance>0.0); UASSERT(info.variance>0.0);
double sqrtVar = sqrt(variance); double sqrtVar = sqrt(info.variance);
_memory->addLink(Link(signature->id(), nearestId, Link::kLocalSpaceClosure, transform, sqrtVar, sqrtVar, scanMatchingIds)); _memory->addLink(Link(signature->id(), nearestId, Link::kLocalSpaceClosure, transform, sqrtVar, sqrtVar, scanMatchingIds));
loopClosureLinksAdded.push_back(std::make_pair(signature->id(), nearestId)); loopClosureLinksAdded.push_back(std::make_pair(signature->id(), nearestId));
+7
View File
@@ -173,6 +173,13 @@ Transform Transform::translation() const
0,0,1, data()[11]); 0,0,1, data()[11]);
} }
Transform Transform::to3DoF() const
{
float x,y,z,roll,pitch,yaw;
this->getTranslationAndEulerAngles(x,y,z,roll,pitch,yaw);
return Transform(x,y,0, 0,0,yaw);
}
void Transform::getTranslationAndEulerAngles(float & x, float & y, float & z, float & roll, float & pitch, float & yaw) const void Transform::getTranslationAndEulerAngles(float & x, float & y, float & z, float & roll, float & pitch, float & yaw) const
{ {
pcl::getTranslationAndEulerAngles(toEigen3f(), x, y, z, roll, pitch, yaw); pcl::getTranslationAndEulerAngles(toEigen3f(), x, y, z, roll, pitch, yaw);
@@ -35,6 +35,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/core/SensorData.h> #include <rtabmap/core/SensorData.h>
class QSpinBox; class QSpinBox;
class QCheckBox;
class QPushButton;
namespace rtabmap { namespace rtabmap {
@@ -59,6 +61,9 @@ private:
bool processingImages_; bool processingImages_;
QSpinBox * decimationSpin_; QSpinBox * decimationSpin_;
int validDecimationValue_; int validDecimationValue_;
QPushButton * pause_;
QCheckBox * showCloudCheckbox_;
QCheckBox * showScanCheckbox_;
}; };
} /* namespace rtabmap */ } /* namespace rtabmap */
+7 -11
View File
@@ -193,9 +193,11 @@ public:
bool getSourceDatabaseStampsUsed() const;//Database group bool getSourceDatabaseStampsUsed() const;//Database group
bool isSourceRGBDColorOnly() const; bool isSourceRGBDColorOnly() const;
bool isSourceStereoDepthGenerated() const; bool isSourceStereoDepthGenerated() const;
bool isSourceScanFromDepth() const;
int getSourceScanFromDepthDecimation() const;
double getSourceScanFromDepthMaxDepth() const;
Transform getSourceLocalTransform() const; //Openni group Transform getSourceLocalTransform() const; //Openni group
Transform getStereoLaserLocalTransform() const; // stereo images Transform getLaserLocalTransform() const; // directory images
Transform getRGBDLaserLocalTransform() const; // rgbd images
Camera * createCamera(bool useRawImages = false); // return camera should be deleted if not null Camera * createCamera(bool useRawImages = false); // return camera should be deleted if not null
int getIgnoredDCComponents() const; int getIgnoredDCComponents() const;
@@ -259,25 +261,19 @@ private slots:
void openDatabaseViewer(); void openDatabaseViewer();
void selectSourceDatabase(); void selectSourceDatabase();
void selectCalibrationPath(); void selectCalibrationPath();
void selectSourceRGBDImagesStamps(); void selectSourceImagesStamps();
void selectSourceRGBDImagesPathRGB(); void selectSourceRGBDImagesPathRGB();
void selectSourceRGBDImagesPathDepth(); void selectSourceRGBDImagesPathDepth();
void selectSourceRGBDImagesPathScans(); void selectSourceImagesPathScans();
void selectSourceRGBDImagesPathGt(); void selectSourceImagesPathGt();
void selectSourceStereoImagesStamps();
void selectSourceStereoImagesPathLeft(); void selectSourceStereoImagesPathLeft();
void selectSourceStereoImagesPathRight(); void selectSourceStereoImagesPathRight();
void selectSourceStereoImagesPathScans();
void selectSourceStereoImagesPathGt();
void selectSourceImagesPath(); void selectSourceImagesPath();
void selectSourceVideoPath(); void selectSourceVideoPath();
void selectSourceStereoVideoPath(); void selectSourceStereoVideoPath();
void selectSourceOniPath(); void selectSourceOniPath();
void selectSourceOni2Path(); void selectSourceOni2Path();
void updateSourceGrpVisibility(); void updateSourceGrpVisibility();
void updateRGBDCameraGroupBoxVisibility();
void updateRGBCameraGroupBoxVisibility();
void updateStereoCameraGroupBoxVisibility();
void testOdometry(); void testOdometry();
void testCamera(); void testCamera();
+61 -21
View File
@@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/core/CameraEvent.h> #include <rtabmap/core/CameraEvent.h>
#include <rtabmap/core/util3d.h> #include <rtabmap/core/util3d.h>
#include <rtabmap/core/util2d.h> #include <rtabmap/core/util2d.h>
#include <rtabmap/core/util3d_filtering.h>
#include <rtabmap/gui/ImageView.h> #include <rtabmap/gui/ImageView.h>
#include <rtabmap/gui/CloudViewer.h> #include <rtabmap/gui/CloudViewer.h>
#include <rtabmap/utilite/UCv2Qt.h> #include <rtabmap/utilite/UCv2Qt.h>
@@ -40,6 +41,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QLabel> #include <QLabel>
#include <QSpinBox> #include <QSpinBox>
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QCheckBox>
#include <QPushButton>
namespace rtabmap { namespace rtabmap {
@@ -66,13 +69,24 @@ CameraViewer::CameraViewer(QWidget * parent) :
decimationSpin_->setMaximum(16); decimationSpin_->setMaximum(16);
decimationSpin_->setValue(1); decimationSpin_->setValue(1);
pause_ = new QPushButton("Pause", this);
pause_->setCheckable(true);
showCloudCheckbox_ = new QCheckBox("Show RGB-D cloud", this);
showCloudCheckbox_->setEnabled(false);
showCloudCheckbox_->setChecked(true);
showScanCheckbox_ = new QCheckBox("Show scan", this);
showScanCheckbox_->setEnabled(false);
QDialogButtonBox * buttonBox = new QDialogButtonBox(this); QDialogButtonBox * buttonBox = new QDialogButtonBox(this);
buttonBox->setStandardButtons(QDialogButtonBox::Close); buttonBox->setStandardButtons(QDialogButtonBox::Close);
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
QHBoxLayout * layout2 = new QHBoxLayout(); QHBoxLayout * layout2 = new QHBoxLayout();
layout2->addWidget(pause_);
layout2->addWidget(decimationLabel); layout2->addWidget(decimationLabel);
layout2->addWidget(decimationSpin_); layout2->addWidget(decimationSpin_);
layout2->addWidget(showCloudCheckbox_);
layout2->addWidget(showScanCheckbox_);
layout2->addStretch(1); layout2->addStretch(1);
layout2->addWidget(buttonBox); layout2->addWidget(buttonBox);
@@ -123,42 +137,68 @@ void CameraViewer::showImage(const rtabmap::SensorData & data)
{ {
imageView_->setImageDepth(uCvMat2QImage(util2d::decimate(data.depthOrRightRaw(), validDecimationValue_))); imageView_->setImageDepth(uCvMat2QImage(util2d::decimate(data.depthOrRightRaw(), validDecimationValue_)));
} }
if((data.stereoCameraModel().isValid() || (data.cameraModels().size() && data.cameraModels().at(0).isValid())))
if(!data.depthOrRightRaw().empty() &&
(data.stereoCameraModel().isValid() || (data.cameraModels().size() && data.cameraModels().at(0).isValid())))
{ {
if(!data.imageRaw().empty() && !data.depthOrRightRaw().empty()) if(showCloudCheckbox_->isChecked())
{ {
cloudView_->addOrUpdateCloud("cloud", util3d::cloudRGBFromSensorData(data, validDecimationValue_)); if(!data.imageRaw().empty() && !data.depthOrRightRaw().empty())
cloudView_->setVisible(true); {
cloudView_->update(); showCloudCheckbox_->setEnabled(true);
} cloudView_->addOrUpdateCloud("cloud", util3d::cloudRGBFromSensorData(data, validDecimationValue_));
else if(!data.depthOrRightRaw().empty()) }
{ else if(!data.depthOrRightRaw().empty())
cloudView_->addOrUpdateCloud("cloud", util3d::cloudFromSensorData(data, validDecimationValue_)); {
cloudView_->setVisible(true); showCloudCheckbox_->setEnabled(true);
cloudView_->update(); cloudView_->addOrUpdateCloud("cloud", util3d::cloudFromSensorData(data, validDecimationValue_));
}
} }
} }
else
if(!data.laserScanRaw().empty())
{ {
cloudView_->setVisible(false); showScanCheckbox_->setEnabled(true);
if(showScanCheckbox_->isChecked())
{
cloudView_->addOrUpdateCloud("scan", util3d::downsample(util3d::laserScanToPointCloud(data.laserScanRaw()), validDecimationValue_), Transform::getIdentity(), Qt::yellow);
}
} }
cloudView_->setVisible(showCloudCheckbox_->isEnabled() || showScanCheckbox_->isEnabled());
if(showCloudCheckbox_->isEnabled() || showScanCheckbox_->isEnabled())
{
cloudView_->update();
}
if(cloudView_->getAddedClouds().contains("cloud"))
{
cloudView_->setCloudVisibility("cloud", showCloudCheckbox_->isChecked());
}
if(cloudView_->getAddedClouds().contains("scan"))
{
cloudView_->setCloudVisibility("scan", showScanCheckbox_->isChecked());
}
processingImages_ = false; processingImages_ = false;
} }
void CameraViewer::handleEvent(UEvent * event) void CameraViewer::handleEvent(UEvent * event)
{ {
if(event->getClassName().compare("CameraEvent") == 0) if(!pause_->isChecked())
{ {
CameraEvent * camEvent = (CameraEvent*)event; if(event->getClassName().compare("CameraEvent") == 0)
if(camEvent->getCode() == CameraEvent::kCodeData)
{ {
if(camEvent->data().isValid()) CameraEvent * camEvent = (CameraEvent*)event;
if(camEvent->getCode() == CameraEvent::kCodeData)
{ {
if(!processingImages_ && this->isVisible() && camEvent->data().isValid()) if(camEvent->data().isValid())
{ {
processingImages_ = true; if(!processingImages_ && this->isVisible() && camEvent->data().isValid())
QMetaObject::invokeMethod(this, "showImage", {
Q_ARG(rtabmap::SensorData, camEvent->data())); processingImages_ = true;
QMetaObject::invokeMethod(this, "showImage",
Q_ARG(rtabmap::SensorData, camEvent->data()));
}
} }
} }
} }
+12 -17
View File
@@ -3544,9 +3544,8 @@ void DatabaseViewer::refineConstraint(int from, int to, bool silent, bool update
} }
} }
float variance = -1.0f;
Transform transform; Transform transform;
RegistrationInfo info;
SensorData dataFrom, dataTo; SensorData dataFrom, dataTo;
dbDriver_->getNodeData(currentLink.from(), dataFrom); dbDriver_->getNodeData(currentLink.from(), dataFrom);
@@ -3582,12 +3581,12 @@ void DatabaseViewer::refineConstraint(int from, int to, bool silent, bool update
UINFO("Uncompress time: %f s", timer.ticks()); UINFO("Uncompress time: %f s", timer.ticks());
RegistrationIcp registration(parameters); RegistrationIcp registration(parameters);
transform = registration.computeTransformation(dataFrom, dataTo, t, 0, 0, &variance); transform = registration.computeTransformation(dataFrom, dataTo, t, &info);
UINFO("Icp time: %f s", timer.ticks()); UINFO("Icp time: %f s", timer.ticks());
if(!transform.isNull()) if(!transform.isNull())
{ {
Link newLink(currentLink.from(), currentLink.to(), currentLink.type(), transform, variance, variance); Link newLink(currentLink.from(), currentLink.to(), currentLink.type(), transform, info.variance, info.variance);
bool updated = false; bool updated = false;
std::multimap<int, Link>::iterator iter = linksRefined_.find(currentLink.from()); std::multimap<int, Link>::iterator iter = linksRefined_.find(currentLink.from());
@@ -3652,9 +3651,7 @@ void DatabaseViewer::refineConstraintVisually(int from, int to, bool silent, boo
ParametersMap parameters = ui_->parameters_toolbox->getParameters(); ParametersMap parameters = ui_->parameters_toolbox->getParameters();
Transform t; Transform t;
std::string rejectedMsg; RegistrationInfo info;
float variance = -1.0f;
std::vector<int> inliers;
// Add sensor data to generate features // Add sensor data to generate features
SensorData dataFrom; SensorData dataFrom;
@@ -3669,7 +3666,7 @@ void DatabaseViewer::refineConstraintVisually(int from, int to, bool silent, boo
RegistrationVis reg(parameters); RegistrationVis reg(parameters);
Signature fromS(dataFrom); Signature fromS(dataFrom);
Signature toS(dataTo); Signature toS(dataTo);
t = reg.computeTransformationMod(fromS, toS, currentLink.transform(), &rejectedMsg, &inliers, &variance); t = reg.computeTransformationMod(fromS, toS, currentLink.transform(), &info);
UDEBUG(""); UDEBUG("");
if(!silent) if(!silent)
@@ -3681,7 +3678,7 @@ void DatabaseViewer::refineConstraintVisually(int from, int to, bool silent, boo
if(!t.isNull()) if(!t.isNull())
{ {
Link newLink(currentLink.from(), currentLink.to(), currentLink.type(), t, variance, variance); Link newLink(currentLink.from(), currentLink.to(), currentLink.type(), t, info.variance, info.variance);
bool updated = false; bool updated = false;
std::multimap<int, Link>::iterator iter = linksRefined_.find(currentLink.from()); std::multimap<int, Link>::iterator iter = linksRefined_.find(currentLink.from());
@@ -3714,7 +3711,7 @@ void DatabaseViewer::refineConstraintVisually(int from, int to, bool silent, boo
{ {
QMessageBox::warning(this, QMessageBox::warning(this,
tr("Add link"), tr("Add link"),
tr("Cannot find a transformation between nodes %1 and %2: %3").arg(from).arg(to).arg(rejectedMsg.c_str())); tr("Cannot find a transformation between nodes %1 and %2: %3").arg(from).arg(to).arg(info.rejectedMsg_.c_str()));
} }
} }
@@ -3743,9 +3740,7 @@ bool DatabaseViewer::addConstraint(int from, int to, bool silent, bool updateGra
ParametersMap parameters = ui_->parameters_toolbox->getParameters(); ParametersMap parameters = ui_->parameters_toolbox->getParameters();
Transform t; Transform t;
std::string rejectedMsg; RegistrationInfo info;
float variance = -1.0f;
std::vector<int> inliers;
// Add sensor data to generate features // Add sensor data to generate features
SensorData dataFrom; SensorData dataFrom;
@@ -3760,7 +3755,7 @@ bool DatabaseViewer::addConstraint(int from, int to, bool silent, bool updateGra
RegistrationVis reg(parameters); RegistrationVis reg(parameters);
Signature fromS(dataFrom); Signature fromS(dataFrom);
Signature toS(dataTo); Signature toS(dataTo);
t = reg.computeTransformationMod(fromS, toS, Transform::getIdentity(), &rejectedMsg, &inliers, &variance); t = reg.computeTransformationMod(fromS, toS, Transform::getIdentity(), &info);
UDEBUG(""); UDEBUG("");
if(!silent) if(!silent)
@@ -3775,11 +3770,11 @@ bool DatabaseViewer::addConstraint(int from, int to, bool silent, bool updateGra
// transform is valid, make a link // transform is valid, make a link
if(from>to) if(from>to)
{ {
linksAdded_.insert(std::make_pair(from, Link(from, to, Link::kUserClosure, t, variance, variance))); linksAdded_.insert(std::make_pair(from, Link(from, to, Link::kUserClosure, t, info.variance, info.variance)));
} }
else else
{ {
linksAdded_.insert(std::make_pair(to, Link(to, from, Link::kUserClosure, t.inverse(), variance, variance))); linksAdded_.insert(std::make_pair(to, Link(to, from, Link::kUserClosure, t.inverse(), info.variance, info.variance)));
} }
updateSlider = true; updateSlider = true;
} }
@@ -3787,7 +3782,7 @@ bool DatabaseViewer::addConstraint(int from, int to, bool silent, bool updateGra
{ {
QMessageBox::warning(this, QMessageBox::warning(this,
tr("Add link"), tr("Add link"),
tr("Cannot find a transformation between nodes %1 and %2: %3").arg(from).arg(to).arg(rejectedMsg.c_str())); tr("Cannot find a transformation between nodes %1 and %2: %3").arg(from).arg(to).arg(info.rejectedMsg_.c_str()));
} }
} }
else if(containsLink(linksRemoved_, from, to)) else if(containsLink(linksRemoved_, from, to))
+12 -13
View File
@@ -735,9 +735,10 @@ void MainWindow::handleEvent(UEvent* anEvent)
void MainWindow::processCameraInfo(const rtabmap::CameraInfo & info) void MainWindow::processCameraInfo(const rtabmap::CameraInfo & info)
{ {
_ui->statsToolBox->updateStat("Camera/Time capturing/ms", (float)info.id_, (float)info.timeCapture_*1000.0); _ui->statsToolBox->updateStat("Camera/Time capturing/ms", (float)info.id, (float)info.timeCapture*1000.0);
_ui->statsToolBox->updateStat("Camera/Time disparity/ms", (float)info.id_, (float)info.timeDisparity_*1000.0); _ui->statsToolBox->updateStat("Camera/Time disparity/ms", (float)info.id, (float)info.timeDisparity*1000.0);
_ui->statsToolBox->updateStat("Camera/Time mirroring/ms", (float)info.id_, (float)info.timeMirroring_*1000.0); _ui->statsToolBox->updateStat("Camera/Time mirroring/ms", (float)info.id, (float)info.timeMirroring*1000.0);
_ui->statsToolBox->updateStat("Camera/Time scan from depth/ms", (float)info.id, (float)info.timeScanFromDepth*1000.0);
} }
void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom) void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom)
@@ -3014,6 +3015,7 @@ void MainWindow::startDetection()
_camera->setMirroringEnabled(_preferencesDialog->isSourceMirroring()); _camera->setMirroringEnabled(_preferencesDialog->isSourceMirroring());
_camera->setColorOnly(_preferencesDialog->isSourceRGBDColorOnly()); _camera->setColorOnly(_preferencesDialog->isSourceRGBDColorOnly());
_camera->setStereoToDepth(_preferencesDialog->isSourceStereoDepthGenerated()); _camera->setStereoToDepth(_preferencesDialog->isSourceStereoDepthGenerated());
_camera->setScanFromDepth(_preferencesDialog->isSourceScanFromDepth(), _preferencesDialog->getSourceScanFromDepthDecimation(), _preferencesDialog->getSourceScanFromDepthMaxDepth());
//Create odometry thread if rgbd slam //Create odometry thread if rgbd slam
if(uStr2Bool(parameters.at(Parameters::kRGBDEnabled()).c_str())) if(uStr2Bool(parameters.at(Parameters::kRGBDEnabled()).c_str()))
@@ -3527,18 +3529,16 @@ void MainWindow::postProcessing()
} }
Transform transform; Transform transform;
std::string rejectedMsg; RegistrationInfo info;
float variance = -1.0f;
RegistrationVis registration(parameters); RegistrationVis registration(parameters);
std::vector<int> inliers; transform = registration.computeTransformation(signatureFrom, signatureTo, Transform(), &info);
transform = registration.computeTransformation(signatureFrom, signatureTo, Transform(), &rejectedMsg, &inliers, &variance);
if(!transform.isNull()) if(!transform.isNull())
{ {
UINFO("Added new loop closure between %d and %d.", from, to); UINFO("Added new loop closure between %d and %d.", from, to);
addedLinks.insert(from); addedLinks.insert(from);
addedLinks.insert(to); addedLinks.insert(to);
_currentLinksMap.insert(std::make_pair(from, Link(from, to, Link::kUserClosure, transform, variance, variance))); _currentLinksMap.insert(std::make_pair(from, Link(from, to, Link::kUserClosure, transform, info.variance, info.variance)));
++loopClosuresAdded; ++loopClosuresAdded;
_initProgressDialog->appendText(tr("Detected loop closure %1->%2! (%3/%4)").arg(from).arg(to).arg(i+1).arg(clusters.size())); _initProgressDialog->appendText(tr("Detected loop closure %1->%2! (%3/%4)").arg(from).arg(to).arg(i+1).arg(clusters.size()));
} }
@@ -3618,18 +3618,17 @@ void MainWindow::postProcessing()
if(!signatureFrom.sensorData().laserScanRaw().empty() && if(!signatureFrom.sensorData().laserScanRaw().empty() &&
!signatureTo.sensorData().laserScanRaw().empty()) !signatureTo.sensorData().laserScanRaw().empty())
{ {
std::string rejectedMsg; RegistrationInfo info;
float variance = -1.0f; Transform transform = regIcp.computeTransformation(signatureFrom.sensorData(), signatureTo.sensorData(), iter->second.transform(), &info);
Transform transform = regIcp.computeTransformation(signatureFrom.sensorData(), signatureTo.sensorData(), iter->second.transform(), &rejectedMsg, 0, &variance);
if(!transform.isNull()) if(!transform.isNull())
{ {
Link newLink(from, to, iter->second.type(), transform*iter->second.transform(), variance, variance); Link newLink(from, to, iter->second.type(), transform*iter->second.transform(), info.variance, info.variance);
iter->second = newLink; iter->second = newLink;
} }
else else
{ {
QString str = tr("Cannot refine link %1->%2 (%3").arg(from).arg(to).arg(rejectedMsg.c_str()); QString str = tr("Cannot refine link %1->%2 (%3").arg(from).arg(to).arg(info.rejectedMsg_.c_str());
_initProgressDialog->appendText(str, Qt::darkYellow); _initProgressDialog->appendText(str, Qt::darkYellow);
UWARN("%s", str.toStdString().c_str()); UWARN("%s", str.toStdString().c_str());
warn = true; warn = true;
+123 -173
View File
@@ -210,9 +210,9 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
// Default Driver // Default Driver
connect(_ui->comboBox_sourceType, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSourceGrpVisibility())); connect(_ui->comboBox_sourceType, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSourceGrpVisibility()));
connect(_ui->comboBox_cameraRGBD, SIGNAL(currentIndexChanged(int)), this, SLOT(updateRGBDCameraGroupBoxVisibility())); connect(_ui->comboBox_cameraRGBD, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSourceGrpVisibility()));
connect(_ui->source_comboBox_image_type, SIGNAL(currentIndexChanged(int)), this, SLOT(updateRGBCameraGroupBoxVisibility())); connect(_ui->source_comboBox_image_type, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSourceGrpVisibility()));
connect(_ui->comboBox_cameraStereo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateStereoCameraGroupBoxVisibility())); connect(_ui->comboBox_cameraStereo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSourceGrpVisibility()));
this->resetSettings(_ui->groupBox_source0); this->resetSettings(_ui->groupBox_source0);
_ui->predictionPlot->showLegend(false); _ui->predictionPlot->showLegend(false);
@@ -388,37 +388,27 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
connect(_ui->checkBox_freenect2EdgeAwareFiltering, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->checkBox_freenect2EdgeAwareFiltering, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->checkBox_freenect2NoiseFiltering, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->checkBox_freenect2NoiseFiltering, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->toolButton_cameraRGBDImages_timestamps, SIGNAL(clicked()), this, SLOT(selectSourceRGBDImagesStamps())); connect(_ui->toolButton_cameraImages_timestamps, SIGNAL(clicked()), this, SLOT(selectSourceImagesStamps()));
connect(_ui->lineEdit_cameraRGBDImages_timestamps, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->lineEdit_cameraImages_timestamps, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->toolButton_cameraRGBDImages_path_rgb, SIGNAL(clicked()), this, SLOT(selectSourceRGBDImagesPathRGB())); connect(_ui->toolButton_cameraRGBDImages_path_rgb, SIGNAL(clicked()), this, SLOT(selectSourceRGBDImagesPathRGB()));
connect(_ui->toolButton_cameraRGBDImages_path_depth, SIGNAL(clicked()), this, SLOT(selectSourceRGBDImagesPathDepth())); connect(_ui->toolButton_cameraRGBDImages_path_depth, SIGNAL(clicked()), this, SLOT(selectSourceRGBDImagesPathDepth()));
connect(_ui->toolButton_cameraRGBDImages_path_scans, SIGNAL(clicked()), this, SLOT(selectSourceRGBDImagesPathScans())); connect(_ui->toolButton_cameraImages_path_scans, SIGNAL(clicked()), this, SLOT(selectSourceImagesPathScans()));
connect(_ui->toolButton_cameraRGBDImages_gt, SIGNAL(clicked()), this, SLOT(selectSourceRGBDImagesPathGt())); connect(_ui->toolButton_cameraImages_gt, SIGNAL(clicked()), this, SLOT(selectSourceImagesPathGt()));
connect(_ui->lineEdit_cameraRGBDImages_path_rgb, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->lineEdit_cameraRGBDImages_path_rgb, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->lineEdit_cameraRGBDImages_path_depth, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->lineEdit_cameraRGBDImages_path_depth, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->checkBox_cameraRGBDImages_timestamps, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->checkBox_cameraImages_timestamps, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->doubleSpinBox_cameraRGBDImages_scale, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->doubleSpinBox_cameraRGBDImages_scale, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->lineEdit_cameraRGBDImages_path_scans, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->lineEdit_cameraImages_path_scans, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->lineEdit_cameraRGBDImages_laser_transform, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->lineEdit_cameraImages_laser_transform, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->spinBox_cameraRGBDImages_max_scan_pts, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->spinBox_cameraImages_max_scan_pts, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->lineEdit_cameraRGBDImages_gt, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->lineEdit_cameraImages_gt, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->comboBox_cameraRGBDImages_gtFormat, SIGNAL(currentIndexChanged(int)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->comboBox_cameraImages_gtFormat, SIGNAL(currentIndexChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->toolButton_cameraStereoImages_timestamps, SIGNAL(clicked()), this, SLOT(selectSourceStereoImagesStamps()));
connect(_ui->lineEdit_cameraStereoImages_timestamps, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->toolButton_cameraStereoImages_path_left, SIGNAL(clicked()), this, SLOT(selectSourceStereoImagesPathLeft())); connect(_ui->toolButton_cameraStereoImages_path_left, SIGNAL(clicked()), this, SLOT(selectSourceStereoImagesPathLeft()));
connect(_ui->toolButton_cameraStereoImages_path_right, SIGNAL(clicked()), this, SLOT(selectSourceStereoImagesPathRight())); connect(_ui->toolButton_cameraStereoImages_path_right, SIGNAL(clicked()), this, SLOT(selectSourceStereoImagesPathRight()));
connect(_ui->toolButton_cameraStereoImages_path_scans, SIGNAL(clicked()), this, SLOT(selectSourceStereoImagesPathScans()));
connect(_ui->toolButton_cameraStereoImages_gt, SIGNAL(clicked()), this, SLOT(selectSourceStereoImagesPathGt()));
connect(_ui->lineEdit_cameraStereoImages_path_left, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->lineEdit_cameraStereoImages_path_left, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->lineEdit_cameraStereoImages_path_right, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->lineEdit_cameraStereoImages_path_right, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->lineEdit_cameraStereoImages_path_scans, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->lineEdit_cameraStereoImages_laser_transform, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->spinBox_cameraStereoImages_max_scan_pts, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->checkBox_stereoImages_timestamps, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->checkBox_stereoImages_rectify, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->checkBox_stereoImages_rectify, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->lineEdit_cameraStereoImages_gt, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->comboBox_cameraStereoImages_gtFormat, SIGNAL(currentIndexChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->toolButton_cameraStereoVideo_path, SIGNAL(clicked()), this, SLOT(selectSourceStereoVideoPath())); connect(_ui->toolButton_cameraStereoVideo_path, SIGNAL(clicked()), this, SLOT(selectSourceStereoVideoPath()));
connect(_ui->lineEdit_cameraStereoVideo_path, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->lineEdit_cameraStereoVideo_path, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
@@ -433,7 +423,9 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
connect(_ui->lineEdit_openniOniPath, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->lineEdit_openniOniPath, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->lineEdit_openni2OniPath, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->lineEdit_openni2OniPath, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->groupBox_scanFromDepth, SIGNAL(toggled(bool)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->spinBox_cameraScanFromDepth_decimation, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->doubleSpinBox_cameraSCanFromDepth_maxDepth, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteSourcePanel()));
//Rtabmap basic //Rtabmap basic
connect(_ui->general_doubleSpinBox_timeThr, SIGNAL(valueChanged(double)), _ui->general_doubleSpinBox_timeThr_2, SLOT(setValue(double))); connect(_ui->general_doubleSpinBox_timeThr, SIGNAL(valueChanged(double)), _ui->general_doubleSpinBox_timeThr_2, SLOT(setValue(double)));
@@ -637,7 +629,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->loopClosure_bowInlierDistance->setObjectName(Parameters::kVisInlierDistance().c_str()); _ui->loopClosure_bowInlierDistance->setObjectName(Parameters::kVisInlierDistance().c_str());
_ui->loopClosure_bowIterations->setObjectName(Parameters::kVisIterations().c_str()); _ui->loopClosure_bowIterations->setObjectName(Parameters::kVisIterations().c_str());
_ui->loopClosure_bowRefineIterations->setObjectName(Parameters::kVisRefineIterations().c_str()); _ui->loopClosure_bowRefineIterations->setObjectName(Parameters::kVisRefineIterations().c_str());
_ui->loopClosure_bowForce2D->setObjectName(Parameters::kVisForce2D().c_str()); _ui->loopClosure_bowForce2D->setObjectName(Parameters::kRegForce3DoF().c_str());
_ui->loopClosure_estimationType->setObjectName(Parameters::kVisEstimationType().c_str()); _ui->loopClosure_estimationType->setObjectName(Parameters::kVisEstimationType().c_str());
connect(_ui->loopClosure_estimationType, SIGNAL(currentIndexChanged(int)), _ui->stackedWidget_loopClosureEstimation, SLOT(setCurrentIndex(int))); connect(_ui->loopClosure_estimationType, SIGNAL(currentIndexChanged(int)), _ui->stackedWidget_loopClosureEstimation, SLOT(setCurrentIndex(int)));
_ui->stackedWidget_loopClosureEstimation->setCurrentIndex(Parameters::defaultVisEstimationType()); _ui->stackedWidget_loopClosureEstimation->setCurrentIndex(Parameters::defaultVisEstimationType());
@@ -646,7 +638,9 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->loopClosure_pnpReprojError->setObjectName(Parameters::kVisPnPReprojError().c_str()); _ui->loopClosure_pnpReprojError->setObjectName(Parameters::kVisPnPReprojError().c_str());
_ui->loopClosure_pnpFlags->setObjectName(Parameters::kVisPnPFlags().c_str()); _ui->loopClosure_pnpFlags->setObjectName(Parameters::kVisPnPFlags().c_str());
_ui->loopClosure_pnpRefineIterations->setObjectName(Parameters::kVisPnPRefineIterations().c_str()); _ui->loopClosure_pnpRefineIterations->setObjectName(Parameters::kVisPnPRefineIterations().c_str());
_ui->loopClosure_bowVarianceFromInliersCount->setObjectName(Parameters::kRegVarianceFromInliersCount().c_str()); _ui->loopClosure_bowVarianceFromInliersCount->setObjectName(Parameters::kRegVarianceFromInliersCount().c_str());
_ui->comboBox_registrationStrategy->setObjectName(Parameters::kRegStrategy().c_str());
_ui->loopClosure_reextract->setObjectName(Parameters::kRGBDLoopClosureReextractFeatures().c_str()); _ui->loopClosure_reextract->setObjectName(Parameters::kRGBDLoopClosureReextractFeatures().c_str());
_ui->loopClosure_correspondencesType->setObjectName(Parameters::kVisCorType().c_str()); _ui->loopClosure_correspondencesType->setObjectName(Parameters::kVisCorType().c_str());
@@ -663,10 +657,8 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->subpix_iterations->setObjectName(Parameters::kVisSubPixIterations().c_str()); _ui->subpix_iterations->setObjectName(Parameters::kVisSubPixIterations().c_str());
_ui->subpix_eps->setObjectName(Parameters::kVisSubPixEps().c_str()); _ui->subpix_eps->setObjectName(Parameters::kVisSubPixEps().c_str());
_ui->loopClosure_icp->setObjectName(Parameters::kRGBDLoopClosureLinkRefining().c_str());
_ui->globalDetection_icpMaxTranslation->setObjectName(Parameters::kIcpMaxTranslation().c_str()); _ui->globalDetection_icpMaxTranslation->setObjectName(Parameters::kIcpMaxTranslation().c_str());
_ui->globalDetection_icpMaxRotation->setObjectName(Parameters::kIcpMaxRotation().c_str()); _ui->globalDetection_icpMaxRotation->setObjectName(Parameters::kIcpMaxRotation().c_str());
_ui->loopClosure_icp2D->setObjectName(Parameters::kIcp2D().c_str());
_ui->loopClosure_icpVoxelSize->setObjectName(Parameters::kIcpVoxelSize().c_str()); _ui->loopClosure_icpVoxelSize->setObjectName(Parameters::kIcpVoxelSize().c_str());
_ui->loopClosure_icpDownsamplingStep->setObjectName(Parameters::kIcpDownsamplingStep().c_str()); _ui->loopClosure_icpDownsamplingStep->setObjectName(Parameters::kIcpDownsamplingStep().c_str());
@@ -1193,28 +1185,26 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
_ui->lineEdit_openni2OniPath->clear(); _ui->lineEdit_openni2OniPath->clear();
_ui->lineEdit_cameraRGBDImages_path_rgb->setText(""); _ui->lineEdit_cameraRGBDImages_path_rgb->setText("");
_ui->lineEdit_cameraRGBDImages_path_depth->setText(""); _ui->lineEdit_cameraRGBDImages_path_depth->setText("");
_ui->checkBox_cameraRGBDImages_timestamps->setChecked(false);
_ui->doubleSpinBox_cameraRGBDImages_scale->setValue(1.0); _ui->doubleSpinBox_cameraRGBDImages_scale->setValue(1.0);
_ui->lineEdit_cameraRGBDImages_timestamps->setText("");
_ui->lineEdit_cameraRGBDImages_path_scans->setText("");
_ui->lineEdit_cameraRGBDImages_laser_transform->setText("0 0 0 0 0 0");
_ui->spinBox_cameraRGBDImages_max_scan_pts->setValue(0);
_ui->lineEdit_cameraRGBDImages_gt->setText("");
_ui->comboBox_cameraRGBDImages_gtFormat->setCurrentIndex(0);
_ui->source_comboBox_image_type->setCurrentIndex(kSrcDC1394-kSrcDC1394); _ui->source_comboBox_image_type->setCurrentIndex(kSrcDC1394-kSrcDC1394);
_ui->lineEdit_cameraStereoImages_timestamps->setText("");
_ui->lineEdit_cameraStereoImages_path_left->setText(""); _ui->lineEdit_cameraStereoImages_path_left->setText("");
_ui->lineEdit_cameraStereoImages_path_right->setText(""); _ui->lineEdit_cameraStereoImages_path_right->setText("");
_ui->lineEdit_cameraStereoImages_path_scans->setText("");
_ui->lineEdit_cameraStereoImages_laser_transform->setText("0 0 0 0 0 0");
_ui->spinBox_cameraStereoImages_max_scan_pts->setValue(0);
_ui->checkBox_stereoImages_timestamps->setChecked(false);
_ui->checkBox_stereoImages_rectify->setChecked(false); _ui->checkBox_stereoImages_rectify->setChecked(false);
_ui->lineEdit_cameraStereoVideo_path->setText(""); _ui->lineEdit_cameraStereoVideo_path->setText("");
_ui->checkBox_stereoVideo_rectify->setChecked(false); _ui->checkBox_stereoVideo_rectify->setChecked(false);
_ui->lineEdit_cameraStereoImages_gt->setText("");
_ui->comboBox_cameraStereoImages_gtFormat->setCurrentIndex(0); _ui->checkBox_cameraImages_timestamps->setChecked(false);
_ui->lineEdit_cameraImages_timestamps->setText("");
_ui->lineEdit_cameraImages_path_scans->setText("");
_ui->lineEdit_cameraImages_laser_transform->setText("0 0 0 0 0 0");
_ui->spinBox_cameraImages_max_scan_pts->setValue(0);
_ui->lineEdit_cameraImages_gt->setText("");
_ui->comboBox_cameraImages_gtFormat->setCurrentIndex(0);
_ui->groupBox_scanFromDepth->setChecked(false);
_ui->spinBox_cameraScanFromDepth_decimation->setValue(8);
_ui->doubleSpinBox_cameraSCanFromDepth_maxDepth->setValue(4.0);
} }
else if(groupBox->objectName() == _ui->groupBox_rtabmap_basic0->objectName()) else if(groupBox->objectName() == _ui->groupBox_rtabmap_basic0->objectName())
{ {
@@ -1491,27 +1481,13 @@ void PreferencesDialog::readCameraSettings(const QString & filePath)
settings.beginGroup("RGBDImages"); settings.beginGroup("RGBDImages");
_ui->lineEdit_cameraRGBDImages_path_rgb->setText(settings.value("path_rgb", _ui->lineEdit_cameraRGBDImages_path_rgb->text()).toString()); _ui->lineEdit_cameraRGBDImages_path_rgb->setText(settings.value("path_rgb", _ui->lineEdit_cameraRGBDImages_path_rgb->text()).toString());
_ui->lineEdit_cameraRGBDImages_path_depth->setText(settings.value("path_depth", _ui->lineEdit_cameraRGBDImages_path_depth->text()).toString()); _ui->lineEdit_cameraRGBDImages_path_depth->setText(settings.value("path_depth", _ui->lineEdit_cameraRGBDImages_path_depth->text()).toString());
_ui->checkBox_cameraRGBDImages_timestamps->setChecked(settings.value("filenames_as_stamps",_ui->checkBox_cameraRGBDImages_timestamps->isChecked()).toBool());
_ui->lineEdit_cameraRGBDImages_timestamps->setText(settings.value("stamps", _ui->lineEdit_cameraRGBDImages_timestamps->text()).toString());
_ui->doubleSpinBox_cameraRGBDImages_scale->setValue(settings.value("scale", _ui->doubleSpinBox_cameraRGBDImages_scale->value()).toDouble()); _ui->doubleSpinBox_cameraRGBDImages_scale->setValue(settings.value("scale", _ui->doubleSpinBox_cameraRGBDImages_scale->value()).toDouble());
_ui->lineEdit_cameraRGBDImages_path_scans->setText(settings.value("path_scans", _ui->lineEdit_cameraRGBDImages_path_scans->text()).toString());
_ui->lineEdit_cameraRGBDImages_laser_transform->setText(settings.value("scan_transform", _ui->lineEdit_cameraRGBDImages_laser_transform->text()).toString());
_ui->spinBox_cameraRGBDImages_max_scan_pts->setValue(settings.value("scan_max_pts", _ui->spinBox_cameraRGBDImages_max_scan_pts->value()).toInt());
_ui->lineEdit_cameraRGBDImages_gt->setText(settings.value("gt_path", _ui->lineEdit_cameraRGBDImages_gt->text()).toString());
_ui->comboBox_cameraRGBDImages_gtFormat->setCurrentIndex(settings.value("gt_format", _ui->comboBox_cameraRGBDImages_gtFormat->currentIndex()).toInt());
settings.endGroup(); // RGBDImages settings.endGroup(); // RGBDImages
settings.beginGroup("StereoImages"); settings.beginGroup("StereoImages");
_ui->lineEdit_cameraStereoImages_timestamps->setText(settings.value("stamps", _ui->lineEdit_cameraStereoImages_timestamps->text()).toString());
_ui->lineEdit_cameraStereoImages_path_left->setText(settings.value("path_left", _ui->lineEdit_cameraStereoImages_path_left->text()).toString()); _ui->lineEdit_cameraStereoImages_path_left->setText(settings.value("path_left", _ui->lineEdit_cameraStereoImages_path_left->text()).toString());
_ui->lineEdit_cameraStereoImages_path_right->setText(settings.value("path_right", _ui->lineEdit_cameraStereoImages_path_right->text()).toString()); _ui->lineEdit_cameraStereoImages_path_right->setText(settings.value("path_right", _ui->lineEdit_cameraStereoImages_path_right->text()).toString());
_ui->lineEdit_cameraStereoImages_path_scans->setText(settings.value("path_scans", _ui->lineEdit_cameraStereoImages_path_scans->text()).toString());
_ui->lineEdit_cameraStereoImages_laser_transform->setText(settings.value("scan_transform", _ui->lineEdit_cameraStereoImages_laser_transform->text()).toString());
_ui->spinBox_cameraStereoImages_max_scan_pts->setValue(settings.value("scan_max_pts", _ui->spinBox_cameraStereoImages_max_scan_pts->value()).toInt());
_ui->checkBox_stereoImages_timestamps->setChecked(settings.value("filenames_as_stamps",_ui->checkBox_stereoImages_timestamps->isChecked()).toBool());
_ui->checkBox_stereoImages_rectify->setChecked(settings.value("rectify",_ui->checkBox_stereoImages_rectify->isChecked()).toBool()); _ui->checkBox_stereoImages_rectify->setChecked(settings.value("rectify",_ui->checkBox_stereoImages_rectify->isChecked()).toBool());
_ui->lineEdit_cameraStereoImages_gt->setText(settings.value("gt_path", _ui->lineEdit_cameraStereoImages_gt->text()).toString());
_ui->comboBox_cameraStereoImages_gtFormat->setCurrentIndex(settings.value("gt_format", _ui->comboBox_cameraStereoImages_gtFormat->currentIndex()).toInt());
settings.endGroup(); // StereoImages settings.endGroup(); // StereoImages
settings.beginGroup("StereoVideo"); settings.beginGroup("StereoVideo");
@@ -1524,6 +1500,14 @@ void PreferencesDialog::readCameraSettings(const QString & filePath)
_ui->source_images_spinBox_startPos->setValue(settings.value("startPos",_ui->source_images_spinBox_startPos->value()).toInt()); _ui->source_images_spinBox_startPos->setValue(settings.value("startPos",_ui->source_images_spinBox_startPos->value()).toInt());
_ui->source_images_refreshDir->setChecked(settings.value("refreshDir",_ui->source_images_refreshDir->isChecked()).toBool()); _ui->source_images_refreshDir->setChecked(settings.value("refreshDir",_ui->source_images_refreshDir->isChecked()).toBool());
_ui->checkBox_rgbImages_rectify->setChecked(settings.value("rectify",_ui->checkBox_rgbImages_rectify->isChecked()).toBool()); _ui->checkBox_rgbImages_rectify->setChecked(settings.value("rectify",_ui->checkBox_rgbImages_rectify->isChecked()).toBool());
_ui->checkBox_cameraImages_timestamps->setChecked(settings.value("filenames_as_stamps",_ui->checkBox_cameraImages_timestamps->isChecked()).toBool());
_ui->lineEdit_cameraImages_timestamps->setText(settings.value("stamps", _ui->lineEdit_cameraImages_timestamps->text()).toString());
_ui->lineEdit_cameraImages_path_scans->setText(settings.value("path_scans", _ui->lineEdit_cameraImages_path_scans->text()).toString());
_ui->lineEdit_cameraImages_laser_transform->setText(settings.value("scan_transform", _ui->lineEdit_cameraImages_laser_transform->text()).toString());
_ui->spinBox_cameraImages_max_scan_pts->setValue(settings.value("scan_max_pts", _ui->spinBox_cameraImages_max_scan_pts->value()).toInt());
_ui->lineEdit_cameraImages_gt->setText(settings.value("gt_path", _ui->lineEdit_cameraImages_gt->text()).toString());
_ui->comboBox_cameraImages_gtFormat->setCurrentIndex(settings.value("gt_format", _ui->comboBox_cameraImages_gtFormat->currentIndex()).toInt());
settings.endGroup(); // images settings.endGroup(); // images
settings.beginGroup("Video"); settings.beginGroup("Video");
@@ -1531,6 +1515,12 @@ void PreferencesDialog::readCameraSettings(const QString & filePath)
_ui->checkBox_rgbVideo_rectify->setChecked(settings.value("rectify",_ui->checkBox_rgbVideo_rectify->isChecked()).toBool()); _ui->checkBox_rgbVideo_rectify->setChecked(settings.value("rectify",_ui->checkBox_rgbVideo_rectify->isChecked()).toBool());
settings.endGroup(); // video settings.endGroup(); // video
settings.beginGroup("ScanFromDepth");
_ui->groupBox_scanFromDepth->setChecked(settings.value("enabled", _ui->groupBox_scanFromDepth->isChecked()).toBool());
_ui->spinBox_cameraScanFromDepth_decimation->setValue(settings.value("decimation", _ui->spinBox_cameraScanFromDepth_decimation->value()).toInt());
_ui->doubleSpinBox_cameraSCanFromDepth_maxDepth->setValue(settings.value("maxDepth", _ui->doubleSpinBox_cameraSCanFromDepth_maxDepth->value()).toDouble());
settings.endGroup();//ScanFromDepth
settings.beginGroup("Database"); settings.beginGroup("Database");
_ui->source_database_lineEdit_path->setText(settings.value("path",_ui->source_database_lineEdit_path->text()).toString()); _ui->source_database_lineEdit_path->setText(settings.value("path",_ui->source_database_lineEdit_path->text()).toString());
_ui->source_checkBox_ignoreOdometry->setChecked(settings.value("ignoreOdometry", _ui->source_checkBox_ignoreOdometry->isChecked()).toBool()); _ui->source_checkBox_ignoreOdometry->setChecked(settings.value("ignoreOdometry", _ui->source_checkBox_ignoreOdometry->isChecked()).toBool());
@@ -1842,27 +1832,13 @@ void PreferencesDialog::writeCameraSettings(const QString & filePath) const
settings.beginGroup("RGBDImages"); settings.beginGroup("RGBDImages");
settings.setValue("path_rgb", _ui->lineEdit_cameraRGBDImages_path_rgb->text()); settings.setValue("path_rgb", _ui->lineEdit_cameraRGBDImages_path_rgb->text());
settings.setValue("path_depth", _ui->lineEdit_cameraRGBDImages_path_depth->text()); settings.setValue("path_depth", _ui->lineEdit_cameraRGBDImages_path_depth->text());
settings.setValue("filenames_as_stamps", _ui->checkBox_cameraRGBDImages_timestamps->isChecked());
settings.setValue("stamps", _ui->lineEdit_cameraRGBDImages_timestamps->text());
settings.setValue("scale", _ui->doubleSpinBox_cameraRGBDImages_scale->value()); settings.setValue("scale", _ui->doubleSpinBox_cameraRGBDImages_scale->value());
settings.setValue("path_scans", _ui->lineEdit_cameraRGBDImages_path_scans->text());
settings.setValue("scan_transform", _ui->lineEdit_cameraRGBDImages_laser_transform->text());
settings.setValue("scan_max_pts", _ui->spinBox_cameraRGBDImages_max_scan_pts->value());
settings.setValue("gt_path", _ui->lineEdit_cameraRGBDImages_gt->text());
settings.setValue("gt_format", _ui->comboBox_cameraRGBDImages_gtFormat->currentIndex());
settings.endGroup(); // RGBDImages settings.endGroup(); // RGBDImages
settings.beginGroup("StereoImages"); settings.beginGroup("StereoImages");
settings.setValue("stamps", _ui->lineEdit_cameraStereoImages_timestamps->text());
settings.setValue("path_left", _ui->lineEdit_cameraStereoImages_path_left->text()); settings.setValue("path_left", _ui->lineEdit_cameraStereoImages_path_left->text());
settings.setValue("path_right", _ui->lineEdit_cameraStereoImages_path_right->text()); settings.setValue("path_right", _ui->lineEdit_cameraStereoImages_path_right->text());
settings.setValue("path_scans", _ui->lineEdit_cameraStereoImages_path_scans->text());
settings.setValue("scan_transform", _ui->lineEdit_cameraStereoImages_laser_transform->text());
settings.setValue("scan_max_pts", _ui->spinBox_cameraStereoImages_max_scan_pts->value());
settings.setValue("filenames_as_stamps", _ui->checkBox_stereoImages_timestamps->isChecked());
settings.setValue("rectify", _ui->checkBox_stereoImages_rectify->isChecked()); settings.setValue("rectify", _ui->checkBox_stereoImages_rectify->isChecked());
settings.setValue("gt_path", _ui->lineEdit_cameraStereoImages_gt->text());
settings.setValue("gt_format", _ui->comboBox_cameraStereoImages_gtFormat->currentIndex());
settings.endGroup(); // StereoImages settings.endGroup(); // StereoImages
settings.beginGroup("StereoVideo"); settings.beginGroup("StereoVideo");
@@ -1875,6 +1851,13 @@ void PreferencesDialog::writeCameraSettings(const QString & filePath) const
settings.setValue("startPos", _ui->source_images_spinBox_startPos->value()); settings.setValue("startPos", _ui->source_images_spinBox_startPos->value());
settings.setValue("refreshDir", _ui->source_images_refreshDir->isChecked()); settings.setValue("refreshDir", _ui->source_images_refreshDir->isChecked());
settings.setValue("rectify", _ui->checkBox_rgbImages_rectify->isChecked()); settings.setValue("rectify", _ui->checkBox_rgbImages_rectify->isChecked());
settings.setValue("filenames_as_stamps", _ui->checkBox_cameraImages_timestamps->isChecked());
settings.setValue("stamps", _ui->lineEdit_cameraImages_timestamps->text());
settings.setValue("path_scans", _ui->lineEdit_cameraImages_path_scans->text());
settings.setValue("scan_transform", _ui->lineEdit_cameraImages_laser_transform->text());
settings.setValue("scan_max_pts", _ui->spinBox_cameraImages_max_scan_pts->value());
settings.setValue("gt_path", _ui->lineEdit_cameraImages_gt->text());
settings.setValue("gt_format", _ui->comboBox_cameraImages_gtFormat->currentIndex());
settings.endGroup(); // images settings.endGroup(); // images
settings.beginGroup("Video"); settings.beginGroup("Video");
@@ -1882,6 +1865,12 @@ void PreferencesDialog::writeCameraSettings(const QString & filePath) const
settings.setValue("rectify", _ui->checkBox_rgbVideo_rectify->isChecked()); settings.setValue("rectify", _ui->checkBox_rgbVideo_rectify->isChecked());
settings.endGroup(); // video settings.endGroup(); // video
settings.beginGroup("ScanFromDepth");
settings.setValue("enabled", _ui->groupBox_scanFromDepth->isChecked());
settings.setValue("decimation", _ui->spinBox_cameraScanFromDepth_decimation->value());
settings.setValue("maxDepth", _ui->doubleSpinBox_cameraSCanFromDepth_maxDepth->value());
settings.endGroup();
settings.beginGroup("Database"); settings.beginGroup("Database");
settings.setValue("path", _ui->source_database_lineEdit_path->text()); settings.setValue("path", _ui->source_database_lineEdit_path->text());
settings.setValue("ignoreOdometry", _ui->source_checkBox_ignoreOdometry->isChecked()); settings.setValue("ignoreOdometry", _ui->source_checkBox_ignoreOdometry->isChecked());
@@ -2454,9 +2443,9 @@ void PreferencesDialog::selectCalibrationPath()
} }
} }
void PreferencesDialog::selectSourceRGBDImagesStamps() void PreferencesDialog::selectSourceImagesStamps()
{ {
QString dir = _ui->lineEdit_cameraRGBDImages_timestamps->text(); QString dir = _ui->lineEdit_cameraImages_timestamps->text();
if(dir.isEmpty()) if(dir.isEmpty())
{ {
dir = getWorkingDirectory(); dir = getWorkingDirectory();
@@ -2464,7 +2453,7 @@ void PreferencesDialog::selectSourceRGBDImagesStamps()
QString path = QFileDialog::getOpenFileName(this, tr("Select file"), dir, tr("Timestamps file (*.txt)")); QString path = QFileDialog::getOpenFileName(this, tr("Select file"), dir, tr("Timestamps file (*.txt)"));
if(path.size()) if(path.size())
{ {
_ui->lineEdit_cameraRGBDImages_timestamps->setText(path); _ui->lineEdit_cameraImages_timestamps->setText(path);
} }
} }
@@ -2483,9 +2472,9 @@ void PreferencesDialog::selectSourceRGBDImagesPathRGB()
} }
void PreferencesDialog::selectSourceRGBDImagesPathScans() void PreferencesDialog::selectSourceImagesPathScans()
{ {
QString dir = _ui->lineEdit_cameraRGBDImages_path_scans->text(); QString dir = _ui->lineEdit_cameraImages_path_scans->text();
if(dir.isEmpty()) if(dir.isEmpty())
{ {
dir = getWorkingDirectory(); dir = getWorkingDirectory();
@@ -2493,7 +2482,7 @@ void PreferencesDialog::selectSourceRGBDImagesPathScans()
QString path = QFileDialog::getExistingDirectory(this, tr("Select scans directory"), dir); QString path = QFileDialog::getExistingDirectory(this, tr("Select scans directory"), dir);
if(path.size()) if(path.size())
{ {
_ui->lineEdit_cameraRGBDImages_path_scans->setText(path); _ui->lineEdit_cameraImages_path_scans->setText(path);
} }
} }
@@ -2511,9 +2500,9 @@ void PreferencesDialog::selectSourceRGBDImagesPathDepth()
} }
} }
void PreferencesDialog::selectSourceRGBDImagesPathGt() void PreferencesDialog::selectSourceImagesPathGt()
{ {
QString dir = _ui->lineEdit_cameraRGBDImages_gt->text(); QString dir = _ui->lineEdit_cameraImages_gt->text();
if(dir.isEmpty()) if(dir.isEmpty())
{ {
dir = getWorkingDirectory(); dir = getWorkingDirectory();
@@ -2522,33 +2511,19 @@ void PreferencesDialog::selectSourceRGBDImagesPathGt()
if(path.size()) if(path.size())
{ {
QStringList list; QStringList list;
for(int i=0; i<_ui->comboBox_cameraRGBDImages_gtFormat->count(); ++i) for(int i=0; i<_ui->comboBox_cameraImages_gtFormat->count(); ++i)
{ {
list.push_back(_ui->comboBox_cameraRGBDImages_gtFormat->itemText(i)); list.push_back(_ui->comboBox_cameraImages_gtFormat->itemText(i));
} }
QString item = QInputDialog::getItem(this, tr("Ground Truth Format"), tr("Format:"), list, 0, false); QString item = QInputDialog::getItem(this, tr("Ground Truth Format"), tr("Format:"), list, 0, false);
if(!item.isEmpty()) if(!item.isEmpty())
{ {
_ui->lineEdit_cameraRGBDImages_gt->setText(path); _ui->lineEdit_cameraImages_gt->setText(path);
_ui->comboBox_cameraRGBDImages_gtFormat->setCurrentIndex(_ui->comboBox_cameraRGBDImages_gtFormat->findText(item)); _ui->comboBox_cameraImages_gtFormat->setCurrentIndex(_ui->comboBox_cameraImages_gtFormat->findText(item));
} }
} }
} }
void PreferencesDialog::selectSourceStereoImagesStamps()
{
QString dir = _ui->lineEdit_cameraStereoImages_timestamps->text();
if(dir.isEmpty())
{
dir = getWorkingDirectory();
}
QString path = QFileDialog::getOpenFileName(this, tr("Select file"), dir, tr("Timestamps file (*.txt)"));
if(path.size())
{
_ui->lineEdit_cameraStereoImages_timestamps->setText(path);
}
}
void PreferencesDialog::selectSourceStereoImagesPathLeft() void PreferencesDialog::selectSourceStereoImagesPathLeft()
{ {
QString dir = _ui->lineEdit_cameraStereoImages_path_left->text(); QString dir = _ui->lineEdit_cameraStereoImages_path_left->text();
@@ -2577,44 +2552,6 @@ void PreferencesDialog::selectSourceStereoImagesPathRight()
} }
} }
void PreferencesDialog::selectSourceStereoImagesPathScans()
{
QString dir = _ui->lineEdit_cameraStereoImages_path_scans->text();
if(dir.isEmpty())
{
dir = getWorkingDirectory();
}
QString path = QFileDialog::getExistingDirectory(this, tr("Select scans directory"), dir);
if(path.size())
{
_ui->lineEdit_cameraStereoImages_path_scans->setText(path);
}
}
void PreferencesDialog::selectSourceStereoImagesPathGt()
{
QString dir = _ui->lineEdit_cameraStereoImages_gt->text();
if(dir.isEmpty())
{
dir = getWorkingDirectory();
}
QString path = QFileDialog::getOpenFileName(this, tr("Select file"), dir, tr("Ground Truth (*.txt)"));
if(path.size())
{
QStringList list;
for(int i=0; i<_ui->comboBox_cameraStereoImages_gtFormat->count(); ++i)
{
list.push_back(_ui->comboBox_cameraStereoImages_gtFormat->itemText(i));
}
QString item = QInputDialog::getItem(this, tr("Ground Truth Format"), tr("Format:"), list);
if(!item.isEmpty())
{
_ui->lineEdit_cameraStereoImages_gt->setText(path);
_ui->comboBox_cameraStereoImages_gtFormat->setCurrentIndex(_ui->comboBox_cameraStereoImages_gtFormat->findText(item));
}
}
}
void PreferencesDialog::selectSourceImagesPath() void PreferencesDialog::selectSourceImagesPath()
{ {
QString dir = _ui->source_images_lineEdit_path->text(); QString dir = _ui->source_images_lineEdit_path->text();
@@ -2935,6 +2872,11 @@ void PreferencesDialog::addParameter(const QObject * object, int value)
this->addParameter(_ui->graphOptimization_stopEpsilon, _ui->graphOptimization_stopEpsilon->value()); this->addParameter(_ui->graphOptimization_stopEpsilon, _ui->graphOptimization_stopEpsilon->value());
this->addParameter(_ui->graphOptimization_robust, _ui->graphOptimization_robust->isChecked()); this->addParameter(_ui->graphOptimization_robust, _ui->graphOptimization_robust->isChecked());
} }
else if(comboBox == _ui->comboBox_registrationStrategy)
{
this->addParameters(_ui->groupBox_visualTransform2);
this->addParameters(_ui->groupBox_icp2);
}
} }
// Add parameter // Add parameter
_parameters.insert(rtabmap::ParametersPair(object->objectName().toStdString(), QString::number(value).toStdString())); _parameters.insert(rtabmap::ParametersPair(object->objectName().toStdString(), QString::number(value).toStdString()));
@@ -2981,10 +2923,6 @@ void PreferencesDialog::addParameter(const QObject * object, bool value)
this->addParameters(_ui->groupBox_visualTransform2); this->addParameters(_ui->groupBox_visualTransform2);
this->addParameters(_ui->groupBox_icp2); this->addParameters(_ui->groupBox_icp2);
} }
else if(value && checkbox == _ui->loopClosure_icp)
{
this->addParameters(_ui->groupBox_icp2);
}
if(groupBox) if(groupBox)
{ {
@@ -3409,23 +3347,24 @@ void PreferencesDialog::updateSourceGrpVisibility()
_ui->groupBox_sourceStereo->setVisible(_ui->comboBox_sourceType->currentIndex() == 1); _ui->groupBox_sourceStereo->setVisible(_ui->comboBox_sourceType->currentIndex() == 1);
_ui->groupBox_sourceRGB->setVisible(_ui->comboBox_sourceType->currentIndex() == 2); _ui->groupBox_sourceRGB->setVisible(_ui->comboBox_sourceType->currentIndex() == 2);
_ui->groupBox_sourceDatabase->setVisible(_ui->comboBox_sourceType->currentIndex() == 3); _ui->groupBox_sourceDatabase->setVisible(_ui->comboBox_sourceType->currentIndex() == 3);
}
void PreferencesDialog::updateRGBDCameraGroupBoxVisibility() _ui->groupBox_scanFromDepth->setVisible(_ui->comboBox_sourceType->currentIndex() <= 1);
{
_ui->groupBox_openni2->setVisible(_ui->comboBox_cameraRGBD->currentIndex() == kSrcOpenNI2-kSrcOpenNI_PCL);
_ui->groupBox_freenect2->setVisible(_ui->comboBox_cameraRGBD->currentIndex() == kSrcFreenect2-kSrcOpenNI_PCL);
}
void PreferencesDialog::updateRGBCameraGroupBoxVisibility() _ui->stackedWidget_rgbd->setVisible(_ui->comboBox_sourceType->currentIndex() == 0 && (_ui->comboBox_cameraRGBD->currentIndex() == kSrcOpenNI2-kSrcRGBD || _ui->comboBox_cameraRGBD->currentIndex() == kSrcFreenect2-kSrcRGBD));
{ _ui->groupBox_openni2->setVisible(_ui->comboBox_sourceType->currentIndex() == 0 && _ui->comboBox_cameraRGBD->currentIndex() == kSrcOpenNI2-kSrcRGBD);
_ui->source_groupBox_images->setVisible(_ui->source_comboBox_image_type->currentIndex() == kSrcImages-kSrcUsbDevice); _ui->groupBox_freenect2->setVisible(_ui->comboBox_sourceType->currentIndex() == 0 && _ui->comboBox_cameraRGBD->currentIndex() == kSrcFreenect2-kSrcRGBD);
_ui->source_groupBox_video->setVisible(_ui->source_comboBox_image_type->currentIndex() == kSrcVideo-kSrcUsbDevice);
}
void PreferencesDialog::updateStereoCameraGroupBoxVisibility() _ui->stackedWidget_stereo->setVisible(_ui->comboBox_sourceType->currentIndex() == 1 && (_ui->comboBox_cameraStereo->currentIndex() == kSrcStereoVideo-kSrcStereo || _ui->comboBox_cameraStereo->currentIndex() == kSrcStereoImages-kSrcStereo));
{ _ui->groupBox_cameraStereoImages->setVisible(_ui->comboBox_sourceType->currentIndex() == 1 && _ui->comboBox_cameraStereo->currentIndex() == kSrcStereoImages-kSrcStereo);
_ui->groupBox_cameraStereoImages->setVisible(_ui->comboBox_cameraStereo->currentIndex() == kSrcStereoImages-kSrcDC1394);
_ui->stackedWidget_image->setVisible(_ui->comboBox_sourceType->currentIndex() == 2 && (_ui->source_comboBox_image_type->currentIndex() == kSrcImages-kSrcRGB || _ui->source_comboBox_image_type->currentIndex() == kSrcVideo-kSrcRGB));
_ui->source_groupBox_images->setVisible(_ui->comboBox_sourceType->currentIndex() == 2 && _ui->source_comboBox_image_type->currentIndex() == kSrcImages-kSrcRGB);
_ui->source_groupBox_video->setVisible(_ui->comboBox_sourceType->currentIndex() == 2 && _ui->source_comboBox_image_type->currentIndex() == kSrcVideo-kSrcRGB);
_ui->groupBox_sourceImages_optional->setVisible(
(_ui->comboBox_sourceType->currentIndex() == 0 && _ui->comboBox_cameraRGBD->currentIndex() == kSrcRGBDImages-kSrcRGBD) ||
(_ui->comboBox_sourceType->currentIndex() == 1 && _ui->comboBox_cameraStereo->currentIndex() == kSrcStereoImages-kSrcStereo) ||
(_ui->comboBox_sourceType->currentIndex() == 2 && _ui->comboBox_sourceType->currentIndex() == kSrcImages-kSrcRGB));
} }
/*** GETTERS ***/ /*** GETTERS ***/
@@ -3701,19 +3640,9 @@ Transform PreferencesDialog::getSourceLocalTransform() const
return t; return t;
} }
Transform PreferencesDialog::getStereoLaserLocalTransform() const Transform PreferencesDialog::getLaserLocalTransform() const
{ {
Transform t = Transform::fromString(_ui->lineEdit_cameraStereoImages_laser_transform->text().replace("PI_2", QString::number(3.141592/2.0)).toStdString()); Transform t = Transform::fromString(_ui->lineEdit_cameraImages_laser_transform->text().replace("PI_2", QString::number(3.141592/2.0)).toStdString());
if(t.isNull())
{
return Transform::getIdentity();
}
return t;
}
Transform PreferencesDialog::getRGBDLaserLocalTransform() const
{
Transform t = Transform::fromString(_ui->lineEdit_cameraRGBDImages_laser_transform->text().replace("PI_2", QString::number(3.141592/2.0)).toStdString());
if(t.isNull()) if(t.isNull())
{ {
return Transform::getIdentity(); return Transform::getIdentity();
@@ -3753,6 +3682,18 @@ bool PreferencesDialog::isSourceStereoDepthGenerated() const
{ {
return _ui->checkbox_stereo_depthGenerated->isChecked(); return _ui->checkbox_stereo_depthGenerated->isChecked();
} }
bool PreferencesDialog::isSourceScanFromDepth() const
{
return _ui->groupBox_scanFromDepth->isChecked();
}
int PreferencesDialog::getSourceScanFromDepthDecimation() const
{
return _ui->spinBox_cameraScanFromDepth_decimation->value();
}
double PreferencesDialog::getSourceScanFromDepthMaxDepth() const
{
return _ui->doubleSpinBox_cameraSCanFromDepth_maxDepth->value();
}
Camera * PreferencesDialog::createCamera(bool useRawImages) Camera * PreferencesDialog::createCamera(bool useRawImages)
{ {
@@ -3848,12 +3789,12 @@ Camera * PreferencesDialog::createCamera(bool useRawImages)
_ui->doubleSpinBox_cameraRGBDImages_scale->value(), _ui->doubleSpinBox_cameraRGBDImages_scale->value(),
this->getGeneralInputRate(), this->getGeneralInputRate(),
this->getSourceLocalTransform()); this->getSourceLocalTransform());
((CameraRGBDImages*)camera)->setGroundTruthPath(_ui->lineEdit_cameraRGBDImages_gt->text().toStdString(), _ui->comboBox_cameraRGBDImages_gtFormat->currentIndex()); ((CameraRGBDImages*)camera)->setGroundTruthPath(_ui->lineEdit_cameraImages_gt->text().toStdString(), _ui->comboBox_cameraImages_gtFormat->currentIndex());
((CameraRGBDImages*)camera)->setScanPath( ((CameraRGBDImages*)camera)->setScanPath(
_ui->lineEdit_cameraRGBDImages_path_scans->text().isEmpty()?"":_ui->lineEdit_cameraRGBDImages_path_scans->text().append(QDir::separator()).toStdString(), _ui->lineEdit_cameraImages_path_scans->text().isEmpty()?"":_ui->lineEdit_cameraImages_path_scans->text().append(QDir::separator()).toStdString(),
_ui->spinBox_cameraRGBDImages_max_scan_pts->value(), _ui->spinBox_cameraImages_max_scan_pts->value(),
this->getRGBDLaserLocalTransform()); this->getLaserLocalTransform());
((CameraRGBDImages*)camera)->setTimestamps(_ui->checkBox_cameraRGBDImages_timestamps->isChecked(), _ui->lineEdit_cameraRGBDImages_timestamps->text().toStdString()); ((CameraRGBDImages*)camera)->setTimestamps(_ui->checkBox_cameraImages_timestamps->isChecked(), _ui->lineEdit_cameraImages_timestamps->text().toStdString());
} }
else if(driver == kSrcDC1394) else if(driver == kSrcDC1394)
{ {
@@ -3885,12 +3826,12 @@ Camera * PreferencesDialog::createCamera(bool useRawImages)
_ui->checkBox_stereoImages_rectify->isChecked(), _ui->checkBox_stereoImages_rectify->isChecked(),
this->getGeneralInputRate(), this->getGeneralInputRate(),
this->getSourceLocalTransform()); this->getSourceLocalTransform());
((CameraStereoImages*)camera)->setGroundTruthPath(_ui->lineEdit_cameraStereoImages_gt->text().toStdString(), _ui->comboBox_cameraStereoImages_gtFormat->currentIndex()); ((CameraStereoImages*)camera)->setGroundTruthPath(_ui->lineEdit_cameraImages_gt->text().toStdString(), _ui->comboBox_cameraImages_gtFormat->currentIndex());
((CameraStereoImages*)camera)->setScanPath( ((CameraStereoImages*)camera)->setScanPath(
_ui->lineEdit_cameraStereoImages_path_scans->text().isEmpty()?"":_ui->lineEdit_cameraStereoImages_path_scans->text().append(QDir::separator()).toStdString(), _ui->lineEdit_cameraImages_path_scans->text().isEmpty()?"":_ui->lineEdit_cameraImages_path_scans->text().append(QDir::separator()).toStdString(),
_ui->spinBox_cameraStereoImages_max_scan_pts->value(), _ui->spinBox_cameraImages_max_scan_pts->value(),
this->getStereoLaserLocalTransform()); this->getLaserLocalTransform());
((CameraStereoImages*)camera)->setTimestamps(_ui->checkBox_stereoImages_timestamps->isChecked(), _ui->lineEdit_cameraStereoImages_timestamps->text().toStdString()); ((CameraStereoImages*)camera)->setTimestamps(_ui->checkBox_cameraImages_timestamps->isChecked(), _ui->lineEdit_cameraImages_timestamps->text().toStdString());
} }
else if(driver == kSrcStereoVideo) else if(driver == kSrcStereoVideo)
{ {
@@ -3925,6 +3866,13 @@ Camera * PreferencesDialog::createCamera(bool useRawImages)
((CameraImages*)camera)->setStartIndex(_ui->source_images_spinBox_startPos->value()); ((CameraImages*)camera)->setStartIndex(_ui->source_images_spinBox_startPos->value());
((CameraImages*)camera)->setDirRefreshed(_ui->source_images_refreshDir->isChecked()); ((CameraImages*)camera)->setDirRefreshed(_ui->source_images_refreshDir->isChecked());
((CameraImages*)camera)->setImagesRectified(_ui->checkBox_rgbImages_rectify->isChecked()); ((CameraImages*)camera)->setImagesRectified(_ui->checkBox_rgbImages_rectify->isChecked());
((CameraRGBDImages*)camera)->setGroundTruthPath(_ui->lineEdit_cameraImages_gt->text().toStdString(), _ui->comboBox_cameraImages_gtFormat->currentIndex());
((CameraRGBDImages*)camera)->setScanPath(
_ui->lineEdit_cameraImages_path_scans->text().isEmpty()?"":_ui->lineEdit_cameraImages_path_scans->text().append(QDir::separator()).toStdString(),
_ui->spinBox_cameraImages_max_scan_pts->value(),
this->getLaserLocalTransform());
((CameraRGBDImages*)camera)->setTimestamps(_ui->checkBox_cameraImages_timestamps->isChecked(), _ui->lineEdit_cameraImages_timestamps->text().toStdString());
} }
else if(driver == kSrcDatabase) else if(driver == kSrcDatabase)
{ {
@@ -4153,6 +4101,7 @@ void PreferencesDialog::testOdometry()
cameraThread.setMirroringEnabled(isSourceMirroring()); cameraThread.setMirroringEnabled(isSourceMirroring());
cameraThread.setColorOnly(_ui->checkbox_rgbd_colorOnly->isChecked()); cameraThread.setColorOnly(_ui->checkbox_rgbd_colorOnly->isChecked());
cameraThread.setStereoToDepth(_ui->checkbox_stereo_depthGenerated->isChecked()); cameraThread.setStereoToDepth(_ui->checkbox_stereo_depthGenerated->isChecked());
cameraThread.setScanFromDepth(_ui->groupBox_scanFromDepth->isChecked(), _ui->spinBox_cameraScanFromDepth_decimation->value(), _ui->doubleSpinBox_cameraSCanFromDepth_maxDepth->value());
UEventsManager::createPipe(&cameraThread, &odomThread, "CameraEvent"); UEventsManager::createPipe(&cameraThread, &odomThread, "CameraEvent");
UEventsManager::createPipe(&odomThread, odomViewer, "OdometryEvent"); UEventsManager::createPipe(&odomThread, odomViewer, "OdometryEvent");
UEventsManager::createPipe(odomViewer, &odomThread, "OdometryResetEvent"); UEventsManager::createPipe(odomViewer, &odomThread, "OdometryResetEvent");
@@ -4220,6 +4169,7 @@ void PreferencesDialog::testCamera()
cameraThread.setMirroringEnabled(isSourceMirroring()); cameraThread.setMirroringEnabled(isSourceMirroring());
cameraThread.setColorOnly(_ui->checkbox_rgbd_colorOnly->isChecked()); cameraThread.setColorOnly(_ui->checkbox_rgbd_colorOnly->isChecked());
cameraThread.setStereoToDepth(_ui->checkbox_stereo_depthGenerated->isChecked()); cameraThread.setStereoToDepth(_ui->checkbox_stereo_depthGenerated->isChecked());
cameraThread.setScanFromDepth(_ui->groupBox_scanFromDepth->isChecked(), _ui->spinBox_cameraScanFromDepth_decimation->value(), _ui->doubleSpinBox_cameraSCanFromDepth_maxDepth->value());
UEventsManager::createPipe(&cameraThread, window, "CameraEvent"); UEventsManager::createPipe(&cameraThread, window, "CameraEvent");
cameraThread.start(); cameraThread.start();
File diff suppressed because it is too large Load Diff
+10 -28
View File
@@ -29,7 +29,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/utilite/UEventsManager.h> #include <rtabmap/utilite/UEventsManager.h>
#include <rtabmap/utilite/UFile.h> #include <rtabmap/utilite/UFile.h>
#include <rtabmap/utilite/UConversion.h> #include <rtabmap/utilite/UConversion.h>
#include <rtabmap/core/OdometryICP.h>
#include <rtabmap/core/OdometryLocalMap.h> #include <rtabmap/core/OdometryLocalMap.h>
#include <rtabmap/core/OdometryF2F.h> #include <rtabmap/core/OdometryF2F.h>
#include <rtabmap/core/OdometryMono.h> #include <rtabmap/core/OdometryMono.h>
@@ -76,7 +75,6 @@ void showUsage()
"\n" "\n"
" -d # ICP decimation (default 4)\n" " -d # ICP decimation (default 4)\n"
" -v # ICP voxel size (default 0.005)\n" " -v # ICP voxel size (default 0.005)\n"
" -s # ICP samples (default 0, not used if voxel is set.)\n"
" -cr #.# ICP correspondence ratio (default 0.7)\n" " -cr #.# ICP correspondence ratio (default 0.7)\n"
" -p2p ICP point to point (default point to plane)" " -p2p ICP point to point (default point to plane)"
"\n" "\n"
@@ -117,7 +115,6 @@ int main (int argc, char * argv[])
int resetCountdown = rtabmap::Parameters::defaultOdomResetCountdown(); int resetCountdown = rtabmap::Parameters::defaultOdomResetCountdown();
int decimation = 4; int decimation = 4;
float voxel = 0.005; float voxel = 0.005;
int samples = 10000;
float ratio = 0.7f; float ratio = 0.7f;
int maxClouds = 10; int maxClouds = 10;
int briefBytes = rtabmap::Parameters::defaultBRIEFBytes(); int briefBytes = rtabmap::Parameters::defaultBRIEFBytes();
@@ -402,23 +399,6 @@ int main (int argc, char * argv[])
} }
continue; continue;
} }
if(strcmp(argv[i], "-s") == 0)
{
++i;
if(i < argc)
{
samples = std::atoi(argv[i]);
if(samples < 0)
{
showUsage();
}
}
else
{
showUsage();
}
continue;
}
if(strcmp(argv[i], "-cr") == 0) if(strcmp(argv[i], "-cr") == 0)
{ {
++i; ++i;
@@ -689,15 +669,13 @@ int main (int argc, char * argv[])
} }
else if(icp) // ICP else if(icp) // ICP
{ {
UINFO("ICP maximum correspondences distance = %f", distance); parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpMaxCorrespondenceDistance(), uNumber2Str(distance)));
UINFO("ICP iterations = %d", iterations); parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpIterations(), uNumber2Str(iterations)));
UINFO("Cloud decimation = %d", decimation); parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpVoxelSize(), uNumber2Str(voxel)));
UINFO("Cloud voxel size = %f", voxel); parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpCorrespondenceRatio(), uNumber2Str(ratio)));
UINFO("Cloud samples = %d", samples); parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpPointToPlane(), p2p?"false":"true"));
UINFO("Cloud correspondence ratio = %f", ratio);
UINFO("Cloud point to plane = %s", p2p?"false":"true");
odom = new rtabmap::OdometryICP(decimation, voxel, samples, distance, iterations, ratio, !p2p); odom = new rtabmap::OdometryF2F(parameters);
} }
rtabmap::OdometryThread odomThread(odom); rtabmap::OdometryThread odomThread(odom);
@@ -811,6 +789,10 @@ int main (int argc, char * argv[])
if(camera->isCalibrated()) if(camera->isCalibrated())
{ {
rtabmap::CameraThread cameraThread(camera); rtabmap::CameraThread cameraThread(camera);
if(icp)
{
cameraThread.setScanFromDepth(true, decimation, maxDepth);
}
odomThread.start(); odomThread.start();
cameraThread.start(); cameraThread.start();