Skip to content

Commit aff625b

Browse files
authored
Merge pull request #241 from JuliaControl/simplify_op
changed: `f̂ ` now internally handle the operating points
2 parents 14766cb + 11d4f9e commit aff625b

File tree

5 files changed

+31
-22
lines changed

5 files changed

+31
-22
lines changed

src/controller/transcription.jl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,7 +1159,6 @@ function predict!(
11591159
k0 = @views K0[(1 + nk*(j-1)):(nk*j)]
11601160
x̂0next = @views X̂0[(1 + nx̂*(j-1)):(nx̂*j)]
11611161
f̂!(x̂0next, û0, k0, mpc.estim, model, x̂0, u0, d0)
1162-
x̂0next .+= mpc.estim.f̂op .- mpc.estim.x̂op
11631162
x̂0 = @views X̂0[(1 + nx̂*(j-1)):(nx̂*j)]
11641163
d0 = @views D̂0[(1 + nd*(j-1)):(nd*j)]
11651164
ŷ0 = @views Ŷ0[(1 + ny*(j-1)):(ny*j)]
@@ -1318,8 +1317,6 @@ function con_nonlinprogeq!(
13181317
x̂0next_Z̃ = @views X̂0_Z̃[(1 + nx̂*(j-1)):(nx̂*j)]
13191318
ŝnext = @views geq[(1 + nx̂*(j-1)):(nx̂*j)]
13201319
f̂!(x̂0next, û0, k0, mpc.estim, model, x̂0, u0, d0)
1321-
# handle operating points (but should be zeros for NonLinModel):
1322-
x̂0next .+= mpc.estim.f̂op .- mpc.estim.x̂op
13231320
ŝnext .= x̂0next .- x̂0next_Z̃
13241321
x̂0 = x̂0next_Z̃ # using states in Z̃ for next iteration (allow parallel for)
13251322
d0 = d0next

src/estimator/execute.jl

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,19 @@ end
1919
Mutating state function ``\mathbf{f̂}`` of the augmented model.
2020
2121
By introducing an augmented state vector ``\mathbf{x̂_0}`` like in [`augment_model`](@ref),
22-
the function returns the next state of the augmented model, defined as:
22+
the function returns the next state of the augmented model, as deviation vectors:
2323
```math
2424
\begin{aligned}
25-
\mathbf{x̂_0}(k+1) &= \mathbf{f̂}\Big(\mathbf{x̂_0}(k), \mathbf{u_0}(k), \mathbf{d_0}(k)\Big) \\
25+
\mathbf{x̂_0}(k+1) &= \mathbf{f̂}\Big(\mathbf{x̂_0}(k), \mathbf{u_0}(k), \mathbf{d_0}(k)\Big)
2626
\mathbf{ŷ_0}(k) &= \mathbf{ĥ}\Big(\mathbf{x̂_0}(k), \mathbf{d_0}(k)\Big)
2727
\end{aligned}
2828
```
2929
where ``\mathbf{x̂_0}(k+1)`` is stored in `x̂0next` argument. The method mutates `x̂0next`,
3030
`û0` and `k0` in place. The argument `û0` stores the disturbed input of the augmented model
3131
``\mathbf{û_0}``, and `k0`, the intermediate stage values of `model.solver`, when applicable.
32-
The model parameter `model.p` is not included in the function signature for conciseness. See
33-
Extended Help for details on ``\mathbf{û_0, f̂}`` and ``\mathbf{ĥ}`` implementations.
32+
The model parameter `model.p` is not included in the function signature for conciseness.
33+
The operating points are handled inside ``\mathbf{f̂}``. See Extended Help for details on
34+
``\mathbf{û_0, f̂}`` and ``\mathbf{ĥ}`` implementations.
3435
3536
# Extended Help
3637
!!! details "Extended Help"
@@ -41,7 +42,8 @@ Extended Help for details on ``\mathbf{û_0, f̂}`` and ``\mathbf{ĥ}`` implem
4142
\begin{aligned}
4243
\mathbf{f̂}\Big(\mathbf{x̂_0}(k), \mathbf{u_0}(k), \mathbf{d_0}(k)\Big) &= \begin{bmatrix}
4344
\mathbf{f}\Big(\mathbf{x_0}(k), \mathbf{û_0}(k), \mathbf{d_0}(k), \mathbf{p}\Big) \\
44-
\mathbf{A_s} \mathbf{x_s}(k) \end{bmatrix} \\
45+
\mathbf{A_s} \mathbf{x_s}(k) \end{bmatrix}
46+
+ \mathbf{f̂_{op}} - \mathbf{x̂_{op}} \\
4547
\mathbf{ĥ}\Big(\mathbf{x̂_0}(k), \mathbf{d_0}(k)\Big) &=
4648
\mathbf{h}\Big(\mathbf{x_0}(k), \mathbf{d_0}(k), \mathbf{p}\Big) + \mathbf{y_{s_y}}(k)
4749
\end{aligned}
@@ -55,37 +57,41 @@ Extended Help for details on ``\mathbf{û_0, f̂}`` and ``\mathbf{ĥ}`` implem
5557
\end{aligned}
5658
```
5759
The ``\mathbf{f}`` and ``\mathbf{h}`` functions above are in fact the [`f!`](@ref) and
58-
[`h!`](@ref) methods, respectively.
60+
[`h!`](@ref) methods, respectively. The operating points ``\mathbf{x̂_{op}, f̂_{op}}``
61+
are computed by [`augment_model`](@ref) (almost always zeros in practice for
62+
[`NonLinModel`](@ref)).
5963
"""
6064
function f̂!(x̂0next, û0, k0, estim::StateEstimator, model::SimModel, x̂0, u0, d0)
61-
return f̂!(x̂0next, û0, k0, model, estim.As, estim.Cs_u, x̂0, u0, d0)
65+
return f̂!(x̂0next, û0, k0, model, estim.As, estim.Cs_u, estim.f̂op, estim.x̂op, x̂0, u0, d0)
6266
end
6367

6468
"""
6569
f̂!(x̂0next, _ , _ , estim::StateEstimator, model::LinModel, x̂0, u0, d0) -> nothing
6670
67-
Use the augmented model matrices if `model` is a [`LinModel`](@ref).
71+
Use the augmented model matrices and operating points if `model` is a [`LinModel`](@ref).
6872
"""
6973
function f̂!(x̂0next, _ , _ , estim::StateEstimator, ::LinModel, x̂0, u0, d0)
7074
mul!(x̂0next, estim.Â, x̂0)
7175
mul!(x̂0next, estim.B̂u, u0, 1, 1)
7276
mul!(x̂0next, estim.B̂d, d0, 1, 1)
77+
x̂0next .+= estim.f̂op .- estim.x̂op
7378
return nothing
7479
end
7580

7681
"""
77-
f̂!(x̂0next, û0, k0, model::SimModel, As, Cs_u, x̂0, u0, d0)
82+
f̂!(x̂0next, û0, k0, model::SimModel, As, Cs_u, f̂op, x̂op, x̂0, u0, d0)
7883
7984
Same than [`f̂!`](@ref) for [`SimModel`](@ref) but without the `estim` argument.
8085
"""
81-
function f̂!(x̂0next, û0, k0, model::SimModel, As, Cs_u, x̂0, u0, d0)
86+
function f̂!(x̂0next, û0, k0, model::SimModel, As, Cs_u, f̂op, x̂op, x̂0, u0, d0)
8287
# `@views` macro avoid copies with matrix slice operator e.g. [a:b]
8388
@views xd, xs = x̂0[1:model.nx], x̂0[model.nx+1:end]
8489
@views xdnext, xsnext = x̂0next[1:model.nx], x̂0next[model.nx+1:end]
8590
mul!(û0, Cs_u, xs) # ys_u = Cs_u*xs
8691
û0 .+= u0 # û0 = u0 + ys_u
8792
f!(xdnext, k0, model, xd, û0, d0, model.p)
8893
mul!(xsnext, As, xs)
94+
x̂0next .+= f̂op .- x̂op
8995
return nothing
9096
end
9197

src/estimator/internal_model.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,10 @@ State function ``\mathbf{f̂}`` of [`InternalModel`](@ref) for [`NonLinModel`](@
172172
173173
It calls [`f!`](@ref) directly since this estimator does not augment the states.
174174
"""
175-
function f̂!(x̂0next, _ , k0, ::InternalModel, model::NonLinModel, x̂0, u0, d0)
176-
return f!(x̂0next, k0, model, x̂0, u0, d0, model.p)
175+
function f̂!(x̂0next, _ , k0, estim::InternalModel, model::NonLinModel, x̂0, u0, d0)
176+
f!(x̂0next, k0, model, x̂0, u0, d0, model.p)
177+
x̂0next .+= estim.f̂op .- estim.x̂op
178+
return x̂0next
177179
end
178180

179181
@doc raw"""

src/estimator/kalman.jl

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,6 @@ function update_estimate!(estim::UnscentedKalmanFilter, y0m, d0, u0)
867867
P̂next = estim.buffer.
868868
mul!(P̂next, X̄0next, Ŝ_X̄0nextᵀ)
869869
P̂next .+=
870-
x̂0next .+= estim.f̂op .- estim.x̂op
871870
estim.x̂0 .= x̂0next
872871
estim.cov.P̂ .= Hermitian(P̂next, :L)
873872
return nothing
@@ -1068,11 +1067,17 @@ objects with the linearization points.
10681067
"""
10691068
function get_ekf_linfunc(NT, model, i_ym, nint_u, nint_ym, jacobian)
10701069
As, Cs_u, Cs_y = init_estimstoch(model, i_ym, nint_u, nint_ym)
1071-
f̂_ekf!(x̂0next, x̂0, û0, k0, u0, d0) = f̂!(x̂0next, û0, k0, model, As, Cs_u, x̂0, u0, d0)
1072-
ĥ_ekf!(ŷ0, x̂0, d0) = ĥ!(ŷ0, model, Cs_y, x̂0, d0)
1070+
nxs = size(As, 1)
1071+
x̂op, f̂op = [model.xop; zeros(nxs)], [model.fop; zeros(nxs)]
1072+
f̂_ekf!(x̂0next, x̂0, û0, k0, u0, d0) = f̂!(
1073+
x̂0next, û0, k0, model, As, Cs_u, f̂op, x̂op, x̂0, u0, d0
1074+
)
1075+
ĥ_ekf!(ŷ0, x̂0, d0) = ĥ!(
1076+
ŷ0, model, Cs_y, x̂0, d0
1077+
)
10731078
strict = Val(true)
10741079
nu, ny, nd, nk = model.nu, model.ny, model.nd, model.nk
1075-
nx̂ = model.nx + size(As, 1)
1080+
nx̂ = model.nx + nxs
10761081
x̂0next = zeros(NT, nx̂)
10771082
ŷ0 = zeros(NT, ny)
10781083
x̂0 = zeros(NT, nx̂)
@@ -1232,7 +1237,6 @@ function predict_estimate_kf!(estim::Union{KalmanFilter, ExtendedKalmanFilter},
12321237
mul!(Â_P̂corr_Âᵀ, Â, P̂corr_Âᵀ)
12331238
P̂next = estim.buffer.
12341239
P̂next .= Â_P̂corr_Âᵀ .+
1235-
x̂0next .+= estim.f̂op .- estim.x̂op
12361240
estim.x̂0 .= x̂0next
12371241
estim.cov.P̂ .= Hermitian(P̂next, :L)
12381242
return nothing

src/estimator/mhe/execute.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ function predict!(V̂, X̂0, û0, k0, ŷ0, estim::MovingHorizonEstimator, mode
610610
= @views Z̃[(1 + nx̃ + nŵ*(j-1)):(nx̃ + nŵ*j)]
611611
x̂0next = @views X̂0[(1 + nx̂ *(j-1)):(nx̂ *j)]
612612
f̂!(x̂0next, û0, k0, estim, model, x̂0, u0, d0)
613-
x̂0next .+= .+ estim.f̂op .- estim.x̂op
613+
x̂0next .+=
614614
y0nextm = @views estim.Y0m[(1 + nym * (j-1)):(nym*j)]
615615
d0next = @views estim.D0[(1 + nd*j):(nd*(j+1))]
616616
ĥ!(ŷ0next, estim, model, x̂0next, d0next)
@@ -629,7 +629,7 @@ function predict!(V̂, X̂0, û0, k0, ŷ0, estim::MovingHorizonEstimator, mode
629629
V̂[(1 + nym*(j-1)):(nym*j)] .= y0m .- ŷ0m
630630
x̂0next = @views X̂0[(1 + nx̂ *(j-1)):(nx̂ *j)]
631631
f̂!(x̂0next, û0, k0, estim, model, x̂0, u0, d0)
632-
x̂0next .+= .+ estim.f̂op .- estim.x̂op
632+
x̂0next .+=
633633
x̂0 = x̂0next
634634
end
635635
end

0 commit comments

Comments
 (0)