Revision: 6361
          http://playerstage.svn.sourceforge.net/playerstage/?rev=6361&view=rev
Author:   gbiggs
Date:     2008-04-18 01:10:03 -0700 (Fri, 18 Apr 2008)

Log Message:
-----------
Merging changes 6287:6302 from trunk

Modified Paths:
--------------
    code/player/branches/cmake/libplayercore/driver.h
    code/player/branches/cmake/server/drivers/planner/wavefront/CMakeLists.txt
    code/player/branches/cmake/server/drivers/planner/wavefront/Makefile.test
    code/player/branches/cmake/server/drivers/planner/wavefront/plan.c
    code/player/branches/cmake/server/drivers/planner/wavefront/plan.h
    code/player/branches/cmake/server/drivers/planner/wavefront/plan_plan.c
    code/player/branches/cmake/server/drivers/planner/wavefront/wavefront.cc
    code/player/branches/cmake/server/drivers/shell/passthrough.cc

Added Paths:
-----------
    code/player/branches/cmake/server/drivers/planner/wavefront/plan_control.c

Modified: code/player/branches/cmake/libplayercore/driver.h
===================================================================
--- code/player/branches/cmake/libplayercore/driver.h   2008-04-18 08:07:57 UTC 
(rev 6360)
+++ code/player/branches/cmake/libplayercore/driver.h   2008-04-18 08:10:03 UTC 
(rev 6361)
@@ -189,7 +189,7 @@
     @param timestamp Timestamp for the message body (if NULL, then the
     current time will be filled in)
     @param copy if set to false the data will be claimed and the caller should 
