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

Modified Files:
        sicks3000.cc 
Log Message:
added serial stream opaque driver and modified s3000 and nav200 drivers to use 
it



Index: sicks3000.cc
===================================================================
RCS file: /cvsroot/playerstage/code/player/server/drivers/laser/sicks3000.cc,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** sicks3000.cc        1 Nov 2007 22:16:19 -0000       1.6
--- sicks3000.cc        6 Dec 2007 02:35:36 -0000       1.7
***************
*** 49,53 ****
  @par Requires
  
! - none
  
  @par Configuration requests
--- 49,53 ----
  @par Requires
  
! - opaque
  
  @par Configuration requests
***************
*** 58,71 ****
  @par Configuration file options
  
- - port (string)
-   - Default: "/dev/ttyS0"
-   - Serial port to which laser is attached.  If you are using a
-     USB/232 or USB/422 converter, this will be "/dev/ttyUSBx".
- 
- - transfer_rate (integer)
-   - Rate desired for data transfers, negotiated after connection
-   - Default: 38400
-   - Baud rate.  Valid values are 9600, 19200, 38400, 125k, 250k, 500k
- 
  - pose (length tuple)
    - Default: [0.0 0.0 0.0]
--- 58,61 ----
***************
*** 84,89 ****
--- 74,87 ----
    name "sicks3000"
    provides ["laser:0"]
+   requires ["opaque:0"]
+ )
+ 
+ driver
+ (
+   name "serialstream"
+   provides ["opaque:0]
    port "/dev/ttyS0"
  )
+ 
  @endverbatim
  
***************
*** 113,132 ****
  #include <arpa/inet.h> // for htons etc
  
- #undef HAVE_HI_SPEED_SERIAL
- #ifdef HAVE_LINUX_SERIAL_H
-   #ifndef DISABLE_HIGHSPEEDSICK
-     #include <linux/serial.h>
-     #define HAVE_HI_SPEED_SERIAL
-   #endif
- #endif
- 
  #include <libplayercore/playercore.h>
! #include <replace/replace.h>
  extern PlayerTime* GlobalTime;
  
! #define DEFAULT_LASER_PORT "/dev/ttyS0"
! #define DEFAULT_LASER_TRANSFER_RATE 38400
! 
! #define RX_BUFFER_SIZE 4096
  
  // The laser device class.
--- 111,119 ----
  #include <arpa/inet.h> // for htons etc
  
  #include <libplayercore/playercore.h>
! //#include <replace/replace.h>
  extern PlayerTime* GlobalTime;
  
! #define DEFAULT_RX_BUFFER_SIZE 4096
  
  // The laser device class.
***************
*** 151,175 ****
      virtual void Main();
  
-     // Open the terminal
-     // Returns 0 on success
-     int OpenTerm();
- 
-     // Close the terminal
-     // Returns 0 on success
-     int CloseTerm();
-     
-     // Set the terminal speed
-       // can be any value valid for the s3000
-     // Returns 0 on success
-     int ChangeTermSpeed(int speed);
- 
-     // Set the laser data rate
-     // Valid values are 9600 and 38400
-     // Returns 0 on success
-     int SetLaserSpeed(int speed);
- 
-     // Read range data from laser
-     int ReadLaserData();
- 
      // Process range data from laser
      int ProcessLaserData();
--- 138,141 ----
***************
*** 181,184 ****
--- 147,151 ----
      // Get the time (in ms)
      int64_t GetTime();
+     
  
    protected:
***************
*** 188,197 ****
      double size[2];
      
-     // Name of device used to communicate with the laser
-     const char *device_name;
-     
-     // laser device file descriptor
-     int laser_fd;           
- 
      // Scan width and resolution.
      int scan_width, scan_res;
--- 155,158 ----
***************
*** 204,225 ****
      // the values used by the laser.
      int scan_min_segment, scan_max_segment;
- 
-     // Range resolution (1 = 1mm, 10 = 1cm, 100 = 10cm).
-     int range_res;
- 
-     // Turn intensity data on/off
-     bool intensity;
- 
-     // Is the laser upside-down? (if so, we'll reverse the ordering of the
-     // readings)
-     int invert;
- 
-     bool can_do_hi_speed;
-     int connect_rate;  // Desired rate for first connection
-     int transfer_rate; // Desired rate for operation
-     int current_rate;  // Current rate
- 
-     int scan_id;
      
      // rx buffer
      uint8_t * rx_buffer;
--- 165,173 ----
      // the values used by the laser.
      int scan_min_segment, scan_max_segment;
      
+     // Opaque Driver info
+     Device *opaque;
+     player_devaddr_t opaque_id;
+ 
      // rx buffer
      uint8_t * rx_buffer;
***************
*** 230,238 ****
      player_laser_data_t data_packet;
      player_laser_config_t config_packet;
-     
- 
- #ifdef HAVE_HI_SPEED_SERIAL
-   struct serial_struct old_serial;
- #endif
  };
  
