Chapter 4: Transfer Functions and Block Diagrams

Lesson 4: Block Diagram Reduction Techniques

This lesson develops a rigorous algebra of block diagrams for single-input single-output (SISO) linear time-invariant (LTI) systems. Starting from the definition of transfer functions and basic block diagram representation, we derive series, parallel, and feedback reductions, prove the equivalence of summing/pickoff point moves, and formulate algorithmic procedures that can be implemented in software. We then illustrate these procedures in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica, with remarks on their use in robotic control loops.

1. Conceptual Role of Block Diagram Reduction

A block diagram is a graphical encoding of algebraic relations among Laplace-domain signals. For SISO LTI systems with zero initial conditions, each block is typically labeled by a transfer function \( G(s) \), and interconnections are linear combinations and copies of signals. If \( R(s) \) is the Laplace transform of the input and \( Y(s) \) that of the output, the goal of block diagram reduction is to obtain an equivalent single block

\[ G_{\text{eq}}(s) = \frac{Y(s)}{R(s)} \]

such that, for any admissible input \( r(t) \), the time-domain output resulting from the original interconnection equals the output of the reduced block diagram. Because the system is linear and time-invariant, this equivalence can be established entirely in the Laplace domain through algebraic manipulation.

Reduction is essential for:

  • Analytical tasks such as stability analysis (via poles of \( G_{\text{eq}}(s) \)) and steady-state error computation.
  • Controller design, where a complex plant and sensor network are reduced to a simple equivalent plant for which standard design techniques (e.g., PID tuning) apply.
  • Robotics, where multiple actuators, gear trains, sensors, and filters are combined into a single joint-level transfer function before designing joint-space controllers.

2. Series, Parallel, and Feedback Interconnections

2.1 Series (Cascade) Connection

Consider two blocks in series with input \( R(s) \), intermediate signal \( X(s) \), and output \( Y(s) \):

\[ X(s) = G_1(s) R(s), \quad Y(s) = G_2(s) X(s). \]

Substituting the first equation into the second gives

\[ Y(s) = G_2(s) G_1(s) R(s) \quad\Rightarrow\quad \frac{Y(s)}{R(s)} = G_2(s) G_1(s). \]

Thus, a series connection is equivalent to a single block with transfer function \( G_{\text{eq}}(s) = \prod_i G_i(s) \).

2.2 Parallel Connection

For two blocks in parallel, both receive the same input \( R(s) \) and their outputs are summed:

\[ Y(s) = G_1(s)R(s) + G_2(s)R(s) = \bigl(G_1(s) + G_2(s)\bigr) R(s). \]

Hence, the equivalent transfer function is \( G_{\text{eq}}(s)=G_1(s)+G_2(s) \). More generally, the parallel combination of \( m \) blocks is \( \sum_{i=1}^m G_i(s) \).

2.3 Negative Feedback Connection

Consider the standard single-loop negative feedback structure with forward path \( G(s) \) and feedback path \( H(s) \). Let \( R(s) \) be the reference, \( Y(s) \) the output, and \( E(s) \) the error:

\[ E(s) = R(s) - H(s)Y(s), \quad Y(s) = G(s) E(s). \]

Eliminating \( E(s) \):

\[ Y(s) = G(s)\bigl(R(s) - H(s)Y(s)\bigr) = G(s)R(s) - G(s)H(s)Y(s). \]

Collecting terms in \( Y(s) \):

\[ \bigl(1 + G(s)H(s)\bigr) Y(s) = G(s)R(s) \quad\Rightarrow\quad \frac{Y(s)}{R(s)} = \frac{G(s)}{1 + G(s)H(s)}. \]

For positive feedback (i.e., the summing junction uses a plus sign in the feedback input), the sign changes to \( 1 - G(s)H(s) \) in the denominator.

2.4 Rational Formulas in Terms of Numerator and Denominator Polynomials

It is often convenient, especially for computation, to write transfer functions as rational functions of the complex variable \( s \):

\[ G(s) = \frac{N_G(s)}{D_G(s)}, \quad H(s) = \frac{N_H(s)}{D_H(s)}, \]

