60 float *plan,
int nplan)
62 static NavFn *nav = NULL;
65 nav =
new NavFn(nx,ny);
67 if (nav->
nx != nx || nav->
ny != ny)
70 nav =
new NavFn(nx,ny);
87 ROS_DEBUG(
"[NavFn] Path found, %d steps\n", len);
93 for (
int i=0; i<len; i++)
95 plan[i*2] = nav->
pathx[i];
96 plan[i*2+1] = nav->
pathy[i];
195 ROS_DEBUG(
"[NavFn] Array is %d x %d\n", xs, ys);
233 for (
int i=0; i<
ny; i++)
236 for (
int j=0; j<
nx; j++, k++, cmap++, cm++)
262 for (
int i=0; i<
ny; i++)
265 for (
int j=0; j<
nx; j++, k++, cmap++, cm++)
268 if (i<7 || i > ny-8 || j<7 || j > nx-8)
293 static char costmap_filename[1000];
294 static int file_number = 0;
295 snprintf( costmap_filename, 1000,
"navfn-dijkstra-costmap-%04d", file_number++ );
308 ROS_DEBUG(
"[NavFn] Path found, %d steps\n", len);
337 ROS_DEBUG(
"[NavFn] Path found, %d steps\n", len);
366 ROS_INFO(
"[NavFn] Setting simple obstacle\n");
368 for (
int i=
ny/3; i<
ny; i++)
371 for (
int i=ny/3; i<
ny; i++)
375 for (
int i=20; i<ny-ny/3; i++)
378 for (
int i=20; i<ny-ny/3; i++)
381 for (
int i=20; i<ny-ny/3; i++)
388 #define push_cur(n) { if (n>=0 && n<ns && !pending[n] && \ 389 costarr[n]<COST_OBS && curPe<PRIORITYBUFSIZE) \ 390 { curP[curPe++]=n; pending[n]=true; }} 391 #define push_next(n) { if (n>=0 && n<ns && !pending[n] && \ 392 costarr[n]<COST_OBS && nextPe<PRIORITYBUFSIZE) \ 393 { nextP[nextPe++]=n; pending[n]=true; }} 394 #define push_over(n) { if (n>=0 && n<ns && !pending[n] && \ 395 costarr[n]<COST_OBS && overPe<PRIORITYBUFSIZE) \ 396 { overP[overPe++]=n; pending[n]=true; }} 405 for (
int i=0; i<
ns; i++)
415 for (
int i=0; i<
nx; i++)
418 for (
int i=0; i<
nx; i++)
421 for (
int i=0; i<
ny; i++, pc+=
nx)
424 for (
int i=0; i<
ny; i++, pc+=
nx)
435 memset(
pending, 0, ns*
sizeof(
bool));
444 for (
int i=0; i<
ns; i++, pc++)
474 #define INVSQRT2 0.707106781 491 if (l<r) tc=l;
else tc=r;
492 if (u<d) ta=u;
else ta=d;
515 float v = -0.2301*d*d + 0.5307*d + 0.7040;
559 #define INVSQRT2 0.707106781 576 if (l<r) tc=l;
else tc=r;
577 if (u<d) ta=u;
else ta=d;
600 float v = -0.2301*d*d + 0.5307*d + 0.7040;
661 for (; cycle < cycles; cycle++)
711 ROS_DEBUG(
"[NavFn] Used %d cycles, %d cells visited (%d%%), priority buf max %d\n",
712 cycle,nc,(
int)((nc*100.0)/(
ns-
nobs)),nwv);
714 if (cycle < cycles)
return true;
743 for (; cycle < cycles; cycle++)
795 ROS_DEBUG(
"[NavFn] Used %d cycles, %d cells visited (%d%%), priority buf max %d\n",
796 cycle,nc,(
int)((nc*100.0)/(
ns-
nobs)),nwv);
832 pathx =
new float[n];
833 pathy =
new float[n];
839 if (st == NULL) st =
start;
840 int stc = st[1]*
nx + st[0];
848 for (
int i=0; i<n; i++)
851 int nearest_point=std::max(0,std::min(
nx*
ny-1,stc+(
int)round(dx)+(
int)(
nx*round(dy))));
859 if (stc < nx || stc >
ns-
nx)
870 bool oscillation_detected =
false;
875 ROS_DEBUG(
"[PathCalc] oscillation detected, attempting fix.");
876 oscillation_detected =
true;
892 oscillation_detected)
918 ROS_DEBUG(
"[Path] Pot: %0.1f pos: %0.1f,%0.1f",
923 ROS_DEBUG(
"[PathCalc] No path found, high potential");
941 float x1 = (1.0-dx)*
gradx[stc] + dx*
gradx[stc+1];
942 float x2 = (1.0-dx)*
gradx[stcnx] + dx*
gradx[stcnx+1];
943 float x = (1.0-dy)*x1 + dy*x2;
944 float y1 = (1.0-dx)*
grady[stc] + dx*
grady[stc+1];
945 float y2 = (1.0-dx)*
grady[stcnx] + dx*
grady[stcnx+1];
946 float y = (1.0-dy)*y1 + dy*y2;
949 ROS_DEBUG(
"[Path] %0.2f,%0.2f %0.2f,%0.2f %0.2f,%0.2f %0.2f,%0.2f; final x=%.3f, y=%.3f\n",
955 if (x == 0.0 && y == 0.0)
967 if (dx > 1.0) { stc++; dx -= 1.0; }
968 if (dx < -1.0) { stc--; dx += 1.0; }
969 if (dy > 1.0) { stc+=
nx; dy -= 1.0; }
970 if (dy < -1.0) { stc-=
nx; dy += 1.0; }
979 ROS_DEBUG(
"[PathCalc] No path found, path too long");
997 if (n < nx || n >
ns-
nx)
1028 dy += potarr[n-
nx]- cv;
1030 dy += cv - potarr[n+
nx];
1034 float norm =
hypot(dx, dy);
1068 ROS_DEBUG(
"[NavFn] Saving costmap and start/goal points");
1070 sprintf(fn,
"%s.txt",fname);
1071 FILE *fp = fopen(fn,
"w");
1074 ROS_WARN(
"Can't open file %s", fn);
1082 sprintf(fn,
"%s.pgm",fname);
1083 fp = fopen(fn,
"wb");
1086 ROS_WARN(
"Can't open file %s", fn);
1089 fprintf(fp,
"P5\n%d\n%d\n%d\n",
nx,
ny, 0xff);
void updateCell(int n)
Updates the cell at index n.
void setupNavFn(bool keepit=false)
NavFn(int nx, int ny)
Constructs the planner.
float * getPathY()
Accessor for the y-coordinates of a path.
int create_nav_plan_astar(const COSTTYPE *costmap, int nx, int ny, int *goal, int *start, float *plan, int nplan)
void(* displayFn)(NavFn *nav)
void updateCellAstar(int n)
Updates the cell at index n using the A* heuristic.
INLINE Rall1d< T, V, S > hypot(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
void setStart(int *start)
Sets the start position for the planner. Note: the navigation cost field computed gives the cost to g...
void setCostmap(const COSTTYPE *cmap, bool isROS=true, bool allow_unknown=true)
Set up the cost array for the planner, usually from ROS.
bool calcNavFnDijkstra(bool atStart=false)
Caclulates the full navigation function using Dijkstra.
TFSIMD_FORCE_INLINE const tfScalar & y() const
float getLastPathCost()
Gets the cost of the path found the last time a navigation function was computed. ...
void setGoal(int *goal)
Sets the goal position for the planner. Note: the navigation cost field computed gives the cost to ge...
Navigation function class. Holds buffers for costmap, navfn map. Maps are pixel-based. Origin is upper left, x is right, y is down.
TFSIMD_FORCE_INLINE const tfScalar & x() const
int calcPath(int n, int *st=NULL)
Calculates the path for at mose <n> cycles.
void initCost(int k, float v)
Initialize cell k with cost v for propagation.
void savemap(const char *fname)
bool propNavFnDijkstra(int cycles, bool atStart=false)
Run propagation for <cycles> iterations, or until start is reached using breadth-first Dijkstra metho...
void display(void fn(NavFn *nav), int n=100)
int getPathLen()
Accessor for the length of a path.
void setNavArr(int nx, int ny)
Sets or resets the size of the map.
float * getPathX()
Accessor for the x-coordinates of a path.
bool calcNavFnAstar()
Calculates a plan using the A* heuristic, returns true if one is found.
bool propNavFnAstar(int cycles)
Run propagation for <cycles> iterations, or until start is reached using the best-first A* method wit...