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