Revision: 4480
http://playerstage.svn.sourceforge.net/playerstage/?rev=4480&view=rev
Author: gerkey
Date: 2008-04-04 18:55:18 -0700 (Fri, 04 Apr 2008)
Log Message:
-----------
more speedups
Modified Paths:
--------------
code/player/trunk/server/drivers/planner/wavefront/plan.c
code/player/trunk/server/drivers/planner/wavefront/plan.h
code/player/trunk/server/drivers/planner/wavefront/plan_plan.c
code/player/trunk/server/drivers/planner/wavefront/test.c
code/player/trunk/server/drivers/planner/wavefront/wavefront.cc
Modified: code/player/trunk/server/drivers/planner/wavefront/plan.c
===================================================================
--- code/player/trunk/server/drivers/planner/wavefront/plan.c 2008-04-05
00:31:33 UTC (rev 4479)
+++ code/player/trunk/server/drivers/planner/wavefront/plan.c 2008-04-05
01:55:18 UTC (rev 4480)
@@ -61,6 +61,8 @@
plan->des_min_radius = des_min_radius;
plan->max_radius = max_radius;
+ plan->dist_kernel_width = 0;
+ plan->dist_kernel = NULL;
plan->dist_penalty = dist_penalty;
//plan->queue_start = 0;
@@ -77,7 +79,43 @@
return plan;
}
+void
+plan_compute_dist_kernel(plan_t* plan)
+{
+ int i,j;
+ float* p;
+ // Compute variable sized kernel, for use in propagating distance from
+ // obstacles
+ plan->dist_kernel_width = 1 + 2 * (int)ceil(plan->max_radius / plan->scale);
+ plan->dist_kernel = (float*)realloc(plan->dist_kernel,
+ sizeof(float) *
+ plan->dist_kernel_width *
+ plan->dist_kernel_width);
+ assert(plan->dist_kernel);
+
+ p = plan->dist_kernel;
+ for(j=-plan->dist_kernel_width/2;j<plan->dist_kernel_width/2;j++)
+ {
+ for(i=-plan->dist_kernel_width/2;i<plan->dist_kernel_width/2;i++,p++)
+ {
+ *p = sqrt(i*i+j*j) * plan->scale;
+ // also compute a 3x3 kernel, used when propagating distance from goal
+ if((abs(i) <= 1) && (abs(j) <= 1))
+ plan->dist_kernel_3x3[i+1][j+1] = *p;
+ }
+ }
+ for(j=0;j<3;j++)
+ {
+ for(i=0;i<3;i++)
+ {
+ printf("%.3f ", plan->dist_kernel_3x3[i][j]);
+ }
+ puts("");
+ }
+}
+
+
// Destroy a planner
void plan_free(plan_t *plan)
{
@@ -85,6 +123,8 @@
free(plan->cells);
heap_free(plan->heap);
free(plan->waypoints);
+ if(plan->dist_kernel)
+ free(plan->dist_kernel);
free(plan);
return;
@@ -97,16 +137,16 @@
int i, j;
plan_cell_t *cell;
+ cell = plan->cells;
for (j = 0; j < plan->size_y; j++)
{
- for (i = 0; i < plan->size_x; i++)
+ for (i = 0; i < plan->size_x; i++, cell++)
{
- cell = plan->cells + PLAN_INDEX(plan, i, j);
cell->ci = i;
cell->cj = j;
cell->occ_state = 0;
cell->occ_dist = plan->max_radius;
- cell->plan_cost = 1e12;
+ cell->plan_cost = PLAN_MAX_COST;
cell->plan_next = NULL;
}
}
@@ -215,35 +255,40 @@
plan_update_cspace_naive(plan_t* plan)
{
int i, j;
- int di, dj, dn;
- double r;
+ int di, dj;
+ float* p;
plan_cell_t *cell, *ncell;
PLAYER_MSG0(2,"Generating C-space....");
- dn = (int) ceil(plan->max_radius / plan->scale);
for (j = plan->min_y; j <= plan->max_y; j++)
{
- for (i = plan->min_x; i <= plan->max_x; i++)
+ cell = plan->cells + PLAN_INDEX(plan, 0, j);
+ for (i = plan->min_x; i <= plan->max_x; i++, cell++)
{
- cell = plan->cells + PLAN_INDEX(plan, i, j);
if (cell->occ_state < 0)
continue;
cell->occ_dist = FLT_MAX;
- for (dj = -dn; dj <= +dn; dj++)
+ p = plan->dist_kernel;
+ for (dj = -plan->dist_kernel_width/2;
+ dj <= plan->dist_kernel_width/2;
+ dj++)
{
- for (di = -dn; di <= +dn; di++)
+ di = -plan->dist_kernel_width/2;
+ //ncell = plan->cells + PLAN_INDEX(plan, i + di, j + dj);
+ ncell = cell + di + dj*plan->size_x;
+ for (; di <= plan->dist_kernel_width/2;
+ di++, ncell++, p++)
{
if (!PLAN_VALID_BOUNDS(plan, i + di, j + dj))
continue;
- ncell = plan->cells + PLAN_INDEX(plan, i + di, j + dj);
- r = plan->scale * sqrt(di * di + dj * dj);
- if (r < ncell->occ_dist)
- ncell->occ_dist = r;
+ //if(*p < ncell->occ_dist)
+ if(0.1 < ncell->occ_dist)
+ ncell->occ_dist = *p;
}
}
}
@@ -317,9 +362,6 @@
int ci, cj;
plan_cell_t* cell;
- ci = PLAN_GXWX(plan, lx);
- cj = PLAN_GYWY(plan, ly);
-
pixels = (guchar*)malloc(sizeof(guchar)*plan->size_x*plan->size_y*3);
p=0;
@@ -363,30 +405,36 @@
}
}
- cell = plan->cells + PLAN_INDEX(plan, ci, cj);
- while (cell != NULL)
+ ci = PLAN_GXWX(plan, lx);
+ cj = PLAN_GYWY(plan, ly);
+
+ if(PLAN_VALID_BOUNDS(plan,ci,cj))
{
- paddr = 3*PLAN_INDEX(plan,cell->ci,plan->size_y - cell->cj - 1);
- pixels[paddr] = 0;
- pixels[paddr+1] = 255;
- pixels[paddr+2] = 0;
+ cell = plan->cells + PLAN_INDEX(plan, ci, cj);
+ while (cell != NULL)
+ {
+ paddr = 3*PLAN_INDEX(plan,cell->ci,plan->size_y - cell->cj - 1);
+ pixels[paddr] = 0;
+ pixels[paddr+1] = 255;
+ pixels[paddr+2] = 0;
- cell = cell->plan_next;
- }
+ cell = cell->plan_next;
+ }
- for(p=0;p<plan->waypoint_count;p++)
- {
- cell = plan->waypoints[p];
- for(j=-3;j<=3;j++)
+ for(p=0;p<plan->waypoint_count;p++)
{
- cj = cell->cj + j;
- for(i=-3;i<=3;i++)
+ cell = plan->waypoints[p];
+ for(j=-3;j<=3;j++)
{
- ci = cell->ci + i;
- paddr = 3*PLAN_INDEX(plan,ci,plan->size_y - cj - 1);
- pixels[paddr] = 255;
- pixels[paddr+1] = 0;
- pixels[paddr+2] = 255;
+ cj = cell->cj + j;
+ for(i=-3;i<=3;i++)
+ {
+ ci = cell->ci + i;
+ paddr = 3*PLAN_INDEX(plan,ci,plan->size_y - cj - 1);
+ pixels[paddr] = 255;
+ pixels[paddr+1] = 0;
+ pixels[paddr+2] = 255;
+ }
}
}
}
@@ -405,119 +453,6 @@
}
#endif
-#if 0
-void
-plan_update_cspace_dp(plan_t* plan)
-{
- int i, j;
- int di, dj, dn;
- double r;
- plan_cell_t *cell, *ncell;
- //heap_t* Q;
- plan_cell_t** Q;
- int qhead, qtail;
-
- PLAYER_MSG0(2,"Generating C-space....");
-
- // We'll look this far away from obstacles when updating cell costs
- dn = (int) ceil(plan->max_radius / plan->scale);
-
- // We'll need space for, at most, dn^2 cells in our queue (which is a
- // binary heap).
- //Q = heap_alloc(dn*dn, NULL);
- Q = (plan_cell_t**)malloc(sizeof(plan_cell_t*)*dn*dn);
- assert(Q);
-
- // Make space for the marks that we'll use.
- if(plan->marks_size != plan->size_x*plan->size_y)
- {
- plan->marks_size = plan->size_x*plan->size_y;
- plan->marks = (unsigned char*)realloc(plan->marks,
- sizeof(unsigned char*) *
- plan->marks_size);
- }
- assert(plan->marks);
-
- // For each obstacle (or unknown cell), spread a wave out in all
- // directions, updating occupancy distances (inverse costs) on the way.
- // Don't ever raise the occupancy distance of a cell.
- for (j = 0; j < plan->size_y; j++)
- {
- for (i = 0; i < plan->size_x; i++)
- {
- cell = plan->cells + PLAN_INDEX(plan, i, j);
- if (cell->occ_state < 0)
- continue;
-
- //cell->occ_dist = plan->max_radius;
- cell->occ_dist = 0.0;
-
- // clear the marks
- memset(plan->marks,0,sizeof(unsigned char)*plan->size_x*plan->size_y);
-
- // Start with the current cell
- //heap_reset(Q);
- //heap_insert(Q, cell->occ_dist, cell);
- qhead = 0;
- Q[qhead] = cell;
- qtail = 1;
-
- //while(!heap_empty(Q))
- while(qtail != qhead)
- {
- //ncell = heap_extract_max(Q);
- ncell = Q[qhead++];
-
- // Mark it, so we don't come back
- plan->marks[PLAN_INDEX(plan, ncell->ci, ncell->cj)] = 1;
-
- // Is this cell an obstacle or unknown cell (and not the initial
- // cell? If so, don't bother updating its cost here.
- if((ncell != cell) && (ncell->occ_state >= 0))
- continue;
-
- // How far are we from the obstacle cell we started with?
- r = plan->scale * hypot(ncell->ci - cell->ci,
- ncell->cj - cell->cj);
-
- // Are we past the distance at which we care?
- if(r > plan->max_radius)
- continue;
-
- // Update the occupancy distance if we're closer
- if(r < ncell->occ_dist)
- {
- ncell->occ_dist = r;
- // Also put its neighbors on the queue for processing
- for(dj = -1; dj <= 1; dj+= 2)
- {
- for(di = -1; di <= 1; di+= 2)
- {
- if (!PLAN_VALID(plan, ncell->ci + di, ncell->cj + dj))
- continue;
- // Have we already seen this cell?
- if(plan->marks[PLAN_INDEX(plan, ncell->ci + di, ncell->cj + dj)])
- continue;
- // Add it to the queue
- /*
- heap_insert(Q, ncell->occ_dist,
- plan->cells + PLAN_INDEX(plan,
- ncell->ci+di,
- ncell->cj+dj));
- */
- Q[qtail++] = plan->cells + PLAN_INDEX(plan,
- ncell->ci+di,
- ncell->cj+dj);
- }
- }
- }
- }
- }
- }
- //heap_free(Q);
-}
-#endif
-
// Construct the configuration space from the occupancy grid.
// This treats both occupied and unknown cells as bad.
//
Modified: code/player/trunk/server/drivers/planner/wavefront/plan.h
===================================================================
--- code/player/trunk/server/drivers/planner/wavefront/plan.h 2008-04-05
00:31:33 UTC (rev 4479)
+++ code/player/trunk/server/drivers/planner/wavefront/plan.h 2008-04-05
01:55:18 UTC (rev 4480)
@@ -66,8 +66,11 @@
// The grid data
plan_cell_t *cells;
- unsigned char* marks;
- size_t marks_size;
+
+ // Distance penalty kernel, pre-computed in plan_compute_dist_kernel();
+ float* dist_kernel;
+ int dist_kernel_width;
+ float dist_kernel_3x3[3][3];
// Queue of cells to update
//int queue_start, queue_len, queue_size;
@@ -84,6 +87,8 @@
plan_t *plan_alloc(double abs_min_radius, double des_min_radius,
double max_radius, double dist_penalty);
+void plan_compute_dist_kernel(plan_t* plan);
+
// Destroy a planner
void plan_free(plan_t *plan);
@@ -106,7 +111,7 @@
void plan_update_cspace(plan_t *plan, const char* cachefile);
// Generate the plan
-void plan_update_plan(plan_t *plan, double gx, double gy);
+void plan_update_plan(plan_t *plan, double lx, double ly, double gx, double
gy);
// Generate a path to the goal
void plan_update_waypoints(plan_t *plan, double px, double py);
Modified: code/player/trunk/server/drivers/planner/wavefront/plan_plan.c
===================================================================
--- code/player/trunk/server/drivers/planner/wavefront/plan_plan.c
2008-04-05 00:31:33 UTC (rev 4479)
+++ code/player/trunk/server/drivers/planner/wavefront/plan_plan.c
2008-04-05 01:55:18 UTC (rev 4480)
@@ -20,18 +20,20 @@
// Generate the plan
-void plan_update_plan(plan_t *plan, double gx, double gy)
+void
+plan_update_plan(plan_t *plan, double lx, double ly, double gx, double gy)
{
int oi, oj, di, dj, ni, nj;
+ int gi, gj, li,lj;
float cost;
plan_cell_t *cell, *ncell;
// Reset the grid
+ cell = plan->cells;
for (nj = 0; nj < plan->size_y; nj++)
{
- for (ni = 0; ni < plan->size_x; ni++)
+ for (ni = 0; ni < plan->size_x; ni++,cell++)
{
- cell = plan->cells + PLAN_INDEX(plan, ni, nj);
cell->plan_cost = PLAN_MAX_COST;
cell->plan_next = NULL;
}
@@ -43,13 +45,20 @@
heap_reset(plan->heap);
// Initialize the goal cell
- ni = PLAN_GXWX(plan, gx);
- nj = PLAN_GYWY(plan, gy);
+ gi = PLAN_GXWX(plan, gx);
+ gj = PLAN_GYWY(plan, gy);
- if (!PLAN_VALID_BOUNDS(plan, ni, nj))
+ if (!PLAN_VALID_BOUNDS(plan, gi, gj))
return;
+
+ // Initialize the start cell
+ li = PLAN_GXWX(plan, lx);
+ lj = PLAN_GYWY(plan, ly);
+
+ if (!PLAN_VALID_BOUNDS(plan, li, lj))
+ return;
- cell = plan->cells + PLAN_INDEX(plan, ni, nj);
+ cell = plan->cells + PLAN_INDEX(plan, gi, gj);
cell->plan_cost = 0;
plan_push(plan, cell);
@@ -83,11 +92,15 @@
if (ncell->occ_dist < plan->abs_min_radius)
continue;
+ /*
if(di && dj)
cost = cell->plan_cost + plan->scale * M_SQRT2;
else
cost = cell->plan_cost + plan->scale;
+ */
+ cost = cell->plan_cost + plan->dist_kernel_3x3[di+1][dj+1];
+
if (ncell->occ_dist < plan->max_radius)
cost += plan->dist_penalty * (plan->max_radius - ncell->occ_dist);
@@ -95,6 +108,10 @@
{
ncell->plan_cost = cost;
ncell->plan_next = cell;
+
+ // Are we done?
+ if((ncell->ci == li) && (ncell->cj == lj))
+ return;
plan_push(plan, ncell);
}
}
Modified: code/player/trunk/server/drivers/planner/wavefront/test.c
===================================================================
--- code/player/trunk/server/drivers/planner/wavefront/test.c 2008-04-05
00:31:33 UTC (rev 4479)
+++ code/player/trunk/server/drivers/planner/wavefront/test.c 2008-04-05
01:55:18 UTC (rev 4480)
@@ -61,6 +61,7 @@
dist_penalty)));
plan->scale = res;
+ plan_compute_dist_kernel(plan);
plan->size_x = sx;
plan->size_y = sy;
plan->origin_x = 0.0;
@@ -97,7 +98,7 @@
// compute costs to the new goal
t_p0 = get_time();
- plan_update_plan(plan, gx, gy);
+ plan_update_plan(plan, lx, ly, gx, gy);
t_p1 = get_time();
// compute a path to the goal from the current position
Modified: code/player/trunk/server/drivers/planner/wavefront/wavefront.cc
===================================================================
--- code/player/trunk/server/drivers/planner/wavefront/wavefront.cc
2008-04-05 00:31:33 UTC (rev 4479)
+++ code/player/trunk/server/drivers/planner/wavefront/wavefront.cc
2008-04-05 01:55:18 UTC (rev 4480)
@@ -507,6 +507,7 @@
// Got new map info pushed to us. We'll save this info and get the new
// map.
this->plan->scale = info->scale;
+ plan_compute_dist_kernel(this->plan);
this->plan->size_x = info->width;
this->plan->size_y = info->height;
this->plan->origin_x = info->origin.px;
@@ -767,7 +768,8 @@
#endif
// compute costs to the new goal
- plan_update_plan(this->plan, this->target_x, this->target_y);
+ plan_update_plan(this->plan, this->localize_x, this->localize_x,
+ this->target_x, this->target_y);
// compute a path to the goal from the current position
plan_update_waypoints(this->plan, this->localize_x, this->localize_y);
@@ -1124,6 +1126,7 @@
{
PLAYER_WARN("failed to get map info");
this->plan->scale = 0.1;
+ plan_compute_dist_kernel(this->plan);
this->plan->size_x = 0;
this->plan->size_y = 0;
this->plan->origin_x = 0.0;
@@ -1135,6 +1138,7 @@
// copy in the map info
this->plan->scale = info->scale;
+ plan_compute_dist_kernel(this->plan);
this->plan->size_x = info->width;
this->plan->size_y = info->height;
this->plan->origin_x = info->origin.px;
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Register now and save $200. Hurry, offer ends at 11:59 p.m.,
Monday, April 7! Use priority code J8TLD2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit