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 
00036 #ifndef _extract_polygon_primitives_CPP_
00037 #define _extract_polygon_primitives_CPP_
00038 
00039 
00040 #include <vector>
00041 #include <fstream>
00042 #include <stdio.h>
00043 
00044 #include "extract_polygon_primitives.h"
00045 
00046 
00047 
00048 
00049 #define _VERTICAL_PLG_LONG_EXPANSION_ 0.2
00050 #define _VERTICAL_PLG_PERP_EXPANSION_ 0.5
00051 #define _GROUND_PLG_LONG_EXPANSION_ 15 
00052 #define _GROUND_PLG_PERP_EXPANSION_ 0.3
00053 
00054 #define _MAX_ITERATION_TIME_ 20.0
00055 #define DEBUG 0
00056 #define USE_EXPANSION 1
00057 
00058 bool polygon_has_quality(double area, double solidity)
00059 {
00060         
00061         if (area > 7)
00062         {
00063                 if (solidity >48)
00064                         return true;
00065                 else
00066                         return false;
00067         }
00068         else
00069                 return false;
00070 
00071 
00072         
00073         
00074         
00075         
00076         
00077         
00078         
00079         
00080         
00081 }
00082 
00083 
00084 int publish_point_cloud(std::vector<boost::shared_ptr<ros::Publisher> >* publishers, pcl::PointCloud<pcl::PointXYZ>* pc, std::string topic_name)
00085 {
00086         int index=-1;
00087         for (size_t i=0; publishers->size(); ++i)
00088         {
00089                 if ((*publishers)[i]->getTopic()==topic_name)   
00090                 {
00091                         index=i;
00092                         break;
00093                 }
00094         }
00095 
00096         if (index==-1)
00097                 ROS_ERROR("Topic name %s not in the publishers list. Cannot publish.", topic_name.c_str());
00098 
00099         sensor_msgs::PointCloud2 cloud_msg;  
00100         pcl::toROSMsg(*pc, cloud_msg);
00101         (*publishers)[index]->publish(cloud_msg);
00102         return 1;
00103 }
00104 
00105 int publish_point_cloud(std::vector<boost::shared_ptr<ros::Publisher> >* publishers, pcl::PointCloud<pcl::PointXYZ>::Ptr pc, std::string topic_name)
00106 {
00107 
00108         pcl::PointCloud<pcl::PointXYZ> cloud_tmp; 
00109         cloud_tmp = *pc;
00110         return publish_point_cloud(publishers, &cloud_tmp, topic_name);
00111 }
00118 int main(int argc, char **argv)
00119 {
00120         
00121         flag_msg_received = false;
00122 
00123 
00124         std::vector<std::string> label;
00125         label.push_back((const char*)"A");      
00126         label.push_back((const char*)"B");      
00127         label.push_back((const char*)"C");      
00128         label.push_back((const char*)"D");      
00129         label.push_back((const char*)"E");      
00130         label.push_back((const char*)"F");      
00131         label.push_back((const char*)"G");      
00132         label.push_back((const char*)"H");      
00133         label.push_back((const char*)"I");      
00134 
00135         std::vector<double> r_time_detection;
00136         std::vector<double> r_time_expansion;
00137         std::vector<double> r_time_total;
00138         std::vector<size_t> r_input_pts;
00139         std::vector<size_t> r_input_pts_after_expansion;
00140         std::vector<size_t> r_input_pts_after_detection;
00141         std::vector<size_t> r_input_pts_explained;
00142         std::vector<size_t> r_input_pts_ground_explained;
00143         std::vector<size_t> r_area;
00144         std::vector<size_t> r_ground_area;
00145         std::vector<size_t> r_num_plg;
00146         std::vector<size_t> r_num_searches;
00147 
00148         
00149         sensor_msgs::PointCloud2 cloud_msg;  
00150         pcl::PointCloud<pcl::PointXYZ> cloud_to_process; 
00151         pcl::PointCloud<pcl::PointXYZ> cloud_to_process1; 
00152         pcl::PointCloud<pcl::PointXYZ> cloud_elim; 
00153         pcl::PointCloud<pcl::PointNormal> cloud_normals; 
00154         pcl::PointCloud<pcl::Normal> normals; 
00155         std::vector<c_polygon_primitive> plg; 
00156 
00157         
00158         ros::init(argc, argv, "extract_polygon_primitives"); 
00159         ros::NodeHandle n; 
00160         pn = &n;
00161         ros::Rate r(0.1);
00162         ros::Subscriber sub_point_cloud = n.subscribe("/filtered_cloud", 1, PointCloudHandler);  
00163 
00164 
00165         boost::shared_ptr<ros::Publisher> pub1(new ros::Publisher); 
00166         *pub1 = n.advertise<sensor_msgs::PointCloud2>("/epp_pc_all", 1);
00167         publishers.push_back(pub1);
00168 
00169         boost::shared_ptr<ros::Publisher> pub2(new ros::Publisher); 
00170         *pub2 = n.advertise<sensor_msgs::PointCloud2>("/epp_pc_filtered", 1);
00171         publishers.push_back(pub2);
00172 
00173 #if DEBUG
00174         for (int i=0; i<_MAX_NUM_POLYGONS_; ++i)
00175         {
00176                 char str[1024];
00177                 sprintf(str,"/inliers_%d",i);
00178                 boost::shared_ptr<ros::Publisher> pub_tmp(new ros::Publisher); 
00179                 *pub_tmp = n.advertise<sensor_msgs::PointCloud2>(str, 1);
00180                 publishers.push_back(pub_tmp);
00181 
00182                 sprintf(str,"/projected_%d",i);
00183                 boost::shared_ptr<ros::Publisher> pub_tmp1(new ros::Publisher); 
00184                 *pub_tmp1 = n.advertise<sensor_msgs::PointCloud2>(str, 1);
00185                 publishers.push_back(pub_tmp1);
00186 
00187         }
00188 #endif
00189 
00190         ros::Publisher normals_pub = n.advertise<visualization_msgs::Marker>("/normals", 1);
00191         ros::Publisher markerarray_pub = n.advertise<visualization_msgs::MarkerArray>("/PolygonMarkers", 1);
00192         visualization_msgs::MarkerArray marker_array_msg; 
00193         visualization_msgs::Marker marker;
00194         ros::Publisher marker_pub = n.advertise<visualization_msgs::Marker>("/gpp_mesh", 1);
00195 
00196         ros::Publisher pub_polygon_primitive = n.advertise<polygon_primitive_msg::polygon_primitive>("/polygon_primitive", 1);
00197         tf::TransformListener listener;
00198         tf::StampedTransform vehicle_tf;
00199         for (int j=0; j<10; j++)
00200                 ros::spinOnce();
00201 
00202         unsigned int count=0;
00203         int iteration=0;
00204 
00205         
00206         while(n.ok())
00207         {
00208                 if (flag_msg_received) 
00209                 {
00210 
00211                         ros::Time t = ros::Time::now();
00212                         flag_msg_received=0; 
00213                         cloud_to_process = cloud; 
00214 
00215                         ROS_INFO("New Velodyne pc received. %ld points", cloud_to_process.points.size());
00216 
00217                         r_input_pts.push_back(cloud_to_process.points.size());
00218 #if DEBUG
00219                         
00220 #endif
00221 
00222 
00223                         ros::Time t_expansion = ros::Time::now();
00224 #if USE_EXPANSION
00225                         
00226                         
00227                         
00228                         
00229                         for (int i=0; i<(int)plg.size();i++)
00230                         {
00231                                 if (i==0)
00232                                         plg[i].polygon_expansion(&cloud_to_process, _GROUND_PLG_LONG_EXPANSION_, _GROUND_PLG_PERP_EXPANSION_);
00233                                 else
00234                                         plg[i].polygon_expansion(&cloud_to_process, _VERTICAL_PLG_LONG_EXPANSION_, _VERTICAL_PLG_PERP_EXPANSION_);
00235 
00236                                 polygon_primitive_msg::polygon_primitive polygon_primitive_msg;
00237                                 plg[i].export_to_polygon_primitive_msg(&polygon_primitive_msg);
00238                                 pub_polygon_primitive.publish(polygon_primitive_msg);
00239 
00240 #if 1
00241                                 
00242 
00243                                 create_publish_marker_array(&plg, &marker_array_msg );
00244                                 markerarray_pub.publish(marker_array_msg);
00245 #endif
00246                         }       
00247 #endif
00248                         ros::Duration d_expansion = ros::Time::now()-t_expansion;
00249 
00250                         
00251                         get_vehicle_position(&n, &listener, &vehicle_tf, &laser_ts);
00252 
00253                         
00254                         compute_normals(&cloud_to_process, vehicle_tf.getOrigin().x(),vehicle_tf.getOrigin().y(),vehicle_tf.getOrigin().z(),0,30, &normals);
00255 #if DEBUG
00256                         
00257 
00258 
00259                         
00260                         
00261                         
00262                         
00263 
00264                         
00265                         
00266                         
00267                         
00268                         
00269                         
00270 
00271                         
00272                         
00273                         
00274                         
00275                         
00276                         
00277 
00278                         
00279                         
00280                         
00281                         
00282                         
00283                         
00284 
00285                         
00286 
00287                         
00288                         
00289 #endif
00290 
00291                         cloud_to_process1 = cloud_to_process;
00292 
00293 
00294                         ros::Time t_detection = ros::Time::now();
00295                         r_input_pts_after_expansion.push_back(cloud_to_process.points.size());
00296                         int ret=0;
00297 
00298                         int num_searches = 0;
00299                         
00300                         
00301                         
00302                         
00303                         int times=-1;
00304                         bool to_break=false;
00305                         for (int i=(int)plg.size(); i<_MAX_NUM_POLYGONS_;i++)
00306                         {
00307 
00308                                 num_searches++;
00309 #if DEBUG
00310                                 publish_point_cloud(&publishers, &cloud_to_process1, "/epp_pc_all");
00311 #endif
00312 
00313                                 char str[1024];
00314                                 sprintf(str,"p%d",i);
00315                                 plg.push_back(*(new c_polygon_primitive(&n,str,cr[i%16], g[i%16],b[i%16])));
00316 
00317                                 if (i==0)
00318                                 {
00319                                         ret = plg[i].polygon_create(&cloud_to_process1, &normals, 0.3,0.2,100,0);
00320                                         plg[i].data.misc.ground_search = true;
00321                                 }
00322 #if USE_EXPANSION<1
00323                                 else if (times<0)
00324                                 {
00325                                         ret = plg[i].polygon_create(&cloud_to_process1, &normals, 0.3,0.2,1000,0);
00326                                         plg[i].data.misc.ground_search = true;
00327                                 }
00328 #endif
00329                                 else
00330                                 {
00331                                         ret = plg[i].polygon_create(&cloud_to_process1, &normals, 0.2,0.7,1000,1);
00332                                         plg[i].data.misc.ground_search = false;
00333                                         
00334                                 }
00335                                 times++;
00336 
00337                                 if ((ros::Time::now()-t).toSec()>_MAX_ITERATION_TIME_)
00338                                 {
00339                                         ROS_INFO("Stoping detection: %f seconds limit reached", _MAX_ITERATION_TIME_);
00340                                         to_break=true;
00341                                 }
00342 
00343 
00344 
00345                                 
00346                                 if (ret==0)
00347                                 {
00348                                         
00349                                         
00350                                         ROS_WARN("Deleting candidate polygon %d due to error in create",i);
00351                                         plg.erase(--plg.end());          
00352                                         i--;
00353                                         if(to_break)
00354                                                 break;
00355                                         else
00356                                                 continue;
00357                                 }
00358 
00359 
00360 #if DEBUG
00361                                 
00362 #endif
00363 
00364                                 
00365                                 if (i==0)
00366                                         plg[i].polygon_expansion(&cloud_to_process1,  _GROUND_PLG_LONG_EXPANSION_,_GROUND_PLG_PERP_EXPANSION_ , &normals);
00367                                 else
00368                                         plg[i].polygon_expansion(&cloud_to_process1,  _VERTICAL_PLG_LONG_EXPANSION_, _VERTICAL_PLG_PERP_EXPANSION_, &normals);
00369 
00370 
00371 
00372 
00373                                 
00374                                 
00375                                 
00376 
00377 #if EXPANSION <1
00378                                 if(times>0)
00379 #else
00380                                 if (i!=0)
00381 #endif
00382                                 {
00383                                         if (!polygon_has_quality(plg[i].data.hulls.convex.area, plg[i].data.hulls.convex.solidity))
00384                                         {
00385                                                 ROS_WARN("Deleting candidate plg %d due to low area=%f solidity=%f",i,plg[i].data.hulls.convex.area, plg[i].data.hulls.convex.solidity);
00386 
00387                                                 plg.erase(--plg.end());          
00388 
00389                                                 i--;
00390                                                 if(to_break)
00391                                                         break;
00392                                                 else
00393                                                         continue;
00394                                         }
00395                                 }
00396 
00397 
00398                                 polygon_primitive_msg::polygon_primitive polygon_primitive_msg;
00399                                 plg[i].export_to_polygon_primitive_msg(&polygon_primitive_msg);
00400                                 pub_polygon_primitive.publish(polygon_primitive_msg);
00401 
00402 #if 1
00403                                 create_publish_marker_array(&plg, &marker_array_msg );
00404                                 markerarray_pub.publish(marker_array_msg);
00405 #endif
00406 
00407 
00408                                 ROS_INFO("Adding new plg %d with area=%f solidity=%f",i,plg[i].data.hulls.convex.area, plg[i].data.hulls.convex.solidity);
00409                                 if(to_break)
00410                                         break;
00411                         }
00412 
00413 
00414                         
00415                         size_t n=0;
00416                         size_t n1=0;
00417                         size_t a=0;
00418                         size_t a1=0;
00419                         for (size_t i=0; i<plg.size(); ++i)
00420                         {
00421                                 if (!plg[i].data.misc.ground_search)
00422                                 {
00423                                         n+= plg[i].pointclouds.all->points.size();
00424                                         a+= plg[i].data.hulls.convex.area;
00425                                 }
00426                                 else
00427                                 {
00428                                         n1+= plg[i].pointclouds.all->points.size();
00429                                         a1+= plg[i].data.hulls.convex.area;
00430                                 }
00431                         }
00432                         r_input_pts_explained.push_back(n);
00433                         r_input_pts_ground_explained.push_back(n1);
00434                         r_area.push_back(a);
00435                         r_ground_area.push_back(a1);
00436                         r_num_plg.push_back(plg.size());
00437                         r_num_searches.push_back(num_searches);
00438 
00439                         r_input_pts_after_detection.push_back(cloud_to_process1.points.size());
00440                         ros::Duration d_detection = ros::Time::now()-t_detection;
00441                         ros::Duration d = ros::Time::now()-t;
00442 
00443 
00444                         create_publish_marker_array(&plg, &marker_array_msg );
00445                         markerarray_pub.publish(marker_array_msg);
00446 
00447 #if DEBUG
00448                         publish_point_cloud(&publishers, &cloud_to_process1, "/epp_pc_all");
00449 
00450                         for (size_t i=0; i<plg.size(); ++i)
00451                         {
00452                                 char str[1024];
00453                                 sprintf(str,"/inliers_%ld",i);
00454 
00455                                 plg[i].pointclouds.all->height=1;
00456                                 publish_point_cloud(&publishers, plg[i].pointclouds.all, str);
00457 
00458                                 sprintf(str,"/projected_%ld",i);
00459                                 publish_point_cloud(&publishers, plg[i].pointclouds.projected, str);
00460 
00461 
00462                         }
00463 #endif
00464 
00465                         for (size_t i=0; i<plg.size();i++)
00466                         {
00467                                 plg[i].print_polygon_information();
00468                         }
00469 
00470                         
00471                         count++;
00472                         char str[1024];
00473                         sprintf(str,"mesh/polygons%d.dae",count);
00474                         wrapper_collada wc(str);
00475 
00476 
00477 
00478                         for (size_t i=1; i<plg.size();i++)
00479                         {
00480 
00481                                 pcl::PointCloud<pcl::PointXYZ> normal;
00482                                 pcl::PointXYZ p;
00483                                 p.x = plg[i].data.planes.current->values[0];
00484                                 p.y = plg[i].data.planes.current->values[1];
00485                                 p.z = plg[i].data.planes.current->values[2];
00486                                 normal.points.push_back(p);
00487                                 std::string pname(plg[i].data.misc.name);
00488                                 wc.add_polygon_fixed_color_on_both_sides(pname,
00489                                                 plg[i].data.hulls.convex.polygon,
00490                                                 normal.makeShared(),
00491                                                 (float)plg[i].data.misc.color.r/255.0,
00492                                                 (float)plg[i].data.misc.color.g/255.0,
00493                                                 (float)plg[i].data.misc.color.b/255.0,
00494                                                 1.0);  
00495 
00496                         }
00497 
00498                         wc.write_file();        
00499 
00500                         marker.id = 1;  
00501                         marker.header.stamp = ros::Time::now(); 
00502                         marker.type = visualization_msgs::Marker::MESH_RESOURCE;    
00503                         marker.action = visualization_msgs::Marker::ADD;    
00504                         marker.ns = "ns";
00505                         char str1[1024];
00506                         sprintf(str1,"package://polygon_primitives_extraction/bin/%s", str);
00507                         marker.mesh_resource = str1;
00508                         marker.mesh_use_embedded_materials = 1; 
00509                         marker.header.frame_id = "/world";
00510                         marker.scale.x = 1;
00511                         marker.scale.y = 1;
00512                         marker.scale.z = 1;
00513                         marker.color.r = 0.2;
00514                         marker.color.g = 0.2;
00515                         marker.color.b = 0.2;
00516                         marker.color.a = 1;     
00517                         marker_pub.publish(marker); 
00518                         
00519 
00520                         
00521 
00522                         FILE* pFile;
00523 
00524                         std::string ss = "./" + label[iteration] + ".obj";
00525                         pFile = fopen (ss.c_str(),"w+");
00526                         for (size_t i=0; i<plg.size();i++)
00527                         {
00528                                 for (size_t j=0 ; j<plg[i].data.hulls.convex.polygon->points.size() ; ++j)
00529                                 {
00530                                         fprintf(pFile, "v %f %f %f\n",plg[i].data.hulls.convex.polygon->points[j].x,plg[i].data.hulls.convex.polygon->points[j].y,plg[i].data.hulls.convex.polygon->points[j].z);
00531                                 }
00532                         }
00533 
00534                         fprintf(pFile, "\n");
00535                         int count =1;
00536                         for (size_t i=0; i<plg.size();i++)
00537                         {
00538 
00539                                 fprintf(pFile, "f ");
00540                                 for (size_t j=0 ; j<plg[i].data.hulls.convex.polygon->points.size() ; ++j)
00541                                 {
00542                                         fprintf(pFile, "%d ",count);
00543                                         count ++;
00544                                 }
00545                                 fprintf(pFile, "\n");
00546                         }
00547                         fclose (pFile);
00548 
00549                         ss = "./" + label[iteration] + "_noground.obj";
00550                         pFile = fopen (ss.c_str(),"w+");
00551                         for (size_t i=1; i<plg.size();i++)
00552                         {
00553                                 for (size_t j=0 ; j<plg[i].data.hulls.convex.polygon->points.size() ; ++j)
00554                                 {
00555                                         fprintf(pFile, "v %f %f %f\n",plg[i].data.hulls.convex.polygon->points[j].x,plg[i].data.hulls.convex.polygon->points[j].y,plg[i].data.hulls.convex.polygon->points[j].z);
00556                                 }
00557                         }
00558 
00559                         fprintf(pFile, "\n");
00560                         count =1;
00561                         for (size_t i=1; i<plg.size();i++)
00562                         {
00563 
00564                                 fprintf(pFile, "f ");
00565                                 for (size_t j=0 ; j<plg[i].data.hulls.convex.polygon->points.size() ; ++j)
00566                                 {
00567                                         fprintf(pFile, "%d ",count);
00568                                         count ++;
00569                                 }
00570                                 fprintf(pFile, "\n");
00571                         }
00572                         fclose (pFile);
00573 
00574                         iteration++;
00575 
00576                         
00577                         
00578                         
00579                         
00580                         
00581                         
00582                         
00583                         
00584 
00585                         
00586                         
00587                         
00588                         
00589 
00590                         
00591                         
00592                         
00593                         
00594                         
00595                         
00596                         
00597                         
00598 
00599 
00600                         
00601                         
00602 
00603                         
00604                         
00605                         
00606                         
00607                         
00608                         
00609                         
00610                         
00611 
00612                         
00613                         
00614                         
00615                         
00616 
00617                         
00618                         
00619                         
00620                         
00621                         
00622                         
00623                         
00624                         
00625 
00626 
00627                         
00628                         
00629 
00630                         
00631                         
00632                         
00633                         
00634 
00635 
00636                         ROS_INFO("Processing took %f secs",d.toSec());
00637                         ROS_INFO("Expansion took %f secs",d_expansion.toSec());
00638                         ROS_INFO("Detection took %f secs",d_detection.toSec());
00639 
00640                         r_time_total.push_back(d.toSec());
00641                         r_time_detection.push_back( d_detection.toSec());
00642                         r_time_expansion.push_back(d_expansion.toSec());
00643                 }
00644 
00645 
00646                 
00647                 ros::spinOnce(); 
00648                 ros::spinOnce(); 
00649                 ros::spinOnce(); 
00650                 ros::spinOnce(); 
00651         }
00652 
00653         for (size_t i=0; i<r_time_total.size(); i++)
00654         {
00655                 printf("%s ",label[i].c_str()); 
00656         }
00657 
00658         printf("\nTotal processing time\nA=["); 
00659         for (size_t i=0; i<r_time_total.size(); i++)
00660         {
00661                 printf("%f ",r_time_total[i]);  
00662         }
00663 
00664         printf("];\nDetection processing time\nB=[");   
00665         for (size_t i=0; i<r_time_total.size(); i++)
00666         {
00667                 printf("%f ",r_time_detection[i]);      
00668         }
00669 
00670         printf("];\nExpansion processing time\nC=[");   
00671         for (size_t i=0; i<r_time_total.size(); i++)
00672         {
00673                 printf("%f ",r_time_expansion[i]);      
00674         }
00675 
00676         printf("];\nInput pts\nD=[");   
00677         for (size_t i=0; i<r_time_total.size(); i++)
00678         {
00679                 printf("%ld ",r_input_pts[i]);  
00680         }
00681 
00682         printf("];\nInput pts after expansion\nE=[");   
00683         for (size_t i=0; i<r_time_total.size(); i++)
00684         {
00685                 printf("%ld ",r_input_pts_after_expansion[i]);  
00686         }
00687 
00688         printf("];\nInput pts after detection\nF=[");   
00689         for (size_t i=0; i<r_time_total.size(); i++)
00690         {
00691                 printf("%ld ",r_input_pts_after_detection[i]);  
00692         }
00693 
00694         printf("];\nExplained pts\nG=[");       
00695         for (size_t i=0; i<r_time_total.size(); i++)
00696         {
00697                 printf("%ld ",r_input_pts_explained[i]);        
00698         }
00699 
00700         printf("];\nGround Explained pts\nH=[");        
00701         for (size_t i=0; i<r_time_total.size(); i++)
00702         {
00703                 printf("%ld ",r_input_pts_ground_explained[i]); 
00704         }
00705 
00706         printf("];\nArea\nI=[");        
00707         for (size_t i=0; i<r_time_total.size(); i++)
00708         {
00709                 printf("%ld ",r_area[i]);       
00710         }
00711 
00712         printf("];\nGround Area\nJ=["); 
00713         for (size_t i=0; i<r_time_total.size(); i++)
00714         {
00715                 printf("%ld ",r_ground_area[i]);        
00716         }
00717 
00718         printf("];\nNumber of plg\nL=[");       
00719         for (size_t i=0; i<r_time_total.size(); i++)
00720         {
00721                 printf("%ld ",r_num_plg[i]);    
00722         }
00723 
00724         printf("];\nNumber of searches\nM=[");  
00725         for (size_t i=0; i<r_time_total.size(); i++)
00726         {
00727                 printf("%ld ",r_num_searches[i]);       
00728         }
00729 
00730         printf("];\n"); 
00731 
00732 
00733         
00734         return 0;
00735 }
00736 
00737 #endif
00738