g2o
Loading...
Searching...
No Matches
se3quat.h
Go to the documentation of this file.
1// g2o - General Graph Optimization
2// Copyright (C) 2011 H. Strasdat
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright notice,
10// this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27#ifndef G2O_SE3QUAT_H_
28#define G2O_SE3QUAT_H_
29
30#include <Eigen/Core>
31#include <Eigen/Geometry>
32#include <cassert>
33
34#include "g2o/stuff/misc.h"
35#include "se3_ops.h"
36
37namespace g2o {
38
40 public:
42
43 protected:
46
47 public:
49 _r.setIdentity();
50 _t.setZero();
51 }
52
53 SE3Quat(const Matrix3& R, const Vector3& t) : _r(Quaternion(R)), _t(t) {
54 normalizeRotation();
55 }
56
57 SE3Quat(const Quaternion& q, const Vector3& t) : _r(q), _t(t) {
58 normalizeRotation();
59 }
60
65 template <typename Derived>
66 explicit SE3Quat(const Eigen::MatrixBase<Derived>& v) {
67 assert((v.size() == 6 || v.size() == 7) &&
68 "Vector dimension does not match");
69 if (v.size() == 6) {
70 for (int i = 0; i < 3; i++) {
71 _t[i] = v[i];
72 _r.coeffs()(i) = v[i + 3];
73 }
74 _r.w() = 0.; // recover the positive w
75 if (_r.norm() > 1.) {
76 _r.normalize();
77 } else {
78 double w2 = cst(1.) - _r.squaredNorm();
79 _r.w() = (w2 < cst(0.)) ? cst(0.) : std::sqrt(w2);
80 }
81 } else if (v.size() == 7) {
82 int idx = 0;
83 for (int i = 0; i < 3; ++i, ++idx) _t(i) = v(idx);
84 for (int i = 0; i < 4; ++i, ++idx) _r.coeffs()(i) = v(idx);
85 normalizeRotation();
86 }
87 }
88
89 inline const Vector3& translation() const { return _t; }
90
91 inline void setTranslation(const Vector3& t_) { _t = t_; }
92
93 inline const Quaternion& rotation() const { return _r; }
94
95 void setRotation(const Quaternion& r_) { _r = r_; }
96
97 inline SE3Quat operator*(const SE3Quat& tr2) const {
98 SE3Quat result(*this);
99 result._t += _r * tr2._t;
100 result._r *= tr2._r;
101 result.normalizeRotation();
102 return result;
103 }
104
105 inline SE3Quat& operator*=(const SE3Quat& tr2) {
106 _t += _r * tr2._t;
107 _r *= tr2._r;
108 normalizeRotation();
109 return *this;
110 }
111
112 inline Vector3 operator*(const Vector3& v) const { return _t + _r * v; }
113
114 inline SE3Quat inverse() const {
115 SE3Quat ret;
116 ret._r = _r.conjugate();
117 ret._t = ret._r * (_t * -cst(1.));
118 return ret;
119 }
120
121 inline double operator[](int i) const {
122 assert(i < 7);
123 if (i < 3) return _t[i];
124 return _r.coeffs()[i - 3];
125 }
126
127 inline Vector7 toVector() const {
128 Vector7 v;
129 v[0] = _t(0);
130 v[1] = _t(1);
131 v[2] = _t(2);
132 v[3] = _r.x();
133 v[4] = _r.y();
134 v[5] = _r.z();
135 v[6] = _r.w();
136 return v;
137 }
138
139 inline void fromVector(const Vector7& v) {
140 _r = Quaternion(v[6], v[3], v[4], v[5]);
141 _t = Vector3(v[0], v[1], v[2]);
142 }
143
144 inline Vector6 toMinimalVector() const {
145 Vector6 v;
146 v[0] = _t(0);
147 v[1] = _t(1);
148 v[2] = _t(2);
149 v[3] = _r.x();
150 v[4] = _r.y();
151 v[5] = _r.z();
152 return v;
153 }
154
155 inline void fromMinimalVector(const Vector6& v) {
156 double w = cst(1.) - v[3] * v[3] - v[4] * v[4] - v[5] * v[5];
157 if (w > 0) {
158 _r = Quaternion(std::sqrt(w), v[3], v[4], v[5]);
159 } else {
160 _r = Quaternion(0, -v[3], -v[4], -v[5]);
161 }
162 _t = Vector3(v[0], v[1], v[2]);
163 }
164
165 Vector6 log() const {
166 Vector6 res;
167 Matrix3 _R = _r.toRotationMatrix();
168 double d = cst(0.5) * (_R(0, 0) + _R(1, 1) + _R(2, 2) - 1);
169 Vector3 omega;
170 Vector3 upsilon;
171
172 Vector3 dR = deltaR(_R);
173 Matrix3 V_inv;
174
175 if (std::abs(d) > cst(0.99999)) {
176 omega = 0.5 * dR;
177 Matrix3 Omega = skew(omega);
178 V_inv = Matrix3::Identity() - cst(0.5) * Omega +
179 (cst(1.) / cst(12.)) * (Omega * Omega);
180 } else {
181 double theta = std::acos(d);
182 omega = theta / (2 * std::sqrt(1 - d * d)) * dR;
183 Matrix3 Omega = skew(omega);
184 V_inv = (Matrix3::Identity() - cst(0.5) * Omega +
185 (1 - theta / (2 * std::tan(theta / 2))) / (theta * theta) *
186 (Omega * Omega));
187 }
188
189 upsilon = V_inv * _t;
190 for (int i = 0; i < 3; i++) {
191 res[i] = omega[i];
192 }
193 for (int i = 0; i < 3; i++) {
194 res[i + 3] = upsilon[i];
195 }
196
197 return res;
198 }
199
200 Vector3 map(const Vector3& xyz) const { return _r * xyz + _t; }
201
202 static SE3Quat exp(const Vector6& update) {
203 Vector3 omega;
204 for (int i = 0; i < 3; i++) omega[i] = update[i];
205 Vector3 upsilon;
206 for (int i = 0; i < 3; i++) upsilon[i] = update[i + 3];
207
208 double theta = omega.norm();
209 Matrix3 Omega = skew(omega);
210
211 Matrix3 R;
212 Matrix3 V;
213 if (theta < cst(0.00001)) {
214 Matrix3 Omega2 = Omega * Omega;
215
216 R = (Matrix3::Identity() + Omega + cst(0.5) * Omega2);
217
218 V = (Matrix3::Identity() + cst(0.5) * Omega + cst(1.) / cst(6.) * Omega2);
219 } else {
220 Matrix3 Omega2 = Omega * Omega;
221
222 R = (Matrix3::Identity() + std::sin(theta) / theta * Omega +
223 (1 - std::cos(theta)) / (theta * theta) * Omega2);
224
225 V = (Matrix3::Identity() +
226 (1 - std::cos(theta)) / (theta * theta) * Omega +
227 (theta - std::sin(theta)) / (std::pow(theta, 3)) * Omega2);
228 }
229 return SE3Quat(Quaternion(R), V * upsilon);
230 }
231
232 Eigen::Matrix<double, 6, 6, Eigen::ColMajor> adj() const {
233 Matrix3 R = _r.toRotationMatrix();
234 Eigen::Matrix<double, 6, 6, Eigen::ColMajor> res;
235 res.block(0, 0, 3, 3) = R;
236 res.block(3, 3, 3, 3) = R;
237 res.block(3, 0, 3, 3) = skew(_t) * R;
238 res.block(0, 3, 3, 3) = Matrix3::Zero(3, 3);
239 return res;
240 }
241
242 Eigen::Matrix<double, 4, 4, Eigen::ColMajor> to_homogeneous_matrix() const {
243 Eigen::Matrix<double, 4, 4, Eigen::ColMajor> homogeneous_matrix;
244 homogeneous_matrix.setIdentity();
245 homogeneous_matrix.block(0, 0, 3, 3) = _r.toRotationMatrix();
246 homogeneous_matrix.col(3).head(3) = translation();
247
248 return homogeneous_matrix;
249 }
250
252 if (_r.w() < 0) {
253 _r.coeffs() *= -1;
254 }
255 _r.normalize();
256 }
257
261 operator Isometry3() const {
262 Isometry3 result = (Isometry3)rotation();
263 result.translation() = translation();
264 return result;
265 }
266};
267
268inline std::ostream& operator<<(std::ostream& out_str, const SE3Quat& se3) {
269 out_str << se3.to_homogeneous_matrix() << std::endl;
270 return out_str;
271}
272
273// G2O_TYPES_SLAM3D_API Quaternion euler_to_quat(double yaw, double pitch,
274// double roll); G2O_TYPES_SLAM3D_API void quat_to_euler(const Quaternion& q,
275// double& yaw, double& pitch, double& roll); G2O_TYPES_SLAM3D_API void
276// jac_quat3_euler3(Eigen::Matrix<double, 6, 6, Eigen::ColMajor>& J, const
277// SE3Quat& t);
278
279} // namespace g2o
280
281#endif
void normalizeRotation()
Definition se3quat.h:251
SE3Quat operator*(const SE3Quat &tr2) const
Definition se3quat.h:97
Quaternion _r
Definition se3quat.h:44
Vector6 toMinimalVector() const
Definition se3quat.h:144
static SE3Quat exp(const Vector6 &update)
Definition se3quat.h:202
SE3Quat(const Quaternion &q, const Vector3 &t)
Definition se3quat.h:57
Eigen::Matrix< double, 4, 4, Eigen::ColMajor > to_homogeneous_matrix() const
Definition se3quat.h:242
SE3Quat & operator*=(const SE3Quat &tr2)
Definition se3quat.h:105
const Quaternion & rotation() const
Definition se3quat.h:93
Vector3 operator*(const Vector3 &v) const
Definition se3quat.h:112
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
Definition se3quat.h:41
void fromVector(const Vector7 &v)
Definition se3quat.h:139
Vector6 log() const
Definition se3quat.h:165
void fromMinimalVector(const Vector6 &v)
Definition se3quat.h:155
const Vector3 & translation() const
Definition se3quat.h:89
SE3Quat inverse() const
Definition se3quat.h:114
Vector3 _t
Definition se3quat.h:45
void setRotation(const Quaternion &r_)
Definition se3quat.h:95
SE3Quat(const Matrix3 &R, const Vector3 &t)
Definition se3quat.h:53
SE3Quat(const Eigen::MatrixBase< Derived > &v)
Definition se3quat.h:66
void setTranslation(const Vector3 &t_)
Definition se3quat.h:91
double operator[](int i) const
Definition se3quat.h:121
Vector3 map(const Vector3 &xyz) const
Definition se3quat.h:200
Eigen::Matrix< double, 6, 6, Eigen::ColMajor > adj() const
Definition se3quat.h:232
Vector7 toVector() const
Definition se3quat.h:127
#define G2O_TYPES_SLAM3D_API
some general case utility functions
VectorN< 3 > Vector3
Definition eigen_types.h:51
VectorN< 7 > Vector7
Definition eigen_types.h:54
MatrixN< 3 > Matrix3
Definition eigen_types.h:72
constexpr double cst(long double v)
Definition misc.h:60
Eigen::Transform< double, 3, Eigen::Isometry, Eigen::ColMajor > Isometry3
Definition eigen_types.h:77
VectorN< 6 > Vector6
Definition eigen_types.h:53
std::ostream & operator<<(std::ostream &os, const G2OBatchStatistics &st)
Eigen::Quaternion< double > Quaternion
Definition eigen_types.h:81
Vector3 deltaR(const Matrix3 &R)
Definition se3_ops.hpp:39
Matrix3 skew(const Vector3 &v)
Definition se3_ops.hpp:27