Chapter 12: Advanced PID Design and Implementation
Lesson 4: Filtered Derivative Action and Noise Sensitivity
This lesson studies the mathematical structure of derivative action in PID controllers, explains why ideal differentiation is extremely sensitive to measurement noise, and derives the standard filtered derivative form used in practical PID implementations. We analyze its effect on noise-to-control and noise-to-output transfer functions and provide multi-language implementations suitable for robotic control software.
1. Conceptual Overview of Derivative Action
In previous lessons on PID control, the controller output \( u(t) \) for a parallel PID was written as
\[ u(t) = K_p e(t) + K_i \int_0^t e(\xi)\,\mathrm{d}\xi + K_d \frac{\mathrm{d}}{\mathrm{d}t} e(t), \]
where \( e(t) = r(t) - y(t) \) is the tracking error, \( K_p \) is the proportional gain, \( K_i \) the integral gain, and \( K_d \) the derivative gain.
The derivative term \( u_D(t) = K_d \frac{\mathrm{d}}{\mathrm{d}t} e(t) \) predicts the future trend of the error and can reduce overshoot and improve damping. In the Laplace domain (using earlier Laplace-transform tools), the derivative part corresponds to the transfer function
\[ C_D(s) = K_d s. \]
However, real measurements are never perfectly smooth: sensor noise, quantization, and unmodeled high-frequency effects introduce rapid variations in the feedback signal. Since differentiation amplifies high-frequency components, a pure \( K_d s \) term can generate very large and fast control signals, leading to actuator wear, saturation, or even instability.
To visualize the signal paths, consider the simplified controller structure where only the derivative path is shown explicitly:
flowchart TD
R["reference r(t)"] --> SUM["+ error"]
Y["output y(t) with noise"] --> SUM
N["measurement noise n(t)"] --> Y
SUM --> E["error e(t)"]
E --> D["derivative block Kd * d/dt with filter"]
D --> U["control signal u(t)"]
The core idea of this lesson is: instead of using the ideal derivative \( K_d s \), we use a filtered derivative block that behaves like a derivative at low and medium frequencies but remains bounded at high frequencies where noise dominates.
2. Ideal Derivative Action and Noise Amplification
Consider unity feedback with plant transfer function \( G(s) \) and controller transfer function \( C(s) \). Let measurement noise \( n(t) \) be added to the plant output before the feedback summing junction. In the Laplace domain, using \( R(s) \), \( Y(s) \), \( U(s) \), and \( N(s) \) for the transforms, we have
\[ e(t) = r(t) - y(t) - n(t) \quad \Longrightarrow \quad E(s) = R(s) - Y(s) - N(s), \]
\[ U(s) = C(s) E(s), \qquad Y(s) = G(s) U(s). \]
Eliminating \( E(s) \) and \( U(s) \), we obtain
\[ Y(s) = \frac{G(s)C(s)}{1 + G(s)C(s)} R(s) - \frac{G(s)C(s)}{1 + G(s)C(s)} N(s), \]
\[ U(s) = \frac{C(s)}{1 + G(s)C(s)} R(s) - \frac{C(s)}{1 + G(s)C(s)} N(s). \]
Therefore, the transfer functions from noise \( N(s) \) are
\[ T_{y n}(s) = \frac{Y(s)}{N(s)} = - \frac{G(s)C(s)}{1 + G(s)C(s)}, \qquad T_{u n}(s) = \frac{U(s)}{N(s)} = - \frac{C(s)}{1 + G(s)C(s)}. \]
For typical strictly proper plants, we have \( \lim_{|s|\to\infty} G(s) = 0 \), so for large \( |s| \) we obtain the approximations
\[ T_{y n}(s) \approx - G(s)C(s), \qquad T_{u n}(s) \approx - C(s). \]
If the derivative part of \( C(s) \) is ideal, \( C_D(s) = K_d s \), then for large \( |s| \)
\[ |T_{u n}(s)| \approx |K_d s| \quad \text{grows without bound as } |s|\to\infty. \]
Thus, even if the plant output \( Y(s) \) is strongly attenuated at high frequency (small \( G(s) \)), the actuator signal \( U(s) \) can become arbitrarily large when measurement noise has high-frequency components. This is the mathematical explanation for the intuitive statement “derivative action amplifies noise”.
3. First-Order Filtered Derivative Structure
A standard remedy is to replace the ideal derivative \( K_d s \) by a first-order filtered derivative, also called a “real differentiator”:
\[ C_D(s) = K_d \frac{N s}{1 + N s}, \]
where \( N > 0 \) (with units of time constant\(^{-1}\)) is a tuning parameter. The complete PID controller in parallel form becomes
\[ C_{\text{PID}}(s) = K_p + \frac{K_i}{s} + K_d \frac{N s}{1 + N s}. \]
Two important limiting properties of \( C_D(s) \) are:
-
Low-frequency behavior. For small
\( |s| \), \( N s \ll 1 \), so
\[ C_D(s) = K_d \frac{N s}{1 + N s} \approx K_d N s (1 - N s + \dots) \approx K_d N s. \]
Thus, at sufficiently low frequencies the slope is that of an ideal derivative scaled by \( N \). -
High-frequency behavior. For large
\( |s| \), \( N s \gg 1 \), so
\[ C_D(s) = K_d \frac{N s}{1 + N s} \approx K_d \frac{N s}{N s} = K_d. \]
At high frequency, the gain approaches the finite constant \( K_d \), instead of growing without bound.
In other words, the derivative action behaves like a derivative around the frequencies of interest but smoothly transitions to a bounded gain for very fast variations. This preserves the beneficial “predictive” effect on the error while limiting the amplification of high-frequency measurement noise.
4. Noise-to-Control and Noise-to-Output with Filtered Derivative
Substitute the filtered derivative form into the noise transfer functions derived earlier. For simplicity, consider that the derivative term dominates the controller at high frequencies, so we approximate
\[ C(s) \approx C_D(s) = K_d \frac{N s}{1 + N s}. \]
For strictly proper \( G(s) \) and large \( |s| \), we still have \( T_{y n}(s) \approx -G(s) C(s) \) and \( T_{u n}(s) \approx -C(s) \). Hence
\[ T_{u n}(s) \approx - K_d \frac{N s}{1 + N s}. \]
Therefore, the magnitude of the noise-to-control transfer is asymptotically bounded:
\[ \lim_{|s|\to\infty} |T_{u n}(s)| = \lim_{|s|\to\infty} \left| K_d \frac{N s}{1 + N s} \right| = |K_d|. \]
By contrast, with an ideal derivative \( C_D(s) = K_d s \) we would obtain
\[ \lim_{|s|\to\infty} |T_{u n}(s)| = \lim_{|s|\to\infty} |K_d s| = \infty. \]
Thus, derivative filtering replaces an unbounded noise amplification by a finite bound determined by \( K_d \). In many physical plants, \( T_{y n}(s) \) already decays rapidly at high frequency because \( G(s) \) becomes very small. The main benefit of derivative filtering is therefore to protect the actuator signal \( u(t) \) and the actuators themselves.
In later chapters on frequency response, this boundedness will be interpreted as a finite high-frequency gain of the controller.
5. Selecting the Filter Parameter \( N \) (Trade-Offs)
The parameter \( N \) plays a double role:
- It roughly defines the frequency range where the controller behaves like a derivative.
- Together with \( K_d \), it sets the maximum high-frequency gain of the derivative path.
Qualitatively:
- Large \( N \). The transition from derivative-like behavior to bounded behavior occurs at higher frequencies. The derivative effect is “stronger” over a wider range, improving transient response but also amplifying measurement noise over a wider band.
- Small \( N \). The derivative path behaves more like a low-pass filter, significantly limiting noise amplification but also reducing the derivative effect on the dominant closed-loop dynamics.
A simple design workflow is:
flowchart TD
A["Start from PID gains tuned ignoring noise"] --> B["Inspect sensor noise level in measurements"]
B --> C["Choose initial N (e.g. 5..20 times dominant pole frequency)"]
C --> D["Simulate/experiment: observe u(t) and actuator limits"]
D --> E{"noise problem?"}
E -->|yes| F["Decrease N or Kd until u(t) is acceptable"]
E -->|no| G["Optionally increase N slightly for faster response"]
F --> D
G --> H["Finalize PID with filtered derivative"]
The numerical choice of \( N \) is often empirical and depends on sensor quality and actuator limits. The analytical bounds from the previous section guarantee that the high-frequency gain of the derivative path is finite, but they do not specify a unique optimal value of \( N \).
6. Python Implementation with
python-control (Robotics-Oriented)
In Python, the python-control library allows concise
modeling of PID controllers with filtered derivative action. Consider a
simple actuated joint modeled as a second-order plant. We simulate the
response with and without noise and inspect the control signal.
import numpy as np
import control as ctrl
import matplotlib.pyplot as plt
# Simple second-order joint model: G(s) = 1 / (J s^2 + B s + K)
J = 0.01
B = 0.1
K = 0.0
numG = [1.0]
denG = [J, B, K + 1.0] # add unity feedback stiffness term
G = ctrl.TransferFunction(numG, denG)
# PID gains
Kp = 50.0
Ki = 0.0
Kd = 2.0
N = 20.0 # derivative filter parameter
# PID controller with filtered derivative: C(s) = Kp + Ki/s + Kd * (N s)/(1 + N s)
C = ctrl.pid(Kp, Ki, Kd, N)
# Closed-loop from reference to output (unity feedback)
T = ctrl.feedback(C*G, 1)
t = np.linspace(0.0, 2.0, 2000)
t, y = ctrl.step_response(T, T=t)
# Approximate actuator signal u(t) via simulation with measurement noise
dt = t[1] - t[0]
r = np.ones_like(t) # unit step reference
noise_std = 0.01 # measurement noise standard deviation
rng = np.random.default_rng(0)
xG = np.zeros(len(denG) - 1)
u_hist = []
y_hist = []
e_prev = 0.0
d_filt = 0.0
alpha = np.exp(-dt * N) # discrete low-pass coefficient for derivative filter
for k in range(len(t)):
y_meas = xG[-1] + noise_std * rng.normal()
e = r[k] - y_meas
# discrete-time filtered derivative of error
d_raw = (e - e_prev) / dt
d_filt = alpha * d_filt + (1.0 - alpha) * d_raw
u = Kp * e + Kd * d_filt # (Ki = 0 in this example)
u_hist.append(u)
y_hist.append(y_meas)
# simple plant integration: forward Euler on state-space form
# J q_dd + B q_d + K q = u
# state x = [q, q_d]
q = xG[0]
qd = xG[1]
qdd = (u - B * qd - K * q) / J
qd_new = qd + dt * qdd
q_new = q + dt * qd
xG = np.array([q_new, qd_new])
e_prev = e
u_hist = np.array(u_hist)
plt.figure()
plt.subplot(2, 1, 1)
plt.plot(t, y_hist, label="measured position")
plt.plot(t, r, linestyle="--", label="reference")
plt.ylabel("position")
plt.legend()
plt.subplot(2, 1, 2)
plt.plot(t, u_hist)
plt.xlabel("time [s]")
plt.ylabel("control torque u(t)")
plt.tight_layout()
plt.show()
In robotics frameworks such as ROS, similar logic is often embedded in controller nodes written in Python or C++, with the derivative term smoothed by a first-order filter to reduce amplification of encoder noise.
7. C++ Implementation (ROS-Style Filtered Derivative)
In C++ robotic software (e.g., ROS controllers), the derivative term is usually implemented by smoothing the discrete derivative of the error with a low-pass filter. Below is a minimal C++ class realizing the continuous idea \( K_d \frac{N s}{1 + N s} \) as a discrete filter:
#include <cmath>
class FilteredDerivative
{
public:
FilteredDerivative(double Kd, double N, double dt)
: Kd_(Kd), N_(N), dt_(dt), d_filt_(0.0), e_prev_(0.0)
{
alpha_ = std::exp(-N_ * dt_);
}
double update(double e)
{
// raw discrete derivative of error
double d_raw = (e - e_prev_) / dt_;
// low-pass filter with pole around 1/N
d_filt_ = alpha_ * d_filt_ + (1.0 - alpha_) * d_raw;
e_prev_ = e;
return Kd_ * d_filt_;
}
private:
double Kd_, N_, dt_;
double alpha_;
double d_filt_;
double e_prev_;
};
// Example usage in a joint controller loop:
//
// FilteredDerivative d_term(2.0, 20.0, dt);
// double u = Kp * e + d_term.update(e);
Libraries such as ros_control or
control_toolbox in ROS adopt similar constructions
internally: a discrete derivative followed by a first-order low-pass
filter whose time constant is tuned according to the chosen
\( N \).
8. Java Implementation (Custom PID with Filtered Derivative)
In Java-based robotics frameworks (for example, educational robot platforms or FIRST-style control code), a PID loop can be written with a similar filtered derivative structure:
public class FilteredDerivativePID {
private double Kp;
private double Ki;
private double Kd;
private double N;
private double dt;
private double integral;
private double ePrev;
private double dFilt;
private double alpha;
public FilteredDerivativePID(double Kp, double Ki, double Kd,
double N, double dt) {
this.Kp = Kp;
this.Ki = Ki;
this.Kd = Kd;
this.N = N;
this.dt = dt;
this.integral = 0.0;
this.ePrev = 0.0;
this.dFilt = 0.0;
this.alpha = Math.exp(-N * dt);
}
public double update(double reference, double measurement) {
double e = reference - measurement;
// integral term
integral += e * dt;
// filtered derivative term
double dRaw = (e - ePrev) / dt;
dFilt = alpha * dFilt + (1.0 - alpha) * dRaw;
ePrev = e;
return Kp * e + Ki * integral + Kd * dFilt;
}
}
Many Java robotics libraries (for instance, those used in differential-drive or arm control) expose PID controllers where the derivative term is internally filtered in a similar way to avoid amplifying encoder quantization noise.
9. MATLAB/Simulink Implementation with pid(Kp,Ki,Kd,N)
MATLAB's Control System Toolbox provides a direct representation of a
PID with filtered derivative using the function pid:
% Plant: simple second-order joint model
J = 0.01; B = 0.1; K = 0;
G = tf(1, [J B K+1]); % G(s) = 1 / (J s^2 + B s + 1)
Kp = 50; Ki = 0; Kd = 2; N = 20; % filtered derivative parameter N
C = pid(Kp, Ki, Kd, 1/N); % Mathematically: Kd * (N s)/(1 + N s)
% Some MATLAB versions parameterize the filter as Td/N
T = feedback(C*G, 1); % closed-loop transfer from reference to output
t = linspace(0, 2, 1000);
[y, t] = step(T, t);
figure;
plot(t, y, "LineWidth", 1.5); grid on;
xlabel("time (s)");
ylabel("joint position");
title("Step response with filtered derivative PID");
% In Simulink, one can use a PID Controller block and specify the
% filter coefficient N directly in the block parameters.
In Simulink models of robotic joints or end-effector motion, the PID Controller block can be configured with a filter coefficient, corresponding to the first-order filtered derivative structure analyzed in this lesson.
10. Wolfram Mathematica Implementation
In Wolfram Mathematica, the filtered derivative PID can be expressed using symbolic transfer functions and simulated numerically:
(* Parameters *)
J = 0.01; B = 0.1; K = 0;
Kp = 50; Ki = 0; Kd = 2; N = 20;
(* Plant and controller in s-domain *)
s = LaplaceTransformVariable;
G = TransferFunctionModel[1/(J s^2 + B s + (K + 1)), s];
CD = TransferFunctionModel[Kd N s/(1 + N s), s];
CP = TransferFunctionModel[Kp, s];
CI = TransferFunctionModel[Ki/s, s];
C = CP + CI + CD;
(* Closed-loop system from reference to output *)
Tsys = SystemsModelFeedbackConnect[C*G, 1];
(* Step response *)
StepResponsePlot[Tsys, {0, 2},
PlotRange -> All,
Frame -> True,
FrameLabel -> {"time (s)", "output y(t)"},
PlotLegends -> {"step response"}
]
Mathematica is particularly convenient for analytic manipulation of \( G(s) \), \( C(s) \), and the resulting closed-loop transfer functions, allowing direct verification of the high-frequency limits derived earlier.
11. Problems and Solutions
Problem 1 (Noise-to-Control Transfer Function): Consider a unity-feedback system with plant \( G(s) \) and controller \( C(s) \). Measurement noise \( n(t) \) is added to the plant output before the error computation. Derive the transfer function \( T_{u n}(s) = U(s)/N(s) \), and show that for strictly proper \( G(s) \) and large \( |s| \) we have \( T_{u n}(s) \approx - C(s) \).
Solution:
From the derivation earlier in the lesson:
\[ E(s) = R(s) - Y(s) - N(s), \quad U(s) = C(s) E(s), \quad Y(s) = G(s) U(s). \]
Eliminating \( E(s) \) and \( Y(s) \), we find
\[ Y(s) = \frac{G(s)C(s)}{1 + G(s)C(s)} R(s) - \frac{G(s)C(s)}{1 + G(s)C(s)} N(s). \]
For the control signal,
\[ U(s) = C(s) \bigl(R(s) - Y(s) - N(s)\bigr). \]
Setting \( R(s) = 0 \) and substituting \( Y(s) = - \frac{G(s)C(s)}{1 + G(s)C(s)} N(s) \), we get
\[ U(s) = C(s) \left( -\left(- \frac{G(s)C(s)}{1 + G(s)C(s)} N(s)\right) - N(s) \right) = C(s)\left( \frac{G(s)C(s)}{1 + G(s)C(s)} - 1 \right) N(s). \]
Simplifying the factor,
\[ \frac{G(s)C(s)}{1 + G(s)C(s)} - 1 = \frac{G(s)C(s) - (1 + G(s)C(s))}{1 + G(s)C(s)} = -\frac{1}{1 + G(s)C(s)}. \]
Hence
\[ T_{u n}(s) = \frac{U(s)}{N(s)} = - \frac{C(s)}{1 + G(s)C(s)}. \]
If \( G(s) \) is strictly proper, then \( \lim_{|s|\to\infty} G(s) = 0 \), so \( 1 + G(s)C(s) \to 1 \). Therefore,
\[ T_{u n}(s) \approx - C(s) \quad \text{for large } |s|. \]
Problem 2 (Boundedness of Filtered Derivative): Let \( C_D(s) = K_d \frac{N s}{1 + N s} \) with \( K_d > 0 \), \( N > 0 \). Show that \( C_D(s) \) is bounded for all \( s \) with \( \operatorname{Re}(s) \ge 0 \).
Solution:
For any complex \( s \) with \( \operatorname{Re}(s) \ge 0 \), we have
\[ C_D(s) = K_d \frac{N s}{1 + N s}. \]
If \( 1 + N s = 0 \), then \( s = -1/N \), which has negative real part. Thus, the denominator does not vanish in the closed right half-plane. Since \( C_D(s) \) is a rational function with no poles in \( \operatorname{Re}(s) \ge 0 \), and its numerator and denominator are first order in \( s \), the magnitude is bounded there. In particular,
\[ \lim_{|s|\to\infty} C_D(s) = K_d, \]
so the high-frequency gain is bounded by \( |K_d| \), and the maximum magnitude on the closed right half-plane is finite.
Problem 3 (Comparison of Ideal vs Filtered Derivative at High Frequency): Suppose \( C_{\text{ideal}}(s) = K_d s \) and \( C_{\text{filt}}(s) = K_d \frac{N s}{1 + N s} \). Compute the ratio \( C_{\text{filt}}(s) / C_{\text{ideal}}(s) \) and study its limit as \( |s|\to\infty \).
Solution:
By direct computation,
\[ \frac{C_{\text{filt}}(s)}{C_{\text{ideal}}(s)} = \frac{K_d \frac{N s}{1 + N s}}{K_d s} = \frac{N}{1 + N s}. \]
For large \( |s| \) we have
\[ \lim_{|s|\to\infty} \frac{C_{\text{filt}}(s)}{C_{\text{ideal}}(s)} = \lim_{|s|\to\infty} \frac{N}{1 + N s} = 0. \]
Thus, at very high frequencies the filtered derivative behaves as a much weaker differentiator than the ideal one: its magnitude is negligible compared to the ideal derivative. This confirms the intuition that the filter suppresses high-frequency noise amplification.
Problem 4 (Closed-Loop with PD and Filtered Derivative): Consider a first-order plant \( G(s) = \frac{K}{\tau s + 1} \) controlled by a PD with filtered derivative \( C(s) = K_p + K_d \frac{N s}{1 + N s} \). Derive the closed-loop transfer function \( T(s) = Y(s)/R(s) \) for unity feedback.
Solution:
For unity feedback, \( T(s) = \frac{G(s)C(s)}{1 + G(s)C(s)} \). We have
\[ G(s) = \frac{K}{\tau s + 1}, \quad C(s) = K_p + K_d \frac{N s}{1 + N s} = \frac{K_p (1 + N s) + K_d N s}{1 + N s}. \]
Therefore,
\[ G(s)C(s) = \frac{K}{\tau s + 1} \cdot \frac{K_p (1 + N s) + K_d N s}{1 + N s} = \frac{K \bigl(K_p (1 + N s) + K_d N s\bigr)}{(\tau s + 1)(1 + N s)}. \]
Hence
\[ T(s) = \frac{\dfrac{K \bigl(K_p (1 + N s) + K_d N s\bigr)}{(\tau s + 1)(1 + N s)}} {1 + \dfrac{K \bigl(K_p (1 + N s) + K_d N s\bigr)}{(\tau s + 1)(1 + N s)}} = \frac{K \bigl(K_p (1 + N s) + K_d N s\bigr)} {(\tau s + 1)(1 + N s) + K \bigl(K_p (1 + N s) + K_d N s\bigr)}. \]
Expanding the denominator yields an explicit second-order polynomial in \( s \), whose coefficients depend on \( K, \tau, K_p, K_d, N \). This expression can be used to analyze transient response and to relate the filter parameter \( N \) to the closed-loop pole locations.
Problem 5 (Qualitative Design Question): Explain qualitatively why, in a robotic joint with significant encoder quantization noise, it is usually preferable to keep \( K_d \) moderate and tune \( N \) rather than simply increasing \( K_d \) to improve damping.
Solution:
Increasing \( K_d \) increases the derivative contribution for all frequencies. Since the noise-to-control transfer behaves as \( T_{u n}(s) \approx - C(s) \) at high frequencies, a large \( K_d \) directly scales up the actuator response to measurement noise (encoder quantization, communication jitter, etc.). This can cause rapid, high-amplitude torques that excite structural modes, saturate amplifiers, and increase mechanical wear.
By contrast, tuning \( N \) changes the frequency region where the derivative behaves like a differentiator, while keeping the high-frequency gain bounded by \( K_d \). A moderate \( K_d \) with carefully chosen \( N \) can provide sufficient damping in the frequency range relevant to the dominant closed-loop poles, while avoiding excessive amplification of very high-frequency quantization noise.
12. Summary
This lesson analyzed derivative action in PID controllers from a linear-systems viewpoint. We showed that ideal differentiation corresponds to the transfer function \( K_d s \), which yields an unbounded high-frequency gain and therefore very strong amplification of measurement noise in the actuator signal. Introducing a first-order filtered derivative \( K_d \frac{N s}{1 + N s} \) preserves derivative-like behavior in the frequency range of interest while bounding the high-frequency gain by \( K_d \).
We derived the noise-to-control and noise-to-output transfer functions,
explained the high-frequency limiting behavior, and discussed the
trade-offs in selecting the filter parameter \( N \).
Finally, we implemented filtered derivative PID controllers in Python
(python-control), C++ (ROS-style classes), Java,
MATLAB/Simulink, and Wolfram Mathematica, with an eye toward practical
robotic control software where measurement noise and actuator limits
play a crucial role.
13. References
- Åström, K.J., & Hägglund, T. (1995). PID Controllers: Theory, Design, and Tuning. Instrument Society of America.
- Åström, K.J. (1993). Limitations on control system performance. European Journal of Control, 1(1), 2–20.
- Ho, W.K., Hang, C.C., & Cao, L.S. (1995). Tuning of PID controllers based on gain and phase margin specifications. Automatica, 31(3), 497–502.
- Visioli, A. (2006). Practical PID control: A review of design methods. Control Engineering Practice, 14(7), 777–797.
- Grimble, M.J. (1991). Robust industrial control: Optimal design and tuning of PID controllers. IEE Proceedings D (Control Theory and Applications), 138(1), 25–37.
- Kristiansson, B., & Lennartson, B. (2006). Robust and optimal tuning of PI and PID controllers. IEE Proceedings Control Theory and Applications, 153(1), 76–88.
- Panagopoulos, H., Åström, K.J., & Hägglund, T. (2002). Design of PID controllers based on constrained optimization. IEE Proceedings Control Theory and Applications, 149(1), 32–40.
- Zhuang, M., & Atherton, D.P. (1993). Automatic tuning of optimum PID controllers. IEE Proceedings D (Control Theory and Applications), 140(3), 216–224.
- Hjalmarsson, H. (2005). From experiment design to closed-loop control. Automatica, 41(3), 393–438.
- Silva, G.J., Datta, A., & Bhattacharyya, S.P. (2005). PID Controllers for Time-Delay Systems. Birkhäuser.