OSVR-Core
TestIMU_Common.h
Go to the documentation of this file.
1 
11 // Copyright 2016 Sensics, Inc.
12 //
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 //
17 // http://www.apache.org/licenses/LICENSE-2.0
18 //
19 // Unless required by applicable law or agreed to in writing, software
20 // distributed under the License is distributed on an "AS IS" BASIS,
21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 // See the License for the specific language governing permissions and
23 // limitations under the License.
24 
25 #ifndef INCLUDED_TestIMU_Common_h_GUID_F125CC83_F6D6_4EA5_9281_0DBEC87D309D
26 #define INCLUDED_TestIMU_Common_h_GUID_F125CC83_F6D6_4EA5_9281_0DBEC87D309D
27 
28 // Internal Includes
29 #include "TestIMU.h"
30 
31 #include "ConfigParams.h"
32 #include "IMUStateMeasurements.h"
33 #include "IMUStateMeasurements.h"
34 
35 // Library/third-party includes
36 #include <osvr/Util/Angles.h>
37 
38 // Standard includes
39 #include <iostream>
40 #include <memory>
41 
42 using std::unique_ptr;
43 using namespace osvr;
44 using namespace vbtracker;
45 using namespace Eigen;
46 struct TestData {
49  ConfigParams params;
50 #if 0
51  state.setErrorCovariance(
53 #endif
54 
55  originalStateError = state.errorCovariance();
57  processModel.setDamping(params.linearVelocityDecayCoefficient,
59  processModel.setNoiseAutocorrelation(
61 
63  imuVariance = Eigen::Vector3d::Constant(params.imu.orientationVariance);
64  }
65  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
68 
70  util::Angle yawCorrection = 0;
71 
75  return getTransformedOrientation(quat, roomToCameraRotation,
76  yawCorrection);
77  }
78 
83 
84  BodyProcessModel processModel;
85  Eigen::Vector3d imuVariance;
86 };
87 namespace Eigen {
88 inline void outputQuat(std::ostream &os, Quaterniond const &q) {
89  os << "[" << q.w() << " (" << q.vec().transpose() << ")]";
90 }
91 inline std::ostream &operator<<(std::ostream &os, Quaterniond const &q) {
92  outputQuat(os, q);
93  return os;
94 }
95 } // namespace Eigen
96 
97 namespace Catch {
98 template <> struct TypelistTypeNameTrait<kalman::QFirst> {
99  static const char *get() { return "kalman::QFirst"; }
100 };
101 template <> struct TypelistTypeNameTrait<kalman::QLast> {
102  static const char *get() { return "kalman::QLast"; }
103 };
104 template <> struct TypelistTypeNameTrait<kalman::SplitQ> {
105  static const char *get() { return "kalman::SplitQ"; }
106 };
107 } // namespace Catch
108 
109 static const double SMALL_VALUE = 0.1;
110 
111 template <typename MeasurementType, typename InProgressType>
112 inline void commonSmallPositiveYChecks(TestData *data,
113  MeasurementType &kalmanMeas,
114  InProgressType &inProgress) {
115 
116  Vector3d residual = kalmanMeas.getResidual(data->state);
117 
118  CAPTURE(residual.transpose());
119  AND_THEN("residual directly computed by measurement should be 0, "
120  "SMALL_VALUE, 0") {
121  CHECK(residual.isApprox(Vector3d(0, SMALL_VALUE, 0)));
122  }
123 
124  CAPTURE(inProgress.deltaz.transpose());
125  AND_THEN("computed deltaz should equal residual") {
126  CHECK(residual.isApprox(inProgress.deltaz));
127  }
128 
129  AND_THEN("delta z (residual/propagated mean residual) should be "
130  "approximately 0, SMALL_VALUE, 0") {
131  REQUIRE(inProgress.deltaz[0] == Approx(0.));
132  REQUIRE(inProgress.deltaz[1] == Approx(SMALL_VALUE));
133  REQUIRE(inProgress.deltaz[2] == Approx(0.));
134  }
135 
136  CAPTURE(inProgress.stateCorrection.transpose());
137  AND_THEN("state correction should have a rotation component with small "
138  "positive y") {
139  REQUIRE(inProgress.stateCorrectionFinite);
140  REQUIRE(inProgress.stateCorrection[3] == Approx(0.));
141  REQUIRE(inProgress.stateCorrection[4] > 0);
142  REQUIRE(inProgress.stateCorrection[4] < SMALL_VALUE);
143  REQUIRE(inProgress.stateCorrection[5] == Approx(0.));
144  }
145 
146  AND_THEN("state correction should have an angular velocity component "
147  "with zero or small positive y") {
148  REQUIRE(inProgress.stateCorrection[9] == Approx(0.));
149  REQUIRE(inProgress.stateCorrection[10] >= 0.);
150  REQUIRE(inProgress.stateCorrection[11] == Approx(0.));
151  }
152  AND_THEN("state correction should not contain any translational/linear "
153  "velocity components") {
154  REQUIRE(inProgress.stateCorrection.template head<3>().isZero());
155  REQUIRE(
156  inProgress.stateCorrection.template segment<3>(6).isZero());
157  }
158  AND_WHEN("the correction is applied") {
159  auto errorCovarianceCorrectionWasFinite = inProgress.finishCorrection();
160  THEN("the new error covariance should be finite") {
161  REQUIRE(errorCovarianceCorrectionWasFinite);
162  AND_THEN("State error should have decreased") {
163  REQUIRE((data->state.errorCovariance().array() <=
164  data->originalStateError.array())
165  .all());
166  }
167  }
168  }
169 }
170 
171 template <typename MeasurementType>
172 inline void smallPositiveYChecks(TestData *data, MeasurementType &kalmanMeas) {
173  using JacobianType = typename MeasurementType::JacobianType;
174 
175  JacobianType jacobian = kalmanMeas.getJacobian(data->state);
176  AND_THEN("the jacobian should be finite") {
177  INFO("jacobian\n" << jacobian);
178  REQUIRE(jacobian.allFinite());
179  AND_THEN("the jacobian should not be zero") {
180  REQUIRE_FALSE(jacobian.isZero());
181  }
182  auto inProgress = kalman::beginCorrection(
183  data->state, data->processModel, kalmanMeas);
184  commonSmallPositiveYChecks(data, kalmanMeas, inProgress);
185  }
186 }
187 
188 #endif // INCLUDED_TestIMU_Common_h_GUID_F125CC83_F6D6_4EA5_9281_0DBEC87D309D
AngleRadiansd Angle
Default angle type.
Definition: Angles.h:63
double linearVelocityDecayCoefficient
The value used in exponential decay of linear velocity: it&#39;s the proportion of that velocity remainin...
Definition: ConfigParams.h:151
static Quaternion Identity()
Definition: Quaternion.h:133
double processNoiseAutocorrelation[6]
This is the autocorrelation kernel of the process noise.
Definition: ConfigParams.h:146
The main namespace for all C++ elements of the framework, internal and external.
Definition: namespace_osvr.dox:3
iterative scaling algorithm to equilibrate rows and column norms in matrices
Definition: TestIMU_Common.h:87
Definition: catch_typelist.h:23
const Block< const Coefficients, 3, 1 > vec() const
Definition: Quaternion.h:87
double orientationVariance
units: rad^2
Definition: ConfigParams.h:55
IMUInputParams imu
IMU input-related parameters.
Definition: ConfigParams.h:254
Header.
CorrectionInProgress< StateType, MeasurementType > beginCorrection(StateType &state, ProcessModelType &processModel, MeasurementType &meas)
Definition: FlexibleKalmanCorrect.h:135
Definition: TestIMU_Common.h:46
General configuration parameters.
Definition: ConfigParams.h:82
Can specialize to get better names.
Definition: catch_typelist.h:25
Scalar w() const
Definition: Quaternion.h:75
StateSquareMatrix const & errorCovariance() const
P.
Definition: PoseState.h:183
Eigen::Quaterniond xform(Eigen::Quaterniond const &quat)
Transform the IMU-measured quaternion using the calibration output mocked up in this struct...
Definition: TestIMU_Common.h:74
TestData()
Definition: TestIMU_Common.h:47
Definition: Quaternion.h:47
Definition: catch.hpp:2629
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:127
Header.
BodyState state
Default constructor is no translation, identity rotation, 10 along main diagonal as the state covaria...
Definition: TestIMU_Common.h:81
double angularVelocityDecayCoefficient
The value used in exponential decay of angular velocity: it&#39;s the proportion of that velocity remaini...
Definition: ConfigParams.h:156
A basically-constant-velocity model, with the addition of some damping of the velocities inspired by ...
Definition: PoseSeparatelyDampedConstantVelocity.h:43