Chapter 25: Multiloop and Cascade Control Structures (SISO Focus)
Lesson 5: Industrial Examples of Multiloop SISO Control
This lesson illustrates how cascade and multiloop SISO architectures are used in industrial practice. We analyze two canonical cases: servo drives for robot joints (current–speed–position loops) and thermal processes with flow–temperature cascade control. For each case we derive closed-loop transfer functions, discuss bandwidth separation, and show how such controllers are implemented in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica.
1. Industrial Motivation for Multiloop SISO Control
In previous lessons of this chapter you saw the abstract structure of inner/outer loops and cascade control. Here we emphasize why industry uses multiloop SISO structures instead of a single feedback loop:
- Different time scales: Inner loops control fast physics (currents, flows, pressures), outer loops control slow variables (speed, position, temperature, level).
- Disturbance localization: Disturbances that enter through a fast subsystem (e.g. flow fluctuations, supply voltage changes) are suppressed by a dedicated inner loop.
- Modularity: Inner loops are often implemented in embedded drives or dedicated PLC function blocks; outer loops are tuned by process or robotics engineers without modifying the inner firmware.
Consider a plant split conceptually into a fast inner part with transfer function \( G_i(s) \) and a slower outer part \( G_o(s) \). An inner controller \( C_i(s) \) and an outer controller \( C_o(s) \) are arranged in cascade. The inner closed loop from inner reference to inner variable is
\[ T_i(s) = \frac{C_i(s)G_i(s)}{1 + C_i(s)G_i(s)},\qquad S_i(s) = \frac{1}{1 + C_i(s)G_i(s)}. \]
The outer loop sees the equivalent plant \( G_{\text{eq}}(s) \) given by
\[ G_{\text{eq}}(s) = G_o(s)\,T_i(s). \]
If the inner loop is tuned so that \( |C_i(j\omega)G_i(j\omega)| \gg 1 \) in the frequency band of interest for the outer loop, then \( T_i(s) \approx 1 \) and \( S_i(s) \approx 0 \) in that band. The outer loop can then be designed almost as if the inner variable were perfectly controlled.
The complete two-loop closed-loop transfer from outer reference \( R(s) \) to output \( Y(s) \) is, using the convention that both loops use unity feedback:
\[ T_{\text{cas}}(s) = \frac{Y(s)}{R(s)} = \frac{C_o(s)C_i(s)G_i(s)G_o(s)}{1 + C_i(s)G_i(s) + C_o(s)C_i(s)G_i(s)G_o(s)}. \]
When \( C_i(s)G_i(s) \) has much larger magnitude than \( C_o(s)G_o(s) \) over the outer bandwidth, the term \( 1 + C_i(s)G_i(s) \) is dominated by \( C_i(s)G_i(s) \) and the overall loop behaves closely to the simple one-loop form \( T_{\text{cas}}(s) \approx \frac{C_o(s)G_o(s)}{1 + C_o(s)G_o(s)} \).
flowchart TD
A["Start from process or robot joint description"] --> B["Identify fast and slow dynamics"]
B --> C["Select structure: cascade, ratio, or override"]
C --> D["Choose inner loop measurement and actuator"]
D --> E["Design and tune inner loop (fast, high bandwidth)"]
E --> F["Model equivalent plant seen by outer loop"]
F --> G["Design and tune outer loop for specs"]
G --> H["Implement in PLC / drive / robot controller"]
H --> I["Commission and validate (check margins, responses)"]
2. Servo Drive Example: Current–Speed–Position Loops
A very common industrial example is a servo drive controlling a robot joint or a machine axis. The actuator is often a DC or permanent-magnet synchronous motor. The control structure typically has three nested SISO loops:
- Inner loop: current (torque) control.
- Middle loop: speed control.
- Outer loop: position control.
For a simplified DC motor model (armature control, single axis), the dynamics are
\[ L\frac{di(t)}{dt} + R\,i(t) = v(t) - K_e\,\omega(t), \]
\[ J\frac{d\omega(t)}{dt} + B\,\omega(t) = K_t\,i(t) - T_L(t), \qquad \frac{d\theta(t)}{dt} = \omega(t), \]
where \( i(t) \) is current, \( v(t) \) armature voltage, \( \omega(t) \) angular speed, \( \theta(t) \) position, and \( T_L(t) \) the load torque.
In Laplace domain, neglecting load torque for the moment:
\[ I(s) = \frac{1}{L s + R}\bigl(V(s) - K_e\Omega(s)\bigr), \qquad \Omega(s) = \frac{K_t}{J s + B}I(s), \qquad \Theta(s) = \frac{1}{s}\Omega(s). \]
For the inner current loop we usually treat \( \omega(t) \) as slowly varying and approximate the electrical plant by \( G_i(s) = \frac{1}{L s + R} \). With a PI current controller
\[ C_i(s) = K_{pi} + \frac{K_{ii}}{s}, \]
the inner closed-loop transfer from current reference \( I_{\text{ref}}(s) \) to measured current \( I(s) \) is
\[ T_i(s) = \frac{I(s)}{I_{\text{ref}}(s)} = \frac{C_i(s)G_i(s)}{1 + C_i(s)G_i(s)}. \]
With sufficiently aggressive inner-loop gains, \( T_i(s) \approx 1 \) up to a crossover frequency \( \omega_{ci} \) that is well above the desired speed-loop bandwidth. Then the mechanical dynamics become approximately
\[ \Omega(s) \approx \frac{K_t}{J s + B}\,I_{\text{ref}}(s), \qquad \Theta(s) \approx \frac{K_t}{s(J s + B)}\,I_{\text{ref}}(s). \]
The speed loop uses a PI controller \( C_\omega(s) = K_{p\omega} + \frac{K_{i\omega}}{s} \) and sees the plant \( G_\omega(s) = \frac{K_t}{J s + B} \). The closed-loop speed transfer from speed reference \( \Omega_{\text{ref}}(s) \) to speed is
\[ T_\omega(s) = \frac{\Omega(s)}{\Omega_{\text{ref}}(s)} \approx \frac{C_\omega(s)G_\omega(s)}{1 + C_\omega(s)G_\omega(s)}. \]
Finally, the position loop uses a PI controller \( C_\theta(s) = K_{p\theta} + \frac{K_{i\theta}}{s} \), seeing approximately the plant \( G_\theta(s) = \frac{K_t}{s(J s + B)} \) because the speed loop has been made fast. The complete approximate cascade is thus
\[ \Theta(s) \approx \frac{C_\theta(s)G_\theta(s)}{1 + C_\theta(s)G_\theta(s)}\, \Theta_{\text{ref}}(s), \]
where the inner two loops (current and speed) mainly improve disturbance rejection and robustness of the torque/speed generation, while the outer position loop is tuned for tracking accuracy and overshoot.
flowchart TD
Rpos["Position ref theta_ref"] --> Cpos["Position controller Ctheta"]
Cpos --> Wref["Speed ref omega_ref"]
Wref --> Cw["Speed controller Comega"]
Cw --> Iref["Current ref i_ref"]
Iref --> Ci["Current controller Ci"]
Ci --> Motor["Motor + mechanics"]
Motor --> Theta["Measured position theta"]
Theta --> Cpos
Motor --> Wmeas["Speed sensor"]
Wmeas --> Cw
Motor --> Imeas["Current sensor"]
Imeas --> Ci
Commercial robot joint drives typically implement the current loop in the power electronics stage (kHz range), the speed loop in the drive firmware (hundreds of Hz), and the position loop in the robot controller (tens of Hz). This natural timescale separation matches the theory of cascade control.
3. Process Example: Flow–Temperature Cascade Control
Another classical industrial example is jacketed vessel temperature control. The outer loop controls product temperature \( T(t) \), while the inner loop controls jacket flow rate \( F(t) \) by manipulating a control valve opening. Flow disturbances (from supply pressure, upstream control actions, etc.) act quickly and are best rejected by the inner loop.
A simple linear model for the inner flow loop (valve and piping) is a first-order system
\[ G_F(s) = \frac{F(s)}{U(s)} = \frac{K_F}{T_F s + 1}, \]
where \( U(s) \) is the valve input from the flow controller. The outer temperature dynamics can also be modeled as first order with respect to flow,
\[ G_T(s) = \frac{T(s)}{F(s)} = \frac{K_T}{T_T s + 1}, \]
with typically \( T_T \gg T_F \), i.e. temperature responds much more slowly than flow.
3.1 Single Temperature Loop (No Cascade)
Suppose a single temperature controller \( C_T(s) \) directly drives the valve. Let \( d_F(t) \) be an additive flow disturbance at the output of \( G_F \). Then
\[ F(s) = G_F(s)U(s) + d_F(s),\qquad T(s) = G_T(s)F(s). \]
With negative unity feedback on temperature, the control law is \( U(s) = C_T(s)\bigl(T_{\text{sp}}(s) - T(s)\bigr) \). Solving for \( T(s) \), we obtain:
\[ T(s) = \frac{G_T(s)G_F(s)C_T(s)}{1 + G_T(s)G_F(s)C_T(s)}\,T_{\text{sp}}(s) + \frac{G_T(s)}{1 + G_T(s)G_F(s)C_T(s)}\,d_F(s). \]
Thus the transfer from disturbance \( d_F \) to temperature \( T \) is
\[ T_{d,\text{single}}(s) = \frac{T(s)}{d_F(s)} = \frac{G_T(s)}{1 + G_T(s)G_F(s)C_T(s)}. \]
3.2 Cascade Flow–Temperature Control
Now we add an inner flow loop with controller \( C_F(s) \) and flow setpoint \( F_{\text{sp}}(s) \). The inner loop behaves as
\[ U(s) = C_F(s)\bigl(F_{\text{sp}}(s) - F(s)\bigr), \qquad F(s) = G_F(s)U(s) + d_F(s). \]
Solving for \( F(s) \) gives the inner closed-loop and disturbance response:
\[ F(s) = \underbrace{\frac{C_F(s)G_F(s)}{1 + C_F(s)G_F(s)}}_{T_F(s)} F_{\text{sp}}(s) + \underbrace{\frac{1}{1 + C_F(s)G_F(s)}}_{S_F(s)} d_F(s). \]
The outer temperature loop now uses \( F_{\text{sp}}(s) \) as its control signal: \( F_{\text{sp}}(s) = C_T(s)\bigl(T_{\text{sp}}(s) - T(s)\bigr) \), and \( T(s) = G_T(s)F(s) \). Substituting \( F(s) \) yields
\[ T(s) = G_T(s)T_F(s)C_T(s)\bigl(T_{\text{sp}}(s) - T(s)\bigr) + G_T(s)S_F(s)\,d_F(s). \]
Rearranging, the cascade closed-loop from temperature setpoint to temperature is
\[ \frac{T(s)}{T_{\text{sp}}(s)} = \frac{G_T(s)T_F(s)C_T(s)}{1 + G_T(s)T_F(s)C_T(s)}, \]
and from disturbance \( d_F \) to temperature \( T \) we have
\[ T_{d,\text{cas}}(s) = \frac{T(s)}{d_F(s)} = \frac{G_T(s)S_F(s)}{1 + G_T(s)T_F(s)C_T(s)}. \]
Comparing with the single-loop case, we see the extra factor \( S_F(s) = \frac{1}{1 + C_F(s)G_F(s)} \), which is small in the frequency range where the inner flow loop has high gain. Hence cascade control attenuates flow disturbances much more strongly than a single temperature loop, while leaving the outer-loop structure analogous to a single-loop design with plant \( G_T(s)T_F(s) \).
4. Frequency-Domain Interpretation and Bandwidth Separation
The examples above suggest a general frequency-domain guideline: the inner loop must be significantly faster than the outer loop so that the inner closed loop can be approximated as a unity-gain element over the outer-loop bandwidth.
Let \( L_i(s) = C_i(s)G_i(s) \) be the inner-loop open-loop transfer function, and define the inner crossover frequency \( \omega_{ci} \) by \( |L_i(j\omega_{ci})| = 1 \). Similarly, let \( L_o(s) = C_o(s)G_{\text{eq}}(s) \) be the outer-loop open loop (with \( G_{\text{eq}}(s) = G_o(s)T_i(s) \)), and define \( \omega_{co} \) by \( |L_o(j\omega_{co})| = 1 \). A typical design rule is
\[ \omega_{ci} \geq 4\,\omega_{co} \]
(and often as large as \( 8\,\omega_{co} \) or more), provided that the inner-loop stability margins remain acceptable. In the servo-drive example, current-loop bandwidth might be in the kHz range, speed-loop bandwidth in hundreds of Hz, and position-loop bandwidth in tens of Hz.
In terms of sensitivity functions, the outer loop experiences the effective plant \( G_{\text{eq}}(s) = G_o(s)T_i(s) \). The outer-loop sensitivity \( S_o(s) \) and complementary sensitivity \( T_o(s) \) satisfy
\[ S_o(s) = \frac{1}{1 + L_o(s)},\qquad T_o(s) = \frac{L_o(s)}{1 + L_o(s)}. \]
If \( T_i(s) \approx 1 \) and \( S_i(s) \approx 0 \) for \( \omega \leq \omega_{co} \), then the outer-loop trade-offs between tracking (low \( |S_o| \)) and noise attenuation (low \( |T_o| \) at high frequency) are essentially the same as in a single-loop design on \( G_o(s) \). The inner loop mainly reshapes the plant at higher frequencies and localizes fast disturbances (such as valve or power-electronics effects).
5. Software Implementations: Robot Joint Cascade Servo
We now implement a simplified cascade servo for a single robot joint in several languages. We use the DC motor model from Section 2 and three nested PI loops (current, speed, position). For brevity, we simulate a small time interval and ignore friction nonlinearities and saturation.
5.1 Python (NumPy & Control/Robotics Context)
The following script simulates the cascaded loops using explicit Euler
integration. This can represent one joint of a robot arm; in practice,
such code would be embedded in a real-time loop or implemented via
specialized libraries (e.g. python-control and robotics
toolboxes).
import numpy as np
import matplotlib.pyplot as plt
# Sampling and simulation horizon
Ts = 1e-4
T_end = 0.2
N = int(T_end / Ts)
# Motor parameters (simplified)
J = 0.01 # inertia
B = 0.001 # viscous damping
L = 1e-3 # inductance
R = 0.5 # resistance
Kt = 0.05 # torque constant
Ke = 0.05 # back-EMF constant
# PI gains for the three loops
Kp_i, Ki_i = 50.0, 5e3 # current loop
Kp_w, Ki_w = 2.0, 200.0 # speed loop
Kp_th, Ki_th = 20.0, 200.0 # position loop
# States
i = 0.0 # current
w = 0.0 # speed
theta = 0.0 # position
xi_i = 0.0 # integral current
xi_w = 0.0 # integral speed
xi_th = 0.0 # integral position
theta_ref = np.deg2rad(90.0) # 90 degrees step
time = np.zeros(N)
theta_hist = np.zeros(N)
w_hist = np.zeros(N)
i_hist = np.zeros(N)
for k in range(N):
# Outer position loop
e_th = theta_ref - theta
xi_th += e_th * Ts
w_ref = Kp_th * e_th + Ki_th * xi_th
# Middle speed loop
e_w = w_ref - w
xi_w += e_w * Ts
i_ref = Kp_w * e_w + Ki_w * xi_w
# Inner current loop
e_i = i_ref - i
xi_i += e_i * Ts
v = Kp_i * e_i + Ki_i * xi_i
# Motor dynamics (continuous-time model discretized with Euler)
di = (-R * i + v - Ke * w) / L
dw = (-B * w + Kt * i) / J
dtheta = w
i += di * Ts
w += dw * Ts
theta += dtheta * Ts
time[k] = k * Ts
theta_hist[k] = theta
w_hist[k] = w
i_hist[k] = i
# Plot position response
plt.figure()
plt.plot(time, theta_hist, label="theta(t)")
plt.axhline(theta_ref, linestyle="--", label="theta_ref")
plt.xlabel("Time [s]")
plt.ylabel("Position [rad]")
plt.legend()
plt.grid(True)
plt.show()
To link this with robotics toolboxes, one could model the robot kinematics separately (e.g. with a DH-model) and treat the above servo as acting on each joint independently, provided that dynamic coupling is modest or compensated at a higher level.
5.2 C++ (Embedded/ROS Control Style Skeleton)
In C++, cascaded loops are typically implemented in real-time threads or as controllers in frameworks such as ros_control. The following fragment shows the nested-loop logic; a more complete implementation would interface with hardware drivers and run at a fixed update rate.
#include <iostream>
struct PIController {
double kp;
double ki;
double xi;
double Ts;
PIController(double kp_, double ki_, double Ts_)
: kp(kp_), ki(ki_), xi(0.0), Ts(Ts_) {}
double update(double ref, double meas) {
double e = ref - meas;
xi += e * Ts;
return kp * e + ki * xi;
}
};
int main() {
double Ts = 1e-4;
int N = 2000;
// PI loops
PIController current_loop(50.0, 5000.0, Ts);
PIController speed_loop(2.0, 200.0, Ts);
PIController position_loop(20.0, 200.0, Ts);
// Motor states
double i = 0.0;
double w = 0.0;
double theta = 0.0;
// Parameters
double J = 0.01;
double B = 0.001;
double R = 0.5;
double L = 1e-3;
double Kt = 0.05;
double Ke = 0.05;
double theta_ref = 1.57; // rad
for (int k = 0; k < N; ++k) {
double w_ref = position_loop.update(theta_ref, theta);
double i_ref = speed_loop.update(w_ref, w);
double v = current_loop.update(i_ref, i);
// Simple Euler integration of motor model
double di = (-R * i + v - Ke * w) / L;
double dw = (-B * w + Kt * i) / J;
double dtheta = w;
i += di * Ts;
w += dw * Ts;
theta += dtheta * Ts;
}
std::cout << "Final theta [rad]: " << theta << std::endl;
return 0;
}
In a ROS-based robot, similar loops would be executed inside controller callbacks (e.g. position, velocity, and effort controllers) associated with each joint handle. The mathematical structure is exactly the cascade discussed earlier.
5.3 Java (High-Level Structure)
Java is used in some robotics platforms (for example, educational and competition robots). The following code expresses the same structure; in a real system, sensor readings and actuator commands would come from hardware APIs.
public class CascadeServo {
static class PIController {
double kp, ki, xi, Ts;
PIController(double kp, double ki, double Ts) {
this.kp = kp;
this.ki = ki;
this.Ts = Ts;
this.xi = 0.0;
}
double update(double ref, double meas) {
double e = ref - meas;
xi += e * Ts;
return kp * e + ki * xi;
}
}
public static void main(String[] args) {
double Ts = 1e-4;
int N = 2000;
PIController currentLoop = new PIController(50.0, 5000.0, Ts);
PIController speedLoop = new PIController(2.0, 200.0, Ts);
PIController positionLoop = new PIController(20.0, 200.0, Ts);
double i = 0.0;
double w = 0.0;
double theta = 0.0;
double J = 0.01;
double B = 0.001;
double R = 0.5;
double L = 1e-3;
double Kt = 0.05;
double Ke = 0.05;
double thetaRef = 1.57; // rad
for (int k = 0; k < N; ++k) {
double wRef = positionLoop.update(thetaRef, theta);
double iRef = speedLoop.update(wRef, w);
double v = currentLoop.update(iRef, i);
double di = (-R * i + v - Ke * w) / L;
double dw = (-B * w + Kt * i) / J;
double dtheta = w;
i += di * Ts;
w += dw * Ts;
theta += dtheta * Ts;
}
System.out.println("Final theta [rad]: " + theta);
}
}
This pattern mirrors industrial motion-control APIs: the low-level drive handles current control, a mid-level loop handles speed, and a high-level controller (often in another task or processor) handles position.
5.4 MATLAB/Simulink (Transfer-Function View)
MATLAB and Simulink are standard tools for designing and tuning multiloop controllers before implementing them in embedded code. The following script models a current loop and speed loop in transfer-function form and computes the resulting closed-loop responses.
s = tf('s');
% Inner current loop (approximate electrical dynamics)
G_i = 1 / (1e-3 * s + 0.5);
C_i = 50 + 5000 / s;
T_i = feedback(C_i * G_i, 1); % inner closed loop
% Speed plant (mechanical dynamics)
J = 0.01; B = 0.001; Kt = 0.05;
G_w = Kt / (J * s + B);
% Speed loop on top of closed current loop
C_w = 2 + 200 / s;
G_eq = T_i * G_w;
T_w = feedback(C_w * G_eq, 1);
figure;
step(T_w);
grid on;
title('Speed loop step response with inner current loop');
% In Simulink, the same structure is built by nesting Feedback blocks:
% outer speed PID feeding the reference of an inner current PID,
% which drives a Transfer Fcn block for G_i and a mechanical plant block.
5.5 Wolfram Mathematica (Symbolic and Numeric)
Mathematica can represent the cascade symbolically and perform analytic or numeric analysis of closed-loop behavior.
s = LaplaceTransformVariable;
Gi = TransferFunctionModel[1/(0.001*s + 0.5), s];
Ci = TransferFunctionModel[50 + 5000/s, s];
Ti = FeedbackConnect[Ci*Gi, 1];
Gw = TransferFunctionModel[0.05/(0.01*s + 0.001), s];
Cw = TransferFunctionModel[2 + 200/s, s];
Geq = SeriesConnect[Ti, Gw];
Tw = FeedbackConnect[Cw*Geq, 1];
(* Step response *)
Plot[
Evaluate@Last@OutputResponse[Tw, UnitStep[t], {t, 0, 0.2}],
{t, 0, 0.2},
AxesLabel -> {"t", "omega(t)"}
]
Symbolic manipulation of TransferFunctionModel objects
allows derivation of closed-loop poles, zeros, and sensitivity functions
for the multiloop arrangement in a way that mirrors the manual
derivations in earlier sections.
6. Problems and Solutions
Problem 1 (Inner Closed Loop and Equivalent Plant): Consider the cascade structure with inner plant \( G_i(s) = \frac{1}{T_i s + 1} \), inner controller \( C_i(s) = K_i \) (pure gain), outer plant \( G_o(s) = \frac{K_o}{T_o s + 1} \), and outer controller \( C_o(s) = K_o^c \). Derive:
- The inner closed-loop transfer \( T_i(s) \).
- The equivalent plant \( G_{\text{eq}}(s) = G_o(s)T_i(s) \).
- The overall closed-loop transfer from outer reference to output.
Solution:
1. The inner closed loop is
\[ T_i(s) = \frac{C_i(s)G_i(s)}{1 + C_i(s)G_i(s)} = \frac{K_i \frac{1}{T_i s + 1}}{1 + K_i \frac{1}{T_i s + 1}} = \frac{K_i}{T_i s + 1 + K_i}. \]
2. The equivalent plant seen by the outer loop is
\[ G_{\text{eq}}(s) = G_o(s)T_i(s) = \frac{K_o}{T_o s + 1} \cdot \frac{K_i}{T_i s + 1 + K_i}. \]
3. The outer loop is a standard unity-feedback system with plant \( G_{\text{eq}}(s) \) and controller \( C_o(s) = K_o^c \). The closed-loop transfer is
\[ T_{\text{cas}}(s) = \frac{K_o^c G_{\text{eq}}(s)}{1 + K_o^c G_{\text{eq}}(s)} = \frac{K_o^c \frac{K_o K_i}{(T_o s + 1)(T_i s + 1 + K_i)}} {1 + K_o^c \frac{K_o K_i}{(T_o s + 1)(T_i s + 1 + K_i)}}. \]
Problem 2 (Effect of Inner-Loop Speed on Outer Loop): In the servo-drive example, show that if the inner current loop is made infinitely fast (i.e. \( T_i(s) \to 1 \)), the speed loop sees exactly the mechanical plant \( G_\omega(s) = \frac{K_t}{J s + B} \). What approximation is used when we say that the inner loop is “fast enough”?
Solution:
From Section 2, with a finite inner loop we have \( I(s) = T_i(s)I_{\text{ref}}(s) \), so
\[ \Omega(s) = \frac{K_t}{J s + B} I(s) = \frac{K_t}{J s + B} T_i(s) I_{\text{ref}}(s). \]
If \( T_i(s) \to 1 \) (ideal current control), then
\[ \Omega(s) \to \frac{K_t}{J s + B} I_{\text{ref}}(s), \]
so the speed loop sees \( G_\omega(s) = \frac{K_t}{J s + B} \). In practice, the inner loop is considered “fast enough” when \( T_i(s) \approx 1 \) and \( S_i(s) \approx 0 \) for frequencies up to the speed-loop bandwidth. This means the magnitude and phase deviations of \( T_i \) from unity are small over the frequency range where the outer loop has significant gain.
Problem 3 (Cascade vs Single-Loop Disturbance Rejection): For the flow–temperature system of Section 3, compare the disturbance transfers \( T_{d,\text{single}}(s) \) and \( T_{d,\text{cas}}(s) \). Show explicitly that, for low frequencies where \( |C_F(s)G_F(s)| \gg 1 \), the cascade configuration reduces the disturbance effect by approximately a factor of \( |C_F(s)G_F(s)| \).
Solution:
Recall \( T_{d,\text{single}}(s) = \frac{G_T(s)}{1 + G_T(s)G_F(s)C_T(s)} \) and \( T_{d,\text{cas}}(s) = \frac{G_T(s)S_F(s)}{1 + G_T(s)T_F(s)C_T(s)} \) with \( S_F(s) = \frac{1}{1 + C_F(s)G_F(s)} \) and \( T_F(s) = \frac{C_F(s)G_F(s)}{1 + C_F(s)G_F(s)} \).
For low frequencies where \( |C_F(s)G_F(s)| \gg 1 \), we have the approximations
\[ S_F(s) \approx \frac{1}{C_F(s)G_F(s)},\qquad T_F(s) \approx 1. \]
Hence
\[ T_{d,\text{cas}}(s) \approx \frac{G_T(s)\frac{1}{C_F(s)G_F(s)}}{1 + G_T(s)C_T(s)} = \frac{1}{C_F(s)G_F(s)}\cdot \frac{G_T(s)}{1 + G_T(s)C_T(s)}. \]
Compared with the single-loop expression, the cascade structure introduces approximately the factor \( \frac{1}{C_F(s)G_F(s)} \) at low frequency, so the disturbance amplitude in temperature is reduced by roughly \( |C_F(s)G_F(s)| \) in magnitude where the inner flow loop has large gain. This quantifies the intuitive benefit of cascade control.
Problem 4 (Bandwidth Selection Rule-of-Thumb): Suppose a robot joint current loop has gain crossover frequency \( \omega_{ci} \) and phase margin \( \varphi_{mi} \). The speed loop is to be designed on top of this inner loop. Argue why choosing \( \omega_{co} \leq \frac{1}{4}\omega_{ci} \) for the speed loop is sensible from the viewpoint of interaction and robustness.
Solution:
The equivalent plant for the speed loop is \( G_\omega(s)T_i(s) \). Near the speed-loop crossover frequency \( \omega_{co} \), we would like \( T_i(s) \) to be close to unity and have nearly constant phase. If \( \omega_{co} \leq \frac{1}{4}\omega_{ci} \), then \( |L_i(j\omega_{co})| = |C_i(j\omega_{co})G_i(j\omega_{co})| \) is still large (because the inner loop only reaches unity gain at the much higher frequency \( \omega_{ci} \)), so \( |T_i(j\omega_{co})| \approx 1 \) and \( |S_i(j\omega_{co})| \approx 0 \).
Furthermore, because \( \omega_{co} \) lies well below the inner crossover, the phase of \( T_i(j\omega) \) varies slowly and adds little uncertainty to the speed-loop phase margin. Thus, the outer-loop robustness analysis can safely treat the inner loop as a nominal unity-gain block with small, bounded modeling error. Choosing the outer bandwidth closer to \( \omega_{ci} \) would increase interaction and reduce the validity of the single-loop design assumptions.
7. Summary
In this lesson we connected the theory of cascade and multiloop SISO control to concrete industrial patterns. Servo drives for robot joints use nested current, speed, and position loops to exploit natural time-scale separations, while thermal processes commonly employ flow–temperature cascade control to improve disturbance rejection. We derived closed-loop transfer functions for these structures, emphasizing the role of inner-loop sensitivity \( S_i(s) \) and equivalent plants \( G_{\text{eq}}(s) = G_o(s)T_i(s) \). Finally, we illustrated how such controllers are implemented in Python, C++, Java, MATLAB/Simulink, and Mathematica, preparing the ground for more advanced case studies and for future courses on multivariable and optimal control.
8. References
- Ziegler, J.G., & Nichols, N.B. (1942). Optimum settings for automatic controllers. Transactions of the ASME, 64(11), 759–768.
- Åström, K.J., & Hägglund, T. (1995). PID Controllers: Theory, Design, and Tuning. 2nd ed., Instrument Society of America.
- Shinskey, F.G. (1967). Multiloop and cascade control: Fundamental principles and analytical design. ISA Transactions, 6(4), 343–360.
- Skogestad, S., & Postlethwaite, I. (1996). Multivariable Feedback Control: Analysis and Design. Wiley. (Chapters on interaction and decentralized SISO loops.)
- Morari, M., & Zafiriou, E. (1989). Robust Process Control. Prentice Hall. (Cascade and multiloop robustness.)
- Maciejowski, J.M. (1984). Multivariable feedback design using classical techniques. IEE Proceedings, 131(6), 215–223.
- Franklin, G.F., Powell, J.D., & Emami-Naeini, A. (2015). Feedback Control of Dynamic Systems, 7th ed. Pearson. (Chapters on cascaded and servo control structures.)
- Goodwin, G.C., Graebe, S.F., & Salgado, M.E. (2001). Control System Design. Prentice Hall. (Frequency-domain loop-shaping and cascade.)