testGPSFactor.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 
20 #include <gtsam/base/Testable.h>
22 
24 
25 #include <GeographicLib/Config.h>
27 
28 using namespace std;
29 using namespace gtsam;
30 using namespace GeographicLib;
31 
32 #if GEOGRAPHICLIB_VERSION_MINOR<37
33 static const auto& kWGS84 = Geocentric::WGS84;
34 #else
35 static const auto& kWGS84 = Geocentric::WGS84();
36 #endif
37 
38 // *************************************************************************
39 namespace example {
40 // ENU Origin is where the plane was in hold next to runway
41 static constexpr double lat0 = 33.86998, lon0 = -84.30626, h0 = 274;
42 
43 // Convert from GPS to ENU
44 static const LocalCartesian origin_ENU(lat0, lon0, h0, kWGS84);
45 
46 // Dekalb-Peachtree Airport runway 2L
47 static constexpr double lat = 33.87071, lon = -84.30482, h = 274;
48 
49 // Random lever arm
50 static const Point3 leverArm(0.1, 0.2, 0.3);
51 } // namespace example
52 
53 // *************************************************************************
54 TEST( GPSFactor, Constructor ) {
55  using namespace example;
56 
57  // From lat-lon to geocentric
58  double E, N, U;
59  origin_ENU.Forward(lat, lon, h, E, N, U);
60  EXPECT_DOUBLES_EQUAL(133.24, E, 1e-2);
61  EXPECT_DOUBLES_EQUAL(80.98, N, 1e-2);
62  EXPECT_DOUBLES_EQUAL(0, U, 1e-2);
63 
64  // Factor
65  Key key(1);
66  SharedNoiseModel model = noiseModel::Isotropic::Sigma(3, 0.25);
68 
69  // Create a linearization point at zero error
70  Pose3 T(Rot3::RzRyRx(0.15, -0.30, 0.45), Point3(E, N, U));
71  EXPECT(assert_equal(Z_3x1,factor.evaluateError(T),1e-5));
72 
73  // Calculate numerical derivatives
74  Matrix expectedH = numericalDerivative11<Vector, Pose3>(
75  [&factor](const Pose3& T) { return factor.evaluateError(T); }, T);
76 
77  // Use the factor to calculate the derivative
78  Matrix actualH;
79  factor.evaluateError(T, actualH);
80 
81  // Verify we get the expected error
82  EXPECT(assert_equal(expectedH, actualH, 1e-8));
83 }
84 
85 // *************************************************************************
86 TEST( GPSFactorArm, Constructor ) {
87  using namespace example;
88 
89  // From lat-lon to geocentric
90  double E, N, U;
91  origin_ENU.Forward(lat, lon, h, E, N, U);
92 
93  // Factor
94  Key key(1);
95  SharedNoiseModel model = noiseModel::Isotropic::Sigma(3, 0.25);
97 
98  // Create a linearization point at zero error
99  const Rot3 nRb = Rot3::RzRyRx(0.15, -0.30, 0.45);
100  const Point3 np = Point3(E, N, U) - nRb * leverArm;
101  Pose3 T(nRb, np);
102  EXPECT(assert_equal(Z_3x1,factor.evaluateError(T),1e-5));
103 
104  // Calculate numerical derivatives
105  Matrix expectedH = numericalDerivative11<Vector, Pose3>(
106  [&factor](const Pose3& T) { return factor.evaluateError(T); }, T);
107 
108  // Use the factor to calculate the derivative
109  Matrix actualH;
110  factor.evaluateError(T, actualH);
111 
112  // Verify we get the expected error
113  EXPECT(assert_equal(expectedH, actualH, 1e-8));
114 }
115 
116 // *************************************************************************
117 TEST( GPSFactorArmCalib, Constructor ) {
118  using namespace example;
119 
120  // From lat-lon to geocentric
121  double E, N, U;
122  origin_ENU.Forward(lat, lon, h, E, N, U);
123 
124  // Factor
125  Key key1(1), key2(2);
126  SharedNoiseModel model = noiseModel::Isotropic::Sigma(3, 0.25);
128 
129  // Create a linearization point at zero error
130  const Rot3 nRb = Rot3::RzRyRx(0.15, -0.30, 0.45);
131  const Point3 np = Point3(E, N, U) - nRb * leverArm;
132  Pose3 T(nRb, np);
133  EXPECT(assert_equal(Z_3x1,factor.evaluateError(T, leverArm),1e-5));
134 
135  // Calculate numerical derivatives
136  Matrix expectedH1 = numericalDerivative11<Vector, Pose3>(
137  [&factor](const Pose3& pose_arg) {
138  return factor.evaluateError(pose_arg, leverArm);
139  },
140  T);
141  Matrix expectedH2 = numericalDerivative11<Vector, Point3>(
142  [&factor, &T](const Point3& point_arg) {
143  return factor.evaluateError(T, point_arg);
144  },
145  leverArm);
146 
147  // Use the factor to calculate the derivative
148  Matrix actualH1, actualH2;
149  factor.evaluateError(T, leverArm, actualH1, actualH2);
150 
151  // Verify we get the expected error
152  EXPECT(assert_equal(expectedH1, actualH1, 1e-8));
153  EXPECT(assert_equal(expectedH2, actualH2, 1e-8));
154 }
155 
156 // *************************************************************************
157 TEST( GPSFactor2, Constructor ) {
158  using namespace example;
159 
160  // From lat-lon to geocentric
161  double E, N, U;
162  origin_ENU.Forward(lat, lon, h, E, N, U);
163 
164  // Factor
165  Key key(1);
166  SharedNoiseModel model = noiseModel::Isotropic::Sigma(3, 0.25);
168 
169  // Create a linearization point at zero error
170  NavState T(Rot3::RzRyRx(0.15, -0.30, 0.45), Point3(E, N, U), Vector3::Zero());
171  EXPECT(assert_equal(Z_3x1,factor.evaluateError(T),1e-5));
172 
173  // Calculate numerical derivatives
174  Matrix expectedH = numericalDerivative11<Vector, NavState>(
175  [&factor](const NavState& T) { return factor.evaluateError(T); }, T);
176 
177  // Use the factor to calculate the derivative
178  Matrix actualH;
179  factor.evaluateError(T, actualH);
180 
181  // Verify we get the expected error
182  EXPECT(assert_equal(expectedH, actualH, 1e-8));
183 }
184 
185 // *************************************************************************
186 TEST( GPSFactor2Arm, Constructor ) {
187  using namespace example;
188 
189  // From lat-lon to geocentric
190  double E, N, U;
191  origin_ENU.Forward(lat, lon, h, E, N, U);
192 
193  // Factor
194  Key key(1);
195  SharedNoiseModel model = noiseModel::Isotropic::Sigma(3, 0.25);
197 
198  // Create a linearization point at zero error
199  const Rot3 nRb = Rot3::RzRyRx(0.15, -0.30, 0.45);
200  const Point3 np = Point3(E, N, U) - nRb * leverArm;
201  NavState T(nRb, np, Vector3::Zero());
202  EXPECT(assert_equal(Z_3x1,factor.evaluateError(T),1e-5));
203 
204  // Calculate numerical derivatives
205  Matrix expectedH = numericalDerivative11<Vector, NavState>(
206  [&factor](const NavState& T) { return factor.evaluateError(T); }, T);
207 
208  // Use the factor to calculate the derivative
209  Matrix actualH;
210  factor.evaluateError(T, actualH);
211 
212  // Verify we get the expected error
213  EXPECT(assert_equal(expectedH, actualH, 1e-8));
214 }
215 
216 // *************************************************************************
217 TEST( GPSFactor2ArmCalib, Constructor ) {
218  using namespace example;
219 
220  // From lat-lon to geocentric
221  double E, N, U;
222  origin_ENU.Forward(lat, lon, h, E, N, U);
223 
224  // Factor
225  Key key1(1), key2(2);
226  SharedNoiseModel model = noiseModel::Isotropic::Sigma(3, 0.25);
228 
229  // Create a linearization point at zero error
230  const Rot3 nRb = Rot3::RzRyRx(0.15, -0.30, 0.45);
231  const Point3 np = Point3(E, N, U) - nRb * leverArm;
232  NavState T(nRb, np, Vector3::Zero());
233  EXPECT(assert_equal(Z_3x1,factor.evaluateError(T, leverArm),1e-5));
234 
235  // Calculate numerical derivatives
236  Matrix expectedH1 = numericalDerivative11<Vector, NavState>(
237  [&factor](const NavState& nav_arg) {
238  return factor.evaluateError(nav_arg, leverArm);
239  },
240  T);
241  Matrix expectedH2 = numericalDerivative11<Vector, Point3>(
242  [&factor, &T](const Point3& point_arg) {
243  return factor.evaluateError(T, point_arg);
244  },
245  leverArm);
246 
247  // Use the factor to calculate the derivative
248  Matrix actualH1, actualH2;
249  factor.evaluateError(T, leverArm, actualH1, actualH2);
250 
251  // Verify we get the expected error
252  EXPECT(assert_equal(expectedH1, actualH1, 1e-8));
253  EXPECT(assert_equal(expectedH2, actualH2, 1e-8));
254 }
255 
256 //***************************************************************************
257 TEST(GPSData, init) {
258 
259  // GPS Reading 1 will be ENU origin
260  double t1 = 84831;
261  Point3 NED1(0, 0, 0);
262  LocalCartesian enu(35.4393283333333, -119.062986666667, 275.54, kWGS84);
263 
264  // GPS Readin 2
265  double t2 = 84831.5;
266  double E, N, U;
267  enu.Forward(35.4394633333333, -119.063146666667, 276.52, E, N, U);
268  Point3 NED2(N, E, -U);
269 
270  // Estimate initial state
271  const auto [T, nV] = GPSFactor::EstimateState(t1, NED1, t2, NED2, 84831.0796);
272 
273  // Check values values
274  EXPECT(assert_equal((Vector )Vector3(29.9575, -29.0564, -1.95993), nV, 1e-4));
275  EXPECT( assert_equal(Rot3::Ypr(-0.770131, 0.046928, 0), T.rotation(), 1e-5));
276  Point3 expectedT(2.38461, -2.31289, -0.156011);
277  EXPECT(assert_equal(expectedT, T.translation(), 1e-5));
278 }
279 
280 // *************************************************************************
281 int main() {
282  TestResult tr;
283  return TestRegistry::runAllTests(tr);
284 }
285 // *************************************************************************
key1
const Symbol key1('v', 1)
gtsam::GPSFactorArm
Definition: GPSFactor.h:124
TestRegistry::runAllTests
static int runAllTests(TestResult &result)
Definition: TestRegistry.cpp:27
gtsam::GPSFactorArmCalib
Definition: GPSFactor.h:196
e
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Testable.h
Concept check for values that can be used in unit tests.
EXPECT
#define EXPECT(condition)
Definition: Test.h:150
GeographicLib
Namespace for GeographicLib.
Definition: JacobiConformal.hpp:15
gtsam::Z_3x1
static const Eigen::MatrixBase< Vector3 >::ConstantReturnType Z_3x1
Definition: Vector.h:47
TestHarness.h
example::origin_ENU
static const LocalCartesian origin_ENU(lat0, lon0, h0, kWGS84)
GeographicLib::LocalCartesian::Forward
void Forward(real lat, real lon, real h, real &x, real &y, real &z) const
Definition: LocalCartesian.hpp:104
test_eigen.np
np
Definition: test_eigen.py:5
example::lon0
static constexpr double lon0
Definition: testGPSFactor.cpp:41
kWGS84
static const auto & kWGS84
Definition: testGPSFactor.cpp:33
gtsam::NavState
Definition: NavState.h:38
T
Eigen::Triplet< double > T
Definition: Tutorial_sparse_example.cpp:6
gtsam::Matrix
Eigen::MatrixXd Matrix
Definition: base/Matrix.h:39
initial::nRb
const Rot3 nRb
Definition: testScenarioRunner.cpp:149
gtsam::Vector3
Eigen::Vector3d Vector3
Definition: Vector.h:44
h
const double h
Definition: testSimpleHelicopter.cpp:19
gtsam::Vector
Eigen::VectorXd Vector
Definition: Vector.h:39
pruning_fixture::factor
DecisionTreeFactor factor(D &C &B &A, "0.0 0.0 0.0 0.60658897 0.61241912 0.61241969 0.61247685 0.61247742 0.0 " "0.0 0.0 0.99995287 1.0 1.0 1.0 1.0")
example
Definition: testOrdering.cpp:28
main
int main()
Definition: testGPSFactor.cpp:281
numericalDerivative.h
Some functions to compute numerical derivatives.
example::lat0
static constexpr double lat0
Definition: testGPSFactor.cpp:41
key2
const Symbol key2('v', 2)
gtsam::Rot3
Rot3 is a 3D rotation represented as a rotation matrix if the preprocessor symbol GTSAM_USE_QUATERNIO...
Definition: Rot3.h:58
gtsam::Pose3
Definition: Pose3.h:37
gtsam::SharedNoiseModel
noiseModel::Base::shared_ptr SharedNoiseModel
Definition: NoiseModel.h:762
Eigen::Triplet< double >
model
noiseModel::Diagonal::shared_ptr model
Definition: doc/Code/Pose2SLAMExample.cpp:7
EXPECT_DOUBLES_EQUAL
#define EXPECT_DOUBLES_EQUAL(expected, actual, threshold)
Definition: Test.h:161
TestResult
Definition: TestResult.h:26
key
const gtsam::Symbol key('X', 0)
E
DiscreteKey E(5, 2)
Config.h
gtsam
traits
Definition: SFMdata.h:40
std
Definition: BFloat16.h:88
LocalCartesian.hpp
Header for GeographicLib::LocalCartesian class.
GeographicLib::LocalCartesian
Local cartesian coordinates.
Definition: LocalCartesian.hpp:38
TEST
TEST(GPSFactor, Constructor)
Definition: testGPSFactor.cpp:54
gtsam::GPSFactor2Arm
Definition: GPSFactor.h:337
gtsam::assert_equal
bool assert_equal(const Matrix &expected, const Matrix &actual, double tol)
Definition: Matrix.cpp:41
gtsam::GPSFactor2ArmCalib
Definition: GPSFactor.h:408
gtsam::Point3
Vector3 Point3
Definition: Point3.h:38
U
@ U
Definition: testDecisionTree.cpp:342
gtsam::GPSFactor2
Definition: GPSFactor.h:260
N
#define N
Definition: igam.h:9
lon
static const double lon
Definition: testGeographicLib.cpp:34
example::leverArm
static const Point3 leverArm(0.1, 0.2, 0.3)
screwPose2::expectedT
Point2 expectedT(-0.0446635, 0.29552)
gtsam::Key
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:97
init
Definition: TutorialInplaceLU.cpp:2
GPSFactor.h
Header file for GPS factor.
example::h0
static constexpr double h0
Definition: testGPSFactor.cpp:41
gtsam::GPSFactor
Definition: GPSFactor.h:37
lat
static const double lat
Definition: testGeographicLib.cpp:34


gtsam
Author(s):
autogenerated on Fri Mar 7 2025 04:07:08