Bode plots and loop shaping: place gain and phase together

Read Bode plots and shape a position-control loop with a lead controller. Calculate crossover and phase margin, compare closed-loop tracking, and check what the model leaves out.

By 12 min read

What you will learn

  • Read magnitude in decibels and phase in degrees on a logarithmic frequency axis.
  • Calculate the frequency response of a plant and lead controller.
  • Find gain crossover and evaluate phase margin at that frequency.
  • Explain why phase lead also changes magnitude and moves crossover.
  • Distinguish loop gain from closed-loop tracking and identify model limits.

Before you start

Increasing a controller gain can improve tracking at one frequency while leaving less room for phase lag near crossover. A Bode plot makes that trade visible. A lead controller lets you change the shape as well as the overall gain.

This lesson follows one position-control model all the way from its equations to a working frequency-domain experiment. You will calculate the loop's gain crossover, inspect its phase there, and compare the loop with the closed-loop tracking response.

Read Bode plots for loop shaping

A Bode plot uses two aligned graphs: magnitude and phase versus frequency. Equal horizontal distances represent equal frequency ratios. Moving from 0.1 to 1 rad/s covers the same distance as moving from 1 to 10 rad/s: each is one decade.

For a dimensionless frequency response H(jω), magnitude in decibels is 20 log₁₀|H(jω)|. A magnitude of 1 gives 0 dB, 2 gives about 6.0206 dB, and 0.5 gives about −6.0206 dB. These are amplitude ratios; the logarithm does not make the underlying signals logarithmic.

Angular frequency ω uses rad/s. Frequency f in cycles per second uses Hz, with ω = 2πf. A point at 1 rad/s therefore represents about 0.159155 Hz.

Phase describes the shift between sinusoidal input and output. A phase of −90° corresponds to a quarter-cycle lag at that frequency. A phase angle alone does not imply a fixed time delay across every frequency.

Define the plant and lead controller

Let y be position in meters and u a commanded velocity in m/s. A simple velocity lag followed by position integration gives:

ÿ/wp + ẏ = u
G(s) = Y(s)/U(s) = 1/[s(1 + s/wp)]

The positive number wp is the velocity-response pole frequency in rad/s. The plant has a pole at zero from position integration and a pole at −wp from the lag. Its transfer-function units are seconds.

Use unity negative feedback, e = r − y, and a lead controller:

C(s) = K(1 + s/z)/(1 + s/p), with p ≥ z > 0
L(s) = C(s)G(s)

K has units of 1/s, so C maps a position error to a velocity command. The corner frequencies z and p use rad/s; the corresponding zero and pole are at −z and −p. L is dimensionless because the controller and plant units cancel.

The model is continuous, linear, and time invariant. Transfer functions use zero initial conditions; frequency responses describe sinusoidal behavior. The experiment includes no sampling delay, saturation, measurement filter, or structural resonance.

Add the magnitude and phase factors

Substitute s = jω, where j² = −1. A factor 1 + jω/a has magnitude √(1 + (ω/a)²) and phase arctan(ω/a). Multiplication combines magnitudes and adds phases; division subtracts the denominator's phase.

|L(jω)| = K √(1 + (ω/z)²)
/ [ω √(1 + (ω/wp)²) √(1 + (ω/p)²)]

The integrator contributes −90°. The two poles add lag, while the zero adds lead:

∠L(jω) = −90° − arctan(ω/wp) + arctan(ω/z) − arctan(ω/p)

Convert the arctangents to degrees before adding them to −90°. The lab uses this continuous, unwrapped phase expression, so its curve has no artificial jumps at an angle convention's boundary.

Far below both controller corners, C approaches K. Far above them, C approaches Kp/z. The gain-only comparison uses C = K at every frequency, with the same plant and low-frequency controller gain as the shaped loop.

Find crossover and phase margin

The gain crossover frequency ωc satisfies |L(jωc)| = 1, or 0 dB. At that frequency, the phase margin is PM = 180° + ∠L(jωc). These definitions match the MathWorks margin documentation.

