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

Modified Files:
        nav200.cc sicknav200.cc 
Log Message:
fixed provides parsing in driver examples
serial stream fixes
added mapping capability to nav200 driver, and other bug fixes
added vectormap to playerprop utility


Index: nav200.cc
===================================================================
RCS file: 
/cvsroot/playerstage/code/player/server/drivers/position/nav200/nav200.cc,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** nav200.cc   6 Dec 2007 02:35:36 -0000       1.3
--- nav200.cc   14 Dec 2007 00:19:55 -0000      1.4
***************
*** 697,723 ****
        else
        {
!         if(receivedBuffer[3]=='E'){
!           error.F0 = receivedBuffer[4];
!           error.F1 = receivedBuffer[5];
!           error.F2 = receivedBuffer[6];
!           error.F3 = receivedBuffer[7];
!   
!           //check out what the error is and it out
!           PrintErrorMsg();
            sn200->InQueue->ClearFilter();
!           return -2;
          }
!   
!         packet.header = receivedBuffer[0];
!         packet.length = receivedBuffer[1];
!         packet.mode = receivedBuffer[2];
!         packet.function = receivedBuffer[3];
!         packet.dataLength = packet.length-HEADER_SIZE-FOOTER_SIZE;
!         memcpy(packet.data, receivedBuffer+4, packet.dataLength);
!         packet.BCC = receivedBuffer[4+packet.dataLength];
!   
!         memmove(receivedBuffer, receivedBuffer+dataLength, 
bytesReceived-dataLength);
!         bytesReceived-=dataLength;
!         sn200->InQueue->ClearFilter();
          return 1;
        }
--- 697,723 ----
        else
        {
!           packet.header = receivedBuffer[0];
!           packet.length = receivedBuffer[1];
!           packet.mode = receivedBuffer[2];
!           packet.function = receivedBuffer[3];
!           packet.dataLength = packet.length-HEADER_SIZE-FOOTER_SIZE;
!           memcpy(packet.data, receivedBuffer+4, packet.dataLength);
!           packet.BCC = receivedBuffer[4+packet.dataLength];
!     
!           memmove(receivedBuffer, receivedBuffer+dataLength, 
bytesReceived-dataLength);
!           bytesReceived-=dataLength;
            sn200->InQueue->ClearFilter();
!           
!           if(receivedBuffer[3]=='E'){
!                 error.F0 = receivedBuffer[4];
!                 error.F1 = receivedBuffer[5];
!                 error.F2 = receivedBuffer[6];
!                 error.F3 = receivedBuffer[7];
!         
!                 //check out what the error is and it out
!                 PrintErrorMsg();
!                 return -2;
          }
! 
          return 1;
        }

Index: sicknav200.cc
===================================================================
RCS file: 
/cvsroot/playerstage/code/player/server/drivers/position/nav200/sicknav200.cc,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** sicknav200.cc       6 Dec 2007 02:35:36 -0000       1.9
--- sicknav200.cc       14 Dec 2007 00:19:55 -0000      1.10
***************
*** 72,75 ****
--- 72,76 ----
    name "sicknav200"
    provides ["position2d:0"]
+   provides ["vectormap:0"]
    requires ["opaque:0"]
  )
***************
*** 114,117 ****
--- 115,120 ----
  #include "nav200.h"
  
+ #define DEFAULT_SICKNAV200_MODE "positioning"
+ 
  // The laser device class.
  class SickNAV200 : public Driver
***************
*** 134,137 ****
--- 137,147 ----
      // Main function for device thread.
      virtual void Main();
+     
+     // Add new reflectors.
+     void UpdateMap();
+     // Get the reflector positions from the device.
+     void GetReflectors();
+     // Build the well known binary view of the reflector positions.
+     void BuildWKB();
  
    protected:
***************
*** 141,149 ****
      double size[2];
      
      // Name of device used to communicate with the laser
      //char *device_name;
      
-     bool nchanged;
-     
      // storage for outgoing data
      player_position2d_data_t data_packet;
--- 151,167 ----
      double size[2];
      
