GCC Code Coverage Report


Directory: ./
File: include/quadruped-walkgen/quadruped_augmented_time.hxx
Date: 2024-12-02 00:24:10
Exec Total Coverage
Lines: 0 390 0.0%
Branches: 0 1312 0.0%

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