- 3.0.2 rigid body dynamics module.
InertiaMatrix.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_INERTIAMATRIX_H_
11 #define _IIT_RBD_INERTIAMATRIX_H_
12 
13 #include "rbd.h"
14 
15 
16 namespace iit {
17 namespace rbd {
18 
19 namespace tpl {
24 template<typename SCALAR>
25 class InertiaMatrixDense : public Core<SCALAR>::Matrix66
26 {
27 public:
28  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
29 
30  typedef SCALAR Scalar;
31 private:
32  typedef Core<Scalar> Cores;
33  typedef typename Cores::Matrix66 Base;
34  typedef typename Cores::Matrix33 Mat33;
35  typedef typename Cores::Vector3 Vec3;
36  typedef MatrixBlock<const Base,3,3> Block33_const;
37  typedef MatrixBlock<Base,3,3> Block33_t;
38 
39 public:
40  template<typename OtherDerived>
42 
43  template<typename OtherDerived>
45 
50  InertiaMatrixDense(Scalar m, const Vec3& com, const Mat33& I);
51 
52 public:
69  void fill(Scalar m, const Vec3& com, const Mat33& tensor);
70 
72 
77  Scalar getMass() const;
82  Vec3 getCOM() const;
87  const Block33_const get3x3Tensor() const;
89 
91 
106  void changeMass(Scalar m);
121  void changeCOM(const Vec3& newcom);
127  void changeRotationalInertia(const Mat33& tensor);
129 protected:
130  void setTheFixedZeros();
131 
132  template<typename Vector>
134  const MatrixBase<Vector>& v,
135  Block33_t block);
136 private:
137  void set(Scalar m, const Vec3& com, const Mat33& I);
138 
139 };
140 
141 template<typename SCALAR>
142 class InertiaMatrixSparse : public SparseMatrix<SCALAR>
143 {
144  typedef SparseMatrix<SCALAR> Base;
145 };
146 
147 
148 #define block33 this->template block<3,3>
149 #define data (this->operator())
150 #define TPL template<typename S>
151 #define CLASS InertiaMatrixDense<S>
152 
153 
154 /* I do not care here about the creation of temporaries, thus I use const
155  * refs to actual Eigen matrices, rather than the common base of the
156  * matrix expression. If you haven't read Eigen docs, this comment is
157  * completely obscure!
158  */
159 TPL
160 inline CLASS::InertiaMatrixDense() : Base() {
161  setTheFixedZeros();
162 }
163 
168 TPL
170  Scalar mass, const Vec3& cogPosition, const Mat33& tensor)
171 : Base()
172 {
173  setTheFixedZeros();
174  set(mass, cogPosition, tensor);
175 }
176 
177 TPL
178 inline void CLASS::fill(Scalar mass, const Vec3& comPosition,
179  const Mat33& tensor)
180 {
181  set(mass, comPosition, tensor);
182 }
183 
184 TPL
185 inline typename CLASS::Scalar CLASS::getMass() const
186 {
187  return data(LX,LX);
188 }
189 
190 TPL
191 inline typename CLASS::Vec3 CLASS::getCOM() const
192 {
193  return Vec3(
194  data(AZ,LY)/data(LX,LX), // X coordinate of the COM
195  data(AX,LZ)/data(LX,LX), // Y
196  data(AY,LX)/data(LX,LX));// Z
197 }
198 
199 TPL
200 inline const typename CLASS::Block33_const CLASS::get3x3Tensor() const
201 {
202  return block33(AX,AX);
203 }
204 
205 TPL
206 inline void CLASS::changeMass(Scalar newMass) {
207  // Note the use of indices AX and hard-coded 0, to make it independent from
208  // the convention angular/linear
209  this->block<3,6>(AX,0) *= newMass/getMass();
210  block33(LX,AX) = block33(AX,LX).transpose();
211  data(LX,LX) = data(LY,LY) = data(LZ,LZ) = newMass;
212 }
213 
214 TPL
215 inline void CLASS::changeCOM(const Vec3& newcom)
216 {
217  // Update the angular-linear block according to the new COM position
218  setSkewSymmetricBlock( getMass() * newcom, block33(AX,LX));
219 
220  // Correct the 3x3 tensor. Use the block(AX,LX) which reflects the new COM
221  // and the block(LX,AX) which instead is still based on the previous value.
222  // I = I - m(cx)(cx)^T + m(c'x)(c'x)^T
223  // where cx is the skew symmetric matrix for the old COM vector, while
224  // c'x is the one for the new COM vector.
225  block33(AX,AX) += (
226  ( block33(AX,LX) * block33(AX,LX).transpose() ) -
227  ( block33(LX,AX).transpose() * block33(LX,AX) )
228  ) / getMass();
229  // Update the linear-angular block
230  block33(LX,AX) = block33(AX,LX).transpose();
231  // alternatively:
232  // setSkewSymmetricBlock( - getMass() * newcom, block33(LX,AX));
233 }
234 
235 TPL
236 inline void CLASS::changeRotationalInertia(const Mat33& tensor)
237 {
238  block33(AX,AX) = tensor;
239 }
240 
241 TPL
242 inline void CLASS::set(
243  Scalar mass,
244  const Vec3& com,
245  const Mat33& tensor)
246 {
247  block33(AX,AX) = tensor;// + mass * comCrossMx * comCrossMx.transpose();
248 
249  data(AX,LY) = data(LY,AX) = - ( data(AY,LX) = data(LX,AY) = mass*com(Z) );
250  data(AZ,LX) = data(LX,AZ) = - ( data(AX,LZ) = data(LZ,AX) = mass*com(Y) );
251  data(AY,LZ) = data(LZ,AY) = - ( data(AZ,LY) = data(LY,AZ) = mass*com(X) );
252  // Equivalent, just slightly less efficient (probably because of Eigen's blocks and repeated product):
253  //setSkewSymmetricBlock( mass * com, block33(AX,LX));
254  //setSkewSymmetricBlock(- mass * com, block33(LX,AX));
255 
256  data(LX,LX) = data(LY,LY) = data(LZ,LZ) = mass;
257 }
258 
259 TPL
260 template<typename OtherDerived>
261 inline CLASS& CLASS::operator=
262  (const MatrixBase<OtherDerived>& other)
263 {
264  // Here we silently assume that 'other' is also an inertia...
265  // Type safety would suggest to prevent the assignment of anything but
266  // another inertia, but that would prevent, for example, the assignment
267  // of matrix expressions. We also do not want to perform any check, for
268  // performance reasons (remember this library is meant primarily to support
269  // code generation, not to be a robust API for user applications).
270  block33(AX,AX) = other.template block<3,3>(AX,AX);
271  data(AX,LY) = data(LY,AX) = - ( data(AY,LX) = data(LX,AY) = other(LX,AY) );
272  data(AZ,LX) = data(LX,AZ) = - ( data(AX,LZ) = data(LZ,AX) = other(LZ,AX) );
273  data(AY,LZ) = data(LZ,AY) = - ( data(AZ,LY) = data(LY,AZ) = other(LY,AZ) );
274  data(LX,LX) = data(LY,LY) = data(LZ,LZ) = other(LX,LX);
275  return *this;
276 }
277 
278 TPL
279 template<typename OtherDerived>
280 inline CLASS& CLASS::operator+=
281  (const MatrixBase<OtherDerived>& other)
282 {
283  block33(AX,AX) += other.template block<3,3>(AX,AX);
284  data(AX,LY) = data(LY,AX) = - ( data(AY,LX) = (data(LX,AY) += other(LX,AY)) );
285  data(AZ,LX) = data(LX,AZ) = - ( data(AX,LZ) = (data(LZ,AX) += other(LZ,AX)) );
286  data(AY,LZ) = data(LZ,AY) = - ( data(AZ,LY) = (data(LY,AZ) += other(LY,AZ)) );
287  data(LX,LX) = data(LY,LY) = (data(LZ,LZ) += other(LX,LX));
288  return *this;
289 }
290 
291 TPL
292 inline void CLASS::setTheFixedZeros()
293 {
294  block33(LX,LX).setZero(); // the diagonal won't be zero, but who cares
295  data(AX,LX) = data(AY,LY) = data(AZ,LZ) =
296  data(LX,AX) = data(LY,AY) = data(LZ,AZ) = 0;
297 }
298 
299 TPL
300 template<typename Vector>
301 inline void CLASS::setSkewSymmetricBlock(
302  const MatrixBase<Vector>& v, Block33_t block)
303 {
304  block(X,Y) = - ( block(Y,X) = v(Z) );
305  block(Z,X) = - ( block(X,Z) = v(Y) );
306  block(Y,Z) = - ( block(Z,Y) = v(X) );
307 }
308 
309 
310 #undef block33
311 #undef data
312 #undef TPL
313 #undef CLASS
314 }
315 
317 
318 }
319 }
320 
321 
322 #endif /* INERTIAMATRIX_H_ */
Definition: rbd.h:173
#define CLASS
Definition: InertiaMatrix.h:151
void changeRotationalInertia(const Mat33 &tensor)
PlainMatrix< Scalar, 6, 6 > Matrix66
Definition: rbd.h:79
#define data
Definition: InertiaMatrix.h:149
Definition: rbd.h:175
Definition: rbd.h:175
InertiaMatrixDense< SCALAR > & operator+=(const MatrixBase< OtherDerived > &other)
ct::core::ADCodegenLinearizer< state_dim, control_dim >::ADCGScalar Scalar
typename Core< S >::Matrix33 Mat33
Definition: types.h:23
void changeCOM(const Vec3 &newcom)
Definition: InertiaMatrix.h:25
Definition: rbd.h:175
void fill(Scalar m, const Vec3 &com, const Mat33 &tensor)
PlainMatrix< Scalar, 3, 3 > Matrix33
Definition: rbd.h:78
CppAD::AD< CppAD::cg::CG< double > > SCALAR
Definition: rbd.h:175
Eigen::Block< XprType, R, C > MatrixBlock
Definition: rbd.h:57
const Block33_const get3x3Tensor() const
InertiaMatrixDense< SCALAR > & operator=(const MatrixBase< OtherDerived > &other)
Definition: rbd.h:72
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef SCALAR Scalar
Definition: InertiaMatrix.h:30
tpl::InertiaMatrixDense< double > InertiaMatrixDense
Definition: InertiaMatrix.h:316
Eigen::MatrixBase< Derived > MatrixBase
Definition: rbd.h:51
Definition: rbd.h:173
void setSkewSymmetricBlock(const MatrixBase< Vector > &v, Block33_t block)
#define block33
Definition: InertiaMatrix.h:148
Definition: InertiaMatrix.h:142
#define TPL
Definition: InertiaMatrix.h:150
PlainMatrix< Scalar, 3, 1 > Vector3
Definition: rbd.h:80
Definition: rbd.h:173
Definition: rbd.h:175
typename Core< S >::Vector3 Vec3
Definition: types.h:25
Eigen::SparseMatrix< Scalar > SparseMatrix
Definition: rbd.h:60
Definition: rbd.h:175