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