Skip to content

feat: Phase-3 diagnostic signals + fault injection (oil/exhaust/starter/gnss/rateOfTurn) - #5

Merged
navado merged 1 commit into
mainfrom
feat/diagnostic-fault-modeling
Jun 22, 2026
Merged

feat: Phase-3 diagnostic signals + fault injection (oil/exhaust/starter/gnss/rateOfTurn)#5
navado merged 1 commit into
mainfrom
feat/diagnostic-fault-modeling

Conversation

@navado

@navado navado commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Phase-3 diagnostic-signal modeling (per docs/superpowers/plans/2026-06-22-diagnostic-signal-modeling.md). Models signals that don't exist in engine state today so downstream diagnostics can detect anomalies, plus a shared fault injector so a demo can trigger the exact anomaly each diagnostic is meant to catch.

New SignalK paths

Emitted only when the caller supplies the value (None => omitted), exactly like propulsion.main.runTime, so existing call sites/tests are unaffected.

path units value semantics
propulsion.main.oilPressure Pa f(rpm): 0 stopped, ~250 kPa idle -> ~450 kPa cruise + noise
propulsion.main.exhaustTemperature K wet-exhaust temp, f(load) + warmup; spikes dry-hot under cooling fault
electrical.batteries.starter.voltage V ~12.7 float / ~14.2 charging, dips on crank
electrical.batteries.starter.stateOfCharge ratio cranking-bank SOC
electrical.batteries.starter.current A + charging / − crank
navigation.gnss.satellites count 8–13 nominal
navigation.gnss.horizontalDilution HDOP 0.6–1.5 nominal
navigation.gnss.methodQuality "GNSS Fix" / "no GNSS"
navigation.gnss.antennaAltitude m masthead antenna height
navigation.rateOfTurn rad/s heading delta per tick, +stbd, normalised ±180°

gps_degraded also re-emits navigation.position with a jitter offset (physics state untouched). alternator_belt drives the already-published electrical.alternators.1.current/power to 0 while running.

Fault mechanism

engine/faults.py::FaultState holds {fault_id: {active, severity}}. Seeded from SIM_FAULTS="raw_water_blocked,alternator_belt" at boot AND toggled live via set_fault/clear_fault commands (intercepted in Engine.submit_command). All OFF by default.

Fault ids: low_oil_pressure, raw_water_blocked, alternator_belt, weak_starter, gps_degraded.

Tests

182 passed, 4 deselected (-k "not geogrid_real and not open_meteo"); ruff clean. Covers each model's nominal range, each fault deviating + recovering, a raw_water_blocked integration check (exhaust + coolant rise at steady RPM), the writer published-path set, and engine fault-command toggling.

🤖 Generated with Claude Code

…er/gnss/rateOfTurn)

Model diagnostic engine/nav signals that can DEVIATE, plus a shared fault
injector so demos/diagnostics have reproducible anomalies.

New SignalK paths (emitted only when supplied, like runTime):
  propulsion.main.oilPressure (Pa), propulsion.main.exhaustTemperature (K),
  electrical.batteries.starter.{voltage,stateOfCharge,current},
  navigation.gnss.{satellites,horizontalDilution,methodQuality,antennaAltitude},
  navigation.rateOfTurn (rad/s).

Shared FaultState (engine/faults.py): {fault_id: {active, severity}}, seeded
from SIM_FAULTS env at boot and toggled live via set_fault/clear_fault commands
(intercepted in Engine.submit_command). Faults OFF by default.
  - low_oil_pressure  -> oilPressure drops toward alarm
  - raw_water_blocked -> exhaust + coolant rise at steady RPM (P2 discriminator)
  - alternator_belt   -> alternator current -> 0 + coupled coolant rise (E2)
  - weak_starter      -> deep crank dip / slow recovery
  - gps_degraded      -> sats down, HDOP up, quality "no GNSS", position jitter

Models in engine/diagnostics.py + extended ThermalModel (wet exhaust + cooling-
fault coupling). Wired engine.tick -> TelemetrySnapshot -> SignalK sink -> writer.
Tests: model nominal ranges, each fault deviates+recovers, raw_water_blocked
integration (exhaust+coolant), writer published-path set, engine fault commands.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@navado
navado merged commit af71c8f into main Jun 22, 2026
3 checks passed
@navado
navado deleted the feat/diagnostic-fault-modeling branch June 22, 2026 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant