spatio_temporal_voxel_layer.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Software License Agreement
4  *
5  * Copyright (c) 2018, Simbe Robotics, Inc.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of Simbe Robotics, Inc. nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * Author: Steve Macenski (steven.macenski@simberobotics.com)
36  *********************************************************************/
37 
39 
41 
42 /*****************************************************************************/
44 /*****************************************************************************/
45 {
46 }
47 
48 /*****************************************************************************/
50 /*****************************************************************************/
51 {
53  {
55  }
56  if (_voxel_grid)
57  {
58  delete _voxel_grid;
59  }
60 }
61 
62 /*****************************************************************************/
64 /*****************************************************************************/
65 {
66  ROS_INFO("%s being initialized as SpatioTemporalVoxelLayer!", \
67  getName().c_str());
68 
69  // initialize parameters, grid, and sub/pubs
70  ros::NodeHandle nh("~/" + name_), g_nh, prefix_nh;
71 
73  ROS_INFO("%s's global frame is %s.", \
74  getName().c_str(), _global_frame.c_str());
75 
76  bool track_unknown_space;
77  double transform_tolerance, map_save_time;
78  std::string topics_string;
79  int decay_model_int;
80  // source names
81  nh.param("observation_sources", topics_string, std::string(""));
82  // timeout in seconds for transforms
83  nh.param("transform_tolerance", transform_tolerance, 0.2);
84  // whether to default on
85  nh.param("enabled", _enabled, true);
86  enabled_ = _enabled; // costmap_2d for some unexplicable reason uses globals
87  // publish the voxel grid to visualize
88  nh.param("publish_voxel_map", _publish_voxels, false);
89  // size of each voxel in meters
90  nh.param("voxel_size", _voxel_size, 0.05);
91  // 1=takes highest in layers, 0=takes current layer
92  nh.param("combination_method", _combination_method, 1);
93  // number of voxels per vertical needed to have obstacle
94  nh.param("mark_threshold", _mark_threshold, 0);
95  // clear under robot footprint
96  nh.param("update_footprint_enabled", _update_footprint_enabled, true);
97  // keep tabs on unknown space
98  nh.param("track_unknown_space", track_unknown_space, \
100  nh.param("decay_model", decay_model_int, 0);
101  _decay_model = static_cast<volume_grid::GlobalDecayModel>(decay_model_int);
102  // decay param
103  nh.param("voxel_decay", _voxel_decay, -1.);
104  // whether to map or navigate
105  nh.param("mapping_mode", _mapping_mode, false);
106  // if mapping, how often to save a map for safety
107  nh.param("map_save_duration", map_save_time, 60.);
108  ROS_INFO("%s loaded parameters from parameter server.", getName().c_str());
109 
110  if (_mapping_mode)
111  {
112  _map_save_duration = ros::Duration(map_save_time);
114  }
115 
116  if (track_unknown_space)
117  {
119  }
120  else
121  {
123  }
124 
125  _voxel_pub = nh.advertise<sensor_msgs::PointCloud2>("voxel_grid", 1);
126  _grid_saver = nh.advertiseService("spatiotemporal_voxel_grid/save_grid", \
128  this);
129 
131  (double)default_value_, \
132  _decay_model, \
133  _voxel_decay, \
135  matchSize();
136  current_ = true;
137  ROS_INFO("%s created underlying voxel grid.", getName().c_str());
138 
139  const std::string tf_prefix = tf::getPrefixParam(prefix_nh);
140  std::stringstream ss(topics_string);
141  std::string source;
142  while (ss >> source)
143  {
144  ros::NodeHandle source_node(nh, source);
145 
146  // get the parameters for the specific topic
147  double observation_keep_time, expected_update_rate, min_obstacle_height;
148  double max_obstacle_height, min_z, max_z, vFOV, vFOVPadding;
149  double hFOV, decay_acceleration;
150  std::string topic, sensor_frame, data_type;
151  bool inf_is_valid, clearing, marking, voxel_filter, clear_after_reading, enabled;
152 
153  source_node.param("topic", topic, source);
154  source_node.param("sensor_frame", sensor_frame, std::string(""));
155  source_node.param("observation_persistence", observation_keep_time, 0.0);
156  source_node.param("expected_update_rate", expected_update_rate, 0.0);
157  source_node.param("data_type", data_type, std::string("PointCloud2"));
158  source_node.param("min_obstacle_height", min_obstacle_height, 0.0);
159  source_node.param("max_obstacle_height", max_obstacle_height, 3.0);
160  source_node.param("inf_is_valid", inf_is_valid, false);
161  source_node.param("clearing", clearing, false);
162  source_node.param("marking", marking, true);
163  // minimum distance from camera it can see
164  source_node.param("min_z", min_z, 0.);
165  // maximum distance from camera it can see
166  source_node.param("max_z", max_z, 10.);
167  // vertical FOV angle in rad
168  source_node.param("vertical_fov_angle", vFOV, 0.7);
169  // vertical FOV padding in meters (3D lidar frustum only)
170  source_node.param("vertical_fov_padding", vFOVPadding, 0.0);
171  // horizontal FOV angle in rad
172  source_node.param("horizontal_fov_angle", hFOV, 1.04);
173  // acceleration scales the model's decay in presence of readings
174  source_node.param("decay_acceleration", decay_acceleration, 0.);
175  // performs an approximate voxel filter over the data to reduce
176  source_node.param("voxel_filter", voxel_filter, false);
177  // clears measurement buffer after reading values from it
178  source_node.param("clear_after_reading", clear_after_reading, false);
179  // Whether the frustum is enabled on startup. Can be toggled with service
180  source_node.param("enabled", enabled, true);
181 
182  // model type - default depth camera frustum model
183  int model_type_int;
184  source_node.param("model_type", model_type_int, 0);
185  ModelType model_type = static_cast<ModelType>(model_type_int);
186 
187  if (!sensor_frame.empty())
188  {
189  sensor_frame = tf::resolve(tf_prefix, sensor_frame);
190  }
191 
192  if (!(data_type == "PointCloud2" || data_type == "LaserScan"))
193  {
194  throw std::runtime_error( \
195  "Only topics that use pointclouds or laser scans are supported.");
196  }
197 
198  std::string obstacle_range_param_name;
199  double obstacle_range = 3.0;
200  if (source_node.searchParam("obstacle_range", obstacle_range_param_name))
201  {
202  source_node.getParam(obstacle_range_param_name, obstacle_range);
203  }
204 
205  // create an observation buffer
206  _observation_buffers.push_back(
208  (new buffer::MeasurementBuffer(topic, observation_keep_time, \
209  expected_update_rate, min_obstacle_height, max_obstacle_height, \
210  obstacle_range, *tf_, _global_frame, sensor_frame, \
211  transform_tolerance, min_z, max_z, vFOV, vFOVPadding, hFOV, \
212  decay_acceleration, marking, clearing, _voxel_size, \
213  voxel_filter, enabled, clear_after_reading, model_type)));
214 
215  // Add buffer to marking observation buffers
216  if (marking == true)
217  {
218  _marking_buffers.push_back(_observation_buffers.back());
219  }
220 
221  // Add buffer to clearing observation buffers
222  if (clearing == true)
223  {
224  _clearing_buffers.push_back(_observation_buffers.back());
225  }
226 
227  // create a callback for the topic
228  if (data_type == "LaserScan")
229  {
232  topic, 50));
233  _observation_subscribers.push_back(sub);
234 
236  > filter(new tf::MessageFilter<sensor_msgs::LaserScan>(*sub, \
237  *tf_, _global_frame, 50));
238 
239  if (inf_is_valid)
240  {
241  filter->registerCallback(
243  this, _1,_observation_buffers.back()));
244  } else {
245  filter->registerCallback(
247  this, _1, _observation_buffers.back()));
248  }
249 
250  _observation_subscribers.push_back(sub);
251  _observation_notifiers.push_back(filter);
252 
253  _observation_notifiers.back()->setTolerance(ros::Duration(0.05));
254  }
255 
256  else if (data_type == "PointCloud2")
257  {
260  topic, 50));
261  _observation_subscribers.push_back(sub);
262 
265  *tf_, _global_frame, 50));
266  filter->registerCallback(
267  boost::bind(&SpatioTemporalVoxelLayer::PointCloud2Callback, this, _1, \
268  _observation_buffers.back()));
269 
270  ros::ServiceServer server;
271  boost::function < bool(std_srvs::SetBool::Request&, \
272  std_srvs::SetBool::Response&) > serv_callback;
273 
274  serv_callback = boost::bind(&SpatioTemporalVoxelLayer::BufferEnablerCallback, \
275  this, _1, _2, _observation_buffers.back(), \
277 
278  std::string topic = source + "/toggle_enabled";
279  server = nh.advertiseService(topic, serv_callback);
280 
281  _buffer_enabler_servers.push_back(server);
282  _observation_subscribers.push_back(sub);
283  _observation_notifiers.push_back(filter);
284  }
285 
286  if (sensor_frame != "")
287  {
288  std::vector<std::string> target_frames;
289  target_frames.reserve(2);
290  target_frames.push_back(_global_frame);
291  target_frames.push_back(sensor_frame);
292  _observation_notifiers.back()->setTargetFrames(target_frames);
293  }
294  }
295 
296  // Dynamic reconfigure
297  dynamic_reconfigure::Server<dynamicReconfigureType>::CallbackType f;
299  this, _1, _2);
301  _dynamic_reconfigure_server->setCallback(f);
302 
303  ROS_INFO("%s initialization complete!", getName().c_str());
304 }
305 
306 /*****************************************************************************/
308  const sensor_msgs::LaserScanConstPtr& message, \
310 /*****************************************************************************/
311 {
312  // laser scan where infinity is invalid callback function
313  sensor_msgs::PointCloud2 cloud;
314  cloud.header = message->header;
315  try
316  {
318  message->header.frame_id, *message, cloud, *tf_);
319  } catch (tf::TransformException &ex) {
320  ROS_WARN("TF returned a transform exception to frame %s: %s", \
321  _global_frame.c_str(), ex.what());
322  _laser_projector.projectLaser(*message, cloud);
323  }
324  // buffer the point cloud
325  buffer->Lock();
326  buffer->BufferROSCloud(cloud);
327  buffer->Unlock();
328 }
329 
330 /*****************************************************************************/
332  const sensor_msgs::LaserScanConstPtr& raw_message, \
334 /*****************************************************************************/
335 {
336  // Filter infinity to max_range
337  float epsilon = 0.0001;
338  sensor_msgs::LaserScan message = *raw_message;
339  for (size_t i = 0; i < message.ranges.size(); i++)
340  {
341  float range = message.ranges[i];
342  if (!std::isfinite(range) && range > 0)
343  {
344  message.ranges[i] = message.range_max - epsilon;
345  }
346  }
347  sensor_msgs::PointCloud2 cloud;
348  cloud.header = message.header;
349  try {
351  message.header.frame_id, message, cloud, *tf_);
352  } catch (tf::TransformException &ex) {
353  ROS_WARN("TF returned a transform exception to frame %s: %s", \
354  _global_frame.c_str(), ex.what());
355  _laser_projector.projectLaser(message, cloud);
356  }
357  // buffer the point cloud
358  buffer->Lock();
359  buffer->BufferROSCloud(cloud);
360  buffer->Unlock();
361 }
362 
363 /*****************************************************************************/
365  const sensor_msgs::PointCloud2ConstPtr& message, \
367 /*****************************************************************************/
368 {
369  // buffer the point cloud
370  buffer->Lock();
371  buffer->BufferROSCloud(*message);
372  buffer->Unlock();
373 }
374 
375 /*****************************************************************************/
377  std_srvs::SetBool::Request& request, \
378  std_srvs::SetBool::Response& response, \
381 /*****************************************************************************/
382 {
383  buffer->Lock();
384  if (buffer->IsEnabled() != request.data)
385  {
386  buffer->SetEnabled(request.data);
387  if (request.data)
388  {
389  subcriber->subscribe();
390  buffer->ResetLastUpdatedTime();
391  response.message = "Enabling sensor";
392  }
393  else if (subcriber)
394  {
395  subcriber->unsubscribe();
396  response.message = "Disabling sensor";
397  }
398  }
399  else
400  {
401  response.message = "Sensor already in the required state doing nothing";
402  }
403  buffer->Unlock();
404  response.success = true;
405  return response.success;
406 }
407 
408 
409 /*****************************************************************************/
411  std::vector<observation::MeasurementReading>& marking_observations) const
412 /*****************************************************************************/
413 {
414  // get marking observations and static marked areas
415  bool current = true;
416 
417  for (unsigned int i = 0; i != _marking_buffers.size(); ++i)
418  {
419  _marking_buffers[i]->Lock();
420  _marking_buffers[i]->GetReadings(marking_observations);
421  current = _marking_buffers[i]->UpdatedAtExpectedRate();
422  _marking_buffers[i]->Unlock();
423  }
424  marking_observations.insert(marking_observations.end(), \
425  _static_observations.begin(), \
426  _static_observations.end());
427  return current;
428 }
429 
430 /*****************************************************************************/
432  std::vector<observation::MeasurementReading>& clearing_observations) const
433 /*****************************************************************************/
434 {
435  // get clearing observations
436  bool current = true;
437  for (unsigned int i = 0; i != _clearing_buffers.size(); ++i)
438  {
439  _clearing_buffers[i]->Lock();
440  _clearing_buffers[i]->GetReadings(clearing_observations);
441  current = _clearing_buffers[i]->UpdatedAtExpectedRate();
442  _clearing_buffers[i]->Unlock();
443  }
444  return current;
445 }
446 
447 /*****************************************************************************/
449 /*****************************************************************************/
450 {
451  for (unsigned int i = 0; i != _clearing_buffers.size(); ++i)
452  {
453  _clearing_buffers[i]->Lock();
454  if (_clearing_buffers[i]->ClearAfterReading())
455  {
456  _clearing_buffers[i]->ResetAllMeasurements();
457  }
458  _clearing_buffers[i]->Unlock();
459  }
460 
461  for (unsigned int i = 0; i != _marking_buffers.size(); ++i)
462  {
463  _marking_buffers[i]->Lock();
464  if (_marking_buffers[i]->ClearAfterReading())
465  {
466  _marking_buffers[i]->ResetAllMeasurements();
467  }
468  _marking_buffers[i]->Unlock();
469  }
470  return;
471 }
472 
473 /*****************************************************************************/
474 bool SpatioTemporalVoxelLayer::updateFootprint(double robot_x, double robot_y, \
475  double robot_yaw, double* min_x,\
476  double* min_y, double* max_x, \
477  double* max_y)
478 /*****************************************************************************/
479 {
480  // updates layer costmap to include footprint for clearing in voxel grid
482  {
483  return false;
484  }
485  costmap_2d::transformFootprint(robot_x, robot_y, robot_yaw, getFootprint(), \
487  for (unsigned int i = 0; i < _transformed_footprint.size(); i++)
488  {
490  min_x, min_y, max_x, max_y);
491  }
492 }
493 
494 /*****************************************************************************/
496 /*****************************************************************************/
497 {
498  // subscribe and place info in buffers from sensor sources
499  ROS_INFO("%s was activated.", getName().c_str());
500 
502  for (sub_it; sub_it != _observation_subscribers.end(); ++sub_it)
503  {
504  (*sub_it)->subscribe();
505  }
506 
508  for (buf_it; buf_it != _observation_buffers.end(); ++buf_it)
509  {
510  (*buf_it)->ResetLastUpdatedTime();
511  }
512 }
513 
514 /*****************************************************************************/
516 /*****************************************************************************/
517 {
518  // unsubscribe from all sensor sources
519  ROS_INFO("%s was deactivated.", getName().c_str());
520 
522  for (sub_it; sub_it != _observation_subscribers.end(); ++sub_it)
523  {
524  if (*sub_it != NULL)
525  {
526  (*sub_it)->unsubscribe();
527  }
528  }
529 }
530 
531 /*****************************************************************************/
533 /*****************************************************************************/
534 {
535  boost::recursive_mutex::scoped_lock lock(_voxel_grid_lock);
536  // reset layer
537  Costmap2D::resetMaps();
538  this->ResetGrid();
539  current_ = true;
541  for (it; it != _observation_buffers.end(); ++it)
542  {
543  (*it)->ResetLastUpdatedTime();
544  }
545 }
546 
547 /*****************************************************************************/
550 /*****************************************************************************/
551 {
552  // observations to always be added to the map each update cycle not marked
553  ROS_INFO("%s: Adding static observation to map.", getName().c_str());
554 
555  try {
556  _static_observations.push_back(obs);
557  return true;
558  } catch(...) {
559  ROS_WARN("Could not add static observations to voxel layer");
560  return false;
561  }
562 }
563 
564 /*****************************************************************************/
566 /*****************************************************************************/
567 {
568  // kill all static observations added to each update cycle
569  ROS_INFO("%s: Removing static observations to map.", getName().c_str());
570 
571  try {
572  _static_observations.clear();
573  return true;
574  } catch(...) {
575  ROS_WARN("Couldn't remove static observations from %s.", \
576  getName().c_str());
577  return false;
578  }
579 }
580 
581 /*****************************************************************************/
583  SpatioTemporalVoxelLayerConfig& config, uint32_t level)
584 /*****************************************************************************/
585 {
586  boost::recursive_mutex::scoped_lock lock(_voxel_grid_lock);
587  bool update_grid(false);
588  auto updateFlagIfChanged = [&update_grid](auto& own, const auto& reference)
589  {
590  if (static_cast<float>(std::abs(own - reference)) >= FLT_EPSILON)
591  {
592  own = reference;
593  update_grid = true;
594  }
595  };
596 
597  auto default_value = (config.track_unknown_space) ? \
599  updateFlagIfChanged(default_value_, default_value);
600  updateFlagIfChanged(_voxel_size, config.voxel_size);
601  updateFlagIfChanged(_voxel_decay, config.voxel_decay);
602  int decay_model_int = (int)_decay_model;
603  updateFlagIfChanged(decay_model_int, config.decay_model);
604  updateFlagIfChanged(_publish_voxels, config.publish_voxel_map);
605 
606  _enabled = config.enabled;
607  _combination_method = config.combination_method;
608  _mark_threshold = config.mark_threshold;
609  _update_footprint_enabled = config.update_footprint_enabled;
610  _mapping_mode = config.mapping_mode;
611  _map_save_duration = ros::Duration(config.map_save_duration);
612  _decay_model = static_cast<volume_grid::GlobalDecayModel>(decay_model_int);
613 
614  if (update_grid)
615  {
616  delete _voxel_grid;
618  static_cast<double>(default_value_), _decay_model, \
620  }
621 }
622 
623 /*****************************************************************************/
625 /*****************************************************************************/
626 {
627  if (!_voxel_grid->ResetGrid())
628  {
629  ROS_WARN("Did not clear level set in %s!", getName().c_str());
630  }
631 }
632 
633 /*****************************************************************************/
635 /*****************************************************************************/
636 {
637  // match the master costmap size, volume_grid maintains full w/ expiration.
638  CostmapLayer::matchSize();
639 }
640 
641 /*****************************************************************************/
643  costmap_2d::Costmap2D& master_grid, \
644  int min_i, int min_j, int max_i, int max_j)
645 /*****************************************************************************/
646 {
647  // update costs in master_grid with costmap_
648  if(!_enabled)
649  {
650  return;
651  }
652 
654  {
656  }
657 
658  switch (_combination_method)
659  {
660  case 0:
661  updateWithOverwrite(master_grid, min_i, min_j, max_i, max_j);
662  case 1:
663  updateWithMax(master_grid, min_i, min_j, max_i, max_j);
664  default:
665  break;
666  }
667  return;
668 }
669 
670 /*****************************************************************************/
671 void SpatioTemporalVoxelLayer::UpdateROSCostmap(double* min_x, double* min_y, \
672  double* max_x, double* max_y)
673 /*****************************************************************************/
674 {
675  // grabs map of occupied cells from grid and adds to costmap_
676  Costmap2D::resetMaps();
677 
678  std::unordered_map<volume_grid::occupany_cell, uint>::iterator it;
679  for (it = _voxel_grid->GetFlattenedCostmap()->begin();
680  it != _voxel_grid->GetFlattenedCostmap()->end(); ++it)
681  {
682  uint map_x, map_y;
683  if ( it->second >= _mark_threshold && \
684  worldToMap(it->first.x, it->first.y, map_x, map_y))
685  {
687  touch(it->first.x, it->first.y, min_x, min_y, max_x, max_y);
688  }
689  }
690 }
691 
692 /*****************************************************************************/
694  double robot_x, double robot_y, double robot_yaw, \
695  double* min_x, double* min_y, double* max_x, double* max_y)
696 /*****************************************************************************/
697 {
698  // grabs new max bounds for the costmap
699  if (!_enabled)
700  {
701  return;
702  }
703 
704  boost::recursive_mutex::scoped_lock lock(_voxel_grid_lock);
705 
706  // Steve's Note June 22, 2018
707  // I dislike this necessity, I can't remove the master grid's knowledge about
708  // STVL on the fly so I have play games with the API even though this isn't
709  // really a rolling plugin implementation. It works, but isn't ideal.
711  {
712  updateOrigin(robot_x-getSizeInMetersX()/2, robot_y-getSizeInMetersY()/2);
713  }
714 
715  useExtraBounds(min_x, min_y, max_x, max_y);
716 
717  bool current = true;
718  std::vector<observation::MeasurementReading> marking_observations, \
719  clearing_observations;
720  current = GetMarkingObservations(marking_observations) && current;
721  current = GetClearingObservations(clearing_observations) && current;
723  current_ = current;
724 
725  // navigation mode: clear observations, mapping mode: save maps and publish
726  if (!_mapping_mode)
727  {
728  _voxel_grid->ClearFrustums(clearing_observations);
729  }
731  {
733  time_t rawtime;
734  struct tm* timeinfo;
735  char time_buffer[100];
736  time (&rawtime);
737  timeinfo = localtime (&rawtime);
738  strftime(time_buffer, 100, "%F-%r", timeinfo);
739 
740  spatio_temporal_voxel_layer::SaveGrid srv;
741  srv.request.file_name.data = time_buffer;
742  SaveGridCallback(srv.request, srv.response);
743  }
744 
745  // mark observations
746  _voxel_grid->Mark(marking_observations);
747 
748  // update the ROS Layered Costmap
749  UpdateROSCostmap(min_x, min_y, max_x, max_y);
750 
751  // publish point cloud in navigation mode
753  {
754  pcl::PointCloud<pcl::PointXYZ>::Ptr pc(new pcl::PointCloud<pcl::PointXYZ>);
756  sensor_msgs::PointCloud2 pc2;
757  pcl::toROSMsg(*pc, pc2);
758  pc2.header.frame_id = _global_frame;
759  pc2.header.stamp = ros::Time::now();
760  _voxel_pub.publish(pc2);
761  }
762 
763  // update footprint
764  updateFootprint(robot_x, robot_y, robot_yaw, min_x, min_y, max_x, max_y);
765  return;
766 }
767 
768 /*****************************************************************************/
770  spatio_temporal_voxel_layer::SaveGrid::Request& req, \
771  spatio_temporal_voxel_layer::SaveGrid::Response& resp)
772 /*****************************************************************************/
773 {
774  boost::recursive_mutex::scoped_lock lock(_voxel_grid_lock);
775  double map_size_bytes;
776 
777  if( _voxel_grid->SaveGrid(req.file_name.data, map_size_bytes) )
778  {
779  ROS_INFO( \
780  "SpatioTemporalVoxelGrid: Saved %s grid! Has memory footprint of %f bytes.",
781  req.file_name.data.c_str(), map_size_bytes);
782  resp.map_size_bytes = map_size_bytes;
783  resp.status = true;
784  return true;
785  }
786 
787  ROS_WARN("SpatioTemporalVoxelGrid: Failed to save grid.");
788  resp.status = false;
789  return false;
790 }
791 
792 }; // end namespace
793 
void projectLaser(const sensor_msgs::LaserScan &scan_in, sensor_msgs::PointCloud &cloud_out, double range_cutoff=-1.0, int channel_options=channel_option::Default)
LayeredCostmap * layered_costmap_
double epsilon
void updateWithOverwrite(costmap_2d::Costmap2D &master_grid, int min_i, int min_j, int max_i, int max_j)
void PointCloud2Callback(const sensor_msgs::PointCloud2ConstPtr &message, const boost::shared_ptr< buffer::MeasurementBuffer > &buffer)
void publish(const boost::shared_ptr< M > &message) const
std::string getPrefixParam(ros::NodeHandle &nh)
std::vector< boost::shared_ptr< buffer::MeasurementBuffer > >::iterator observation_buffers_iter
f
bool SaveGrid(const std::string &file_name, double &map_size_bytes)
void UpdateROSCostmap(double *min_x, double *min_y, double *max_x, double *max_y)
std::string getGlobalFrameID() const
bool updateFootprint(double robot_x, double robot_y, double robot_yaw, double *min_x, double *min_y, double *max_x, double *max_y)
double getSizeInMetersX() const
virtual void updateCosts(costmap_2d::Costmap2D &master_grid, int min_i, int min_j, int max_i, int max_j)
TFSIMD_FORCE_INLINE const tfScalar & y() const
PLUGINLIB_EXPORT_CLASS(spatio_temporal_voxel_layer::SpatioTemporalVoxelLayer, costmap_2d::Layer)
static const unsigned char FREE_SPACE
#define ROS_WARN(...)
double getSizeInMetersY() const
void useExtraBounds(double *min_x, double *min_y, double *max_x, double *max_y)
std::string name_
std::string getName() const
dynamic_reconfigure::Server< dynamicReconfigureType > dynamicReconfigureServerType
tf::TransformListener * tf_
void LaserScanValidInfCallback(const sensor_msgs::LaserScanConstPtr &raw_message, const boost::shared_ptr< buffer::MeasurementBuffer > &buffer)
std::string resolve(const std::string &prefix, const std::string &frame_name)
std::vector< boost::shared_ptr< buffer::MeasurementBuffer > > _observation_buffers
void ClearFrustums(const std::vector< observation::MeasurementReading > &clearing_observations)
std::vector< boost::shared_ptr< buffer::MeasurementBuffer > > _marking_buffers
#define ROS_INFO(...)
bool searchParam(const std::string &key, std::string &result) const
bool param(const std::string &param_name, T &param_val, const T &default_val) const
def default_value(type)
std::unordered_map< occupany_cell, uint > * GetFlattenedCostmap()
TFSIMD_FORCE_INLINE const tfScalar & x() const
bool setConvexPolygonCost(const std::vector< geometry_msgs::Point > &polygon, unsigned char cost_value)
std::vector< boost::shared_ptr< tf::MessageFilterBase > > _observation_notifiers
bool GetClearingObservations(std::vector< observation::MeasurementReading > &marking_observations) const
std::vector< boost::shared_ptr< message_filters::SubscriberBase > >::iterator observation_subscribers_iter
void Mark(const std::vector< observation::MeasurementReading > &marking_observations)
unsigned char default_value_
static const unsigned char LETHAL_OBSTACLE
static const unsigned char NO_INFORMATION
std::vector< boost::shared_ptr< message_filters::SubscriberBase > > _observation_subscribers
void GetOccupancyPointCloud(pcl::PointCloud< pcl::PointXYZ >::Ptr &pc)
bool getParam(const std::string &key, std::string &s) const
const std::vector< geometry_msgs::Point > & getFootprint() const
std::vector< boost::shared_ptr< buffer::MeasurementBuffer > > _clearing_buffers
void toROSMsg(const sensor_msgs::PointCloud2 &cloud, sensor_msgs::Image &image)
static Time now()
virtual void updateOrigin(double new_origin_x, double new_origin_y)
bool GetMarkingObservations(std::vector< observation::MeasurementReading > &marking_observations) const
void updateWithMax(costmap_2d::Costmap2D &master_grid, int min_i, int min_j, int max_i, int max_j)
void transformLaserScanToPointCloud(const std::string &target_frame, const sensor_msgs::LaserScan &scan_in, sensor_msgs::PointCloud &cloud_out, tf::Transformer &tf, double range_cutoff, int channel_options=channel_option::Default)
void touch(double x, double y, double *min_x, double *min_y, double *max_x, double *max_y)
bool AddStaticObservations(const observation::MeasurementReading &obs)
unsigned char * costmap_
bool SaveGridCallback(spatio_temporal_voxel_layer::SaveGrid::Request &req, spatio_temporal_voxel_layer::SaveGrid::Response &resp)
bool BufferEnablerCallback(std_srvs::SetBool::Request &request, std_srvs::SetBool::Response &response, boost::shared_ptr< buffer::MeasurementBuffer > &buffer, boost::shared_ptr< message_filters::SubscriberBase > &subcriber)
bool worldToMap(double wx, double wy, unsigned int &mx, unsigned int &my) const
std::vector< observation::MeasurementReading > _static_observations
unsigned int getIndex(unsigned int mx, unsigned int my) const
void transformFootprint(double x, double y, double theta, const std::vector< geometry_msgs::Point > &footprint_spec, std::vector< geometry_msgs::Point > &oriented_footprint)
virtual void updateBounds(double robot_x, double robot_y, double robot_yaw, double *min_x, double *min_y, double *max_x, double *max_y)
void DynamicReconfigureCallback(dynamicReconfigureType &config, uint32_t level)
void LaserScanCallback(const sensor_msgs::LaserScanConstPtr &message, const boost::shared_ptr< buffer::MeasurementBuffer > &buffer)


spatio_temporal_voxel_layer
Author(s):
autogenerated on Sat Dec 21 2019 04:06:19