@@ -31,9 +31,10 @@ void PathAlignCritic::initialize()
3131 getParam (threshold_to_consider_, " threshold_to_consider" , 0 .5f );
3232 getParam (use_path_orientations_, " use_path_orientations" , false );
3333 getParam (use_geometric_alignment_, " use_geometric_alignment" , false );
34- getParam (search_window_, " search_window" , 0.5 );
3534 getParam (score_arc_length_, " score_arc_length" , true );
36- getParam (lookahead_distance_, " lookahead_distance" , 1 .0f );
35+ getParam (search_window_, " search_window" , 0.3 );
36+ getParam (lookahead_distance_, " lookahead_distance" , 0 .7f );
37+ getParam (early_termination_distance_, " early_termination_distance" , 0 .025f );
3738
3839 if (!score_arc_length_ && !use_geometric_alignment_) {
3940 RCLCPP_WARN (logger_,
@@ -341,29 +342,44 @@ float PathAlignCritic::computeMinDistanceToPath(float px, float py, Eigen::Index
341342
342343 closest_seg_idx = std::clamp (closest_seg_idx, Eigen::Index (0 ), num_segments - 1 );
343344
344- // Limit search to window around hint (exploits path locality)
345+ float min_dist_sq = distSqToSegment (px, py, closest_seg_idx);
346+ Eigen::Index best_seg = closest_seg_idx;
347+
348+ // Early termination if already very close
349+ const float good_enough_dist_sq = early_termination_distance_ * early_termination_distance_;
350+ if (min_dist_sq < good_enough_dist_sq) {
351+ return std::sqrt (min_dist_sq);
352+ }
353+
354+ // Adaptive search window - smaller if hint is good
355+ const float adaptive_window = (min_dist_sq < 0 .01f ) ? search_window_ * 0 .5f : search_window_;
356+
345357 const float hint_distance = cumulative_distances_ (closest_seg_idx);
346- const float start_distance = std::max (0 .0f , hint_distance - static_cast < float >(search_window_) );
347- const float end_distance = hint_distance + static_cast < float >(search_window_) ;
358+ const float start_distance = std::max (0 .0f , hint_distance - adaptive_window );
359+ const float end_distance = hint_distance + adaptive_window ;
348360
349361 const Eigen::Index start_idx = static_cast <Eigen::Index>(
350362 utils::findClosestPathPtBinary (
351363 cumulative_distances_.data (),
352364 path_size_cache_,
353365 start_distance));
354366
355- float min_dist_sq = std::numeric_limits<float >::max ();
356- Eigen::Index best_seg = closest_seg_idx;
357-
358367 for (Eigen::Index seg_idx = start_idx; seg_idx < num_segments; ++seg_idx) {
359368 if (cumulative_distances_ (seg_idx) > end_distance) {break ;}
360369 if (segment_len_sq_ (seg_idx) < 1e-6f ) {continue ;}
370+ if (seg_idx == closest_seg_idx) {continue ;} // Already checked
361371
362372 const float dist_sq = distSqToSegment (px, py, seg_idx);
363373
364374 if (dist_sq < min_dist_sq) {
365375 min_dist_sq = dist_sq;
366376 best_seg = seg_idx;
377+
378+ // Early exit if found very close match
379+ if (min_dist_sq < good_enough_dist_sq) {
380+ closest_seg_idx = best_seg;
381+ return std::sqrt (min_dist_sq);
382+ }
367383 }
368384 }
369385
0 commit comments