mirror of
https://github.com/introlab/rtabmap_ros.git
synced 2026-10-03 16:27:46 +08:00
New 2d scan type: CV_32FC5 (x,y,normal_x,normal_y,normal_z)
This commit is contained in:
@@ -192,17 +192,20 @@ pcl::PointCloud<pcl::PointXYZ> RTABMAP_EXP laserScanFromDepthImages(
|
||||
|
||||
// return CV_32FC3 (x,y,z)
|
||||
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const Transform & transform = Transform());
|
||||
// return CV_32FC6 (x,y,z,normal_z,normal_y,normalz)
|
||||
// return CV_32FC6 (x,y,z,normal_x,normal_y,normal_z)
|
||||
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointNormal> & cloud, const Transform & transform = Transform());
|
||||
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform());
|
||||
// return CV_32FC4 (x,y,z,rgb)
|
||||
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGB> & cloud, const Transform & transform = Transform());
|
||||
// return CV_32FC7 (x,y,z,rgb,normal_z,normal_y,normalz)
|
||||
// return CV_32FC7 (x,y,z,rgb,normal_x,normal_y,normal_z)
|
||||
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGB> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform());
|
||||
// return CV_32FC7 (x,y,z,rgb,normal_z,normal_y,normalz)
|
||||
// return CV_32FC7 (x,y,z,rgb,normal_x,normal_y,normal_z)
|
||||
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGBNormal> & cloud, const Transform & transform = Transform());
|
||||
// return CV_32FC2 (x,y)
|
||||
cv::Mat RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const Transform & transform = Transform());
|
||||
// return CV_32FC5 (x,y,normal_x, normal_y, normal_z)
|
||||
cv::Mat RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointNormal> & cloud, const Transform & transform = Transform());
|
||||
cv::Mat RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform());
|
||||
// For laserScan of type CV_32FC2, z is set to null.
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP laserScanToPointCloud(const cv::Mat & laserScan, const Transform & transform = Transform());
|
||||
// For laserScan of type CV_32FC2, CV_32FC3 and CV_32FC4, normals are set to null.
|
||||
|
||||
+33
-12
@@ -2438,6 +2438,7 @@ Transform Memory::computeIcpTransformMulti(
|
||||
std::string msg;
|
||||
int maxPoints = fromScan.cols;
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr assembledToClouds(new pcl::PointCloud<pcl::PointXYZ>);
|
||||
bool is2D = true;
|
||||
for(std::map<int, Transform>::const_iterator iter = poses.begin(); iter!=poses.end(); ++iter)
|
||||
{
|
||||
if(iter->first != fromId)
|
||||
@@ -2447,14 +2448,21 @@ Transform Memory::computeIcpTransformMulti(
|
||||
{
|
||||
cv::Mat scan;
|
||||
s->sensorData().uncompressData(0, 0, &scan);
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud = util3d::laserScanToPointCloud(
|
||||
scan,
|
||||
s->sensorData().laserScanInfo().localTransform() * toPose.inverse() * iter->second);
|
||||
if(scan.cols > maxPoints)
|
||||
if(!scan.empty())
|
||||
{
|
||||
maxPoints = scan.cols;
|
||||
if(scan.channels() != 2 && scan.channels() != 5)
|
||||
{
|
||||
is2D = false;
|
||||
}
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud = util3d::laserScanToPointCloud(
|
||||
scan,
|
||||
s->sensorData().laserScanInfo().localTransform() * toPose.inverse() * iter->second);
|
||||
if(scan.cols > maxPoints)
|
||||
{
|
||||
maxPoints = scan.cols;
|
||||
}
|
||||
*assembledToClouds += *cloud;
|
||||
}
|
||||
*assembledToClouds += *cloud;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2464,12 +2472,25 @@ Transform Memory::computeIcpTransformMulti(
|
||||
}
|
||||
if(assembledToClouds->size())
|
||||
{
|
||||
assembledData.setLaserScanRaw(
|
||||
util3d::laserScanFromPointCloud(*assembledToClouds),
|
||||
LaserScanInfo(
|
||||
fromS->sensorData().laserScanInfo().maxPoints()?fromS->sensorData().laserScanInfo().maxPoints():maxPoints,
|
||||
fromS->sensorData().laserScanInfo().maxRange(),
|
||||
Transform::getIdentity())); // scans are in base frame
|
||||
if(is2D)
|
||||
{
|
||||
assembledData.setLaserScanRaw(
|
||||
util3d::laserScan2dFromPointCloud(*assembledToClouds),
|
||||
LaserScanInfo(
|
||||
fromS->sensorData().laserScanInfo().maxPoints()?fromS->sensorData().laserScanInfo().maxPoints():maxPoints,
|
||||
fromS->sensorData().laserScanInfo().maxRange(),
|
||||
Transform::getIdentity())); // scans are in base frame
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
assembledData.setLaserScanRaw(
|
||||
util3d::laserScanFromPointCloud(*assembledToClouds),
|
||||
LaserScanInfo(
|
||||
fromS->sensorData().laserScanInfo().maxPoints()?fromS->sensorData().laserScanInfo().maxPoints():maxPoints,
|
||||
fromS->sensorData().laserScanInfo().maxRange(),
|
||||
Transform::getIdentity())); // scans are in base frame
|
||||
}
|
||||
}
|
||||
|
||||
Transform guess = poses.at(fromId).inverse() * poses.at(toId);
|
||||
|
||||
@@ -207,7 +207,7 @@ void OccupancyGrid::createLocalMap(
|
||||
UDEBUG("scan channels=%d, occupancyFromCloud_=%d normalsSegmentation_=%d grid3D_=%d",
|
||||
node.sensorData().laserScanRaw().empty()?0:node.sensorData().laserScanRaw().channels(), occupancyFromCloud_?1:0, normalsSegmentation_?1:0, grid3D_?1:0);
|
||||
|
||||
if(node.sensorData().laserScanRaw().channels() == 2 && !occupancyFromCloud_)
|
||||
if((node.sensorData().laserScanRaw().channels() == 2 || node.sensorData().laserScanRaw().channels() == 5) && !occupancyFromCloud_)
|
||||
{
|
||||
UDEBUG("2D laser scan");
|
||||
//2D
|
||||
|
||||
@@ -39,11 +39,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <pcl/conversions.h>
|
||||
|
||||
#ifdef RTABMAP_POINTMATCHER
|
||||
#include <fstream>
|
||||
#include "pointmatcher/PointMatcher.h"
|
||||
typedef PointMatcher<float> PM;
|
||||
typedef PM::DataPoints DP;
|
||||
|
||||
DP pclToDP(const pcl::PointCloud<pcl::PointXYZ>::Ptr & pclCloud)
|
||||
DP pclToDP(const pcl::PointCloud<pcl::PointXYZ>::Ptr & pclCloud, bool is2D)
|
||||
{
|
||||
UDEBUG("");
|
||||
typedef DP::Label Label;
|
||||
@@ -63,8 +64,11 @@ DP pclToDP(const pcl::PointCloud<pcl::PointXYZ>::Ptr & pclCloud)
|
||||
isFeature.push_back(true);
|
||||
featLabels.push_back(Label("y", 1));
|
||||
isFeature.push_back(true);
|
||||
featLabels.push_back(Label("z", 1));
|
||||
isFeature.push_back(true);
|
||||
if(!is2D)
|
||||
{
|
||||
featLabels.push_back(Label("z", 1));
|
||||
isFeature.push_back(true);
|
||||
}
|
||||
featLabels.push_back(Label("pad", 1));
|
||||
|
||||
// create cloud
|
||||
@@ -72,20 +76,21 @@ DP pclToDP(const pcl::PointCloud<pcl::PointXYZ>::Ptr & pclCloud)
|
||||
cloud.getFeatureViewByName("pad").setConstant(1);
|
||||
|
||||
// fill cloud
|
||||
View viewX(cloud.getFeatureViewByName("x"));
|
||||
View viewY(cloud.getFeatureViewByName("y"));
|
||||
View viewZ(cloud.getFeatureViewByName("z"));
|
||||
View view(cloud.getFeatureViewByName("x"));
|
||||
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;
|
||||
view(0, i) = pclCloud->at(i).x;
|
||||
view(1, i) = pclCloud->at(i).y;
|
||||
if(!is2D)
|
||||
{
|
||||
view(2, i) = pclCloud->at(i).z;
|
||||
}
|
||||
}
|
||||
|
||||
return cloud;
|
||||
}
|
||||
|
||||
DP pclToDP(const pcl::PointCloud<pcl::PointNormal>::Ptr & pclCloud)
|
||||
DP pclToDP(const pcl::PointCloud<pcl::PointNormal>::Ptr & pclCloud, bool is2D)
|
||||
{
|
||||
UDEBUG("");
|
||||
typedef DP::Label Label;
|
||||
@@ -105,8 +110,11 @@ DP pclToDP(const pcl::PointCloud<pcl::PointNormal>::Ptr & pclCloud)
|
||||
isFeature.push_back(true);
|
||||
featLabels.push_back(Label("y", 1));
|
||||
isFeature.push_back(true);
|
||||
featLabels.push_back(Label("z", 1));
|
||||
isFeature.push_back(true);
|
||||
if(!is2D)
|
||||
{
|
||||
featLabels.push_back(Label("z", 1));
|
||||
isFeature.push_back(true);
|
||||
}
|
||||
|
||||
descLabels.push_back(Label("normals", 3));
|
||||
isFeature.push_back(false);
|
||||
@@ -120,17 +128,18 @@ DP pclToDP(const pcl::PointCloud<pcl::PointNormal>::Ptr & pclCloud)
|
||||
cloud.getFeatureViewByName("pad").setConstant(1);
|
||||
|
||||
// fill cloud
|
||||
View viewX(cloud.getFeatureViewByName("x"));
|
||||
View viewY(cloud.getFeatureViewByName("y"));
|
||||
View viewZ(cloud.getFeatureViewByName("z"));
|
||||
View view(cloud.getFeatureViewByName("x"));
|
||||
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;
|
||||
view(0, i) = pclCloud->at(i).x;
|
||||
view(1, i) = pclCloud->at(i).y;
|
||||
if(!is2D)
|
||||
{
|
||||
view(2, 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;
|
||||
@@ -151,14 +160,13 @@ void pclFromDP(const DP & cloud, pcl::PointCloud<pcl::PointXYZ> & pclCloud)
|
||||
pclCloud.is_dense = true;
|
||||
|
||||
// fill cloud
|
||||
ConstView viewX(cloud.getFeatureViewByName("x"));
|
||||
ConstView viewY(cloud.getFeatureViewByName("y"));
|
||||
ConstView viewZ(cloud.getFeatureViewByName("z"));
|
||||
ConstView view(cloud.getFeatureViewByName("x"));
|
||||
bool is3D = cloud.featureExists("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);
|
||||
pclCloud.at(i).x = view(0, i);
|
||||
pclCloud.at(i).y = view(1, i);
|
||||
pclCloud.at(i).z = is3D?view(2, i):0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,17 +182,16 @@ void pclFromDP(const DP & cloud, pcl::PointCloud<pcl::PointNormal> & pclCloud)
|
||||
pclCloud.is_dense = true;
|
||||
|
||||
// fill cloud
|
||||
ConstView viewX(cloud.getFeatureViewByName("x"));
|
||||
ConstView viewY(cloud.getFeatureViewByName("y"));
|
||||
ConstView viewZ(cloud.getFeatureViewByName("z"));
|
||||
ConstView view(cloud.getFeatureViewByName("x"));
|
||||
bool is3D = cloud.featureExists("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).x = view(0, i);
|
||||
pclCloud.at(i).y = view(1, i);
|
||||
pclCloud.at(i).z = is3D?view(2, i):0;
|
||||
pclCloud.at(i).normal_x = viewNormalX(0, i);
|
||||
pclCloud.at(i).normal_y = viewNormalY(0, i);
|
||||
pclCloud.at(i).normal_z = viewNormalZ(0, i);
|
||||
@@ -319,6 +326,12 @@ void RegistrationIcp::parseParameters(const ParametersMap & parameters)
|
||||
icp->outlierFilters.clear();
|
||||
icp->outlierFilters.push_back(PM::get().OutlierFilterRegistrar.create("TrimmedDistOutlierFilter", params));
|
||||
params.clear();
|
||||
if(_pointToPlane)
|
||||
{
|
||||
params["maxAngle"] = uNumber2Str(_maxRotation<=0.0f?M_PI:_maxRotation);
|
||||
icp->outlierFilters.push_back(PM::get().OutlierFilterRegistrar.create("SurfaceNormalOutlierFilter", params));
|
||||
params.clear();
|
||||
}
|
||||
|
||||
icp->errorMinimizer.reset(PM::get().ErrorMinimizerRegistrar.create(_pointToPlane?"PointToPlaneErrorMinimizer":"PointToPointErrorMinimizer"));
|
||||
|
||||
@@ -332,6 +345,11 @@ void RegistrationIcp::parseParameters(const ParametersMap & parameters)
|
||||
params["smoothLength"] = uNumber2Str(4);
|
||||
icp->transformationCheckers.push_back(PM::get().TransformationCheckerRegistrar.create("DifferentialTransformationChecker", params));
|
||||
params.clear();
|
||||
|
||||
params["maxRotationNorm"] = uNumber2Str(_maxRotation<=0.0f?M_PI:_maxRotation);
|
||||
params["maxTranslationNorm"] = uNumber2Str(_maxTranslation<=0.0f?std::numeric_limits<float>::max():_maxTranslation);
|
||||
icp->transformationCheckers.push_back(PM::get().TransformationCheckerRegistrar.create("BoundTransformationChecker", params));
|
||||
params.clear();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -408,20 +426,25 @@ Transform RegistrationIcp::computeTransformationImpl(
|
||||
if( _pointToPlane &&
|
||||
_voxelSize == 0.0f &&
|
||||
fromScan.channels() >= 6 &&
|
||||
toScan.channels() >= 6)
|
||||
toScan.channels() >= 6 &&
|
||||
!((fromScan.channels() == 5 || toScan.channels() == 5) && !_libpointmatcher)) // PCL crashes if 2D)
|
||||
{
|
||||
//special case if we have already normals computed and there is no filtering
|
||||
pcl::PointCloud<pcl::PointNormal>::Ptr fromCloudNormals = util3d::laserScanToPointCloudNormal(fromScan, fromLocalTransform);
|
||||
pcl::PointCloud<pcl::PointNormal>::Ptr toCloudNormals = util3d::laserScanToPointCloudNormal(toScan, guess * toLocalTransform);
|
||||
|
||||
fromCloudNormals = util3d::removeNaNNormalsFromPointCloud(fromCloudNormals);
|
||||
toCloudNormals = util3d::removeNaNNormalsFromPointCloud(toCloudNormals);
|
||||
|
||||
|
||||
UDEBUG("Conversion time = %f s", timer.ticks());
|
||||
pcl::PointCloud<pcl::PointNormal>::Ptr fromCloudNormalsRegistered(new pcl::PointCloud<pcl::PointNormal>());
|
||||
#ifdef RTABMAP_POINTMATCHER
|
||||
if(_libpointmatcher)
|
||||
{
|
||||
// Load point clouds
|
||||
DP data = pclToDP(fromCloudNormals);
|
||||
DP ref = pclToDP(toCloudNormals);
|
||||
DP data = pclToDP(fromCloudNormals, fromScan.channels() == 5);
|
||||
DP ref = pclToDP(toCloudNormals, toScan.channels() == 5);
|
||||
|
||||
// Compute the transformation to express data in ref
|
||||
PM::TransformationParameters T;
|
||||
@@ -451,9 +474,6 @@ Transform RegistrationIcp::computeTransformationImpl(
|
||||
else
|
||||
#endif
|
||||
{
|
||||
fromCloudNormals = util3d::removeNaNNormalsFromPointCloud(fromCloudNormals);
|
||||
toCloudNormals = util3d::removeNaNNormalsFromPointCloud(toCloudNormals);
|
||||
|
||||
icpT = util3d::icpPointToPlane(
|
||||
fromCloudNormals,
|
||||
toCloudNormals,
|
||||
@@ -502,14 +522,14 @@ Transform RegistrationIcp::computeTransformationImpl(
|
||||
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr fromCloudRegistered(new pcl::PointCloud<pcl::PointXYZ>());
|
||||
if(_pointToPlane && // ICP Point To Plane
|
||||
!((fromScan.channels() == 2 || toScan.channels() == 2) && !_libpointmatcher)) // PCL crashes if 2D
|
||||
!((fromScan.channels() == 2 || fromScan.channels() == 5 || toScan.channels() == 2 || toScan.channels() == 5) && !_libpointmatcher)) // PCL crashes if 2D
|
||||
{
|
||||
pcl::PointCloud<pcl::Normal>::Ptr normals;
|
||||
Eigen::Vector3f viewpointFrom(fromLocalTransform.x(), fromLocalTransform.y(), fromLocalTransform.z());
|
||||
Transform toT = guess * toLocalTransform;
|
||||
Eigen::Vector3f viewpointTo(toT.x(), toT.y(), toT.z());
|
||||
|
||||
if(fromScan.channels() == 2)
|
||||
if(fromScan.channels() == 2 || fromScan.channels() == 5)
|
||||
{
|
||||
normals = util3d::computeFastOrganizedNormals2D(
|
||||
fromCloudFiltered,
|
||||
@@ -524,7 +544,7 @@ Transform RegistrationIcp::computeTransformationImpl(
|
||||
pcl::PointCloud<pcl::PointNormal>::Ptr fromCloudNormals(new pcl::PointCloud<pcl::PointNormal>);
|
||||
pcl::concatenateFields(*fromCloudFiltered, *normals, *fromCloudNormals);
|
||||
|
||||
if(toScan.channels() == 2)
|
||||
if(toScan.channels() == 2 || toScan.channels() == 5)
|
||||
{
|
||||
normals = util3d::computeFastOrganizedNormals2D(
|
||||
toCloudFiltered,
|
||||
@@ -544,8 +564,22 @@ Transform RegistrationIcp::computeTransformationImpl(
|
||||
fromCloudNormals = util3d::removeNaNNormalsFromPointCloud(fromCloudNormals);
|
||||
|
||||
// update output scans
|
||||
fromSignature.sensorData().setLaserScanRaw(util3d::laserScanFromPointCloud(*fromCloudNormals, fromLocalTransform.inverse()), LaserScanInfo(maxLaserScansFrom, fromSignature.sensorData().laserScanInfo().maxRange(), fromLocalTransform));
|
||||
toSignature.sensorData().setLaserScanRaw(util3d::laserScanFromPointCloud(*toCloudNormals, (guess*toLocalTransform).inverse()), LaserScanInfo(maxLaserScansTo, toSignature.sensorData().laserScanInfo().maxRange(), toLocalTransform));
|
||||
if(fromScan.channels() == 2 || toScan.channels() == 5)
|
||||
{
|
||||
fromSignature.sensorData().setLaserScanRaw(util3d::laserScan2dFromPointCloud(*fromCloudNormals, fromLocalTransform.inverse()), LaserScanInfo(maxLaserScansFrom, fromSignature.sensorData().laserScanInfo().maxRange(), fromLocalTransform));
|
||||
}
|
||||
else
|
||||
{
|
||||
fromSignature.sensorData().setLaserScanRaw(util3d::laserScanFromPointCloud(*fromCloudNormals, fromLocalTransform.inverse()), LaserScanInfo(maxLaserScansFrom, fromSignature.sensorData().laserScanInfo().maxRange(), fromLocalTransform));
|
||||
}
|
||||
if(toScan.channels() == 2 || toScan.channels() == 5)
|
||||
{
|
||||
toSignature.sensorData().setLaserScanRaw(util3d::laserScan2dFromPointCloud(*toCloudNormals, (guess*toLocalTransform).inverse()), LaserScanInfo(maxLaserScansTo, toSignature.sensorData().laserScanInfo().maxRange(), toLocalTransform));
|
||||
}
|
||||
else
|
||||
{
|
||||
toSignature.sensorData().setLaserScanRaw(util3d::laserScanFromPointCloud(*toCloudNormals, (guess*toLocalTransform).inverse()), LaserScanInfo(maxLaserScansTo, toSignature.sensorData().laserScanInfo().maxRange(), toLocalTransform));
|
||||
}
|
||||
|
||||
UDEBUG("Compute normals (%d,%d) time = %f s", (int)fromCloudNormals->size(), (int)toCloudNormals->size(), timer.ticks());
|
||||
|
||||
@@ -557,8 +591,8 @@ Transform RegistrationIcp::computeTransformationImpl(
|
||||
if(_libpointmatcher)
|
||||
{
|
||||
// Load point clouds
|
||||
DP data = pclToDP(fromCloudNormals);
|
||||
DP ref = pclToDP(toCloudNormals);
|
||||
DP data = pclToDP(fromCloudNormals, fromScan.channels() == 2 || fromScan.channels() == 5);
|
||||
DP ref = pclToDP(toCloudNormals, toScan.channels() == 2 || toScan.channels() == 5);
|
||||
|
||||
// Compute the transformation to express data in ref
|
||||
PM::TransformationParameters T;
|
||||
@@ -612,7 +646,7 @@ Transform RegistrationIcp::computeTransformationImpl(
|
||||
}
|
||||
else // ICP Point to Point
|
||||
{
|
||||
if(_pointToPlane && ((fromScan.channels() == 2 || toScan.channels() == 2) && !_libpointmatcher))
|
||||
if(_pointToPlane && ((fromScan.channels() == 2 || fromScan.channels() == 5 || toScan.channels() == 2 || toScan.channels() == 5) && !_libpointmatcher))
|
||||
{
|
||||
UWARN("ICP PointToPlane ignored for 2d scans with PCL registration (some crash issues). Use libpointmatcher (%s) or disable %s to avoid this warning.", Parameters::kIcpPM().c_str(), Parameters::kIcpPointToPlane().c_str());
|
||||
}
|
||||
@@ -628,8 +662,8 @@ Transform RegistrationIcp::computeTransformationImpl(
|
||||
if(_libpointmatcher)
|
||||
{
|
||||
// Load point clouds
|
||||
DP data = pclToDP(fromCloudFiltered);
|
||||
DP ref = pclToDP(toCloudFiltered);
|
||||
DP data = pclToDP(fromCloudFiltered, fromScan.channels() == 2 || fromScan.channels() == 5);
|
||||
DP ref = pclToDP(toCloudFiltered, toScan.channels() == 2 || toScan.channels() == 5);
|
||||
|
||||
// Compute the transformation to express data in ref
|
||||
PM::TransformationParameters T;
|
||||
|
||||
@@ -1116,7 +1116,7 @@ bool Rtabmap::process(
|
||||
else
|
||||
{
|
||||
UINFO("Odometry refining rejected: %s", info.rejectedMsg.c_str());
|
||||
if(info.covariance.at<double>(0,0) > 0.0 && info.covariance.at<double>(5,5) > 0.0)
|
||||
if(!info.covariance.empty() && info.covariance.at<double>(0,0) > 0.0 && info.covariance.at<double>(0,0) != 1.0 && info.covariance.at<double>(5,5) > 0.0 && info.covariance.at<double>(5,5) != 1.0)
|
||||
{
|
||||
_memory->updateLink(Link(oldId, signature->id(), signature->getLinks().begin()->second.type(), guess, (info.covariance*100.0).inv()));
|
||||
}
|
||||
|
||||
+96
-17
@@ -1459,9 +1459,75 @@ cv::Mat laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud,
|
||||
return laserScan;
|
||||
}
|
||||
|
||||
cv::Mat laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointNormal> & cloud, const Transform & transform)
|
||||
{
|
||||
cv::Mat laserScan(1, (int)cloud.size(), CV_32FC(5));
|
||||
bool nullTransform = transform.isNull();
|
||||
for(unsigned int i=0; i<cloud.size(); ++i)
|
||||
{
|
||||
float * ptr = laserScan.ptr<float>(0, i);
|
||||
if(!nullTransform)
|
||||
{
|
||||
pcl::PointNormal pt = util3d::transformPoint(cloud.at(i), transform);
|
||||
ptr[0] = pt.x;
|
||||
ptr[1] = pt.y;
|
||||
ptr[2] = pt.normal_x;
|
||||
ptr[3] = pt.normal_y;
|
||||
ptr[4] = pt.normal_z;
|
||||
}
|
||||
else
|
||||
{
|
||||
const pcl::PointNormal & pt = cloud.at(i);
|
||||
ptr[0] = pt.x;
|
||||
ptr[1] = pt.y;
|
||||
ptr[2] = pt.normal_x;
|
||||
ptr[3] = pt.normal_y;
|
||||
ptr[4] = pt.normal_z;
|
||||
}
|
||||
|
||||
}
|
||||
return laserScan;
|
||||
}
|
||||
|
||||
cv::Mat laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform)
|
||||
{
|
||||
UASSERT(cloud.size() == normals.size());
|
||||
cv::Mat laserScan(1, (int)cloud.size(), CV_32FC(5));
|
||||
bool nullTransform = transform.isNull() || transform.isIdentity();
|
||||
for(unsigned int i=0; i<cloud.size(); ++i)
|
||||
{
|
||||
float * ptr = laserScan.ptr<float>(0, i);
|
||||
if(!nullTransform)
|
||||
{
|
||||
pcl::PointNormal pt;
|
||||
pt.x = cloud.at(i).x;
|
||||
pt.y = cloud.at(i).y;
|
||||
pt.z = cloud.at(i).z;
|
||||
pt.normal_x = normals.at(i).normal_x;
|
||||
pt.normal_y = normals.at(i).normal_y;
|
||||
pt.normal_z = normals.at(i).normal_z;
|
||||
pt = util3d::transformPoint(pt, transform);
|
||||
ptr[0] = pt.x;
|
||||
ptr[1] = pt.y;
|
||||
ptr[2] = pt.normal_x;
|
||||
ptr[3] = pt.normal_y;
|
||||
ptr[4] = pt.normal_z;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr[0] = cloud.at(i).x;
|
||||
ptr[1] = cloud.at(i).y;
|
||||
ptr[2] = normals.at(i).normal_x;
|
||||
ptr[3] = normals.at(i).normal_y;
|
||||
ptr[4] = normals.at(i).normal_z;
|
||||
}
|
||||
}
|
||||
return laserScan;
|
||||
}
|
||||
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr laserScanToPointCloud(const cv::Mat & laserScan, const Transform & transform)
|
||||
{
|
||||
UASSERT(laserScan.empty() || laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
UASSERT(laserScan.empty() || laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(5) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr output(new pcl::PointCloud<pcl::PointXYZ>);
|
||||
output->resize(laserScan.cols);
|
||||
@@ -1480,7 +1546,7 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr laserScanToPointCloud(const cv::Mat & laserS
|
||||
|
||||
pcl::PointCloud<pcl::PointNormal>::Ptr laserScanToPointCloudNormal(const cv::Mat & laserScan, const Transform & transform)
|
||||
{
|
||||
UASSERT(laserScan.empty() || laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
UASSERT(laserScan.empty() || laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(5) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
|
||||
pcl::PointCloud<pcl::PointNormal>::Ptr output(new pcl::PointCloud<pcl::PointNormal>);
|
||||
output->resize(laserScan.cols);
|
||||
@@ -1498,7 +1564,7 @@ pcl::PointCloud<pcl::PointNormal>::Ptr laserScanToPointCloudNormal(const cv::Mat
|
||||
|
||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr laserScanToPointCloudRGB(const cv::Mat & laserScan, const Transform & transform, unsigned char r, unsigned char g, unsigned char b)
|
||||
{
|
||||
UASSERT(laserScan.empty() || laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
UASSERT(laserScan.empty() || laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(5) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
|
||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr output(new pcl::PointCloud<pcl::PointXYZRGB>);
|
||||
output->resize(laserScan.cols);
|
||||
@@ -1517,7 +1583,7 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr laserScanToPointCloudRGB(const cv::Mat &
|
||||
|
||||
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr laserScanToPointCloudRGBNormal(const cv::Mat & laserScan, const Transform & transform, unsigned char r, unsigned char g, unsigned char b)
|
||||
{
|
||||
UASSERT(laserScan.empty() || laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
UASSERT(laserScan.empty() || laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(5) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
|
||||
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr output(new pcl::PointCloud<pcl::PointXYZRGBNormal>);
|
||||
output->resize(laserScan.cols);
|
||||
@@ -1536,12 +1602,12 @@ pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr laserScanToPointCloudRGBNormal(cons
|
||||
pcl::PointXYZ laserScanToPoint(const cv::Mat & laserScan, int index)
|
||||
{
|
||||
UASSERT(!laserScan.empty() && index < laserScan.cols);
|
||||
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(5) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
pcl::PointXYZ output;
|
||||
const float * ptr = laserScan.ptr<float>(0, index);
|
||||
output.x = ptr[0];
|
||||
output.y = ptr[1];
|
||||
if(laserScan.channels() >= 3)
|
||||
if(laserScan.channels() >= 3 && laserScan.channels() != 5)
|
||||
{
|
||||
output.z = ptr[2];
|
||||
}
|
||||
@@ -1551,16 +1617,22 @@ pcl::PointXYZ laserScanToPoint(const cv::Mat & laserScan, int index)
|
||||
pcl::PointNormal laserScanToPointNormal(const cv::Mat & laserScan, int index)
|
||||
{
|
||||
UASSERT(!laserScan.empty() && index < laserScan.cols);
|
||||
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(5) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
pcl::PointNormal output;
|
||||
const float * ptr = laserScan.ptr<float>(0, index);
|
||||
output.x = ptr[0];
|
||||
output.y = ptr[1];
|
||||
if(laserScan.channels() >= 3)
|
||||
if(laserScan.channels() >= 3 && laserScan.channels() != 5)
|
||||
{
|
||||
output.z = ptr[2];
|
||||
}
|
||||
if(laserScan.channels() == 6)
|
||||
if(laserScan.channels() == 5)
|
||||
{
|
||||
output.normal_x = ptr[2];
|
||||
output.normal_y = ptr[3];
|
||||
output.normal_z = ptr[4];
|
||||
}
|
||||
else if(laserScan.channels() == 6)
|
||||
{
|
||||
output.normal_x = ptr[3];
|
||||
output.normal_y = ptr[4];
|
||||
@@ -1578,12 +1650,12 @@ pcl::PointNormal laserScanToPointNormal(const cv::Mat & laserScan, int index)
|
||||
pcl::PointXYZRGB laserScanToPointRGB(const cv::Mat & laserScan, int index, unsigned char r, unsigned char g, unsigned char b)
|
||||
{
|
||||
UASSERT(!laserScan.empty() && index < laserScan.cols);
|
||||
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(5) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
pcl::PointXYZRGB output;
|
||||
const float * ptr = laserScan.ptr<float>(0, index);
|
||||
output.x = ptr[0];
|
||||
output.y = ptr[1];
|
||||
if(laserScan.channels() >= 3)
|
||||
if(laserScan.channels() >= 3 && laserScan.channels() != 5)
|
||||
{
|
||||
output.z = ptr[2];
|
||||
}
|
||||
@@ -1606,16 +1678,22 @@ pcl::PointXYZRGB laserScanToPointRGB(const cv::Mat & laserScan, int index, unsig
|
||||
pcl::PointXYZRGBNormal laserScanToPointRGBNormal(const cv::Mat & laserScan, int index, unsigned char r, unsigned char g, unsigned char b)
|
||||
{
|
||||
UASSERT(!laserScan.empty() && index < laserScan.cols);
|
||||
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(5) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
pcl::PointXYZRGBNormal output;
|
||||
const float * ptr = laserScan.ptr<float>(0, index);
|
||||
output.x = ptr[0];
|
||||
output.y = ptr[1];
|
||||
if(laserScan.channels() >= 3)
|
||||
if(laserScan.channels() >= 3 && laserScan.channels() != 5)
|
||||
{
|
||||
output.z = ptr[2];
|
||||
}
|
||||
if(laserScan.channels() == 6)
|
||||
if(laserScan.channels() == 5)
|
||||
{
|
||||
output.normal_x = ptr[2];
|
||||
output.normal_y = ptr[3];
|
||||
output.normal_z = ptr[4];
|
||||
}
|
||||
else if(laserScan.channels() == 6)
|
||||
{
|
||||
output.normal_x = ptr[3];
|
||||
output.normal_y = ptr[4];
|
||||
@@ -1646,12 +1724,13 @@ pcl::PointXYZRGBNormal laserScanToPointRGBNormal(const cv::Mat & laserScan, int
|
||||
void getMinMax3D(const cv::Mat & laserScan, cv::Point3f & min, cv::Point3f & max)
|
||||
{
|
||||
UASSERT(!laserScan.empty());
|
||||
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(5) || laserScan.type() == CV_32FC(6) || laserScan.type() == CV_32FC(7));
|
||||
|
||||
const float * ptr = laserScan.ptr<float>(0, 0);
|
||||
min.x = max.x = ptr[0];
|
||||
min.y = max.y = ptr[1];
|
||||
min.z = max.z = laserScan.channels() >= 3?ptr[2]:0.0f;
|
||||
bool is3d = laserScan.channels() >= 3 && laserScan.channels() != 5;
|
||||
min.z = max.z = is3d?ptr[2]:0.0f;
|
||||
for(int i=1; i<laserScan.cols; ++i)
|
||||
{
|
||||
ptr = laserScan.ptr<float>(0, i);
|
||||
@@ -1662,7 +1741,7 @@ void getMinMax3D(const cv::Mat & laserScan, cv::Point3f & min, cv::Point3f & max
|
||||
if(ptr[1] < min.y) min.y = ptr[1];
|
||||
else if(ptr[1] > max.y) max.y = ptr[1];
|
||||
|
||||
if(laserScan.channels() >= 3)
|
||||
if(is3d)
|
||||
{
|
||||
if(ptr[2] < min.z) min.z = ptr[2];
|
||||
else if(ptr[2] > max.z) max.z = ptr[2];
|
||||
|
||||
@@ -2011,12 +2011,13 @@ cv::Mat computeNormals(
|
||||
if(laserScan.channels() == 2)
|
||||
{
|
||||
normals = util3d::computeNormals2D(cloud, searchK, searchRadius);
|
||||
return util3d::laserScan2dFromPointCloud(*cloud, *normals);
|
||||
}
|
||||
else
|
||||
{
|
||||
normals = util3d::computeNormals(cloud, searchK, searchRadius);
|
||||
return util3d::laserScanFromPointCloud(*cloud, *normals);
|
||||
}
|
||||
return util3d::laserScanFromPointCloud(*cloud, *normals);
|
||||
}
|
||||
else // 4 channels
|
||||
{
|
||||
|
||||
@@ -38,61 +38,65 @@ namespace util3d
|
||||
|
||||
cv::Mat transformLaserScan(const cv::Mat & laserScan, const Transform & transform)
|
||||
{
|
||||
UASSERT(laserScan.empty() || laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6));
|
||||
UASSERT(laserScan.empty() || laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(5) || laserScan.type() == CV_32FC(6));
|
||||
|
||||
cv::Mat output = laserScan.clone();
|
||||
|
||||
if(!transform.isNull() && !transform.isIdentity())
|
||||
{
|
||||
Eigen::Affine3f transform3f = transform.toEigen3f();
|
||||
for(int i=0; i<laserScan.cols; ++i)
|
||||
{
|
||||
const float * ptr = laserScan.ptr<float>(0, i);
|
||||
float * out = output.ptr<float>(0, i);
|
||||
if(laserScan.type() == CV_32FC2)
|
||||
{
|
||||
pcl::PointXYZ pt(
|
||||
laserScan.at<cv::Vec2f>(i)[0],
|
||||
laserScan.at<cv::Vec2f>(i)[1], 0);
|
||||
pt = util3d::transformPoint(pt, transform);
|
||||
output.at<cv::Vec2f>(i)[0] = pt.x;
|
||||
output.at<cv::Vec2f>(i)[1] = pt.y;
|
||||
pcl::PointXYZ pt(ptr[0], ptr[1], 0);
|
||||
pt = pcl::transformPoint(pt, transform3f);
|
||||
out[0] = pt.x;
|
||||
out[1] = pt.y;
|
||||
}
|
||||
else if(laserScan.type() == CV_32FC3)
|
||||
else if(laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4))
|
||||
{
|
||||
pcl::PointXYZ pt(
|
||||
laserScan.at<cv::Vec3f>(i)[0],
|
||||
laserScan.at<cv::Vec3f>(i)[1],
|
||||
laserScan.at<cv::Vec3f>(i)[2]);
|
||||
pt = util3d::transformPoint(pt, transform);
|
||||
output.at<cv::Vec3f>(i)[0] = pt.x;
|
||||
output.at<cv::Vec3f>(i)[1] = pt.y;
|
||||
output.at<cv::Vec3f>(i)[2] = pt.z;
|
||||
const float * ptr = laserScan.ptr<float>(0, i);
|
||||
pcl::PointXYZ pt(ptr[0], ptr[1], ptr[2]);
|
||||
pt = pcl::transformPoint(pt, transform3f);
|
||||
out[0] = pt.x;
|
||||
out[1] = pt.y;
|
||||
out[2] = pt.z;
|
||||
}
|
||||
else if(laserScan.type() == CV_32FC(4))
|
||||
{
|
||||
pcl::PointXYZ pt(
|
||||
laserScan.at<cv::Vec4f>(i)[0],
|
||||
laserScan.at<cv::Vec4f>(i)[1],
|
||||
laserScan.at<cv::Vec4f>(i)[2]);
|
||||
pt = util3d::transformPoint(pt, transform);
|
||||
output.at<cv::Vec4f>(i)[0] = pt.x;
|
||||
output.at<cv::Vec4f>(i)[1] = pt.y;
|
||||
output.at<cv::Vec4f>(i)[2] = pt.z;
|
||||
}
|
||||
else
|
||||
else if(laserScan.type() == CV_32FC(5))
|
||||
{
|
||||
pcl::PointNormal pt;
|
||||
pt.x=laserScan.at<cv::Vec6f>(i)[0];
|
||||
pt.y=laserScan.at<cv::Vec6f>(i)[1];
|
||||
pt.z=laserScan.at<cv::Vec6f>(i)[2];
|
||||
pt.normal_x=laserScan.at<cv::Vec6f>(i)[3];
|
||||
pt.normal_y=laserScan.at<cv::Vec6f>(i)[4];
|
||||
pt.normal_z=laserScan.at<cv::Vec6f>(i)[5];
|
||||
pt.x=ptr[0];
|
||||
pt.y=ptr[1];
|
||||
pt.z=0;
|
||||
pt.normal_x=ptr[2];
|
||||
pt.normal_y=ptr[3];
|
||||
pt.normal_z=ptr[4];
|
||||
pt = util3d::transformPoint(pt, transform);
|
||||
output.at<cv::Vec6f>(i)[0] = pt.x;
|
||||
output.at<cv::Vec6f>(i)[1] = pt.y;
|
||||
output.at<cv::Vec6f>(i)[2] = pt.z;
|
||||
output.at<cv::Vec6f>(i)[3] = pt.normal_x;
|
||||
output.at<cv::Vec6f>(i)[4] = pt.normal_y;
|
||||
output.at<cv::Vec6f>(i)[5] = pt.normal_z;
|
||||
out[0] = pt.x;
|
||||
out[1] = pt.y;
|
||||
out[2] = pt.normal_x;
|
||||
out[3] = pt.normal_y;
|
||||
out[4] = pt.normal_z;
|
||||
}
|
||||
else // 6 and 7 channels
|
||||
{
|
||||
pcl::PointNormal pt;
|
||||
pt.x=ptr[0];
|
||||
pt.y=ptr[1];
|
||||
pt.z=ptr[2];
|
||||
pt.normal_x=ptr[3];
|
||||
pt.normal_y=ptr[4];
|
||||
pt.normal_z=ptr[5];
|
||||
pt = util3d::transformPoint(pt, transform);
|
||||
out[0] = pt.x;
|
||||
out[1] = pt.y;
|
||||
out[2] = pt.z;
|
||||
out[3] = pt.normal_x;
|
||||
out[4] = pt.normal_y;
|
||||
out[5] = pt.normal_z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3757,7 +3757,7 @@ void DatabaseViewer::updateConstraintView(
|
||||
constraintsViewer_->removeCloud("scan1");
|
||||
if(!dataFrom.laserScanRaw().empty())
|
||||
{
|
||||
if(dataFrom.laserScanRaw().channels() == 6)
|
||||
if(dataFrom.laserScanRaw().channels() >= 5)
|
||||
{
|
||||
pcl::PointCloud<pcl::PointNormal>::Ptr scan;
|
||||
scan = rtabmap::util3d::laserScanToPointCloudNormal(dataFrom.laserScanRaw(), dataFrom.laserScanInfo().localTransform());
|
||||
@@ -3780,7 +3780,7 @@ void DatabaseViewer::updateConstraintView(
|
||||
}
|
||||
if(!dataTo.laserScanRaw().empty())
|
||||
{
|
||||
if(dataTo.laserScanRaw().channels() == 6)
|
||||
if(dataTo.laserScanRaw().channels() >= 5)
|
||||
{
|
||||
pcl::PointCloud<pcl::PointNormal>::Ptr scan;
|
||||
scan = rtabmap::util3d::laserScanToPointCloudNormal(dataTo.laserScanRaw(), t*dataTo.laserScanInfo().localTransform());
|
||||
|
||||
@@ -57,12 +57,12 @@ public slots:
|
||||
void resetChanges();
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void contextMenuEvent(QContextMenuEvent * e) override;
|
||||
virtual void mousePressEvent(QMouseEvent *event);
|
||||
virtual void mouseMoveEvent(QMouseEvent *event);
|
||||
virtual void mouseReleaseEvent(QMouseEvent *event);
|
||||
virtual void paintEvent(QPaintEvent *event);
|
||||
virtual void resizeEvent(QResizeEvent *event);
|
||||
virtual void contextMenuEvent(QContextMenuEvent * e);
|
||||
|
||||
private:
|
||||
void drawLineTo(const QPoint &endPoint);
|
||||
|
||||
@@ -2888,7 +2888,7 @@ void MainWindow::createAndAddScanToMap(int nodeId, const Transform & pose, int m
|
||||
{
|
||||
cloudRGBWithNormals = util3d::laserScanToPointCloudRGBNormal(scan, iter->sensorData().laserScanInfo().localTransform());
|
||||
}
|
||||
else if(scan.channels() == 6 && _preferencesDialog->getCloudVoxelSizeScan(0) <= 0.0)
|
||||
else if((scan.channels() == 5 || scan.channels() == 6) && _preferencesDialog->getCloudVoxelSizeScan(0) <= 0.0)
|
||||
{
|
||||
cloudWithNormals = util3d::laserScanToPointCloudNormal(scan, iter->sensorData().laserScanInfo().localTransform());
|
||||
}
|
||||
@@ -2983,7 +2983,7 @@ void MainWindow::createAndAddScanToMap(int nodeId, const Transform & pose, int m
|
||||
pcl::PointCloud<pcl::Normal>::Ptr normals;
|
||||
if(cloud->size())
|
||||
{
|
||||
if(scan.channels() == 2)
|
||||
if(scan.channels() == 2 || scan.channels() == 5)
|
||||
{
|
||||
normals = util3d::computeFastOrganizedNormals2D(cloud, _preferencesDialog->getScanNormalKSearch(), _preferencesDialog->getScanNormalRadiusSearch(), scanViewpoint);
|
||||
}
|
||||
@@ -3024,7 +3024,14 @@ void MainWindow::createAndAddScanToMap(int nodeId, const Transform & pose, int m
|
||||
added = _cloudViewer->addCloud(scanName, cloudWithNormals, pose, color);
|
||||
if(added && nodeId > 0)
|
||||
{
|
||||
scan = util3d::laserScanFromPointCloud(*cloudWithNormals);
|
||||
if(scan.channels() == 5)
|
||||
{
|
||||
scan = util3d::laserScan2dFromPointCloud(*cloudWithNormals);
|
||||
}
|
||||
else
|
||||
{
|
||||
scan = util3d::laserScanFromPointCloud(*cloudWithNormals);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(cloudRGB.get())
|
||||
|
||||
@@ -63,25 +63,16 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-831</y>
|
||||
<y>0</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>1</number>
|
||||
<number>21</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_22">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
|
||||
@@ -4570,16 +4561,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>
|
||||
@@ -12580,16 +12562,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>
|
||||
@@ -12729,16 +12702,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>
|
||||
@@ -12896,16 +12860,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>
|
||||
@@ -12985,16 +12940,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>
|
||||
@@ -13106,16 +13052,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>
|
||||
@@ -13808,7 +13745,7 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="label_144">
|
||||
<property name="text">
|
||||
<string>Point to plane ICP. Only for ICP 3D.</string>
|
||||
<string>Point to plane ICP.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
|
||||
Reference in New Issue
Block a user