66 ROS_INFO(
"%s being initialized as SpatioTemporalVoxelLayer!", \
73 ROS_INFO(
"%s's global frame is %s.", \
76 bool track_unknown_space;
77 double transform_tolerance, map_save_time;
78 std::string topics_string;
81 nh.param(
"observation_sources", topics_string, std::string(
""));
83 nh.param(
"transform_tolerance", transform_tolerance, 0.2);
98 nh.param(
"track_unknown_space", track_unknown_space, \
100 nh.param(
"decay_model", decay_model_int, 0);
107 nh.param(
"map_save_duration", map_save_time, 60.);
108 ROS_INFO(
"%s loaded parameters from parameter server.",
getName().c_str());
116 if (track_unknown_space)
125 _voxel_pub = nh.advertise<sensor_msgs::PointCloud2>(
"voxel_grid", 1);
126 _grid_saver = nh.advertiseService(
"spatiotemporal_voxel_grid/save_grid", \
140 std::stringstream ss(topics_string);
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;
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);
164 source_node.
param(
"min_z", min_z, 0.);
166 source_node.
param(
"max_z", max_z, 10.);
168 source_node.
param(
"vertical_fov_angle", vFOV, 0.7);
170 source_node.
param(
"vertical_fov_padding", vFOVPadding, 0.0);
172 source_node.
param(
"horizontal_fov_angle", hFOV, 1.04);
174 source_node.
param(
"decay_acceleration", decay_acceleration, 0.);
176 source_node.
param(
"voxel_filter", voxel_filter,
false);
178 source_node.
param(
"clear_after_reading", clear_after_reading,
false);
180 source_node.
param(
"enabled", enabled,
true);
184 source_node.
param(
"model_type", model_type_int, 0);
187 if (!sensor_frame.empty())
189 sensor_frame =
tf::resolve(tf_prefix, sensor_frame);
192 if (!(data_type ==
"PointCloud2" || data_type ==
"LaserScan"))
194 throw std::runtime_error( \
195 "Only topics that use pointclouds or laser scans are supported.");
198 std::string obstacle_range_param_name;
199 double obstacle_range = 3.0;
200 if (source_node.
searchParam(
"obstacle_range", obstacle_range_param_name))
202 source_node.
getParam(obstacle_range_param_name, obstacle_range);
209 expected_update_rate, min_obstacle_height, max_obstacle_height, \
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)));
222 if (clearing ==
true)
228 if (data_type ==
"LaserScan")
241 filter->registerCallback(
245 filter->registerCallback(
256 else if (data_type ==
"PointCloud2")
266 filter->registerCallback(
271 boost::function < bool(std_srvs::SetBool::Request&, \
272 std_srvs::SetBool::Response&) > serv_callback;
278 std::string topic = source +
"/toggle_enabled";
279 server = nh.advertiseService(topic, serv_callback);
286 if (sensor_frame !=
"")
288 std::vector<std::string> target_frames;
289 target_frames.reserve(2);
291 target_frames.push_back(sensor_frame);
297 dynamic_reconfigure::Server<dynamicReconfigureType>::CallbackType
f;
308 const sensor_msgs::LaserScanConstPtr& message, \
313 sensor_msgs::PointCloud2 cloud;
314 cloud.header = message->header;
318 message->header.frame_id, *message, cloud, *
tf_);
320 ROS_WARN(
"TF returned a transform exception to frame %s: %s", \
326 buffer->BufferROSCloud(cloud);
332 const sensor_msgs::LaserScanConstPtr& raw_message, \
338 sensor_msgs::LaserScan message = *raw_message;
339 for (
size_t i = 0; i < message.ranges.size(); i++)
341 float range = message.ranges[i];
342 if (!std::isfinite(range) && range > 0)
344 message.ranges[i] = message.range_max - epsilon;
347 sensor_msgs::PointCloud2 cloud;
348 cloud.header = message.header;
351 message.header.frame_id, message, cloud, *
tf_);
353 ROS_WARN(
"TF returned a transform exception to frame %s: %s", \
359 buffer->BufferROSCloud(cloud);
365 const sensor_msgs::PointCloud2ConstPtr& message, \
371 buffer->BufferROSCloud(*message);
377 std_srvs::SetBool::Request& request, \
378 std_srvs::SetBool::Response& response, \
384 if (buffer->IsEnabled() != request.data)
386 buffer->SetEnabled(request.data);
389 subcriber->subscribe();
390 buffer->ResetLastUpdatedTime();
391 response.message =
"Enabling sensor";
395 subcriber->unsubscribe();
396 response.message =
"Disabling sensor";
401 response.message =
"Sensor already in the required state doing nothing";
404 response.success =
true;
405 return response.success;
411 std::vector<observation::MeasurementReading>& marking_observations)
const 424 marking_observations.insert(marking_observations.end(),
\ 432 std::vector<observation::MeasurementReading>& clearing_observations)
const 475 double robot_yaw,
double* min_x,\
476 double* min_y,
double* max_x, \
490 min_x, min_y, max_x, max_y);
504 (*sub_it)->subscribe();
510 (*buf_it)->ResetLastUpdatedTime();
526 (*sub_it)->unsubscribe();
537 Costmap2D::resetMaps();
543 (*it)->ResetLastUpdatedTime();
559 ROS_WARN(
"Could not add static observations to voxel layer");
569 ROS_INFO(
"%s: Removing static observations to map.",
getName().c_str());
575 ROS_WARN(
"Couldn't remove static observations from %s.", \
583 SpatioTemporalVoxelLayerConfig& config, uint32_t level)
587 bool update_grid(
false);
588 auto updateFlagIfChanged = [&update_grid](
auto& own,
const auto& reference)
590 if (static_cast<float>(std::abs(own - reference)) >= FLT_EPSILON)
600 updateFlagIfChanged(
_voxel_size, config.voxel_size);
603 updateFlagIfChanged(decay_model_int, config.decay_model);
638 CostmapLayer::matchSize();
644 int min_i,
int min_j,
int max_i,
int max_j)
672 double* max_x,
double* max_y)
676 Costmap2D::resetMaps();
678 std::unordered_map<volume_grid::occupany_cell, uint>::iterator it;
684 worldToMap(it->first.x, it->first.y, map_x, map_y))
687 touch(it->first.x, it->first.y, min_x, min_y, max_x, max_y);
694 double robot_x,
double robot_y,
double robot_yaw, \
695 double* min_x,
double* min_y,
double* max_x,
double* max_y)
718 std::vector<observation::MeasurementReading> marking_observations, \
719 clearing_observations;
735 char time_buffer[100];
737 timeinfo = localtime (&rawtime);
738 strftime(time_buffer, 100,
"%F-%r", timeinfo);
740 spatio_temporal_voxel_layer::SaveGrid srv;
741 srv.request.file_name.data = time_buffer;
754 pcl::PointCloud<pcl::PointXYZ>::Ptr pc(
new pcl::PointCloud<pcl::PointXYZ>);
756 sensor_msgs::PointCloud2 pc2;
764 updateFootprint(robot_x, robot_y, robot_yaw, min_x, min_y, max_x, max_y);
770 spatio_temporal_voxel_layer::SaveGrid::Request& req, \
771 spatio_temporal_voxel_layer::SaveGrid::Response& resp)
775 double map_size_bytes;
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;
787 ROS_WARN(
"SpatioTemporalVoxelGrid: Failed to save grid.");
volume_grid::GlobalDecayModel _decay_model
void projectLaser(const sensor_msgs::LaserScan &scan_in, sensor_msgs::PointCloud &cloud_out, double range_cutoff=-1.0, int channel_options=channel_option::Default)
virtual void onInitialize(void)
LayeredCostmap * layered_costmap_
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< geometry_msgs::Point > _transformed_footprint
std::vector< boost::shared_ptr< buffer::MeasurementBuffer > >::iterator observation_buffers_iter
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 _update_footprint_enabled
bool updateFootprint(double robot_x, double robot_y, double robot_yaw, double *min_x, double *min_y, double *max_x, double *max_y)
bool RemoveStaticObservations(void)
std::string _global_frame
double getSizeInMetersX() const
virtual void updateCosts(costmap_2d::Costmap2D &master_grid, int min_i, int min_j, int max_i, int max_j)
virtual void activate(void)
TFSIMD_FORCE_INLINE const tfScalar & y() const
PLUGINLIB_EXPORT_CLASS(spatio_temporal_voxel_layer::SpatioTemporalVoxelLayer, costmap_2d::Layer)
static const unsigned char FREE_SPACE
double getSizeInMetersY() const
void useExtraBounds(double *min_x, double *min_y, double *max_x, double *max_y)
ros::ServiceServer _grid_saver
ros::Publisher _voxel_pub
std::string getName() const
dynamic_reconfigure::Server< dynamicReconfigureType > dynamicReconfigureServerType
virtual void deactivate(void)
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 ObservationsResetAfterReading() const
void ClearFrustums(const std::vector< observation::MeasurementReading > &clearing_observations)
std::vector< boost::shared_ptr< buffer::MeasurementBuffer > > _marking_buffers
bool searchParam(const std::string &key, std::string &result) const
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
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)
ros::Duration _map_save_duration
ros::Time _last_map_save_time
virtual ~SpatioTemporalVoxelLayer(void)
unsigned char default_value_
boost::recursive_mutex _voxel_grid_lock
volume_grid::SpatioTemporalVoxelGrid * _voxel_grid
static const unsigned char LETHAL_OBSTACLE
virtual void matchSize(void)
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)
dynamicReconfigureServerType * _dynamic_reconfigure_server
virtual void updateOrigin(double new_origin_x, double new_origin_y)
bool GetMarkingObservations(std::vector< observation::MeasurementReading > &marking_observations) const
laser_geometry::LaserProjection _laser_projector
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)
SpatioTemporalVoxelLayer(void)
std::vector< ros::ServiceServer > _buffer_enabler_servers
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)