Chapter 24: Robustness Analysis with Classical Tools

Lesson 3: Nichols- and Bode-Based Robustness Interpretation

In this lesson we connect robustness concepts (sensitivity peaks, gain/phase margins, and multiplicative uncertainty) with graphical interpretations on Bode and Nichols plots. We derive quantitative relations between phase margin and maximum sensitivity, interpret constant-sensitivity contours in the Nichols plane, and show how simple uncertainty models lead to frequency-domain robustness tests. Finally, we implement these ideas in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica with a focus on robot joint servo loops.

1. Loop Transfer Function, Sensitivity, and Frequency Representations

For a standard unity-feedback loop with plant \( P(s) \) and controller \( C(s) \), the loop transfer function is

\[ L(s) = C(s)P(s), \quad S(s) = \frac{1}{1 + L(s)}, \quad T(s) = \frac{L(s)}{1 + L(s)}. \]

The functions \( S \) and \( T \) are the sensitivity and complementary sensitivity. As introduced in Chapter 22, \( S \) governs disturbance sensitivity and parameter variations at the plant input, while \( T \) shapes reference tracking and sensor noise amplification.

In the frequency domain, we evaluate \( L(j\omega) \), \( S(j\omega) \), and \( T(j\omega) \). Two important graphical views are:

  • Bode plot: magnitude (often in dB) and phase of \( L(j\omega) \) versus frequency on logarithmic axes.
  • Nichols plot: phase of \( L(j\omega) \) (horizontal axis, degrees) versus magnitude in dB (vertical axis).

Because both Bode and Nichols plots represent the same complex values \( L(j\omega) \), robustness properties can be read from either representation. Nichols plots are particularly convenient because loci of constant closed-loop gain and constant sensitivity become simple curves over the phase–gain plane.

flowchart TD
  A["Start from P(s), C(s)"] --> B["Form L(s) = C(s)P(s)"]
  B --> C["Compute L(jw) on frequency grid"]
  C --> D["Bode: mag(w), phase(w)"]
  C --> E["Nichols: phase(w) vs 20log10|L(jw)|"]
  D --> F["Read gain/phase margins"]
  E --> G["Overlay constant S and T contours"]
  F --> H["Infer classical robustness"]
  G --> H
        

2. Sensitivity, Maximum Sensitivity, and Distance to the Critical Point

Let \( L(j\omega) \) be the loop frequency response. From the definition of sensitivity,

\[ S(j\omega) = \frac{1}{1 + L(j\omega)}. \]

Taking magnitudes,

\[ \bigl|S(j\omega)\bigr| = \frac{1}{\bigl|1 + L(j\omega)\bigr|}. \]

In the Nyquist plane, \( 1 + L(j\omega) \) is the vector from the point \( -1 \) to \( L(j\omega) \), so \( \bigl|1 + L(j\omega)\bigr| \) is exactly the distance from the Nyquist curve to the critical point \( -1 \). Therefore,

\[ \bigl|S(j\omega)\bigr| = \frac{1}{\text{dist}\bigl(L(j\omega), -1\bigr)}. \]

The maximum sensitivity (defined in Chapter 22) is

\[ M_S = \sup_{\omega \in \mathbb{R}} \bigl|S(j\omega)\bigr|. \]

A bound \( M_S \leq M_S^{\star} \) is equivalent to a minimum distance between the Nyquist (or Nichols) locus and \( -1 \):

\[ \bigl|S(j\omega)\bigr| \leq M_S^{\star} \;\forall \omega \quad \Longleftrightarrow \quad \bigl|1 + L(j\omega)\bigr| \geq \frac{1}{M_S^{\star}} \;\forall \omega. \]

In the Nyquist plane this corresponds to the Nyquist curve lying outside a circle centred at \( -1 \) with radius \( 1/M_S^{\star} \). In the Nichols plane, this circle maps to a curve known as an \( M_S \)-contour. Demanding that the Nichols locus lies on the “safe side” of this contour directly enforces a sensitivity bound.

The complementary sensitivity function obeys

