g2o
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 "se3_ops.h"
31 
32 #include <Eigen/Core>
33 #include <Eigen/Geometry>
34 
35 namespace g2o {
36 
37  typedef Eigen::Matrix<double, 6, 1, Eigen::ColMajor> Vector6d;
38  typedef Eigen::Matrix<double, 7, 1, Eigen::ColMajor> Vector7d;
39 
41  public:
43 
44  protected:
45 
46  Eigen::Quaterniond _r;
48 
49  public:
51  _r.setIdentity();
52  _t.setZero();
53  }
54 
55  SE3Quat(const Matrix3D& R, const Vector3D& t):_r(Eigen::Quaterniond(R)),_t(t){
56  normalizeRotation();
57  }
58 
59  SE3Quat(const Eigen::Quaterniond& q, const Vector3D& t):_r(q),_t(t){
60  normalizeRotation();
61  }
62 
66  template <typename Derived>
67  explicit SE3Quat(const Eigen::MatrixBase<Derived>& v)
68  {
69  assert((v.size() == 6 || v.size() == 7) && "Vector dimension does not match");
70  if (v.size() == 6) {
71  for (int i=0; i<3; i++){
72  _t[i]=v[i];
73  _r.coeffs()(i)=v[i+3];
74  }
75  _r.w() = 0.; // recover the positive w
76  if (_r.norm()>1.){
77  _r.normalize();
78  } else {
79  double w2=1.-_r.squaredNorm();
80  _r.w()= (w2<0.) ? 0. : sqrt(w2);
81  }
82  }
83  else if (v.size() == 7) {
84  int idx = 0;
85  for (int i=0; i<3; ++i, ++idx)
86  _t(i) = v(idx);
87  for (int i=0; i<4; ++i, ++idx)
88  _r.coeffs()(i) = v(idx);
89  normalizeRotation();
90  }
91  }
92 
93  inline const Vector3D& translation() const {return _t;}
94 
95  inline void setTranslation(const Vector3D& t_) {_t = t_;}
96 
97  inline const Eigen::Quaterniond& rotation() const {return _r;}
98 
99  void setRotation(const Eigen::Quaterniond& r_) {_r=r_;}
100 
101  inline SE3Quat operator* (const SE3Quat& tr2) const{
102  SE3Quat result(*this);
103  result._t += _r*tr2._t;
104  result._r*=tr2._r;
105  result.normalizeRotation();
106  return result;
107  }
108 
109  inline SE3Quat& operator*= (const SE3Quat& tr2){
110  _t+=_r*tr2._t;
111  _r*=tr2._r;
112  normalizeRotation();
113  return *this;
114  }
115 
116  inline Vector3D operator* (const Vector3D& v) const {
117  return _t+_r*v;
118  }
119 
120  inline SE3Quat inverse() const{
121  SE3Quat ret;
122  ret._r=_r.conjugate();
123  ret._t=ret._r*(_t*-1.);
124  return ret;
125  }
126 
127  inline double operator [](int i) const {
128  assert(i<7);
129  if (i<3)
130  return _t[i];
131  return _r.coeffs()[i-3];
132  }
133 
134 
135  inline Vector7d toVector() const{
136  Vector7d v;
137  v[0]=_t(0);
138  v[1]=_t(1);
139  v[2]=_t(2);
140  v[3]=_r.x();
141  v[4]=_r.y();
142  v[5]=_r.z();
143  v[6]=_r.w();
144  return v;
145  }
146 
147  inline void fromVector(const Vector7d& v){
148  _r=Eigen::Quaterniond(v[6], v[3], v[4], v[5]);
149  _t=Vector3D(v[0], v[1], v[2]);
150  }
151 
152  inline Vector6d toMinimalVector() const{
153  Vector6d v;
154  v[0]=_t(0);
155  v[1]=_t(1);
156  v[2]=_t(2);
157  v[3]=_r.x();
158  v[4]=_r.y();
159  v[5]=_r.z();
160  return v;
161  }
162 
163  inline void fromMinimalVector(const Vector6d& v){
164  double w = 1.-v[3]*v[3]-v[4]*v[4]-v[5]*v[5];
165  if (w>0){
166  _r=Eigen::Quaterniond(sqrt(w), v[3], v[4], v[5]);
167  } else {
168  _r=Eigen::Quaterniond(0, -v[3], -v[4], -v[5]);
169  }
170  _t=Vector3D(v[0], v[1], v[2]);
171  }
172 
173 
174 
175  Vector6d log() const {
176  Vector6d res;
177  Matrix3D _R = _r.toRotationMatrix();
178  double d = 0.5*(_R(0,0)+_R(1,1)+_R(2,2)-1);
179  Vector3D omega;
180  Vector3D upsilon;
181 
182 
183  Vector3D dR = deltaR(_R);
184  Matrix3D V_inv;
185 
186  if (d>0.99999)
187  {
188 
189  omega=0.5*dR;
190  Matrix3D Omega = skew(omega);
191  V_inv = Matrix3D::Identity()- 0.5*Omega + (1./12.)*(Omega*Omega);
192  }
193  else
194  {
195  double theta = acos(d);
196  omega = theta/(2*sqrt(1-d*d))*dR;
197  Matrix3D Omega = skew(omega);
198  V_inv = ( Matrix3D::Identity() - 0.5*Omega
199  + ( 1-theta/(2*tan(theta/2)))/(theta*theta)*(Omega*Omega) );
200  }
201 
202  upsilon = V_inv*_t;
203  for (int i=0; i<3;i++){
204  res[i]=omega[i];
205  }
206  for (int i=0; i<3;i++){
207  res[i+3]=upsilon[i];
208  }
209 
210  return res;
211 
212  }
213 
214  Vector3D map(const Vector3D & xyz) const
215  {
216  return _r*xyz + _t;
217  }
218 
219 
220  static SE3Quat exp(const Vector6d & update)
221  {
222  Vector3D omega;
223  for (int i=0; i<3; i++)
224  omega[i]=update[i];
225  Vector3D upsilon;
226  for (int i=0; i<3; i++)
227  upsilon[i]=update[i+3];
228 
229  double theta = omega.norm();
230  Matrix3D Omega = skew(omega);
231 
232  Matrix3D R;
233  Matrix3D V;
234  if (theta<0.00001)
235  {
236  //TODO: CHECK WHETHER THIS IS CORRECT!!!
237  R = (Matrix3D::Identity() + Omega + Omega*Omega);
238 
239  V = R;
240  }
241  else
242  {
243  Matrix3D Omega2 = Omega*Omega;
244 
245  R = (Matrix3D::Identity()
246  + sin(theta)/theta *Omega
247  + (1-cos(theta))/(theta*theta)*Omega2);
248 
249  V = (Matrix3D::Identity()
250  + (1-cos(theta))/(theta*theta)*Omega
251  + (theta-sin(theta))/(pow(theta,3))*Omega2);
252  }
253  return SE3Quat(Eigen::Quaterniond(R),V*upsilon);
254  }
255 
256  Eigen::Matrix<double, 6, 6, Eigen::ColMajor> adj() const
257  {
258  Matrix3D R = _r.toRotationMatrix();
259  Eigen::Matrix<double, 6, 6, Eigen::ColMajor> res;
260  res.block(0,0,3,3) = R;
261  res.block(3,3,3,3) = R;
262  res.block(3,0,3,3) = skew(_t)*R;
263  res.block(0,3,3,3) = Matrix3D::Zero(3,3);
264  return res;
265  }
266 
267  Eigen::Matrix<double,4,4,Eigen::ColMajor> to_homogeneous_matrix() const
268  {
269  Eigen::Matrix<double,4,4,Eigen::ColMajor> homogeneous_matrix;
270  homogeneous_matrix.setIdentity();
271  homogeneous_matrix.block(0,0,3,3) = _r.toRotationMatrix();
272  homogeneous_matrix.col(3).head(3) = translation();
273 
274  return homogeneous_matrix;
275  }
276 
278  if (_r.w()<0){
279  _r.coeffs() *= -1;
280  }
281  _r.normalize();
282  }
283 
287  operator Isometry3D() const
288  {
289  Isometry3D result = (Isometry3D) rotation();
290  result.translation() = translation();
291  return result;
292  }
293  };
294 
295  inline std::ostream& operator <<(std::ostream& out_str, const SE3Quat& se3)
296  {
297  out_str << se3.to_homogeneous_matrix() << std::endl;
298  return out_str;
299  }
300 
301  //G2O_TYPES_SLAM3D_API Eigen::Quaterniond euler_to_quat(double yaw, double pitch, double roll);
302  //G2O_TYPES_SLAM3D_API void quat_to_euler(const Eigen::Quaterniond& q, double& yaw, double& pitch, double& roll);
303  //G2O_TYPES_SLAM3D_API void jac_quat3_euler3(Eigen::Matrix<double, 6, 6, Eigen::ColMajor>& J, const SE3Quat& t);
304 
305 } // end namespace
306 
307 #endif
Eigen::Matrix< double, 4, 4, Eigen::ColMajor > to_homogeneous_matrix() const
Definition: se3quat.h:267
Eigen::Matrix< double, 3, 1, Eigen::ColMajor > Vector3D
Definition: eigen_types.h:46
Vector7d toVector() const
Definition: se3quat.h:135
Vector3D map(const Vector3D &xyz) const
Definition: se3quat.h:214
Eigen::Matrix< double, 7, 1 > Vector7d
Definition: sim3.h:35
Line2D operator*(const SE2 &t, const Line2D &l)
Definition: line_2d.h:48
Eigen::Matrix< double, 6, 6, Eigen::ColMajor > adj() const
Definition: se3quat.h:256
Vector6d log() const
Definition: se3quat.h:175
SE3Quat(const Eigen::Quaterniond &q, const Vector3D &t)
Definition: se3quat.h:59
SE3Quat inverse() const
Definition: se3quat.h:120
static SE3Quat exp(const Vector6d &update)
Definition: se3quat.h:220
Vector6d toMinimalVector() const
Definition: se3quat.h:152
#define G2O_TYPES_SLAM3D_API
void fromMinimalVector(const Vector6d &v)
Definition: se3quat.h:163
Eigen::Transform< double, 3, Eigen::Isometry, Eigen::ColMajor > Isometry3D
Definition: eigen_types.h:66
void normalizeRotation()
Definition: se3quat.h:277
void fromVector(const Vector7d &v)
Definition: se3quat.h:147
const Eigen::Quaterniond & rotation() const
Definition: se3quat.h:97
SE3Quat(const Matrix3D &R, const Vector3D &t)
Definition: se3quat.h:55
Eigen::Matrix< double, 3, 3, Eigen::ColMajor > Matrix3D
Definition: eigen_types.h:61
Eigen::Quaterniond _r
Definition: se3quat.h:46
std::ostream & operator<<(std::ostream &os, const G2OBatchStatistics &st)
Definition: batch_stats.cpp:48
void setTranslation(const Vector3D &t_)
Definition: se3quat.h:95
Vector3D _t
Definition: se3quat.h:47
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
Definition: se3quat.h:42
G2O_TYPES_SLAM3D_API Vector3D deltaR(const Matrix3D &R)
Definition: se3_ops.h:41
void setRotation(const Eigen::Quaterniond &r_)
Definition: se3quat.h:99
G2O_TYPES_SLAM3D_API Matrix3D skew(const Vector3D &v)
Definition: se3_ops.h:28
SE3Quat(const Eigen::MatrixBase< Derived > &v)
Definition: se3quat.h:67
const Vector3D & translation() const
Definition: se3quat.h:93
Matrix< double, 6, 1, Eigen::ColMajor > Vector6d
Definition: types_icp.cpp:75