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
JuliaControl:dev ← JuliaControl:dsp
opened 06:45AM - 13 May 21 UTC
It would probably be worth adding to the standard library if someone’s up for it.
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.