Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
83e646b
wip: support FOH in `RungeKutta(4)`
franckgaga Oct 22, 2026
b734225
wip: idem
franckgaga Oct 24, 2026
89855fc
wip: idem
franckgaga Oct 25, 2026
2739d02
added: `h` argument to `ShootingMethod`s
franckgaga Oct 25, 2026
9ec2cd4
doc: `LinModel` detail in `updatestate!`
franckgaga Oct 25, 2026
612d270
Merge branch 'main' into foh_updatestate_modelonly
franckgaga Oct 28, 2026
43f948f
changed: left limit in `updatestate!` doc
franckgaga Oct 26, 2026
300dfae
removed: useless parameter in methods
franckgaga Oct 27, 2026
075dfdb
doc: minor change
franckgaga Oct 28, 2026
465cce1
doc: `StateEstimator` does not support `unext` and `dnext`
franckgaga Oct 28, 2026
e4ee6f4
doc: minor correction
franckgaga Oct 28, 2026
eca7e54
added: temp fix
franckgaga Oct 28, 2026
870c601
removed: `unext` and `dnext` arg to `updatestate!(::PredictiveControl…
franckgaga Oct 28, 2026
df83f24
wip: new `f̂!` supporting only ZOH
franckgaga Oct 28, 2026
b4f0722
debug: UKF with new `f̂!` signature
franckgaga Oct 28, 2026
0e787f8
doc: math notation in `updatestate!`
franckgaga Oct 28, 2026
06b7e83
added: `NonLinMPC` and `SingleShooting` support `h=1`
franckgaga Oct 28, 2026
b259c87
changed: re-implementing `f̂!` with FOH support
franckgaga Oct 28, 2026
93337be
changed: idem
franckgaga Oct 28, 2026
cc130a1
changed: idem
franckgaga Oct 28, 2026
daff46a
added: comment about `û0next` and `û0` aliasing
franckgaga Oct 28, 2026
cbd103f
changed: avoid aliasing and apply `transcription.h`
franckgaga Oct 28, 2026
de15ac3
doc: `h` only applies to internal predictions in `SingleShooting`
franckgaga Oct 28, 2026
506782c
doc: idem
franckgaga Oct 28, 2026
b60ee5c
changed: new `f̂!` signature in `ExtendedKalmanFilter`
franckgaga Oct 28, 2026
a030b07
debug: correct signature for `h!`
franckgaga Oct 28, 2026
10d9f5e
changed: new `f!` signature for `InternalModel`
franckgaga Oct 28, 2026
93d2651
changed: new `f!` signature for linearization
franckgaga Oct 28, 2026
4886eb0
changed: idem
franckgaga Oct 29, 2026
8775e21
added: `MovingHorizonEstimator` with `SingleShooting` support `h=1`
franckgaga Oct 31, 2026
dfb1e14
removed: useless comment
franckgaga Oct 31, 2026
3ee8533
test: update `SimModel` tests
franckgaga Oct 31, 2026
9ee3510
debug: `ExtendedKalmanFilter` argument order in Jacobian
franckgaga Oct 31, 2026
a746642
changed: using buffers for D horizons
franckgaga Oct 31, 2026
6a4c0cf
debug: MHE measured dist. exception for `k+1`
franckgaga Oct 31, 2026
7792ec9
test: looser tolerance for MHE vs KF
franckgaga Oct 31, 2026
2a2f275
test: revert tolerances and remove the effect of `d`
franckgaga Oct 31, 2026
98ad8e0
doc: `FOH` meas. disturbance in pH neutralization example
franckgaga Oct 31, 2026
d66fd0a
test: debug test
franckgaga Nov 1, 2026
179ce6a
doc: minor correction
franckgaga Nov 1, 2026
abacf34
test: call `updatestate!` with `unext` kwarg
franckgaga Nov 1, 2026
cc0835a
test: new `SingleShooting(1)` and `MultipleShooting(1)` tests
franckgaga Nov 1, 2026
da34cdb
debug: do not use `buffer.x̂` in `getinfo(mhe)`
franckgaga Nov 2, 2026
db678f4
test: debug variable name clash
franckgaga Nov 2, 2026
6cf8ab2
debug: do not use `buffer.x` in `getinfo(model)`
franckgaga Nov 2, 2026
4979478
test: avoid clashes on `Ts` variable name
franckgaga Nov 2, 2026
917db63
bench: `updatestate!` on the pendulum
franckgaga Nov 2, 2026
698e31d
bench: cleanup
franckgaga Nov 2, 2026
e0d56aa
bench: cleanup 2
franckgaga Nov 2, 2026
287433f
added: special path for ZOH in `RungeKutta`
franckgaga Nov 2, 2026
112ceff
added: remove `Ûi` allocation in `NonLinMPC`
franckgaga Nov 3, 2026
546a984
added: remove `Ûi` allocation in `MovingHorizonEstimator`
franckgaga Nov 3, 2026
3594ae8
debug: forgotten `Ûi` cache
franckgaga Nov 3, 2026
a926be1
debug: idem
franckgaga Nov 3, 2026
6966f88
debug: idem
franckgaga Nov 3, 2026
710a6e3
debug: `InternalModel` with `SingleShooting` now work
franckgaga Nov 3, 2026
2ce9c89
debug: rename eq. const. to `con_nonlinroots!` in `NonLinModelDAE`
franckgaga Nov 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion benchmark/1_bench_sim_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,9 @@ UNIT_MODEL["NonLinModel"]["linearize!"] =
## ----------------- CASE STUDIES ---------------------------------------------------------
## ----------------------------------------------------------------------------------------
const CASE_MODEL = SUITE["SimModel"]["CASE STUDIES"]
# TODO: Add case study benchmarks for SimModel

u_pendulum = [0.5]
CASE_MODEL["NonLinModel"]["pendulum"]["updatestate!"] =
@benchmarkable(
updatestate!($pendulum_model, $u_pendulum);
)
25 changes: 16 additions & 9 deletions docs/src/manual/nonlinmpc2.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ function simDAE(plant, N; x_0)
Y_data, U_data, D_data, X_data = zeros(ny, N), zeros(nu, N), zeros(nd, N), zeros(nx, N)
c_Ain_0 = plant.p[1]
setstate!(plant, x_0)
x = x_0
x, d = x_0, [10.0]
for i=1:N
u = i ≤ (1N÷4) ? [10.0] : [11.0]
d = i ≤ (2N÷4) ? [10.0] : [12.0]
Expand All @@ -226,7 +226,9 @@ function simDAE(plant, N; x_0)
U_data[:, i] = u
D_data[:, i] = d
X_data[:, i] = x
x = updatestate!(plant, u, d)
dnext = i+1 ≤ (2N÷4) ? [10.0] : [12.0]
x = updatestate!(plant, u, d; dnext)
d = dnext
end
plant.p[1] = c_Ain_0
return SimResult(plant, U_data, Y_data, D_data; X_data)
Expand All @@ -236,7 +238,10 @@ N = 81
res = simDAE(plant, N; x_0)
```

