g2o
Loading...
Searching...
No Matches
sim3.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_SIM_3
28#define G2O_SIM_3
29
30#include <Eigen/Geometry>
31#include <cassert>
32
33#include "g2o/stuff/misc.h"
35
36namespace g2o {
37struct Sim3 {
38 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
39
40 protected:
43 double s;
44
45 public:
46 Sim3() {
47 r.setIdentity();
48 t.fill(0.);
49 s = 1.;
50 }
51
52 Sim3(const Quaternion& r, const Vector3& t, double s) : r(r), t(t), s(s) {
54 }
55
56 Sim3(const Matrix3& R, const Vector3& t, double s)
57 : r(Quaternion(R)), t(t), s(s) {
59 }
60
61 Sim3(const Vector7& update) {
62 Vector3 omega;
63 for (int i = 0; i < 3; i++) omega[i] = update[i];
64
65 Vector3 upsilon;
66 for (int i = 0; i < 3; i++) upsilon[i] = update[i + 3];
67
68 double sigma = update[6];
69 double theta = omega.norm();
70 Matrix3 Omega = skew(omega);
71 s = std::exp(sigma);
72 Matrix3 Omega2 = Omega * Omega;
73 Matrix3 I;
74 I.setIdentity();
75 Matrix3 R;
76
77 double eps = cst(0.00001);
78 double A, B, C;
79 if (fabs(sigma) < eps) {
80 C = 1;
81 if (theta < eps) {
82 A = cst(1. / 2.);
83 B = cst(1. / 6.);
84 R = (I + Omega +
85 Omega * Omega /
86 2); // R=I+(1-cos(theta))*a^a^+sin(theta)*a^~=(omit
87 // O(theta^3))=I+theta^2/2*a^a^+theta*a^
88 } else {
89 double theta2 = theta * theta;
90 A = (1 - std::cos(theta)) / (theta2);
91 B = (theta - std::sin(theta)) / (theta2 * theta);
92 R = I + std::sin(theta) / theta * Omega +
93 (1 - std::cos(theta)) / (theta * theta) * Omega2;
94 }
95 } else {
96 C = (s - 1) / sigma;
97 if (theta < eps) {
98 double sigma2 = sigma * sigma;
99 A = ((sigma - 1) * s + 1) / sigma2;
100 B = ((cst(0.5) * sigma2 - sigma + 1) * s - 1) /
101 (sigma2 *
102 sigma); // B=[C-((s*cos(theta)-1)*sigma+s*sin(theta)*theta)/(sigma^2+theta^2)]/theta^2~=(omit
103 // O(theta^2))=
104 //(1/2*s*sigma-s)/(sigma^2)+[C-(s-1)*sigma/(sigma^2+theta^2)]/theta^2~=(0.5*sigma^2*s-s*sigma)/sigma^3+[s-1]/sigma^3=[s*(0.5*sigma^2-sigma+1)-1]/sigma^3
105 R = (I + Omega +
106 Omega2 /
107 2); // R=I+(1-cos(theta))*a^a^+sin(theta)*a^~=I+theta^2/2*a^a^+theta*a^
108 } else {
109 R = I + std::sin(theta) / theta * Omega +
110 (1 - std::cos(theta)) / (theta * theta) * Omega2;
111 double a = s * std::sin(theta);
112 double b = s * std::cos(theta);
113 double theta2 = theta * theta;
114 double sigma2 = sigma * sigma;
115 double c = theta2 + sigma2;
116 A = (a * sigma + (1 - b) * theta) / (theta * c);
117 B = (C - ((b - 1) * sigma + a * theta) / (c)) * 1 / (theta2);
118 }
119 }
120 r = Quaternion(R);
121
122 Matrix3 W = A * Omega + B * Omega2 + C * I;
123 t = W * upsilon;
124 }
125
126 Vector3 map(const Vector3& xyz) const { return s * (r * xyz) + t; }
127
128 Vector7 log() const {
129 Vector7 res;
130 double sigma = std::log(s);
131
132 Vector3 omega;
133 Vector3 upsilon;
134
135 Matrix3 R = r.toRotationMatrix();
136 double d = cst(0.5) * (R(0, 0) + R(1, 1) + R(2, 2) - 1);
137
138 Matrix3 Omega;
139
140 double eps = cst(0.00001);
141 Matrix3 I = Matrix3::Identity();
142
143 double A, B, C;
144 if (fabs(sigma) < eps) {
145 C = 1;
146 if (d > 1 - eps) {
147 omega = 0.5 * deltaR(R);
148 Omega = skew(omega);
149 A = cst(1. / 2.);
150 B = cst(1. / 6.);
151 } else {
152 double theta = std::acos(d);
153 double theta2 = theta * theta;
154 omega = theta / (2 * std::sqrt(1 - d * d)) * deltaR(R);
155 Omega = skew(omega);
156 A = (1 - std::cos(theta)) / (theta2);
157 B = (theta - std::sin(theta)) / (theta2 * theta);
158 }
159 } else {
160 C = (s - 1) / sigma;
161 if (d > 1 - eps) {
162 double sigma2 = sigma * sigma;
163 omega = cst(0.5) * deltaR(R);
164 Omega = skew(omega);
165 A = ((sigma - 1) * s + 1) / (sigma2);
166 B = ((cst(0.5) * sigma2 - sigma + 1) * s - 1) /
167 (sigma2 *
168 sigma); // B=[C-((s*cos(theta)-1)*sigma+s*sin(theta)*theta)/(sigma^2+theta^2)]/theta^2
169 // use
170 // limit(theta->0)(B)=limit(theta->0){[(sigma2+theta2)*(s*sigma*sin(theta)-s*sin(theta)-s*theta*cos(theta))+(s*cos(theta)*sigma-sigma+s*sin(theta)*theta)*2*theta]/(2*theta)}=
171 //=limit(theta->0)(s*sigma-s)*sin(theta)/(2*(sigma2+theta2)*theta)+limit(theta->0)[-s*cos(theta)/(2*(sigma2+theta2))+(s*cos(theta)*sigma-sigma+s*sin(theta)*theta)/(sigma2+theta2)^2]=
172 //=limit(theta->0)(s*sigma-s)*cos(theta)/(2*(sigma2+3*theta2))+-s/(2*sigma2)+(s-1)/sigma^3=
173 //=(s*sigma-s)/2/sigma2-s/2/sigma2+(s-1)/sigma^3=[(0.5*sigma2-sigma+1)*s-1]/sigma^3
174 } else {
175 double theta = std::acos(d);
176 omega = theta / (2 * std::sqrt(1 - d * d)) * deltaR(R);
177 Omega = skew(omega);
178 double theta2 = theta * theta;
179 double a = s * std::sin(theta);
180 double b = s * std::cos(theta);
181 double c = theta2 + sigma * sigma;
182 A = (a * sigma + (1 - b) * theta) / (theta * c);
183 B = (C - ((b - 1) * sigma + a * theta) / (c)) * 1 / (theta2);
184 }
185 }
186
187 Matrix3 W = A * Omega + B * Omega * Omega + C * I;
188
189 upsilon = W.lu().solve(t);
190
191 for (int i = 0; i < 3; i++) res[i] = omega[i];
192
193 for (int i = 0; i < 3; i++) res[i + 3] = upsilon[i];
194
195 res[6] = sigma;
196
197 return res;
198 }
199
200 Sim3 inverse() const {
201 return Sim3(r.conjugate(), r.conjugate() * ((-1 / s) * t), 1 / s);
202 }
203
204 double operator[](int i) const {
205 assert(i < 8);
206 if (i < 4) {
207 return r.coeffs()[i];
208 }
209 if (i < 7) {
210 return t[i - 4];
211 }
212 return s;
213 }
214
215 double& operator[](int i) {
216 assert(i < 8);
217 if (i < 4) {
218 return r.coeffs()[i];
219 }
220 if (i < 7) {
221 return t[i - 4];
222 }
223 return s;
224 }
225
226 Sim3 operator*(const Sim3& other) const {
227 Sim3 ret;
228 ret.r = r * other.r;
229 ret.t = s * (r * other.t) + t;
230 ret.s = s * other.s;
231 return ret;
232 }
233
234 Sim3& operator*=(const Sim3& other) {
235 Sim3 ret = (*this) * other;
236 *this = ret;
237 return *this;
238 }
240 if (r.w() < 0) {
241 r.coeffs() *= -1;
242 }
243 r.normalize();
244 }
245 inline const Vector3& translation() const { return t; }
246
247 inline Vector3& translation() { return t; }
248
249 inline const Quaternion& rotation() const { return r; }
250
251 inline Quaternion& rotation() { return r; }
252
253 inline const double& scale() const { return s; }
254
255 inline double& scale() { return s; }
256};
257
258inline std::ostream& operator<<(std::ostream& out_str, const Sim3& sim3) {
259 out_str << sim3.rotation().coeffs() << std::endl;
260 out_str << sim3.translation() << std::endl;
261 out_str << sim3.scale() << std::endl;
262
263 return out_str;
264}
265
266} // namespace g2o
267
268#endif
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
G2O_TYPES_SLAM3D_API Vector3 deltaR(const Matrix3 &R)
G2O_TYPES_SLAM3D_API Matrix3 skew(const Vector3 &v)
constexpr double cst(long double v)
Definition misc.h:60
std::ostream & operator<<(std::ostream &os, const G2OBatchStatistics &st)
Eigen::Quaternion< double > Quaternion
Definition eigen_types.h:81
Vector7 log() const
Definition sim3.h:128
double s
Definition sim3.h:43
Sim3(const Matrix3 &R, const Vector3 &t, double s)
Definition sim3.h:56
double operator[](int i) const
Definition sim3.h:204
Quaternion & rotation()
Definition sim3.h:251
Vector3 map(const Vector3 &xyz) const
Definition sim3.h:126
const Quaternion & rotation() const
Definition sim3.h:249
Vector3 & translation()
Definition sim3.h:247
Sim3(const Quaternion &r, const Vector3 &t, double s)
Definition sim3.h:52
Sim3 & operator*=(const Sim3 &other)
Definition sim3.h:234
void normalizeRotation()
Definition sim3.h:239
Sim3 operator*(const Sim3 &other) const
Definition sim3.h:226
double & operator[](int i)
Definition sim3.h:215
Quaternion r
Definition sim3.h:41
Vector3 t
Definition sim3.h:42
Sim3(const Vector7 &update)
Definition sim3.h:61
Sim3 inverse() const
Definition sim3.h:200
const Vector3 & translation() const
Definition sim3.h:245
Sim3()
Definition sim3.h:46
const double & scale() const
Definition sim3.h:253
double & scale()
Definition sim3.h:255