StaticSystems

Basic Operation of StaticSystems

Static systems are the systems whose output y at time t depends on the current time t and the value of their inputs u. The input-output relation of static systems are represented by their output function outputfunc which is of the form

\[ y = g(u, t)\]

where g is the output function outputfunc. Note that outputfunc is expected to have two inputs, the value u of the input and the current time t. The simulation in Jusdl is a clocked-simulation, that is the data flowing through the input and output connections of components is actually sampled at time t. Therefore, for example, the system modeled by

\[y(t) = g(u(t),t)\]

is actually sampled at clock ticks t which is generated by a Clock. Therefore the sampled system corresponds to

\[y[k] = g(u_k, t_k)\]

where $k$ is $k_i T_s$ where $k_i$ is an integer number, $T_s$ is the sampling interval. $T_s$ corresponds to sampling time dt of Clock. Thus, the system given above is coded like

function g(u, t)
    # Define the relation `y = g(u, t)`
end

For further clarity, let us continue with a case study. Consider the following static system,

\[ y(t) = g(u(t), t) = \left[ \begin{array}{l} t u_1(t) \\ sin(u_1(t)) \\ cos(u_2(t)) \end{array} \right]\]

Note that the number of inputs is 2 and the number of outputs of is 3. To define such a system, the output function is written as


julia> g(u, t) = [t * u[1], sin(u[1]), cos(u[2])]
g (generic function with 1 method)

Note that the function g is defined in such a way that the input value u is sampled, which implies u is not a vector of function but is a vector of real. Having defined output function outputfunc, the system can be constructed.

julia> ss = StaticSystem(Bus(2), Bus(3), g)
StaticSystem(outputfunc:g, input:Bus(nlinks:2, eltype:Link{Float64}, isreadable:false, iswritable:false), output:Bus(nlinks:3, eltype:Link{Float64}, isreadable:false, iswritable:false))

Note the construction of input bus Bus(2) and output bus Bus(3) by recalling that the number of input is 2 and the number of output is 3.

A StaticSystem operates by being triggered through its trigger link. When triggered from its trigger link, a StaticSystem read the current time t from its trigger link and computes its output y according to its output function outputfunc and writes its output t to its output bus (if output bus exists since output bus may be nothing depending on the relation defined by outputfunc). When constructed, a StaticSystem is not ready to be triggered since its trigger link is not writeable.

julia> ss.trigger
Link(state:open, eltype:Float64, hasmaster:false, numslaves:0, isreadable:false, iswritable:false)

To make ss drivable, we need to launch ss.

julia> task = launch(ss)
(Task (runnable) @0x00007f70295b8280, Task (runnable) @0x00007f70295b8010)

Now, ss is drivable from its trigger link.

julia> ss.trigger
Link(state:open, eltype:Float64, hasmaster:false, numslaves:0, isreadable:false, iswritable:true)

Now let us drive ss.

julia> put!(ss.trigger, 1.)
1.0

As this point ss wait for its to be written. Let us write some data to input of ss.

julia> put!(ss.input, [10., 10.])
2-element Array{Float64,1}:
 10.0
 10.0

ss read the value u of its input , read the current time t, and computed its output value y and wrote it its output. To signal that it succeeded to be take the step, it put a true to its handshake which needs to be taken.

julia> ss.handshake
Link(state:open, eltype:Bool, hasmaster:false, numslaves:0, isreadable:true, iswritable:false)

julia> take!(ss.handshake)
true

We can see the current data in the output of ss.