no longer use or free it */
-    void Publish(player_devaddr_t addr,
+    virtual void Publish(player_devaddr_t addr,
                  QueuePointer &queue,
                  uint8_t type,
                  uint8_t subtype,
@@ -211,7 +211,7 @@
      @param timestamp Timestamp for the message body (if NULL, then the
      current time will be filled in)
      @param copy if set to false the data will be claimed and the caller 
should no longer use or free it */
-     void Publish(player_devaddr_t addr, 
+     virtual void Publish(player_devaddr_t addr, 
                   uint8_t type, 
                   uint8_t subtype,
                   void* src=NULL, 
@@ -229,7 +229,7 @@
     @param hdr The message header
     @param src The message body 
     @param copy if set to false the data will be claimed and the caller should 
no longer use or free it */
-    void Publish(QueuePointer &queue,
+    virtual void Publish(QueuePointer &queue,
                  player_msghdr_t* hdr,
                  void* src,
                  bool copy = true);
@@ -241,7 +241,7 @@
     @param hdr The message header
     @param src The message body 
     @param copy if set to false the data will be claimed and the caller should 
no longer use or free it */ 
-    void Publish(player_msghdr_t* hdr,
+    virtual void Publish(player_msghdr_t* hdr,
                  void* src,
                  bool copy = true);
 

Modified: 
code/player/branches/cmake/server/drivers/planner/wavefront/CMakeLists.txt
===================================================================
--- code/player/branches/cmake/server/drivers/planner/wavefront/CMakeLists.txt  
2008-04-18 08:07:57 UTC (rev 6360)
+++ code/player/branches/cmake/server/drivers/planner/wavefront/CMakeLists.txt  
2008-04-18 08:10:03 UTC (rev 6361)
@@ -3,4 +3,4 @@
     wavefront_includeDir wavefront_libDir wavefront_linkFlags wavefront_cFlags)
 PLAYERDRIVER_ADD_DRIVER (wavefront build_wavefront
     "${wavefront_includeDir}" "${wavefront_libDir}" "${wavefront_linkFlags}" 
"${wavefront_cFlags}"
-    plan.c plan_plan.c plan_waypoint.c wavefront.cc heap.c)
\ No newline at end of file
+    plan.c plan_plan.c plan_waypoint.c wavefront.cc heap.c plan_control.c)
\ No newline at end of file

Modified: 
code/player/branches/cmake/server/drivers/planner/wavefront/Makefile.test
===================================================================
--- code/player/branches/cmake/server/drivers/planner/wavefront/Makefile.test   
2008-04-18 08:07:57 UTC (rev 6360)
+++ code/player/branches/cmake/server/drivers/planner/wavefront/Makefile.test   
2008-04-18 08:10:03 UTC (rev 6361)
@@ -2,7 +2,7 @@
 CFLAGS = -I. -I../../../.. -Wall -Werror -g  `pkg-config --cflags 
gdk-pixbuf-2.0`
 LIBS = -L../../../../libplayercore/.libs -lplayererror `pkg-config --libs 
gdk-pixbuf-2.0`
 
-SRCS = test.c plan.c plan_plan.c plan_waypoint.c heap.c
+SRCS = test.c plan.c plan_plan.c plan_waypoint.c heap.c plan_control.c
 
 test: $(SRCS) plan.h heap.h
        gcc $(CFLAGS) -o $@ $(SRCS) $(LIBS)

Modified: code/player/branches/cmake/server/drivers/planner/wavefront/plan.c
===================================================================
--- code/player/branches/cmake/server/drivers/planner/wavefront/plan.c  
2008-04-18 08:07:57 UTC (rev 6360)
+++ code/player/branches/cmake/server/drivers/planner/wavefront/plan.c  
2008-04-18 08:10:03 UTC (rev 6361)
@@ -180,18 +180,11 @@
 }
 
 // Initialize the plan
-void plan_init(plan_t *plan, 
-               double res, double sx, double sy, double ox, double oy)
+void plan_init(plan_t *plan)
 {
   int i, j;
   plan_cell_t *cell;
 
-  plan->scale = res;
-  plan->size_x = sx;
-  plan->size_y = sy;
-  plan->origin_x = ox;
-  plan->origin_y = oy;
-
   cell = plan->cells;
   for (j = 0; j < plan->size_y; j++)
   {
@@ -224,9 +217,9 @@
 
   for (j = plan->min_y; j <= plan->max_y; j++)
   {
-    cell = plan->cells + PLAN_INDEX(plan,plan->min_x,j);
-    for (i = plan->min_x; i <= plan->max_x; i++, cell++)
+    for (i = plan->min_x; i <= plan->max_x; i++)
     {
+      cell = plan->cells + PLAN_INDEX(plan,i,j);
       cell->plan_cost = PLAN_MAX_COST;
       cell->plan_next = NULL;
       cell->mark = 0;
@@ -380,7 +373,7 @@
   }
 }
 
-#if 1
+#if 0
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
         void

Modified: code/player/branches/cmake/server/drivers/planner/wavefront/plan.h
===================================================================
--- code/player/branches/cmake/server/drivers/planner/wavefront/plan.h  
2008-04-18 08:07:57 UTC (rev 6360)
+++ code/player/branches/cmake/server/drivers/planner/wavefront/plan.h  
2008-04-18 08:10:03 UTC (rev 6361)
@@ -109,8 +109,7 @@
 void plan_free(plan_t *plan);
 
 // Initialize the plan
-void plan_init(plan_t *plan, 
-               double res, double sx, double sy, double ox, double oy);
+void plan_init(plan_t *plan);
 
 // Reset the plan
 void plan_reset(plan_t *plan);
@@ -145,6 +144,10 @@
 void plan_convert_waypoint(plan_t* plan, plan_cell_t *waypoint, 
                            double *px, double *py);
 
+double plan_get_carrot(plan_t* plan, double* px, double* py, 
+                       double lx, double ly, 
+                       double maxdist, double distweight);
+
 #if HAVE_OPENSSL_MD5_H && HAVE_LIBCRYPTO
 // Write the cspace occupancy distance values to a file, one per line.
 // Read them back in with plan_read_cspace().

Copied: 
code/player/branches/cmake/server/drivers/planner/wavefront/plan_control.c 
(from rev 6302, 
code/player/trunk/server/drivers/planner/wavefront/plan_control.c)
===================================================================
--- code/player/branches/cmake/server/drivers/planner/wavefront/plan_control.c  
                        (rev 0)
+++ code/player/branches/cmake/server/drivers/planner/wavefront/plan_control.c  
2008-04-18 08:10:03 UTC (rev 6361)
@@ -0,0 +1,151 @@
+#include <stdlib.h>
+
+#include "plan.h"
+
+double _plan_check_path(plan_t* plan, plan_cell_t* s, plan_cell_t* g);
+
+double
+plan_get_carrot(plan_t* plan, double* px, double* py, 
+                double lx, double ly, double maxdist, double distweight)
+{
+  plan_cell_t* cell, *ncell;
+  int li, lj;
+  double dist, d;
+  double cost, bestcost;
+
+  li = PLAN_GXWX(plan, lx);
+  lj = PLAN_GYWY(plan, ly);
+
+  cell = plan->cells + PLAN_INDEX(plan,li,lj);
+
+  // Step back from maxdist, looking for the best carrot
+  bestcost = -1.0;
+  for(dist = maxdist; dist >= plan->scale; dist -= plan->scale)
+  {
+    // Find a point the required distance ahead, following the cost gradient
+    d=plan->scale;
+    for(ncell = cell;
+        (ncell->plan_next && (d < dist));
+        ncell = ncell->plan_next, d+=plan->scale);
+
+    // Check whether the straight-line path is clear
+    if((cost = _plan_check_path(plan, cell, ncell)) < 0.0)
+      continue;
+
+    // Weight distance
+    cost += distweight * (1.0/(dist*dist));
+    if((bestcost < 0.0) || (cost < bestcost))
+    {
+      bestcost = cost;
+      *px = PLAN_WXGX(plan,ncell->ci);
+      *py = PLAN_WYGY(plan,ncell->cj);
+    }
+  }
+
+  return(bestcost);
+}
+
+double
+_plan_check_path(plan_t* plan, plan_cell_t* s, plan_cell_t* g)
+{
+  // Bresenham raytracing
+  int x0,x1,y0,y1;
+  int x,y;
+  int xstep, ystep;
+  char steep;
+  int tmp;
+  int deltax, deltay, error, deltaerr;
+  int obscost=0;
+
+  x0 = s->ci;
+  y0 = s->cj;
+  
+  x1 = g->ci;
+  y1 = g->cj;
+
+  if(abs(y1-y0) > abs(x1-x0))
+    steep = 1;
+  else
+    steep = 0;
+
+  if(steep)
+  {
+    tmp = x0;
+    x0 = y0;
+    y0 = tmp;
+
+    tmp = x1;
+    x1 = y1;
+    y1 = tmp;
+  }
+
+  deltax = abs(x1-x0);
+  deltay = abs(y1-y0);
+  error = 0;
+  deltaerr = deltay;
+
+  x = x0;
+  y = y0;
+
+  if(x0 < x1)
+    xstep = 1;
+  else
+    xstep = -1;
+  if(y0 < y1)
+    ystep = 1;
+  else
+    ystep = -1;
+
+  if(steep)
+  {
+    if(plan->cells[PLAN_INDEX(plan,y,x)].occ_dist_dyn < plan->abs_min_radius)
+      return -1;
+    else
+      obscost += plan->dist_penalty * 
+              (plan->abs_min_radius - 
+               plan->cells[PLAN_INDEX(plan,y,x)].occ_dist_dyn);
+  }
+  else
+  {
+    if(plan->cells[PLAN_INDEX(plan,x,y)].occ_dist_dyn < plan->abs_min_radius)
+      return -1;
+    else
+      obscost += plan->dist_penalty * 
+              (plan->abs_min_radius - 
+               plan->cells[PLAN_INDEX(plan,x,y)].occ_dist_dyn);
+  }
+
+  while(x != (x1 + xstep * 1))
+  {
+    x += xstep;
+    error += deltaerr;
+    if(2*error >= deltax)
+    {
+      y += ystep;
+      error -= deltax;
+    }
+
+    if(steep)
+    {
+      if(plan->cells[PLAN_INDEX(plan,y,x)].occ_dist_dyn < plan->abs_min_radius)
+        return -1;
+      else
+        obscost += plan->dist_penalty * 
+                (plan->abs_min_radius - 
+                 plan->cells[PLAN_INDEX(plan,y,x)].occ_dist_dyn);
+    }
+    else
+    {
+      if(plan->cells[PLAN_INDEX(plan,x,y)].occ_dist_dyn < plan->abs_min_radius)
+        return -1;
+      else
+        obscost += plan->dist_penalty * 
+                (plan->abs_min_radius - 
+                 plan->cells[PLAN_INDEX(plan,x,y)].occ_dist_dyn);
+    }
+  }
+
+  return(obscost);
+}
+
+

Modified: 
code/player/branches/cmake/server/drivers/planner/wavefront/plan_plan.c
===================================================================
--- code/player/branches/cmake/server/drivers/planner/wavefront/plan_plan.c     
2008-04-18 08:07:57 UTC (rev 6360)
+++ code/player/branches/cmake/server/drivers/planner/wavefront/plan_plan.c     
2008-04-18 08:10:03 UTC (rev 6361)
@@ -13,6 +13,9 @@
 #include <limits.h>
 #include <float.h>
 
+#include <sys/time.h>
+static double get_time(void);
+
 #include "plan.h"
 
 // Plan queue stuff
@@ -27,7 +30,10 @@
 {
   plan_cell_t* cell;
   int li, lj;
+  double t0,t1;
 
+  t0 = get_time();
+
   // Set bounds to look over the entire grid
   plan_set_bounds(plan, 0, 0, plan->size_x - 1, plan->size_y - 1);
 
@@ -35,7 +41,7 @@
   plan_reset(plan);
 
   plan->path_count = 0;
-  if(_plan_update_plan(plan, lx, ly, gx, gy) != 0)
+  if(_plan_update_plan(plan, lx, ly, gx, gy) < 0)
   {
     // no path
     return(-1);
@@ -59,6 +65,10 @@
     plan->path[plan->path_count++] = cell;
   }
 
+  t1 = get_time();
+
+  printf("computed global path: %.6lf\n", t1-t0);
+
   return(0);
 }
 
@@ -69,7 +79,10 @@
   int li, lj;
   int xmin,ymin,xmax,ymax;
   plan_cell_t* cell;
+  double t0,t1;
 
+  t0 = get_time();
+
   // Set bounds as directed
   xmin = PLAN_GXWX(plan, lx - plan_halfwidth);
   ymin = PLAN_GXWX(plan, ly - plan_halfwidth);
@@ -87,8 +100,9 @@
     return(-1);
   }
 
-  printf("local goal: %.3lf, %.3lf\n", gx, gy);
+  //printf("local goal: %.3lf, %.3lf\n", gx, gy);
 
+  plan->lpath_count = 0;
   if(_plan_update_plan(plan, lx, ly, gx, gy) != 0)
   {
     puts("local plan update failed");
@@ -112,6 +126,10 @@
     }
     plan->lpath[plan->lpath_count++] = cell;
   }
+
+  t1 = get_time();
+
+  printf("computed local path: %.6lf\n", t1-t0);
   return(0);
 }
 
@@ -124,7 +142,6 @@
   int gi, gj, li,lj;
   float cost;
   plan_cell_t *cell, *ncell;
-  int reached_start=0;
 
   // Reset the queue
   heap_reset(plan->heap);
@@ -137,7 +154,7 @@
   li = PLAN_GXWX(plan, lx);
   lj = PLAN_GYWY(plan, ly);
 
-  printf("planning from %d,%d to %d,%d\n", li,lj,gi,gj);
+  //printf("planning from %d,%d to %d,%d\n", li,lj,gi,gj);
 
   if(!PLAN_VALID_BOUNDS(plan, gi, gj))
   {
@@ -199,24 +216,19 @@
           ncell->plan_cost = cost;
           ncell->plan_next = cell;
 
-          // Are we done?
-          if((ncell->ci == li) && (ncell->cj == lj))
-            reached_start=1;
-
           plan_push(plan, ncell);
         }
       }
     }
   }
 
