FEEDBACK

This function forms the closed-loop interconnection of a plant G and a feedback path H. It is useful for analyzing the equivalent transfer function of standard control architectures without manually expanding the loop algebra.

For negative feedback, the closed-loop transfer function is

T(s) = \frac{G(s)}{1 + G(s)H(s)}

For positive feedback, the denominator changes sign to 1 - G(s)H(s). The wrapper accepts both systems as 2-row coefficient arrays of the form [[numerator], [denominator]], applies either negative or positive feedback, and returns the resulting transfer function as the library’s formatted string.

Excel Usage

=FEEDBACK(sysdata_plant, sysdata_feedback, positive)
  • sysdata_plant (list[list], required): Numerator and denominator of the plant G.
  • sysdata_feedback (list[list], optional, default: [[1],[1]]): Numerator and denominator of the feedback path H.
  • positive (bool, optional, default: false): Set to true for positive feedback. Defaults to false (negative feedback).

Returns (str): String representation of the resulting closed-loop system.

Example 1: Unity negative feedback

Inputs:

sysdata_plant sysdata_feedback positive
1 1 false
1 1

Excel formula:

=FEEDBACK({1;1,1}, {1;1}, FALSE)

Expected output:

"<TransferFunction>: sys[2]\nInputs (1): ['u[0]']\nOutputs (1): ['y[0]']\n\n 1\n -----\n s + 2"

Example 2: Negative feedback using the default unity path

Inputs:

sysdata_plant positive
2 false
1

Excel formula:

=FEEDBACK({2;1,2}, FALSE)

Expected output:

"<TransferFunction>: sys[5]\nInputs (1): ['u[0]']\nOutputs (1): ['y[0]']\n\n 2\n -----\n s + 4"

Example 3: Positive feedback on a first-order plant

Inputs:

sysdata_plant sysdata_feedback positive
1 1 true
1 1

Excel formula:

=FEEDBACK({1;1,3}, {1;1}, TRUE)

Expected output:

"<TransferFunction>: sys[8]\nInputs (1): ['u[0]']\nOutputs (1): ['y[0]']\n\n 1\n -----\n s + 2"

Example 4: Dynamic feedback path with first-order sensor dynamics

Inputs:

sysdata_plant sysdata_feedback positive
5 1 false
1 1

Excel formula:

=FEEDBACK({5;1,4}, {1;1,2}, FALSE)

Expected output:

"<TransferFunction>: sys[11]\nInputs (1): ['u[0]']\nOutputs (1): ['y[0]']\n\n 5 s + 10\n --------------\n s^2 + 6 s + 13"

Python Code

Show Code
import control as ct

def feedback(sysdata_plant, sysdata_feedback=[[1], [1]], positive=False):
    """
    Feedback interconnection of two LTI systems.

    See: https://python-control.readthedocs.io/en/latest/generated/control.feedback.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        sysdata_plant (list[list]): Numerator and denominator of the plant G.
        sysdata_feedback (list[list], optional): Numerator and denominator of the feedback path H. Default is [[1], [1]].
        positive (bool, optional): Set to true for positive feedback. Defaults to false (negative feedback). Default is False.

    Returns:
        str: String representation of the resulting closed-loop system.
    """
    try:
      def to2d(value):
        return [[value]] if not isinstance(value, list) else value

      def parse_coefficients(row, label):
        if not isinstance(row, list):
          return None, f"Error: {label} must be a list of coefficients"

        coefficients = []
        for item in row:
          if item is None or str(item).strip() == "":
            continue
          try:
            coefficients.append(float(item))
          except (TypeError, ValueError):
            return None, f"Error: {label} contains a non-numeric coefficient"

        if not coefficients:
          return None, f"Error: {label} must contain at least one numeric coefficient"

        return coefficients, None

      def to_tf(data, label):
        matrix = to2d(data)
        if not isinstance(matrix, list) or len(matrix) < 2:
          return None, f"Error: {label} must be provided as [[numerator], [denominator]]"

        numerator, error = parse_coefficients(matrix[0], f"{label} numerator")
        if error:
          return None, error

        denominator, error = parse_coefficients(matrix[1], f"{label} denominator")
        if error:
          return None, error

        return ct.tf(numerator, denominator), None

      plant, error = to_tf(sysdata_plant, "sysdata_plant")
      if error:
        return error

      feedback_sys, error = to_tf(sysdata_feedback, "sysdata_feedback")
      if error:
        return error

      sign = 1 if positive else -1

      res = ct.feedback(plant, feedback_sys, sign=sign)
      return str(res)
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Numerator and denominator of the plant G.
Numerator and denominator of the feedback path H.
Set to true for positive feedback. Defaults to false (negative feedback).