julia> println(ss.output[1].buffer.data)
[10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

Let us further drive ss.

julia> for t in 2. : 10.
           put!(ss.trigger, t)
           put!(ss.input, [10 * t, 20 * t])
           take!(ss.handshake)
       end

The data written to the output of ss is also written to the internal buffers of output.

julia> println(ss.output[1].buffer.data)
[10.0, 40.0, 90.0, 160.0, 250.0, 360.0, 490.0, 640.0, 810.0, 1000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

Full API

Jusdl.Components.Systems.StaticSystems.StaticSystemType
StaticSystem(input, output, outputfunc)

Construts a StaticSystem with input input, output output and output function outputfunc. outputfunc is a two-argument function of the form

\[ y = g(u, t)\]

where g is outputfunc, t is the time, u is the input at time t and y is the output at time t. input and output may be nothing depending on relation defined in outputfunc.

Example

julia> g(u, t) = [u[1] + u[2], sin(u[2]), cos([1])]  # The system has 2 inputs and 3 outputs.
g (generic function with 1 method)

julia> ss = StaticSystem(Bus(2), Bus(3), g)
StaticSystem(outputfunc:g, input:Bus(nlinks:2, eltype:Link{Float64}, isreadable:false, iswritable:false), output:Bus(nlinks:3, eltype:Link{Float64}, isreadable:false, iswritable:false))

julia> g2(u, t) = t  # The system does not have any input.
g2 (generic function with 1 method)

julia> ss2 = StaticSystem(nothing, Bus(), g2)
StaticSystem(outputfunc:g2, input:nothing, output:Bus(nlinks:1, eltype:Link{Float64}, isreadable:false, iswritable:false))
source
Jusdl.Components.Systems.StaticSystems.AdderType
Adder(input::Bus[, signs])

Construts an Adder with input bus input and signs signs. signs is a tuplle of + and/or -. The output function g of Adder is of the form,

\[ y = g(u, t) = \sum_{j = 1}^n s_k u_k\]

where n is the length of the input, $s_k$ is the kth element of signs, $u_k$ is the kth value of input and $y$ is the value of output. The default value of signs is all +.

Example

julia> adder = Adder(Bus(3), (+, +, -));

julia> adder.outputfunc([3, 4, 5], 0.) == 3 + 4 - 5
true
source
Jusdl.Components.Systems.StaticSystems.MultiplierType
Multiplier(input::Bus[, ops])

Construts an Multiplier with input bus input and signs signs. signs is a tuplle of * and/or /. The output function g of Multiplier is of the form,

\[ y = g(u, t) = \prod_{j = 1}^n s_k u_k\]

where n is the length of the input, $s_k$ is the kth element of signs, $u_k$ is the kth value of input and $y$ is the value of the output. The default value of signs is all *.

Example

julia> mlt = Multiplier(Bus(3), (*, *, /));

julia> mlt.outputfunc([3, 4, 5], 0.) == 3 * 4 / 5
true
source
Jusdl.Components.Systems.StaticSystems.GainType
Gain(input; gain=1.)

Constructs a Gain whose output function g is of the form

\[ y = g(u, t) = K u\]

where $K$ is gain, $u$ is the value of input and y is the value of output.

Example

julia> K = [1. 2.; 3. 4.];

julia> g = Gain(Bus(2), gain=K);

julia> g.outputfunc([1., 2.], 0.) == K * [1., 2.]
true
source
Jusdl.Components.Systems.StaticSystems.MemoryType
Memory(input::Bus{Union{Missing, T}}, numdelay::Int; initial=Vector{T}(undef, length(input)))

Constructs a 'Memorywith input businput. A 'Memory delays the values of input by an amount of numdelay. initial determines the transient output from the Memory, that is, until the internal buffer of Memory is full, the values from initial is returned.

source
Jusdl.Components.Systems.StaticSystems.CouplerType
Coupler(conmat::AbstractMatrix, cplmat::AbstractMatrix)

Constructs a coupler from connection matrix conmat of size $n \times n$ and coupling matrix cplmat of size $d \times d$. The output function g of Coupler is of the form

\[ y = g(u, t) = (E \otimes P) u\]

where $\otimes$ is the Kronecker product, $E$ is conmat and $P$ is cplmat, $u$ is the value of input and y is the value of output.

source