-  /*
-  if(!reached_start)
+  cell = plan->cells + PLAN_INDEX(plan, li, lj);
+  if(!cell->plan_next)
   {
     puts("never found start");
     return(-1);
   }
   else
-  */
     return(0);
 }
 
@@ -314,3 +326,11 @@
   else
     return(heap_extract_max(plan->heap));
 }
+
+double 
+static get_time(void)
+{
+  struct timeval curr;
+  gettimeofday(&curr,NULL);
+  return(curr.tv_sec + curr.tv_usec / 1e6);
+}

Modified: 
code/player/branches/cmake/server/drivers/planner/wavefront/wavefront.cc
===================================================================
--- code/player/branches/cmake/server/drivers/planner/wavefront/wavefront.cc    
2008-04-18 08:07:57 UTC (rev 6360)
+++ code/player/branches/cmake/server/drivers/planner/wavefront/wavefront.cc    
2008-04-18 08:10:03 UTC (rev 6361)
@@ -297,6 +297,8 @@
     bool always_insert_rotational_waypoints;
     // Should map be updated on every new goal?
     int force_map_refresh;
+    // Should we do velocity control, or position control?
+    bool velocity_control;
 
     // methods for internal use
     int SetupLocalize();
@@ -388,6 +390,7 @@
   this->always_insert_rotational_waypoints =
           cf->ReadInt(section, "add_rotational_waypoints", 1);
   this->force_map_refresh = cf->ReadInt(section, "force_map_refresh", 0);
