read_velodyne.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 ***************************************************************************************************/
33 #ifndef _READ_VELODYNE_CPP_
34 #define _READ_VELODYNE_CPP_
35 
36 #include "read_velodyne.h"
37 
39 {
40  public:
41 
44  {
45  coefficients = pcl::ModelCoefficients::Ptr(new pcl::ModelCoefficients);
46  indices = pcl::PointIndices::Ptr(new pcl::PointIndices);
47 
48  }
49 
52  {
53  delete &coefficients;
54  delete &indices;
55  }
56 
57 
59  pcl::ModelCoefficients::Ptr coefficients;
60  pcl::PointIndices::Ptr indices;
61  pcl::PointCloud<PointT> cloud;
62 
63 
64 
65  private:
66 
67 
68 
69 };
70 
71 void signal_handler(int sig)
72 {
73  printf("%d %d %d\n",sig,SIGSEGV,SIGINT);
74 
75  if(sig==SIGSEGV)
76  {
77 
78  signal(SIGSEGV, SIG_DFL);
79 
80  ROS_WARN("System segfaulted");
81 
82  ros::shutdown();
83 
84  exit(0);
85  }
86  else if(sig==SIGINT)
87  {
88  ROS_WARN("Ctrl-c pressed");
89 
90  ros::shutdown();
91 
92  exit(0);
93  }
94 }
95 
100 
101 int main(int argc, char **argv)
102 {
103  if(argc < 4) {
104  fprintf(stderr,
105  "usage: example4-velodyne <logfile> <start_time> <end time>\n"
106  "\n"
107  "start_time and end_time are given in seconds from the\n"
108  "start of the log file\n");
109  return 1;
110  }
111 
112  lcm_eventlog_t *log = lcm_eventlog_create(argv[1], "r");
113  if(!log) {
114  fprintf(stderr, "error opening log file\n");
115  return 1;
116  }
117 
118  double start_time = strtod(argv[2], NULL);
119  double end_time = strtod(argv[3], NULL);
120 
121  Config *config = config_parse_default();
122  if(!config) {
123  fprintf(stderr, "couldn't find config file\n");
124  return 1;
125  }
126 
127  // load the velodyne sensor calibration
129 
130  // read the first timestamp of the log file
132  int64_t first_timestamp = event->timestamp;
133 
134  // compute the desired start and end timestamps
135  int64_t start_utime = first_timestamp + (int64_t)(start_time * 1000000);
136  int64_t end_utime = first_timestamp + (int64_t)(end_time * 1000000);
137 
138  lcmtypes_pose_t last_pose;
139  memset(&last_pose, 0, sizeof(last_pose));
140 
141 
143  t_flags.debug=false;
144 
146  ros::init(argc, argv, "point_cloud_publisher");
147 
148  ros::NodeHandle n;
149  ros::Publisher cloud_pub = n.advertise<sensor_msgs::PointCloud2>("cloud", 1);
150 
151  ros::Publisher pub[10];
152 
153  for (int i=0; i< _NUM_POLYGONS_; i ++)
154  {
155  char str[256];
156  sprintf(str, "plg_%d",i);
157  pub[i] = n.advertise<sensor_msgs::PointCloud2>(str, 1);
158  }
159 
161  ros::Publisher marker_pub = n.advertise<visualization_msgs::Marker>("visualization_marker", 10);
162 
163 
164  ros::Rate r(0.5);
165 
166  //pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>);
167  pcl::PointCloud<PointT> cloud;
168  sensor_msgs::PointCloud2 cloud_msg;
169  cloud.header.frame_id = "/sensor_frame";
170  cloud.height = 1;
171  cloud.is_dense=0;
172 
173  while(1)
174  {
175  // release the last event
177 
178  // read an event
179  event = lcm_eventlog_read_next_event(log);
180 
181  if(!event)
182  break;
183 
184  // always keep track of the current pose
185  if(!strcmp(event->channel, "POSE")) {
186  if(last_pose.utime)
187  lcmtypes_pose_t_decode_cleanup(&last_pose);
188 
189  lcmtypes_pose_t_decode(event->data, 0, event->datalen, &last_pose);
190  }
191 
192  // ignore other messages until the desired start time
193  if(event->timestamp < start_utime) {
194  continue;
195  }
196 
197  // quit if we're done
198  if(event->timestamp >= end_utime) {
199  break;
200  }
201 
202  if(!strcmp(event->channel, "VELODYNE")) {
203  // parse the LCM packet into a velodyne data packet.
205  lcmtypes_velodyne_t_decode(event->data, 0, event->datalen,
206  &vel);
207 
208  // compute the velodyne-to-local transformation matrix
209  //
210  // This is an approximation because we're using the last recorded
211  // pose. A more accurate projection might be to project the
212  // vehicle's pose forward based on its last measured velocity.
213  double velodyne_to_local[16];
214  config_util_sensor_to_local_with_pose (config, "VELODYNE",
215  velodyne_to_local, &last_pose);
216 
217  // parse the velodyne data packet
218  velodyne_decoder_t vdecoder;
219  velodyne_decoder_init(vcalib, &vdecoder, vel.data, vel.datalen);
220 
221  // project each sample in the velodyne data packet into the local
222  // frame
223  velodyne_sample_t vsample;
224 
225  while (!velodyne_decoder_next(vcalib, &vdecoder, &vsample))
226  {
227  if (vsample.range < 0.01)
228  {
229  continue;
230  }
231 
232  double sensor_xyz[4] = {vsample.xyz[0], vsample.xyz[1], vsample.xyz[2], 1 };
233  double local_xyz[4];
234 
235  matrix_vector_multiply_4x4_4d(velodyne_to_local, sensor_xyz, local_xyz);
236 
237  //printf("%f %f %f\n", local_xyz[0], local_xyz[1], local_xyz[2]);
238 
239 
240  PointT Pt;
241  Pt.x = local_xyz[0];
242  Pt.y = local_xyz[1];
243  Pt.z = local_xyz[2];
244 
245  //Pt.x = sensor_xyz[0];
246  //Pt.y = sensor_xyz[1];
247  //Pt.z = sensor_xyz[2];
248  cloud.push_back(Pt);
249 
250  }
251 
252  cloud.width = cloud.size();
254  }
255 }
256 
257  while(n.ok())
258  {
259 
260  visualization_msgs::Marker markers;
261  markers.header.frame_id = "/sensor_frame";
262  markers.header.stamp = ros::Time::now();
263  markers.ns = "triangles";
264  markers.action = visualization_msgs::Marker::ADD;
265  markers.pose.orientation.w = 1.0;
266  markers.type = visualization_msgs::Marker::TRIANGLE_LIST;
267 
268  markers.scale.x = 1;
269  markers.scale.y = 1;
270  markers.scale.z = 1;
271 
272  markers.color.r = 1;
273  markers.color.g = 1;
274  markers.color.b = 1;
275  markers.color.a = 1;
276 
277  geometry_msgs::Point p;
278  std_msgs::ColorRGBA color;
279  p.x = 0;
280  p.y = 0;
281  p.z = 0;
282  markers.points.push_back(p);
283  color.r = 1.0f;
284  color.g = 0.2f;
285  color.b = 1.0f;
286  color.a = 1.0;
287  markers.colors.push_back(color);
288 
289  p.x = 10;
290  p.y = 10;
291  p.z = 0;
292  markers.points.push_back(p);
293  color.r = 1.0f;
294  color.g = 0.2f;
295  color.b = 0.5f;
296  color.a = 1.0;
297  markers.colors.push_back(color);
298 
299  p.x = 10;
300  p.y = -10;
301  p.z = 0;
302  markers.points.push_back(p);
303  color.r = 0.8f;
304  color.g = 0.2f;
305  color.b = 1.0f;
306  color.a = 1.0;
307  markers.colors.push_back(color);
308 
309  marker_pub.publish(markers);
310 
311  printf("num pts = %d\n",(int)markers.points.size());
312  printf("num colors = %d\n",(int)markers.colors.size());
313 
314 // cloud.header.stamp = ros::Time::now();
315  ROS_ERROR("Cloud timestamp not set, problem during migration lar3 to lar4");
316  ROS_INFO("publishing cloud with %d points",(int)cloud.size());
317 
318  pcl::toROSMsg(cloud, cloud_msg);
319  cloud_pub.publish(cloud_msg);
320 
321  c_polygon_representation *plg[10];
322 
324  //pcl::ModelCoefficients coefficients;
325  //pcl::PointIndices::Ptr indices_model(new pcl::PointIndices);
326  //pcl::PointCloud<PointT> cloud_model;
327 
329  sensor_msgs::PointCloud2 cloud_model_msg;
330 
331 
333  pcl::SACSegmentation<PointT> seg;
334  seg.setOptimizeCoefficients(true);
335  seg.setModelType(pcl::SACMODEL_PLANE);
336  seg.setMethodType (pcl::SAC_RANSAC);
337  seg.setDistanceThreshold (0.3);
338  seg.setMaxIterations (1000);
339 
341  pcl::ExtractIndices<PointT> extract;
342 
343 
344  pcl::PointCloud<PointT> cloud_tmp;
345  cloud_tmp = cloud;
346 
348  for (int i=0; i<_NUM_POLYGONS_;i++)
349  {
350 
351  plg[i] = new c_polygon_representation;
353  seg.setInputCloud(cloud_tmp.makeShared());
354  seg.segment(*plg[i]->indices, *plg[i]->coefficients);
355 
356  if (plg[i]->indices->indices.size () == 0)
357  {
358  ROS_ERROR("Could not estimate a planar model for the given dataset."); return (-1);
359  }
360  //std::cerr << "Model coefficients: " << coefficients[i].values[0] << " " << coefficients[i].values[1] << " " << coefficients[i].values[2] << " " coefficients[i].values[3] << std::endl;
361  //std::cerr << "Model inliers: " << model[i].size () << std::endl;
362 
364  extract.setInputCloud(cloud_tmp.makeShared());
365  extract.setIndices(plg[i]->indices);
366  extract.setNegative(false);
367  extract.filter(plg[i]->cloud);
368  extract.setNegative(true);
369  extract.filter(cloud_tmp);
370  }
371 
373  for (int i=0; i<_NUM_POLYGONS_;i++)
374  {
375 
377  plg[i]->cloud.header.frame_id = "/sensor_frame";
378  plg[i]->cloud.height = 1; //1 since its and unordered pc
379  plg[i]->cloud.is_dense=0;
380  plg[i]->cloud.width = plg[i]->cloud.size();
381  ROS_INFO("publishing cloud_model[%d] with %d points",i,(int)plg[i]->cloud.size());
382  pcl::toROSMsg(plg[i]->cloud, cloud_model_msg);
383  pub[i].publish(cloud_model_msg);
384  }
385 
386 
387 
388 
389 
390 
391 
392 
393 
394 
395  //for (size_t i = 0; i < inliers.indices.size (); ++i)
396  //{
397  //Pt.x = cloud.points[inliers.indices[i]].x;
398  //Pt.y = cloud.points[inliers.indices[i]].y;
399  //Pt.z = cloud.points[inliers.indices[i]].z;
400 
403  //uint8_t r = 255, g = 0, b = 0; // Example: Red color
404  //uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
405  //Pt.rgb = *reinterpret_cast<float*>(&rgb);
406 
407  //cloud_inliers.push_back(Pt);
408  //}
409 
410  //cloud_inliers.header.stamp = ros::Time::now();
411  //cloud_inliers.width = cloud_inliers.size();
412  //ROS_INFO("publishing cloud_inliers with %d points",cloud_inliers.size());
413  //pcl::toROSMsg(cloud_inliers, cloud_inliers_msg);
414  //cloud_inliers_pub.publish(cloud_inliers_msg);
415 
416  //pcl::ExtractIndices<PointXYZ> extract;
417 
418 
419 
420  r.sleep();
421 
422 
423 }
425 
427 
428 
429  return 0;
430 }
431 
432 #endif
433 
int lcmtypes_velodyne_t_decode(const void *buf, int offset, int maxlen, lcmtypes_velodyne_t *p)
Config * config_parse_default(void)
Definition: config.cpp:603
int lcmtypes_pose_t_decode_cleanup(lcmtypes_pose_t *p)
void lcm_eventlog_destroy(lcm_eventlog_t *l)
Definition: eventlog.cpp:74
lcm_eventlog_event_t * lcm_eventlog_read_next_event(lcm_eventlog_t *l)
Definition: eventlog.cpp:80
velodyne_calib_t * velodyne_calib_create()
Definition: velodyne.cpp:273
int velodyne_decoder_init(velodyne_calib_t *v, velodyne_decoder_t *vd, const void *_data, int datalen)
Definition: velodyne.cpp:61
int lcmtypes_pose_t_decode(const void *buf, int offset, int maxlen, lcmtypes_pose_t *p)
c_polygon_representation()
Constructor. Allocate space for Ptr objecs.
static void matrix_vector_multiply_4x4_4d(const double m[16], const double v[4], double result[4])
Definition: small_linalg.h:106
pcl::PointIndices::Ptr indices
header file for read_velodyne.cpp
int velodyne_decoder_next(velodyne_calib_t *v, velodyne_decoder_t *vd, struct velodyne_sample *sample)
Definition: velodyne.cpp:87
int lcmtypes_velodyne_t_decode_cleanup(lcmtypes_velodyne_t *p)
int main(int argc, char **argv)
int config_util_sensor_to_local_with_pose(Config *cfg, const char *name, double m[16], lcmtypes_pose_t *p)
~c_polygon_representation()
destructor. free space of Ptr objecs
void lcm_eventlog_free_event(lcm_eventlog_event_t *le)
Definition: eventlog.cpp:118
pcl::PointXYZ PointT
Definition: read_velodyne.h:85
void signal_handler(int sig)
pcl::ModelCoefficients::Ptr coefficients
Variables for polyplane segmentation and representation.
#define _NUM_POLYGONS_
Definition: read_velodyne.h:86
lcm_eventlog_t * lcm_eventlog_create(const char *path, const char *mode)
Definition: eventlog.cpp:61
pcl::PointCloud< PointT > cloud
double xyz[3]
Definition: velodyne.h:63
double range
Definition: velodyne.h:65


mit_darpa_logs_player
Author(s): Miguel Oliveira
autogenerated on Mon Mar 2 2015 01:32:15