This particular loop has exactly one positive gain crossover. To see why, differentiate its log magnitude with respect to log frequency:

d ln|L| / d lnω = −1 − ω²/(wp² + ω²)

  • ω²/(z² + ω²) − ω²/(p² + ω²) < 0

The positive fraction is always less than one, so the entire expression is negative. Magnitude tends to infinity as ω approaches zero and to zero as ω grows without bound. Continuity and strict decrease give one crossing.

The lab solves for that crossing with bisection on the exact magnitude formula. It does not locate crossover by picking the nearest plotted sample. Other plants can have multiple crossings, for which the same one-number interpretation requires more care.

Place a lead zero and pole

For p greater than z, the controller contributes arctan(ω/z) − arctan(ω/p) of positive phase. Its maximum occurs at ωm = √(zp). That geometric mean lies halfway between the corners on a logarithmic frequency axis.

Writing a = p/z, the maximum phase lead is arcsin((a − 1)/(a + 1)). With z = 0.5 rad/s and p = 2 rad/s, a = 4, ωm = 1 rad/s, and the maximum lead is 36.869898°. If p = z, the factors cancel and C = K, with zero phase lead everywhere.

Placing this phase increase near the desired crossover is a useful design move. The Illinois ECE 486 lead-compensation notes explain the same geometric placement and its magnitude tradeoff.

Adding lead also raises loop magnitude and moves crossover. Evaluate the new phase margin at the new crossover, then adjust K and the corners again if needed. The controller's maximum phase lead is not the amount by which phase margin must improve.

Check one shaped loop by hand

Set K = 1 1/s, wp = 1 rad/s, z = 0.5 rad/s, and p = 2 rad/s. At ω = 1 rad/s:

C(j) = (1 + 2j)/(1 + 0.5j) = 1.6 + 1.2j
G(j) = 1/[j(1 + j)] = −0.5 − 0.5j
L(j) = −0.2 − 1.4j

Its magnitude is √2 = 1.414214, its magnitude in decibels is 3.010300 dB, and its phase is −98.130102°. Since the magnitude exceeds one, this inspection frequency is below crossover.

For this example, squaring the magnitude equation and setting x = ω² gives x³ + 5x² − 12x − 4 = 0. The positive solution is x = 2, so ωc = √2 = 1.414214 rad/s, or 0.225079 Hz. Evaluating the phase there gives −109.471221°, hence PM = 70.528779°.

With C = K alone, the crossover is 0.786151 rad/s and the phase margin is 51.827292°. The shaped loop improves this margin by about 18.701487°, even though the controller's maximum phase lead is about 36.87°. The two margins use different frequencies.

Separate loop gain from closed-loop tracking

For the unity feedback connection, the reference-to-output transfer function and sensitivity are:

T(s) = Y(s)/R(s) = L(s)/(1 + L(s))
S(s) = E(s)/R(s) = 1/(1 + L(s))

At the worked example's ω = 1 rad/s, T = (9 − 7j)/13. Its magnitude is √(10/13) = 0.877058, while |S| = √(5/13) = 0.620174. Complex T and S add to one; their magnitudes do not generally add to one.

The low-frequency limit of T is one for this position loop. A closed-loop half-power bandwidth would be measured where |T| reaches 1/√2 relative to that limit. Crossover instead uses |L| = 1, so it describes a different transfer function and threshold.

At crossover, |T| = 1/[2 sin(PM/2)] for this phase range. It equals 1/√2 when PM is 90°, but has other values at other margins. Continue with control bandwidth to connect a tracking frequency response to motion and command limits.

Check stability and physical limits

The characteristic equation 1 + L(s) = 0 becomes:

s³ + (wp + p)s² + wp p(1 + K/z)s + K wp p = 0

All coefficients are positive. The remaining cubic Routh stability condition is (wp + p)(1 + K/z) > K. It holds because p ≥ z and wp is positive, so this entire parameter family has an asymptotically stable ideal closed loop.

