19 #define _USE_MATH_DEFINES
34 #define DEG2RAD M_PI/180.0
45 internal_status = HOKUYO_STATUS_NOT_READY;
46 info =
"Hokuyo Laser";
47 device_status = DEVICE_OK_STANBY;
51 bool br = config.
check(
"GENERAL");
54 yCError(LASERHOKUYO,
"cannot read 'GENERAL' section");
61 period = general_config.
check(
"Period",
Value(50),
"Period of the sampling thread").asInt32() / 1000.0;
63 if (general_config.
check(
"max_angle") ==
false) {
yCError(LASERHOKUYO) <<
"Missing max_angle param";
return false; }
64 if (general_config.
check(
"min_angle") ==
false) {
yCError(LASERHOKUYO) <<
"Missing min_angle param";
return false; }
68 start_position = general_config.
check(
"Start_Position",
Value(0),
"Start position").asInt32();
69 end_position = general_config.
check(
"End_Position",
Value(1080),
"End Position").asInt32();
71 error_codes = general_config.
check(
"Convert_Error_Codes",
Value(0),
"Substitute error codes with legal measurments").asInt32();
72 std::string s = general_config.
check(
"Laser_Mode",
Value(
"GD"),
"Laser Mode (GD/MD").asString();
74 if (general_config.
check(
"Measurement_Units"))
76 yCError(LASERHOKUYO) <<
"Deprecated parameter 'Measurement_Units'. Please Remove it from the configuration file.";
81 yCInfo(LASERHOKUYO,
"'error_codes' option enabled. Invalid samples will be substituted with out-of-range measurements.");
86 yCInfo(LASERHOKUYO,
"Using GD mode (single acquisition)");
91 yCInfo(LASERHOKUYO,
"Using MD mode (continuous acquisition)");
96 yCError(LASERHOKUYO,
"Laser_mode not found. Using GD mode (single acquisition)");
100 bool br2 = config.
check(
"SERIAL_PORT_CONFIGURATION");
103 yCError(LASERHOKUYO,
"cannot read 'SERIAL_PORT_CONFIGURATION' section");
107 string ss = serial_config.
toString();
110 prop.
put(
"device",
"serialport");
113 if (!driver.isValid())
115 yCError(LASERHOKUYO,
"Error opening PolyDriver check parameters");
120 driver.view(pSerial);
124 yCError(LASERHOKUYO,
"Error opening serial driver. Device not available");
136 pSerial->receive(b_ans);
139 yCInfo(LASERHOKUYO,
"URG device successfully initialized.");
144 yCError(LASERHOKUYO,
"Error: URG device not found.");
164 pSerial->receive(b_ans);
166 yCDebug(LASERHOKUYO,
"%s",ans.c_str());
174 pSerial->receive(b_ans);
176 yCDebug(LASERHOKUYO,
"%s", ans.c_str());
184 pSerial->receive(b_ans);
197 yCDebug(LASERHOKUYO,
"%s", ans.c_str());
200 found = ans.find(
"MODL");
201 if (found!=string::npos) sensor_properties.MODL = string(ans.c_str()+found+5);
202 found = ans.find(
"DMIN");
203 if (found!=string::npos) sensor_properties.DMIN = atoi(ans.c_str()+found+5);
204 found = ans.find(
"DMAX");
205 if (found!=string::npos) sensor_properties.DMAX = atoi(ans.c_str()+found+5);
206 found = ans.find(
"ARES");
207 if (found!=string::npos) sensor_properties.ARES = atoi(ans.c_str()+found+5);
208 found = ans.find(
"AMIN");
209 if (found!=string::npos) sensor_properties.AMIN = atoi(ans.c_str()+found+5);
210 found = ans.find(
"AMAX");
211 if (found!=string::npos) sensor_properties.AMAX = atoi(ans.c_str()+found+5);
212 found = ans.find(
"AFRT");
213 if (found!=string::npos) sensor_properties.AFRT = atoi(ans.c_str()+found+5);
214 found = ans.find(
"SCAN");
215 if (found!=string::npos) sensor_properties.SCAN = atoi(ans.c_str()+found+5);
223 pSerial->receive(b_ans);
232 laser_data.resize(sensorsNum);
234 if (laser_mode==MD_MODE)
238 std::snprintf(message, 255,
"MD%04d%04d%02d%01d%02d\n",start_position,end_position,1,1,0);
245 else if (laser_mode==GD_MODE)
249 std::snprintf(message, 255,
"GD%04d%04d%02d\n",start_position,end_position,1);
256 return PeriodicThread::start();
261 PeriodicThread::stop();
269 pSerial->receive(b_ans);
290 yCError(LASERHOKUYO,
"setDistanceRange NOT YET IMPLEMENTED");
304 yCError(LASERHOKUYO,
"setScanLimits NOT YET IMPLEMENTED");
316 yCError(LASERHOKUYO,
"setHorizontalResolution NOT YET IMPLEMENTED");
328 yCError(LASERHOKUYO,
"setScanRate NOT YET IMPLEMENTED");
334 if (internal_status != HOKUYO_STATUS_NOT_READY)
337 yCTrace(LASERHOKUYO,
"data: %s", laser_data.toString().c_str());
349 if (internal_status != HOKUYO_STATUS_NOT_READY)
352 yCTrace(LASERHOKUYO,
"data: %s", laser_data.toString().c_str());
353 size_t size = laser_data.size();
355 if (max_angle < min_angle)
357 yCError(LASERHOKUYO) <<
"getLaserMeasurement failed";
362 double laser_angle_of_view = max_angle - min_angle;
363 for (
size_t i = 0; i < size; i++)
365 double angle = (i / double(size)*laser_angle_of_view + min_angle)*
DEG2RAD;
366 data[i].set_polar(laser_data[i], angle);
379 status = device_status;
386 yCTrace(LASERHOKUYO,
"laserHokuyo:: thread initialising...");
387 yCTrace(LASERHOKUYO,
"... done!");
391 inline int laserHokuyo::calculateCheckSum(
const char*
buffer,
int size,
char actual_sum)
393 char expected_sum = 0x00;
396 for (i = 0; i < size; ++i)
398 expected_sum +=
buffer[i];
400 expected_sum = (expected_sum & 0x3f) + 0x30;
402 return (expected_sum == actual_sum) ? 0 : -1;
405 inline long laserHokuyo::decodeDataValue(
const char* data,
int data_byte)
408 for (
int i = 0; i < data_byte; ++i)
412 value |= data[i] - 0x30;
417 int laserHokuyo::readData(
const Laser_mode_type laser_mode,
const char* text_data,
const int text_data_len,
int current_line,
yarp::sig::Vector& data)
419 static char data_block [4000];
421 if (text_data_len==0)
423 return HOKUYO_STATUS_ERROR_NOTHING_RECEIVED;
429 if (text_data_len == 1 &&
430 text_data[0] ==
'\n')
433 int len = strlen(data_block);
434 for (
int value_counter =0; value_counter < len; value_counter+=3)
436 int value = decodeDataValue(data_block+value_counter, 3);
437 if (value<sensor_properties.DMIN && error_codes==1)
439 value=sensor_properties.DMAX;
444 return HOKUYO_STATUS_ACQUISITION_COMPLETE;
448 if (current_line == 0)
451 if ((laser_mode == MD_MODE && (text_data[0] !=
'M' || text_data[1] !=
'D')) ||
452 (laser_mode == GD_MODE && (text_data[0] !=
'G' || text_data[1] !=
'D')))
454 yCTrace(LASERHOKUYO,
"Invalid answer to a MD command: %s", text_data);
455 return HOKUYO_STATUS_ERROR_INVALID_COMMAND;
458 return HOKUYO_STATUS_OK;
462 if (current_line == 1)
464 if ((laser_mode == MD_MODE && (text_data[0] !=
'9' || text_data[1] !=
'9' || text_data[2] !=
'b' )) ||
465 (laser_mode == GD_MODE && (text_data[0] !=
'0' || text_data[1] !=
'0' || text_data[2] !=
'P' )))
467 yCTrace(LASERHOKUYO,
"Invalid sensor status: %s", text_data);
468 return HOKUYO_STATUS_ERROR_BUSY;
471 return HOKUYO_STATUS_OK;
475 if (current_line >= 2)
477 char expected_checksum = text_data[text_data_len - 2];
478 if (calculateCheckSum(text_data, text_data_len - 2, expected_checksum) < 0)
480 yCTrace(LASERHOKUYO,
"Checksum error, line: %d: %s", current_line, text_data);
481 return HOKUYO_STATUS_ERROR_INVALID_CHECKSUM;
486 if (current_line == 2)
492 if (current_line >= 3)
494 strncat (data_block, text_data, text_data_len-2 );
500 return HOKUYO_STATUS_OK;
508 constexpr
int buffer_size = 128;
509 char command [buffer_size];
510 char answer [buffer_size];
517 bool timeout =
false;
518 bool rx_completed =
false;
524 int answer_len = pSerial->receiveLine(answer, buffer_size);
525 internal_status = readData(laser_mode, answer,answer_len,current_line,data_vector);
526 if (internal_status < 0 && internal_status != HOKUYO_STATUS_ERROR_NOTHING_RECEIVED)
530 if (internal_status == HOKUYO_STATUS_OK)
534 if (internal_status == HOKUYO_STATUS_ACQUISITION_COMPLETE)
539 if (t2-t1>maxtime) timeout =
true;
541 while (rx_completed ==
false && timeout ==
false && error ==
false);
545 yCError(LASERHOKUYO,
"laserHokuyo Timeout!");
549 yCError(LASERHOKUYO,
"laserHokuyo Communication Error, internal status=%d",internal_status);
551 yCTrace(LASERHOKUYO,
"time: %.3f %.3f",t2-t1, t2-old);
558 laser_data=data_vector;
562 if (laser_mode==GD_MODE)
564 std::snprintf(command, buffer_size,
"GD%04d%04d%02d\n",start_position,end_position,1);
574 yCTrace(LASERHOKUYO,
"laserHokuyo Thread releasing...");
575 yCTrace(LASERHOKUYO,
"... done.");
582 this->mutex.unlock();
bool setScanRate(double rate) override
set the scan rate (scans per seconds)
bool getDeviceStatus(Device_status &status) override
get the device status
bool getLaserMeasurement(std::vector< LaserMeasurementData > &data) override
Get the device measurements.
void run() override
Loop function.
bool getScanRate(double &rate) override
get the scan rate (scans per seconds)
bool getScanLimits(double &min, double &max) override
get the scan angular range.
bool getDistanceRange(double &min, double &max) override
get the device detection range
void threadRelease() override
Release method.
bool setHorizontalResolution(double step) override
get the angular step between two measurments (if available)
bool threadInit() override
Initialization method.
bool close() override
Close the DeviceDriver.
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
bool setDistanceRange(double min, double max) override
set the device detection range.
bool getDeviceInfo(std::string &device_info) override
get the device hardware charactestics
bool setScanLimits(double min, double max) override
set the scan angular range.
bool getHorizontalResolution(double &step) override
get the angular step between two measurments.
bool getRawData(yarp::sig::Vector &data) override
Get the device measurements.
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.
void clear()
Empties the bottle of any objects it contains.
void addString(const char *str)
Places a string in the bottle, at the end of the list.
A class for storing options and configuration information.
void fromString(const std::string &txt, bool wipe=true)
Interprets a string as a list of properties.
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
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 double nowSystem()
static void delaySystem(double seconds)
A single value (typically within a Bottle).
virtual yarp::conf::float64_t asFloat64() const
Get 64-bit floating point value.
virtual std::string asString() const
Get string value.
void push_back(const T &elem)
Push a new element in the vector: size is changed.
#define yCInfo(component,...)
#define yCError(component,...)
#define yCTrace(component,...)
#define yCDebug(component,...)
#define YARP_LOG_COMPONENT(name,...)