blockmem_gridmap.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2017, 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 PLANNER_CSPACE_BLOCKMEM_GRIDMAP_H
31 #define PLANNER_CSPACE_BLOCKMEM_GRIDMAP_H
32 
33 #include <bitset>
34 #include <cassert>
35 #include <limits>
36 #include <memory>
37 
39 
40 namespace planner_cspace
41 {
42 template <class T, int DIM, int NONCYCLIC>
44 {
45 public:
46  virtual const CyclicVecInt<DIM, NONCYCLIC>& size() const = 0;
47  virtual size_t ser_size() const = 0;
48  virtual void clear(const T zero) = 0;
49  virtual void clear_partially(
50  const T zero, const CyclicVecInt<DIM, NONCYCLIC>& min, const CyclicVecInt<DIM, NONCYCLIC>& max) = 0;
51  virtual void copy_partially(
53  const CyclicVecInt<DIM, NONCYCLIC>& max) = 0;
54  virtual void copy_partially(
55  const CyclicVecInt<DIM, NONCYCLIC>& dst_min,
57  const CyclicVecInt<DIM, NONCYCLIC>& src_min,
58  const CyclicVecInt<DIM, NONCYCLIC>& src_max) = 0;
59  virtual void reset(const CyclicVecInt<DIM, NONCYCLIC>& size) = 0;
60  virtual T& operator[](const CyclicVecInt<DIM, NONCYCLIC>& pos) = 0;
61  virtual const T operator[](const CyclicVecInt<DIM, NONCYCLIC>& pos) const = 0;
62  virtual std::function<void(CyclicVecInt<DIM, NONCYCLIC>, size_t&, size_t&)> getAddressor() const = 0;
63  virtual bool validate(const CyclicVecInt<DIM, NONCYCLIC>& pos, const int tolerance = 0) const = 0;
64 };
65 
66 template <class T, int DIM, int NONCYCLIC, int BLOCK_WIDTH = 0x20, bool ENABLE_VALIDATION = false>
67 class BlockMemGridmap : public BlockMemGridmapBase<T, DIM, NONCYCLIC>
68 {
69 private:
70  static constexpr bool isPowOf2(const int v)
71  {
72  return v && ((v & (v - 1)) == 0);
73  }
74  static_assert(isPowOf2(BLOCK_WIDTH), "BLOCK_WIDTH must be power of 2");
75  static_assert(BLOCK_WIDTH > 0, "BLOCK_WIDTH must be >0");
76 
77  static constexpr size_t log2Recursive(const size_t v, const size_t depth = 0)
78  {
79  return v == 1 ? depth : log2Recursive(v >> 1, depth + 1);
80  }
81 
82 protected:
83  constexpr static size_t block_bit_ = log2Recursive(BLOCK_WIDTH);
84  constexpr static size_t block_bit_mask_ = (1 << block_bit_) - 1;
85 
86  std::unique_ptr<T[]> c_;
89  size_t ser_size_;
90  size_t ser_capacity_;
92  size_t block_num_;
93  T dummy_;
94 
95  inline void block_addr(
96  const CyclicVecInt<DIM, NONCYCLIC>& pos, size_t& baddr, size_t& addr) const
97  {
98  addr = 0;
99  baddr = 0;
100  for (int i = 0; i < NONCYCLIC; i++)
101  {
102  addr = (addr << block_bit_) + (pos[i] & block_bit_mask_);
103  baddr *= block_size_[i];
104  baddr += pos[i] >> block_bit_;
105  }
106  for (int i = NONCYCLIC; i < DIM; i++)
107  {
108  addr *= size_[i];
109  addr += pos[i];
110  }
111  }
112 
113 public:
114  std::function<void(CyclicVecInt<DIM, NONCYCLIC>, size_t&, size_t&)> getAddressor() const
115  {
116  return std::bind(
118  this,
119  std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
120  }
121  const CyclicVecInt<DIM, NONCYCLIC>& size() const override
122  {
123  return size_;
124  }
125  size_t ser_size() const override
126  {
127  return ser_size_;
128  }
129  void clear(const T zero) override
130  {
131  for (size_t i = 0; i < ser_size_; i++)
132  {
133  c_[i] = zero;
134  }
135  }
137  const T zero, const CyclicVecInt<DIM, NONCYCLIC>& min, const CyclicVecInt<DIM, NONCYCLIC>& max) override
138  {
140  for (p[0] = min[0]; p[0] <= max[0]; ++p[0])
141  {
142  for (p[1] = min[1]; p[1] <= max[1]; ++p[1])
143  {
144  for (p[2] = min[2]; p[2] <= max[2]; ++p[2])
145  {
146  assert(validate(p));
147  (*this)[p] = zero;
148  }
149  }
150  }
151  }
154  const CyclicVecInt<DIM, NONCYCLIC>& max) override
155  {
156  assert(DIM == 3); // copy_partially is available only for DIM=3
157 
159  for (p[0] = min[0]; p[0] <= max[0]; ++p[0])
160  {
161  for (p[1] = min[1]; p[1] <= max[1]; ++p[1])
162  {
163  for (p[2] = min[2]; p[2] <= max[2]; ++p[2])
164  {
165  assert(validate(p));
166  (*this)[p] = base[p];
167  }
168  }
169  }
170  }
172  const CyclicVecInt<DIM, NONCYCLIC>& dst_min,
174  const CyclicVecInt<DIM, NONCYCLIC>& src_min,
175  const CyclicVecInt<DIM, NONCYCLIC>& src_max) override
176  {
177  assert(DIM == 3); // copy_partially is available only for DIM=3
178 
179  CyclicVecInt<DIM, NONCYCLIC> p = src_min;
180  const CyclicVecInt<DIM, NONCYCLIC> offset = dst_min - src_min;
181 
182  for (p[0] = src_min[0]; p[0] <= src_max[0]; ++p[0])
183  {
184  for (p[1] = src_min[1]; p[1] <= src_max[1]; ++p[1])
185  {
186  for (p[2] = src_min[2]; p[2] <= src_max[2]; ++p[2])
187  {
188  assert(src.validate(p));
189  assert(validate(p + offset));
190  (*this)[p + offset] = src[p];
191  }
192  }
193  }
194  }
196  {
198 
199  for (int i = 0; i < NONCYCLIC; i++)
200  {
201  if (size_tmp[i] < BLOCK_WIDTH)
202  size_tmp[i] = BLOCK_WIDTH;
203  }
204 
205  block_ser_size_ = 1;
206  block_num_ = 1;
207  for (int i = 0; i < DIM; i++)
208  {
209  int width;
210  if (i < NONCYCLIC)
211  {
212  width = BLOCK_WIDTH;
213  block_size_[i] = (size_tmp[i] + width - 1) / width;
214  }
215  else
216  {
217  width = size_tmp[i];
218  block_size_[i] = 1;
219  }
220 
221  block_ser_size_ *= width;
222  block_num_ *= block_size_[i];
223  }
225 
227  {
229  c_.reset(new T[ser_size_]);
230  }
231  size_ = size;
232  }
234  : BlockMemGridmap()
235  {
236  reset(size_);
237  }
239  : ser_capacity_(0)
240  , dummy_(std::numeric_limits<T>::max())
241  {
242  }
243  T& operator[](const CyclicVecInt<DIM, NONCYCLIC>& pos) override
244  {
245  size_t baddr, addr;
246  block_addr(pos, baddr, addr);
247  const size_t a = baddr * block_ser_size_ + addr;
248  if (ENABLE_VALIDATION)
249  {
250  if (a >= ser_size_)
251  return dummy_;
252  }
253  return c_[a];
254  }
255  const T operator[](const CyclicVecInt<DIM, NONCYCLIC>& pos) const override
256  {
257  size_t baddr, addr;
258  block_addr(pos, baddr, addr);
259  const size_t a = baddr * block_ser_size_ + addr;
260  if (ENABLE_VALIDATION)
261  {
262  if (a >= ser_size_)
263  return std::numeric_limits<T>::max();
264  }
265  return c_[a];
266  }
267  bool validate(const CyclicVecInt<DIM, NONCYCLIC>& pos, const int tolerance = 0) const override
268  {
269  for (int i = 0; i < NONCYCLIC; i++)
270  {
271  if (pos[i] < tolerance || size_[i] - tolerance <= pos[i])
272  return false;
273  }
274  for (int i = NONCYCLIC; i < DIM; i++)
275  {
276  if (pos[i] < 0 || size_[i] <= pos[i])
277  return false;
278  }
279  return true;
280  }
281 
282  void clear_positive(const T zero)
283  {
284  for (size_t i = 0; i < ser_size_; i++)
285  {
286  if (c_[i] >= 0)
287  c_[i] = zero;
288  }
289  }
292  {
293  reset(gm.size_);
294  memcpy(c_.get(), gm.c_.get(), ser_size_ * sizeof(T));
295 
296  return *this;
297  }
298 };
299 } // namespace planner_cspace
300 
301 #endif // PLANNER_CSPACE_BLOCKMEM_GRIDMAP_H
planner_cspace::BlockMemGridmapBase::clear_partially
virtual void clear_partially(const T zero, const CyclicVecInt< DIM, NONCYCLIC > &min, const CyclicVecInt< DIM, NONCYCLIC > &max)=0
min
int min(int a, int b)
planner_cspace
Definition: bbf.h:33
planner_cspace::BlockMemGridmapBase::clear
virtual void clear(const T zero)=0
planner_cspace::BlockMemGridmap::BlockMemGridmap
BlockMemGridmap()
Definition: blockmem_gridmap.h:238
planner_cspace::BlockMemGridmap::validate
bool validate(const CyclicVecInt< DIM, NONCYCLIC > &pos, const int tolerance=0) const override
Definition: blockmem_gridmap.h:267
planner_cspace::BlockMemGridmap::getAddressor
std::function< void(CyclicVecInt< DIM, NONCYCLIC >, size_t &, size_t &)> getAddressor() const
Definition: blockmem_gridmap.h:114
planner_cspace::BlockMemGridmapBase::size
virtual const CyclicVecInt< DIM, NONCYCLIC > & size() const =0
planner_cspace::BlockMemGridmap::block_addr
void block_addr(const CyclicVecInt< DIM, NONCYCLIC > &pos, size_t &baddr, size_t &addr) const
Definition: blockmem_gridmap.h:95
planner_cspace::BlockMemGridmap::size_
CyclicVecInt< DIM, NONCYCLIC > size_
Definition: blockmem_gridmap.h:87
planner_cspace::BlockMemGridmap::operator[]
T & operator[](const CyclicVecInt< DIM, NONCYCLIC > &pos) override
Definition: blockmem_gridmap.h:243
planner_cspace::BlockMemGridmap::block_bit_mask_
constexpr static size_t block_bit_mask_
Definition: blockmem_gridmap.h:84
planner_cspace::BlockMemGridmap
Definition: blockmem_gridmap.h:67
planner_cspace::BlockMemGridmapBase::validate
virtual bool validate(const CyclicVecInt< DIM, NONCYCLIC > &pos, const int tolerance=0) const =0
planner_cspace::BlockMemGridmapBase::getAddressor
virtual std::function< void(CyclicVecInt< DIM, NONCYCLIC >, size_t &, size_t &)> getAddressor() const =0
planner_cspace::BlockMemGridmap::ser_size_
size_t ser_size_
Definition: blockmem_gridmap.h:89
planner_cspace::BlockMemGridmap::BlockMemGridmap
BlockMemGridmap(const CyclicVecInt< DIM, NONCYCLIC > &size_)
Definition: blockmem_gridmap.h:233
planner_cspace::BlockMemGridmapBase::operator[]
virtual T & operator[](const CyclicVecInt< DIM, NONCYCLIC > &pos)=0
planner_cspace::BlockMemGridmapBase
Definition: blockmem_gridmap.h:43
planner_cspace::BlockMemGridmapBase::reset
virtual void reset(const CyclicVecInt< DIM, NONCYCLIC > &size)=0
planner_cspace::BlockMemGridmap::copy_partially
void copy_partially(const BlockMemGridmapBase< T, DIM, NONCYCLIC > &base, const CyclicVecInt< DIM, NONCYCLIC > &min, const CyclicVecInt< DIM, NONCYCLIC > &max) override
Definition: blockmem_gridmap.h:152
planner_cspace::BlockMemGridmap::operator=
const BlockMemGridmap< T, DIM, NONCYCLIC, BLOCK_WIDTH, ENABLE_VALIDATION > & operator=(const BlockMemGridmap< T, DIM, NONCYCLIC, BLOCK_WIDTH, ENABLE_VALIDATION > &gm)
Definition: blockmem_gridmap.h:290
planner_cspace::BlockMemGridmap::isPowOf2
static constexpr bool isPowOf2(const int v)
Definition: blockmem_gridmap.h:70
planner_cspace::BlockMemGridmap::dummy_
T dummy_
Definition: blockmem_gridmap.h:93
planner_cspace::BlockMemGridmap::block_num_
size_t block_num_
Definition: blockmem_gridmap.h:92
planner_cspace::BlockMemGridmap::ser_capacity_
size_t ser_capacity_
Definition: blockmem_gridmap.h:90
planner_cspace::BlockMemGridmap::log2Recursive
static constexpr size_t log2Recursive(const size_t v, const size_t depth=0)
Definition: blockmem_gridmap.h:77
planner_cspace::BlockMemGridmap::reset
void reset(const CyclicVecInt< DIM, NONCYCLIC > &size) override
Definition: blockmem_gridmap.h:195
planner_cspace::BlockMemGridmap::clear_positive
void clear_positive(const T zero)
Definition: blockmem_gridmap.h:282
planner_cspace::BlockMemGridmap::ser_size
size_t ser_size() const override
Definition: blockmem_gridmap.h:125
planner_cspace::BlockMemGridmapBase::copy_partially
virtual void copy_partially(const BlockMemGridmapBase< T, DIM, NONCYCLIC > &base, const CyclicVecInt< DIM, NONCYCLIC > &min, const CyclicVecInt< DIM, NONCYCLIC > &max)=0
planner_cspace::BlockMemGridmap::c_
std::unique_ptr< T[]> c_
Definition: blockmem_gridmap.h:86
std
planner_cspace::BlockMemGridmap::block_bit_
constexpr static size_t block_bit_
Definition: blockmem_gridmap.h:83
planner_cspace::BlockMemGridmap::clear
void clear(const T zero) override
Definition: blockmem_gridmap.h:129
planner_cspace::BlockMemGridmap::copy_partially
void copy_partially(const CyclicVecInt< DIM, NONCYCLIC > &dst_min, const BlockMemGridmapBase< T, DIM, NONCYCLIC > &src, const CyclicVecInt< DIM, NONCYCLIC > &src_min, const CyclicVecInt< DIM, NONCYCLIC > &src_max) override
Definition: blockmem_gridmap.h:171
planner_cspace::BlockMemGridmap::clear_partially
void clear_partially(const T zero, const CyclicVecInt< DIM, NONCYCLIC > &min, const CyclicVecInt< DIM, NONCYCLIC > &max) override
Definition: blockmem_gridmap.h:136
planner_cspace::BlockMemGridmap::operator[]
const T operator[](const CyclicVecInt< DIM, NONCYCLIC > &pos) const override
Definition: blockmem_gridmap.h:255
cyclic_vec.h
planner_cspace::BlockMemGridmap::block_size_
CyclicVecInt< DIM, NONCYCLIC > block_size_
Definition: blockmem_gridmap.h:88
planner_cspace::BlockMemGridmap::block_ser_size_
size_t block_ser_size_
Definition: blockmem_gridmap.h:91
planner_cspace::BlockMemGridmap::size
const CyclicVecInt< DIM, NONCYCLIC > & size() const override
Definition: blockmem_gridmap.h:121
planner_cspace::CyclicVecBase
Definition: cyclic_vec.h:78
planner_cspace::BlockMemGridmapBase::ser_size
virtual size_t ser_size() const =0


planner_cspace
Author(s): Atsushi Watanabe
autogenerated on Fri May 16 2025 02:15:22