From 4f861f653aec8514972476e0c8e30876a58d11ae Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Mon, 15 Jun 2015 23:13:04 +0100 Subject: [PATCH] Track age of heading/speed/altitude; use this when deciding what to emit in FATSV format. --- debian/changelog | 5 +++ net_io.c | 100 ++++++++++++++++++++++++++++++----------------- track.c | 5 ++- track.h | 10 ++++- 4 files changed, 81 insertions(+), 39 deletions(-) diff --git a/debian/changelog b/debian/changelog index 7787566..b6428fe 100644 --- a/debian/changelog +++ b/debian/changelog @@ -13,6 +13,11 @@ dump1090-mutability (1.15~dev) UNRELEASED; urgency=medium * Fix endian issues affecting big-endian hosts in Beast input/output and avrmlat output. (github issue #44) * 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 Thu, 19 Feb 2015 22:39:19 +0000 diff --git a/net_io.c b/net_io.c index 69506f1..fe68a70 100644 --- a/net_io.c +++ b/net_io.c @@ -1422,11 +1422,25 @@ static void writeFATSV() { for (a = Modes.aircrafts; a; a = a->next) { int altValid = 0; int alt = 0; + uint64_t altAge = 999999; + int groundValid = 0; int ground = 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; - uint64_t emittedMillisAgo; + int changed = 0; + char *p, *end; // skip non-ICAO @@ -1441,60 +1455,71 @@ static void writeFATSV() { continue; } - emittedMillisAgo = (now - a->fatsv_last_emitted); - - // don't emit more than once every five seconds - if (emittedMillisAgo < 5000) { - continue; - } + emittedAge = (now - a->fatsv_last_emitted); if (a->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) { - altValid = 1; + altValid = 1; alt = a->altitude; + altAge = now - a->seenAltitude; } if (a->bFlags & MODES_ACFLAGS_AOG_VALID) { groundValid = 1; if (a->bFlags & MODES_ACFLAGS_AOG) { + // force zero altitude on ground alt = 0; + altValid = 1; + altAge = 0; ground = 1; } } if (a->bFlags & MODES_ACFLAGS_LATLON_VALID) { latlonValid = 1; + latlonAge = now - a->seenLatLon; } - // if it's over 10,000 feet, don't emit more than once every 10 seconds - if (alt > 10000 && emittedMillisAgo < 10000) { + if (a->bFlags & MODES_ACFLAGS_HEADING_VALID) { + 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; } - // disable if you want only ads-b - // also don't send mode S very often - if (!latlonValid) { - if (emittedMillisAgo < 30000) { + // if it hasn't changed altitude, heading, or speed much, + // don't update so often + changed = 0; + 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; - } } else { - // if it hasn't changed altitude very much and it hasn't changed - // heading very much, don't update real often - 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; - } - } else { - // above 10,000 feet, don't update so often when it - // hasn't changed much - if (emittedMillisAgo < 30000) { - continue; - } - } - } + // Above 10000 feet, emit up to every 10s when changing, 30s otherwise + if (changed && emittedAge < 10000) + continue; + if (!changed && emittedAge < 30000) + continue; } 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); } - 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); useful = 1; } - if (a->bFlags & MODES_ACFLAGS_SPEED_VALID) { + if (speedValid && speedAge < emittedAge) { p += snprintf(p, bufsize(p,end), "\tspeed\t%d", a->speed); 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); useful = 1; } - if (a->bFlags & MODES_ACFLAGS_HEADING_VALID) { + if (trackValid && trackAge < emittedAge) { p += snprintf(p, bufsize(p,end), "\theading\t%d", a->track); useful = 1; } @@ -1559,6 +1586,7 @@ static void writeFATSV() { a->fatsv_last_emitted = now; a->fatsv_emitted_altitude = alt; a->fatsv_emitted_track = a->track; + a->fatsv_emitted_speed = a->speed; } } diff --git a/track.c b/track.c index 8907f2c..52896dc 100644 --- a/track.c +++ b/track.c @@ -147,7 +147,7 @@ static int speed_check(struct aircraft *a, struct modesMessage *mm, double lat, speed = (mm->velocity + a->speed) / 2; else if (mm->bFlags & MODES_ACFLAGS_SPEED_VALID) 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; else speed = surface ? 100 : 600; // guess @@ -469,6 +469,7 @@ struct aircraft *trackUpdateFromMessage(struct modesMessage *mm) } a->altitude = mm->altitude; a->modeC = (mm->altitude + 49) / 100; + a->seenAltitude = now; } // 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 (mm->bFlags & MODES_ACFLAGS_HEADING_VALID) { a->track = mm->heading; + a->seenTrack = now; } // If a (new) SPEED has been received, copy it to the aircraft structure if (mm->bFlags & MODES_ACFLAGS_SPEED_VALID) { a->speed = mm->velocity; + a->seenSpeed = now; } // If a (new) Vertical Descent rate has been received, copy it to the aircraft structure diff --git a/track.h b/track.h index fdb3bbd..734f9e2 100644 --- a/track.h +++ b/track.h @@ -68,8 +68,13 @@ struct aircraft { int speed; // Velocity int track; // Angle of flight int vert_rate; // Vertical rate. + 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 int modeA; // Squawk int modeC; // Altitude @@ -78,7 +83,8 @@ struct aircraft { int modeACflags; // Flags for mode A/C recognition 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 // Encoded latitude and longitude as extracted by odd and even CPR encoded messages