Monado OpenXR Runtime
m_filter_one_euro.h
Go to the documentation of this file.
1// Copyright 2021-2023, Collabora, Ltd.
2// Copyright 2021, Jan Schmidt
3// SPDX-License-Identifier: BSL-1.0
4/*!
5 * @file
6 * @brief Header for a "One Euro Filter" implementation.
7 * @author Moshi Turner <moshiturner@protonmail.com>
8 * @author Jan Schmidt <jan@centricular.com>
9 * @author Rylie Pavlik <rylie.pavlik@collabora.com>
10 * @ingroup aux_math
11 *
12 * See the original publication:
13 *
14 * Casiez, G., Roussel, N., and Vogel, D. 2012. 1 € filter: a simple speed-based low-pass filter for noisy input in
15 * interactive systems. In: Proceedings of the SIGCHI Conference on Human Factors in Computing Systems. Association for
16 * Computing Machinery, New York, NY, USA, 2527–2530.
17 *
18 * Available at: https://hal.inria.fr/hal-00670496/document
19 */
20
21#pragma once
22
23#include "xrt/xrt_defines.h"
24#include "math/m_api.h"
25
26// Suggestions. These are suitable for head tracking.
27#define M_EURO_FILTER_HEAD_TRACKING_FCMIN 30.0
28#define M_EURO_FILTER_HEAD_TRACKING_FCMIN_D 25.0
29#define M_EURO_FILTER_HEAD_TRACKING_BETA 0.6
30
31// Suggestions. These are suitable for noisy eye tracking data.
32#define M_EURO_FILTER_EYE_TRACKING_FCMIN 1.00
33#define M_EURO_FILTER_EYE_TRACKING_FCMIN_D 0.05
34#define M_EURO_FILTER_EYE_TRACKING_BETA 0.007
35
36
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41/*!
42 * @brief Base data type for One Euro filter instances.
43 *
44 * @ingroup aux_math
45 */
47{
48 /** Minimum frequency cutoff for filter, default = 25.0 */
49 float fc_min;
50
51 /** Minimum frequency cutoff for derivative filter, default = 10.0 */
52 float fc_min_d;
53
54 /** Beta value for "responsiveness" of filter - default = 0.01 */
55 float beta;
56
57 /** true if we have already processed a history sample */
59
60 /** Timestamp of previous sample (nanoseconds) */
61 uint64_t prev_ts;
62};
63
64/*!
65 * @brief One Euro filter for a single float measurement.
66 *
67 * @ingroup aux_math
68 */
70{
71 /** Base/common data */
73
74 /** The most recent measurement, after filtering. */
75 double prev_y;
76
77 /** The most recent sample derivative, after filtering. */
78 double prev_dy;
79};
80
81/*!
82 * @brief One Euro filter for a 2D float measurement.
83 *
84 * @ingroup aux_math
85 */
87{
88 /** Base/common data */
90
91 /** The most recent measurement, after filtering. */
93
94 /** The most recent sample derivative, after filtering. */
96};
97
98/*!
99 * @brief One Euro filter for a 3D float measurement.
100 *
101 * @ingroup aux_math
102 */
104{
105 /** Base/common data */
107
108 /** The most recent measurement, after filtering. */
110
111 /** The most recent sample derivative, after filtering. */
113};
114
115
116/*!
117 * @brief One Euro filter for a unit quaternion (used as 3D rotation).
118 *
119 * @ingroup aux_math
120 */
122{
123 /** Base/common data */
125
126 /** The most recent measurement, after filtering. */
128
129 /** The most recent sample derivative, after filtering. */
131};
132
133/**
134 * @brief Initialize a 1D filter
135 *
136 * @param f self pointer
137 * @param fc_min Minimum frequency cutoff for filter
138 * @param fc_min_d Minimum frequency cutoff for derivative filter
139 * @param beta Beta value for "responsiveness" of filter
140 *
141 * @public @memberof m_filter_euro_f32
142 */
143void
144m_filter_euro_f32_init(struct m_filter_euro_f32 *f, double fc_min, double fc_min_d, double beta);
145
146/**
147 * @brief Filter a measurement and commit changes to filter state
148 *
149 * @param[in,out] f self pointer
150 * @param ts measurement timestamp
151 * @param in_y raw measurement
152 * @param[out] out_y filtered measurement
153 *
154 * @public @memberof m_filter_euro_f32
155 */
156void
157m_filter_euro_f32_run(struct m_filter_euro_f32 *f, uint64_t ts, const float *in_y, float *out_y);
158
159/**
160 * @brief Initialize a 2D filter
161 *
162 * @param f self pointer
163 * @param fc_min Minimum frequency cutoff for filter
164 * @param beta Beta value for "responsiveness" of filter
165 * @param fc_min_d Minimum frequency cutoff for derivative filter
166 *
167 * @public @memberof m_filter_euro_vec2
168 */
169void
170m_filter_euro_vec2_init(struct m_filter_euro_vec2 *f, double fc_min, double fc_min_d, double beta);
171
172/**
173 * @brief Filter a measurement and commit changes to filter state
174 *
175 * @param[in,out] f self pointer
176 * @param ts measurement timestamp
177 * @param in_y raw measurement
178 * @param[out] out_y filtered measurement
179 *
180 * @public @memberof m_filter_euro_vec2
181 */
182void
183m_filter_euro_vec2_run(struct m_filter_euro_vec2 *f, uint64_t ts, const struct xrt_vec2 *in_y, struct xrt_vec2 *out_y);
184
185/**
186 * @brief Filter a measurement **without** committing changes to filter state
187 *
188 * Similar to @ref m_filter_euro_vec2_run but @p f is not modified.
189 *
190 * @param[in] f self pointer
191 * @param ts measurement timestamp
192 * @param in_y raw measurement
193 * @param[out] out_y filtered measurement
194 *
195 * @public @memberof m_filter_euro_vec2
196 */
197void
199 uint64_t ts,
200 const struct xrt_vec2 *in_y,
201 struct xrt_vec2 *out_y);
202
203/**
204 * @brief Initialize a 3D filter
205 *
206 * @param f self pointer
207 * @param fc_min Minimum frequency cutoff for filter
208 * @param fc_min_d Minimum frequency cutoff for derivative filter
209 * @param beta Beta value for "responsiveness" of filter
210 *
211 * @public @memberof m_filter_euro_vec3
212 */
213void
214m_filter_euro_vec3_init(struct m_filter_euro_vec3 *f, double fc_min, double fc_min_d, double beta);
215
216/**
217 * @brief Filter a measurement and commit changes to filter state
218 *
219 * @param[in,out] f self pointer
220 * @param ts measurement timestamp
221 * @param in_y raw measurement
222 * @param[out] out_y filtered measurement
223 *
224 * @public @memberof m_filter_euro_vec3
225 */
226void
227m_filter_euro_vec3_run(struct m_filter_euro_vec3 *f, uint64_t ts, const struct xrt_vec3 *in_y, struct xrt_vec3 *out_y);
228
229/**
230 * @brief Initialize a unit quaternion (3D rotation) filter
231 *
232 * @param f self pointer
233 * @param fc_min Minimum frequency cutoff for filter
234 * @param fc_min_d Minimum frequency cutoff for derivative filter
235 * @param beta Beta value for "responsiveness" of filter
236 *
237 * @public @memberof m_filter_euro_quat
238 */
239void
240m_filter_euro_quat_init(struct m_filter_euro_quat *f, double fc_min, double fc_min_d, double beta);
241
242/**
243 * @brief Filter a measurement and commit changes to filter state
244 *
245 * @param[in,out] f self pointer
246 * @param ts measurement timestamp
247 * @param in_y raw measurement
248 * @param[out] out_y filtered measurement
249 *
250 * @public @memberof m_filter_euro_quat
251 */
252void
253m_filter_euro_quat_run(struct m_filter_euro_quat *f, uint64_t ts, const struct xrt_quat *in_y, struct xrt_quat *out_y);
254
255
256#ifdef __cplusplus
257}
258#endif
C interface to math library.
One Euro filter for a single float measurement.
Definition: m_filter_one_euro.h:70
void m_filter_euro_f32_run(struct m_filter_euro_f32 *f, uint64_t ts, const float *in_y, float *out_y)
Filter a measurement and commit changes to filter state.
Definition: m_filter_one_euro.c:136
double prev_y
The most recent measurement, after filtering.
Definition: m_filter_one_euro.h:75
double prev_dy
The most recent sample derivative, after filtering.
Definition: m_filter_one_euro.h:78
void m_filter_euro_f32_init(struct m_filter_euro_f32 *f, double fc_min, double fc_min_d, double beta)
Initialize a 1D filter.
Definition: m_filter_one_euro.c:130
struct m_filter_one_euro_base base
Base/common data.
Definition: m_filter_one_euro.h:72
One Euro filter for a unit quaternion (used as 3D rotation).
Definition: m_filter_one_euro.h:122
struct m_filter_one_euro_base base
Base/common data.
Definition: m_filter_one_euro.h:124
struct xrt_quat prev_dy
The most recent sample derivative, after filtering.
Definition: m_filter_one_euro.h:130
struct xrt_quat prev_y
The most recent measurement, after filtering.
Definition: m_filter_one_euro.h:127
void m_filter_euro_quat_init(struct m_filter_euro_quat *f, double fc_min, double fc_min_d, double beta)
Initialize a unit quaternion (3D rotation) filter.
Definition: m_filter_one_euro.c:256
void m_filter_euro_quat_run(struct m_filter_euro_quat *f, uint64_t ts, const struct xrt_quat *in_y, struct xrt_quat *out_y)
Filter a measurement and commit changes to filter state.
Definition: m_filter_one_euro.c:262
One Euro filter for a 2D float measurement.
Definition: m_filter_one_euro.h:87
struct xrt_vec2 prev_y
The most recent measurement, after filtering.
Definition: m_filter_one_euro.h:92
void m_filter_euro_vec2_run(struct m_filter_euro_vec2 *f, uint64_t ts, const struct xrt_vec2 *in_y, struct xrt_vec2 *out_y)
Filter a measurement and commit changes to filter state.
Definition: m_filter_one_euro.c:169
struct m_filter_one_euro_base base
Base/common data.
Definition: m_filter_one_euro.h:89
struct xrt_vec2 prev_dy
The most recent sample derivative, after filtering.
Definition: m_filter_one_euro.h:95
void m_filter_euro_vec2_run_no_commit(struct m_filter_euro_vec2 *f, uint64_t ts, const struct xrt_vec2 *in_y, struct xrt_vec2 *out_y)
Filter a measurement without committing changes to filter state.
Definition: m_filter_one_euro.c:195
void m_filter_euro_vec2_init(struct m_filter_euro_vec2 *f, double fc_min, double fc_min_d, double beta)
Initialize a 2D filter.
Definition: m_filter_one_euro.c:163
One Euro filter for a 3D float measurement.
Definition: m_filter_one_euro.h:104
struct xrt_vec3 prev_y
The most recent measurement, after filtering.
Definition: m_filter_one_euro.h:109
void m_filter_euro_vec3_run(struct m_filter_euro_vec3 *f, uint64_t ts, const struct xrt_vec3 *in_y, struct xrt_vec3 *out_y)
Filter a measurement and commit changes to filter state.
Definition: m_filter_one_euro.c:229
struct xrt_vec3 prev_dy
The most recent sample derivative, after filtering.
Definition: m_filter_one_euro.h:112
struct m_filter_one_euro_base base
Base/common data.
Definition: m_filter_one_euro.h:106
void m_filter_euro_vec3_init(struct m_filter_euro_vec3 *f, double fc_min, double fc_min_d, double beta)
Initialize a 3D filter.
Definition: m_filter_one_euro.c:223
Base data type for One Euro filter instances.
Definition: m_filter_one_euro.h:47
float beta
Beta value for "responsiveness" of filter - default = 0.01.
Definition: m_filter_one_euro.h:55
float fc_min
Minimum frequency cutoff for filter, default = 25.0.
Definition: m_filter_one_euro.h:49
bool have_prev_y
true if we have already processed a history sample
Definition: m_filter_one_euro.h:58
uint64_t prev_ts
Timestamp of previous sample (nanoseconds)
Definition: m_filter_one_euro.h:61
float fc_min_d
Minimum frequency cutoff for derivative filter, default = 10.0.
Definition: m_filter_one_euro.h:52
A quaternion with single floats.
Definition: xrt_defines.h:235
A 2 element vector with single floats.
Definition: xrt_defines.h:268
A 3 element vector with single floats.
Definition: xrt_defines.h:289
Common defines and enums for XRT.