Building a Steer-by-Wire System · Chapter 2 · Part 2 of 5

6Gates failed of 11
Steer-by-Wire

The fault-injection campaign

Girish Radhakrishnan
Girish RadhakrishnanJune 29, 2026 · 7 min read
Steer-by-WireFault InjectionSeries

384 runs across nine fault types and three operating points; 1,920 source files. The 11-metric acceptance verdict is 5 PASS / 6 FAIL.

Dataset: sbw_ch2/dataset/ · 384 runs · 1,920 source files · Acceptance spec: acceptance_spec_sheet.csv (11 metrics)

Runs analysed384
Pooled SP coverage93.21%
FTTI breaches34/324
Handover RWA fails18/48
Verdict5 PASS / 6 FAIL

Executive summary

The campaign exercises a dual-channel steer-by-wire system with 324 single-point fault injections, 48 commanded A→B handover runs, and 12 fault-free golden baselines. The 11-metric acceptance verdict is 5 PASS / 6 FAIL:

  • Coverage falls short of the 99% gate at 93.21% pooled. Two fault types drive the shortfall: motor_driver_open (50%) and mild angle_sensor_bias (88.9%).
  • FTTI compliance is clean on the self-steer hazard at every operating point, but incorrect-steer and handover-omission hazards both miss the 150 ms gate. Incorrect-steer breaches come from the 12 mild torque_sensor_drift runs (210–230 ms) and the four undetected mild angle_sensor_bias runs.
  • Handover RWA deviation fails on 18 of 48 runs, clustered in severe motor_driver_short residual carry-over (up to 8.807 deg) and a park + severe omission cluster at ~3.3 deg.
  • The eotti bounded-window metric is informational: every detected run completes handover inside an observable degraded window of 1.17–3.49 s, well below the 5 s budget.
  • False positives: PASS – zero DTC latches across all 12 golden runs on 18 monitors across both ECUs.

Dataset

Campaign overview384 runs · 1,920 files
324Single-point injections
48Handover-dedicated
12Golden baselines
Rig DAQ
MF4 · 1 kHz
Master clock
ECU-A
MF4 · 100 Hz
Primary channel
ECU-B
MF4 · 100 Hz
Backup channel
Steering robot
CSV · 100 Hz
Input profile
Ambient
CSV · 1 Hz
Temp & voltage
Single-point run matrix · 324 runs
Operating points
High-speed
120 kph
Urban
50 kph
Parking
5 kph
Severity
Mild
Moderate
Severe
Fault types
Motor driver short
Motor driver open
Angle sensor bias
Angle sensor open
Torque sensor drift
Cross-channel freeze
CAN corruption
CAN timeout
Channel supply dropout
Motor driveAngle sensingTorque sensingBus / channelPower
9 faults3 severity3 op pointsECU-A / ECU-B2 repeats324

The run matrix from operator_log.xlsx: 324 single-point + 48 handover + 12 golden = 384. Single-point runs span nine fault types × three magnitudes (mild / moderate / severe) × three operating points (park / urban / hs) × 2 channels (ECUA / ECUB) × 2 repeats = 324.

Operator log flags two truncated runs (inj_077, inj_244); these are processed on their available samples and their detection signatures recover normally inside the truncated window.

Each run carries five synchronised sources: rig DAQ at 1 kHz (master clock), ECU-A and ECU-B at 100 Hz, steering robot at 100 Hz, ambient sensors at 1 Hz. Clock alignment uses MDF header timestamps relative to the rig master. Robot angles convert from radians to degrees; rack position in millimetres maps to road-wheel angle. ECU-B channel names reconcile to the shared schema (theta_cmd → HwaCmd_B, and so on).

Methodology

Every run goes through ingest, harmonisation, event extraction, and gate scoring.

