-
-
Notifications
You must be signed in to change notification settings - Fork 45
Add analysis points #110
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
Merged
Merged
Add analysis points #110
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
f0a1f40
add analysis points
baggepinnen f839206
add `get_looptransfer`
baggepinnen b6c69cd
Add open_loop
baggepinnen 4111d5e
handle cases with more than one analysis point
baggepinnen ae1910a
add ability to linearize between two analysis points
baggepinnen 16e349a
handle systems with subsystems
baggepinnen cfb5aea
add docs on linear analysis and analysis points
baggepinnen 27887ac
Merge branch 'main' into analysis_points
baggepinnen c90780a
mark linear analysis interface as experimental
baggepinnen 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
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
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
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 |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# Linear Analysis | ||
|
||
!!! danger "Experimental" | ||
The interface described here is currently experimental and at any time subject to breaking changes not respecting semantic versioning. | ||
|
||
Linear analysis refers to the process of linearizing a nonlinear model and analysing the resulting linear dynamical system. To facilitate linear analysis, ModelingToolkitStandardLibrary provides the concept of an [`AnalysisPoint`](@ref), which can be inserted in-between two causal blocks (such as those from the `Blocks` sub module). Once a model containing analysis points is built, several operations are available: | ||
|
||
- [`get_sensitivity`](@ref) get the [sensitivity function (wiki)](https://en.wikipedia.org/wiki/Sensitivity_(control_systems)), $S(s)$, as defined in the field of control theory. | ||
- [`get_comp_sensitivity`](@ref) get the complementary sensitivity function $T(s) : S(s)+T(s)=1$. | ||
- [`get_looptransfer`](@ref) get the (open) loop-transfer function where the loop starts and ends in the analysis point. | ||
- [`linearize`](@ref) can be called with two analysis points denoting the input and output of the linearized system. Parts of the model not appearing between the input and output will be removed. | ||
- [`open_loop`](@ref) return a new (nonlinear) system where the loop has been broken in the analysis point, i.e., the connection the analysis point usually implies has been removed. | ||
|
||
An analysis point can be created explicitly using the constructor [`AnalysisPoint`](@ref), or automatically when connecting two causal components using `connect`: | ||
```julia | ||
connect(comp1.output, :analysis_point_name, comp2.input) | ||
``` | ||
|
||
Of the above mentioned functions, all except for [`open_loop`](@ref) return the output of [`ModelingToolkit.linearize`](@ref), which is | ||
```julia | ||
matrices, simplified_sys = linearize(...) | ||
# matrices = (; A, B, C, D) | ||
``` | ||
i.e., `matrices` is a named tuple containing the matrices of a linear state-space system on the form | ||
```math | ||
\begin{aligned} | ||
\dot x &= Ax + Bu\\ | ||
y &= Cx + Du | ||
\end{aligned} | ||
``` | ||
|
||
## Example | ||
The following example builds a simple closed-loop system with a plant $P$ and a controller $C$. Two analysis points are inserted, one before and one after $P$. We then derive a number of sensitivity functions and show the corresponding code using the package ControlSystemBase.jl | ||
|
||
```@example LINEAR_ANALYSIS | ||
using ModelingToolkitStandardLibrary.Blocks, ModelingToolkit | ||
@named P = FirstOrder(k=1, T=1) # A first-order system with pole in -1 | ||
@named C = Gain(-1) # A P controller | ||
t = ModelingToolkit.get_iv(P) | ||
eqs = [ | ||
connect(P.output, :plant_output, C.input) # Connect with an automatically created analysis point called :plant_output | ||
connect(C.output, :plant_input, P.input) # Connect with an automatically created analysis point called :plant_input | ||
] | ||
sys = ODESystem(eqs, t, systems=[P,C], name=:feedback_system) | ||
|
||
matrices_S = get_sensitivity(sys, :plant_input)[1] # Compute the matrices of a state-space representation of the (input)sensitivity function. | ||
matrices_T = get_comp_sensitivity(sys, :plant_input)[1] | ||
``` | ||
Continued linear analysis and design can be performed using ControlSystemsBase.jl. | ||
We create `ControlSystemsBase.StateSpace` objects using | ||
```@example LINEAR_ANALYSIS | ||
using ControlSystemsBase, Plots | ||
S = ss(matrices_S...) | ||
T = ss(matrices_T...) | ||
bodeplot([S, T], lab=["S" "" "T" ""]) | ||
``` | ||
|
||
The sensitivity functions obtained this way should be equivalent to the ones obtained with the code below | ||
|
||
```@example LINEAR_ANALYSIS_CS | ||
using ControlSystemsBase | ||
P = tf(1.0, [1, 1]) |> ss | ||
C = 1 # Negative feedback assumed in ControlSystems | ||
S = sensitivity(P, C) # or feedback(1, P*C) | ||
T = comp_sensitivity(P, C) # or feedback(P*C) | ||
``` | ||
|
||
We may also derive the loop-transfer function $L(s) = P(s)C(s)$ using | ||
|
||
```@example LINEAR_ANALYSIS | ||
matrices_L = get_looptransfer(sys, :plant_output)[1] | ||
L = ss(matrices_L...) | ||
``` | ||
which is equivalent to the following with ControlSystems | ||
```@example LINEAR_ANALYSIS_CS | ||
L = P*(-C) # Add the minus sign to build the negative feedback into the controller | ||
``` | ||
|
||
|
||
To obtain the transfer function between two analysis points, we call `linearize` | ||
```@example LINEAR_ANALYSIS | ||
matrices_P = linearize(sys, :plant_input, :plant_output)[1] | ||
``` | ||
this particular transfer function should be equivalent to the linear system `P`, i.e., equivalent to this call | ||
```@example LINEAR_ANALYSIS | ||
@unpack input, output = P # To get the correct namespace | ||
linearize(P, [input.u], [output.u])[1] | ||
``` | ||
|
||
## Index | ||
```@index | ||
Pages = ["linear_analysis.md"] | ||
``` | ||
|
||
```@autodocs | ||
Modules = [ModelingToolkitStandardLibrary.Blocks] | ||
Pages = ["Blocks/analysis_points.jl"] | ||
Order = [:function, :type] | ||
Private = false | ||
``` |
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
Oops, something went wrong.
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.
Remember compat.
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.
This is in
docs/Project.toml
where no packages have compat so far :Phttps://github.com/SciML/ModelingToolkitStandardLibrary.jl/blob/de1151f3381b6f4c9a3205c767a076d1627308e6/docs/Project.toml