SickLMS2xx.cc
Go to the documentation of this file.
1 
16 /* Auto-generated header */
18 
19 /* Implementation dependencies */
20 #include <sstream>
21 #include <iostream>
22 #include <termios.h>
23 #include <sys/ioctl.h>
24 #include <signal.h>
25 
31 
32 #ifdef HAVE_LINUX_SERIAL_H
33 #include <linux/serial.h>
34 #else
35 #define B500000 0010005
36 #endif
37 
38 /* Associate the namespace */
39 namespace SickToolbox {
40 
45  SickLMS2xx::SickLMS2xx( const std::string sick_device_path ): SickLIDAR< SickLMS2xxBufferMonitor, SickLMS2xxMessage >( ),
46  _sick_device_path(sick_device_path),
47  _curr_session_baud(SICK_BAUD_UNKNOWN),
48  _desired_session_baud(SICK_BAUD_UNKNOWN),
49  _sick_type(SICK_LMS_TYPE_UNKNOWN),
50  _sick_mean_value_sample_size(0),
51  _sick_values_subrange_start_index(0),
52  _sick_values_subrange_stop_index(0)
53  {
54 
55  /* Initialize the protected/private structs */
64  memset(&_old_term,0,sizeof(struct termios));
65 
66  }
67 
72 
73  try {
74 
75  /* Attempt to uninitialize the device */
77 
78  }
79 
80  /* Catch an I/O exception */
81  catch(SickIOException &sick_io_exception) {
82  std::cerr << sick_io_exception.what() << std::endl;
83  }
84 
85  /* Catch anything else */
86  catch(...) {
87  std::cerr << "SickLMS2xx::~SickLMS2xx: Unknown exception!" << std::endl;
88  }
89 
90  }
91 
98  void SickLMS2xx::Initialize( const sick_lms_2xx_baud_t desired_baud_rate, const uint32_t delay )
100 
101  /* Buffer the desired baud rate in case we have to reset */
102  _desired_session_baud = desired_baud_rate;
103 
104  try {
105 
106  std::cout << std::endl << "\t*** Attempting to initialize the Sick LMS..." << std::endl << std::flush;
107 
108  /* Initialize the serial term for communication */
109  std::cout << "\tAttempting to open device @ " << _sick_device_path << std::endl << std::flush;
110  _setupConnection(delay);
111  std::cout << "\t\tDevice opened!" << std::endl << std::flush;
112 
113  /* Start/reset the buffer monitor */
114  if (!_sick_monitor_running) {
115  std::cout << "\tAttempting to start buffer monitor..." << std::endl;
116  _startListening();
117  std::cout << "\t\tBuffer monitor started!" << std::endl;
118  }
119  else {
120  std::cout << "\tAttempting to reset buffer monitor..." << std::endl;
122  std::cout << "\t\tBuffer monitor reset!" << std::endl;
123  }
124 
125  try {
126 
127  std::cout << "\tAttempting to set requested baud rate..." << std::endl;
129 
130  }
131 
132  /* Assume a timeout is due to a misconfigured terminal baud */
133  catch(SickTimeoutException &sick_timeout) {
134 
135  /* Check whether to do an autodetect */
137  std::cout << "\tFailed to set requested baud rate..." << std::endl << std::flush;
138  std::cout << "\tAttempting to detect LMS baud rate..." << std::endl << std::flush;
139  if((default_baud != SICK_BAUD_9600) && _testSickBaud(SICK_BAUD_9600)) {
140  std::cout << "\t\tDetected LMS baud @ " << SickBaudToString(SICK_BAUD_9600) << "!" << std::endl;
141  } else if((default_baud != SICK_BAUD_19200) && _testSickBaud(SICK_BAUD_19200)) {
142  std::cout << "\t\tDetected LMS baud @ " << SickBaudToString(SICK_BAUD_19200) << "!" << std::endl;
143  } else if((default_baud != SICK_BAUD_38400) && _testSickBaud(SICK_BAUD_38400)) {
144  std::cout << "\t\tDetected LMS baud @ " << SickBaudToString(SICK_BAUD_38400) << "!" << std::endl;
145  } else if((default_baud) != SICK_BAUD_500K && _testSickBaud(SICK_BAUD_500K)) {
146  std::cout << "\t\tDetected LMS baud @ " << SickBaudToString(SICK_BAUD_500K) << "!" << std::endl;
147  } else {
148  _stopListening();
149  throw SickIOException("SickLMS2xx::Initialize: failed to detect baud rate!");
150  }
151  std::cout << std::flush;
152 
153  /* Try again! */
155  std::cout << "\tAttempting to setup desired baud (again)..." << std::endl << std::flush;
157  }
158 
159  }
160 
161  /* Catch anything else */
162  catch(...) {
163  std::cerr << "SickLMS2xx::Initialize: Unknown exception!" << std::endl;
164  throw;
165  }
166 
167  std::cout << "\t\tOperating @ " << SickBaudToString(_curr_session_baud) << std::endl;
168 
169  /* Set the device to request range mode */
171 
172  /* Acquire the type of device that we are working with */
173  std::cout << "\tAttempting to sync driver..." << std::endl << std::flush;
174  _getSickType(); // Get the Sick device type string
175  _getSickStatus(); // Get the Sick device status
176  _getSickConfig(); // Get the Sick current config
177  std::cout << "\t\tDriver synchronized!" << std::endl << std::flush;
178 
179  /* Set the flag */
180  _sick_initialized = true;
181 
182  }
183 
184  /* Handle a config exception */
185  catch(SickConfigException &sick_config_exception) {
186  std::cerr << sick_config_exception.what() << std::endl;
187  throw;
188  }
189 
190  /* Handle a timeout exception */
191  catch(SickTimeoutException &sick_timeout_exception) {
192  std::cerr << sick_timeout_exception.what() << std::endl;
193  throw;
194  }
195 
196  /* Handle any I/O exceptions */
197  catch(SickIOException &sick_io_exception) {
198  std::cerr << sick_io_exception.what() << std::endl;
199  throw;
200  }
201 
202  /* Handle any thread exceptions */
203  catch(SickThreadException &sick_thread_exception) {
204  std::cerr << sick_thread_exception.what() << std::endl;
205  throw;
206  }
207 
208  /* Handle anything else */
209  catch(...) {
210  std::cerr << "SickLMS2xx::Initialize: Unknown exception!" << std::endl;
211  throw;
212  }
213 
214  /* Initialization was successful! */
215  std::cout << "\t*** Init. complete: Sick LMS is online and ready!" << std::endl;
216  std::cout << "\tSick Type: " << SickTypeToString(GetSickType()) << std::endl;
217  std::cout << "\tScan Angle: " << GetSickScanAngle() << " (deg)" << std::endl;
218  std::cout << "\tScan Resolution: " << GetSickScanResolution() << " (deg)" << std::endl;
219  std::cout << "\tMeasuring Mode: " << SickMeasuringModeToString(GetSickMeasuringMode()) << std::endl;
220  std::cout << "\tMeasuring Units: " << SickMeasuringUnitsToString(GetSickMeasuringUnits()) << std::endl;
221  std::cout << std::endl << std::flush;
222 
223  }
224 
230 
231  if (_sick_initialized) {
232 
233  std::cout << std::endl << "\t*** Attempting to uninitialize the Sick LMS..." << std::endl;
234 
235  try {
236 
237  /* Restore original operating mode */
239 
240  /* Restore original baud rate settings */
242 
243  /* Attempt to cancel the buffer monitor */
244  if (_sick_monitor_running) {
245  std::cout << "\tAttempting to stop buffer monitor..." << std::endl;
246  _stopListening();
247  std::cout << "\t\tBuffer monitor stopped!" << std::endl;
248  }
249 
250  std::cout << "\t*** Uninit. complete - Sick LMS is now offline!" << std::endl << std::flush;
251 
252  }
253 
254  /* Handle any config exceptions */
255  catch(SickConfigException &sick_config_exception) {
256  std::cerr << sick_config_exception.what() << " (attempting to kill connection anyways)" << std::endl;
257  throw;
258  }
259 
260  /* Handle a timeout exception */
261  catch(SickTimeoutException &sick_timeout_exception) {
262  std::cerr << sick_timeout_exception.what() << " (attempting to kill connection anyways)" << std::endl;
263  throw;
264  }
265 
266  /* Handle any I/O exceptions */
267  catch(SickIOException &sick_io_exception) {
268  std::cerr << sick_io_exception.what() << " (attempting to kill connection anyways)" << std::endl;
269  throw;
270  }
271 
272  /* Handle any thread exceptions */
273  catch(SickThreadException &sick_thread_exception) {
274  std::cerr << sick_thread_exception.what() << " (attempting to kill connection anyways)" << std::endl;
275  throw;
276  }
277 
278  /* Handle anything else */
279  catch(...) {
280  std::cerr << "SickLMS2xx::Unintialize: Unknown exception!!!" << std::endl;
281  throw;
282  }
283 
284  /* Reset the flag */
285  _sick_initialized = false;
286 
287  }
288 
289  }
290 
295  std::string SickLMS2xx::GetSickDevicePath( ) const {
296  return _sick_device_path;
297  }
298 
304 
305  /* Ensure the device is initialized */
306  if (!_sick_initialized) {
307  throw SickConfigException("SickLMS2xx::GetSickType: Sick LMS is not initialized!");
308  }
309 
310  /* Return the Sick LMS type */
311  return _sick_type;
312 
313  }
314 
320 
321  /* Ensure the device is initialized */
322  if (!_sick_initialized) {
323  throw SickConfigException("SickLMS2xx::GetSickScanAngle: Sick LMS is not initialized!");
324  }
325 
326  /* Return the Sick scan angle */
328 
329  }
330 
336 
337  /* Ensure the device is initialized */
338  if (!_sick_initialized) {
339  throw SickConfigException("SickLMS2xx::GetSickScanResolution: Sick LMS is not initialized!");
340  }
341 
342  /* Return the scan resolution */
344 
345  }
346 
353 
354  /* Ensure the device is initialized */
355  if (!_sick_initialized) {
356  throw SickConfigException("SickLMS2xx::SetSickMeasuringUnits: Sick LMS is not initialized!");
357  }
358 
359  /* Ensure a valid units type was given */
360  if (!_validSickMeasuringUnits(sick_units)) {
361  throw SickConfigException("SickLMS2xx::SetSickMeasuringUnits: Undefined measurement units!");
362  }
363 
364  /* Make sure the write is necessary */
365  if (sick_units != _sick_device_config.sick_measuring_units) {
366 
367  /* Setup a local copy of the config */
368  sick_lms_2xx_device_config_t sick_device_config;
369 
370  /* Copy the configuration locally */
371  sick_device_config = _sick_device_config;
372 
373  /* Set the units value */
374  sick_device_config.sick_measuring_units = sick_units;
375 
376  try {
377 
378  /* Attempt to set the new configuration */
379  _setSickConfig(sick_device_config);
380 
381  }
382 
383  /* Handle any config exceptions */
384  catch(SickConfigException &sick_config_exception) {
385  std::cerr << sick_config_exception.what() << std::endl;
386  throw;
387  }
388 
389  /* Handle a timeout exception */
390  catch(SickTimeoutException &sick_timeout_exception) {
391  std::cerr << sick_timeout_exception.what() << std::endl;
392  throw;
393  }
394 
395  /* Handle any I/O exceptions */
396  catch(SickIOException &sick_io_exception) {
397  std::cerr << sick_io_exception.what() << std::endl;
398  throw;
399  }
400 
401  /* Handle any thread exceptions */
402  catch(SickThreadException &sick_thread_exception) {
403  std::cerr << sick_thread_exception.what() << std::endl;
404  throw;
405  }
406 
407  /* Handle anything else */
408  catch(...) {
409  std::cerr << "SickLMS2xx::SetSickMeasuringUnits: Unknown exception!!!" << std::endl;
410  throw;
411  }
412 
413  }
414  else {
415  std::cerr << "\tSickLMS2xx::SetSickMeasuringUnits - Device is already configured w/ these units. (skipping write)" << std::endl;
416  }
417 
418  }
419 
425 
426  /* Ensure the device is initialized */
427  if (!_sick_initialized) {
428  throw SickConfigException("SickLMS2xx::GetSickMeasuringUnits: Sick LMS is not initialized!");
429  }
430 
431  /* Return the measurement units */
433 
434  }
435 
442 
443  /* Ensure the device is initialized */
444  if (!_sick_initialized) {
445  throw SickConfigException("SickLMS2xx::SetSickSensitivity: Sick LMS is not initialized!");
446  }
447 
448  /* Ensure the command is supported by the given Sick model */
449  if (!_isSickLMS211() && !_isSickLMS221() && !_isSickLMS291()) {
450  throw SickConfigException("SickLMS2xx::SetSickSensitivity: This command is not supported by this Sick model!");
451  }
452 
453  /* Ensure this is a valid sick sensitivity value*/
454  if (!_validSickSensitivity(sick_sensitivity)) {
455  throw SickConfigException("SickLMS2xx::SetSickSensitivity: Undefined sensitivity level!");
456  }
457 
458  /* Make sure the write is necessary */
459  if (sick_sensitivity != _sick_device_config.sick_peak_threshold) {
460 
461  /* Setup a local copy of the config */
462  sick_lms_2xx_device_config_t sick_device_config;
463 
464  /* Copy the configuration locally */
465  sick_device_config = _sick_device_config;
466 
467  /* Set the units value */
468  sick_device_config.sick_peak_threshold = sick_sensitivity;
469 
470  try {
471 
472  /* Attempt to set the new configuration */
473  _setSickConfig(sick_device_config);
474 
475  }
476 
477  /* Handle any config exceptions */
478  catch(SickConfigException &sick_config_exception) {
479  std::cerr << sick_config_exception.what() << std::endl;
480  throw;
481  }
482 
483  /* Handle a timeout exception */
484  catch(SickTimeoutException &sick_timeout_exception) {
485  std::cerr << sick_timeout_exception.what() << std::endl;
486  throw;
487  }
488 
489  /* Handle any I/O exceptions */
490  catch(SickIOException &sick_io_exception) {
491  std::cerr << sick_io_exception.what() << std::endl;
492  throw;
493  }
494 
495  /* Handle any thread exceptions */
496  catch(SickThreadException &sick_thread_exception) {
497  std::cerr << sick_thread_exception.what() << std::endl;
498  throw;
499  }
500 
501  /* Handle anything else */
502  catch(...) {
503  std::cerr << "SickLMS2xx::SetSickSensitivity: Unknown exception!!!" << std::endl;
504  throw;
505  }
506 
507  }
508  else {
509  std::cerr << "\tSickLMS2xx::SetSickSensitivity - Sick is already operating at this sensitivity level! (skipping write)" << std::endl;
510  }
511 
512  }
513 
520 
521  /* Ensure the device is initialized */
522  if (!_sick_initialized) {
523  throw SickConfigException("SickLMS2xx::SetSickPeakThreshold: Sick LMS is not initialized!");
524  }
525 
526  /* Ensure the command is supported by the given Sick model */
527  if (!_isSickLMS200() && !_isSickLMS220()) {
528  throw SickConfigException("SickLMS2xx::SetSickPeakThreshold: This command is not supported by this Sick model!");
529  }
530 
531  /* Ensure this is a valid sick sensitivity value*/
532  if (!_validSickPeakThreshold(sick_peak_threshold)) {
533  throw SickConfigException("SickLMS2xx::SetSickPeakThreshold: Undefined peak threshold!");
534  }
535 
536  /* Make sure the write is necessary */
537  if (sick_peak_threshold != _sick_device_config.sick_peak_threshold) {
538 
539  /* Setup a local copy of the config */
540  sick_lms_2xx_device_config_t sick_device_config;
541 
542  /* Copy the configuration locally */
543  sick_device_config = _sick_device_config;
544 
545  /* Set the units value */
546  sick_device_config.sick_peak_threshold = sick_peak_threshold;
547 
548  try {
549 
550  /* Attempt to set the new configuration */
551  _setSickConfig(sick_device_config);
552 
553  }
554 
555  /* Handle any config exceptions */
556  catch(SickConfigException &sick_config_exception) {
557  std::cerr << sick_config_exception.what() << std::endl;
558  throw;
559  }
560 
561  /* Handle a timeout exception */
562  catch(SickTimeoutException &sick_timeout_exception) {
563  std::cerr << sick_timeout_exception.what() << std::endl;
564  throw;
565  }
566 
567  /* Handle any I/O exceptions */
568  catch(SickIOException &sick_io_exception) {
569  std::cerr << sick_io_exception.what() << std::endl;
570  throw;
571  }
572 
573  /* Handle any thread exceptions */
574  catch(SickThreadException &sick_thread_exception) {
575  std::cerr << sick_thread_exception.what() << std::endl;
576  throw;
577  }
578 
579  /* Handle anything else */
580  catch(...) {
581  std::cerr << "SickLMS2xx::SetSickPeakThreshold: Unknown exception!!!" << std::endl;
582  throw;
583  }
584 
585  }
586  else {
587  std::cerr << "\tSickLMS2xx::SetSickPeakThreshold - Sick is already operating w/ given threshold! (skipping write)" << std::endl;
588  }
589 
590  }
591 
597 
598  /* Ensure the device is initialized */
599  if (!_sick_initialized) {
600  throw SickConfigException("SickLMS2xx::GetSickSensitivity: Sick LMS is not initialized!");
601  }
602 
603  /* Make sure sensitivity is something that is defined for this model */
604  if(!_isSickLMS211() && !_isSickLMS221() && !_isSickLMS291()) {
605  std::cerr << "Sensitivity is undefined for model: " << SickTypeToString(GetSickType()) << " (returning \"Unknown\")" << std::endl;
607  }
608 
609  /* If its supported than return the actual value */
610  return (sick_lms_2xx_sensitivity_t)_sick_device_config.sick_peak_threshold; //If the device is 211/221/291 then this value is sensitivity
611 
612  }
613 
619 
620  /* Ensure the device is initialized */
621  if (!_sick_initialized) {
622  throw SickConfigException("SickLMS2xx::GetSickPeakThreshold: Sick LMS is not initialized!");
623  }
624 
625  /* Make sure sensitivity is something that is defined for this model */
626  if(!_isSickLMS200() && !_isSickLMS220()) {
627  std::cerr << "Peak threshold is undefined for model: " << SickTypeToString(GetSickType()) << " (returning \"Unknown\")" << std::endl;
629  }
630 
631  /* If its supported than return the actual value */
632  return (sick_lms_2xx_peak_threshold_t)_sick_device_config.sick_peak_threshold; //If the device is 211/221/291 then this value is sensitivity
633 
634  }
635 
642 
643  /* Ensure the device is initialized */
644  if (!_sick_initialized) {
645  throw SickConfigException("SickLMS2xx::SetSickMeasuringUnits: Sick LMS is not initialized!");
646  }
647 
648  /* Ensure this is a valid sick sensitivity value*/
649  if (!_validSickMeasuringMode(sick_measuring_mode)) {
650  throw SickConfigException("SickLMS2xx::SetSickMeasuringMode: Undefined measuring mode!");
651  }
652 
653  /* Make sure the write is necessary */
654  if (sick_measuring_mode != _sick_device_config.sick_measuring_mode) {
655 
656  /* Setup a local copy of the config */
657  sick_lms_2xx_device_config_t sick_device_config;
658 
659  /* Copy the configuration locally */
660  sick_device_config = _sick_device_config;
661 
662  /* Set the units value */
663  sick_device_config.sick_measuring_mode = sick_measuring_mode;
664 
665  try {
666 
667  /* Attempt to set the new configuration */
668  _setSickConfig(sick_device_config);
669 
670  }
671 
672  /* Handle any config exceptions */
673  catch(SickConfigException &sick_config_exception) {
674  std::cerr << sick_config_exception.what() << std::endl;
675  throw;
676  }
677 
678  /* Handle a timeout exception */
679  catch(SickTimeoutException &sick_timeout_exception) {
680  std::cerr << sick_timeout_exception.what() << std::endl;
681  throw;
682  }
683 
684  /* Handle any I/O exceptions */
685  catch(SickIOException &sick_io_exception) {
686  std::cerr << sick_io_exception.what() << std::endl;
687  throw;
688  }
689 
690  /* Handle any thread exceptions */
691  catch(SickThreadException &sick_thread_exception) {
692  std::cerr << sick_thread_exception.what() << std::endl;
693  throw;
694  }
695 
696  /* Handle anything else */
697  catch(...) {
698  std::cerr << "SickLMS2xx::SetSickMeasuringMode: Unknown exception!!!" << std::endl;
699  throw;
700  }
701 
702  }
703  else {
704  std::cerr << "\tSickLMS2xx::SetSickMeasuringMode - Sick is already operating w/ this measuring mode! (skipping write)" << std::endl;
705  }
706 
707  }
708 
714 
715  /* Ensure the device is initialized */
716  if (!_sick_initialized) {
717  throw SickConfigException("SickLMS2xx::GetSickMeasuringMode: Sick LMS is not initialized!");
718  }
719 
720  /* Return the determined measuring mode */
722 
723  }
724 
730 
731  /* Ensure the device is initialized */
732  if (!_sick_initialized) {
733  throw SickConfigException("SickLMS2xx::GetSickScanAngle: Sick LMS is not initialized!");
734  }
735 
736  /* Return the current operating mode of the device */
738 
739  }
740 
745  void SickLMS2xx::SetSickAvailability( const uint8_t sick_availability_flags )
747 
748  /* Ensure the device is initialized */
749  if (!_sick_initialized) {
750  throw SickConfigException("SickLMS2xx::SetSickAvailabilityFlags: Sick LMS is not initialized!");
751  }
752 
753  /* Ensure this is a valid sick sensitivity value*/
754  if ( sick_availability_flags > 7 ) {
755  throw SickConfigException("SickLMS2xx::SetSickAvailabilityFlags: Invalid availability!");
756  }
757 
758  /* Setup a local copy of the config */
759  sick_lms_2xx_device_config_t sick_device_config;
760 
761  /* Copy the configuration locally */
762  sick_device_config = _sick_device_config;
763 
764  /* Maintain the higher level bits */
765  sick_device_config.sick_availability_level &= 0xF8;
766 
767  /* Set the new availability flags */
768  sick_device_config.sick_availability_level |= sick_availability_flags;
769 
770  /* Make sure the write is necessary */
772 
773  try {
774 
775  /* Attempt to set the new configuration */
776  _setSickConfig(sick_device_config);
777 
778  }
779 
780  /* Handle any config exceptions */
781  catch(SickConfigException &sick_config_exception) {
782  std::cerr << sick_config_exception.what() << std::endl;
783  throw;
784  }
785 
786  /* Handle a timeout exception */
787  catch(SickTimeoutException &sick_timeout_exception) {
788  std::cerr << sick_timeout_exception.what() << std::endl;
789  throw;
790  }
791 
792  /* Handle any I/O exceptions */
793  catch(SickIOException &sick_io_exception) {
794  std::cerr << sick_io_exception.what() << std::endl;
795  throw;
796  }
797 
798  /* Handle any thread exceptions */
799  catch(SickThreadException &sick_thread_exception) {
800  std::cerr << sick_thread_exception.what() << std::endl;
801  throw;
802  }
803 
804  /* Handle anything else */
805  catch(...) {
806  std::cerr << "SickLMS2xx::SetSickAvailabilityFlags: Unknown exception!!!" << std::endl;
807  throw;
808  }
809 
810  }
811  else {
812  std::cerr << "\tSickLMS2xx::SetSickAvailability - Device is already operating w/ given availability. (skipping write)" << std::endl;
813  }
814 
815  }
816 
822 
823  /* Ensure the device is initialized */
824  if (!_sick_initialized) {
825  throw SickConfigException("SickLMS2xx::GetSickAvailabilityFlags: Sick LMS is not initialized!");
826  }
827 
828  /* Return the availability flags */
830 
831  }
832 
840 
841  /* Ensure the device is initialized */
842  if (!_sick_initialized) {
843  throw SickConfigException("SickLMS2xx::SetSickVariant: Sick LMS is not initialized!");
844  }
845 
846  /* A sanity check to make sure that the command is supported */
848  throw SickConfigException("SickLMS2xx::SetSickVariant: Command not supported on this model!");
849  }
850 
851  /* Ensure the given scan angle is defined */
852  if (!_validSickScanAngle(scan_angle)) {
853  throw SickConfigException("SickLMS2xx::SetSickVariant: Undefined scan angle!");
854  }
855 
856  /* Ensure the given scan resolution is defined */
857  if (!_validSickScanResolution(scan_resolution)) {
858  throw SickConfigException("SickLMS2xx::SetSickMeasuringUnits: Undefined scan resolution!");
859  }
860 
861  SickLMS2xxMessage message, response;
862  uint8_t payload_buffer[SickLMS2xxMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
863 
864  payload_buffer[0] = 0x3B; // Command to set sick variant
865 
866  /* Map the scan angle */
867  switch(scan_angle) {
868  case SICK_SCAN_ANGLE_100:
869  payload_buffer[1] = 0x64;
870  break;
871  case SICK_SCAN_ANGLE_180:
872  payload_buffer[1] = 0xB4;
873  break;
874  default:
875  throw SickConfigException("SickLMS2xx::SetSickVariant: Given scan angle is invalid!");
876  }
877 
878  /* Map the resolution */
879  switch(scan_resolution) {
881  payload_buffer[3] = 0x64;
882  break;
884  payload_buffer[3] = 0x32;
885  break;
887  payload_buffer[3] = 0x19;
888  break;
889  default:
890  throw SickConfigException("SickLMS2xx::SetSickVariant: Given scan resolution is invalid!");
891  }
892 
893  /* Build the request message */
894  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,5);
895 
896  try {
897 
898  /*
899  * Set the device to request measured mode
900  *
901  * NOTE: This is done since the Sick stops sending
902  * data if the variant is reset midstream.
903  */
905 
906  /* Send the variant request and get a reply */
908 
909  }
910 
911  /* Handle a config exception */
912  catch(SickConfigException &sick_config_exception) {
913  std::cerr << sick_config_exception.what() << std::endl;
914  throw;
915  }
916 
917  /* Handle a timeout exception */
918  catch(SickTimeoutException &sick_timeout_exception) {
919  std::cerr << sick_timeout_exception.what() << std::endl;
920  throw;
921  }
922 
923  /* Handle any I/O exceptions */
924  catch(SickIOException &sick_io_exception) {
925  std::cerr << sick_io_exception.what() << std::endl;
926  throw;
927  }
928 
929  /* Handle any thread exceptions */
930  catch(SickThreadException &sick_thread_exception) {
931  std::cerr << sick_thread_exception.what() << std::endl;
932  throw;
933  }
934 
935  /* Handle anything else */
936  catch(...) {
937  std::cerr << "SickLMS2xx::SetSickVariant: Unknown exception!!!" << std::endl;
938  throw;
939  }
940 
941  /* Extract the payload length */
942  response.GetPayload(payload_buffer);
943 
944  /* Check if the configuration was successful */
945  if(payload_buffer[1] != 0x01) {
946  throw SickConfigException("SickLMS2xx::SetSickVariant: Configuration was unsuccessful!");
947  }
948 
949  /* Update the scan angle of the device */
950  memcpy(&_sick_operating_status.sick_scan_angle,&payload_buffer[2],2);
953 
954  /* Update the angular resolution of the device */
955  memcpy(&_sick_operating_status.sick_scan_resolution,&payload_buffer[4],2);
958 
959  }
960 
977  void SickLMS2xx::GetSickScan( unsigned int * const measurement_values,
978  unsigned int & num_measurement_values,
979  unsigned int * const sick_field_a_values,
980  unsigned int * const sick_field_b_values,
981  unsigned int * const sick_field_c_values,
982  unsigned int * const sick_telegram_index,
983  unsigned int * const sick_real_time_scan_index ) throw( SickConfigException, SickTimeoutException, SickIOException, SickThreadException) {
984 
985  /* Ensure the device is initialized */
986  if (!_sick_initialized) {
987  throw SickConfigException("SickLMS2xx::GetSickScan: Sick LMS is not initialized!");
988  }
989 
990  /* Declare message objects */
991  SickLMS2xxMessage response;
992 
993  /* Declare some useful variables and a buffer */
994  uint8_t payload_buffer[SickLMS2xxMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
995 
996  try {
997 
998  /* Restore original operating mode */
1000 
1001  /* Receive a data frame from the stream. */
1003 
1004  /* Check that our payload has the proper command byte of 0xB0 */
1005  if(response.GetCommandCode() != 0xB0) {
1006  throw SickIOException("SickLMS2xx::GetSickScan: Unexpected message!");
1007  }
1008 
1009  /* Acquire the payload buffer and length*/
1010  response.GetPayload(payload_buffer);
1011 
1012  /* Define a local scan profile object */
1013  sick_lms_2xx_scan_profile_b0_t sick_scan_profile;
1014 
1015  /* Initialize the profile */
1016  memset(&sick_scan_profile,0,sizeof(sick_lms_2xx_scan_profile_b0_t));
1017 
1018  /* Parse the message payload */
1019  _parseSickScanProfileB0(&payload_buffer[1],sick_scan_profile);
1020 
1021  /* Return the request values! */
1022  num_measurement_values = sick_scan_profile.sick_num_measurements;
1023 
1024  for (unsigned int i = 0; i < num_measurement_values; i++) {
1025 
1026  /* Copy the measurement value */
1027  measurement_values[i] = sick_scan_profile.sick_measurements[i];
1028 
1029  /* If requested, copy field A values */
1030  if(sick_field_a_values) {
1031  sick_field_a_values[i] = sick_scan_profile.sick_field_a_values[i];
1032  }
1033 
1034  /* If requested, copy field B values */
1035  if(sick_field_b_values) {
1036  sick_field_b_values[i] = sick_scan_profile.sick_field_b_values[i];
1037  }
1038 
1039  /* If requested, copy field C values */
1040  if(sick_field_c_values) {
1041  sick_field_c_values[i] = sick_scan_profile.sick_field_c_values[i];
1042  }
1043 
1044  }
1045 
1046  /* If requested, copy the real time scan index */
1047  if(sick_real_time_scan_index) {
1048  *sick_real_time_scan_index = sick_scan_profile.sick_real_time_scan_index;
1049  }
1050 
1051  /* If requested, copy the telegram index */
1052  if(sick_telegram_index) {
1053  *sick_telegram_index = sick_scan_profile.sick_telegram_index;
1054  }
1055 
1056  }
1057 
1058  /* Handle any config exceptions */
1059  catch(SickConfigException &sick_config_exception) {
1060  std::cerr << sick_config_exception.what() << std::endl;
1061  throw;
1062  }
1063 
1064  /* Handle a timeout exception */
1065  catch(SickTimeoutException &sick_timeout_exception) {
1066  std::cerr << sick_timeout_exception.what() << std::endl;
1067  throw;
1068  }
1069 
1070  /* Handle any I/O exceptions */
1071  catch(SickIOException &sick_io_exception) {
1072  std::cerr << sick_io_exception.what() << std::endl;
1073  throw;
1074  }
1075 
1076  /* Handle any thread exceptions */
1077  catch(SickThreadException &sick_thread_exception) {
1078  std::cerr << sick_thread_exception.what() << std::endl;
1079  throw;
1080  }
1081 
1082  /* Handle anything else */
1083  catch(...) {
1084  std::cerr << "SickLMS2xx::GetSickScan: Unknown exception!!!" << std::endl;
1085  throw;
1086  }
1087 
1088  }
1089 
1107  void SickLMS2xx::GetSickScan( unsigned int * const range_values,
1108  unsigned int * const reflect_values,
1109  unsigned int & num_range_measurements,
1110  unsigned int & num_reflect_measurements,
1111  unsigned int * const sick_field_a_values,
1112  unsigned int * const sick_field_b_values,
1113  unsigned int * const sick_field_c_values,
1114  unsigned int * const sick_telegram_index,
1115  unsigned int * const sick_real_time_scan_index ) throw( SickConfigException, SickTimeoutException, SickIOException, SickThreadException) {
1116 
1117  /* Ensure the device is initialized */
1118  if (!_sick_initialized) {
1119  throw SickConfigException("SickLMS2xx::GetSickScan: Sick LMS is not initialized!");
1120  }
1121 
1122  /* Declare message objects */
1123  SickLMS2xxMessage response;
1124 
1125  /* Declare some useful variables and a buffer */
1126  uint8_t payload_buffer[SickLMS2xxMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
1127 
1128  try {
1129 
1130  /* Restore original operating mode */
1132 
1133  /* Receive a data frame from the stream. */
1135 
1136  /* Check that our payload has the proper command byte of 0xB0 */
1137  if(response.GetCommandCode() != 0xC4) {
1138  throw SickIOException("SickLMS2xx::GetSickScan: Unexpected message!");
1139  }
1140 
1141  /* Acquire the payload buffer and length*/
1142  response.GetPayload(payload_buffer);
1143 
1144  /* Define a local scan profile object */
1145  sick_lms_2xx_scan_profile_c4_t sick_scan_profile;
1146 
1147  /* Initialize the profile */
1148  memset(&sick_scan_profile,0,sizeof(sick_lms_2xx_scan_profile_c4_t));
1149 
1150  /* Parse the message payload */
1151  _parseSickScanProfileC4(&payload_buffer[1],sick_scan_profile);
1152 
1153  /* Return the requested values! */
1154  num_range_measurements = sick_scan_profile.sick_num_range_measurements;
1155  num_reflect_measurements = sick_scan_profile.sick_num_reflect_measurements;
1156 
1157  for (unsigned int i = 0; i < sick_scan_profile.sick_num_range_measurements; i++) {
1158 
1159  /* Copy the measurement value */
1160  range_values[i] = sick_scan_profile.sick_range_measurements[i];
1161 
1162  /* If requested, copy field A values */
1163  if(sick_field_a_values) {
1164  sick_field_a_values[i] = sick_scan_profile.sick_field_a_values[i];
1165  }
1166 
1167  /* If requested, copy field B values */
1168  if(sick_field_b_values) {
1169  sick_field_b_values[i] = sick_scan_profile.sick_field_b_values[i];
1170  }
1171 
1172  /* If requested, copy field C values */
1173  if(sick_field_c_values) {
1174  sick_field_c_values[i] = sick_scan_profile.sick_field_c_values[i];
1175  }
1176 
1177  }
1178 
1179  /* Copy the reflectivity measurements */
1180  for( unsigned int i = 0; i < num_reflect_measurements; i++) {
1181  reflect_values[i] = sick_scan_profile.sick_reflect_measurements[i];
1182  }
1183 
1184  /* If requested, copy the telegram index */
1185  if(sick_telegram_index) {
1186  *sick_telegram_index = sick_scan_profile.sick_telegram_index;
1187  }
1188 
1189  /* If requested, copy the real time scan index */
1190  if(sick_real_time_scan_index) {
1191  *sick_real_time_scan_index = sick_scan_profile.sick_real_time_scan_index;
1192  }
1193 
1194  }
1195 
1196  /* Handle any config exceptions */
1197  catch(SickConfigException &sick_config_exception) {
1198  std::cerr << sick_config_exception.what() << std::endl;
1199  throw;
1200  }
1201 
1202  /* Handle a timeout exception */
1203  catch(SickTimeoutException &sick_timeout_exception) {
1204  std::cerr << sick_timeout_exception.what() << std::endl;
1205  throw;
1206  }
1207 
1208  /* Handle any I/O exceptions */
1209  catch(SickIOException &sick_io_exception) {
1210  std::cerr << sick_io_exception.what() << std::endl;
1211  throw;
1212  }
1213 
1214  /* Handle any thread exceptions */
1215  catch(SickThreadException &sick_thread_exception) {
1216  std::cerr << sick_thread_exception.what() << std::endl;
1217  throw;
1218  }
1219 
1220  /* Handle anything else */
1221  catch(...) {
1222  std::cerr << "SickLMS2xx::GetSickScan: Unknown exception!!!" << std::endl;
1223  throw;
1224  }
1225 
1226  }
1227 
1250  void SickLMS2xx::GetSickScanSubrange( const uint16_t sick_subrange_start_index,
1251  const uint16_t sick_subrange_stop_index,
1252  unsigned int * const measurement_values,
1253  unsigned int & num_measurement_values,
1254  unsigned int * const sick_field_a_values,
1255  unsigned int * const sick_field_b_values,
1256  unsigned int * const sick_field_c_values,
1257  unsigned int * const sick_telegram_index,
1258  unsigned int * const sick_real_time_scan_index ) throw( SickConfigException, SickTimeoutException, SickIOException, SickThreadException) {
1259 
1260  /* Ensure the device is initialized */
1261  if (!_sick_initialized) {
1262  throw SickConfigException("SickLMS2xx::GetSickScanSubrange: Sick LMS is not initialized!");
1263  }
1264 
1265  /* Declare message object */
1266  SickLMS2xxMessage response;
1267 
1268  /* Declare some useful variables and a buffer */
1269  uint8_t payload_buffer[SickLMS2xxMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
1270 
1271  try {
1272 
1273  /* Restore original operating mode */
1274  _setSickOpModeMonitorStreamValuesSubrange(sick_subrange_start_index,sick_subrange_stop_index);
1275 
1276  /* Receive a data frame from the stream. */
1278 
1279  /* Check that our payload has the proper command byte of 0xB0 */
1280  if(response.GetCommandCode() != 0xB7) {
1281  throw SickIOException("SickLMS2xx::GetSickScanSubrange: Unexpected message!");
1282  }
1283 
1284  /* Acquire the payload buffer and length*/
1285  response.GetPayload(payload_buffer);
1286 
1287  /* Define a local scan profile object */
1288  sick_lms_2xx_scan_profile_b7_t sick_scan_profile;
1289 
1290  /* Initialize the profile */
1291  memset(&sick_scan_profile,0,sizeof(sick_lms_2xx_scan_profile_b7_t));
1292 
1293  /* Parse the message payload */
1294  _parseSickScanProfileB7(&payload_buffer[1],sick_scan_profile);
1295 
1296  /* Return the request values! */
1297  num_measurement_values = sick_scan_profile.sick_num_measurements;
1298 
1299  for (unsigned int i = 0; i < num_measurement_values; i++) {
1300 
1301  /* Copy the measurement value */
1302  measurement_values[i] = sick_scan_profile.sick_measurements[i];
1303 
1304  /* If requested, copy field A values */
1305  if(sick_field_a_values) {
1306  sick_field_a_values[i] = sick_scan_profile.sick_field_a_values[i];
1307  }
1308 
1309  /* If requested, copy field B values */
1310  if(sick_field_b_values) {
1311  sick_field_b_values[i] = sick_scan_profile.sick_field_b_values[i];
1312  }
1313 
1314  /* If requested, copy field C values */
1315  if(sick_field_c_values) {
1316  sick_field_c_values[i] = sick_scan_profile.sick_field_c_values[i];
1317  }
1318 
1319  }
1320 
1321  /* If requested, copy the real time scan index */
1322  if(sick_real_time_scan_index) {
1323  *sick_real_time_scan_index = sick_scan_profile.sick_real_time_scan_index;
1324  }
1325 
1326  /* If requested, copy the telegram index */
1327  if(sick_telegram_index) {
1328  *sick_telegram_index = sick_scan_profile.sick_telegram_index;
1329  }
1330 
1331  }
1332 
1333  /* Handle any config exceptions */
1334  catch(SickConfigException &sick_config_exception) {
1335  std::cerr << sick_config_exception.what() << std::endl;
1336  throw;
1337  }
1338 
1339  /* Handle a timeout exception */
1340  catch(SickTimeoutException &sick_timeout_exception) {
1341  std::cerr << sick_timeout_exception.what() << std::endl;
1342  throw;
1343  }
1344 
1345  /* Handle any I/O exceptions */
1346  catch(SickIOException &sick_io_exception) {
1347  std::cerr << sick_io_exception.what() << std::endl;
1348  throw;
1349  }
1350 
1351  /* Handle any thread exceptions */
1352  catch(SickThreadException &sick_thread_exception) {
1353  std::cerr << sick_thread_exception.what() << std::endl;
1354  throw;
1355  }
1356 
1357  /* Handle anything else */
1358  catch(...) {
1359  std::cerr << "SickLMS2xx::GetSickScanSubrange: Unknown exception!!!" << std::endl;
1360  throw;
1361  }
1362 
1363  }
1364 
1388  void SickLMS2xx::GetSickPartialScan( unsigned int * const measurement_values,
1389  unsigned int & num_measurement_values,
1390  unsigned int & partial_scan_index,
1391  unsigned int * const sick_field_a_values,
1392  unsigned int * const sick_field_b_values,
1393  unsigned int * const sick_field_c_values,
1394  unsigned int * const sick_telegram_index,
1395  unsigned int * const sick_real_time_scan_index ) throw( SickConfigException, SickTimeoutException, SickIOException, SickThreadException) {
1396 
1397  /* Ensure the device is initialized */
1398  if (!_sick_initialized) {
1399  throw SickConfigException("SickLMS2xx::GetSickPartialScan: Sick LMS is not initialized!");
1400  }
1401 
1402  /* Declare message objects */
1403  SickLMS2xxMessage response;
1404 
1405  /* Declare some useful variables and a buffer */
1406  uint8_t payload_buffer[SickLMS2xxMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
1407 
1408  try {
1409 
1410  /* Restore original operating mode */
1412 
1413  /* Receive a data frame from the stream. */
1415 
1416  /* Check that our payload has the proper command byte of 0xB0 */
1417  if(response.GetCommandCode() != 0xB0) {
1418  throw SickIOException("SickLMS2xx::GetSickPartialScan: Unexpected message!");
1419  }
1420 
1421  /* Acquire the payload buffer and length*/
1422  response.GetPayload(payload_buffer);
1423 
1424  /* Define a local scan profile object */
1425  sick_lms_2xx_scan_profile_b0_t sick_scan_profile;
1426 
1427  /* Initialize the profile */
1428  memset(&sick_scan_profile,0,sizeof(sick_lms_2xx_scan_profile_b0_t));
1429 
1430  /* Parse the message payload */
1431  _parseSickScanProfileB0(&payload_buffer[1],sick_scan_profile);
1432 
1433  /* Return the request values! */
1434  num_measurement_values = sick_scan_profile.sick_num_measurements;
1435 
1436  /* Assign the partial scan index */
1437  partial_scan_index = sick_scan_profile.sick_partial_scan_index;
1438 
1439  for (unsigned int i = 0; i < num_measurement_values; i++) {
1440 
1441  /* Copy the measurement value */
1442  measurement_values[i] = sick_scan_profile.sick_measurements[i];
1443 
1444  /* If requested, copy field A values */
1445  if(sick_field_a_values) {
1446  sick_field_a_values[i] = sick_scan_profile.sick_field_a_values[i];
1447  }
1448 
1449  /* If requested, copy field B values */
1450  if(sick_field_b_values) {
1451  sick_field_b_values[i] = sick_scan_profile.sick_field_b_values[i];
1452  }
1453 
1454  /* If requested, copy field C values */
1455  if(sick_field_c_values) {
1456  sick_field_c_values[i] = sick_scan_profile.sick_field_c_values[i];
1457  }
1458 
1459  }
1460 
1461  /* If requested, copy the real time scan index */
1462  if(sick_real_time_scan_index) {
1463  *sick_real_time_scan_index = sick_scan_profile.sick_real_time_scan_index;
1464  }
1465 
1466  /* If requested, copy the telegram index */
1467  if(sick_telegram_index) {
1468  *sick_telegram_index = sick_scan_profile.sick_telegram_index;
1469  }
1470 
1471  }
1472 
1473  /* Handle any config exceptions */
1474  catch(SickConfigException &sick_config_exception) {
1475  std::cerr << sick_config_exception.what() << std::endl;
1476  throw;
1477  }
1478 
1479  /* Handle a timeout exception */
1480  catch(SickTimeoutException &sick_timeout_exception) {
1481  std::cerr << sick_timeout_exception.what() << std::endl;
1482  throw;
1483  }
1484 
1485  /* Handle any I/O exceptions */
1486  catch(SickIOException &sick_io_exception) {
1487  std::cerr << sick_io_exception.what() << std::endl;
1488  throw;
1489  }
1490 
1491  /* Handle any thread exceptions */
1492  catch(SickThreadException &sick_thread_exception) {
1493  std::cerr << sick_thread_exception.what() << std::endl;
1494  throw;
1495  }
1496 
1497  /* Handle anything else */
1498  catch(...) {
1499  std::cerr << "SickLMS2xx::GetSickPartialScan: Unknown exception!!!" << std::endl;
1500  throw;
1501  }
1502 
1503  }
1504 
1519  void SickLMS2xx::GetSickMeanValues( const uint8_t sick_sample_size,
1520  unsigned int * const measurement_values,
1521  unsigned int & num_measurement_values,
1522  unsigned int * const sick_telegram_index,
1523  unsigned int * const sick_real_time_scan_index ) throw( SickConfigException, SickTimeoutException, SickIOException, SickThreadException) {
1524 
1525  /* Ensure the device is initialized */
1526  if (!_sick_initialized) {
1527  throw SickConfigException("SickLMS2xx::GetSickMeanValues: Sick LMS is not initialized!");
1528  }
1529 
1530  /* Declare message objects */
1531  SickLMS2xxMessage response;
1532 
1533  /* Declare some useful variables and a buffer */
1534  uint8_t payload_buffer[SickLMS2xxMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
1535 
1536  try {
1537 
1538  /* Restore original operating mode */
1539  _setSickOpModeMonitorStreamMeanValues(sick_sample_size);
1540 
1541  /* Receive a data frame from the stream. (NOTE: Can take 10+ seconds for a reply) */
1543 
1544  /* Check that our payload has the proper command byte of 0xB0 */
1545  if(response.GetCommandCode() != 0xB6) {
1546  throw SickIOException("SickLMS2xx::GetSickMeanValues: Unexpected message!");
1547  }
1548 
1549  /* Acquire the payload buffer and length*/
1550  response.GetPayload(payload_buffer);
1551 
1552  /* Define a local scan profile object */
1553  sick_lms_2xx_scan_profile_b6_t sick_scan_profile;
1554 
1555  /* Initialize the profile */
1556  memset(&sick_scan_profile,0,sizeof(sick_lms_2xx_scan_profile_b6_t));
1557 
1558  /* Parse the message payload */
1559  _parseSickScanProfileB6(&payload_buffer[1],sick_scan_profile);
1560 
1561  /* Return the request values! */
1562  num_measurement_values = sick_scan_profile.sick_num_measurements;
1563 
1564  for (unsigned int i = 0; i < num_measurement_values; i++) {
1565  /* Copy the measurement value */
1566  measurement_values[i] = sick_scan_profile.sick_measurements[i];
1567  }
1568 
1569  /* If requested, copy the real time scan index */
1570  if(sick_real_time_scan_index) {
1571  *sick_real_time_scan_index = sick_scan_profile.sick_real_time_scan_index;
1572  }
1573 
1574  /* If requested, copy the telegram index */
1575  if(sick_telegram_index) {
1576  *sick_telegram_index = sick_scan_profile.sick_telegram_index;
1577  }
1578 
1579  }
1580 
1581  /* Handle any config exceptions */
1582  catch(SickConfigException &sick_config_exception) {
1583  std::cerr << sick_config_exception.what() << std::endl;
1584  throw;
1585  }
1586 
1587  /* Handle a timeout exception */
1588  catch(SickTimeoutException &sick_timeout_exception) {
1589  std::cerr << sick_timeout_exception.what() << std::endl;
1590  throw;
1591  }
1592 
1593  /* Handle any I/O exceptions */
1594  catch(SickIOException &sick_io_exception) {
1595  std::cerr << sick_io_exception.what() << std::endl;
1596  throw;
1597  }
1598 
1599  /* Handle any thread exceptions */
1600  catch(SickThreadException &sick_thread_exception) {
1601  std::cerr << sick_thread_exception.what() << std::endl;
1602  throw;
1603  }
1604 
1605  /* Handle anything else */
1606  catch(...) {
1607  std::cerr << "SickLMS2xx::GetSickMeanValues: Unknown exception!!!" << std::endl;
1608  throw;
1609  }
1610 
1611  }
1612 
1633  void SickLMS2xx::GetSickMeanValuesSubrange( const uint8_t sick_sample_size,
1634  const uint16_t sick_subrange_start_index,
1635  const uint16_t sick_subrange_stop_index,
1636  unsigned int * const measurement_values,
1637  unsigned int & num_measurement_values,
1638  unsigned int * const sick_telegram_index,
1639  unsigned int * const sick_real_time_scan_index ) throw( SickConfigException, SickTimeoutException, SickIOException, SickThreadException) {
1640 
1641  /* Ensure the device is initialized */
1642  if (!_sick_initialized) {
1643  throw SickConfigException("SickLMS2xx::GetSickMeanValuesSubrange: Sick LMS is not initialized!");
1644  }
1645 
1646  /* Declare message objects */
1647  SickLMS2xxMessage response;
1648 
1649  /* Declare some useful variables and a buffer */
1650  uint8_t payload_buffer[SickLMS2xxMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
1651 
1652  try {
1653 
1654  /* Restore original operating mode */
1655  _setSickOpModeMonitorStreamMeanValuesSubrange(sick_sample_size,sick_subrange_start_index,sick_subrange_stop_index);
1656 
1657  /* Receive a data frame from the stream. */
1659 
1660  /* Check that our payload has the proper command byte of 0xB0 */
1661  if(response.GetCommandCode() != 0xBF) {
1662  throw SickIOException("SickLMS2xx::GetSickMeanValuesSubrange: Unexpected message!");
1663  }
1664 
1665  /* Acquire the payload buffer and length*/
1666  response.GetPayload(payload_buffer);
1667 
1668  /* Define a local scan profile object */
1669  sick_lms_2xx_scan_profile_bf_t sick_scan_profile;
1670 
1671  /* Initialize the profile */
1672  memset(&sick_scan_profile,0,sizeof(sick_lms_2xx_scan_profile_bf_t));
1673 
1674  /* Parse the message payload */
1675  _parseSickScanProfileBF(&payload_buffer[1],sick_scan_profile);
1676 
1677  /* Return the request values! */
1678  num_measurement_values = sick_scan_profile.sick_num_measurements;
1679 
1680  for (unsigned int i = 0; i < num_measurement_values; i++) {
1681 
1682  /* Copy the measurement value */
1683  measurement_values[i] = sick_scan_profile.sick_measurements[i];
1684 
1685  }
1686 
1687  /* If requested, copy the real time scan index */
1688  if(sick_real_time_scan_index) {
1689  *sick_real_time_scan_index = sick_scan_profile.sick_real_time_scan_index;
1690  }
1691 
1692  /* If requested, copy the telegram index */
1693  if(sick_telegram_index) {
1694  *sick_telegram_index = sick_scan_profile.sick_telegram_index;
1695  }
1696 
1697  }
1698 
1699  /* Handle any config exceptions */
1700  catch(SickConfigException &sick_config_exception) {
1701  std::cerr << sick_config_exception.what() << std::endl;
1702  throw;
1703  }
1704 
1705  /* Handle a timeout exception */
1706  catch(SickTimeoutException &sick_timeout_exception) {
1707  std::cerr << sick_timeout_exception.what() << std::endl;
1708  throw;
1709  }
1710 
1711  /* Handle any I/O exceptions */
1712  catch(SickIOException &sick_io_exception) {
1713  std::cerr << sick_io_exception.what() << std::endl;
1714  throw;
1715  }
1716 
1717  /* Handle any thread exceptions */
1718  catch(SickThreadException &sick_thread_exception) {
1719  std::cerr << sick_thread_exception.what() << std::endl;
1720  throw;
1721  }
1722 
1723  /* Handle anything else */
1724  catch(...) {
1725  std::cerr << "SickLMS2xx::GetMeanValuesSubrange: Unknown exception!!!" << std::endl;
1726  throw;
1727  }
1728 
1729  }
1730 
1739 
1740  /* Ensure the device is initialized */
1741  if (!_sick_initialized) {
1742  throw SickConfigException("SickLMS2xx::GetSickStatus: Sick LMS is not initialized!");
1743  }
1744 
1745  try {
1746 
1747  /* Refresh the status info! */
1748  _getSickStatus();
1749 
1750  }
1751 
1752  /* Catch any timeout exceptions */
1753  catch(SickTimeoutException &sick_timeout_exception) {
1754  std::cerr << sick_timeout_exception.what() << std::endl;
1755  throw;
1756  }
1757 
1758  /* Catch any I/O exceptions */
1759  catch(SickIOException &sick_io_exception) {
1760  std::cerr << sick_io_exception.what() << std::endl;
1761  throw;
1762  }
1763 
1764  /* Catch any thread exceptions */
1765  catch(SickThreadException &sick_thread_exception) {
1766  std::cerr << sick_thread_exception.what() << std::endl;
1767  throw;
1768  }
1769 
1770  /* Catch anything else */
1771  catch(...) {
1772  std::cerr << "SickLMS2xx::GetSickStatus: Unknown exception!" << std::endl;
1773  throw;
1774  }
1775 
1776  /* Return the latest Sick status */
1778  }
1779 
1784 
1785  /* Ensure the device is initialized */
1786  if (!_sick_initialized) {
1787  throw SickConfigException("SickLMS2xx::IsSickLMS2xxFast: Sick LMS is not initialized!");
1788  }
1789 
1790  return (_sick_type == SICK_LMS_TYPE_211_S14 ||
1793 
1794  }
1795 
1801 
1802  /* Ensure the device is initialized */
1803  if (!_sick_initialized) {
1804  throw SickConfigException("SickLMS2xx::ResetSick: Sick LMS is not initialized!");
1805  }
1806 
1807  SickLMS2xxMessage message,response;
1808  uint8_t payload[SickLMS2xxMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
1809 
1810  /* Construct the reset command */
1811  payload[0] = 0x10; // Request field reset
1813 
1814  std::cout << "\tResetting the device..." << std::endl;
1815  std::cout << "\tWaiting for Power on message..." << std::endl;
1816 
1817  try {
1818 
1819  /* Send the reset command and wait for the reply */
1820  _sendMessageAndGetReply(message,response,0x91,(unsigned int)60e6,DEFAULT_SICK_LMS_2XX_NUM_TRIES);
1821 
1822  std::cout << "\t\tPower on message received!" << std::endl;
1823  std::cout << "\tWaiting for LMS Ready message..." << std::endl;
1824 
1825  /* Set terminal baud to the detected rate to get the LMS ready message */
1827 
1828  /* Receive the LMS ready message after power on */
1829  _recvMessage(response,(unsigned int)30e6);
1830 
1831  /* Verify the response */
1832  if(response.GetCommandCode() != 0x90) {
1833  std::cerr << "SickLMS2xx::ResetSick: Unexpected reply! (assuming device has been reset!)" << std::endl;
1834  } else {
1835  std::cout << "\t\tLMS Ready message received!" << std::endl;
1836  }
1837  std::cout << std::endl;
1838 
1839  /* Reinitialize and sync the device */
1841 
1842  }
1843 
1844  /* Catch any timeout exceptions */
1845  catch(SickTimeoutException &sick_timeout_exception) {
1846  std::cerr << sick_timeout_exception.what() << std::endl;
1847  throw;
1848  }
1849 
1850  /* Catch any I/O exceptions */
1851  catch(SickIOException &sick_io_exception) {
1852  std::cerr << sick_io_exception.what() << std::endl;
1853  throw;
1854  }
1855 
1856  /* Catch any thread exceptions */
1857  catch(SickThreadException &sick_thread_exception) {
1858  std::cerr << sick_thread_exception.what() << std::endl;
1859  throw;
1860  }
1861 
1862  /* Catch anything else */
1863  catch(...) {
1864  std::cerr << "SickLMS2xx::ResetSick: Unknown exception!!!" << std::endl;
1865  throw;
1866  }
1867 
1868  std::cout << "\tRe-initialization sucessful. LMS is ready to go!" << std::endl;
1869 
1870  }
1871 
1876  std::string SickLMS2xx::GetSickStatusAsString( ) const {
1877 
1878  std::stringstream str_stream;
1879 
1880  str_stream << "\t=============== Sick LMS Status ===============" << std::endl;
1881 
1882  /* If Sick is initialized then print the status! */
1883  if (_sick_initialized) {
1884 
1885  str_stream << "\tVariant: " << _sickVariantToString(_sick_operating_status.sick_variant) << std::endl;
1886  str_stream << "\tSensor Status: " << SickStatusToString((sick_lms_2xx_status_t)_sick_operating_status.sick_device_status) << std::endl;
1887  str_stream << "\tScan Angle: " << GetSickScanAngle() << " (deg)" << std::endl;
1888  str_stream << "\tScan Resolution: " << GetSickScanResolution() << " (deg)" << std::endl;
1889  str_stream << "\tOperating Mode: " << SickOperatingModeToString(GetSickOperatingMode()) << std::endl;
1890  str_stream << "\tMeasuring Mode: " << SickMeasuringModeToString(GetSickMeasuringMode()) << std::endl;
1891  str_stream << "\tMeasuring Units: " << SickMeasuringUnitsToString(GetSickMeasuringUnits()) << std::endl;
1892 
1893  }
1894  else {
1895 
1896  str_stream << "\t Unknown (Device is not initialized)" << std::endl;
1897 
1898  }
1899 
1900  str_stream << "\t===============================================" << std::endl;
1901 
1902  return str_stream.str();
1903  }
1904 
1910 
1911  std::stringstream str_stream;
1912 
1913  str_stream << "\t============== Sick LMS Software ==============" << std::endl;
1914 
1915  if (_sick_initialized) {
1916 
1917  str_stream << "\tSystem Software: " << std::string((char *)_sick_software_status.sick_system_software_version) << std::endl;
1918  str_stream << "\tSystem Boot PROM Software: " << std::string((char *)_sick_software_status.sick_prom_software_version) << std::endl;
1919 
1920  }
1921  else {
1922 
1923  str_stream << "\t Unknown (Device is not initialized)" << std::endl;
1924 
1925  }
1926 
1927  str_stream << "\t===============================================" << std::endl;
1928 
1929  return str_stream.str();
1930  }
1931 
1936  std::string SickLMS2xx::GetSickConfigAsString( ) const {
1937 
1938  std::stringstream str_stream;
1939 
1940  str_stream<< "\t=============== Sick LMS Config ===============" << std::endl;
1941 
1942  if (_sick_initialized) {
1943 
1944  str_stream << "\tBlanking Value: " << _sick_device_config.sick_blanking << std::endl;
1945 
1946  if(_isSickLMS211() || _isSickLMS221() || _isSickLMS291()) {
1947  str_stream << "\tSensitivity: " << SickSensitivityToString(GetSickSensitivity()) << std::endl;
1948  }
1949  else {
1950  str_stream << "\tPeak Thresh: " << SickPeakThresholdToString((sick_lms_2xx_peak_threshold_t)_sick_device_config.sick_peak_threshold) << std::endl;
1951  str_stream << "\tStop Thresh: " << (unsigned int)_sick_device_config.sick_stop_threshold << std::endl;
1952  }
1953 
1954  str_stream << "\tAvailability: " << _sickAvailabilityToString(_sick_device_config.sick_availability_level) << std::endl;
1955  str_stream << "\tMeasuring Mode: " << SickMeasuringModeToString((sick_lms_2xx_measuring_mode_t)_sick_device_config.sick_measuring_mode) << std::endl;
1956  str_stream << "\tMeasuring Units: " << SickMeasuringUnitsToString((sick_lms_2xx_measuring_units_t)_sick_device_config.sick_measuring_units) << std::endl;
1957  str_stream << "\tTemporary Field: " << _sickTemporaryFieldToString(_sick_device_config.sick_temporary_field) << std::endl;
1958  str_stream << "\tSubtractive Fields: " << _sickSubtractiveFieldsToString(_sick_device_config.sick_subtractive_fields) << std::endl;
1959  str_stream << "\tMultiple Evaluation: " << (unsigned int)_sick_device_config.sick_multiple_evaluation << std::endl;
1960  str_stream << "\tSuppressed Objects Multiple Evaluation: " << (unsigned int)_sick_device_config.sick_multiple_evaluation_suppressed_objects << std::endl;
1961  str_stream << "\tDazzling Multiple Evaluation: " << (unsigned int)_sick_device_config.sick_dazzling_multiple_evaluation << std::endl;
1962  str_stream << "\tRestart Mode: " << _sickRestartToString(_sick_device_config.sick_restart) << std::endl;
1963  str_stream << "\tRestart Time: " << (unsigned int)_sick_device_config.sick_restart_time << std::endl;
1964  str_stream << "\tFields B,C Restart Time: " << (unsigned int)_sick_device_config.sick_fields_b_c_restart_times << std::endl;
1965  str_stream << "\tContour Function A: " << _sickContourFunctionToString(_sick_device_config.sick_contour_a_reference) << std::endl;
1966  str_stream << "\tContour Function B: " << _sickContourFunctionToString(_sick_device_config.sick_contour_b_reference) << std::endl;
1967  str_stream << "\tContour Function C: " << _sickContourFunctionToString(_sick_device_config.sick_contour_c_reference) << std::endl;
1968  str_stream << "\tPixel Oriented Evaluation: " << (unsigned int)_sick_device_config.sick_pixel_oriented_evaluation << std::endl;
1969  str_stream << "\tSingle Measured Value Eval. Mode: " << (unsigned int)_sick_device_config.sick_single_measured_value_evaluation_mode << std::endl;
1970 
1971  }
1972  else {
1973 
1974  str_stream << "\t Unknown (Device is not initialized)" << std::endl;
1975 
1976  }
1977 
1978  str_stream << "\t===============================================" << std::endl;
1979 
1980  return str_stream.str();
1981  }
1982 
1987  std::cout << GetSickStatusAsString() << std::endl;
1988  }
1989 
1994  std::cout << GetSickSoftwareVersionAsString() << std::endl;
1995  }
1996 
2001  std::cout << GetSickConfigAsString() << std::endl;
2002  }
2003 
2009  std::string SickLMS2xx::SickTypeToString( const sick_lms_2xx_type_t sick_type ) {
2010 
2011  switch(sick_type) {
2013  return "Sick LMS 200-30106";
2015  return "Sick LMS 211-30106";
2017  return "Sick LMS 211-30206";
2018  case SICK_LMS_TYPE_211_S07:
2019  return "Sick LMS 211-S07";
2020  case SICK_LMS_TYPE_211_S14:
2021  return "Sick LMS 211-S14";
2022  case SICK_LMS_TYPE_211_S15:
2023  return "Sick LMS 211-S15";
2024  case SICK_LMS_TYPE_211_S19:
2025  return "Sick LMS 211-S19";
2026  case SICK_LMS_TYPE_211_S20:
2027  return "Sick LMS 211-S20";
2029  return "Sick LMS 220-30106";
2031  return "Sick LMS 221-30106";
2033  return "Sick LMS 221-30206";
2034  case SICK_LMS_TYPE_221_S07:
2035  return "Sick LMS 221-S07";
2036  case SICK_LMS_TYPE_221_S14:
2037  return "Sick LMS 221-S14";
2038  case SICK_LMS_TYPE_221_S15:
2039  return "Sick LMS 221-S15";
2040  case SICK_LMS_TYPE_221_S16:
2041  return "Sick LMS 221-S16";
2042  case SICK_LMS_TYPE_221_S19:
2043  return "Sick LMS 221-S19";
2044  case SICK_LMS_TYPE_221_S20:
2045  return "Sick LMS 221-S20";
2046  case SICK_LMS_TYPE_291_S05:
2047  return "Sick LMS 291-S05";
2048  case SICK_LMS_TYPE_291_S14:
2049  return "Sick LMS 291-S14";
2050  case SICK_LMS_TYPE_291_S15:
2051  return "Sick LMS 291-S15";
2052  default:
2053  return "Unknown!";
2054  }
2055 
2056  }
2057 
2063 
2064  switch(scan_angle_int) {
2065  case 90:
2066  return SICK_SCAN_ANGLE_90;
2067  case 100:
2068  return SICK_SCAN_ANGLE_100;
2069  case 180:
2070  return SICK_SCAN_ANGLE_180;
2071  default:
2072  return SICK_SCAN_ANGLE_UNKNOWN;
2073  }
2074 
2075  }
2076 
2082 
2083  switch(scan_resolution_int) {
2084  case 25:
2085  return SICK_SCAN_RESOLUTION_25;
2086  case 50:
2087  return SICK_SCAN_RESOLUTION_50;
2088  case 100:
2089  return SICK_SCAN_RESOLUTION_100;
2090  default:
2092  }
2093 
2094  }
2095 
2101  return IntToSickScanResolution((const int)(scan_resolution_double*100));
2102  }
2103 
2109  std::string SickLMS2xx::SickBaudToString( const sick_lms_2xx_baud_t baud_rate ) {
2110 
2111  switch(baud_rate) {
2112  case SICK_BAUD_9600:
2113  return "9600bps";
2114  case SICK_BAUD_19200:
2115  return "19200bps";
2116  case SICK_BAUD_38400:
2117  return "38400bps";
2118  case SICK_BAUD_500K:
2119  return "500Kbps";
2120  default:
2121  return "Unknown!";
2122  }
2123 
2124  }
2125 
2131 
2132  switch(baud_int) {
2133  case 9600:
2134  return SICK_BAUD_9600;
2135  case 19200:
2136  return SICK_BAUD_19200;
2137  case 38400:
2138  return SICK_BAUD_38400;
2139  case 500000:
2140  return SICK_BAUD_500K;
2141  default:
2142  return SICK_BAUD_UNKNOWN;
2143  }
2144 
2145  }
2146 
2151  sick_lms_2xx_baud_t SickLMS2xx::StringToSickBaud( const std::string baud_str ) {
2152 
2153  int baud_int;
2154  std::istringstream input_stream(baud_str);
2155  input_stream >> baud_int;
2156 
2157  return IntToSickBaud(baud_int);
2158 
2159  }
2160 
2166  std::string SickLMS2xx::SickStatusToString( const sick_lms_2xx_status_t sick_status ) {
2167 
2168  /* Return a string */
2169  if(sick_status != SICK_STATUS_OK) {
2170  return "Error (possibly fatal)";
2171  }
2172  return "OK!";
2173 
2174  }
2175 
2182 
2183  switch(sick_measuring_mode) {
2185  return "8m/80m; fields A,B,Dazzle";
2187  return "8m/80m; 3 reflector bits";
2189  return "8m/80m; fields A,B,C";
2191  return "16m; 4 reflector bits";
2192  case SICK_MS_MODE_16_FA_FB:
2193  return "16m; fields A & B";
2195  return "32m; 2 reflector bits";
2196  case SICK_MS_MODE_32_FA:
2197  return "32m; field A";
2199  return "32m; immediate";
2201  return "Reflectivity";
2202  default:
2203  return "Unknown";
2204  }
2205  }
2206 
2213 
2214  switch(sick_operating_mode) {
2216  return "Installation Mode";
2218  return "Diagnostic Mode";
2220  return "Stream mim measured values for each segment";
2222  return "Min measured value for each segment when object detected";
2224  return "Min vertical distance";
2226  return "Min vertical distance when object detected";
2228  return "Stream all measured values";
2230  return "Request measured values";
2232  return "Stream mean measured values";
2234  return "Stream measured value subrange";
2236  return "Stream mean measured value subrange";
2238  return "Stream measured and field values";
2240  return "Stream measured values from partial scan";
2242  return "Stream range w/ reflectivity from partial scan";
2244  return "Stream min measured values for each segment over a subrange";
2246  return "Output navigation data records";
2248  return "Stream range w/ reflectivity values";
2249  default:
2250  return "Unknown!";
2251  };
2252 
2253  }
2254 
2260  std::string SickLMS2xx::SickSensitivityToString( const sick_lms_2xx_sensitivity_t sick_sensitivity ) {
2261 
2262  switch(sick_sensitivity) {
2264  return "Standard (~30m @ 10% reflectivity)";
2266  return "Medium (~25m @ 10% reflectivity)";
2267  case SICK_SENSITIVITY_LOW:
2268  return "Low (~20m @ 10% relfectivity)";
2269  case SICK_SENSITIVITY_HIGH:
2270  return "High (~42m @ 10% reflectivity)";
2271  default:
2272  return "Unknown!";
2273  }
2274 
2275  }
2276 
2283 
2284  switch(sick_peak_threshold) {
2286  return "Peak detection, no black extension";
2288  return "Peak detection w/ black extension";
2290  return "No peak detection, no black extension";
2292  return "No peak detection w/ black extension";
2293  default:
2294  return "Unknown!";
2295  }
2296 
2297  }
2298 
2305 
2306  /* Return the proper string */
2307  switch(sick_units) {
2309  return "Centimeters (cm)";
2311  return "Millimeters (mm)";
2312  default:
2313  return "Unknown!";
2314  }
2315 
2316  }
2317 
2323  }
2324 
2329  void SickLMS2xx::_setupConnection( const uint32_t delay ) throw ( SickIOException, SickThreadException ) {
2330 
2331  try {
2332 
2333  /* Open the device */
2334  if((_sick_fd = open(_sick_device_path.c_str(), O_RDWR | O_NOCTTY | O_NDELAY)) < 0) {
2335  throw SickIOException("SickLMS2xx::_setupConnection: - Unable to open serial port");
2336  }
2337 
2338  // Sleep to allow the SICK to power on for some applications
2339  sleep(delay);
2340 
2341  /* Backup the original term settings */
2342  if(tcgetattr(_sick_fd,&_old_term) < 0) {
2343  throw SickIOException("SickLMS2xx::_setupConnection: tcgetattr() failed!");
2344  }
2345 
2346  /* Set the host terminal baud rate to the new speed */
2348 
2349  }
2350 
2351  /* Handle any I/O exceptions */
2352  catch(SickIOException &sick_io_exception) {
2353  std::cerr << sick_io_exception.what() << std::endl;
2354  throw;
2355  }
2356 
2357  /* Handle any thread exceptions */
2358  catch(SickThreadException &sick_thread_exception) {
2359  std::cerr << sick_thread_exception.what() << std::endl;
2360  throw;
2361  }
2362 
2363  /* Handle unknown exceptions */
2364  catch(...) {
2365  std::cerr << "SickLMS2xx::_setupConnection: Unknown exception!" << std::endl;
2366  throw;
2367  }
2368 
2369  }
2370 
2375 
2376  /* Check whether device was initialized */
2377  if(!_sick_initialized) {
2378  return;
2379  }
2380 
2381  /* Restore old terminal settings */
2382  if (tcsetattr(_sick_fd,TCSANOW,&_old_term) < 0) {
2383  throw SickIOException("SickLMS2xx::_teardownConnection: tcsetattr() failed!");
2384  }
2385 
2386  /* Actually close the device */
2387  if(close(_sick_fd) != 0) {
2388  throw SickIOException("SickLMS2xx::_teardownConnection: close() failed!");
2389  }
2390 
2391  }
2392 
2397 
2398  try {
2399 
2400  /* Acquire access to the data stream */
2402 
2403  /* Nobody is reading a message, so safely flush! */
2404  if (tcflush(_sick_fd,TCIOFLUSH) != 0) {
2405  throw SickThreadException("SickLMS2xx::_flushTerminalBuffer: tcflush() failed!");
2406  }
2407 
2408  /* Attempt to release the data stream */
2410 
2411  }
2412 
2413  /* Handle thread exceptions */
2414  catch(SickThreadException &sick_thread_exception) {
2415  std::cerr << sick_thread_exception.what() << std::endl;
2416  throw;
2417  }
2418 
2419  /* A sanity check */
2420  catch(...) {
2421  std::cerr << "SickLMS2xx::_flushTerminalBuffer: Unknown exception!" << std::endl;
2422  throw;
2423  }
2424 
2425  }
2426 
2438  SickLMS2xxMessage &recv_message,
2439  const unsigned int timeout_value,
2440  const unsigned int num_tries ) throw( SickIOException, SickThreadException, SickTimeoutException ) {
2441 
2442  uint8_t sick_reply_code = send_message.GetCommandCode() + 0x80;
2443 
2444  try {
2445 
2446  /* Send a message and get reply using a reply code */
2447  _sendMessageAndGetReply(send_message,recv_message,sick_reply_code,timeout_value,num_tries);
2448 
2449  }
2450 
2451  /* Handle a timeout! */
2452  catch (SickTimeoutException &sick_timeout) {
2453  /* For now just rethrow it */
2454  throw;
2455  }
2456 
2457  /* Handle a thread exception */
2458  catch (SickThreadException &sick_thread_exception) {
2459  std::cerr << sick_thread_exception.what() << std::endl;
2460  throw;
2461  }
2462 
2463  /* Handle write buffer exceptions */
2464  catch (SickIOException &sick_io_error) {
2465  std::cerr << sick_io_error.what() << std::endl;
2466  throw;
2467  }
2468 
2469  /* A safety net */
2470  catch (...) {
2471  std::cerr << "SickLMS2xx::_sendMessageAndGetReply: Unknown exception!!!" << std::endl;
2472  throw;
2473  }
2474 
2475  }
2476 
2486  SickLMS2xxMessage &recv_message,
2487  const uint8_t reply_code,
2488  const unsigned int timeout_value,
2489  const unsigned int num_tries ) throw( SickIOException, SickThreadException, SickTimeoutException ) {
2490 
2491  try {
2492 
2493  /* Attempt to flush the terminal buffer */
2495 
2496  /* Send a message and get reply using parent's method */
2498 
2499  }
2500 
2501  /* Handle a timeout! */
2502  catch (SickTimeoutException &sick_timeout) {
2503  throw;
2504  }
2505 
2506  /* Handle a thread exception */
2507  catch (SickThreadException &sick_thread_exception) {
2508  std::cerr << sick_thread_exception.what() << std::endl;
2509  throw;
2510  }
2511 
2512  /* Handle write buffer exceptions */
2513  catch (SickIOException &sick_io_error) {
2514  std::cerr << sick_io_error.what() << std::endl;
2515  throw;
2516  }
2517 
2518  /* A safety net */
2519  catch (...) {
2520  std::cerr << "SickLMS2xx::_sendMessageAndGetReply: Unknown exception!!!" << std::endl;
2521  throw;
2522  }
2523 
2524  }
2525 
2531 
2532  SickLMS2xxMessage message, response;
2533 
2534  uint8_t payload[SickLMS2xxMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
2535 
2536  /* Another sanity check */
2537  if(baud_rate == SICK_BAUD_UNKNOWN) {
2538  throw SickIOException("SickLMS2xx::_setSessionBaud: Undefined baud rate!");
2539  }
2540 
2541  /* Construct the command telegram */
2542  payload[0] = 0x20;
2543  payload[1] = baud_rate;
2544 
2546 
2547  try {
2548 
2549  /* Send the status request and get a reply */
2551 
2552  /* Set the host terminal baud rate to the new speed */
2553  _setTerminalBaud(baud_rate);
2554 
2555  /* Sick likes a sleep here */
2556  usleep(250000);
2557 
2558  }
2559 
2560  /* Catch a timeout */
2561  catch(SickTimeoutException &sick_timeout_exception) {
2562  std::cerr << sick_timeout_exception.what() << std::endl;
2563  throw;
2564  }
2565 
2566  /* Catch any I/O exceptions */
2567  catch(SickIOException &sick_io_exception) {
2568  std::cerr << sick_io_exception.what() << std::endl;
2569  throw;
2570  }
2571 
2572  /* Catch any thread exceptions */
2573  catch(SickThreadException &sick_thread_exception) {
2574  std::cerr << sick_thread_exception.what() << std::endl;
2575  throw;
2576  }
2577 
2578  /* Catch anything else */
2579  catch(...) {
2580  std::cerr << "SickLMS2xx::_getSickErrors: Unknown exception!!!" << std::endl;
2581  throw;
2582  }
2583 
2584  }
2585 
2591 
2592  try {
2593 
2594  /* Another sanity check */
2595  if(baud_rate == SICK_BAUD_UNKNOWN) {
2596  throw SickIOException("SickLMS2xx::_testBaudRate: Undefined baud rate!");
2597  }
2598 
2599  /* Attempt to get status information at the current baud */
2600  std::cout << "\t\tChecking " << SickBaudToString(baud_rate) << "..." << std::endl;
2601 
2602  /* Set the host terminal baud rate to the test speed */
2603  _setTerminalBaud(baud_rate);
2604 
2605  try {
2606 
2607  /* Check to see if the Sick replies! */
2608  _getSickErrors();
2609 
2610  }
2611 
2612  /* Catch a timeout exception */
2613  catch(SickTimeoutException &sick_timeout_exception) {
2614  /* This means that the current baud rate timed out! */
2615  return false;
2616  }
2617 
2618  /* Catch anything else and throw it away */
2619  catch(...) {
2620  std::cerr << "SickLMS2xx::_testBaudRate: Unknown exception!" << std::endl;
2621  throw;
2622  }
2623 
2624  }
2625 
2626  /* Handle any IO exceptions */
2627  catch(SickIOException &sick_io_exception) {
2628  std::cerr << sick_io_exception.what() << std::endl;
2629  throw;
2630  }
2631 
2632  /* Handle thread exceptions */
2633  catch(SickThreadException &sick_thread_exception) {
2634  std::cerr << sick_thread_exception.what() << std::endl;
2635  throw;
2636  }
2637 
2638  /* A safety net */
2639  catch(...) {
2640  std::cerr << "SickLMS2xx::_testBaudRate: Unknown exception!!!" << std::endl;
2641  throw;
2642  }
2643 
2644  /* Success! */
2645  return true;
2646 
2647  }
2648 
2654 
2655  struct termios term;
2656 
2657 #ifdef HAVE_LINUX_SERIAL_H
2658  struct serial_struct serial;
2659 #endif
2660 
2661  try {
2662 
2663  /* If seeting baud to 500k */
2664  if (baud_rate == SICK_BAUD_500K) {
2665 
2666 #ifdef HAVE_LINUX_SERIAL_H
2667 
2668  /* Get serial attributes */
2669  if(ioctl(_sick_fd,TIOCGSERIAL,&serial) < 0) {
2670  throw SickIOException("SickLMS2xx::_setTerminalBaud: ioctl() failed!");
2671  }
2672 
2673  /* Set the custom devisor */
2674  serial.flags |= ASYNC_SPD_CUST;
2675  serial.custom_divisor = 48; // for FTDI USB/serial converter divisor is 240/5
2676 
2677  /* Set the new attibute values */
2678  if(ioctl(_sick_fd,TIOCSSERIAL,&serial) < 0) {
2679  throw SickIOException("SickLMS2xx::_setTerminalBaud: ioctl() failed!");
2680  }
2681 
2682 #else
2683  throw SickIOException("SickLMS2xx::_setTerminalBaud - 500K baud is only supported under Linux!");
2684 #endif
2685 
2686  }
2687 
2688 #ifdef HAVE_LINUX_SERIAL_H
2689 
2690  else { /* Using a standard baud rate */
2691 
2692  /* We let the next few errors slide in case USB adapter is being used */
2693  if(ioctl(_sick_fd,TIOCGSERIAL,&serial) < 0) {
2694  std::cerr << "SickLMS2xx::_setTermSpeed: ioctl() failed while trying to get serial port info!" << std::endl;
2695  std::cerr << "\tNOTE: This is normal when connected via USB!" <<std::endl;
2696  }
2697 
2698  serial.custom_divisor = 0;
2699  serial.flags &= ~ASYNC_SPD_CUST;
2700 
2701  if(ioctl(_sick_fd,TIOCSSERIAL,&serial) < 0) {
2702  std::cerr << "SickLMS2xx::_setTerminalBaud: ioctl() failed while trying to set serial port info!" << std::endl;
2703  std::cerr << "\tNOTE: This is normal when connected via USB!" <<std::endl;
2704  }
2705 
2706  }
2707 
2708 #endif
2709 
2710  /* Attempt to acquire device attributes */
2711  if(tcgetattr(_sick_fd,&term) < 0) {
2712  throw SickIOException("SickLMS2xx::_setTerminalBaud: Unable to get device attributes!");
2713  }
2714 
2715  /* Switch on the baud rate */
2716  switch(baud_rate) {
2717  case SICK_BAUD_9600: {
2718  cfmakeraw(&term);
2719  cfsetispeed(&term,B9600);
2720  cfsetospeed(&term,B9600);
2721  break;
2722  }
2723  case SICK_BAUD_19200: {
2724  cfmakeraw(&term);
2725  cfsetispeed(&term,B19200);
2726  cfsetospeed(&term,B19200);
2727  break;
2728  }
2729  case SICK_BAUD_38400: {
2730  cfmakeraw(&term);
2731  cfsetispeed(&term,B38400);
2732  cfsetospeed(&term,B38400);
2733  break;
2734  }
2735  case SICK_BAUD_500K: {
2736  cfmakeraw(&term);
2737  cfsetispeed(&term,B38400);
2738  cfsetospeed(&term,B38400);
2739  break;
2740  }
2741  default:
2742  throw SickIOException("SickLMS2xx::_setTerminalBaud: Unknown baud rate!");
2743  }
2744 
2745  /* Attempt to set the device attributes */
2746  if(tcsetattr(_sick_fd,TCSAFLUSH,&term) < 0 ) {
2747  throw SickIOException("SickLMS2xx::_setTerminalBaud: Unable to set device attributes!");
2748  }
2749 
2750  /* Buffer the rate locally */
2751  _curr_session_baud = baud_rate;
2752 
2753  /* Attempt to flush the I/O buffers */
2755 
2756  } // try
2757 
2758  /* Catch an IO exception */
2759  catch(SickIOException sick_io_exception) {
2760  std::cerr << sick_io_exception.what() << std::endl;
2761  throw;
2762  }
2763 
2764  /* Catch an IO exception */
2765  catch(SickThreadException sick_thread_exception) {
2766  std::cerr << sick_thread_exception.what() << std::endl;
2767  throw;
2768  }
2769 
2770  /* A sanity check */
2771  catch(...) {
2772  std::cerr << "SickLMS2xx::_setTerminalBaud: Unknown exception!!!" << std::endl;
2773  throw;
2774  }
2775 
2776  }
2777 
2782 
2783  SickLMS2xxMessage message,response;
2784 
2785  int payload_length;
2786  uint8_t payload_buffer[SickLMS2xxMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
2787 
2788  /* Get the LMS type */
2789  payload_buffer[0] = 0x3A; //Command to request LMS type
2790 
2791  /* Build the message */
2792  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,1);
2793 
2794  try {
2795 
2796  /* Send the status request and get a reply */
2798 
2799  }
2800 
2801  /* Catch any timeout exceptions */
2802  catch(SickTimeoutException &sick_timeout_exception) {
2803  std::cerr << sick_timeout_exception.what() << std::endl;
2804  throw;
2805  }
2806 
2807  /* Catch any I/O exceptions */
2808  catch(SickIOException &sick_io_exception) {
2809  std::cerr << sick_io_exception.what() << std::endl;
2810  throw;
2811  }
2812 
2813  /* Catch any thread exceptions */
2814  catch(SickThreadException &sick_thread_exception) {
2815  std::cerr << sick_thread_exception.what() << std::endl;
2816  throw;
2817  }
2818 
2819  /* Catch anything else */
2820  catch(...) {
2821  std::cerr << "SickLMS2xx::_getSickType: Unknown exception!!!" << std::endl;
2822  throw;
2823  }
2824 
2825  /* Reset the buffer */
2826  memset(payload_buffer,0,1);
2827 
2828  /* Get the payload */
2829  response.GetPayload(payload_buffer);
2830 
2831  /* Acquire the payload length */
2832  payload_length = response.GetPayloadLength();
2833 
2834  /* Dynamically allocate the string length */
2835  char * string_buffer = new char[payload_length-1];
2836 
2837  /* Initialize the buffer */
2838  memset(string_buffer,0,payload_length-1);
2839  memcpy(string_buffer,&payload_buffer[1],payload_length-2);
2840 
2841  /* Convert to a standard string */
2842  std::string type_string = string_buffer;
2843 
2844  /* Set the Sick LMS type in the driver */
2845  if(type_string.find("LMS200;30106") != std::string::npos) {
2847  } else if(type_string.find("LMS211;30106") != std::string::npos) {
2849  } else if(type_string.find("LMS211;30206") != std::string::npos) {
2851  } else if(type_string.find("LMS211;S07") != std::string::npos) {
2853  } else if(type_string.find("LMS211;S14") != std::string::npos) {
2855  } else if(type_string.find("LMS211;S15") != std::string::npos) {
2857  } else if(type_string.find("LMS211;S19") != std::string::npos) {
2859  } else if(type_string.find("LMS211;S20") != std::string::npos) {
2861  } else if(type_string.find("LMS220;30106") != std::string::npos) {
2863  } else if(type_string.find("LMS221;30106") != std::string::npos) {
2865  } else if(type_string.find("LMS221;30206") != std::string::npos) {
2867  } else if(type_string.find("LMS221;S07") != std::string::npos) {
2869  } else if(type_string.find("LMS221;S14") != std::string::npos) {
2871  } else if(type_string.find("LMS221;S15") != std::string::npos) {
2873  } else if(type_string.find("LMS221;S16") != std::string::npos) {
2875  } else if(type_string.find("LMS221;S19") != std::string::npos) {
2877  } else if(type_string.find("LMS221;S20") != std::string::npos) {
2879  } else if(type_string.find("LMS291;S05") != std::string::npos) {
2881  } else if(type_string.find("LMS291;S14") != std::string::npos) {
2883  } else if(type_string.find("LMS291;S15") != std::string::npos) {
2885  } else {
2887  }
2888 
2889  /* Reclaim the allocated string buffer */
2890  if (string_buffer) {
2891  delete [] string_buffer;
2892  }
2893 
2894  }
2895 
2900 
2901  SickLMS2xxMessage message, response;
2902 
2903  uint8_t payload_buffer[SickLMS2xxMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
2904 
2905  /* Set the command code */
2906  payload_buffer[0] = 0x74;
2907 
2908  /* Build the request message */
2909  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,1);
2910 
2911  try {
2912 
2913  /* Send the status request and get a reply */
2915 
2916  }
2917 
2918  /* Catch any timeout exceptions */
2919  catch(SickTimeoutException &sick_timeout_exception) {
2920  std::cerr << sick_timeout_exception.what() << std::endl;
2921  throw;
2922  }
2923 
2924  /* Catch any I/O exceptions */
2925  catch(SickIOException &sick_io_exception) {
2926  std::cerr << sick_io_exception.what() << std::endl;
2927  throw;
2928  }
2929 
2930  /* Catch any thread exceptions */
2931  catch(SickThreadException &sick_thread_exception) {
2932  std::cerr << sick_thread_exception.what() << std::endl;
2933  throw;
2934  }
2935 
2936  /* Catch anything else */
2937  catch(...) {
2938  std::cerr << "SickLMS2xx::_getSickConfig: Unknown exception!!!" << std::endl;
2939  throw;
2940  }
2941 
2942  /* Reset the payload buffer */
2943  payload_buffer[0] = 0;
2944 
2945  /* Extract the payload */
2946  response.GetPayload(payload_buffer);
2947 
2948  /* Obtain the configuration results */
2949  _parseSickConfigProfile(&payload_buffer[1],_sick_device_config);
2950 
2951  }
2952 
2959 
2960  try {
2961 
2962  std::cout << "\tAttempting to configure the device (this can take a few seconds)..." << std::endl;
2963 
2964  /* Attempt to set the Sick into installation mode */
2966 
2967  /* Define our message objects */
2968  SickLMS2xxMessage message, response;
2969  uint8_t payload_buffer[SickLMS2xxMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
2970 
2971  /* Set the command code */
2972  payload_buffer[0] = 0x77; // Command to configure device
2973 
2974  /*
2975  * Build the corresponding config message
2976  */
2977 
2978  /* Set Block A */
2979  uint16_t temp_buffer = host_to_sick_lms_2xx_byte_order(sick_device_config.sick_blanking);
2980  memcpy(&payload_buffer[1],&temp_buffer,2);
2981 
2982  /* Set Block B */
2983  payload_buffer[3] = sick_device_config.sick_stop_threshold; // NOTE: This value will be 0 for LMS 211/221/291
2984  payload_buffer[4] = sick_device_config.sick_peak_threshold; // NOTE: This value is equivalent to sensitivity field on 211/221/291
2985 
2986  /* Set Block C */
2987  payload_buffer[5] = sick_device_config.sick_availability_level;
2988 
2989  /* Set Block D */
2990  payload_buffer[6] = sick_device_config.sick_measuring_mode;
2991 
2992  /* Set Block E */
2993  payload_buffer[7] = sick_device_config.sick_measuring_units;
2994 
2995  /* Set Block F */
2996  payload_buffer[8] = sick_device_config.sick_temporary_field;
2997 
2998  /* Set Block G */
2999  payload_buffer[9] = sick_device_config.sick_subtractive_fields;
3000 
3001  /* Set Block H */
3002  payload_buffer[10] = sick_device_config.sick_multiple_evaluation;
3003 
3004  /* Set Block I */
3005  payload_buffer[11] = sick_device_config.sick_restart;
3006 
3007  /* Set Block J */
3008  payload_buffer[12] = sick_device_config.sick_restart_time;
3009 
3010  /* Set Block K */
3011  payload_buffer[13] = sick_device_config.sick_multiple_evaluation_suppressed_objects;
3012 
3013  /* Set Block L */
3014  payload_buffer[14] = sick_device_config.sick_contour_a_reference;
3015 
3016  /* Set Block M */
3017  payload_buffer[15] = sick_device_config.sick_contour_a_positive_tolerance_band;
3018 
3019  /* Set Block N */
3020  payload_buffer[16] = sick_device_config.sick_contour_a_negative_tolerance_band;
3021 
3022  /* Set Block O */
3023  payload_buffer[17] = sick_device_config.sick_contour_a_start_angle;
3024 
3025  /* Set Block P */
3026  payload_buffer[18] = sick_device_config.sick_contour_a_stop_angle;
3027 
3028  /* Set Block Q */
3029  payload_buffer[19] = sick_device_config.sick_contour_b_reference;
3030 
3031  /* Set Block R */
3032  payload_buffer[20] = sick_device_config.sick_contour_b_positive_tolerance_band;
3033 
3034  /* Set Block S */
3035  payload_buffer[21] = sick_device_config.sick_contour_b_negative_tolerance_band;
3036 
3037  /* Set Block T */
3038  payload_buffer[22] = sick_device_config.sick_contour_b_start_angle;
3039 
3040  /* Set Block U */
3041  payload_buffer[23] = sick_device_config.sick_contour_b_stop_angle;
3042 
3043  /* Set Block V */
3044  payload_buffer[24] = sick_device_config.sick_contour_c_reference;
3045 
3046  /* Set Block W */
3047  payload_buffer[25] = sick_device_config.sick_contour_c_positive_tolerance_band;
3048 
3049  /* Set Block X */
3050  payload_buffer[26] = sick_device_config.sick_contour_c_negative_tolerance_band;
3051 
3052  /* Set Block Y */
3053  payload_buffer[27] = sick_device_config.sick_contour_c_start_angle;
3054 
3055  /* Set Block Z */
3056  payload_buffer[28] = sick_device_config.sick_contour_c_stop_angle;
3057 
3058  /* Set Block A1 */
3059  payload_buffer[29] = sick_device_config.sick_pixel_oriented_evaluation;
3060 
3061  /* Set Block A2 */
3062  payload_buffer[30] = sick_device_config.sick_single_measured_value_evaluation_mode;
3063 
3064  /* Set Block A3 */
3065  temp_buffer = host_to_sick_lms_2xx_byte_order(sick_device_config.sick_fields_b_c_restart_times);
3066  memcpy(&payload_buffer[31],&temp_buffer,2);
3067 
3068  /* Set Block A4 */
3069  temp_buffer = host_to_sick_lms_2xx_byte_order(sick_device_config.sick_dazzling_multiple_evaluation);
3070  memcpy(&payload_buffer[33],&temp_buffer,2);
3071 
3072  /* Populate the message container */
3073  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,35);
3074 
3075  /* Send the status request and get a reply */
3077 
3078  /* Reset the payload buffer */
3079  memset(payload_buffer,0,35);
3080 
3081  /* Extract the payload contents */
3082  response.GetPayload(payload_buffer);
3083 
3084  /* Check whether the configuration was successful */
3085  if (payload_buffer[1] != 0x01) {
3086  throw SickConfigException("SickLMS2xx::_setSickConfig: Configuration failed!");
3087  }
3088 
3089  /* Success */
3090  std::cout << "\t\tConfiguration successful! :o)" << std::endl;
3091 
3092  /* Update the local configuration data */
3093  _parseSickConfigProfile(&payload_buffer[2],_sick_device_config);
3094 
3095  /* Set the device back to request range mode */
3097 
3098  /* Refresh the status info! */
3099  _getSickStatus();
3100 
3101  }
3102 
3103  /* Catch any timeout exceptions */
3104  catch(SickTimeoutException &sick_timeout_exception) {
3105  std::cerr << sick_timeout_exception.what() << std::endl;
3106  throw;
3107  }
3108 
3109  /* Catch any config exceptions */
3110  catch(SickConfigException &sick_config_exception) {
3111  std::cerr << sick_config_exception.what() << std::endl;
3112  throw;
3113  }
3114 
3115  /* Catch any I/O exceptions */
3116  catch(SickIOException &sick_io_exception) {
3117  std::cerr << sick_io_exception.what() << std::endl;
3118  throw;
3119  }
3120 
3121  /* Catch any thread exceptions */
3122  catch(SickThreadException &sick_thread_exception) {
3123  std::cerr << sick_thread_exception.what() << std::endl;
3124  throw;
3125  }
3126 
3127  /* Catch anything else */
3128  catch(...) {
3129  std::cerr << "SickLMS2xx::_setSickConfig: Unknown exception!" << std::endl;
3130  throw;
3131  }
3132 
3133  }
3134 
3138  void SickLMS2xx::_getSickErrors( unsigned int * const num_sick_errors, uint8_t * const error_type_buffer,
3139  uint8_t * const error_num_buffer ) throw( SickTimeoutException, SickIOException, SickThreadException ) {
3140 
3141  SickLMS2xxMessage message, response;
3142 
3143  int payload_length;
3144  uint8_t payload_buffer[SickLMS2xxMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
3145 
3146  /* The command to request LMS status */
3147  payload_buffer[0] = 0x32;
3148 
3149  /* Build the request message */
3150  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,1);
3151 
3152  try {
3153 
3154  /* Send the status request and get a reply */
3156 
3157  }
3158 
3159  /* Catch any timeout exceptions */
3160  catch(SickTimeoutException &sick_timeout_exception) {
3161  std::cerr << sick_timeout_exception.what() << std::endl;
3162  throw;
3163  }
3164 
3165  /* Catch any I/O exceptions */
3166  catch(SickIOException &sick_io_exception) {
3167  std::cerr << sick_io_exception.what() << std::endl;
3168  throw;
3169  }
3170 
3171  /* Catch any thread exceptions */
3172  catch(SickThreadException &sick_thread_exception) {
3173  std::cerr << sick_thread_exception.what() << std::endl;
3174  throw;
3175  }
3176 
3177  /* Catch anything else */
3178  catch(...) {
3179  std::cerr << "SickLMS2xx::_getSickErrors: Unknown exception!!!" << std::endl;
3180  throw;
3181  }
3182 
3183  /* Extract the payload_length */
3184  payload_length = response.GetPayloadLength();
3185 
3186  /* Compute the number of errors */
3187  double num_errors = ((payload_length-2)/((double)2));
3188 
3189  /* Assign the number of errors if necessary */
3190  if (num_sick_errors) {
3191  *num_sick_errors = (unsigned int)num_errors;
3192  }
3193 
3194  /* Populate the return buffers with the error data */
3195  for (unsigned int i = 0, k = 1; i < (unsigned int)num_errors && (error_type_buffer || error_num_buffer); i++) {
3196 
3197  /* Check if the error type has been requested */
3198  if (error_type_buffer) {
3199  error_type_buffer[i] = payload_buffer[k];
3200  }
3201  k++;
3202 
3203  /* Check if the error number has been requested */
3204  if (error_num_buffer) {
3205  error_num_buffer[i] = payload_buffer[k];
3206  }
3207  k++;
3208 
3209  }
3210 
3211  }
3212 
3217 
3218  SickLMS2xxMessage message,response;
3219 
3220  uint8_t payload_buffer[SickLMS2xxMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
3221 
3222  /* The command to request LMS status */
3223  payload_buffer[0] = 0x31;
3224 
3225  /* Build the request message */
3226  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,1);
3227 
3228  try {
3229 
3230  /* Send the status request and get a reply */
3232 
3233  }
3234 
3235  /* Catch any timeout exceptions */
3236  catch(SickTimeoutException &sick_timeout_exception) {
3237  std::cerr << sick_timeout_exception.what() << std::endl;
3238  throw;
3239  }
3240 
3241  /* Catch any I/O exceptions */
3242  catch(SickIOException &sick_io_exception) {
3243  std::cerr << sick_io_exception.what() << std::endl;
3244  throw;
3245  }
3246 
3247  /* Catch any thread exceptions */
3248  catch(SickThreadException &sick_thread_exception) {
3249  std::cerr << sick_thread_exception.what() << std::endl;
3250  throw;
3251  }
3252 
3253  /* Catch anything else */
3254  catch(...) {
3255  std::cerr << "SickLMS2xx::_getSickStatus: Unknown exception!" << std::endl;
3256  throw;
3257  }
3258 
3259  /* Reset the payload buffer */
3260  payload_buffer[0] = 0;
3261 
3262  /* Extract the payload contents */
3263  response.GetPayload(payload_buffer);
3264 
3265  /*
3266  * Extract the current Sick LMS operating config
3267  */
3268 
3269  /* Buffer the Sick LMS operating mode */
3270  _sick_operating_status.sick_operating_mode = payload_buffer[8];
3271 
3272  /* Buffer the status code */
3274 
3275  /* Buffer the number of motor revolutions */
3276  memcpy(&_sick_operating_status.sick_num_motor_revs,&payload_buffer[67],2);
3278 
3279  /* Buffer the measuring mode of the device */
3280  _sick_operating_status.sick_measuring_mode = payload_buffer[102];
3281 
3282  /* Buffer the scan angle of the device */
3283  memcpy(&_sick_operating_status.sick_scan_angle,&payload_buffer[107],2);
3286 
3287  /* Buffer the angular resolution of the device */
3288  memcpy(&_sick_operating_status.sick_scan_resolution,&payload_buffer[109],2);
3291 
3292  /* Buffer the variant type */
3293  _sick_operating_status.sick_variant = payload_buffer[18];
3294 
3295  /* Buffer the Sick LMS address */
3296  _sick_operating_status.sick_address = payload_buffer[120];
3297 
3298  /* Buffer the current measured value unit */
3299  _sick_operating_status.sick_measuring_units = payload_buffer[122];
3300 
3301  /* Buffer the laser switch flag */
3302  _sick_operating_status.sick_laser_mode = payload_buffer[123];
3303 
3304 
3305  /*
3306  * Extract the current Sick LMS software config
3307  */
3308 
3309  /* Buffer the software version string */
3310  memcpy(_sick_software_status.sick_system_software_version,&payload_buffer[1],7);
3311 
3312  /* Buffer the boot prom software version */
3313  memcpy(_sick_software_status.sick_prom_software_version,&payload_buffer[124],7);
3314 
3315  /*
3316  * Extract the Sick LMS restart config
3317  */
3318 
3319  /* Buffer the restart mode of the device */
3320  _sick_restart_status.sick_restart_mode = payload_buffer[111];
3321 
3322  /* Buffer the restart time of the device */
3323  memcpy(&_sick_restart_status.sick_restart_time,&payload_buffer[112],2);
3326 
3327  /*
3328  * Extract the Sick LMS pollution status
3329  */
3330 
3331  /* Buffer the pollution values */
3332  for (unsigned int i = 0, k = 19; i < 8; i++, k+=2) {
3333  memcpy(&_sick_pollution_status.sick_pollution_vals[i],&payload_buffer[k],2);
3336  }
3337 
3338  /* Buffer the reference pollution values */
3339  for (unsigned int i = 0, k = 35; i < 4; i++, k+=2) {
3340  memcpy(&_sick_pollution_status.sick_reference_pollution_vals[i],&payload_buffer[k],2);
3343  }
3344 
3345  /* Buffer the calibrating pollution values */
3346  for (unsigned int i = 0, k = 43; i < 8; i++, k+=2) {
3347  memcpy(&_sick_pollution_status.sick_pollution_calibration_vals[i],&payload_buffer[k],2);
3350  }
3351 
3352  /* Buffer the calibrating reference pollution values */
3353  for (unsigned int i = 0, k = 59; i < 4; i++, k+=2) {
3354  memcpy(&_sick_pollution_status.sick_reference_pollution_calibration_vals[i],&payload_buffer[k],2);
3357  }
3358 
3359  /*
3360  * Extract the Sick LMS signal config
3361  */
3362 
3363  /* Buffer the reference scale 1 value (Dark signal 100%) */
3364  memcpy(&_sick_signal_status.sick_reference_scale_1_dark_100,&payload_buffer[71],2);
3367 
3368  /* Buffer the reference scale 2 value (Dark signal 100%) */
3369  memcpy(&_sick_signal_status.sick_reference_scale_2_dark_100,&payload_buffer[75],2);
3372 
3373  /* Buffer the reference scale 1 value (Dark signal 66%) */
3374  memcpy(&_sick_signal_status.sick_reference_scale_1_dark_66,&payload_buffer[77],2);
3377 
3378  /* Buffer the reference scale 2 value (Dark signal 100%) */
3379  memcpy(&_sick_signal_status.sick_reference_scale_2_dark_66,&payload_buffer[81],2);
3382 
3383  /* Buffer the signal amplitude */
3384  memcpy(&_sick_signal_status.sick_signal_amplitude,&payload_buffer[83],2);
3387 
3388  /* Buffer the angle used for power measurement */
3389  memcpy(&_sick_signal_status.sick_current_angle,&payload_buffer[85],2);
3392 
3393  /* Buffer the peak threshold value */
3394  memcpy(&_sick_signal_status.sick_peak_threshold,&payload_buffer[87],2);
3397 
3398  /* Buffer the angle used for reference target power measurement */
3399  memcpy(&_sick_signal_status.sick_angle_of_measurement,&payload_buffer[89],2);
3402 
3403  /* Buffer the signal amplitude calibration value */
3404  memcpy(&_sick_signal_status.sick_signal_amplitude_calibration_val,&payload_buffer[91],2);
3407 
3408  /* Buffer the target value of stop threshold */
3409  memcpy(&_sick_signal_status.sick_stop_threshold_target_value,&payload_buffer[93],2);
3412 
3413  /* Buffer the target value of peak threshold */
3414  memcpy(&_sick_signal_status.sick_peak_threshold_target_value,&payload_buffer[95],2);
3417 
3418  /* Buffer the actual value of stop threshold */
3419  memcpy(&_sick_signal_status.sick_stop_threshold_actual_value,&payload_buffer[97],2);
3422 
3423  /* Buffer the actual value of peak threshold */
3424  memcpy(&_sick_signal_status.sick_peak_threshold_actual_value,&payload_buffer[99],2);
3427 
3428  /* Buffer reference target "single measured values" */
3429  memcpy(&_sick_signal_status.sick_reference_target_single_measured_vals,&payload_buffer[103],2);
3432 
3433  /* Buffer reference target "mean measured values" */
3434  memcpy(&_sick_signal_status.sick_reference_target_mean_measured_vals,&payload_buffer[105],2);
3437 
3438 
3439  /*
3440  * Extract the Sick LMS field config
3441  */
3442 
3443  /* Buffer the offset for multiple evaluations of field set 2 */
3445 
3446  /* Buffer the evaluation number */
3447  _sick_field_status.sick_field_evaluation_number = payload_buffer[118];
3448 
3449  /* Buffer the active field set number */
3450  _sick_field_status.sick_field_set_number = payload_buffer[121];
3451 
3452 
3453  /*
3454  * Extract the Sick LMS baud config
3455  */
3456 
3457  /* Buffer the permanent baud rate flag */
3458  _sick_baud_status.sick_permanent_baud_rate = payload_buffer[119];
3459 
3460  /* Buffer the baud rate of the device */
3461  memcpy(&_sick_baud_status.sick_baud_rate,&payload_buffer[116],2);
3464 
3465  /* Buffer calibration value 1 for counter 0 */
3466  //memcpy(&_sick_status_data.sick_calibration_counter_0_value_1,&payload_buffer[131],4);
3467  //_sick_status_data.sick_calibration_counter_0_value_1 =
3468  // sick_lms_2xx_to_host_byte_order(_sick_status_data.sick_calibration_counter_0_value_1);
3469 
3470  /* Buffer calibration value 2 for counter 0 */
3471  //memcpy(&_sick_status_data.sick_calibration_counter_0_value_2,&payload_buffer[135],4);
3472  //_sick_status_data.sick_calibration_counter_0_value_2 =
3473  // sick_lms_2xx_to_host_byte_order(_sick_status_data.sick_calibration_counter_0_value_2);
3474 
3475  /* Buffer calibration value 1 for counter 1 */
3476  //memcpy(&_sick_status_data.sick_calibration_counter_1_value_1,&payload_buffer[139],4);
3477  //_sick_status_data.sick_calibration_counter_1_value_1 =
3478  // sick_lms_2xx_to_host_byte_order(_sick_status_data.sick_calibration_counter_1_value_1);
3479 
3480  /* Buffer calibration value 2 for counter 1 */
3481  //memcpy(&_sick_status_data.sick_calibration_counter_1_value_2,&payload_buffer[143],4);
3482  //_sick_status_data.sick_calibration_counter_1_value_2 =
3483  // sick_lms_2xx_to_host_byte_order(_sick_status_data.sick_calibration_counter_1_value_2);
3484 
3485  /* Buffer M0 value counter 0 */
3486  //memcpy(&_sick_status_data.sick_counter_0_M0,&payload_buffer[147],2);
3487  //_sick_status_data.sick_counter_0_M0 = sick_lms_2xx_to_host_byte_order(_sick_status_data.sick_counter_0_M0);
3488 
3489  /* Buffer M0 value counter 1 */
3490  //memcpy(&_sick_status_data.sick_counter_1_M0,&payload_buffer[149],2);
3491  //_sick_status_data.sick_counter_1_M0 = sick_lms_2xx_to_host_byte_order(_sick_status_data.sick_counter_1_M0);
3492 
3493  /* Buffer calibration interval */
3494  //memcpy(&_sick_status_data.sick_calibration_interval,&payload_buffer[151],2);
3495  //_sick_status_data.sick_calibration_interval = sick_lms_2xx_to_host_byte_order(_sick_status_data.sick_calibration_interval);
3496 
3497  }
3498 
3504 
3505  /* Assign the password for entering installation mode */
3506  uint8_t sick_password[9] = DEFAULT_SICK_LMS_2XX_SICK_PASSWORD;
3507 
3508  /* Check if mode should be changed */
3510 
3511  try {
3512 
3513  /* Attempt to switch modes! */
3515 
3516  }
3517 
3518  /* Catch any config exceptions */
3519  catch(SickConfigException &sick_config_exception) {
3520  std::cerr << sick_config_exception.what() << std::endl;
3521  throw;
3522  }
3523 
3524  /* Catch any timeout exceptions */
3525  catch(SickTimeoutException &sick_timeout_exception) {
3526  std::cerr << sick_timeout_exception.what() << std::endl;
3527  throw;
3528  }
3529 
3530  /* Catch any I/O exceptions */
3531  catch(SickIOException &sick_io_exception) {
3532  std::cerr << sick_io_exception.what() << std::endl;
3533  throw;
3534  }
3535 
3536  /* Catch any thread exceptions */
3537  catch(SickThreadException &sick_thread_exception) {
3538  std::cerr << sick_thread_exception.what() << std::endl;
3539  throw;
3540  }
3541 
3542  /* Catch anything else */
3543  catch(...) {
3544  std::cerr << "SickLMS2xx::_setSickOpModeInstallation: Unknown exception!!!" << std::endl;
3545  throw;
3546  }
3547 
3548  /* Assign the new operating mode */
3550 
3551  /* Reset these parameters */
3553 
3554  }
3555 
3556  }
3557 
3563 
3564  /* Check if mode should be changed */
3566 
3567  std::cout << "\tAttempting to enter diagnostic mode..." << std::endl;
3568 
3569  try {
3570 
3571  /* Attempt to switch modes! */
3573 
3574  }
3575 
3576  /* Catch any config exceptions */
3577  catch(SickConfigException &sick_config_exception) {
3578  std::cerr << sick_config_exception.what() << std::endl;
3579  throw;
3580  }
3581 
3582  /* Catch any timeout exceptions */
3583  catch(SickTimeoutException &sick_timeout_exception) {
3584  std::cerr << sick_timeout_exception.what() << std::endl;
3585  throw;
3586  }
3587 
3588  /* Catch any I/O exceptions */
3589  catch(SickIOException &sick_io_exception) {
3590  std::cerr << sick_io_exception.what() << std::endl;
3591  throw;
3592  }
3593 
3594  /* Catch any thread exceptions */
3595  catch(SickThreadException &sick_thread_exception) {
3596  std::cerr << sick_thread_exception.what() << std::endl;
3597  throw;
3598  }
3599 
3600  /* Catch anything else */
3601  catch(...) {
3602  std::cerr << "SickLMS2xx::_setSickOpModeInstallation: Unknown exception!!!" << std::endl;
3603  throw;
3604  }
3605 
3606  /* Assign the new operating mode */
3608 
3609  /* Reset these parameters */
3611 
3612  std::cout << "Success!" << std::endl;
3613 
3614  }
3615 
3616  }
3617 
3623 
3624  /* Check if mode should be changed */
3626 
3627  try {
3628 
3629  /* Attempt to switch operating mode */
3631 
3632  }
3633 
3634  /* Catch any config exceptions */
3635  catch(SickConfigException &sick_config_exception) {
3636  std::cerr << sick_config_exception.what() << std::endl;
3637  throw;
3638  }
3639 
3640  /* Catch any timeout exceptions */
3641  catch(SickTimeoutException &sick_timeout_exception) {
3642  std::cerr << sick_timeout_exception.what() << std::endl;
3643  throw;
3644  }
3645 
3646  /* Catch any I/O exceptions */
3647  catch(SickIOException &sick_io_exception) {
3648  std::cerr << sick_io_exception.what() << std::endl;
3649  throw;
3650  }
3651 
3652  /* Catch any thread exceptions */
3653  catch(SickThreadException &sick_thread_exception) {
3654  std::cerr << sick_thread_exception.what() << std::endl;
3655  throw;
3656  }
3657 
3658  /* Catch anything else */
3659  catch(...) {
3660  std::cerr << "SickLMS2xx::_setSickOpModeMonitorRequestValues: Unknown exception!!!" << std::endl;
3661  throw;
3662  }
3663 
3664  /* Assign the new operating mode */
3666 
3667  /* Reset these parameters */
3669 
3670  }
3671 
3672  }
3673 
3679 
3680  /* Check if mode should be changed */
3682 
3683  std::cout << "\tRequesting measured value data stream..." << std::endl;
3684 
3685  try {
3686 
3687  /* Attempt to switch modes */
3689 
3690  }
3691 
3692  /* Catch any config exceptions */
3693  catch(SickConfigException &sick_config_exception) {
3694  std::cerr << sick_config_exception.what() << std::endl;
3695  throw;
3696  }
3697 
3698  /* Catch any timeout exceptions */
3699  catch(SickTimeoutException &sick_timeout_exception) {
3700  std::cerr << sick_timeout_exception.what() << std::endl;
3701  throw;
3702  }
3703 
3704  /* Catch any I/O exceptions */
3705  catch(SickIOException &sick_io_exception) {
3706  std::cerr << sick_io_exception.what() << std::endl;
3707  throw;
3708  }
3709 
3710  /* Catch any thread exceptions */
3711  catch(SickThreadException &sick_thread_exception) {
3712  std::cerr << sick_thread_exception.what() << std::endl;
3713  throw;
3714  }
3715 
3716  /* Catch anything else */
3717  catch(...) {
3718  std::cerr << "SickLMS2xx::_setSickOpModeMonitorStreamValues: Unknown exception!!!" << std::endl;
3719  throw;
3720  }
3721 
3722  /* Assign the new operating mode */
3724 
3725  /* Reset these parameters */
3727 
3728  std::cout << "\t\tData stream started!" << std::endl;
3729 
3730  }
3731 
3732  }
3733 
3739 
3740  /* A sanity check to make sure that the command is supported */
3742  throw SickConfigException("SickLMS2xx::_setSickOpModeMonitorStreamRangeAndReflectivity: Mode not supported by this model!");
3743  }
3744 
3745  /* Check if mode should be changed */
3747 
3748  /* Define the parameters */
3749  uint8_t mode_params[4] = {0x01,0x00,0xB5,0x00}; //1 to 181
3750 
3751  std::cout << "\tRequesting range & reflectivity data stream..." << std::endl;
3752 
3753  try {
3754 
3755  /* Attempt to switch modes */
3757 
3758  }
3759 
3760  /* Catch any config exceptions */
3761  catch(SickConfigException &sick_config_exception) {
3762  std::cerr << sick_config_exception.what() << std::endl;
3763  throw;
3764  }
3765 
3766  /* Catch any timeout exceptions */
3767  catch(SickTimeoutException &sick_timeout_exception) {
3768  std::cerr << sick_timeout_exception.what() << std::endl;
3769  throw;
3770  }
3771 
3772  /* Catch any I/O exceptions */
3773  catch(SickIOException &sick_io_exception) {
3774  std::cerr << sick_io_exception.what() << std::endl;
3775  throw;
3776  }
3777 
3778  /* Catch any thread exceptions */
3779  catch(SickThreadException &sick_thread_exception) {
3780  std::cerr << sick_thread_exception.what() << std::endl;
3781  throw;
3782  }
3783 
3784  /* Catch anything else */
3785  catch(...) {
3786  std::cerr << "SickLMS2xx::_setSickOpModeStreamRangeAndReflectivity: Unknown exception!!!" << std::endl;
3787  throw;
3788  }
3789 
3790  /* Assign the new operating mode */
3792 
3793  /* Reset these parameters */
3795 
3796  std::cout << "\t\tData stream started!" << std::endl;
3797 
3798  }
3799 
3800  }
3801 
3807 
3808  /* Check if mode should be changed */
3810 
3811  std::cout << "\tRequesting partial scan data stream..." << std::endl;
3812 
3813  try {
3814 
3815  /* Attempt to switch modes */
3817 
3818  }
3819 
3820  /* Catch any config exceptions */
3821  catch(SickConfigException &sick_config_exception) {
3822  std::cerr << sick_config_exception.what() << std::endl;
3823  throw;
3824  }
3825 
3826  /* Catch any timeout exceptions */
3827  catch(SickTimeoutException &sick_timeout_exception) {
3828  std::cerr << sick_timeout_exception.what() << std::endl;
3829  throw;
3830  }
3831 
3832  /* Catch any I/O exceptions */
3833  catch(SickIOException &sick_io_exception) {
3834  std::cerr << sick_io_exception.what() << std::endl;
3835  throw;
3836  }
3837 
3838  /* Catch any thread exceptions */
3839  catch(SickThreadException &sick_thread_exception) {
3840  std::cerr << sick_thread_exception.what() << std::endl;
3841  throw;
3842  }
3843 
3844  /* Catch anything else */
3845  catch(...) {
3846  std::cerr << "SickLMS2xx::_setSickOpModeStreamValuesFromPartialScan: Unknown exception!!!" << std::endl;
3847  throw;
3848  }
3849 
3850  /* Assign the new operating mode */
3852 
3853  /* Reset these parameters */
3855 
3856  std::cout << "\t\tData stream started!" << std::endl;
3857 
3858  }
3859 
3860  }
3861 
3865  void SickLMS2xx::_setSickOpModeMonitorStreamMeanValues( const uint8_t sample_size )
3867 
3868  /* Check if mode should be changed */
3870  _sick_mean_value_sample_size != sample_size) {
3871 
3872  /* Make sure the sample size is legitimate */
3873  if(sample_size < 2 || sample_size > 250) {
3874  throw SickConfigException("SickLMS2xx::_setSickOpModeMonitorStreamMeanValues: Invalid sample size!");
3875  }
3876 
3877  std::cout << "\tRequesting mean value data stream (sample size = " << (int)sample_size << ")..." << std::endl;
3878 
3879  try {
3880 
3881  /* Attempt to switch modes */
3883 
3884  }
3885 
3886  /* Catch any config exceptions */
3887  catch(SickConfigException &sick_config_exception) {
3888  std::cerr << sick_config_exception.what() << std::endl;
3889  throw;
3890  }
3891 
3892  /* Catch any timeout exceptions */
3893  catch(SickTimeoutException &sick_timeout_exception) {
3894  std::cerr << sick_timeout_exception.what() << std::endl;
3895  throw;
3896  }
3897 
3898  /* Catch any I/O exceptions */
3899  catch(SickIOException &sick_io_exception) {
3900  std::cerr << sick_io_exception.what() << std::endl;
3901  throw;
3902  }
3903 
3904  /* Catch any thread exceptions */
3905  catch(SickThreadException &sick_thread_exception) {
3906  std::cerr << sick_thread_exception.what() << std::endl;
3907  throw;
3908  }
3909 
3910  /* Catch anything else */
3911  catch(...) {
3912  std::cerr << "SickLMS2xx::_setSickOpModeStreamRangeFromPartialScan: Unknown exception!!!" << std::endl;
3913  throw;
3914  }
3915 
3916  /* Assign the new operating mode */
3918 
3919  /* Buffer the current sample size! */
3920  _sick_mean_value_sample_size = sample_size;
3921 
3922  /* Reset these parameters */
3924 
3925  std::cout << "\t\tData stream started!" << std::endl;
3926 
3927  }
3928 
3929  }
3930 
3936  void SickLMS2xx::_setSickOpModeMonitorStreamValuesSubrange( const uint16_t subrange_start_index, const uint16_t subrange_stop_index )
3938 
3939  /* Check if mode should be changed */
3941  _sick_values_subrange_start_index != subrange_start_index ||
3942  _sick_values_subrange_stop_index != subrange_stop_index ) {
3943 
3944  /* Compute the maximum subregion bound */
3945  unsigned int max_subrange_stop_index = (unsigned int)((_sick_operating_status.sick_scan_angle*100)/_sick_operating_status.sick_scan_resolution + 1) ;
3946 
3947  /* Ensure the subregion is properly defined for the given variant */
3948  if(subrange_start_index > subrange_stop_index || subrange_start_index == 0 || subrange_stop_index > max_subrange_stop_index) {
3949  throw SickConfigException("SickLMS2xx::_setSickOpMonitorStreamValuesSubrange: Invalid subregion bounds!");
3950  }
3951 
3952  /* Setup a few buffers */
3953  uint8_t mode_params[4] = {0};
3954  uint16_t temp_buffer = 0;
3955 
3956  /* Assign the subrange start index */
3957  temp_buffer = host_to_sick_lms_2xx_byte_order(subrange_start_index);
3958  memcpy(mode_params,&temp_buffer,2);
3959 
3960  /* Assign the subrange stop index */
3961  temp_buffer = host_to_sick_lms_2xx_byte_order(subrange_stop_index);
3962  memcpy(&mode_params[2],&temp_buffer,2);
3963 
3964  std::cout << "\tRequesting measured value stream... (subrange = [" << subrange_start_index << "," << subrange_stop_index << "])" << std::endl;
3965 
3966  try {
3967 
3968  /* Attempt to switch modes */
3970 
3971  }
3972 
3973  /* Catch any config exceptions */
3974  catch(SickConfigException &sick_config_exception) {
3975  std::cerr << sick_config_exception.what() << std::endl;
3976  throw;
3977  }
3978 
3979  /* Catch any timeout exceptions */
3980  catch(SickTimeoutException &sick_timeout_exception) {
3981  std::cerr << sick_timeout_exception.what() << std::endl;
3982  throw;
3983  }
3984 
3985  /* Catch any I/O exceptions */
3986  catch(SickIOException &sick_io_exception) {
3987  std::cerr << sick_io_exception.what() << std::endl;
3988  throw;
3989  }
3990 
3991  /* Catch any thread exceptions */
3992  catch(SickThreadException &sick_thread_exception) {
3993  std::cerr << sick_thread_exception.what() << std::endl;
3994  throw;
3995  }
3996 
3997  /* Catch anything else */
3998  catch(...) {
3999  std::cerr << "SickLMS2xx::_setSickOpModeInstallation: Unknown exception!!!" << std::endl;
4000  throw;
4001  }
4002 
4003  /* Assign the new operating mode */
4005 
4006  /* Reset this parameter */
4008 
4009  /* Buffer the starting/stopping indices */
4010  _sick_values_subrange_start_index = subrange_start_index;
4011  _sick_values_subrange_stop_index = subrange_stop_index;
4012 
4013  std::cout << "\t\tData stream started!" << std::endl;
4014 
4015  }
4016 
4017  }
4018 
4025  void SickLMS2xx::_setSickOpModeMonitorStreamMeanValuesSubrange( const uint16_t sample_size, const uint16_t subrange_start_index, const uint16_t subrange_stop_index )
4027 
4028  /* Check if mode should be changed */
4030  _sick_values_subrange_start_index != subrange_start_index ||
4031  _sick_values_subrange_stop_index != subrange_stop_index ||
4032  _sick_mean_value_sample_size != sample_size ) {
4033 
4034  /* Make sure the sample size is legit */
4035  if(sample_size < 2 || sample_size > 250) {
4036  throw SickConfigException("SickLMS2xx::_setSickOpModeMonitorStreamMeanValuesSubrange: Invalid sample size!");
4037  }
4038 
4039  /* Compute the maximum subregion bound */
4040  unsigned int max_subrange_stop_index = (unsigned int)((_sick_operating_status.sick_scan_angle*100)/_sick_operating_status.sick_scan_resolution + 1) ;
4041 
4042  /* Ensure the subregion is properly defined for the given variant */
4043  if(subrange_start_index > subrange_stop_index || subrange_start_index == 0 || subrange_stop_index > max_subrange_stop_index) {
4044  throw SickConfigException("SickLMS2xx::_setSickOpMonitorStreamMeanValuesSubrange: Invalid subregion bounds!");
4045  }
4046 
4047  /* Setup a few buffers */
4048  uint8_t mode_params[5] = {0};
4049  uint16_t temp_buffer = 0;
4050 
4051  /* Assign the sample size */
4052  mode_params[0] = sample_size;
4053 
4054  /* Assign the subrange start index */
4055  temp_buffer = host_to_sick_lms_2xx_byte_order(subrange_start_index);
4056  memcpy(&mode_params[1],&temp_buffer,2);
4057 
4058  /* Assign the subrange stop index */
4059  temp_buffer = host_to_sick_lms_2xx_byte_order(subrange_stop_index);
4060  memcpy(&mode_params[3],&temp_buffer,2);
4061 
4062  std::cout << "\tRequesting mean value stream... (subrange = [" << subrange_start_index << "," << subrange_stop_index << "])" << std::endl;
4063 
4064  try {
4065 
4066  /* Attempt to switch modes */
4068 
4069  }
4070 
4071  /* Catch any config exceptions */
4072  catch(SickConfigException &sick_config_exception) {
4073  std::cerr << sick_config_exception.what() << std::endl;
4074  throw;
4075  }
4076 
4077  /* Catch any timeout exceptions */
4078  catch(SickTimeoutException &sick_timeout_exception) {
4079  std::cerr << sick_timeout_exception.what() << std::endl;
4080  throw;
4081  }
4082 
4083  /* Catch any I/O exceptions */
4084  catch(SickIOException &sick_io_exception) {
4085  std::cerr << sick_io_exception.what() << std::endl;
4086  throw;
4087  }
4088 
4089  /* Catch any thread exceptions */
4090  catch(SickThreadException &sick_thread_exception) {
4091  std::cerr << sick_thread_exception.what() << std::endl;
4092  throw;
4093  }
4094 
4095  /* Catch anything else */
4096  catch(...) {
4097  std::cerr << "SickLMS2xx::_setSickOpModeInstallation: Unknown exception!!!" << std::endl;
4098  throw;
4099  }
4100 
4101  /* Assign the new operating mode */
4103 
4104  /* Buffer the sample size */
4105  _sick_mean_value_sample_size = sample_size;
4106 
4107  /* Buffer the starting/stopping indices */
4108  _sick_values_subrange_start_index = subrange_start_index;
4109  _sick_values_subrange_stop_index = subrange_stop_index;
4110 
4111  std::cout << "\t\tData stream started!" << std::endl;
4112 
4113  }
4114 
4115  }
4116 
4122  void SickLMS2xx::_switchSickOperatingMode( const uint8_t sick_mode, const uint8_t * const mode_params )
4124 
4125  SickLMS2xxMessage message,response;
4126 
4127  uint8_t payload_buffer[SickLMS2xxMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
4128  uint16_t num_partial_scans = 0;
4129 
4130  /* Construct the correct switch mode packet */
4131  payload_buffer[0] = 0x20;
4132  payload_buffer[1] = sick_mode;
4133 
4134  switch(sick_mode) {
4135 
4137 
4138  /* Make sure the params are defined */
4139  if(mode_params == NULL) {
4140  throw SickConfigException("SickLMS2xx::_switchSickOperatingMode - Requested mode requires parameters!");
4141  }
4142 
4143  memcpy(&payload_buffer[2],mode_params,8); //Copy password
4144  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,10);
4145  break;
4146 
4148  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,2);
4149  break;
4150 
4152  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,2);
4153  break;
4154 
4156  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,2);
4157  break;
4158 
4160  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,2);
4161  break;
4162 
4164  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,2);
4165  break;
4166 
4168  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,2);
4169  break;
4170 
4172  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,2);
4173  break;
4174 
4176 
4177  /* Make sure the params are defined */
4178  if(mode_params == NULL) {
4179  throw SickConfigException("SickLMS2xx::_switchSickOperatingMode - Requested mode requires parameters!");
4180  }
4181 
4182  payload_buffer[2] = *mode_params;
4183  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,3);
4184  break;
4185 
4187 
4188  /* Make sure the params are defined */
4189  if(mode_params == NULL) {
4190  throw SickConfigException("SickLMS2xx::_switchSickOperatingMode - Requested mode requires parameters!");
4191  }
4192 
4193  memcpy(&payload_buffer[2],mode_params,2); //Begin range
4194  memcpy(&payload_buffer[4],&mode_params[2],2); //End range
4195  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,6);
4196  break;
4197 
4199 
4200  /* Make sure the params are defined */
4201  if(mode_params == NULL) {
4202  throw SickConfigException("SickLMS2xx::_switchSickOperatingMode - Requested mode requires parameters!");
4203  }
4204 
4205  payload_buffer[2] = mode_params[0]; //Sample size
4206  memcpy(&payload_buffer[3],&mode_params[1],2); //Begin mean range
4207  memcpy(&payload_buffer[5],&mode_params[3],2); //End mean range
4208  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,7);
4209  break;
4210 
4212 
4213  /* Make sure the params are defined */
4214  if(mode_params == NULL) {
4215  throw SickConfigException("SickLMS2xx::_switchSickOperatingMode - Requested mode requires parameters!");
4216  }
4217 
4218  memcpy(&payload_buffer[2],mode_params,2); //Start
4219  memcpy(&payload_buffer[4],&mode_params[2],2); //End
4220  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,6);
4221  break;
4222 
4224  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,2);
4225  break;
4226 
4228 
4229  /* Make sure the params are defined */
4230  if(mode_params == NULL) {
4231  throw SickConfigException("SickLMS2xx::_switchSickOperatingMode - Requested mode requires parameters!");
4232  }
4233 
4234  /* Get the number of partial scans (between 1 and 5) */
4235  memcpy(&num_partial_scans,mode_params,2);
4236 
4237  /* Setup the command packet */
4238  memcpy(&payload_buffer[2],mode_params,num_partial_scans*4+2);
4239  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,num_partial_scans*4+4);
4240  break;
4241 
4243 
4244  /* Make sure the params are defined */
4245  if(mode_params == NULL) {
4246  throw SickConfigException("SickLMS2xx::_switchSickOperatingMode - Requested mode requires parameters!");
4247  }
4248 
4249  /* Get the number of partial scans (between 1 and 5) */
4250  memcpy(&num_partial_scans,mode_params,2);
4251 
4252  /* Setup the command packet */
4253  memcpy(&payload_buffer[2],mode_params,num_partial_scans*4+2);
4254  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,num_partial_scans*4+4);
4255  break;
4256 
4258  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,2);
4259  break;
4260 
4262 
4263  /* Make sure the params are defined */
4264  if(mode_params == NULL) {
4265  throw SickConfigException("SickLMS2xx::_switchSickOperatingMode - Requested mode requires parameters!");
4266  }
4267 
4268  memcpy(&payload_buffer[2],mode_params,2); //Start
4269  memcpy(&payload_buffer[4],&mode_params[2],2); //End
4270  message.BuildMessage(DEFAULT_SICK_LMS_2XX_SICK_ADDRESS,payload_buffer,6);
4271  break;
4272 
4273  case SICK_OP_MODE_UNKNOWN:
4274  //Let this case go straight to default
4275 
4276  default:
4277  throw SickConfigException("SickLMS2xx::_switchSickOperatingMode: Unrecognized operating mode!");
4278  }
4279 
4280  try {
4281 
4282  /* Attempt to send the message and get the reply */
4284 
4285  }
4286 
4287  /* Catch any timeout exceptions */
4288  catch(SickTimeoutException &sick_timeout_exception) {
4289  std::cerr << sick_timeout_exception.what() << std::endl;
4290  throw;
4291  }
4292 
4293  /* Catch any I/O exceptions */
4294  catch(SickIOException &sick_io_exception) {
4295  std::cerr << sick_io_exception.what() << std::endl;
4296  throw;
4297  }
4298 
4299  /* Catch any thread exceptions */
4300  catch(SickThreadException &sick_thread_exception) {
4301  std::cerr << sick_thread_exception.what() << std::endl;
4302  throw;
4303  }
4304 
4305  /* Catch anything else */
4306  catch(...) {
4307  std::cerr << "SickLMS2xx::_switchSickOperatingMode: Unknown exception!!!" << std::endl;
4308  throw;
4309  }
4310 
4311  /* Reset the buffer */
4312  memset(payload_buffer,0,sizeof(payload_buffer));
4313 
4314  /* Obtain the response payload */
4315  response.GetPayload(payload_buffer);
4316 
4317  /* Make sure the reply was expected */
4318  if(payload_buffer[1] != 0x00) {
4319  throw SickConfigException("SickLMS2xx::_switchSickOperatingMode: configuration request failed!");
4320  }
4321 
4322  }
4323 
4329  void SickLMS2xx::_parseSickScanProfileB0( const uint8_t * const src_buffer, sick_lms_2xx_scan_profile_b0_t &sick_scan_profile ) const {
4330 
4331  /* Read block A, the number of measurments */
4332  sick_scan_profile.sick_num_measurements = src_buffer[0] + 256*(src_buffer[1] & 0x03);
4333 
4334  /* Check whether this is a partial scan */
4335  sick_scan_profile.sick_partial_scan_index = ((src_buffer[1] & 0x18) >> 3);
4336 
4337  /* Extract the measurements and Field values (if there are any) */
4338  _extractSickMeasurementValues(&src_buffer[2],
4339  sick_scan_profile.sick_num_measurements,
4340  sick_scan_profile.sick_measurements,
4341  sick_scan_profile.sick_field_a_values,
4342  sick_scan_profile.sick_field_b_values,
4343  sick_scan_profile.sick_field_c_values);
4344 
4345  /* If the Sick is pulling real-time indices then pull them too */
4346  unsigned int data_offset = 2 + 2*sick_scan_profile.sick_num_measurements;
4347  if (_returningRealTimeIndices()) {
4348  sick_scan_profile.sick_real_time_scan_index = src_buffer[data_offset];
4349  data_offset++;
4350  }
4351 
4352  /* Buffer the Sick telegram index */
4353  sick_scan_profile.sick_telegram_index = src_buffer[data_offset];
4354 
4355  }
4356 
4362  void SickLMS2xx::_parseSickScanProfileB6( const uint8_t * const src_buffer, sick_lms_2xx_scan_profile_b6_t &sick_scan_profile ) const {
4363 
4364  /* Read Block A, the sample size used in computing the mean return */
4365  sick_scan_profile.sick_sample_size = src_buffer[0];
4366 
4367  /* Read Block B, the number of measured values sent */
4368  sick_scan_profile.sick_num_measurements = src_buffer[1] + 256*(src_buffer[2] & 0x03);
4369 
4370  /* Read Block C, extract the range measurements and Field values (if there are any) */
4371  _extractSickMeasurementValues(&src_buffer[3],
4372  sick_scan_profile.sick_num_measurements,
4373  sick_scan_profile.sick_measurements);
4374 
4375  /* Read Block D, if the Sick is pulling real-time indices then pull them too */
4376  unsigned int data_offset = 3 + 2*sick_scan_profile.sick_num_measurements;
4377  if (_returningRealTimeIndices()) {
4378  sick_scan_profile.sick_real_time_scan_index = src_buffer[data_offset];
4379  data_offset++;
4380  }
4381 
4382  /* Read Block E, buffer the Sick telegram index */
4383  sick_scan_profile.sick_telegram_index = src_buffer[data_offset];
4384 
4385  }
4386 
4392  void SickLMS2xx::_parseSickScanProfileB7( const uint8_t * const src_buffer, sick_lms_2xx_scan_profile_b7_t &sick_scan_profile ) const {
4393 
4394  /* Read Block A, Sick LMS measured value subrange start index */
4395  sick_scan_profile.sick_subrange_start_index = src_buffer[0] + 256*src_buffer[1];
4396 
4397  /* Read Block B, Sick LMS measured value subrange stop index */
4398  sick_scan_profile.sick_subrange_stop_index = src_buffer[2] + 256*src_buffer[3];
4399 
4400  /* Read block C, the number of measurements */
4401  sick_scan_profile.sick_num_measurements = src_buffer[4] + 256*(src_buffer[5] & 0x03);
4402 
4403  /* Acquire the partial scan index (also in Block C) */
4404  sick_scan_profile.sick_partial_scan_index = ((src_buffer[5] & 0x18) >> 3);
4405 
4406  /* Read Block D, extract the range measurements and Field values (if there are any) */
4407  _extractSickMeasurementValues(&src_buffer[6],
4408  sick_scan_profile.sick_num_measurements,
4409  sick_scan_profile.sick_measurements,
4410  sick_scan_profile.sick_field_a_values,
4411  sick_scan_profile.sick_field_b_values,
4412  sick_scan_profile.sick_field_c_values);
4413 
4414  /* Read Block E, if the Sick is pulling real-time indices then pull them too */
4415  unsigned int data_offset = 6 + 2*sick_scan_profile.sick_num_measurements;
4416  if (_returningRealTimeIndices()) {
4417  sick_scan_profile.sick_real_time_scan_index = src_buffer[data_offset];
4418  data_offset++;
4419  }
4420 
4421  /* Read Block F, buffer the Sick telegram index */
4422  sick_scan_profile.sick_telegram_index = src_buffer[data_offset];
4423 
4424  }
4425 
4431  void SickLMS2xx::_parseSickScanProfileBF( const uint8_t * const src_buffer, sick_lms_2xx_scan_profile_bf_t &sick_scan_profile ) const {
4432 
4433  /* Read Block A, the sample size used in computing the mean return */
4434  sick_scan_profile.sick_sample_size = src_buffer[0];
4435 
4436  /* Read Block B, Sick LMS measured value subrange start index */
4437  sick_scan_profile.sick_subrange_start_index = src_buffer[1] + 256*src_buffer[2];
4438 
4439  /* Read Block C, Sick LMS measured value subrange stop index */
4440  sick_scan_profile.sick_subrange_stop_index = src_buffer[3] + 256*src_buffer[4];
4441 
4442  /* Read Block D, the number of measured values sent */
4443  sick_scan_profile.sick_num_measurements = src_buffer[5] + 256*(src_buffer[6] & 0x3F);
4444 
4445  /* Read Block E, extract the mean measurements */
4446  _extractSickMeasurementValues(&src_buffer[7],
4447  sick_scan_profile.sick_num_measurements,
4448  sick_scan_profile.sick_measurements);
4449 
4450  /* Read Block D, if the Sick is pulling real-time indices then pull them too */
4451  unsigned int data_offset = 7 + 2*sick_scan_profile.sick_num_measurements;
4452  if (_returningRealTimeIndices()) {
4453  sick_scan_profile.sick_real_time_scan_index = src_buffer[data_offset];
4454  data_offset++;
4455  }
4456 
4457  /* Read Block E, buffer the Sick telegram index */
4458  sick_scan_profile.sick_telegram_index = src_buffer[data_offset];
4459 
4460  }
4461 
4467  void SickLMS2xx::_parseSickScanProfileC4( const uint8_t * const src_buffer, sick_lms_2xx_scan_profile_c4_t &sick_scan_profile ) const {
4468 
4469  /* Read block A - the number of range measurments. We need the low two bits
4470  * of the most significant byte. */
4471  sick_scan_profile.sick_num_range_measurements = src_buffer[0] + 256*(src_buffer[1] & 0x03);
4472 
4473  /* Read Block B - Extract the range measurements and Field values (if there are any) */
4474  _extractSickMeasurementValues(&src_buffer[2],
4475  sick_scan_profile.sick_num_range_measurements,
4476  sick_scan_profile.sick_range_measurements,
4477  sick_scan_profile.sick_field_a_values,
4478  sick_scan_profile.sick_field_b_values,
4479  sick_scan_profile.sick_field_c_values);
4480 
4481  /* Read Block D - Extract the number of range measurements */
4482  unsigned int data_offset = 2 + 2*sick_scan_profile.sick_num_range_measurements;
4483  sick_scan_profile.sick_num_reflect_measurements = src_buffer[data_offset] + 256*(src_buffer[data_offset+1] & 0x03);
4484  data_offset += 2;
4485 
4486  /* Read Block E - Extract the reflectivity value subrange start index */
4487  sick_scan_profile.sick_reflect_subrange_start_index = src_buffer[data_offset] + 256*src_buffer[data_offset+1];
4488  data_offset += 2;
4489 
4490  /* Read Block F - Extract the reflectivity value subrange stop index */
4491  sick_scan_profile.sick_reflect_subrange_stop_index = src_buffer[data_offset] + 256*src_buffer[data_offset+1];
4492  data_offset += 2;
4493 
4494  /* Read blocks G...H. Mask out the reflectivity values and store in provided buffer. */
4495  for(unsigned int i=0; i < sick_scan_profile.sick_num_reflect_measurements; i++,data_offset++) {
4496  sick_scan_profile.sick_reflect_measurements[i] = src_buffer[data_offset];
4497  }
4498 
4499  /* Read Block I - real-time scan indices */
4500  if (_returningRealTimeIndices()) {
4501  sick_scan_profile.sick_real_time_scan_index = src_buffer[data_offset];
4502  data_offset++;
4503  }
4504 
4505  /* Read Block J - the telegram scan index */
4506  sick_scan_profile.sick_telegram_index = src_buffer[data_offset];
4507 
4508  }
4509 
4515  void SickLMS2xx::_parseSickConfigProfile( const uint8_t * const src_buffer, sick_lms_2xx_device_config_t &sick_device_config ) const {
4516 
4517  /* Buffer Block A */
4518  memcpy(&sick_device_config.sick_blanking,&src_buffer[0],2);
4519  sick_device_config.sick_blanking = sick_lms_2xx_to_host_byte_order(sick_device_config.sick_blanking);
4520 
4521  /* Buffer Block B */
4522  sick_device_config.sick_peak_threshold = src_buffer[3]; // NOTE: This value represent sensitivity for LMS 211/221/291
4523  sick_device_config.sick_stop_threshold = src_buffer[2]; // NOTE: This value will be 0 for LMS 211/221/291
4524 
4525  /* Buffer Block C */
4526  sick_device_config.sick_availability_level = src_buffer[4];
4527 
4528  /* Buffer Block D */
4529  sick_device_config.sick_measuring_mode = src_buffer[5];
4530 
4531  /* Buffer Block E */
4532  sick_device_config.sick_measuring_units = src_buffer[6];
4533 
4534  /* Buffer Block F */
4535  sick_device_config.sick_temporary_field = src_buffer[7];
4536 
4537  /* Buffer Block G */
4538  sick_device_config.sick_subtractive_fields = src_buffer[8];
4539 
4540  /* Buffer Block H */
4541  sick_device_config.sick_multiple_evaluation = src_buffer[9];
4542 
4543  /* Buffer Block I */
4544  sick_device_config.sick_restart = src_buffer[10];
4545 
4546  /* Buffer Block J */
4547  sick_device_config.sick_restart_time = src_buffer[11];
4548 
4549  /* Buffer Block K */
4550  sick_device_config.sick_multiple_evaluation_suppressed_objects = src_buffer[12];
4551 
4552  /* Buffer Block L */
4553  sick_device_config.sick_contour_a_reference = src_buffer[13];
4554 
4555  /* Buffer Block M */
4556  sick_device_config.sick_contour_a_positive_tolerance_band = src_buffer[14];
4557 
4558  /* Buffer Block N */
4559  sick_device_config.sick_contour_a_negative_tolerance_band = src_buffer[15];
4560 
4561  /* Buffer Block O */
4562  sick_device_config.sick_contour_a_start_angle = src_buffer[16];
4563 
4564  /* Buffer Block P */
4565  sick_device_config.sick_contour_a_stop_angle = src_buffer[17];
4566 
4567  /* Buffer Block Q */
4568  sick_device_config.sick_contour_b_reference = src_buffer[18];
4569 
4570  /* Buffer Block R */
4571  sick_device_config.sick_contour_b_positive_tolerance_band = src_buffer[19];
4572 
4573  /* Buffer Block S */
4574  sick_device_config.sick_contour_b_negative_tolerance_band = src_buffer[20];
4575 
4576  /* Buffer Block T */
4577  sick_device_config.sick_contour_b_start_angle = src_buffer[21];
4578 
4579  /* Buffer Block U */
4580  sick_device_config.sick_contour_b_stop_angle = src_buffer[22];
4581 
4582  /* Buffer Block V */
4583  sick_device_config.sick_contour_c_reference = src_buffer[23];
4584 
4585  /* Buffer Block W */
4586  sick_device_config.sick_contour_c_positive_tolerance_band = src_buffer[24];
4587 
4588  /* Buffer Block X */
4589  sick_device_config.sick_contour_c_negative_tolerance_band = src_buffer[25];
4590 
4591  /* Buffer Block Y */
4592  sick_device_config.sick_contour_c_start_angle = src_buffer[26];
4593 
4594  /* Buffer Block Z */
4595  sick_device_config.sick_contour_c_stop_angle = src_buffer[27];
4596 
4597  /* Buffer Block A1 */
4598  sick_device_config.sick_pixel_oriented_evaluation = src_buffer[28];
4599 
4600  /* Buffer Block A2 */
4601  sick_device_config.sick_single_measured_value_evaluation_mode = src_buffer[29];
4602 
4603  /* Buffer Block A3 */
4604  memcpy(&sick_device_config.sick_fields_b_c_restart_times,&src_buffer[30],2);
4605  sick_device_config.sick_fields_b_c_restart_times =
4607 
4608  /* Buffer Block A4 */
4609  memcpy(&sick_device_config.sick_dazzling_multiple_evaluation,&src_buffer[32],2);
4610  sick_device_config.sick_dazzling_multiple_evaluation =
4612 
4613  }
4614 
4624  void SickLMS2xx::_extractSickMeasurementValues( const uint8_t * const byte_sequence, const uint16_t num_measurements, uint16_t * const measured_values,
4625  uint8_t * const field_a_values, uint8_t * const field_b_values, uint8_t * const field_c_values ) const {
4626 
4627  /* Parse the byte sequence and fill the return buffer with range measurements... */
4630  {
4631 
4632  /* Extract the range and Field values */
4633  for(unsigned int i = 0; i < num_measurements; i++) {
4634  measured_values[i] = byte_sequence[i*2] + 256*(byte_sequence[i*2+1] & 0x1F);
4635 
4636  if(field_a_values) {
4637  field_a_values[i] = byte_sequence[i*2+1] & 0x20;
4638  }
4639 
4640  if(field_b_values) {
4641  field_b_values[i] = byte_sequence[i*2+1] & 0x40;
4642  }
4643 
4644  if(field_c_values) {
4645  field_c_values[i] = byte_sequence[i*2+1] & 0x80;
4646  }
4647 
4648  }
4649 
4650  break;
4651  }
4653  {
4654 
4655  /* Extract the range and Field A */
4656  for(unsigned int i = 0; i < num_measurements; i++) {
4657  measured_values[i] = byte_sequence[i*2] + 256*(byte_sequence[i*2+1] & 0x1F);
4658 
4659  if(field_a_values) {
4660  field_a_values[i] = byte_sequence[i*2+1] & 0xE0;
4661  }
4662 
4663  }
4664 
4665  break;
4666  }
4668  {
4669 
4670  /* Extract the range and Fields A,B and C */
4671  for(unsigned int i = 0; i < num_measurements; i++) {
4672  measured_values[i] = byte_sequence[i*2] + 256*(byte_sequence[i*2+1] & 0x1F);
4673 
4674  if(field_a_values) {
4675  field_a_values[i] = byte_sequence[i*2+1] & 0x20;
4676  }
4677 
4678  if(field_b_values) {
4679  field_b_values[i] = byte_sequence[i*2+1] & 0x40;
4680  }
4681 
4682  if(field_c_values) {
4683  field_c_values[i] = byte_sequence[i*2+1] & 0x80;
4684  }
4685 
4686  }
4687 
4688  break;
4689  }
4691  {
4692 
4693  /* Extract the range and reflector values */
4694  for(unsigned int i = 0; i < num_measurements; i++) {
4695  measured_values[i] = byte_sequence[i*2] + 256*(byte_sequence[i*2+1] & 0x3F);
4696 
4697  if (field_a_values) {
4698  field_a_values[i] = byte_sequence[i*2+1] & 0xC0;
4699  }
4700 
4701  }
4702 
4703  break;
4704  }
4705  case SICK_MS_MODE_16_FA_FB:
4706  {
4707 
4708  /* Extract the range and Fields A and B values */
4709  for(unsigned int i = 0; i < num_measurements; i++) {
4710  measured_values[i] = byte_sequence[i*2] + 256*(byte_sequence[i*2+1] & 0x3F);
4711 
4712  if(field_a_values) {
4713  field_a_values[i] = byte_sequence[i*2+1] & 0x40;
4714  }
4715 
4716  if(field_b_values) {
4717  field_b_values[i] = byte_sequence[i*2+1] & 0x80;
4718  }
4719 
4720  }
4721 
4722  break;
4723  }
4725  {
4726 
4727  /* Extract the range and reflector values */
4728  for(unsigned int i = 0; i < num_measurements; i++) {
4729  measured_values[i] = byte_sequence[i*2] + 256*(byte_sequence[i*2+1] & 0x7F);
4730 
4731  if(field_a_values) {
4732  field_a_values[i] = byte_sequence[i*2+1] & 0x80;
4733  }
4734 
4735  }
4736 
4737  break;
4738  }
4739  case SICK_MS_MODE_32_FA:
4740  {
4741 
4742  /* Extract the range and Field A values */
4743  for(unsigned int i = 0; i < num_measurements; i++) {
4744  measured_values[i] = byte_sequence[i*2] + 256*(byte_sequence[i*2+1] & 0x7F);
4745 
4746  if(field_a_values) {
4747  field_a_values[i] = byte_sequence[i*2+1] & 0x80;
4748  }
4749 
4750  }
4751 
4752  break;
4753  }
4755  {
4756 
4757  /* Extract the range measurements (no flags for this mode */
4758  for(unsigned int i = 0; i < num_measurements; i++) {
4759  measured_values[i] = byte_sequence[i*2] + 256*(byte_sequence[i*2+1]);
4760  }
4761 
4762  break;
4763  }
4765  {
4766 
4767  /* Extract the reflectivity values */
4768  for(unsigned int i = 0; i < num_measurements; i++) {
4769  measured_values[i] = byte_sequence[i*2] + 256*(byte_sequence[i*2+1]);
4770  }
4771 
4772  break;
4773  }
4774  default:
4775  break;
4776  }
4777 
4778  }
4779 
4785 
4786  /* Check the given units value */
4787  if (sick_units != SICK_MEASURING_UNITS_CM && sick_units != SICK_MEASURING_UNITS_MM) {
4788  return false;
4789  }
4790 
4791  /* Valid */
4792  return true;
4793  }
4794 
4800 
4801  /* Check the given Sick type value */
4802  switch(_sick_type) {
4804  return true;
4805  default:
4806  return false;
4807  }
4808 
4809  }
4810 
4816 
4817  /* Check the given Sick type value */
4818  switch(_sick_type) {
4820  return true;
4822  return true;
4823  case SICK_LMS_TYPE_211_S07:
4824  return true;
4825  case SICK_LMS_TYPE_211_S14:
4826  return true;
4827  case SICK_LMS_TYPE_211_S15:
4828  return true;
4829  case SICK_LMS_TYPE_211_S19:
4830  return true;
4831  case SICK_LMS_TYPE_211_S20:
4832  return true;
4833  default:
4834  return false;
4835  }
4836 
4837  }
4838 
4844 
4845  /* Check the given Sick type value */
4846  switch(_sick_type) {
4848  return true;
4849  default:
4850  return false;
4851  }
4852 
4853  }
4854 
4860 
4861  /* Check the given Sick type value */
4862  switch(_sick_type) {
4864  return true;
4866  return true;
4867  case SICK_LMS_TYPE_221_S07:
4868  return true;
4869  case SICK_LMS_TYPE_221_S14:
4870  return true;
4871  case SICK_LMS_TYPE_221_S15:
4872  return true;
4873  case SICK_LMS_TYPE_221_S16:
4874  return true;
4875  case SICK_LMS_TYPE_221_S19:
4876  return true;
4877  case SICK_LMS_TYPE_221_S20:
4878  return true;
4879  default:
4880  return false;
4881  }
4882 
4883  }
4884 
4890 
4891  /* Check the given Sick type value */
4892  switch(_sick_type) {
4893  case SICK_LMS_TYPE_291_S05:
4894  return true;
4895  case SICK_LMS_TYPE_291_S14:
4896  return true;
4897  case SICK_LMS_TYPE_291_S15:
4898  return true;
4899  default:
4900  return false;
4901  }
4902 
4903  }
4904 
4911  }
4912 
4917  bool SickLMS2xx::_validSickScanAngle( const sick_lms_2xx_scan_angle_t sick_scan_angle ) const {
4918 
4919  /* Check the given Sick scan angle */
4920  if (sick_scan_angle != SICK_SCAN_ANGLE_90 &&
4921  sick_scan_angle != SICK_SCAN_ANGLE_100 &&
4922  sick_scan_angle != SICK_SCAN_ANGLE_180 ) {
4923 
4924  return false;
4925  }
4926 
4927  /* Valid */
4928  return true;
4929  }
4930 
4936 
4937  /* Check the given Sick scan resolution value */
4938  if (sick_scan_resolution != SICK_SCAN_RESOLUTION_25 &&
4939  sick_scan_resolution != SICK_SCAN_RESOLUTION_50 &&
4940  sick_scan_resolution != SICK_SCAN_RESOLUTION_100 ) {
4941 
4942  return false;
4943  }
4944 
4945  /* Valid */
4946  return true;
4947  }
4948 
4953  bool SickLMS2xx::_validSickSensitivity( const sick_lms_2xx_sensitivity_t sick_sensitivity ) const {
4954 
4955  /* Check the given Sick sensitivity value */
4956  if (sick_sensitivity != SICK_SENSITIVITY_STANDARD &&
4957  sick_sensitivity != SICK_SENSITIVITY_MEDIUM &&
4958  sick_sensitivity != SICK_SENSITIVITY_LOW &&
4959  sick_sensitivity != SICK_SENSITIVITY_HIGH ) {
4960 
4961  return false;
4962  }
4963 
4964  /* Valid */
4965  return true;
4966  }
4967 
4972  bool SickLMS2xx::_validSickPeakThreshold( const sick_lms_2xx_peak_threshold_t sick_peak_threshold ) const {
4973 
4974  /* Check the given Sick scan angle */
4975  if (sick_peak_threshold != SICK_PEAK_THRESHOLD_DETECTION_WITH_NO_BLACK_EXTENSION &&
4976  sick_peak_threshold != SICK_PEAK_THRESHOLD_DETECTION_WITH_BLACK_EXTENSION &&
4979 
4980  return false;
4981  }
4982 
4983  /* Valid */
4984  return true;
4985  }
4986 
4991  bool SickLMS2xx::_validSickMeasuringMode( const sick_lms_2xx_measuring_mode_t sick_measuring_mode ) const {
4992 
4993  /* Check the given measuring mode */
4994  if (sick_measuring_mode != SICK_MS_MODE_8_OR_80_FA_FB_DAZZLE &&
4995  sick_measuring_mode != SICK_MS_MODE_8_OR_80_REFLECTOR &&
4996  sick_measuring_mode != SICK_MS_MODE_8_OR_80_FA_FB_FC &&
4997  sick_measuring_mode != SICK_MS_MODE_16_REFLECTOR &&
4998  sick_measuring_mode != SICK_MS_MODE_16_FA_FB &&
4999  sick_measuring_mode != SICK_MS_MODE_32_REFLECTOR &&
5000  sick_measuring_mode != SICK_MS_MODE_32_FA &&
5001  sick_measuring_mode != SICK_MS_MODE_32_IMMEDIATE &&
5002  sick_measuring_mode != SICK_MS_MODE_REFLECTIVITY ) {
5003 
5004  return false;
5005  }
5006 
5007  /* Valid */
5008  return true;
5009  }
5010 
5016  sick_lms_2xx_baud_t SickLMS2xx::_baudToSickBaud( const int baud_rate ) const {
5017 
5018  switch(baud_rate) {
5019  case B9600:
5020  return SICK_BAUD_9600;
5021  case B19200:
5022  return SICK_BAUD_19200;
5023  case B38400:
5024  return SICK_BAUD_38400;
5025  case B500000:
5026  return SICK_BAUD_500K;
5027  default:
5028  std::cerr << "Unexpected baud rate!" << std::endl;
5029  return SICK_BAUD_9600;
5030  }
5031 
5032  }
5033 
5039  std::string SickLMS2xx::_sickAvailabilityToString( const uint8_t availability_flags ) const {
5040 
5041  /* Check if availability is specified */
5042  if (availability_flags == 0) {
5043  return "Default (Unspecified)";
5044  }
5045 
5046  std::string availability_str;
5047 
5048  /* Check if set to highest possible availability */
5049  if (0x01 & availability_flags) {
5050  availability_str += "Highest";
5051  }
5052 
5053  /* Check for real-time indices */
5054  if (0x02 & availability_flags) {
5055 
5056  /* Check whether to add a spacer */
5057  if (availability_str.length() > 0) {
5058  availability_str += ", ";
5059  }
5060 
5061  availability_str += "Real-time indices";
5062  }
5063 
5064  /* Check for real-time indices */
5065  if (0x04 & availability_flags) {
5066 
5067  /* Check whether to add a spacer */
5068  if (availability_str.length() > 0) {
5069  availability_str += ", ";
5070  }
5071 
5072  availability_str += "No effect dazzle";
5073  }
5074 
5075  /* Return the string */
5076  return availability_str;
5077 
5078  }
5079 
5085  std::string SickLMS2xx::_sickRestartToString( const uint8_t restart_code ) const {
5086 
5087  std::string restart_str;
5088 
5089  /* Identify restart mode */
5090  switch(restart_code) {
5091  case 0x00:
5092  restart_str += "Restart when button actuated";
5093  break;
5094  case 0x01:
5095  restart_str += "Restart after set time";
5096  break;
5097  case 0x02:
5098  restart_str += "No restart block";
5099  break;
5100  case 0x03:
5101  restart_str += "Button switches field set, restart after set time";
5102  break;
5103  case 0x04:
5104  restart_str += "Button switches field set, no restart block";
5105  break;
5106  case 0x05:
5107  restart_str += "LMS2xx operates as a slave, restart after set time";
5108  break;
5109  case 0x06:
5110  restart_str += "LMS2xx operates as a slave, immediate restart";
5111  break;
5112  default:
5113  restart_str += "Unknown!";
5114  }
5115 
5116  /* Return the restart code */
5117  return restart_str;
5118 
5119  }
5120 
5126  std::string SickLMS2xx::_sickTemporaryFieldToString( const uint8_t temp_field_code ) const {
5127 
5128  switch(temp_field_code) {
5129  case 0:
5130  return "Not used";
5131  case 1:
5132  return "Belongs to field set no. 1";
5133  case 2:
5134  return "Belongs to field set no. 2";
5135  default:
5136  return "Unknown!";
5137  }
5138 
5139  }
5140 
5146  std::string SickLMS2xx::_sickSubtractiveFieldsToString( const uint8_t subt_field_code ) const {
5147 
5148  switch(subt_field_code) {
5149  case 0:
5150  return "Not active";
5151  case 1:
5152  return "Active";
5153  default:
5154  return "Unknown!";
5155  }
5156 
5157  }
5158 
5164  std::string SickLMS2xx::_sickContourFunctionToString( const uint8_t contour_function_code ) const {
5165 
5166  switch(contour_function_code) {
5167  case 0:
5168  return "Not active";
5169  default: {
5170 
5171  /* For converting an int to string */
5172  std::ostringstream output_str;
5173 
5174  /* Indicate its active and include min object size */
5175  output_str << "Active, Min object size: " << (int)contour_function_code << " (cm)";
5176  return output_str.str();
5177 
5178  }
5179  }
5180 
5181  }
5182 
5188  std::string SickLMS2xx::_sickVariantToString( const unsigned int sick_variant ) const {
5189 
5190  /* Return the correct string */
5191  if(sick_variant == SICK_LMS_VARIANT_2XX_TYPE_6) {
5192  return "Standard device (LMS2xx,type 6)";
5193  }
5194  else if (sick_variant == SICK_LMS_VARIANT_SPECIAL) {
5195  return "Special device (LMS211-/221-S19/-S20)";
5196  }
5197  else {
5198  return "Unknown";
5199  }
5200 
5201  }
5202 
5203 } //namespace SickToolbox
LMS has encountered an error.
Definition: SickLMS2xx.hh:172
uint8_t sick_partial_scan_index
Indicates the start angle of the scan (This is useful for partial scans)
Definition: SickLMS2xx.hh:463
uint8_t sick_restart
Indicates the restart level of the device.
Definition: SickLMS2xx.hh:382
sick_lms_2xx_peak_threshold_t
Sick peak threshold. Only valid for Sick LMS 200/220!
Definition: SickLMS2xx.hh:158
uint8_t sick_variant
Sick variant {special,standard}.
Definition: SickLMS2xx.hh:257
bool _isSickLMS220() const
Indicates whether the Sick is an LMS 220.
Definition: SickLMS2xx.cc:4843
void _recvMessage(SickLMS2xxMessage &sick_message, const unsigned int timeout_value) const
std::string _sickContourFunctionToString(const uint8_t contour_function_code) const
Converts Sick LMS contour function code to a corresponding string.
Definition: SickLMS2xx.cc:5164
Standard sensitivity: 30m @ 10% reflectivity.
Definition: SickLMS2xx.hh:147
uint16_t sick_pollution_vals[8]
Calibrating the pollution channels.
Definition: SickLMS2xx.hh:297
void PrintSickConfig() const
Prints out the Sick LMS configurations parameters.
Definition: SickLMS2xx.cc:2000
#define DEFAULT_SICK_LMS_2XX_BYTE_INTERVAL
Minimum time in microseconds between transmitted bytes.
Definition: SickLMS2xx.hh:38
void AcquireDataStream()
Acquires a lock on the data stream.
uint16_t sick_reference_scale_1_dark_100
Receive signal amplitude in ADC incs when reference signal is switched off (Signal 1...
Definition: SickLMS2xx.hh:314
uint16_t sick_num_range_measurements
Number of range measurements.
Definition: SickLMS2xx.hh:497
uint16_t sick_current_angle
Angle used for power measurement.
Definition: SickLMS2xx.hh:319
uint8_t sick_peak_threshold
Peak threshold/black correction (This applies to Sick LMS 200/220 models, when Sick LMS 211/221/291 m...
Definition: SickLMS2xx.hh:374
SickLMS2xx(const std::string sick_device_path)
Primary constructor.
Definition: SickLMS2xx.cc:45
Low sensitivity: 20m @ 10% reflectivity.
Definition: SickLMS2xx.hh:149
uint8_t sick_contour_a_stop_angle
When contour function is active the stop angle of area to be monitored is defined (deg) ...
Definition: SickLMS2xx.hh:389
uint16_t sick_num_measurements
Number of measurements.
Definition: SickLMS2xx.hh:456
void _switchSickOperatingMode(const uint8_t sick_mode, const uint8_t *const mode_params=NULL)
Attempts to switch the operating mode of the Sick LMS 2xx.
Definition: SickLMS2xx.cc:4122
sick_lms_2xx_baud_t
Defines available Sick LMS 2xx baud rates.
Definition: SickLMS2xx.hh:223
sick_lms_2xx_scan_resolution_t
Defines the available resolution settings for the Sick LMS 2xx.
Definition: SickLMS2xx.hh:125
uint8_t sick_sample_size
Number of scans used in computing the returned mean.
Definition: SickLMS2xx.hh:481
struct termios _old_term
Definition: SickLMS2xx.hh:753
#define DEFAULT_SICK_LMS_2XX_SICK_MESSAGE_TIMEOUT
The max time to wait for a message reply (usecs)
Definition: SickLMS2xx.hh:34
void PrintSickStatus() const
Prints ths status of the Sick LMS 2xx unit.
Definition: SickLMS2xx.cc:1986
unsigned int GetPayloadLength() const
Definition: SickMessage.hh:68
Streams measured values of partial scan directly after measurement.
Definition: SickLMS2xx.hh:211
uint8_t sick_contour_c_negative_tolerance_band
When contour function is active the negative tolerance is defined in (cm)
Definition: SickLMS2xx.hh:397
static std::string SickStatusToString(const sick_lms_2xx_status_t sick_status)
Converts the Sick LMS 2xx status code to a string.
Definition: SickLMS2xx.cc:2166
uint8_t sick_real_time_scan_index
If real-time scan indices are requested, this value is set (modulo 256)
Definition: SickLMS2xx.hh:462
void SetSickSensitivity(const sick_lms_2xx_sensitivity_t sick_sensitivity=SICK_SENSITIVITY_STANDARD)
Sets the Sick LMS sensitivity level.
Definition: SickLMS2xx.cc:440
A structure for aggregating the data that collectively defines the system software for the Sick LMS 2...
Definition: SickLMS2xx.hh:270
uint16_t sick_subrange_stop_index
Measurement subrange stop index.
Definition: SickLMS2xx.hh:478
uint8_t sick_measuring_units
Sick measuring units {cm,mm}.
Definition: SickLMS2xx.hh:255
uint8_t sick_availability_level
Availability level of the Sick LMS.
Definition: SickLMS2xx.hh:376
bool _isSickLMS221() const
Indicates whether the Sick is an LMS 221.
Definition: SickLMS2xx.cc:4859
uint8_t sick_real_time_scan_index
If real-time scan indices are requested, this value is set (modulo 256)
Definition: SickLMS2xx.hh:507
uint16_t sick_measurements[SICK_MAX_NUM_MEASUREMENTS]
Range/reflectivity measurement buffer.
Definition: SickLMS2xx.hh:457
bool _testSickBaud(const sick_lms_2xx_baud_t baud_rate)
Attempts to detect whether the LMS is operating at the given baud rate.
Definition: SickLMS2xx.cc:2590
uint8_t sick_single_measured_value_evaluation_mode
Multiple evaluation (min: 1, max: 125)
Definition: SickLMS2xx.hh:401
A structure for aggregating the data that collectively defines the operating status of the device...
Definition: SickLMS2xx.hh:247
std::string _sickSubtractiveFieldsToString(const uint8_t subt_field_code) const
Converts Sick LMS subtractive fields code to a corresponding string.
Definition: SickLMS2xx.cc:5146
sick_lms_2xx_baud_status_t _sick_baud_status
Definition: SickLMS2xx.hh:738
uint8_t _sick_mean_value_sample_size
Definition: SickLMS2xx.hh:744
Installation mode for writing EEPROM.
Definition: SickLMS2xx.hh:199
uint8_t sick_telegram_index
Telegram index modulo 256.
Definition: SickLMS2xx.hh:461
uint8_t sick_field_b_values[SICK_MAX_NUM_MEASUREMENTS]
Reflects the Field B but value returned w/ range measurement.
Definition: SickLMS2xx.hh:418
bool _returningRealTimeIndices() const
Definition: SickLMS2xx.hh:867
uint16_t sick_reference_target_mean_measured_vals
Reference target "mean measured values." Low byte: Current number of filtered mean measured values...
Definition: SickLMS2xx.hh:328
void _parseSickScanProfileB7(const uint8_t *const src_buffer, sick_lms_2xx_scan_profile_b7_t &sick_scan_profile) const
Parses a byte sequence into a scan profile corresponding to message B7.
Definition: SickLMS2xx.cc:4392
bool _validSickMeasuringUnits(const sick_lms_2xx_measuring_units_t sick_units) const
Indicates whether the given measuring units are valid/defined.
Definition: SickLMS2xx.cc:4784
#define DEFAULT_SICK_LMS_2XX_SICK_SWITCH_MODE_TIMEOUT
Can take the Sick LD up to 3 seconds to reply (usecs)
Definition: SickLMS2xx.hh:35
Sick LMS 2xx returns reflectivity (echo amplitude) values instead of range measurements.
Definition: SickLMS2xx.hh:189
sick_lms_2xx_pollution_status_t _sick_pollution_status
Definition: SickLMS2xx.hh:729
Contains some simple exception classes.
uint16_t sick_scan_angle
Sick scanning angle (deg)
Definition: SickLMS2xx.hh:248
A structure for aggregating the data that collectively defines the pollution values and settings for ...
Definition: SickLMS2xx.hh:296
uint8_t sick_contour_b_start_angle
When contour function is active the start angle of area to be monitored is defined (deg) ...
Definition: SickLMS2xx.hh:393
uint8_t sick_contour_b_negative_tolerance_band
When contour function is active the negative tolerance is defined in (cm) uint8_t sick_contour_b_star...
Definition: SickLMS2xx.hh:392
sick_lms_2xx_status_t
Defines the status of the Sick LMS 2xx unit.
Definition: SickLMS2xx.hh:170
uint16_t sick_signal_amplitude_calibration_val
Calibration of the laser power.
Definition: SickLMS2xx.hh:322
uint16_t sick_angle_of_measurement
Angles used to reference target for power measurement.
Definition: SickLMS2xx.hh:321
uint8_t sick_field_evaluation_number
Number of evaluations when the field is infirnged (lies in [1,125])
Definition: SickLMS2xx.hh:342
uint16_t sick_baud_rate
Sick baud as reported by the device.
Definition: SickLMS2xx.hh:357
uint16_t host_to_sick_lms_2xx_byte_order(uint16_t value)
Converts host byte order (little-endian) to Sick LMS byte order (little-endian)
uint8_t sick_temporary_field
Indicates whether the temporary field is being used.
Definition: SickLMS2xx.hh:379
uint8_t sick_multiple_evaluation_offset_field_2
Offset for multiple evaluation of field set 2 (see page 105 of telegram listing)
Definition: SickLMS2xx.hh:344
void GetSickScan(unsigned int *const measurement_values, unsigned int &num_measurement_values, unsigned int *const sick_field_a_values=NULL, unsigned int *const sick_field_b_values=NULL, unsigned int *const sick_field_c_values=NULL, unsigned int *const sick_telegram_index=NULL, unsigned int *const sick_real_time_scan_index=NULL)
Returns the most recent measured values obtained by the Sick LMS 2xx.
Definition: SickLMS2xx.cc:977
uint8_t sick_contour_b_stop_angle
When contour function is active the stop angle of area to be monitored is defined (deg) ...
Definition: SickLMS2xx.hh:394
uint16_t sick_subrange_start_index
Measurement subrange start index.
Definition: SickLMS2xx.hh:477
std::string GetSickSoftwareVersionAsString() const
Acquire the Sick LMS&#39;s operating params as a printable string.
Definition: SickLMS2xx.cc:1909
void SetSickAvailability(const uint8_t sick_availability_flags=SICK_FLAG_AVAILABILITY_DEFAULT)
Sets the availability level of the device.
Definition: SickLMS2xx.cc:745
A class for monitoring the receive buffer when interfacing with a Sick LMS LIDAR. ...
uint8_t sick_field_c_values[SICK_MAX_NUM_MEASUREMENTS]
Reflects the Field C (or dazzle - depending upon sensor mode) value returned w/ range measurement...
Definition: SickLMS2xx.hh:505
void Initialize(const sick_lms_2xx_baud_t desired_baud_rate, const uint32_t delay=0)
Attempts to initialize the Sick LMS 2xx and then sets communication at at the given baud rate...
Definition: SickLMS2xx.cc:98
uint16_t sick_reference_pollution_calibration_vals[4]
Reference pollution calibration values.
Definition: SickLMS2xx.hh:300
void SetSickPeakThreshold(const sick_lms_2xx_peak_threshold_t sick_peak_threshold=SICK_PEAK_THRESHOLD_DETECTION_WITH_NO_BLACK_EXTENSION)
Sets the Sick LMS sensitivity level.
Definition: SickLMS2xx.cc:518
void _parseSickScanProfileBF(const uint8_t *const src_buffer, sick_lms_2xx_scan_profile_bf_t &sick_scan_profile) const
Parses a byte sequence into a scan profile corresponding to message B6.
Definition: SickLMS2xx.cc:4431
#define B500000
Definition: SickLMS2xx.cc:35
std::string _sickTemporaryFieldToString(const uint8_t temp_field_code) const
Converts Sick LMS temporary field code to a corresponding string.
Definition: SickLMS2xx.cc:5126
static std::string SickMeasuringModeToString(const sick_lms_2xx_measuring_mode_t sick_measuring_mode)
Converts the Sick measuring mode to a corresponding string.
Definition: SickLMS2xx.cc:2181
uint16_t sick_reference_pollution_vals[4]
Reference pollution values.
Definition: SickLMS2xx.hh:299
uint8_t GetSickAvailability() const
Gets the current Sick LMS 2xx availability level flags.
Definition: SickLMS2xx.cc:821
uint16_t sick_blanking
Maximum diameter of objects that are not to be detected (units cm)
Definition: SickLMS2xx.hh:371
void SetDataStream(const unsigned int sick_fd)
A method for setting/changing the current data stream.
uint16_t sick_measurements[SICK_MAX_NUM_MEASUREMENTS]
Range/reflectivity measurement buffer.
Definition: SickLMS2xx.hh:480
uint16_t sick_num_reflect_measurements
Number of reflectivity measurements.
Definition: SickLMS2xx.hh:498
std::string GetSickDevicePath() const
Gets the Sick LMS 2xx device path.
Definition: SickLMS2xx.cc:295
uint8_t sick_field_a_values[SICK_MAX_NUM_MEASUREMENTS]
Reflects the Field A bit value returned w/ range measurement.
Definition: SickLMS2xx.hh:503
bool _validSickSensitivity(const sick_lms_2xx_sensitivity_t sick_sensitivity) const
Indicates whether the given sensitivity is defined.
Definition: SickLMS2xx.cc:4953
void SetSickMeasuringUnits(const sick_lms_2xx_measuring_units_t sick_units=SICK_MEASURING_UNITS_MM)
Sets the measurement units for the device.
Definition: SickLMS2xx.cc:351
uint8_t sick_pixel_oriented_evaluation
Pixel oriented evaluation.
Definition: SickLMS2xx.hh:400
static std::string SickOperatingModeToString(const sick_lms_2xx_operating_mode_t sick_operating_mode)
Converts the Sick operating mode to a corresponding string.
Definition: SickLMS2xx.cc:2212
uint8_t sick_telegram_index
Telegram index modulo 256.
Definition: SickLMS2xx.hh:439
uint16_t sick_peak_threshold_target_value
Target value of the peak threshold in ADC incs.
Definition: SickLMS2xx.hh:324
sick_lms_2xx_measuring_mode_t
Defines the measurment modes supported by Sick LMS 2xx.
Definition: SickLMS2xx.hh:180
uint8_t sick_contour_a_negative_tolerance_band
When contour function is active the negative tolerance is defined in (cm)
Definition: SickLMS2xx.hh:387
static sick_lms_2xx_baud_t StringToSickBaud(const std::string baud_str)
Converts string to corresponding Sick LMS baud.
Definition: SickLMS2xx.cc:2151
Streams minimum measured values for each segment in a sub-range.
Definition: SickLMS2xx.hh:213
sick_lms_2xx_baud_t _curr_session_baud
Definition: SickLMS2xx.hh:711
void ReleaseDataStream()
Releases a lock on the data stream.
Streams all measured values in a scan.
Definition: SickLMS2xx.hh:205
~SickLMS2xx()
Destructor.
Definition: SickLMS2xx.cc:71
Streams mean values from a sample size of n consecutive scans.
Definition: SickLMS2xx.hh:207
void _getSickType()
Acquires the sick device type (as a string) from the unit.
Definition: SickLMS2xx.cc:2781
sick_lms_2xx_type_t GetSickType() const
Gets the Sick LMS 2xx type.
Definition: SickLMS2xx.cc:303
sick_lms_2xx_sensitivity_t
Sick sensitivities. Only valid for Sick LMS 211/221/291!
Definition: SickLMS2xx.hh:146
void _setupConnection()
Attempts to open a I/O stream using the device path given at object instantiation.
Definition: SickLMS2xx.cc:2321
uint8_t sick_multiple_evaluation_suppressed_objects
Multiple evaluation for objects less than the blanking size.
Definition: SickLMS2xx.hh:384
Scanning angle of 180 degrees.
Definition: SickLMS2xx.hh:117
No peak threshold detection, active black extension.
Definition: SickLMS2xx.hh:162
void GetSickMeanValues(const uint8_t sick_sample_size, unsigned int *const measurement_values, unsigned int &num_measurement_values, unsigned int *const sick_telegram_index=NULL, unsigned int *const sick_real_time_index=NULL)
Returns the most recent mean measured values from the Sick LMS 2xx.
Definition: SickLMS2xx.cc:1519
A structure for aggregating the data that define a scan profile obtained from reply B0 (See page 49 T...
Definition: SickLMS2xx.hh:414
uint8_t sick_subtractive_fields
Indicates whether fields A and B are subtractive.
Definition: SickLMS2xx.hh:380
Scanning angle of 100 degrees.
Definition: SickLMS2xx.hh:116
std::string _sick_device_path
Definition: SickLMS2xx.hh:708
sick_lms_2xx_sensitivity_t GetSickSensitivity() const
Gets the current Sick LMS 2xx sensitivity level.
Definition: SickLMS2xx.cc:596
Measurement range 8/80m; reflector bits in 8 levels.
Definition: SickLMS2xx.hh:182
double GetSickScanResolution() const
Gets the current angular resolution.
Definition: SickLMS2xx.cc:335
uint16_t sick_subrange_start_index
Measurement subrange start index.
Definition: SickLMS2xx.hh:454
#define DEFAULT_SICK_LMS_2XX_SICK_ADDRESS
Sick LMS default serial address.
Definition: SickLMS2xx.hh:32
void SetSickVariant(const sick_lms_2xx_scan_angle_t scan_angle, const sick_lms_2xx_scan_resolution_t scan_resolution)
Sets the variant of the Sick LMS 2xx (scan angle and scan resolution)
Definition: SickLMS2xx.cc:838
uint16_t sick_reference_scale_1_dark_66
Receive signal amplitude in ADC incs when reference signal is switched off (Signal 1...
Definition: SickLMS2xx.hh:316
Defines simple utility functions for working with the Sick LMS 2xx laser range finder units...
Definition of class SickLMS2xxMessage.
uint8_t sick_measuring_units
Measured value and field value units.
Definition: SickLMS2xx.hh:378
uint8_t sick_real_time_scan_index
If real-time scan indices are requested, this value is set (modulo 256)
Definition: SickLMS2xx.hh:483
Medium sensitivity: 25m @ 10% reflectivity.
Definition: SickLMS2xx.hh:148
virtual const char * what() const
From the standard exception library.
uint8_t sick_real_time_scan_index
If real-time scan indices are requested, this value is set (modulo 256)
Definition: SickLMS2xx.hh:440
uint16_t sick_reflect_subrange_start_index
Start index of the measured reflectivity value subrange.
Definition: SickLMS2xx.hh:501
void _extractSickMeasurementValues(const uint8_t *const byte_sequence, const uint16_t num_measurements, uint16_t *const measured_values, uint8_t *const field_a_values=NULL, uint8_t *const field_b_values=NULL, uint8_t *const field_c_values=NULL) const
Extracts the measured values (w/ flags) that were returned by the device.
Definition: SickLMS2xx.cc:4624
void _setSickConfig(const sick_lms_2xx_device_config_t &sick_config)
Sets the current configuration in flash.
Definition: SickLMS2xx.cc:2957
A structure for aggregating the data that define a scan profile obtained from reply B4 (See page 79 T...
Definition: SickLMS2xx.hh:496
uint8_t sick_system_software_version[8]
Sick system software version.
Definition: SickLMS2xx.hh:271
uint16_t sick_num_measurements
Number of measurements.
Definition: SickLMS2xx.hh:436
sick_lms_2xx_operating_mode_t GetSickOperatingMode() const
Gets the current Sick LMS 2xx operating mode.
Definition: SickLMS2xx.cc:729
Scanning angle of 90 degrees.
Definition: SickLMS2xx.hh:115
void _parseSickScanProfileB0(const uint8_t *const src_buffer, sick_lms_2xx_scan_profile_b0_t &sick_scan_profile) const
Parses a byte sequence into a scan profile corresponding to message B0.
Definition: SickLMS2xx.cc:4329
void _setTerminalBaud(const sick_lms_2xx_baud_t sick_baud)
Sets the local terminal baud rate.
Definition: SickLMS2xx.cc:2653
static std::string SickSensitivityToString(const sick_lms_2xx_sensitivity_t sick_sensitivity)
Converts Sick LMS 2xx sensitivity level to a corresponding string.
Definition: SickLMS2xx.cc:2260
uint8_t sick_restart_time
Inidicates the restart time of the device.
Definition: SickLMS2xx.hh:383
void _setSickOpModeInstallation()
Sets the device to installation mode.
Definition: SickLMS2xx.cc:3502
uint8_t sick_contour_c_stop_angle
When contour function is active the stop angle of area to be monitored is defined (deg) ...
Definition: SickLMS2xx.hh:399
sick_lms_2xx_measuring_units_t
Defines the available Sick LMS 2xx measured value units.
Definition: SickLMS2xx.hh:136
uint16_t _sick_values_subrange_start_index
Definition: SickLMS2xx.hh:747
uint16_t sick_num_motor_revs
Sick number of motor revs.
Definition: SickLMS2xx.hh:250
bool _isSickLMS211() const
Indicates whether the Sick is an LMS 211.
Definition: SickLMS2xx.cc:4815
uint8_t sick_sample_size
Number of scans used in computing the returned mean.
Definition: SickLMS2xx.hh:438
uint16_t sick_reference_scale_2_dark_100
Receive signal amplitude in ADC incs when reference signal is switched off (Signal 2...
Definition: SickLMS2xx.hh:315
Measurement range 16m; fields A and B.
Definition: SickLMS2xx.hh:185
sick_lms_2xx_baud_t _baudToSickBaud(const int baud_rate) const
Converts a termios baud to an equivalent Sick baud.
Definition: SickLMS2xx.cc:5016
Measurement range 32m; immediate data transmission, no flags.
Definition: SickLMS2xx.hh:188
A structure for aggregating the data that define a scan profile obtained from reply B7 (See page 63 T...
Definition: SickLMS2xx.hh:453
sick_lms_2xx_baud_t _desired_session_baud
Definition: SickLMS2xx.hh:714
static std::string SickBaudToString(const sick_lms_2xx_baud_t baud_rate)
Converts Sick LMS baud to a corresponding string.
Definition: SickLMS2xx.cc:2109
A structure for aggregating the data that collectively define the signal config and status...
Definition: SickLMS2xx.hh:313
bool _isSickLMS291() const
Indicates whether the Sick is an LMS 291.
Definition: SickLMS2xx.cc:4889
void _getSickStatus()
Acquires (and buffers) the status of the Sick LMS 2xx.
Definition: SickLMS2xx.cc:3216
A structure for aggregating the data that collectively defines the system restart config for the Sick...
Definition: SickLMS2xx.hh:281
uint8_t sick_field_a_values[SICK_MAX_NUM_MEASUREMENTS]
Reflects the Field A bit value returned w/ range measurement.
Definition: SickLMS2xx.hh:458
Diagnostic mode for testing purposes.
Definition: SickLMS2xx.hh:200
Special models (i.e. LMS211-/221-S19/-S20.
Definition: SickLMS2xx.hh:106
void _setSickOpModeMonitorStreamValuesFromPartialScan()
Sets the device to monitor mode and tells it to start sending partial scans.
Definition: SickLMS2xx.cc:3805
bool IsSickLMS2xxFast() const
Indicates whether the device is an LMS Fast.
Definition: SickLMS2xx.cc:1783
uint16_t sick_range_measurements[SICK_MAX_NUM_MEASUREMENTS]
Range measurement buffer.
Definition: SickLMS2xx.hh:499
Measurement range 16m; reflector bits in 4 levels.
Definition: SickLMS2xx.hh:184
std::string _sickRestartToString(const uint8_t restart_code) const
Converts restart code to a corresponding string.
Definition: SickLMS2xx.cc:5085
static std::string SickTypeToString(const sick_lms_2xx_type_t sick_type)
Converts the Sick LMS type to a corresponding string.
Definition: SickLMS2xx.cc:2009
void _getSickConfig()
Acquires (and buffers) the current Sick LMS configuration from the device.
Definition: SickLMS2xx.cc:2899
sick_lms_2xx_scan_angle_t
Defines the scan angle for the Sick LMS 2xx.
Definition: SickLMS2xx.hh:114
void GetPayload(uint8_t *const payload_buffer) const
Get the payload contents as a sequence of well-formed bytes.
Definition: SickMessage.hh:156
bool _validSickScanAngle(const sick_lms_2xx_scan_angle_t sick_scan_angle) const
Indicates whether the given scan angle is defined.
Definition: SickLMS2xx.cc:4917
void Uninitialize()
Uninitializes the LMS by putting it in a mode where it stops streaming data, and returns it to the de...
Definition: SickLMS2xx.cc:229
sick_lms_2xx_measuring_mode_t GetSickMeasuringMode() const
Gets the current Sick LMS 2xx measuring mode.
Definition: SickLMS2xx.cc:713
uint8_t sick_permanent_baud_rate
0 - When power is switched on baud rate is 9600/1 - configured transmission rate is used ...
Definition: SickLMS2xx.hh:358
sick_lms_2xx_signal_status_t _sick_signal_status
Definition: SickLMS2xx.hh:732
uint16_t sick_dazzling_multiple_evaluation
Number of scans that take place before LMS switches the outputs (only applies to availability level 1...
Definition: SickLMS2xx.hh:373
static sick_lms_2xx_scan_angle_t IntToSickScanAngle(const int scan_angle_int)
Converts integer to corresponding Sick LMS scan angle.
Definition: SickLMS2xx.cc:2062
Streams measured values with associated flags.
Definition: SickLMS2xx.hh:210
Sends measured range values on request (i.e. when polled)
Definition: SickLMS2xx.hh:206
Sends the min measured values when object is detected.
Definition: SickLMS2xx.hh:202
#define DEFAULT_SICK_LMS_2XX_SICK_BAUD
Initial baud rate of the LMS (whatever is set in flash)
Definition: SickLMS2xx.hh:30
sick_lms_2xx_peak_threshold_t GetSickPeakThreshold() const
Gets the current Sick LMS 2xx sensitivity level.
Definition: SickLMS2xx.cc:618
std::string GetSickStatusAsString() const
Acquire the Sick LMS&#39;s status as a printable string.
Definition: SickLMS2xx.cc:1876
std::string GetSickConfigAsString() const
Acquire the Sick LMS&#39;s config as a printable string.
Definition: SickLMS2xx.cc:1936
void _setSessionBaud(const sick_lms_2xx_baud_t baud_rate)
Sets the baud rate for the current communication session.
Definition: SickLMS2xx.cc:2530
uint8_t sick_contour_a_start_angle
When contour function is active the start angle of area to be monitored is defined (deg) ...
Definition: SickLMS2xx.hh:388
Provides an abstract parent for all Sick LIDAR devices.
Definition: SickLIDAR.hh:53
uint8_t sick_field_b_values[SICK_MAX_NUM_MEASUREMENTS]
Reflects the Field B but value returned w/ range measurement.
Definition: SickLMS2xx.hh:459
uint16_t sick_peak_threshold_actual_value
Actual value of the peak threshold in ADC incs.
Definition: SickLMS2xx.hh:326
Definition of class SickLMS2xx. Code by Jason C. Derenick and Thomas H. Miller. Contact derenick(at)l...
uint8_t sick_contour_a_positive_tolerance_band
When contour function is active the positive tolerance is defined in (cm)
Definition: SickLMS2xx.hh:386
uint16_t sick_num_measurements
Number of measurements.
Definition: SickLMS2xx.hh:415
sick_lms_2xx_restart_status_t _sick_restart_status
Definition: SickLMS2xx.hh:726
Measurement range 32m; reflector bit in 2 levels.
Definition: SickLMS2xx.hh:186
uint16_t sick_reference_target_single_measured_vals
Reference target "single measured values." Low byte: Current number of filtered single measured value...
Definition: SickLMS2xx.hh:327
sick_lms_2xx_type_t _sick_type
Definition: SickLMS2xx.hh:717
void SetSickMeasuringMode(const sick_lms_2xx_measuring_mode_t sick_measuring_mode=SICK_MS_MODE_8_OR_80_FA_FB_DAZZLE)
Sets the measuring mode for the device.
Definition: SickLMS2xx.cc:640
High sensitivity: 42m @ 10% reflectivity.
Definition: SickLMS2xx.hh:150
A structure for aggregating the data that collectively defines the Sick&#39;s config. ...
Definition: SickLMS2xx.hh:370
#define DEFAULT_SICK_LMS_2XX_NUM_TRIES
The max number of tries before giving up on a request.
Definition: SickLMS2xx.hh:39
static sick_lms_2xx_scan_resolution_t DoubleToSickScanResolution(const double scan_resolution_double)
Converts double to corresponding Sick LMS scan resolution.
Definition: SickLMS2xx.cc:2100
uint8_t sick_telegram_index
Telegram index modulo 256.
Definition: SickLMS2xx.hh:420
Peak threshold detection, active black extension.
Definition: SickLMS2xx.hh:160
void _setSickOpModeMonitorRequestValues()
Sets the device to monitor mode and tells it to send values only upon request.
Definition: SickLMS2xx.cc:3621
void _setSickOpModeMonitorStreamMeanValues(const uint8_t sample_size)
Sets the device to monitor mode and tells it to send mean measured values.
Definition: SickLMS2xx.cc:3865
double GetSickScanAngle() const
Gets the current scan angle of the device.
Definition: SickLMS2xx.cc:319
uint16_t sick_signal_amplitude
Laser power in % of calibration value.
Definition: SickLMS2xx.hh:318
void _setSickOpModeMonitorStreamValues()
Sets the device to monitor mode and tells it to stream measured values.
Definition: SickLMS2xx.cc:3677
uint8_t sick_field_a_values[SICK_MAX_NUM_MEASUREMENTS]
Reflects the Field A bit value returned w/ range measurement.
Definition: SickLMS2xx.hh:417
Measurement range 32m; field A.
Definition: SickLMS2xx.hh:187
uint8_t sick_field_set_number
Active field set number.
Definition: SickLMS2xx.hh:343
bool _isSickUnknown() const
Indicates whether the Sick type is unknown.
Definition: SickLMS2xx.cc:4909
Standard: peak threshold detection, no black extension.
Definition: SickLMS2xx.hh:159
void ResetSick()
Reset the Sick LMS 2xx active field values NOTE: Considered successful if the LMS ready message is re...
Definition: SickLMS2xx.cc:1800
sick_lms_2xx_operating_mode_t
Defines the operating modes supported by Sick LMS 2xx. See page 41 of the LMS 2xx telegram manual for...
Definition: SickLMS2xx.hh:198
Defines a class for monitoring the receive buffer when interfacing w/ a Sick LMS 2xx laser range find...
uint8_t sick_telegram_index
Telegram index modulo 256.
Definition: SickLMS2xx.hh:482
void _parseSickScanProfileB6(const uint8_t *const src_buffer, sick_lms_2xx_scan_profile_b6_t &sick_scan_profile) const
Parses a byte sequence into a scan profile corresponding to message B6.
Definition: SickLMS2xx.cc:4362
Sick outputs navigation data records.
Definition: SickLMS2xx.hh:214
bool _validSickScanResolution(const sick_lms_2xx_scan_resolution_t sick_scan_resolution) const
Indicates whether the given scan resolution is defined.
Definition: SickLMS2xx.cc:4935
uint16_t sick_lms_2xx_to_host_byte_order(uint16_t value)
Converts Sick LMS byte order (little-endian) to host byte order (little-endian)
uint16_t sick_pollution_calibration_vals[8]
Calibrating the pollution channel values.
Definition: SickLMS2xx.hh:298
void BuildMessage(uint8_t dest_address, const uint8_t *const payload_buffer, const unsigned int payload_length)
Consructs a message object from given parameter values.
void GetSickPartialScan(unsigned int *const measurement_values, unsigned int &num_measurement_values, unsigned int &partial_scan_index, unsigned int *const sick_field_a_values=NULL, unsigned int *const sick_field_b_values=NULL, unsigned int *const sick_field_c_values=NULL, unsigned int *const sick_telegram_index=NULL, unsigned int *const sick_real_time_scan_index=NULL)
Returns the most recent partial scan obtained by Sick LMS 2xx.
Definition: SickLMS2xx.cc:1388
void GetSickScanSubrange(const uint16_t sick_subrange_start_index, const uint16_t sick_subrange_stop_index, unsigned int *const measurement_values, unsigned int &num_measurement_values, unsigned int *const sick_field_a_values=NULL, unsigned int *const sick_field_b_values=NULL, unsigned int *const sick_field_c_values=NULL, unsigned int *const sick_telegram_index=NULL, unsigned int *const sick_real_time_scan_index=NULL)
Returns the most recent measured values from the corresponding subrange.
Definition: SickLMS2xx.cc:1250
sick_lms_2xx_device_config_t _sick_device_config
Definition: SickLMS2xx.hh:741
uint8_t sick_telegram_index
Telegram index modulo 256.
Definition: SickLMS2xx.hh:506
uint8_t sick_multiple_evaluation
Multiple evalutation of scan data.
Definition: SickLMS2xx.hh:381
std::string _sickAvailabilityToString(const uint8_t availability_code) const
Converts given restart level to a corresponding string.
Definition: SickLMS2xx.cc:5039
uint8_t sick_field_c_values[SICK_MAX_NUM_MEASUREMENTS]
Reflects the Field C (or dazzle - depending upon sensor mode) value returned w/ range measurement...
Definition: SickLMS2xx.hh:460
uint16_t sick_reflect_subrange_stop_index
Stop index of the measured reflectivity value subrange.
Definition: SickLMS2xx.hh:502
A structure for aggregating the data that define a scan profile obtained from reply BF (See page 71 T...
Definition: SickLMS2xx.hh:476
static std::string SickPeakThresholdToString(const sick_lms_2xx_peak_threshold_t sick_peak_threshold)
Converts Sick LMS 2xx peak threshold to a corresponding string.
Definition: SickLMS2xx.cc:2282
uint16_t sick_stop_threshold_actual_value
Actual value of the stop threshold in ADC incs.
Definition: SickLMS2xx.hh:325
virtual void _sendMessageAndGetReply(const SICK_MSG_CLASS &send_message, SICK_MSG_CLASS &recv_message, const uint8_t *const byte_sequence, const unsigned int byte_sequence_length, const unsigned int byte_interval, const unsigned int timeout_value, const unsigned int num_tries)
Definition: SickLIDAR.hh:396
Encapsulates the Sick LIDAR Matlab/C++ toolbox.
Definition: SickLD.cc:44
sick_lms_2xx_operating_status_t _sick_operating_status
Definition: SickLMS2xx.hh:720
Measured values are in centimeters.
Definition: SickLMS2xx.hh:137
void _setSickOpModeMonitorStreamValuesSubrange(const uint16_t subrange_start_index, const uint16_t subrange_stop_index)
Sets the device to monitor mode and tells it to send a measured value subrange.
Definition: SickLMS2xx.cc:3936
uint8_t sick_measuring_mode
Measuring mode of the device.
Definition: SickLMS2xx.hh:377
Streams measured range from a scan and sub-range of reflectivity values.
Definition: SickLMS2xx.hh:215
SickLMS2xx::sick_lms_2xx_measuring_units_t GetSickMeasuringUnits() const
Gets the current Sick LMS 2xx measuring units.
Definition: SickLMS2xx.cc:424
A structure for aggregating the data that collectively define the baud config.
Definition: SickLMS2xx.hh:356
uint8_t sick_stop_threshold
Stop threshold in mV (This only applies to Sick LMS 200/220 models)
Definition: SickLMS2xx.hh:375
Sends min vertical distance to object when detected.
Definition: SickLMS2xx.hh:204
bool _validSickMeasuringMode(const sick_lms_2xx_measuring_mode_t sick_measuring_mode) const
Indicates whether the given measuring mode is defined.
Definition: SickLMS2xx.cc:4991
Measured values are in milimeters.
Definition: SickLMS2xx.hh:138
static sick_lms_2xx_baud_t IntToSickBaud(const int baud_int)
Converts integer to corresponding Sick LMS baud.
Definition: SickLMS2xx.cc:2130
#define DEFAULT_SICK_LMS_2XX_SICK_MEAN_VALUES_MESSAGE_TIMEOUT
When using mean values, the Sick can sometimes take more than 10s to respond.
Definition: SickLMS2xx.hh:36
#define DEFAULT_SICK_LMS_2XX_SICK_CONFIG_MESSAGE_TIMEOUT
The sick can take some time to respond to config commands (usecs)
Definition: SickLMS2xx.hh:37
uint16_t sick_subrange_stop_index
Measurement subrange stop index.
Definition: SickLMS2xx.hh:455
void PrintSickSoftwareVersion() const
Prints out relevant software versioning information.
Definition: SickLMS2xx.cc:1993
uint8_t sick_contour_b_positive_tolerance_band
When contour function is active the positive tolerance is defined in (cm)
Definition: SickLMS2xx.hh:391
uint8_t sick_device_status
Sick device status {ok,error}.
Definition: SickLMS2xx.hh:254
uint16_t sick_stop_threshold_target_value
Target value of the stop threshold in ADC incs.
Definition: SickLMS2xx.hh:323
uint16_t sick_measurements[SICK_MAX_NUM_MEASUREMENTS]
Range/reflectivity measurement buffer.
Definition: SickLMS2xx.hh:437
uint16_t sick_measurements[SICK_MAX_NUM_MEASUREMENTS]
Range/reflectivity measurement buffer.
Definition: SickLMS2xx.hh:416
uint16_t sick_reference_scale_2_dark_66
Receive signal amplitude in ADC incs when reference signal is switched off (Signal 2...
Definition: SickLMS2xx.hh:317
A structure for aggregating the data that define a scan profile obtained from reply B6 (See page 61 T...
Definition: SickLMS2xx.hh:435
Thrown instance where the driver can&#39;t read,write,drain,flush,... the buffers.
void _flushTerminalBuffer()
Flushes terminal I/O buffers.
Definition: SickLMS2xx.cc:2396
uint16_t sick_scan_resolution
Sick angular resolution (1/100 deg)
Definition: SickLMS2xx.hh:249
void _teardownConnection()
Closes the data connection associated with the device.
Definition: SickLMS2xx.cc:2374
sick_lms_2xx_status_t GetSickStatus()
Acquire the Sick LMS 2xx status.
Definition: SickLMS2xx.cc:1738
static std::string SickMeasuringUnitsToString(const sick_lms_2xx_measuring_units_t sick_units)
Converts the Sick LMS measurement units to a corresponding string.
Definition: SickLMS2xx.cc:2304
bool _validSickPeakThreshold(const sick_lms_2xx_peak_threshold_t sick_peak_threshold) const
Indicates whether the given peak threshold is valid.
Definition: SickLMS2xx.cc:4972
uint8_t sick_contour_c_start_angle
When contour function is active the start angle of area to be monitored is defined (deg) ...
Definition: SickLMS2xx.hh:398
void _setSickOpModeDiagnostic()
Sets the device to diagnostic mode.
Definition: SickLMS2xx.cc:3561
uint8_t sick_partial_scan_index
Indicates the start angle of the scan (This is useful for partial scans)
Definition: SickLMS2xx.hh:422
#define DEFAULT_SICK_LMS_2XX_SICK_PASSWORD
Password for entering installation mode.
Definition: SickLMS2xx.hh:33
uint8_t sick_field_b_values[SICK_MAX_NUM_MEASUREMENTS]
Reflects the Field B but value returned w/ range measurement.
Definition: SickLMS2xx.hh:504
Measurement range 8/80m; fields A,B, and C.
Definition: SickLMS2xx.hh:183
uint16_t sick_fields_b_c_restart_times
Restart times for fields B and C.
Definition: SickLMS2xx.hh:372
void _parseSickScanProfileC4(const uint8_t *const src_buffer, sick_lms_2xx_scan_profile_c4_t &sick_scan_profile) const
Parses a byte sequence into a scan profile corresponding to message C4.
Definition: SickLMS2xx.cc:4467
uint16_t sick_num_measurements
Number of measurements.
Definition: SickLMS2xx.hh:479
void _parseSickConfigProfile(const uint8_t *const src_buffer, sick_lms_2xx_device_config_t &sick_device_config) const
Parses a byte sequence into a Sick config structure.
Definition: SickLMS2xx.cc:4515
sick_lms_2xx_type_t
Defines the Sick LMS 2xx types. This enum lists all of the supported Sick LMS models.
Definition: SickLMS2xx.hh:63
A structure for aggregating the data that collectively define the signal config and status...
Definition: SickLMS2xx.hh:341
std::string _sickVariantToString(const unsigned int sick_variant) const
Converts the Sick LMS variant to a corresponding string.
Definition: SickLMS2xx.cc:5188
bool _isSickLMS200() const
Indicates whether the Sick is an LMS 200.
Definition: SickLMS2xx.cc:4799
A class to represent all messages sent to and from the Sick LMS 2xx.
Thrown when the driver detects (or the Sick reports) an invalid config.
uint8_t sick_field_c_values[SICK_MAX_NUM_MEASUREMENTS]
Reflects the Field C (or dazzle - depending upon sensor mode) value returned w/ range measurement...
Definition: SickLMS2xx.hh:419
uint8_t sick_contour_c_positive_tolerance_band
When contour function is active the positive tolerance is defined in (cm)
Definition: SickLMS2xx.hh:396
Sick LMS type 291-S14 (LMS Fast)
Definition: SickLMS2xx.hh:92
uint16_t sick_peak_threshold
Peak threshold in ADC incs for power measurement.
Definition: SickLMS2xx.hh:320
sick_lms_2xx_field_status_t _sick_field_status
Definition: SickLMS2xx.hh:735
Makes handling timeouts much easier.
void _setSickOpModeMonitorStreamRangeAndReflectivity()
Sets the device to monitor mode and tells it to stream both range and reflectivity values...
Definition: SickLMS2xx.cc:3737
uint16_t _sick_values_subrange_stop_index
Definition: SickLMS2xx.hh:750
void _sendMessageAndGetReply(const SickLMS2xxMessage &sick_send_message, SickLMS2xxMessage &sick_recv_message, const unsigned int timeout_value, const unsigned int num_tries)
Sends a message and searches for the corresponding reply.
Definition: SickLMS2xx.cc:2437
uint16_t sick_reflect_measurements[SICK_MAX_NUM_MEASUREMENTS]
Reflect measurements buffer.
Definition: SickLMS2xx.hh:500
void _getSickErrors(unsigned int *const num_sick_errors=NULL, uint8_t *const error_type_buffer=NULL, uint8_t *const error_num_buffer=NULL)
Obtains any error codes from the Sick LMS.
Definition: SickLMS2xx.cc:3138
Thrown when error occurs during thread initialization, and uninitialization.
uint8_t sick_prom_software_version[8]
Sick boot prom software version.
Definition: SickLMS2xx.hh:272
void GetSickMeanValuesSubrange(const uint8_t sick_sample_size, const uint16_t sick_subrange_start_index, const uint16_t sick_subrange_stop_index, unsigned int *const measurement_values, unsigned int &num_measurement_values, unsigned int *const sick_telegram_index=NULL, unsigned int *const sick_real_time_index=NULL)
Returns the most recent mean measured values from the specified subrange.
Definition: SickLMS2xx.cc:1633
sick_lms_2xx_software_status_t _sick_software_status
Definition: SickLMS2xx.hh:723
uint8_t sick_real_time_scan_index
If real-time scan indices are requested, this value is set (modulo 256)
Definition: SickLMS2xx.hh:421
void _setSickOpModeMonitorStreamMeanValuesSubrange(const uint16_t sample_size, const uint16_t subrange_start_index, const uint16_t subrange_stop_index)
Sets the device to monitor mode and tells it to send a mean value subrange.
Definition: SickLMS2xx.cc:4025
static sick_lms_2xx_scan_resolution_t IntToSickScanResolution(const int scan_resolution_int)
Converts integer to corresponding Sick LMS scan resolution.
Definition: SickLMS2xx.cc:2081
Measurement range 8m/80m; fields A,B and Dazzle (Default)
Definition: SickLMS2xx.hh:181


sicktoolbox
Author(s): Jason Derenick , Thomas Miller
autogenerated on Tue Sep 10 2019 03:37:34