Frequency-Domain Stability · Lesson
English translation
Execution setup
The Python option uses python-control. If the module is missing, run %pip install control==0.10.2 in a Colab or Jupyter code cell.
Topics covered
Before simulating all time responses, try assessing stability from the frequency response and open-loop poles.
Overall workflow
Open-loop poles → Nyquist plot → stability margins → check closed-loop poles
Nyquist and open-loop poles
Counting only encirclements of −1 can lead to an incorrect stability assessment. Use both the number of open-loop right-half-plane poles and the sign of the encirclement direction, and check against directly calculated closed-loop poles.
Conditions for interpreting stability margins
The gain crossover frequency is where the open-loop response magnitude is 1. The difference between the phase at this frequency and −180° is the phase margin.
At a frequency where phase is −180°, the reciprocal of the response magnitude is the gain margin. Mark crossover points on the Bode plot to show where both margins are calculated.
Checking frequency response and closed-loop poles
Examine the Nyquist plot and closed-loop poles of L(s)=5/((s+1)(s+2)(s+3)). This example has no open-loop right-half-plane poles.
import numpy as np
import matplotlib.pyplot as plt
import control as ctl
s=ctl.tf('s')
L=5/((s+1)*(s+2)*(s+3));omega=np.logspace(-3,3,1000)
z=np.array([ctl.evalfr(L,1j*w) for w in omega])
plt.plot(z.real,z.imag,label='positive frequency');plt.plot(z.real,-z.imag,linestyle='--',label='negative frequency');plt.scatter([-1],[0],marker='x',label='-1');plt.xlabel('Real');plt.ylabel('Imaginary');plt.axis('equal');plt.grid();plt.legend()
print('Closed-loop poles:',ctl.poles(ctl.feedback(L,1)))
Closed-loop poles: [-3.90416086+0.j -1.04791957+1.31124804j -1.04791957-1.31124804j]
Reference example
View more examples