Track age of heading/speed/altitude; use this when deciding what to emit in FATSV format.
This commit is contained in:
parent
03b53c2d29
commit
4f861f653a
5
debian/changelog
vendored
5
debian/changelog
vendored
|
@ -13,6 +13,11 @@ dump1090-mutability (1.15~dev) UNRELEASED; urgency=medium
|
||||||
* Fix endian issues affecting big-endian hosts in Beast input/output
|
* Fix endian issues affecting big-endian hosts in Beast input/output
|
||||||
and avrmlat output. (github issue #44)
|
and avrmlat output. (github issue #44)
|
||||||
* Fix queueing/resending very old Mode A/C messages (github issue #47)
|
* Fix queueing/resending very old Mode A/C messages (github issue #47)
|
||||||
|
* Support a variety of sample input formats, generalize sample conversion
|
||||||
|
* Support noise measurement via --measure-noise
|
||||||
|
* Support DC filtering (quite expensive) via --dcfilter
|
||||||
|
* Track age of heading/speed/altitude; use this when deciding what to emit
|
||||||
|
in FATSV format
|
||||||
|
|
||||||
-- Oliver Jowett <oliver@mutability.co.uk> Thu, 19 Feb 2015 22:39:19 +0000
|
-- Oliver Jowett <oliver@mutability.co.uk> Thu, 19 Feb 2015 22:39:19 +0000
|
||||||
|
|
||||||
|
|
94
net_io.c
94
net_io.c
|
@ -1422,11 +1422,25 @@ static void writeFATSV() {
|
||||||
for (a = Modes.aircrafts; a; a = a->next) {
|
for (a = Modes.aircrafts; a; a = a->next) {
|
||||||
int altValid = 0;
|
int altValid = 0;
|
||||||
int alt = 0;
|
int alt = 0;
|
||||||
|
uint64_t altAge = 999999;
|
||||||
|
|
||||||
int groundValid = 0;
|
int groundValid = 0;
|
||||||
int ground = 0;
|
int ground = 0;
|
||||||
|
|
||||||
int latlonValid = 0;
|
int latlonValid = 0;
|
||||||
|
uint64_t latlonAge = 999999;
|
||||||
|
|
||||||
|
int speedValid = 0;
|
||||||
|
uint64_t speedAge = 999999;
|
||||||
|
|
||||||
|
int trackValid = 0;
|
||||||
|
uint64_t trackAge = 999999;
|
||||||
|
|
||||||
|
uint64_t emittedAge;
|
||||||
|
|
||||||
int useful = 0;
|
int useful = 0;
|
||||||
uint64_t emittedMillisAgo;
|
int changed = 0;
|
||||||
|
|
||||||
char *p, *end;
|
char *p, *end;
|
||||||
|
|
||||||
// skip non-ICAO
|
// skip non-ICAO
|
||||||
|
@ -1441,61 +1455,72 @@ static void writeFATSV() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
emittedMillisAgo = (now - a->fatsv_last_emitted);
|
emittedAge = (now - a->fatsv_last_emitted);
|
||||||
|
|
||||||
// don't emit more than once every five seconds
|
|
||||||
if (emittedMillisAgo < 5000) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) {
|
if (a->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) {
|
||||||
altValid = 1;
|
altValid = 1;
|
||||||
alt = a->altitude;
|
alt = a->altitude;
|
||||||
|
altAge = now - a->seenAltitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->bFlags & MODES_ACFLAGS_AOG_VALID) {
|
if (a->bFlags & MODES_ACFLAGS_AOG_VALID) {
|
||||||
groundValid = 1;
|
groundValid = 1;
|
||||||
|
|
||||||
if (a->bFlags & MODES_ACFLAGS_AOG) {
|
if (a->bFlags & MODES_ACFLAGS_AOG) {
|
||||||
|
// force zero altitude on ground
|
||||||
alt = 0;
|
alt = 0;
|
||||||
|
altValid = 1;
|
||||||
|
altAge = 0;
|
||||||
ground = 1;
|
ground = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->bFlags & MODES_ACFLAGS_LATLON_VALID) {
|
if (a->bFlags & MODES_ACFLAGS_LATLON_VALID) {
|
||||||
latlonValid = 1;
|
latlonValid = 1;
|
||||||
|
latlonAge = now - a->seenLatLon;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if it's over 10,000 feet, don't emit more than once every 10 seconds
|
if (a->bFlags & MODES_ACFLAGS_HEADING_VALID) {
|
||||||
if (alt > 10000 && emittedMillisAgo < 10000) {
|
trackValid = 1;
|
||||||
|
trackAge = now - a->seenTrack;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->bFlags & MODES_ACFLAGS_SPEED_VALID) {
|
||||||
|
speedValid = 1;
|
||||||
|
speedAge = now - a->seenSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't send mode S very often
|
||||||
|
if (!latlonValid && emittedAge < 30000) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable if you want only ads-b
|
// if it hasn't changed altitude, heading, or speed much,
|
||||||
// also don't send mode S very often
|
// don't update so often
|
||||||
if (!latlonValid) {
|
changed = 0;
|
||||||
if (emittedMillisAgo < 30000) {
|
if (trackValid && abs(a->track - a->fatsv_emitted_track) >= 2) {
|
||||||
continue;
|
changed = 1;
|
||||||
}
|
}
|
||||||
|
if (speedValid && abs(a->speed - a->fatsv_emitted_speed) >= 25) {
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
if (altValid && abs(alt - a->fatsv_emitted_altitude) >= 50) {
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!altValid || alt < 10000) {
|
||||||
|
// Below 10000 feet, emit up to every 5s when changing, 10s otherwise
|
||||||
|
if (changed && emittedAge < 5000)
|
||||||
|
continue;
|
||||||
|
if (!changed && emittedAge < 10000)
|
||||||
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// if it hasn't changed altitude very much and it hasn't changed
|
// Above 10000 feet, emit up to every 10s when changing, 30s otherwise
|
||||||
// heading very much, don't update real often
|
if (changed && emittedAge < 10000)
|
||||||
if (abs(a->track - a->fatsv_emitted_track) < 2 && abs(alt - a->fatsv_emitted_altitude) < 50) {
|
|
||||||
if (alt < 10000) {
|
|
||||||
// it hasn't changed much but we're below 10,000 feet
|
|
||||||
// so update more frequently
|
|
||||||
if (emittedMillisAgo < 10000) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
if (!changed && emittedAge < 30000)
|
||||||
} else {
|
|
||||||
// above 10,000 feet, don't update so often when it
|
|
||||||
// hasn't changed much
|
|
||||||
if (emittedMillisAgo < 30000) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p = prepareWrite(&Modes.fatsv_out, TSV_MAX_PACKET_SIZE);
|
p = prepareWrite(&Modes.fatsv_out, TSV_MAX_PACKET_SIZE);
|
||||||
if (!p)
|
if (!p)
|
||||||
|
@ -1513,12 +1538,14 @@ static void writeFATSV() {
|
||||||
p += snprintf(p, bufsize(p,end), "\tsquawk\t%04x", a->modeA);
|
p += snprintf(p, bufsize(p,end), "\tsquawk\t%04x", a->modeA);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (altValid) {
|
// only emit alt, speed, latlon, track if they have been received since the last time
|
||||||
|
|
||||||
|
if (altValid && altAge < emittedAge) {
|
||||||
p += snprintf(p, bufsize(p,end), "\talt\t%d", alt);
|
p += snprintf(p, bufsize(p,end), "\talt\t%d", alt);
|
||||||
useful = 1;
|
useful = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->bFlags & MODES_ACFLAGS_SPEED_VALID) {
|
if (speedValid && speedAge < emittedAge) {
|
||||||
p += snprintf(p, bufsize(p,end), "\tspeed\t%d", a->speed);
|
p += snprintf(p, bufsize(p,end), "\tspeed\t%d", a->speed);
|
||||||
useful = 1;
|
useful = 1;
|
||||||
}
|
}
|
||||||
|
@ -1531,12 +1558,12 @@ static void writeFATSV() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (latlonValid) {
|
if (latlonValid && latlonAge < emittedAge) {
|
||||||
p += snprintf(p, bufsize(p,end), "\tlat\t%.5f\tlon\t%.5f", a->lat, a->lon);
|
p += snprintf(p, bufsize(p,end), "\tlat\t%.5f\tlon\t%.5f", a->lat, a->lon);
|
||||||
useful = 1;
|
useful = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->bFlags & MODES_ACFLAGS_HEADING_VALID) {
|
if (trackValid && trackAge < emittedAge) {
|
||||||
p += snprintf(p, bufsize(p,end), "\theading\t%d", a->track);
|
p += snprintf(p, bufsize(p,end), "\theading\t%d", a->track);
|
||||||
useful = 1;
|
useful = 1;
|
||||||
}
|
}
|
||||||
|
@ -1559,6 +1586,7 @@ static void writeFATSV() {
|
||||||
a->fatsv_last_emitted = now;
|
a->fatsv_last_emitted = now;
|
||||||
a->fatsv_emitted_altitude = alt;
|
a->fatsv_emitted_altitude = alt;
|
||||||
a->fatsv_emitted_track = a->track;
|
a->fatsv_emitted_track = a->track;
|
||||||
|
a->fatsv_emitted_speed = a->speed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
track.c
5
track.c
|
@ -147,7 +147,7 @@ static int speed_check(struct aircraft *a, struct modesMessage *mm, double lat,
|
||||||
speed = (mm->velocity + a->speed) / 2;
|
speed = (mm->velocity + a->speed) / 2;
|
||||||
else if (mm->bFlags & MODES_ACFLAGS_SPEED_VALID)
|
else if (mm->bFlags & MODES_ACFLAGS_SPEED_VALID)
|
||||||
speed = mm->velocity;
|
speed = mm->velocity;
|
||||||
else if (a->bFlags & MODES_ACFLAGS_SPEED_VALID)
|
else if ((a->bFlags & MODES_ACFLAGS_SPEED_VALID) && (now - a->seenSpeed) < 30000)
|
||||||
speed = a->speed;
|
speed = a->speed;
|
||||||
else
|
else
|
||||||
speed = surface ? 100 : 600; // guess
|
speed = surface ? 100 : 600; // guess
|
||||||
|
@ -469,6 +469,7 @@ struct aircraft *trackUpdateFromMessage(struct modesMessage *mm)
|
||||||
}
|
}
|
||||||
a->altitude = mm->altitude;
|
a->altitude = mm->altitude;
|
||||||
a->modeC = (mm->altitude + 49) / 100;
|
a->modeC = (mm->altitude + 49) / 100;
|
||||||
|
a->seenAltitude = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a (new) SQUAWK has been received, copy it to the aircraft structure
|
// If a (new) SQUAWK has been received, copy it to the aircraft structure
|
||||||
|
@ -483,11 +484,13 @@ struct aircraft *trackUpdateFromMessage(struct modesMessage *mm)
|
||||||
// If a (new) HEADING has been received, copy it to the aircraft structure
|
// If a (new) HEADING has been received, copy it to the aircraft structure
|
||||||
if (mm->bFlags & MODES_ACFLAGS_HEADING_VALID) {
|
if (mm->bFlags & MODES_ACFLAGS_HEADING_VALID) {
|
||||||
a->track = mm->heading;
|
a->track = mm->heading;
|
||||||
|
a->seenTrack = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a (new) SPEED has been received, copy it to the aircraft structure
|
// If a (new) SPEED has been received, copy it to the aircraft structure
|
||||||
if (mm->bFlags & MODES_ACFLAGS_SPEED_VALID) {
|
if (mm->bFlags & MODES_ACFLAGS_SPEED_VALID) {
|
||||||
a->speed = mm->velocity;
|
a->speed = mm->velocity;
|
||||||
|
a->seenSpeed = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a (new) Vertical Descent rate has been received, copy it to the aircraft structure
|
// If a (new) Vertical Descent rate has been received, copy it to the aircraft structure
|
||||||
|
|
10
track.h
10
track.h
|
@ -68,8 +68,13 @@ struct aircraft {
|
||||||
int speed; // Velocity
|
int speed; // Velocity
|
||||||
int track; // Angle of flight
|
int track; // Angle of flight
|
||||||
int vert_rate; // Vertical rate.
|
int vert_rate; // Vertical rate.
|
||||||
|
|
||||||
uint64_t seen; // Time (millis) at which the last packet was received
|
uint64_t seen; // Time (millis) at which the last packet was received
|
||||||
uint64_t seenLatLon; // Time (millis) at which the last lat long was calculated
|
uint64_t seenLatLon; // Time (millis) at which lat, lon was measured
|
||||||
|
uint64_t seenAltitude; // Time (millis) at which altitude was measured
|
||||||
|
uint64_t seenSpeed; // Time (millis) at which speed was measured
|
||||||
|
uint64_t seenTrack; // Time (millis) at which track was measured
|
||||||
|
|
||||||
long messages; // Number of Mode S messages received
|
long messages; // Number of Mode S messages received
|
||||||
int modeA; // Squawk
|
int modeA; // Squawk
|
||||||
int modeC; // Altitude
|
int modeC; // Altitude
|
||||||
|
@ -78,7 +83,8 @@ struct aircraft {
|
||||||
int modeACflags; // Flags for mode A/C recognition
|
int modeACflags; // Flags for mode A/C recognition
|
||||||
|
|
||||||
int fatsv_emitted_altitude; // last FA emitted altitude
|
int fatsv_emitted_altitude; // last FA emitted altitude
|
||||||
int fatsv_emitted_track; // last FA emitted angle of flight
|
int fatsv_emitted_track; // last FA emitted track
|
||||||
|
int fatsv_emitted_speed; // last FA emitted speed
|
||||||
uint64_t fatsv_last_emitted; // time (millis) aircraft was last FA emitted
|
uint64_t fatsv_last_emitted; // time (millis) aircraft was last FA emitted
|
||||||
|
|
||||||
// Encoded latitude and longitude as extracted by odd and even CPR encoded messages
|
// Encoded latitude and longitude as extracted by odd and even CPR encoded messages
|
||||||
|
|
Loading…
Reference in a new issue