where \( N_G(s), D_G(s), N_H(s), D_H(s) \) are polynomials with real coefficients. Using this representation:

  • Series:

    \[ G_{\text{series}}(s) = \frac{N_1(s)}{D_1(s)} \frac{N_2(s)}{D_2(s)} = \frac{N_1(s) N_2(s)}{D_1(s) D_2(s)}. \]

  • Parallel:

    \[ G_{\text{parallel}}(s) = \frac{N_1(s)}{D_1(s)} + \frac{N_2(s)}{D_2(s)} = \frac{N_1(s)D_2(s) + N_2(s)D_1(s)}{D_1(s)D_2(s)}. \]

  • Negative feedback:

    \[ G_{\text{cl}}(s) = \frac{\dfrac{N_G(s)}{D_G(s)}}{1 + \dfrac{N_G(s)}{D_G(s)} \dfrac{N_H(s)}{D_H(s)}} = \frac{N_G(s)D_H(s)}{D_G(s)D_H(s) + N_G(s)N_H(s)}. \]

These formulas directly translate into polynomial operations (convolution for multiplication, addition with proper alignment for sums), which we exploit in coding sections.

3. Moving Summing and Pickoff Points

Difficult block diagrams often contain summing junctions and pickoff (branch) points that prevent immediate application of series, parallel, or feedback formulas. Standard reduction techniques rely on algebraic equivalence theorems that allow us to move these junctions across blocks, at the cost of inserting or removing blocks with appropriate transfer functions.

3.1 Moving a Summing Point Across a Block

Suppose we have an input \( R(s) \) and a disturbance \( D(s) \), summed before a block \( G(s) \):

\[ Y(s) = G(s)\bigl(R(s) + D(s)\bigr) = G(s)R(s) + G(s)D(s). \]

This is equivalent to a diagram where \( R(s) \) alone feeds \( G(s) \), and the disturbance is injected after the block, but scaled by \( G(s) \):

\[ Y(s) = G(s)R(s) + G(s)D(s). \]

Rule (Summing point after block): moving a summing junction from the input side to the output side of a block multiplies the other input(s) of the summing junction by the block transfer function \( G(s) \).

Conversely, moving the summing point from the output back to the input (when algebraically permissible) divides the additional signals by \( G(s) \), i.e., requires an explicit block with transfer function \( 1/G(s) \) in those paths.

3.2 Moving a Pickoff Point Across a Block

Consider a pickoff point at the output of a block \( G(s) \), producing a copied signal \( Z(s) \):

\[ Y(s) = G(s)X(s), \quad Z(s) = Y(s) = G(s)X(s). \]

If we move the pickoff to the input side of \( G(s) \) but wish to keep \( Z(s) \) unchanged, we must insert a block with transfer function \( G(s) \) in the branch:

\[ Z(s) = G(s)X(s) \]

with \( X(s) \) now taken from the new pickoff point.

Similarly, moving a pickoff from the input to the output requires dividing by \( G(s) \) in the branch if we want the branch signal to remain the same; this may be undesirable if \( G(s) \) is not easily invertible, so in practice we choose moves that insert only causal, proper blocks.

3.3 Algebraic Justification

All these moves preserve the mapping \( R(s) \mapsto Y(s) \) (and other outputs of interest) because they correspond to inserting factors like \( G(s)G^{-1}(s) = 1 \) in paths that do not change the overall algebraic relation between input and output. The linearity and time invariance of the system guarantee that signals can be added and split without cross-coupling beyond what is represented in the diagram.

4. Systematic Reduction Workflow

Complex block diagrams are reduced by iteratively applying the rules from Sections 2 and 3. A typical workflow that is implemented in many control toolboxes is:

flowchart TD
  A["Start from full block diagram (R to Y)"] --> B["Locate obvious series blocks and reduce them"]
  B --> C["Locate parallel branches and reduce them"]
  C --> D["Identify innermost feedback loops without nested loops"]
  D --> E["Reduce each loop using G/(1+GH) (negative feedback)"]
  E --> F["Move summing/pickoff points to expose new series/parallel/feedback patterns"]
  F --> G["Repeat algebraic reductions until a single equivalent G_eq(s) remains"]
        

This algorithm terminates for any finite diagram of LTI blocks and summing/pickoff points. Different reduction orders lead to algebraically equivalent \( G_{\text{eq}}(s) \) (up to algebraic simplification), though intermediate expressions can differ in degree or factorization.

