11const DEFAULT_NONLINMPC_OPTIMIZER = optimizer_with_attributes (Ipopt. Optimizer," sb" => " yes" )
22
3- struct NonLinMPC{NT<: Real , SE<: StateEstimator , JEfunc<: Function } <: PredictiveController{NT}
3+ struct NonLinMPC{
4+ NT<: Real ,
5+ SE<: StateEstimator ,
6+ JM<: JuMP.GenericModel ,
7+ JEfunc<: Function
8+ } <: PredictiveController{NT}
49 estim:: SE
5- optim:: JuMP.Model
10+ # note: `NT` and the number type `JNT` in `JuMP.GenericModel{JNT}` can be
11+ # different since solvers that support non-Float64 are scarce.
12+ optim:: JM
613 con:: ControllerConstraint{NT}
714 ΔŨ:: Vector{NT}
815 ŷ :: Vector{NT}
@@ -35,27 +42,28 @@ struct NonLinMPC{NT<:Real, SE<:StateEstimator, JEfunc<:Function} <: PredictiveCo
3542 D̂E:: Vector{NT}
3643 Ŷop:: Vector{NT}
3744 Dop:: Vector{NT}
38- function NonLinMPC {NT, SE, JEFunc} (
39- estim:: SE , Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt, JE:: JEFunc , optim
40- ) where {NT<: Real , SE<: StateEstimator , JEFunc<: Function }
45+ function NonLinMPC {NT, SE, JM, JEFunc} (
46+ estim:: SE , Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt, JE:: JEFunc , optim:: JM
47+ ) where {NT<: Real , SE<: StateEstimator , JM <: JuMP.GenericModel , JEFunc<: Function }
4148 model = estim. model
4249 nu, ny, nd = model. nu, model. ny, model. nd
4350 ŷ = copy (model. yop) # dummy vals (updated just before optimization)
4451 validate_weights (model, Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt)
4552 M_Hp, N_Hc, L_Hp = float (M_Hp), float (N_Hc), float (L_Hp) # debug julia 1.6
46- R̂y, R̂u = zeros (ny* Hp), zeros (nu* Hp) # dummy vals (updated just before optimization)
53+ # dummy vals (updated just before optimization):
54+ R̂y, R̂u = zeros (NT, ny* Hp), zeros (NT, nu* Hp)
4755 noR̂u = iszero (L_Hp)
4856 S, T = init_ΔUtoU (nu, Hp, Hc)
4957 E, F, G, J, K, V, ex̂, fx̂, gx̂, jx̂, kx̂, vx̂ = init_predmat (estim, model, Hp, Hc)
5058 con, S̃, Ñ_Hc, Ẽ = init_defaultcon (estim, Hp, Hc, Cwt, S, N_Hc, E, ex̂, fx̂, gx̂, jx̂, kx̂, vx̂)
5159 P̃, q̃, p = init_quadprog (model, Ẽ, S̃, M_Hp, Ñ_Hc, L_Hp)
5260 Ks, Ps = init_stochpred (estim, Hp)
5361 # dummy vals (updated just before optimization):
54- d0, D̂0, D̂E = zeros (nd), zeros (nd* Hp), zeros (nd + nd* Hp)
62+ d0, D̂0, D̂E = zeros (NT, nd), zeros (NT, nd* Hp), zeros (NT, nd + nd* Hp)
5563 Ŷop, Dop = repeat (model. yop, Hp), repeat (model. dop, Hp)
5664 nvar = size (Ẽ, 2 )
57- ΔŨ = zeros (nvar)
58- mpc = new {NT, SE, JEFunc} (
65+ ΔŨ = zeros (NT, nvar)
66+ mpc = new {NT, SE, JM, JEFunc} (
5967 estim, optim, con,
6068 ΔŨ, ŷ,
6169 Hp, Hc,
@@ -67,7 +75,7 @@ struct NonLinMPC{NT<:Real, SE<:StateEstimator, JEfunc<:Function} <: PredictiveCo
6775 d0, D̂0, D̂E,
6876 Ŷop, Dop,
6977 )
70- init_optimization! (mpc)
78+ init_optimization! (mpc, optim )
7179 return mpc
7280 end
7381end
@@ -168,7 +176,7 @@ function NonLinMPC(
168176 M_Hp = nothing ,
169177 N_Hc = nothing ,
170178 L_Hp = nothing ,
171- optim:: JuMP.Model = JuMP. Model (DEFAULT_NONLINMPC_OPTIMIZER, add_bridges= false ),
179+ optim:: JuMP.GenericModel = JuMP. Model (DEFAULT_NONLINMPC_OPTIMIZER, add_bridges= false ),
172180 kwargs...
173181)
174182 estim = UnscentedKalmanFilter (model; kwargs... )
@@ -188,7 +196,7 @@ function NonLinMPC(
188196 M_Hp = nothing ,
189197 N_Hc = nothing ,
190198 L_Hp = nothing ,
191- optim:: JuMP.Model = JuMP. Model (DEFAULT_NONLINMPC_OPTIMIZER, add_bridges= false ),
199+ optim:: JuMP.GenericModel = JuMP. Model (DEFAULT_NONLINMPC_OPTIMIZER, add_bridges= false ),
192200 kwargs...
193201)
194202 estim = SteadyKalmanFilter (model; kwargs... )
@@ -231,13 +239,13 @@ function NonLinMPC(
231239 M_Hp = nothing ,
232240 N_Hc = nothing ,
233241 L_Hp = nothing ,
234- optim:: JuMP.Model = JuMP. Model (DEFAULT_NONLINMPC_OPTIMIZER, add_bridges= false ),
235- ) where {NT<: Real , SE<: StateEstimator{NT} , JEFunc<: Function }
242+ optim:: JM = JuMP. Model (DEFAULT_NONLINMPC_OPTIMIZER, add_bridges= false ),
243+ ) where {NT<: Real , SE<: StateEstimator{NT} , JM <: JuMP.GenericModel , JEFunc<: Function }
236244 Hp = default_Hp (estim. model, Hp)
237- isnothing (M_Hp) && (M_Hp = Diagonal (repeat (Mwt, Hp)))
238- isnothing (N_Hc) && (N_Hc = Diagonal (repeat (Nwt, Hc)))
239- isnothing (L_Hp) && (L_Hp = Diagonal (repeat (Lwt, Hp)))
240- return NonLinMPC {NT, SE, JEFunc} (estim, Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt, JE, optim)
245+ isnothing (M_Hp) && (M_Hp = Diagonal {NT} (repeat (Mwt, Hp)))
246+ isnothing (N_Hc) && (N_Hc = Diagonal {NT} (repeat (Nwt, Hc)))
247+ isnothing (L_Hp) && (L_Hp = Diagonal {NT} (repeat (Lwt, Hp)))
248+ return NonLinMPC {NT, SE, JM, JEFunc} (estim, Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt, JE, optim)
241249end
242250
243251"""
@@ -256,13 +264,13 @@ function addinfo!(info, mpc::NonLinMPC)
256264end
257265
258266"""
259- init_optimization!(mpc::NonLinMPC)
267+ init_optimization!(mpc::NonLinMPC, optim::JuMP.GenericModel )
260268
261269Init the nonlinear optimization for [`NonLinMPC`](@ref) controllers.
262270"""
263- function init_optimization! (mpc:: NonLinMPC{NT, SE, JEFunc } ) where {NT <: Real , SE, JEFunc}
271+ function init_optimization! (mpc:: NonLinMPC , optim :: JuMP.GenericModel{JNT } ) where JNT <: Real
264272 # --- variables and linear constraints ---
265- optim, con = mpc . optim, mpc. con
273+ con = mpc. con
266274 nvar = length (mpc. ΔŨ)
267275 set_silent (optim)
268276 limit_solve_time (mpc)
@@ -277,10 +285,10 @@ function init_optimization!(mpc::NonLinMPC{NT, SE, JEFunc}) where {NT<:Real, SE,
277285 # inspired from https://jump.dev/JuMP.jl/stable/tutorials/nonlinear/tips_and_tricks/#User-defined-operators-with-vector-outputs
278286 Jfunc, gfunc = let mpc= mpc, model= model, ng= ng, nvar= nvar , nŶ= Hp* ny, nx̂= nx̂
279287 last_ΔŨtup_float, last_ΔŨtup_dual = nothing , nothing
280- Ŷ_cache:: DiffCache{Vector{NT }, Vector{NT }} = DiffCache (zeros (NT , nŶ), nvar + 3 )
281- g_cache:: DiffCache{Vector{NT }, Vector{NT }} = DiffCache (zeros (NT , ng), nvar + 3 )
282- x̂_cache:: DiffCache{Vector{NT }, Vector{NT }} = DiffCache (zeros (NT , nx̂), nvar + 3 )
283- function Jfunc (ΔŨtup:: NT ... )
288+ Ŷ_cache:: DiffCache{Vector{JNT }, Vector{JNT }} = DiffCache (zeros (JNT , nŶ), nvar + 3 )
289+ g_cache:: DiffCache{Vector{JNT }, Vector{JNT }} = DiffCache (zeros (JNT , ng), nvar + 3 )
290+ x̂_cache:: DiffCache{Vector{JNT }, Vector{JNT }} = DiffCache (zeros (JNT , nx̂), nvar + 3 )
291+ function Jfunc (ΔŨtup:: JNT ... )
284292 Ŷ = get_tmp (Ŷ_cache, ΔŨtup[1 ])
285293 ΔŨ = collect (ΔŨtup)
286294 if ΔŨtup != last_ΔŨtup_float
@@ -304,7 +312,7 @@ function init_optimization!(mpc::NonLinMPC{NT, SE, JEFunc}) where {NT<:Real, SE,
304312 end
305313 return obj_nonlinprog (mpc, model, Ŷ, ΔŨ)
306314 end
307- function gfunc_i (i, ΔŨtup:: NTuple{N, NT } ) where N
315+ function gfunc_i (i, ΔŨtup:: NTuple{N, JNT } ) where N
308316 g = get_tmp (g_cache, ΔŨtup[1 ])
309317 if ΔŨtup != last_ΔŨtup_float
310318 x̂ = get_tmp (x̂_cache, ΔŨtup[1 ])
0 commit comments