-
Notifications
You must be signed in to change notification settings - Fork 16
some more examples of delay problems #165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
baggepinnen
wants to merge
1
commit into
master
Choose a base branch
from
moredelays
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -181,4 +181,66 @@ figsim = simplot(model3, decho, zeros(ss(model3).nx), sysname="ARX") | |
simplot!(model4, decho, zeros(model4.nx), ploty=false, plotu=false, sysname="Subspace") | ||
``` | ||
|
||
Keep in mind that we do not add any disturbance in our simualtions here, and estimating 24:th order models is likely going to be a challenging task in practice. | ||
## Case study: influence of one-sample delay | ||
The following example investigates the influence of an unexpected _single sample_ delay in the estimation of a model for a double-mass system with the velocity of one of the masses as output. The system is available as one of the demo systems in ControlSystems.jl, and its frequency response looks like follows | ||
```@example DELAY | ||
P = DemoSystems.double_mass_model(outputs=2) |> minreal | ||
bp = bodeplot(P, lab="Continuous-time system without delay") | ||
``` | ||
|
||
We now create a discrete-time equivalent to the system, with a one sample delay (0.01s) | ||
```@example DELAY | ||
Ts = 0.01 | ||
Pd = c2d(P*delay(Ts), Ts) | ||
bodeplot!(bp, Pd, lab="Discrete-time system with delay") | ||
``` | ||
Not much changes in the Bode plot, except for at the very highest frequencies, which is exactly what we expect from a one-sample delay. | ||
|
||
We now generate some dataset to use for identification | ||
```@example DELAY | ||
u = sign.(repeat(randn(100), inner=5)) | ||
res = lsim(Pd, u') | ||
plot(res, plotu=true) | ||
``` | ||
|
||
|
||
The first model we'll estimate is an ARX model, i.e., a discrete-time transfer function. The discrete-time order of the true system _without_ delay is 3, so we estimate a third-order model without delay | ||
```@example DELAY | ||
d = iddata(res) | ||
model_arx = arx(d, 3, 3) | ||
bodeplot!(bp, model_arx, lab="ARX model") | ||
``` | ||
As we can see, the fit is terrible! The least-squares estimation that underpins the [`arx`](@ref) estimator tries to find a model that relates the last three outputs and inputs to the current output, but this is not possible due to the extra delay, in this case the result is catastrophic due to the "shortsightedness" of the [`arx`](@ref) function, it only looks at the immediate past and future, i.e., high-frequency properties. | ||
|
||
If we specify that we have a delay (1 sample delay implies causality, 2 samples delay implies causality + one sample pure delay), we indeed get what we would expect: | ||
```@example DELAY | ||
model_arx_2 = arx(d, 3, 3, inputdelay=2) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The usage of 'inputdelay=2' for a single-sample delay may be confusing; please add clarification in the text to explain the relationship between the specified delay value and the system delay representation. Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||
bodeplot!(bp, model_arx_2, lab="ARX model with delay") | ||
``` | ||
|
||
We can compare the models also in simulation, the model oblivious to the delay does no better here: | ||
```@example DELAY | ||
plot(res, lab="Data") | ||
simplot!(model_arx, d, ploty=false, sysname="ARX model") | ||
simplot!(model_arx_2, d, ploty=false, sysname="ARX model with delay") | ||
``` | ||
|
||
For comparison, we also estimate a model using subspace identification ([`subspaceid`](@ref)), which uses an internal prediction horizon that is much longer than the [`arx`](@ref) method. We compare two cases, one where we explicitly tell [`subspaceid`](@ref) to focus on simulation, and one where the focus is on shorter-term prediction | ||
```@example DELAY | ||
model_sim = subspaceid(d, 3, focus=:simulation) | ||
model_pred = subspaceid(d, 3, focus=:prediction) | ||
bodeplot(P, lab="Continuous-time system without delay") | ||
bodeplot!(model_sim, lab="Simulation model") | ||
bodeplot!(model_pred, lab="Prediction model", legend=:bottomleft) | ||
``` | ||
|
||
We see that although the result is not perfect, we do have one state variable to little after all, the fit is much better. This also carries over to the time domain: | ||
```@example DELAY | ||
plot(res, lab="Data") | ||
simplot!(model_sim, d, ploty=false, sysname="Simulation model") | ||
simplot!(model_pred, d, ploty=false, sysname="Prediction model") | ||
``` | ||
|
||
Try increasing the internal prediction horizon of the [`subspaceid`](@ref) method by setting `r = 30` and you'll get an even better fit. | ||
|
||
What's the takeaway here? When fitting linear black-box models like we did here, we can simply handle the delay by increasing the model order by one for each sample of delay. However, if we are fitting parametric models from first principles and using "short-sighted" methods, we must explicitly take care of the delay in order to not suffer from poor fit. A short-sighted method is any method that tries to fit either local differences (like ARX), or that tries to fit derivatives (the finite-difference approximation to a derivative is a difference). |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Consider revising the informal term 'catastrophic' to a more neutral expression to maintain an objective tone in the documentation.
Copilot uses AI. Check for mistakes.