Skip to content

Commit 5ff0fe4

Browse files
committed
changed: MHE without collect on decision var.
1 parent bb07f7f commit 5ff0fe4

File tree

5 files changed

+43
-65
lines changed

5 files changed

+43
-65
lines changed

src/controller/nonlinmpc.jl

+10-14
Original file line numberDiff line numberDiff line change
@@ -314,24 +314,20 @@ function init_optimization!(mpc::NonLinMPC, optim::JuMP.GenericModel{JNT}) where
314314
û_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nu), Nc)
315315
Ȳ_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nŶ), Nc)
316316
Ū_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nU), Nc)
317-
function Jfunc(ΔŨtup::T...)::T where T <: Real
317+
function Jfunc(ΔŨtup::T...)::T where {T <: Real}
318318
ΔŨ1 = ΔŨtup[begin]
319-
ΔŨ, Ŷ = get_tmp(ΔŨ_cache, ΔŨ1), get_tmp(Ŷ_cache, ΔŨ1)
320319
if T == JNT
321-
isnewvalue = (ΔŨtup !== last_ΔŨtup_float)
322-
isnewvalue && (last_ΔŨtup_float = ΔŨtup)
320+
last_ΔŨtup_float = ΔŨtup
323321
else
324-
isnewvalue = (ΔŨtup !== last_ΔŨtup_dual)
325-
isnewvalue && (last_ΔŨtup_dual = ΔŨtup)
326-
end
327-
if isnewvalue
328-
x̂, x̂next = get_tmp(x̂_cache, ΔŨ1), get_tmp(x̂next_cache, ΔŨ1)
329-
u, û = get_tmp(u_cache, ΔŨ1), get_tmp(û_cache, ΔŨ1)
330-
ΔŨ .= ΔŨtup
331-
Ŷ, x̂end = predict!(Ŷ, x̂, x̂next, u, û, mpc, model, ΔŨ)
332-
g = get_tmp(g_cache, ΔŨ1)
333-
g = con_nonlinprog!(g, mpc, model, x̂end, Ŷ, ΔŨ)
322+
last_ΔŨtup_dual = ΔŨtup
334323
end
324+
ΔŨ, Ŷ = get_tmp(ΔŨ_cache, ΔŨ1), get_tmp(Ŷ_cache, ΔŨ1)
325+
x̂, x̂next = get_tmp(x̂_cache, ΔŨ1), get_tmp(x̂next_cache, ΔŨ1)
326+
u, û = get_tmp(u_cache, ΔŨ1), get_tmp(û_cache, ΔŨ1)
327+
ΔŨ .= ΔŨtup
328+
Ŷ, x̂end = predict!(Ŷ, x̂, x̂next, u, û, mpc, model, ΔŨ)
329+
g = get_tmp(g_cache, ΔŨ1)
330+
g = con_nonlinprog!(g, mpc, model, x̂end, Ŷ, ΔŨ)
335331
U, Ȳ, Ū = get_tmp(U_cache, ΔŨ1), get_tmp(Ȳ_cache, ΔŨ1), get_tmp(Ū_cache, ΔŨ1)
336332
return obj_nonlinprog!(U, Ȳ, Ū, mpc, model, Ŷ, ΔŨ)::T
337333
end

src/estimator/mhe/construct.jl

