Chapter 16: Nichols Chart and Classical Design

Lesson 2: M and N Circles and Closed-Loop Response Interpretation

In this lesson we develop the mathematical structure of Hall circles (M- and N-circles) and show how they allow us to infer the closed-loop frequency response directly from the open-loop Nichols plot of a unity-feedback system. We derive the circle equations in the complex plane, connect them to the gain–phase Nichols coordinates, and then implement numerical computations in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica, with a viewpoint oriented toward robotic servo loops.

1. Closed-Loop Response from Open-Loop Frequency Data

Consider the standard unity-feedback loop with open-loop transfer function \( G(s) \). The closed-loop transfer function from reference input to output is

\[ T(s) = \frac{G(s)}{1 + G(s)} . \]

At steady-state sinusoidal excitation with angular frequency \( \omega \), we evaluate the loop at \( s = j\omega \) and define \( L(j\omega) = G(j\omega) \). Write \( L(j\omega) \) in polar form \( L(j\omega) = L(\omega)e^{j\phi(\omega)} \), where \( L(\omega) = |L(j\omega)| \) and \( \phi(\omega) = \arg L(j\omega) \). Then

\[ T(j\omega) = \frac{L(\omega)e^{j\phi(\omega)}}{1 + L(\omega)e^{j\phi(\omega)}}. \]

Define the closed-loop magnitude \( M(\omega) = |T(j\omega)| \) and phase \( \psi(\omega) = \arg T(j\omega) \). Using complex arithmetic we obtain

\[ M(\omega) = \frac{L(\omega)}{\left| 1 + L(\omega)e^{j\phi(\omega)} \right|} = \frac{L(\omega)} {\sqrt{1 + L(\omega)^2 + 2L(\omega)\cos\phi(\omega)}} , \]

\[ \psi(\omega) = \phi(\omega) - \arctan\!\left( \frac{L(\omega)\sin\phi(\omega)} {1 + L(\omega)\cos\phi(\omega)} \right). \]

On the Nichols chart we plot open-loop points \( (\phi(\omega),\,L_{\text{dB}}(\omega)) \) with \( L_{\text{dB}}(\omega) = 20\log_{10} L(\omega) \). M- and N-contours are precomputed loci of constant \( M(\omega) \) and \( \psi(\omega) \) in this gain–phase plane, allowing us to read the closed-loop response directly from the open-loop Nichols curve.

2. M-Circles in the \( G \)-Plane (Constant Closed-Loop Magnitude)

Let \( z = L(j\omega) = x + jy \) denote the open-loop point in the complex plane. For a given frequency, the closed-loop magnitude is

\[ M = |T(j\omega)| = \frac{|z|}{|1 + z|} . \]

An M-circle is the locus of all points \( z \) such that this magnitude equals a prescribed constant \( M > 0 \). We show that each such locus is a circle.

2.1 Algebraic derivation

Write explicitly

\[ |z|^2 = x^2 + y^2, \qquad |1+z|^2 = (1+x)^2 + y^2. \]

The condition \( |z| = M|1+z| \) implies

\[ x^2 + y^2 = M^2\bigl((1+x)^2 + y^2\bigr) = M^2(x^2 + 2x + 1 + y^2). \]

Collect terms:

\[ (1 - M^2)x^2 + (1 - M^2)y^2 - 2M^2 x - M^2 = 0. \]

For \( M \neq 1 \), divide by \( 1 - M^2 \) (note that this changes sign depending on whether \( M > 1 \) or \( 0 < M < 1 \)):

\[ x^2 + y^2 + \frac{2M^2}{M^2 - 1}x + \frac{M^2}{M^2 - 1} = 0. \]

Complete the square in \( x \):

\[ \begin{aligned} x^2 + \frac{2M^2}{M^2 - 1}x &= \left( x + \frac{M^2}{M^2 - 1} \right)^2 - \frac{M^4}{(M^2 - 1)^2},\\[4pt] \Rightarrow\quad \left( x + \frac{M^2}{M^2 - 1} \right)^2 + y^2 &= \frac{M^4}{(M^2 - 1)^2} - \frac{M^2}{M^2 - 1}. \end{aligned} \]

Bring to a common denominator \( (M^2 - 1)^2 \):

\[ \frac{M^4 - M^2(M^2 - 1)}{(M^2 - 1)^2} = \frac{M^2}{(M^2 - 1)^2}. \]

