7.8 KiB
7.8 KiB
MOTORSIGNAL DEBUGGING MAP
This document maps common symptoms in the MotorSignal app to their specific root causes in the GNSS/Telemetry/Speedometer subsystems. Use this guide to jump directly to the responsible layer during triage.
1. Symptom: "Speedometer shows 0 while moving"
Possible Causes & Investigation:
- Permissions Issue: If OS-level location permissions were denied or revoked,
LocationServicestream does not initialize.- Check:
LocationService.hasPermissions()
- Check:
- Deadband Overreach: If the rider is moving slower than 1.3 MPH (0.6 m/s),
LocationService._applyEmaFilterenforces 0.0 to prevent stationary jitter.- Check:
LocationService._applyEmaFilter
- Check:
- Validation Rejection: The OS is sending fixes with terrible accuracy (> 80m-100m) or physically impossible acceleration, causing
LocationService._isValidPositionto silently drop the fix instead of updating the EMA.- Check: Look for
Accuracy poororImpossible accelerationlogs from_emitGpsDiagnostic.
- Check: Look for
2. Symptom: "Speedometer freezes at a high speed during a tunnel/dead zone"
Possible Causes & Investigation:
- Signal Loss Freeze: When GPS fixes stop arriving,
LocationServicestops emitting new positions. However,TelemetryService._emitSample()continues to fire at 20Hz using_latestPosition(which contains the last known high speed).- Status (RESOLVED):
- Recording Health (Phase 1D):
RideStateMachine._recordTelemetryEvidence()checks_lastSeenGpsTimestampand only refreshes GPS freshness when a genuinely newer GPS fix arrives. AfterevidenceStaleAfterMs(4000 ms) without a new fix,RideStateMachinetruthfully transitions recording health toDEGRADED. - Speed Presentation (Phase 1E):
TelemetrySamplenow exposesisSpeedFreshandfreshSpeed, evaluating the GNSS fix age against the canonical 4000 ms staleness bound.SpeedReadoutconsumesfreshSpeedand truthfully presents--when GPS is stale or unavailable, preventing frozen speeds from being displayed while avoiding fabricated zero-speed measurements. When fresh GPS fixes resume, numerical speed presentation automatically recovers.
- Recording Health (Phase 1D):
- Status (RESOLVED):
3. Symptom: "Speedometer lags significantly behind real-world braking/acceleration"
Possible Causes & Investigation:
- EMA Tuning Conflict:
LocationService._applyEmaFilteruses a fast dynamic alpha (0.90) for accelerating/braking and 0.75 for cruising. If the delta threshold (> 0.4 m/s) isn't being tripped cleanly due to noisy GPS, it may stick to the slower 0.75 cruising alpha.- Check:
LocationService._applyEmaFilter
- Check:
4. Symptom: "Leaning the bike on the kickstand records a new 'Max Lean Angle' record"
Possible Causes & Investigation:
- Low-Speed Gate Failure:
RideStateMachine._processStatsrestricts dynamic metrics (lean, accel, braking) to speeds>= 3.0 MPH. If a false GPS speed spike momentarily registers > 3.0 MPH while the bike is tilted on the kickstand, it can permanently updatestate.maxLeanLeftorstate.maxLeanRight.- Check:
RideStateMachine._processStats(isDynamicallyMoving = sample.speed! >= 3.0).
- Check:
5. Symptom: "App constantly auto-starts a ride while parked in the driveway"
Possible Causes & Investigation:
- Auto-Start Jitter:
RideStateMachine._onTelemetryUpdatepromotes areadystate toridingifsample.speed! >= 1.5. IfLocationServicefails to enforce the 0.6 m/s (1.3 MPH) deadband correctly, GPS multipath bounce in a driveway can trigger a false start.- Check:
LocationService._applyEmaFilterdeadband logic.
- Check:
6. Symptom: "Dashboard flickers or UI lags severely during high-speed rides"
Possible Causes & Investigation:
- Provider Granularity Issue: The dashboard is supposed to isolate high-frequency (20Hz) UI updates entirely within
SpeedReadout(which uses.selecton the telemetry provider). If an outer widget (likeResponsiveDashboardLayoutorDashboardScreen) accidentally watches the roottelemetryStreamProviderwithout.select, it will trigger 20 rebuilds per second of the entire screen.- Check:
EvolutionPortraitDashboardandResponsiveDashboardLayoutusage ofref.watch.
- Check:
7. Symptom: "GPS Weak / Degraded indicator won't go away even with clear skies"
Possible Causes & Investigation:
- Pre-commit DB Failure or Watchdog Staleness: The dashboard claims
RECORDINGorDEGRADEDbased entirely on the primaryRecordingHealthContractinRideStateMachine. If_lastDbCommitMonotonicMsstops advancing (due to a SQLite deadlock) or_lastAcceptedTelemetryTimestops advancing, health defaults to degraded.- Check: Database flush interval in
RideStateMachine._persistOwnedTelemetrySnapshotand the_evaluateRecordingHealthwatchdog loop.
- Check: Database flush interval in
8. Symptom: "Trip distance or moving time inflated after riding through tunnel/dead zone"
Possible Causes & Investigation:
- Stale GNSS Integration (RESOLVED in Phase 1F): When GPS fixes stop advancing,
TelemetryServiceemits cached positions at 20Hz. Previously,_movingTimeAccumulatorcontinued to increment based on the cached speed, and upon GPS recovery, the distance between pre-outage coordinates and post-outage coordinates could be added as an artificial catch-up jump.- Resolution:
RideStateMachine._processStatsgates moving/stopped time onsample.isSpeedFresh && _lastSample!.isSpeedFresh. Distance and elevation requirehasFreshGps = sample.isSpeedFresh && (_lastSample?.isSpeedFresh ?? false). When GPS is lost, time and distance cease accumulating; upon recovery, the first fresh fix resets baseline coordinates without integrating across the outage gap. - Check:
RideStateMachine._processStatstime accumulation, distance, and elevation gating.
- Resolution:
9. Symptom: "Performance launch timer records anomalous 0-60 time or finishes without GPS"
Possible Causes & Investigation:
- Stale Speed in Performance State Machine (RESOLVED in Phase 1F): If GPS fixes stop during an active launch or countdown, the state machine previously retained cached speeds, allowing runs to complete across signal loss or trigger high-speed launch anomalies upon recovery.
- Resolution:
PerformanceLaunchStateMachineandPerformanceTimerServiceinspectsample.isSpeedFresh. Inlaunchedorcountdown, active runs abort immediately withPerformanceAbortReason.gpsLost. Inready, the state machine reverts toidle, preventing high-speed launch anomalies when fresh GPS resumes. - Check:
PerformanceLaunchStateMachine._onTelemetryUpdateandPerformanceTimerService._onTelemetryUpdate.
- Resolution:
10. Symptom: "Compass/Heading indicator remains stuck pointing in old direction after turning into tunnel/garage"
Possible Causes & Investigation:
- Stale GNSS Heading Override (RESOLVED in Phase 1G): When GPS fixes stopped advancing while moving,
TelemetryServicecontinued to use the cached_latestPosition.heading, overriding live compass heading indefinitely.- Resolution:
TelemetryService._emitSample()gates GPS heading selection onisGpsFresh(4000 ms bound). When GPS fix age exceeds 4000 ms, heading immediately falls back to live hardware compass. - Check:
TelemetryService._emitSample()heading selection andCompassService.headingStream.
- Resolution:
11. Symptom: "Map marker shows vehicle at active location when GPS signal is lost"
Possible Causes & Investigation:
- Unindicated Stale Map Coordinate (RESOLVED in Phase 1G):
DashboardMapPanelrendered the vehicle marker identically whether coordinates were current or stale.- Resolution:
DashboardMapPanelwatchess.value?.isGpsFresh. When stale, the marker is dimmed and a subtleLAST KNOWN LOCATIONbadge is displayed, preserving the last-known position truthfully without fabricating position. - Check:
DashboardMapPanelandTelemetrySample.isGpsFresh.
- Resolution: