TooN
se2.h
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 //All rights reserved.
7 //
8 //Redistribution and use in source and binary forms, with or without
9 //modification, are permitted provided that the following conditions
10 //are met:
11 //1. Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //2. Redistributions in binary form must reproduce the above copyright
14 // notice, this list of conditions and the following disclaimer in the
15 // documentation and/or other materials provided with the distribution.
16 //
17 //THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
18 //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 //IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 //ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
21 //LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 //CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 //SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 //INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 //CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 //POSSIBILITY OF SUCH DAMAGE.
28 
29 /* This code mostly made by copying from se3.h !! */
30 
31 #ifndef TOON_INCLUDE_SE2_H
32 #define TOON_INCLUDE_SE2_H
33 
34 #include <TooN/so2.h>
35 
36 
37 namespace TooN {
38 
49 template <typename Precision = DefaultPrecision>
50 class SE2 {
51 public:
53  SE2() : my_translation(Zeros) {}
54  template <class A> SE2(const SO2<Precision>& R, const Vector<2,Precision,A>& T) : my_rotation(R), my_translation(T) {}
55  template <int S, class P, class A> SE2(const Vector<S, P, A> & v) { *this = exp(v); }
56 
58  SO2<Precision> & get_rotation(){return my_rotation;}
60  const SO2<Precision> & get_rotation() const {return my_rotation;}
62  Vector<2, Precision> & get_translation() {return my_translation;}
64  const Vector<2, Precision> & get_translation() const {return my_translation;}
65 
69  template <int S, typename P, typename A>
70  static inline SE2 exp(const Vector<S,P, A>& vect);
71 
74  static inline Vector<3, Precision> ln(const SE2& se2);
76  Vector<3, Precision> ln() const { return SE2::ln(*this); }
77 
79  SE2 inverse() const {
80  const SO2<Precision> & rinv = my_rotation.inverse();
81  return SE2(rinv, -(rinv*my_translation));
82  };
83 
86  template <typename P>
88  return SE2<typename Internal::MultiplyType<Precision,P>::type>(my_rotation*rhs.get_rotation(), my_translation + my_rotation*rhs.get_translation());
89  }
90 
93  template <typename P>
94  inline SE2& operator *=(const SE2<P>& rhs) {
95  *this = *this * rhs;
96  return *this;
97  }
98 
104  static inline Matrix<3,3, Precision> generator(int i) {
105  Matrix<3,3,Precision> result(Zeros);
106  if(i < 2){
107  result[i][2] = 1;
108  return result;
109  }
110  result[0][1] = -1;
111  result[1][0] = 1;
112  return result;
113  }
114 
117  template<typename Accessor>
119  Vector<3, Precision> result;
120  result[2] = vect[2];
121  result.template slice<0,2>() = my_rotation * vect.template slice<0,2>();
122  result[0] += vect[2] * my_translation[1];
123  result[1] -= vect[2] * my_translation[0];
124  return result;
125  }
126 
127  template <typename Accessor>
129  Matrix<3,3,Precision> result;
130  for(int i=0; i<3; ++i)
131  result.T()[i] = adjoint(M.T()[i]);
132  for(int i=0; i<3; ++i)
133  result[i] = adjoint(result[i]);
134  return result;
135  }
136 
137 private:
138  SO2<Precision> my_rotation;
139  Vector<2, Precision> my_translation;
140 };
141 
144 template <class Precision>
145 inline std::ostream& operator<<(std::ostream& os, const SE2<Precision> & rhs){
146  std::streamsize fw = os.width();
147  for(int i=0; i<2; i++){
148  os.width(fw);
149  os << rhs.get_rotation().get_matrix()[i];
150  os.width(fw);
151  os << rhs.get_translation()[i] << '\n';
152  }
153  return os;
154 }
155 
158 template <class Precision>
159 inline std::istream& operator>>(std::istream& is, SE2<Precision>& rhs){
160  for(int i=0; i<2; i++)
161  is >> rhs.get_rotation().my_matrix[i].ref() >> rhs.get_translation()[i];
162  rhs.get_rotation().coerce();
163  return is;
164 }
165 
166 
168 // operator * //
169 // SE2 * Vector //
171 
172 namespace Internal {
173 template<int S, typename P, typename PV, typename A>
174 struct SE2VMult;
175 }
176 
177 template<int S, typename P, typename PV, typename A>
178 struct Operator<Internal::SE2VMult<S,P,PV,A> > {
179  const SE2<P> & lhs;
180  const Vector<S,PV,A> & rhs;
181 
182  Operator(const SE2<P> & l, const Vector<S,PV,A> & r ) : lhs(l), rhs(r) {}
183 
184  template <int S0, typename P0, typename A0>
185  void eval(Vector<S0, P0, A0> & res ) const {
186  SizeMismatch<3,S>::test(3, rhs.size());
187  res.template slice<0,2>()=lhs.get_rotation()*rhs.template slice<0,2>();
188  res.template slice<0,2>()+=lhs.get_translation() * rhs[2];
189  res[2] = rhs[2];
190  }
191  int size() const { return 3; }
192 };
193 
196 template<int S, typename P, typename PV, typename A>
199 }
200 
203 template <typename P, typename PV, typename A>
205  return lhs.get_translation() + lhs.get_rotation() * rhs;
206 }
207 
209 // operator * //
210 // Vector * SE2 //
212 
213 namespace Internal {
214 template<int S, typename P, typename PV, typename A>
215 struct VSE2Mult;
216 }
217 
218 template<int S, typename P, typename PV, typename A>
219 struct Operator<Internal::VSE2Mult<S,P,PV,A> > {
220  const Vector<S,PV,A> & lhs;
221  const SE2<P> & rhs;
222 
223  Operator(const Vector<S,PV,A> & l, const SE2<P> & r ) : lhs(l), rhs(r) {}
224 
225  template <int S0, typename P0, typename A0>
226  void eval(Vector<S0, P0, A0> & res ) const {
227  SizeMismatch<3,S>::test(3, lhs.size());
228  res.template slice<0,2>() = lhs.template slice<0,2>()*rhs.get_rotation();
229  res[2] = lhs[2];
230  res[2] += lhs.template slice<0,2>() * rhs.get_translation();
231  }
232  int size() const { return 3; }
233 };
234 
237 template<int S, typename P, typename PV, typename A>
240 }
241 
243 // operator * //
244 // SE2 * Matrix //
246 
247 namespace Internal {
248 template <int R, int C, typename PM, typename A, typename P>
249 struct SE2MMult;
250 }
251 
252 template<int R, int Cols, typename PM, typename A, typename P>
253 struct Operator<Internal::SE2MMult<R, Cols, PM, A, P> > {
254  const SE2<P> & lhs;
255  const Matrix<R,Cols,PM,A> & rhs;
256 
257  Operator(const SE2<P> & l, const Matrix<R,Cols,PM,A> & r ) : lhs(l), rhs(r) {}
258 
259  template <int R0, int C0, typename P0, typename A0>
260  void eval(Matrix<R0, C0, P0, A0> & res ) const {
261  SizeMismatch<3,R>::test(3, rhs.num_rows());
262  for(int i=0; i<rhs.num_cols(); ++i)
263  res.T()[i] = lhs * rhs.T()[i];
264  }
265  int num_cols() const { return rhs.num_cols(); }
266  int num_rows() const { return 3; }
267 };
268 
271 template <int R, int Cols, typename PM, typename A, typename P>
274 }
275 
277 // operator * //
278 // Matrix * SE2 //
280 
281 namespace Internal {
282 template <int Rows, int C, typename PM, typename A, typename P>
283 struct MSE2Mult;
284 }
285 
286 template<int Rows, int C, typename PM, typename A, typename P>
287 struct Operator<Internal::MSE2Mult<Rows, C, PM, A, P> > {
288  const Matrix<Rows,C,PM,A> & lhs;
289  const SE2<P> & rhs;
290 
291  Operator( const Matrix<Rows,C,PM,A> & l, const SE2<P> & r ) : lhs(l), rhs(r) {}
292 
293  template <int R0, int C0, typename P0, typename A0>
294  void eval(Matrix<R0, C0, P0, A0> & res ) const {
295  SizeMismatch<3, C>::test(3, lhs.num_cols());
296  for(int i=0; i<lhs.num_rows(); ++i)
297  res[i] = lhs[i] * rhs;
298  }
299  int num_cols() const { return 3; }
300  int num_rows() const { return lhs.num_rows(); }
301 };
302 
305 template <int Rows, int C, typename PM, typename A, typename P>
308 }
309 
310 template <typename Precision>
311 template <int S, typename PV, typename Accessor>
313 {
314  SizeMismatch<3,S>::test(3, mu.size());
315 
316  static const Precision one_6th = 1.0/6.0;
317  static const Precision one_20th = 1.0/20.0;
318 
319  SE2<Precision> result;
320 
321  const Precision theta = mu[2];
322  const Precision theta_sq = theta * theta;
323 
324  const Vector<2, Precision> cross = makeVector( -theta * mu[1], theta * mu[0]);
325  result.get_rotation() = SO2<Precision>::exp(theta);
326 
327  if (theta_sq < 1e-8){
328  result.get_translation() = mu.template slice<0,2>() + 0.5 * cross;
329  } else {
330  Precision A, B;
331  if (theta_sq < 1e-6) {
332  A = 1.0 - theta_sq * one_6th*(1.0 - one_20th * theta_sq);
333  B = 0.5 - 0.25 * one_6th * theta_sq;
334  } else {
335  const Precision inv_theta = (1.0/theta);
336  const Precision sine = result.my_rotation.get_matrix()[1][0];
337  const Precision cosine = result.my_rotation.get_matrix()[0][0];
338  A = sine * inv_theta;
339  B = (1 - cosine) * (inv_theta * inv_theta);
340  }
341  result.get_translation() = TooN::operator*(A,mu.template slice<0,2>()) + TooN::operator*(B,cross);
342  }
343  return result;
344 }
345 
346 template <typename Precision>
348  const Precision theta = se2.get_rotation().ln();
349 
350  Precision shtot = 0.5;
351  if(fabs(theta) > 0.00001)
352  shtot = sin(theta/2)/theta;
353 
354  const SO2<Precision> halfrotator(theta * -0.5);
355  Vector<3, Precision> result;
356  result.template slice<0,2>() = (halfrotator * se2.get_translation())/(2 * shtot);
357  result[2] = theta;
358  return result;
359 }
360 
364 template <typename Precision>
365 inline SE2<Precision> operator*(const SO2<Precision> & lhs, const SE2<Precision>& rhs){
366  return SE2<Precision>( lhs*rhs.get_rotation(), lhs*rhs.get_translation());
367 }
368 
369 }
370 #endif
SE2< Precision > operator*(const SO2< Precision > &lhs, const SE2< Precision > &rhs)
Multiply a SO2 with and SE2.
Definition: se2.h:365
SE2< typename Internal::MultiplyType< Precision, P >::type > operator*(const SE2< P > &rhs) const
Right-multiply by another SE2 (concatenate the two transformations)
Definition: se2.h:87
Vector< 3, Precision > ln() const
Definition: se2.h:76
std::istream & operator>>(std::istream &is, SE2< Precision > &rhs)
Read an SE2 from a stream.
Definition: se2.h:159
Pretty generic SFINAE introspection generator.
Definition: vec_test.cc:21
A vector.
Definition: vector.hh:126
Definition: se2.h:249
Vector< 3, typename Internal::MultiplyType< PV, P >::type > operator*(const Vector< S, PV, A > &lhs, const SE2< P > &rhs)
Left-multiply with a Vector<3>
Definition: se2.h:238
Class to represent a two-dimensional rotation matrix.
Definition: so2.h:37
static SO2 exp(const Precision &d)
Exponentiate an angle in the Lie algebra to generate a new SO2.
Definition: so2.h:89
Matrix< Rows, 3, typename Internal::MultiplyType< PM, P >::type > operator*(const Matrix< Rows, C, PM, A > &lhs, const SE2< P > &rhs)
Left-multiply with a Matrix<3>
Definition: se2.h:306
Vector< 3, Precision > adjoint(const Vector< 3, Precision, Accessor > &vect) const
transfers a vector in the Lie algebra, from one coord frame to another so that exp(adjoint(vect)) = (...
Definition: se2.h:118
Definition: operators.hh:119
Vector< 2, typename Internal::MultiplyType< P, PV >::type > operator*(const SE2< P > &lhs, const Vector< 2, PV, A > &rhs)
Right-multiply with a Vector<2> (special case, extended to be a homogeneous vector) ...
Definition: se2.h:204
const SO2< Precision > & get_rotation() const
Definition: se2.h:60
Definition: se2.h:174
SE2 inverse() const
compute the inverse of the transformation
Definition: se2.h:79
Vector< 3, typename Internal::MultiplyType< P, PV >::type > operator*(const SE2< P > &lhs, const Vector< S, PV, A > &rhs)
Right-multiply with a Vector<3>
Definition: se2.h:197
Matrix< 3, Cols, typename Internal::MultiplyType< P, PM >::type > operator*(const SE2< P > &lhs, const Matrix< R, Cols, PM, A > &rhs)
Right-multiply with a Matrix<3>
Definition: se2.h:272
const Vector< 2, Precision > & get_translation() const
Definition: se2.h:64
static Matrix< 3, 3, Precision > generator(int i)
returns the generators for the Lie group.
Definition: se2.h:104
static SE2 exp(const Vector< S, P, A > &vect)
Exponentiate a Vector in the Lie Algebra to generate a new SE2.
Definition: size_mismatch.hh:103
Vector< 2, Precision > & get_translation()
Returns the translation part of the transformation as a Vector.
Definition: se2.h:62
Represent a two-dimensional Euclidean transformation (a rotation and a translation).
Definition: se2.h:50
SE2()
Default constructor. Initialises the the rotation to zero (the identity) and the translation to zero...
Definition: se2.h:53
SO2< Precision > & get_rotation()
Returns the rotation part of the transformation as a SO2.
Definition: se2.h:58
Definition: se2.h:215
Definition: se2.h:283
SE2 & operator*=(const SE2< P > &rhs)
Self right-multiply by another SE2 (concatenate the two transformations)
Definition: se2.h:94