Skip to content

Commit 5f3a969

Browse files
authored
Merge pull request #240 from JuliaControl/doc_transcription
doc: describing the internal of the various prediction and transcription methods
2 parents aff625b + bd1b9f6 commit 5f3a969

File tree

8 files changed

+126
-52
lines changed

8 files changed

+126
-52
lines changed

Project.toml

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

66
[deps]
77
ControlSystemsBase = "aaaaaaaa-a6ca-5380-bf3e-84a91bcd477e"

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ for more detailed examples.
115115
- supported transcription methods of the optimization problem:
116116
- direct single shooting
117117
- direct multiple shooting
118+
- trapezoidal collocation
118119
- additional information about the optimum to ease troubleshooting
119120
- real-time control loop features:
120121
- implementations that carefully limits the allocations

docs/src/internals/predictive_control.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,8 @@ ModelPredictiveControl.linconstrainteq!
4141
```@docs
4242
ModelPredictiveControl.optim_objective!(::PredictiveController)
4343
ModelPredictiveControl.set_warmstart!
44+
ModelPredictiveControl.predict!
45+
ModelPredictiveControl.con_nonlinprog!
46+
ModelPredictiveControl.con_nonlinprogeq!
4447
ModelPredictiveControl.getinput!
4548
```

docs/src/internals/state_estim.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ ModelPredictiveControl.linconstraint!(::MovingHorizonEstimator, ::LinModel)
4040
```@docs
4141
ModelPredictiveControl.optim_objective!(::MovingHorizonEstimator)
4242
ModelPredictiveControl.set_warmstart_mhe!
43+
ModelPredictiveControl.predict_mhe!
44+
ModelPredictiveControl.con_nonlinprog_mhe!
4345
```
4446

4547
## Remove Operating Points

src/controller/transcription.jl

