control//digital control//zero-order hold

A zero-order hold is the element that turns a digital controller's sequence of numbers into a continuous signal by keeping each value constant until the next one arrives, which is what a DAC, a PWM generator or a motor driver's register does, and it matters for two reasons: it makes the discrete model of the plant exact at the sampling instants, and it delays the command by half a sample period on average.


A zero-order hold is the element that turns a digital controller's sequence of numbers into a continuous signal by keeping each value constant until the next one arrives, which is what a DAC, a PWM generator or a motor driver's register does, and it matters for two reasons: it makes the discrete model of the plant exact at the sampling instants, and it delays the command by half a sample period on average.

The delay is visible in the shape. The held command is a staircase whose steps start at the right values, but the staircase as a whole sits half a step behind the smooth signal it stands for. To a sine of angular frequency ω\omegaω it looks like a pure delay of T/2T/2T/2, a phase lag of ωT/2\omega T/2ωT/2 radians: 0.5 ms for a loop at 1 kHz, 50 ms for one at 10 Hz. That half period is the entry for sampling in every timing budget of a loop (loop delay), and it is why the sampling rate is chosen as a multiple of the bandwidth.

The same staircase is what makes discretization exact. If the input really is constant between samples, the continuous plant x˙=Ax+Bu\dot x=Ax+Bux˙=Ax+Bu is reproduced at the sampling instants, with no approximation, by

xk+1=Adxk+Bduk,Ad=eAT,Bd=∫0TeAτ dτ  B.x_{k+1}=A_dx_k+B_du_k,\qquad A_d=e^{AT},\qquad B_d=\int_0^T e^{A\tau}\,d\tau\;B.xk+1​=Ad​xk​+Bd​uk​,Ad​=eAT,Bd​=∫0T​eAτdτB.

The matrix exponential does the work, and libraries compute both matrices (scipy.signal.cont2discrete with the zoh method, c2d in MATLAB). A Kalman filter or an MPC designed on this model is consistent with what the actuator actually receives (discretization).

The hold comes with the hardware interface, and its delay is there whether the designer counts it or not; the only lever on it is the rate.

Computation can add a whole period on top. If the command computed from sample kkk is written out only at tick k+1k+1k+1, the loop runs one period behind; reading, computing and writing within the same interrupt keeps the delay at the hold's half period plus the computation time.

The transfer function of the hold, (1−e−sT)/s(1-e^{-sT})/s(1−e−sT)/s, is what frequency-domain design adds to the plant to account for it. Holds of higher order (a ramp between samples) exist and are rare in control: a ramp towards the next value needs that value before it is known, and a ramp extrapolated from past values adds an error of its own.