-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Route server corner smoothing #5226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
SteveMacenski
merged 48 commits into
ros-navigation:main
from
alexanderjyuen:route_server_corner_smoothing
Jun 12, 2025
Merged
Changes from 11 commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
b2f9d6d
added edge length method
alexanderjyuen d198fa8
Added corner arc class
alexanderjyuen 8cb47e0
replaced double vectors with Coordinates, added methods to return sta…
alexanderjyuen 88b1648
using Coordinates, fixed direction of tangents
alexanderjyuen c4dc85d
added corner arc in header, added logger in protected variable
alexanderjyuen 815d88c
first pass of corner smoothing algorithm
alexanderjyuen 537cf97
reassigning next edge to have a different start, if a corner occurs b…
alexanderjyuen e623d9d
using unique pointer instead of raw pointers for new edges and nodes
alexanderjyuen 66eee22
added smoothing parameter
alexanderjyuen d33bc2d
made angle of interpolation a parameter
alexanderjyuen 6c1b2b6
const for return methods, added flag for smoothing corners
alexanderjyuen 9cac954
moved getEdgeLength() into the Directional Edge struct
alexanderjyuen 2c96ceb
using float instead of double
alexanderjyuen d4bd9dc
smoothing radius is float, couple methods moved to protected
alexanderjyuen 752ff04
removed signed_angle_ as a member variable
alexanderjyuen 690ad2a
removed unnecessary member variables
alexanderjyuen 7dc35f8
removed angle of interpolation and inferring it from path density and…
alexanderjyuen 2626b6a
consolidated corner arc into one header function
alexanderjyuen 5d6d37d
readded newline
alexanderjyuen 4f7bba1
changed corner arc to corner smoothing
alexanderjyuen 4d6b8e0
replaced the use of edges with coordinates to generate smoothing arc,…
alexanderjyuen f0dff73
linting
alexanderjyuen 53f2209
fixing cpplint
alexanderjyuen 5b0b709
linting for headers
alexanderjyuen c827e52
cpplinting
alexanderjyuen d46468f
Update nav2_route/src/path_converter.cpp
SteveMacenski edbe42a
Update nav2_route/src/path_converter.cpp
SteveMacenski 46ca874
Update nav2_route/src/path_converter.cpp
SteveMacenski 68befab
Update nav2_route/src/path_converter.cpp
SteveMacenski e9a1882
Update nav2_route/include/nav2_route/corner_smoothing.hpp
SteveMacenski 9555c93
fixed divide by zeros and accessing empty route.edges
alexanderjyuen b3cf20a
Merge branch 'route_server_corner_smoothing' of github.com:alexanderj…
alexanderjyuen 5a39b87
uncrustify linting
alexanderjyuen 752d1f2
cpp linting
alexanderjyuen b41c896
path converter linting
alexanderjyuen 2024731
changed all doubles to floats
alexanderjyuen ee16acb
added check for edges that are colinear to avoid divide by 0, fixed f…
alexanderjyuen 4e5baaf
linting
alexanderjyuen cc2114a
Update nav2_route/include/nav2_route/corner_smoothing.hpp
SteveMacenski 1ce133e
added doxygen for corner arc class
alexanderjyuen 9dafb46
Merge branch 'route_server_corner_smoothing' of github.com:alexanderj…
alexanderjyuen 1728030
added warning message if corner can't be smoothed
alexanderjyuen 55d54ec
added smooth_corners to the nav2 params file
alexanderjyuen 989d092
added smoothing flag and radius parameter to README.md'
alexanderjyuen 7e3e547
typo in README
alexanderjyuen dfff167
added testing for corner smoothing
alexanderjyuen 0a7fa13
Merge branch 'main' into route_server_corner_smoothing
alexanderjyuen b2903a4
Update nav2_route/include/nav2_route/corner_smoothing.hpp
SteveMacenski File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| // Copyright (c) 2025, Polymath Robotics | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| #ifndef NAV2_ROUTE__CORNER_ARC_HPP_ | ||
| #define NAV2_ROUTE__CORNER_ARC_HPP_ | ||
|
|
||
| #include <vector> | ||
| #include <cmath> | ||
|
|
||
| #include "nav2_route/types.hpp" | ||
| #include "nav2_route/utils.hpp" | ||
|
|
||
| namespace nav2_route | ||
| { | ||
| class CornerArc | ||
| { | ||
| public: | ||
| /** | ||
| * @brief Constructor | ||
| */ | ||
| CornerArc(EdgePtr start_edge, EdgePtr end_edge, double minimum_radius); | ||
|
|
||
| ~CornerArc() = default; | ||
|
|
||
| void interpolateArc(const double & max_angle_resolution, std::vector<geometry_msgs::msg::PoseStamped> & poses); | ||
|
|
||
| double getEdgeLength(const EdgePtr edge); | ||
|
|
||
| double getAngleBetweenEdges(const EdgePtr start_edge, const EdgePtr end_edge); | ||
alexanderjyuen marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| double getSignedAngleBetweenEdges(const EdgePtr start_edge, const EdgePtr end_edge); | ||
|
|
||
| bool isCornerValid() const { return valid_corner_; } | ||
|
|
||
| Coordinates getCornerStart() const { return start_coordinate_; } | ||
|
|
||
| Coordinates getCornerEnd() const { return end_coordinate_; } | ||
|
|
||
| private: | ||
| EdgePtr start_edge_; | ||
| EdgePtr end_edge_; | ||
| double start_edge_length_; | ||
| double end_edge_length_; | ||
| double minimum_radius_; | ||
| double signed_angle_; | ||
| bool valid_corner_{false}; | ||
| Coordinates start_coordinate_; | ||
| Coordinates end_coordinate_; | ||
| Coordinates circle_center_coordinate_; | ||
| }; | ||
|
|
||
| } // namespace nav2_route | ||
|
|
||
| #endif // NAV2_ROUTE__CORNER_ARC_HPP_ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| // Copyright (c) 2025, Polymath Robotics | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| #include "nav2_route/corner_arc.hpp" | ||
| #include <iostream> | ||
|
|
||
| namespace nav2_route | ||
| { | ||
|
|
||
| CornerArc::CornerArc(EdgePtr start_edge, EdgePtr end_edge, double minimum_radius) | ||
| { | ||
| start_edge_ = start_edge; | ||
| end_edge_ = end_edge; | ||
|
|
||
| double angle = getAngleBetweenEdges(start_edge, end_edge); | ||
|
|
||
| double tangent_length = minimum_radius/(std::tan(angle/2)); | ||
|
|
||
| start_edge_length_ = getEdgeLength(start_edge); | ||
| end_edge_length_ = getEdgeLength(end_edge); | ||
|
|
||
| if(tangent_length < start_edge_length_ && tangent_length < end_edge_length_){ | ||
| std::vector<double> start_edge_unit_tangent; | ||
| std::vector<double> end_edge_unit_tangent; | ||
| std::vector<double> unit_bisector; | ||
|
|
||
| start_edge_unit_tangent.push_back((start_edge->start->coords.x -start_edge->end->coords.x)/start_edge_length_); | ||
| start_edge_unit_tangent.push_back((start_edge->start->coords.y -start_edge->end->coords.y)/start_edge_length_); | ||
| end_edge_unit_tangent.push_back((end_edge->end->coords.x - end_edge->start->coords.x)/end_edge_length_); | ||
| end_edge_unit_tangent.push_back((end_edge->end->coords.y - end_edge->start->coords.y)/end_edge_length_); | ||
|
|
||
| double bisector_x = start_edge_unit_tangent[0]+end_edge_unit_tangent[0]; | ||
| double bisector_y = start_edge_unit_tangent[1]+end_edge_unit_tangent[1]; | ||
| double bisector_magnitude = std::sqrt(bisector_x*bisector_x + bisector_y*bisector_y); | ||
|
|
||
| unit_bisector.push_back(bisector_x/bisector_magnitude); | ||
| unit_bisector.push_back(bisector_y/bisector_magnitude); | ||
|
|
||
| start_coordinate_.x = start_edge->end->coords.x + start_edge_unit_tangent[0]*tangent_length; | ||
| start_coordinate_.y = start_edge->end->coords.y + start_edge_unit_tangent[1]*tangent_length; | ||
|
|
||
| end_coordinate_.x = end_edge->start->coords.x + end_edge_unit_tangent[0]*tangent_length; | ||
| end_coordinate_.y = end_edge->start->coords.y + end_edge_unit_tangent[1]*tangent_length; | ||
|
|
||
| double signed_angle = getSignedAngleBetweenEdges(start_edge, end_edge); | ||
|
|
||
| double bisector_length = minimum_radius/std::sin(signed_angle/2); | ||
|
|
||
| circle_center_coordinate_.x = end_edge->start->coords.x + unit_bisector[0]*bisector_length; | ||
| circle_center_coordinate_.y = end_edge->start->coords.y + unit_bisector[1]*bisector_length; | ||
|
|
||
| minimum_radius_ = minimum_radius; | ||
| valid_corner_ = true; | ||
|
|
||
| } | ||
| } | ||
|
|
||
| void CornerArc::interpolateArc(const double & max_angle_resolution, std::vector<geometry_msgs::msg::PoseStamped> & poses) | ||
| { | ||
|
|
||
| std::vector<double> r_start{ start_coordinate_.x-circle_center_coordinate_.x, start_coordinate_.y-circle_center_coordinate_.y }; | ||
| std::vector<double> r_end{ end_coordinate_.x-circle_center_coordinate_.x, end_coordinate_.y-circle_center_coordinate_.y }; | ||
| double cross = r_start[0]*r_end[1] - r_start[1]*r_end[0]; | ||
| double dot = r_start[0]*r_end[0] + r_start[1]*r_end[1]; | ||
| signed_angle_ = std::atan2(cross, dot); | ||
alexanderjyuen marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| int N = std::ceil(std::abs(signed_angle_)/max_angle_resolution); | ||
| double angle_resolution = signed_angle_/N; | ||
|
|
||
| float x, y; | ||
|
|
||
| for(int i = 0; i <= N; i++){ | ||
| double angle = i*angle_resolution; | ||
| x = circle_center_coordinate_.x + (r_start[0]*std::cos(angle) - r_start[1]*std::sin(angle)); | ||
| y = circle_center_coordinate_.y + (r_start[0]*std::sin(angle) + r_start[1]*std::cos(angle)); | ||
| poses.push_back(utils::toMsg(x, y)); | ||
| } | ||
| } | ||
|
|
||
| double CornerArc::getEdgeLength(const EdgePtr edge){ | ||
| const Coordinates & start = edge->start->coords; | ||
| const Coordinates & end = edge->end->coords; | ||
|
|
||
| float dx = end.x - start.x; | ||
| float dy = end.y - start.y; | ||
|
|
||
| return double(sqrt(dx*dx + dy*dy)); | ||
| } | ||
|
|
||
| double CornerArc::getAngleBetweenEdges(const EdgePtr start_edge, const EdgePtr end_edge){ | ||
|
|
||
| double start_dx = start_edge->start->coords.x - start_edge->end->coords.x; | ||
| double start_dy = start_edge->start->coords.y - start_edge->end->coords.y; | ||
|
|
||
| double end_dx = end_edge->end->coords.x - end_edge->start->coords.x; | ||
| double end_dy = end_edge->end->coords.y - end_edge->start->coords.y; | ||
|
|
||
| double angle = acos((start_dx*end_dx + start_dy*end_dy)/(getEdgeLength(start_edge)*getEdgeLength(end_edge))); | ||
|
|
||
| return angle; | ||
| } | ||
|
|
||
| double CornerArc::getSignedAngleBetweenEdges(const EdgePtr start_edge, const EdgePtr end_edge){ | ||
|
|
||
| double start_edge_length = getEdgeLength(start_edge); | ||
| double end_edge_length = getEdgeLength(end_edge); | ||
|
|
||
| double start_dx = (start_edge->start->coords.x - start_edge->end->coords.x)/start_edge_length; | ||
| double start_dy = (start_edge->start->coords.y - start_edge->end->coords.y)/start_edge_length; | ||
|
|
||
| double end_dx = (end_edge->end->coords.x - end_edge->start->coords.x)/end_edge_length; | ||
| double end_dy = (end_edge->end->coords.y - end_edge->start->coords.y)/end_edge_length; | ||
|
|
||
| double dot = start_dx*end_dx + start_dy*end_dy; | ||
| dot = std::clamp(dot, -1.0, 1.0); | ||
|
|
||
| double angle = std::acos(dot); | ||
|
|
||
| return angle; | ||
| } | ||
|
|
||
|
|
||
| } // namespace nav2_route | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.