Sample and discretise
Understand aliasing, sample-and-hold behaviour, and digital implementation. 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 11 in the Learning LabSampling, aliasing, and sensor filters
Choose a sample rate with bandwidth and aliasing in mind.
Sampling records a signal every Ts seconds, with sampling frequency fs=1/Ts. Sinusoids whose frequencies differ by integer multiples of fs can produce identical samples. Folding into the range 0 to fs/2 gives the apparent alias frequency.
For a signal band limited below B hertz, ideal reconstruction needs fs>2*B. Real control systems need additional margin for delay, filters, and unmodelled high frequencies. Sampling at twice the expected control bandwidth is usually not an adequate design rule.
An analogue anti-alias filter acts before the converter. A digital filter cannot recover information already folded into the wrong frequency. Also distinguish the sensor sampling rate from the controller update rate and the numerical simulation step.
See it in action
fs, signal_hz = 100., 70.
alias_hz = abs((signal_hz+fs/2)%fs-fs/2)
print('Sample period:',1/fs,'s')
print('Apparent frequency:',alias_hz,'Hz')
Choose sampling from the whole sensing and control chain.
Zero-order hold models
Derive an exact discrete update for a held first order input.
A digital actuator commonly holds u[k] constant until the next update. For dy/dt=-y/tau+K*u/tau, exact integration over Ts gives y[k+1]=a*y[k]+b*u[k], where a=exp(-Ts/tau) and b=K*(1-a).
This is a zero-order hold (ZOH) model. It is exact at sample times for this linear plant and a piecewise constant input. It is different from Euler, which uses a=1-Ts/tau and b=K*Ts/tau.
SciPy cont2discrete can compute ZOH state-space models. Even an exact plant discretisation does not remove controller computation delay, sampling jitter, or actuator limits. Model those separately when needed.
See it in action
import math
tau, gain, ts = 2., 3., 0.2
a = math.exp(-ts/tau)
b = gain*(1-a)
y = 0.
for _ in range(10):
y = a*y+b*1.
print('At 2 s:',y,'Exact:',gain*(1-math.exp(-2/tau)))
An exact sampled plant model still needs a realistic controller timing model.
Practical: choose a controller sample period
Compare the same digital PI law across sample periods.
Use the exact plant update y_next=a*y+(1-a)*u for tau=1. At each sample, compute e=1-y, apply u=2*e+I, update y, then update I by Ts*e. This is an explicit forward-Euler integral controller.
The homogeneous closed-loop matrix for states [y,I] is [[a-2*b,b],[-Ts,1]], where b=1-a. Its eigenvalues must be inside the unit circle. The continuous PI design does not automatically remain stable for a large sample period.
Compare Ts=0.05, 0.5, and 3.5 seconds. Keep the physical model and gains unchanged. Large steps here change the actual digital controller, not just the numerical integration accuracy.
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.
- Plot poles against the unit circle for all three sample periods.
- Simulate the reference response for 30 seconds at each period.
- Compare settling and oscillation in physical seconds.
- Select a period and explain the remaining timing margin.
What to hand in
- A discrete pole plot.
- Three sampled response traces.
- A sample-period recommendation backed by stability evidence.
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
for ts in [0.05,0.5,3.5]:
a = np.exp(-ts); b = 1-a
closed = np.array([[a-2*b,b],[-ts,1.]])
print('Ts:',ts,'Poles:',np.linalg.eigvals(closed))
Check the implemented discrete loop, not just its continuous design.
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.