Skip to content

Commit 7bde163

Browse files
authored
Merge pull request #246 from JuliaControl/debug_ms_setmodel
debug: `setmodel!` now works with `LinMPC` based on `MultipleShooting`
2 parents 36deef6 + 07a9967 commit 7bde163

File tree

3 files changed

+45
-23
lines changed

3 files changed

+45
-23
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ModelPredictiveControl"
22
uuid = "61f9bdb8-6ae4-484a-811f-bbf86720c31c"
33
authors = ["Francis Gagnon"]
4-
version = "1.9.2"
4+
version = "1.9.3"
55

66
[deps]
77
ControlSystemsBase = "aaaaaaaa-a6ca-5380-bf3e-84a91bcd477e"

src/controller/execute.jl

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ function setmodel_controller!(mpc::PredictiveController, uop_old, x̂op_old)
611611
model, estim, transcription = mpc.estim.model, mpc.estim, mpc.transcription
612612
nu, ny, nd, Hp, Hc = model.nu, model.ny, model.nd, mpc.Hp, mpc.Hc
613613
optim, con = mpc.optim, mpc.con
614-
# --- predictions matrices ---
614+
# --- prediction matrices ---
615615
E, G, J, K, V, B, ex̂, gx̂, jx̂, kx̂, vx̂, bx̂ = init_predmat(
616616
model, estim, transcription, Hp, Hc
617617
)
@@ -623,20 +623,46 @@ function setmodel_controller!(mpc::PredictiveController, uop_old, x̂op_old)
623623
mpc.K .= K
624624
mpc.V .= V
625625
mpc.B .= B
626+
# --- defect matrices ---
627+
Eŝ, Gŝ, Jŝ, Kŝ, Vŝ, Bŝ = init_defectmat(model, estim, transcription, Hp, Hc)
628+
A_ŝ, Ẽŝ = augmentdefect(Eŝ, mpc.nϵ)
629+
con.Ẽŝ .= Ẽŝ
630+
con.Gŝ .= Gŝ
631+
con.Jŝ .= Jŝ
632+
con.Kŝ .= Kŝ
633+
con.Vŝ .= Vŝ
634+
con.Bŝ .= Bŝ
626635
# --- linear inequality constraints ---
627636
con.ẽx̂ .= ẽx̂
628637
con.gx̂ .= gx̂
629638
con.jx̂ .= jx̂
630639
con.kx̂ .= kx̂
631640
con.vx̂ .= vx̂
632641
con.bx̂ .= bx̂
642+
con.A_Ymin .= A_Ymin
643+
con.A_Ymax .= A_Ymax
644+
con.A_x̂min .= A_x̂min
645+
con.A_x̂max .= A_x̂max
646+
con.A .= [
647+
con.A_Umin
648+
con.A_Umax
649+
con.A_ΔŨmin
650+
con.A_ΔŨmax
651+
con.A_Ymin
652+
con.A_Ymax
653+
con.A_x̂min
654+
con.A_x̂max
655+
]
656+
# --- linear equality constraints ---
657+
con.A_ŝ .= A_ŝ
658+
con.Aeq .= A_ŝ
659+
# --- operating points ---
633660
con.U0min .+= mpc.Uop # convert U0 to U with the old operating point
634661
con.U0max .+= mpc.Uop # convert U0 to U with the old operating point
635662
con.Y0min .+= mpc.Yop # convert Y0 to Y with the old operating point
636663
con.Y0max .+= mpc.Yop # convert Y0 to Y with the old operating point
637664
con.x̂0min .+= x̂op_old # convert x̂0 to x̂ with the old operating point
638665
con.x̂0max .+= x̂op_old # convert x̂0 to x̂ with the old operating point
639-
# --- operating points ---
640666
mpc.lastu0 .+= uop_old .- model.uop
641667
for i in 0:Hp-1
642668
mpc.Uop[(1+nu*i):(nu+nu*i)] .= model.uop
@@ -649,35 +675,20 @@ function setmodel_controller!(mpc::PredictiveController, uop_old, x̂op_old)
649675
con.Y0max .-= mpc.Yop # convert Y to Y0 with the new operating point
650676
con.x̂0min .-= estim.x̂op # convert x̂ to x̂0 with the new operating point
651677
con.x̂0max .-= estim.x̂op # convert x̂ to x̂0 with the new operating point
652-
con.A_Ymin .= A_Ymin
653-
con.A_Ymax .= A_Ymax
654-
con.A_x̂min .= A_x̂min
655-
con.A_x̂max .= A_x̂max
656-
con.A .= [
657-
con.A_Umin
658-
con.A_Umax
659-
con.A_ΔŨmin
660-
con.A_ΔŨmax
661-
con.A_Ymin
662-
con.A_Ymax
663-
con.A_x̂min
664-
con.A_x̂max
665-
]
678+
# --- quadratic programming Hessian matrix ---
679+
= init_quadprog(model, mpc.weights, mpc.Ẽ, mpc.P̃Δu, mpc.P̃u)
680+
mpc.H̃ .=
681+
# --- JuMP optimization ---
666682
Z̃var::Vector{JuMP.VariableRef} = optim[:Z̃var]
667683
A = con.A[con.i_b, :]
668684
b = con.b[con.i_b]
669685
# deletion is required for sparse solvers like OSQP, when the sparsity pattern changes
670686
JuMP.delete(optim, optim[:linconstraint])
671687
JuMP.unregister(optim, :linconstraint)
672688
@constraint(optim, linconstraint, A*Z̃var .≤ b)
673-
Aeq = con.Aeq
674-
beq = con.beq
675689
JuMP.delete(optim, optim[:linconstrainteq])
676690
JuMP.unregister(optim, :linconstrainteq)
677-
@constraint(optim, linconstrainteq, Aeq*Z̃var .== beq)
678-
# --- quadratic programming Hessian matrix ---
679-
= init_quadprog(model, mpc.weights, mpc.Ẽ, mpc.P̃Δu, mpc.P̃u)
680-
mpc.H̃ .=
691+
@constraint(optim, linconstrainteq, con.Aeq*Z̃var .== con.beq)
681692
set_objective_hessian!(mpc, Z̃var)
682693
return nothing
683694
end

test/3_test_predictive_control.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,17 @@ end
436436
@test mpc.weights.M_Hp diagm(1:1000)
437437
@test mpc.weights.Ñ_Hc diagm([0.1;1e6])
438438
@test mpc.weights.L_Hp diagm(1.1:1000.1)
439+
440+
estim2 = KalmanFilter(LinModel(tf(5, [2, 1]), 3))
441+
mpc_ms = LinMPC(estim2, Nwt=[0], Hp=1000, Hc=1, transcription=MultipleShooting())
442+
r = [15]
443+
preparestate!(mpc_ms, [0])
444+
u = moveinput!(mpc_ms, r)
445+
@test u [3] atol=1e-2
446+
setmodel!(mpc_ms, LinModel(tf(10, [2, 1]), 3))
447+
r = [40]
448+
u = moveinput!(mpc_ms, r)
449+
@test u [4] atol=1e-2
439450
end
440451

441452
@testitem "LinMPC real-time simulations" setup=[SetupMPCtests] begin

0 commit comments

Comments
 (0)