15 #ifndef NAV2_UTIL__GEOMETRY_UTILS_HPP_
16 #define NAV2_UTIL__GEOMETRY_UTILS_HPP_
21 #include "geometry_msgs/msg/pose.hpp"
22 #include "geometry_msgs/msg/pose_stamped.hpp"
23 #include "geometry_msgs/msg/point.hpp"
24 #include "geometry_msgs/msg/quaternion.hpp"
25 #include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
26 #include "nav_msgs/msg/path.hpp"
27 #include "nav2_msgs/msg/waypoint_status.hpp"
31 namespace geometry_utils
39 inline geometry_msgs::msg::Quaternion orientationAroundZAxis(
double angle)
42 q.setRPY(0, 0, angle);
53 inline double euclidean_distance(
54 const geometry_msgs::msg::Point & pos1,
55 const geometry_msgs::msg::Point & pos2,
56 const bool is_3d =
false)
58 double dx = pos1.x - pos2.x;
59 double dy = pos1.y - pos2.y;
62 double dz = pos1.z - pos2.z;
63 return std::hypot(dx, dy, dz);
66 return std::hypot(dx, dy);
76 inline double euclidean_distance(
77 const geometry_msgs::msg::Pose & pos1,
78 const geometry_msgs::msg::Pose & pos2,
79 const bool is_3d =
false)
81 double dx = pos1.position.x - pos2.position.x;
82 double dy = pos1.position.y - pos2.position.y;
85 double dz = pos1.position.z - pos2.position.z;
86 return std::hypot(dx, dy, dz);
89 return std::hypot(dx, dy);
99 inline double euclidean_distance(
100 const geometry_msgs::msg::PoseStamped & pos1,
101 const geometry_msgs::msg::PoseStamped & pos2,
102 const bool is_3d =
false)
104 return euclidean_distance(pos1.pose, pos2.pose, is_3d);
110 template<
typename Iter,
typename Getter>
111 inline Iter min_by(Iter begin, Iter end, Getter getCompareVal)
116 auto lowest = getCompareVal(*begin);
117 Iter lowest_it = begin;
118 for (Iter it = ++begin; it != end; ++it) {
119 auto comp = getCompareVal(*it);
120 if (
comp <= lowest) {
131 template<
typename Iter,
typename Getter>
132 inline Iter first_after_integrated_distance(Iter begin, Iter end, Getter getCompareVal)
138 for (Iter it = begin; it != end - 1; it++) {
139 dist += euclidean_distance(*it, *(it + 1));
140 if (dist > getCompareVal) {
155 inline double calculate_path_length(
const nav_msgs::msg::Path & path,
size_t start_index = 0)
157 if (start_index + 1 >= path.poses.size()) {
160 double path_length = 0.0;
161 for (
size_t idx = start_index; idx < path.poses.size() - 1; ++idx) {
162 path_length += euclidean_distance(path.poses[idx].pose, path.poses[idx + 1].pose);
174 inline int find_next_matching_goal_in_waypoint_statuses(
175 const std::vector<nav2_msgs::msg::WaypointStatus> & waypoint_statuses,
176 const geometry_msgs::msg::PoseStamped & goal)
178 auto itr = std::find_if(waypoint_statuses.begin(), waypoint_statuses.end(),
179 [&goal](
const nav2_msgs::msg::WaypointStatus & status){
180 return status.waypoint_pose == goal &&
181 status.waypoint_status == nav2_msgs::msg::WaypointStatus::PENDING;
184 if (itr == waypoint_statuses.end()) {
188 return itr - waypoint_statuses.begin();