\[ \bigl|T(j\omega)\bigr| = \frac{\bigl|L(j\omega)\bigr|}{\bigl|1 + L(j\omega)\bigr|}, \quad M_T = \sup_{\omega \in \mathbb{R}} \bigl|T(j\omega)\bigr|. \]

Together, \( M_S \) and \( M_T \) provide robust stability and performance indices. Typical classical design targets are \( 1.3 \lesssim M_S \lesssim 2 \) (moderate robustness and disturbance rejection) and \( M_T \lesssim 2 \) to avoid excessive resonance.

3. Phase Margin and Maximum Sensitivity: Bode–Nichols Connection

Classical design often specifies a phase margin \( \varphi_m \) at the gain crossover frequency \( \omega_c \), where \( \bigl|L(j\omega_c)\bigr| = 1 \). For reasonably shaped loops, there is a tight relationship between \( \varphi_m \) and the maximum sensitivity \( M_S \).

At \( \omega = \omega_c \) we write \( L(j\omega_c) = e^{j\theta_c} \) with \( \theta_c = \angle L(j\omega_c) \). Then

\[ 1 + L(j\omega_c) = 1 + e^{j\theta_c}, \quad \bigl|1 + L(j\omega_c)\bigr| = \sqrt{\bigl(1 + \cos\theta_c\bigr)^2 + \sin^2\theta_c} = 2\bigl|\cos(\theta_c/2)\bigr|. \]

Hence

\[ \bigl|S(j\omega_c)\bigr| = \frac{1}{\bigl|1 + L(j\omega_c)\bigr|} = \frac{1}{2\bigl|\cos(\theta_c/2)\bigr|}. \]

The phase margin in radians is \( \varphi_m = \pi + \theta_c \), i.e. the extra phase before the loop reaches \( -\pi \). Substituting \( \theta_c = -\pi + \varphi_m \) and using trigonometric identities,

\[ \cos\left(\frac{\theta_c}{2}\right) = \cos\left(-\frac{\pi}{2} + \frac{\varphi_m}{2}\right) = \sin\left(\frac{\varphi_m}{2}\right), \]

and thus

\[ \bigl|S(j\omega_c)\bigr| = \frac{1}{2\sin\left(\varphi_m/2\right)}. \]

In many practical designs the peak of \( |S(j\omega)| \) occurs near \( \omega_c \), giving the widely used approximation

\[ M_S \approx \frac{1}{2\sin\left(\varphi_m/2\right)}. \]

This formula links a purely Bode-based quantity (phase margin) with the sensitivity peak used in robust stability analysis. On a Nichols chart, decreasing \( \varphi_m \) corresponds to moving the locus closer to the critical point at phase \( -180^\circ \) and 0 dB, thereby increasing \( M_S \) and reducing robustness.

flowchart TD
  Pm["Specify phase margin phi_m"] --> C1["At wc: |L(jw_c)| = 1"]
  C1 --> C2["Compute |S(jw_c)| = 1/(2 sin(phi_m/2))"]
  C2 --> C3["Approximate M_S ≈ |S(jw_c)|"]
  C3 --> Bode["Check on Bode: S peak"]
  C3 --> Nichols["Check on Nichols: distance to (-180 deg, 0 dB)"]
        

4. Multiplicative Uncertainty and Bode/Nichols Robustness Tests

Consider an output multiplicative uncertainty model introduced in Chapter 23:

\[ P(s) = P_0(s)\bigl(1 + W_2(s)\Delta_2(s)\bigr), \quad \bigl|\Delta_2(j\omega)\bigr| \leq 1. \]

Here \( P_0(s) \) is the nominal plant, \( W_2(s) \) shapes the frequency dependence of the uncertainty, and \( \Delta_2(s) \) is any stable perturbation bounded in magnitude. With a fixed controller \( C(s) \), the nominal complementary sensitivity is \( T_0(s) = L_0(s)/(1 + L_0(s)) \) with \( L_0(s) = C(s)P_0(s) \).

The perturbed closed loop can be redrawn as a unity-feedback interconnection between \( T_0(s)W_2(s) \) and \( \Delta_2(s) \). The small-gain theorem states that this interconnection is internally stable for all \( \Delta_2 \) satisfying the bound if

