Skip to content

Commit b899454

Browse files
committed
created path_utils
Signed-off-by: silanus23 <[email protected]>
1 parent 78c0c32 commit b899454

File tree

3 files changed

+183
-0
lines changed

3 files changed

+183
-0
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) 2025 Berkan Tali
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef NAV2_UTIL__PATH_UTILS_HPP_
16+
#define NAV2_UTIL__PATH_UTILS_HPP_
17+
18+
#include <algorithm>
19+
#include <cmath>
20+
#include <limits>
21+
22+
#include "geometry_msgs/msg/pose.hpp"
23+
#include "geometry_msgs/msg/pose_stamped.hpp"
24+
#include "geometry_msgs/msg/point.hpp"
25+
#include "geometry_msgs/msg/quaternion.hpp"
26+
#include "nav_msgs/msg/path.hpp"
27+
#include "nav2_msgs/msg/waypoint_status.hpp"
28+
#include "nav2_util/geometry_utils.hpp"
29+
#include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
30+
31+
namespace nav2_util
32+
{
33+
34+
struct PathSearchResult
35+
{
36+
double distance;
37+
size_t closest_segment_index;
38+
};
39+
40+
PathSearchResult distanceFromPath(
41+
const nav_msgs::msg::Path & path,
42+
const geometry_msgs::msg::PoseStamped & robot_pose);
43+
44+
PathSearchResult distanceFromPath(
45+
const nav_msgs::msg::Path & path,
46+
const geometry_msgs::msg::PoseStamped & robot_pose,
47+
const size_t start_index,
48+
const double search_window_length);
49+
50+
} // namespace nav2_util
51+
52+
#endif // NAV2_UTIL__PATH_UTILS_HPP_

nav2_util/src/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ add_library(${library_name} SHARED
55
robot_utils.cpp
66
odometry_utils.cpp
77
array_parser.cpp
8+
path_utils.cpp
89
)
910
target_include_directories(${library_name}
1011
PUBLIC
@@ -16,6 +17,7 @@ target_link_libraries(${library_name} PUBLIC
1617
${lifecycle_msgs_TARGETS}
1718
${nav2_msgs_TARGETS}
1819
${nav_msgs_TARGETS}
20+
${nav_2d_msgs_TARGETS}
1921
${rcl_interfaces_TARGETS}
2022
rclcpp::rclcpp
2123
rclcpp_action::rclcpp_action

nav2_util/src/path_utils.cpp

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright (c) 2025 Berkan Tali
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "nav2_util/path_utils.hpp"
16+
17+
#include <limits>
18+
#include <cmath>
19+
20+
#include "nav2_util/geometry_utils.hpp"
21+
22+
namespace nav2_util
23+
{
24+
PathSearchResult distanceFromPath(
25+
const nav_msgs::msg::Path & path,
26+
const geometry_msgs::msg::PoseStamped & robot_pose)
27+
{
28+
PathSearchResult result;
29+
result.closest_segment_index = 0;
30+
result.distance = std::numeric_limits<double>::infinity();
31+
32+
if (path.poses.empty()) {
33+
result.distance = std::numeric_limits<double>::infinity();
34+
return result;
35+
}
36+
37+
if (path.poses.size() == 1) {
38+
result.distance = nav2_util::geometry_utils::distanceToPoint(robot_pose, path.poses.front());
39+
result.closest_segment_index = 0;
40+
return result;
41+
}
42+
43+
double min_distance = std::numeric_limits<double>::max();
44+
size_t closest_segment = 0;
45+
46+
for (size_t i = 0; i < path.poses.size() - 1; ++i) {
47+
const double current_distance = nav2_util::geometry_utils::distanceToSegment(
48+
robot_pose,
49+
path.poses[i],
50+
path.poses[i + 1]);
51+
52+
if (current_distance < min_distance) {
53+
min_distance = current_distance;
54+
closest_segment = i; // 🔥 Track closest segment in global search too
55+
}
56+
}
57+
58+
result.distance = min_distance;
59+
result.closest_segment_index = closest_segment;
60+
return result;
61+
}
62+
63+
PathSearchResult distanceFromPath(
64+
const nav_msgs::msg::Path & path,
65+
const geometry_msgs::msg::PoseStamped & robot_pose,
66+
const size_t start_index,
67+
const double search_window_length)
68+
{
69+
PathSearchResult result;
70+
result.closest_segment_index = start_index;
71+
result.distance = std::numeric_limits<double>::infinity();
72+
73+
if (path.poses.empty()) {
74+
result.distance = std::numeric_limits<double>::infinity();
75+
return result;
76+
}
77+
78+
if (path.poses.size() == 1) {
79+
result.distance = nav2_util::geometry_utils::distanceToPoint(robot_pose, path.poses.front());
80+
result.closest_segment_index = 0;
81+
return result;
82+
}
83+
84+
if (start_index >= path.poses.size()) {
85+
result.distance = std::numeric_limits<double>::infinity();
86+
return result;
87+
}
88+
89+
if (start_index == path.poses.size() - 1) {
90+
result.distance = nav2_util::geometry_utils::distanceToPoint(robot_pose, path.poses.back());
91+
result.closest_segment_index = start_index;
92+
return result;
93+
}
94+
95+
if (search_window_length <= 0.0) {
96+
result.distance = nav2_util::geometry_utils::distanceToPoint(robot_pose,
97+
path.poses[start_index]);
98+
result.closest_segment_index = start_index;
99+
return result;
100+
}
101+
102+
double min_distance = std::numeric_limits<double>::max();
103+
size_t closest_segment = start_index;
104+
size_t segments_checked = 0;
105+
const size_t max_segments = static_cast<size_t>(search_window_length);
106+
107+
for (size_t i = start_index; i < path.poses.size() - 1; ++i) {
108+
const double current_segment_dist = nav2_util::geometry_utils::distanceToSegment(
109+
robot_pose,
110+
path.poses[i],
111+
path.poses[i + 1]);
112+
113+
if (current_segment_dist < min_distance) {
114+
min_distance = current_segment_dist;
115+
closest_segment = i;
116+
}
117+
118+
segments_checked++;
119+
if (segments_checked >= max_segments) {
120+
break;
121+
}
122+
}
123+
124+
result.closest_segment_index = closest_segment;
125+
result.distance = min_distance;
126+
return result;
127+
}
128+
129+
} // namespace nav2_util

0 commit comments

Comments
 (0)