--- 178,181 ----
***************
*** 267,285 ****
      : Driver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN, 
PLAYER_LASER_CODE)
  {
    // allocate our recieve buffer
!   rx_buffer_size = RX_BUFFER_SIZE;
    rx_buffer = new uint8_t[rx_buffer_size];
    assert(rx_buffer);
    
    memset(&data_packet,0,sizeof(data_packet));
!   data_packet.min_angle = DTOR(-95);
!   data_packet.max_angle = DTOR(95);
!   data_packet.resolution = DTOR(0.25);
    data_packet.max_range = 49;
  
    memset(&config_packet,0,sizeof(config_packet));
!   config_packet.min_angle = DTOR(-95);
!   config_packet.max_angle = DTOR(95);
!   config_packet.resolution = DTOR(0.25);
    config_packet.max_range = 49;
    
--- 210,230 ----
      : Driver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN, 
PLAYER_LASER_CODE)
  {
+         
+   rx_count = 0;
    // allocate our recieve buffer
!   rx_buffer_size = cf->ReadInt(section, "buffer_size", 
DEFAULT_RX_BUFFER_SIZE);
    rx_buffer = new uint8_t[rx_buffer_size];
    assert(rx_buffer);
    
    memset(&data_packet,0,sizeof(data_packet));
!   data_packet.min_angle = DTOR(-135);
!   data_packet.max_angle = DTOR(135);
!   data_packet.resolution = DTOR(0.5);
    data_packet.max_range = 49;
  
    memset(&config_packet,0,sizeof(config_packet));
!   config_packet.min_angle = DTOR(-135);
!   config_packet.max_angle = DTOR(135);
!   config_packet.resolution = DTOR(0.5);
    config_packet.max_range = 49;
    
***************
*** 291,314 ****
    this->size[1] = 0.15;
  
!   // Serial port
!   this->device_name = cf->ReadString(section, "port", DEFAULT_LASER_PORT);
! 
!   // Serial rate
!   this->transfer_rate = cf->ReadInt(section, "transfer_rate", 
DEFAULT_LASER_TRANSFER_RATE);
!   this->current_rate = 0;
! 
! #ifdef HAVE_HI_SPEED_SERIAL
!   this->can_do_hi_speed = true;
! #else
!   this->can_do_hi_speed = false;
! #endif
! 
!   if (!this->can_do_hi_speed && this->transfer_rate > 38400)
    {
!     PLAYER_ERROR1("sicklms200: requested hi speed serial, but no support 
compiled in. Defaulting to %d bps.",
!                   DEFAULT_LASER_TRANSFER_RATE);
!     this->connect_rate = DEFAULT_LASER_TRANSFER_RATE;
    }
  
    return;
  }
--- 236,250 ----
    this->size[1] = 0.15;
  
!   this->opaque = NULL;
!   // Must have an opaque device
!   if (cf->ReadDeviceAddr(&this->opaque_id, section, "requires",
!                        PLAYER_OPAQUE_CODE, -1, NULL) != 0)
    {
!       puts ("No Opaque driver specified");
!     this->SetError(-1);    
!     return;
    }
  
