Nav2 Navigation Stack - lyrical  lyrical
ROS 2 Navigation Stack
polygon_utils.hpp
1 // Copyright (c) 2022 Samsung R&D Institute Russia
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef NAV2_COLLISION_MONITOR__POLYGON_UTILS_HPP_
16 #define NAV2_COLLISION_MONITOR__POLYGON_UTILS_HPP_
17 
18 #include <cmath>
19 #include <string>
20 #include <utility>
21 #include <vector>
22 
23 #include "tf2/LinearMath/Transform.hpp"
24 #include "tf2/LinearMath/Vector3.hpp"
25 
26 #include "nav2_util/array_parser.hpp"
27 
28 #include "nav2_collision_monitor/types.hpp"
29 
30 namespace nav2_collision_monitor
31 {
32 
49 inline bool parsePolygonPoints(
50  const std::string & points_str,
51  std::size_t min_vertices,
52  std::vector<Point> & out,
53  std::string & error_msg)
54 {
55  std::string parse_error;
56  const std::vector<std::vector<float>> vvf = nav2_util::parseVVF(points_str, parse_error);
57  if (!parse_error.empty()) {
58  error_msg = "error parsing points '" + points_str + "': " + parse_error;
59  return false;
60  }
61  if (vvf.size() < min_vertices) {
62  error_msg = "polygon must have at least " + std::to_string(min_vertices) + " vertices";
63  return false;
64  }
65 
66  std::vector<Point> parsed;
67  parsed.reserve(vvf.size());
68  for (const std::vector<float> & v : vvf) {
69  if (v.size() != 2) {
70  error_msg = "each point must be a pair of numbers [x, y]";
71  return false;
72  }
73  Point point;
74  point.x = v[0];
75  point.y = v[1];
76  parsed.push_back(point);
77  }
78 
79  out = std::move(parsed);
80  return true;
81 }
82 
89 inline void transformPolygonPoints(
90  const tf2::Transform & tf,
91  const std::vector<Point> & in,
92  std::vector<Point> & out)
93 {
94  out.resize(in.size());
95  for (std::size_t i = 0; i < in.size(); ++i) {
96  const tf2::Vector3 p_b = tf * tf2::Vector3(in[i].x, in[i].y, 0.0);
97  out[i].x = p_b.x();
98  out[i].y = p_b.y();
99  }
100 }
101 
108 inline std::vector<Point> circleToPolygon(double radius, int edges = 16)
109 {
110  std::vector<Point> poly;
111  poly.reserve(static_cast<std::size_t>(edges));
112  const double angle_increment = 2.0 * M_PI / edges;
113  for (int i = 0; i < edges; ++i) {
114  const double angle = angle_increment * i;
115  Point p;
116  p.x = radius * std::cos(angle);
117  p.y = radius * std::sin(angle);
118  poly.push_back(p);
119  }
120  return poly;
121 }
122 
123 } // namespace nav2_collision_monitor
124 
125 #endif // NAV2_COLLISION_MONITOR__POLYGON_UTILS_HPP_