From 3985596609348daecc7f2453bcbd00823000ab48 Mon Sep 17 00:00:00 2001 From: Venkateshprasad <32921645+ven-k@users.noreply.github.com> Date: Mon, 3 Jul 2023 12:40:48 +0530 Subject: [PATCH 1/7] refactor: Blocks/math.jl --- src/Blocks/analysis_points.jl | 2 +- src/Blocks/math.jl | 240 +++++++++++++++------------- test/Blocks/math.jl | 10 +- test/Blocks/test_analysis_points.jl | 6 +- 4 files changed, 141 insertions(+), 117 deletions(-) diff --git a/src/Blocks/analysis_points.jl b/src/Blocks/analysis_points.jl index bc3234e9b..a6b90866d 100644 --- a/src/Blocks/analysis_points.jl +++ b/src/Blocks/analysis_points.jl @@ -46,7 +46,7 @@ See also [`get_sensitivity`](@ref), [`get_comp_sensitivity`](@ref), [`get_looptr ```julia using ModelingToolkitStandardLibrary.Blocks @named P = FirstOrder(k = 1, T = 1) -@named C = Gain(-1) +@named C = Gain(; k = -1) t = ModelingToolkit.get_iv(P) eqs = [connect(P.output, C.input) connect(C.output, :plant_input, P.input)] diff --git a/src/Blocks/math.jl b/src/Blocks/math.jl index b3858a66d..f70c34e04 100644 --- a/src/Blocks/math.jl +++ b/src/Blocks/math.jl @@ -1,5 +1,5 @@ """ - Gain(k; name) + Gain(; name, k) Output the product of a gain value with the input signal. @@ -12,15 +12,16 @@ Output the product of a gain value with the input signal. - `input` - `output` """ -@component function Gain(k; name) - @named siso = SISO() - @unpack u, y = siso - pars = @parameters k=k [description = "Gain of Gain $name"] - eqs = [ - y ~ k * u, - ] - extend(ODESystem(eqs, t, [], pars; name = name), siso) +@mtkmodel Gain begin + @extend u, y = siso = SISO() + @parameters begin + k, [description = "Gain"] + end + @equations begin + y ~ k * u + end end +Gain.f(k; name) = Gain.f(; k, name) """ MatrixGain(K::AbstractArray; name) @@ -36,39 +37,48 @@ Output the product of a gain matrix with the input signal vector. - `input` - `output` """ -@component function MatrixGain(K::AbstractArray; name) - nout, nin = size(K, 1), size(K, 2) - @named input = RealInput(; nin = nin) - @named output = RealOutput(; nout = nout) - eqs = [output.u[i] ~ sum(K[i, j] * input.u[j] for j in 1:nin) for i in 1:nout] - compose(ODESystem(eqs, t, [], []; name = name), [input, output]) +@mtkmodel MatrixGain begin + @parameters begin + K, [description = "Matrix gain"] + end + begin + nout = size(getdefault(K), 1) + nin = size(getdefault(K), 2) + end + @components begin + input = RealInput(; nin = size(K, 2)) + output = RealOutput(; nout = size(K, 1)) + end + @equations begin + [(@info i, j; output.u[i] ~ sum(getdefault(K)[i, j] * input.u[j])) for j in 1:nin + for i in 1:nout]... + end end +MatrixGain.f(K; name) = MatrixGain.f(; name, K) """ - Sum(n::Int; name) + Sum(; input.nin::Int, name) Output the sum of the elements of the input port vector. - -# Parameters: - - - `n`: Input port dimension +Input port dimension can be set with `input.nin` # Connectors: - `input` - `output` """ -@component function Sum(n::Int; name) - @named input = RealInput(; nin = n) - @named output = RealOutput() - eqs = [ - output.u ~ sum(input.u), - ] - compose(ODESystem(eqs, t, [], []; name = name), [input, output]) +@mtkmodel Sum begin + @components begin + input = RealInput(; nin) + output = RealOutput() + end + @equations begin + output.u ~ sum(input.u) + end end """ - Feedback(;name) + Feedback(; name) Output difference between reference input (input1) and feedback input (input2). @@ -78,18 +88,19 @@ Output difference between reference input (input1) and feedback input (input2). - `input2` - `output` """ -@component function Feedback(; name) - @named input1 = RealInput() - @named input2 = RealInput() - @named output = RealOutput() - eqs = [ - output.u ~ input1.u - input2.u, - ] - return compose(ODESystem(eqs, t, [], []; name = name), input1, input2, output) +@mtkmodel Feedback begin + @components begin + input1 = RealInput() + input2 = RealInput() + output = RealOutput() + end + @equations begin + output.u ~ input1.u - input2.u + end end """ - Add(;name, k1=1, k2=1) + Add(; name, k1 = 1, k2 = 1) Output the sum of the two scalar inputs. @@ -104,20 +115,23 @@ Output the sum of the two scalar inputs. - `input2` - `output` """ -@component function Add(; name, k1 = 1, k2 = 1) - @named input1 = RealInput() - @named input2 = RealInput() - @named output = RealOutput() - pars = @parameters(k1=k1, [description = "Gain of Add $name input1"], - k2=k2, [description = "Gain of Add $name input2"],) - eqs = [ - output.u ~ k1 * input1.u + k2 * input2.u, - ] - return compose(ODESystem(eqs, t, [], pars; name = name), input1, input2, output) +@mtkmodel Add begin + @components begin + input1 = RealInput() + input2 = RealInput() + output = RealOutput() + end + @parameters begin + k1 = 1, [description = "Gain of Add input1"] + k2 = 1, [description = "Gain of Add input2"] + end + @equations begin + output.u ~ k1 * input1.u + k2 * input2.u + end end """ - Add(;name, k1=1, k2=1,k3=1) + Add(; name, k1 = 1, k2 = 1, k3 = 1) Output the sum of the three scalar inputs. @@ -134,22 +148,25 @@ Output the sum of the three scalar inputs. - `input3` - `output` """ -@component function Add3(; name, k1 = 1, k2 = 1, k3 = 1) - @named input1 = RealInput() - @named input2 = RealInput() - @named input3 = RealInput() - @named output = RealOutput() - pars = @parameters(k1=k1, [description = "Gain of Add $name input1"], - k2=k2, [description = "Gain of Add $name input2"], - k3=k3, [description = "Gain of Add $name input3"],) - eqs = [ - output.u ~ k1 * input1.u + k2 * input2.u + k3 * input3.u, - ] - return compose(ODESystem(eqs, t, [], pars; name = name), input1, input2, input3, output) +@mtkmodel Add3 begin + @components begin + input1 = RealInput() + input2 = RealInput() + input3 = RealInput() + output = RealOutput() + end + @parameters begin + k1 = 1, [description = "Gain of Add input1"] + k2 = 1, [description = "Gain of Add input2"] + k3 = 1, [description = "Gain of Add input3"] + end + @equations begin + output.u ~ k1 * input1.u + k2 * input2.u + k3 * input3.u + end end """ - Product(;name) + Product(; name) Output product of the two inputs. @@ -159,18 +176,19 @@ Output product of the two inputs. - `input2` - `output` """ -@component function Product(; name) - @named input1 = RealInput() - @named input2 = RealInput() - @named output = RealOutput() - eqs = [ - output.u ~ input1.u * input2.u, - ] - return compose(ODESystem(eqs, t, [], []; name = name), input1, input2, output) +@mtkmodel Product begin + @components begin + input1 = RealInput() + input2 = RealInput() + output = RealOutput() + end + @equations begin + output.u ~ input1.u * input2.u + end end """ - Division(;name) + Division(; name) Output first input divided by second input. @@ -180,18 +198,19 @@ Output first input divided by second input. - `input2` - `output` """ -@component function Division(; name) - @named input1 = RealInput() - @named input2 = RealInput(u_start = 1.0) # denominator can not be zero - @named output = RealOutput() - eqs = [ - output.u ~ input1.u / input2.u, - ] - return compose(ODESystem(eqs, t, [], []; name = name), input1, input2, output) +@mtkmodel Division begin + @components begin + input1 = RealInput() + input2 = RealInput(u_start = 1.0) # denominator can not be zero + output = RealOutput() + end + @equations begin + output.u ~ input1.u / input2.u + end end """ - StaticNonLinearity(func ;name) + StaticNonLinearity(func; name) Applies the given function to the input. @@ -202,15 +221,19 @@ If the given function is not composed of simple core methods (e.g. sin, abs, ... - `input` - `output` """ -@component function StaticNonLinearity(func; name) - @named siso = SISO() - @unpack u, y = siso - eqs = [y ~ func(u)] - extend(ODESystem(eqs, t, [], []; name = name), siso) +@mtkmodel StaticNonLinearity begin + @parameters begin + func + end + @extend u, y = siso = SISO() + @equations begin + y ~ first(getdefault(func))(u) + end end +StaticNonLinearity.f(func; name) = StaticNonLinearity.f(; name = name, func = [func]) """ - Abs(;name) + Abs(; name) Output the absolute value of the input. @@ -221,7 +244,7 @@ See [`StaticNonLinearity`](@ref) @component Abs(; name) = StaticNonLinearity(abs; name) """ - Sign(;name) + Sign(; name) Output the sign of the input @@ -232,7 +255,7 @@ See [`StaticNonLinearity`](@ref) @component Sign(; name) = StaticNonLinearity(sign; name) """ - Sqrt(;name) + Sqrt(; name) Output the square root of the input (input >= 0 required). @@ -243,7 +266,7 @@ See [`StaticNonLinearity`](@ref) @component Sqrt(; name) = StaticNonLinearity(sqrt; name) """ - Sin(;name) + Sin(; name) Output the sine of the input. @@ -254,7 +277,7 @@ See [`StaticNonLinearity`](@ref) @component Sin(; name) = StaticNonLinearity(sin; name) """ - Cos(;name) + Cos(; name) Output the cosine of the input. @@ -265,7 +288,7 @@ See [`StaticNonLinearity`](@ref) @component Cos(; name) = StaticNonLinearity(cos; name) """ - Tan(;name) + Tan(; name) Output the tangent of the input. @@ -276,7 +299,7 @@ See [`StaticNonLinearity`](@ref) @component Tan(; name) = StaticNonLinearity(tan; name) """ - Asin(;name) + Asin(; name) Output the arc sine of the input. @@ -287,7 +310,7 @@ See [`StaticNonLinearity`](@ref) @component Asin(; name) = StaticNonLinearity(asin; name) """ - Acos(;name) + Acos(; name) Output the arc cosine of the input. @@ -298,7 +321,7 @@ See [`StaticNonLinearity`](@ref) @component Acos(; name) = StaticNonLinearity(acos; name) """ - Atan(;name) + Atan(; name) Output the arc tangent of the input. @@ -309,7 +332,7 @@ See [`StaticNonLinearity`](@ref) @component Atan(; name) = StaticNonLinearity(atan; name) """ - Atan2(;name) + Atan2(; name) Output the arc tangent of the input. @@ -319,18 +342,19 @@ Output the arc tangent of the input. - `input2` - `output` """ -@component function Atan2(; name) - @named input1 = RealInput() - @named input2 = RealInput() - @named output = RealOutput() - eqs = [ - output.u ~ atan(input1.u, input2.u), - ] - compose(ODESystem(eqs, t, [], []; name = name), [input1, input2, output]) +@mtkmodel Atan2 begin + @components begin + input1 = RealInput() + input2 = RealInput() + output = RealOutput() + end + @equations begin + output.u ~ atan(input1.u, input2.u) + end end """ - Sinh(;name) + Sinh(; name) Output the hyperbolic sine of the input. @@ -341,7 +365,7 @@ See [`StaticNonLinearity`](@ref) @component Sinh(; name) = StaticNonLinearity(sinh; name) """ - Cosh(;name) + Cosh(; name) Output the hyperbolic cosine of the input. @@ -352,7 +376,7 @@ See [`StaticNonLinearity`](@ref) @component Cosh(; name) = StaticNonLinearity(cosh; name) """ - Tanh(;name) + Tanh(; name) Output the hyperbolic tangent of the input. @@ -363,7 +387,7 @@ See [`StaticNonLinearity`](@ref) @component Tanh(; name) = StaticNonLinearity(tanh; name) """ - Exp(;name) + Exp(; name) Output the exponential (base e) of the input. @@ -374,7 +398,7 @@ See [`StaticNonLinearity`](@ref) @component Exp(; name) = StaticNonLinearity(exp; name) """ - Log(;name) + Log(; name) Output the natural (base e) logarithm of the input. @@ -385,7 +409,7 @@ See [`StaticNonLinearity`](@ref) @component Log(; name) = StaticNonLinearity(log; name) """ - Log10(;name) + Log10(; name) Output the base 10 logarithm of the input. diff --git a/test/Blocks/math.jl b/test/Blocks/math.jl index 4e1fe53f4..1ad2317fc 100644 --- a/test/Blocks/math.jl +++ b/test/Blocks/math.jl @@ -8,7 +8,7 @@ using OrdinaryDiffEq: ReturnCode.Success @testset "Gain" begin @named c = Constant(; k = 1) - @named gain = Gain(1;) + @named gain = Gain(; k = 1) @named int = Integrator(; k = 1) @named model = ODESystem([ connect(c.output, gain.input), @@ -27,7 +27,7 @@ end @testset "Feedback loop" begin @named c = Constant(; k = 2) - @named gain = Gain(1;) + @named gain = Gain(; k = 1) @named int = Integrator(; k = 1) @named fb = Feedback(;) @named model = ODESystem([ @@ -191,14 +191,14 @@ end @testset "MatrixGain" begin K = [1 2; 3 4] - @named gain = MatrixGain(K;) + @named gain = MatrixGain(; K) K = [1, 2] - @named gain = MatrixGain(K;) + @named gain = MatrixGain(; K) # TODO: end @testset "Sum" begin - @named s = Sum(2;) + @named s = Sum(; input.nin = 2) # TODO: end diff --git a/test/Blocks/test_analysis_points.jl b/test/Blocks/test_analysis_points.jl index fab92b37b..ccadd22ed 100644 --- a/test/Blocks/test_analysis_points.jl +++ b/test/Blocks/test_analysis_points.jl @@ -6,7 +6,7 @@ using ModelingToolkit: get_eqs, vars, @set!, get_iv using ControlSystemsBase @named P = FirstOrder(k = 1, T = 1) -@named C = Gain(-1) +@named C = Gain(; k = -1) t = ModelingToolkit.get_iv(P) @test_logs (:warn,) (:warn,) connect(P.input, :bad_connection, C.output) @@ -106,7 +106,7 @@ matrices2, _ = linearize(sys, :plant_input, [P.output.u]) ## Test with subsystems @named P = FirstOrder(k = 1, T = 1) -@named C = Gain(1) +@named C = Gain(; k = 1) @named add = Blocks.Add(k2 = -1) t = ModelingToolkit.get_iv(P) @@ -303,7 +303,7 @@ G = CS.feedback(Pss, Kss, pos_feedback = true) ## Multiple analysis points ==================================================== @named P = FirstOrder(k = 1, T = 1) -@named C = Gain(1) +@named C = Gain(; k = 1) @named add = Blocks.Add(k2 = -1) t = ModelingToolkit.get_iv(P) From 2505ad332111900cf3787db93d6c08e6616cb9dc Mon Sep 17 00:00:00 2001 From: Venkateshprasad <32921645+ven-k@users.noreply.github.com> Date: Mon, 3 Jul 2023 12:43:01 +0530 Subject: [PATCH 2/7] refactor: Blocks/continuous.jl --- src/Blocks/continuous.jl | 183 ++++++++++++++++++++++---------------- test/Blocks/continuous.jl | 14 +-- 2 files changed, 113 insertions(+), 84 deletions(-) diff --git a/src/Blocks/continuous.jl b/src/Blocks/continuous.jl index a2caab9ef..af34d36dd 100644 --- a/src/Blocks/continuous.jl +++ b/src/Blocks/continuous.jl @@ -1,7 +1,8 @@ """ - Integrator(;name, k=1, x_start=0.0) + Integrator(;name, k = 1, x = 0.0) Outputs `y = ∫k*u dt`, corresponding to the transfer function `1/s`. +Initial value of integrator state `x` can be set with `x` # Connectors: @@ -11,22 +12,25 @@ Outputs `y = ∫k*u dt`, corresponding to the transfer function `1/s`. # Parameters: - `k`: Gain of integrator - - `x_start`: Initial value of integrator """ -@component function Integrator(; name, k = 1, x_start = 0.0) - @named siso = SISO() - @unpack u, y = siso - sts = @variables x(t)=x_start [description = "State of Integrator $name"] - pars = @parameters k=k [description = "Gain of Integrator $name"] - eqs = [D(x) ~ k * u - y ~ x] - extend(ODESystem(eqs, t, sts, pars; name = name), siso) +@mtkmodel Integrator begin + @extend u, y = siso = SISO() + @variables begin + x(t) = 0.0, [description = "State of Integrator"] + end + @parameters begin + k = 1, [description = "Gain of Integrator"] + end + @equations begin + D(x) ~ k * u + y ~ x + end end - """ - Derivative(; name, k=1, T, x_start=0.0) + Derivative(; name, k = 1, T, x = 0.0) Outputs an approximate derivative of the input. The transfer function of this block is +Initial value of the state `x` can be set with `x` ``` k k @@ -44,31 +48,37 @@ A smaller `T` leads to a more ideal approximation of the derivative. - `k`: Gain - `T`: [s] Time constants (T>0 required; T=0 is ideal derivative block) - - `x_start`: Initial value of state # Connectors: - `input` - `output` """ -@component function Derivative(; name, k = 1, T, x_start = 0.0) - @symcheck T > 0 || throw(ArgumentError("Time constant `T` has to be strictly positive")) - @named siso = SISO() - @unpack u, y = siso - sts = @variables x(t)=x_start [description = "State of Derivative $name"] - pars = @parameters T=T [description = "Time constant of Derivative $name"] k=k [ - description = "Gain of Derivative $name", - ] - eqs = [D(x) ~ (u - x) / T - y ~ (k / T) * (u - x)] - extend(ODESystem(eqs, t, sts, pars; name = name), siso) +@mtkmodel Derivative begin + @extend u, y = siso = SISO() + @variables begin + x(t) = 0.0, [description = "State of Derivative"] + end + @parameters begin + T = T, [description = "Time constant of Derivative"] + k = 1, [description = "Gain of Derivative"] + end + begin + @symcheck T > 0 || + throw(ArgumentError("Time constant `T` has to be strictly positive")) + end + @equations begin + D(x) ~ (u - x) / T + y ~ (k / T) * (u - x) + end end """ - FirstOrder(; name, k=1, T, x_start=0.0, lowpass=true) + FirstOrder(; name, k = 1.0, T, x = 0.0, lowpass = true) A first-order filter with a single real pole in `s = -T` and gain `k`. If `lowpass=true` (default), the transfer function is given by `Y(s)/U(s) = ` +Initial value of the state `x` can be set with `x` ``` k @@ -88,7 +98,6 @@ sT + 1 - k - `k`: Gain - `T`: [s] Time constants (T>0 required) - - `x_start`: Initial value of state # Connectors: @@ -97,21 +106,28 @@ sT + 1 - k See also [`SecondOrder`](@ref) """ -@component function FirstOrder(; name, k = 1, T, x_start = 0.0, lowpass = true) - @symcheck T > 0 || throw(ArgumentError("Time constant `T` has to be strictly positive")) - @named siso = SISO() - @unpack u, y = siso - sts = @variables x(t)=x_start [description = "State of FirstOrder filter $name"] - pars = @parameters T=T [description = "Time constant of FirstOrder filter $name"] k=k [ - description = "Gain of FirstOrder $name", - ] - eqs = [D(x) ~ (k * u - x) / T - lowpass ? y ~ x : y ~ k * u - x] - extend(ODESystem(eqs, t, sts, pars; name = name), siso) +@mtkmodel FirstOrder begin + @extend u, y = siso = SISO() + @variables begin + x(t) = 0.0, [description = "State of FirstOrder filter"] + end + @parameters begin + lowpass = true + T = T, [description = "Time constant of FirstOrder filter"] + k = 1.0, [description = "Gain of FirstOrder"] + end + begin + @symcheck T > 0 || + throw(ArgumentError("Time constant `T` has to be strictly positive")) + end + @equations begin + D(x) ~ (k * u - x) / T + getdefault(lowpass) ? y ~ x : y ~ k * u - x + end end """ - SecondOrder(; name, k=1, w, d, x_start=0.0, xd_start=0.0) + SecondOrder(; name, k = 1.0, w, d, x = 0.0, xd = 0.0) A second-order filter with gain `k`, a bandwidth of `w` rad/s and relative damping `d`. The transfer function is given by `Y(s)/U(s) = ` @@ -124,44 +140,47 @@ s² + 2d*w*s + w^2 Critical damping corresponds to `d=1`, which yields the fastest step response without overshoot, `d < 1` results in an underdamped filter while `d > 1` results in an overdamped filter. `d = 1/√2` corresponds to a Butterworth filter of order 2 (maximally flat frequency response). +Initial value of the state `x` can be set with `x`, and of derivative state `xd` with `xd`. # Parameters: - `k`: Gain - `w`: [`rad/s`] Angular frequency - `d`: Damping - - `x_start`: Initial value of state (output) - - `xd_start`: Initial value of derivative of state (output) # Connectors: - `input` - `output` """ -@component function SecondOrder(; name, k = 1, w, d, x_start = 0.0, xd_start = 0.0) - @named siso = SISO() - @unpack u, y = siso - @variables x(t)=x_start [description = "State of SecondOrder filter $name"] - @variables xd(t)=xd_start [description = "Derivative state of SecondOrder filter $name"] - @parameters k=k [description = "Gain of SecondOrder $name"] - @parameters w=w [description = "Bandwidth of SecondOrder $name"] - @parameters d=d [description = "Relative damping of SecondOrder $name"] - eqs = [D(x) ~ xd +@mtkmodel SecondOrder begin + @extend u, y = siso = SISO() + @variables begin + x(t) = 0.0, [description = "State of SecondOrder filter"] + xd(t) = 0.0, [description = "Derivative state of SecondOrder filter"] + end + @parameters begin + k = 1.0, [description = "Gain of SecondOrder"] + w, [description = "Bandwidth of SecondOrder"] + d, [description = "Relative damping of SecondOrder"] + end + @equations begin + D(x) ~ xd D(xd) ~ w * (w * (k * u - x) - 2 * d * xd) - y ~ x] - extend(ODESystem(eqs, t; name = name), siso) + y ~ x + end end """ - PI(;name, k=1, T, x_start=0.0) + PI(;name, gainPI.k = 1.0, T, int.x = 0.0) Textbook version of a PI-controller without actuator saturation and anti-windup measure. +Initial value of integrator state `x` can be set with `int.x` +Initial value of gain can be set with `gainPI.k` # Parameters: - - `k`: Gain - `T`: [s] Integrator time constant (T>0 required) - - `x_start`: Initial value for the integrator # Connectors: @@ -170,22 +189,28 @@ Textbook version of a PI-controller without actuator saturation and anti-windup See also [`LimPI`](@ref) """ -@component function PI(; name, k = 1, T, x_start = 0.0) - @symcheck T > 0 || throw(ArgumentError("Time constant `T` has to be strictly positive")) - @named err_input = RealInput() # control error - @named ctr_output = RealOutput() # control signal - @named gainPI = Gain(k) - @named addPI = Add() - @named int = Integrator(k = 1 / T, x_start = x_start) - sys = [err_input, ctr_output, gainPI, addPI, int] - eqs = [ - 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), - ] - ODESystem(eqs, t, [], []; name = name, systems = sys) +@mtkmodel PI begin + @parameters begin + T, [description = "Integrator time constant"] + end + begin + @symcheck T > 0 || + throw(ArgumentError("Time constant `T` has to be strictly positive")) + end + @components begin + err_input = RealInput() # control error + ctr_output = RealOutput() # control signal + gainPI = Gain(; k = 1.0) + 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) + end end """ @@ -224,12 +249,12 @@ See also [`LimPID`](@ref) @named gainPID = Gain(k) @named addPID = Add3() if with_I - @named int = Integrator(k = 1 / Ti, x_start = xi_start) + @named int = Integrator(k = 1 / Ti, x = xi_start) else @named Izero = Constant(k = 0) end if with_D - @named der = Derivative(k = Td, T = 1 / Nd, x_start = xd_start) + @named der = Derivative(k = Td, T = 1 / Nd, x = xd_start) else @named Dzero = Constant(k = 0) end @@ -265,16 +290,16 @@ See also [`LimPID`](@ref) end """ - LimPI(;name, k=1, T, u_max=1, u_min=-u_max, Ta) + LimPI(; name, T, Ta, k = 1.0, x_start = 0.0, u_max = 1.0, u_min = -u_max) Text-book version of a PI-controller with actuator saturation and anti-windup measure. +Initial value of gain can be set with `gainPI.k` +Initial value of integrator state `x` can be set with `int.x` # Parameters: - - `k`: Gain - `T`: [s] Integrator time constant (T>0 required) - `Ta`: [s] Tracking time constant (Ta>0 required) - - `x_start`: Initial value for the integrator # Connectors: @@ -291,7 +316,7 @@ Text-book version of a PI-controller with actuator saturation and anti-windup me @named gainPI = Gain(k) @named addPI = Add() @named addTrack = Add() - @named int = Integrator(k = 1 / T, x_start = x_start) + @named int = Integrator(k = 1 / T, x = x_start) @named limiter = Limiter(y_max = u_max, y_min = u_min) @named addSat = Add(k1 = 1, k2 = -1) @named gainTrack = Gain(1 / Ta) @@ -376,7 +401,7 @@ where the transfer function for the derivative includes additional filtering, se @named measurement = RealInput() @named ctr_output = RealOutput() # control signal @named addP = Add(k1 = wp, k2 = -1) - @named gainPID = Gain(k) + @named gainPID = Gain(; k) @named addPID = Add3() @named limiter = Limiter(y_max = u_max, y_min = u_min) if with_I @@ -387,12 +412,12 @@ where the transfer function for the derivative includes additional filtering, se else @named addI = Add(k1 = 1, k2 = -1) end - @named int = Integrator(k = 1 / Ti, x_start = xi_start) + @named int = Integrator(k = 1 / Ti, x = xi_start) else @named Izero = Constant(k = 0) end if with_D - @named der = Derivative(k = Td, T = 1 / Nd, x_start = xd_start) + @named der = Derivative(k = Td, T = 1 / Nd, x = xd_start) @named addD = Add(k1 = wd, k2 = -1) else @named Dzero = Constant(k = 0) diff --git a/test/Blocks/continuous.jl b/test/Blocks/continuous.jl index 5a1f09746..3dffa3b1f 100644 --- a/test/Blocks/continuous.jl +++ b/test/Blocks/continuous.jl @@ -13,10 +13,10 @@ an integrator with a constant input is often used together with the system under @testset "Constant" begin @named c = Constant(; k = 1) - @named int = Integrator() + @named int = Integrator(x = 1) @named iosys = ODESystem(connect(c.output, int.input), t, systems = [int, c]) sys = structural_simplify(iosys) - prob = ODEProblem(sys, Pair[int.x => 1.0], (0.0, 1.0)) + prob = ODEProblem(sys, Pair[], (0.0, 1.0)) sol = solve(prob, Rodas4()) @test sol.retcode == Success @test all(sol[c.output.u] .≈ 1) @@ -147,7 +147,7 @@ end @testset "PI" begin re_val = 2 @named ref = Constant(; k = re_val) - @named pi_controller = PI(k = 1, T = 1) + @named pi_controller = PI(int.k = 1, T = 1) @named plant = Plant() @named fb = Feedback() @named model = ODESystem([ @@ -227,8 +227,12 @@ end @testset "LimPI" begin re_val = 1 @named ref = Constant(; k = re_val) - @named pi_controller_lim = LimPI(k = 3, T = 0.5, u_max = 1.5, u_min = -1.5, Ta = 0.1) - @named pi_controller = PI(k = 3, T = 0.5) + @named pi_controller_lim = LimPI(k = 3, + T = 0.5, + u_max = 1.5, + u_min = -1.5, + Ta = 0.1) + @named pi_controller = PI(gainPI.k = 3, T = 0.5) @named sat = Limiter(y_max = 1.5, y_min = -1.5) @named plant = Plant() @named fb = Feedback() From 9875e7fced494995ef8f68ce01e2f70ce75fb8b3 Mon Sep 17 00:00:00 2001 From: Venkateshprasad <32921645+ven-k@users.noreply.github.com> Date: Mon, 3 Jul 2023 12:46:14 +0530 Subject: [PATCH 3/7] refactor: Blocks/nonlinear.jl --- src/Blocks/nonlinear.jl | 67 +++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/src/Blocks/nonlinear.jl b/src/Blocks/nonlinear.jl index 502b50478..bab526a83 100644 --- a/src/Blocks/nonlinear.jl +++ b/src/Blocks/nonlinear.jl @@ -2,7 +2,7 @@ _clamp(u, u_min, u_max) = max(min(u, u_max), u_min) _dead_zone(u, u_min, u_max) = ifelse(u > u_max, u - u_max, ifelse(u < u_min, u - u_min, 0)) """ - Limiter(;name, y_max, y_min=y_max > 0 ? -y_max : -Inf) + Limiter(;name, y_max, y_min = y_max > 0 ? -y_max : -Inf) Limit the range of a signal. @@ -30,7 +30,7 @@ Limit the range of a signal. end """ - DeadZone(; name, u_max, u_min=-u_max) + DeadZone(; name, u_max, u_min = -u_max) The DeadZone block defines a region of zero output. If the input is within `u_min` ... `u_max`, the output is zero. Outside of this zone, the output is a linear function of the input with a slope of 1. @@ -56,50 +56,57 @@ If the input is within `u_min` ... `u_max`, the output is zero. Outside of this - `input` - `output` """ -@component function DeadZone(; name, u_max, u_min = -u_max) - if !ModelingToolkit.isvariable(u_max) - u_max ≥ u_min || throw(ArgumentError("`u_min` must be smaller than `u_max`")) +@mtkmodel DeadZone begin + @parameters begin + u_max, [description = "Upper limit of dead zone of DeadZone"] + u_min = -u_max, [description = "Lower limit of dead zone of DeadZone"] + end + begin + if !ModelingToolkit.isvariable(u_max) + u_max ≥ u_min || throw(ArgumentError("`u_min` must be smaller than `u_max`")) + end + end + + @extend u, y = siso = SISO() + + @equations begin + y ~ _dead_zone(u, u_min, u_max) end - @named siso = SISO() - @unpack u, y = siso - pars = @parameters u_max=u_max [ - description = "Upper limit of dead zone of DeadZone $name", - ] u_min=u_min [description = "Lower limit of dead zone of DeadZone $name"] - eqs = [ - y ~ _dead_zone(u, u_min, u_max), - ] - extend(ODESystem(eqs, t, [], pars; name = name), siso) end """ - SlewRateLimiter(;name, rising=1, falling=-rising, Td=0.001, y_start=0.0) + SlewRateLimiter(; name, y_start, rising = 1.0, falling = -rising, Td = 0.001) Limits the slew rate of a signal. +Initial value of state `Y` can be set with `int.y` # Parameters: - `rising`: Maximum rising slew rate - `falling`: Maximum falling slew rate - `Td`: [s] Derivative time constant + - `y_start`: Initial value of `y` state of SISO # Connectors: - `input` - `output` """ -@component function SlewRateLimiter(; name, rising = 1, falling = -rising, Td = 0.001, - y_start = 0.0) - rising ≥ falling || throw(ArgumentError("`rising` must be smaller than `falling`")) - Td > 0 || throw(ArgumentError("Time constant `Td` must be strictly positive")) - @named siso = SISO(y_start = y_start) - @unpack u, y = siso - pars = @parameters rising=rising [ - description = "Maximum rising slew rate of SlewRateLimiter $name", - ] falling=falling [description = "Maximum falling slew rate of SlewRateLimiter $name"] Td=Td [ - description = "Derivative time constant of SlewRateLimiter $name", - ] - eqs = [ - D(y) ~ max(min((u - y) / Td, rising), falling), - ] - extend(ODESystem(eqs, t, [], pars; name = name), siso) +@mtkmodel SlewRateLimiter begin + @parameters begin + rising = 1.0, [description = "Maximum rising slew rate of SlewRateLimiter"] + falling = -rising, [description = "Derivative time constant of SlewRateLimiter"] + Td = 0.001, [description = "Derivative time constant"] + y_start + end + begin + getdefault(rising) ≥ getdefault(falling) || + throw(ArgumentError("`rising` must be smaller than `falling`")) + getdefault(Td) > 0 || + throw(ArgumentError("Time constant `Td` must be strictly positive")) + end + @extend u, y = siso = SISO(y_start = y_start) + @equations begin + D(y) ~ max(min((u - y) / Td, rising), falling) + end end From 0d4a2dc64a9b48ce6fe5c8174d7eb3e58aa571e8 Mon Sep 17 00:00:00 2001 From: Venkateshprasad <32921645+ven-k@users.noreply.github.com> Date: Mon, 3 Jul 2023 12:48:22 +0530 Subject: [PATCH 4/7] refactor: Blocks/sources.jl (limited) --- src/Blocks/sources.jl | 61 ++++++++++++++++------- src/Electrical/Analog/ideal_components.jl | 38 ++++++++------ test/Blocks/sources.jl | 2 +- test/demo.jl | 2 +- 4 files changed, 68 insertions(+), 35 deletions(-) diff --git a/src/Blocks/sources.jl b/src/Blocks/sources.jl index 1b640de9c..a0c753cc7 100644 --- a/src/Blocks/sources.jl +++ b/src/Blocks/sources.jl @@ -59,6 +59,8 @@ function triangular(x, f, amplitude, offset, start_time) end """ + Constant(; name, k = 0.0) + Generate constant signal. # Parameters: @@ -69,17 +71,20 @@ Generate constant signal. - `output` """ -@component function Constant(; name, k = 1) - @named output = RealOutput() - pars = @parameters k=k [description = "Constant output value of block $name"] - eqs = [ - output.u ~ k, - ] - compose(ODESystem(eqs, t, [], pars; name = name), [output]) +@mtkmodel Constant begin + @components begin + output = RealOutput() + end + @parameters begin + k = 0.0, [description = "Constant output value of block"] + end + @equations begin + output.u ~ k + end end """ - TimeVaryingFunction(f; t=t, name) + TimeVaryingFunction(f; name) Outputs ``f(t)``. @@ -88,15 +93,23 @@ The input variable `t` can be changed by passing a different variable as the key # Connectors: - `output` """ -@component function TimeVaryingFunction(f; t = t, name) - @named output = RealOutput() - eqs = [ - output.u ~ f(t), - ] - compose(ODESystem(eqs, Blocks.t; name = name), [output]) +@mtkmodel TimeVaryingFunction begin + @parameters begin + f + end + @components begin + output = RealOutput() + end + @equations begin + output.u ~ first(getdefault(f))(t) + end end +TimeVaryingFunction.f(f; name) = TimeVaryingFunction.f(; f = [f], name) """ + Sine(; name, frequency, amplitude = 1, phase = 0, offset = 0, start_time = 0, + smooth = false) + Generate sine signal. # Parameters: @@ -138,7 +151,10 @@ Generate sine signal. end """ -Generate cosine signal. + Cosine(; name, frequency, amplitude = 1, phase = 0, offset = 0, start_time = 0, + smooth = false) + +Cosine signal. # Parameters: - `frequency`: [Hz] Frequency of sine wave @@ -177,6 +193,8 @@ Generate cosine signal. end """ + ContinuousClock(; name, offset = 0, start_time = 0) + Generate current time signal. # Parameters: @@ -199,6 +217,8 @@ Generate current time signal. end """ +Ramp(; name, height = 1, duration = 1, offset = 0, start_time = 0, smooth = false) + Generate ramp signal. # Parameters: @@ -239,6 +259,8 @@ Generate ramp signal. end """ + Square(; name, frequency = 1.0, amplitude = 1.0, offset = 0.0, start_time = 0.0, + smooth = false) Generate smooth square signal. # Parameters: @@ -321,7 +343,9 @@ Generate step signal. end """ -Generate exponentially damped sine signal. + ExpSine(; name, frequency, amplitude = 1, damping = 0.1, phase = 0, offset = 0, start_time = 0, smooth = false) + +Exponentially damped sine signal. # Parameters: @@ -367,6 +391,9 @@ Generate exponentially damped sine signal. end """ + Triangular(; name, amplitude = 1.0, frequency = 1.0, offset = 0.0, + start_time = 0.0, smooth = false) + Generate smooth triangular signal for frequencies less than or equal to 25 Hz # Parameters: @@ -548,7 +575,7 @@ end """ SampledData(; name, buffer) -data input component. +data input component. # Parameters: - `buffer`: a `Parameter` type which holds the data and sample time diff --git a/src/Electrical/Analog/ideal_components.jl b/src/Electrical/Analog/ideal_components.jl index ed0b9a808..75104ac79 100644 --- a/src/Electrical/Analog/ideal_components.jl +++ b/src/Electrical/Analog/ideal_components.jl @@ -89,14 +89,17 @@ Creates an ideal capacitor. - `C`: [`F`] Capacitance - `v_start`: [`V`] Initial voltage of capacitor """ -@component function Capacitor(; name, C, v_start = 0.0) - @named oneport = OnePort(; v_start = v_start) - @unpack v, i = oneport - pars = @parameters C = C - eqs = [ - D(v) ~ i / C, - ] - extend(ODESystem(eqs, t, [], pars; name = name), oneport) +@mtkmodel Capacitor begin + @parameters begin + C + end + @variables begin + v + end + @extend v, i = oneport = OnePort(; v = v) + @equations begin + D(v) ~ i / C + end end """ @@ -118,14 +121,17 @@ See [OnePort](@ref) - `L`: [`H`] Inductance - `i_start`: [`A`] Initial current through inductor """ -@component function Inductor(; name, L, i_start = 0.0) - @named oneport = OnePort(; i_start = i_start) - @unpack v, i = oneport - pars = @parameters L = L - eqs = [ - D(i) ~ 1 / L * v, - ] - extend(ODESystem(eqs, t, [], pars; name = name), oneport) +@mtkmodel Inductor begin # name, L, i_start = 0.0) + @parameters begin + L + end + @variables begin + i + end + @extend v, i = oneport = OnePort(; i = i) + @equations begin + D(i) ~ 1 / L * v + end end """ diff --git a/test/Blocks/sources.jl b/test/Blocks/sources.jl index 2ad5160eb..f0ef3c952 100644 --- a/test/Blocks/sources.jl +++ b/test/Blocks/sources.jl @@ -37,7 +37,7 @@ end systems = [int, src]) sys = structural_simplify(iosys) - prob = ODEProblem(sys, Pair[int.x => 0.0], (0.0, 10.0)) + prob = ODEProblem(sys, Pair[], (0.0, 10.0)) sol = solve(prob, Rodas4()) @test sol.retcode == Success diff --git a/test/demo.jl b/test/demo.jl index 9f47185c9..3ce518687 100644 --- a/test/demo.jl +++ b/test/demo.jl @@ -12,7 +12,7 @@ using Test @named capacitor = Capacitor(C = C) @named voltage = Voltage() @named ground = Ground() - @named source = Constant() + @named source = Constant(k = 1) rc_eqs = [connect(source.output, voltage.V) connect(voltage.p, resistor.p) From 4acbee659d09e9ed50e42ea592e3ec6b6c8ac1b4 Mon Sep 17 00:00:00 2001 From: Venkateshprasad <32921645+ven-k@users.noreply.github.com> Date: Mon, 3 Jul 2023 12:48:46 +0530 Subject: [PATCH 5/7] refactor: Blocks/utils.jl (limited) --- src/Blocks/Blocks.jl | 1 + src/Blocks/utils.jl | 33 +++++++++++++------- src/Electrical/Analog/ideal_components.jl | 38 ++++++++++------------- test/Hydraulic/isothermal_compressible.jl | 2 +- 4 files changed, 39 insertions(+), 35 deletions(-) diff --git a/src/Blocks/Blocks.jl b/src/Blocks/Blocks.jl index 38331019b..1a7cdb5c6 100644 --- a/src/Blocks/Blocks.jl +++ b/src/Blocks/Blocks.jl @@ -5,6 +5,7 @@ module Blocks using ModelingToolkit, Symbolics using IfElse: ifelse import ..@symcheck +using ModelingToolkit: getdefault @parameters t D = Differential(t) diff --git a/src/Blocks/utils.jl b/src/Blocks/utils.jl index b9ff73c7a..59db3655b 100644 --- a/src/Blocks/utils.jl +++ b/src/Blocks/utils.jl @@ -55,27 +55,36 @@ Connector with one output signal of type Real. """ RealOutput """ - SISO(;name, u_start=0.0, y_start=0.0) + SISO(;name, u_start = 0.0, y_start = 0.0) Single input single output (SISO) continuous system block. # Parameters: - - `u_start`: Initial value for the input - - `y_start`: Initial value for the output + - `u`: Initial value for the input + - `y`: Initial value for the output """ -@component function SISO(; name, u_start = 0.0, y_start = 0.0) - @named input = RealInput(u_start = u_start) - @named output = RealOutput(u_start = y_start) - @variables(u(t)=u_start, [description = "Input of SISO system $name"], - y(t)=y_start, [description = "Output of SISO system $name"],) - eqs = [u ~ input.u - y ~ output.u] - return ODESystem(eqs, t, [u, y], []; name = name, systems = [input, output]) +@mtkmodel SISO begin + @parameters begin + u_start = 0.0 + y_start = 0.0 + end + @variables begin + u(t) = u_start, [description = "Input of SISO system"] + y(t) = y_start, [description = "Output of SISO system"] + end + @components begin + input = RealInput(u_start = 0.0) + output = RealOutput(u_start = 0.0) + end + @equations begin + u ~ input.u + y ~ output.u + end end """ - MIMO(;name, nin=1, nout=1, u_start=zeros(nin), y_start=zeros(nout)) + MIMO(; name, nin = 1, nout = 1, u_start = zeros(nin), y_start = zeros(nout)) Base class for a multiple input multiple output (MIMO) continuous system block. diff --git a/src/Electrical/Analog/ideal_components.jl b/src/Electrical/Analog/ideal_components.jl index 75104ac79..ed0b9a808 100644 --- a/src/Electrical/Analog/ideal_components.jl +++ b/src/Electrical/Analog/ideal_components.jl @@ -89,17 +89,14 @@ Creates an ideal capacitor. - `C`: [`F`] Capacitance - `v_start`: [`V`] Initial voltage of capacitor """ -@mtkmodel Capacitor begin - @parameters begin - C - end - @variables begin - v - end - @extend v, i = oneport = OnePort(; v = v) - @equations begin - D(v) ~ i / C - end +@component function Capacitor(; name, C, v_start = 0.0) + @named oneport = OnePort(; v_start = v_start) + @unpack v, i = oneport + pars = @parameters C = C + eqs = [ + D(v) ~ i / C, + ] + extend(ODESystem(eqs, t, [], pars; name = name), oneport) end """ @@ -121,17 +118,14 @@ See [OnePort](@ref) - `L`: [`H`] Inductance - `i_start`: [`A`] Initial current through inductor """ -@mtkmodel Inductor begin # name, L, i_start = 0.0) - @parameters begin - L - end - @variables begin - i - end - @extend v, i = oneport = OnePort(; i = i) - @equations begin - D(i) ~ 1 / L * v - end +@component function Inductor(; name, L, i_start = 0.0) + @named oneport = OnePort(; i_start = i_start) + @unpack v, i = oneport + pars = @parameters L = L + eqs = [ + D(i) ~ 1 / L * v, + ] + extend(ODESystem(eqs, t, [], pars; name = name), oneport) end """ diff --git a/test/Hydraulic/isothermal_compressible.jl b/test/Hydraulic/isothermal_compressible.jl index 7d831ac02..3d637fdf8 100644 --- a/test/Hydraulic/isothermal_compressible.jl +++ b/test/Hydraulic/isothermal_compressible.jl @@ -256,7 +256,7 @@ end if use_input @named input = B.SampledData(Float64) else - @named input = B.TimeVaryingFunction(f; t) + @named input = B.TimeVaryingFunction(f) end push!(systems, input) From 518df2b72f9f964468039e3ad316076e0c32f8d1 Mon Sep 17 00:00:00 2001 From: Venkateshprasad <32921645+ven-k@users.noreply.github.com> Date: Tue, 11 Jul 2023 19:23:20 +0530 Subject: [PATCH 6/7] docs: set MTK to 8 --- docs/Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Project.toml b/docs/Project.toml index 9027ab4aa..d69549620 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -13,7 +13,7 @@ ControlSystemsBase = "1.1" DifferentialEquations = "7.6" Documenter = "0.27" IfElse = "0.1" -ModelingToolkit = "8.33" +ModelingToolkit = "8" ModelingToolkitStandardLibrary = "1.8" OrdinaryDiffEq = "6.31" Plots = "1.36" \ No newline at end of file From 6a09473f58635468b526169e02b47fa69ce918fc Mon Sep 17 00:00:00 2001 From: Venkateshprasad <32921645+ven-k@users.noreply.github.com> Date: Mon, 17 Jul 2023 11:39:44 +0530 Subject: [PATCH 7/7] refactor: update the arglist of non-dsl components to match the style of dsl components - this will allow upgradation of those without breaking again --- src/Blocks/continuous.jl | 36 +++++++++++++++++------------------- test/Blocks/continuous.jl | 8 ++++---- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/Blocks/continuous.jl b/src/Blocks/continuous.jl index af34d36dd..4cacd52df 100644 --- a/src/Blocks/continuous.jl +++ b/src/Blocks/continuous.jl @@ -214,7 +214,7 @@ See also [`LimPI`](@ref) end """ - PID(;name, k=1, Ti=false, Td=false, Nd=10, xi_start=0, xd_start=0) + PID(;name, k=1, Ti=false, Td=false, Nd=10, int__x=0, der__x=0) Text-book version of a PID-controller without actuator saturation and anti-windup measure. @@ -224,8 +224,8 @@ Text-book version of a PID-controller without actuator saturation and anti-windu - `Ti`: [s] Integrator time constant (Ti>0 required). If set to false, no integral action is used. - `Td`: [s] Derivative time constant (Td>0 required). If set to false, no derivative action is used. - `Nd`: [s] Time constant for the derivative approximation (Nd>0 required; Nd=0 is ideal derivative). - - `x_start`: Initial value for the integrator. - - `xd_start`: Initial value for the derivative state. + - `int__x`: Initial value for the integrator. + - `der__x`: Initial value for the derivative state. # Connectors: @@ -234,8 +234,8 @@ Text-book version of a PID-controller without actuator saturation and anti-windu See also [`LimPID`](@ref) """ -@component function PID(; name, k = 1, Ti = false, Td = false, Nd = 10, xi_start = 0, - xd_start = 0) +@component function PID(; name, k = 1, Ti = false, Td = false, Nd = 10, int__x = 0, + der__x = 0) with_I = !isequal(Ti, false) with_D = !isequal(Td, false) @named err_input = RealInput() # control error @@ -249,12 +249,12 @@ See also [`LimPID`](@ref) @named gainPID = Gain(k) @named addPID = Add3() if with_I - @named int = Integrator(k = 1 / Ti, x = xi_start) + @named int = Integrator(k = 1 / Ti, x = int__x) else @named Izero = Constant(k = 0) end if with_D - @named der = Derivative(k = Td, T = 1 / Nd, x = xd_start) + @named der = Derivative(k = Td, T = 1 / Nd, x = der__x) else @named Dzero = Constant(k = 0) end @@ -290,11 +290,9 @@ See also [`LimPID`](@ref) end """ - LimPI(; name, T, Ta, k = 1.0, x_start = 0.0, u_max = 1.0, u_min = -u_max) + LimPI(; name, T, Ta, k = 1.0, int__x = 0.0, u_max = 1.0, u_min = -u_max) Text-book version of a PI-controller with actuator saturation and anti-windup measure. -Initial value of gain can be set with `gainPI.k` -Initial value of integrator state `x` can be set with `int.x` # Parameters: @@ -306,7 +304,7 @@ Initial value of integrator state `x` can be set with `int.x` - `err_input` - `ctr_output` """ -@component function LimPI(; name, k = 1, T, u_max, u_min = -u_max, Ta, x_start = 0.0) +@component function LimPI(; name, k = 1, T, u_max, u_min = -u_max, Ta, 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")) @@ -316,7 +314,7 @@ Initial value of integrator state `x` can be set with `int.x` @named gainPI = Gain(k) @named addPI = Add() @named addTrack = Add() - @named int = Integrator(k = 1 / T, x = x_start) + @named int = Integrator(k = 1 / T, x = int__x) @named limiter = Limiter(y_max = u_max, y_min = u_min) @named addSat = Add(k1 = 1, k2 = -1) @named gainTrack = Gain(1 / Ta) @@ -376,8 +374,8 @@ where the transfer function for the derivative includes additional filtering, se u_max = Inf, u_min = u_max > 0 ? -u_max : -Inf, gains = false, - xi_start = 0.0, - xd_start = 0.0) + int__x = 0.0, + der__x = 0.0) with_I = !isequal(Ti, false) with_D = !isequal(Td, false) with_AWM = Ni != Inf @@ -412,12 +410,12 @@ where the transfer function for the derivative includes additional filtering, se else @named addI = Add(k1 = 1, k2 = -1) end - @named int = Integrator(k = 1 / Ti, x = xi_start) + @named int = Integrator(k = 1 / Ti, x = int__x) else @named Izero = Constant(k = 0) end if with_D - @named der = Derivative(k = Td, T = 1 / Nd, x = xd_start) + @named der = Derivative(k = Td, T = 1 / Nd, x = der__x) @named addD = Add(k1 = wd, k2 = -1) else @named Dzero = Constant(k = 0) @@ -473,7 +471,7 @@ where the transfer function for the derivative includes additional filtering, se end """ - StateSpace(A, B, C, D=0; x_start=zeros(size(A,1)), u0=zeros(size(B,2)), y0=zeros(size(C,1)), name) + StateSpace(A, B, C, D = 0; x = zeros(size(A,1)), u0 = zeros(size(B,2)), y0 = zeros(size(C,1)), name) A linear, time-invariant state-space system on the form. @@ -506,7 +504,7 @@ y &= h(x, u) linearized around the operating point `x₀, u₀`, we have `y0, u0 = h(x₀, u₀), u₀`. """ -@component function StateSpace(; A, B, C, D = nothing, x_start = zeros(size(A, 1)), name, +@component function StateSpace(; A, B, C, D = nothing, x = zeros(size(A, 1)), name, u0 = zeros(size(B, 2)), y0 = zeros(size(C, 1))) nx, nu, ny = size(A, 1), size(B, 2), size(C, 1) size(A, 2) == nx || error("`A` has to be a square matrix.") @@ -522,7 +520,7 @@ linearized around the operating point `x₀, u₀`, we have `y0, u0 = h(x₀, u end @named input = RealInput(nin = nu) @named output = RealOutput(nout = ny) - @variables x(t)[1:nx]=x_start [ + @variables x(t)[1:nx]=x [ description = "State variables of StateSpace system $name", ] # pars = @parameters A=A B=B C=C D=D # This is buggy diff --git a/test/Blocks/continuous.jl b/test/Blocks/continuous.jl index 3dffa3b1f..bdd4739c8 100644 --- a/test/Blocks/continuous.jl +++ b/test/Blocks/continuous.jl @@ -92,7 +92,7 @@ end B = [0, 1] C = [0.9 1;] D = [0;;] - @named ss = StateSpace(; A, B, C, D, x_start = zeros(2)) + @named ss = StateSpace(; A, B, C, D, x = zeros(2)) @named c = Constant(; k = 1) @named model = ODESystem([ connect(c.output, ss.input), @@ -113,7 +113,7 @@ end # non-zero operating point u0 = [1] # This causes no effective input to the system since c.k = 1 y0 = [2] - @named ss = StateSpace(; A, B, C, D, x_start = zeros(2), u0, y0) + @named ss = StateSpace(; A, B, C, D, x = zeros(2), u0, y0) @named model = ODESystem([ connect(c.output, ss.input), ], @@ -133,11 +133,11 @@ end """ Second order demo plant """ -@component function Plant(; name, x_start = zeros(2)) +@component function Plant(; name, x = zeros(2)) @named input = RealInput() @named output = RealOutput() D = Differential(t) - sts = @variables x1(t)=x_start[1] x2(t)=x_start[2] + sts = @variables x1(t)=x[1] x2(t)=x[2] eqs = [D(x1) ~ x2 D(x2) ~ -x1 - 0.5 * x2 + input.u output.u ~ 0.9 * x1 + x2]