+ 
    return;
  }
***************
*** 324,336 ****
  int SickS3000::Setup()
  {
!   PLAYER_MSG1(2, "Laser initialising (%s)", this->device_name);
!     
!   // Open the terminal
!   if (OpenTerm())
!     return 1;
! 
!   if (ChangeTermSpeed(this->transfer_rate))
    {
!     return 1;
    }
  
--- 260,282 ----
  int SickS3000::Setup()
  {
!   
!   PLAYER_MSG0(2, "Laser initialising");
!   // Subscribe to the opaque device.
!   if(Device::MatchDeviceAddress(this->opaque_id, this->device_addr))
    {
!     PLAYER_ERROR("attempt to subscribe to self");
!     return(-1);
!   }
!   
!   if(!(this->opaque = deviceTable->GetDevice(this->opaque_id)))
!   {
!     PLAYER_ERROR("unable to locate suitable opaque device");
!     return(-1);
!   }
!    
!   if(this->opaque->Subscribe(this->InQueue) != 0)
!   {
!     PLAYER_ERROR("unable to subscribe to opaque device");
!     return(-1);
    }
  
***************
*** 339,343 ****
    // Start the device thread
    StartThread();
! 
    return 0;
  }
--- 285,289 ----
    // Start the device thread
    StartThread();
!   
    return 0;
  }
***************
*** 351,356 ****
    StopThread();
  
!   CloseTerm();
! 
    PLAYER_MSG0(2, "laser shutdown");
    
--- 297,302 ----
    StopThread();
  
!   opaque->Unsubscribe(InQueue);
!   
    PLAYER_MSG0(2, "laser shutdown");
    
***************
*** 364,367 ****
--- 310,323 ----
                             void * data)
  {
+ 
+   if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA, 
PLAYER_OPAQUE_DATA_STATE, opaque_id))
+   {
+     player_opaque_data_t * recv = reinterpret_cast<player_opaque_data_t * > 
(data);
+     memmove(&rx_buffer[rx_count], recv->data, recv->data_count);
+     rx_count += recv->data_count;
+     ProcessLaserData();
+     return 0;
+   }
+   
    if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,
                                   PLAYER_LASER_REQ_GET_CONFIG,
***************
*** 394,398 ****
      return(0);
    }
- 
    // Don't know how to handle this message.
    return(-1);
