Skip to content

Commit 6dc66e0

Browse files
committed
debug: add JuMP prefix where needed
1 parent 6414850 commit 6dc66e0

File tree

4 files changed

+84
-22
lines changed

4 files changed

+84
-22
lines changed

src/ModelPredictiveControl.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import ControlSystemsBase: iscontinuous, isdiscrete, sminreal, minreal, c2d, d2c
1616

1717
import JuMP
1818
import JuMP: MOIU, MOI, GenericModel, Model, optimizer_with_attributes, register
19-
import JuMP: @variable, @constraint, @objective, @NLconstraint, @NLobjective
19+
import JuMP: @variable, @operator, @constraint, @objective
2020

2121
import PreallocationTools: DiffCache, get_tmp
2222

src/controller/nonlinmpc.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -319,22 +319,22 @@ function init_optimization!(mpc::NonLinMPC, model::SimModel, optim)
319319
if length(con.i_g) 0
320320
for i in eachindex(con.Y0min)
321321
name = Symbol("g_Y0min_$i")
322-
optim[name] = add_nonlinear_operator(optim, nΔŨ, gfunc[i]; name)
322+
optim[name] = JuMP.add_nonlinear_operator(optim, nΔŨ, gfunc[i]; name)
323323
end
324324
i_end_Ymin = 1Hp*ny
325325
for i in eachindex(con.Y0max)
326326
name = Symbol("g_Y0max_$i")
327-
optim[name] = add_nonlinear_operator(optim, nΔŨ, gfunc[i_end_Ymin+i]; name)
327+
optim[name] = JuMP.add_nonlinear_operator(optim, nΔŨ, gfunc[i_end_Ymin+i]; name)
328328
end
329329
i_end_Ymax = 2Hp*ny
330330
for i in eachindex(con.x̂0min)
331331
name = Symbol("g_x̂0min_$i")
332-
optim[name] = add_nonlinear_operator(optim, nΔŨ, gfunc[i_end_Ymax+i]; name)
332+
optim[name] = JuMP.add_nonlinear_operator(optim, nΔŨ, gfunc[i_end_Ymax+i]; name)
333333
end
334334
i_end_x̂min = 2Hp*ny + nx̂
335335
for i in eachindex(con.x̂0max)
336336
name = Symbol("g_x̂0max_$i")
337-
optim[name] = add_nonlinear_operator(optim, nΔŨ, gfunc[i_end_x̂min+i]; name)
337+
optim[name] = JuMP.add_nonlinear_operator(optim, nΔŨ, gfunc[i_end_x̂min+i]; name)
338338
end
339339
end
340340
return nothing
@@ -402,23 +402,23 @@ function setnonlincon!(
402402
) where JNT<:Real
403403
ΔŨvar = optim[:ΔŨvar]
404404
con = mpc.con
405-
nonlin_constraints = all_constraints(optim, NonlinearExpr, MOI.LessThan{JNT})
406-
map(con_ref -> JuMP.delete(optim, con_ref), JuMP.nonlin_constraints)
405+
nonlin_constraints = JuMP.all_constraints(optim, JuMP.NonlinearExpr, MOI.LessThan{JNT})
406+
map(con_ref -> JuMP.delete(optim, con_ref), nonlin_constraints)
407407
for i in findall(.!isinf.(con.Y0min))
408408
gfunc_i = optim[Symbol("g_Y0min_$(i)")]
409-
JuMP.@constraint(optim, gfunc_i(ΔŨvar...) <= 0)
409+
@constraint(optim, gfunc_i(ΔŨvar...) <= 0)
410410
end
411411
for i in findall(.!isinf.(con.Y0max))
412412
gfunc_i = optim[Symbol("g_Y0max_$(i)")]
413-
JuMP.@constraint(optim, gfunc_i(ΔŨvar...) <= 0)
413+
@constraint(optim, gfunc_i(ΔŨvar...) <= 0)
414414
end
415415
for i in findall(.!isinf.(con.x̂0min))
416416
gfunc_i = optim[Symbol("g_x̂0min_$(i)")]
417-
JuMP.@constraint(optim, gfunc_i(ΔŨvar...) <= 0)
417+
@constraint(optim, gfunc_i(ΔŨvar...) <= 0)
418418
end
419419
for i in findall(.!isinf.(con.x̂0max))
420420
gfunc_i = optim[Symbol("g_x̂0max_$(i)")]
421-
JuMP.@constraint(optim, gfunc_i(ΔŨvar...) <= 0)
421+
@constraint(optim, gfunc_i(ΔŨvar...) <= 0)
422422
end
423423
return nothing
424424
end

