Chapter 30: Limitations of Linear Control and Pathways to Advanced Topics

Lesson 4: Role of Classical Linear Control in a Complete Control Architecture

This lesson explains how the single-loop classical linear controllers studied in this course (PID, lead/lag, loop-shaping) fit into complete industrial and mechatronic control architectures. We formalize layered control structures, show how inner linear feedback loops can be aggregated as equivalent plants for upper layers, and analyze how sensitivity and bandwidth determine the degree to which higher-level (possibly nonlinear or optimal) algorithms can treat classical loops as modular subsystems.

1. Complete Control Architectures and Layers

Real-world systems rarely consist of a single feedback loop. Instead, a complete control architecture is layered:

  • High-level layer: mission planning, trajectory generation, constraint and safety logic.
  • Intermediate layer: set-point management, mode switching, fault handling.
  • Low-level layer: fast classical linear controllers (PID, lead/lag) that drive actuators.
  • Physical layer: plant dynamics, sensors, actuators, and communication channels.

Classical linear control primarily occupies the low-level layer, where it ensures local stability, tracking, and disturbance rejection around a nominal operating point. Higher layers can then assume that the low-level layer behaves approximately as a linear map with well-known closed-loop properties.

Let \( P(s) \) denote the LTI plant and \( C(s) \) a classical linear controller. The low-level loop is typically unity feedback, sometimes with a sensor dynamics \( H(s) \). For simplicity, assume \( H(s)=1 \). The loop transfer function is

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

The sensitivity function and complementary sensitivity function are

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

In a complete architecture, the pair \( (S,T) \) summarizes the frequency-domain behavior of the low-level linear loop as seen by upper layers: tracking of references, disturbance rejection, and noise amplification.

flowchart TD
  PL["High-level planner / supervisor"] --> RG["Reference generator"]
  RG --> LL["Low-level linear controller C(s)"]
  LL --> PLANT["Physical plant P(s)"]
  PLANT --> SENS["Sensors"]
  SENS --> FEED["Feedback signals to C(s)"]
  PLANT --> MON["Safety & diagnostics"]
  MON --> PL
        

2. Classical Linear Feedback as a Modular Block

Consider a standard negative-feedback loop with a classical controller and an LTI plant, with:

  • \( r(t) \): reference (set-point) coming from a higher-level module,
  • \( d(t) \): disturbance entering at the plant input,
  • \( n(t) \): sensor noise added to the measurement.

In the Laplace domain, assuming unity sensor dynamics and zero initial conditions, we have

\[ \begin{aligned} y(s) &= P(s)\big(u(s) + d(s)\big), \\ u(s) &= C(s)\big(r(s) - y(s) - n(s)\big). \end{aligned} \]

Eliminating \( u(s) \) and solving for \( y(s) \) gives

\[ \begin{aligned} y(s) &= P(s)C(s)\big(r(s) - y(s) - n(s)\big) + P(s)d(s) \\ \big(1 + P(s)C(s)\big)y(s) &= P(s)C(s)\big(r(s) - n(s)\big) + P(s)d(s) \\ y(s) &= \frac{P(s)C(s)}{1 + P(s)C(s)}\,r(s) + \frac{P(s)}{1 + P(s)C(s)}\,d(s) - \frac{P(s)C(s)}{1 + P(s)C(s)}\,n(s). \end{aligned} \]

Using the definitions of \( S(s) \) and \( T(s) \), this becomes

\[ y(s) = T(s)r(s) + S(s)d(s) - T(s)n(s). \]

From the viewpoint of an upper-level planner that selects \( r(t) \), the low-level closed-loop subsystem is a linear operator mapping \( (r,d,n) \mapsto y \). Its behavior is completely characterized by \( S(s) \) and \( T(s) \). The role of classical design is to shape \( S \) and \( T \) so that:

  • Tracking: \( T(j\omega) \approx 1 \) at low frequencies.
  • Disturbance rejection: \( S(j\omega) \approx 0 \) at frequencies where typical disturbances live.
  • Noise attenuation: \( T(j\omega) \) small at high frequencies.