Hence, for \( M \neq 1 \) we obtain the circle equation

\[ \left( x + \frac{M^2}{M^2 - 1} \right)^2 + y^2 = \frac{M^2}{(M^2 - 1)^2}. \]

That is, the M-circle has center \( C_M = \bigl(-\tfrac{M^2}{M^2 - 1},\,0\bigr) \) and radius \( R_M = \dfrac{M}{|M^2 - 1|} \).

2.2 The special case \( M = 1 \)

If \( M = 1 \), the defining relation \( |z| = |1+z| \) means equal distance from the points \( 0 \) and \( -1 \). The locus is the perpendicular bisector of the segment joining these points, namely the vertical line

\[ x = -\frac{1}{2}. \]

Geometrically, the M-circles are Apollonius circles for the pair of points \( 0 \) and \( -1 \), and together (for all values of \( M \)) they tessellate the complex plane with respect to the closed-loop magnitude.

3. N-Circles in the \( G \)-Plane (Constant Closed-Loop Phase)

An N-circle is the locus of points \( z = x + jy \) such that the closed-loop phase \( \psi = \arg T(j\omega) \) equals a prescribed constant \( \psi_0 \). From the expression \( T = \dfrac{z}{1+z} \) we have

\[ \psi_0 = \arg\!\left(\frac{z}{1+z}\right) = \arg z - \arg(1+z). \]

Equivalently, the complex ratio \( e^{j\psi_0}\dfrac{1+z}{z} \) must be real and positive. Thus its imaginary part must vanish:

\[ \Im\!\left\{ e^{j\psi_0}\frac{1+z}{z} \right\} = 0. \]

Let \( c = \cos\psi_0 \) and \( s = \sin\psi_0 \). Using \( e^{j\psi_0} = c + js \) and \( z = x + jy \), we compute

\[ \frac{1+z}{z} = \frac{1}{z} + 1 = \frac{x - jy}{x^2 + y^2} + 1. \]

Multiplying by \( e^{j\psi_0} \) and extracting the imaginary part simplifies (after straightforward algebra) to

\[ \Im\!\left\{ e^{j\psi_0}\frac{1+z}{z} \right\} = \frac{-c\,y + s\,(x^2 + x + y^2)}{x^2 + y^2}. \]

The denominator is nonzero away from the origin, so the locus condition is equivalent to

\[ -c\,y + s\,(x^2 + x + y^2) = 0. \]

For \( s \neq 0 \) (\( \psi_0 \) not an integer multiple of \( \pi \)), divide by \( s \) and denote \( \cot\psi_0 = c/s \):

\[ x^2 + x + y^2 - (\cot\psi_0)\,y = 0. \]

Complete the squares in \( x \) and \( y \):

\[ \begin{aligned} x^2 + x &= \left(x + \tfrac{1}{2}\right)^2 - \tfrac{1}{4},\\[4pt] y^2 - (\cot\psi_0)y &= \left( y - \tfrac{1}{2}\cot\psi_0 \right)^2 - \tfrac{1}{4}\cot^2\psi_0. \end{aligned} \]

Substituting back, the N-circle satisfies

\[ \begin{aligned} \left(x + \tfrac{1}{2}\right)^2 + \left( y - \tfrac{1}{2}\cot\psi_0 \right)^2 &= \tfrac{1}{4} + \tfrac{1}{4}\cot^2\psi_0\\[4pt] &= \tfrac{1}{4}\bigl(1 + \cot^2\psi_0\bigr) = \tfrac{1}{4}\csc^2\psi_0. \end{aligned} \]

Thus each N-circle is a circle with center \( C_N = \bigl(-\tfrac{1}{2},\,\tfrac{1}{2}\cot\psi_0\bigr) \) and radius \( R_N = \tfrac{1}{2}|\csc\psi_0| \). All N-circles pass through the points \( z = 0 \) and \( z = -1 \), since both satisfy \( x^2 + x + y^2 = 0 \).

Geometrically, the angle at the point \( z \) subtended by the chord joining \( 0 \) and \( -1 \) is constant along each N-circle (an application of the inscribed angle theorem). This is precisely the constant closed-loop phase requirement.

4. From Hall Circles to Nichols Chart

The Hall circles (M- and N-circles) are defined in the complex \( G(j\omega) \)-plane. The Nichols chart is obtained by mapping each point \( z = L(j\omega) \) to its phase and log-magnitude:

