Monado OpenXR Runtime
Loading...
Searching...
No Matches
t_constellation_tracker_internal.hpp
Go to the documentation of this file.
1// Copyright 2026, Beyley Cardellio
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Internal ures for the constellation tracker.
6 * @author Beyley Cardellio <ep1cm1n10n123@gmail.com>
7 * @ingroup tracking
8 */
9
10#pragma once
11
12#include "xrt/xrt_frame.h"
13#include "xrt/xrt_tracking.h"
14
15#include "util/u_debug.h"
16#include "util/u_logging.h"
17#include "util/u_var.h"
18#include "util/u_threading.h"
19#include "util/u_weak_ptr.hpp"
20#include "util/u_sink.h"
21#include "util/u_frame.h"
23
25
26#include "math/m_api.h"
27
28#include <vector>
29#include <memory>
30#include <mutex>
31#include <shared_mutex>
32#include <optional>
33#include <stdexcept>
34#include <array>
35
37#include "led_search_model.h"
38#include "pose_optimize.h"
39#include "pose_metrics.h"
41
42
43#define CT_TRACE(ct, ...) U_LOG_IFL_T(ct->log_level, __VA_ARGS__)
44#define CT_DEBUG(ct, ...) U_LOG_IFL_D(ct->log_level, __VA_ARGS__)
45#define CT_INFO(ct, ...) U_LOG_IFL_I(ct->log_level, __VA_ARGS__)
46#define CT_WARN(ct, ...) U_LOG_IFL_W(ct->log_level, __VA_ARGS__)
47#define CT_ERROR(ct, ...) U_LOG_IFL_E(ct->log_level, __VA_ARGS__)
48
49#define MIN_ROT_ERROR DEG_TO_RAD(30)
50#define MIN_POS_ERROR 0.10
51
52/*
53 *
54 * Forward declares for C callback functions
55 *
56 */
57
58extern "C" void
59constellation_tracker_camera_push_blobs(t_blob_sink *tbs, t_blob_observation *tbo);
60
61extern "C" void
62constellation_tracker_camera_destroy(t_blob_sink *tbs);
63
64extern "C" void *
65constellation_tracker_camera_slow_thread(void *ptr);
66
67extern "C" void *
68constellation_tracker_camera_fast_thread(void *ptr);
69
70extern "C" void
71constellation_tracker_node_break_apart(xrt_frame_node *node);
72
73extern "C" void
74constellation_tracker_node_destroy(xrt_frame_node *node);
75
76
77namespace xrt::tracking::constellation {
78
79namespace os = xrt::auxiliary::os;
80
81// Forward-declares
82struct CameraMosaic;
83struct Device;
84struct Camera;
85struct ConstellationTracker;
86
88{
89 //! The ID of the device.
90 t_constellation_device_id_t device_id{XRT_CONSTELLATION_INVALID_DEVICE_ID};
91
92 //! The "predicted" pose, which is the pose the device expects itself to be at at the time of the blobservation.
93 std::optional<xrt_pose> Txr_world_device_prior{std::nullopt};
94
95 //! The final found pose of the device in this specific sample.
96 std::optional<xrt_pose> Tcv_cam_device_found{std::nullopt};
97
98 //! Whether the device needs to have the slow processing thread run over it
100};
101
103{
104public: // Fields
105 t_blobwatch *source{nullptr};
106 uint64_t id{};
107 int64_t timestamp_ns{};
108 t_blob blobs[XRT_CONSTELLATION_MAX_BLOBS_PER_FRAME]{};
109 uint32_t blob_count{};
110
111 //! The camera's position in the constellation tracker's tracking origin
112 std::optional<xrt_pose> Txr_world_cam{std::nullopt};
113
114 std::array<DeviceState, XRT_CONSTELLATION_MAX_DEVICES> device_states{};
115 uint32_t device_count{};
116
117public: // Methods
118 std::optional<DeviceState *>
119 GetDeviceState(t_constellation_device_id_t device_id);
120
121 CameraSample(t_blob_observation &blobservation, Camera *camera);
122
123 void
124 MarkMatchingBlobs(ConstellationTracker *ct,
126 t_constellation_device_id_t device_id,
127 pose_metrics_blob_match_info &blob_match_info);
128
130 ToBlobObservation() const &
131 {
132 t_blob_observation obs = {
133 .source = this->source,
134 .id = this->id,
135 .timestamp_ns = this->timestamp_ns,
136 .blobs = const_cast<t_blob *>(this->blobs),
137 .num_blobs = this->blob_count,
138 };
139
140 return obs;
141 }
142
144 ToBlobObservation() && = delete;
146 ToBlobObservation() const && = delete;
147};
148
150{
151public: // Fields
152 //! Whether to draw the blobs in the sample
153 bool draw_blobs{true};
154 //! Whether to draw the raw blob IDs
155 bool draw_blob_ids{false};
156 //! Whether to draw the device IDs on the blobs where possible
157 bool draw_blob_device_ids{true};
158 //! Whether to draw the LED IDs on the blobs where possible
159 bool draw_blob_led_ids{false};
160
161 //! Whether to draw the prior device pose in the sample, if it exists.
162 bool draw_prior{false};
163 //! Whether to draw the final device pose in the sample, if it exists.
164 bool draw_found{false};
165
166public: // Methods
167 void
168 SetupDebugTracking(void *root);
169};
170
171struct Camera
172{
173public: // Fields
174 t_blob_sink base = {
175 .push_blobs = constellation_tracker_camera_push_blobs,
176 .destroy = constellation_tracker_camera_destroy,
177 };
178
179 //! The owner tracker, so we can retrieve it from the blob sink callback
181 std::weak_ptr<CameraMosaic> mosaic;
182
183 t_camera_calibration calibration;
184
185 camera_model model;
186
187 CameraScribbleSettings scribble_settings{};
188
189 //! The index in the mosaic
190 size_t index;
191
192 //! Does "slow" processing for this camera when fast recovery paths fail.
194 struct
195 {
196 std::optional<CameraSample> sample{std::nullopt};
197
198 correspondence_search *cs{nullptr};
199
200 u_sink_debug debug_sink{};
201 } slow_processing_thread_data;
202
203 /*!
204 * Does "fast" processing for this camera, trying to recover a pose quickly. It's valid for this to happen at
205 * the same time as a slow process.
206 */
208 struct
209 {
210 std::optional<CameraSample> sample{std::nullopt};
211
212 correspondence_search *cs{nullptr};
213
214 u_sink_debug debug_sink{};
215 } fast_processing_thread_data;
216
217 //! Locks all processing data
218 mutable os::Mutex processing_lock;
219 //! All data protected by the processing lock
220 struct
221 {
222 xrt_pose Txr_origin_cam;
223 bool has_concrete_pose;
224 } locked_data;
225
226public: // Methods (t_constellation_tracker.cpp)
227 static Camera *
228 Get(t_blob_sink *tbs)
229 {
230 return container_of(tbs, Camera, base);
231 }
232
233 Camera(ConstellationTracker *tracker,
234 std::weak_ptr<CameraMosaic> mosaic,
235 const t_constellation_tracker_camera &camera_params,
236 enum u_logging_level *log_level_ptr,
237 size_t index);
238
239 ~Camera();
240
241 // Delete all copy/move ctors, since the pointers for `base` need to be stable
242 Camera(const Camera &) = delete;
243 Camera(Camera &&) = delete;
244 Camera &
245 operator=(const Camera &) = delete;
246 Camera &
247 operator=(Camera &&) = delete;
248
249 std::optional<xrt_pose>
250 GetWorldPose(timepoint_ns when_ns);
251
252 void
253 DeferSampleToSlowThread(CameraSample &sample);
254
255 //! Fast matching based on prior pose
256 bool
257 TryDevicePose(std::unique_ptr<Device> &device,
258 CameraSample &sample,
259 xrt_pose &Tcv_cam_world,
260 xrt_pose &Tcv_world_device_prior,
261 xrt_pose &Tcv_world_device_candidate,
262 xrt_pose &Tcv_cam_device_found);
263
264 bool
265 TryDeviceBlobRecovery(std::unique_ptr<Device> &device,
266 CameraSample &sample,
267 xrt_pose &Tcv_cam_world,
268 xrt_pose &Tcv_world_device_prior,
269 xrt_pose &Tcv_cam_device_found);
270
271 void
272 SlowSampleProcess(CameraSample &sample);
273
274 //! Returns whether a slow search is needed
275 bool
276 FastSampleProcess(CameraSample &sample);
277
278 void
279 PushPose(CameraSample &sample,
280 std::unique_ptr<Device> &device,
281 pose_metrics &score,
282 xrt_pose &Tcv_cam_device,
283 bool optimize);
284
285public: // Public (constellation_debug_scribble.cpp)
286 void
287 DebugScribbleSample(CameraSample &sample, bool fast);
288};
289
291{
292public: // Fields
293 std::vector<std::unique_ptr<Camera>> cameras;
294 //! The index of this mosaic in the tracker.
295 size_t index;
296
298
299public: // Methods
301 const t_constellation_tracker_camera_mosaic &mosaic_params,
302 size_t index);
303
304 ~CameraMosaic() = default;
305
306 std::optional<xrt_pose>
307 GetTrackingOriginPose(timepoint_ns when_ns);
308};
309
310struct Device
311{
312public: // Fields
315
316 t_constellation_device_id_t id;
317
318 // @todo remove when clang-format is updated in CI
319 // clang-format off
320 t_constellation_search_model *search_model{nullptr};
321 xrt_vec3 prior_pos_error{MIN_POS_ERROR, MIN_POS_ERROR, MIN_POS_ERROR};
322 xrt_vec3 prior_rot_error{MIN_POS_ERROR, MIN_POS_ERROR, MIN_POS_ERROR};
323 float gravity_error_rad{MIN_ROT_ERROR}; /* Gravity vector uncertainty in radians 0..M_PI */
324
325 mutable os::Mutex data_lock;
326 struct
327 {
328 std::optional<xrt_pose> Txr_world_device_last_known;
329 } locked_data;
330 // clang-format on
331
332public: // Methods
335 t_constellation_device_id_t id);
336
337 ~Device();
338};
339
341{
342public: // Fields
343 xrt_frame_node node = {
344 .next = nullptr,
345 .break_apart = constellation_tracker_node_break_apart,
346 .destroy = constellation_tracker_node_destroy,
347 };
348 xrt_tracking_origin tracking_origin = {
349 .name = "Constellation Tracker",
351 .initial_offset = XRT_POSE_IDENTITY,
352 };
353
354 //! Whether the constellation tracker is running
355 bool running = true;
356
357 enum u_logging_level log_level = U_LOGGING_WARN;
358
360
361 std::vector<std::shared_ptr<CameraMosaic>> mosaics;
362
363 std::shared_mutex device_lock;
364 std::vector<std::unique_ptr<Device>> devices;
365 t_constellation_device_id_t next_device_id{0};
366
367public: // Methods
368 static ConstellationTracker *
369 Get(xrt_frame_node *node)
370 {
371 return container_of(node, ConstellationTracker, node);
372 }
373
374 ConstellationTracker(t_constellation_tracker_params *params);
375
376 ~ConstellationTracker();
377
378 // Delete all copy/move ctors, since the pointers for `node` need to be stable
379 ConstellationTracker(const ConstellationTracker &) = delete;
380 ConstellationTracker(ConstellationTracker &&) = delete;
381 ConstellationTracker &
382 operator=(const ConstellationTracker &) = delete;
383 ConstellationTracker &
384 operator=(ConstellationTracker &&) = delete;
385
386 void
387 SetupVariableTracking();
388
389 t_constellation_device_id_t
391
392 void
393 RemoveDevice(t_constellation_device_id_t device_id);
394};
395
396}; // namespace xrt::tracking::constellation
Definition device.hpp:68
Ab-initio blob<->LED correspondence search.
u_logging_level
Logging level enum.
Definition u_logging.h:45
@ U_LOGGING_WARN
Warning messages: indicating a potential problem.
Definition u_logging.h:49
int64_t timepoint_ns
Integer timestamp type.
Definition u_time.h:77
#define container_of(ptr, type, field)
Get the holder from a pointer to a field.
Definition xrt_compiler.h:226
@ XRT_TRACKING_TYPE_CONSTELLATION
The device(s) are tracked through a constellation of lights as seen by cameras.
Definition xrt_tracking.h:63
LED search model management code.
C interface to math library.
Metrics for constellation tracking poses.
RANSAC PnP pose refinement.
Definition t_rift_blobwatch.c:82
Definition camera_model.h:19
Definition correspondence_search.h:92
All in one helper that handles locking, waiting for change and starting a thread.
Definition os_threading.h:499
Definition pose_metrics.h:85
Definition pose_metrics.h:61
Definition t_constellation.h:80
A generic interface to allow a tracking system to receive "snapshots" of seen t_blob in a frame.
Definition t_constellation.h:101
void(* push_blobs)(struct t_blob_sink *tbs, struct t_blob_observation *observation)
Push a set of blobs into the sink.
Definition t_constellation.h:109
A blob is a 2d position in a camera sensor's view that is being tracked.
Definition t_constellation.h:37
Definition t_constellation.h:152
Essential calibration data for a single camera, or single lens/sensor of a stereo camera.
Definition t_tracking.h:236
Definition led_search_model.h:40
A constellation tracker camera mosaic is a set of cameras that may or may not be physically attached,...
Definition t_constellation_tracker.h:60
A constellation tracker camera is a single camera that the constellation tracker will use to track de...
Definition t_constellation_tracker.h:34
Parameters for adding a device to the constellation tracker.
Definition t_constellation_tracker.h:79
A constellation tracker device is a device that the constellation tracker will attempt to track in 6d...
Definition t_constellation.h:327
The LED model is a series of points which define the real-world positions of all LEDs.
Definition t_constellation.h:266
Definition t_constellation_tracker.h:94
A constellation tracker tracking source is an arbitrary source of tracking data for the constellation...
Definition t_constellation.h:221
Allows more safely to debug sink inputs and outputs.
Definition u_sink.h:214
Definition t_constellation_tracker_internal.hpp:172
os_thread_helper slow_processing_thread
Does "slow" processing for this camera when fast recovery paths fail.
Definition t_constellation_tracker_internal.hpp:193
os_thread_helper fast_processing_thread
Does "fast" processing for this camera, trying to recover a pose quickly.
Definition t_constellation_tracker_internal.hpp:207
os::Mutex processing_lock
Locks all processing data.
Definition t_constellation_tracker_internal.hpp:218
ConstellationTracker * tracker
The owner tracker, so we can retrieve it from the blob sink callback.
Definition t_constellation_tracker_internal.hpp:180
size_t index
The index in the mosaic.
Definition t_constellation_tracker_internal.hpp:190
Definition t_constellation_tracker_internal.hpp:291
size_t index
The index of this mosaic in the tracker.
Definition t_constellation_tracker_internal.hpp:295
Definition t_constellation_tracker_internal.hpp:103
std::optional< xrt_pose > Txr_world_cam
The camera's position in the constellation tracker's tracking origin.
Definition t_constellation_tracker_internal.hpp:112
Definition t_constellation_tracker_internal.hpp:150
Definition t_constellation_tracker_internal.hpp:341
Definition t_constellation_tracker_internal.hpp:311
Definition t_constellation_tracker_internal.hpp:88
t_constellation_device_id_t device_id
The ID of the device.
Definition t_constellation_tracker_internal.hpp:90
std::optional< xrt_pose > Txr_world_device_prior
The "predicted" pose, which is the pose the device expects itself to be at at the time of the blobser...
Definition t_constellation_tracker_internal.hpp:93
std::optional< xrt_pose > Tcv_cam_device_found
The final found pose of the device in this specific sample.
Definition t_constellation_tracker_internal.hpp:96
bool needs_slow_processing
Whether the device needs to have the slow processing thread run over it.
Definition t_constellation_tracker_internal.hpp:99
A interface object used for destroying a frame graph.
Definition xrt_frame.h:87
void(* break_apart)(struct xrt_frame_node *node)
Called first in when the graph is being destroyed, remove any references frames and other objects and...
Definition xrt_frame.h:94
A pose composed of a position and orientation.
Definition xrt_defines.h:492
A tracking system or device origin.
Definition xrt_tracking.h:78
char name[256]
For debugging.
Definition xrt_tracking.h:80
A 3 element vector with single floats.
Definition xrt_defines.h:289
Header defining the tracking system integration in Monado.
Header defining the constellation tracker parameters and functions.
Small debug helpers.
xrt_frame helpers.
xrt_frame helpers for scribbling onto frames.
Basic logging functionality.
xrt_frame_sink converters and other helpers.
Slightly higher level thread safe helpers.
Variable tracking code.
C++ helpers for weak pointers.
Data frame header.
Header defining the tracking system integration in Monado.