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);
void run() override
Loop function.
bool getDistanceRange(double &min, double &max) override
get the device detection range
bool close() override
Close the DeviceDriver.
bool threadInit() override
Initialization method.
bool getRawData(yarp::sig::Vector &data) override
Get the device measurements.
bool getHorizontalResolution(double &step) override
get the angular step between two measurments.
bool getScanRate(double &rate) override
get the scan rate (scans per seconds)
void threadRelease() override
Release method.
bool getDeviceInfo(std::string &device_info) override
get the device hardware charactestics
bool setScanRate(double rate) override
set the scan rate (scans per seconds)
bool setScanLimits(double min, double max) override
set the scan angular range.
bool setDistanceRange(double min, double max) override
set the device detection range.
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
bool getScanLimits(double &min, double &max) override
get the scan angular range.
bool getLaserMeasurement(std::vector< LaserMeasurementData > &data) override
Get the device measurements.
bool getDeviceStatus(Device_status &status) override
get the device status
bool setHorizontalResolution(double step) override
get the angular step between two measurments (if available)
A simple collection of objects that can be described and transmitted in a portable way.
size_type size() const
Gets the number of elements in the bottle.
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
A class for storing options and configuration information.
bool fromConfigFile(const std::string &fname, bool wipe=true)
Interprets a file as a list of properties.
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
Helper class for finding config files and other external resources.
std::string findFileByName(const std::string &name)
Find the full path to a file.
A base class for nested structures that can be searched.
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
virtual std::string toString() const =0
Return a standard text representation of the content of the object.
virtual Bottle & findGroup(const std::string &key) const =0
Gets a list corresponding to a given keyword.
static void delaySystem(double seconds)
virtual yarp::conf::float64_t asFloat64() const
Get 64-bit floating point value.
virtual std::int32_t asInt32() const
Get 32-bit integer value.
virtual std::string asString() const
Get string value.
#define yCInfo(component,...)
#define yCError(component,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
#define YARP_LOG_COMPONENT(name,...)
double now()
Return the current time in seconds, relative to an arbitrary starting point.
const yarp::os::LogComponent & RPLIDAR()