Skip to content

Commit 8e7b41f

Browse files
committed
MultipleShooting with LinMPC starts to work 🎉
1 parent 3db0f96 commit 8e7b41f

File tree

2 files changed

+25
-13
lines changed

2 files changed

+25
-13
lines changed

src/controller/execute.jl

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ end
473473
474474
Optimize the objective function of `mpc` [`PredictiveController`](@ref) and return the solution `Z̃`.
475475
476-
If first warm-starts the solver with [`set_warm_start!`](@ref). It then calls
476+
If first warm-starts the solver with [`set_warmstart!`](@ref). It then calls
477477
`JuMP.optimize!(mpc.optim)` and extract the solution. A failed optimization prints an
478478
`@error` log in the REPL and returns the warm-start value. A failed optimization also prints
479479
[`getinfo`](@ref) results in the debug log [if activated](https://docs.julialang.org/en/v1/stdlib/Logging/#Example:-Enable-debug-level-messages).
@@ -741,17 +741,22 @@ function setmodel_controller!(mpc::PredictiveController, x̂op_old)
741741
con.A_x̂min
742742
con.A_x̂max
743743
]
744+
Z̃var::Vector{JuMP.VariableRef} = optim[:Z̃var]
744745
A = con.A[con.i_b, :]
745746
b = con.b[con.i_b]
746-
ΔŨvar::Vector{JuMP.VariableRef} = optim[:ΔŨvar]
747747
# deletion is required for sparse solvers like OSQP, when the sparsity pattern changes
748748
JuMP.delete(optim, optim[:linconstraint])
749749
JuMP.unregister(optim, :linconstraint)
750-
@constraint(optim, linconstraint, A*ΔŨvar .≤ b)
750+
@constraint(optim, linconstraint, A*Z̃var .≤ b)
751+
Aeq = con.Aeq
752+
beq = con.beq
753+
JuMP.delete(optim, optim[:linconstrainteq])
754+
JuMP.unregister(optim, :linconstrainteq)
755+
@constraint(optim, linconstrainteq, Aeq*Z̃var .== beq)
751756
# --- quadratic programming Hessian matrix ---
752757
= init_quadprog(model, mpc.weights, mpc.Ẽ. mpc.P̃, mpc.S̃)
753758
mpc.H̃ .=
754-
set_objective_hessian!(mpc, ΔŨvar)
759+
set_objective_hessian!(mpc, Z̃var)
755760
return nothing
756761
end
757762