\[ \sup_{\omega \in \mathbb{R}} \bigl|W_2(j\omega)T_0(j\omega)\bigr| < 1. \]

This yields a simple robust stability test:

  • Choose or identify a weight \( W_2(s) \) that upper-bounds the relative modeling error.
  • Compute \( W_2(j\omega)T_0(j\omega) \) over frequency.
  • Verify that its magnitude stays below 0 dB on a Bode plot, or equivalently that the Nichols locus of \( L_0 \) stays outside the corresponding “forbidden” contour defined by \( |W_2 T_0| = 1 \).

Analogous tests exist for input multiplicative uncertainty, where \( W_1(s) \) shapes uncertainty in the controller or actuator, and the loop \( C(s)S(s) \) appears in the small-gain condition. In all cases, Bode plots visualize the inequality \( \bigl|W(j\omega)F(j\omega)\bigr| < 1 \) as a magnitude bound, while Nichols plots encode the same constraint as a region in the phase–gain plane.

5. Python Implementation – Nichols/Bode Robustness for a Robot Joint

We illustrate the above concepts for a simplified robot revolute joint driven by a motor, modeled as

\[ P(s) = \frac{K}{Js^2 + Bs}, \]

where \( J \) is the reflected inertia, \( B \) the viscous damping, and \( K \) the torque constant scaled by amplifier gain. A PI controller with lead shaping is

\[ C(s) = k_p\left(1 + \frac{1}{T_i s}\right)\frac{T_l s + 1}{\alpha T_l s + 1}. \]

Using python-control and the roboticstoolbox package (for broader robot models), we can compute Bode and Nichols plots, and evaluate \( M_S \) and the multiplicative uncertainty test.


import numpy as np
import control
from control.matlab import tf, bode, nichols

# Optional robotics models (not strictly needed for this example)
# from roboticstoolbox import models as rtb_models

# Robot joint approximated as P(s) = K / (J s^2 + B s)
J = 0.02   # kg m^2 (effective inertia)
B = 0.1    # N m s/rad (viscous friction)
K = 1.0    # N m / V (torque constant * amplifier gain)

s = control.TransferFunction.s
P = K / (J * s**2 + B * s)

# PI + lead controller
kp = 50.0
Ti = 0.1
Tl = 0.02
alpha = 0.2

C = kp * (1 + 1 / (Ti * s)) * ((Tl * s + 1) / (alpha * Tl * s + 1))

L = C * P
S = 1 / (1 + L)
T = L / (1 + L)

# Frequency grid
w = np.logspace(-1, 3, 600)

# Compute sensitivity peak M_S
magS, phaseS, wS = control.bode(S, w, Plot=False)
MS = np.max(magS)
print(f"Maximum sensitivity M_S ≈ {MS:.2f}")

# Simple multiplicative output uncertainty weight
# Example: about 20% error above 50 rad/s
W2 = 0.2 * (s / 50 + 1) / (s / 500 + 1)

magWT, phaseWT, wWT = control.bode(W2 * T, w, Plot=False)
robust_index = np.max(magWT)
print(f"max |W2(jw) T(jw)| ≈ {robust_index:.2f}")

if robust_index < 1.0:
    print("Small-gain condition satisfied: robustly stable for the modeled output uncertainty.")
else:
    print("Robust stability not guaranteed for the chosen W2.")

# Plot Bode and Nichols for inspection
control.bode(L, w)
control.nichols(L, w)
      

In a robotics workflow, the joint dynamics \( P(s) \) can be extracted from a roboticstoolbox rigid-body model or from identified frequency-response data of a joint under torque excitation, and then analyzed as above to tune the servo gains for robust performance.

6. C++ Implementation – Robustness Evaluation for Servo Control

In C++, low-level robot servo loops are often implemented in real-time frameworks such as ROS control or Orocos, using Eigen for linear algebra. Below is a minimal illustration computing \( M_S \) and the small-gain robustness index \( \sup_{\omega} |W_2 T| \) for a SISO joint model.


#include <iostream>
#include <complex>
#include <vector>
#include <cmath>

