19 #define _USE_MATH_DEFINES 
   42 #define DEG2RAD M_PI/180.0 
   49     maxsize = bufferSize + 1;
 
   52     elems = (
byte *)calloc(maxsize, 
sizeof(
byte));
 
   64     info = 
"Fake Laser device for test/debugging";
 
   65     device_status = DEVICE_OK_STANBY;
 
   74     bool br = config.
check(
"GENERAL");
 
   78         clip_max_enable = general_config.
check(
"clip_max");
 
   79         clip_min_enable = general_config.
check(
"clip_min");
 
   80         if (clip_max_enable) { max_distance = general_config.
find(
"clip_max").
asFloat64(); }
 
   81         if (clip_min_enable) { min_distance = general_config.
find(
"clip_min").
asFloat64(); }
 
   82         if (general_config.
check(
"max_angle") == 
false) { 
yCError(
RPLIDAR) << 
"Missing max_angle param"; 
return false; }
 
   83         if (general_config.
check(
"min_angle") == 
false) { 
yCError(
RPLIDAR) << 
"Missing min_angle param"; 
return false; }
 
   84         if (general_config.
check(
"resolution") == 
false) { 
yCError(
RPLIDAR) << 
"Missing resolution param"; 
return false; }
 
   88         do_not_clip_infinity_enable = (general_config.
find(
"allow_infinity").
asInt32()!=0);
 
   96     bool bs = config.
check(
"SKIP");
 
  102         size_t s_mins = mins.
size();
 
  103         size_t s_maxs = mins.