--- 350,353 ----
***************
*** 405,408 ****
--- 360,366 ----
    for(;;)
    {
+       // Waits for the opaque driver to pass data onto this thread.
+       InQueue->Wait();
+       
      // test if we are supposed to cancel
      pthread_testcancel();
***************
*** 411,618 ****
      ProcessMessages();
      
!     // read data into our ring buffer and then process it
!     int ret = ReadLaserData();
!       if (ret < 0)
!       {
!               PLAYER_WARN("Error reading from S3000 device");
!       }
!       else if (ret > 0)
!       ProcessLaserData();
!   }
! }
! 
! 
! 
! 
////////////////////////////////////////////////////////////////////////////////
! // Open the terminal
! // Returns 0 on success
! int SickS3000::OpenTerm()
! {
!   this->laser_fd = ::open(this->device_name, O_RDWR | O_SYNC , S_IRUSR | 
S_IWUSR );
!   if (this->laser_fd < 0)
!   {
!     PLAYER_ERROR2("unable to open serial port [%s]; [%s]",
!                   (char*) this->device_name, strerror(errno));
!     return 1;
!   }
! 
!   // set the serial port speed to 9600 to match the laser
!   // later we can ramp the speed up to the SICK's 38K
!   //
!   struct termios term;
!   if( tcgetattr( this->laser_fd, &term ) < 0 )
!     RETURN_ERROR(1, "Unable to get serial port attributes");
!   
!   cfmakeraw( &term );
!   cfsetispeed( &term, B9600 );
!   cfsetospeed( &term, B9600 );
!   
!   if( tcsetattr( this->laser_fd, TCSAFLUSH, &term ) < 0 )
!     RETURN_ERROR(1, "Unable to set serial port attributes");
! 
!   // Make sure queue is empty
!   //
!   tcflush(this->laser_fd, TCIOFLUSH);
!     
!   return 0;
! }
! 
! 
! 
////////////////////////////////////////////////////////////////////////////////
! // Close the terminal
! // Returns 0 on success
! //
! int SickS3000::CloseTerm()
! {
!   ::close(this->laser_fd);
!   return 0;
! }
! 
! 
! 
////////////////////////////////////////////////////////////////////////////////
! // Set the terminal speed
! // Valid values are 9600 and 38400
! // Returns 0 on success
! //
! int SickS3000::ChangeTermSpeed(int speed)
! {
!   struct termios term;
! 
!   current_rate = speed;
! 
! #ifdef HAVE_HI_SPEED_SERIAL
!   struct serial_struct serial;
! 
!   // we should check and reset the AYSNC_SPD_CUST flag
!   // since if it's set and we request 38400, we're likely
!   // to get another baud rate instead (based on custom_divisor)
!   // this way even if the previous player doesn't reset the
!   // port correctly, we'll end up with the right speed we want
!   if (ioctl(this->laser_fd, TIOCGSERIAL, &serial) < 0) 
!   {
!     //RETURN_ERROR(1, "error on TIOCGSERIAL in beginning");
!     PLAYER_WARN("ioctl() failed while trying to get serial port info");
!   }
!   else
!   {
!     serial.flags &= ~ASYNC_SPD_CUST;
!     serial.custom_divisor = 0;
!     if (ioctl(this->laser_fd, TIOCSSERIAL, &serial) < 0) 
!     {
!       //RETURN_ERROR(1, "error on TIOCSSERIAL in beginning");
!       PLAYER_WARN("ioctl() failed while trying to set serial port info");
!     }
!   }
! #endif  
! 
!   //printf("LASER: change TERM speed: %d\n", speed);
! 
!   int term_speed;
!   switch(speed)
!   {
!     case 9600:
!               term_speed = B9600;
!               break;
!       case 19200:
!               term_speed = B19200;
!               break;
!       case 38400:
!               term_speed = B38400;
!               break;
!       default:
!               term_speed = speed;
!   }
! 
!   switch(term_speed)
!   {
!     case B9600:
!     case B19200:
!     case B38400:
!       //PLAYER_MSG0(2, "terminal speed to 9600");
!       if( tcgetattr( this->laser_fd, &term ) < 0 )
!         RETURN_ERROR(1, "unable to get device attributes");
!         
!       cfmakeraw( &term );
!         cfsetispeed( &term, term_speed );
!         cfsetospeed( &term, term_speed );
!         
!       if( tcsetattr( this->laser_fd, TCSAFLUSH, &term ) < 0 )
!         RETURN_ERROR(1, "unable to set device attributes");
!       break;
! 
!     case 500000:
!       //PLAYER_MSG0(2, "terminal speed to 500000");
! 
! #ifdef HAVE_HI_SPEED_SERIAL    
!       if (ioctl(this->laser_fd, TIOCGSERIAL, &this->old_serial) < 0) {
!         RETURN_ERROR(1, "error on TIOCGSERIAL ioctl");
!       }
!     
!       serial = this->old_serial;
!     
!       serial.flags |= ASYNC_SPD_CUST;
!       serial.custom_divisor = 48; // for FTDI USB/serial converter divisor is 
240/5
!     
!       if (ioctl(this->laser_fd, TIOCSSERIAL, &serial) < 0) {
!         RETURN_ERROR(1, "error on TIOCSSERIAL ioctl");
!       }
!     
! #else
!       fprintf(stderr, "sicklms200: Trying to change to 500kbps, but no 
support compiled in, defaulting to 38.4kbps.\n");
! #endif
! 
!       // even if we are doing 500kbps, we have to set the speed to 38400...
!       // the driver will know we want 500000 instead.
! 
!       if( tcgetattr( this->laser_fd, &term ) < 0 )
!         RETURN_ERROR(1, "unable to get device attributes");    
! 
!       cfmakeraw( &term );
!       cfsetispeed( &term, B38400 );
!       cfsetospeed( &term, B38400 );
!     
!       if( tcsetattr( this->laser_fd, TCSAFLUSH, &term ) < 0 )
!         RETURN_ERROR(1, "unable to set device attributes");
      
-       break;
-     default:
-       PLAYER_ERROR1("unknown speed %d", speed);
-   }
-   return 0;
- }
- 
- 
-   
- 
- 
- 
- 
////////////////////////////////////////////////////////////////////////////////
- // Read range data from laser
- //
- int SickS3000::ReadLaserData()
- {
-   if (rx_count == rx_buffer_size)
-   {
-     PLAYER_WARN("S3000 RX buffer full\n");
-     return 0; 
-   }
-   // Read a packet from the laser
-   //
-   //int len = ReadFromLaser(&rx_buffer[rx_count], rx_buffer_size - rx_count);
-   int len = read(this->laser_fd, &rx_buffer[rx_count], rx_buffer_size - 
rx_count);
-   if (len == 0)
-   {
-     PLAYER_MSG0(2, "empty packet");
-     return 0;
-   }
-   if (len < 0)
-   {
-     PLAYER_ERROR2("error reading form s3000: %d %s", errno, strerror(errno));
-     return -1;
    }
- 
-   rx_count += len;
-    
-   return len;
  }
  
--- 369,375 ----
      ProcessMessages();
      
!     //usleep(1000);
      
    }
  }
  
