Chapter 6: Time Response of Second-Order and Higher-Order Systems
Lesson 2: Damping Ratio, Natural Frequency, and Pole Locations
In this lesson we study the intrinsic parameters of a standard second-order linear system: the damping ratio \( \zeta \), the undamped natural frequency \( \omega_n \), and the locations of the closed-loop poles in the complex \( s \)-plane. We develop the analytic relationships between physical parameters, characteristic equation, and pole locations, and show how these quantities are computed and used in software (Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica), including a robotics-oriented viewpoint.
1. Standard Second-Order Model and Physical Origin of \( \omega_n \) and \( \zeta \)
In Lesson 1 of this chapter we introduced the standard second-order transfer function obtained from typical physical systems such as mass–spring–damper translational dynamics, torsional shafts, or joint servo drives in robotic manipulators. For a single-degree-of-freedom mass–spring–damper system,
\[ m \ddot{y}(t) + c \dot{y}(t) + k y(t) = K u(t), \]
where \( y(t) \) is displacement (e.g., a robot joint angle), \( u(t) \) is an input (e.g., actuator force or torque), \( m \) is mass, \( c \) is viscous damping, and \( k \) is stiffness. Dividing by \( m \) yields
\[ \ddot{y}(t) + \frac{c}{m} \dot{y}(t) + \frac{k}{m} y(t) = \frac{K}{m} u(t). \]
We define the undamped natural frequency and damping ratio by matching this equation to the canonical second-order form
\[ \ddot{y}(t) + 2 \zeta \omega_n \dot{y}(t) + \omega_n^2 y(t) = \omega_n^2 u(t), \]
so that
\[ \omega_n^2 = \frac{k}{m}, \qquad 2 \zeta \omega_n = \frac{c}{m}. \]
Therefore
\[ \omega_n = \sqrt{\frac{k}{m}}, \qquad \zeta = \frac{c}{2\sqrt{km}}. \]
\( \omega_n \) is the oscillation frequency of the undamped system (\( c=0 \)), and \( \zeta \) is the ratio between the actual damping \( c \) and the critical damping \( c_{\text{cr}} = 2\sqrt{km} \): \( \zeta = c / c_{\text{cr}} \). These definitions extend to any LTI system whose transfer function denominator can be written as
\[ G(s) = \frac{\text{(constant gain)}}{s^2 + 2\zeta \omega_n s + \omega_n^2}. \]
flowchart TD
A["Physical parameters (m, c, k, etc.)"]
--> B["Differential equation in time domain"]
B --> C["Normalize coefficients (divide by m)"]
C --> D["Canonical form: y'' + 2 zeta omega_n y' + omega_n^2 y = omega_n^2 u"]
D --> E["Characteristic equation: s^2 + 2 zeta omega_n s + omega_n^2 = 0"]
E --> F["Poles in s-plane and time response"]
2. Characteristic Equation and Pole Locations
The transfer function of a standard second-order system with unity DC gain is
\[ G(s) = \frac{\omega_n^2}{s^2 + 2 \zeta \omega_n s + \omega_n^2}. \]
The denominator is the characteristic polynomial
\[ p(s) = s^2 + 2 \zeta \omega_n s + \omega_n^2. \]
The poles are the roots of \( p(s) = 0 \), given by the quadratic formula
\[ s_{1,2} = -\zeta \omega_n \pm \omega_n \sqrt{\zeta^2 - 1}. \]
Three qualitatively distinct cases occur:
- Overdamped: \( \zeta > 1 \). Two distinct real negative poles \( s_1, s_2 \in \mathbb{R} \) with \( s_1 \neq s_2 \).
- Critically damped: \( \zeta = 1 \). A repeated real pole at \( s = -\omega_n \).
- Underdamped: \( 0 < \zeta < 1 \). A complex conjugate pair of poles
\[ s_{1,2} = -\zeta \omega_n \pm j \omega_n \sqrt{1 - \zeta^2} = -\sigma \pm j \omega_d, \]
where we define
\[ \sigma \triangleq \zeta \omega_n, \qquad \omega_d \triangleq \omega_n \sqrt{1 - \zeta^2}. \]
The parameters \( \sigma \) and \( \omega_d \) have a clear time-domain interpretation: \( \sigma \) is the exponential decay rate of the oscillation envelope, and \( \omega_d \) is the damped natural frequency, i.e., the oscillation frequency in the presence of damping.
If \( \zeta = 0 \), the poles are purely imaginary \( s_{1,2} = \pm j \omega_n \) and the system exhibits undamped sinusoidal oscillation. If \( \zeta < 0 \), then \( \Re(s_{1,2}) > 0 \) and the system is unstable (growing oscillation).
3. Geometric Relations Between \( \zeta \), \( \omega_n \), and Pole Locations
Consider the underdamped case \( 0 < \zeta < 1 \). The poles can be written as
\[ s_{1,2} = -\zeta \omega_n \pm j \omega_n \sqrt{1 - \zeta^2}. \]
In Cartesian coordinates, for one pole we have
\[ \Re(s) = -\zeta \omega_n = -\sigma, \qquad \Im(s) = \pm \omega_n \sqrt{1 - \zeta^2} = \pm \omega_d. \]
The radius of the pole from the origin is
\[ \lvert s \rvert = \sqrt{\Re(s)^2 + \Im(s)^2} = \sqrt{\zeta^2 \omega_n^2 + \omega_n^2 (1 - \zeta^2)} = \omega_n. \]
Thus, for a second-order system the undamped natural frequency is simply the distance from the origin to either pole in the \( s \)-plane. Let \( \theta \) be the angle that the pole makes with the negative real axis (i.e., measured from left to right). Then
\[ \cos \theta = \frac{\zeta \omega_n}{\omega_n} = \zeta, \qquad \sin \theta = \frac{\omega_d}{\omega_n} = \sqrt{1 - \zeta^2}. \]
Therefore:
- The angle \( \theta \) of the pole with respect to the negative real axis encodes the damping ratio: \( \zeta = \cos \theta \).
- The radius \( \omega_n \) encodes how “fast” the oscillation is.
Conversely, if we know the pole location \( p \in \mathbb{C} \setminus \mathbb{R} \) with \( \Re(p) < 0 \), we can recover \( \omega_n \) and \( \zeta \) as
\[ \omega_n = \sqrt{\Re(p)^2 + \Im(p)^2}, \qquad \zeta = -\frac{\Re(p)}{\omega_n}. \]
For the overdamped case \( \zeta > 1 \) with real poles \( s_1, s_2 < 0 \), we have
\[ p(s) = (s - s_1)(s - s_2) = s^2 - (s_1 + s_2)s + s_1 s_2 = s^2 + 2\zeta \omega_n s + \omega_n^2, \]
so that
\[ \omega_n^2 = s_1 s_2, \qquad 2\zeta \omega_n = - (s_1 + s_2), \]
i.e.,
\[ \omega_n = \sqrt{s_1 s_2}, \qquad \zeta = -\frac{s_1 + s_2}{2\sqrt{s_1 s_2}}, \]
provided \( s_1 < 0 \), \( s_2 < 0 \). This gives a unified mapping between real poles and the canonical parameters \( \zeta \) and \( \omega_n \).
4. Time-Domain Solution of the Homogeneous Equation
Consider the homogeneous second-order equation (zero input) in canonical form:
\[ \ddot{y}(t) + 2 \zeta \omega_n \dot{y}(t) + \omega_n^2 y(t) = 0. \]
We look for exponential solutions of the form \( y(t) = e^{s t} \), which gives the characteristic equation
\[ s^2 + 2 \zeta \omega_n s + \omega_n^2 = 0. \]
For \( 0 < \zeta < 1 \) (underdamped), the roots are \( s_{1,2} = -\zeta \omega_n \pm j \omega_d \) with \( \omega_d = \omega_n \sqrt{1 - \zeta^2} \). The general solution is
\[ y(t) = e^{-\zeta \omega_n t}\left( C_1 \cos(\omega_d t) + C_2 \sin(\omega_d t) \right), \]
where \( C_1, C_2 \) depend on initial conditions \( y(0) \), \( \dot{y}(0) \). We see:
- \( e^{-\zeta \omega_n t} \) is an exponential envelope with decay rate \( \zeta \omega_n = \sigma \).
- \( \omega_d \) is the oscillation frequency of the damped system.
For \( \zeta = 1 \) (critical damping), the repeated root \( s = -\omega_n \) leads to
\[ y(t) = (C_1 + C_2 t) e^{-\omega_n t}, \]
which decays to zero without oscillation, and is the “fastest” non-oscillatory response achievable by any linear second-order system with fixed \( \omega_n \).
For \( \zeta > 1 \) (overdamped), with real roots \( s_1, s_2 < 0 \), we obtain
\[ y(t) = C_1 e^{s_1 t} + C_2 e^{s_2 t}, \]
again non-oscillatory but generally slower than the critically damped response for the same \( \omega_n \). These explicit solutions connect the pole locations in the complex plane with the qualitative shape of the time response.
5. Classification of Second-Order Responses by Damping Ratio
Using the relations above, second-order systems are classified by \( \zeta \) as:
- \( \zeta < 0 \): negative damping, poles in the right-half plane (RHP), exponentially growing oscillations, physically unstable.
- \( \zeta = 0 \): undamped, purely imaginary poles, sustained sinusoidal oscillations.
- \( 0 < \zeta < 1 \): underdamped, decaying oscillations with frequency \( \omega_d \).
- \( \zeta = 1 \): critically damped, fastest non-oscillatory decay.
- \( \zeta > 1 \): overdamped, slow non-oscillatory decay with two distinct real poles.
From a robotics perspective, joint servo loops are usually designed to be underdamped with a moderate damping ratio (e.g., \( \zeta \approx 0.5 \)–\( 0.9 \)) to balance fast response and limited oscillation. The canonical second-order model provides a compact way to summarize and tune such behavior.
flowchart TD
S["Start with zeta"] --> A["zeta < 0?"]
A -->|yes| U["Unstable: RHP poles, \ngrowing oscillation"]
A -->|no| B["zeta = 0?"]
B -->|yes| P["Purely imaginary poles, \nsustained oscillation"]
B -->|no| C["0 < zeta < 1?"]
C -->|yes| D["Underdamped: complex conjugate poles, \ndecaying oscillation"]
C -->|no| E["zeta = 1?"]
E -->|yes| F["Critically damped: \nrepeated real pole, \nfastest non-oscillatory"]
E -->|no| G["Overdamped: two distinct \nreal negative poles, \nslow decay"]
6. Computational Lab — Python Implementation
We now show how to compute \( \zeta \) and \( \omega_n \) from pole
locations and construct the corresponding transfer function in Python.
We use the
python-control library for transfer-function operations,
which is widely used in robotics for modeling and simulation of joint
servos and mobile robot dynamics.
import numpy as np
from control import TransferFunction, step_response, pole
def second_order_from_poles(p1, p2):
"""
Given two poles p1, p2 (complex or real) of a second-order system,
return (zeta, omega_n).
"""
# For a second-order system, p(s) = (s - p1)(s - p2)
# = s**2 - (p1 + p2)s + p1*p2
# and p(s) = s**2 + 2 zeta omega_n s + omega_n**2
s1 = p1
s2 = p2
# Sum and product
s_sum = s1 + s2
s_prod = s1 * s2
omega_n = np.sqrt(np.real(s_prod))
# For complex conjugate or negative real poles, real part is negative
zeta = -np.real(s_sum) / (2.0 * omega_n)
return float(zeta), float(omega_n)
def transfer_function_from_zn(zeta, omega_n, k=1.0):
"""
Construct G(s) = k * omega_n^2 / (s^2 + 2 zeta omega_n s + omega_n^2).
"""
num = [k * omega_n**2]
den = [1.0, 2.0 * zeta * omega_n, omega_n**2]
return TransferFunction(num, den)
# Example: design a joint servo model with zeta = 0.7, omega_n = 8 rad/s
zeta_des = 0.7
omega_n_des = 8.0
G = transfer_function_from_zn(zeta_des, omega_n_des)
print("G(s) =", G)
print("Poles:", pole(G))
# Recover zeta and omega_n from the actual poles:
p = pole(G)
zeta_hat, omega_n_hat = second_order_from_poles(p[0], p[1])
print("Recovered zeta =", zeta_hat, ", omega_n =", omega_n_hat)
# Time response (will be used in later lessons to define performance metrics)
t, y = step_response(G)
In robotics-oriented Python stacks, such as
roboticstoolbox-python, these second-order models appear
frequently in joint servo modeling, where \( \zeta \) and \( \omega_n \)
are tuned to achieve acceptable tracking performance on each actuated
joint.
7. Computational Lab — C++ Implementation
C++ is widely used in robotics middleware such as ROS and ROS 2. Control
loops for robot joints often run in C++ using Eigen for linear algebra
and frameworks such as
ros_control for controller integration. The following
snippet computes \( \zeta \) and \( \omega_n \) from two poles using
std::complex.
#include <iostream>
#include <complex>
#include <cmath>
struct SecondOrderParams {
double zeta;
double omega_n;
};
SecondOrderParams fromPoles(const std::complex<double>& p1,
const std::complex<double>& p2)
{
// p(s) = (s - p1)(s - p2)
std::complex<double> s_sum = p1 + p2;
std::complex<double> s_prod = p1 * p2;
double omega_n = std::sqrt(s_prod.real());
double zeta = -s_sum.real() / (2.0 * omega_n);
SecondOrderParams params{zeta, omega_n};
return params;
}
int main()
{
// Example: underdamped poles at -4 +- j*4*std::sqrt(3)
std::complex<double> p1(-4.0, 4.0 * std::sqrt(3.0));
std::complex<double> p2(-4.0, -4.0 * std::sqrt(3.0));
SecondOrderParams params = fromPoles(p1, p2);
std::cout << "zeta = " << params.zeta << std::endl;
std::cout << "omega_n = " << params.omega_n << std::endl;
// In a ROS controller, one could use these parameters to check that
// the closed-loop joint dynamics remain within acceptable ranges.
return 0;
}
In a full robotic application, the poles \( p_1, p_2 \) would come from the closed-loop characteristic polynomial of a joint or end-effector controller, and the computation above can be used to monitor effective damping and natural frequency as gains are tuned.
8. Computational Lab — Java Implementation
Java is used in several robotics platforms, such as the FRC (FIRST
Robotics Competition) ecosystem via WPILib. Although we do
not rely on a specific framework here, we show a small utility class for
computing \( \zeta \) and \( \omega_n \) from poles, which can be
integrated in Java-based robotic control stacks.
public final class SecondOrderSystem {
private final double zeta;
private final double omegaN;
public SecondOrderSystem(double poleReal1, double poleImag1,
double poleReal2, double poleImag2) {
// p1 = poleReal1 + j poleImag1
// p2 = poleReal2 + j poleImag2
double sumReal = poleReal1 + poleReal2;
double sumImag = poleImag1 + poleImag2;
double prodReal = poleReal1 * poleReal2 - poleImag1 * poleImag2;
double prodImag = poleReal1 * poleImag2 + poleReal2 * poleImag1;
// For a stable second-order system, the product should be real > 0
if (Math.abs(prodImag) > 1e-6) {
throw new IllegalArgumentException("Poles are not a valid conjugate pair.");
}
double omegaN = Math.sqrt(prodReal);
double zeta = -sumReal / (2.0 * omegaN);
this.zeta = zeta;
this.omegaN = omegaN;
}
public double getZeta() {
return zeta;
}
public double getOmegaN() {
return omegaN;
}
public double[] canonicalDenominator() {
// returns [1, 2 zeta omega_n, omega_n^2]
return new double[] {1.0, 2.0 * zeta * omegaN, omegaN * omegaN};
}
}
In frameworks like WPILib, one could pair such a utility
with plant models (e.g., LinearSystemId) and verify that
controller tuning yields acceptable damping ratios for mechanisms such
as arm joints, elevators, or flywheels.
9. MATLAB/Simulink and Wolfram Mathematica Implementations
9.1 MATLAB / Simulink
MATLAB with Control System Toolbox and Robotics System Toolbox is standard in many control and robotics courses. The following script constructs a second-order model and extracts its poles and canonical parameters.
% Desired parameters for a robotic joint servo
zeta = 0.7;
wn = 8; % rad/s
K_dc = 1.0; % DC gain
num = K_dc * wn^2;
den = [1 2*zeta*wn wn^2];
G = tf(num, den);
disp('Transfer function G(s):');
G
p = pole(G)
% Recover parameters from poles (assuming stable system)
s1 = p(1);
s2 = p(2);
wn_hat = sqrt(s1 * s2);
zeta_hat = - (s1 + s2) / (2 * wn_hat);
fprintf('Recovered zeta = %.4f, omega_n = %.4f\n', zeta_hat, wn_hat);
% Simulink: one can create a "Transfer Fcn" block with numerator [num]
% and denominator [den], then use "Step" blocks and scopes to study the
% time response within a larger robotic manipulator model.
9.2 Wolfram Mathematica
In Wolfram Mathematica, symbolic manipulation makes it easy to derive and visualize relationships between poles, \( \zeta \), and \( \omega_n \).
(* Parameters *)
zeta = 0.5;
wn = 6;
(* Define transfer function model *)
sys = TransferFunctionModel[
wn^2 / (s^2 + 2 zeta wn s + wn^2),
s
];
(* Poles *)
poles = PoleZeroPlot[sys, PlotRange -> All]
(* Recover omega_n and zeta from one pole *)
p = First@SystemsModelPoles[sys];
sigma = -Re[p];
omegaD = Im[p];
omegaNrec = Sqrt[sigma^2 + omegaD^2];
zetarec = sigma / omegaNrec;
{omegaNrec, zetarec}
Such symbolic computations can also be combined with robotic manipulator dynamics to analyze how changes in inertia or damping (e.g., due to different payloads) affect the effective \( \zeta \) and \( \omega_n \) of joint motion.
10. Problems and Solutions
Problem 1 (Identify \( \zeta \) and \( \omega_n \) from the Denominator): Consider a second-order transfer function
\[ G(s) = \frac{10}{s^2 + 6s + 25}. \]
(a) Express the denominator in the canonical form \( s^2 + 2 \zeta \omega_n s + \omega_n^2 \). (b) Compute \( \omega_n \) and \( \zeta \). (c) Classify the damping (under/critical/over).
Solution:
(a) Comparing denominators,
\[ s^2 + 6 s + 25 \equiv s^2 + 2 \zeta \omega_n s + \omega_n^2. \]
Hence
\[ 2 \zeta \omega_n = 6, \qquad \omega_n^2 = 25. \]
(b) From \( \omega_n^2 = 25 \) we get \( \omega_n = 5 \; \text{rad/s} \) (taking the positive root). Then
\[ 2 \zeta \cdot 5 = 6 \quad \Longrightarrow \quad \zeta = \frac{6}{10} = 0.6. \]
(c) Since \( 0 < 0.6 < 1 \), the system is underdamped with complex conjugate poles.
Problem 2 (Compute \( \zeta \) and \( \omega_n \) from Complex Poles): Suppose a closed-loop robotic joint has dominant closed-loop poles at \( s_{1,2} = -4 \pm j 4\sqrt{3} \). Compute \( \omega_n \) and \( \zeta \).
Solution:
Let \( p = -4 + j 4\sqrt{3} \). Then
\[ \Re(p) = -4, \qquad \Im(p) = 4\sqrt{3}. \]
The undamped natural frequency is
\[ \omega_n = \sqrt{\Re(p)^2 + \Im(p)^2} = \sqrt{(-4)^2 + (4\sqrt{3})^2} = \sqrt{16 + 48} = \sqrt{64} = 8. \]
The damping ratio is
\[ \zeta = -\frac{\Re(p)}{\omega_n} = -\frac{-4}{8} = 0.5. \]
Hence the system is underdamped with \( \zeta = 0.5 \), \( \omega_n = 8 \; \text{rad/s} \), and damped frequency \( \omega_d = \omega_n \sqrt{1 - \zeta^2} = 8 \sqrt{1 - 0.25} = 8 \sqrt{0.75} = 4\sqrt{3} \).
Problem 3 (Geometric Proof of \( \omega_n = \lvert s \rvert \) and \( \zeta = \cos \theta \)): For an underdamped second-order system with poles \( s_{1,2} = -\zeta \omega_n \pm j \omega_d \), prove that \( \omega_n = \lvert s \rvert \) and \( \zeta = \cos \theta \), where \( \theta \) is the angle of the pole with respect to the negative real axis.
Solution:
Consider \( s = -\zeta \omega_n + j \omega_d \) with \( \omega_d = \omega_n \sqrt{1 - \zeta^2} \). Then
\[ \lvert s \rvert = \sqrt{(\Re(s))^2 + (\Im(s))^2} = \sqrt{(\zeta \omega_n)^2 + (\omega_n^2 (1 - \zeta^2))} = \sqrt{\omega_n^2} = \omega_n. \]
Let \( \theta \) be the angle between the vector from the origin to \( s \) and the negative real axis. The adjacent side (along the negative real axis) has length \( \zeta \omega_n \) and the hypotenuse has length \( \omega_n \). Therefore
\[ \cos \theta = \frac{\zeta \omega_n}{\omega_n} = \zeta. \]
Thus, the undamped natural frequency is the distance from the origin to the pole, and the damping ratio is the cosine of the angle measured from the negative real axis.
Problem 4 (Damping Ratio from Real Negative Poles): A second-order system has overdamped closed-loop poles at \( s_1 = -1 \) and \( s_2 = -9 \). Find \( \zeta \) and \( \omega_n \) for the equivalent standard form.
Solution:
For real poles \( s_1, s_2 < 0 \), we have \( \omega_n^2 = s_1 s_2 \) and \( 2\zeta \omega_n = - (s_1 + s_2) \). Thus
\[ \omega_n^2 = (-1)(-9) = 9 \quad \Longrightarrow \quad \omega_n = 3. \]
Then
\[ 2 \zeta \omega_n = - (s_1 + s_2) = -(-1 - 9) = 10, \]
\[ 2 \zeta \cdot 3 = 10 \quad \Longrightarrow \quad \zeta = \frac{10}{6} = \frac{5}{3} \approx 1.667. \]
Since \( \zeta > 1 \), the system is strongly overdamped, with a relatively slow return to equilibrium.
Problem 5 (Stability Condition in Canonical Parameters): Consider the canonical second-order characteristic polynomial \( p(s) = s^2 + 2 \zeta \omega_n s + \omega_n^2 \) with scalar parameters \( \zeta, \omega_n \in \mathbb{R} \). Determine conditions on \( \zeta \) and \( \omega_n \) for which the system is asymptotically stable (i.e., both poles lie in the left-half plane).
Solution:
A real second-order polynomial \( s^2 + a_1 s + a_0 \) with real coefficients is asymptotically stable if and only if \( a_1 > 0 \) and \( a_0 > 0 \). For the canonical form we have \( a_1 = 2 \zeta \omega_n \) and \( a_0 = \omega_n^2 \). Thus:
- \( a_0 = \omega_n^2 > 0 \) if and only if \( \omega_n \neq 0 \), and typically we choose \( \omega_n > 0 \) by definition.
- \( a_1 = 2 \zeta \omega_n > 0 \) if and only if \( \zeta \omega_n > 0 \). With \( \omega_n > 0 \), this is equivalent to \( \zeta > 0 \).
Therefore, the system is asymptotically stable if and only if \( \omega_n > 0 \) and \( \zeta > 0 \).
11. Summary
In this lesson we analyzed the canonical second-order LTI model, introduced the undamped natural frequency \( \omega_n \) and damping ratio \( \zeta \), and connected them to the pole locations of the transfer function. We derived explicit formulas linking physical parameters \( (m, c, k) \) to \( \omega_n \) and \( \zeta \), and then connected these to the roots of the characteristic polynomial. We showed that the magnitude of the pole equals \( \omega_n \) and that the damping ratio equals \( \cos \theta \), where \( \theta \) is the angle of the pole with respect to the negative real axis.
We also derived the homogeneous time-domain solutions for underdamped, critically damped, and overdamped systems, and saw how these solutions are composed of exponentials and sinusoids whose rates and frequencies are directly determined by \( \omega_n \) and \( \zeta \). Finally, we implemented practical computations in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica, emphasizing their relevance for robotics applications where joint and actuator dynamics are often approximated by such second-order models. These relationships form the quantitative foundation for the transient performance measures studied in the next lesson.
12. References
- Kalman, R. E. (1960). On the general theory of control systems. IRE Transactions on Automatic Control.
- Zames, G. (1966). On the input–output stability of time-varying nonlinear feedback systems. IEEE Transactions on Automatic Control.
- Routh, E. J. (1877). A treatise on the stability of a given state of motion, particularly the motion of a ship. Proceedings of the London Mathematical Society.
- Bode, H. W. (1945). Network analysis and feedback amplifier design. Bell Telephone Laboratories Monograph.
- Ogata, K. (1990). Modern Control Engineering. Prentice Hall. (Foundational theoretical treatment of second-order systems and damping.)
- Franklin, G. F., Powell, J. D., & Emami-Naeini, A. (1994). Feedback Control of Dynamic Systems. Addison-Wesley.