texturize_polygon_primitives.cpp
Go to the documentation of this file.
1 /**************************************************************************************************
2  Software License Agreement (BSD License)
3 
4  Copyright (c) 2011-2013, LAR toolkit developers - University of Aveiro - http://lars.mec.ua.pt
5  All rights reserved.
6 
7  Redistribution and use in source and binary forms, with or without modification, are permitted
8  provided that the following conditions are met:
9 
10  *Redistributions of source code must retain the above copyright notice, this list of
11  conditions and the following disclaimer.
12  *Redistributions in binary form must reproduce the above copyright notice, this list of
13  conditions and the following disclaimer in the documentation and/or other materials provided
14  with the distribution.
15  *Neither the name of the University of Aveiro nor the names of its contributors may be used to
16  endorse or promote products derived from this software without specific prior written permission.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
19  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
21  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 ***************************************************************************************************/
36 #ifndef _texturize_polygon_primitives_CPP_
37 #define _texturize_polygon_primitives_CPP_
38 
39 
41 
42 #define _USE_THREADS_ 0
43 
44 void handler_cam_roof_fc(const sensor_msgs::ImageConstPtr& msg)
45 {
46  try
47  {
48  cam_roof_fc.cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::TYPE_8UC3);
49  }
50  catch (cv_bridge::Exception& e)
51  {
52  ROS_ERROR("cv_bridge exception: %s", e.what());
53  return;
54  }
55 
56  cam_roof_fc.image_ts = msg->header.stamp;
58  cam_roof_fc.image = cam_roof_fc.cv_ptr->image;//copy the cam images
59 }
60 
61 void handler_cam_roof_fl(const sensor_msgs::ImageConstPtr& msg)
62 {
63  try
64  {
65  cam_roof_fl.cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::TYPE_8UC3);
66  }
67  catch (cv_bridge::Exception& e)
68  {
69  ROS_ERROR("cv_bridge exception: %s", e.what());
70  return;
71  }
72 
73  cam_roof_fl.image_ts = msg->header.stamp;
75  cam_roof_fl.image = cam_roof_fl.cv_ptr->image;//copy the cam images
76 }
77 
78 void handler_cam_roof_fr(const sensor_msgs::ImageConstPtr& msg)
79 {
80  try
81  {
82  cam_roof_fr.cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::TYPE_8UC3);
83  }
84  catch (cv_bridge::Exception& e)
85  {
86  ROS_ERROR("cv_bridge exception: %s", e.what());
87  return;
88  }
89 
90  cam_roof_fr.image_ts = msg->header.stamp;
92  cam_roof_fr.image = cam_roof_fr.cv_ptr->image;//copy the cam images
93 }
94 
95 void handler_cam_roof_rc(const sensor_msgs::ImageConstPtr& msg)
96 {
97  try
98  {
99  cam_roof_rc.cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::TYPE_8UC3);
100  }
101  catch (cv_bridge::Exception& e)
102  {
103  ROS_ERROR("cv_bridge exception: %s", e.what());
104  return;
105  }
106 
107  cam_roof_rc.image_ts = msg->header.stamp;
108  cam_roof_rc.msg_received = true;
109  cam_roof_rc.image = cam_roof_rc.cv_ptr->image;//copy the cam images
110 }
111 
112 void handler_cam_roof_fc_6mm(const sensor_msgs::ImageConstPtr& msg)
113 {
114  try
115  {
116  cam_roof_fc_6mm.cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::TYPE_8UC3);
117  }
118  catch (cv_bridge::Exception& e)
119  {
120  ROS_ERROR("cv_bridge exception: %s", e.what());
121  return;
122  }
123 
124  cam_roof_fc_6mm.image_ts = msg->header.stamp;
126  cam_roof_fc_6mm.image = cam_roof_fc_6mm.cv_ptr->image;//copy the cam images
127 }
128 
130 {
131  if (cam->msg_received)
132  {
133  ros::Time t = ros::Time::now();
134  ROS_INFO("Building local mesh for camera %s to plg %s",cam_name.c_str(), plg->data.misc.name);
135 
136  //First step is to query for the camera transformation at timestamp
137  try
138  {
139  p_listener->lookupTransform("/tf_" + cam_name, "/world", cam->image_ts, cam->tf);
140  }
141  catch (tf::TransformException ex){ROS_ERROR("%s",ex.what()); return -1;}
142 
143  char str[1024];
144  ros::Duration dur = ros::Time::now() - mission_start;
145  sprintf(str,"{%s, %s, %0.1f}", plg->data.misc.name,cam_name.c_str(), dur.toSec());
146  std::string projection_name = str;
147  //Now we map the camera projection to the polygon
148  int v = plg->add_camera_projection_known_camera(&cam->image, cam->image_ts, cam->tf, cam_name, projection_name, plg->colormap->cv_color(plg->cp.size()));
149 
150  if (v!=-1)
151  {
152  ros::Duration d = ros::Time::now() - t;
153  ROS_INFO("Successfully build of local mesh (%ld faces) for camera projection %s to plg %s (%f seconds)",plg->cp[v].mesh.number_of_faces(), cam_name.c_str(),plg->data.misc.name, d.toSec());
154  return v;
155  }
156  else
157  {
158  ROS_INFO("Could not build local mesh for camera %s to plg %s",cam_name.c_str(),plg->data.misc.name);
159  return v;
160  }
161  }
162  else
163  {
164  ROS_INFO("Did not receive any new image from camera %s. Cannot create local mesh",cam_name.c_str());
165  return -1;
166  }
167 
168  return -1;
169 }
170 
171 
173 {
175 
176 #if _USE_THREADS_
177  ROS_INFO("\n__________________________________\nStart processing thread plg %s\n__________________________________\n", plg->data.misc.name);
178  pthread_mutex_lock(&plg->mutex);
179 #endif
180  //-------------------------------------------
181  //Compute the camera's projections to the polygon plg
182  //-------------------------------------------
183  add_camera_projection_to_polygon("cam_roof_fc_6mm", &cam_roof_fc_6mm, plg);
184  //add_camera_projection_to_polygon("cam_roof_fc", &cam_roof_fc, plg);
185  //add_camera_projection_to_polygon("cam_roof_fr", &cam_roof_fr, plg);
186  //add_camera_projection_to_polygon("cam_roof_fl", &cam_roof_fl, plg);
187  //add_camera_projection_to_polygon("cam_roof_rc", &cam_roof_rc, plg);
188 
189  //-------------------------------------------
190  //Build the global mesh for this particular polygon
191  //-------------------------------------------
193 #if _USE_THREADS_
194  pthread_mutex_unlock(&plg->mutex);
195  ROS_INFO("\n__________________________________\nFinished processing thread plg %s\n__________________________________\n", plg->data.misc.name);
196 #endif
197  return NULL;
198 }
199 
205 void polygon_primitive_received_handler(const polygon_primitive_msg::polygon_primitive& input)
206 {
207 
208  ros::Duration(0.1).sleep();
209 
210  ROS_INFO("Received a new polygon primitive msg. Polygon name %s", input.name.c_str());
211 
212  //----------------------------------------------------
213  //Skip some polygon if required
214  //----------------------------------------------------
215  if (input.name!="p1")
216  return;
217 
218  //----------------------------------------------------
219  //Find the key of this polygon in the map structure. The pointer plg will point to the polygon
220  //----------------------------------------------------
222  std::map<std::string, c_polygon_primitive_with_texture>::iterator it;
223  it = pmap.find(input.name);
224 
225  //----------------------------------------------------
226  //a key with this id was found. Must adapt the polygon
227  //----------------------------------------------------
228  if (it != pmap.end())
229  {
230  ROS_INFO("have a key with code %s . Will addapt polygon", input.name.c_str());
231 
232  it->second.readapt_to_new_plane((polygon_primitive_msg::polygon_primitive*)&input); //adapt the polygon to new plane
233 
234  //for (size_t i=0; i<it->second.cp.size(); i++)
235  //{
236  //printf("RE adding projection camera %d to mesh\n",(int)i);
237  //it->second.dp.add_point_cloud(&it->second.cp[i].vertex_projectable, &it->second.cp[i].vertex_projectable_weight, i);
238  //}
239 
240  plg = &it->second; //Set the pointer to the polygon in the map were using
241 
242  }
243  else //no key found, should add to map
244  {
245  ROS_INFO("have no key with code %s . Will add polygon to pmap", input.name.c_str());
246 
247  //Create a polygon from the polygon_msg
248  c_polygon_primitive_with_texture new_plg_from_msg(p_node);
249  new_plg_from_msg.import_from_polygon_primitive_msg((polygon_primitive_msg::polygon_primitive*) &input);
250 
251  //Add the polygon to the map
252  std::pair< std::map<std::string, c_polygon_primitive_with_texture>::iterator, bool> ret;
253  ret = pmap.insert(std::pair<std::string, c_polygon_primitive_with_texture>(input.name, new_plg_from_msg));
254  if (ret.second==false)
255  {
256  plg=NULL;
257  ROS_ERROR("Error, could not insert polygon to map");
258  }
259  else
260  {
261  plg = &ret.first->second;
262  }
263  }
264 
265 #if _USE_THREADS_
266  pthread_create(&plg->thread,NULL,process_polygon_primitive,(void*) plg);
267 #else
268  process_polygon_primitive((void*)plg);
269 #endif
270 }
271 
278 int main(int argc, char **argv)
279 {
280  ros::init(argc, argv, "texturize_polygon_primitives"); // Initialize ROS coms
281  ros::NodeHandle n; //The node handle
282  p_node = &n;
283  ros::Rate r(10);
284  ros::Rate r1(1);
285 
286  cv::startWindowThread();
287 
288  tf::TransformListener listener;
289  p_listener = &listener;
290 
291  image_transport::ImageTransport it(n);
292  image_transport::Subscriber sub_fc = it.subscribe("/cam_roof_fc", 1, handler_cam_roof_fc);
293  while(n.ok()){ros::spinOnce(); if (cam_roof_fc.msg_received) break; ROS_INFO("Waiting for first topic /cam_roof_fc");r1.sleep();}
294 
295  image_transport::Subscriber sub_fl = it.subscribe("/cam_roof_fl", 1, handler_cam_roof_fl);
296  //while(n.ok()){ros::spinOnce(); if (cam_roof_fl.msg_received) break; ROS_INFO("Waiting for first topic /cam_roof_fl");r1.sleep();}
297 
298  image_transport::Subscriber sub_fr = it.subscribe("/cam_roof_fr", 1, handler_cam_roof_fr);
299  //while(n.ok()){ros::spinOnce(); if (cam_roof_fr.msg_received) break; ROS_INFO("Waiting for first topic /cam_roof_fr");r1.sleep();}
300 
301  image_transport::Subscriber sub_rc = it.subscribe("/cam_roof_rc", 1, handler_cam_roof_rc);
302  //while(n.ok()){ros::spinOnce(); if (cam_roof_rc.msg_received) break; ROS_INFO("Waiting for first topic /cam_roof_rc");r1.sleep();}
303 
304  image_transport::Subscriber sub_fc_6mm = it.subscribe("/cam_roof_fc_6mm", 1, handler_cam_roof_fc_6mm);
305  //while(n.ok()){ros::spinOnce(); if (cam_roof_fc_6mm.msg_received) break; ROS_INFO("Waiting for first topic /cam_roof_fc_6mm");r1.sleep();}
306 
307  ros::Subscriber sub_polygon_primitive = n.subscribe("/polygon_primitive", 10, polygon_primitive_received_handler);
308  ros::Publisher markerarray_pub = n.advertise<visualization_msgs::MarkerArray>("/PolygonMarkers_with_texture", 5);
309  p_markerarray_pub = &markerarray_pub;
310 
311  ROS_INFO("Waiting for topic /polygon_primitive");
312  mission_start = ros::Time::now();
313 
314  ros::Time t=ros::Time::now();
315  while(n.ok())
316  {
317  ros::Duration d = ros::Time::now()-t;
318  //ROS_INFO("duration = %f", d.toSec());
319  if (d.toSec()>5)
320  {
321  //-------------------------------------------
322  //Send new info to rviz
323  //-------------------------------------------
324  std::vector<visualization_msgs::Marker> marker_vec;
325  visualization_msgs::MarkerArray marker_array_msg;
326  std::map<std::string, c_polygon_primitive_with_texture>::iterator it;
327 
328  ROS_INFO("Sending textured polygon primitives to RVIZ");
329  for (it=pmap.begin(); it!=pmap.end();++it)
330  {
331  visualization_msgs::MarkerArray marker_vec;
332  // visualization_msgs::MarkerArray marker_array_msg;
333 
334 
335 #if _USE_THREADS_
336  if (pthread_mutex_trylock(&it->second.mutex)) //check mutex
337  {
338 #endif
339  ROS_INFO("Sending tpp %s", it->second.data.misc.name);
340  it->second.create_textures_vizualization_msg(&marker_vec, false);
341  //marker_array_msg.set_markers_vec(marker_vec);
342  p_markerarray_pub->publish(marker_vec);
343 
344  for (size_t i=0; i<it->second.cp.size();i++)
345  {
346  cv::namedWindow(it->second.cp[i].projection_name);
347  cv::imshow(it->second.cp[i].projection_name,it->second.cp[i].image_gui);
348  //cv::namedWindow(it->second.cp[i].projection_name+"canny");
349  //cv::imshow(it->second.cp[i].projection_name+"canny",it->second.cp[i].mask_projectable_pixels);
350  }
351 
352 #if _USE_THREADS_
353  pthread_mutex_unlock(&it->second.mutex);
354  }
355  else
356  {
357  ROS_WARN("Could not send tpp %s. Thread locked", it->second.data.misc.name);
358  }
359 #endif
360 
361  }
362 
363  cv::waitKey(50);
364 
365  t=ros::Time::now();
366  }
367 
368  r.sleep();
369  ros::spinOnce();
370  }
371 
372  PFLN
373 
374  return 0;
375 }
376 #endif
377 
#define PFLN
_EXTERN_ ros::Publisher * p_markerarray_pub
_EXTERN_ t_cam cam_roof_rc
int add_camera_projection_known_camera(cv::Mat *m, ros::Time t, tf::StampedTransform tf, std::string cam_name, std::string projection_name, cv::Scalar color)
std::vector< class_camera_projection > cp
tf::StampedTransform tf
void handler_cam_roof_fr(const sensor_msgs::ImageConstPtr &msg)
_EXTERN_ t_cam cam_roof_fl
_EXTERN_ t_cam cam_roof_fc
int main(int argc, char **argv)
The main function for the extraction of polygon primitives.
_EXTERN_ tf::TransformListener * p_listener
void handler_cam_roof_fc_6mm(const sensor_msgs::ImageConstPtr &msg)
_EXTERN_ t_cam cam_roof_fr
_EXTERN_ ros::Time mission_start
_EXTERN_ t_cam cam_roof_fc_6mm
struct t_polygon_primitive_data::@2 misc
void handler_cam_roof_fl(const sensor_msgs::ImageConstPtr &msg)
int add_camera_projection_to_polygon(std::string cam_name, t_cam *cam, c_polygon_primitive_with_texture *plg)
void polygon_primitive_received_handler(const polygon_primitive_msg::polygon_primitive &input)
Handles the receiving of a new polygonal primitive message.
t_polygon_primitive_data data
_EXTERN_ ros::NodeHandle * p_node
cv_bridge::CvImagePtr cv_ptr
void init(void)
Definition: ddt.cpp:142
Header of the texturize polygon primitives binary.
int build_global_mesh(ros::Publisher *p_marker_pub)
void * process_polygon_primitive(void *ptr)
_EXTERN_ std::map< std::string, c_polygon_primitive_with_texture > pmap
void handler_cam_roof_fc(const sensor_msgs::ImageConstPtr &msg)
void handler_cam_roof_rc(const sensor_msgs::ImageConstPtr &msg)


polygon_primitives_extraction
Author(s): Miguel Oliveira
autogenerated on Mon Mar 2 2015 01:32:42