Exemplo n.º 1
0
void transformation (int argc, char *argv[])
{
	bool isCSV = true;
	
	typedef PointMatcher<float> PM;
	typedef PM::DataPoints DP;
	typedef PM::Parameters Parameters;
	
	// Load point clouds
	//const DP ref(DP::load(argv[1]));
	//const DP data(DP::load(argv[2]));

	const DP ref(DP::load("Golden.csv"));
	const DP data(DP::load("Final.csv"));
	// Create the default ICP algorithm
	PM::ICP icp;
	
    string configFile = "my_config.yaml";
    
	if (configFile.empty())
	{
		// See the implementation of setDefault() to create a custom ICP algorithm
		icp.setDefault();
	}
	else
	{
		// load YAML config
		ifstream ifs(configFile.c_str());
		if (!ifs.good())
		{
			cout << "Cannot open config file" << configFile;
		}
		icp.loadFromYaml(ifs);
	}


	// Compute the transformation to express data in ref
	PM::TransformationParameters T = icp(data, ref);
	

	// Transform data to express it in ref
	DP data_out(data);
	icp.transformations.apply(data_out, T);
	
	// Safe files to see the results
	ref.save("test_ref.vtk");
	data.save("test_data_in.vtk");
	data_out.save("test_data_out.vtk");
	cout << "Final transformation:" << endl << T << endl;

    // Updating transform matrix 
    T(0,3) = offset_x;
    T(1,3) = offset_y;
    T(2,3) = offset_z;
	cout << "Final transformation:" << endl << T << endl;

    if(MATRIX_DUMP == 1) {
        for(int i = 0; i < 4; i++)
        {
            Trans_dump << T(i,0) <<"," <<T(i,1) <<"," << T(i,2) << "," << T(i,3) <<endl;
        }
         Trans_dump << endl << endl;
    }
     
    float R[3][3];
    
    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 3; j++)
            R[j][i] = T(i,j); // Euler angle function uses Column Major
    }
    	
    Eigen::Matrix4f transform_1 = Eigen::Matrix4f::Identity();
    //Eigen::Affine3f A;
    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 3; j++)
            transform_1 (i,j) = T(i,j); // Euler angle function uses Column Major
            //transform_1 (i,j) = R[i][j]; // Euler angle function uses Column Major
    }
    
    cout << "Writing to cloud transformed" <<endl;
    pcl::transformPointCloud (*cloud_golden, *cloud_transformed, transform_1);
    eulerAngles(R); 

    cout << "Euler Angles : X  = "  << Angle[0] * 180/ PI  << ", Y = " << Angle[1] * 180/ PI << " , Z = " <<    Angle[2] * 180/ PI << endl;
    //pcl::getTransformation(0,0,0,-1*Angle[2],-1*Angle[0],-1*Angle[1]);
    //transform_1 = A.matrix();
    //pcl::transformPointCloud (*cloud_golden, *cloud_transformed, transform_1);

}
bool CloudMatcher::match(pointmatcher_ros::MatchClouds::Request& req, pointmatcher_ros::MatchClouds::Response& res)
{
	// get and check reference
	const DP referenceCloud(PointMatcher_ros::rosMsgToPointMatcherCloud<float>(req.reference));
	const unsigned referenceGoodCount(referenceCloud.features.cols());
	const unsigned referencePointCount(req.reference.width * req.reference.height);
	const double referenceGoodRatio(double(referenceGoodCount) / double(referencePointCount));
	
	if (referenceGoodCount == 0)
	{
		ROS_ERROR("I found no good points in the reference cloud");
		return false;
	}
	if (referenceGoodRatio < 0.5)
	{
        ROS_WARN_STREAM("Partial reference cloud! Missing " << 100 - referenceGoodRatio*100.0 <<
                        "% of the cloud (received " << referenceGoodCount << ")");
	}
	
	// get and check reading
	const DP readingCloud(PointMatcher_ros::rosMsgToPointMatcherCloud<float>(req.readings));
	const unsigned readingGoodCount(referenceCloud.features.cols());
	const unsigned readingPointCount(req.readings.width * req.readings.height);
	const double readingGoodRatio(double(readingGoodCount) / double(readingPointCount));
	
	if (readingGoodCount == 0)
	{
		ROS_ERROR("I found no good points in the reading cloud");
		return false;
	}
	if (readingGoodRatio < 0.5)
	{
		ROS_WARN_STREAM("Partial reference cloud! Missing " << 100 - readingGoodRatio*100.0 << "% of the cloud (received " << readingGoodCount << ")");
	}
	
	// check dimensions
	if (referenceCloud.features.rows() != readingCloud.features.rows())
	{
        ROS_ERROR_STREAM("Dimensionality missmatch: reference cloud is " <<
                         referenceCloud.features.rows() - 1 << " while reading cloud is " <<
                         readingCloud.features.rows() - 1);
		return false;
	}
	
	// call ICP
    PM::TransformationParameters transform;
	try 
	{
        transform = icp(readingCloud, referenceCloud);
		tf::transformTFToMsg(PointMatcher_ros::eigenMatrixToTransform<float>(transform), res.transform);
		ROS_INFO_STREAM("match ratio: " << icp.errorMinimizer->getWeightedPointUsedRatio() << endl);
	}
	catch (PM::ConvergenceError error)
	{
		ROS_ERROR_STREAM("ICP failed to converge: " << error.what());
		return false;
	}

    if(traceMatching)
    {
        std::stringstream ss;
        ss << "reading_" << matchedCloudsCount << ".vtk";
        readingCloud.save(ss.str());

        ss.str(std::string());
        ss << "reference_" << matchedCloudsCount << ".vtk";
        referenceCloud.save(ss.str());

        PM::Transformation* rigidTrans;
        rigidTrans = PM::get().REG(Transformation).create("RigidTransformation");
        PM::DataPoints matchedCloud = rigidTrans->compute(readingCloud, transform);

        ss.str(std::string());
        ss << "matched_" << matchedCloudsCount << ".vtk";
        matchedCloud.save(ss.str());
    }

    matchedCloudsCount++;
	
	return true;
}