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,46 @@ 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). The [`ManualEstimator`](@ref)
92+ serves as a wrapper to provide the minimal required information to construct any
93+ [`PredictiveController`](@ref) object, e.g.:
94+ ```jldoctest
95+ f(x,u,_,_) = 0.5*sin.(x + u)
96+ h(x,_,_) = x
97+ model = NonLinModel(f, h, 10.0, 1, 1, 1, solver=nothing)
98+ linModel = linearize(model, x=[0], u=[0])
99+ man = ManualEstimator(linModel, nint_u=[1])
100+ mpc = LinMPC(man)
101+ estim = MovingHorizonEstimator(model, nint_u=[1], He=5)
102+ estim = setconstraint!(estim, v̂min=[-0.001], v̂max=[0.001])
103+ initstate!(estim, [0], [0])
104+ y_data, ŷ_data = zeros(5), zeros(5)
105+ for i=1:5
106+ y = model() # simulated measurement
107+ x̂ = preparestate!(estim, y) # correct nonlinear MHE state estimate
108+ ŷ = estim() # nonlinear MHE estimated output
109+ setstate!(mpc, x̂) # update MPC with the MHE corrected state
110+ u = moveinput!(mpc, [0])
111+ y_data[i], ŷ_data[i] = y[1], ŷ[1]
112+ updatestate!(estim, u, y) # update nonlinear MHE estimation
113+ updatestate!(model, u .+ 0.5) # update plant simulator with load disturbance
114+ end
115+ YandŶ = collect([y_data ŷ_data]')
90116
91- ```julia
92- a=1
117+ # output
118+ 2×5 Matrix{Float64}:
119+ 0.0 0.239713 0.227556 0.157837 0.0986288
120+ -1.41242e-19 0.238713 0.226556 0.156837 0.0976288
93121 ```
122+
123+ A second use case is to allow the user to manually provide the state estimate computed
124+ from an external source, e.g. an observer from [`LowLevelParticleFilters`](@extref LowLevelParticleFilters).
125+ A custom stochastic model for the unmeasured disturbances (other than integrated white
126+ noise) can be specified by constructing a [`SimModel`](@ref) object with the augmented
127+ state-space matrices/functions directly, and by setting `nint_u=0` and `nint_ym=0`. See
128+ [`Disturbance-gallery`](@ext_ref LowLevelParticleFilters) for examples of other
129+ disturbance models.
94130"""
95131function ManualEstimator (
96132 model:: SM ;
0 commit comments