All articles
Simulation August 12, 2026 17 min read

Closed-Loop PID Simulation and Performance Metrics That Matter

How to simulate a PID loop with first-order, FOPDT and second-order plants, and how to read rise time, overshoot, settling time, IAE, ISE and ITAE.

A PID loop is judged on a plot, but the plot is only as honest as the plant model, the integrator and the numbers you extract from the trajectory. Guess-and-check on the live plant still happens because it feels faster than building a simulation. It is not: every bump test costs product, operator time and, if the loop is close to the edge, a trip. A closed-loop run against a first-order, FOPDT or second-order plant, integrated with RK4 at a sample time that respects τ, lets you see rise time, overshoot, settling time and the IAE, ISE and ITAE integrals before you touch the DCS. PID Solver 360 is built around that workflow: put a model and gains in front of the closed-loop simulator, read the metrics, and only then decide whether the loop is ready for the plant.

Why simulation beats guess-and-check on the plant

Live tuning is a one-shot experiment with an expensive plant as the laboratory. You change Kp, wait for a disturbance or a setpoint step, squint at a trend, and decide whether overshoot is “about right”. That hides three problems a simulation makes explicit.

Repeatability: a plant is never in the same state twice. Fouling, inventory and upstream pressure move apparent K and L, so two bump tests a shift apart can disagree by 20 %. A simulation holds K, τ and L fixed so the only variable is the controller. Observability: the DCS shows PV, SP and perhaps OP, not unsaturated u, the derivative state, the integral, or the fraction of the run spent on a limit. If the output is clamped for a quarter of the run, the overshoot belongs to a saturated actuator, not to the linear PID you thought you were testing. Cost: aggressive Ziegler–Nichols on a dead-time-dominant FOPDT plant routinely produces 25–50 % overshoot — off-spec product on a slow temperature loop, a relief-valve lift on pressure. Simulation is where you discover that, not the night shift.

Model error is real, so you still confirm on the plant. The point is sequence: identify a model, simulate, reject gain sets that fail the metrics, then test a short list of survivors. Guess-and-check inverts that sequence. A simulation also answers questions the plant will not answer on demand — dead time up 30 % from fouling, an actuator that saturates at 80 %, PI instead of PID because the PV is noisy.

The closed-loop object you are actually integrating

A continuous PID in parallel form is

u(t) = Kp e(t) + Ki ∫ e(τ) dτ + Kd de/dt
e(t) = SP(t) − PV(t)

The plant is a linear ODE, or a delay plus an ODE, plus the parts textbooks omit: clamps, a derivative filter, transport delay, and sample interval dt. Those parts dominate the metrics. A textbook overshoot formula assumes an unsaturated linear PID with no delay; if the valve hits 100 % for the first 12 seconds, that formula is not your loop.

PID Solver 360 time-steps a discrete PID against a continuous plant: P, I and D at each sample, optional saturation, a delay buffer for FOPDT, RK4 over dt. The record of t, PV, SP, e and u is what the metrics see — the same split a PLC uses. Do not treat dt as a plotting resolution, and do not disable saturation unless you intend to simulate a different actuator.

Plant models that earn their keep

You do not need a high-order first-principles model to decide whether a PID is sane. You need a model whose step response has the same gain, the same dominant lag and the same delay as the plant you will face. Three structures cover most loops.

First-order lag

A first-order plant is

G(s) = K / (τ s + 1)

or, in the time domain the integrator actually sees,

τ y' = K u − y

K is process gain. τ is the 63 % time after a step in u. There is no delay. A first-order plant under PI cannot overshoot if the controller is continuous, linear and unsaturated; if the simulation shows 40 % overshoot, look at saturation, coarse dt, or noisy D. Putting L = 0 on a plant with piping lag makes every tuning rule look better than it is, because Ziegler–Nichols, Cohen–Coon and IMC all spend their conservatism on L.

First-order plus dead time (FOPDT)

The workhorse of PID tuning is

G(s) = K e^{−L s} / (τ s + 1)

Three numbers: K from ΔPV / ΔOP, τ from the exponential after the delay, L from the time until PV first moves. Ziegler–Nichols, Cohen–Coon, IMC-PI and SIMC are all derived for this structure.

L/τ is the useful dimensionless number. Below about 0.1 the plant is lag-dominant. Near 1, Ziegler–Nichols will overshoot. Above 2, PID will struggle; consider a Smith predictor, detuned PI, or cascade. Fit K, L and τ from the 28 % / 63 % points or a least-squares step. If the simulated open-loop step does not overlay the bump test, fix the model before you touch Kp.

Second-order plants

A second-order plant

G(s) = K / (τ² s² + 2 ζ τ s + 1)

has a pair of poles. In state form the integrator sees

