OdometryICP: added p2p (point to point) option

git-svn-id: http://rtabmap.googlecode.com/svn/trunk/rtabmap@1631 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
matlabbe
2014-08-05 00:35:21 +00:00
parent a0da05a352
commit 52af62394e
3 changed files with 88 additions and 36 deletions

View File

@@ -99,6 +99,7 @@ public:
float maxCorrespondenceDistance = 0.05f, float maxCorrespondenceDistance = 0.05f,
int maxIterations = 30, int maxIterations = 30,
float maxFitness = 0.01f, float maxFitness = 0.01f,
bool pointToPlane = true,
const ParametersMap & odometryParameter = rtabmap::ParametersMap()); const ParametersMap & odometryParameter = rtabmap::ParametersMap());
void reset(); void reset();
@@ -112,8 +113,10 @@ private:
float _maxCorrespondenceDistance; float _maxCorrespondenceDistance;
int _maxIterations; int _maxIterations;
float _maxFitness; float _maxFitness;
bool _pointToPlane;
pcl::PointCloud<pcl::PointNormal>::Ptr _previousCloud; pcl::PointCloud<pcl::PointNormal>::Ptr _previousCloudNormal; // for point ot plane
pcl::PointCloud<pcl::PointXYZ>::Ptr _previousCloud; // for point to point
}; };
// return true if odometry is correctly computed // return true if odometry is correctly computed

View File

