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( pgm_file_name.c_str(),&sx,&sy,true);
125  if (cmap)
126  {
127  nav = new NavFn(sx,sy);
128 
129 
130  }
131  else
132  {
133  sx = (int)((.001 + size) / (res*.001));
134  sy = sx;
135  nav = new NavFn(sx,sy); // size in pixels
136  goal[0] = sx-10;
137  goal[1] = sy/2;
138  start[0] = 20;
139  start[1] = sy/2;
140  }
141 
142  // display
143  nwin = new NavWin(sx,sy,"Potential Field");
144  nwin->maxval = 2*sx*COST_NEUTRAL;
145  Fl::visual(FL_RGB);
146  nwin->show();
147 
148 
149  // set goal and robot poses
150  int *gg = goal;
151  nav->setGoal(gg);
152  int *ss = start;
153  nav->setStart(ss);
154 
155  // set display function
156  nav->display(dispPot,dispn);
157 
158 
159  nav->priInc = inc;
160  printf("[NavTest] priority increment: %d\n", inc);
161 
162  double t0 = get_ms();
163  // set up cost map from file, if it exists
164  if (cmap)
165  {
166  // nav->setCostMap(cmap);
167  memcpy(nav->costarr,cmap,sx*sy);
168  nav->setupNavFn(true);
169  }
170  else
171  {
172  nav->setupNavFn(false);
173  }
174  double t1 = get_ms();
175  // nav->calcNavFnAstar();
176  nav->calcNavFnDijkstra(true);
177  double t2 = get_ms();
178  printf("Setup: %d ms Plan: %d ms Total: %d ms\n",
179  (int)(t1-t0), (int)(t2-t1), (int)(t2-t0));
180 
181  // draw potential field
182  float mmax = 0.0;
183  float *pp = nav->potarr;
184  int ntot = 0;
185  for (int i=0; i<nav->ny*nav->nx; i++, pp++)
186  {
187  if (*pp < 10e7 && *pp > mmax)
188  mmax = *pp;
189  if (*pp > 10e7)
190  ntot++; // number of uncalculated cells
191  }
192  printf("[NavFn] Cells not touched: %d/%d\n", ntot, nav->nx*nav->ny);
193  nwin->maxval = 4*mmax/3/15;
194  dispPot(nav);
195  while (Fl::check()) {
196  if( Fl::event_key( 'q' ))
197  {
198  break;
199  }
200  }
201 
202  return 0;
203 }
204 
205 
206 // read in a PGM file for obstacles
207 // no expansion yet...
208 
209 static int CS;
210 
211 void
212 setcostobs(COSTTYPE *cmap, int n, int w)
213 {
214  CS = 11;
215  for (int i=-CS/2; i<CS/2; i++)
216  {
217  COSTTYPE *cm = i*w + &cmap[n];
218  for (int j=-CS/2; j<CS/2; j++)
219  cm[j] = COST_NEUTRAL + 50;
220  }
221  CS = 7;
222  for (int i=-CS/2; i<CS/2; i++)
223  {
224  COSTTYPE *cm = i*w + &cmap[n];
225  for (int j=-CS/2; j<CS/2; j++)
226  cm[j] = COST_OBS;
227  }
228 }
229 
230 void setcostunk(COSTTYPE *cmap, int n, int w)
231 {
232  cmap[n] = COST_OBS;
233 }
234 
235 #define unknown_gray 0xCC // seems to be the value of "unknown" in maps
236 
237 COSTTYPE *
238 readPGM(const char *fname, int *width, int *height, bool raw)
239 {
240  pm_init("navtest",0);
241 
242  FILE *pgmfile;
243  pgmfile = fopen(fname,"r");
244  if (!pgmfile)
245  {
246  printf("[NavTest] Can't find file %s\n", fname);
247  return NULL;
248  }
249 
250  printf("[NavTest] Reading costmap file %s\n", fname);
251  int ncols, nrows;
252  gray maxval;
253  int format;
254  pgm_readpgminit(pgmfile, &ncols, &nrows, &maxval, &format);
255  printf("[NavTest] Size: %d x %d\n", ncols, nrows);
256 
257  // set up cost map
258  COSTTYPE *cmap = (COSTTYPE *)malloc(ncols*nrows*sizeof(COSTTYPE));
259  if (!raw)
260  for (int i=0; i<ncols*nrows; i++)
261  cmap[i] = COST_NEUTRAL;
262 
263  gray * row(pgm_allocrow(ncols));
264  int otot = 0;
265  int utot = 0;
266  int ftot = 0;
267  for (int ii = 0; ii < nrows; ii++) {
268  pgm_readpgmrow(pgmfile, row, ncols, maxval, format);
269  if (raw) // raw costmap from ROS
270  {
271  for (int jj(ncols - 1); jj >= 0; --jj)
272  {
273  int v = row[jj];
274  cmap[ii*ncols+jj] = v;
275  if (v >= COST_OBS_ROS)
276  otot++;
277  if (v == 0)
278  ftot++;
279  }
280  }
281  else
282  {
283  ftot = ncols*nrows;
284  for (int jj(ncols - 1); jj >= 0; --jj)
285  {
286  if (row[jj] < unknown_gray && ii < nrows-7 && ii > 7)
287  {
288  setcostobs(cmap,ii*ncols+jj,ncols);
289  otot++;
290  ftot--;
291  }
292  else if (row[jj] <= unknown_gray)
293  {
294  setcostunk(cmap,ii*ncols+jj,ncols);
295  utot++;
296  ftot--;
297  }
298  }
299  }
300  }
301  printf("[NavTest] Found %d obstacle cells, %d free cells, %d unknown cells\n", otot, ftot, utot);
302  pgm_freerow(row);
303  *width = ncols;
304  *height = nrows;
305  return cmap;
306 }
Definition: navfn.h:81
void setupNavFn(bool keepit=false)
Definition: navfn.cpp:365
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
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 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
void display(void fn(NavFn *nav), int n=100)
Definition: navfn.cpp:1014
float priInc
Definition: navfn.h:182
int ny
Definition: navfn.h:124


navfn
Author(s): Kurt Konolige, Eitan Marder-Eppstein, contradict@gmail.com
autogenerated on Sun Mar 3 2019 03:44:39