5. Polynomial Representation and Operations

For computational purposes, it is standard to represent transfer functions by their numerator and denominator coefficients. For example, an \( n \)-th order denominator and an \( m \)-th order numerator are written as

\[ G(s) = \frac{b_m s^m + b_{m-1} s^{m-1} + \dots + b_0} {a_n s^n + a_{n-1} s^{n-1} + \dots + a_0}, \]

and stored as coefficient vectors \( \mathbf{b} = [b_m, \dots, b_0] \) and \( \mathbf{a} = [a_n, \dots, a_0] \).

Using this representation:

  • Multiplication of transfer functions corresponds to polynomial convolution of numerators and denominators.
  • Addition of transfer functions corresponds to computing a common denominator and adding appropriately scaled numerators.
  • Feedback reduction combines both operations as in Section 2.4.

These operations will appear explicitly in our multi-language implementations.

6. Python Implementation — Block Diagram Reduction

In Python, the python-control library (control package) provides high-level operations series, parallel, and feedback. These are widely used in robotics to model joint actuators, sensors, and controllers in libraries that interface with ROS (Robot Operating System).


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

# Example: simple robotic joint actuator model (linearized)
# Plant: Gp(s) = K / (J s^2 + b s)
J = 0.01   # effective inertia
b = 0.1    # viscous friction
K = 1.0    # motor torque constant

s = ct.TransferFunction.s
Gp = K / (J * s**2 + b * s)

# Controller: proportional gain Kc
Kc = 20.0
Gc = Kc

# Sensor: encoder with gain Ks
Ks = 1.0
H = Ks

# Forward path is series of controller and plant
G_forward = ct.series(Gc, Gp)

# Closed-loop transfer function from reference to output (negative feedback)
T = ct.feedback(G_forward, H)  # G_forward / (1 + G_forward*H)

print("Closed-loop transfer function T(s) = Y(s)/R(s):")
print(T)

# --- Low-level implementation using polynomials ---

def convolve(a, b):
    """Convolution of two 1D coefficient arrays."""
    return np.convolve(a, b)

def series(num1, den1, num2, den2):
    num = convolve(num1, num2)
    den = convolve(den1, den2)
    return num, den

def parallel(num1, den1, num2, den2):
    den = convolve(den1, den2)
    num1_ext = convolve(num1, den2)
    num2_ext = convolve(num2, den1)
    num = num1_ext + num2_ext
    return num, den

def feedback(numG, denG, numH=None, denH=None):
    """
    Negative feedback: G / (1 + G H)
    If H is None, assume unity feedback H(s) = 1.
    """
    if numH is None or denH is None:
        numH = np.array([1.0])
        denH = np.array([1.0])

    num = convolve(numG, denH)
    den1 = convolve(denG, denH)
    den2 = convolve(numG, numH)
    # Pad and add denominators
    if den1.size < den2.size:
        den1 = np.pad(den1, (den2.size - den1.size, 0))
    elif den2.size < den1.size:
        den2 = np.pad(den2, (den1.size - den2.size, 0))
    den = den1 + den2
    return num, den

# Example: numerically define Gp(s) and unity feedback
num_Gp = np.array([K])
den_Gp = np.array([J, b, 0.0])  # J s^2 + b s

# Controller is a gain Kc
num_Gc = np.array([Kc])
den_Gc = np.array([1.0])

# Series: controller * plant
num_forward, den_forward = series(num_Gc, den_Gc, num_Gp, den_Gp)

# Closed-loop with unity sensor (H(s) = 1)
num_cl, den_cl = feedback(num_forward, den_forward)

print("Closed-loop numerator coefficients:", num_cl)
print("Closed-loop denominator coefficients:", den_cl)
      

In robotic applications, such code can be wrapped into ROS nodes that compute or visualize closed-loop characteristics for each joint or actuator chain.

7. C++ Implementation — Polynomial-Based Reduction

In C++, we can represent transfer functions using standard containers such as std::vector<double>. In robotics, similar structures underlie control components in frameworks like ROS (ros_control) and libraries using Eigen for linear algebra.


#include <vector>
#include <iostream>
#include <algorithm>

struct TransferFunction {
    std::vector<double> num; // numerator coefficients (descending powers of s)
    std::vector<double> den; // denominator coefficients
};

