Chapter 21: Loop Shaping and Servo Design

Lesson 1: Loop-Shaping Philosophy and Workflow

This lesson introduces the frequency-domain philosophy of loop shaping for single-input single-output (SISO) servo systems. We formalize the role of the open-loop transfer function \( L(s) = C(s)G(s) \), show how closed-loop tracking, disturbance rejection and robustness requirements translate into inequalities on \( L(j\omega) \), and summarize a systematic workflow for loop-shaping-based servo design. Implementation sketches in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica illustrate how these ideas appear in software, particularly in robotic joint servo control.

1. Unity Feedback and Open-Loop / Closed-Loop Relations

Throughout this chapter we consider a standard unity-feedback SISO servo configuration with controller transfer function \( C(s) \) and plant transfer function \( G(s) \). The loop transfer function is

\[ L(s) = C(s)G(s). \]

For a reference input \( R(s) \) and output \( Y(s) \), the closed-loop transfer function from reference to output in unity feedback is obtained by elementary block-diagram algebra:

\[ Y(s) = G(s)C(s)\bigl(R(s) - Y(s)\bigr) \quad \Longrightarrow \quad \bigl(1 + C(s)G(s)\bigr)Y(s) = C(s)G(s)R(s). \]

Hence

\[ \frac{Y(s)}{R(s)} = \frac{C(s)G(s)}{1 + C(s)G(s)} = \frac{L(s)}{1 + L(s)}. \]

The error signal in the servo loop is \( E(s) = R(s) - Y(s) \), so

\[ \frac{E(s)}{R(s)} = 1 - \frac{Y(s)}{R(s)} = 1 - \frac{L(s)}{1 + L(s)} = \frac{1}{1 + L(s)}. \]

These simple identities show that \( L(s) \) completely determines both tracking and error behavior. The philosophy of loop shaping is to design \( C(s) \) so that the frequency response \( L(j\omega) \) has a prescribed shape consistent with performance and robustness objectives.

2. Servo Objectives in Terms of \( L(j\omega) \)

Consider the closed-loop transfer function \( T(s) = \dfrac{L(s)}{1 + L(s)} \). For a constant (step) reference of amplitude \( r_0 \), we have \( R(s) = \dfrac{r_0}{s} \) and the final value theorem (for stable closed loop) gives

\[ y_{\infty} = \lim_{t \to \infty} y(t) = \lim_{s \to 0} s \frac{Y(s)}{1} = \lim_{s \to 0} s T(s) \frac{r_0}{s} = T(0) r_0. \]

The steady-state error is

\[ e_{\infty} = r_0 - y_{\infty} = r_0\bigl(1 - T(0)\bigr) = r_0 \frac{1}{1 + L(0)}. \]

Thus, for unit-step tracking \( r_0 = 1 \), we obtain the key relation

\[ e_{\infty} = \frac{1}{1 + L(0)}. \]

If we require \( |e_{\infty}| \leq \varepsilon \), then necessarily

\[ \frac{1}{1 + |L(0)|} \leq \varepsilon \quad \Longrightarrow \quad |L(0)| \geq \frac{1}{\varepsilon} - 1. \]

This shows that large low-frequency gain is needed for high accuracy. Conversely, at high frequencies, sensor noise and unmodeled dynamics motivate making \( |L(j\omega)| \) small for large \( \omega \). The resulting desired shape is:

  • Very high magnitude of \( L(j\omega) \) for small \( \omega \) (good tracking and disturbance rejection).
  • Unity gain around a design crossover frequency \( \omega_c \) with sufficient phase margin (stability and transient behavior).
  • Rapid roll-off for large \( \omega \) to attenuate noise and protect actuators.

These frequency-domain objectives will be refined throughout Chapters 21–22, but already illustrate the core loop-shaping philosophy: design a target shape for the loop transfer function and synthesize a controller that realizes it.

3. From Time-Domain Specs to Target Loop Shape

In previous chapters, performance requirements were often expressed in the time domain (rise time, overshoot, settling time) or as steady-state error bounds. Under standard approximations, these can be related to the bandwidth and crossover of \( L(j\omega) \) and hence \( T(j\omega) \).

For a well-damped second-order dominant closed loop \( T(s) \approx \dfrac{\omega_n^2}{s^2 + 2\zeta \omega_n s + \omega_n^2} \) with \( \zeta \in (0,1) \), typical approximations are:

