Directory: | ./ |
---|---|
File: | include/crocoddyl/multibody/actions/contact-invdyn.hpp |
Date: | 2025-03-26 19:23:43 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 126 | 160 | 78.8% |
Branches: | 121 | 252 | 48.0% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /////////////////////////////////////////////////////////////////////////////// | ||
2 | // BSD 3-Clause License | ||
3 | // | ||
4 | // Copyright (C) 2021-2025, Heriot-Watt University, University of Edinburgh | ||
5 | // Copyright note valid unless otherwise stated in individual files. | ||
6 | // All rights reserved. | ||
7 | /////////////////////////////////////////////////////////////////////////////// | ||
8 | |||
9 | #ifndef CROCODDYL_MULTIBODY_ACTIONS_CONTACT_INVDYN_HPP_ | ||
10 | #define CROCODDYL_MULTIBODY_ACTIONS_CONTACT_INVDYN_HPP_ | ||
11 | |||
12 | #include "crocoddyl/core/actuation-base.hpp" | ||
13 | #include "crocoddyl/core/constraints/constraint-manager.hpp" | ||
14 | #include "crocoddyl/core/costs/cost-sum.hpp" | ||
15 | #include "crocoddyl/core/diff-action-base.hpp" | ||
16 | #include "crocoddyl/multibody/contacts/multiple-contacts.hpp" | ||
17 | #include "crocoddyl/multibody/data/contacts.hpp" | ||
18 | #include "crocoddyl/multibody/fwd.hpp" | ||
19 | #include "crocoddyl/multibody/states/multibody.hpp" | ||
20 | |||
21 | namespace crocoddyl { | ||
22 | |||
23 | /** | ||
24 | * @brief Differential action model for contact inverse dynamics in multibody | ||
25 | * systems. | ||
26 | * | ||
27 | * This class implements forward kinematic with holonomic contact constraints | ||
28 | * (defined at the acceleration level) and inverse-dynamics computation using | ||
29 | * the Recursive Newton Euler Algorithm (RNEA). The stack of cost and constraint | ||
30 | * functions are implemented in `CostModelSumTpl` and | ||
31 | * `ConstraintModelManagerTpl`, respectively. The acceleration and contact | ||
32 | * forces are decision variables defined as the control inputs, and the | ||
33 | * under-actuation and contact constraint are under the name `tau` and its frame | ||
34 | * name, thus the user is not allowed to use it. | ||
35 | * | ||
36 | * Additionally, it is important to note that `calcDiff()` computes the | ||
37 | * derivatives using the latest stored values by `calc()`. Thus, we need to | ||
38 | * first run `calc()`. | ||
39 | * | ||
40 | * \sa `DifferentialActionModelAbstractTpl`, `calc()`, `calcDiff()`, | ||
41 | * `createData()` | ||
42 | */ | ||
43 | template <typename _Scalar> | ||
44 | class DifferentialActionModelContactInvDynamicsTpl | ||
45 | : public DifferentialActionModelAbstractTpl<_Scalar> { | ||
46 | public: | ||
47 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW | ||
48 | ✗ | CROCODDYL_DERIVED_CAST(DifferentialActionModelBase, | |
49 | DifferentialActionModelContactInvDynamicsTpl) | ||
50 | |||
51 | typedef _Scalar Scalar; | ||
52 | typedef DifferentialActionModelAbstractTpl<Scalar> Base; | ||
53 | typedef DifferentialActionDataContactInvDynamicsTpl<Scalar> Data; | ||
54 | typedef StateMultibodyTpl<Scalar> StateMultibody; | ||
55 | typedef ActuationModelAbstractTpl<Scalar> ActuationModelAbstract; | ||
56 | typedef CostModelSumTpl<Scalar> CostModelSum; | ||
57 | typedef ConstraintModelManagerTpl<Scalar> ConstraintModelManager; | ||
58 | typedef ContactModelMultipleTpl<Scalar> ContactModelMultiple; | ||
59 | typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract; | ||
60 | typedef DifferentialActionDataAbstractTpl<Scalar> | ||
61 | DifferentialActionDataAbstract; | ||
62 | typedef ContactItemTpl<Scalar> ContactItem; | ||
63 | typedef MathBaseTpl<Scalar> MathBase; | ||
64 | typedef typename MathBase::VectorXs VectorXs; | ||
65 | typedef typename MathBase::MatrixXs MatrixXs; | ||
66 | |||
67 | /** | ||
68 | * @brief Initialize the contact inverse-dynamics action model | ||
69 | * | ||
70 | * It describes the kinematic evolution of the multibody system with contacts, | ||
71 | * and computes the needed torques using inverse-dynamics. | ||
72 | * | ||
73 | * @param[in] state State of the multibody system | ||
74 | * @param[in] actuation Actuation model | ||
75 | * @param[in] contacts Multiple contacts | ||
76 | * @param[in] costs Cost model | ||
77 | */ | ||
78 | DifferentialActionModelContactInvDynamicsTpl( | ||
79 | std::shared_ptr<StateMultibody> state, | ||
80 | std::shared_ptr<ActuationModelAbstract> actuation, | ||
81 | std::shared_ptr<ContactModelMultiple> contacts, | ||
82 | std::shared_ptr<CostModelSum> costs); | ||
83 | |||
84 | /** | ||
85 | * @brief Initialize the contact inverse-dynamics action model | ||
86 | * | ||
87 | * @param[in] state State of the multibody system | ||
88 | * @param[in] actuation Actuation model | ||
89 | * @param[in] contacts Multiple contacts | ||
90 | * @param[in] costs Cost model | ||
91 | * @param[in] constraints Constraints model | ||
92 | */ | ||
93 | DifferentialActionModelContactInvDynamicsTpl( | ||
94 | std::shared_ptr<StateMultibody> state, | ||
95 | std::shared_ptr<ActuationModelAbstract> actuation, | ||
96 | std::shared_ptr<ContactModelMultiple> contacts, | ||
97 | std::shared_ptr<CostModelSum> costs, | ||
98 | std::shared_ptr<ConstraintModelManager> constraints); | ||
99 | 606 | virtual ~DifferentialActionModelContactInvDynamicsTpl() = default; | |
100 | |||
101 | /** | ||
102 | * @brief Compute the system acceleration, cost value and constraint residuals | ||
103 | * | ||
104 | * It extracts the acceleration value from control vector and also computes | ||
105 | * the cost and constraints. | ||
106 | * | ||
107 | * @param[in] data Contact inverse-dynamics data | ||
108 | * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$ | ||
109 | * @param[in] u Control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$ | ||
110 | */ | ||
111 | virtual void calc(const std::shared_ptr<DifferentialActionDataAbstract>& data, | ||
112 | const Eigen::Ref<const VectorXs>& x, | ||
113 | const Eigen::Ref<const VectorXs>& u) override; | ||
114 | |||
115 | /** | ||
116 | * @brief @copydoc Base::calc(const | ||
117 | * std::shared_ptr<DifferentialActionDataAbstract>& data, const | ||
118 | * Eigen::Ref<const VectorXs>& x) | ||
119 | */ | ||
120 | virtual void calc(const std::shared_ptr<DifferentialActionDataAbstract>& data, | ||
121 | const Eigen::Ref<const VectorXs>& x) override; | ||
122 | |||
123 | /** | ||
124 | * @brief Compute the derivatives of the dynamics, cost and constraint | ||
125 | * functions | ||
126 | * | ||
127 | * It computes the partial derivatives of the dynamical system and the cost | ||
128 | * and contraint functions. It assumes that `calc()` has been run first. This | ||
129 | * function builds a quadratic approximation of the time-continuous action | ||
130 | * model (i.e., dynamical system, cost and constraint functions). | ||
131 | * | ||
132 | * @param[in] data Contact inverse-dynamics data | ||
133 | * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$ | ||
134 | * @param[in] u Control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$ | ||
135 | */ | ||
136 | virtual void calcDiff( | ||
137 | const std::shared_ptr<DifferentialActionDataAbstract>& data, | ||
138 | const Eigen::Ref<const VectorXs>& x, | ||
139 | const Eigen::Ref<const VectorXs>& u) override; | ||
140 | |||
141 | /** | ||
142 | * @brief @copydoc Base::calcDiff(const | ||
143 | * std::shared_ptr<DifferentialActionDataAbstract>& data, const | ||
144 | * Eigen::Ref<const VectorXs>& x) | ||
145 | */ | ||
146 | virtual void calcDiff( | ||
147 | const std::shared_ptr<DifferentialActionDataAbstract>& data, | ||
148 | const Eigen::Ref<const VectorXs>& x) override; | ||
149 | |||
150 | /** | ||
151 | * @brief Create the contact inverse-dynamics data | ||
152 | * | ||
153 | * @return contact inverse-dynamics data | ||
154 | */ | ||
155 | virtual std::shared_ptr<DifferentialActionDataAbstract> createData() override; | ||
156 | |||
157 | /** | ||
158 | * @brief Cast the contact-invdyn model to a different scalar type. | ||
159 | * | ||
160 | * It is useful for operations requiring different precision or scalar types. | ||
161 | * | ||
162 | * @tparam NewScalar The new scalar type to cast to. | ||
163 | * @return DifferentialActionModelContactInvDynamicsTpl<NewScalar> A | ||
164 | * differential-action model with the new scalar type. | ||
165 | */ | ||
166 | template <typename NewScalar> | ||
167 | DifferentialActionModelContactInvDynamicsTpl<NewScalar> cast() const; | ||
168 | |||
169 | /** | ||
170 | * @brief Checks that a specific data belongs to the contact inverse-dynamics | ||
171 | * model | ||
172 | */ | ||
173 | virtual bool checkData( | ||
174 | const std::shared_ptr<DifferentialActionDataAbstract>& data) override; | ||
175 | |||
176 | /** | ||
177 | * @brief Computes the quasic static commands | ||
178 | * | ||
179 | * The quasic static commands are the ones produced for a reference posture as | ||
180 | * an equilibrium point with zero acceleration, i.e., for | ||
181 | * \f$\mathbf{f^q_x}\delta\mathbf{q}+\mathbf{f_u}\delta\mathbf{u}=\mathbf{0}\f$ | ||
182 | * | ||
183 | * @param[in] data Contact inverse-dynamics data | ||
184 | * @param[out] u Quasic-static commands | ||
185 | * @param[in] x State point (velocity has to be zero) | ||
186 | * @param[in] maxiter Maximum allowed number of iterations (default 100) | ||
187 | * @param[in] tol Tolerance (default 1e-9) | ||
188 | */ | ||
189 | virtual void quasiStatic( | ||
190 | const std::shared_ptr<DifferentialActionDataAbstract>& data, | ||
191 | Eigen::Ref<VectorXs> u, const Eigen::Ref<const VectorXs>& x, | ||
192 | const std::size_t maxiter = 100, | ||
193 | const Scalar tol = Scalar(1e-9)) override; | ||
194 | |||
195 | /** | ||
196 | * @brief Return the number of inequality constraints | ||
197 | */ | ||
198 | virtual std::size_t get_ng() const override; | ||
199 | |||
200 | /** | ||
201 | * @brief Return the number of equality constraints | ||
202 | */ | ||
203 | virtual std::size_t get_nh() const override; | ||
204 | |||
205 | /** | ||
206 | * @brief Return the number of equality terminal constraints | ||
207 | */ | ||
208 | virtual std::size_t get_ng_T() const override; | ||
209 | |||
210 | /** | ||
211 | * @brief Return the number of equality terminal constraints | ||
212 | */ | ||
213 | virtual std::size_t get_nh_T() const override; | ||
214 | |||
215 | /** | ||
216 | * @brief Return the lower bound of the inequality constraints | ||
217 | */ | ||
218 | virtual const VectorXs& get_g_lb() const override; | ||
219 | |||
220 | /** | ||
221 | * @brief Return the upper bound of the inequality constraints | ||
222 | */ | ||
223 | virtual const VectorXs& get_g_ub() const override; | ||
224 | |||
225 | /** | ||
226 | * @brief Return the actuation model | ||
227 | */ | ||
228 | const std::shared_ptr<ActuationModelAbstract>& get_actuation() const; | ||
229 | |||
230 | /** | ||
231 | * @brief Return the contact model | ||
232 | */ | ||
233 | const std::shared_ptr<ContactModelMultiple>& get_contacts() const; | ||
234 | |||
235 | /** | ||
236 | * @brief Return the cost model | ||
237 | */ | ||
238 | const std::shared_ptr<CostModelSum>& get_costs() const; | ||
239 | |||
240 | /** | ||
241 | * @brief Return the constraint model manager | ||
242 | */ | ||
243 | const std::shared_ptr<ConstraintModelManager>& get_constraints() const; | ||
244 | |||
245 | /** | ||
246 | * @brief Return the Pinocchio model | ||
247 | */ | ||
248 | pinocchio::ModelTpl<Scalar>& get_pinocchio() const; | ||
249 | |||
250 | /** | ||
251 | * @brief Print relevant information of the contact inverse-dynamics model | ||
252 | * @param[out] os Output stream object | ||
253 | */ | ||
254 | virtual void print(std::ostream& os) const override; | ||
255 | |||
256 | protected: | ||
257 | using Base::g_lb_; //!< Lower bound of the inequality constraints | ||
258 | using Base::g_ub_; //!< Upper bound of the inequality constraints | ||
259 | using Base::ng_; //!< Number of inequality constraints | ||
260 | using Base::nh_; //!< Number of equality constraints | ||
261 | using Base::nu_; //!< Control dimension | ||
262 | using Base::state_; //!< Model of the state | ||
263 | |||
264 | private: | ||
265 | void init(const std::shared_ptr<StateMultibody>& state); | ||
266 | std::shared_ptr<ActuationModelAbstract> actuation_; //!< Actuation model | ||
267 | std::shared_ptr<ContactModelMultiple> contacts_; //!< Contact model | ||
268 | std::shared_ptr<CostModelSum> costs_; //!< Cost model | ||
269 | std::shared_ptr<ConstraintModelManager> constraints_; //!< Constraint model | ||
270 | pinocchio::ModelTpl<Scalar>* pinocchio_; //!< Pinocchio model | ||
271 | |||
272 | public: | ||
273 | /** | ||
274 | * @brief Actuation residual | ||
275 | * | ||
276 | * This residual function enforces the torques of under-actuated joints (e.g., | ||
277 | * floating-base joints) to be zero. We compute these torques and their | ||
278 | * derivatives using RNEA inside | ||
279 | * `DifferentialActionModelContactInvDynamicsTpl`. | ||
280 | * | ||
281 | * As described in `ResidualModelAbstractTpl`, the residual value and its | ||
282 | * Jacobians are calculated by `calc` and `calcDiff`, respectively. | ||
283 | * | ||
284 | * \sa `ResidualModelAbstractTpl`, `calc()`, `calcDiff()`, `createData()` | ||
285 | */ | ||
286 | class ResidualModelActuation : public ResidualModelAbstractTpl<_Scalar> { | ||
287 | public: | ||
288 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW | ||
289 | ✗ | CROCODDYL_INNER_DERIVED_CAST(ResidualModelBase, | |
290 | DifferentialActionModelContactInvDynamicsTpl, | ||
291 | ResidualModelActuation) | ||
292 | |||
293 | typedef _Scalar Scalar; | ||
294 | typedef MathBaseTpl<Scalar> MathBase; | ||
295 | typedef ResidualModelAbstractTpl<Scalar> Base; | ||
296 | typedef StateMultibodyTpl<Scalar> StateMultibody; | ||
297 | typedef ResidualDataAbstractTpl<Scalar> ResidualDataAbstract; | ||
298 | typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract; | ||
299 | typedef typename MathBase::VectorXs VectorXs; | ||
300 | |||
301 | /** | ||
302 | * @brief Initialize the actuation residual model | ||
303 | * | ||
304 | * @param[in] state State of the multibody system | ||
305 | * @param[in] nu Dimension of the joint torques | ||
306 | * @param[in] nc Dimension of all the contacts | ||
307 | */ | ||
308 | 251 | ResidualModelActuation(std::shared_ptr<StateMultibody> state, | |
309 | const std::size_t nu, const std::size_t nc) | ||
310 | 502 | : Base(state, state->get_nv() - nu, state->get_nv() + nc, true, true, | |
311 | true), | ||
312 | 251 | na_(nu), | |
313 |
1/2✓ Branch 4 taken 251 times.
✗ Branch 5 not taken.
|
753 | nc_(nc) {} |
314 | 502 | virtual ~ResidualModelActuation() = default; | |
315 | |||
316 | /** | ||
317 | * @brief Compute the actuation residual | ||
318 | * | ||
319 | * @param[in] data Actuation residual data | ||
320 | * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$ | ||
321 | * @param[in] u Control input \f$\mathbf{u}\in\mathbb{R}^{nv+nu}\f$ | ||
322 | */ | ||
323 | 23365 | virtual void calc(const std::shared_ptr<ResidualDataAbstract>& data, | |
324 | const Eigen::Ref<const VectorXs>&, | ||
325 | const Eigen::Ref<const VectorXs>&) override { | ||
326 | typename Data::ResidualDataActuation* d = | ||
327 | 23365 | static_cast<typename Data::ResidualDataActuation*>(data.get()); | |
328 | // Update the under-actuation set and residual | ||
329 | 23365 | std::size_t nrow = 0; | |
330 | 665320 | for (std::size_t k = 0; | |
331 |
2/2✓ Branch 2 taken 641955 times.
✓ Branch 3 taken 23365 times.
|
665320 | k < static_cast<std::size_t>(d->actuation->tau_set.size()); ++k) { |
332 |
2/2✓ Branch 3 taken 127365 times.
✓ Branch 4 taken 514590 times.
|
641955 | if (!d->actuation->tau_set[k]) { |
333 | 127365 | data->r(nrow) = d->pinocchio->tau(k); | |
334 | 127365 | nrow += 1; | |
335 | } | ||
336 | } | ||
337 | 23365 | } | |
338 | |||
339 | /** | ||
340 | * @brief @copydoc Base::calc(const std::shared_ptr<ResidualDataAbstract>& | ||
341 | * data, const Eigen::Ref<const VectorXs>& x) | ||
342 | */ | ||
343 | ✗ | virtual void calc(const std::shared_ptr<ResidualDataAbstract>& data, | |
344 | const Eigen::Ref<const VectorXs>&) override { | ||
345 | ✗ | data->r.setZero(); | |
346 | } | ||
347 | |||
348 | /** | ||
349 | * @brief Compute the derivatives of the actuation residual | ||
350 | * | ||
351 | * @param[in] data Actuation residual data | ||
352 | * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$ | ||
353 | * @param[in] u Control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$ | ||
354 | */ | ||
355 | 3135 | virtual void calcDiff(const std::shared_ptr<ResidualDataAbstract>& data, | |
356 | const Eigen::Ref<const VectorXs>&, | ||
357 | const Eigen::Ref<const VectorXs>&) override { | ||
358 | typename Data::ResidualDataActuation* d = | ||
359 | 3135 | static_cast<typename Data::ResidualDataActuation*>(data.get()); | |
360 | 3135 | std::size_t nrow = 0; | |
361 | 3135 | const std::size_t nv = state_->get_nv(); | |
362 |
1/2✓ Branch 2 taken 3135 times.
✗ Branch 3 not taken.
|
3135 | d->dtau_dx.leftCols(nv) = d->pinocchio->dtau_dq; |
363 |
1/2✓ Branch 2 taken 3135 times.
✗ Branch 3 not taken.
|
3135 | d->dtau_dx.rightCols(nv) = d->pinocchio->dtau_dv; |
364 | 3135 | d->dtau_dx -= d->actuation->dtau_dx; | |
365 |
1/2✓ Branch 2 taken 3135 times.
✗ Branch 3 not taken.
|
3135 | d->dtau_du.leftCols(nv) = d->pinocchio->M; |
366 |
3/6✓ Branch 3 taken 3135 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 3135 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 3135 times.
✗ Branch 10 not taken.
|
3135 | d->dtau_du.rightCols(nc_) = -d->contact->Jc.transpose(); |
367 | 77748 | for (std::size_t k = 0; | |
368 |
2/2✓ Branch 2 taken 74613 times.
✓ Branch 3 taken 3135 times.
|
77748 | k < static_cast<std::size_t>(d->actuation->tau_set.size()); ++k) { |
369 |
2/2✓ Branch 3 taken 15675 times.
✓ Branch 4 taken 58938 times.
|
74613 | if (!d->actuation->tau_set[k]) { |
370 |
2/4✓ Branch 2 taken 15675 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 15675 times.
✗ Branch 6 not taken.
|
15675 | d->Rx.row(nrow) = d->dtau_dx.row(k); |
371 |
2/4✓ Branch 2 taken 15675 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 15675 times.
✗ Branch 6 not taken.
|
15675 | d->Ru.row(nrow) = d->dtau_du.row(k); |
372 | 15675 | nrow += 1; | |
373 | } | ||
374 | } | ||
375 | 3135 | } | |
376 | |||
377 | /** | ||
378 | * @brief @copydoc Base::calcDiff(const | ||
379 | * std::shared_ptr<ResidualDataAbstract>& data, const Eigen::Ref<const | ||
380 | * VectorXs>& x) | ||
381 | */ | ||
382 | ✗ | virtual void calcDiff(const std::shared_ptr<ResidualDataAbstract>& data, | |
383 | const Eigen::Ref<const VectorXs>&) override { | ||
384 | ✗ | data->Rx.setZero(); | |
385 | ✗ | data->Ru.setZero(); | |
386 | } | ||
387 | |||
388 | /** | ||
389 | * @brief Create the actuation residual data | ||
390 | * | ||
391 | * @return Actuation residual data | ||
392 | */ | ||
393 | 27948 | virtual std::shared_ptr<ResidualDataAbstract> createData( | |
394 | DataCollectorAbstract* const data) override { | ||
395 | return std::allocate_shared<typename Data::ResidualDataActuation>( | ||
396 | ✗ | Eigen::aligned_allocator<typename Data::ResidualDataActuation>(), | |
397 |
1/2✓ Branch 2 taken 27948 times.
✗ Branch 3 not taken.
|
27948 | this, data); |
398 | } | ||
399 | |||
400 | /** | ||
401 | * @brief Cast the actuation-residual model to a different scalar type. | ||
402 | * | ||
403 | * It is useful for operations requiring different precision or scalar | ||
404 | * types. | ||
405 | * | ||
406 | * @tparam NewScalar The new scalar type to cast to. | ||
407 | * @return | ||
408 | * DifferentialActionModelContactInvDynamicsTpl<NewScalar>::ResidualModelActuation | ||
409 | * A residual model with the new scalar type. | ||
410 | */ | ||
411 | template <typename NewScalar> | ||
412 | typename DifferentialActionModelContactInvDynamicsTpl< | ||
413 | NewScalar>::ResidualModelActuation | ||
414 | ✗ | cast() const { | |
415 | typedef typename DifferentialActionModelContactInvDynamicsTpl< | ||
416 | NewScalar>::ResidualModelActuation ReturnType; | ||
417 | typedef StateMultibodyTpl<NewScalar> StateType; | ||
418 | ✗ | ReturnType ret(std::static_pointer_cast<StateType>( | |
419 | ✗ | state_->template cast<NewScalar>()), | |
420 | ✗ | na_, nc_); | |
421 | ✗ | return ret; | |
422 | } | ||
423 | |||
424 | /** | ||
425 | * @brief Print relevant information of the actuation residual model | ||
426 | * | ||
427 | * @param[out] os Output stream object | ||
428 | */ | ||
429 | ✗ | virtual void print(std::ostream& os) const override { | |
430 | ✗ | os << "ResidualModelActuation {nx=" << state_->get_nx() | |
431 | ✗ | << ", ndx=" << state_->get_ndx() << ", nu=" << nu_ << ", na=" << na_ | |
432 | ✗ | << "}"; | |
433 | } | ||
434 | |||
435 | protected: | ||
436 | using Base::nu_; | ||
437 | using Base::state_; | ||
438 | |||
439 | private: | ||
440 | std::size_t na_; //!< Number of actuated joints | ||
441 | std::size_t nc_; //!< Number of contacts | ||
442 | }; | ||
443 | |||
444 | public: | ||
445 | /** | ||
446 | * @brief Contact-acceleration residual | ||
447 | * | ||
448 | * This residual function is defined as \f$\mathbf{r} = \mathbf{a_0}\f$, where | ||
449 | * \f$\mathbf{a_0}\f$ defines the desired contact acceleration, which might | ||
450 | * also include the Baumgarte stabilization gains. Furthermore, the Jacobians | ||
451 | * of the residual function are computed analytically. This is used by | ||
452 | * `ConstraintModelManagerTpl` inside parent | ||
453 | * `DifferentialActionModelContactInvDynamicsTpl` class. | ||
454 | * | ||
455 | * As described in `ResidualModelAbstractTpl`, the residual value and its | ||
456 | * Jacobians are calculated by `calc` and `calcDiff`, respectively. | ||
457 | * | ||
458 | * \sa `ResidualModelAbstractTpl`, `calc()`, `calcDiff()`, `createData()` | ||
459 | */ | ||
460 | class ResidualModelContact : public ResidualModelAbstractTpl<_Scalar> { | ||
461 | public: | ||
462 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW | ||
463 | ✗ | CROCODDYL_INNER_DERIVED_CAST(ResidualModelBase, | |
464 | DifferentialActionModelContactInvDynamicsTpl, | ||
465 | ResidualModelContact) | ||
466 | |||
467 | typedef _Scalar Scalar; | ||
468 | typedef MathBaseTpl<Scalar> MathBase; | ||
469 | typedef ResidualModelAbstractTpl<Scalar> Base; | ||
470 | typedef StateMultibodyTpl<Scalar> StateMultibody; | ||
471 | typedef ResidualDataAbstractTpl<Scalar> ResidualDataAbstract; | ||
472 | typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract; | ||
473 | typedef typename MathBase::VectorXs VectorXs; | ||
474 | typedef typename MathBase::MatrixXs MatrixXs; | ||
475 | |||
476 | /** | ||
477 | * @brief Initialize the contact-acceleration residual model | ||
478 | * | ||
479 | * @param[in] state State of the multibody system | ||
480 | * @param[in] id Contact frame id | ||
481 | * @param[in] nr Dimension of the contact-acceleration residual | ||
482 | * @param[in] nc Dimension of all contacts | ||
483 | */ | ||
484 | 700 | ResidualModelContact(std::shared_ptr<StateMultibody> state, | |
485 | const pinocchio::FrameIndex id, const std::size_t nr, | ||
486 | const std::size_t nc) | ||
487 | 700 | : Base(state, nr, state->get_nv() + nc, true, true, true), | |
488 | 700 | id_(id), | |
489 |
2/4✓ Branch 1 taken 700 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 700 times.
✗ Branch 7 not taken.
|
700 | frame_name_(state->get_pinocchio()->frames[id].name), |
490 |
1/2✓ Branch 3 taken 700 times.
✗ Branch 4 not taken.
|
2100 | nc_(nc) {} |
491 | 1400 | virtual ~ResidualModelContact() = default; | |
492 | |||
493 | /** | ||
494 | * @brief Compute the contact-acceleration residual | ||
495 | * | ||
496 | * @param[in] data Contact-acceleration residual data | ||
497 | * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$ | ||
498 | * @param[in] u Control input \f$\mathbf{u}\in\mathbb{R}^{nv+nu}\f$ | ||
499 | */ | ||
500 | 63366 | void calc(const std::shared_ptr<ResidualDataAbstract>& data, | |
501 | const Eigen::Ref<const VectorXs>&, | ||
502 | const Eigen::Ref<const VectorXs>&) override { | ||
503 | typename Data::ResidualDataContact* d = | ||
504 | 63366 | static_cast<typename Data::ResidualDataContact*>(data.get()); | |
505 | 63366 | d->r = d->contact->a0; | |
506 | 63366 | } | |
507 | |||
508 | /** | ||
509 | * @brief @copydoc Base::calc(const std::shared_ptr<ResidualDataAbstract>& | ||
510 | * data, const Eigen::Ref<const VectorXs>& x) | ||
511 | */ | ||
512 | ✗ | virtual void calc(const std::shared_ptr<ResidualDataAbstract>& data, | |
513 | const Eigen::Ref<const VectorXs>&) override { | ||
514 | ✗ | data->r.setZero(); | |
515 | } | ||
516 | |||
517 | /** | ||
518 | * @brief Compute the derivatives of the contact-acceleration residual | ||
519 | * | ||
520 | * @param[in] data Contact-acceleration residual data | ||
521 | * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$ | ||
522 | * @param[in] u Control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$ | ||
523 | */ | ||
524 | 8778 | void calcDiff(const std::shared_ptr<ResidualDataAbstract>& data, | |
525 | const Eigen::Ref<const VectorXs>&, | ||
526 | const Eigen::Ref<const VectorXs>&) override { | ||
527 | typename Data::ResidualDataContact* d = | ||
528 | 8778 | static_cast<typename Data::ResidualDataContact*>(data.get()); | |
529 | 8778 | d->Rx = d->contact->da0_dx; | |
530 |
1/2✓ Branch 4 taken 8778 times.
✗ Branch 5 not taken.
|
8778 | d->Ru.leftCols(state_->get_nv()) = d->contact->Jc; |
531 | 8778 | } | |
532 | |||
533 | /** | ||
534 | * @brief @copydoc Base::calcDiff(const | ||
535 | * std::shared_ptr<ResidualDataAbstract>& data, const Eigen::Ref<const | ||
536 | * VectorXs>& x) | ||
537 | */ | ||
538 | ✗ | virtual void calcDiff(const std::shared_ptr<ResidualDataAbstract>& data, | |
539 | const Eigen::Ref<const VectorXs>&) override { | ||
540 | ✗ | data->Rx.setZero(); | |
541 | ✗ | data->Ru.setZero(); | |
542 | } | ||
543 | |||
544 | /** | ||
545 | * @brief Create the contact-acceleration residual data | ||
546 | * | ||
547 | * @return contact-acceleration residual data | ||
548 | */ | ||
549 | 76196 | virtual std::shared_ptr<ResidualDataAbstract> createData( | |
550 | DataCollectorAbstract* const data) override { | ||
551 | return std::allocate_shared<typename Data::ResidualDataContact>( | ||
552 | ✗ | Eigen::aligned_allocator<typename Data::ResidualDataContact>(), this, | |
553 |
1/2✓ Branch 2 taken 76196 times.
✗ Branch 3 not taken.
|
76196 | data, id_); |
554 | } | ||
555 | |||
556 | /** | ||
557 | * @brief Cast the contact-residual model to a different scalar type. | ||
558 | * | ||
559 | * It is useful for operations requiring different precision or scalar | ||
560 | * types. | ||
561 | * | ||
562 | * @tparam NewScalar The new scalar type to cast to. | ||
563 | * @return typename | ||
564 | * DifferentialActionModelContactInvDynamicsTpl<NewScalar>::ResidualModelContact | ||
565 | * A residual model with the new scalar type. | ||
566 | */ | ||
567 | template <typename NewScalar> | ||
568 | typename DifferentialActionModelContactInvDynamicsTpl< | ||
569 | NewScalar>::ResidualModelContact | ||
570 | ✗ | cast() const { | |
571 | typedef typename DifferentialActionModelContactInvDynamicsTpl< | ||
572 | NewScalar>::ResidualModelContact ReturnType; | ||
573 | typedef StateMultibodyTpl<NewScalar> StateType; | ||
574 | ✗ | ReturnType ret(std::static_pointer_cast<StateType>( | |
575 | ✗ | state_->template cast<NewScalar>()), | |
576 | ✗ | id_, nr_, nc_); | |
577 | ✗ | return ret; | |
578 | } | ||
579 | |||
580 | /** | ||
581 | * @brief Print relevant information of the contact-acceleration residual | ||
582 | * model | ||
583 | * | ||
584 | * @param[out] os Output stream object | ||
585 | */ | ||
586 | ✗ | virtual void print(std::ostream& os) const override { | |
587 | ✗ | os << "ResidualModelContact {frame=" << frame_name_ << ", nr=" << nr_ | |
588 | ✗ | << "}"; | |
589 | } | ||
590 | |||
591 | protected: | ||
592 | using Base::nr_; | ||
593 | using Base::nu_; | ||
594 | using Base::state_; | ||
595 | |||
596 | private: | ||
597 | pinocchio::FrameIndex id_; //!< Reference frame id | ||
598 | std::string frame_name_; //!< Reference frame name | ||
599 | std::size_t nc_; //!< Dimension of all contacts | ||
600 | }; | ||
601 | }; | ||
602 | template <typename _Scalar> | ||
603 | struct DifferentialActionDataContactInvDynamicsTpl | ||
604 | : public DifferentialActionDataAbstractTpl<_Scalar> { | ||
605 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW | ||
606 | typedef _Scalar Scalar; | ||
607 | typedef MathBaseTpl<Scalar> MathBase; | ||
608 | typedef DifferentialActionDataAbstractTpl<Scalar> Base; | ||
609 | typedef JointDataAbstractTpl<Scalar> JointDataAbstract; | ||
610 | typedef DataCollectorJointActMultibodyInContactTpl<Scalar> | ||
611 | DataCollectorJointActMultibodyInContact; | ||
612 | typedef CostDataSumTpl<Scalar> CostDataSum; | ||
613 | typedef ConstraintDataManagerTpl<Scalar> ConstraintDataManager; | ||
614 | typedef ContactModelMultipleTpl<Scalar> ContactModelMultiple; | ||
615 | typedef ContactItemTpl<Scalar> ContactItem; | ||
616 | typedef typename MathBase::VectorXs VectorXs; | ||
617 | typedef typename MathBase::MatrixXs MatrixXs; | ||
618 | |||
619 | template <template <typename Scalar> class Model> | ||
620 | 31432 | explicit DifferentialActionDataContactInvDynamicsTpl( | |
621 | Model<Scalar>* const model) | ||
622 | : Base(model), | ||
623 |
1/2✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
|
31432 | pinocchio(pinocchio::DataTpl<Scalar>(model->get_pinocchio())), |
624 |
4/8✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 31430 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 31430 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 31430 times.
✗ Branch 11 not taken.
|
94296 | multibody( |
625 |
2/4✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 31430 times.
✗ Branch 6 not taken.
|
31432 | &pinocchio, model->get_actuation()->createData(), |
626 | std::make_shared<JointDataAbstract>( | ||
627 |
2/4✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 31430 times.
✗ Branch 5 not taken.
|
62864 | model->get_state(), model->get_actuation(), model->get_nu()), |
628 |
1/2✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
|
31432 | model->get_contacts()->createData(&pinocchio)), |
629 |
3/6✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 31430 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 31430 times.
✗ Branch 9 not taken.
|
31432 | tmp_xstatic(model->get_state()->get_nx()), |
630 |
2/4✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 31430 times.
✗ Branch 6 not taken.
|
31432 | tmp_rstatic(model->get_actuation()->get_nu() + |
631 |
3/6✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 31430 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 31430 times.
✗ Branch 9 not taken.
|
31432 | model->get_contacts()->get_nc()), |
632 |
2/4✓ Branch 2 taken 31430 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 31430 times.
✗ Branch 6 not taken.
|
31432 | tmp_Jstatic(model->get_state()->get_nv(), |
633 |
2/4✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 31430 times.
✗ Branch 6 not taken.
|
31432 | model->get_actuation()->get_nu() + |
634 |
4/8✓ Branch 2 taken 31430 times.
✗ Branch 3 not taken.
✓ Branch 7 taken 31430 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 31430 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 31430 times.
✗ Branch 15 not taken.
|
94296 | model->get_contacts()->get_nc()) { |
635 | // Set constant values for Fu, df_dx, and df_du | ||
636 |
2/4✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 31430 times.
✗ Branch 6 not taken.
|
31432 | const std::size_t nv = model->get_state()->get_nv(); |
637 |
2/4✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 31430 times.
✗ Branch 6 not taken.
|
31432 | const std::size_t nc = model->get_contacts()->get_nc_total(); |
638 |
3/6✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 31430 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 31430 times.
✗ Branch 8 not taken.
|
31432 | Fu.leftCols(nv).diagonal().setOnes(); |
639 |
3/6✓ Branch 2 taken 31430 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 31430 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 31430 times.
✗ Branch 9 not taken.
|
31432 | multibody.joint->da_du.leftCols(nv).diagonal().setOnes(); |
640 |
4/8✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 31430 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 31430 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 31430 times.
✗ Branch 12 not taken.
|
31432 | MatrixXs df_dx = MatrixXs::Zero(nc, model->get_state()->get_ndx()); |
641 |
3/6✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 31430 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 31430 times.
✗ Branch 8 not taken.
|
31432 | MatrixXs df_du = MatrixXs::Zero(nc, model->get_nu()); |
642 | 31432 | std::size_t fid = 0; | |
643 | 31432 | for (typename ContactModelMultiple::ContactModelContainer::const_iterator | |
644 |
2/4✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 31430 times.
✗ Branch 6 not taken.
|
31432 | it = model->get_contacts()->get_contacts().begin(); |
645 |
4/6✓ Branch 1 taken 107626 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 107626 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 76196 times.
✓ Branch 10 taken 31430 times.
|
107628 | it != model->get_contacts()->get_contacts().end(); ++it) { |
646 |
1/2✓ Branch 4 taken 76196 times.
✗ Branch 5 not taken.
|
76196 | const std::size_t nc = it->second->contact->get_nc(); |
647 |
3/6✓ Branch 1 taken 76196 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 76196 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 76196 times.
✗ Branch 8 not taken.
|
76196 | df_du.block(fid, nv + fid, nc, nc).diagonal().setOnes(); |
648 | 76196 | fid += nc; | |
649 | } | ||
650 | 31432 | std::vector<bool> contact_status; | |
651 | 31432 | for (typename ContactModelMultiple::ContactModelContainer::const_iterator | |
652 |
2/4✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 31430 times.
✗ Branch 6 not taken.
|
31432 | it = model->get_contacts()->get_contacts().begin(); |
653 |
4/6✓ Branch 1 taken 107626 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 107626 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 76196 times.
✓ Branch 10 taken 31430 times.
|
107628 | it != model->get_contacts()->get_contacts().end(); ++it) { |
654 | 76196 | const std::shared_ptr<ContactItem>& m_i = it->second; | |
655 |
1/2✓ Branch 2 taken 76196 times.
✗ Branch 3 not taken.
|
76196 | contact_status.push_back(m_i->active); |
656 | 76196 | m_i->active = true; | |
657 | } | ||
658 |
2/4✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 31430 times.
✗ Branch 6 not taken.
|
31432 | model->get_contacts()->updateForceDiff(multibody.contacts, df_dx, df_du); |
659 | 31432 | std::size_t cid = 0; | |
660 | 31432 | for (typename ContactModelMultiple::ContactModelContainer::const_iterator | |
661 |
2/4✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 31430 times.
✗ Branch 6 not taken.
|
31432 | it = model->get_contacts()->get_contacts().begin(); |
662 |
4/6✓ Branch 1 taken 107626 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 107626 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 76196 times.
✓ Branch 10 taken 31430 times.
|
107628 | it != model->get_contacts()->get_contacts().end(); ++it) { |
663 | 76196 | const std::shared_ptr<ContactItem>& m_i = it->second; | |
664 |
1/2✓ Branch 1 taken 76196 times.
✗ Branch 2 not taken.
|
76196 | m_i->active = contact_status[cid]; |
665 | 76196 | cid++; | |
666 | } | ||
667 |
2/4✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 31430 times.
✗ Branch 6 not taken.
|
31432 | costs = model->get_costs()->createData(&multibody); |
668 |
2/4✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 31430 times.
✗ Branch 6 not taken.
|
31432 | constraints = model->get_constraints()->createData(&multibody); |
669 |
1/2✓ Branch 2 taken 31430 times.
✗ Branch 3 not taken.
|
31432 | costs->shareMemory(this); |
670 |
1/2✓ Branch 2 taken 31430 times.
✗ Branch 3 not taken.
|
31432 | constraints->shareMemory(this); |
671 | |||
672 |
1/2✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
|
31432 | tmp_xstatic.setZero(); |
673 |
1/2✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
|
31432 | tmp_rstatic.setZero(); |
674 |
1/2✓ Branch 1 taken 31430 times.
✗ Branch 2 not taken.
|
31432 | tmp_Jstatic.setZero(); |
675 | 31432 | } | |
676 | 62860 | virtual ~DifferentialActionDataContactInvDynamicsTpl() = default; | |
677 | |||
678 | pinocchio::DataTpl<Scalar> pinocchio; //!< Pinocchio data | ||
679 | DataCollectorJointActMultibodyInContact multibody; //!< Multibody data | ||
680 | std::shared_ptr<CostDataSum> costs; //!< Costs data | ||
681 | std::shared_ptr<ConstraintDataManager> constraints; //!< Constraints data | ||
682 | VectorXs | ||
683 | tmp_xstatic; //!< State point used for computing the quasi-static input | ||
684 | VectorXs | ||
685 | tmp_rstatic; //!< Factorization used for computing the quasi-static input | ||
686 | MatrixXs tmp_Jstatic; //!< Jacobian used for computing the quasi-static input | ||
687 | |||
688 | using Base::cost; | ||
689 | using Base::Fu; | ||
690 | using Base::Fx; | ||
691 | using Base::Lu; | ||
692 | using Base::Luu; | ||
693 | using Base::Lx; | ||
694 | using Base::Lxu; | ||
695 | using Base::Lxx; | ||
696 | using Base::r; | ||
697 | using Base::xout; | ||
698 | |||
699 | struct ResidualDataActuation : public ResidualDataAbstractTpl<_Scalar> { | ||
700 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW | ||
701 | |||
702 | typedef _Scalar Scalar; | ||
703 | typedef MathBaseTpl<Scalar> MathBase; | ||
704 | typedef ResidualDataAbstractTpl<Scalar> Base; | ||
705 | typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract; | ||
706 | typedef DataCollectorActMultibodyInContactTpl<Scalar> | ||
707 | DataCollectorActMultibodyInContact; | ||
708 | typedef ActuationDataAbstractTpl<Scalar> ActuationDataAbstract; | ||
709 | typedef ContactDataMultipleTpl<Scalar> ContactDataMultiple; | ||
710 | typedef typename MathBase::MatrixXs MatrixXs; | ||
711 | |||
712 | template <template <typename Scalar> class Model> | ||
713 | 27950 | ResidualDataActuation(Model<Scalar>* const model, | |
714 | DataCollectorAbstract* const data) | ||
715 | : Base(model, data), | ||
716 |
5/10✓ Branch 1 taken 27948 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 27948 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 27948 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 27948 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 27948 times.
✗ Branch 16 not taken.
|
27950 | dtau_dx(model->get_state()->get_nv(), model->get_state()->get_ndx()), |
717 |
4/8✓ Branch 4 taken 27948 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 27948 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 27948 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 27948 times.
✗ Branch 15 not taken.
|
55900 | dtau_du(model->get_state()->get_nv(), model->get_nu()) { |
718 | // Check that proper shared data has been passed | ||
719 | 27950 | DataCollectorActMultibodyInContact* d = | |
720 |
1/2✓ Branch 0 taken 27948 times.
✗ Branch 1 not taken.
|
27950 | dynamic_cast<DataCollectorActMultibodyInContact*>(shared); |
721 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 27948 times.
|
27950 | if (d == NULL) { |
722 | ✗ | throw_pretty( | |
723 | "Invalid argument: the shared data should be derived from " | ||
724 | "DataCollectorActMultibodyInContact"); | ||
725 | } | ||
726 | // Avoids data casting at runtime | ||
727 | 27950 | pinocchio = d->pinocchio; | |
728 | 27950 | actuation = d->actuation; | |
729 | 27950 | contact = d->contacts; | |
730 |
1/2✓ Branch 1 taken 27948 times.
✗ Branch 2 not taken.
|
27950 | dtau_dx.setZero(); |
731 |
1/2✓ Branch 1 taken 27948 times.
✗ Branch 2 not taken.
|
27950 | dtau_du.setZero(); |
732 | 27950 | } | |
733 | 55894 | virtual ~ResidualDataActuation() = default; | |
734 | |||
735 | pinocchio::DataTpl<Scalar>* pinocchio; //!< Pinocchio data | ||
736 | std::shared_ptr<ActuationDataAbstract> actuation; //!< Actuation data | ||
737 | std::shared_ptr<ContactDataMultiple> contact; //!< Contact data | ||
738 | MatrixXs dtau_dx; | ||
739 | MatrixXs dtau_du; | ||
740 | using Base::r; | ||
741 | using Base::Ru; | ||
742 | using Base::Rx; | ||
743 | using Base::shared; | ||
744 | }; | ||
745 | |||
746 | struct ResidualDataContact : public ResidualDataAbstractTpl<_Scalar> { | ||
747 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW | ||
748 | |||
749 | typedef _Scalar Scalar; | ||
750 | typedef MathBaseTpl<Scalar> MathBase; | ||
751 | typedef ResidualDataAbstractTpl<Scalar> Base; | ||
752 | typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract; | ||
753 | typedef DataCollectorMultibodyInContactTpl<Scalar> | ||
754 | DataCollectorMultibodyInContact; | ||
755 | typedef ContactModelMultipleTpl<Scalar> ContactModelMultiple; | ||
756 | |||
757 | template <template <typename Scalar> class Model> | ||
758 | 76196 | ResidualDataContact(Model<Scalar>* const model, | |
759 | DataCollectorAbstract* const data, const std::size_t id) | ||
760 | 76196 | : Base(model, data) { | |
761 | 76196 | DataCollectorMultibodyInContact* d = | |
762 |
1/2✓ Branch 0 taken 76196 times.
✗ Branch 1 not taken.
|
76196 | dynamic_cast<DataCollectorMultibodyInContact*>(shared); |
763 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 76196 times.
|
76196 | if (d == NULL) { |
764 | ✗ | throw_pretty( | |
765 | "Invalid argument: the shared data should be derived from " | ||
766 | "DataCollectorMultibodyInContact"); | ||
767 | } | ||
768 | 76196 | typename ContactModelMultiple::ContactDataContainer::iterator it, end; | |
769 | 152392 | for (it = d->contacts->contacts.begin(), | |
770 | 76196 | end = d->contacts->contacts.end(); | |
771 |
1/2✓ Branch 2 taken 151420 times.
✗ Branch 3 not taken.
|
151420 | it != end; ++it) { |
772 |
2/2✓ Branch 2 taken 76196 times.
✓ Branch 3 taken 75224 times.
|
151420 | if (id == it->second->frame) { // TODO(cmastalli): use model->get_id() |
773 | // and avoid to pass id in constructor | ||
774 | 76196 | contact = it->second.get(); | |
775 | 76196 | break; | |
776 | } | ||
777 | } | ||
778 | 76196 | } | |
779 | 152392 | virtual ~ResidualDataContact() = default; | |
780 | |||
781 | ContactDataAbstractTpl<Scalar>* contact; //!< Contact force data | ||
782 | using Base::r; | ||
783 | using Base::Ru; | ||
784 | using Base::Rx; | ||
785 | using Base::shared; | ||
786 | }; | ||
787 | }; | ||
788 | } // namespace crocoddyl | ||
789 | |||
790 | /* --- Details -------------------------------------------------------------- */ | ||
791 | /* --- Details -------------------------------------------------------------- */ | ||
792 | /* --- Details -------------------------------------------------------------- */ | ||
793 | #include <crocoddyl/multibody/actions/contact-invdyn.hxx> | ||
794 | |||
795 | CROCODDYL_DECLARE_EXTERN_TEMPLATE_CLASS( | ||
796 | crocoddyl::DifferentialActionModelContactInvDynamicsTpl) | ||
797 | CROCODDYL_DECLARE_EXTERN_TEMPLATE_STRUCT( | ||
798 | crocoddyl::DifferentialActionDataContactInvDynamicsTpl) | ||
799 | |||
800 | #endif // CROCODDYL_MULTIBODY_ACTIONS_CONTACT_INVDYN_HPP_ | ||
801 |