y'' = (K u − y − 2 ζ τ y') / τ²

ζ below 1 is underdamped: the open-loop plant already rings. Servos look like this. ζ above 1 is overdamped and can often be reduced to FOPDT. Use second-order when the bump test overshoots in open loop, not because it has more parameters. Derivative action then supplies damping the plant does not have. The τ above is the natural-period parameter, not the first-order 63 % time.

Dead time: Padé approximation versus a delay buffer

Dead time is not a pole. It is a translation of the input,

u_applied(t) = u(t − L)

That translation is why a PID cannot cancel delay with a zero, and why every aggressive tuning rule overshoots on FOPDT plants. How you implement it in a simulator changes the metrics.

A Padé approximation replaces e^{−Ls} with a rational transfer function. The first-order Padé is

e^{−L s} ≈ (1 − L s / 2) / (1 + L s / 2)

It is convenient in Laplace-domain algebra and a poor delay for closed-loop PID work. First-order Padé has a right-half-plane zero the true delay does not have, and high-frequency phase flattens while a true delay contributes −ωL forever. A PID with derivative action lives at high frequency; optimistic phase makes a simulated Kd that “stabilises” the loop destabilise the real one.

A delay buffer is the honest implementation. Store the last N = round(L / dt) outputs and feed the oldest to the plant. The delay is exact to one sample. PID Solver 360 uses this for FOPDT, so the RK4 step sees delayed u. Shrink dt until L / dt is at least ten, and do not initialise the buffer with zeros unless the plant starts at rest. If Padé and a buffer disagree on overshoot, believe the buffer.

RK4 versus Euler: the integrator is part of the plant

The plant ODE is continuous. The controller is discrete. Between samples you must advance y. The cheapest method is forward Euler:

x(t + h) = x(t) + h f(x(t), u)

Euler is first-order accurate. For a first-order lag it is stable only if h < 2τ; the pole at 1 − h/τ goes negative for h > τ. A dt that is merely “a bit smaller than τ” can make a stable plant look oscillatory. That ring inflates overshoot, oscillation count and ISE, and you will detune a good PID to compensate for the integrator.

Fourth-order Runge–Kutta evaluates the derivative four times per step:

k1 = f(x, u)
k2 = f(x + h k1 / 2, u)
k3 = f(x + h k2 / 2, u)
k4 = f(x + h k3, u)
x+ = x + (h / 6) (k1 + 2 k2 + 2 k3 + k4)

Local error is O(h⁵), global error O(h⁴). For these smooth linear plants, RK4 at h = dt is accurate enough that the metrics belong to the PID and the model, not the stepper. PID Solver 360 integrates first-order, FOPDT (the lag part) and second-order plants this way, holding u constant over the interval because a PLC output is a zero-order hold. If a spreadsheet Euler model rings at a period near 2 dt, that is the Euler stability boundary, not a plant mode. RK4 is not a licence for huge steps: the controller still samples at dt, the delay buffer still quantises L, and D is still (e_k − e_{k−1}) / dt.

Sample time dt versus plant τ

A rule that has survived contact with real PLCs: dt should be a small fraction of closed-loop rise time and of τ. PID Solver 360 warns when dt > τ / 2 and recommends dt ≤ τ / 10. Three mechanisms break when dt is coarse.

The discrete derivative Kd (e_k − e_{k−1}) / dt has gain 2 Kd / dt at Nyquist, so halving dt doubles unfiltered D and a very large dt turns PID into clumsy PI. The delay buffer rounds L to integer steps; on FOPDT a coarse dt can round L to zero and silently drop the delay. Always check delaySteps = round(L / dt). Even RK4 is integrating a ZOH staircase: if dt is a third of τ, interpolated 10–90 % rise time is fiction. Set dt to min(τ, L, Td) / 20 when those parameters are known, confirm that an open-loop step matches the analytic exponential, and extend duration from 10 τ + 5 L until settling time is finite and ITAE has stopped growing.

Actuator saturation

Every real output has limits. A simulation that lets u run to 400 % is a different actuator from the field, and every metric will be optimistic.

Saturation replaces u with clip(u, uMin, uMax), so the plant sees a weaker input and the linear overshoot formula is void. Meanwhile the integral keeps accumulating; when PV finally crosses SP the output slams to the opposite limit. That is windup: large overshoot, long settle, high saturation fraction, ITAE that keeps growing. Anti-windup is not optional. Back-calculation, used in PID Solver 360, recomputes the integral so P + I + D sits on the limit. Conditional integration (freeze I while saturated) is the other common approach. Either collapses saturating-PI overshoot relative to a naive accumulator; neither restores infinite-actuator rise time. Enable true OP limits, enable anti-windup, and treat saturationFraction above about 0.25 as a design problem, not a tuning problem.

Derivative filtering

The derivative of a staircase PV is a train of impulses. An unfiltered D term on a noisy measurement will dominate u, saturate the actuator, and make ISE explode. Practising engineers therefore filter D. The usual first-order filter is

Tf = Td / N
D(s) = Kd s / (Tf s + 1)

N in the range 8 to 20 is typical. PID Solver 360 implements a discrete low-pass on raw D with α = dt / (Tf + dt), and takes derivative on measurement so a setpoint step does not produce kick. If D acts on e = SP − PV, a step in SP makes de/dt a Dirac delta and the output spikes. Taking −dPV/dt still damps the plant. A common 2-DOF default is b = 1, c = 0 — P on error, D on measurement. A filter of Td/N only shapes D; P still sees the noisy PV.

Time-domain metrics that matter

Once the trajectory exists, you still have to turn it into numbers a reviewer can argue about. The classical metrics are defined on a single setpoint step from an initial PV, with the sign of the step taken into account so a downward step does not report negative overshoot as a success.

Rise time

Rise time is the interval between the PV crossing 10 % of the commanded span and the PV crossing 90 % of that span:

t_r = t_90 − t_10
span = SP − PV0
level(α) = PV0 + α · span

Linear interpolation is enough if dt is fine. Rise time is a speed metric and ignores everything after 90 %, so use it with overshoot, never instead of it. On FOPDT plants it cannot be shorter than something on the order of L.

Peak time and overshoot

Peak time is the time at which PV is furthest past the setpoint in the direction of the step. Overshoot is that excursion as a percentage of the span:

M_p = max (dir · (PV − SP))
OS% = 100 · M_p / |span|

where dir is the sign of the step. A 10 % overshoot on a 50-degree step is 5 degrees. Chemical loops often want little or no overshoot; motion loops often accept 5–15 %. Quarter-amplitude-decay Ziegler–Nichols commonly lands at 20–50 %. If you simulate it on FOPDT and see 8 %, suspect L too small or saturation clipping the peak.

Settling time at 2 % and 5 %

Settling time is the first time after which PV remains inside a band around SP. The band is usually ±2 % or ±5 % of the span:

|PV(t) − SP| ≤ 0.02 |span|   for all t ≥ t_s

Walk backward from the end of the record and find the last exit from the band. If the trajectory is still leaving at T_final, settling time is undefined. PID Solver 360 uses ±2 % and reports null when the last sample is still outside. A 5 % band is always shorter or equal; quote the band with t_s. If SSE is 3 % of span, the 2 % band is never home.

Steady-state error

SSE is SP − PV at t_final. With a working Ki it should be numerically zero. Remaining offset means Ki is zero, the run ended too soon, the output is on a limit, or the integral is still crawling. If SSE continues to fall when you extend T, you needed more time, not more Ki. Peak error, max |e(t)|, captures the worst excursion including undershoot.

The table below is the set PID Solver 360 puts on the KPI dashboard after each run. Use it as a reading list, not as a single-score leaderboard.

MetricDefinitionWhat it punishesTypical use
Rise time t_rt_90 − t_10 of the commanded spanSluggish Kp, delay, saturationSpeed spec at equal overshoot
Peak time t_pTime of extreme PV in the step directionSlow ringingSanity check against L and τ
Overshoot OS%100 × peak excursion / \span\Aggressive Kp/Ki, missing damping, windupQuality and safety limits on PV
Settling time t_sLast entry into ±2 % or ±5 % bandHunting, slow I, unfinished runHow long until you can walk away
Steady-state errorSP − PV at t_finalMissing Ki, saturation, short runOffset spec; PI vs P
IAE∫ \e\dtAll error, equally by sizeGeneral-purpose objective
ISE∫ e² dtLarge early errorsAggressive disturbance rejection
ITAE∫ t \e\dtError that hangs aroundPrefer small residual hunting
Oscillation countHalf the PV slope sign changesNear-stability, noise, coarse dtStability-margin sanity check

IAE, ISE and ITAE: what the integrals actually punish

Time-domain peaks answer how bad the worst moment was. Integral criteria answer how bad the whole story was. They are the right objectives for an optimiser, and they are easy to misread if you treat them as interchangeable.

IAE  = ∫_0^T |e(t)| dt
ISE  = ∫_0^T e(t)² dt
ITAE = ∫_0^T t |e(t)| dt

PID Solver 360 evaluates these with the trapezoidal rule on the sampled error, which is the correct discrete analogue at the accuracy of dt.

IAE weights every unit of error the same. A 10-unit error for 1 s costs the same as a 1-unit error for 10 s. Because it uses |e|, positive and negative lobes do not cancel — unlike the raw integral of e, which a PI loop drives to zero while the PV is still swinging.

ISE squares the error, so a 10-unit spike costs 100 and a 1-unit tail costs 1. Optimising ISE spends authority on the early transient: aggressive Kp, more overshoot. That can be right for a disturbance that must not get large, and wrong for a quality loop specified not to overshoot. If you minimise ISE and then complain about overshoot, you asked for it.

ITAE multiplies |e| by time, so late error is expensive. It typically gives less overshoot and a shorter settle than ISE, at the price of a slower rise, and it is the most sensitive to duration: a leftover SSE makes ITAE grow without bound. Compare ITAE only at equal T and after SSE is essentially zero. Absolute values are not portable across step sizes; normalise by |span| (and |span|² for ISE). Nelder–Mead in PID Solver 360 needs a scalar. The spec is usually a constraint — OS% under 10, t_s under 40 s — plus a soft wish for small ITAE. An optimiser that dumps champion ISE with 45 % overshoot has been asked the wrong question.

Oscillation count

A simple count of how often the PV slope changes sign, halved so that a full cycle is one oscillation, is a crude stability metric and a surprisingly useful one. A well-damped step has zero or one turning point. A quarter-amplitude-decay response has two or three visible swings. Four or more is a loop living near its ultimate gain.

The count is not a substitute for a Nyquist margin. Noise and coarse Euler steps both create spurious slope changes. Use it as a flag: if the count jumps from 1 to 6 when you raise Kp by 20 %, you found the edge. Confirm with a longer run or a robustness sweep on K and L. Phase margin is a frequency-domain number; oscillation count is a time-domain symptom.

Interpreting metrics versus engineering guarantees

A dashboard full of green numbers is not a guarantee that the plant will behave. It is a guarantee that this model, this dt, this saturation setting and this step size produced those numbers. The gap between the two is where control engineers earn their pay.

The FOPDT triple (K, τ, L) comes from one bump test at one operating point. Gain changes with valve position; dead time changes with level. Rerun with L × 1.3 and K × 1.2; if the perturbed metrics are still inside spec, you have a robustness argument. If not, you do not, regardless of nominal ITAE.

Saturation, stiction and a pH curve violate the linear ODE — match step size and OP limits to the real move. Rise time on 10–90 % is not “time to enter the band”; 2 % settle is not 5 %. Name the definition. PID Solver 360 reports ±2 % settling and trapezoidal IAE, ISE and ITAE. A Nelder–Mead ITAE minimum is a search from a given start, not the unique best PID. Metrics describe how a given structure and model respond to a step. They do not certify that the transmitter is in the right place or that the loop should not be a cascade.

A checklist for a trustworthy simulation

Before you believe a rise time, an overshoot or an ITAE from any tool, including PID Solver 360, walk this list.

  • Plant structure matches the bump test: first-order only if there is no delay, FOPDT if the curve is sigmoidal, second-order if open-loop rings.
  • K, τ, L (and ζ if used) overlay the open-loop step. If they do not, stop.
  • Dead time is a delay buffer, not a first-order Padé, unless you have checked high-frequency phase on purpose.
  • Integrator is RK4 or better. If you must use Euler, confirm that halving dt does not change OS% by more than a point.
  • dt ≤ τ / 10; L / dt is several samples on FOPDT; the rising edge resolves 10 % and 90 % crossings.
  • Duration reaches a true settle: t_s finite at 2 %, SSE negligible, ITAE not growing from leftover offset.
  • Saturation limits equal the real OP range; anti-windup on if the actuator can hit a stop; inspect saturationFraction.
  • Derivative filtered with Td/N (N around 10) and, unless studying kick, taken on measurement.
  • Metrics reported with definitions: 10–90 rise, OS% of span, 2 % or 5 % settle, integrals over a stated T.
  • IAE, ISE and ITAE compared only at equal T and equal step size; the auto-tuning objective matches the spec.
  • A robustness rerun with K and L perturbed still meets the constraints you will defend to operations.
  • The plot agrees with the numbers. If OS% is 2 and the PV clearly overshoots, check span, sign, and T_final.

When that list is green, the simulation is evidence. When any item is red, the dashboard is a screenshot.

Putting the numbers to work

The job is not to collect metrics. It is to reject bad tunings quickly and take a short list of good ones to the plant. Start with a FOPDT or second-order model that fits the bump test. Run the closed loop in the closed-loop simulator with RK4, a dt that respects τ and L, saturation on, and a derivative filter on. Read overshoot and settling time against the process spec first. Use IAE as a tie-breaker, ISE only if large early error is truly the enemy, and ITAE when the complaint is a long tail. Treat oscillation count and saturation fraction as alarms. Then perturb the model and see whether the survivor is still a survivor.

That sequence is slower than typing a new Kp into the DCS and hoping. It is faster than explaining a relief-valve lift. PID Solver 360 exists so the cheap work happens on the model, and the plant only sees the gain set that already passed the metrics that matter.

Try it in the solver

Put this into practice — model your process, auto-tune it and check the stability margins.

Launch PID Solver 360