+  this->velocity_control = cf->ReadInt(section, "velocity_control", 0);
 }
 
 
@@ -412,8 +415,9 @@
   this->new_goal = false;
 
   this->waypoint_count = 0;
-  this->waypoints = NULL;
-  this->waypoints_allocated = 0;
+  this->waypoints_allocated = 8;
+  this->waypoints = (double (*)[2])malloc(this->waypoints_allocated * 
+                                          sizeof(this->waypoints[0]));
 
   if(SetupPosition() < 0)
     return(-1);
@@ -507,14 +511,10 @@
   // 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;
   this->plan->origin_y = info->origin.py;
-  // Set the bounds to search the whole grid.
-  plan_set_bounds(this->plan,
-                  0, 0, this->plan->size_x - 1, this->plan->size_y - 1);
 
   // Now get the map data, possibly in separate tiles.
   if(this->GetMap(true) < 0)
@@ -608,6 +608,7 @@
                          (void*)&vel_cmd,sizeof(vel_cmd),NULL);
   }
 
+  this->stopped = false;
 }
 
 void
@@ -659,8 +660,6 @@
   this->waypoint_odom_x = wx_odom;
   this->waypoint_odom_y = wy_odom;
   this->waypoint_odom_a = wa_odom;
-
-  this->stopped = false;
 }
 
 
@@ -676,6 +675,7 @@
   double replan_timediff, replan_dist;
   bool rotate_waypoint=false;
   bool replan;
+  int rotate_dir=0;
 
   pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
 
@@ -717,7 +717,7 @@
             !this->atgoal;
 
     // Did we get a new goal, or is it time to replan?
