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;
62 visualization_msgs::msg::Marker curr_marker;
63 curr_marker.header.frame_id = frame;
64 curr_marker.header.stamp = now;
65 curr_marker.action = 0;
67 auto getSphereSize = []() {
68 geometry_msgs::msg::Vector3 v_msg;
75 auto getSphereColor = []() {
76 std_msgs::msg::ColorRGBA c_msg;
84 auto getLineColor = []() {
85 std_msgs::msg::ColorRGBA c_msg;
93 unsigned int marker_idx = 1;
94 for (
unsigned int i = 0; i != graph.size(); i++) {
95 if (graph[i].nodeid == std::numeric_limits<int>::max()) {
98 curr_marker.ns =
"route_graph";
99 curr_marker.id = marker_idx++;
100 curr_marker.type = visualization_msgs::msg::Marker::SPHERE;
101 curr_marker.pose.position.x = graph[i].coords.x;
102 curr_marker.pose.position.y = graph[i].coords.y;
103 curr_marker.scale = getSphereSize();
104 curr_marker.color = getSphereColor();
105 msg.markers.push_back(curr_marker);
108 curr_marker.ns =
"route_graph_ids";
109 curr_marker.id = marker_idx++;
110 curr_marker.type = visualization_msgs::msg::Marker::TEXT_VIEW_FACING;
111 curr_marker.pose.position.x = graph[i].coords.x + 0.07;
112 curr_marker.pose.position.y = graph[i].coords.y;
113 curr_marker.text = std::to_string(graph[i].nodeid);
114 curr_marker.scale.z = 0.1;
115 msg.markers.push_back(curr_marker);
117 for (
unsigned int j = 0; j != graph[i].neighbors.size(); j++) {
118 curr_marker.ns =
"route_graph";
119 curr_marker.id = marker_idx++;
120 curr_marker.type = visualization_msgs::msg::Marker::LINE_LIST;
121 curr_marker.pose.position.x = 0;
122 curr_marker.pose.position.y = 0;
123 curr_marker.points.resize(2);
124 curr_marker.points[0].x = graph[i].coords.x;
125 curr_marker.points[0].y = graph[i].coords.y;
126 curr_marker.points[1].x = graph[i].neighbors[j].end->coords.x;
127 curr_marker.points[1].y = graph[i].neighbors[j].end->coords.y;
128 curr_marker.scale.x = 0.03;
129 curr_marker.color = getLineColor();
130 msg.markers.push_back(curr_marker);
131 curr_marker.points.clear();
134 curr_marker.ns =
"route_graph_ids";
135 curr_marker.id = marker_idx++;
136 curr_marker.type = visualization_msgs::msg::Marker::TEXT_VIEW_FACING;
137 curr_marker.pose.position.x =
138 graph[i].coords.x + ((graph[i].neighbors[j].end->coords.x - graph[i].coords.x) / 2.0) +
142 float y_offset = 0.0;
143 if (graph[i].nodeid > graph[i].neighbors[j].end->nodeid) {
149 curr_marker.pose.position.y =
150 graph[i].coords.y + ((graph[i].neighbors[j].end->coords.y - graph[i].coords.y) / 2.0) +
152 curr_marker.text = std::to_string(graph[i].neighbors[j].edgeid);
153 curr_marker.scale.z = 0.1;
154 msg.markers.push_back(curr_marker);
168 inline nav2_msgs::msg::Route toMsg(
169 const nav2_route::Route & route,
const std::string & frame,
const rclcpp::Time & now)
171 nav2_msgs::msg::Route msg;
172 msg.header.frame_id = frame;
173 msg.header.stamp = now;
174 msg.route_cost = route.route_cost;
176 nav2_msgs::msg::RouteNode route_node;
177 nav2_msgs::msg::RouteEdge route_edge;
178 route_node.nodeid = route.start_node->nodeid;
179 route_node.position.x = route.start_node->coords.x;
180 route_node.position.y = route.start_node->coords.y;
181 msg.nodes.push_back(route_node);
184 for (
unsigned int i = 0; i != route.edges.size(); i++) {
185 route_edge.edgeid = route.edges[i]->edgeid;
186 route_edge.start.x = route.edges[i]->start->coords.x;
187 route_edge.start.y = route.edges[i]->start->coords.y;
188 route_edge.end.x = route.edges[i]->end->coords.x;
189 route_edge.end.y = route.edges[i]->end->coords.y;
190 msg.edges.push_back(route_edge);
192 route_node.nodeid = route.edges[i]->end->nodeid;
193 route_node.position.x = route.edges[i]->end->coords.x;
194 route_node.position.y = route.edges[i]->end->coords.y;
195 msg.nodes.push_back(route_node);
209 inline float normalizedDot(
210 const float v1x,
const float v1y,
211 const float v2x,
const float v2y)
213 const float mag1 = std::hypotf(v1x, v1y);
214 const float mag2 = std::hypotf(v2x, v2y);
215 if (mag1 < 1e-6 || mag2 < 1e-6) {
218 return (v1x / mag1) * (v2x / mag2) + (v1y / mag1) * (v2y / mag2);
228 inline Coordinates findClosestPoint(
229 const geometry_msgs::msg::PoseStamped & pose,
230 const Coordinates & start,
const Coordinates & end)
233 const float vx = end.x - start.x;
234 const float vy = end.y - start.y;
235 const float ux = start.x - pose.pose.position.x;
236 const float uy = start.y - pose.pose.position.y;
237 const float uv = vx * ux + vy * uy;
238 const float vv = vx * vx + vy * vy;
245 const float t = -uv / vv;
246 if (t > 0.0 && t < 1.0) {
247 pt.x = (1.0 - t) * start.x + t * end.x;
248 pt.y = (1.0 - t) * start.y + t * end.y;
249 }
else if (t <= 0.0) {
258 inline float distance(
const Coordinates & coords,
const geometry_msgs::msg::PoseStamped & pose)
260 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.