int main() {
    using std::complex;
    using std::vector;

    const double J = 0.02;
    const double B = 0.1;
    const double K = 1.0;

    const double kp = 50.0;
    const double Ti = 0.1;
    const double Tl = 0.02;
    const double alpha = 0.2;

    const complex<double> j(0.0, 1.0);

    auto P = [&] (double w) {
        complex<double> s = j * w;
        return K / (J * s * s + B * s);
    };

    auto C = [&] (double w) {
        complex<double> s = j * w;
        complex<double> pi = (1.0 + 1.0 / (Ti * s));
        complex<double> lead = (Tl * s + 1.0) / (alpha * Tl * s + 1.0);
        return kp * pi * lead;
    };

    auto W2 = [&] (double w) {
        complex<double> s = j * w;
        return 0.2 * (s / 50.0 + 1.0) / (s / 500.0 + 1.0);
    };

    // Logarithmic frequency grid
    vector<double> w;
    for (int k = 0; k <= 600; ++k) {
        double exponent = -1.0 + 4.0 * static_cast<double>(k) / 600.0;
        w.push_back(std::pow(10.0, exponent));
    }

    double MS = 0.0;
    double robust_index = 0.0;

    for (std::size_t k = 0; k < w.size(); ++k) {
        double wk = w[k];
        complex<double> L = C(wk) * P(wk);
        complex<double> S = 1.0 / (1.0 + L);
        complex<double> T = L / (1.0 + L);

        double magS = std::abs(S);
        double magWT = std::abs(W2(wk) * T);

        if (magS > MS) {
            MS = magS;
        }
        if (magWT > robust_index) {
            robust_index = magWT;
        }
    }

    std::cout << "Maximum sensitivity M_S ≈ " << MS << std::endl;
    std::cout << "max |W2(jw) T(jw)| ≈ " << robust_index << std::endl;

    if (robust_index < 1.0) {
        std::cout << "Small-gain robust stability condition satisfied." << std::endl;
    } else {
        std::cout << "Robust stability not guaranteed." << std::endl;
    }

    return 0;
}
      

In a ROS-based robot controller, such a computation can be integrated offline into tuning tools that evaluate robustness for each joint using its identified dynamics and controller parameters, leveraging Eigen for multi-joint MIMO generalizations.

7. Java Implementation – Bode-Based Robustness Indicators

Java is frequently used in educational and competition robotics (e.g., FRC robots via WPILib). Here we sketch a Java program using Apache Commons Math to compute a simple robustness index from sampled frequency response data of a position loop.


import org.apache.commons.math3.complex.Complex;
import java.util.ArrayList;
import java.util.List;

public class NicholsRobustness {
    public static void main(String[] args) {
        double J = 0.02;
        double B = 0.1;
        double K = 1.0;

        double kp = 50.0;
        double Ti = 0.1;
        double Tl = 0.02;
        double alpha = 0.2;

        Complex j = new Complex(0.0, 1.0);

        List<Double> w = new ArrayList<>();
        int N = 600;
        for (int k = 0; k <= N; ++k) {
            double exponent = -1.0 + 4.0 * (double) k / (double) N;
            w.add(Math.pow(10.0, exponent));
        }

        double MS = 0.0;
        double robustIndex = 0.0;

        for (double wk : w) {
            Complex s = j.multiply(wk);

            Complex P = new Complex(K, 0.0).divide(
                    s.multiply(s).multiply(J).add(s.multiply(B))
            );

            Complex pi = new Complex(1.0, 0.0).add(
                    new Complex(1.0, 0.0).divide(s.multiply(Ti))
            );

            Complex lead = s.multiply(Tl).add(1.0)
                    .divide(s.multiply(alpha * Tl).add(1.0));

            Complex C = pi.multiply(lead).multiply(kp);

            Complex L = C.multiply(P);
            Complex S = new Complex(1.0, 0.0).divide(
                    new Complex(1.0, 0.0).add(L)
            );
            Complex T = L.divide(
                    new Complex(1.0, 0.0).add(L)
            );

            Complex W2 = (s.divide(50.0).add(1.0))
                    .divide(s.divide(500.0).add(1.0))
                    .multiply(0.2);

            double magS = S.abs();
            double magWT = W2.multiply(T).abs();

            if (magS > MS) {
                MS = magS;
            }
            if (magWT > robustIndex) {
                robustIndex = magWT;
            }
        }

        System.out.printf("Maximum sensitivity M_S ≈ %.2f%n", MS);
        System.out.printf("max |W2(jw) T(jw)| ≈ %.2f%n", robustIndex);
        if (robustIndex < 1.0) {
            System.out.println("Small-gain robust stability condition satisfied.");
        } else {
            System.out.println("Robust stability not guaranteed.");
        }
    }
}
      

