navtest.cpp
Go to the documentation of this file.
1 //
2 // simple timing test of the nav fn planner
3 // expects a cost map in maps/willow-full-0.05.pgm
4 //
5 
6 #include <navfn/navfn.h>
7 #include <navfn/navwin.h>
8 #include <sys/time.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <stdint.h>
12 
13 #include <string>
14 #include <fstream>
15 
16 using namespace navfn;
17 
18 #ifdef __APPLE__
19 # include <netpbm/pgm.h>
20 #else
21 extern "C" {
22 #include <stdio.h>
23 // pgm.h is not very friendly with system headers... need to undef max() and min() afterwards
24 #include <pgm.h>
25 #undef max
26 #undef min
27 }
28 #endif
29 
30 int goal[2];
31 int start[2];
32 
33 double get_ms()
34 {
35  struct timeval t0;
36  gettimeofday(&t0,NULL);
37  double ret = t0.tv_sec * 1000.0;
38  ret += ((double)t0.tv_usec)*0.001;
39  return ret;
40 }
41 
43 
44 void
46 {
47  nwin->drawPot(nav);
48  Fl::check();
49 }
50 
51 
52 // <raw> is true for ROS-generated raw cost maps
53 COSTTYPE *readPGM(const char *fname, int *width, int *height, bool raw = false);
54 
55 int main(int argc, char **argv)
56 {
57  int dispn = 0;
58 
59  int res = 50; // 50 mm resolution
60  double size = 40.0; // 40 m on a side
61  int inc = 2*COST_NEUTRAL; // thin wavefront
62  bool got_start_goal = false;
63  std::string pgm_file_name;
64 
65  start[0] = 420;
66  start[1] = 420;
67 
68  goal[0] = 580;
69  goal[1] = 400;
70 
71  if (argc > 1)
72  {
73  pgm_file_name = std::string( argv[ 1 ]) + ".pgm";
74  std::string txt_file_name = std::string( argv[ 1 ]) + ".txt";
75 
76  std::ifstream txt_stream( txt_file_name.c_str() );
77  if( txt_stream )
78  {
79  std::string name;
80  int x, y;
81  for( int i = 0; i < 2; i++ )
82  {
83  txt_stream >> name >> x >> y;
84  if( txt_stream && name == "Goal:" )
85  {
86  goal[0] = x;
87  goal[1] = y;
88  }
89  else if( txt_stream && name == "Start:" )
90  {
91  start[0] = x;
92  start[1] = y;
93  }
94  }
95  got_start_goal = true;
96  printf( "start is %d, %d, goal is %d, %d.\n", start[ 0 ], start[ 1 ], goal[ 0 ], goal[ 1 ]);
97  }
98  else
99  {
100  printf( "Failed to open file %s, assuming you didn't want to open a file.\n", txt_file_name.c_str() );
101  }
102  }
103 
104  // get resolution (mm) and perhaps size (m)
105  if( !got_start_goal )
106  {
107  if (argc > 1)
108  res = atoi(argv[1]);
109 
110  if (argc > 2)
111  size = atoi(argv[2]);
112 
113  if (argc > 3)
114  inc = atoi(argv[3]);
115 
116  if (argc > 4)
117  dispn = atoi(argv[4]);
118  }
119  NavFn *nav;
120 
121  // try reading in a file
122  int sx,sy;
123  COSTTYPE *cmap = NULL;
124  // cmap = readPGM("maps/willow-full-0.05.pgm",&sx,&sy);
125  // cmap = readPGM("maps/navfn_test1.pgm",&sx,&sy,true);
126  // cmap = readPGM("initial_costmap_1165_945.pgm",&sx,&sy,true);
127  // cmap = readPGM("initial_costmap_2332_1825.pgm",&sx,&sy,true);
128  cmap = readPGM( pgm_file_name.c_str(),&sx,&sy,true);
129  // cmap = readPGM("navfn_pathlong.pgm",&sx,&sy,true);
130  if (cmap)
131  {
132  nav = new NavFn(sx,sy);
133 
134 
135  }
136  else
137  {
138  sx = (int)((.001 + size) / (res*.001));
139  sy = sx;
140  nav = new NavFn(sx,sy); // size in pixels
141  goal[0] = sx-10;
142  goal[1] = sy/2;
143  start[0] = 20;
144  start[1] = sy/2;
145  }
146 
147  // display
148  nwin = new NavWin(sx,sy,"Potential Field");
149  nwin->maxval = 2*sx*COST_NEUTRAL;
150  Fl::visual(FL_RGB);
151  nwin->show();
152 
153 
154  // set goal and robot poses
155  int *gg = goal;
156  nav->setGoal(gg);
157  int *ss = start;
158  nav->setStart(ss);
159 
160  // set display function
161  nav->display(dispPot,dispn);
162 
163 
164  nav->priInc = inc;
165  printf("[NavTest] priority increment: %d\n", inc);
166 
167 #if 0
168  // calculate the nav fn and path
169  double t0 = get_ms();
170  // set up cost map from file, if it exists
171  if (cmap)
172  {
173  nav->setCostmap(cmap);
174  nav->setupNavFn(true);
175  }
176  else
177  {
178  nav->setupNavFn(false);
179  nav->setObs(); // simple obstacles
180  }
181  //nav->propNavFnDijkstra(sx*sy/20);
182  nav->propNavFnAstar(sx*sy/20);
183  double t1 = get_ms();
184 
185  printf("Time for plan calculation: %d ms\n", (int)(t1-t0));
186 
187  // path
188  nav->calcPath(4000);
189 
190 #else
191  double t0 = get_ms();
192  // set up cost map from file, if it exists
193  if (cmap)
194  {
195  // nav->setCostMap(cmap);
196  memcpy(nav->costarr,cmap,sx*sy);
197  nav->setupNavFn(true);
198  }
199  else
200  {
201  nav->setupNavFn(false);
202  nav->setObs(); // simple obstacles
203  }
204  double t1 = get_ms();
205  // nav->calcNavFnAstar();
206  nav->calcNavFnDijkstra(true);
207  double t2 = get_ms();
208  printf("Setup: %d ms Plan: %d ms Total: %d ms\n",
209  (int)(t1-t0), (int)(t2-t1), (int)(t2-t0));
210 #endif
211 
212  // draw potential field
213  float mmax = 0.0;
214  float *pp = nav->potarr;
215  int ntot = 0;
216  for (int i=0; i<nav->ny*nav->nx; i++, pp++)
217  {
218  if (*pp < 10e7 && *pp > mmax)
219  mmax = *pp;
220  if (*pp > 10e7)
221  ntot++; // number of uncalculated cells
222  }
223  printf("[NavFn] Cells not touched: %d/%d\n", ntot, nav->nx*nav->ny);
224  nwin->maxval = 4*mmax/3/15;
225  dispPot(nav);
226  while (Fl::check()) {
227  if( Fl::event_key( 'q' ))
228  {
229  break;
230  }
231  }
232 
233 #if 0
234  goal[1] = size-2;
235  int k = nav->getCellIndex(gg);
236  int st_nx = nav->st_nx;
237  for (int i=0; i<900; i++, k--)
238  {
239  float npot = nav->potgrid[k];
240  printf("Pot: %0.1f\n", npot);
241  printf("L: %0.1f R: %0.1f U: %0.1f D: %0.1f\n",
242  nav->potgrid[k-1], nav->potgrid[k+1], nav->potgrid[k-st_nx], nav->potgrid[k+st_nx]);
243  }
244 #endif
245 
246  return 0;
247 }
248 
249 
250 // read in a PGM file for obstacles
251 // no expansion yet...
252 
253 static int CS;
254 
255 void
256 setcostobs(COSTTYPE *cmap, int n, int w)
257 {
258  CS = 11;
259  for (int i=-CS/2; i<CS/2; i++)
260  {
261  COSTTYPE *cm = i*w + &cmap[n];
262  for (int j=-CS/2; j<CS/2; j++)
263  cm[j] = COST_NEUTRAL + 50;
264  }
265  CS = 7;
266  for (int i=-CS/2; i<CS/2; i++)
267  {
268  COSTTYPE *cm = i*w + &cmap[n];
269  for (int j=-CS/2; j<CS/2; j++)
270  cm[j] = COST_OBS;
271  }
272 }
273 
274 void setcostunk(COSTTYPE *cmap, int n, int w)
275 {
276  cmap[n] = COST_OBS;
277 }
278 
279 #define unknown_gray 0xCC // seems to be the value of "unknown" in maps
280 
281 COSTTYPE *
282 readPGM(const char *fname, int *width, int *height, bool raw)
283 {
284  pm_init("navtest",0);
285 
286  FILE *pgmfile;
287  pgmfile = fopen(fname,"r");
288  if (!pgmfile)
289  {
290  printf("[NavTest] Can't find file %s\n", fname);
291  return NULL;
292  }
293 
294  printf("[NavTest] Reading costmap file %s\n", fname);
295  int ncols, nrows;
296  gray maxval;
297  int format;
298  pgm_readpgminit(pgmfile, &ncols, &nrows, &maxval, &format);
299  printf("[NavTest] Size: %d x %d\n", ncols, nrows);
300 
301  // set up cost map
302  COSTTYPE *cmap = (COSTTYPE *)malloc(ncols*nrows*sizeof(COSTTYPE));
303  if (!raw)
304  for (int i=0; i<ncols*nrows; i++)
305  cmap[i] = COST_NEUTRAL;
306 
307  gray * row(pgm_allocrow(ncols));
308  int otot = 0;
309  int utot = 0;
310  int ftot = 0;
311  for (int ii = 0; ii < nrows; ii++) {
312  pgm_readpgmrow(pgmfile, row, ncols, maxval, format);
313  if (raw) // raw costmap from ROS
314  {
315  for (int jj(ncols - 1); jj >= 0; --jj)
316  {
317  int v = row[jj];
318  cmap[ii*ncols+jj] = v;
319  if (v >= COST_OBS_ROS)
320  otot++;
321  if (v == 0)
322  ftot++;
323  }
324  }
325  else
326  {
327  ftot = ncols*nrows;
328  for (int jj(ncols - 1); jj >= 0; --jj)
329  {
330  if (row[jj] < unknown_gray && ii < nrows-7 && ii > 7)
331  {
332  setcostobs(cmap,ii*ncols+jj,ncols);
333  otot++;
334  ftot--;
335  }
336 #if 1
337  else if (row[jj] <= unknown_gray)
338  {
339  setcostunk(cmap,ii*ncols+jj,ncols);
340  utot++;
341  ftot--;
342  }
343 #endif
344  }
345  }
346  }
347  printf("[NavTest] Found %d obstacle cells, %d free cells, %d unknown cells\n", otot, ftot, utot);
348  pgm_freerow(row);
349  *width = ncols;
350  *height = nrows;
351  return cmap;
352 }
Definition: navfn.h:81
void setupNavFn(bool keepit=false)
Definition: navfn.cpp:402
float maxval
Definition: navwin.h:29
void setStart(int *start)
Sets the start position for the planner. Note: the navigation cost field computed gives the cost to g...
Definition: navfn.cpp:181
void setCostmap(const COSTTYPE *cmap, bool isROS=true, bool allow_unknown=true)
Set up the cost array for the planner, usually from ROS.
Definition: navfn.cpp:228
bool calcNavFnDijkstra(bool atStart=false)
Caclulates the full navigation function using Dijkstra.
Definition: navfn.cpp:290
TFSIMD_FORCE_INLINE const tfScalar & y() const
int nx
Definition: navfn.h:124
float * potarr
Definition: navfn.h:171
COSTTYPE * costarr
Definition: navfn.h:170
void setGoal(int *goal)
Sets the goal position for the planner. Note: the navigation cost field computed gives the cost to ge...
Definition: navfn.cpp:173
void setObs()
Definition: navfn.cpp:362
void drawPot(NavFn *nav)
Definition: navwin.cpp:30
Navigation function class. Holds buffers for costmap, navfn map. Maps are pixel-based. Origin is upper left, x is right, y is down.
Definition: navfn.h:106
TFSIMD_FORCE_INLINE const tfScalar & x() const
int calcPath(int n, int *st=NULL)
Calculates the path for at mose <n> cycles.
Definition: navfn.cpp:822
void display(void fn(NavFn *nav), int n=100)
Definition: navfn.cpp:1051
float priInc
Definition: navfn.h:182
bool propNavFnAstar(int cycles)
Run propagation for <cycles> iterations, or until start is reached using the best-first A* method wit...
Definition: navfn.cpp:729
int ny
Definition: navfn.h:124


navfn
Author(s): Kurt Konolige, Eitan Marder-Eppstein, contradict@gmail.com
autogenerated on Thu Jan 21 2021 04:06:04