OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
TestIMU_EKF.cpp
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 // Internal Includes
26 #include "TestIMU_Common.h"
27 
28 // Library/third-party includes
29 // - none
30 
31 // Standard includes
32 // - none
33 
34 #if 0
35 CATCH_TYPELIST_DESCRIBED_TESTCASE("identity calibration output", "[.][ekf]", kalman::QFirst,
37  kalman::QLast, kalman::SplitQ) {
38 #endif
39 CATCH_TYPELIST_DESCRIBED_TESTCASE("identity calibration output", "[.][ekf]",
40  kalman::SplitQ,
41  kalman::QLastWithSplitInnovation) {
42  using MeasurementType = OrientationMeasurementUsingPolicy<TypeParam>;
43  using JacobianType = typename MeasurementType::JacobianType;
44  unique_ptr<TestData> data(new TestData);
45  GIVEN("an identity state") {
46  WHEN("filtering in an identity measurement") {
47  Quaterniond xformedMeas = data->xform(Quaterniond::Identity());
48 
49  THEN("the transformed measurement should equal the measurement") {
50  CAPTURE(xformedMeas);
51  REQUIRE(xformedMeas.isApprox(Quaterniond::Identity()));
52 
53  MeasurementType kalmanMeas{xformedMeas, data->imuVariance};
54  AND_THEN("residual should be zero") {
55  CAPTURE(kalmanMeas.getResidual(data->state));
56  REQUIRE(kalmanMeas.getResidual(data->state)
57  .isApproxToConstant(0.));
58  }
59 
60  JacobianType jacobian = kalmanMeas.getJacobian(data->state);
61  AND_THEN("the jacobian should be finite") {
62  INFO("jacobian\n" << jacobian);
63  REQUIRE(jacobian.allFinite());
64  AND_THEN("the jacobian should not be zero") {
65  REQUIRE_FALSE(jacobian.isApproxToConstant(0));
66  }
67  auto correctionInProgress = kalman::beginCorrection(
68  data->state, data->processModel, kalmanMeas);
69  AND_THEN("computed deltaz should be zero") {
70  CAPTURE(correctionInProgress.deltaz.transpose());
71  REQUIRE(
72  correctionInProgress.deltaz.isApproxToConstant(0.));
73  }
74  CAPTURE(correctionInProgress.stateCorrection.transpose());
75  AND_THEN("state correction should be finite") {
76  REQUIRE(correctionInProgress.stateCorrectionFinite);
77  AND_THEN("state correction should be zero") {
78  REQUIRE(correctionInProgress.stateCorrection
79  .isApproxToConstant(0.));
80  }
81  }
82  }
83  }
84  }
85  WHEN("filtering in a small positive rotation about y") {
86  Quaterniond smallPositiveRotationAboutY(
87  AngleAxisd(SMALL_VALUE, Vector3d::UnitY()));
88  CAPTURE(SMALL_VALUE);
89  CAPTURE(smallPositiveRotationAboutY);
90  Quaterniond xformedMeas = data->xform(smallPositiveRotationAboutY);
91  CAPTURE(xformedMeas);
92 
93  THEN("the transformed measurement should equal the measurement") {
94  REQUIRE(xformedMeas.isApprox(smallPositiveRotationAboutY));
96  MeasurementType kalmanMeas{xformedMeas, data->imuVariance};
97  smallPositiveYChecks(data.get(), kalmanMeas);
98  }
99  }
100  }
101  GIVEN("a state rotated about y") {
102  Quaterniond stateRotation(AngleAxisd(M_PI / 4., Vector3d::UnitY()));
103  data->state.setQuaternion(stateRotation);
104  WHEN("filtering in a small positive rotation about y") {
105  Quaterniond smallPositiveRotationAboutY =
106  stateRotation *
107  Quaterniond(AngleAxisd(SMALL_VALUE, Vector3d::UnitY()));
108  CAPTURE(SMALL_VALUE);
109  CAPTURE(smallPositiveRotationAboutY);
110  Quaterniond xformedMeas = data->xform(smallPositiveRotationAboutY);
111  CAPTURE(xformedMeas);
112 
113  THEN("the transformed measurement should equal the measurement") {
114  REQUIRE(xformedMeas.isApprox(smallPositiveRotationAboutY));
115 
117  MeasurementType kalmanMeas{xformedMeas, data->imuVariance};
118  smallPositiveYChecks(data.get(), kalmanMeas);
119  }
120  }
121  }
122  GIVEN("a state rotated about x") {
123  Quaterniond stateRotation(AngleAxisd(M_PI / 4., Vector3d::UnitX()));
124  data->state.setQuaternion(stateRotation);
125  WHEN("filtering in a small positive rotation about y") {
126  Quaterniond smallPositiveRotationAboutY =
127  stateRotation *
128  Quaterniond(AngleAxisd(SMALL_VALUE, Vector3d::UnitY()));
129  CAPTURE(SMALL_VALUE);
130  CAPTURE(smallPositiveRotationAboutY);
131  Quaterniond xformedMeas = data->xform(smallPositiveRotationAboutY);
132  CAPTURE(xformedMeas);
133 
134  THEN("the transformed measurement should equal the measurement") {
135  REQUIRE(xformedMeas.isApprox(smallPositiveRotationAboutY));
136 
138  MeasurementType kalmanMeas{xformedMeas, data->imuVariance};
139  smallPositiveYChecks(data.get(), kalmanMeas);
140  }
141  }
142  }
143 }
void setQuaternion(Eigen::Quaterniond const &quaternion)
Intended for startup use.
Definition: PoseState.h:189
CorrectionInProgress< StateType, MeasurementType > beginCorrection(StateType &state, ProcessModelType &processModel, MeasurementType &meas)
CATCH_TYPELIST_DESCRIBED_TESTCASE("identity calibration output","[.][ekf]", kalman::SplitQ, kalman::QLastWithSplitInnovation)
Definition: TestIMU_EKF.cpp:39
Eigen::Quaterniond xform(Eigen::Quaterniond const &quat)
BodyState state