コード例 #1
0
  bool SnapIt::processModelPlane(jsk_pcl_ros::CallSnapIt::Request& req,
                                 jsk_pcl_ros::CallSnapIt::Response& res) {
    // first build plane model
    geometry_msgs::PolygonStamped target_plane = req.request.target_plane;
    // check the size of the points
    if (target_plane.polygon.points.size() < 3) {
      NODELET_ERROR("not enough points included in target_plane");
      return false;
    }
    pcl::PointCloud<pcl::PointXYZ>::Ptr points_inside_pole (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointIndices::Ptr inliers(new pcl::PointIndices);
    EigenVector3fVector points;
    Eigen::Vector3f n, p;
    if (!extractPointsInsidePlanePole(target_plane, inliers, points, n, p)) {
      return false;
    }

    if (inliers->indices.size() < 3) {
      NODELET_ERROR("not enough points inside of the target_plane");
      return false;
    }
    
    pcl::ExtractIndices<pcl::PointXYZ> extract;
    extract.setInputCloud(input_);
    extract.setIndices(inliers);
    extract.filter(*points_inside_pole);

    publishPointCloud(debug_candidate_points_pub_, points_inside_pole);
    
    // estimate plane
    
    pcl::ModelCoefficients::Ptr plane_coefficients (new pcl::ModelCoefficients);
    pcl::PointIndices::Ptr plane_inliers (new pcl::PointIndices);
    extractPlanePoints(points_inside_pole, plane_inliers, plane_coefficients,
                       n, req.request.eps_angle);

    if (plane_inliers->indices.size () == 0)
    {
      NODELET_ERROR ("Could not estimate a planar model for the given dataset.");
      return false;
    }

    // extract plane points
    pcl::PointCloud<pcl::PointXYZ>::Ptr plane_points (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::ProjectInliers<pcl::PointXYZ> proj;
    proj.setModelType (pcl::SACMODEL_PLANE);
    proj.setIndices (plane_inliers);
    proj.setInputCloud (points_inside_pole);
    proj.setModelCoefficients (plane_coefficients);
    proj.filter (*plane_points);
    publishPointCloud(debug_candidate_points_pub3_, plane_points);
    
    // next, compute convexhull and centroid
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_hull (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::ConcaveHull<pcl::PointXYZ> chull;
    chull.setInputCloud (plane_points);
    chull.setDimension(2);
    chull.setAlpha (0.1);
    
    chull.reconstruct (*cloud_hull);

    if (cloud_hull->points.size() < 3) {
      NODELET_ERROR("failed to estimate convex hull");
      return false;
    }
    publishConvexHullMarker(cloud_hull);
    
    Eigen::Vector4f C_new_4f;
    pcl::compute3DCentroid(*cloud_hull, C_new_4f);
    Eigen::Vector3f C_new;
    for (size_t i = 0; i < 3; i++) {
      C_new[i] = C_new_4f[i];
    }
    
    Eigen::Vector3f n_prime;
    n_prime[0] = plane_coefficients->values[0];
    n_prime[1] = plane_coefficients->values[1];
    n_prime[2] = plane_coefficients->values[2];
    plane_coefficients->values[3] = plane_coefficients->values[3] / n_prime.norm();
    n_prime.normalize();
    
    if (n_prime.dot(n) < 0) {
      n_prime = - n_prime;
      plane_coefficients->values[3] = - plane_coefficients->values[3];
    }
    
    Eigen::Vector3f n_cross = n.cross(n_prime);
    double theta = asin(n_cross.norm());

    Eigen::Quaternionf trans (Eigen::AngleAxisf(theta, n_cross.normalized()));
    
    // compute C
    Eigen::Vector3f C_orig(0, 0, 0);
    for (size_t i = 0; i < points.size(); i++) {
      C_orig = C_orig + points[i];
    }
    C_orig = C_orig / points.size();
    // compute C
    Eigen::Vector3f C = trans * C_orig;
    

    Eigen::Affine3f A = Eigen::Translation3f(C) * Eigen::Translation3f(C_new - C) * trans * Eigen::Translation3f(C_orig).inverse();
    tf::poseEigenToMsg((Eigen::Affine3d)A, res.transformation);

    geometry_msgs::PointStamped centroid;
    centroid.point.x = C_orig[0];
    centroid.point.y = C_orig[1];
    centroid.point.z = C_orig[2];
    centroid.header = target_plane.header;
    debug_centroid_pub_.publish(centroid);

    geometry_msgs::PointStamped centroid_transformed;
    centroid_transformed.point.x = C_new[0];
    centroid_transformed.point.y = C_new[1];
    centroid_transformed.point.z = C_new[2];
    centroid_transformed.header = target_plane.header;
    debug_centroid_after_trans_pub_.publish(centroid_transformed);
    
    return true;
  }
コード例 #2
0
void rgb_pcl::cloud_cb (const sensor_msgs::PointCloud2ConstPtr& input){
	
	// Container for original & filtered data
#if PR2
	if(target_frame.find(base_frame) == std::string::npos){
		getTransformCloud(input, *input);
	}
	sensor_msgs::PointCloud2 in = *input;
	sensor_msgs::PointCloud2 out;
	pcl_ros::transformPointCloud(target_frame, net_transform, in, out);
#endif
	
// 	ROS_INFO("Cloud acquired...");
	
	pcl::PCLPointCloud2* cloud = new pcl::PCLPointCloud2; 
	pcl::PCLPointCloud2ConstPtr cloudPtr(cloud);
	pcl::PCLPointCloud2::Ptr cloud_filtered_blob (new pcl::PCLPointCloud2);
				  
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZRGB>), 
						 cloud_p (new pcl::PointCloud<pcl::PointXYZRGB>), 
						 cloud_f (new pcl::PointCloud<pcl::PointXYZRGB>);
						 
	Mat displayImage = cv::Mat(Size(640, 480), CV_8UC3);
	displayImage = Scalar(120);

	// Convert to PCL data type
#if PR2
	pcl_conversions::toPCL(out, *cloud);
#endif
#if !PR2
	pcl_conversions::toPCL(*input, *cloud);
#endif
// 	ROS_INFO("\t=>Cloud rotated...");

	// Perform the actual filtering
	pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
	sor.setInputCloud (cloudPtr);
	sor.setLeafSize (0.005, 0.005, 0.005);
	sor.filter (*cloud_filtered_blob);
	
	pcl::fromPCLPointCloud2 (*cloud_filtered_blob, *cloud_filtered);

	ModelCoefficientsPtr coefficients (new pcl::ModelCoefficients);
	
	PointCloudPtr plane_points(new PointCloud), point_points_2d_hull(new PointCloud);
		
	std::vector<PointCloudPtr> object_clouds;
	pcl::PointCloud<pcl::PointXYZRGB> combinedCloud;
	
#if PR2
	make_crop_box_marker(marker_publisher, base_frame, 0, 0.2, -1, 0.2, 1.3, 2, 1.3);
// 	Define your cube with two points in space: 
	Eigen::Vector4f minPoint; 
	minPoint[0]=0.2;  // define minimum point x 
	minPoint[1]=-1;  // define minimum point y 
	minPoint[2]=0.2;  // define minimum point z 
	Eigen::Vector4f maxPoint; 
	maxPoint[0]=1.5;  // define max point x 
	maxPoint[1]=1;  // define max point y 
	maxPoint[2]=1.5;  // define max point z 

	pcl::CropBox<pcl::PointXYZRGB> cropFilter; 
	cropFilter.setInputCloud (cloud_filtered); 
	cropFilter.setMin(minPoint); 
	cropFilter.setMax(maxPoint); 

   	cropFilter.filter (*cloud_filtered); 
#endif
	
#if !PR2
	//Rotate the point cloud
	Eigen::Affine3f transform_1 = Eigen::Affine3f::Identity();

	// Define a rotation matrix (see https://en.wikipedia.org/wiki/Rotation_matrix)
	float theta = M_PI; // The angle of rotation in radians

	// Define a translation of 0 meters on the x axis
	transform_1.translation() << 0.0, 0.0, 1.0;

	// The same rotation matrix as before; tetha radians arround X axis
	transform_1.rotate (Eigen::AngleAxisf (theta, Eigen::Vector3f::UnitX()));

	// Executing the transformation
	pcl::transformPointCloud (*cloud_filtered, *cloud_filtered, transform_1);
#endif
	
	interpretTableScene(cloud_filtered, coefficients, plane_points, point_points_2d_hull, object_clouds);
	
	int c = 0;
#if PUBLISH_CLOUDS
	int ID_object = -1;
#endif
	for(auto cloudCluster: object_clouds){
// 		get_cloud_matching(cloudCluster); //histogram matching
	
#if PUBLISH_CLOUDS
		ID_object = c;
#endif
		combinedCloud += *cloudCluster;
		combinedCloud.header = cloud_filtered->header;
		c++;
	}
	
#if DISPLAY
	drawPointCloud(combinedCloud, displayImage);
#endif
	
	getTracker(object_clouds, displayImage);
	
	stateDetection();
// 	ROS_INFO("\t=>Cloud analysed...");
	
#if PUBLISH_CLOUDS
	
	sensor_msgs::PointCloud2 output;
	
	if(object_clouds.size() >= ID_object && ID_object >= 0){
		pcl::toROSMsg(combinedCloud, output);
		// Publish the data
		pub.publish (output);
	}
	
#endif
	
	end = ros::Time::now();
	std::stringstream ss;
	ss <<(end-begin);
	string s_FPS = ss.str();
#if DISPLAY
	cv::putText(displayImage, "FPS: "+to_string((int)1/(stof(s_FPS))) + "   Desired: "+to_string(DESIRED_FPS), cv::Point(10, 10), CV_FONT_HERSHEY_COMPLEX, 0.4, Scalar(0,0,0));
	imshow("RGB", displayImage);
#endif
	waitKey(1);

	begin = ros::Time::now();
	
}