Once this is achieved, the higher-level modules can treat the low-level loop as an approximate unity-gain, bandwidth-limited subsystem with known robustness margins.

3. Cascaded Loops and Equivalent Plants

In Chapter 25, you studied cascade control with inner and outer loops (e.g., inner current loop and outer speed loop for a motor). Let the plant factor as \( P(s) = P_1(s)P_2(s) \), where:

  • \( P_1(s) \) is a fast subsystem (e.g., actuator or current dynamics),
  • \( P_2(s) \) is a slower subsystem (e.g., mechanical position dynamics).

An inner controller \( C_{\mathrm{in}}(s) \) is wrapped around \( P_1(s) \) to form an inner closed loop with input \( v(s) \) and output \( \tilde{u}(s) \) (the signal feeding \( P_2 \)):

\[ \tilde{u}(s) = \frac{P_1(s)C_{\mathrm{in}}(s)}{1 + P_1(s)C_{\mathrm{in}}(s)}\,v(s) = T_{\mathrm{in}}(s)v(s), \]

where \( T_{\mathrm{in}}(s) \) is the inner complementary sensitivity. The outer loop sees an equivalent plant

\[ P_{\mathrm{eq}}(s) = P_2(s)T_{\mathrm{in}}(s) = P_2(s)\frac{P_1(s)C_{\mathrm{in}}(s)}{1 + P_1(s)C_{\mathrm{in}}(s)}. \]

Designing an outer controller \( C_{\mathrm{out}}(s) \) around \( P_{\mathrm{eq}}(s) \) yields a two-loop architecture whose overall loop transfer function is

\[ L_{\mathrm{tot}}(s) = C_{\mathrm{out}}(s)P_{\mathrm{eq}}(s) = C_{\mathrm{out}}(s)P_2(s)T_{\mathrm{in}}(s). \]

The associated overall sensitivity and complementary sensitivity are

\[ S_{\mathrm{tot}}(s) = \frac{1}{1 + L_{\mathrm{tot}}(s)}, \qquad T_{\mathrm{tot}}(s) = \frac{L_{\mathrm{tot}}(s)}{1 + L_{\mathrm{tot}}(s)}. \]

Thus, from the perspective of the outer loop, the inner loop is fully captured by the equivalent map \( P_{\mathrm{eq}}(s) \). This is precisely how classical linear controllers become modules in larger architectures.

flowchart TD
  R["Outer reference r(t)"] --> COUT["Outer controller C_out(s)"]
  COUT --> V["Intermediate command v(t)"]
  V --> CIN["Inner controller C_in(s)"]
  CIN --> P1["Fast subsystem P1(s)"]
  P1 --> P2["Slow subsystem P2(s)"]
  P2 --> Y["Output y(t)"]
  Y --> FB["Feedback to C_out(s) and/or C_in(s)"]
        

4. Interaction with Advanced / Nonlinear Modules

Modern control architectures frequently include components that are not classical LTI blocks: constraint handlers, logic-based mode switches, or optimal controllers built in future courses (e.g., modern state-space, optimal, or robust control). Classical linear controllers still play a key role:

  • As stabilizing inner loops, ensuring basic stability and bandwidth, while higher-level algorithms compute references \( r(t) \) or intermediate set-points.
  • As baseline controllers, around which robust or adaptive schemes are designed to guarantee minimum performance even under uncertainty.
  • As filters for estimation and measurement (e.g., linear filters in Chapter 26).

Mathematically, a high-level module can be viewed as generating a reference trajectory \( r_h(t) \) that respects constraints and mission objectives. The low-level linear loop then enforces

\[ y(t) \approx r_h(t) \quad \text{for time-scales where} \quad T(j\omega) \approx 1. \]

On faster time-scales, internal dynamics of the low-level loop dominate, but high-level modules typically change more slowly, so they perceive the low-level system as approximately unity-gain and phase-lagged, characterized by its bandwidth and margins.

This separation of roles allows advanced methods to focus on what to do (trajectory, constraints, switching), while classical linear control determines how to enforce those decisions on the plant.

5. Time-Scale Separation and Approximate Modularity

