- 3.0.2 optimal control module.
StateFeedbackPolicyHandler-impl.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 #pragma once
7 
8 namespace ct {
9 namespace optcon {
10 
11 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
13 {
14 }
15 
16 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
18 {
19 }
20 
21 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
23  const SCALAR& newTimeHorizon,
25 {
26  // get the current reference trajectories from the StateFeedbackController
27  core::FeedbackTrajectory<STATE_DIM, CONTROL_DIM, SCALAR>& FeedbackTraj = policy.getFeedbackTrajectory();
28  core::ControlTrajectory<CONTROL_DIM, SCALAR>& FeedForwardTraj = policy.getFeedforwardTrajectory();
29  core::StateTrajectory<STATE_DIM, SCALAR>& StateRefTraj = policy.getReferenceStateTrajectory();
30 
31  // current number of discrete elements
32  int currentSize = FeedForwardTraj.size();
33 
34  // compute new controller length as a function of the time horizon
35  int Kn_new = std::max(1, (int)std::lround(newTimeHorizon / dt_));
36 
37  // compute number indices to be shifted. Note: it does not make sense to shift more entries than are available
38  int num_di = FeedForwardTraj.getIndexFromTime(delay);
39  num_di = std::min(num_di, currentSize - 1);
40 
41 
42 #ifdef DEBUG_POLICYHANDLER
43  std::cout << "DEBUG_POLICYHANDLER: Controller shifting: " << std::endl
44  << "delay: " << delay << " newT: " << newTimeHorizon << std::endl
45  << " new Discrete Controller has: " << std::endl
46  << Kn_new << " control elements, shifted about " << num_di << " elements." << std::endl
47  << Kn_new + 1 << " state elements, shifted about " << num_di << " elements." << std::endl;
48 #endif
49 
50 
51  // Step 1 - Truncate Front: remove first 'num_di' elements from controller and shift time accordingly
52  if (num_di > 0)
53  {
54  FeedForwardTraj.eraseFront(num_di, num_di * dt_);
55  FeedbackTraj.eraseFront(num_di, num_di * dt_);
56  StateRefTraj.eraseFront(num_di, num_di * dt_);
57  currentSize -= num_di;
58  }
59 
60 
61  // Step 2 - Resize overall controller
62  if (Kn_new > currentSize)
63  {
64  //extend at back with constant value taken from last element
65  bool timeIsRelative = true;
66  for (int i = 0; i < Kn_new - currentSize; i++)
67  {
68  FeedbackTraj.push_back(FeedbackTraj.back(), dt_, timeIsRelative);
69  FeedForwardTraj.push_back(FeedForwardTraj.back(), dt_, timeIsRelative);
70  StateRefTraj.push_back(StateRefTraj.back(), dt_, timeIsRelative);
71  }
72  }
73  else if (Kn_new < currentSize)
74  {
75  // remove elements from back
76  for (int i = 0; i < currentSize - Kn_new; i++)
77  {
78  FeedbackTraj.pop_back();
79  FeedForwardTraj.pop_back();
80  StateRefTraj.pop_back();
81  }
82  }
83 
84  // safety check, which should never be entered
85  if (FeedForwardTraj.size() == 0)
86  {
87  throw std::runtime_error("ERROR in StateFeedbackPolicyHandler.h: new policy should not have size 0.");
88  }
89 }
90 
91 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR>
94  SCALAR& effectivelyTruncated)
95 {
96  // current controller length
97  size_t currentSize = policy.getFeedforwardTrajectory().size();
98 
99  size_t num_di = policy.getFeedforwardTrajectory().getIndexFromTime(delay);
100  num_di = std::min(num_di, currentSize - 1);
101 
102  effectivelyTruncated = num_di * dt_;
103 
104 #ifdef DEBUG_POLICYHANDLER
105  std::cout << "DEBUG_WARMSTART: Current Controller Size: " << currentSize << " elements." << std::endl;
106  std::cout << "DEBUG_WARMSTART: Controller truncation: truncation about " << num_di << " elements." << std::endl;
107  std::cout << "DEBUG_WARMSTART: Controller new size: " << currentSize - num_di << " elements." << std::endl;
108 #endif
109 
110  // remove first num_di elements from controller
111  if (num_di > 0 && num_di < currentSize)
112  {
113  policy.getFeedbackTrajectory().eraseFront(num_di, effectivelyTruncated);
114  policy.getFeedforwardTrajectory().eraseFront(num_di, effectivelyTruncated);
115  policy.getReferenceStateTrajectory().eraseFront(num_di, effectivelyTruncated);
116  }
117 }
118 
119 } // namespace optcon
120 } // namespace ct
StateFeedbackPolicyHandler(const SCALAR &dt)
Definition: StateFeedbackPolicyHandler-impl.h:12
virtual void truncateSolutionFront(const SCALAR &delay, StateFeedbackController_t &policy, SCALAR &effectivelyTruncated) override
Definition: StateFeedbackPolicyHandler-impl.h:92
const double dt
Definition: LQOCSolverTiming.cpp:18
CppAD::AD< CppAD::cg::CG< double > > SCALAR
for i
Definition: mpc_unittest_plotting.m:14
void eraseFront(const size_t &N, const SCALAR &dt=0.0)
void push_back(const T &data, const SCALAR &time, const bool timeIsAbsolute)
virtual ~StateFeedbackPolicyHandler()
Definition: StateFeedbackPolicyHandler-impl.h:17
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef core::StateFeedbackController< STATE_DIM, CONTROL_DIM, SCALAR > StateFeedbackController_t
Definition: StateFeedbackPolicyHandler.h:21
virtual void designWarmStartingPolicy(const SCALAR &delay, const SCALAR &newTimeHorizon, StateFeedbackController_t &policy) override
Definition: StateFeedbackPolicyHandler-impl.h:22
size_t getIndexFromTime(const SCALAR &t)