Track age of heading/speed/altitude; use this when deciding what to emit in FATSV format.

This commit is contained in:
Oliver Jowett 2015-06-15 23:13:04 +01:00
parent 03b53c2d29
commit 4f861f653a
4 changed files with 81 additions and 39 deletions

5
debian/changelog vendored
View file

@ -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

View file

@ -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,60 +1455,71 @@ 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) {
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; 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) { continue;
if (alt < 10000) { if (!changed && emittedAge < 30000)
// it hasn't changed much but we're below 10,000 feet continue;
// so update more frequently
if (emittedMillisAgo < 10000) {
continue;
}
} else {
// above 10,000 feet, don't update so often when it
// hasn't changed much
if (emittedMillisAgo < 30000) {
continue;
}
}
}
} }
p = prepareWrite(&Modes.fatsv_out, TSV_MAX_PACKET_SIZE); p = prepareWrite(&Modes.fatsv_out, TSV_MAX_PACKET_SIZE);
@ -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;
} }
} }

View file

@ -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
View file

@ -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