Skip to content

Commit 4d790c1

Browse files
committed
debug : InternalModel for NonLinModel now works
1 parent dc329ed commit 4d790c1

File tree

7 files changed

+123
-109
lines changed

7 files changed

+123
-109
lines changed

docs/src/manual/linmpc.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ for details).
8282

8383
[^1]: We could have use an [`InternalModel`](@ref) structure with
8484
`mpc = LinMPC(InternalModel(model), Hp=15, Hc=2, Mwt=[1, 1], Nwt=[0.1, 0.1])` to avoid
85-
state estimator design . It was tested on the example of this page and it gives similar
85+
state estimator design. It was tested on the example of this page and it gives similar
8686
results.
8787

8888
Before closing the loop, we call [`initstate!`](@ref) with the actual plant inputs and

src/controller/explicitmpc.jl

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ struct ExplicitMPC{S<:StateEstimator} <: PredictiveController
22
estim::S
33
ΔŨ::Vector{Float64}
44
::Vector{Float64}
5-
Ŷs::Vector{Float64}
65
Hp::Int
76
Hc::Int
87
M_Hp::Diagonal{Float64, Vector{Float64}}
@@ -29,12 +28,12 @@ struct ExplicitMPC{S<:StateEstimator} <: PredictiveController
2928
Ps::Matrix{Float64}
3029
d::Vector{Float64}
3130
::Vector{Float64}
32-
Yop::Vector{Float64}
31+
Ŷop::Vector{Float64}
3332
Dop::Vector{Float64}
3433
function ExplicitMPC{S}(estim::S, Hp, Hc, Mwt, Nwt, Lwt, ru) where {S<:StateEstimator}
3534
model = estim.model
3635
nu, ny, nd = model.nu, model.ny, model.nd
37-
, Ŷs = zeros(ny), zeros(ny*Hp)
36+
= zeros(ny)
3837
Cwt = Inf # no slack variable ϵ for ExplicitMPC
3938
Ewt = 0 # economic costs not supported for ExplicitMPC
4039
validate_weights(model, Hp, Hc, Mwt, Nwt, Lwt, Cwt, ru)
@@ -52,20 +51,20 @@ struct ExplicitMPC{S<:StateEstimator} <: PredictiveController
5251
P̃_chol = cholesky(P̃)
5352
Ks, Ps = init_stochpred(estim, Hp)
5453
d, D̂ = zeros(nd), zeros(nd*Hp)
55-
Yop, Dop = repeat(model.yop, Hp), repeat(model.dop, Hp)
54+
Ŷop, Dop = repeat(model.yop, Hp), repeat(model.dop, Hp)
5655
nvar = size(Ẽ, 2)
5756
ΔŨ = zeros(nvar)
5857
mpc = new(
5958
estim,
60-
ΔŨ, ŷ, Ŷs,
59+
ΔŨ, ŷ,
6160
Hp, Hc,
6261
M_Hp, Ñ_Hc, L_Hp, Cwt, Ewt, R̂u, R̂y,
6362
S̃_Hp, T_Hp, T_Hc,
6463
Ẽ, F, G, J, K, Q, P̃, q̃, p,
6564
P̃_chol,
6665
Ks, Ps,
6766
d, D̂,
68-
Yop, Dop,
67+
Ŷop, Dop,
6968
)
7069
return mpc
7170
end

src/controller/linmpc.jl

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ struct LinMPC{S<:StateEstimator} <: PredictiveController
44
con::ControllerConstraint
55
ΔŨ::Vector{Float64}
66
::Vector{Float64}
7-
Ŷs::Vector{Float64}
87
Hp::Int
98
Hc::Int
109
M_Hp::Diagonal{Float64, Vector{Float64}}
@@ -30,12 +29,12 @@ struct LinMPC{S<:StateEstimator} <: PredictiveController
3029
Ps::Matrix{Float64}
3130
d::Vector{Float64}
3231
::Vector{Float64}
33-
Yop::Vector{Float64}
32+
Ŷop::Vector{Float64}
3433
Dop::Vector{Float64}
3534
function LinMPC{S}(estim::S, Hp, Hc, Mwt, Nwt, Lwt, Cwt, ru, optim) where {S<:StateEstimator}
3635
model = estim.model
3736
nu, ny, nd = model.nu, model.ny, model.nd
38-
, Ŷs = zeros(ny), zeros(ny*Hp)
37+
= zeros(ny)
3938
Ewt = 0 # economic costs not supported for LinMPC
4039
validate_weights(model, Hp, Hc, Mwt, Nwt, Lwt, Cwt, ru)
4140
M_Hp = Diagonal{Float64}(repeat(Mwt, Hp))
@@ -51,19 +50,19 @@ struct LinMPC{S<:StateEstimator} <: PredictiveController
5150
P̃, q̃, p = init_quadprog(model, Ẽ, S̃_Hp, M_Hp, Ñ_Hc, L_Hp)
5251
Ks, Ps = init_stochpred(estim, Hp)
5352
d, D̂ = zeros(nd), zeros(nd*Hp)
54-
Yop, Dop = repeat(model.yop, Hp), repeat(model.dop, Hp)
53+
Ŷop, Dop = repeat(model.yop, Hp), repeat(model.dop, Hp)
5554
nvar = size(Ẽ, 2)
5655
ΔŨ = zeros(nvar)
5756
mpc = new(
5857
estim, optim, con,
59-
ΔŨ, ŷ, Ŷs,
58+
ΔŨ, ŷ,
6059
Hp, Hc,
6160
M_Hp, Ñ_Hc, L_Hp, Cwt, Ewt, R̂u, R̂y,
6261
S̃_Hp, T_Hp, T_Hc,
6362
Ẽ, F, G, J, K, Q, P̃, q̃, p,
6463
Ks, Ps,
6564
d, D̂,
66-
Yop, Dop,
65+
Ŷop, Dop,
6766
)
6867
init_optimization!(mpc)
6968
return mpc

