Skip to content

Commit ad12293

Browse files
authored
Merge pull request #234 from JuliaControl/trapezoidal
added: simple `TrapezoidalCollocation()` transcription method
2 parents d92771c + bf181ac commit ad12293

File tree

9 files changed

+281
-135
lines changed

9 files changed

+281
-135
lines changed

.github/workflows/benchmark.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ name: Benchmark
22
on:
33
pull_request_target:
44
branches: [ main ]
5+
concurrency:
6+
# Skip intermediate builds: always.
7+
# Cancel intermediate builds: only if it is a pull request build.
8+
group: ${{ github.workflow }}-${{ github.ref }}
9+
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
510
permissions:
611
pull-requests: write # needed to post comments
712
jobs:

docs/src/public/predictive_control.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,9 @@ SingleShooting
109109
```@docs
110110
MultipleShooting
111111
```
112+
113+
### TrapezoidalCollocation
114+
115+
```@docs
116+
TrapezoidalCollocation
117+
```

src/ModelPredictiveControl.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export MovingHorizonEstimator
3939
export ManualEstimator
4040
export default_nint, initstate!
4141
export PredictiveController, ExplicitMPC, LinMPC, NonLinMPC, setconstraint!, moveinput!
42-
export TranscriptionMethod, SingleShooting, MultipleShooting
42+
export TranscriptionMethod, SingleShooting, MultipleShooting, TrapezoidalCollocation
4343
export SimResult, getinfo, sim!
4444

4545
include("general.jl")