std::vector<double> convolve(const std::vector<double>& a,
                               const std::vector<double>& b) {
    std::vector<double> c(a.size() + b.size() - 1, 0.0);
    for (std::size_t i = 0; i < a.size(); ++i) {
        for (std::size_t j = 0; j < b.size(); ++j) {
            c[i + j] += a[i] * b[j];
        }
    }
    return c;
}

std::vector<double> addPoly(const std::vector<double>& a,
                              const std::vector<double>& b) {
    std::size_t n = std::max(a.size(), b.size());
    std::vector<double> c(n, 0.0);
    // Right-align coefficients
    for (std::size_t i = 0; i < a.size(); ++i) {
        c[n - a.size() + i] += a[i];
    }
    for (std::size_t i = 0; i < b.size(); ++i) {
        c[n - b.size() + i] += b[i];
    }
    return c;
}

TransferFunction series(const TransferFunction& G1,
                       const TransferFunction& G2) {
    TransferFunction G;
    G.num = convolve(G1.num, G2.num);
    G.den = convolve(G1.den, G2.den);
    return G;
}

TransferFunction parallel(const TransferFunction& G1,
                         const TransferFunction& G2) {
    TransferFunction G;
    std::vector<double> den = convolve(G1.den, G2.den);
    std::vector<double> num1 = convolve(G1.num, G2.den);
    std::vector<double> num2 = convolve(G2.num, G1.den);
    G.den = den;
    G.num = addPoly(num1, num2);
    return G;
}

// Negative feedback: G / (1 + G H)
TransferFunction feedback(const TransferFunction& G,
                          const TransferFunction& H) {
    TransferFunction T;
    std::vector<double> num = convolve(G.num, H.den);
    std::vector<double> den1 = convolve(G.den, H.den);
    std::vector<double> den2 = convolve(G.num, H.num);
    T.num = num;
    T.den = addPoly(den1, den2);
    return T;
}

int main() {
    // Example: DC motor-like plant Gp(s) = K / (J s^2 + b s)
    double J = 0.01;
    double b = 0.1;
    double K = 1.0;
    double Kc = 20.0; // proportional controller

    TransferFunction Gp{ {K}, {J, b, 0.0} }; // num, den
    TransferFunction Gc{ {Kc}, {1.0} };

    // Forward path
    TransferFunction Gforward = series(Gc, Gp);

    // Sensor H(s) = 1
    TransferFunction H{ {1.0}, {1.0} };

    // Closed-loop
    TransferFunction Tcl = feedback(Gforward, H);

    std::cout << "Closed-loop numerator: ";
    for (double c : Tcl.num) std::cout << c << " ";
    std::cout << "\nClosed-loop denominator: ";
    for (double c : Tcl.den) std::cout << c << " ";
    std::cout << std::endl;

    return 0;
}
      

In a robotic control stack, such code can be wrapped into a library that computes equivalent transfer functions for cascaded actuators, gear trains, and filters before tuning PID gains in ros_control.

8. Java Implementation — Transfer Function Utilities

Java-based robotics frameworks, such as those used in educational robotics (e.g., WPILib), frequently encapsulate control logic using transfer function or state-space abstractions. Below is a lightweight Java utility for series, parallel, and feedback combination, using arrays for polynomial coefficients.


public class TransferFunction {
    public double[] num; // numerator (descending powers of s)
    public double[] den; // denominator

    public TransferFunction(double[] num, double[] den) {
        this.num = num;
        this.den = den;
    }
}

public class TFAlgebra {

    public static double[] convolve(double[] a, double[] b) {
        double[] c = new double[a.length + b.length - 1];
        for (int i = 0; i < a.length; ++i) {
            for (int j = 0; j < b.length; ++j) {
                c[i + j] += a[i] * b[j];
            }
        }
        return c;
    }

    public static double[] addPoly(double[] a, double[] b) {
        int n = Math.max(a.length, b.length);
        double[] c = new double[n];
        // Right-align
        for (int i = 0; i < a.length; ++i) {
            c[n - a.length + i] += a[i];
        }
        for (int i = 0; i < b.length; ++i) {
            c[n - b.length + i] += b[i];
        }
        return c;
    }

