Revision: 9131
          http://sourceforge.net/p/playerstage/svn/9131
Author:   jpgr87
Date:     2013-11-10 19:16:50 +0000 (Sun, 10 Nov 2013)
Log Message:
-----------
Applied patch #638: Add Ranger to VFH

Modified Paths:
--------------
    code/player/trunk/server/drivers/position/vfh/vfh.cc

Modified: code/player/trunk/server/drivers/position/vfh/vfh.cc
===================================================================
--- code/player/trunk/server/drivers/position/vfh/vfh.cc        2013-11-10 
19:06:56 UTC (rev 9130)
+++ code/player/trunk/server/drivers/position/vfh/vfh.cc        2013-11-10 
19:16:50 UTC (rev 9131)
@@ -93,6 +93,8 @@
     obstacles
   - @ref interface_sonar : the sonar that will be used to avoid
     obstacles
+  - @ref interface_ranger : the ranger that will be used to avoid
+    obstacles
 
 - @todo : add support for getting the robot's true global pose via the
   @ref interface_simulation interface
@@ -280,8 +282,11 @@
     int ShutdownLaser();
     int SetupSonar();
     int ShutdownSonar();
+    int SetupRanger();
+    int ShutdownRanger();
     void ProcessLaser(player_laser_data_t &);
     void ProcessSonar(player_sonar_data_t &);
+    void ProcessRanger(player_ranger_data_range_t &);
 
     // Send commands to underlying position device
     void PutCommand( int speed, int turnrate );
@@ -330,6 +335,12 @@
     player_devaddr_t sonar_addr;
     int num_sonars;
     player_pose3d_t * sonar_poses;
+    
+    // Ranger device info
+    Device *ranger;
+    player_devaddr_t ranger_addr;
+    int num_rangers;
+    player_pose3d_t * ranger_poses;
 
     // Laser range and bearing values
     int laser_count;
@@ -397,11 +408,13 @@
   if (this->SetupOdom() != 0)
     return -1;
 
-  // Initialise the laser.
+  // Initialise the laser/sonar/ranger.
   if (this->laser_addr.interf && this->SetupLaser() != 0)
     return -1;
   if (this->sonar_addr.interf && this->SetupSonar() != 0)
     return -1;
+  if (this->ranger_addr.interf && this->SetupRanger() != 0)
+    return -1;
 
   // initialize some navigation state
   rotatedir = 1;
@@ -430,6 +443,10 @@
   // Stop the sonar
   if(this->sonar)
     this->ShutdownSonar();
+  
+  // Stop the ranger
+  if(this->ranger)
+    this->ShutdownRanger();
 
   // Stop the odom device.
   this->ShutdownOdom();
@@ -572,7 +589,51 @@
   return 0;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// Set up the ranger
+int VFH_Class::SetupRanger()
+{
+  if(!(this->ranger = deviceTable->GetDevice(this->ranger_addr)))
+  {
+    PLAYER_ERROR("unable to locate suitable ranger device");
+    return -1;
+  }
+  if (this->ranger->Subscribe(this->InQueue) != 0)
+  {
+    PLAYER_ERROR("unable to subscribe to ranger device");
+    return -1;
+  }
 
+  player_ranger_geom_t* cfg;
+  Message* msg;
+
+  // Get the ranger poses
+  if(!(msg = this->ranger->Request(this->InQueue,
+                                   PLAYER_MSGTYPE_REQ,
+                                   PLAYER_RANGER_REQ_GET_GEOM,
+                                   NULL, 0, NULL,false)))
+  {
+    PLAYER_ERROR("failed to get ranger geometry");
+    return(-1);
+  }
+
+  // Store the ranger poses
+  cfg = (player_ranger_geom_t*)msg->GetPayload();
+  this->num_rangers = cfg->element_poses_count;
+  this->ranger_poses = new player_pose3d_t[num_rangers];
+  for(int i=0;i<this->num_rangers;i++)
+  {
+    this->ranger_poses[i] = cfg->element_poses[i];
+  }
+
+  delete msg;
+
+  this->laser_count = 0;
+  //this->laser_ranges = NULL;
+  return 0;
+}
+
+
 
////////////////////////////////////////////////////////////////////////////////
 // Shut down the laser
 int VFH_Class::ShutdownLaser()
@@ -596,6 +657,18 @@
 }
 
 
////////////////////////////////////////////////////////////////////////////////
+// Shut down the ranger
+int VFH_Class::ShutdownRanger()
+{
+  this->ranger->Unsubscribe(this->InQueue);
+  //delete [] laser_ranges;
+  //laser_ranges = NULL;
+  delete [] ranger_poses;
+  ranger_poses = NULL;
+  return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // Process new odometry data
 void
 VFH_Class::ProcessOdom(player_msghdr_t* hdr, player_position2d_data_t &data)
@@ -723,6 +796,57 @@
 }
 
 
