Causal.jl vs ModelingToolkit.jl for causal, discrete-time, and Simulink-like systems

That sounds a lot like ModelingToolkit?

using ModelingToolkit, OrdinaryDiffEq, Plots
using ModelingToolkitStandardLibrary.Electrical
using ModelingToolkitStandardLibrary.Blocks: Constant

R = 1.0
C = 1.0
V = 1.0
@variables t
@named resistor = Resistor(R=R)
@named capacitor = Capacitor(C=C)
@named source = Voltage()
@named constant = Constant(k=V)
@named ground = Ground()

rc_eqs = [
        connect(constant.output, source.V)
        connect(source.p, resistor.p)
        connect(resistor.n, capacitor.p)
        connect(capacitor.n, source.n, ground.g)
        ]

@named rc_model = ODESystem(rc_eqs, t, systems=[resistor, capacitor, constant, source, ground])
sys = structural_simplify(rc_model)
prob = ODAEProblem(sys, Pair[], (0, 10.0))
sol = solve(prob, Tsit5())
plot(sol, vars = [capacitor.v, resistor.i],
     title = "RC Circuit Demonstration",
     labels = ["Capacitor Voltage" "Resistor Current"])
savefig("plot.png")

image

That’s the first tutorial at:

6 Likes

Agreed, though there have already been some nice wins. If you haven’t seen the Instron talk at JuliaCon, check it out.

It shows some MTK wins, but also some things we’re working on and next directions.

Causal is just a subset of acausal modeling. Causal modeling is acausal modeling where all of the components only have input and output ports, no free ports. If you made ModelingToolkit throw an error on any open component that wasn’t labelled input, output, or internal, then it would be a causal modeling system. Indeed having inputs and outputs labelled makes it easier to throw nice error messages (“Input not connected”, “Two inputs connected”, etc.), but all of those nice debugging messages can (and are) thrown from acausal modeling systems as well (indeed, the purpose for input/output designations in acausal modeling systems is simply for GUIs and error messages, they serve no other purpose).

It’s hard to find systems which are truly “easier” to think causally. Take for example your electronic systems example. What direction is the flow? In general, the flow goes in the direction of the lower voltage. That can be dependent on parameters and even can change in time. The direction of flow is not clear cut, which is why circuit systems usually want a way to just “connect” components. This is acausal, and then SPICE system use something called modal node analysis (MNA) to find a causal arrow. But a generalized form of MNA is Pantelides algorithm for index reduction because connecting electrical circuits generates Index-2 DAEs, and then finding a causal flow is a subset of what structural_simplify does with index reduction and tearing.

Note that Julia Computing is using this as a way to build a differentiable SPICE called Cedar.

It is of course built on ModelingToolkit and uses its algorithms to transform circuit components into ODEs to simulate.

2 Likes

All control systems are inherently causal, the same goes for signal-processing systems. For many engineers, such systems are what you are mostly modeling, and then the causal approach may very well feel more intuitive.

11 Likes

Nice! I hadn’t spotted that one, thanks for pointing it out.

I’ve been keeping my eye out for this as there are some projects I’m involved with that it could be useful for around the design/optimisation of power converters. I’m guessing that it is commercial only - are there any aspects that might be made open to researchers?

Nice! It would be amazing having something like that in Julia!

I tend to disagree. From a modelling perspective, acausal modelling may be the way to go since it is a strict generalization of causal systems, in addition to solving it faster due to the transformations that reduce the index of the DAE.

However, engineering systems (continuous and discrete control systems, communication systems, signal processing, etc…) are inherently causal as we often build more complex systems by joining isolated-but-simple blocks, which can nicely be represented as block diagrams that relates inputs and output, as it is done in Simulink. Since “causal modelling is also known as explicit modelling, block-oriented modelling”, it is the natural way of modelling more complex systems in engineering. A challenging engineering problem is far cry from an RC model and looks like something like this


I could implement such a system in Simulink. But in Julia, I do not even know if it is possible.

To sum things up, causal vs. acausal modeling is a pointless discussion for the end user. It does not matter how the algorithm solves it under the hood as long as (s)he can understand how is the input-output relationship of each block diagram. Furthermore, a GUI such as pysimCoder would be even better.

1 Like

Why not write exactly the same thing using the blocks library?

https://mtkstdlib.sciml.ai/stable/API/blocks/

This is just connecting basic blocks and other blocks with only inputs and outputs? I agree that it can have an extra level of complexity to know that acausal exists in the system, but using the causal subset with causal blocks gives a causal model.

2 Likes

I’ll take a look, thanks for the reference.

@ChrisRackauckas Not really, a system like that works with different sampling rate, is it possible to define different sampling rate?

You use the discrete update operator.

And with multiple clocks:

3 Likes

What would be a (mature enough) platform for desktop GUI development in Julia? In particular, do you think that the QML.jl package for Qt5 development (that you discuss elsewhere here at Discourse) is usable for making something like Julia version of pysimCoder? I am myself not in GUI development, just asking if the time is ripe for encouraging students for such adventures.

1 Like

Well, QML.jl could definitly be used, and I like it, mainly because I have years of QT development experiance. But on the other hand there are not enough maintainers for this package, and it usually takes some time before it works with new Julia versions. In the moment it only works with Julia 1.7, but not with 1.8rc4.

1 Like

Sounds like you’re a good candidate for a new maintainer :blush:

Jokes aside, people with both experience and motivation often make good maintainers of open-source software.

2 Likes

Well, this year I will still be busy with improving the quality of my own packages, in particular KiteControllers.jl If you look at this package you can see that I did a lot of control design with Simulink and later ported it to Julia…

4 Likes

There has been some improvements lately to MTK and MTKstdlib that makes life easier for control engineers, see, e.g., this tutorial building and analyzing the closed-loop properties of a speed-controlled DC motor using MTK stdlib. This should hopefully show that, given a block diagram, building the corresponding control system in MTK using standard-library components like PID controllers etc. is rather straightforward.

See also this tutorial that is building and auto tuning a cascade PI + P servo-control system and this tutorial with some general illustrations on how to use MTK for control-purposes.

10 Likes

https://mtkstdlib.sciml.ai/stable/API/blocks/

Updated link for future readers: Basic Blocks ¡ ModelingToolkitStandardLibrary.jl

4 Likes

Here is a relevant and recent youtube video from @ChrisRackauckas:
https://youtu.be/ZYkojUozeC4