    public static TransferFunction series(TransferFunction G1,
                                          TransferFunction G2) {
        double[] num = convolve(G1.num, G2.num);
        double[] den = convolve(G1.den, G2.den);
        return new TransferFunction(num, den);
    }

    public static TransferFunction parallel(TransferFunction G1,
                                            TransferFunction G2) {
        double[] den = convolve(G1.den, G2.den);
        double[] num1 = convolve(G1.num, G2.den);
        double[] num2 = convolve(G2.num, G1.den);
        double[] num = addPoly(num1, num2);
        return new TransferFunction(num, den);
    }

    // Negative feedback: G / (1 + G H)
    public static TransferFunction feedback(TransferFunction G,
                                            TransferFunction H) {
        double[] num = convolve(G.num, H.den);
        double[] den1 = convolve(G.den, H.den);
        double[] den2 = convolve(G.num, H.num);
        double[] den = addPoly(den1, den2);
        return new TransferFunction(num, den);
    }

    public static void main(String[] args) {
        // Example: P-controlled motor-like plant
        double J = 0.01, b = 0.1, K = 1.0, Kc = 20.0;

        TransferFunction Gp = new TransferFunction(
            new double[]{K},
            new double[]{J, b, 0.0}
        );
        TransferFunction Gc = new TransferFunction(
            new double[]{Kc},
            new double[]{1.0}
        );
        TransferFunction Gforward = series(Gc, Gp);
        TransferFunction H = new TransferFunction(
            new double[]{1.0},
            new double[]{1.0}
        );
        TransferFunction Tcl = feedback(Gforward, H);

        System.out.print("Closed-loop numerator: ");
        for (double c : Tcl.num) System.out.print(c + " ");
        System.out.println();
        System.out.print("Closed-loop denominator: ");
        for (double c : Tcl.den) System.out.print(c + " ");
        System.out.println();
    }
}
      

In Java-based robotics, this reduction logic can be integrated with higher-level libraries (e.g., WPILib) to analytically study continuous approximations to the discrete controllers actually executed on hardware.

9. MATLAB/Simulink Implementation — Built-in Operations

MATLAB's Control System Toolbox and Simulink offer built-in functions and graphical tools for block diagram reduction. These are heavily used in robotics via the Robotics System Toolbox and Simscape Multibody, where plant models of robot manipulators and mobile robots are connected to controllers using block diagrams.


% Define Laplace variable and basic transfer functions
s = tf('s');

% Simple robotic joint: Gp(s) = K / (J s^2 + b s)
J = 0.01;
b = 0.1;
K = 1.0;
Gp = K / (J*s^2 + b*s);

% Controller: proportional gain
Kc = 20;
Gc = Kc;

% Sensor gain
Ks = 1;
H = Ks;

% Series connection: controller then plant
Gforward = series(Gc, Gp);  % or simply: Gforward = Gc*Gp;

% Closed-loop from reference to output (negative feedback)
T = feedback(Gforward, H);  % shorthand for Gforward / (1 + Gforward*H)

% Display transfer function and step response
T = minreal(T);  % cancel any common factors
disp('Closed-loop transfer function T(s) = Y(s)/R(s):');
T

figure;
step(T);
title('Closed-loop step response of joint position');

% In Simulink, an equivalent model can be built using blocks:
%  - 'Gain' blocks for Kc and Ks
%  - 'Transfer Fcn' block for Gp(s)
%  - 'Sum' blocks for summing junctions
%  - 'Scope' for visualizing Y(t)
% and the reduction is implicit in the underlying simulation.
      

Simulink can also export linearized models of nonlinear robotic systems as transfer functions or state-space systems, which are then reduced using the same algebra.

10. Wolfram Mathematica Implementation — Symbolic Reduction

Wolfram Mathematica is often used in robotics research to symbolically derive dynamic models and simplify closed-loop transfer functions. Using symbolic functions of \( s \), we can encode the same series, parallel, and feedback operations:


(* Define symbolic parameters and Laplace variable *)
ClearAll["Global`*"];
J =.; b =.; K =.; Kc =.; Ks =.;
SetAttributes[{J, b, K, Kc, Ks}, Constant];

(* Plant: Gp(s) = K / (J s^2 + b s) *)
Gp[s_] := K/(J s^2 + b s);

(* Controller: proportional *)
Gc[s_] := Kc;