\[ \phi = \arg z, \qquad L_{\text{dB}} = 20\log_{10}|z|. \]

Under this change of coordinates, each M-circle and each N-circle becomes a smooth curve in the \( (\phi, L_{\text{dB}}) \) plane. For a given open-loop frequency response \( L(j\omega) \), its Nichols locus is a curve parameterized by \( \omega \). The intersections between this locus and the transformed M- and N-contours encode the corresponding closed-loop magnitude and phase at the same frequency.

Analytically, with \( L = L(\omega) \) and \( \phi = \phi(\omega) \) known from the Nichols point, we compute

\[ M(\omega) = \frac{L}{\sqrt{1 + L^2 + 2L\cos\phi}}, \]

\[ \psi(\omega) = \phi - \arctan\!\left( \frac{L\sin\phi}{1 + L\cos\phi} \right). \]

The M- and N-contours in a standard Nichols chart are simply level sets of these two functions expressed in terms of \( L_{\text{dB}} \) and \( \phi \). Numerically, they are pre-tabulated and rendered as a dense grid of curves that the open-loop Nichols locus threads through.

5. Closed-Loop Interpretation: Resonant Peak and Bandwidth

Let \( \omega \mapsto (\phi(\omega), L_{\text{dB}}(\omega)) \) be the open-loop Nichols locus. Superimpose on it the M- and N-contours associated with the closed-loop transfer function \( T(s) = \dfrac{G(s)}{1+G(s)} \).

  • Closed-loop magnitude at a given frequency. For a point on the Nichols locus corresponding to frequency \( \omega_k \), find which M-contour passes through (or is closest to) this point. Its label (e.g. \( M = 0.8 \) or \( M_{\text{dB}} = -1.94\,\text{dB} \)) is precisely \( |T(j\omega_k)| \).
  • Closed-loop phase at a given frequency. The N-contour passing through the same point encodes \( \psi(\omega_k) \).
  • Resonant peak \( M_r \). The maximum closed-loop magnitude over all frequencies is \( M_r = \max_{\omega} |T(j\omega)| \). On the Nichols chart, this is the largest M-contour intersected by the Nichols locus.
  • Bandwidth. With low-frequency closed-loop gain normalized near \( 0\,\text{dB} \), the bandwidth is the frequency where the closed-loop magnitude crosses the \( -3\,\text{dB} \) M-contour (i.e., \( M \approx 0.707 \)).

Other classical quantities (gain margin, phase margin) can be read using the Nichols plot alone (as in the Nyquist and Bode viewpoints), but M- and N-contours augment this by providing direct access to the complete closed-loop frequency response without recomputing \( T(j\omega) \) explicitly.

6. Workflow for Using M and N Circles on Nichols Chart

The following flow summarizes how M- and N-contours are used in practice to interpret closed-loop response from open-loop data.

flowchart TD
  A["Model plant G(s) for servo (e.g. robot joint)"] --> B["Compute open-loop L(jw) = G(jw)*C(jw)"]
  B --> C["Plot Nichols curve: phase vs 20log10|L(jw)|"]
  C --> D["Overlay chart with M-contours (const |T|) and N-contours (const arg T)"]
  D --> E["For each frequency point, find intersecting M- and N-contours"]
  E --> F["Read closed-loop magnitude and phase T(jw) from contour labels"]
  F --> G["Infer Mr, bandwidth, and time-response hints for design"]
        

7. Python Implementation for a Robotic Joint Loop

Consider a simple linearized joint-position loop of a robotic arm, with open-loop transfer function

\[ G(s) = \frac{K}{s(0.1s + 1)}, \]

where the inner electrical dynamics of the motor have been reduced to a first-order lag of time constant \( 0.1 \) and \( K \) is the outer-loop proportional gain. The following Python code (using numpy and the python-control library, which is frequently used in robotics research alongside ROS) computes open-loop Nichols data and reconstructs the closed-loop magnitude/phase using the Hall-circle formula:


import numpy as np
import control as ct  # python-control toolbox

# Plant: G(s) = K / (s (0.1 s + 1))
K = 5.0
num = [K]
den = [0.1, 1.0, 0.0]
G = ct.tf(num, den)

# Unity feedback closed-loop transfer T(s) = G(s)/(1+G(s))
T = ct.feedback(G, 1)