////////////////////////////////////////////////////////////////////////////////
+// Process new ranger data, in a very crude way.
+void
+VFH_Class::ProcessRanger(player_ranger_data_range_t &data)
+{
+  int i;
+  double b, r;
+  double cone_width = 50.0;  // TODO take the cone with from ranger 
configuration
+  int count = 361;
+  float rangerDistToCenter = 0.0;
+
+  this->laser_count = count;
+  //if (!laser_ranges)
+         //this->laser_ranges = new double[laser_count][2];
+
+  for(i = 0; i < laser_count; i++)
+    this->laser_ranges[i][0] = -1;
+
+  //b += 90.0;
+  for(i = 0; i < (int)data.ranges_count; i++)
+  {
+    for(b = RTOD(this->ranger_poses[i].pyaw) + 90.0 - cone_width/2.0;
+        b < RTOD(this->ranger_poses[i].pyaw) + 90.0 + cone_width/2.0;
+        b+=0.5)
+    {
+      if((b < 0) || (rint(b*2) >= count))
+        continue;
+      // Rangers give distance readings from the perimeter of the robot while 
lasers give distance
+      // from the laser; hence, typically the distance from a single point, 
like the center.
+      // Since this version of the VFH+ algorithm was written for lasers and 
we pass the algorithm
+      // laser ranges, we must make the ranger readings appear like laser 
ranges. To do this, we take
+      // into account the offset of a ranger's geometry from the center. 
Simply add the distance from
+      // the center of the robot to each device to the ranger's distance 
reading.
+      rangerDistToCenter = static_cast<float> 
(sqrt(pow(this->ranger_poses[i].px,2) + pow(this->ranger_poses[i].py,2)));
+      this->laser_ranges[(int)rint(b * 2)][0] = (rangerDistToCenter + 
data.ranges[i]) * 1e3;
+      this->laser_ranges[(int)rint(b * 2)][1] = b;
+    }
+  }
+
+  r = 1000000.0;
+  for (i = 0; i < laser_count; i++)
+  {
+    if (this->laser_ranges[i][0] != -1) {
+      r = this->laser_ranges[i][0];
+    } else {
+      this->laser_ranges[i][0] = r;
+    }
+  }
+  r = 1000000.0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // Send commands to the underlying position device
 void
 VFH_Class::PutCommand( int cmd_speed, int cmd_turnrate )
@@ -796,6 +920,12 @@
     ProcessSonar(*reinterpret_cast<player_sonar_data_t *> (data));
     return 0;
   }
+  else if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA,
+                                PLAYER_RANGER_DATA_RANGE, this->ranger_addr))
+  {
+    ProcessRanger(*reinterpret_cast<player_ranger_data_range_t *> (data));
+    return 0;
+  }
   else if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
                                 PLAYER_PLANNER_CMD_GOAL,
                                 this->planner_id))
@@ -1221,11 +1351,17 @@
   memset(&this->sonar_addr,0,sizeof(player_devaddr_t));
   cf->ReadDeviceAddr(&this->sonar_addr, section, "requires",
                      PLAYER_SONAR_CODE, -1, NULL);
+  this->ranger = NULL;
+  memset(&this->ranger_addr,0,sizeof(player_devaddr_t));
+  cf->ReadDeviceAddr(&this->ranger_addr, section, "requires",
+                     PLAYER_RANGER_CODE, -1, NULL);
 
-  if((!this->laser_addr.interf && !this->sonar_addr.interf) ||
-     (this->laser_addr.interf && this->sonar_addr.interf))
+  if((!this->laser_addr.interf && !this->sonar_addr.interf && 
!this->ranger_addr.interf) ||
+     (this->laser_addr.interf && this->sonar_addr.interf)  ||
+     (this->laser_addr.interf && this->ranger_addr.interf) ||
+     (this->sonar_addr.interf && this->ranger_addr.interf))
   {
-    PLAYER_ERROR("vfh needs exactly one sonar or one laser");
+    PLAYER_ERROR("vfh needs exactly one ranger, one sonar or one laser");
     this->SetError(-1);
     return;
   }
@@ -1276,4 +1412,3 @@
   else
     return(RTOD(d2));
 }
-

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


------------------------------------------------------------------------------
November Webinars for C, C++, Fortran Developers
Accelerate application performance with scalable programming models. Explore
techniques for threading, error checking, porting, and tuning. Get the most 
from the latest Intel processors and coprocessors. See abstracts and register
http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk
_______________________________________________
Playerstage-commit mailing list
Playerstage-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to