Skip to content

Commit 3726017

Browse files
committed
added: ensure that sum(nb)==Hp
1 parent 2667e0d commit 3726017

File tree

5 files changed

+55
-11
lines changed

5 files changed

+55
-11
lines changed

src/controller/construct.jl

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -457,9 +457,53 @@ end
457457
estimate_delays(::SimModel) = 0
458458

459459

460-
"Get move blocking vector `nb` and actual `Hc` value from provided `Hc_arg` argument"
461-
move_blocking(Hc_arg::AbstractVector{Int}) = (Hc_arg, length(nb))
462-
move_blocking(Hc_arg::Int) = (fill(1, length(Hc_arg)), Hc_arg)
460+
"""
461+
move_blocking(Hp::Int, Hc::AbstractVector{Int}) -> nb, Hc
462+
463+
Get move blocking vector `nb` and actual control horizon from `Hp` and `Hc` arguments.
464+
465+
The argument `Hc` is in fact the move blocking vector `nb` provided by the user. The `nb`
466+
vector is modified in these two cases:
467+
468+
- If `sum(nb) < Hp`, a new element is added to `nb` with the value `Hp - sum(nb)`.
469+
- If `sum(nb) > Hp`, the intervals are truncated until the sum is `Hp`. For example, if
470+
`Hp = 10` and `nb = [1, 2, 3, 6, 7]`, then `nb` is truncated to `[1, 2, 3, 4]`.
471+
"""
472+
function move_blocking(Hp_arg::Int, Hc_arg::AbstractVector{Int})
473+
Hp = Hp_arg
474+
nb = Hc_arg
475+
if sum(nb) < Hp
476+
newblock = [Hp - sum(nb)]
477+
nb = [nb; newblock]
478+
elseif sum(nb) > Hp
479+
#For example, if Hp = 10 and nb = [1, 2, 3, 6, 7], than nb is truncated to [1, 2, 3, 4]
480+
nb = nb[begin:findfirst((Hp), cumsum(nb))]
481+
if sum(nb) > Hp
482+
# if the last block is too large, it is truncated to fit Hp:
483+
nb[end] = Hp - @views sum(nb[begin:end-1])
484+
end
485+
end
486+
Hc = length(nb)
487+
return nb, Hc
488+
end
489+
490+
"""
491+
move_blocking(Hp::Int, Hc::Int) -> nb, Hc
492+
493+
Construct a move blocking vector `nb` to fit the provides `Hp` and `Hc` horizons.
494+
495+
The vector is filled with `1`s for the first `Hc` blocks. If `Hc < Hp`, the last block in
496+
`nb` is set to `Hp - Hc` to ensure the total sum is `Hp`.
497+
"""
498+
function move_blocking(Hp_arg::Int, Hc_arg::Int)
499+
Hp, Hc = Hp_arg, Hc_arg
500+
nb = fill(1, Hc_arg)
501+
if Hc < Hp
502+
newblock = Hp - Hc
503+
nb = [nb; newblock]
504+
end
505+
return nb, Hc
506+
end
463507

464508