We can now plot the result:
Providing a `dnext` keyword argument to [`updatestate!`](@ref) allows discretizing the
measured disturbances with first-order hold (FOH), instead of zero-order hold, which is
consistent with the method applied by the [`MovingHorizonEstimator`](@ref). We can now plot
the result:

```@example 1
using Plots
Expand Down Expand Up @@ -324,10 +329,9 @@ function simMHE(mhe, plant, N; x_0, x̂_0)
c_Ain_0 = plant.p[1]
setstate!(plant, x_0); setstate!(mhe, x̂_0)
initstate!(mhe, [10], [7], [10])
x = x_0
x, d = x_0, [10.0]
for i=1:N
u = i ≤ (1N÷4) ? [10.0] : [11.0]
d = i ≤ (2N÷4) ? [10.0] : [12.0]
c_Ain = i ≤ (3N÷4) ? c_Ain_0 : (c_Ain_0 - 0.01)
plant.p[1] = c_Ain
y = evaloutput(plant, d)
Expand All @@ -342,8 +346,10 @@ function simMHE(mhe, plant, N; x_0, x̂_0)
X_data[3, i] = c_Ain
Ŷ_data[:, i] = ŷ
X̂_data[:, i] = x̂
x = updatestate!(plant, u, d)
dnext = i+1 ≤ (2N÷4) ? [10.0] : [12.0]
x = updatestate!(plant, u, d; dnext)
x̂ = updatestate!(mhe, u, ym, dm)
d = dnext
end
plant.p[1] = c_Ain_0
return SimResult(mhe, U_data, Y_data, D_data; plant, X_data, X̂_data, Ŷ_data)
Expand Down Expand Up @@ -399,9 +405,8 @@ function simNMPC(nmpc, plant, N, ry; x_0, x̂_0, noise=false)
c_Ain_0 = plant.p[1]
setstate!(plant, x_0); setstate!(nmpc, x̂_0)
initstate!(nmpc, [10], [7], [10])
x = x_0
x, d = x_0, [10.0]
for i=1:N
d = i ≤ (1N÷3) ? [10.0] : [12.0]
c_Ain = i ≤ (2N÷3) ? c_Ain_0 : (c_Ain_0 + 0.01)
plant.p[1] = c_Ain
y = evaloutput(plant, d)
Expand All @@ -418,8 +423,10 @@ function simNMPC(nmpc, plant, N, ry; x_0, x̂_0, noise=false)
X_data[3, i] = c_Ain
Ŷ_data[:, i] = ŷ
X̂_data[:, i] = x̂
x = updatestate!(plant, u, d)
dnext = i+1 ≤ (1N÷3) ? [10.0] : [12.0]
x = updatestate!(plant, u, d; dnext)
x̂ = updatestate!(nmpc, u, ym, dm)
d = dnext
end
plant.p[1] = c_Ain_0
return SimResult(nmpc, U_data, Y_data, D_data; plant, X_data, X̂_data, Ŷ_data, Ry_data)
Expand Down
5 changes: 3 additions & 2 deletions src/controller/execute.jl
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,12 @@ function getinfo(mpc::PredictiveController{NT}) where NT<:Real
Ue, Ŷe = Vector{NT}(undef, nUe), Vector{NT}(undef, nŶe)
U0, Ŷ0 = similar(mpc.Uop), similar(mpc.Yop)
Û0, X̂0 = Vector{NT}(undef, nÛ0), Vector{NT}(undef, nX̂0)
Ûi = Vector{NT}(undef, nÛ0)
U, Ŷ = buffer.U, buffer.Ŷ
D̂ = buffer.D̂
U0 = getU0!(U0, mpc, Z̃)
ΔŨ = getΔŨ!(ΔŨ, mpc, transcription, Z̃)
Ŷ0, x̂0end = predict!(Ŷ0, x̂0end, X̂0, Û0, K, mpc, model, transcription, U0, Z̃)
Ŷ0, x̂0end = predict!(Ŷ0, x̂0end, X̂0, Û0, Ûi, K, mpc, model, transcription, U0, Z̃)
Ue, Ŷe = extended_vectors!(Ue, Ŷe, mpc, U0, Ŷ0)
U .= U0 .+ mpc.Uop
Ŷ .= Ŷ0 .+ mpc.Yop
Expand Down Expand Up @@ -464,7 +465,7 @@ If first warm-starts the solver with [`set_warmstart!`](@ref). It then calls
`@error` log in the REPL and returns the warm-start value. A failed optimization also prints
[`getinfo`](@ref) results in the debug log [if activated](https://docs.julialang.org/en/v1/stdlib/Logging/#Example:-Enable-debug-level-messages).
"""
function optim_objective!(mpc::PredictiveController{NT}) where {NT<:Real}
function optim_objective!(mpc::PredictiveController)
model, optim = mpc.estim.model, mpc.optim
Z̃var::Vector{JuMP.VariableRef} = optim[:Z̃var]
Z̃s = set_warmstart!(mpc, mpc.transcription, Z̃var)
Expand Down
2 changes: 1 addition & 1 deletion src/controller/explicitmpc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ optim_objective!(mpc::ExplicitMPC) = lmul!(-1, ldiv!(mpc.Z̃, mpc.H̃_chol, mpc.

"Compute the predictions but not the terminal states if `mpc` is an [`ExplicitMPC`](@ref)."
function predict!(
Ŷ0, x̂0end, _ , _ , _ , mpc::ExplicitMPC, ::LinModel, ::TranscriptionMethod, _ , Z̃
Ŷ0, x̂0end, _ , _ , _ , _ , mpc::ExplicitMPC, ::LinModel, ::TranscriptionMethod, _ , Z̃
)
# in-place operations to reduce allocations :
Ŷ0 .= mul!(Ŷ0, mpc.Ẽ, Z̃) .+ mpc.F
Expand Down
77 changes: 43 additions & 34 deletions src/controller/nonlinmpc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -606,15 +606,16 @@ function addinfo!(info, mpc::NonLinMPC{NT}) where NT<:Real
Ue, Ŷe = zeros(NT, nUe), zeros(NT, nŶe)
U0, Ŷ0 = zeros(NT, nU), zeros(NT, nŶ)
Û0, X̂0 = zeros(NT, nU), zeros(NT, nX̂)
Ûi = zeros(NT, nU)
gc, g = zeros(NT, nc), zeros(NT, ng)
gi, geq = zeros(NT, ngi), zeros(NT, neq)
J_cache = (
Cache(ΔŨ), Cache(x̂0end), Cache(Ue), Cache(Ŷe), Cache(U0), Cache(Ŷ0),
Cache(Û0), Cache(K), Cache(X̂0),
Cache(Û0), Cache(Ûi), Cache(K), Cache(X̂0),
Cache(gc), Cache(g), Cache(geq),
)
function J!(Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K, X̂0, gc, g, geq)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K, X̂0, gc, g, geq, mpc, Z̃)
function J!(Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, g, geq)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, g, geq, mpc, Z̃)
return obj_nonlinprog!(Ŷ0, U0, mpc, Ue, Ŷe, ΔŨ)
end
if !isnothing(hess)
Expand All @@ -629,11 +630,11 @@ function addinfo!(info, mpc::NonLinMPC{NT}) where NT<:Real
# --- inequality constraint derivatives ---
∇g_cache = (
Cache(ΔŨ), Cache(x̂0end), Cache(Ue), Cache(Ŷe), Cache(U0), Cache(Ŷ0),
Cache(Û0), Cache(K), Cache(X̂0),
Cache(Û0), Cache(Ûi), Cache(K), Cache(X̂0),
Cache(gc), Cache(geq), Cache(g)
)
function gi!(gi, Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K, X̂0, gc, geq, g)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K, X̂0, gc, g, geq, mpc, Z̃)
function gi!(gi, Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K, X̂0, gc, geq, g)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K, X̂0, gc, g, geq, mpc, Z̃)
gi .= @views g[i_g]
return nothing
end
Expand All @@ -657,11 +658,13 @@ function addinfo!(info, mpc::NonLinMPC{NT}) where NT<:Real
end
∇²g_cache = (
Cache(ΔŨ), Cache(x̂0end), Cache(Ue), Cache(Ŷe), Cache(U0), Cache(Ŷ0),
Cache(Û0), Cache(K), Cache(X̂0),
Cache(Û0), Cache(Ûi), Cache(K), Cache(X̂0),
Cache(gc), Cache(geq), Cache(g), Cache(gi)
)
function ℓ_gi(Z̃, λi, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K, X̂0, gc, geq, g, gi)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K, X̂0, gc, g, geq, mpc, Z̃)
function ℓ_gi(Z̃, λi, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, geq, g, gi)
update_predictions!(
ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, g, geq, mpc, Z̃
)
gi .= @views g[i_g]
return dot(λi, gi)
end
Expand All @@ -674,11 +677,13 @@ function addinfo!(info, mpc::NonLinMPC{NT}) where NT<:Real
# --- equality constraint derivatives ---
geq_cache = (
Cache(ΔŨ), Cache(x̂0end), Cache(Ue), Cache(Ŷe), Cache(U0), Cache(Ŷ0),
Cache(Û0), Cache(K), Cache(X̂0),
Cache(Û0), Cache(Ûi), Cache(K), Cache(X̂0),
Cache(gc), Cache(g)
)
function geq!(geq, Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K, X̂0, gc, g)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K, X̂0, gc, g, geq, mpc, Z̃)
function geq!(geq, Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, g)
update_predictions!(
ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, g, geq, mpc, Z̃
)
return nothing
end
∇geq_prep = prepare_jacobian(geq!, geq, mpc.jacobian, mpc.Z̃, geq_cache...)
Expand All @@ -701,11 +706,13 @@ function addinfo!(info, mpc::NonLinMPC{NT}) where NT<:Real
end
∇²geq_cache = (
Cache(ΔŨ), Cache(x̂0end), Cache(Ue), Cache(Ŷe), Cache(U0), Cache(Ŷ0),
Cache(Û0), Cache(K), Cache(X̂0),
Cache(Û0), Cache(Ûi), Cache(K), Cache(X̂0),
Cache(gc), Cache(geq), Cache(g)
)
function ℓ_geq(Z̃, λeq, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K, X̂0, gc, geq, g)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K, X̂0, gc, g, geq, mpc, Z̃)
function ℓ_geq(Z̃, λeq, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, geq, g)
update_predictions!(
ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, g, geq, mpc, Z̃
)
return dot(λeq, geq)
end
∇²ℓgeq_prep = prepare_hessian(ℓ_geq, hess, mpc.Z̃, Constant(λeq), ∇²geq_cache...)
Expand Down Expand Up @@ -846,16 +853,17 @@ function get_nonlinobj_op(mpc::NonLinMPC, optim::JuMP.GenericModel{JNT}) where J
Ue::Vector{JNT}, Ŷe::Vector{JNT} = zeros(JNT, nUe), zeros(JNT, nŶe)
U0::Vector{JNT}, Ŷ0::Vector{JNT} = zeros(JNT, nU), zeros(JNT, nŶ)
Û0::Vector{JNT}, X̂0::Vector{JNT} = zeros(JNT, nU), zeros(JNT, nX̂)
Ûi::Vector{JNT} = zeros(JNT, nU)
gc::Vector{JNT}, g::Vector{JNT} = zeros(JNT, nc), zeros(JNT, ng)
geq::Vector{JNT} = zeros(JNT, neq)
function J!(Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K̄, X̂0, gc, g, geq)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K̄, X̂0, gc, g, geq, mpc, Z̃)
function J!(Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, g, geq)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, g, geq, mpc, Z̃)
return obj_nonlinprog!(Ŷ0, U0, mpc, Ue, Ŷe, ΔŨ)
end
Z̃_J = zeros(JNT, nZ̃)
J_cache = (
Cache(ΔŨ), Cache(x̂0end), Cache(Ue), Cache(Ŷe), Cache(U0), Cache(Ŷ0),
Cache(Û0), Cache(K̄), Cache(X̂0),
Cache(Û0), Cache(Ûi), Cache(K̄), Cache(X̂0),
Cache(gc), Cache(g), Cache(geq),
)
∇J_prep = prepare_gradient(J!, grad, Z̃_J, J_cache...; strict)
Expand Down Expand Up @@ -974,24 +982,25 @@ function get_nonlincon_oracle(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JN
Ue::Vector{JNT}, Ŷe::Vector{JNT} = zeros(JNT, nUe), zeros(JNT, nŶe)
U0::Vector{JNT}, Ŷ0::Vector{JNT} = zeros(JNT, nU), zeros(JNT, nŶ)
Û0::Vector{JNT}, X̂0::Vector{JNT} = zeros(JNT, nU), zeros(JNT, nX̂)
Ûi::Vector{JNT} = zeros(JNT, nU)
gc::Vector{JNT}, g::Vector{JNT} = zeros(JNT, nc), zeros(JNT, ng)
gi::Vector{JNT}, geq::Vector{JNT} = zeros(JNT, ngi), zeros(JNT, neq)
λi::Vector{JNT}, λeq::Vector{JNT} = rand(JNT, ngi), rand(JNT, neq)
# -------------- inequality constraint: nonlinear oracle -----------------------------
function gi!(gi, Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K̄, X̂0, gc, geq, g)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K̄, X̂0, gc, g, geq, mpc, Z̃)
function gi!(gi, Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, geq, g)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, g, geq, mpc, Z̃)
gi .= @views g[i_g]
return nothing
end
function ℓ_gi(Z̃, λi, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K̄, X̂0, gc, geq, g, gi)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K̄, X̂0, gc, g, geq, mpc, Z̃)
function ℓ_gi(Z̃, λi, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, geq, g, gi)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, g, geq, mpc, Z̃)
gi .= @views g[i_g]
return dot(λi, gi)
end
Z̃_∇gi = zeros(JNT, nZ̃)
∇gi_cache = (
Cache(ΔŨ), Cache(x̂0end), Cache(Ue), Cache(Ŷe), Cache(U0), Cache(Ŷ0),
Cache(Û0), Cache(K̄), Cache(X̂0),
Cache(Û0), Cache(Ûi), Cache(K̄), Cache(X̂0),
Cache(gc), Cache(geq), Cache(g)
)
∇gi_prep = prepare_jacobian(gi!, gi, jac, Z̃_∇gi, ∇gi_cache...; strict)
Expand All @@ -1000,7 +1009,7 @@ function get_nonlincon_oracle(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JN
if !isnothing(hess)
∇²gi_cache = (
Cache(ΔŨ), Cache(x̂0end), Cache(Ue), Cache(Ŷe), Cache(U0), Cache(Ŷ0),
Cache(Û0), Cache(K̄), Cache(X̂0),
Cache(Û0), Cache(Ûi), Cache(K̄), Cache(X̂0),
Cache(gc), Cache(geq), Cache(g), Cache(gi)
)
∇²gi_prep = prepare_hessian(
Expand Down Expand Up @@ -1044,18 +1053,18 @@ function get_nonlincon_oracle(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JN
eval_hessian_lagrangian = isnothing(hess) ? nothing : ∇²gi_func!
)
# ------------- equality constraints : nonlinear oracle ------------------------------
function geq!(geq, Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K̄, X̂0, gc, g)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K̄, X̂0, gc, g, geq, mpc, Z̃)
function geq!(geq, Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, g)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, g, geq, mpc, Z̃)
return nothing
end
function ℓ_geq(Z̃, λeq, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K̄, X̂0, gc, geq, g)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K̄, X̂0, gc, g, geq, mpc, Z̃)
function ℓ_geq(Z̃, λeq, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, geq, g)
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, g, geq, mpc, Z̃)
return dot(λeq, geq)
end
Z̃_∇geq = zeros(JNT, nZ̃)
∇geq_cache = (
Cache(ΔŨ), Cache(x̂0end), Cache(Ue), Cache(Ŷe), Cache(U0), Cache(Ŷ0),
Cache(Û0), Cache(K̄), Cache(X̂0),
Cache(Û0), Cache(Ûi), Cache(K̄), Cache(X̂0),
Cache(gc), Cache(g)
)
∇geq_prep = prepare_jacobian(geq!, geq, jac, Z̃_∇geq, ∇geq_cache...; strict)
Expand All @@ -1064,7 +1073,7 @@ function get_nonlincon_oracle(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JN
if !isnothing(hess)
∇²geq_cache = (
Cache(ΔŨ), Cache(x̂0end), Cache(Ue), Cache(Ŷe), Cache(U0), Cache(Ŷ0),
Cache(Û0), Cache(K̄), Cache(X̂0),
Cache(Û0), Cache(Ûi), Cache(K̄), Cache(X̂0),
Cache(gc), Cache(geq), Cache(g)
)
∇²geq_prep = prepare_hessian(
Expand Down Expand Up @@ -1119,7 +1128,7 @@ end

"""
update_predictions!(
ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K̄, X̂0, gc, g, geq,
ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, g, geq,
mpc::PredictiveController, Z̃
) -> nothing

Expand All @@ -1128,18 +1137,18 @@ Update in-place all vectors for the predictions of `mpc` controller at decision
The method mutates all the arguments before the `mpc` argument.
"""
function update_predictions!(
ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K̄, X̂0, gc, g, geq,
ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, Ûi, K̄, X̂0, gc, g, geq,
mpc::PredictiveController, Z̃
)
model, transcription = mpc.estim.model, mpc.transcription
U0 = getU0!(U0, mpc, Z̃)
ΔŨ = getΔŨ!(ΔŨ, mpc, transcription, Z̃)
Ŷ0, x̂0end = predict!(Ŷ0, x̂0end, X̂0, Û0, K̄, mpc, model, transcription, U0, Z̃)
Ŷ0, x̂0end = predict!(Ŷ0, x̂0end, X̂0, Û0, Ûi, K̄, mpc, model, transcription, U0, Z̃)
Ue, Ŷe = extended_vectors!(Ue, Ŷe, mpc, U0, Ŷ0)
ϵ = getslack(mpc, Z̃)
gc = con_custom!(gc, mpc, Ue, Ŷe, ϵ)
g = con_nonlinprog!(g, mpc, model, transcription, x̂0end, Ŷ0, gc, ϵ)
geq = con_nonlinprogeq!(geq, X̂0, Û0, K̄, mpc, model, transcription, U0, Z̃)
geq = con_nonlinprogeq!(geq, X̂0, Û0, Ûi, K̄, mpc, model, transcription, U0, Z̃)
return nothing
end

Expand Down
Loading
Loading