sick_generic_laser.cpp
Go to the documentation of this file.
1 
62 #ifdef _MSC_VER
63 //#define _WIN32_WINNT 0x0501
64 #pragma warning(disable: 4996)
65 #pragma warning(disable: 4267)
66 #endif
67 
70 #include "softwarePLL.h"
71 #if defined LDMRS_SUPPORT && LDMRS_SUPPORT > 0
73 #endif
74 #if defined SCANSEGMENT_XD_SUPPORT && SCANSEGMENT_XD_SUPPORT > 0
76 #endif
83 
84 #include "launchparser.h"
85 #if __ROS_VERSION != 1 // launchparser for native Windows/Linux and ROS-2
86 #define USE_LAUNCHPARSER // settings and parameter by LaunchParser
87 #endif
88 
89 #define _USE_MATH_DEFINES
90 
91 #include <math.h>
92 #include <string>
93 #include <stdio.h>
94 #include <stdlib.h>
95 #include <signal.h>
96 
97 #ifdef GITHASH
98 #define GITHASH_STR (strlen(GITHASH)>2?(std::string(" githash:")+std::string(GITHASH)):(std::string("")))
99 #else
100 #define GITHASH_STR std::string("")
101 #endif
102 #ifdef GITINFO
103 #define GITINFO_STR (strlen(GITINFO)>2?(std::string(" gitinfo:")+std::string(GITINFO)):(std::string("")))
104 #else
105 #define GITINFO_STR std::string("")
106 #endif
107 
108 #define DELETE_PTR(p) if(p){delete(p);p=0;}
109 
110 static bool s_isInitialized = false;
112 
113 static std::string versionInfo = std::string(SICK_SCAN_XD_VERSION) + GITHASH_STR + GITINFO_STR;
114 static bool s_shutdownSignalReceived = false;
115 
116 void setVersionInfo(std::string _versionInfo)
117 {
118  versionInfo = _versionInfo;
119 }
120 
121 std::string getVersionInfo()
122 {
123  return (versionInfo);
124 }
125 
126 void mainGenericLaserInternal(int argc, char **argv, std::string nodeName, rosNodePtr nhPriv, bool do_ros_spin, int & exit_code);
127 
129 {
130 public:
131  GenericLaserCallable(int _argc, char** _argv, std::string _nodeName, rosNodePtr _nhPriv, int* _exit_code)
132  : argc(_argc), argv(_argv), nodeName(_nodeName), nhPriv(_nhPriv), exit_code(_exit_code)
133  {
135  }
137  {
139  }
140  void join(void)
141  {
142  if(generic_laser_thread && generic_laser_thread->joinable())
143  {
144  generic_laser_thread->join();
145  }
146  }
147  int argc;
148  char** argv;
149  std::string nodeName;
151  int* exit_code;
152  std::thread* generic_laser_thread;
153 };
154 
156 
159 std::string s_status_message = "";
160 int32_t s_verbose_level = 1; // verbose level: 0=DEBUG, 1=INFO, 2=WARN, 3=ERROR, 4=FATAL or 5=QUIET (equivalent to ros::console::levels), default verbose level is 1 (INFO), i.e. print informational, warnings and error messages.
161 
170 bool getTagVal(std::string tagVal, std::string &tag, std::string &val)
171 {
172  bool ret = false;
173  std::size_t pos;
174  pos = tagVal.find(":=");
175  tag = "";
176  val = "";
177  if (pos == std::string::npos)
178  {
179  ret = false;
180  }
181  else
182  {
183  tag = tagVal.substr(0, pos);
184  val = tagVal.substr(pos + 2);
185  ret = true;
186  }
187  return (ret);
188 }
189 
190 bool stopScannerAndExit(bool force_immediate_shutdown)
191 {
192  bool success = true;
193  if (s_scanner != NULL)
194  {
195  if (s_isInitialized)
196  {
197  success = s_scanner->stopScanData(force_immediate_shutdown);
198  }
201  }
203  return success;
204 }
205 
207 {
209 }
210 
211 void rosSignalHandler(int signalRecv)
212 {
213  ROS_INFO_STREAM("Caught signal " << signalRecv << "\n");
214  ROS_INFO_STREAM("good bye\n");
215  ROS_INFO_STREAM("You are leaving the following version of this node:\n");
216  ROS_INFO_STREAM(getVersionInfo() << "\n");
218  ROS_INFO_STREAM("sick_generic_laser: stop and exit (line " << __LINE__ << ")");
219  std::this_thread::sleep_for(std::chrono::milliseconds(100));
220  stopScannerAndExit(true);
221  ROS_INFO_STREAM("sick_generic_laser: exit (line " << __LINE__ << ")");
222  std::this_thread::sleep_for(std::chrono::milliseconds(100));
223  std::cout << "sick_generic_laser: exit (line " << __LINE__ << ")" << std::endl;
224  rosShutdown();
225  std::cout << "sick_generic_laser: exit (line " << __LINE__ << ")" << std::endl;
226 }
227 
233 bool convertSendSOPASCommand(const std::string& sopas_ascii_request, std::string& sopas_response, bool wait_for_reply)
234 {
235  sopas_response = "";
236  std::string sopas_request = sopas_ascii_request;
237  std::vector<unsigned char> sopas_response_raw;
238  if (s_scanner != NULL && s_isInitialized)
239  {
240  if (sopas_ascii_request[0] != 0x02) // append <stx> and <etx>
241  {
242  sopas_request.clear();
243  sopas_request.push_back((char)0x02); // <stx>
244  sopas_request.insert(sopas_request.end(), sopas_ascii_request.begin(), sopas_ascii_request.end());
245  sopas_request.push_back((char)0x03); // <etx>
246  }
247  if (s_scanner->convertSendSOPASCommand(sopas_request, &sopas_response_raw, wait_for_reply) == sick_scan_xd::ExitSuccess)
248  {
249  sopas_response = s_scanner->sopasReplyToString(sopas_response_raw);
250  ROS_INFO_STREAM("convertSendSOPASCommand(): sopas_request = \"" << sopas_ascii_request << "\", sopas_response = \"" << sopas_response << "\"\n");
251  return true;
252  }
253  else
254  {
255  ROS_WARN_STREAM("## WARNING in convertSendSOPASCommand(\"" << sopas_ascii_request << "\"): SickScanCommon::convertSendSOPASCommand() failed.\n");
256  }
257  }
258  else
259  {
260 #if defined SCANSEGMENT_XD_SUPPORT && SCANSEGMENT_XD_SUPPORT > 0
261  sick_scan_xd::SickScanServices* sopas_service = 0;
262  if ((sopas_service = sick_scansegment_xd::sopasService()) != 0)
263  {
264  if (sopas_service->sendSopasAndCheckAnswer(sopas_request, sopas_response_raw, sopas_response))
265  {
266  ROS_INFO_STREAM("convertSendSOPASCommand(): sopas_request = \"" << sopas_ascii_request << "\", sopas_response = \"" << sopas_response << "\"\n");
267  return true;
268  }
269  else
270  {
271  ROS_WARN_STREAM("## WARNING in convertSendSOPASCommand(\"" << sopas_ascii_request << "\"): SickScanServices::sendSopasAndCheckAnswer() failed.\n");
272  }
273  }
274 #endif
275  ROS_WARN_STREAM("## WARNING in convertSendSOPASCommand(\"" << sopas_ascii_request << "\") failed: scanner not initialized\n");
276  }
277  return false;
278 }
279 
280 // fprintf-like conversion of va_args to string, thanks to https://codereview.stackexchange.com/questions/115760/use-va-list-to-format-a-string
281 std::string vargs_to_string(const char *const format, ...)
282 {
283  std::size_t length = std::max<size_t>((size_t)1024, 2 * strlen(format));
284  std::vector<char> temp;
285  std::va_list args;
286  for (int cnt = 0; temp.size() <= length && cnt < 10; cnt++)
287  {
288  temp.resize(length + 1);
289  va_start(args, format);
290 #ifdef WIN32
291  std::size_t required_length = _vsnprintf_s(temp.data(), temp.size(), _TRUNCATE, format, args);
292 #else
293  std::size_t required_length = std::vsnprintf(temp.data(), temp.size(), format, args);
294 #endif
295  va_end(args);
296  length = std::max<size_t>(length, required_length);
297  }
298  return std::string {temp.data(), length};
299 }
300 
301 // Set the global diagnostic status and message (OK, WARN, ERROR, INIT or EXIT)
302 void setDiagnosticStatus(SICK_DIAGNOSTIC_STATUS status_code, const std::string& status_message)
303 {
304  static bool status_first_time = true;
305  bool notify_status_update = (status_first_time || s_status_code != status_code || s_status_code == SICK_DIAGNOSTIC_STATUS_WARN || s_status_code == SICK_DIAGNOSTIC_STATUS_ERROR);
306  s_status_code = status_code;
307  s_status_message = status_message;
308  if (notify_status_update) // status changed, notify registered listener
310  status_first_time = false;
311 }
312 
313 // Returns the global diagnostic status and message (OK, WARN, ERROR, INIT or EXIT)
314 void getDiagnosticStatus(SICK_DIAGNOSTIC_STATUS& status_code, std::string& status_message)
315 {
316  status_code = s_status_code;
317  status_message = s_status_message;
318 }
319 
320 // Set verbose level 0=DEBUG, 1=INFO, 2=WARN, 3=ERROR, 4=FATAL or 5=QUIET (equivalent to ros::console::levels),
321 // i.e. print messages on console above the given verbose level.
322 // Default verbose level is 1 (INFO), i.e. print informational, warnings and error messages.
324 {
326 }
327 
328 // Returns the current verbose level 0=DEBUG, 1=INFO, 2=WARN, 3=ERROR, 4=FATAL or 5=QUIET. Default verbose level is 1 (INFO)
330 {
331  return s_verbose_level;
332 }
333 
334 inline bool ends_with(std::string const &value, std::string const &ending)
335 {
336  if (ending.size() > value.size())
337  { return false; }
338  return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
339 }
340 
352 bool parseLaunchfileSetParameter(rosNodePtr nhPriv, int argc, char **argv)
353 {
354  std::string tag;
355  std::string val;
356  int launchArgcFileIdx = -1;
357  for (int n = 1; n < argc; n++)
358  {
359  std::string extKey = ".launch";
360  std::string argv_str = argv[n];
361  if (ends_with(argv_str, extKey))
362  {
363  launchArgcFileIdx = n;
364  std::vector<std::string> tagList, typeList, valList;
365  LaunchParser launchParser;
366  bool ret = launchParser.parseFile(argv_str, tagList, typeList, valList);
367  if (ret == false)
368  {
369  ROS_INFO_STREAM("Cannot parse launch file (check existence and content): >>>" << argv_str << "<<<\n");
370  exit(-1);
371  }
372  for (size_t i = 0; i < tagList.size(); i++)
373  {
374  printf("%-30s %-10s %-20s\n", tagList[i].c_str(), typeList[i].c_str(), valList[i].c_str());
375  if(typeList[i] == "bool" && !valList[i].empty())
376  rosSetParam(nhPriv, tagList[i], (bool)(valList[i][0] == '1' || valList[i][0] == 't' || valList[i][0] == 'T'));
377  else if(typeList[i] == "int" && !valList[i].empty())
378  rosSetParam(nhPriv, tagList[i], (int)std::stoi(valList[i]));
379  else if(typeList[i] == "float" && !valList[i].empty())
380  rosSetParam(nhPriv, tagList[i], (float)std::stof(valList[i]));
381  else if(typeList[i] == "double" && !valList[i].empty())
382  rosSetParam(nhPriv, tagList[i], (double)std::stod(valList[i]));
383  else // parameter type "string"
384  rosSetParam(nhPriv, tagList[i], valList[i]);
385  }
386  }
387  }
388 
389  for (int n = 1; n < argc; n++)
390  {
391  std::string argv_str = argv[n];
392 
393  // Ignore all arguments after and including --ros-args
394  if (argv_str == "--ros-args") {
395  break;
396  }
397 
398  if (getTagVal(argv_str, tag, val))
399  {
400  rosSetParam(nhPriv, tag, val);
401  }
402  else
403  {
404  if (launchArgcFileIdx != n)
405  {
406  ROS_ERROR_STREAM("## ERROR parseLaunchfileSetParameter(): Tag-Value setting not valid. Use pattern: <tag>:=<value> (e.g. hostname:=192.168.0.4) (Check the entry: " << argv_str << ")\n");
407  return false;
408  }
409  }
410  }
411  return true;
412 }
413 
423 void mainGenericLaserInternal(int argc, char **argv, std::string nodeName, rosNodePtr nhPriv, bool do_ros_spin, int & exit_code)
424 {
425  std::string tag;
426  std::string val;
427 
428  exit_code = sick_scan_xd::ExitSuccess;
429  bool doInternalDebug = false;
430  bool emulSensor = false;
431  for (int i = 0; i < argc; i++)
432  {
433  std::string argv_str = argv[i];
434  if (getTagVal(argv_str, tag, val))
435  {
436  if (tag.compare("__internalDebug") == 0)
437  {
438  int debugState = 0;
439  sscanf(val.c_str(), "%d", &debugState);
440  if (debugState > 0)
441  {
442  doInternalDebug = true;
443  }
444  }
445  if (tag.compare("__emulSensor") == 0)
446  {
447  int dummyState = 0;
448  sscanf(val.c_str(), "%d", &dummyState);
449  if (dummyState > 0)
450  {
451  emulSensor = true;
452  }
453  }
454  }
455  }
456 
457 #ifdef USE_LAUNCHPARSER
458  if(!parseLaunchfileSetParameter(nhPriv, argc, argv))
459  {
460  ROS_ERROR_STREAM("## ERROR sick_generic_laser: parseLaunchfileSetParameter() failed, aborting\n");
461  exit_code = sick_scan_xd::ExitError;
462  exit(-1);
463  }
464 #endif
465 
466  std::string scannerName;
467  rosDeclareParam(nhPriv, "scanner_type", scannerName);
468  rosGetParam(nhPriv, "scanner_type", scannerName);
469  if (false == rosGetParam(nhPriv, "scanner_type", scannerName) || scannerName.empty())
470  {
471  ROS_ERROR_STREAM("cannot find parameter ""scanner_type"" in the param set. Please specify scanner_type.");
472  ROS_ERROR_STREAM("Try to set " << nodeName << " as fallback.\n");
473  scannerName = nodeName;
474  }
475 
476  std::string cloud_topic = "cloud";
477  rosDeclareParam(nhPriv, "hostname", "192.168.0.4");
478  rosDeclareParam(nhPriv, "imu_enable", false);
479  rosDeclareParam(nhPriv, "imu_topic", "imu");
480  rosDeclareParam(nhPriv, "cloud_topic", cloud_topic);
481  if (doInternalDebug)
482  {
483 #ifdef ROSSIMU
484  nhPriv->setParam("name", scannerName);
485  rossimu_settings(*nhPriv); // just for tiny simulations under Visual C++
486 #else
487  rosSetParam(nhPriv, "hostname", "192.168.0.4");
488  rosSetParam(nhPriv, "imu_enable", false);
489  rosSetParam(nhPriv, "imu_topic", "imu");
490  rosSetParam(nhPriv, "cloud_topic", "cloud");
491 #endif
492  }
493  rosGetParam(nhPriv, "cloud_topic", cloud_topic);
494 
495 
496 // check for TCP - use if ~hostname is set.
497  bool useTCP = false;
498  std::string hostname;
499  if (rosGetParam(nhPriv, "hostname", hostname))
500  {
501  useTCP = true;
502  }
503  bool changeIP = false;
504  std::string sNewIp;
505  rosDeclareParam(nhPriv, "new_IP_address", sNewIp);
506  if (rosGetParam(nhPriv, "new_IP_address", sNewIp) && !sNewIp.empty())
507  {
508  changeIP = true;
509  }
510  std::string port = "2112";
511  rosDeclareParam(nhPriv, "port", port);
512  rosGetParam(nhPriv, "port", port);
513 
514  int timelimit = 5;
515  rosDeclareParam(nhPriv, "timelimit", timelimit);
516  rosGetParam(nhPriv, "timelimit", timelimit);
517 
518  bool subscribe_datagram = false;
519  rosDeclareParam(nhPriv, "subscribe_datagram", subscribe_datagram);
520  rosGetParam(nhPriv, "subscribe_datagram", subscribe_datagram);
521 
522  int device_number = 0;
523  rosDeclareParam(nhPriv, "device_number", device_number);
524  rosGetParam(nhPriv, "device_number", device_number);
525 
526  std::string frame_id = "cloud";
527  rosDeclareParam(nhPriv, "frame_id", frame_id);
528  rosGetParam(nhPriv, "frame_id", frame_id);
529 
530  setDiagnosticStatus(SICK_DIAGNOSTIC_STATUS::INIT, "sick_scan_xd initializing " + hostname + ":" + port);
531  if(scannerName == "sick_ldmrs")
532  {
533 #if defined LDMRS_SUPPORT && LDMRS_SUPPORT > 0
534  ROS_INFO("Initializing LDMRS...");
535  sick_scan_xd::SickLdmrsNode ldmrs;
536  exit_code = ldmrs.init(nhPriv, hostname, frame_id);
537  if(exit_code != sick_scan_xd::ExitSuccess)
538  {
539  ROS_ERROR("LDMRS initialization failed.");
540  exit_code = sick_scan_xd::ExitError;
541  return;
542  }
543  ROS_INFO("LDMRS initialized.");
545  // Run event loop
546  // rosSpin(nhPriv);
547  while(rosOk()) // return after signal, while rosSpin runs in sick_generic_caller
548  {
549  std::this_thread::sleep_for(std::chrono::seconds(1));
550  }
551  exit_code = sick_scan_xd::ExitSuccess;
552  return;
553 #else
554  ROS_ERROR("LDMRS not supported. Please build sick_scan_xd with option LDMRS_SUPPORT");
555  exit_code = sick_scan_xd::ExitError;
556  return;
557 #endif
558  }
559 
560  // Optional timestamp mode:
561  // TICKS_TO_SYSTEM_TIMESTAMP = 0, // default: convert lidar ticks in microseconds to system timestamp by software-pll
562  // TICKS_TO_MICROSEC_OFFSET_TIMESTAMP = 1 // optional tick-mode: convert lidar ticks in microseconds to timestamp by 1.0e-6*(curtick-firstTick)+firstSystemTimestamp;
563  // TICKS_TO_LIDAR_TIMESTAMP = 2 // optional tick-mode: convert lidar ticks in microseconds to lidar timestamp by sec = tick/1000000, nsec = 1000 * (tick % 1000000)
564  int tick_to_timestamp_mode = 0;
565  rosDeclareParam(nhPriv, "tick_to_timestamp_mode", tick_to_timestamp_mode);
566  rosGetParam(nhPriv, "tick_to_timestamp_mode", tick_to_timestamp_mode);
567  SoftwarePLL::instance().setTicksToTimestampMode(tick_to_timestamp_mode);
568 
569  // Start TF publisher
570  sick_scan_xd::SickTransformPublisher tf_publisher(nhPriv);
571  tf_publisher.run();
572 
573  if(scannerName == SICK_SCANNER_SCANSEGMENT_XD_NAME || scannerName == SICK_SCANNER_PICOSCAN_NAME)
574  {
575 #if defined SCANSEGMENT_XD_SUPPORT && SCANSEGMENT_XD_SUPPORT > 0
576  exit_code = sick_scansegment_xd::run(nhPriv, scannerName);
577  std::cout << "sick_generic_laser: sick_scansegment_xd finished with " << (exit_code == sick_scan_xd::ExitSuccess ? "success" : "ERROR") << std::endl;
578  tf_publisher.stop();
579  return;
580 #else
581  ROS_ERROR_STREAM("SCANSEGMENT_XD_SUPPORT deactivated, " << scannerName << " not supported. Please build sick_scan_xd with option SCANSEGMENT_XD_SUPPORT");
582  exit_code = sick_scan_xd::ExitError;
583  tf_publisher.stop();
584  return;
585 #endif
586  }
587 
589 
590  char colaDialectId = 'A'; // A or B (Ascii or Binary)
591 
592  float range_min = parser->get_range_min();
593  rosDeclareParam(nhPriv, "range_min", range_min);
594  if (rosGetParam(nhPriv, "range_min", range_min))
595  {
596  parser->set_range_min(range_min);
597  }
598  float range_max = parser->get_range_max();
599  rosDeclareParam(nhPriv, "range_max", range_max);
600  if (rosGetParam(nhPriv, "range_max", range_max))
601  {
602  parser->set_range_max(range_max);
603  }
604  int range_filter_handling = parser->get_range_filter_config();
605  rosDeclareParam(nhPriv, "range_filter_handling", range_filter_handling);
606  if (rosGetParam(nhPriv, "range_filter_handling", range_filter_handling))
607  {
608  parser->set_range_filter_config((sick_scan_xd::RangeFilterResultHandling)range_filter_handling);
609  }
610  ROS_INFO_STREAM("Range filter configuration: range_min=" << range_min << ", range_max=" << range_max << ", range_filter_handling=" << range_filter_handling);
611 
612  float time_increment = parser->get_time_increment();
613  rosDeclareParam(nhPriv, "time_increment", time_increment);
614  if (rosGetParam(nhPriv, "time_increment", time_increment))
615  {
616  parser->set_time_increment(time_increment);
617  }
618 
619  /*
620  * Check, if parameter for protocol type is set
621  */
622  bool use_binary_protocol = true;
623  rosDeclareParam(nhPriv, "emul_sensor", emulSensor);
624  if (true == rosGetParam(nhPriv, "emul_sensor", emulSensor))
625  {
626  ROS_INFO_STREAM("Found emul_sensor overwriting default settings. Emulation:" << (emulSensor ? "True" : "False"));
627  }
628  rosDeclareParam(nhPriv, "use_binary_protocol", use_binary_protocol);
629  if (true == rosGetParam(nhPriv, "use_binary_protocol", use_binary_protocol))
630  {
631  ROS_INFO("Found sopas_protocol_type param overwriting default protocol:");
632  if (use_binary_protocol == true)
633  {
634  ROS_INFO("Binary protocol activated");
635  }
636  else
637  {
638  if (parser->getCurrentParamPtr()->getNumberOfLayers() > 4)
639  {
640  rosSetParam(nhPriv, "sopas_protocol_type", true);
641  use_binary_protocol = true;
642  ROS_WARN("This scanner type does not support ASCII communication.\n"
643  "Binary communication has been activated.\n"
644  "The parameter \"sopas_protocol_type\" has been set to \"True\".");
645  }
646  else
647  {
648  ROS_INFO("ASCII protocol activated");
649  }
650  }
651  parser->getCurrentParamPtr()->setUseBinaryProtocol(use_binary_protocol);
652  }
653 
654 
655  if (parser->getCurrentParamPtr()->getUseBinaryProtocol())
656  {
657  colaDialectId = 'B';
658  }
659  else
660  {
661  colaDialectId = 'A';
662  }
663 
664  sick_scan_xd::SickScanMonitor* scan_msg_monitor = 0;
665  sick_scan_xd::PointCloudMonitor* pointcloud_monitor = 0;
666  bool message_monitoring_enabled = true;
667  int read_timeout_millisec_default = READ_TIMEOUT_MILLISEC_DEFAULT;
668  int read_timeout_millisec_startup = READ_TIMEOUT_MILLISEC_STARTUP;
669  int read_timeout_millisec_kill_node = READ_TIMEOUT_MILLISEC_KILL_NODE;
670  rosDeclareParam(nhPriv, "message_monitoring_enabled", message_monitoring_enabled);
671  rosGetParam(nhPriv, "message_monitoring_enabled", message_monitoring_enabled);
672  rosDeclareParam(nhPriv, "read_timeout_millisec_default", read_timeout_millisec_default);
673  rosGetParam(nhPriv, "read_timeout_millisec_default", read_timeout_millisec_default);
674  rosDeclareParam(nhPriv, "read_timeout_millisec_startup", read_timeout_millisec_startup);
675  rosGetParam(nhPriv, "read_timeout_millisec_startup", read_timeout_millisec_startup);
676  rosDeclareParam(nhPriv, "read_timeout_millisec_kill_node", read_timeout_millisec_kill_node);
677  rosGetParam(nhPriv, "read_timeout_millisec_kill_node", read_timeout_millisec_kill_node);
678  int message_monitoring_read_timeout_millisec = read_timeout_millisec_default;
679  if(message_monitoring_enabled)
680  {
681  scan_msg_monitor = new sick_scan_xd::SickScanMonitor(message_monitoring_read_timeout_millisec);
682 #if __ROS_VERSION > 0 // point cloud monitoring in Linux-ROS
683  if (read_timeout_millisec_kill_node > 0)
684  {
685  pointcloud_monitor = new sick_scan_xd::PointCloudMonitor();
686  bool pointcloud_monitor_started = pointcloud_monitor->startPointCloudMonitoring(nhPriv, read_timeout_millisec_kill_node, cloud_topic);
687  ROS_INFO_STREAM("PointCloudMonitor" << (pointcloud_monitor_started?" ":" NOT ") << "started.");
688  }
689  else
690  {
691  ROS_INFO_STREAM("PointCloudMonitor deactivated due to configuration read_timeout_millisec_kill_node=" << read_timeout_millisec_kill_node <<", pointcloud will not be monitored for timeout errors.");
692  }
693 #endif
694  }
695 
696  bool start_services = true;
697  sick_scan_xd::SickScanServices* services = 0;
698  exit_code = sick_scan_xd::ExitError;
699 
700  //sick_scan_xd::SickScanConfig cfg;
701  //std::chrono::system_clock::time_point timestamp_rosOk = std::chrono::system_clock::now();
702 
703  while (rosOk() && s_runState != scanner_finalize)
704  {
705  //if (rosOk())
706  // timestamp_rosOk = std::chrono::system_clock::now();
707  //else if (std::chrono::duration<double>(std::chrono::system_clock::now() - timestamp_rosOk).count() > 2 * 1000) // 2 seconds timeout to stop the scanner
708  // s_runState = scanner_finalize;
709 
710  switch (s_runState)
711  {
712  case scanner_init:
713  setDiagnosticStatus(SICK_DIAGNOSTIC_STATUS::INIT, "sick_scan_xd initializing " + hostname + ":" + port);
714  ROS_INFO_STREAM("Start initialising scanner [Ip: " << hostname << "] [Port:" << port << "]");
715  // attempt to connect/reconnect
716  DELETE_PTR(s_scanner); // disconnect scanner
717  if (useTCP)
718  {
719  s_scanner = new sick_scan_xd::SickScanCommonTcp(hostname, port, timelimit, nhPriv, parser, colaDialectId);
720  }
721  else
722  {
723  ROS_ERROR("TCP is not switched on. Probably hostname or port not set. Use roslaunch to start node.");
724  exit(-1);
725  }
726 
727  if (emulSensor)
728  {
729  s_scanner->setEmulSensor(true);
730  }
731  exit_code = s_scanner->init(nhPriv);
732  if (exit_code == sick_scan_xd::ExitError || exit_code == sick_scan_xd::ExitFatal)
733  {
734  ROS_ERROR("## ERROR in mainGenericLaser: init failed, retrying..."); // ROS_ERROR("init failed, shutting down");
735  continue;
736  }
737 
738  // Start ROS services
739  rosDeclareParam(nhPriv, "start_services", start_services);
740  rosGetParam(nhPriv, "start_services", start_services);
741  if (true == start_services)
742  {
743  services = new sick_scan_xd::SickScanServices(nhPriv, s_scanner, parser->getCurrentParamPtr());
744  ROS_INFO("SickScanServices: ros services initialized");
745  }
746 
747  s_isInitialized = true;
748  // signal(SIGINT, SIG_DFL); // change back to standard signal handler after initialising
749 
750  if (exit_code == sick_scan_xd::ExitSuccess) // OK -> loop again
751  {
752  if (changeIP)
753  {
756  }
757  else
758  {
759  s_runState = scanner_run; // after initialising switch to run state
761 #if __ROS_VERSION > 0
762  ROS_INFO_STREAM("Setup completed, sick_scan_xd is up and running. Pointcloud is published on topic \"" << cloud_topic << "\"");
763 #else
764  ROS_INFO("Setup completed, sick_scan_xd is up and running.");
765 #endif
766  }
767  }
768  else
769  {
770  s_runState = scanner_init; // If there was an error, try to restart scanner
771  setDiagnosticStatus(SICK_DIAGNOSTIC_STATUS::INIT, "sick_scan_xd initializing " + hostname + ":" + port);
772  }
773  break;
774 
775  case scanner_run:
776  if (exit_code == sick_scan_xd::ExitSuccess) // OK -> loop again
777  {
778  if(do_ros_spin)
779  {
780  rosSpinOnce(nhPriv);
781  }
782  exit_code = s_scanner->loopOnce(nhPriv);
783 
784  if(scan_msg_monitor && message_monitoring_enabled) // Monitor scanner messages
785  {
786  exit_code = scan_msg_monitor->checkStateReinitOnError(nhPriv, s_runState, s_scanner, parser, services);
787  if(exit_code == sick_scan_xd::ExitSuccess) // monitoring reports normal operation
788  {
790  }
791  else // scanner re-init failed after read timeout or tcp error
792  {
794  ROS_ERROR("## ERROR in sick_generic_laser main loop: read timeout, scanner re-init failed");
795  }
796  }
797  }
798  else
799  {
800  s_runState = scanner_finalize; // interrupt
801  }
802  break;
803 
804  case scanner_finalize:
806  break; // ExitError or similiar -> interrupt while-Loop
807 
808  default:
809  ROS_ERROR("Invalid run state in main loop");
810  break;
811  }
812  }
813  printf("sick_generic_laser: leaving main loop...");
815 
816  tf_publisher.stop();
817  if(pointcloud_monitor)
818  pointcloud_monitor->stopPointCloudMonitoring();
819  DELETE_PTR(scan_msg_monitor);
820  DELETE_PTR(pointcloud_monitor);
821  DELETE_PTR(services);
822  DELETE_PTR(s_scanner); // close connnect
823  DELETE_PTR(parser); // close parser
824  return;
825 }
826 
837 bool startGenericLaser(int argc, char **argv, std::string nodeName, rosNodePtr nhPriv, int* exit_code)
838 {
839  if (s_generic_laser_thread == 0)
840  {
841  s_isInitialized = false;
842  s_scanner = NULL;
843  s_shutdownSignalReceived = false;
845  s_status_message = "";
847  s_generic_laser_thread = new GenericLaserCallable(argc, argv, nodeName, nhPriv, exit_code);
848  }
849  return (s_generic_laser_thread != 0);
850 }
851 
856 {
857  if (s_generic_laser_thread != 0)
858  {
860  delete s_generic_laser_thread;
862  }
863 }
864 
873 int mainGenericLaser(int argc, char **argv, std::string nodeName, rosNodePtr nhPriv)
874 {
875  int result;
876  mainGenericLaserInternal(argc, argv, nodeName, nhPriv, true, result);
877  return result;
878 }
879 
880 // Send odometry data to NAV350
881 #include "sick_scan_api.h"
883 int32_t SickScanApiNavOdomVelocityImpl(SickScanApiHandle apiHandle, SickScanNavOdomVelocityMsg* src_msg) // odometry data in nav coordinates
884 {
885  if(s_scanner)
886  {
888  nav_msg.vel_x = src_msg->vel_x;
889  nav_msg.vel_y = src_msg->vel_y;
890  nav_msg.omega = src_msg->omega;
891  nav_msg.timestamp = src_msg->timestamp;
892  nav_msg.coordbase = src_msg->coordbase;
894  return SICK_SCAN_API_SUCCESS;
895  }
896  return SICK_SCAN_API_ERROR;
897 }
898 int32_t SickScanApiOdomVelocityImpl(SickScanApiHandle apiHandle, SickScanOdomVelocityMsg* src_msg) // odometry data in system coordinates
899 {
901  {
903  nav_msg.vel_x = src_msg->vel_x;
904  nav_msg.vel_y = src_msg->vel_y;
905  double angle_shift = -1.0 * s_scanner->getCurrentParamPtr()->getScanAngleShift();
906  sick_scan_xd::rotateXYbyAngleOffset(nav_msg.vel_x, nav_msg.vel_y, angle_shift); // Convert to velocity in lidar coordinates in m/s
907  nav_msg.omega = src_msg->omega; // angular velocity in radians/s
908  nav_msg.coordbase = 0; // 0 = local coordinate system of the NAV350
909  SoftwarePLL::instance().convSystemtimeToLidarTimestamp(src_msg->timestamp_sec, src_msg->timestamp_nsec, nav_msg.timestamp);
911  return SICK_SCAN_API_SUCCESS;
912  }
913  else
914  {
915  ROS_WARN_STREAM("## ERROR SickScanCommon::messageCbRosOdom(): SoftwarePLL not yet ready, timestamp can not be converted from system time to lidar time, odometry message ignored.");
916  }
917  return SICK_SCAN_API_ERROR;
918 }
s_shutdownSignalReceived
static bool s_shutdownSignalReceived
Definition: sick_generic_laser.cpp:114
sick_scan_xd::PointCloudMonitor::stopPointCloudMonitoring
void stopPointCloudMonitoring(void)
Definition: sick_generic_monitoring.cpp:186
s_verbose_level
int32_t s_verbose_level
Definition: sick_generic_laser.cpp:160
sick_scan_xd::SickScanServices::sendSopasAndCheckAnswer
bool sendSopasAndCheckAnswer(const std::string &sopasCmd, std::vector< unsigned char > &sopasReplyBin, std::string &sopasReplyString)
Definition: sick_scan_services.cpp:207
ros::NodeHandle::setParam
void setParam(const std::string &key, bool b) const
SickScanOdomVelocityMsgType
Definition: sick_scan_api.h:431
sick_scan_xd::PointCloudMonitor
Definition: sick_generic_monitoring.h:110
SICK_SCAN_API_SUCCESS
@ SICK_SCAN_API_SUCCESS
Definition: sick_scan_api.h:609
vargs_to_string
std::string vargs_to_string(const char *const format,...)
Definition: sick_generic_laser.cpp:281
GenericLaserCallable::nhPriv
rosNodePtr nhPriv
Definition: sick_generic_laser.cpp:150
NULL
#define NULL
sick_generic_laser.h
ends_with
bool ends_with(std::string const &value, std::string const &ending)
Definition: sick_generic_laser.cpp:334
rosSetParam
void rosSetParam(rosNodePtr nh, const std::string &param_name, const T &param_value)
Definition: sick_ros_wrapper.h:168
GITINFO_STR
#define GITINFO_STR
Definition: sick_generic_laser.cpp:105
sick_scan_xd_version.h
sick_scan_xd_api_test.sopas_response
sopas_response
Definition: sick_scan_xd_api_test.py:453
SickScanOdomVelocityMsgType::timestamp_sec
uint32_t timestamp_sec
Definition: sick_scan_api.h:436
SickScanNavOdomVelocityMsgType::timestamp
uint32_t timestamp
Definition: sick_scan_api.h:427
sick_scan_xd::SickScanServices
Definition: sick_scan_services.h:76
SICK_SCAN_XD_VERSION
#define SICK_SCAN_XD_VERSION
Definition: sick_scan_xd_version.h:3
getDiagnosticStatus
void getDiagnosticStatus(SICK_DIAGNOSTIC_STATUS &status_code, std::string &status_message)
Definition: sick_generic_laser.cpp:314
sick_generic_monitoring.h
GenericLaserCallable::nodeName
std::string nodeName
Definition: sick_generic_laser.cpp:149
scanner_run
@ scanner_run
Definition: sick_generic_laser.h:14
imu_delay_tester.args
args
Definition: imu_delay_tester.py:124
convertSendSOPASCommand
bool convertSendSOPASCommand(const std::string &sopas_ascii_request, std::string &sopas_response, bool wait_for_reply)
Converts a given SOPAS command from ascii to binary (in case of binary communication),...
Definition: sick_generic_laser.cpp:233
SoftwarePLL::instance
static SoftwarePLL & instance()
Definition: softwarePLL.h:24
mainGenericLaserInternal
void mainGenericLaserInternal(int argc, char **argv, std::string nodeName, rosNodePtr nhPriv, bool do_ros_spin, int &exit_code)
Internal Startup routine.
Definition: sick_generic_laser.cpp:423
sick_scan_xd::SickScanCommon::loopOnce
int loopOnce(rosNodePtr nh)
parsing datagram and publishing ros messages
Definition: sick_scan_common.cpp:4360
sick_nav_scandata_parser.h
notifyDiagnosticListener
void notifyDiagnosticListener(SICK_DIAGNOSTIC_STATUS status_code, const std::string &status_message)
Definition: api_impl.cpp:1492
sick_scan_xd::SickGenericParser
Definition: sick_generic_parser.h:239
sick_scan_xd::SickScanCommon::convertSendSOPASCommand
virtual int convertSendSOPASCommand(const std::string &sopas_ascii_request, std::vector< unsigned char > *reply, bool wait_for_reply=true)
Converts a given SOPAS command from ascii to binary (in case of binary communication),...
Definition: sick_scan_common.cpp:830
ROS_WARN
#define ROS_WARN(...)
Definition: sick_scan_logging.h:122
sick_scan_xd::ExitFatal
@ ExitFatal
Definition: abstract_parser.h:48
SoftwarePLL::setTicksToTimestampMode
void setTicksToTimestampMode(int val)
Definition: softwarePLL.h:106
SoftwarePLL::convSystemtimeToLidarTimestamp
bool convSystemtimeToLidarTimestamp(uint32_t systemtime_sec, uint32_t systemtime_nanosec, uint32_t &tick)
Definition: softwarePLL.cpp:264
SickScanOdomVelocityMsgType::vel_x
float vel_x
Definition: sick_scan_api.h:433
sick_scan_xd::SickScanCommonTcp::setEmulSensor
void setEmulSensor(bool _emulFlag)
Set emulation flag (using emulation instead of "real" scanner - currently implemented for radar.
Definition: sick_scan_common_tcp.cpp:301
INIT
@ INIT
Definition: sick_scan_logging.h:76
GenericLaserCallable::exit_code
int * exit_code
Definition: sick_generic_laser.cpp:151
joinGenericLaser
void joinGenericLaser(void)
Waits until all GenericLaser jobs finished.
Definition: sick_generic_laser.cpp:855
scansegment_threads.h
launchparser.h
sick_ros_wrapper.h
DELETE_PTR
#define DELETE_PTR(p)
Definition: sick_generic_laser.cpp:108
sick_scan_api.h
sick_scansegment_xd::sopasService
sick_scan_xd::SickScanServices * sopasService()
Definition: scansegment_threads.cpp:69
s_isInitialized
static bool s_isInitialized
Definition: sick_generic_laser.cpp:110
SICK_SCAN_API_ERROR
@ SICK_SCAN_API_ERROR
Definition: sick_scan_api.h:610
sick_scan_xd::SickScanMonitor::checkStateReinitOnError
sick_scan_xd::ExitCode checkStateReinitOnError(rosNodePtr nh, NodeRunState runState, SickScanCommonTcp *scanner, sick_scan_xd::SickGenericParser *parser, sick_scan_xd::SickScanServices *services)
Definition: sick_generic_monitoring.cpp:121
READ_TIMEOUT_MILLISEC_DEFAULT
#define READ_TIMEOUT_MILLISEC_DEFAULT
Definition: sick_scan_common.h:94
ROS_WARN_STREAM
#define ROS_WARN_STREAM(args)
Definition: sick_scan_logging.h:123
sick_scan_xd::ScannerBasicParam::getScanAngleShift
double getScanAngleShift()
Definition: sick_generic_parser.cpp:505
ROS_INFO_STREAM
#define ROS_INFO_STREAM(...)
Definition: sick_scan_ros2_example.cpp:71
SickScanApiOdomVelocityImpl
int32_t SickScanApiOdomVelocityImpl(SickScanApiHandle apiHandle, SickScanOdomVelocityMsg *src_msg)
Definition: sick_generic_laser.cpp:898
sick_scan_xd::SickTransformPublisher
Definition: sick_tf_publisher.h:87
softwarePLL.h
setDiagnosticStatus
void setDiagnosticStatus(SICK_DIAGNOSTIC_STATUS status_code, const std::string &status_message)
Definition: sick_generic_laser.cpp:302
versionInfo
static std::string versionInfo
Definition: sick_generic_laser.cpp:113
sick_scan_xd::SickScanCommon::getCurrentParamPtr
ScannerBasicParam * getCurrentParamPtr()
Definition: sick_scan_common.h:348
sick_generic_parser.h
sick_scan_xd::SickScanCommon::init
virtual int init(rosNodePtr nh)
init routine of scanner
Definition: sick_scan_common.cpp:1513
sick_scan_common_tcp.h
s_status_code
SICK_DIAGNOSTIC_STATUS s_status_code
Definition: sick_generic_laser.cpp:158
NodeRunState
NodeRunState
Definition: sick_generic_laser.h:12
imu_delay_tester.parser
parser
Definition: imu_delay_tester.py:116
rossimu_settings
int rossimu_settings(ros::NodeHandle &nhPriv)
Definition: rossimu.cpp:443
SickScanApiHandle
void * SickScanApiHandle
Definition: sick_scan_api.h:456
sick_scan_xd::rotateXYbyAngleOffset
void rotateXYbyAngleOffset(float &x, float &y, double angle_offset)
Definition: sick_nav_scandata_parser.cpp:764
OK
@ OK
Definition: sick_scan_logging.h:73
range_max
float range_max
Definition: sick_scan_test.cpp:529
SICK_DIAGNOSTIC_STATUS_ERROR
#define SICK_DIAGNOSTIC_STATUS_ERROR
Definition: sick_scan_logging.h:81
s_generic_laser_thread
static GenericLaserCallable * s_generic_laser_thread
Definition: sick_generic_laser.cpp:155
sick_scan_xd::ExitSuccess
@ ExitSuccess
Definition: abstract_parser.h:46
getVersionInfo
std::string getVersionInfo()
Definition: sick_generic_laser.cpp:121
sick_tf_publisher.h
scanner_init
@ scanner_init
Definition: sick_generic_laser.h:14
GenericLaserCallable::argc
int argc
Definition: sick_generic_laser.cpp:147
GenericLaserCallable
Definition: sick_generic_laser.cpp:128
sick_scan_xd::SickScanMonitor
Definition: sick_generic_monitoring.h:76
ros::NodeHandle
GITHASH_STR
#define GITHASH_STR
Definition: sick_generic_laser.cpp:100
rosGetParam
bool rosGetParam(rosNodePtr nh, const std::string &param_name, T &param_value)
Definition: sick_ros_wrapper.h:167
ROS_INFO
#define ROS_INFO(...)
Definition: sick_scan_logging.h:117
sick_scan_xd_api_test.verbose_level
verbose_level
Definition: sick_scan_xd_api_test.py:346
SickScanOdomVelocityMsgType::vel_y
float vel_y
Definition: sick_scan_api.h:434
SickScanNavOdomVelocityMsgType::vel_x
float vel_x
Definition: sick_scan_api.h:424
scanner_finalize
@ scanner_finalize
Definition: sick_generic_laser.h:14
rosSpinOnce
void rosSpinOnce(rosNodePtr nh)
Definition: sick_ros_wrapper.h:208
rosShutdown
void rosShutdown(void)
Definition: sick_ros_wrapper.h:209
sick_scan_xd::SickTransformPublisher::stop
void stop()
Definition: sick_tf_publisher.cpp:139
LaunchParser::parseFile
bool parseFile(std::string launchFileFullName, std::vector< std::string > &nameVec, std::vector< std::string > &typeVec, std::vector< std::string > &valVec)
Definition: launchparser.cpp:209
sick_scan_xd::SickScanCommonTcp::stopScanData
bool stopScanData(bool force_immediate_shutdown=false)
Definition: sick_scan_common_tcp.cpp:630
SICK_DIAGNOSTIC_STATUS_WARN
#define SICK_DIAGNOSTIC_STATUS_WARN
Definition: sick_scan_logging.h:80
getVerboseLevel
int32_t getVerboseLevel()
Definition: sick_generic_laser.cpp:329
sick_ldmrs_node.h
SickScanOdomVelocityMsgType::timestamp_nsec
uint32_t timestamp_nsec
Definition: sick_scan_api.h:437
GenericLaserCallable::join
void join(void)
Definition: sick_generic_laser.cpp:140
sick_scan_xd::SickTransformPublisher::run
void run()
Definition: sick_tf_publisher.cpp:128
sick_scan_xd::SickScanCommon::sopasReplyToString
std::string sopasReplyToString(const std::vector< unsigned char > &reply)
Converts reply from sendSOPASCommand to string.
Definition: sick_scan_common.h:360
sick_scan_xd::SickScanCommon::messageCbNavOdomVelocity
void messageCbNavOdomVelocity(const sick_scan_msg::NAVOdomVelocity &msg)
Definition: sick_scan_common.cpp:1422
SickScanOdomVelocityMsgType::omega
float omega
Definition: sick_scan_api.h:435
range_min
float range_min
Definition: sick_scan_test.cpp:528
GenericLaserCallable::generic_laser_thread
std::thread * generic_laser_thread
Definition: sick_generic_laser.cpp:152
READ_TIMEOUT_MILLISEC_STARTUP
#define READ_TIMEOUT_MILLISEC_STARTUP
Definition: sick_scan_common.h:93
SickScanNavOdomVelocityMsgType::vel_y
float vel_y
Definition: sick_scan_api.h:425
mainGenericLaser
int mainGenericLaser(int argc, char **argv, std::string nodeName, rosNodePtr nhPriv)
Internal Startup routine.
Definition: sick_generic_laser.cpp:873
startGenericLaser
bool startGenericLaser(int argc, char **argv, std::string nodeName, rosNodePtr nhPriv, int *exit_code)
Runs mainGenericLaser non-blocking in a new thread.
Definition: sick_generic_laser.cpp:837
sick_scan_services.h
ROS_ERROR
#define ROS_ERROR(...)
Definition: sick_scan_logging.h:127
SickScanNavOdomVelocityMsgType
Definition: sick_scan_api.h:422
GenericLaserCallable::argv
char ** argv
Definition: sick_generic_laser.cpp:148
length
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
sick_scan_xd::SickScanCommonTcp
Definition: sick_scan_common_tcp.h:91
SickScanApiNavOdomVelocityImpl
int32_t SickScanApiNavOdomVelocityImpl(SickScanApiHandle apiHandle, SickScanNavOdomVelocityMsg *src_msg)
Definition: sick_generic_laser.cpp:883
SoftwarePLL::IsInitialized
bool IsInitialized() const
Definition: softwarePLL.h:47
s_runState
static NodeRunState s_runState
Definition: sick_generic_laser.cpp:157
GenericLaserCallable::GenericLaserCallable
GenericLaserCallable(int _argc, char **_argv, std::string _nodeName, rosNodePtr _nhPriv, int *_exit_code)
Definition: sick_generic_laser.cpp:131
ROS::seconds
double seconds(ROS::Duration duration)
Definition: ros_wrapper.cpp:180
getTagVal
bool getTagVal(std::string tagVal, std::string &tag, std::string &val)
splitting expressions like <tag>:=into <tag> and
Definition: sick_generic_laser.cpp:170
sick_scan_xd::PointCloudMonitor::startPointCloudMonitoring
bool startPointCloudMonitoring(rosNodePtr nh, int timeout_millisec=READ_TIMEOUT_MILLISEC_KILL_NODE, const std::string &ros_cloud_topic="cloud")
Definition: sick_generic_monitoring.cpp:168
ROS_ERROR_STREAM
#define ROS_ERROR_STREAM(...)
Definition: sick_scan_ros2_example.cpp:72
s_scanner
static sick_scan_xd::SickScanCommonTcp * s_scanner
Definition: sick_generic_laser.cpp:111
stopScannerAndExit
bool stopScannerAndExit(bool force_immediate_shutdown)
Definition: sick_generic_laser.cpp:190
s_status_message
std::string s_status_message
Definition: sick_generic_laser.cpp:159
args
setVersionInfo
void setVersionInfo(std::string _versionInfo)
Definition: sick_generic_laser.cpp:116
LaunchParser
Definition: launchparser.h:12
sick_scan_xd::RangeFilterResultHandling
enum sick_scan_xd::RangeFilterResultHandlingEnum RangeFilterResultHandling
READ_TIMEOUT_MILLISEC_KILL_NODE
#define READ_TIMEOUT_MILLISEC_KILL_NODE
Definition: sick_scan_common.h:95
SickScanNavOdomVelocityMsgType::omega
float omega
Definition: sick_scan_api.h:426
rosOk
bool rosOk(void)
Definition: sick_ros_wrapper.h:206
SICK_SCANNER_SCANSEGMENT_XD_NAME
#define SICK_SCANNER_SCANSEGMENT_XD_NAME
Definition: sick_generic_parser.h:82
GenericLaserCallable::mainGenericLaserCb
void mainGenericLaserCb(void)
Definition: sick_generic_laser.cpp:136
SICK_DIAGNOSTIC_STATUS
SICK_DIAGNOSTIC_STATUS
Definition: sick_scan_logging.h:71
EXIT
@ EXIT
Definition: sick_scan_logging.h:77
parseLaunchfileSetParameter
bool parseLaunchfileSetParameter(rosNodePtr nhPriv, int argc, char **argv)
Parses an optional launchfile and sets all parameters. This function is used at startup to enable sys...
Definition: sick_generic_laser.cpp:352
rosDeclareParam
void rosDeclareParam(rosNodePtr nh, const std::string &param_name, const T &param_value)
Definition: sick_ros_wrapper.h:166
setVerboseLevel
void setVerboseLevel(int32_t verbose_level)
Definition: sick_generic_laser.cpp:323
sick_scan_xd::NAVOdomVelocity
::sick_scan_xd::NAVOdomVelocity_< std::allocator< void > > NAVOdomVelocity
Definition: NAVOdomVelocity.h:69
shutdownSignalReceived
bool shutdownSignalReceived()
Definition: sick_generic_laser.cpp:206
rosSignalHandler
void rosSignalHandler(int signalRecv)
Definition: sick_generic_laser.cpp:211
SickScanNavOdomVelocityMsgType::coordbase
uint8_t coordbase
Definition: sick_scan_api.h:428
sick_scan_xd::ExitError
@ ExitError
Definition: abstract_parser.h:47
sick_scansegment_xd::run
int run(rosNodePtr node, const std::string &scannerName)
Definition: scansegment_threads.cpp:74
SICK_SCANNER_PICOSCAN_NAME
#define SICK_SCANNER_PICOSCAN_NAME
Definition: sick_generic_parser.h:83


sick_scan_xd
Author(s): Michael Lehning , Jochen Sprickerhof , Martin Günther
autogenerated on Fri Oct 25 2024 02:47:10