RODESystem

Construction of RODESystem

A RODESystem is represented by the state function

\[\begin{array}{l} dx = f(x, u, t, W) \end{array}\]

and the output function

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

where $t$ is the time, $x \in R^n$ is the state, $u \in R^p$ and $y \in R^m$ is output of the system. Therefore to construct a RODESystem, we need to define statefunc and outputfunc with the corresponding syntax,

function statefunc(dx, x, u, t)
    dx .= ... # Update dx 
end

and

function outputfunc(x, u, t)
    y = ... # Compute y
    return y
end

As an example, consider the system with the state function

\[ \begin{array}{l} dx_1 = 2 x_1 sin(W_1 - W_2) \\ dx_2 = -2 x_2 cos(W_1 + W_2) \end{array}\]

and with the output function

\[ y = x\]

That is, all the state variable are taken as output. The statefunc and the outputfunc is defined as,


julia> function statefunc(dx, x, u, t, W)
           dx[1] = 2x[1]*sin(W[1] - W[2])
           dx[2] = -2x[2]*cos(W[1] + W[2])
       end
statefunc (generic function with 1 method)

julia> outputfunc(x, u, t) = x
outputfunc (generic function with 1 method)

To construct the RODESystem, we need to specify the initial condition and time.

julia> x0 = [1., 1.]
2-element Array{Float64,1}:
 1.0
 1.0

julia> t = 0.
0.0

Note from statefunc, the system has not any input, i.e. input is nothing, and has an output with a dimension of 1.

julia> input = nothing

julia> output = Bus(2)
2-element Bus{Link{Float64}}:
 Link(state:open, eltype:Float64, hasmaster:false, numslaves:0, isreadable:false, iswritable:false)
 Link(state:open, eltype:Float64, hasmaster:false, numslaves:0, isreadable:false, iswritable:false)

We are ready to construct the system

julia> ds = RODESystem(input, output, statefunc, outputfunc, x0, t)
ERROR: Fixed timestep methods require a choice of dt or choosing the tstops

Note that ds has a solver to solve its state function statefunc which is random differential equation. To solve its statefunc, the step size of the solver must be specified. See Random Differential Equtions of DifferentialEquations package.

julia> ds.solver.params[:dt] = 1 / 100
ERROR: UndefVarError: ds not defined

Basic Operation of RODESystem

When a RODESystem is triggered from its trigger link, it read the current time from its trigger link, reads its input (if available, i.e. its input is not nothing), solves its state function, computes its output value and writes its output value its output bus (again, if available, i.e., its output bus is not nothing). To drive a RODESystem, it must be launched. Let us continue with ds constructed in the previous section.

julia> task = launch(ds)
ERROR: UndefVarError: ds not defined

When launched, ds is ready to be driven. We can drive ds by drive(ds, t) or put!(ds.trigger, t) where t is the time until which we will drive ds.

julia> drive(ds, 1.)
ERROR: UndefVarError: ds not defined

When triggered, ds read the time t from its trigger link, solved its differential equation, computed its value and writes its output value to its output bus. To signal that, the evolution is succeeded, ds writes true to its handshake link which must be taken to further drive ds. (approve(ds)) can also be used.

julia> take!(ds.handshake)
ERROR: UndefVarError: ds not defined

We can continue to drive ds.

julia> for t in 2. : 10.
           put!(ds.trigger, t)
           take!(ds.handshake)
       end
ERROR: UndefVarError: ds not defined

After each evolution, ds writes its current output value to its output bus.

julia> [ds.output[1].buffer.data ds.output[2].buffer.data]
ERROR: UndefVarError: ds not defined

When launched, a task was constructed which still running. As long as no exception is thrown during the evolution of ds, the state of task is running which implies ds can be driven.

julia> task
ERROR: UndefVarError: task not defined

To terminate the task safely, ds should be terminated safely.

julia> terminate(ds)
ERROR: UndefVarError: ds not defined

Note that the state of task is done which implies the task has been terminated safely.

julia> task
ERROR: UndefVarError: task not defined

Full API

Jusdl.Components.Systems.DynamicSystems.RODESystemType
RODESystem(input, output, statefunc, outputfunc, state, t, modelargs=(), solverargs=(); 
    alg=RODEAlg, modelkwargs=NamedTuple(), solverkwargs=NamedTuple())

Constructs a RODESystem with input and output. statefunc is the state function and outputfunc is the output function. 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 differential equation of the system.

The RODESystem is represented by the equations,

\[ \begin{array}{l} dx = f(x, u, t, W)dt \\[0.25] y = g(x, u, t) \end{array}\]

where $x$ is the state, $u$ is the value of input, $y$ the value of output, ant $t$ is the time t. $f$ is the statefunc and $g$ is the outputfunc. $W$ is the Wiene process. noise is the noise of the system and solver is used to solve the above differential equation.

The signature of statefunc must be of the form

function statefunc(dx, x, u, t, W)
    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> function statefunc(dx, x, u, t, W)
         dx[1] = 2x[1]*sin(W[1] - W[2])
         dx[2] = -2x[2]*cos(W[1] + W[2])
       end;

julia> outputfunc(x, u, t) = x;

julia> ds = RODESystem(nothing, Bus(2), statefunc, outputfunc, [1., 1.], 0., solverkwargs=(dt=0.01,))
RODESystem(state:[1.0, 1.0], t:0.0, input:nothing, output:Bus(nlinks:2, eltype:Link{Float64}, isreadable:false, iswritable:false))
Info

See DifferentialEquations for more information about modelargs, modelkwargs, solverargs solverkwargs and alg.

source