sick_generic_parser.cpp
Go to the documentation of this file.
1 
50 #ifdef _MSC_VER
51 #pragma warning(disable: 4267)
52 #endif
53 
54 #define _CRT_SECURE_NO_WARNINGS
55 #define _USE_MATH_DEFINES
56 #include <math.h>
58 #include <ros/ros.h>
59 
60 #ifdef _MSC_VER
61 #include "sick_scan/rosconsole_simu.hpp"
62 #endif
63 
64 namespace sick_scan
65 {
66 
73  void ScannerBasicParam::setScannerName(std::string _s)
74  {
75  scannerName = _s;
76  }
77 
85  {
86  return(scannerName);
87  }
88 
89 
97  {
98  numberOfLayers = _layerNum;
99  }
100 
108  {
109  return(numberOfLayers);
110 
111  }
112 
120  {
121  numberOfShots = _shots;
122  }
123 
131  {
132  return(numberOfShots);
133  }
134 
142  {
143  this->numberOfMaximumEchos = _maxEchos;
144  }
145 
146 
154  {
155  return(numberOfMaximumEchos);
156  }
157 
165  {
166  currentParamSet = _ptr;
167  }
168 
169 
176  {
177  angleDegressResolution = _res;
178  }
179 
186  {
187  return(angleDegressResolution);
188  }
189 
196  {
197  expectedFrequency = _freq;
198  }
199 
207  {
208  return(expectedFrequency);
209  }
210 
211 
218  {
219  this->elevationDegreeResolution = _elevRes;
220  }
221 
222 
229  {
230  return(this->elevationDegreeResolution);
231  }
232 
239  {
240  this->useBinaryProtocol = _useBinary;
241  }
242 
248  void ScannerBasicParam::setDeviceIsRadar(bool _deviceIsRadar)
249  {
250  deviceIsRadar = _deviceIsRadar;
251  }
252 
259  {
260  return(deviceIsRadar);
261  }
262 
269  {
270  return(this->useBinaryProtocol);
271  }
277  void ScannerBasicParam::setIntensityResolutionIs16Bit(bool _IntensityResolutionIs16Bit)
278  {
279  this->IntensityResolutionIs16Bit = _IntensityResolutionIs16Bit;
280  }
281 
288  {
290  }
291 
292 
293 
299  {
300  this->elevationDegreeResolution = 0.0;
301  this->setUseBinaryProtocol(false);
302  }
303 
309  SickGenericParser::SickGenericParser(std::string _scanType) :
310  AbstractParser(),
311  override_range_min_((float)0.05),
312  override_range_max_((float)100.0),
313  override_time_increment_((float)-1.0)
314  {
315  setScannerType(_scanType);
323  allowedScannerNames.push_back(SICK_SCANNER_RMS_3XX_NAME); // Radar scanner
324  basicParams.resize(allowedScannerNames.size()); // resize to number of supported scanner types
325  for (int i = 0; i < basicParams.size(); i++) // set specific parameter for each scanner type - scanner type is identified by name
326  {
327  basicParams[i].setDeviceIsRadar(false); // Default
328  basicParams[i].setScannerName(allowedScannerNames[i]); // set scanner type for this parameter object
329 
330  if (basicParams[i].getScannerName().compare(SICK_SCANNER_MRS_1XXX_NAME) == 0) // MRS1000 - 4 layer, 1101 shots per scan
331  {
332  basicParams[i].setNumberOfMaximumEchos(3);
333  basicParams[i].setNumberOfLayers(4);
334  basicParams[i].setNumberOfShots(1101);
335  basicParams[i].setAngularDegreeResolution(0.25);
336  basicParams[i].setElevationDegreeResolution(2.5); // in [degree]
337  basicParams[i].setExpectedFrequency(50.0);
338  basicParams[i].setUseBinaryProtocol(true);
339  basicParams[i].setDeviceIsRadar(false); // Default
340  }
341  if (basicParams[i].getScannerName().compare(SICK_SCANNER_LMS_1XXX_NAME) == 0) // LMS1000 - 4 layer, 1101 shots per scan
342  {
343  basicParams[i].setNumberOfMaximumEchos(3);
344  basicParams[i].setNumberOfLayers(4);
345  basicParams[i].setNumberOfShots(1101);
346  basicParams[i].setAngularDegreeResolution(1.00); // 0.25° wurde nicht unterstuetzt. (SFA 4)
347  basicParams[i].setElevationDegreeResolution(0.0); // in [degree]
348  basicParams[i].setExpectedFrequency(50.0);
349  basicParams[i].setUseBinaryProtocol(true);
350  basicParams[i].setDeviceIsRadar(false); // Default
351  }
352  if (basicParams[i].getScannerName().compare(SICK_SCANNER_TIM_5XX_NAME) == 0) // TIM_5xx - 1 Layer, max. 811 shots per scan
353  {
354  basicParams[i].setNumberOfMaximumEchos(1);
355  basicParams[i].setNumberOfLayers(1);
356  basicParams[i].setNumberOfShots(811);
357  basicParams[i].setAngularDegreeResolution(0.3333);
358  basicParams[i].setExpectedFrequency(15.0);
359  basicParams[i].setUseBinaryProtocol(true);
360  basicParams[i].setDeviceIsRadar(false); // Default
361  }
362  if (basicParams[i].getScannerName().compare(SICK_SCANNER_TIM_7XX_NAME) == 0) // TIM_5xx - 1 Layer, max. 811 shots per scan
363  {
364  basicParams[i].setNumberOfMaximumEchos(1);
365  basicParams[i].setNumberOfLayers(1);
366  basicParams[i].setNumberOfShots(811);
367  basicParams[i].setAngularDegreeResolution(0.3333);
368  basicParams[i].setExpectedFrequency(15.0);
369  basicParams[i].setUseBinaryProtocol(true);
370  basicParams[i].setDeviceIsRadar(false); // Default
371  }
372  if (basicParams[i].getScannerName().compare(SICK_SCANNER_LMS_5XX_NAME) == 0) // LMS_5xx - 1 Layer
373  {
374  basicParams[i].setNumberOfMaximumEchos(1);
375  basicParams[i].setNumberOfLayers(1);
376  basicParams[i].setNumberOfShots(381);
377  basicParams[i].setAngularDegreeResolution(0.5);
378  basicParams[i].setExpectedFrequency(15.0);
379  basicParams[i].setUseBinaryProtocol(true);
380  basicParams[i].setDeviceIsRadar(false); // Default
381  }
382  if (basicParams[i].getScannerName().compare(SICK_SCANNER_LMS_1XX_NAME) == 0) // LMS_1xx - 1 Layer
383  {
384  basicParams[i].setNumberOfMaximumEchos(1);
385  basicParams[i].setNumberOfLayers(1);
386  basicParams[i].setNumberOfShots(1141);
387  basicParams[i].setAngularDegreeResolution(0.5);
388  basicParams[i].setExpectedFrequency(25.0);
389  basicParams[i].setUseBinaryProtocol(true);
390  basicParams[i].setDeviceIsRadar(false); // Default
391  }
392  if (basicParams[i].getScannerName().compare(SICK_SCANNER_MRS_6XXX_NAME) == 0) //
393  {
394  basicParams[i].setNumberOfMaximumEchos(5);
395  basicParams[i].setNumberOfLayers(24);
396  basicParams[i].setNumberOfShots(925);
397  basicParams[i].setAngularDegreeResolution(0.13);
398  basicParams[i].setElevationDegreeResolution(1.25); // in [degree]
399  basicParams[i].setExpectedFrequency(50.0);
400  basicParams[i].setUseBinaryProtocol(true);
401  basicParams[i].setDeviceIsRadar(false); // Default
402  }
403 
404  if (basicParams[i].getScannerName().compare(SICK_SCANNER_RMS_3XX_NAME) == 0) // Radar
405  {
406  basicParams[i].setNumberOfMaximumEchos(1);
407  basicParams[i].setNumberOfLayers(0); // for radar scanner
408  basicParams[i].setNumberOfShots(65);
409  basicParams[i].setAngularDegreeResolution(0.00);
410  basicParams[i].setElevationDegreeResolution(0.00); // in [degree]
411  basicParams[i].setExpectedFrequency(0.00);
412  basicParams[i].setUseBinaryProtocol(false); // use ASCII-Protocol
413  basicParams[i].setDeviceIsRadar(true); // Device is a radar
414 
415  }
416 
417  }
418 
419  int scannerIdx = lookUpForAllowedScanner(scannerType);
420  if (scannerIdx == -1) // find index of parameter set - derived from scanner type name
421  {
422  ROS_ERROR("Scanner not supported.\n");
423  throw new std::string("scanner type " + scannerType + " not supported.");
424  }
425  else
426  {
427  currentParamSet = &(basicParams[scannerIdx]);
428  }
429  }
430 
436  {
437  return(currentParamSet);
438  }
439 
445  int SickGenericParser::lookUpForAllowedScanner(std::string scannerName)
446  {
447  int iRet = -1;
448  for (int i = 0; i < allowedScannerNames.size(); i++)
449  {
450  if (allowedScannerNames[i].compare(scannerName) == 0)
451  {
452  return(i);
453  }
454  }
455 
456  return(iRet);
457  }
458 
464  {
465  }
466 
480  int SickGenericParser::checkForDistAndRSSI(std::vector<char *>& fields, int expected_number_of_data, int& distNum, int& rssiNum, std::vector<float>& distVal, std::vector<float>& rssiVal, int& distMask)
481  {
482  int iRet = ExitSuccess;
483  distNum = 0;
484  rssiNum = 0;
485  int baseOffset = 20;
486 
487  distMask = 0;
488  // More in depth checks: check data length and RSSI availability
489  // 25: Number of data (<= 10F)
490  unsigned short int number_of_data = 0;
491  if (strstr(fields[baseOffset], "DIST") != fields[baseOffset]) // First initial check
492  {
493  ROS_WARN("Field 20 of received data does not start with DIST (is: %s). Unexpected data, ignoring scan", fields[20]);
494  return ExitError;
495  }
496 
497  int offset = 20;
498  do
499  {
500  bool distFnd = false;
501  bool rssiFnd = false;
502  if (strlen(fields[offset]) == 5)
503  {
504  if (strstr(fields[offset], "DIST") == fields[offset])
505  {
506  distFnd = true;
507  distNum++;
508  int distId = -1;
509  if (1 == sscanf(fields[offset], "DIST%d", &distId))
510  {
511  distMask |= (1 << (distId - 1)); // set bit regarding to id
512  }
513  }
514  if (strstr(fields[offset], "RSSI") == fields[offset])
515  {
516  rssiNum++;
517  rssiFnd = true;
518  }
519  }
520  if (rssiFnd || distFnd)
521  {
522  offset += 5;
523  if (offset >= fields.size())
524  {
525  ROS_WARN("Missing RSSI or DIST data");
526  return ExitError;
527  }
528  number_of_data = 0;
529  sscanf(fields[offset], "%hx", &number_of_data);
530  if (number_of_data != expected_number_of_data)
531  {
532  ROS_WARN("number of dist or rssi values mismatching.");
533  return ExitError;
534  }
535  offset++;
536  // Here is the first value
537  for (int i = 0; i < number_of_data; i++)
538  {
539  if (distFnd)
540  {
541  unsigned short iRange;
542  float range;
543  sscanf(fields[offset + i], "%hx", &iRange);
544  range = iRange / 1000.0;
545  distVal.push_back(range);
546  }
547  else
548  {
549  unsigned short iRSSI;
550  sscanf(fields[offset + i], "%hx", &iRSSI);
551  rssiVal.push_back((float)iRSSI);
552  }
553  }
554  offset += number_of_data;
555  }
556  else
557  {
558  offset++; // necessary????
559  }
560  } while (offset < fields.size());
561 
562  return(iRet);
563  }
564 
565 
566  void SickGenericParser::checkScanTiming(float time_increment, float scan_time, float angle_increment, float tol)
567  {
568  if (this->getCurrentParamPtr()->getNumberOfLayers() > 1)
569  {
570  return;
571  }
572 
573  float expected_time_increment = this->getCurrentParamPtr()->getNumberOfLayers() * scan_time * angle_increment / (2.0 * M_PI);
574  if (fabs(expected_time_increment - time_increment) > 0.00001)
575  {
576  ROS_WARN_THROTTLE(60, "The time_increment, scan_time and angle_increment values reported by the scanner are inconsistent! "
577  "Expected time_increment: %.9f, reported time_increment: %.9f. "
578  "Perhaps you should set the parameter time_increment to the expected value. This message will print every 60 seconds.",
579  expected_time_increment, time_increment);
580  }
581  };
582 
583 
584 
595  int SickGenericParser::parse_datagram(char* datagram, size_t datagram_length, SickScanConfig &config,
596  sensor_msgs::LaserScan &msg, int &numEchos, int &echoMask)
597  {
598  // echoMask introduced to get a workaround for cfg bug using MRS1104
599  ros::NodeHandle tmpParam("~");
600  bool dumpData = false;
601  int verboseLevel = 0;
602  tmpParam.getParam("verboseLevel", verboseLevel);
603 
604  int HEADER_FIELDS = 32;
605  char* cur_field;
606  size_t count;
607  int scannerIdx = lookUpForAllowedScanner(getScannerType());
608 
609  // Reserve sufficient space
610  std::vector<char *> fields;
611  fields.reserve(datagram_length / 2);
612 
613  // ----- only for debug output
614  std::vector<char> datagram_copy_vec;
615  datagram_copy_vec.resize(datagram_length + 1); // to avoid using malloc. destructor frees allocated mem.
616  char* datagram_copy = &(datagram_copy_vec[0]);
617 
618  if (verboseLevel > 0) {
619  ROS_WARN("Verbose LEVEL activated. Only for DEBUG.");
620  }
621 
622  if (verboseLevel > 0)
623  {
624  static int cnt = 0;
625  char szDumpFileName[255] = {0};
626  char szDir[255] = {0};
627 #ifdef _MSC_VER
628  strcpy(szDir,"C:\\temp\\");
629 #else
630  strcpy(szDir,"/tmp/");
631 #endif
632  sprintf(szDumpFileName,"%stmp%06d.bin", szDir, cnt);
633  bool isBinary = this->getCurrentParamPtr()->getUseBinaryProtocol();
634  if (isBinary)
635  {
636  FILE *ftmp;
637  ftmp = fopen(szDumpFileName,"wb");
638  if (ftmp != NULL)
639  {
640  fwrite(datagram, datagram_length, 1, ftmp);
641  fclose(ftmp);
642  }
643  }
644  cnt++;
645  }
646 
647  strncpy(datagram_copy, datagram, datagram_length); // datagram will be changed by strtok
648  datagram_copy[datagram_length] = 0;
649 
650  // ----- tokenize
651  count = 0;
652  cur_field = strtok(datagram, " ");
653 
654  while (cur_field != NULL)
655  {
656  fields.push_back(cur_field);
657  //std::cout << cur_field << std::endl;
658  cur_field = strtok(NULL, " ");
659  }
660 
661  //std::cout << fields[27] << std::endl;
662 
663  count = fields.size();
664 
665 
666  if (verboseLevel > 0)
667  {
668  static int cnt = 0;
669  char szDumpFileName[255] = {0};
670  char szDir[255] = {0};
671 #ifdef _MSC_VER
672  strcpy(szDir,"C:\\temp\\");
673 #else
674  strcpy(szDir,"/tmp/");
675 #endif
676  sprintf(szDumpFileName,"%stmp%06d.txt", szDir, cnt);
677  ROS_WARN("Verbose LEVEL activated. Only for DEBUG.");
678  FILE *ftmp;
679  ftmp = fopen(szDumpFileName,"w");
680  if (ftmp != NULL)
681  {
682  int i;
683  for (i = 0; i < count; i++)
684  {
685  fprintf(ftmp, "%3d: %s\n", i, fields[i]);
686  }
687  fclose(ftmp);
688  }
689  cnt++;
690  }
691 
692  // Validate header. Total number of tokens is highly unreliable as this may
693  // change when you change the scanning range or the device name using SOPAS ET
694  // tool. The header remains stable, however.
695  if (count < HEADER_FIELDS)
696  {
697  ROS_WARN(
698  "received less fields than minimum fields (actual: %d, minimum: %d), ignoring scan", (int)count, HEADER_FIELDS);
699  ROS_WARN("are you using the correct node? (124 --> sick_tim310_1130000m01, > 33 --> sick_tim551_2050001, 580 --> sick_tim310s01, 592 --> sick_tim310)");
700  // ROS_DEBUG("received message was: %s", datagram_copy);
701  return ExitError;
702  }
703 
704  if (basicParams[scannerIdx].getNumberOfLayers() == 1)
705  {
706  if (strcmp(fields[15], "0"))
707  {
708  ROS_WARN("Field 15 of received data is not equal to 0 (%s). Unexpected data, ignoring scan", fields[15]);
709  return ExitError;
710  }
711  }
712  else // fields[15] enthält keine "0"
713  {
714 
715  //other layers are here on alternate values
716  // ROS_WARN("Field 15 of received data is not equal to 0 (%s). Unexpected data, ignoring scan", fields[15]);
717  // return ExitError;
718  }
719  if (strcmp(fields[20], "DIST1"))
720  {
721  ROS_WARN("Field 20 of received data is not equal to DIST1i (%s). Unexpected data, ignoring scan", fields[20]);
722  return ExitError;
723  }
724 
725  // More in depth checks: check data length and RSSI availability
726  // 25: Number of data (<= 10F)
727  unsigned short int number_of_data = 0;
728  sscanf(fields[25], "%hx", &number_of_data);
729 
730  int numOfExpectedShots = basicParams[scannerIdx].getNumberOfShots();
731  if (number_of_data < 1 || number_of_data > numOfExpectedShots)
732  {
733  ROS_WARN("Data length is outside acceptable range 1-%d (%d). Ignoring scan", numOfExpectedShots, number_of_data);
734  return ExitError;
735  }
736  if (count < HEADER_FIELDS + number_of_data)
737  {
738  ROS_WARN("Less fields than expected for %d data points (%zu). Ignoring scan", number_of_data, count);
739  return ExitError;
740  }
741  ROS_DEBUG("Number of data: %d", number_of_data);
742 
743  // Calculate offset of field that contains indicator of whether or not RSSI data is included
744  size_t rssi_idx = 26 + number_of_data;
745  bool rssi = false;
746  if (strcmp(fields[rssi_idx], "RSSI1") == 0)
747  {
748  rssi = true;
749  }
750  unsigned short int number_of_rssi_data = 0;
751  if (rssi)
752  {
753  sscanf(fields[rssi_idx + 5], "%hx", &number_of_rssi_data);
754 
755  // Number of RSSI data should be equal to number of data
756  if (number_of_rssi_data != number_of_data)
757  {
758  ROS_WARN("Number of RSSI data is lower than number of range data (%d vs %d", number_of_data, number_of_rssi_data);
759  return ExitError;
760  }
761 
762  // Check if the total length is still appropriate.
763  // RSSI data size = number of RSSI readings + 6 fields describing the data
764  if (count < HEADER_FIELDS + number_of_data + number_of_rssi_data + 6)
765  {
766  ROS_WARN("Less fields than expected for %d data points (%zu). Ignoring scan", number_of_data, count);
767  return ExitError;
768  }
769 
770  if (strcmp(fields[rssi_idx], "RSSI1"))
771  {
772  ROS_WARN("Field %zu of received data is not equal to RSSI1 (%s). Unexpected data, ignoring scan", rssi_idx + 1, fields[rssi_idx + 1]);
773  }
774  }
775 
776  if (basicParams[scannerIdx].getNumberOfLayers() > 1)
777  {
778  short layer = -1;
779  sscanf(fields[15], "%hx", &layer);
780  msg.header.seq = layer;
781  }
782  // ----- read fields into msg
783  msg.header.frame_id = config.frame_id;
784  // evtl. debug stream benutzen
785  ROS_DEBUG("publishing with frame_id %s", config.frame_id.c_str());
786 
787  ros::Time start_time = ros::Time::now(); // will be adjusted in the end
788 
789 
790  /*
791 
792  */
793  // <STX> (\x02)
794  // 0: Type of command (SN)
795  // 1: Command (LMDscandata)
796  // 2: Firmware version number (1)
797  // 3: Device number (1)
798  // 4: Serial number (eg. B96518)
799  // 5 + 6: Device Status (0 0 = ok, 0 1 = error)
800  // 7: Telegram counter (eg. 99)
801  // 8: Scan counter (eg. 9A)
802  // 9: Time since startup (eg. 13C8E59)
803 
804 
805  // 10: Time of transmission (eg. 13C9CBE)
806  // 11 + 12: Input status (0 0)
807  // 13 + 14: Output status (8 0)
808  // 15: Reserved Byte A (0)
809 
810  // 16: Scanning Frequency (5DC)
811  unsigned short scanning_freq = -1;
812  sscanf(fields[16], "%hx", &scanning_freq);
813  msg.scan_time = 1.0 / (scanning_freq / 100.0);
814  // ROS_DEBUG("hex: %s, scanning_freq: %d, scan_time: %f", fields[16], scanning_freq, msg.scan_time);
815 
816  // 17: Measurement Frequency (36)
817  unsigned short measurement_freq = -1;
818  sscanf(fields[17], "%hx", &measurement_freq);
819  msg.time_increment = 1.0 / (measurement_freq * 100.0);
820  if (override_time_increment_ > 0.0)
821  {
822  // Some lasers may report incorrect measurement frequency
823  msg.time_increment = override_time_increment_;
824  }
825  // ROS_DEBUG("measurement_freq: %d, time_increment: %f", measurement_freq, msg.time_increment);
826 
827  // 18: Number of encoders (0)
828  // 19: Number of 16 bit channels (1)
829  // 20: Measured data contents (DIST1)
830 
831  // 21: Scaling factor (3F800000)
832  // ignored for now (is always 1.0):
833  // unsigned int scaling_factor_int = -1;
834  // sscanf(fields[21], "%x", &scaling_factor_int);
835  //
836  // float scaling_factor = reinterpret_cast<float&>(scaling_factor_int);
837  // // ROS_DEBUG("hex: %s, scaling_factor_int: %d, scaling_factor: %f", fields[21], scaling_factor_int, scaling_factor);
838 
839  // 22: Scaling offset (00000000) -- always 0
840  // 23: Starting angle (FFF92230)
841  int starting_angle = -1;
842  sscanf(fields[23], "%x", &starting_angle);
843  msg.angle_min = (starting_angle / 10000.0) / 180.0 * M_PI - M_PI / 2;
844  // ROS_DEBUG("starting_angle: %d, angle_min: %f", starting_angle, msg.angle_min);
845 
846  // 24: Angular step width (2710)
847  unsigned short angular_step_width = -1;
848  sscanf(fields[24], "%hx", &angular_step_width);
849  msg.angle_increment = (angular_step_width / 10000.0) / 180.0 * M_PI;
850  msg.angle_max = msg.angle_min + (number_of_data - 1) * msg.angle_increment;
851 
852  // 25: Number of data (<= 10F)
853  // This is already determined above in number_of_data
854  int index_min = 0;
855 
856 #if 1 // neuer Ansatz
857  int distNum = 0;
858  int rssiNum = 0;
859 
860 
861  checkForDistAndRSSI(fields, number_of_data, distNum, rssiNum, msg.ranges, msg.intensities, echoMask);
862  if (config.intensity)
863  {
864  if (rssiNum > 0)
865  {
866 
867  }
868  else
869  {
870  ROS_WARN_ONCE("Intensity parameter is enabled, but the scanner is not configured to send RSSI values! "
871  "Please read the section 'Enabling intensity (RSSI) output' here: http://wiki.ros.org/sick_tim.");
872  }
873  }
874  numEchos = distNum;
875 #endif
876  // 26 + n: RSSI data included
877  // IF RSSI not included:
878  // 26 + n + 1 .. 26 + n + 3 = unknown (but seems to be [0, 1, B] always)
879  // 26 + n + 4 .. count - 4 = device label
880  // count - 3 .. count - 1 = unknown (but seems to be 0 always)
881  // <ETX> (\x03)
882 
883  msg.range_min = override_range_min_;
884  msg.range_max = override_range_max_;
885 
886  if (basicParams[scannerIdx].getNumberOfLayers() > 1)
887  {
888  char szDummy[255] = { 0 };
889  sprintf(szDummy, "%s_%+04d", config.frame_id.c_str(), msg.header.seq);
890  msg.header.frame_id = szDummy;
891  }
892  // ----- adjust start time
893  // - last scan point = now ==> first scan point = now - number_of_data * time increment
894 #ifndef _MSC_VER // TIMING in Simulation not correct
895  msg.header.stamp = start_time - ros::Duration().fromSec(number_of_data * msg.time_increment);
896 
897  // - shift forward to time of first published scan point
898  msg.header.stamp += ros::Duration().fromSec((double)index_min * msg.time_increment);
899 
900  // - add time offset (to account for USB latency etc.)
901  msg.header.stamp += ros::Duration().fromSec(config.time_offset);
902 #endif
903  // ----- consistency check
904 
905  this->checkScanTiming(msg.time_increment, msg.scan_time, msg.angle_increment, 0.00001);
906  return ExitSuccess;
907  }
908 
909 
916  {
917  override_range_min_ = min;
918  }
919 
926  {
927  override_range_max_ = max;
928  }
929 
930 
937  {
938  return(override_range_max_);
939  }
940 
947  {
948  return(override_range_min_);
949  }
950 
957  {
959  }
960 
967  void SickGenericParser::setScannerType(std::string _scannerType)
968  {
969  scannerType = _scannerType;
970  }
971 
978  return(scannerType);
979 
980  }
981 
982 } /* namespace sick_scan */
void set_range_max(float max)
Setting maximum range.
void setCurrentParamPtr(ScannerBasicParam *_ptr)
Set pointer to corresponding parameter object to the parser.
int lookUpForAllowedScanner(std::string scannerName)
checks the given scannerName/scannerType of validity
void setNumberOfMaximumEchos(int _maxEchos)
Set number of maximum echoes for this laser scanner type.
double getElevationDegreeResolution(void)
get angular resolution in VERTICAL direction for multilayer scanner
SickGenericParser(std::string scannerType)
Construction of parser object.
#define SICK_SCANNER_LMS_1XX_NAME
void setNumberOfLayers(int _layerNum)
Setting number of scanner layers (depending of scanner type/family)
void setScannerType(std::string s)
setting scannertype
double getExpectedFrequency(void)
get expected scan frequency
void setElevationDegreeResolution(double _elevRes)
set angular resolution in VERTICAL direction for multilayer scanner
#define SICK_SCANNER_TIM_5XX_NAME
float get_range_min(void)
Getting minimum range.
ScannerBasicParam * currentParamSet
void setDeviceIsRadar(bool _deviceIsRadar)
flag to mark the device as radar (instead of laser scanner)
int checkForDistAndRSSI(std::vector< char * > &fields, int expected_number_of_data, int &distNum, int &rssiNum, std::vector< float > &distVal, std::vector< float > &rssiVal, int &distMask)
check for DIST and RSSI-entries in the datagram. Helper routine for parser
int getNumberOfShots(void)
Get number of shots per scan.
#define ROS_WARN(...)
bool getIntensityResolutionIs16Bit(void)
Get the RSSI Value length.
#define SICK_SCANNER_LMS_1XXX_NAME
std::string getScannerType(void)
getting scannertype
void setNumberOfShots(int _shots)
Set number of shots per scan.
void setAngularDegreeResolution(double _res)
Set angular resolution in degrees.
int getNumberOfLayers(void)
Getting number of scanner layers.
int getNumberOfMaximumEchos(void)
Get number of maximum echoes for this laser scanner type.
#define ROS_WARN_THROTTLE(period,...)
Duration & fromSec(double t)
#define ROS_WARN_ONCE(...)
#define SICK_SCANNER_RMS_3XX_NAME
virtual ~SickGenericParser()
Destructor of parser.
virtual int parse_datagram(char *datagram, size_t datagram_length, SickScanConfig &config, sensor_msgs::LaserScan &msg, int &numEchos, int &echoMask)
Parsing Ascii datagram.
void checkScanTiming(float time_increment, float scan_time, float angle_increment, float tol)
float get_range_max(void)
Getting maximum range.
#define SICK_SCANNER_MRS_6XXX_NAME
bool getUseBinaryProtocol(void)
flag to decide between usage of ASCII-sopas or BINARY-sopas
ScannerBasicParam * getCurrentParamPtr()
Gets Pointer to parameter object.
double getAngularDegreeResolution(void)
Get angular resolution in degress.
void setScannerName(std::string _s)
Setting name (type) of scanner.
std::string getScannerName(void)
Getting name (type) of scanner.
std::vector< std::string > allowedScannerNames
#define SICK_SCANNER_MRS_1XXX_NAME
ScannerBasicParam()
Construction of parameter object.
void setIntensityResolutionIs16Bit(bool _IntensityResolutionIs16Bit)
Set the RSSI Value length.
bool getParam(const std::string &key, std::string &s) const
void set_time_increment(float time)
setting time increment between shots
std::vector< ScannerBasicParam > basicParams
static Time now()
void set_range_min(float min)
Setting minimum range.
void setUseBinaryProtocol(bool _useBinary)
flag to decide between usage of ASCII-sopas or BINARY-sopas
#define SICK_SCANNER_LMS_5XX_NAME
void setExpectedFrequency(double _freq)
set expected scan frequency
#define ROS_ERROR(...)
#define SICK_SCANNER_TIM_7XX_NAME
bool getDeviceIsRadar(void)
flag to mark the device as radar (instead of laser scanner)
#define ROS_DEBUG(...)


sick_scan
Author(s): Michael Lehning , Jochen Sprickerhof , Martin Günther
autogenerated on Tue Jul 9 2019 04:55:32