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 Moses Turner <moses@collabora.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 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 /**
21  * @brief Opaque type for storing the history of a space relation in a ring buffer
22  *
23  * @note Unlike the bare C++ data structure @ref HistoryBuffer this wraps, **this is a thread safe interface**,
24  * and is safe for concurrent access from multiple threads.
25  * (It is using a simple mutex, not a reader/writer lock, but that is fine until proven to be a bottleneck.)
26  *
27  * @ingroup aux_util
28  */
29 struct m_relation_history;
30 
31 /**
32  * @brief Describes how the resulting space relation for the desired time stamp was generated.
33  *
34  * @relates m_relation_history
35  */
37 {
38  M_RELATION_HISTORY_RESULT_INVALID = 0, //!< The supplied timestamp was invalid (0) or buffer was empty
39  M_RELATION_HISTORY_RESULT_EXACT, //!< The exact desired timestamp was found
40  M_RELATION_HISTORY_RESULT_INTERPOLATED, //!< The desired timestamp was between two entries
41  M_RELATION_HISTORY_RESULT_PREDICTED, //!< The desired timestamp was newer than the most recent entry
42  M_RELATION_HISTORY_RESULT_REVERSE_PREDICTED, //!< The desired timestamp was older than the oldest entry
43 };
44 
45 /*!
46  * Creates an opaque relation_history object.
47  *
48  * @public @memberof m_relation_history
49  */
50 void
52 
53 /*!
54  * Pushes a new pose to the history.
55  *
56  * If the history is full, it will also pop a pose out of the other side of the buffer.
57  *
58  * @return false if the timestamp is earlier than the most recent timestamp already recorded
59  *
60  * @public @memberof m_relation_history
61  */
62 bool
64  struct xrt_space_relation const *in_relation,
65  uint64_t timestamp);
66 
67 /*!
68  * Interpolates or extrapolates to the desired timestamp.
69  *
70  * Read-only operation - doesn't remove anything from the buffer or anything like that - you can call this as often as
71  * you want.
72  *
73  * @public @memberof m_relation_history
74  */
77  uint64_t at_timestamp_ns,
78  struct xrt_space_relation *out_relation);
79 
80 /*!
81  * Estimates the movement (velocity and angular velocity) of a new relation based on
82  * the latest relation found in the buffer (as returned by m_relation_history_get_latest).
83  *
84  * Read-only on m_relation_history and in_relation.
85  * Copies in_relation->pose to out_relation->pose, and writes new flags and linear/angular velocities to
86  * out_relation->pose. OK to alias in_relation and out_relation.
87  *
88  * @public @memberof m_relation_history
89  */
90 bool
92  const struct xrt_space_relation *in_relation,
93  uint64_t timestamp,
94  struct xrt_space_relation *out_relation);
95 
96 /*!
97  * Get the latest report in the buffer, if any.
98  *
99  * @param rh self
100  * @param[out] out_time_ns Populated with the latest report time, if any
101  * @param[out] out_relation Populated with the latest relation, if any
102  *
103  * @return false if the history is empty.
104  *
105  * @public @memberof m_relation_history
106  */
107 bool
109  uint64_t *out_time_ns,
110  struct xrt_space_relation *out_relation);
111 
112 /*!
113  * Returns the number of items in the history.
114  *
115  * @public @memberof m_relation_history
116  */
117 uint32_t
119 
120 /*!
121  * Clears the history from all of the items.
122  *
123  * @public @memberof m_relation_history
124  */
125 void
127 
128 /*!
129  * Destroys an opaque relation_history object.
130  *
131  * @public @memberof m_relation_history
132  */
133 void
135 
136 #ifdef __cplusplus
137 }
138 #endif
139 
140 
141 #ifdef __cplusplus
142 namespace xrt::auxiliary::math {
143 
144 /*!
145  * C++ interface for @ref m_relation_history, non-copyable/deletable.
146  *
147  * @ingroup aux_math
148  */
149 class RelationHistory
150 {
151 public:
152  /*!
153  * @copydoc m_relation_history_result
154  */
155  typedef m_relation_history_result Result;
156 
157 
158 private:
159  m_relation_history *mPtr{nullptr};
160 
161 
162 public:
163  // clang-format off
164  RelationHistory() noexcept { m_relation_history_create(&mPtr); }
165  ~RelationHistory() { m_relation_history_destroy(&mPtr); }
166  // clang-format on
167 
168  // Special non-copyable reference.
169  RelationHistory(RelationHistory const &) = delete;
170  RelationHistory(RelationHistory &&) = delete;
171  RelationHistory &
172  operator=(RelationHistory const &) = delete;
173  RelationHistory &
174  operator=(RelationHistory &&) = delete;
175 
176 
177  /*!
178  * @copydoc m_relation_history_push
179  */
180  bool
181  push(xrt_space_relation const &relation, uint64_t ts) noexcept
182  {
183  return m_relation_history_push(mPtr, &relation, ts);
184  }
185 
186  /*!
187  * @copydoc m_relation_history_get
188  */
189  Result
190  get(uint64_t at_time_ns, xrt_space_relation *out_relation) const noexcept
191  {
192  return m_relation_history_get(mPtr, at_time_ns, out_relation);
193  }
194 
195  /*!
196  * @copydoc m_relation_history_get_latest
197  */
198  bool
199  get_latest(uint64_t *out_time_ns, xrt_space_relation *out_relation) const noexcept
200  {
201  return m_relation_history_get_latest(mPtr, out_time_ns, out_relation);
202  }
203 
204  /*!
205  * @copydoc m_relation_history_get_size
206  */
207  size_t
208  size() const noexcept
209  {
210  return m_relation_history_get_size(mPtr);
211  }
212 
213  /*!
214  * @copydoc m_relation_history_clear
215  */
216  void
217  clear() noexcept
218  {
219  return m_relation_history_clear(mPtr);
220  }
221 };
222 
223 } // namespace xrt::auxiliary::math
224 #endif
enum m_relation_history_result m_relation_history_get(const struct m_relation_history *rh, uint64_t at_timestamp_ns, struct xrt_space_relation *out_relation)
Definition: m_relation_history.cpp:84
@ M_RELATION_HISTORY_RESULT_INTERPOLATED
The desired timestamp was between two entries.
Definition: m_relation_history.h:40
@ M_RELATION_HISTORY_RESULT_PREDICTED
The desired timestamp was newer than the most recent entry.
Definition: m_relation_history.h:41
@ M_RELATION_HISTORY_RESULT_REVERSE_PREDICTED
The desired timestamp was older than the oldest entry.
Definition: m_relation_history.h:42
@ M_RELATION_HISTORY_RESULT_INVALID
The supplied timestamp was invalid (0) or buffer was empty.
Definition: m_relation_history.h:38
@ M_RELATION_HISTORY_RESULT_EXACT
The exact desired timestamp was found.
Definition: m_relation_history.h:39
C++-only functionality in the Math helper library.
Definition: m_documentation.hpp:15
Definition: m_relation_history.cpp:46
bool m_relation_history_get_latest(const struct m_relation_history *rh, uint64_t *out_time_ns, struct xrt_space_relation *out_relation)
Get the latest report in the buffer, if any.
Definition: m_relation_history.cpp:231
void m_relation_history_destroy(struct m_relation_history **rh)
Destroys an opaque relation_history object.
Definition: m_relation_history.cpp:259
bool m_relation_history_estimate_motion(struct m_relation_history *rh, const struct xrt_space_relation *in_relation, uint64_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:184
m_relation_history_result
Describes how the resulting space relation for the desired time stamp was generated.
Definition: m_relation_history.h:37
bool m_relation_history_push(struct m_relation_history *rh, struct xrt_space_relation const *in_relation, uint64_t timestamp)
Pushes a new pose to the history.
Definition: m_relation_history.cpp:60
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:245
enum m_relation_history_result m_relation_history_get(const struct m_relation_history *rh, uint64_t at_timestamp_ns, struct xrt_space_relation *out_relation)
Interpolates or extrapolates to the desired timestamp.
Definition: m_relation_history.cpp:84
void m_relation_history_clear(struct m_relation_history *rh)
Clears the history from all of the items.
Definition: m_relation_history.cpp:252
void m_relation_history_create(struct m_relation_history **rh)
Creates an opaque relation_history object.
Definition: m_relation_history.cpp:53
A relation with two spaces, includes velocity and acceleration.
Definition: xrt_defines.h:657
static const cJSON * get(const cJSON *json, const char *f)
Less typing.
Definition: u_json.c:36
Common defines and enums for XRT.