Closed franckgaga closed 3 months ago
The way I have it setup in LowLevelParticleFilters.jl is to offer predict!
and correct!
, but also an update!
that performs them both. This package could do something similar, in which case all estimators would support predict/correct except for MHE which only supports the combined update. Having them separate when possible is nice since it offers a lot of flexibility in how the estimator is used, enabling things like
In principle, a moving-horizon estimator can also perform both of those steps, the correction involves solving the optimization problem, while the prediction only advances the state using the internal prediction model.
It's not quite clear to me what the function evalstate!
does, would postupdate!
and preupdate!
be descriptive names? Alternatively, predict_and_correct! / correct_and_predict!
to make it abundantly clear what's happening, at the expense of some verbosity?
Alright thanks for your tips!
Clearly, I will implement the predict!
and correct!
functions, but it will be in a new minor version, a bit later.
For now, I'll just code the current-form for all the observers in the package.
@baggepinnen Another point, I'm thinking on switching to the current form by default (to remove the one sample delay). Do you agree with this breaking change ?
And about that, why did you chose the the delayed form by default in kalman
and place
function of ControlSystemsBase.jl
?
Do you agree with this breaking change ?
I do
why did you chose the the delayed form by default in kalman and place function of ControlSystemsBase.jl ?
I didn't, this precedes my involvement in the package. The choice was likely made to conform to other similar toolboxes. The solution to the standard Ricatti equation also gives you the delayed form, so it makes sense to have that be the default there I guess.
Okay after some deep reflection (sadly also in the night, the static gain on my brain is sometimes zero haha) here is what would be the new API for state estimation:
I purposefully avoided the "correct" and "predict" keyword in the API, to avoid possible confusion with your toolbox and similar toolboxes. Moreover, I will presumably add these two functions latter in the API.
For now, my goal is to create a simple API that works for all the state estimators, no matter if it's in the current or delayed form. This way, a user can write its own for loop with e.g. setpoint bumps and disturbances, and switch the estimator inside the constructor, before the for loop. The code inside the for loop will still work without any change. Here's the new API:
for i = 1:100
ry = ... # current output setpoints
ym, d = ... # current measured outputs and disturbances
preparestate!(mpc, ym, d) # compute x̂(k|k) in the current form, do nothing in the delayed form
u = moveinput!(mpc, ry, d)
# sending the current manipulated inputs to the plant...
updatestate!(mpc, u, ym, d) # compute x̂(k+1|k), this method will always do something (with more computations in the delayed form)
end
My initial idea was to move everything in the moveinput!
function (that's what MATLAB do for linear MPC). But I don't like this idea since it mixes the concept of estimation and control, meaning that the estimator cannot be used without a mpc controller. I also like that updatestate!
is always called at the end of the for loop, no matter if its a StateEstimator
or a SimModel
object.
P.S.:
In principle, a moving-horizon estimator can also perform both of those steps, the correction involves solving the optimization problem, while the prediction only advances the state using the internal prediction model.
Doing that would neglect the constraints on the state estimate during the prediction step.
I finished the implementation for all the estimators except the MHE. Thanks for the tips, it does clearly improve the closed-loop performance for e.g. disturbance rejection. The detailed equations are also documented in the internal documentation.
Cool, Nice work!
Disturbance rejection when there is no measurement of the disturbance relies solely on the measurement feedback, so it makes sense that reacting to this one sample earlier improves the rejection 😊
Hello @baggepinnen,
I'm working in implementing the current form for all the estimators in the package. Two points about that:
1- The
predict
andcorrect
is a good idea except for theMovingHorizonEstimator
: this separation is impossible afaik. It needs to be a single function that solve the full optimization problem over the window $N_k$. I prefer to have a uniform API for all the state estimators. About the possible confusion between the current and delayed form: I'm hesitating between keeping theupdatestate!
method for both forms (and it should be called before or aftermoveintput
, depending on the chosen form, a bit more confusing IMO but simpler API). The other option would be to create a new method for the current form e.g.evalstate!
. Do you have a preference or other ideas ?2- After these new features are merged, I feel like it would be a good timing to move to v1. The user base seems to be growing according to stars and I'm not a fan of keeping packages in v0 eternally.