+23-43
Original file line numberDiff line numberDiff line change
@@ -1008,72 +1008,52 @@ function init_optimization!(
10081008
Jfunc, gfunc = let estim=estim, model=model, nZ̃=nZ̃, nV̂=nV̂, nX̂=nX̂, ng=ng, nx̂=nx̂, nu=nu, nŷ=nŷ
10091009
Nc = nZ̃ + 3
10101010
last_Z̃tup_float, last_Z̃tup_dual = nothing, nothing
1011+
Z̃_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nZ̃), Nc)
10111012
V̂_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nV̂), Nc)
10121013
g_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, ng), Nc)
10131014
X̂_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nX̂), Nc)
10141015
x̄_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nx̂), Nc)
10151016
û_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nu), Nc)
10161017
ŷ_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nŷ), Nc)
1017-
function Jfunc(Z̃tup::JNT...)
1018+
function Jfunc(Z̃tup::T...)::T where {T <: Real}
10181019
Z̃1 = Z̃tup[begin]
1019-
= get_tmp(V̂_cache, Z̃1)
1020-
= collect(Z̃tup)
1021-
if Z̃tup !== last_Z̃tup_float
1022-
g = get_tmp(g_cache, Z̃1)
1023-
= get_tmp(X̂_cache, Z̃1)
1024-
û, ŷ = get_tmp(û_cache, Z̃1), get_tmp(ŷ_cache, Z̃1)
1025-
V̂, X̂ = predict!(V̂, X̂, û, ŷ, estim, model, Z̃)
1026-
g = con_nonlinprog!(g, estim, model, X̂, V̂, Z̃)
1020+
if T == JNT
10271021
last_Z̃tup_float = Z̃tup
1028-
end
1029-
= get_tmp(x̄_cache, Z̃1)
1030-
return obj_nonlinprog!(x̄, estim, model, V̂, Z̃)
1031-
end
1032-
function Jfunc(Z̃tup::ForwardDiff.Dual...)
1033-
Z̃1 = Z̃tup[begin]
1034-
= get_tmp(V̂_cache, Z̃1)
1035-
= collect(Z̃tup)
1036-
if Z̃tup !== last_Z̃tup_dual
1037-
g = get_tmp(g_cache, Z̃1)
1038-
= get_tmp(X̂_cache, Z̃1)
1039-
û, ŷ = get_tmp(û_cache, Z̃1), get_tmp(ŷ_cache, Z̃1)
1040-
V̂, X̂ = predict!(V̂, X̂, û, ŷ, estim, model, Z̃)
1041-
g = con_nonlinprog!(g, estim, model, X̂, V̂, Z̃)
1022+
else
10421023
last_Z̃tup_dual = Z̃tup
10431024
end
1025+
Z̃, V̂ = get_tmp(Z̃_cache, Z̃1), get_tmp(V̂_cache, Z̃1)
1026+
= get_tmp(X̂_cache, Z̃1)
1027+
û, ŷ = get_tmp(û_cache, Z̃1), get_tmp(ŷ_cache, Z̃1)
1028+
Z̃ .= Z̃tup
1029+
V̂, X̂ = predict!(V̂, X̂, û, ŷ, estim, model, Z̃)
1030+
g = get_tmp(g_cache, Z̃1)
1031+
g = con_nonlinprog!(g, estim, model, X̂, V̂, Z̃)
10441032
= get_tmp(x̄_cache, Z̃1)
1045-
return obj_nonlinprog!(x̄, estim, model, V̂, Z̃)
1033+
return obj_nonlinprog!(x̄, estim, model, V̂, Z̃)::T
10461034
end
1047-
function gfunc_i(i, Z̃tup::NTuple{N, JNT}) where N
1035+
function gfunc_i(i, Z̃tup::NTuple{N, T})::T where {N, T <:Real}
10481036
Z̃1 = Z̃tup[begin]
10491037
g = get_tmp(g_cache, Z̃1)
1050-
if Z̃tup !== last_Z̃tup_float
1051-
= collect(Z̃tup)
1052-
= get_tmp(V̂_cache, Z̃1)
1053-
= get_tmp(X̂_cache, Z̃1)
1054-
û, ŷ = get_tmp(û_cache, Z̃1), get_tmp(ŷ_cache, Z̃1)
1055-
V̂, X̂ = predict!(V̂, X̂, û, ŷ, estim, model, Z̃)
1056-
g = con_nonlinprog!(g, estim, model, X̂, V̂, Z̃)
1057-
last_Z̃tup_float = Z̃tup
1038+
if T == JNT
1039+
isnewvalue = (Z̃tup !== last_Z̃tup_float)
1040+
isnewvalue && (last_Z̃tup_float = Z̃tup)
1041+
else
1042+
isnewvalue = (Z̃tup !== last_Z̃tup_dual)
1043+
isnewvalue && (last_Z̃tup_dual = Z̃tup)
10581044
end
1059-
return g[i]
1060-
end
1061-
function gfunc_i(i, Z̃tup::NTuple{N, ForwardDiff.Dual}) where N
1062-
Z̃1 = Z̃tup[begin]
1063-
g = get_tmp(g_cache, Z̃1)
1064-
if Z̃tup !== last_Z̃tup_dual
1065-
= collect(Z̃tup)
1066-
= get_tmp(V̂_cache, Z̃1)
1045+
if isnewvalue
1046+
Z̃, V̂ = get_tmp(Z̃_cache, Z̃1), get_tmp(V̂_cache, Z̃1)
10671047
= get_tmp(X̂_cache, Z̃1)
10681048
û, ŷ = get_tmp(û_cache, Z̃1), get_tmp(ŷ_cache, Z̃1)
1049+
Z̃ .= Z̃tup
10691050
V̂, X̂ = predict!(V̂, X̂, û, ŷ, estim, model, Z̃)
10701051
g = con_nonlinprog!(g, estim, model, X̂, V̂, Z̃)
1071-
last_Z̃tup_dual = Z̃tup
10721052
end
10731053
return g[i]
10741054
end
10751055
gfunc = [(Z̃...) -> gfunc_i(i, Z̃) for i in 1:ng]
1076-
Jfunc, gfunc
1056+
(Jfunc, gfunc)
10771057
end
10781058
register(optim, :Jfunc, nZ̃, Jfunc, autodiff=true)
10791059
@NLobjective(optim, Min, Jfunc(Z̃var...))