A key reason classical low-level controllers can be treated as modular blocks is time-scale separation. Suppose the inner closed-loop transfer function is \( T_{\mathrm{in}}(s) \), and its bandwidth is \( \omega_{\mathrm{in}} \). Assume the outer controller \( C_{\mathrm{out}}(s) \) has bandwidth \( \omega_{\mathrm{out}} \) with

\[ \omega_{\mathrm{out}} \ll \omega_{\mathrm{in}}. \]

Suppose the ideal inner loop (as seen by the outer loop) would be unity gain, i.e. \( T_{\mathrm{in},\mathrm{ideal}}(s) = 1 \). In reality, \( T_{\mathrm{in}}(s) \) deviates from 1. Define the deviation

\[ \Delta T_{\mathrm{in}}(s) = T_{\mathrm{in}}(s) - 1. \]

Assume that in the frequency band where \( C_{\mathrm{out}}(s) \) has significant gain,

\[ \sup_{|\omega| \le \omega_{\mathrm{out}}} \big|\Delta T_{\mathrm{in}}(j\omega)\big| \le \varepsilon, \qquad \varepsilon \ll 1. \]

Let \( P_2(s) \) be the outer plant component; the ideal outer loop (if the inner loop were exactly unity) would have loop transfer function

\[ L_{\mathrm{ideal}}(s) = C_{\mathrm{out}}(s)P_2(s). \]

With the true inner loop, the actual outer loop has

\[ L_{\mathrm{actual}}(s) = C_{\mathrm{out}}(s)P_2(s)T_{\mathrm{in}}(s) = L_{\mathrm{ideal}}(s)\big(1 + \Delta T_{\mathrm{in}}(s)\big). \]

The corresponding complementary sensitivities are

\[ T_{\mathrm{ideal}}(s) = \frac{L_{\mathrm{ideal}}(s)}{1 + L_{\mathrm{ideal}}(s)}, \qquad T_{\mathrm{actual}}(s) = \frac{L_{\mathrm{actual}}(s)}{1 + L_{\mathrm{actual}}(s)}. \]

A first-order bound on the deviation between these two can be derived by linearizing in \( \Delta T_{\mathrm{in}} \). For small \( \Delta T_{\mathrm{in}} \):

\[ T_{\mathrm{actual}}(s) - T_{\mathrm{ideal}}(s) \approx \frac{L_{\mathrm{ideal}}(s)}{\big(1 + L_{\mathrm{ideal}}(s)\big)^2} \Delta T_{\mathrm{in}}(s). \]

Thus, in the outer-loop frequency band, a uniform bound \( |\Delta T_{\mathrm{in}}(j\omega)| \le \varepsilon \) implies

\[ \big|T_{\mathrm{actual}}(j\omega) - T_{\mathrm{ideal}}(j\omega)\big| \lesssim \varepsilon \left|\frac{L_{\mathrm{ideal}}(j\omega)}{\big(1 + L_{\mathrm{ideal}}(j\omega)\big)^2}\right|. \]

If the outer loop is reasonably well-designed (so that \( |L_{\mathrm{ideal}}(j\omega)| \) is not extremely large in its operating band), this deviation is small. This justifies treating the inner linear loop as an almost ideal unity-gain block when designing outer loops or high-level controllers.

6. Python Implementation — Low-Level Classical Loop Inside an Architecture

Python offers several libraries for linear control, including python-control (often imported as control) and scipy.signal. The snippet below constructs a cascaded architecture: an inner PI controller \( C_{\mathrm{in}}(s) \) around a fast subsystem \( P_1(s) \), and an outer PI controller \( C_{\mathrm{out}}(s) \) around the equivalent plant \( P_{\mathrm{eq}}(s) \).


import numpy as np
import matplotlib.pyplot as plt

# python-control library: pip install control
import control as ctl

# Laplace variable
s = ctl.TransferFunction.s

# Fast subsystem P1(s) and slow subsystem P2(s)
P1 = 1 / (0.05 * s + 1)     # time constant 0.05 s (fast)
P2 = 1 / (s * (0.5 * s + 1))  # second-order-ish slow dynamics

# Inner PI controller C_in(s) = Kp_in + Ki_in / s
Kp_in = 5.0
Ki_in = 50.0
C_in = Kp_in + Ki_in / s