In a robot control stack written in Java (e.g., using WPILib), such robustness checks can be coupled with plant models derived from system identification of drivetrain or arm subsystems.

8. MATLAB/Simulink and Wolfram Mathematica Implementations

MATLAB with Control System Toolbox and Robotics System Toolbox is the de facto environment for many industrial robot controllers. The following script computes robustness indices and visualizes Bode and Nichols plots for the same joint servo model.


% Robot joint parameters
J = 0.02;
B = 0.1;
K = 1.0;

s = tf('s');
P = K / (J * s^2 + B * s);

kp = 50;
Ti = 0.1;
Tl = 0.02;
alpha = 0.2;

C = kp * (1 + 1/(Ti*s)) * ((Tl*s + 1)/(alpha*Tl*s + 1));

L = C * P;
S = feedback(1, L);     % S = 1/(1+L)
T = feedback(L, 1);     % T = L/(1+L)

% Uncertainty weight
W2 = 0.2 * (s/50 + 1) / (s/500 + 1);

w = logspace(-1, 3, 600);

[magS, ~, ~] = bode(S, w);
MS = max(squeeze(magS));

[magWT, ~, ~] = bode(W2 * T, w);
robustIndex = max(squeeze(magWT));

fprintf('Maximum sensitivity M_S ≈ %.2f\n', MS);
fprintf('max |W2(jw) T(jw)| ≈ %.2f\n', robustIndex);

figure; bodemag(L, S, T, w); grid on;
legend('L','S','T');

figure; nichols(L, w); grid on;

% In Simulink, the same loop can be realized with Transfer Fcn blocks
% and PID Controller blocks, and robustness evaluated via linearization
% (linmod / linearize) around operating points of a Robotics System Toolbox
% manipulator model.
      

In Wolfram Mathematica, analogous computations can be carried out with transfer-function models and parametric plots, even when a dedicated Nichols-plot function is not available:


s = I*ω;

J = 0.02;
B = 0.1;
K = 1.0;

P[ω_] := K/(J*s^2 + B*s);

kp = 50.;
Ti = 0.1;
Tl = 0.02;
α = 0.2;

C[ω_] := kp*(1 + 1/(Ti*s))*((Tl*s + 1)/(α*Tl*s + 1));

L[ω_] := C[ω]*P[ω];
S[ω_] := 1/(1 + L[ω]);
T[ω_] := L[ω]/(1 + L[ω]);

W2[ω_] := 0.2*(s/50 + 1)/(s/500 + 1);

ωrange = LogRange[10^-1, 10^3, 600];

