Design for uncertainty and interaction
Use sensitivity, uncertainty sweeps, cascade loops, and simple decoupling. 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 18 in the Learning LabSensitivity and robustness tradeoffs
Distinguish tracking, disturbances, and measurement noise in frequency.
For loop L=P*C, sensitivity is S=1/(1+L), and complementary sensitivity is T=L/(1+L). They satisfy S+T=1 at each frequency. Output disturbances pass through S; reference passes through T; sensor noise contributes -T*n to the true output in unity feedback.
Large low-frequency loop gain makes S small, improving slow disturbance rejection. Small high-frequency loop gain makes T small, reducing measurement-noise transmission. The controller cannot make both S and T small at the same frequency.
Peaks in abs(S) indicate frequencies where disturbances or model uncertainty can be amplified. With stable multiplicative uncertainty bounded by W, the small-gain condition abs(W*T)<1 at every frequency is a sufficient robust-stability check under the standard interconnection assumptions. A finite grid is only a sampled check.
See it in action
import numpy as np
w=np.logspace(-2,2,200)
L=4/(1+1j*w)**2
S=1/(1+L); T=L/(1+L)
print('Identity error:',np.max(np.abs(S+T-1)))
print('Sampled peak sensitivity:',np.max(np.abs(S)))
Design low-frequency accuracy and high-frequency noise rejection together.
Cascade control and interacting loops
Recognise when loop interaction matters.
Cascade control uses an inner loop for a faster measured variable and an outer loop for a slower one. A position loop may command a speed reference, while the speed loop commands voltage. Tune and validate the inner loop before closing the outer loop.
The inner loop should respond sufficiently faster than the outer loop for the intended approximation. There is no universal ratio that replaces a coupled stability check. Saturation of the inner actuator must be visible to outer-loop anti-windup.
For a two-input, two-output static gain matrix G0, a static decoupler D=G0^-1 gives G0*D=I when G0 is invertible. It only cancels nominal steady interaction. Dynamic mismatch, uncertainty, and an ill-conditioned G0 can produce large commands.
See it in action
import numpy as np
G0=np.array([[2.,0.5],[0.4,1.]])
D=np.linalg.solve(G0,np.eye(2))
print('Decoupler:',D)
print('Nominal product:',G0@D)
print('Condition number:',np.linalg.cond(G0))
Test interacting loops together after designing their individual parts.
Practical: stress-test uncertain plants
Evaluate performance across a declared parameter set.
Use P=K/(tau*s+1) with fixed PI gains Kp=2,Ki=1. The closed-loop denominator is tau*s^2+(1+K*Kp)*s+K*Ki. Sweep K in [0.7,1,1.3] and tau in [0.5,1,2].
All these positive parameter cases are stable, but settling and overshoot can differ. Add response metrics and input limits to see which requirements survive. A grid provides evidence for tested cases, not a proof over every possible plant.
Choose the worst observed metric, not the average, when checking a requirement that must hold across the set. Keep nominal and worst-case results side by side so uncertainty has a visible engineering cost.
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.
- Sweep the nine parameter combinations and record poles.
- Simulate each closed-loop step response with numerator [2*K,K].
- Measure overshoot and settling; mark the worst case for each metric.
- Add a delay or actuator cap and explain how it changes your confidence.
What to hand in
- An uncertainty table.
- Overlaid responses and worst-case metrics.
- A clear boundary between tested evidence and proof.
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
from itertools import product
for gain,tau in product([0.7,1.,1.3],[0.5,1.,2.]):
poles=np.roots([tau,1+2*gain,gain])
print('K,tau:',gain,tau,'Poles:',poles)
State the uncertainty set and report the worst tested case.
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.