Monado OpenXR Runtime
t_fusion.hpp
Go to the documentation of this file.
1// Copyright 2019, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief C++ sensor fusion/filtering code that uses flexkalman
6 * @author Rylie Pavlik <rylie.pavlik@collabora.com>
7 * @ingroup aux_tracking
8 */
9
10#pragma once
11
12#ifndef __cplusplus
13#error "This header is C++-only."
14#endif
15
16#include <Eigen/Core>
17#include <Eigen/Geometry>
18
19#include "flexkalman/AugmentedProcessModel.h"
20#include "flexkalman/AugmentedState.h"
21#include "flexkalman/BaseTypes.h"
22#include "flexkalman/PoseState.h"
23
24
25namespace xrt::auxiliary::tracking {
26
27namespace types = flexkalman::types;
28using flexkalman::types::Vector;
29
30//! For things like accelerometers, which on some level measure the local vector
31//! of a world direction.
32template <typename State>
33class WorldDirectionMeasurement : public flexkalman::MeasurementBase<WorldDirectionMeasurement<State>>
34{
35public:
36 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
37 static constexpr size_t Dimension = 3;
38 using MeasurementVector = types::Vector<Dimension>;
39 using MeasurementSquareMatrix = types::SquareMatrix<Dimension>;
40 WorldDirectionMeasurement(types::Vector<3> const &direction,
41 types::Vector<3> const &reference,
42 types::Vector<3> const &variance)
43 : direction_(direction.normalized()), reference_(reference.normalized()), covariance_(variance.asDiagonal())
44 {}
45
46 MeasurementSquareMatrix const &
47 getCovariance(State const & /*s*/)
48 {
49 return covariance_;
50 }
51
52 types::Vector<3>
53 predictMeasurement(State const &s) const
54 {
55 return s.getCombinedQuaternion() * reference_;
56 }
57
58 MeasurementVector
59 getResidual(MeasurementVector const &predictedMeasurement, State const &s) const
60 {
61 return predictedMeasurement - reference_;
62 }
63
64 MeasurementVector
65 getResidual(State const &s) const
66 {
67 return getResidual(predictMeasurement(s), s);
68 }
69
70private:
71 types::Vector<3> direction_;
72 types::Vector<3> reference_;
73 MeasurementSquareMatrix covariance_;
74};
75#if 0
76//! For things like accelerometers, which on some level measure the local vector
77//! of a world direction.
78class LinAccelWithGravityMeasurement
79 : public flexkalman::MeasurementBase<LinAccelWithGravityMeasurement>
80{
81public:
82 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
83 static constexpr size_t Dimension = 3;
84 using MeasurementVector = types::Vector<Dimension>;
85 using MeasurementSquareMatrix = types::SquareMatrix<Dimension>;
86 LinAccelWithGravityMeasurement(types::Vector<3> const &direction,
87 types::Vector<3> const &reference,
88 types::Vector<3> const &variance)
89 : direction_(direction), reference_(reference),
90 covariance_(variance.asDiagonal())
91 {}
92
93 // template <typename State>
94 MeasurementSquareMatrix const &
95 getCovariance(State const & /*s*/)
96 {
97 return covariance_;
98 }
99
100 // template <typename State>
101 types::Vector<3>
102 predictMeasurement(State const &s) const
103 {
104 return reference_;
105 }
106
107 // template <typename State>
108 MeasurementVector
109 getResidual(MeasurementVector const &predictedMeasurement,
110 State const &s) const
111 {
112 s.getQuaternion().conjugate() *
113 predictedMeasurement return predictedMeasurement -
114 reference_.normalized();
115 }
116
117 template <typename State>
118 MeasurementVector
119 getResidual(State const &s) const
120 {
121 MeasurementVector residual =
122 direction_ - reference_ * s.getQuaternion();
123 return getResidual(predictMeasurement(s), s);
124 }
125
126private:
127 types::Vector<3> direction_;
128 types::Vector<3> reference_;
129 MeasurementSquareMatrix covariance_;
130};
131#endif
132
133class BiasedGyroMeasurement : public flexkalman::MeasurementBase<BiasedGyroMeasurement>
134{
135public:
136 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
137 static constexpr size_t Dimension = 3;
138 using MeasurementVector = types::Vector<Dimension>;
139 using MeasurementSquareMatrix = types::SquareMatrix<Dimension>;
140 BiasedGyroMeasurement(types::Vector<3> const &angVel, types::Vector<3> const &variance)
141 : angVel_(angVel), covariance_(variance.asDiagonal())
142 {}
143
144 template <typename State>
145 MeasurementSquareMatrix const &
146 getCovariance(State const & /*s*/)
147 {
148 return covariance_;
149 }
150
151 template <typename State>
152 types::Vector<3>
153 predictMeasurement(State const &s) const
154 {
155 return s.b().stateVector() + angVel_;
156 }
157
158 template <typename State>
159 MeasurementVector
160 getResidual(MeasurementVector const &predictedMeasurement, State const &s) const
161 {
162 return predictedMeasurement - s.a().angularVelocity();
163 }
164
165 template <typename State>
166 MeasurementVector
167 getResidual(State const &s) const
168 {
169 return getResidual(predictMeasurement(s), s);
170 }
171
172private:
173 types::Vector<3> angVel_;
174 MeasurementSquareMatrix covariance_;
175};
176/*!
177 * For PS Move-like things, where there's a directly-computed absolute position
178 * that is not at the tracked body's origin.
179 */
180class AbsolutePositionLeverArmMeasurement : public flexkalman::MeasurementBase<AbsolutePositionLeverArmMeasurement>
181{
182public:
183 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
184 using State = flexkalman::pose_externalized_rotation::State;
185 static constexpr size_t Dimension = 3;
186 using MeasurementVector = types::Vector<Dimension>;
187 using MeasurementSquareMatrix = types::SquareMatrix<Dimension>;
188
189 /*!
190 * @todo the point we get from the camera isn't the center of the ball,
191 * but the center of the visible surface of the ball - a closer
192 * approximation would be translation along the vector to the center of
193 * projection....
194 */
195 AbsolutePositionLeverArmMeasurement(MeasurementVector const &measurement,
196 MeasurementVector const &knownLocationInBodySpace,
197 MeasurementVector const &variance)
198 : measurement_(measurement), knownLocationInBodySpace_(knownLocationInBodySpace),
199 covariance_(variance.asDiagonal())
200 {}
201
202 MeasurementSquareMatrix const &
203 getCovariance(State const & /*s*/)
204 {
205 return covariance_;
206 }
207
208 types::Vector<3>
209 predictMeasurement(State const &s) const
210 {
211 return s.getIsometry() * knownLocationInBodySpace_;
212 }
213
214 MeasurementVector
215 getResidual(MeasurementVector const &predictedMeasurement, State const & /*s*/) const
216 {
217 return measurement_ - predictedMeasurement;
218 }
219
220 MeasurementVector
221 getResidual(State const &s) const
222 {
223 return getResidual(predictMeasurement(s), s);
224 }
225
226private:
227 MeasurementVector measurement_;
228 MeasurementVector knownLocationInBodySpace_;
229 MeasurementSquareMatrix covariance_;
230};
231
232} // namespace xrt::auxiliary::tracking
For PS Move-like things, where there's a directly-computed absolute position that is not at the track...
Definition: t_fusion.hpp:181
AbsolutePositionLeverArmMeasurement(MeasurementVector const &measurement, MeasurementVector const &knownLocationInBodySpace, MeasurementVector const &variance)
Definition: t_fusion.hpp:195
For things like accelerometers, which on some level measure the local vector of a world direction.
Definition: t_fusion.hpp:34