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

Modified Files:
        sicknav200.cc 
Log Message:
These changes were contributed by David Olsen, including:
Extensive NAV200 changes, adding new constallelation configuration options
Fix to memory leak of messages when a player client is destroyed
Fix to laser interface which assumed intensity was provided
Fix to memory leaks in vectormap interface (mainly leaking geoms)
Proper error handling in C++ PlayerClient Peek
Mutex lock in VectorMapProxy GetLayerData
playerv vectormap rendering bug 



Index: sicknav200.cc
===================================================================
RCS file: 
/cvsroot/playerstage/code/player/server/drivers/position/nav200/sicknav200.cc,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -d -r1.12 -r1.13
*** sicknav200.cc       20 Dec 2007 23:28:27 -0000      1.12
--- sicknav200.cc       4 Feb 2008 18:59:44 -0000       1.13
***************
*** 35,40 ****
  output of the device. 
  
! Currently the driver assumes the nav200 has been correctly initialised and 
loaded with the 
! reflector layers.
  
  @par Compile-time dependencies
--- 35,45 ----
  output of the device. 
  
! By default, the driver will enter positioning mode and use the reflectors 
stored on the nav200.
! To map the visible reflectors and store them on the nav200, set the mode 
property to mapping.
! To copy the reflector positions from a vectormap onto the nav200, add a 
vectormap to the requires
! list of the driver and set the mode property to fetch.
! To get the reflector positions from the nav200 to display using the vectormap 
this driver
! provides, set the mode to upload. Note: mapping and fetch also provide the 
reflectors positions
! for display, as well as storing them on the nav200.
  
  @par Compile-time dependencies
***************
*** 44,48 ****
  @par Provides
  
! - @ref interface_laser
  
  @par Requires
--- 49,54 ----
  @par Provides
  
! - @ref interface_position2d
! - @ref interface_vectormap
  
  @par Requires
***************
*** 64,67 ****
--- 70,78 ----
    - Default: [0.15 0.15]
    - Footprint (x,y) of the laser.
+ 
+ - wheelBase (double)
+   - Default: -1.0
+   - Distance between front and rear wheels. Used to calculate velocities
+     when vehicle movement data is provided.
        
  @par Example 
***************
*** 71,76 ****
  (
    name "sicknav200"
!   provides ["position2d:0"]
!   provides ["vectormap:0"]
    requires ["opaque:0"]
  )
--- 82,86 ----
  (
    name "sicknav200"
!   provides ["position2d:0" "vectormap:0"]
    requires ["opaque:0"]
  )
***************
*** 84,88 ****
  @endverbatim
  
! @author Kathy Fung, Toby Collett, inro technologies
  
  */
--- 94,98 ----
  @endverbatim
  
! @author Kathy Fung, Toby Collett, David Olsen, inro technologies
  
  */
***************
*** 138,145 ****
      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();
--- 148,159 ----
      virtual void Main();
      
!     // Get device to map reflectors.
      void UpdateMap();
      // Get the reflector positions from the device.
      void GetReflectors();
+     // 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();
***************
*** 151,160 ****
      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.
--- 165,177 ----
      double size[2];
      
+     // TODO: Add reflector layer support.
      // Reflector positions.
!     PositionXY reflectors[32];
      int numReflectors;
      uint8_t* wkbData;
      int wkbSize;
      
+     DoubleProperty wheelBase;
+     
      // If mode is set to mapping the reflector positions will be mapped,
      // and mode will be automatically set back to positioning.
***************
*** 171,174 ****
--- 188,200 ----
      int min_radius, max_radius;
      
+     // Reflector Map Driver info
+     // Provides reflector positions if not mapped by nav200
+     Device *reflector_map;
+     player_devaddr_t reflector_map_id;
+     
+     // Velocity Driver info
+     Device *velocity;
+     player_devaddr_t velocity_id;
+     
      // Opaque Driver info
      Device *opaque;
