mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-11 22:10:21 +08:00
libpointmatcher integration
This commit is contained in:
@@ -155,6 +155,7 @@ option(WITH_GTSAM "Include GTSAM support" ON)
|
||||
option(WITH_TORO "Include TORO support" ON)
|
||||
option(WITH_VERTIGO "Include Vertigo support" ON)
|
||||
option(WITH_CVSBA "Include cvsba support" ON)
|
||||
option(WITH_POINTMATCHER "Include libpointmatcher support" ON)
|
||||
option(WITH_FLYCAPTURE2 "Include FlyCapture2/Triclops support" ON)
|
||||
option(WITH_ZED "Include ZED sdk support" ON)
|
||||
option(WITH_REALSENSE "Include RealSense support" ON)
|
||||
@@ -302,6 +303,13 @@ IF(WITH_CVSBA)
|
||||
ENDIF(cvsba_FOUND)
|
||||
ENDIF(WITH_CVSBA)
|
||||
|
||||
IF(WITH_POINTMATCHER)
|
||||
find_package(libpointmatcher QUIET)
|
||||
IF(libpointmatcher_FOUND)
|
||||
MESSAGE(STATUS "Found libpointmatcher: ${libpointmatcher_INCLUDE_DIRS}")
|
||||
ENDIF(libpointmatcher_FOUND)
|
||||
ENDIF(WITH_POINTMATCHER)
|
||||
|
||||
IF(WITH_ZED)
|
||||
IF(WIN32) # Windows
|
||||
SET(ZED_INCLUDE_DIRS $ENV{ZED_INCLUDE_DIRS})
|
||||
@@ -471,6 +479,9 @@ IF(NOT cvsba_FOUND)
|
||||
ELSE()
|
||||
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${cvsba_LIBRARIES})
|
||||
ENDIF()
|
||||
IF(NOT libpointmatcher_FOUND)
|
||||
SET(POINTMATCHER "//")
|
||||
ENDIF(NOT libpointmatcher_FOUND)
|
||||
IF(NOT Freenect_FOUND)
|
||||
SET(FREENECT "//")
|
||||
ELSE()
|
||||
@@ -823,6 +834,14 @@ ELSE()
|
||||
MESSAGE(STATUS " With cvsba = NO (cvsba not found)")
|
||||
ENDIF()
|
||||
|
||||
IF(libpointmatcher_FOUND)
|
||||
MESSAGE(STATUS " With libpointmatcher = YES (License: BSD)")
|
||||
ELSEIF(NOT WITH_POINTMATCHER)
|
||||
MESSAGE(STATUS " With libpointmatcher = NO (WITH_POINTMATCHER=OFF)")
|
||||
ELSE()
|
||||
MESSAGE(STATUS " With libpointmatcher = NO (libpointmatcher not found)")
|
||||
ENDIF()
|
||||
|
||||
IF(ZED_FOUND)
|
||||
IF(CUDA_FOUND)
|
||||
MESSAGE(STATUS " With ZED = YES (With CUDA)")
|
||||
|
||||
@@ -47,6 +47,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@FREENECT@#define RTABMAP_FREENECT
|
||||
@FREENECT2@#define RTABMAP_FREENECT2
|
||||
@CVSBA@#define RTABMAP_CVSBA
|
||||
@POINTMATCHER@#define RTABMAP_POINTMATCHER
|
||||
@DC1394@#define RTABMAP_DC1394
|
||||
@FLYCAPTURE2@#define RTABMAP_FLYCAPTURE2
|
||||
@ZED@#define RTABMAP_ZED
|
||||
|
||||
@@ -512,6 +512,9 @@ class RTABMAP_EXP Parameters
|
||||
RTABMAP_PARAM(Icp, PointToPlane, bool, false, "Use point to plane ICP.");
|
||||
RTABMAP_PARAM(Icp, PointToPlaneNormalNeighbors, int, 20, "Number of neighbors to compute normals for point to plane.");
|
||||
|
||||
RTABMAP_PARAM(Icp, PM, bool, false, "Use libpointmatcher for ICP registration instead of PCL's implementation.");
|
||||
RTABMAP_PARAM_STR(Icp, PMConfig, "", uFormat("Configuration file (*.yaml) used by libpointmatcher. Note that data filters set for libpointmatcher are done after filtering done by rtabmap (i.e., %s, %s), so make sure to disable those in rtabmap if you want to use only those from libpointmatcher. Parameters %s, %s and %s are also ignored if configuration file is set.", kIcpVoxelSize().c_str(), kIcpDownsamplingStep().c_str(), kIcpIterations().c_str(), kIcpEpsilon().c_str(), kIcpMaxCorrespondenceDistance().c_str()).c_str());
|
||||
|
||||
// Stereo disparity
|
||||
RTABMAP_PARAM(Stereo, WinWidth, int, 15, "Window width.");
|
||||
RTABMAP_PARAM(Stereo, WinHeight, int, 3, "Window height.");
|
||||
|
||||
@@ -41,7 +41,7 @@ class RTABMAP_EXP RegistrationIcp : public Registration
|
||||
public:
|
||||
// take ownership of child
|
||||
RegistrationIcp(const ParametersMap & parameters = ParametersMap(), Registration * child = 0);
|
||||
virtual ~RegistrationIcp() {}
|
||||
virtual ~RegistrationIcp();
|
||||
|
||||
virtual void parseParameters(const ParametersMap & parameters);
|
||||
|
||||
@@ -65,6 +65,9 @@ private:
|
||||
float _correspondenceRatio;
|
||||
bool _pointToPlane;
|
||||
int _pointToPlaneNormalNeighbors;
|
||||
bool _libpointmatcher;
|
||||
std::string _libpointmatcherConfig;
|
||||
void * _libpointmatcherICP;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -243,6 +243,17 @@ IF(cvsba_FOUND)
|
||||
)
|
||||
ENDIF(cvsba_FOUND)
|
||||
|
||||
IF(libpointmatcher_FOUND)
|
||||
SET(INCLUDE_DIRS
|
||||
${INCLUDE_DIRS}
|
||||
${libpointmatcher_INCLUDE_DIRS}
|
||||
)
|
||||
SET(LIBRARIES
|
||||
${LIBRARIES}
|
||||
${libpointmatcher_LIBRARIES}
|
||||
)
|
||||
ENDIF(libpointmatcher_FOUND)
|
||||
|
||||
IF(ZED_FOUND)
|
||||
SET(INCLUDE_DIRS
|
||||
${INCLUDE_DIRS}
|
||||
|
||||
+394
-29
@@ -37,6 +37,176 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <rtabmap/utilite/UMath.h>
|
||||
#include <rtabmap/utilite/UTimer.h>
|
||||
#include <pcl/io/pcd_io.h>
|
||||
#include <pcl/io/vtk_io.h>
|
||||
#include <pcl/conversions.h>
|
||||
|
||||
#ifdef RTABMAP_POINTMATCHER
|
||||
#include "pointmatcher/PointMatcher.h"
|
||||
typedef PointMatcher<float> PM;
|
||||
typedef PM::DataPoints DP;
|
||||
|
||||
DP pclToDP(const pcl::PointCloud<pcl::PointXYZ>::Ptr & pclCloud)
|
||||
{
|
||||
typedef DP::Label Label;
|
||||
typedef DP::Labels Labels;
|
||||
typedef DP::View View;
|
||||
|
||||
if (pclCloud->empty())
|
||||
return DP();
|
||||
|
||||
// fill labels
|
||||
// conversions of descriptor fields from pcl
|
||||
// see http://www.ros.org/wiki/pcl/Overview
|
||||
Labels featLabels;
|
||||
Labels descLabels;
|
||||
std::vector<bool> isFeature;
|
||||
featLabels.push_back(Label("x", 1));
|
||||
isFeature.push_back(true);
|
||||
featLabels.push_back(Label("y", 1));
|
||||
isFeature.push_back(true);
|
||||
featLabels.push_back(Label("z", 1));
|
||||
isFeature.push_back(true);
|
||||
featLabels.push_back(Label("pad", 1));
|
||||
|
||||
// create cloud
|
||||
DP cloud(featLabels, descLabels, pclCloud->size());
|
||||
cloud.getFeatureViewByName("pad").setConstant(1);
|
||||
|
||||
// fill cloud
|
||||
View viewX(cloud.getFeatureViewByName("x"));
|
||||
View viewY(cloud.getFeatureViewByName("y"));
|
||||
View viewZ(cloud.getFeatureViewByName("z"));
|
||||
for(unsigned int i=0; i<pclCloud->size(); ++i)
|
||||
{
|
||||
viewX(0, i) = pclCloud->at(i).x;
|
||||
viewY(0, i) = pclCloud->at(i).y;
|
||||
viewZ(0, i) = pclCloud->at(i).z;
|
||||
}
|
||||
|
||||
return cloud;
|
||||
}
|
||||
|
||||
DP pclToDP(const pcl::PointCloud<pcl::PointNormal>::Ptr & pclCloud)
|
||||
{
|
||||
typedef DP::Label Label;
|
||||
typedef DP::Labels Labels;
|
||||
typedef DP::View View;
|
||||
|
||||
if (pclCloud->empty())
|
||||
return DP();
|
||||
|
||||
// fill labels
|
||||
// conversions of descriptor fields from pcl
|
||||
// see http://www.ros.org/wiki/pcl/Overview
|
||||
Labels featLabels;
|
||||
Labels descLabels;
|
||||
std::vector<bool> isFeature;
|
||||
featLabels.push_back(Label("x", 1));
|
||||
isFeature.push_back(true);
|
||||
featLabels.push_back(Label("y", 1));
|
||||
isFeature.push_back(true);
|
||||
featLabels.push_back(Label("z", 1));
|
||||
isFeature.push_back(true);
|
||||
|
||||
descLabels.push_back(Label("normals", 3));
|
||||
isFeature.push_back(false);
|
||||
isFeature.push_back(false);
|
||||
isFeature.push_back(false);
|
||||
|
||||
featLabels.push_back(Label("pad", 1));
|
||||
|
||||
// create cloud
|
||||
DP cloud(featLabels, descLabels, pclCloud->size());
|
||||
cloud.getFeatureViewByName("pad").setConstant(1);
|
||||
|
||||
// fill cloud
|
||||
View viewX(cloud.getFeatureViewByName("x"));
|
||||
View viewY(cloud.getFeatureViewByName("y"));
|
||||
View viewZ(cloud.getFeatureViewByName("z"));
|
||||
View viewNormalX(cloud.getDescriptorRowViewByName("normals",0));
|
||||
View viewNormalY(cloud.getDescriptorRowViewByName("normals",1));
|
||||
View viewNormalZ(cloud.getDescriptorRowViewByName("normals",2));
|
||||
for(unsigned int i=0; i<pclCloud->size(); ++i)
|
||||
{
|
||||
viewX(0, i) = pclCloud->at(i).x;
|
||||
viewY(0, i) = pclCloud->at(i).y;
|
||||
viewZ(0, i) = pclCloud->at(i).z;
|
||||
viewNormalX(0, i) = pclCloud->at(i).normal_x;
|
||||
viewNormalY(0, i) = pclCloud->at(i).normal_y;
|
||||
viewNormalZ(0, i) = pclCloud->at(i).normal_z;
|
||||
}
|
||||
|
||||
return cloud;
|
||||
}
|
||||
|
||||
void pclFromDP(const DP & cloud, pcl::PointCloud<pcl::PointXYZ> & pclCloud)
|
||||
{
|
||||
typedef DP::ConstView ConstView;
|
||||
|
||||
if (cloud.features.cols() == 0)
|
||||
return;
|
||||
|
||||
pclCloud.resize(cloud.features.cols());
|
||||
pclCloud.is_dense = true;
|
||||
|
||||
// fill cloud
|
||||
ConstView viewX(cloud.getFeatureViewByName("x"));
|
||||
ConstView viewY(cloud.getFeatureViewByName("y"));
|
||||
ConstView viewZ(cloud.getFeatureViewByName("z"));
|
||||
for(unsigned int i=0; i<pclCloud.size(); ++i)
|
||||
{
|
||||
pclCloud.at(i).x = viewX(0, i);
|
||||
pclCloud.at(i).y = viewY(0, i);
|
||||
pclCloud.at(i).z = viewZ(0, i);
|
||||
}
|
||||
}
|
||||
|
||||
void pclFromDP(const DP & cloud, pcl::PointCloud<pcl::PointNormal> & pclCloud)
|
||||
{
|
||||
typedef DP::ConstView ConstView;
|
||||
|
||||
if (cloud.features.cols() == 0)
|
||||
return;
|
||||
|
||||
pclCloud.resize(cloud.features.cols());
|
||||
pclCloud.is_dense = true;
|
||||
|
||||
// fill cloud
|
||||
ConstView viewX(cloud.getFeatureViewByName("x"));
|
||||
ConstView viewY(cloud.getFeatureViewByName("y"));
|
||||
ConstView viewZ(cloud.getFeatureViewByName("z"));
|
||||
ConstView viewNormalX(cloud.getDescriptorRowViewByName("normals",0));
|
||||
ConstView viewNormalY(cloud.getDescriptorRowViewByName("normals",1));
|
||||
ConstView viewNormalZ(cloud.getDescriptorRowViewByName("normals",2));
|
||||
for(unsigned int i=0; i<pclCloud.size(); ++i)
|
||||
{
|
||||
pclCloud.at(i).x = viewX(0, i);
|
||||
pclCloud.at(i).y = viewY(0, i);
|
||||
pclCloud.at(i).z = viewZ(0, i);
|
||||
pclCloud.at(i).normal_x = viewNormalX(0, i);
|
||||
pclCloud.at(i).normal_y = viewNormalY(0, i);
|
||||
pclCloud.at(i).normal_z = viewNormalZ(0, i);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename PointMatcher<T>::TransformationParameters eigenMatrixToDim(const typename PointMatcher<T>::TransformationParameters& matrix, int dimp1)
|
||||
{
|
||||
typedef typename PointMatcher<T>::TransformationParameters M;
|
||||
assert(matrix.rows() == matrix.cols());
|
||||
assert((matrix.rows() == 3) || (matrix.rows() == 4));
|
||||
assert((dimp1 == 3) || (dimp1 == 4));
|
||||
|
||||
if (matrix.rows() == dimp1)
|
||||
return matrix;
|
||||
|
||||
M out(M::Identity(dimp1,dimp1));
|
||||
out.topLeftCorner(2,2) = matrix.topLeftCorner(2,2);
|
||||
out.topRightCorner(2,1) = matrix.topRightCorner(2,1);
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
@@ -51,11 +221,24 @@ RegistrationIcp::RegistrationIcp(const ParametersMap & parameters, Registration
|
||||
_epsilon(Parameters::defaultIcpEpsilon()),
|
||||
_correspondenceRatio(Parameters::defaultIcpCorrespondenceRatio()),
|
||||
_pointToPlane(Parameters::defaultIcpPointToPlane()),
|
||||
_pointToPlaneNormalNeighbors(Parameters::defaultIcpPointToPlaneNormalNeighbors())
|
||||
_pointToPlaneNormalNeighbors(Parameters::defaultIcpPointToPlaneNormalNeighbors()),
|
||||
_libpointmatcher(Parameters::defaultIcpPM()),
|
||||
_libpointmatcherConfig(Parameters::defaultIcpPMConfig()),
|
||||
_libpointmatcherICP(0)
|
||||
{
|
||||
this->parseParameters(parameters);
|
||||
}
|
||||
|
||||
RegistrationIcp::~RegistrationIcp()
|
||||
{
|
||||
#ifdef RTABMAP_POINTMATCHER
|
||||
if(_libpointmatcherICP)
|
||||
{
|
||||
delete (PM::ICP*)_libpointmatcherICP;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void RegistrationIcp::parseParameters(const ParametersMap & parameters)
|
||||
{
|
||||
Registration::parseParameters(parameters);
|
||||
@@ -71,6 +254,81 @@ void RegistrationIcp::parseParameters(const ParametersMap & parameters)
|
||||
Parameters::parse(parameters, Parameters::kIcpPointToPlane(), _pointToPlane);
|
||||
Parameters::parse(parameters, Parameters::kIcpPointToPlaneNormalNeighbors(), _pointToPlaneNormalNeighbors);
|
||||
|
||||
Parameters::parse(parameters, Parameters::kIcpPM(), _libpointmatcher);
|
||||
Parameters::parse(parameters, Parameters::kIcpPMConfig(), _libpointmatcherConfig);
|
||||
#ifndef RTABMAP_POINTMATCHER
|
||||
if(_libpointmatcher)
|
||||
{
|
||||
UWARN("Parameter %s is set to true but RTAB-MAp has not been built with libpointmatcher support. Setting to false.", Parameters::kIcpPM().c_str());
|
||||
_libpointmatcher = false;
|
||||
}
|
||||
#else
|
||||
if(_libpointmatcher)
|
||||
{
|
||||
UINFO("libpointmatcher enabled! config=\"%s\"", _libpointmatcherConfig.c_str());
|
||||
if(_libpointmatcherICP!=0)
|
||||
{
|
||||
delete (PM::ICP*)_libpointmatcherICP;
|
||||
_libpointmatcherICP = 0;
|
||||
}
|
||||
|
||||
_libpointmatcherICP = new PM::ICP();
|
||||
|
||||
PM::ICP * icp = (PM::ICP*)_libpointmatcherICP;
|
||||
|
||||
bool useDefaults = true;
|
||||
if(!_libpointmatcherConfig.empty())
|
||||
{
|
||||
// load YAML config
|
||||
std::ifstream ifs(_libpointmatcherConfig.c_str());
|
||||
if (ifs.good())
|
||||
{
|
||||
icp->loadFromYaml(ifs);
|
||||
useDefaults = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("Cannot open libpointmatcher config file \"%s\", using default values instead.", _libpointmatcherConfig.c_str());
|
||||
}
|
||||
}
|
||||
if(useDefaults)
|
||||
{
|
||||
// Create the default ICP algorithm
|
||||
// See the implementation of setDefault() to create a custom ICP algorithm
|
||||
icp->setDefault();
|
||||
|
||||
icp->readingDataPointsFilters.clear();
|
||||
icp->readingDataPointsFilters.push_back(PM::get().DataPointsFilterRegistrar.create("IdentityDataPointsFilter"));
|
||||
|
||||
icp->referenceDataPointsFilters.clear();
|
||||
icp->referenceDataPointsFilters.push_back(PM::get().DataPointsFilterRegistrar.create("IdentityDataPointsFilter"));
|
||||
|
||||
PM::Parameters params;
|
||||
params["maxDist"] = uNumber2Str(_maxCorrespondenceDistance);
|
||||
icp->matcher.reset(PM::get().MatcherRegistrar.create("KDTreeMatcher", params));
|
||||
params.clear();
|
||||
|
||||
params["ratio"] = uNumber2Str(0.65); // For kinect cloud, 0.65 is better than 0.85
|
||||
icp->outlierFilters.clear();
|
||||
icp->outlierFilters.push_back(PM::get().OutlierFilterRegistrar.create("TrimmedDistOutlierFilter", params));
|
||||
params.clear();
|
||||
|
||||
icp->errorMinimizer.reset(PM::get().ErrorMinimizerRegistrar.create(_pointToPlane?"PointToPlaneErrorMinimizer":"PointToPointErrorMinimizer"));
|
||||
|
||||
icp->transformationCheckers.clear();
|
||||
params["maxIterationCount"] = uNumber2Str(_maxIterations);
|
||||
icp->transformationCheckers.push_back(PM::get().TransformationCheckerRegistrar.create("CounterTransformationChecker", params));
|
||||
params.clear();
|
||||
|
||||
params["minDiffRotErr"] = uNumber2Str(_epsilon*_epsilon*100.0f);
|
||||
params["minDiffTransErr"] = uNumber2Str(_epsilon*_epsilon);
|
||||
params["smoothLength"] = uNumber2Str(4);
|
||||
icp->transformationCheckers.push_back(PM::get().TransformationCheckerRegistrar.create("DifferentialTransformationChecker", params));
|
||||
params.clear();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
UASSERT_MSG(_voxelSize >= 0, uFormat("value=%d", _voxelSize).c_str());
|
||||
UASSERT_MSG(_downsamplingStep >= 0, uFormat("value=%d", _downsamplingStep).c_str());
|
||||
UASSERT_MSG(_maxCorrespondenceDistance > 0.0f, uFormat("value=%f", _maxCorrespondenceDistance).c_str());
|
||||
@@ -90,12 +348,13 @@ Transform RegistrationIcp::computeTransformationImpl(
|
||||
UDEBUG("Voxel size=%f", _voxelSize);
|
||||
UDEBUG("PointToPlane=%d", _pointToPlane?1:0);
|
||||
UDEBUG("Normal neighborhood=%d", _pointToPlaneNormalNeighbors);
|
||||
UDEBUG("Max corrrespondence distance=%f", _maxCorrespondenceDistance);
|
||||
UDEBUG("Max correspondence distance=%f", _maxCorrespondenceDistance);
|
||||
UDEBUG("Max Iterations=%d", _maxIterations);
|
||||
UDEBUG("Correspondence Ratio=%f", _correspondenceRatio);
|
||||
UDEBUG("Max translation=%f", _maxTranslation);
|
||||
UDEBUG("Max rotation=%f", _maxRotation);
|
||||
UDEBUG("Downsampling step=%d", _downsamplingStep);
|
||||
UDEBUG("libpointmatcher=%d", _libpointmatcher?1:0);
|
||||
|
||||
UTimer timer;
|
||||
std::string msg;
|
||||
@@ -149,15 +408,50 @@ Transform RegistrationIcp::computeTransformationImpl(
|
||||
|
||||
UDEBUG("Conversion time = %f s", timer.ticks());
|
||||
pcl::PointCloud<pcl::PointNormal>::Ptr fromCloudNormalsRegistered(new pcl::PointCloud<pcl::PointNormal>());
|
||||
icpT = util3d::icpPointToPlane(
|
||||
fromCloudNormals,
|
||||
toCloudNormals,
|
||||
_maxCorrespondenceDistance,
|
||||
_maxIterations,
|
||||
hasConverged,
|
||||
*fromCloudNormalsRegistered,
|
||||
_epsilon,
|
||||
this->force3DoF());
|
||||
#ifdef RTABMAP_POINTMATCHER
|
||||
if(_libpointmatcher)
|
||||
{
|
||||
// Load point clouds
|
||||
DP data = pclToDP(fromCloudNormals);
|
||||
DP ref = pclToDP(toCloudNormals);
|
||||
|
||||
// Compute the transformation to express data in ref
|
||||
PM::TransformationParameters T;
|
||||
try
|
||||
{
|
||||
UASSERT(_libpointmatcherICP != 0);
|
||||
PM::ICP & icp = *((PM::ICP*)_libpointmatcherICP);
|
||||
T = icp(data, ref);
|
||||
icpT = Transform::fromEigen3d(Eigen::Affine3d(Eigen::Matrix4d(eigenMatrixToDim<double>(T.template cast<double>(), 4))));
|
||||
|
||||
float matchRatio = icp.errorMinimizer->getWeightedPointUsedRatio();
|
||||
UDEBUG("match ratio: %f", matchRatio);
|
||||
|
||||
if(!icpT.isNull())
|
||||
{
|
||||
fromCloudNormalsRegistered = util3d::transformPointCloud(fromCloudNormals, icpT);
|
||||
hasConverged = true;
|
||||
}
|
||||
}
|
||||
catch(const std::exception & e)
|
||||
{
|
||||
UWARN("libpointmatcher has failed: %s", e.what());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
icpT = util3d::icpPointToPlane(
|
||||
fromCloudNormals,
|
||||
toCloudNormals,
|
||||
_maxCorrespondenceDistance,
|
||||
_maxIterations,
|
||||
hasConverged,
|
||||
*fromCloudNormalsRegistered,
|
||||
_epsilon,
|
||||
this->force3DoF());
|
||||
}
|
||||
|
||||
if(!icpT.isNull() && hasConverged)
|
||||
{
|
||||
util3d::computeVarianceAndCorrespondences(
|
||||
@@ -219,15 +513,52 @@ Transform RegistrationIcp::computeTransformationImpl(
|
||||
if(toCloudNormals->size() && fromCloudNormals->size())
|
||||
{
|
||||
pcl::PointCloud<pcl::PointNormal>::Ptr fromCloudNormalsRegistered(new pcl::PointCloud<pcl::PointNormal>());
|
||||
icpT = util3d::icpPointToPlane(
|
||||
fromCloudNormals,
|
||||
toCloudNormals,
|
||||
_maxCorrespondenceDistance,
|
||||
_maxIterations,
|
||||
hasConverged,
|
||||
*fromCloudNormalsRegistered,
|
||||
_epsilon,
|
||||
this->force3DoF());
|
||||
|
||||
#ifdef RTABMAP_POINTMATCHER
|
||||
if(_libpointmatcher)
|
||||
{
|
||||
// Load point clouds
|
||||
DP data = pclToDP(fromCloudNormals);
|
||||
DP ref = pclToDP(toCloudNormals);
|
||||
|
||||
// Compute the transformation to express data in ref
|
||||
PM::TransformationParameters T;
|
||||
try
|
||||
{
|
||||
UASSERT(_libpointmatcherICP != 0);
|
||||
PM::ICP & icp = *((PM::ICP*)_libpointmatcherICP);
|
||||
T = icp(data, ref);
|
||||
icpT = Transform::fromEigen3d(Eigen::Affine3d(Eigen::Matrix4d(eigenMatrixToDim<double>(T.template cast<double>(), 4))));
|
||||
|
||||
float matchRatio = icp.errorMinimizer->getWeightedPointUsedRatio();
|
||||
UDEBUG("match ratio: %f", matchRatio);
|
||||
|
||||
if(!icpT.isNull())
|
||||
{
|
||||
fromCloudNormalsRegistered = util3d::transformPointCloud(fromCloudNormals, icpT);
|
||||
hasConverged = true;
|
||||
}
|
||||
}
|
||||
catch(const std::exception & e)
|
||||
{
|
||||
UWARN("libpointmatcher has failed: %s", e.what());
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
icpT = util3d::icpPointToPlane(
|
||||
fromCloudNormals,
|
||||
toCloudNormals,
|
||||
_maxCorrespondenceDistance,
|
||||
_maxIterations,
|
||||
hasConverged,
|
||||
*fromCloudNormalsRegistered,
|
||||
_epsilon,
|
||||
this->force3DoF());
|
||||
}
|
||||
|
||||
|
||||
if(!icpT.isNull() && hasConverged)
|
||||
{
|
||||
util3d::computeVarianceAndCorrespondences(
|
||||
@@ -248,15 +579,49 @@ Transform RegistrationIcp::computeTransformationImpl(
|
||||
toSignature.sensorData().setLaserScanRaw(util3d::laserScanFromPointCloud(*toCloudFiltered, (guess*toLocalTransform).inverse()), LaserScanInfo(maxLaserScansTo, toSignature.sensorData().laserScanInfo().maxRange(), toLocalTransform));
|
||||
}
|
||||
|
||||
icpT = util3d::icp(
|
||||
fromCloudFiltered,
|
||||
toCloudFiltered,
|
||||
_maxCorrespondenceDistance,
|
||||
_maxIterations,
|
||||
hasConverged,
|
||||
*fromCloudRegistered,
|
||||
_epsilon,
|
||||
this->force3DoF()); // icp2D
|
||||
#ifdef RTABMAP_POINTMATCHER
|
||||
if(_libpointmatcher)
|
||||
{
|
||||
// Load point clouds
|
||||
DP data = pclToDP(fromCloudFiltered);
|
||||
DP ref = pclToDP(toCloudFiltered);
|
||||
|
||||
// Compute the transformation to express data in ref
|
||||
PM::TransformationParameters T;
|
||||
try
|
||||
{
|
||||
UASSERT(_libpointmatcherICP != 0);
|
||||
PM::ICP & icp = *((PM::ICP*)_libpointmatcherICP);
|
||||
T = icp(data, ref);
|
||||
icpT = Transform::fromEigen3d(Eigen::Affine3d(Eigen::Matrix4d(eigenMatrixToDim<double>(T.template cast<double>(), 4))));
|
||||
|
||||
float matchRatio = icp.errorMinimizer->getWeightedPointUsedRatio();
|
||||
UDEBUG("match ratio: %f", matchRatio);
|
||||
|
||||
if(!icpT.isNull())
|
||||
{
|
||||
fromCloudRegistered = util3d::transformPointCloud(fromCloudFiltered, icpT);
|
||||
hasConverged = true;
|
||||
}
|
||||
}
|
||||
catch(const std::exception & e)
|
||||
{
|
||||
UWARN("libpointmatcher has failed: %s", e.what());
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
icpT = util3d::icp(
|
||||
fromCloudFiltered,
|
||||
toCloudFiltered,
|
||||
_maxCorrespondenceDistance,
|
||||
_maxIterations,
|
||||
hasConverged,
|
||||
*fromCloudRegistered,
|
||||
_epsilon,
|
||||
this->force3DoF()); // icp2D
|
||||
}
|
||||
|
||||
if(!icpT.isNull() && hasConverged)
|
||||
{
|
||||
|
||||
@@ -306,6 +306,7 @@ private slots:
|
||||
void changeWorkingDirectory();
|
||||
void changeDictionaryPath();
|
||||
void changeOdometryORBSLAM2Vocabulary();
|
||||
void changeIcpPMConfigPath();
|
||||
void readSettingsEnd();
|
||||
void setupTreeView();
|
||||
void updateBasicParameter();
|
||||
|
||||
@@ -95,6 +95,14 @@ AboutDialog::AboutDialog(QWidget * parent) :
|
||||
_ui->label_cvsba->setText(Optimizer::isAvailable(Optimizer::kTypeCVSBA)?"Yes":"No");
|
||||
_ui->label_cvsba_license->setEnabled(Optimizer::isAvailable(Optimizer::kTypeCVSBA)?true:false);
|
||||
|
||||
#ifdef RTABMAP_POINTMATCHER
|
||||
_ui->label_libpointmatcher->setText("Yes");
|
||||
_ui->label_libpointmatcher_license->setEnabled(true);
|
||||
#else
|
||||
_ui->label_libpointmatcher->setText("No");
|
||||
_ui->label_libpointmatcher_license->setEnabled(false);
|
||||
#endif
|
||||
|
||||
#ifdef RTABMAP_FOVIS
|
||||
_ui->label_fovis->setText("Yes");
|
||||
_ui->label_fovis_license->setEnabled(true);
|
||||
|
||||
@@ -238,6 +238,9 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
{
|
||||
_ui->graphOptimization_robust->setEnabled(false);
|
||||
}
|
||||
#ifndef RTABMAP_POINTMATCHER
|
||||
_ui->groupBox_libpointmatcher->setEnabled(false);
|
||||
#endif
|
||||
if(!CameraOpenni::available())
|
||||
{
|
||||
_ui->comboBox_cameraRGBD->setItemData(0, 0, Qt::UserRole - 1);
|
||||
@@ -856,6 +859,10 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
_ui->loopClosure_icpPointToPlane->setObjectName(Parameters::kIcpPointToPlane().c_str());
|
||||
_ui->loopClosure_icpPointToPlaneNormals->setObjectName(Parameters::kIcpPointToPlaneNormalNeighbors().c_str());
|
||||
|
||||
_ui->groupBox_libpointmatcher->setObjectName(Parameters::kIcpPM().c_str());
|
||||
_ui->lineEdit_IcpPMConfigPath->setObjectName(Parameters::kIcpPMConfig().c_str());
|
||||
connect(_ui->toolButton_IcpConfigPath, SIGNAL(clicked()), this, SLOT(changeIcpPMConfigPath()));
|
||||
|
||||
// Occupancy grid
|
||||
_ui->groupBox_grid_3d->setObjectName(Parameters::kGrid3D().c_str());
|
||||
_ui->checkBox_grid_groundObstacle->setObjectName(Parameters::kGridGroundIsObstacle().c_str());
|
||||
@@ -4051,6 +4058,23 @@ void PreferencesDialog::changeOdometryORBSLAM2Vocabulary()
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesDialog::changeIcpPMConfigPath()
|
||||
{
|
||||
QString path;
|
||||
if(_ui->lineEdit_IcpPMConfigPath->text().isEmpty())
|
||||
{
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select file"), this->getWorkingDirectory(), tr("libpointmatcher (*.yaml)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select file"), _ui->lineEdit_IcpPMConfigPath->text(), tr("libpointmatcher (*.yaml)"));
|
||||
}
|
||||
if(!path.isEmpty())
|
||||
{
|
||||
_ui->lineEdit_IcpPMConfigPath->setText(path);
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesDialog::updateSourceGrpVisibility()
|
||||
{
|
||||
_ui->groupBox_sourceRGBD->setVisible(_ui->comboBox_sourceType->currentIndex() == 0);
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>831</width>
|
||||
<height>832</height>
|
||||
<width>861</width>
|
||||
<height>902</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@@ -161,6 +161,19 @@ p, li { white-space: pre-wrap; }
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,0,1">
|
||||
<item row="17" column="1">
|
||||
<widget class="QLabel" name="label_octomap">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="label_pcl_license">
|
||||
<property name="text">
|
||||
@@ -230,20 +243,27 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="1">
|
||||
<widget class="QLabel" name="label_octomap">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_79">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
<string>Qt version :</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="0">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>OpenCV version :</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="0">
|
||||
<widget class="QLabel" name="label_24">
|
||||
<property name="text">
|
||||
<string>With CPU-TSDF :</string>
|
||||
@@ -253,7 +273,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="1">
|
||||
<item row="18" column="1">
|
||||
<widget class="QLabel" name="label_cputsdf">
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -266,7 +286,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="0">
|
||||
<item row="19" column="0">
|
||||
<widget class="QLabel" name="label_25">
|
||||
<property name="text">
|
||||
<string>With FOVIS :</string>
|
||||
@@ -286,7 +306,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0">
|
||||
<item row="17" column="0">
|
||||
<widget class="QLabel" name="label_20">
|
||||
<property name="text">
|
||||
<string>With Octomap :</string>
|
||||
@@ -296,7 +316,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="20" column="1">
|
||||
<item row="21" column="1">
|
||||
<widget class="QLabel" name="label_dvo">
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -309,7 +329,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="21" column="0">
|
||||
<item row="22" column="0">
|
||||
<widget class="QLabel" name="label_28">
|
||||
<property name="text">
|
||||
<string>With ORB SLAM 2 :</string>
|
||||
@@ -319,7 +339,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="21" column="1">
|
||||
<item row="22" column="1">
|
||||
<widget class="QLabel" name="label_orbslam2">
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -365,7 +385,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="1">
|
||||
<item row="19" column="1">
|
||||
<widget class="QLabel" name="label_fovis">
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -378,7 +398,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="19" column="0">
|
||||
<item row="20" column="0">
|
||||
<widget class="QLabel" name="label_26">
|
||||
<property name="text">
|
||||
<string>With Viso2 :</string>
|
||||
@@ -457,16 +477,6 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>OpenCV version :</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
@@ -658,7 +668,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="2">
|
||||
<item row="17" column="2">
|
||||
<widget class="QLabel" name="label_octomap_license">
|
||||
<property name="text">
|
||||
<string>BSD</string>
|
||||
@@ -668,7 +678,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="2">
|
||||
<item row="18" column="2">
|
||||
<widget class="QLabel" name="label_cputsdf_license">
|
||||
<property name="text">
|
||||
<string>BSD</string>
|
||||
@@ -678,7 +688,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="2">
|
||||
<item row="19" column="2">
|
||||
<widget class="QLabel" name="label_fovis_license">
|
||||
<property name="text">
|
||||
<string>GPLv2</string>
|
||||
@@ -688,7 +698,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="19" column="2">
|
||||
<item row="20" column="2">
|
||||
<widget class="QLabel" name="label_viso2_license">
|
||||
<property name="text">
|
||||
<string>GPLv3</string>
|
||||
@@ -698,7 +708,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="20" column="2">
|
||||
<item row="21" column="2">
|
||||
<widget class="QLabel" name="label_dvo_license">
|
||||
<property name="text">
|
||||
<string>GPLv3</string>
|
||||
@@ -761,7 +771,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="19" column="1">
|
||||
<item row="20" column="1">
|
||||
<widget class="QLabel" name="label_viso2">
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -774,7 +784,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="20" column="0">
|
||||
<item row="21" column="0">
|
||||
<widget class="QLabel" name="label_27">
|
||||
<property name="text">
|
||||
<string>With DVO :</string>
|
||||
@@ -784,16 +794,6 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_79">
|
||||
<property name="text">
|
||||
<string>Qt version :</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLabel" name="label_qt_license">
|
||||
<property name="text">
|
||||
@@ -847,7 +847,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="21" column="2">
|
||||
<item row="22" column="2">
|
||||
<widget class="QLabel" name="label_orbslam2_license">
|
||||
<property name="text">
|
||||
<string>GPLv3</string>
|
||||
@@ -857,6 +857,39 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="2">
|
||||
<widget class="QLabel" name="label_libpointmatcher_license">
|
||||
<property name="text">
|
||||
<string>BSD</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0">
|
||||
<widget class="QLabel" name="label_29">
|
||||
<property name="text">
|
||||
<string>With libpointmatcher :</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="1">
|
||||
<widget class="QLabel" name="label_libpointmatcher">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
||||
@@ -63,25 +63,16 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<y>-310</y>
|
||||
<width>678</width>
|
||||
<height>2739</height>
|
||||
<height>2736</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -95,7 +86,7 @@
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>20</number>
|
||||
<number>21</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_22">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
|
||||
@@ -4530,16 +4521,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
<string>Directory of images (optional settings)</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_93">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -11561,22 +11543,6 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_415">
|
||||
<property name="text">
|
||||
<string>Path to ORB vocabulary (*.txt).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_OdomORBSLAM2VocPath"/>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="label_414">
|
||||
<property name="text">
|
||||
@@ -11625,6 +11591,22 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_OdomORBSLAM2VocPath"/>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_415">
|
||||
<property name="text">
|
||||
<string>Path to ORB vocabulary (*.txt).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QToolButton" name="toolButton_OdomORBSLAM2VocPath">
|
||||
<property name="text">
|
||||
@@ -11835,7 +11817,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="stackedWidget_odometryFiltering">
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_31">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_84"/>
|
||||
@@ -12491,16 +12473,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
<widget class="QWidget" name="page_54">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_85">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -12640,16 +12613,7 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_55">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_86">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -12807,16 +12771,7 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -12896,16 +12851,7 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -13017,16 +12963,7 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -13763,6 +13700,61 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_libpointmatcher">
|
||||
<property name="title">
|
||||
<string>libpointmatcher</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_126">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_422">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>libpointmatcher: <a href="https://github.com/ethz-asl/libpointmatcher"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/ethz-asl/libpointmatcher</span></a></p><p>libpointmatcher is a modular library implementing the Iterative Closest Point (ICP) algorithm for aligning point clouds. It has applications in robotics and computer vision. When enabled, libpointmatcher is used for ICP registration instead of PCL's implementation.</p><p>Below we can set a <a href="https://github.com/ethz-asl/libpointmatcher/blob/master/doc/Configuration.md"><span style=" text-decoration: underline; color:#0000ff;">configuration file</span></a> (*.yaml) used by libpointmatcher. Note that data filters set for libpointmatcher are done after filtering done by rtabmap (i.e., voxel filtering or downsampling above), so make sure to disable those in rtabmap if you want to use only those from libpointmatcher. Maximum iterations, epsilon and max correspondence distance parameters are also ignored if configuration file is set.<br/></p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButton_IcpConfigPath">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_IcpPMConfigPath"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_423">
|
||||
<property name="text">
|
||||
<string>Configuration file (*.yaml).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
Reference in New Issue
Block a user