# Frequency grid
w = np.logspace(-1, 2, 400)  # rad/s

# Open-loop frequency response L(jw)
L = ct.evalfr(G, 1j*w[0])  # just to check type
Lw = np.array([ct.evalfr(G, 1j*wi) for wi in w])

# Nichols coordinates for open-loop
phi = np.angle(Lw)          # rad
Lm = np.abs(Lw)
L_db = 20.0 * np.log10(Lm)

# Closed-loop via Hall-circle formula (from open-loop L)
Tw = Lw / (1.0 + Lw)
M = np.abs(Tw)
psi = np.angle(Tw)

# For comparison, closed-loop directly from T(s)
Tw_direct = np.array([ct.evalfr(T, 1j*wi) for wi in w])
M_direct = np.abs(Tw_direct)
psi_direct = np.angle(Tw_direct)

# Check maximum closed-loop peak Mr and its frequency
Mr = M.max()
idx_mr = np.argmax(M)
w_mr = w[idx_mr]
Mr_db = 20.0 * np.log10(Mr)

print(f"Closed-loop resonant peak Mr = {Mr:.3f} ({Mr_db:.2f} dB) at w = {w_mr:.3f} rad/s")

# Example: function mapping Nichols point to closed-loop magnitude/phase
def closed_loop_from_nichols(L_db_point, phi_point):
    L_lin = 10.0**(L_db_point / 20.0)
    # Form complex open-loop point on ray with phase phi_point
    L_point = L_lin * np.exp(1j * phi_point)
    T_point = L_point / (1.0 + L_point)
    return np.abs(T_point), np.angle(T_point)

# This function would be used if you had only Nichols coordinates, e.g. from log files.
      

In a robotics software stack, such functions can be wrapped inside ROS nodes to analyze experimental frequency responses of joint actuators and to link Nichols-based design with time-domain step performance.

8. C++ Implementation for Closed-Loop Response from Open-Loop Data

In C++, robotics code frequently relies on libraries like Eigen (for linear algebra) and runs inside a ROS node. Below is a minimal example that evaluates a second-order plant resembling a flexible joint and computes the corresponding closed-loop magnitude and phase using the Hall-circle relations:


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

// Example plant: G(s) = K / (s^2 + 2*zeta*wn*s + wn^2)
std::complex<double> G_of_jw(double K, double zeta, double wn, double w)
{
    std::complex<double> jw(0.0, w);
    std::complex<double> denom = jw * jw + 2.0 * zeta * wn * jw
                                  + std::complex<double>(wn * wn, 0.0);
    return std::complex<double>(K, 0.0) / denom;
}

int main()
{
    double K   = 10.0;
    double zeta = 0.3;
    double wn   = 5.0;

    std::vector<double> w_vec;
    for (int i = 0; i <= 400; ++i) {
        double w = std::pow(10.0, -1.0 + 3.0 * i / 400.0); // 10^-1 .. 10^2
        w_vec.push_back(w);
    }

    double Mr = 0.0;
    double w_mr = 0.0;

    for (double w : w_vec) {
        std::complex<double> L = G_of_jw(K, zeta, wn, w);
        std::complex<double> T = L / (1.0 + L);

        double M   = std::abs(T);
        double psi = std::arg(T);         // radians
        double Lm  = std::abs(L);
        double phi = std::arg(L);
        double L_db = 20.0 * std::log10(Lm);

        // Here (phi, L_db) is the Nichols point, (M, psi) is closed-loop response.
        if (M > Mr) {
            Mr   = M;
            w_mr = w;
        }

        // In a ROS node, you might publish these quantities for analysis.
    }

    double Mr_db = 20.0 * std::log10(Mr);
    std::cout << "Closed-loop peak Mr = " << Mr
              << " (" << Mr_db << " dB)"
              << " at w = " << w_mr << " rad/s\n";

    return 0;
}
      

This pattern can be integrated into a robot joint controller to evaluate how design iterations move the open-loop Nichols locus relative to desirable M-contours (e.g. limiting \( M_r \)).

9. Java Implementation for Nichols-Based Closed-Loop Analysis

For Java-based robotic systems (for example, industrial manipulators or educational robots built on top of libraries such as EJML and WPILib), one can implement similar computations using java.lang.Math and java.lang.Complex-like utilities (either from Apache Commons Math or a custom simple complex class).


