- 3.0.2 optimal control module.
DmsSolver.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 
10 
13 
14 #include <ct/optcon/nlp/Nlp>
15 
16 #include <memory>
17 
18 namespace ct {
19 namespace optcon {
20 
33 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR = double>
34 struct DmsPolicy
35 {
36  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
38  typedef typename DIMENSIONS::state_vector_array_t state_vector_array_t;
39  typedef typename DIMENSIONS::control_vector_array_t control_vector_array_t;
40  typedef typename DIMENSIONS::time_array_t time_array_t;
41 
42  state_vector_array_t xSolution_;
43  control_vector_array_t uSolution_;
44  time_array_t tSolution_;
45 };
46 
47 
58 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR = double>
59 class DmsSolver : public OptConSolver<DmsSolver<STATE_DIM, CONTROL_DIM, SCALAR>,
60  DmsPolicy<STATE_DIM, CONTROL_DIM, SCALAR>,
61  DmsSettings,
62  STATE_DIM,
63  CONTROL_DIM,
64  SCALAR>
65 {
66 public:
67  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
68 
72  STATE_DIM,
73  CONTROL_DIM>
75 
77  typedef typename DIMENSIONS::state_vector_t state_vector_t;
82 
83  typedef DmsPolicy<STATE_DIM, CONTROL_DIM, SCALAR> Policy_t;
84 
86 
94  : nlpSolver_(nullptr), settings_(settingsDms)
95  {
96  // Create system, linearsystem and costfunction instances
97  this->setProblem(problem);
98 
99  dmsProblem_ =
100  std::shared_ptr<DmsProblem<STATE_DIM, CONTROL_DIM, SCALAR>>(new DmsProblem<STATE_DIM, CONTROL_DIM, SCALAR>(
101  settingsDms, this->systems_, this->linearSystems_, this->costFunctions_, this->inputBoxConstraints_,
102  this->stateBoxConstraints_, this->generalConstraints_, x0_));
103 
104  // SNOPT only works for the double type
105  if (settingsDms.solverSettings_.solverType_ == NlpSolverType::SNOPT)
106  nlpSolver_ = std::shared_ptr<SnoptSolver>(new SnoptSolver(dmsProblem_, settingsDms.solverSettings_));
107  else if (settingsDms.solverSettings_.solverType_ == NlpSolverType::IPOPT)
108  nlpSolver_ = std::shared_ptr<IpoptSolver>(new IpoptSolver(dmsProblem_, settingsDms.solverSettings_));
109  else
110  std::cout << "Unknown solver type... Exiting" << std::endl;
111 
112  configure(settingsDms);
113  }
114 
115 
119  ~DmsSolver() override = default;
120 
121  void configure(const DmsSettings& settings) override
122  {
123  dmsProblem_->configure(settings);
124  dmsProblem_->changeTimeHorizon(tf_);
125  dmsProblem_->changeInitialState(x0_);
126  }
127 
128  bool solve() override
129  {
130  if (!nlpSolver_->isInitialized())
131  nlpSolver_->configure(settings_.solverSettings_);
132 
133  return nlpSolver_->solve();
134  }
135 
136  const Policy_t& getSolution() override
137  {
138  policy_.xSolution_ = dmsProblem_->getStateSolution();
139  policy_.uSolution_ = dmsProblem_->getInputSolution();
140  policy_.tSolution_ = dmsProblem_->getTimeSolution();
141  return policy_;
142  }
143 
145  {
146  return core::StateTrajectory<STATE_DIM, SCALAR>(dmsProblem_->getTimeArray(), dmsProblem_->getStateTrajectory());
147  }
148 
150  {
152  dmsProblem_->getTimeArray(), dmsProblem_->getInputTrajectory());
153  }
154 
155  const core::tpl::TimeArray<SCALAR>& getTimeArray() const override { return dmsProblem_->getTimeArray(); }
156  void setInitialGuess(const Policy_t& initialGuess) override
157  {
158  dmsProblem_->setInitialGuess(initialGuess.xSolution_, initialGuess.uSolution_);
159  }
160 
161  SCALAR getTimeHorizon() const override { return dmsProblem_->getTimeHorizon(); }
162  void changeTimeHorizon(const SCALAR& tf) override
163  {
164  tf_ = tf;
165  if (dmsProblem_)
166  dmsProblem_->changeTimeHorizon(tf);
167  }
168 
170  {
171  x0_ = x0;
172  if (dmsProblem_)
173  dmsProblem_->changeInitialState(x0);
174  }
175 
176  void changeCostFunction(const typename Base::OptConProblem_t::CostFunctionPtr_t& cf) override
177  {
178  this->getCostFunctionInstances().resize(settings_.N_);
179  if (cf)
180  for (size_t i = 0; i < settings_.N_; i++)
181  this->getCostFunctionInstances()[i] = typename Base::OptConProblem_t::CostFunctionPtr_t(cf->clone());
182  }
183 
184  void changeNonlinearSystem(const typename Base::OptConProblem_t::DynamicsPtr_t& dyn) override
185  {
186  this->getNonlinearSystemsInstances().resize(settings_.N_);
187 
188  if (dyn)
189  for (size_t i = 0; i < settings_.N_; i++)
190  this->getNonlinearSystemsInstances()[i] = typename Base::OptConProblem_t::DynamicsPtr_t(dyn->clone());
191  }
192 
193  void changeLinearSystem(const typename Base::OptConProblem_t::LinearPtr_t& lin) override
194  {
195  this->getLinearSystemsInstances().resize(settings_.N_);
196 
197  if (lin)
198  for (size_t i = 0; i < settings_.N_; i++)
199  this->getLinearSystemsInstances()[i] = typename Base::OptConProblem_t::LinearPtr_t(lin->clone());
200  }
201 
202  void changeInputBoxConstraints(const typename Base::OptConProblem_t::ConstraintPtr_t con) override
203  {
204  this->getInputBoxConstraintsInstances().push_back(
205  typename Base::OptConProblem_t::ConstraintPtr_t(con->clone()));
206  }
207 
208  void changeStateBoxConstraints(const typename Base::OptConProblem_t::ConstraintPtr_t con) override
209  {
210  this->getStateBoxConstraintsInstances().push_back(
211  typename Base::OptConProblem_t::ConstraintPtr_t(con->clone()));
212  }
213 
214  void changeGeneralConstraints(const typename Base::OptConProblem_t::ConstraintPtr_t con) override
215  {
216  this->getGeneralConstraintsInstances().push_back(typename Base::OptConProblem_t::ConstraintPtr_t(con->clone()));
217  }
218 
222  void printSolution() { dmsProblem_->printSolution(); }
223  std::vector<typename OptConProblem_t::DynamicsPtr_t>& getNonlinearSystemsInstances() override { return systems_; }
224  const std::vector<typename OptConProblem_t::DynamicsPtr_t>& getNonlinearSystemsInstances() const override
225  {
226  return systems_;
227  }
228 
229  std::vector<typename OptConProblem_t::LinearPtr_t>& getLinearSystemsInstances() override { return linearSystems_; }
230  const std::vector<typename OptConProblem_t::LinearPtr_t>& getLinearSystemsInstances() const override
231  {
232  return linearSystems_;
233  }
234 
235  std::vector<typename OptConProblem_t::CostFunctionPtr_t>& getCostFunctionInstances() override
236  {
237  return costFunctions_;
238  }
239  const std::vector<typename OptConProblem_t::CostFunctionPtr_t>& getCostFunctionInstances() const override
240  {
241  return costFunctions_;
242  }
243 
244  std::vector<typename OptConProblem_t::ConstraintPtr_t>& getInputBoxConstraintsInstances() override
245  {
246  return inputBoxConstraints_;
247  }
248 
249  const std::vector<typename OptConProblem_t::ConstraintPtr_t>& getInputBoxConstraintsInstances() const override
250  {
251  return inputBoxConstraints_;
252  }
253 
254  std::vector<typename OptConProblem_t::ConstraintPtr_t>& getStateBoxConstraintsInstances() override
255  {
256  return stateBoxConstraints_;
257  }
258 
259  const std::vector<typename OptConProblem_t::ConstraintPtr_t>& getStateBoxConstraintsInstances() const override
260  {
261  return stateBoxConstraints_;
262  }
263 
264  std::vector<typename OptConProblem_t::ConstraintPtr_t>& getGeneralConstraintsInstances() override
265  {
266  return generalConstraints_;
267  }
268  const std::vector<typename OptConProblem_t::ConstraintPtr_t>& getGeneralConstraintsInstances() const override
269  {
270  return generalConstraints_;
271  }
272 
273 
274 private:
275  std::shared_ptr<DmsProblem<STATE_DIM, CONTROL_DIM, SCALAR>> dmsProblem_;
276  std::shared_ptr<tpl::NlpSolver<SCALAR>> nlpSolver_;
277  DmsSettings settings_;
279  Policy_t policy_;
281  state_vector_t x0_;
282  SCALAR tf_;
284  std::vector<typename OptConProblem_t::DynamicsPtr_t> systems_;
285  std::vector<typename OptConProblem_t::LinearPtr_t> linearSystems_;
286  std::vector<typename OptConProblem_t::CostFunctionPtr_t> costFunctions_;
287  std::vector<typename OptConProblem_t::ConstraintPtr_t> inputBoxConstraints_;
288  std::vector<typename OptConProblem_t::ConstraintPtr_t> stateBoxConstraints_;
289  std::vector<typename OptConProblem_t::ConstraintPtr_t> generalConstraints_;
290 };
291 
292 
293 } // namespace optcon
294 } // namespace ct
void changeGeneralConstraints(const typename Base::OptConProblem_t::ConstraintPtr_t con) override
Definition: DmsSolver.h:214
const core::tpl::TimeArray< SCALAR > & getTimeArray() const override
Definition: DmsSolver.h:155
void changeTimeHorizon(const SCALAR &tf) override
Change the time horizon the solver operates on.
Definition: DmsSolver.h:162
Definition: OptConSolver.h:39
bool solve() override
Definition: DmsSolver.h:128
const std::vector< typename OptConProblem_t::ConstraintPtr_t > & getGeneralConstraintsInstances() const override
Definition: DmsSolver.h:268
DmsDimensions< STATE_DIM, CONTROL_DIM, SCALAR > DIMENSIONS
Definition: DmsSolver.h:76
const std::vector< typename OptConProblem_t::DynamicsPtr_t > & getNonlinearSystemsInstances() const override
Definition: DmsSolver.h:224
std::vector< typename OptConProblem_t::ConstraintPtr_t > & getInputBoxConstraintsInstances() override
Direct accessor to the box constraint instances.
Definition: DmsSolver.h:244
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef DmsDimensions< STATE_DIM, CONTROL_DIM, SCALAR > DIMENSIONS
Definition: DmsSolver.h:37
const std::vector< typename OptConProblem_t::ConstraintPtr_t > & getInputBoxConstraintsInstances() const override
Definition: DmsSolver.h:249
DmsPolicy< STATE_DIM, CONTROL_DIM, SCALAR > Policy_t
Definition: DmsSolver.h:83
DIMENSIONS::control_vector_t control_vector_t
Definition: DmsSolver.h:79
DIMENSIONS::state_vector_t state_vector_t
Definition: DmsSolver.h:77
void configure(const DmsSettings &settings) override
Definition: DmsSolver.h:121
std::vector< typename OptConProblem_t::ConstraintPtr_t > & getStateBoxConstraintsInstances() override
Definition: DmsSolver.h:254
void changeNonlinearSystem(const typename Base::OptConProblem_t::DynamicsPtr_t &dyn) override
Definition: DmsSolver.h:184
void printSolution()
Prints out the solution trajectories of the DMS problem.
Definition: DmsSolver.h:222
The DMS policy used as a solution container.
Definition: DmsSolver.h:34
const std::vector< typename OptConProblem_t::CostFunctionPtr_t > & getCostFunctionInstances() const override
Definition: DmsSolver.h:239
std::vector< typename OptConProblem_t::CostFunctionPtr_t > & getCostFunctionInstances() override
Direct accessor to the cost function instances.
Definition: DmsSolver.h:235
This class sets up the DMS problem.
Definition: DmsProblem.h:34
DIMENSIONS::control_vector_array_t control_vector_array_t
Definition: DmsSolver.h:39
control_vector_array_t uSolution_
Definition: DmsSolver.h:43
DIMENSIONS::control_vector_array_t control_vector_array_t
Definition: DmsSolver.h:78
std::vector< typename OptConProblem_t::DynamicsPtr_t > & getNonlinearSystemsInstances() override
Direct accessor to the system instances.
Definition: DmsSolver.h:223
DIMENSIONS::state_vector_array_t state_vector_array_t
Definition: DmsSolver.h:38
CppAD::AD< CppAD::cg::CG< double > > SCALAR
const std::vector< typename OptConProblem_t::LinearPtr_t > & getLinearSystemsInstances() const override
Definition: DmsSolver.h:230
void changeLinearSystem(const typename Base::OptConProblem_t::LinearPtr_t &lin) override
Definition: DmsSolver.h:193
Defines basic types used in the DMS algorithm.
Definition: DmsDimensions.h:18
void changeStateBoxConstraints(const typename Base::OptConProblem_t::ConstraintPtr_t con) override
Definition: DmsSolver.h:208
void changeInitialState(const core::StateVector< STATE_DIM, SCALAR > &x0) override
Change the initial state for the optimal control problem.
Definition: DmsSolver.h:169
for i
Definition: mpc_unittest_plotting.m:14
time_array_t tSolution_
Definition: DmsSolver.h:44
void changeInputBoxConstraints(const typename Base::OptConProblem_t::ConstraintPtr_t con) override
Definition: DmsSolver.h:202
DmsSolver(const ContinuousOptConProblem< STATE_DIM, CONTROL_DIM, SCALAR > problem, DmsSettings settingsDms)
Custom constructor, converts the optcon problem to a DMS problem.
Definition: DmsSolver.h:93
DIMENSIONS::state_vector_array_t state_vector_array_t
Definition: DmsSolver.h:80
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef OptConSolver< DmsSolver< STATE_DIM, CONTROL_DIM, SCALAR >, DmsPolicy< STATE_DIM, CONTROL_DIM, SCALAR >, DmsSettings, STATE_DIM, CONTROL_DIM > Base
Definition: DmsSolver.h:74
ContinuousOptConProblem< STATE_DIM, CONTROL_DIM, SCALAR > OptConProblem_t
Definition: DmsSolver.h:85
state_vector_array_t xSolution_
Definition: DmsSolver.h:42
const std::vector< typename OptConProblem_t::ConstraintPtr_t > & getStateBoxConstraintsInstances() const override
Definition: DmsSolver.h:259
tpl::IpoptSolver< double > IpoptSolver
Definition: IpoptSolver.h:200
Defines the DMS settings.
Definition: DmsSettings.h:23
std::vector< typename OptConProblem_t::ConstraintPtr_t > & getGeneralConstraintsInstances() override
Direct accessor to the general constraints.
Definition: DmsSolver.h:264
Class to solve a specfic DMS problem.
Definition: DmsSolver.h:59
Definition: SnoptSolver.h:297
DIMENSIONS::time_array_t time_array_t
Definition: DmsSolver.h:81
StateVector< state_dim > x0
Definition: ConstrainedNLOCTest.cpp:14
SCALAR getTimeHorizon() const override
Get the time horizon the solver currently operates on.
Definition: DmsSolver.h:161
const Policy_t & getSolution() override
Definition: DmsSolver.h:136
void setInitialGuess(const Policy_t &initialGuess) override
Definition: DmsSolver.h:156
std::vector< typename OptConProblem_t::LinearPtr_t > & getLinearSystemsInstances() override
Direct accessor to the linear system instances.
Definition: DmsSolver.h:229
const core::ControlTrajectory< CONTROL_DIM, SCALAR > getControlTrajectory() const override
Definition: DmsSolver.h:149
Definition: OptConProblemBase.h:40
DIMENSIONS::time_array_t time_array_t
Definition: DmsSolver.h:40
const core::StateTrajectory< STATE_DIM, SCALAR > getStateTrajectory() const override
Definition: DmsSolver.h:144
void changeCostFunction(const typename Base::OptConProblem_t::CostFunctionPtr_t &cf) override
Definition: DmsSolver.h:176