Construction and Simulation of Subsystems
In this tutorial, we will construct and simulate subsystems. A subsystem consists of connected components. A subsystem can serve as a component of a model. That is, components of a model can be a subsystem consisting of sub-components. The input/output port of a subsystem can be specified from the input/output port of components of the subsystem. It is also possible that a subsystem may have no input/output. That is, the input or output of a subsystem is nothing.
Like the construction of a model, a subsystem is constructed by constructing the sub-components of the subsystem and connecting the sub-components.
Since a subsystem serves a standalone component in a model, the components of the subsystem must be connected to each other. Otherwise, the subsystem cannot take step which in turn causes the simulation to get stuck.
Consider the simple subsystem whose block diagram is given below.
We first construct the subsystem.
using Jusdl
# Construct a subsystem
adder = Adder((+,-))
gain = Gain()
gen = ConstantGenerator()
connect!(gen.output, adder.input[2])
connect!(adder.output, gain.input)
sub = SubSystem([gen, adder, gain], adder.input[1], gain.output)
SubSystem(input:Inport(numpins:1, eltype:Inpin{Float64}), output:Outport(numpins:1, eltype:Outpin{Float64}), components:AbstractComponent[ConstantGenerator(amp:1.0), Adder(signs:(+, -), input:Inport(numpins:2, eltype:Inpin{Float64}), output:Outport(numpins:1, eltype:Outpin{Float64})), Gain(gain:1.0, input:Inport(numpins:1, eltype:Inpin{Float64}), output:Outport(numpins:1, eltype:Outpin{Float64}))])
Since these components will serve as a subsystem, we must connect them. The input port of adder
and output port of gain
is specified as the input and output port of the subsystem sub
. That is, we have a single-input-single-output subsystem.
Then, we construct the model. We drive the subsystem with a generator and save its output in a writer as shown in the block diagram below.
Thus, we construct other remaining components.
model = Model()
addnode!(model, sub, label=:sub)
addnode!(model, SinewaveGenerator(frequency=5), label=:gen)
addnode!(model, Writer(), label=:writer)
Then, to construct the model, we connect the components of the model
addbranch!(model, :gen => :sub, 1 => 1)
addbranch!(model, :sub => :writer, 1 => 1)
At this step, we are ready to simulate the model.
sim = simulate!(model)
sim
Simulation(state:done, retcode:success, path:/tmp/Simulation-0366380b-d652-4a84-984f-8fc3ee28db69)
We, then, read the simulation data from the writer and plot it.
using Plots
t, x = read(getnode(model, :writer).component)
plot(t, x)