scan_estimator_ust.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 <cstdint>
19 #include <memory>
20 #include <utility>
21 #include <vector>
22 
23 #include <ros/time.h>
24 
26 #include <scip2/logger.h>
27 
28 namespace urg_stamped
29 {
30 namespace device_state_estimator
31 {
32 
33 std::pair<ros::Time, bool> ScanEstimatorUST::pushScanSample(const ros::Time& t_recv, const uint64_t device_wall_stamp)
34 {
35  const ClockState clock = clock_estim_->getClockState();
36  const ros::Time t_stamp = clock.stampToTime(device_wall_stamp);
37  if (!clock.initialized_)
38  {
39  return std::pair<ros::Time, bool>(t_stamp, true);
40  }
41 
42  stamps_.push_back(device_wall_stamp);
43  if (stamps_.size() < STAMP_SAMPLES)
44  {
45  return std::pair<ros::Time, bool>(t_stamp, true);
46  }
47  stamps_.pop_front();
48 
49  const int64_t interval = device_wall_stamp - stamps_[stamps_.size() - 2];
50 
51  std::vector<int64_t> intervals;
52  for (size_t i = 1; i < stamps_.size(); ++i)
53  {
54  const int64_t interval = stamps_[i] - stamps_[i - 1];
55  intervals.push_back(interval);
56  }
57  std::sort(intervals.begin(), intervals.end());
58  primary_interval_ = intervals[intervals.size() / 2];
59 
60  const int64_t interval_diff = interval - primary_interval_;
61  if (-1 <= interval_diff && interval_diff <= 1)
62  {
63  scans_.emplace_front(device_wall_stamp, interval);
64  if (scans_.size() >= MAX_INTERVAL_SAMPLES)
65  {
66  scans_.pop_back();
67  }
68 
69  // Find cycle of timestamp increment
70  auto it = scans_.begin();
71  auto it_change0 = scans_.end();
72  auto it_change1 = scans_.end();
73  for (; it != scans_.end(); it++)
74  {
75  if (it->interval_ != primary_interval_)
76  {
77  it_change0 = it;
78  break;
79  }
80  }
81  if (it_change0 != scans_.end())
82  {
83  auto it_prev = it;
84  size_t num_samples = 0;
85  for (it++; it != scans_.end(); it++)
86  {
87  num_samples++;
88  if (it->interval_ != primary_interval_)
89  {
90  it_change1 = it_prev;
91  if (num_samples >= MIN_INTERVAL_SAMPLES)
92  {
93  break;
94  }
95  }
96  it_prev = it;
97  }
98  }
99  if (it_change1 != scans_.end())
100  {
101  // Calculate scan interval
102  if (it_change0 != scans_.end() && it_change1 != scans_.end())
103  {
104  const int64_t stamp_diff = it_change0->stamp_ - it_change1->stamp_;
105  const double ideal_scan_interval_cnt =
107  const int num_scans = std::lround(static_cast<double>(stamp_diff) / ideal_scan_interval_cnt);
108  const ros::Time new_origin = clock.stampToTime(it_change0->stamp_);
109  if (new_origin != scan_.origin_)
110  {
111  scan_.origin_ = clock.stampToTime(it_change0->stamp_);
112  scan_.interval_ = ros::Duration(stamp_diff * DEVICE_TIMESTAMP_RESOLUTION / (clock.gain_ * num_scans));
114  << "scan_origin: " << scan_.origin_ << " interval: " << scan_.interval_ << std::endl;
115  }
116  }
117  }
118  else
119  {
120  if (scan_.origin_.isValid() && scan_.origin_ + ros::Duration(30) < t_recv)
121  {
122  scan_.origin_ = t_stamp;
123  scan_.interval_ = ideal_scan_interval_ * (1.0 / clock.gain_);
125  << "no-increment scan_origin: " << scan_.origin_ << " interval: " << scan_.interval_ << std::endl;
126  }
127  }
128  }
129 
130  if (scan_.origin_.isZero())
131  {
132  return std::pair<ros::Time, bool>(t_stamp, true);
133  }
134 
135  const ros::Time t_estimated = scan_.fit(t_stamp);
136  const ros::Duration t_comp = t_estimated - t_stamp;
137  const bool valid =
140 
141  return std::pair<ros::Time, bool>(t_estimated, valid);
142 }
143 
144 } // namespace device_state_estimator
145 } // namespace urg_stamped
urg_stamped::device_state_estimator::ScanState::interval_
ros::Duration interval_
Definition: device_state_estimator.h:174
urg_stamped::device_state_estimator::ScanEstimatorUST::STAMP_SAMPLES
static constexpr size_t STAMP_SAMPLES
Definition: device_state_estimator.h:411
logger.h
urg_stamped::device_state_estimator::ScanEstimatorUST::MAX_INTERVAL_SAMPLES
static constexpr size_t MAX_INTERVAL_SAMPLES
Definition: device_state_estimator.h:412
time.h
urg_stamped::device_state_estimator::ScanEstimator::scan_
ScanState scan_
Definition: device_state_estimator.h:251
urg_stamped::device_state_estimator::ClockState::gain_
double gain_
Definition: device_state_estimator.h:61
urg_stamped::device_state_estimator::ScanEstimatorUST::primary_interval_
int64_t primary_interval_
Definition: device_state_estimator.h:416
urg_stamped::device_state_estimator::ScanState::fit
ros::Time fit(const ros::Time &t) const
Definition: device_state_estimator.cpp:38
ros::Time::isValid
static bool isValid()
urg_stamped::device_state_estimator::ScanEstimator::clock_estim_
ClockEstimator::Ptr clock_estim_
Definition: device_state_estimator.h:250
TimeBase< Time, Duration >::isZero
bool isZero() const
urg_stamped::device_state_estimator::ScanEstimatorUST::stamps_
std::deque< uint64_t > stamps_
Definition: device_state_estimator.h:414
urg_stamped::device_state_estimator::ScanEstimator::ideal_scan_interval_
ros::Duration ideal_scan_interval_
Definition: device_state_estimator.h:252
urg_stamped::device_state_estimator::ScanEstimatorUST::scans_
std::deque< ScanSampleUST > scans_
Definition: device_state_estimator.h:415
scip2::logger::debug
std::ostream & debug()
Definition: logger.cpp:93
ros::Time
device_state_estimator.h
urg_stamped::device_state_estimator::ScanEstimatorUST::MIN_INTERVAL_SAMPLES
static constexpr size_t MIN_INTERVAL_SAMPLES
Definition: device_state_estimator.h:413
urg_stamped::device_state_estimator::ScanEstimatorUST::pushScanSample
std::pair< ros::Time, bool > pushScanSample(const ros::Time &t_recv, const uint64_t device_wall_stamp) final
Definition: scan_estimator_ust.cpp:33
DurationBase< Duration >::toSec
double toSec() const
urg_stamped::device_state_estimator::ClockState::initialized_
bool initialized_
Definition: device_state_estimator.h:63
urg_stamped
Definition: device_state_estimator.h:35
urg_stamped::device_state_estimator::ScanState::origin_
ros::Time origin_
Definition: device_state_estimator.h:173
ros::Duration
urg_stamped::device_state_estimator::ClockState
Definition: device_state_estimator.h:57
urg_stamped::device_state_estimator::ClockState::stampToTime
ros::Time stampToTime(const uint64_t stamp) const
Definition: device_state_estimator.cpp:32
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