- 3.0.2 optimal control module.
ConstraintTest.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 
12 #pragma once
13 
14 namespace ct {
15 namespace optcon {
16 namespace example {
17 
18 const bool verbose = true;
19 
20 const size_t state_dim = 12;
21 const size_t control_dim = 4;
22 
23 
25 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR = double>
26 class PureStateConstraint_Example : public ct::optcon::ConstraintBase<STATE_DIM, CONTROL_DIM, SCALAR>
27 {
28 public:
29  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
34  typedef Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> VectorXs;
35  typedef Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> MatrixXs;
36 
38  {
39  Base::lb_.resize(STATE_DIM);
40  Base::ub_.resize(STATE_DIM);
41  Base::lb_.setZero();
42  Base::ub_.setZero();
43  }
44 
45  PureStateConstraint_Example(const PureStateConstraint_Example& arg) : Base(arg), A_(arg.A_) {}
48  {
49  return new PureStateConstraint_Example(*this);
50  }
51 
52  virtual size_t getConstraintSize() const override { return STATE_DIM; }
53  virtual VectorXs evaluate(const state_vector_t& x, const control_vector_t& u, const SCALAR t) override
54  {
55  return A_ * x;
56  }
57 
58  virtual Eigen::Matrix<ct::core::ADCGScalar, Eigen::Dynamic, 1> evaluateCppadCg(
61  ct::core::ADCGScalar t) override
62  {
63  return A_.template cast<ct::core::ADCGScalar>() * x;
64  }
65 
66  virtual MatrixXs jacobianState(const state_vector_t& x, const control_vector_t& u, const SCALAR t) override
67  {
68  return A_;
69  }
70 
71  void setA(const Eigen::Matrix<SCALAR, STATE_DIM, STATE_DIM>& A) { A_ = A; }
72 
73 private:
74  Eigen::Matrix<SCALAR, STATE_DIM, STATE_DIM> A_;
75 };
76 
78 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR = double>
79 class StateInputConstraint_Example : public ct::optcon::ConstraintBase<STATE_DIM, CONTROL_DIM, SCALAR>
80 {
81 public:
82  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
87  typedef Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> VectorXs;
88  typedef Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> MatrixXs;
89 
91  {
92  Base::lb_.resize(CONTROL_DIM);
93  Base::ub_.resize(CONTROL_DIM);
94  Base::lb_.setZero();
95  Base::ub_.setZero();
96  }
97 
99  : ct::optcon::ConstraintBase<STATE_DIM, CONTROL_DIM, SCALAR>(arg), A_(arg.A_), B_(arg.B_)
100  {
101  Base::lb_.resize(CONTROL_DIM);
102  Base::ub_.resize(CONTROL_DIM);
103  Base::lb_.setZero();
104  Base::ub_.setZero();
105  }
106 
108  {
109  return new StateInputConstraint_Example(*this);
110  }
111 
113  virtual size_t getConstraintSize() const override { return CONTROL_DIM; }
114  VectorXs evaluate(const state_vector_t& x, const control_vector_t& u, const SCALAR t) override
115  {
116  return A_ * x + B_ * u;
117  }
118  virtual Eigen::Matrix<ct::core::ADCGScalar, Eigen::Dynamic, 1> evaluateCppadCg(
121  ct::core::ADCGScalar t) override
122  {
123  return (A_.template cast<ct::core::ADCGScalar>() * x + B_.template cast<ct::core::ADCGScalar>() * u);
124  }
125 
126  virtual MatrixXs jacobianState(const state_vector_t& x, const control_vector_t& u, const SCALAR t) override
127  {
128  return A_;
129  }
130 
131  virtual MatrixXs jacobianInput(const state_vector_t& x, const control_vector_t& u, const SCALAR t) override
132  {
133  return B_;
134  }
135 
136  void setAB(const Eigen::Matrix<SCALAR, CONTROL_DIM, STATE_DIM>& A,
137  const Eigen::Matrix<SCALAR, CONTROL_DIM, CONTROL_DIM> B)
138  {
139  A_ = A;
140  B_ = B;
141  }
142 
143 private:
144  Eigen::Matrix<SCALAR, CONTROL_DIM, STATE_DIM> A_;
145  Eigen::Matrix<SCALAR, CONTROL_DIM, CONTROL_DIM> B_;
146 };
147 
148 
149 TEST(pureStateConstraintTest, pureStateConstraintTest)
150 {
151  std::shared_ptr<ct::optcon::ConstraintContainerAD<state_dim, control_dim>> constraintAD(
152  new ct::optcon::ConstraintContainerAD<state_dim, control_dim>());
153 
154  std::shared_ptr<ct::optcon::ConstraintContainerAnalytical<state_dim, control_dim>> constraintAN(
156 
157  Eigen::Matrix<double, state_dim, state_dim> A;
158  A.setRandom();
159 
160  std::shared_ptr<PureStateConstraint_Example<state_dim, control_dim>> term1_ad(
162  term1_ad->setName("term1_ad");
163  term1_ad->setA(A);
164 
165  std::shared_ptr<PureStateConstraint_Example<state_dim, control_dim, double>> term1_an(
167  term1_an->setName("term1_an");
168  term1_an->setA(A);
169 
170  constraintAD->addIntermediateConstraint(term1_ad, verbose);
171  constraintAD->initialize();
172  constraintAN->addIntermediateConstraint(term1_an, verbose);
173  constraintAN->initialize();
174 
175  std::shared_ptr<ct::optcon::ConstraintContainerAnalytical<state_dim, control_dim>> constraintAN_cloned(
176  constraintAN->clone());
177  std::shared_ptr<ct::optcon::ConstraintContainerAD<state_dim, control_dim>> constraintAD_cloned(
178  constraintAD->clone());
179 
180  size_t nRuns = 100;
181 
182  for (size_t i = 0; i < nRuns; i++)
183  {
184  /* evaluate constraint */
185  Eigen::VectorXd g1_ad, g1_an, g1_ad_cl, g1_an_cl;
186 
187  Eigen::Matrix<double, state_dim, 1> state;
188  state.setRandom();
189  Eigen::Matrix<double, control_dim, 1> input;
190  input.setRandom();
191 
192  std::random_device rd;
193  std::mt19937 gen(rd());
194  std::uniform_real_distribution<> time_distr(0, 100);
195  double time = time_distr(gen);
196 
197  constraintAN->setCurrentStateAndControl(state, input, time);
198  constraintAD->setCurrentStateAndControl(state, input, time);
199  constraintAD_cloned->setCurrentStateAndControl(state, input, time);
200  constraintAN_cloned->setCurrentStateAndControl(state, input, time);
201 
202  g1_an = constraintAN->evaluateIntermediate();
203  g1_ad = constraintAD->evaluateIntermediate();
204  g1_an_cl = constraintAN_cloned->evaluateIntermediate();
205  g1_ad_cl = constraintAD_cloned->evaluateIntermediate();
206 
207  // test if constraint violations are the same
208  ASSERT_TRUE(g1_an.isApprox(g1_ad));
209  ASSERT_TRUE(g1_an.isApprox(g1_ad_cl));
210  ASSERT_TRUE(g1_an.isApprox(g1_an_cl));
211 
212  Eigen::MatrixXd F_an, F_ad, F_cloned, F_cloned_an;
213  F_an.setZero();
214  F_ad.setZero();
215  F_cloned.setZero();
216  F_cloned_an.setZero();
217 
218  F_an = constraintAN->jacobianStateIntermediate();
219  F_ad = constraintAD->jacobianStateIntermediate();
220  F_cloned_an = constraintAN_cloned->jacobianStateIntermediate();
221  F_cloned = constraintAD_cloned->jacobianStateIntermediate();
222 
223  // compare jacobians
224 
225  ASSERT_TRUE(F_an.isApprox(F_ad));
226  ASSERT_TRUE(F_an.isApprox(F_cloned));
227  ASSERT_TRUE(F_an.isApprox(F_cloned_an));
228  }
229 }
230 
231 
232 TEST(stateInputConstraintTest, stateInputConstraintTest)
233 {
234  std::shared_ptr<ct::optcon::ConstraintContainerAD<state_dim, control_dim>> constraintAD(
235  new ct::optcon::ConstraintContainerAD<state_dim, control_dim>());
236  std::shared_ptr<ct::optcon::ConstraintContainerAnalytical<state_dim, control_dim>> constraintAN(
238 
239  Eigen::Matrix<double, control_dim, state_dim> A;
240  A.setRandom();
241  Eigen::Matrix<double, control_dim, control_dim> B;
242  B.setRandom();
243 
244  std::shared_ptr<StateInputConstraint_Example<state_dim, control_dim>> term1_ad(
246  term1_ad->setName("term1_ad");
247  term1_ad->setAB(A, B);
248 
249  std::shared_ptr<StateInputConstraint_Example<state_dim, control_dim, double>> term1_an(
251  term1_an->setName("term1_an");
252  term1_an->setAB(A, B);
253 
254 
255  // std::cout << "Adding terms to constraintAD" << std::endl;
256  constraintAD->addIntermediateConstraint(term1_ad, verbose);
257  constraintAD->initialize();
258  constraintAN->addIntermediateConstraint(term1_an, verbose);
259  constraintAN->initialize();
260 
261  /* evaluate constraint */
262  Eigen::VectorXd g1_ad, g1_an;
263 
264  Eigen::Matrix<double, state_dim, 1> state;
265  state.setRandom();
266  Eigen::Matrix<double, control_dim, 1> input;
267  input.setRandom();
268  double time = 1.0;
269 
270 
271  constraintAN->setCurrentStateAndControl(state, input, time);
272  constraintAD->setCurrentStateAndControl(state, input, time);
273 
274 
275  g1_an = constraintAN->evaluateIntermediate();
276  g1_ad = constraintAD->evaluateIntermediate();
277 
278  // test if constraint violations are the same
279  ASSERT_TRUE(g1_an.isApprox(g1_ad));
280 
281  Eigen::MatrixXd C_an, C_ad, C_cloned, C_cloned_an;
282  Eigen::MatrixXd D_an, D_ad, D_cloned, D_cloned_an;
283 
284  C_an = constraintAN->jacobianStateIntermediate();
285  C_ad = constraintAD->jacobianStateIntermediate();
286  D_an = constraintAN->jacobianInputIntermediate();
287  D_ad = constraintAD->jacobianInputIntermediate();
288 
289 
290  std::shared_ptr<ct::optcon::ConstraintContainerAnalytical<state_dim, control_dim>> constraintAN_cloned(
291  constraintAN->clone());
292 
293  std::shared_ptr<ct::optcon::ConstraintContainerAD<state_dim, control_dim>> constraintAD_cloned(
294  constraintAD->clone());
295 
296  C_cloned_an = constraintAN_cloned->jacobianStateIntermediate();
297  C_cloned = constraintAD_cloned->jacobianStateIntermediate();
298  D_cloned_an = constraintAN_cloned->jacobianInputIntermediate();
299  D_cloned = constraintAD_cloned->jacobianInputIntermediate();
300 
301  // compare jacobians
302  ASSERT_TRUE(C_an.isApprox(C_ad));
303  ASSERT_TRUE(C_an.isApprox(C_cloned));
304  ASSERT_TRUE(C_an.isApprox(C_cloned_an));
305 
306  ASSERT_TRUE(D_an.isApprox(D_ad));
307  ASSERT_TRUE(D_an.isApprox(D_cloned));
308  ASSERT_TRUE(D_an.isApprox(D_cloned_an));
309 }
310 
311 } // namespace example
312 } // namespace optcon
313 } // namespace ct
virtual VectorXs evaluate(const state_vector_t &x, const control_vector_t &u, const SCALAR t) override
The evaluation of the constraint violation. Note this method is SCALAR typed.
Definition: ConstraintTest.h:53
core::StateVector< STATE_DIM, SCALAR > state_vector_t
Definition: ConstraintTest.h:32
core::ControlVector< CONTROL_DIM, SCALAR > control_vector_t
Definition: ConstraintTest.h:86
virtual ~StateInputConstraint_Example()
Definition: ConstraintTest.h:112
ct::core::ControlVector< control_dim > u
Definition: LoadFromFileTest.cpp:21
virtual ~PureStateConstraint_Example()
Definition: ConstraintTest.h:46
PureStateConstraint_Example()
Definition: ConstraintTest.h:37
virtual Eigen::Matrix< ct::core::ADCGScalar, Eigen::Dynamic, 1 > evaluateCppadCg(const core::StateVector< STATE_DIM, ct::core::ADCGScalar > &x, const core::ControlVector< CONTROL_DIM, ct::core::ADCGScalar > &u, ct::core::ADCGScalar t) override
Definition: ConstraintTest.h:58
const size_t state_dim
Definition: ConstraintComparison.h:20
VectorXs evaluate(const state_vector_t &x, const control_vector_t &u, const SCALAR t) override
The evaluation of the constraint violation. Note this method is SCALAR typed.
Definition: ConstraintTest.h:114
virtual size_t getConstraintSize() const override
The evaluate method used for jit compilation in constraint container ad.
Definition: ConstraintTest.h:52
void setA(const Eigen::Matrix< SCALAR, STATE_DIM, STATE_DIM > &A)
Definition: ConstraintTest.h:71
clear all close all load ct GNMSLog0 mat reformat t
Definition: gnmsPlot.m:6
core::StateVector< STATE_DIM, SCALAR > state_vector_t
Definition: ConstraintTest.h:85
virtual size_t getConstraintSize() const override
The evaluate method used for jit compilation in constraint container ad.
Definition: ConstraintTest.h:113
virtual MatrixXs jacobianState(const state_vector_t &x, const control_vector_t &u, const SCALAR t) override
Returns the constraint jacobian wrt state.
Definition: ConstraintTest.h:66
CppAD::AD< CppAD::cg::CG< double > > SCALAR
TEST(ConstraintComparison, comparisonAnalyticAD)
Definition: ConstraintComparison.h:158
A state input constraint term.
Definition: ConstraintTest.h:79
for i
Definition: mpc_unittest_plotting.m:14
VectorXs ub_
lower bound on the constraints
Definition: ConstraintBase.h:203
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef ct::core::tpl::TraitSelector< SCALAR >::Trait Trait
Definition: ConstraintTest.h:30
PureStateConstraint_Example(const PureStateConstraint_Example &arg)
Definition: ConstraintTest.h:45
Contains all the constraints using analytically calculated jacobians.
Definition: ConstraintContainerAnalytical.h:27
ct::core::StateVector< state_dim > x
Definition: LoadFromFileTest.cpp:20
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > MatrixXs
Definition: ConstraintTest.h:35
StateInputConstraint_Example()
Definition: ConstraintTest.h:90
ct::optcon::ConstraintBase< state_dim, control_dim, SCALAR > Base
Definition: ConstraintTest.h:31
virtual MatrixXs jacobianState(const state_vector_t &x, const control_vector_t &u, const SCALAR t) override
Returns the constraint jacobian wrt state.
Definition: ConstraintTest.h:126
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > MatrixXs
Definition: ConstraintTest.h:88
virtual MatrixXs jacobianInput(const state_vector_t &x, const control_vector_t &u, const SCALAR t) override
Returns the constraint jacobian wrt input.
Definition: ConstraintTest.h:131
virtual StateInputConstraint_Example< STATE_DIM, CONTROL_DIM, SCALAR > * clone() const override
Creates a new instance of the object with same properties than original.
Definition: ConstraintTest.h:107
ct::optcon::ConstraintBase< STATE_DIM, CONTROL_DIM, SCALAR > Base
Definition: ConstraintTest.h:84
Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 > VectorXs
Definition: ConstraintTest.h:34
VectorXs lb_
Definition: ConstraintBase.h:202
StateInputConstraint_Example(const StateInputConstraint_Example &arg)
Definition: ConstraintTest.h:98
A pure state constraint term.
Definition: ConstraintTest.h:26
core::ControlVector< CONTROL_DIM, SCALAR > control_vector_t
Definition: ConstraintTest.h:33
const bool verbose
Definition: ConstraintComparison.h:18
void setAB(const Eigen::Matrix< SCALAR, CONTROL_DIM, STATE_DIM > &A, const Eigen::Matrix< SCALAR, CONTROL_DIM, CONTROL_DIM > B)
Definition: ConstraintTest.h:136
Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 > VectorXs
Definition: ConstraintTest.h:87
virtual Eigen::Matrix< ct::core::ADCGScalar, Eigen::Dynamic, 1 > evaluateCppadCg(const core::StateVector< STATE_DIM, ct::core::ADCGScalar > &x, const core::ControlVector< CONTROL_DIM, ct::core::ADCGScalar > &u, ct::core::ADCGScalar t) override
Definition: ConstraintTest.h:118
const size_t control_dim
Definition: ConstraintComparison.h:21
Base class for the constraints used in this toolbox.
Definition: ConstraintBase.h:21
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef ct::core::tpl::TraitSelector< SCALAR >::Trait Trait
Definition: ConstraintTest.h:83
virtual PureStateConstraint_Example< STATE_DIM, CONTROL_DIM, SCALAR > * clone() const override
Creates a new instance of the object with same properties than original.
Definition: ConstraintTest.h:47