map_by_time.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017 The Cartographer 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 #ifndef CARTOGRAPHER_SENSOR_MAP_BY_TIME_H_
18 #define CARTOGRAPHER_SENSOR_MAP_BY_TIME_H_
19 
20 #include <algorithm>
21 #include <iterator>
22 #include <map>
23 #include <memory>
24 #include <vector>
25 
29 #include "glog/logging.h"
30 
31 namespace cartographer {
32 namespace sensor {
33 
34 // 'DataType' must contain a 'time' member of type common::Time.
35 template <typename DataType>
36 class MapByTime {
37  public:
38  // Appends data to a 'trajectory_id', creating trajectories as needed.
39  void Append(const int trajectory_id, const DataType& data) {
40  CHECK_GE(trajectory_id, 0);
41  auto& trajectory = data_[trajectory_id];
42  if (!trajectory.empty()) {
43  CHECK_GT(data.time, std::prev(trajectory.end())->first);
44  }
45  trajectory.emplace(data.time, data);
46  }
47 
48  // Removes data no longer needed once 'node_id' gets removed from 'nodes'.
49  // 'NodeType' must contain a 'time' member of type common::Time.
50  template <typename NodeType>
52  const mapping::NodeId& node_id) {
53  const int trajectory_id = node_id.trajectory_id;
54  CHECK_GE(trajectory_id, 0);
55  if (data_.count(trajectory_id) == 0) {
56  return;
57  }
58 
59  // Data only important between 'gap_start' and 'gap_end' is no longer
60  // needed. We retain the first and last data of the gap so that
61  // interpolation with the adjacent data outside the gap is still possible.
62  const auto node_it = nodes.find(node_id);
63  CHECK(node_it != nodes.end());
64  const common::Time gap_start =
65  node_it != nodes.BeginOfTrajectory(trajectory_id)
66  ? std::prev(node_it)->data.time
67  : common::Time::min();
68  const auto next_it = std::next(node_it);
69  const common::Time gap_end = next_it != nodes.EndOfTrajectory(trajectory_id)
70  ? next_it->data.time
71  : common::Time::max();
72  CHECK_LT(gap_start, gap_end);
73 
74  auto& trajectory = data_.at(trajectory_id);
75  auto data_it = trajectory.lower_bound(gap_start);
76  auto data_end = trajectory.upper_bound(gap_end);
77  if (data_it == data_end) {
78  return;
79  }
80  if (gap_end != common::Time::max()) {
81  // Retain the last data inside the gap.
82  data_end = std::prev(data_end);
83  if (data_it == data_end) {
84  return;
85  }
86  }
87  if (gap_start != common::Time::min()) {
88  // Retain the first data inside the gap.
89  data_it = std::next(data_it);
90  }
91  while (data_it != data_end) {
92  data_it = trajectory.erase(data_it);
93  }
94  if (trajectory.empty()) {
95  data_.erase(trajectory_id);
96  }
97  }
98 
99  bool HasTrajectory(const int trajectory_id) const {
100  return data_.count(trajectory_id) != 0;
101  }
102 
104  public:
105  using iterator_category = std::bidirectional_iterator_tag;
106  using value_type = DataType;
108  using pointer = const DataType*;
109  using reference = const DataType&;
110 
111  explicit ConstIterator(
112  typename std::map<common::Time, DataType>::const_iterator iterator)
113  : iterator_(iterator) {}
114 
115  const DataType& operator*() const { return iterator_->second; }
116 
117  const DataType* operator->() const { return &iterator_->second; }
118 
120  ++iterator_;
121  return *this;
122  }
123 
125  --iterator_;
126  return *this;
127  }
128 
129  bool operator==(const ConstIterator& it) const {
130  return iterator_ == it.iterator_;
131  }
132 
133  bool operator!=(const ConstIterator& it) const { return !operator==(it); }
134 
135  private:
136  typename std::map<common::Time, DataType>::const_iterator iterator_;
137  };
138 
140  public:
141  using iterator_category = std::bidirectional_iterator_tag;
142  using value_type = int;
144  using pointer = const int*;
145  using reference = const int&;
146 
148  typename std::map<int, std::map<common::Time, DataType>>::const_iterator
149  current_trajectory)
150  : current_trajectory_(current_trajectory) {}
151 
152  int operator*() const { return current_trajectory_->first; }
153 
155  ++current_trajectory_;
156  return *this;
157  }
158 
160  --current_trajectory_;
161  return *this;
162  }
163 
164  bool operator==(const ConstTrajectoryIterator& it) const {
165  return current_trajectory_ == it.current_trajectory_;
166  }
167 
168  bool operator!=(const ConstTrajectoryIterator& it) const {
169  return !operator==(it);
170  }
171 
172  private:
173  typename std::map<int, std::map<common::Time, DataType>>::const_iterator
175  };
176 
177  ConstIterator BeginOfTrajectory(const int trajectory_id) const {
178  return ConstIterator(data_.at(trajectory_id).begin());
179  }
180 
181  ConstIterator EndOfTrajectory(const int trajectory_id) const {
182  return ConstIterator(data_.at(trajectory_id).end());
183  }
184 
185  // Returns Range object for range-based loops over the trajectory IDs.
188  ConstTrajectoryIterator(data_.begin()),
189  ConstTrajectoryIterator(data_.end()));
190  }
191 
192  mapping::Range<ConstIterator> trajectory(const int trajectory_id) const {
193  return mapping::Range<ConstIterator>(BeginOfTrajectory(trajectory_id),
194  EndOfTrajectory(trajectory_id));
195  }
196 
197  // Returns an iterator to the first element in the container belonging to
198  // trajectory 'trajectory_id' whose time is not considered to go before
199  // 'time', or EndOfTrajectory(trajectory_id) if all keys are considered to go
200  // before 'time'. 'trajectory_id' must refer to an existing trajectory.
201  ConstIterator lower_bound(const int trajectory_id,
202  const common::Time time) const {
203  return ConstIterator(data_.at(trajectory_id).lower_bound(time));
204  }
205 
206  private:
207  std::map<int, std::map<common::Time, DataType>> data_;
208 };
209 
210 } // namespace sensor
211 } // namespace cartographer
212 
213 #endif // CARTOGRAPHER_SENSOR_MAP_BY_TIME_H_
void Append(const int trajectory_id, const DataType &data)
Definition: map_by_time.h:39
std::map< int, std::map< common::Time, DataType > >::const_iterator current_trajectory_
Definition: map_by_time.h:174
void Trim(const mapping::MapById< mapping::NodeId, NodeType > &nodes, const mapping::NodeId &node_id)
Definition: map_by_time.h:51
ConstIterator lower_bound(const int trajectory_id, const common::Time time) const
Definition: map_by_time.h:201
bool HasTrajectory(const int trajectory_id) const
Definition: map_by_time.h:99
ConstIterator end() const
Definition: id.h:357
std::bidirectional_iterator_tag iterator_category
Definition: map_by_time.h:105
ConstIterator BeginOfTrajectory(const int trajectory_id) const
Definition: map_by_time.h:177
int64_t int64
Definition: port.h:33
UniversalTimeScaleClock::time_point Time
Definition: time.h:44
bool operator==(const ConstIterator &it) const
Definition: map_by_time.h:129
ConstIterator EndOfTrajectory(const int trajectory_id) const
Definition: id.h:323
static time_point time
std::map< common::Time, DataType >::const_iterator iterator_
Definition: map_by_time.h:136
ConstIterator EndOfTrajectory(const int trajectory_id) const
Definition: map_by_time.h:181
mapping::Range< ConstIterator > trajectory(const int trajectory_id) const
Definition: map_by_time.h:192
std::map< int, std::map< common::Time, DataType > > data_
Definition: map_by_time.h:207
ConstIterator(typename std::map< common::Time, DataType >::const_iterator iterator)
Definition: map_by_time.h:111
ConstTrajectoryIterator(typename std::map< int, std::map< common::Time, DataType >>::const_iterator current_trajectory)
Definition: map_by_time.h:147
bool operator!=(const ConstTrajectoryIterator &it) const
Definition: map_by_time.h:168
ConstIterator find(const IdType &id) const
Definition: id.h:275
bool operator!=(const ConstIterator &it) const
Definition: map_by_time.h:133
ConstIterator BeginOfTrajectory(const int trajectory_id) const
Definition: id.h:320
mapping::Range< ConstTrajectoryIterator > trajectory_ids() const
Definition: map_by_time.h:186
bool operator==(const ConstTrajectoryIterator &it) const
Definition: map_by_time.h:164


cartographer
Author(s): The Cartographer Authors
autogenerated on Mon Feb 28 2022 22:00:58