***************
*** 622,625 ****
--- 379,383 ----
    while(rx_count >= 22)
    {
+       
      // find our continuous data header
      unsigned int ii;
***************
*** 646,649 ****
--- 404,414 ----
      // through to the end of the packet including the checksum
      unsigned short size = 2*htons(*reinterpret_cast<unsigned short *> 
(&rx_buffer[6]));
+     //printf("size %d", size);
+     if (size > rx_buffer_size - 26)
+     {
+       PLAYER_WARN("Requested Size of data is larger than the buffer size");
+       memmove(rx_buffer, &rx_buffer[1], --rx_count);
+               return 0;
+     }
      
      // check if we have enough data yet
***************
*** 703,707 ****
      }
        
!     memmove(rx_buffer, &rx_buffer[size+4], size+4);
      rx_count -= (size + 4);
      continue;
--- 468,472 ----
      }
        
!     memmove(rx_buffer, &rx_buffer[size+4], rx_count - (size+4));
      rx_count -= (size + 4);
      continue;
***************
*** 756,791 ****
    return CRC_16;
  }
!            
!            
!            
! /*           
! 
////////////////////////////////////////////////////////////////////////////////
! // Create a CRC for the given packet
! //
! unsigned short SickS3000::CreateCRC(uint8_t* data, ssize_t len)
! {
!   uint16_t uCrc16;
!   uint8_t abData[2];
!   
!   uCrc16 = 0;
!   abData[0] = 0;
!   
!   while(len-- )
!   {
!     abData[1] = abData[0];
!     abData[0] = *data++;
!     
!     if( uCrc16 & 0x8000 )
!     {
!       uCrc16 = (uCrc16 & 0x7fff) << 1;
!       uCrc16 ^= CRC16_GEN_POL;
!     }
!     else
!     {    
!       uCrc16 <<= 1;
!     }
!     uCrc16 ^= MAKEUINT16(abData[0],abData[1]);
!   }
!   return (uCrc16); 
! }
! */
--- 521,524 ----
    return CRC_16;
  }
! 
! 


-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper
from Novell.  From the desktop to the data center, Linux is going
mainstream.  Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to