testPreintegratedRotation.cpp
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9 
10  * -------------------------------------------------------------------------- */
11 
21 
22 #include <memory>
23 
24 #include "gtsam/base/Matrix.h"
25 #include "gtsam/base/Vector.h"
26 
27 using namespace gtsam;
28 
29 //******************************************************************************
30 // Example where gyro measures small rotation about x-axis, with bias.
31 namespace biased_x_rotation {
32 const double omega = 0.1;
33 const Vector3 trueOmega(omega, 0, 0);
34 const Vector3 bias(1, 2, 3);
36 const double deltaT = 0.5;
37 } // namespace biased_x_rotation
38 
39 //******************************************************************************
40 TEST(PreintegratedRotation, integrateGyroMeasurement) {
41  // Example where IMU is identical to body frame, then omega is roll
42  using namespace biased_x_rotation;
43  auto p = std::make_shared<PreintegratedRotationParams>();
44 
45  // Check the value.
46  Matrix3 H_bias;
47  const internal::IncrementalRotation f{measuredOmega, deltaT, p->getBodyPSensor()};
48  const Rot3 incrR = f(bias, H_bias);
49  const Rot3 expected = Rot3::Roll(omega * deltaT);
50  EXPECT(assert_equal(expected, incrR, 1e-9))
51 
52  // Check the derivative:
53  EXPECT(assert_equal(numericalDerivative11<Rot3, Vector3>(f, bias), H_bias))
54 
55  // Check value of deltaRij() after integration.
56  Matrix3 F;
60 
61  // Check that system matrix F is the first derivative of compose:
62  EXPECT(assert_equal<Matrix3>(pim.deltaRij().inverse().AdjointMap(), F))
63 
64  // Make sure delRdelBiasOmega is H_bias after integration.
65  EXPECT(assert_equal<Matrix3>(H_bias, pim.delRdelBiasOmega()))
66 
67  // Check if we make a correction to the bias, the value and Jacobian are
68  // correct. Note that the bias is subtracted from the measurement, and the
69  // integration time is taken into account, so we expect -deltaT*delta change.
70  Matrix3 H;
71  const double delta = 0.05;
72  const Vector3 biasOmegaIncr(delta, 0, 0);
73  Rot3 corrected = pim.biascorrectedDeltaRij(biasOmegaIncr, H);
74  EQUALITY(Vector3(-deltaT * delta, 0, 0), expected.logmap(corrected))
75  EXPECT(assert_equal(Rot3::Roll((omega - delta) * deltaT), corrected, 1e-9))
76 
77  // Check the derivative matches the numerical one
78  auto g = [&](const Vector3& increment) {
79  return pim.biascorrectedDeltaRij(increment, {});
80  };
81  Matrix3 expectedH = numericalDerivative11<Rot3, Vector3>(g, biasOmegaIncr);
82  EXPECT(assert_equal(expectedH, H));
83 
84  // Let's integrate a second IMU measurement and check the Jacobian update:
86  expectedH = numericalDerivative11<Rot3, Vector3>(g, biasOmegaIncr);
87  corrected = pim.biascorrectedDeltaRij(biasOmegaIncr, H);
88  EXPECT(assert_equal(expectedH, H));
89 }
90 
91 //******************************************************************************
92 
93 // Create params where x and y axes are exchanged.
94 static std::shared_ptr<PreintegratedRotationParams> paramsWithTransform() {
95  auto p = std::make_shared<PreintegratedRotationParams>();
96  p->setBodyPSensor({Rot3::Yaw(M_PI_2), {0, 0, 0}});
97  return p;
98 }
99 
100 TEST(PreintegratedRotation, integrateGyroMeasurementWithTransform) {
101  // Example where IMU is rotated, so measured omega indicates pitch.
102  using namespace biased_x_rotation;
103  auto p = paramsWithTransform();
104 
105  // Check the value.
106  Matrix3 H_bias;
107  const internal::IncrementalRotation f{measuredOmega, deltaT, p->getBodyPSensor()};
108  const Rot3 expected = Rot3::Pitch(omega * deltaT); // Pitch, because of sensor-IMU rotation!
109  EXPECT(assert_equal(expected, f(bias, H_bias), 1e-9))
110 
111  // Check the derivative:
112  EXPECT(assert_equal(numericalDerivative11<Rot3, Vector3>(f, bias), H_bias))
113 
114  // Check value of deltaRij() after integration.
115  Matrix3 F;
118  EXPECT(assert_equal(expected, pim.deltaRij(), 1e-9))
119 
120  // Check that system matrix F is the first derivative of compose:
121  EXPECT(assert_equal<Matrix3>(pim.deltaRij().inverse().AdjointMap(), F))
122 
123  // Make sure delRdelBiasOmega is H_bias after integration.
124  EXPECT(assert_equal<Matrix3>(H_bias, pim.delRdelBiasOmega()))
125 
126  // Check the bias correction in same way, but will now yield pitch change.
127  Matrix3 H;
128  const double delta = 0.05;
129  const Vector3 biasOmegaIncr(delta, 0, 0);
130  Rot3 corrected = pim.biascorrectedDeltaRij(biasOmegaIncr, H);
131  EQUALITY(Vector3(0, -deltaT * delta, 0), expected.logmap(corrected))
132  EXPECT(assert_equal(Rot3::Pitch((omega - delta) * deltaT), corrected, 1e-9))
133 
134  // Check the derivative matches the *expectedH* one
135  auto g = [&](const Vector3& increment) {
136  return pim.biascorrectedDeltaRij(increment, {});
137  };
138  Matrix3 expectedH = numericalDerivative11<Rot3, Vector3>(g, biasOmegaIncr);
139  EXPECT(assert_equal(expectedH, H));
140 
141  // Let's integrate a second IMU measurement and check the Jacobian update:
143  corrected = pim.biascorrectedDeltaRij(biasOmegaIncr, H);
144  expectedH = numericalDerivative11<Rot3, Vector3>(g, biasOmegaIncr);
145  EXPECT(assert_equal(expectedH, H));
146 }
147 
148 // Create params we have a non-axis-aligned rotation and even an offset.
149 static std::shared_ptr<PreintegratedRotationParams> paramsWithArbitraryTransform() {
150  auto p = std::make_shared<PreintegratedRotationParams>();
151  p->setBodyPSensor({Rot3::Expmap({1,2,3}), {4,5,6}});
152  return p;
153 }
154 
155 TEST(PreintegratedRotation, integrateGyroMeasurementWithArbitraryTransform) {
156  // Example with a non-axis-aligned transform and some position.
157  using namespace biased_x_rotation;
159 
160  // Check the derivative:
161  Matrix3 H_bias;
162  const internal::IncrementalRotation f{measuredOmega, deltaT, p->getBodyPSensor()};
163  f(bias, H_bias);
164  EXPECT(assert_equal(numericalDerivative11<Rot3, Vector3>(f, bias), H_bias))
165 
166  // Check derivative of deltaRij() after integration.
167  Matrix3 F;
170 
171  // Check that system matrix F is the first derivative of compose:
172  EXPECT(assert_equal<Matrix3>(pim.deltaRij().inverse().AdjointMap(), F))
173 
174  // Make sure delRdelBiasOmega is H_bias after integration.
175  EXPECT(assert_equal<Matrix3>(H_bias, pim.delRdelBiasOmega()))
176 
177  // Check the bias correction in same way, but will now yield pitch change.
178  Matrix3 H;
179  const double delta = 0.05;
180  const Vector3 biasOmegaIncr(delta, 0, 0);
181  Rot3 corrected = pim.biascorrectedDeltaRij(biasOmegaIncr, H);
182 
183  // Check the derivative matches the numerical one
184  auto g = [&](const Vector3& increment) {
185  return pim.biascorrectedDeltaRij(increment, {});
186  };
187  Matrix3 expectedH = numericalDerivative11<Rot3, Vector3>(g, biasOmegaIncr);
188  EXPECT(assert_equal(expectedH, H));
189 
190  // Let's integrate a second IMU measurement and check the Jacobian update:
192  corrected = pim.biascorrectedDeltaRij(biasOmegaIncr, H);
193  expectedH = numericalDerivative11<Rot3, Vector3>(g, biasOmegaIncr);
194  EXPECT(assert_equal(expectedH, H));
195 }
196 
197 //******************************************************************************
198 int main() {
199  TestResult tr;
200  return TestRegistry::runAllTests(tr);
201 }
202 //******************************************************************************
TestRegistry::runAllTests
static int runAllTests(TestResult &result)
Definition: TestRegistry.cpp:27
H
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics set mxtics default set mytics default set mx2tics default set my2tics default set xtics border mirror norotate autofreq set ytics border mirror norotate autofreq set ztics border nomirror norotate autofreq set nox2tics set noy2tics set timestamp bottom norotate set rrange[*:*] noreverse nowriteback set trange[*:*] noreverse nowriteback set urange[*:*] noreverse nowriteback set vrange[*:*] noreverse nowriteback set xlabel matrix size set x2label set timefmt d m y n H
Definition: gnuplot_common_settings.hh:74
gtsam::PreintegratedRotation::delRdelBiasOmega
const Matrix3 & delRdelBiasOmega() const
Definition: PreintegratedRotation.h:166
Vector.h
typedef and functions to augment Eigen's VectorXd
paramsWithTransform
static std::shared_ptr< PreintegratedRotationParams > paramsWithTransform()
Definition: testPreintegratedRotation.cpp:94
e
Array< double, 1, 3 > e(1./3., 0.5, 2.)
EXPECT
#define EXPECT(condition)
Definition: Test.h:150
TestHarness.h
gtsam::PreintegratedRotation::integrateGyroMeasurement
void integrateGyroMeasurement(const Vector3 &measuredOmega, const Vector3 &biasHat, double deltaT, OptionalJacobian< 3, 3 > F={})
Calculate an incremental rotation given the gyro measurement and a time interval, and update both del...
Definition: PreintegratedRotation.cpp:97
Matrix.h
typedef and functions to augment Eigen's MatrixXd
gtsam::PreintegratedRotation::deltaRij
const Rot3 & deltaRij() const
Definition: PreintegratedRotation.h:165
biased_x_rotation::bias
const Vector3 bias(1, 2, 3)
gtsam::Rot3::Yaw
static Rot3 Yaw(double t)
Positive yaw is to right (as in aircraft heading). See ypr.
Definition: Rot3.h:174
gtsam::Vector3
Eigen::Vector3d Vector3
Definition: Vector.h:43
main
int main()
Definition: testPreintegratedRotation.cpp:198
biased_x_rotation::deltaT
const double deltaT
Definition: testPreintegratedRotation.cpp:36
gtsam::Rot3::Roll
static Rot3 Roll(double t)
Definition: Rot3.h:180
EQUALITY
#define EQUALITY(expected, actual)
Definition: Test.h:127
biased_x_rotation::omega
const double omega
Definition: testPreintegratedRotation.cpp:32
biased_x_rotation::trueOmega
const Vector3 trueOmega(omega, 0, 0)
numericalDerivative.h
Some functions to compute numerical derivatives.
biased_x_rotation::measuredOmega
const Vector3 measuredOmega
Definition: testPreintegratedRotation.cpp:35
gtsam.examples.PlanarManipulatorExample.delta
def delta(g0, g1)
Definition: PlanarManipulatorExample.py:45
paramsWithArbitraryTransform
static std::shared_ptr< PreintegratedRotationParams > paramsWithArbitraryTransform()
Definition: testPreintegratedRotation.cpp:149
gtsam::Rot3
Rot3 is a 3D rotation represented as a rotation matrix if the preprocessor symbol GTSAM_USE_QUATERNIO...
Definition: Rot3.h:58
gtsam::Rot3::AdjointMap
Matrix3 AdjointMap() const
Definition: Rot3.h:396
gtsam::Rot3::Pitch
static Rot3 Pitch(double t)
Positive pitch is up (increasing aircraft altitude).See ypr.
Definition: Rot3.h:177
cholesky::expected
Matrix expected
Definition: testMatrix.cpp:971
biased_x_rotation
Definition: testPreintegratedRotation.cpp:31
PreintegratedRotation.h
gtsam::symbol_shorthand::F
Key F(std::uint64_t j)
Definition: inference/Symbol.h:153
gtsam::Rot3::inverse
Rot3 inverse() const
inverse of a rotation
Definition: Rot3.h:308
g
void g(const string &key, int i)
Definition: testBTree.cpp:41
TestResult
Definition: TestResult.h:26
M_PI_2
#define M_PI_2
Definition: mconf.h:118
tree::f
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Definition: testExpression.cpp:218
gtsam
traits
Definition: SFMdata.h:40
gtsam::TEST
TEST(SmartFactorBase, Pinhole)
Definition: testSmartFactorBase.cpp:38
gtsam::PreintegratedRotation
Definition: PreintegratedRotation.h:117
gtsam::Rot3::Expmap
static Rot3 Expmap(const Vector3 &v, OptionalJacobian< 3, 3 > H={})
Definition: Rot3.h:374
p
float * p
Definition: Tutorial_Map_using.cpp:9
gtsam::assert_equal
bool assert_equal(const Matrix &expected, const Matrix &actual, double tol)
Definition: Matrix.cpp:40
gtsam::PreintegratedRotation::biascorrectedDeltaRij
Rot3 biascorrectedDeltaRij(const Vector3 &biasOmegaIncr, OptionalJacobian< 3, 3 > H={}) const
Return a bias corrected version of the integrated rotation.
Definition: PreintegratedRotation.cpp:130


gtsam
Author(s):
autogenerated on Fri Nov 1 2024 03:41:02