-
Notifications
You must be signed in to change notification settings - Fork 89
Numerical stability issue with ss->zpk conversion? #475
Description
ControlSystems.jl v0.9.2
SS-system/odd result:
I have the following system:
A=[
0.0 0.0 0.0;
1.0 0.0 -0.00578297;
0.0 1.0 0.0;
]
B=[1.0; 0.0; 0.0]
C=[0.0 0.0 1.0]
D=[0]
ss_sys=ss(A,B,C,D)If I call zpk(), I get strange results:
julia> zpk(ss_sys)
TransferFunction{Continuous, ControlSystems.SisoZpk{Float64, ComplexF64}}
1.0
0.0---
1.0Why is this odd?/correcting for numerical noise
If I look at the poly-rational view of the system, I get:
tf(ss_sys)
TransferFunction{Continuous, ControlSystems.SisoRational{Float64}}
7.771561172376096e-16s^2 - 1.2776238400569184e-15s + 1.0000000000000007
-----------------------------------------------------------------------
1.0s^3 + 0.005782969999999999sWhich indicates the numerator is actually a constant of 1 with numerical noise "generating" false terms for s^2 & s^1.
Manual cleanup of numerical noise
If I create a cleaned-up version of this poly-rational view, I can generate a zpk view that generates useful output in my simulation:
tf_sys = tf([1], [1, 0, 0.0057829713287632966, 0])
zpk(tf_sys)
TransferFunction{Continuous, ControlSystems.SisoZpk{Float64, ComplexF64}}
1.0
1.0---------------------------------------------
(1.0s^2 + 0.0057829713287632966)(1.0s + -0.0)Further analysis
This time, if I manually "dirty-up" the poly-rational function, I can see where things go foul:
tf_debug = tf([1e-15, -1e-15, 1], [1, 0, 0.0057829713287632966, 0])
zpk(tf_debug)
TransferFunction{Continuous, ControlSystems.SisoZpk{Float64, ComplexF64}}
1.0s^2 - 1.0s + 9.999999999999999e14
1.0e-15---------------------------------------------
(1.0s^2 + 0.0057829713287632966)(1.0s + -0.0)As you can see, the poly-rational form wants to normalize the gain factor to ensure the most significant term of the polynomial (s^2 in this case) has a coefficient of 1.
In other words, numerical error is pushing the transfer function to a value of H(s)=0!!!