Update of /cvsroot/playerstage/code/player/server/drivers/position/nav200
In directory 
sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32449/server/drivers/position/nav200

Modified Files:
        sicknav200.cc 
Log Message:
patch to support reconnection to hardware
adds a fetch mode to upload reflectors from a vectormap
fixes to speed calculations (may not be perfect yet)

Index: sicknav200.cc
===================================================================
RCS file: 
/cvsroot/playerstage/code/player/server/drivers/position/nav200/sicknav200.cc,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** sicknav200.cc       4 Feb 2008 19:40:27 -0000       1.14
--- sicknav200.cc       19 Feb 2008 19:06:28 -0000      1.15
***************
*** 154,159 ****
      // Set the reflector positions.
      void SetReflectors(player_vectormap_layer_data_t* data);
!     // Fetch the reflector positions from a provided vectormap and download 
to device.
!     void FetchReflectors();
      // Build the well known binary view of the reflector positions.
      void BuildWKB();
--- 154,164 ----
      // Set the reflector positions.
      void SetReflectors(player_vectormap_layer_data_t* data);
!     // Checks if the reflectors stored on the NAV200 are identical to those 
in the database.
!     // If they are not, the reflectors in the database are copied to the 
NAV200.
!     void FetchIfNeeded();
!     // Fetch the reflector positions from a provided vectormap.
!     player_vectormap_layer_data_t* FetchReflectors();
!     // Extract reflector positions from vectormap layer. Returns number of 
reflectors.
!     int InterpretLayerData(player_vectormap_layer_data_t* data, PositionXY* 
reflectors);
      // Build the well known binary view of the reflector positions.
      void BuildWKB();
***************
*** 171,174 ****
--- 176,181 ----
      uint8_t* wkbData;
      uint32_t wkbSize;
+     double speed;
+     double steeringAngle;
      
      DoubleProperty wheelBase;
***************
*** 177,180 ****
--- 184,188 ----
      // and mode will be automatically set back to positioning.
      StringProperty mode;
+     bool fetchOnStart; // If true, fetch reflectors whenever connecting.
      
      // Name of device used to communicate with the laser
***************
*** 205,208 ****
--- 213,220 ----
      // Vector map interface
      player_devaddr_t vectormap_addr;
+     // Position interface
+     player_devaddr_t debug_addr;
+     player_position2d_data_t debug_packet;
+     struct timeval previous;
  };
  
***************
*** 229,233 ****
  SickNAV200::SickNAV200(ConfigFile* cf, int section)
      : Driver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN),
!         wheelBase ("wheelBase", -1.0, 0),
        mode ("mode", DEFAULT_SICKNAV200_MODE, 0)
  {
--- 241,245 ----
  SickNAV200::SickNAV200(ConfigFile* cf, int section)
      : Driver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN),
!         wheelBase ("wheelbase", -1.0, 0),
        mode ("mode", DEFAULT_SICKNAV200_MODE, 0)
  {
***************
*** 261,264 ****
--- 273,291 ----
        return;
    }
+   
+   // Create debug interface
+   if (cf->ReadDeviceAddr(&(this->debug_addr), section, 
+                        "provides", PLAYER_POSITION2D_CODE, 2, NULL) != 0)
+   {
+       PLAYER_ERROR("Could not read debug interface device address.");
+       this->SetError(-1);
+       return;
+   }  
+   if (this->AddInterface(this->debug_addr))
+   {
+       PLAYER_ERROR("Could not add debug interface.");
+       this->SetError(-1);
+       return;
+   }
  
    // Laser geometry.
***************
*** 273,276 ****
--- 300,307 ----
    this->wkbSize = 0;
    
+   this->speed = 0;
+   this->steeringAngle = 0;
+   this->fetchOnStart = false;
+   
    // Serial port - done in the opaque driver
    //this->device_name = strdup(cf->ReadString(section, "port", DEFAULT_PORT));
***************
*** 306,309 ****
--- 337,342 ----
                  PLAYER_VECTORMAP_CODE, -1, NULL);
    
+   gettimeofday(&previous, NULL);
+   
    return;
  }
***************
*** 412,415 ****
--- 445,457 ----
      return 0;
    }
+ 
+   if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA, 
PLAYER_POSITION2D_DATA_STATE, velocity_id))
+   {
+     player_position2d_data_t * recv = 
reinterpret_cast<player_position2d_data_t * > (data);
+     speed = recv->vel.px;
+     steeringAngle = recv->pos.pa;
+     return 0;
+   }
+ 
        
    if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,
