Skip to content

Commit af8de3b

Browse files
committed
debug: getinfo! correct output predictions MPC
1 parent 4fd1054 commit af8de3b

File tree

5 files changed

+34
-28
lines changed

5 files changed

+34
-28
lines changed

src/controller/execute.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,13 @@ function getinfo(mpc::PredictiveController{NT}) where NT<:Real
124124
Ȳ, Ū = similar(mpc.Yop), similar(mpc.Uop)
125125
ΔŨ = Vector{NT}(undef, nΔŨ)
126126
Ŷe, Ue = Vector{NT}(undef, nŶe), Vector{NT}(undef, nUe)
127-
Ŷ0, x̂0end = predict!(Ȳ, x̂0, x̂0next, u0, û0, mpc, model, transcription, Z̃)
128-
ΔŨ, Ŷe, Ue = nonlinprog_vectors!(ΔŨ, Ŷe, Ue, Ū, mpc, Ŷ0, Z̃)
129-
J = obj_nonlinprog!(Ȳ, Ū, mpc, model, Ue, Ŷe, ΔŨ, Z̃)
127+
# careful, 1st arg is Ȳ in NonLinMPC to save memory, but Ŷ0 in this func for clarity:
128+
Ŷ0, x̂0end = predict!(Ŷ0, x̂0next, x̂0, u0, û0, mpc, model, transcription, Z̃)
129+
ΔŨ, Ŷe, Ue = nonlinprog_vectors!(ΔŨ, Ŷe, Ue, Ū, mpc, Ŷ0, Z̃)
130+
J = obj_nonlinprog!(Ȳ, Ū, mpc, model, Ue, Ŷe, ΔŨ, Z̃)
130131
U, Ŷ = Ū, Ȳ
131-
U .= mul!(U, mpc.P̃u, mpc.Z̃) .+ mpc.Tu_lastu
132-
.= Ŷ0 .+ mpc.Yop
132+
U .= mul!(U, mpc.P̃u, Z̃) .+ mpc.Tu_lastu
133+
Ŷ .= Ŷ0 .+ mpc.Yop
133134
predictstoch!(Ŷs, mpc, mpc.estim)
134135
info[:ΔU] = Z̃[1:mpc.Hc*model.nu]
135136
info[] = mpc.== 1 ? mpc.Z̃[end] : zero(NT)

src/controller/explicitmpc.jl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,14 @@ The solution is ``\mathbf{Z̃ = - H̃^{-1} q̃}``, see [`init_quadprog`](@ref).
193193
optim_objective!(mpc::ExplicitMPC) = lmul!(-1, ldiv!(mpc.Z̃, mpc.H̃_chol, mpc.q̃))
194194

195195
"Compute the predictions but not the terminal states if `mpc` is an [`ExplicitMPC`](@ref)."
196-
function predict!(Ŷ, x̂, _ , _ , _ , mpc::ExplicitMPC, ::LinModel, ::TranscriptionMethod, Z̃)
196+
function predict!(
197+
Ŷ0, x̂0next, _ , _ , _ , mpc::ExplicitMPC, ::LinModel, ::TranscriptionMethod, Z̃
198+
)
197199
# in-place operations to reduce allocations :
198-
Ŷ .= mul!(Ŷ, mpc.Ẽ, Z̃) .+ mpc.F
199-
x̂ .= NaN
200-
return Ŷ, x̂
200+
Ŷ0 .= mul!(Ŷ0, mpc.Ẽ, Z̃) .+ mpc.F
201+
x̂0end = x̂0next
202+
x̂0end .= NaN
203+
return Ŷ0, x̂0end
201204
end
202205

203206
"`ExplicitMPC` does not support custom nonlinear constraint, return `true`."

