| Line | Branch | Exec | Source | 
    
      | 1 |  |  | #ifndef __quadruped_walkgen_quadruped_augmented_hxx__ | 
    
      | 2 |  |  | #define __quadruped_walkgen_quadruped_augmented_hxx__ | 
    
      | 3 |  |  |  | 
    
      | 4 |  |  | #include "crocoddyl/core/utils/exception.hpp" | 
    
      | 5 |  |  |  | 
    
      | 6 |  |  | namespace quadruped_walkgen { | 
    
      | 7 |  |  | template <typename Scalar> | 
    
      | 8 |  | ✗ | ActionModelQuadrupedAugmentedTpl<Scalar>::ActionModelQuadrupedAugmentedTpl( | 
    
      | 9 |  |  | typename Eigen::Matrix<Scalar, 3, 1> offset_CoM) | 
    
      | 10 |  |  | : crocoddyl::ActionModelAbstractTpl<Scalar>( | 
    
      | 11 |  | ✗ | boost::make_shared<crocoddyl::StateVectorTpl<Scalar> >(20), 12, 32) { | 
    
      | 12 |  |  | // Relative forces to compute the norm mof the command | 
    
      | 13 |  | ✗ | relative_forces = true; | 
    
      | 14 |  | ✗ | uref_.setZero(); | 
    
      | 15 |  |  |  | 
    
      | 16 |  |  | // Model parameters | 
    
      | 17 |  | ✗ | mu = Scalar(1); | 
    
      | 18 |  | ✗ | dt_ = Scalar(0.02); | 
    
      | 19 |  | ✗ | mass = Scalar(2.50000279); | 
    
      | 20 |  | ✗ | min_fz_in_contact = Scalar(0.0); | 
    
      | 21 |  | ✗ | max_fz_in_contact = Scalar(25.0); | 
    
      | 22 |  |  |  | 
    
      | 23 |  |  | // Matrix model initialization | 
    
      | 24 |  | ✗ | g.setZero(); | 
    
      | 25 |  | ✗ | g[8] = Scalar(-9.81) * dt_; | 
    
      | 26 |  | ✗ | gI.setZero(); | 
    
      | 27 |  | ✗ | gI.diagonal() << Scalar(0.00578574), Scalar(0.01938108), Scalar(0.02476124); | 
    
      | 28 |  | ✗ | A.setIdentity(); | 
    
      | 29 |  | ✗ | A.topRightCorner(6, 6) << Eigen::Matrix<Scalar, 6, 6>::Identity() * dt_; | 
    
      | 30 |  | ✗ | B.setZero(); | 
    
      | 31 |  | ✗ | lever_arms.setZero(); | 
    
      | 32 |  | ✗ | R.setZero(); | 
    
      | 33 |  |  |  | 
    
      | 34 |  |  | // Weight vectors initialization | 
    
      | 35 |  | ✗ | force_weights_.setConstant(Scalar(0.2)); | 
    
      | 36 |  | ✗ | state_weights_ << Scalar(1.), Scalar(1.), Scalar(150.), Scalar(35.), | 
    
      | 37 |  | ✗ | Scalar(30.), Scalar(8.), Scalar(20.), Scalar(20.), Scalar(15.), | 
    
      | 38 |  | ✗ | Scalar(4.), Scalar(4.), Scalar(8.); | 
    
      | 39 |  | ✗ | friction_weight_ = Scalar(10); | 
    
      | 40 |  | ✗ | heuristic_weights_.setConstant(Scalar(1)); | 
    
      | 41 |  | ✗ | stop_weights_.setConstant(Scalar(1)); | 
    
      | 42 |  |  | // pshoulder_ << Scalar(0.1946), Scalar(0.15005), Scalar(0.1946), | 
    
      | 43 |  |  | // Scalar(-0.15005), Scalar(-0.1946), Scalar(0.15005), | 
    
      | 44 |  |  | //     Scalar(-0.1946), Scalar(-0.15005); | 
    
      | 45 |  | ✗ | pshoulder_0 << Scalar(0.18), Scalar(0.18), Scalar(-0.21), Scalar(-0.21), | 
    
      | 46 |  | ✗ | Scalar(0.14695), Scalar(-0.14695), Scalar(0.14695), Scalar(-0.14695); | 
    
      | 47 |  |  | // pshoulder_tmp.setZero(); | 
    
      | 48 |  |  | // pcentrifugal_tmp_1.setZero(); | 
    
      | 49 |  |  | // pcentrifugal_tmp_2.setZero(); | 
    
      | 50 |  |  | // pcentrifugal_tmp.setZero(); | 
    
      | 51 |  |  | // UpperBound vector | 
    
      | 52 |  | ✗ | ub.setZero(); | 
    
      | 53 |  | ✗ | for (int i = 0; i < 4; i = i + 1) { | 
    
      | 54 |  | ✗ | ub(6 * i + 5) = max_fz_in_contact; | 
    
      | 55 |  |  | } | 
    
      | 56 |  |  |  | 
    
      | 57 |  |  | // Temporary vector used | 
    
      | 58 |  | ✗ | Fa_x_u.setZero(); | 
    
      | 59 |  | ✗ | rub_.setZero(); | 
    
      | 60 |  | ✗ | rub_max_.setZero(); | 
    
      | 61 |  | ✗ | Arr.setZero(); | 
    
      | 62 |  | ✗ | r.setZero(); | 
    
      | 63 |  | ✗ | lever_tmp.setZero(); | 
    
      | 64 |  | ✗ | R_tmp.setZero(); | 
    
      | 65 |  | ✗ | gait.setZero(); | 
    
      | 66 |  | ✗ | base_vector_x << Scalar(1.), Scalar(0.), Scalar(0.); | 
    
      | 67 |  | ✗ | base_vector_y << Scalar(0.), Scalar(1.), Scalar(0.); | 
    
      | 68 |  | ✗ | base_vector_z << Scalar(0.), Scalar(0.), Scalar(1.); | 
    
      | 69 |  | ✗ | forces_3d.setZero(); | 
    
      | 70 |  | ✗ | gait_double.setZero(); | 
    
      | 71 |  |  |  | 
    
      | 72 |  |  | // bool to add heuristic for foot position | 
    
      | 73 |  | ✗ | centrifugal_term = true; | 
    
      | 74 |  | ✗ | symmetry_term = true; | 
    
      | 75 |  | ✗ | T_gait = Scalar(0.48); | 
    
      | 76 |  |  |  | 
    
      | 77 |  |  | // // Used for shoulder height weight | 
    
      | 78 |  |  | // pshoulder_0 <<  Scalar(0.1946) ,   Scalar(0.1946) ,   Scalar(-0.1946), | 
    
      | 79 |  |  | // Scalar(-0.1946) , | 
    
      | 80 |  |  | //                 Scalar(0.15005) ,  Scalar(-0.15005)  , Scalar(0.15005)  , | 
    
      | 81 |  |  | //                 Scalar(-0.15005) ; | 
    
      | 82 |  | ✗ | sh_hlim = Scalar(0.27); | 
    
      | 83 |  | ✗ | sh_weight.setConstant(Scalar(1.)); | 
    
      | 84 |  | ✗ | sh_ub_max_.setZero(); | 
    
      | 85 |  | ✗ | psh.setZero(); | 
    
      | 86 |  | ✗ | pheuristic_.setZero(); | 
    
      | 87 |  | ✗ | offset_com = offset_CoM;  // x, y, z offset | 
    
      | 88 |  |  |  | 
    
      | 89 |  | ✗ | shoulder_reference_position = false;  // Using predicted trajectory of the CoM | 
    
      | 90 |  |  | } | 
    
      | 91 |  |  |  | 
    
      | 92 |  |  | template <typename Scalar> | 
    
      | 93 |  | ✗ | ActionModelQuadrupedAugmentedTpl<Scalar>::~ActionModelQuadrupedAugmentedTpl() {} | 
    
      | 94 |  |  |  | 
    
      | 95 |  |  | template <typename Scalar> | 
    
      | 96 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::calc( | 
    
      | 97 |  |  | const boost::shared_ptr<crocoddyl::ActionDataAbstractTpl<Scalar> >& data, | 
    
      | 98 |  |  | const Eigen::Ref<const typename MathBase::VectorXs>& x, | 
    
      | 99 |  |  | const Eigen::Ref<const typename MathBase::VectorXs>& u) { | 
    
      | 100 |  | ✗ | if (static_cast<std::size_t>(x.size()) != state_->get_nx()) { | 
    
      | 101 |  | ✗ | throw_pretty("Invalid argument: " | 
    
      | 102 |  |  | << "x has wrong dimension (it should be " + | 
    
      | 103 |  |  | std::to_string(state_->get_nx()) + ")"); | 
    
      | 104 |  |  | } | 
    
      | 105 |  | ✗ | if (static_cast<std::size_t>(u.size()) != nu_) { | 
    
      | 106 |  | ✗ | throw_pretty("Invalid argument: " | 
    
      | 107 |  |  | << "u has wrong dimension (it should be " + | 
    
      | 108 |  |  | std::to_string(nu_) + ")"); | 
    
      | 109 |  |  | } | 
    
      | 110 |  |  |  | 
    
      | 111 |  |  | ActionDataQuadrupedAugmentedTpl<Scalar>* d = | 
    
      | 112 |  | ✗ | static_cast<ActionDataQuadrupedAugmentedTpl<Scalar>*>(data.get()); | 
    
      | 113 |  |  |  | 
    
      | 114 |  |  | //  Update B : | 
    
      | 115 |  | ✗ | for (int i = 0; i < 4; i = i + 1) { | 
    
      | 116 |  | ✗ | lever_tmp.setZero(); | 
    
      | 117 |  | ✗ | if (gait(i, 0) != 0) { | 
    
      | 118 |  | ✗ | lever_tmp.head(2) = x.block(12 + 2 * i, 0, 2, 1); | 
    
      | 119 |  | ✗ | lever_tmp += -x.block(0, 0, 3, 1); | 
    
      | 120 |  | ✗ | R_tmp << Scalar(0.0), -lever_tmp[2], lever_tmp[1], lever_tmp[2], | 
    
      | 121 |  | ✗ | Scalar(0.0), -lever_tmp[0], -lever_tmp[1], lever_tmp[0], Scalar(0.0); | 
    
      | 122 |  | ✗ | B.block(9, 3 * i, 3, 3) << dt_ * R * R_tmp; | 
    
      | 123 |  |  |  | 
    
      | 124 |  |  | // Compute pdistance of the shoulder wrt contact point | 
    
      | 125 |  | ✗ | if (shoulder_reference_position) { | 
    
      | 126 |  |  | // Ref vector as reference for the shoulder trajectory, roll and pitch | 
    
      | 127 |  |  | // at first | 
    
      | 128 |  | ✗ | psh.block(0, i, 3, 1) << xref_(0, 0) - offset_com(0, 0) + | 
    
      | 129 |  | ✗ | pshoulder_0(0, i) * cos(xref_(5, 0)) - | 
    
      | 130 |  | ✗ | pshoulder_0(1, i) * sin(xref_(5, 0)) - | 
    
      | 131 |  | ✗ | x(12 + 2 * i), | 
    
      | 132 |  | ✗ | xref_(1, 0) - offset_com(1, 0) + | 
    
      | 133 |  | ✗ | pshoulder_0(0, i) * sin(xref_(5, 0)) + | 
    
      | 134 |  | ✗ | pshoulder_0(1, i) * cos(xref_(5, 0)) - x(12 + 2 * i + 1), | 
    
      | 135 |  | ✗ | xref_(2, 0) - offset_com(2, 0); | 
    
      | 136 |  |  | } else { | 
    
      | 137 |  |  | // psh.block(0, i, 3, 1) << x(0) + pshoulder_0(0, i) - pshoulder_0(1, i) | 
    
      | 138 |  |  | // * x(5) - x(12 + 2 * i), | 
    
      | 139 |  |  | //                          x(1) + pshoulder_0(1, i) + pshoulder_0(0, i) | 
    
      | 140 |  |  | //                          * x(5) - x(12 + 2 * i + 1), x(2) - | 
    
      | 141 |  |  | //                          offset_com + pshoulder_0(1, i) * x(3) - | 
    
      | 142 |  |  | //                          pshoulder_0(0, i) * x(4); | 
    
      | 143 |  |  | // Correction, no approximation for yaw | 
    
      | 144 |  | ✗ | psh.block(0, i, 3, 1) | 
    
      | 145 |  | ✗ | << x(0) - offset_com(0, 0) + pshoulder_0(0, i) * cos(x(5)) - | 
    
      | 146 |  | ✗ | pshoulder_0(1, i) * sin(x(5)) - x(12 + 2 * i), | 
    
      | 147 |  | ✗ | x(1) - offset_com(1, 0) + pshoulder_0(0, i) * sin(x(5)) + | 
    
      | 148 |  | ✗ | pshoulder_0(1, i) * cos(x(5)) - x(12 + 2 * i + 1), | 
    
      | 149 |  | ✗ | x(2) - offset_com(2, 0) + pshoulder_0(1, i) * x(3) - | 
    
      | 150 |  | ✗ | pshoulder_0(0, i) * x(4); | 
    
      | 151 |  |  | } | 
    
      | 152 |  |  |  | 
    
      | 153 |  |  | } else { | 
    
      | 154 |  |  | // Compute pdistance of the shoulder wrt contact point | 
    
      | 155 |  | ✗ | psh.block(0, i, 3, 1).setZero(); | 
    
      | 156 |  |  | } | 
    
      | 157 |  |  | }; | 
    
      | 158 |  |  |  | 
    
      | 159 |  |  | // Discrete dynamic : A*x + B*u + g | 
    
      | 160 |  | ✗ | d->xnext.template head<12>() = | 
    
      | 161 |  | ✗ | A.diagonal().cwiseProduct(x.block(0, 0, 12, 1)) + g; | 
    
      | 162 |  | ✗ | d->xnext.template head<6>() = | 
    
      | 163 |  | ✗ | d->xnext.template head<6>() + | 
    
      | 164 |  | ✗ | A.topRightCorner(6, 6).diagonal().cwiseProduct(x.block(6, 0, 6, 1)); | 
    
      | 165 |  | ✗ | d->xnext.template segment<6>(6) = | 
    
      | 166 |  | ✗ | d->xnext.template segment<6>(6) + B.block(6, 0, 6, 12) * u; | 
    
      | 167 |  | ✗ | d->xnext.template tail<8>() = x.tail(8); | 
    
      | 168 |  |  |  | 
    
      | 169 |  |  | // Residual cost on the state and force norm | 
    
      | 170 |  | ✗ | d->r.template head<12>() = state_weights_.cwiseProduct(x.head(12) - xref_); | 
    
      | 171 |  | ✗ | d->r.template segment<8>(12) = | 
    
      | 172 |  | ✗ | ((heuristic_weights_.cwiseProduct(x.tail(8) - pheuristic_)).array() * | 
    
      | 173 |  | ✗ | gait_double.array()) | 
    
      | 174 |  |  | .matrix(); | 
    
      | 175 |  | ✗ | d->r.template tail<12>() = force_weights_.cwiseProduct(u - uref_); | 
    
      | 176 |  |  |  | 
    
      | 177 |  |  | // Friction cone | 
    
      | 178 |  | ✗ | for (int i = 0; i < 4; i = i + 1) { | 
    
      | 179 |  | ✗ | Fa_x_u.segment(6 * i, 6) << u(3 * i) - mu * u(3 * i + 2), | 
    
      | 180 |  | ✗ | -u(3 * i) - mu * u(3 * i + 2), u(3 * i + 1) - mu * u(3 * i + 2), | 
    
      | 181 |  | ✗ | -u(3 * i + 1) - mu * u(3 * i + 2), -u(3 * i + 2), u(3 * i + 2); | 
    
      | 182 |  |  | } | 
    
      | 183 |  | ✗ | rub_max_ = (Fa_x_u - ub).cwiseMax(Scalar(0.)); | 
    
      | 184 |  |  |  | 
    
      | 185 |  |  | // Shoulder height weight | 
    
      | 186 |  | ✗ | sh_ub_max_ << Scalar(0.5) * sh_weight(0) * | 
    
      | 187 |  | ✗ | (psh.block(0, 0, 3, 1).squaredNorm() - sh_hlim * sh_hlim), | 
    
      | 188 |  | ✗ | Scalar(0.5) * sh_weight(1) * | 
    
      | 189 |  | ✗ | (psh.block(0, 1, 3, 1).squaredNorm() - sh_hlim * sh_hlim), | 
    
      | 190 |  | ✗ | Scalar(0.5) * sh_weight(2) * | 
    
      | 191 |  | ✗ | (psh.block(0, 2, 3, 1).squaredNorm() - sh_hlim * sh_hlim), | 
    
      | 192 |  | ✗ | Scalar(0.5) * sh_weight(3) * | 
    
      | 193 |  | ✗ | (psh.block(0, 3, 3, 1).squaredNorm() - sh_hlim * sh_hlim); | 
    
      | 194 |  |  |  | 
    
      | 195 |  | ✗ | sh_ub_max_ = sh_ub_max_.cwiseMax(Scalar(0.)); | 
    
      | 196 |  |  |  | 
    
      | 197 |  |  | // Cost computation | 
    
      | 198 |  |  | // d->cost = Scalar(0.5) * d->r.transpose() * d->r     + friction_weight_ * | 
    
      | 199 |  |  | // Scalar(0.5) * rub_max_.squaredNorm() | 
    
      | 200 |  |  | //         + Scalar(0.5)*( (stop_weights_.cwiseProduct(x.tail(8) - pref_) | 
    
      | 201 |  |  | //         ).array() * gait_double.array() | 
    
      | 202 |  |  | //         ).matrix().squaredNorm()  ; | 
    
      | 203 |  |  |  | 
    
      | 204 |  | ✗ | d->cost = | 
    
      | 205 |  | ✗ | Scalar(0.5) * d->r.transpose() * d->r + | 
    
      | 206 |  | ✗ | friction_weight_ * Scalar(0.5) * rub_max_.squaredNorm() + | 
    
      | 207 |  | ✗ | Scalar(0.5) * ((stop_weights_.cwiseProduct(x.tail(8) - pstop_)).array() * | 
    
      | 208 |  | ✗ | gait_double.array()) | 
    
      | 209 |  |  | .matrix() | 
    
      | 210 |  | ✗ | .squaredNorm() + | 
    
      | 211 |  | ✗ | sh_ub_max_.sum(); | 
    
      | 212 |  |  | } | 
    
      | 213 |  |  |  | 
    
      | 214 |  |  | template <typename Scalar> | 
    
      | 215 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::calcDiff( | 
    
      | 216 |  |  | const boost::shared_ptr<crocoddyl::ActionDataAbstractTpl<Scalar> >& data, | 
    
      | 217 |  |  | const Eigen::Ref<const typename MathBase::VectorXs>& x, | 
    
      | 218 |  |  | const Eigen::Ref<const typename MathBase::VectorXs>& u) { | 
    
      | 219 |  | ✗ | if (static_cast<std::size_t>(x.size()) != state_->get_nx()) { | 
    
      | 220 |  | ✗ | throw_pretty("Invalid argument: " | 
    
      | 221 |  |  | << "x has wrong dimension (it should be " + | 
    
      | 222 |  |  | std::to_string(state_->get_nx()) + ")"); | 
    
      | 223 |  |  | } | 
    
      | 224 |  | ✗ | if (static_cast<std::size_t>(u.size()) != nu_) { | 
    
      | 225 |  | ✗ | throw_pretty("Invalid argument: " | 
    
      | 226 |  |  | << "u has wrong dimension (it should be " + | 
    
      | 227 |  |  | std::to_string(nu_) + ")"); | 
    
      | 228 |  |  | } | 
    
      | 229 |  |  |  | 
    
      | 230 |  |  | ActionDataQuadrupedAugmentedTpl<Scalar>* d = | 
    
      | 231 |  | ✗ | static_cast<ActionDataQuadrupedAugmentedTpl<Scalar>*>(data.get()); | 
    
      | 232 |  |  |  | 
    
      | 233 |  |  | // Cost derivatives : Lx | 
    
      | 234 |  | ✗ | d->Lx.setZero(); | 
    
      | 235 |  | ✗ | d->Lx.template head<12>() = | 
    
      | 236 |  | ✗ | (state_weights_.array() * d->r.template head<12>().array()).matrix(); | 
    
      | 237 |  | ✗ | d->Lx.template tail<8>() = | 
    
      | 238 |  | ✗ | (heuristic_weights_.array() * d->r.template segment<8>(12).array()) | 
    
      | 239 |  |  | .matrix() + | 
    
      | 240 |  | ✗ | ((stop_weights_.cwiseProduct(x.tail(8) - pstop_)).array() * | 
    
      | 241 |  | ✗ | gait_double.array() * stop_weights_.array()) | 
    
      | 242 |  |  | .matrix(); | 
    
      | 243 |  |  |  | 
    
      | 244 |  |  | // Cost derivative : Lu | 
    
      | 245 |  | ✗ | for (int i = 0; i < 4; i = i + 1) { | 
    
      | 246 |  | ✗ | r = friction_weight_ * rub_max_.segment(6 * i, 6); | 
    
      | 247 |  | ✗ | d->Lu.block(i * 3, 0, 3, 1) << r(0) - r(1), r(2) - r(3), | 
    
      | 248 |  | ✗ | -mu * (r(0) + r(1) + r(2) + r(3)) - r(4) + r(5); | 
    
      | 249 |  |  | } | 
    
      | 250 |  | ✗ | d->Lu = d->Lu + | 
    
      | 251 |  | ✗ | (force_weights_.array() * d->r.template tail<12>().array()).matrix(); | 
    
      | 252 |  |  |  | 
    
      | 253 |  |  | // Hessian : Lxx | 
    
      | 254 |  |  | // Hessian : Lxx | 
    
      | 255 |  | ✗ | d->Lxx.setZero(); | 
    
      | 256 |  |  |  | 
    
      | 257 |  | ✗ | d->Lxx.diagonal().head(12) = | 
    
      | 258 |  | ✗ | (state_weights_.array() * state_weights_.array()).matrix(); | 
    
      | 259 |  | ✗ | d->Lxx.diagonal().tail(8) = | 
    
      | 260 |  | ✗ | (gait_double.array() * heuristic_weights_.array() * | 
    
      | 261 |  | ✗ | heuristic_weights_.array()) | 
    
      | 262 |  |  | .matrix(); | 
    
      | 263 |  | ✗ | d->Lxx.diagonal().tail(8) += | 
    
      | 264 |  | ✗ | (gait_double.array() * stop_weights_.array() * stop_weights_.array()) | 
    
      | 265 |  |  | .matrix(); | 
    
      | 266 |  |  |  | 
    
      | 267 |  |  | // Shoulder height derivative cost | 
    
      | 268 |  | ✗ | for (int j = 0; j < 4; j = j + 1) { | 
    
      | 269 |  | ✗ | if (sh_ub_max_[j] > Scalar(0.)) { | 
    
      | 270 |  | ✗ | if (shoulder_reference_position) { | 
    
      | 271 |  | ✗ | d->Lx(12 + 2 * j, 0) += -sh_weight(j) * psh(0, j); | 
    
      | 272 |  | ✗ | d->Lx(12 + 2 * j + 1, 0) += -sh_weight(j) * psh(1, j); | 
    
      | 273 |  |  |  | 
    
      | 274 |  | ✗ | d->Lxx(12 + 2 * j, 12 + 2 * j) += sh_weight(j); | 
    
      | 275 |  | ✗ | d->Lxx(12 + 2 * j + 1, 12 + 2 * j + 1) += sh_weight(j); | 
    
      | 276 |  |  |  | 
    
      | 277 |  |  | } else { | 
    
      | 278 |  |  | // Approximation of small even for yaw (wrong) | 
    
      | 279 |  |  | // d->Lx(0, 0) += sh_weight(j) * psh(0, j); | 
    
      | 280 |  |  | // d->Lx(1, 0) += sh_weight(j) * psh(1, j); | 
    
      | 281 |  |  | // d->Lx(2, 0) += sh_weight(j) * psh(2, j); | 
    
      | 282 |  |  | // d->Lx(3, 0) += sh_weight(j) * pshoulder_0(1, j) * psh(2, j); | 
    
      | 283 |  |  | // d->Lx(4, 0) += -sh_weight(j) * pshoulder_0(0, j) * psh(2, j); | 
    
      | 284 |  |  | // d->Lx(5, 0) += sh_weight(j) * (-pshoulder_0(1, j) * psh(0, j) + | 
    
      | 285 |  |  | // pshoulder_0(0, j) * psh(1, j)); | 
    
      | 286 |  |  |  | 
    
      | 287 |  |  | // d->Lx(12 + 2 * j, 0) += -sh_weight(j) * psh(0, j); | 
    
      | 288 |  |  | // d->Lx(12 + 2 * j + 1, 0) += -sh_weight(j) * psh(1, j); | 
    
      | 289 |  |  |  | 
    
      | 290 |  |  | // d->Lxx(0, 0) += sh_weight(j); | 
    
      | 291 |  |  | // d->Lxx(1, 1) += sh_weight(j); | 
    
      | 292 |  |  | // d->Lxx(2, 2) += sh_weight(j); | 
    
      | 293 |  |  | // d->Lxx(3, 3) += sh_weight(j) * pshoulder_0(1, j) * pshoulder_0(1, j); | 
    
      | 294 |  |  | // d->Lxx(3, 3) += sh_weight(j) * pshoulder_0(0, j) * pshoulder_0(0, j); | 
    
      | 295 |  |  | // d->Lxx(5, 5) += sh_weight(j) * (pshoulder_0(1, j) * pshoulder_0(1, j) | 
    
      | 296 |  |  | // + pshoulder_0(0, j) * pshoulder_0(0, j)); | 
    
      | 297 |  |  |  | 
    
      | 298 |  |  | // d->Lxx(12 + 2 * j, 12 + 2 * j) += sh_weight(j); | 
    
      | 299 |  |  | // d->Lxx(12 + 2 * j + 1, 12 + 2 * j + 1) += sh_weight(j); | 
    
      | 300 |  |  |  | 
    
      | 301 |  |  | // d->Lxx(0, 5) += -sh_weight(j) * pshoulder_0(1, j); | 
    
      | 302 |  |  | // d->Lxx(5, 0) += -sh_weight(j) * pshoulder_0(1, j); | 
    
      | 303 |  |  |  | 
    
      | 304 |  |  | // d->Lxx(1, 5) += sh_weight(j) * pshoulder_0(0, j); | 
    
      | 305 |  |  | // d->Lxx(5, 1) += sh_weight(j) * pshoulder_0(0, j); | 
    
      | 306 |  |  |  | 
    
      | 307 |  |  | // d->Lxx(2, 3) += sh_weight(j) * pshoulder_0(1, j); | 
    
      | 308 |  |  | // d->Lxx(2, 4) += -sh_weight(j) * pshoulder_0(0, j); | 
    
      | 309 |  |  | // d->Lxx(3, 2) += sh_weight(j) * pshoulder_0(1, j); | 
    
      | 310 |  |  | // d->Lxx(4, 2) += -sh_weight(j) * pshoulder_0(0, j); | 
    
      | 311 |  |  |  | 
    
      | 312 |  |  | // d->Lxx(3, 4) += -sh_weight(j) * pshoulder_0(1, j) * pshoulder_0(0, | 
    
      | 313 |  |  | // j); d->Lxx(4, 3) += -sh_weight(j) * pshoulder_0(1, j) * | 
    
      | 314 |  |  | // pshoulder_0(0, j); | 
    
      | 315 |  |  |  | 
    
      | 316 |  |  | // d->Lxx(0, 12 + 2 * j) += -sh_weight(j); | 
    
      | 317 |  |  | // d->Lxx(12 + 2 * j, 0) += -sh_weight(j); | 
    
      | 318 |  |  |  | 
    
      | 319 |  |  | // d->Lxx(5, 12 + 2 * j) += sh_weight(j) * pshoulder_0(1, j); | 
    
      | 320 |  |  | // d->Lxx(12 + 2 * j, 5) += sh_weight(j) * pshoulder_0(1, j); | 
    
      | 321 |  |  |  | 
    
      | 322 |  |  | // d->Lxx(1, 12 + 2 * j + 1) += -sh_weight(j); | 
    
      | 323 |  |  | // d->Lxx(12 + 2 * j + 1, 1) += -sh_weight(j); | 
    
      | 324 |  |  |  | 
    
      | 325 |  |  | // d->Lxx(5, 12 + 2 * j + 1) += -sh_weight(j) * pshoulder_0(0, j); | 
    
      | 326 |  |  | // d->Lxx(12 + 2 * j + 1, 5) += -sh_weight(j) * pshoulder_0(0, j); | 
    
      | 327 |  | ✗ | d->Lx(0, 0) += sh_weight(j) * psh(0, j); | 
    
      | 328 |  | ✗ | d->Lx(1, 0) += sh_weight(j) * psh(1, j); | 
    
      | 329 |  | ✗ | d->Lx(2, 0) += sh_weight(j) * psh(2, j); | 
    
      | 330 |  | ✗ | d->Lx(3, 0) += sh_weight(j) * pshoulder_0(1, j) * psh(2, j); | 
    
      | 331 |  | ✗ | d->Lx(4, 0) += -sh_weight(j) * pshoulder_0(0, j) * psh(2, j); | 
    
      | 332 |  | ✗ | d->Lx(5, 0) += | 
    
      | 333 |  | ✗ | sh_weight(j) * | 
    
      | 334 |  | ✗ | ((-sin(x(5)) * pshoulder_0(0, j) - cos(x(5)) * pshoulder_0(1, j)) * | 
    
      | 335 |  | ✗ | psh(0, j) + | 
    
      | 336 |  | ✗ | (cos(x(5)) * pshoulder_0(0, j) - sin(x(5)) * pshoulder_0(1, j)) * | 
    
      | 337 |  | ✗ | psh(1, j)); | 
    
      | 338 |  |  |  | 
    
      | 339 |  | ✗ | d->Lx(12 + 2 * j, 0) += -sh_weight(j) * psh(0, j); | 
    
      | 340 |  | ✗ | d->Lx(12 + 2 * j + 1, 0) += -sh_weight(j) * psh(1, j); | 
    
      | 341 |  |  |  | 
    
      | 342 |  | ✗ | d->Lxx(0, 0) += sh_weight(j); | 
    
      | 343 |  | ✗ | d->Lxx(1, 1) += sh_weight(j); | 
    
      | 344 |  | ✗ | d->Lxx(2, 2) += sh_weight(j); | 
    
      | 345 |  | ✗ | d->Lxx(3, 3) += sh_weight(j) * pshoulder_0(1, j) * pshoulder_0(1, j); | 
    
      | 346 |  | ✗ | d->Lxx(3, 3) += sh_weight(j) * pshoulder_0(0, j) * pshoulder_0(0, j); | 
    
      | 347 |  | ✗ | d->Lxx(5, 5) += | 
    
      | 348 |  | ✗ | sh_weight(j) * | 
    
      | 349 |  | ✗ | ((-cos(x(5)) * pshoulder_0(0, j) + sin(x(5)) * pshoulder_0(1, j)) * | 
    
      | 350 |  | ✗ | psh(0, j) + | 
    
      | 351 |  | ✗ | (-sin(x(5)) * pshoulder_0(0, j) - cos(x(5)) * pshoulder_0(1, j)) * | 
    
      | 352 |  | ✗ | (-sin(x(5)) * pshoulder_0(0, j) - | 
    
      | 353 |  | ✗ | cos(x(5)) * pshoulder_0(1, j)) + | 
    
      | 354 |  | ✗ | (-sin(x(5)) * pshoulder_0(0, j) - cos(x(5)) * pshoulder_0(1, j)) * | 
    
      | 355 |  | ✗ | psh(1, j) + | 
    
      | 356 |  | ✗ | (cos(x(5)) * pshoulder_0(0, j) - sin(x(5)) * pshoulder_0(1, j)) * | 
    
      | 357 |  | ✗ | (cos(x(5)) * pshoulder_0(0, j) - | 
    
      | 358 |  | ✗ | sin(x(5)) * pshoulder_0(1, j))); | 
    
      | 359 |  |  |  | 
    
      | 360 |  | ✗ | d->Lxx(12 + 2 * j, 12 + 2 * j) += sh_weight(j); | 
    
      | 361 |  | ✗ | d->Lxx(12 + 2 * j + 1, 12 + 2 * j + 1) += sh_weight(j); | 
    
      | 362 |  |  |  | 
    
      | 363 |  | ✗ | d->Lxx(0, 5) += sh_weight(j) * (-sin(x(5)) * pshoulder_0(0, j) - | 
    
      | 364 |  | ✗ | cos(x(5)) * pshoulder_0(1, j)); | 
    
      | 365 |  | ✗ | d->Lxx(5, 0) += sh_weight(j) * (-sin(x(5)) * pshoulder_0(0, j) - | 
    
      | 366 |  | ✗ | cos(x(5)) * pshoulder_0(1, j)); | 
    
      | 367 |  |  |  | 
    
      | 368 |  | ✗ | d->Lxx(1, 5) += sh_weight(j) * (cos(x(5)) * pshoulder_0(0, j) - | 
    
      | 369 |  | ✗ | sin(x(5)) * pshoulder_0(1, j)); | 
    
      | 370 |  | ✗ | d->Lxx(5, 1) += sh_weight(j) * (cos(x(5)) * pshoulder_0(0, j) - | 
    
      | 371 |  | ✗ | sin(x(5)) * pshoulder_0(1, j)); | 
    
      | 372 |  |  |  | 
    
      | 373 |  | ✗ | d->Lxx(2, 3) += sh_weight(j) * pshoulder_0(1, j); | 
    
      | 374 |  | ✗ | d->Lxx(2, 4) += -sh_weight(j) * pshoulder_0(0, j); | 
    
      | 375 |  | ✗ | d->Lxx(3, 2) += sh_weight(j) * pshoulder_0(1, j); | 
    
      | 376 |  | ✗ | d->Lxx(4, 2) += -sh_weight(j) * pshoulder_0(0, j); | 
    
      | 377 |  |  |  | 
    
      | 378 |  | ✗ | d->Lxx(3, 4) += -sh_weight(j) * pshoulder_0(1, j) * pshoulder_0(0, j); | 
    
      | 379 |  | ✗ | d->Lxx(4, 3) += -sh_weight(j) * pshoulder_0(1, j) * pshoulder_0(0, j); | 
    
      | 380 |  |  |  | 
    
      | 381 |  | ✗ | d->Lxx(0, 12 + 2 * j) += -sh_weight(j); | 
    
      | 382 |  | ✗ | d->Lxx(12 + 2 * j, 0) += -sh_weight(j); | 
    
      | 383 |  |  |  | 
    
      | 384 |  | ✗ | d->Lxx(5, 12 + 2 * j) += | 
    
      | 385 |  | ✗ | -sh_weight(j) * | 
    
      | 386 |  | ✗ | (-sin(x(5)) * pshoulder_0(0, j) - cos(x(5)) * pshoulder_0(1, j)); | 
    
      | 387 |  | ✗ | d->Lxx(12 + 2 * j, 5) += | 
    
      | 388 |  | ✗ | -sh_weight(j) * | 
    
      | 389 |  | ✗ | (-sin(x(5)) * pshoulder_0(0, j) - cos(x(5)) * pshoulder_0(1, j)); | 
    
      | 390 |  |  |  | 
    
      | 391 |  | ✗ | d->Lxx(1, 12 + 2 * j + 1) += -sh_weight(j); | 
    
      | 392 |  | ✗ | d->Lxx(12 + 2 * j + 1, 1) += -sh_weight(j); | 
    
      | 393 |  |  |  | 
    
      | 394 |  | ✗ | d->Lxx(5, 12 + 2 * j + 1) += | 
    
      | 395 |  | ✗ | -sh_weight(j) * | 
    
      | 396 |  | ✗ | (cos(x(5)) * pshoulder_0(0, j) - sin(x(5)) * pshoulder_0(1, j)); | 
    
      | 397 |  | ✗ | d->Lxx(12 + 2 * j + 1, 5) += | 
    
      | 398 |  | ✗ | -sh_weight(j) * | 
    
      | 399 |  | ✗ | (cos(x(5)) * pshoulder_0(0, j) - sin(x(5)) * pshoulder_0(1, j)); | 
    
      | 400 |  |  | } | 
    
      | 401 |  |  | } | 
    
      | 402 |  |  | } | 
    
      | 403 |  |  |  | 
    
      | 404 |  |  | // Hessian : Luu | 
    
      | 405 |  |  | // Matrix friction cone hessian (20x12) | 
    
      | 406 |  | ✗ | Arr.diagonal() = | 
    
      | 407 |  | ✗ | ((Fa_x_u - ub).array() >= 0.).matrix().template cast<Scalar>(); | 
    
      | 408 |  | ✗ | for (int i = 0; i < 4; i = i + 1) { | 
    
      | 409 |  | ✗ | r = friction_weight_ * Arr.diagonal().segment(6 * i, 6); | 
    
      | 410 |  | ✗ | d->Luu.block(3 * i, 3 * i, 3, 3) << r(0) + r(1), 0.0, mu * (r(1) - r(0)), | 
    
      | 411 |  | ✗ | 0.0, r(2) + r(3), mu * (r(3) - r(2)), mu * (r(1) - r(0)), | 
    
      | 412 |  | ✗ | mu * (r(3) - r(2)), mu * mu * (r(0) + r(1) + r(2) + r(3)) + r(4) + r(5); | 
    
      | 413 |  |  | } | 
    
      | 414 |  | ✗ | d->Luu.diagonal() = | 
    
      | 415 |  | ✗ | d->Luu.diagonal() + | 
    
      | 416 |  | ✗ | (force_weights_.array() * force_weights_.array()).matrix(); | 
    
      | 417 |  |  |  | 
    
      | 418 |  |  | // Dynamic derivatives | 
    
      | 419 |  | ✗ | d->Fx.setZero(); | 
    
      | 420 |  | ✗ | d->Fx.block(0, 0, 12, 12) << A; | 
    
      | 421 |  | ✗ | d->Fx.block(12, 12, 8, 8) << Eigen::Matrix<Scalar, 8, 8>::Identity(); | 
    
      | 422 |  |  |  | 
    
      | 423 |  | ✗ | for (int i = 0; i < 4; i = i + 1) { | 
    
      | 424 |  | ✗ | if (gait(i, 0) != 0) { | 
    
      | 425 |  | ✗ | forces_3d = u.block(3 * i, 0, 3, 1); | 
    
      | 426 |  | ✗ | d->Fx.block(9, 0, 3, 1) += -dt_ * R * (base_vector_x.cross(forces_3d)); | 
    
      | 427 |  | ✗ | d->Fx.block(9, 1, 3, 1) += -dt_ * R * (base_vector_y.cross(forces_3d)); | 
    
      | 428 |  | ✗ | d->Fx.block(9, 2, 3, 1) += -dt_ * R * (base_vector_z.cross(forces_3d)); | 
    
      | 429 |  |  |  | 
    
      | 430 |  | ✗ | d->Fx.block(9, 12 + 2 * i, 3, 1) += | 
    
      | 431 |  | ✗ | dt_ * R * (base_vector_x.cross(forces_3d)); | 
    
      | 432 |  | ✗ | d->Fx.block(9, 12 + 2 * i + 1, 3, 1) += | 
    
      | 433 |  | ✗ | dt_ * R * (base_vector_y.cross(forces_3d)); | 
    
      | 434 |  |  | } | 
    
      | 435 |  |  | } | 
    
      | 436 |  |  | // d->Fu << Eigen::Matrix<Scalar, 20, 12>::Zero() ; | 
    
      | 437 |  | ✗ | d->Fu.block(0, 0, 12, 12) << B; | 
    
      | 438 |  |  | } | 
    
      | 439 |  |  |  | 
    
      | 440 |  |  | template <typename Scalar> | 
    
      | 441 |  |  | boost::shared_ptr<crocoddyl::ActionDataAbstractTpl<Scalar> > | 
    
      | 442 |  | ✗ | ActionModelQuadrupedAugmentedTpl<Scalar>::createData() { | 
    
      | 443 |  | ✗ | return boost::make_shared<ActionDataQuadrupedAugmentedTpl<Scalar> >(this); | 
    
      | 444 |  |  | } | 
    
      | 445 |  |  |  | 
    
      | 446 |  |  | //////////////////////////////// | 
    
      | 447 |  |  | // get & set parameters //////// | 
    
      | 448 |  |  | //////////////////////////////// | 
    
      | 449 |  |  |  | 
    
      | 450 |  |  | template <typename Scalar> | 
    
      | 451 |  |  | const typename Eigen::Matrix<Scalar, 12, 1>& | 
    
      | 452 |  | ✗ | ActionModelQuadrupedAugmentedTpl<Scalar>::get_force_weights() const { | 
    
      | 453 |  | ✗ | return force_weights_; | 
    
      | 454 |  |  | } | 
    
      | 455 |  |  | template <typename Scalar> | 
    
      | 456 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_force_weights( | 
    
      | 457 |  |  | const typename MathBase::VectorXs& weights) { | 
    
      | 458 |  | ✗ | if (static_cast<std::size_t>(weights.size()) != 12) { | 
    
      | 459 |  | ✗ | throw_pretty("Invalid argument: " | 
    
      | 460 |  |  | << "Weights vector has wrong dimension (it should be 12)"); | 
    
      | 461 |  |  | } | 
    
      | 462 |  | ✗ | force_weights_ = weights; | 
    
      | 463 |  |  | } | 
    
      | 464 |  |  |  | 
    
      | 465 |  |  | template <typename Scalar> | 
    
      | 466 |  |  | const typename Eigen::Matrix<Scalar, 12, 1>& | 
    
      | 467 |  | ✗ | ActionModelQuadrupedAugmentedTpl<Scalar>::get_state_weights() const { | 
    
      | 468 |  | ✗ | return state_weights_; | 
    
      | 469 |  |  | } | 
    
      | 470 |  |  | template <typename Scalar> | 
    
      | 471 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_state_weights( | 
    
      | 472 |  |  | const typename MathBase::VectorXs& weights) { | 
    
      | 473 |  | ✗ | if (static_cast<std::size_t>(weights.size()) != 12) { | 
    
      | 474 |  | ✗ | throw_pretty("Invalid argument: " | 
    
      | 475 |  |  | << "Weights vector has wrong dimension (it should be 12)"); | 
    
      | 476 |  |  | } | 
    
      | 477 |  | ✗ | state_weights_ = weights; | 
    
      | 478 |  |  | } | 
    
      | 479 |  |  |  | 
    
      | 480 |  |  | template <typename Scalar> | 
    
      | 481 |  |  | const typename Eigen::Matrix<Scalar, 8, 1>& | 
    
      | 482 |  | ✗ | ActionModelQuadrupedAugmentedTpl<Scalar>::get_heuristic_weights() const { | 
    
      | 483 |  | ✗ | return heuristic_weights_; | 
    
      | 484 |  |  | } | 
    
      | 485 |  |  | template <typename Scalar> | 
    
      | 486 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_heuristic_weights( | 
    
      | 487 |  |  | const typename MathBase::VectorXs& weights) { | 
    
      | 488 |  | ✗ | if (static_cast<std::size_t>(weights.size()) != 8) { | 
    
      | 489 |  | ✗ | throw_pretty("Invalid argument: " | 
    
      | 490 |  |  | << "Weights vector has wrong dimension (it should be 8)"); | 
    
      | 491 |  |  | } | 
    
      | 492 |  | ✗ | heuristic_weights_ = weights; | 
    
      | 493 |  |  | } | 
    
      | 494 |  |  |  | 
    
      | 495 |  |  | template <typename Scalar> | 
    
      | 496 |  |  | const typename Eigen::Matrix<Scalar, 8, 1>& | 
    
      | 497 |  | ✗ | ActionModelQuadrupedAugmentedTpl<Scalar>::get_stop_weights() const { | 
    
      | 498 |  | ✗ | return stop_weights_; | 
    
      | 499 |  |  | } | 
    
      | 500 |  |  | template <typename Scalar> | 
    
      | 501 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_stop_weights( | 
    
      | 502 |  |  | const typename MathBase::VectorXs& weights) { | 
    
      | 503 |  | ✗ | if (static_cast<std::size_t>(weights.size()) != 8) { | 
    
      | 504 |  | ✗ | throw_pretty("Invalid argument: " | 
    
      | 505 |  |  | << "Weights vector has wrong dimension (it should be 8)"); | 
    
      | 506 |  |  | } | 
    
      | 507 |  | ✗ | stop_weights_ = weights; | 
    
      | 508 |  |  | } | 
    
      | 509 |  |  |  | 
    
      | 510 |  |  | template <typename Scalar> | 
    
      | 511 |  | ✗ | const Scalar& ActionModelQuadrupedAugmentedTpl<Scalar>::get_friction_weight() | 
    
      | 512 |  |  | const { | 
    
      | 513 |  | ✗ | return friction_weight_; | 
    
      | 514 |  |  | } | 
    
      | 515 |  |  | template <typename Scalar> | 
    
      | 516 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_friction_weight( | 
    
      | 517 |  |  | const Scalar& weight) { | 
    
      | 518 |  | ✗ | friction_weight_ = weight; | 
    
      | 519 |  |  | } | 
    
      | 520 |  |  |  | 
    
      | 521 |  |  | template <typename Scalar> | 
    
      | 522 |  | ✗ | const Scalar& ActionModelQuadrupedAugmentedTpl<Scalar>::get_mu() const { | 
    
      | 523 |  | ✗ | return mu; | 
    
      | 524 |  |  | } | 
    
      | 525 |  |  | template <typename Scalar> | 
    
      | 526 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_mu(const Scalar& mu_coeff) { | 
    
      | 527 |  | ✗ | mu = mu_coeff; | 
    
      | 528 |  |  | } | 
    
      | 529 |  |  |  | 
    
      | 530 |  |  | template <typename Scalar> | 
    
      | 531 |  | ✗ | const Scalar& ActionModelQuadrupedAugmentedTpl<Scalar>::get_mass() const { | 
    
      | 532 |  | ✗ | return mass; | 
    
      | 533 |  |  | } | 
    
      | 534 |  |  | template <typename Scalar> | 
    
      | 535 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_mass(const Scalar& m) { | 
    
      | 536 |  |  | // The model need to be updated after this changed | 
    
      | 537 |  | ✗ | mass = m; | 
    
      | 538 |  |  | } | 
    
      | 539 |  |  |  | 
    
      | 540 |  |  | template <typename Scalar> | 
    
      | 541 |  | ✗ | const Scalar& ActionModelQuadrupedAugmentedTpl<Scalar>::get_dt() const { | 
    
      | 542 |  | ✗ | return dt_; | 
    
      | 543 |  |  | } | 
    
      | 544 |  |  | template <typename Scalar> | 
    
      | 545 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_dt(const Scalar& dt) { | 
    
      | 546 |  |  | // The model need to be updated after this changed | 
    
      | 547 |  | ✗ | dt_ = dt; | 
    
      | 548 |  | ✗ | g[8] = Scalar(-9.81) * dt_; | 
    
      | 549 |  | ✗ | A.topRightCorner(6, 6) << Eigen::Matrix<Scalar, 6, 6>::Identity() * dt_; | 
    
      | 550 |  |  | } | 
    
      | 551 |  |  |  | 
    
      | 552 |  |  | template <typename Scalar> | 
    
      | 553 |  |  | const typename Eigen::Matrix<Scalar, 3, 3>& | 
    
      | 554 |  | ✗ | ActionModelQuadrupedAugmentedTpl<Scalar>::get_gI() const { | 
    
      | 555 |  | ✗ | return gI; | 
    
      | 556 |  |  | } | 
    
      | 557 |  |  | template <typename Scalar> | 
    
      | 558 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_gI( | 
    
      | 559 |  |  | const typename MathBase::Matrix3s& inertia_matrix) { | 
    
      | 560 |  |  | // The model need to be updated after this changed | 
    
      | 561 |  | ✗ | if (static_cast<std::size_t>(inertia_matrix.size()) != 9) { | 
    
      | 562 |  | ✗ | throw_pretty("Invalid argument: " | 
    
      | 563 |  |  | << "gI has wrong dimension : 3x3"); | 
    
      | 564 |  |  | } | 
    
      | 565 |  | ✗ | gI = inertia_matrix; | 
    
      | 566 |  |  | } | 
    
      | 567 |  |  |  | 
    
      | 568 |  |  | template <typename Scalar> | 
    
      | 569 |  | ✗ | const Scalar& ActionModelQuadrupedAugmentedTpl<Scalar>::get_min_fz_contact() | 
    
      | 570 |  |  | const { | 
    
      | 571 |  |  | // The model need to be updated after this changed | 
    
      | 572 |  | ✗ | return min_fz_in_contact; | 
    
      | 573 |  |  | } | 
    
      | 574 |  |  | template <typename Scalar> | 
    
      | 575 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_min_fz_contact( | 
    
      | 576 |  |  | const Scalar& min_fz) { | 
    
      | 577 |  |  | // The model need to be updated after this changed | 
    
      | 578 |  | ✗ | min_fz_in_contact = min_fz; | 
    
      | 579 |  |  | } | 
    
      | 580 |  |  |  | 
    
      | 581 |  |  | template <typename Scalar> | 
    
      | 582 |  | ✗ | const Scalar& ActionModelQuadrupedAugmentedTpl<Scalar>::get_max_fz_contact() | 
    
      | 583 |  |  | const { | 
    
      | 584 |  |  | // The model need to be updated after this changed | 
    
      | 585 |  | ✗ | return max_fz_in_contact; | 
    
      | 586 |  |  | } | 
    
      | 587 |  |  | template <typename Scalar> | 
    
      | 588 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_max_fz_contact( | 
    
      | 589 |  |  | const Scalar& max_fz) { | 
    
      | 590 |  |  | // The model need to be updated after this changed | 
    
      | 591 |  | ✗ | max_fz_in_contact = max_fz; | 
    
      | 592 |  | ✗ | for (int i = 0; i < 4; i = i + 1) { | 
    
      | 593 |  | ✗ | ub(6 * i + 5) = max_fz_in_contact; | 
    
      | 594 |  |  | } | 
    
      | 595 |  |  | } | 
    
      | 596 |  |  |  | 
    
      | 597 |  |  | template <typename Scalar> | 
    
      | 598 |  | ✗ | const bool& ActionModelQuadrupedAugmentedTpl<Scalar>::get_symmetry_term() | 
    
      | 599 |  |  | const { | 
    
      | 600 |  | ✗ | return symmetry_term; | 
    
      | 601 |  |  | } | 
    
      | 602 |  |  | template <typename Scalar> | 
    
      | 603 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_symmetry_term( | 
    
      | 604 |  |  | const bool& sym_term) { | 
    
      | 605 |  |  | // The model need to be updated after this changed | 
    
      | 606 |  | ✗ | symmetry_term = sym_term; | 
    
      | 607 |  |  | } | 
    
      | 608 |  |  |  | 
    
      | 609 |  |  | template <typename Scalar> | 
    
      | 610 |  | ✗ | const bool& ActionModelQuadrupedAugmentedTpl<Scalar>::get_centrifugal_term() | 
    
      | 611 |  |  | const { | 
    
      | 612 |  | ✗ | return centrifugal_term; | 
    
      | 613 |  |  | } | 
    
      | 614 |  |  | template <typename Scalar> | 
    
      | 615 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_centrifugal_term( | 
    
      | 616 |  |  | const bool& cent_term) { | 
    
      | 617 |  |  | // The model need to be updated after this changed | 
    
      | 618 |  | ✗ | centrifugal_term = cent_term; | 
    
      | 619 |  |  | } | 
    
      | 620 |  |  |  | 
    
      | 621 |  |  | template <typename Scalar> | 
    
      | 622 |  | ✗ | const bool& ActionModelQuadrupedAugmentedTpl< | 
    
      | 623 |  |  | Scalar>::get_shoulder_reference_position() const { | 
    
      | 624 |  | ✗ | return shoulder_reference_position; | 
    
      | 625 |  |  | } | 
    
      | 626 |  |  | template <typename Scalar> | 
    
      | 627 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_shoulder_reference_position( | 
    
      | 628 |  |  | const bool& reference) { | 
    
      | 629 |  | ✗ | shoulder_reference_position = reference; | 
    
      | 630 |  |  | } | 
    
      | 631 |  |  |  | 
    
      | 632 |  |  | template <typename Scalar> | 
    
      | 633 |  | ✗ | const Scalar& ActionModelQuadrupedAugmentedTpl<Scalar>::get_T_gait() const { | 
    
      | 634 |  |  | // The model need to be updated after this changed | 
    
      | 635 |  | ✗ | return T_gait; | 
    
      | 636 |  |  | } | 
    
      | 637 |  |  | template <typename Scalar> | 
    
      | 638 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_T_gait( | 
    
      | 639 |  |  | const Scalar& T_gait_) { | 
    
      | 640 |  |  | // The model need to be updated after this changed | 
    
      | 641 |  | ✗ | T_gait = T_gait_; | 
    
      | 642 |  |  | } | 
    
      | 643 |  |  |  | 
    
      | 644 |  |  | template <typename Scalar> | 
    
      | 645 |  | ✗ | const Scalar& ActionModelQuadrupedAugmentedTpl<Scalar>::get_shoulder_hlim() | 
    
      | 646 |  |  | const { | 
    
      | 647 |  | ✗ | return sh_hlim; | 
    
      | 648 |  |  | } | 
    
      | 649 |  |  | template <typename Scalar> | 
    
      | 650 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_shoulder_hlim( | 
    
      | 651 |  |  | const Scalar& hlim) { | 
    
      | 652 |  |  | // The model need to be updated after this changed | 
    
      | 653 |  | ✗ | sh_hlim = hlim; | 
    
      | 654 |  |  | } | 
    
      | 655 |  |  |  | 
    
      | 656 |  |  | template <typename Scalar> | 
    
      | 657 |  |  | const typename Eigen::Matrix<Scalar, 4, 1>& | 
    
      | 658 |  | ✗ | ActionModelQuadrupedAugmentedTpl<Scalar>::get_shoulder_contact_weight() const { | 
    
      | 659 |  | ✗ | return sh_weight; | 
    
      | 660 |  |  | } | 
    
      | 661 |  |  | template <typename Scalar> | 
    
      | 662 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_shoulder_contact_weight( | 
    
      | 663 |  |  | const typename Eigen::Matrix<Scalar, 4, 1>& weight) { | 
    
      | 664 |  |  | // The model need to be updated after this changed | 
    
      | 665 |  | ✗ | sh_weight = weight; | 
    
      | 666 |  |  | } | 
    
      | 667 |  |  |  | 
    
      | 668 |  |  | /////////////////////////// | 
    
      | 669 |  |  | //// get A & B matrix ///// | 
    
      | 670 |  |  | /////////////////////////// | 
    
      | 671 |  |  | template <typename Scalar> | 
    
      | 672 |  |  | const typename Eigen::Matrix<Scalar, 12, 12>& | 
    
      | 673 |  | ✗ | ActionModelQuadrupedAugmentedTpl<Scalar>::get_A() const { | 
    
      | 674 |  | ✗ | return A; | 
    
      | 675 |  |  | } | 
    
      | 676 |  |  | template <typename Scalar> | 
    
      | 677 |  |  | const typename Eigen::Matrix<Scalar, 12, 12>& | 
    
      | 678 |  | ✗ | ActionModelQuadrupedAugmentedTpl<Scalar>::get_B() const { | 
    
      | 679 |  | ✗ | return B; | 
    
      | 680 |  |  | } | 
    
      | 681 |  |  |  | 
    
      | 682 |  |  | // to modify the cost on the command : || fz - m*g/nb contact ||^2 | 
    
      | 683 |  |  | // --> set to True | 
    
      | 684 |  |  | template <typename Scalar> | 
    
      | 685 |  | ✗ | const bool& ActionModelQuadrupedAugmentedTpl<Scalar>::get_relative_forces() | 
    
      | 686 |  |  | const { | 
    
      | 687 |  | ✗ | return relative_forces; | 
    
      | 688 |  |  | } | 
    
      | 689 |  |  | template <typename Scalar> | 
    
      | 690 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::set_relative_forces( | 
    
      | 691 |  |  | const bool& rel_forces) { | 
    
      | 692 |  | ✗ | relative_forces = rel_forces; | 
    
      | 693 |  | ✗ | uref_.setZero(); | 
    
      | 694 |  | ✗ | if (relative_forces) { | 
    
      | 695 |  | ✗ | for (int i = 0; i < 4; i = i + 1) { | 
    
      | 696 |  | ✗ | if (gait[i] == 1) { | 
    
      | 697 |  | ✗ | uref_[3 * i + 2] = (Scalar(9.81) * mass) / (gait.sum()); | 
    
      | 698 |  |  | } | 
    
      | 699 |  |  | } | 
    
      | 700 |  |  | } | 
    
      | 701 |  |  | } | 
    
      | 702 |  |  |  | 
    
      | 703 |  |  | //////////////////////// | 
    
      | 704 |  |  | // Update current model | 
    
      | 705 |  |  | //////////////////////// | 
    
      | 706 |  |  |  | 
    
      | 707 |  |  | template <typename Scalar> | 
    
      | 708 |  | ✗ | void ActionModelQuadrupedAugmentedTpl<Scalar>::update_model( | 
    
      | 709 |  |  | const Eigen::Ref<const typename MathBase::MatrixXs>& l_feet, | 
    
      | 710 |  |  | const Eigen::Ref<const typename MathBase::MatrixXs>& l_stop, | 
    
      | 711 |  |  | const Eigen::Ref<const typename MathBase::MatrixXs>& xref, | 
    
      | 712 |  |  | const Eigen::Ref<const typename MathBase::MatrixXs>& S) { | 
    
      | 713 |  | ✗ | if (static_cast<std::size_t>(l_feet.size()) != 12) { | 
    
      | 714 |  | ✗ | throw_pretty("Invalid argument: " | 
    
      | 715 |  |  | << "l_feet matrix has wrong dimension (it should be : 3x4)"); | 
    
      | 716 |  |  | } | 
    
      | 717 |  | ✗ | if (static_cast<std::size_t>(xref.size()) != 12) { | 
    
      | 718 |  | ✗ | throw_pretty("Invalid argument: " | 
    
      | 719 |  |  | << "xref vector has wrong dimension (it should be 12 )"); | 
    
      | 720 |  |  | } | 
    
      | 721 |  | ✗ | if (static_cast<std::size_t>(S.size()) != 4) { | 
    
      | 722 |  | ✗ | throw_pretty("Invalid argument: " | 
    
      | 723 |  |  | << "S vector has wrong dimension (it should be 4x1)"); | 
    
      | 724 |  |  | } | 
    
      | 725 |  |  |  | 
    
      | 726 |  | ✗ | xref_ = xref; | 
    
      | 727 |  | ✗ | gait = S; | 
    
      | 728 |  |  |  | 
    
      | 729 |  | ✗ | uref_.setZero(); | 
    
      | 730 |  | ✗ | if (relative_forces) { | 
    
      | 731 |  | ✗ | for (int i = 0; i < 4; i = i + 1) { | 
    
      | 732 |  | ✗ | if (gait[i] == 1) { | 
    
      | 733 |  | ✗ | uref_[3 * i + 2] = (Scalar(9.81) * mass) / (gait.sum()); | 
    
      | 734 |  |  | } | 
    
      | 735 |  |  | } | 
    
      | 736 |  |  | } | 
    
      | 737 |  |  |  | 
    
      | 738 |  | ✗ | for (int i = 0; i < 4; i = i + 1) { | 
    
      | 739 |  | ✗ | gait_double(2 * i, 0) = gait(i, 0); | 
    
      | 740 |  | ✗ | gait_double(2 * i + 1, 0) = gait(i, 0); | 
    
      | 741 |  |  |  | 
    
      | 742 |  | ✗ | pheuristic_.block(2 * i, 0, 2, 1) = l_feet.block(0, i, 2, 1); | 
    
      | 743 |  | ✗ | pstop_.block(2 * i, 0, 2, 1) = l_stop.block(0, i, 2, 1); | 
    
      | 744 |  |  | } | 
    
      | 745 |  |  |  | 
    
      | 746 |  | ✗ | R_tmp << cos(xref(5, 0)), -sin(xref(5, 0)), Scalar(0), sin(xref(5, 0)), | 
    
      | 747 |  | ✗ | cos(xref(5, 0)), Scalar(0), Scalar(0), Scalar(0), Scalar(1.0); | 
    
      | 748 |  |  |  | 
    
      | 749 |  |  | // Centrifual term | 
    
      | 750 |  |  | // pcentrifugal_tmp_1 = xref.block(6, 0, 3, 1); | 
    
      | 751 |  |  | // pcentrifugal_tmp_2 = xref.block(9, 0, 3, 1); | 
    
      | 752 |  |  | // pcentrifugal_tmp = 0.5 * std::sqrt(xref(2, 0) / 9.81) * | 
    
      | 753 |  |  | // pcentrifugal_tmp_1.cross(pcentrifugal_tmp_2); | 
    
      | 754 |  |  |  | 
    
      | 755 |  |  | // for (int i = 0; i < 4; i = i + 1) { | 
    
      | 756 |  |  | //   pshoulder_tmp.block(0, i, 2, 1) = | 
    
      | 757 |  |  | //       R_tmp.block(0, 0, 2, 2) * | 
    
      | 758 |  |  | //       (pshoulder_0.block(0, i, 2, 1) + symmetry_term * 0.25 * T_gait * | 
    
      | 759 |  |  | //       xref.block(6, 0, 2, 1) + | 
    
      | 760 |  |  | //        centrifugal_term * pcentrifugal_tmp.block(0, 0, 2, 1)); | 
    
      | 761 |  |  | // } | 
    
      | 762 |  |  |  | 
    
      | 763 |  | ✗ | R = (R_tmp.transpose() * gI * R_tmp).inverse();  // I_inv | 
    
      | 764 |  |  |  | 
    
      | 765 |  | ✗ | for (int i = 0; i < 4; i = i + 1) { | 
    
      | 766 |  |  | // pshoulder_[2 * i] = pshoulder_tmp(0, i) + xref(0, 0); | 
    
      | 767 |  |  | // pshoulder_[2 * i + 1] = pshoulder_tmp(1, i) + xref(1, 0); | 
    
      | 768 |  |  |  | 
    
      | 769 |  | ✗ | if (S(i, 0) != 0) { | 
    
      | 770 |  |  | // set limit for normal force, (foot in contact with the ground) | 
    
      | 771 |  | ✗ | ub[5 * i + 4] = -min_fz_in_contact; | 
    
      | 772 |  |  |  | 
    
      | 773 |  |  | // B update | 
    
      | 774 |  | ✗ | B.block(6, 3 * i, 3, 3).diagonal() << dt_ / mass, dt_ / mass, dt_ / mass; | 
    
      | 775 |  |  |  | 
    
      | 776 |  |  | //  Assuption 1 : levers arms not depends on the state, but on the | 
    
      | 777 |  |  | //  predicted position (xfref) | 
    
      | 778 |  |  | //  --> B will be updated with the update_B method for each calc function | 
    
      | 779 |  |  |  | 
    
      | 780 |  |  | // lever_tmp = lever_arms.block(0,i,3,1) - xref.block(0,0,3,1) ; | 
    
      | 781 |  |  | // R_tmp << 0.0, -lever_tmp[2], lever_tmp[1], | 
    
      | 782 |  |  | // lever_tmp[2], 0.0, -lever_tmp[0], -lever_tmp[1], lever_tmp[0], 0.0 ; | 
    
      | 783 |  |  | // B.block(9 , 3*i  , 3,3) << dt_ * R* R_tmp; | 
    
      | 784 |  |  | } else { | 
    
      | 785 |  |  | // set limit for normal force at 0.0 | 
    
      | 786 |  | ✗ | ub[5 * i + 4] = Scalar(0.0); | 
    
      | 787 |  | ✗ | B.block(6, 3 * i, 3, 3).setZero(); | 
    
      | 788 |  | ✗ | B.block(9, 3 * i, 3, 3).setZero(); | 
    
      | 789 |  |  | }; | 
    
      | 790 |  |  | }; | 
    
      | 791 |  |  | } | 
    
      | 792 |  |  | }  // namespace quadruped_walkgen | 
    
      | 793 |  |  |  | 
    
      | 794 |  |  | #endif | 
    
      | 795 |  |  |  |