11@doc raw """
22 initstate!(mpc::PredictiveController, u, ym, d=[]) -> x̂
33
4- Init the states of `mpc.estim` [`StateEstimator`](@ref) and warm start `mpc.ΔŨ ` at zero.
4+ Init the states of `mpc.estim` [`StateEstimator`](@ref) and warm start `mpc.Z̃ ` at zero.
55"""
66function initstate! (mpc:: PredictiveController , u, ym, d= mpc. estim. buffer. empty)
7- mpc. ΔŨ .= 0
7+ mpc. Z̃ .= 0
88 return initstate! (mpc. estim, u, ym, d)
99end
1010
@@ -67,8 +67,9 @@ function moveinput!(
6767 validate_args (mpc, ry, d, D̂, R̂y, R̂u)
6868 initpred! (mpc, mpc. estim. model, d, D̂, R̂y, R̂u)
6969 linconstraint! (mpc, mpc. estim. model)
70- ΔŨ = optim_objective! (mpc)
71- return getinput (mpc, ΔŨ)
70+ linconstrainteq! (mpc, mpc. transcription)
71+ Z̃ = optim_objective! (mpc)
72+ return getinput (mpc, Z̃)
7273end
7374
7475@doc raw """
@@ -323,6 +324,22 @@ function linconstraint!(mpc::PredictiveController, ::SimModel)
323324 return nothing
324325end
325326
327+ linconstrainteq! (mpc:: PredictiveController , transcription:: SingleShooting ) = nothing
328+ function linconstrainteq! (mpc:: PredictiveController , transcription:: MultipleShooting )
329+ nx̂, Fŝ = mpc. estim. nx̂, mpc. con. Fŝ
330+ Fŝ .= mpc. con. Bŝ
331+ mul! (Fŝ, mpc. con. Kŝ, mpc. estim. x̂0, 1 , 1 )
332+ mul! (Fŝ, mpc. con. Vŝ, mpc. estim. lastu0, 1 , 1 )
333+ if mpc. estim. model. nd ≠ 0
334+ mul! (Fŝ, mpc. con. Gŝ, mpc. d0, 1 , 1 )
335+ mul! (Fŝ, mpc. con. Jŝ, mpc. D̂0, 1 , 1 )
336+ end
337+ mpc. con. beq .= @. - Fŝ
338+ linconeq = mpc. optim[:linconstrainteq ]
339+ JuMP. set_normalized_rhs (linconeq, mpc. con. beq)
340+ return nothing
341+ end
342+
326343@doc raw """
327344 predict!(Ŷ0, x̂0, _, _, _, mpc::PredictiveController, model::LinModel, ΔŨ) -> Ŷ0, x̂0end
328345
@@ -467,39 +484,21 @@ function obj_econ(::PredictiveController, ::SimModel, _ , ::AbstractVector{NT})
467484end
468485
469486@doc raw """
470- optim_objective!(mpc::PredictiveController) -> ΔŨ
487+ optim_objective!(mpc::PredictiveController) -> Z̃
471488
472- Optimize the objective function of `mpc` [`PredictiveController`](@ref) and return the solution `ΔŨ `.
489+ Optimize the objective function of `mpc` [`PredictiveController`](@ref) and return the solution `Z̃ `.
473490
474- If supported by `mpc.optim`, it warm-starts the solver at:
475- ```math
476- \m athbf{ΔŨ} =
477- \b egin{bmatrix}
478- \m athbf{Δu}_{k-1}(k+0) \\
479- \m athbf{Δu}_{k-1}(k+1) \\
480- \v dots \\
481- \m athbf{Δu}_{k-1}(k+H_c-2) \\
482- \m athbf{0} \\
483- ϵ_{k-1}
484- \e nd{bmatrix}
485- ```
486- where ``\m athbf{Δu}_{k-1}(k+j)`` is the input increment for time ``k+j`` computed at the
487- last control period ``k-1``. It then calls `JuMP.optimize!(mpc.optim)` and extract the
488- solution. A failed optimization prints an `@error` log in the REPL and returns the
489- warm-start value. A failed optimization also prints [`getinfo`](@ref) results in
490- the debug log [if activated](https://docs.julialang.org/en/v1/stdlib/Logging/#Example:-Enable-debug-level-messages).
491+ If first warm-starts the solver with [`set_warm_start!`](@ref). It then calls
492+ `JuMP.optimize!(mpc.optim)` and extract the solution. A failed optimization prints an
493+ `@error` log in the REPL and returns the warm-start value. A failed optimization also prints
494+ [`getinfo`](@ref) results in the debug log [if activated](https://docs.julialang.org/en/v1/stdlib/Logging/#Example:-Enable-debug-level-messages).
491495"""
492496function optim_objective! (mpc:: PredictiveController{NT} ) where {NT<: Real }
493497 model, optim = mpc. estim. model, mpc. optim
494- nu, Hc = model. nu, mpc. Hc
495- ΔŨvar:: Vector{JuMP.VariableRef} = optim[:ΔŨvar ]
496- # initial ΔŨ (warm-start): [Δu_{k-1}(k); Δu_{k-1}(k+1); ... ; 0_{nu × 1}; ϵ_{k-1}]
497- ΔŨ0 = mpc. buffer. ΔŨ
498- ΔŨ0[1 : (Hc* nu- nu)] .= @views mpc. ΔŨ[nu+ 1 : Hc* nu]
499- ΔŨ0[(Hc* nu- nu+ 1 ): (Hc* nu)] .= 0
500- mpc. nϵ == 1 && (ΔŨ0[end ] = mpc. ΔŨ[end ])
501- JuMP. set_start_value .(ΔŨvar, ΔŨ0)
502- set_objective_linear_coef! (mpc, ΔŨvar)
498+ nu, Hc = model. nu, mpc. Hc
499+ Z̃var:: Vector{JuMP.VariableRef} = optim[:Z̃var ]
500+ Z̃0 = set_warmstart! (mpc, mpc. transcription, Z̃var)
501+ set_objective_linear_coef! (mpc, Z̃var)
503502 try
504503 JuMP. optimize! (optim)
505504 catch err
@@ -529,11 +528,11 @@ function optim_objective!(mpc::PredictiveController{NT}) where {NT<:Real}
529528 @debug info2debugstr (getinfo (mpc))
530529 end
531530 if iserror (optim)
532- mpc. ΔŨ .= ΔŨ0
531+ mpc. Z̃ .= Z̃0
533532 else
534- mpc. ΔŨ .= JuMP. value .(ΔŨvar )
533+ mpc. Z̃ .= JuMP. value .(Z̃var )
535534 end
536- return mpc. ΔŨ
535+ return mpc. Z̃
537536end
538537
539538" By default, no need to modify the objective function."
@@ -549,17 +548,17 @@ function preparestate!(mpc::PredictiveController, ym, d=mpc.estim.buffer.empty)
549548end
550549
551550@doc raw """
552- getinput(mpc::PredictiveController, ΔŨ ) -> u
551+ getinput(mpc::PredictiveController, Z̃ ) -> u
553552
554- Get current manipulated input `u` from a [`PredictiveController`](@ref) solution `ΔŨ `.
553+ Get current manipulated input `u` from a [`PredictiveController`](@ref) solution `Z̃ `.
555554
556- The first manipulated input ``\m athbf{u}(k)`` is extracted from the input increments vector
557- ``\m athbf{ΔŨ }`` and applied on the plant (from the receding horizon principle).
555+ The first manipulated input ``\m athbf{u}(k)`` is extracted from the decision vector
556+ ``\m athbf{Z̃ }`` and applied on the plant (from the receding horizon principle).
558557"""
559- function getinput (mpc, ΔŨ )
558+ function getinput (mpc, Z̃ )
560559 Δu = mpc. buffer. u
561560 for i in 1 : mpc. estim. model. nu
562- Δu[i] = ΔŨ [i]
561+ Δu[i] = Z̃ [i]
563562 end
564563 u = Δu
565564 u .+ = mpc. estim. lastu0 .+ mpc. estim. model. uop
0 commit comments