Skip to content

Commit 2829d7c

Browse files
committed
fixed reviews
Signed-off-by: silanus23 <[email protected]>
1 parent 61067ba commit 2829d7c

File tree

4 files changed

+77
-137
lines changed

4 files changed

+77
-137
lines changed

nav2_util/include/nav2_util/geometry_utils.hpp

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -189,43 +189,32 @@ inline int find_next_matching_goal_in_waypoint_statuses(
189189
}
190190

191191
/**
192-
* @brief Find the distance to a point
193-
* @param global_pose Robot's current or planned position
194-
* @param target target point
195-
* @return int
192+
* @brief Find the shortest distance from a point to a line segment
193+
*
194+
* Uses the closed-form solution for the distance from a point to a segment in 2D.
195+
* See: https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
196+
*
197+
* @param point The point to measure from
198+
* @param start The start pose of the segment
199+
* @param end The end pose of the segment
200+
* @return double The shortest distance
196201
*/
197-
inline double distanceToPoint(
198-
const geometry_msgs::msg::PoseStamped & point1,
199-
const geometry_msgs::msg::PoseStamped & point2)
202+
inline double distance_to_segment(
203+
const geometry_msgs::msg::Point & point,
204+
const geometry_msgs::msg::Pose & start,
205+
const geometry_msgs::msg::Pose & end)
200206
{
201-
const double dx = point1.pose.position.x - point2.pose.position.x;
202-
const double dy = point1.pose.position.y - point2.pose.position.y;
203-
return std::hypot(dx, dy);
204-
}
205-
206-
/**
207-
* @brief Find the shortest distance to a vector
208-
* @param global_pose Robot's current or planned position
209-
* @param start Starting point of target vector
210-
* @param finish End point of target vector
211-
* @return int
212-
*/
213-
inline double distanceToSegment(
214-
const geometry_msgs::msg::PoseStamped & point,
215-
const geometry_msgs::msg::PoseStamped & start,
216-
const geometry_msgs::msg::PoseStamped & end)
217-
{
218-
const auto & p = point.pose.position;
219-
const auto & a = start.pose.position;
220-
const auto & b = end.pose.position;
207+
const auto & p = point;
208+
const auto & a = start.position;
209+
const auto & b = end.position;
221210

222211
const double dx_seg = b.x - a.x;
223212
const double dy_seg = b.y - a.y;
224213

225214
const double seg_len_sq = (dx_seg * dx_seg) + (dy_seg * dy_seg);
226215

227216
if (seg_len_sq <= 1e-9) {
228-
return distanceToPoint(point, start);
217+
return euclidean_distance(point, a);
229218
}
230219

231220
const double dot = ((p.x - a.x) * dx_seg) + ((p.y - a.y) * dy_seg);

nav2_util/include/nav2_util/path_utils.hpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,27 @@
3131
namespace nav2_util
3232
{
3333

34+
/**
35+
* @brief Result of searching for the closest segment on a path.
36+
*/
3437
struct PathSearchResult
3538
{
39+
/**
40+
* @brief The minimum distance from the robot to the path.
41+
*/
3642
double distance;
43+
44+
/**
45+
* @brief The index of the closest path segment.
46+
*/
3747
size_t closest_segment_index;
3848
};
3949

40-
PathSearchResult distanceFromPath(
41-
const nav_msgs::msg::Path & path,
42-
const geometry_msgs::msg::PoseStamped & robot_pose);
43-
44-
PathSearchResult distanceFromPath(
50+
PathSearchResult distance_from_path(
4551
const nav_msgs::msg::Path & path,
4652
const geometry_msgs::msg::PoseStamped & robot_pose,
47-
const size_t start_index,
48-
const double search_window_length);
53+
const size_t start_index = 0,
54+
const double search_window_length = std::numeric_limits<double>::max());
4955

5056
} // namespace nav2_util
5157

nav2_util/src/path_utils.cpp

Lines changed: 28 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -13,116 +13,62 @@
1313
// limitations under the License.
1414

1515
#include "nav2_util/path_utils.hpp"
16-
1716
#include <limits>
1817
#include <cmath>
19-
2018
#include "nav2_util/geometry_utils.hpp"
21-
2219
namespace nav2_util
2320
{
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-
}
5721

58-
result.distance = min_distance;
59-
result.closest_segment_index = closest_segment;
60-
return result;
61-
}
62-
63-
PathSearchResult distanceFromPath(
22+
PathSearchResult distance_from_path(
6423
const nav_msgs::msg::Path & path,
6524
const geometry_msgs::msg::PoseStamped & robot_pose,
6625
const size_t start_index,
6726
const double search_window_length)
6827
{
6928
PathSearchResult result;
7029
result.closest_segment_index = start_index;
71-
result.distance = std::numeric_limits<double>::infinity();
30+
result.distance = std::numeric_limits<double>::max();
7231

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());
32+
if (path.poses.size() < 2) {
33+
if (path.poses.empty()) {
34+
return result;
35+
}
36+
result.distance = nav2_util::geometry_utils::euclidean_distance(
37+
robot_pose.pose, path.poses.front().pose);
8038
result.closest_segment_index = 0;
8139
return result;
8240
}
8341

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;
42+
if (start_index >= path.poses.size() - 1) {
43+
result.distance = nav2_util::geometry_utils::euclidean_distance(
44+
robot_pose.pose,
45+
path.poses.back().pose);
46+
result.closest_segment_index = path.poses.size() - 1;
9247
return result;
9348
}
9449

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);
50+
double distance_traversed = 0.0;
10651

