Skip to content

Commit 5c85eeb

Browse files
authored
Merge pull request #200 from JuliaControl/cherry_pick
Cherry pick doc and general improvements commits from `hessian_objective`
2 parents 9e80002 + 128922f commit 5c85eeb

File tree

8 files changed

+32
-31
lines changed

8 files changed

+32
-31
lines changed

docs/Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ Documenter = "1"
1616
JuMP = "1"
1717
LinearAlgebra = "1.10"
1818
Logging = "1.10"
19-
ModelingToolkit = "9.50"
19+
ModelingToolkit = "9.50 - 9.76"
2020
Plots = "1"

docs/src/manual/mtk.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ the last section.
2323
will work for all corner cases.
2424

2525
!!! compat
26-
The example relies on features and bugfixes of `ModelingToolkit.jl` v9.50.
26+
The example works on `ModelingToolkit.jl` v9.50 to 9.76 (corresponding to the following
27+
`[compat]` entry: `ModelingToolkit = "9.50 - 9.76"`).
2728

2829
We first construct and instantiate the pendulum model:
2930

src/controller/execute.jl

+4-4
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ function optim_objective!(mpc::PredictiveController{NT}) where {NT<:Real}
395395
model, optim = mpc.estim.model, mpc.optim
396396
nu, Hc = model.nu, mpc.Hc
397397
Z̃var::Vector{JuMP.VariableRef} = optim[:Z̃var]
398-
Z̃0 = set_warmstart!(mpc, mpc.transcription, Z̃var)
398+
Z̃s = set_warmstart!(mpc, mpc.transcription, Z̃var)
399399
set_objective_linear_coef!(mpc, Z̃var)
400400
try
401401
JuMP.optimize!(optim)
@@ -405,7 +405,7 @@ function optim_objective!(mpc::PredictiveController{NT}) where {NT<:Real}
405405
MOIU.reset_optimizer(optim)
406406
JuMP.optimize!(optim)
407407
else
408-
rethrow(err)
408+
rethrow()
409409
end
410410
end
411411
if !issolved(optim)
@@ -426,7 +426,7 @@ function optim_objective!(mpc::PredictiveController{NT}) where {NT<:Real}
426426
@debug info2debugstr(getinfo(mpc))
427427
end
428428
if iserror(optim)
429-
mpc.Z̃ .= Z̃0
429+
mpc.Z̃ .= Z̃s
430430
else
431431
mpc.Z̃ .= JuMP.value.(Z̃var)
432432
end
@@ -488,7 +488,7 @@ Call `periodsleep(mpc.estim.model)`.
488488
periodsleep(mpc::PredictiveController, busywait=false) = periodsleep(mpc.estim.model, busywait)
489489

490490
"""
491-
setstate!(mpc::PredictiveController, x̂, P̂=nothing) -> mpc
491+
setstate!(mpc::PredictiveController, x̂[, P̂]) -> mpc
492492
493493
Call [`setstate!`](@ref) on `mpc.estim` [`StateEstimator`](@ref).
494494
"""

src/controller/transcription.jl

+14-14
Original file line numberDiff line numberDiff line change
@@ -972,14 +972,14 @@ where ``\mathbf{Δu}(k+j|k-1)`` is the input increment for time ``k+j`` computed
972972
last control period ``k-1``, and ``ϵ(k-1)``, the slack variable of the last control period.
973973
"""
974974
function set_warmstart!(mpc::PredictiveController, transcription::SingleShooting, Z̃var)
975-
nu, Hc, Z̃0 = mpc.estim.model.nu, mpc.Hc, mpc.buffer.
975+
nu, Hc, Z̃s = mpc.estim.model.nu, mpc.Hc, mpc.buffer.
976976
# --- input increments ΔU ---
977-
Z̃0[1:(Hc*nu-nu)] .= @views mpc.Z̃[nu+1:Hc*nu]
978-
Z̃0[(Hc*nu-nu+1):(Hc*nu)] .= 0
977+
Z̃s[1:(Hc*nu-nu)] .= @views mpc.Z̃[nu+1:Hc*nu]
978+
Z̃s[(Hc*nu-nu+1):(Hc*nu)] .= 0
979979
# --- slack variable ϵ ---
980-
mpc.== 1 && (Z̃0[end] = mpc.Z̃[end])
981-
JuMP.set_start_value.(Z̃var, Z̃0)
982-
return Z̃0
980+
mpc.== 1 && (Z̃s[end] = mpc.Z̃[end])
981+
JuMP.set_start_value.(Z̃var, Z̃s)
982+
return Z̃s
983983
end
984984

985985
@doc raw"""
@@ -1009,17 +1009,17 @@ last control period ``k-1``, expressed as a deviation from the operating point
10091009
``\mathbf{x̂_{op}}``.
10101010
"""
10111011
function set_warmstart!(mpc::PredictiveController, transcription::MultipleShooting, Z̃var)
1012-
nu, nx̂, Hp, Hc, Z̃0 = mpc.estim.model.nu, mpc.estim.nx̂, mpc.Hp, mpc.Hc, mpc.buffer.
1012+
nu, nx̂, Hp, Hc, Z̃s = mpc.estim.model.nu, mpc.estim.nx̂, mpc.Hp, mpc.Hc, mpc.buffer.
10131013
# --- input increments ΔU ---
1014-
Z̃0[1:(Hc*nu-nu)] .= @views mpc.Z̃[nu+1:Hc*nu]
1015-
Z̃0[(Hc*nu-nu+1):(Hc*nu)] .= 0
1014+
Z̃s[1:(Hc*nu-nu)] .= @views mpc.Z̃[nu+1:Hc*nu]
1015+
Z̃s[(Hc*nu-nu+1):(Hc*nu)] .= 0
10161016
# --- predicted states X̂0 ---
1017-
Z̃0[(Hc*nu+1):(Hc*nu+Hp*nx̂-nx̂)] .= @views mpc.Z̃[(Hc*nu+nx̂+1):(Hc*nu+Hp*nx̂)]
1018-
Z̃0[(Hc*nu+Hp*nx̂-nx̂+1):(Hc*nu+Hp*nx̂)] .= @views mpc.Z̃[(Hc*nu+Hp*nx̂-nx̂+1):(Hc*nu+Hp*nx̂)]
1017+
Z̃s[(Hc*nu+1):(Hc*nu+Hp*nx̂-nx̂)] .= @views mpc.Z̃[(Hc*nu+nx̂+1):(Hc*nu+Hp*nx̂)]
1018+
Z̃s[(Hc*nu+Hp*nx̂-nx̂+1):(Hc*nu+Hp*nx̂)] .= @views mpc.Z̃[(Hc*nu+Hp*nx̂-nx̂+1):(Hc*nu+Hp*nx̂)]
10191019
# --- slack variable ϵ ---
1020-
mpc.== 1 && (Z̃0[end] = mpc.Z̃[end])
1021-
JuMP.set_start_value.(Z̃var, Z̃0)
1022-
return Z̃0
1020+
mpc.== 1 && (Z̃s[end] = mpc.Z̃[end])
1021+
JuMP.set_start_value.(Z̃var, Z̃s)
1022+
return Z̃s
10231023
end
10241024

10251025
getΔŨ!(ΔŨ, mpc::PredictiveController, ::SingleShooting, Z̃) = (ΔŨ .= Z̃) # since mpc.P̃Δu = I

src/estimator/execute.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ function validate_args(estim::StateEstimator, ym, d, u=nothing)
330330
end
331331

332332
"""
333-
setstate!(estim::StateEstimator, x̂, P̂=nothing) -> estim
333+
setstate!(estim::StateEstimator, x̂[, P̂]) -> estim
334334
335335
Set `estim.x̂0` to `x̂ - estim.x̂op` from the argument `x̂`, and `estim.P̂` to `P̂` if applicable.
336336

