SLAMflex SE  0.1.0
SLAMflex provides detection and tracking of dominant planes for smartphone devices. This plane can then be used to show AR content relative to the plane orientation. The detection of plane is performed in the field of view of the smartphone camera. In subsequent frames it is tracked. The interface returns the plane position and orientation.
se2.h
Go to the documentation of this file.
1 // -*- c++ -*-
2 
3 // Copyright (C) 2005,2009 Tom Drummond (twd20@cam.ac.uk),
4 // Ed Rosten (er258@cam.ac.uk), Gerhard Reitmayr (gr281@cam.ac.uk)
5 //
6 // This file is part of the TooN Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11 
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING. If not, write to the Free
19 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 // USA.
21 
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction. Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License. This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
30 
31 /* This code mostly made by copying from se3.h !! */
32 
33 #ifndef TOON_INCLUDE_SE2_H
34 #define TOON_INCLUDE_SE2_H
35 
36 #include "so2.h"
37 
38 
39 namespace TooN {
40 
51 template <typename Precision = double>
52 class SE2 {
53 public:
56  template <class A> SE2(const SO2<Precision>& R, const Vector<2,Precision,A>& T) : my_rotation(R), my_translation(T) {}
57  template <int S, class P, class A> SE2(const Vector<S, P, A> & v) { *this = exp(v); }
58 
62  const SO2<Precision> & get_rotation() const {return my_rotation;}
67 
71  template <int S, typename P, typename A>
72  static inline SE2 exp(const Vector<S,P, A>& vect);
73 
76  static inline Vector<3, Precision> ln(const SE2& se2);
78  Vector<3, Precision> ln() const { return SE2::ln(*this); }
79 
81  SE2 inverse() const {
82  const SO2<Precision> & rinv = my_rotation.inverse();
83  return SE2(rinv, -(rinv*my_translation));
84  };
85 
88  template <typename P>
91  }
92 
95  inline SE2& operator *=(const SE2& rhs) {
96  *this = *this * rhs;
97  return *this;
98  }
99 
105  static inline Matrix<3,3, Precision> generator(int i) {
107  if(i < 2){
108  result[i][2] = 1;
109  return result;
110  }
111  result[0][1] = -1;
112  result[1][0] = 1;
113  return result;
114  }
115 
118  template<typename Accessor>
120  Vector<3, Precision> result;
121  result[2] = vect[2];
122  result.template slice<0,2>() = my_rotation * vect.template slice<0,2>();
123  result[0] += vect[2] * my_translation[1];
124  result[1] -= vect[2] * my_translation[0];
125  return result;
126  }
127 
128  template <typename Accessor>
130  Matrix<3,3,Precision> result;
131  for(int i=0; i<3; ++i)
132  result.T()[i] = adjoint(M.T()[i]);
133  for(int i=0; i<3; ++i)
134  result[i] = adjoint(result[i]);
135  return result;
136  }
137 
138 private:
141 };
142 
145 template <class Precision>
146 inline std::ostream& operator<<(std::ostream& os, const SE2<Precision> & rhs){
147  std::streamsize fw = os.width();
148  for(int i=0; i<2; i++){
149  os.width(fw);
150  os << rhs.get_rotation().get_matrix()[i];
151  os.width(fw);
152  os << rhs.get_translation()[i] << '\n';
153  }
154  return os;
155 }
156 
159 template <class Precision>
160 inline std::istream& operator>>(std::istream& is, SE2<Precision>& rhs){
161  for(int i=0; i<2; i++)
162  is >> rhs.get_rotation().my_matrix[i].ref() >> rhs.get_translation()[i];
163  rhs.get_rotation().coerce();
164  return is;
165 }
166 
167 
169 // operator * //
170 // SE2 * Vector //
172 
173 namespace Internal {
174 template<int S, typename P, typename PV, typename A>
175 struct SE2VMult;
176 }
177 
178 template<int S, typename P, typename PV, typename A>
179 struct Operator<Internal::SE2VMult<S,P,PV,A> > {
180  const SE2<P> & lhs;
182 
183  Operator(const SE2<P> & l, const Vector<S,PV,A> & r ) : lhs(l), rhs(r) {}
184 
185  template <int S0, typename P0, typename A0>
186  void eval(Vector<S0, P0, A0> & res ) const {
187  SizeMismatch<3,S>::test(3, rhs.size());
188  res.template slice<0,2>()=lhs.get_rotation()*rhs.template slice<0,2>();
189  res.template slice<0,2>()+=lhs.get_translation() * rhs[2];
190  res[2] = rhs[2];
191  }
192  int size() const { return 3; }
193 };
194 
197 template<int S, typename P, typename PV, typename A>
200 }
201 
204 template <typename P, typename PV, typename A>
206  return lhs.get_translation() + lhs.get_rotation() * rhs;
207 }
208 
210 // operator * //
211 // Vector * SE2 //
213 
214 namespace Internal {
215 template<int S, typename P, typename PV, typename A>
216 struct VSE2Mult;
217 }
218 
219 template<int S, typename P, typename PV, typename A>
220 struct Operator<Internal::VSE2Mult<S,P,PV,A> > {
222  const SE2<P> & rhs;
223 
224  Operator(const Vector<S,PV,A> & l, const SE2<P> & r ) : lhs(l), rhs(r) {}
225 
226  template <int S0, typename P0, typename A0>
227  void eval(Vector<S0, P0, A0> & res ) const {
228  SizeMismatch<3,S>::test(3, lhs.size());
229  res.template slice<0,2>() = lhs.template slice<0,2>()*rhs.get_rotation();
230  res[2] = lhs[2];
231  res[2] += lhs.template slice<0,2>() * rhs.get_translation();
232  }
233  int size() const { return 3; }
234 };
235 
238 template<int S, typename P, typename PV, typename A>
241 }
242 
244 // operator * //
245 // SE2 * Matrix //
247 
248 namespace Internal {
249 template <int R, int C, typename PM, typename A, typename P>
250 struct SE2MMult;
251 }
252 
253 template<int R, int Cols, typename PM, typename A, typename P>
254 struct Operator<Internal::SE2MMult<R, Cols, PM, A, P> > {
255  const SE2<P> & lhs;
257 
258  Operator(const SE2<P> & l, const Matrix<R,Cols,PM,A> & r ) : lhs(l), rhs(r) {}
259 
260  template <int R0, int C0, typename P0, typename A0>
261  void eval(Matrix<R0, C0, P0, A0> & res ) const {
262  SizeMismatch<3,R>::test(3, rhs.num_rows());
263  for(int i=0; i<rhs.num_cols(); ++i)
264  res.T()[i] = lhs * rhs.T()[i];
265  }
266  int num_cols() const { return rhs.num_cols(); }
267  int num_rows() const { return 3; }
268 };
269 
272 template <int R, int Cols, typename PM, typename A, typename P>
275 }
276 
278 // operator * //
279 // Matrix * SE2 //
281 
282 namespace Internal {
283 template <int Rows, int C, typename PM, typename A, typename P>
284 struct MSE2Mult;
285 }
286 
287 template<int Rows, int C, typename PM, typename A, typename P>
288 struct Operator<Internal::MSE2Mult<Rows, C, PM, A, P> > {
290  const SE2<P> & rhs;
291 
292  Operator( const Matrix<Rows,C,PM,A> & l, const SE2<P> & r ) : lhs(l), rhs(r) {}
293 
294  template <int R0, int C0, typename P0, typename A0>
295  void eval(Matrix<R0, C0, P0, A0> & res ) const {
296  SizeMismatch<3, C>::test(3, lhs.num_cols());
297  for(int i=0; i<lhs.num_rows(); ++i)
298  res[i] = lhs[i] * rhs;
299  }
300  int num_cols() const { return 3; }
301  int num_rows() const { return lhs.num_rows(); }
302 };
303 
306 template <int Rows, int C, typename PM, typename A, typename P>
309 }
310 
311 template <typename Precision>
312 template <int S, typename PV, typename Accessor>
314 {
315  SizeMismatch<3,S>::test(3, mu.size());
316 
317  static const Precision one_6th = 1.0/6.0;
318  static const Precision one_20th = 1.0/20.0;
319 
320  SE2<Precision> result;
321 
322  const Precision theta = mu[2];
323  const Precision theta_sq = theta * theta;
324 
325  const Vector<2, Precision> cross = makeVector( -theta * mu[1], theta * mu[0]);
326  result.get_rotation() = SO2<Precision>::exp(theta);
327 
328  if (theta_sq < 1e-8){
329  result.get_translation() = mu.template slice<0,2>() + 0.5 * cross;
330  } else {
331  Precision A, B;
332  if (theta_sq < 1e-6) {
333  A = 1.0 - theta_sq * one_6th*(1.0 - one_20th * theta_sq);
334  B = 0.5 - 0.25 * one_6th * theta_sq;
335  } else {
336  const Precision inv_theta = (1.0/theta);
337  const Precision sine = result.my_rotation.get_matrix()[1][0];
338  const Precision cosine = result.my_rotation.get_matrix()[0][0];
339  A = sine * inv_theta;
340  B = (1 - cosine) * (inv_theta * inv_theta);
341  }
342  result.get_translation() = TooN::operator*(A,mu.template slice<0,2>()) + TooN::operator*(B,cross);
343  }
344  return result;
345 }
346 
347 template <typename Precision>
349  const Precision theta = se2.get_rotation().ln();
350 
351  Precision shtot = 0.5;
352  if(fabs(theta) > 0.00001)
353  shtot = sin(theta/2)/theta;
354 
355  const SO2<Precision> halfrotator(theta * -0.5);
356  Vector<3, Precision> result;
357  result.template slice<0,2>() = (halfrotator * se2.get_translation())/(2 * shtot);
358  result[2] = theta;
359  return result;
360 }
361 
365 template <typename Precision>
366 inline SE2<Precision> operator*(const SO2<Precision> & lhs, const SE2<Precision>& rhs){
367  return SE2<Precision>( lhs*rhs.get_rotation(), lhs*rhs.get_translation());
368 }
369 
370 }
371 #endif
const Matrix< Rows, C, PM, A > & lhs
Definition: se2.h:289
SE2 inverse() const
compute the inverse of the transformation
Definition: se2.h:81
const SO2< Precision > & get_rotation() const
Definition: se2.h:62
Operator(const Vector< S, PV, A > &l, const SE2< P > &r)
Definition: se2.h:224
void eval(Matrix< R0, C0, P0, A0 > &res) const
Definition: se2.h:261
Vector< 3, typename Internal::MultiplyType< PV, P >::type > operator*(const Vector< S, PV, A > &lhs, const SE2< P > &rhs)
Definition: se2.h:239
Everything lives inside this namespace.
Definition: allocator.hh:48
void eval(Vector< S0, P0, A0 > &res) const
Definition: se2.h:186
static void test(int s1, int s2)
Matrix< 3, Cols, typename Internal::MultiplyType< P, PM >::type > operator*(const SE2< P > &lhs, const Matrix< R, Cols, PM, A > &rhs)
Definition: se2.h:273
Definition: se2.h:52
SO2< Precision > & get_rotation()
Returns the rotation part of the transformation as a SO2.
Definition: se2.h:60
std::istream & operator>>(std::istream &is, SE2< Precision > &rhs)
Definition: se2.h:160
SE2< typename Internal::MultiplyType< Precision, P >::type > operator*(const SE2< P > &rhs) const
Definition: se2.h:89
SE2()
Default constructor. Initialises the the rotation to zero (the identity) and the translation to zero...
Definition: se2.h:55
SE2 & operator*=(const SE2 &rhs)
Definition: se2.h:95
SE2< Precision > operator*(const SO2< Precision > &lhs, const SE2< Precision > &rhs)
Definition: se2.h:366
void eval(Vector< S0, P0, A0 > &res) const
Definition: se2.h:227
static SE2 exp(const Vector< S, P, A > &vect)
Vector< 2, Precision > & get_translation()
Returns the translation part of the transformation as a Vector.
Definition: se2.h:64
SE2(const SO2< Precision > &R, const Vector< 2, Precision, A > &T)
Definition: se2.h:56
Vector< 1 > makeVector(double x1)
Definition: make_vector.hh:4
SE2(const Vector< S, P, A > &v)
Definition: se2.h:57
Matrix< 3, 3, Precision > adjoint(const Matrix< 3, 3, Precision, Accessor > &M) const
Definition: se2.h:129
void eval(Matrix< R0, C0, P0, A0 > &res) const
Definition: se2.h:295
Vector< 3, Precision > ln() const
Definition: se2.h:78
static Matrix< 3, 3, Precision > generator(int i)
Definition: se2.h:105
const Matrix< R, Cols, PM, A > & rhs
Definition: se2.h:256
SO2< Precision > my_rotation
Definition: se2.h:139
const Vector< 2, Precision > & get_translation() const
Definition: se2.h:66
Operator(const Matrix< Rows, C, PM, A > &l, const SE2< P > &r)
Definition: se2.h:292
Definition: so2.h:39
Vector< 3, typename Internal::MultiplyType< P, PV >::type > operator*(const SE2< P > &lhs, const Vector< S, PV, A > &rhs)
Definition: se2.h:198
Vector< 2, typename Internal::MultiplyType< P, PV >::type > operator*(const SE2< P > &lhs, const Vector< 2, PV, A > &rhs)
Definition: se2.h:205
Vector< 2, Precision > my_translation
Definition: se2.h:140
Matrix< Rows, 3, typename Internal::MultiplyType< PM, P >::type > operator*(const Matrix< Rows, C, PM, A > &lhs, const SE2< P > &rhs)
Definition: se2.h:307
static SO2 exp(const Precision &d)
Exponentiate an angle in the Lie algebra to generate a new SO2.
Definition: so2.h:84
Vector< 3, Precision > adjoint(const Vector< 3, Precision, Accessor > &vect) const
Definition: se2.h:119
Vector< Internal::Sizer< S1, S2 >::size, typename Internal::MultiplyType< P1, P2 >::type > operator*(const DiagonalMatrix< S1, P1, B1 > &d, const Vector< S2, P2, B2 > &v)
Definition: diagmatrix.h:111
Operator(const SE2< P > &l, const Matrix< R, Cols, PM, A > &r)
Definition: se2.h:258
Operator(const SE2< P > &l, const Vector< S, PV, A > &r)
Definition: se2.h:183
static Operator< Internal::Zero > Zeros
Definition: objects.h:727