-    if(this->new_goal || replan)
+    if(this->new_goal || replan || (this->velocity_control && !this->atgoal))
     {
 #if 0
       // Should we get a new map?
@@ -768,101 +768,78 @@
 #endif
 
       // compute costs to the new goal.  Try local plan first
-      if(plan_do_local(this->plan, this->localize_x, this->localize_y, 5.0) < 
0)
+      if(new_goal ||
+         (this->plan->path_count == 0) ||
+         (plan_do_local(this->plan, this->localize_x, 
+                         this->localize_y, 5.0) < 0))
       {
-        puts("Wavefront: local plan failed");
+        if(!new_goal && (this->plan->path_count != 0))
+           puts("Wavefront: local plan failed");
 
-        if(plan_do_global(this->plan, this->localize_x, this->localize_x, 
+        // Create a global plan
+        if(plan_do_global(this->plan, this->localize_x, this->localize_y, 
                           this->target_x, this->target_y) < 0)
           puts("Wavefront: global plan failed");
+        else
+          this->new_goal = false;
       }
-                       
-      // extract waypoints along the path to the goal from the current position
-      plan_update_waypoints(this->plan, this->localize_x, this->localize_y);
 
-#if 0
-      if(this->plan->waypoint_count == 0)
+      if(!this->velocity_control)
       {
-        // No path.  If we only searched a bounding box last time, grow the
-        // bounds to encompass the whole map and try again.
-        if((plan->min_x > 0) || (plan->max_x < (plan->size_x - 1)) ||
-           (plan->min_y > 0) || (plan->max_y < (plan->size_y - 1)))
-        {
-          // Unfortunately, this computation can take a while (e.g., 1-2
-          // seconds).  So we'll stop the robot while it thinks.
-          this->StopPosition();
+        // extract waypoints along the path to the goal from the current 
position
+        plan_update_waypoints(this->plan, this->localize_x, this->localize_y);
 
-          // Set the bounds to search the whole grid.
-          plan_set_bounds(this->plan, 0, 0,
-                          this->plan->size_x - 1,
-                          this->plan->size_y - 1);
-
-          struct timeval t0, t1;
-          gettimeofday(&t0, NULL);
-          plan_update_cspace(this->plan,this->cspace_fname);
-          gettimeofday(&t1, NULL);
-          printf("time to update: %f\n",
-               (t1.tv_sec + t1.tv_usec/1e6) -
-               (t0.tv_sec + t0.tv_usec/1e6));
-
-          // compute costs to the new goal
-          plan_update_plan(this->plan, 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);
-        }
-      }
-#endif
-
-      if(this->plan->waypoint_count == 0)
-      {
-        fprintf(stderr, "Wavefront (port %d):\n  "
-                "No path from (%.3lf,%.3lf,%.3lf) to (%.3lf,%.3lf,%.3lf)\n",
-                this->device_addr.robot,
-                this->localize_x,
-                this->localize_y,
-                RTOD(this->localize_a),
-                this->target_x,
-                this->target_y,
-                RTOD(this->target_a));
-        // Only fail here if this is our first try at making a plan;
-        // if we're replanning and don't find a path then we'll just stick
-        // with the old plan.
-        if(this->curr_waypoint < 0)
+        if(this->plan->waypoint_count == 0)
         {
-          //this->curr_waypoint = -1;
-          this->new_goal=false;
-          this->waypoint_count = 0;
+          fprintf(stderr, "Wavefront (port %d):\n  "
+                  "No path from (%.3lf,%.3lf,%.3lf) to (%.3lf,%.3lf,%.3lf)\n",
+                  this->device_addr.robot,
+                  this->localize_x,
+                  this->localize_y,
+                  RTOD(this->localize_a),
+                  this->target_x,
+                  this->target_y,
+                  RTOD(this->target_a));
+          // Only fail here if this is our first try at making a plan;
+          // if we're replanning and don't find a path then we'll just stick
+          // with the old plan.
+          if(this->curr_waypoint < 0)
+          {
+            //this->curr_waypoint = -1;
+            this->new_goal=false;
+            this->waypoint_count = 0;
+          }
         }
-      }
-      else
-        if (this->plan->waypoint_count > this->waypoints_allocated)
+        else
         {
-          this->waypoints = (double (*)[2])realloc(this->waypoints, 
sizeof(this->waypoints[0])*this->plan->waypoint_count);
-          this->waypoints_allocated = this->plan->waypoint_count;
+          if (this->plan->waypoint_count > this->waypoints_allocated)
+          {
+            this->waypoints = (double (*)[2])realloc(this->waypoints, 
sizeof(this->waypoints[0])*this->plan->waypoint_count);
+            this->waypoints_allocated = this->plan->waypoint_count;
+          }
+          this->waypoint_count = this->plan->waypoint_count;
         }
-        this->waypoint_count = this->plan->waypoint_count;
 
-      if(this->plan->waypoint_count > 0)
-      {
-        for(int i=0;i<this->plan->waypoint_count;i++)
+        if(this->plan->waypoint_count > 0)
         {
-          double wx, wy;
-          plan_convert_waypoint(this->plan,
-                                this->plan->waypoints[i],
-                                &wx, &wy);
-          this->waypoints[i][0] = wx;
-          this->waypoints[i][1] = wy;
+          for(int i=0;i<this->plan->waypoint_count;i++)
+          {
+            double wx, wy;
+            plan_convert_waypoint(this->plan,
+                                  this->plan->waypoints[i],
+                                  &wx, &wy);
+            this->waypoints[i][0] = wx;
+            this->waypoints[i][1] = wy;
+          }
+
+          this->curr_waypoint = 0;
+          // Why is this here?
+          this->new_goal = true;
         }
-
-        this->curr_waypoint = 0;
-        this->new_goal = true;
+        last_replan_time = t;
+        last_replan_lx = this->localize_x;
+        last_replan_ly = this->localize_y;
       }
-      last_replan_time = t;
-      last_replan_lx = this->localize_x;
-      last_replan_ly = this->localize_y;
     }
 
     if(!this->enable)
@@ -872,95 +849,191 @@
       continue;
     }
 
-    bool going_for_target = (this->curr_waypoint == 
this->plan->waypoint_count);
-    dist = sqrt(((this->localize_x - this->target_x) *
-                 (this->localize_x - this->target_x)) +
-                ((this->localize_y - this->target_y) *
-                 (this->localize_y - this->target_y)));
-    // Note that we compare the current heading and waypoint heading in the
-    // *odometric* frame.   We do this because comparing the current
-    // heading and waypoint heading in the localization frame is unreliable
-    // when making small adjustments to achieve a desired heading (i.e., the
-    // robot gets there and VFH stops, but here we don't realize we're done
-    // because the localization heading hasn't changed sufficiently).
-    angle = fabs(this->angle_diff(this->waypoint_odom_a,this->position_a));
-    if(going_for_target && dist < this->dist_eps && angle < this->ang_eps)
+
+    if(this->velocity_control)
     {
-      // we're at the final target, so stop
-      StopPosition();
-      this->curr_waypoint = -1;
-      this->new_goal = false;
-      this->atgoal = true;
+      if(this->plan->path_count && !this->atgoal)
+      {
+        // Check doneness
+        dist = sqrt(((this->localize_x - this->target_x) *
+                     (this->localize_x - this->target_x)) +
+                    ((this->localize_y - this->target_y) *
+                     (this->localize_y - this->target_y)));
+        angle = fabs(this->angle_diff(this->target_a,this->localize_a));
+        if((dist < this->dist_eps) && (angle < this->ang_eps))
+        {
+          this->StopPosition();
+          this->new_goal = false;
+          this->curr_waypoint = -1;
+          this->atgoal = true;
+        }
+        else
+        {
+          // Compute velocities
+          double wx, wy;
+          double maxd=2.0;
+          double distweight=10.0;
+
+          if(plan_get_carrot(this->plan, &wx, &wy,
+                             this->localize_x, this->localize_y,
+                             maxd, distweight) < 0)
+          {
+            puts("Failed to find a carrot");
+            this->StopPosition();
+          }
+          else
+          {
+            // Establish fake waypoints, for client-side visualization
+            this->curr_waypoint = 0;
+            this->waypoint_count = 2;
+            this->waypoints[0][0] = this->localize_x;
+            this->waypoints[0][1] = this->localize_y;
+            this->waypoint_x = this->waypoints[1][0] = wx;
+            this->waypoint_y = this->waypoints[1][1] = wy;
+            this->waypoint_a = 0.0;
+
+            // TODO: expose these control params in the .cfg file
+            double tvmin = 0.1;
+            double tvmax = 0.5;
+            double avmin = DTOR(10.0);
+            double avmax = DTOR(45.0);
+            double amin = DTOR(5.0);
+            double amax = DTOR(20.0);
+
+            double d = sqrt((this->localize_x-wx)*(this->localize_x-wx) +
+                            (this->localize_y-wy)*(this->localize_y-wy));
+            double b = atan2(wy - this->localize_y, wx - this->localize_x);
+
+            double av,tv;
+            double a = amin + (d / maxd) * (amax-amin);
+            double ad = angle_diff(b, this->localize_a);
+
+            // Are we on top of the goal?
+            if(d < this->dist_eps)
+            {
+              if(!rotate_dir)
+              {
+                if(ad < 0)
+                  rotate_dir = -1;
+                else
+                  rotate_dir = 1;
+              }
+
+              tv = 0.0;
+              av = rotate_dir * (avmin + (fabs(ad)/M_PI) * (avmax-avmin));
+            }
+            else
+            {
+              rotate_dir = 0;
+
+              if(fabs(ad) > a)
+                tv = 0.0;
+              else
+                tv = tvmin + (d / (M_SQRT2 * maxd)) * (tvmax-tvmin);
+
+              av = avmin + (fabs(ad)/M_PI) * (avmax-avmin);
+              if(ad < 0)
+                av = -av;
+            }
+
+            this->PutPositionCommand(tv,0.0,av,0);
+          }
+        }
+      }
+      else
+        this->StopPosition();
     }
-    else if(this->curr_waypoint < 0)
+    else // !velocity_control
     {
-      // no more waypoints, so stop
-      StopPosition();
-    }
-    else
-    {
-      // are we there yet?  ignore angle, cause this is just a waypoint
-      dist = sqrt(((this->localize_x - this->waypoint_x) *
-                   (this->localize_x - this->waypoint_x)) +
-                  ((this->localize_y - this->waypoint_y) *
-                   (this->localize_y - this->waypoint_y)));
+      bool going_for_target = (this->curr_waypoint == 
this->plan->waypoint_count);
+      dist = sqrt(((this->localize_x - this->target_x) *
+                   (this->localize_x - this->target_x)) +
+                  ((this->localize_y - this->target_y) *
+                   (this->localize_y - this->target_y)));
       // Note that we compare the current heading and waypoint heading in the
       // *odometric* frame.   We do this because comparing the current
       // heading and waypoint heading in the localization frame is unreliable
       // when making small adjustments to achieve a desired heading (i.e., the
       // robot gets there and VFH stops, but here we don't realize we're done
       // because the localization heading hasn't changed sufficiently).
-      if(this->new_goal ||
-         (rotate_waypoint &&
-          (fabs(this->angle_diff(this->waypoint_odom_a,this->position_a))
-           < M_PI/4.0)) ||
-         (!rotate_waypoint && (dist < this->dist_eps)))
+      angle = fabs(this->angle_diff(this->waypoint_odom_a,this->position_a));
+      if(going_for_target && dist < this->dist_eps && angle < this->ang_eps)
       {
-        if(this->curr_waypoint == this->waypoint_count)
+        // we're at the final target, so stop
+        StopPosition();
+        this->curr_waypoint = -1;
+        this->new_goal = false;
+        this->atgoal = true;
+      }
+      else if(this->curr_waypoint < 0)
+      {
+        // no more waypoints, so stop
+        StopPosition();
+      }
+      else
+      {
+        // are we there yet?  ignore angle, cause this is just a waypoint
+        dist = sqrt(((this->localize_x - this->waypoint_x) *
+                     (this->localize_x - this->waypoint_x)) +
+                    ((this->localize_y - this->waypoint_y) *
+                     (this->localize_y - this->waypoint_y)));
+        // Note that we compare the current heading and waypoint heading in the
+        // *odometric* frame.   We do this because comparing the current
+        // heading and waypoint heading in the localization frame is unreliable
+        // when making small adjustments to achieve a desired heading (i.e., 
the
+        // robot gets there and VFH stops, but here we don't realize we're done
+        // because the localization heading hasn't changed sufficiently).
+        if(this->new_goal ||
+           (rotate_waypoint &&
+            (fabs(this->angle_diff(this->waypoint_odom_a,this->position_a))
+             < M_PI/4.0)) ||
+           (!rotate_waypoint && (dist < this->dist_eps)))
         {
-          // no more waypoints, so wait for target achievement
+          if(this->curr_waypoint == this->waypoint_count)
+          {
+            // no more waypoints, so wait for target achievement
 
-          //puts("waiting for goal achievement");
-          usleep(CYCLE_TIME_US);
-          continue;
-        }
-        // get next waypoint
-        this->waypoint_x = this->waypoints[this->curr_waypoint][0];
-        this->waypoint_y = this->waypoints[this->curr_waypoint][1];
-        this->curr_waypoint++;
+            //puts("waiting for goal achievement");
+            usleep(CYCLE_TIME_US);
+            continue;
+          }
+          // get next waypoint
+          this->waypoint_x = this->waypoints[this->curr_waypoint][0];
+          this->waypoint_y = this->waypoints[this->curr_waypoint][1];
+          this->curr_waypoint++;
 
-        this->waypoint_a = this->target_a;
-        if(this->always_insert_rotational_waypoints ||
-           (this->curr_waypoint == 2))
-        {
-          dist = sqrt((this->waypoint_x - this->localize_x) *
-                      (this->waypoint_x - this->localize_x) +
-                      (this->waypoint_y - this->localize_y) *
-                      (this->waypoint_y - this->localize_y));
-          angle = atan2(this->waypoint_y - this->localize_y,
-                        this->waypoint_x - this->localize_x);
-          if((dist > this->dist_eps) &&
-             fabs(this->angle_diff(angle,this->localize_a)) > M_PI/4.0)
+          this->waypoint_a = this->target_a;
+          if(this->always_insert_rotational_waypoints ||
+             (this->curr_waypoint == 2))
           {
-            this->waypoint_x = this->localize_x;
-            this->waypoint_y = this->localize_y;
-            this->waypoint_a = angle;
-            this->curr_waypoint--;
-            rotate_waypoint=true;
+            dist = sqrt((this->waypoint_x - this->localize_x) *
+                        (this->waypoint_x - this->localize_x) +
+                        (this->waypoint_y - this->localize_y) *
+                        (this->waypoint_y - this->localize_y));
+            angle = atan2(this->waypoint_y - this->localize_y,
+                          this->waypoint_x - this->localize_x);
+            if((dist > this->dist_eps) &&
+               fabs(this->angle_diff(angle,this->localize_a)) > M_PI/4.0)
+            {
+              this->waypoint_x = this->localize_x;
+              this->waypoint_y = this->localize_y;
+              this->waypoint_a = angle;
+              this->curr_waypoint--;
+              rotate_waypoint=true;
+            }
+            else
+              rotate_waypoint=false;
           }
           else
             rotate_waypoint=false;
+
+          this->new_goal = false;
         }
-        else
-          rotate_waypoint=false;
 
-        this->new_goal = false;
+        SetWaypoint(this->waypoint_x, this->waypoint_y, this->waypoint_a);
       }
-
-      SetWaypoint(this->waypoint_x, this->waypoint_y, this->waypoint_a);
     }
 
-
     usleep(CYCLE_TIME_US);
   }
 }