***************
*** 203,206 ****
--- 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)
  {
***************
*** 242,246 ****
    this->size[1] = 0.15;
    
-   this->reflectors = NULL;
    this->numReflectors = 0;
    this->wkbData = NULL;
--- 269,272 ----
***************
*** 250,257 ****
    //this->device_name = strdup(cf->ReadString(section, "port", DEFAULT_PORT));
  
!   // 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;
--- 276,284 ----
    //this->device_name = strdup(cf->ReadString(section, "port", DEFAULT_PORT));
  
!   // nav200 parameters, convert to mm
    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->RegisterProperty ("wheelbase", &this->wheelBase, cf, section);
    
    this->opaque = NULL;
***************
*** 267,270 ****
--- 294,309 ----
    PLAYER_MSG0(2, "reading opaque id now");
    
+   PLAYER_MSG0(2, "reading velocity id now");
+   this->velocity = NULL;
+   memset(&this->velocity_id, 0, sizeof(this->velocity_id));
+   cf->ReadDeviceAddr(&this->velocity_id, section, "requires",
+                 PLAYER_POSITION2D_CODE, -1, NULL);
+   
+   PLAYER_MSG0(2, "reading reflector map id now");
+   this->reflector_map = NULL;
+   memset(&this->reflector_map_id, 0, sizeof(this->reflector_map_id));
+   cf->ReadDeviceAddr(&this->reflector_map_id, section, "requires",
+                 PLAYER_VECTORMAP_CODE, -1, NULL);
+   
    return;
  }
***************
*** 273,277 ****
  {
    //free(device_name);
-       delete [] reflectors;
        delete [] wkbData;
  }
--- 312,315 ----
***************
*** 285,289 ****
    
    // Subscribe to the opaque device.
!   if(Device::MatchDeviceAddress(this->opaque_id, this->device_addr))
    {
      PLAYER_ERROR("attempt to subscribe to self");
--- 323,327 ----
    
    // Subscribe to the opaque device.
!   if(Device::MatchDeviceAddress(this->opaque_id, this->position_addr) || 
Device::MatchDeviceAddress(this->opaque_id, this->vectormap_addr))
    {
      PLAYER_ERROR("attempt to subscribe to self");
***************
*** 303,306 ****
--- 341,374 ----
    }
    
+   if (this->velocity_id.interf == PLAYER_POSITION2D_CODE) // Velocity is 
provided.
+   {
+       if(!(this->velocity = deviceTable->GetDevice(this->velocity_id)))
+     {
+       PLAYER_ERROR("unable to locate suitable position2d device");
+       return(-1);
+     }
+      
+     if(this->velocity->Subscribe(this->InQueue) != 0)
+     {
+       PLAYER_ERROR("unable to subscribe to position2d device");
+       return(-1);
+     }
+   }
+   
+   if (this->reflector_map_id.interf == PLAYER_VECTORMAP_CODE) // Reflector 
positions are provided.
+   {
+       if(!(this->reflector_map = 
deviceTable->GetDevice(this->reflector_map_id)))
+       {
+         PLAYER_ERROR("unable to locate suitable vectormap device");
+         return(-1);
+       }
+          
+       if(this->reflector_map->Subscribe(this->InQueue) != 0)
+       {
+         PLAYER_ERROR("unable to subscribe to vectormap device");
+         return(-1);
+       }
+   }
+   
    // Open the terminal
    Laser.Initialise(this, opaque, opaque_id);
***************
*** 364,368 ****
    }
    
!   static char layerName[5] = "0"; // Dumb name.
    
        // Request for map info
--- 432,436 ----
    }
    
!   char* layerName = "0"; // Dumb name.
    
        // Request for map info
***************
*** 371,374 ****
--- 439,443 ----
                                        this->vectormap_addr))
        {
+         // I am not sure if this and the below block of code leak memory. 
Based on postgis.cc
          player_extent2d_t extent;
          if (numReflectors > 0)
***************
*** 395,407 ****
                  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;
        
--- 464,476 ----
                  extent.x0 = extent.y0 = extent.x1 = extent.y1 = 0;
          
!         player_vectormap_layer_info_t* layerInfo = new 
player_vectormap_layer_info_t;
!         layerInfo->name = strdup(layerName);
!         layerInfo->name_count = strlen(layerInfo->name)+1;
!         layerInfo->extent = extent;
          
!         static player_vectormap_info_t response;
          response.srid = 0;
          response.layers_count = 1;
!         response.layers = layerInfo;
          response.extent = extent;
        
***************
*** 418,434 ****
                                   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,
--- 487,505 ----
                                   this->vectormap_addr))
        {
!         char* featureName = "point";
!         player_vectormap_feature_data* feature = new 
player_vectormap_feature_data;
!         memset(feature,0,sizeof(feature));
!         feature->name = strdup(featureName);
!         feature->name_count = strlen(feature->name)+1;
!         feature->wkb = new uint8_t[wkbSize];
!         feature->wkb_count = wkbSize;
!         for (uint32_t i=0; i < wkbSize; ++i)
!                 feature->wkb[i] = wkbData[i];
          
!         static player_vectormap_layer_data_t response;
!         response.name = strdup(layerName);
          response.name_count = strlen(response.name)+1;
!         response.features_count = numReflectors > 0; // If we have no data, 
don't publish a feature.
!         response.features = numReflectors > 0 ? feature : NULL;
          
          this->Publish(this->vectormap_addr,
***************
*** 440,443 ****
--- 511,535 ----
          return(0);
        }
+       // Write layer data
+       else if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,
+                                      PLAYER_VECTORMAP_REQ_WRITE_LAYER,
+                                          this->vectormap_addr))
+       {
+               player_vectormap_layer_data_t* layerData = 
reinterpret_cast<player_vectormap_layer_data_t*>(data);
+               
+               SetReflectors(layerData);
+               
+               // Does the ack need the layer data?
+               this->Publish(this->vectormap_addr,
+                         resp_queue,
+                         PLAYER_MSGTYPE_RESP_ACK,
+                         PLAYER_VECTORMAP_REQ_WRITE_LAYER,
+                         (void*)layerData,
+                         sizeof(player_vectormap_layer_data_t),
+                         NULL);
+               
+               return 0;
+       }
+       
  
        if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_REQ, 
