findpath.cpp
Go to the documentation of this file.
1 
3 // STL A* Search implementation
4 // (C)2001 Justin Heyes-Jones
5 //
6 // Finding a path on a simple grid maze
7 // This shows how to do shortest path finding using A*
8 
10 
11 #include "stlastar.h" // See header for copyright and usage information
12 
13 #include <iostream>
14 #include <math.h>
15 
16 #define DEBUG_LISTS 0
17 #define DEBUG_LIST_LENGTHS_ONLY 0
18 
19 using namespace std;
20 //using namespace astar;
21 
22 // map helper functions
23 
24 static uint8_t* _map = NULL;
25 static unsigned int _map_width=0, _map_height=0;
26 
27 uint8_t GetMap( unsigned int x, unsigned int y )
28 {
29  assert(_map);
30 
31  if(x >= _map_width || y >= _map_height)
32  return 9;
33 
34  return _map[(y*_map_width)+x];
35 }
36 
37 // Definitions
38 
40 {
41 public:
42  unsigned int x; // the (x,y) positions of the node
43  unsigned int y;
44 
45  MapSearchNode() { x = y = 0; }
46  MapSearchNode( unsigned int px, unsigned int py ) { x=px; y=py; }
47 
48  float GoalDistanceEstimate( MapSearchNode &nodeGoal );
49  bool IsGoal( MapSearchNode &nodeGoal );
50  bool GetSuccessors( AStarSearch<MapSearchNode> *astarsearch, MapSearchNode *parent_node );
51  float GetCost( MapSearchNode &successor );
52  bool IsSameState( MapSearchNode &rhs );
53 
54  void PrintNodeInfo();
55 
56 
57 };
58 
60 {
61 
62  // same state in a maze search is simply when (x,y) are the same
63  if( (x == rhs.x) &&
64  (y == rhs.y) )
65  {
66  return true;
67  }
68  else
69  {
70  return false;
71  }
72 
73 }
74 
76 {
77  //cout << x << "\t" << y << endl;
78  cout << "Node position : (" << x << ", " << y << ")" << endl;
79 }
80 
81 // Here's the heuristic function that estimates the distance from a Node
82 // to the Goal.
83 
85 {
86  float xd = fabs(float(((float)x - (float)nodeGoal.x)));
87  float yd = fabs(float(((float)y - (float)nodeGoal.y)));
88  return xd + yd;
89  //return 1.001 * (xd + yd );
90 }
91 
93 {
94 
95  if( (x == nodeGoal.x) &&
96  (y == nodeGoal.y) )
97  {
98  return true;
99  }
100 
101  return false;
102 }
103 
104 // This generates the successors to the given Node. It uses a helper function called
105 // AddSuccessor to give the successors to the AStar class. The A* specific initialisation
106 // is done for each node internally, so here you just set the state information that
107 // is specific to the application
109  MapSearchNode *parent_node )
110 {
111 
112  int parent_x = -1;
113  int parent_y = -1;
114 
115  if( parent_node )
116  {
117  parent_x = parent_node->x;
118  parent_y = parent_node->y;
119  }
120 
121  MapSearchNode NewNode;
122 
123  int ix = (int)x;
124  int iy = (int)y;
125 
126  // push each possible move except allowing the search to go backwards
127 
128  if( (GetMap( ix-1, iy ) < 9u)
129  && !((parent_x == ix-1) && (parent_y == iy))
130  )
131  {
132  NewNode = MapSearchNode( ix-1, iy );
133  astarsearch->AddSuccessor( NewNode );
134  }
135 
136  if( (GetMap( ix, iy-1 ) < 9u)
137  && !((parent_x == ix) && (parent_y == iy-1))
138  )
139  {
140  NewNode = MapSearchNode( ix, iy-1 );
141  astarsearch->AddSuccessor( NewNode );
142  }
143 
144  if( (GetMap( ix+1, iy ) < 9u)
145  && !((parent_x == ix+1) && (parent_y == iy))
146  )
147  {
148  NewNode = MapSearchNode( ix+1, iy );
149  astarsearch->AddSuccessor( NewNode );
150  }
151 
152 
153  if( (GetMap( ix, iy+1 ) < 9u)
154  && !((parent_x == ix) && (parent_y == iy+1))
155  )
156  {
157  NewNode = MapSearchNode( ix, iy+1 );
158  astarsearch->AddSuccessor( NewNode );
159  }
160 
161  return true;
162 }
163 
164 // given this node, what does it cost to move to successor. In the case
165 // of our map the answer is the map terrain value at this node since that is
166 // conceptually where we're moving
167 
169 {
170  return (float) GetMap( x, y );
171 
172 }
173 
174 
175 // Main
176 
177 #include "astar.h"
178 using namespace ast;
179 
180 bool ast::astar( uint8_t* map,
181  uint32_t width,
182  uint32_t height,
183  const point_t start,
184  const point_t goal,
185  std::vector<point_t>& path )
186 {
187  //cout << "STL A* Search implementation\n(C)2001 Justin Heyes-Jones\n";
188 
189  // set the static vars
190  _map = map;
191  _map_width = width;
192  _map_height = height;
193 
194  // Our sample problem defines the world as a 2d array representing a terrain
195  // Each element contains an integer from 0 to 5 which indicates the cost
196  // of travel across the terrain. Zero means the least possible difficulty
197  // in travelling (think ice rink if you can skate) whilst 5 represents the
198  // most difficult. 9 indicates that we cannot pass.
199 
200  // Create an instance of the search class...
201 
202  AStarSearch<MapSearchNode> astarsearch;
203 
204  unsigned int SearchCount = 0;
205 
206  const unsigned int NumSearches = 1;
207 
208  bool path_found = false;
209 
210  while(SearchCount < NumSearches)
211  {
212 
213  // Create a start state
214  MapSearchNode nodeStart;
215  nodeStart.x = start.x;
216  nodeStart.y = start.y;
217 
218  // Define the goal state
219  MapSearchNode nodeEnd;
220  nodeEnd.x = goal.x;
221  nodeEnd.y = goal.y;
222 
223  // Set Start and goal states
224 
225  astarsearch.SetStartAndGoalStates( nodeStart, nodeEnd );
226 
227  unsigned int SearchState;
228  unsigned int SearchSteps = 0;
229 
230  do
231  {
232  SearchState = astarsearch.SearchStep();
233 
234  SearchSteps++;
235 
236  #if DEBUG_LISTS
237 
238  cout << "Steps:" << SearchSteps << "\n";
239 
240  int len = 0;
241 
242  cout << "Open:\n";
243  MapSearchNode *p = astarsearch.GetOpenListStart();
244  while( p )
245  {
246  len++;
247 #if !DEBUG_LIST_LENGTHS_ONLY
248  ((MapSearchNode *)p)->PrintNodeInfo();
249 #endif
250  p = astarsearch.GetOpenListNext();
251 
252  }
253 
254  cout << "Open list has " << len << " nodes\n";
255 
256  len = 0;
257 
258  cout << "Closed:\n";
259  p = astarsearch.GetClosedListStart();
260  while( p )
261  {
262  len++;
263 #if !DEBUG_LIST_LENGTHS_ONLY
264  p->PrintNodeInfo();
265 #endif
266  p = astarsearch.GetClosedListNext();
267  }
268 
269  cout << "Closed list has " << len << " nodes\n";
270 #endif
271 
272  }
274 
276  {
277  //cout << "Search found goal state\n";
278 
279  MapSearchNode *node = astarsearch.GetSolutionStart();
280 
281 #if DISPLAY_SOLUTION
282  cout << "Displaying solution\n";
283 #endif
284  int steps = 0;
285 
286  //node->PrintNodeInfo();
287 
288  path.push_back( point_t( node->x, node->y ) );
289 
290  for( ;; )
291  {
292  node = astarsearch.GetSolutionNext();
293 
294  if( !node )
295  {
296  break;
297  }
298 
299  //node->PrintNodeInfo();
300 
301  path.push_back( point_t( node->x, node->y ) );
302 
303  steps ++;
304 
305  };
306 
307  //cout << "Solution steps " << steps << endl;
308 
309  // Once you're done with the solution you can free the nodes up
310  astarsearch.FreeSolutionNodes();
311 
312  path_found = true;
313 
314  }
315  else if( SearchState == AStarSearch<MapSearchNode>::SEARCH_STATE_FAILED )
316  {
317  cout << "Search terminated. Did not find goal state\n";
318 
319  }
320 
321  // Display the number of loops the search went through
322  //cout << "SearchSteps : " << SearchSteps << "\n";
323 
324  SearchCount ++;
325 
326  astarsearch.EnsureMemoryFreed();
327  }
328 
329  return path_found;
330 }
331 
332 // // STL container iterator macros
333 // #define VAR(V,init) __typeof(init) V=(init)
334 // #define FOR_EACH(I,C) for(VAR(I,(C).begin());I!=(C).end();I++)
335 
336 // int main( int argc, char *argv[] )
337 // {
338 // std::vector<point_t> path;
339 
340 // bool result = astar( map, 30, 30, point_t( 1,1 ), point_t( 25,20 ), path );
341 
342 // printf( "#%s:\n", result ? "PATH" : "NOPATH" );
343 
344 // FOR_EACH( it, path )
345 // printf( "%d, %d\n", it->x, it->y );
346 // puts("");
347 // }
348 
bool GetSuccessors(AStarSearch< MapSearchNode > *astarsearch, MapSearchNode *parent_node)
Definition: findpath.cpp:108
bool astar(uint8_t *map, uint32_t width, uint32_t height, const point_t start, const point_t goal, std::vector< point_t > &path)
Definition: findpath.cpp:180
UserState * GetOpenListStart()
Definition: stlastar.h:509
bool IsSameState(MapSearchNode &rhs)
Definition: findpath.cpp:59
UserState * GetOpenListNext()
Definition: stlastar.h:529
Definition: astar.h:2
static uint8_t * _map
Definition: findpath.cpp:24
uint32_t x
Definition: astar.h:8
UserState * GetClosedListStart()
Definition: stlastar.h:549
MapSearchNode(unsigned int px, unsigned int py)
Definition: findpath.cpp:46
void EnsureMemoryFreed()
Definition: stlastar.h:595
UserState * GetClosedListNext()
Definition: stlastar.h:570
void SetStartAndGoalStates(UserState &Start, UserState &Goal)
Definition: stlastar.h:135
unsigned int x
Definition: findpath.cpp:42
float GetCost(MapSearchNode &successor)
Definition: findpath.cpp:168
void FreeSolutionNodes()
Definition: stlastar.h:409
static unsigned int _map_width
Definition: findpath.cpp:25
uint32_t y
Definition: astar.h:8
unsigned int y
Definition: findpath.cpp:43
void PrintNodeInfo()
Definition: findpath.cpp:75
static unsigned int _map_height
Definition: findpath.cpp:25
unsigned int SearchStep()
Definition: stlastar.h:169
bool AddSuccessor(UserState &State)
Definition: stlastar.h:390
uint8_t GetMap(unsigned int x, unsigned int y)
Definition: findpath.cpp:27
float GoalDistanceEstimate(MapSearchNode &nodeGoal)
Definition: findpath.cpp:84
bool IsGoal(MapSearchNode &nodeGoal)
Definition: findpath.cpp:92
UserState * GetSolutionStart()
Definition: stlastar.h:441
UserState * GetSolutionNext()
Definition: stlastar.h:455


stage
Author(s): Richard Vaughan , Brian Gerkey , Reed Hedges , Andrew Howard , Toby Collett , Pooya Karimian , Jeremy Asher , Alex Couture-Beil , Geoff Biggs , Rich Mattes , Abbas Sadat
autogenerated on Mon Jun 10 2019 15:06:09