src/general.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ const DEFAULT_CWT = 1e5
77
const DEFAULT_EWT = 0.0
88

99
"Termination status that means 'no solution available'."
10-
const ERROR_STATUSES = [
10+
const ERROR_STATUSES = (
1111
INFEASIBLE, DUAL_INFEASIBLE, LOCALLY_INFEASIBLE, INFEASIBLE_OR_UNBOUNDED,
1212
NUMERICAL_ERROR, INVALID_MODEL, INVALID_OPTION, INTERRUPTED,
1313
OTHER_ERROR
14-
]
14+
)
1515

1616
"Verify that `optim` termination status is `OPTIMAL` or `LOCALLY_SOLVED`."
1717
function issolved(optim::JuMP.GenericModel)
@@ -22,7 +22,7 @@ end
2222
"Verify that `optim` termination status means 'no solution available'."
2323
function iserror(optim::JuMP.GenericModel)
2424
status = termination_status(optim)
25-
return any(status .== ERROR_STATUSES)
25+
return any(errstatus->isequal(status, errstatus), ERROR_STATUSES)
2626
end
2727

2828
"Evaluate the quadratic programming objective function `0.5x'*H*x + q'*x` at `x`."

src/plot_sim.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ function sim!(
129129
U_data[:, i] = u
130130
D_data[:, i] = d
131131
X_data[:, i] = plant.x
132-
x = updatestate!(plant, u, d)
132+
updatestate!(plant, u, d)
133133
end
134134
return SimResult(plant, T_data, Y_data, U_data, Y_data,
135135
U_data, U_data, U_data, D_data, X_data, X_data)

test/test_state_estim.jl

+6-4
Original file line numberDiff line numberDiff line change
@@ -682,10 +682,12 @@ end
682682

683683
mhe4 = setconstraint!(MovingHorizonEstimator(nonlinmodel, He=1, nint_ym=0), x̂max=[50,50,50,50])
684684
g_X̂max_end = mhe4.optim.nlp_model.operators.registered_multivariate_operators[end].f
685-
@test g_X̂max_end((1.0, 1.0, 1.0, 1.0)) 0.0 # test gfunc_i(i,::NTuple{N, Float64})
686-
# test gfunc_i(i,::NTuple{N, ForwardDiff.Dual}) :
687-
@test ForwardDiff.gradient(g_X̂max_end, [1.0, 1.0, 1.0, 1.0]) [0.0, 0.0, 0.0, 0.0]
688-
685+
# test gfunc_i(i,::NTuple{N, Float64}):
686+
@test g_X̂max_end(
687+
(1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0)) 0.0
688+
# test gfunc_i(i,::NTuple{N, ForwardDiff.Dual}):
689+
@test ForwardDiff.gradient(
690+
g_X̂max_end, [1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0]) [0, 0, 0, 0, 0, 0, 0, 0]
689691
= diagm([1/4, 1/4, 1/4, 1/4].^2)
690692
= diagm([1, 1].^2)
691693
optim = Model(Ipopt.Optimizer)

0 commit comments

Comments
 (0)