FAILURE MAP
← Case archive

FA-11946 / Discrete control systems / Open access

A setpoint step produces an unwanted derivative kick · case 01

A setpoint step produces an unwanted derivative kick.

Verified by executionVariant 1 · 6 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The derivative uses error differences including setpoint changes.

VERIFIED REPAIR

Differentiate measurement with negative sign.

Unsuccessful approach: Suppressing derivative whenever the setpoint changes loses simultaneous measurement movement.

Case contract

Return the derivative contribution -gain*(measurement-previous_measurement) for unit sample time, independent of setpoint motion.

Why this case matters

An offline discrete controller model isolates this state or arithmetic fault; it makes no physical plant or safety claim.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(sp, old_sp, y, old_y, gain):
    return gain*((sp-y)-(old_sp-old_y))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('setpoint only', solve(N, 0, 0, 0, 2), 0)
check('both move', solve(N, 0, N, 0, 2), -2*N)
check('measurement rises', solve(0, 0, N, 0, 3), -3*N)
check('measurement falls', solve(0, 0, 0, N, 3), 3*N)
check('stationary', solve(N, N, N, N, 2), 0)
check('disabled gain', solve(N, 0, N, 0, 0), 0)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
setpoint only20Failed
both move0-2Failed
measurement rises-3-3Passed
measurement falls33Passed
stationary00Passed
disabled gain00Passed

SHA-256 / 05f1064264843596e7db4fd9ac4bf6ab960c181cba24701dd7fcad97e2c4a6ee

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(sp, old_sp, y, old_y, gain):
    return 0 if sp != old_sp else -gain*(y-old_y)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('setpoint only', solve(N, 0, 0, 0, 2), 0)
check('both move', solve(N, 0, N, 0, 2), -2*N)
check('measurement rises', solve(0, 0, N, 0, 3), -3*N)
check('measurement falls', solve(0, 0, 0, N, 3), 3*N)
check('stationary', solve(N, N, N, N, 2), 0)
check('disabled gain', solve(N, 0, N, 0, 0), 0)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
setpoint only00Passed
both move0-2Failed
measurement rises-3-3Passed
measurement falls33Passed
stationary00Passed
disabled gain00Passed

SHA-256 / d509d4ed0dc1d219c1cd6766c54da5ac925a8c5c6df044c844dff1924c94d092

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(sp, old_sp, y, old_y, gain):
    return -gain*(y-old_y)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('setpoint only', solve(N, 0, 0, 0, 2), 0)
check('both move', solve(N, 0, N, 0, 2), -2*N)
check('measurement rises', solve(0, 0, N, 0, 3), -3*N)
check('measurement falls', solve(0, 0, 0, N, 3), 3*N)
check('stationary', solve(N, N, N, N, 2), 0)
check('disabled gain', solve(N, 0, N, 0, 0), 0)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
setpoint only00Passed
both move-2-2Passed
measurement rises-3-3Passed
measurement falls33Passed
stationary00Passed
disabled gain00Passed

SHA-256 / ec5a836357b1383910906369e5455109f4e31f71341c68f3c4b84fadde347b8f

Verification & scope

Integer-valued controlled examples only; no physical plant, stability guarantee, timing jitter, or hardware behavior is modeled. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:38:52.391774+00:00.

Case digest / b6125313a6f12f541fa194f01f83c31198657c9c45c9ded23b39ae83fb3456ab