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();