Skip to content

Commit 512544c

Browse files
committed
added field :x̂end in dict of getinfo
1 parent c10f838 commit 512544c

File tree

5 files changed

+124
-71
lines changed

5 files changed

+124
-71
lines changed

src/controller/explicitmpc.jl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ struct ExplicitMPC{SE<:StateEstimator} <: PredictiveController
2020
J::Matrix{Float64}
2121
K::Matrix{Float64}
2222
V::Matrix{Float64}
23+
ẽx̂::Matrix{Float64}
24+
fx̂::Vector{Float64}
25+
gx̂::Matrix{Float64}
26+
jx̂::Matrix{Float64}
27+
kx̂::Matrix{Float64}
28+
vx̂::Matrix{Float64}
2329
::Hermitian{Float64, Matrix{Float64}}
2430
::Vector{Float64}
2531
p::Vector{Float64}
@@ -44,8 +50,8 @@ struct ExplicitMPC{SE<:StateEstimator} <: PredictiveController
4450
R̂y, R̂u = zeros(ny*Hp), zeros(nu*Hp) # dummy vals (updated just before optimization)
4551
noR̂u = iszero(L_Hp)
4652
S, T = init_ΔUtoU(nu, Hp, Hc)
47-
E, F, G, J, K, V = init_predmat(estim, model, Hp, Hc)
48-
S̃, Ñ_Hc, Ẽ = S, N_Hc, E # no slack variable ϵ for ExplicitMPC
53+
E, F, G, J, K, V, ex̂, fx̂, gx̂, jx̂, kx̂, vx̂ = init_predmat(estim, model, Hp, Hc)
54+
S̃, Ñ_Hc, Ẽ, ẽx̂ = S, N_Hc, E, ex̂ # no slack variable ϵ for ExplicitMPC
4955
P̃, q̃, p = init_quadprog(model, Ẽ, S̃, M_Hp, Ñ_Hc, L_Hp)
5056
P̃_chol = cholesky(P̃)
5157
Ks, Ps = init_stochpred(estim, Hp)
@@ -59,7 +65,7 @@ struct ExplicitMPC{SE<:StateEstimator} <: PredictiveController
5965
Hp, Hc,
6066
M_Hp, Ñ_Hc, L_Hp, Cwt, Ewt, R̂u, R̂y, noR̂u,
6167
S̃, T,
62-
Ẽ, F, G, J, K, V, P̃, q̃, p,
68+
Ẽ, F, G, J, K, V, ẽx̂, fx̂, gx̂, jx̂, kx̂, vx̂, P̃, q̃, p,
6369
P̃_chol,
6470
Ks, Ps,
6571
d0, D̂0,

src/controller/linmpc.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ struct LinMPC{SE<:StateEstimator} <: PredictiveController
2222
J::Matrix{Float64}
2323
K::Matrix{Float64}
2424
V::Matrix{Float64}
25-
ex̂::Matrix{Float64}
25+
ẽx̂::Matrix{Float64}
2626
fx̂::Vector{Float64}
2727
gx̂::Matrix{Float64}
2828
jx̂::Matrix{Float64}
@@ -51,7 +51,7 @@ struct LinMPC{SE<:StateEstimator} <: PredictiveController
5151
noR̂u = iszero(L_Hp)
5252
S, T = init_ΔUtoU(nu, Hp, Hc)
5353
E, F, G, J, K, V, ex̂, fx̂, gx̂, jx̂, kx̂, vx̂ = init_predmat(estim, model, Hp, Hc)
54-
con, S̃, Ñ_Hc, Ẽ = init_defaultcon(estim, Hp, Hc, C, S, N_Hc, E, ex̂)
54+
con, S̃, Ñ_Hc, Ẽ, ẽx̂ = init_defaultcon(estim, Hp, Hc, C, S, N_Hc, E, ex̂)
5555
P̃, q̃, p = init_quadprog(model, Ẽ, S̃, M_Hp, Ñ_Hc, L_Hp)
5656
Ks, Ps = init_stochpred(estim, Hp)
5757
d0, D̂0 = zeros(nd), zeros(nd*Hp)
@@ -64,7 +64,7 @@ struct LinMPC{SE<:StateEstimator} <: PredictiveController
6464
Hp, Hc,
6565
M_Hp, Ñ_Hc, L_Hp, Cwt, Ewt, R̂u, R̂y, noR̂u,
6666
S̃, T,
67-
Ẽ, F, G, J, K, V, ex̂, fx̂, gx̂, jx̂, kx̂, vx̂, P̃, q̃, p,
67+
Ẽ, F, G, J, K, V, ẽx̂, fx̂, gx̂, jx̂, kx̂, vx̂, P̃, q̃, p,
6868
Ks, Ps,
6969
d0, D̂0,
7070
Ŷop, Dop,