\[ t_r \approx \frac{1.8}{\omega_n}, \qquad t_s \approx \frac{4}{\zeta \omega_n}, \]

where \( t_r \) is rise time and \( t_s \) is the 2% settling time. Empirically, the closed-loop bandwidth \( \omega_b \) is on the order of \( \omega_n \), and for well-designed loops \( \omega_c \) (the magnitude crossover of \( L(j\omega) \)) is close to \( \omega_b \). Thus:

\[ \text{fast tracking} \quad \Longleftrightarrow \quad \omega_c \text{ large}, \quad \text{subject to sufficient phase margin and actuator limits.} \]

Consequently, a typical loop-shaping design begins by converting:

  • Time-domain requirements (e.g. \( t_s \leq t_s^{\star} \))
  • Steady-state accuracy (\( |e_{\infty}| \leq \varepsilon \))
  • Robustness margins (gain margin, phase margin)

into frequency-domain constraints on \( |L(j\omega)| \) and the phase of \( L(j\omega) \). The outcome is a target loop shape that the actual \( L(j\omega) \) should approximate.

4. Simple Inequalities for Low- and High-Frequency Loop Gain

To make the loop-shaping trade-offs explicit, we can write simple inequalities. Assume closed-loop stability and unity feedback.

4.1 Low-Frequency Gain and Tracking

Suppose a unit-step reference must be tracked with relative steady-state error at most \( \varepsilon \), i.e. \( |e_{\infty}| \leq \varepsilon \). As derived earlier,

\[ e_{\infty} = \frac{1}{1 + L(0)}. \]

Taking magnitudes and enforcing the specification gives

\[ |L(0)| \geq \frac{1}{\varepsilon} - 1. \]

For example, if \( \varepsilon = 0.02 \), we need \( |L(0)| \geq 49 \), i.e. at least about 34 dB of loop gain at zero frequency.

4.2 High-Frequency Behavior and Noise

Suppose sensor noise \( n(t) \) enters at the measurement, so the controller sees \( y(t) + n(t) \). In the Laplace domain, the noise-to-output transfer function (under unity feedback) can be expressed in terms of \( L(s) \) and \( G(s) \). A standard calculation yields, for measurement noise:

\[ \frac{Y(s)}{N(s)} = -\frac{G(s)C(s)}{1 + C(s)G(s)} = -\frac{L(s)}{1 + L(s)}. \]

At high frequencies where \( |L(j\omega)| \ll 1 \), this behaves approximately as \( Y(s)/N(s) \approx -L(s) \), so noise amplification is controlled by \( |L(j\omega)| \). A bound of the form

\[ |L(j\omega)| \leq \gamma_{\text{noise}} \quad \text{for } \omega \geq \omega_{\text{noise}} \]

expresses a high-frequency constraint coming from noise or unmodeled dynamics. The combination of low-frequency inequality (tracking) and high-frequency inequality (noise) forces \( L(j\omega) \) to have a characteristic S-shaped magnitude plot with a crossover near \( \omega_c \).

5. Loop-Shaping Workflow (High-Level)

The design of a servo via loop shaping can be organized into a systematic workflow. At this stage we remain in the SISO setting and assume a transfer-function model \( G(s) \) of the plant is available from earlier modeling and identification steps.

  1. Model and uncertainty: Start from a nominal \( G(s) \) and, if known, a description of model uncertainty (e.g. parameter ranges, neglected dynamics).
  2. Performance objectives: Translate time-domain requirements (tracking, overshoot, settling time) and accuracy specifications into frequency-domain constraints on the closed-loop response.
  3. Target loop shape: Sketch a desired magnitude and phase profile \( L_d(j\omega) \) that satisfies these constraints while respecting margin requirements (gain and phase margins).
  4. Controller structure: Choose a realizable structure for \( C(s) \) (e.g. PI, PID, lead, lag, lead–lag) suitable for implementation on the target hardware.
  5. Synthesis: Solve approximately \( C(s)G(s) \approx L_d(s) \) over the frequencies of interest, adjusting controller parameters to match the target magnitude and phase.
  6. Verification: Check Bode plots, stability margins, and time responses (steps, disturbances). Iterate the design if requirements are not met.
  7. Implementation and refinement: Implement the controller in embedded software, test on the real system, and refine the model and loop shape if discrepancies arise.
