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 }