src/controller/nonlinmpc.jl

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct NonLinMPC{SE<:StateEstimator, JEfunc<:Function} <: PredictiveController
2525
J::Matrix{Float64}
2626
K::Matrix{Float64}
2727
V::Matrix{Float64}
28-
ex̂::Matrix{Float64}
28+
ẽx̂::Matrix{Float64}
2929
fx̂::Vector{Float64}
3030
gx̂::Matrix{Float64}
3131
jx̂::Matrix{Float64}
@@ -55,7 +55,7 @@ struct NonLinMPC{SE<:StateEstimator, JEfunc<:Function} <: PredictiveController
5555
noR̂u = iszero(L_Hp)
5656
S, T = init_ΔUtoU(nu, Hp, Hc)
5757
E, F, G, J, K, V, ex̂, fx̂, gx̂, jx̂, kx̂, vx̂ = init_predmat(estim, model, Hp, Hc)
58-
con, S̃, Ñ_Hc, Ẽ = init_defaultcon(estim, Hp, Hc, C, S, N_Hc, E, ex̂)
58+
con, S̃, Ñ_Hc, Ẽ, ẽx̂ = init_defaultcon(estim, Hp, Hc, C, S, N_Hc, E, ex̂)
5959
P̃, q̃, p = init_quadprog(model, Ẽ, S̃, M_Hp, Ñ_Hc, L_Hp)
6060
Ks, Ps = init_stochpred(estim, Hp)
6161
d0, D̂0 = zeros(nd), zeros(nd*Hp)
@@ -68,7 +68,7 @@ struct NonLinMPC{SE<:StateEstimator, JEfunc<:Function} <: PredictiveController
6868
Hp, Hc,
6969
M_Hp, Ñ_Hc, L_Hp, Cwt, Ewt, JE, R̂u, R̂y, noR̂u,
7070
S̃, T,
71-
Ẽ, F, G, J, K, V, ex̂, fx̂, gx̂, jx̂, kx̂, vx̂, P̃, q̃, p,
71+
Ẽ, F, G, J, K, V, ẽx̂, fx̂, gx̂, jx̂, kx̂, vx̂, P̃, q̃, p,
7272
Ks, Ps,
7373
d0, D̂0,
7474
Ŷop, Dop,
@@ -278,8 +278,8 @@ function init_optimization!(mpc::NonLinMPC)
278278
if ΔŨtup != last_ΔŨtup_float
279279
= get_tmp(x̂_cache, ΔŨtup[1])
280280
C = get_tmp(C_cache, ΔŨtup[1])
281-
predict!(x̂, Ŷ, mpc, model, ΔŨ)
282-
con_nonlinprog!(C, mpc, model, , Ŷ, ΔŨ)
281+
Ŷ, x̂end = predict!(Ŷ, x̂, mpc, model, ΔŨ)
282+
con_nonlinprog!(C, mpc, model, end, Ŷ, ΔŨ)
283283
last_ΔŨtup_float = ΔŨtup
284284
end
285285
return obj_nonlinprog(mpc, model, Ŷ, ΔŨ)
@@ -290,8 +290,8 @@ function init_optimization!(mpc::NonLinMPC)
290290
if ΔŨtup != last_ΔŨtup_dual
291291
= get_tmp(x̂_cache, ΔŨtup[1])
292292
C = get_tmp(C_cache, ΔŨtup[1])
293-
predict!(x̂, Ŷ, mpc, model, ΔŨ)
294-
con_nonlinprog!(C, mpc, model, , Ŷ, ΔŨ)
293+
Ŷ, x̂end = predict!(Ŷ, x̂, mpc, model, ΔŨ)
294+
con_nonlinprog!(C, mpc, model, end, Ŷ, ΔŨ)
295295
last_ΔŨtup_dual = ΔŨtup
296296
end
297297
return obj_nonlinprog(mpc, model, Ŷ, ΔŨ)
@@ -302,8 +302,8 @@ function init_optimization!(mpc::NonLinMPC)
302302
= get_tmp(x̂_cache, ΔŨtup[1])
303303
= get_tmp(Ŷ_cache, ΔŨtup[1])
304304
ΔŨ = collect(ΔŨtup)
305-
predict!(x̂, Ŷ, mpc, model, ΔŨ)
306-
con_nonlinprog!(C, mpc, model, , Ŷ, ΔŨ)
305+
Ŷ, x̂end = predict!(Ŷ, x̂, mpc, model, ΔŨ)
306+
C = con_nonlinprog!(C, mpc, model, end, Ŷ, ΔŨ)
307307
last_ΔŨtup_float = ΔŨtup
308308
end
309309
return C[i]
@@ -314,8 +314,8 @@ function init_optimization!(mpc::NonLinMPC)
314314
= get_tmp(x̂_cache, ΔŨtup[1])
315315
= get_tmp(Ŷ_cache, ΔŨtup[1])
316316
ΔŨ = collect(ΔŨtup)
317-
predict!(x̂, Ŷ, mpc, model, ΔŨ)
318-
con_nonlinprog!(C, mpc, model, , Ŷ, ΔŨ)
317+
Ŷ, x̂end = predict!(Ŷ, x̂, mpc, model, ΔŨ)
318+
C = con_nonlinprog!(C, mpc, model, end, Ŷ, ΔŨ)
319319
last_ΔŨtup_dual = ΔŨtup
320320
end
321321
return C[i]
@@ -377,25 +377,25 @@ function setnonlincon!(mpc::NonLinMPC, ::NonLinModel)
377377
end
378378

