- 3.0.2 optimal control module.
SensitivityIntegratorCT.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 
6 
7 #pragma once
8 
9 namespace ct {
10 namespace optcon {
11 
12 
22 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR = double>
24 {
25 public:
26  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
29  typedef Eigen::Matrix<SCALAR, STATE_DIM, STATE_DIM> state_matrix;
30  typedef Eigen::Matrix<SCALAR, CONTROL_DIM, CONTROL_DIM> control_matrix;
31  typedef Eigen::Matrix<SCALAR, STATE_DIM, CONTROL_DIM> state_control_matrix;
32 
33 
41  const ct::core::IntegrationType stepperType = ct::core::IntegrationType::EULERCT)
42  : cacheData_(false), cacheSensitivities_(false)
43  {
44  setControlledSystem(system);
45  initializeDerived(stepperType);
46  }
47 
51  ~SensitivityIntegratorCT() = default;
58  {
59  switch (stepperType)
60  {
61  case ct::core::IntegrationType::EULERCT:
62  {
63  stepperState_ = std::shared_ptr<ct::core::internal::StepperCTBase<state_vector, SCALAR>>(
65  stepperDX0_ = std::shared_ptr<ct::core::internal::StepperCTBase<state_matrix, SCALAR>>(
67  stepperDU0_ = std::shared_ptr<ct::core::internal::StepperCTBase<state_control_matrix, SCALAR>>(
69  stepperCost_ = std::shared_ptr<ct::core::internal::StepperCTBase<SCALAR, SCALAR>>(
71  stepperCostDX0_ = std::shared_ptr<ct::core::internal::StepperCTBase<state_vector, SCALAR>>(
73  stepperCostDU0_ = std::shared_ptr<ct::core::internal::StepperCTBase<control_vector, SCALAR>>(
75  break;
76  }
77 
78  case ct::core::IntegrationType::RK4CT:
79  {
80  stepperState_ = std::shared_ptr<ct::core::internal::StepperCTBase<state_vector, SCALAR>>(
82  stepperDX0_ = std::shared_ptr<ct::core::internal::StepperCTBase<state_matrix, SCALAR>>(
84  stepperDU0_ = std::shared_ptr<ct::core::internal::StepperCTBase<state_control_matrix, SCALAR>>(
86  stepperCost_ = std::shared_ptr<ct::core::internal::StepperCTBase<SCALAR, SCALAR>>(
88  stepperCostDX0_ = std::shared_ptr<ct::core::internal::StepperCTBase<state_vector, SCALAR>>(
90  stepperCostDU0_ = std::shared_ptr<ct::core::internal::StepperCTBase<control_vector, SCALAR>>(
92  break;
93  }
94 
95  default:
96  throw std::runtime_error("Invalid CT integration type");
97  }
98  }
99 
108  {
109  linearSystem_ = linearSystem;
110  cacheData_ = true;
111 
112  dX0dot_ = [this](const state_matrix& dX0In, state_matrix& dX0dt, const SCALAR t) {
113  if (cacheSensitivities_)
114  arraydX0_.push_back(dX0In);
115 
116  dX0dt = arrayA_[dX0Index_] * dX0In;
117  dX0Index_++;
118  };
119 
120  dU0dot_ = [this](const state_control_matrix& dU0In, state_control_matrix& dU0dt, const SCALAR t) {
121  if (cacheSensitivities_)
122  arraydU0_.push_back(dU0In);
123 
124  dU0dt = arrayA_[dU0Index_] * dU0In +
125  arrayB_[dU0Index_] *
126  controlledSystem_->getController()->getDerivativeU0(
127  statesCached_[dU0Index_], timesCached_[dU0Index_]);
128  dU0Index_++;
129  };
130 
131  dUfdot_ = [this](const state_control_matrix& dUfIn, state_control_matrix& dUfdt, const SCALAR t) {
132  if (cacheSensitivities_)
133  arraydUf_.push_back(dUfIn);
134 
135  dUfdt = arrayA_[dU0Index_] * dUfIn +
136  arrayB_[dU0Index_] *
137  controlledSystem_->getController()->getDerivativeUf(
138  statesCached_[dU0Index_], timesCached_[dU0Index_]);
139  dU0Index_++;
140  };
141  }
142 
149  const std::shared_ptr<ct::core::ControlledSystem<STATE_DIM, CONTROL_DIM, SCALAR>>& controlledSystem)
150  {
151  controlledSystem_ = controlledSystem;
152  xDot_ = [this](const state_vector& x, state_vector& dxdt, const SCALAR t) {
153  control_vector controlAction;
154  controlledSystem_->getController()->computeControl(x, t, controlAction);
155 
156  if (cacheData_)
157  {
158  statesCached_.push_back(x);
159  controlsCached_.push_back(controlAction);
160  timesCached_.push_back(t);
161  }
162 
163  controlledSystem_->computeControlledDynamics(x, t, controlAction, dxdt);
164  };
165  }
166 
175  {
176  costFunction_ = costFun;
177  cacheSensitivities_ = true;
178  costDot_ = [this](const SCALAR& costIn, SCALAR& cost, const SCALAR t) {
179  costFunction_->setCurrentStateAndControl(
180  statesCached_[costIndex_], controlsCached_[costIndex_], timesCached_[costIndex_]);
181  cost = costFunction_->evaluateIntermediate();
182  costIndex_++;
183  };
184 
185  costdX0dot_ = [this](const state_vector& costdX0In, state_vector& costdX0dt, const SCALAR t) {
186  costFunction_->setCurrentStateAndControl(
187  statesCached_[costIndex_], controlsCached_[costIndex_], timesCached_[costIndex_]);
188  costdX0dt = arraydX0_[costIndex_].transpose() * costFunction_->stateDerivativeIntermediate();
189  costIndex_++;
190  };
191 
192  costdU0dot_ = [this](const control_vector& costdU0In, control_vector& costdU0dt, const SCALAR t) {
193  costFunction_->setCurrentStateAndControl(
194  statesCached_[costIndex_], controlsCached_[costIndex_], timesCached_[costIndex_]);
195  costdU0dt = arraydU0_[costIndex_].transpose() * costFunction_->stateDerivativeIntermediate() +
196  controlledSystem_->getController()->getDerivativeU0(
197  statesCached_[costIndex_], timesCached_[costIndex_]) *
198  costFunction_->controlDerivativeIntermediate();
199  costIndex_++;
200  };
201 
202  costdUfdot_ = [this](const control_vector& costdUfIn, control_vector& costdUfdt, const SCALAR t) {
203  costFunction_->setCurrentStateAndControl(
204  statesCached_[costIndex_], controlsCached_[costIndex_], timesCached_[costIndex_]);
205  costdUfdt = arraydUf_[costIndex_].transpose() * costFunction_->stateDerivativeIntermediate() +
206  controlledSystem_->getController()->getDerivativeUf(
207  statesCached_[costIndex_], timesCached_[costIndex_]) *
208  costFunction_->controlDerivativeIntermediate();
209  costIndex_++;
210  };
211  }
212 
225  void integrate(state_vector& state,
226  const SCALAR startTime,
227  const size_t numSteps,
228  const SCALAR dt,
230  ct::core::tpl::TimeArray<SCALAR>& timeTrajectory)
231  {
232  clearStates();
234  cacheData_ = true;
235  stateTrajectory.clear();
236  timeTrajectory.clear();
237  SCALAR time = startTime;
238  stateTrajectory.push_back(state);
239  timeTrajectory.push_back(time);
240 
241  for (size_t i = 0; i < numSteps; ++i)
242  {
243  stepperState_->do_step(xDot_, state, time, dt);
244  time += dt;
245  stateTrajectory.push_back(state);
246  timeTrajectory.push_back(time);
247  }
248  }
249 
260  void integrate(state_vector& state, const SCALAR startTime, const size_t numSteps, const SCALAR dt)
261  {
262  clearStates();
264  SCALAR time = startTime;
265  for (size_t i = 0; i < numSteps; ++i)
266  {
267  stepperState_->do_step(xDot_, state, time, dt);
268  time += dt;
269  }
270  }
271 
272 
282  void integrateSensitivityDX0(state_matrix& dX0, const SCALAR startTime, const size_t numSteps, const SCALAR dt)
283  {
284  dX0Index_ = 0;
285  SCALAR time = startTime;
286  dX0.setIdentity();
287  for (size_t i = 0; i < numSteps; ++i)
288  {
289  stepperDX0_->do_step(dX0dot_, dX0, time, dt);
290  time += dt;
291  }
292  }
293 
303  void integrateSensitivityDU0(state_control_matrix& dU0,
304  const SCALAR startTime,
305  const size_t numSteps,
306  const SCALAR dt)
307  {
308  dU0Index_ = 0;
309  SCALAR time = startTime;
310  dU0.setZero();
311  for (size_t i = 0; i < numSteps; ++i)
312  {
313  stepperDU0_->do_step(dU0dot_, dU0, time, dt);
314  time += dt;
315  }
316  }
317 
327  void integrateSensitivityDUf(state_control_matrix& dUf,
328  const SCALAR startTime,
329  const size_t numSteps,
330  const SCALAR dt)
331  {
332  dU0Index_ = 0;
333  SCALAR time = startTime;
334  dUf.setZero();
335  for (size_t i = 0; i < numSteps; ++i)
336  {
337  stepperDU0_->do_step(dUfdot_, dUf, time, dt);
338  time += dt;
339  }
340  }
341 
351  void integrateCost(SCALAR& cost, const SCALAR startTime, const size_t numSteps, const SCALAR dt)
352  {
353  SCALAR time = startTime;
354  costIndex_ = 0;
355  if (statesCached_.size() == 0 || controlsCached_.size() == 0 || timesCached_.size() == 0)
356  throw std::runtime_error("States cached are empty");
357 
358  for (size_t i = 0; i < numSteps; ++i)
359  {
360  stepperCost_->do_step(costDot_, cost, time, dt);
361  time += dt;
362  }
363  }
364 
365 
375  void integrateCostSensitivityDX0(state_vector& dX0, const SCALAR startTime, const size_t numSteps, const SCALAR dt)
376  {
377  costIndex_ = 0;
378  SCALAR time = startTime;
379  dX0.setZero();
380  for (size_t i = 0; i < numSteps; ++i)
381  {
382  stepperCostDX0_->do_step(costdX0dot_, dX0, time, dt);
383  time += dt;
384  }
385  }
386 
396  void integrateCostSensitivityDU0(control_vector& dU0,
397  const SCALAR startTime,
398  const size_t numSteps,
399  const SCALAR dt)
400  {
401  costIndex_ = 0;
402  SCALAR time = startTime;
403  dU0.setZero();
404  for (size_t i = 0; i < numSteps; ++i)
405  {
406  stepperCostDU0_->do_step(costdU0dot_, dU0, time, dt);
407  time += dt;
408  }
409  }
410 
420  void integrateCostSensitivityDUf(control_vector& dUf,
421  const SCALAR& startTime,
422  const size_t numSteps,
423  const SCALAR dt)
424  {
425  costIndex_ = 0;
426  SCALAR time = startTime;
427  dUf.setZero();
428  for (size_t i = 0; i < numSteps; ++i)
429  {
430  stepperCostDU0_->do_step(costdUfdot_, dUf, time, dt);
431  time += dt;
432  }
433  }
434 
439  void linearize()
440  {
441  for (size_t i = 0; i < statesCached_.size(); ++i)
442  {
443  arrayA_.push_back(linearSystem_->getDerivativeState(statesCached_[i], controlsCached_[i], timesCached_[i]));
444  arrayB_.push_back(
445  linearSystem_->getDerivativeControl(statesCached_[i], controlsCached_[i], timesCached_[i]));
446  }
447  }
448 
452  void clearStates()
453  {
454  statesCached_.clear();
455  controlsCached_.clear();
456  timesCached_.clear();
457  }
458 
459 
464  {
465  arraydX0_.clear();
466  arraydU0_.clear();
467  arraydUf_.clear();
468  }
469 
470 
475  {
476  arrayA_.clear();
477  arrayB_.clear();
478  }
479 
480 private:
481  std::shared_ptr<ct::core::ControlledSystem<STATE_DIM, CONTROL_DIM, SCALAR>> controlledSystem_;
482  std::shared_ptr<ct::core::LinearSystem<STATE_DIM, CONTROL_DIM, SCALAR>> linearSystem_;
483  std::shared_ptr<optcon::CostFunctionQuadratic<STATE_DIM, CONTROL_DIM, SCALAR>> costFunction_;
484 
485  // Integrate the function
486  std::function<void(const SCALAR, SCALAR&, const SCALAR)> costDot_;
487  std::function<void(const state_vector&, state_vector&, const SCALAR)> costdX0dot_;
488  std::function<void(const control_vector&, control_vector&, const SCALAR)> costdU0dot_;
489  std::function<void(const control_vector&, control_vector&, const SCALAR)> costdUfdot_;
490 
491  // Sensitivities
492  std::function<void(const state_matrix&, state_matrix&, const SCALAR)> dX0dot_;
493  std::function<void(const state_control_matrix&, state_control_matrix&, const SCALAR)> dU0dot_;
494  std::function<void(const state_control_matrix&, state_control_matrix&, const SCALAR)> dUfdot_;
495 
496  // Cache
497  bool cacheData_;
498  bool cacheSensitivities_;
502 
505 
509 
510  std::shared_ptr<ct::core::internal::StepperCTBase<state_vector, SCALAR>> stepperState_;
511  std::shared_ptr<ct::core::internal::StepperCTBase<state_matrix, SCALAR>> stepperDX0_;
512  std::shared_ptr<ct::core::internal::StepperCTBase<state_control_matrix, SCALAR>> stepperDU0_;
513 
514  std::shared_ptr<ct::core::internal::StepperCTBase<SCALAR, SCALAR>> stepperCost_;
515  std::shared_ptr<ct::core::internal::StepperCTBase<state_vector, SCALAR>> stepperCostDX0_;
516  std::shared_ptr<ct::core::internal::StepperCTBase<control_vector, SCALAR>> stepperCostDU0_;
517 
518  size_t costIndex_;
519  size_t dX0Index_;
520  size_t dU0Index_;
521 
522  std::function<void(const state_vector&, state_vector&, const SCALAR)> xDot_;
523 };
524 }
525 }
void integrateCostSensitivityDUf(control_vector &dUf, const SCALAR &startTime, const size_t numSteps, const SCALAR dt)
Integrates the sensitivity of the cost with respect to the final control input uF.
Definition: SensitivityIntegratorCT.h:420
void integrateCost(SCALAR &cost, const SCALAR startTime, const size_t numSteps, const SCALAR dt)
Integrates the costfunction using the states and controls from the costintegration.
Definition: SensitivityIntegratorCT.h:351
void integrateSensitivityDU0(state_control_matrix &dU0, const SCALAR startTime, const size_t numSteps, const SCALAR dt)
Integrates the sensitivity ODE of the integrator with respec to the initial control input u0...
Definition: SensitivityIntegratorCT.h:303
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef ct::core::StateVector< STATE_DIM, SCALAR > state_vector
Definition: SensitivityIntegratorCT.h:27
void integrate(state_vector &state, const SCALAR startTime, const size_t numSteps, const SCALAR dt)
Integrates the system starting from state and startTime for numSteps integration steps. Returns only the final state and time.
Definition: SensitivityIntegratorCT.h:260
void integrateCostSensitivityDX0(state_vector &dX0, const SCALAR startTime, const size_t numSteps, const SCALAR dt)
Integrates the sensitivity of the cost with respect to the initial state x0.
Definition: SensitivityIntegratorCT.h:375
clear all close all load ct GNMSLog0 mat reformat t
Definition: gnmsPlot.m:6
void clearSensitivities()
Clears the cached sensitivities.
Definition: SensitivityIntegratorCT.h:463
const double dt
Definition: LQOCSolverTiming.cpp:18
Describes a cost function with a quadratic approximation, i.e. one that can compute first and second ...
Definition: CostFunctionQuadratic.hpp:29
CppAD::AD< CppAD::cg::CG< double > > SCALAR
Eigen::Matrix< SCALAR, STATE_DIM, STATE_DIM > state_matrix
Definition: SensitivityIntegratorCT.h:29
for i
Definition: mpc_unittest_plotting.m:14
~SensitivityIntegratorCT()=default
Destroys the object.
void clearStates()
Clears the cached states, controls and times.
Definition: SensitivityIntegratorCT.h:452
void integrate(state_vector &state, const SCALAR startTime, const size_t numSteps, const SCALAR dt, ct::core::StateVectorArray< STATE_DIM, SCALAR > &stateTrajectory, ct::core::tpl::TimeArray< SCALAR > &timeTrajectory)
Integrates the system starting from state and startTime for numSteps integration steps. Returns the full state and time trajectories.
Definition: SensitivityIntegratorCT.h:225
ct::core::StateVector< state_dim > x
Definition: LoadFromFileTest.cpp:20
void clearLinearization()
Clears the linearized matrices.
Definition: SensitivityIntegratorCT.h:474
void setControlledSystem(const std::shared_ptr< ct::core::ControlledSystem< STATE_DIM, CONTROL_DIM, SCALAR >> &controlledSystem)
Changes the controlledsystem to be integrated.
Definition: SensitivityIntegratorCT.h:148
Eigen::Matrix< SCALAR, CONTROL_DIM, CONTROL_DIM > control_matrix
Definition: SensitivityIntegratorCT.h:30
void initializeDerived(const ct::core::IntegrationType stepperType)
Initializes the steppers.
Definition: SensitivityIntegratorCT.h:57
This class can integrate a controlled system and a costfunction. Furthermore, it provides first order...
Definition: SensitivityIntegratorCT.h:23
Eigen::Matrix< SCALAR, STATE_DIM, CONTROL_DIM > state_control_matrix
Definition: SensitivityIntegratorCT.h:31
SensitivityIntegratorCT(const std::shared_ptr< ct::core::ControlledSystem< STATE_DIM, CONTROL_DIM, SCALAR >> &system, const ct::core::IntegrationType stepperType=ct::core::IntegrationType::EULERCT)
Constructor.
Definition: SensitivityIntegratorCT.h:40
void setCostFunction(const std::shared_ptr< CostFunctionQuadratic< STATE_DIM, CONTROL_DIM, SCALAR >> costFun)
Prepares the integrator to provide cost integration and first order cost derivatives. This is done by enabling sensitivity caching and setting up the function objects.
Definition: SensitivityIntegratorCT.h:174
void integrateCostSensitivityDU0(control_vector &dU0, const SCALAR startTime, const size_t numSteps, const SCALAR dt)
Integrates the sensitivity of the cost with respect to the initial control input u0.
Definition: SensitivityIntegratorCT.h:396
void integrateSensitivityDX0(state_matrix &dX0, const SCALAR startTime, const size_t numSteps, const SCALAR dt)
Integrates the sensitivity ODE of the integrator with respec to the initial state x0...
Definition: SensitivityIntegratorCT.h:282
ct::core::ControlVector< CONTROL_DIM, SCALAR > control_vector
Definition: SensitivityIntegratorCT.h:28
void linearize()
Linearizes the system around the rollout from the state interation.
Definition: SensitivityIntegratorCT.h:439
void setLinearSystem(const std::shared_ptr< ct::core::LinearSystem< STATE_DIM, CONTROL_DIM, SCALAR >> &linearSystem)
Prepares the integrator to provide first order sensitivity generation by setting a linearsystem...
Definition: SensitivityIntegratorCT.h:107
void integrateSensitivityDUf(state_control_matrix &dUf, const SCALAR startTime, const size_t numSteps, const SCALAR dt)
Integrates the sensitivity ODE of the integrator with respec to the final control input uf...
Definition: SensitivityIntegratorCT.h:327