autogenu-jupyter
An automatic code generator and the continuation/GMRES (C/GMRES) based numerical solvers for nonlinear MPC
Loading...
Searching...
No Matches
single_shooting_nlp.hpp
Go to the documentation of this file.
1#ifndef CGMRES__SINGLE_SHOOTING_NLP_HPP_
2#define CGMRES__SINGLE_SHOOTING_NLP_HPP_
3
4#include <array>
5
6#include "cgmres/types.hpp"
7#include "cgmres/horizon.hpp"
8
11
12namespace cgmres {
13namespace detail {
14
15template <class OCP, int N>
17public:
18 static constexpr int nx = OCP::nx;
19 static constexpr int nu = OCP::nu;
20 static constexpr int nc = OCP::nc;
21 static constexpr int nuc = nu + nc;
22 static constexpr int nub = OCP::nub;
23 static constexpr int dim = nuc * N + 2 * N * nub;
24
25 SingleShootingNLP(const OCP& ocp, const Horizon& horizon)
26 : ocp_(ocp),
27 horizon_(horizon),
28 dx_(Vector<nx>::Zero()) {
29 static_assert(OCP::nx > 0);
30 static_assert(OCP::nu > 0);
31 static_assert(OCP::nc >= 0);
32 static_assert(OCP::nub >= 0);
33 static_assert(N > 0);
34 std::fill(x_.begin(), x_.end(), Vector<nx>::Zero());
35 std::fill(lmd_.begin(), lmd_.end(), Vector<nx>::Zero());
36 }
37
38 SingleShootingNLP() = default;
39
40 ~SingleShootingNLP() = default;
41
42 template <typename VectorType>
43 void eval_fonc_hu(const Scalar t, const MatrixBase<VectorType>& x, const Vector<dim>& solution,
44 Vector<dim>& fonc_hu) {
45 const Scalar T = horizon_.T(t);
46 const Scalar dt = T / N;
47 assert(T >= 0);
48 x_[0] = x;
49 // Compute the state trajectory over the horizon
50 ocp_.eval_f(t, x_[0].data(), solution.template head<nuc>().data(), dx_.data());
51 x_[1] = x_[0] + dt * dx_;
52 for (size_t i=1; i<N; ++i) {
53 const int inucb2 = i * (nuc + 2 * nub);
54 ocp_.eval_f(t+i*dt, x_[i].data(), solution.template segment<nuc>(inucb2).data(), dx_.data());
55 x_[i+1] = x_[i] + dt * dx_;
56 }
57 // Compute the Lagrange multiplier over the horizon
58 ocp_.eval_phix(t+T, x_[N].data(), lmd_[N].data());
59 for (size_t i=N-1; i>=1; --i) {
60 const int inucb2 = i * (nuc + 2 * nub);
61 ocp_.eval_hx(t+i*dt, x_[i].data(), solution.template segment<nuc>(inucb2).data(),
62 lmd_[i+1].data(), dx_.data());
63 lmd_[i] = lmd_[i+1] + dt * dx_;
64 }
65 // Compute the erros in the first order necessary conditions (FONC)
66 ocp_.eval_hu(t, x_[0].data(), solution.template head<nuc>().data(), lmd_[1].data(),
67 fonc_hu.template head<nuc>().data());
68 for (size_t i=1; i<N; ++i) {
69 const int inucb2 = i * (nuc + 2 * nub);
70 ocp_.eval_hu(t+i*dt, x_[i].data(), solution.template segment<nuc>(inucb2).data(),
71 lmd_[i+1].data(), fonc_hu.template segment<nuc>(inucb2).data());
72 }
73 if constexpr (nub > 0) {
74 for (size_t i=0; i<N; ++i) {
75 const int inucb2 = i * (nuc + 2 * nub);
76 const auto uc = solution.template segment<nuc>(inucb2);
77 const auto dummy = solution.template segment<nub>(inucb2+nuc);
78 const auto mu = solution.template segment<nub>(inucb2+nuc+nub);
79 auto fonc_huc = fonc_hu.template segment<nuc>(inucb2);
80 auto fonc_hdummy = fonc_hu.template segment<nub>(inucb2+nuc);
81 auto fonc_hmu = fonc_hu.template segment<nub>(inucb2+nuc+nub);
82 ubounds::eval_hu(ocp_, uc, dummy, mu, fonc_huc);
83 ubounds::eval_hdummy(ocp_, uc, dummy, mu, fonc_hdummy);
84 ubounds::eval_hmu(ocp_, uc, dummy, mu, fonc_hmu);
85 }
86 }
87 }
88
89 void retrive_dummy(Vector<dim>& solution, Vector<dim>& fonc_hu, const Scalar min_dummy) {
90 if constexpr (nub > 0) {
91 for (size_t i=0; i<N; ++i) {
92 const int inucb2 = i * (nuc + 2 * nub);
93 const auto uc = solution.template segment<nuc>(inucb2);
94 auto dummy = solution.template segment<nub>(inucb2+nuc);
95 const auto mu = solution.template segment<nub>(inucb2+nuc+nub);
96 auto fonc_hmu = fonc_hu.template segment<nub>(inucb2+nuc+nub);
97 ubounds::eval_hmu(ocp_, uc, dummy, mu, fonc_hmu);
98 ubounds::clip_dummy(dummy, min_dummy);
99 dummy.array() = fonc_hmu.array().abs().sqrt();
100 }
101 }
102 }
103
104 void retrive_mu(Vector<dim>& solution, Vector<dim>& fonc_hu) {
105 if constexpr (nub > 0) {
106 for (size_t i=0; i<N; ++i) {
107 const int inucb2 = i * (nuc + 2 * nub);
108 const auto uc = solution.template segment<nuc>(inucb2);
109 const auto dummy = solution.template segment<nub>(inucb2+nuc);
110 auto mu = solution.template segment<nub>(inucb2+nuc+nub);
111 auto fonc_hdummy = fonc_hu.template segment<nub>(inucb2+nuc);
112 mu.setZero();
113 ubounds::eval_hdummy(ocp_, uc, dummy, mu, fonc_hdummy);
114 mu.array() = - fonc_hdummy.array() / (2.0 * dummy.array());
115 }
116 }
117 }
118
119 void synchronize_ocp() { ocp_.synchronize(); }
120
121 const OCP& ocp() const { return ocp_; }
122
123 const Horizon& horizon() const { return horizon_; }
124
125 const std::array<Vector<nx>, N+1>& x() const { return x_; }
126
127 const std::array<Vector<nx>, N+1>& lmd() const { return lmd_; }
128
129 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
130
131private:
132 OCP ocp_;
133 Horizon horizon_;
134 Vector<nx> dx_;
135 std::array<Vector<nx>, N+1> x_, lmd_;
136};
137
138} // namespace detail
139} // namespace cgmres
140
141#endif // CGMRES__SINGLE_SHOOTING_NLP_HPP_
Horizon of MPC.
Definition: horizon.hpp:18
Scalar T(const Scalar t) const
Gets the length of the horizon.
Definition: horizon.hpp:50
Definition: single_shooting_nlp.hpp:16
static constexpr int nc
Definition: single_shooting_nlp.hpp:20
void synchronize_ocp()
Definition: single_shooting_nlp.hpp:119
void retrive_dummy(Vector< dim > &solution, Vector< dim > &fonc_hu, const Scalar min_dummy)
Definition: single_shooting_nlp.hpp:89
SingleShootingNLP(const OCP &ocp, const Horizon &horizon)
Definition: single_shooting_nlp.hpp:25
static constexpr int nx
Definition: single_shooting_nlp.hpp:18
static constexpr int dim
Definition: single_shooting_nlp.hpp:23
const OCP & ocp() const
Definition: single_shooting_nlp.hpp:121
const std::array< Vector< nx >, N+1 > & x() const
Definition: single_shooting_nlp.hpp:125
const Horizon & horizon() const
Definition: single_shooting_nlp.hpp:123
void eval_fonc_hu(const Scalar t, const MatrixBase< VectorType > &x, const Vector< dim > &solution, Vector< dim > &fonc_hu)
Definition: single_shooting_nlp.hpp:43
static constexpr int nub
Definition: single_shooting_nlp.hpp:22
static constexpr int nuc
Definition: single_shooting_nlp.hpp:21
void retrive_mu(Vector< dim > &solution, Vector< dim > &fonc_hu)
Definition: single_shooting_nlp.hpp:104
const std::array< Vector< nx >, N+1 > & lmd() const
Definition: single_shooting_nlp.hpp:127
static constexpr int nu
Definition: single_shooting_nlp.hpp:19
void clip_dummy(const MatrixBase< VectorType > &dummy, const Scalar min)
Definition: control_input_bounds.hpp:127
void eval_hmu(const OCP &ocp, const MatrixBase< VectorType1 > &u, const MatrixBase< VectorType2 > &dummy, const MatrixBase< VectorType3 > &mu, const MatrixBase< VectorType4 > &hmu)
Definition: control_input_bounds.hpp:47
void eval_hdummy(const OCP &ocp, const MatrixBase< VectorType1 > &u, const MatrixBase< VectorType2 > &dummy, const MatrixBase< VectorType3 > &mu, const MatrixBase< VectorType4 > &hdummy)
Definition: control_input_bounds.hpp:32
void eval_hu(const OCP &ocp, const MatrixBase< VectorType1 > &u, const MatrixBase< VectorType2 > &dummy, const MatrixBase< VectorType3 > &mu, const MatrixBase< VectorType4 > &hu)
Definition: control_input_bounds.hpp:15
Definition: continuation_gmres.hpp:11
Eigen::Matrix< Scalar, size, 1 > Vector
Alias of Eigen::Vector.
Definition: types.hpp:23
double Scalar
Alias of double.
Definition: types.hpp:11
Eigen::MatrixBase< MatrixType > MatrixBase
Alias of Eigen::MatrixBase.
Definition: types.hpp:29