Skip to content

Commit b9f325f

Browse files
authored
Merge pull request #274 from JuliaControl/lastu_arg
added: `lastu` keyword argument to `moveinput!`
2 parents a93a568 + ed07620 commit b9f325f

File tree

4 files changed

+24
-17
lines changed

4 files changed

+24
-17
lines changed

docs/src/internals/predictive_control.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ ModelPredictiveControl.get_nonlinops(::NonLinMPC, ::ModelPredictiveControl.Gener
3030
## Update Quadratic Optimization
3131

3232
```@docs
33-
ModelPredictiveControl.initpred!(::PredictiveController, ::LinModel, ::Any, ::Any, ::Any, ::Any)
33+
ModelPredictiveControl.initpred!(::PredictiveController, ::LinModel, ::Any, ::Any, ::Any, ::Any, ::Any)
3434
ModelPredictiveControl.linconstraint!(::PredictiveController, ::LinModel, ::TranscriptionMethod)
3535
ModelPredictiveControl.linconstrainteq!
3636
```

src/controller/construct.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -553,14 +553,15 @@ get_Hc(nb::AbstractVector{Int}) = length(nb)
553553

554554

555555
"""
556-
validate_args(mpc::PredictiveController, ry, d, D̂, R̂y, R̂u)
556+
validate_args(mpc::PredictiveController, ry, d, lastu, D̂, R̂y, R̂u)
557557
558558
Check the dimensions of the arguments of [`moveinput!`](@ref).
559559
"""
560-
function validate_args(mpc::PredictiveController, ry, d, D̂, R̂y, R̂u)
560+
function validate_args(mpc::PredictiveController, ry, d, lastu, D̂, R̂y, R̂u)
561561
ny, nd, nu, Hp = mpc.estim.model.ny, mpc.estim.model.nd, mpc.estim.model.nu, mpc.Hp
562562
size(ry) (ny,) && throw(DimensionMismatch("ry size $(size(ry)) ≠ output size ($ny,)"))
563563
size(d) (nd,) && throw(DimensionMismatch("d size $(size(d)) ≠ measured dist. size ($nd,)"))
564+
size(lastu) (nu,) && throw(DimensionMismatch("lastu size $(size(lastu)) ≠ manip. input size ($nu,)"))
564565
size(D̂) (nd*Hp,) && throw(DimensionMismatch("D̂ size $(size(D̂)) ≠ measured dist. size × Hp ($(nd*Hp),)"))
565566
size(R̂y) (ny*Hp,) && throw(DimensionMismatch("R̂y size $(size(R̂y)) ≠ output size × Hp ($(ny*Hp),)"))
566567
size(R̂u) (nu*Hp,) && throw(DimensionMismatch("R̂u size $(size(R̂u)) ≠ manip. input size × Hp ($(nu*Hp),)"))

src/controller/execute.jl

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ See also [`LinMPC`](@ref), [`ExplicitMPC`](@ref), [`NonLinMPC`](@ref).
3737
- `mpc::PredictiveController` : solve optimization problem of `mpc`.
3838
- `ry=mpc.estim.model.yop` : current output setpoints ``\mathbf{r_y}(k)``.
3939
- `d=[]` : current measured disturbances ``\mathbf{d}(k)``.
40+
- `lastu=mpc.lastu0+mpc.estim.model.uop`: last manipulated input ``\mathbf{u}(k-1)``.
4041
- `D̂=repeat(d, mpc.Hp)` or *`Dhat`* : predicted measured disturbances ``\mathbf{D̂}``, constant
4142
in the future by default or ``\mathbf{d̂}(k+j)=\mathbf{d}(k)`` for ``j=1`` to ``H_p``.
4243
- `R̂y=repeat(ry, mpc.Hp)` or *`Rhaty`* : predicted output setpoints ``\mathbf{R̂_y}``, constant
@@ -59,6 +60,7 @@ function moveinput!(
5960
mpc::PredictiveController,
6061
ry::Vector = mpc.estim.model.yop,
6162
d ::Vector = mpc.buffer.empty;
63+
lastu::Vector = (mpc.buffer.u .= mpc.lastu0 .+ mpc.estim.model.uop),
6264
Dhat ::Vector = repeat!(mpc.buffer.D̂, d, mpc.Hp),
6365
Rhaty::Vector = repeat!(mpc.buffer.Ŷ, ry, mpc.Hp),
6466
Rhatu::Vector = mpc.Uop,
@@ -69,8 +71,8 @@ function moveinput!(
6971
if mpc.estim.direct && !mpc.estim.corrected[]
7072
@warn "preparestate! should be called before moveinput! with current estimators"
7173
end
72-
validate_args(mpc, ry, d, D̂, R̂y, R̂u)
73-
initpred!(mpc, mpc.estim.model, d, D̂, R̂y, R̂u)
74+
validate_args(mpc, ry, d, lastu, D̂, R̂y, R̂u)
75+
initpred!(mpc, mpc.estim.model, d, lastu, D̂, R̂y, R̂u)
7476
linconstraint!(mpc, mpc.estim.model, mpc.transcription)
7577
linconstrainteq!(mpc, mpc.estim.model, mpc.transcription)
7678
= optim_objective!(mpc)
@@ -189,7 +191,7 @@ function addinfo!(info, mpc::PredictiveController)
189191
end
190192

191193
@doc raw"""
192-
initpred!(mpc::PredictiveController, model::LinModel, d, D̂, R̂y, R̂u) -> nothing
194+
initpred!(mpc::PredictiveController, model::LinModel, d, lastu, D̂, R̂y, R̂u) -> nothing
193195
194196
Init linear model prediction matrices `F, q̃, r` and current estimated output `ŷ`.
195197
@@ -208,8 +210,8 @@ They are computed with these equations using in-place operations:
208210
\end{aligned}
209211
```
210212
"""
211-
function initpred!(mpc::PredictiveController, model::LinModel, d, D̂, R̂y, R̂u)
212-
F = initpred_common!(mpc, model, d, D̂, R̂y, R̂u)
213+
function initpred!(mpc::PredictiveController, model::LinModel, d, lastu, D̂, R̂y, R̂u)
214+
F = initpred_common!(mpc, model, d, lastu, D̂, R̂y, R̂u)
213215
F .+= mpc.B # F = F + B
214216
mul!(F, mpc.K, mpc.estim.x̂0, 1, 1) # F = F + K*x̂0
215217
mul!(F, mpc.V, mpc.lastu0, 1, 1) # F = F + V*lastu0
@@ -241,24 +243,25 @@ function initpred!(mpc::PredictiveController, model::LinModel, d, D̂, R̂y, R̂
241243
end
242244

243245
@doc raw"""
244-
initpred!(mpc::PredictiveController, model::SimModel, d, D̂, R̂y, R̂u)
246+
initpred!(mpc::PredictiveController, model::SimModel, d, lastu, D̂, R̂y, R̂u)
245247
246-
Init `ŷ, F, d0, D̂0, D̂e, R̂y, R̂u` vectors when model is not a [`LinModel`](@ref).
248+
Init `lastu0, ŷ, F, d0, D̂0, D̂e, R̂y, R̂u` vectors when model is not a [`LinModel`](@ref).
247249
"""
248-
function initpred!(mpc::PredictiveController, model::SimModel, d, D̂, R̂y, R̂u)
249-
F = initpred_common!(mpc, model, d, D̂, R̂y, R̂u)
250+
function initpred!(mpc::PredictiveController, model::SimModel, d, lastu, D̂, R̂y, R̂u)
251+
F = initpred_common!(mpc, model, d, lastu, D̂, R̂y, R̂u)
250252
return nothing
251253
end
252254

253255
"""
254-
initpred_common!(mpc::PredictiveController, model::SimModel, d, D̂, R̂y, R̂u) -> mpc.F
256+
initpred_common!(mpc::PredictiveController, model::SimModel, d, lastu, D̂, R̂y, R̂u) -> F
255257
256258
Common computations of `initpred!` for all types of [`SimModel`](@ref).
257259
258260
Will also init `mpc.F` with 0 values, or with the stochastic predictions `Ŷs` if `mpc.estim`
259261
is an [`InternalModel`](@ref). The function returns `mpc.F`.
260262
"""
261-
function initpred_common!(mpc::PredictiveController, model::SimModel, d, D̂, R̂y, R̂u)
263+
function initpred_common!(mpc::PredictiveController, model::SimModel, d, lastu, D̂, R̂y, R̂u)
264+
mpc.lastu0 .= lastu .- model.uop
262265
mul!(mpc.Tu_lastu0, mpc.Tu, mpc.lastu0)
263266
mpc.ŷ .= evaloutput(mpc.estim, d)
264267
if model.nd > 0

test/3_test_predictive_control.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,12 @@ end
8181
preparestate!(mpc1, [10])
8282
u = moveinput!(mpc1, r)
8383
@test u [1] atol=1e-2
84-
u = mpc1(r)
84+
u = mpc1(r, lastu=[-1])
8585
@test u [1] atol=1e-2
8686
info = getinfo(mpc1)
8787
@test info[:u] u
8888
@test info[:Ŷ][end] r[1] atol=1e-2
89+
@test info[:ΔU] [2.0] atol=1e-2
8990
mpc2 = LinMPC(linmodel, Nwt=[0], Cwt=Inf, Hp=1000, Hc=1)
9091
preparestate!(mpc2, [10])
9192
u = moveinput!(mpc2, r)
@@ -515,11 +516,12 @@ end
515516
preparestate!(mpc1, y)
516517
u = moveinput!(mpc1, r)
517518
@test u [1] atol=1e-2
518-
u = mpc1(r)
519+
u = mpc1(r, lastu=[-1])
519520
@test u [1] atol=1e-2
520521
info = getinfo(mpc1)
521522
@test info[:u] u
522523
@test info[:Ŷ][end] r[1] atol=1e-2
524+
@test info[:ΔU] [2.0] atol=1e-2
523525
mpc2 = ExplicitMPC(model, Nwt=[0], Hp=1000, Hc=1)
524526
preparestate!(mpc2, y)
525527
u = moveinput!(mpc2, [5])
@@ -756,11 +758,12 @@ end
756758
preparestate!(nmpc_lin, [10])
757759
u = moveinput!(nmpc_lin, ry)
758760
@test u [1] atol=5e-2
759-
u = nmpc_lin(ry)
761+
u = nmpc_lin(ry, lastu=[-1])
760762
@test u [1] atol=5e-2
761763
info = getinfo(nmpc_lin)
762764
@test info[:u] u
763765
@test info[:Ŷ][end] ry[1] atol=5e-2
766+
@test info[:ΔU] [2.0] atol=5e-2
764767
setmodel!(nmpc_lin; Mwt=[0], Lwt=[1])
765768
u = moveinput!(nmpc_lin; R̂u=fill(ru[1], Hp))
766769
@test u [4] atol=5e-2

0 commit comments

Comments
 (0)