urg_stamped.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018-2021 The urg_stamped Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <ros/console.h>
18 #include <ros/ros.h>
19 
20 #include <sensor_msgs/LaserScan.h>
21 #include <urg_stamped/Status.h>
22 #include <std_msgs/Header.h>
23 
24 #include <boost/bind/bind.hpp>
25 #include <boost/format.hpp>
26 #include <boost/thread.hpp>
27 
28 #include <algorithm>
29 #include <cstdint>
30 #include <list>
31 #include <map>
32 #include <random>
33 #include <string>
34 #include <utility>
35 #include <vector>
36 
37 #include <scip2/scip2.h>
38 #include <scip2/walltime.h>
39 #include <scip2/logger.h>
40 
41 #include <urg_stamped/ros_logger.h>
42 #include <urg_stamped/strings.h>
43 
45 
46 namespace urg_stamped
47 {
49  const boost::posix_time::ptime& time_read,
50  const std::string& echo_back,
51  const std::string& status,
52  const scip2::ScanData& scan,
53  const bool has_intensity)
54 {
55  if (status != "99")
56  {
57  if (status != "00")
58  {
59  scip2::logger::error() << echo_back << " errored with " << status << std::endl;
60  errorCountIncrement(status);
61  }
62  return;
63  }
64 
65  if (!est_)
66  {
68  << "Received scan data before timestamp estimator initialization"
69  << std::endl;
70  return;
71  }
72 
73  const uint64_t walltime_device = walltime_.update(scan.timestamp_);
74  const ros::Time time_read_ros = ros::Time::fromBoost(time_read);
75 
76  if (next_sync_.isValid() && time_read_ros > next_sync_)
77  {
80  }
81 
82  std::pair<ros::Time, bool> t_scan = est_->scan_->pushScanSample(time_read_ros, walltime_device);
83  sensor_msgs::LaserScan msg(msg_base_);
84  msg.header.stamp = t_scan.first;
85  if (is_uust2_)
86  {
87  msg.header.stamp += uust2_stamp_offset_;
88  }
89  if (!t_scan.second)
90  {
94  {
95  // Fallback to naive sensor timestamp
96  msg.header.stamp = est_->clock_->getClockState().stampToTime(walltime_device);
97  }
98  else
99  {
100  return;
101  }
102  }
103  else
104  {
106  }
107 
108  if (msg.header.stamp > time_read_ros)
109  {
111  << std::setprecision(6) << std::fixed
112  << "estimated future timestamp (read: " << time_read_ros.toSec()
113  << ", estimated: " << msg.header.stamp.toSec() << std::endl;
115  return;
116  }
117 
118  if (scan.ranges_.size() != step_max_ - step_min_ + 1)
119  {
121  << "Size of the received scan data is wrong "
122  "(expected: "
123  << step_max_ - step_min_ + 1
124  << ", received: " << scan.ranges_.size() << "); refreshing" << std::endl;
125  scip_->sendCommand(
126  (has_intensity ? "ME" : "MD") +
127  (boost::format("%04d%04d") % step_min_ % step_max_).str() +
128  "00000");
129  return;
130  }
131 
132  msg.ranges.reserve(scan.ranges_.size());
133  for (auto& r : scan.ranges_)
134  msg.ranges.push_back(r * 1e-3);
135  if (has_intensity)
136  {
137  msg.intensities.reserve(scan.intensities_.size());
138  for (auto& r : scan.intensities_)
139  msg.intensities.push_back(r);
140  }
141 
142  pub_scan_.publish(msg);
144 }
145 
147  const boost::posix_time::ptime& time_send, const std::string& cmd)
148 {
149  time_tm_request_ = std::make_pair(cmd, time_send);
150 }
151 
153  const boost::posix_time::ptime& time_read,
154  const std::string& echo_back,
155  const std::string& status,
156  const scip2::Timestamp& time_device)
157 {
158  if (status != "00")
159  {
160  scip2::logger::error() << echo_back << " errored with " << status << std::endl;
161  errorCountIncrement(status);
162 
163  if (echo_back[2] == '0' && delay_estim_state_ == DelayEstimState::ESTIMATION_STARTING)
164  {
166  << "Failed to enter the time synchronization mode, "
167  "even after receiving successful QT command response. "
168  "QT command may be ignored by the sensor firmware"
169  << std::endl;
171  }
172  return;
173  }
174 
175  if (!est_)
176  {
178  << "Received time sync response before timestamp estimator initialization"
179  << std::endl;
180  return;
181  }
182 
184  switch (echo_back[2])
185  {
186  case '0':
187  {
188  scip2::logger::debug() << "Entered the time synchronization mode" << std::endl;
190 
192  est_->clock_->startSync();
193 
194  sendTM1();
195  break;
196  }
197  case '1':
198  {
199  if (time_tm_request_.first != echo_back)
200  {
202  << "Ignoring unmatched TM1 response. Expected " << time_tm_request_.first
203  << ", received " << echo_back
204  << std::endl;
205  break;
206  }
207 
208  const uint64_t walltime_device = walltime_.update(time_device.timestamp_);
209 
210  est_->clock_->pushSyncSample(
212  ros::Time::fromBoost(time_read),
213  walltime_device);
214 
215  if (est_->clock_->hasEnoughSyncSamples())
216  {
217  scip_->sendCommand("TM2");
218  break;
219  }
220 
221  const std::pair<ros::Duration, ros::Duration> wait = est_->clock_->syncWaitDuration();
222  sleepRandom(wait.first.toSec(), wait.second.toSec());
223 
224  sendTM1();
225  break;
226  }
227  case '2':
228  {
229  if (!est_->clock_->finishSync() && !est_->clock_->getClockState().initialized_)
230  {
231  // Immediately retry if initial clock sync is failed
233  << std::setprecision(6) << std::fixed
234  << "Retrying initial clock state estimation (took "
235  << (ros::Time::now() - tm_start_time_).toSec()
236  << ")"
237  << std::endl;
239  break;
240  }
241 
243  scip_->sendCommand(
244  (publish_intensity_ ? "ME" : "MD") +
245  (boost::format("%04d%04d") % step_min_ % step_max_).str() +
246  "00000");
248  << std::setprecision(6) << std::fixed
249  << "Leaving the time synchronization mode (took "
250  << (ros::Time::now() - tm_start_time_).toSec()
251  << ")"
252  << std::endl;
253  tm_success_ = true;
254  publishStatus();
255  break;
256  }
257  }
258 }
259 
261  const boost::posix_time::ptime& time_read,
262  const std::string& echo_back,
263  const std::string& status,
264  const std::map<std::string, std::string>& params)
265 {
266  if (status != "00")
267  {
268  scip2::logger::error() << echo_back << " errored with " << status << std::endl;
269  errorCountIncrement(status);
270  return;
271  }
272 
273  const auto amin = params.find("AMIN");
274  const auto amax = params.find("AMAX");
275  const auto dmin = params.find("DMIN");
276  const auto dmax = params.find("DMAX");
277  const auto ares = params.find("ARES");
278  const auto afrt = params.find("AFRT");
279  const auto scan = params.find("SCAN");
280  if (amin == params.end() || amax == params.end() ||
281  dmin == params.end() || dmax == params.end() ||
282  ares == params.end() || afrt == params.end() ||
283  scan == params.end())
284  {
285  scip2::logger::error() << "PP doesn't have required parameters" << std::endl;
286  return;
287  }
288  step_min_ = std::stoi(amin->second);
289  step_max_ = std::stoi(amax->second);
290  ideal_scan_interval_ = ros::Duration(60.0 / std::stoi(scan->second));
291  msg_base_.scan_time = ideal_scan_interval_.toSec();
292  msg_base_.angle_increment = 2.0 * M_PI / std::stoi(ares->second);
293  msg_base_.time_increment = msg_base_.scan_time / std::stoi(ares->second);
294  msg_base_.range_min = std::stoi(dmin->second) * 1e-3;
295  msg_base_.range_max = std::stoi(dmax->second) * 1e-3;
296  msg_base_.angle_min =
297  (std::stoi(amin->second) - std::stoi(afrt->second)) * msg_base_.angle_increment;
298  msg_base_.angle_max =
299  (std::stoi(amax->second) - std::stoi(afrt->second)) * msg_base_.angle_increment;
300 
302 }
303 
305  const boost::posix_time::ptime& time_read,
306  const std::string& echo_back,
307  const std::string& status,
308  const std::map<std::string, std::string>& params)
309 {
310  if (status != "00")
311  {
312  scip2::logger::error() << echo_back << " errored with " << status << std::endl;
313  errorCountIncrement(status);
314  return;
315  }
316 
317  const char* keys[] =
318  {
319  "VEND",
320  "PROD",
321  "FIRM",
322  "PROT",
323  "SERI",
324  };
325  for (const char* key : keys)
326  {
327  const auto kv = params.find(key);
328  if (kv == params.end())
329  {
330  scip2::logger::error() << "VV doesn't have key " << key << std::endl;
331  continue;
332  }
333  scip2::logger::info() << key << ": " << kv->second << std::endl;
334  }
335  if (!est_)
336  {
337  int firm_major = 1;
338  int firm_minor = 0;
339  int firm_patch = 0;
340  {
341  const auto firm_it = params.find("FIRM");
342  if (firm_it == params.end())
343  {
345  << "Could not detect sensor hardware revision. Fallback to UUST1 mode"
346  << std::endl;
347  }
348  else
349  {
350  const std::vector<std::string> version = urg_stamped::strings::split(firm_it->second, '.');
351  if (version.size() < 3)
352  {
354  << "Invalid firmware version (" << firm_it->second << "). Fallback to UUST1 mode"
355  << std::endl;
356  }
357  else
358  {
359  firm_major = std::stoi(version[0]);
360  firm_minor = std::stoi(version[1]);
361  firm_patch = std::stoi(version[2]);
362  }
363  }
364  }
365  std::string prod;
366  {
367  const auto prod_it = params.find("PROD");
368  if (prod_it == params.end())
369  {
371  << "Could not detect sensor model. Fallback to UTM mode"
372  << std::endl;
373  prod = "UTM";
374  }
375  else
376  {
377  prod = prod_it->second.substr(0, 3);
378  }
379  }
382  std::string model;
383  is_uust2_ = false;
384  if (prod == "UTM")
385  {
388  }
389  else
390  {
391  if (prod != "UST")
392  {
394  << "Unknown sensor model. Fallback to UST mode"
395  << std::endl;
396  }
397  if (firm_major == 4 && firm_minor == 0 && firm_patch < 3)
398  {
399  model = "UST (UUST2Unfixed)";
401  is_uust2_ = true;
402  }
403  else
404  {
405  model = "UST (UUST1, UUST2Fixed)";
407  }
409  }
410  est_.reset(new device_state_estimator::Estimator(clock, scan));
411  scip2::logger::info() << "Initialized timestamp estimator for " << model << std::endl;
412  }
413 }
414 
416  const boost::posix_time::ptime& time_read,
417  const std::string& echo_back,
418  const std::string& status,
419  const std::map<std::string, std::string>& params)
420 {
421  if (status != "00")
422  {
423  scip2::logger::error() << echo_back << " errored with " << status << std::endl;
424  errorCountIncrement(status);
425  return;
426  }
427 
428  const auto stat = params.find("STAT");
429  if (stat != params.end())
430  {
431  scip2::logger::debug() << "sensor status: " << stat->second << std::endl;
432  }
433  const auto mesm = params.find("MESM");
434  if (mesm != params.end())
435  {
436  scip2::logger::debug() << "measurement status: " << mesm->second << std::endl;
437  }
438 
440  {
441  if (mesm == params.end())
442  {
443  scip2::logger::error() << "II doesn't have measurement state" << std::endl;
445  }
446  else
447  {
448  // MESM (measurement state) value depends on the sensor model.
449  // UTM-30LX-EW: "Idle"
450  // UST-**LX: "Measuring"
451  std::string state(mesm->second);
452  const auto tolower = [](unsigned char c)
453  {
454  return std::tolower(c);
455  };
456  std::transform(state.begin(), state.end(), state.begin(), tolower);
457  if (state.find("idle") != std::string::npos || state.find("measuring") != std::string::npos)
458  {
459  if (last_measurement_state_ != state && last_measurement_state_ != "")
460  {
461  scip2::logger::info() << "Sensor is idle, entering time synchronization mode" << std::endl;
462  }
464  retryTM();
465  }
466  else
467  {
468  if (last_measurement_state_ != state)
469  {
470  scip2::logger::info() << "Sensor is not idle (" << state << ")" << std::endl;
471  }
473  }
474  last_measurement_state_ = state;
475  }
476  return;
477  }
478 }
479 
481  const boost::posix_time::ptime& time_read,
482  const std::string& echo_back,
483  const std::string& status)
484 {
485  if (status != "00")
486  {
487  scip2::logger::error() << echo_back << " errored with " << status << std::endl;
488  errorCountIncrement(status);
489  return;
490  }
491 
492  scip2::logger::debug() << "Scan data stopped" << std::endl;
493 
495  {
497  retryTM();
498  }
499 }
500 
502  const boost::posix_time::ptime& time_read,
503  const std::string& echo_back,
504  const std::string& status)
505 {
506  if (status == "01")
507  {
508  scip2::logger::info() << "Sensor reboot in-progress" << std::endl;
509  scip_->sendCommand("RB"); // Sending it 2 times in 1 sec. is needed
510  return;
511  }
512  else if (status == "00")
513  {
514  scip2::logger::info() << "Sensor reboot succeeded" << std::endl;
515  device_->stop();
516  sleepRandom(1.0, 2.0);
517  ros::shutdown();
518  return;
519  }
521  << echo_back << " errored with " << status << std::endl
522  << "Failed to reboot. Please power-off the sensor." << std::endl;
523 }
524 
526  const boost::posix_time::ptime& time_read,
527  const std::string& echo_back,
528  const std::string& status)
529 {
530  const bool requested = cmd_resetting_;
531  cmd_resetting_ = false;
532 
533  if (status != "00")
534  {
535  scip2::logger::error() << echo_back << " errored with " << status << std::endl;
536  if (!requested)
537  {
538  errorCountIncrement(status);
539  return;
540  }
541  scip2::logger::error() << "Failed to reset. Rebooting the sensor and exiting." << std::endl;
542  hardReset();
543  return;
544  }
545  scip2::logger::info() << "Sensor reset succeeded" << std::endl;
546  if (failed_)
547  {
548  scip2::logger::info() << "Restarting urg_stamped" << std::endl;
549  device_->stop();
550  sleepRandom(0.5, 1.0);
551  ros::shutdown();
552  return;
553  }
554  scip_->sendCommand("PP");
555  scip_->sendCommand("VV");
557  tm_try_count_ = 0;
558 }
559 
561 {
562  softReset();
563  device_->startWatchdog(boost::posix_time::seconds(1));
564 }
565 
567 {
569  << "internal state on failure: "
570  << "delay_estim_state_=" << static_cast<int>(delay_estim_state_) << " "
571  << "tm_try_count_=" << tm_try_count_ << " "
572  << "error_count_.error=" << error_count_.error << " "
573  << "error_count_.abnormal_error=" << error_count_.abnormal_error << " "
574  << std::endl;
576  device_->stop();
577  ros::shutdown();
578 }
579 
581 {
582  scip_->sendCommand("II");
583 }
584 
586 {
587  if (scan_drop_count_ > 0)
588  {
589  auto& logger =
593  logger
594  << "Dropped "
596  << " scans with large time estimation error" << std::endl;
597  scan_drop_count_ = 0;
598  }
599 
600  tm_try_count_ = 0;
601  scip2::logger::debug() << "Starting communication delay estimation" << std::endl;
603  retryTM();
604 }
605 
607 {
608  bool retry = true;
610  switch (delay_estim_state_)
611  {
613  scip2::logger::debug() << "Stopping scan" << std::endl;
615  scip_->sendCommand("QT");
616  tm_try_count_++;
618  {
619  scip2::logger::error() << "Failed to enter time synchronization mode" << std::endl;
621  softReset();
622  }
623  break;
625  scip2::logger::debug() << "Checking sensor state" << std::endl;
626  sendII();
627  break;
629  scip2::logger::debug() << "Entering the time synchronization mode" << std::endl;
630  scip_->sendCommand("TM0");
631  break;
633  scip2::logger::warn() << "Timeout occured during the time synchronization" << std::endl;
634  scip_->sendCommand("TM2");
635  retry = false;
636  break;
637  default:
638  retry = false;
639  break;
640  }
641  if (retry)
642  {
644  }
645 }
646 
647 void UrgStampedNode::errorCountIncrement(const std::string& status)
648 {
650  {
651  // Already resetting or rebooting.
652  return;
653  }
654 
655  if (status == "00")
656  {
657  return;
658  }
659 
660  if (status == "0L")
661  {
664  {
665  failed_ = true;
668  << "Error count exceeded limit, rebooting the sensor and exiting."
669  << std::endl;
670  hardReset();
671  }
672  }
673  else
674  {
677  {
678  failed_ = true;
680  if (tm_success_)
681  {
683  << "Error count exceeded limit, resetting the sensor and exiting." << std::endl;
684  softReset();
685  }
686  else
687  {
689  << "Error count exceeded limit without successful time sync, "
690  "rebooting the sensor and exiting."
691  << std::endl;
692  hardReset();
693  }
694  }
695  }
696 }
697 
699 {
700  cmd_resetting_ = true;
701  scip_->sendCommand("RS");
702 }
703 
705 {
706  scip2::logger::error() << "Rebooting the sensor" << std::endl;
707  scip_->sendCommand("RB");
708 }
709 
710 void UrgStampedNode::sleepRandom(const double min, const double max)
711 {
712  std::uniform_real_distribution<double> rnd(min, max);
714 }
715 
717 {
718  std::stringstream cmd;
719  tm_key_++;
720  cmd << "TM1;" << std::hex << tm_key_;
721  scip_->sendCommand(
722  cmd.str(),
723  boost::bind(&UrgStampedNode::cbTMSend, this, boost::arg<1>(), cmd.str()));
724 }
725 
727 {
728  if (!est_)
729  {
730  return;
731  }
732  const device_state_estimator::ClockState clock = est_->clock_->getClockState();
733  const device_state_estimator::ScanState scan = est_->scan_->getScanState();
734  const device_state_estimator::CommDelay comm_delay = est_->clock_->getCommDelay();
735 
736  urg_stamped::Status msg;
737  msg.header.stamp = ros::Time::now();
738  msg.header.frame_id = msg_base_.header.frame_id;
739  msg.sensor_clock_origin = clock.origin_;
740  msg.sensor_clock_gain = clock.gain_;
741  msg.communication_delay = comm_delay.min_;
742  msg.communication_delay_sigma = comm_delay.sigma_;
743  msg.scan_time_origin = scan.origin_;
744  msg.scan_interval = scan.interval_;
745  pub_status_.publish(msg);
746 }
747 
748 void UrgStampedNode::cbSyncStart(const std_msgs::Header::ConstPtr& msg)
749 {
750  if (msg->frame_id == msg_base_.header.frame_id)
751  {
752  return;
753  }
754  switch (delay_estim_state_)
755  {
758  return;
759  break;
760  default:
761  break;
762  }
763  std::uniform_real_distribution<double> rnd(0, clock_estim_interval_.toSec());
764  ros::Duration offset(rnd(random_engine_));
765  next_sync_ += offset;
767  << std::fixed << std::setprecision(3)
768  << "Concurrent time synchronization detected. Delaying the next time sync by "
769  << offset.toSec() << "s"
770  << std::endl;
771 }
772 
774 {
775  std_msgs::Header msg;
776  msg.frame_id = msg_base_.header.frame_id;
777  msg.stamp = ros::Time::now();
779 }
780 
782  : nh_("")
783  , pnh_("~")
784  , failed_(false)
785  , delay_estim_state_(DelayEstimState::IDLE)
786  , tm_key_(0)
787  , last_sync_time_(0)
788  , tm_success_(false)
789  , scan_drop_count_(0)
790  , scan_drop_continuous_(0)
791  , cmd_resetting_(false)
792  , is_uust2_(false)
793 {
794  std::random_device rd;
795  random_engine_.seed(rd());
796 
797  std::string ip;
798  int port;
799  double clock_estim_interval;
800 
801  pnh_.param("ip_address", ip, std::string("192.168.0.10"));
802  pnh_.param("ip_port", port, 10940);
803  pnh_.param("frame_id", msg_base_.header.frame_id, std::string("laser"));
804  pnh_.param("publish_intensity", publish_intensity_, true);
805  pnh_.param("clock_estim_interval", clock_estim_interval, 30.0);
806  pnh_.param("error_limit", error_count_max_, 4);
807  pnh_.param("fallback_on_continuous_scan_drop", fallback_on_continuous_scan_drop_, 5);
808  clock_estim_interval_ = ros::Duration(clock_estim_interval);
809 
810  // 30s * 40Hz = 1200scans total, output info level log if dropped 90/1200scans or more
811  pnh_.param("log_scan_drop_more_than", log_scan_drop_more_than_, static_cast<int>(clock_estim_interval * 3));
812 
813  double tm_interval, tm_timeout;
814  pnh_.param("tm_interval", tm_interval, 0.06);
815  tm_command_interval_ = ros::Duration(tm_interval);
816  pnh_.param("tm_timeout", tm_timeout, 10.0);
817  tm_try_max_ = static_cast<int>(tm_timeout / tm_interval);
818 
819  // UUST2 doesn't support estimating communication delay. Static offset can be specified to compensate the delay
820  double uust2_stamp_offset;
821  pnh_.param("uust2_stamp_offset", uust2_stamp_offset, 0.0);
822  uust2_stamp_offset_ = ros::Duration(uust2_stamp_offset);
823 
824  urg_stamped::setROSLogger(msg_base_.header.frame_id + ": ");
825 
826  bool debug;
827  pnh_.param("debug", debug, false);
828  if (debug)
829  {
830  // Enable debug level log at the beginning of the node to show initialization related logs.
832  {
834  }
835  }
836 
837  pub_scan_ = nh_.advertise<sensor_msgs::LaserScan>("scan", 10);
838  pub_status_ = pnh_.advertise<urg_stamped::Status>("status", 1, true);
839 
840  pub_sync_start_ = nh_.advertise<std_msgs::Header>("urg_stamped_sync_start", 1, true);
841  sub_sync_start_ = nh_.subscribe("urg_stamped_sync_start", 1, &UrgStampedNode::cbSyncStart, this);
842 
843  device_.reset(new scip2::ConnectionTcp(ip, port));
844  device_->registerCloseCallback(
845  boost::bind(&UrgStampedNode::cbClose, this));
846  device_->registerConnectCallback(
847  boost::bind(&UrgStampedNode::cbConnect, this));
848 
849  scip_.reset(new scip2::Protocol(device_));
850  scip_->registerCallback<scip2::ResponsePP>(
851  boost::bind(&UrgStampedNode::cbPP, this,
852  boost::arg<1>(),
853  boost::arg<2>(),
854  boost::arg<3>(),
855  boost::arg<4>()));
856  scip_->registerCallback<scip2::ResponseVV>(
857  boost::bind(&UrgStampedNode::cbVV, this,
858  boost::arg<1>(),
859  boost::arg<2>(),
860  boost::arg<3>(),
861  boost::arg<4>()));
862  scip_->registerCallback<scip2::ResponseII>(
863  boost::bind(&UrgStampedNode::cbII, this,
864  boost::arg<1>(),
865  boost::arg<2>(),
866  boost::arg<3>(),
867  boost::arg<4>()));
868  scip_->registerCallback<scip2::ResponseMD>(
869  boost::bind(&UrgStampedNode::cbM, this,
870  boost::arg<1>(),
871  boost::arg<2>(),
872  boost::arg<3>(),
873  boost::arg<4>(),
874  false));
875  scip_->registerCallback<scip2::ResponseME>(
876  boost::bind(&UrgStampedNode::cbM, this,
877  boost::arg<1>(),
878  boost::arg<2>(),
879  boost::arg<3>(),
880  boost::arg<4>(),
881  true));
882  scip_->registerCallback<scip2::ResponseTM>(
883  boost::bind(&UrgStampedNode::cbTM, this,
884  boost::arg<1>(),
885  boost::arg<2>(),
886  boost::arg<3>(),
887  boost::arg<4>()));
888  scip_->registerCallback<scip2::ResponseQT>(
889  boost::bind(&UrgStampedNode::cbQT, this,
890  boost::arg<1>(),
891  boost::arg<2>(),
892  boost::arg<3>()));
893  scip_->registerCallback<scip2::ResponseRB>(
894  boost::bind(&UrgStampedNode::cbRB, this,
895  boost::arg<1>(),
896  boost::arg<2>(),
897  boost::arg<3>()));
898  scip_->registerCallback<scip2::ResponseRS>(
899  boost::bind(&UrgStampedNode::cbRS, this,
900  boost::arg<1>(),
901  boost::arg<2>(),
902  boost::arg<3>()));
903 
905  {
907  }
908 }
909 
911 {
912  boost::thread thread(
913  boost::bind(&scip2::Connection::spin, device_.get()));
914  ros::spin();
916  scip_->sendCommand("QT");
917  device_->stop();
918  thread.join();
919 }
920 } // namespace urg_stamped
urg_stamped::device_state_estimator::ScanState::interval_
ros::Duration interval_
Definition: device_state_estimator.h:174
scip2::logger::info
std::ostream & info()
Definition: logger.cpp:97
scip2.h
urg_stamped::UrgStampedNode::ResponseErrorCount
Definition: urg_stamped.h:105
urg_stamped::UrgStampedNode::publishSyncStart
void publishSyncStart()
Definition: urg_stamped.cpp:773
urg_stamped::UrgStampedNode::UrgStampedNode
UrgStampedNode()
Definition: urg_stamped.cpp:781
scip2::ResponsePP
Definition: parameters.h:86
scip2::ScanData
Definition: stream.h:33
urg_stamped::UrgStampedNode::uust2_stamp_offset_
ros::Duration uust2_stamp_offset_
Definition: urg_stamped.h:133
urg_stamped::UrgStampedNode::spin
void spin()
Definition: urg_stamped.cpp:910
urg_stamped::UrgStampedNode::cbII
void cbII(const boost::posix_time::ptime &time_read, const std::string &echo_back, const std::string &status, const std::map< std::string, std::string > &params)
Definition: urg_stamped.cpp:415
urg_stamped::UrgStampedNode::scip_
scip2::Protocol::Ptr scip_
Definition: urg_stamped.h:79
urg_stamped::device_state_estimator::ScanEstimator::Ptr
std::shared_ptr< ScanEstimator > Ptr
Definition: device_state_estimator.h:233
urg_stamped::UrgStampedNode::step_max_
uint32_t step_max_
Definition: urg_stamped.h:75
urg_stamped::UrgStampedNode::cbTM
void cbTM(const boost::posix_time::ptime &time_read, const std::string &echo_back, const std::string &status, const scip2::Timestamp &time_device)
Definition: urg_stamped.cpp:152
urg_stamped::strings::split
std::vector< std::string > split(const std::string &s, const char delim)
Definition: strings.h:28
logger.h
urg_stamped::UrgStampedNode::nh_
ros::NodeHandle nh_
Definition: urg_stamped.h:65
scip2::ResponseME
Definition: stream.h:162
urg_stamped::UrgStampedNode::sendTM1
void sendTM1()
Definition: urg_stamped.cpp:716
urg_stamped::UrgStampedNode::DelayEstimState::STOPPING_SCAN
@ STOPPING_SCAN
scip2::Connection::spin
virtual void spin()=0
urg_stamped::device_state_estimator::ClockState::origin_
ros::Time origin_
Definition: device_state_estimator.h:60
ros.h
urg_stamped::UrgStampedNode::scan_drop_count_
int scan_drop_count_
Definition: urg_stamped.h:118
urg_stamped::UrgStampedNode::cbSyncStart
void cbSyncStart(const std_msgs::Header::ConstPtr &msg)
Definition: urg_stamped.cpp:748
ros::Timer::stop
void stop()
scip2::Timestamp::timestamp_
uint32_t timestamp_
Definition: time_sync.h:34
urg_stamped::device_state_estimator::ClockEstimator::Ptr
std::shared_ptr< ClockEstimator > Ptr
Definition: device_state_estimator.h:200
TimeBase< Time, Duration >::toSec
double toSec() const
urg_stamped::UrgStampedNode::cbVV
void cbVV(const boost::posix_time::ptime &time_read, const std::string &echo_back, const std::string &status, const std::map< std::string, std::string > &params)
Definition: urg_stamped.cpp:304
ros::shutdown
ROSCPP_DECL void shutdown()
scip2::ResponseRB
Definition: reboot.h:28
urg_stamped::device_state_estimator::ClockState::gain_
double gain_
Definition: device_state_estimator.h:61
urg_stamped::UrgStampedNode::est_
device_state_estimator::Estimator::Ptr est_
Definition: urg_stamped.h:130
urg_stamped::UrgStampedNode::error_count_max_
int error_count_max_
Definition: urg_stamped.h:117
urg_stamped::UrgStampedNode::estimateSensorClock
void estimateSensorClock(const ros::TimerEvent &event=ros::TimerEvent())
Definition: urg_stamped.cpp:585
urg_stamped::UrgStampedNode::errorCountIncrement
void errorCountIncrement(const std::string &status="")
Definition: urg_stamped.cpp:647
urg_stamped::device_state_estimator::CommDelay
Definition: device_state_estimator.h:42
urg_stamped::UrgStampedNode::cbQT
void cbQT(const boost::posix_time::ptime &time_read, const std::string &echo_back, const std::string &status)
Definition: urg_stamped.cpp:480
ros::console::set_logger_level
ROSCONSOLE_DECL bool set_logger_level(const std::string &name, levels::Level level)
urg_stamped::UrgStampedNode::cbRB
void cbRB(const boost::posix_time::ptime &time_read, const std::string &echo_back, const std::string &status)
Definition: urg_stamped.cpp:501
urg_stamped::UrgStampedNode::tm_start_time_
ros::Time tm_start_time_
Definition: urg_stamped.h:97
urg_stamped::UrgStampedNode::cbClose
void cbClose()
Definition: urg_stamped.cpp:566
urg_stamped::UrgStampedNode::publish_intensity_
bool publish_intensity_
Definition: urg_stamped.h:81
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
ros::NodeHandle::advertise
Publisher advertise(AdvertiseOptions &ops)
scip2::Walltime::update
uint64_t update(const uint32_t &time_device)
Definition: walltime.h:37
urg_stamped::UrgStampedNode::DelayEstimState::EXITING
@ EXITING
urg_stamped::UrgStampedNode::ResponseErrorCount::abnormal_error
int abnormal_error
Definition: urg_stamped.h:112
urg_stamped::device_state_estimator::CommDelay::min_
ros::Duration min_
Definition: device_state_estimator.h:45
scip2::ResponseTM
Definition: time_sync.h:42
scip2::ResponseMD
Definition: stream.h:102
urg_stamped::UrgStampedNode::cbConnect
void cbConnect()
Definition: urg_stamped.cpp:560
urg_stamped::device_state_estimator::ClockEstimatorUUST2
Definition: device_state_estimator.h:321
urg_stamped::UrgStampedNode::time_tm_request_
std::pair< std::string, boost::posix_time::ptime > time_tm_request_
Definition: urg_stamped.h:96
console.h
urg_stamped::UrgStampedNode::random_engine_
std::default_random_engine random_engine_
Definition: urg_stamped.h:102
urg_stamped::UrgStampedNode::device_
scip2::Connection::Ptr device_
Definition: urg_stamped.h:78
scip2::ResponseVV
Definition: parameters.h:95
ros::Time::isValid
static bool isValid()
ros::console::levels::Debug
Debug
urg_stamped::UrgStampedNode::tm_success_
bool tm_success_
Definition: urg_stamped.h:116
urg_stamped::UrgStampedNode::clock_estim_interval_
ros::Duration clock_estim_interval_
Definition: urg_stamped.h:85
urg_stamped::UrgStampedNode::DelayEstimState::ESTIMATING
@ ESTIMATING
urg_stamped::device_state_estimator::ScanEstimatorUTM
Definition: device_state_estimator.h:371
scip2::ResponseII
Definition: parameters.h:104
scip2::ResponseRS
Definition: reset.h:28
urg_stamped::UrgStampedNode::sendII
void sendII()
Definition: urg_stamped.cpp:580
walltime.h
urg_stamped::UrgStampedNode::cbM
void cbM(const boost::posix_time::ptime &time_read, const std::string &echo_back, const std::string &status, const scip2::ScanData &scan, const bool has_intensity)
Definition: urg_stamped.cpp:48
params
std::vector< urg_sim::URGSimulator::Params > params({ { .model=urg_sim::URGSimulator::Model::UTM,.boot_duration=0.01,.comm_delay_base=0.0002,.comm_delay_sigma=0.0004,.scan_interval=0.02505,.clock_rate=1.0,.hex_ii_timestamp=false,.angle_resolution=1440,.angle_min=0,.angle_max=1080,.angle_front=540, }, { .model=urg_sim::URGSimulator::Model::UTM,.boot_duration=0.01,.comm_delay_base=0.0002,.comm_delay_sigma=0.0004,.scan_interval=0.02505,.clock_rate=1.001,.hex_ii_timestamp=false,.angle_resolution=1440,.angle_min=0,.angle_max=1080,.angle_front=540, }, { .model=urg_sim::URGSimulator::Model::UTM,.boot_duration=0.01,.comm_delay_base=0.0002,.comm_delay_sigma=0.0004,.scan_interval=0.02505,.clock_rate=0.999,.hex_ii_timestamp=false,.angle_resolution=1440,.angle_min=0,.angle_max=1080,.angle_front=540, }, { .model=urg_sim::URGSimulator::Model::UST_UUST1,.boot_duration=0.01,.comm_delay_base=0.0005,.comm_delay_sigma=0.0005,.scan_interval=0.02505,.clock_rate=1.0,.hex_ii_timestamp=true,.angle_resolution=1440,.angle_min=0,.angle_max=1080,.angle_front=540, }, { .model=urg_sim::URGSimulator::Model::UST_UUST1,.boot_duration=0.01,.comm_delay_base=0.0005,.comm_delay_sigma=0.0005,.scan_interval=0.02505,.clock_rate=1.001,.hex_ii_timestamp=true,.angle_resolution=1440,.angle_min=0,.angle_max=1080,.angle_front=540, }, { .model=urg_sim::URGSimulator::Model::UST_UUST1,.boot_duration=0.01,.comm_delay_base=0.0005,.comm_delay_sigma=0.0005,.scan_interval=0.02505,.clock_rate=0.999,.hex_ii_timestamp=true,.angle_resolution=1440,.angle_min=0,.angle_max=1080,.angle_front=540, }, { .model=urg_sim::URGSimulator::Model::UST_UUST2,.boot_duration=0.01,.comm_delay_base=0.0002,.comm_delay_sigma=0.0002,.scan_interval=0.02505,.clock_rate=1.0,.hex_ii_timestamp=true,.angle_resolution=1440,.angle_min=0,.angle_max=1080,.angle_front=540, }, { .model=urg_sim::URGSimulator::Model::UST_UUST2,.boot_duration=0.01,.comm_delay_base=0.0002,.comm_delay_sigma=0.0002,.scan_interval=0.02505,.clock_rate=1.001,.hex_ii_timestamp=true,.angle_resolution=1440,.angle_min=0,.angle_max=1080,.angle_front=540, }, { .model=urg_sim::URGSimulator::Model::UST_UUST2,.boot_duration=0.01,.comm_delay_base=0.0002,.comm_delay_sigma=0.0002,.scan_interval=0.02505,.clock_rate=0.999,.hex_ii_timestamp=true,.angle_resolution=1440,.angle_min=0,.angle_max=1080,.angle_front=540, }, })
urg_stamped::UrgStampedNode::msg_base_
sensor_msgs::LaserScan msg_base_
Definition: urg_stamped.h:73
scip2::ScanData::ranges_
std::vector< int32_t > ranges_
Definition: stream.h:37
urg_stamped::UrgStampedNode::pnh_
ros::NodeHandle pnh_
Definition: urg_stamped.h:66
urg_stamped::device_state_estimator::ClockEstimatorUUST1
Definition: device_state_estimator.h:272
ros::NodeHandle::subscribe
Subscriber subscribe(const std::string &topic, uint32_t queue_size, const boost::function< void(C)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints())
urg_stamped::UrgStampedNode::error_count_
ResponseErrorCount error_count_
Definition: urg_stamped.h:115
ros::TimerEvent
urg_stamped::UrgStampedNode::hardReset
void hardReset()
Definition: urg_stamped.cpp:704
urg_stamped::UrgStampedNode::is_uust2_
bool is_uust2_
Definition: urg_stamped.h:132
strings.h
urg_stamped::UrgStampedNode::tm_try_max_
int tm_try_max_
Definition: urg_stamped.h:125
urg_stamped::UrgStampedNode::walltime_
scip2::Walltime< 24 > walltime_
Definition: urg_stamped.h:100
urg_stamped::setROSLogger
void setROSLogger(const std::string &prefix)
Definition: ros_logger.cpp:113
urg_stamped::UrgStampedNode::tm_key_
uint32_t tm_key_
Definition: urg_stamped.h:98
urg_stamped::UrgStampedNode::next_sync_
ros::Time next_sync_
Definition: urg_stamped.h:84
urg_stamped::UrgStampedNode::step_min_
uint32_t step_min_
Definition: urg_stamped.h:74
urg_stamped::UrgStampedNode::DelayEstimState
DelayEstimState
Definition: urg_stamped.h:86
urg_stamped::UrgStampedNode::retryTM
void retryTM(const ros::TimerEvent &event=ros::TimerEvent())
Definition: urg_stamped.cpp:606
urg_stamped::UrgStampedNode::DelayEstimState::STATE_CHECKING
@ STATE_CHECKING
scip2::logger::debug
std::ostream & debug()
Definition: logger.cpp:93
urg_stamped::UrgStampedNode::delay_estim_state_
DelayEstimState delay_estim_state_
Definition: urg_stamped.h:95
urg_stamped::device_state_estimator::Estimator
Definition: device_state_estimator.h:255
urg_stamped::UrgStampedNode::publishStatus
void publishStatus()
Definition: urg_stamped.cpp:726
urg_stamped::UrgStampedNode::ResponseErrorCount::error
int error
Definition: urg_stamped.h:113
scip2::Timestamp
Definition: time_sync.h:31
scip2::ScanData::intensities_
std::vector< int32_t > intensities_
Definition: stream.h:38
urg_stamped.h
scip2::ConnectionTcp
Definition: connection.h:92
ros::console::notifyLoggerLevelsChanged
ROSCONSOLE_DECL void notifyLoggerLevelsChanged()
ros::Time
urg_stamped::UrgStampedNode::pub_sync_start_
ros::Publisher pub_sync_start_
Definition: urg_stamped.h:69
urg_stamped::UrgStampedNode::sub_sync_start_
ros::Subscriber sub_sync_start_
Definition: urg_stamped.h:70
urg_stamped::UrgStampedNode::cmd_resetting_
bool cmd_resetting_
Definition: urg_stamped.h:128
urg_stamped::UrgStampedNode::sleepRandom
void sleepRandom(const double min, const double max)
Definition: urg_stamped.cpp:710
urg_stamped::UrgStampedNode::pub_status_
ros::Publisher pub_status_
Definition: urg_stamped.h:68
urg_stamped::UrgStampedNode::fallback_on_continuous_scan_drop_
int fallback_on_continuous_scan_drop_
Definition: urg_stamped.h:120
urg_stamped::UrgStampedNode::failed_
bool failed_
Definition: urg_stamped.h:82
urg_stamped::UrgStampedNode::softReset
void softReset()
Definition: urg_stamped.cpp:698
urg_stamped::UrgStampedNode::log_scan_drop_more_than_
int log_scan_drop_more_than_
Definition: urg_stamped.h:121
ros::NodeHandle::param
T param(const std::string &param_name, const T &default_val) const
scip2::ResponseQT
Definition: quit.h:28
urg_stamped::UrgStampedNode::timer_retry_tm_
ros::Timer timer_retry_tm_
Definition: urg_stamped.h:71
urg_stamped::device_state_estimator::ScanEstimatorUST
Definition: device_state_estimator.h:397
ros::spin
ROSCPP_DECL void spin()
urg_stamped::UrgStampedNode::cbPP
void cbPP(const boost::posix_time::ptime &time_read, const std::string &echo_back, const std::string &status, const std::map< std::string, std::string > &params)
Definition: urg_stamped.cpp:260
urg_stamped::UrgStampedNode::tm_try_count_
int tm_try_count_
Definition: urg_stamped.h:126
ros::Duration::sleep
bool sleep() const
scip2::ScanData::timestamp_
uint32_t timestamp_
Definition: stream.h:36
DurationBase< Duration >::toSec
double toSec() const
ROSCONSOLE_DEFAULT_NAME
#define ROSCONSOLE_DEFAULT_NAME
urg_stamped::UrgStampedNode::scan_drop_continuous_
int scan_drop_continuous_
Definition: urg_stamped.h:119
urg_stamped::device_state_estimator::CommDelay::sigma_
ros::Duration sigma_
Definition: device_state_estimator.h:46
urg_stamped::UrgStampedNode::cbRS
void cbRS(const boost::posix_time::ptime &time_read, const std::string &echo_back, const std::string &status)
Definition: urg_stamped.cpp:525
scip2::Protocol
Definition: protocol.h:33
urg_stamped
Definition: device_state_estimator.h:35
urg_stamped::device_state_estimator::ScanState
Definition: device_state_estimator.h:170
urg_stamped::UrgStampedNode::tm_command_interval_
ros::Duration tm_command_interval_
Definition: urg_stamped.h:123
urg_stamped::UrgStampedNode::pub_scan_
ros::Publisher pub_scan_
Definition: urg_stamped.h:67
urg_stamped::UrgStampedNode::DelayEstimState::ESTIMATION_STARTING
@ ESTIMATION_STARTING
scip2::logger::error
std::ostream & error()
Definition: logger.cpp:105
urg_stamped::UrgStampedNode::cbTMSend
void cbTMSend(const boost::posix_time::ptime &time_send, const std::string &cmd)
Definition: urg_stamped.cpp:146
urg_stamped::device_state_estimator::ScanState::origin_
ros::Time origin_
Definition: device_state_estimator.h:173
ros::NodeHandle::createTimer
Timer createTimer(Duration period, const TimerCallback &callback, bool oneshot=false, bool autostart=true) const
urg_stamped::UrgStampedNode::ideal_scan_interval_
ros::Duration ideal_scan_interval_
Definition: urg_stamped.h:76
ros::Duration
urg_stamped::device_state_estimator::ClockState
Definition: device_state_estimator.h:57
urg_stamped::UrgStampedNode::last_measurement_state_
std::string last_measurement_state_
Definition: urg_stamped.h:124
ros::Time::fromBoost
static Time fromBoost(const boost::posix_time::ptime &t)
ros::Time::now
static Time now()
ros_logger.h
urg_stamped::UrgStampedNode::DelayEstimState::IDLE
@ IDLE
scip2::logger::warn
std::ostream & warn()
Definition: logger.cpp:101


urg_stamped
Author(s): Atsushi Watanabe
autogenerated on Wed Dec 18 2024 03:10:57