***************
*** 548,552 ****
                else if (strncmp(mode, "fetch", 5) == 0)
                {
!                       FetchReflectors(); // Fetch reflectors from database
                        mode.SetValue("positioning");
                }
--- 590,594 ----
                else if (strncmp(mode, "fetch", 5) == 0)
                {
!                       SetReflectors(FetchReflectors()); // Fetch reflectors 
from database
                        mode.SetValue("positioning");
                }
***************
*** 607,610 ****
--- 649,661 ----
    BuildWKB(); // Build an empty WKB.
    
+   PLAYER_MSG1(2, "Wheel base: %lf", wheelBase.GetValue());
+   
+   if (strncmp(mode, "fetch", 5) == 0)
+   {
+       fetchOnStart = true;
+     FetchIfNeeded();
+     mode.SetValue("positioning");
+   }
+   
    LaserPos Reading;
    for(;;)
***************
*** 616,649 ****
      ProcessMessages();
      
-     player_position2d_geom_t* vel = NULL;
-     if (velocity)
-     {
-       Message* response = velocity->Request(this->InQueue, 
PLAYER_MSGTYPE_REQ, PLAYER_POSITION2D_REQ_GET_GEOM, NULL, 0, 0, true);
-       if (response->GetDataSize() == sizeof(vel))
-               vel = 
reinterpret_cast<player_position2d_geom_t*>(response->GetPayload());
-       else
-               PLAYER_ERROR("invalid response to velocity request\n");
-     }
-     
      bool gotReading;
