mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
fix(military): hold the last track and speed when a poll omits them
MilitaryFlightRecords coerced a missing course to 0 (`courseDeg || 0`) and a missing speed to 0 (`speedMps ?? 0`) before stickyNumber, so the hold-last-known-good merge never ran. When an adsb.lol row arrived without `track` or `gs`, the aircraft's icon swung to north and the position history got a 0 kt / 0 degree fix, so dead reckoning stopped or turned it north. The civil FlightRecords holds the last value for the same input. Pass the raw values to stickyNumber, with 0 as the fallback only until a value is known, as before. A grounded row without a speed still reads 0, so a parked aircraft doesn't coast at its landing speed.
This commit is contained in:
1 parent
d4492d8f8c
commit
557d3bb41e
4 files changed
+52
-5
No files matched your search
@@ -1,5 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
- Military aircraft keep their last heading and speed when an adsb.lol row omits
|
||||
`track` or `gs`, instead of turning north and stopping; a grounded row without
|
||||
a speed still reads 0.
|
||||
|
||||
- Add Barcelona's bike share to the GBFS registry: Bicing (543 stations, the
|
||||
city's PBSC system) and AMBici (237 e-bike stations across the metropolitan
|
||||
area, run by nextbike). Both are keyless GBFS 2.3 feeds listed in
|
||||
|
||||
@@ -584,7 +584,9 @@ pinning, first-position grace, source time and sea-surface placement are unchang
|
||||
|
||||
Military flights also separate portable records and source acquisition from
|
||||
Cesium snapshot application. The metadata owner retains aviation feet, source
|
||||
fix times, sticky fields and partial-feed retention. Rendering retains ground
|
||||
fix times, sticky fields and partial-feed retention. A row without track or
|
||||
speed holds the last known value, as civil records do; a grounded row without
|
||||
speed reads 0. Rendering retains ground
|
||||
model ownership, motion history, military registration and tracking cleanup.
|
||||
|
||||
Civil flights separate source acquisition, portable record reconciliation and
|
||||
|
||||
@@ -39,8 +39,6 @@ export class MilitaryFlightRecords {
|
||||
? prevMeta.altitudeFt * 0.3048
|
||||
: 0
|
||||
: 3048);
|
||||
const track = aircraft.courseDeg || 0;
|
||||
const speedMps = aircraft.speedMps ?? 0;
|
||||
const verticalRateMps = aircraft.verticalRateMps;
|
||||
const callsign = aircraft.callsign;
|
||||
const type = aircraft.typeCode;
|
||||
@@ -148,8 +146,15 @@ export class MilitaryFlightRecords {
|
||||
// altitudeFt/baro).
|
||||
geoAltitudeM,
|
||||
renderAltitudeM,
|
||||
speedMps: stickyNumber(speedMps, prevMeta?.speedMps, null),
|
||||
track: stickyNumber(track, prevMeta?.track, null),
|
||||
// A poll that omits track/speed holds the last values, like the civil
|
||||
// records; 0 only until one is known. A grounded row without a speed
|
||||
// reads 0, so a parked plane never coasts at its landing speed.
|
||||
speedMps: stickyNumber(
|
||||
aircraft.speedMps,
|
||||
onGround ? 0 : prevMeta?.speedMps,
|
||||
0,
|
||||
),
|
||||
track: stickyNumber(aircraft.courseDeg, prevMeta?.track, 0),
|
||||
// Analyst seam (additive): sticky like the other kinematics.
|
||||
verticalRateMps: stickyNumber(
|
||||
verticalRateMps,
|
||||
|
||||
@@ -114,3 +114,39 @@ test('military emergency status follows the latest poll instead of sticking', ()
|
||||
);
|
||||
assert.equal(next.meta.emergency, null);
|
||||
});
|
||||
|
||||
test('military records hold the last track and speed when a poll omits them', () => {
|
||||
const records = store();
|
||||
records.receive(observation({ courseDeg: 270, speedMps: 200 }), context());
|
||||
const missing = records.receive(
|
||||
observation({ courseDeg: null, speedMps: null }),
|
||||
context(),
|
||||
);
|
||||
assert.equal(missing.meta.track, 270);
|
||||
assert.equal(missing.meta.speedMps, 200);
|
||||
const north = records.receive(
|
||||
observation({ courseDeg: 0, speedMps: 0 }),
|
||||
context(),
|
||||
);
|
||||
assert.equal(north.meta.track, 0);
|
||||
assert.equal(north.meta.speedMps, 0);
|
||||
const unseen = store().receive(
|
||||
observation({ courseDeg: undefined, speedMps: undefined }),
|
||||
context(),
|
||||
);
|
||||
assert.equal(unseen.meta.track, 0);
|
||||
assert.equal(unseen.meta.speedMps, 0);
|
||||
const landing = store();
|
||||
landing.receive(observation({ courseDeg: 90, speedMps: 70 }), context());
|
||||
const parked = landing.receive(
|
||||
observation({
|
||||
onGround: true,
|
||||
baroAltitudeM: null,
|
||||
courseDeg: null,
|
||||
speedMps: null,
|
||||
}),
|
||||
context(),
|
||||
);
|
||||
assert.equal(parked.meta.speedMps, 0);
|
||||
assert.equal(parked.meta.track, 90);
|
||||
});
|
||||
Reference in new issue
Block a user