flowchart TD
  A["Start: nominal plant G(s)"] --> B["Specify time-domain and frequency specs"]
  B --> C["Sketch target loop L_d(jw)"]
  C --> D["Choose controller structure C(s)"]
  D --> E["Tune C(s) so C(s)G(s) approx L_d(jw)"]
  E --> F["Analyze: Bode, margins, time responses"]
  F --> G{"Specs satisfied?"}
  G -->|yes| H["Implement in embedded / robot controller"]
  G -->|no| C
        

This flow will be revisited in later lessons with detailed design examples and case studies.

6. Template Loop Shapes for Servo Systems

To make the workflow concrete, it is common to use template loop shapes for servo systems. Here we outline a typical template for a position servo (e.g. robot joint or DC motor axis).

6.1 Type-1 Servo Template

For zero steady-state error to step inputs, the closed loop must contain an integrator. In a unity feedback servo, this is most conveniently implemented in the controller. A simple PI controller \( C(s) = K_p + \dfrac{K_i}{s} \) yields a loop transfer function of the form

\[ L(s) = \left(K_p + \frac{K_i}{s}\right)G(s) = \frac{K_i}{s}G(s) + K_p G(s). \]

Near \( s = 0 \) the term with \( 1/s \) dominates, so \( L(s) \) behaves like an integrator at very low frequency, leading to \( e_{\infty} = 0 \) for steps (provided the closed loop is stable).

6.2 Bandwidth and Roll-Off

The low-frequency part of the magnitude plot is shaped by the integral action and proportional gain, while the high-frequency part is shaped by the plant dynamics and any additional filters. A typical servo loop-shaping template is:

  • For \( \omega \ll \omega_c \): magnitude rising with slope near \( +20 \) dB/decade (integrator behavior).
  • At \( \omega \approx \omega_c \): magnitude near 0 dB and phase margin in a desired range (e.g. 45–60 degrees).
  • For \( \omega \gg \omega_c \): magnitude decaying at \( -20 \) to \( -40 \) dB/decade, with no excessive peaking in the closed-loop response.

In robotics, joint servo loops often follow such templates, with inner torque or current loops providing fast dynamics and outer position loops shaped for accuracy and robustness. Later chapters will discuss how multi-loop and two-degree-of-freedom structures fit into the same philosophy.

7. Software Lab — Loop Shaping for a Simple DC-Motor Servo

As a concrete example, consider a simple DC motor driving a rotational load (e.g. a robot joint) with dynamics approximated by

\[ G(s) = \frac{K}{J s^2 + b s}, \]

where \( J \) is the equivalent inertia, \( b \) is viscous friction, and \( K \) is an effective gain from control input (e.g. voltage) to torque. We choose a PI controller

\[ C(s) = K_p + \frac{K_i}{s}. \]

Below are skeleton implementations in several languages that compute and visualize the loop gain \( L(s) = C(s)G(s) \) and the closed-loop response. These are not full industrial implementations but capture the essential computations behind loop shaping.

7.1 Python (with python-control and robotics context)


import control as ctrl
import numpy as np
import matplotlib.pyplot as plt

# DC motor parameters (simple model)
J = 0.01   # inertia
b = 0.1    # viscous friction
K = 1.0    # effective torque gain

# Plant G(s) = K / (J s^2 + b s)
numG = [K]
denG = [J, b, 0.0]
G = ctrl.TransferFunction(numG, denG)

# PI controller C(s) = Kp + Ki / s
Kp = 20.0
Ki = 40.0
C = ctrl.TransferFunction([Kp, Ki], [1.0, 0.0])

L = C * G          # loop transfer
T = ctrl.feedback(L, 1)  # closed loop from r to y

# Bode plot of L(jw)
mag, phase, omega = ctrl.bode(L, dB=True, Hz=False, omega_limits=(1e-1, 1e3), omega_num=500)

# Step response of closed loop
t, y = ctrl.step_response(T)
plt.figure()
plt.plot(t, y)
plt.xlabel("time [s]")
plt.ylabel("position response")
plt.grid(True)

plt.show()

# In a robotics context, such a loop would be embedded in a joint controller.
# Libraries such as 'roboticstoolbox' for Python can provide the multi-DOF
# manipulator model, while 'python-control' handles single-joint loop analysis.
      

7.2 C++ (discrete-time simulation, ROS-style servo concept)


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