!     if (vel)
      {
!       if (wheelBase < 0)
        {
!               PLAYER_WARN("vehicle movement data provided but wheelBase not 
set. Add wheelbase to the NAV config file");
                gotReading = Laser.GetPositionAuto(Reading);
        }
        else
        {
-               double steeringAngle = vel->pose.pyaw;
-               double speed = vel->pose.px;
                // Convert vehicle movement data into NAV200 format and 
coordinates.
                //double arcRadius = wheelBase / tan(steeringAngle);
                //double angularVelocity = speed / arcRadius;
!               double angularVelocity = speed * tan(steeringAngle) / wheelBase;
                double velX = speed - pose[1] * angularVelocity;
                double velY = pose[0] * angularVelocity;
                double navVelX = velX * cos(pose[2]) + velY * sin(pose[2]);
                double navVelY = velY * cos(pose[2]) - velX * sin(pose[2]);
                gotReading = Laser.GetPositionSpeedVelocity(short(navVelX * 
1000), short(navVelY * 1000), short(angularVelocity * 32768.0 / M_PI), Reading);
        }
--- 667,693 ----
      ProcessMessages();
      
      bool gotReading;
!     if (velocity)
      {
!       if (wheelBase.GetValue() <= 0)
        {
!               PLAYER_WARN("vehicle movement data provided but wheelbase not 
set. Add wheelbase to the NAV config file");
                gotReading = Laser.GetPositionAuto(Reading);
        }
        else
        {
                // Convert vehicle movement data into NAV200 format and 
coordinates.
                //double arcRadius = wheelBase / tan(steeringAngle);
                //double angularVelocity = speed / arcRadius;
!               double angularVelocity = speed * tan(steeringAngle) / 
wheelBase.GetValue();
                double velX = speed - pose[1] * angularVelocity;
                double velY = pose[0] * angularVelocity;
                double navVelX = velX * cos(pose[2]) + velY * sin(pose[2]);
                double navVelY = velY * cos(pose[2]) - velX * sin(pose[2]);
+               debug_packet.vel.pa = angularVelocity;
+               debug_packet.vel.px = navVelX;
+               debug_packet.vel.py = navVelY;
+               debug_packet.stall = 0;
+               this->Publish(this->debug_addr, PLAYER_MSGTYPE_DATA, 
PLAYER_POSITION2D_DATA_STATE, (void*)&debug_packet, sizeof(debug_packet), NULL);
                gotReading = Laser.GetPositionSpeedVelocity(short(navVelX * 
1000), short(navVelY * 1000), short(angularVelocity * 32768.0 / M_PI), Reading);
        }
***************
*** 661,667 ****
        double leftx = -sin(angle);
        double lefty = cos(angle);
!       data_packet.pos.pa = atan2(forwardy, forwardx);
!       data_packet.pos.px = static_cast<double> (Reading.pos.x)/1000 - 
forwardx * pose[0] - leftx * pose[1];
!       data_packet.pos.py = static_cast<double> (Reading.pos.y)/1000 - 
forwardy * pose[0] - lefty * pose[1];
        if(Reading.quality==0xFF || Reading.quality==0xFE || 
Reading.quality==0x00)
        {
--- 705,729 ----
        double leftx = -sin(angle);
        double lefty = cos(angle);
!       double newAngle = atan2(forwardy, forwardx);
!       double newX = static_cast<double> (Reading.pos.x)/1000 - forwardx * 
pose[0] - leftx * pose[1];
!       double newY = static_cast<double> (Reading.pos.y)/1000 - forwardy * 
pose[0] - lefty * pose[1];
!       
!       // Begin debug stuff
!       struct timeval current;
!       gettimeofday(&current, NULL);
!       double dt = static_cast<double> (current.tv_sec - previous.tv_sec) + 
static_cast<double>(current.tv_usec - previous.tv_usec) / 1000000.0;
!       
!       double angVel = (newAngle - data_packet.pos.pa) / dt;
!       double velX = (newX - data_packet.pos.px) / dt;
!       double velY = (newY - data_packet.pos.py) / dt;
!       PLAYER_MSG3(2, "Vx: %lf\tVy: %lf\tVa: %lf", velX, velY, angVel);
!       data_packet.vel.pa = angVel;
!       data_packet.vel.px = velX;
!       data_packet.vel.py = velY;
!       // End debug stuff
!       
!       data_packet.pos.pa = newAngle;
!       data_packet.pos.px = newX;
!       data_packet.pos.py = newY;
        if(Reading.quality==0xFF || Reading.quality==0xFE || 
Reading.quality==0x00)
        {
***************
*** 681,685 ****
      {
        PLAYER_WARN("Failed to get reading from laser scanner\n");
!       usleep(100000);
      }
    }
--- 743,750 ----
      {
        PLAYER_WARN("Failed to get reading from laser scanner\n");
!       sleep(1);
!       // May have been disconnected. Attempt to return to positioning mode.
!         if (fetchOnStart)
!               FetchIfNeeded();
      }
    }
***************
*** 805,813 ****
  const unsigned wkbPointSize = 21;
  
! void SickNAV200::SetReflectors(player_vectormap_layer_data_t* data)
  {
!       PLAYER_MSG0(2, "Downloading reflectors.");
!       
!       numReflectors = 0;
        for (unsigned f = 0; f < data->features_count; f++)
        {
--- 870,876 ----
  const unsigned wkbPointSize = 21;
  
! int SickNAV200::InterpretLayerData(player_vectormap_layer_data_t* data, 
PositionXY* reflectors)
  {
!       int numReflectors = 0;
        for (unsigned f = 0; f < data->features_count; f++)
        {
***************
*** 816,838 ****
                if (feature.wkb_count < wkbHeaderSize)
                {
!                       PLAYER_WARN("WKB too small in SetReflectors\n");
                        continue;
                }
                if (wkb[0] == 0)
                {
!                       PLAYER_WARN("SetReflectors does not support big endian 
wkb data\n");
                        continue;
                }
!               if (*reinterpret_cast<uint32_t*>(wkb + 1) != 4)
                {
!                       PLAYER_WARN("SetReflectors only supports MultiPoint 
data\n");
                        continue;
                }
!               unsigned reflectorsInFeature = *reinterpret_cast<uint32_t*>(wkb 
+ 5);
                if (!reflectorsInFeature)
                        continue;
!               if (feature.wkb_count != wkbHeaderSize + wkbPointSize * 
reflectorsInFeature)
                {
!                       PLAYER_WARN("Unexpected WKB size in SetReflectors\n");
                        continue;
                }
--- 879,911 ----
                if (feature.wkb_count < wkbHeaderSize)
                {
!                       PLAYER_WARN("WKB too small in InterpretLayerData\n");
                        continue;
                }
                if (wkb[0] == 0)
                {
!                       PLAYER_WARN("InterpretLayerData does not support big 
endian wkb data\n");
                        continue;
                }
!               uint32_t type = *reinterpret_cast<uint32_t*>(wkb + 1);
!               bool extendedWKB = type >> 24 == 32; // Extended WKBs seem to 
store a flag in the type variable.
!               int headerSize = extendedWKB ? wkbHeaderSize + 4 : 
wkbHeaderSize;
!               if (type & 0xffffff != 4) // Ignore the most significant byte, 
it might have a flag in.
                {
!                       PLAYER_WARN1("InterpretLayerData only supports 
MultiPoint data %d\n", *reinterpret_cast<uint32_t*>(wkb + 1));
                        continue;
                }
!               unsigned reflectorsInFeature = 0;
!               if (extendedWKB)
!               {
!                       unsigned spacialReferenceID = 
*reinterpret_cast<uint32_t*>(wkb + 5);
!                       reflectorsInFeature = *reinterpret_cast<uint32_t*>(wkb 
+ 9);
!               }
!               else
!                       reflectorsInFeature = *reinterpret_cast<uint32_t*>(wkb 
+ 5);
                if (!reflectorsInFeature)
                        continue;
!               if (feature.wkb_count != headerSize + wkbPointSize * 
reflectorsInFeature)
                {
!                       PLAYER_WARN("Unexpected WKB size in 
InterpretLayerData\n");
                        continue;
                }
***************
*** 847,853 ****
                for (unsigned r = 0; r < reflectorsInFeature; r++)
                {
!                       uint8_t* pointData = wkb + wkbHeaderSize + wkbPointSize 
* r;
                        if (pointData[0] == 0)
!                               PLAYER_ERROR("SetReflectors does not support 
big endian wkb data, let alone inconsistently\n");
                        if (*reinterpret_cast<uint32_t*>(pointData + 1) != 1)
                                PLAYER_ERROR("Malformed wkb data, expected 
point\n");
--- 920,926 ----
                for (unsigned r = 0; r < reflectorsInFeature; r++)
                {
!                       uint8_t* pointData = wkb + headerSize + wkbPointSize * 
r;
                        if (pointData[0] == 0)
!                               PLAYER_ERROR("InterpretLayerData does not 
support big endian wkb data, let alone inconsistently\n");
                        if (*reinterpret_cast<uint32_t*>(pointData + 1) != 1)
                                PLAYER_ERROR("Malformed wkb data, expected 
point\n");
***************
*** 856,859 ****
--- 929,940 ----
                }
        }
+       return numReflectors;
+ }
+ 
+ void SickNAV200::SetReflectors(player_vectormap_layer_data_t* data)
+ {
+       PLAYER_MSG0(2, "Downloading reflectors.");
+       
+       numReflectors = InterpretLayerData(data, reflectors);
        
        BuildWKB(); // Might be something odd about the passed wkb, so build it 
the usual way.
***************
*** 881,886 ****
  }
  
! void SickNAV200::FetchReflectors()
  {
        PLAYER_MSG0(2, "Fetching reflectors from vectormap");
        if (reflector_map)
--- 962,988 ----
  }
  
! void SickNAV200::FetchIfNeeded()
  {
+       // Check if reflectors are correct.
+       player_vectormap_layer_data_t* dbData = FetchReflectors();
+       PositionXY dbReflectors[32];
+       int numDBReflectors = InterpretLayerData(dbData, dbReflectors);
+       GetReflectors();
+       // Determine if db and nav reflectors are identical.
+       bool same = numDBReflectors == numReflectors;
+       for (int i = 0; i < numReflectors && same; i++)
+               same = reflectors[i].x == dbReflectors[i].x && reflectors[i].y 
== dbReflectors[i].y;
+       if (!same) // If the reflectors are different.
+       {
+               PLAYER_MSG0(2, "Updating reflectors.");
+               SetReflectors(dbData); // Update the nav200 ones.
+       }
+       else
+               PLAYER_MSG0(2, "No reflector update needed.");
+ }
+ 
+ player_vectormap_layer_data_t* SickNAV200::FetchReflectors()
+ {
+       player_vectormap_layer_data_t* layerData = NULL;
        PLAYER_MSG0(2, "Fetching reflectors from vectormap");
        if (reflector_map)
***************
*** 904,910 ****
                                if (response->GetHeader()->type == 
PLAYER_MSGTYPE_RESP_ACK && response->GetHeader()->subtype == 
PLAYER_VECTORMAP_REQ_GET_LAYER_DATA)
                                {
!                                       player_vectormap_layer_data_t* 
layerData = 
reinterpret_cast<player_vectormap_layer_data_t*>(response->GetPayload());
!                                       
!                                       SetReflectors(layerData);
                                        gotReflectors = true;
                                }
--- 1006,1010 ----
                                if (response->GetHeader()->type == 
PLAYER_MSGTYPE_RESP_ACK && response->GetHeader()->subtype == 
PLAYER_VECTORMAP_REQ_GET_LAYER_DATA)
                                {
!                                       layerData = 
reinterpret_cast<player_vectormap_layer_data_t*>(response->GetPayload());
                                        gotReflectors = true;
                                }
***************
*** 917,920 ****
--- 1017,1021 ----
        else
                PLAYER_WARN("no vectormap provided to fetch reflectors from\n");
+       return layerData;
  }
  


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to