@@ -51,7 +51,7 @@ void BoundedTrackingErrorLayer::onInitialize()
5151
5252 wall_thickness_ = node->declare_or_get_parameter (name_ + " ." + " wall_thickness" , 1 );
5353
54- int corridor_cost_param = node->declare_or_get_parameter (name_ + " ." + " corridor_cost" , 250 );
54+ int corridor_cost_param = node->declare_or_get_parameter (name_ + " ." + " corridor_cost" , 190 );
5555 corridor_cost_ = static_cast <unsigned char >(std::clamp (corridor_cost_param, 1 , 254 ));
5656
5757 bool enabled_param = node->declare_or_get_parameter (name_ + " ." + " enabled" , true );
@@ -87,12 +87,54 @@ void BoundedTrackingErrorLayer::onInitialize()
8787 nav2::qos::StandardTopicQoS ()
8888 );
8989
90+ goal_sub_ = node->create_subscription <geometry_msgs::msg::PoseStamped>(
91+ " goal_pose" ,
92+ std::bind (&BoundedTrackingErrorLayer::goalCallback, this , std::placeholders::_1),
93+ nav2::qos::StandardTopicQoS ()
94+ );
95+
9096 dyn_params_handler_ = node->add_on_set_parameters_callback (
9197 std::bind (
9298 &BoundedTrackingErrorLayer::dynamicParametersCallback,
9399 this , std::placeholders::_1));
94100}
95101
102+ void BoundedTrackingErrorLayer::goalCallback (const geometry_msgs::msg::PoseStamped::SharedPtr msg)
103+ {
104+ auto node = node_.lock ();
105+ if (!node) {
106+ return ;
107+ }
108+
109+ std::lock_guard<std::mutex> lock (data_mutex_);
110+
111+ // Check if this is a new goal (different position from last goal)
112+ bool is_new_goal = false ;
113+ if (last_goal_.header .frame_id .empty ()) {
114+ is_new_goal = true ;
115+ } else {
116+ double dx = msg->pose .position .x - last_goal_.pose .position .x ;
117+ double dy = msg->pose .position .y - last_goal_.pose .position .y ;
118+ double distance = std::hypot (dx, dy);
119+
120+ if (distance > 0.1 ) {
121+ is_new_goal = true ;
122+ }
123+ }
124+
125+ if (is_new_goal) {
126+ RCLCPP_DEBUG (
127+ node->get_logger (),
128+ " New goal received, clearing corridor" );
129+
130+ // Clear corridor data
131+ last_path_ = nav_msgs::msg::Path ();
132+ last_tracking_feedback_ = nav2_msgs::msg::TrackingFeedback ();
133+ }
134+
135+ last_goal_ = *msg;
136+ }
137+
96138void BoundedTrackingErrorLayer::pathCallback (const nav_msgs::msg::Path::SharedPtr msg)
97139{
98140 auto node = node_.lock ();
@@ -114,6 +156,52 @@ void BoundedTrackingErrorLayer::pathCallback(const nav_msgs::msg::Path::SharedPt
114156 last_path_ = nav_msgs::msg::Path ();
115157 return ;
116158 }
159+
160+ // Check for path discontinuity (replanning detection)
161+ bool path_discontinuity = false ;
162+ if (!last_path_.poses .empty () && msg->poses .size () >= 2 ) {
163+ size_t old_size = last_path_.poses .size ();
164+ size_t new_size = msg->poses .size ();
165+
166+ if (old_size != new_size) {
167+ path_discontinuity = true ;
168+ RCLCPP_DEBUG (
169+ node->get_logger (),
170+ " Path size changed from %zu to %zu, clearing corridor" , old_size, new_size);
171+ } else if (old_size >= 2 ) {
172+ double threshold = corridor_width_ * 0.5 ;
173+
174+ // Compare points if size stays same and points change
175+
176+ size_t old_mid_idx = old_size / 2 ;
177+ size_t new_mid_idx = new_size / 2 ;
178+ double mid_dx = msg->poses [new_mid_idx].pose .position .x -
179+ last_path_.poses [old_mid_idx].pose .position .x ;
180+ double mid_dy = msg->poses [new_mid_idx].pose .position .y -
181+ last_path_.poses [old_mid_idx].pose .position .y ;
182+ double mid_dist = std::hypot (mid_dx, mid_dy);
183+
184+ double end_dx = msg->poses .back ().pose .position .x -
185+ last_path_.poses .back ().pose .position .x ;
186+ double end_dy = msg->poses .back ().pose .position .y -
187+ last_path_.poses .back ().pose .position .y ;
188+ double end_dist = std::hypot (end_dx, end_dy);
189+
190+ if (mid_dist > threshold || end_dist > threshold) {
191+ path_discontinuity = true ;
192+ RCLCPP_DEBUG (
193+ node->get_logger (),
194+ " Path discontinuity detected (mid: %.2fm, end: %.2fm), clearing corridor" ,
195+ mid_dist, end_dist);
196+ }
197+ }
198+ }
199+
200+ if (path_discontinuity) {
201+ // Clear corridor on replanning
202+ last_tracking_feedback_ = nav2_msgs::msg::TrackingFeedback ();
203+ }
204+
117205 last_path_ = *msg;
118206 last_tracking_feedback_ = nav2_msgs::msg::TrackingFeedback ();
119207}
@@ -172,7 +260,6 @@ WallPolygons BoundedTrackingErrorLayer::getWallPolygons(
172260 double outer_half_width = corridor_width_ * 0.5 ;
173261 double inner_half_width = (corridor_width_ - (wall_thickness_ * resolution * 2.0 )) * 0.5 ;
174262
175- // Reserve space for efficiency
176263 size_t estimated_points = (segment.poses .size () / step_size_) + 1 ;
177264 walls.left_outer .reserve (estimated_points);
178265 walls.left_inner .reserve (estimated_points);
@@ -187,7 +274,6 @@ WallPolygons BoundedTrackingErrorLayer::getWallPolygons(
187274 double px = current_pose.pose .position .x ;
188275 double py = current_pose.pose .position .y ;
189276
190- // Only draw corridor if we have enough lookahead distance
191277 if (current_index + step_size_ >= segment.poses .size ()) {
192278 break ;
193279 }
@@ -205,7 +291,6 @@ WallPolygons BoundedTrackingErrorLayer::getWallPolygons(
205291 double perp_x = -dy / norm;
206292 double perp_y = dx / norm;
207293
208- // Calculate all 4 points at this location
209294 walls.left_outer .push_back ({px + perp_x * outer_half_width, py + perp_y * outer_half_width});
210295 walls.left_inner .push_back ({px + perp_x * inner_half_width, py + perp_y * inner_half_width});
211296 walls.right_outer .push_back ({px - perp_x * outer_half_width, py - perp_y * outer_half_width});
@@ -284,7 +369,7 @@ void BoundedTrackingErrorLayer::updateCosts(
284369 transformed_segment.header .frame_id = costmap_frame;
285370 transformed_segment.poses .reserve (segment.poses .size ());
286371
287- // Use longer timeout for first pose to wait for TF, no wait for rest
372+ // Use longer timeout for first pose to wait for TF
288373 for (size_t i = 0 ; i < segment.poses .size (); ++i) {
289374 const auto & pose = segment.poses [i];
290375 geometry_msgs::msg::PoseStamped transformed_pose;
@@ -451,6 +536,7 @@ void BoundedTrackingErrorLayer::deactivate()
451536 std::lock_guard<std::mutex> lock (data_mutex_);
452537 last_path_ = nav_msgs::msg::Path ();
453538 last_tracking_feedback_ = nav2_msgs::msg::TrackingFeedback ();
539+ last_goal_ = geometry_msgs::msg::PoseStamped ();
454540 }
455541
456542 enabled_.store (false );
0 commit comments