clock_estimator_uust1.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2024 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 <algorithm>
18 #include <cmath>
19 #include <cstdint>
20 #include <vector>
21 
22 #include <ros/time.h>
23 
25 #include <scip2/logger.h>
26 
27 namespace urg_stamped
28 {
29 namespace device_state_estimator
30 {
31 
33 {
34  sync_samples_.clear();
36 }
37 
39  const ros::Time& t_req, const ros::Time& t_res, const uint64_t device_wall_stamp)
40 {
41  const SyncSampleUUST1 s(t_req, t_res, device_wall_stamp);
43  {
45  return;
46  }
47  sync_samples_.push_back(s);
48  if (comm_delay_.min_.isZero() || comm_delay_.min_ > s.delay_)
49  {
50  comm_delay_.min_ = s.delay_;
51  }
52 }
53 
55 {
56  const size_t n = sync_samples_.size();
58  {
59  return true;
60  }
61  if (n < MIN_SYNC_SAMPLES)
62  {
63  return false;
64  }
65  if (n >= MAX_SYNC_SAMPLES)
66  {
67  return true;
68  }
69  const OriginFracPart overflow_range = originFracOverflow();
70  return overflow_range.t_max_ > overflow_range.t_min_;
71 }
72 
74 {
76  {
78  << "Communication delay is too large. Maybe unsupported sensor model"
79  << std::endl;
80  return false;
81  }
82  const OriginFracPart overflow_range = originFracOverflow();
83  if (!overflow_range)
84  {
86  << "Failed to find origin fractional part overflow: "
87  << overflow_range.t_min_ << ", " << overflow_range.t_max_
88  << ", samples=" << sync_samples_.size()
89  << std::endl;
90  return false;
91  }
92  const auto min_delay = findMinDelay(overflow_range);
93  if (min_delay == sync_samples_.cend())
94  {
95  scip2::logger::info() << "Failed to find minimal delay sample" << std::endl;
96  return false;
97  }
99 
101  << "delay: " << min_delay->delay_
102  << ", delay sigma: " << comm_delay_.sigma_
103  << ", device timestamp: " << min_delay->device_wall_stamp_
104  << std::endl;
105 
106  const ClockSample clock =
107  {
108  .t_estim_ = min_delay->t_process_,
109  .stamp_ = min_delay->device_wall_stamp_,
110  .origin_ = overflow_range.compensate(min_delay->t_origin_),
111  };
112  return pushClockSample(clock);
113 }
114 
115 std::vector<ClockEstimatorUUST1::SyncSampleUUST1>::const_iterator
117 {
118  if (sync_samples_.size() == 0)
119  {
120  return sync_samples_.cend();
121  }
122  auto it_min_delay = sync_samples_.cbegin();
123  for (auto it = sync_samples_.cbegin() + 1; it != sync_samples_.cend(); it++)
124  {
125  if (overflow_range.isOnOverflow(it->t_process_))
126  {
127  continue;
128  }
129  if (it->delay_ < it_min_delay->delay_)
130  {
131  it_min_delay = it;
132  }
133  }
134  return it_min_delay;
135 }
136 
138 {
139  if (sync_samples_.size() == 0)
140  {
141  return OriginFracPart();
142  }
143 
144  const ros::Duration max_delay = comm_delay_.min_ + delaySigma();
145  int valid_samples = 0;
146 
147  auto it_min_origin = sync_samples_.begin();
148  auto it_max_origin = sync_samples_.begin();
149  for (auto it = sync_samples_.begin() + 1; it != sync_samples_.end(); it++)
150  {
151  if (it->delay_ > max_delay)
152  {
153  continue;
154  }
155  valid_samples++;
156  if (it->t_origin_ < it_min_origin->t_origin_)
157  {
158  it_min_origin = it;
159  }
160  if (it->t_origin_ > it_max_origin->t_origin_)
161  {
162  it_max_origin = it;
163  }
164  }
165 
166  if (valid_samples < MIN_SYNC_SAMPLES ||
167  it_min_origin->delay_ > max_delay ||
168  it_max_origin->delay_ > max_delay)
169  {
170  return OriginFracPart();
171  }
172 
173  double t_min = std::fmod(it_min_origin->t_process_.toSec(), DEVICE_TIMESTAMP_RESOLUTION);
174  double t_max = std::fmod(it_max_origin->t_process_.toSec(), DEVICE_TIMESTAMP_RESOLUTION);
175  if (t_min > t_max + DEVICE_TIMESTAMP_RESOLUTION / 2)
176  {
178  }
179  else if (t_max > t_min + DEVICE_TIMESTAMP_RESOLUTION / 2)
180  {
182  }
183  if (std::abs(t_max - t_min) > DEVICE_TIMESTAMP_RESOLUTION / 4)
184  {
185  return OriginFracPart(t_min, t_max, false);
186  }
187  return OriginFracPart(t_min, t_max);
188 }
189 
191 {
192  if (sync_samples_.size() == 0)
193  {
194  return ros::Duration();
195  }
196  double sum = 0;
197  for (const auto& s : sync_samples_)
198  {
199  const double delay_diff = (s.delay_ - comm_delay_.min_).toSec();
200  sum += delay_diff * delay_diff;
201  }
202  return ros::Duration(std::sqrt(sum / sync_samples_.size()));
203 }
204 
205 } // namespace device_state_estimator
206 } // namespace urg_stamped
207 
urg_stamped::device_state_estimator::ClockEstimatorUUST1::cnt_dropped_samples_
int cnt_dropped_samples_
Definition: device_state_estimator.h:309
scip2::logger::info
std::ostream & info()
Definition: logger.cpp:97
urg_stamped::device_state_estimator::ClockEstimatorUUST1::MAX_SYNC_SAMPLES
static constexpr int MAX_SYNC_SAMPLES
Definition: device_state_estimator.h:293
logger.h
urg_stamped::device_state_estimator::ClockEstimator::comm_delay_
CommDelay comm_delay_
Definition: device_state_estimator.h:224
s
XmlRpcServer s
urg_stamped::device_state_estimator::ClockSample
Definition: device_state_estimator.h:49
time.h
urg_stamped::device_state_estimator::OriginFracPart
Definition: device_state_estimator.h:108
urg_stamped::device_state_estimator::ClockEstimatorUUST1::delaySigma
ros::Duration delaySigma() const
Definition: clock_estimator_uust1.cpp:190
urg_stamped::device_state_estimator::ClockEstimatorUUST1::sync_samples_
std::vector< SyncSampleUUST1 > sync_samples_
Definition: device_state_estimator.h:308
urg_stamped::device_state_estimator::ClockEstimatorUUST1::finishSync
bool finishSync() override
Definition: clock_estimator_uust1.cpp:73
urg_stamped::device_state_estimator::CommDelay::min_
ros::Duration min_
Definition: device_state_estimator.h:45
urg_stamped::device_state_estimator::ClockEstimatorUUST1::findMinDelay
std::vector< SyncSampleUUST1 >::const_iterator findMinDelay(const OriginFracPart &overflow_range) const
Definition: clock_estimator_uust1.cpp:116
urg_stamped::device_state_estimator::ClockEstimatorUUST1::originFracOverflow
OriginFracPart originFracOverflow() const
Definition: clock_estimator_uust1.cpp:137
urg_stamped::device_state_estimator::ClockEstimatorUUST1::pushSyncSample
void pushSyncSample(const ros::Time &t_req, const ros::Time &t_res, const uint64_t device_wall_stamp) override
Definition: clock_estimator_uust1.cpp:38
urg_stamped::device_state_estimator::OriginFracPart::compensate
ros::Time compensate(const ros::Time &t) const
Definition: device_state_estimator.cpp:54
urg_stamped::device_state_estimator::ClockEstimatorUUST1::MAX_DROPPED_SAMPLES
static constexpr int MAX_DROPPED_SAMPLES
Definition: device_state_estimator.h:294
urg_stamped::device_state_estimator::ClockSample::t_estim_
ros::Time t_estim_
Definition: device_state_estimator.h:52
urg_stamped::device_state_estimator::OriginFracPart::t_min_
const double t_min_
Definition: device_state_estimator.h:112
urg_stamped::device_state_estimator::ClockEstimator::pushClockSample
bool pushClockSample(const ClockSample &clock)
Definition: device_state_estimator.cpp:65
scip2::logger::debug
std::ostream & debug()
Definition: logger.cpp:93
urg_stamped::device_state_estimator::OriginFracPart::t_max_
const double t_max_
Definition: device_state_estimator.h:113
urg_stamped::device_state_estimator::OriginFracPart::isOnOverflow
bool isOnOverflow(const ros::Time &t) const
Definition: device_state_estimator.cpp:46
urg_stamped::device_state_estimator::ClockEstimatorUUST1::hasEnoughSyncSamples
bool hasEnoughSyncSamples() const override
Definition: clock_estimator_uust1.cpp:54
ros::Time
urg_stamped::device_state_estimator::ClockEstimatorUUST1::SyncSampleUUST1
Definition: device_state_estimator.h:296
urg_stamped::device_state_estimator::ClockEstimatorUUST1::startSync
void startSync() override
Definition: clock_estimator_uust1.cpp:32
device_state_estimator.h
urg_stamped::device_state_estimator::CommDelay::sigma_
ros::Duration sigma_
Definition: device_state_estimator.h:46
urg_stamped
Definition: device_state_estimator.h:35
scip2::logger::error
std::ostream & error()
Definition: logger.cpp:105
urg_stamped::device_state_estimator::ClockEstimatorUUST1::MIN_SYNC_SAMPLES
static constexpr int MIN_SYNC_SAMPLES
Definition: device_state_estimator.h:292
ros::Duration
DurationBase< Duration >::isZero
bool isZero() const
urg_stamped::device_state_estimator::DEVICE_TIMESTAMP_RESOLUTION
static constexpr double DEVICE_TIMESTAMP_RESOLUTION
Definition: device_state_estimator.h:40


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