From efd6b943101fe2ddbef05202c285c2c3cdfbde07 Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Fri, 1 Jan 2016 13:42:30 +0000 Subject: [PATCH] Track HAE altitude separately to baro altitude where possible. --- dump1090.h | 4 ++++ mode_s.c | 31 ++++++++++++++++++++++++++----- track.c | 31 +++++++++++++++++++++++++++++++ track.h | 4 +++- 4 files changed, 64 insertions(+), 6 deletions(-) diff --git a/dump1090.h b/dump1090.h index 23ece25..6050348 100644 --- a/dump1090.h +++ b/dump1090.h @@ -163,6 +163,8 @@ typedef struct rtlsdr_dev rtlsdr_dev_t; #define MODES_ACFLAGS_REL_CPR_USED (1<<16) // Lat/lon derived from relative CPR #define MODES_ACFLAGS_CATEGORY_VALID (1<<17) // Aircraft category is known #define MODES_ACFLAGS_FROM_MLAT (1<<18) // Data was derived from multilateration +#define MODES_ACFLAGS_ALTITUDE_HAE_VALID (1<<19) // altitude_hae is valid +#define MODES_ACFLAGS_HAE_DELTA_VALID (1<<20) // hae_delta is valid #define MODES_ACFLAGS_LLEITHER_VALID (MODES_ACFLAGS_LLEVEN_VALID | MODES_ACFLAGS_LLODD_VALID) #define MODES_ACFLAGS_LLBOTH_VALID (MODES_ACFLAGS_LLEVEN_VALID | MODES_ACFLAGS_LLODD_VALID) @@ -389,6 +391,8 @@ struct modesMessage { int vert_rate; // Vertical rate. int velocity; // Reported by aircraft, or computed from from EW and NS velocity unsigned category; // A0 - D7 encoded as a single hex byte + int altitude_hae; // altitude reported as GNSS HAE + int hae_delta; // difference between HAE and baro alt // DF 18 int cf; // Control Field diff --git a/mode_s.c b/mode_s.c index b81913d..07994dc 100644 --- a/mode_s.c +++ b/mode_s.c @@ -846,6 +846,11 @@ static void decodeExtendedSquitter(struct modesMessage *mm) } } + if (msg[10] != 0) { + mm->bFlags |= MODES_ACFLAGS_HAE_DELTA_VALID; + mm->hae_delta = ((msg[10] & 0x80) ? -25 : 25) * ((msg[10] & 0x7f) - 1); + } + break; } @@ -910,9 +915,18 @@ static void decodeExtendedSquitter(struct modesMessage *mm) } if (AC12Field) {// Only attempt to decode if a valid (non zero) altitude is present - mm->altitude = decodeAC12Field(AC12Field, &mm->unit); - if (mm->altitude != INVALID_ALTITUDE) - mm->bFlags |= MODES_ACFLAGS_ALTITUDE_VALID; + if (metype == 20 || metype == 21 || metype == 22) { + // Position reported as HAE + mm->altitude_hae = decodeAC12Field(AC12Field, &mm->unit); + if (mm->altitude_hae != INVALID_ALTITUDE) { + mm->bFlags |= MODES_ACFLAGS_ALTITUDE_HAE_VALID; + } + } else { + mm->altitude = decodeAC12Field(AC12Field, &mm->unit); + if (mm->altitude != INVALID_ALTITUDE) { + mm->bFlags |= MODES_ACFLAGS_ALTITUDE_VALID; + } + } } if (metype == 0 || metype == 18 || metype == 22) @@ -1011,15 +1025,22 @@ static void displayExtendedSquitter(struct modesMessage *mm) { printf(" Vertical status : %s\n", (mm->bFlags & MODES_ACFLAGS_VERTRATE_VALID) ? "Valid" : "Unavailable"); printf(" Vertical rate src : %d\n", ((mm->msg[8] >> 4) & 1)); printf(" Vertical rate : %d\n", mm->vert_rate); - } else { printf(" Unrecognized ME subtype: %d subtype: %d\n", mm->metype, mm->mesub); } + + if (mm->bFlags & MODES_ACFLAGS_HAE_DELTA_VALID) { + printf(" HAE - Barometric : %d ft\n", mm->hae_delta); + } else { + printf(" HAE - Barometric : not valid\n"); + } } else if (mm->metype >= 5 && mm->metype <= 22) { // Airborne position Baro printf(" F flag : %s\n", (mm->msg[6] & 0x04) ? "odd" : "even"); printf(" T flag : %s\n", (mm->msg[6] & 0x08) ? "UTC" : "non-UTC"); if (mm->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) - printf(" Altitude : %d feet\n", mm->altitude); + printf(" Altitude : %d feet barometric\n", mm->altitude); + else if (mm->bFlags & MODES_ACFLAGS_ALTITUDE_HAE_VALID) + printf(" Altitude : %d feet HAE\n", mm->altitude_hae); else printf(" Altitude : not valid\n"); if (mm->bFlags & MODES_ACFLAGS_LATLON_VALID) { diff --git a/track.c b/track.c index e8ca4d8..744bf88 100644 --- a/track.c +++ b/track.c @@ -522,9 +522,34 @@ struct aircraft *trackUpdateFromMessage(struct modesMessage *mm) a->altitude = mm->altitude; a->modeC = (mm->altitude + 49) / 100; a->seenAltitude = now; + + // reporting of HAE and baro altitudes is mutually exclusive + // so if we see a baro altitude, assume the HAE altitude is invalid + // we will recalculate it from baro + HAE delta below, where possible + a->bFlags &= ~MODES_ACFLAGS_ALTITUDE_HAE_VALID; } } + // If a (new) HAE altitude has been received, copy it to the aircraft structure + if (mm->bFlags & MODES_ACFLAGS_ALTITUDE_HAE_VALID) { + a->altitude_hae = mm->altitude_hae; + + // reporting of HAE and baro altitudes is mutually exclusive + // if you have both, you're meant to report baro and a HAE delta, + // so if we see explicit HAE then assume the delta is invalid too + a->bFlags &= ~(MODES_ACFLAGS_ALTITUDE_VALID | MODES_ACFLAGS_HAE_DELTA_VALID); + } + + // If a (new) HAE/barometric difference has been received, copy it to the aircraft structure + if (mm->bFlags & MODES_ACFLAGS_HAE_DELTA_VALID) { + a->hae_delta = mm->hae_delta; + + // reporting of HAE and baro altitudes is mutually exclusive + // if you have both, you're meant to report baro and a HAE delta, + // so if we see a HAE delta then assume the HAE altitude is invalid + a->bFlags &= ~MODES_ACFLAGS_ALTITUDE_HAE_VALID; + } + // If a (new) SQUAWK has been received, copy it to the aircraft structure if (mm->bFlags & MODES_ACFLAGS_SQUAWK_VALID) { if (a->modeA != mm->modeA) { @@ -559,6 +584,12 @@ struct aircraft *trackUpdateFromMessage(struct modesMessage *mm) // Update the aircrafts a->bFlags to reflect the newly received mm->bFlags; a->bFlags |= mm->bFlags; + // If we have a baro altitude and a HAE delta from baro, calculate the HAE altitude + if ((a->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) && (a->bFlags & MODES_ACFLAGS_HAE_DELTA_VALID)) { + a->altitude_hae = a->altitude + a->hae_delta; + a->bFlags |= MODES_ACFLAGS_ALTITUDE_HAE_VALID; + } + // Update mlat flags. The mlat flags indicate which bits in bFlags // were last set based on a mlat-derived message. if (mm->bFlags & MODES_ACFLAGS_FROM_MLAT) diff --git a/track.h b/track.h index 51f74b8..84ee85b 100644 --- a/track.h +++ b/track.h @@ -64,7 +64,9 @@ struct aircraft { uint32_t addr; // ICAO address char flight[16]; // Flight number double signalLevel[8]; // Last 8 Signal Amplitudes - int altitude; // Altitude + int altitude; // Altitude (Baro) + int altitude_hae; // Altitude (HAE) + int hae_delta; // Difference between HAE and Baro altitudes int speed; // Velocity int track; // Angle of flight int vert_rate; // Vertical rate.