ControlSystems.jl icon indicating copy to clipboard operation
ControlSystems.jl copied to clipboard

bode() returns only phases in interval +/- 180°

Open stephans3 opened this issue 4 years ago • 6 comments

If I want to determine the phase at some frequency using bode(G, w) with w as a 1-element vector, bode() only returns values in the interval (-180°, 180°).

This is a problem in case of higher-order systems or delay systems with phases below -180°.

This problem does not occur for vectors w with n>1 elements.

So is it a bug or a feature? :D

G = tf(1, [1, 3, 3, 1]) bode(G, [1.7]) # ϕ = -178° bode(G, [1.78]) # ϕ = 177° is wrong, should be ϕ=-360° + 177° = -183°

stephans3 avatar Jan 15 '21 10:01 stephans3

This was discussed in #312, and I think the feeling is that it would be good to fix it, but #312 requires some more further work for MIMO and delay systems. The current behavior is at least consistent.

olof3 avatar Jan 15 '21 11:01 olof3

Have you seen the function unwrap? I think you just need to unwrap the entire phase curve

bodeplot(G)

will plot the phase correctly

baggepinnen avatar Jan 15 '21 12:01 baggepinnen

Right, I was mixing things up. However, unwrap will not by default give you what you want if there are more than one or two integrators.

olof3 avatar Jan 15 '21 12:01 olof3

Nope, the problem is still there if the phase starts at below -180 degrees (maybe already below -90?).

baggepinnen avatar Jan 15 '21 12:01 baggepinnen

Yes, the general problem is that it is tricky to compute where the bode plot should start. Thus bode assumes that the first frequency in the vector is "small enough", and "assumes" that the frequency there is in (-180,180). It will then unwrap from that frequency. That is why you see the problem when you only input one frequency.

Edit: I don't think it is feasible to compute the "correct" phase for arbitrary frequencies without

  1. starting at a low frequency
  2. computing based on the zeros and poles what multiple on 360 should be added
  3. Unwrapping from that frequency, with a fine enough grid, until the frequency you are interested in.

We do not do step 2 in this toolbox (see #312), and step 3 based on the vector you input.

mfalt avatar Jan 15 '21 12:01 mfalt

Unwrap also fails if the change in frequency between two grid points is too large

w = exp10.(LinRange(-2, 5, 200))
P = tf(1,[1,1])*delay(1)
bodeplot(P, w)

image

baggepinnen avatar Jul 03 '22 11:07 baggepinnen