(* Sensor gain *)
H[s_] := Ks;

(* Series connection: Gforward(s) = Gc(s) Gp(s) *)
Gforward[s_] := Gc[s] Gp[s];

(* Closed-loop transfer: T(s) = Gforward / (1 + Gforward*H) *)
T[s_] := Simplify[Gforward[s]/(1 + Gforward[s] H[s])];

(* Example numeric substitution *)
Jval = 0.01; bval = 0.1; Kval = 1.0; Kcval = 20.0; Ksval = 1.0;
Tnum[s_] = T[s] /. {J -> Jval, b -> bval, K -> Kval,
                    Kc -> Kcval, Ks -> Ksval} // Together

(* Extract numerator and denominator polynomials in s *)
num = Numerator[Tnum[s]];
den = Denominator[Tnum[s]];

{num, den}
      

Such symbolic workflows allow one to derive compact closed-form transfer functions for complex robotic systems (e.g., multi-link manipulators) before numerical controller tuning.

11. Problems and Solutions

Problem 1 (Series and Parallel Reduction): A block diagram has input \( R(s) \) feeding two blocks \( G_1(s) \) and \( G_2(s) \) in parallel. Their outputs are summed and then passed through \( G_3(s) \) to produce \( Y(s) \). Derive the equivalent transfer function \( G_{\text{eq}}(s) = Y(s)/R(s) \).

Solution:

First, write the output of the parallel pair:

\[ U(s) = G_1(s)R(s) + G_2(s)R(s) = \bigl(G_1(s) + G_2(s)\bigr)R(s). \]

The signal \( U(s) \) then passes through \( G_3(s) \):

\[ Y(s) = G_3(s) U(s) = G_3(s)\bigl(G_1(s) + G_2(s)\bigr) R(s). \]

Therefore,

\[ G_{\text{eq}}(s) = \frac{Y(s)}{R(s)} = G_3(s) \bigl(G_1(s) + G_2(s)\bigr). \]


Problem 2 (Moving a Summing Point): In a block diagram, the error signal \( E(s) = R(s) - D(s) \) is formed by subtracting a disturbance \( D(s) \) from the reference \( R(s) \), and then passed through a block \( G(s) \) to produce \( Y(s) \). Show that this is equivalent to a diagram in which \( R(s) \) alone is passed through \( G(s) \) and \( D(s) \) is subtracted at the output, but scaled by \( G(s) \).

Solution:

Original structure:

\[ E(s) = R(s) - D(s), \quad Y(s) = G(s)E(s) = G(s)\bigl(R(s) - D(s)\bigr) = G(s)R(s) - G(s)D(s). \]

Consider the modified structure where \( R(s) \) is first passed through \( G(s) \), giving \( Y_0(s) = G(s)R(s) \), and then \( G(s)D(s) \) is subtracted:

\[ Y(s) = Y_0(s) - G(s)D(s) = G(s)R(s) - G(s)D(s), \]

which is identical to the original expression. Thus, moving the summing point from the input to the output requires scaling the disturbance by \( G(s) \).


Problem 3 (Unity Feedback with Series Blocks): Consider a unity feedback system in which the forward path consists of two series blocks \( G_1(s) \) and \( G_2(s) \). The feedback path is unity (\( H(s) = 1 \)). Derive the closed-loop transfer function \( T(s) = Y(s)/R(s) \).

Solution:

First reduce the series connection:

\[ G_{\text{forward}}(s) = G_2(s) G_1(s). \]

With unity feedback, the closed-loop transfer function is

\[ T(s) = \frac{G_{\text{forward}}(s)}{1 + G_{\text{forward}}(s)} = \frac{G_2(s)G_1(s)}{1 + G_2(s)G_1(s)}. \]

This result is independent of whether we view the cascade as \( G_1(s)G_2(s) \) or \( G_2(s)G_1(s) \), because multiplication of transfer functions is commutative.


Problem 4 (Nested Feedback Loop): Consider the following nested feedback structure:

  • The inner loop has forward path \( G_2(s) \) and unity feedback.
  • The outer loop has forward path \( G_1(s) \) followed by the inner closed-loop block, and feedback path \( H(s) \).

The diagram can be visualized as:

