Skip to content

Commit ca7aafe

Browse files
committed
idem MHE
1 parent f9aeb7a commit ca7aafe

File tree

1 file changed

+71
-55
lines changed

1 file changed

+71
-55
lines changed

src/estimator/mhe/construct.jl

Lines changed: 71 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,63 +1003,11 @@ function init_optimization!(
10031003
JuMP.set_attribute(optim, "nlp_scaling_max_gradient", 10.0/C)
10041004
end
10051005
end
1006-
He = estim.He
1007-
nV̂, nX̂, ng = He*estim.nym, He*estim.nx̂, length(con.i_g)
1008-
nx̂, nŷ, nu = estim.nx̂, model.ny, model.nu
1009-
# see init_optimization!(mpc::NonLinMPC, optim) for details on the inspiration
1010-
Jfunc, gfunc = let estim=estim, model=model, nZ̃=nZ̃, nV̂=nV̂, nX̂=nX̂, ng=ng, nx̂=nx̂, nu=nu, nŷ=nŷ
1011-
Nc = nZ̃ + 3
1012-
last_Z̃tup_float, last_Z̃tup_dual = nothing, nothing
1013-
Z̃_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nZ̃), Nc)
1014-
V̂_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nV̂), Nc)
1015-
g_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, ng), Nc)
1016-
X̂_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nX̂), Nc)
1017-
x̄_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nx̂), Nc)
1018-
û_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nu), Nc)
1019-
ŷ_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nŷ), Nc)
1020-
function Jfunc(Z̃tup::T...)::T where {T <: Real}
1021-
Z̃1 = Z̃tup[begin]
1022-
if T == JNT
1023-
last_Z̃tup_float = Z̃tup
1024-
else
1025-
last_Z̃tup_dual = Z̃tup
1026-
end
1027-
Z̃, V̂ = get_tmp(Z̃_cache, Z̃1), get_tmp(V̂_cache, Z̃1)
1028-
= get_tmp(X̂_cache, Z̃1)
1029-
û, ŷ = get_tmp(û_cache, Z̃1), get_tmp(ŷ_cache, Z̃1)
1030-
Z̃ .= Z̃tup
1031-
V̂, X̂ = predict!(V̂, X̂, û, ŷ, estim, model, Z̃)
1032-
g = get_tmp(g_cache, Z̃1)
1033-
g = con_nonlinprog!(g, estim, model, X̂, V̂, Z̃)
1034-
= get_tmp(x̄_cache, Z̃1)
1035-
return obj_nonlinprog!(x̄, estim, model, V̂, Z̃)::T
1036-
end
1037-
function gfunc_i(i, Z̃tup::NTuple{N, T})::T where {N, T <:Real}
1038-
Z̃1 = Z̃tup[begin]
1039-
g = get_tmp(g_cache, Z̃1)
1040-
if T == JNT
1041-
isnewvalue = (Z̃tup !== last_Z̃tup_float)
1042-
isnewvalue && (last_Z̃tup_float = Z̃tup)
1043-
else
1044-
isnewvalue = (Z̃tup !== last_Z̃tup_dual)
1045-
isnewvalue && (last_Z̃tup_dual = Z̃tup)
1046-
end
1047-
if isnewvalue
1048-
Z̃, V̂ = get_tmp(Z̃_cache, Z̃1), get_tmp(V̂_cache, Z̃1)
1049-
= get_tmp(X̂_cache, Z̃1)
1050-
û, ŷ = get_tmp(û_cache, Z̃1), get_tmp(ŷ_cache, Z̃1)
1051-
Z̃ .= Z̃tup
1052-
V̂, X̂ = predict!(V̂, X̂, û, ŷ, estim, model, Z̃)
1053-
g = con_nonlinprog!(g, estim, model, X̂, V̂, Z̃)
1054-
end
1055-
return g[i]
1056-
end
1057-
gfunc = [(Z̃...) -> gfunc_i(i, Z̃) for i in 1:ng]
1058-
(Jfunc, gfunc)
1059-
end
1006+
Jfunc, gfunc = get_optim_functions(estim, optim)
10601007
register(optim, :Jfunc, nZ̃, Jfunc, autodiff=true)
10611008
@NLobjective(optim, Min, Jfunc(Z̃var...))
1062-
if ng 0
1009+
nV̂, nX̂ = estim.He*estim.nym, estim.He*estim.nx̂
1010+
if length(con.i_g) 0
10631011
for i in eachindex(con.X̂min)
10641012
sym = Symbol("g_X̂min_$i")
10651013
register(optim, sym, nZ̃, gfunc[i], autodiff=true)
@@ -1081,4 +1029,72 @@ function init_optimization!(
10811029
end
10821030
end
10831031
return nothing
1032+
end
1033+
1034+
1035+
"""
1036+
get_optim_functions(estim::MovingHorizonEstimator, ::JuMP.GenericModel) -> Jfunc, gfunc
1037+
1038+
Get the objective `Jfunc` and constraints `gfunc` functions for [`MovingHorizonEstimator`](@ref).
1039+
1040+
Inspired from: [User-defined operators with vector outputs](https://jump.dev/JuMP.jl/stable/tutorials/nonlinear/tips_and_tricks/#User-defined-operators-with-vector-outputs)
1041+
"""
1042+
function get_optim_functions(
1043+
estim::MovingHorizonEstimator, ::JuMP.GenericModel{JNT}
1044+
) where {JNT <: Real}
1045+
model, con = estim.model, estim.con
1046+
nx̂, nym, nŷ, nu, He = estim.nx̂, estim.nym, model.ny, model.nu, estim.He
1047+
nV̂, nX̂, ng, nZ̃ = He*nym, He*nx̂, length(con.i_g), length(estim.Z̃)
1048+
Nc = nZ̃ + 3
1049+
last_Z̃tup_float, last_Z̃tup_dual = nothing, nothing
1050+
Z̃_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nZ̃), Nc)
1051+
V̂_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nV̂), Nc)
1052+
g_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, ng), Nc)
1053+
X̂_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nX̂), Nc)
1054+
x̄_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nx̂), Nc)
1055+
û_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nu), Nc)
1056+
ŷ_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nŷ), Nc)
1057+
function Jfunc(Z̃tup::T...)::T where {T <: Real}
1058+
Z̃1 = Z̃tup[begin]
1059+
if T == JNT
1060+
last_Z̃tup_float = Z̃tup
1061+
else
1062+
last_Z̃tup_dual = Z̃tup
1063+
end
1064+
Z̃, V̂ = get_tmp(Z̃_cache, Z̃1), get_tmp(V̂_cache, Z̃1)
1065+
= get_tmp(X̂_cache, Z̃1)
1066+
û, ŷ = get_tmp(û_cache, Z̃1), get_tmp(ŷ_cache, Z̃1)
1067+
for i in eachindex(Z̃tup)
1068+
Z̃[i] = Z̃tup[i] # Z̃ .= Z̃tup seems to produce a type instability
1069+
end
1070+
V̂, X̂ = predict!(V̂, X̂, û, ŷ, estim, model, Z̃)
1071+
g = get_tmp(g_cache, Z̃1)
1072+
g = con_nonlinprog!(g, estim, model, X̂, V̂, Z̃)
1073+
= get_tmp(x̄_cache, Z̃1)
1074+
return obj_nonlinprog!(x̄, estim, model, V̂, Z̃)::T
1075+
end
1076+
function gfunc_i(i, Z̃tup::NTuple{N, T})::T where {N, T <:Real}
1077+
Z̃1 = Z̃tup[begin]
1078+
g = get_tmp(g_cache, Z̃1)
1079+
if T == JNT
1080+
isnewvalue = (Z̃tup !== last_Z̃tup_float)
1081+
isnewvalue && (last_Z̃tup_float = Z̃tup)
1082+
else
1083+
isnewvalue = (Z̃tup !== last_Z̃tup_dual)
1084+
isnewvalue && (last_Z̃tup_dual = Z̃tup)
1085+
end
1086+
if isnewvalue
1087+
Z̃, V̂ = get_tmp(Z̃_cache, Z̃1), get_tmp(V̂_cache, Z̃1)
1088+
= get_tmp(X̂_cache, Z̃1)
1089+
û, ŷ = get_tmp(û_cache, Z̃1), get_tmp(ŷ_cache, Z̃1)
1090+
for i in eachindex(Z̃tup)
1091+
Z̃[i] = Z̃tup[i] # Z̃ .= Z̃tup seems to produce a type instability
1092+
end
1093+
V̂, X̂ = predict!(V̂, X̂, û, ŷ, estim, model, Z̃)
1094+
g = con_nonlinprog!(g, estim, model, X̂, V̂, Z̃)
1095+
end
1096+
return g[i]
1097+
end
1098+
gfunc = [(Z̃...) -> gfunc_i(i, Z̃) for i in 1:ng]
1099+
return Jfunc, gfunc
10841100
end

0 commit comments

Comments
 (0)