n-Dimensional Fast Methods  0.7
 All Classes Functions Variables Typedefs Pages
gmm.hpp
1 
28 #ifndef GMM_HPP_
29 #define GMM_HPP_
30 
31 #include <fast_methods/fm/eikonalsolver.hpp>
32 
33 template < class grid_t > class GMM : public EikonalSolver <grid_t> {
34 
35  public:
36  GMM(double dt = -1) : EikonalSolver<grid_t>("GMM"), deltau_(dt) {}
37 
38  GMM(const char * name, double dt = -1) : EikonalSolver<grid_t>(name), deltau_(dt) {}
39 
40  virtual ~GMM() { clear(); }
41 
42  void setup
43  () {
45  if (deltau_ < 0)
46  // Original paper dt:
47  //deltau_ = grid_->getLeafSize()/(grid_->getMaxSpeed()*sqrt(grid_t::getNDims()));
48 
49  // FIM paper dt:
50  deltau_ = 1/grid_->getMaxSpeed();
51  }
52 
54  virtual void computeInternal
55  () {
56  if (!setup_)
57  setup();
58 
59  unsigned int n_neighs;
60  unsigned int j = 0;
61  bool stopWavePropagation = false;
62 
63  // Algorithm initialization
64  tm_= std::numeric_limits<double>::infinity();
65  for (unsigned int &i: init_points_) { // For each initial point
66  grid_->getCell(i).setArrivalTime(0);
67  grid_->getCell(i).setState(FMState::FROZEN);
68  n_neighs = grid_->getNeighbors(i, neighbors_);
69  for (unsigned int s = 0; s < n_neighs; ++s){ // For each neighbor
70  j = neighbors_[s];
71  if ((grid_->getCell(j).getState() == FMState::FROZEN) || grid_->getCell(j).isOccupied())
72  continue;
73  else {
74  double new_arrival_time = solveEikonal(j);
75  if (new_arrival_time < tm_){
76  tm_ = new_arrival_time;
77  }
78  grid_->getCell(j).setArrivalTime(new_arrival_time);
79  grid_->getCell(j).setState(FMState::NARROW);
80  gamma_.push_back(j);
81  } // neighbors open.
82  } // For each neighbor.
83  } // For each initial point.
84 
85  // Main loop
86  while(!stopWavePropagation && !gamma_.empty()) {
87 
88  tm_ += deltau_;
89 
90  std::list<unsigned int>::reverse_iterator k = gamma_.rbegin();
91  std::list<unsigned int>::iterator i = k.base();//iterator points to the next element the reverse_iterator is currently pointing to
92  i--;
93  k = gamma_.rend();
94  std::list<unsigned int>::iterator q = k.base();
95  q--;//the end of a reverse list is the first element of that list
96  //This is needed because some functions, like std::list::erase, do not work with reverse iterators
97 
98  // First pass
99  for( ; i!=q; --i) {//for each gamma in the reverse order
100  if( grid_->getCell(*i).getArrivalTime() <= tm_) {
101  n_neighs = grid_->getNeighbors(*i, neighbors_);
102  for (unsigned int s = 0; s < n_neighs; ++s){ // For each neighbor of gamma
103  j = neighbors_[s];
104  if ( (grid_->getCell(j).getState() == FMState::FROZEN) || grid_->getCell(j).isOccupied() || (grid_->getCell(j).getVelocity() == 0)) // If Frozen,obstacle or velocity = 0
105  continue;
106  else {
107  double new_arrival_time = solveEikonal(j);
108  if (new_arrival_time < grid_->getCell(j).getArrivalTime()) // Updating narrow band if necessary.
109  grid_->getCell(j).setArrivalTime(new_arrival_time);
110  }
111  }//for each neighbor of gamma
112  }
113  }//for each gamma in the reverse order
114 
115  // Second pass
116  const size_t narrow_size = gamma_.size();
117  i = gamma_.begin();
118  for(size_t z = 0; z < narrow_size; ++z) {//for each gamma in the forward order
119  if( grid_->getCell(*i).getArrivalTime()<= tm_) {
120  n_neighs = grid_->getNeighbors(*i, neighbors_);
121  for (unsigned int s = 0; s < n_neighs; ++s) {// for each neighbor of gamma
122  j = neighbors_[s];
123  if ((grid_->getCell(j).getState() == FMState::FROZEN) || grid_->getCell(j).isOccupied() || (grid_->getCell(j).getVelocity() == 0)) // If Frozen,obstacle or velocity = 0
124  continue;
125  else {
126  double new_arrival_time = solveEikonal(j);
127  if (new_arrival_time < grid_->getCell(j).getArrivalTime()) {
128  grid_->getCell(j).setArrivalTime(new_arrival_time);
129  }
130  if (grid_->getCell(j).getState() == FMState::OPEN){
131  gamma_.push_back(j);
132  grid_->getCell(j).setState(FMState::NARROW);
133  }
134  }
135  }//for each neighbor of gamma
136  grid_->getCell(*i).setState(FMState::FROZEN);
137  if (*i == goal_idx_)
138  stopWavePropagation = true;
139  i = gamma_.erase(i);
140  }
141  else
142  ++i;
143  }//for each gamma in the forward order
144  }//while gamma is not zero
145  }//compute
146 
147  virtual void clear
148  () {
149  gamma_.clear();
150  }
151 
152  virtual void reset
153  () {
155  gamma_.clear();
156  tm_ = 0;
157  }
158 
159  protected:
167 
168  private:
170  double tm_;
171 
173  double deltau_;
174 
176  std::list<unsigned int> gamma_;
177 };
178 
179 #endif /* GMM_H_*/
Abstract class that serves as interface for the actual EikonalSolvers implemented. It requires (at least) the computeInternal method to be implemented,.
double deltau_
For each updating step, tm_ is increased by this value.
Definition: gmm.hpp:173
virtual void setup()
Checks that the solver is ready to run. Sets the grid unclean.
Definition: solver.hpp:94
virtual void reset()
Clears temporal data, so it is ready to run again.
Definition: gmm.hpp:153
std::array< unsigned int, 2 *grid_t::getNDims()> neighbors_
Auxiliar array which stores the neighbor of each iteration of the computeFM() function.
virtual double solveEikonal(const int &idx)
Solves nD Eikonal equation for cell idx. If heuristics are activated, it will add the estimated trave...
grid_t * grid_
Grid container.
Definition: solver.hpp:219
double tm_
Global bound that determines the group of cells of gamma that will be updated in each step...
Definition: gmm.hpp:170
std::vector< unsigned int > init_points_
Initial index.
Definition: solver.hpp:228
virtual void computeInternal()
Actual method that implements GMM.
Definition: gmm.hpp:55
bool setup_
Setup status.
Definition: solver.hpp:225
void setup()
Checks that the solver is ready to run. Sets the grid unclean.
Definition: gmm.hpp:43
virtual void clear()
Clears the solver, it is not recommended to be used out of the destructor.
Definition: gmm.hpp:148
unsigned int goal_idx_
Goal index.
Definition: solver.hpp:231
Templated class which computes Group Marching Method (GMM).
Definition: gmm.hpp:33
virtual void reset()
Clears temporal data, so it is ready to run again.
Definition: solver.hpp:176
std::list< unsigned int > gamma_
List wich stores the narrow band of each iteration.
Definition: gmm.hpp:176