Skip to content

Commit 4ab5d3b

Browse files
authored
Merge pull request #321 from JuliaControl/debug_imc_colloc
debug: `InternalModel` with `TrapezoidalCollocation` now works
2 parents bf93872 + 4c35776 commit 4ab5d3b

5 files changed

Lines changed: 48 additions & 11 deletions

File tree

Project.toml

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

66
[deps]

src/controller/transcription.jl

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,7 +1264,6 @@ function con_nonlinprogeq!(
12641264
nΔU, nX̂ = nu*Hc, nx̂*Hp
12651265
f_threads = transcription.f_threads
12661266
Ts, p = model.Ts, model.p
1267-
As, Cs_u = mpc.estim.As, mpc.estim.Cs_u
12681267
nk = get_nk(model, transcription)
12691268
D̂0 = mpc.D̂0
12701269
X̂0_Z̃ = @views Z̃[(nΔU+1):(nΔU+nX̂)]
@@ -1281,19 +1280,18 @@ function con_nonlinprogeq!(
12811280
x̂0next = @views X̂0[(1 + nx̂*(j-1)):(nx̂*j)]
12821281
x̂0next_Z̃ = @views X̂0_Z̃[(1 + nx̂*(j-1)):(nx̂*j)]
12831282
ŝnext = @views geq[(1 + nx̂*(j-1)):(nx̂*j)]
1284-
x0, xs = @views x̂0[1:nx], x̂0[nx+1:end]
1283+
x0 = @views x̂0[1:nx]
1284+
xsnext = @views x̂0next[nx+1:end]
12851285
x0next_Z̃, xsnext_Z̃ = @views x̂0next_Z̃[1:nx], x̂0next_Z̃[nx+1:end]
12861286
sdnext, ssnext = @views ŝnext[1:nx], ŝnext[nx+1:end]
12871287
k1, k2 = @views k0[1:nx], k0[nx+1:2*nx]
12881288
# ----------------- stochastic defects -----------------------------------------
1289-
xsnext = @views x̂0next[nx+1:end]
1290-
mul!(xsnext, As, xs)
1289+
fs!(x̂0next, mpc.estim, model, x̂0)
12911290
ssnext .= @. xsnext - xsnext_Z̃
12921291
# ----------------- deterministic defects --------------------------------------
12931292
u0 = @views U0[(1 + nu*(j-1)):(nu*j)]
12941293
û0 = @views Û0[(1 + nu*(j-1)):(nu*j)]
1295-
mul!(û0, Cs_u, xs) # ys_u(k) = Cs_u*xs(k)
1296-
û0 .+= u0 # û0(k) = u0(k) + ys_u(k)
1294+
f̂_input!(û0, mpc.estim, model, x̂0, u0)
12971295
if f_threads || h < 1 || j < 2
12981296
# we need to recompute k1 with multi-threading, even with h==1, since the
12991297
# last iteration (j-1) may not be executed (iterations are re-orderable)
@@ -1307,8 +1305,7 @@ function con_nonlinprogeq!(
13071305
else
13081306
u0next = @views U0[(1 + nu*j):(nu*(j+1))]
13091307
û0next = @views Û0[(1 + nu*j):(nu*(j+1))]
1310-
mul!(û0next, Cs_u, xsnext_Z̃) # ys_u(k+1) = Cs_u*xs(k+1)
1311-
û0next .+= u0next # û0(k+1) = u0(k+1) + ys_u(k+1)
1308+
f̂_input!(û0next, mpc.estim, model, x̂0next_Z̃, u0next)
13121309
end
13131310
model.f!(k2, x0next_Z̃, û0next, d̂0next, p)
13141311
sdnext .= @. x0 - x0next_Z̃ + 0.5*Ts*(k1 + k2)

src/estimator/execute.jl

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,31 @@ function f̂!(x̂0next, û0, k0, model::SimModel, As, Cs_u, f̂op, x̂op, x̂0,
108108
return nothing
109109
end
110110

111+
#TODO: delete the following two generic functions and replace with linear eq. constraints
112+
113+
"""
114+
fs!(x̂0next, estim::StateEstimator, model::SimModel, x̂0) -> nothing
115+
116+
State update function of the stochastic model only.
117+
"""
118+
function fs!(x̂0next, estim::StateEstimator, model::SimModel, x̂0)
119+
xs, xsnext = @views x̂0[model.nx+1:end], x̂0next[model.nx+1:end]
120+
mul!(xsnext, estim.As, xs)
121+
return nothing
122+
end
123+
124+
@doc raw"""
125+
f̂_input!(û0, estim::StateEstimator, model::SimModel, x̂0, u0) -> nothing
126+
127+
Compute the disturbed input of the augmented model ``\mathbf{û_0}`` from `x̂0` and `u0`.
128+
"""
129+
function f̂_input!(û0, estim::StateEstimator, model::SimModel, x̂0, u0)
130+
xs = @views x̂0[model.nx+1:end]
131+
mul!(û0, estim.Cs_u, xs) # ys_u = Cs_u*xs
132+
û0 .+= u0 # û0 = u0 + ys_u
133+
return nothing
134+
end
135+
111136
@doc raw"""
112137
ĥ!(ŷ0, estim::StateEstimator, model::SimModel, x̂0, d0) -> nothing
113138
@@ -141,7 +166,6 @@ function ĥ!(ŷ0, model::SimModel, Cs_y, x̂0, d0)
141166
return nothing
142167
end
143168

144-
145169
@doc raw"""
146170
initstate!(estim::StateEstimator, u, ym, d=[]) -> x̂
147171

src/estimator/internal_model.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,22 @@ function f̂!(x̂0next, _ , k0, estim::InternalModel, model::NonLinModel, x̂0,
180180
return nothing
181181
end
182182

183+
#TODO: delete the following 2 generic functions and replace with linear eq. constraints.
184+
185+
"""
186+
fs!(x̂0next, estim::InternalModel, model::SimModel, _ ) -> nothing
187+
188+
Does nothing since [`InternalModel`](@ref) does not augment the state vector.
189+
"""
190+
fs!( _ , ::InternalModel, ::SimModel, _ ) = nothing
191+
192+
@doc raw"""
193+
f̂_input!(û0, estim::InternalModel, model::SimModel, x̂0, u0) -> nothing
194+
195+
Compute `û0 .= u0` since [`InternalModel`](@ref) does not augment the state vector.
196+
"""
197+
f̂_input!(û0, ::InternalModel, ::SimModel, _ , u0) = (û0 .= u0; nothing)
198+
183199
@doc raw"""
184200
ĥ!(ŷ0, estim::InternalModel, model::NonLinModel, x̂0, d0)
185201

test/3_test_predictive_control.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,7 @@ end
989989
@test u [1.0] atol=5e-2
990990

991991
transcription = TrapezoidalCollocation(1)
992-
nmpc5_1 = NonLinMPC(nonlinmodel_c; Nwt=[0], Hp=100, Hc=1, transcription)
992+
nmpc5_1 = NonLinMPC(InternalModel(nonlinmodel_c); Nwt=[0], Hp=100, Hc=1, transcription)
993993
preparestate!(nmpc5_1, [0.0])
994994
u = moveinput!(nmpc5_1, [1/0.001])
995995
@test u [1.0] atol=5e-2

0 commit comments

Comments
 (0)