diff --git a/changelog.d/1654-flight-trails-signal-lost.md b/changelog.d/1654-flight-trails-signal-lost.md new file mode 100644 index 000000000..933708459 --- /dev/null +++ b/changelog.d/1654-flight-trails-signal-lost.md @@ -0,0 +1,7 @@ +- A tracked flight's trail splits at feed gaps, impossible jumps and reports + without altitude instead of joining a day of history into one line, keeps + every history point, and follows the path the aircraft was drawn along so it + no longer cuts across turns. A tracked aircraft that stops reporting shows + STALE, keeps flying on its last heading for five minutes, then stops dimmed + as SIGNAL LOST and is kept ten minutes after its last report; aircraft on or + near the ground hold instead (Sameh Khamis, @samehkhamis, #1654). diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index 4fa9edd5b..1f92e1cf7 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -1444,6 +1444,52 @@ use the supplied asset resolver, including the preload path. Enrichment receives an abort signal and cannot update a later lifecycle after destruction. Existing camera, terrain floor, trail, selection and measured model-size policies remain. +A tracked civil or military aircraft's trail (`src/data/trailContinuity.js`) lifts +the pen, drawing nothing, between two points more than 48 minutes or over 1,500 kt +apart (a parked aircraft within 0.1 nm keeps one line for up to three hours) and at a +waypoint with no altitude; a ground waypoint is drawn on the ground. The head joins the +aircraft only within 150 km. Each trail keeps up to 2,000 points, a full day of history +at one fix per minute plus the live session; past that the oldest recorded points go +first, and the oldest reports only once none are left. The renderer +(`src/data/trailRenderer.js`) freezes every chunk of 128 points except the newest into +static geometry, so a long trail costs about as much per frame as a short one; +`scripts/qa-trail-freeze.mjs` checks that a freeze never shows a blank frame. +While an aircraft is tracked, its trail between reports is the path its icon was +drawn along: the displayed position is recorded about once a second or every 150 m +(`recordTrailPoint`). Recorded points are thinned by shape: one stays only where +dropping it would move the line more than 30 m across the track or in height from any +position it stood for, or leave a straight piece longer than 10 km, so straight flight +adds a vertex every 10 km at most and a turn keeps its curve. A recorded point that +would turn the line back sharper than 120° over a short step is dropped. Reports stay +in the trail as anchors, in time order. Recorded points never join two reports that are +not one flight under the 48-minute and 1,500 kt rules; the points between them go and +nothing is recorded across such a pair. A report for a time the display has already +passed replaces what was drawn after it, and nothing is recorded until the icon has +eased onto it, so the line reads arc, report, corrected path. History from before tracking started, and the backfill, run report to report. +The trail never runs past the icon or through its 3D model, and the head runs from the +newest kept point outside the model to the icon (to the model's tail when the model is +the visual). A contact with no new report coasts along its reported track for 5 minutes +past its last real report, at no more than 1,500 kt and never below known ground, then stops; +one that +went quiet on the ground, or within 150 m of a known ground floor, holds at its last +report, records nothing and draws no head (with the ground unknown, a low barometric +altitude alone does not hold it). The hold-or-coast choice is made once per report (`staleHoldsForFix` +in `src/data/motionModel.js`), and the forward fix built when a repeated position carries +new speed or course follows the same rules and is never a trail report. A live report +with no altitude breaks the line and leaves no point at an invented height, and so does +such a report seeded from position history when tracking starts. + +A contact that misses an update is stale from the first miss: it is drawn with the +45%-alpha stale fade (`STALE_ALPHA`), the tracked billboard and 3D model included, and the +tracked label reads STALE. For the tracked aircraft a poll that re-sends a fix no newer +than the last one is a miss too. Once its coast has ended, or it holds at its last report +after a miss, it stands still, dimmed, and the label reads SIGNAL LOST ·