Skip to content
Open
18 changes: 11 additions & 7 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
name = "ModelingToolkitStandardLibrary"
uuid = "16a59e39-deab-5bd0-87e4-056b12336739"
authors = ["Chris Rackauckas and Julia Computing"]
version = "2.25.0"
authors = ["Chris Rackauckas and Julia Computing"]

[deps]
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"
IfElse = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
ModelingToolkitBase = "7771a370-6774-4173-bd38-47e70ca0b839"
PreallocationTools = "d236fae5-4411-538c-8e31-a6e3d9e00b46"
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"

Expand All @@ -18,19 +18,21 @@ Aqua = "0.8"
ChainRulesCore = "1.24"
ControlSystemsBase = "1.4"
DataFrames = "1.7"
DataInterpolations = "6"
DataInterpolations = "8"
DiffEqBase = "6.152"
ForwardDiff = "0.10"
ForwardDiff = "0.10, 1"
IfElse = "0.1"
LinearAlgebra = "1.10"
ModelingToolkit = "10"
ModelingToolkit = "11"
ModelingToolkitBase = "1"
OrdinaryDiffEq = "6.87"
OrdinaryDiffEqDefault = "1.1"
PreallocationTools = "0.4.23"
SafeTestsets = "0.1"
SciCompDSL = "1"
SciMLStructures = "1.4.2"
SymbolicIndexingInterface = "0.3.28"
Symbolics = "6.14"
Symbolics = "7"
Test = "1"
julia = "1.10"

Expand All @@ -42,12 +44,14 @@ DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
DataInterpolations = "82cc6244-b520-54b8-b5a6-8a565e85f1d0"
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
OrdinaryDiffEqDefault = "50262376-6c5a-4cf5-baba-aaf4f84d72d7"
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
SciCompDSL = "91a8cdf1-4ca6-467b-a780-87fda3fff15e"
SciMLStructures = "53ae85a6-f571-4167-b2af-e1d143709226"
SymbolicIndexingInterface = "2efcf032-c050-4f8e-a9bb-153293bab1f5"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["ADTypes", "Aqua", "LinearAlgebra", "OrdinaryDiffEqDefault", "OrdinaryDiffEq", "SafeTestsets", "Test", "ControlSystemsBase", "DataFrames", "DataInterpolations", "SciMLStructures", "SymbolicIndexingInterface", "ForwardDiff"]
test = ["ADTypes", "Aqua", "LinearAlgebra", "OrdinaryDiffEqDefault", "OrdinaryDiffEq", "SafeTestsets", "Test", "ControlSystemsBase", "DataFrames", "DataInterpolations", "SciMLStructures", "SymbolicIndexingInterface", "ForwardDiff", "SciCompDSL", "ModelingToolkit"]
4 changes: 2 additions & 2 deletions src/Blocks/Blocks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
The module `Blocks` contains common input-output components, referred to as blocks.
"""
module Blocks
using ModelingToolkit, Symbolics
using ModelingToolkitBase, Symbolics
import IfElse: ifelse
import ..@symcheck
using ModelingToolkit: getdefault, t_nounits as t, D_nounits as D
using ModelingToolkitBase: getdefault, t_nounits as t, D_nounits as D

export RealInput, RealInputArray, RealOutput, RealOutputArray, SISO
include("utils.jl")
Expand Down
181 changes: 111 additions & 70 deletions src/Blocks/continuous.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,28 @@ Initial value of integrator state ``x`` can be set with `x`

- `x`: State of Integrator. Defaults to 0.0.
"""
@mtkmodel Integrator begin
@extend u, y = siso = SISO()
@variables begin
x(t) = 0.0, [description = "State of Integrator"]
@component function Integrator(; name, k = 1, x = 0.0)
@named siso = SISO()
@unpack u, y = siso

pars = @parameters begin
k = k, [description = "Gain"]
end
@parameters begin
k = 1, [description = "Gain"]

systems = @named begin
end
@equations begin
D(x) ~ k * u
y ~ x

