| Directory: | ./ |
|---|---|
| File: | include/pinocchio/algorithm/center-of-mass.hxx |
| Date: | 2025-02-12 21:03:38 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 211 | 211 | 100.0% |
| Branches: | 182 | 453 | 40.2% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // | ||
| 2 | // Copyright (c) 2015-2020 CNRS INRIA | ||
| 3 | // | ||
| 4 | |||
| 5 | #ifndef __pinocchio_algorithm_center_of_mass_hxx__ | ||
| 6 | #define __pinocchio_algorithm_center_of_mass_hxx__ | ||
| 7 | |||
| 8 | #include "pinocchio/algorithm/check.hpp" | ||
| 9 | #include "pinocchio/multibody/visitor.hpp" | ||
| 10 | #include "pinocchio/algorithm/kinematics.hpp" | ||
| 11 | #include "pinocchio/algorithm/jacobian.hpp" | ||
| 12 | |||
| 13 | /// @cond DEV | ||
| 14 | |||
| 15 | namespace pinocchio | ||
| 16 | { | ||
| 17 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
| 18 | 7 | Scalar computeTotalMass(const ModelTpl<Scalar, Options, JointCollectionTpl> & model) | |
| 19 | { | ||
| 20 | 7 | Scalar m = Scalar(0); | |
| 21 |
2/2✓ Branch 0 taken 178 times.
✓ Branch 1 taken 7 times.
|
185 | for (JointIndex i = 1; i < (JointIndex)(model.njoints); ++i) |
| 22 | { | ||
| 23 |
0/4✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
178 | m += model.inertias[i].mass(); |
| 24 | } | ||
| 25 | 7 | return m; | |
| 26 | } | ||
| 27 | |||
| 28 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
| 29 | 2 | Scalar computeTotalMass( | |
| 30 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 31 | DataTpl<Scalar, Options, JointCollectionTpl> & data) | ||
| 32 | { | ||
| 33 |
0/2✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
2 | data.mass[0] = computeTotalMass(model); |
| 34 | 2 | return data.mass[0]; | |
| 35 | } | ||
| 36 | |||
| 37 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
| 38 | 2 | void computeSubtreeMasses( | |
| 39 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 40 | DataTpl<Scalar, Options, JointCollectionTpl> & data) | ||
| 41 | { | ||
| 42 |
0/2✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
2 | data.mass[0] = Scalar(0); |
| 43 | |||
| 44 | // Forward Step | ||
| 45 |
2/2✓ Branch 0 taken 54 times.
✓ Branch 1 taken 2 times.
|
56 | for (JointIndex i = 1; i < (JointIndex)(model.njoints); ++i) |
| 46 | { | ||
| 47 |
0/2✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
54 | data.mass[i] = model.inertias[i].mass(); |
| 48 | } | ||
| 49 | |||
| 50 | // Backward Step | ||
| 51 |
2/2✓ Branch 0 taken 54 times.
✓ Branch 1 taken 2 times.
|
56 | for (JointIndex i = (JointIndex)(model.njoints - 1); i > 0; --i) |
| 52 | { | ||
| 53 | 54 | const JointIndex & parent = model.parents[i]; | |
| 54 | 54 | data.mass[parent] += data.mass[i]; | |
| 55 | } | ||
| 56 | 2 | } | |
| 57 | namespace impl | ||
| 58 | { | ||
| 59 | template< | ||
| 60 | typename Scalar, | ||
| 61 | int Options, | ||
| 62 | template<typename, int> class JointCollectionTpl, | ||
| 63 | typename ConfigVectorType> | ||
| 64 | 907 | const typename DataTpl<Scalar, Options, JointCollectionTpl>::Vector3 & centerOfMass( | |
| 65 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 66 | DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 67 | const Eigen::MatrixBase<ConfigVectorType> & q, | ||
| 68 | const bool computeSubtreeComs) | ||
| 69 | { | ||
| 70 | 907 | ::pinocchio::impl::forwardKinematics(model, data, q.derived()); | |
| 71 | |||
| 72 | 907 | centerOfMass(model, data, POSITION, computeSubtreeComs); | |
| 73 | 907 | return data.com[0]; | |
| 74 | } | ||
| 75 | |||
| 76 | template< | ||
| 77 | typename Scalar, | ||
| 78 | int Options, | ||
| 79 | template<typename, int> class JointCollectionTpl, | ||
| 80 | typename ConfigVectorType, | ||
| 81 | typename TangentVectorType> | ||
| 82 | 82 | const typename DataTpl<Scalar, Options, JointCollectionTpl>::Vector3 & centerOfMass( | |
| 83 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 84 | DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 85 | const Eigen::MatrixBase<ConfigVectorType> & q, | ||
| 86 | const Eigen::MatrixBase<TangentVectorType> & v, | ||
| 87 | const bool computeSubtreeComs) | ||
| 88 | { | ||
| 89 | 82 | ::pinocchio::impl::forwardKinematics(model, data, q.derived(), v.derived()); | |
| 90 | |||
| 91 | 82 | centerOfMass(model, data, VELOCITY, computeSubtreeComs); | |
| 92 | 82 | return data.com[0]; | |
| 93 | } | ||
| 94 | |||
| 95 | template< | ||
| 96 | typename Scalar, | ||
| 97 | int Options, | ||
| 98 | template<typename, int> class JointCollectionTpl, | ||
| 99 | typename ConfigVectorType, | ||
| 100 | typename TangentVectorType1, | ||
| 101 | typename TangentVectorType2> | ||
| 102 | 6 | const typename DataTpl<Scalar, Options, JointCollectionTpl>::Vector3 & centerOfMass( | |
| 103 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 104 | DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 105 | const Eigen::MatrixBase<ConfigVectorType> & q, | ||
| 106 | const Eigen::MatrixBase<TangentVectorType1> & v, | ||
| 107 | const Eigen::MatrixBase<TangentVectorType2> & a, | ||
| 108 | const bool computeSubtreeComs) | ||
| 109 | { | ||
| 110 | 6 | ::pinocchio::impl::forwardKinematics(model, data, q, v, a); | |
| 111 | |||
| 112 | 6 | centerOfMass(model, data, ACCELERATION, computeSubtreeComs); | |
| 113 | 6 | return data.com[0]; | |
| 114 | } | ||
| 115 | } // namespace impl | ||
| 116 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
| 117 | 1005 | const typename DataTpl<Scalar, Options, JointCollectionTpl>::Vector3 & centerOfMass( | |
| 118 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 119 | DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 120 | KinematicLevel kinematic_level, | ||
| 121 | const bool computeSubtreeComs) | ||
| 122 | { | ||
| 123 |
1/2✓ Branch 1 taken 1005 times.
✗ Branch 2 not taken.
|
1005 | assert(model.check(data) && "data is not consistent with model."); |
| 124 |
2/6✓ Branch 0 taken 1005 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1005 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
1005 | PINOCCHIO_CHECK_INPUT_ARGUMENT(kinematic_level >= 0 && kinematic_level <= 2); |
| 125 | |||
| 126 | typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model; | ||
| 127 | typedef DataTpl<Scalar, Options, JointCollectionTpl> Data; | ||
| 128 | |||
| 129 | typedef typename Model::JointIndex JointIndex; | ||
| 130 | |||
| 131 | typedef typename Data::SE3 SE3; | ||
| 132 | typedef typename Data::Motion Motion; | ||
| 133 | typedef typename Data::Inertia Inertia; | ||
| 134 | |||
| 135 | 1005 | const bool do_position = (kinematic_level >= POSITION); | |
| 136 | 1005 | const bool do_velocity = (kinematic_level >= VELOCITY); | |
| 137 | 1005 | const bool do_acceleration = (kinematic_level >= ACCELERATION); | |
| 138 | |||
| 139 |
0/2✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
1005 | data.mass[0] = 0; |
| 140 |
1/2✓ Branch 0 taken 1005 times.
✗ Branch 1 not taken.
|
1005 | if (do_position) |
| 141 | 1005 | data.com[0].setZero(); | |
| 142 |
2/2✓ Branch 0 taken 97 times.
✓ Branch 1 taken 908 times.
|
1005 | if (do_velocity) |
| 143 | 97 | data.vcom[0].setZero(); | |
| 144 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 991 times.
|
1005 | if (do_acceleration) |
| 145 | 14 | data.acom[0].setZero(); | |
| 146 | |||
| 147 | // Forward Step | ||
| 148 |
2/3✓ Branch 0 taken 27291 times.
✓ Branch 1 taken 1005 times.
✗ Branch 2 not taken.
|
28296 | for (JointIndex i = 1; i < (JointIndex)(model.njoints); ++i) |
| 149 | { | ||
| 150 |
0/2✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
27291 | const typename Inertia::Scalar & mass = model.inertias[i].mass(); |
| 151 | 27291 | const typename SE3::Vector3 & lever = model.inertias[i].lever(); | |
| 152 | |||
| 153 | 27291 | const Motion & v = data.v[i]; | |
| 154 | 27291 | const Motion & a = data.a[i]; | |
| 155 | |||
| 156 |
0/2✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
27291 | data.mass[i] = mass; |
| 157 | |||
| 158 |
1/2✓ Branch 0 taken 27291 times.
✗ Branch 1 not taken.
|
27291 | if (do_position) |
| 159 |
3/6✓ Branch 1 taken 27291 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 27291 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 27291 times.
✗ Branch 9 not taken.
|
27291 | data.com[i].noalias() = mass * lever; |
| 160 | |||
| 161 |
2/2✓ Branch 0 taken 2763 times.
✓ Branch 1 taken 24528 times.
|
27291 | if (do_velocity) |
| 162 |
7/14✓ Branch 1 taken 2763 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2763 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2763 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2763 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2763 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 2763 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 2763 times.
✗ Branch 21 not taken.
|
2763 | data.vcom[i].noalias() = mass * (v.angular().cross(lever) + v.linear()); |
| 163 | |||
| 164 |
2/2✓ Branch 0 taken 379 times.
✓ Branch 1 taken 26912 times.
|
27291 | if (do_acceleration) |
| 165 |
7/14✓ Branch 1 taken 379 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 379 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 379 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 379 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 379 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 379 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 379 times.
✗ Branch 21 not taken.
|
758 | data.acom[i].noalias() = |
| 166 |
2/4✓ Branch 1 taken 379 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 379 times.
✗ Branch 5 not taken.
|
379 | mass * (a.angular().cross(lever) + a.linear()) |
| 167 |
1/2✓ Branch 1 taken 379 times.
✗ Branch 2 not taken.
|
758 | + v.angular().cross( |
| 168 | 379 | data.vcom[i]); // take into accound the coriolis part of the acceleration | |
| 169 | } | ||
| 170 | |||
| 171 | // Backward Step | ||
| 172 |
2/2✓ Branch 0 taken 27291 times.
✓ Branch 1 taken 1005 times.
|
28296 | for (JointIndex i = (JointIndex)(model.njoints - 1); i > 0; --i) |
| 173 | { | ||
| 174 | 27291 | const JointIndex & parent = model.parents[i]; | |
| 175 | 27291 | const SE3 & liMi = data.liMi[i]; | |
| 176 | |||
| 177 | 27291 | data.mass[parent] += data.mass[i]; | |
| 178 | |||
| 179 |
1/2✓ Branch 0 taken 27291 times.
✗ Branch 1 not taken.
|
27291 | if (do_position) |
| 180 |
4/8✓ Branch 5 taken 27291 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 27291 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 27291 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 27291 times.
✗ Branch 16 not taken.
|
27291 | data.com[parent] += (liMi.rotation() * data.com[i] + data.mass[i] * liMi.translation()); |
| 181 | |||
| 182 |
2/2✓ Branch 0 taken 2763 times.
✓ Branch 1 taken 24528 times.
|
27291 | if (do_velocity) |
| 183 |
1/2✓ Branch 5 taken 2763 times.
✗ Branch 6 not taken.
|
2763 | data.vcom[parent] += liMi.rotation() * data.vcom[i]; |
| 184 | |||
| 185 |
2/2✓ Branch 0 taken 379 times.
✓ Branch 1 taken 26912 times.
|
27291 | if (do_acceleration) |
| 186 |
1/2✓ Branch 5 taken 379 times.
✗ Branch 6 not taken.
|
379 | data.acom[parent] += liMi.rotation() * data.acom[i]; |
| 187 | |||
| 188 |
2/2✓ Branch 0 taken 27047 times.
✓ Branch 1 taken 244 times.
|
27291 | if (computeSubtreeComs) |
| 189 | { | ||
| 190 |
1/2✓ Branch 0 taken 27047 times.
✗ Branch 1 not taken.
|
27047 | if (do_position) |
| 191 | 27047 | data.com[i] /= data.mass[i]; | |
| 192 |
2/2✓ Branch 0 taken 2573 times.
✓ Branch 1 taken 24474 times.
|
27047 | if (do_velocity) |
| 193 | 2573 | data.vcom[i] /= data.mass[i]; | |
| 194 |
2/2✓ Branch 0 taken 271 times.
✓ Branch 1 taken 26776 times.
|
27047 | if (do_acceleration) |
| 195 | 271 | data.acom[i] /= data.mass[i]; | |
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 199 |
1/2✓ Branch 0 taken 1005 times.
✗ Branch 1 not taken.
|
1005 | if (do_position) |
| 200 | 1005 | data.com[0] /= data.mass[0]; | |
| 201 |
2/2✓ Branch 0 taken 97 times.
✓ Branch 1 taken 908 times.
|
1005 | if (do_velocity) |
| 202 | 97 | data.vcom[0] /= data.mass[0]; | |
| 203 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 991 times.
|
1005 | if (do_acceleration) |
| 204 | 14 | data.acom[0] /= data.mass[0]; | |
| 205 | |||
| 206 | 1005 | return data.com[0]; | |
| 207 | } | ||
| 208 | |||
| 209 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
| 210 | 1 | const typename DataTpl<Scalar, Options, JointCollectionTpl>::Vector3 & getComFromCrba( | |
| 211 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 212 | DataTpl<Scalar, Options, JointCollectionTpl> & data) | ||
| 213 | { | ||
| 214 | PINOCCHIO_UNUSED_VARIABLE(model); | ||
| 215 | |||
| 216 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | assert(model.check(data) && "data is not consistent with model."); |
| 217 | 1 | return data.com[0] = data.liMi[1].act(data.oYcrb[1].lever()); | |
| 218 | } | ||
| 219 | |||
| 220 | /* --- JACOBIAN ---------------------------------------------------------- */ | ||
| 221 | /* --- JACOBIAN ---------------------------------------------------------- */ | ||
| 222 | /* --- JACOBIAN ---------------------------------------------------------- */ | ||
| 223 | |||
| 224 | template< | ||
| 225 | typename Scalar, | ||
| 226 | int Options, | ||
| 227 | template<typename, int> class JointCollectionTpl, | ||
| 228 | typename Matrix3x> | ||
| 229 | struct JacobianCenterOfMassBackwardStep | ||
| 230 | : public fusion::JointUnaryVisitorBase< | ||
| 231 | JacobianCenterOfMassBackwardStep<Scalar, Options, JointCollectionTpl, Matrix3x>> | ||
| 232 | { | ||
| 233 | typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model; | ||
| 234 | typedef DataTpl<Scalar, Options, JointCollectionTpl> Data; | ||
| 235 | |||
| 236 | typedef boost::fusion:: | ||
| 237 | vector<const Model &, Data &, const Eigen::MatrixBase<Matrix3x> &, const bool &> | ||
| 238 | ArgsType; | ||
| 239 | |||
| 240 | template<typename JointModel> | ||
| 241 | 1194 | static void algo( | |
| 242 | const JointModelBase<JointModel> & jmodel, | ||
| 243 | JointDataBase<typename JointModel::JointDataDerived> & jdata, | ||
| 244 | const Model & model, | ||
| 245 | Data & data, | ||
| 246 | const Eigen::MatrixBase<Matrix3x> & Jcom, | ||
| 247 | const bool & computeSubtreeComs) | ||
| 248 | { | ||
| 249 |
1/2✓ Branch 1 taken 597 times.
✗ Branch 2 not taken.
|
1194 | const JointIndex & i = (JointIndex)jmodel.id(); |
| 250 | 1194 | const JointIndex & parent = model.parents[i]; | |
| 251 | |||
| 252 |
1/2✓ Branch 3 taken 597 times.
✗ Branch 4 not taken.
|
1194 | data.com[parent] += data.com[i]; |
| 253 |
0/2✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
1194 | data.mass[parent] += data.mass[i]; |
| 254 | |||
| 255 | typedef typename Data::Matrix6x Matrix6x; | ||
| 256 | typedef typename SizeDepType<JointModel::NV>::template ColsReturn<Matrix6x>::Type ColBlock; | ||
| 257 | |||
| 258 | 1194 | Matrix3x & Jcom_ = PINOCCHIO_EIGEN_CONST_CAST(Matrix3x, Jcom); | |
| 259 | |||
| 260 |
1/2✓ Branch 1 taken 597 times.
✗ Branch 2 not taken.
|
1194 | ColBlock Jcols = jmodel.jointCols(data.J); |
| 261 |
3/6✓ Branch 2 taken 597 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 597 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 597 times.
✗ Branch 9 not taken.
|
1194 | Jcols = data.oMi[i].act(jdata.S()); |
| 262 | |||
| 263 |
3/4✓ Branch 1 taken 1284 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 687 times.
✓ Branch 4 taken 597 times.
|
2568 | for (Eigen::DenseIndex col_id = 0; col_id < jmodel.nv(); ++col_id) |
| 264 | { | ||
| 265 |
6/12✓ Branch 1 taken 687 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 687 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 687 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 687 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 687 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 687 times.
✗ Branch 17 not taken.
|
2748 | jmodel.jointCols(Jcom_).col(col_id) = |
| 266 |
2/4✓ Branch 1 taken 687 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 687 times.
✗ Branch 5 not taken.
|
1374 | data.mass[i] * Jcols.col(col_id).template segment<3>(Motion::LINEAR) |
| 267 |
2/4✓ Branch 2 taken 687 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 687 times.
✗ Branch 6 not taken.
|
2748 | - data.com[i].cross(Jcols.col(col_id).template segment<3>(Motion::ANGULAR)); |
| 268 | } | ||
| 269 | |||
| 270 |
1/2✓ Branch 0 taken 597 times.
✗ Branch 1 not taken.
|
1194 | if (computeSubtreeComs) |
| 271 |
1/2✓ Branch 3 taken 597 times.
✗ Branch 4 not taken.
|
1194 | data.com[i] /= data.mass[i]; |
| 272 | } | ||
| 273 | }; | ||
| 274 | namespace impl | ||
| 275 | { | ||
| 276 | template< | ||
| 277 | typename Scalar, | ||
| 278 | int Options, | ||
| 279 | template<typename, int> class JointCollectionTpl, | ||
| 280 | typename ConfigVectorType> | ||
| 281 | 10 | const typename DataTpl<Scalar, Options, JointCollectionTpl>::Matrix3x & jacobianCenterOfMass( | |
| 282 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 283 | DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 284 | const Eigen::MatrixBase<ConfigVectorType> & q, | ||
| 285 | const bool computeSubtreeComs) | ||
| 286 | { | ||
| 287 | 10 | ::pinocchio::impl::forwardKinematics(model, data, q); | |
| 288 | 10 | return jacobianCenterOfMass(model, data, computeSubtreeComs); | |
| 289 | } | ||
| 290 | } // namespace impl | ||
| 291 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
| 292 | 12 | const typename DataTpl<Scalar, Options, JointCollectionTpl>::Matrix3x & jacobianCenterOfMass( | |
| 293 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 294 | DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 295 | const bool computeSubtreeComs) | ||
| 296 | { | ||
| 297 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | assert(model.check(data) && "data is not consistent with model."); |
| 298 | |||
| 299 | typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model; | ||
| 300 | typedef DataTpl<Scalar, Options, JointCollectionTpl> Data; | ||
| 301 | |||
| 302 | typedef typename Model::JointIndex JointIndex; | ||
| 303 | |||
| 304 | typedef typename Data::Matrix3x Matrix3x; | ||
| 305 | typedef typename Data::SE3 SE3; | ||
| 306 | typedef typename Data::Inertia Inertia; | ||
| 307 | |||
| 308 | 12 | data.com[0].setZero(); | |
| 309 |
0/2✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
12 | data.mass[0] = Scalar(0); |
| 310 | |||
| 311 |
2/2✓ Branch 0 taken 324 times.
✓ Branch 1 taken 12 times.
|
336 | for (JointIndex i = 1; i < (JointIndex)(model.njoints); ++i) |
| 312 | { | ||
| 313 |
0/2✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
324 | const typename Inertia::Scalar & mass = model.inertias[i].mass(); |
| 314 | 324 | const typename SE3::Vector3 & lever = model.inertias[i].lever(); | |
| 315 | |||
| 316 |
0/2✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
324 | data.mass[i] = mass; |
| 317 |
4/8✓ Branch 2 taken 324 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 324 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 324 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 324 times.
✗ Branch 13 not taken.
|
324 | data.com[i].noalias() = mass * data.oMi[i].act(lever); |
| 318 | } | ||
| 319 | |||
| 320 | // Backward step | ||
| 321 | typedef JacobianCenterOfMassBackwardStep<Scalar, Options, JointCollectionTpl, Matrix3x> Pass2; | ||
| 322 |
2/2✓ Branch 0 taken 324 times.
✓ Branch 1 taken 12 times.
|
336 | for (JointIndex i = (JointIndex)(model.njoints - 1); i > 0; --i) |
| 323 | { | ||
| 324 |
1/2✓ Branch 1 taken 324 times.
✗ Branch 2 not taken.
|
324 | Pass2::run( |
| 325 | 324 | model.joints[i], data.joints[i], | |
| 326 | 648 | typename Pass2::ArgsType(model, data, data.Jcom, computeSubtreeComs)); | |
| 327 | } | ||
| 328 | |||
| 329 | 12 | data.com[0] /= data.mass[0]; | |
| 330 | 12 | data.Jcom /= data.mass[0]; | |
| 331 | |||
| 332 | 12 | return data.Jcom; | |
| 333 | } | ||
| 334 | |||
| 335 | template< | ||
| 336 | typename Scalar, | ||
| 337 | int Options, | ||
| 338 | template<typename, int> class JointCollectionTpl, | ||
| 339 | typename Matrix3x> | ||
| 340 | struct JacobianSubtreeCenterOfMassBackwardStep | ||
| 341 | : public fusion::JointUnaryVisitorBase< | ||
| 342 | JacobianSubtreeCenterOfMassBackwardStep<Scalar, Options, JointCollectionTpl, Matrix3x>> | ||
| 343 | { | ||
| 344 | typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model; | ||
| 345 | typedef DataTpl<Scalar, Options, JointCollectionTpl> Data; | ||
| 346 | |||
| 347 | typedef boost::fusion:: | ||
| 348 | vector<const Model &, Data &, const JointIndex &, const Eigen::MatrixBase<Matrix3x> &> | ||
| 349 | ArgsType; | ||
| 350 | |||
| 351 | template<typename JointModel> | ||
| 352 | 222 | static void algo( | |
| 353 | const JointModelBase<JointModel> & jmodel, | ||
| 354 | JointDataBase<typename JointModel::JointDataDerived> & jdata, | ||
| 355 | const Model & model, | ||
| 356 | Data & data, | ||
| 357 | const JointIndex & subtree_root_id, | ||
| 358 | const Eigen::MatrixBase<Matrix3x> & Jcom) | ||
| 359 | { | ||
| 360 | PINOCCHIO_UNUSED_VARIABLE(model); | ||
| 361 | |||
| 362 |
1/2✓ Branch 1 taken 111 times.
✗ Branch 2 not taken.
|
222 | const JointIndex & i = (JointIndex)jmodel.id(); |
| 363 | |||
| 364 | typedef typename Data::Matrix6x Matrix6x; | ||
| 365 | typedef typename SizeDepType<JointModel::NV>::template ColsReturn<Matrix6x>::Type ColBlock; | ||
| 366 | |||
| 367 | 222 | Matrix3x & Jcom_ = PINOCCHIO_EIGEN_CONST_CAST(Matrix3x, Jcom); | |
| 368 | |||
| 369 |
1/2✓ Branch 1 taken 111 times.
✗ Branch 2 not taken.
|
222 | ColBlock Jcols = jmodel.jointCols(data.J); |
| 370 |
3/6✓ Branch 2 taken 111 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 111 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 111 times.
✗ Branch 9 not taken.
|
222 | Jcols = data.oMi[i].act(jdata.S()); |
| 371 | |||
| 372 |
3/4✓ Branch 1 taken 352 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 241 times.
✓ Branch 4 taken 111 times.
|
704 | for (Eigen::DenseIndex col_id = 0; col_id < jmodel.nv(); ++col_id) |
| 373 | { | ||
| 374 |
5/10✓ Branch 1 taken 241 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 241 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 241 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 241 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 241 times.
✗ Branch 14 not taken.
|
964 | jmodel.jointCols(Jcom_).col(col_id) = |
| 375 |
2/4✓ Branch 1 taken 241 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 241 times.
✗ Branch 5 not taken.
|
482 | Jcols.col(col_id).template segment<3>(Motion::LINEAR) |
| 376 |
2/4✓ Branch 2 taken 241 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 241 times.
✗ Branch 6 not taken.
|
964 | - data.com[subtree_root_id].cross(Jcols.col(col_id).template segment<3>(Motion::ANGULAR)); |
| 377 | } | ||
| 378 | } | ||
| 379 | }; | ||
| 380 | namespace impl | ||
| 381 | { | ||
| 382 | template< | ||
| 383 | typename Scalar, | ||
| 384 | int Options, | ||
| 385 | template<typename, int> class JointCollectionTpl, | ||
| 386 | typename ConfigVectorType, | ||
| 387 | typename Matrix3xLike> | ||
| 388 | 3 | void jacobianSubtreeCenterOfMass( | |
| 389 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 390 | DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 391 | const Eigen::MatrixBase<ConfigVectorType> & q, | ||
| 392 | const JointIndex & rootSubtreeId, | ||
| 393 | const Eigen::MatrixBase<Matrix3xLike> & res) | ||
| 394 | { | ||
| 395 | 3 | ::pinocchio::impl::forwardKinematics(model, data, q); | |
| 396 | 3 | ::pinocchio::jacobianSubtreeCenterOfMass(model, data, rootSubtreeId, res); | |
| 397 | 3 | } | |
| 398 | |||
| 399 | template< | ||
| 400 | typename Scalar, | ||
| 401 | int Options, | ||
| 402 | template<typename, int> class JointCollectionTpl, | ||
| 403 | typename Matrix3xLike> | ||
| 404 | 32 | void jacobianSubtreeCenterOfMass( | |
| 405 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 406 | DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 407 | const JointIndex & rootSubtreeId, | ||
| 408 | const Eigen::MatrixBase<Matrix3xLike> & res) | ||
| 409 | { | ||
| 410 | typedef DataTpl<Scalar, Options, JointCollectionTpl> Data; | ||
| 411 | typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model; | ||
| 412 | |||
| 413 |
2/4✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 32 times.
✗ Branch 4 not taken.
|
32 | assert(model.check(data) && "data is not consistent with model."); |
| 414 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
32 | PINOCCHIO_CHECK_INPUT_ARGUMENT((int)rootSubtreeId < model.njoints, "Invalid joint id."); |
| 415 |
1/24✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
|
32 | PINOCCHIO_CHECK_ARGUMENT_SIZE( |
| 416 | res.rows(), 3, "the resulting matrix does not have the right size."); | ||
| 417 |
1/24✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
|
32 | PINOCCHIO_CHECK_ARGUMENT_SIZE( |
| 418 | res.cols(), model.nv, "the resulting matrix does not have the right size."); | ||
| 419 | |||
| 420 | 32 | Matrix3xLike & Jcom_subtree = PINOCCHIO_EIGEN_CONST_CAST(Matrix3xLike, res); | |
| 421 | |||
| 422 | typedef typename Data::SE3 SE3; | ||
| 423 | typedef typename Data::Inertia Inertia; | ||
| 424 | |||
| 425 | typedef typename Model::IndexVector IndexVector; | ||
| 426 | 32 | const IndexVector & subtree = model.subtrees[rootSubtreeId]; | |
| 427 | |||
| 428 | 32 | const bool computeSubtreeComs = true; | |
| 429 | |||
| 430 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 27 times.
|
32 | if (rootSubtreeId == 0) |
| 431 | { | ||
| 432 |
0/4✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
5 | data.mass[0] = 0; |
| 433 |
1/2✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
|
5 | data.com[0].setZero(); |
| 434 | } | ||
| 435 | |||
| 436 |
2/2✓ Branch 1 taken 273 times.
✓ Branch 2 taken 32 times.
|
305 | for (size_t k = 0; k < subtree.size(); ++k) |
| 437 | { | ||
| 438 | 273 | const JointIndex joint_id = subtree[k]; | |
| 439 |
0/2✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
273 | const typename Inertia::Scalar & mass = model.inertias[joint_id].mass(); |
| 440 | 273 | const typename SE3::Vector3 & lever = model.inertias[joint_id].lever(); | |
| 441 | |||
| 442 |
0/2✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
273 | data.mass[joint_id] = mass; |
| 443 |
3/6✓ Branch 2 taken 273 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 273 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 273 times.
✗ Branch 10 not taken.
|
273 | data.com[joint_id] = mass * data.oMi[joint_id].act(lever); |
| 444 | } | ||
| 445 | |||
| 446 | // Backward step | ||
| 447 | typedef JacobianCenterOfMassBackwardStep<Scalar, Options, JointCollectionTpl, Matrix3xLike> | ||
| 448 | Pass2; | ||
| 449 |
2/2✓ Branch 1 taken 273 times.
✓ Branch 2 taken 32 times.
|
305 | for (Eigen::DenseIndex k = (Eigen::DenseIndex)subtree.size() - 1; k >= 0; --k) |
| 450 | { | ||
| 451 | 273 | const JointIndex joint_id = subtree[(size_t)k]; | |
| 452 |
1/2✓ Branch 1 taken 273 times.
✗ Branch 2 not taken.
|
273 | Pass2::run( |
| 453 | 273 | model.joints[joint_id], data.joints[joint_id], | |
| 454 |
1/2✓ Branch 1 taken 273 times.
✗ Branch 2 not taken.
|
546 | typename Pass2::ArgsType(model, data, Jcom_subtree, computeSubtreeComs)); |
| 455 | } | ||
| 456 | |||
| 457 |
2/12✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 32 times.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
|
32 | PINOCCHIO_CHECK_INPUT_ARGUMENT( |
| 458 | check_expression_if_real<Scalar>(data.mass[rootSubtreeId] > 0.), | ||
| 459 | "The mass of the subtree is not positive."); | ||
| 460 |
0/4✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
32 | const Scalar mass_inv_subtree = Scalar(1) / data.mass[rootSubtreeId]; |
| 461 | 32 | typename Data::Vector3 & com_subtree = data.com[rootSubtreeId]; | |
| 462 | if (!computeSubtreeComs) | ||
| 463 | com_subtree *= mass_inv_subtree; | ||
| 464 | |||
| 465 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 27 times.
|
32 | if (rootSubtreeId == 0) |
| 466 | { | ||
| 467 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | Jcom_subtree *= mass_inv_subtree; |
| 468 | 5 | return; // skip the rest | |
| 469 | } | ||
| 470 | |||
| 471 |
1/2✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
|
27 | const int idx_v = model.joints[rootSubtreeId].idx_v(); |
| 472 | 27 | const int nv_subtree = data.nvSubtree[rootSubtreeId]; | |
| 473 | |||
| 474 |
2/4✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 27 times.
✗ Branch 5 not taken.
|
27 | Jcom_subtree.middleCols(idx_v, nv_subtree) *= mass_inv_subtree; |
| 475 | |||
| 476 | // Second backward step | ||
| 477 | typedef JacobianSubtreeCenterOfMassBackwardStep< | ||
| 478 | Scalar, Options, JointCollectionTpl, Matrix3xLike> | ||
| 479 | Pass3; | ||
| 480 |
2/2✓ Branch 1 taken 111 times.
✓ Branch 2 taken 27 times.
|
138 | for (JointIndex parent = model.parents[rootSubtreeId]; parent > 0; |
| 481 | 111 | parent = model.parents[parent]) | |
| 482 | { | ||
| 483 |
1/2✓ Branch 1 taken 111 times.
✗ Branch 2 not taken.
|
111 | Pass3::run( |
| 484 | 111 | model.joints[parent], data.joints[parent], | |
| 485 |
1/2✓ Branch 1 taken 111 times.
✗ Branch 2 not taken.
|
222 | typename Pass3::ArgsType(model, data, rootSubtreeId, Jcom_subtree)); |
| 486 | } | ||
| 487 | } | ||
| 488 | |||
| 489 | template< | ||
| 490 | typename Scalar, | ||
| 491 | int Options, | ||
| 492 | template<typename, int> class JointCollectionTpl, | ||
| 493 | typename Matrix3xLike> | ||
| 494 | 29 | void getJacobianSubtreeCenterOfMass( | |
| 495 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 496 | const DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 497 | const JointIndex & rootSubtreeId, | ||
| 498 | const Eigen::MatrixBase<Matrix3xLike> & res) | ||
| 499 | { | ||
| 500 | typedef DataTpl<Scalar, Options, JointCollectionTpl> Data; | ||
| 501 | |||
| 502 |
2/4✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 29 times.
✗ Branch 4 not taken.
|
29 | assert(model.check(data) && "data is not consistent with model."); |
| 503 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
29 | PINOCCHIO_CHECK_INPUT_ARGUMENT(((int)rootSubtreeId < model.njoints), "Invalid joint id."); |
| 504 |
1/24✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
|
29 | PINOCCHIO_CHECK_ARGUMENT_SIZE( |
| 505 | res.rows(), 3, "the resulting matrix does not have the right size."); | ||
| 506 |
1/24✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
|
29 | PINOCCHIO_CHECK_ARGUMENT_SIZE( |
| 507 | res.cols(), model.nv, "the resulting matrix does not have the right size."); | ||
| 508 | |||
| 509 | 29 | Matrix3xLike & Jcom_subtree = PINOCCHIO_EIGEN_CONST_CAST(Matrix3xLike, res); | |
| 510 | |||
| 511 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 27 times.
|
29 | if (rootSubtreeId == 0) |
| 512 | { | ||
| 513 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | Jcom_subtree = data.Jcom; |
| 514 | 2 | return; | |
| 515 | } | ||
| 516 | |||
| 517 |
1/2✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
|
27 | const int idx_v = model.joints[rootSubtreeId].idx_v(); |
| 518 | 27 | const int nv_subtree = data.nvSubtree[rootSubtreeId]; | |
| 519 | |||
| 520 |
0/2✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
27 | const Scalar mass_ratio = data.mass[0] / data.mass[rootSubtreeId]; |
| 521 |
3/6✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 27 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 27 times.
✗ Branch 8 not taken.
|
27 | Jcom_subtree.middleCols(idx_v, nv_subtree) = |
| 522 |
1/2✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
|
27 | mass_ratio * data.Jcom.middleCols(idx_v, nv_subtree); |
| 523 | |||
| 524 | 27 | const typename Data::Vector3 & com_subtree = data.com[rootSubtreeId]; | |
| 525 | |||
| 526 |
2/2✓ Branch 1 taken 241 times.
✓ Branch 2 taken 27 times.
|
268 | for (int parent = data.parents_fromRow[(size_t)idx_v]; parent >= 0; |
| 527 | 241 | parent = data.parents_fromRow[(size_t)parent]) | |
| 528 | { | ||
| 529 |
1/2✓ Branch 1 taken 241 times.
✗ Branch 2 not taken.
|
241 | typename Data::Matrix6x::ConstColXpr Jcol = data.J.col(parent); |
| 530 |
5/10✓ Branch 1 taken 241 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 241 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 241 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 241 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 241 times.
✗ Branch 14 not taken.
|
482 | Jcom_subtree.col(parent).noalias() = |
| 531 |
1/2✓ Branch 1 taken 241 times.
✗ Branch 2 not taken.
|
241 | Jcol.template segment<3>(Motion::LINEAR) |
| 532 |
1/2✓ Branch 1 taken 241 times.
✗ Branch 2 not taken.
|
482 | - com_subtree.cross(Jcol.template segment<3>(Motion::ANGULAR)); |
| 533 | } | ||
| 534 | } | ||
| 535 | } // namespace impl | ||
| 536 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
| 537 | 7 | const typename DataTpl<Scalar, Options, JointCollectionTpl>::Matrix3x & getJacobianComFromCrba( | |
| 538 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 539 | DataTpl<Scalar, Options, JointCollectionTpl> & data) | ||
| 540 | { | ||
| 541 | PINOCCHIO_UNUSED_VARIABLE(model); | ||
| 542 |
1/2✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
7 | assert(model.check(data) && "data is not consistent with model."); |
| 543 | |||
| 544 | // Extract the total mass of the system. | ||
| 545 | 7 | data.mass[0] = data.oYcrb[0].mass(); | |
| 546 | 7 | data.com[0] = data.oYcrb[0].lever(); | |
| 547 | |||
| 548 |
3/6✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 7 times.
✗ Branch 10 not taken.
|
7 | data.Jcom.noalias() = data.Ag.template middleRows<3>(Force::LINEAR) / data.mass[0]; |
| 549 | |||
| 550 | 7 | return data.Jcom; | |
| 551 | } | ||
| 552 | |||
| 553 | template< | ||
| 554 | typename Scalar, | ||
| 555 | int Options, | ||
| 556 | template<typename, int> class JointCollectionTpl, | ||
| 557 | typename ConfigVectorType> | ||
| 558 | 907 | const typename DataTpl<Scalar, Options, JointCollectionTpl>::Vector3 & centerOfMass( | |
| 559 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 560 | DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 561 | const Eigen::MatrixBase<ConfigVectorType> & q, | ||
| 562 | const bool computeSubtreeComs) | ||
| 563 | { | ||
| 564 |
1/2✓ Branch 2 taken 907 times.
✗ Branch 3 not taken.
|
907 | return impl::centerOfMass(model, data, make_const_ref(q), computeSubtreeComs); |
| 565 | } | ||
| 566 | |||
| 567 | template< | ||
| 568 | typename Scalar, | ||
| 569 | int Options, | ||
| 570 | template<typename, int> class JointCollectionTpl, | ||
| 571 | typename ConfigVectorType, | ||
| 572 | typename TangentVectorType> | ||
| 573 | 82 | const typename DataTpl<Scalar, Options, JointCollectionTpl>::Vector3 & centerOfMass( | |
| 574 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 575 | DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 576 | const Eigen::MatrixBase<ConfigVectorType> & q, | ||
| 577 | const Eigen::MatrixBase<TangentVectorType> & v, | ||
| 578 | const bool computeSubtreeComs) | ||
| 579 | { | ||
| 580 |
2/4✓ Branch 2 taken 82 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 82 times.
✗ Branch 6 not taken.
|
164 | return impl::centerOfMass( |
| 581 | 164 | model, data, make_const_ref(q), make_const_ref(v), computeSubtreeComs); | |
| 582 | } | ||
| 583 | |||
| 584 | template< | ||
| 585 | typename Scalar, | ||
| 586 | int Options, | ||
| 587 | template<typename, int> class JointCollectionTpl, | ||
| 588 | typename ConfigVectorType, | ||
| 589 | typename TangentVectorType1, | ||
| 590 | typename TangentVectorType2> | ||
| 591 | 6 | const typename DataTpl<Scalar, Options, JointCollectionTpl>::Vector3 & centerOfMass( | |
| 592 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 593 | DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 594 | const Eigen::MatrixBase<ConfigVectorType> & q, | ||
| 595 | const Eigen::MatrixBase<TangentVectorType1> & v, | ||
| 596 | const Eigen::MatrixBase<TangentVectorType2> & a, | ||
| 597 | const bool computeSubtreeComs) | ||
| 598 | { | ||
| 599 |
3/6✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
|
12 | return impl::centerOfMass( |
| 600 | 12 | model, data, make_const_ref(q), make_const_ref(v), make_const_ref(a), computeSubtreeComs); | |
| 601 | } | ||
| 602 | |||
| 603 | template< | ||
| 604 | typename Scalar, | ||
| 605 | int Options, | ||
| 606 | template<typename, int> class JointCollectionTpl, | ||
| 607 | typename ConfigVectorType> | ||
| 608 | 10 | const typename DataTpl<Scalar, Options, JointCollectionTpl>::Matrix3x & jacobianCenterOfMass( | |
| 609 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 610 | DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 611 | const Eigen::MatrixBase<ConfigVectorType> & q, | ||
| 612 | const bool computeSubtreeComs) | ||
| 613 | { | ||
| 614 |
1/2✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
|
10 | return impl::jacobianCenterOfMass(model, data, make_const_ref(q), computeSubtreeComs); |
| 615 | } | ||
| 616 | |||
| 617 | template< | ||
| 618 | typename Scalar, | ||
| 619 | int Options, | ||
| 620 | template<typename, int> class JointCollectionTpl, | ||
| 621 | typename ConfigVectorType, | ||
| 622 | typename Matrix3xLike> | ||
| 623 | 3 | void jacobianSubtreeCenterOfMass( | |
| 624 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 625 | DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 626 | const Eigen::MatrixBase<ConfigVectorType> & q, | ||
| 627 | const JointIndex & rootSubtreeId, | ||
| 628 | const Eigen::MatrixBase<Matrix3xLike> & res) | ||
| 629 | { | ||
| 630 |
2/4✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
|
3 | impl::jacobianSubtreeCenterOfMass(model, data, make_const_ref(q), rootSubtreeId, make_ref(res)); |
| 631 | 3 | } | |
| 632 | |||
| 633 | template< | ||
| 634 | typename Scalar, | ||
| 635 | int Options, | ||
| 636 | template<typename, int> class JointCollectionTpl, | ||
| 637 | typename Matrix3xLike> | ||
| 638 | 32 | void jacobianSubtreeCenterOfMass( | |
| 639 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 640 | DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 641 | const JointIndex & rootSubtreeId, | ||
| 642 | const Eigen::MatrixBase<Matrix3xLike> & res) | ||
| 643 | { | ||
| 644 |
1/2✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
|
32 | impl::jacobianSubtreeCenterOfMass(model, data, rootSubtreeId, make_ref(res)); |
| 645 | 32 | } | |
| 646 | |||
| 647 | template< | ||
| 648 | typename Scalar, | ||
| 649 | int Options, | ||
| 650 | template<typename, int> class JointCollectionTpl, | ||
| 651 | typename Matrix3xLike> | ||
| 652 | 29 | void getJacobianSubtreeCenterOfMass( | |
| 653 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 654 | const DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 655 | const JointIndex & rootSubtreeId, | ||
| 656 | const Eigen::MatrixBase<Matrix3xLike> & res) | ||
| 657 | { | ||
| 658 |
1/2✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
|
29 | impl::getJacobianSubtreeCenterOfMass(model, data, rootSubtreeId, make_ref(res)); |
| 659 | 29 | } | |
| 660 | |||
| 661 | } // namespace pinocchio | ||
| 662 | |||
| 663 | /// @endcond | ||
| 664 | |||
| 665 | #endif // ifndef __pinocchio_algorithm_center_of_mass_hxx__ | ||
| 666 |