DiscreteSystem
Construction of DiscreteSystem
DiscreteSystem
s evolve by the following discrete time difference equation.
where $x_k$ is the state, $y_k$ is the value of output
and $u_k$ is the value of input
at discrete time t
. $f$ is the state function and $g$ is the output function of the system. See the main constructor.
Basic Construction of DiscreteSystem
When a DiscreteSystem
is triggered from its trigger
link, it reads current time from its trigger
link, reads its input
, solves its difference equation, computes its output and writes its output value to its output
bus. Let us continue with an example.
We first define state function sfunc
and output function ofunc
of the system,
julia> using Jusdl # hide
julia> sfunc(dx, x, u, t) = (dx .= -0.5x)
sfunc (generic function with 1 method)
julia> ofunc(x, u, t) = x
ofunc (generic function with 1 method)
From sfunc
, it is seen that the system does not have any input, and from ofunc
the system has one output. Thus, the input
and output
of the system is
julia> input = nothing
julia> output = Bus(1)
1-element Bus{Link{Float64}}:
Link(state:open, eltype:Float64, hasmaster:false, numslaves:0, isreadable:false, iswritable:false)
We also need to specify the initial condition and time of the system
julia> x0 = [1.]
1-element Array{Float64,1}:
1.0
julia> t = 0.
0.0
We are now ready to construct the system ds
.
julia> ds = DiscreteSystem(input, output, sfunc, ofunc, x0, t)
DiscreteSystem(state:[1.0], t:0.0, input:nothing, output:Bus(nlinks:1, eltype:Link{Float64}, isreadable:false, iswritable:false))
To drive ds
, we need to launch
it.
julia> task = launch(ds)
(Task (runnable) @0x00007f70295a24a0, Task (runnable) @0x00007f70295a2230)
At this point, ds
is ready to be driven. To drive ds
, we can either use drive(ds, t)
or put!(ds.trigger, t)
.
julia> drive(ds, 1.)
1.0
When the above code is executed, ds
evolves until its time is ds.t
is 1., During this evolution, ds
reads time t
from its trigger
link, reads its input
(in this example, ds
has no input, so it does nothing when reading its input), solves its difference equation, computes its output and writes its output value to its output
. To signal that the evolution is succeeded, ds
writes true
its handshake
link which needs to be taken to further drive ds
.
julia> ds.handshake # `handshake` link is readable
ERROR: UndefVarError: ds not defined
julia> take!(ds.handshake)
ERROR: UndefVarError: ds not defined
We continue to drive ds
,
julia> for i in 2. : 10.
drive(ds, i)
take!(ds.handshake)
end
ERROR: UndefVarError: drive not defined
Note that all the output values of ds
is written to its output
bus.
julia> ds.output[1].buffer.data
64-element Array{Float64,1}:
-0.5
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
When we launched ds
, we constructed a task
which is still running.
julia> task
(Task (runnable) @0x00007f70295a24a0, Task (runnable) @0x00007f70295a2230)
As long nothing goes wrong, i.e. no exception is thrown, during the evolution of ds
, it is possible to drive ds
. To safely terminate the task
, we need to terminate the ds
.
julia> terminate(ds)
We can confirm that the task
is not running and its state is done
.
julia> task
(Task (runnable) @0x00007f70295a24a0, Task (done) @0x00007f70295a2230)
Since the task
is not running any more, ds
cannot be drivable any more. However to drive ds
again, we need launch ds
again.
Full API
Jusdl.Components.Systems.DynamicSystems.DiscreteSystem
— TypeDiscreteSystem(input, output, statefunc, outputfunc, state, t, modelargs=(), solverargs=();
alg=DiscreteAlg, modelkwargs=NamedTuple(), solverkwargs=NamedTuple())
Construct a DiscreteSystem
with input
and output
. statefunc
is the state function and outputfunc
is the output function of DiscreteSystem
. state
is the initial state and t
is the time. modelargs
and modelkwargs
are passed into ODEProblem
and solverargs
and solverkwargs
are passed into solve
method of DifferentialEquations
. alg
is the algorithm to solve the diffence equation of the system.
The system is represented by
where $x_k$ is the state, $y_k$ is the value of output, $u_k$ is the value of input at dicrete time $k$. $f` is `statefunc` and$g`is
outputfunc`.
The signature of statefunc
must be of the form
function statefunc(dx, x, u, t)
dx = ... # Update dx
end
and the signature of outputfunc
must be of the form
function outputfunc(x, u, t)
y = ... # Compute y
return y
end
Example
julia> sfunc(dx,x,u,t) = (dx .= 0.5x)
sfunc (generic function with 1 method)
julia> ofunc(x, u, t) = x
ofunc (generic function with 1 method)
julia> ds = DiscreteSystem(Bus(1), Bus(1), sfunc, ofunc, [1.], 0.)
DiscreteSystem(state:[1.0], t:0.0, input:Bus(nlinks:1, eltype:Link{Float64}, isreadable:false, iswritable:false), output:Bus(nlinks:1, eltype:Link{Float64}, isreadable:false, iswritable:false))
See DifferentialEquations for more information about modelargs
, modelkwargs
, solverargs
, solverkwargs
and alg
.