Open Loop vs Closed Loop

Open loop: apply a fixed input and hope the output is correct. Closed loop: measure the output, compare to the desired value, and adjust. This feedback principle is the foundation of all control systems.

Why It Matters

Almost nothing in the real world is predictable enough for open loop control. Motors vary with temperature, loads change, disturbances happen. Closed loop control is how thermostats, cruise control, quadcopters, and industrial robots maintain desired behavior despite uncertainty. Understanding the feedback loop structure is prerequisite to PID, Kalman filtering, and every other control technique.

Open Loop Control

Reference → Controller → Plant → Output

The controller computes the input based solely on the desired output, with no knowledge of what actually happened.

Examples:

  • Microwave: runs for 2 minutes regardless of food temperature
  • Stepper motor: send 200 pulses for one revolution (assumes no steps lost)
  • Sprinkler timer: waters for 30 minutes whether the ground is wet or dry

Problems: no way to detect or correct errors, disturbances, or plant variations.

Closed Loop (Feedback) Control

Reference ──→ [+] ──→ Controller ──→ Plant ──→ Output
               ↑ [-]                              │
               └────────── Sensor ←───────────────┘

error = reference - measurement

The sensor measures the actual output and feeds it back. The controller reacts to the error (difference between desired and actual), continuously adjusting.

Examples:

  • Thermostat: measures room temperature, turns heater on/off to maintain 22°C
  • Cruise control: measures speed, adjusts throttle to maintain 100 km/h
  • Quadcopter: IMU measures attitude, adjusts motor speeds 1000× per second

Why Feedback Works

PropertyOpen LoopClosed Loop
Disturbance rejectionNoneController compensates
Plant variation toleranceSensitiveRobust (feedback corrects)
Steady-state accuracyDepends on calibrationCan be exact (integral action)
Stability riskLow (no feedback loop)Can oscillate if designed poorly
ComplexitySimpleRequires sensor + controller

Disturbance Rejection

Open loop: a door opens, cold air enters, room gets cold. Controller doesn’t know.

Closed loop: sensor detects temperature drop → error increases → heater output increases → temperature returns to setpoint.

Sensitivity to Plant Variations

A motor’s torque constant changes with temperature. An open loop controller sends the same voltage and gets different speeds. A closed loop controller measures speed and adjusts — it doesn’t need to know why the plant changed.

Feedback Types

Negative feedback (the norm): output is subtracted from reference. Error drives correction. Stabilizing.

Positive feedback: output is added to reference. Error amplifies itself. Destabilizing — but useful for:

  • Schmitt triggers (hysteresis in comparators)
  • Oscillators (deliberately self-exciting circuits)
  • Latches (bistable flip-flops)

Block Diagram Algebra

Control systems are drawn as block diagrams. Three fundamental combinations:

Series:     G₁ → G₂     = G₁(s) × G₂(s)

Parallel:   G₁ ──┐
                  + ──→   = G₁(s) + G₂(s)
            G₂ ──┘

Negative feedback:
            R → [+] → G → Y     Closed loop TF = G(s) / (1 + G(s)H(s))
                 ↑[-]     │
                 └── H ←──┘

The closed loop transfer function G/(1+GH) is the most important formula in control theory. When GH is large, the output ≈ 1/H — the system behavior is determined by the sensor, not the plant. This is why feedback makes systems robust.

Python: Comparing Open vs Closed Loop

import numpy as np
import matplotlib.pyplot as plt
 
dt, steps = 0.01, 500
setpoint = 1.0
Kp = 5.0
 
# Simple first-order plant: y_dot = -y + u
# Open loop: u = setpoint (constant)
y_open = 0.0
open_hist = []
for _ in range(steps):
    u = setpoint
    y_open += (-y_open + u) * dt
    open_hist.append(y_open)
 
# Closed loop: u = Kp * (setpoint - y)
y_closed = 0.0
closed_hist = []
for _ in range(steps):
    error = setpoint - y_closed
    u = Kp * error
    y_closed += (-y_closed + u) * dt
    closed_hist.append(y_closed)
 
t = np.arange(steps) * dt
plt.plot(t, open_hist, label='Open loop')
plt.plot(t, closed_hist, label='Closed loop (Kp=5)')
plt.axhline(y=setpoint, color='r', linestyle='--', label='Setpoint')
plt.xlabel('Time (s)'); plt.ylabel('Output'); plt.legend(); plt.grid(); plt.show()