int main() {
    // Simple DC motor parameters
    double J  = 0.01;
    double b  = 0.1;
    double K  = 1.0;

    // PI gains from loop-shaping considerations
    double Kp = 20.0;
    double Ki = 40.0;

    double dt    = 0.0005;  // integration step
    double t_end = 1.0;     // simulation horizon

    // States: x1 = position, x2 = velocity
    double x1 = 0.0;
    double x2 = 0.0;
    double integral_error = 0.0;
    double ref = 1.0;       // unit-step reference

    int steps = static_cast<int>(t_end / dt);
    std::vector<double> time(steps), y(steps);

    for (int k = 0; k < steps; ++k) {
        double t = k * dt;
        double e = ref - x1;              // position error
        integral_error += e * dt;
        double u = Kp * e + Ki * integral_error; // PI control torque command

        // Motor dynamics: J * x2_dot + b * x2 = K * u
        double x2_dot = (K * u - b * x2) / J;
        double x1_dot = x2;

        x1 += dt * x1_dot;
        x2 += dt * x2_dot;

        time[k] = t;
        y[k]    = x1;
    }

    // Print final position as a simple check
    std::cout << "Final position: " << y.back() << std::endl;

    // In a ROS-based robot, similar PI computations appear inside a
    // position controller node using libraries such as 'ros_control',
    // while plant dynamics are provided by the robot's URDF and dynamics engine.
    return 0;
}
      

7.3 Java (basic step-response simulation)


public class LoopShapingServo {
    public static void main(String[] args) {
        double J  = 0.01;
        double b  = 0.1;
        double K  = 1.0;

        double Kp = 20.0;
        double Ki = 40.0;

        double dt    = 0.0005;
        double tEnd  = 1.0;
        int steps    = (int)(tEnd / dt);

        double x1 = 0.0;   // position
        double x2 = 0.0;   // velocity
        double integralError = 0.0;
        double ref = 1.0;

        double[] y = new double[steps];

        for (int k = 0; k < steps; ++k) {
            double e = ref - x1;
            integralError += e * dt;
            double u = Kp * e + Ki * integralError;

            double x2dot = (K * u - b * x2) / J;
            double x1dot = x2;

            x1 += dt * x1dot;
            x2 += dt * x2dot;

            y[k] = x1;
        }

        System.out.println("Final position: " + y[steps - 1]);

        // Java-based robotics frameworks (e.g. certain mobile-robot and competition libraries)
        // use similar update loops for servo control, often with abstractions for sensors,
        // actuators, and timing.
    }
}
      

7.4 MATLAB / Simulink


% DC motor parameters
J = 0.01;
b = 0.1;
K = 1.0;

s = tf('s');

% Plant and PI controller
G = K / (J*s^2 + b*s);
Kp = 20;
Ki = 40;
C = Kp + Ki/s;

L = C*G;
T = feedback(L, 1);

% Bode plot of loop transfer
figure; bode(L); grid on;

% Step response of closed loop
figure; step(T); grid on;

% In Simulink, the same servo can be implemented using blocks:
%   - Transfer Fcn for G(s)
%   - Sum blocks for feedback
%   - PI controller block or manual gain + integrator
% This allows visual experimentation with loop shapes and performance.
      

7.5 Wolfram Mathematica


J = 0.01;
b = 0.1;
K = 1.0;

Kp = 20.0;
Ki = 40.0;

s = LaplaceTransformVariable;

G = TransferFunctionModel[K/(J*s^2 + b*s), s];
C = TransferFunctionModel[Kp + Ki/s, s];

L = SystemsModelSeriesConnect[C, G];
T = SystemsModelFeedbackConnect[L];

BodePlot[L, {s, 0.1, 1000},
  FrameLabel -> {"Frequency (rad/s)", "Magnitude/Phase"},
  GridLines -> Automatic
];

StepResponsePlot[T, {0, 1},
  FrameLabel -> {"time (s)", "position"},
  GridLines -> Automatic
];
      

These models allow inspection of the loop gain shape and closed-loop behavior. In later lessons we will tune parameters \( K_p \), \( K_i \) and add lead/lag compensation directly from frequency-domain specifications.

8. Example of Iterative Loop-Shaping Refinement

In practice, the designer rarely obtains an acceptable loop on the first attempt. A typical iteration is:

  • Increase \( K_p \) to raise bandwidth, improving tracking but reducing phase margin.
  • Add lead compensation to increase phase margin near crossover without excessively reducing gain.
  • Introduce low-pass filtering (e.g. first-order roll-off) to attenuate high-frequency noise.
