footprint.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2019, the neonavigation authors
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef COSTMAP_CSPACE_COSTMAP_3D_LAYER_FOOTPRINT_H
31 #define COSTMAP_CSPACE_COSTMAP_3D_LAYER_FOOTPRINT_H
32 
33 #include <algorithm>
34 #include <cmath>
35 #include <memory>
36 #include <vector>
37 
38 #include <ros/ros.h>
39 
40 #include <costmap_cspace_msgs/CSpace3D.h>
41 #include <costmap_cspace_msgs/CSpace3DUpdate.h>
42 #include <geometry_msgs/PolygonStamped.h>
43 #include <nav_msgs/OccupancyGrid.h>
44 
45 #include <xmlrpcpp/XmlRpcValue.h>
46 
49 #include <costmap_cspace/polygon.h>
50 
51 namespace costmap_cspace
52 {
54 {
55 public:
56  using Ptr = std::shared_ptr<Costmap3dLayerFootprint>;
57 
58 protected:
60  geometry_msgs::PolygonStamped footprint_;
66 
68  struct Rect
69  {
71  };
73  std::vector<bool> unknown_buf_;
74 
75 public:
77  : linear_expand_(0.0)
78  , linear_spread_(0.0)
80  , keep_unknown_(false)
81  , range_max_(0)
82  {
83  }
85  {
86  const int linear_spread_min_cost =
87  config.hasMember("linear_spread_min_cost") ? static_cast<int>(config["linear_spread_min_cost"]) : 0;
89  static_cast<double>(config["linear_expand"]),
90  static_cast<double>(config["linear_spread"]),
91  linear_spread_min_cost);
92  setFootprint(costmap_cspace::Polygon(config["footprint"]));
93  if (config.hasMember("keep_unknown"))
94  setKeepUnknown(config["keep_unknown"]);
95  }
96  void setKeepUnknown(const bool keep_unknown)
97  {
98  keep_unknown_ = keep_unknown;
99  }
101  const float linear_expand,
102  const float linear_spread,
103  const int linear_spread_min_cost = 0)
104  {
105  linear_expand_ = linear_expand;
106  linear_spread_ = linear_spread;
107  linear_spread_min_cost_ = linear_spread_min_cost;
108 
109  ROS_ASSERT(linear_expand >= 0.0);
110  ROS_ASSERT(std::isfinite(linear_expand));
111  ROS_ASSERT(linear_spread >= 0.0);
112  ROS_ASSERT(std::isfinite(linear_spread));
115  }
116  void setFootprint(const Polygon footprint)
117  {
118  footprint_p_ = footprint;
119  footprint_radius_ = footprint.radius();
120  footprint_ = footprint.toMsg();
121  }
123  {
124  return footprint_p_;
125  }
126  const geometry_msgs::PolygonStamped& getFootprintMsg() const
127  {
128  return footprint_;
129  }
130  float getFootprintRadius() const
131  {
132  return footprint_radius_;
133  }
134  int getRangeMax() const
135  {
136  return range_max_;
137  }
138  const CSpace3Cache& getTemplate() const
139  {
140  return cs_template_;
141  }
142  void setMapMetaData(const costmap_cspace_msgs::MapMetaData3D& info)
143  {
144  ROS_ASSERT(footprint_p_.v.size() > 2);
145 
146  range_max_ =
147  std::ceil((footprint_radius_ + linear_expand_ + linear_spread_) / info.linear_resolution);
148  cs_template_.reset(range_max_, range_max_, info.angle);
149 
150  const float eps = info.linear_resolution / 100.0;
151  // C-Space template
152  for (size_t yaw = 0; yaw < info.angle; yaw++)
153  {
154  for (int y = -range_max_; y <= range_max_; y++)
155  {
156  for (int x = -range_max_; x <= range_max_; x++)
157  {
158  auto f = footprint_p_;
159  f.move(x * info.linear_resolution,
160  y * info.linear_resolution,
161  yaw * info.angular_resolution);
162  Vec p;
163  p[0] = 0;
164  p[1] = 0;
165  if (f.inside(p))
166  {
167  cs_template_.e(x, y, yaw) = 100;
168  }
169  else
170  {
171  const float d = f.dist(p);
172  if (d < linear_expand_)
173  {
174  cs_template_.e(x, y, yaw) = 100;
175  }
176  else if (d < linear_expand_ + linear_spread_)
177  {
178  cs_template_.e(x, y, yaw) = 100 - (d - linear_expand_) * (100 - linear_spread_min_cost_) / linear_spread_;
179  }
180  else if (std::abs(linear_expand_ + linear_spread_ - d) < eps)
181  {
183  }
184  else
185  {
186  cs_template_.e(x, y, yaw) = 0;
187  }
188  }
189  }
190  }
191  if (footprint_radius_ == 0)
192  cs_template_.e(0, 0, yaw) = 100;
193  }
194  }
195 
196 protected:
197  bool updateChain(const bool output)
198  {
199  return false;
200  }
202  const nav_msgs::OccupancyGrid::ConstPtr& map,
203  const UpdatedRegion& region)
204  {
205  if (root_)
206  generateCSpace(map_, map, region);
207  else
208  generateCSpace(map_overlay_, map, region);
209  }
210  virtual void generateCSpace(
211  CSpace3DMsg::Ptr map,
212  const nav_msgs::OccupancyGrid::ConstPtr& msg,
213  const UpdatedRegion& region)
214  {
215  ROS_ASSERT(ang_grid_ > 0);
216  clearTravelableArea(map, msg);
217  for (size_t yaw = 0; yaw < map->info.angle; yaw++)
218  {
219  generateSpecifiedCSpace(map, msg, yaw);
220  }
221  }
222 
223  // Clear travelable area in OVERWRITE mode
225  CSpace3DMsg::Ptr map,
226  const nav_msgs::OccupancyGrid::ConstPtr& msg)
227  {
228  if (overlay_mode_ != OVERWRITE || root_)
229  {
230  return;
231  }
232  const int ox =
233  std::lround((msg->info.origin.position.x - map->info.origin.position.x) /
234  map->info.linear_resolution);
235  const int oy =
236  std::lround((msg->info.origin.position.y - map->info.origin.position.y) /
237  map->info.linear_resolution);
238  const double resolution_scale = msg->info.resolution / map->info.linear_resolution;
239 
240  for (size_t yaw = 0; yaw < map->info.angle; yaw++)
241  {
242  for (size_t i = 0; i < msg->data.size(); i++)
243  {
244  const auto& val = msg->data[i];
245  if (val < 0)
246  continue;
247 
248  const int x = std::lround((i % msg->info.width) * resolution_scale);
249  if (x < range_max_ || static_cast<int>(msg->info.width) - range_max_ <= x)
250  continue;
251  const int y = std::lround((i / msg->info.width) * resolution_scale);
252  if (y < range_max_ || static_cast<int>(msg->info.height) - range_max_ <= y)
253  continue;
254 
255  const int res_up = std::ceil(resolution_scale);
256  for (int yp = 0; yp < res_up; yp++)
257  {
258  const int y2 = y + oy + yp;
259  if (static_cast<size_t>(y2) >= map->info.height)
260  continue;
261  for (int xp = 0; xp < res_up; xp++)
262  {
263  const int x2 = x + ox + xp;
264  if (static_cast<size_t>(x2) >= map->info.width)
265  continue;
266 
267  map->getCost(x2, y2, yaw) = -1;
268  }
269  }
270  }
271  }
272  }
273 
275  CSpace3DMsg::Ptr map,
276  const nav_msgs::OccupancyGrid::ConstPtr& msg,
277  const size_t yaw)
278  {
279  const auto getMaskedRange = [this, msg](const int pos, Rect& result)
280  {
281  const int gx = pos % msg->info.width;
282  const int gy = pos / msg->info.width;
283  const int8_t* const ptr = msg->data.data() + pos;
284  result.x_min = (gx == 0 || (*(ptr - 1) >= *ptr)) ? 0 : -range_max_;
285  result.x_max = (gx == static_cast<int>(msg->info.width) - 1 || (*(ptr + 1) >= *ptr)) ? 0 : range_max_;
286  result.y_min = (gy == 0 || (*(ptr - msg->info.width) >= *ptr)) ? 0 : -range_max_;
287  result.y_max =
288  (gy == static_cast<int>(msg->info.height) - 1 || (*(ptr + msg->info.width) >= *ptr)) ? 0 : range_max_;
289  };
290  const auto getRange = (msg->info.resolution == map->info.linear_resolution) ?
291  getMaskedRange :
292  std::function<void(const int, Rect&)>([](const int, Rect&) {});
293 
294  const int ox =
295  std::lround((msg->info.origin.position.x - map->info.origin.position.x) / map->info.linear_resolution);
296  const int oy =
297  std::lround((msg->info.origin.position.y - map->info.origin.position.y) / map->info.linear_resolution);
298  const double resolution_scale = msg->info.resolution / map->info.linear_resolution;
299  if (keep_unknown_)
300  {
301  unknown_buf_.resize(msg->data.size());
302  for (size_t i = 0; i < msg->data.size(); i++)
303  {
304  const int gx = std::lround((i % msg->info.width) * resolution_scale) + ox;
305  const int gy = std::lround((i / msg->info.width) * resolution_scale) + oy;
306  if (static_cast<size_t>(gx) >= map->info.width ||
307  static_cast<size_t>(gy) >= map->info.height)
308  continue;
309  // If the cell is unknown in parent map and also updated map,
310  // the cell is never measured.
311  // Never measured cells should be marked unknown
312  // to be correctly processed in the planner.
313  unknown_buf_[i] = msg->data[i] < 0 && map->getCost(gx, gy, yaw) < 0;
314  }
315  }
317  for (size_t i = 0; i < msg->data.size(); i++)
318  {
319  const int8_t val = msg->data[i];
320  if (val < 0)
321  {
322  continue;
323  }
324  const int gx = std::lround((i % msg->info.width) * resolution_scale) + ox;
325  const int gy = std::lround((i / msg->info.width) * resolution_scale) + oy;
326  if (static_cast<size_t>(gx) >= map->info.width ||
327  static_cast<size_t>(gy) >= map->info.height)
328  continue;
329  if (val == 0)
330  {
331  int8_t& m = map->getCost(gx, gy, yaw);
332  if (m < 0)
333  m = 0;
334  continue;
335  }
336  getRange(i, range);
337  const int map_x_min = std::max(gx + range.x_min, 0);
338  const int map_x_max = std::min(gx + range.x_max, static_cast<int>(map->info.width) - 1);
339  const int map_y_min = std::max(gy + range.y_min, 0);
340  const int map_y_max = std::min(gy + range.y_max, static_cast<int>(map->info.height) - 1);
341  for (int map_y = map_y_min; map_y <= map_y_max; ++map_y)
342  {
343  // Use raw pointers for faster iteration
344  int8_t* cost_addr = &(map->getCost(map_x_min, map_y, yaw));
345  const char* cs_addr = &(cs_template_.e(map_x_min - gx, map_y - gy, yaw));
346  for (int n = 0; n <= map_x_max - map_x_min; ++n, ++cost_addr, ++cs_addr)
347  {
348  const int8_t c = *cs_addr * val / 100;
349  if (c > 0 && *cost_addr < c)
350  *cost_addr = c;
351  }
352  }
353  }
354  if (keep_unknown_)
355  {
356  for (size_t i = 0; i < unknown_buf_.size(); i++)
357  {
358  if (!unknown_buf_[i])
359  continue;
360  const int gx = std::lround((i % msg->info.width) * resolution_scale) + ox;
361  const int gy = std::lround((i / msg->info.width) * resolution_scale) + oy;
362  if (static_cast<size_t>(gx) >= map->info.width ||
363  static_cast<size_t>(gy) >= map->info.height)
364  continue;
365  map->getCost(gx, gy, yaw) = -1;
366  }
367  }
368  }
369 };
370 } // namespace costmap_cspace
371 
372 #endif // COSTMAP_CSPACE_COSTMAP_3D_LAYER_FOOTPRINT_H
costmap_cspace::Costmap3dLayerBase::map_overlay_
CSpace3DMsg::Ptr map_overlay_
Definition: base.h:263
costmap_cspace::CSpace3DMsg::Ptr
std::shared_ptr< CSpace3DMsg > Ptr
Definition: base.h:52
costmap_cspace::Costmap3dLayerFootprint::generateSpecifiedCSpace
void generateSpecifiedCSpace(CSpace3DMsg::Ptr map, const nav_msgs::OccupancyGrid::ConstPtr &msg, const size_t yaw)
Definition: footprint.h:274
costmap_cspace::Costmap3dLayerFootprint::loadConfig
void loadConfig(XmlRpc::XmlRpcValue config)
Definition: footprint.h:84
costmap_cspace::Costmap3dLayerFootprint::getFootprintRadius
float getFootprintRadius() const
Definition: footprint.h:130
costmap_cspace::Costmap3dLayerFootprint::setMapMetaData
void setMapMetaData(const costmap_cspace_msgs::MapMetaData3D &info)
Definition: footprint.h:142
costmap_cspace::Costmap3dLayerFootprint::getRangeMax
int getRangeMax() const
Definition: footprint.h:134
ros.h
costmap_cspace::UpdatedRegion
Definition: base.h:102
costmap_cspace::Costmap3dLayerFootprint::getFootprintMsg
const geometry_msgs::PolygonStamped & getFootprintMsg() const
Definition: footprint.h:126
polygon.h
costmap_cspace::Polygon::radius
float radius() const
Definition: polygon.h:141
base.h
costmap_cspace::Costmap3dLayerFootprint::setExpansion
void setExpansion(const float linear_expand, const float linear_spread, const int linear_spread_min_cost=0)
Definition: footprint.h:100
costmap_cspace::Costmap3dLayerBase::overlay_mode_
MapOverlayMode overlay_mode_
Definition: base.h:259
costmap_cspace::Costmap3dLayerFootprint::Rect::x_max
int x_max
Definition: footprint.h:70
costmap_cspace::Costmap3dLayerFootprint::linear_spread_min_cost_
int linear_spread_min_cost_
Definition: footprint.h:63
costmap_cspace::Costmap3dLayerBase::root_
bool root_
Definition: base.h:260
f
f
costmap_cspace::Costmap3dLayerFootprint::Rect::y_max
int y_max
Definition: footprint.h:70
costmap_cspace::Costmap3dLayerFootprint::linear_expand_
float linear_expand_
Definition: footprint.h:61
costmap_cspace::Costmap3dLayerFootprint
Definition: footprint.h:53
costmap_cspace::Costmap3dLayerFootprint::keep_unknown_
bool keep_unknown_
Definition: footprint.h:65
costmap_cspace::Vec
Definition: polygon.h:44
costmap_cspace::Costmap3dLayerFootprint::Rect::x_min
int x_min
Definition: footprint.h:70
costmap_cspace::Costmap3dLayerFootprint::Rect
Definition: footprint.h:68
costmap_cspace::Costmap3dLayerFootprint::generateCSpace
virtual void generateCSpace(CSpace3DMsg::Ptr map, const nav_msgs::OccupancyGrid::ConstPtr &msg, const UpdatedRegion &region)
Definition: footprint.h:210
costmap_cspace::OVERWRITE
@ OVERWRITE
Definition: base.h:98
costmap_cspace::Costmap3dLayerBase
Definition: base.h:252
costmap_cspace::Costmap3dLayerFootprint::footprint_radius_
float footprint_radius_
Definition: footprint.h:59
costmap_cspace::CSpace3Cache::e
char & e(const int &x, const int &y, const int &yaw)
Definition: cspace3_cache.h:73
cspace3_cache.h
costmap_cspace::Costmap3dLayerFootprint::range_max_
int range_max_
Definition: footprint.h:72
d
d
costmap_cspace::Costmap3dLayerFootprint::updateCSpace
void updateCSpace(const nav_msgs::OccupancyGrid::ConstPtr &map, const UpdatedRegion &region)
Definition: footprint.h:201
costmap_cspace::Costmap3dLayerFootprint::footprint_
geometry_msgs::PolygonStamped footprint_
Definition: footprint.h:60
costmap_cspace::Costmap3dLayerFootprint::Costmap3dLayerFootprint
Costmap3dLayerFootprint()
Definition: footprint.h:76
XmlRpcValue.h
costmap_cspace::Costmap3dLayerFootprint::footprint_p_
Polygon footprint_p_
Definition: footprint.h:64
costmap_cspace::Costmap3dLayerFootprint::updateChain
bool updateChain(const bool output)
Definition: footprint.h:197
costmap_cspace::Polygon::toMsg
geometry_msgs::PolygonStamped toMsg() const
Definition: polygon.h:123
costmap_cspace::Costmap3dLayerFootprint::linear_spread_
float linear_spread_
Definition: footprint.h:62
costmap_cspace::Costmap3dLayerFootprint::getTemplate
const CSpace3Cache & getTemplate() const
Definition: footprint.h:138
costmap_cspace::Costmap3dLayerBase::ang_grid_
int ang_grid_
Definition: base.h:258
costmap_cspace
Definition: costmap_3d.h:46
XmlRpc::XmlRpcValue::hasMember
bool hasMember(const std::string &name) const
costmap_cspace::CSpace3Cache
Definition: cspace3_cache.h:39
costmap_cspace::CSpace3Cache::reset
void reset(const int &x, const int &y, const int &yaw)
Definition: cspace3_cache.h:57
costmap_cspace::Costmap3dLayerFootprint::setKeepUnknown
void setKeepUnknown(const bool keep_unknown)
Definition: footprint.h:96
costmap_cspace::Costmap3dLayerFootprint::cs_template_
CSpace3Cache cs_template_
Definition: footprint.h:67
costmap_cspace::Polygon
Definition: polygon.h:90
costmap_cspace::Polygon::v
std::vector< Vec > v
Definition: polygon.h:93
costmap_cspace::Costmap3dLayerFootprint::getFootprint
Polygon & getFootprint()
Definition: footprint.h:122
costmap_cspace::Costmap3dLayerBase::map_
CSpace3DMsg::Ptr map_
Definition: base.h:262
ROS_ASSERT
#define ROS_ASSERT(cond)
costmap_cspace::Costmap3dLayerFootprint::setFootprint
void setFootprint(const Polygon footprint)
Definition: footprint.h:116
costmap_cspace::Costmap3dLayerFootprint::Rect::y_min
int y_min
Definition: footprint.h:70
costmap_cspace::Costmap3dLayerFootprint::clearTravelableArea
void clearTravelableArea(CSpace3DMsg::Ptr map, const nav_msgs::OccupancyGrid::ConstPtr &msg)
Definition: footprint.h:224
costmap_cspace::Costmap3dLayerFootprint::unknown_buf_
std::vector< bool > unknown_buf_
Definition: footprint.h:73
XmlRpc::XmlRpcValue
costmap_cspace::Costmap3dLayerBase::Ptr
std::shared_ptr< Costmap3dLayerBase > Ptr
Definition: base.h:255


costmap_cspace
Author(s): Atsushi Watanabe
autogenerated on Fri May 16 2025 02:15:10