pinocchio  2.7.1
A fast and flexible implementation of Rigid Body Dynamics algorithms and their analytical derivatives
code-generator-base.hpp
1 //
2 // Copyright (c) 2018-2020 CNRS INRIA
3 //
4 
5 #ifndef __pinocchio_utils_code_generator_base_hpp__
6 #define __pinocchio_utils_code_generator_base_hpp__
7 
8 #include "pinocchio/codegen/cppadcg.hpp"
9 
10 #include "pinocchio/multibody/model.hpp"
11 #include "pinocchio/multibody/data.hpp"
12 
13 namespace pinocchio
14 {
15 
16  template<typename _Scalar>
17  struct CodeGenBase
18  {
19  typedef _Scalar Scalar;
20  typedef CppAD::cg::CG<Scalar> CGScalar;
21  typedef CppAD::AD<CGScalar> ADScalar;
22 
23  enum { Options = 0 };
24 
31 
32  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic,Options> MatrixXs;
33  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,1,Options> VectorXs;
34  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic,Options|Eigen::RowMajor> RowMatrixXs;
35  typedef Eigen::Matrix<ADScalar,Eigen::Dynamic,1,Options> ADVectorXs;
36  typedef Eigen::Matrix<ADScalar,Eigen::Dynamic,Eigen::Dynamic,Options> ADMatrixXs;
37 
38  typedef typename Model::ConfigVectorType ConfigVectorType;
39  typedef typename Model::TangentVectorType TangentVectorType;
40 
41  typedef typename ADModel::ConfigVectorType ADConfigVectorType;
42  typedef typename ADModel::TangentVectorType ADTangentVectorType;
43 
44  typedef CppAD::ADFun<CGScalar> ADFun;
45 
46  CodeGenBase(const Model & model,
47  const Eigen::DenseIndex dim_input,
48  const Eigen::DenseIndex dim_output,
49  const std::string & function_name,
50  const std::string & library_name)
51  : ad_model(model.template cast<ADScalar>())
52  , ad_data(ad_model)
54  , library_name(library_name + "_" + model.name)
55  , build_forward(true)
56  , build_jacobian(true)
57  {
58  ad_X = ADVectorXs(dim_input);
59  ad_Y = ADVectorXs(dim_output);
60 
61  y = VectorXs(ad_Y.size());
62 
63  jac = RowMatrixXs(ad_Y.size(),ad_X.size());
64  }
65 
67  virtual void buildMap() = 0;
68 
69  void initLib()
70  {
71  buildMap();
72 
73  // generates source code
74  cgen_ptr = std::unique_ptr<CppAD::cg::ModelCSourceGen<Scalar> >(new CppAD::cg::ModelCSourceGen<Scalar>(ad_fun, function_name));
75  cgen_ptr->setCreateForwardZero(build_forward);
76  cgen_ptr->setCreateJacobian(build_jacobian);
77  libcgen_ptr = std::unique_ptr<CppAD::cg::ModelLibraryCSourceGen<Scalar> >(new CppAD::cg::ModelLibraryCSourceGen<Scalar>(*cgen_ptr));
78 
79  dynamicLibManager_ptr
80  = std::unique_ptr<CppAD::cg::DynamicModelLibraryProcessor<Scalar> >(new CppAD::cg::DynamicModelLibraryProcessor<Scalar>(*libcgen_ptr,library_name));
81  }
82 
83  CppAD::cg::ModelCSourceGen<Scalar> & codeGenerator()
84  { return *cgen_ptr; }
85 
86  void compileLib(const std::string& gccPath = "/usr/bin/gcc")
87  {
88  CppAD::cg::GccCompiler<Scalar> compiler(gccPath);
89  std::vector<std::string> compile_options = compiler.getCompileFlags();
90  compile_options[0] = "-Ofast";
91  compiler.setCompileFlags(compile_options);
92  dynamicLibManager_ptr->createDynamicLibrary(compiler,false);
93  }
94 
95  bool existLib() const
96  {
97  const std::string filename = dynamicLibManager_ptr->getLibraryName() + CppAD::cg::system::SystemInfo<>::DYNAMIC_LIB_EXTENSION;
98  std::ifstream file(filename.c_str());
99  return file.good();
100  }
101 
102  void compileAndLoadLib(const std::string& gccPath)
103  {
104  compileLib(gccPath);
105  loadLib(false);
106  }
107 
108  void loadLib(const bool generate_if_not_exist = true)
109  {
110  if(!existLib() && generate_if_not_exist)
111  compileLib();
112 
113  const auto it = dynamicLibManager_ptr->getOptions().find("dlOpenMode");
114  if (it == dynamicLibManager_ptr->getOptions().end())
115  {
116  dynamicLib_ptr.reset(new CppAD::cg::LinuxDynamicLib<Scalar>(dynamicLibManager_ptr->getLibraryName() + CppAD::cg::system::SystemInfo<>::DYNAMIC_LIB_EXTENSION));
117  }
118  else
119  {
120  int dlOpenMode = std::stoi(it->second);
121  dynamicLib_ptr.reset(new CppAD::cg::LinuxDynamicLib<Scalar>(dynamicLibManager_ptr->getLibraryName() + CppAD::cg::system::SystemInfo<>::DYNAMIC_LIB_EXTENSION, dlOpenMode));
122  }
123 
124  generatedFun_ptr = dynamicLib_ptr->model(function_name.c_str());
125  }
126 
127  template<typename Vector>
128  void evalFunction(const Eigen::MatrixBase<Vector> & x)
129  {
130  assert(build_forward);
131 
132  generatedFun_ptr->ForwardZero(PINOCCHIO_EIGEN_CONST_CAST(Vector,x),y);
133  }
134 
135  template<typename Vector>
136  void evalJacobian(const Eigen::MatrixBase<Vector> & x)
137  {
138  assert(build_jacobian);
139 
140  CppAD::cg::ArrayView<const Scalar> x_(PINOCCHIO_EIGEN_CONST_CAST(Vector,x).data(),(size_t)x.size());
141  CppAD::cg::ArrayView<Scalar> jac_(jac.data(),(size_t)jac.size());
142  generatedFun_ptr->Jacobian(x_,jac_);
143  }
144 
146  Eigen::DenseIndex getInputDimension() const { return ad_X.size(); }
148  Eigen::DenseIndex getOutputDimension() const { return ad_Y.size(); }
149 
150  protected:
151 
152  ADModel ad_model;
153  ADData ad_data;
154 
156  const std::string function_name;
158  const std::string library_name;
159 
162 
165 
166  ADVectorXs ad_X, ad_Y;
167  ADFun ad_fun;
168 
169  ADConfigVectorType ad_q, ad_q_plus;
170  ADTangentVectorType ad_dq, ad_v, ad_a;
171 
172  VectorXs y;
173  RowMatrixXs jac;
174 
175  std::unique_ptr<CppAD::cg::ModelCSourceGen<Scalar> > cgen_ptr;
176  std::unique_ptr<CppAD::cg::ModelLibraryCSourceGen<Scalar> > libcgen_ptr;
177  std::unique_ptr<CppAD::cg::DynamicModelLibraryProcessor<Scalar> > dynamicLibManager_ptr;
178  std::unique_ptr<CppAD::cg::DynamicLib<Scalar> > dynamicLib_ptr;
179  std::unique_ptr<CppAD::cg::GenericModel<Scalar> > generatedFun_ptr;
180 
181  }; // struct CodeGenBase
182 
183 } // namespace pinocchio
184 
185 #endif // ifndef __pinocchio_utils_code_generator_base_hpp__
pinocchio::DataTpl
Definition: data.hpp:29
pinocchio::CodeGenBase::build_jacobian
bool build_jacobian
Options to build or not the Jacobian of he function.
Definition: code-generator-base.hpp:164
pinocchio::CodeGenBase
Definition: code-generator-base.hpp:17
pinocchio::ModelTpl::ConfigVectorType
VectorXs ConfigVectorType
Dense vectorized version of a joint configuration vector.
Definition: model.hpp:66
pinocchio::CodeGenBase::getOutputDimension
Eigen::DenseIndex getOutputDimension() const
Dimension of the output vector.
Definition: code-generator-base.hpp:148
pinocchio::CodeGenBase::function_name
const std::string function_name
Name of the function.
Definition: code-generator-base.hpp:156
pinocchio::CodeGenBase::library_name
const std::string library_name
Name of the library.
Definition: code-generator-base.hpp:158
pinocchio::CodeGenBase::build_forward
bool build_forward
Options to generate or not the source code for the evaluation function.
Definition: code-generator-base.hpp:161
pinocchio::CodeGenBase::getInputDimension
Eigen::DenseIndex getInputDimension() const
Dimension of the input vector.
Definition: code-generator-base.hpp:146
pinocchio::ModelTpl::TangentVectorType
VectorXs TangentVectorType
Dense vectorized version of a joint tangent vector (e.g. velocity, acceleration, etc)....
Definition: model.hpp:73
pinocchio::ModelTpl
Definition: fwd.hpp:23
pinocchio
Main pinocchio namespace.
Definition: treeview.dox:11
pinocchio::CodeGenBase::buildMap
virtual void buildMap()=0
build the mapping Y = f(X)