pinocchio  3.7.0
A fast and flexible implementation of Rigid Body Dynamics algorithms and their analytical derivatives
 
Loading...
Searching...
No Matches
casadi-algo.hpp
1//
2// Copyright (c) 2021 INRIA
3//
4
5#ifndef __pinocchio_autodiff_code_generator_algo_hpp__
6#define __pinocchio_autodiff_code_generator_algo_hpp__
7
8#include <casadi/core/casadi_types.hpp>
9#include <casadi/core/code_generator.hpp>
10
11#include "pinocchio/autodiff/casadi.hpp"
12#include "pinocchio/algorithm/aba.hpp"
13#include "pinocchio/algorithm/aba-derivatives.hpp"
14#include "pinocchio/algorithm/joint-configuration.hpp"
15#include "pinocchio/algorithm/constrained-dynamics-derivatives.hpp"
16#include "pinocchio/algorithm/constrained-dynamics.hpp"
17
18namespace pinocchio
19{
20 namespace casadi
21 {
22
23 template<typename _Scalar>
25 {
26 typedef _Scalar Scalar;
27 typedef ::casadi::SX ADScalar;
28 typedef ::casadi::SXVector ADSVector;
29 typedef ::casadi::DM DMMatrix;
30 typedef ::casadi::DMVector DMVector;
31 enum
32 {
33 Options = 0
34 };
35
40
41 typedef typename Model::ConfigVectorType ConfigVectorType;
42 typedef typename Model::TangentVectorType TangentVectorType;
43 typedef typename ADModel::ConfigVectorType ADConfigVectorType;
44 typedef typename ADModel::TangentVectorType ADTangentVectorType;
45
46 typedef typename Data::MatrixXs MatrixXs;
47 typedef typename Data::VectorXs VectorXs;
48 typedef typename Data::RowMatrixXs RowMatrixXs;
49
50 typedef ::casadi::Function ADFun;
51
53 const Model & model,
54 const std::string & filename,
55 const std::string & libname,
56 const std::string & fun_name)
57 : ad_model(model.template cast<ADScalar>())
58 , ad_data(ad_model)
59 , filename(filename)
60 , libname(libname)
61 , fun_name(fun_name)
62 , cg_generated(filename)
63 , build_forward(true)
64 , build_jacobian(true)
65 {
66 }
67
68 virtual ~AutoDiffAlgoBase()
69 {
70 }
71
73 virtual void buildMap() = 0;
74
75 void initLib()
76 {
77 buildMap();
78 // Generated code;
79 cg_generated.add(ad_fun);
80 fun_operation_count = ad_fun.n_instructions() - ad_fun.nnz_in() - ad_fun.nnz_out();
82 {
83 cg_generated.add(ad_fun_derivs);
84 fun_derivs_operation_count =
85 ad_fun_derivs.n_instructions() - ad_fun_derivs.nnz_in() - ad_fun_derivs.nnz_out();
86 }
87 cg_generated.generate();
88 }
89
90 bool existLib() const
91 {
92 std::ifstream file((libname + ".so").c_str());
93 return file.good();
94 }
95
96 void compileLib()
97 {
98 std::string compile_command =
99 "clang -fPIC -shared -Ofast -DNDEBUG " + filename + ".c -o " + libname + ".so";
100
101#ifdef __APPLE__
102 compile_command += " -isysroot "
103 "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/"
104 "Developer/SDKs/MacOSX.sdk";
105#endif
106
107 const int flag = system(compile_command.c_str());
108 if (flag != 0)
109 {
110 std::cerr << "Compilation failed" << std::endl; // TODO: raised here
111 }
112 }
113
114 void loadLib(const bool generate_if_not_exist = true)
115 {
116 if (!existLib() && generate_if_not_exist)
117 compileLib();
118
119 fun = ::casadi::external(fun_name, "./" + libname + ".so");
120 if (build_jacobian)
121 {
122 fun_derivs = ::casadi::external(fun_name + "_derivs", "./" + libname + ".so");
123 }
124 }
125
126 casadi_int getFunOperationCount() const
127 {
128 return fun_operation_count;
129 }
130
131 casadi_int getFunDerivsOperationCount() const
132 {
133 return fun_derivs_operation_count;
134 }
135
136 protected:
137 ADModel ad_model;
138 ADData ad_data;
139 std::string filename, libname, fun_name;
140 ::casadi::CodeGenerator cg_generated;
141
146
147 ADFun ad_fun, ad_fun_derivs;
148 ADFun fun, fun_derivs;
149 std::vector<DMMatrix> fun_output, fun_output_derivs;
150 casadi_int fun_operation_count, fun_derivs_operation_count;
151 };
152
153 template<typename _Scalar>
154 struct AutoDiffABA : public AutoDiffAlgoBase<_Scalar>
155 {
157 typedef typename Base::Scalar Scalar;
158
159 typedef typename Base::TangentVectorType TangentVectorType;
160 typedef typename Base::RowMatrixXs RowMatrixXs;
161 typedef typename Base::VectorXs VectorXs;
162 typedef typename Base::MatrixXs MatrixXs;
163
164 typedef typename Base::ADFun ADFun;
165 typedef typename Base::DMVector DMVector;
166 typedef typename Base::DMMatrix DMMatrix;
167 typedef typename Base::ADScalar ADScalar;
168 typedef typename Base::ADSVector ADSVector;
169 typedef typename Base::ADConfigVectorType ADConfigVectorType;
170 typedef typename Base::ADTangentVectorType ADTangentVectorType;
171
172 explicit AutoDiffABA(
173 const Model & model,
174 const std::string & filename = "casadi_aba",
175 const std::string & libname = "libcasadi_cg_aba",
176 const std::string & fun_name = "eval_f")
177 : Base(model, filename, libname, fun_name)
178 , ddq(model.nv)
179 , ddq_dq(model.nv, model.nv)
180 , ddq_dv(model.nv, model.nv)
181 , ddq_dtau(model.nv, model.nv)
182 , cs_q(ADScalar::sym("q", model.nq))
183 , cs_v(ADScalar::sym("v", model.nv))
184 , cs_tau(ADScalar::sym("tau", model.nv))
185 , cs_v_int(ADScalar::sym("v_inc", model.nv))
186 , cs_ddq(model.nv, 1)
187 , q_ad(model.nq)
188 , q_int_ad(model.nq)
189 , v_ad(model.nv)
190 , v_int_ad(model.nv)
191 , tau_ad(model.nv)
192 , q_vec((size_t)model.nq)
193 , v_vec((size_t)model.nv)
194 , v_int_vec((size_t)model.nv)
195 , tau_vec((size_t)model.nv)
196 {
197 q_ad = Eigen::Map<ADConfigVectorType>(
198 static_cast<std::vector<ADScalar>>(cs_q).data(), model.nq, 1);
199 v_int_ad = Eigen::Map<ADConfigVectorType>(
200 static_cast<std::vector<ADScalar>>(cs_v_int).data(), model.nv, 1);
201 v_ad = Eigen::Map<ADTangentVectorType>(
202 static_cast<std::vector<ADScalar>>(cs_v).data(), model.nv, 1);
203 tau_ad = Eigen::Map<ADTangentVectorType>(
204 static_cast<std::vector<ADScalar>>(cs_tau).data(), model.nv, 1);
205
206 Eigen::Map<TangentVectorType>(v_int_vec.data(), model.nv, 1).setZero();
207 }
208
209 virtual ~AutoDiffABA()
210 {
211 }
212
213 virtual void buildMap()
214 {
215 // Integrate q + v_int = q_int
216 pinocchio::integrate(ad_model, q_ad, v_int_ad, q_int_ad);
217 // Run ABA with new q_int
218 pinocchio::aba(ad_model, ad_data, q_int_ad, v_ad, tau_ad, Convention::WORLD);
219 // Copy Output
220 pinocchio::casadi::copy(ad_data.ddq, cs_ddq);
221
222 cs_ddq_dq = jacobian(cs_ddq, cs_v_int);
223 cs_ddq_dv = jacobian(cs_ddq, cs_v);
224 cs_ddq_dtau = jacobian(cs_ddq, cs_tau);
225
226 ad_fun = ADFun(fun_name, ADSVector{cs_q, cs_v_int, cs_v, cs_tau}, ADSVector{cs_ddq});
227
228 ad_fun_derivs = ADFun(
229 fun_name + "_derivs", ADSVector{cs_q, cs_v_int, cs_v, cs_tau},
230 ADSVector{cs_ddq_dq, cs_ddq_dv, cs_ddq_dtau});
231 }
232
233 template<typename ConfigVectorType1, typename TangentVectorType1, typename TangentVectorType2>
234 void evalFunction(
235 const Eigen::MatrixBase<ConfigVectorType1> & q,
236 const Eigen::MatrixBase<TangentVectorType1> & v,
237 const Eigen::MatrixBase<TangentVectorType2> & tau)
238 {
239 Eigen::Map<ConfigVectorType1>(q_vec.data(), ad_model.nq, 1) = q;
240 Eigen::Map<TangentVectorType1>(v_vec.data(), ad_model.nv, 1) = v;
241 Eigen::Map<TangentVectorType2>(tau_vec.data(), ad_model.nv, 1) = tau;
242 fun_output = fun(DMVector{q_vec, v_int_vec, v_vec, tau_vec});
243 ddq = Eigen::Map<TangentVectorType>(
244 static_cast<std::vector<Scalar>>(fun_output[0]).data(), ad_model.nv, 1);
245 }
246
247 template<typename ConfigVectorType1, typename TangentVectorType1, typename TangentVectorType2>
248 void evalJacobian(
249 const Eigen::MatrixBase<ConfigVectorType1> & q,
250 const Eigen::MatrixBase<TangentVectorType1> & v,
251 const Eigen::MatrixBase<TangentVectorType2> & tau)
252 {
253 Eigen::Map<ConfigVectorType1>(q_vec.data(), ad_model.nq, 1) = q;
254 Eigen::Map<TangentVectorType1>(v_vec.data(), ad_model.nv, 1) = v;
255 Eigen::Map<TangentVectorType2>(tau_vec.data(), ad_model.nv, 1) = tau;
256 fun_output_derivs = fun_derivs(DMVector{q_vec, v_int_vec, v_vec, tau_vec});
257
258 ddq_dq = Eigen::Map<MatrixXs>(
259 static_cast<std::vector<Scalar>>(fun_output_derivs[0]).data(), ad_model.nv, ad_model.nv);
260 ddq_dv = Eigen::Map<MatrixXs>(
261 static_cast<std::vector<Scalar>>(fun_output_derivs[1]).data(), ad_model.nv, ad_model.nv);
262 ddq_dtau = Eigen::Map<MatrixXs>(
263 static_cast<std::vector<Scalar>>(fun_output_derivs[2]).data(), ad_model.nv, ad_model.nv);
264 }
265
266 TangentVectorType ddq;
267 RowMatrixXs ddq_dq, ddq_dv, ddq_dtau;
268
269 protected:
270 using Base::ad_data;
271 using Base::ad_model;
272 using Base::cg_generated;
273 using Base::filename;
274 using Base::fun_name;
275 using Base::libname;
276
277 using Base::ad_fun;
278 using Base::ad_fun_derivs;
279 using Base::fun;
280 using Base::fun_derivs;
281 using Base::fun_output;
282 using Base::fun_output_derivs;
283
284 ADScalar cs_q, cs_v, cs_tau, cs_v_int, cs_ddq;
285
286 // Derivatives
287 ADScalar cs_ddq_dq, cs_ddq_dv, cs_ddq_dtau;
288
289 ADConfigVectorType q_ad, q_int_ad;
290 ADTangentVectorType v_ad, v_int_ad, tau_ad;
291
292 std::vector<Scalar> q_vec, v_vec, v_int_vec, tau_vec;
293 };
294
295 template<typename _Scalar>
297 {
298
300 typedef typename Base::Scalar Scalar;
301
302 typedef typename Base::TangentVectorType TangentVectorType;
303 typedef typename Base::RowMatrixXs RowMatrixXs;
304 typedef typename Base::VectorXs VectorXs;
305 typedef typename Base::MatrixXs MatrixXs;
306
307 typedef typename Base::ADFun ADFun;
308 typedef typename Base::DMVector DMVector;
309 typedef typename Base::DMMatrix DMMatrix;
310 typedef typename Base::ADScalar ADScalar;
311 typedef typename Base::ADSVector ADSVector;
312 typedef typename Base::ADConfigVectorType ADConfigVectorType;
313 typedef typename Base::ADTangentVectorType ADTangentVectorType;
314
315 explicit AutoDiffABADerivatives(
316 const Model & model,
317 const std::string & filename = "casadi_abaDerivs",
318 const std::string & libname = "libcasadi_cg_abaDerivs",
319 const std::string & fun_name = "eval_f")
320 : Base(model, filename, libname, fun_name)
321 , cs_q(ADScalar::sym("q", model.nq))
322 , cs_v(ADScalar::sym("v", model.nv))
323 , cs_tau(ADScalar::sym("tau", model.nv))
324 , q_ad(model.nq)
325 , v_ad(model.nv)
326 , tau_ad(model.nv)
327 , cs_ddq(model.nv, 1)
328 , q_vec((size_t)model.nq)
329 , v_vec((size_t)model.nv)
330 , tau_vec((size_t)model.nv)
331 , ddq(model.nv)
332 , ddq_dq(model.nv, model.nv)
333 , ddq_dv(model.nv, model.nv)
334 , ddq_dtau(model.nv, model.nv)
335 {
336 q_ad = Eigen::Map<ADConfigVectorType>(
337 static_cast<std::vector<ADScalar>>(cs_q).data(), model.nq, 1);
338 v_ad = Eigen::Map<ADTangentVectorType>(
339 static_cast<std::vector<ADScalar>>(cs_v).data(), model.nv, 1);
340 tau_ad = Eigen::Map<ADTangentVectorType>(
341 static_cast<std::vector<ADScalar>>(cs_tau).data(), model.nv, 1);
342
343 Base::build_jacobian = false;
344 }
345
347 {
348 }
349
350 virtual void buildMap()
351 {
352 // Run ABA with new q_int
353 pinocchio::computeABADerivatives(ad_model, ad_data, q_ad, v_ad, tau_ad);
354 // Copy Output
355 ad_data.Minv.template triangularView<Eigen::StrictlyLower>() =
356 ad_data.Minv.transpose().template triangularView<Eigen::StrictlyLower>();
357 pinocchio::casadi::copy(ad_data.ddq, cs_ddq);
358 pinocchio::casadi::copy(ad_data.ddq_dq, cs_ddq_dq);
359 pinocchio::casadi::copy(ad_data.ddq_dv, cs_ddq_dv);
360 pinocchio::casadi::copy(ad_data.Minv, cs_ddq_dtau);
361
362 ad_fun = ADFun(
363 fun_name, ADSVector{cs_q, cs_v, cs_tau},
364 ADSVector{cs_ddq, cs_ddq_dq, cs_ddq_dv, cs_ddq_dtau});
365 }
366
367 template<typename ConfigVectorType1, typename TangentVectorType1, typename TangentVectorType2>
368 void evalFunction(
369 const Eigen::MatrixBase<ConfigVectorType1> & q,
370 const Eigen::MatrixBase<TangentVectorType1> & v,
371 const Eigen::MatrixBase<TangentVectorType2> & tau)
372 {
373 Eigen::Map<ConfigVectorType1>(q_vec.data(), ad_model.nq, 1) = q;
374 Eigen::Map<TangentVectorType1>(v_vec.data(), ad_model.nv, 1) = v;
375 Eigen::Map<TangentVectorType2>(tau_vec.data(), ad_model.nv, 1) = tau;
376 fun_output = fun(DMVector{q_vec, v_vec, tau_vec});
377
378 ddq = Eigen::Map<TangentVectorType>(
379 static_cast<std::vector<Scalar>>(fun_output[0]).data(), ad_model.nv, 1);
380 ddq_dq = Eigen::Map<MatrixXs>(
381 static_cast<std::vector<Scalar>>(fun_output[1]).data(), ad_model.nv, ad_model.nv);
382 ddq_dv = Eigen::Map<MatrixXs>(
383 static_cast<std::vector<Scalar>>(fun_output[2]).data(), ad_model.nv, ad_model.nv);
384 ddq_dtau = Eigen::Map<MatrixXs>(
385 static_cast<std::vector<Scalar>>(fun_output[3]).data(), ad_model.nv, ad_model.nv);
386 }
387
388 TangentVectorType ddq;
389 RowMatrixXs ddq_dq, ddq_dv, ddq_dtau;
390
391 protected:
392 using Base::ad_data;
393 using Base::ad_model;
394 using Base::cg_generated;
395 using Base::filename;
396 using Base::fun_name;
397 using Base::libname;
398
399 using Base::ad_fun;
400 using Base::ad_fun_derivs;
401 using Base::fun;
402 using Base::fun_derivs;
403 using Base::fun_output;
404 using Base::fun_output_derivs;
405
406 ADScalar cs_q, cs_v, cs_tau, cs_ddq;
407 // Derivatives
408 ADScalar cs_ddq_dq, cs_ddq_dv, cs_ddq_dtau;
409
410 ADConfigVectorType q_ad;
411 ADTangentVectorType v_ad, tau_ad;
412 std::vector<Scalar> q_vec, v_vec, tau_vec;
413 };
414
415 template<typename _Scalar>
417 {
419 typedef typename Base::Scalar Scalar;
420 typedef typename Base::ADScalar ADScalar;
421 typedef typename Base::ADSVector ADSVector;
422
423 typedef typename Base::TangentVectorType TangentVectorType;
424 typedef typename Base::RowMatrixXs RowMatrixXs;
425 typedef typename Base::VectorXs VectorXs;
426 typedef typename Base::MatrixXs MatrixXs;
427
428 typedef typename Base::ADFun ADFun;
429 typedef typename Base::DMVector DMVector;
430 typedef typename Base::DMMatrix DMMatrix;
431 typedef typename Base::ADConfigVectorType ADConfigVectorType;
432 typedef typename Base::ADTangentVectorType ADTangentVectorType;
433
435 typedef Eigen::aligned_allocator<ConstraintModel> ConstraintModelAllocator;
436 typedef typename std::vector<ConstraintModel, ConstraintModelAllocator> ConstraintModelVector;
438 typedef Eigen::aligned_allocator<ConstraintData> ConstraintDataAllocator;
439 typedef typename std::vector<ConstraintData, ConstraintDataAllocator> ConstraintDataVector;
440
443 typedef Eigen::aligned_allocator<ADConstraintModel> ADConstraintModelAllocator;
444 typedef typename std::vector<ADConstraintModel, ADConstraintModelAllocator>
445 ADConstraintModelVector;
447 typedef Eigen::aligned_allocator<ADConstraintData> ADConstraintDataAllocator;
448 typedef typename std::vector<ADConstraintData, ADConstraintDataAllocator>
449 ADConstraintDataVector;
450
451 static Eigen::DenseIndex constraintDim(const ConstraintModelVector & contact_models)
452 {
453 Eigen::DenseIndex num_total_constraints = 0;
454 for (typename ConstraintModelVector::const_iterator it = contact_models.begin();
455 it != contact_models.end(); ++it)
456 {
457 PINOCCHIO_CHECK_INPUT_ARGUMENT(
458 it->size() > 0, "The dimension of the constraint must be positive");
459 num_total_constraints += it->size();
460 }
462 }
463
465 const Model & model,
466 const ConstraintModelVector & contact_models,
467 const std::string & filename = "casadi_contactDyn",
468 const std::string & libname = "libcasadi_cg_contactDyn",
469 const std::string & fun_name = "eval_f")
470 : Base(model, filename, libname, fun_name)
471 , nc(constraintDim(contact_models))
472 , cs_q(ADScalar::sym("q", model.nq))
473 , cs_v(ADScalar::sym("v", model.nv))
474 , cs_tau(ADScalar::sym("tau", model.nv))
475 , cs_v_int(ADScalar::sym("v_inc", model.nv))
476 , q_ad(model.nq)
477 , q_int_ad(model.nq)
478 , v_ad(model.nv)
479 , v_int_ad(model.nv)
480 , tau_ad(model.nv)
481 , cs_ddq(model.nv, 1)
482 , cs_lambda_c(model.nv, 1)
483 , q_vec((size_t)model.nq)
484 , v_vec((size_t)model.nv)
485 , v_int_vec((size_t)model.nv)
486 , tau_vec((size_t)model.nv)
487 , ddq(model.nv)
488 , ddq_dq(model.nv, model.nv)
489 , ddq_dv(model.nv, model.nv)
490 , ddq_dtau(model.nv, model.nv)
491 {
492 lambda_c.resize(nc);
493 lambda_c.setZero();
494 dlambda_dq.resize(nc, model.nv);
495 dlambda_dq.setZero();
496 dlambda_dv.resize(nc, model.nv);
497 dlambda_dv.setZero();
498 dlambda_dtau.resize(nc, model.nv);
499 dlambda_dtau.setZero();
500 q_ad = Eigen::Map<ADConfigVectorType>(
501 static_cast<std::vector<ADScalar>>(cs_q).data(), model.nq, 1);
502 v_int_ad = Eigen::Map<ADConfigVectorType>(
503 static_cast<std::vector<ADScalar>>(cs_v_int).data(), model.nv, 1);
504 v_ad = Eigen::Map<ADTangentVectorType>(
505 static_cast<std::vector<ADScalar>>(cs_v).data(), model.nv, 1);
506 tau_ad = Eigen::Map<ADTangentVectorType>(
507 static_cast<std::vector<ADScalar>>(cs_tau).data(), model.nv, 1);
508
509 Eigen::Map<TangentVectorType>(v_int_vec.data(), model.nv, 1).setZero();
510
511 for (int k = 0; k < contact_models.size(); ++k)
512 {
513 ad_contact_models.push_back(contact_models[k].template cast<ADScalar>());
514 ad_contact_datas.push_back(ADConstraintData(ad_contact_models[k]));
515 }
516 }
517
519 {
520 }
521
522 virtual void buildMap()
523 {
524 pinocchio::initConstraintDynamics(ad_model, ad_data, ad_contact_models);
525 // Integrate q + v_int = q_int
526 pinocchio::integrate(ad_model, q_ad, v_int_ad, q_int_ad);
527 // Run contact dynamics with new q_int
529 ad_model, ad_data, q_int_ad, v_ad, tau_ad, ad_contact_models, ad_contact_datas);
530 // Copy Output
531 pinocchio::casadi::copy(ad_data.ddq, cs_ddq);
532 pinocchio::casadi::copy(ad_data.lambda_c, cs_lambda_c);
533
534 cs_ddq_dq = jacobian(cs_ddq, cs_v_int);
535 cs_ddq_dv = jacobian(cs_ddq, cs_v);
536 cs_ddq_dtau = jacobian(cs_ddq, cs_tau);
537
538 cs_lambda_dq = jacobian(cs_lambda_c, cs_v_int);
539 cs_lambda_dv = jacobian(cs_lambda_c, cs_v);
540 cs_lambda_dtau = jacobian(cs_lambda_c, cs_tau);
541
542 ad_fun =
543 ADFun(fun_name, ADSVector{cs_q, cs_v_int, cs_v, cs_tau}, ADSVector{cs_ddq, cs_lambda_c});
544 ad_fun_derivs = ADFun(
545 fun_name + "_derivs", ADSVector{cs_q, cs_v_int, cs_v, cs_tau},
546 ADSVector{cs_ddq_dq, cs_ddq_dv, cs_ddq_dtau, cs_lambda_dq, cs_lambda_dv, cs_lambda_dtau});
547 }
548
549 template<typename ConfigVectorType1, typename TangentVectorType1, typename TangentVectorType2>
550 void evalFunction(
551 const Eigen::MatrixBase<ConfigVectorType1> & q,
552 const Eigen::MatrixBase<TangentVectorType1> & v,
553 const Eigen::MatrixBase<TangentVectorType2> & tau)
554 {
555 Eigen::Map<ConfigVectorType1>(q_vec.data(), ad_model.nq, 1) = q;
556 Eigen::Map<TangentVectorType1>(v_vec.data(), ad_model.nv, 1) = v;
557 Eigen::Map<TangentVectorType2>(tau_vec.data(), ad_model.nv, 1) = tau;
558 fun_output = fun(DMVector{q_vec, v_int_vec, v_vec, tau_vec});
559 ddq = Eigen::Map<TangentVectorType>(
560 static_cast<std::vector<Scalar>>(fun_output[0]).data(), ad_model.nv, 1);
561 lambda_c = Eigen::Map<TangentVectorType>(
562 static_cast<std::vector<Scalar>>(fun_output[1]).data(), nc, 1);
563 }
564
565 template<typename ConfigVectorType1, typename TangentVectorType1, typename TangentVectorType2>
566 void evalJacobian(
567 const Eigen::MatrixBase<ConfigVectorType1> & q,
568 const Eigen::MatrixBase<TangentVectorType1> & v,
569 const Eigen::MatrixBase<TangentVectorType2> & tau)
570 {
571 Eigen::Map<ConfigVectorType1>(q_vec.data(), ad_model.nq, 1) = q;
572 Eigen::Map<TangentVectorType1>(v_vec.data(), ad_model.nv, 1) = v;
573 Eigen::Map<TangentVectorType2>(tau_vec.data(), ad_model.nv, 1) = tau;
574 fun_output_derivs = fun_derivs(DMVector{q_vec, v_int_vec, v_vec, tau_vec});
575 ddq_dq = Eigen::Map<MatrixXs>(
576 static_cast<std::vector<Scalar>>(fun_output_derivs[0]).data(), ad_model.nv, ad_model.nv);
577 ddq_dv = Eigen::Map<MatrixXs>(
578 static_cast<std::vector<Scalar>>(fun_output_derivs[1]).data(), ad_model.nv, ad_model.nv);
579 ddq_dtau = Eigen::Map<MatrixXs>(
580 static_cast<std::vector<Scalar>>(fun_output_derivs[2]).data(), ad_model.nv, ad_model.nv);
581 dlambda_dq = Eigen::Map<MatrixXs>(
582 static_cast<std::vector<Scalar>>(fun_output_derivs[3]).data(), nc, ad_model.nv);
583 dlambda_dv = Eigen::Map<MatrixXs>(
584 static_cast<std::vector<Scalar>>(fun_output_derivs[4]).data(), nc, ad_model.nv);
585 dlambda_dtau = Eigen::Map<MatrixXs>(
586 static_cast<std::vector<Scalar>>(fun_output_derivs[5]).data(), nc, ad_model.nv);
587 }
588
589 TangentVectorType ddq;
590 VectorXs lambda_c;
591 RowMatrixXs ddq_dq, ddq_dv, ddq_dtau, dlambda_dq, dlambda_dv, dlambda_dtau;
592
593 protected:
594 using Base::ad_data;
595 using Base::ad_model;
596 using Base::cg_generated;
597 using Base::filename;
598 using Base::fun_name;
599 using Base::libname;
600
601 using Base::ad_fun;
602 using Base::ad_fun_derivs;
603 using Base::fun;
604 using Base::fun_derivs;
605 using Base::fun_output;
606 using Base::fun_output_derivs;
607
608 ADConstraintModelVector ad_contact_models;
609 ADConstraintDataVector ad_contact_datas;
610
611 Eigen::DenseIndex nc;
612 ADScalar cs_q, cs_v, cs_tau, cs_v_int, cs_ddq, cs_lambda_c;
613
614 // Derivatives
615 ADScalar cs_ddq_dq, cs_ddq_dv, cs_ddq_dtau, cs_lambda_dq, cs_lambda_dv, cs_lambda_dtau;
616
617 ADConfigVectorType q_ad, q_int_ad;
618 ADTangentVectorType v_ad, v_int_ad, tau_ad;
619
620 std::vector<Scalar> q_vec, v_vec, v_int_vec, tau_vec;
621 };
622
623 template<typename _Scalar>
625 {
627 typedef typename Base::Scalar Scalar;
628 typedef typename Base::ADScalar ADScalar;
629 typedef typename Base::ADSVector ADSVector;
630
631 typedef typename Base::TangentVectorType TangentVectorType;
632 typedef typename Base::RowMatrixXs RowMatrixXs;
633 typedef typename Base::VectorXs VectorXs;
634 typedef typename Base::MatrixXs MatrixXs;
635
636 typedef typename Base::ADFun ADFun;
637 typedef typename Base::DMVector DMVector;
638 typedef typename Base::DMMatrix DMMatrix;
639 typedef typename Base::ADConfigVectorType ADConfigVectorType;
640 typedef typename Base::ADTangentVectorType ADTangentVectorType;
641
643 typedef Eigen::aligned_allocator<ConstraintModel> ConstraintModelAllocator;
644 typedef typename std::vector<ConstraintModel, ConstraintModelAllocator> ConstraintModelVector;
646 typedef Eigen::aligned_allocator<ConstraintData> ConstraintDataAllocator;
647 typedef typename std::vector<ConstraintData, ConstraintDataAllocator> ConstraintDataVector;
648
651 typedef Eigen::aligned_allocator<ADConstraintModel> ADConstraintModelAllocator;
652 typedef typename std::vector<ADConstraintModel, ADConstraintModelAllocator>
653 ADConstraintModelVector;
655 typedef Eigen::aligned_allocator<ADConstraintData> ADConstraintDataAllocator;
656 typedef typename std::vector<ADConstraintData, ADConstraintDataAllocator>
657 ADConstraintDataVector;
658
659 static Eigen::DenseIndex constraintDim(const ConstraintModelVector & contact_models)
660 {
661 Eigen::DenseIndex num_total_constraints = 0;
662 for (typename ConstraintModelVector::const_iterator it = contact_models.begin();
663 it != contact_models.end(); ++it)
664 {
665 PINOCCHIO_CHECK_INPUT_ARGUMENT(
666 it->size() > 0, "The dimension of the constraint must be positive");
667 num_total_constraints += it->size();
668 }
670 }
671
673 const Model & model,
674 const ConstraintModelVector & contact_models,
675 const std::string & filename = "casadi_contactDynDerivs",
676 const std::string & libname = "libcasadi_cg_contactDynDerivs",
677 const std::string & fun_name = "eval_f")
678 : Base(model, filename, libname, fun_name)
679 , nc(constraintDim(contact_models))
680 , cs_q(ADScalar::sym("q", model.nq))
681 , cs_v(ADScalar::sym("v", model.nv))
682 , cs_tau(ADScalar::sym("tau", model.nv))
683 , q_ad(model.nq)
684 , v_ad(model.nv)
685 , tau_ad(model.nv)
686 , cs_ddq(model.nv, 1)
687 , cs_lambda_c(model.nv, 1)
688 , q_vec((size_t)model.nq)
689 , v_vec((size_t)model.nv)
690 , tau_vec((size_t)model.nv)
691 , ddq(model.nv)
692 , ddq_dq(model.nv, model.nv)
693 , ddq_dv(model.nv, model.nv)
694 , ddq_dtau(model.nv, model.nv)
695 {
696 lambda_c.resize(nc);
697 lambda_c.setZero();
698 dlambda_dq.resize(nc, model.nv);
699 dlambda_dq.setZero();
700 dlambda_dv.resize(nc, model.nv);
701 dlambda_dv.setZero();
702 dlambda_dtau.resize(nc, model.nv);
703 dlambda_dtau.setZero();
704
705 q_ad = Eigen::Map<ADConfigVectorType>(
706 static_cast<std::vector<ADScalar>>(cs_q).data(), model.nq, 1);
707 v_ad = Eigen::Map<ADTangentVectorType>(
708 static_cast<std::vector<ADScalar>>(cs_v).data(), model.nv, 1);
709 tau_ad = Eigen::Map<ADTangentVectorType>(
710 static_cast<std::vector<ADScalar>>(cs_tau).data(), model.nv, 1);
711
712 for (int k = 0; k < contact_models.size(); ++k)
713 {
714 ad_contact_models.push_back(contact_models[k].template cast<ADScalar>());
715 ad_contact_datas.push_back(ADConstraintData(ad_contact_models[k]));
716 }
717
718 Base::build_jacobian = false;
719 }
720
722 {
723 }
724
725 virtual void buildMap()
726 {
727 pinocchio::initConstraintDynamics(ad_model, ad_data, ad_contact_models);
729 ad_model, ad_data, q_ad, v_ad, tau_ad, ad_contact_models, ad_contact_datas);
730 pinocchio::computeConstraintDynamicsDerivatives(
731 ad_model, ad_data, ad_contact_models, ad_contact_datas);
732 // Copy Output
733 pinocchio::casadi::copy(ad_data.ddq, cs_ddq);
734 pinocchio::casadi::copy(ad_data.lambda_c, cs_lambda_c);
735 pinocchio::casadi::copy(ad_data.ddq_dq, cs_ddq_dq);
736 pinocchio::casadi::copy(ad_data.ddq_dv, cs_ddq_dv);
737 pinocchio::casadi::copy(ad_data.ddq_dtau, cs_ddq_dtau);
738 pinocchio::casadi::copy(ad_data.dlambda_dq, cs_lambda_dq);
739 pinocchio::casadi::copy(ad_data.dlambda_dv, cs_lambda_dv);
740 pinocchio::casadi::copy(ad_data.dlambda_dtau, cs_lambda_dtau);
741
742 ad_fun = ADFun(
743 fun_name, ADSVector{cs_q, cs_v, cs_tau},
744 ADSVector{
745 cs_ddq, cs_lambda_c, cs_ddq_dq, cs_ddq_dv, cs_ddq_dtau, cs_lambda_dq, cs_lambda_dv,
746 cs_lambda_dtau});
747 }
748
749 template<typename ConfigVectorType1, typename TangentVectorType1, typename TangentVectorType2>
750 void evalFunction(
751 const Eigen::MatrixBase<ConfigVectorType1> & q,
752 const Eigen::MatrixBase<TangentVectorType1> & v,
753 const Eigen::MatrixBase<TangentVectorType2> & tau)
754 {
755 Eigen::Map<ConfigVectorType1>(q_vec.data(), ad_model.nq, 1) = q;
756 Eigen::Map<TangentVectorType1>(v_vec.data(), ad_model.nv, 1) = v;
757 Eigen::Map<TangentVectorType2>(tau_vec.data(), ad_model.nv, 1) = tau;
758 fun_output = fun(DMVector{q_vec, v_vec, tau_vec});
759 ddq = Eigen::Map<TangentVectorType>(
760 static_cast<std::vector<Scalar>>(fun_output[0]).data(), ad_model.nv, 1);
761 lambda_c = Eigen::Map<TangentVectorType>(
762 static_cast<std::vector<Scalar>>(fun_output[1]).data(), nc, 1);
763 ddq_dq = Eigen::Map<MatrixXs>(
764 static_cast<std::vector<Scalar>>(fun_output[2]).data(), ad_model.nv, ad_model.nv);
765 ddq_dv = Eigen::Map<MatrixXs>(
766 static_cast<std::vector<Scalar>>(fun_output[3]).data(), ad_model.nv, ad_model.nv);
767 ddq_dtau = Eigen::Map<MatrixXs>(
768 static_cast<std::vector<Scalar>>(fun_output[4]).data(), ad_model.nv, ad_model.nv);
769 dlambda_dq = Eigen::Map<MatrixXs>(
770 static_cast<std::vector<Scalar>>(fun_output[5]).data(), nc, ad_model.nv);
771 dlambda_dv = Eigen::Map<MatrixXs>(
772 static_cast<std::vector<Scalar>>(fun_output[6]).data(), nc, ad_model.nv);
773 dlambda_dtau = Eigen::Map<MatrixXs>(
774 static_cast<std::vector<Scalar>>(fun_output[7]).data(), nc, ad_model.nv);
775 }
776
777 TangentVectorType ddq, lambda_c;
778 RowMatrixXs ddq_dq, ddq_dv, ddq_dtau, dlambda_dq, dlambda_dv, dlambda_dtau;
779
780 protected:
781 using Base::ad_data;
782 using Base::ad_model;
783 using Base::cg_generated;
784 using Base::filename;
785 using Base::fun_name;
786 using Base::libname;
787
788 using Base::ad_fun;
789 using Base::ad_fun_derivs;
790 using Base::fun;
791 using Base::fun_derivs;
792 using Base::fun_output;
793 using Base::fun_output_derivs;
794 ADConstraintModelVector ad_contact_models;
795 ADConstraintDataVector ad_contact_datas;
796
797 Eigen::DenseIndex nc;
798 ADScalar cs_q, cs_v, cs_tau, cs_ddq, cs_lambda_c;
799
800 // Derivatives
801 ADScalar cs_ddq_dq, cs_ddq_dv, cs_ddq_dtau, cs_lambda_dq, cs_lambda_dv, cs_lambda_dtau;
802
803 ADConfigVectorType q_ad;
804 ADTangentVectorType v_ad, tau_ad;
805
806 std::vector<Scalar> q_vec, v_vec, tau_vec;
807 };
808
809 } // namespace casadi
810
811} // namespace pinocchio
812
813#endif // ifndef __pinocchio_autodiff_code_generator_algo_hpp__
Main pinocchio namespace.
Definition treeview.dox:11
void initConstraintDynamics(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const std::vector< RigidConstraintModelTpl< Scalar, Options >, Allocator > &contact_models)
Init the forward dynamics data according to the contact information contained in contact_models.
void computeABADerivatives(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q, const Eigen::MatrixBase< TangentVectorType1 > &v, const Eigen::MatrixBase< TangentVectorType2 > &tau, const Eigen::MatrixBase< MatrixType1 > &aba_partial_dq, const Eigen::MatrixBase< MatrixType2 > &aba_partial_dv, const Eigen::MatrixBase< MatrixType3 > &aba_partial_dtau)
The derivatives of the Articulated-Body algorithm.
const DataTpl< Scalar, Options, JointCollectionTpl >::TangentVectorType & constraintDynamics(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q, const Eigen::MatrixBase< TangentVectorType1 > &v, const Eigen::MatrixBase< TangentVectorType2 > &tau, const std::vector< RigidConstraintModelTpl< Scalar, Options >, ConstraintModelAllocator > &contact_models, std::vector< RigidConstraintDataTpl< Scalar, Options >, ConstraintDataAllocator > &contact_datas, ProximalSettingsTpl< Scalar > &settings)
Computes the forward dynamics with contact constraints according to a given list of contact informati...
void integrate(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ConfigVectorType > &q, const Eigen::MatrixBase< TangentVectorType > &v, const Eigen::MatrixBase< ReturnType > &qout)
Integrate a configuration vector for the specified model for a tangent vector during one unit time.
const DataTpl< Scalar, Options, JointCollectionTpl >::TangentVectorType & aba(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q, const Eigen::MatrixBase< TangentVectorType1 > &v, const Eigen::MatrixBase< TangentVectorType2 > &tau, const Convention convention=Convention::LOCAL)
The Articulated-Body algorithm. It computes the forward dynamics, aka the joint accelerations given t...
VectorXs lambda_c
Lagrange Multipliers corresponding to the contact forces in pinocchio::forwardDynamics.
Definition data.hpp:485
MatrixXs dlambda_dq
Partial derivatives of the constraints forces with respect to the joint configuration,...
Definition data.hpp:430
RowMatrixXs ddq_dtau
Partial derivative of the joint acceleration vector with respect to the joint torques.
Definition data.hpp:416
RowMatrixXs ddq_dv
Partial derivative of the joint acceleration vector with respect to the joint velocity.
Definition data.hpp:412
TangentVectorType ddq
The joint accelerations computed from ABA.
Definition data.hpp:256
RowMatrixXs Minv
The inverse of the joint space inertia matrix (a square matrix of dim model.nv).
Definition data.hpp:202
RowMatrixXs ddq_dq
Partial derivative of the joint acceleration vector with respect to the joint configuration.
Definition data.hpp:408
VectorXs TangentVectorType
Dense vectorized version of a joint tangent vector (e.g. velocity, acceleration, etc)....
Definition model.hpp:95
int nq
Dimension of the configuration vector representation.
Definition model.hpp:98
int nv
Dimension of the velocity vector space.
Definition model.hpp:101
VectorXs ConfigVectorType
Dense vectorized version of a joint configuration vector.
Definition model.hpp:87
virtual void buildMap()
build the mapping Y = f(X)
virtual void buildMap()
build the mapping Y = f(X)
virtual void buildMap()=0
build the mapping Y = f(X)
bool build_jacobian
Options to build or not the Jacobian of he function.
bool build_forward
Options to generate or not the source code for the evaluation function.
virtual void buildMap()
build the mapping Y = f(X)
virtual void buildMap()
build the mapping Y = f(X)