Controlsystem.jl : how to mix continuous and discrete time transfer functions


I am using Julia 0.5.2

I am modeling a continuous time RLC circuit in the s domain. I am modeling a digital controller in the z domain.

I tried multiplying the 2 transfer functions together to get the open loop transfer function, but I get this message:

Sampling time mismatch

in *(::ControlSystems.TransferFunction{ControlSystems.SisoRational}, ::ControlSystems.TransferFunction{ControlSystems.SisoRational}) at /home/venkat/.julia/v0.5/ControlSystems/src/types/transferfunction.jl:437
_ in *(::ControlSystems.TransferFunction{ControlSystems.SisoRational}, ::ControlSystems.TransferFunction{ControlSystems.SisoRational}, ::ControlSystems.TransferFunction{ControlSystems.SisoRational}) at ./operators.jl:138_
_ in include_string(::String, ::String) at ./loading.jl:441_

How do we work in both the domains? Do I have to convert my z domain transfer functions to s domain, by bilinear transform?

any advice is appreciated.

PS: I guess I can use the c2d function to convert the continuous to discrete. But, I feel that we always lose something in conversion. Ideally, continuous and discrete transfer functions should coexist.


I can’t seem to use c2d. It does not seem reliable. For example, here is a simple modeling of an inductor:

using ControlSystems

w = logspace(1.0, 7.5, 1000)

samp_freq = big"24.0e6" # 24 MHz.
dig_t_step = 1.0/samp_freq

s = tf("s")

L = big"150.0e-9"
dcr = big"2.0e-3" # actual dcr is 0.2 mohm. I am adding the scaled top/bottom fet resistances.

l_imp = dcr + L*s
bodeplot(l_imp, w, title="inductor bode")

the bode plot looks right.
Now, I make it discrete time:

dig_l = c2d(l_imp, dig_t_step)
bodeplot(dig_l, w, title="digital inductor bode")

the bodeplot is totally different!
Am I doing something wrong?

Best regards.


Sampling of a continuous time system does distort the frequency response, in particular near the nyquist frequency. Is this what you are observing? (I can’t generate a plot right now). See, e.g., IFAC professional brief chapter 6 for more details.


The short answer is that ControlSystems.jl does not support mixed continuous and discrete time systems. This would require some sort of blocks for converting the signals, i.e. ADC and DAC, which is not implemented, and some more advanced way of simulating. It should be possible to go to/from discrete time, but this has it’s downsides as you mention.

The reason why your example fails seems to be that the system is not proper (i.e. it has a derivative term). The discretization is implemented as converting the system to state-space and doing the discretization there, and then converting back. However, since a state-space model can not represent direct derivatives, this fails, unfortunately silently. This is a bug, and we will either “fix” this by throwing an error, or try to implement some other way of discretizing systems.
A work around would be to make the system proper by adding a pole at a high enough frequency, for example

l_imp2 = (dcr + L*s)/(s/samp_freq+1)
l_impd = c2d(l_imp2, dig_t_step)

which should work more or less as expected.

EDIT: : If the solution above is not exact enough, it seems better to define the system in discrete time directly, with a one step dicrete time derivative, see for example, i.e.

l_impd = dcr + L*(z-1)/(dig_t_step*z)

EDIT2: Typo in code


Thanks for all who replied. Appreciate your time and interest.