5555Construct a manual state estimator for `model` ([`LinModel`](@ref) or [`NonLinModel`](@ref)).
5656
5757This [`StateEstimator`](@ref) type allows the construction of [`PredictiveController`](@ref)
58- objects but turns off the built-in state estimation. The user must manually provides the
58+ objects but turns off the built-in state estimation. The user must manually provides the
5959estimate ``\m athbf{x̂}_{k}(k)`` or ``\m athbf{x̂}_{k-1}(k)`` through [`setstate!`](@ref) at
60- each time step. Calling [`preparestate!`](@ref) and [`updatestate!`](@ref) will not modify
61- the estimate. See Extended Help for usage examples.
60+ each time step ``k``. The states in the estimator must obviously represent the same thing as
61+ in the controller, both for the deterministic and the stochastic model of the unmeasured
62+ disturbances (`nint_u` and `nint_ym` arguments). Calling [`preparestate!`](@ref) and
63+ [`updatestate!`](@ref) on this object will do nothing at all. See Extended Help for usage
64+ examples.
6265
6366# Arguments
6467- `model::SimModel` : (deterministic) model for the estimations.
@@ -84,13 +87,51 @@ ManualEstimator estimator with a sample time Ts = 0.5 s, LinModel and:
8487
8588# Extended Help
8689!!! details "Extended Help"
87- A first use case is a linear predictive controller based on nonlinear state estimation.
88- The [`ManualEstimator`](@ref) serves as a wrapper to provide the minimal required
89- information to construct a [`PredictiveController`](@ref). e.g.:
90+ A first use case is a linear predictive controller based on nonlinear state estimation,
91+ for example a nonlinear [`MovingHorizonEstimator`](@ref) (MHE). Note that the model
92+ augmentation scheme with `nint_u` and `nint_ym` options must be identical for both
93+ [`StateEstimator`](@ref) objects (see [`SteadyKalmanFilter`](@ref) extended help for
94+ details on augmentation). The [`ManualEstimator`](@ref) serves as a wrapper to provide
95+ the minimal required information to construct any [`PredictiveController`](@ref) object:
9096
91- ```julia
92- a=1
97+ ```jldoctest
98+ julia> function man_sim()
99+ f(x,u,_,_) = 0.5*sin.(x + u)
100+ h(x,_,_) = x
101+ model = NonLinModel(f, h, 10.0, 1, 1, 1, solver=nothing)
102+ linModel = linearize(model, x=[0], u=[0])
103+ man = ManualEstimator(linModel, nint_u=[1])
104+ mpc = LinMPC(man)
105+ estim = MovingHorizonEstimator(model, nint_u=[1], He=5)
106+ estim = setconstraint!(estim, v̂min=[-0.001], v̂max=[0.001])
107+ initstate!(estim, [0], [0])
108+ y_data, ŷ_data = zeros(5), zeros(5)
109+ for i=1:5
110+ y = model() # simulated measurement
111+ x̂ = preparestate!(estim, y) # correct nonlinear MHE state estimate
112+ ŷ = estim() # nonlinear MHE estimated output
113+ setstate!(mpc, x̂) # update MPC with the MHE corrected state
114+ u = moveinput!(mpc, [0])
115+ y_data[i], ŷ_data[i] = y[1], ŷ[1]
116+ updatestate!(estim, u, y) # update nonlinear MHE estimation
117+ updatestate!(model, u .+ 0.5) # update simulator with load disturbance
118+ end
119+ return collect([y_data ŷ_data]')
120+ end;
121+
122+ julia> YandŶ = round.(man_sim(), digits=6)
123+ 2×5 Matrix{Float64}:
124+ 0.0 0.239713 0.227556 0.157837 0.098629
125+ -0.0 0.238713 0.226556 0.156837 0.097629
93126 ```
127+
128+ A second use case is to allow the user to manually provide the state estimate computed
129+ from an external source, e.g. an observer from [`LowLevelParticleFilters`](@extref LowLevelParticleFilters).
130+ A custom stochastic model for the unmeasured disturbances (other than integrated white
131+ noise) can be specified by constructing a [`SimModel`](@ref) object with the augmented
132+ state-space matrices/functions directly, and by setting `nint_u=0` and `nint_ym=0`. See
133+ [`Disturbance-gallery`](@extref LowLevelParticleFilters) for examples of other
134+ disturbance models.
94135"""
95136function ManualEstimator (
96137 model:: SM ;
0 commit comments