MOVEdot

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_cmdHwaCmd_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.