# Inner closed-loop complementary sensitivity T_in(s)
T_in = ctl.feedback(C_in * P1, 1)

# Equivalent plant for outer loop
P_eq = T_in * P2

# Outer PI controller C_out(s)
Kp_out = 2.0
Ki_out = 1.0
C_out = Kp_out + Ki_out / s

# Overall closed-loop (reference r to output y)
L_tot = C_out * P_eq
T_tot = ctl.feedback(L_tot, 1)

# Compare with ideal outer loop assuming T_in(s) = 1
P_ideal = P2
L_ideal = C_out * P_ideal
T_ideal = ctl.feedback(L_ideal, 1)

t = np.linspace(0, 5, 1000)
t1, y_actual = ctl.step_response(T_tot, T=t)
t2, y_ideal  = ctl.step_response(T_ideal, T=t)

plt.figure()
plt.plot(t1, y_actual, label="Two-loop actual")
plt.plot(t2, y_ideal, "--", label="Outer loop with ideal inner unity block")
plt.xlabel("Time [s]")
plt.ylabel("Output y(t)")
plt.grid(True)
plt.legend()
plt.title("Role of fast inner loop: near-unity equivalent plant for outer loop")
plt.show()
      

Here, the inner linear loop is simulated explicitly, and the outer loop is designed as if the inner loop were unity. The resulting responses illustrate the small discrepancy predicted by the analysis in the previous section when the inner loop bandwidth is much higher than the outer loop bandwidth.

7. C++ Implementation — Low-Level PID Servo Class

In embedded and industrial environments, the low-level classical controller is often implemented in C or C++. Below is a minimal C++11-style implementation of a discrete-time PID used as a low-level servo in a larger architecture. The outer architecture (trajectory generator, supervisor, etc.) interacts only via the reference r and measured output y.


#include <iostream>
#include <vector>

struct PID {
    double Kp;
    double Ki;
    double Kd;
    double dt;

    double integrator;
    double prev_error;

    PID(double Kp_, double Ki_, double Kd_, double dt_)
        : Kp(Kp_), Ki(Ki_), Kd(Kd_), dt(dt_),
          integrator(0.0), prev_error(0.0) {}

    double update(double error) {
        // Trapezoidal integration for I term
        integrator += 0.5 * (error + prev_error) * dt;
        double derivative = (error - prev_error) / dt;
        prev_error = error;
        return Kp * error + Ki * integrator + Kd * derivative;
    }
};

// Example: first-order plant x_dot = (-1/T)*x + (K/T)*u
struct FirstOrderPlant {
    double T;
    double K;
    double x;

    FirstOrderPlant(double T_, double K_)
        : T(T_), K(K_), x(0.0) {}

    double step(double u, double dt) {
        double dx = (-x / T) + (K / T) * u;
        x += dt * dx;
        return x; // y = x
    }
};

int main() {
    double dt = 0.001;
    PID lowLevelPID(2.0, 50.0, 0.01, dt);
    FirstOrderPlant plant(0.05, 1.0);

    double r = 1.0;           // reference from higher-level module
    std::vector<double> y_log, u_log;

    double y = 0.0;
    for (int k = 0; k < 20000; ++k) {
        double error = r - y;
        double u = lowLevelPID.update(error);

        // Plant update
        y = plant.step(u, dt);

        y_log.push_back(y);
        u_log.push_back(u);
    }

    std::cout << "Final output y = " << y << std::endl;
    return 0;
}
      

In a complete architecture, the main loop of the real-time system will:

  1. Receive a reference r from a higher-level module.
  2. Read sensor data y.
  3. Compute u = PID.update(r - y) at a fixed sampling period.
  4. Send u to the actuator.

The higher-level modules do not need to know the details of the PID implementation; they only depend on the effective closed-loop behavior (e.g., bandwidth, damping) provided by the low-level classical controller.

8. Java Implementation — Low-Level Controller in a Service Class

For Java-based control frameworks (e.g., in process control or robotics middleware), the low-level linear controller can be encapsulated as a service object. Below is a simple discrete-time PI controller class together with a main loop skeleton.


