FA-11956 / Discrete control systems / Open access
Automatic takeover counts proportional action twice · case 01
Automatic takeover counts proportional action twice.
ROOT CAUSE
The integral state is initialized to the manual output directly.
VERIFIED REPAIR
Subtract proportional and feedforward contributions from manual output.
Unsuccessful approach: Subtracting proportional action alone leaves a feedforward bump.
Case contract
On takeover set I so P+I+F exactly equals the previous manual command; return I. No output limits are modeled.
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(manual, proportional, feedforward):
return manual
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('all active', solve(10*N, 2*N, N), 7*N)
check('no feedforward', solve(10*N, 2*N, 0), 8*N)
check('negative feedforward', solve(0, N, -2*N), N)
check('negative proportional', solve(N, -N, N), N)
check('zero command', solve(0, N, N), -2*N)
check('all zero', solve(0, 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| all active | 10 | 7 | Failed |
| no feedforward | 10 | 8 | Failed |
| negative feedforward | 0 | 1 | Failed |
| negative proportional | 1 | 1 | Passed |
| zero command | 0 | -2 | Failed |
| all zero | 0 | 0 | Passed |
SHA-256 / 0e8b79b116a288f5a0adeef0486486462dfe6c45150a6cb4c4586d6196cdae3b
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(manual, proportional, feedforward):
return manual-proportional
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('all active', solve(10*N, 2*N, N), 7*N)
check('no feedforward', solve(10*N, 2*N, 0), 8*N)
check('negative feedforward', solve(0, N, -2*N), N)
check('negative proportional', solve(N, -N, N), N)
check('zero command', solve(0, N, N), -2*N)
check('all zero', solve(0, 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| all active | 8 | 7 | Failed |
| no feedforward | 8 | 8 | Passed |
| negative feedforward | -1 | 1 | Failed |
| negative proportional | 2 | 1 | Failed |
| zero command | -1 | -2 | Failed |
| all zero | 0 | 0 | Passed |
SHA-256 / 4cee6037963be8fe2dbdec320f8f8b3ed532fcf6c2eb25b4d11ddd2444f50c53
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(manual, proportional, feedforward):
return manual-proportional-feedforward
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('all active', solve(10*N, 2*N, N), 7*N)
check('no feedforward', solve(10*N, 2*N, 0), 8*N)
check('negative feedforward', solve(0, N, -2*N), N)
check('negative proportional', solve(N, -N, N), N)
check('zero command', solve(0, N, N), -2*N)
check('all zero', solve(0, 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| all active | 7 | 7 | Passed |
| no feedforward | 8 | 8 | Passed |
| negative feedforward | 1 | 1 | Passed |
| negative proportional | 1 | 1 | Passed |
| zero command | -2 | -2 | Passed |
| all zero | 0 | 0 | Passed |
SHA-256 / 491007a551d48e1447dcfc58c39531136f1c05758dcb818219b444edea59b954
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.435014+00:00.
Case digest / db6cc4915cdfaed71e33e633c1907bf470740019e2296175e29085b317149db8