379379
"""
380-
con_nonlinprog!(C, mpc::NonLinMPC, model::SimModel, , Ŷ, ΔŨ)
380+
con_nonlinprog!(C, mpc::NonLinMPC, model::SimModel, x̂end, Ŷ, ΔŨ)
381381
382382
Nonlinear constrains for [`NonLinMPC`](@ref) when `model` is not a [`LinModel`](@ref).
383383
"""
384-
function con_nonlinprog!(C, mpc::NonLinMPC, model::SimModel, , Ŷ, ΔŨ)
384+
function con_nonlinprog!(C, mpc::NonLinMPC, model::SimModel, end, Ŷ, ΔŨ)
385385
ny, nx̂, Hp = model.ny, mpc.estim.nx̂, mpc.Hp
386386
i_end_Ymin, i_end_Ymax = 1Hp*ny , 2Hp*ny
387387
i_end_x̂min, i_end_x̂max = 2Hp*ny + 1nx̂, 2Hp*ny + 2nx̂
388388
if !isinf(mpc.C) # constraint softening activated :
389389
ϵ = ΔŨ[end]
390390
C[ 1:i_end_Ymin] = (mpc.con.Ymin - Ŷ) - ϵ*mpc.con.c_Ymin
391391
C[i_end_Ymin+1:i_end_Ymax] = (Ŷ - mpc.con.Ymax) - ϵ*mpc.con.c_Ymax
392-
C[i_end_Ymax+1:i_end_x̂min] = (mpc.con.x̂min - ) - ϵ*mpc.con.c_x̂min
393-
C[i_end_x̂min+1:i_end_x̂max] = ( - mpc.con.x̂max) - ϵ*mpc.con.c_x̂max
392+
C[i_end_Ymax+1:i_end_x̂min] = (mpc.con.x̂min - end) - ϵ*mpc.con.c_x̂min
393+
C[i_end_x̂min+1:i_end_x̂max] = (end - mpc.con.x̂max) - ϵ*mpc.con.c_x̂max
394394
else # no constraint softening :
395-
C[ 1:i_end_Ymin] = (mpc.con.Ymin -)
396-
C[i_end_Ymin+1:i_end_Ymax] = (- mpc.con.Ymax)
397-
C[i_end_Ymax+1:i_end_x̂min] = mpc.con.x̂min -
398-
C[i_end_x̂min+1:i_end_x̂max] = - mpc.con.x̂max
395+
C[ 1:i_end_Ymin] = mpc.con.Ymin -
396+
C[i_end_Ymin+1:i_end_Ymax] =- mpc.con.Ymax
397+
C[i_end_Ymax+1:i_end_x̂min] = mpc.con.x̂min - end
398+
C[i_end_x̂min+1:i_end_x̂max] = end - mpc.con.x̂max
399399
end
400400
C[isinf.(C)] .= 0 # replace ±Inf with 0 to avoid INVALID_MODEL error
401401
return C