public class PIController {
    private final double Kp;
    private final double Ki;
    private final double dt;

    private double integrator = 0.0;
    private double prevError = 0.0;

    public PIController(double Kp, double Ki, double dt) {
        this.Kp = Kp;
        this.Ki = Ki;
        this.dt = dt;
    }

    public double update(double error) {
        integrator += 0.5 * (error + prevError) * dt;
        prevError = error;
        return Kp * error + Ki * integrator;
    }
}

class FirstOrderPlant {
    private final double T;
    private final double K;
    private double x = 0.0;

    public FirstOrderPlant(double T, double K) {
        this.T = T;
        this.K = K;
    }

    public double step(double u, double dt) {
        double dx = (-x / T) + (K / T) * u;
        x += dt * dx;
        return x;
    }
}

public class LowLevelLoop {
    public static void main(String[] args) {
        double dt = 0.01;
        PIController controller = new PIController(3.0, 20.0, dt);
        FirstOrderPlant plant = new FirstOrderPlant(0.1, 1.0);

        double r = 1.0; // reference from high-level controller
        double y = 0.0;

        for (int k = 0; k < 2000; ++k) {
            double error = r - y;
            double u = controller.update(error);
            y = plant.step(u, dt);

            // logging or telemetry to higher layer
        }
    }
}
      

In a layered architecture, the outer coordinator may periodically update r or switch between different controller instances, but the local PI controller continues to enforce linear feedback at the fast sampling rate.

9. MATLAB/Simulink Implementation — Cascade of Inner and Outer Loops

MATLAB with the Control System Toolbox is a standard environment for designing and verifying linear controllers before implementing them in embedded software or Simulink diagrams. The following script constructs an inner and outer loop, and computes the overall closed-loop transfer function.


% Inner and outer classical controllers in a cascade architecture

s = tf('s');

% Fast and slow dynamics
P1 = 1 / (0.05*s + 1);            % fast
P2 = 1 / (s*(0.5*s + 1));         % slower

% Inner PI controller
Kp_in = 5;
Ki_in = 60;
C_in = Kp_in + Ki_in/s;

% Inner closed loop and equivalent plant for the outer loop
T_in  = feedback(C_in*P1, 1);
P_eq  = T_in * P2;

% Outer PI controller
Kp_out = 2;
Ki_out = 1;
C_out  = Kp_out + Ki_out/s;

% Overall two-loop closed loop (r -> y)
T_tot = feedback(C_out*P_eq, 1);

% For comparison: outer loop designed assuming ideal inner unity block
P_ideal = P2;
T_ideal = feedback(C_out*P_ideal, 1);

figure; step(T_tot, T_ideal, 5);
legend('Two-loop actual','Outer loop with ideal inner block');
grid on; title('Role of inner classical loop within complete architecture');
      

A corresponding Simulink realization would place the inner loop (with C_in and P1) in one subsystem block and the outer loop (with C_out and P2) in another. The interface signals between these subsystems define the modular structure that high-level logic can exploit.

10. Wolfram Mathematica Implementation — Symbolic Aggregation of Loops

Wolfram Mathematica is well suited for symbolic manipulation of transfer functions and state-space models. The code below constructs an inner and outer loop and simplifies the overall closed-loop transfer function symbolically.


(* Define Laplace variable and transfer functions *)
s = LaplaceTransformVariable;

P1[s_] := 1/(0.05 s + 1);
P2[s_] := 1/(s (0.5 s + 1));

KpIn  = 5;
KiIn  = 60;
Cin[s_] := KpIn + KiIn/s;

KinLoopTF[s_] := (P1[s] Cin[s])/(1 + P1[s] Cin[s]);
Peq[s_] := KinLoopTF[s] P2[s];

KpOut = 2;
KiOut = 1;
Cout[s_] := KpOut + KiOut/s;

Ltot[s_] := Cout[s] Peq[s];
Ttot[s_] := Ltot[s]/(1 + Ltot[s]);

(* Ideal case: inner loop is unity *)
Lideal[s_] := Cout[s] P2[s];
Tideal[s_] := Lideal[s]/(1 + Lideal[s]);

