00001
00011 #include "aalgorithm.h"
00012 #include "pathqueue.h"
00013 #include "map.h"
00014 #include <math.h>
00015 #include <stdlib.h>
00016
00017 #define SQRT2 1.41421356
00018 #define WALL_COST 1000
00020 GraphMapCell graph[MAP_HEIGHT][MAP_WIDTH];
00022 void pushNodeInOrder(NodeQueue * q, int x, int y);
00023 float cFunction(int x1, int y1, int x2, int y2);
00024
00045 int aAlgorithm(double xstart_real,double ystart_real, double xgoal_real, double ygoal_real, double ** original_path){
00052 NodeQueue * prioritySet = newQueue();
00056 Node nbest;
00057 int i, j;
00058 int xcontig, ycontig;
00059 int xstart, ystart, xgoal, ygoal;
00060
00061 xstart = ShmapPoint2Cell_X(xstart_real); ystart = ShmapPoint2Cell_Y(ystart_real);
00062 xgoal = ShmapPoint2Cell_X(xgoal_real); ygoal = ShmapPoint2Cell_Y(ygoal_real);
00063
00065
00066
00067 initGraphStructure();
00069 calculateMapHeuristic(xgoal, ygoal);
00070
00072 pushNodeInOrder(prioritySet,xstart,ystart);
00073 graph[ystart][xstart].g = 0;
00074 graph[ystart][xstart].f = graph[ystart][xstart].g + graph[ystart][xstart].h ;
00075 graph[ystart][xstart].bx = xstart;
00076 graph[ystart][xstart].by = ystart;
00077
00079
00080 do {
00083 popNode(prioritySet, &nbest);
00084
00086 graph[nbest.y][nbest.x].processed = 1;
00087
00089 if((nbest.x==xgoal) && (nbest.y==ygoal)){
00090 NodeQueue * list = newQueue();
00091 int nbpoints, count;
00092
00093
00094 drainQueue(prioritySet);
00095 delQueue(prioritySet);
00096
00097
00098
00099
00100 nbpoints = getPathLength(xstart, ystart, xgoal, ygoal);
00101 (*original_path) = (double *) malloc(2 * sizeof(double) * (nbpoints));
00102
00103
00104
00105
00106
00107 i = xgoal;j = ygoal;
00108 pushNodeLast( list, xgoal, ygoal);
00109 while ( ! ((i== xstart) && (j == ystart)) ) {
00110 xcontig = graph[j][i].bx;
00111 ycontig = graph[j][i].by;
00112 pushNodeLast( list, xcontig, ycontig);
00113 i=xcontig;j=ycontig;
00114 }
00115
00116
00117
00118 *((*original_path)) = xstart_real;
00119 *((*original_path) + 1) = ystart_real;
00120 popNode( list, &nbest);
00121 count = 0;
00122 while(!queueIsEmpty( list)){
00123 count++;
00124 popNode( list, &nbest);
00125 *((*original_path) + count*2) = ShmapCell2Point_X(nbest.x);
00126 *((*original_path) + count*2+1) = ShmapCell2Point_Y(nbest.y);
00127 }
00128
00129 *((*original_path) + count*2) = xgoal_real;
00130 *((*original_path) + count*2+1) = ygoal_real;
00131 drainQueue(list);
00132 delQueue(list);
00133 return nbpoints;
00134 }
00135
00137 for (i=-1;i<=1;i++){
00138 for (j=-1;j<=1;j++){
00139 if (!((i== 0) && (j==0))){
00140 xcontig=nbest.x+i;ycontig=nbest.y+j;
00141 if(ShmapIsCellInMap(xcontig, ycontig) && (graph[ycontig][xcontig].processed == 0)){
00143 if (!isInQueue(prioritySet,xcontig,ycontig)){
00144
00145 graph[ycontig][xcontig].g=graph[nbest.y][nbest.x].g + cFunction(nbest.x, nbest.y, xcontig, ycontig);
00146 graph[ycontig][xcontig].f = graph[ycontig][xcontig].g + graph[ycontig][xcontig].h;
00147 graph[ycontig][xcontig].bx=nbest.x;
00148 graph[ycontig][xcontig].by=nbest.y;
00149 if(ShmapIsFreeCell(xcontig, ycontig)) pushNodeInOrder(prioritySet,xcontig,ycontig);
00150 } else if ((graph[nbest.y][nbest.x].g + cFunction(nbest.x, nbest.y, xcontig, ycontig)) < graph[ycontig][xcontig].g){
00152 graph[ycontig][xcontig].bx=nbest.x;
00153 graph[ycontig][xcontig].by=nbest.y;
00154 graph[ycontig][xcontig].g = (graph[nbest.y][nbest.x].g + cFunction(nbest.x, nbest.y, xcontig, ycontig));
00155 }
00156 }
00157 }
00158 }
00159 }
00161 } while(!queueIsEmpty(prioritySet));
00163 delQueue(prioritySet);
00165
00167 return -1;
00168
00169 }
00170
00171
00172
00182 float cFunction(int x1, int y1, int x2, int y2)
00183 {
00184 float c;
00185
00186 if(!ShmapIsFreeCell(x2,y2)) c = WALL_COST;
00187 else if( (x1==x2) || (y1 == y2) ) c=1.0;
00188 else c=SQRT2;
00189
00190 return c;
00191
00192 }
00193
00201 void calculateMapHeuristic(int xgoal, int ygoal){
00210 int i, j;
00211 for(i=0;i<MAP_HEIGHT;i++){
00212 for (j=0;j<MAP_WIDTH;j++){
00213 graph[i][j].h=sqrt(abs(xgoal-j)*abs(xgoal-j)+abs(ygoal-i)*abs(ygoal-i));
00214 }
00215 }
00216 #if 0
00217
00218
00219 Node n;
00220 NodeQueue * toProcess = malloc(sizeof(NodeQueue));
00221 int xcontig, ycontig;
00222 float h;
00223 float newh;
00224 newQueue(toProcess);
00225 graph[ygoal][xgoal].h=0;
00226 graph[ygoal][xgoal].processed=1;
00227
00228 pushNode(toProcess, xgoal, ygoal);
00229 while(!queueIsEmpty(toProcess)){
00230
00231
00232 popNode(toProcess,&n);
00233 graph[n.y][n.x].processed=1;
00234
00235 h = graph[n.y][n.x].h;
00236
00237
00238 for (xcontig = n.x-1 ; xcontig <= n.x + 1 ; xcontig++){
00239 for (ycontig = n.y - 1 ; ycontig <= n.y + 1 ; ycontig++){
00240 if(ShmapIsCellInMap(xcontig, ycontig) && (graph[ycontig][xcontig].processed==0)) {
00241
00242 if ((!isInQueue(toProcess,xcontig,ycontig))) pushNode(toProcess,xcontig,ycontig);
00243
00244 newh= h + calculateCost(n.x, n.y, xcontig, ycontig);
00245 if( ( (graph[ycontig][xcontig].h < 0) || (graph[ycontig][xcontig].h > newh )) )
00246 graph[ycontig][xcontig].h=newh ;
00247 }
00248
00249 }
00250 }
00251 }
00252
00253
00254 for(i=0;i<MAP_HEIGHT;i++){
00255 for (j=0;j<MAP_WIDTH;j++){
00256 graph[i][j].processed=0;
00257 }
00258 }
00259 #endif
00260
00261 }
00262
00272 float calculateCost(int x1, int y1, int x2, int y2){
00273
00274 if( (x1==x2) || (y1 == y2) ) return 1.0;
00275 else return SQRT2;
00276
00277 }
00278
00291 void initGraphStructure(void){
00292 int i,j;
00293
00294
00295 for(i=0;i<MAP_HEIGHT;i++){
00296 for (j=0;j<MAP_WIDTH;j++){
00297 graph[i][j].h=-1;
00298 graph[i][j].f=-1;
00299 graph[i][j].g=0xFFFF;
00300 graph[i][j].bx=-1;
00301 graph[i][j].by=-1;
00302 graph[i][j].processed=0;
00303 }
00304 }
00305 }
00314 void pushNodeInOrder(NodeQueue * q, int x, int y){
00315 Node *current;
00316 Node *last;
00317 Node *n= malloc(sizeof(Node));
00318
00319 if (n == NULL) {
00320
00321 fprintf(stderr, "Couldn't allocate memory\n");
00322 exit(EXIT_FAILURE);
00323 }
00324
00325 n->x=x;
00326 n->y=y;
00327 n->next=NULL;
00328
00329 if (queueIsEmpty(q)) {
00330 q->first=n;
00331 q->last=n;
00332 } else {
00333
00334 current=q->first;
00335 last=NULL;
00336 while (current!=NULL){
00337 if ( graph[y][x].f < graph[current->y][current->x].f ){
00338 if(last==NULL) q->first = n;
00339 else last->next = n;
00340 n->next=current;
00341 current=NULL;
00342 } else {
00343 if (current->next==NULL){
00344
00345 (q->last)->next=n;
00346 q->last=n;
00347 current = NULL;
00348 } else {
00349 last=current;
00350 current=current->next;
00351 }
00352 }
00353 }
00354 }
00355 }
00370 int getPathLength(int xstart, int ystart, int xgoal, int ygoal){
00371 int i,j,tmpx, tmpy, nbpoints;
00372
00373 i = xgoal;j = ygoal; nbpoints =1;
00374 while ( ! ((i== xstart) && (j == ystart)) ) {
00375 tmpx = graph[j][i].bx;
00376 tmpy = graph[j][i].by;
00377 nbpoints++;
00378 i=tmpx;j=tmpy;
00379 ShmapSetCellValue(i,j, MAP_PATH);
00380 }
00381 ShmapSetCellValue(xgoal,ygoal, MAP_GOAL);
00382 ShmapSetCellValue(xstart,ystart, MAP_START);
00383 return nbpoints;
00384 }
00385