src/estimator/mhe/construct.jl

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -606,15 +606,15 @@ function setnonlincon!(
606606
) where JNT<:Real
607607
optim, con = estim.optim, estim.con
608608
Z̃var = optim[:Z̃var]
609-
nonlin_constraints = all_constraints(optim, NonlinearExpr, MOI.LessThan{JNT})
610-
map(con_ref -> JuMP.delete(optim, con_ref), JuMP.nonlin_constraints)
609+
nonlin_constraints = JuMP.all_constraints(optim, JuMP.NonlinearExpr, MOI.LessThan{JNT})
610+
map(con_ref -> JuMP.delete(optim, con_ref), nonlin_constraints)
611611
for i in findall(.!isinf.(con.X̂0min))
612612
gfunc_i = optim[Symbol("g_X̂0min_$(i)")]
613-
JuMP.@constraint(optim, gfunc_i(Z̃var...) <= 0)
613+
@constraint(optim, gfunc_i(Z̃var...) <= 0)
614614
end
615615
for i in findall(.!isinf.(con.X̂0max))
616616
gfunc_i = optim[Symbol("g_X̂0max_$(i)")]
617-
JuMP.@constraint(optim, gfunc_i(Z̃var...) <= 0)
617+
@constraint(optim, gfunc_i(Z̃var...) <= 0)
618618
end
619619
for i in findall(.!isinf.(con.V̂min))
620620
gfunc_i = optim[Symbol("g_V̂min_$(i)")]
@@ -1082,28 +1082,90 @@ function init_optimization!(
10821082
if length(con.i_g) 0
10831083
for i in eachindex(con.X̂0min)
10841084
name = Symbol("g_X̂0min_$i")
1085-
optim[name] = add_nonlinear_operator(optim, nZ̃, gfunc[i]; name)
1085+
optim[name] = JuMP.add_nonlinear_operator(
1086+
optim, nZ̃, gfunc[i]; name
1087+
)
10861088
end
10871089
i_end_X̂min = nX̂
10881090
for i in eachindex(con.X̂0max)
10891091
name = Symbol("g_X̂0max_$i")
1090-
optim[name] = add_nonlinear_operator(optim, nZ̃, gfunc[i_end_X̂min + i]; name)
1092+
optim[name] = JuMP.add_nonlinear_operator(
1093+
optim, nZ̃, gfunc[i_end_X̂min + i]; name
1094+
)
10911095
end
10921096
i_end_X̂max = 2*nX̂
10931097
for i in eachindex(con.V̂min)
10941098
name = Symbol("g_V̂min_$i")
1095-
optim[name] = add_nonlinear_operator(optim, nZ̃, gfunc[i_end_X̂max + i]; name)
1099+
optim[name] = JuMP.add_nonlinear_operator(
1100+
optim, nZ̃, gfunc[i_end_X̂max + i]; name
1101+
)
10961102
end
10971103
i_end_V̂min = 2*nX̂ + nV̂
10981104
for i in eachindex(con.V̂max)
10991105
name = Symbol("g_V̂max_$i")
1100-
optim[name] = add_nonlinear_operator(optim, nZ̃, gfunc[i_end_V̂min + i]; name)
1106+
optim[name] = JuMP.add_nonlinear_operator(
1107+
optim, nZ̃, gfunc[i_end_V̂min + i]; name
1108+
)
11011109
end
11021110
end
11031111
return nothing
11041112
end
11051113

11061114

1115+
"""
1116+
get_optim_functions(estim::MovingHorizonEstimator, ::JuMP.GenericModel) -> Jfunc, gfunc
1117+
1118+
Get the objective `Jfunc` and constraints `gfunc` functions for [`MovingHorizonEstimator`](@ref).
1119+
1120+
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)
1121+
"""
1122+
function get_optim_functions(
1123+
estim::MovingHorizonEstimator, ::JuMP.GenericModel{JNT}
1124+
) where {JNT <: Real}
1125+
model, con = estim.model, estim.con
1126+
nx̂, nym, nŷ, nu, He = estim.nx̂, estim.nym, model.ny, model.nu, estim.He
1127+
nV̂, nX̂, ng, nZ̃ = He*nym, He*nx̂, length(con.i_g), length(estim.Z̃)
1128+
Nc = nZ̃ + 3
1129+
Z̃_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nZ̃), Nc)
1130+
V̂_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nV̂), Nc)
1131+
g_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, ng), Nc)
1132+
X̂_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nX̂), Nc)
1133+
x̄_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nx̂), Nc)
1134+
û_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nu), Nc)
1135+
ŷ_cache::DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache(zeros(JNT, nŷ), Nc)
1136+
function Jfunc(Z̃tup::T...)::T where {T <: Real}
1137+
Z̃1 = Z̃tup[begin]
1138+
Z̃, g = get_tmp(Z̃_cache, Z̃1), get_tmp(g_cache, Z̃1)
1139+
for i in eachindex(Z̃tup)
1140+
Z̃[i] = Z̃tup[i] # Z̃ .= Z̃tup seems to produce a type instability
1141+
end
1142+
V̂, X̂ = get_tmp(V̂_cache, Z̃1), get_tmp(X̂_cache, Z̃1)
1143+
û, ŷ = get_tmp(û_cache, Z̃1), get_tmp(ŷ_cache, Z̃1)
1144+
V̂, X̂ = predict!(V̂, X̂, û, ŷ, estim, model, Z̃)
1145+
g = get_tmp(g_cache, Z̃1)
1146+
g = con_nonlinprog!(g, estim, model, X̂, V̂, Z̃)
1147+
= get_tmp(x̄_cache, Z̃1)
1148+
return obj_nonlinprog!(x̄, estim, model, V̂, Z̃)::T
1149+
end
1150+
function gfunc_i(i, Z̃tup::NTuple{N, T})::T where {N, T <:Real}
1151+
Z̃1 = Z̃tup[begin]
1152+
Z̃, g = get_tmp(Z̃_cache, Z̃1), get_tmp(g_cache, Z̃1)
1153+
if any(new !== old for (new, old) in zip(Z̃tup, Z̃)) # new Z̃tup, update predictions:
1154+
V̂, X̂ = get_tmp(V̂_cache, Z̃1), get_tmp(X̂_cache, Z̃1)
1155+
û, ŷ = get_tmp(û_cache, Z̃1), get_tmp(ŷ_cache, Z̃1)
1156+
for i in eachindex(Z̃tup)
1157+
Z̃[i] = Z̃tup[i] # Z̃ .= Z̃tup seems to produce a type instability
1158+
end
1159+
V̂, X̂ = predict!(V̂, X̂, û, ŷ, estim, model, Z̃)
1160+
g = con_nonlinprog!(g, estim, model, X̂, V̂, Z̃)
1161+
end
1162+
return g[i]
1163+
end
1164+
gfunc = [(Z̃...) -> gfunc_i(i, Z̃) for i in 1:ng]
1165+
return Jfunc, gfunc
1166+
end
1167+
1168+
11071169
"""
11081170
get_optim_functions(estim::MovingHorizonEstimator, ::JuMP.GenericModel) -> Jfunc, gfunc
11091171

test/test_predictive_control.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -507,11 +507,11 @@ end
507507
u = moveinput!(nmpc4, [0], d, R̂u=fill(12, nmpc4.Hp))
508508
@test u [12] atol=5e-2
509509
nmpc5 = setconstraint!(NonLinMPC(nonlinmodel, Hp=15, Cwt=Inf), ymin=[1])
510-
g_Ymin_end = nmpc5.optim[:g_Ymin_15].func
510+
g_Y0min_end = nmpc5.optim[:g_Y0min_15].func
511511
# test gfunc_i(i,::NTuple{N, Float64}):
512-
@test g_Ymin_end(20.0, 10.0) 0.0
512+
@test g_Y0min_end(20.0, 10.0) 0.0
513513
# test gfunc_i(i,::NTuple{N, ForwardDiff.Dual}) :
514-
@test ForwardDiff.gradient(vec->g_Ymin_end(vec...), [20.0, 10.0]) [-5, -5] atol=1e-3
514+
@test ForwardDiff.gradient(vec->g_Y0min_end(vec...), [20.0, 10.0]) [-5, -5] atol=1e-3
515515
linmodel3 = LinModel{Float32}(0.5*ones(1,1), ones(1,1), ones(1,1), zeros(1,0), zeros(1,0), 1.0)
516516
nmpc6 = NonLinMPC(linmodel3, Hp=10)
517517
@test moveinput!(nmpc6, [0]) [0.0]

0 commit comments

Comments
 (0)