Time-Domain Response & Steady-State Error

How a control loop behaves in time. Learn standard test inputs, first- and second-order responses, poles and their meaning, damping ratio and natural frequency, rise time, peak time, overshoot and settling time, dominant poles, system type and error constants (Kp, Kv, Ka), and steady-state error — with Python formulas for every specification.

Performance specifications are usually written in the time domain: 'reach the setpoint within 2 s, overshoot less than 10%, no steady error'. This lesson connects those words to pole locations and loop gain.

Second-order systems are the reference: most closed loops behave approximately like one, dominated by a pair of complex poles.

An analogy

A car's suspension shows all the specs: a soft, under-damped suspension bounces (overshoot), a stiff over-damped one is slow, and a critically damped one settles quickly without bouncing.

Test inputs and responses

Step (sudden setpoint change), ramp (tracking a moving target), impulse (a shock) and sinusoid (vibration) reveal different properties. The response has a transient part (dies away if stable) and a steady-state part.

Poles tell the story

Where the closed-loop poles lie in the s-plane determines behaviour:

System type and steady-state error

The type of a unity-feedback loop is the number of pure integrators (poles at s = 0) in G(s). Type 0: finite step error. Type 1: zero step error, finite ramp error. Type 2: zero ramp error. That's why PI control (adding an integrator) removes offset, and why servo systems tracking ramps need more integrators.

Zeros, higher order and real loops

Zeros change the response shape: a left-half-plane zero adds overshoot, a right-half-plane zero (inverse response, e.g. boiler drum 'swell') makes the output first move the wrong way and limits achievable speed. Higher-order systems are approximated by their dominant poles when the others are ≥ 5× further left. Dead time adds no poles but a phase lag that dominates process-control performance.

Formulas

Worked example: Overshoot spec → ζ

Given: Max overshoot 10%

Find: Minimum ζ.

Answer: ζ ≥ 0.59

Worked example: Settling time

Given: ζ = 0.5, ωₙ = 10

Find: t_s (2%).

Answer: 0.8 s

Worked example: Ramp error

Given: G(s) = 20/(s(s + 4)), unit ramp

Find: e_ss.

Answer: e_ss = 1/5 = 0.2

Second-order specifications and steady-state error

import math
# Second-order step response specifications
def specs(zeta, wn):
    wd = wn * math.sqrt(1 - zeta**2)
    Mp = math.exp(-zeta * math.pi / math.sqrt(1 - zeta**2)) * 100
    tp = math.pi / wd
    ts = 4 / (zeta * wn)
    tr = (math.pi - math.acos(zeta)) / wd
    return Mp, tp, ts, tr
for z in (0.2, 0.5, 0.707):
    Mp, tp, ts, tr = specs(z, 10.0)
    print(f"zeta={z:5.3f}, wn=10: overshoot {Mp:5.1f}%, tr {tr:.3f} s, tp {tp:.3f} s, ts(2%) {ts:.2f} s")
# steady-state error of a type-0 loop with K = 9 to a unit step
K = 9
print(f"type-0, Kp={K}: e_ss = 1/(1+Kp) = {1/(1+K):.3f}")
# zeta=0.200, wn=10: overshoot  52.7%, tr 0.181 s, tp 0.321 s, ts(2%) 2.00 s
# zeta=0.500, wn=10: overshoot  16.3%, tr 0.242 s, tp 0.363 s, ts(2%) 0.80 s
# zeta=0.707, wn=10: overshoot   4.3%, tr 0.333 s, tp 0.444 s, ts(2%) 0.57 s
# type-0, Kp=9: e_ss = 1/(1+Kp) = 0.100

Damping ratio alone sets overshoot; ζωₙ (the real part of the poles) sets settling time. ζ ≈ 0.7 is a popular compromise. A type-0 loop always leaves a step error — integral action (a pole at s = 0) removes it.

Common mistakes

Applications

Key takeaways

Going further