(* Simplify expressions *)
FullSimplify[Ttot[s]]
FullSimplify[Tideal[s]]
      

Symbolic expressions obtained from Ttot[s] and Tideal[s] provide insight into the exact difference between the ideal and true cascaded architectures, complementing the numerical frequency-domain and time-domain analyses in previous sections.

11. Problems and Solutions

Problem 1 (Closed-Loop Transfer Channels in a Complete Architecture). Consider the low-level loop with plant \( P(s) \) and controller \( C(s) \). A disturbance \( d(s) \) enters additively at the plant input, and measurement noise \( n(s) \) is added to the output before the feedback summing junction. Derive the transfer functions from \( r(s) \), \( d(s) \), and \( n(s) \) to the output \( y(s) \), and express them in terms of \( S(s) \) and \( T(s) \).

Solution. As in Section 2, the equations are

\[ \begin{aligned} y(s) &= P(s)\big(u(s) + d(s)\big), \\ u(s) &= C(s)\big(r(s) - y(s) - n(s)\big). \end{aligned} \]

Substitute \( u(s) \) into \( y(s) \):

\[ \begin{aligned} y(s) &= P(s)C(s)\big(r(s) - y(s) - n(s)\big) + P(s)d(s) \\ &= P(s)C(s)r(s) - P(s)C(s)y(s) - P(s)C(s)n(s) + P(s)d(s). \end{aligned} \]

Collect the \( y(s) \) terms:

\[ \big(1 + P(s)C(s)\big)y(s) = P(s)C(s)r(s) - P(s)C(s)n(s) + P(s)d(s). \]

Therefore,

\[ y(s) = \frac{P(s)C(s)}{1 + P(s)C(s)}\,r(s) + \frac{P(s)}{1 + P(s)C(s)}\,d(s) - \frac{P(s)C(s)}{1 + P(s)C(s)}\,n(s). \]

With \( L(s) = P(s)C(s) \), \( S(s) = 1/(1 + L(s)) \), \( T(s) = L(s)/(1 + L(s)) \), we get

\[ y(s) = T(s)r(s) + S(s)d(s) - T(s)n(s). \]

These three closed-loop channels are central when embedding the low-level loop into a larger architecture: high-level planning primarily interacts with the \( r \mapsto y \) channel, whereas robustness analysis focuses on the \( d \mapsto y \) and \( n \mapsto y \) channels.

Problem 2 (Equivalent Plant for Outer Loop). Let \( P(s) = P_1(s)P_2(s) \) and an inner loop with controller \( C_{\mathrm{in}}(s) \) around \( P_1(s) \) as in Section 3. Show by explicit block-diagram algebra that the equivalent plant seen by an outer controller is \( P_{\mathrm{eq}}(s) = P_2(s)T_{\mathrm{in}}(s) \), where \( T_{\mathrm{in}}(s) = P_1(s)C_{\mathrm{in}}(s) / \big(1 + P_1(s)C_{\mathrm{in}}(s)\big) \).

Solution. Denote by \( v(s) \) the input to the inner loop and by \( \tilde{u}(s) \) its output, which drives \( P_2(s) \). Then

\[ \tilde{u}(s) = P_1(s)\big(u_{\mathrm{in}}(s) + d_1(s)\big), \qquad u_{\mathrm{in}}(s) = C_{\mathrm{in}}(s)\big(v(s) - \tilde{u}(s)\big), \]

where \( d_1(s) \) is an inner disturbance (set to zero for the equivalent-plant analysis). With \( d_1(s) = 0 \),

\[ \tilde{u}(s) = P_1(s)C_{\mathrm{in}}(s)\big(v(s) - \tilde{u}(s)\big). \]

Hence

\[ \tilde{u}(s)\big(1 + P_1(s)C_{\mathrm{in}}(s)\big) = P_1(s)C_{\mathrm{in}}(s)v(s), \]

which yields

\[ \tilde{u}(s) = \frac{P_1(s)C_{\mathrm{in}}(s)}{1 + P_1(s)C_{\mathrm{in}}(s)}\,v(s) = T_{\mathrm{in}}(s)v(s). \]

