gtsam
Loading...
Searching...
No Matches
Unit3.h
1/* ----------------------------------------------------------------------------
2
3 * Atlanta, Georgia 30332-0415
4 * All Rights Reserved
5 * GTSAM Copyright 2010, Georgia Tech Research Corporation,
6 * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7
8 * See LICENSE for the license information
9
10 * -------------------------------------------------------------------------- */
11
12/*
13 * @file Unit3.h
14 * @date Feb 02, 2011
15 * @author Can Erdogan
16 * @author Frank Dellaert
17 * @author Alex Trevor
18 * @brief Develop a Unit3 class - basically a point on a unit sphere
19 */
20
21#pragma once
22
23#include <vector>
24
27#include <gtsam/base/Manifold.h>
28#include <gtsam/base/Vector.h>
30#include <gtsam/base/Matrix.h>
31#include <gtsam/dllexport.h>
32
33
34#include <random>
35#include <string>
36
37#ifdef GTSAM_USE_TBB
38#include <mutex> // std::mutex
39#endif
40
41namespace gtsam {
42
44class GTSAM_EXPORT Unit3 {
45
46private:
47
48 Vector3 p_;
49 mutable std::optional<Matrix32> B_;
50 mutable std::optional<Matrix62> H_B_;
51
52#ifdef GTSAM_USE_TBB
53 mutable std::mutex B_mutex_;
54#endif
55
56public:
57
58 inline constexpr static auto dimension = 2;
59
62
65 p_(1.0, 0.0, 0.0) {
66 }
67
69 explicit Unit3(const Vector3& p);
70
72 Unit3(double x, double y, double z);
73
76 explicit Unit3(const Point2& p, double f);
77
79 Unit3(const Unit3& u) : p_(u.p_) {}
80
82 Unit3& operator=(const Unit3& u) {
83 if (this == &u) return *this;
84 p_ = u.p_;
85
86 // Since p_ has changed, the old cached basis is no longer valid.
87 B_.reset();
88 H_B_.reset();
89 return *this;
90 }
91
93 static Unit3 FromPoint3(const Point3& point, //
95
102 static Unit3 Random(std::mt19937 & rng);
103
105
108
109 GTSAM_EXPORT friend std::ostream& operator<<(std::ostream& os,
110 const Unit3& pair);
111
113 void print(const std::string& s = std::string()) const;
114
116 bool equals(const Unit3& s, double tol = 1e-9) const {
117 return equal_with_abs_tol(p_, s.p_, tol);
118 }
119
120
123
130 const Matrix32& basis(OptionalJacobian<6, 2> H = {}) const;
131
133 Matrix3 skew() const;
134
136 Point3 point3(OptionalJacobian<3, 2> H = {}) const;
137
139 Vector3 unitVector(OptionalJacobian<3, 2> H = {}) const;
140
151 Vector3 scaled(double magnitude, OptionalJacobian<3, 2> H_this = {},
152 OptionalJacobian<3, 1> H_magnitude = {}) const;
153
155 friend Point3 operator*(double s, const Unit3& d) {
156 return Point3(s * d.p_);
157 }
158
160 double dot(const Unit3& q, OptionalJacobian<1,2> H1 = {}, //
161 OptionalJacobian<1,2> H2 = {}) const;
162
165 Vector2 errorVector(const Unit3& q, OptionalJacobian<2, 2> H_p = {}, //
166 OptionalJacobian<2, 2> H_q = {}) const;
167
169 double distance(const Unit3& q, OptionalJacobian<1, 2> H = {}) const;
170
172 Unit3 cross(const Unit3& q, OptionalJacobian<2, 2> H_p = {},
173 OptionalJacobian<2, 2> H_q = {}) const;
174
176 Point3 cross(const Point3& q, OptionalJacobian<3, 2> H_p = {},
177 OptionalJacobian<3, 3> H_q = {}) const;
178
182
184 inline static size_t Dim() {
185 return 2;
186 }
187
189 inline size_t dim() const {
190 return 2;
191 }
192
197
199 Unit3 retract(const Vector2& v, OptionalJacobian<2,2> H = {}) const;
200
202 Vector2 localCoordinates(const Unit3& s) const;
203
209 Vector2 localCoordinates(const Unit3& s, OptionalJacobian<2, 2> H1,
210 OptionalJacobian<2, 2> H2 = {}) const;
211
213
214#ifdef GTSAM_ALLOW_DEPRECATED_SINCE_V43
216 Vector2 error(const Unit3& q, OptionalJacobian<2, 2> H_q = {}) const {
217 return errorVector(q, {}, H_q);
218 }
219#endif
220
221private:
222
225#if GTSAM_ENABLE_BOOST_SERIALIZATION
227 friend class boost::serialization::access;
228 template<class ARCHIVE>
229 void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
230 ar & BOOST_SERIALIZATION_NVP(p_);
231 }
232#endif
233
235};
236
238GTSAM_EXPORT Unit3 cross(const Unit3& p, const Unit3& q,
239 OptionalJacobian<2, 2> H_p = {},
240 OptionalJacobian<2, 2> H_q = {});
241
243GTSAM_EXPORT Point3 cross(const Unit3& p, const Point3& q,
244 OptionalJacobian<3, 2> H_p = {},
245 OptionalJacobian<3, 3> H_q = {});
246
248GTSAM_EXPORT Point3 cross(const Point3& p, const Unit3& q,
249 OptionalJacobian<3, 3> H_p = {},
250 OptionalJacobian<3, 2> H_q = {});
251
253
260template <>
261struct traits<Unit3> : public internal::Manifold<Unit3> {
263 inline constexpr static int QcqpVectorDim = 4;
264
266 template <int D = 1>
267 static Matrix QcqpValue(const Unit3& value) {
268 if constexpr (D == 1) {
269 Eigen::Matrix<double, 4, 1> X;
270 X(0, 0) = 1.0;
271 X.segment<3>(1) = value.unitVector();
272 return X;
273 } else if constexpr (D >= 3) {
274 Matrix X = Matrix::Zero(1, D);
275 X.block(0, 0, 1, 3) = value.unitVector().transpose();
276 return X;
277 } else {
278 throw std::invalid_argument(
279 "traits<Unit3>::QcqpValue supports D=1 and D>=3.");
280 }
281 }
282
284 template <int D = 1>
285 static std::vector<std::pair<Matrix, double>> QcqpConstraints() {
286 if constexpr (D == 1) {
287 // Homogenized: pin the leading coordinate and the direction's norm.
288 std::vector<std::pair<Matrix, double>> constraints;
289 Matrix A = Matrix::Zero(4, 4);
290 A(0, 0) = 1.0;
291 constraints.emplace_back(A, 1.0);
292 A.setZero();
293 A(1, 1) = A(2, 2) = A(3, 3) = 1.0;
294 constraints.emplace_back(A, 1.0);
295 return constraints;
296 } else if constexpr (D >= 3) {
297 return {{Matrix::Identity(1, 1), 1.0}};
298 } else {
299 throw std::invalid_argument(
300 "traits<Unit3>::QcqpConstraints supports D=1 and D>=3.");
301 }
302 }
303
305 template <int D = 1>
306 static Unit3 FromQcqpValue(const Matrix& X) {
307 if constexpr (D == 1) {
308 if (X.rows() != QcqpVectorDim || X.cols() != 1) {
309 throw std::invalid_argument(
310 "traits<Unit3>::FromQcqpValue requires a 4-by-1 matrix.");
311 }
312 return Unit3(Point3(X.block(1, 0, 3, 1)));
313 } else if constexpr (D >= 3) {
314 if (X.rows() != 1 || X.cols() != D) {
315 throw std::invalid_argument(
316 "traits<Unit3>::FromQcqpValue requires a 1-by-D matrix.");
317 }
318 return Unit3(Point3(X.block(0, 0, 1, 3).transpose()));
319 } else {
320 throw std::invalid_argument(
321 "traits<Unit3>::FromQcqpValue supports D=1 and D>=3.");
322 }
323 }
324};
325
326template<> struct traits<const Unit3> : public internal::Manifold<Unit3> {
327};
328
329} // namespace gtsam
330
typedef and functions to augment Eigen's MatrixXd
Base class and basic functions for Manifold types.
typedef and functions to augment Eigen's VectorXd
serialization for Vectors
3D Point
2D Point
Global functions in a separate testing namespace.
Definition chartTesting.h:28
Vector3 Point3
As of GTSAM 4, in order to make GTSAM more lean, it is now possible to just typedef Point3 to Vector3...
Definition Point3.h:38
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
Point3 cross(const Point3 &p, const Point3 &q, OptionalJacobian< 3, 3 > H1, OptionalJacobian< 3, 3 > H2)
cross product
Definition Point3.cpp:66
double dot(const V1 &a, const V2 &b)
Dot product.
Definition Vector.h:191
bool equal_with_abs_tol(const Eigen::DenseBase< MATRIX > &A, const Eigen::DenseBase< MATRIX > &B, double tol=1e-9)
equals with a tolerance
Definition Matrix.h:81
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition Group.h:37
Both ManifoldTraits and Testable.
Definition Manifold.h:156
OptionalJacobian is an Eigen::Ref like class that can take be constructed using either a fixed size o...
Definition OptionalJacobian.h:40
Represents a 3D point on a unit sphere.
Definition Unit3.h:44
Unit3(const Unit3 &u)
Copy constructor: copies essential data and discards caches.
Definition Unit3.h:79
Vector3 unitVector(OptionalJacobian< 3, 2 > H={}) const
Return unit-norm Vector.
Definition Unit3.cpp:151
Unit3()
Default constructor.
Definition Unit3.h:64
friend Point3 operator*(double s, const Unit3 &d)
Return scaled direction as Point3 (no Jacobians; see scaled()).
Definition Unit3.h:155
static size_t Dim()
Dimensionality of tangent space = 2 DOF.
Definition Unit3.h:184
size_t dim() const
Dimensionality of tangent space = 2 DOF.
Definition Unit3.h:189
bool equals(const Unit3 &s, double tol=1e-9) const
The equals function with tolerance.
Definition Unit3.h:116
CoordinatesMode
Definition Unit3.h:193
@ EXPMAP
Use the exponential map to retract.
Definition Unit3.h:194
@ RENORM
Retract with vector addition and renormalize.
Definition Unit3.h:195
Unit3 & operator=(const Unit3 &u)
Copy assignment: copies essential data and invalidates local caches.
Definition Unit3.h:82
static Matrix QcqpValue(const Unit3 &value)
Lift a direction to a 1-by-D row, zero-padded above the ambient dimension.
Definition Unit3.h:267
static Unit3 FromQcqpValue(const Matrix &X)
Recover a direction by normalizing the leading three entries.
Definition Unit3.h:306
static std::vector< std::pair< Matrix, double > > QcqpConstraints()
The single unit-norm constraint, ||X||^2 = 1.
Definition Unit3.h:285
static constexpr int QcqpVectorDim
Dimension of the D=1 homogenized QCQP vector: [1; p].
Definition Unit3.h:263
STL class.