Revision: 8249
          http://playerstage.svn.sourceforge.net/playerstage/?rev=8249&view=rev
Author:   gbiggs
Date:     2009-09-08 01:43:42 +0000 (Tue, 08 Sep 2009)

Log Message:
-----------
Applied patch #2836953: grid map driver

Modified Paths:
--------------
    code/player/trunk/server/drivers/map/CMakeLists.txt

Added Paths:
-----------
    code/player/trunk/config/gridmap.cfg
    code/player/trunk/server/drivers/map/gridmap.cc
    code/player/trunk/server/drivers/map/gridmap.h

Added: code/player/trunk/config/gridmap.cfg
===================================================================
--- code/player/trunk/config/gridmap.cfg                                (rev 0)
+++ code/player/trunk/config/gridmap.cfg        2009-09-08 01:43:42 UTC (rev 
8249)
@@ -0,0 +1,51 @@
+# Desc: Sample configuration for using the gridmap driver with Stage
+# Author: Marco Paladini
+# Date: 08 September 2009
+# CVS: $Id: simple.cfg,v 1.34 2007-11-02 01:11:39 gerkey Exp $
+
+
+# load the Stage plugin simulation driver
+driver
+(              
+  name "stage"
+  provides ["simulation:0" ]
+  plugin "libstageplugin"
+
+  # load the named file into the simulator
+  worldfile "simple.world"     
+)
+
+# Export the map
+driver
+(              
+  name "gridmap"
+  provides ["map:0" ]
+  requires ["position2d:0" "sonar:0"]
+  width 510 
+  height 510
+  startx -200 
+  starty -200
+  scale 0.032 
+  sonartreshold 4.5
+)
+
+# Create a Stage driver and attach position2d and laser interfaces 
+# to the model "robot1"
+driver
+( 
+  name "stage"
+  provides ["position2d:0" "laser:0" "sonar:0" ]
+  model "robot1" 
+)
+
+# Demonstrates use of a Player "abstract driver": one that doesn't
+# interface directly with hardware, but only with other Player devices.
+# The VFH driver attempts to drive to commanded positions without 
+# bumping into obstacles.
+driver 
+(
+  name "vfh"
+  provides ["position2d:1"]
+  requires ["position2d:0" "laser:0" ]
+)
+

Modified: code/player/trunk/server/drivers/map/CMakeLists.txt
===================================================================
--- code/player/trunk/server/drivers/map/CMakeLists.txt 2009-09-08 01:38:21 UTC 
(rev 8248)
+++ code/player/trunk/server/drivers/map/CMakeLists.txt 2009-09-08 01:43:42 UTC 
(rev 8249)
@@ -19,3 +19,7 @@
 
 PLAYERDRIVER_OPTION (vmapfile build_vmapfile ON)
 PLAYERDRIVER_ADD_DRIVER (vmapfile build_vmapfile SOURCES vmapfile.cc)
+
+PLAYERDRIVER_OPTION (gridmap build_gridmap ON)
+PLAYERDRIVER_ADD_DRIVER (gridmap build_gridmap SOURCES gridmap.cc)
+

