pinocchio  3.7.0
A fast and flexible implementation of Rigid Body Dynamics algorithms and their analytical derivatives
 
Loading...
Searching...
No Matches
se3-tpl.hpp
1//
2// Copyright (c) 2015-2021 CNRS INRIA
3// Copyright (c) 2016 Wandercraft, 86 rue de Paris 91400 Orsay, France.
4//
5
6#ifndef __pinocchio_spatial_se3_tpl_hpp__
7#define __pinocchio_spatial_se3_tpl_hpp__
8
9#include "pinocchio/spatial/fwd.hpp"
10#include "pinocchio/spatial/se3-base.hpp"
11
12#include "pinocchio/math/quaternion.hpp"
13#include "pinocchio/math/rotation.hpp"
14#include "pinocchio/spatial/cartesian-axis.hpp"
15
16#include <Eigen/Geometry>
17
18namespace pinocchio
19{
20 template<typename _Scalar, int _Options>
22 {
23 enum
24 {
25 Options = _Options,
26 LINEAR = 0,
27 ANGULAR = 3
28 };
29 typedef _Scalar Scalar;
30 typedef Eigen::Matrix<Scalar, 3, 1, Options> Vector3;
31 typedef Eigen::Matrix<Scalar, 4, 1, Options> Vector4;
32 typedef Eigen::Matrix<Scalar, 6, 1, Options> Vector6;
33 typedef Eigen::Matrix<Scalar, 3, 3, Options> Matrix3;
34 typedef Eigen::Matrix<Scalar, 4, 4, Options> Matrix4;
35 typedef Eigen::Matrix<Scalar, 6, 6, Options> Matrix6;
36 typedef Matrix3 AngularType;
37 typedef typename PINOCCHIO_EIGEN_REF_TYPE(Matrix3) AngularRef;
38 typedef typename PINOCCHIO_EIGEN_REF_CONST_TYPE(Matrix3) ConstAngularRef;
39 typedef Vector3 LinearType;
40 typedef typename PINOCCHIO_EIGEN_REF_TYPE(Vector3) LinearRef;
41 typedef typename PINOCCHIO_EIGEN_REF_CONST_TYPE(Vector3) ConstLinearRef;
42 typedef Matrix6 ActionMatrixType;
43 typedef Matrix4 HomogeneousMatrixType;
45 }; // traits SE3Tpl
46
47 template<typename _Scalar, int _Options>
48 struct SE3Tpl : public SE3Base<SE3Tpl<_Scalar, _Options>>
49 {
51
52 PINOCCHIO_SE3_TYPEDEF_TPL(SE3Tpl);
54 typedef Eigen::Quaternion<Scalar, Options> Quaternion;
55 typedef typename traits<SE3Tpl>::Vector3 Vector3;
56 typedef typename traits<SE3Tpl>::Matrix3 Matrix3;
57 typedef typename traits<SE3Tpl>::Matrix4 Matrix4;
58 typedef typename traits<SE3Tpl>::Vector4 Vector4;
59 typedef typename traits<SE3Tpl>::Matrix6 Matrix6;
60
61 using Base::rotation;
62 using Base::translation;
63
64 SE3Tpl()
65 : rot()
66 , trans() {};
67
68 template<typename QuaternionLike, typename Vector3Like>
69 SE3Tpl(
70 const Eigen::QuaternionBase<QuaternionLike> & quat,
71 const Eigen::MatrixBase<Vector3Like> & trans)
72 : rot(quat.matrix())
73 , trans(trans)
74 {
76 }
77
78 template<typename Matrix3Like, typename Vector3Like>
79 SE3Tpl(const Eigen::MatrixBase<Matrix3Like> & R, const Eigen::MatrixBase<Vector3Like> & trans)
80 : rot(R)
81 , trans(trans){EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Vector3Like, 3)
83
84 SE3Tpl(const SE3Tpl & other)
85 {
86 *this = other;
87 }
88
89 template<typename S2, int O2>
90 explicit SE3Tpl(const SE3Tpl<S2, O2> & other)
91 {
92 *this = other.template cast<Scalar>();
93 }
94
95 template<typename Matrix4Like>
96 explicit SE3Tpl(const Eigen::MatrixBase<Matrix4Like> & m)
97 : rot(m.template block<3, 3>(LINEAR, LINEAR))
98 , trans(m.template block<3, 1>(LINEAR, ANGULAR))
99 {
101 }
102
103 explicit SE3Tpl(int)
104 : rot(AngularType::Identity())
105 , trans(LinearType::Zero())
106 {
107 }
108
109 template<int O2>
110 SE3Tpl(const SE3Tpl<Scalar, O2> & clone)
111 : rot(clone.rotation())
112 , trans(clone.translation())
113 {
114 }
115
116 template<int O2>
117 SE3Tpl & operator=(const SE3Tpl<Scalar, O2> & other)
118 {
119 rot = other.rotation();
120 trans = other.translation();
121 return *this;
122 }
123
130 {
131 rot = other.rotation();
132 trans = other.translation();
133 return *this;
134 }
135
136 static SE3Tpl Identity()
137 {
138 return SE3Tpl(1);
139 }
140
141 SE3Tpl & setIdentity()
142 {
143 rot.setIdentity();
144 trans.setZero();
145 return *this;
146 }
147
150 {
151 return SE3Tpl(rot.transpose(), -rot.transpose() * trans);
152 }
153
154 static SE3Tpl Random()
155 {
156 return SE3Tpl().setRandom();
157 }
158
159 SE3Tpl & setRandom()
160 {
161 Quaternion q;
163 rot = q.matrix();
164 trans.setRandom();
165
166 return *this;
167 }
168
169 HomogeneousMatrixType toHomogeneousMatrix_impl() const
170 {
171 HomogeneousMatrixType M;
172 M.template block<3, 3>(LINEAR, LINEAR) = rot;
173 M.template block<3, 1>(LINEAR, ANGULAR) = trans;
174 M.template block<1, 3>(ANGULAR, LINEAR).setZero();
175 M(3, 3) = 1;
176 return M;
177 }
178
180 template<typename Matrix6Like>
181 void toActionMatrix_impl(const Eigen::MatrixBase<Matrix6Like> & action_matrix) const
182 {
183 typedef Eigen::Block<Matrix6Like, 3, 3> Block3;
184
185 Matrix6Like & M = action_matrix.const_cast_derived();
186 M.template block<3, 3>(ANGULAR, ANGULAR) = M.template block<3, 3>(LINEAR, LINEAR) = rot;
187 M.template block<3, 3>(ANGULAR, LINEAR).setZero();
188 Block3 B = M.template block<3, 3>(LINEAR, ANGULAR);
189
190 B.col(0) = trans.cross(rot.col(0));
191 B.col(1) = trans.cross(rot.col(1));
192 B.col(2) = trans.cross(rot.col(2));
193 }
194
195 ActionMatrixType toActionMatrix_impl() const
196 {
197 ActionMatrixType res;
198 toActionMatrix_impl(res);
199 return res;
200 }
201
202 template<typename Matrix6Like>
203 void
204 toActionMatrixInverse_impl(const Eigen::MatrixBase<Matrix6Like> & action_matrix_inverse) const
205 {
206 typedef Eigen::Block<Matrix6Like, 3, 3> Block3;
207
208 Matrix6Like & M = action_matrix_inverse.const_cast_derived();
209 M.template block<3, 3>(ANGULAR, ANGULAR) = M.template block<3, 3>(LINEAR, LINEAR) =
210 rot.transpose();
211 Block3 C = M.template block<3, 3>(ANGULAR, LINEAR); // used as temporary
212 Block3 B = M.template block<3, 3>(LINEAR, ANGULAR);
213
214#define PINOCCHIO_INTERNAL_COMPUTATION(axis_id, v3_in, v3_out, R, res) \
215 CartesianAxis<axis_id>::cross(v3_in, v3_out); \
216 res.col(axis_id).noalias() = R.transpose() * v3_out;
217
218 PINOCCHIO_INTERNAL_COMPUTATION(0, trans, C.col(0), rot, B);
219 PINOCCHIO_INTERNAL_COMPUTATION(1, trans, C.col(0), rot, B);
220 PINOCCHIO_INTERNAL_COMPUTATION(2, trans, C.col(0), rot, B);
221
222#undef PINOCCHIO_INTERNAL_COMPUTATION
223
224 C.setZero();
225 }
226
227 ActionMatrixType toActionMatrixInverse_impl() const
228 {
229 ActionMatrixType res;
230 toActionMatrixInverse_impl(res);
231 return res;
232 }
233
234 template<typename Matrix6Like>
235 void toDualActionMatrix_impl(const Eigen::MatrixBase<Matrix6Like> & dual_action_matrix) const
236 {
237 typedef Eigen::Block<Matrix6Like, 3, 3> Block3;
238
239 Matrix6Like & M = dual_action_matrix.const_cast_derived();
240 M.template block<3, 3>(ANGULAR, ANGULAR) = M.template block<3, 3>(LINEAR, LINEAR) = rot;
241 M.template block<3, 3>(LINEAR, ANGULAR).setZero();
242 Block3 B = M.template block<3, 3>(ANGULAR, LINEAR);
243
244 B.col(0) = trans.cross(rot.col(0));
245 B.col(1) = trans.cross(rot.col(1));
246 B.col(2) = trans.cross(rot.col(2));
247 }
248
249 ActionMatrixType toDualActionMatrix_impl() const
250 {
251 ActionMatrixType res;
252 toDualActionMatrix_impl(res);
253 return res;
254 }
255
256 void disp_impl(std::ostream & os) const
257 {
258 os << " R =\n" << rot << std::endl << " p = " << trans.transpose() << std::endl;
259 }
260
262
264 template<typename D>
265 typename SE3GroupAction<D>::ReturnType act_impl(const D & d) const
266 {
267 return d.se3Action(*this);
268 }
269
271 template<typename D>
272 typename SE3GroupAction<D>::ReturnType actInv_impl(const D & d) const
273 {
274 return d.se3ActionInverse(*this);
275 }
276
277 template<typename EigenDerived>
278 typename EigenDerived::PlainObject
279 actOnEigenObject(const Eigen::MatrixBase<EigenDerived> & p) const
280 {
281 return (rotation() * p + translation()).eval();
282 }
283
284 template<typename MapDerived>
285 Vector3 actOnEigenObject(const Eigen::MapBase<MapDerived> & p) const
286 {
287 return Vector3(rotation() * p + translation());
288 }
289
290 template<typename EigenDerived>
291 typename EigenDerived::PlainObject
292 actInvOnEigenObject(const Eigen::MatrixBase<EigenDerived> & p) const
293 {
294 return (rotation().transpose() * (p - translation())).eval();
295 }
296
297 template<typename MapDerived>
298 Vector3 actInvOnEigenObject(const Eigen::MapBase<MapDerived> & p) const
299 {
300 return Vector3(rotation().transpose() * (p - translation()));
301 }
302
303 Vector3 act_impl(const Vector3 & p) const
304 {
305 return Vector3(rotation() * p + translation());
306 }
307
308 Vector3 actInv_impl(const Vector3 & p) const
309 {
310 return Vector3(rotation().transpose() * (p - translation()));
311 }
312
313 template<int O2>
314 SE3Tpl act_impl(const SE3Tpl<Scalar, O2> & m2) const
315 {
316 return SE3Tpl(rot * m2.rotation(), translation() + rotation() * m2.translation());
317 }
318
319 template<int O2>
320 SE3Tpl actInv_impl(const SE3Tpl<Scalar, O2> & m2) const
321 {
322 return SE3Tpl(
323 rot.transpose() * m2.rotation(), rot.transpose() * (m2.translation() - translation()));
324 }
325
326 template<int O2>
327 SE3Tpl __mult__(const SE3Tpl<Scalar, O2> & m2) const
328 {
329 return this->act_impl(m2);
330 }
331
332 template<int O2>
333 bool isEqual(const SE3Tpl<Scalar, O2> & m2) const
334 {
335 return (rotation() == m2.rotation() && translation() == m2.translation());
336 }
337
338 template<int O2>
339 bool isApprox_impl(
340 const SE3Tpl<Scalar, O2> & m2,
341 const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision()) const
342 {
343 return rotation().isApprox(m2.rotation(), prec)
344 && translation().isApprox(m2.translation(), prec);
345 }
346
347 bool isIdentity(const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision()) const
348 {
349 return rotation().isIdentity(prec) && translation().isZero(prec);
350 }
351
352 ConstAngularRef rotation_impl() const
353 {
354 return rot;
355 }
356 AngularRef rotation_impl()
357 {
358 return rot;
359 }
360 void rotation_impl(const AngularType & R)
361 {
362 rot = R;
363 }
364 ConstLinearRef translation_impl() const
365 {
366 return trans;
367 }
368 LinearRef translation_impl()
369 {
370 return trans;
371 }
372 void translation_impl(const LinearType & p)
373 {
374 trans = p;
375 }
376
378 template<typename NewScalar>
380 {
381 typedef SE3Tpl<NewScalar, Options> ReturnType;
382 ReturnType res(rot.template cast<NewScalar>(), trans.template cast<NewScalar>());
383
384 // During the cast, it may appear that the matrix is not normalized correctly.
385 // Force the normalization of the rotation part of the matrix.
386 internal::cast_call_normalize_method<SE3Tpl, NewScalar, Scalar>::run(res);
387 return res;
388 }
389
390 bool isNormalized(const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision()) const
391 {
392 return isUnitary(rot, prec);
393 }
394
395 void normalize()
396 {
397 rot = orthogonalProjection(rot);
398 }
399
400 PlainType normalized() const
401 {
402 PlainType res(*this);
403 res.normalize();
404 return res;
405 }
406
419 template<typename OtherScalar>
420 static SE3Tpl Interpolate(const SE3Tpl & A, const SE3Tpl & B, const OtherScalar & alpha);
421
422 protected:
423 AngularType rot;
424 LinearType trans;
425
426 }; // class SE3Tpl
427
428 namespace internal
429 {
430 template<typename Scalar, int Options>
431 struct cast_call_normalize_method<SE3Tpl<Scalar, Options>, Scalar, Scalar>
432 {
433 template<typename T>
434 static void run(T &)
435 {
436 }
437 };
438
439 template<typename Scalar, int Options, typename NewScalar>
440 struct cast_call_normalize_method<SE3Tpl<Scalar, Options>, NewScalar, Scalar>
441 {
442 template<typename T>
443 static void run(T & self)
444 {
445 if (
446 pinocchio::cast<NewScalar>(Eigen::NumTraits<Scalar>::epsilon())
447 > Eigen::NumTraits<NewScalar>::epsilon())
448 self.normalize();
449 }
450 };
451
452 } // namespace internal
453
454} // namespace pinocchio
455
456#endif // ifndef __pinocchio_spatial_se3_tpl_hpp__
void uniformRandom(Eigen::QuaternionBase< Derived > &q)
Uniformly random quaternion sphere.
Main pinocchio namespace.
Definition treeview.dox:11
Matrix3 orthogonalProjection(const Eigen::MatrixBase< Matrix3 > &mat)
Orthogonal projection of a matrix on the SO(3) manifold.
Definition rotation.hpp:105
bool isUnitary(const Eigen::MatrixBase< MatrixLike > &mat, const typename MatrixLike::RealScalar &prec=Eigen::NumTraits< typename MatrixLike::Scalar >::dummy_precision())
Check whether the input matrix is Unitary within the given precision.
Definition matrix.hpp:155
Base class for rigid transformation.
Definition se3-base.hpp:31
void toActionMatrix_impl(const Eigen::MatrixBase< Matrix6Like > &action_matrix) const
Vb.toVector() = bXa.toMatrix() * Va.toVector()
Definition se3-tpl.hpp:181
SE3GroupAction< D >::ReturnType actInv_impl(const D &d) const
by = aXb.actInv(ay)
Definition se3-tpl.hpp:272
static SE3Tpl Interpolate(const SE3Tpl &A, const SE3Tpl &B, const OtherScalar &alpha)
Linear interpolation on the SE3 manifold.
SE3Tpl inverse() const
aXb = bXa.inverse()
Definition se3-tpl.hpp:149
SE3GroupAction< D >::ReturnType act_impl(const D &d) const
— GROUP ACTIONS ON M6, F6 and I6 —
Definition se3-tpl.hpp:265
SE3Tpl & operator=(const SE3Tpl &other)
Copy assignment operator.
Definition se3-tpl.hpp:129
SE3Tpl< NewScalar, Options > cast() const
Definition se3-tpl.hpp:379
Common traits structure to fully define base classes for CRTP.
Definition fwd.hpp:72