MS = Max[Abs[S /@ ωrange]];
robustIndex = Max[Abs[W2[#]*T[#]] & /@ ωrange];

Print["Maximum sensitivity M_S ≈ ", MS];
Print["max |W2(jw) T(jw)| ≈ ", robustIndex];

(* Nichols-like plot: phase vs magnitude of L(jω) *)
ParametricPlot[
  {
    Arg[L[ω]]*180/Pi,
    20*Log10[Abs[L[ω]]]
  },
  {ω, 10^-1, 10^3},
  AxesLabel -> {"phase (deg)", "mag (dB)"}
]
      

For robot manipulators modeled symbolically in Mathematica, joint-space linearizations around nominal trajectories can be mapped to SISO or low-order MIMO loops and analyzed using the same Bode- and Nichols-based robustness measures.

9. Problems and Solutions

Problem 1 (Phase Margin and Maximum Sensitivity): Consider a unity-feedback SISO system with loop transfer function \( L(s) \). Assume that \( \bigl|L(j\omega_c)\bigr| = 1 \) at the gain crossover frequency \( \omega_c \), and that the Nyquist curve is approximately straight in a neighborhood of \( \omega_c \). Show that

\[ \bigl|S(j\omega_c)\bigr| = \frac{1}{2\sin\left(\varphi_m/2\right)}, \]

where \( \varphi_m \) is the phase margin (in radians), and conclude that \( M_S \approx 1/\bigl(2\sin(\varphi_m/2)\bigr) \).

Solution: At \( \omega_c \), write \( L(j\omega_c) = e^{j\theta_c} \) with \( |L(j\omega_c)| = 1 \). Then

\[ 1 + L(j\omega_c) = 1 + e^{j\theta_c}, \quad \bigl|1 + L(j\omega_c)\bigr| = 2\bigl|\cos(\theta_c/2)\bigr|. \]

The phase margin is \( \varphi_m = \pi + \theta_c \), so \( \theta_c = -\pi + \varphi_m \). Using the identity \( \cos(-\pi/2 + x) = \sin x \) we obtain

\[ \cos\left(\frac{\theta_c}{2}\right) = \cos\left(-\frac{\pi}{2} + \frac{\varphi_m}{2}\right) = \sin\left(\frac{\varphi_m}{2}\right). \]

Thus

\[ \bigl|S(j\omega_c)\bigr| = \frac{1}{\bigl|1 + L(j\omega_c)\bigr|} = \frac{1}{2\sin\left(\varphi_m/2\right)}. \]

If the sensitivity peak occurs near \( \omega_c \) (which is typical for smooth loop-shapes), then \( M_S \approx \bigl|S(j\omega_c)\bigr| \), giving the asserted approximation.

Problem 2 (Nyquist Circle and Sensitivity Bound): Let \( M_S^{\star} > 1 \). Prove that the condition \( \bigl|S(j\omega)\bigr| \leq M_S^{\star} \) for all \( \omega \) holds if and only if the Nyquist curve of \( L(j\omega) \) lies outside the circle centred at \( -1 \) with radius \( 1/M_S^{\star} \).

Solution: The sensitivity bound is equivalent to

\[ \bigl|S(j\omega)\bigr| \leq M_S^{\star} \quad \Longleftrightarrow \quad \frac{1}{\bigl|1 + L(j\omega)\bigr|} \leq M_S^{\star} \quad \Longleftrightarrow \quad \bigl|1 + L(j\omega)\bigr| \geq \frac{1}{M_S^{\star}}. \]

As remarked earlier, \( \bigl|1 + L(j\omega)\bigr| \) is the Euclidean distance from \( L(j\omega) \) to \( -1 \) in the complex plane. Thus the inequality states that every point of the Nyquist curve must lie at distance at least \( 1/M_S^{\star} \) from \( -1 \), i.e. outside the closed disk of that radius. This disk is exactly the claimed circle region.

Problem 3 (Small-Gain Robust Stability with Output Uncertainty): Suppose \( W_2(s) \) has magnitude \( \bigl|W_2(j\omega)\bigr| \leq 0.3 \) for all \( \omega \), representing at most 30% multiplicative output uncertainty. A controller is designed such that the complementary sensitivity satisfies \( \bigl|T_0(j\omega)\bigr| \leq 2 \) for all \( \omega \). Use the small-gain condition to determine whether robust stability is guaranteed.

Solution: The robust stability test for output multiplicative uncertainty is

\[ \sup_{\omega} \bigl|W_2(j\omega)T_0(j\omega)\bigr| < 1. \]

The given bounds imply \( \bigl|W_2(j\omega)T_0(j\omega)\bigr| \leq 0.3 \times 2 = 0.6 \) for all \( \omega \), so

\[ \sup_{\omega} \bigl|W_2(j\omega)T_0(j\omega)\bigr| \leq 0.6 < 1, \]

and the closed loop is robustly stable for all admissible uncertainties.

Problem 4 (Bode vs Nichols Interpretation): Two controllers \( C_1 \) and \( C_2 \) are designed for the same plant. On the Bode plot of \( L_1 = C_1P \), the phase margin is \( 30^\circ \), while for \( L_2 = C_2P \) it is \( 60^\circ \). Assuming similar loop shapes and crossover frequencies, compare the approximate maximum sensitivities \( M_S^{(1)} \) and \( M_S^{(2)} \).

Solution: Using the approximation \( M_S \approx 1/\bigl(2\sin(\varphi_m/2)\bigr) \), we have in radians: \( \varphi_m^{(1)} = 30^\circ = \pi/6 \) and \( \varphi_m^{(2)} = 60^\circ = \pi/3 \). Therefore

\[ M_S^{(1)} \approx \frac{1}{2\sin(\pi/12)}, \quad M_S^{(2)} \approx \frac{1}{2\sin(\pi/6)} = \frac{1}{2 \cdot 1/2} = 1. \]

Numerically, \( \sin(\pi/12) \approx 0.2588 \), so \( M_S^{(1)} \approx 1/(2 \times 0.2588) \approx 1.93 \), while \( M_S^{(2)} \approx 1 \). Thus \( C_2 \) yields a substantially smaller sensitivity peak and is more robust to plant uncertainty, consistent with its larger phase margin in both Bode and Nichols interpretations.

Problem 5 (Reading Uncertainty Tests from Nichols Plot): Suppose the Nichols chart displays contours where the magnitude of \( W_2(j\omega)T_0(j\omega) \) equals 0 dB (unity). The Nichols locus of \( L_0 \) lies entirely below these contours. Explain what this implies for robust stability with respect to \( W_2 \) and how you would confirm this on a Bode plot.

Solution: The contours where \( |W_2(j\omega)T_0(j\omega)| = 1 \) (0 dB) delimit the boundary of the small-gain condition. If the Nichols locus of \( L_0 \) is entirely on the side of the chart where \( |W_2 T_0| < 1 \), then

\[ \sup_{\omega} \bigl|W_2(j\omega)T_0(j\omega)\bigr| < 1, \]

and robust stability follows. On a Bode plot of \( W_2T_0 \), the same condition is verified by checking that the magnitude curve remains below 0 dB across all frequencies.

10. Summary

In this lesson we connected classical robustness measures to the geometry of Bode and Nichols plots. Starting from \( S = 1/(1 + L) \) and \( T = L/(1 + L) \), we showed how sensitivity peaks correspond to distance from the critical point \( -1 \), and how phase margin determines \( M_S \) via \( M_S \approx 1/\bigl(2\sin(\varphi_m/2)\bigr) \). We then applied the small-gain theorem to multiplicative uncertainty, deriving the robust stability condition \( \sup_{\omega} |W_2(j\omega)T_0(j\omega)| < 1 \) and interpreting it on both Bode and Nichols charts. Finally, we implemented these ideas in Python, C++, Java, MATLAB/Simulink, and Mathematica with a robotics-oriented servo example. These constructions prepare us for the treatment of time-delay uncertainty and the limitations of classical robustness indicators in subsequent lessons.

11. References

  1. Bode, H. W. (1945). Network Analysis and Feedback Amplifier Design. Van Nostrand.
  2. Nyquist, H. (1932). Regeneration theory. Bell System Technical Journal, 11(1), 126–147.
  3. Nichols, N. B. (1947). Theory of servo-mechanisms. Technical Reports of the Radiation Laboratory, MIT, Vol. 25.
  4. Zames, G. (1966). On the input-output stability of time-varying nonlinear feedback systems. IEEE Transactions on Automatic Control, 11(2), 228–238.
  5. Astrom, K. J., & Hagglund, T. (1984). Automatic tuning of simple regulators with specifications on phase and amplitude margins. Automatica, 20(5), 645–651.
  6. Doyle, J. C., Wall, J. E., & Stein, G. (1982). Performance and robustness analysis for structured uncertainty. Proceedings of the 21st IEEE Conference on Decision and Control, 629–636.
  7. MacFarlane, A. G. J., & Kouvaritakis, B. (1977). A modern perspective on classical frequency-response methods. International Journal of Control, 25(2), 177–236.
  8. Skogestad, S., & Postlethwaite, I. (1996). Multivariable Feedback Control: Analysis and Design. Wiley.
  9. Francis, B. A. (1987). A Course in H∞ Control Theory. Springer.
  10. Safonov, M. G. (1980). Stability and robustness of multivariable feedback systems. MIT Press.