NASA Astrobee Robot Software  0.19.1
Flight software for the Astrobee robots operating inside the International Space Station.
feature_tracker.h
Go to the documentation of this file.
1 /* Copyright (c) 2017, United States Government, as represented by the
2  * Administrator of the National Aeronautics and Space Administration.
3  *
4  * All rights reserved.
5  *
6  * The Astrobee platform is licensed under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with the
8  * License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15  * License for the specific language governing permissions and limitations
16  * under the License.
17  */
18 
19 #ifndef VISION_COMMON_FEATURE_TRACKER_H_
20 #define VISION_COMMON_FEATURE_TRACKER_H_
21 
26 
27 #include <map>
28 #include <vector>
29 
30 namespace vision_common {
31 template <typename FeatureTrackType = FeatureTrack>
33  public:
34  using IdFeatureTrackMap = std::map<FeatureId, FeatureTrackType>;
35  explicit FeatureTracker(const FeatureTrackerParams& params);
36 
37  // Default constructor only for serialization
38  FeatureTracker() = default;
39 
40  virtual ~FeatureTracker() = default;
41 
42  // Add new feature points to existing or new tracks. Optionally removes
43  // any existing tracks that weren't detected in passed feature_points.
44  virtual void Update(const FeaturePoints& feature_points);
45 
46  // Remove any points older than oldest_allowed_time from each feature track.
47  // Removes any feature tracks that subsequently have no more detections.
48  virtual void RemoveOldPoints(const localization_common::Time oldest_allowed_time);
49 
50  // Returns a reference to the feature tracks.
51  const IdFeatureTrackMap& feature_tracks() const;
52 
53  // Returns feature track references ordered from longest to shortest
54  std::vector<std::reference_wrapper<const FeatureTrackType>> FeatureTracksLengthOrdered() const;
55 
56  // Returns the number of feature tracks.
57  size_t size() const;
58 
59  // Returns if no feature tracks exist.
60  bool empty() const;
61 
62  // Deletes all feature tracks.
63  virtual void Clear();
64 
65  private:
66  // Add new feature point to an existing track with the same track id
67  // create a new track if this doesn't exist.
68  void AddOrUpdateTrack(const FeaturePoint& feature_point);
69 
70  // Remove any feature tracks without detections at the provided timestamp
71  void RemoveUndetectedFeatureTracks(const localization_common::Time& time);
72 
73  // Remove any feature tracks with no detections.
74  void RemoveEmptyFeatureTracks();
75 
76  // Serialization function
77  friend class boost::serialization::access;
78  template <class ARCHIVE>
79  void serialize(ARCHIVE& ar, const unsigned int /*version*/) {
80  ar& BOOST_SERIALIZATION_NVP(id_feature_track_map_);
81  ar& BOOST_SERIALIZATION_NVP(params_);
82  }
83 
84  IdFeatureTrackMap id_feature_track_map_;
85  FeatureTrackerParams params_;
86 };
87 
88 // Implementation
89 template <typename FeatureTrackType>
91 
92 template <typename FeatureTrackType>
94  if (feature_points.empty() && params_.remove_undetected_feature_tracks) {
95  Clear();
96  LogDebug("UpdateFeatureTracks: Removed all feature tracks.");
97  return;
98  }
99 
100  const int starting_num_feature_tracks = size();
101  LogDebug("UpdateFeatureTracks: Starting num feature tracks: " << starting_num_feature_tracks);
102  for (const auto& feature_point : feature_points) {
103  AddOrUpdateTrack(feature_point);
104  }
105  const int post_add_num_feature_tracks = size();
106  LogDebug("UpdateFeatureTracks: Added feature tracks: " << post_add_num_feature_tracks - starting_num_feature_tracks);
107 
108  if (params_.remove_undetected_feature_tracks) {
109  const auto feature_points_timestamp = feature_points.front().timestamp;
110  RemoveUndetectedFeatureTracks(feature_points_timestamp);
111  }
112  const int removed_num_feature_tracks = post_add_num_feature_tracks - size();
113  LogDebug("UpdateFeatureTracks: Removed feature tracks: " << removed_num_feature_tracks);
114  LogDebug("UpdateFeatureTracks: Final total num feature tracks: " << size());
115 }
116 
117 template <typename FeatureTrackType>
119  for (auto& feature_track : id_feature_track_map_) {
120  feature_track.second.RemoveOldValues(oldest_allowed_time);
121  }
122  RemoveEmptyFeatureTracks();
123 }
124 
125 template <typename FeatureTrackType>
127  const {
128  return id_feature_track_map_;
129 }
130 
131 template <typename FeatureTrackType>
132 std::vector<std::reference_wrapper<const FeatureTrackType>>
134  std::map<int, int> length_id_map;
135  for (const auto& feature_track : feature_tracks()) {
136  length_id_map.insert({feature_track.second.size(), feature_track.first});
137  }
138  std::vector<std::reference_wrapper<const FeatureTrackType>> feature_tracks_length_ordered;
139  // Add tracks in order from longest to shortest
140  for (auto it = length_id_map.crbegin(); it != length_id_map.crend(); ++it) {
141  feature_tracks_length_ordered.emplace_back((this->feature_tracks().at(it->second)));
142  }
143 
144  return feature_tracks_length_ordered;
145 }
146 
147 template <typename FeatureTrackType>
149  return id_feature_track_map_.size();
150 }
151 
152 template <typename FeatureTrackType>
154  return id_feature_track_map_.empty();
155 }
156 
157 template <typename FeatureTrackType>
159  id_feature_track_map_.clear();
160 }
161 
162 template <typename FeatureTrackType>
164  if (id_feature_track_map_.count(feature_point.feature_track_id) == 0) {
165  id_feature_track_map_[feature_point.feature_track_id] = FeatureTrackType(feature_point.feature_track_id);
166  }
167  id_feature_track_map_[feature_point.feature_track_id].Add(feature_point.timestamp, feature_point);
168 }
169 
170 template <typename FeatureTrackType>
171 void FeatureTracker<FeatureTrackType>::RemoveUndetectedFeatureTracks(
172  const localization_common::Time& feature_point_timestamp) {
173  for (auto feature_it = id_feature_track_map_.cbegin(); feature_it != id_feature_track_map_.cend();) {
174  if (!feature_it->second.Contains(feature_point_timestamp)) {
175  feature_it = id_feature_track_map_.erase(feature_it);
176  } else {
177  ++feature_it;
178  }
179  }
180 }
181 
182 template <typename FeatureTrackType>
183 void FeatureTracker<FeatureTrackType>::RemoveEmptyFeatureTracks() {
184  for (auto feature_it = id_feature_track_map_.cbegin(); feature_it != id_feature_track_map_.cend();) {
185  if (feature_it->second.empty()) {
186  feature_it = id_feature_track_map_.erase(feature_it);
187  } else {
188  ++feature_it;
189  }
190  }
191 }
192 } // namespace vision_common
193 
194 #endif // VISION_COMMON_FEATURE_TRACKER_H_
vision_common::FeatureTracker::size
size_t size() const
Definition: feature_tracker.h:148
feature_track.h
vision_common
Definition: brisk_feature_detector_and_matcher.h:25
vision_common::FeatureTracker::feature_tracks
const IdFeatureTrackMap & feature_tracks() const
Definition: feature_tracker.h:126
vision_common::FeatureTracker
Definition: feature_tracker.h:32
vision_common::FeaturePoint
Definition: feature_point.h:34
vision_common::FeatureTracker::FeatureTracker
FeatureTracker()=default
feature_tracker_params.h
vision_common::FeatureTracker< SpacedFeatureTrack >::IdFeatureTrackMap
std::map< FeatureId, SpacedFeatureTrack > IdFeatureTrackMap
Definition: feature_tracker.h:34
feature_point.h
vision_common::FeaturePoints
std::vector< FeaturePoint > FeaturePoints
Definition: feature_point.h:56
time.h
vision_common::FeatureTracker::Clear
virtual void Clear()
Definition: feature_tracker.h:158
vision_common::FeaturePoint::feature_track_id
FeatureId feature_track_id
Definition: feature_point.h:41
vision_common::FeatureTracker::RemoveOldPoints
virtual void RemoveOldPoints(const localization_common::Time oldest_allowed_time)
Definition: feature_tracker.h:118
vision_common::FeatureTracker::empty
bool empty() const
Definition: feature_tracker.h:153
vision_common::FeaturePoint::timestamp
localization_common::Time timestamp
Definition: feature_point.h:42
vision_common::FeatureTracker::~FeatureTracker
virtual ~FeatureTracker()=default
vision_common::FeatureTrackerParams
Definition: feature_tracker_params.h:22
LogDebug
#define LogDebug(msg)
Definition: logger.h:69
vision_common::FeatureTracker::Update
virtual void Update(const FeaturePoints &feature_points)
Definition: feature_tracker.h:93
localization_common::Time
double Time
Definition: time.h:23
vision_common::FeatureTracker::FeatureTracksLengthOrdered
std::vector< std::reference_wrapper< const FeatureTrackType > > FeatureTracksLengthOrdered() const
Definition: feature_tracker.h:133