- 3.0.2 optimal control module.
LQOCProblem-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 namespace ct {
9 namespace optcon {
10 
11 
12 template <int STATE_DIM, int CONTROL_DIM, typename SCALAR>
14 {
15  changeNumStages(N);
16 }
17 
18 template <int STATE_DIM, int CONTROL_DIM, typename SCALAR>
20 {
22 }
23 template <int STATE_DIM, int CONTROL_DIM, typename SCALAR>
25 {
26  if (std::accumulate(nbu_.begin(), nbu_.end(), 0) > 0)
27  return true;
28 
29  return false;
30 }
31 
32 template <int STATE_DIM, int CONTROL_DIM, typename SCALAR>
34 {
35  if (std::accumulate(nbx_.begin(), nbx_.end(), 0) > 0)
36  return true;
37 
38  return false;
39 }
40 
41 template <int STATE_DIM, int CONTROL_DIM, typename SCALAR>
43 {
44  if (std::accumulate(ng_.begin(), ng_.end(), 0) > 0)
45  return true;
46 
47  return false;
48 }
49 
50 template <int STATE_DIM, int CONTROL_DIM, typename SCALAR>
52 {
53  return K_;
54 }
55 
56 template <int STATE_DIM, int CONTROL_DIM, typename SCALAR>
58 {
59  K_ = N;
60 
61  A_.resize(N);
62  B_.resize(N);
63  b_.resize(N + 1);
64 
65  P_.resize(N);
66  q_.resize(N + 1);
67  qv_.resize(N + 1);
68  Q_.resize(N + 1);
69 
70  rv_.resize(N);
71  R_.resize(N);
72 
73  x_lb_.resize(N + 1);
74  x_ub_.resize(N + 1);
75  x_I_.resize(N + 1);
76  u_lb_.resize(N);
77  u_ub_.resize(N);
78  u_I_.resize(N);
79 
80  nbx_.resize(N + 1);
81  nbu_.resize(N);
82 
83  ng_.resize(N + 1);
84  d_lb_.resize(N + 1);
85  d_ub_.resize(N + 1);
86  C_.resize(N + 1);
87  D_.resize(N + 1);
88 }
89 
90 
91 template <int STATE_DIM, int CONTROL_DIM, typename SCALAR>
93 {
102  q_.setConstant((SCALAR)0.0);
103 
104  // reset the number of box constraints
105  std::fill(nbx_.begin(), nbx_.end(), 0);
106  std::fill(nbu_.begin(), nbu_.end(), 0);
107 
108  // reset general constraints
109  assert(ng_.size() == d_lb_.size());
110  assert(d_lb_.size() == d_ub_.size());
111  assert(d_lb_.size() == C_.size());
112  assert(d_lb_.size() == D_.size());
113  std::fill(ng_.begin(), ng_.end(), nGenConstr);
114  for (size_t i = 0; i < ng_.size(); i++)
115  {
116  d_lb_[i].resize(nGenConstr, 1);
117  d_lb_[i].setZero();
118  d_ub_[i].resize(nGenConstr, 1);
119  d_ub_[i].setZero();
120  C_[i].resize(nGenConstr, STATE_DIM);
121  C_[i].setZero();
122  D_[i].resize(nGenConstr, CONTROL_DIM);
123  D_[i].setZero();
124  }
125 }
126 
127 
128 template <int STATE_DIM, int CONTROL_DIM, typename SCALAR>
130  const int nConstr,
131  const constr_vec_t& u_lb,
132  const constr_vec_t& u_ub,
133  const VectorXi& sp,
135 {
136  if ((u_lb.rows() != u_ub.rows()) || (u_lb.size() != nConstr) || (sp.rows() != nConstr) ||
137  (sp(sp.rows() - 1) > (CONTROL_DIM - 1)))
138  {
139  std::cout << "n.o. constraints : " << nConstr << std::endl;
140  std::cout << "u_lb : " << u_lb.transpose() << std::endl;
141  std::cout << "u_ub : " << u_ub.transpose() << std::endl;
142  std::cout << "sparsity : " << sp.transpose() << std::endl;
143  throw(std::runtime_error("LQOCProblem setInputBoxConstraint: error in constraint config"));
144  }
145 
146  if (index >= K_)
147  throw(std::runtime_error("LQOCProblem cannot set an intermediate input Box constraint at time >= K_"));
148 
149  nbu_[index] = nConstr;
150 
151  // loop through box constraints and assign bounds in differential format
152  for (int i = 0; i < nConstr; i++)
153  {
154  u_I_[index](i) = sp(i);
155  u_lb_[index](i) = u_lb(i) - u_nom_abs(sp(i)); // substract the corresponding entry in nom-control
156  u_ub_[index](i) = u_ub(i) - u_nom_abs(sp(i)); // substract the corresponding entry in nom-control
157  }
158 }
159 
160 template <int STATE_DIM, int CONTROL_DIM, typename SCALAR>
162  const constr_vec_t& u_lb,
163  const constr_vec_t& u_ub,
164  const VectorXi& sp,
166 {
167  for (int i = 0; i < K_; i++)
168  setInputBoxConstraint(i, nConstr, u_lb, u_ub, sp, u_nom_abs[i]);
169 }
170 
171 
172 template <int STATE_DIM, int CONTROL_DIM, typename SCALAR>
174  const int nConstr,
175  const constr_vec_t& x_lb,
176  const constr_vec_t& x_ub,
177  const VectorXi& sp,
179 {
180  if ((x_lb.rows() != x_ub.rows()) || (x_lb.size() != nConstr) || (sp.rows() != nConstr) ||
181  (sp(sp.rows() - 1) > (STATE_DIM - 1)))
182  {
183  std::cout << "n.o. constraints : " << nConstr << std::endl;
184  std::cout << "x_lb : " << x_lb.transpose() << std::endl;
185  std::cout << "x_ub : " << x_ub.transpose() << std::endl;
186  std::cout << "sparsity : " << sp.transpose() << std::endl;
187  throw(std::runtime_error("LQOCProblem setIntermediateStateBoxConstraint: error in constraint config"));
188  }
189 
190  if (index >= K_)
191  throw(std::runtime_error("LQOCProblem cannot set an intermediate state Box constraint at time >= K_"));
192 
193  nbx_[index] = nConstr;
194 
195  // loop through box constraints and assign bounds in differential format
196  for (int i = 0; i < nConstr; i++)
197  {
198  x_I_[index](i) = sp(i);
199  x_lb_[index](i) = x_lb(i) - x_nom_abs(sp(i)); // substract the corresponding entry in nom-state
200  x_ub_[index](i) = x_ub(i) - x_nom_abs(sp(i)); // substract the corresponding entry in nom-state
201  }
202 }
203 
204 template <int STATE_DIM, int CONTROL_DIM, typename SCALAR>
206  const constr_vec_t& x_lb,
207  const constr_vec_t& x_ub,
208  const VectorXi& sp,
210 {
211  for (int i = 0; i < K_; i++)
212  setIntermediateStateBoxConstraint(i, nConstr, x_lb, x_ub, sp, x_nom_abs[i]);
213 }
214 
215 
216 template <int STATE_DIM, int CONTROL_DIM, typename SCALAR>
218  const constr_vec_t& x_lb,
219  const constr_vec_t& x_ub,
220  const VectorXi& sp,
222 {
223  if (nConstr > 0)
224  {
225  if ((x_lb.rows() != x_ub.rows()) || (x_lb.size() != nConstr) || (sp.rows() != nConstr) ||
226  (sp(sp.rows() - 1) > (STATE_DIM - 1)))
227  {
228  std::cout << "n.o. constraints : " << nConstr << std::endl;
229  std::cout << "ux_lb : " << x_lb.transpose() << std::endl;
230  std::cout << "ux_ub : " << x_ub.transpose() << std::endl;
231  std::cout << "sparsity : " << sp.transpose() << std::endl;
232  throw(std::runtime_error("LQOCProblem setTerminalBoxConstraint: error in constraint config"));
233  }
234 
235  nbx_[K_] = nConstr;
236 
237  // loop through box constraints and assign bounds in differential format
238  for (int i = 0; i < nConstr; i++)
239  {
240  x_I_[K_](i) = sp(i);
241  x_lb_[K_](i) = x_lb(i) - x_nom_abs(sp(i)); // substract the corresponding entry in nom-state
242  x_ub_[K_](i) = x_ub(i) - x_nom_abs(sp(i)); // substract the corresponding entry in nom-state
243  }
244  }
245 }
246 
247 template <int STATE_DIM, int CONTROL_DIM, typename SCALAR>
249  const constr_vec_t& d_ub,
250  const constr_state_jac_t& C,
251  const constr_control_jac_t& D)
252 {
253  if (d_lb.size() != d_ub.size() || C.rows() != D.rows() || d_lb.size() != C.rows())
254  {
255  std::cout << "d_lb : " << std::endl << d_lb << std::endl;
256  std::cout << "d_ub : " << std::endl << d_ub << std::endl;
257  std::cout << "C : " << std::endl << C << std::endl;
258  std::cout << "D : " << std::endl << D << std::endl;
259  throw(std::runtime_error("LQOCProblem setGeneralConstraints: error in constraint config"));
260  }
261 
262  std::fill(ng_.begin(), ng_.end(), d_lb.rows());
263  d_lb_.setConstant(d_lb);
264  d_ub_.setConstant(d_ub);
265  C_.setConstant(C);
266  D_.setConstant(D);
267 }
268 
269 
270 template <int STATE_DIM, int CONTROL_DIM, typename SCALAR>
275  const double dt)
276 {
277  setZero();
278 
280  x0.setZero(); // by definition
282  u0.setZero(); // by definition
283 
286  linearSystem.getAandB(x0, u0, 0, A, B);
287 
291 
292  // feed current state and control to cost function
293  costFunction.setCurrentStateAndControl(x0, u0, 0);
294 
295  // intermediate stage
297  P_ =
300 
303 
304  // final stage
305  Q_[K_] = costFunction.stateSecondDerivativeTerminal();
306  qv_[K_] = costFunction.stateDerivativeTerminal();
307 }
308 
309 } // namespace optcon
310 } // namespace ct
ct::core::StateControlMatrixArray< STATE_DIM, CONTROL_DIM, SCALAR > B_
Definition: LQOCProblem.hpp:207
bool isGeneralConstrained() const
Definition: LQOCProblem-impl.hpp:42
ct::core::StateMatrixArray< STATE_DIM, SCALAR > A_
affine, time-varying system dynamics in discrete time
Definition: LQOCProblem.hpp:206
state_box_constr_sparsity_array_t x_I_
Definition: LQOCProblem.hpp:236
ct::core::ControlMatrixArray< CONTROL_DIM, SCALAR > R_
Definition: LQOCProblem.hpp:219
ct::core::FeedbackArray< STATE_DIM, CONTROL_DIM, SCALAR > P_
LQ approximation of the cross terms of the cost function.
Definition: LQOCProblem.hpp:222
constr_control_jac_array_t D_
Definition: LQOCProblem.hpp:250
void setInputBoxConstraint(const int index, const int nConstr, const constr_vec_t &u_lb, const constr_vec_t &u_ub, const VectorXi &sp, const ct::core::ControlVector< CONTROL_DIM, SCALAR > &u_nom_abs)
set input box constraints at a specific index
Definition: LQOCProblem-impl.hpp:129
virtual state_vector_t stateDerivativeIntermediate()=0
Computes intermediate-cost first-order derivative with respect to state.
ct::core::StateVectorArray< STATE_DIM, SCALAR > b_
Definition: LQOCProblem.hpp:208
virtual void setCurrentStateAndControl(const state_vector_t &x, const control_vector_t &u, const SCALAR &t=SCALAR(0.0))
Definition: CostFunction-impl.hpp:30
void setTerminalBoxConstraints(const int nConstr, const constr_vec_t &x_lb, const constr_vec_t &x_ub, const VectorXi &sp, const ct::core::StateVector< STATE_DIM, SCALAR > &x_nom_abs)
set box constraints for terminal stage
Definition: LQOCProblem-impl.hpp:217
std::vector< int > ng_
number of general inequality constraints
Definition: LQOCProblem.hpp:252
input_box_constr_array_t u_lb_
bounds of box constraints for input and state
Definition: LQOCProblem.hpp:225
Eigen::Matrix< SCALAR, -1, -1 > constr_state_jac_t
Definition: LQOCProblem.hpp:63
void setConstant(const T &data)
void setInputBoxConstraints(const int nConstr, const constr_vec_t &u_lb, const constr_vec_t &u_ub, const VectorXi &sp, const ct::core::ControlVectorArray< CONTROL_DIM, SCALAR > &u_nom_abs)
set uniform input box constraints, with the same constraint being applied at each intermediate stage ...
Definition: LQOCProblem-impl.hpp:161
Eigen::Matrix< SCALAR, -1, -1 > constr_control_jac_t
Definition: LQOCProblem.hpp:64
ct::core::StateMatrixArray< STATE_DIM, SCALAR > Q_
Definition: LQOCProblem.hpp:215
virtual control_matrix_t controlSecondDerivativeIntermediate()=0
Computes intermediate-cost second-order derivative with respect to input.
void setGeneralConstraints(const constr_vec_t &d_lb, const constr_vec_t &d_ub, const constr_state_jac_t &C, const constr_control_jac_t &D)
set general (in)equaltiy constraints, with the same constraint applied at each stage ...
Definition: LQOCProblem-impl.hpp:248
constr_vec_array_t d_ub_
general constraint upper bound
Definition: LQOCProblem.hpp:247
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
std::vector< int > nbx_
the number of state box constraints at every stage.
Definition: LQOCProblem.hpp:242
virtual void getAandB(const state_vector_t &x, const control_vector_t &u, const state_vector_t &x_next, const int n, size_t subSteps, state_matrix_t &A, state_control_matrix_t &B)=0
CppAD::AD< CppAD::cg::CG< double > > SCALAR
void setIntermediateStateBoxConstraint(const int index, const int nConstr, const constr_vec_t &x_lb, const constr_vec_t &x_ub, const VectorXi &sp, const ct::core::StateVector< STATE_DIM, SCALAR > &x_nom_abs)
set state box constraints at a specific index
Definition: LQOCProblem-impl.hpp:173
input_box_constr_sparsity_array_t u_I_
container for the box constraint sparsity pattern An example for how an element of this array might l...
Definition: LQOCProblem.hpp:235
int getNumberOfStages()
returns the number of discrete time steps in the LQOCP, including terminal stage
Definition: LQOCProblem-impl.hpp:51
state_box_constr_array_t x_ub_
Definition: LQOCProblem.hpp:228
Eigen::VectorXi VectorXi
Definition: LQOCProblem.hpp:82
for i
Definition: mpc_unittest_plotting.m:14
constr_state_jac_array_t C_
linear general constraint matrices
Definition: LQOCProblem.hpp:249
void setZero(const int &nGenConstr=0)
set all member variables to zero
Definition: LQOCProblem-impl.hpp:92
bool isConstrained() const
return a flag indicating whether this LQOC Problem is constrained or not
Definition: LQOCProblem-impl.hpp:19
LQOCProblem(int N=0)
constructor
Definition: LQOCProblem-impl.hpp:13
constr_vec_array_t d_lb_
general constraint lower bound
Definition: LQOCProblem.hpp:245
void setIntermediateStateBoxConstraints(const int nConstr, const constr_vec_t &x_lb, const constr_vec_t &x_ub, const VectorXi &sp, const ct::core::StateVectorArray< STATE_DIM, SCALAR > &x_nom_abs)
set uniform state box constraints, with the same constraint being applied at each intermediate stage ...
Definition: LQOCProblem-impl.hpp:205
virtual state_vector_t stateDerivativeTerminal()=0
virtual state_matrix_t stateSecondDerivativeIntermediate()=0
Computes intermediate-cost second-order derivative with respect to state.
ct::core::ControlVectorArray< CONTROL_DIM, SCALAR > rv_
LQ approximation of the pure control penalty.
Definition: LQOCProblem.hpp:218
std::vector< int > nbu_
the number of input box constraints at every stage.
Definition: LQOCProblem.hpp:239
ct::core::StateVectorArray< STATE_DIM, SCALAR > qv_
LQ approximation of the pure state penalty, including terminal state penalty.
Definition: LQOCProblem.hpp:214
virtual control_vector_t controlDerivativeIntermediate()=0
Computes intermediate-cost first-order derivative with respect to control.
bool isInputBoxConstrained() const
Definition: LQOCProblem-impl.hpp:24
StateVector< state_dim > x0
Definition: ConstrainedNLOCTest.cpp:14
void changeNumStages(int N)
change the number of discrete time steps in the LQOCP
Definition: LQOCProblem-impl.hpp:57
ct::core::ScalarArray< SCALAR > q_
constant term of in the LQ approximation of the cost function
Definition: LQOCProblem.hpp:211
Eigen::Matrix< SCALAR, -1, -1 > constr_vec_t
Definition: LQOCProblem.hpp:62
virtual control_state_matrix_t stateControlDerivativeIntermediate()=0
Computes intermediate-cost derivative with respect to state and control.
bool isStateBoxConstrained() const
Definition: LQOCProblem-impl.hpp:33
virtual state_matrix_t stateSecondDerivativeTerminal()=0
Computes final-cost second-order derivative with respect to state.
void setFromTimeInvariantLinearQuadraticProblem(ct::core::DiscreteLinearSystem< STATE_DIM, CONTROL_DIM, SCALAR > &linearSystem, ct::optcon::CostFunctionQuadratic< STATE_DIM, CONTROL_DIM, SCALAR > &costFunction, const ct::core::StateVector< STATE_DIM, SCALAR > &stateOffset, const double dt)
a convenience method which constructs an unconstrained LQOC Problem from an LTI system and continuous...
Definition: LQOCProblem-impl.hpp:271
state_box_constr_array_t x_lb_
Definition: LQOCProblem.hpp:227
input_box_constr_array_t u_ub_
Definition: LQOCProblem.hpp:226