+     // Reflector positions.
+     PositionXY* reflectors;
+     int numReflectors;
+     uint8_t* wkbData;
+     int wkbSize;
+     
+     // If mode is set to mapping the reflector positions will be mapped,
+     // and mode will be automatically set back to positioning.
+     StringProperty mode;
+     
      // Name of device used to communicate with the laser
      //char *device_name;
      
      // storage for outgoing data
      player_position2d_data_t data_packet;
***************
*** 156,160 ****
      Device *opaque;
      player_devaddr_t opaque_id;
! 
  };
  
--- 174,182 ----
      Device *opaque;
      player_devaddr_t opaque_id;
!     
!     // Position interface
!     player_devaddr_t position_addr;
!     // Vector map interface
!     player_devaddr_t vectormap_addr;
  };
  
***************
*** 180,185 ****
  // Constructor
  SickNAV200::SickNAV200(ConfigFile* cf, int section)
!     : Driver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN, 
PLAYER_POSITION2D_CODE)
  {
    // Laser geometry.
    this->pose[0] = cf->ReadTupleLength(section, "pose", 0, 0.0);
--- 202,238 ----
  // Constructor
  SickNAV200::SickNAV200(ConfigFile* cf, int section)
!     : Driver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN),
!       mode ("mode", DEFAULT_SICKNAV200_MODE, 0)
  {
+   // Create position interface
+   if (cf->ReadDeviceAddr(&(this->position_addr), section, 
+                        "provides", PLAYER_POSITION2D_CODE, -1, NULL) != 0)
+   {
+       PLAYER_ERROR("Could not read position interface device address.");
+       this->SetError(-1);
+       return;
+   }  
+   if (this->AddInterface(this->position_addr))
+   {
+       PLAYER_ERROR("Could not add position interface.");
+       this->SetError(-1);
+       return;
+   }
+   
+   // Create vectormap interface
+   if (cf->ReadDeviceAddr(&(this->vectormap_addr), section, 
+                            "provides", PLAYER_VECTORMAP_CODE, -1, NULL) != 0)
+   {
+       PLAYER_ERROR("Could not read vectormap interface device address.");
+       this->SetError(-1);
+       return;
+   }
+   if (this->AddInterface(this->vectormap_addr))
+   {
+       PLAYER_ERROR("Could not add vectormap interface.");
+       this->SetError(-1);
+       return;
+   }
+ 
    // Laser geometry.
    this->pose[0] = cf->ReadTupleLength(section, "pose", 0, 0.0);
***************
*** 188,193 ****
    this->size[0] = 0.15;
    this->size[1] = 0.15;
! 
!   nchanged = true;
    
    // Serial port - done in the opaque driver
--- 241,249 ----
    this->size[0] = 0.15;
    this->size[1] = 0.15;
!   
!   this->reflectors = NULL;
!   this->numReflectors = 0;
!   this->wkbData = NULL;
!   this->wkbSize = 0;
    
    // Serial port - done in the opaque driver
***************
*** 195,200 ****
  
    // nav200 parameters, convert to cm
!   this->min_radius = static_cast<int> (cf->ReadLength(section, "min_radius", 
1) * 100);
!   this->max_radius = static_cast<int> (cf->ReadLength(section, "max_radius", 
30) * 100);
    
    this->opaque = NULL;
--- 251,257 ----
  
    // nav200 parameters, convert to cm
!   this->min_radius = static_cast<int> (cf->ReadLength(section, "min_radius", 
1) * 1000);
!   this->max_radius = static_cast<int> (cf->ReadLength(section, "max_radius", 
30) * 1000);
!   this->RegisterProperty ("mode", &this->mode, cf, section);
    
    this->opaque = NULL;
***************
*** 216,219 ****
--- 273,278 ----
  {
    //free(device_name);
+       delete [] reflectors;
+       delete [] wkbData;
  }
  
***************
*** 246,251 ****
    // Open the terminal
    Laser.Initialise(this, opaque, opaque_id);
!   puts("Laser initilised");
! 
  
    PLAYER_MSG0(2, "NAV200 ready");
--- 305,309 ----
    // Open the terminal
    Laser.Initialise(this, opaque, opaque_id);
!   PLAYER_MSG0(2, "Laser initialised");
  
    PLAYER_MSG0(2, "NAV200 ready");
***************
*** 289,293 ****
    if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,
                                   PLAYER_POSITION2D_REQ_GET_GEOM,
!                                  this->device_addr))
    {
      player_position2d_geom_t geom={{0}};
--- 347,351 ----
    if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,
                                   PLAYER_POSITION2D_REQ_GET_GEOM,
!                                  this->position_addr))
    {
      player_position2d_geom_t geom={{0}};
***************
*** 298,302 ****
      geom.size.sw = this->size[1];
  
!     this->Publish(this->device_addr,
                    resp_queue,
                    PLAYER_MSGTYPE_RESP_ACK,
--- 356,360 ----
      geom.size.sw = this->size[1];
  
!     this->Publish(this->position_addr,
                    resp_queue,
                    PLAYER_MSGTYPE_RESP_ACK,
***************
*** 305,308 ****
--- 363,469 ----
      return(0);
    }
+   
+   static char layerName[5] = "0"; // Dumb name.
+   
+       // Request for map info
+       if (Message::MatchMessage(hdr,  PLAYER_MSGTYPE_REQ,
+                                       PLAYER_VECTORMAP_REQ_GET_MAP_INFO,
+                                       this->vectormap_addr))
+       {
+         player_extent2d_t extent;
+         if (numReflectors > 0)
+         {
+                 extent.x0 = extent.x1 = reflectors[0].x;
+                 extent.y0 = extent.y1 = reflectors[0].y;
+                 for (int i = 1; i < numReflectors; i++)
+                 {
+                         if (reflectors[i].x < extent.x0)
+                                 extent.x0 = reflectors[i].x;
+                         if (reflectors[i].x > extent.x1)
+                                 extent.x1 = reflectors[i].x;
+                         if (reflectors[i].y < extent.y0)
+                                 extent.y0 = reflectors[i].y;
+                         if (reflectors[i].y > extent.y1)
+                                 extent.y1 = reflectors[i].y;
+                 }
+                 extent.x0 = extent.x0 / 1000.0 - 1; // Convert to metres, 1 
metre as a margin.
+                 extent.x1 = extent.x1 / 1000.0 + 1;
+                 extent.y0 = extent.y0 / 1000.0 - 1;
+                 extent.y1 = extent.y1 / 1000.0 + 1;
+         }
+         else
+                 extent.x0 = extent.y0 = extent.x1 = extent.y1 = 0;
+         
+         static player_vectormap_layer_info_t layerInfo;
+         layerInfo.name = layerName;
+         layerInfo.name_count = strlen(layerInfo.name)+1;
+         layerInfo.extent = extent;
+         
+         player_vectormap_info_t response;
+         response.srid = 0;
+         response.layers_count = 1;
+         response.layers = &layerInfo;
+         response.extent = extent;
+       
+         this->Publish(this->vectormap_addr,
+                       resp_queue,
+                       PLAYER_MSGTYPE_RESP_ACK,
+                       PLAYER_VECTORMAP_REQ_GET_MAP_INFO,
+                       (void*)&response);
+         return(0);
+       }
+       // Request for layer data
+       else if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,
+                                  PLAYER_VECTORMAP_REQ_GET_LAYER_DATA,
+                                  this->vectormap_addr))
+       {
+         static char featureName[6] = "point";
+         player_vectormap_feature_data feature;
+         memset(&feature,0,sizeof(feature));
+         feature.name = featureName;
+         feature.name_count = strlen(feature.name)+1;
+         feature.wkb = wkbData;
+         feature.wkb_count = wkbSize;
+         
+         player_vectormap_layer_data_t response;
+         response.name = layerName;
+         response.name_count = strlen(response.name)+1;
+         response.features_count = wkbSize > 0; // If we have no data, dont' 
publish a feature.
+         response.features = &feature;
+         
+         this->Publish(this->vectormap_addr,
+                       resp_queue,
+                       PLAYER_MSGTYPE_RESP_ACK,
+                       PLAYER_VECTORMAP_REQ_GET_LAYER_DATA,
+                       (void*)&response);
+       
+         return(0);
+       }
+ 
+       if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_REQ, 
PLAYER_SET_STRPROP_REQ, this->vectormap_addr) ||
+                       Message::MatchMessage (hdr, PLAYER_MSGTYPE_REQ, 
PLAYER_SET_STRPROP_REQ, this->position_addr))
+       {
+           player_strprop_req_t req = *reinterpret_cast<player_strprop_req_t*> 
(data);
+           PLAYER_MSG1(2, "%s", req.key);
+               if (strcmp("mode", req.key) == 0)
+           {
+               mode.SetValueFromMessage(reinterpret_cast<void*> (&req));
+               if (strncmp(mode, "mapping", 7) == 0)
+               {
+                       UpdateMap();
+                       mode.SetValue("positioning"); // Automatically return 
to positioning.
+               }
+               else if (strncmp(mode, "positioning", 11) == 0)
+               {
+                       // Default.
+               }
+               else
+               {
+                       PLAYER_ERROR1("Unrecognised mode: %s", mode.GetValue());
+               }
+               
+               return 0;
+           }
+       }
  
    // Don't know how to handle this message.
