15 #ifndef NAV2_UTIL__SMOOTHER_UTILS_HPP_
16 #define NAV2_UTIL__SMOOTHER_UTILS_HPP_
24 #include "nav2_util/geometry_utils.hpp"
25 #include "nav_msgs/msg/path.hpp"
26 #include "angles/angles.h"
27 #include "tf2/utils.hpp"
50 inline std::vector<PathSegment> findDirectionalPathSegments(
51 const nav_msgs::msg::Path & path,
bool is_holonomic =
false)
53 std::vector<PathSegment> segments;
55 curr_segment.start = 0;
60 curr_segment.end = path.poses.size() - 1;
61 segments.push_back(curr_segment);
66 for (
unsigned int idx = 1; idx < path.poses.size() - 1; ++idx) {
68 double oa_x = path.poses[idx].pose.position.x -
69 path.poses[idx - 1].pose.position.x;
70 double oa_y = path.poses[idx].pose.position.y -
71 path.poses[idx - 1].pose.position.y;
72 double ab_x = path.poses[idx + 1].pose.position.x -
73 path.poses[idx].pose.position.x;
74 double ab_y = path.poses[idx + 1].pose.position.y -
75 path.poses[idx].pose.position.y;
78 double dot_product = (oa_x * ab_x) + (oa_y * ab_y);
79 if (dot_product < 0.0) {
80 curr_segment.end = idx;
81 segments.push_back(curr_segment);
82 curr_segment.start = idx;
86 double cur_theta = tf2::getYaw(path.poses[idx].pose.orientation);
87 double next_theta = tf2::getYaw(path.poses[idx + 1].pose.orientation);
88 double dtheta = angles::shortest_angular_distance(cur_theta, next_theta);
89 if (fabs(ab_x) < 1e-4 && fabs(ab_y) < 1e-4 && fabs(dtheta) > 1e-4) {
90 curr_segment.end = idx;
91 segments.push_back(curr_segment);
92 curr_segment.start = idx;
96 curr_segment.end = path.poses.size() - 1;
97 segments.push_back(curr_segment);
108 inline void updateApproximatePathOrientations(
109 nav_msgs::msg::Path & path,
110 bool & reversing_segment,
111 bool is_holonomic =
false)
113 double dx, dy, theta, pt_yaw;
114 reversing_segment =
false;
117 dx = path.poses[2].pose.position.x - path.poses[1].pose.position.x;
118 dy = path.poses[2].pose.position.y - path.poses[1].pose.position.y;
119 theta = atan2(dy, dx);
120 pt_yaw = tf2::getYaw(path.poses[1].pose.orientation);
121 if (!is_holonomic && fabs(angles::shortest_angular_distance(pt_yaw, theta)) > M_PI_2) {
122 reversing_segment =
true;
126 for (
unsigned int i = 0; i != path.poses.size() - 1; i++) {
127 dx = path.poses[i + 1].pose.position.x - path.poses[i].pose.position.x;
128 dy = path.poses[i + 1].pose.position.y - path.poses[i].pose.position.y;
129 theta = atan2(dy, dx);
132 if (fabs(dx) < 1e-4 && fabs(dy) < 1e-4) {
137 if (reversing_segment) {
141 path.poses[i].pose.orientation = nav2_util::geometry_utils::orientationAroundZAxis(theta);
A segment of a path in start/end indices.