Skip to content

Commit fdbc414

Browse files
committed
added : NonLinModel mpc objective function
1 parent 8a0fb61 commit fdbc414

File tree

4 files changed

+62
-18
lines changed

4 files changed

+62
-18
lines changed

example/juMPC.jl

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ f2(x,u,d) = A*x + Bu*u + Bd*d
3838
h2(x,_) = C*x
3939

4040
nonLinModel1 = NonLinModel(f,h,Ts,2,4,2)
41-
nonLinModel2 = NonLinModel(f2,h2,Ts,2,4,2,1)
41+
nonLinModel2 = setop!(NonLinModel(f2,h2,Ts,2,4,2,1), uop=[10,10],yop=[50,30],dop=[5])
4242

4343
internalModel1 = InternalModel(linModel1)
4444
internalModel2 = InternalModel(linModel1,stoch_ym=[tf([1,0],[1,-1],Ts) 0; 0 tf([1,0],[1,-1],Ts)])
@@ -69,7 +69,13 @@ initstate!(uscKalmanFilter1,[0,0],[2,1])
6969

7070
nmpc1 = NonLinMPC(uscKalmanFilter1)
7171

72-
nmpc2 = NonLinMPC(nonLinModel1)
72+
nmpc2 = NonLinMPC(nonLinModel2, Hp=15, Hc=1, Mwt=[1, 1] , Nwt=[0.1, 0.1], Cwt=1e5)
73+
74+
setconstraint!(nmpc2, c_umin=[0,0], c_umax=[0,0])
75+
setconstraint!(nmpc2, c_ŷmin=[1,1], c_ŷmax=[1,1])
76+
setconstraint!(nmpc2, umin=[5, 9.9], umax=[Inf,Inf])
77+
setconstraint!(nmpc2, ŷmin=[-Inf,-Inf], ŷmax=[55, 35])
78+
setconstraint!(nmpc2, Δumin=[-Inf,-Inf],Δumax=[+Inf,+Inf])
7379

7480

7581
nx = linModel4.nx
@@ -127,11 +133,13 @@ function test_mpc(model, mpc)
127133
return u_data, y_data, r_data, d_data
128134
end
129135

130-
@time u_data, y_data, r_data, d_data = test_mpc(linModel4, mpc)
136+
#@time u_data, y_data, r_data, d_data = test_mpc(linModel4, mpc)
137+
138+
#@time u_data, y_data, r_data, d_data = test_mpc(linModel4, nmpc)
139+
140+
@time u_data, y_data, r_data, d_data = test_mpc(nonLinModel2, nmpc2)
131141

132-
@time u_data, y_data, r_data, d_data = test_mpc(linModel4, nmpc)
133142

134-
#=
135143
using PlotThemes, Plots
136144
#theme(:default)
137145
theme(:dark)
@@ -152,5 +160,5 @@ pd = plot(0:N-1,d_data[1,:],label=raw"$d_1$")
152160
display(pd)
153161
display(pu)
154162
display(py)
155-
=#
163+
156164

src/controller/linmpc.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ struct LinMPC{S<:StateEstimator} <: PredictiveController
1313
L_Hp::Diagonal{Float64, Vector{Float64}}
1414
C::Float64
1515
R̂u::Vector{Float64}
16+
R̂y::Vector{Float64}
1617
S̃_Hp::Matrix{Bool}
1718
T_Hp::Matrix{Bool}
1819
T_Hc::Matrix{Bool}
@@ -41,7 +42,8 @@ struct LinMPC{S<:StateEstimator} <: PredictiveController
4142
L_Hp = Diagonal{Float64}(repeat(Lwt, Hp))
4243
C = Cwt
4344
# manipulated input setpoint predictions are constant over Hp :
44-
R̂u = ~iszero(Lwt) ? repeat(ru, Hp) : R̂u = Float64[]
45+
R̂u = ~iszero(Lwt) ? repeat(ru, Hp) : R̂u = Float64[]
46+
R̂y = zeros(ny* Hp) # dummy R̂y (updated just before optimization)
4547
S_Hp, T_Hp, S_Hc, T_Hc = init_ΔUtoU(nu, Hp, Hc)
4648
E, F, G, J, Kd, Q = init_deterpred(model, Hp, Hc)
4749
con, S̃_Hp, Ñ_Hc, Ẽ = init_defaultcon(model, Hp, Hc, C, S_Hp, S_Hc, N_Hc, E)
@@ -55,7 +57,7 @@ struct LinMPC{S<:StateEstimator} <: PredictiveController
5557
estim, optim, con,
5658
ΔŨ, x̂d, x̂s, ŷ,
5759
Hp, Hc,
58-
M_Hp, Ñ_Hc, L_Hp, Cwt, R̂u,
60+
M_Hp, Ñ_Hc, L_Hp, Cwt, R̂u, R̂y,
5961
S̃_Hp, T_Hp, T_Hc,
6062
Ẽ, F, G, J, Kd, Q, P̃, q̃,
6163
Ks, Ps,

