n-Dimensional Fast Methods  0.7
 All Classes Functions Variables Typedefs Pages
ndgridmap.hpp
1 
28 #ifndef NDGRIDMAP_HPP_
29 #define NDGRIDMAP_HPP_
30 
31 #include <iostream>
32 #include <vector>
33 #include <string>
34 #include <algorithm>
35 #include <cstddef>
36 #include <array>
37 #include <sstream>
38 
39 #include <utility>
40 
41 #include <fast_methods/console/console.h>
42 
46 
47 template <class T, size_t ndims> class nDGridMap {
48 
49  friend std::ostream& operator <<
50  (std::ostream & os, nDGridMap<T,ndims> & g) {
51  os << console::str_info("Grid cell information");
52  os << "\t" << g.getCell(0).type() << std::endl;
53  os << "\t" << g.ncells_ << " cells." << std::endl;
54  os << "\t" << g.leafsize_ << " leafsize (m)." << std::endl;
55  os << "\t" << ndims << " dimensions:" << std::endl;
56 
57  for (unsigned int i = 0; i < ndims; ++i)
58  os << "\t\t" << "d" << i << "\tsize: " << g.dimsize_[i] << std::endl;
59 
60  return os;
61  }
62 
63  public:
64 
65  nDGridMap () : leafsize_(1.0f), clean_(true) {}
66 
69  nDGridMap
70  (const std::array<unsigned int, ndims> & dimsize, double leafsize = 1.0f) :
71  leafsize_(leafsize),
72  clean_(true) {
73  resize(dimsize);
74  }
75 
77  void resize
78  (const std::array<unsigned int, ndims> & dimsize) {
79  dimsize_ = dimsize;
80  // Computing the total number of cells and the auxiliar array d_.
81  ncells_= 1;
82  for (unsigned int i = 0; i < ndims; ++i) {
83  ncells_ *= dimsize_[i];
84  d_[i] = ncells_;
85  }
86 
87  //Resizing gridmap and initializing with default values.
88  cells_.clear();
89  cells_.resize(ncells_, T());
90 
91  // Setting the index_ member of the cells, which a-priori is unknown.
92  for (unsigned int i = 0; i < cells_.size(); ++i)
93  cells_[i].setIndex(i);
94  clean_ = true;
95  }
96 
98  inline T & operator[]
99  (unsigned int idx) {
100  return cells_[idx];
101  }
102 
104  inline double getLeafSize() const { return leafsize_; }
105 
106  inline void setLeafSize(const double leafsize) { leafsize_ = leafsize; }
107 
109  inline T & getCell
110  (unsigned int idx) {
111  return cells_[idx];
112  }
113 
115  inline std::array<unsigned int, ndims> getDimSizes() const { return dimsize_;}
116 
118  double getMinValueInDim
119  (unsigned int idx, unsigned int dim) {
120  n_neighs = 0; // How many neighbors obtained in that dimension.
121  getNeighborsInDim(idx,n_,dim);
122 
123  if (n_neighs == 1)
124  return cells_[n_[0]].getValue();
125  else
126  return (cells_[n_[0]].getValue()<cells_[n_[1]].getValue()) ? cells_[n_[0]].getValue() : cells_[n_[1]].getValue();
127  }
128 
130  unsigned int getNumberNeighborsInDim
131  (int idx, std::array<unsigned int, ndims> &m, unsigned int dim) {
132  n_neighs = 0;
133  getNeighborsInDim(idx,n_,dim);
134  m = n_;
135  return n_neighs;
136  }
137 
141  unsigned int getNeighbors
142  (unsigned int idx, std::array<unsigned int, 2*ndims> & neighs) {
143  n_neighs = 0;
144  for (unsigned int i = 0; i < ndims; ++i)
145  getNeighborsInDim(idx,neighs,i);
146 
147  return n_neighs;
148  }
149 
154  void getNeighborsInDim
155  (unsigned int idx, std::array<unsigned int, 2*ndims>& neighs, unsigned int dim) {
156  unsigned int c1,c2; // Candidate neighbors in dimension.
157  if (dim == 0) {
158  c1 = idx-1;
159  c2 = idx+1;
160  }
161  else {
162  c1 = idx-d_[dim-1];
163  c2 = idx+d_[dim-1];
164  }
165  // Checking neighbor 1: is in the same n-dimensional slice (row, plane, cube, etc)?
166  if ((c1 >= 0) && (c1/d_[dim] == idx/d_[dim]))
167  neighs[n_neighs++] = c1;
168  // Checking neighbor 2. Full check, not necessary: if >ncells_ then is in another slice.
169  if (c2/d_[dim] == idx/d_[dim])
170  neighs[n_neighs++] = c2;
171  }
172 
174  void getNeighborsInDim
175  (unsigned int idx, std::array<unsigned int, 2>& neighs, unsigned int dim) {
176  // Candidate neighbors in dimension.
177  unsigned int c1,c2;
178  if (dim == 0) {
179  c1 = idx-1;
180  c2 = idx+1;
181  }
182  else {
183  c1 = idx-d_[dim-1];
184  c2 = idx+d_[dim-1];
185  }
186  // Checking neighbor 1: is in the same n-dimensional slice (row, plane, cube, etc)?
187  if ((c1 >= 0) && (c1/d_[dim] == idx/d_[dim]))
188  neighs[n_neighs++] = c1;
189  // Checking neighbor 2. Full check, not necessary: if >ncells_ then is in another slice.
190  if (c2/d_[dim] == idx/d_[dim])
191  neighs[n_neighs++] = c2;
192  }
193 
195  unsigned int idx2coord
196  (unsigned int idx, std::array<unsigned int, ndims> & coords) {
197  if (coords.size() != ndims)
198  return -1;
199  else {
200  coords[ndims-1] = idx/d_[ndims-2]; // First step done apart.
201  unsigned int aux = idx - coords[ndims-1]*d_[ndims-2];
202  for (unsigned int i = ndims - 2; i > 0; --i) {
203  coords[i] = aux/d_[i-1];
204  aux -= coords[i]*d_[i-1];
205  }
206  coords[0] = aux; //Last step done apart.
207  }
208  return 1;
209  }
210 
212  unsigned int coord2idx
213  (const std::array<unsigned int, ndims> & coords, unsigned int & idx) {
214  if (coords.size() != ndims)
215  return -1;
216  else {
217  idx = coords[0];
218  for(unsigned int i = 1; i < ndims; ++i)
219  idx += coords[i]*d_[i-1];
220  }
221  return 1;
222  }
223 
225  void showCoords
226  (unsigned int idx) {
227  std::array<unsigned int, ndims> coords;
228  idx2coord(idx, coords);
229  for (unsigned int i = 0; i < ndims; ++i)
230  std::cout << coords[i] << "\t";
231  std::cout << '\n';
232  }
233 
235  void showCoords
236  (std::array<unsigned int, ndims> coords) {
237  for (unsigned int i = 0; i < ndims; ++i)
238  std::cout << coords[i] << "\t";
239  std::cout << '\n';
240  }
241 
243  void showIdx
244  (const std::array<unsigned int, ndims> & coords) {
245  unsigned int idx;
246  coord2idx(coords, idx);
247  std::cout << idx << '\n';
248  }
249 
251  inline unsigned int size
252  () const {
253  return ncells_;
254  }
255 
257  inline double getMaxValue
258  () const {
259  double max = 0;
260  for (const T & c:cells_) {
261  if (!isinf(c.getValue()) && c.getValue() > max)
262  max = c.getValue();
263  }
264  return max;
265  }
266 
268  inline bool isClean
269  () const {
270  return clean_;
271  }
272 
274  inline void setClean
275  (bool c) {
276  clean_ = c;
277  }
278 
280  void clean
281  () {
282  if(!clean_) {
283  for (T & c:cells_)
284  c.setDefault();
285  clean_ = true;
286  }
287  }
288 
290  void clear
291  () {
292  cells_.clear();
293  occupied_.clear();
294  }
295 
297  std::string getDimSizesStr()
298  {
299  std::stringstream ss;
300  for(const auto& d : dimsize_)
301  ss << d << "\t";
302  return ss.str();
303  }
304 
306  inline void setOccupiedCells
307  (const std::vector<unsigned int> & obs) {
308  occupied_ = obs;
309  }
310 
312  inline void setOccupiedCells
313  (std::vector<unsigned int>&& obs) {
314  occupied_ = std::move(obs);
315  }
316 
318  inline void getOccupiedCells
319  (std::vector<unsigned int> & obs) const {
320  obs = occupied_;
321  }
322 
324  static constexpr size_t getNDims() {return ndims;}
325 
327  double getAvgSpeed
328  () {
329  double sum = 0;
330  unsigned int nObs = 0;
331  for (const T & c : cells_) {
332  if (!c.isOccupied())
333  sum += c.getVelocity();
334  else
335  ++nObs;
336  }
337  return sum/(ncells_ - nObs);
338  }
339 
341  double getMaxSpeed
342  () {
343  double max = 0;
344  for (const T & c : cells_)
345  if (max < c.getVelocity())
346  max = c.getVelocity();
347  return max;
348  }
349 
350  private:
352  std::vector<T> cells_;
353 
355  std::array<unsigned int, ndims> dimsize_;
356 
358  double leafsize_;
359 
361  unsigned int ncells_;
362 
364  bool clean_;
365 
366  // Auxiliar vectors to speed things up.
370  std::array<unsigned int, ndims> d_;
371 
374  std::array<unsigned int, 2> n_;
375 
378  unsigned int n_neighs;
379 
381  std::vector<unsigned int> occupied_;
382 };
383 
384 #endif /* NDGRIDCELL_HPP_*/
void getOccupiedCells(std::vector< unsigned int > &obs) const
Returns the indices of the occupied cells of the grid.
Definition: ndgridmap.hpp:319
std::array< unsigned int, ndims > dimsize_
Size of each dimension.
Definition: ndgridmap.hpp:355
void resize(const std::array< unsigned int, ndims > &dimsize)
Resizes each dimension of the grid according dimsize.
Definition: ndgridmap.hpp:78
static constexpr size_t getNDims()
Makes the number of dimensions of the grid available at compilation time.
Definition: ndgridmap.hpp:324
static std::string str_info(const std::string &val)
double getMinValueInDim(unsigned int idx, unsigned int dim)
Returns the minimum value of neighbors of cell idx in dimension dim.
Definition: ndgridmap.hpp:119
unsigned int getNumberNeighborsInDim(int idx, std::array< unsigned int, ndims > &m, unsigned int dim)
Returns number of valid neighbors for cell idx in dimension dim, stored in m.
Definition: ndgridmap.hpp:131
void setOccupiedCells(const std::vector< unsigned int > &obs)
Sets the cells which are occupied. Usually called by grid loaders.
Definition: ndgridmap.hpp:307
bool clean_
Flag to indicate if the grid is ready to use.
Definition: ndgridmap.hpp:364
double getMaxValue() const
Returns the maximum value of the cells in the grid.
Definition: ndgridmap.hpp:258
std::vector< T > cells_
Main container for the class.
Definition: ndgridmap.hpp:352
Templated class which represents a n-dimensional grid map. Its cells are assumed to be cubic...
Definition: ndgridmap.hpp:47
double getMaxSpeed()
Returns the maximum speed (occupancy value) in the grid.
Definition: ndgridmap.hpp:342
void getNeighborsInDim(unsigned int idx, std::array< unsigned int, 2 *ndims > &neighs, unsigned int dim)
Computes the indices of the 4-connectivity neighbors of cell idx in a specified direction dim...
Definition: ndgridmap.hpp:155
double getAvgSpeed()
Returns the avegare velocity ignoring those with 0 velocitie (obstacles).
Definition: ndgridmap.hpp:328
void clean()
Cleans the grid if it is not clean already. Calls Cell::setDefault()
Definition: ndgridmap.hpp:281
double leafsize_
Real size of the cells. It is assumed that the cells in the grid are cubic.
Definition: ndgridmap.hpp:358
unsigned int n_neighs
Internal variable that counts the number of neighbors found in every iteration. Modified by getNeighb...
Definition: ndgridmap.hpp:378
unsigned int idx2coord(unsigned int idx, std::array< unsigned int, ndims > &coords)
Transforms from index to coordinates.
Definition: ndgridmap.hpp:196
unsigned int ncells_
Number of cells in the grid (size)
Definition: ndgridmap.hpp:361
std::vector< unsigned int > occupied_
Caches the occupied cells (obstacles).
Definition: ndgridmap.hpp:381
void clear()
Erases the content of the grid. Must be resized later.
Definition: ndgridmap.hpp:291
T & getCell(unsigned int idx)
Returns the cell with index idx.
Definition: ndgridmap.hpp:110
std::array< unsigned int, ndims > getDimSizes() const
Returns the size of each dimension.
Definition: ndgridmap.hpp:115
unsigned int size() const
Returns number of cells in the grid.
Definition: ndgridmap.hpp:252
std::array< unsigned int, 2 > n_
Auxiliar array to speed up neighbor and indexing generalization: for getMinValueInDim() function...
Definition: ndgridmap.hpp:374
void showIdx(const std::array< unsigned int, ndims > &coords)
Shows the index from the coordinates.
Definition: ndgridmap.hpp:244
unsigned int getNeighbors(unsigned int idx, std::array< unsigned int, 2 *ndims > &neighs)
Computes the indices of the 4-connectivity neighbors. As it is based on arrays (to improve performanc...
Definition: ndgridmap.hpp:142
void setClean(bool c)
Sets the state of the grid. True means clean.
Definition: ndgridmap.hpp:275
unsigned int coord2idx(const std::array< unsigned int, ndims > &coords, unsigned int &idx)
Transforms from coordinates to index.
Definition: ndgridmap.hpp:213
std::string getDimSizesStr()
Returns "size(dim(0)) \t size(dim(1)) \t...".
Definition: ndgridmap.hpp:297
double getLeafSize() const
Returns the leaf size of the grid.
Definition: ndgridmap.hpp:104
void showCoords(unsigned int idx)
Shows the coordinates from an index.
Definition: ndgridmap.hpp:226
std::array< unsigned int, ndims > d_
Auxiliar array to speed up neighbor and indexing generalization: stores parcial multiplications of di...
Definition: ndgridmap.hpp:370
bool isClean() const
Returns if the grid is clean (ready to use)
Definition: ndgridmap.hpp:269