10752
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;
53+
if (distance_traversed > search_window_length) {
54+
break;
11655
}
11756

118-
segments_checked++;
119-
if (segments_checked >= max_segments) {
120-
break;
57+
const double current_distance = geometry_utils::distance_to_segment(
58+
robot_pose.pose.position,
59+
path.poses[i].pose,
60+
path.poses[i + 1].pose);
61+
62+
if (current_distance < result.distance) {
63+
result.distance = current_distance;
64+
result.closest_segment_index = i;
12165
}
66+
67+
distance_traversed += geometry_utils::euclidean_distance(
68+
path.poses[i].pose,
69+
path.poses[i + 1].pose);
12270
}
12371

124-
result.closest_segment_index = closest_segment;
125-
result.distance = min_distance;
12672
return result;
12773
}
12874

nav2_util/test/test_path_utils.cpp

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "gtest/gtest.h"
2020
#include "geometry_msgs/msg/pose_stamped.hpp"
21+
#include "geometry_msgs/msg/pose.hpp"
2122
#include "nav_msgs/msg/path.hpp"
2223
#include "nav2_util/path_utils.hpp"
2324

@@ -168,20 +169,20 @@ TEST(PathUtilsTest, EmptyAndSinglePointPaths)
168169
auto robot_pose = createPose(5.0, 5.0);
169170
nav_msgs::msg::Path empty_path;
170171

171-
auto result = nav2_util::distanceFromPath(empty_path, robot_pose);
172-
EXPECT_EQ(result.distance, std::numeric_limits<double>::infinity());
172+
auto result = nav2_util::distance_from_path(empty_path, robot_pose);
173+
EXPECT_EQ(result.distance, std::numeric_limits<double>::max());
173174

174175
nav_msgs::msg::Path single_point_path;
175176
single_point_path.poses.push_back(createPose(0.0, 0.0));
176-
result = nav2_util::distanceFromPath(single_point_path, robot_pose);
177+
result = nav2_util::distance_from_path(single_point_path, robot_pose);
177178
EXPECT_NEAR(result.distance, 7.071, 0.01);
178179
}
179180

180181
TEST_F(CuttingCornerTest, TrajectoryCutsCorner)
181182
{
182183
for (size_t i = 0; i < robot_trajectory.size(); ++i) {
183184
const auto & robot_pose = robot_trajectory[i];
184-
auto result = nav2_util::distanceFromPath(target_path, robot_pose);
185+
auto result = nav2_util::distance_from_path(target_path, robot_pose);
185186
EXPECT_NEAR(result.distance, expected_distances[i], 0.1);
186187
}
187188
}
@@ -191,15 +192,15 @@ TEST_F(RetracingPathTest, TrajectoryFollowsRetracingPath)
191192
const double expected_distance = 0.5;
192193

193194
for (const auto & robot_pose : robot_trajectory) {
194-
auto result = nav2_util::distanceFromPath(target_path, robot_pose);
195+
auto result = nav2_util::distance_from_path(target_path, robot_pose);
195196
EXPECT_NEAR(result.distance, expected_distance, 1e-6);
196197
}
197198
}
198199

199200
TEST_F(CloverleafPathTest, TrajectoryFollowsCloverleafLoop)
200201
{
201202
for (const auto & robot_pose : robot_trajectory) {
202-
auto result = nav2_util::distanceFromPath(target_path, robot_pose);
203+
auto result = nav2_util::distance_from_path(target_path, robot_pose);
203204
EXPECT_LT(result.distance, 0.25);
204205
}
205206
}
@@ -209,23 +210,23 @@ TEST_F(RetracingCircleTest, TrajectoryFollowsRetracingCircle)
209210
const double expected_distance = 0.2;
210211

