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

📄 sicklms200.cc

📁 机器人仿真软件
💻 CC
📖 第 1 页 / 共 3 页
字号:
  for (tries = 0; tries < DEFAULT_LASER_RETRIES; tries++)  {    packet[0] = 0x74;    len = 1;    //PLAYER_MSG0(2, "sending get configuration request to laser");    if (WriteToLaser(packet, len) < 0)      return 1;    // Wait for laser to return data    //PLAYER_MSG0(2, "waiting for reply");    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] != 0xF4)    {      PLAYER_ERROR("unexpected packet type");      return 1;    }    break;  }  if (tries >= DEFAULT_LASER_RETRIES)    return 1;    //PLAYER_MSG0(2, "get configuration request ok");  //PLAYER_TRACE1("laser units [%d]", (int) packet[7]);  for (tries = 0; tries < DEFAULT_LASER_RETRIES; tries++)  {    // Modify the configuration and send it back    packet[0] = 0x77;    // Return intensity in top 3 data bits    packet[6] = (intensity ? 0x01 : 0x00);     // Set the units for the range reading    if (this->range_res == 1)      packet[7] = 0x01;    else if (this->range_res == 10)      packet[7] = 0x00;    else if (this->range_res == 100)      packet[7] = 0x02;    else      packet[7] = 0x01;    //PLAYER_MSG0(2, "sending set configuration request to laser");    if (WriteToLaser(packet, len) < 0)      return 1;    // Wait for the change to "take"    //PLAYER_MSG0(2, "waiting for acknowledge");    len = ReadFromLaser(packet, sizeof(packet), false, 10000);    if (len < 0)      return 1;    else if (len < 1)    {      PLAYER_ERROR("timeout");      continue;    }    else if (packet[0] == NACK)    {      PLAYER_ERROR("request denied by laser");      return 1;    }    else if (packet[0] != 0xF7)    {      PLAYER_ERROR("unexpected packet type");      return 1;    }    //PLAYER_MSG0(2, "set configuration request ok");    break;  }  return (tries >= DEFAULT_LASER_RETRIES);}////////////////////////////////////////////////////////////////////////////////// Change the resolution of the laser// Valid widths are: 100, 180 (degrees)// Valid resolitions are: 25, 50, 100 (1/100 degree)//int SickLMS200::SetLaserRes(int width, int res){  int tries;  ssize_t len;  uint8_t packet[512];  for (tries = 0; tries < DEFAULT_LASER_RETRIES; tries++)  {    len = 0;    packet[len++] = 0x3B;    packet[len++] = (width & 0xFF);    packet[len++] = (width >> 8);    packet[len++] = (res & 0xFF);    packet[len++] = (res >> 8);    //PLAYER_MSG0(2, "sending set variant request to laser");    if (WriteToLaser(packet, len) < 0)      return 1;    // Wait for laser to return data    //PLAYER_MSG0(2, "waiting for reply");    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] != 0xBB)    {      PLAYER_ERROR("unexpected packet type");      return 1;    }    // See if the request was accepted    if (packet[1] == 0)    {      PLAYER_ERROR("variant request ignored");      return 1;    }        break;  }  return (tries >= DEFAULT_LASER_RETRIES);}////////////////////////////////////////////////////////////////////////////////// Request data from the laser// Returns 0 on success//int SickLMS200::RequestLaserData(int min_segment, int max_segment){  int tries;  ssize_t len;  uint8_t packet[20];  for (tries = 0; tries < DEFAULT_LASER_RETRIES; tries++)  {    len = 0;    packet[len++] = 0x20; /* mode change command */        if (min_segment == 0 && max_segment == 360)    {      // Use this for raw scan data...      //      packet[len++] = 0x24;    }    else    {              // Or use this for selected scan data...      //      int first = min_segment + 1;      int last = max_segment + 1;      packet[len++] = 0x27;      packet[len++] = (first & 0xFF);      packet[len++] = (first >> 8);      packet[len++] = (last & 0xFF);      packet[len++] = (last >> 8);    }    //PLAYER_MSG0(2, "sending scan data request to laser");    //printf("LASER: RLD: writing scan data\n");    if (WriteToLaser(packet, len) < 0)      return 1;    // Wait for laser to return ack    // This should be fairly prompt    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);}////////////////////////////////////////////////////////////////////////////////// Read range data from laser//int SickLMS200::ReadLaserData(uint16_t *data, size_t datalen){  uint8_t raw_data[1024];  // Read a packet from the laser  //  int len = ReadFromLaser(raw_data, sizeof(raw_data));  if (len == 0)  {    PLAYER_MSG0(2, "empty packet");    return 1;  }  // Process raw packets  //  if (raw_data[0] == 0xB0)  {    // Determine the number of values returned    //    //int units = raw_data[2] >> 6;    int count = (int) raw_data[1] | ((int) (raw_data[2] & 0x3F) << 8);    assert((size_t) count <= datalen);    // Strip the status info and shift everything down a few bytes    // to remove packet header.    //    for (int i = 0; i < count; i++)    {      int src = 2 * i + 3;      data[i] = raw_data[src + 0] | (raw_data[src + 1] << 8);    }  }  else if (raw_data[0] == 0xB7)  {    // Determine which values were returned    //    //int first = ((int) raw_data[1] | ((int) raw_data[2] << 8)) - 1;    //int last =  ((int) raw_data[3] | ((int) raw_data[4] << 8)) - 1;            // Determine the number of values returned    //    //int units = raw_data[6] >> 6;    int count = (int) raw_data[5] | ((int) (raw_data[6] & 0x3F) << 8);    assert((size_t) count <= datalen);    // Strip the status info and shift everything down a few bytes    // to remove packet header.    //    for (int i = 0; i < count; i++)    {      int src = 2 * i + 7;      data[i] = raw_data[src + 0] | (raw_data[src + 1] << 8);    }  }  else    RETURN_ERROR(1, "unexpected packet type");    return 0;}////////////////////////////////////////////////////////////////////////////////// Write a packet to the laser//ssize_t SickLMS200::WriteToLaser(uint8_t *data, ssize_t len){  uint8_t buffer[4 + 1024 + 2];  assert(4 + len + 2 < (ssize_t) sizeof(buffer));  // Create header  //  buffer[0] = STX;  buffer[1] = 0;  buffer[2] = LOBYTE(len);  buffer[3] = HIBYTE(len);  // Copy body  //  memcpy(buffer + 4, data, len);  // Create footer (CRC)  //  uint16_t crc = CreateCRC(buffer, 4 + len);  buffer[4 + len + 0] = LOBYTE(crc);  buffer[4 + len + 1] = HIBYTE(crc);  // Make sure both input and output queues are empty  //  tcflush(this->laser_fd, TCIOFLUSH);  ssize_t bytes = 0;#ifdef HAVE_HI_SPEED_SERIAL  struct timeval start, end;  // have to write one char at a time, because if we're  // high speed, then must take no longer than 55 us between  // chars  int ret;  if (current_rate > 38400) {    //printf("LASER: writing %d bytes\n", 6+len);    for (int i =0; i < 6 + len; i++) {      do {        gettimeofday(&start, NULL);        ret = ::write(this->laser_fd, buffer + i, 1);      } while (!ret);      if (ret > 0) {        bytes += ret;      }      // need to do this sort of busy wait to ensure the right timing      // although I've noticed you will get some anamolies that are      // in the ms range; this could be a problem...      int usecs;       do {        gettimeofday(&end, NULL);        usecs= (end.tv_sec - start.tv_sec)*1000000 +          (end.tv_usec - start.tv_usec);      } while (usecs < 60);      //printf("usecs: %d bytes=%02X\n", (end.tv_sec - start.tv_sec)*1000000 +      //     (end.tv_usec - start.tv_usec), *(buffer + i));          }  } else {    bytes = ::write( this->laser_fd, buffer, 4 + len + 2);  }#else      // Write the data to the port  //  bytes = ::write( this->laser_fd, buffer, 4 + len + 2);#endif  // Make sure the queue is drained  // Synchronous IO doesnt always work  //  ::tcdrain(this->laser_fd);      // Return the actual number of bytes sent, including header and footer  //  return bytes;}////////////////////////////////////////////////////////////////////////////////// Read a packet from the laser// Set ack to true to ignore all packets except ack and nack// Set timeout to -1 to make this blocking, otherwise it will return in timeout ms.// Returns the packet length (0 if timeout occurs)//ssize_t SickLMS200::ReadFromLaser(uint8_t *data, ssize_t maxlen, bool ack, int timeout){  // If the timeout is infinite,  // go to blocking io  //  if (timeout < 0)  {    //PLAYER_MSG0(2, "using blocking io");    int flags = ::fcntl(this->laser_fd, F_GETFL);    if (flags < 0)    {      PLAYER_ERROR("unable to get device flags");      return 0;    }    if (::fcntl(this->laser_fd, F_SETFL, flags & (~O_NONBLOCK)) < 0)    {      PLAYER_ERROR("unable to set device flags");      return 0;    }  }  //  // Otherwise, use non-blocking io  //  else  {    //PLAYER_MSG0(2, "using non-blocking io");    int flags = ::fcntl(this->laser_fd, F_GETFL);    if (flags < 0)    {      PLAYER_ERROR("unable to get device flags");      return 0;    }    if (::fcntl(this->laser_fd, F_SETFL, flags | O_NONBLOCK) < 0)    {      PLAYER_ERROR("unable to set device flags");      return 0;    }  }  int64_t start_time = GetTime();  int64_t stop_time = start_time + timeout;  //PLAYER_MSG2(2, "%Ld %Ld", start_time, stop_time);  int bytes = 0;  uint8_t header[5] = {0};  uint8_t footer[3];      // Read until we get a valid header  // or we timeout  //  while (true)  {    if (timeout >= 0)      usleep(1000);    //printf("reading %d\n", timeout); fflush(stdout);    bytes = ::read(this->laser_fd, header + sizeof(header) - 1, 1);    //printf("bytes read %d\n", bytes); fflush(stdout);        if (header[0] == STX && header[1] == 0x80)    {      if (!ack)        break;      if (header[4] == ACK || header[4] == NACK)        break;    }    memmove(header, header + 1, sizeof(header) - 1);    if (timeout >= 0 && GetTime() >= stop_time)    {      //PLAYER_MSG2(2, "%Ld %Ld", GetTime(), stop_time);      //PLAYER_MSG0(2, "timeout on read (1)");      return 0;    }  }  // Determine data length  // Includes status, but not CRC, so subtract status to get data packet length.  //  ssize_t len = ((int) header[2] | ((int) header[3] << 8)) - 1;      // Check for buffer overflows  //  if (len > maxlen)    RETURN_ERROR(0, "buffer overflow (len > max_len)");  // Read in the data  // Note that we smooge the packet type from the header  // onto the front of the data buffer.  //  bytes = 0;  data[bytes++] = header[4];  while (bytes < len)  {    if (timeout >= 0)      usleep(1000);    bytes += ::read(this->laser_fd, data + bytes, len - bytes);    if (timeout >= 0 && GetTime() >= stop_time)    {      //PLAYER_MSG2(2, "%Ld %Ld", GetTime(), stop_time);      RETURN_ERROR(0, "timeout on read (3)");    }  }  // Read in footer  //  bytes = 0;  while (bytes < 3)  {    if (timeout >= 0)      usleep(1000);    bytes += ::read(this->laser_fd, footer + bytes, 3 - bytes);    if (timeout >= 0 && GetTime() >= stop_time)    {      //PLAYER_MSG2(2, "%Ld %Ld", GetTime(), stop_time);      RETURN_ERROR(0, "timeout on read (4)");    }  }      // Construct entire packet  // And check the CRC  //  uint8_t buffer[4 + 1024 + 1];  assert(4 + len + 1 < (ssize_t) sizeof(buffer));  memcpy(buffer, header, 4);  memcpy(buffer + 4, data, len);  memcpy(buffer + 4 + len, footer, 1);  uint16_t crc = CreateCRC(buffer, 4 + len + 1);  if (crc != MAKEUINT16(footer[1], footer[2]))    RETURN_ERROR(0, "CRC error, ignoring packet");      return len;}           ////////////////////////////////////////////////////////////////////////////////// Create a CRC for the given packet//unsigned short SickLMS200::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); }////////////////////////////////////////////////////////////////////////////////// Get the time (in ms)//int64_t SickLMS200::GetTime(){  struct timeval tv;  //gettimeofday(&tv, NULL);  GlobalTime->GetTime(&tv);  return (int64_t) tv.tv_sec * 1000 + (int64_t) tv.tv_usec / 1000;}

⌨️ 快捷键说明

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