29 #include "nav2_costmap_2d/footprint.hpp"
36 #include "geometry_msgs/msg/point32.hpp"
37 #include "nav2_util/array_parser.hpp"
38 #include "nav2_costmap_2d/costmap_math.hpp"
44 const std::vector<geometry_msgs::msg::Point> & footprint)
46 double min_dist = std::numeric_limits<double>::max();
47 double max_dist = 0.0;
49 if (footprint.size() <= 2) {
50 return std::pair<double, double>(min_dist, max_dist);
53 for (
unsigned int i = 0; i < footprint.size() - 1; ++i) {
55 double vertex_dist = distance(0.0, 0.0, footprint[i].x, footprint[i].y);
56 double edge_dist = distanceToLine(
57 0.0, 0.0, footprint[i].x, footprint[i].y,
58 footprint[i + 1].x, footprint[i + 1].y);
59 min_dist = std::min(min_dist, std::min(vertex_dist, edge_dist));
60 max_dist = std::max(max_dist, std::max(vertex_dist, edge_dist));
64 double vertex_dist = distance(0.0, 0.0, footprint.back().x, footprint.back().y);
65 double edge_dist = distanceToLine(
66 0.0, 0.0, footprint.back().x, footprint.back().y,
67 footprint.front().x, footprint.front().y);
68 min_dist = std::min(min_dist, std::min(vertex_dist, edge_dist));
69 max_dist = std::max(max_dist, std::max(vertex_dist, edge_dist));
71 return std::pair<double, double>(min_dist, max_dist);
74 geometry_msgs::msg::Point32
toPoint32(
const geometry_msgs::msg::Point & pt)
76 geometry_msgs::msg::Point32 point32;
83 geometry_msgs::msg::Point
toPoint(
const geometry_msgs::msg::Point32 & pt)
85 geometry_msgs::msg::Point point;
92 geometry_msgs::msg::Polygon
toPolygon(
const std::vector<geometry_msgs::msg::Point> & pts)
94 geometry_msgs::msg::Polygon polygon;
95 polygon.points.reserve(pts.size());
96 for (
const auto & pt : pts) {
102 std::vector<geometry_msgs::msg::Point>
toPointVector(
const geometry_msgs::msg::Polygon & polygon)
104 std::vector<geometry_msgs::msg::Point> pts;
105 pts.reserve(polygon.points.size());
106 for (
const auto & point : polygon.points) {
113 double x,
double y,
double theta,
114 const std::vector<geometry_msgs::msg::Point> & footprint_spec,
115 std::vector<geometry_msgs::msg::Point> & oriented_footprint)
118 oriented_footprint.resize(footprint_spec.size());
119 double cos_th = cos(theta);
120 double sin_th = sin(theta);
121 for (
unsigned int i = 0; i < footprint_spec.size(); ++i) {
122 double new_x = x + (footprint_spec[i].x * cos_th - footprint_spec[i].y * sin_th);
123 double new_y = y + (footprint_spec[i].x * sin_th + footprint_spec[i].y * cos_th);
124 geometry_msgs::msg::Point & new_pt = oriented_footprint[i];
131 double x,
double y,
double theta,
132 const std::vector<geometry_msgs::msg::Point> & footprint_spec,
133 geometry_msgs::msg::PolygonStamped & oriented_footprint)
136 oriented_footprint.polygon.points.clear();
137 double cos_th = cos(theta);
138 double sin_th = sin(theta);
139 for (
unsigned int i = 0; i < footprint_spec.size(); ++i) {
140 geometry_msgs::msg::Point32 new_pt;
141 new_pt.x = x + (footprint_spec[i].x * cos_th - footprint_spec[i].y * sin_th);
142 new_pt.y = y + (footprint_spec[i].x * sin_th + footprint_spec[i].y * cos_th);
143 oriented_footprint.polygon.points.push_back(new_pt);
147 void padFootprint(std::vector<geometry_msgs::msg::Point> & footprint,
double padding)
150 for (
unsigned int i = 0; i < footprint.size(); i++) {
151 geometry_msgs::msg::Point & pt = footprint[i];
152 pt.x += sign0(pt.x) * padding;
153 pt.y += sign0(pt.y) * padding;
160 std::vector<geometry_msgs::msg::Point> points;
164 geometry_msgs::msg::Point pt;
165 for (
int i = 0; i < N; ++i) {
166 double angle = i * 2 * M_PI / N;
167 pt.x = cos(angle) * radius;
168 pt.y = sin(angle) * radius;
170 points.push_back(pt);
178 const std::string & footprint_string,
179 std::vector<geometry_msgs::msg::Point> & footprint)
182 std::vector<std::vector<float>> vvf = nav2_util::parseVVF(footprint_string, error);
187 "nav2_costmap_2d"),
"Error parsing footprint parameter: '%s'", error.c_str());
190 "nav2_costmap_2d"),
" Footprint string was '%s'.", footprint_string.c_str());
195 if (vvf.size() < 3) {
199 "You must specify at least three points for the robot footprint,"
200 " reverting to previous footprint.");
203 footprint.reserve(vvf.size());
204 for (
unsigned int i = 0; i < vvf.size(); i++) {
205 if (vvf[i].size() == 2) {
206 geometry_msgs::msg::Point point;
210 footprint.push_back(point);
215 "Points in the footprint specification must be pairs of numbers."
216 " Found a point with %d numbers.",
217 static_cast<int>(vvf[i].size()));
geometry_msgs::msg::Polygon toPolygon(const std::vector< geometry_msgs::msg::Point > &pts)
Convert vector of Points to Polygon msg.
geometry_msgs::msg::Point toPoint(const geometry_msgs::msg::Point32 &pt)
Convert Point32 to Point.
void transformFootprint(double x, double y, double theta, const std::vector< geometry_msgs::msg::Point > &footprint_spec, std::vector< geometry_msgs::msg::Point > &oriented_footprint)
Given a pose and base footprint, build the oriented footprint of the robot (list of Points)
bool makeFootprintFromString(const std::string &footprint_string, std::vector< geometry_msgs::msg::Point > &footprint)
Make the footprint from the given string.
std::pair< double, double > calculateMinAndMaxDistances(const std::vector< geometry_msgs::msg::Point > &footprint)
Calculate the extreme distances for the footprint.
void padFootprint(std::vector< geometry_msgs::msg::Point > &footprint, double padding)
Adds the specified amount of padding to the footprint (in place)
geometry_msgs::msg::Point32 toPoint32(const geometry_msgs::msg::Point &pt)
Convert Point to Point32.
std::vector< geometry_msgs::msg::Point > makeFootprintFromRadius(double radius)
Create a circular footprint from a given radius.
std::vector< geometry_msgs::msg::Point > toPointVector(const geometry_msgs::msg::Polygon &polygon)
Convert Polygon msg to vector of Points.