10 #ifndef SPATIAL_DYN_EIGEN_SPATIAL_INERTIA_H_
11 #define SPATIAL_DYN_EIGEN_SPATIAL_INERTIA_H_
13 #include "spatial_motion_base.h"
14 #include "spatial_force_base.h"
20 template<
typename Scalar>
28 : mass(other.mass), com(other.com), I_com(other.I_com) {}
31 : mass(other.mass), com(std::move(other.com)), I_com(std::move(other.I_com)) {}
33 template<
typename ComDerived,
typename IComDerived>
35 const Eigen::MatrixBase<ComDerived>& com,
36 const Eigen::MatrixBase<IComDerived>& I_com_flat);
42 template<
typename OtherDerived>
44 typedef typename Eigen::ScalarBinaryOpTraits<Scalar,
49 template<
typename OtherDerived>
63 Eigen::Matrix<Scalar,6,1> I_com_flat()
const;
66 Eigen::Matrix<Scalar,3,1> com = Eigen::Matrix<Scalar,3,1>::Zero();
67 Eigen::Matrix<Scalar,3,3> I_com = Eigen::Matrix<Scalar,3,3>::Zero();
71 template<
typename Scalar>
79 template<
typename OtherDerived>
81 : Eigen::Matrix<Scalar,6,6>(other) {};
83 template<
typename OtherDerived>
85 : Eigen::Matrix<Scalar,6,6>(std::move(other)) {};
87 template<
typename OtherDerived>
89 typedef typename Eigen::ScalarBinaryOpTraits<Scalar,
94 template<
typename OtherDerived>
100 template<
typename OtherDerived>
106 template<
typename TransformScalar,
int Dim,
typename Scalar>
109 static_assert(Dim == 3,
"YOU_CAN_ONLY_APPLY_3D_TRANSFORMS_TO_SPATIAL_INERTIAS");
112 result.mass = I.mass;
113 result.com = T.translation() + I.com;
114 result.I_com = I.I_com;
118 template<
typename TransformScalar,
int Dim,
int Mode,
int Options,
typename Scalar>
119 inline SpatialInertia<Scalar>
120 operator*(
const Eigen::Transform<TransformScalar, Dim, Mode, Options>& T,
const SpatialInertia<Scalar>& I) {
121 static_assert(Dim == 3,
"YOU_CAN_ONLY_APPLY_3D_TRANSFORMS_TO_SPATIAL_INERTIAS");
122 static_assert(Mode ==
int(Eigen::Isometry),
123 "YOU_CAN_ONLY_APPLY_ISOMETRY_TRANSFORMS_TO_SPATIAL_INERTIAS");
125 SpatialInertia<Scalar> result;
126 result.mass = I.mass;
127 result.com = T * I.com;
128 result.I_com = T.linear() * I.I_com * T.linear().transpose();
132 template<
typename TransformScalar,
int Dim,
typename Scalar>
133 SpatialInertiaMatrix<Scalar>
134 operator*(
const Eigen::Translation<TransformScalar, Dim>& T,
const SpatialInertiaMatrix<Scalar>& I) {
135 static_assert(Dim == 3,
"YOU_CAN_ONLY_APPLY_3D_TRANSFORMS_TO_SPATIAL_INERTIAS");
137 SpatialInertiaMatrix<Scalar> result = I;
138 result.template rightCols<3>() -= result.template leftCols<3>().rowwise().cross(T.translation());
139 result.template bottomRows<3>() -= result.template topRows<3>().colwise().cross(T.translation());
143 template<
typename TransformScalar,
int Dim,
int Mode,
int Options,
typename Scalar>
144 SpatialInertiaMatrix<Scalar>
145 operator*(
const Eigen::Transform<TransformScalar, Dim, Mode, Options>& T,
146 const SpatialInertiaMatrix<Scalar>& I) {
147 static_assert(Dim == 3,
"YOU_CAN_ONLY_APPLY_3D_TRANSFORMS_TO_SPATIAL_INERTIAS");
148 static_assert(Mode ==
int(Eigen::Isometry),
149 "YOU_CAN_ONLY_APPLY_ISOMETRY_TRANSFORMS_TO_SPATIAL_INERTIAS");
151 SpatialInertiaMatrix<Scalar> result = I;
152 result.template leftCols<3>() = result.template leftCols<3>() * T.linear().transpose();
153 result.template rightCols<3>() = result.template rightCols<3>() * T.linear().transpose() -
154 result.template leftCols<3>().rowwise().cross(T.translation());
155 result.template topRows<3>() = T.linear() * result.template topRows<3>();
156 result.template bottomRows<3>() = T.linear() * result.template bottomRows<3>() -
157 result.template topRows<3>().colwise().cross(T.translation());
161 template<
typename Scalar>
162 template<
typename ComDerived,
typename IComDerived>
163 inline SpatialInertia<Scalar>::SpatialInertia(Scalar m,
164 const Eigen::MatrixBase<ComDerived>& c,
165 const Eigen::MatrixBase<IComDerived>& I) : mass(m), com(c) {
166 static_assert(ComDerived::RowsAtCompileTime == 3 && ComDerived::ColsAtCompileTime == 1,
167 "COM_MUST_BE_A_VECTOR_OF_SIZE_3");
168 static_assert(IComDerived::RowsAtCompileTime == 6 && ComDerived::ColsAtCompileTime == 1,
169 "I_COM_MUST_BE_A_VECTOR_OF_SIZE_6");
171 I_com << I(0), I(3), I(4),
176 template<
typename Scalar>
177 inline SpatialInertia<Scalar>&
178 SpatialInertia<Scalar>::operator=(
const SpatialInertia<Scalar>& other) {
185 template<
typename Scalar>
186 inline SpatialInertia<Scalar>&
187 SpatialInertia<Scalar>::operator=(SpatialInertia<Scalar>&& other) {
189 com = std::move(other.com);
190 I_com = std::move(other.I_com);
194 template<
typename Scalar>
195 template<
typename OtherDerived>
196 typename SpatialInertia<Scalar>::template MotionProductTraits<OtherDerived>::ReturnType
197 SpatialInertia<Scalar>::operator*(
const SpatialMotionBase<OtherDerived>& other)
const {
198 typename MotionProductTraits<OtherDerived>::ReturnType result;
199 Eigen::Matrix<Scalar,3,1> mc = mass * com;
200 result.template topRows<3>() = mass * other.matrix().template topRows<3>() +
201 other.matrix().template bottomRows<3>().cross(mc);
202 result.template bottomRows<3>() = I_com * other.matrix().template bottomRows<3>() -
203 other.matrix().template topRows<3>().cross(mc) -
204 other.matrix().template bottomRows<3>().cross(com).cross(mc);
208 template<
typename Scalar>
209 SpatialInertia<Scalar>&
210 SpatialInertia<Scalar>::operator+=(
const SpatialInertia<Scalar>& other) {
211 Eigen::Vector3d com_new = (mass * com + other.mass * other.com) / (mass + other.mass);
212 I_com += other.I_com -
213 mass * ctrl_utils::DoubleCrossMatrix(com_new - com) -
214 other.mass * ctrl_utils::DoubleCrossMatrix(com_new - other.com);
216 com = std::move(com_new);
220 template<
typename Scalar>
221 SpatialInertia<Scalar>
222 SpatialInertia<Scalar>::operator+(
const SpatialInertia<Scalar>& other)
const {
223 SpatialInertia<Scalar> I_total;
224 I_total.com = (mass * com + other.mass * other.com) / (mass + other.mass);
225 I_total.I_com = I_com + other.I_com -
226 mass * ctrl_utils::DoubleCrossMatrix(I_total.com - com) -
227 other.mass * ctrl_utils::DoubleCrossMatrix(I_total.com - other.com);
228 I_total.mass = mass + other.mass;
232 template<
typename Scalar>
233 inline bool SpatialInertia<Scalar>::operator==(
const SpatialInertia<Scalar>& other)
const {
234 return mass == other.mass && com == other.com && I_com == other.I_com;
237 template<
typename Scalar>
238 inline bool SpatialInertia<Scalar>::operator!=(
const SpatialInertia<Scalar>& other)
const {
239 return !(*
this == other);
242 template<
typename Scalar>
243 SpatialInertiaMatrix<Scalar> SpatialInertia<Scalar>::matrix()
const {
244 const double mcx = mass * com(0);
245 const double mcy = mass * com(1);
246 const double mcz = mass * com(2);
247 const double Imcxx = I_com(0,0) + mass * (com(1) * com(1) + com(2) * com(2));
248 const double Imcyy = I_com(1,1) + mass * (com(0) * com(0) + com(2) * com(2));
249 const double Imczz = I_com(2,2) + mass * (com(0) * com(0) + com(1) * com(1));
250 const double Imcxy = I_com(0,1) - mass * com(0) * com(1);
251 const double Imcxz = I_com(0,2) - mass * com(0) * com(2);
252 const double Imcyz = I_com(1,2) - mass * com(1) * com(2);
253 SpatialInertiaMatrix<Scalar> result;
254 result << mass, 0, 0, 0, mcz, -mcy,
255 0, mass, 0, -mcz, 0, mcx,
256 0, 0, mass, mcy, -mcx, 0,
257 0, -mcz, mcy, Imcxx, Imcxy, Imcxz,
258 mcz, 0, -mcx, Imcxy, Imcyy, Imcyz,
259 -mcy, mcx, 0, Imcxz, Imcyz, Imczz;
263 template<
typename Scalar>
264 inline Eigen::Matrix<Scalar,6,1> SpatialInertia<Scalar>::I_com_flat()
const {
265 Eigen::Matrix<Scalar,6,1> result;
266 result << I_com(0,0), I_com(1,1), I_com(2,2), I_com(0,1), I_com(0,2), I_com(1,2);
270 template<
typename Scalar>
271 inline SpatialInertiaMatrix<Scalar>::SpatialInertiaMatrix(
const SpatialInertia<Scalar>& other) {
272 const double& mass = other.mass;
273 const Eigen::Matrix<Scalar,3,1>& com = other.com;
274 const Eigen::Matrix<Scalar,3,3>& I_com = other.I_com;
275 const double mcx = mass * com(0);
276 const double mcy = mass * com(1);
277 const double mcz = mass * com(2);
278 const double Imcxx = I_com(0,0) + mass * (com(1) * com(1) + com(2) * com(2));
279 const double Imcyy = I_com(1,1) + mass * (com(0) * com(0) + com(2) * com(2));
280 const double Imczz = I_com(2,2) + mass * (com(0) * com(0) + com(1) * com(1));
281 const double Imcxy = I_com(0,1) - mass * com(0) * com(1);
282 const double Imcxz = I_com(0,2) - mass * com(0) * com(2);
283 const double Imcyz = I_com(1,2) - mass * com(1) * com(2);
284 *
this << mass, 0, 0, 0, mcz, -mcy,
285 0, mass, 0, -mcz, 0, mcx,
286 0, 0, mass, mcy, -mcx, 0,
287 0, -mcz, mcy, Imcxx, Imcxy, Imcxz,
288 mcz, 0, -mcx, Imcxy, Imcyy, Imcyz,
289 -mcy, mcx, 0, Imcxz, Imcyz, Imczz;
292 template<
typename Scalar>
293 template<
typename OtherDerived>
294 inline typename SpatialInertiaMatrix<Scalar>::template MotionProductTraits<OtherDerived>::ReturnType
295 SpatialInertiaMatrix<Scalar>::operator*(
const SpatialMotionBase<OtherDerived>& other)
const {
296 return Eigen::Matrix<Scalar,6,6>::operator*(other.matrix());
299 template<
typename Scalar>
300 inline SpatialInertiaMatrix<Scalar>&
301 SpatialInertiaMatrix<Scalar>::operator+=(
const SpatialInertia<Scalar>& other) {
302 *
this += other.matrix();
306 template<
typename Scalar>
307 template<
typename OtherDerived>
308 inline SpatialInertiaMatrix<Scalar>&
309 SpatialInertiaMatrix<Scalar>::operator+=(
const Eigen::MatrixBase<OtherDerived>& other) {
310 Eigen::Matrix<Scalar,6,6>::operator+=(other);
Definition: spatial_force.h:18
Definition: spatial_inertia.h:72
Definition: spatial_inertia.h:21
Definition: spatial_motion_base.h:18
Definition: discrete_dynamics.cc:21
Definition: spatial_inertia.h:88
Definition: spatial_inertia.h:43