src/controller/construct.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -600,11 +600,11 @@ end
600600
ex̂, fx̂, gx̂, jx̂, kx̂, vx̂, bx̂,
601601
Eŝ, Fŝ, Gŝ, Jŝ, Kŝ, Vŝ, Bŝ,
602602
gc!=nothing, nc=0
603-
) -> con, nϵ, P̃Δu, P̃u, Ẽ, Ẽŝ
603+
) -> con, nϵ, P̃Δu, P̃u, Ẽ
604604
605605
Init `ControllerConstraint` struct with default parameters based on estimator `estim`.
606606
607-
Also return `P̃Δu`, `P̃u`, `Ẽ` and `Ẽŝ` matrices for the the augmented decision vector `Z̃`.
607+
Also return `P̃Δu`, `P̃u` and `` matrices for the the augmented decision vector `Z̃`.
608608
"""
609609
function init_defaultcon_mpc(
610610
estim::StateEstimator{NT},
@@ -660,7 +660,7 @@ function init_defaultcon_mpc(
660660
C_ymin , C_ymax , c_x̂min , c_x̂max , i_g,
661661
gc! , nc
662662
)
663-
return con, nϵ, P̃Δu, P̃u, Ẽ, Ẽŝ
663+
return con, nϵ, P̃Δu, P̃u, Ẽ
664664
end
665665

666666
"Repeat predictive controller constraints over prediction `Hp` and control `Hc` horizons."

src/controller/explicitmpc.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct ExplicitMPC{
5050
R̂y, R̂u, Tu_lastu0 = zeros(NT, ny*Hp), zeros(NT, nu*Hp), zeros(NT, nu*Hp)
5151
lastu0 = zeros(NT, nu)
5252
transcription = SingleShooting() # explicit MPC only supports SingleShooting
53+
validate_transcription(model, transcription)
5354
PΔu = init_ZtoΔU(estim, transcription, Hp, Hc)
5455
Pu, Tu = init_ZtoU(estim, transcription, Hp, Hc, nb)
5556
E, G, J, K, V, B = init_predmat(model, estim, transcription, Hp, Hc)

src/controller/linmpc.jl

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ struct LinMPC{
55
NT<:Real,
66
SE<:StateEstimator,
77
CW<:ControllerWeights,
8-
TM<:TranscriptionMethod,
8+
TM<:ShootingMethod,
99
JM<:JuMP.GenericModel
1010
} <: PredictiveController{NT}
1111
estim::SE
@@ -54,7 +54,7 @@ struct LinMPC{
5454
NT<:Real,
5555
SE<:StateEstimator,
5656
CW<:ControllerWeights,
57-
TM<:TranscriptionMethod,
57+
TM<:ShootingMethod,
5858
JM<:JuMP.GenericModel
5959
}
6060
model = estim.model
@@ -63,6 +63,7 @@ struct LinMPC{
6363
# dummy vals (updated just before optimization):
6464
R̂y, R̂u, Tu_lastu0 = zeros(NT, ny*Hp), zeros(NT, nu*Hp), zeros(NT, nu*Hp)
6565
lastu0 = zeros(NT, nu)
66+
validate_transcription(model, transcription)
6667
PΔu = init_ZtoΔU(estim, transcription, Hp, Hc)
6768
Pu, Tu = init_ZtoU(estim, transcription, Hp, Hc, nb)
6869
E, G, J, K, V, B, ex̂, gx̂, jx̂, kx̂, vx̂, bx̂ = init_predmat(
@@ -71,7 +72,7 @@ struct LinMPC{
7172
Eŝ, Gŝ, Jŝ, Kŝ, Vŝ, Bŝ = init_defectmat(model, estim, transcription, Hp, Hc)
7273
# dummy vals (updated just before optimization):
7374
F, fx̂, Fŝ = zeros(NT, ny*Hp), zeros(NT, nx̂), zeros(NT, nx̂*Hp)
74-
con, nϵ, P̃Δu, P̃u, Ẽ, Ẽŝ = init_defaultcon_mpc(
75+
con, nϵ, P̃Δu, P̃u, Ẽ = init_defaultcon_mpc(
7576
estim, weights, transcription,
7677
Hp, Hc,
7778
PΔu, Pu, E,
@@ -156,7 +157,7 @@ arguments. This controller allocates memory at each time step for the optimizati
156157
- `N_Hc=Diagonal(repeat(Nwt,Hc))` : positive semidefinite symmetric matrix ``\mathbf{N}_{H_c}``.
157158
- `L_Hp=Diagonal(repeat(Lwt,Hp))` : positive semidefinite symmetric matrix ``\mathbf{L}_{H_p}``.
158159
- `Cwt=1e5` : slack variable weight ``C`` (scalar), use `Cwt=Inf` for hard constraints only.
159-
- `transcription=SingleShooting()` : a [`TranscriptionMethod`](@ref) for the optimization.
160+
- `transcription=SingleShooting()` : [`SingleShooting`](@ref) or [`MultipleShooting`](@ref).
160161
- `optim=JuMP.Model(OSQP.MathOptInterfaceOSQP.Optimizer)` : quadratic optimizer used in
161162
the predictive controller, provided as a [`JuMP.Model`](@extref) object (default to
162163
[`OSQP`](https://osqp.org/docs/parsers/jump.html) optimizer).
@@ -215,7 +216,7 @@ function LinMPC(
215216
N_Hc = Diagonal(repeat(Nwt, get_Hc(move_blocking(Hp, Hc)))),
216217
L_Hp = Diagonal(repeat(Lwt, Hp)),
217218
Cwt = DEFAULT_CWT,
218-
transcription::TranscriptionMethod = DEFAULT_LINMPC_TRANSCRIPTION,
219+
transcription::ShootingMethod = DEFAULT_LINMPC_TRANSCRIPTION,
219220
optim::JuMP.GenericModel = JuMP.Model(DEFAULT_LINMPC_OPTIMIZER, add_bridges=false),
220221
kwargs...
221222
)
@@ -259,7 +260,7 @@ function LinMPC(
259260
N_Hc = Diagonal(repeat(Nwt, get_Hc(move_blocking(Hp, Hc)))),
260261
L_Hp = Diagonal(repeat(Lwt, Hp)),
261262
Cwt = DEFAULT_CWT,
262-
transcription::TranscriptionMethod = DEFAULT_LINMPC_TRANSCRIPTION,
263+
transcription::ShootingMethod = DEFAULT_LINMPC_TRANSCRIPTION,
263264
optim::JM = JuMP.Model(DEFAULT_LINMPC_OPTIMIZER, add_bridges=false),
264265
) where {NT<:Real, SE<:StateEstimator{NT}, JM<:JuMP.GenericModel}
265266
isa(estim.model, LinModel) || error(MSG_LINMODEL_ERR)

src/controller/nonlinmpc.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ struct NonLinMPC{
8686
# dummy vals (updated just before optimization):
8787
R̂y, R̂u, Tu_lastu0 = zeros(NT, ny*Hp), zeros(NT, nu*Hp), zeros(NT, nu*Hp)
8888
lastu0 = zeros(NT, nu)
89+
validate_transcription(model, transcription)
8990
PΔu = init_ZtoΔU(estim, transcription, Hp, Hc)
9091
Pu, Tu = init_ZtoU(estim, transcription, Hp, Hc, nb)
9192
E, G, J, K, V, B, ex̂, gx̂, jx̂, kx̂, vx̂, bx̂ = init_predmat(
@@ -94,7 +95,7 @@ struct NonLinMPC{
9495
Eŝ, Gŝ, Jŝ, Kŝ, Vŝ, Bŝ = init_defectmat(model, estim, transcription, Hp, Hc)
9596
# dummy vals (updated just before optimization):
9697
F, fx̂, Fŝ = zeros(NT, ny*Hp), zeros(NT, nx̂), zeros(NT, nx̂*Hp)
97-
con, nϵ, P̃Δu, P̃u, Ẽ, Ẽŝ = init_defaultcon_mpc(
98+
con, nϵ, P̃Δu, P̃u, Ẽ = init_defaultcon_mpc(
9899
estim, weights, transcription,
99100
Hp, Hc,
100101
PΔu, Pu, E,
@@ -561,8 +562,10 @@ Inspired from: [User-defined operators with vector outputs](@extref JuMP User-de
561562
function get_optim_functions(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JNT<:Real
562563
# ----------- common cache for Jfunc, gfuncs and geqfuncs ----------------------------
563564
model = mpc.estim.model
565+
transcription = mpc.transcription
564566
grad, jac = mpc.gradient, mpc.jacobian
565-
nu, ny, nx̂, nϵ, nk = model.nu, model.ny, mpc.estim.nx̂, mpc.nϵ, model.nk
567+
nu, ny, nx̂, nϵ = model.nu, model.ny, mpc.estim.nx̂, mpc.
568+
nk = get_nk(model, transcription)
566569
Hp, Hc = mpc.Hp, mpc.Hc
567570
ng, nc, neq = length(mpc.con.i_g), mpc.con.nc, mpc.con.neq
568571
nZ̃, nU, nŶ, nX̂, nK = length(mpc.Z̃), Hp*nu, Hp*ny, Hp*nx̂, Hp*nk

0 commit comments

Comments
 (0)