Analysis pipeline5 stages · every run
1Harmonise
5 sources → 100 Hz grid on rig master clock
384 runs
2Extract events
t_inject, t_detect, t_eop from residuals & DTCs
per run
3Coverage
correct monitor DTC latched per fault
324 SP runs
4FTTI check
total_ms vs hazard-class gate
34 breach
5Handover QC
steady-state RWA dev after t_eop + 1 s
≤ 1.0°
Fault injection is refined from the targeted monitor residual (5σ departure) with fallback to t = 3.0 s. FTTI compares total_ms (injection to emergency-op completion) against the hazard-class gate. All 384 runs complete in ~400 s on 8 parallel workers.

Per-run event extraction

FieldDefinition
t_injectResidual steps outside pre-fault baseline; fallback to nominal injection instant at 3.0 s if no residual step
t_detectFirst new DTC latch on the injected channel
t_eopA→B channel swap completes
total_ms(t_eop − t_inject) × 1000. Compared to the governing FTTI.
rwa_dev_deg (handover only)Mean |RWA_cmd − RWA_achieved| over [t_eop + 1.0 s, end] (steady-state, excludes the transient handover spike)

A run passes the timing gate if total_ms < governing_ftti_ms. Undetected runs count as a timing failure.

Processing runs in parallel via ProcessPoolExecutor (8 workers). All 384 runs complete in ~400 s. No runs failed to harmonise.

Coverage

Diagnostic coverage by faultpooled 93.21% · target ≥ 99%
99% target0%25%50%75%100%Motor driver open50%Angle sensor bias88.89%CAN corruption100%Angle sensor open100%CAN timeout100%Channel supply dropout100%Cross-channel freeze100%Motor driver short100%Torque sensor drift100%
All 18 ECU-A motor-driver-open runs detect; all 18 ECU-B runs miss. The four angle-sensor-bias misses are all mild magnitude (two urban, two park). Every other fault type reaches 100%.

Pooled single-point coverage: 93.21% (302 / 324). The 99% gate fails on two fault types.

motor_driver_open – standby-channel blindness

All 18 ECU-A-injected runs detect; all 18 ECU-B-injected runs miss. Coverage: 50.00%. The pattern is fully consistent with hot-standby behaviour: the standby motor carries no current, so an open-circuit monitor that relies on current/voltage residuals has no signal to detect.

angle_sensor_bias – mild-magnitude borderline

Coverage: 88.89% (32 / 36). The four misses are all mild magnitude (two at urban, two at park). All moderate and severe runs detect. This is a sensitivity boundary, not a protocol error.

Every other fault type reaches 100% coverage.

FTTI compliance

FTTI compliance by hazard34 / 324 breach overall
Self-steer (commission)Gate: 100 / 200 / 500 ms · motor_driver_short, cross_channel_signal_freeze, can_corruption0 / 108Incorrect-steerGate: < 150 ms · 12 mild torque_sensor_drift (210–230 ms) + 4 undetected angle_sensor_bias16 / 72Handover-omissionGate: < 150 ms · all 18 ECU-B motor_driver_open (undetected)18 / 144
Self-steer timing is clean at every operating point. Incorrect-steer breaches concentrate on mild torque-sensor drift (210–230 ms vs 150 ms gate). Handover-omission breaches are the same 18 undetected ECU-B motor-driver-open runs from the coverage gap.

Self-steer hazard (commission faults) – PASS

Op pointGateBreachesVerdict
hs< 100 ms0 / 36PASS
urban< 200 ms0 / 36PASS
park< 500 ms0 / 36PASS

All motor_driver_short, cross_channel_signal_freeze, and can_corruption runs detect inside their operating-point budget.

Incorrect-steer hazard – FAIL (16/72 breach)

FaultMagnitudeOp pointnRange (ms)Mean (ms)
torque_sensor_driftmildpark4220–230228
torque_sensor_driftmildhs4210–230220
torque_sensor_driftmildurban4210–220215
angle_sensor_biasmildpark2––
angle_sensor_biasmildurban2––

All 12 mild torque_sensor_drift runs sit at 210–230 ms, well above the 150 ms gate. Moderate (110–130 ms) and severe (70–80 ms) sit cleanly below. This is magnitude-dependent monitor sensitivity. The four undetected mild angle_sensor_bias runs also count here – an undetected fault is, by construction, a gate breach.

Handover-omission hazard – FAIL (18/144 breach)