vars = @variables begin
x(t) = x, [description = "State of Integrator"]
end

equations = Equation[
D(x) ~ k * u,
y ~ x
]

sys = System(equations, t, vars, pars; name, systems)
return extend(sys, siso)
end

"""
Expand All @@ -37,8 +47,8 @@ end
Outputs an approximate derivative of the input. The transfer function of this block is

```
k k ks
─ - ─────── = ──────
k k ks
─ - ─────── = ──────
T sT² + T sT + 1
```

Expand All @@ -62,23 +72,32 @@ Initial value of the state ``x`` can be set with `x`.
- `input`
- `output`
"""
@mtkmodel Derivative begin
@extend u, y = siso = SISO()
@variables begin
x(t) = 0.0, [description = "Derivative-filter state"]
end
@parameters begin
@component function Derivative(; name, k = 1, T = nothing, x = 0.0)
@symcheck T > 0 ||
throw(ArgumentError("Time constant `T` has to be strictly positive"))

@named siso = SISO()
@unpack u, y = siso

pars = @parameters begin
T = T, [description = "Time constant"]
k = 1, [description = "Gain"]
k = k, [description = "Gain"]
end
begin
@symcheck T > 0 ||
throw(ArgumentError("Time constant `T` has to be strictly positive"))

systems = @named begin
end
@equations begin
D(x) ~ (u - x) / T
y ~ (k / T) * (u - x)

vars = @variables begin
x(t) = x, [description = "Derivative-filter state"]
end

equations = Equation[
D(x) ~ (u - x) / T,
y ~ (k / T) * (u - x)
]

sys = System(equations, t, vars, pars; name, systems)
return extend(sys, siso)
end

"""
Expand Down Expand Up @@ -116,26 +135,32 @@ Initial value of the state `x` can be set with `x`

See also [`SecondOrder`](@ref)
"""
@mtkmodel FirstOrder begin
@extend u, y = siso = SISO()
@structural_parameters begin
lowpass = true
end
@variables begin
x(t) = 0.0, [description = "State of FirstOrder filter"]
end
@parameters begin
@component function FirstOrder(; name, lowpass = true, T = nothing, k = 1.0, x = 0.0)
@symcheck T > 0 ||
throw(ArgumentError("Time constant `T` has to be strictly positive"))

@named siso = SISO()
@unpack u, y = siso

pars = @parameters begin
T = T, [description = "Time constant"]
k = 1.0, [description = "Gain"]
k = k, [description = "Gain"]
end
begin
@symcheck T > 0 ||
throw(ArgumentError("Time constant `T` has to be strictly positive"))

systems = @named begin
end
@equations begin
D(x) ~ (k * u - x) / T
lowpass ? y ~ x : y ~ k * u - x

vars = @variables begin
x(t) = x, [description = "State of FirstOrder filter"]
end

equations = Equation[
D(x) ~ (k * u - x) / T,
lowpass ? (y ~ x) : (y ~ k * u - x)
]

sys = System(equations, t, vars, pars; name, systems)
return extend(sys, siso)
end

"""
Expand Down Expand Up @@ -165,22 +190,32 @@ Initial value of the state `x` can be set with `x`, and of derivative state `xd`
- `input`
- `output`
"""
@mtkmodel SecondOrder begin
@extend u, y = siso = SISO()
@variables begin
x(t), [description = "State of SecondOrder filter", guess = 0.0]
xd(t), [description = "Derivative state of SecondOrder filter", guess = 0.0]
@component function SecondOrder(; name, k = 1.0, w = 1.0, d = 1.0, x = nothing, xd = nothing)
@named siso = SISO()
@unpack u, y = siso

pars = @parameters begin
k = k, [description = "Gain"]
w = w, [description = "Bandwidth (angular frequency)"]
d = d, [description = "Relative damping"]
end
@parameters begin
k = 1.0, [description = "Gain"]
w = 1.0, [description = "Bandwidth (angular frequency)"]
d = 1.0, [description = "Relative damping"]

