- 3.0.2 core module.
DiscreteSystemLinearizerADCG.h
Go to the documentation of this file.
1 /**********************************************************************************************************************
2 This file is part of the Control Toolbox (https://github.com/ethz-adrl/control-toolbox), copyright by ETH Zurich.
3 Licensed under the BSD-2 license (see LICENSE file in main directory)
4 **********************************************************************************************************************/
5 #pragma once
6 
7 #ifdef CPPADCG
8 
9 namespace ct {
10 namespace core {
11 
13 
48 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR = double>
49 class DiscreteSystemLinearizerADCG : public DiscreteLinearSystem<STATE_DIM, CONTROL_DIM, SCALAR>
50 {
51 public:
52  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
53 
54  typedef DiscreteLinearSystem<STATE_DIM, CONTROL_DIM, SCALAR> Base;
55 
56  typedef CppAD::AD<CppAD::cg::CG<SCALAR>> ADCGScalar;
57 
58  typedef DiscreteControlledSystem<STATE_DIM, CONTROL_DIM, ADCGScalar> system_t;
59  typedef DynamicsLinearizerADCG<STATE_DIM, CONTROL_DIM, ADCGScalar, int>
60  linearizer_t;
61 
62 
63  typedef typename Base::state_vector_t state_vector_t;
64  typedef typename Base::control_vector_t control_vector_t;
65 
66  typedef typename Base::state_matrix_t state_matrix_t;
67  typedef typename Base::state_control_matrix_t state_control_matrix_t;
68 
70 
73  DiscreteSystemLinearizerADCG(std::shared_ptr<system_t> nonlinearSystem, bool cacheJac = true)
74  : Base(nonlinearSystem->getType()),
75  dFdx_(state_matrix_t::Zero()),
76  dFdu_(state_control_matrix_t::Zero()),
77  cacheJac_(cacheJac),
78  nonlinearSystem_(nonlinearSystem),
79  linearizer_(std::bind(&system_t::propagateControlledDynamics,
80  nonlinearSystem_.get(),
81  std::placeholders::_1,
82  std::placeholders::_2,
83  std::placeholders::_3,
84  std::placeholders::_4))
85  {
86  }
87 
89  DiscreteSystemLinearizerADCG(const DiscreteSystemLinearizerADCG& arg)
90  : Base(arg.nonlinearSystem_->getType()),
91  dFdx_(arg.dFdx_),
92  dFdu_(arg.dFdu_),
93  cacheJac_(arg.cacheJac_),
94  nonlinearSystem_(arg.nonlinearSystem_->clone()),
95  linearizer_(arg.linearizer_)
96  {
97  }
98 
100  virtual ~DiscreteSystemLinearizerADCG() {}
102  DiscreteSystemLinearizerADCG<STATE_DIM, CONTROL_DIM, SCALAR>* clone() const override
103  {
104  return new DiscreteSystemLinearizerADCG<STATE_DIM, CONTROL_DIM, SCALAR>(*this);
105  }
106 
108 
121  const state_matrix_t& getDerivativeState(const state_vector_t& x, const control_vector_t& u, const int t = 0)
122  {
123  dFdx_ = linearizer_.getDerivativeState(x, u, t);
124  return dFdx_;
125  }
126 
127 
129 
142  const state_control_matrix_t& getDerivativeControl(const state_vector_t& x,
143  const control_vector_t& u,
144  const int t = 0)
145  {
146  dFdu_ = linearizer_.getDerivativeControl(x, u, t);
147  return dFdu_;
148  }
149 
151 
167  void getAandB(const state_vector_t& x,
168  const control_vector_t& u,
169  const state_vector_t& x_next,
170  const int n,
171  size_t numSteps,
172  state_matrix_t& A,
173  state_control_matrix_t& B) override
174  {
175  dFdx_ = linearizer_.getDerivativeState(x, u, n);
176  dFdu_ = linearizer_.getDerivativeControl(x, u, n);
177 
178  A = dFdx_;
179  B = dFdu_;
180  }
181 
183 
189  void compileJIT(const std::string& libName = "DiscreteSystemLinearizerADCG") { linearizer_.compileJIT(libName); }
191 
204  void generateCode(const std::string& systemName,
205  const std::string& outputDir = ct::core::CODEGEN_OUTPUT_DIR,
206  const std::string& templateDir = ct::core::CODEGEN_TEMPLATE_DIR,
207  const std::string& ns1 = "core",
208  const std::string& ns2 = "generated",
209  bool useReverse = false,
210  bool ignoreZero = true)
211  {
212  std::string codeJacA, codeJacB;
213  linearizer_.generateCode(codeJacA, codeJacB, useReverse, ignoreZero);
214 
215  writeCodeFile(
216  templateDir, outputDir, systemName, ns1, ns2, codeJacA, codeJacB, "AUTOGENERATED_CODE_PLACEHOLDER");
217  }
218 
220  const linearizer_t& getLinearizer() const { return linearizer_; }
221 private:
223 
234  void writeCodeFile(const std::string& templateDir,
235  const std::string& outputDir,
236  const std::string& systemName,
237  const std::string& ns1,
238  const std::string& ns2,
239  const std::string& codeJacA,
240  const std::string& codeJacB,
241  const std::string& codePlaceholder)
242  {
243  std::cout << "Generating discrete linear system..." << std::endl;
244 
245  size_t maxTempVarCountState, maxTempVarCountControl;
246  linearizer_.getMaxTempVarCount(maxTempVarCountState, maxTempVarCountControl);
247 
248  std::string header = internal::CGHelpers::parseFile(templateDir + "/DiscreteLinearSystem.tpl.h");
249  std::string sourceA = internal::CGHelpers::parseFile(templateDir + "/DiscreteLinearSystem.tplA.cpp");
250  std::string sourceB = internal::CGHelpers::parseFile(templateDir + "/DiscreteLinearSystem.tplB.cpp");
251 
252  const std::string scalarName(linearizer_.getOutScalarType());
253 
254  replaceSizesAndNames(header, systemName, scalarName, ns1, ns2);
255  replaceSizesAndNames(sourceA, systemName, scalarName, ns1, ns2);
256  replaceSizesAndNames(sourceB, systemName, scalarName, ns1, ns2);
257 
258  internal::CGHelpers::replaceOnce(header, "MAX_COUNT_STATE", std::to_string(maxTempVarCountState));
259  internal::CGHelpers::replaceOnce(header, "MAX_COUNT_CONTROL", std::to_string(maxTempVarCountControl));
260 
261  internal::CGHelpers::replaceOnce(sourceA, codePlaceholder + "_JAC_A", codeJacA);
262  internal::CGHelpers::replaceOnce(sourceB, codePlaceholder + "_JAC_B", codeJacB);
263 
264  internal::CGHelpers::writeFile(outputDir + "/" + systemName + ".h", header);
265  internal::CGHelpers::writeFile(outputDir + "/" + systemName + "_A.cpp", sourceA);
266  internal::CGHelpers::writeFile(outputDir + "/" + systemName + "_B.cpp", sourceB);
267 
268 
269  std::cout << "... Done! Successfully generated discrete linear system" << std::endl;
270  }
271 
273 
280  void replaceSizesAndNames(std::string& file,
281  const std::string& systemName,
282  const std::string& scalarName,
283  const std::string& ns1,
284  const std::string& ns2)
285  {
286  internal::CGHelpers::replaceAll(file, "LINEAR_SYSTEM_NAME", systemName);
287  internal::CGHelpers::replaceAll(file, "NS1", ns1);
288  internal::CGHelpers::replaceAll(file, "NS2", ns2);
289  internal::CGHelpers::replaceAll(file, "STATE_DIM", std::to_string(STATE_DIM));
290  internal::CGHelpers::replaceAll(file, "CONTROL_DIM", std::to_string(CONTROL_DIM));
291  internal::CGHelpers::replaceAll(file, "SCALAR", scalarName);
292  }
293 
294 protected:
295  state_matrix_t dFdx_;
296  state_control_matrix_t dFdu_;
297 
298  bool cacheJac_;
299 
300  std::shared_ptr<system_t> nonlinearSystem_;
301 
302  linearizer_t linearizer_;
303 };
304 
305 } // namespace core
306 } // namespace ct
307 
308 #endif
Eigen::Matrix< double, nControls, 1 > control_vector_t
constexpr size_t n
Definition: MatrixInversionTest.cpp:14
Eigen::Matrix< double, nStates, nStates > state_matrix_t
Eigen::Matrix< double, nStates, 1 > state_vector_t