When p = z, the canceled controller factor corresponds to a stable pole; the reduced characteristic polynomial is s² + wp s + K wp. The stability argument is about this stated model. Phase margin alone does not certify a physical robot with delays, saturation, uncertain modes, or a different feedback connection.

Lead also changes noise-driven command effort. If additive measurement noise n enters yₘ = y + n, then U/N = −C/(1 + L) = −CS, while Y/N = −T. At high frequency, S tends to one and the noise-to-command gain tends to Kp/z in 1/s.

A larger pole-to-zero ratio can therefore demand more high-frequency velocity command from the same measured position noise. Actual command levels depend on the noise spectrum and units. Check derivative filtering, actuator limits, model uncertainty, and sampled implementation before choosing hardware settings.

Shape the loop in the lab

Start with Lead near crossover and confirm the worked values at 1 rad/s. Switch to Gain only, then Higher gain without lead. Increasing K moves crossover upward, where this plant contributes more lag.

Next compare Lead above crossover with the default. The same pole-to-zero ratio puts the same maximum phase lead at a different frequency, so its effect on crossover and margin changes. Wider lead range adds more maximum lead while also moving crossover; its phase margin need not exceed the default's.

Shape a position-control loop

Where does the loop cross unity gain?

Move a controller zero and pole, then inspect magnitude and phase together. The green curve shows closed-loop tracking at each frequency.

1.00
1.00
0.50
4.00

G(s) = 1/[s(1 + s/wp)] and C(s) = K(1 + s/z)/(1 + s/p), with p = z × ratio. Position uses meters, velocity command uses m/s, and K uses 1/s. The plotted gains L = CG and T = L/(1 + L) are dimensionless.

1.0 rad/s = 0.159155 Hz
Loop and closed-loop Bode magnitudesLogarithmic frequency from 0.01 to 100 radians per second. Solid blue is lead-shaped loop L, orange dashes are gain-only loop K G, and green dotted line is closed-loop tracking T. The blue loop crosses zero decibels at 1.414214 radians per second. The inspection dot is at 1.000000 radians per second and 3.010300 decibels.-100-60-20020600.010.1110100ω (rad/s, log)Magnitude (dB)
Blue solid: shaped loop L. Orange dashes: gain-only loop KG with the same K and plant. Green dotted: closed-loop tracking T. The blue ring and dashed vertical guide locate |L| = 1, or 0 dB. The orange inspection guide and filled blue dot follow the frequency control.
Unwrapped loop Bode phase and phase marginLogarithmic frequency from 0.01 to 100 radians per second. Solid blue is lead-shaped loop phase and orange dashes are gain-only phase. The vertical blue segment at the shaped crossover spans from minus 180 degrees to the loop phase, a margin of 70.528779 degrees. The inspection dot is at 1.000000 radians per second and -98.130102 degrees.-180-120-6000.010.1110100ω (rad/s, log)Phase (deg)
Blue solid: shaped loop phase. Orange dashes: gain-only phase. The thick blue segment measures phase margin above −180° at the shaped loop’s crossover. Its length is not the controller’s maximum phase lead. Each crossover readout uses its own loop.
Gain crossover (rad/s)
1.414214
Gain crossover (Hz)
0.225079
Phase margin (deg)
70.528779
Gain-only crossover (rad/s)
0.786151
Gain-only phase margin (deg)
51.827292
Loop magnitude |L|
1.414214
Loop magnitude (dB)
3.010300
Loop phase (deg)
-98.130102
Closed-loop magnitude |T|
0.877058
Sensitivity magnitude |S|
0.620174
Lead pole p (rad/s)
2.000000
Maximum phase lead (deg)
36.869898
Peak-lead frequency (rad/s)
1.000000
Controller high-frequency gain (1/s)
4.000000

The controller adds positive phase and raises magnitude. Crossover moves, so compare the two phase margins at their separate crossover frequencies. Closed-loop tracking magnitude at crossover generally differs from one.