systems = @named begin
end
@equations begin
D(x) ~ xd
D(xd) ~ w * (w * (k * u - x) - 2 * d * xd)
y ~ x

vars = @variables begin
x(t) = x, [description = "State of SecondOrder filter", guess = 0.0]
xd(t) = xd, [description = "Derivative state of SecondOrder filter", guess = 0.0]
end

equations = Equation[
D(x) ~ xd,
D(xd) ~ w * (w * (k * u - x) - 2 * d * xd),
y ~ x
]

sys = System(equations, t, vars, pars; name, systems)
return extend(sys, siso)
end

"""
Expand All @@ -206,29 +241,35 @@ U(s) = k (1 + \\dfrac{1}{sT}) E(S)

See also [`LimPI`](@ref)
"""
@mtkmodel PI begin
@parameters begin
k = 1.0, [description = "Proportional gain"]
T = 1.0, [description = "Integrator time constant"]
end
begin
@symcheck T > 0 ||
throw(ArgumentError("Time constant `T` has to be strictly positive"))
@component function PI(; name, k = 1.0, T = 1.0)
@symcheck T > 0 ||
throw(ArgumentError("Time constant `T` has to be strictly positive"))

pars = @parameters begin
k = k, [description = "Proportional gain"]
T = T, [description = "Integrator time constant"]
end
@components begin

systems = @named begin
err_input = RealInput() # control error
ctr_output = RealOutput() # control signal
gainPI = Gain(; k)
addPI = Add()
int = Integrator(k = 1 / T, x = 0.0)
end
@equations begin
connect(err_input, addPI.input1)
connect(addPI.output, gainPI.input)
connect(gainPI.output, ctr_output)
connect(err_input, int.input)
connect(int.output, addPI.input2)

vars = @variables begin
end

equations = Equation[
connect(err_input, addPI.input1),
connect(addPI.output, gainPI.input),
connect(gainPI.output, ctr_output),
connect(err_input, int.input),
connect(int.output, addPI.input2)
]

return System(equations, t, vars, pars; name, systems)
end

"""
Expand Down Expand Up @@ -337,7 +378,7 @@ The simplified expression above is given without the anti-windup protection.
- `err_input`
- `ctr_output`
"""
@component function LimPI(; name, k = 1, T, u_max, u_min = -u_max, Ta, int__x = 0.0)
@component function LimPI(; name, k = 1, T = nothing, u_max = nothing, u_min = -u_max, Ta = nothing, int__x = 0.0)
@symcheck Ta > 0 ||
throw(ArgumentError("Time constant `Ta` has to be strictly positive"))
@symcheck T > 0 || throw(ArgumentError("Time constant `T` has to be strictly positive"))
Expand Down Expand Up @@ -610,7 +651,7 @@ To set the initial state, it's recommended to set the initial condition for `x`,
- `input`
- `output`

See also [`StateSpace`](@ref) which handles MIMO systems, as well as [ControlSystemsMTK.jl](https://juliacontrol.github.io/ControlSystemsMTK.jl/stable/) for an interface between [ControlSystems.jl](https://juliacontrol.github.io/ControlSystems.jl/stable/) and ModelingToolkit.jl for advanced manipulation of transfer functions and linear statespace systems. For linearization, see [`linearize`](@ref) and [Linear Analysis](https://docs.sciml.ai/ModelingToolkitStandardLibrary/stable/API/linear_analysis/).
See also [`StateSpace`](@ref) which handles MIMO systems, as well as [ControlSystemsMTK.jl](https://juliacontrol.github.io/ControlSystemsMTK.jl/stable/) for an interface between [ControlSystems.jl](https://juliacontrol.github.io/ControlSystems.jl/stable/) and ModelingToolkitBase.jl for advanced manipulation of transfer functions and linear statespace systems. For linearization, see [`linearize`](@ref) and [Linear Analysis](https://docs.sciml.ai/ModelingToolkitStandardLibrary/stable/API/linear_analysis/).
"""
@component function TransferFunction(; b = [1], a = [1, 1], name)
nb = length(b)
Expand Down
Loading
Loading