findpath.cpp
Go to the documentation of this file.
00001 
00002 
00003 // STL A* Search implementation
00004 // (C)2001 Justin Heyes-Jones
00005 //
00006 // Finding a path on a simple grid maze
00007 // This shows how to do shortest path finding using A*
00008 
00010 
00011 #include "stlastar.h" // See header for copyright and usage information
00012 
00013 #include <iostream>
00014 #include <math.h>
00015 
00016 #define DEBUG_LISTS 0
00017 #define DEBUG_LIST_LENGTHS_ONLY 0
00018 
00019 using namespace std;
00020 //using namespace astar;
00021 
00022 // map helper functions
00023 
00024 static uint8_t* _map = NULL;
00025 static unsigned int _map_width=0, _map_height=0;
00026 
00027 uint8_t GetMap( unsigned int x, unsigned int y )
00028 {
00029   assert(_map);
00030 
00031   if(x >= _map_width || y >= _map_height)
00032                 return 9;
00033 
00034         return _map[(y*_map_width)+x];
00035 }
00036 
00037 // Definitions
00038 
00039 class MapSearchNode
00040 {
00041 public:
00042         unsigned int x;  // the (x,y) positions of the node
00043         unsigned int y; 
00044         
00045         MapSearchNode() { x = y = 0; }
00046         MapSearchNode( unsigned int px, unsigned int py ) { x=px; y=py; }
00047 
00048         float GoalDistanceEstimate( MapSearchNode &nodeGoal );
00049         bool IsGoal( MapSearchNode &nodeGoal );
00050         bool GetSuccessors( AStarSearch<MapSearchNode> *astarsearch, MapSearchNode *parent_node );
00051         float GetCost( MapSearchNode &successor );
00052         bool IsSameState( MapSearchNode &rhs );
00053 
00054         void PrintNodeInfo(); 
00055 
00056 
00057 };
00058 
00059 bool MapSearchNode::IsSameState( MapSearchNode &rhs )
00060 {
00061 
00062         // same state in a maze search is simply when (x,y) are the same
00063         if( (x == rhs.x) &&
00064                 (y == rhs.y) )
00065         {
00066                 return true;
00067         }
00068         else
00069         {
00070                 return false;
00071         }
00072 
00073 }
00074 
00075 void MapSearchNode::PrintNodeInfo()
00076 {
00077   //cout << x << "\t" << y << endl;
00078   cout << "Node position : (" << x << ", " << y << ")" << endl;
00079 }
00080 
00081 // Here's the heuristic function that estimates the distance from a Node
00082 // to the Goal. 
00083 
00084 float MapSearchNode::GoalDistanceEstimate( MapSearchNode &nodeGoal )
00085 {
00086   float xd = fabs(float(((float)x - (float)nodeGoal.x)));
00087   float yd = fabs(float(((float)y - (float)nodeGoal.y)));
00088   return xd + yd;       
00089   //return 1.001 * (xd + yd );
00090 }
00091 
00092 bool MapSearchNode::IsGoal( MapSearchNode &nodeGoal )
00093 {
00094 
00095         if( (x == nodeGoal.x) &&
00096                 (y == nodeGoal.y) )
00097         {
00098                 return true;
00099         }
00100 
00101         return false;
00102 }
00103 
00104 // This generates the successors to the given Node. It uses a helper function called
00105 // AddSuccessor to give the successors to the AStar class. The A* specific initialisation
00106 // is done for each node internally, so here you just set the state information that
00107 // is specific to the application
00108 bool MapSearchNode::GetSuccessors( AStarSearch<MapSearchNode> *astarsearch, 
00109                                                                                           MapSearchNode *parent_node )
00110 {
00111 
00112         int parent_x = -1; 
00113         int parent_y = -1; 
00114 
00115         if( parent_node )
00116         {
00117                 parent_x = parent_node->x;
00118                 parent_y = parent_node->y;
00119         }
00120         
00121         MapSearchNode NewNode;
00122 
00123         int ix = (int)x;
00124         int iy = (int)y;
00125 
00126         // push each possible move except allowing the search to go backwards
00127 
00128         if( (GetMap( ix-1, iy ) < 9u) 
00129                         && !((parent_x == ix-1) && (parent_y == iy))
00130           ) 
00131         {
00132                 NewNode = MapSearchNode( ix-1, iy );
00133                 astarsearch->AddSuccessor( NewNode );
00134         }       
00135 
00136         if( (GetMap( ix, iy-1 ) < 9u) 
00137                 && !((parent_x == ix) && (parent_y == iy-1))
00138           ) 
00139         {
00140                 NewNode = MapSearchNode( ix, iy-1 );
00141                 astarsearch->AddSuccessor( NewNode );
00142         }       
00143 
00144         if( (GetMap( ix+1, iy ) < 9u)
00145                 && !((parent_x == ix+1) && (parent_y == iy))
00146           ) 
00147         {
00148                 NewNode = MapSearchNode( ix+1, iy );
00149                 astarsearch->AddSuccessor( NewNode );
00150         }       
00151 
00152                 
00153         if( (GetMap( ix, iy+1 ) < 9u) 
00154                 && !((parent_x == ix) && (parent_y == iy+1))
00155                 )
00156         {
00157                 NewNode = MapSearchNode( ix, iy+1 );
00158                 astarsearch->AddSuccessor( NewNode );
00159         }       
00160 
00161         return true;
00162 }
00163 
00164 // given this node, what does it cost to move to successor. In the case
00165 // of our map the answer is the map terrain value at this node since that is 
00166 // conceptually where we're moving
00167 
00168 float MapSearchNode::GetCost( MapSearchNode &successor )
00169 {
00170         return (float) GetMap( x, y );
00171 
00172 }
00173 
00174 
00175 // Main
00176 
00177 #include "astar.h"
00178 using namespace ast;
00179 
00180 bool ast::astar( uint8_t* map, 
00181                                 uint32_t width, 
00182                                 uint32_t height,
00183                                 const point_t start, 
00184                                 const point_t goal, 
00185                                 std::vector<point_t>& path )
00186 {
00187   //cout << "STL A* Search implementation\n(C)2001 Justin Heyes-Jones\n";
00188 
00189         // set the static vars
00190         _map = map;
00191         _map_width = width;
00192         _map_height = height;
00193 
00194         // Our sample problem defines the world as a 2d array representing a terrain
00195         // Each element contains an integer from 0 to 5 which indicates the cost 
00196         // of travel across the terrain. Zero means the least possible difficulty 
00197         // in travelling (think ice rink if you can skate) whilst 5 represents the 
00198         // most difficult. 9 indicates that we cannot pass.
00199 
00200         // Create an instance of the search class...
00201 
00202         AStarSearch<MapSearchNode> astarsearch;
00203 
00204         unsigned int SearchCount = 0;
00205 
00206         const unsigned int NumSearches = 1;
00207         
00208         bool path_found = false;
00209 
00210         while(SearchCount < NumSearches)
00211         {
00212           
00213                 // Create a start state
00214                 MapSearchNode nodeStart;
00215                 nodeStart.x = start.x;
00216                 nodeStart.y = start.y;
00217 
00218                 // Define the goal state
00219                 MapSearchNode nodeEnd;
00220                 nodeEnd.x = goal.x;
00221                 nodeEnd.y = goal.y;
00222                 
00223                 // Set Start and goal states
00224                 
00225                 astarsearch.SetStartAndGoalStates( nodeStart, nodeEnd );
00226 
00227                 unsigned int SearchState;
00228                 unsigned int SearchSteps = 0;
00229 
00230                 do
00231                 {
00232                         SearchState = astarsearch.SearchStep();
00233 
00234                         SearchSteps++;
00235 
00236         #if DEBUG_LISTS
00237 
00238                         cout << "Steps:" << SearchSteps << "\n";
00239                         
00240                         int len = 0;
00241                         
00242                         cout << "Open:\n";
00243                         MapSearchNode *p = astarsearch.GetOpenListStart();
00244                         while( p )
00245                                 {
00246                                         len++;
00247 #if !DEBUG_LIST_LENGTHS_ONLY                    
00248                                         ((MapSearchNode *)p)->PrintNodeInfo();
00249 #endif
00250                                         p = astarsearch.GetOpenListNext();
00251                                         
00252                                 }
00253                         
00254                         cout << "Open list has " << len << " nodes\n";
00255                         
00256                         len = 0;
00257                         
00258                         cout << "Closed:\n";
00259                         p = astarsearch.GetClosedListStart();
00260                         while( p )
00261                                 {
00262                                         len++;
00263 #if !DEBUG_LIST_LENGTHS_ONLY                    
00264                                         p->PrintNodeInfo();
00265 #endif                  
00266                                         p = astarsearch.GetClosedListNext();
00267                                 }
00268                         
00269                         cout << "Closed list has " << len << " nodes\n";
00270 #endif
00271 
00272                 }
00273                 while( SearchState == AStarSearch<MapSearchNode>::SEARCH_STATE_SEARCHING );
00274 
00275                 if( SearchState == AStarSearch<MapSearchNode>::SEARCH_STATE_SUCCEEDED )
00276                 {
00277                   //cout << "Search found goal state\n";
00278 
00279                                 MapSearchNode *node = astarsearch.GetSolutionStart();
00280                                 
00281 #if DISPLAY_SOLUTION
00282                                 cout << "Displaying solution\n";
00283 #endif
00284                                 int steps = 0;
00285                                 
00286                                 //node->PrintNodeInfo();
00287                                 
00288                                 path.push_back( point_t( node->x, node->y ) );
00289                                 
00290                                 for( ;; )
00291                                   {
00292                                          node = astarsearch.GetSolutionNext();
00293                                          
00294                                          if( !node )
00295                                                 {
00296                                                   break;
00297                                                 }
00298                                          
00299                                          //node->PrintNodeInfo();
00300                                          
00301                                          path.push_back( point_t( node->x, node->y ) );
00302                                          
00303                                          steps ++;
00304                                          
00305                                   };
00306                                 
00307                                 //cout << "Solution steps " << steps << endl;
00308                                 
00309                                 // Once you're done with the solution you can free the nodes up
00310                                 astarsearch.FreeSolutionNodes();
00311                                 
00312                                 path_found = true;
00313                                 
00314                 }
00315                 else if( SearchState == AStarSearch<MapSearchNode>::SEARCH_STATE_FAILED ) 
00316                   {
00317                          cout << "Search terminated. Did not find goal state\n";
00318                          
00319                   }
00320                 
00321                 // Display the number of loops the search went through
00322                 //cout << "SearchSteps : " << SearchSteps << "\n";
00323                 
00324                 SearchCount ++;
00325                 
00326                 astarsearch.EnsureMemoryFreed();
00327         }
00328         
00329         return path_found;  
00330 }
00331 
00332 //   // STL container iterator macros
00333 // #define VAR(V,init) __typeof(init) V=(init)
00334 // #define FOR_EACH(I,C) for(VAR(I,(C).begin());I!=(C).end();I++)
00335 
00336 // int main( int argc, char *argv[] )
00337 // {
00338 //   std::vector<point_t> path;
00339 
00340 //   bool result = astar( map, 30, 30, point_t( 1,1 ), point_t( 25,20 ), path );
00341 
00342 //   printf( "#%s:\n", result ? "PATH" : "NOPATH" );
00343   
00344 //   FOR_EACH( it, path )
00345 //       printf( "%d, %d\n", it->x, it->y );
00346 //   puts("");
00347 // }
00348 


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 Thu Aug 27 2015 15:20:57