pinocchio  2.1.3
code-generator-base.hpp
1 //
2 // Copyright (c) 2018 CNRS
3 //
4 
5 #ifndef __pinocchio_utils_code_generator_base_hpp__
6 #define __pinocchio_utils_code_generator_base_hpp__
7 
8 #include "pinocchio/multibody/model.hpp"
9 #include "pinocchio/multibody/data.hpp"
10 
11 #ifdef PINOCCHIO_WITH_CPPADCG_SUPPORT
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 
37  typedef typename Model::ConfigVectorType CongigVectorType;
38  typedef typename Model::TangentVectorType TangentVectorType;
39 
40  typedef typename ADModel::ConfigVectorType ADCongigVectorType;
41  typedef typename ADModel::TangentVectorType ADTangentVectorType;
42 
43  typedef CppAD::ADFun<CGScalar> ADFun;
44 
45  CodeGenBase(const Model & model,
46  const Eigen::DenseIndex dim_input,
47  const Eigen::DenseIndex dim_output,
48  const std::string & function_name,
49  const std::string & library_name)
50  : ad_model(model.template cast<ADScalar>())
51  , ad_data(ad_model)
52  , function_name(function_name)
53  , library_name(library_name + "_" + model.name)
54  , build_forward(true)
55  , build_jacobian(true)
56  {
57  ad_X = ADVectorXs(dim_input);
58  ad_Y = ADVectorXs(dim_output);
59 
60  y = VectorXs(ad_Y.size());
61 
62  jac = RowMatrixXs(ad_Y.size(),ad_X.size());
63  }
64 
66  virtual void buildMap() = 0;
67 
68  void initLib()
69  {
70  buildMap();
71 
72  // generates source code
73  cgen_ptr = std::unique_ptr<CppAD::cg::ModelCSourceGen<Scalar> >(new CppAD::cg::ModelCSourceGen<Scalar>(ad_fun, function_name));
74  cgen_ptr->setCreateForwardZero(build_forward);
75  cgen_ptr->setCreateJacobian(build_jacobian);
76  libcgen_ptr = std::unique_ptr<CppAD::cg::ModelLibraryCSourceGen<Scalar> >(new CppAD::cg::ModelLibraryCSourceGen<Scalar>(*cgen_ptr));
77 
78  dynamicLibManager_ptr
79  = std::unique_ptr<CppAD::cg::DynamicModelLibraryProcessor<Scalar> >(new CppAD::cg::DynamicModelLibraryProcessor<Scalar>(*libcgen_ptr,library_name));
80  }
81 
82  CppAD::cg::ModelCSourceGen<Scalar> & codeGenerator()
83  { return *cgen_ptr; }
84 
85  void compileLib()
86  {
87  CppAD::cg::GccCompiler<Scalar> compiler;
88  std::vector<std::string> compile_options = compiler.getCompileFlags();
89  compile_options[0] = "-Ofast";
90  compiler.setCompileFlags(compile_options);
91  dynamicLibManager_ptr->createDynamicLibrary(compiler,false);
92  }
93 
94  bool existLib() const
95  {
96  const std::string filename = dynamicLibManager_ptr->getLibraryName() + CppAD::cg::system::SystemInfo<>::DYNAMIC_LIB_EXTENSION;
97  std::ifstream file(filename.c_str());
98  return file.good();
99  }
100 
101  void loadLib(const bool generate_if_not_exist = true)
102  {
103  if(not existLib() && generate_if_not_exist)
104  compileLib();
105 
106  const auto it = dynamicLibManager_ptr->getOptions().find("dlOpenMode");
107  if (it == dynamicLibManager_ptr->getOptions().end())
108  {
109  dynamicLib_ptr.reset(new CppAD::cg::LinuxDynamicLib<Scalar>(dynamicLibManager_ptr->getLibraryName() + CppAD::cg::system::SystemInfo<>::DYNAMIC_LIB_EXTENSION));
110  }
111  else
112  {
113  int dlOpenMode = std::stoi(it->second);
114  dynamicLib_ptr.reset(new CppAD::cg::LinuxDynamicLib<Scalar>(dynamicLibManager_ptr->getLibraryName() + CppAD::cg::system::SystemInfo<>::DYNAMIC_LIB_EXTENSION, dlOpenMode));
115  }
116 
117  generatedFun_ptr = dynamicLib_ptr->model(function_name.c_str());
118  }
119 
120  template<typename Vector>
121  void evalFunction(const Eigen::MatrixBase<Vector> & x)
122  {
123  assert(build_forward);
124 
125  generatedFun_ptr->ForwardZero(PINOCCHIO_EIGEN_CONST_CAST(Vector,x),y);
126  }
127 
128  template<typename Vector>
129  void evalJacobian(const Eigen::MatrixBase<Vector> & x)
130  {
131  assert(build_jacobian);
132 
133  CppAD::cg::ArrayView<const Scalar> x_(PINOCCHIO_EIGEN_CONST_CAST(Vector,x).data(),(size_t)x.size());
134  CppAD::cg::ArrayView<Scalar> jac_(jac.data(),(size_t)jac.size());
135  generatedFun_ptr->Jacobian(x_,jac_);
136  }
137 
139  Eigen::DenseIndex getInputDimension() const { return ad_X.size(); }
141  Eigen::DenseIndex getOutputDimension() const { return ad_Y.size(); }
142 
143  protected:
144 
145  ADModel ad_model;
146  ADData ad_data;
147 
149  const std::string function_name;
151  const std::string library_name;
152 
155 
158 
159  ADVectorXs ad_X, ad_Y;
160  ADFun ad_fun;
161 
162  ADCongigVectorType ad_q, ad_q_plus;
163  ADTangentVectorType ad_dq, ad_v, ad_a;
164 
165  VectorXs y;
166  RowMatrixXs jac;
167 
168  std::unique_ptr<CppAD::cg::ModelCSourceGen<Scalar> > cgen_ptr;
169  std::unique_ptr<CppAD::cg::ModelLibraryCSourceGen<Scalar> > libcgen_ptr;
170  std::unique_ptr<CppAD::cg::DynamicModelLibraryProcessor<Scalar> > dynamicLibManager_ptr;
171  std::unique_ptr<CppAD::cg::DynamicLib<Scalar> > dynamicLib_ptr;
172  std::unique_ptr<CppAD::cg::GenericModel<Scalar> > generatedFun_ptr;
173 
174  }; // struct CodeGenBase
175 
176 } // namespace pinocchio
177 
178 #endif // PINOCCHIO_WITH_CPPADCG_SUPPORT
179 
180 #endif // ifndef __pinocchio_utils_code_generator_base_hpp__
bool build_forward
Options to generate or not the source code for the evaluation function.
const std::string function_name
Name of the function.
VectorXs ConfigVectorType
Dense vectorized version of a joint configuration vector.
const std::string library_name
Name of the library.
bool build_jacobian
Options to build or not the Jacobian of he function.
Eigen::DenseIndex getOutputDimension() const
Dimension of the output vector.
virtual void buildMap()=0
build the mapping Y = f(X)
Eigen::DenseIndex getInputDimension() const
Dimension of the input vector.
Main pinocchio namespace.
Definition: treeview.dox:24
std::string name
Model name;.
VectorXs TangentVectorType
Dense vectorized version of a joint tangent vector (e.g. velocity, acceleration, etc). It also handles the notion of co-tangent vector (e.g. torque, etc).