size();
 
  104         if (s_mins == s_maxs && s_maxs > 1 )
 
  106             for (
size_t s = 1; s < s_maxs; s++)
 
  111                 if (range.
max >= 0 && range.
max <= 360 &&
 
  112                     range.
min >= 0 && range.
min <= 360 &&
 
  115                     range_skip_vector.push_back(range);
 
  127     if (max_angle <= min_angle)            { 
yCError(
RPLIDAR) << 
"max_angle should be > min_angle";  
return false; }
 
  128     double fov = (max_angle - min_angle);
 
  129     if (fov >360)                          { 
yCError(
RPLIDAR) << 
"max_angle - min_angle <= 360";  
return false; }
 
  130     sensorsNum = (int)(fov/resolution);
 
  131     laser_data.resize(sensorsNum,0.0);
 
  134     yCInfo(
RPLIDAR, 
"max_dist %f, min_dist %f", max_distance, min_distance);
 
  135     yCInfo(
RPLIDAR, 
"max_angle %f, min_angle %f", max_angle, min_angle);
 
  140     bool ok = general_config.
check(
"Serial_Configuration");
 
  143         yCError(
RPLIDAR, 
"Cannot find configuration file for serial port communication!");
 
  146     std::string serial_filename = general_config.
find(
"Serial_Configuration").
asString();
 
  150     std::string serial_completefilename= rf.
findFileByName(serial_filename);
 
  152     prop.
put(
"device", 
"serialport");
 
  156         yCError(
RPLIDAR, 
"Unable to read from serial port configuration file");
 
  162     if (!driver.isValid())
 
  167     driver.view(pSerial);
 
  170         yCError(
RPLIDAR, 
"Error opening serial driver. Device not available");
 
  175     int cleanup = pSerial->flush();
 
  182     bool b_health = HW_getHealth();
 
  183     if (b_health == 
false)
 
  187         b_health = HW_getHealth();
 
  188         if (b_health == 
false)
 
  195             yCInfo(
RPLIDAR, 
"Sensor recovered from a previous error status");
 
  203     return PeriodicThread::start();
 
  208     PeriodicThread::stop();
 
  225     std::lock_guard<std::mutex> guard(mutex);
 
  233     std::lock_guard<std::mutex> guard(mutex);
 
  241     std::lock_guard<std::mutex> guard(mutex);
 
  249     std::lock_guard<std::mutex> guard(mutex);
 
  257     std::lock_guard<std::mutex> guard(mutex);
 
  264     std::lock_guard<std::mutex> guard(mutex);
 
  271     std::lock_guard<std::mutex> guard(mutex);
 
  278     std::lock_guard<std::mutex> guard(mutex);
 
  286     std::lock_guard<std::mutex> guard(mutex);
 
  294     std::lock_guard<std::mutex> guard(mutex);
 
  298     size_t size = laser_data.size();
 
  300     if (max_angle < min_angle) { 
yCError(
RPLIDAR) << 
"getLaserMeasurement failed"; 
return false; }
 
  301     double laser_angle_of_view = max_angle - min_angle;
 
  302     for (
size_t i = 0; i < size; i++)
 
  304         double angle = (i / double(size)*laser_angle_of_view + min_angle)* 
DEG2RAD;
 
  305         data[i].set_polar(laser_data[i], angle);
 
  312     std::lock_guard<std::mutex> guard(mutex);
 
  313     status = device_status;
 
  332 bool RpLidar::HW_getInfo(
string& s_info)
 
  335     unsigned char cmd_arr[2];
 
  338     pSerial->send((
char *)cmd_arr, 2);
 
  342     unsigned char s[255];
 
  343     r = pSerial->receiveBytes(s, 7);
 
  350     if ((
unsigned char)s[0] != 0xA5 || (
unsigned char)s[1] != 0x5A || (
unsigned char)s[2] != 0x14 || (
unsigned char)s[6] != 0x04)
 
  356     r = pSerial->receiveBytes(s, 20);
 
  363     sprintf(info, 
"model %d fw_major %d fw_minor %d hardware %d serial number %c%c%c%c%c %c%c%c%c%c %c%c%c%c%c%c",
 
  364                    s[0],  s[1],  s[2],  s[3],
 
  365                    s[4],  s[5],  s[6],  s[7],  s[8],
 
  366                    s[9],  s[10], s[11], s[12], s[13],
 
  367                    s[14], s[15], s[16], s[17], s[18], s[19]);
 
  372 bool RpLidar::HW_getHealth()
 
  377     unsigned char cmd_arr[2];
 
  380     pSerial->send((
char *)cmd_arr, 2);
 
  384     unsigned char s[255];
 
  386     r = pSerial->receiveBytes(s,7);
 
  393     if ((
unsigned char)s[0] != 0xA5 || (
unsigned char)s[1] != 0x5A || (
unsigned char)s[2] != 3 || (
unsigned char)s[6] != 0x06)
 
  400     r = pSerial->receiveBytes(s,3);
 
  408     int code = s[1] << 8 | s[2];
 
  413     else if (status == 1)
 
  418     else if (status == 2)
 
  427 bool RpLidar::HW_reset()
 
  431     unsigned char cmd_arr[2];
 
  434     pSerial->send((
char *)cmd_arr, 2);
 
  440 bool RpLidar::HW_start()
 
  446     unsigned char cmd_arr[2];
 
  453     pSerial->send((
char *)cmd_arr,2);
 
  457     unsigned char s[255];
 
  459     r = pSerial->receiveBytes(s, 7);
 
  466     if ((
unsigned char)s[0] != 0xA5 || (
unsigned char)s[1] != 0x5A || (
unsigned char)s[2] != 0x05 ||
 
  467         (
unsigned char)s[5] != 0x40 || (
unsigned char)s[6] != 0x81)
 
  476 bool RpLidar::HW_stop()
 
  480     unsigned char cmd_arr[2];
 
  483     pSerial->send((
char*)cmd_arr,2);
 
  489 #define DEBUG_LOCKING 1 
  496     const int packet = 100;
 
  497     std::lock_guard<std::mutex> guard(mutex);
 
  499     unsigned char buff[packet*3];
 
  500     memset(buff, 0, packet*3);
 
  503     static unsigned int total_r = 0;
 
  504     unsigned int count = 0;
 
  507         r = pSerial->receiveBytes(buff, packet);
 
  508 #ifdef DEBUG_BYTES_READ_1 
  511         buffer->write_elems(buff, r);
 
  514 #ifdef DEBUG_BYTES_READ_2 
  521     while (
buffer->size() < (packet * 2) || r < packet);
 
  523     unsigned char minibuff[15];
 
  524     unsigned int ok_count = 0;
 
  525     bool new_scan = 
false;
 
  528         buffer->select_elems(minibuff,15);
 
  530         int start = (minibuff[0]) & 0x01;
 
  531         int lock = (minibuff[0] >> 1) & 0x01;
 
  532         int check = (minibuff[1] & 0x01);
 
  534         int start_n1 = (minibuff[5]) & 0x01;
 
  535         int lock_n1 = (minibuff[5] >> 1) & 0x01;
 
  536         int start_n2 = (minibuff[10]) & 0x01;
 
  537         int lock_n2 = (minibuff[10] >> 1) & 0x01;
 
  538         int check_n1 = (minibuff[6] & 0x01);
 
  539         int check_n2 = (minibuff[11] & 0x01);
 
  541         int quality = (minibuff[0] >> 2);
 
  542         int i_angle = ((minibuff[2] >> 1) << 8) | (minibuff[1]);
 
  543         int i_distance = (minibuff[4] << 8) | (minibuff[3]); 
 
  548             yCError(
RPLIDAR) << 
"lock error 1 " << 
"previous ok" << ok_count << 
"total r" << total_r;
 
  550            buffer->throw_away_elem();
 
  556         if (start_n1 == lock_n1)
 
  559             yCError(
RPLIDAR) << 
"lock error 2 " << 
"previous ok" << ok_count << 
"total r" << total_r;
 
  561            buffer->throw_away_elem();
 
  567         if (start_n2 == lock_n2)
 
  570             yCError(
RPLIDAR) << 
"lock error 3 " << 
"previous ok" << ok_count << 
"total r" << total_r;
 
  572            buffer->throw_away_elem();
 
  578         if (start == 1 && start_n1 == 1)
 
  581             yCError(
RPLIDAR) << 
"lock error 4 " << 
"previous ok" << ok_count << 
"total r" << total_r;
 
  583             buffer->throw_away_elem();
 
  592             yCError(
RPLIDAR) << 
"checksum error 1" << 
"previous ok" << ok_count << 
"total r" << total_r;
 
  594              buffer->throw_away_elem();
 
  603             yCError(
RPLIDAR) << 
"checksum error 2" << 
"previous ok" << ok_count << 
"total r" << total_r;
 
  605             buffer->throw_away_elem();
 
  614             yCError(
RPLIDAR) << 
"checksum error 3" << 
"previous ok" << ok_count << 
"total r" << total_r;
 
  616             buffer->throw_away_elem();
 
  627         if (start == 1 && new_scan == 
false)
 
  632         else if (start == 1 && new_scan == 
true)
 
  638         double distance = i_distance / 4.0 / 1000; 
 
  639         double angle = i_angle / 64.0; 
 
  640         angle = (360 - angle) + 90;
 
  641         if (angle >= 360) angle -= 360;
 
  650             distance = std::numeric_limits<double>::infinity();
 
  659             if (distance < min_distance)
 
  660                 distance = max_distance;
 
  664             if (distance > max_distance)
 
  666                 if (!do_not_clip_infinity_enable && distance <= std::numeric_limits<double>::infinity())
 
  668                     distance = max_distance;
 
  673         for (
auto& i : range_skip_vector)
 
  675             if (angle > i.min && angle < i.max)
 
  677                 distance = std::numeric_limits<double>::infinity();
 
  704         buffer->throw_away_elems(5);
 
  706         int elem = (int)(angle / resolution);
 
  707         if (elem >= 0 && elem < (
int)laser_data.size())
 
  709             laser_data[elem] = distance;
 
  713             yCDebug(
RPLIDAR) << 
"RpLidar::run() invalid angle: elem" << elem << 
">" << 
"laser_data.size()" << laser_data.size();
 
  716     while (
buffer->size() > packet &&  isRunning() );
 
  737     std::lock_guard<std::mutex> guard(mutex);