flowchart TD
  S["Initial PI design"] --> A["Analyze Bode: \ncheck crossover, margins"]
  A --> B{"Bandwidth too low?"}
  B -->|yes| C["Increase Kp, \nadjust Ki"]
  B -->|no| D{"Margins too small?"}
  D -->|yes| E["Add lead term \nor reduce Kp"]
  D -->|no| F{"Noise / actuator \nissues?"}
  F -->|yes| G["Add high-frequency \nroll-off filter"]
  F -->|no| H["Accept design, \nmove to implementation"]
  C --> A
  E --> A
  G --> A
        

This iterative process reflects the fundamental trade-offs inherent in loop shaping: improving one aspect of performance (e.g. speed) often degrades another (e.g. robustness or noise sensitivity). Later chapters will formalize these trade-offs using sensitivity functions and robustness measures.

9. Problems and Solutions

Problem 1 (Closed-Loop Maps for Reference and Noise): Consider a unity-feedback system with controller \( C(s) \), plant \( G(s) \), and loop transfer \( L(s) = C(s)G(s) \). Assume a reference input \( R(s) \) and measurement noise \( N(s) \) added at the sensor (so the controller sees \( Y(s) + N(s) \)). Derive the transfer functions \( \dfrac{Y(s)}{R(s)} \) and \( \dfrac{Y(s)}{N(s)} \).

Solution:

The controller input is \( E(s) = R(s) - Y(s) - N(s) \), so the control signal is \( U(s) = C(s)E(s) \). The plant output is \( Y(s) = G(s)U(s) = G(s)C(s)E(s) = L(s)E(s) \). Therefore

\[ Y(s) = L(s)\bigl(R(s) - Y(s) - N(s)\bigr) = L(s)R(s) - L(s)Y(s) - L(s)N(s). \]

Rearranging terms gives

\[ \bigl(1 + L(s)\bigr)Y(s) = L(s)R(s) - L(s)N(s), \]

hence

\[ \frac{Y(s)}{R(s)} = \frac{L(s)}{1 + L(s)}, \qquad \frac{Y(s)}{N(s)} = -\frac{L(s)}{1 + L(s)}. \]

The same factor \( L(s)/(1 + L(s)) \) governs both reference tracking and measurement noise transfer, illustrating why the shape of \( L(j\omega) \) is central.

Problem 2 (Steady-State Error Requirement as a Constraint on \( L(0) \)): For a unity-feedback servo tracking a unit step, show that requiring \( |e_{\infty}| \leq \varepsilon \) is equivalent to \( |L(0)| \geq \dfrac{1}{\varepsilon} - 1 \). Explain how this influences the low-frequency part of the loop-shaping design.

Solution:

From the general relation in Section 2 we have \( e_{\infty} = 1/(1 + L(0)) \). Taking magnitudes,

\[ |e_{\infty}| = \left|\frac{1}{1 + L(0)}\right| = \frac{1}{|1 + L(0)|}. \]

The design requirement \( |e_{\infty}| \leq \varepsilon \) implies \( 1/|1 + L(0)| \leq \varepsilon \), or

\[ |1 + L(0)| \geq \frac{1}{\varepsilon}. \]

If \( L(0) \) is real and positive (typical for low frequency), then \( |1 + L(0)| = 1 + |L(0)| \) and we obtain

\[ 1 + |L(0)| \geq \frac{1}{\varepsilon} \quad \Longrightarrow \quad |L(0)| \geq \frac{1}{\varepsilon} - 1. \]

Thus, the low-frequency magnitude of \( L(j\omega) \) must be at least \( 20\log_{10}\bigl(\frac{1}{\varepsilon} - 1\bigr) \) dB near \( \omega = 0 \). Loop shaping must therefore allocate sufficiently high gain at very low frequencies to meet accuracy specifications.

Problem 3 (Approximate Bandwidth Requirement from Settling Time): A servo must have settling time \( t_s \leq 0.2 \) s with well-damped behavior (assume \( \zeta \approx 0.7 \) and a second-order dominant closed loop). Estimate a suitable closed-loop natural frequency \( \omega_n \) and an associated loop crossover frequency \( \omega_c \) that should be targeted by loop shaping.

Solution:

Using the approximation \( t_s \approx 4/(\zeta \omega_n) \) and the given \( t_s^{\star} = 0.2 \) s, we have

\[ 0.2 \approx \frac{4}{\zeta \omega_n} \quad \Longrightarrow \quad \omega_n \approx \frac{4}{0.2 \zeta} = \frac{20}{\zeta}. \]

For \( \zeta \approx 0.7 \),