src/controller/transcription.jl

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -283,14 +283,14 @@ function init_predmat(
283283
Âpow_csum = cumsum(Âpow, dims=3)
284284
# helper function to improve code clarity and be similar to eqs. in docstring:
285285
getpower(array3D, power) = @views array3D[:,:, power+1]
286-
# --- state estimates ---
286+
# --- current state estimates x̂0 ---
287287
kx̂ = getpower(Âpow, Hp)
288288
K = Matrix{NT}(undef, Hp*ny, nx̂)
289289
for j=1:Hp
290290
iRow = (1:ny) .+ ny*(j-1)
291291
K[iRow,:] =*getpower(Âpow, j)
292292
end
293-
# --- manipulated inputs u ---
293+
# --- previous manipulated inputs lastu0 ---
294294
vx̂ = getpower(Âpow_csum, Hp-1)*B̂u
295295
V = Matrix{NT}(undef, Hp*ny, nu)
296296
for j=1:Hp
@@ -306,7 +306,7 @@ function init_predmat(
306306
E[iRow, iCol] = V[iRow .- ny*(j-1),:]
307307
ex̂[: , iCol] = getpower(Âpow_csum, Hp-j)*B̂u
308308
end
309-
# --- measured disturbances d ---
309+
# --- current measured disturbances d0 and predictions D̂0 ---
310310
gx̂ = getpower(Âpow, Hp-1)*B̂d
311311
G = Matrix{NT}(undef, Hp*ny, nd)
312312
jx̂ = Matrix{NT}(undef, nx̂, Hp*nd)
@@ -348,16 +348,16 @@ function init_predmat(
348348
) where {NT<:Real}
349349
Ĉ, D̂d = estim.Ĉ, estim.D̂d
350350
nu, nx̂, ny, nd = model.nu, estim.nx̂, model.ny, model.nd
351-
# --- state estimates ---
351+
# --- current state estimates x̂0 ---
352352
K = zeros(NT, Hp*ny, nx̂)
353353
kx̂ = zeros(NT, nx̂, nx̂)
354-
# --- manipulated inputs u ---
354+
# --- previous manipulated inputs lastu0 ---
355355
V = zeros(NT, Hp*ny, nu)
356356
vx̂ = zeros(NT, nx̂, nu)
357357
# --- decision variables Z ---
358358
E = [zeros(NT, Hp*ny, Hc*nu) repeatdiag(Ĉ, Hp)]
359359
ex̂ = [zeros(NT, nx̂, Hc*nu + (Hp-1)*nx̂) I]
360-
# --- measured disturbances d ---
360+
# --- current measured disturbances d0 and predictions D̂0 ---
361361
G = zeros(NT, Hp*ny, nd)
362362
gx̂ = zeros(NT, nx̂, nd)
363363
J = repeatdiag(D̂d, Hp)
@@ -451,6 +451,7 @@ matrices ``\mathbf{E_ŝ, G_ŝ, J_ŝ, K_ŝ, V_ŝ, B_ŝ}`` are defined in th
451451
\mathbf{E_ŝ} &= \begin{bmatrix}
452452
\mathbf{B̂_u} & \mathbf{0} & \cdots & \mathbf{0} & -\mathbf{I} & \mathbf{0} & \cdots & \mathbf{0} \\
453453
\mathbf{B̂_u} & \mathbf{B̂_u} & \cdots & \mathbf{0} & \mathbf{Â} & -\mathbf{I} & \cdots & \mathbf{0} \\
454+
\mathbf{B̂_u} & \mathbf{B̂_u} & \cdots & \mathbf{0} & \mathbf{0} & \mathbf{Â} & \cdots & \mathbf{0} \\
454455
\vdots & \vdots & \ddots & \vdots & \vdots & \vdots & \ddots & \vdots \\
455456
\mathbf{B̂_u} & \mathbf{B̂_u} & \cdots & \mathbf{B̂_u} & \mathbf{0} & \mathbf{0} & \cdots & -\mathbf{I} \end{bmatrix} \\
456457
\mathbf{G_ŝ} &= \begin{bmatrix}
@@ -474,9 +475,9 @@ function init_defectmat(
474475
) where {NT<:Real}
475476
nu, nx̂, nd = model.nu, estim.nx̂, model.nd
476477
Â, B̂u, B̂d = estim.Â, estim.B̂u, estim.B̂d
477-
# --- state estimates ---
478+
# --- current state estimates x̂0 ---
478479
Kŝ = [Â; zeros(NT, nx̂*(Hp-1), nx̂)]
479-
# --- manipulated inputs u ---
480+
# --- previous manipulated inputs lastu0 ---
480481
Vŝ = repeat(B̂u, Hp)
481482
# --- decision variables Z ---
482483
nI_nx̂ = Matrix{NT}(-I, nx̂, nx̂)
@@ -486,7 +487,13 @@ function init_defectmat(
486487
iCol = (1:nu) .+ nu*(j-1)
487488
Eŝ[iRow, iCol] = B̂u
488489
end
489-
# --- measured disturbances d ---
490+
for j=1:Hp-1
491+
iRow = (1:nx̂) .+ nx̂*j
492+
iCol = (1:nx̂) .+ nx̂*(j-1) .+ nu*Hc
493+
Eŝ[iRow, iCol] =
494+
end
495+
display(Eŝ)
496+
# --- current measured disturbances d0 and predictions D̂0 ---
490497
Gŝ = [B̂d; zeros(NT, (Hp-1)*nx̂, nd)]
491498
Jŝ = [zeros(nx̂, nd*Hp); repeatdiag(B̂d, Hp-1) zeros(NT, nx̂*(Hp-1), nd)]
492499
# --- state x̂op and state update f̂op operating points ---

0 commit comments

Comments
 (0)