00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00035 #include <stdio.h>
00036 #include <ros/ros.h>
00037 #include <laser_geometry/laser_geometry.h>
00038 #include <sensor_msgs/LaserScan.h>
00039 #include <sensor_msgs/PointCloud2.h>
00040 #include <tf/transform_listener.h>
00041 #include <pcl_ros/transforms.h>
00042 #include <pcl/ros/conversions.h>
00043 #include <pcl/point_cloud.h>
00044 #include <pcl/point_types.h>
00045 #include <pcl/segmentation/extract_polygonal_prism_data.h>
00046 #include <pcl/filters/extract_indices.h>
00047 #include <pcl/filters/project_inliers.h>
00048 
00049 ros::NodeHandle* p_n;
00050 tf::TransformListener *p_listener;
00051 pcl::PointCloud<pcl::PointXYZ> pc_accumulated;
00052 pcl::PointCloud<pcl::PointXYZ> convex_hull;
00053 double perpendicular_treshold = 0.2;
00054 double output_freq;
00055 
00056 bool laserscan_0_arrived=false;
00057 
00058 void filter_cloud(pcl::PointCloud<pcl::PointXYZ>* pc_in, std::string pc_frame_id)
00059 {
00060         pcl::PointCloud<pcl::PointXYZ> pc_transformed;
00061         pcl::PointCloud<pcl::PointXYZ> pc_filtered;
00062         pcl::PointCloud<pcl::PointXYZ> pc_projected;
00063         tf::StampedTransform transform;
00064 
00065         
00066         try
00067         {
00068                 
00069                 p_listener->lookupTransform(pc_frame_id, ros::names::remap("/tracking_frame"), ros::Time(0), transform);
00070                 
00071         }
00072         catch (tf::TransformException ex)
00073         {
00074                 ROS_ERROR("%s",ex.what());
00075         }
00076 
00077 
00078         pcl_ros::transformPointCloud(*pc_in,pc_transformed,transform.inverse());
00079         pc_transformed.header.frame_id = ros::names::remap("/tracking_frame");
00080         
00081 
00082         pcl::ExtractPolygonalPrismData<pcl::PointXYZ> epp; 
00083         pcl::PointCloud<pcl::PointXYZ>::ConstPtr input_cloud_constptr; 
00084         input_cloud_constptr.reset (new pcl::PointCloud<pcl::PointXYZ> (pc_transformed));
00085         pcl::PointCloud<pcl::PointXYZ>::ConstPtr convex_hull_constptr;
00086         convex_hull_constptr.reset (new pcl::PointCloud<pcl::PointXYZ> (convex_hull));
00087 
00088         
00089         pcl::ExtractIndices<pcl::PointXYZ> extract; 
00090         pcl::PointIndices::Ptr indices;
00091         indices.reset();
00092         indices = pcl::PointIndices::Ptr(new pcl::PointIndices); 
00093 
00094         
00095         epp.setInputCloud(input_cloud_constptr);
00096         epp.setInputPlanarHull(convex_hull_constptr);
00097         epp.setHeightLimits(-perpendicular_treshold, perpendicular_treshold); 
00098         epp.setViewPoint(0,0,0); 
00099         epp.segment(*indices);
00100 
00101         extract.setInputCloud(pc_transformed.makeShared());
00102         extract.setIndices(indices);
00103         extract.setNegative(false);
00104         extract.filter(pc_filtered);
00105 
00106         pcl::ProjectInliers<pcl::PointXYZ> projection;
00107         projection.setModelType(pcl::SACMODEL_PLANE); 
00108         pcl::ModelCoefficients::Ptr coeff(new pcl::ModelCoefficients);
00109         coeff->values.resize(4);
00110         coeff->values[0] = 0;
00111         coeff->values[1] = 0;
00112         coeff->values[2] = 1;
00113         coeff->values[3] = 0;
00114 
00115         projection.setInputCloud(pc_filtered.makeShared());
00116         projection.setModelCoefficients(coeff);
00117         
00118 
00119         coeff.reset();
00120         input_cloud_constptr.reset();
00121         convex_hull_constptr.reset();
00122         indices.reset();
00123 
00124 
00125     pc_accumulated += pc_transformed;
00126 
00127 
00128 
00129 
00130 
00131 
00132 }
00133 
00134 void scan_0_cb (const sensor_msgs::LaserScan::ConstPtr& scan_in)
00135 {
00136         laser_geometry::LaserProjection projector;
00137         sensor_msgs::PointCloud2 pcmsg_in;
00138 
00139         projector.transformLaserScanToPointCloud(scan_in->header.frame_id, *scan_in,pcmsg_in,*p_listener);   
00140         pcmsg_in.header.stamp=ros::Time();
00141         pcmsg_in.header.frame_id=scan_in->header.frame_id;
00142 
00143         pcl::PointCloud<pcl::PointXYZ> pc_in;
00144         pcl::fromROSMsg(pcmsg_in,pc_in);
00145         filter_cloud(&pc_in, scan_in->header.frame_id);
00146         
00147         laserscan_0_arrived=true;
00148 }
00149 
00150 int main(int argc, char **argv)
00151 {
00152         ros::init(argc, argv, "simple_planar_pc_generator_node");
00153         ros::NodeHandle n("~");
00154         tf::TransformListener listener(n,ros::Duration(10));
00155         p_listener=&listener;
00156         p_n=&n;
00157         
00158         n.param("output_frequency", output_freq, 200.0);
00159         n.param("perpendicular_treshold", perpendicular_treshold, 0.1);
00160 
00161         
00162         if (ros::names::remap("/tracking_frame")=="/tracking_frame")
00163         {
00164                 ROS_ERROR("/tracking_frame was not remapped. Aborting program.");       
00165                 ros::shutdown();
00166         }
00167 
00168         pc_accumulated.header.frame_id = ros::names::remap("/tracking_frame");
00169 
00170         ros::Subscriber sub_0 = n.subscribe ("/laserscan0", 1, scan_0_cb);
00171         
00172         
00173         ros::Publisher pub = n.advertise<sensor_msgs::PointCloud2>("/pc_out", 1);
00174 
00175         
00176         
00177         convex_hull.header.frame_id = ros::names::remap("/tracking_frame");
00178         pcl::PointXYZ pt;
00179         pt.x = -500; pt.y=-500; pt.z=0;
00180         convex_hull.points.push_back(pt);
00181 
00182         pt.x = 500; pt.y=-500; pt.z=0;
00183         convex_hull.points.push_back(pt);
00184 
00185         pt.x = 500; pt.y= 500; pt.z=0;
00186         convex_hull.points.push_back(pt);
00187 
00188         pt.x = -500; pt.y=500; pt.z=0;
00189         convex_hull.points.push_back(pt);
00190 
00191         ros::Rate loop_rate(output_freq);
00192         
00193         while (n.ok())
00194         {
00195                 ros::spinOnce();
00196 
00197                 if (laserscan_0_arrived)
00198                 {
00199                         laserscan_0_arrived=false;
00200                         
00201                         sensor_msgs::PointCloud2 pcmsg_out;
00202                         pcl::toROSMsg(pc_accumulated, pcmsg_out);
00203                         pcmsg_out.header.stamp = ros::Time::now();
00204 
00205 
00206 
00207                         pub.publish(pcmsg_out);
00208                         pc_accumulated.erase(pc_accumulated.begin(), pc_accumulated.end());
00209                 }
00210 
00211 
00212                 loop_rate.sleep();      
00213         }
00214 }