211212
for (const auto & robot_pose : robot_trajectory) {
212-
auto result = nav2_util::distanceFromPath(target_path, robot_pose);
213+
auto result = nav2_util::distance_from_path(target_path, robot_pose);
213214
EXPECT_NEAR(result.distance, expected_distance, 0.01);
214215
}
215216
}
216217

217218
TEST_F(ZigZagPathTest, TrajectoryFollowsZigZagPath)
218219
{
219220
for (const auto & robot_pose : robot_trajectory) {
220-
auto result = nav2_util::distanceFromPath(target_path, robot_pose);
221+
auto result = nav2_util::distance_from_path(target_path, robot_pose);
221222
EXPECT_LT(result.distance, 1.0);
222223
}
223224
}
224225

225226
TEST_F(HairpinTurnTest, TrajectoryFollowsHairpinTurn)
226227
{
227228
for (const auto & robot_pose : robot_trajectory) {
228-
auto result = nav2_util::distanceFromPath(target_path, robot_pose);
229+
auto result = nav2_util::distance_from_path(target_path, robot_pose);
229230
EXPECT_LT(result.distance, 1.5);
230231
}
231232
}
@@ -239,7 +240,8 @@ TEST_F(CuttingCornerWindowedTest, WindowedSearch)
239240

240241
for (size_t i = 0; i < robot_trajectory.size(); ++i) {
241242
const auto & robot_pose = robot_trajectory[i];
242-
auto result = nav2_util::distanceFromPath(target_path, robot_pose, start_index, search_window);
243+
auto result = nav2_util::distance_from_path(target_path, robot_pose, start_index,
244+
search_window);
243245
start_index = result.closest_segment_index;
244246
EXPECT_NEAR(result.distance, expected_distances[i], 0.15);
245247
}
@@ -255,7 +257,8 @@ TEST_F(RetracingPathWindowedTest, WindowedSearch)
255257

256258
for (size_t i = 0; i < robot_trajectory.size(); ++i) {
257259
const auto & robot_pose = robot_trajectory[i];
258-
auto result = nav2_util::distanceFromPath(target_path, robot_pose, start_index, search_window);
260+
auto result = nav2_util::distance_from_path(target_path, robot_pose, start_index,
261+
search_window);
259262
start_index = result.closest_segment_index;
260263
EXPECT_NEAR(result.distance, expected_distance, 1e-6);
261264
}
@@ -270,7 +273,8 @@ TEST_F(ZigZagPathWindowedTest, WindowedSearch)
270273

271274
for (size_t i = 0; i < robot_trajectory.size(); ++i) {
272275
const auto & robot_pose = robot_trajectory[i];
273-
auto result = nav2_util::distanceFromPath(target_path, robot_pose, start_index, search_window);
276+
auto result = nav2_util::distance_from_path(target_path, robot_pose, start_index,
277+
search_window);
274278
start_index = result.closest_segment_index;
275279
EXPECT_LT(result.distance, 1.0);
276280
}
@@ -285,7 +289,8 @@ TEST_F(HairpinTurnWindowedTest, WindowedSearch)
285289

286290
for (size_t i = 0; i < robot_trajectory.size(); ++i) {
287291
const auto & robot_pose = robot_trajectory[i];
288-
auto result = nav2_util::distanceFromPath(target_path, robot_pose, start_index, search_window);
292+
auto result = nav2_util::distance_from_path(target_path, robot_pose, start_index,
293+
search_window);
289294
start_index = result.closest_segment_index;
290295
EXPECT_LT(result.distance, 1.5);
291296
}
@@ -298,12 +303,6 @@ TEST(PathUtilsWindowedTest, EdgeCases)
298303
test_path.poses.push_back(createPose(0.0, 0.0));
299304
test_path.poses.push_back(createPose(10.0, 0.0));
300305

301-
auto result = nav2_util::distanceFromPath(test_path, robot_pose, 1, 5.0);
306+
auto result = nav2_util::distance_from_path(test_path, robot_pose, 1, 5.0);
302307
EXPECT_NEAR(result.distance, 7.071, 0.01);
303-
304-
result = nav2_util::distanceFromPath(test_path, robot_pose, 0, 0.0);
305-
EXPECT_NEAR(result.distance, 7.071, 0.01);
306-
307-
result = nav2_util::distanceFromPath(test_path, robot_pose, 10, 5.0);
308-
EXPECT_EQ(result.distance, std::numeric_limits<double>::infinity());
309308
}

0 commit comments

Comments
 (0)