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 Ryan Pavlik <ryan.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 
25 namespace xrt_fusion {
26 namespace types = flexkalman::types;
27 using flexkalman::types::Vector;
28 
29 //! For things like accelerometers, which on some level measure the local vector
30 //! of a world direction.
31 template <typename State>
33  : public flexkalman::MeasurementBase<WorldDirectionMeasurement<State>>
34 {
35 public:
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()),
44  reference_(reference.normalized()),
45  covariance_(variance.asDiagonal())
46  {}
47 
48  MeasurementSquareMatrix const &
49  getCovariance(State const & /*s*/)
50  {
51  return covariance_;
52  }
53 
54  types::Vector<3>
55  predictMeasurement(State const &s) const
56  {
57  return s.getCombinedQuaternion() * reference_;
58  }
59 
60  MeasurementVector
61  getResidual(MeasurementVector const &predictedMeasurement,
62  State const &s) const
63  {
64  return predictedMeasurement - reference_;
65  }
66 
67  MeasurementVector
68  getResidual(State const &s) const
69  {
70  return getResidual(predictMeasurement(s), s);
71  }
72 
73 private:
74  types::Vector<3> direction_;
75  types::Vector<3> reference_;
76  MeasurementSquareMatrix covariance_;
77 };
78 #if 0
79 //! For things like accelerometers, which on some level measure the local vector
80 //! of a world direction.
81 class LinAccelWithGravityMeasurement
82  : public flexkalman::MeasurementBase<LinAccelWithGravityMeasurement>
83 {
84 public:
85  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
86  static constexpr size_t Dimension = 3;
87  using MeasurementVector = types::Vector<Dimension>;
88  using MeasurementSquareMatrix = types::SquareMatrix<Dimension>;
89  LinAccelWithGravityMeasurement(types::Vector<3> const &direction,
90  types::Vector<3> const &reference,
91  types::Vector<3> const &variance)
92  : direction_(direction), reference_(reference),
93  covariance_(variance.asDiagonal())
94  {}
95 
96  // template <typename State>
97  MeasurementSquareMatrix const &
98  getCovariance(State const & /*s*/)
99  {
100  return covariance_;
101  }
102 
103  // template <typename State>
104  types::Vector<3>
105  predictMeasurement(State const &s) const
106  {
107  return reference_;
108  }
109 
110  // template <typename State>
111  MeasurementVector
112  getResidual(MeasurementVector const &predictedMeasurement,
113  State const &s) const
114  {
115  s.getQuaternion().conjugate() *
116  predictedMeasurement return predictedMeasurement -
117  reference_.normalized();
118  }
119 
120  template <typename State>
121  MeasurementVector
122  getResidual(State const &s) const
123  {
124  MeasurementVector residual =
125  direction_ - reference_ * s.getQuaternion();
126  return getResidual(predictMeasurement(s), s);
127  }
128 
129 private:
130  types::Vector<3> direction_;
131  types::Vector<3> reference_;
132  MeasurementSquareMatrix covariance_;
133 };
134 #endif
135 
137  : public flexkalman::MeasurementBase<BiasedGyroMeasurement>
138 {
139 public:
140  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
141  static constexpr size_t Dimension = 3;
142  using MeasurementVector = types::Vector<Dimension>;
143  using MeasurementSquareMatrix = types::SquareMatrix<Dimension>;
144  BiasedGyroMeasurement(types::Vector<3> const &angVel,
145  types::Vector<3> const &variance)
146  : angVel_(angVel), covariance_(variance.asDiagonal())
147  {}
148 
149  template <typename State>
150  MeasurementSquareMatrix const &
151  getCovariance(State const & /*s*/)
152  {
153  return covariance_;
154  }
155 
156  template <typename State>
157  types::Vector<3>
158  predictMeasurement(State const &s) const
159  {
160  return s.b().stateVector() + angVel_;
161  }
162 
163  template <typename State>
164  MeasurementVector
165  getResidual(MeasurementVector const &predictedMeasurement,
166  State const &s) const
167  {
168  return predictedMeasurement - s.a().angularVelocity();
169  }
170 
171  template <typename State>
172  MeasurementVector
173  getResidual(State const &s) const
174  {
175  return getResidual(predictMeasurement(s), s);
176  }
177 
178 private:
179  types::Vector<3> angVel_;
180  MeasurementSquareMatrix covariance_;
181 };
182 /*!
183  * For PS Move-like things, where there's a directly-computed absolute position
184  * that is not at the tracked body's origin.
185  */
187  : public flexkalman::MeasurementBase<AbsolutePositionLeverArmMeasurement>
188 {
189 public:
190  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
191  using State = flexkalman::pose_externalized_rotation::State;
192  static constexpr size_t Dimension = 3;
193  using MeasurementVector = types::Vector<Dimension>;
194  using MeasurementSquareMatrix = types::SquareMatrix<Dimension>;
195 
196  /*!
197  * @todo the point we get from the camera isn't the center of the ball,
198  * but the center of the visible surface of the ball - a closer
199  * approximation would be translation along the vector to the center of
200  * projection....
201  */
203  MeasurementVector const &measurement,
204  MeasurementVector const &knownLocationInBodySpace,
205  MeasurementVector const &variance)
206  : measurement_(measurement),
207  knownLocationInBodySpace_(knownLocationInBodySpace),
208  covariance_(variance.asDiagonal())
209  {}
210 
211  MeasurementSquareMatrix const &
212  getCovariance(State const & /*s*/)
213  {
214  return covariance_;
215  }
216 
217  types::Vector<3>
218  predictMeasurement(State const &s) const
219  {
220  return s.getIsometry() * knownLocationInBodySpace_;
221  }
222 
223  MeasurementVector
224  getResidual(MeasurementVector const &predictedMeasurement,
225  State const & /*s*/) const
226  {
227  return measurement_ - predictedMeasurement;
228  }
229 
230  MeasurementVector
231  getResidual(State const &s) const
232  {
233  return getResidual(predictMeasurement(s), s);
234  }
235 
236 private:
237  MeasurementVector measurement_;
238  MeasurementVector knownLocationInBodySpace_;
239  MeasurementSquareMatrix covariance_;
240 };
241 } // namespace xrt_fusion
For PS Move-like things, where there&#39;s a directly-computed absolute position that is not at the track...
Definition: t_fusion.hpp:186
For things like accelerometers, which on some level measure the local vector of a world direction...
Definition: t_fusion.hpp:32
AbsolutePositionLeverArmMeasurement(MeasurementVector const &measurement, MeasurementVector const &knownLocationInBodySpace, MeasurementVector const &variance)
Definition: t_fusion.hpp:202
Definition: t_fusion.hpp:25
Definition: t_fusion.hpp:136