// Simple complex helper class (minimal subset)
class C {
    public final double re, im;
    public C(double r, double i) { re = r; im = i; }

    public C add(C other) { return new C(re + other.re, im + other.im); }
    public C sub(C other) { return new C(re - other.re, im - other.im); }
    public C mul(C other) {
        return new C(re * other.re - im * other.im,
                     re * other.im + im * other.re);
    }
    public C div(C other) {
        double d = other.re * other.re + other.im * other.im;
        return new C((re * other.re + im * other.im) / d,
                     (im * other.re - re * other.im) / d);
    }
    public double abs() { return Math.hypot(re, im); }
    public double arg() { return Math.atan2(im, re); }
}

public class NicholsClosedLoop {

    // Plant: G(s) = K / (s * (Ts + 1))
    public static C GofJw(double K, double T, double w) {
        C jw = new C(0.0, w);
        C denom = jw.mul(jw.mul(new C(T, 0.0))).add(jw); // Ts^2 + s
        // safer: denom = T*(jw^2) + jw
        // but we'll keep it simple here
        return new C(K, 0.0).div(denom);
    }

    public static void main(String[] args) {
        double K = 5.0;
        double T = 0.1;

        double Mr = 0.0;
        double wMr = 0.0;

        for (int i = 0; i <= 400; ++i) {
            double w = Math.pow(10.0, -1.0 + 3.0 * i / 400.0);
            C L = GofJw(K, T, w);
            C Tjw = L.div(L.add(new C(1.0, 0.0)));

            double M = Tjw.abs();
            double psi = Tjw.arg(); // rad
            double Lmag = L.abs();
            double phi = L.arg();
            double Ldb = 20.0 * Math.log10(Lmag);

            if (M > Mr) {
                Mr = M;
                wMr = w;
            }

            // In a robotics framework, (phi, Ldb, M, psi) can be logged per frequency.
        }

        double Mr_db = 20.0 * Math.log10(Mr);
        System.out.printf("Closed-loop peak Mr = %.3f (%.2f dB) at w = %.3f rad/s%n",
                          Mr, Mr_db, wMr);
    }
}
      

This code illustrates how Nichols-based closed-loop analysis can be embedded in Java tooling around mechatronic plants.

10. MATLAB/Simulink Implementation (Control Toolbox)

MATLAB is widely used in control and robotics (often together with the Robotics System Toolbox). The following script constructs a plant, plots its Nichols locus, and verifies the closed-loop response using feedback:


% Plant: G(s) = K / (s (0.1 s + 1))
K = 5;
s = tf('s');
G = K / (s * (0.1*s + 1));

% Unity feedback
T = feedback(G, 1);

% Nichols plot of open-loop
figure;
nichols(G);
grid on;
title('Open-loop Nichols locus with M and N contours');

% Closed-loop Bode from Nichols (conceptual: MATLAB internally uses T(s))
figure;
bode(T);
grid on;
title('Closed-loop Bode plot from T(s) = G(s)/(1+G(s))');

% Resonant peak and bandwidth from closed-loop Bode
[Mr, wMr] = getPeakGain(T);      % closed-loop resonant peak
[mag, phase, w] = bode(T);
mag = squeeze(mag);
mag_db = 20*log10(mag);
idx = find(mag_db >= -3, 1, 'last'); % approximate bandwidth
wbw = w(idx);

fprintf('Closed-loop peak Mr = %.3f (%.2f dB) at w = %.3f rad/s\n', ...
        Mr, 20*log10(Mr), wMr);
fprintf('Approximate closed-loop bandwidth ~ %.3f rad/s\n', wbw);

% In Simulink, this plant and controller could be placed in a feedback loop;
% the Nichols chart guides controller tuning for desired Mr and bandwidth.
      

In Simulink, the same plant and controller blocks can be simulated in time domain; Nichols-based tuning is then validated against step and disturbance responses, especially important for robotic actuators with flexible joints and sensor noise.

11. Wolfram Mathematica Implementation

Mathematica provides symbolic and numeric tools for Nichols plots. The code below defines a plant and uses NicholsPlot, then evaluates the closed-loop transfer function along a frequency grid:


(* Plant and closed-loop definition *)
K = 5.0;
G[s_] := K/(s (0.1 s + 1));
T[s_] := G[s]/(1 + G[s]);

