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>
32 const Eigen::Ref<
const typename MathBaseTpl<ToScalar>::VectorXs>&)>
34 const std::function<
void(
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 };
53inline constexpr CompilerType defaultCompilerType() {
56#elif defined(__GNUC__) 63inline const char* compilerExecutable(CompilerType compiler) {
66#ifdef CROCODDYL_CODEGEN_GCC_COMPILER_PATH 67 return CROCODDYL_CODEGEN_GCC_COMPILER_PATH;
69 return "/usr/bin/gcc";
72#ifdef CROCODDYL_CODEGEN_CLANG_COMPILER_PATH 73 return CROCODDYL_CODEGEN_CLANG_COMPILER_PATH;
75 return "/usr/bib/clang";
81template <
typename Scalar>
84template <
typename _Scalar>
87 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
88 CROCODDYL_DERIVED_FLOATINGPOINT_CAST(ActionModelBase, ActionModelCodeGenTpl)
90 typedef _Scalar Scalar;
91 typedef MathBaseTpl<Scalar> MathBase;
92 typedef ActionModelAbstractTpl<Scalar> Base;
93 typedef ActionDataCodeGenTpl<Scalar> Data;
94 typedef ActionDataAbstractTpl<Scalar> ActionDataAbstract;
95 typedef typename MathBase::VectorXs VectorXs;
96 typedef typename MathBase::MatrixXs MatrixXs;
98 typedef CppAD::cg::CG<Scalar> CGScalar;
99 typedef CppAD::AD<CGScalar> ADScalar;
100 typedef MathBaseTpl<ADScalar> ADMathBase;
101 typedef ActionModelAbstractTpl<ADScalar> ADBase;
102 typedef ActionDataAbstractTpl<ADScalar> ADActionDataAbstract;
103 typedef typename ADMathBase::VectorXs ADVectorXs;
104 typedef typename ADMathBase::MatrixXs ADMatrixXs;
105 typedef CppAD::ADFun<CGScalar> ADFun;
106 typedef CppAD::cg::ModelCSourceGen<Scalar> CSourceGen;
107 typedef CppAD::cg::ModelLibraryCSourceGen<Scalar> LibraryCSourceGen;
108 typedef CppAD::cg::DynamicModelLibraryProcessor<Scalar> LibraryProcessor;
109 typedef CppAD::cg::DynamicLib<Scalar> DynamicLib;
110 typedef CppAD::cg::GenericModel<Scalar> GenericModel;
111 typedef CppAD::cg::LinuxDynamicLib<Scalar> LinuxDynamicLib;
112 typedef CppAD::cg::system::SystemInfo<> SystemInfo;
113 typedef std::function<void(std::shared_ptr<ADBase>,
114 const Eigen::Ref<const ADVectorXs>&)>
133 ActionModelCodeGenTpl(
134 std::shared_ptr<Base> model,
const std::string& lib_fname,
135 bool autodiff =
false,
const std::size_t np = 0,
136 ParamsEnvironment updateParams = EmptyParamsEnv,
137 CompilerType compiler = defaultCompilerType(),
138 const std::string& compile_options =
"-O3 -ffast-math -march=native");
156 ActionModelCodeGenTpl(
157 std::shared_ptr<ADBase> ad_model,
const std::string& lib_fname,
158 bool autodiff =
false,
const std::size_t np = 0,
159 ParamsEnvironment updateParams = EmptyParamsEnv,
160 CompilerType compiler = defaultCompilerType(),
161 const std::string& compile_options =
"-O3 -ffast-math -march=native");
170 ActionModelCodeGenTpl(
const std::string& lib_fname,
171 std::shared_ptr<Base> model);
180 ActionModelCodeGenTpl(
const std::string& lib_fname,
181 std::shared_ptr<ADBase> ad_model);
187 ActionModelCodeGenTpl(
const ActionModelCodeGenTpl<Scalar>& other);
189 virtual ~ActionModelCodeGenTpl() =
default;
207 bool existLib(
const std::string& lib_fname)
const;
214 void loadLib(
const std::string& lib_fname);
222 void update_p(
const std::shared_ptr<ActionDataAbstract>& data,
223 const Eigen::Ref<const VectorXs>& p)
const;
232 virtual void calc(
const std::shared_ptr<ActionDataAbstract>& data,
233 const Eigen::Ref<const VectorXs>& x,
234 const Eigen::Ref<const VectorXs>& u)
override;
240 virtual void calc(
const std::shared_ptr<ActionDataAbstract>& data,
241 const Eigen::Ref<const VectorXs>& x)
override;
256 virtual void calcDiff(
const std::shared_ptr<ActionDataAbstract>& data,
257 const Eigen::Ref<const VectorXs>& x,
258 const Eigen::Ref<const VectorXs>& u)
override;
264 virtual void calcDiff(
const std::shared_ptr<ActionDataAbstract>& data,
265 const Eigen::Ref<const VectorXs>& x)
override;
272 virtual std::shared_ptr<ActionDataAbstract> createData()
override;
277 virtual bool checkData(
278 const std::shared_ptr<ActionDataAbstract>& data)
override;
293 virtual void quasiStatic(
const std::shared_ptr<ActionDataAbstract>& data,
294 Eigen::Ref<VectorXs> u,
295 const Eigen::Ref<const VectorXs>& x,
297 const Scalar )
override;
308 template <
typename NewScalar>
309 ActionModelCodeGenTpl<NewScalar> cast()
const;
314 const std::shared_ptr<Base>& get_model()
const;
316 std::size_t get_np()
const;
321 virtual std::size_t get_ng()
const override;
326 virtual std::size_t get_nh()
const override;
331 virtual std::size_t get_ng_T()
const override;
336 virtual std::size_t get_nh_T()
const override;
341 virtual const VectorXs& get_g_lb()
const override;
346 virtual const VectorXs& get_g_ub()
const override;
352 std::size_t get_nX()
const;
358 std::size_t get_nX_T()
const;
364 std::size_t get_nX3()
const;
370 std::size_t get_nY1()
const;
376 std::size_t get_nY1_T()
const;
382 std::size_t get_nY2()
const;
388 std::size_t get_nY2_T()
const;
394 std::size_t get_nY3()
const;
401 virtual void print(std::ostream& os)
const override;
404 ActionModelCodeGenTpl();
413 std::shared_ptr<Base> model_;
414 std::shared_ptr<ADBase>
416 std::shared_ptr<ADActionDataAbstract>
455 const std::string Y1fun_name_;
458 const std::string Y2fun_name_;
461 const std::string Y3fun_name_;
462 const std::string lib_fname_;
463 CompilerType compiler_type_;
464 const std::string compile_options_;
466 ParamsEnvironment updateParams_;
469 std::unique_ptr<ADFun> ad_calc_;
470 std::unique_ptr<ADFun>
472 std::unique_ptr<ADFun>
474 std::unique_ptr<ADFun> ad_calcDiff_T_;
476 std::unique_ptr<ADFun>
478 std::unique_ptr<CSourceGen>
480 std::unique_ptr<CSourceGen>
483 std::unique_ptr<CSourceGen>
485 std::unique_ptr<CSourceGen>
488 std::unique_ptr<CSourceGen> quasiStaticCG_;
490 std::unique_ptr<LibraryCSourceGen>
492 std::unique_ptr<LibraryProcessor>
494 std::unique_ptr<DynamicLib> dynLib_;
495 std::unique_ptr<GenericModel> calcFun_;
496 std::unique_ptr<GenericModel>
498 std::unique_ptr<GenericModel>
500 std::unique_ptr<GenericModel>
502 std::unique_ptr<GenericModel>
508 void recordCalcDiff();
509 void recordCalcDiff_T();
510 void recordQuasiStatic();
512 void tapeCalcOutput();
513 void tapeCalcOutput_T();
514 void tapeCalcDiffOutput();
515 void tapeCalcDiffOutput_T();
518 VectorXs wCostHess_T_;
520 static void EmptyParamsEnv(std::shared_ptr<ADBase>,
521 const Eigen::Ref<const ADVectorXs>&);
524template <
typename _Scalar>
526 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
528 typedef _Scalar Scalar;
529 typedef MathBaseTpl<Scalar> MathBase;
530 typedef ActionDataAbstractTpl<Scalar> Base;
531 typedef typename MathBase::VectorXs VectorXs;
532 typedef typename MathBase::MatrixXs MatrixXs;
534 template <
template <
typename Scalar>
class Model>
535 explicit ActionDataCodeGenTpl(Model<Scalar>*
const model) : Base(model) {
536 ActionModelCodeGenTpl<Scalar>* m =
537 static_cast<ActionModelCodeGenTpl<Scalar>*
>(model);
538 X.resize(m->get_nX());
539 X_T.resize(m->get_nX_T());
540 X3.resize(m->get_nX3());
541 Y1.resize(m->get_nY1());
542 J1.resize(m->get_nY1() * m->get_nX());
543 H1.resize(m->get_nX() * m->get_nX());
544 Y1_T.resize(m->get_nY1_T());
545 J1_T.resize(m->get_nY1_T() * m->get_nX_T());
546 H1_T.resize(m->get_nX_T() * m->get_nX_T());
547 Y2.resize(m->get_nY2());
548 Y2_T.resize(m->get_nY2_T());
549 Y3.resize(m->get_nY3());
598 template <
template <
typename Scalar>
class Model>
599 void set_Y1(Model<Scalar>*
const model) {
600 const std::size_t nx = model->get_state()->get_nx();
601 const std::size_t ng = model->get_ng();
602 const std::size_t nh = model->get_nh();
603 Eigen::DenseIndex it_Y1 = 0;
606 xnext = Y1.segment(it_Y1, nx);
608 g = Y1.segment(it_Y1, ng);
610 h = Y1.segment(it_Y1, nh);
613 template <
template <
typename Scalar>
class Model>
614 void set_D1(Model<Scalar>*
const model) {
615 const std::size_t ndx = model->get_state()->get_ndx();
616 const std::size_t nu = model->get_nu();
617 const std::size_t ng = model->get_ng();
618 const std::size_t nh = model->get_nh();
619 const std::size_t np = model->get_np();
620 const std::size_t nxu = ndx + nu + np;
621 Eigen::DenseIndex it_J1 = 0;
622 Lx = Eigen::Map<VectorXs>(J1.data() + it_J1, ndx);
624 Lu = Eigen::Map<VectorXs>(J1.data() + it_J1, nu);
626 Eigen::Map<MatrixXs> J1_map(J1.data() + it_J1, nxu, ndx);
627 Fx = J1_map.topRows(ndx).transpose();
628 Fu = J1_map.middleRows(ndx, nu).transpose();
630 Eigen::Map<MatrixXs> G_map(J1.data() + it_J1, nxu, ng);
631 Gx = G_map.topRows(ndx).transpose();
632 Gu = G_map.middleRows(ndx, nu).transpose();
634 Eigen::Map<MatrixXs> H_map(J1.data() + it_J1, nxu, nh);
635 Hx = H_map.topRows(ndx).transpose();
636 Hu = H_map.middleRows(ndx, nu).transpose();
637 Eigen::Map<MatrixXs> H1_map(H1.data(), nxu, nxu);
638 Lxx = H1_map.topLeftCorner(ndx, ndx);
639 Luu = H1_map.middleCols(ndx, nu).middleRows(ndx, nu);
640 Lxu = H1_map.middleCols(ndx, nu).topRows(ndx);
643 template <
template <
typename Scalar>
class Model>
644 void set_Y1_T(Model<Scalar>*
const model) {
645 const std::size_t ng = model->get_ng_T();
646 const std::size_t nh = model->get_nh_T();
647 Eigen::DenseIndex it_Y1 = 0;
650 g = Y1_T.segment(it_Y1, ng);
652 h = Y1_T.segment(it_Y1, nh);
655 template <
template <
typename Scalar>
class Model>
656 void set_D1_T(Model<Scalar>*
const model) {
657 const std::size_t ndx = model->get_state()->get_ndx();
658 const std::size_t ng = model->get_ng();
659 const std::size_t np = model->get_np();
660 const std::size_t nxp = ndx + np;
661 Eigen::DenseIndex it_J1 = 0;
662 Lx = Eigen::Map<VectorXs>(J1_T.data() + it_J1, ndx);
664 Gx = Eigen::Map<MatrixXs>(J1_T.data() + it_J1, nxp, ng)
668 Hx = Eigen::Map<MatrixXs>(J1_T.data() + it_J1, nxp, ng)
671 Lxx = Eigen::Map<MatrixXs>(H1_T.data(), nxp, nxp).topLeftCorner(ndx, ndx);
674 template <
template <
typename Scalar>
class Model>
675 void set_Y2(Model<Scalar>*
const model) {
676 const std::size_t ndx = model->get_state()->get_ndx();
677 const std::size_t nu = model->get_nu();
678 const std::size_t ng = model->get_ng();
679 const std::size_t nh = model->get_nh();
680 Eigen::DenseIndex it_Y2 = 0;
681 Fx = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, ndx, ndx);
683 Fu = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, ndx, nu);
685 Lx = Eigen::Map<VectorXs>(Y2.data() + it_Y2, ndx);
687 Lu = Eigen::Map<VectorXs>(Y2.data() + it_Y2, nu);
689 Lxx = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, ndx, ndx);
691 Lxu = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, ndx, nu);
693 Luu = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, nu, nu);
695 Gx = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, ng, ndx);
697 Gu = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, ng, nu);
699 Hx = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, nh, ndx);
701 Hu = Eigen::Map<MatrixXs>(Y2.data() + it_Y2, nh, nu);
704 template <
template <
typename Scalar>
class Model>
705 void set_Y2_T(Model<Scalar>*
const model) {
706 const std::size_t ndx = model->get_state()->get_ndx();
707 const std::size_t ng = model->get_ng_T();
708 const std::size_t nh = model->get_nh_T();
709 Eigen::DenseIndex it_Y2 = 0;
710 Lx = Eigen::Map<VectorXs>(Y2_T.data() + it_Y2, ndx);
712 Lxx = Eigen::Map<MatrixXs>(Y2_T.data() + it_Y2, ndx, ndx);
714 Gx = Eigen::Map<MatrixXs>(Y2_T.data() + it_Y2, ng, ndx);
716 Hx = Eigen::Map<MatrixXs>(Y2_T.data() + it_Y2, nh, ndx);
725#include "crocoddyl/core/codegen/action.hxx" Abstract class for action model.