⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sicklms200.cc

📁 机器人仿真软件
💻 CC
📖 第 1 页 / 共 3 页
字号:
                  resp_queue,                  PLAYER_MSGTYPE_RESP_ACK,                  PLAYER_LASER_REQ_SET_CONFIG,                  data, hdr->size, NULL);    // Return 0 to say that we handled this message    return(0);  }  else if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,                                 PLAYER_LASER_REQ_GET_CONFIG,                                 this->device_addr))  {    if(hdr->size != 0)    {      PLAYER_ERROR2("request is wrong length (%d != %d); ignoring",                    hdr->size, 0);      return(-1);    }    player_laser_config_t config;    config.intensity = this->intensity;    config.resolution = DTOR(this->scan_res)/100;    config.min_angle = DTOR(this->min_angle)/100;    config.max_angle = DTOR(this->max_angle)/100;    if(this->range_res == 1)      config.max_range = 8.0;    else if(this->range_res == 10)      config.max_range = 80.0;    else if(this->range_res == 100)      config.max_range = 150.0;    else    {      PLAYER_WARN("Invalid range_res!");      config.max_range = 8.0;    }    config.range_res = ((double)this->range_res)/1000.0;    this->Publish(this->device_addr,                  resp_queue,                  PLAYER_MSGTYPE_RESP_ACK,                  PLAYER_LASER_REQ_GET_CONFIG,                  (void*)&config, sizeof(config), NULL);    return(0);  }  else if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,                                 PLAYER_LASER_REQ_GET_GEOM,                                 this->device_addr))  {    if(hdr->size != 0)    {      PLAYER_ERROR2("request is wrong length (%d != %d); ignoring",                    hdr->size, 0);      return(PLAYER_MSGTYPE_RESP_NACK);    }    player_laser_geom_t geom;    geom.pose.px = this->pose[0];    geom.pose.py = this->pose[1];    geom.pose.pa = this->pose[2];    geom.size.sl = this->size[0];    geom.size.sw = this->size[1];    this->Publish(this->device_addr,                  resp_queue,                  PLAYER_MSGTYPE_RESP_ACK,                  PLAYER_LASER_REQ_GET_GEOM,                  (void*)&geom, sizeof(geom), NULL);    return(0);  }  // Don't know how to handle this message.  return(-1);}////////////////////////////////////////////////////////////////////////////////// Main function for device threadvoid SickLMS200::Main() {  int itmp;  float tmp;  bool first = true;    // Ask the laser to send data  if (RequestLaserData(this->scan_min_segment, this->scan_max_segment) != 0)  {    PLAYER_ERROR("laser not responding; exiting laser thread");    return;  }  while(true)  {    // test if we are supposed to cancel    pthread_testcancel();        ProcessMessages();     // Get the time at which we started reading    // This will be a pretty good estimate of when the phenomena occured    double time;    GlobalTime->GetTimeDouble(&time);        // Process incoming data    uint16_t mm_ranges[PLAYER_LASER_MAX_SAMPLES];    if (ReadLaserData(mm_ranges, PLAYER_LASER_MAX_SAMPLES) == 0)    {      player_laser_data_t data;      if (first)      {        PLAYER_MSG0(2, "receiving data");        first = false;      }            // Prepare packet      data.min_angle = DTOR((this->scan_min_segment *                              this->scan_res) / 1e2 - this->scan_width / 2.0);      data.max_angle = DTOR((this->scan_max_segment *                              this->scan_res) / 1e2  -                             this->scan_width / 2.0);      if(this->range_res == 1)        data.max_range = 8.0;      else if(this->range_res == 10)        data.max_range = 80.0;      else if(this->range_res == 100)        data.max_range = 150.0;      else      {        PLAYER_WARN("Invalid range_res!");        data.max_range = 8.0;      }      data.resolution = DTOR(this->scan_res / 1e2);      data.ranges_count = data.intensity_count =               this->scan_max_segment - this->scan_min_segment + 1;      for (int i = 0; i < this->scan_max_segment - this->scan_min_segment + 1; i++)      {        data.intensity[i] = ((mm_ranges[i] >> 13) & 0x0007);        data.ranges[i] =  (mm_ranges[i] & 0x1FFF)  * this->range_res / 1e3;      }      // if the laser is upside-down, reverse the data and intensity      // arrays, in place.  this could probably be made more efficient by      // burying it in a lower-level loop where the data is being read, but      // i can't be bothered to figure out where.      if(this->invert)      {        for (int i = 0;              i < (this->scan_max_segment - this->scan_min_segment + 1)/2;              i++)        {          tmp=data.ranges[i];          data.ranges[i]=data.ranges[this->scan_max_segment-this->scan_min_segment-i];          data.ranges[this->scan_max_segment-this->scan_min_segment-i] = tmp;          itmp=data.intensity[i];          data.intensity[i]=data.intensity[this->scan_max_segment-this->scan_min_segment-i];          data.intensity[this->scan_max_segment-this->scan_min_segment-i] = itmp;        }      }      data.id = this->scan_id++;            // Make data available      this->Publish(this->device_addr, NULL,                     PLAYER_MSGTYPE_DATA, PLAYER_LASER_DATA_SCAN,                    (void*)&data, sizeof(data), &time);    }  }}////////////////////////////////////////////////////////////////////////////////// Compute the start and end scan segments based on the current resolution and// scan angles.  Returns 0 if the configuration is valid.int SickLMS200::CheckScanConfig(){  if (this->scan_res == 25)  {    // For high res, drop the scan range down to 100 degrees.    // The angles must be interpreted differently too.    this->scan_width = 100;    this->scan_min_segment = (this->min_angle + 5000) / this->scan_res;    this->scan_max_segment = (this->max_angle + 5000) / this->scan_res;    if (this->scan_min_segment < 0)      this->scan_min_segment = 0;    if (this->scan_min_segment > 400)      this->scan_min_segment = 400;        if (this->scan_max_segment < 0)      this->scan_max_segment = 0;    if (this->scan_max_segment > 400)      this->scan_max_segment = 400;    return 0;  }  else if (this->scan_res == 50 || this->scan_res == 100)  {    this->scan_width = 180;    this->scan_min_segment = (this->min_angle + 9000) / this->scan_res;    this->scan_max_segment = (this->max_angle + 9000) / this->scan_res;        if (this->scan_min_segment < 0)      this->scan_min_segment = 0;    if (this->scan_min_segment > 360)      this->scan_min_segment = 360;    if (this->scan_max_segment < 0)      this->scan_max_segment = 0;    if (this->scan_max_segment > 360)      this->scan_max_segment = 360;    return 0;  }  if (!(this->range_res == 1 || this->range_res == 10 || this->range_res == 100))    return -1;    return 0;}////////////////////////////////////////////////////////////////////////////////// Open the terminal// Returns 0 on successint SickLMS200::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 SickLMS200::CloseTerm(){  /* REMOVE#ifdef HAVE_HI_SPEED_SERIAL  if (ioctl(this->laser_fd, TIOCSSERIAL, &this->old_serial) < 0) {    //RETURN_ERROR(1, "error trying to reset serial to old state");    PLAYER_WARN("ioctl() failed while trying to reset serial to old state");  }#endif  */  ::close(this->laser_fd);  return 0;}////////////////////////////////////////////////////////////////////////////////// Set the terminal speed// Valid values are 9600 and 38400// Returns 0 on success//int SickLMS200::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);  switch(speed)  {    case 9600:      //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, B9600 );      cfsetospeed( &term, B9600 );              if( tcsetattr( this->laser_fd, TCSAFLUSH, &term ) < 0 )        RETURN_ERROR(1, "unable to set device attributes");      break;    case 38400:      //PLAYER_MSG0(2, "terminal speed to 38400");      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;    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;}  ////////////////////////////////////////////////////////////////////////////////// Put the laser into configuration mode//int SickLMS200::SetLaserMode(){  int tries;  ssize_t len;  uint8_t packet[20];  for (tries = 0; tries < DEFAULT_LASER_RETRIES; tries++)  {    packet[0] = 0x20; /* mode change command */    packet[1] = 0x00; /* configuration mode */    packet[2] = 0x53; // S - the password     packet[3] = 0x49; // I    packet[4] = 0x43; // C    packet[5] = 0x4B; // K    packet[6] = 0x5F; // _    packet[7] = 0x4C; // L    packet[8] = 0x4D; // M    packet[9] = 0x53; // S    len = 10;      PLAYER_MSG0(2, "sending configuration mode request to laser");    if (WriteToLaser(packet, len) < 0)      return 1;    // Wait for laser to return ack    // This could take a while...    //    PLAYER_MSG0(2, "waiting for acknowledge");    len = ReadFromLaser(packet, sizeof(packet), true, 10000);    if (len < 0)      return 1;    else if (len < 1)    {      PLAYER_WARN("timeout");      continue;    }    else if (packet[0] == NACK)    {      PLAYER_ERROR("request denied by laser");      return 1;    }    else if (packet[0] != ACK)    {      PLAYER_ERROR("unexpected packet type");      return 1;    }    break;  }  return (tries >= DEFAULT_LASER_RETRIES);}////////////////////////////////////////////////////////////////////////////////// Set the laser data rate// Valid values are 9600 and 38400// Returns 0 on success//int SickLMS200::SetLaserSpeed(int speed){  int tries;  ssize_t len;  uint8_t packet[20];  for (tries = 0; tries < DEFAULT_LASER_RETRIES; tries++)  {    packet[0] = 0x20;    packet[1] = (speed == 9600 ? 0x42 : (speed == 38400 ? 0x40 : 0x48));    len = 2;    //PLAYER_MSG0(2, "sending baud rate request to laser");    if (WriteToLaser(packet, len) < 0)      return 1;                // Wait for laser to return ack    //PLAYER_MSG0(2, "waiting for acknowledge");    len = ReadFromLaser(packet, sizeof(packet), true, 20000);    if (len < 0)      return 1;    else if (len < 1)    {      PLAYER_ERROR("no reply from laser");      return 1;    }    else if (packet[0] == NACK)    {      PLAYER_ERROR("request denied by laser");      return 1;    }    else if (packet[0] != ACK)    {      PLAYER_ERROR("unexpected packet type");      return 1;          }    break;  }  return (tries >= DEFAULT_LASER_RETRIES);}////////////////////////////////////////////////////////////////////////////////// Get the laser type//int SickLMS200::GetLaserType(char *buffer, size_t bufflen){  int tries;  ssize_t len;  uint8_t packet[512];  for (tries = 0; tries < DEFAULT_LASER_RETRIES; tries++)  {    packet[0] = 0x3A;    len = 1;    //PLAYER_MSG0(2, "sending get type request to laser");    if (WriteToLaser(packet, len) < 0)      return 1;    // Wait for laser to return data    len = ReadFromLaser(packet, sizeof(packet), false, 10000);    if (len < 0)      return 1;    else if (len < 1)    {      PLAYER_WARN("timeout");      continue;    }    else if (packet[0] == NACK)    {      PLAYER_ERROR("request denied by laser");      return 1;    }    else if (packet[0] != 0xBA)    {      PLAYER_ERROR("unexpected packet type");      return 1;    }    // NULL terminate the return string    assert((size_t) len < sizeof(packet));    packet[len] = 0;    // Copy to buffer    assert(bufflen >= (size_t) len - 1);    strcpy(buffer, (char*) (packet + 1));    break;  }  return (tries >= DEFAULT_LASER_RETRIES);}////////////////////////////////////////////////////////////////////////////////// Set the laser configuration// Returns 0 on success//int SickLMS200::SetLaserConfig(bool intensity){  int tries;  ssize_t len;  uint8_t packet[512];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -