geometry_map.cpp
Go to the documentation of this file.
00001 
00064 //##################
00065 //#### includes ####
00066 // standard includes
00067 #include <sstream>
00068 #include <cmath>
00069 #include <vector>
00070 #include <iostream>
00071 #include <fstream>
00072 #include <queue>
00073 #include <functional>
00074 
00075 // external includes
00076 #include <boost/timer.hpp>
00077 #include <boost/tuple/tuple.hpp>
00078 #include <boost/tuple/tuple_comparison.hpp>
00079 #include <Eigen/Geometry>
00080 //#include <pcl/win32_macros.h> // not available anymore in pcl 1.7
00081 #include <pcl/io/pcd_io.h>
00082 #include <pcl/point_types.h>
00083 #include <pcl/point_cloud.h>
00084 #include <pcl/common/centroid.h>
00085 
00086 //#include <cob_3d_mapping_slam/dof/tflink.h>
00087 #include "cob_3d_mapping_geometry_map/geometry_map.h"
00088 
00089 using namespace cob_3d_mapping;
00090 
00091 void
00092 GeometryMap::addMapEntry (Polygon::Ptr& p_ptr)
00093 {
00094   Polygon& p = *p_ptr;
00095 
00096   cob_3d_mapping::MergeConfig limits;
00097   limits.d_thresh = d_;
00098   limits.angle_thresh = cos_angle_;
00099   //    limits.weighting_method="COMBINED";
00100   limits.weighting_method = "AREA";
00101   p.merge_settings_ = limits;
00102   p.assignWeight ();
00103 
00104   std::vector<int> intersections;
00105   if (map_polygon_.size () > 0)
00106   {
00107     p.getMergeCandidates (map_polygon_, intersections);
00108     if (intersections.size () > 0) // if polygon has to be merged ...
00109     {
00110       std::vector<Polygon::Ptr> merge_candidates;
00111       for (int i = intersections.size () - 1; i >= 0; --i)
00112       {
00113         // copies pointer to polygon
00114         merge_candidates.push_back (map_polygon_[intersections[i]]);
00115         // delete pointer in map, polygon still available. However there should be a better solution than
00116         // copying and deleting pointers manually.
00117         map_polygon_[intersections[i]] = map_polygon_.back ();
00118         map_polygon_.pop_back ();
00119       }
00120       // merge polygon with merge candidates
00121       p.merge (merge_candidates); // merge all new candidates into p
00122       map_polygon_.push_back (p_ptr); // add p to map, candidates were dropped!
00123     }
00124     else //if polygon does not have to be merged , add new polygon
00125     {
00126       //p.computeAttributes(p.normal,p.centroid);
00127       //p.assignWeight();
00128       p.id_ = new_id_++;
00129       p.frame_stamp_ = frame_counter_;
00130       map_polygon_.push_back (p_ptr);
00131     }
00132   }
00133   else
00134   {
00135     //p.computeAttributes(p.normal,p.centroid);
00136     //p.assignWeight();
00137     p.id_ = new_id_++;
00138     p.frame_stamp_ = frame_counter_;
00139     map_polygon_.push_back (p_ptr);
00140   }
00141   if (save_to_file_)
00142     saveMap (file_path_);
00143 }
00144 
00145 void
00146 GeometryMap::addMapEntry (Cylinder::Ptr& c_ptr)
00147 {
00148   Cylinder& c = *c_ptr;
00149 
00150   //c.frame_stamp_ = frame_counter_;
00151   cob_3d_mapping::MergeConfig limits;
00152   limits.d_thresh = d_;
00153   limits.angle_thresh = cos_angle_;
00154   //limits.weighting_method="COUNTER";
00155   limits.weighting_method = "AREA";
00156 
00157   c.merge_settings_ = limits;
00158   c.assignWeight ();
00159 
00160   std::vector<int> intersections;
00161   if (map_cylinder_.size () > 0)
00162   {
00163     c.getMergeCandidates (map_cylinder_, intersections);
00164     if (intersections.size () > 0) // if polygon has to be merged ...
00165     {
00166       std::vector<Polygon::Ptr> merge_candidates;
00167       for (int i = intersections.size () - 1; i >= 0; --i)
00168       {
00169         // copies pointer to polygon
00170         merge_candidates.push_back (map_cylinder_[intersections[i]]);
00171         // delete pointer in map, polygon still available. However there should be a better solution than
00172         // copying and deleting pointers manually.
00173         map_cylinder_[intersections[i]] = map_cylinder_.back ();
00174         map_cylinder_.pop_back ();
00175       }
00176       // merge polygon with merge candidates
00177       c.merge (merge_candidates); // merge all new candidates into p
00178       map_cylinder_.push_back (c_ptr); // add p to map, candidates were dropped!
00179     }
00180     else //if polygon does not have to be merged , add new polygon
00181     {
00182       //p.computeAttributes(p.normal,p.centroid);
00183       //p.assignWeight();
00184       c.id_ = new_id_++;
00185       c.frame_stamp_ = frame_counter_;
00186       map_cylinder_.push_back (c_ptr);
00187     }
00188   }
00189   else
00190   {
00191     /*std::cout << "adding first element" << std::endl;
00192     for (unsigned int i = 0; i < c.contours_[0].size (); i++)
00193     {
00194       std::cout << c.contours_[0][i] (0) << "," << c.contours_[0][i] (1) << std::endl;
00195     }*/
00196     //p.computeAttributes(p.normal,p.centroid);
00197     //p.assignWeight();
00198     c.id_ = new_id_++;
00199     c.frame_stamp_ = frame_counter_;
00200     map_cylinder_.push_back (c_ptr);
00201   }
00202   if (save_to_file_)
00203     saveMap (file_path_);
00204 }
00205 
00206 /*void
00207  GeometryMap::addMapEntry(ShapeCluster::Ptr& sc_ptr)
00208  {
00209  sc_ptr->computeAttributes();
00210  if (map_shape_cluster_.size())
00211  {
00212  std::vector<int> intersections;
00213  sc_ptr->getMergeCandidates(map_shape_cluster_, intersections);
00214  ROS_DEBUG_STREAM(intersections.size());
00215  if(intersections.size())
00216  {
00217  std::vector<ShapeCluster::Ptr> do_merge;
00218  for(int i=intersections.size()-1; i>=0; --i)
00219  {
00220  do_merge.push_back(map_shape_cluster_[intersections[i]]);
00221  map_shape_cluster_[intersections[i]] = map_shape_cluster_.back();
00222  map_shape_cluster_.pop_back();
00223  }
00224  sc_ptr->merge(do_merge);
00225  sc_ptr->id = new_id_++;
00226  map_shape_cluster_.push_back(sc_ptr);
00227  }
00228  else
00229  {
00230  sc_ptr->id = new_id_++;
00231  sc_ptr->frame_stamp = frame_counter_;
00232  map_shape_cluster_.push_back(sc_ptr);
00233  }
00234  }
00235  else
00236  {
00237  sc_ptr->id = new_id_++;
00238  sc_ptr->frame_stamp = frame_counter_;
00239  map_shape_cluster_.push_back(sc_ptr);
00240  }
00241  }*/
00242 
00243 /*bool
00244  GeometryMap::computeTfError(const std::vector<Polygon::Ptr>& list_polygon, const Eigen::Affine3f& tf_old, Eigen::Affine3f& adjust_tf)
00245  {
00246  return false;
00247  if (map_polygon_.size() < 10)
00248  {
00249  adjust_tf = Eigen::Affine3f::Identity();
00250  last_tf_err_ = Eigen::Affine3f::Identity();
00251  return false;
00252  }
00253  cob_3d_mapping::merge_config  limits;
00254  limits.d_thresh=d_;
00255  limits.angle_thresh=cos_angle_;
00256  limits.weighting_method="COUNTER";
00257  // min heap to store polygons with max overlap (Landmark elements: overlap, num_vertices, idx_old, idx_new)
00258  typedef boost::tuple<float,unsigned int,unsigned int> Landmark;
00259  std::priority_queue<Landmark> landmarks_queue;
00260  const size_t q_size = 3;
00261  int sum_overlap = 0;
00262  for (size_t p=0; p<map_polygon_.size(); ++p) // old polys
00263  {
00264  Polygon::Ptr pp = map_polygon_[p];
00265 
00266  for (size_t q=0; q<list_polygon.size(); ++q) // new polys
00267  {
00268  Polygon::Ptr pq = list_polygon[q];
00269  pq->merge_settings_=limits;
00270  if ( !pp->hasSimilarParametersWith(pq) ) continue;
00271  //if ( pq->contours[pq->outerContourIndex()].size() < 20 ) continue;
00272  //int abs_overlap;
00273  //float rel_overlap;
00274  //if (!pp->getContourOverlap(pq, rel_overlap, abs_overlap)) continue;
00275  //if (abs_overlap < 10) continue;
00276  //if (rel_overlap < 0.3) continue;
00277  //sum_overlap += abs_overlap;
00278  float w = pp->computeSimilarity(pq);
00279  ROS_DEBUG_STREAM("Sim: " << w);
00280  if (w < 0.70) continue;
00281  landmarks_queue.push( Landmark(w, p, q) );
00282  }
00283  }
00284  if (landmarks_queue.size() < q_size) return false;
00285 
00286  Landmark lm;
00287  DOF6::TFLinkvf tfe;
00288  Eigen::Vector3f n,m;
00289  float d1, d2;
00290  int i = 0;
00291  while (landmarks_queue.size() != 0)
00292  {
00293  lm = landmarks_queue.top(); landmarks_queue.pop();
00294  n = map_polygon_[lm.get<1>()]->normal;
00295  m = list_polygon[lm.get<2>()]->normal;
00296  d1 = map_polygon_[lm.get<1>()]->d;
00297  d2 = list_polygon[lm.get<2>()]->d;
00298  float weight = 2.0f/(fabs(d1)+fabs(d2));//(float)lm.get<0>();
00299  tfe(DOF6::TFLinkvf::TFLinkObj( d2 * m , true, false, weight),
00300  DOF6::TFLinkvf::TFLinkObj( d1 * n , true, false, weight));
00301 
00302  ROS_DEBUG_STREAM("%Overlap: "<<lm.get<0>()<<" Weigth: "<<weight);
00303  ROS_DEBUG_STREAM("%Area(old/new): "<<map_polygon_[lm.get<1>()]->computeArea3d()<<", "
00304  <<list_polygon[lm.get<2>()]->computeArea3d());
00305  ROS_DEBUG_STREAM("vector_a"<<i<<" = ["<<n(0)<<","<<n(1)<<","<<n(2)<<"];");
00306  ROS_DEBUG_STREAM("vector_b"<<i<<" = ["<<m(0)<<","<<m(1)<<","<<m(2)<<"];");
00307  ROS_DEBUG_STREAM("origin_a"<<i<<" = "<<d1<<" * vector_a"<<i<<";");
00308  ROS_DEBUG_STREAM("origin_b"<<i<<" = "<<d2<<" * vector_b"<<i<<";");
00309  ++i;
00310  }
00311 
00312  tfe.finish();
00313  Eigen::Affine3f tf;
00314  tf.matrix().topLeftCorner<3,3>() = tfe.getRotation();
00315  tf.matrix().topRightCorner<3,1>() = tfe.getTranslation();
00316  tf.matrix().bottomLeftCorner<1,4>() << 0, 0, 0, 1;
00317 
00318  float roll, pitch, yaw;
00319  pcl::getEulerAngles(tf, roll, pitch, yaw);
00320  ROS_DEBUG_STREAM("Angles: r="<<roll*180.0f/M_PI<<" p="<<pitch*180.0f/M_PI<<" y="<<yaw*180.0f/M_PI);
00321 
00322  adjust_tf = tf;
00323  last_tf_err_ = adjust_tf;
00324 
00325  return true;
00326  }*/
00327 
00328 void
00329 GeometryMap::cleanUp ()
00330 {
00331   int n_dropped = 0, m_dropped = 0, c_dropped = 0;
00332   for (int idx = map_polygon_.size () - 1; idx >= 0; --idx)
00333   {
00334     if (map_polygon_[idx]->merged_ <= 1 && (frame_counter_ - 3) > (int)map_polygon_[idx]->frame_stamp_
00335         && (int)map_polygon_[idx]->frame_stamp_ > 1)
00336     {
00337       //ROS_INFO ("cleaning id %d", idx);
00338       map_polygon_[idx] = map_polygon_.back ();
00339       map_polygon_.pop_back ();
00340       ++n_dropped;
00341     }
00342   }
00343 
00344   /*for(int idx = map_cylinder_.size() - 1 ; idx >= 0; --idx)
00345    {
00346    bool drop_cyl=false;
00347    ROS_DEBUG_STREAM("merged:"<<(int)map_cylinder_[idx]->merged_<<" frame ctr:"<<frame_counter_<<" frame st:"<<(int)map_cylinder_[idx]->frame_stamp_<<" size:"<<(int)map_cylinder_[idx]->contours_[0].size());
00348 
00349    if (map_cylinder_[idx]->merged_ <= 1 && (frame_counter_ - 2) > (int)map_cylinder_[idx]->frame_stamp_)
00350    {
00351    drop_cyl=true;
00352    }
00353    // TODO<<<<WATCH OUT<<<<< presentation configuration - hard coded limits >>>>>>>>>>>>>>>>>>
00354    if ((int)map_cylinder_[idx]->contours_[0].size()<30 && (int)map_cylinder_[idx]->merged_ <= 1)
00355    {
00356    drop_cyl=true;
00357    }
00358    if (map_cylinder_[idx]->r_ < 0.1 || map_cylinder_[idx]->r_>0.2)
00359    {
00360    drop_cyl=true;
00361    }
00362    if ( drop_cyl==true)
00363    {
00364    map_cylinder_[idx] = map_cylinder_.back();
00365    map_cylinder_.pop_back();
00366    ++c_dropped;
00367    }
00368    }
00369    for(int idx = map_shape_cluster_.size() - 1 ; idx >= 0; --idx)
00370    {
00371    ROS_DEBUG_STREAM( map_shape_cluster_[idx]->merged_ <<", " << (frame_counter_ - 3) <<" > "<<(int)map_shape_cluster_[idx]->frame_stamp_);
00372    if (map_shape_cluster_[idx]->merged_ <= 1 && (frame_counter_ - 3) > (int)map_shape_cluster_[idx]->frame_stamp_)
00373    {
00374    map_shape_cluster_[idx] = map_shape_cluster_.back();
00375    map_shape_cluster_.pop_back();
00376    ++m_dropped;
00377    }
00378    }*/
00379   //ROS_DEBUG_STREAM ("Dropped " << n_dropped << " Polys, " << c_dropped << " Cyls, " << m_dropped << " Clusters");
00380 }
00381 
00382 void
00383 GeometryMap::saveMapEntry (std::string path, int ctr, cob_3d_mapping::Polygon& p)
00384 {
00385   std::stringstream ss;
00386   ss << path << "polygon_" << ctr << ".pl";
00387   std::ofstream plane_file;
00388   plane_file.open (ss.str ().c_str ());
00389   plane_file << p.normal_ (0) << " " << p.normal_ (1) << " " << p.normal_ (2) << " " << p.d_;
00390   ss.str ("");
00391   ss.clear ();
00392   plane_file.close ();
00393   for (int i = 0; i < (int)p.contours_.size (); i++)
00394   {
00395     pcl::PointCloud<pcl::PointXYZ> pc;
00396     ss << path << "polygon_" << ctr << "_" << i << ".pcd";
00397     for (int j = 0; j < (int)p.contours_[i].size (); j++)
00398     {
00399       pcl::PointXYZ pt;
00400       pt.getVector3fMap () = Eigen::Vector3f (p.contours_[i][j] (0), p.contours_[i][j] (1), 0);
00401       pc.points.push_back (pt);
00402     }
00403     pcl::io::savePCDFileASCII (ss.str (), pc);
00404     ss.str ("");
00405     ss.clear ();
00406   }
00407 }
00408 
00409 void
00410 GeometryMap::saveMap (std::string path)
00411 {
00412 
00413   //    only for polygons
00414   static int ctr = 0;
00415   std::stringstream ss;
00416   ss << path << "/" << ctr << "_";
00417   for (size_t i = 0; i < map_polygon_.size (); i++)
00418   {
00419     saveMapEntry (ss.str (), i, *map_polygon_[i]);
00420   }
00421   ctr++;
00422 }
00423 
00424 void
00425 GeometryMap::clearMap ()
00426 {
00427   map_polygon_.clear ();
00428   map_cylinder_.clear ();
00429 }
00430 
00431 void
00432 GeometryMap::colorizeMap ()
00433 {
00434 
00435   //coloring for polygon
00436   for (unsigned int i = 0; i < map_polygon_.size (); i++)
00437   {
00438     if (map_polygon_[i]->color_[3] == 1.0f)
00439       continue;
00440     if (fabs (map_polygon_[i]->normal_[2]) < 0.1) //plane is vertical
00441     {
00442       map_polygon_[i]->color_[0] = 0.75;
00443       map_polygon_[i]->color_[1] = 0.75;
00444       map_polygon_[i]->color_[2] = 0;
00445       map_polygon_[i]->color_[3] = 0.8;
00446     }
00447     else if (fabs (map_polygon_[i]->normal_[0]) < 0.12 && fabs (map_polygon_[i]->normal_[1]) < 0.12
00448         && fabs (map_polygon_[i]->normal_[2]) > 0.9) //plane is horizontal
00449     {
00450       map_polygon_[i]->color_[0] = 0;
00451       map_polygon_[i]->color_[1] = 0.5;
00452       map_polygon_[i]->color_[2] = 0;
00453       map_polygon_[i]->color_[3] = 0.8;
00454     }
00455     else
00456     {
00457       map_polygon_[i]->color_[0] = 0.75;
00458       map_polygon_[i]->color_[1] = 0.75;
00459       map_polygon_[i]->color_[2] = 0.75;
00460       map_polygon_[i]->color_[3] = 0.8;
00461     }
00462   }
00463 
00464   //coloring for cylinder
00465   for (unsigned int i = 0; i < map_cylinder_.size (); i++)
00466   {
00467     if (map_cylinder_[i]->color_[3] == 1.0f)
00468       continue;
00469     if (fabs (map_cylinder_[i]->normal_[0]) < 0.1 && fabs (map_cylinder_[i]->normal_[1]) < 0.1) //cylinder is vertical
00470     {
00471       map_cylinder_[i]->color_[0] = 0.5;
00472       map_cylinder_[i]->color_[1] = 0.5;
00473       map_cylinder_[i]->color_[2] = 0;
00474       map_cylinder_[i]->color_[3] = 1;
00475     }
00476     else if (fabs (map_cylinder_[i]->normal_[2]) < 0.12) //plane is horizontal
00477     {
00478       map_cylinder_[i]->color_[0] = 0;
00479       map_cylinder_[i]->color_[1] = 0.5;
00480       map_cylinder_[i]->color_[2] = 0;
00481       map_cylinder_[i]->color_[3] = 1;
00482     }
00483     else
00484     {
00485       map_cylinder_[i]->color_[0] = 1;
00486       map_cylinder_[i]->color_[1] = 1;
00487       map_cylinder_[i]->color_[2] = 1;
00488       map_cylinder_[i]->color_[3] = 1;
00489     }
00490   }
00491 
00492 }
00493 


cob_3d_mapping_geometry_map
Author(s): Georg Arbeiter
autogenerated on Wed Aug 26 2015 11:03:21