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 #include <sensor_msgs/LaserScan.h>
20 
21 #include <boost/bind/bind.hpp>
22 #include <boost/format.hpp>
23 #include <boost/thread.hpp>
24 
25 #include <algorithm>
26 #include <list>
27 #include <map>
28 #include <random>
29 #include <string>
30 #include <vector>
31 
32 #include <scip2/scip2.h>
33 #include <scip2/walltime.h>
34 #include <scip2/logger.h>
35 
40 #include <urg_stamped/ros_logger.h>
41 
43 
44 namespace urg_stamped
45 {
47  const boost::posix_time::ptime& time_read,
48  const std::string& echo_back,
49  const std::string& status,
50  const scip2::ScanData& scan,
51  const bool has_intensity)
52 {
53  if (status != "99")
54  {
55  if (status != "00")
56  {
57  scip2::logger::error() << echo_back << " errored with " << status << std::endl;
58  errorCountIncrement(status);
59  }
60  return;
61  }
62 
63  const uint64_t walltime_device = walltime_.update(scan.timestamp_);
64  if (detectDeviceTimeJump(time_read, walltime_device))
65  {
66  errorCountIncrement(status);
67  return;
68  }
69 
70  const auto estimated_timestamp_lf =
72  ros::Duration().fromNSec(walltime_device * 1e6 * device_time_origin_.gain_) +
73  ros::Duration(msg_base_.time_increment * step_min_);
74 
75  if (t0_ == ros::Time(0))
76  t0_ = estimated_timestamp_lf;
77 
78  const ros::Time time_read_ros = ros::Time::fromBoost(time_read);
79  const auto receive_time =
81  time_read_ros -
83  ros::Duration(msg_base_.scan_time));
84 
85  sensor_msgs::LaserScan msg(msg_base_);
86  msg.header.stamp =
88  t0_ +
90  timestamp_lpf_.update((estimated_timestamp_lf - t0_).toSec()) +
91  timestamp_hpf_.update((receive_time - t0_).toSec())));
92 
93  if (msg.header.stamp > time_read_ros)
94  {
96  << std::setprecision(6) << std::fixed
97  << "estimated future timestamp (read: " << time_read_ros.toSec()
98  << ", estimated: " << msg.header.stamp.toSec() << std::endl;
100  return;
101  }
102 
103  if (scan.ranges_.size() != step_max_ - step_min_ + 1)
104  {
106  << "Size of the received scan data is wrong "
107  "(expected: "
108  << step_max_ - step_min_ + 1
109  << ", received: " << scan.ranges_.size() << "); refreshing" << std::endl;
110  scip_->sendCommand(
111  (has_intensity ? "ME" : "MD") +
112  (boost::format("%04d%04d") % step_min_ % step_max_).str() +
113  "00000");
114  return;
115  }
116 
117  msg.ranges.reserve(scan.ranges_.size());
118  for (auto& r : scan.ranges_)
119  msg.ranges.push_back(r * 1e-3);
120  if (has_intensity)
121  {
122  msg.intensities.reserve(scan.intensities_.size());
123  for (auto& r : scan.intensities_)
124  msg.intensities.push_back(r);
125  }
126 
127  pub_scan_.publish(msg);
129 }
130 
131 void UrgStampedNode::cbTMSend(const boost::posix_time::ptime& time_send)
132 {
133  time_tm_request = time_send;
134 }
135 
137  const boost::posix_time::ptime& time_read,
138  const std::string& echo_back,
139  const std::string& status,
140  const scip2::Timestamp& time_device)
141 {
142  if (status != "00")
143  {
144  scip2::logger::error() << echo_back << " errored with " << status << std::endl;
145  errorCountIncrement(status);
146 
147  if (echo_back[2] == '0' && delay_estim_state_ == DelayEstimState::ESTIMATION_STARTING)
148  {
150  << "Failed to enter the time synchronization mode, "
151  "even after receiving successful QT command response. "
152  "QT command may be ignored by the sensor firmware"
153  << std::endl;
155  }
156  return;
157  }
158 
160  switch (echo_back[2])
161  {
162  case '0':
163  {
164  scip2::logger::debug() << "Entered the time synchronization mode" << std::endl;
166  scip_->sendCommand(
167  "TM1",
168  boost::bind(&UrgStampedNode::cbTMSend, this, boost::arg<1>()));
169  break;
170  }
171  case '1':
172  {
173  const uint64_t walltime_device = walltime_.update(time_device.timestamp_);
174  if (detectDeviceTimeJump(time_read, walltime_device))
175  {
176  errorCountIncrement(status);
177  break;
178  }
179 
180  const auto delay =
181  ros::Time::fromBoost(time_read) -
183  communication_delays_.push_back(delay);
185  communication_delays_.pop_front();
186 
188  time_tm_request, time_read, walltime_device);
189  device_time_origins_.push_back(origin);
191  device_time_origins_.pop_front();
192 
193  if (communication_delays_.size() >= tm_iter_num_)
194  {
195  std::vector<ros::Duration> delays(communication_delays_.begin(), communication_delays_.end());
196  std::vector<ros::Time> origins(device_time_origins_.begin(), device_time_origins_.end());
197  sort(delays.begin(), delays.end());
198  sort(origins.begin(), origins.end());
199 
201  {
204  }
205  else
206  {
210  }
213  << "delay: "
214  << std::setprecision(6) << std::fixed << estimated_communication_delay_.toSec()
215  << ", device timestamp: " << walltime_device
216  << ", device time origin: " << origins[tm_iter_num_ / 2].toSec()
217  << std::endl;
218  scip_->sendCommand("TM2");
219  }
220  else
221  {
222  ros::Duration(0.005).sleep();
223  scip_->sendCommand(
224  "TM1",
225  boost::bind(&UrgStampedNode::cbTMSend, this, boost::arg<1>()));
226  }
227  break;
228  }
229  case '2':
230  {
232  scip_->sendCommand(
233  (publish_intensity_ ? "ME" : "MD") +
234  (boost::format("%04d%04d") % step_min_ % step_max_).str() +
235  "00000");
236  timeSync();
239  t0_ = ros::Time();
240  scip2::logger::debug() << "Leaving the time synchronization mode" << std::endl;
241  tm_success_ = true;
242  break;
243  }
244  }
245 }
246 
248  const boost::posix_time::ptime& time_read,
249  const std::string& echo_back,
250  const std::string& status,
251  const std::map<std::string, std::string>& params)
252 {
253  if (status != "00")
254  {
255  scip2::logger::error() << echo_back << " errored with " << status << std::endl;
256  errorCountIncrement(status);
257  return;
258  }
259 
260  const auto amin = params.find("AMIN");
261  const auto amax = params.find("AMAX");
262  const auto dmin = params.find("DMIN");
263  const auto dmax = params.find("DMAX");
264  const auto ares = params.find("ARES");
265  const auto afrt = params.find("AFRT");
266  const auto scan = params.find("SCAN");
267  if (amin == params.end() || amax == params.end() ||
268  dmin == params.end() || dmax == params.end() ||
269  ares == params.end() || afrt == params.end() ||
270  scan == params.end())
271  {
272  scip2::logger::error() << "PP doesn't have required parameters" << std::endl;
273  return;
274  }
275  step_min_ = std::stoi(amin->second);
276  step_max_ = std::stoi(amax->second);
277  msg_base_.scan_time = 60.0 / std::stoi(scan->second);
278  msg_base_.angle_increment = 2.0 * M_PI / std::stoi(ares->second);
279  msg_base_.time_increment = msg_base_.scan_time / std::stoi(ares->second);
280  msg_base_.range_min = std::stoi(dmin->second) * 1e-3;
281  msg_base_.range_max = std::stoi(dmax->second) * 1e-3;
282  msg_base_.angle_min =
283  (std::stoi(amin->second) - std::stoi(afrt->second)) * msg_base_.angle_increment;
284  msg_base_.angle_max =
285  (std::stoi(amax->second) - std::stoi(afrt->second)) * msg_base_.angle_increment;
286 
289  delayEstimation();
290 }
291 
293  const boost::posix_time::ptime& time_read,
294  const std::string& echo_back,
295  const std::string& status,
296  const std::map<std::string, std::string>& params)
297 {
298  if (status != "00")
299  {
300  scip2::logger::error() << echo_back << " errored with " << status << std::endl;
301  errorCountIncrement(status);
302  return;
303  }
304 
305  const char* keys[] =
306  {
307  "VEND",
308  "PROD",
309  "FIRM",
310  "PROT",
311  "SERI",
312  };
313  for (const char* key : keys)
314  {
315  const auto kv = params.find(key);
316  if (kv == params.end())
317  {
318  scip2::logger::error() << "VV doesn't have key " << key << std::endl;
319  continue;
320  }
321  scip2::logger::info() << key << ": " << kv->second << std::endl;
322  }
323 }
324 
325 void UrgStampedNode::cbIISend(const boost::posix_time::ptime& time_send)
326 {
327  time_ii_request = time_send;
328 }
329 
331  const boost::posix_time::ptime& time_read,
332  const std::string& echo_back,
333  const std::string& status,
334  const std::map<std::string, std::string>& params)
335 {
336  if (status != "00")
337  {
338  scip2::logger::error() << echo_back << " errored with " << status << std::endl;
339  errorCountIncrement(status);
340  return;
341  }
342 
343  const auto stat = params.find("STAT");
344  if (stat != params.end())
345  {
346  scip2::logger::debug() << "sensor status: " << stat->second << std::endl;
347  }
348  const auto mesm = params.find("MESM");
349  if (mesm != params.end())
350  {
351  scip2::logger::debug() << "measurement status: " << mesm->second << std::endl;
352  }
353 
355  {
356  if (mesm == params.end())
357  {
358  scip2::logger::error() << "II doesn't have measurement state" << std::endl;
360  }
361  else
362  {
363  // MESM (measurement state) value depends on the sensor model.
364  // UTM-30LX-EW: "Idle"
365  // UST-**LX: "Measuring"
366  std::string state(mesm->second);
367  const auto tolower = [](unsigned char c)
368  {
369  return std::tolower(c);
370  };
371  std::transform(state.begin(), state.end(), state.begin(), tolower);
372  if (state.find("idle") != std::string::npos || state.find("measuring") != std::string::npos)
373  {
374  if (last_measurement_state_ != state && last_measurement_state_ != "")
375  {
376  scip2::logger::info() << "Sensor is idle, entering time synchronization mode" << std::endl;
377  }
379  retryTM();
380  }
381  else
382  {
383  if (last_measurement_state_ != state)
384  {
385  scip2::logger::info() << "Sensor is not idle (" << state << ")" << std::endl;
386  }
388  }
389  last_measurement_state_ = state;
390  }
391  return;
392  }
393 
394  const auto delay =
395  ros::Time::fromBoost(time_read) -
397 
398  if (delay.toSec() < 0.002)
399  {
400  const auto time = params.find("TIME");
401  if (time == params.end())
402  {
403  scip2::logger::debug() << "II doesn't have timestamp" << std::endl;
404  return;
405  }
406  if (time->second.size() != 6 && time->second.size() != 4)
407  {
408  scip2::logger::debug() << "Timestamp in II is ill-formatted (" << time->second << ")" << std::endl;
409  return;
410  }
411  const uint32_t time_device =
412  time->second.size() == 6 ?
413  std::stoi(time->second, nullptr, 16) :
414  *(scip2::Decoder<4>(time->second).begin());
415 
416  const uint64_t walltime_device = walltime_.update(time_device);
417  if (detectDeviceTimeJump(time_read, walltime_device))
418  {
419  errorCountIncrement(status);
420  return;
421  }
422 
423  ros::Time time_at_device_timestamp;
425  time_read, walltime_device, estimated_communication_delay_, time_at_device_timestamp);
426 
427  const auto now = ros::Time::fromBoost(time_read);
428  if (last_sync_time_ == ros::Time(0))
429  last_sync_time_ = now;
430  const double dt = std::min((now - last_sync_time_).toSec(), 10.0);
431  last_sync_time_ = now;
432 
433  const double gain =
434  (time_at_device_timestamp - device_time_origin_.origin_).toSec() /
435  (time_at_device_timestamp - origin).toSec();
436  const double exp_lpf_alpha =
437  dt * (1.0 / 30.0); // 30 seconds exponential LPF
438  const double updated_gain =
439  (1.0 - exp_lpf_alpha) * device_time_origin_.gain_ + exp_lpf_alpha * gain;
440  device_time_origin_.gain_ = updated_gain;
442  ros::Duration(exp_lpf_alpha * (origin - device_time_origin_.origin_).toSec());
443 
445  << "on scan delay: " << std::setprecision(6) << std::fixed << delay
446  << ", device timestamp: " << walltime_device
447  << ", device time origin: " << origin
448  << ", gain: " << updated_gain << std::endl;
449  }
450  else
451  {
453  << "on scan delay (" << std::setprecision(6) << std::fixed << delay
454  << ") is larger than expected; skipping" << std::endl;
455  }
456 }
457 
459  const boost::posix_time::ptime& time_read,
460  const std::string& echo_back,
461  const std::string& status)
462 {
463  if (status != "00")
464  {
465  scip2::logger::error() << echo_back << " errored with " << status << std::endl;
466  errorCountIncrement(status);
467  return;
468  }
469 
470  scip2::logger::debug() << "Scan data stopped" << std::endl;
471 
473  {
475  retryTM();
476  }
477 }
478 
480  const boost::posix_time::ptime& time_read,
481  const std::string& echo_back,
482  const std::string& status)
483 {
484  if (status == "01")
485  {
486  scip2::logger::info() << "Sensor reboot in-progress" << std::endl;
487  scip_->sendCommand("RB"); // Sending it 2 times in 1 sec. is needed
488  return;
489  }
490  else if (status == "00")
491  {
492  scip2::logger::info() << "Sensor reboot succeeded" << std::endl;
493  device_->stop();
494  sleepRandom(1.0, 2.0);
495  ros::shutdown();
496  return;
497  }
499  << echo_back << " errored with " << status << std::endl
500  << "Failed to reboot. Please power-off the sensor." << std::endl;
501 }
502 
504  const boost::posix_time::ptime& time_read,
505  const std::string& echo_back,
506  const std::string& status)
507 {
508  if (status != "00")
509  {
511  << echo_back << " errored with " << status << std::endl
512  << "Failed to reset. Rebooting the sensor and exiting." << std::endl;
513  hardReset();
514  return;
515  }
516  scip2::logger::info() << "Sensor reset succeeded" << std::endl;
517  if (failed_)
518  {
519  scip2::logger::info() << "Restarting urg_stamped" << std::endl;
520  device_->stop();
521  sleepRandom(0.5, 1.0);
522  ros::shutdown();
523  return;
524  }
525  scip_->sendCommand("VV");
526  scip_->sendCommand("PP");
528  tm_try_count_ = 0;
529 }
530 
532 {
533  scip_->sendCommand("RS");
534  device_->startWatchdog(boost::posix_time::seconds(1));
535 }
536 
538 {
540  << "internal state on failure: "
541  << "delay_estim_state_=" << static_cast<int>(delay_estim_state_) << " "
542  << "tm_try_count_=" << tm_try_count_ << " "
543  << "error_count_.error=" << error_count_.error << " "
544  << "error_count_.abnormal_error=" << error_count_.abnormal_error << " "
545  << std::endl;
547  device_->stop();
548  ros::shutdown();
549 }
550 
552 {
553  scip_->sendCommand(
554  "II",
555  boost::bind(&UrgStampedNode::cbIISend, this, boost::arg<1>()));
556 }
557 
559 {
561  {
562  sendII();
563  }
566  &UrgStampedNode::timeSync, this, true);
567 }
568 
570 {
571  tm_try_count_ = 0;
572  timer_sync_.stop(); // Stop timer for sync using II command.
573  scip2::logger::debug() << "Starting communication delay estimation" << std::endl;
578  &UrgStampedNode::retryTM, this);
579  retryTM();
580 }
581 
583 {
584  switch (delay_estim_state_)
585  {
587  scip2::logger::debug() << "Stopping scan" << std::endl;
588  scip_->sendCommand("QT");
589  tm_try_count_++;
591  {
592  scip2::logger::error() << "Failed to enter time synchronization mode" << std::endl;
594  softReset();
595  }
596  break;
598  scip2::logger::debug() << "Checking sensor state" << std::endl;
599  sendII();
600  break;
602  scip2::logger::debug() << "Entering the time synchronization mode" << std::endl;
603  scip_->sendCommand("TM0");
604  break;
606  scip2::logger::warn() << "Timeout occured during the time synchronization" << std::endl;
607  scip_->sendCommand("TM2");
608  break;
609  default:
610  break;
611  }
612 }
613 
614 void UrgStampedNode::errorCountIncrement(const std::string& status)
615 {
617  {
618  // Already resetting or rebooting.
619  return;
620  }
621 
622  if (status == "00")
623  {
624  return;
625  }
626 
627  if (status == "0L")
628  {
631  {
632  failed_ = true;
635  << "Error count exceeded limit, rebooting the sensor and exiting."
636  << std::endl;
637  hardReset();
638  }
639  }
640  else
641  {
644  {
645  failed_ = true;
647  if (tm_success_)
648  {
650  << "Error count exceeded limit, resetting the sensor and exiting." << std::endl;
651  softReset();
652  }
653  else
654  {
656  << "Error count exceeded limit without successful time sync, "
657  "rebooting the sensor and exiting."
658  << std::endl;
659  hardReset();
660  }
661  }
662  }
663 }
664 
666 {
667  scip_->sendCommand("RS");
668 }
669 
671 {
672  scip2::logger::error() << "Rebooting the sensor" << std::endl;
673  scip_->sendCommand("RB");
674 }
675 
676 void UrgStampedNode::sleepRandom(const double min, const double max)
677 {
678  std::uniform_real_distribution<double> rnd(min, max);
680 }
681 
683  const boost::posix_time::ptime& time_response,
684  const uint64_t& device_timestamp)
685 {
686  ros::Time time_at_device_timestamp;
687  const ros::Time current_origin =
689  time_response, device_timestamp, estimated_communication_delay_, time_at_device_timestamp);
690 
693 
694  if (jumped)
695  {
697  << "Device time origin jumped\n"
698  "last origin: "
699  << std::setprecision(3) << std::fixed << device_time_origin_.origin_.toSec()
700  << ", current origin: " << current_origin.toSec()
701  << ", allowed_device_time_origin_diff: " << allowed_device_time_origin_diff_
702  << ", device_timestamp: " << device_timestamp << std::endl;
703  }
704  return jumped;
705 }
706 
708  : nh_("")
709  , pnh_("~")
710  , failed_(false)
712  , tm_iter_num_(5)
713  , tm_median_window_(35)
716  , last_sync_time_(0)
717  , timestamp_lpf_(20)
718  , timestamp_hpf_(20)
719  , timestamp_outlier_removal_(ros::Duration(0.001), ros::Duration())
720  , timestamp_moving_average_(5, ros::Duration())
721  , tm_success_(false)
722 {
723  std::random_device rd;
724  random_engine_.seed(rd());
725 
726  std::string ip;
727  int port;
728  double sync_interval_min;
729  double sync_interval_max;
730  double delay_estim_interval;
731 
732  pnh_.param("ip_address", ip, std::string("192.168.0.10"));
733  pnh_.param("ip_port", port, 10940);
734  pnh_.param("frame_id", msg_base_.header.frame_id, std::string("laser"));
735  pnh_.param("publish_intensity", publish_intensity_, true);
736  pnh_.param("sync_interval_min", sync_interval_min, 1.0);
737  pnh_.param("sync_interval_max", sync_interval_max, 1.5);
738  sync_interval_ = std::uniform_real_distribution<double>(sync_interval_min, sync_interval_max);
739  pnh_.param("delay_estim_interval", delay_estim_interval, 20.0);
740  pnh_.param("error_limit", error_count_max_, 4);
741  pnh_.param("allowed_device_time_origin_diff", allowed_device_time_origin_diff_, 1.0);
742 
743  double tm_interval, tm_timeout;
744  pnh_.param("tm_interval", tm_interval, 0.06);
745  tm_command_interval_ = ros::Duration(tm_interval);
746  pnh_.param("tm_timeout", tm_timeout, 10.0);
747  tm_try_max_ = static_cast<int>(tm_timeout / tm_interval);
748 
749  urg_stamped::setROSLogger(msg_base_.header.frame_id + ": ");
750 
751  bool debug;
752  pnh_.param("debug", debug, false);
753  if (debug)
754  {
755  // Enable debug level log at the beginning of the node to show initialization related logs.
757  {
759  }
760  }
761 
762  pub_scan_ = nh_.advertise<sensor_msgs::LaserScan>("scan", 10);
763 
764  device_.reset(new scip2::ConnectionTcp(ip, port));
765  device_->registerCloseCallback(
766  boost::bind(&UrgStampedNode::cbClose, this));
767  device_->registerConnectCallback(
768  boost::bind(&UrgStampedNode::cbConnect, this));
769 
770  scip_.reset(new scip2::Protocol(device_));
771  scip_->registerCallback<scip2::ResponsePP>(
772  boost::bind(&UrgStampedNode::cbPP, this,
773  boost::arg<1>(),
774  boost::arg<2>(),
775  boost::arg<3>(),
776  boost::arg<4>()));
777  scip_->registerCallback<scip2::ResponseVV>(
778  boost::bind(&UrgStampedNode::cbVV, this,
779  boost::arg<1>(),
780  boost::arg<2>(),
781  boost::arg<3>(),
782  boost::arg<4>()));
783  scip_->registerCallback<scip2::ResponseII>(
784  boost::bind(&UrgStampedNode::cbII, this,
785  boost::arg<1>(),
786  boost::arg<2>(),
787  boost::arg<3>(),
788  boost::arg<4>()));
789  scip_->registerCallback<scip2::ResponseMD>(
790  boost::bind(&UrgStampedNode::cbM, this,
791  boost::arg<1>(),
792  boost::arg<2>(),
793  boost::arg<3>(),
794  boost::arg<4>(),
795  false));
796  scip_->registerCallback<scip2::ResponseME>(
797  boost::bind(&UrgStampedNode::cbM, this,
798  boost::arg<1>(),
799  boost::arg<2>(),
800  boost::arg<3>(),
801  boost::arg<4>(),
802  true));
803  scip_->registerCallback<scip2::ResponseTM>(
804  boost::bind(&UrgStampedNode::cbTM, this,
805  boost::arg<1>(),
806  boost::arg<2>(),
807  boost::arg<3>(),
808  boost::arg<4>()));
809  scip_->registerCallback<scip2::ResponseQT>(
810  boost::bind(&UrgStampedNode::cbQT, this,
811  boost::arg<1>(),
812  boost::arg<2>(),
813  boost::arg<3>()));
814  scip_->registerCallback<scip2::ResponseRB>(
815  boost::bind(&UrgStampedNode::cbRB, this,
816  boost::arg<1>(),
817  boost::arg<2>(),
818  boost::arg<3>()));
819  scip_->registerCallback<scip2::ResponseRS>(
820  boost::bind(&UrgStampedNode::cbRS, this,
821  boost::arg<1>(),
822  boost::arg<2>(),
823  boost::arg<3>()));
824 
825  if (delay_estim_interval > 0.0)
826  {
828  ros::Duration(delay_estim_interval), &UrgStampedNode::delayEstimation, this);
829  }
830 }
831 
833 {
834  boost::thread thread(
835  boost::bind(&scip2::Connection::spin, device_.get()));
836  ros::spin();
837  timer_sync_.stop();
839  scip_->sendCommand("QT");
840  device_->stop();
841  thread.join();
842 }
843 } // namespace urg_stamped
ros::Time update(const ros::Time &stamp)
void cbTM(const boost::posix_time::ptime &time_read, const std::string &echo_back, const std::string &status, const scip2::Timestamp &time_device)
scip2::Protocol::Ptr scip_
Definition: urg_stamped.h:60
scip2::Walltime< 24 > walltime_
Definition: urg_stamped.h:90
ROSCONSOLE_DECL void notifyLoggerLevelsChanged()
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:46
std::vector< int32_t > ranges_
Definition: stream.h:36
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
bool detectDeviceTimeJump(const boost::posix_time::ptime &time_response, const uint64_t &device_timestamp)
void cbQT(const boost::posix_time::ptime &time_read, const std::string &echo_back, const std::string &status)
void stop()
sensor_msgs::LaserScan msg_base_
Definition: urg_stamped.h:55
void cbTMSend(const boost::posix_time::ptime &time_send)
std::ostream & info()
Definition: logger.cpp:97
void cbRS(const boost::posix_time::ptime &time_read, const std::string &echo_back, const std::string &status)
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)
DelayEstimState delay_estim_state_
Definition: urg_stamped.h:74
void cbRB(const boost::posix_time::ptime &time_read, const std::string &echo_back, const std::string &status)
void setInterval(const ros::Duration &interval)
uint32_t timestamp_
Definition: stream.h:35
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)
std::uniform_real_distribution< double > sync_interval_
Definition: urg_stamped.h:93
ResponseErrorCount error_count_
Definition: urg_stamped.h:112
void retryTM(const ros::TimerEvent &event=ros::TimerEvent())
std::default_random_engine random_engine_
Definition: urg_stamped.h:92
std::list< ros::Duration > communication_delays_
Definition: urg_stamped.h:76
double communication_delay_filter_alpha_
Definition: urg_stamped.h:82
std::list< ros::Time > device_time_origins_
Definition: urg_stamped.h:77
ros::Duration tm_command_interval_
Definition: urg_stamped.h:116
bool param(const std::string &param_name, T &param_val, const T &default_val) const
void publish(const boost::shared_ptr< M > &message) const
uint64_t update(const uint32_t &time_device)
Definition: walltime.h:35
boost::posix_time::ptime time_ii_request
Definition: urg_stamped.h:84
void setROSLogger(const std::string &prefix)
Definition: ros_logger.cpp:113
FirstOrderHPF< double > timestamp_hpf_
Definition: urg_stamped.h:98
boost::posix_time::ptime time_tm_request
Definition: urg_stamped.h:75
std::ostream & debug()
Definition: logger.cpp:93
ros::Duration estimated_communication_delay_
Definition: urg_stamped.h:78
ros::Time estimateOriginByAverage(const boost::posix_time::ptime &time_request, const boost::posix_time::ptime &time_response, const uint64_t &device_timestamp)
ros::Time update(const ros::Time &stamp)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ROSCPP_DECL void spin()
bool detectTimeJump(const ros::Time &last_device_time_origin, const ros::Time &current_device_time_origin, const double allowed_device_time_origin_diff)
std::vector< int32_t > intensities_
Definition: stream.h:37
void timeSync(const ros::TimerEvent &event=ros::TimerEvent())
std::ostream & warn()
Definition: logger.cpp:101
uint32_t timestamp_
Definition: time_sync.h:33
std::string last_measurement_state_
Definition: urg_stamped.h:117
void delayEstimation(const ros::TimerEvent &event=ros::TimerEvent())
device_time_origin::DriftedTime device_time_origin_
Definition: urg_stamped.h:87
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)
ros::Time estimateOrigin(const boost::posix_time::ptime &time_response, const uint64_t &device_timestamp, const ros::Duration &communication_delay, ros::Time &time_at_device_timestamp)
Duration & fromNSec(int64_t t)
FirstOrderLPF< double > timestamp_lpf_
Definition: urg_stamped.h:97
static Time fromBoost(const boost::posix_time::ptime &t)
ROSCPP_DECL void shutdown()
void sleepRandom(const double min, const double max)
ROSCONSOLE_DECL bool set_logger_level(const std::string &name, levels::Level level)
void cbIISend(const boost::posix_time::ptime &time_send)
bool sleep() const
void errorCountIncrement(const std::string &status="")
virtual void spin()=0
TimestampMovingAverage timestamp_moving_average_
Definition: urg_stamped.h:100
ros::Publisher pub_scan_
Definition: urg_stamped.h:50
void setInterval(const ros::Duration &interval)
TimestampOutlierRemover timestamp_outlier_removal_
Definition: urg_stamped.h:99
#define ROSCONSOLE_DEFAULT_NAME
std::ostream & error()
Definition: logger.cpp:105
scip2::Connection::Ptr device_
Definition: urg_stamped.h:59


urg_stamped
Author(s): Atsushi Watanabe
autogenerated on Mon Jul 3 2023 02:11:32