***************
*** 314,317 ****
--- 475,502 ----
  void SickNAV200::Main() 
  {
+   if (!Laser.EnterStandby())
+   {
+       PLAYER_ERROR("unable to enter standby mode\n");
+   }
+   if (!Laser.SetReflectorRadius(0, 45))
+   {
+       PLAYER_ERROR("unable to set reflector radius\n");
+       return ;
+   }
+   
+   if (!Laser.EnterPositioning())
+   {
+       PLAYER_ERROR("unable to enter position mode\n");
+       return ;
+   }
+   if (!Laser.SetActionRadii(min_radius, max_radius))
+   {
+       PLAYER_ERROR("failed to set action radii\n");
+       return ;
+   }
+   
+   // Download the reflector positions in case the vectormap is subscribed to.
+   GetReflectors();
+       
    LaserPos Reading;
    for(;;)
***************
*** 323,340 ****
      ProcessMessages();
      
-     if (nchanged)
-     {
-         if (!Laser.EnterStandby() || !Laser.EnterPositioning())
-         {
-             PLAYER_ERROR("unable to enter standby or position mode\n");
-             return ;
-         }
-         if (!Laser.SetActionRadii(min_radius, max_radius))
-         {
-             PLAYER_ERROR("failed to set action radii\n");
-             return ;
-         }
-         nchanged = false;
-     }
      // get update and publish result
      if(Laser.GetPositionAuto(Reading))
--- 508,511 ----
***************
*** 353,357 ****
        }
  
