19 #include <sensor_msgs/LaserScan.h> 21 #include <boost/bind/bind.hpp> 22 #include <boost/format.hpp> 23 #include <boost/thread.hpp> 46 const boost::posix_time::ptime& time_read,
47 const std::string& echo_back,
48 const std::string& status,
50 const bool has_intensity)
56 ROS_ERROR(
"%s errored with %s", echo_back.c_str(), status.c_str());
70 const auto estimated_timestamp_lf =
76 t0_ = estimated_timestamp_lf;
78 const auto receive_time =
94 ROS_DEBUG(
"Size of the received scan data is wrong (expected: %d, received: %lu); refreshing",
97 (has_intensity ?
"ME" :
"MD") +
103 msg.ranges.reserve(scan.
ranges_.size());
105 msg.ranges.push_back(r * 1e-3);
110 msg.intensities.push_back(r);
122 const boost::posix_time::ptime& time_read,
123 const std::string& echo_back,
124 const std::string& status,
129 ROS_ERROR(
"%s errored with %s", echo_back.c_str(), status.c_str());
135 "Failed to enter the time synchronization mode, " 136 "even after receiving successful QT command response. " 137 "QT command may be ignored by the sensor firmware");
144 switch (echo_back[2])
148 ROS_DEBUG(
"Entered the time synchronization mode");
181 sort(delays.begin(), delays.end());
182 sort(origins.begin(), origins.end());
196 ROS_DEBUG(
"delay: %0.6f, device timestamp: %ld, device time origin: %0.6f",
200 scip_->sendCommand(
"TM2");
222 ROS_DEBUG(
"Leaving the time synchronization mode");
229 const boost::posix_time::ptime& time_read,
230 const std::string& echo_back,
231 const std::string& status,
232 const std::map<std::string, std::string>& params)
236 ROS_ERROR(
"%s errored with %s", echo_back.c_str(), status.c_str());
241 const auto amin = params.find(
"AMIN");
242 const auto amax = params.find(
"AMAX");
243 const auto dmin = params.find(
"DMIN");
244 const auto dmax = params.find(
"DMAX");
245 const auto ares = params.find(
"ARES");
246 const auto afrt = params.find(
"AFRT");
247 const auto scan = params.find(
"SCAN");
248 if (amin == params.end() || amax == params.end() ||
249 dmin == params.end() || dmax == params.end() ||
250 ares == params.end() || afrt == params.end() ||
251 scan == params.end())
253 ROS_ERROR(
"PP doesn't have required parameters");
258 msg_base_.scan_time = 60.0 / std::stoi(scan->second);
259 msg_base_.angle_increment = 2.0 * M_PI / std::stoi(ares->second);
261 msg_base_.range_min = std::stoi(dmin->second) * 1e-3;
262 msg_base_.range_max = std::stoi(dmax->second) * 1e-3;
264 (std::stoi(amin->second) - std::stoi(afrt->second)) *
msg_base_.angle_increment;
266 (std::stoi(amax->second) - std::stoi(afrt->second)) *
msg_base_.angle_increment;
274 const boost::posix_time::ptime& time_read,
275 const std::string& echo_back,
276 const std::string& status,
277 const std::map<std::string, std::string>& params)
281 ROS_ERROR(
"%s errored with %s", echo_back.c_str(), status.c_str());
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)
300 ROS_ERROR(
"%s errored with %s", echo_back.c_str(), status.c_str());
309 if (delay.toSec() < 0.002)
311 const auto time = params.find(
"TIME");
312 if (time == params.end())
317 if (time->second.size() != 6 && time->second.size() != 4)
319 ROS_DEBUG(
"Timestamp in II is ill-formatted (%s)", time->second.c_str());
322 const uint32_t time_device =
323 time->second.size() == 6 ?
324 std::stoi(time->second,
nullptr, 16) :
346 (time_at_device_timestamp - origin).toSec();
347 const double exp_lpf_alpha =
349 const double updated_gain =
355 ROS_DEBUG(
"on scan delay: %0.6f, device timestamp: %ld, device time origin: %0.6f, gain: %0.6f",
363 ROS_DEBUG(
"on scan delay (%0.6f) is larger than expected; skipping",
369 const boost::posix_time::ptime& time_read,
370 const std::string& echo_back,
371 const std::string& status)
375 ROS_ERROR(
"%s errored with %s", echo_back.c_str(), status.c_str());
390 const boost::posix_time::ptime& time_read,
391 const std::string& echo_back,
392 const std::string& status)
394 if (status !=
"00" && status !=
"01")
396 ROS_ERROR(
"%s errored with %s", echo_back.c_str(), status.c_str());
397 ROS_ERROR(
"Failed to reboot. Please power-off the sensor.");
402 const boost::posix_time::ptime& time_read,
403 const std::string& echo_back,
404 const std::string& status)
408 ROS_ERROR(
"%s errored with %s", echo_back.c_str(), status.c_str());
409 ROS_ERROR(
"Failed to reset. Rebooting the sensor and exiting.");
417 scip_->sendCommand(
"PP");
423 scip_->sendCommand(
"RS");
424 device_->startWatchdog(boost::posix_time::seconds(1));
440 ROS_DEBUG(
"Starting communication delay estimation");
455 scip_->sendCommand(
"QT");
458 ROS_DEBUG(
"Entering the time synchronization mode");
462 scip_->sendCommand(
"QT");
463 scip_->sendCommand(
"TM0");
466 ROS_WARN(
"Timeout occured during the time synchronization");
467 scip_->sendCommand(
"TM2");
484 ROS_ERROR(
"Error count exceeded limit, rebooting the sensor and exiting.");
493 ROS_ERROR(
"Error count exceeded limit, resetting the sensor and exiting.");
501 scip_->sendCommand(
"RS");
508 scip_->sendCommand(
"RB");
509 scip_->sendCommand(
"RB");
515 const boost::posix_time::ptime& time_response,
516 const uint64_t& device_timestamp)
529 "Device time origin jumped.\n" 530 "last origin: %0.3f, current origin: %0.3f, " 531 "allowed_device_time_origin_diff: %0.3f, device_timestamp: %ld",
555 double sync_interval_min;
556 double sync_interval_max;
557 double delay_estim_interval;
559 pnh_.
param(
"ip_address", ip, std::string(
"192.168.0.10"));
563 pnh_.
param(
"sync_interval_min", sync_interval_min, 1.0);
564 pnh_.
param(
"sync_interval_max", sync_interval_max, 1.5);
565 sync_interval_ = std::uniform_real_distribution<double>(sync_interval_min, sync_interval_max);
566 pnh_.
param(
"delay_estim_interval", delay_estim_interval, 20.0);
585 device_->registerConnectCallback(
643 if (delay_estim_interval > 0.0)
652 boost::thread thread(
657 scip_->sendCommand(
"QT");
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_
scip2::Walltime< 24 > walltime_
ROSCONSOLE_DECL void notifyLoggerLevelsChanged()
void publish(const boost::shared_ptr< M > &message) const
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)
std::vector< int32_t > ranges_
double allowed_device_time_origin_diff_
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)
FLT update(const FLT &in)
sensor_msgs::LaserScan msg_base_
void cbTMSend(const boost::posix_time::ptime &time_send)
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 > ¶ms)
DelayEstimState delay_estim_state_
void cbRB(const boost::posix_time::ptime &time_read, const std::string &echo_back, const std::string &status)
void setInterval(const ros::Duration &interval)
ros::Time last_sync_time_
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 > ¶ms)
std::uniform_real_distribution< double > sync_interval_
ResponseErrorCount error_count_
void retryTM(const ros::TimerEvent &event=ros::TimerEvent())
std::default_random_engine random_engine_
std::list< ros::Duration > communication_delays_
double communication_delay_filter_alpha_
std::list< ros::Time > device_time_origins_
uint64_t update(const uint32_t &time_device)
boost::posix_time::ptime time_ii_request
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
FirstOrderHPF< double > timestamp_hpf_
ros::Timer timer_retry_tm_
boost::posix_time::ptime time_tm_request
ros::Duration estimated_communication_delay_
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
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)
bool detectTimeJump(const ros::Time &last_device_time_origin, const ros::Time ¤t_device_time_origin, const double allowed_device_time_origin_diff)
std::vector< int32_t > intensities_
ros::Timer timer_delay_estim_
void timeSync(const ros::TimerEvent &event=ros::TimerEvent())
bool estimated_communication_delay_init_
void delayEstimation(const ros::TimerEvent &event=ros::TimerEvent())
device_time_origin::DriftedTime device_time_origin_
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 > ¶ms)
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_
static Time fromBoost(const boost::posix_time::ptime &t)
ROSCPP_DECL void shutdown()
ROSCONSOLE_DECL bool set_logger_level(const std::string &name, levels::Level level)
void cbIISend(const boost::posix_time::ptime &time_send)
TimestampMovingAverage timestamp_moving_average_
void setInterval(const ros::Duration &interval)
TimestampOutlierRemover timestamp_outlier_removal_
#define ROSCONSOLE_DEFAULT_NAME
void errorCountIncrement(const std::string &status)
scip2::Connection::Ptr device_