From f46640a5c2a8738581091db2ffe4bb3b3f96de4a Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Tue, 19 Mar 2019 18:44:09 +0000 Subject: [PATCH] Track and report autopilot FMS/MCP separately; also report autopilot altitude source. --- dump1090.h | 6 +++++- net_io.c | 38 ++++++++++++++++++++++++++++++-------- track.c | 24 ++++++++++++++++-------- track.h | 14 +++++++++++--- 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/dump1090.h b/dump1090.h index 3c4b93b..43e6109 100644 --- a/dump1090.h +++ b/dump1090.h @@ -227,6 +227,10 @@ typedef enum { EMERGENCY_RESERVED = 7 } emergency_t; +typedef enum { + NAV_ALT_INVALID, NAV_ALT_UNKNOWN, NAV_ALT_AIRCRAFT, NAV_ALT_MCP, NAV_ALT_FMS +} nav_altitude_source_t; + #define MODES_NON_ICAO_ADDRESS (1<<24) // Set on addresses to indicate they are not ICAO addresses #define MODES_DEBUG_DEMOD (1<<0) @@ -581,7 +585,7 @@ struct modesMessage { unsigned mcp_altitude; // MCP/FCU selected altitude float qnh; // altimeter setting (QFE or QNH/QNE), millibars - enum { NAV_ALT_INVALID, NAV_ALT_UNKNOWN, NAV_ALT_AIRCRAFT, NAV_ALT_MCP, NAV_ALT_FMS } altitude_source; + nav_altitude_source_t altitude_source; nav_modes_t modes; } nav; diff --git a/net_io.c b/net_io.c index 09547b7..2d8c0b8 100644 --- a/net_io.c +++ b/net_io.c @@ -1155,8 +1155,10 @@ static char *append_flags(char *p, char *end, struct aircraft *a, datasource_t s p = safe_snprintf(p, end, "\"emergency\","); if (a->nav_qnh_valid.source == source) p = safe_snprintf(p, end, "\"nav_qnh\","); - if (a->nav_altitude_valid.source == source) - p = safe_snprintf(p, end, "\"nav_altitude\","); + if (a->nav_altitude_mcp_valid.source == source) + p = safe_snprintf(p, end, "\"nav_altitude_mcp\","); + if (a->nav_altitude_fms_valid.source == source) + p = safe_snprintf(p, end, "\"nav_altitude_fms\","); if (a->nav_heading_valid.source == source) p = safe_snprintf(p, end, "\"nav_heading\","); if (a->nav_modes_valid.source == source) @@ -1267,6 +1269,18 @@ static const char *sil_type_enum_string(sil_type_t type) } } +static const char *nav_altitude_source_enum_string(nav_altitude_source_t src) +{ + switch (src) { + case NAV_ALT_INVALID: return "invalid"; + case NAV_ALT_UNKNOWN: return "unknown"; + case NAV_ALT_AIRCRAFT: return "aircraft"; + case NAV_ALT_MCP: return "mcp"; + case NAV_ALT_FMS: return "fms"; + default: return "invalid"; + } +} + char *generateAircraftJson(const char *url_path, int *len) { uint64_t now = mstime(); struct aircraft *a; @@ -1341,8 +1355,10 @@ char *generateAircraftJson(const char *url_path, int *len) { p = safe_snprintf(p, end, ",\"category\":\"%02X\"", a->category); if (trackDataValid(&a->nav_qnh_valid)) p = safe_snprintf(p, end, ",\"nav_qnh\":%.1f", a->nav_qnh); - if (trackDataValid(&a->nav_altitude_valid)) - p = safe_snprintf(p, end, ",\"nav_altitude\":%d", a->nav_altitude); + if (trackDataValid(&a->nav_altitude_mcp_valid)) + p = safe_snprintf(p, end, ",\"nav_altitude_mcp\":%d", a->nav_altitude_mcp); + if (trackDataValid(&a->nav_altitude_fms_valid)) + p = safe_snprintf(p, end, ",\"nav_altitude_fms\":%d", a->nav_altitude_fms); if (trackDataValid(&a->nav_heading_valid)) p = safe_snprintf(p, end, ",\"nav_heading\":%.1f", a->nav_heading); if (trackDataValid(&a->nav_modes_valid)) { @@ -2119,7 +2135,9 @@ static void writeFATSV() (trackDataValid(&a->mach_valid) && fabs(a->mach - a->fatsv_emitted_mach) >= 0.02); int immediate = - (trackDataValid(&a->nav_altitude_valid) && unsigned_difference(a->nav_altitude, a->fatsv_emitted_nav_altitude) > 50) || + (trackDataValid(&a->nav_altitude_mcp_valid) && unsigned_difference(a->nav_altitude_mcp, a->fatsv_emitted_nav_altitude_mcp) > 50) || + (trackDataValid(&a->nav_altitude_fms_valid) && unsigned_difference(a->nav_altitude_fms, a->fatsv_emitted_nav_altitude_fms) > 50) || + (trackDataValid(&a->nav_altitude_src_valid) && a->nav_altitude_src != a->fatsv_emitted_nav_altitude_src) || (trackDataValid(&a->nav_heading_valid) && heading_difference(a->nav_heading, a->fatsv_emitted_nav_heading) > 2) || (trackDataValid(&a->nav_modes_valid) && a->nav_modes != a->fatsv_emitted_nav_modes) || (trackDataValid(&a->nav_qnh_valid) && fabs(a->nav_qnh - a->fatsv_emitted_nav_qnh) > 0.8) || // 0.8 is the ES message resolution @@ -2220,8 +2238,10 @@ static void writeFATSV() p = appendFATSVMeta(p, end, "track_rate", a, &a->track_rate_valid, "%.2f", a->track_rate); p = appendFATSVMeta(p, end, "roll", a, &a->roll_valid, "%.1f", a->roll); p = appendFATSVMeta(p, end, "heading_magnetic", a, &a->mag_heading_valid, "%.1f", a->mag_heading); - p = appendFATSVMeta(p, end, "heading_true", a, &a->true_heading_valid, "%.1f", a->true_heading); - p = appendFATSVMeta(p, end, "nav_alt", a, &a->nav_altitude_valid, "%u", a->nav_altitude); + p = appendFATSVMeta(p, end, "heading_true", a, &a->true_heading_valid, "%.1f", a->true_heading); + p = appendFATSVMeta(p, end, "nav_alt_mcp", a, &a->nav_altitude_mcp_valid, "%u", a->nav_altitude_mcp); + p = appendFATSVMeta(p, end, "nav_alt_fms", a, &a->nav_altitude_fms_valid, "%u", a->nav_altitude_fms); + p = appendFATSVMeta(p, end, "nav_alt_src", a, &a->nav_altitude_src_valid, "%s", nav_altitude_source_enum_string(a->nav_altitude_src)); p = appendFATSVMeta(p, end, "nav_heading", a, &a->nav_heading_valid, "%.1f", a->nav_heading); p = appendFATSVMeta(p, end, "nav_modes", a, &a->nav_modes_valid, "{%s}", nav_modes_flags_string(a->nav_modes)); p = appendFATSVMeta(p, end, "nav_qnh", a, &a->nav_qnh_valid, "%.1f", a->nav_qnh); @@ -2255,7 +2275,9 @@ static void writeFATSV() a->fatsv_emitted_mag_heading = a->mag_heading; a->fatsv_emitted_true_heading = a->true_heading; a->fatsv_emitted_airground = a->airground; - a->fatsv_emitted_nav_altitude = a->nav_altitude; + a->fatsv_emitted_nav_altitude_mcp = a->nav_altitude_mcp; + a->fatsv_emitted_nav_altitude_fms = a->nav_altitude_fms; + a->fatsv_emitted_nav_altitude_src = a->nav_altitude_src; a->fatsv_emitted_nav_heading = a->nav_heading; a->fatsv_emitted_nav_modes = a->nav_modes; a->fatsv_emitted_nav_qnh = a->nav_qnh; diff --git a/track.c b/track.c index acbe870..bd34c1a 100644 --- a/track.c +++ b/track.c @@ -116,7 +116,9 @@ struct aircraft *trackCreateAircraft(struct modesMessage *mm) { F(squawk, 15, 70); // ADS-B or Mode S F(airground, 15, 70); // ADS-B or Mode S F(nav_qnh, 60, 70); // Comm-B only - F(nav_altitude, 60, 70); // ADS-B or Comm-B + F(nav_altitude_mcp, 60, 70); // ADS-B or Comm-B + F(nav_altitude_fms, 60, 70); // ADS-B or Comm-B + F(nav_altitude_src, 60, 70); // ADS-B or Comm-B F(nav_heading, 60, 70); // ADS-B or Comm-B F(nav_modes, 60, 70); // ADS-B or Comm-B F(cpr_odd, 60, 70); // ADS-B only @@ -1091,12 +1093,16 @@ struct aircraft *trackUpdateFromMessage(struct modesMessage *mm) memcpy(a->callsign, mm->callsign, sizeof(a->callsign)); } - // prefer MCP over FMS - // unless the source says otherwise - if (mm->nav.mcp_altitude_valid && mm->nav.altitude_source != NAV_ALT_FMS && accept_data(&a->nav_altitude_valid, mm->source)) { - a->nav_altitude = mm->nav.mcp_altitude; - } else if (mm->nav.fms_altitude_valid && accept_data(&a->nav_altitude_valid, mm->source)) { - a->nav_altitude = mm->nav.fms_altitude; + if (mm->nav.mcp_altitude_valid && accept_data(&a->nav_altitude_mcp_valid, mm->source)) { + a->nav_altitude_mcp = mm->nav.mcp_altitude; + } + + if (mm->nav.fms_altitude_valid && accept_data(&a->nav_altitude_fms_valid, mm->source)) { + a->nav_altitude_fms = mm->nav.fms_altitude; + } + + if (mm->nav.altitude_source != NAV_ALT_INVALID && accept_data(&a->nav_altitude_src_valid, mm->source)) { + a->nav_altitude_src = mm->nav.altitude_source; } if (mm->nav.heading_valid && accept_data(&a->nav_heading_valid, mm->source)) { @@ -1311,7 +1317,9 @@ static void trackRemoveStaleAircraft(uint64_t now) EXPIRE(squawk); EXPIRE(airground); EXPIRE(nav_qnh); - EXPIRE(nav_altitude); + EXPIRE(nav_altitude_mcp); + EXPIRE(nav_altitude_fms); + EXPIRE(nav_altitude_src); EXPIRE(nav_heading); EXPIRE(nav_modes); EXPIRE(cpr_odd); diff --git a/track.h b/track.h index daac95a..3aa31e7 100644 --- a/track.h +++ b/track.h @@ -151,8 +151,14 @@ struct aircraft { data_validity nav_qnh_valid; float nav_qnh; // Altimeter setting (QNH/QFE), millibars - data_validity nav_altitude_valid; - unsigned nav_altitude; // FMS or FCU selected altitude + data_validity nav_altitude_mcp_valid; + unsigned nav_altitude_mcp; // FCU/MCP selected altitude + + data_validity nav_altitude_fms_valid; + unsigned nav_altitude_fms; // FMS selected altitude + + data_validity nav_altitude_src_valid; + nav_altitude_source_t nav_altitude_src; // source of altitude used by automation data_validity nav_heading_valid; float nav_heading; // target heading, degrees (0-359) @@ -220,7 +226,9 @@ struct aircraft { unsigned fatsv_emitted_tas; // -"- TAS float fatsv_emitted_mach; // -"- Mach number airground_t fatsv_emitted_airground; // -"- air/ground state - unsigned fatsv_emitted_nav_altitude; // -"- target altitude + unsigned fatsv_emitted_nav_altitude_mcp; // -"- MCP altitude + unsigned fatsv_emitted_nav_altitude_fms; // -"- FMS altitude + unsigned fatsv_emitted_nav_altitude_src; // -"- automation altitude source float fatsv_emitted_nav_heading; // -"- target heading nav_modes_t fatsv_emitted_nav_modes; // -"- enabled navigation modes float fatsv_emitted_nav_qnh; // -"- altimeter setting