Monado OpenXR Runtime
m_relation_history.h
Go to the documentation of this file.
1// Copyright 2021, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Small utility for keeping track of the history of an xrt_space_relation, ie. for knowing where a HMD or
6 * controller was in the past
7 * @author Moshi Turner <moshiturner@protonmail.com>
8 * @author Rylie Pavlik <rylie.pavlik@collabora.com>
9 * @author Korcan Hussein <korcan.hussein@collabora.com>
10 * @ingroup aux_util
11 */
12#pragma once
13
14#include "xrt/xrt_defines.h"
15
17
18#ifdef __cplusplus
19extern "C" {
20#endif
21
22/**
23 * @brief Opaque type for storing the history of a space relation in a ring buffer
24 *
25 * @note Unlike the bare C++ data structure @ref HistoryBuffer this wraps, **this is a thread safe interface**,
26 * and is safe for concurrent access from multiple threads.
27 * (It is using a simple mutex, not a reader/writer lock, but that is fine until proven to be a bottleneck.)
28 *
29 * @ingroup aux_util
30 */
32
33/**
34 * @brief Describes how the resulting space relation for the desired time stamp was generated.
35 *
36 * @relates m_relation_history
37 */
39{
40 M_RELATION_HISTORY_RESULT_INVALID = 0, //!< The supplied timestamp was invalid (0) or buffer was empty
41 M_RELATION_HISTORY_RESULT_EXACT, //!< The exact desired timestamp was found
42 M_RELATION_HISTORY_RESULT_INTERPOLATED, //!< The desired timestamp was between two entries
43 M_RELATION_HISTORY_RESULT_PREDICTED, //!< The desired timestamp was newer than the most recent entry
44 M_RELATION_HISTORY_RESULT_REVERSE_PREDICTED, //!< The desired timestamp was older than the oldest entry
45};
46
48{
51};
52
53/*!
54 * Creates an opaque relation_history object.
55 *
56 * @public @memberof m_relation_history
57 */
58void
59m_relation_history_create(struct m_relation_history **rh, struct m_relation_history_filters *motion_vector_filters);
60
61/*!
62 * Pushes a new pose to the history.
63 *
64 * If the history is full, it will also pop a pose out of the other side of the buffer.
65 *
66 * @return false if the timestamp is earlier than the most recent timestamp already recorded
67 *
68 * @public @memberof m_relation_history
69 */
70bool
71m_relation_history_push(struct m_relation_history *rh, struct xrt_space_relation const *in_relation, int64_t timestamp);
72
73/*!
74 * Interpolates or extrapolates to the desired timestamp.
75 *
76 * Read-only operation - doesn't remove anything from the buffer or anything like that - you can call this as often as
77 * you want.
78 *
79 * @public @memberof m_relation_history
80 */
83 int64_t at_timestamp_ns,
84 struct xrt_space_relation *out_relation);
85
86/*!
87 * Estimates the movement (velocity and angular velocity) of a new relation based on
88 * the latest relation found in the buffer (as returned by m_relation_history_get_latest).
89 *
90 * Read-only on m_relation_history and in_relation.
91 * Copies in_relation->pose to out_relation->pose, and writes new flags and linear/angular velocities to
92 * out_relation->pose. OK to alias in_relation and out_relation.
93 *
94 * @public @memberof m_relation_history
95 */
96bool
98 const struct xrt_space_relation *in_relation,
99 int64_t timestamp,
100 struct xrt_space_relation *out_relation);
101
102/*!
103 * Get the latest report in the buffer, if any.
104 *
105 * @param rh self
106 * @param[out] out_time_ns Populated with the latest report time, if any
107 * @param[out] out_relation Populated with the latest relation, if any
108 *
109 * @return false if the history is empty.
110 *
111 * @public @memberof m_relation_history
112 */
113bool
115 int64_t *out_time_ns,
116 struct xrt_space_relation *out_relation);
117
118/*!
119 * Returns the number of items in the history.
120 *
121 * @public @memberof m_relation_history
122 */
123uint32_t
125
126/*!
127 * Clears the history from all of the items.
128 *
129 * @public @memberof m_relation_history
130 */
131void
133
134/*!
135 * Destroys an opaque relation_history object.
136 *
137 * @public @memberof m_relation_history
138 */
139void
141
142#ifdef __cplusplus
143}
144#endif
145
146
147#ifdef __cplusplus
148namespace xrt::auxiliary::math {
149
150/*!
151 * C++ interface for @ref m_relation_history, non-copyable/deletable.
152 *
153 * @ingroup aux_math
154 */
155class RelationHistory
156{
157public:
158 /*!
159 * @copydoc m_relation_history_result
160 */
161 typedef m_relation_history_result Result;
162
163
164private:
165 m_relation_history *mPtr{nullptr};
166
167
168public:
169 // clang-format off
170 RelationHistory(struct m_relation_history_filters *motion_vector_filters) noexcept { m_relation_history_create(&mPtr, motion_vector_filters); }
171 ~RelationHistory() { m_relation_history_destroy(&mPtr); }
172 // clang-format on
173
174 // Special non-copyable reference.
175 RelationHistory(RelationHistory const &) = delete;
176 RelationHistory(RelationHistory &&) = delete;
177 RelationHistory &
178 operator=(RelationHistory const &) = delete;
179 RelationHistory &
180 operator=(RelationHistory &&) = delete;
181
182
183 /*!
184 * @copydoc m_relation_history_push
185 */
186 bool
187 push(xrt_space_relation const &relation, int64_t ts) noexcept
188 {
189 return m_relation_history_push(mPtr, &relation, ts);
190 }
191
192 /*!
193 * @copydoc m_relation_history_get
194 */
195 Result
196 get(int64_t at_time_ns, xrt_space_relation *out_relation) const noexcept
197 {
198 return m_relation_history_get(mPtr, at_time_ns, out_relation);
199 }
200
201 /*!
202 * @copydoc m_relation_history_get_latest
203 */
204 bool
205 get_latest(int64_t *out_time_ns, xrt_space_relation *out_relation) const noexcept
206 {
207 return m_relation_history_get_latest(mPtr, out_time_ns, out_relation);
208 }
209
210 /*!
211 * @copydoc m_relation_history_get_size
212 */
213 size_t
214 size() const noexcept
215 {
216 return m_relation_history_get_size(mPtr);
217 }
218
219 /*!
220 * @copydoc m_relation_history_clear
221 */
222 void
223 clear() noexcept
224 {
225 return m_relation_history_clear(mPtr);
226 }
227};
228
229} // namespace xrt::auxiliary::math
230#endif
Header for a "One Euro Filter" implementation.
enum m_relation_history_result m_relation_history_get(const struct m_relation_history *rh, int64_t at_timestamp_ns, struct xrt_space_relation *out_relation)
Definition: m_relation_history.cpp:93
@ M_RELATION_HISTORY_RESULT_INTERPOLATED
The desired timestamp was between two entries.
Definition: m_relation_history.h:42
@ M_RELATION_HISTORY_RESULT_PREDICTED
The desired timestamp was newer than the most recent entry.
Definition: m_relation_history.h:43
@ M_RELATION_HISTORY_RESULT_REVERSE_PREDICTED
The desired timestamp was older than the oldest entry.
Definition: m_relation_history.h:44
@ M_RELATION_HISTORY_RESULT_INVALID
The supplied timestamp was invalid (0) or buffer was empty.
Definition: m_relation_history.h:40
@ M_RELATION_HISTORY_RESULT_EXACT
The exact desired timestamp was found.
Definition: m_relation_history.h:41
C++-only functionality in the Math helper library.
Definition: m_documentation.hpp:15
static Eigen::Map< const Eigen::Vector3f > position(const struct xrt_pose &pose)
Return a Eigen type wrapping a pose's position (const).
Definition: m_eigen_interop.hpp:217
static Eigen::Map< const Eigen::Quaternionf > orientation(const struct xrt_pose &pose)
Return a Eigen type wrapping a pose's orientation (const).
Definition: m_eigen_interop.hpp:199
One Euro filter for a unit quaternion (used as 3D rotation).
Definition: m_filter_one_euro.h:117
One Euro filter for a 3D float measurement.
Definition: m_filter_one_euro.h:99
Definition: m_relation_history.h:48
Definition: m_relation_history.cpp:50
void m_relation_history_destroy(struct m_relation_history **rh)
Destroys an opaque relation_history object.
Definition: m_relation_history.cpp:306
m_relation_history_result
Describes how the resulting space relation for the desired time stamp was generated.
Definition: m_relation_history.h:39
void m_relation_history_create(struct m_relation_history **rh, struct m_relation_history_filters *motion_vector_filters)
Creates an opaque relation_history object.
Definition: m_relation_history.cpp:59
uint32_t m_relation_history_get_size(const struct m_relation_history *rh)
Returns the number of items in the history.
Definition: m_relation_history.cpp:292
bool m_relation_history_push(struct m_relation_history *rh, struct xrt_space_relation const *in_relation, int64_t timestamp)
Pushes a new pose to the history.
Definition: m_relation_history.cpp:69
bool m_relation_history_estimate_motion(struct m_relation_history *rh, const struct xrt_space_relation *in_relation, int64_t timestamp, struct xrt_space_relation *out_relation)
Estimates the movement (velocity and angular velocity) of a new relation based on the latest relation...
Definition: m_relation_history.cpp:193
void m_relation_history_clear(struct m_relation_history *rh)
Clears the history from all of the items.
Definition: m_relation_history.cpp:299
enum m_relation_history_result m_relation_history_get(const struct m_relation_history *rh, int64_t at_timestamp_ns, struct xrt_space_relation *out_relation)
Interpolates or extrapolates to the desired timestamp.
Definition: m_relation_history.cpp:93
bool m_relation_history_get_latest(const struct m_relation_history *rh, int64_t *out_time_ns, struct xrt_space_relation *out_relation)
Get the latest report in the buffer, if any.
Definition: m_relation_history.cpp:278
A relation with two spaces, includes velocity and acceleration.
Definition: xrt_defines.h:659
static const cJSON * get(const cJSON *json, const char *f)
Less typing.
Definition: u_json.c:36
Common defines and enums for XRT.