src/controller/nonlinmpc.jl

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct NonLinMPC{S<:StateEstimator, JEFunc<:Function} <: PredictiveController
1515
E::Float64
1616
JE::JEFunc
1717
R̂u::Vector{Float64}
18+
R̂y::Vector{Float64}
1819
S̃_Hp::Matrix{Bool}
1920
T_Hp::Matrix{Bool}
2021
T_Hc::Matrix{Bool}
@@ -46,6 +47,7 @@ struct NonLinMPC{S<:StateEstimator, JEFunc<:Function} <: PredictiveController
4647
C = Cwt
4748
# manipulated input setpoint predictions are constant over Hp :
4849
R̂u = ~iszero(Lwt) ? repeat(ru, Hp) : R̂u = Float64[]
50+
R̂y = zeros(ny* Hp) # dummy R̂y (updated just before optimization)
4951
S_Hp, T_Hp, S_Hc, T_Hc = init_ΔUtoU(nu, Hp, Hc)
5052
E, F, G, J, Kd, Q = init_deterpred(model, Hp, Hc)
5153
con, S̃_Hp, Ñ_Hc, Ẽ = init_defaultcon(model, Hp, Hc, C, S_Hp, S_Hc, N_Hc, E)
@@ -59,7 +61,7 @@ struct NonLinMPC{S<:StateEstimator, JEFunc<:Function} <: PredictiveController
5961
estim, optim, con,
6062
ΔŨ, x̂d, x̂s, ŷ,
6163
Hp, Hc,
62-
M_Hp, Ñ_Hc, L_Hp, Cwt, Ewt, JE, R̂u,
64+
M_Hp, Ñ_Hc, L_Hp, Cwt, Ewt, JE, R̂u, R̂y,
6365
S̃_Hp, T_Hp, T_Hc,
6466
Ẽ, F, G, J, Kd, Q, P̃, q̃,
6567
Ks, Ps,
@@ -189,17 +191,47 @@ init_objective!(mpc::NonLinMPC, _ ) = nothing
189191

190192
function obj_nonlinprog(mpc::NonLinMPC, model::LinModel, ΔŨ::NTuple{N, T}) where {T, N}
191193
ΔŨ = collect(ΔŨ) # convert NTuple to Vector
194+
Jqp = obj_quadprog(ΔŨ, mpc.P̃, mpc.q̃)
192195
U = mpc.S̃_Hp*ΔŨ + mpc.T_Hp*(mpc.estim.lastu0 + model.uop)
193196
UE = [U; U[end-model.nu+1:end]]
194197
ŶE = [mpc.ŷ; mpc.*ΔŨ + mpc.F]
195-
mpc.D̂0 + mpc.Dop
196198
D̂E = [mpc.d0 + model.dop; mpc.D̂0 + mpc.Dop]
197-
return obj_quadprog(ΔŨ, mpc.P̃, mpc.q̃) + mpc.JE(UE, ŶE, D̂E)
199+
return Jqp + mpc.JE(UE, ŶE, D̂E)
198200
end
199201

200202