Added: code/player/trunk/server/drivers/map/gridmap.cc
===================================================================
--- code/player/trunk/server/drivers/map/gridmap.cc                             
(rev 0)
+++ code/player/trunk/server/drivers/map/gridmap.cc     2009-09-08 01:43:42 UTC 
(rev 8249)
@@ -0,0 +1,606 @@
+/*  gridmap
+ *  Player PLUGIN by Marco Paladini
+ *  paladini.marco(at)gmail.com
+ *
+ *  Player - One Hell of a Robot Server
+ *  Copyright (C) 2003  
+ *     Brian Gerkey, Andrew Howard
+ *                      
+ * 
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/*
+ * Desc: A Mapping driver which maps from sonar data
+ * from the multidriver example by Andrew Howard
+ * Author: Marco Paladini, (mail: [email protected])
+ * Date: 29 April 2006
+ */
+
+/** @ingroup drivers */
+/** @{ */
+/** @defgroup driver_mapping gridmap
+  * @brief Provides a map using sonars
+Mapping Driver plugin
+
+This driver is a very simple start to
+have the robot mapping its own environment.
+It works with an occupancy grid map, using
+the @ref player_map_data_t data type.
+this driver subscribes to odometry position2d and sonar device, every 
100milliseconds puts an occupied line on the map, based on the endpoint of the 
sonar ray.
+
+this plugin driver uses
+- "odometry" @ref interface_position2d : source of odometry information
+- @ref interface_sonar : source of sonar data
+
+...@par Configuration requests
+provides ["map:0"]
+requires ["position2d:0" "sonar:0"]
+
+...@par Configuration file options
+  - width (integer)
+     map width in pixels, defaults to 0 if not specified.
+  - height (integer)
+     map height in pixels, defaults to 0 if not specified.
+  - startx (integer)
+     initial global robot x position in pixels
+  - starty (integer)
+     initial global robot y position in pixels
+  - scale (float)
+     pixels/meter, the stage simple.world
+     has a 16 meter map with a 0.028 scale, so 1 meter is (int) 1/0.028 = 36 
pixels
+  - sonartreshold (float)
+     sonar data above the treshold is ignored.
+     this is the most simple way to account for maximum range readings due to 
reflections.
+     for a stage simulated pioneer robot the sonar range is 5 meters, so 
treshold should be less than 5. defaults to 1 if not specified.
+
+The following configuration file illustrates the use of the driver in a stage 
simulated world (here map width height and resolution were taken from the world 
file for an easy comparison of the stage world with the map):
+
+...@verbatim
+driver
+(              
+  name "stage"
+  provides ["simulation:0" ]
+  plugin "libstageplugin"
+
+  # load the named file into the simulator
+  worldfile "simple.world"     
+)
+
+# Create a Stage driver and attach position2d and laser interfaces 
+# to the model "robot1"
+driver
+( 
+  name "stage"
+  provides ["position2d:0" "sonar:0" "laser:0"]
+  model "robot1" 
+)
+
+driver
+( 
+  name "gridmap"
+  provides ["map:0"]
+  requires ["position2d:0" "sonar:0"]
+  plugin "mapping.so"
+  width 809
+  height 689
+  startx 0
+  starty 0
+  scale 0.028
+  treshold 4.5
+)
+...@endverbatim
+*/
+
+// ONLY if you need something that was #define'd as a result of configure 
+// (e.g., HAVE_CFMAKERAW), then #include <config.h>, like so:
+/*
+#if HAVE_CONFIG_H
+  #include <config.h>
+#endif
+*/
+
+
+#include "gridmap.h"
+#include <libplayercore/playercore.h>
+
+//#include <gtk/gtk.h>
+//#define USEGTK 0
+#define DEBUG 0
+
+using namespace std;
+
+////////////////////////////////////////////////////////////////////////////////
+// The class for the driver
+class gridmap : public ThreadedDriver
+{
+  public:
+      // function to decide empty and occupied cells
+    int mapTreshold();
+    Map map_data;
+    // Constructor; need that
+    gridmap(ConfigFile* cf, int section);
+
+    // Must implement the following methods.
+    virtual int Setup();
+    virtual int Shutdown();
+    virtual int ProcessMessage(QueuePointer & resp_queue,
+                               player_msghdr * hdr, 
+                               void * data);
+
+  private:
+    // Main function for device thread.
+    virtual void Main();
+
+    // Method for Mapping
+    virtual int UpdateMap(player_position2d_data_t* odom, player_sonar_data_t* 
sonar);
+    //my map interface
+    player_devaddr_t map_addr;
+    player_map_data_t map,published_map;
+    player_map_info_t map_info;
+  
+    // odometry position interface
+    player_devaddr_t odom_addr;
+    Device* odom_dev;
+    player_position2d_data_t last_odom_data;
+
+    // Address of and pointer to the sonar device to which I'll subscribe
+    player_devaddr_t sonar_addr;
+    Device* sonar_dev;
+    player_sonar_data_t last_sonar_data;
+    player_sonar_geom_t sonar_geom;
+    // distance from sonar to the center of the robot. in pixels
+    int *sonar_dist;
+
+    // What distance from the robot should be accounted as "obstacle"?
+    float sonar_treshold;
+    // how many times do i have to sense an obstacle to say it's there?
+    int map_treshold;
+    // pixel offset from position2d (0,0,0)
+    int startx,starty;
+
+#ifdef USEGTK
+  GtkWidget *mainwin;
+#endif
+
+};
+
+
+// A factory creation function, declared outside of the class so that it
+// can be invoked without any object context (alternatively, you can
+// declare it static in the class).  In this function, we create and return
+// (as a generic Driver*) a pointer to a new instance of this driver.
+Driver* gridmap_Init(ConfigFile* cf, int section)
+{
+  // Create and return a new instance of this driver
+  return ((Driver*) (new gridmap(cf, section)));
+}
+
+// A driver registration function, again declared outside of the class so
+// that it can be invoked without object context.  In this function, we add
+// the driver into the given driver table, indicating which interface the
+// driver can support and how to create a driver instance.
+void gridmap_Register(DriverTable* table)
+{
+  table->AddDriver("gridmap", gridmap_Init);
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Constructor.  Retrieve options from the configuration file and do any
+// pre-Setup() setup.
+gridmap::gridmap(ConfigFile* cf, int section)
+    : ThreadedDriver(cf, section)
+{
+
+  // Create my map interface
+  if (cf->ReadDeviceAddr(&(this->map_addr), section, 
+                         "provides",PLAYER_MAP_CODE , 0, NULL) != 0)
+  {
+   this->SetError(-1);
+   return;
+  }
+
+  if (this->AddInterface(this->map_addr))
+    {
+      PLAYER_ERROR("Can't add map interface");
+      this->SetError(-1);    
+      return;
+    }
+
+  // let the config file tell us the initial pixel offset
+  this->startx = cf->ReadInt(section, "startx", 0);
+  this->starty = cf->ReadInt(section, "starty", 0);
+  // fill config values in the map
+  this->map.width = cf->ReadInt(section, "width", 0);
+  this->map.height = cf->ReadInt(section, "height", 0);
+  this->map.col = 0;
+  this->map.row = 0;
+  this->map.data_count = map.width*map.height;
+  this->published_map.data = (int8_t 
*)malloc(this->map.data_count*sizeof(int8_t));
+  // fill the map_info data
+  this->map_info.scale = cf->ReadFloat(section, "scale", 1.0);
+  // What distance from the robot should be accounted as "obstacle"?
+  this->sonar_treshold = cf->ReadFloat(section, "sonartreshold", 1.0);
+  this->map_treshold = cf->ReadInt(section, "maptreshold", 3);
+  this->map_info.width = this->map.width;
+  this->map_info.height = this->map.height;
+  this->map_info.origin.px = this->map.col;
+  this->map_info.origin.py = this->map.row;
+  this->map_info.origin.pa = 0;
+  // fill the map data with free space
+  // reasons for this are some good obstacle avoidance always there
+  // can't bear to say all the world is unknown
+  for(uint i=0;i<this->map.width*this->map.height;i++)
+     this->published_map.data[i]=-1;
+
+  // Open the position interface
+  if (cf->ReadDeviceAddr(&(this->odom_addr), section, 
+                         "requires", PLAYER_POSITION2D_CODE, 0, NULL) != 0)
+  {
+    PLAYER_ERROR("Can't open position2d interface");
+    this->SetError(-1);
+    return;
+  }
+
+  // Find out which sonar I'll subscribe to
+  this->sonar_dev = NULL;
+  memset(&this->sonar_addr,0,sizeof(player_devaddr_t));
+  if(cf->ReadDeviceAddr(&this->sonar_addr, section, "requires",
+                     PLAYER_SONAR_CODE, -1, NULL) != 0 )
+  {
+    PLAYER_ERROR("Can't find sonar");
+    this->SetError(-1);
+    return;
+  }
+
+printf("creating a %dx%d pixels map, sonar treshold at 
%f\n",this->map.width,this->map.height,this->sonar_treshold);
+/// creating the Map object
+this->map_data.width=this->map.width;
+this->map_data.height=this->map.height;
+#ifdef USEGTK
+
+  /* Initialize the widget set */
+  gtk_init(NULL,NULL);
+
+  /* Create the main window */
+  this->mainwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+  /* Set up our GUI elements */
+
+
+  /* Show the application window */
+  gtk_widget_show_all (mainwin);
+
+  /* Enter the main event loop, and wait for user interaction */
+  gtk_main ();
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Set up the device.  Return 0 if things go well, and -1 otherwise.
+int gridmap::Setup()
+{   
+  puts("Map driver initialising");
+
+  // Subscribe to the sonar device
+  if(!(this->sonar_dev = deviceTable->GetDevice(this->sonar_addr)))
+  {
+    PLAYER_ERROR("unable to locate suitable sonar device");
+    return(-1);
+  }
+  if(this->sonar_dev->Subscribe(this->InQueue) != 0)
+  {
+    PLAYER_ERROR("unable to subscribe to sonar device");
+    return(-1);
+  }
+  // request sonar geometry
+  Message* msg;
+  // Get the sonar poses
+  if(!(msg = this->sonar_dev->Request(this->InQueue,
+                                  PLAYER_MSGTYPE_REQ,
+                                  PLAYER_SONAR_REQ_GET_GEOM,
+                                  NULL, 0, NULL,false)))
+  {
+    PLAYER_ERROR("failed to get sonar geometry");
+    return(-1);
+  }
+  else
+  {
+    // write the geometry inside the driver
+    this->sonar_geom = *(player_sonar_geom_t*) msg->GetPayload();
+    // calculate the distance from the sonar to the center of the robot (in 
pixels).
+    sonar_dist=(int *)malloc(sonar_geom.poses_count*sizeof(int));
+    for(uint s;s<this->sonar_geom.poses_count;s++)
+    this->sonar_dist[s]=(int)(sqrt(pow(this->sonar_geom.poses[s].px,2) +
+                                  pow(this->sonar_geom.poses[s].py,2)) /
+                                  this->map_info.scale);
+  }
+
+  // Subscribe to the odometry device
+  if(!(this->odom_dev = deviceTable->GetDevice(this->odom_addr)))
+  {
+    PLAYER_ERROR("unable to locate suitable odometry device");
+    return(-1);
+  }
+  if(this->odom_dev->Subscribe(this->InQueue) != 0)
+  {
+    PLAYER_ERROR("unable to subscribe to odometry device");
+    return(-1);
+  }
+
+  // Here you do whatever else is necessary to setup the device, like open and
+  // configure a serial port.
+    
+  puts("Mapping driver ready");
+
+  // Start the device thread; spawns a new thread and executes
+  // gridmap::Main(), which contains the main loop for the driver.
+  this->StartThread();
+
+  return(0);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Shutdown the device
+int gridmap::Shutdown()
+{
+  puts("Shutting example driver down");
+
+  // Stop and join the driver thread
+  //  this->StopThread();
+
+  // Unsubscribe from the laser
+  this->sonar_dev->Unsubscribe(this->InQueue);
+
+  // Here you would shut the device down by, for example, closing a
+  // serial port.
+
+  puts("Mapping driver has been shutdown");
+
+  return(0);
+}
+
+// decide which cells are occupied and which cells are free
+int gridmap::mapTreshold()
+{
+
+    // fill config values in the map
+  published_map.width = this->map.width;
+  published_map.height = this->map.height;
+  published_map.col = 0;
+  published_map.row = 0;
+  published_map.data_count = this->map.data_count;
+  for(uint i=0;i<this->map.width;i++) {
+      for (uint j=0;j<this->map.height;j++){
+       MAP_POINT x(i,j);
+       if(this->map_data.find(x) != this->map_data.end()){
+       if (map_data[x].P > this->map_treshold) 
published_map.data[i+this->map.width*j]=1;
+       else  published_map.data[i+this->map.width*j]=0;
+       }
+      }
+    }
+
+
+#ifdef USEGTK
+
+  gtk_main_quit ();
+
+#endif
+
+  return(1);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//                                                                          //
+//                                                                          //
+//            UpdateMap function, the real work of this driver              //
+//                                                                          //
+//                                                                          //
+//////////////////////////////////////////////////////////////////////////////
+
+int gridmap::UpdateMap(player_position2d_data_t* odom, player_sonar_data_t* 
sonar)
+{
+  /// TODO: choose a update policy
+  /// don't overwrite the map if the robot stands still
+  if (odom->vel.px == 0 && odom->vel.py == 0 && odom->vel.pa == 0) return(0);
+
+  uint s,x,y;
+  int px,py,r,o;
+  float th_sonar;
+  // compute r * tan(alfa/2), where alfa is the sonar angular aperture
+  // and r is the sonar distance
+  // using pi/8 for the angular sonar aperture
+  for (s=0;s< sonar->ranges_count;s++)
+  {
+  Sonar sonar_model;
+  if(DEBUG) printf("sonar %d, %f\n",s,sonar->ranges[s]);
+  r =(int) (sonar->ranges[s]  / this->map_info.scale);
+  // if above treshold ignore this sonar reading
+  if(sonar->ranges[s] <= 0.001 || sonar->ranges[s] > this->sonar_treshold) 
continue;
+  th_sonar = this->sonar_geom.poses[s].pyaw + odom->pos.pa;
+  // using a line 10 times smaller 'cause real sonar wave was too big
+  o = (int) (r*tanf(M_PI/16) / 10);
+  // px and py are the global coordinates for the starting point of the sonar 
ray
+  // map width/2 and height/2 are added 'cause stage puts 0,0 in the center of 
the
+  // window, maps have 0,0 on the bottom left corner
+  px=(int) (odom->pos.px/this->map_info.scale +startx + 
this->map_info.width/2);
+  py=(int) (odom->pos.py/this->map_info.scale +starty + 
this->map_info.height/2);
+//  i=r+this->sonar_dist[s]; // along the sonar ray
+  //for(float th=th_sonar-sonar_aperture;th<th_sonar+sonar_aperture;th+=0.01)
+  //  {
+    float th=th_sonar;
+    // for every degree of the arc
+    x = (int) LOCAL2GLOBAL_X(r,0,px,py,th);
+    y = (int) LOCAL2GLOBAL_Y(r,0,px,py,th);
+       //point[0]=x; point[1]=y;
+       //int *point,pose;
+       MAP_POINT point(x,y);
+
+/*     pose[0]=(double)px;
+       pose[1]=(double)py;
+       pose[2]=(double)odom->pos.pa;
+       pose[3]=sonar_model.sensor_model(x,y,r);*/
+       double prob; // probability of point beinng occupied
+       if(this->map_data.find(point) != this->map_data.end())
+         { prob=this->map_data[point].P;       } 
+       else    { prob=0.5; }
+
+       // this point can be added on the map           
+       MAP_POSE f((double)px,(double)py,(double)odom->pos.pa,
+                  prob * // a simple multiplication
+                  sonar_model.sensor_model(x,y,r));
+       this->map_data[point] = f;
+       // put a lousy player map in addition to updating the probability
+       //if (MAP_VALID(this->map,x,y)) 
this->map.data[MAP_INDEX(this->map,x,y)]=1;
+       
+
+  }
+  return(1);
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Main function for device thread
+void gridmap::Main() 
+{
+  // The main loop; interact with the device here
+  for(;;)
+  {
+    // test if we are supposed to cancel
+    pthread_testcancel();
+
+    // Process incoming messages.  Calls ProcessMessage() on each pending
+    // message.
+    this->ProcessMessages();
+
+    // Do work here.  
+    this->UpdateMap(&this->last_odom_data,&this->last_sonar_data);
+    // Send out new messages with Driver::Publish()
+    //
+
+    // Sleep (or you might, for example, block on a read() instead)
+    usleep(100000);
+  }
+  return;
+}
+
+
+int gridmap::ProcessMessage(QueuePointer & resp_queue, 
+                                player_msghdr * hdr, 
+                                void * data)
+{ //puts("gridmap processing messages..");
+  // Handle new data from the sonar
+  if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA, PLAYER_SONAR_DATA_RANGES, 
+                           this->sonar_addr))
+  {
+    // Put the sonar data in the last_sonar_data variable
+    this->last_sonar_data = * (player_sonar_data_t *)data;
+    /*  uncomment this to see sonar data printed on the console.
+        should set a debug level for this
+    puts("Sonar Data Received.");  
+    for(int i=0;i<sonar_data->ranges_count;i++)
+      {
+       printf(" %d:%f ",i,sonar_data->ranges[i]);
+      }
+    */
+    return(0);
+  }
+
+  // Handle new data from the position2d
+  if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA,
+                              PLAYER_POSITION2D_DATA_STATE, this->odom_addr))
+  {
+    // Put the odometry data in the last_odom_data variable
+    this->last_odom_data = * (player_position2d_data_t *)data;
+    return(0);
+  }
+
+
+  // Is it a request for the map info?
+  if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ, 
+                           PLAYER_MAP_REQ_GET_INFO, 
+                           this->map_addr) )
+  {
+    this->Publish(this->map_addr, 
+                 resp_queue, 
+                 PLAYER_MSGTYPE_RESP_ACK, 
+                 PLAYER_MAP_DATA_INFO,
+                 &this->map_info, 
+                 sizeof(player_map_info_t),
+                 NULL);
+    return(0);
+  }
+
+  // Is it a request for the map data?
+  if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ, 
+                           PLAYER_MAP_REQ_GET_DATA, 
+                           this->map_addr) )
+  {
+    this->mapTreshold();
+    player_map_data_t* mapreq = (player_map_data_t*)data;
+
+    // Can't declare a map tile on the stack (it's too big)
+    /*
+    size_t mapsize = (sizeof(player_map_data_t) - PLAYER_MAP_MAX_TILE_SIZE +
+                      (mapreq->width * mapreq->height));
+                      */
+    size_t mapsize = sizeof(player_map_data_t);
+    player_map_data_t* mapresp = (player_map_data_t*)calloc(1,mapsize);
+    assert(mapresp);
+
+    int i, j;
+    int oi, oj, si, sj;
+
+    // Construct reply
+    oi = mapresp->col = mapreq->col;
+    oj = mapresp->row = mapreq->row;
+    si = mapresp->width = mapreq->width;
+    sj = mapresp->height = mapreq->height;
+    mapresp->data_count = mapresp->width * mapresp->height;
+    mapresp->data = new int8_t [mapresp->data_count];
+    // Grab the pixels from the map
+    for(j = 0; j < sj; j++)
+    {
+      for(i = 0; i < si; i++)
+      {
+        if(MAP_VALID(this->map, i + oi, j + oj))
+          mapresp->data[i + j * si] = 
this->published_map.data[MAP_INDEX(this->map, i+oi, j+oj)];
+        else
+        {
+          PLAYER_WARN2("requested cell (%d,%d) is offmap", i+oi, j+oj);
+          mapresp->data[i + j * si] = 0;
+        }
+      }
+    }
+
+    this->Publish(this->device_addr, resp_queue,
+                  PLAYER_MSGTYPE_RESP_ACK,
+                  PLAYER_MAP_REQ_GET_DATA,
+                  (void*)mapresp);
+    delete [] mapresp->data;
+    free(mapresp);
+    puts("Map data sent!");
+    return(0);
+  }
+
+  // Tell the caller that you don't know how to handle this message
+  return(-1);
+}
+

