- 3.0.2 rigid body dynamics module.
robcogen_commons.h
Go to the documentation of this file.
1 /* CPYHDR { */
2 /*
3  * This file is part of the 'iit-rbd' library.
4  * Copyright © 2015 2016, Marco Frigerio (marco.frigerio@iit.it)
5  *
6  * See the LICENSE file for more information.
7  */
8 /* } CPYHDR */
9 
10 #ifndef IIT_RBD_ROBCOGEN_COMMON_EXPRESSIONS_
11 #define IIT_RBD_ROBCOGEN_COMMON_EXPRESSIONS_
12 
13 
14 #include "rbd.h"
15 #include "InertiaMatrix.h"
16 #include "TransformsBase.h"
17 #include "types.h"
18 #include "internals.h"
19 
20 
21 namespace iit {
22 namespace rbd {
23 
41 #define DScalar typename Derived::Scalar
42 
43 
57 template <typename Derived>
59 {
60  typedef DScalar Scalar;
61  // This is a "manual" implementation of the matrix product, as the obvious
62  // implementation (plain matrix-matrix-vector multiplication) would not
63  // exploit the (known) sparsity pattern and the fact that the first and last
64  // term ( v cross* and v) have the same coefficients.
65 
66  // Pre-compute some recurring quantities.
67  Scalar wx2 = v(AX)*v(AX);
68  Scalar wy2 = v(AY)*v(AY);
69  Scalar wz2 = v(AZ)*v(AZ);
70 
71  Scalar v_AXAY = v(AX)*v(AY);
72  Scalar v_AXAZ = v(AX)*v(AZ);
73  Scalar v_AXLY = v(AX)*v(LY);
74  Scalar v_AXLZ = v(AX)*v(LZ);
75 
76  Scalar v_AYAZ = v(AY)*v(AZ);
77  Scalar v_AYLX = v(AY)*v(LX);
78  Scalar v_AYLZ = v(AY)*v(LZ);
79 
80  Scalar v_AZLX = v(AZ)*v(LX);
81  Scalar v_AZLY = v(AZ)*v(LY);
82 
83  Scalar m = I(LX,LX); // the mass
84  // Copy some of the coefficients for more efficient access
85  // 'aa' stands for angular-angular, a 3x3 sub-block of the spatial inertia
87  I(AX,AX), I(AX,AY), I(AX,AZ),
88  I(AY,AY), I(AY,AZ),
89  I(AZ,AZ));
90  Scalar cmX = I(AZ, LY);
91  Scalar cmY = I(AX, LZ);
92  Scalar cmZ = I(AY, LX);
93 
94  typename Core<Scalar>::ForceVector ret;
95  ret(AX) = cmZ * (v_AXLZ - v_AZLX)
96  + cmY * (v_AXLY - v_AYLX)
97  + v_AYAZ * (Iaa.ZZ - Iaa.YY)
98  - v_AXAZ*Iaa.XY - (wz2 - wy2)*Iaa.YZ + v_AXAY*Iaa.XZ;
99 
100  ret(AY) = cmZ * (v_AYLZ - v_AZLY)
101  - cmX * (v_AXLY - v_AYLX)
102  - v_AXAZ * (Iaa.ZZ - Iaa.XX)
103  + v_AYAZ*Iaa.XY - v_AXAY*Iaa.YZ + (wz2 - wx2)*Iaa.XZ;
104 
105  ret(AZ) = cmX * (v_AZLX - v_AXLZ)
106  - cmY * (v_AYLZ - v_AZLY)
107  + v_AXAY * (Iaa.YY - Iaa.XX)
108  + v_AXAZ*Iaa.YZ - Iaa.XZ*v_AYAZ - (wy2 - wx2)*Iaa.XY;
109 
110  ret(LX) = m * (v_AYLZ - v_AZLY) - cmX * (wz2 + wy2) + v_AXAZ*cmZ + v_AXAY*cmY;
111  ret(LY) = - m * (v_AXLZ - v_AZLX) - cmY * (wz2 + wx2) + v_AXAY*cmX + v_AYAZ*cmZ;
112  ret(LZ) = m * (v_AXLY - v_AYLX) - cmZ * (wy2 + wx2) + v_AXAZ*cmX + v_AYAZ*cmY;
113  return ret;
114 }
115 
125 template <typename Derived>
126 inline Force<DScalar> vxIv(const DScalar& omegaz, const MatrixBase<Derived>& I)
127 {
128  DScalar wz2 = omegaz*omegaz;
129  Force<DScalar> ret;
130  ret(AX) = -I(AY,AZ) * wz2;
131  ret(AY) = I(AX,AY) * wz2;
132  ret(AZ) = 0;
133  ret(LX) = I(AY,LZ) * wz2;
134  ret(LY) = I(AZ,LX) * wz2;
135  ret(LZ) = 0;
136  return ret;
137 }
138 
139 // very important, un-define the convenience macros to avoid polluting the namespace
140 #undef DScalar
141 
142 
152 template<typename S = double>
153 inline void motionCrossProductMx(const Velocity<S>& v, Mat66<S>& vx)
154 {
155  vx(AY,AZ) = vx(LY,LZ) = - ( vx(AZ,AY) = vx(LZ,LY) = v(AX) );
156  vx(AZ,AX) = vx(LZ,LX) = - ( vx(AX,AZ) = vx(LX,LZ) = v(AY) );
157  vx(AX,AY) = vx(LX,LY) = - ( vx(AY,AX) = vx(LY,LX) = v(AZ) );
158 
159  vx(LY,AZ) = - ( vx(LZ,AY) = v(LX) );
160  vx(LZ,AX) = - ( vx(LX,AZ) = v(LY) );
161  vx(LX,AY) = - ( vx(LY,AX) = v(LZ) );
162 }
171 template<typename S = double>
172 inline void forceCrossProductMx(const Velocity<S>& v, Mat66<S>& vx)
173 {
174  vx(AY,AZ) = vx(LY,LZ) = - ( vx(AZ,AY) = vx(LZ,LY) = v(AX) );
175  vx(AZ,AX) = vx(LZ,LX) = - ( vx(AX,AZ) = vx(LX,LZ) = v(AY) );
176  vx(AX,AY) = vx(LX,LY) = - ( vx(AY,AX) = vx(LY,LX) = v(AZ) );
177 
178  vx(AY,LZ) = - ( vx(AZ,LY) = v(LX) );
179  vx(AZ,LX) = - ( vx(AX,LZ) = v(LY) );
180  vx(AX,LY) = - ( vx(AY,LX) = v(LZ) );
181 }
182 
183 
184 template<typename S = double>
185 void fillInertia(S mass, const Vec3<S>& com, const internal::SymmMat3x3Coefficients<S>& I3x3,
186  InertiaMat<S>& I)
187 {
188  I(AX,AX) = I3x3.XX;
189  I(AY,AY) = I3x3.YY;
190  I(AZ,AZ) = I3x3.ZZ;
191  I(AY,AX) = I(AX,AY) = I3x3.XY;
192  I(AZ,AX) = I(AX,AZ) = I3x3.XZ;
193  I(AZ,AY) = I(AY,AZ) = I3x3.YZ;
194 
195  I(AX,LY) = I(LY,AX) = - ( I(AY,LX) = I(LX,AY) = mass*com(Z) );
196  I(AZ,LX) = I(LX,AZ) = - ( I(AX,LZ) = I(LZ,AX) = mass*com(Y) );
197  I(AY,LZ) = I(LZ,AY) = - ( I(AZ,LY) = I(LY,AZ) = mass*com(X) );
198 
199  I(LX,LX) = I(LY,LY) = I(LZ,LZ) = mass;
200 }
201 
202 
217 template<typename Scalar = double>
219  const InertiaMat<Scalar>& I_A,
220  const Mat66<Scalar>& XF,
221  InertiaMat<Scalar>& I_B)
222 {
223  // The coefficients of the 3x3 rotation matrix
225  XF(AX,AX),XF(AX,AY),XF(AX,AZ),
226  XF(AY,AX),XF(AY,AY),XF(AY,AZ),
227  XF(AZ,AX),XF(AZ,AY),XF(AZ,AZ));
228  Scalar mass = I_A.getMass();
229 
230  // The relative position 'r' of the origin of frame B wrt A (in A coordinates).
231  // The vector is basically "reconstructed" from the matrix XF, which has
232  // this form:
233  // | E -E rx |
234  // | 0 E |
235  // where 'rx' is the cross product matrix. The strategy is to compute
236  // E^T (-E rx) = -rx , and then get the coordinates of 'r' from 'rx'.
237  // This code is a manual implementation of the E transpose multiplication,
238  // limited to the elements of interest.
239  // Note that this is necessary because, currently, spatial transforms do
240  // not carry explicitly the information about the translation vector.
241  Scalar rx = E.XY * XF(AX,LZ) + E.YY * XF(AY,LZ) + E.ZY * XF(AZ,LZ);
242  Scalar ry = E.XZ * XF(AX,LX) + E.YZ * XF(AY,LX) + E.ZZ * XF(AZ,LX);
243  Scalar rz = E.XX * XF(AX,LY) + E.YX * XF(AY,LY) + E.ZX * XF(AZ,LY);
244 
245  // The relative position of the CoM wrt A (in A coordinates)
246  Scalar comAx = I_A(AZ,LY)/mass;
247  Scalar comAy = I_A(AX,LZ)/mass;
248  Scalar comAz = I_A(AY,LX)/mass;
249 
250  // The relative position of the CoM wrt B (in A coordinates)
251  typename Core<Scalar>::Vector3 p(comAx-rx, comAy-ry, comAz-rz);
252 
253  // Pre-computation of some recurring squares
254  Scalar cx2 = comAx*comAx;
255  Scalar cy2 = comAy*comAy;
256  Scalar cz2 = comAz*comAz;
257  Scalar px2 = p(X)*p(X);
258  Scalar py2 = p(Y)*p(Y);
259  Scalar pz2 = p(Z)*p(Z);
260 
261  // Manual implementation of the parallel axis theorem, to translate the
262  // 3x3 tensor from frame A to frame B :
264  I_A(AX,AX), I_A(AX,AY), I_A(AX,AZ)
265  , I_A(AY,AY), I_A(AY,AZ)
266  , I_A(AZ,AZ));
267  I_translated.XX += mass*( py2 + pz2 - cy2 - cz2 );
268  I_translated.YY += mass*( px2 + pz2 - cx2 - cz2 );
269  I_translated.ZZ += mass*( px2 + py2 - cx2 - cy2 );
270  I_translated.XY += mass*( comAx*comAy - p(X)*p(Y) );
271  I_translated.XZ += mass*( comAx*comAz - p(X)*p(Z) );
272  I_translated.YZ += mass*( comAy*comAz - p(Y)*p(Z) );
273 
274  // Rotate the 3x3 tensor
276  internal::rot_symmetric_EAET<Scalar>(E, I_translated, I3x3_B);
277  // Rotate the CoM vector
278  typename Core<Scalar>::Vector3 p_B(
279  E.XX*p(X) + E.XY*p(Y) + E.XZ*p(Z),
280  E.YX*p(X) + E.YY*p(Y) + E.YZ*p(Z),
281  E.ZX*p(X) + E.ZY*p(Y) + E.ZZ*p(Z)
282  );
283 
284  // Finally copy the coefficients into the destination matrix
285  fillInertia(mass, p_B, I3x3_B, I_B);
286 }
287 
289 
290 
291 
292 #define block33 template block<3,3>
293 
312 
314 template <typename D1, typename D2, typename D3>
316  const MatrixBase<D1>& Ia_A,
317  const MatrixBase<D2>& XM,
318  const MatrixBase<D3>& Ia_B_const)
319 {
320  typedef typename D1::Scalar Scalar; // we assume D1 D2 D3 use the same scalar type!
321 
322  MatrixBase<D3>& Ia_B = const_cast<MatrixBase<D3>&>(Ia_B_const);
323  // Get the coefficients of the 3x3 rotation matrix B_E_A
324  // It is the transpose of the angular-angular block of the spatial transform
326  XM(AX,AX),XM(AY,AX),XM(AZ,AX),
327  XM(AX,AY),XM(AY,AY),XM(AZ,AY),
328  XM(AX,AZ),XM(AY,AZ),XM(AZ,AZ));
329 
330  // Recover the translation vector. See comment in method 'transformInertia'
331  Scalar rx = E.XY * XM(LZ,AX) + E.YY * XM(LZ,AY) + E.ZY * XM(LZ,AZ);
332  Scalar ry = E.XZ * XM(LX,AX) + E.YZ * XM(LX,AY) + E.ZZ * XM(LX,AZ);
333  Scalar rz = E.XX * XM(LY,AX) + E.YX * XM(LY,AY) + E.ZX * XM(LY,AZ);
334 
335  // Angular-angular 3x3 sub-block:
336 
338 
339  // ## compute I + (Crx + Crx^T) :
340 
341  // Remember that, for a revolute joint, the structure of the matrix is as
342  // follows (note the zeros):
343  // [ia1, ia2, 0, ia4, ia5, ia6 ]
344  // [ia2, ia7, 0, ia8, ia9, ia10]
345  // [0 , 0, 0, 0, 0, 0 ]
346  // [ia4, ia8, 0, ia11, ia12, ia13]
347  // [ia5, ia9, 0, ia12, ia14, ia15]
348  // [ia6, ia10, 0, ia13, ia15, ia16]
349 
350  // copying the coefficients results in slightly fewer invocations of the
351  // operator(int,int), in the rest of the function
353  Ia_A(AX,LX),Ia_A(AX,LY),Ia_A(AX,LZ),
354  Ia_A(AY,LX),Ia_A(AY,LY),Ia_A(AY,LZ),
355  Scalar(0), Scalar(0), Scalar(0));
356 
357  aux1.XX = Ia_A(AX,AX) + 2*C.XY*rz - 2*C.XZ*ry;
358  aux1.YY = Ia_A(AY,AY) + 2*C.YZ*rx - 2*C.YX*rz;
359  aux1.ZZ = Scalar(0);
360  aux1.XY = Ia_A(AX,AY) + C.YY*rz - C.XX*rz - C.YZ*ry + C.XZ*rx;
361  aux1.XZ = C.XX*ry - C.XY*rx;
362  aux1.YZ = C.YX*ry - C.YY*rx;
363 
364  // ## compute (- rx M) (note the minus)
366  Ia_A(LX,LX),Ia_A(LX,LY),Ia_A(LX,LZ)
367  ,Ia_A(LY,LY),Ia_A(LY,LZ)
368  ,Ia_A(LZ,LZ));
370  rxM.XX = rz*M.XY - ry*M.XZ;
371  rxM.YY = rx*M.YZ - rz*M.XY;
372  rxM.ZZ = ry*M.XZ - rx*M.YZ;
373  rxM.XY = rz*M.YY - ry*M.YZ;
374  rxM.YX = rx*M.XZ - rz*M.XX;
375  rxM.XZ = rz*M.YZ - ry*M.ZZ;
376  rxM.ZX = ry*M.XX - rx*M.XY;
377  rxM.YZ = rx*M.ZZ - rz*M.XZ;
378  rxM.ZY = ry*M.XY - rx*M.YY;
379 
380  // ## compute (I + (Crx + Crx^T)) - (rxM) rx
381  aux1.XX += rxM.XY*rz - rxM.XZ*ry;
382  aux1.YY += rxM.YZ*rx - rxM.YX*rz;
383  aux1.ZZ += rxM.ZX*ry - rxM.ZY*rx;
384  aux1.XY += rxM.XZ*rx - rxM.XX*rz;
385  aux1.XZ += rxM.XX*ry - rxM.XY*rx;
386  aux1.YZ += rxM.YX*ry - rxM.YY*rx;
387 
388  // ## compute E ( .. ) E^T
389  internal::rot_symmetric_EAET<Scalar>(E, aux1, aux2);
390 
391  // Copy the result, angular-angular block of the output
392  Ia_B(AX,AX) = aux2.XX;
393  Ia_B(AY,AY) = aux2.YY;
394  Ia_B(AZ,AZ) = aux2.ZZ;
395  Ia_B(AY,AX) = Ia_B(AX,AY) = aux2.XY;
396  Ia_B(AZ,AX) = Ia_B(AX,AZ) = aux2.XZ;
397  Ia_B(AZ,AY) = Ia_B(AY,AZ) = aux2.YZ;
398  // aux2.write(Ia_B.block33(AX,AX)); // this is be equivalent, but it uses a block expression
399 
400 
401  // Angular-linear block (and linear-angular block)
402  // Calculate E ( C -rxM ) E^T
403  // - note that 'rxM' already contains the coefficients of (- rx * M)
404  // - for a revolute joint, the last line of C is zero
405  rxM.XX += C.XX;
406  rxM.XY += C.XY;
407  rxM.XZ += C.XZ;
408  rxM.YX += C.YX;
409  rxM.YY += C.YY;
410  rxM.YZ += C.YZ;
411 
413  internal::rot_EAET<Scalar>(E, rxM, aux3);
414  // copy the result, also to the symmetric 3x3 block
415  Ia_B(LX,AX) = Ia_B(AX,LX) = aux3.XX;
416  Ia_B(LY,AX) = Ia_B(AX,LY) = aux3.XY;
417  Ia_B(LZ,AX) = Ia_B(AX,LZ) = aux3.XZ;
418  Ia_B(LX,AY) = Ia_B(AY,LX) = aux3.YX;
419  Ia_B(LY,AY) = Ia_B(AY,LY) = aux3.YY;
420  Ia_B(LZ,AY) = Ia_B(AY,LZ) = aux3.YZ;
421  Ia_B(LX,AZ) = Ia_B(AZ,LX) = aux3.ZX;
422  Ia_B(LY,AZ) = Ia_B(AZ,LY) = aux3.ZY;
423  Ia_B(LZ,AZ) = Ia_B(AZ,LZ) = aux3.ZZ;
424 
425  // Linear-linear block
426  internal::rot_symmetric_EAET<Scalar>(E, M, aux1);
427  Ia_B(LX,LX) = aux1.XX;
428  Ia_B(LY,LY) = aux1.YY;
429  Ia_B(LZ,LZ) = aux1.ZZ;
430  Ia_B(LY,LX) = Ia_B(LX,LY) = aux1.XY;
431  Ia_B(LZ,LX) = Ia_B(LX,LZ) = aux1.XZ;
432  Ia_B(LZ,LY) = Ia_B(LY,LZ) = aux1.YZ;
433  //aux1.write(Ia_B.block33(LX,LX)); // this is be equivalent, but it uses a block expression
434 }
435 
437 template <typename D1, typename D2, typename D3>
439  const MatrixBase<D1>& Ia_A,
440  const MatrixBase<D2>& XM,
441  const MatrixBase<D3>& Ia_B_const)
442 {
443  typedef typename D1::Scalar Scalar; // we assume D1 D2 D3 use the same scalar type!
444 
445  MatrixBase<D3>& Ia_B = const_cast<MatrixBase<D3>&>(Ia_B_const);
446  // Get the coefficients of the 3x3 rotation matrix B_E_A
447  // It is the transpose of the angular-angular block of the spatial transform
449  XM(AX,AX),XM(AY,AX),XM(AZ,AX),
450  XM(AX,AY),XM(AY,AY),XM(AZ,AY),
451  XM(AX,AZ),XM(AY,AZ),XM(AZ,AZ));
452 
453  // Recover the translation vector. See comment in method 'transformInertia'
454  Scalar rx = E.XY * XM(LZ,AX) + E.YY * XM(LZ,AY) + E.ZY * XM(LZ,AZ);
455  Scalar ry = E.XZ * XM(LX,AX) + E.YZ * XM(LX,AY) + E.ZZ * XM(LX,AZ);
456  Scalar rz = E.XX * XM(LY,AX) + E.YX * XM(LY,AY) + E.ZX * XM(LY,AZ);
457 
458  // Angular-angular 3x3 sub-block:
459 
461 
462  // Remember that, for a prismatic joint, the structure of the matrix is as
463  // follows (note the zeros):
464 
465  // [ia1, ia2, ia3, | ia4, ia5, 0 ]
466  // [ia2, ia6, ia7, | ia8, ia9, 0 ]
467  // [ia3, ia7, ia10,| ia11, ia12, 0 ]
468  // -----------------|-----------------
469  // [ia4, ia8, ia11,| ia13, ia14, 0 ]
470  // [ia5, ia9, ia12,| ia14, ia15, 0 ]
471  // [0 , 0, 0, | 0, 0, 0 ]
472 
473  // [ I | C ]
474  // -----|-----
475  // [ C^T | M ]
476 
477  // copying the coefficients results in slightly fewer invocations of the
478  // operator(int,int), in the rest of the function
480  Ia_A(AX,LX), Ia_A(AX,LY), 0,
481  Ia_A(AY,LX), Ia_A(AY,LY), 0,
482  Ia_A(AZ,LX), Ia_A(AZ,LY), 0);
483 
484  // ## compute I + (Crx + Crx^T) :
485  aux1.XX = Ia_A(AX,AX) + 2*C.XY*rz;
486  aux1.YY = Ia_A(AY,AY) - 2*C.YX*rz;
487  aux1.ZZ = Ia_A(AZ,AZ) + 2*C.ZX*ry - 2*C.ZY*rx;
488  aux1.XY = Ia_A(AX,AY) + (C.YY - C.XX)*rz;
489  aux1.XZ = Ia_A(AX,AZ) + C.ZY*rz + C.XX*ry - C.XY*rx;
490  aux1.YZ = Ia_A(AY,AZ) - C.ZX*rz + C.YX*ry - C.YY*rx;
491 
492 
494  Ia_A(LX,LX),Ia_A(LX,LY), 0
495  ,Ia_A(LY,LY), 0
496  , 0);
497  // ## compute the term (- rx M) (note the minus)
499  rxM.XX = rz*M.XY;
500  rxM.XY = rz*M.YY;
501  rxM.YX = - rz*M.XX;
502  rxM.YY = - rz*M.XY;
503  rxM.ZX = ry*M.XX - rx*M.XY;
504  rxM.ZY = ry*M.XY - rx*M.YY;
505  rxM.XZ = 0.0;
506  rxM.YZ = 0.0;
507  rxM.ZZ = 0.0;
508 
509  // ## compute (I + (Crx + Crx^T)) - (rxM) rx
510  aux1.XX += rxM.XY*rz;
511  aux1.YY += - rxM.YX*rz;
512  aux1.ZZ += rxM.ZX*ry - rxM.ZY*rx;
513  aux1.XY += - rxM.XX*rz;
514  aux1.XZ += rxM.XX*ry - rxM.XY*rx;
515  aux1.YZ += rxM.YX*ry - rxM.YY*rx;
516 
517  // ## compute E ( I + Crx + (Crx)^T - rx M rx ) E^T
518  internal::rot_symmetric_EAET<Scalar>(E, aux1, aux2);
519 
520  // Copy the result, angular-angular block of the output
521  Ia_B(AX,AX) = aux2.XX;
522  Ia_B(AY,AY) = aux2.YY;
523  Ia_B(AZ,AZ) = aux2.ZZ;
524  Ia_B(AY,AX) = Ia_B(AX,AY) = aux2.XY;
525  Ia_B(AZ,AX) = Ia_B(AX,AZ) = aux2.XZ;
526  Ia_B(AZ,AY) = Ia_B(AY,AZ) = aux2.YZ;
527  // aux2.write(Ia_B.block33(AX,AX)); // this is be equivalent, but it uses a block expression
528 
529 
530  // Angular-linear block (and linear-angular block)
531  // Calculate E ( C -rxM ) E^T
532  // - note that 'rxM' already contains the coefficients of (- rx * M)
533  // - for a prismatic joint, the last column of C is zero
534  rxM.XX += C.XX;
535  rxM.XY += C.XY;
536  //rxM.XZ stays zero
537  rxM.YX += C.YX;
538  rxM.YY += C.YY;
539  //rxM.YZ stays zero
540  rxM.ZX += C.ZX;
541  rxM.ZY += C.ZY;
542 
544  internal::rot_EAET<Scalar>(E, rxM, aux3); // TODO exploit the zeros in rxM
545  // copy the result, also to the symmetric 3x3 block
546  Ia_B(LX,AX) = Ia_B(AX,LX) = aux3.XX;
547  Ia_B(LY,AX) = Ia_B(AX,LY) = aux3.XY;
548  Ia_B(LZ,AX) = Ia_B(AX,LZ) = aux3.XZ;
549  Ia_B(LX,AY) = Ia_B(AY,LX) = aux3.YX;
550  Ia_B(LY,AY) = Ia_B(AY,LY) = aux3.YY;
551  Ia_B(LZ,AY) = Ia_B(AY,LZ) = aux3.YZ;
552  Ia_B(LX,AZ) = Ia_B(AZ,LX) = aux3.ZX;
553  Ia_B(LY,AZ) = Ia_B(AZ,LY) = aux3.ZY;
554  Ia_B(LZ,AZ) = Ia_B(AZ,LZ) = aux3.ZZ;
555 
556  // Linear-linear block
557  internal::rot_symmetric_EAET<Scalar>(E, M, aux1); // TODO exploit the zeros in M
558  Ia_B(LX,LX) = aux1.XX;
559  Ia_B(LY,LY) = aux1.YY;
560  Ia_B(LZ,LZ) = aux1.ZZ;
561  Ia_B(LY,LX) = Ia_B(LX,LY) = aux1.XY;
562  Ia_B(LZ,LX) = Ia_B(LX,LZ) = aux1.XZ;
563  Ia_B(LZ,LY) = Ia_B(LY,LZ) = aux1.YZ;
564  //aux1.write(Ia_B.block33(LX,LX)); // this is be equivalent, but it uses a block expression
565 }
567 #undef block33
568 
592 
594 template <typename D1, typename D2>
596  const MatrixBase<D1>& IA,
597  const Vec6<typename D1::Scalar>& U,
598  const typename D1::Scalar& D,
599  const MatrixBase<D2>& Ia_const)
600 {
601  typedef typename D1::Scalar Scalar; // we assume D1 D2 use the same scalar type!
602 
603  MatrixBase<D2>& Ia = const_cast<MatrixBase<D2>&>(Ia_const);
604 
605  Scalar UD_AX = U(AX) / D;
606  Scalar UD_AY = U(AY) / D;
607  //Scalar UD_AZ = U(AZ) / D;
608  Scalar UD_LX = U(LX) / D;
609  Scalar UD_LY = U(LY) / D;
610  Scalar UD_LZ = U(LZ) / D;
611 
612  Ia(AX,AX) = IA(AX,AX) - U(AX)*UD_AX;
613  Ia(AX,AY) = Ia(AY,AX) = IA(AX,AY) - U(AX)*UD_AY;
614  //Ia(AX,AZ) = Ia(AZ,AX) = 0; // it is assumed to be set already
615  Ia(AX,LX) = Ia(LX,AX) = IA(AX,LX) - U(AX)*UD_LX;
616  Ia(AX,LY) = Ia(LY,AX) = IA(AX,LY) - U(AX)*UD_LY;
617  Ia(AX,LZ) = Ia(LZ,AX) = IA(AX,LZ) - U(AX)*UD_LZ;
618 
619  Ia(AY,AY) = IA(AY,AY) - U(AY)*UD_AY;
620  //Ia(AY,AZ) = Ia(AZ,AY) = 0; // it is assumed to be set already
621  Ia(AY,LX) = Ia(LX,AY) = IA(AY,LX) - U(AY)*UD_LX;
622  Ia(AY,LY) = Ia(LY,AY) = IA(AY,LY) - U(AY)*UD_LY;
623  Ia(AY,LZ) = Ia(LZ,AY) = IA(AY,LZ) - U(AY)*UD_LZ;
624 
625  //The whole row AZ it is assumed to be already set to zero
626 
627  Ia(LX,LX) = IA(LX,LX) - U(LX)*UD_LX;
628  Ia(LX,LY) = Ia(LY,LX) = IA(LX,LY) - U(LX)*UD_LY;
629  Ia(LX,LZ) = Ia(LZ,LX) = IA(LX,LZ) - U(LX)*UD_LZ;
630 
631  Ia(LY,LY) = IA(LY,LY) - U(LY)*UD_LY;
632  Ia(LY,LZ) = Ia(LZ,LY) = IA(LY,LZ) - U(LY)*UD_LZ;
633 
634  Ia(LZ,LZ) = IA(LZ,LZ) - U(LZ)*UD_LZ;
635 }
636 
638 template <typename D1, typename D2>
640  const MatrixBase<D1>& IA,
641  const Vec6<typename D1::Scalar>& U,
642  const typename D1::Scalar& D,
643  const MatrixBase<D2>& Ia_const)
644 {
645  typedef typename D1::Scalar Scalar; // we assume D1 D2 use the same scalar type!
646 
647  MatrixBase<D2>& Ia = const_cast<MatrixBase<D2>&>(Ia_const);
648 
649  Scalar UD_AX = U(AX) / D;
650  Scalar UD_AY = U(AY) / D;
651  Scalar UD_AZ = U(AZ) / D;
652  Scalar UD_LX = U(LX) / D;
653  Scalar UD_LY = U(LY) / D;
654  //Scalar UD_LZ = U(LZ) / D;
655 
656  Ia(AX,AX) = IA(AX,AX) - U(AX)*UD_AX;
657  Ia(AX,AY) = Ia(AY,AX) = IA(AX,AY) - U(AX)*UD_AY;
658  Ia(AX,AZ) = Ia(AZ,AX) = IA(AX,AZ) - U(AX)*UD_AZ;
659  Ia(AX,LX) = Ia(LX,AX) = IA(AX,LX) - U(AX)*UD_LX;
660  Ia(AX,LY) = Ia(LY,AX) = IA(AX,LY) - U(AX)*UD_LY;
661  //Ia(AX,LZ) = Ia(LZ,AX) = 0; // it is assumed to be set already
662 
663  Ia(AY,AY) = IA(AY,AY) - U(AY)*UD_AY;
664  Ia(AY,AZ) = Ia(AZ,AY) = IA(AY,AZ) - U(AY)*UD_AZ;
665  Ia(AY,LX) = Ia(LX,AY) = IA(AY,LX) - U(AY)*UD_LX;
666  Ia(AY,LY) = Ia(LY,AY) = IA(AY,LY) - U(AY)*UD_LY;
667  //Ia(AY,LZ) = Ia(LZ,AY) = 0; // it is assumed to be set already
668 
669  Ia(AZ,AZ) = IA(AZ,AZ) - U(AZ)*UD_AZ;
670  Ia(AZ,LX) = Ia(LX,AZ) = IA(AZ,LX) - U(AZ)*UD_LX;
671  Ia(AZ,LY) = Ia(LY,AZ) = IA(AZ,LY) - U(AZ)*UD_LY;
672  //Ia(AZ,LZ) = Ia(LZ,AZ) = 0; // it is assumed to be set already
673 
674  Ia(LX,LX) = IA(LX,LX) - U(LX)*UD_LX;
675  Ia(LX,LY) = Ia(LY,LX) = IA(LX,LY) - U(LX)*UD_LY;
676  //Ia(LX,LZ) = Ia(LZ,LX) = 0; // it is assumed to be set already
677 
678  Ia(LY,LY) = IA(LY,LY) - U(LY)*UD_LY;
679  //Ia(LY,LZ) = Ia(LZ,LY) = 0; // it is assumed to be set already
680 
681  //Ia(LZ,LZ) = 0; // it is assumed to be set already
682 }
684 
685 
686 
687 
688 }
689 }
690 
691 #endif
Scalar YZ
Definition: internals.h:30
Definition: rbd.h:173
void compute_Ia_revolute(const MatrixBase< D1 > &IA, const Vec6< typename D1::Scalar > &U, const typename D1::Scalar &D, const MatrixBase< D2 > &Ia_const)
Definition: robcogen_commons.h:595
typename Core< S >::VelocityVector Velocity
Definition: types.h:21
Scalar YX
Definition: internals.h:30
Definition: rbd.h:175
Scalar XZ
Definition: internals.h:64
void compute_Ia_prismatic(const MatrixBase< D1 > &IA, const Vec6< typename D1::Scalar > &U, const typename D1::Scalar &D, const MatrixBase< D2 > &Ia_const)
Definition: robcogen_commons.h:639
Definition: rbd.h:175
Scalar ZZ
Definition: internals.h:64
ct::core::ADCodegenLinearizer< state_dim, control_dim >::ADCGScalar Scalar
Force< DScalar > vxIv(const Velocity< DScalar > &v, const MatrixBase< Derived > &I)
Definition: robcogen_commons.h:58
Definition: internals.h:28
Scalar YZ
Definition: internals.h:64
Definition: InertiaMatrix.h:25
Definition: rbd.h:175
Definition: rbd.h:175
Scalar XX
Definition: internals.h:64
Scalar XY
Definition: internals.h:64
void transformInertia(const InertiaMat< Scalar > &I_A, const Mat66< Scalar > &XF, InertiaMat< Scalar > &I_B)
Definition: robcogen_commons.h:218
typename Core< S >::Vector6 Vec6
Definition: types.h:26
typename Core< S >::Matrix66 Mat66
Definition: types.h:24
Scalar XX
Definition: internals.h:30
Vector6D ForceVector
a 3D subvector of a 6D vector
Definition: rbd.h:92
void fillInertia(S mass, const Vec3< S > &com, const internal::SymmMat3x3Coefficients< S > &I3x3, InertiaMat< S > &I)
Definition: robcogen_commons.h:185
Eigen::MatrixBase< Derived > MatrixBase
Definition: rbd.h:51
Scalar YY
Definition: internals.h:30
Definition: rbd.h:173
void forceCrossProductMx(const Velocity< S > &v, Mat66< S > &vx)
Definition: robcogen_commons.h:172
Scalar ZX
Definition: internals.h:30
Scalar XZ
Definition: internals.h:30
void ctransform_Ia_prismatic(const MatrixBase< D1 > &Ia_A, const MatrixBase< D2 > &XM, const MatrixBase< D3 > &Ia_B_const)
Definition: robcogen_commons.h:438
typename Core< S >::ForceVector Force
Definition: types.h:22
Scalar YY
Definition: internals.h:64
Scalar XY
Definition: internals.h:30
Scalar ZY
Definition: internals.h:30
PlainMatrix< Scalar, 3, 1 > Vector3
Definition: rbd.h:80
Definition: rbd.h:173
Definition: rbd.h:175
Scalar ZZ
Definition: internals.h:30
typename Core< S >::Vector3 Vec3
Definition: types.h:25
void ctransform_Ia_revolute(const MatrixBase< D1 > &Ia_A, const MatrixBase< D2 > &XM, const MatrixBase< D3 > &Ia_B_const)
Definition: robcogen_commons.h:315
#define DScalar
Definition: robcogen_commons.h:41
Definition: rbd.h:175
void motionCrossProductMx(const Velocity< S > &v, Mat66< S > &vx)
Definition: robcogen_commons.h:153