src/controller/nonlinmpc.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ function get_optim_functions(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JNT
551551
x̂0, x̂0next = get_tmp(x̂0_cache, Z̃1), get_tmp(x̂0next_cache, Z̃1)
552552
u0, û0 = get_tmp(u0_cache, Z̃1), get_tmp(û0_cache, Z̃1)
553553
gc, g = get_tmp(gc_cache, Z̃1), get_tmp(g_cache, Z̃1)
554-
Ŷ0, x̂0end = predict!(Ȳ, x̂0, x̂0next, u0, û0, mpc, model, transcription, Z̃)
554+
Ŷ0, x̂0end = predict!(Ȳ, x̂0next, x̂0, u0, û0, mpc, model, transcription, Z̃)
555555
ΔŨ, Ŷe, Ue = nonlinprog_vectors!(ΔŨ, Ŷe, Ue, Ū, mpc, Ŷ0, Z̃)
556556
ϵ = (nϵ 0) ? Z̃[end] : zero(T) # ϵ = 0 if nϵ == 0 (meaning no relaxation)
557557
gc = con_custom!(gc, mpc, Ue, Ŷe, ϵ)

src/controller/transcription.jl

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -607,32 +607,32 @@ end
607607

608608
@doc raw"""
609609
predict!(
610-
Ŷ0, x̂0, _, _, _,
610+
Ŷ0, x̂0next, _, _, _,
611611
mpc::PredictiveController, model::LinModel, transcription::TranscriptionMethod,
612612
613613
) -> Ŷ0, x̂0end
614614
615615
Compute the predictions `Ŷ0` and terminal states `x̂0end` if model is a [`LinModel`](@ref).
616616
617-
The method mutates `Ŷ0` and `x̂0` vector arguments. The `x̂end` vector is used for
617+
The method mutates `Ŷ0` and `x̂0next` vector arguments. The `x̂end` vector is used for
618618
the terminal constraints applied on ``\mathbf{x̂}_{k-1}(k+H_p)``. The computations are
619619
identical for any [`TranscriptionMethod`](@ref).
620620
"""
621621
function predict!(
622-
Ŷ0, x̂0, _ , _ , _ ,
622+
Ŷ0, x̂0next, _ , _ , _ ,
623623
mpc::PredictiveController, ::LinModel, ::TranscriptionMethod,
624624
625625
)
626626
# in-place operations to reduce allocations :
627-
Ŷ0 .= mul!(Ŷ0, mpc.Ẽ, Z̃) .+ mpc.F
628-
x̂0 .= mul!(x̂0, mpc.con.ẽx̂, Z̃) .+ mpc.con.fx̂
629-
x̂0end = x̂0
627+
Ŷ0 .= mul!(Ŷ0, mpc.Ẽ, Z̃) .+ mpc.F
628+
x̂0end = x̂0next
629+
x̂0end .= mul!(x̂0end, mpc.con.ẽx̂, Z̃) .+ mpc.con.fx̂
630630
return Ŷ0, x̂0end
631631
end
632632

633633
@doc raw"""
634634
predict!(
635-
Ŷ0, x̂0, x̂0next, u0, û0,
635+
Ŷ0, x̂0next, x̂0, u0, û0,
636636
mpc::PredictiveController, model::NonLinModel, transcription::SingleShooting,
637637
638638
) -> Ŷ0, x̂0end
@@ -642,7 +642,7 @@ Compute vectors if `model` is a [`NonLinModel`](@ref) and for [`SingleShooting`]
642642
The method mutates `Ŷ0`, `x̂0`, `x̂0next`, `u0` and `û0` arguments.
643643
"""
644644
function predict!(
645-
Ŷ0, x̂0, x̂0next, u0, û0,
645+
Ŷ0, x̂0next, x̂0, u0, û0,
646646
mpc::PredictiveController, model::NonLinModel, ::SingleShooting,
647647
648648
)
@@ -663,37 +663,38 @@ function predict!(
663663
ŷ0 = @views Ŷ0[(1 + ny*(j-1)):(ny*j)]
664664
ĥ!(ŷ0, mpc.estim, model, x̂0, d0)
665665
end
666-
Ŷ0 .+= mpc.F # F = Ŷs if mpc.estim is an InternalModel, else F = 0.
667-
x̂0end = x̂0
666+
Ŷ0 .+= mpc.F # F = Ŷs if mpc.estim is an InternalModel, else F = 0.
667+
x0end = x0next
668668
return Ŷ0, x̂0end
669669
end
670670

671671
@doc raw"""
672672
predict!(
673-
Ŷ0, x̂0, _ , _ , _ ,
673+
Ŷ0, x̂0next, _ , _ , _ ,
674674
mpc::PredictiveController, model::NonLinModel, transcription::MultipleShooting,
675675
676676
) -> Ŷ0, x̂0end
677677
678678
Compute vectors if `model` is a [`NonLinModel`](@ref) and for [`MultipleShooting`](@ref).
679679
680-
The method mutates `Ŷ0` and `x̂0` arguments.
680+
The method mutates `Ŷ0` and `x̂0next` arguments.
681681
"""
682682
function predict!(
683-
Ŷ0, x̂0, x̂0next, u0, û0,
683+
Ŷ0, x̂0next, _, _, _,
684684
mpc::PredictiveController, model::NonLinModel, ::MultipleShooting,
685685
686686
)
687687
nu, ny, nd, nx̂, Hp, Hc = model.nu, model.ny, model.nd, mpc.estim.nx̂, mpc.Hp, mpc.Hc
688688
X̂0 = @views Z̃[(nu*Hc+1):(nu*Hc+nx̂*Hp)] # Z̃ = [ΔU; X̂0; ϵ]
689689
D̂0 = mpc.D̂0
690690
for j=1:Hp
691-
x̂0 .= @views X̂0[(1 + nx̂*(j-1)):(nx̂*j)]
692-
d0 = @views D̂0[(1 + nd*(j-1)):(nd*j)]
693-
ŷ0 = @views Ŷ0[(1 + ny*(j-1)):(ny*j)]
691+
x̂0 = @views X̂0[(1 + nx̂*(j-1)):(nx̂*j)]
692+
d0 = @views D̂0[(1 + nd*(j-1)):(nd*j)]
693+
ŷ0 = @views Ŷ0[(1 + ny*(j-1)):(ny*j)]
694694
ĥ!(ŷ0, mpc.estim, model, x̂0, d0)
695695
end
696-
Ŷ0 .+= mpc.F # F = Ŷs if mpc.estim is an InternalModel, else F = 0.
697-
x̂0end = x̂0
696+
Ŷ0 .+= mpc.F # F = Ŷs if mpc.estim is an InternalModel, else F = 0.
697+
x̂0end = x̂0next
698+
x̂0end .= x̂0
698699
return Ŷ0, x̂0end
699700
end

test/3_test_predictive_control.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,7 @@ end
616616
h = (x,d,_) -> linmodel2.C*x + linmodel2.Dd*d
617617
nonlinmodel = NonLinModel(f, h, 3000.0, 1, 2, 1, 1, solver=nothing)
618618
nmpc2 = NonLinMPC(nonlinmodel, Nwt=[0], Hp=1000, Hc=1)
619+
# if d=[0.1], the output will eventually reach 7*0.1=0.7, no action needed (u=0):
619620
d = [0.1]
620621
preparestate!(nmpc2, [0], d)
621622
u = moveinput!(nmpc2, 7d, d)

0 commit comments

Comments
 (0)