!       this->Publish(this->device_addr,
                     PLAYER_MSGTYPE_DATA,
                     PLAYER_POSITION2D_DATA_STATE,
--- 524,528 ----
        }
  
!       this->Publish(this->position_addr,
                     PLAYER_MSGTYPE_DATA,
                     PLAYER_POSITION2D_DATA_STATE,
***************
*** 366,368 ****
--- 537,676 ----
  }
  
+ void SickNAV200::UpdateMap()
+ {
+       if (!Laser.EnterStandby())
+       {
+               PLAYER_ERROR("Unable to enter standby mode.\n");
+       }
+       
+       PLAYER_MSG0(2, "Deleting old reflectors.");
+       PositionXY pos; // Just somewhere for delete to output the position to.
+       while(Laser.DeleteReflectorPosition(0,0,pos))
+       {
+               PLAYER_MSG0(4, "Deleted a reflector.");
+       }
+       
+       if (!Laser.EnterMapping())
+       {
+               PLAYER_ERROR("Unable to enter mapping mode.\n");
+               return;
+       }
+       // Map the reflectors.
+       PLAYER_MSG0(2, "Started mapping.");
+       numReflectors = Laser.StartMapping(0, 0, 0, 0, 45); // Radius may not 
be needed.
+       PLAYER_MSG1(2, "Mapped %d reflectors.", numReflectors);
+       
+       if (numReflectors < 0)
+       {
+               PLAYER_ERROR("Reflector mapping failed.\n");
+               return;
+       }
  
+       delete [] reflectors; // Clear old reflector positions.
+       reflectors = new PositionXY[numReflectors];
+       for (uint8_t i = 0; i < numReflectors; i++)
+       {
+               if (!Laser.MappingPosition(0, i, reflectors[i]))
+                       PLAYER_ERROR1("Failed to get reflector %d\n", i);
+               else
+                       PLAYER_MSG2(4, "Got reflector. X = %d, Y = %d", 
reflectors[i].x, reflectors[i].y);
+       }
+       
+       if (!Laser.EnterStandby())
+       {
+               PLAYER_ERROR("Unable to return to standby mode after 
mapping.\n");
+               return;
+       }
+       
+       PLAYER_MSG0(2, "Inserting reflectors.");
+       for (int i = 0; i < numReflectors; i++)
+       {
+               if 
(!Laser.InsertReflectorPosition(0,i,reflectors[i].x,reflectors[i].y))
+               {
+                       PLAYER_ERROR1("Unable to insert reflector %d.\n", i);
+                       return;
+               }
+       }
+       
+       BuildWKB(); // Update wkb to show new reflectors.
+       
+       if (!Laser.EnterPositioning())
+       {
+               PLAYER_ERROR("Unable to return to positioning mode after 
mapping.\n");
+               return;
+       }
+       
+       PLAYER_MSG0(2, "Mapping complete.");
+ }
+ 
+ void SickNAV200::GetReflectors()
+ {
+       PLAYER_MSG0(2, "Uploading reflectors.");
+       
+       if (!Laser.EnterStandby())
+       {
+               PLAYER_ERROR("Unable to enter standby mode.\n");
+       }
+       
+       if (!Laser.EnterUpload())
+       {
+               PLAYER_ERROR("Unable to enter upload mode.\n");
+               return;
+       }
+       
+       delete [] reflectors; // Clear old reflector positions.
+       reflectors = new PositionXY[32]; // Max 32 reflectors in a layer.
+       numReflectors = 0;
+       ReflectorData reflector;
+       while (true)
+       {
+               if (!Laser.GetUploadTrans(0, reflector))
+               {
+                       PLAYER_ERROR("Error getting reflector.\n");
+                       return;
+               }
+               if (reflector.number <= 32) // If it's a valid reflector.
+               {
+                       PLAYER_MSG1(4, "Reflector %d", reflector.number);
+                       reflectors[reflector.number] = reflector.pos;
+                       if (reflector.number >= numReflectors)
+                               numReflectors = reflector.number + 1;
+               }
+               else
+                       break;
+       }
+       
+       BuildWKB();
+       
+       if (!Laser.EnterStandby())
+       {
+               PLAYER_ERROR("Unable to return to standby mode after getting 
reflectors.\n");
+       }
+       
+       if (!Laser.EnterPositioning())
+       {
+               PLAYER_ERROR("Unable to return to positioning mode after 
getting reflectors.\n");
+               return;
+       }
+ }
+ 
+ void SickNAV200::BuildWKB()
+ {
+       // Encode reflector positions in well known binary format for 
publishing.
+       delete [] wkbData; // Clear old data.
+       wkbSize = 9 + 21 * numReflectors;
+       wkbData = new uint8_t[wkbSize];
+       wkbData[0] = 1; // Little endian (0 for big endian).
+       *reinterpret_cast<uint32_t*>(wkbData + 1) = 4; // MultiPoint
+       *reinterpret_cast<uint32_t*>(wkbData + 5) = numReflectors; // Num 
points.
+       for (int i = 0; i < numReflectors; i++)
+       {
+               wkbData[9 + 21 * i] = 1; // Still little endian.
+               uint32_t wkbType = 1; // Point
+               *reinterpret_cast<uint32_t*>(wkbData + 9 + 21 * i + 1) = 
wkbType;
+               double x = reflectors[i].x / 1000.0; // mm to metres.
+               double y = reflectors[i].y / 1000.0;
+               *reinterpret_cast<double*>(wkbData + 9 + 21 * i + 5) = x;
+               *reinterpret_cast<double*>(wkbData + 9 + 21 * i + 13) = y;
+       }
+ }


-------------------------------------------------------------------------
SF.Net email is sponsored by:
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services
for just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to