@@ -78,7 +78,7 @@ void SpatioTemporalVoxelLayer::onInitialize(void)
7878 RCLCPP_INFO (
7979 logger_, " %s's global frame is %s." ,
8080 getName ().c_str (), _global_frame.c_str ());
81-
81+
8282 bool track_unknown_space;
8383 double transform_tolerance, map_save_time;
8484 int decay_model_int;
@@ -108,6 +108,12 @@ void SpatioTemporalVoxelLayer::onInitialize(void)
108108 // clear under robot footprint
109109 declareParameter (" update_footprint_enabled" , rclcpp::ParameterValue (true ));
110110 node->get_parameter (name_ + " .update_footprint_enabled" , _update_footprint_enabled);
111+ // use 3d transform for clearing footprint
112+ declareParameter (" footprint_projection_enabled" , rclcpp::ParameterValue (false ));
113+ node->get_parameter (name_ + " .footprint_projection_enabled" , _footprint_projection_enabled);
114+ // footprint frame ( used only with footprint projection enabled )
115+ declareParameter (" footprint_frame" , rclcpp::ParameterValue (std::string (" " )));
116+ node->get_parameter (name_ + " .footprint_frame" , _footprint_frame);
111117 // keep tabs on unknown space
112118 declareParameter (
113119 " track_unknown_space" ,
@@ -543,17 +549,43 @@ bool SpatioTemporalVoxelLayer::updateFootprint(
543549 double * min_y, double * max_x, double * max_y)
544550/* ****************************************************************************/
545551{
546- // updates layer costmap to include footprint for clearing in voxel grid
552+ // Updates layer costmap to include footprint for clearing in voxel grid
547553 if (!_update_footprint_enabled) {
548554 return false ;
549555 }
550- nav2_costmap_2d::transformFootprint (
551- robot_x, robot_y, robot_yaw,
552- getFootprint (), _transformed_footprint);
553- for (unsigned int i = 0 ; i < _transformed_footprint.size (); i++) {
554- touch (
555- _transformed_footprint[i].x , _transformed_footprint[i].y ,
556- min_x, min_y, max_x, max_y);
556+
557+ if (!_footprint_projection_enabled) {
558+ // Simple 2D transformation
559+ nav2_costmap_2d::transformFootprint (
560+ robot_x, robot_y, robot_yaw,
561+ getFootprint (), _transformed_footprint);
562+ for (unsigned int i = 0 ; i < _transformed_footprint.size (); i++) {
563+ touch (
564+ _transformed_footprint[i].x , _transformed_footprint[i].y ,
565+ min_x, min_y, max_x, max_y);
566+ }
567+ } else {
568+ // Using tf2 for 3d rotation to provide accurate projection of the footprint
569+ try {
570+ geometry_msgs::msg::TransformStamped tf_footprint_stamped =
571+ tf_->lookupTransform (
572+ _global_frame, _footprint_frame,
573+ rclcpp::Time (0 ));
574+
575+ _transformed_footprint = getFootprint ();
576+ for (unsigned int i = 0 ; i < _transformed_footprint.size (); i++) {
577+ tf2::doTransform (_transformed_footprint[i], _transformed_footprint[i], tf_footprint_stamped);
578+ touch (
579+ _transformed_footprint[i].x , _transformed_footprint[i].y ,
580+ min_x, min_y, max_x, max_y);
581+ }
582+
583+ } catch (tf2::TransformException &ex) {
584+ RCLCPP_WARN (
585+ rclcpp::get_logger (" SpatioTemporalVoxelLayer" ),
586+ " Could not perform a transform for footprint projection: %s" , ex.what ());
587+ return false ;
588+ }
557589 }
558590
559591 return true ;
0 commit comments