gtsam
Loading...
Searching...
No Matches
Rot2.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
19
20#pragma once
21
22#include <gtsam/base/Matrix.h>
26
27#include <random>
28#include <stdexcept>
29#include <utility>
30#include <vector>
31
32namespace gtsam {
33
40 class GTSAM_EXPORT Rot2 : public MatrixLieGroup<Rot2, 1, 2> {
42 double c_, s_;
43
45 inline Rot2(double c, double s) : c_(c), s_(s) {}
46
47 public:
48
51
53 Rot2() : c_(1.0), s_(0.0) {}
54
56 Rot2(const Rot2& r) = default;
57
58 Rot2& operator=(const Rot2& other) = default;
59
61 Rot2(double theta) : c_(cos(theta)), s_(sin(theta)) {}
62
63 // Rot2& operator=(const gtsam::Rot2& other) = default;
64
66 static Rot2 fromAngle(double theta) {
67 return Rot2(theta);
68 }
69
71 static Rot2 fromDegrees(double theta) {
72 static const double degree = M_PI / 180;
73 return fromAngle(theta * degree);
74 }
75
77 static Rot2 fromCosSin(double c, double s);
78
86 static Rot2 relativeBearing(const Point2& d, OptionalJacobian<1,2> H =
87 {});
88
90 static Rot2 atan2(double y, double x);
91
98 static Rot2 Random(std::mt19937 & rng);
99
103
105 void print(const std::string& s = "theta") const;
106
108 bool equals(const Rot2& R, double tol = 1e-9) const;
109
113
115 inline static Rot2 Identity() { return Rot2(); }
116
118 Rot2 inverse() const { return Rot2(c_, -s_);}
119
121 Rot2 operator*(const Rot2& R) const {
122 return fromCosSin(c_ * R.c_ - s_ * R.s_, s_ * R.c_ + c_ * R.s_);
123 }
124
128
129 using LieAlgebra = Matrix2;
130
132 static Rot2 Expmap(const Vector1& v, ChartJacobian H = {});
133
135 static Vector1 Logmap(const Rot2& r, ChartJacobian H = {});
136
138 Matrix1 AdjointMap() const { return I_1x1; }
139
141 static Matrix1 adjointMap(const Vector1&);
142
144 static Vector1 adjoint(const Vector1&, const Vector1&,
145 OptionalJacobian<1, 1> Hxi = {},
146 OptionalJacobian<1, 1> Hy = {});
147
149 static Matrix ExpmapDerivative(const Vector& /*v*/) {
150 return I_1x1;
151 }
152
154 static Matrix LogmapDerivative(const Vector& /*v*/) {
155 return I_1x1;
156 }
157
158 // Chart at origin simply uses exponential map and its inverse
160 static Rot2 Retract(const Vector1& v, ChartJacobian H = {}) {
161 return Expmap(v, H);
162 }
163 static Vector1 Local(const Rot2& r, ChartJacobian H = {}) {
164 return Logmap(r, H);
165 }
166 };
167
168 using LieGroup<Rot2, 1>::inverse; // version with derivative
169
171 static Matrix2 Hat(const Vector1& xi);
172
174 static Vector1 Vee(const Matrix2& X);
175
179
183 Point2 rotate(const Point2& p, OptionalJacobian<2, 1> H1 = {},
184 OptionalJacobian<2, 2> H2 = {}) const;
185
187 inline Point2 operator*(const Point2& p) const {
188 return rotate(p);
189 }
190
194 Point2 unrotate(const Point2& p, OptionalJacobian<2, 1> H1 = {},
195 OptionalJacobian<2, 2> H2 = {}) const;
196
200
202 inline Point2 unit() const {
203 return Point2(c_, s_);
204 }
205
207 double theta() const {
208 return ::atan2(s_, c_);
209 }
210
212 double degrees() const {
213 const double degree = M_PI / 180;
214 return theta() / degree;
215 }
216
218 inline double c() const {
219 return c_;
220 }
221
223 inline double s() const {
224 return s_;
225 }
226
228 Matrix2 matrix() const;
229
231 Matrix2 transpose() const;
232
234 static Rot2 ClosestTo(const Matrix2& M);
235
237 Vector4 vec(OptionalJacobian<4, 1> H = {}) const;
239
240 private:
241#if GTSAM_ENABLE_BOOST_SERIALIZATION
243 friend class boost::serialization::access;
244 template<class ARCHIVE>
245 void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
246 ar & BOOST_SERIALIZATION_NVP(c_);
247 ar & BOOST_SERIALIZATION_NVP(s_);
248 }
249#endif
250
251 };
252
253template <>
254struct traits<Rot2> : public internal::MatrixLieGroup<Rot2, 2> {
256 inline constexpr static int QcqpVectorDim = 3;
257
267 template <int D = 1>
268 static Matrix QcqpValue(const Rot2& value) {
269 if constexpr (D == 1) {
270 return Vector3(1.0, value.c(), value.s());
271 } else if constexpr (D >= 2) {
272 Matrix X = Matrix::Zero(2, D);
273 X.leftCols<2>() = value.matrix().transpose();
274 return X;
275 } else {
276 throw std::invalid_argument(
277 "traits<Rot2>::QcqpValue requires D>=1.");
278 }
279 }
280
289 template <int D = 1>
290 static std::vector<std::pair<Matrix, double>> QcqpConstraints() {
291 if constexpr (D == 1) {
292 // The minimal homogenized Rot2 lifted vector is x = [h, c, s].
293 std::vector<std::pair<Matrix, double>> constraints;
294 constraints.reserve(2);
295
296 Matrix A = Matrix::Zero(QcqpVectorDim, QcqpVectorDim);
297
298 // The quadratic lift fixes x(0)^2 = 1; a hard prior pins its sign.
299 A(0, 0) = 1.0;
300 constraints.emplace_back(A, 1.0);
301
302 // c^2 + s^2 = 1 simultaneously enforces orthonormality and det(R)=1.
303 A.setZero();
304 A(1, 1) = 1.0;
305 A(2, 2) = 1.0;
306 constraints.emplace_back(A, 1.0);
307
308 return constraints;
309 } else if constexpr (D >= 2) {
310 std::vector<std::pair<Matrix, double>> constraints;
311 constraints.reserve(3);
312
313 Matrix A = Matrix::Zero(2, 2);
314 A(0, 0) = 1.0;
315 constraints.emplace_back(A, 1.0);
316
317 A.setZero();
318 A(1, 1) = 1.0;
319 constraints.emplace_back(A, 1.0);
320
321 A.setZero();
322 A(0, 1) = 0.5;
323 A(1, 0) = 0.5;
324 constraints.emplace_back(A, 0.0);
325
326 return constraints;
327 } else {
328 throw std::invalid_argument(
329 "traits<Rot2>::QcqpConstraints only supports D=1 and D>=2.");
330 }
331 }
332
340 template <int D>
341 static Rot2 FromQcqpValue(const Matrix& X) {
342 if constexpr (D == 1) {
343 if (X.rows() != QcqpVectorDim || X.cols() != 1 ||
344 std::abs(X(0, 0)) < 1e-9) {
345 throw std::invalid_argument(
346 "traits<Rot2>::FromQcqpValue requires a 3-by-1 vector with a "
347 "nonzero homogenization entry.");
348 }
349 const Vector x = X.col(0) / X(0, 0);
350 return Rot2::atan2(x(2), x(1));
351 } else {
352 static_assert(D >= 2,
353 "traits<Rot2>::FromQcqpValue requires D >= 2.");
354 if (X.rows() != 2 || X.cols() != D) {
355 throw std::invalid_argument(
356 "traits<Rot2>::FromQcqpValue requires a 2-by-D matrix.");
357 }
358 return Rot2::ClosestTo(X.template leftCols<2>().transpose());
359 }
360 }
361};
362
363template <>
364struct traits<const Rot2> : public traits<Rot2> {};
365
366} // namespace gtsam
Base class and basic functions for Matrix Lie groups.
typedef and functions to augment Eigen's MatrixXd
Macros for Matrix constants to avoid excessive template instantiation.
2D Point
Global functions in a separate testing namespace.
Definition chartTesting.h:28
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
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
Rotation matrix NOTE: the angle theta is in radians unless explicitly stated.
Definition Rot2.h:40
Rot2 operator*(const Rot2 &R) const
Compose - make a new rotation by adding angles.
Definition Rot2.h:121
double c() const
return cos
Definition Rot2.h:218
static Matrix ExpmapDerivative(const Vector &)
Left-trivialized derivative of the exponential map.
Definition Rot2.h:149
Point2 unit() const
Creates a unit vector as a Point2.
Definition Rot2.h:202
double theta() const
return angle (RADIANS)
Definition Rot2.h:207
Rot2 inverse() const
The inverse rotation - negative angle.
Definition Rot2.h:118
Point2 operator*(const Point2 &p) const
syntactic sugar for rotate
Definition Rot2.h:187
static Rot2 fromCosSin(double c, double s)
Named constructor from cos(theta),sin(theta) pair.
Definition Rot2.cpp:30
double s() const
return sin
Definition Rot2.h:223
Rot2(const Rot2 &r)=default
copy constructor
static Rot2 Expmap(const Vector1 &v, ChartJacobian H={})
Exponential map at identity - create a rotation from canonical coordinates.
Definition Rot2.cpp:63
static Rot2 Identity()
Identity.
Definition Rot2.h:115
double degrees() const
return angle (DEGREES)
Definition Rot2.h:212
static Matrix LogmapDerivative(const Vector &)
Left-trivialized derivative inverse of the exponential map.
Definition Rot2.h:154
Matrix1 AdjointMap() const
Calculate Adjoint map.
Definition Rot2.h:138
static Matrix2 Hat(const Vector1 &xi)
Hat maps from tangent vector to Lie algebra.
Definition Rot2.cpp:92
static Vector1 Logmap(const Rot2 &r, ChartJacobian H={})
Log map at identity - return the canonical coordinates of this rotation.
Definition Rot2.cpp:73
Matrix2 matrix() const
return 2*2 rotation matrix
Definition Rot2.cpp:100
Rot2(double theta)
Constructor from angle in radians == exponential map at identity.
Definition Rot2.h:61
static Rot2 fromDegrees(double theta)
Named constructor from angle in degrees.
Definition Rot2.h:71
Point2 rotate(const Point2 &p, OptionalJacobian< 2, 1 > H1={}, OptionalJacobian< 2, 2 > H2={}) const
rotate point from rotated coordinate frame to world
Definition Rot2.cpp:107
Rot2()
default constructor, zero rotation
Definition Rot2.h:53
static Vector1 Vee(const Matrix2 &X)
Vee maps from Lie algebra to tangent vector.
Definition Rot2.cpp:97
static Rot2 ClosestTo(const Matrix2 &M)
Find closest valid rotation matrix, given a 2x2 matrix.
Definition Rot2.cpp:140
static Rot2 fromAngle(double theta)
Named constructor from angle in radians.
Definition Rot2.h:66
static Rot2 atan2(double y, double x)
Named constructor that behaves as atan2, i.e., y,x order (!) and normalizes.
Definition Rot2.cpp:41
Definition Rot2.h:159
static std::vector< std::pair< Matrix, double > > QcqpConstraints()
Return row-space QCQP equality constraints A, b such that trace(x_i' A x_i) = b[j].
Definition Rot2.h:290
static constexpr int QcqpVectorDim
Dimension of the D=1 homogenized QCQP vector [h, cos(theta), sin(theta)].
Definition Rot2.h:256
static Matrix QcqpValue(const Rot2 &value)
Return a matrix-valued QCQP variable for Rot2.
Definition Rot2.h:268
static Rot2 FromQcqpValue(const Matrix &X)
Project a D=1 minimal vector or canonical 2-by-D lift back to Rot2.
Definition Rot2.h:341