zekeriyasari / Causal.jl

Causal.jl - A modeling and simulation framework adopting causal modeling approach.
https://zekeriyasari.github.io/Causal.jl/dev/
Other
115 stars 7 forks source link

Multiple inputs, multiple outpus (MIMO system) with Causal.ContinuousLinearSystem #52

Closed Ricardo-Luis closed 3 years ago

Ricardo-Luis commented 3 years ago

Hi, First of all, congratulations for your work! I discovered Causal (Jusdl) on JuliaCon2020. I'm a new adopter of Julia coming from Matlab/Simulink. I tested with success some examples that you provided in Pluto (Julia notebook).

In Causal.ContinuousLinearSystem the state-space model could admit multiple inputs and outputs? That is, could x, y and u be vectors?

Best regards, Ricardo Luís

Tried code for a 3-phase voltage system feeding a 3-phase balanced RL load, to simulate the load currents:

(voltage, frequency, Resistor, Inductance)

(U, f, R, L)=(230., 50., 10., 10.e-3); using Causal

three-phase voltages:

u1=SinewaveGenerator(amplitude=U*sqrt(2), frequency=f, phase=0.)
u2=SinewaveGenerator(amplitude=U*sqrt(2), frequency=f, phase=-2*pi/3)
u3=SinewaveGenerator(amplitude=U*sqrt(2), frequency=f, phase=2*pi/3)

state-space model parameters:

Aa=-R/L*[1 0 0; 0 1 0; 0 0 1]
Bb=1/L*[1 0 0; 0 1 0; 0 0 1]
Cc=[1 0 0; 0 1 0; 0 0 1]
Dd=zeros(3,3)

@defmodel model begin @nodes begin gen=[u1;u2;u3] ds = ContinuousLinearSystem(A=Aa, B=Bb, C=Cc, D=Dd, state=zeros(3,3)) writerin = Writer() writerout = Writer() end @branches begin gen => ds gen => writerin ds => writerout end end

zekeriyasari commented 3 years ago

Thank you @Ricardo-Luis I am very glad that you liked Causal.jl

ContinuousLinearSystem is a generic continuous-time linear system, so it is possible for ContinuousLinearSystem to have p-dimensional input vector, n-dimensional state vector and m-dimensional output vector. The important point here is that while constructing an instance of ContinuousLinearSystem, the input, state and output dimensions must be specified explicitly and, of course correctly (in order not to have a DimensionMismatch error).

In the code above, you constructed three different voltage sources having different phases. Of course this is an option, but you do not have to do so. You can combine all these voltage sources into one single three-phase voltage source gen. Again, we need to be careful here because now gen has an output of length three.

Below is the complete code I wrote to simulate the system. Hope this helps.

using Causal
using Plots 

# Define system parameters 
U, f, R, L = 230., 50., 10., 10.e-3

# A single 3-phase voltage source. 
gen = FunctionGenerator(readout = t -> [
        sin(2π * f * t + 0.),
        sin(2π * f * t - 2/3π),
        sin(2π * f * t + 2/3π)
    ],
    output = Outport(3)
)

# State-space model parameters 
Aa = -R / L * [1. 0 0; 0 1 0; 0 0 1]
Bb = 1 / L * [1. 0 0; 0 1 0; 0 0 1]
Cc = [1. 0 0; 0 1 0; 0 0 1]
Dd = zeros(3,3)

# The model 
@defmodel model begin
    @nodes begin
        gen = gen
        ds = ContinuousLinearSystem(A=Aa, B=Bb, C=Cc, D=Dd, state=zeros(3), input=Inport(3), output=Outport(3))
        writerin = Writer(input=Inport(3))
        writerout = Writer(input=Inport(3))
    end
    @branches begin
        gen => ds
        gen => writerin
        ds => writerout
    end
end

# Simulate for 10 periods 
T = 1 / f       # Period 
ti = 0.         # Initial time 
dt = T / 100    # Sampling period 
tf = 10T        # Simulation final time. 
sim = simulate!(model, ti, dt, tf)

# Plots results 
t, u = read(getnode(model, :writerin).component)
t, y = read(getnode(model, :writerout).component)
plt = plot(layout=(3,2))
plot!(t, u[:, 1], subplot=1, label="phase-a")
plot!(t, u[:, 2], subplot=3, label="phase-b")
plot!(t, u[:, 3], subplot=5, label="phase-c")
plot!(t, y[:, 1], subplot=2, label="y1")
plot!(t, y[:, 2], subplot=4, label="y2")
plot!(t, y[:, 3], subplot=6, label="y3")
display(plt)