18 #include "std_msgs/msg/color_rgba.hpp"
19 #include "visualization_msgs/msg/marker_array.hpp"
20 #include "visualization_msgs/msg/marker.hpp"
21 #include "geometry_msgs/msg/vector3.hpp"
22 #include "nav2_util/geometry_utils.hpp"
23 #include "nav2_msgs/msg/route.hpp"
24 #include "nav2_route/types.hpp"
25 #include "nav2_costmap_2d/costmap_2d.hpp"
26 #include "nav2_util/line_iterator.hpp"
28 #ifndef NAV2_ROUTE__UTILS_HPP_
29 #define NAV2_ROUTE__UTILS_HPP_
43 inline geometry_msgs::msg::PoseStamped toMsg(
const float x,
const float y)
45 geometry_msgs::msg::PoseStamped pose;
46 pose.pose.position.x = x;
47 pose.pose.position.y = y;
58 inline visualization_msgs::msg::MarkerArray toMsg(
59 const nav2_route::Graph & graph,
const std::string & frame,
const rclcpp::Time & now)
61 visualization_msgs::msg::MarkerArray msg;
63 visualization_msgs::msg::Marker nodes_marker;
64 nodes_marker.header.frame_id = frame;
65 nodes_marker.header.stamp = now;
66 nodes_marker.action = 0;
67 nodes_marker.ns =
"route_graph_nodes";
68 nodes_marker.type = visualization_msgs::msg::Marker::SPHERE_LIST;
69 nodes_marker.scale.x = 0.1;
70 nodes_marker.scale.y = 0.1;
71 nodes_marker.scale.z = 0.1;
72 nodes_marker.color.r = 1.0;
73 nodes_marker.color.a = 1.0;
74 nodes_marker.points.reserve(graph.size());
76 visualization_msgs::msg::Marker edges_marker;
77 edges_marker.header.frame_id = frame;
78 edges_marker.header.stamp = now;
79 edges_marker.action = 0;
80 edges_marker.ns =
"route_graph_edges";
81 edges_marker.type = visualization_msgs::msg::Marker::LINE_LIST;
82 edges_marker.scale.x = 0.05;
83 edges_marker.color.g = 1.0;
84 edges_marker.color.a = 0.5;
85 constexpr
size_t points_per_edge = 2;
87 constexpr
size_t likely_min_edges_per_node = 2;
88 edges_marker.points.reserve(graph.size() * points_per_edge * likely_min_edges_per_node);
90 geometry_msgs::msg::Point node_pos;
91 geometry_msgs::msg::Point edge_start;
92 geometry_msgs::msg::Point edge_end;
94 visualization_msgs::msg::Marker node_id_marker;
95 node_id_marker.header.frame_id = frame;
96 node_id_marker.header.stamp = now;
97 node_id_marker.action = 0;
98 node_id_marker.ns =
"route_graph_node_ids";
99 node_id_marker.type = visualization_msgs::msg::Marker::TEXT_VIEW_FACING;
100 node_id_marker.scale.x = 0.1;
101 node_id_marker.scale.y = 0.1;
102 node_id_marker.scale.z = 0.1;
103 node_id_marker.color.a = 1.0;
104 node_id_marker.color.r = 1.0;
106 visualization_msgs::msg::Marker edge_id_marker;
107 edge_id_marker.header.frame_id = frame;
108 edge_id_marker.header.stamp = now;
109 edge_id_marker.action = 0;
110 edge_id_marker.ns =
"route_graph_edge_ids";
111 edge_id_marker.type = visualization_msgs::msg::Marker::TEXT_VIEW_FACING;
112 edge_id_marker.scale.x = 0.1;
113 edge_id_marker.scale.y = 0.1;
114 edge_id_marker.scale.z = 0.1;
115 edge_id_marker.color.a = 1.0;
116 edge_id_marker.color.g = 1.0;
118 for (
const auto & node : graph) {
119 node_pos.x = node.coords.x;
120 node_pos.y = node.coords.y;
121 nodes_marker.points.push_back(node_pos);
125 node_id_marker.pose.position.x = node.coords.x + 0.07;
126 node_id_marker.pose.position.y = node.coords.y;
127 node_id_marker.text = std::to_string(node.nodeid);
128 msg.markers.push_back(node_id_marker);
130 for (
const auto & neighbor : node.neighbors) {
131 edge_start.x = node.coords.x;
132 edge_start.y = node.coords.y;
133 edge_end.x = neighbor.end->coords.x;
134 edge_end.y = neighbor.end->coords.y;
135 edges_marker.points.push_back(edge_start);
136 edges_marker.points.push_back(edge_end);
139 float y_offset = 0.0;
140 if (node.nodeid > neighbor.end->nodeid) {
145 const float x_offset = 0.07;
149 edge_id_marker.pose.position.x =
150 node.coords.x + ((neighbor.end->coords.x - node.coords.x) / 2.0) + x_offset;
151 edge_id_marker.pose.position.y =
152 node.coords.y + ((neighbor.end->coords.y - node.coords.y) / 2.0) + y_offset;
153 edge_id_marker.text = std::to_string(neighbor.edgeid);
154 msg.markers.push_back(edge_id_marker);
158 msg.markers.push_back(edges_marker);
159 msg.markers.push_back(nodes_marker);
170 inline nav2_msgs::msg::Route toMsg(
171 const nav2_route::Route & route,
const std::string & frame,
const rclcpp::Time & now)
173 nav2_msgs::msg::Route msg;
174 msg.header.frame_id = frame;
175 msg.header.stamp = now;
176 msg.route_cost = route.route_cost;
178 nav2_msgs::msg::RouteNode route_node;
179 nav2_msgs::msg::RouteEdge route_edge;
180 route_node.nodeid = route.start_node->nodeid;
181 route_node.position.x = route.start_node->coords.x;
182 route_node.position.y = route.start_node->coords.y;
183 msg.nodes.push_back(route_node);
186 for (
unsigned int i = 0; i != route.edges.size(); i++) {
187 route_edge.edgeid = route.edges[i]->edgeid;
188 route_edge.start.x = route.edges[i]->start->coords.x;
189 route_edge.start.y = route.edges[i]->start->coords.y;
190 route_edge.end.x = route.edges[i]->end->coords.x;
191 route_edge.end.y = route.edges[i]->end->coords.y;
192 msg.edges.push_back(route_edge);
194 route_node.nodeid = route.edges[i]->end->nodeid;
195 route_node.position.x = route.edges[i]->end->coords.x;
196 route_node.position.y = route.edges[i]->end->coords.y;
197 msg.nodes.push_back(route_node);
211 inline float normalizedDot(
212 const float v1x,
const float v1y,
213 const float v2x,
const float v2y)
215 const float mag1 = std::hypotf(v1x, v1y);
216 const float mag2 = std::hypotf(v2x, v2y);
217 if (mag1 < 1e-6 || mag2 < 1e-6) {
220 return (v1x / mag1) * (v2x / mag2) + (v1y / mag1) * (v2y / mag2);
230 inline Coordinates findClosestPoint(
231 const geometry_msgs::msg::PoseStamped & pose,
232 const Coordinates & start,
const Coordinates & end)
235 const float vx = end.x - start.x;
236 const float vy = end.y - start.y;
237 const float ux = start.x - pose.pose.position.x;
238 const float uy = start.y - pose.pose.position.y;
239 const float uv = vx * ux + vy * uy;
240 const float vv = vx * vx + vy * vy;
247 const float t = -uv / vv;
248 if (t > 0.0 && t < 1.0) {
249 pt.x = (1.0 - t) * start.x + t * end.x;
250 pt.y = (1.0 - t) * start.y + t * end.y;
251 }
else if (t <= 0.0) {
260 inline float distance(
const Coordinates & coords,
const geometry_msgs::msg::PoseStamped & pose)
262 return hypotf(coords.x - pose.pose.position.x, coords.y - pose.pose.position.y);
An ordered set of nodes and edges corresponding to the planned route.