src/controller/nonlinmpc.jl

Lines changed: 5 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ struct NonLinMPC{S<:StateEstimator, JEfunc<:Function} <: PredictiveController
66
con::ControllerConstraint
77
ΔŨ::Vector{Float64}
88
::Vector{Float64}
9-
Ŷs::Vector{Float64}
109
Hp::Int
1110
Hc::Int
1211
M_Hp::Diagonal{Float64, Vector{Float64}}
@@ -33,14 +32,14 @@ struct NonLinMPC{S<:StateEstimator, JEfunc<:Function} <: PredictiveController
3332
Ps::Matrix{Float64}
3433
d::Vector{Float64}
3534
::Vector{Float64}
36-
Yop::Vector{Float64}
35+
Ŷop::Vector{Float64}
3736
Dop::Vector{Float64}
3837
function NonLinMPC{S, JEFunc}(
3938
estim::S, Hp, Hc, Mwt, Nwt, Lwt, Cwt, Ewt, JE::JEFunc, ru, optim
4039
) where {S<:StateEstimator, JEFunc<:Function}
4140
model = estim.model
4241
nu, ny, nd = model.nu, model.ny, model.nd
43-
, Ŷs = zeros(ny), zeros(ny*Hp)
42+
= zeros(ny)
4443
validate_weights(model, Hp, Hc, Mwt, Nwt, Lwt, Cwt, ru, Ewt)
4544
M_Hp = Diagonal(convert(Vector{Float64}, repeat(Mwt, Hp)))
4645
N_Hc = Diagonal(convert(Vector{Float64}, repeat(Nwt, Hc)))
@@ -55,19 +54,19 @@ struct NonLinMPC{S<:StateEstimator, JEfunc<:Function} <: PredictiveController
5554
P̃, q̃, p = init_quadprog(model, Ẽ, S̃_Hp, M_Hp, Ñ_Hc, L_Hp)
5655
Ks, Ps = init_stochpred(estim, Hp)
5756
d, D̂ = zeros(nd), zeros(nd*Hp)
58-
Yop, Dop = repeat(model.yop, Hp), repeat(model.dop, Hp)
57+
Ŷop, Dop = repeat(model.yop, Hp), repeat(model.dop, Hp)
5958
nvar = size(Ẽ, 2)
6059
ΔŨ = zeros(nvar)
6160
mpc = new(
6261
estim, optim, con,
63-
ΔŨ, ŷ, Ŷs,
62+
ΔŨ, ŷ,
6463
Hp, Hc,
6564
M_Hp, Ñ_Hc, L_Hp, Cwt, Ewt, JE, R̂u, R̂y,
6665
S̃_Hp, T_Hp, T_Hc,
6766
Ẽ, F, G, J, K, Q, P̃, q̃, p,
6867
Ks, Ps,
6968
d, D̂,
70-
Yop, Dop,
69+
Ŷop, Dop,
7170
)
7271
init_optimization!(mpc)
7372
return mpc
@@ -319,59 +318,6 @@ function setnonlincon!(mpc::NonLinMPC, ::NonLinModel)
319318
return nothing
320319
end
321320

