Monado OpenXR Runtime
Loading...
Searching...
No Matches
t_led_sync_refinement.h
Go to the documentation of this file.
1// Copyright 2026, Beyley Cardellio
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief A routine to automatically refine latency offsets of LED blink times using constellation samples.
6 * @author Beyley Cardellio <ep1cm1n10n123@gmail.com>
7 * @ingroup tracking
8 */
9
10#pragma once
11
12#include "util/u_time.h"
13#include "util/u_logging.h"
14
15#include "os/os_threading.h"
16
19
20
21//! 10 seconds after last visually seen sample to resync
22#define T_LED_SYNC_DEFAULT_RESYNC_TIME (time_duration_ns)(U_TIME_1S_IN_NS * 5LL)
23
24//! Flags to control the behavior of the LED sync refinement routine.
26{
27 T_LED_SYNC_REFINEMENT_FLAGS_NONE = 0,
28 //! Whether to try to optimize the blink duration after finding an offset, to lessen power usage.
30 /*!
31 * Whether to lock in a clock offset and have it be driven entirely by the sync refinement, utilizing the
32 * optical samples to measure clock skew/offset between the device and host, rather than the driver's normal
33 * remote clock synchronization.
34 *
35 * Use this flag when the driver's clock tracking is very noisy and is causing LED sync to be unreliable. But
36 * currently will cause LED sync to eventually drift as clock skew between the devices takes effect.
37 */
39 /*!
40 * Whether the device has specified a maximum latency cap. This prevents the sync refinement from searching
41 * parts of the exposure that aren't possible, which can cause refinement to sometimes take longer.
42 */
44};
45
46//! Options for the LED sync refinement.
48{
49 //! The flags to use when refining.
51
52 //! How long the LEDs should be initially blinking for, in nanoseconds.
54
55 //! The minimum duration to use for the LED blinks, if using reduction.
57 //! The maximum duration to use for the LED blinks, if using reduction.
59
60 //! Time to wait after the last visually seen sample before resyncing.
62 //! Frames to wait after the sample was applied to let the device settle.
63 uint32_t settle_frames;
64
65 //! The maximum latency offset to use, if using a latency cap.
67};
68
70{
71 T_LED_SYNC_SAMPLE_TIMESTAMP_MODE_INVALID = 0,
72 //! Used when the LED sync refinement is just computing a basic latency offset.
74 //! Used when the LED sync refinement is fully deriving the clock offset, latency included.
76};
77
78//! A sample read out from the driver, to pass to the device in question.
80{
81 union {
82 //! The latency offset from the device timestamps to the host.
84
85 //! The clock offset from the host timestamp to the device.
87 } timestamp;
88 enum t_led_sync_sample_timestamp_mode timestamp_mode;
89
90 //! The latency offset to apply to fudge the blink to line up as best as possible with the exposure.
92 //! The duration to make the LEDs blink for, in nanoseconds.
94};
95
97{
98 //! The initial phase, where we haven't made any adjustments yet.
100 //! Trying to find some offset that gets us in sync at all.
102 //! Trying to align the rising edge of the LED blinks with the falling edge of the camera exposure.
104 //! Trying to align the falling edge of the LED blinks with the rising edge of the camera exposure.
106 //! We've found an offset, now we can optimize the blink duration to something that keeps it tracking.
108 //! We've found an offset and optimized the center of the LED blink to the center of the exposure.
110};
111
113{
114 //! Whether the structure has been fully initialized.
116
117 enum u_logging_level log_level;
118
119 //! The options to use for refinement
121
122 struct os_mutex lock;
123
124 /*!
125 * Whether we know the actual exposure time of the frames. We may not, so we have to work without it in some
126 * cases.
127 */
129 //! The known time the frame was exposed for.
131
132 //! The known interval between frames.
134
135 //! Whether we have a sample ready to be sent to the driver/device.
137 //! The sample to be sent to the driver/device on it's next convenience.
139 //! Whether the sample has been applied
141
142 //! The current search phase
144
145 /*!
146 * The current estimated latency offset between the device and the host, in nanoseconds. This is what we are
147 * trying to refine.
148 */
150 /*!
151 * The amount of fudge between the latency offset and the actual blink start time, in nanoseconds, so we can
152 * place the blink at the optimal time for the exposure.
153 */
155
156 //! How long the LEDs blink for, each frame.
158
159 //! The amount of frames since the controller was last visually seen.
161
162 //! The sequence ID of the latest timing event we processed.
164
165 //! The time the latest sample was applied to the driver/device
167
168 //! The found left edge of the exposure, -1 if not found yet.
170 //! The found right edge of the exposure, -1 if not found yet.
172
173 struct
174 {
175 //! The current left bound of the binary search, if we're in a find edge phase.
177 //! The current right bound of the binary search, if we're in a find edge phase.
179 } binary_search_state;
180
181 struct
182 {
183 //! The last blink duration that didn't cause the device to become unstable.
185
186 //! Whether we're currently trying to back off a lower blink duration.
188 } blink_time_refinement_state;
189
190 struct
191 {
192 //! The latest estimated host->device clock offset from the driver.
194
195 bool has_saved_offset;
196 time_duration_ns saved_offset;
197 } optical_driven_offset;
198};
199
200int
201t_led_sync_refinement_init(struct t_led_sync_refinement *refinement,
202 const struct t_led_sync_refinement_options *options);
203
204void
205t_led_sync_refinement_destroy(struct t_led_sync_refinement *refinement);
206
207void
208t_led_sync_push_timing_event(struct t_led_sync_refinement *refinement,
209 const struct t_timing_event_camera_exposure_start *event);
210
211void
212t_led_sync_push_constellation_sample(struct t_led_sync_refinement *refinement,
213 const struct t_constellation_tracker_sample *sample);
214
215bool
216t_led_sync_get_sample(struct t_led_sync_refinement *refinement, struct t_led_sync_sample *out_sample);
217
218void
219t_led_sync_mark_latest_sample_applied(struct t_led_sync_refinement *refinement, timepoint_ns apply_time_ns);
220
221/*!
222 * Pushes a clock offset to the refinement routine, this is the offset *from* the host *to* the device.
223 *
224 * To convert a timestamp from host -> device domain, you would do:
225 * `device_timestamp = host_timestamp + clock_offset_ns`
226 */
227void
u_logging_level
Logging level enum.
Definition u_logging.h:45
int64_t timepoint_ns
Integer timestamp type.
Definition u_time.h:77
int64_t time_duration_ns
Integer duration type in nanoseconds.
Definition u_time.h:88
Wrapper around OS threading native functions.
A wrapper around a native mutex.
Definition os_threading.h:69
Definition t_constellation.h:316
Options for the LED sync refinement.
Definition t_led_sync_refinement.h:48
time_duration_ns time_to_resync_ns
Time to wait after the last visually seen sample before resyncing.
Definition t_led_sync_refinement.h:61
time_duration_ns min_blink_duration_ns
The minimum duration to use for the LED blinks, if using reduction.
Definition t_led_sync_refinement.h:56
uint32_t settle_frames
Frames to wait after the sample was applied to let the device settle.
Definition t_led_sync_refinement.h:63
time_duration_ns max_blink_duration_ns
The maximum duration to use for the LED blinks, if using reduction.
Definition t_led_sync_refinement.h:58
enum t_led_sync_refinement_flags flags
The flags to use when refining.
Definition t_led_sync_refinement.h:50
time_duration_ns initial_blink_duration_ns
How long the LEDs should be initially blinking for, in nanoseconds.
Definition t_led_sync_refinement.h:53
time_duration_ns latency_cap_ns
The maximum latency offset to use, if using a latency cap.
Definition t_led_sync_refinement.h:66
Definition t_led_sync_refinement.h:113
uint32_t frames_since_last_visually_seen
The amount of frames since the controller was last visually seen.
Definition t_led_sync_refinement.h:160
time_duration_ns found_left_edge_ns
The found left edge of the exposure, -1 if not found yet.
Definition t_led_sync_refinement.h:169
time_duration_ns found_right_edge_ns
The found right edge of the exposure, -1 if not found yet.
Definition t_led_sync_refinement.h:171
time_duration_ns right_bound_ns
The current right bound of the binary search, if we're in a find edge phase.
Definition t_led_sync_refinement.h:178
bool has_sample_for_driver
Whether we have a sample ready to be sent to the driver/device.
Definition t_led_sync_refinement.h:136
time_duration_ns left_bound_ns
The current left bound of the binary search, if we're in a find edge phase.
Definition t_led_sync_refinement.h:176
time_duration_ns current_latency_offset_ns
The current estimated latency offset between the device and the host, in nanoseconds.
Definition t_led_sync_refinement.h:149
uint32_t current_sequence_id
The sequence ID of the latest timing event we processed.
Definition t_led_sync_refinement.h:163
bool sample_applied
Whether the sample has been applied.
Definition t_led_sync_refinement.h:140
bool backing_off
Whether we're currently trying to back off a lower blink duration.
Definition t_led_sync_refinement.h:187
struct t_led_sync_sample sample_for_driver
The sample to be sent to the driver/device on it's next convenience.
Definition t_led_sync_refinement.h:138
time_duration_ns last_good_blink_duration_ns
The last blink duration that didn't cause the device to become unstable.
Definition t_led_sync_refinement.h:184
time_duration_ns exposure_time_ns
The known time the frame was exposed for.
Definition t_led_sync_refinement.h:130
time_duration_ns current_blink_duration_ns
How long the LEDs blink for, each frame.
Definition t_led_sync_refinement.h:157
enum t_led_sync_phase phase
The current search phase.
Definition t_led_sync_refinement.h:143
bool initialized
Whether the structure has been fully initialized.
Definition t_led_sync_refinement.h:115
time_duration_ns current_blink_fudge_ns
The amount of fudge between the latency offset and the actual blink start time, in nanoseconds,...
Definition t_led_sync_refinement.h:154
time_duration_ns driver_host_device_clock_offset_ns
The latest estimated host->device clock offset from the driver.
Definition t_led_sync_refinement.h:193
timepoint_ns last_sample_apply_time_ns
The time the latest sample was applied to the driver/device.
Definition t_led_sync_refinement.h:166
bool has_exposure_time
Whether we know the actual exposure time of the frames.
Definition t_led_sync_refinement.h:128
time_duration_ns exposure_interval_ns
The known interval between frames.
Definition t_led_sync_refinement.h:133
struct t_led_sync_refinement_options options
The options to use for refinement.
Definition t_led_sync_refinement.h:120
A sample read out from the driver, to pass to the device in question.
Definition t_led_sync_refinement.h:80
time_duration_ns fudge_offset_ns
The latency offset to apply to fudge the blink to line up as best as possible with the exposure.
Definition t_led_sync_refinement.h:91
time_duration_ns host_device_clock_offset_ns
The clock offset from the host timestamp to the device.
Definition t_led_sync_refinement.h:86
time_duration_ns device_host_latency_ns
The latency offset from the device timestamps to the host.
Definition t_led_sync_refinement.h:83
time_duration_ns blink_duration_ns
The duration to make the LEDs blink for, in nanoseconds.
Definition t_led_sync_refinement.h:93
Marks beginning of a camera exposure, pushed from the source to the sink.
Definition t_time_sync.h:29
Header defining the tracking system integration in Monado.
void t_led_sync_push_host_device_clock_offset(struct t_led_sync_refinement *refinement, time_duration_ns clock_offset_ns)
Pushes a clock offset to the refinement routine, this is the offset from the host to the device.
Definition t_led_sync_refinement.c:679
t_led_sync_sample_timestamp_mode
Definition t_led_sync_refinement.h:70
@ T_LED_SYNC_SAMPLE_TIMESTAMP_MODE_HOST_DEVICE_CLOCK_OFFSET
Used when the LED sync refinement is fully deriving the clock offset, latency included.
Definition t_led_sync_refinement.h:75
@ T_LED_SYNC_SAMPLE_TIMESTAMP_MODE_DEVICE_HOST_LATENCY
Used when the LED sync refinement is just computing a basic latency offset.
Definition t_led_sync_refinement.h:73
t_led_sync_refinement_flags
Flags to control the behavior of the LED sync refinement routine.
Definition t_led_sync_refinement.h:26
@ T_LED_SYNC_REFINEMENT_FLAGS_BLINK_DURATION
Whether to try to optimize the blink duration after finding an offset, to lessen power usage.
Definition t_led_sync_refinement.h:29
@ T_LED_SYNC_REFINEMENT_FLAGS_OPTICAL_DRIVEN_OFFSET
Whether to lock in a clock offset and have it be driven entirely by the sync refinement,...
Definition t_led_sync_refinement.h:38
@ T_LED_SYNC_REFINEMENT_FLAGS_HAS_LATENCY_CAP
Whether the device has specified a maximum latency cap.
Definition t_led_sync_refinement.h:43
t_led_sync_phase
Definition t_led_sync_refinement.h:97
@ T_LED_SYNC_SEARCH_PHASE_REFINE_BLINK_DURATION
We've found an offset, now we can optimize the blink duration to something that keeps it tracking.
Definition t_led_sync_refinement.h:107
@ T_LED_SYNC_SEARCH_PHASE_FIND_LEFT_EDGE
Trying to align the falling edge of the LED blinks with the rising edge of the camera exposure.
Definition t_led_sync_refinement.h:105
@ T_LED_SYNC_SEARCH_PHASE_INIT
The initial phase, where we haven't made any adjustments yet.
Definition t_led_sync_refinement.h:99
@ T_LED_SYNC_SEARCH_PHASE_FIND_INITIAL_OFFSET
Trying to find some offset that gets us in sync at all.
Definition t_led_sync_refinement.h:101
@ T_LED_SYNC_SEARCH_PHASE_FIND_RIGHT_EDGE
Trying to align the rising edge of the LED blinks with the falling edge of the camera exposure.
Definition t_led_sync_refinement.h:103
@ T_LED_SYNC_SEARCH_PHASE_MAINTAIN_OFFSET
We've found an offset and optimized the center of the LED blink to the center of the exposure.
Definition t_led_sync_refinement.h:109
Header defining interfaces for time synchronization in Monado.
Basic logging functionality.
Time-keeping: a clock that is steady, convertible to system time, and ideally high-resolution.