Ocean
Loading...
Searching...
No Matches
tracking/slam/Tracker.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_TRACKING_SLAM_TRACKER_H
9#define META_OCEAN_TRACKING_SLAM_TRACKER_H
10
12
15
17#include "ocean/math/Numeric.h"
19#include "ocean/math/Vector3.h"
20
21namespace Ocean
22{
23
24namespace Tracking
25{
26
27namespace SLAM
28{
29
30/**
31 * This class implements the base class for all SLAM trackers.
32 * @ingroup trackingslam
33 */
34class OCEAN_TRACKING_SLAM_EXPORT Tracker
35{
36 public:
37
38 /**
39 * Definition of individual tracker states.
40 */
41 enum TrackerState : uint32_t
42 {
43 /// The tracker is in an unknown state (e.g., not yet started).
44 TS_UNKNOWN = 0u,
45 /// The tracker is currently initializing (e.g., building initial map).
47 /// The tracker is currently tracking (e.g., has a valid map and pose).
48 TS_TRACKING
49 };
50
51 /**
52 * This class implements a configuration object for the tracker.
53 * The configuration holds all parameters that control the behavior of the tracker, including feature detection thresholds, tracking distances, and gravity constraints.
54 */
56 {
57 public:
58
59 /**
60 * Creates a new default configuration object.
61 */
62 inline Configuration();
63
64 /**
65 * Returns the mean Harris threshold.
66 * The mean threshold is calculated as the average of the minimum and maximum Harris thresholds.
67 * @return The mean Harris threshold value, with range [harrisThresholdMin_, harrisThresholdMax_]
68 */
69 inline unsigned int harrisThresholdMean() const;
70
71 /**
72 * Returns whether the time interval between the previous and current frame is within the expected range.
73 * This function checks if the frame rate is consistent with the expected frames per second.
74 * @param previousFrameTimestamp The timestamp of the previous frame, must be valid
75 * @param currentFrameTimestamp The timestamp of the current frame, must be valid and >= previousFrameTimestamp
76 * @return True, if the interval is within the expected range; False otherwise
77 */
78 bool isInsideExpectedFrameInterval(const Timestamp& previousFrameTimestamp, const Timestamp& currentFrameTimestamp) const;
79
80 /**
81 * Returns whether this configuration object holds valid setting values.
82 * A configuration is valid if all parameters are within their valid ranges.
83 * @return True, if so; False otherwise
84 */
85 inline bool isValid() const;
86
87 public:
88
89 /// The number of spatial bins used for feature distribution, with range [1, 10000].
90 unsigned int numberBins_ = 200u;
91
92 /// The minimal threshold value for Harris corners, with range [1, harrisThresholdMax_].
93 unsigned int harrisThresholdMin_ = 5u;
94
95 /// The maximal threshold value for Harris corners, with range [harrisThresholdMin_, 254].
96 unsigned int harrisThresholdMax_ = 40u;
97
98 /// The size of the image patches to be used for 2D/2D tracking in pixels, possible values are {7, 15, 31}.
99 unsigned int patchSize_ = 7u;
100
101 /// The maximal projection error for pose estimation in pixels, with range [0, infinity).
102 Scalar maximalProjectionError_ = Scalar(3.5);
103
104 /// The maximal tracking distance for unguided tracking as a fraction of image diagonal, with range (0, 1].
105 float maximalTrackingDistanceUnguided_ = 0.025f;
106
107 /// The maximal tracking distance for IMU-guided tracking as a fraction of image diagonal, with range (0, maximalTrackingDistanceUnguided_].
108 float maximalTrackingDistanceGuidedIMU_ = 0.015f;
109
110 /// The maximal tracking distance for object point-guided tracking as a fraction of image diagonal, with range (0, maximalTrackingDistanceGuidedIMU_].
111 float maximalTrackingDistanceGuidedObjectPoint_ = 0.01f;
112
113 /// The gravity direction in the world coordinate system (pointing towards ground), must be a unit vector.
114 Vector3 worldGravity_ = Vector3(0, -1, 0);
115
116 /// The weight factor for gravity constraints in optimization, with range [0, infinity).
117 Scalar gravityWeightFactor_ = Scalar(0.001);
118
119 /// The maximal angle between measured and expected gravity direction in radians, with range (0, pi/2].
120 Scalar gravityMaximalAngle_ = Numeric::deg2rad(15);
121
122 /// The expected number of frames per second, with range (0, infinity).
123 double expectedFramesPerSecond_ = 30.0;
124 };
125
126 /**
127 * This class holds a pair of tracking parameters defining the pyramid configuration.
128 * The parameters specify the number of pyramid layers and the search radius in the coarsest layer, which together determine the tracking behavior for feature point tracking.
129 */
131 {
132 public:
133
134 /**
135 * Creates an invalid tracking parameter pair.
136 */
138
139 /**
140 * Creates a new tracking parameter pair.
141 * @param layers The number of pyramid layers to use, with range [1, infinity)
142 * @param coarsestLayerRadius The search radius in the coarsest pyramid layer in pixels, with range [1, infinity)
143 */
144 inline TrackingParameterPair(const unsigned int layers, const unsigned int coarsestLayerRadius);
145
146 /**
147 * Returns whether this parameter pair is valid.
148 * A parameter pair is valid if both the number of layers and the coarsest layer radius are non-zero.
149 * @return True, if so; False otherwise
150 */
151 inline bool isValid() const;
152
153 public:
154
155 /// The number of pyramid layers, with range [1, infinity), 0 if invalid.
156 unsigned int layers_ = 0u;
157
158 /// The search radius in the coarsest pyramid layer in pixels, with range [1, infinity), 0 if invalid.
159 unsigned int coarsestLayerRadius_ = 0u;
160 };
161
162 /**
163 * This class holds tracking parameters for different tracking modes.
164 * The class provides separate parameter sets for unguided tracking, IMU-guided tracking, and object point-guided tracking, allowing the tracker to adapt its behavior based on available information.
165 */
167 {
168 public:
169
170 /**
171 * Creates invalid tracking parameters.
172 */
174
175 /**
176 * Creates new tracking parameters based on frame dimensions and configuration.
177 * @param width The width of the frame in pixels, with range [1, infinity)
178 * @param height The height of the frame in pixels, with range [1, infinity)
179 * @param configuration The configuration object containing tracking settings, must be valid
180 */
181 TrackingParameters(const unsigned int width, const unsigned int height, const Tracker::Configuration& configuration);
182
183 /**
184 * Returns the appropriate tracking parameter pair based on camera motion and available guidance.
185 * @param world_T_previousCamera The transformation of the previous camera in world coordinates, must be valid
186 * @param previousCamera_Q_currentCamera The rotation from the previous camera to the current camera, invalid if no IMU data is available
187 * @param strongMotionAngle The angle threshold for detecting strong motion in radians, with range [0, pi], default is 1 degree
188 * @return The tracking parameter pair to use for the current tracking situation
189 */
190 const TrackingParameterPair& parameterPair(const HomogenousMatrix4& world_T_previousCamera, const Quaternion& previousCamera_Q_currentCamera, const Scalar strongMotionAngle = Numeric::deg2rad(1)) const;
191
192 /**
193 * Returns whether these tracking parameters are valid.
194 * Tracking parameters are valid if the patch size is non-zero and all parameter pairs are valid.
195 * @return True, if so; False otherwise
196 */
197 inline bool isValid() const;
198
199 public:
200
201 /// The patch size in pixels, possible values are {7, 15, 31}, 0 if invalid.
202 unsigned int patchSize_ = 0u;
203
204 /// Tracking parameters for unguided tracking (no IMU, no prior object points).
206
207 /// Tracking parameters for IMU-guided tracking (IMU rotation available).
209
210 /// Tracking parameters for object point-guided tracking (3D object points available for prediction).
212 };
213
214 /// True, to enabled logging (for debugging purposes); False, to disable logging.
215 static constexpr bool loggingEnabled_ = false;
216
217 protected:
218
219 /**
220 * This class implements a delay debugger for performance monitoring.
221 * In release builds, the debugger logs warnings when delays exceed the specified threshold.
222 */
224 {
225 public:
226
227 /**
228 * Reports a delay and logs a warning if it exceeds the threshold.
229 * In debug builds, this function does nothing.
230 * In release builds, this function measures the elapsed time since the debugger was created and logs a warning if it exceeds the specified threshold.
231 * @param description A human-readable description of the operation being measured, must be valid
232 * @param maxDelayMs The maximum acceptable delay in milliseconds, with range [0, infinity), default is 1.0ms
233 */
234 inline void reportDelay(const char* description, const double maxDelayMs = 1.0);
235
236#ifndef OCEAN_DEBUG
237 protected:
238
239 /// The high performance timer for measuring elapsed time (release builds only).
241#endif // OCEAN_DEBUG
242 };
243
244 public:
245
246 /**
247 * Translates a tracker state to a human-readable string.
248 * @param trackerState The tracker state to translate
249 * @return The string representation of the tracker state, 'Invalid' for unknown values
250 */
251 static std::string translateTrackerState(const TrackerState trackerState);
252
253 protected:
254
255 /**
256 * Creates a new tracker object.
257 */
258 Tracker() = default;
259
260 /**
261 * Destructs this tracker object.
262 */
263 virtual ~Tracker() = default;
264};
265
267{
268 ocean_assert(isValid());
269}
270
272{
273 return (harrisThresholdMin_ + harrisThresholdMax_ + 1u) / 2u;
274}
275
277{
278 if (numberBins_ <= 1u || numberBins_ > 10000u)
279 {
280 return false;
281 }
282
283 if (harrisThresholdMin_ <= 0u || harrisThresholdMax_ >= 255u || harrisThresholdMin_ > harrisThresholdMax_)
284 {
285 return false;
286 }
287
288 if (patchSize_ != 7u && patchSize_ != 15u && patchSize_ != 31u)
289 {
290 return false;
291 }
292
293 if (maximalProjectionError_ < Scalar(0))
294 {
295 return false;
296 }
297
298 if (maximalTrackingDistanceUnguided_ <= 0.0f || maximalTrackingDistanceUnguided_ > 1.0f)
299 {
300 return false;
301 }
302
303 if (maximalTrackingDistanceGuidedIMU_ <= 0.0f || maximalTrackingDistanceGuidedIMU_ > maximalTrackingDistanceUnguided_)
304 {
305 return false;
306 }
307
308 if (maximalTrackingDistanceGuidedObjectPoint_ <= 0.0f || maximalTrackingDistanceGuidedObjectPoint_ > maximalTrackingDistanceGuidedIMU_)
309 {
310 return false;
311 }
312
313 if (!worldGravity_.isUnit())
314 {
315 return false;
316 }
317
318 if (gravityMaximalAngle_ <= 0 || gravityMaximalAngle_ > Numeric::pi_2())
319 {
320 return false;
321 }
322
323 if (expectedFramesPerSecond_ <= 0.0)
324 {
325 return false;
326 }
327
328 return true;
329}
330
331inline Tracker::TrackingParameterPair::TrackingParameterPair(const unsigned int layers, const unsigned int coarsestLayerRadius) :
332 layers_(layers),
333 coarsestLayerRadius_(coarsestLayerRadius)
334{
335 // nothing to do here
336}
337
339{
340 return layers_ != 0u && coarsestLayerRadius_ != 0u;
341}
342
344{
345 return patchSize_ != 0u && trackingParametersUnguided_.isValid() && trackingParametersGuidedIMU_.isValid() && trackingParametersGuidedObjectPoint_.isValid();
346}
347
348inline void Tracker::DelayDebugger::reportDelay([[maybe_unused]] const char* description, [[maybe_unused]] const double maxDelayMs)
349{
350#ifdef OCEAN_DEBUG
351 // no-op in debug builds
352#else
353 const double delay = timer_.mseconds();
354
355 if (delay > maxDelayMs)
356 {
357 Log::warning() << "Delay: " << description << ": " << delay << "ms";
358 }
359#endif // OCEAN_DEBUG
360}
361
362inline std::string Tracker::translateTrackerState(const TrackerState trackerState)
363{
364 switch (trackerState)
365 {
366 case TS_UNKNOWN:
367 return "Unknown";
368
369 case TS_INITIALIZING:
370 return "Initializing";
371
372 case TS_TRACKING:
373 return "Tracking";
374 }
375
376 ocean_assert(false && "Invalid tracker state");
377 return "Invalid";
378}
379
380}
381
382}
383
384}
385
386#endif // META_OCEAN_TRACKING_SLAM_TRACKER_H
This class implements a high performance timer.
Definition HighPerformanceTimer.h:31
static MessageObject warning()
Returns the message for warning messages.
Definition Messenger.h:1090
static constexpr T pi_2()
Returns PI/2 which is equivalent to 90 degree.
Definition Numeric.h:938
This class implements a timestamp.
Definition Timestamp.h:64
This class implements a configuration object for the tracker.
Definition tracking/slam/Tracker.h:56
bool isValid() const
Returns whether this configuration object holds valid setting values.
Definition tracking/slam/Tracker.h:276
unsigned int harrisThresholdMean() const
Returns the mean Harris threshold.
Definition tracking/slam/Tracker.h:271
Configuration()
Creates a new default configuration object.
Definition tracking/slam/Tracker.h:266
bool isInsideExpectedFrameInterval(const Timestamp &previousFrameTimestamp, const Timestamp &currentFrameTimestamp) const
Returns whether the time interval between the previous and current frame is within the expected range...
This class implements a delay debugger for performance monitoring.
Definition tracking/slam/Tracker.h:224
void reportDelay(const char *description, const double maxDelayMs=1.0)
Reports a delay and logs a warning if it exceeds the threshold.
Definition tracking/slam/Tracker.h:348
HighPerformanceTimer timer_
The high performance timer for measuring elapsed time (release builds only).
Definition tracking/slam/Tracker.h:240
This class holds a pair of tracking parameters defining the pyramid configuration.
Definition tracking/slam/Tracker.h:131
bool isValid() const
Returns whether this parameter pair is valid.
Definition tracking/slam/Tracker.h:338
TrackingParameterPair()=default
Creates an invalid tracking parameter pair.
This class holds tracking parameters for different tracking modes.
Definition tracking/slam/Tracker.h:167
bool isValid() const
Returns whether these tracking parameters are valid.
Definition tracking/slam/Tracker.h:343
TrackingParameterPair trackingParametersGuidedIMU_
Tracking parameters for IMU-guided tracking (IMU rotation available).
Definition tracking/slam/Tracker.h:208
const TrackingParameterPair & parameterPair(const HomogenousMatrix4 &world_T_previousCamera, const Quaternion &previousCamera_Q_currentCamera, const Scalar strongMotionAngle=Numeric::deg2rad(1)) const
Returns the appropriate tracking parameter pair based on camera motion and available guidance.
TrackingParameterPair trackingParametersGuidedObjectPoint_
Tracking parameters for object point-guided tracking (3D object points available for prediction).
Definition tracking/slam/Tracker.h:211
TrackingParameters(const unsigned int width, const unsigned int height, const Tracker::Configuration &configuration)
Creates new tracking parameters based on frame dimensions and configuration.
TrackingParameters()=default
Creates invalid tracking parameters.
TrackingParameterPair trackingParametersUnguided_
Tracking parameters for unguided tracking (no IMU, no prior object points).
Definition tracking/slam/Tracker.h:205
This class implements the base class for all SLAM trackers.
Definition tracking/slam/Tracker.h:35
virtual ~Tracker()=default
Destructs this tracker object.
Tracker()=default
Creates a new tracker object.
static std::string translateTrackerState(const TrackerState trackerState)
Translates a tracker state to a human-readable string.
Definition tracking/slam/Tracker.h:362
TrackerState
Definition of individual tracker states.
Definition tracking/slam/Tracker.h:42
@ TS_UNKNOWN
The tracker is in an unknown state (e.g., not yet started).
Definition tracking/slam/Tracker.h:44
@ TS_INITIALIZING
The tracker is currently initializing (e.g., building initial map).
Definition tracking/slam/Tracker.h:46
@ TS_TRACKING
The tracker is currently tracking (e.g., has a valid map and pose).
Definition tracking/slam/Tracker.h:48
float Scalar
Definition of a scalar type.
Definition Math.h:129
The namespace covering the entire Ocean framework.
Definition Accessor.h:15