Analyse stability
Use pole locations and Routh tests to find stable gain ranges. This module has 3 lessons and takes about 2h 25m. Each lesson has a practice exercise that runs real Python in your browser and a short quiz.
Start module 06 in the Learning LabPoles and internal stability
Classify continuous linear systems using their poles.
A finite dimensional continuous LTI state model is asymptotically stable when every eigenvalue of A has a strictly negative real part. For a minimal transfer function, these are its poles. A positive real part means some free motion grows.
A pole on the imaginary axis is a boundary case. A simple undamped oscillator can keep moving forever without decaying, but it is not asymptotically stable. Repeated imaginary-axis poles can produce growth. Resonant bounded inputs can also produce unbounded output.
Calculate polynomial roots and inspect their real parts. Use a tolerance when classifying computed roots near zero. Do not call a marginal system stable simply because a short simulation looks bounded.
See it in action
import numpy as np
for den in [[1,3,2],[1,-1,2],[1,0,4]]:
poles = np.roots(den)
print(den, poles, 'Asymptotically stable:', bool(np.all(poles.real<0)))
Stability is a property of all modes, not one attractive plot.
Routh stability without solving roots
Use a cubic Routh table to derive a gain limit.
For a monic cubic s^3+a*s^2+b*s+c, the first column of the Routh table is 1, a, (a*b-c)/a, c when a is nonzero. Strict positivity gives a>0, c>0, and a*b>c, which also forces b>0.
For s^3+3*s^2+2*s+K, the range is 0<K<6. At K=6 the polynomial factors as (s+3)*(s^2+2), giving a pair of imaginary-axis poles. The boundary is not asymptotically stable.
The number of sign changes in a regular first column equals the number of right-half-plane roots. Zero pivots or a row of zeros need special Routh handling. This lesson uses the regular cubic case and checks boundaries with roots.
See it in action
import numpy as np
for gain in [1.,5.,6.,7.]:
column = [1.,3.,(6-gain)/3,gain]
print('K:',gain,'Routh column:',column,'poles:',np.roots([1,3,2,gain]))
Use strict inequalities and analyse boundary cases separately.
Practical: find the stability boundary
Combine analytical bounds, roots, and time responses.
Unity feedback around P(s)=1/[s*(s+1)*(s+2)] with C=K gives denominator s^3+3*s^2+2*s+K. The analytical stable interval is 0<K<6.
A gain sweep records the largest pole real part, sometimes called the spectral abscissa. A negative value means all poles are in the left half plane. Close to zero, decay can be very slow, so simulations need longer records.
A finite sweep only tests selected values. Use Routh to establish the interval and the sweep to illustrate it. Never infer that every untested gain is safe just because a few simulations passed.
Your experiment plan
Use the browser editor or the downloadable notebook. All plant data are simulated. Keep a notebook with parameters, predictions, results, and units.
- Derive the Routh range and mark it on your gain plot.
- Plot responses for K=1, 5, 6, and 7 over a long enough interval.
- Measure the largest real part and explain the response at each gain.
- Write a recommendation with margin from the instability boundary.
What to hand in
- A pole-real-part versus gain plot.
- Four labelled step responses.
- An analytical stability interval and a justified working gain.
Reflect on your results
Which assumption matters most? Describe one result that surprised you and one experiment that would test your explanation.
The automatic exercise checks the core code behaviour. Review observations and written deliverables yourself or with a mentor.
See it in action
import numpy as np
import matplotlib.pyplot as plt
gains = np.linspace(0.1,8,100)
rightmost = [max(np.roots([1,3,2,k]).real) for k in gains]
plt.plot(gains,rightmost); plt.axhline(0,color='black')
plt.xlabel('Controller gain K'); plt.ylabel('Largest pole real part (1/s)'); plt.show()
Use analysis to establish a bound and simulation to examine behaviour.
Free, open and run by a nonprofit.
This page is part of Control Engineering, a free course of 20 modules and 60 lessons in the engineering.fit( ) Learning Lab. The Learning Lab is built and run by engineering.fit( ), a nonprofit founded by Abdullateef Opeyemi Bakare that helps African engineering students gain research experience. You do not need an account or pay a fee to learn.