Lines changed: 66 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ order hold) between the samples, but linear interpolation will be added soon.
7575
7676
This transcription computes the predictions by calling the continuous-time model in the
7777
equality constraint function and by using the implicit trapezoidal rule. It can handle
78-
moderately stiff systems and is A-stable. However, it may not be as efficient as more
79-
advanced collocation methods for highly stiff systems. Note that the built-in [`StateEstimator`](@ref)
78+
moderately stiff systems and is A-stable. Note that the built-in [`StateEstimator`](@ref)
8079
will still use the `solver` provided at the construction of the [`NonLinModel`](@ref) to
8180
estimate the plant states, not the trapezoidal rule (see `supersample` option of
8281
[`RungeKutta`](@ref) for stiff systems). See Extended Help for more details.
@@ -89,7 +88,8 @@ transcription method.
8988
Note that the stochastic model of the unmeasured disturbances is strictly discrete-time,
9089
as described in [`ModelPredictiveControl.init_estimstoch`](@ref). Collocation methods
9190
require continuous-time dynamics. Because of this, the stochastic states are transcribed
92-
separately using a [`MultipleShooting`](@ref) method.
91+
separately using a [`MultipleShooting`](@ref) method. See [`con_nonlinprogeq!`](@ref)
92+
for more details.
9393
"""
9494
struct TrapezoidalCollocation <: CollocationMethod
9595
nc::Int
@@ -1119,8 +1119,14 @@ getU0!(U0, mpc::PredictiveController, Z̃) = (mul!(U0, mpc.P̃u, Z̃) .+ mpc.Tu_
11191119
Compute the predictions `Ŷ0`, terminal states `x̂0end` if model is a [`LinModel`](@ref).
11201120
11211121
The method mutates `Ŷ0` and `x̂0end` vector arguments. The `x̂end` vector is used for
1122-
the terminal constraints applied on ``\mathbf{x̂}_{k-1}(k+H_p)``. The computations are
1123-
identical for any [`TranscriptionMethod`](@ref) if the model is linear.
1122+
the terminal constraints applied on ``\mathbf{x̂_0}(k+H_p)``. The computations are
1123+
identical for any [`TranscriptionMethod`](@ref) if the model is linear:
1124+
```math
1125+
\begin{aligned}
1126+
\mathbf{Ŷ_0} &= \mathbf{Ẽ Z̃} + \mathbf{F} \\
1127+
\mathbf{x̂_0}(k+H_p) &= \mathbf{ẽ_x̂ Z̃} + \mathbf{f_x̂}
1128+
\end{aligned}
1129+
```
11241130
"""
11251131
function predict!(
11261132
Ŷ0, x̂0end, _, _, _,
@@ -1142,7 +1148,14 @@ end
11421148
11431149
Compute vectors if `model` is a [`NonLinModel`](@ref) and for [`SingleShooting`](@ref).
11441150
1145-
The method mutates `Ŷ0`, `x̂0end`, `X̂0`, `Û0` and `K0` arguments.
1151+
The method mutates `Ŷ0`, `x̂0end`, `X̂0`, `Û0` and `K0` arguments. The augmented model of
1152+
[`f̂!`](@ref) and [`ĥ!`](@ref) functions is called recursively in a `for` loop:
1153+
```math
1154+
\begin{aligned}
1155+
\mathbf{x̂_0}(k+1) &= \mathbf{f̂}\Big(\mathbf{x̂_0}(k), \mathbf{u_0}(k), \mathbf{d_0}(k) \Big) \\
1156+
\mathbf{ŷ_0}(k) &= \mathbf{ĥ}\Big(\mathbf{x̂_0}(k), \mathbf{d_0}(k) \Big)
1157+
\end{aligned}
1158+
```
11461159
"""
11471160
function predict!(
11481161
Ŷ0, x̂0end, X̂0, Û0, K0,
@@ -1173,17 +1186,22 @@ end
11731186
predict!(
11741187
Ŷ0, x̂0end, _ , _ , _ ,
11751188
mpc::PredictiveController, model::NonLinModel, transcription::TranscriptionMethod,
1176-
U0, Z̃
1189+
_ , Z̃
11771190
) -> Ŷ0, x̂0end
11781191
11791192
Compute vectors if `model` is a [`NonLinModel`](@ref) and other [`TranscriptionMethod`](@ref).
11801193
1181-
The method mutates `Ŷ0` and `x̂0end` arguments.
1194+
The method mutates `Ŷ0` and `x̂0end` arguments. The augmented output function [`ĥ!`](@ref)
1195+
is called multiple times in a `for` loop:
1196+
```math
1197+
\mathbf{ŷ_0}(k) = \mathbf{ĥ}\Big(\mathbf{x̂_0^†}(k+j), \mathbf{d_0}(k) \Big)
1198+
```
1199+
in which ``\mathbf{x̂_0^†}`` is the augmented state extracted from the decision variable `Z̃`.
11821200
"""
11831201
function predict!(
11841202
Ŷ0, x̂0end, _, _, _,
11851203
mpc::PredictiveController, model::NonLinModel, ::TranscriptionMethod,
1186-
U0, Z̃
1204+
_ , Z̃
11871205
)
11881206
nu, ny, nd, nx̂, Hp, Hc = model.nu, model.ny, model.nd, mpc.estim.nx̂, mpc.Hp, mpc.Hc
11891207
X̂0 = @views Z̃[(nu*Hc+1):(nu*Hc+nx̂*Hp)] # Z̃ = [ΔU; X̂0; ϵ]
@@ -1208,7 +1226,7 @@ end
12081226
Nonlinear constrains when `model` is a [`LinModel`](@ref).
12091227
12101228
The method mutates the `g` vectors in argument and returns it. Only the custom constraints
1211-
are include in the `g` vector.
1229+
`gc` are include in the `g` vector.
12121230
"""
12131231
function con_nonlinprog!(
12141232
g, ::PredictiveController, ::LinModel, ::TranscriptionMethod, _ , _ , gc, ϵ
@@ -1285,7 +1303,7 @@ function con_nonlinprog!(
12851303
return g
12861304
end
12871305

1288-
"""
1306+
@doc raw"""
12891307
con_nonlinprogeq!(
12901308
geq, X̂0, Û0, K0
12911309
mpc::PredictiveController, model::NonLinModel, transcription::MultipleShooting,
@@ -1294,7 +1312,14 @@ end
12941312
12951313
Nonlinear equality constrains for [`NonLinModel`](@ref) and [`MultipleShooting`](@ref).
12961314
1297-
The method mutates the `geq`, `X̂0`, `Û0` and `K0` vectors in argument.
1315+
The method mutates the `geq`, `X̂0`, `Û0` and `K0` vectors in argument. The nonlinear
1316+
equality constraints `geq` only includes the augmented state defects, computed with:
1317+
```math
1318+
\mathbf{ŝ}(k+1) = \mathbf{f̂}\Big(\mathbf{x̂_0}(k), \mathbf{u_0}(k), \mathbf{d_0}(k)\Big)
1319+
- \mathbf{x̂_0^†}(k+1)
1320+
```
1321+
in which ``\mathbf{x̂_0^†}`` is the augmented state extracted from the decision variables
1322+
`Z̃`, and ``\mathbf{f̂}``, the augmented state function defined in [`f̂!`](@ref).
12981323
"""
12991324
function con_nonlinprogeq!(
13001325
geq, X̂0, Û0, K0,
@@ -1333,21 +1358,33 @@ end
13331358
13341359
Nonlinear equality constrains for [`NonLinModel`](@ref) and [`TrapezoidalCollocation`](@ref).
13351360
1336-
The method mutates the `geq`, `X̂0`, `Û0` and `K0` vectors in argument. The deterministic
1337-
and stochastic states are handled separately since collocation methods require
1338-
continuous-time state-space models, and the stochastic model of the unmeasured disturbances
1339-
is discrete-time. Also note that operating points in `model` are typically zeros for
1340-
[`NonLinModel`](@ref), but they are handled rigorously here if it's not the case. It should
1341-
be noted that linearization of continuous-time dynamics at non-equilibrium points leads to:
1361+
The method mutates the `geq`, `X̂0`, `Û0` and `K0` vectors in argument.
1362+
1363+
The nonlinear equality constraints `geq` only includes the state defects. The deterministic
1364+
and stochastic states are handled separately since collocation methods require continuous-
1365+
time state-space models, and the stochastic model of the unmeasured disturbances
1366+
is discrete-time. The deterministic and stochastic defects are respectively computed with:
13421367
```math
1343-
\mathbf{ẋ_0}(t) ≈ \mathbf{A x_0}(t) + \mathbf{B_u u_0}(t) + \mathbf{B_d d_0}(t)
1368+
\begin{aligned}
1369+
\mathbf{s_d}(k+1) &= \mathbf{x_0}(k) - \mathbf{x_0^†}(k+1)
1370+
+ 0.5 T_s (\mathbf{k}_1 + \mathbf{k}_2) \\
1371+
\mathbf{s_s}(k+1) &= \mathbf{A_s x_s}(k) - \mathbf{x_s^†}(k+1)
1372+
\end{aligned}
13441373
```
1345-
as opposed to, for discrete-time models:
1374+
in which ``\mathbf{x_0^†}`` and ``\mathbf{x_s^†}`` are the deterministic and stochastic
1375+
states extracted from the decision variables `Z̃`. The ``\mathbf{k}`` coefficients are
1376+
evaluated from the continuous-time function `model.f!` and:
13461377
```math
1347-
\mathbf{x_0}(k+1) ≈ \mathbf{A x_0}(k) + \mathbf{B_u u_0}(k) + \mathbf{B_d d_0}(k)
1348-
+ \mathbf{f_{op}} - \mathbf{x_{op}}
1378+
\begin{aligned}
1379+
\mathbf{k}_1 &= \mathbf{f}\Big(\mathbf{x_0}(k), \mathbf{û_0}(k), \mathbf{d_0}(k) \Big) \\
1380+
\mathbf{k}_2 &= \mathbf{f}\Big(\mathbf{x_0^†}(k+1), \mathbf{û_0}(k), \mathbf{d_0}(k+1)\Big)
1381+
\end{aligned}
13491382
```
1350-
hence no need to add `model.fop` and subtract `model.xop` in the collocation equations.
1383+
and the input of the augmented model is:
1384+
```math
1385+
\mathbf{û_0}(k) = \mathbf{u_0}(k) + \mathbf{C_{s_u} x_s}(k)
1386+
```
1387+
the ``\mathbf{A_s, C_{s_u}}`` matrices are defined in [`init_estimstoch`](@ref) doc.
13511388
"""
13521389
function con_nonlinprogeq!(
13531390
geq, X̂0, Û0, K0,
@@ -1378,17 +1415,18 @@ function con_nonlinprogeq!(
13781415
sdnext, ssnext = @views ŝnext[1:nx], ŝnext[nx+1:end]
13791416
mul!(û0, Cs_u, xs) # ys_u = Cs_u*xs
13801417
û0 .+= u0 # û0 = u0 + ys_u
1381-
ẋ0, ẋ0next = @views k0[1:nx], k0[nx+1:2*nx]
1382-
# no need to handle model.fop and model.xop, see docstring:
1383-
model.f!(ẋ0, xd, û0, d0, p)
1384-
model.f!(ẋ0next, xdnext_Z̃, û0, d0next, p) # assuming ZOH on manipulated inputs u
1418+
k1, k2 = @views k0[1:nx], k0[nx+1:2*nx]
1419+
model.f!(k1, xd, û0, d0, p)
1420+
model.f!(k2, xdnext_Z̃, û0, d0next, p) # assuming ZOH on manipulated inputs u
13851421
xsnext = @views x̂0next[nx+1:end]
13861422
mul!(xsnext, As, xs)
1387-
sdnext .= @. xd - xdnext_Z̃ + (Ts/2)*(ẋ0 + ẋ0next)
1423+
sdnext .= @. xd - xdnext_Z̃ + (Ts/2)*(k1 + k2)
13881424
ssnext .= @. xsnext - xsnext_Z̃
13891425
x̂0 = x̂0next_Z̃ # using states in Z̃ for next iteration (allow parallel for)
13901426
d0 = d0next
13911427
end
13921428
return geq
13931429
end
1430+
1431+
"No eq. constraints for other cases e.g. [`SingleShooting`](@ref), returns `geq` unchanged."
13941432
con_nonlinprogeq!(geq,_,_,_,::PredictiveController,::SimModel,::TranscriptionMethod,_,_)=geq

src/estimator/construct.jl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -356,11 +356,14 @@ end
356356
"""
357357
default_nint(model::SimModel, i_ym=1:model.ny, nint_u=0)
358358
359-
One integrator on each measured output by default if `model` is not a [`LinModel`](@ref).
359+
One integrator on each measured output by default for other cases e.g. [`NonLinModel`](@ref).
360360
361-
Theres is no verification the augmented model remains observable. If the integrator quantity
362-
per manipulated input `nint_u ≠ 0`, the method returns zero integrator on each measured
363-
output.
361+
If the integrator quantity per manipulated input `nint_u ≠ 0`, the method returns zero
362+
integrator on each measured output.
363+
364+
!!! warning
365+
Theres is no verification the augmented model remains observable. The resulting
366+
[`StateEstimator`](@ref) object should be assessed separately with e.g.: [`sim!`](@ref).
364367
"""
365368
function default_nint(model::SimModel, i_ym=1:model.ny, nint_u=0)
366369
validate_ym(model, i_ym)

src/estimator/execute.jl

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ By introducing an augmented state vector ``\mathbf{x̂_0}`` like in [`augment_mo
2222
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
```
@@ -65,10 +65,23 @@ function f̂!(x̂0next, û0, k0, estim::StateEstimator, model::SimModel, x̂0,
6565
return f̂!(x̂0next, û0, k0, model, estim.As, estim.Cs_u, estim.f̂op, estim.x̂op, x̂0, u0, d0)
6666
end
6767

68-
"""
68+
@doc raw"""
6969
f̂!(x̂0next, _ , _ , estim::StateEstimator, model::LinModel, x̂0, u0, d0) -> nothing
7070
7171
Use the augmented model matrices and operating points if `model` is a [`LinModel`](@ref).
72+
73+
# Extended Help
74+
!!! details "Extended Help"
75+
76+
This method computes:
77+
```math
78+
\begin{aligned}
79+
\mathbf{x̂_0}(k+1) &= \mathbf{Â x̂_0}(k) + \mathbf{B̂_u u_0}(k) + \mathbf{B̂_d d_0}(k)
80+
+ \mathbf{f̂_{op}} - \mathbf{x̂_{op}} \\
81+
\mathbf{ŷ_0}(k) &= \mathbf{Ĉ x̂_0}(k) + \mathbf{D̂_d d_0}(k)
82+
\end{aligned}
83+
```
84+
with the augmented matrices constructed by [`augment_model`](@ref).
7285
"""
7386
function f̂!(x̂0next, _ , _ , estim::StateEstimator, ::LinModel, x̂0, u0, d0)
7487
mul!(x̂0next, estim.Â, x̂0)

src/estimator/mhe/execute.jl

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ function getinfo(estim::MovingHorizonEstimator{NT}) where NT<:Real
115115
info = Dict{Symbol, Any}()
116116
V̂, X̂0 = similar(estim.Y0m[1:nym*Nk]), similar(estim.X̂0[1:nx̂*Nk])
117117
û0, k0, ŷ0 = buffer.û, buffer.k, buffer.
118-
V̂, X̂0 = predict!(V̂, X̂0, û0, k0, ŷ0, estim, model, estim.Z̃)
118+
V̂, X̂0 = predict_mhe!(V̂, X̂0, û0, k0, ŷ0, estim, model, estim.Z̃)
119119
x̂0arr = @views estim.Z̃[nx̃-nx̂+1:nx̃]
120120
= estim.x̂0arr_old - x̂0arr
121121
X̂0 = [x̂0arr; X̂0]
@@ -418,7 +418,7 @@ function optim_objective!(estim::MovingHorizonEstimator{NT}) where NT<:Real
418418
# --------- update estimate -----------------------
419419
û0, ŷ0, k0 = buffer.û, buffer.ŷ, buffer.k
420420
estim.Ŵ[1:nŵ*Nk] .= @views estim.Z̃[nx̃+1:nx̃+nŵ*Nk] # update Ŵ with optimum for warm-start
421-
V̂, X̂0 = predict!(V̂, X̂0, û0, k0, ŷ0, estim, model, estim.Z̃)
421+
V̂, X̂0 = predict_mhe!(V̂, X̂0, û0, k0, ŷ0, estim, model, estim.Z̃)
422422
x̂0next = @views X̂0[end-nx̂+1:end]
423423
estim.x̂0 .= x̂0next
424424
return estim.
@@ -461,7 +461,7 @@ function set_warmstart_mhe!(V̂, X̂0, estim::MovingHorizonEstimator{NT}, Z̃var
461461
# --- process noise estimates Ŵ ---
462462
Z̃s[nx̃+1:end] = estim.
463463
# verify definiteness of objective function:
464-
V̂, X̂0 = predict!(V̂, X̂0, û0, k0, ŷ0, estim, model, Z̃s)
464+
V̂, X̂0 = predict_mhe!(V̂, X̂0, û0, k0, ŷ0, estim, model, Z̃s)
465465
Js = obj_nonlinprog!(x̄, estim, model, V̂, Z̃s)
466466
if !isfinite(Js)
467467
Z̃s[nx̃+1:end] = 0
@@ -578,16 +578,22 @@ function obj_nonlinprog!(
578578
return dot(x̄, invP̄, x̄) + dot(Ŵ, invQ̂_Nk, Ŵ) + dot(V̂, invR̂_Nk, V̂) +
579579
end
580580

581-
"""
582-
predict!(V̂, X̂0, û0, k0, ŷ0, estim::MovingHorizonEstimator, model::LinModel, Z̃) -> V̂, X̂0
581+
@doc raw"""
582+
predict_mhe!(V̂, X̂0, _, _, _, estim::MovingHorizonEstimator, model::LinModel, Z̃) -> V̂, X̂0
583583
584584
Compute the `V̂` vector and `X̂0` vectors for the `MovingHorizonEstimator` and `LinModel`.
585585
586-
The function mutates `V̂`, `X̂0`, `û0` and `ŷ0` vector arguments. The vector `V̂` is the
587-
estimated sensor noises from ``k-N_k+1`` to ``k``. The `X̂0` vector is estimated states from
588-
``k-N_k+2`` to ``k+1``.
586+
The function mutates `V̂` and `X̂0` vector arguments. The vector `V̂` is the estimated sensor
587+
noises from ``k-N_k+1`` to ``k``. The `X̂0` vector is estimated states from ``k-N_k+2`` to
588+
``k+1``. The computations are (by truncating the matrices when `N_k < H_e`):
589+
```math
590+
\begin{aligned}
591+
\mathbf{V̂} &= \mathbf{Ẽ Z̃} + \mathbf{F} \\
592+
\mathbf{X̂_0} &= \mathbf{Ẽ_x̂ Z̃} + \mathbf{F_x̂}
593+
\end{aligned}
594+
```
589595
"""
590-
function predict!(V̂, X̂0, _ , _ , _ , estim::MovingHorizonEstimator, ::LinModel, Z̃)
596+
function predict_mhe!(V̂, X̂0, _ , _ , _ , estim::MovingHorizonEstimator, ::LinModel, Z̃)
591597
nϵ, Nk = estim.nϵ, estim.Nk[]
592598
nX̂, nŴ, nYm = estim.nx̂*Nk, estim.nx̂*Nk, estim.nym*Nk
593599
nZ̃ =+ estim.nx̂ + nŴ
@@ -596,8 +602,16 @@ function predict!(V̂, X̂0, _ , _ , _ , estim::MovingHorizonEstimator, ::LinMod
596602
return V̂, X̂0
597603
end
598604

599-
"Compute the two vectors when `model` is not a `LinModel`."
600-
function predict!(V̂, X̂0, û0, k0, ŷ0, estim::MovingHorizonEstimator, model::SimModel, Z̃)
605+
@doc raw"""
606+
predict_mhe!(V̂, X̂0, û0, k0, ŷ0, estim::MovingHorizonEstimator, model::SimModel, Z̃) -> V̂, X̂0
607+
608+
Compute the vectors when `model` is *not* a [`LinModel`](@ref).
609+
610+
The function mutates `V̂`, `X̂0`, `û0` and `ŷ0` vector arguments. The augmented model of
611+
[`f̂!`](@ref) and [`ĥ!`](@ref) is called recursively in a `for` loop from ``j=1`` to ``N_k``,
612+
and by adding the estimated process noise ``\mathbf{ŵ}``.
613+
"""
614+
function predict_mhe!(V̂, X̂0, û0, k0, ŷ0, estim::MovingHorizonEstimator, model::SimModel, Z̃)
601615
nϵ, Nk = estim.nϵ, estim.Nk[]
602616
nu, nd, nx̂, nŵ, nym = model.nu, model.nd, estim.nx̂, estim.nx̂, estim.nym
603617
nx̃ =+ nx̂
@@ -646,18 +660,18 @@ The method mutates all the arguments before `estim` argument.
646660
"""
647661
function update_prediction!(V̂, X̂0, û0, k0, ŷ0, g, estim::MovingHorizonEstimator, Z̃)
648662
model = estim.model
649-
V̂, X̂0 = predict!(V̂, X̂0, û0, k0, ŷ0, estim, model, Z̃)
663+
V̂, X̂0 = predict_mhe!(V̂, X̂0, û0, k0, ŷ0, estim, model, Z̃)
650664
ϵ = getϵ(estim, Z̃)
651-
g = con_nonlinprog!(g, estim, model, X̂0, V̂, ϵ)
665+
g = con_nonlinprog_mhe!(g, estim, model, X̂0, V̂, ϵ)
652666
return nothing
653667
end
654668

655669
"""
656-
con_nonlinprog!(g, estim::MovingHorizonEstimator, model::SimModel, X̂0, V̂, ϵ)
670+
con_nonlinprog_mhe!(g, estim::MovingHorizonEstimator, model::SimModel, X̂0, V̂, ϵ) -> g
657671
658-
Nonlinear constrains for [`MovingHorizonEstimator`](@ref).
672+
Compute nonlinear constrains `g` in-place for [`MovingHorizonEstimator`](@ref).
659673
"""
660-
function con_nonlinprog!(g, estim::MovingHorizonEstimator, ::SimModel, X̂0, V̂, ϵ)
674+
function con_nonlinprog_mhe!(g, estim::MovingHorizonEstimator, ::SimModel, X̂0, V̂, ϵ)
661675
nX̂con, nX̂ = length(estim.con.X̂0min), estim.nx̂ *estim.Nk[]
662676
nV̂con, nV̂ = length(estim.con.V̂min), estim.nym*estim.Nk[]
663677
for i in eachindex(g)
@@ -684,7 +698,7 @@ function con_nonlinprog!(g, estim::MovingHorizonEstimator, ::SimModel, X̂0, V̂
684698
end
685699

686700
"No nonlinear constraints if `model` is a [`LinModel`](@ref), return `g` unchanged."
687-
con_nonlinprog!(g, ::MovingHorizonEstimator, ::LinModel, _ , _ , _ ) = g
701+
con_nonlinprog_mhe!(g, ::MovingHorizonEstimator, ::LinModel, _ , _ , _ ) = g
688702

689703
"Throw an error if P̂ != nothing."
690704
function setstate_cov!(::MovingHorizonEstimator, P̂)

0 commit comments

Comments
 (0)