\[ \omega_n \approx \frac{20}{0.7} \approx 28.6 \text{ rad/s}. \]

The closed-loop bandwidth \( \omega_b \) is typically of the same order as \( \omega_n \). For well-shaped loops, the crossover frequency \( \omega_c \) is also close to the bandwidth, so a reasonable target is \( \omega_c \approx 25 \) to \( 30 \) rad/s. In loop shaping we therefore design \( L(j\omega) \) so that its magnitude crosses 0 dB in this range with adequate phase margin.

Problem 4 (Loop-Shaping Constraints for an Integrator Plant): Let the plant be \( G(s) = 1/s \) (e.g. a velocity integrator). We use a proportional controller \( C(s) = K \), so \( L(s) = K/s \). Assume we want:

  • A unit-step steady-state error \( |e_{\infty}| \leq 0.05 \).
  • A crossover frequency \( \omega_c \leq 20 \) rad/s to respect actuator limits.

Determine a feasible range for \( K \) that satisfies both constraints (ignoring phase margin for this problem).

Solution:

For \( G(s) = 1/s \) and controller \( C(s) = K \) we have \( L(s) = \dfrac{K}{s} \). The closed-loop transfer function is \( T(s) = \dfrac{L(s)}{1 + L(s)} = \dfrac{K}{s + K} \), a stable first-order system.

First, the steady-state error for a unit step is \( e_{\infty} = 1/(1 + L(0)) \). Here, \( L(0) = \infty \) (due to the integrator), so \( e_{\infty} = 0 \). The specification \( |e_{\infty}| \leq 0.05 \) is automatically satisfied for any \( K > 0 \) because the loop has integral action.

Next, the magnitude of \( L(j\omega) \) is \( |L(j\omega)| = K/\omega \). The crossover frequency \( \omega_c \) satisfies \( |L(j\omega_c)| = 1 \), i.e.

\[ \frac{K}{\omega_c} = 1 \quad \Longrightarrow \quad \omega_c = K. \]

The actuator constraint requires \( \omega_c \leq 20 \) rad/s, so \( K \leq 20 \). There is no lower bound on \( K \) from the step error (since it is already zero), but small \( K \) would yield extremely slow closed-loop response (small \( \omega_c \)). A practical design might choose \( K \) close to (but safely below) 20 rad/s, then refine using phase margin and robustness considerations.

10. Summary

In this lesson we introduced the key idea of loop shaping: designing the controller so that the open-loop transfer function \( L(s) = C(s)G(s) \) has a frequency response \( L(j\omega) \) with prescribed low-frequency gain, crossover behavior, and high-frequency roll-off. We related steady-state error directly to \( L(0) \), showed how time-domain settling-time specifications translate into approximate bandwidth targets, and outlined a systematic workflow for iterative loop-shaping design. Finally, we illustrated these ideas on a simple DC-motor servo with multi-language software sketches that mirror the structure of practical robotic joint controllers. Subsequent lessons will refine these concepts using quantitative frequency-domain performance measures, sensitivity functions, and detailed case studies.

11. References

  1. Bode, H. W. (1945). Network Analysis and Feedback Amplifier Design. Van Nostrand, New York.
  2. Horowitz, I. M. (1963). Synthesis of feedback systems with given loop transfer function. International Journal of Control, 1(1), 1–28.
  3. Horowitz, I. M. (1965). Synthesis of Feedback Systems. Academic Press.
  4. Maciejowski, J. M. (1989). Multivariable Feedback Design. Addison–Wesley.
  5. Safonov, M. G., & Athans, M. (1977). Gain and phase margin for multiloop LQG regulators. IEEE Transactions on Automatic Control, 22(2), 173–179.
  6. Doyle, J. C. (1978). Guaranteed margins for LQG regulators. IEEE Transactions on Automatic Control, 23(4), 756–757.
  7. Glover, K., & McFarlane, D. C. (1989). Robust stabilization of normalized coprime factor plant descriptions with H-infinity-bounded uncertainty. IEEE Transactions on Automatic Control, 34(8), 821–830.
  8. Skogestad, S., & Postlethwaite, I. (1996). Multivariable Feedback Control: Analysis and Design. Wiley.
  9. Francis, B. A., & Wonham, W. M. (1976). The internal model principle for linear multivariable regulators. Applied Mathematics and Optimization, 2(2), 170–194.
  10. Ogata, K. (2010). Modern Control Engineering (5th ed.). Prentice Hall. (Classical loop-shaping material in early chapters.)