src/estimator/mhe/execute.jl

+8-8
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ Optimize objective of `estim` [`MovingHorizonEstimator`](@ref) and return the so
364364
365365
If supported by `estim.optim`, it warm-starts the solver at:
366366
```math
367-
\mathbf{} =
367+
\mathbf{Z̃_s} =
368368
\begin{bmatrix}
369369
ϵ_{k-1} \\
370370
\mathbf{x̂}_{k-1}(k-N_k+p) \\
@@ -391,12 +391,12 @@ function optim_objective!(estim::MovingHorizonEstimator{NT}) where NT<:Real
391391
X̂0 = Vector{NT}(undef, nx̂*Nk)
392392
û0, ŷ0, x̄, k0 = buffer.û, buffer.ŷ, buffer.x̂, buffer.k
393393
ϵ_0 = estim. 0 ? estim.Z̃[begin] : empty(estim.Z̃)
394-
Z̃_0 = [ϵ_0; estim.x̂0arr_old; estim.Ŵ]
395-
V̂, X̂0 = predict!(V̂, X̂0, û0, k0, ŷ0, estim, model, Z̃_0)
396-
J_0 = obj_nonlinprog!(x̄, estim, model, V̂, Z̃_0)
397-
# initial Z̃0 with Ŵ=0 if objective or constraint function not finite :
398-
isfinite(J_0) || (Z̃_0 = [ϵ_0; estim.x̂0arr_old; zeros(NT, nŵ*estim.He)])
399-
JuMP.set_start_value.(Z̃var, Z̃_0)
394+
Z̃s = [ϵ_0; estim.x̂0arr_old; estim.Ŵ]
395+
V̂, X̂0 = predict!(V̂, X̂0, û0, k0, ŷ0, estim, model, Z̃s)
396+
J_0 = obj_nonlinprog!(x̄, estim, model, V̂, Z̃s)
397+
# warm-start Z̃s with Ŵ=0 if objective or constraint function not finite :
398+
isfinite(J_0) || (Z̃s = [ϵ_0; estim.x̂0arr_old; zeros(NT, nŵ*estim.He)])
399+
JuMP.set_start_value.(Z̃var, Z̃s)
400400
# ------- solve optimization problem --------------
401401
try
402402
JuMP.optimize!(optim)
@@ -428,7 +428,7 @@ function optim_objective!(estim::MovingHorizonEstimator{NT}) where NT<:Real
428428
@debug info2debugstr(getinfo(estim))
429429
end
430430
if iserror(optim)
431-
estim.Z̃ .= Z̃_0
431+
estim.Z̃ .= Z̃s
432432
else
433433
estim.Z̃ .= JuMP.value.(Z̃var)
434434
end

src/general.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function limit_solve_time(optim::GenericModel, Ts)
5151
if isa(err, MOI.UnsupportedAttribute{MOI.TimeLimitSec})
5252
@warn "Solving time limit is not supported by the optimizer."
5353
else
54-
rethrow(err)
54+
rethrow()
5555
end
5656
end
5757
end

test/2_test_state_estim.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1364,7 +1364,7 @@ end
13641364
X̂_mhe = zeros(4, 6)
13651365
X̂_kf = zeros(4, 6)
13661366
for i in 1:6
1367-
y = [50,31] #+ randn(2)
1367+
y = [50,31] + randn(2)
13681368
x̂_mhe = preparestate!(mhe, y, [25])
13691369
x̂_kf = preparestate!(kf, y, [25])
13701370
X̂_mhe[:,i] = x̂_mhe

0 commit comments

Comments
 (0)