- 3.0.2 optimal control module.
CostFunctionAD-impl.hpp
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 
6 #pragma once
7 
8 #ifdef CPPADCG
9 
10 namespace ct {
11 namespace optcon {
12 
13 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
14 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::CostFunctionAD()
15  : CostFunctionQuadratic<STATE_DIM, CONTROL_DIM, SCALAR>(),
16  stateControlTime_(Eigen::Matrix<SCALAR, STATE_DIM + CONTROL_DIM + 1, 1>::Zero())
17 {
18  intermediateFun_ = [&](const Eigen::Matrix<CGScalar, STATE_DIM + CONTROL_DIM + 1, 1>& stateInputTime) {
19  return this->evaluateIntermediateCg(stateInputTime);
20  };
21 
22  finalFun_ = [&](const Eigen::Matrix<CGScalar, STATE_DIM + CONTROL_DIM + 1, 1>& stateInputTime) {
23  return this->evaluateTerminalCg(stateInputTime);
24  };
25 
26  intermediateCostCodegen_ = std::shared_ptr<JacCG>(new JacCG(intermediateFun_, STATE_DIM + CONTROL_DIM + 1, 1));
27  finalCostCodegen_ = std::shared_ptr<JacCG>(new JacCG(finalFun_, STATE_DIM + CONTROL_DIM + 1, 1));
28 
29  setCurrentStateAndControl(this->x_, this->u_, this->t_);
30 }
31 
32 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
33 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::CostFunctionAD(const CostFunctionAD& arg)
34  : CostFunctionQuadratic<STATE_DIM, CONTROL_DIM, SCALAR>(arg),
35  stateControlTime_(arg.stateControlTime_),
36  intermediateFun_(arg.intermediateFun_),
37  finalFun_(arg.finalFun_)
38 {
39  intermediateTerms_.resize(arg.intermediateTerms_.size());
40  finalTerms_.resize(arg.finalTerms_.size());
41 
42  for (size_t i = 0; i < intermediateTerms_.size(); ++i)
43  intermediateTerms_[i] =
44  std::shared_ptr<TermBase<STATE_DIM, CONTROL_DIM, SCALAR, CGScalar>>(arg.intermediateTerms_[i]->clone());
45 
46  for (size_t i = 0; i < finalTerms_.size(); ++i)
47  finalTerms_[i] =
48  std::shared_ptr<TermBase<STATE_DIM, CONTROL_DIM, SCALAR, CGScalar>>(arg.finalTerms_[i]->clone());
49 
50  intermediateCostCodegen_ = std::shared_ptr<JacCG>(arg.intermediateCostCodegen_->clone());
51  finalCostCodegen_ = std::shared_ptr<JacCG>(arg.finalCostCodegen_->clone());
52 }
53 
54 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
55 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::CostFunctionAD(const std::string& filename, bool verbose)
56  : CostFunctionAD()
57 {
58  loadFromConfigFile(filename, verbose);
59 }
60 
61 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
62 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::~CostFunctionAD()
63 {
64 }
65 
66 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
67 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>* CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::clone() const
68 {
69  return new CostFunctionAD(*this);
70 }
71 
72 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
73 void CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::initialize()
74 {
75  intermediateFun_ = [&](const Eigen::Matrix<CGScalar, STATE_DIM + CONTROL_DIM + 1, 1>& stateInputTime) {
76  return this->evaluateIntermediateCg(stateInputTime);
77  };
78 
79  finalFun_ = [&](const Eigen::Matrix<CGScalar, STATE_DIM + CONTROL_DIM + 1, 1>& stateInputTime) {
80  return this->evaluateTerminalCg(stateInputTime);
81  };
82 
83  intermediateCostCodegen_->update(intermediateFun_, STATE_DIM + CONTROL_DIM + 1, 1);
84  finalCostCodegen_->update(finalFun_, STATE_DIM + CONTROL_DIM + 1, 1);
85 
88  settings.createForwardZero_ = true;
89  settings.createJacobian_ = true;
90  settings.createHessian_ = true;
91 
92  finalCostCodegen_->compileJIT(settings, "finalCosts");
93  intermediateCostCodegen_->compileJIT(settings, "intermediateCosts");
94 }
95 
96 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
97 void CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::addIntermediateADTerm(
98  std::shared_ptr<TermBase<STATE_DIM, CONTROL_DIM, SCALAR, CGScalar>> term,
99  bool verbose)
100 {
101  intermediateTerms_.push_back(term);
102 
103  if (verbose)
104  {
105  std::cout << term->getName() + " added as intermediate AD term" << std::endl;
106  }
107 }
108 
109 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
110 void CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::addFinalADTerm(
111  std::shared_ptr<TermBase<STATE_DIM, CONTROL_DIM, SCALAR, CGScalar>> term,
112  bool verbose)
113 {
114  finalTerms_.push_back(term);
115 
116  if (verbose)
117  {
118  std::cout << term->getName() + " added as final AD term" << std::endl;
119  }
120 }
121 
122 // set state and control
123 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
124 void CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::setCurrentStateAndControl(const state_vector_t& x,
125  const control_vector_t& u,
126  const SCALAR& t)
127 {
128  this->x_ = x;
129  this->u_ = u;
130  this->t_ = t;
131 
132  stateControlTime_ << x, u, t;
133 }
134 
135 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
136 void CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::loadFromConfigFile(const std::string& filename, bool verbose)
137 {
138  this->intermediateCostAnalytical_.clear();
139  this->finalCostAnalytical_.clear();
140 
141  boost::property_tree::ptree pt;
142  boost::property_tree::read_info(filename, pt);
143  int i = 0;
144  std::string currentTerm;
145  do
146  {
147  currentTerm = "term" + std::to_string(i);
148  std::string termKind = pt.get<std::string>(currentTerm + ".kind");
149  boost::algorithm::to_lower(termKind);
150  int currentTermType = pt.get<int>(currentTerm + ".type");
151  std::string termName;
152  try
153  {
154  termName = pt.get<std::string>(currentTerm + ".name");
155  } catch (boost::property_tree::ptree_bad_path err)
156  {
157  termName = "Unnamed";
158  if (verbose)
159  {
160  std::cout << "Name field for " + currentTerm + " does not exist" << std::endl;
161  }
162  }
163 
164  std::shared_ptr<TermBase<STATE_DIM, CONTROL_DIM, SCALAR, CGScalar>> term;
165 
166  CT_LOADABLE_TERMS(SCALAR, CGScalar);
167 
168  if (!term)
169  {
170  throw std::runtime_error("Term type \"" + termKind + "\" not supported");
171  }
172  else
173  {
174  if (term)
175  addADTerm(filename, currentTerm, currentTermType, term, this, verbose);
176  else
177  throw std::runtime_error("Term type \"" + termKind + "\" loaded but unsupported.");
178  }
179  currentTerm = "term" + std::to_string(++i);
180  } while (pt.find(currentTerm) != pt.not_found());
181 }
182 
183 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
184 typename CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::MatrixCg
185 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::evaluateIntermediateCg(
186  const Eigen::Matrix<CGScalar, STATE_DIM + CONTROL_DIM + 1, 1>& stateInputTime)
187 {
188  CGScalar y = CGScalar(0.0);
189 
190  for (auto it : intermediateTerms_)
191  y += it->evaluateCppadCg(stateInputTime.segment(0, STATE_DIM), stateInputTime.segment(STATE_DIM, CONTROL_DIM),
192  stateInputTime(STATE_DIM + CONTROL_DIM));
193 
194  Eigen::Matrix<CGScalar, 1, 1> out;
195  out << y;
196  return out;
197 }
198 
199 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
200 typename CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::MatrixCg
201 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::evaluateTerminalCg(
202  const Eigen::Matrix<CGScalar, STATE_DIM + CONTROL_DIM + 1, 1>& stateInputTime)
203 {
204  CGScalar y = CGScalar(0.0);
205 
206  for (auto it : finalTerms_)
207  y += it->evaluateCppadCg(stateInputTime.segment(0, STATE_DIM), stateInputTime.segment(STATE_DIM, CONTROL_DIM),
208  stateInputTime(STATE_DIM + CONTROL_DIM));
209 
210  Eigen::Matrix<CGScalar, 1, 1> out;
211  out << y;
212  return out;
213 }
214 
215 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
216 SCALAR CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::evaluateIntermediate()
217 {
218  return this->evaluateIntermediateBase() + intermediateCostCodegen_->forwardZero(stateControlTime_)(0);
219 }
220 
221 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
222 SCALAR CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::evaluateTerminal()
223 {
224  return this->evaluateTerminalBase() + finalCostCodegen_->forwardZero(stateControlTime_)(0);
225 }
226 
227 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
228 typename CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::state_vector_t
229 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::stateDerivativeIntermediate()
230 {
231  Eigen::Matrix<SCALAR, 1, STATE_DIM + CONTROL_DIM + 1> jacTot =
232  intermediateCostCodegen_->jacobian(stateControlTime_);
233  return jacTot.template leftCols<STATE_DIM>().transpose() + this->stateDerivativeIntermediateBase();
234 }
235 
236 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
237 typename CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::state_vector_t
238 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::stateDerivativeTerminal()
239 {
240  Eigen::Matrix<SCALAR, 1, STATE_DIM + CONTROL_DIM + 1> jacTot = finalCostCodegen_->jacobian(stateControlTime_);
241  return jacTot.template leftCols<STATE_DIM>().transpose() + this->stateDerivativeTerminalBase();
242 }
243 
244 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
245 typename CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::control_vector_t
246 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::controlDerivativeIntermediate()
247 {
248  Eigen::Matrix<SCALAR, 1, STATE_DIM + CONTROL_DIM + 1> jacTot =
249  intermediateCostCodegen_->jacobian(stateControlTime_);
250  return jacTot.template block<1, CONTROL_DIM>(0, STATE_DIM).transpose() + this->controlDerivativeIntermediateBase();
251 }
252 
253 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
254 typename CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::control_vector_t
255 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::controlDerivativeTerminal()
256 {
257  Eigen::Matrix<SCALAR, 1, STATE_DIM + CONTROL_DIM + 1> jacTot = finalCostCodegen_->jacobian(stateControlTime_);
258  return jacTot.template block<1, CONTROL_DIM>(0, STATE_DIM).transpose() + this->controlDerivativeTerminalBase();
259 }
260 
261 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
262 typename CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::state_matrix_t
263 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::stateSecondDerivativeIntermediate()
264 {
265  Eigen::Matrix<SCALAR, 1, 1> w;
266  w << SCALAR(1.0);
267  MatrixXs hesTot = intermediateCostCodegen_->hessian(stateControlTime_, w);
268  return hesTot.template block<STATE_DIM, STATE_DIM>(0, 0) + this->stateSecondDerivativeIntermediateBase();
269 }
270 
271 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
272 typename CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::state_matrix_t
273 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::stateSecondDerivativeTerminal()
274 {
275  Eigen::Matrix<SCALAR, 1, 1> w;
276  w << SCALAR(1.0);
277  MatrixXs hesTot = finalCostCodegen_->hessian(stateControlTime_, w);
278  return hesTot.template block<STATE_DIM, STATE_DIM>(0, 0) + this->stateSecondDerivativeTerminalBase();
279 }
280 
281 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
282 typename CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::control_matrix_t
283 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::controlSecondDerivativeIntermediate()
284 {
285  Eigen::Matrix<SCALAR, 1, 1> w;
286  w << SCALAR(1.0);
287  MatrixXs hesTot = intermediateCostCodegen_->hessian(stateControlTime_, w);
288  return hesTot.template block<CONTROL_DIM, CONTROL_DIM>(STATE_DIM, STATE_DIM) +
289  this->controlSecondDerivativeIntermediateBase();
290 }
291 
292 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
293 typename CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::control_matrix_t
294 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::controlSecondDerivativeTerminal()
295 {
296  Eigen::Matrix<SCALAR, 1, 1> w;
297  w << SCALAR(1.0);
298  MatrixXs hesTot = finalCostCodegen_->hessian(stateControlTime_, w);
299  return hesTot.template block<CONTROL_DIM, CONTROL_DIM>(STATE_DIM, STATE_DIM) +
300  this->controlSecondDerivativeTerminalBase();
301 }
302 
303 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
304 typename CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::control_state_matrix_t
305 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::stateControlDerivativeIntermediate()
306 {
307  Eigen::Matrix<SCALAR, 1, 1> w;
308  w << SCALAR(1.0);
309  MatrixXs hesTot = intermediateCostCodegen_->hessian(stateControlTime_, w);
310  return hesTot.template block<CONTROL_DIM, STATE_DIM>(STATE_DIM, 0) + this->stateControlDerivativeIntermediateBase();
311 }
312 
313 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
314 typename CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::control_state_matrix_t
315 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::stateControlDerivativeTerminal()
316 {
317  Eigen::Matrix<SCALAR, 1, 1> w;
318  w << SCALAR(1.0);
319  MatrixXs hesTot = finalCostCodegen_->hessian(stateControlTime_, w);
320  return hesTot.template block<CONTROL_DIM, STATE_DIM>(STATE_DIM, 0) + this->stateControlDerivativeTerminalBase();
321 }
322 
323 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
324 std::shared_ptr<ct::optcon::
325  TermBase<STATE_DIM, CONTROL_DIM, SCALAR, typename CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::CGScalar>>
326 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::getIntermediateADTermById(const size_t id)
327 {
328  return intermediateTerms_[id];
329 }
330 
331 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
332 std::shared_ptr<ct::optcon::
333  TermBase<STATE_DIM, CONTROL_DIM, SCALAR, typename CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::CGScalar>>
334 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::getFinalADTermById(const size_t id)
335 {
336  return finalTerms_[id];
337 }
338 
339 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
340 std::shared_ptr<
341  TermBase<STATE_DIM, CONTROL_DIM, SCALAR, typename CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::CGScalar>>
342 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::getIntermediateADTermByName(const std::string& name)
343 {
344  for (auto term : intermediateTerms_)
345  if (term->getName() == name)
346  return term;
347 
348  throw std::runtime_error("Term " + name + " not found in the CostFunctionAD");
349 }
350 
351 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
352 std::shared_ptr<
353  TermBase<STATE_DIM, CONTROL_DIM, SCALAR, typename CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::CGScalar>>
354 CostFunctionAD<STATE_DIM, CONTROL_DIM, SCALAR>::getFinalADTermByName(const std::string& name)
355 {
356  for (auto term : finalTerms_)
357  if (term->getName() == name)
358  return term;
359 
360  throw std::runtime_error("Term " + name + " not found in the CostFunctionAD");
361 }
362 } // namespace optcon
363 } // namespace ct
364 
365 #endif
state_vector_t x_
Definition: CostFunction.hpp:103
virtual void setCurrentStateAndControl(const state_vector_t &x, const control_vector_t &u, const SCALAR &t=SCALAR(0.0))
Definition: CostFunction-impl.hpp:30
ct::core::ControlVector< control_dim > u
Definition: LoadFromFileTest.cpp:21
Eigen::Matrix< double, nControls, 1 > control_vector_t
SCALAR t_
Definition: CostFunction.hpp:105
clear all close all load ct GNMSLog0 mat reformat t
Definition: gnmsPlot.m:6
CppAD::AD< CppAD::cg::CG< double > > SCALAR
void addADTerm(const std::string &filename, std::string &currentTerm, int currentTermType, TERM_PTR term, costFuncType *costFunc, bool verbose=false)
Definition: utilities.hpp:113
for i
Definition: mpc_unittest_plotting.m:14
ct::core::DerivativesCppadCG< state_dim, control_dim > JacCG
ct::core::StateVector< state_dim > x
Definition: LoadFromFileTest.cpp:20
control_vector_t u_
Definition: CostFunction.hpp:104
Eigen::Matrix< double, nStates, 1 > state_vector_t
const bool verbose
Definition: ConstraintComparison.h:18
#define CT_LOADABLE_TERMS(SCALAR_EVAL, SCALAR)
Definition: TermLoadMacros.hpp:18