All 18 breaches are ECU-B-injected motor_driver_open runs that the standby-channel monitor cannot see. This is the coverage gap from §4.1 showing up in the timing gate.

Most other fault types resolve in 10–50 ms with low scatter. torque_sensor_drift is the outlier, with mean ~141 ms driven by the magnitude-dependent latency ladder (severe ~77 ms, moderate ~125 ms, mild ~221 ms).

Handover quality (RWA deviation)

Handover RWA deviation (failures only)18 / 48 fail
02468tolerance · 1.0°8.81°MD short · severe · park5.48°MD short · severe · hs/urban3.46°MD short · moderate3.41°Park + severe omissionmax |cmd − achieved| · °
Measured steady-state over [t_eop + 1.0 s, end], excluding the handover transient. Thirty runs sit at ~0.03° and pass cleanly. Failures split between severe motor-driver-short residual carry-over (up to 8.81°) and a park + severe omission cluster at ~3.3°.

30 / 48 runs sit at ~0.03 deg steady-state RWA deviation, well inside the 1.0 deg gate. 18 / 48 fail, and the failure population splits into three groups:

  • Severe motor driver short – 6 runs: mean deviation ~5.4 deg at high-speed/urban and ~8.7 deg at park. The fault residual carries forward into B's tracking. Maximum deviation: 8.807 deg.
  • Park + severe omission faults – 6 runs across motor_driver_open, channel_supply_dropout, and can_timeout. Tight cluster at ~3.2–3.4 deg, indistinguishable across the three fault types. Mechanism looks like a B-channel calibration/gain offset that only becomes observable post-handover under high-current conditions.
  • Moderate motor driver short – 6 runs: ~3.40–3.46 deg across all operating points.

False-positive check

All 12 golden runs: 0 DTC latches across 18 monitors on both ECUs. false_positive_rate PASSes.

Data quality

  • All 384 runs harmonised without error; no source missing.
  • Truncated runs inj_077 and inj_244 processed on available samples; detection and handover signatures recovered inside the truncated window.

Acceptance verdict

Acceptance gates6 fail · 5 pass (11 total)
MetricObservedGate
cov_spf_per_fault_typemin=50.00% (motor_driver_open)≥ 99%fail
cov_spf_pooled93.21%≥ 99%fail
detect_time_vs_ftti34/324 breach< governing FTTIfail
ftti_selfsteer_hs0/36 breach< 100 mspass
ftti_selfsteer_urban0/36 breach< 200 mspass
ftti_selfsteer_park0/36 breach< 500 mspass
ftti_incorrect_steer16/72 breach< 150 msfail
handover_omission18/144 breach< 150 msfail
rwa_handover_dev18/48 fail (max=8.807 deg)≤ 1.0 degfail
false_positive_rate0 DTC latches in 12 golden runs= 0pass
eottiobservable window 1.17–3.49 s; no second-fault evidence available≤ 5 spass
Overall: 5 PASS / 6 FAIL. Failures fall into three localised mechanisms.

Overall: 5 PASS / 6 FAIL. The campaign does not meet acceptance. Failures fall into three localised mechanisms:

  1. Standby-channel blindness for motor_driver_open drives both the coverage shortfall and the handover-omission FTTI breach.
  2. Mild torque_sensor_drift exceeds the incorrect-steer 150 ms gate at all three operating points (12 / 12 mild runs).
  3. A park + severe operating regime exposes a steady-state B-channel gain/calibration offset of ~3.3 deg on three different omission-fault types, and a larger residual carry-over (up to 8.81 deg) for severe motor_driver_short.

Per-run feature table published (384 rows). Coverage CSV and verdict CSV in the workspace artifacts folder.

All data in this series is synthetic, generated to mirror a real steer-by-wire validation program. No customer data is used.


Next in the series: the regression run. If comparing 384 runs before and after a fix still happens in spreadsheets, we would like to talk: founders@movedot.com, or www.movedot.ai.

Your privacy choices

With your permission, we measure visits, clicks, and campaign performance and can link browsing activity to contact details you submit. Optional tracking stays off until you accept. Cookie policy.