Since \( y(s) = P_2(s)\tilde{u}(s) \), we have

\[ y(s) = P_2(s)T_{\mathrm{in}}(s)v(s). \]

Therefore, from the outer-loop perspective, the map from \( v(s) \) to \( y(s) \) is exactly \( P_{\mathrm{eq}}(s) = P_2(s)T_{\mathrm{in}}(s) \), as required.

Problem 3 (Effect of Inner Loop Bandwidth on Outer Loop Design). Assume the inner loop has complementary sensitivity \( T_{\mathrm{in}}(s) \) and the outer loop uses controller \( C_{\mathrm{out}}(s) \) designed for the ideal plant \( P_2(s) \) (i.e., with \( T_{\mathrm{in}}(s) \equiv 1 \)). Let \( L_{\mathrm{ideal}}(s) = C_{\mathrm{out}}(s)P_2(s) \) and \( L_{\mathrm{actual}}(s) = C_{\mathrm{out}}(s)P_2(s)T_{\mathrm{in}}(s) \). Show that if \( T_{\mathrm{in}}(s) = 1 + \Delta T_{\mathrm{in}}(s) \) with \( |\Delta T_{\mathrm{in}}(j\omega)| \le \varepsilon \) over the outer-loop bandwidth, then to first order in \( \varepsilon \)

\[ T_{\mathrm{actual}}(s) - T_{\mathrm{ideal}}(s) \approx \frac{L_{\mathrm{ideal}}(s)}{\big(1 + L_{\mathrm{ideal}}(s)\big)^2} \Delta T_{\mathrm{in}}(s), \]

where \( T_{\mathrm{actual}} \) and \( T_{\mathrm{ideal}} \) are the closed-loop complementary sensitivities for the actual and ideal outer loops, respectively.

Solution. By definition,

\[ T_{\mathrm{ideal}}(s) = \frac{L_{\mathrm{ideal}}(s)}{1 + L_{\mathrm{ideal}}(s)}, \qquad T_{\mathrm{actual}}(s) = \frac{L_{\mathrm{actual}}(s)}{1 + L_{\mathrm{actual}}(s)}. \]

Substitute \( L_{\mathrm{actual}}(s) = L_{\mathrm{ideal}}(s)\big(1 + \Delta T_{\mathrm{in}}(s)\big) \). Write \( L = L_{\mathrm{ideal}}(s) \) and \( \delta = \Delta T_{\mathrm{in}}(s) \) for brevity. Then

\[ T_{\mathrm{actual}}(s) = \frac{L(1 + \delta)}{1 + L(1 + \delta)} = \frac{L + L\delta}{1 + L + L\delta}. \]

Treat \( \delta \) as a small perturbation. The map \( f(L) = L/(1 + L) \) has derivative