src/predictive_control.jl

Lines changed: 57 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ function setconstraint!(
198198
model, con, optim = mpc.estim.model, mpc.con, mpc.optim
199199
nu, ny, nx̂, Hp, Hc = model.nu, model.ny, mpc.estim.nx̂, mpc.Hp, mpc.Hc
200200
notSolvedYet = (termination_status(optim) == OPTIMIZE_NOT_CALLED)
201-
C, E, ex̂ = mpc.C, mpc.Ẽ[:, 1:nu*Hc], mpc.ex̂
201+
C, E, ex̂ = mpc.C, mpc.Ẽ[:, 1:nu*Hc], mpc.ẽx̂[:, 1:nu*Hc]
202202
isnothing(Umin) && !isnothing(umin) && (Umin = repeat(umin, Hp))
203203
isnothing(Umax) && !isnothing(umax) && (Umax = repeat(umax, Hp))
204204
isnothing(ΔUmin) && !isnothing(Δumin) && (ΔUmin = repeat(Δumin, Hc))
@@ -386,18 +386,19 @@ Get additional information about `mpc` controller optimum to ease troubleshootin
386386
The function should be called after calling [`moveinput!`](@ref). It returns the dictionary
387387
`info` with the following fields:
388388
389-
- `:ΔU` : optimal manipulated input increments over `Hc` ``(\mathbf{ΔU})``
390-
- `:ϵ` : optimal slack variable ``(ϵ)``
391-
- `:J` : objective value optimum ``(J)``
392-
- `:U` : optimal manipulated inputs over `Hp` ``(\mathbf{U})``
393-
- `:u` : current optimal manipulated input ``(\mathbf{u})``
394-
- `:d` : current measured disturbance ``(\mathbf{d})``
395-
- `:D̂` : predicted measured disturbances over `Hp` ``(\mathbf{D̂})``
396-
- `:ŷ` : current estimated output ``(\mathbf{ŷ})``
397-
- `:Ŷ` : optimal predicted outputs over `Hp` ``(\mathbf{Ŷ})``
398-
- `:Ŷs` : predicted stochastic output over `Hp` of [`InternalModel`](@ref) ``(\mathbf{Ŷ_s})``
399-
- `:R̂y` : predicted output setpoint over `Hp` ``(\mathbf{R̂_y})``
400-
- `:R̂u` : predicted manipulated input setpoint over `Hp` ``(\mathbf{R̂_u})``
389+
- `:ΔU` : optimal manipulated input increments over `Hc` ``(\mathbf{ΔU})``
390+
- `:ϵ` : optimal slack variable ``(ϵ)``
391+
- `:J` : objective value optimum ``(J)``
392+
- `:U` : optimal manipulated inputs over `Hp` ``(\mathbf{U})``
393+
- `:u` : current optimal manipulated input ``(\mathbf{u})``
394+
- `:d` : current measured disturbance ``(\mathbf{d})``
395+
- `:D̂` : predicted measured disturbances over `Hp` ``(\mathbf{D̂})``
396+
- `:ŷ` : current estimated output ``(\mathbf{ŷ})``
397+
- `:Ŷ` : optimal predicted outputs over `Hp` ``(\mathbf{Ŷ})``
398+
- `:x̂end : optimal terminal states ``(\mathbf{x̂}_{k-1}(k+H_p))``
399+
- `:Ŷs` : predicted stochastic output over `Hp` of [`InternalModel`](@ref) ``(\mathbf{Ŷ_s})``
400+
- `:R̂y` : predicted output setpoint over `Hp` ``(\mathbf{R̂_y})``
401+
- `:R̂u` : predicted manipulated input setpoint over `Hp` ``(\mathbf{R̂_u})``
401402
402403
For [`LinMPC`](@ref) and [`NonLinMPC`](@ref), the field `:sol` also contains the optimizer
403404
solution summary that can be printed. Lastly, the optimal economic cost `:JE` is also
@@ -416,17 +417,18 @@ julia> round.(getinfo(mpc)[:Ŷ], digits=3)
416417
"""
417418
function getinfo(mpc::PredictiveController)
418419
info = Dict{Symbol, InfoDictType}()
419-
x̂, Ŷ = similar(mpc.estim.x̂), similar(mpc.Ŷop)
420-
predict!(x̂, Ŷ, mpc, mpc.estim.model, mpc.ΔŨ)
421-
info[:ΔU] = mpc.ΔŨ[1:mpc.Hc*mpc.estim.model.nu]
422-
info[] = isinf(mpc.C) ? NaN : mpc.ΔŨ[end]
423-
info[:J] = obj_nonlinprog(mpc, mpc.estim.model, Ŷ, mpc.ΔŨ) + mpc.p[]
424-
info[:U] = mpc.*mpc.ΔŨ + mpc.T*(mpc.estim.lastu0 + mpc.estim.model.uop)
425-
info[:u] = info[:U][1:mpc.estim.model.nu]
426-
info[:d] = mpc.d0 + mpc.estim.model.dop
427-
info[:D̂] = mpc.D̂0 + mpc.Dop
428-
info[:ŷ] = mpc.
429-
info[:Ŷ] =
420+
Ŷ, x̂ = similar(mpc.Ŷop), similar(mpc.estim.x̂)
421+
Ŷ, x̂end = predict!(Ŷ, x̂, mpc, mpc.estim.model, mpc.ΔŨ)
422+
info[:ΔU] = mpc.ΔŨ[1:mpc.Hc*mpc.estim.model.nu]
423+
info[] = isinf(mpc.C) ? NaN : mpc.ΔŨ[end]
424+
info[:J] = obj_nonlinprog(mpc, mpc.estim.model, Ŷ, mpc.ΔŨ) + mpc.p[]
425+
info[:U] = mpc.*mpc.ΔŨ + mpc.T*(mpc.estim.lastu0 + mpc.estim.model.uop)
426+
info[:u] = info[:U][1:mpc.estim.model.nu]
427+
info[:d] = mpc.d0 + mpc.estim.model.dop
428+
info[:D̂] = mpc.D̂0 + mpc.Dop
429+
info[:ŷ] = mpc.
430+
info[:Ŷ] =
431+
info[:x̂end] =end
430432
info[:Ŷs] = mpc.Ŷop - repeat(mpc.estim.model.yop, mpc.Hp) # Ŷop = Ŷs + Yop
431433
info[:R̂y] = mpc.R̂y
432434
info[:R̂u] = mpc.R̂u
@@ -592,25 +594,27 @@ end
592594
predictstoch!(::PredictiveController, ::StateEstimator, _ , _ ) = nothing
593595

594596
@doc raw"""
595-
predict!( _ , Ŷ, mpc::PredictiveController, model::LinModel, ΔŨ)
597+
predict!(Ŷ, x̂, mpc::PredictiveController, model::LinModel, ΔŨ) -> Ŷ, x̂end
596598
597-
Compute the outputs predictions ``\mathbf{Ŷ}`` when `model` is a [`LinModel`](@ref).
599+
Compute the predictions `Ŷ` and terminal states `x̂end` if model is a [`LinModel`](@ref).
600+
601+
The method mutates `Ŷ` and `x̂` vector arguments. The `x̂end` vector is used for
602+
the terminal constraints applied on ``\mathbf{x̂}_{k-1}(k+H_p)``.
598603
"""
599-
function predict!( _ , Ŷ, mpc::PredictiveController, ::LinModel, ΔŨ::Vector{T}) where {T<:Real}
600-
mul!(Ŷ, mpc.Ẽ, ΔŨ) + mpc.F # in-place operations to reduce allocations
601-
return nothing
604+
function predict!(Ŷ, x̂, mpc::PredictiveController, ::LinModel, ΔŨ::Vector{T}) where {T<:Real}
605+
# in-place operations to reduce allocations :
606+
mul!(Ŷ, mpc.Ẽ, ΔŨ) + mpc.F
607+
mul!(x̂, mpc.ẽx̂, ΔŨ) + mpc.fx̂
608+
end =
609+
return Ŷ, x̂end
602610
end
603611

604612
@doc raw"""
605-
predict!(x̂, Ŷ, mpc::PredictiveController, model::SimModel, ΔŨ)
606-
607-
Compute ``\mathbf{x̂}_{k-1}(k+H_p)``, ``\mathbf{Ŷ}`` if `model` is not a [`LinModel`](@ref).
613+
predict!(Ŷ, x̂, mpc::PredictiveController, model::SimModel, ΔŨ) -> Ŷ, x̂end
608614
609-
The method mutates `x̂` and `Ŷ` vector arguments. After a `predict!` call, `x̂` will contain
610-
the states at the end of the prediction horizon ``\mathbf{x̂}_{k-1}(k+H_p)`` (used for
611-
terminal constraints).
615+
Compute both vectors if `model` is not a [`LinModel`](@ref).
612616
"""
613-
function predict!(x̂, Ŷ, mpc::PredictiveController, model::SimModel, ΔŨ::Vector{T}) where {T<:Real}
617+
function predict!(Ŷ, x̂, mpc::PredictiveController, model::SimModel, ΔŨ::Vector{T}) where {T<:Real}
614618
nu, ny, nd, Hp, Hc = model.nu, model.ny, model.nd, mpc.Hp, mpc.Hc
615619
u0::Vector{T} = copy(mpc.estim.lastu0)
616620
d0::Vector{T} = copy(mpc.d0)
@@ -624,7 +628,8 @@ function predict!(x̂, Ŷ, mpc::PredictiveController, model::SimModel, ΔŨ::V
624628
Ŷ[(1 + ny*(j-1)):(ny*j)] = (mpc.estim, x̂, d0)
625629
end
626630
Ŷ[:] =+ mpc.Ŷop # Ŷop = Ŷs + Yop, and Ŷs=0 if mpc.estim is not an InternalModel
627-
return nothing
631+
end =
632+
return Ŷ, x̂end
628633
end
629634

630635
@doc raw"""
@@ -980,7 +985,7 @@ function init_defaultcon(estim, Hp, Hc, C, S, N_Hc, E, ex̂)
980985
A_Umin, A_Umax, S̃ = relaxU(C, c_Umin, c_Umax, S)
981986
A_ΔŨmin, A_ΔŨmax, ΔŨmin, ΔŨmax, Ñ_Hc = relaxΔU(C, c_ΔUmin, c_ΔUmax, ΔUmin, ΔUmax, N_Hc)
982987
A_Ymin, A_Ymax, Ẽ = relaxŶ(model, C, c_Ymin, c_Ymax, E)
983-
A_x̂min, A_x̂max = relaxterminal(model, C, c_x̂min, c_x̂max, ex̂)
988+
A_x̂min, A_x̂max, ẽx̂ = relaxterminal(model, C, c_x̂min, c_x̂max, ex̂)
984989
i_Umin, i_Umax = .!isinf.(Umin), .!isinf.(Umax)
985990
i_ΔŨmin, i_ΔŨmax = .!isinf.(ΔŨmin), .!isinf.(ΔŨmax)
986991
i_Ymin, i_Ymax = .!isinf.(Ymin), .!isinf.(Ymax)
@@ -996,7 +1001,7 @@ function init_defaultcon(estim, Hp, Hc, C, S, N_Hc, E, ex̂)
9961001
A_Umin , A_Umax, A_ΔŨmin, A_ΔŨmax , A_Ymin, A_Ymax, A_x̂min, A_x̂max,
9971002
A , b , i_b , c_Ymin , c_Ymax, c_x̂min, c_x̂max,
9981003
)
999-
return con, S̃, Ñ_Hc, Ẽ
1004+
return con, S̃, Ñ_Hc, Ẽ, ẽx̂
10001005
end
10011006

10021007
"Repeat predictive controller constraints over prediction `Hp` and control `Hc` horizons."
@@ -1105,7 +1110,7 @@ function relaxŶ(::LinModel, C, c_Ymin, c_Ymax, E)
11051110
if !isinf(C) # ΔŨ = [ΔU; ϵ]
11061111
# ϵ impacts predicted output constraint calculations:
11071112
A_Ymin, A_Ymax = -[E c_Ymin], [E -c_Ymax]
1108-
# ϵ has not impact on output predictions
1113+
# ϵ has no impact on output predictions
11091114
= [E zeros(size(E, 1), 1)]
11101115
else # ΔŨ = ΔU (only hard constraints)
11111116
= E
@@ -1117,7 +1122,7 @@ end
11171122
"Return empty matrices if model is not a [`LinModel`](@ref)"
11181123
function relaxŶ(::SimModel, C, c_Ymin, c_Ymax, E)
11191124
= !isinf(C) ? [E zeros(0, 1)] : E
1120-
A_Ymin, A_Ymax = Ẽ, Ẽ
1125+
A_Ymin, A_Ymax = -Ẽ,
11211126
return A_Ymin, A_Ymax, Ẽ
11221127
end
11231128

@@ -1128,16 +1133,23 @@ TBW
11281133
"""
11291134
function relaxterminal(::LinModel, C, c_x̂min, c_x̂max, ex̂)
11301135
if !isinf(C) # ΔŨ = [ΔU; ϵ]
1131-
# ϵ impacts predicted terminal state calculations:
1132-
A_x̂min, A_x̂max = -[ex̂ c_x̂min], [ex̂ -c_x̂max]
1136+
# ϵ impacts terminal constraint calculations:
1137+
A_x̂min, A_x̂max = -[ex̂ c_x̂min], [ex̂ -c_x̂max]
1138+
# ϵ has no impact on terminal state predictions
1139+
ẽx̂ = [ex̂ zeros(size(ex̂, 1), 1)]
11331140
else # ΔŨ = ΔU (only hard constraints)
1141+
ẽx̂ = ex̂
11341142
A_x̂min, A_x̂max = -ex̂, ex̂
11351143
end
1136-
return A_x̂min, A_x̂max
1144+
return A_x̂min, A_x̂max, ẽx̂
11371145
end
11381146

11391147
"Return empty matrices if model is not a [`LinModel`](@ref)"
1140-
relaxterminal(::SimModel, C, c_x̂min, c_x̂max, ex̂) = -ex̂, ex̂
1148+
function relaxterminal(::SimModel, C, c_x̂min, c_x̂max, ex̂)
1149+
ẽx̂ = !isinf(C) ? [ex̂ zeros(0, 1)] : ex̂
1150+
A_x̂min, A_x̂max = -ẽx̂, ẽx̂
1151+
return A_x̂min, A_x̂max, ẽx̂
1152+
end
11411153

11421154

11431155
@doc raw"""

0 commit comments

Comments
 (0)