15 #ifndef NAV2_ROUTE__CORNER_SMOOTHING_HPP_
16 #define NAV2_ROUTE__CORNER_SMOOTHING_HPP_
22 #include "nav2_route/types.hpp"
23 #include "nav2_route/utils.hpp"
46 start_edge_length_ = hypotf(corner.x - start.x, corner.y - start.y);
47 end_edge_length_ = hypotf(end.x - corner.x, end.y - corner.y);
50 if (start_edge_length_ == 0.0 || end_edge_length_ == 0.0) {
return;}
55 if (std::abs(angle) < 1E-6 || std::abs(angle - M_PI) < 1E-6) {
return;}
57 float tangent_length = minimum_radius / (std::tan(std::fabs(angle) / 2));
59 if (tangent_length < start_edge_length_ && tangent_length < end_edge_length_) {
60 std::vector<float> start_edge_unit_tangent =
61 {(start.x - corner.x) / start_edge_length_, (start.y - corner.y) / start_edge_length_};
62 std::vector<float> end_edge_unit_tangent =
63 {(end.x - corner.x) / end_edge_length_, (end.y - corner.y) / end_edge_length_};
65 float bisector_x = start_edge_unit_tangent[0] + end_edge_unit_tangent[0];
66 float bisector_y = start_edge_unit_tangent[1] + end_edge_unit_tangent[1];
67 float bisector_magnitude = std::sqrt(bisector_x * bisector_x + bisector_y * bisector_y);
69 std::vector<float> unit_bisector =
70 {bisector_x / bisector_magnitude, bisector_y / bisector_magnitude};
72 start_coordinate_.x = corner.x + start_edge_unit_tangent[0] * tangent_length;
73 start_coordinate_.y = corner.y + start_edge_unit_tangent[1] * tangent_length;
75 end_coordinate_.x = corner.x + end_edge_unit_tangent[0] * tangent_length;
76 end_coordinate_.y = corner.y + end_edge_unit_tangent[1] * tangent_length;
78 float bisector_length = minimum_radius / std::sin(angle / 2);
80 circle_center_coordinate_.x = corner.x + unit_bisector[0] * bisector_length;
81 circle_center_coordinate_.y = corner.y + unit_bisector[1] * bisector_length;
98 const float & max_angle_resolution,
99 std::vector<geometry_msgs::msg::PoseStamped> & poses)
101 std::vector<float> r_start{start_coordinate_.x - circle_center_coordinate_.x,
102 start_coordinate_.y - circle_center_coordinate_.y};
103 std::vector<float> r_end{end_coordinate_.x - circle_center_coordinate_.x,
104 end_coordinate_.y - circle_center_coordinate_.y};
105 float cross = r_start[0] * r_end[1] - r_start[1] * r_end[0];
106 float dot = r_start[0] * r_end[0] + r_start[1] * r_end[1];
107 float signed_angle = std::atan2(cross, dot);
109 int N = std::max(1,
static_cast<int>(std::ceil(std::abs(signed_angle) / max_angle_resolution)));
110 float angle_resolution = signed_angle / N;
113 for (
int i = 0; i <= N; i++) {
114 float angle = i * angle_resolution;
115 x = circle_center_coordinate_.x +
116 (r_start[0] * std::cos(angle) - r_start[1] * std::sin(angle));
117 y = circle_center_coordinate_.y +
118 (r_start[0] * std::sin(angle) + r_start[1] * std::cos(angle));
119 poses.push_back(utils::toMsg(x, y));
153 float start_dx = start.x - corner.x;
154 float start_dy = start.y - corner.y;
156 float end_dx = end.x - corner.x;
157 float end_dy = end.y - corner.y;
160 acos((start_dx * end_dx + start_dy * end_dy) / (start_edge_length_ * end_edge_length_));
166 bool valid_corner_{
false};
167 float start_edge_length_;
168 float end_edge_length_;
169 Coordinates start_coordinate_;
170 Coordinates end_coordinate_;
171 Coordinates circle_center_coordinate_;
A class used to smooth corners defined by the edges and nodes of the route graph. Used with path conv...
bool isCornerValid() const
return if a valid corner arc (one that doesn't overrun the edge lengths) is generated
void interpolateArc(const float &max_angle_resolution, std::vector< geometry_msgs::msg::PoseStamped > &poses)
interpolates the arc for a path of certain density
Coordinates getCornerStart() const
return the start coordinate of the corner arc
~CornerArc()=default
A destructor for nav2_route::CornerArc.
float getAngleBetweenEdges(const Coordinates &start, const Coordinates &corner, const Coordinates &end)
find the signed angle between a corner generated by 3 points
CornerArc(const Coordinates &start, const Coordinates &corner, const Coordinates &end, float minimum_radius)
A constructor for nav2_route::CornerArc.
Coordinates getCornerEnd() const
return the end coordinate of the corner arc
An object to store Node coordinates in different frames.