Skip to content

Commit

Permalink
Fixed issue #18.
Browse files Browse the repository at this point in the history
When oscillation is detected during gradient following, calcPath() falls back on simple grid following.
  • Loading branch information
hershwg committed Jan 5, 2013
1 parent 9ddb146 commit 3d65d16
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 8 deletions.
24 changes: 17 additions & 7 deletions navfn/src/navfn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,15 @@ namespace navfn {
pathy[npath] = stc/nx + dy;
npath++;

bool oscillation_detected = false;
if( npath > 2 &&
pathx[npath-1] == pathx[npath-3] &&
pathy[npath-1] == pathy[npath-3] )
{
ROS_DEBUG("[PathCalc] oscillation detected, attempting fix.");
oscillation_detected = true;
}

int stcnx = stc+nx;
int stcpx = stc-nx;

Expand All @@ -877,8 +886,8 @@ namespace navfn {
potarr[stcnx-1] >= POT_HIGH ||
potarr[stcpx] >= POT_HIGH ||
potarr[stcpx+1] >= POT_HIGH ||
potarr[stcpx-1] >= POT_HIGH)

potarr[stcpx-1] >= POT_HIGH ||
oscillation_detected)
{
ROS_DEBUG("[Path] Pot fn boundary, following grid (%0.1f/%d)", potarr[stc], npath);
// check eight neighbors to find the lowest
Expand Down Expand Up @@ -926,11 +935,6 @@ namespace navfn {
gradCell(stcnx+1);


// show gradients
ROS_DEBUG("[Path] %0.2f,%0.2f %0.2f,%0.2f %0.2f,%0.2f %0.2f,%0.2f\n",
gradx[stc], grady[stc], gradx[stc+1], grady[stc+1],
gradx[stcnx], grady[stcnx], gradx[stcnx+1], grady[stcnx+1]);

// get interpolated gradient
float x1 = (1.0-dx)*gradx[stc] + dx*gradx[stc+1];
float x2 = (1.0-dx)*gradx[stcnx] + dx*gradx[stcnx+1];
Expand All @@ -939,6 +943,12 @@ namespace navfn {
float y2 = (1.0-dx)*grady[stcnx] + dx*grady[stcnx+1];
float y = (1.0-dy)*y1 + dy*y2; // interpolated y

// show gradients
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",
gradx[stc], grady[stc], gradx[stc+1], grady[stc+1],
gradx[stcnx], grady[stcnx], gradx[stcnx+1], grady[stcnx+1],
x, y);

// check for zero gradient, failed
if (x == 0.0 && y == 0.0)
{
Expand Down
61 changes: 60 additions & 1 deletion navfn/test/path_calc_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,60 @@ navfn::NavFn* make_willow_nav()
return nav;
}

void print_neighborhood_of_last_path_entry( navfn::NavFn* nav )
{
printf("last path entries:\n");
for( int i = nav->npath - 4; i < nav->npath; i++ )
{
printf("%.3f, %.3f\n", nav->pathx[ i ], nav->pathy[ i ]);
}
printf("potential field neighborhood of last entry:\n");
int xf = nav->pathx[ nav->npath-1 ];
int yf = nav->pathy[ nav->npath-1 ];

printf( " " );
for( int x = xf - 2; x <= xf + 2; x++ )
{
printf( " %6d", x );
}
printf( "\n" );

for( int y = yf - 2; y <= yf + 2; y++ )
{
printf( "%5d:", y );
for( int x = xf - 2; x <= xf + 2; x++ )
{
printf( " %5.1f", nav->potarr[ y * nav->nx + x ] );
}
printf( "\n" );
}

printf("gradient neighborhood of last entry:\n");
printf( " " );
for( int x = xf - 2; x <= xf + 2; x++ )
{
printf( " %6d", x );
}
printf( "\n" );

for( int y = yf - 2; y <= yf + 2; y++ )
{
printf( "%5d x:", y );
for( int x = xf - 2; x <= xf + 2; x++ )
{
printf( " %5.1f", nav->gradx[ y * nav->nx + x ] );
}
printf( "\n" );

printf( " y:" );
for( int x = xf - 2; x <= xf + 2; x++ )
{
printf( " %5.1f", nav->grady[ y * nav->nx + x ] );
}
printf( "\n" );
}
}

TEST(PathCalc, oscillate_in_pinch_point)
{
navfn::NavFn* nav = make_willow_nav();
Expand All @@ -71,7 +125,12 @@ TEST(PathCalc, oscillate_in_pinch_point)
nav->setGoal( goal );
nav->setStart( start );

EXPECT_TRUE( nav->calcNavFnDijkstra( true ));
bool plan_success = nav->calcNavFnDijkstra( true );
EXPECT_TRUE( plan_success );
if( !plan_success )
{
print_neighborhood_of_last_path_entry( nav );
}
}

TEST(PathCalc, easy_nav_should_always_work)
Expand Down

0 comments on commit 3d65d16

Please sign in to comment.