ThetaStar.cpp
Go to the documentation of this file.
1 
7 #include "ThetaStar.h"
8 
9 ThetaStar::ThetaStar(const Map &map, const EnvironmentOptions &options, const Point &start, const Point &goal, const float &radius)
10  : PathPlanner(map, options, start, goal, radius)
11 {
12  currPath = std::list<Point>();
13  close = std::unordered_map<int, Node>();
14  open = std::vector<std::list<Node>>();
15  openSize = 0;
16  glPathCreated = false;
17  visChecker = LineOfSight(this->radius/ map.GetCellSize());
18 }
19 
20 
22 {
23  currPath = obj.currPath;
24  close = obj.close;
25  open = obj.open;
26  openSize = obj.openSize;
27  glPathCreated = obj.glPathCreated;
28  visChecker = obj.visChecker;
29 
30 }
31 
32 
34 
35 
36 bool ThetaStar::GetNext(const Point &curr, Point &next)
37 {
38  if(glPathCreated)
39  {
40  if(currPath.size() == 0)
41  {
42  next = curr;
43  return true;
44  }
45 
46  if(currPath.size() > 1)
47  {
48  float sqDistToCurr = (currPath.front() - curr).SquaredEuclideanNorm();
49  float sqDelta = options->delta * options->delta;
50  if(sqDistToCurr < sqDelta)
51  {
52  currPath.pop_front();
53  next = currPath.front();
54  return true;
55  }
56  }
57 
58  Node currNode = map->GetClosestNode(curr), nextNode = map->GetClosestNode(currPath.front());
59  if(currNode == nextNode || visChecker.checkLine(currNode.i, currNode.j, nextNode.i, nextNode.j, *map))
60  {
61  next = currPath.front();
62  return true;
63  }
64 
65  Point last = currPath.front();
66  currPath.pop_front();
67 
68  bool isLastAccessible = SearchPath(map->GetClosestNode(curr), map->GetClosestNode(last));
69  if(isLastAccessible)
70  {
71  next = currPath.front();
72  return true;
73  }
74 
75  }
76  return false;
77 }
78 
79 
80 bool ThetaStar::SearchPath(const Node &start, const Node &goal)
81 {
82  if(glPathCreated)
83  {
84  close.clear();
85  for(auto &l : open)
86  {
87  l.clear();
88  }
89  openSize = 0;
90  }
91  else
92  {
93  open.resize(map->GetHeight());
94  }
95 
96  Node curNode;
97  curNode.i = start.i;
98  curNode.j = start.j;
99  curNode.g = 0;
100  curNode.H = ComputeHFromCellToCell(curNode.i, curNode.j, goal.i, goal.j);
101  curNode.F = options->hweight * curNode.H;
102  curNode.parent = nullptr;
103  AddOpen(curNode);
104  int closeSize = 0;
105  bool pathfound = false;
106  while (!StopCriterion())
107  {
108  curNode = FindMin();
109  close.insert({curNode.i * map->GetWidth() + curNode.j, curNode});
110  closeSize++;
111  open[curNode.i].pop_front();
112  openSize--;
113  if (curNode == goal)
114  {
115  pathfound = true;
116  break;
117  }
118  std::list<Node> successors = FindSuccessors(curNode);
119  std::list<Node>::iterator it = successors.begin();
120  auto parent = &(close.find(curNode.i * map->GetWidth() + curNode.j)->second);
121  while (it != successors.end()) {
122  it->parent = parent;
123  it->H = ComputeHFromCellToCell(it->i, it->j, goal.i, goal.j);
124  *it = ResetParent(*it, *it->parent);
125  it->F = it->g + options->hweight * it->H;
126  AddOpen(*it);
127  it++;
128  }
129  }
130 
131  if (pathfound)
132  {
133  MakePrimaryPath(curNode);
134  }
135  return pathfound;
136 }
137 
138 
139 bool ThetaStar::StopCriterion() const
140 {
141  if (!openSize)
142  {
143  return true;
144  }
145  return false;
146 }
147 
148 
149 void ThetaStar::AddOpen(Node newNode)
150 {
151  std::list<Node>::iterator iter, pos;
152 
153  if (open[newNode.i].size() == 0) {
154  open[newNode.i].push_back(newNode);
155  openSize++;
156  return;
157  }
158 
159  pos = open[newNode.i].end();
160  bool posFound = false;
161  for (iter = open[newNode.i].begin(); iter != open[newNode.i].end(); ++iter)
162  {
163  if (!posFound && iter->F >= newNode.F)
164  {
165  if(iter->F == newNode.F)
166  {
167  if((options->breakingties == CN_SP_BT_GMAX && newNode.g >= iter->g)
168  || (options->breakingties == CN_SP_BT_GMIN && newNode.g <= iter->g))
169  {
170  pos = iter;
171  posFound = true;
172  }
173  }
174  else
175  {
176  pos = iter;
177  posFound = true;
178  }
179  }
180  if (iter->j == newNode.j)
181  {
182  if (newNode.F >= iter->F)
183  return;
184  else
185  {
186  if (pos == iter)
187  {
188  iter->F = newNode.F;
189  iter->g = newNode.g;
190  iter->parent = newNode.parent;
191  return;
192  }
193  open[newNode.i].erase(iter);
194  openSize--;
195  break;
196  }
197  }
198  }
199  openSize++;
200  open[newNode.i].insert(pos, newNode);
201 }
202 
203 
204 Node ThetaStar::FindMin()
205 {
206  Node min;
207  min.F = std::numeric_limits<double>::infinity();
208  for (int i = 0; i < open.size(); i++)
209  {
210  if(!open[i].empty() && open[i].begin()->F <= min.F)
211  {
212  if(open[i].begin()->F == min.F)
213  {
214  if((options->breakingties == CN_SP_BT_GMAX && open[i].begin()->g >= min.g)
215  || (options->breakingties == CN_SP_BT_GMIN && open[i].begin()->g <= min.g))
216  {
217  min = *open[i].begin();
218  }
219  }
220  else
221  {
222  min = *open[i].begin();
223  }
224  }
225  }
226  return min;
227 }
228 
229 
230 float ThetaStar::ComputeHFromCellToCell(int i1, int j1, int i2, int j2) const
231 {
232  switch (options->metrictype)
233  {
234  case CN_SP_MT_EUCL:
235  return static_cast<float>(sqrt((i2 - i1)*(i2 - i1)+(j2 - j1)*(j2 - j1)));
236  case CN_SP_MT_DIAG:
237  return static_cast<float>(abs(abs(i2 - i1) - abs(j2 - j1)) + sqrt(2) * (std::min(abs(i2 - i1),abs(j2 - j1))));
238  case CN_SP_MT_MANH:
239  return (abs(i2 - i1) + abs(j2 - j1));
240  case CN_SP_MT_CHEB:
241  return std::max(abs(i2 - i1),abs(j2 - j1));
242  default:
243  return 0;
244  }
245 }
246 
247 
248 Node ThetaStar::ResetParent(Node current, Node parent)
249 {
250 
251  if (parent.parent == nullptr)
252  return current;
253  if(current == *parent.parent)
254  return current;
255 
256  if (visChecker.checkLine(parent.parent->i, parent.parent->j, current.i, current.j, *map))
257  {
258  current.g = parent.parent->g + Distance(parent.parent->i, parent.parent->j, current.i, current.j);
259  current.parent = parent.parent;
260  return current;
261  }
262  return current;
263 }
264 
265 
266 float ThetaStar::Distance(int i1, int j1, int i2, int j2) const
267 {
268  return static_cast<float>(sqrt(pow(i1 - i2, 2.0f) + pow(j1 - j2, 2.0f)));
269 }
270 
271 
272 void ThetaStar::MakePrimaryPath(Node curNode)
273 {
274 
275 
276  Node current = curNode;
277  while(current.parent)
278  {
279  currPath.push_front(map->GetPoint(current));
280  current = *current.parent;
281  }
282  //std::cout<<map->GetPoint(current).ToString();
283 }
284 
285 
286 std::list<Node> ThetaStar::FindSuccessors(Node curNode)
287 {
288  Node newNode;
289  std::list<Node> successors;
290  for (int i = -1; i <= +1; i++)
291  for (int j = -1; j <= +1; j++)
292  if ((i != 0 || j != 0) && map->CellOnGrid(curNode.i + i, curNode.j + j) &&
293  (visChecker.checkTraversability(curNode.i + i, curNode.j + j, *map)))
294  {
295  if (i != 0 && j != 0)
296  {
297  if (!options->cutcorners)
298  {
299  if (map->CellIsObstacle(curNode.i, curNode.j + j) ||
300  map->CellIsObstacle(curNode.i + i, curNode.j))
301  continue;
302  }
303  else if (!options->allowsqueeze)
304  {
305  if (map->CellIsObstacle(curNode.i, curNode.j + j) &&
306  map->CellIsObstacle(curNode.i + i, curNode.j))
307  continue;
308  }
309  }
310  if (close.find((curNode.i + i) * map->GetWidth() + curNode.j + j) == close.end())
311  {
312  newNode.i = curNode.i + i;
313  newNode.j = curNode.j + j;
314  if(i == 0 || j == 0)
315  newNode.g = curNode.g + 1;
316  else
317  newNode.g = curNode.g + sqrt(2);
318  successors.push_front(newNode);
319  }
320  }
321  return successors;
322 }
323 
324 
326 {
327  if(!glPathCreated)
328  {
329  Node start = map->GetClosestNode(glStart);
330  Node goal = map->GetClosestNode(glGoal);
331 
332  glPathCreated = SearchPath(start, goal);
333  //currPath.push_back(glGoal);
334  }
335  return glPathCreated;
336 }
337 
339 {
340  if(this != &obj)
341  {
343  currPath = obj.currPath;
344  close = obj.close;
345  open = obj.open;
346  openSize = obj.openSize;
347  glPathCreated = obj.glPathCreated;
348  visChecker = obj.visChecker;
349  }
350  return *this;
351 }
352 
354 {
355  return new ThetaStar(*this);
356 }
357 
bool CreateGlobalPath() override
Finds path from global start to global goal position using Theta* algorithm.
Definition: ThetaStar.cpp:325
PathPlanner class implements base pathfinder interface and behavior.
Definition: PathPlanner.h:25
ThetaStar(const Map &map, const EnvironmentOptions &options, const Point &start, const Point &goal, const float &radius)
ThetaStar constructor with parametes.
Definition: ThetaStar.cpp:9
The Node class defines a cell of grid (see Map class)
Definition: Geom.h:21
double g
g-value of node for A* based algorithms.
Definition: Geom.h:26
float GetCellSize() const
Return size of cell side.
Definition: Map.cpp:133
The Point class defines a position (or euclidean vector from (0,0)) in 2D space.
Definition: Geom.h:61
#define CN_SP_BT_GMIN
Gmin constant.
Definition: Const.h:139
#define CN_SP_MT_EUCL
Euclid distance constant.
Definition: Const.h:104
~ThetaStar() override
ThetaStar destructor.
Definition: ThetaStar.cpp:33
File contains ThetaStar class.
#define CN_SP_MT_MANH
Manhattan distance constant.
Definition: Const.h:103
ThetaStar & operator=(const ThetaStar &obj)
Assignment operator.
Definition: ThetaStar.cpp:338
#define CN_SP_MT_CHEB
Chebyshev distance constant.
Definition: Const.h:105
bool GetNext(const Point &curr, Point &next) override
Returns current goal of agent from global path.
Definition: ThetaStar.cpp:36
Class EnvironmentOptions contains environment and algoritms parameters.
double F
F = g + h. Value for A* based algorithms.
Definition: Geom.h:28
Map class describes static environment.
Definition: Map.h:36
#define CN_SP_MT_DIAG
Diagonal distance constant.
Definition: Const.h:102
ThetaStar * Clone() const override
Method for cloning inheritors objects. Creates copy of object in memmory and return pointer to copy...
Definition: ThetaStar.cpp:353
int i
The number of row. Part of (i,j) address of cell on grid.
Definition: Geom.h:24
ThetaStar class implements Theta* algorithm, which creates path from start to goal position...
Definition: ThetaStar.h:22
int j
The number of column. Part of (i,j) address of cell on grid.
Definition: Geom.h:25
PathPlanner & operator=(const PathPlanner &obj)
Assignment operator.
Definition: PathPlanner.h:75
#define CN_SP_BT_GMAX
Gmax constant.
Definition: Const.h:140
This class implements line-of-sight function between two cells on the grid for a variable size of age...
Definition: LineOfSight.h:30
Node * parent
The node from which the transition to this node was made. Value for A* based algorithms.
Definition: Geom.h:29
double H
h-value of node for A* based algorithms.
Definition: Geom.h:27


ORCAStar
Author(s): Stepan Drgachev
autogenerated on Wed Jul 15 2020 16:13:14