322-
# TODO: déplacer les 2 prochaines méthodes dans predictive_control.jl
323-
324-
"""
325-
obj_nonlinprog(mpc::PredictiveController, model::LinModel, ΔŨ::Vector{Real})
326-
327-
Objective function for [`NonLinMPC`](@ref) when `model` is a [`LinModel`](@ref).
328-
"""
329-
function obj_nonlinprog(mpc::PredictiveController, model::LinModel, Ŷ, ΔŨ::Vector{T}) where {T<:Real}
330-
J = obj_quadprog(ΔŨ, mpc.P̃, mpc.q̃)
331-
if !iszero(mpc.E)
332-
U = mpc.S̃_Hp*ΔŨ + mpc.T_Hp*(mpc.estim.lastu0 + model.uop)
333-
UE = [U; U[(end - model.nu + 1):end]]
334-
ŶE = [mpc.ŷ; Ŷ]
335-
D̂E = [mpc.d; mpc.D̂]
336-
J += mpc.E*mpc.JE(UE, ŶE, D̂E)
337-
end
338-
return J
339-
end
340-
341-
"""
342-
obj_nonlinprog(mpc::PredictiveController, model::SimModel, ΔŨ::Vector{Real})
343-
344-
Objective function for [`NonLinMPC`](@ref) when `model` is not a [`LinModel`](@ref).
345-
"""
346-
function obj_nonlinprog(mpc::PredictiveController, model::SimModel, Ŷ, ΔŨ::Vector{T}) where {T<:Real}
347-
# --- output setpoint tracking term ---
348-
êy = mpc.R̂y -
349-
JR̂y = êy'*mpc.M_Hp*êy
350-
# --- move suppression and slack variable term ---
351-
JΔŨ = ΔŨ'*mpc.Ñ_Hc*ΔŨ
352-
# --- input over prediction horizon ---
353-
if !isempty(mpc.R̂u) || !iszero(mpc.E)
354-
U = mpc.S̃_Hp*ΔŨ + mpc.T_Hp*(mpc.estim.lastu0 + model.uop)
355-
end
356-
# --- input setpoint tracking term ---
357-
if !isempty(mpc.R̂u)
358-
êu = mpc.R̂u - U
359-
JR̂u = êu'*mpc.L_Hp*êu
360-
else
361-
JR̂u = 0.0
362-
end
363-
# --- economic term ---
364-
if !iszero(mpc.E)
365-
UE = [U; U[(end - model.nu + 1):end]]
366-
ŶE = [mpc.ŷ; Ŷ]
367-
D̂E = [mpc.d; mpc.D̂]
368-
E_JE = mpc.E*mpc.JE(UE, ŶE, D̂E)
369-
else
370-
E_JE = 0.0
371-
end
372-
return JR̂y + JΔŨ + JR̂u + E_JE
373-
end
374-
375321

376322
"""
377323
con_nonlinprog(mpc::NonLinMPC, ::LinModel, ΔŨ::Vector{Real})

src/estimator/kalman.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ of sigma points, and ``\mathbf{X̂}_{k-1}^j(k)``, the vector at the ``j``th colu
517517
\mathbf{X̄}_{k-1}(k) &= \begin{bmatrix} \mathbf{X̂}_{k-1}^{1}(k) - \mathbf{x̂}_{k-1}(k) & \mathbf{X̂}_{k-1}^{2}(k) - \mathbf{x̂}_{k-1}(k) & \cdots & \mathbf{X̂}_{k-1}^{n_σ}(k) - \mathbf{x̂}_{k-1}(k) \end{bmatrix} \\
518518
\mathbf{Ȳ^m}(k) &= \begin{bmatrix} \mathbf{Ŷ^m}^{1}(k) - \mathbf{ŷ^m}(k) & \mathbf{Ŷ^m}^{2}(k) - \mathbf{ŷ^m}(k) & \cdots & \mathbf{Ŷ^m}^{n_σ}(k) - \mathbf{ŷ^m}(k) \end{bmatrix} \\
519519
\mathbf{M̂}(k) &= \mathbf{Ȳ^m}(k) \mathbf{Ŝ} \mathbf{Ȳ^m}'(k) + \mathbf{R̂} \\
520-
\mathbf{K̂}(k) &= \mathbf{X̄}_{k-1}(k) \mathbf{Ŝ} \mathbf{Ȳ^m}'(k) \big[\mathbf{M̂}(k)\big]^{-1} \\
520+
\mathbf{K̂}(k) &= \mathbf{X̄}_{k-1}(k) \mathbf{Ŝ} \mathbf{Ȳ^m}'(k) \mathbf{M̂^{-1}}(k) \\
521521
\mathbf{x̂}_k(k) &= \mathbf{x̂}_{k-1}(k) + \mathbf{K̂}(k) \big[ \mathbf{y^m}(k) - \mathbf{ŷ^m}(k) \big] \\
522522
\mathbf{P̂}_k(k) &= \mathbf{P̂}_{k-1}(k) - \mathbf{K̂}(k) \mathbf{M̂}(k) \mathbf{K̂}'(k) \\
523523
\mathbf{X̂}_k(k) &= \bigg[\begin{matrix} \mathbf{x̂}_{k}(k) & \mathbf{x̂}_{k}(k) & \cdots & \mathbf{x̂}_{k}(k) \end{matrix}\bigg] + \bigg[\begin{matrix} \mathbf{0} & \gamma \sqrt{\mathbf{P̂}_{k}(k)} & - \gamma \sqrt{\mathbf{P̂}_{k}(k)} \end{matrix}\bigg] \\

0 commit comments

Comments
 (0)