gtsam
Loading...
Searching...
No Matches
Pose2.h
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
18
19// \callgraph
20
21#pragma once
22
25#include <gtsam/geometry/Rot2.h>
26#include <gtsam/base/Lie.h>
27#include <gtsam/dllexport.h>
28#include <gtsam/base/std_optional_serialization.h>
29
30#include <optional>
31
32namespace gtsam {
33
39class GTSAM_EXPORT Pose2: public MatrixLieGroup<Pose2, 3, 3> {
40
41public:
42
44 using Rotation = Rot2;
45 using Translation = Point2;
46
48 using LieAlgebra = Matrix3;
49
50private:
51
52 Rot2 r_;
53 Point2 t_;
54
55public:
56
59
62 r_(traits<Rot2>::Identity()), t_(traits<Point2>::Identity()) {
63 }
64
66 Pose2(const Pose2& pose) = default;
67 // : r_(pose.r_), t_(pose.t_) {}
68
69 Pose2& operator=(const Pose2& other) = default;
70
77 Pose2(double x, double y, double theta) :
78 r_(Rot2::fromAngle(theta)), t_(x, y) {
79 }
80
82 Pose2(double theta, const Point2& t) :
83 r_(Rot2::fromAngle(theta)), t_(t) {
84 }
85
87 Pose2(const Rot2& r, const Point2& t) : r_(r), t_(t) {}
88
90 Pose2(const Matrix &T)
91 : r_(Rot2::atan2(T(1, 0), T(0, 0))), t_(T(0, 2), T(1, 2)) {
92#ifndef NDEBUG
93 if (T.rows() != 3 || T.cols() != 3) {
94 throw;
95 }
96#endif
97 }
98
102
110 static std::optional<Pose2> Align(const Point2Pairs& abPointPairs);
111
112 // Version of Pose2::Align that takes 2 matrices.
113 static std::optional<Pose2> Align(ConstMatrixView a, ConstMatrixView b);
114
118
120 void print(const std::string& s = "") const;
121
123 bool equals(const Pose2& pose, double tol = 1e-9) const;
124
128
130 inline static Pose2 Identity() { return Pose2(); }
131
133 Pose2 inverse() const;
134
136 inline Pose2 operator*(const Pose2& p2) const {
137 return Pose2(r_*p2.r(), t_ + r_*p2.t());
138 }
139
143
145 static Pose2 Expmap(const Vector3& xi, ChartJacobian H = {});
146
148 static Vector3 Logmap(const Pose2& p, ChartJacobian H = {});
149
154 Matrix3 AdjointMap() const;
155
159 static Matrix3 adjointMap(const Vector3& v);
160
161 // temporary fix for wrappers until case issue is resolved
162 static Matrix3 adjointMap_(const Vector3 &xi) { return adjointMap(xi);}
163 static Vector3 adjoint_(const Vector3 &xi, const Vector3 &y) { return adjoint(xi, y);}
164
166 static Matrix3 ExpmapDerivative(const Vector3& v);
167
174 static Matrix3 LogmapDerivative(const Pose2& pose);
175
183 static Matrix3 LogmapDerivative(const Vector3& xi);
184
185 // Chart at origin, depends on compile-time flag SLOW_BUT_CORRECT_EXPMAP
186 struct GTSAM_EXPORT ChartAtOrigin {
187 static Pose2 Retract(const Vector3& v, ChartJacobian H = {});
188 static Vector3 Local(const Pose2& r, ChartJacobian H = {});
189 };
190
191 using LieGroup<Pose2, 3>::inverse; // version with derivative
192
194 static Matrix3 Hat(const Vector3& xi);
195
197 static Vector3 Vee(const Matrix3& X);
198
202
204 Point2 transformTo(const Point2& point,
205 OptionalJacobian<2, 3> Dpose = {},
206 OptionalJacobian<2, 2> Dpoint = {}) const;
207
213 Matrix transformTo(ConstMatrixView points) const;
214
216 Point2 transformFrom(const Point2& point,
217 OptionalJacobian<2, 3> Dpose = {},
218 OptionalJacobian<2, 2> Dpoint = {}) const;
219
225 Matrix transformFrom(ConstMatrixView points) const;
226
228 inline Point2 operator*(const Point2& point) const {
229 return transformFrom(point);
230 }
231
235
237 inline double x() const { return t_.x(); }
238
240 inline double y() const { return t_.y(); }
241
243 inline double theta() const { return r_.theta(); }
244
246 inline const Point2& t() const { return t_; }
247
249 inline const Rot2& r() const { return r_; }
250
252 inline const Point2& translation(OptionalJacobian<2, 3> Hself={}) const {
253 if (Hself) {
254 *Hself = Matrix::Zero(2, 3);
255 (*Hself).block<2, 2>(0, 0) = rotation().matrix();
256 }
257 return t_;
258 }
259
261 inline const Rot2& rotation(OptionalJacobian<1, 3> Hself={}) const {
262 if (Hself) *Hself = Matrix13{{0, 0, 1}};
263 return r_;
264 }
265
267 Matrix3 matrix() const;
268
270 Vector9 vec(OptionalJacobian<9, 3> H = {}) const;
271
277 Rot2 bearing(const Point2& point,
278 OptionalJacobian<1, 3> H1={}, OptionalJacobian<1, 2> H2={}) const;
279
285 Rot2 bearing(const Pose2& pose,
286 OptionalJacobian<1, 3> H1={}, OptionalJacobian<1, 3> H2={}) const;
287
293 double range(const Point2& point,
294 OptionalJacobian<1, 3> H1={},
295 OptionalJacobian<1, 2> H2={}) const;
296
302 double range(const Pose2& point,
303 OptionalJacobian<1, 3> H1={},
304 OptionalJacobian<1, 3> H2={}) const;
305
309
315 inline static std::pair<size_t, size_t> translationInterval() { return {0, 1}; }
316
322 static std::pair<size_t, size_t> rotationInterval() { return {2, 2}; }
323
324
325
327 GTSAM_EXPORT
328 friend std::ostream &operator<<(std::ostream &os, const Pose2& p);
329
333
334#ifdef GTSAM_ALLOW_DEPRECATED_SINCE_V43
336 static inline Matrix3 wedge(double vx, double vy, double w) {
337 return Hat(TangentVector(vx, vy, w));
338 }
339
342 Pose2(const Vector& v) : Pose2() {
343 *this = Expmap(v);
344 }
345#endif
347
348 private:
349
350#if GTSAM_ENABLE_BOOST_SERIALIZATION //
351 // Serialization function
352 friend class boost::serialization::access;
353 template<class Archive>
354 void serialize(Archive & ar, const unsigned int /*version*/) {
355 ar & BOOST_SERIALIZATION_NVP(t_);
356 ar & BOOST_SERIALIZATION_NVP(r_);
357 }
358#endif
359}; // Pose2
360
361#ifdef GTSAM_ALLOW_DEPRECATED_SINCE_V43
363template <>
364inline Matrix wedge<Pose2>(const Vector& xi) {
365 // NOTE(chris): Need eval() as workaround for Apple clang + avx2.
366 return Matrix(Pose2::Hat(xi)).eval();
367}
368#endif
369
370// Convenience typedef
371using Pose2Pair = std::pair<Pose2, Pose2>;
372using Pose2Pairs = std::vector<Pose2Pair>;
373
394template <>
395struct traits<Pose2> : public internal::MatrixLieGroup<Pose2, 3> {
397 inline constexpr static int QcqpVectorDim = 7;
398
403 template <int D = 1>
404 static Matrix QcqpValue(const Pose2& value) {
405 if constexpr (D == 1) {
406 const Matrix3 T = value.matrix();
407 Vector7 X;
408 X(0, 0) = 1.0;
409 X.segment<2>(1) = T.col(0).head<2>();
410 X.segment<2>(3) = T.col(1).head<2>();
411 X.segment<2>(5) = T.col(2).head<2>();
412 return X;
413 } else {
414 throw std::invalid_argument(
415 "traits<Pose2>::QcqpValue only supports D=1.");
416 }
417 }
418
423 template <int D = 1>
424 static std::vector<std::pair<Matrix, double>> QcqpConstraints() {
425 if constexpr (D == 1) {
426 std::vector<std::pair<Matrix, double>> constraints;
427 constraints.reserve(5);
428
429 Matrix A = Matrix::Zero(7, 7);
430
431 // Homogenization.
432 A(0, 0) = 1.0;
433 constraints.emplace_back(A, 1.0);
434
435 // det(R) = r00*r11 - r10*r01 = 1.
436 A.setZero();
437 A(1, 4) = 0.5;
438 A(4, 1) = 0.5;
439 A(2, 3) = -0.5;
440 A(3, 2) = -0.5;
441 constraints.emplace_back(A, 1.0);
442
443 // RR^T = I.
444 A.setZero();
445 A(1, 1) = 1.0;
446 A(3, 3) = 1.0;
447 constraints.emplace_back(A, 1.0);
448
449 A.setZero();
450 A(1, 2) = 0.5;
451 A(2, 1) = 0.5;
452 A(3, 4) = 0.5;
453 A(4, 3) = 0.5;
454 constraints.emplace_back(A, 0.0);
455
456 A.setZero();
457 A(2, 2) = 1.0;
458 A(4, 4) = 1.0;
459 constraints.emplace_back(A, 1.0);
460
461 return constraints;
462 } else {
463 throw std::invalid_argument(
464 "traits<Pose2>::QcqpConstraints only supports D=1.");
465 }
466 }
467
469 template <int D>
470 static Pose2 FromQcqpValue(const Matrix& X) {
471 if constexpr (D == 1) {
472 if (X.rows() != QcqpVectorDim || X.cols() != 1 ||
473 std::abs(X(0, 0)) < 1e-9) {
474 throw std::invalid_argument(
475 "traits<Pose2>::FromQcqpValue requires a 7-by-1 vector with a "
476 "nonzero homogenization entry.");
477 }
478 const Vector x = X.col(0) / X(0, 0);
479 Matrix2 R;
480 R.col(0) = x.segment<2>(1);
481 R.col(1) = x.segment<2>(3);
482 return Pose2(Rot2::ClosestTo(R), x.segment<2>(5));
483 } else {
484 throw std::invalid_argument(
485 "traits<Pose2>::FromQcqpValue only supports D=1.");
486 }
487 }
488};
489
490template <>
491struct traits<const Pose2> : public traits<Pose2> {};
492
493// bearing and range traits, used in RangeFactor
494template <typename T>
495struct Bearing<Pose2, T> : HasBearing<Pose2, T, Rot2> {};
496
497template <typename T>
498struct Range<Pose2, T> : HasRange<Pose2, T, double> {};
499
500} // namespace gtsam
Base class and basic functions for Lie types.
2D rotation
2D Point
Bearing-Range product.
Global functions in a separate testing namespace.
Definition chartTesting.h:28
void print(const Matrix &A, const string &s, ostream &stream)
print without optional string, must specify cout yourself
Definition Matrix.cpp:143
Vector2 Point2
As of GTSAM 4, in order to make GTSAM more lean, it is now possible to just typedef Point2 to Vector2...
Definition Point2.h:32
Eigen::Ref< const Matrix, 0, Eigen::Stride< Eigen::Dynamic, Eigen::Dynamic > > ConstMatrixView
Dynamic-stride const Matrix view for accepting NumPy arrays without copies.
Definition Matrix.h:42
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition Group.h:37
A CRTP helper class that implements Lie group methods Prerequisites: methods operator*,...
Definition Lie.h:114
A CRTP helper class that implements matrix Lie group methods.
Definition MatrixLieGroup.h:51
Both LieGroupTraits and Testable.
Definition MatrixLieGroup.h:350
OptionalJacobian is an Eigen::Ref like class that can take be constructed using either a fixed size o...
Definition OptionalJacobian.h:40
Template to create a binary predicate.
Definition Testable.h:112
Definition BearingRange.h:36
Definition BearingRange.h:42
Definition BearingRange.h:182
Definition BearingRange.h:196
A 2D pose (Point2,Rot2).
Definition Pose2.h:39
Pose2 operator*(const Pose2 &p2) const
compose syntactic sugar
Definition Pose2.h:136
static Vector3 Vee(const Matrix3 &X)
Vee maps from Lie algebra to tangent vector.
Definition Pose2.cpp:232
Matrix3 LieAlgebra
LieGroup Concept requirements.
Definition Pose2.h:48
double y() const
get y
Definition Pose2.h:240
const Point2 & translation(OptionalJacobian< 2, 3 > Hself={}) const
translation
Definition Pose2.h:252
Pose2 inverse() const
inverse
Definition Pose2.cpp:219
Point2 transformFrom(const Point2 &point, OptionalJacobian< 2, 3 > Dpose={}, OptionalJacobian< 2, 2 > Dpoint={}) const
Return point coordinates in global frame.
Definition Pose2.cpp:257
Point2 operator*(const Point2 &point) const
syntactic sugar for transformFrom
Definition Pose2.h:228
Pose2(double x, double y, double theta)
construct from (x,y,theta)
Definition Pose2.h:77
Rot2 Rotation
Pose Concept requirements.
Definition Pose2.h:44
const Point2 & t() const
translation
Definition Pose2.h:246
static std::pair< size_t, size_t > translationInterval()
Return the start and end indices (inclusive) of the translation component of the exponential map para...
Definition Pose2.h:315
Pose2(const Pose2 &pose)=default
copy constructor
Pose2(double theta, const Point2 &t)
construct from rotation and translation
Definition Pose2.h:82
double x() const
get x
Definition Pose2.h:237
const Rot2 & r() const
rotation
Definition Pose2.h:249
const Rot2 & rotation(OptionalJacobian< 1, 3 > Hself={}) const
rotation
Definition Pose2.h:261
static std::pair< size_t, size_t > rotationInterval()
Return the start and end indices (inclusive) of the rotation component of the exponential map paramet...
Definition Pose2.h:322
double theta() const
get theta
Definition Pose2.h:243
Pose2()
default constructor = origin
Definition Pose2.h:61
Point2 transformTo(const Point2 &point, OptionalJacobian< 2, 3 > Dpose={}, OptionalJacobian< 2, 2 > Dpoint={}) const
Return point coordinates in pose coordinate frame.
Definition Pose2.cpp:238
static Pose2 Identity()
identity for group operation
Definition Pose2.h:130
Matrix3 matrix() const
return transformation matrix
Definition Pose2.cpp:38
Pose2(const Rot2 &r, const Point2 &t)
construct from r,t
Definition Pose2.h:87
static Matrix3 Hat(const Vector3 &xi)
Hat maps from tangent vector to Lie algebra.
Definition Pose2.cpp:224
Pose2(const Matrix &T)
Constructor from 3*3 matrix.
Definition Pose2.h:90
Definition Pose2.h:186
static Pose2 FromQcqpValue(const Matrix &X)
Project a D=1 homogenized QCQP vector back to Pose2.
Definition Pose2.h:470
static std::vector< std::pair< Matrix, double > > QcqpConstraints()
Return the five D=1 lifted SE(2) manifold constraints A, b such that trace(x' A x) = b.
Definition Pose2.h:424
static Matrix QcqpValue(const Pose2 &value)
Return the D=1 homogenized QCQP variable x = [1, r00, r10, r01, r11, tx, ty].
Definition Pose2.h:404
static constexpr int QcqpVectorDim
Dimension of the D=1 homogenized QCQP vector.
Definition Pose2.h:397
Rotation matrix NOTE: the angle theta is in radians unless explicitly stated.
Definition Rot2.h:40
static Rot2 ClosestTo(const Matrix2 &M)
Find closest valid rotation matrix, given a 2x2 matrix.
Definition Rot2.cpp:140