Readouts use exact frequency formulas and numerical root finding, independent of the 321 curve samples. These positive parameters give a stable ideal closed loop; the article checks its characteristic polynomial. Delays, sampling, sensor noise spectra, actuator limits, and unmodeled resonances are excluded.

Both plots use fixed axes across settings so comparisons preserve scale. The inspection control changes the selected-frequency readouts and dots; crossover readouts describe the entire loop. The green magnitude curve describes closed-loop tracking, and the blue curves describe loop gain.

Reproduce the calculations in Python

This standard-library example uses complex arithmetic to evaluate C, G, L, and T. It solves crossover independently of a plot and prints the same default values as the lab. It evaluates a frequency-domain model; it does not simulate a time trajectory.

import cmath
import math

K, wp, z, p = 1.0, 1.0, 0.5, 2.0

def loop(omega, lead=True):
    s = complex(0.0, omega)
    controller = K * (1 + s / z) / (1 + s / p) if lead else K
    return controller / (s * (1 + s / wp))

def crossover(lead=True):
    low, high = 0.01, 100.0
    for _ in range(90):
        middle = (low + high) / 2
        if abs(loop(middle, lead)) > 1:
            low = middle
        else:
            high = middle
    return (low + high) / 2

value = loop(1.0)
wc = crossover()
pm = 180 + math.degrees(cmath.phase(loop(wc)))
baseline = crossover(False)
baseline_pm = 180 + math.degrees(cmath.phase(loop(baseline, False)))
print(f"Loop magnitude: {abs(value):.6f}")
print(f"Loop dB and phase: {20 * math.log10(abs(value)):.6f}, "
      f"{math.degrees(cmath.phase(value)):.6f} deg")
print(f"Crossover: {wc:.6f} rad/s = {wc / (2 * math.pi):.6f} Hz")
print(f"Phase margin: {pm:.6f} deg")
print(f"Gain-only crossover and margin: {baseline:.6f}, {baseline_pm:.6f}")
print(f"Closed-loop magnitude: {abs(value / (1 + value)):.6f}")
print(f"Sensitivity magnitude: {abs(1 / (1 + value)):.6f}")

Expected output:

Loop magnitude: 1.414214
Loop dB and phase: 3.010300, -98.130102 deg
Crossover: 1.414214 rad/s = 0.225079 Hz
Phase margin: 70.528779 deg
Gain-only crossover and margin: 0.786151, 51.827292
Closed-loop magnitude: 0.877058
Sensitivity magnitude: 0.620174

Try it yourself

Exercise 1. A lead controller has K = 2 1/s, z = 1 rad/s, and p = 9 rad/s. Find its peak-lead frequency, maximum phase lead, and high-frequency gain. Can these values alone tell you the phase margin of a loop containing that controller?

Check the lead-controller calculation

The peak is at √(1 × 9) = 3 rad/s. The maximum lead is arcsin((9 − 1)/(9 + 1)) = arcsin(0.8) = 53.130102°. The high-frequency controller gain is Kp/z = 18 1/s.

You also need the plant and the resulting crossover frequency to calculate phase margin. The controller phase maximum may occur away from that crossover, and the plant contributes its own phase.

Exercise 2. At some frequency a loop has L = −0.5 − 0.5j. Calculate |L| in decibels, T = L/(1 + L), and |T|. Is this frequency a gain crossover or a closed-loop half-power point for a system with unit DC tracking gain?

Check the loop and closed-loop values

|L| = 1/√2, so its magnitude is −3.010300 dB. Dividing (−0.5 − 0.5j) by (0.5 − 0.5j) gives T = −j, with |T| = 1.

This frequency is neither point: gain crossover requires |L| = 1, while the closed-loop half-power point requires |T| = 1/√2. The −3 dB value belongs to L here, so it cannot be used as the bandwidth threshold for T.

Sources and further study

Continue with control bandwidth to evaluate how well a closed loop follows changing references. Then examine controller discretization to see what changes when the command updates at sampled times.