Chapter 14: Bode Plot Construction and Interpretation
Lesson 2: Bode Plots for First-Order and Second-Order Factors
In this lesson we derive the analytical Bode magnitude and phase curves for the basic building blocks of linear time-invariant transfer functions: first-order and second-order factors. By exploiting factorization in the complex frequency domain and the logarithmic decibel scale, we show how any rational transfer function can be interpreted as a sum of simple magnitude and phase contributions. This lesson provides the mathematical foundation for approximate and exact Bode plot construction used in later design-oriented chapters.
1. Decomposition into Standard First- and Second-Order Factors
Consider a proper rational transfer function in the Laplace domain, with real coefficients and no pole-zero cancellations:
\[ G(s) = K \frac{\prod_{k=1}^{m_z} (1 + \tfrac{s}{z_k}) \prod_{\ell=1}^{m_z^{(2)}} \left( 1 + 2\zeta_{z,\ell}\tfrac{s}{\omega_{n,z,\ell}} + \left(\tfrac{s}{\omega_{n,z,\ell}}\right)^2 \right)} {\prod_{k=1}^{m_p} (1 + \tfrac{s}{p_k}) \prod_{\ell=1}^{m_p^{(2)}} \left( 1 + 2\zeta_{p,\ell}\tfrac{s}{\omega_{n,p,\ell}} + \left(\tfrac{s}{\omega_{n,p,\ell}}\right)^2 \right)} \]
Here \( K \) is a real constant gain, the factors \( (1 + \tfrac{s}{p_k}) \) and \( (1 + \tfrac{s}{z_k}) \) are first-order real poles and zeros, and the quadratic factors represent conjugate complex poles or zeros in standard second-order form.
For sinusoidal steady-state analysis we evaluate \( G(j\omega) \). Because magnitude and phase of a product factorize, in decibels we obtain
\[ 20\log_{10}\lvert G(j\omega)\rvert = 20\log_{10}\lvert K\rvert + \sum_{i} 20\log_{10}\lvert G_i(j\omega)\rvert, \]
and the phase is additive:
\[ \angle G(j\omega) = \angle K + \sum_i \angle G_i(j\omega). \]
Therefore, it is enough to study the Bode magnitude and phase of individual first-order and second-order factors; arbitrary rational systems then follow by superposition in the logarithmic domain.
2. First-Order Pole Factor
A standard first-order pole factor with corner (break) frequency \( \omega_c \) is
\[ G_p(s) = \frac{1}{1 + \tfrac{s}{\omega_c}} = \frac{\omega_c}{s + \omega_c}. \]
Evaluating at \( s = j\omega \):
\[ G_p(j\omega) = \frac{1}{1 + j\tfrac{\omega}{\omega_c}}. \]
The magnitude is
\[ \lvert G_p(j\omega)\rvert = \frac{1}{\sqrt{1 + \left(\tfrac{\omega}{\omega_c}\right)^2}}, \quad \lvert G_p(j\omega)\rvert_{\text{dB}} = -10\log_{10}\!\left(1 + \left(\tfrac{\omega}{\omega_c}\right)^2\right). \]
For the phase, recall that \( \angle(1 + jx) = \tan^{-1}\!\left(\tfrac{x}{1}\right) \). Thus,
\[ \angle G_p(j\omega) = -\tan^{-1}\!\left(\tfrac{\omega}{\omega_c}\right). \]
Asymptotically:
- For \( \omega \ll \omega_c \): \( \lvert G_p(j\omega)\rvert \approx 1 \) (0 dB), \( \angle G_p(j\omega) \approx 0^\circ \).
- For \( \omega \gg \omega_c \): \( \lvert G_p(j\omega)\rvert \approx \tfrac{\omega_c}{\omega} \), which is a slope of \( -20 \,\text{dB/decade} \) on the log scale, and \( \angle G_p(j\omega) \to -90^\circ \).
Near the corner frequency \( \omega = \omega_c \) we have \( \lvert G_p(j\omega_c)\rvert = \tfrac{1}{\sqrt{2}} \), i.e. about \( -3 \,\text{dB} \), and \( \angle G_p(j\omega_c) = -45^\circ \).
flowchart TD
A["First-order pole G_p(s) = 1 / (1 + s/omega_c)"] --> B["Low freq: \nomega << omega_c"]
B --> B1["Magnitude ~ 0 dB, \nphase ~ 0 deg"]
A --> C["Corner: \nomega = omega_c"]
C --> C1["Magnitude ~ -3 dB, \nphase ~ -45 deg"]
A --> D["High freq: \nomega >> omega_c"]
D --> D1["Magnitude slope -20 dB/dec, \nphase → -90 deg"]
3. First-Order Zero and Elementary s-Factors
A standard first-order zero factor with corner frequency \( \omega_z \) is
\[ G_z(s) = 1 + \tfrac{s}{\omega_z}. \]
At \( s = j\omega \):
\[ G_z(j\omega) = 1 + j\tfrac{\omega}{\omega_z}, \quad \lvert G_z(j\omega)\rvert = \sqrt{1 + \left(\tfrac{\omega}{\omega_z}\right)^2}, \quad \lvert G_z(j\omega)\rvert_{\text{dB}} = 10\log_{10}\!\left(1 + \left(\tfrac{\omega}{\omega_z}\right)^2\right). \]
The phase is
\[ \angle G_z(j\omega) = \tan^{-1}\!\left(\tfrac{\omega}{\omega_z}\right). \]
Asymptotics:
- For \( \omega \ll \omega_z \): \( \lvert G_z(j\omega)\rvert \approx 1 \) (0 dB), \( \angle G_z(j\omega) \approx 0^\circ \).
- For \( \omega \gg \omega_z \): \( \lvert G_z(j\omega)\rvert \approx \tfrac{\omega}{\omega_z} \), i.e. \( +20 \,\text{dB/decade} \) slope, and \( \angle G_z(j\omega) \to +90^\circ \).
Two additional fundamental first-order factors appear frequently in control:
- Integrator \( G_I(s) = \tfrac{1}{s} \): \( \lvert G_I(j\omega)\rvert = \tfrac{1}{\omega} \) (slope \( -20\,\text{dB/decade} \) starting at any reference frequency) and \( \angle G_I(j\omega) = -90^\circ \).
- Differentiator \( G_D(s) = s \): \( \lvert G_D(j\omega)\rvert = \omega \) (slope \( +20\,\text{dB/decade} \)) and \( \angle G_D(j\omega) = +90^\circ \).
These elementary factors, together with constant gains, form the basic building blocks for Bode magnitude and phase diagrams of more complex systems.
4. Canonical Second-Order Pole Factor: Magnitude
A standard second-order pole factor with natural frequency \( \omega_n \) and damping ratio \( \zeta \) is written as
\[ G_2(s) = \frac{\omega_n^2}{s^2 + 2\zeta\omega_n s + \omega_n^2}. \]
Evaluating at \( s = j\omega \) and defining the dimensionless frequency \( r = \tfrac{\omega}{\omega_n} \), the denominator becomes
\[ D(j\omega) = -\omega^2 + j2\zeta\omega_n\omega + \omega_n^2 = \omega_n^2\left( 1 - r^2 + j2\zeta r \right). \]
Hence
\[ G_2(j\omega) = \frac{1}{1 - r^2 + j2\zeta r}, \]
and the magnitude is
\[ \lvert G_2(j\omega)\rvert = \frac{1}{\sqrt{\left(1 - r^2\right)^2 + \left(2\zeta r\right)^2}}. \]
In decibels,
\[ \lvert G_2(j\omega)\rvert_{\text{dB}} = -10\log_{10}\!\left( \left(1 - r^2\right)^2 + \left(2\zeta r\right)^2 \right). \]
Asymptotic behavior:
- For \( \omega \ll \omega_n \) (i.e. \( r \ll 1 \)), \( 1 - r^2 \approx 1 \), \( 2\zeta r \approx 0 \), so \( \lvert G_2(j\omega)\rvert \approx 1 \) (0 dB).
- For \( \omega \gg \omega_n \) (i.e. \( r \gg 1 \)), \( 1 - r^2 \approx -r^2 \), so \( \lvert G_2(j\omega)\rvert \approx \tfrac{1}{r^2} = \left(\tfrac{\omega_n}{\omega}\right)^2 \), giving a slope of \( -40 \,\text{dB/decade} \).
At \( \omega = \omega_n \) (i.e. \( r = 1 \)), the magnitude is
\[ \lvert G_2(j\omega_n)\rvert = \frac{1}{\sqrt{(1 - 1)^2 + (2\zeta)^2}} = \frac{1}{2\zeta}. \]
Therefore, if \( \zeta < \tfrac{1}{\sqrt{2}} \), the magnitude exhibits a resonant peak \( M_r \) around \( \omega \approx \omega_n \). For underdamped systems (typical in motion control and robotics joints), this peak is critical for bandwidth and overshoot trade-offs.
5. Canonical Second-Order Pole Factor: Phase
For the same second-order factor, the phase is obtained from the complex denominator \( 1 - r^2 + j2\zeta r \). The phase of the reciprocal is the negative of the denominator phase, hence
\[ \angle G_2(j\omega) = -\tan^{-1}\!\left( \frac{2\zeta r}{1 - r^2} \right). \]
Important limits:
- \( \omega \to 0 \): \( r \to 0 \), phase \( \angle G_2(j\omega) \to 0^\circ \).
- \( \omega \to \infty \): \( r \to \infty \), \( 1 - r^2 \approx -r^2 \) and \( \tfrac{2\zeta r}{1 - r^2} \approx -\tfrac{2\zeta}{r} \to 0^- \), so \( \angle G_2(j\omega) \to -180^\circ \).
The transition in phase typically occurs over approximately two decades centered at \( \omega_n \). A common engineering approximation is:
- \( \omega \le 0.1\omega_n \): \( \angle G_2(j\omega) \approx 0^\circ \).
- \( \omega \ge 10\omega_n \): \( \angle G_2(j\omega) \approx -180^\circ \).
- Between \( 0.1\omega_n \) and \( 10\omega_n \), a smooth S-shaped phase curve descending from \( 0^\circ \) to \( -180^\circ \), with steeper slope near \( \omega_n \). The exact shape depends on \( \zeta \).
For underdamped poles, the rapid phase drop around the resonant frequency directly impacts phase margin in feedback systems, a key consideration in later stability-margin lessons.
6. Factor-Based Bode Plot Construction Workflow
The practical procedure for hand-constructing a Bode plot by factors is:
flowchart TD
A["Start from transfer function G(s)"] --> B["Factor G(s) into gain K, first-order and second-order factors"]
B --> C["Identify corner frequencies (poles/zeros, omega_c, omega_n)"]
C --> D["For each factor: sketch asymptotic magnitude (slopes 0, +/-20, +/-40 dB/dec)"]
D --> E["Add magnitudes in dB across frequency axis"]
E --> F["For each factor: sketch phase (0, +/-90, -180 deg transitions)"]
F --> G["Add phase contributions to obtain total phase"]
G --> H["Refine around corners and resonant peaks if higher accuracy needed"]
This factor-based approach mirrors how software tools (e.g., MATLAB, Python control libraries) compute Bode plots numerically, but it preserves analytical insight into how each pole and zero affects magnitude and phase.
7. Python Lab — First- and Second-Order Bode Plots (Robotics-Oriented)
We now generate Bode plots in Python using the
python-control library. Consider a simplified DC motor
position loop often used as a single joint model in robotic arms. The
open-loop plant can be approximated as a second-order system plus an
integrator (due to velocity-to-position integration). Here we restrict
ourselves to first- and second-order factors to connect with the theory.
import numpy as np
import matplotlib.pyplot as plt
# python-control for LTI systems (pip install control)
import control as ctl
# ----- First-order pole and zero -----
omega_c = 10.0 # rad/s corner frequency for pole
omega_z = 5.0 # rad/s corner frequency for zero
G_p = ctl.TransferFunction([omega_c], [1.0, omega_c]) # 1 / (1 + s/omega_c)
G_z = ctl.TransferFunction([1.0, omega_z], [omega_z]) # 1 + s/omega_z
# ----- Second-order plant (e.g., DC motor speed loop) -----
omega_n = 20.0
zeta = 0.3
G_2 = ctl.TransferFunction([omega_n**2],
[1.0, 2*zeta*omega_n, omega_n**2])
# Total plant as product of first- and second-order factors
G_total = G_p * G_2
# Frequency range (logarithmic)
omega = np.logspace(-1, 3, 500)
# Bode plots
plt.figure()
mag_p, phase_p, w = ctl.bode(G_p, omega, Plot=False)
plt.subplot(2, 1, 1)
plt.semilogx(w, 20*np.log10(mag_p))
plt.ylabel("Magnitude (dB)")
plt.title("First-order pole 1 / (1 + s/omega_c)")
plt.subplot(2, 1, 2)
plt.semilogx(w, np.degrees(phase_p))
plt.ylabel("Phase (deg)")
plt.xlabel("Frequency (rad/s)")
plt.tight_layout()
plt.figure()
mag_2, phase_2, w2 = ctl.bode(G_2, omega, Plot=False)
plt.subplot(2, 1, 1)
plt.semilogx(w2, 20*np.log10(mag_2))
plt.ylabel("Magnitude (dB)")
plt.title("Second-order factor omega_n^2 / (s^2 + 2 zeta omega_n s + omega_n^2)")
plt.subplot(2, 1, 2)
plt.semilogx(w2, np.degrees(phase_2))
plt.ylabel("Phase (deg)")
plt.xlabel("Frequency (rad/s)")
plt.tight_layout()
plt.figure()
mag_tot, phase_tot, w3 = ctl.bode(G_total, omega, Plot=False)
plt.subplot(2, 1, 1)
plt.semilogx(w3, 20*np.log10(mag_tot))
plt.ylabel("Magnitude (dB)")
plt.title("Combined first- and second-order plant")
plt.subplot(2, 1, 2)
plt.semilogx(w3, np.degrees(phase_tot))
plt.ylabel("Phase (deg)")
plt.xlabel("Frequency (rad/s)")
plt.tight_layout()
plt.show()
In a robotics setting (e.g., ROS-based control), such continuous-time transfer functions are often obtained from linearization or identification of actuator dynamics, then discretized and used to analyze servo loop bandwidth and resonance.
8. C++ Implementation for Bode Magnitude and Phase
In C++, we can compute Bode magnitude and phase numerically for use in custom analysis tools or embedded diagnostics on a robot controller. The code below uses the standard library and can be combined with Eigen for vectorized operations.
#include <iostream>
#include <cmath>
#include <vector>
struct BodePoint {
double omega;
double mag_dB;
double phase_deg;
};
BodePoint firstOrderPoleBode(double omega, double omega_c) {
double x = omega / omega_c;
double mag = 1.0 / std::sqrt(1.0 + x * x);
double mag_dB = 20.0 * std::log10(mag);
double phase_rad = -std::atan(x);
double phase_deg = phase_rad * 180.0 / M_PI;
return {omega, mag_dB, phase_deg};
}
BodePoint secondOrderPoleBode(double omega, double omega_n, double zeta) {
double r = omega / omega_n;
double num = 1.0; // magnitude of numerator is 1 in normalized form
double denom_real = 1.0 - r * r;
double denom_imag = 2.0 * zeta * r;
double denom_mag = std::sqrt(denom_real * denom_real + denom_imag * denom_imag);
double mag = num / denom_mag;
double mag_dB = 20.0 * std::log10(mag);
double phase_rad = -std::atan2(denom_imag, denom_real);
double phase_deg = phase_rad * 180.0 / M_PI;
return {omega, mag_dB, phase_deg};
}
int main() {
double omega_c = 10.0;
double omega_n = 20.0;
double zeta = 0.4;
std::vector<double> omega_vec;
for (int k = -1; k <= 3; ++k) {
// decade sampling for illustration
double omega = std::pow(10.0, static_cast<double>(k));
omega_vec.push_back(omega);
}
std::cout << "First-order pole Bode points:\n";
for (double omega : omega_vec) {
BodePoint bp = firstOrderPoleBode(omega, omega_c);
std::cout << "omega=" << bp.omega
<< " rad/s, |G| dB=" << bp.mag_dB
<< ", phase=" << bp.phase_deg << " deg\n";
}
std::cout << "\nSecond-order pole Bode points:\n";
for (double omega : omega_vec) {
BodePoint bp = secondOrderPoleBode(omega, omega_n, zeta);
std::cout << "omega=" << bp.omega
<< " rad/s, |G| dB=" << bp.mag_dB
<< ", phase=" << bp.phase_deg << " deg\n";
}
return 0;
}
In a robotics controller (e.g., built on top of
ros_control), such functions can be used offline to analyze
how changes in inertia or damping parameters affect the Bode
characteristics of joint drives.
9. Java Implementation for Bode Samples
Java is commonly used in high-level robot control stacks and simulation frameworks. The code below computes first- and second-order Bode points similar to the C++ snippet, and can be integrated with plotting libraries or exported to tools such as MATLAB.
public class BodeFactors {
public static class BodePoint {
public double omega;
public double magDb;
public double phaseDeg;
public BodePoint(double omega, double magDb, double phaseDeg) {
this.omega = omega;
this.magDb = magDb;
this.phaseDeg = phaseDeg;
}
}
public static BodePoint firstOrderPole(double omega, double omegaC) {
double x = omega / omegaC;
double mag = 1.0 / Math.sqrt(1.0 + x * x);
double magDb = 20.0 * Math.log10(mag);
double phaseRad = -Math.atan(x);
double phaseDeg = Math.toDegrees(phaseRad);
return new BodePoint(omega, magDb, phaseDeg);
}
public static BodePoint secondOrderPole(double omega, double omegaN, double zeta) {
double r = omega / omegaN;
double real = 1.0 - r * r;
double imag = 2.0 * zeta * r;
double denomMag = Math.sqrt(real * real + imag * imag);
double mag = 1.0 / denomMag;
double magDb = 20.0 * Math.log10(mag);
double phaseRad = -Math.atan2(imag, real);
double phaseDeg = Math.toDegrees(phaseRad);
return new BodePoint(omega, magDb, phaseDeg);
}
public static void main(String[] args) {
double omegaC = 10.0;
double omegaN = 20.0;
double zeta = 0.5;
double[] omegas = {0.1, 1.0, 10.0, 100.0, 1000.0};
System.out.println("First-order pole:");
for (double omega : omegas) {
BodePoint bp = firstOrderPole(omega, omegaC);
System.out.printf("omega=%.3f, |G| dB=%.3f, phase=%.3f deg%n",
bp.omega, bp.magDb, bp.phaseDeg);
}
System.out.println("\nSecond-order pole:");
for (double omega : omegas) {
BodePoint bp = secondOrderPole(omega, omegaN, zeta);
System.out.printf("omega=%.3f, |G| dB=%.3f, phase=%.3f deg%n",
bp.omega, bp.magDb, bp.phaseDeg);
}
}
}
This numerical computation mirrors the analytical formulas and enables easy integration in Java-based control design tools or simulation environments for mechatronic systems.
10. MATLAB/Simulink Implementation
MATLAB and Simulink are standard tools for control and robotics. The following script constructs first- and second-order factors, plots Bode diagrams, and can be connected to Simulink plants (e.g., rigid-body joint models from the Robotics System Toolbox).
% First-order pole and zero
omega_c = 10; % rad/s
omega_z = 5; % rad/s
s = tf('s');
G_p = 1 / (1 + s/omega_c); % first-order pole
G_z = 1 + s/omega_z; % first-order zero
% Second-order factor (e.g. joint speed dynamics)
omega_n = 20;
zeta = 0.4;
G_2 = omega_n^2 / (s^2 + 2*zeta*omega_n*s + omega_n^2);
G_total = G_p * G_2;
w = logspace(-1, 3, 500);
figure;
bode(G_p, w);
grid on;
title('First-order pole');
figure;
bode(G_2, w);
grid on;
title('Second-order factor');
figure;
bode(G_total, w);
grid on;
title('Combined first- and second-order plant');
% In Simulink, one can linearize a robot joint model and call bode on the
% resulting linearized plant to inspect first- and second-order behavior.
In Simulink, the Linear Analysis Tool can extract a linear model of a nonlinear robotic manipulator about an operating point; this linear model will typically exhibit dominant second-order factors corresponding to joint inertias and damping.
11. Wolfram Mathematica Implementation
Wolfram Mathematica provides symbolic and numeric tools for transfer
functions and Bode plots. The following code builds the standard factors
and uses BodePlot.
(* First-order and second-order factors *)
omegaC = 10.0;
omegaZ = 5.0;
omegaN = 20.0;
zeta = 0.3;
s = I*ω (* symbolic frequency variable for frequency response *);
Gpole[s_] := 1/(1 + s/omegaC);
Gzero[s_] := 1 + s/omegaZ;
G2nd[s_] := omegaN^2/(s^2 + 2*zeta*omegaN*s + omegaN^2);
Gtotal[s_] := Gpole[s]*G2nd[s];
(* Frequency range *)
wmin = 0.1;
wmax = 1000;
BodePlot[
{Gpole[I*ω], G2nd[I*ω], Gtotal[I*ω]},
{ω, wmin, wmax},
PlotLayout -> {"Magnitude", "Phase"},
PlotLegends -> {"First-order pole", "Second-order", "Combined"}
]
Mathematica can also be used to symbolically manipulate magnitude and phase expressions, for example to derive resonance conditions or solve for frequencies at which the magnitude equals a specified dB level.
12. Problems and Solutions
Problem 1 (First-Order Pole: Exact vs Asymptotic Magnitude): Consider the first-order pole \( G_p(s) = \tfrac{1}{1 + \tfrac{s}{10}} \). Compute the exact magnitude in dB at \( \omega = 1 \,\text{rad/s} \), \( 10 \,\text{rad/s} \), and \( 100 \,\text{rad/s} \), and compare with the standard asymptotic Bode approximation.
Solution:
The magnitude is
\[ \lvert G_p(j\omega)\rvert_{\text{dB}} = -10\log_{10}\!\left(1 + \left(\tfrac{\omega}{10}\right)^2\right). \]
- \( \omega = 1 \): \( \tfrac{\omega}{10} = 0.1 \), \( 1 + 0.1^2 = 1.01 \), so \( \lvert G_p(j1)\rvert_{\text{dB}} \approx -10\log_{10}(1.01) \approx -0.043 \,\text{dB} \). The asymptote is 0 dB; the error is negligible.
- \( \omega = 10 \): \( \tfrac{\omega}{10} = 1 \), \( 1 + 1^2 = 2 \), \( \lvert G_p(j10)\rvert_{\text{dB}} = -10\log_{10} 2 \approx -3.01 \,\text{dB} \). The asymptote jumps from 0 dB to a straight line of slope \( -20\,\text{dB/decade} \), intersecting at this frequency at \( -3\,\text{dB} \); exact and asymptotic coincide here.
- \( \omega = 100 \): \( \tfrac{\omega}{10} = 10 \), \( 1 + 10^2 = 101 \), \( \lvert G_p(j100)\rvert_{\text{dB}} = -10\log_{10}(101) \approx -20.0 \,\text{dB} \). The asymptotic line predicts starting at \( -3 \,\text{dB} \) at \( \omega = 10 \) and decreasing with \( -20\,\text{dB/decade} \), giving \( -3 - 20 = -23 \,\text{dB} \). Thus the asymptotic approximation has an error of about 3 dB at one decade above the corner.
Problem 2 (Integrator vs First-Order Pole at Low Frequency): Let \( G_I(s) = \tfrac{1}{s} \) and \( G_p(s) = \tfrac{1}{1 + \tfrac{s}{\omega_c}} \) with \( \omega_c = 10 \,\text{rad/s} \). For \( \omega = 0.1 \,\text{rad/s} \), compare the magnitudes in dB and explain which factor dominates a feedback loop sensitivity at low frequency.
Solution:
For the integrator:
\[ \lvert G_I(j\omega)\rvert = \frac{1}{\omega} \Rightarrow \lvert G_I(j0.1)\rvert = 10, \quad 20\log_{10} 10 = 20\,\text{dB}. \]
For the first-order pole at \( \omega = 0.1 \):
\[ \lvert G_p(j0.1)\rvert = \frac{1}{\sqrt{1 + (0.1/10)^2}} = \frac{1}{\sqrt{1 + 0.0001}} \approx 0.99995, \quad \lvert G_p(j0.1)\rvert_{\text{dB}} \approx 0\,\text{dB}. \]
Thus, at low frequencies the integrator dominates the loop gain with a high magnitude (20 dB here), while the first-order pole behaves approximately as a constant gain. This explains why integrators are effective in reducing steady-state error but also increase low-frequency loop gain.
Problem 3 (Resonant Peak of Second-Order Pole): Consider a second-order factor \( G_2(s) = \tfrac{\omega_n^2}{s^2 + 2\zeta\omega_n s + \omega_n^2} \) with \( \zeta = 0.2 \). Determine the resonant peak magnitude \( M_r \) (in dB) using the standard approximation and comment on its physical significance.
Solution:
For \( \zeta < \tfrac{1}{\sqrt{2}} \), the resonant peak is approximately
\[ M_r = \frac{1}{2\zeta\sqrt{1 - \zeta^2}}. \]
For \( \zeta = 0.2 \),
\[ 1 - \zeta^2 = 1 - 0.04 = 0.96, \quad 2\zeta\sqrt{1 - \zeta^2} = 0.4\sqrt{0.96} \approx 0.4 \cdot 0.9799 \approx 0.392. \]
Thus \( M_r \approx \tfrac{1}{0.392} \approx 2.55 \). In decibels:
\[ 20\log_{10} M_r \approx 20\log_{10}(2.55) \approx 20 \cdot 0.406 \approx 8.1\,\text{dB}. \]
Physically, this means that around the resonant frequency the magnitude response amplifies disturbances and reference commands by about 8 dB. In a robot joint, such a resonance can cause overshoot and oscillatory motion unless carefully damped or compensated.
Problem 4 (Asymptotic Slope Composition): Let \( G(s) = \tfrac{K(1 + \tfrac{s}{10})}{(1 + \tfrac{s}{1})(1 + \tfrac{s}{100})} \) with \( K = 1 \). Determine the asymptotic magnitude slope (in dB/decade) for: (a) \( \omega < 1 \,\text{rad/s} \), (b) \( 1 < \omega < 10 \), (c) \( 10 < \omega < 100 \), (d) \( \omega > 100 \).
Solution:
We have one zero at \( 10 \,\text{rad/s} \) and two poles at \( 1 \,\text{rad/s} \) and \( 100 \,\text{rad/s} \). The magnitude asymptote slope is obtained by adding contributions: each zero contributes \( +20\,\text{dB/dec} \) above its corner; each pole contributes \( -20\,\text{dB/dec} \) above its corner.
- (a) \( \omega < 1 \): no pole or zero has been passed. Slope = 0 dB/decade.
- (b) \( 1 < \omega < 10 \): one pole at 1 is active (\( -20\,\text{dB/dec} \)); zero at 10 and pole at 100 are not yet active. Net slope: \( -20\,\text{dB/decade} \).
- (c) \( 10 < \omega < 100 \): pole at 1 and zero at 10 are active; their contributions cancel (\( -20 + 20 = 0\,\text{dB/dec} \)); pole at 100 is not yet active. Net slope: \( 0\,\text{dB/decade} \).
- (d) \( \omega > 100 \): both poles and the zero are active: \( -20 - 20 + 20 = -20\,\text{dB/decade} \).
Problem 5 (Second-Order Pole and Time-Domain Behavior): A second-order plant has \( \omega_n = 5\,\text{rad/s} \) and \( \zeta = 0.7 \). Use the magnitude expression to show that no resonance (peak) occurs and explain how this relates to the step response overshoot.
Solution:
The resonant peak formula requires \( \zeta < \tfrac{1}{\sqrt{2}} \approx 0.707 \) for a true peak above 0 dB. For \( \zeta = 0.7 \), this condition is nearly violated; the peak is at or below 0 dB, and the magnitude response is relatively flat near \( \omega_n \).
The magnitude is
\[ \lvert G_2(j\omega)\rvert = \frac{1}{\sqrt{\left(1 - r^2\right)^2 + (2\zeta r)^2}}, \quad r = \tfrac{\omega}{\omega_n}. \]
The denominator is never significantly smaller than 1 for \( \zeta \approx 0.7 \), so \( \lvert G_2(j\omega)\rvert \le 1 \). In the time domain, such a heavily damped second-order system exhibits small or no overshoot, consistent with the absence of a resonant peak in the Bode magnitude plot. For motion control, this corresponds to a well-damped joint with smooth response.
13. Summary
In this lesson, we decomposed rational transfer functions into first- and second-order factors and derived their exact magnitude and phase responses in the frequency domain. For first-order poles and zeros, we obtained simple asymptotic Bode approximations with slopes of \( \pm 20\,\text{dB/decade} \) and phase transitions of \( \pm 90^\circ \). For canonical second-order poles we expressed magnitude and phase as functions of the normalized frequency \( r = \tfrac{\omega}{\omega_n} \) and damping ratio \( \zeta \), revealing the conditions for resonant peaks and the characteristic phase drop to \( -180^\circ \).
We also implemented these formulas in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica, illustrating how factor-based Bode analysis is integrated into modern control and robotics toolchains. The next lessons will extend these ideas to additional factors (complex zeros, delays) and to approximate hand-sketching techniques and stability interpretation.
14. References
- Bode, H. W. (1940). Relations between attenuation and phase in feedback amplifier design. Bell System Technical Journal, 19(3), 421–454.
- Bode, H. W. (1945). Network analysis and feedback amplifier design. Van Nostrand. (Classic monograph introducing logarithmic magnitude and phase plots.)
- Nichols, N. B. (1947). Theory of servo mechanisms. Journal of the Franklin Institute, 244(1), 1–36.
- Evans, W. R. (1950). Graphical analysis of control systems. Transactions of the American Institute of Electrical Engineers, 69(1), 547–551.
- Zames, G. (1966). On the input-output stability of time-varying nonlinear feedback systems. Part I: Conditions derived using concepts of generalized gain. IEEE Transactions on Automatic Control, 11(2), 228–238.
- Horowitz, I. M. (1963). Synthesis of feedback systems. Academic Press. (Develops frequency-domain design using Bode-type shaping.)
- Åström, K. J., & Hägglund, T. (1984). Automatic tuning of simple regulators with specifications on phase and amplitude margins. Automatica, 20(5), 645–651.
- MacFarlane, A. G. J., & Kouvaritakis, B. (1977). A unified approach to the design of robust multivariable systems using frequency response techniques. IEEE Transactions on Automatic Control, 22(1), 28–38.
- Middleton, R. H., & Goodwin, G. C. (1988). Digital control and estimation: A unified approach. Prentice-Hall.
- Skogestad, S., & Postlethwaite, I. (1996). Multivariable feedback control: Analysis and design. Wiley.