PLAYER_SET_STRPROP_REQ, this->vectormap_addr) ||
***************
*** 452,456 ****
                {
                        UpdateMap();
!                       mode.SetValue("positioning"); // Automatically return 
to positioning.
                }
                else if (strncmp(mode, "positioning", 11) == 0)
--- 544,558 ----
                {
                        UpdateMap();
!                       mode.SetValue("positioning"); // Automatically return 
to positioning mode.
!               }
!               else if (strncmp(mode, "fetch", 5) == 0)
!               {
!                       FetchReflectors(); // Fetch reflectors from database
!                       mode.SetValue("positioning");
!               }
!               else if (strncmp(mode, "upload", 5) == 0)
!               {
!                       GetReflectors(); // Get reflectors from NAV200
!                       mode.SetValue("positioning");
                }
                else if (strncmp(mode, "positioning", 11) == 0)
***************
*** 503,509 ****
    }
    
!   // Download the reflector positions in case the vectormap is subscribed to.
!   GetReflectors();
!       
    LaserPos Reading;
    for(;;)
--- 605,610 ----
    }
    
!   BuildWKB(); // Build an empty WKB.
!   
    LaserPos Reading;
    for(;;)
***************
*** 515,529 ****
      ProcessMessages();
      
      // get update and publish result
!     if(Laser.GetPositionAuto(Reading))
      {
!       double angle = M_PI + Reading.orientation/32768.0*M_PI - pose[2];
!       double dx = sin(angle);
!       double dy = cos(angle);
!       double rx = sin(angle + M_PI/2.0);
!       double ry = cos(angle + M_PI/2.0);
!       data_packet.pos.pa = atan2(dx, dy);
!       data_packet.pos.px = static_cast<double> (Reading.pos.x)/1000 - dx * 
pose[1] - rx * pose[0];
!       data_packet.pos.py = static_cast<double> (Reading.pos.y)/1000 - dy * 
pose[1] - ry * pose[0];
        if(Reading.quality==0xFF || Reading.quality==0xFE || 
Reading.quality==0x00)
        {
--- 616,667 ----
      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);
+       }
+     }
+     else
+       gotReading = Laser.GetPositionAuto(Reading);
+     
      // get update and publish result
!     if(gotReading)
      {
!       // Use NAV200 position and orientation data to determine vehicle 
position and orientation.
!       double angle = Reading.orientation/32768.0*M_PI - pose[2];
!       double forwardx = cos(angle);
!       double forwardy = sin(angle);
!       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)
        {
***************
*** 571,574 ****
--- 709,714 ----
        numReflectors = Laser.StartMapping(0, 0, 0, 0, 45); // Radius may not 
be needed.
        PLAYER_MSG1(2, "Mapped %d reflectors.", numReflectors);
+       if (numReflectors > 32)
+               PLAYER_ERROR("More reflectors mapped than NAV200 supports.\n");
        
        if (numReflectors < 0)
***************
*** 578,583 ****
        }
  
-       delete [] reflectors; // Clear old reflector positions.
-       reflectors = new PositionXY[numReflectors];
        for (uint8_t i = 0; i < numReflectors; i++)
        {
--- 718,721 ----
***************
*** 630,635 ****
        }
        
-       delete [] reflectors; // Clear old reflector positions.
-       reflectors = new PositionXY[32]; // Max 32 reflectors in a layer.
        numReflectors = 0;
        ReflectorData reflector;
