Designing a band pass filter with modeling toolkit

What is the best way to design a band pass filter in the continues domain using modelling toolkit?
Some hints how to do it in Python: Butterworth Bandpass — SciPy Cookbook documentation

Update: OK, I can design a filter with DSP.jl: Filters - filter design and filtering · DSP.jl

But how would I convert such a filter for use with modeling toolkit?

You can @symbolic_register the calls

But a simple second degree band pass filter is just a few differential equations… Why not keep it as symbolic linear equations in modelingtoolkit?

You can design the filter using DSP.jl, convert it to a transfer function from ControlSystemsBase, convert that to a statespace system and then use ControlSystemsMTK to convert that to an ODE system. Make sure to perform balancing on the statespace system using balance_statespace before converting it to an ODESystem.

Here’s an unfinished PR that adds an interface between DSP and ControlSystems


It would probably be worth adding to the standard library if someone’s up for it.

1 Like

Before doing analog filter design with DSP, beware of analogfilter design seems to be broken · Issue #341 · JuliaDSP/DSP.jl · GitHub
TLDR; analog filter design is quite broken in DSP but the problem can be worked around.

Having said that, here’s how you can convert a filter to an MTK system with the PR #843

using DSP, ControlSystemsBase

# Digital filter
fs = 100
df = digitalfilter(Bandpass(5, 10; fs), Butterworth(2))
G = tf(df, 1/fs)
bodeplot(G, xscale=:identity, yscale=:identity, hz=true)

# Analog filter
af = analogfilter(Bandpass(0.05, 0.30), Butterworth(2))
G = tf(af)
bodeplot(G, xscale=:identity, yscale=:identity, hz=true)

# Convert to statespace for simulation with MTK
sys = ss(G) # This performs numerical scaling automatically

using ControlSystemsMTK
odesys = ODESystem(sys; name=:filter)

The resulting odesys will have connectors input::RealInput and output::RealOutput from ModelingToolkitStandardLibrary.