Rot3M.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 
21 #include <gtsam/config.h> // Get GTSAM_USE_QUATERNIONS macro
22 
23 #ifndef GTSAM_USE_QUATERNIONS
24 
25 #include <gtsam/geometry/Rot3.h>
26 #include <gtsam/geometry/SO3.h>
27 #include <boost/math/constants/constants.hpp>
28 #include <cmath>
29 
30 using namespace std;
31 
32 namespace gtsam {
33 
34 /* ************************************************************************* */
35 Rot3::Rot3() : rot_(I_3x3) {}
36 
37 /* ************************************************************************* */
38 Rot3::Rot3(const Point3& col1, const Point3& col2, const Point3& col3) {
39  Matrix3 R;
40  R << col1, col2, col3;
41  rot_ = SO3(R);
42 }
43 
44 /* ************************************************************************* */
45 Rot3::Rot3(double R11, double R12, double R13, double R21, double R22,
46  double R23, double R31, double R32, double R33) {
47  Matrix3 R;
48  R << R11, R12, R13, R21, R22, R23, R31, R32, R33;
49  rot_ = SO3(R);
50 }
51 
52 /* ************************************************************************* */
54 }
55 
56 /* ************************************************************************* */
57 Rot3 Rot3::Rx(double t) {
58  double st = sin(t), ct = cos(t);
59  return Rot3(
60  1, 0, 0,
61  0, ct,-st,
62  0, st, ct);
63 }
64 
65 /* ************************************************************************* */
66 Rot3 Rot3::Ry(double t) {
67  double st = sin(t), ct = cos(t);
68  return Rot3(
69  ct, 0, st,
70  0, 1, 0,
71  -st, 0, ct);
72 }
73 
74 /* ************************************************************************* */
75 Rot3 Rot3::Rz(double t) {
76  double st = sin(t), ct = cos(t);
77  return Rot3(
78  ct,-st, 0,
79  st, ct, 0,
80  0, 0, 1);
81 }
82 
83 /* ************************************************************************* */
84 // Considerably faster than composing matrices above !
85 Rot3 Rot3::RzRyRx(double x, double y, double z, OptionalJacobian<3, 1> Hx,
87  double cx=cos(x),sx=sin(x);
88  double cy=cos(y),sy=sin(y);
89  double cz=cos(z),sz=sin(z);
90  double ss_ = sx * sy;
91  double cs_ = cx * sy;
92  double sc_ = sx * cy;
93  double cc_ = cx * cy;
94  double c_s = cx * sz;
95  double s_s = sx * sz;
96  double _cs = cy * sz;
97  double _cc = cy * cz;
98  double s_c = sx * cz;
99  double c_c = cx * cz;
100  double ssc = ss_ * cz, csc = cs_ * cz, sss = ss_ * sz, css = cs_ * sz;
101  if (Hx) (*Hx) << 1, 0, 0;
102  if (Hy) (*Hy) << 0, cx, -sx;
103  if (Hz) (*Hz) << -sy, sc_, cc_;
104  return Rot3(
105  _cc,- c_s + ssc, s_s + csc,
106  _cs, c_c + sss, -s_c + css,
107  -sy, sc_, cc_
108  );
109 }
110 
111 /* ************************************************************************* */
114 
118 
119  Matrix3 rot = rot_.matrix(), rot_orth;
120 
121  // Check if determinant is already 1.
122  // If yes, then return the current Rot3.
123  if (std::fabs(rot.determinant()-1) < 1e-12) return Rot3(rot_);
124 
125  Vector3 x = rot.block<1, 3>(0, 0), y = rot.block<1, 3>(1, 0);
126  double error = x.dot(y);
127 
128  Vector3 x_ort = x - (error / 2) * y, y_ort = y - (error / 2) * x;
129  Vector3 z_ort = x_ort.cross(y_ort);
130 
131  rot_orth.block<1, 3>(0, 0) = 0.5 * (3 - x_ort.dot(x_ort)) * x_ort;
132  rot_orth.block<1, 3>(1, 0) = 0.5 * (3 - y_ort.dot(y_ort)) * y_ort;
133  rot_orth.block<1, 3>(2, 0) = 0.5 * (3 - z_ort.dot(z_ort)) * z_ort;
134 
135  return Rot3(rot_orth);
136 }
137 
138 /* ************************************************************************* */
139 Rot3 Rot3::operator*(const Rot3& R2) const {
140  return Rot3(rot_*R2.rot_);
141 }
142 
143 /* ************************************************************************* */
144 Matrix3 Rot3::transpose() const {
145  return rot_.matrix().transpose();
146 }
147 
148 /* ************************************************************************* */
151  if (H1) *H1 = rot_.matrix() * skewSymmetric(-p.x(), -p.y(), -p.z());
152  if (H2) *H2 = rot_.matrix();
153  return rot_.matrix() * p;
154 }
155 
156 /* ************************************************************************* */
157 // Log map at identity - return the canonical coordinates of this rotation
159  return SO3::Logmap(R.rot_,H);
160 }
161 
162 /* ************************************************************************* */
164  if (H) throw std::runtime_error("Rot3::CayleyChart::Retract Derivative");
165  const double x = omega(0), y = omega(1), z = omega(2);
166  const double x2 = x * x, y2 = y * y, z2 = z * z;
167  const double xy = x * y, xz = x * z, yz = y * z;
168  const double f = 1.0 / (4.0 + x2 + y2 + z2), _2f = 2.0 * f;
169  return Rot3((4 + x2 - y2 - z2) * f, (xy - 2 * z) * _2f, (xz + 2 * y) * _2f,
170  (xy + 2 * z) * _2f, (4 - x2 + y2 - z2) * f, (yz - 2 * x) * _2f,
171  (xz - 2 * y) * _2f, (yz + 2 * x) * _2f, (4 - x2 - y2 + z2) * f);
172 }
173 
174 /* ************************************************************************* */
176  if (H) throw std::runtime_error("Rot3::CayleyChart::Local Derivative");
177  // Create a fixed-size matrix
178  Matrix3 A = R.matrix();
179 
180  // Check if (A+I) is invertible. Same as checking for -1 eigenvalue.
181  if ((A + I_3x3).determinant() == 0.0) {
182  throw std::runtime_error("Rot3::CayleyChart::Local Invalid Rotation");
183  }
184 
185  // Mathematica closed form optimization.
186  // The following are the essential computations for the following algorithm
187  // 1. Compute the inverse of P = (A+I), using a closed-form formula since P is 3x3
188  // 2. Compute the Cayley transform C = 2 * P^{-1} * (A-I)
189  // 3. C is skew-symmetric, so we pick out the computations corresponding only to x, y, and z.
190  const double a = A(0, 0), b = A(0, 1), c = A(0, 2);
191  const double d = A(1, 0), e = A(1, 1), f = A(1, 2);
192  const double g = A(2, 0), h = A(2, 1), i = A(2, 2);
193  const double di = d * i, ce = c * e, cd = c * d, fg = f * g;
194  const double M = 1 + e - f * h + i + e * i;
195  const double K = -4.0 / (cd * h + M + a * M - g * (c + ce) - b * (d + di - fg));
196  const double x = a * f - cd + f;
197  const double y = b * f - ce - c;
198  const double z = fg - di - d;
199  return K * Vector3(x, y, z);
200 }
201 
202 /* ************************************************************************* */
205  if (mode == Rot3::EXPMAP) return Expmap(omega, H);
206  if (mode == Rot3::CAYLEY) return CayleyChart::Retract(omega, H);
207  else throw std::runtime_error("Rot3::Retract: unknown mode");
208 }
209 
210 /* ************************************************************************* */
213  if (mode == Rot3::EXPMAP) return Logmap(R, H);
214  if (mode == Rot3::CAYLEY) return CayleyChart::Local(R, H);
215  else throw std::runtime_error("Rot3::Local: unknown mode");
216 }
217 
218 /* ************************************************************************* */
219 Matrix3 Rot3::matrix() const {
220  return rot_.matrix();
221 }
222 
223 /* ************************************************************************* */
224 Point3 Rot3::r1() const { return Point3(rot_.matrix().col(0)); }
225 
226 /* ************************************************************************* */
227 Point3 Rot3::r2() const { return Point3(rot_.matrix().col(1)); }
228 
229 /* ************************************************************************* */
230 Point3 Rot3::r3() const { return Point3(rot_.matrix().col(2)); }
231 
232 /* ************************************************************************* */
234  return gtsam::Quaternion(rot_.matrix());
235 }
236 
237 /* ************************************************************************* */
238 
239 } // namespace gtsam
240 
241 #endif
int EIGEN_BLAS_FUNC() rot(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pc, RealScalar *ps)
SO3 rot_
Definition: Rot3.h:67
Point3 r1() const
first column
Definition: Rot3M.cpp:224
Matrix< RealScalar, Dynamic, Dynamic > M
Definition: bench_gemm.cpp:38
Scalar * y
Eigen::Vector3d Vector3
Definition: Vector.h:43
void determinant(const MatrixType &m)
Definition: determinant.cpp:14
Use the Lie group exponential map to retract.
Definition: Rot3.h:343
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
Rot2 R(Rot2::fromAngle(0.1))
const double cx
static Cal3_S2 K(500, 500, 0.1, 640/2, 480/2)
static Vector3 Local(const Rot3 &r, OptionalJacobian< 3, 3 > H=boost::none)
Definition: Rot3M.cpp:175
Definition: Half.h:150
Pose3 x2(Rot3::Ypr(0.0, 0.0, 0.0), l2)
Matrix< float, 2, 1 > xy
Definition: LLT_solve.cpp:7
Matrix3 matrix() const
Definition: Rot3M.cpp:219
const MatrixNN & matrix() const
Return matrix.
Definition: SOn.h:152
static Rot3 RzRyRx(double x, double y, double z, OptionalJacobian< 3, 1 > Hx=boost::none, OptionalJacobian< 3, 1 > Hy=boost::none, OptionalJacobian< 3, 1 > Hz=boost::none)
Rotations around Z, Y, then X axes as in http://en.wikipedia.org/wiki/Rotation_matrix, counterclockwise when looking from unchanging axis.
Definition: Rot3M.cpp:85
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 set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics set mxtics default set mytics default set mx2tics default set my2tics default set xtics border mirror norotate autofreq set ytics border mirror norotate autofreq set ztics border nomirror norotate autofreq set nox2tics set noy2tics set timestamp bottom norotate set rrange[*:*] noreverse nowriteback set trange[*:*] noreverse nowriteback set urange[*:*] noreverse nowriteback set vrange[*:*] noreverse nowriteback set xlabel matrix size set x2label set timefmt d m y n H
Point3 rotate(const Point3 &p, OptionalJacobian< 3, 3 > H1=boost::none, OptionalJacobian< 3, 3 > H2=boost::none) const
Definition: Rot3M.cpp:149
3*3 matrix representation of SO(3)
Real fabs(const Real &a)
static Vector3 Local(const Rot3 &r, ChartJacobian H=boost::none)
Definition: Rot3M.cpp:211
Point2 z2
void g(const string &key, int i)
Definition: testBTree.cpp:43
Array33i a
Retract and localCoordinates using the Cayley transform.
Definition: Rot3.h:345
EIGEN_DEVICE_FUNC const CosReturnType cos() const
static Rot3 Rx(double t)
Rotation around X axis as in http://en.wikipedia.org/wiki/Rotation_matrix, counterclockwise when look...
Definition: Rot3M.cpp:57
SO< 3 > SO3
Definition: SO3.h:34
static EIGEN_DEVICE_FUNC Matrix< Scalar, 2, 2 > toRotationMatrix(const Scalar &s)
Definition: RotationBase.h:182
Point3 r2() const
second column
Definition: Rot3M.cpp:227
Point3 r3() const
third column
Definition: Rot3M.cpp:230
static Rot3 Retract(const Vector3 &v, ChartJacobian H=boost::none)
Definition: Rot3M.cpp:203
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Array< double, 1, 3 > e(1./3., 0.5, 2.)
EIGEN_DEVICE_FUNC const Scalar & q
static Rot3 Expmap(const Vector3 &v, OptionalJacobian< 3, 3 > H=boost::none)
Definition: Rot3.h:377
#define ROT3_DEFAULT_COORDINATES_MODE
Definition: Rot3.h:43
const G & b
Definition: Group.h:83
Matrix3 transpose() const
Definition: Rot3M.cpp:144
traits
Definition: chartTesting.h:28
const double h
Matrix3 skewSymmetric(double wx, double wy, double wz)
Definition: base/Matrix.h:404
static Vector3 Logmap(const Rot3 &R, OptionalJacobian< 3, 3 > H=boost::none)
Definition: Rot3M.cpp:158
static Rot3 Rz(double t)
Rotation around Z axis as in http://en.wikipedia.org/wiki/Rotation_matrix, counterclockwise when look...
Definition: Rot3M.cpp:75
The quaternion class used to represent 3D orientations and rotations.
Rot3 normalized() const
Definition: Rot3M.cpp:112
const double cy
float * p
static TangentVector Logmap(const SO &R, ChartJacobian H=boost::none)
static double error
Definition: testRot3.cpp:39
EIGEN_DEVICE_FUNC const SinReturnType sin() const
Vector3 Point3
Definition: Point3.h:35
const mpreal csc(const mpreal &x, mp_rnd_t r=mpreal::get_default_rnd())
Definition: mpreal.h:2234
Rot3 operator*(const Rot3 &R2) const
Syntatic sugar for composing two rotations.
Definition: Rot3M.cpp:139
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
static Rot3 Retract(const Vector3 &v, OptionalJacobian< 3, 3 > H=boost::none)
Definition: Rot3M.cpp:163
Q R2(Eigen::AngleAxisd(2, Vector3(0, 1, 0)))
gtsam::Quaternion toQuaternion() const
Definition: Rot3M.cpp:233
Point2 t(10, 10)
static Rot3 Ry(double t)
Rotation around Y axis as in http://en.wikipedia.org/wiki/Rotation_matrix, counterclockwise when look...
Definition: Rot3M.cpp:66
CoordinatesMode
Definition: Rot3.h:342
3D rotation represented as a rotation matrix or quaternion
Eigen::Quaternion< double, Eigen::DontAlign > Quaternion


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:43:53