--- 768,771 ----
***************
*** 666,674 ****
  }
  
  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).
--- 802,927 ----
  }
  
+ const unsigned wkbHeaderSize = 9;
+ 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++)
+       {
+               player_vectormap_feature_data_t feature = data->features[f];
+               uint8_t* wkb = feature.wkb;
+               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;
+               }
+               
+               // Expand the reflectors array
+               int startIndex = numReflectors;
+               numReflectors += reflectorsInFeature;
+               if (numReflectors > 32)
+                       PLAYER_ERROR("More reflectors passed than NAV200 
supports\n");
+               
+               // Copy in new reflectors
+               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");
+                       reflectors[startIndex + r].x = 
int(*reinterpret_cast<double*>(pointData + 5) * 1000.0);
+                       reflectors[startIndex + r].y = 
int(*reinterpret_cast<double*>(pointData + 13) * 1000.0);
+               }
+       }
+       
+       BuildWKB(); // Might be something odd about the passed wkb, so build it 
the usual way.
+       
+       // Download the reflectors to the device.
+       
+       if (!Laser.EnterStandby())
+               PLAYER_ERROR("Unable to enter standby mode.\n");
+       
+       if (!Laser.EnterDownload())
+       {
+               PLAYER_ERROR("Unable to enter download mode.\n");
+               return;
+       }
+       
+       for (int r = 0; r < numReflectors; r++)
+               Laser.DownloadReflector(0, r, reflectors[r].x, reflectors[r].y);
+       Laser.DownloadReflector(0, -1, 0, 0); // Let the NAV know that's all of 
them.
+       
+       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");
+ }
+ 
+ void SickNAV200::FetchReflectors()
+ {
+       PLAYER_MSG0(2, "Fetching reflectors from vectormap");
+       if (reflector_map)
+       {
+               bool gotReflectors = false;
+               
+               Message* mapInfoMessage = reflector_map->Request(this->InQueue, 
PLAYER_MSGTYPE_REQ, PLAYER_VECTORMAP_REQ_GET_MAP_INFO, NULL, 0, NULL);
+               if (mapInfoMessage->GetHeader()->type == 
PLAYER_MSGTYPE_RESP_ACK && mapInfoMessage->GetHeader()->subtype == 
PLAYER_VECTORMAP_REQ_GET_MAP_INFO)
+               {
+                       player_vectormap_info_t* mapInfo = 
reinterpret_cast<player_vectormap_info_t*>(mapInfoMessage->GetPayload());
+                       
+                       if (mapInfo->layers_count == 1)
+                       {
+                               player_vectormap_layer_info_t layer = 
mapInfo->layers[0];
+                               player_vectormap_layer_data_t request;
+                               memset(&request, 0, sizeof(request));
+                               request.name = layer.name;
+                               request.name_count = layer.name_count;
+                         
+                               Message* response = 
reflector_map->Request(this->InQueue, PLAYER_MSGTYPE_REQ, 
PLAYER_VECTORMAP_REQ_GET_LAYER_DATA, (void*)&request, 0, NULL);
+                               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;
+                               }
+                       }
+               }
+               
+               if (!gotReflectors)
+                       PLAYER_WARN("failed to get reflectors from 
vectormap\n");
+       }
+       else
+               PLAYER_WARN("no vectormap provided to fetch reflectors from\n");
+ }
+ 
  void SickNAV200::BuildWKB()
  {
        // Encode reflector positions in well known binary format for 
publishing.
        delete [] wkbData; // Clear old data.
!       wkbSize = wkbHeaderSize + wkbPointSize * numReflectors;
        wkbData = new uint8_t[wkbSize];
        wkbData[0] = 1; // Little endian (0 for big endian).
***************
*** 677,687 ****
        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;
        }
  }
--- 930,941 ----
        for (int i = 0; i < numReflectors; i++)
        {
!               uint8_t* pointData = wkbData + wkbHeaderSize + wkbPointSize * i;
!               pointData[0] = 1; // Still little endian.
                uint32_t wkbType = 1; // Point
!               *reinterpret_cast<uint32_t*>(pointData + 1) = wkbType;
                double x = reflectors[i].x / 1000.0; // mm to metres.
                double y = reflectors[i].y / 1000.0;
!               *reinterpret_cast<double*>(pointData + 5) = x;
!               *reinterpret_cast<double*>(pointData + 13) = y;
        }
  }


-------------------------------------------------------------------------
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