navtest.cpp
Go to the documentation of this file.
00001 //
00002 // simple timing test of the nav fn planner
00003 // expects a cost map in maps/willow-full-0.05.pgm
00004 //
00005 
00006 #include <navfn/navfn.h>
00007 #include <navfn/navwin.h>
00008 #include <sys/time.h>
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <stdint.h>
00012 
00013 #include <string>
00014 #include <fstream>
00015 
00016 using namespace navfn;
00017 
00018 extern "C" {
00019 #include <stdio.h>
00020 // pgm.h is not very friendly with system headers... need to undef max() and min() afterwards
00021 #include <pgm.h>
00022 #undef max
00023 #undef min
00024 }
00025 
00026 int goal[2];
00027 int start[2];
00028 
00029 double get_ms()
00030 {
00031   struct timeval t0;
00032   gettimeofday(&t0,NULL);
00033   double ret = t0.tv_sec * 1000.0;
00034   ret += ((double)t0.tv_usec)*0.001;
00035   return ret;
00036 }
00037 
00038 NavWin *nwin;
00039 
00040 void
00041 dispPot(NavFn *nav)
00042 {
00043   nwin->drawPot(nav);
00044   Fl::check();
00045 }
00046 
00047 
00048 // <raw> is true for ROS-generated raw cost maps
00049 COSTTYPE *readPGM(const char *fname, int *width, int *height, bool raw = false);
00050 
00051 int main(int argc, char **argv)
00052 {
00053   int dispn = 0;
00054 
00055   int res = 50;                 // 50 mm resolution
00056   double size = 40.0;           // 40 m on a side
00057   int inc = 2*COST_NEUTRAL;     // thin wavefront
00058   bool got_start_goal = false;
00059   std::string pgm_file_name;
00060   
00061   start[0] = 420;
00062   start[1] = 420;
00063 
00064   goal[0] = 580;
00065   goal[1] = 400;
00066 
00067   if (argc > 1)
00068   {
00069     pgm_file_name = std::string( argv[ 1 ]) + ".pgm";
00070     std::string txt_file_name = std::string( argv[ 1 ]) + ".txt";
00071 
00072     std::ifstream txt_stream( txt_file_name.c_str() );
00073     if( txt_stream )
00074     {
00075       std::string name;
00076       int x, y;
00077       for( int i = 0; i < 2; i++ )
00078       {
00079         txt_stream >> name >> x >> y;
00080         if( txt_stream && name == "Goal:" )
00081         {
00082           goal[0] = x;
00083           goal[1] = y;
00084         }
00085         else if( txt_stream && name == "Start:" )
00086         {
00087           start[0] = x;
00088           start[1] = y;
00089         }
00090       }
00091       got_start_goal = true;
00092       printf( "start is %d, %d, goal is %d, %d.\n", start[ 0 ], start[ 1 ], goal[ 0 ], goal[ 1 ]);
00093     }
00094     else
00095     {
00096       printf( "Failed to open file %s, assuming you didn't want to open a file.\n", txt_file_name.c_str() );
00097     }
00098   }
00099 
00100   // get resolution (mm) and perhaps size (m)
00101   if( !got_start_goal )
00102   {
00103     if (argc > 1)
00104       res = atoi(argv[1]);
00105 
00106     if (argc > 2)
00107       size = atoi(argv[2]);
00108 
00109     if (argc > 3)
00110       inc = atoi(argv[3]);
00111 
00112     if (argc > 4)
00113       dispn = atoi(argv[4]);
00114   }
00115   NavFn *nav;
00116 
00117   // try reading in a file
00118   int sx,sy;
00119   COSTTYPE *cmap = NULL;
00120   //  cmap = readPGM("maps/willow-full-0.05.pgm",&sx,&sy);
00121   //  cmap = readPGM("maps/navfn_test1.pgm",&sx,&sy,true);
00122   //  cmap = readPGM("initial_costmap_1165_945.pgm",&sx,&sy,true);
00123   //  cmap = readPGM("initial_costmap_2332_1825.pgm",&sx,&sy,true);
00124   cmap = readPGM( pgm_file_name.c_str(),&sx,&sy,true);
00125   //  cmap = readPGM("navfn_pathlong.pgm",&sx,&sy,true);
00126   if (cmap)
00127     {
00128       nav = new NavFn(sx,sy);
00129 
00130 
00131     }
00132   else
00133     {
00134       sx = (int)((.001 + size) / (res*.001));
00135       sy = sx;
00136       nav = new NavFn(sx,sy); // size in pixels
00137       goal[0] = sx-10;
00138       goal[1] = sy/2;
00139       start[0] = 20;
00140       start[1] = sy/2;
00141     }
00142 
00143   // display
00144   nwin = new NavWin(sx,sy,"Potential Field");
00145   nwin->maxval = 2*sx*COST_NEUTRAL;
00146   Fl::visual(FL_RGB);
00147   nwin->show();
00148 
00149 
00150   // set goal and robot poses
00151   int *gg = goal;
00152   nav->setGoal(gg);
00153   int *ss = start;
00154   nav->setStart(ss);
00155 
00156   // set display function
00157   nav->display(dispPot,dispn);
00158 
00159 
00160   nav->priInc = inc;
00161   printf("[NavTest] priority increment: %d\n", inc);
00162 
00163 #if 0
00164   // calculate the nav fn and path
00165   double t0 = get_ms();
00166   // set up cost map from file, if it exists
00167   if (cmap)
00168     {
00169       nav->setCostmap(cmap);
00170       nav->setupNavFn(true);
00171     }
00172   else
00173     {
00174       nav->setupNavFn(false);
00175       nav->setObs();            // simple obstacles
00176     }
00177   //nav->propNavFnDijkstra(sx*sy/20);
00178   nav->propNavFnAstar(sx*sy/20);
00179   double t1 = get_ms();
00180 
00181   printf("Time for plan calculation: %d ms\n", (int)(t1-t0));
00182   
00183   // path
00184   nav->calcPath(4000);
00185 
00186 #else
00187   double t0 = get_ms();
00188   // set up cost map from file, if it exists
00189   if (cmap)
00190     {
00191       //      nav->setCostMap(cmap);
00192       memcpy(nav->costarr,cmap,sx*sy);
00193       nav->setupNavFn(true);
00194     }
00195   else
00196     {
00197       nav->setupNavFn(false);
00198       nav->setObs();            // simple obstacles
00199     }
00200   double t1 = get_ms();
00201   //  nav->calcNavFnAstar();
00202   nav->calcNavFnDijkstra(true);
00203   double t2 = get_ms();
00204   printf("Setup: %d ms  Plan: %d ms  Total: %d ms\n", 
00205          (int)(t1-t0), (int)(t2-t1), (int)(t2-t0));
00206 #endif
00207 
00208   // draw potential field
00209   float mmax = 0.0;
00210   float *pp = nav->potarr;
00211   int ntot = 0;
00212   for (int i=0; i<nav->ny*nav->nx; i++, pp++)
00213     {
00214       if (*pp < 10e7 && *pp > mmax)
00215         mmax = *pp;
00216       if (*pp > 10e7)
00217         ntot++;                 // number of uncalculated cells
00218     }
00219   printf("[NavFn] Cells not touched: %d/%d\n", ntot, nav->nx*nav->ny);
00220   nwin->maxval = 4*mmax/3/15;
00221   dispPot(nav);
00222   while (Fl::check()) {
00223     if( Fl::event_key( 'q' ))
00224     {
00225       break;
00226     }
00227   }
00228 
00229 #if 0
00230   goal[1] = size-2;
00231   int k = nav->getCellIndex(gg);
00232   int st_nx = nav->st_nx;
00233   for (int i=0; i<900; i++, k--)
00234     {
00235       float npot = nav->potgrid[k];
00236       printf("Pot: %0.1f\n", npot);
00237       printf("L: %0.1f R: %0.1f U: %0.1f D: %0.1f\n",
00238              nav->potgrid[k-1], nav->potgrid[k+1], nav->potgrid[k-st_nx], nav->potgrid[k+st_nx]);
00239     }
00240 #endif
00241 
00242   return 0;
00243 }
00244 
00245 
00246 // read in a PGM file for obstacles
00247 // no expansion yet...
00248 
00249 static int CS;
00250 
00251 void
00252 setcostobs(COSTTYPE *cmap, int n, int w)
00253 {
00254   CS = 11;
00255   for (int i=-CS/2; i<CS/2; i++)
00256     {
00257       COSTTYPE *cm = i*w + &cmap[n];
00258       for (int j=-CS/2; j<CS/2; j++)
00259         cm[j] = COST_NEUTRAL + 50;
00260     }
00261   CS = 7;
00262   for (int i=-CS/2; i<CS/2; i++)
00263     {
00264       COSTTYPE *cm = i*w + &cmap[n];
00265       for (int j=-CS/2; j<CS/2; j++)
00266         cm[j] = COST_OBS;
00267     }
00268 }
00269 
00270 void setcostunk(COSTTYPE *cmap, int n, int w)
00271 {
00272   cmap[n] = COST_OBS;
00273 }
00274 
00275 #define unknown_gray 0xCC       // seems to be the value of "unknown" in maps
00276 
00277 COSTTYPE *
00278 readPGM(const char *fname, int *width, int *height, bool raw)
00279 {
00280   pm_init("navtest",0);
00281 
00282   FILE *pgmfile;
00283   pgmfile = fopen(fname,"r");
00284   if (!pgmfile)
00285     {
00286       printf("[NavTest] Can't find file %s\n", fname);
00287       return NULL;
00288     }
00289 
00290   printf("[NavTest] Reading costmap file %s\n", fname);
00291   int ncols, nrows;
00292   gray maxval;
00293   int format;
00294   pgm_readpgminit(pgmfile, &ncols, &nrows, &maxval, &format);
00295   printf("[NavTest] Size: %d x %d\n", ncols, nrows);
00296 
00297   // set up cost map
00298   COSTTYPE *cmap = (COSTTYPE *)malloc(ncols*nrows*sizeof(COSTTYPE));
00299   if (!raw)
00300     for (int i=0; i<ncols*nrows; i++)
00301       cmap[i] = COST_NEUTRAL;
00302 
00303   gray * row(pgm_allocrow(ncols));
00304   int otot = 0;
00305   int utot = 0;
00306   int ftot = 0;
00307   for (int ii = 0; ii < nrows; ii++) {
00308     pgm_readpgmrow(pgmfile, row, ncols, maxval, format);
00309     if (raw)                    // raw costmap from ROS
00310       {
00311         for (int jj(ncols - 1); jj >= 0; --jj)
00312           {
00313             int v = row[jj];
00314             cmap[ii*ncols+jj] = v;
00315             if (v >= COST_OBS_ROS)
00316               otot++;
00317             if (v == 0)
00318               ftot++;
00319           }
00320       }
00321     else
00322       {
00323         ftot = ncols*nrows;
00324         for (int jj(ncols - 1); jj >= 0; --jj)
00325           {
00326             if (row[jj] < unknown_gray && ii < nrows-7 && ii > 7)
00327               {
00328                 setcostobs(cmap,ii*ncols+jj,ncols);
00329                 otot++;
00330                 ftot--;
00331               }
00332 #if 1
00333             else if (row[jj] <= unknown_gray)
00334               {
00335                 setcostunk(cmap,ii*ncols+jj,ncols);
00336                 utot++;
00337                 ftot--;
00338               }
00339 #endif
00340           }
00341       }
00342   }
00343   printf("[NavTest] Found %d obstacle cells, %d free cells, %d unknown cells\n", otot, ftot, utot);
00344   pgm_freerow(row);
00345   *width = ncols;
00346   *height = nrows;
00347   return cmap;
00348 }


navfn
Author(s): Kurt Konolige, Eitan Marder-Eppstein
autogenerated on Mon Oct 6 2014 02:46:56