11#ifndef CROCODDYL_CORE_CODEGEN_ACTION_HPP_
12#define CROCODDYL_CORE_CODEGEN_ACTION_HPP_
14#ifdef CROCODDYL_WITH_CODEGEN
16#include "crocoddyl/core/action-base.hpp"
17#include "crocoddyl/core/utils/stop-watch.hpp"
21template <
typename Scalar>
22std::unique_ptr<CppAD::ADFun<CppAD::cg::CG<Scalar>>> clone_adfun(
23 const CppAD::ADFun<CppAD::cg::CG<Scalar>>& original) {
24 auto cloned = std::make_unique<CppAD::ADFun<CppAD::cg::CG<Scalar>>>();
29template <
typename FromScalar,
typename ToScalar>
31 void(std::shared_ptr<ActionModelAbstractTpl<ToScalar>>,
32 const Eigen::Ref<
const typename MathBaseTpl<ToScalar>::VectorXs>&)>
34 const std::function<
void(
35 std::shared_ptr<ActionModelAbstractTpl<FromScalar>>,
36 const Eigen::Ref<
const typename MathBaseTpl<FromScalar>::VectorXs>&)>&
38 return [fn](std::shared_ptr<ActionModelAbstractTpl<ToScalar>> to_base,
39 const Eigen::Ref<const typename MathBaseTpl<ToScalar>::VectorXs>&
42 const std::shared_ptr<ActionModelAbstractTpl<FromScalar>>& from_base =
43 to_base->template cast<FromScalar>();
44 const typename MathBaseTpl<FromScalar>::VectorXs from_vector =
45 to_vector.template cast<FromScalar>();
47 fn(from_base, from_vector);
51enum CompilerType { GCC = 0, CLANG };
53template <
typename Scalar>
54struct ActionDataCodeGenTpl;
56template <
typename _Scalar>
57class ActionModelCodeGenTpl :
public ActionModelAbstractTpl<_Scalar> {
59 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
60 CROCODDYL_DERIVED_FLOATINGPOINT_CAST(ActionModelBase, ActionModelCodeGenTpl)
62 typedef _Scalar Scalar;
63 typedef MathBaseTpl<Scalar> MathBase;
64 typedef ActionModelAbstractTpl<Scalar> Base;
65 typedef ActionDataCodeGenTpl<Scalar> Data;
66 typedef ActionDataAbstractTpl<Scalar> ActionDataAbstract;
67 typedef typename MathBase::VectorXs VectorXs;
68 typedef typename MathBase::MatrixXs MatrixXs;
70 typedef CppAD::cg::CG<Scalar> CGScalar;
71 typedef CppAD::AD<CGScalar> ADScalar;
72 typedef MathBaseTpl<ADScalar> ADMathBase;
73 typedef ActionModelAbstractTpl<ADScalar> ADBase;
74 typedef ActionDataAbstractTpl<ADScalar> ADActionDataAbstract;
75 typedef typename ADMathBase::VectorXs ADVectorXs;
76 typedef typename ADMathBase::MatrixXs ADMatrixXs;
77 typedef CppAD::ADFun<CGScalar> ADFun;
78 typedef CppAD::cg::ModelCSourceGen<Scalar> CSourceGen;
79 typedef CppAD::cg::ModelLibraryCSourceGen<Scalar> LibraryCSourceGen;
80 typedef CppAD::cg::DynamicModelLibraryProcessor<Scalar> LibraryProcessor;
81 typedef CppAD::cg::DynamicLib<Scalar> DynamicLib;
82 typedef CppAD::cg::GenericModel<Scalar> GenericModel;
83 typedef CppAD::cg::LinuxDynamicLib<Scalar> LinuxDynamicLib;
84 typedef CppAD::cg::system::SystemInfo<> SystemInfo;
85 typedef std::function<void(std::shared_ptr<ADBase>,
86 const Eigen::Ref<const ADVectorXs>&)>
104 ActionModelCodeGenTpl(
105 std::shared_ptr<Base> model,
const std::string& lib_fname,
106 bool autodiff =
false,
const std::size_t np = 0,
107 ParamsEnvironment updateParams = EmptyParamsEnv,
108 CompilerType compiler = CLANG,
109 const std::string& compile_options =
"-Ofast -march=native");
126 ActionModelCodeGenTpl(
127 std::shared_ptr<ADBase> ad_model,
const std::string& lib_fname,
128 bool autodiff =
false,
const std::size_t np = 0,
129 ParamsEnvironment updateParams = EmptyParamsEnv,
130 CompilerType compiler = CLANG,
131 const std::string& compile_options =
"-Ofast -march=native");
140 ActionModelCodeGenTpl(
const std::string& lib_fname,
141 std::shared_ptr<Base> model);
150 ActionModelCodeGenTpl(
const std::string& lib_fname,
151 std::shared_ptr<ADBase> ad_model);
157 ActionModelCodeGenTpl(
const ActionModelCodeGenTpl<Scalar>& other);
159 virtual ~ActionModelCodeGenTpl() =
default;
177 bool existLib(
const std::string& lib_fname)
const;
184 void loadLib(
const std::string& lib_fname);
192 void update_p(
const std::shared_ptr<ActionDataAbstract>& data,
193 const Eigen::Ref<const VectorXs>& p)
const;
202 virtual void calc(
const std::shared_ptr<ActionDataAbstract>& data,
203 const Eigen::Ref<const VectorXs>& x,
204 const Eigen::Ref<const VectorXs>& u)
override;
210 virtual void calc(
const std::shared_ptr<ActionDataAbstract>& data,
211 const Eigen::Ref<const VectorXs>& x)
override;
226 virtual void calcDiff(
const std::shared_ptr<ActionDataAbstract>& data,
227 const Eigen::Ref<const VectorXs>& x,
228 const Eigen::Ref<const VectorXs>& u)
override;
234 virtual void calcDiff(
const std::shared_ptr<ActionDataAbstract>& data,
235 const Eigen::Ref<const VectorXs>& x)
override;
242 virtual std::shared_ptr<ActionDataAbstract> createData()
override;
247 virtual bool checkData(
248 const std::shared_ptr<ActionDataAbstract>& data)
override;
263 virtual void quasiStatic(
const std::shared_ptr<ActionDataAbstract>& data,
264 Eigen::Ref<VectorXs> u,
265 const Eigen::Ref<const VectorXs>& x,
267 const Scalar )
override;
278 template <
typename NewScalar>
279 ActionModelCodeGenTpl<NewScalar> cast()
const;
284 const std::shared_ptr<Base>& get_model()
const;
286 std::size_t get_np()
const;
291 virtual std::size_t get_ng()
const override;
296 virtual std::size_t get_nh()
const override;
301 virtual std::size_t get_ng_T()
const override;
306 virtual std::size_t get_nh_T()
const override;
311 virtual const VectorXs& get_g_lb()
const override;
316 virtual const VectorXs& get_g_ub()
const override;
322 std::size_t get_nX()
const;
328 std::size_t get_nX_T()
const;
334 std::size_t get_nX3()
const;
340 std::size_t get_nY1()
const;
346 std::size_t get_nY1_T()
const;
352 std::size_t get_nY2()
const;
358 std::size_t get_nY2_T()
const;
364 std::size_t get_nY3()
const;
371 virtual void print(std::ostream& os)
const override;
374 ActionModelCodeGenTpl();
383 std::shared_ptr<Base> model_;
384 std::shared_ptr<ADBase>
386 std::shared_ptr<ADActionDataAbstract>
425 const std::string Y1fun_name_;
428 const std::string Y2fun_name_;
431 const std::string Y3fun_name_;
432 const std::string lib_fname_;
433 CompilerType compiler_type_;
434 const std::string compile_options_;
436 ParamsEnvironment updateParams_;
439 std::unique_ptr<ADFun> ad_calc_;
440 std::unique_ptr<ADFun>
442 std::unique_ptr<ADFun>
444 std::unique_ptr<ADFun> ad_calcDiff_T_;
446 std::unique_ptr<ADFun>
448 std::unique_ptr<CSourceGen>
450 std::unique_ptr<CSourceGen>
453 std::unique_ptr<CSourceGen>
455 std::unique_ptr<CSourceGen>
458 std::unique_ptr<CSourceGen> quasiStaticCG_;
460 std::unique_ptr<LibraryCSourceGen>
462 std::unique_ptr<LibraryProcessor>
464 std::unique_ptr<DynamicLib> dynLib_;
465 std::unique_ptr<GenericModel> calcFun_;
466 std::unique_ptr<GenericModel>
468 std::unique_ptr<GenericModel>
470 std::unique_ptr<GenericModel>
472 std::unique_ptr<GenericModel>
478 void recordCalcDiff();
479 void recordCalcDiff_T();
480 void recordQuasiStatic();
482 void tapeCalcOutput();
483 void tapeCalcOutput_T();
484 void tapeCalcDiffOutput();
485 void tapeCalcDiffOutput_T();
488 VectorXs wCostHess_T_;
490 static void EmptyParamsEnv(std::shared_ptr<ADBase>,
491 const Eigen::Ref<const ADVectorXs>&);
494template <
typename _Scalar>
495struct ActionDataCodeGenTpl :
public ActionDataAbstractTpl<_Scalar> {
496 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
498 typedef _Scalar Scalar;
499 typedef MathBaseTpl<Scalar> MathBase;
500 typedef ActionDataAbstractTpl<Scalar> Base;
501 typedef typename MathBase::VectorXs VectorXs;
502 typedef typename MathBase::MatrixXs MatrixXs;
504 template <
template <
typename Scalar>
class Model>
505 explicit ActionDataCodeGenTpl(Model<Scalar>*
const model) : Base(model) {
506 ActionModelCodeGenTpl<Scalar>* m =
507 static_cast<ActionModelCodeGenTpl<Scalar>*
>(model);
508 X.resize(m->get_nX());
509 X_T.resize(m->get_nX_T());
510 X3.resize(m->get_nX3());
511 Y1.resize(m->get_nY1());
512 J1.resize(m->get_nY1() * m->get_nX());
513 H1.resize(m->get_nX() * m->get_nX());
514 Y1_T.resize(m->get_nY1_T());
515 J1_T.resize(m->get_nY1_T() * m->get_nX_T());
516 H1_T.resize(m->get_nX_T() * m->get_nX_T());
517 Y2.resize(m->get_nY2());
518 Y2_T.resize(m->get_nY2_T());
519 Y3.resize(m->get_nY3());
568 template <
template <
typename Scalar>
class Model>
569 void set_Y1(Model<Scalar>*
const model) {
570 const std::size_t nx = model->get_state()->get_nx();
571 const std::size_t ng = model->get_ng();
572 const std::size_t nh = model->get_nh();
573 Eigen::DenseIndex it_Y1 = 0;
576 xnext = Y1.segment(it_Y1, nx);
578 g = Y1.segment(it_Y1, ng);
580 h = Y1.segment(it_Y1, nh);
583 template <
template <
typename Scalar>
class Model>
584 void set_D1(Model<Scalar>*
const model) {
585 const std::size_t ndx = model->get_state()->get_ndx();
586 const std::size_t nu = model->get_nu();
587 const std::size_t ng = model->get_ng();
588 const std::size_t nh = model->get_nh();
589 const std::size_t np = model->get_np();
590 const std::size_t nxu = ndx + nu + np;
591 Eigen::DenseIndex it_J1 = 0;
592 Lx = Eigen::Map<VectorXs>(J1.data() + it_J1, ndx);
594 Lu = Eigen::Map<VectorXs>(J1.data() + it_J1, nu);
596 Eigen::Map<MatrixXs> J1_map(J1.data() + it_J1, nxu, ndx);
597 Fx = J1_map.topRows(ndx).transpose();
598 Fu = J1_map.middleRows(ndx, nu).transpose();
600 Eigen::Map<MatrixXs> G_map(J1.data() + it_J1, nxu, ng);
601 Gx = G_map.topRows(ndx).transpose();
602 Gu = G_map.middleRows(ndx, nu).transpose();
604 Eigen::Map<MatrixXs> H_map(J1.data() + it_J1, nxu, nh);
605 Hx = H_map.topRows(ndx).transpose();
606 Hu = H_map.middleRows(ndx, nu).transpose();
607 Eigen::Map<MatrixXs> H1_map(H1.data(), nxu, nxu);
608 Lxx = H1_map.topLeftCorner(ndx, ndx);
609 Luu = H1_map.middleCols(ndx, nu).middleRows(ndx, nu);
610 Lxu = H1_map.middleCols(ndx, nu).topRows(ndx);
613 template <
template <
typename Scalar>
class Model>
614 void set_Y1_T(Model<Scalar>*
const model) {
615 const std::size_t ng = model->get_ng_T();
616 const std::size_t nh = model->get_nh_T();
617 Eigen::DenseIndex it_Y1 = 0;
620 g = Y1_T.segment(it_Y1, ng);
622 h = Y1_T.segment(it_Y1, nh);
625 template <
template <
typename Scalar>
class Model>
626 void set_D1_T(Model<Scalar>*
const model) {
627 const std::size_t ndx = model->get_state()->get_ndx();
628 const std::size_t ng = model->get_ng();
629 const std::size_t np = model->get_np();
630 const std::size_t nxp = ndx + np;
631 Eigen::DenseIndex it_J1 = 0;
632 Lx = Eigen::Map<VectorXs>(J1_T.data() + it_J1, ndx);
634 Gx = Eigen::Map<MatrixXs>(J1_T.data() + it_J1, nxp, ng)
638 Hx = Eigen::Map<MatrixXs>(J1_T.data() + it_J1, nxp, ng)
641 Lxx = Eigen::Map<MatrixXs>(H1_T.data(), nxp, nxp).topLeftCorner(ndx, ndx);
644 template <
template <
typename Scalar>
class Model>
645 void set_Y2(Model<Scalar>*
const model) {
646 const std::size_t ndx = model->get_state()->get_ndx();
647 const std::size_t nu = model->get_nu();
648 const std::size_t ng = model->get_ng();
649 const std::size_t nh = model->get_nh();
650 Eigen::DenseIndex it_Y2 = 0;
651 Fx = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, ndx, ndx);
653 Fu = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, ndx, nu);
655 Lx = Eigen::Map<VectorXs>(Y2.data() + it_Y2, ndx);
657 Lu = Eigen::Map<VectorXs>(Y2.data() + it_Y2, nu);
659 Lxx = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, ndx, ndx);
661 Lxu = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, ndx, nu);
663 Luu = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, nu, nu);
665 Gx = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, ng, ndx);
667 Gu = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, ng, nu);
669 Hx = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, nh, ndx);
671 Hu = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, nh, nu);
674 template <
template <
typename Scalar>
class Model>
675 void set_Y2_T(Model<Scalar>*
const model) {
676 const std::size_t ndx = model->get_state()->get_ndx();
677 const std::size_t ng = model->get_ng_T();
678 const std::size_t nh = model->get_nh_T();
679 Eigen::DenseIndex it_Y2 = 0;
680 Lx = Eigen::Map<VectorXs>(Y2_T.data() + it_Y2, ndx);
682 Lxx = Eigen::Map<MatrixXs>(Y2_T.data() + it_Y2, ndx, ndx);
684 Gx = Eigen::Map<MatrixXs>(Y2_T.data() + it_Y2, ng, ndx);
686 Hx = Eigen::Map<MatrixXs>(Y2_T.data() + it_Y2, nh, ndx);
695#include "crocoddyl/core/codegen/action.hxx"
697CROCODDYL_DECLARE_FLOATINGPOINT_EXTERN_TEMPLATE_CLASS(
699CROCODDYL_DECLARE_FLOATINGPOINT_EXTERN_TEMPLATE_STRUCT(