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

2 Likes

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.

2 Likes