cppadcg-basic.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2018-2019 CNRS INRIA
3 //
4 
5 #include "pinocchio/codegen/cppadcg.hpp"
6 
7 #include "pinocchio/multibody/model.hpp"
8 #include "pinocchio/parsers/sample-models.hpp"
9 
10 #include <iostream>
11 
12 #include <boost/test/unit_test.hpp>
13 #include <boost/utility/binary.hpp>
14 
15 BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
16 
17  BOOST_AUTO_TEST_CASE(test_simple_cppadcg)
18  {
19  using namespace CppAD;
20  using namespace CppAD::cg;
21 
22  typedef CG<double> CGD;
23  typedef AD<CGD> ADCG;
24 
25  /***************************************************************************
26  * the model
27  **************************************************************************/
28 
29  // independent variable vector
30  CppAD::vector<ADCG> x(2);
31  x[0] = 2.;
32  x[1] = 3.;
33  Independent(x);
34 
35  // dependent variable vector
36  CppAD::vector<ADCG> y(1);
37 
38  // the model
39  ADCG a = x[0] / 1. + x[1] * x[1];
40  y[0] = a / 2;
41 
42  ADFun<CGD> fun(x, y); // the model tape
43 
44  /***************************************************************************
45  * Generate the C source code
46  **************************************************************************/
47 
51  CodeHandler<double> handler;
52 
53  CppAD::vector<CGD> indVars(2);
54  handler.makeVariables(indVars);
55 
56  CppAD::vector<CGD> jac = fun.SparseJacobian(indVars);
57 
58  LanguageC<double> langC("double");
59  LangCDefaultVariableNameGenerator<double> nameGen;
60 
61  std::ostringstream code;
62  handler.generateCode(code, langC, jac, nameGen);
63  std::cout << code.str();
64  }
65 
66  BOOST_AUTO_TEST_CASE(test_eigen_support)
67  {
68  typedef CppAD::cg::CG<double> CGD;
69  typedef CppAD::AD<CGD> ADCG;
70 
71  typedef Eigen::Matrix<ADCG,Eigen::Dynamic,1> ADCGVector;
72 
73  ADCGVector vec_zero(ADCGVector::Zero(100));
74  BOOST_CHECK(vec_zero.isZero());
75 
76  ADCGVector vec_ones(10);
77  vec_ones.fill((ADCG)1);
78  BOOST_CHECK(vec_ones.isOnes());
79 // std::cout << (ADCG)1 << std::endl;
80 
81  ADCG value_one(1.);
82 
83  ADCG value_nan;
84  value_nan = NAN;
85 
86  // nan
87  ADCGVector vec_nan(10);
88  vec_nan.fill((ADCG)NAN);
90 // std::cout << vec_nan.transpose() << std::endl;
91 //
92 // // abs
93  ADCG val_minus_one(-1.);
94  ADCG val_abs(abs(val_minus_one));
95  ADCGVector vec_minus_one(10); vec_minus_one.fill(val_minus_one);
96  vec_minus_one.array().abs();
97 
98  BOOST_CHECK(!vec_ones.isUnitary());
99 
100 
101  }
102 
104  {
105  typedef CppAD::cg::CG<double> CGScalar;
106  typedef CppAD::AD<double> ADScalar;
107  typedef CppAD::AD<float> ADFloat;
108  typedef pinocchio::ModelTpl<CGScalar> CGModel;
109 
111  typedef pinocchio::SE3Tpl<CGScalar> CGSE3;
112 
113  CGSE3 cg_M = M.cast<CGScalar>();
114  BOOST_CHECK(cg_M.cast<double>().isApprox(M));
115 
116  pinocchio::SE3::Vector3 axis(1.,1.,1.);
117  axis.normalize();
118  BOOST_CHECK(axis.isUnitary());
119 
120  pinocchio::JointModelPrismaticUnaligned jmodel_prismatic(axis);
121  typedef pinocchio::JointModelPrismaticUnalignedTpl<CGScalar> CGJointModelPrismaticUnaligned;
122 
123  CGScalar cg_value; cg_value = -1.;
124  ADScalar ad_value; ad_value = -1.;
125  ADFloat ad_float; ad_float = -1.;
126  abs(ad_value);
127  abs(ad_float);
128  abs(cg_value);
129 
130  CPPAD_TESTVECTOR(ADScalar) ad_x(3);
131  CGJointModelPrismaticUnaligned cg_jmodel_prismatic(axis.cast<CGScalar>());
132 
135 
136  CGModel cg_model = model.cast<CGScalar>();
137 
138  {
139  CppAD::AD<double> ad_value(-1.);
140  abs(ad_value); // works perfectly
141 
142  CppAD::cg::CG<double> cg_value(-1.);
143  abs(cg_value); // does not compile because abs<double>(const CppAD::cg::CG<double>&) is defined in namespace CppAD and not CppAD::cg
144 
145  }
146  }
147 
148  BOOST_AUTO_TEST_CASE(test_dynamic_link)
149  {
150  using namespace CppAD;
151  using namespace CppAD::cg;
152 
153  // use a special object for source code generation
154  typedef CG<double> CGD;
155  typedef AD<CGD> ADCG;
156 
157  typedef AD<double> ADScalar;
158 
159  /***************************************************************************
160  * the model
161  **************************************************************************/
162 
163  // independent variable vector
164  std::vector<ADCG> x(2);
165  Independent(x);
166 
167  // dependent variable vector
168  std::vector<ADCG> y(1);
169 
170  // the model equation
171  ADCG a = x[0] / 1. + x[1] * x[1];
172  y[0] = a / 2;
173 
174  ADFun<CGD> fun(x, y);
175 
176 
177  /***************************************************************************
178  * Create the dynamic library
179  * (generates and compiles source code)
180  **************************************************************************/
181  // generates source code
182  ModelCSourceGen<double> cgen(fun, "model");
183  cgen.setCreateJacobian(true);
184  cgen.setCreateForwardOne(true);
185  cgen.setCreateReverseOne(true);
186  cgen.setCreateReverseTwo(true);
187  ModelLibraryCSourceGen<double> libcgen(cgen);
188 
189  // compile source code
190  DynamicModelLibraryProcessor<double> p(libcgen);
191 
192  GccCompiler<double> compiler;
193  std::unique_ptr<DynamicLib<double>> dynamicLib = p.createDynamicLibrary(compiler);
194 
195  // save to files (not really required)
196  SaveFilesModelLibraryProcessor<double> p2(libcgen);
197  p2.saveSources();
198 
199  /***************************************************************************
200  * Use the dynamic library
201  **************************************************************************/
202 
203  std::unique_ptr<GenericModel<double>> model = dynamicLib->model("model");
204  CPPAD_TESTVECTOR(double) xv(x.size()); xv[0] = 2.5; xv[1] = 3.5;
205  CPPAD_TESTVECTOR(double) jac = model->Jacobian(xv);
206 
207  std::vector<ADScalar> x_ad(2);
208  Independent(x_ad);
209 
210  // dependent variable vector
211  std::vector<ADScalar> y_ad(1);
212 
213  // the model equation
214  ADScalar a_ad = x_ad[0] / 1. + x_ad[1] * x_ad[1];
215  y_ad[0] = a_ad / 2;
216 
217  ADFun<double> ad_fun(x_ad, y_ad);
218 
219  CPPAD_TESTVECTOR(double) jac_ref = ad_fun.Jacobian(xv);
220 
221  // print out the result
222  std::cout << jac[0] << " " << jac[1] << std::endl;
223 
224  BOOST_CHECK(Eigen::Map<Eigen::Vector2d>(jac.data()).isApprox(Eigen::Map<Eigen::Vector2d>(jac_ref.data())));
225  }
226 
227 BOOST_AUTO_TEST_SUITE_END()
axis
y
ModelTpl< NewScalar, Options, JointCollectionTpl > cast() const
BOOST_AUTO_TEST_CASE(test_simple_cppadcg)
bool isApprox(const Shape &s1, const Shape &s2, const FCL_REAL tol)
SE3Tpl< NewScalar, Options > cast() const
x
Vec3f a
traits< SE3Tpl >::Vector3 Vector3
M
void humanoidRandom(ModelTpl< Scalar, Options, JointCollectionTpl > &model, bool usingFF=true)
Create a humanoid kinematic tree with 6-DOF limbs and random joint placements.


pinocchio
Author(s):
autogenerated on Fri Jun 23 2023 02:38:29