15 #include "nav2_util/path_utils.hpp"
21 #include "nav2_util/geometry_utils.hpp"
25 PathSearchResult distance_from_path(
26 const nav_msgs::msg::Path & path,
27 const geometry_msgs::msg::Pose & robot_pose,
28 const size_t start_index,
29 const double search_window_length)
31 PathSearchResult result;
32 result.closest_segment_index = start_index;
33 result.distance = std::numeric_limits<double>::max();
35 if (path.poses.empty()) {
39 if (path.poses.size() == 1) {
40 result.distance = nav2_util::geometry_utils::euclidean_distance(
41 robot_pose, path.poses.front().pose);
42 result.closest_segment_index = 0;
46 if (start_index >= path.poses.size()) {
47 throw std::runtime_error(
48 "Invalid operation: requested start index (" + std::to_string(start_index) +
49 ") is greater than or equal to path size (" + std::to_string(path.poses.size()) +
50 "). Application is not properly managing state.");
53 double distance_traversed = 0.0;
54 for (
size_t i = start_index; i < path.poses.size() - 1; ++i) {
55 if (distance_traversed > search_window_length) {
59 const double current_distance = geometry_utils::distance_to_path_segment(
62 path.poses[i + 1].pose);
64 if (current_distance < result.distance) {
65 result.distance = current_distance;
66 result.closest_segment_index = i;
69 distance_traversed += geometry_utils::euclidean_distance(
74 const auto & segment_start = path.poses[result.closest_segment_index];
75 const auto & segment_end = path.poses[result.closest_segment_index + 1];
78 const double cross_product = geometry_utils::cross_product_2d(
79 robot_pose.position, segment_start.pose, segment_end.pose);
80 result.distance *= (cross_product >= 0.0 ? 1.0 : -1.0);