testPose3.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 
17 #include <gtsam/geometry/Pose3.h>
18 #include <gtsam/geometry/Pose2.h>
19 #include <gtsam/base/testLie.h>
20 #include <gtsam/base/lieProxies.h>
22 
23 
25 #include <cmath>
26 #include <functional>
27 
28 using namespace std;
29 using namespace gtsam;
30 using namespace std::placeholders;
31 
34 
35 static const Point3 P(0.2,0.7,-2);
36 static const Rot3 R = Rot3::Rodrigues(0.3,0,0);
37 static const Point3 P2(3.5,-8.2,4.2);
38 static const Pose3 T(R,P2);
39 static const Pose3 T2(Rot3::Rodrigues(0.3,0.2,0.1),P2);
40 static const Pose3 T3(Rot3::Rodrigues(-90, 0, 0), Point3(1, 2, 3));
41 static const double tol=1e-5;
42 
43 /* ************************************************************************* */
45 {
46  Pose3 pose2 = T3;
48  Pose3 origin;
50 }
51 
52 /* ************************************************************************* */
53 TEST( Pose3, constructors)
54 {
55  Pose3 expected(Rot3::Rodrigues(0,0,3),Point3(1,2,0));
56  Pose2 pose2(1,2,3);
58 }
59 
60 /* ************************************************************************* */
61 #ifndef GTSAM_POSE3_EXPMAP
62 TEST( Pose3, retract_first_order)
63 {
64  Pose3 id;
65  Vector v = Z_6x1;
66  v(0) = 0.3;
67  EXPECT(assert_equal(Pose3(R, Point3(0,0,0)), id.retract(v),1e-2));
68  v(3)=0.2;v(4)=0.7;v(5)=-2;
69  EXPECT(assert_equal(Pose3(R, P),id.retract(v),1e-2));
70 }
71 #endif
72 /* ************************************************************************* */
73 TEST( Pose3, retract_expmap)
74 {
75  Vector v = Z_6x1; v(0) = 0.3;
77  EXPECT(assert_equal(Pose3(R, Point3(0,0,0)), pose, 1e-2));
78  EXPECT(assert_equal(v,Pose3::Logmap(pose),1e-2));
79 }
80 
81 /* ************************************************************************* */
82 TEST( Pose3, expmap_a_full)
83 {
84  Pose3 id;
85  Vector v = Z_6x1;
86  v(0) = 0.3;
87  EXPECT(assert_equal(expmap_default<Pose3>(id, v), Pose3(R, Point3(0,0,0))));
88  v(3)=0.2;v(4)=0.394742;v(5)=-2.08998;
89  EXPECT(assert_equal(Pose3(R, P),expmap_default<Pose3>(id, v),1e-5));
90 }
91 
92 /* ************************************************************************* */
93 TEST( Pose3, expmap_a_full2)
94 {
95  Pose3 id;
96  Vector v = Z_6x1;
97  v(0) = 0.3;
98  EXPECT(assert_equal(expmap_default<Pose3>(id, v), Pose3(R, Point3(0,0,0))));
99  v(3)=0.2;v(4)=0.394742;v(5)=-2.08998;
100  EXPECT(assert_equal(Pose3(R, P),expmap_default<Pose3>(id, v),1e-5));
101 }
102 
103 /* ************************************************************************* */
104 TEST(Pose3, expmap_b)
105 {
106  Pose3 p1(Rot3(), Point3(100, 0, 0));
107  Pose3 p2 = p1.retract((Vector(6) << 0.0, 0.0, 0.1, 0.0, 0.0, 0.0).finished());
108  Pose3 expected(Rot3::Rodrigues(0.0, 0.0, 0.1), Point3(100.0, 0.0, 0.0));
110 }
111 
112 /* ************************************************************************* */
113 // test case for screw motion in the plane
114 namespace screwPose3 {
115  double a=0.3, c=cos(a), s=sin(a), w=0.3;
116  Vector xi = (Vector(6) << 0.0, 0.0, w, w, 0.0, 1.0).finished();
117  Rot3 expectedR(c, -s, 0, s, c, 0, 0, 0, 1);
118  Point3 expectedT(0.29552, 0.0446635, 1);
120 }
121 
122 /* ************************************************************************* */
123 // Checks correct exponential map (Expmap) with brute force matrix exponential
124 TEST(Pose3, expmap_c_full)
125 {
128 }
129 
130 /* ************************************************************************* */
131 // assert that T*exp(xi)*T^-1 is equal to exp(Ad_T(xi))
132 TEST(Pose3, Adjoint_full)
133 {
134  Pose3 expected = T * Pose3::Expmap(screwPose3::xi) * T.inverse();
135  Vector xiprime = T.Adjoint(screwPose3::xi);
136  EXPECT(assert_equal(expected, Pose3::Expmap(xiprime), 1e-6));
137 
138  Pose3 expected2 = T2 * Pose3::Expmap(screwPose3::xi) * T2.inverse();
139  Vector xiprime2 = T2.Adjoint(screwPose3::xi);
140  EXPECT(assert_equal(expected2, Pose3::Expmap(xiprime2), 1e-6));
141 
142  Pose3 expected3 = T3 * Pose3::Expmap(screwPose3::xi) * T3.inverse();
143  Vector xiprime3 = T3.Adjoint(screwPose3::xi);
144  EXPECT(assert_equal(expected3, Pose3::Expmap(xiprime3), 1e-6));
145 }
146 
147 /* ************************************************************************* */
148 // Check Adjoint numerical derivatives
149 TEST(Pose3, Adjoint_jacobians)
150 {
151  Vector6 xi = (Vector6() << 0.1, 1.2, 2.3, 3.1, 1.4, 4.5).finished();
152 
153  // Check evaluation sanity check
154  EQUALITY(static_cast<gtsam::Vector>(T.AdjointMap() * xi), T.Adjoint(xi));
155  EQUALITY(static_cast<gtsam::Vector>(T2.AdjointMap() * xi), T2.Adjoint(xi));
156  EQUALITY(static_cast<gtsam::Vector>(T3.AdjointMap() * xi), T3.Adjoint(xi));
157 
158  // Check jacobians
159  Matrix6 actualH1, actualH2, expectedH1, expectedH2;
160  std::function<Vector6(const Pose3&, const Vector6&)> Adjoint_proxy =
161  [&](const Pose3& T, const Vector6& xi) { return T.Adjoint(xi); };
162 
163  T.Adjoint(xi, actualH1, actualH2);
164  expectedH1 = numericalDerivative21(Adjoint_proxy, T, xi);
165  expectedH2 = numericalDerivative22(Adjoint_proxy, T, xi);
166  EXPECT(assert_equal(expectedH1, actualH1));
167  EXPECT(assert_equal(expectedH2, actualH2));
168 
169  T2.Adjoint(xi, actualH1, actualH2);
170  expectedH1 = numericalDerivative21(Adjoint_proxy, T2, xi);
171  expectedH2 = numericalDerivative22(Adjoint_proxy, T2, xi);
172  EXPECT(assert_equal(expectedH1, actualH1));
173  EXPECT(assert_equal(expectedH2, actualH2));
174 
175  T3.Adjoint(xi, actualH1, actualH2);
176  expectedH1 = numericalDerivative21(Adjoint_proxy, T3, xi);
177  expectedH2 = numericalDerivative22(Adjoint_proxy, T3, xi);
178  EXPECT(assert_equal(expectedH1, actualH1));
179  EXPECT(assert_equal(expectedH2, actualH2));
180 }
181 
182 /* ************************************************************************* */
183 // Check AdjointTranspose and jacobians
184 TEST(Pose3, AdjointTranspose)
185 {
186  Vector6 xi = (Vector6() << 0.1, 1.2, 2.3, 3.1, 1.4, 4.5).finished();
187 
188  // Check evaluation
189  EQUALITY(static_cast<Vector>(T.AdjointMap().transpose() * xi),
190  T.AdjointTranspose(xi));
191  EQUALITY(static_cast<Vector>(T2.AdjointMap().transpose() * xi),
193  EQUALITY(static_cast<Vector>(T3.AdjointMap().transpose() * xi),
195 
196  // Check jacobians
197  Matrix6 actualH1, actualH2, expectedH1, expectedH2;
198  std::function<Vector6(const Pose3&, const Vector6&)> AdjointTranspose_proxy =
199  [&](const Pose3& T, const Vector6& xi) {
200  return T.AdjointTranspose(xi);
201  };
202 
203  T.AdjointTranspose(xi, actualH1, actualH2);
204  expectedH1 = numericalDerivative21(AdjointTranspose_proxy, T, xi);
205  expectedH2 = numericalDerivative22(AdjointTranspose_proxy, T, xi);
206  EXPECT(assert_equal(expectedH1, actualH1, 1e-8));
207  EXPECT(assert_equal(expectedH2, actualH2));
208 
209  T2.AdjointTranspose(xi, actualH1, actualH2);
210  expectedH1 = numericalDerivative21(AdjointTranspose_proxy, T2, xi);
211  expectedH2 = numericalDerivative22(AdjointTranspose_proxy, T2, xi);
212  EXPECT(assert_equal(expectedH1, actualH1, 1e-8));
213  EXPECT(assert_equal(expectedH2, actualH2));
214 
215  T3.AdjointTranspose(xi, actualH1, actualH2);
216  expectedH1 = numericalDerivative21(AdjointTranspose_proxy, T3, xi);
217  expectedH2 = numericalDerivative22(AdjointTranspose_proxy, T3, xi);
218  EXPECT(assert_equal(expectedH1, actualH1, 1e-8));
219  EXPECT(assert_equal(expectedH2, actualH2));
220 }
221 
222 /* ************************************************************************* */
223 // assert that T*wedge(xi)*T^-1 is equal to wedge(Ad_T(xi))
224 TEST(Pose3, Adjoint_hat)
225 {
226  auto hat = [](const Vector& xi) { return ::wedge<Pose3>(xi); };
227  Matrix4 expected = T.matrix() * hat(screwPose3::xi) * T.matrix().inverse();
228  Matrix4 xiprime = hat(T.Adjoint(screwPose3::xi));
229  EXPECT(assert_equal(expected, xiprime, 1e-6));
230 
231  Matrix4 expected2 = T2.matrix() * hat(screwPose3::xi) * T2.matrix().inverse();
232  Matrix4 xiprime2 = hat(T2.Adjoint(screwPose3::xi));
233  EXPECT(assert_equal(expected2, xiprime2, 1e-6));
234 
235  Matrix4 expected3 = T3.matrix() * hat(screwPose3::xi) * T3.matrix().inverse();
236  Matrix4 xiprime3 = hat(T3.Adjoint(screwPose3::xi));
237  EXPECT(assert_equal(expected3, xiprime3, 1e-6));
238 }
239 
240 /* ************************************************************************* */
243  Vector w = xi.head(3);
244  Vector v = xi.tail(3);
245  double t = w.norm();
246  if (t < 1e-5)
247  return Pose3(Rot3(), Point3(v));
248  else {
249  Matrix W = skewSymmetric(w/t);
250  Matrix A = I_3x3 + ((1 - cos(t)) / t) * W + ((t - sin(t)) / t) * (W * W);
251  return Pose3(Rot3::Expmap (w), Point3(A * v));
252  }
253 }
254 
255 /* ************************************************************************* */
256 TEST(Pose3, expmaps_galore_full)
257 {
258  Vector xi; Pose3 actual;
259  xi = (Vector(6) << 0.1, 0.2, 0.3, 0.4, 0.5, 0.6).finished();
260  actual = Pose3::Expmap(xi);
261  EXPECT(assert_equal(expm<Pose3>(xi), actual,1e-6));
262  EXPECT(assert_equal(Agrawal06iros(xi), actual,1e-6));
263  EXPECT(assert_equal(xi, Pose3::Logmap(actual),1e-6));
264 
265  xi = (Vector(6) << 0.1, -0.2, 0.3, -0.4, 0.5, -0.6).finished();
266  for (double theta=1.0;0.3*theta<=M_PI;theta*=2) {
267  Vector txi = xi*theta;
268  actual = Pose3::Expmap(txi);
269  EXPECT(assert_equal(expm<Pose3>(txi,30), actual,1e-6));
270  EXPECT(assert_equal(Agrawal06iros(txi), actual,1e-6));
271  Vector log = Pose3::Logmap(actual);
272  EXPECT(assert_equal(actual, Pose3::Expmap(log),1e-6));
273  EXPECT(assert_equal(txi,log,1e-6)); // not true once wraps
274  }
275 
276  // Works with large v as well, but expm needs 10 iterations!
277  xi = (Vector(6) << 0.2, 0.3, -0.8, 100.0, 120.0, -60.0).finished();
278  actual = Pose3::Expmap(xi);
279  EXPECT(assert_equal(expm<Pose3>(xi,10), actual,1e-5));
280  EXPECT(assert_equal(Agrawal06iros(xi), actual,1e-9));
281  EXPECT(assert_equal(xi, Pose3::Logmap(actual),1e-9));
282 }
283 
284 /* ************************************************************************* */
285 // Check translation and its pushforward
287  Matrix actualH;
288  EXPECT(assert_equal(Point3(3.5, -8.2, 4.2), T.translation(actualH), 1e-8));
289 
290  std::function<Point3(const Pose3&)> f = [](const Pose3& T) { return T.translation(); };
291  Matrix numericalH = numericalDerivative11<Point3, Pose3>(f, T);
292  EXPECT(assert_equal(numericalH, actualH, 1e-6));
293 }
294 
295 /* ************************************************************************* */
296 // Check rotation and its pushforward
298  Matrix actualH;
299  EXPECT(assert_equal(R, T.rotation(actualH), 1e-8));
300 
301  std::function<Rot3(const Pose3&)> f = [](const Pose3& T) { return T.rotation(); };
302  Matrix numericalH = numericalDerivative11<Rot3, Pose3>(f, T);
303  EXPECT(assert_equal(numericalH, actualH, 1e-6));
304 }
305 
306 /* ************************************************************************* */
307 TEST(Pose3, Adjoint_compose_full)
308 {
309  // To debug derivatives of compose, assert that
310  // T1*T2*exp(Adjoint(inv(T2),x) = T1*exp(x)*T2
311  const Pose3& T1 = T;
312  Vector x = (Vector(6) << 0.1, 0.1, 0.1, 0.4, 0.2, 0.8).finished();
314  Vector y = T2.inverse().Adjoint(x);
315  Pose3 actual = T1 * T2 * Pose3::Expmap(y);
316  EXPECT(assert_equal(expected, actual, 1e-6));
317 }
318 
319 /* ************************************************************************* */
320 // Check compose and its pushforward
321 // NOTE: testing::compose<Pose3>(t1,t2) = t1.compose(t2) (see lieProxies.h)
323 {
324  Matrix actual = (T2*T2).matrix();
326  EXPECT(assert_equal(actual,expected,1e-8));
327 
328  Matrix actualDcompose1, actualDcompose2;
329  T2.compose(T2, actualDcompose1, actualDcompose2);
330 
331  Matrix numericalH1 = numericalDerivative21(testing::compose<Pose3>, T2, T2);
332  EXPECT(assert_equal(numericalH1,actualDcompose1,5e-3));
333  EXPECT(assert_equal(T2.inverse().AdjointMap(),actualDcompose1,5e-3));
334 
335  Matrix numericalH2 = numericalDerivative22(testing::compose<Pose3>, T2, T2);
336  EXPECT(assert_equal(numericalH2,actualDcompose2,1e-4));
337 }
338 
339 /* ************************************************************************* */
340 // Check compose and its pushforward, another case
341 TEST( Pose3, compose2 )
342 {
343  const Pose3& T1 = T;
344  Matrix actual = (T1*T2).matrix();
346  EXPECT(assert_equal(actual,expected,1e-8));
347 
348  Matrix actualDcompose1, actualDcompose2;
349  T1.compose(T2, actualDcompose1, actualDcompose2);
350 
351  Matrix numericalH1 = numericalDerivative21(testing::compose<Pose3>, T1, T2);
352  EXPECT(assert_equal(numericalH1,actualDcompose1,5e-3));
353  EXPECT(assert_equal(T2.inverse().AdjointMap(),actualDcompose1,5e-3));
354 
355  Matrix numericalH2 = numericalDerivative22(testing::compose<Pose3>, T1, T2);
356  EXPECT(assert_equal(numericalH2,actualDcompose2,1e-5));
357 }
358 
359 /* ************************************************************************* */
361 {
362  Matrix actualDinverse;
363  Matrix actual = T.inverse(actualDinverse).matrix();
364  Matrix expected = T.matrix().inverse();
365  EXPECT(assert_equal(actual,expected,1e-8));
366 
367  Matrix numericalH = numericalDerivative11(testing::inverse<Pose3>, T);
368  EXPECT(assert_equal(numericalH,actualDinverse,5e-3));
369  EXPECT(assert_equal(-T.AdjointMap(),actualDinverse,5e-3));
370 }
371 
372 /* ************************************************************************* */
373 TEST( Pose3, inverseDerivatives2)
374 {
375  Rot3 R = Rot3::Rodrigues(0.3,0.4,-0.5);
376  Point3 t(3.5,-8.2,4.2);
377  Pose3 T(R,t);
378 
379  Matrix numericalH = numericalDerivative11(testing::inverse<Pose3>, T);
380  Matrix actualDinverse;
381  T.inverse(actualDinverse);
382  EXPECT(assert_equal(numericalH,actualDinverse,5e-3));
383  EXPECT(assert_equal(-T.AdjointMap(),actualDinverse,5e-3));
384 }
385 
386 /* ************************************************************************* */
387 TEST( Pose3, compose_inverse)
388 {
389  Matrix actual = (T*T.inverse()).matrix();
390  Matrix expected = I_4x4;
391  EXPECT(assert_equal(actual,expected,1e-8));
392 }
393 
394 /* ************************************************************************* */
396  return pose.transformFrom(point);
397 }
398 TEST(Pose3, Dtransform_from1_a) {
399  Matrix actualDtransform_from1;
400  T.transformFrom(P, actualDtransform_from1, {});
402  EXPECT(assert_equal(numerical, actualDtransform_from1, 1e-8));
403 }
404 
405 TEST(Pose3, Dtransform_from1_b) {
406  Pose3 origin;
407  Matrix actualDtransform_from1;
408  origin.transformFrom(P, actualDtransform_from1, {});
410  EXPECT(assert_equal(numerical, actualDtransform_from1, 1e-8));
411 }
412 
413 TEST(Pose3, Dtransform_from1_c) {
414  Point3 origin(0, 0, 0);
415  Pose3 T0(R, origin);
416  Matrix actualDtransform_from1;
417  T0.transformFrom(P, actualDtransform_from1, {});
418  Matrix numerical = numericalDerivative21(transformFrom_, T0, P);
419  EXPECT(assert_equal(numerical, actualDtransform_from1, 1e-8));
420 }
421 
422 TEST(Pose3, Dtransform_from1_d) {
423  Rot3 I;
424  Point3 t0(100, 0, 0);
425  Pose3 T0(I, t0);
426  Matrix actualDtransform_from1;
427  T0.transformFrom(P, actualDtransform_from1, {});
428  // print(computed, "Dtransform_from1_d computed:");
429  Matrix numerical = numericalDerivative21(transformFrom_, T0, P);
430  // print(numerical, "Dtransform_from1_d numerical:");
431  EXPECT(assert_equal(numerical, actualDtransform_from1, 1e-8));
432 }
433 
434 /* ************************************************************************* */
435 TEST(Pose3, Dtransform_from2) {
436  Matrix actualDtransform_from2;
437  T.transformFrom(P, {}, actualDtransform_from2);
439  EXPECT(assert_equal(numerical, actualDtransform_from2, 1e-8));
440 }
441 
442 /* ************************************************************************* */
444  return pose.transformTo(point);
445 }
446 TEST(Pose3, Dtransform_to1) {
447  Matrix computed;
448  T.transformTo(P, computed, {});
450  EXPECT(assert_equal(numerical, computed, 1e-8));
451 }
452 
453 /* ************************************************************************* */
454 TEST(Pose3, Dtransform_to2) {
455  Matrix computed;
456  T.transformTo(P, {}, computed);
458  EXPECT(assert_equal(numerical, computed, 1e-8));
459 }
460 
461 /* ************************************************************************* */
462 TEST(Pose3, transform_to_with_derivatives) {
463  Matrix actH1, actH2;
464  T.transformTo(P, actH1, actH2);
467  EXPECT(assert_equal(expH1, actH1, 1e-8));
468  EXPECT(assert_equal(expH2, actH2, 1e-8));
469 }
470 
471 /* ************************************************************************* */
472 TEST(Pose3, transform_from_with_derivatives) {
473  Matrix actH1, actH2;
474  T.transformFrom(P, actH1, actH2);
477  EXPECT(assert_equal(expH1, actH1, 1e-8));
478  EXPECT(assert_equal(expH2, actH2, 1e-8));
479 }
480 
481 /* ************************************************************************* */
482 TEST(Pose3, transform_to_translate) {
483  Point3 actual =
484  Pose3(Rot3(), Point3(1, 2, 3)).transformTo(Point3(10., 20., 30.));
485  Point3 expected(9., 18., 27.);
486  EXPECT(assert_equal(expected, actual));
487 }
488 
489 /* ************************************************************************* */
490 TEST(Pose3, transform_to_rotate) {
491  Pose3 transform(Rot3::Rodrigues(0, 0, -1.570796), Point3(0, 0, 0));
492  Point3 actual = transform.transformTo(Point3(2, 1, 10));
493  Point3 expected(-1, 2, 10);
494  EXPECT(assert_equal(expected, actual, 0.001));
495 }
496 
497 /* ************************************************************************* */
498 // Check transformPoseFrom and its pushforward
499 Pose3 transformPoseFrom_(const Pose3& wTa, const Pose3& aTb) {
500  return wTa.transformPoseFrom(aTb);
501 }
502 
503 TEST(Pose3, transformPoseFrom)
504 {
505  Matrix actual = (T2*T2).matrix();
507  EXPECT(assert_equal(actual, expected, 1e-8));
508 
509  Matrix H1, H2;
510  T2.transformPoseFrom(T2, H1, H2);
511 
513  EXPECT(assert_equal(numericalH1, H1, 5e-3));
514  EXPECT(assert_equal(T2.inverse().AdjointMap(), H1, 5e-3));
515 
517  EXPECT(assert_equal(numericalH2, H2, 1e-4));
518 }
519 
520 /* ************************************************************************* */
522  Pose3 transform(Rot3::Rodrigues(0, 0, -1.570796), Point3(2, 4, 0));
523  Point3 actual = transform.transformTo(Point3(3, 2, 10));
524  Point3 expected(2, 1, 10);
525  EXPECT(assert_equal(expected, actual, 0.001));
526 }
527 
529  return pose.transformPoseTo(pose2);
530 }
531 
532 /* ************************************************************************* */
534  Pose3 origin = T.transformPoseTo(T);
536 }
537 
538 /* ************************************************************************* */
539 TEST(Pose3, transformPoseTo_with_derivatives) {
540  Matrix actH1, actH2;
541  Pose3 res = T.transformPoseTo(T2, actH1, actH2);
542  EXPECT(assert_equal(res, T.inverse().compose(T2)));
543 
546  EXPECT(assert_equal(expH1, actH1, 1e-8));
547  EXPECT(assert_equal(expH2, actH2, 1e-8));
548 }
549 
550 /* ************************************************************************* */
551 TEST(Pose3, transformPoseTo_with_derivatives2) {
552  Matrix actH1, actH2;
553  Pose3 res = T.transformPoseTo(T3, actH1, actH2);
554  EXPECT(assert_equal(res, T.inverse().compose(T3)));
555 
558  EXPECT(assert_equal(expH1, actH1, 1e-8));
559  EXPECT(assert_equal(expH2, actH2, 1e-8));
560 }
561 
562 /* ************************************************************************* */
564  Point3 actual = T3.transformFrom(Point3(0, 0, 0));
565  Point3 expected = Point3(1., 2., 3.);
566  EXPECT(assert_equal(expected, actual));
567 }
568 
569 /* ************************************************************************* */
570 TEST(Pose3, transform_roundtrip) {
571  Point3 actual = T3.transformFrom(T3.transformTo(Point3(12., -0.11, 7.0)));
572  Point3 expected(12., -0.11, 7.0);
573  EXPECT(assert_equal(expected, actual));
574 }
575 
576 /* ************************************************************************* */
577 TEST(Pose3, Retract_LocalCoordinates)
578 {
579  Vector6 d;
580  d << 1,2,3,4,5,6; d/=10;
581  const Rot3 R = Rot3::Retract(d.head<3>());
582  Pose3 t = Pose3::Retract(d);
583  EXPECT(assert_equal(d, Pose3::LocalCoordinates(t)));
584 }
585 /* ************************************************************************* */
586 TEST(Pose3, retract_localCoordinates)
587 {
588  Vector6 d12;
589  d12 << 1,2,3,4,5,6; d12/=10;
590  Pose3 t1 = T, t2 = t1.retract(d12);
591  EXPECT(assert_equal(d12, t1.localCoordinates(t2)));
592 }
593 /* ************************************************************************* */
594 TEST(Pose3, expmap_logmap)
595 {
596  Vector d12 = Vector6::Constant(0.1);
597  Pose3 t1 = T, t2 = t1.expmap(d12);
598  EXPECT(assert_equal(d12, t1.logmap(t2)));
599 }
600 
601 /* ************************************************************************* */
602 TEST(Pose3, retract_localCoordinates2)
603 {
604  Pose3 t1 = T;
605  Pose3 t2 = T3;
606  Pose3 origin;
607  Vector d12 = t1.localCoordinates(t2);
608  EXPECT(assert_equal(t2, t1.retract(d12)));
609  Vector d21 = t2.localCoordinates(t1);
610  EXPECT(assert_equal(t1, t2.retract(d21)));
611  // TODO(hayk): This currently fails!
612  // EXPECT(assert_equal(d12, -d21));
613 }
614 /* ************************************************************************* */
615 TEST(Pose3, manifold_expmap)
616 {
617  Pose3 t1 = T;
618  Pose3 t2 = T3;
619  Pose3 origin;
620  Vector d12 = t1.logmap(t2);
621  EXPECT(assert_equal(t2, t1.expmap(d12)));
622  Vector d21 = t2.logmap(t1);
623  EXPECT(assert_equal(t1, t2.expmap(d21)));
624 
625  // Check that log(t1,t2)=-log(t2,t1)
626  EXPECT(assert_equal(d12,-d21));
627 }
628 
629 /* ************************************************************************* */
630 TEST(Pose3, subgroups)
631 {
632  // Frank - Below only works for correct "Agrawal06iros style expmap
633  // lines in canonical coordinates correspond to Abelian subgroups in SE(3)
634  Vector d = (Vector(6) << 0.1, 0.2, 0.3, 0.4, 0.5, 0.6).finished();
635  // exp(-d)=inverse(exp(d))
637  // exp(5d)=exp(2*d+3*d)=exp(2*d)exp(3*d)=exp(3*d)exp(2*d)
638  Pose3 T2 = Pose3::Expmap(2*d);
639  Pose3 T3 = Pose3::Expmap(3*d);
640  Pose3 T5 = Pose3::Expmap(5*d);
643 }
644 
645 /* ************************************************************************* */
647 {
648  Pose3 expected = T2.inverse() * T3;
649  Matrix actualDBetween1,actualDBetween2;
650  Pose3 actual = T2.between(T3, actualDBetween1,actualDBetween2);
651  EXPECT(assert_equal(expected,actual));
652 
653  Matrix numericalH1 = numericalDerivative21(testing::between<Pose3> , T2, T3);
654  EXPECT(assert_equal(numericalH1,actualDBetween1,5e-3));
655 
656  Matrix numericalH2 = numericalDerivative22(testing::between<Pose3> , T2, T3);
657  EXPECT(assert_equal(numericalH2,actualDBetween2,1e-5));
658 }
659 
660 /* ************************************************************************* */
661 // some shared test values - pulled from equivalent test in Pose2
662 Point3 l1(1, 0, 0), l2(1, 1, 0), l3(2, 2, 0), l4(1, 4,-4);
663 Pose3 x1, x2(Rot3::Ypr(0.0, 0.0, 0.0), l2), x3(Rot3::Ypr(M_PI/4.0, 0.0, 0.0), l2);
664 Pose3
665  xl1(Rot3::Ypr(0.0, 0.0, 0.0), Point3(1, 0, 0)),
666  xl2(Rot3::Ypr(0.0, 1.0, 0.0), Point3(1, 1, 0)),
667  xl3(Rot3::Ypr(1.0, 0.0, 0.0), Point3(2, 2, 0)),
668  xl4(Rot3::Ypr(0.0, 0.0, 1.0), Point3(1, 4,-4));
669 
670 /* ************************************************************************* */
671 double range_proxy(const Pose3& pose, const Point3& point) {
672  return pose.range(point);
673 }
675 {
676  Matrix expectedH1, actualH1, expectedH2, actualH2;
677 
678  // establish range is indeed zero
680 
681  // establish range is indeed sqrt2
682  EXPECT_DOUBLES_EQUAL(sqrt(2.0),x1.range(l2),1e-9);
683 
684  // Another pair
685  double actual23 = x2.range(l3, actualH1, actualH2);
686  EXPECT_DOUBLES_EQUAL(sqrt(2.0),actual23,1e-9);
687 
688  // Check numerical derivatives
689  expectedH1 = numericalDerivative21(range_proxy, x2, l3);
690  expectedH2 = numericalDerivative22(range_proxy, x2, l3);
691  EXPECT(assert_equal(expectedH1,actualH1));
692  EXPECT(assert_equal(expectedH2,actualH2));
693 
694  // Another test
695  double actual34 = x3.range(l4, actualH1, actualH2);
696  EXPECT_DOUBLES_EQUAL(5,actual34,1e-9);
697 
698  // Check numerical derivatives
699  expectedH1 = numericalDerivative21(range_proxy, x3, l4);
700  expectedH2 = numericalDerivative22(range_proxy, x3, l4);
701  EXPECT(assert_equal(expectedH1,actualH1));
702  EXPECT(assert_equal(expectedH2,actualH2));
703 }
704 
705 /* ************************************************************************* */
706 double range_pose_proxy(const Pose3& pose, const Pose3& point) {
707  return pose.range(point);
708 }
709 TEST( Pose3, range_pose )
710 {
711  Matrix expectedH1, actualH1, expectedH2, actualH2;
712 
713  // establish range is indeed zero
715 
716  // establish range is indeed sqrt2
718 
719  // Another pair
720  double actual23 = x2.range(xl3, actualH1, actualH2);
721  EXPECT_DOUBLES_EQUAL(sqrt(2.0),actual23,1e-9);
722 
723  // Check numerical derivatives
726  EXPECT(assert_equal(expectedH1,actualH1));
727  EXPECT(assert_equal(expectedH2,actualH2));
728 
729  // Another test
730  double actual34 = x3.range(xl4, actualH1, actualH2);
731  EXPECT_DOUBLES_EQUAL(5,actual34,1e-9);
732 
733  // Check numerical derivatives
736  EXPECT(assert_equal(expectedH1,actualH1));
737  EXPECT(assert_equal(expectedH2,actualH2));
738 }
739 
740 /* ************************************************************************* */
742  return pose.bearing(point);
743 }
745  Matrix expectedH1, actualH1, expectedH2, actualH2;
746  EXPECT(assert_equal(Unit3(1, 0, 0), x1.bearing(l1, actualH1, actualH2), 1e-9));
747 
748  // Check numerical derivatives
749  expectedH1 = numericalDerivative21(bearing_proxy, x1, l1);
750  expectedH2 = numericalDerivative22(bearing_proxy, x1, l1);
751  EXPECT(assert_equal(expectedH1, actualH1, 1e-5));
752  EXPECT(assert_equal(expectedH2, actualH2, 1e-5));
753 }
754 
755 TEST(Pose3, Bearing2) {
756  Matrix expectedH1, actualH1, expectedH2, actualH2;
757  EXPECT(assert_equal(Unit3(0,0.6,-0.8), x2.bearing(l4, actualH1, actualH2), 1e-9));
758 
759  // Check numerical derivatives
760  expectedH1 = numericalDerivative21(bearing_proxy, x2, l4);
761  expectedH2 = numericalDerivative22(bearing_proxy, x2, l4);
762  EXPECT(assert_equal(expectedH1, actualH1, 1e-5));
763  EXPECT(assert_equal(expectedH2, actualH2, 1e-5));
764 }
765 
766 TEST(Pose3, PoseToPoseBearing) {
767  Matrix expectedH1, actualH1, expectedH2, actualH2, H2block;
768  EXPECT(assert_equal(Unit3(0,1,0), xl1.bearing(xl2, actualH1, actualH2), 1e-9));
769 
770  // Check numerical derivatives
771  expectedH1 = numericalDerivative21(bearing_proxy, xl1, l2);
772 
773  // Since the second pose is treated as a point, the value calculated by
774  // numericalDerivative22 only depends on the position of the pose. Here, we
775  // calculate the Jacobian w.r.t. the second pose's position, and then augment
776  // that with zeroes in the block that is w.r.t. the second pose's
777  // orientation.
779  expectedH2 = Matrix(2, 6);
780  expectedH2.setZero();
781  expectedH2.block<2, 3>(0, 3) = H2block;
782 
783  EXPECT(assert_equal(expectedH1, actualH1, 1e-5));
784  EXPECT(assert_equal(expectedH2, actualH2, 1e-5));
785 }
786 
787 /* ************************************************************************* */
788 TEST( Pose3, unicycle )
789 {
790  // velocity in X should be X in inertial frame, rather than global frame
791  Vector x_step = Vector::Unit(6,3)*1.0;
792  EXPECT(assert_equal(Pose3(Rot3::Ypr(0,0,0), l1), expmap_default<Pose3>(x1, x_step), tol));
793  EXPECT(assert_equal(Pose3(Rot3::Ypr(0,0,0), Point3(2,1,0)), expmap_default<Pose3>(x2, x_step), tol));
794  EXPECT(assert_equal(Pose3(Rot3::Ypr(M_PI/4.0,0,0), Point3(2,2,0)), expmap_default<Pose3>(x3, sqrt(2.0) * x_step), tol));
795 }
796 
797 /* ************************************************************************* */
798 TEST( Pose3, adjointMap) {
799  Matrix res = Pose3::adjointMap(screwPose3::xi);
802  Matrix6 expected;
803  expected << wh, Z_3x3, vh, wh;
805 }
806 
807 /* ************************************************************************* */
808 TEST(Pose3, Align1) {
809  Pose3 expected(Rot3(), Point3(10,10,0));
810 
811  Point3Pair ab1(Point3(10,10,0), Point3(0,0,0));
812  Point3Pair ab2(Point3(30,20,0), Point3(20,10,0));
813  Point3Pair ab3(Point3(20,30,0), Point3(10,20,0));
814  const vector<Point3Pair> correspondences{ab1, ab2, ab3};
815 
816  std::optional<Pose3> actual = Pose3::Align(correspondences);
817  EXPECT(assert_equal(expected, *actual));
818 }
819 
820 /* ************************************************************************* */
821 TEST(Pose3, Align2) {
822  Point3 t(20,10,5);
823  Rot3 R = Rot3::RzRyRx(0.3, 0.2, 0.1);
824  Pose3 expected(R, t);
825 
826  Point3 p1(0,0,1), p2(10,0,2), p3(20,-10,30);
828  q2 = expected.transformFrom(p2),
829  q3 = expected.transformFrom(p3);
830  const Point3Pair ab1{q1, p1}, ab2{q2, p2}, ab3{q3, p3};
831  const vector<Point3Pair> correspondences{ab1, ab2, ab3};
832 
833  std::optional<Pose3> actual = Pose3::Align(correspondences);
834  EXPECT(assert_equal(expected, *actual, 1e-5));
835 }
836 
837 /* ************************************************************************* */
838 TEST(Pose3, ExpmapDerivative) {
839  // Iserles05an (Lie-group Methods) says:
840  // scalar is easy: d exp(a(t)) / dt = exp(a(t)) a'(t)
841  // matrix is hard: d exp(A(t)) / dt = exp(A(t)) dexp[-A(t)] A'(t)
842  // where A(t): T -> se(3) is a trajectory in the tangent space of SE(3)
843  // and dexp[A] is a linear map from 4*4 to 4*4 derivatives of se(3)
844  // Hence, the above matrix equation is typed: 4*4 = SE(3) * linear_map(4*4)
845 
846  // In GTSAM, we don't work with the Lie-algebra elements A directly, but with 6-vectors.
847  // xi is easy: d Expmap(xi(t)) / dt = ExmapDerivative[xi(t)] * xi'(t)
848 
849  // Let's verify the above formula.
850 
851  auto xi = [](double t) {
852  Vector6 v;
853  v << 2 * t, sin(t), 4 * t * t, 2 * t, sin(t), 4 * t * t;
854  return v;
855  };
856  auto xi_dot = [](double t) {
857  Vector6 v;
858  v << 2, cos(t), 8 * t, 2, cos(t), 8 * t;
859  return v;
860  };
861 
862  // We define a function T
863  auto T = [xi](double t) { return Pose3::Expmap(xi(t)); };
864 
865  for (double t = -2.0; t < 2.0; t += 0.3) {
866  const Matrix expected = numericalDerivative11<Pose3, double>(T, t);
867  const Matrix actual = Pose3::ExpmapDerivative(xi(t)) * xi_dot(t);
868  CHECK(assert_equal(expected, actual, 1e-7));
869  }
870 }
871 
872 //******************************************************************************
873 namespace test_cases {
874 std::vector<Vector3> small{{0, 0, 0}, //
875  {1e-5, 0, 0}, {0, 1e-5, 0}, {0, 0, 1e-5}, //,
876  {1e-4, 0, 0}, {0, 1e-4, 0}, {0, 0, 1e-4}};
877 std::vector<Vector3> large{{0, 0, 0}, {1, 0, 0}, {0, 1, 0},
878  {0, 0, 1}, {.1, .2, .3}, {1, -2, 3}};
879 auto omegas = [](bool nearZero) { return nearZero ? small : large; };
880 std::vector<Vector3> vs{{1, 0, 0}, {0, 1, 0}, {0, 0, 1},
881  {.4, .3, .2}, {4, 5, 6}, {-10, -20, 30}};
882 } // namespace test_cases
883 
884 //******************************************************************************
885 TEST(Pose3, ExpmapDerivatives) {
886  for (bool nearZero : {true, false}) {
887  for (const Vector3& w : test_cases::omegas(nearZero)) {
888  for (Vector3 v : test_cases::vs) {
889  const Vector6 xi = (Vector6() << w, v).finished();
890  const Matrix6 expectedH =
891  numericalDerivative21<Pose3, Vector6, OptionalJacobian<6, 6> >(
892  &Pose3::Expmap, xi, {});
893  Matrix actualH;
894  Pose3::Expmap(xi, actualH);
895  EXPECT(assert_equal(expectedH, actualH));
896  }
897  }
898  }
899 }
900 
901 //******************************************************************************
902 // Check logmap for all small values, as we don't want wrapping.
903 TEST(Pose3, Logmap) {
904  static constexpr bool nearZero = true;
905  for (const Vector3& w : test_cases::omegas(nearZero)) {
906  for (Vector3 v : test_cases::vs) {
907  const Vector6 xi = (Vector6() << w, v).finished();
909  EXPECT(assert_equal(xi, Pose3::Logmap(pose)));
910  }
911  }
912 }
913 
914 //******************************************************************************
915 // Check logmap derivatives for all values
916 TEST(Pose3, LogmapDerivatives) {
917  for (bool nearZero : {true, false}) {
918  for (const Vector3& w : test_cases::omegas(nearZero)) {
919  for (Vector3 v : test_cases::vs) {
920  const Vector6 xi = (Vector6() << w, v).finished();
922  const Matrix6 expectedH =
923  numericalDerivative21<Vector6, Pose3, OptionalJacobian<6, 6> >(
924  &Pose3::Logmap, pose, {});
925  Matrix actualH;
926  Pose3::Logmap(pose, actualH);
927 #ifdef GTSAM_USE_QUATERNIONS
928  // TODO(Frank): Figure out why quaternions are not as accurate.
929  // Hint: 6 cases fail on Ubuntu 22.04, but none on MacOS.
930  EXPECT(assert_equal(expectedH, actualH, 1e-7));
931 #else
932  EXPECT(assert_equal(expectedH, actualH));
933 #endif
934  }
935  }
936  }
937 }
938 
939 /* ************************************************************************* */
940 Vector6 testDerivAdjoint(const Vector6& xi, const Vector6& v) {
941  return Pose3::adjointMap(xi) * v;
942 }
943 
945  Vector6 v = (Vector6() << 1, 2, 3, 4, 5, 6).finished();
947 
948  Matrix actualH1, actualH2;
949  Vector actual = Pose3::adjoint(screwPose3::xi, v, actualH1, actualH2);
950 
951  Matrix numericalH1 = numericalDerivative21<Vector6, Vector6, Vector6>(
953  Matrix numericalH2 = numericalDerivative22<Vector6, Vector6, Vector6>(
955 
956  EXPECT(assert_equal(expected,actual,1e-5));
957  EXPECT(assert_equal(numericalH1,actualH1,1e-5));
958  EXPECT(assert_equal(numericalH2,actualH2,1e-5));
959 }
960 
961 /* ************************************************************************* */
962 Vector6 testDerivAdjointTranspose(const Vector6& xi, const Vector6& v) {
963  return Pose3::adjointMap(xi).transpose() * v;
964 }
965 
966 TEST( Pose3, adjointTranspose) {
967  Vector xi = (Vector(6) << 0.01, 0.02, 0.03, 1.0, 2.0, 3.0).finished();
968  Vector v = (Vector(6) << 0.04, 0.05, 0.06, 4.0, 5.0, 6.0).finished();
970 
971  Matrix actualH1, actualH2;
972  Vector actual = Pose3::adjointTranspose(xi, v, actualH1, actualH2);
973 
974  Matrix numericalH1 = numericalDerivative21<Vector6, Vector6, Vector6>(
976  Matrix numericalH2 = numericalDerivative22<Vector6, Vector6, Vector6>(
978 
979  EXPECT(assert_equal(expected,actual,1e-15));
980  EXPECT(assert_equal(numericalH1,actualH1,1e-5));
981  EXPECT(assert_equal(numericalH2,actualH2,1e-5));
982 }
983 
984 /* ************************************************************************* */
986  std::ostringstream os;
987  os << Pose3();
988 
989  string expected = "R: [\n\t1, 0, 0;\n\t0, 1, 0;\n\t0, 0, 1\n]\nt: 0 0 0";
990  EXPECT(os.str() == expected);
991 }
992 
993 //******************************************************************************
994 TEST(Pose3 , Invariants) {
995  Pose3 id;
996 
997  EXPECT(check_group_invariants(id,id));
998  EXPECT(check_group_invariants(id,T3));
999  EXPECT(check_group_invariants(T2,id));
1000  EXPECT(check_group_invariants(T2,T3));
1001 
1002  EXPECT(check_manifold_invariants(id,id));
1003  EXPECT(check_manifold_invariants(id,T3));
1004  EXPECT(check_manifold_invariants(T2,id));
1005  EXPECT(check_manifold_invariants(T2,T3));
1006 }
1007 
1008 //******************************************************************************
1009 TEST(Pose3 , LieGroupDerivatives) {
1010  Pose3 id;
1011 
1016 }
1017 
1018 //******************************************************************************
1019 TEST(Pose3 , ChartDerivatives) {
1020  Pose3 id;
1021  if (ROT3_DEFAULT_COORDINATES_MODE == Rot3::EXPMAP) {
1022  CHECK_CHART_DERIVATIVES(id,id);
1026  }
1027 }
1028 
1029 //******************************************************************************
1030 #include "testPoseAdjointMap.h"
1031 
1032 TEST(Pose3, TransformCovariance6MapTo2d) {
1033  // Create 3d scenarios that map to 2d configurations and compare with Pose2 results.
1034  using namespace test_pose_adjoint_map;
1035 
1036  Vector3 s2{0.1, 0.3, 0.7};
1037  Pose2 p2{1.1, 1.5, 31. * degree};
1038  auto cov2 = FullCovarianceFromSigmas<Pose2>(s2);
1039  auto transformed2 = TransformCovariance<Pose2>{p2}(cov2);
1040 
1041  auto match_cov3_to_cov2 = [&](int spatial_axis0, int spatial_axis1, int r_axis,
1042  const Pose2::Jacobian &cov2, const Pose3::Jacobian &cov3) -> void
1043  {
1045  Vector3{cov2.diagonal()},
1046  Vector3{cov3(spatial_axis0, spatial_axis0), cov3(spatial_axis1, spatial_axis1), cov3(r_axis, r_axis)}));
1048  Vector3{cov2(1, 0), cov2(2, 0), cov2(2, 1)},
1049  Vector3{cov3(spatial_axis1, spatial_axis0), cov3(r_axis, spatial_axis0), cov3(r_axis, spatial_axis1)}));
1050  };
1051 
1052  // rotate around x axis
1053  {
1054  auto cov3 = FullCovarianceFromSigmas<Pose3>((Vector6{} << s2(2), 0., 0., 0., s2(0), s2(1)).finished());
1055  auto transformed3 = TransformCovariance<Pose3>{{Rot3::RzRyRx(p2.theta(), 0., 0.), {0., p2.x(), p2.y()}}}(cov3);
1056  match_cov3_to_cov2(4, 5, 0, transformed2, transformed3);
1057  }
1058 
1059  // rotate around y axis
1060  {
1061  auto cov3 = FullCovarianceFromSigmas<Pose3>((Vector6{} << 0., s2(2), 0., s2(1), 0., s2(0)).finished());
1062  auto transformed3 = TransformCovariance<Pose3>{{Rot3::RzRyRx(0., p2.theta(), 0.), {p2.y(), 0., p2.x()}}}(cov3);
1063  match_cov3_to_cov2(5, 3, 1, transformed2, transformed3);
1064  }
1065 
1066  // rotate around z axis
1067  {
1068  auto cov3 = FullCovarianceFromSigmas<Pose3>((Vector6{} << 0., 0., s2(2), s2(0), s2(1), 0.).finished());
1069  auto transformed3 = TransformCovariance<Pose3>{{Rot3::RzRyRx(0., 0., p2.theta()), {p2.x(), p2.y(), 0.}}}(cov3);
1070  match_cov3_to_cov2(3, 4, 2, transformed2, transformed3);
1071  }
1072 }
1073 
1074 /* ************************************************************************* */
1075 TEST(Pose3, TransformCovariance6) {
1076  // Use simple covariance matrices and transforms to create tests that can be
1077  // validated with simple computations.
1078  using namespace test_pose_adjoint_map;
1079 
1080  // rotate 90 around z axis and then 90 around y axis
1081  {
1082  auto cov = FullCovarianceFromSigmas<Pose3>((Vector6{} << 0.1, 0.2, 0.3, 0.5, 0.7, 1.1).finished());
1083  auto transformed = TransformCovariance<Pose3>{{Rot3::RzRyRx(0., 90 * degree, 90 * degree), {0., 0., 0.}}}(cov);
1084  // x from y, y from z, z from x
1086  (Vector6{} << cov(1, 1), cov(2, 2), cov(0, 0), cov(4, 4), cov(5, 5), cov(3, 3)).finished(),
1087  Vector6{transformed.diagonal()}));
1088  // Both the x and z axes are pointing in the negative direction.
1090  (Vector5{} << -cov(2, 1), cov(0, 1), cov(4, 1), -cov(5, 1), cov(3, 1)).finished(),
1091  (Vector5{} << transformed(1, 0), transformed(2, 0), transformed(3, 0),
1092  transformed(4, 0), transformed(5, 0)).finished()));
1093  }
1094 
1095  // translate along the x axis with uncertainty in roty and rotz
1096  {
1097  auto cov = TwoVariableCovarianceFromSigmas<Pose3>(1, 2, 0.7, 0.3);
1098  auto transformed = TransformCovariance<Pose3>{{Rot3::RzRyRx(0., 0., 0.), {20., 0., 0.}}}(cov);
1099  // The uncertainty in roty and rotz causes off-diagonal covariances
1100  EXPECT(assert_equal(0.7 * 0.7 * 20., transformed(5, 1)));
1101  EXPECT(assert_equal(0.7 * 0.7 * 20. * 20., transformed(5, 5)));
1102  EXPECT(assert_equal(-0.3 * 0.3 * 20., transformed(4, 2)));
1103  EXPECT(assert_equal(0.3 * 0.3 * 20. * 20., transformed(4, 4)));
1104  EXPECT(assert_equal(-0.3 * 0.7 * 20., transformed(4, 1)));
1105  EXPECT(assert_equal(0.3 * 0.7 * 20., transformed(5, 2)));
1106  EXPECT(assert_equal(-0.3 * 0.7 * 20. * 20., transformed(5, 4)));
1107  }
1108 
1109  // rotate around x axis and translate along the x axis with uncertainty in rotx
1110  {
1111  auto cov = SingleVariableCovarianceFromSigma<Pose3>(0, 0.1);
1112  auto transformed = TransformCovariance<Pose3>{{Rot3::RzRyRx(90 * degree, 0., 0.), {20., 0., 0.}}}(cov);
1113  // No change
1114  EXPECT(assert_equal(cov, transformed));
1115  }
1116 
1117  // rotate around x axis and translate along the x axis with uncertainty in roty
1118  {
1119  auto cov = SingleVariableCovarianceFromSigma<Pose3>(1, 0.1);
1120  auto transformed = TransformCovariance<Pose3>{{Rot3::RzRyRx(90 * degree, 0., 0.), {20., 0., 0.}}}(cov);
1121  // Uncertainty is spread to other dimensions.
1123  (Vector6{} << 0., 0., 0.1 * 0.1, 0., 0.1 * 0.1 * 20. * 20., 0.).finished(),
1124  Vector6{transformed.diagonal()}));
1125  }
1126 }
1127 
1128 /* ************************************************************************* */
1132 
1133  // Trivial example: start at origin and move to (1, 0, 0) while rotating pi/2
1134  // about z-axis.
1135  Pose3 start;
1136  Pose3 end(Rot3::Rz(M_PI_2), Point3(1, 0, 0));
1137  // This interpolation is easy to calculate by hand.
1138  double t = 0.5;
1139  Pose3 expected0(Rot3::Rz(M_PI_4), Point3(0.5, 0, 0));
1140  EXPECT(assert_equal(expected0, start.interpolateRt(end, t)));
1141 
1142  // Example from Peter Corke
1143  // https://robotacademy.net.au/lesson/interpolating-pose-in-3d/
1144  t = 0.0759; // corresponds to the 10th element when calling `ctraj` in
1145  // the video
1146  Pose3 O;
1147  Pose3 F(Rot3::Roll(0.6).compose(Rot3::Pitch(0.8)).compose(Rot3::Yaw(1.4)),
1148  Point3(1, 2, 3));
1149 
1150  // The expected answer matches the result presented in the video.
1151  Pose3 expected1(interpolate(O.rotation(), F.rotation(), t),
1152  interpolate(O.translation(), F.translation(), t));
1153  EXPECT(assert_equal(expected1, O.interpolateRt(F, t)));
1154 
1155  // Non-trivial interpolation, translation value taken from output.
1156  Pose3 expected2(interpolate(T2.rotation(), T3.rotation(), t),
1158  EXPECT(assert_equal(expected2, T2.interpolateRt(T3, t)));
1159 }
1160 
1161 /* ************************************************************************* */
1162 Pose3 testing_interpolate(const Pose3& t1, const Pose3& t2, double gamma) { return interpolate(t1,t2,gamma); }
1163 
1164 TEST(Pose3, interpolateJacobians) {
1165  {
1166  Pose3 X = Pose3::Identity();
1167  Pose3 Y(Rot3::Rz(M_PI_2), Point3(1, 0, 0));
1168  double t = 0.5;
1169  Pose3 expectedPoseInterp(Rot3::Rz(M_PI_4), Point3(0.5, -0.207107, 0)); // note: different from test above: this is full Pose3 interpolation
1170  Matrix actualJacobianX, actualJacobianY;
1171  EXPECT(assert_equal(expectedPoseInterp, interpolate(X, Y, t, actualJacobianX, actualJacobianY), 1e-5));
1172 
1173  Matrix expectedJacobianX = numericalDerivative31<Pose3,Pose3,Pose3,double>(testing_interpolate, X, Y, t);
1174  EXPECT(assert_equal(expectedJacobianX,actualJacobianX,1e-6));
1175 
1176  Matrix expectedJacobianY = numericalDerivative32<Pose3,Pose3,Pose3,double>(testing_interpolate, X, Y, t);
1177  EXPECT(assert_equal(expectedJacobianY,actualJacobianY,1e-6));
1178  }
1179  {
1180  Pose3 X = Pose3::Identity();
1181  Pose3 Y(Rot3::Identity(), Point3(1, 0, 0));
1182  double t = 0.3;
1183  Pose3 expectedPoseInterp(Rot3::Identity(), Point3(0.3, 0, 0));
1184  Matrix actualJacobianX, actualJacobianY;
1185  EXPECT(assert_equal(expectedPoseInterp, interpolate(X, Y, t, actualJacobianX, actualJacobianY), 1e-5));
1186 
1187  Matrix expectedJacobianX = numericalDerivative31<Pose3,Pose3,Pose3,double>(testing_interpolate, X, Y, t);
1188  EXPECT(assert_equal(expectedJacobianX,actualJacobianX,1e-6));
1189 
1190  Matrix expectedJacobianY = numericalDerivative32<Pose3,Pose3,Pose3,double>(testing_interpolate, X, Y, t);
1191  EXPECT(assert_equal(expectedJacobianY,actualJacobianY,1e-6));
1192  }
1193  {
1194  Pose3 X = Pose3::Identity();
1195  Pose3 Y(Rot3::Rz(M_PI_2), Point3(0, 0, 0));
1196  double t = 0.5;
1197  Pose3 expectedPoseInterp(Rot3::Rz(M_PI_4), Point3(0, 0, 0));
1198  Matrix actualJacobianX, actualJacobianY;
1199  EXPECT(assert_equal(expectedPoseInterp, interpolate(X, Y, t, actualJacobianX, actualJacobianY), 1e-5));
1200 
1201  Matrix expectedJacobianX = numericalDerivative31<Pose3,Pose3,Pose3,double>(testing_interpolate, X, Y, t);
1202  EXPECT(assert_equal(expectedJacobianX,actualJacobianX,1e-6));
1203 
1204  Matrix expectedJacobianY = numericalDerivative32<Pose3,Pose3,Pose3,double>(testing_interpolate, X, Y, t);
1205  EXPECT(assert_equal(expectedJacobianY,actualJacobianY,1e-6));
1206  }
1207  {
1208  Pose3 X(Rot3::Ypr(0.1,0.2,0.3), Point3(10, 5, -2));
1209  Pose3 Y(Rot3::Ypr(1.1,-2.2,-0.3), Point3(-5, 1, 1));
1210  double t = 0.3;
1211  Pose3 expectedPoseInterp(Rot3::Rz(M_PI_4), Point3(0, 0, 0));
1212  Matrix actualJacobianX, actualJacobianY;
1213  interpolate(X, Y, t, actualJacobianX, actualJacobianY);
1214 
1215  Matrix expectedJacobianX = numericalDerivative31<Pose3,Pose3,Pose3,double>(testing_interpolate, X, Y, t);
1216  EXPECT(assert_equal(expectedJacobianX,actualJacobianX,1e-6));
1217 
1218  Matrix expectedJacobianY = numericalDerivative32<Pose3,Pose3,Pose3,double>(testing_interpolate, X, Y, t);
1219  EXPECT(assert_equal(expectedJacobianY,actualJacobianY,1e-6));
1220  }
1221 }
1222 
1223 /* ************************************************************************* */
1224 TEST(Pose3, Create) {
1225  Matrix63 actualH1, actualH2;
1226  Pose3 actual = Pose3::Create(R, P2, actualH1, actualH2);
1227  EXPECT(assert_equal(T, actual));
1228  std::function<Pose3(Rot3, Point3)> create = [](Rot3 R, Point3 t) {
1229  return Pose3::Create(R, t);
1230  };
1231  EXPECT(assert_equal(numericalDerivative21<Pose3,Rot3,Point3>(create, R, P2), actualH1, 1e-9));
1232  EXPECT(assert_equal(numericalDerivative22<Pose3,Rot3,Point3>(create, R, P2), actualH2, 1e-9));
1233 }
1234 
1235 /* ************************************************************************* */
1237  Pose3 pose(Rot3::Identity(), Point3(1, 2, 3));
1238 
1239  // Generate the expected output
1240  std::string expected = "R: [\n\t1, 0, 0;\n\t0, 1, 0;\n\t0, 0, 1\n]\nt: 1 2 3\n";
1241 
1243 }
1244 
1245 /* ************************************************************************* */
1246 TEST(Pose3, ExpmapChainRule) {
1247  // Muliply with an arbitrary matrix and exponentiate
1248  Matrix6 M;
1249  M << 1, 2, 3, 4, 5, 6, //
1250  7, 8, 9, 1, 2, 3, //
1251  4, 5, 6, 7, 8, 9, //
1252  1, 2, 3, 4, 5, 6, //
1253  7, 8, 9, 1, 2, 3, //
1254  4, 5, 6, 7, 8, 9;
1255  auto g = [&](const Vector6& omega) {
1256  return Pose3::Expmap(M*omega);
1257  };
1258 
1259  // Test the derivatives at zero
1260  const Matrix6 expected = numericalDerivative11<Pose3, Vector6>(g, Z_6x1);
1261  EXPECT(assert_equal<Matrix6>(expected, M, 1e-5)); // Pose3::ExpmapDerivative(Z_6x1) is identity
1262 
1263  // Test the derivatives at another value
1264  const Vector6 delta{0.1, 0.2, 0.3, 0.4, 0.5, 0.6};
1265  const Matrix6 expected2 = numericalDerivative11<Pose3, Vector6>(g, delta);
1266  const Matrix6 analytic = Pose3::ExpmapDerivative(M*delta) * M;
1267  EXPECT(assert_equal<Matrix6>(expected2, analytic, 1e-5)); // note tolerance
1268 }
1269 
1270 /* ************************************************************************* */
1271 int main() {
1272  TestResult tr;
1273  return TestRegistry::runAllTests(tr);
1274 }
1275 /* ************************************************************************* */
TestRegistry::runAllTests
static int runAllTests(TestResult &result)
Definition: TestRegistry.cpp:27
gtsam::internal::rotation
Rot3 rotation(const Pose3 &pose, OptionalJacobian< 3, 6 > H)
Definition: slam/expressions.h:80
create
ADT create(const Signature &signature)
Definition: testAlgebraicDecisionTree.cpp:136
gtsam::LieGroup::between
Class between(const Class &g) const
Definition: Lie.h:52
gtsam::Pose3::interpolateRt
Pose3 interpolateRt(const Pose3 &T, double t) const
Definition: Pose3.cpp:160
gtsam::Point3Pair
std::pair< Point3, Point3 > Point3Pair
Definition: Point3.h:42
Pose2.h
2D Pose
gtsam::TransformCovariance
Definition: Lie.h:352
l3
Point3 l3(2, 2, 0)
pose
static const Pose3 pose(Rot3(Vector3(1, -1, -1).asDiagonal()), Point3(0, 0, 0.5))
inverse
const EIGEN_DEVICE_FUNC InverseReturnType inverse() const
Definition: ArrayCwiseUnaryOps.h:411
gtsam::Pose3::transformTo
Point3 transformTo(const Point3 &point, OptionalJacobian< 3, 6 > Hself={}, OptionalJacobian< 3, 3 > Hpoint={}) const
takes point in world coordinates and transforms it to Pose coordinates
Definition: Pose3.cpp:372
s
RealScalar s
Definition: level1_cplx_impl.h:126
e
Array< double, 1, 3 > e(1./3., 0.5, 2.)
d
static const double d[K][N]
Definition: igam.h:11
GTSAM_CONCEPT_TESTABLE_INST
#define GTSAM_CONCEPT_TESTABLE_INST(T)
Definition: Testable.h:176
ceres::sin
Jet< T, N > sin(const Jet< T, N > &f)
Definition: jet.h:439
EXPECT
#define EXPECT(condition)
Definition: Test.h:150
TestHarness.h
gtsam.examples.SFMExample_bal.stream
stream
Definition: SFMExample_bal.py:24
test_cases::omegas
auto omegas
Definition: testPose3.cpp:879
gtsam::Y
GaussianFactorGraphValuePair Y
Definition: HybridGaussianProductFactor.cpp:29
screwPose3::w
double w
Definition: testPose3.cpp:115
gtsam::assert_print_equal
bool assert_print_equal(const std::string &expected, const V &actual, const std::string &s="")
Definition: TestableAssertions.h:352
gtsam::LieGroup::compose
Class compose(const Class &g) const
Definition: Lie.h:48
x
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 x
Definition: gnuplot_common_settings.hh:12
screwPose3::xi
Vector xi
Definition: testPose3.cpp:116
gtsam::numericalDerivative11
internal::FixedSizeMatrix< Y, X >::type numericalDerivative11(std::function< Y(const X &)> h, const X &x, double delta=1e-5)
New-style numerical derivatives using manifold_traits.
Definition: numericalDerivative.h:110
gtsam::numericalDerivative22
internal::FixedSizeMatrix< Y, X2 >::type numericalDerivative22(std::function< Y(const X1 &, const X2 &)> h, const X1 &x1, const X2 &x2, double delta=1e-5)
Definition: numericalDerivative.h:195
bearing_proxy
Unit3 bearing_proxy(const Pose3 &pose, const Point3 &point)
Definition: testPose3.cpp:741
transformPoseTo_
Pose3 transformPoseTo_(const Pose3 &pose, const Pose3 &pose2)
Definition: testPose3.cpp:528
T3
static const Pose3 T3(Rot3::Rodrigues(-90, 0, 0), Point3(1, 2, 3))
gtsam::utils.numerical_derivative.retract
def retract(a, np.ndarray xi)
Definition: numerical_derivative.py:44
gtsam::Matrix
Eigen::MatrixXd Matrix
Definition: base/Matrix.h:39
log
const EIGEN_DEVICE_FUNC LogReturnType log() const
Definition: ArrayCwiseUnaryOps.h:128
simple::pose2
static Pose3 pose2
Definition: testInitializePose3.cpp:58
X
#define X
Definition: icosphere.cpp:20
test_cases::vs
std::vector< Vector3 > vs
Definition: testPose3.cpp:880
gtsam::Vector3
Eigen::Vector3d Vector3
Definition: Vector.h:44
testLie.h
test_pose_adjoint_map
Definition: testPoseAdjointMap.h:24
res
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Definition: PartialRedux_count.cpp:3
os
ofstream os("timeSchurFactors.csv")
tol
static const double tol
Definition: testPose3.cpp:41
gtsam::Vector
Eigen::VectorXd Vector
Definition: Vector.h:39
gtsam::skewSymmetric
Matrix3 skewSymmetric(double wx, double wy, double wz)
Definition: base/Matrix.h:400
screwPose3::c
double c
Definition: testPose3.cpp:115
gtsam::Pose3::matrix
Matrix4 matrix() const
Definition: Pose3.cpp:324
x3
Pose3 x3(Rot3::Ypr(M_PI/4.0, 0.0, 0.0), l2)
EQUALITY
#define EQUALITY(expected, actual)
Definition: Test.h:127
ceres::cos
Jet< T, N > cos(const Jet< T, N > &f)
Definition: jet.h:426
TestableAssertions.h
Provides additional testing facilities for common data structures.
gtsam::Pose3::range
double range(const Point3 &point, OptionalJacobian< 1, 6 > Hself={}, OptionalJacobian< 1, 3 > Hpoint={}) const
Definition: Pose3.cpp:400
A
Matrix< SCALARA, Dynamic, Dynamic, opt_A > A
Definition: bench_gemm.cpp:48
l2
Point3 l2(1, 1, 0)
biased_x_rotation::omega
const double omega
Definition: testPreintegratedRotation.cpp:32
gtsam::Pose3::transformPoseFrom
Pose3 transformPoseFrom(const Pose3 &aTb, OptionalJacobian< 6, 6 > Hself={}, OptionalJacobian< 6, 6 > HaTb={}) const
Definition: Pose3.cpp:332
gtsam::range
Double_ range(const Point2_ &p, const Point2_ &q)
Definition: slam/expressions.h:30
simple::p2
static Point3 p2
Definition: testInitializePose3.cpp:51
gtsam::Pose3::AdjointTranspose
Vector6 AdjointTranspose(const Vector6 &x, OptionalJacobian< 6, 6 > H_this={}, OptionalJacobian< 6, 6 > H_x={}) const
The dual version of Adjoint.
Definition: Pose3.cpp:83
gtsam_unstable.tests.test_ProjectionFactorRollingShutter.point
point
Definition: test_ProjectionFactorRollingShutter.py:25
ceres::Matrix
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > Matrix
Definition: gtsam/3rdparty/ceres/eigen.h:42
gtsam::Pose3::transformPoseTo
Pose3 transformPoseTo(const Pose3 &wTb, OptionalJacobian< 6, 6 > Hself={}, OptionalJacobian< 6, 6 > HwTb={}) const
Definition: Pose3.cpp:339
Expmap
Pose2_ Expmap(const Vector3_ &xi)
Definition: InverseKinematicsExampleExpressions.cpp:47
gtsam::Pose3::Adjoint
Vector6 Adjoint(const Vector6 &xi_b, OptionalJacobian< 6, 6 > H_this={}, OptionalJacobian< 6, 6 > H_xib={}) const
Definition: Pose3.cpp:65
transformPoseFrom_
Pose3 transformPoseFrom_(const Pose3 &wTa, const Pose3 &aTb)
Definition: testPose3.cpp:499
id
static const Similarity3 id
Definition: testSimilarity3.cpp:44
gtsam::transformFrom
Point3_ transformFrom(const Pose3_ &x, const Point3_ &p)
Definition: slam/expressions.h:47
testPoseAdjointMap.h
Support utilities for using AdjointMap for transforming Pose2 and Pose3 covariance matrices.
gtsam.examples.PlanarManipulatorExample.delta
def delta(g0, g1)
Definition: PlanarManipulatorExample.py:45
xl4
Pose3 xl4(Rot3::Ypr(0.0, 0.0, 1.0), Point3(1, 4,-4))
screwPose3::expectedT
Point3 expectedT(0.29552, 0.0446635, 1)
xl2
Pose3 xl2(Rot3::Ypr(0.0, 1.0, 0.0), Point3(1, 1, 0))
I
#define I
Definition: main.h:112
gtsam::transformTo
Line3 transformTo(const Pose3 &wTc, const Line3 &wL, OptionalJacobian< 4, 6 > Dpose, OptionalJacobian< 4, 4 > Dline)
Definition: Line3.cpp:94
x1
Pose3 x1
Definition: testPose3.cpp:663
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_CONCEPT_LIE_INST
#define GTSAM_CONCEPT_LIE_INST(T)
Definition: Lie.h:372
M_PI_4
#define M_PI_4
Definition: mconf.h:119
screwPose3::expected
Pose3 expected(expectedR, expectedT)
Agrawal06iros
Pose3 Agrawal06iros(const Vector &xi)
Definition: testPose3.cpp:242
gtsam::Pose3::inverse
Pose3 inverse() const
inverse transformation with derivatives
Definition: Pose3.cpp:47
gtsam::interpolate
T interpolate(const T &X, const T &Y, double t, typename MakeOptionalJacobian< T, T >::type Hx={}, typename MakeOptionalJacobian< T, T >::type Hy={})
Definition: Lie.h:327
gtsam::Pose3::equals
bool equals(const Pose3 &pose, double tol=1e-9) const
assert equality up to a tolerance
Definition: Pose3.cpp:155
degree
const double degree
Definition: SimpleRotation.cpp:59
gtsam::Pose3::translation
const Point3 & translation(OptionalJacobian< 3, 6 > Hself={}) const
get translation
Definition: Pose3.cpp:310
l4
Point3 l4(1, 4,-4)
screwPose3::expectedR
Rot3 expectedR(c, -s, 0, s, c, 0, 0, 0, 1)
gtsam::Pose3::AdjointMap
Matrix6 AdjointMap() const
Definition: Pose3.cpp:55
CHECK_LIE_GROUP_DERIVATIVES
#define CHECK_LIE_GROUP_DERIVATIVES(t1, t2)
Definition: testLie.h:82
T5
static const Similarity3 T5(R, P, 10)
example2::aTb
Point3 aTb
Definition: testEssentialMatrixFactor.cpp:585
simple::p3
static Point3 p3
Definition: testInitializePose3.cpp:53
test_cases::large
std::vector< Vector3 > large
Definition: testPose3.cpp:877
T2
static const Pose3 T2(Rot3::Rodrigues(0.3, 0.2, 0.1), P2)
transform
EIGEN_DONT_INLINE void transform(const Transformation &t, Data &data)
Definition: geometry.cpp:25
Eigen::Triplet< double >
R
static const Rot3 R
Definition: testPose3.cpp:36
gamma
#define gamma
Definition: mconf.h:85
gtsam::LieGroup::localCoordinates
TangentVector localCoordinates(const Class &g) const
localCoordinates as required by manifold concept: finds tangent vector between *this and g
Definition: Lie.h:136
gtsam::symbol_shorthand::F
Key F(std::uint64_t j)
Definition: inference/Symbol.h:153
range_proxy
double range_proxy(const Pose3 &pose, const Point3 &point)
Definition: testPose3.cpp:671
gtsam::LieGroup::logmap
TangentVector logmap(const Class &g) const
Definition: Lie.h:84
EXPECT_DOUBLES_EQUAL
#define EXPECT_DOUBLES_EQUAL(expected, actual, threshold)
Definition: Test.h:161
p1
Vector3f p1
Definition: MatrixBase_all.cpp:2
g
void g(const string &key, int i)
Definition: testBTree.cpp:41
gtsam::equals
Definition: Testable.h:112
TestResult
Definition: TestResult.h:26
y
Scalar * y
Definition: level1_cplx_impl.h:124
matrix
Map< Matrix< T, Dynamic, Dynamic, ColMajor >, 0, OuterStride<> > matrix(T *data, int rows, int cols, int stride)
Definition: gtsam/3rdparty/Eigen/blas/common.h:110
M_PI_2
#define M_PI_2
Definition: mconf.h:118
tree::f
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Definition: testExpression.cpp:218
screwPose3
Definition: testPose3.cpp:114
gtsam::symbol_shorthand::O
Key O(std::uint64_t j)
Definition: inference/Symbol.h:162
gtsam::Pose3::bearing
Unit3 bearing(const Point3 &point, OptionalJacobian< 2, 6 > Hself={}, OptionalJacobian< 2, 3 > Hpoint={}) const
Definition: Pose3.cpp:426
gtsam::Pose3::rotation
const Rot3 & rotation(OptionalJacobian< 3, 6 > Hself={}) const
get rotation
Definition: Pose3.cpp:316
xl3
Pose3 xl3(Rot3::Ypr(1.0, 0.0, 0.0), Point3(2, 2, 0))
gtsam
traits
Definition: SFMdata.h:40
test_cases::small
std::vector< Vector3 > small
Definition: testPose3.cpp:874
gtsam::symbol_shorthand::W
Key W(std::uint64_t j)
Definition: inference/Symbol.h:170
gtsam::testing::compose
T compose(const T &t1, const T &t2)
Definition: lieProxies.h:39
CHECK
#define CHECK(condition)
Definition: Test.h:108
gtsam::internal::translation
Point3 translation(const Pose3 &pose, OptionalJacobian< 3, 6 > H)
Definition: slam/expressions.h:84
gtsam::numericalDerivative21
internal::FixedSizeMatrix< Y, X1 >::type numericalDerivative21(const std::function< Y(const X1 &, const X2 &)> &h, const X1 &x1, const X2 &x2, double delta=1e-5)
Definition: numericalDerivative.h:166
std
Definition: BFloat16.h:88
gtsam::Pose3::transformFrom
Point3 transformFrom(const Point3 &point, OptionalJacobian< 3, 6 > Hself={}, OptionalJacobian< 3, 3 > Hpoint={}) const
takes point in Pose coordinates and transforms it to world coordinates
Definition: Pose3.cpp:348
origin
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 origin
Definition: gnuplot_common_settings.hh:45
xl1
Pose3 xl1(Rot3::Ypr(0.0, 0.0, 0.0), Point3(1, 0, 0))
transformFrom_
Point3 transformFrom_(const Pose3 &pose, const Point3 &point)
Definition: testPose3.cpp:395
main
int main()
Definition: testPose3.cpp:1271
gtsam::Print
void Print(const CONTAINER &keys, const string &s, const KeyFormatter &keyFormatter)
Definition: Key.cpp:65
v
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
gtsam::Similarity3::matrix
Matrix4 matrix() const
Calculate 4*4 matrix group equivalent.
Definition: Similarity3.cpp:284
gtsam::testing::between
T between(const T &t1, const T &t2)
Definition: lieProxies.h:36
gtsam::assert_equal
bool assert_equal(const Matrix &expected, const Matrix &actual, double tol)
Definition: Matrix.cpp:41
transform_to_
Point3 transform_to_(const Pose3 &pose, const Point3 &point)
Definition: testPose3.cpp:443
gtsam::Point3
Vector3 Point3
Definition: Point3.h:38
gtsam::LieGroup::retract
Class retract(const TangentVector &v) const
retract as required by manifold concept: applies v at *this
Definition: Lie.h:131
P
static const Point3 P(0.2, 0.7,-2)
l1
Point3 l1(1, 0, 0)
testDerivAdjointTranspose
Vector6 testDerivAdjointTranspose(const Vector6 &xi, const Vector6 &v)
Definition: testPose3.cpp:962
gtsam::Unit3
Represents a 3D point on a unit sphere.
Definition: Unit3.h:42
gtsam::internal::Align
static Similarity2 Align(const Point2Pairs &d_abPointPairs, const Rot2 &aRb, const Point2Pair &centroids)
This method estimates the similarity transform from differences point pairs, given a known or estimat...
Definition: Similarity2.cpp:74
gtsam::LieGroup::expmap
Class expmap(const TangentVector &v) const
Definition: Lie.h:78
M_PI
#define M_PI
Definition: mconf.h:117
screwPose3::a
double a
Definition: testPose3.cpp:115
Eigen::placeholders::end
static const EIGEN_DEPRECATED end_t end
Definition: IndexedViewHelper.h:181
T1
static const Similarity3 T1(R, Point3(3.5, -8.2, 4.2), 1)
gtsam::Bearing
Definition: BearingRange.h:35
gtsam::transformPoseTo
Pose3_ transformPoseTo(const Pose3_ &p, const Pose3_ &q)
Definition: slam/expressions.h:57
lieProxies.h
Provides convenient mappings of common member functions for testing.
align_3::t
Point2 t(10, 10)
TEST
TEST(Pose3, equals)
Definition: testPose3.cpp:44
ceres::Vector
Eigen::Matrix< double, Eigen::Dynamic, 1 > Vector
Definition: gtsam/3rdparty/ceres/eigen.h:38
testDerivAdjoint
Vector6 testDerivAdjoint(const Vector6 &xi, const Vector6 &v)
Definition: testPose3.cpp:940
test_cases
Definition: testPose3.cpp:873
adjoint
void adjoint(const MatrixType &m)
Definition: adjoint.cpp:67
x2
Pose3 x2(Rot3::Ypr(0.0, 0.0, 0.0), l2)
CHECK_CHART_DERIVATIVES
#define CHECK_CHART_DERIVATIVES(t1, t2)
Definition: testLie.h:85
ceres::sqrt
Jet< T, N > sqrt(const Jet< T, N > &f)
Definition: jet.h:418
T
static const Pose3 T(R, P2)
Pose3.h
3D Pose manifold SO(3) x R^3 and group SE(3)
P2
static const Point3 P2(3.5,-8.2, 4.2)
gtsam::wedge< Pose3 >
Matrix wedge< Pose3 >(const Vector &xi)
Definition: Pose3.h:436
testing_interpolate
Pose3 testing_interpolate(const Pose3 &t1, const Pose3 &t2, double gamma)
Definition: testPose3.cpp:1162
gtsam::Pose2
Definition: Pose2.h:39
ROT3_DEFAULT_COORDINATES_MODE
#define ROT3_DEFAULT_COORDINATES_MODE
Definition: Rot3.h:43
M
Matrix< RealScalar, Dynamic, Dynamic > M
Definition: bench_gemm.cpp:51
range_pose_proxy
double range_pose_proxy(const Pose3 &pose, const Pose3 &point)
Definition: testPose3.cpp:706


gtsam
Author(s):
autogenerated on Sun Dec 22 2024 04:16:55