@@ -1118,6 +1191,10 @@
       oj += sj;
     }
   }
+
+  plan_init(this->plan);
+  plan_compute_cspace(this->plan);
+
   return(0);
 }
 
@@ -1132,7 +1209,6 @@
   {
     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;
@@ -1144,14 +1220,10 @@
 
   // 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->plan->origin_y = info->origin.py;
-  // Set the bounds to search the whole grid.
-  plan_set_bounds(this->plan,
-                  0, 0, this->plan->size_x - 1, this->plan->size_y - 1);
 
   delete msg;
   return(0);
@@ -1190,9 +1262,6 @@
   if(this->GetMap(false) < 0)
     return(-1);
 
-  //plan_update_cspace(this->plan,this->cspace_fname);
-  plan_compute_cspace(this->plan);
-
   this->have_map = true;
   this->new_map = true;
 
@@ -1271,9 +1340,6 @@
       // Now get the map data, possibly in separate tiles.
       if(this->GetMap(true) < 0) return -1;
 
-      //plan_update_cspace(this->plan,this->cspace_fname);
-      plan_compute_cspace(this->plan);
-
       this->have_map = true;
       this->new_map = true;
     }

Modified: code/player/branches/cmake/server/drivers/shell/passthrough.cc
===================================================================
--- code/player/branches/cmake/server/drivers/shell/passthrough.cc      
2008-04-18 08:07:57 UTC (rev 6360)
+++ code/player/branches/cmake/server/drivers/shell/passthrough.cc      
2008-04-18 08:10:03 UTC (rev 6361)
@@ -225,7 +225,7 @@
          (hdr->type == PLAYER_MSGTYPE_SYNCH) ||
          (hdr->type == PLAYER_MSGTYPE_RESP_NACK)))
     {
-        PLAYER_MSG7(3,"PassThrough: Forwarding SRC->DST Interface code=%d  
%d:%d:%d -> %d:%d:%d",hdr->addr.interf, hdr->addr.host,hdr->addr.robot, 
hdr->addr.index, dstAddr.host, dstAddr.robot, dstAddr.index);
+        PLAYER_MSG7(8,"PassThrough: Forwarding SRC->DST Interface code=%d  
%d:%d:%d -> %d:%d:%d",hdr->addr.interf, hdr->addr.host,hdr->addr.robot, 
hdr->addr.index, dstAddr.host, dstAddr.robot, dstAddr.index);
 
         hdr->addr=dstAddr; //will send to my clients, making it seem like it 
comes from my DST interface
 
@@ -236,7 +236,7 @@
     if (Device::MatchDeviceAddress(hdr->addr,dstAddr) &&
         (hdr->type == PLAYER_MSGTYPE_CMD))
     {
-        PLAYER_MSG7(3,"PassThrough: Forwarding DST->SRC Interface code=%d  
%d:%d:%d -> %d:%d:%d",hdr->addr.interf, hdr->addr.host,hdr->addr.robot, 
hdr->addr.index, srcAddr.host, srcAddr.robot, srcAddr.index);
+        PLAYER_MSG7(8,"PassThrough: Forwarding DST->SRC Interface code=%d  
%d:%d:%d -> %d:%d:%d",hdr->addr.interf, hdr->addr.host,hdr->addr.robot, 
hdr->addr.index, srcAddr.host, srcAddr.robot, srcAddr.index);
 
 
         hdr->addr=srcAddr;  //send to the device to which I subscribed, making 
it seem like it comes from my original interface


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 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
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

Reply via email to