base.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2018, 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_BASE_H
31 #define COSTMAP_CSPACE_COSTMAP_3D_LAYER_BASE_H
32 
33 #include <algorithm>
34 #include <cmath>
35 #include <map>
36 #include <memory>
37 #include <string>
38 
39 #include <ros/ros.h>
40 
41 #include <geometry_msgs/PolygonStamped.h>
42 #include <nav_msgs/OccupancyGrid.h>
43 
44 #include <costmap_cspace_msgs/CSpace3D.h>
45 #include <costmap_cspace_msgs/CSpace3DUpdate.h>
46 
47 namespace costmap_cspace
48 {
49 class CSpace3DMsg : public costmap_cspace_msgs::CSpace3D
50 {
51 public:
52  using Ptr = std::shared_ptr<CSpace3DMsg>;
53  using ConstPtr = std::shared_ptr<const CSpace3DMsg>;
54  size_t address(const int& x, const int& y, const int& yaw) const
55  {
56  return (yaw * info.height + y) * info.width + x;
57  }
58  const int8_t& getCost(const int& x, const int& y, const int& yaw) const
59  {
60  ROS_ASSERT(static_cast<size_t>(yaw) < info.angle);
61  ROS_ASSERT(static_cast<size_t>(x) < info.width);
62  ROS_ASSERT(static_cast<size_t>(y) < info.height);
63 
64  const size_t addr = address(x, y, yaw);
65  ROS_ASSERT(addr < data.size());
66 
67  return data[addr];
68  }
69  int8_t& getCost(const int& x, const int& y, const int& yaw)
70  {
71  ROS_ASSERT(static_cast<size_t>(yaw) < info.angle);
72  ROS_ASSERT(static_cast<size_t>(x) < info.width);
73  ROS_ASSERT(static_cast<size_t>(y) < info.height);
74 
75  const size_t addr = address(x, y, yaw);
76  ROS_ASSERT(addr < data.size());
77 
78  return data[addr];
79  }
80  static void copyCells(CSpace3DMsg& to, const int& to_x, const int& to_y, const int& to_yaw,
81  const CSpace3DMsg& from, const int& from_x, const int& from_y, const int& from_yaw,
82  const int& copy_cell_num)
83  {
84  std::memcpy(to.data.data() + to.address(to_x, to_y, to_yaw),
85  from.data.data() + from.address(from_x, from_y, from_yaw), copy_cell_num * sizeof(int8_t));
86  }
87  static void copyCells(costmap_cspace_msgs::CSpace3DUpdate& to, const int& to_x, const int& to_y, const int& to_yaw,
88  const CSpace3DMsg& from, const int& from_x, const int& from_y, const int& from_yaw,
89  const int& copy_cell_num)
90  {
91  std::memcpy(to.data.data() + (to_yaw * to.height + to_y) * to.width + to_x,
92  from.data.data() + from.address(from_x, from_y, from_yaw), copy_cell_num * sizeof(int8_t));
93  }
94 };
95 
97 {
100 };
101 
103 {
104 public:
105  int x_, y_, yaw_;
106  int width_, height_, angle_;
108 
110  : x_(0)
111  , y_(0)
112  , yaw_(0)
113  , width_(0)
114  , height_(0)
115  , angle_(0)
116  , stamp_(0)
117  {
118  }
120  const int& x, const int& y, const int& yaw,
121  const int& width, const int& height, const int& angle,
122  const ros::Time& stamp = ros::Time())
123  : x_(x)
124  , y_(y)
125  , yaw_(yaw)
126  , width_(width)
127  , height_(height)
128  , angle_(angle)
129  , stamp_(stamp)
130  {
131  }
132  void merge(const UpdatedRegion& region)
133  {
134  if (region.width_ == 0 || region.height_ == 0 || region.angle_ == 0)
135  return;
136  if (region.stamp_ > stamp_)
137  stamp_ = region.stamp_;
138 
139  if (width_ == 0 || height_ == 0 || angle_ == 0)
140  {
141  *this = region;
142  return;
143  }
144  int x2 = x_ + width_;
145  int y2 = y_ + height_;
146  int yaw2 = yaw_ + angle_;
147 
148  const int mx2 = region.x_ + region.width_;
149  const int my2 = region.y_ + region.height_;
150  const int myaw2 = region.yaw_ + region.angle_;
151 
152  if (region.x_ < x_)
153  x_ = region.x_;
154  if (region.y_ < y_)
155  y_ = region.y_;
156  if (region.yaw_ < yaw_)
157  yaw_ = region.yaw_;
158 
159  if (x2 < mx2)
160  x2 = mx2;
161  if (y2 < my2)
162  y2 = my2;
163  if (yaw2 < myaw2)
164  yaw2 = myaw2;
165 
166  width_ = x2 - x_;
167  height_ = y2 - y_;
168  angle_ = yaw2 - yaw_;
169  }
170  void expand(const int& ex)
171  {
172  ROS_ASSERT(ex >= 0);
173  x_ -= ex;
174  y_ -= ex;
175  width_ += 2 * ex;
176  height_ += 2 * ex;
177  }
178  void normalize(const int full_width, const int full_height)
179  {
180  int update_x = x_;
181  int update_y = y_;
182  int update_width = width_;
183  int update_height = height_;
184  if (update_x < 0)
185  {
186  update_width += update_x;
187  update_x = 0;
188  }
189  if (update_y < 0)
190  {
191  update_height += update_y;
192  update_y = 0;
193  }
194  if (update_x + update_width > full_width)
195  {
196  update_width = full_width - update_x;
197  }
198  if (update_y + update_height > full_height)
199  {
200  update_height = full_height - update_y;
201  }
202  if (update_width < 0)
203  {
204  update_width = 0;
205  }
206  if (update_height < 0)
207  {
208  update_height = 0;
209  }
210 
211  x_ = update_x;
212  y_ = update_y;
213  width_ = update_width;
214  height_ = update_height;
215  }
216  void bitblt(const CSpace3DMsg::Ptr& dest, const CSpace3DMsg::ConstPtr& src)
217  {
218  ROS_ASSERT(dest->info.angle == src->info.angle);
219  ROS_ASSERT(dest->info.width == src->info.width);
220  ROS_ASSERT(dest->info.height == src->info.height);
221 
222  normalize(src->info.width, src->info.height);
223  if (width_ == 0 || height_ == 0)
224  return;
225 
226  const size_t copy_length =
227  std::min<size_t>(width_, src->info.width - x_) *
228  sizeof(src->data[0]);
229  for (
230  size_t a = yaw_;
231  static_cast<int>(a) < yaw_ + angle_ && a < src->info.angle;
232  ++a)
233  {
234  auto dest_pos = &dest->data[dest->address(x_, y_, a)];
235  auto src_pos = &src->data[src->address(x_, y_, a)];
236  const auto dest_stride = dest->info.width * sizeof(dest->data[0]);
237  const auto src_stride = src->info.width * sizeof(src->data[0]);
238  for (
239  size_t y = y_;
240  static_cast<int>(y) < y_ + height_ && y < src->info.height;
241  ++y)
242  {
243  memcpy(
244  dest_pos, src_pos, copy_length);
245  src_pos += src_stride;
246  dest_pos += dest_stride;
247  }
248  }
249  }
250 };
251 
253 {
254 public:
255  using Ptr = std::shared_ptr<Costmap3dLayerBase>;
256 
257 protected:
260  bool root_;
261 
264 
268  nav_msgs::OccupancyGrid::ConstPtr map_updated_;
269 
270 public:
272  : ang_grid_(-1)
273  , overlay_mode_(MapOverlayMode::MAX)
274  , root_(true)
275  , map_(new CSpace3DMsg)
276  , map_overlay_(new CSpace3DMsg)
277  {
278  }
279 
280  virtual void loadConfig(XmlRpc::XmlRpcValue config) = 0;
281  virtual void setMapMetaData(const costmap_cspace_msgs::MapMetaData3D& info) = 0;
282 
284  const int ang_resolution)
285  {
286  ang_grid_ = ang_resolution;
287  }
289  const MapOverlayMode overlay_mode)
290  {
291  overlay_mode_ = overlay_mode;
292  }
294  {
295  child_ = child;
296  child_->setMap(getMapOverlay());
297  child_->root_ = false;
298  }
299  void setBaseMap(const nav_msgs::OccupancyGrid::ConstPtr& base_map)
300  {
301  ROS_ASSERT(root_);
302  ROS_ASSERT(ang_grid_ > 0);
303  ROS_ASSERT(base_map->data.size() >= base_map->info.width * base_map->info.height);
304 
305  const size_t xy_size = base_map->info.width * base_map->info.height;
306  map_->header = base_map->header;
307  map_->info.width = base_map->info.width;
308  map_->info.height = base_map->info.height;
309  map_->info.angle = ang_grid_;
310  map_->info.linear_resolution = base_map->info.resolution;
311  map_->info.angular_resolution = 2.0 * M_PI / ang_grid_;
312  map_->info.origin = base_map->info.origin;
313  map_->data.resize(xy_size * map_->info.angle);
314 
315  setMapMetaData(map_->info);
316 
317  for (size_t yaw = 0; yaw < map_->info.angle; yaw++)
318  {
319  for (unsigned int i = 0; i < xy_size; i++)
320  {
321  map_->data[i + yaw * xy_size] = -1;
322  }
323  }
324  updateCSpace(
325  base_map,
327  0, 0, 0,
328  map_->info.width, map_->info.height, map_->info.angle,
329  map_->header.stamp));
330  for (size_t yaw = 0; yaw < map_->info.angle; yaw++)
331  {
332  for (unsigned int i = 0; i < xy_size; i++)
333  {
334  if (base_map->data[i] < 0)
335  {
336  map_->data[i + yaw * xy_size] = -1;
337  }
338  }
339  }
340  *map_overlay_ = *map_;
341  if (child_)
342  child_->setBaseMapChain();
343 
344  updateChainEntry(
346  0, 0, 0, map_->info.width, map_->info.height, map_->info.angle,
347  base_map->header.stamp));
348  }
349  void processMapOverlay(const nav_msgs::OccupancyGrid::ConstPtr& msg)
350  {
351  ROS_ASSERT(!root_);
352  ROS_ASSERT(ang_grid_ > 0);
353  const int ox =
354  std::lround((msg->info.origin.position.x - map_->info.origin.position.x) /
355  map_->info.linear_resolution);
356  const int oy =
357  std::lround((msg->info.origin.position.y - map_->info.origin.position.y) /
358  map_->info.linear_resolution);
359 
360  const int w =
361  std::lround(msg->info.width * msg->info.resolution / map_->info.linear_resolution);
362  const int h =
363  std::lround(msg->info.height * msg->info.resolution / map_->info.linear_resolution);
364 
365  map_updated_ = msg;
366 
367  region_ = UpdatedRegion(ox, oy, 0, w, h, map_->info.angle, msg->header.stamp);
368  updateChainEntry(UpdatedRegion(ox, oy, 0, w, h, map_->info.angle, msg->header.stamp));
369  }
371  {
372  return map_;
373  }
375  {
376  map_ = map;
377  }
379  {
380  return map_overlay_;
381  }
382  int getAngularGrid() const
383  {
384  return ang_grid_;
385  }
386 
387 protected:
388  virtual bool updateChain(const bool output) = 0;
389  virtual void updateCSpace(
390  const nav_msgs::OccupancyGrid::ConstPtr& map,
391  const UpdatedRegion& region) = 0;
392  virtual int getRangeMax() const = 0;
393 
394  bool updateChainEntry(const UpdatedRegion& region, bool output = true)
395  {
396  region_.merge(region);
397 
398  auto region_prev_now = region_;
399  region_prev_now.merge(region_prev_);
400  region_prev_ = region_;
401 
402  region_prev_now.bitblt(map_overlay_, map_);
403  if (map_updated_)
404  {
405  if (map_->header.frame_id == map_updated_->header.frame_id)
406  {
407  updateCSpace(map_updated_, region_);
408  }
409  else
410  {
411  ROS_ERROR("map and map_overlay must have same frame_id. skipping");
412  }
413  }
414 
415  if (updateChain(output))
416  output = false;
417 
418  if (child_)
419  {
420  return child_->updateChainEntry(region_, output);
421  }
422  return false;
423  }
425  {
426  setMapMetaData(map_->info);
427  *map_overlay_ = *map_;
428  if (child_)
429  child_->setBaseMapChain();
430  }
431 };
432 } // namespace costmap_cspace
433 
434 #endif // COSTMAP_CSPACE_COSTMAP_3D_LAYER_BASE_H
void normalize(const int full_width, const int full_height)
Definition: base.h:178
UpdatedRegion(const int &x, const int &y, const int &yaw, const int &width, const int &height, const int &angle, const ros::Time &stamp=ros::Time())
Definition: base.h:119
MapOverlayMode overlay_mode_
Definition: base.h:259
static void copyCells(costmap_cspace_msgs::CSpace3DUpdate &to, const int &to_x, const int &to_y, const int &to_yaw, const CSpace3DMsg &from, const int &from_x, const int &from_y, const int &from_yaw, const int &copy_cell_num)
Definition: base.h:87
void bitblt(const CSpace3DMsg::Ptr &dest, const CSpace3DMsg::ConstPtr &src)
Definition: base.h:216
const int8_t & getCost(const int &x, const int &y, const int &yaw) const
Definition: base.h:58
void merge(const UpdatedRegion &region)
Definition: base.h:132
CSpace3DMsg::Ptr getMap()
Definition: base.h:370
void expand(const int &ex)
Definition: base.h:170
CSpace3DMsg::Ptr map_overlay_
Definition: base.h:263
Costmap3dLayerBase::Ptr child_
Definition: base.h:265
void setOverlayMode(const MapOverlayMode overlay_mode)
Definition: base.h:288
void setBaseMap(const nav_msgs::OccupancyGrid::ConstPtr &base_map)
Definition: base.h:299
int8_t & getCost(const int &x, const int &y, const int &yaw)
Definition: base.h:69
static void copyCells(CSpace3DMsg &to, const int &to_x, const int &to_y, const int &to_yaw, const CSpace3DMsg &from, const int &from_x, const int &from_y, const int &from_yaw, const int &copy_cell_num)
Definition: base.h:80
nav_msgs::OccupancyGrid::ConstPtr map_updated_
Definition: base.h:268
MapOverlayMode
Definition: base.h:96
void setAngleResolution(const int ang_resolution)
Definition: base.h:283
void processMapOverlay(const nav_msgs::OccupancyGrid::ConstPtr &msg)
Definition: base.h:349
TFSIMD_FORCE_INLINE Vector3 & normalize()
bool updateChainEntry(const UpdatedRegion &region, bool output=true)
Definition: base.h:394
TFSIMD_FORCE_INLINE const tfScalar & w() const
void setChild(Costmap3dLayerBase::Ptr child)
Definition: base.h:293
std::shared_ptr< CSpace3DMsg > Ptr
Definition: base.h:52
std::shared_ptr< Costmap3dLayerBase > Ptr
Definition: base.h:255
size_t address(const int &x, const int &y, const int &yaw) const
Definition: base.h:54
std::shared_ptr< const CSpace3DMsg > ConstPtr
Definition: base.h:53
#define ROS_ASSERT(cond)
#define ROS_ERROR(...)
CSpace3DMsg::Ptr getMapOverlay()
Definition: base.h:378
void setMap(CSpace3DMsg::Ptr map)
Definition: base.h:374


costmap_cspace
Author(s): Atsushi Watanabe
autogenerated on Wed May 12 2021 02:20:29