(* Nichols plot of open-loop *)
Needs["ControlSystems`"];
NicholsPlot[G[s], {s, I 10^-1, I 10^2},
  FrameLabel -> {"Phase (deg)", "Gain (dB)"},
  PlotLabel -> "Open-loop Nichols plot"];

(* Numeric closed-loop response via Hall-circle formula *)
wlist = Table[10^x, {x, -1.0, 2.0, 0.01}];
Lvals = G[I #] & /@ wlist;
Tvals = Lvals/(1 + Lvals);

Mvals = Abs /@ Tvals;
psivals = Arg /@ Tvals;

(* Plot closed-loop magnitude as a function of frequency *)
ListLogLinearPlot[
  Transpose[{wlist, 20 Log10[Mvals]}],
  Frame -> True,
  FrameLabel -> {"Frequency (rad/s)", "Closed-loop gain (dB)"},
  PlotLabel -> "Closed-loop Bode magnitude from Hall-circle relation"
]
      

With appropriate post-processing, one can overlay analytic M- and N-contours in the complex plane or gain–phase plane, reinforcing the geometric view of closed-loop response.

12. Problems and Solutions

Problem 1 (M-Circle Parameters): For a unity-feedback system with open-loop point \( z = G(j\omega) \), the constant-magnitude condition is \( M = |T(j\omega)| = |z|/|1+z| \). Derive the center and radius of the M-circle corresponding to a fixed \( M \neq 1 \).

Solution:

Following Section 2, the condition \( |z| = M|1+z| \) with \( z = x + jy \) yields the equation

\[ (1 - M^2)x^2 + (1 - M^2)y^2 - 2M^2 x - M^2 = 0. \]

Dividing by \( 1 - M^2 \) and completing the square, we obtain

\[ \left( x + \frac{M^2}{M^2 - 1} \right)^2 + y^2 = \frac{M^2}{(M^2 - 1)^2}. \]

Hence the M-circle has center \( C_M = \bigl(-\tfrac{M^2}{M^2 - 1},\,0\bigr) \) and radius \( R_M = \dfrac{M}{|M^2 - 1|} \).

Problem 2 (N-Circle Parameters): For the same unity-feedback loop, derive the center and radius of the N-circle corresponding to constant closed-loop phase \( \psi_0 \notin \{k\pi\} \).

Solution:

From Section 3, the constant phase condition \( \psi_0 = \arg z - \arg(1+z) \) is equivalent to requiring the imaginary part of \( e^{j\psi_0}\frac{1+z}{z} \) to vanish. Algebraic manipulation yields

\[ x^2 + x + y^2 - (\cot\psi_0)\,y = 0. \]

Completing the square in \( x \) and \( y \) gives

\[ \left(x + \tfrac{1}{2}\right)^2 + \left( y - \tfrac{1}{2}\cot\psi_0 \right)^2 = \tfrac{1}{4}\csc^2\psi_0. \]

Therefore the N-circle has center \( C_N = \bigl(-\tfrac{1}{2},\,\tfrac{1}{2}\cot\psi_0\bigr) \) and radius \( R_N = \tfrac{1}{2}|\csc\psi_0| \).

Problem 3 (Reading Closed-Loop Gain from Nichols Point): An open-loop point on the Nichols chart is located at phase \( \phi = -135^\circ \) and gain \( L_{\text{dB}} = 6\,\text{dB} \). Compute the corresponding closed-loop gain in dB.

Solution:

First convert to linear magnitude \( L = 10^{L_{\text{dB}}/20} = 10^{6/20} \approx 1.995 \). With \( \phi = -135^\circ = -\tfrac{3\pi}{4} \), we have \( \cos\phi = -\tfrac{\sqrt{2}}{2} \). The closed-loop magnitude is

\[ M = \frac{L}{\sqrt{1 + L^2 + 2L\cos\phi}} = \frac{L}{\sqrt{1 + L^2 - 2L\frac{\sqrt{2}}{2}}} = \frac{L}{\sqrt{1 + L^2 - \sqrt{2}L}}. \]

Substituting \( L \approx 1.995 \) gives numerically \( M \approx 1.13 \). In dB,

\[ M_{\text{dB}} = 20\log_{10}M \approx 20\log_{10}(1.13) \approx 1.06\,\text{dB}. \]

Thus the closed-loop gain at that frequency is slightly above \( 0\,\text{dB} \).

Problem 4 (Bandwidth from Nichols Chart): Suppose the open-loop Nichols locus of a normalized unity-feedback system intersects the \( M = 0.707 \) contour at a frequency \( \omega_b \). Explain why \( \omega_b \) can be interpreted as the approximate closed-loop bandwidth and outline the steps to determine it from the chart.

Solution:

For a system whose low-frequency closed-loop gain is near \( 0\,\text{dB} \) (unity), the bandwidth is defined as the frequency at which the closed-loop magnitude falls to \( -3\,\text{dB} \). Since \( -3\,\text{dB} \) corresponds to \( M = 10^{-3/20} \approx 0.707 \), the M-contour labeled \( -3\,\text{dB} \) directly encodes this threshold.

To determine \( \omega_b \) from the Nichols chart:

  1. Locate the M-contour labeled \( -3\,\text{dB} \) (or \( M = 0.707 \)).
  2. Find the intersection point between this contour and the open-loop Nichols locus.
  3. Identify the frequency \( \omega_b \) associated with this point (from the parametrization of the Nichols locus versus frequency).

The resulting \( \omega_b \) is the approximate closed-loop bandwidth.

Problem 5 (Qualitative Nichols-Based Tuning Flow): Describe a high-level procedure for adjusting a proportional gain \( K \) in a robot joint controller using the Nichols chart and M-contours, with the objective of achieving a specified resonant peak \( M_r \) and bandwidth.

Solution (flow):

flowchart TD
  S["Start with initial K and plant G(s)"] --> A["Compute Nichols curve of L(jw) = K*G(jw)"]
  A --> B["Overlay M-contours; \nlocate current Mr and bandwidth"]
  B --> C["If Mr too high or \nbandwidth too large, \ndecrease K"]
  B --> D["If Mr too low or \nbandwidth too small, \nincrease K"]
  C --> A
  D --> A
  A --> E["Stop when Mr and \nbandwidth meet design \ntargets within tolerance"]
        

13. Summary

In this lesson we expressed the closed-loop transfer function of a unity-feedback system in terms of its open-loop transfer function and derived the Hall-circle loci (M- and N-circles) in the complex plane. M-circles correspond to constant closed-loop magnitude and are Apollonius circles of the points \( 0 \) and \( -1 \), while N-circles correspond to constant closed-loop phase and share the chord from \( 0 \) to \( -1 \). Mapping these circles into Nichols coordinates yields contours of constant closed-loop magnitude and phase that can be superimposed on the open-loop Nichols locus.

We then showed how to interpret resonant peak, bandwidth, and detailed closed-loop frequency response directly from the Nichols chart, and we implemented the relevant computations in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica, with an emphasis on robotic servo applications. These tools prepare us for the next lesson, where we will use Nichols charts explicitly for controller design.

14. References

  1. Hall, A. C. (1943). The Analysis and Synthesis of Linear Servomechanisms. Technology Press, MIT.
  2. Nichols, N. B. (1947). Stability and Transient Response of Feedback Amplifier-Loops. Radiation Laboratory Series, MIT (technical report and related papers).
  3. Horowitz, I. M. (1963). Synthesis of Feedback Systems. Academic Press.
  4. Howowitz, I. M., & Sidi, M. (1972). Quantitative Feedback Theory (QFT): Fundamentals and Applications. International Journal of Control, various articles.
  5. Cerone, V., Canale, M., & Regruto, D. (2002). An Extended Nichols Chart with Constant Magnitude Loci of Sensitivity and Complementary Sensitivity Functions for Loop-Shaping Design. IFAC World Congress Proceedings.
  6. Alavi, S. M. M., & Saif, M. (2015). On Stability Analysis by Using Nyquist and Nichols Charts. arXiv:1511.04752.
  7. Lundberg, K. H., & Malchano, Z. J. (2004). Three-Dimensional Visualization of Nichols, Hall, and Robust-Performance Diagrams. In Proceedings of the American Control Conference.
  8. Ogata, K. (2010). Modern Control Engineering (5th ed.). Prentice Hall. (Chapters on frequency response and Nichols charts.)
  9. Nise, N. S. (2011). Control Systems Engineering (6th ed.). Wiley. (Sections on M- and N-circles and closed-loop frequency response.)
  10. Lurie, B. J., & Enright, P. J. (2000). Classical Feedback Control with MATLAB. Marcel Dekker. (Nichols chart and closed-loop design sections.)