Fix aircraft track propagation issues in web frontend

This commit addresses issue #23 where aircraft track changes were not
propagating properly to the web frontend. The fixes include:

**Server-side improvements:**
- Enhanced WebSocket broadcast reliability with timeout-based queueing
- Increased broadcast channel buffer size (1000 -> 2000)
- Improved error handling and connection management
- Added write timeouts to prevent slow clients from blocking updates
- Enhanced connection cleanup and ping/pong handling
- Added debug endpoint /api/debug/websocket for troubleshooting
- Relaxed position validation thresholds for better track acceptance

**Frontend improvements:**
- Enhanced WebSocket manager with exponential backoff reconnection
- Improved aircraft position update detection and logging
- Fixed position update logic to always propagate changes to map
- Better coordinate validation and error reporting
- Enhanced debugging with detailed console logging
- Fixed track rotation update thresholds and logic
- Improved marker lifecycle management and cleanup
- Better handling of edge cases in aircraft state transitions

**Key bug fixes:**
- Removed overly aggressive position change detection that blocked updates
- Fixed track rotation sensitivity (5° -> 10° threshold)
- Enhanced coordinate validation to handle null/undefined values
- Improved WebSocket message ordering and processing
- Fixed marker position updates to always propagate to Leaflet

These changes ensure reliable real-time aircraft tracking with proper
position, heading, and altitude updates across multiple data sources.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2025-08-25 10:14:03 +02:00
commit 1fe15c06a3
6 changed files with 216 additions and 49 deletions

View file

@ -35,9 +35,9 @@ const (
// MaxDistance represents an infinite distance for initialization
MaxDistance = float64(999999)
// Position validation constants
// Position validation constants - relaxed for better track propagation
MaxSpeedKnots = 2000.0 // Maximum plausible aircraft speed (roughly Mach 3 at cruise altitude)
MaxDistanceNautMiles = 500.0 // Maximum position jump distance in nautical miles
MaxDistanceNautMiles = 1000.0 // Maximum position jump distance in nautical miles (increased from 500)
MaxAltitudeFeet = 60000 // Maximum altitude in feet (commercial ceiling ~FL600)
MinAltitudeFeet = -500 // Minimum altitude (below sea level but allow for dead sea, etc.)
@ -576,7 +576,7 @@ func (m *Merger) mergeAircraftData(state *AircraftState, new *modes.Aircraft, so
if new.TransponderLevel > 0 {
state.TransponderLevel = new.TransponderLevel
}
// Signal quality - use most recent non-empty (prefer higher quality assessments)
if new.SignalQuality != "" {
// Simple quality ordering: Excellent > Good > Fair > Poor
@ -584,7 +584,7 @@ func (m *Merger) mergeAircraftData(state *AircraftState, new *modes.Aircraft, so
(new.SignalQuality == "Excellent") ||
(new.SignalQuality == "Good" && state.SignalQuality != "Excellent") ||
(new.SignalQuality == "Fair" && state.SignalQuality == "Poor")
if shouldUpdate {
state.SignalQuality = new.SignalQuality
}
@ -986,8 +986,8 @@ func (m *Merger) validatePosition(aircraft *modes.Aircraft, state *AircraftState
speedKnots, MaxSpeedKnots))
}
// Warning for high but possible speeds (>800 knots)
if speedKnots > 800 && speedKnots <= MaxSpeedKnots {
// Warning for high but possible speeds (>1000 knots) - increased threshold
if speedKnots > 1000 && speedKnots <= MaxSpeedKnots {
result.Warnings = append(result.Warnings, fmt.Sprintf("High speed detected: %.0f knots", speedKnots))
}
} else if timeDiff < 0 {