465509
"""

src/controller/explicitmpc.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ struct ExplicitMPC{
5151
lastu0 = zeros(NT, nu)
5252
transcription = SingleShooting() # explicit MPC only supports SingleShooting
5353
PΔu = init_ZtoΔU(estim, transcription, Hp, Hc)
54-
Pu, Tu = init_ZtoU(estim, transcription, Hp, Hc)
54+
Pu, Tu = init_ZtoU(estim, transcription, Hp, Hc, nb)
5555
E, G, J, K, V, B = init_predmat(model, estim, transcription, Hp, Hc)
5656
# dummy val (updated just before optimization):
5757
F = zeros(NT, ny*Hp)
@@ -167,7 +167,7 @@ function ExplicitMPC(
167167
@warn("prediction horizon Hp ($Hp) ≤ estimated number of delays in model "*
168168
"($nk), the closed-loop system may be unstable or zero-gain (unresponsive)")
169169
end
170-
nb, Hc = move_blocking(Hc)
170+
nb, Hc = move_blocking(Hp, Hc)
171171
weights = ControllerWeights{NT}(estim.model, Hp, Hc, M_Hp, N_Hc, L_Hp)
172172
return ExplicitMPC{NT}(estim, Hp, Hc, nb, weights)
173173
end

src/controller/linmpc.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ struct LinMPC{
6464
R̂y, R̂u, Tu_lastu0 = zeros(NT, ny*Hp), zeros(NT, nu*Hp), zeros(NT, nu*Hp)
6565
lastu0 = zeros(NT, nu)
6666
PΔu = init_ZtoΔU(estim, transcription, Hp, Hc)
67-
Pu, Tu = init_ZtoU(estim, transcription, Hp, Hc)
67+
Pu, Tu = init_ZtoU(estim, transcription, Hp, Hc, nb)
6868
E, G, J, K, V, B, ex̂, gx̂, jx̂, kx̂, vx̂, bx̂ = init_predmat(
6969
model, estim, transcription, Hp, Hc
7070
)
@@ -267,7 +267,7 @@ function LinMPC(
267267
@warn("prediction horizon Hp ($Hp) ≤ estimated number of delays in model "*
268268
"($nk), the closed-loop system may be unstable or zero-gain (unresponsive)")
269269
end
270-
nb, Hc = move_blocking(Hc)
270+
nb, Hc = move_blocking(Hp, Hc)
271271
weights = ControllerWeights{NT}(estim.model, Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt)
272272
return LinMPC{NT}(estim, Hp, Hc, nb, weights, transcription, optim)
273273
end

src/controller/nonlinmpc.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ struct NonLinMPC{
8787
R̂y, R̂u, Tu_lastu0 = zeros(NT, ny*Hp), zeros(NT, nu*Hp), zeros(NT, nu*Hp)
8888
lastu0 = zeros(NT, nu)
8989
PΔu = init_ZtoΔU(estim, transcription, Hp, Hc)
90-
Pu, Tu = init_ZtoU(estim, transcription, Hp, Hc)
90+
Pu, Tu = init_ZtoU(estim, transcription, Hp, Hc, nb)
9191
E, G, J, K, V, B, ex̂, gx̂, jx̂, kx̂, vx̂, bx̂ = init_predmat(
9292
model, estim, transcription, Hp, Hc
9393
)
@@ -366,7 +366,7 @@ function NonLinMPC(
366366
@warn("prediction horizon Hp ($Hp) ≤ estimated number of delays in model "*
367367
"($nk), the closed-loop system may be unstable or zero-gain (unresponsive)")
368368
end
369-
nb, Hc = move_blocking(Hc)
369+
nb, Hc = move_blocking(Hp, Hc)
370370
validate_JE(NT, JE)
371371
gc! = get_mutating_gc(NT, gc)
372372
weights = ControllerWeights{NT}(estim.model, Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt)

src/controller/transcription.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ function init_ZtoΔU(
121121
end
122122

123123
@doc raw"""
124-
init_ZtoU(estim, transcription, Hp, Hc) -> Pu, Tu
124+
init_ZtoU(estim, transcription, Hp, Hc, nb) -> Pu, Tu
125125
126126
Init decision variables to inputs over ``H_p`` conversion matrices.
127127
@@ -164,7 +164,7 @@ The ``\mathbf{P_u}`` and ``\mathbf{T_u}`` matrices are defined in the Extended H
164164
if `transcription` is a [`MultipleShooting`](@ref)
165165
"""
166166
function init_ZtoU(
167-
estim::StateEstimator{NT}, transcription::TranscriptionMethod, Hp, Hc
167+
estim::StateEstimator{NT}, transcription::TranscriptionMethod, Hp, Hc, nb
168168
) where {NT<:Real}
169169
model = estim.model
170170
# Pu and Tu are `Matrix{NT}`, conversion is faster than `Matrix{Bool}` or `BitMatrix`

0 commit comments

Comments
 (0)