\[ f'(L) = \frac{1}{(1 + L)^2}. \]

To first order in \( \delta \), the change in \( T \) due to the perturbation \( L \mapsto L(1 + \delta) \) is

\[ T_{\mathrm{actual}}(s) - T_{\mathrm{ideal}}(s) \approx f'(L)\cdot L\delta = \frac{L}{(1 + L)^2}\,\Delta T_{\mathrm{in}}(s). \]

Re-substituting \( L = L_{\mathrm{ideal}}(s) \) gives the desired expression. The magnitude of the error is bounded by \( |L_{\mathrm{ideal}}(j\omega)| \big/ \big|1 + L_{\mathrm{ideal}}(j\omega)\big|^2 \cdot \varepsilon \) in the outer-loop frequency band, which is small when the inner-loop perturbation \( \varepsilon \) is small.

Problem 4 (Embedding a Classical Loop in a Discrete-Time Implementation). A continuous-time PI controller has transfer function \( C(s) = K_p + K_i/s \). Show that using the trapezoidal rule to approximate the integral \( \int e(t)\,\mathrm{d}t \) on a sampling grid with period \( T_s \) leads to the discrete-time update

\[ u[k] = u[k-1] + K_p\big(e[k] - e[k-1]\big) + \frac{K_i T_s}{2}\big(e[k] + e[k-1]\big), \]

where \( e[k] = r[k] - y[k] \).

Solution. The continuous PI control law can be written as

\[ u(t) = K_p e(t) + K_i I(t), \qquad I(t) = \int_0^t e(\sigma)\,\mathrm{d}\sigma. \]

On a sampling grid \( t_k = k T_s \), the trapezoidal approximation to the integral gives

\[ I[k] = I[k-1] + \frac{T_s}{2}\big(e[k] + e[k-1]\big). \]

The discrete-time control law is

\[ u[k] = K_p e[k] + K_i I[k]. \]

Substitute \( I[k] \):

\[ \begin{aligned} u[k] &= K_p e[k] + K_i \left(I[k-1] + \frac{T_s}{2}\big(e[k] + e[k-1]\big)\right) \\ &= \big(K_p e[k] + K_i I[k-1]\big) + \frac{K_i T_s}{2}\big(e[k] + e[k-1]\big). \end{aligned} \]

But from the previous step, \( u[k-1] = K_p e[k-1] + K_i I[k-1] \), hence \( K_i I[k-1] = u[k-1] - K_p e[k-1] \). Substituting,

\[ \begin{aligned} u[k] &= K_p e[k] + \big(u[k-1] - K_p e[k-1]\big) + \frac{K_i T_s}{2}\big(e[k] + e[k-1]\big) \\ &= u[k-1] + K_p\big(e[k] - e[k-1]\big) + \frac{K_i T_s}{2}\big(e[k] + e[k-1]\big), \end{aligned} \]

which is the required discrete-time update used in many embedded implementations of low-level PI control.

12. Summary

In this lesson, we placed classical linear controllers within the context of complete control architectures. We showed that:

  • Low-level classical feedback loops can be viewed as linear operators characterized by their sensitivity and complementary sensitivity functions \( S(s) \) and \( T(s) \).
  • In cascaded structures, inner loops around fast subsystems are equivalently represented by a closed-loop transfer function \( T_{\mathrm{in}}(s) \), yielding an effective outer plant \( P_{\mathrm{eq}}(s) = P_2(s)T_{\mathrm{in}}(s) \).
  • Under time-scale separation, deviations of \( T_{\mathrm{in}}(s) \) from unity cause only small perturbations of the outer closed-loop behavior, justifying modular design.
  • Classical linear loops are central building blocks even when combined with higher-level nonlinear or optimal modules; they provide stabilizing, bandwidth-limited interfaces to the physical plant.
  • Implementations in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica all follow the same architectural concepts, differing mainly in syntax and numeric integration details.

These insights prepare you to understand how the classical techniques from this course interface with modern state-space, optimal, robust, and digital control methods that will be developed in subsequent courses.

13. References

  1. Zames, G. (1966). On the input-output stability of time-varying nonlinear feedback systems. IEEE Transactions on Automatic Control, 11(2), 228–238.
  2. Francis, B. A., & Wonham, W. M. (1975). The internal model principle of control theory. Automatica, 12(5), 457–465.
  3. Åström, K. J. (1970). Introduction to stochastic control theory (control architecture and feedback concepts). Various journal and book chapters.
  4. Doyle, J. C., Wall, J. E., & Stein, G. (1992). Performance and robustness analysis for structured uncertainty. Automatica, 26(1), 71–83.
  5. Middleton, R. H., & Goodwin, G. C. (1990). Digital control and estimation: a unified approach (foundation of discrete-time implementations). IEEE-related theoretical contributions.
  6. Skogestad, S. (2003). Simple analytic rules for model reduction and PID controller tuning. Journal of Process Control, 13(4), 291–309.
  7. Isidori, A. (1989). Nonlinear control systems: an introduction (hierarchical and feedback structures). Selected theoretical chapters.
  8. Chen, J., & Francis, B. A. (1995). Optimal sampled-data control systems. Systems & Control Letters, 25(1), 27–34.
  9. Desoer, C. A., & Vidyasagar, M. (1975). Feedback systems: input-output properties. Academic theoretical monograph.
  10. Goodwin, G. C., Graebe, S. F., & Salgado, M. E. (2001). Control system design (chapters on multiloop and hierarchical architectures). Various theoretical sections.