@@ -355,6 +355,7 @@ OdometryICP::OdometryICP(int decimation,
float maxCorrespondenceDistance, float maxCorrespondenceDistance,
int maxIterations, int maxIterations,
float maxFitness, float maxFitness,
bool pointToPlane,
const ParametersMap & odometryParameter) : const ParametersMap & odometryParameter) :
Odometry(odometryParameter), Odometry(odometryParameter),
_decimation(decimation), _decimation(decimation),
@@ -363,14 +364,17 @@ OdometryICP::OdometryICP(int decimation,
_maxCorrespondenceDistance(maxCorrespondenceDistance), _maxCorrespondenceDistance(maxCorrespondenceDistance),
_maxIterations(maxIterations), _maxIterations(maxIterations),
_maxFitness(maxFitness), _maxFitness(maxFitness),
_previousCloud(new pcl::PointCloud<pcl::PointNormal>) _pointToPlane(pointToPlane),
_previousCloudNormal(new pcl::PointCloud<pcl::PointNormal>),
_previousCloud(new pcl::PointCloud<pcl::PointXYZ>)
{ {
} }
void OdometryICP::reset() void OdometryICP::reset()
{ {
Odometry::reset(); Odometry::reset();
_previousCloud.reset(new pcl::PointCloud<pcl::PointNormal>); _previousCloudNormal.reset(new pcl::PointCloud<pcl::PointNormal>);
_previousCloud.reset(new pcl::PointCloud<pcl::PointXYZ>);
} }
// return not null transform if odometry is correctly computed // return not null transform if odometry is correctly computed
@@ -396,44 +400,81 @@ Transform OdometryICP::computeTransform(Image & image, int * quality)
_samples, _samples,
image.localTransform()); image.localTransform());
pcl::PointCloud<pcl::PointNormal>::Ptr newCloud = util3d::computeNormals(newCloudXYZ); if(_pointToPlane)
std::vector<int> indices;
newCloud = util3d::removeNaNNormalsFromPointCloud(newCloud);
if(newCloudXYZ->size() != newCloud->size())
{ {
UWARN("removed nan normals..."); pcl::PointCloud<pcl::PointNormal>::Ptr newCloud = util3d::computeNormals(newCloudXYZ);
}
if(_previousCloud->size() > minPoints && newCloud->size() > minPoints) std::vector<int> indices;
{ newCloud = util3d::removeNaNNormalsFromPointCloud(newCloud);
Transform transform = util3d::icpPointToPlane(newCloud, if(newCloudXYZ->size() != newCloud->size())
_previousCloud,
_maxCorrespondenceDistance,
_maxIterations,
hasConverged,
fitness);
//pcl::io::savePCDFile("old.pcd", *_previousCloud);
//pcl::io::savePCDFile("new.pcd", *newCloud);
//pcl::PointCloud<pcl::PointXYZ>::Ptr newCloudTransformed = util3d::transformPointCloud(newCloud, transform);
//pcl::io::savePCDFile("newicp.pcd", *newCloudTransformed);
if(hasConverged && (_maxFitness == 0 || fitness < _maxFitness))
{ {
output = transform; UWARN("removed nan normals...");
_previousCloud = newCloud;
} }
else
if(_previousCloudNormal->size() > minPoints && newCloud->size() > minPoints)
{ {
UWARN("Transform not valid (hasConverged=%s fitness = %f < %f)", Transform transform = util3d::icpPointToPlane(newCloud,
hasConverged?"true":"false", fitness, _maxFitness); _previousCloudNormal,
_maxCorrespondenceDistance,
_maxIterations,
hasConverged,
fitness);
//pcl::io::savePCDFile("old.pcd", *_previousCloud);
//pcl::io::savePCDFile("new.pcd", *newCloud);
//pcl::PointCloud<pcl::PointXYZ>::Ptr newCloudTransformed = util3d::transformPointCloud(newCloud, transform);
//pcl::io::savePCDFile("newicp.pcd", *newCloudTransformed);
if(hasConverged && (_maxFitness == 0 || fitness < _maxFitness))
{
output = transform;
_previousCloudNormal = newCloud;
}
else
{
UWARN("Transform not valid (hasConverged=%s fitness = %f < %f)",
hasConverged?"true":"false", fitness, _maxFitness);
}
}
else if(newCloud->size() > minPoints)
{
output.setIdentity();
_previousCloudNormal = newCloud;
} }
} }
else if(newCloud->size() > minPoints) else
{ {
output.setIdentity(); //point to point
_previousCloud = newCloud; if(_previousCloud->size() > minPoints && newCloudXYZ->size() > minPoints)
{
Transform transform = util3d::icp(newCloudXYZ,
_previousCloud,
_maxCorrespondenceDistance,
_maxIterations,
hasConverged,
fitness);
//pcl::io::savePCDFile("old.pcd", *_previousCloudNormal);
//pcl::io::savePCDFile("new.pcd", *newCloud);
//pcl::PointCloud<pcl::PointXYZ>::Ptr newCloudTransformed = util3d::transformPointCloud(newCloud, transform);
//pcl::io::savePCDFile("newicp.pcd", *newCloudTransformed);
if(hasConverged && (_maxFitness == 0 || fitness < _maxFitness))
{
output = transform;
_previousCloud = newCloudXYZ;
}
else
{
UWARN("Transform not valid (hasConverged=%s fitness = %f < %f)",
hasConverged?"true":"false", fitness, _maxFitness);
}
}
else if(newCloudXYZ->size() > minPoints)
{
output.setIdentity();
_previousCloud = newCloudXYZ;
}
} }
} }
else else
@@ -445,7 +486,7 @@ Transform OdometryICP::computeTransform(Image & image, int * quality)
timer.elapsed(), timer.elapsed(),
hasConverged?"true":"false", hasConverged?"true":"false",
fitness, fitness,
(int)_previousCloud->size()); (int)(_pointToPlane?_previousCloudNormal->size():_previousCloud->size()));
return output; return output;
} }
@@ -511,7 +552,7 @@ void OdometryThread::mainLoop()
getImage(image); getImage(image);
if(!image.empty()) if(!image.empty())
{ {
int quality = 0; int quality = -1;
Transform pose = _odometry->process(image, &quality); Transform pose = _odometry->process(image, &quality);
image.setPose(pose); // a null pose notify that odometry could not be computed image.setPose(pose); // a null pose notify that odometry could not be computed
this->post(new OdometryEvent(image, quality)); this->post(new OdometryEvent(image, quality));

View File

@@ -45,6 +45,7 @@ void showUsage()
" -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" " -s # ICP samples (default 0, not used if voxel is set.)\n"
" -f #.# ICP fitness (default 0.01)\n" " -f #.# ICP fitness (default 0.01)\n"
" -p2p ICP point to point (default point to plane)"
"\n" "\n"
" -debug Log debug messages\n" " -debug Log debug messages\n"
"\n" "\n"
@@ -88,6 +89,7 @@ int main (int argc, char * argv[])
float sec = 0.0f; float sec = 0.0f;
bool gpu = false; bool gpu = false;
int localHistory = 0; int localHistory = 0;
bool p2p = false;
for(int i=1; i<argc; ++i) for(int i=1; i<argc; ++i)
{ {
@@ -493,6 +495,11 @@ int main (int argc, char * argv[])
icp = true; icp = true;
continue; continue;
} }
if(strcmp(argv[i], "-p2p") == 0)
{
p2p = true;
continue;
}
if(strcmp(argv[i], "-debug") == 0) if(strcmp(argv[i], "-debug") == 0)
{ {
ULogger::setLevel(ULogger::kDebug); ULogger::setLevel(ULogger::kDebug);
@@ -642,8 +649,9 @@ int main (int argc, char * argv[])
UINFO("Cloud voxel size = %f", voxel); UINFO("Cloud voxel size = %f", voxel);
UINFO("Cloud samples = %d", samples); UINFO("Cloud samples = %d", samples);
UINFO("Cloud fitness = %f", fitness); UINFO("Cloud fitness = %f", fitness);
UINFO("Cloud point to plane = %s", p2p?"false":"true");
odom = new rtabmap::OdometryICP(decimation, voxel, samples, distance, iterations, fitness); odom = new rtabmap::OdometryICP(decimation, voxel, samples, distance, iterations, fitness, !p2p);
} }
rtabmap::OdometryThread odomThread(odom); rtabmap::OdometryThread odomThread(odom);
rtabmap::OdometryViewer odomViewer(maxClouds, 2, 0.0, 50); rtabmap::OdometryViewer odomViewer(maxClouds, 2, 0.0, 50);