feat: Phase-3 diagnostic signals + fault injection (oil/exhaust/starter/gnss/rateOfTurn) - #5
Merged
Merged
Conversation
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.propulsion.main.oilPressurepropulsion.main.exhaustTemperatureelectrical.batteries.starter.voltageelectrical.batteries.starter.stateOfChargeelectrical.batteries.starter.currentnavigation.gnss.satellitesnavigation.gnss.horizontalDilutionnavigation.gnss.methodQualitynavigation.gnss.antennaAltitudenavigation.rateOfTurngps_degradedalso re-emitsnavigation.positionwith a jitter offset (physics state untouched).alternator_beltdrives the already-publishedelectrical.alternators.1.current/powerto 0 while running.Fault mechanism
engine/faults.py::FaultStateholds{fault_id: {active, severity}}. Seeded fromSIM_FAULTS="raw_water_blocked,alternator_belt"at boot AND toggled live viaset_fault/clear_faultcommands (intercepted inEngine.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, araw_water_blockedintegration check (exhaust + coolant rise at steady RPM), the writer published-path set, and engine fault-command toggling.🤖 Generated with Claude Code