Added: code/player/trunk/server/drivers/map/gridmap.h
===================================================================
--- code/player/trunk/server/drivers/map/gridmap.h                              
(rev 0)
+++ code/player/trunk/server/drivers/map/gridmap.h      2009-09-08 01:43:42 UTC 
(rev 8249)
@@ -0,0 +1,161 @@
+// objects definitions
+#include <unistd.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <math.h>
+#include <libplayercore/playercore.h>
+#include <iostream>
+#include <map>  //stl
+/*
+ *  Player - One Hell of a Robot Server
+ *  Copyright (C) 2003  
+ *     Brian Gerkey, Andrew Howard
+ *                      
+ * 
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/*
+ * Desc: A Mapping driver which maps from sonar data
+ * from the multidriver example by Andrew Howard
+ * Author: Marco Paladini, (mail: [email protected])
+ * Date: 29 April 2006
+ */
+/// objects definitions for mapping driver
+#define LOCAL2GLOBAL_X(x,y,px,py,pa) (cos(pa)*(x) - sin(pa)*(y) + px)
+#define LOCAL2GLOBAL_Y(x,y,px,py,pa) (sin(pa)*(x) + cos(pa)*(y) + py)
+#define MAP_INDEX(map, i, j) (int)((i) + (j) * map.width)
+#define MAP_VALID(map, i, j) ((i >= 0) && (i <= (int)map.width) && (j >= 0) && 
(j <= (int)map.height))
+#define ROTATE_X(x,y,th) (cos(th)*(x) - sin(th)*(y))
+#define ROTATE_Y(x,y,th) (sin(th)*(x) + cos(th)*(y))
+
+using namespace std;
+
+
+class Sonar
+{
+public:
+double px,py,th;
+double sonar_treshold; //default to 4.5
+double sonar_aperture; // 30 degrees
+double sensor_model(double x,double y,double r);
+       Sonar() 
+       {
+       sonar_treshold=4.5;
+       sonar_aperture=0.5235987;
+       }
+};
+
+class MAP_POINT
+{
+public:
+int x;
+int y; // coordinates on map
+
+MAP_POINT(int x1,int y1)
+{
+  x=x1;
+  y=y1;
+}
+
+ bool operator<(const MAP_POINT &b) const {
+   if (x < b.x) return(1);
+   else if (x == b.x) return(y < b.y);
+   else return(0);
+ }
+
+};
+
+class MAP_POSE
+{
+public:
+double px; 
+double py;
+double pa; // where the robot was when this point was added
+double P;  // occupancy probability
+
+ MAP_POSE()
+   {pa=px=py=P=0;}
+
+MAP_POSE(double px1,
+         double py1,
+         double pa1,
+        double P1)   {
+ pa=pa1;
+ px=px1;
+ py=py1;
+ P=P1;
+ }
+
+};
+
+
+class Map : public map<MAP_POINT,MAP_POSE>
+{
+///
+/// the map is defined as x,y -> pose (px,py,pa,P)
+///
+public:
+int width;
+int height;
+int startx;
+int starty;
+float scale; //default to 0.028
+float sonar_treshold; //default to 4.5
+Map();
+Map(int width,
+    int height,
+    int startx,
+    int starty,
+    int scale,
+    int sonar_treshold);
+~Map();
+player_map_data_t ToPlayer();
+};
+
+Map::~Map() {
+}
+
+Map::Map()
+{
+//some default values (not always good)
+width=800;
+height=800;
+startx=0;
+starty=0;
+scale=0.028;
+sonar_treshold=4.5;
+}
+
+Map::Map(int width,
+    int height,
+    int startx,
+    int starty,
+    int scale,
+    int sonar_treshold)
+{
+std::cout<< "not implemented yet" << std::endl;
+}
+
+
+
+double Sonar::sensor_model(double x,double y,double r)
+{
+return(
+exp((-pow(x,2)/r)-(pow(y,2)/sonar_aperture))/((double)1.7)
+);
+
+}


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to