201203
function obj_nonlinprog(mpc::NonLinMPC, model::SimModel, ΔŨ::NTuple{N, T}) where {T,N}
202-
J = 0.0
203-
#println("yoSimModel")
204-
return J
204+
ΔŨ = collect(ΔŨ) # convert NTuple to Vector
205+
U0 = mpc.S̃_Hp*ΔŨ + mpc.T_Hp*(mpc.estim.lastu0)
206+
# --- output setpoint tracking term ---
207+
Ŷd0 = Vector{T}(undef, model.ny*mpc.Hp)
208+
x̂d = mpc.x̂d
209+
d0 = mpc.d0
210+
for i=1:mpc.Hp
211+
u0 = U0[(1 + model.nu*(i-1)):(model.nu*i)]
212+
x̂d = model.f(x̂d, u0, d0)
213+
d0 = mpc.D̂0[(1 + model.nd*(i-1)):(model.nd*i)]
214+
ŷd0 = model.h(x̂d, d0)
215+
Ŷd0[(1 + model.ny*(i-1)):(model.ny*i)] = ŷd0
216+
end
217+
= Ŷd0 + mpc.F
218+
êy = mpc.R̂y -
219+
JR̂y = êy'*mpc.M_Hp*êy
220+
# --- move suppression term ---
221+
JΔŨ = ΔŨ'*mpc.Ñ_Hc*ΔŨ
222+
# --- input setpoint tracking term ---
223+
U = U0 + mpc.Uop
224+
if !isempty(mpc.R̂u)
225+
êu = mpc.R̂u - U
226+
JR̂u = êu'*mpc.L_Hp*
227+
else
228+
JR̂u = 0.0
229+
end
230+
# --- slack variable term ---
231+
= !isinf(mpc.C) ? mpc.C*ΔŨ[end] : 0.0
232+
# --- economic term ---
233+
UE = [U; U[end-model.nu+1:end]]
234+
ŶE = [mpc.ŷ; Ŷ]
235+
D̂E = [mpc.d0 + model.dop; mpc.D̂0 + mpc.Dop]
236+
return JR̂y + JΔŨ + JR̂u ++ mpc.JE(UE, ŶE, D̂E)
205237
end

src/predictive_control.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ function initpred!(mpc::PredictiveController, model::LinModel, d, D̂, Ŷs, R̂
342342
mpc.d0[:], mpc.D̂0[:] = d - model.dop, D̂ - mpc.Dop
343343
mpc.F[:] = mpc.F + mpc.G*mpc.d0 + mpc.J*mpc.D̂0
344344
end
345+
mpc.R̂y[:] = R̂y
345346
= mpc.F - R̂y
346347
mpc.q̃[:] = 2(mpc.M_Hp*mpc.Ẽ)'*
347348
p ='*mpc.M_Hp*
@@ -355,20 +356,21 @@ function initpred!(mpc::PredictiveController, model::LinModel, d, D̂, Ŷs, R̂
355356
end
356357

357358
@doc raw"""
358-
initpred!(mpc::PredictiveController, model::NonLinModel, d, D̂, Ŷs, _ )
359+
initpred!(mpc::PredictiveController, model::NonLinModel, d, D̂, Ŷs, R̂y )
359360
360361
Init `F`, `d0` and `D̂0` prediction matrices for [`NonLinModel`](@ref).
361362
362-
For [`NonLinModel`](@ref), the constant matrix `F` is ``\mathbf{F = Ŷ_s + Y_{op}}``, thus it
363+
For [`NonLinModel`](@ref), the constant matrix ``\mathbf{F = Ŷ_s + Y_{op}}``, thus it
363364
incorporates the stochastic predictions and the output operating point ``\mathbf{y_{op}}``
364-
repeated over ``H_p``. `d0` and `D̂0` are the measured disturbances and the predictions
365+
repeated over ``H_p``. `d0` and `D̂0` are the measured disturbances and its predictions
365366
without the operating points ``\mathbf{d_{op}}``.
366367
"""
367-
function initpred!(mpc::PredictiveController, model::NonLinModel, d, D̂, Ŷs , _ )
368+
function initpred!(mpc::PredictiveController, model::NonLinModel, d, D̂, Ŷs , R̂y )
368369
mpc.F[:] = Ŷs + mpc.Yop
369370
if model.nd 0
370371
mpc.d0[:], mpc.D̂0[:] = d - model.dop, D̂ - mpc.Dop
371372
end
373+
mpc.R̂y[:] = R̂y
372374
p = 0.0 # only used for LinModel objects
373375
return p
374376
end

0 commit comments

Comments
 (0)