PTransform.h
Go to the documentation of this file.
1 /*
2  * Copyright 2012-2020 CNRS-UM LIRMM, CNRS-AIST JRL
3  */
4 
5 #pragma once
6 
7 #include "EigenTypedef.h"
8 #include "fwd.h"
9 
10 namespace sva
11 {
12 
18 template<typename T>
19 Eigen::Matrix3<T> RotX(T theta);
20 
26 template<typename T>
27 Eigen::Matrix3<T> RotY(T theta);
28 
34 template<typename T>
35 Eigen::Matrix3<T> RotZ(T theta);
36 
44 template<typename T>
46 
53 template<typename T>
55 
63 template<typename T>
64 MotionVec<T> transformError(const PTransform<T> & X_a_b, const PTransform<T> & X_a_c);
65 
74 template<typename T>
75 MotionVec<T> transformVelocity(const PTransform<T> & X_a_b);
76 
83 template<typename T>
84 class PTransform
85 {
86  typedef Eigen::Vector3<T> vector3_t;
87  typedef Eigen::Matrix3<T> matrix3_t;
88  typedef Eigen::Matrix6<T> matrix6_t;
89  typedef Eigen::Quaternion<T> quaternion_t;
90 
91 public:
94  {
95  return PTransform<T>(matrix3_t::Identity(), vector3_t::Zero());
96  }
97 
98 public:
99  // Constructors
101  PTransform() : E_(), r_() {}
102 
104  template<typename T2>
105  PTransform(const PTransform<T2> & pt) : E_(pt.rotation().template cast<T>()), r_(pt.translation().template cast<T>())
106  {
107  }
108 
113  PTransform(const matrix3_t & rot, const vector3_t & trans) : E_(rot), r_(trans) {}
114 
119  PTransform(const quaternion_t & rot, const vector3_t & trans) : E_(rot.matrix()), r_(trans) {}
120 
125  PTransform(const quaternion_t & rot) : E_(rot.matrix()), r_(vector3_t::Zero()) {}
126 
131  PTransform(const matrix3_t & rot) : E_(rot), r_(vector3_t::Zero()) {}
132 
137  PTransform(const vector3_t & trans) : E_(matrix3_t::Identity()), r_(trans) {}
138 
139  // Accessor
141  const matrix3_t & rotation() const
142  {
143  return E_;
144  }
145 
147  matrix3_t & rotation()
148  {
149  return E_;
150  }
151 
153  const vector3_t & translation() const
154  {
155  return r_;
156  }
157 
159  vector3_t & translation()
160  {
161  return r_;
162  }
163 
165  matrix6_t matrix() const
166  {
167  matrix6_t m;
168  m << E_, matrix3_t::Zero(), -E_ * vector3ToCrossMatrix(r_), E_;
169  return m;
170  }
171 
173  matrix6_t dualMatrix() const
174  {
175  matrix6_t m;
176  m << E_, -E_ * vector3ToCrossMatrix(r_), matrix3_t::Zero(), E_;
177  return m;
178  }
179 
180  template<typename T2>
182  {
183  return PTransform<T2>(E_.template cast<T2>(), r_.template cast<T2>());
184  }
185 
186  // Operators
189  {
190  return PTransform<T>(E_ * pt.E_, pt.r_ + pt.E_.transpose() * r_);
191  }
192 
194  MotionVec<T> operator*(const MotionVec<T> & mv) const;
195 
197  Eigen::Vector3<T> angularMul(const MotionVec<T> & mv) const;
199  Eigen::Vector3<T> linearMul(const MotionVec<T> & mv) const;
201  template<typename Derived>
202  void mul(const Eigen::MatrixBase<Derived> & mv, Eigen::MatrixBase<Derived> & result) const;
203 
205  MotionVec<T> invMul(const MotionVec<T> & mv) const;
207  Eigen::Vector3<T> angularInvMul(const MotionVec<T> & mv) const;
209  Eigen::Vector3<T> linearInvMul(const MotionVec<T> & mv) const;
211  template<typename Derived>
212  void invMul(const Eigen::MatrixBase<Derived> & mv, Eigen::MatrixBase<Derived> & result) const;
213 
215  ForceVec<T> dualMul(const ForceVec<T> & fv) const;
217  Eigen::Vector3<T> coupleDualMul(const ForceVec<T> & fv) const;
219  Eigen::Vector3<T> forceDualMul(const ForceVec<T> & fv) const;
221  template<typename Derived>
222  void dualMul(const Eigen::MatrixBase<Derived> & fv, Eigen::MatrixBase<Derived> & result) const;
223 
225  ForceVec<T> transMul(const ForceVec<T> & fv) const;
227  Eigen::Vector3<T> coupleTransMul(const ForceVec<T> & fv) const;
229  Eigen::Vector3<T> forceTransMul(const ForceVec<T> & fv) const;
231  template<typename Derived>
232  void transMul(const Eigen::MatrixBase<Derived> & fv, Eigen::MatrixBase<Derived> & result) const;
233 
235  RBInertia<T> dualMul(const RBInertia<T> & rbI) const;
237  RBInertia<T> transMul(const RBInertia<T> & rbI) const;
238 
240  ABInertia<T> dualMul(const ABInertia<T> & rbI) const;
242  ABInertia<T> transMul(const ABInertia<T> & rbI) const;
243 
246  {
247  return PTransform<T>(E_.transpose(), -E_ * r_);
248  }
249 
250  bool operator==(const PTransform<T> & pt) const
251  {
252  return E_ == pt.E_ && r_ == pt.r_;
253  }
254 
255  bool operator!=(const PTransform<T> & pt) const
256  {
257  return E_ != pt.E_ || r_ != pt.r_;
258  }
259 
260 private:
261  matrix3_t E_;
262  vector3_t r_;
263 };
264 
265 template<typename T>
266 inline Eigen::Matrix3<T> RotX(T theta)
267 {
268  T s = std::sin(theta), c = std::cos(theta);
269  return (Eigen::Matrix3<T>() << 1., 0., 0., 0., c, s, 0., -s, c).finished();
270 }
271 
272 template<typename T>
273 inline Eigen::Matrix3<T> RotY(T theta)
274 {
275  T s = std::sin(theta), c = std::cos(theta);
276  return (Eigen::Matrix3<T>() << c, 0., -s, 0., 1., 0., s, 0., c).finished();
277 }
278 
279 template<typename T>
280 inline Eigen::Matrix3<T> RotZ(T theta)
281 {
282  T s = std::sin(theta), c = std::cos(theta);
283  return (Eigen::Matrix3<T>() << c, s, 0., -s, c, 0., 0., 0., 1.).finished();
284 }
285 
286 template<typename T>
288 {
289  Eigen::Matrix3<T> E_b_c = E_a_c * E_a_b.transpose();
290  return Eigen::Vector3<T>(E_a_b.transpose() * rotationVelocity(E_b_c));
291 }
292 
293 template<typename T>
295 {
296  constexpr T eps = std::numeric_limits<T>::epsilon();
297  constexpr T sqeps = details::sqrt(eps);
298  constexpr T sqsqeps = details::sqrt(sqeps);
299  constexpr T pi = 3.1415926535897932;
300 
301  T trace = E_a_b(0, 0) + E_a_b(1, 1) + E_a_b(2, 2);
302  T acosV = (trace - 1.) * 0.5;
303  T theta = std::acos(std::min(std::max(acosV, -1.), 1.));
304 
305  Eigen::Vector3<T> w(-E_a_b(2, 1) + E_a_b(1, 2), -E_a_b(0, 2) + E_a_b(2, 0), -E_a_b(1, 0) + E_a_b(0, 1));
306 
307  if(1 + trace < sqsqeps) // in case of angle close to pi
308  {
309  // adapted from https://vision.in.tum.de/_media/members/demmeln/nurlanov2021so3log.pdf, sec2.2
310  Eigen::Vector3<T> s = (2 * E_a_b.diagonal() + Eigen::Vector3<T>::Constant(1 - trace)) / (3 - trace);
311  Eigen::Vector3<T> tn2 = theta * s.cwiseSqrt();
312  // If theta is really close to pi the sign of n is derived from (13)
313  // We choose the first non-zero coefficient to be positive arbitrarly
314  if(theta > pi - 1e-7)
315  {
316  if(tn2(0) > 0)
317  {
318  if(E_a_b(0, 1) + E_a_b(1, 0) < 0)
319  {
320  tn2(1) = -tn2(1);
321  }
322  if(E_a_b(0, 2) + E_a_b(2, 0) < 0)
323  {
324  tn2(2) = -tn2(2);
325  }
326  }
327  else if(tn2(1) > 0) // only if tn2(0) == 0
328  {
329  if(E_a_b(1, 2) + E_a_b(2, 1) < 0)
330  {
331  tn2(2) = -tn2(2);
332  }
333  }
334  return tn2;
335  }
336  // The sign is derived from (9)
337  return (w.array() >= 0).select(tn2, -tn2);
338  }
339  else
340  {
341  w *= sinc_inv(theta) * 0.5;
342  }
343 
344  return w;
345 }
346 
347 template<typename T>
348 inline MotionVec<T> transformError(const PTransform<T> & X_a_b, const PTransform<T> & X_a_c)
349 {
350  PTransform<T> X_b_c = X_a_c * X_a_b.inv();
351  return PTransform<T>(Eigen::Matrix3<T>(X_a_b.rotation().transpose())) * transformVelocity(X_b_c);
352 }
353 
354 template<typename T>
356 {
357  return MotionVec<T>(rotationVelocity(X_a_b.rotation()), X_a_b.translation());
358 }
359 
360 // interpolate between transformations, t must be between 0 and 1
361 template<typename T>
362 PTransform<T> interpolate(const PTransform<T> & from, const PTransform<T> & to, double t)
363 {
364  Eigen::Quaternion<T> qfrom(from.rotation());
365  Eigen::Quaternion<T> qto(to.rotation());
366  PTransform<T> result(qfrom.slerp(t, qto), (from.translation() * (1. - t) + to.translation() * t));
367  return result;
368 }
369 
370 template<typename T>
371 inline std::ostream & operator<<(std::ostream & out, const PTransform<T> & pt)
372 {
373  out << pt.matrix();
374  return out;
375 }
376 
377 } // namespace sva
sva::interpolate
PTransform< T > interpolate(const PTransform< T > &from, const PTransform< T > &to, double t)
Definition: PTransform.h:362
sva::MotionVec
Definition: fwd.h:11
sva::PTransform::invMul
MotionVec< T > invMul(const MotionVec< T > &mv) const
Definition: Operators.h:246
sva::operator<<
std::ostream & operator<<(std::ostream &out, const ABInertia< T > &abI)
Definition: ABInertia.h:183
sva::PTransform::operator!=
bool operator!=(const PTransform< T > &pt) const
Definition: PTransform.h:255
sva::PTransform::cast
PTransform< T2 > cast() const
Definition: PTransform.h:181
Eigen::Matrix3
Matrix< T, 3, 3 > Matrix3
Definition: EigenTypedef.h:20
sva::sinc_inv
T sinc_inv(const T x)
Definition: MathFunc.h:225
sva::PTransform::PTransform
PTransform(const quaternion_t &rot, const vector3_t &trans)
Definition: PTransform.h:119
sva::ForceVec
Definition: ForceVec.h:19
sva::PTransform::coupleTransMul
Eigen::Vector3< T > coupleTransMul(const ForceVec< T > &fv) const
Definition: Operators.h:339
sva::PTransform::forceTransMul
Eigen::Vector3< T > forceTransMul(const ForceVec< T > &fv) const
Definition: Operators.h:348
sva
Definition: ABInertia.h:10
fwd.h
sva::PTransform::mul
void mul(const Eigen::MatrixBase< Derived > &mv, Eigen::MatrixBase< Derived > &result) const
Definition: Operators.h:230
sva::PTransform::dualMul
ForceVec< T > dualMul(const ForceVec< T > &fv) const
Definition: Operators.h:289
Eigen::vector3ToCrossMatrix
Matrix3< T > vector3ToCrossMatrix(const Vector3< T > &vec)
Definition: EigenUtility.h:16
sva::PTransform::linearInvMul
Eigen::Vector3< T > linearInvMul(const MotionVec< T > &mv) const
Definition: Operators.h:265
Eigen::Vector3
Matrix< T, 3, 1 > Vector3
Definition: EigenTypedef.h:18
sva::PTransform::PTransform
PTransform(const matrix3_t &rot, const vector3_t &trans)
Definition: PTransform.h:113
sva::PTransform::inv
PTransform< T > inv() const
Definition: PTransform.h:245
sva::rotationVelocity
Eigen::Vector3< T > rotationVelocity(const Eigen::Matrix3< T > &E_a_b)
Definition: PTransform.h:294
sva::PTransform::angularMul
Eigen::Vector3< T > angularMul(const MotionVec< T > &mv) const
Definition: Operators.h:214
sva::PTransform::linearMul
Eigen::Vector3< T > linearMul(const MotionVec< T > &mv) const
Definition: Operators.h:221
sva::PTransform::translation
const vector3_t & translation() const
Definition: PTransform.h:153
sva::PTransform::rotation
const matrix3_t & rotation() const
Definition: PTransform.h:141
sva::rotationError
Eigen::Vector3< T > rotationError(const Eigen::Matrix3< T > &E_a_b, const Eigen::Matrix3< T > &E_a_c)
Definition: PTransform.h:287
sva::PTransform::rotation
matrix3_t & rotation()
Definition: PTransform.h:147
sva::PTransform::operator*
PTransform< T > operator*(const PTransform< T > &pt) const
Definition: PTransform.h:188
sva::PTransform::operator==
bool operator==(const PTransform< T > &pt) const
Definition: PTransform.h:250
sva::RBInertia
Definition: fwd.h:17
sva::PTransform::matrix
matrix6_t matrix() const
Definition: PTransform.h:165
sva::RotY
Eigen::Matrix3< T > RotY(T theta)
Definition: PTransform.h:273
sva::PTransform::translation
vector3_t & translation()
Definition: PTransform.h:159
sva::details::sqrt
constexpr T sqrt(T x)
Definition: MathFunc.h:33
sva::ABInertia
Definition: ABInertia.h:18
sva::PTransform::Identity
static PTransform< T > Identity()
Identity transformation.
Definition: PTransform.h:93
sva::transformVelocity
MotionVec< T > transformVelocity(const PTransform< T > &X_a_b)
Definition: PTransform.h:355
sva::PTransform::PTransform
PTransform(const PTransform< T2 > &pt)
Copy constructor.
Definition: PTransform.h:105
sva::RotX
Eigen::Matrix3< T > RotX(T theta)
Definition: PTransform.h:266
sva::PTransform::PTransform
PTransform()
Default constructor. Rotation and translation are uninitialized.
Definition: PTransform.h:101
sva::PTransform::dualMatrix
matrix6_t dualMatrix() const
Definition: PTransform.h:173
EigenTypedef.h
sva::PTransform
Definition: fwd.h:23
sva::PTransform::coupleDualMul
Eigen::Vector3< T > coupleDualMul(const ForceVec< T > &fv) const
Definition: Operators.h:295
Eigen::Matrix6
Matrix< T, 6, 6 > Matrix6
Definition: EigenTypedef.h:15
sva::PTransform::PTransform
PTransform(const vector3_t &trans)
Definition: PTransform.h:137
sva::PTransform::angularInvMul
Eigen::Vector3< T > angularInvMul(const MotionVec< T > &mv) const
Definition: Operators.h:258
sva::RotZ
Eigen::Matrix3< T > RotZ(T theta)
Definition: PTransform.h:280
sva::PTransform::transMul
ForceVec< T > transMul(const ForceVec< T > &fv) const
Definition: Operators.h:327
sva::PTransform::PTransform
PTransform(const matrix3_t &rot)
Definition: PTransform.h:131
sva::transformError
MotionVec< T > transformError(const PTransform< T > &X_a_b, const PTransform< T > &X_a_c)
Definition: PTransform.h:348
sva::PTransform::forceDualMul
Eigen::Vector3< T > forceDualMul(const ForceVec< T > &fv) const
Definition: Operators.h:303
sva::PTransform::PTransform
PTransform(const quaternion_t &rot)
Definition: PTransform.h:125