Skip to content

Commit 2c8e891

Browse files
committed
add linear analysis documentation
1 parent ae1910a commit 2c8e891

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[deps]
2+
ControlSystemsBase = "aaaaaaaa-a6ca-5380-bf3e-84a91bcd477e"
23
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
34
IfElse = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173"
45
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"

docs/pages.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ pages = [
1111
"Magnetic Components" => "API/magnetic.md",
1212
"Mechanical Components" => "API/mechanical.md",
1313
"Thermal Components" => "API/thermal.md",
14+
"Linear Analysis" => "API/linear_analysis.md",
1415
],
1516
]

docs/src/API/linear_analysis.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Linear Analysis
2+
3+
Lienar 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 inserted inbetween two causal blocks (such as those from the Blocks sub module). Once a model containing analysis points is built, several operations are available
4+
5+
- [`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.
6+
- [`get_comp_sensitivity`](@ref) get the complementary sensitivy function $T(s) : S(s)+T(s)=1$.
7+
- [`get_looptransfer`](@ref) get the (open) loop-transfer function where the loop starts and ends in the analysis point.
8+
- [`linearize`](@ref) can be called with two analysis points denoting the input and output of the linearied system. Parts of the model not appearing between the input and output will be removed.
9+
- [`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 imply has been removed.
10+
11+
Of the above mentioned functions, all except for [`open_loop`](@ref) return the output of [`ModelingToolkit.linearize`](@ref), which is
12+
```julia
13+
matrices, simplified_sys = linearize(...)
14+
# matrices = (; A, B, C, D)
15+
```
16+
i.e., `matrices` is a named tuple containing the matrices of a linear state-space system on the form
17+
```math
18+
\begin{aligned}
19+
\dot x &= Ax + Bu\\
20+
y &= Cx + Du
21+
\end{aligned}
22+
```
23+
24+
## Example
25+
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
26+
27+
```@example LINEAR_ANALYSIS
28+
using ModelingToolkitStandardLibrary.Blocks, ModelingToolkit
29+
@named P = FirstOrder(k=1, T=1) # A first-order system with pole in -1
30+
@named C = Gain(-1) # A P controller
31+
t = ModelingToolkit.get_iv(P)
32+
eqs = [
33+
connect(P.output, :plant_output, C.input) # Connect with an automatically created analysis point called :plant_output
34+
connect(C.output, :plant_input, P.input) # Connect with an automatically created analysis point called :plant_input
35+
]
36+
sys = ODESystem(eqs, t, systems=[P,C], name=:feedback_system)
37+
38+
matrices_S = get_sensitivity(sys, :plant_input)[1] # Compute the matrices of a state-space representation of the (input)sensitivity funciton.
39+
matrices_T = get_comp_sensitivity(sys, :plant_input)[1]
40+
```
41+
Continued linear analysis and design can be performed using ControlSystemsBase.jl.
42+
We create `ControlSystemsBase.StateSpace` objects using
43+
```@example LINEAR_ANALYSIS
44+
using ControlSystemsBase, Plots
45+
S = ss(matrices_S...)
46+
T = ss(matrices_T...)
47+
bodeplot([S, T], lab=["S" "" "T" ""])
48+
```
49+
50+
The sensitivity functions obtained this way should be equivalent to the ones obtained with the code below
51+
52+
```@example LINEAR_ANALYSIS_CS
53+
using ControlSystemsBase
54+
P = tf(1.0, [1, 1]) |> ss
55+
C = 1 # Negative feedback assumed in ControlSystems
56+
S = sensitivity(P, C) # or feedback(1, P*C)
57+
T = comp_sensitivity(P, C) # or feedback(P*C)
58+
```
59+
60+
We may also derive the loop-transfer function $L(s) = P(s)C(s)$ using
61+
62+
```@example LINEAR_ANALYSIS
63+
matrices_L = get_looptransfer(sys, :plant_output)[1]
64+
L = ss(matrices_L...)
65+
```
66+
which is equivalent to the following with ControlSystems
67+
```@example LINEAR_ANALYSIS_CS
68+
L = P*(-C) # Add the minus sign to build the negative feedback into the controller
69+
```
70+
71+
72+
To obtain the transfer function between two analysis points, we call `linearize`
73+
```@example LINEAR_ANALYSIS
74+
matrices_P = linearize(sys, :plant_input, :plant_output)[1]
75+
```
76+
this particular transfer function should be equivalent to the linear system `P`, i.e., equivalent to this call
77+
```@example LINEAR_ANALYSIS
78+
@unpack input, output = P # To get the correct namespace
79+
linearize(P, [input.u], [output.u])[1]
80+
```
81+

0 commit comments

Comments
 (0)