flowchart LR
  R["R(s)"] --> E1["Outer error"]
  E1 --> G1["G1(s)"]
  G1 --> E2["Inner error"]
  E2 --> G2["G2(s)"]
  G2 --> Y["Y(s)"]
  Y -->|"feedback H(s)"| E1
  Y -->|"unity feedback"| E2
      

Derive \( T(s) = Y(s)/R(s) \) in terms of \( G_1(s), G_2(s), H(s) \).

Solution:

First reduce the inner loop (unity feedback):

\[ G_{\text{inner}}(s) = \frac{G_2(s)}{1 + G_2(s)}. \]

The outer forward path is then \( G_{\text{outer}}(s) = G_1(s) G_{\text{inner}}(s) \). Applying the general feedback formula with feedback path \( H(s) \):

\[ T(s) = \frac{G_{\text{outer}}(s)} {1 + G_{\text{outer}}(s) H(s)} = \frac{G_1(s)\dfrac{G_2(s)}{1 + G_2(s)}} {1 + G_1(s)\dfrac{G_2(s)}{1 + G_2(s)} H(s)}. \]

Multiply numerator and denominator by \( 1 + G_2(s) \):

\[ T(s) = \frac{G_1(s)G_2(s)} {1 + G_2(s) + G_1(s)G_2(s)H(s)}. \]

This illustrates the usefulness of reducing inner loops first and then treating the result as a single block in an outer loop.


Problem 5 (Numerical Closed-Loop Calculation): A plant has transfer function \( G_p(s) = \dfrac{10}{0.5 s^2 + s} \) and is controlled by a proportional controller \( G_c(s) = K_c \) with unity feedback \( H(s) = 1 \). For \( K_c = 5 \), compute the closed-loop transfer function \( T(s) = Y(s)/R(s) \).

Solution:

First form the forward path:

\[ G_{\text{forward}}(s) = G_c(s) G_p(s) = 5 \cdot \frac{10}{0.5 s^2 + s} = \frac{50}{0.5 s^2 + s}. \]

With unity feedback, the closed-loop transfer function is

\[ T(s) = \frac{G_{\text{forward}}(s)} {1 + G_{\text{forward}}(s)} = \frac{\dfrac{50}{0.5 s^2 + s}} {1 + \dfrac{50}{0.5 s^2 + s}}. \]

Multiply numerator and denominator by \( 0.5 s^2 + s \):

\[ T(s) = \frac{50}{0.5 s^2 + s + 50}. \]

Equivalently, multiplying numerator and denominator by 2,

\[ T(s) = \frac{100}{s^2 + 2 s + 100}, \]

which is a standard second-order closed-loop system with natural frequency and damping that can be analyzed in subsequent chapters.

12. Summary

In this lesson, we developed a systematic algebra for block diagrams of LTI systems. We derived and proved formulas for series, parallel, and feedback interconnections, and established rules for moving summing and pickoff points. We then formulated an algorithmic workflow for reducing arbitrary SISO block diagrams to a single equivalent transfer function \( G_{\text{eq}}(s) = Y(s)/R(s) \). Finally, we implemented these ideas in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica, emphasizing their role in modeling robotic control loops. These tools and concepts form the basis for later analyses of stability, performance, and controller design.

13. References

  1. Black, H. S. (1934). Stabilized feedback amplifiers. Bell System Technical Journal, 13(1), 1–18.
  2. Nyquist, H. (1932). Regeneration theory. Bell System Technical Journal, 11(1), 126–147.
  3. Bode, H. W. (1940). Relations between attenuation and phase in feedback amplifier design. Bell System Technical Journal, 19(3), 421–454.
  4. Mason, S. J. (1953). Feedback theory—Some properties of signal flow graphs. Proceedings of the IRE, 41(9), 1144–1156.
  5. Truxal, J. G. (1955). Automatic feedback control system synthesis. Transactions of the American Institute of Electrical Engineers, 74(6), 1135–1144.
  6. Zadeh, L. A. (1952). From circuit theory to system theory. Proceedings of the IRE, 50(5), 856–865.
  7. Desoer, C. A. (1963). Notes for a second course on linear systems. IEEE Transactions on Circuit Theory, 10(3), 330–337.
  8. Wolovich, W. A. (1967). Linear multivariable systems. Applied Mathematics and Computation, 2(2), 99–128.