Rework heading/track to include HRD/TAH.
Clean up TIS-B flag output.
This commit is contained in:
parent
05e9601903
commit
1ec32903ba
10
comm_b.c
10
comm_b.c
|
@ -552,8 +552,9 @@ static int decodeBDS50(struct modesMessage *mm, bool store)
|
|||
}
|
||||
|
||||
if (track_valid) {
|
||||
mm->track_valid = 1;
|
||||
mm->track = track;
|
||||
mm->heading_valid = 1;
|
||||
mm->heading = track;
|
||||
mm->heading_type = HEADING_GROUND_TRACK;
|
||||
}
|
||||
|
||||
if (gs_valid) {
|
||||
|
@ -704,8 +705,9 @@ static int decodeBDS60(struct modesMessage *mm, bool store)
|
|||
mm->commb_format = COMMB_HEADING_SPEED;
|
||||
|
||||
if (heading_valid) {
|
||||
mm->mag_heading_valid = 1;
|
||||
mm->mag_heading = heading;
|
||||
mm->heading_valid = 1;
|
||||
mm->heading = heading;
|
||||
mm->heading_type = HEADING_MAGNETIC;
|
||||
}
|
||||
|
||||
if (ias_valid) {
|
||||
|
|
23
dump1090.h
23
dump1090.h
|
@ -177,11 +177,6 @@ typedef enum {
|
|||
AG_UNCERTAIN
|
||||
} airground_t;
|
||||
|
||||
typedef enum {
|
||||
HEADING_TRUE,
|
||||
HEADING_MAGNETIC
|
||||
} heading_source_t;
|
||||
|
||||
typedef enum {
|
||||
SIL_PER_SAMPLE, SIL_PER_HOUR
|
||||
} sil_type_t;
|
||||
|
@ -190,6 +185,14 @@ typedef enum {
|
|||
CPR_SURFACE, CPR_AIRBORNE, CPR_COARSE
|
||||
} cpr_type_t;
|
||||
|
||||
typedef enum {
|
||||
HEADING_GROUND_TRACK, // Direction of track over ground, degrees clockwise from true north
|
||||
HEADING_TRUE, // Heading, degrees clockwise from true north
|
||||
HEADING_MAGNETIC, // Heading, degrees clockwise from magnetic north
|
||||
HEADING_MAGNETIC_OR_TRUE, // HEADING_MAGNETIC or HEADING_TRUE depending on the HRD bit in opstatus
|
||||
HEADING_TRACK_OR_HEADING // HEADING_GROUND_TRACK or HEADING_REF_DIR depending on the TAH bit in opstatus
|
||||
} heading_type_t;
|
||||
|
||||
typedef enum {
|
||||
COMMB_UNKNOWN,
|
||||
COMMB_EMPTY_RESPONSE,
|
||||
|
@ -414,7 +417,7 @@ struct modesMessage {
|
|||
unsigned altitude_valid : 1;
|
||||
unsigned track_valid : 1;
|
||||
unsigned track_rate_valid : 1;
|
||||
unsigned mag_heading_valid : 1;
|
||||
unsigned heading_valid : 1;
|
||||
unsigned roll_valid : 1;
|
||||
unsigned gs_valid : 1;
|
||||
unsigned ias_valid : 1;
|
||||
|
@ -449,9 +452,9 @@ struct modesMessage {
|
|||
|
||||
// following fields are valid if the corresponding _valid field is set:
|
||||
int geom_delta; // Difference between geometric and baro alt
|
||||
float track; // True ground track, degrees (0-359). Reported directly or computed from from EW and NS velocity
|
||||
float heading; // ground track or heading, degrees (0-359). Reported directly or computed from from EW and NS velocity
|
||||
heading_type_t heading_type;// how to interpret 'track_or_heading'
|
||||
float track_rate; // Rate of change of track, degrees/second
|
||||
float mag_heading; // Magnetic heading, degrees (0-359)
|
||||
float roll; // Roll, degrees, negative is left roll
|
||||
unsigned gs; // Groundspeed, kts, reported directly or computed from from EW and NS velocity
|
||||
unsigned ias; // Indicated airspeed, kts
|
||||
|
@ -506,8 +509,8 @@ struct modesMessage {
|
|||
unsigned nic_baro : 1;
|
||||
|
||||
sil_type_t sil_type;
|
||||
enum { ANGLE_HEADING, ANGLE_TRACK } track_angle;
|
||||
heading_source_t hrd;
|
||||
heading_type_t tah;
|
||||
heading_type_t hrd;
|
||||
|
||||
unsigned cc_lw;
|
||||
unsigned cc_antenna_offset;
|
||||
|
|
58
mode_s.c
58
mode_s.c
|
@ -765,12 +765,13 @@ static void decodeESAirborneVelocity(struct modesMessage *mm, int check_imf)
|
|||
mm->gs_valid = 1;
|
||||
|
||||
if (mm->gs) {
|
||||
float heading = atan2(ew_vel, ns_vel) * 180.0 / M_PI;
|
||||
float ground_track = atan2(ew_vel, ns_vel) * 180.0 / M_PI;
|
||||
// We don't want negative values but a 0-360 scale
|
||||
if (heading < 0)
|
||||
heading += 360;
|
||||
mm->track = heading;
|
||||
mm->track_valid = 1;
|
||||
if (ground_track < 0)
|
||||
ground_track += 360;
|
||||
mm->heading = ground_track;
|
||||
mm->heading_type = HEADING_GROUND_TRACK;
|
||||
mm->heading_valid = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -791,8 +792,9 @@ static void decodeESAirborneVelocity(struct modesMessage *mm, int check_imf)
|
|||
}
|
||||
|
||||
if (getbit(me, 14)) {
|
||||
mm->mag_heading_valid = 1;
|
||||
mm->mag_heading = getbits(me, 15, 24) * 360.0 / 1024.0;
|
||||
mm->heading_valid = 1;
|
||||
mm->heading = getbits(me, 15, 24) * 360.0 / 1024.0;
|
||||
mm->heading_type = HEADING_MAGNETIC_OR_TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -828,8 +830,9 @@ static void decodeESSurfacePosition(struct modesMessage *mm, int check_imf)
|
|||
}
|
||||
|
||||
if (getbit(me, 13)) {
|
||||
mm->track_valid = 1;
|
||||
mm->track = getbits(me, 14, 20) * 360.0 / 128.0;
|
||||
mm->heading_valid = 1;
|
||||
mm->heading = getbits(me, 14, 20) * 360.0 / 128.0;
|
||||
mm->heading_type = HEADING_TRACK_OR_HEADING;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1022,12 +1025,12 @@ static void decodeESOperationalStatus(struct modesMessage *mm, int check_imf)
|
|||
mm->opstatus.nic_supp_a = getbit(me, 44);
|
||||
mm->opstatus.nac_p = getbits(me, 45, 48);
|
||||
mm->opstatus.sil = getbits(me, 51, 52);
|
||||
mm->opstatus.hrd = getbit(me, 54) ? HEADING_MAGNETIC : HEADING_TRUE;
|
||||
if (mm->mesub == 0) {
|
||||
mm->opstatus.nic_baro = getbit(me, 53);
|
||||
} else {
|
||||
mm->opstatus.track_angle = getbit(me, 53) ? ANGLE_TRACK : ANGLE_HEADING;
|
||||
mm->opstatus.tah = getbit(me, 53) ? HEADING_GROUND_TRACK : mm->opstatus.hrd;
|
||||
}
|
||||
mm->opstatus.hrd = getbit(me, 54) ? HEADING_MAGNETIC : HEADING_TRUE;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
@ -1064,13 +1067,13 @@ static void decodeESOperationalStatus(struct modesMessage *mm, int check_imf)
|
|||
mm->opstatus.nic_supp_a = getbit(me, 44);
|
||||
mm->opstatus.nac_p = getbits(me, 45, 48);
|
||||
mm->opstatus.sil = getbits(me, 51, 52);
|
||||
mm->opstatus.hrd = getbit(me, 54) ? HEADING_MAGNETIC : HEADING_TRUE;
|
||||
if (mm->mesub == 0) {
|
||||
mm->opstatus.gva = getbits(me, 49, 50);
|
||||
mm->opstatus.nic_baro = getbit(me, 53);
|
||||
} else {
|
||||
mm->opstatus.track_angle = getbit(me, 53) ? ANGLE_TRACK : ANGLE_HEADING;
|
||||
mm->opstatus.tah = getbit(me, 53) ? HEADING_GROUND_TRACK : mm->opstatus.hrd;
|
||||
}
|
||||
mm->opstatus.hrd = getbit(me, 54) ? HEADING_MAGNETIC : HEADING_TRUE;
|
||||
mm->opstatus.sil_type = getbit(me, 55) ? SIL_PER_SAMPLE : SIL_PER_HOUR;
|
||||
break;
|
||||
}
|
||||
|
@ -1299,6 +1302,23 @@ static const char *cpr_type_to_string(cpr_type_t type) {
|
|||
}
|
||||
}
|
||||
|
||||
static const char *heading_type_to_string(heading_type_t type) {
|
||||
switch (type) {
|
||||
case HEADING_GROUND_TRACK:
|
||||
return "Ground track";
|
||||
case HEADING_MAGNETIC:
|
||||
return "Mag heading";
|
||||
case HEADING_TRUE:
|
||||
return "True heading";
|
||||
case HEADING_MAGNETIC_OR_TRUE:
|
||||
return "Heading";
|
||||
case HEADING_TRACK_OR_HEADING:
|
||||
return "Track/Heading";
|
||||
default:
|
||||
return "unknown heading type";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *commb_format_to_string(commb_format_t format) {
|
||||
switch (format) {
|
||||
case COMMB_EMPTY_RESPONSE:
|
||||
|
@ -1585,12 +1605,8 @@ void displayModesMessage(struct modesMessage *mm) {
|
|||
mm->geom_delta);
|
||||
}
|
||||
|
||||
if (mm->track_valid) {
|
||||
printf(" Track: %.1f\n", mm->track);
|
||||
}
|
||||
|
||||
if (mm->mag_heading_valid) {
|
||||
printf(" Mag heading: %.1f\n", mm->mag_heading);
|
||||
if (mm->heading_valid) {
|
||||
printf(" %-13s %.1f\n", heading_type_to_string(mm->heading_type), mm->heading);
|
||||
}
|
||||
|
||||
if (mm->track_rate_valid) {
|
||||
|
@ -1701,8 +1717,8 @@ void displayModesMessage(struct modesMessage *mm) {
|
|||
if (mm->opstatus.nic_baro) printf(" NICbaro: %d\n", mm->opstatus.nic_baro);
|
||||
|
||||
if (mm->mesub == 1)
|
||||
printf(" Heading type: %s\n", (mm->opstatus.track_angle == ANGLE_HEADING ? "heading" : "track angle"));
|
||||
printf(" Heading reference: %s\n", (mm->opstatus.hrd == HEADING_TRUE ? "true north" : "magnetic north"));
|
||||
printf(" Track/heading: %s\n", heading_type_to_string(mm->opstatus.tah));
|
||||
printf(" Heading ref dir: %s\n", heading_type_to_string(mm->opstatus.hrd));
|
||||
}
|
||||
|
||||
if (mm->intent.valid) {
|
||||
|
|
88
net_io.c
88
net_io.c
|
@ -604,14 +604,14 @@ static void modesSendSBSOutput(struct modesMessage *mm, struct aircraft *a) {
|
|||
|
||||
// Field 13 is the ground Speed (if we have it)
|
||||
if (mm->gs_valid) {
|
||||
p += sprintf(p, ",%d", mm->gs);
|
||||
p += sprintf(p, ",%u", mm->gs);
|
||||
} else {
|
||||
p += sprintf(p, ",");
|
||||
}
|
||||
|
||||
// Field 14 is the ground Heading (if we have it)
|
||||
if (mm->track_valid) {
|
||||
p += sprintf(p, ",%.0f", mm->track);
|
||||
if (mm->heading_valid && mm->heading_type == HEADING_GROUND_TRACK) {
|
||||
p += sprintf(p, ",%.0f", mm->heading);
|
||||
} else {
|
||||
p += sprintf(p, ",");
|
||||
}
|
||||
|
@ -1201,6 +1201,10 @@ char *generateAircraftJson(const char *url_path, int *len) {
|
|||
p += snprintf(p, end-p, ",\"track\":%.1f", a->track);
|
||||
if (trackDataValid(&a->track_rate_valid))
|
||||
p += snprintf(p, end-p, ",\"track_rate\":%.2f", a->track_rate);
|
||||
if (trackDataValid(&a->mag_heading_valid))
|
||||
p += snprintf(p, end-p, ",\"mag_heading\":%.1f", a->mag_heading);
|
||||
if (trackDataValid(&a->true_heading_valid))
|
||||
p += snprintf(p, end-p, ",\"true_heading\":%.1f", a->true_heading);
|
||||
if (trackDataValid(&a->gs_valid))
|
||||
p += snprintf(p, end-p, ",\"gs\":%u", a->gs);
|
||||
if (trackDataValid(&a->ias_valid))
|
||||
|
@ -1821,18 +1825,47 @@ static void writeFATSVEvent(struct modesMessage *mm, struct aircraft *a)
|
|||
typedef enum {
|
||||
TISB_IDENT = 1,
|
||||
TISB_SQUAWK = 2,
|
||||
TISB_ALTITUDE = 4,
|
||||
TISB_ALTITUDE_GEOM = 8,
|
||||
TISB_ALT = 4,
|
||||
TISB_ALT_GEOM = 8,
|
||||
TISB_GS = 16,
|
||||
TISB_IAS = 32,
|
||||
TISB_TAS = 64,
|
||||
TISB_POSITION = 128,
|
||||
TISB_TRACK = 256,
|
||||
TISB_MAG_HEADING = 512,
|
||||
TISB_AIRGROUND = 1024,
|
||||
TISB_CATEGORY = 2048
|
||||
TISB_LAT = 128,
|
||||
TISB_LON = 256,
|
||||
TISB_TRACK = 512,
|
||||
TISB_MAG_HEADING = 1024,
|
||||
TISB_TRUE_HEADING = 2048,
|
||||
TISB_AIRGROUND = 4096,
|
||||
TISB_CATEGORY = 8192,
|
||||
TISB_INTENT_ALT = 16384,
|
||||
TISB_INTENT_HEADING = 32768,
|
||||
TISB_ALT_SETTING = 65536
|
||||
} tisb_flags;
|
||||
|
||||
struct {
|
||||
tisb_flags flag;
|
||||
const char *name;
|
||||
} tisb_flag_names[] = {
|
||||
{ TISB_IDENT, "ident" },
|
||||
{ TISB_SQUAWK, "squawk" },
|
||||
{ TISB_ALT, "alt" },
|
||||
{ TISB_ALT_GEOM, "alt_geom" },
|
||||
{ TISB_GS, "gs" },
|
||||
{ TISB_IAS, "ias" },
|
||||
{ TISB_TAS, "tas" },
|
||||
{ TISB_LAT, "lat" },
|
||||
{ TISB_LON, "lat" },
|
||||
{ TISB_TRACK, "track" },
|
||||
{ TISB_MAG_HEADING, "mag_heading" },
|
||||
{ TISB_TRUE_HEADING, "true_heading" },
|
||||
{ TISB_AIRGROUND, "airGround" },
|
||||
{ TISB_CATEGORY, "category" },
|
||||
{ TISB_INTENT_ALT, "intent_alt" },
|
||||
{ TISB_INTENT_HEADING, "intent_heading" },
|
||||
{ TISB_ALT_SETTING, "alt_setting" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static inline unsigned unsigned_difference(unsigned v1, unsigned v2)
|
||||
{
|
||||
return (v1 > v2) ? (v1 - v2) : (v2 - v1);
|
||||
|
@ -1887,6 +1920,7 @@ static void writeFATSV()
|
|||
int trackValid = trackDataValidEx(&a->track_valid, now, 15000, SOURCE_MODE_S); // Comm-B or ES
|
||||
int trackRateValid = trackDataValidEx(&a->track_rate_valid, now, 15000, SOURCE_MODE_S); // Comm-B
|
||||
int rollValid = trackDataValidEx(&a->roll_valid, now, 15000, SOURCE_MODE_S); // Comm-B
|
||||
int trueHeadingValid = trackDataValidEx(&a->true_heading_valid, now, 15000, SOURCE_MODE_S); // Comm-B or ES
|
||||
int magHeadingValid = trackDataValidEx(&a->mag_heading_valid, now, 15000, SOURCE_MODE_S); // Comm-B or ES
|
||||
int gsValid = trackDataValidEx(&a->gs_valid, now, 15000, SOURCE_MODE_S); // Comm-B or ES
|
||||
int iasValid = trackDataValidEx(&a->ias_valid, now, 15000, SOURCE_MODE_S); // Comm-B or ES
|
||||
|
@ -1921,7 +1955,7 @@ static void writeFATSV()
|
|||
if (geomRateValid && abs(a->geom_rate - a->fatsv_emitted_geom_rate) > 500) {
|
||||
changed = 1;
|
||||
}
|
||||
if (trackValid && heading_difference(a->track, a->fatsv_emitted_heading) >= 2) {
|
||||
if (trackValid && heading_difference(a->track, a->fatsv_emitted_track) >= 2) {
|
||||
changed = 1;
|
||||
}
|
||||
if (trackRateValid && fabs(a->track_rate - a->fatsv_emitted_track_rate) >= 0.5) {
|
||||
|
@ -1930,7 +1964,10 @@ static void writeFATSV()
|
|||
if (rollValid && fabs(a->roll - a->fatsv_emitted_roll) >= 5.0) {
|
||||
changed = 1;
|
||||
}
|
||||
if (magHeadingValid && heading_difference(a->mag_heading, a->fatsv_emitted_heading_magnetic) >= 2) {
|
||||
if (magHeadingValid && heading_difference(a->mag_heading, a->fatsv_emitted_mag_heading) >= 2) {
|
||||
changed = 1;
|
||||
}
|
||||
if (trueHeadingValid && heading_difference(a->true_heading, a->fatsv_emitted_true_heading) >= 2) {
|
||||
changed = 1;
|
||||
}
|
||||
if (gsValid && unsigned_difference(a->gs, a->fatsv_emitted_speed) >= 25) {
|
||||
|
@ -2039,14 +2076,14 @@ static void writeFATSV()
|
|||
p += snprintf(p, bufsize(p,end), "\talt\t%d", a->altitude);
|
||||
a->fatsv_emitted_altitude = a->altitude;
|
||||
useful = 1;
|
||||
tisb |= (a->altitude_valid.source == SOURCE_TISB) ? TISB_ALTITUDE : 0;
|
||||
tisb |= (a->altitude_valid.source == SOURCE_TISB) ? TISB_ALT : 0;
|
||||
}
|
||||
|
||||
if (altGeomValid && a->altitude_geom_valid.updated > a->fatsv_last_emitted) {
|
||||
p += snprintf(p, bufsize(p,end), "\talt_geom\t%d", a->altitude_geom);
|
||||
a->fatsv_emitted_altitude_gnss = a->altitude_geom;
|
||||
useful = 1;
|
||||
tisb |= (a->altitude_geom_valid.source == SOURCE_TISB) ? TISB_ALTITUDE_GEOM : 0;
|
||||
tisb |= (a->altitude_geom_valid.source == SOURCE_TISB) ? TISB_ALT_GEOM : 0;
|
||||
}
|
||||
|
||||
if (baroRateValid && a->baro_rate_valid.updated > a->fatsv_last_emitted) {
|
||||
|
@ -2091,12 +2128,12 @@ static void writeFATSV()
|
|||
if (positionValid && a->position_valid.updated > a->fatsv_last_emitted) {
|
||||
p += snprintf(p, bufsize(p,end), "\tlat\t%.5f\tlon\t%.5f", a->lat, a->lon);
|
||||
useful = 1;
|
||||
tisb |= (a->position_valid.source == SOURCE_TISB) ? TISB_POSITION : 0;
|
||||
tisb |= (a->position_valid.source == SOURCE_TISB) ? (TISB_LAT | TISB_LON) : 0;
|
||||
}
|
||||
|
||||
if (trackValid && a->track_valid.updated > a->fatsv_last_emitted) {
|
||||
p += snprintf(p, bufsize(p,end), "\ttrack\t%.0f", a->track);
|
||||
a->fatsv_emitted_heading = a->track;
|
||||
a->fatsv_emitted_track = a->track;
|
||||
useful = 1;
|
||||
tisb |= (a->track_valid.source == SOURCE_TISB) ? TISB_TRACK : 0;
|
||||
}
|
||||
|
@ -2115,11 +2152,18 @@ static void writeFATSV()
|
|||
|
||||
if (magHeadingValid && a->mag_heading_valid.updated > a->fatsv_last_emitted) {
|
||||
p += snprintf(p, bufsize(p,end), "\tmag_heading\t%.0f", a->mag_heading);
|
||||
a->fatsv_emitted_heading_magnetic = a->mag_heading;
|
||||
a->fatsv_emitted_mag_heading = a->mag_heading;
|
||||
useful = 1;
|
||||
tisb |= (a->mag_heading_valid.source == SOURCE_TISB) ? TISB_MAG_HEADING : 0;
|
||||
}
|
||||
|
||||
if (trueHeadingValid && a->true_heading_valid.updated > a->fatsv_last_emitted) {
|
||||
p += snprintf(p, bufsize(p,end), "\true_heading\t%.0f", a->true_heading);
|
||||
a->fatsv_emitted_true_heading = a->true_heading;
|
||||
useful = 1;
|
||||
tisb |= (a->true_heading_valid.source == SOURCE_TISB) ? TISB_TRUE_HEADING : 0;
|
||||
}
|
||||
|
||||
if (airgroundValid && (a->airground == AG_GROUND || a->airground == AG_AIRBORNE) && a->airground_valid.updated > a->fatsv_last_emitted) {
|
||||
p += snprintf(p, bufsize(p,end), "\tairGround\t%s", a->airground == AG_GROUND ? "G+" : "A+");
|
||||
a->fatsv_emitted_airground = a->airground;
|
||||
|
@ -2138,18 +2182,21 @@ static void writeFATSV()
|
|||
p += snprintf(p, bufsize(p,end), "\tintent_alt\t%u", a->intent_altitude);
|
||||
a->fatsv_emitted_intent_altitude = a->intent_altitude;
|
||||
useful = 1;
|
||||
tisb |= (a->category_valid.source == SOURCE_TISB) ? TISB_INTENT_ALT : 0;
|
||||
}
|
||||
|
||||
if (intentHeadingValid && a->intent_heading_valid.updated > a->fatsv_last_emitted) {
|
||||
p += snprintf(p, bufsize(p,end), "\tintent_heading\t%.0f", a->intent_heading);
|
||||
a->fatsv_emitted_intent_heading = a->intent_heading;
|
||||
useful = 1;
|
||||
tisb |= (a->category_valid.source == SOURCE_TISB) ? TISB_INTENT_HEADING : 0;
|
||||
}
|
||||
|
||||
if (altSettingValid && a->alt_setting_valid.updated > a->fatsv_last_emitted) {
|
||||
p += snprintf(p, bufsize(p,end), "\talt_setting\t%.1f", a->alt_setting);
|
||||
a->fatsv_emitted_alt_setting = a->alt_setting;
|
||||
useful = 1;
|
||||
tisb |= (a->category_valid.source == SOURCE_TISB) ? TISB_ALT_SETTING : 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2160,7 +2207,12 @@ static void writeFATSV()
|
|||
}
|
||||
|
||||
if (tisb != 0) {
|
||||
p += snprintf(p, bufsize(p,end), "\ttisb\t%d", (int)tisb);
|
||||
p += snprintf(p, bufsize(p,end), "\ttisb\t");
|
||||
for (int i = 0; tisb_flag_names[i].name; ++i) {
|
||||
if (tisb & tisb_flag_names[i].flag) {
|
||||
p += snprintf(p, bufsize(p,end), "%s ", tisb_flag_names[i].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p += snprintf(p, bufsize(p,end), "\n");
|
||||
|
|
39
track.c
39
track.c
|
@ -81,6 +81,11 @@ struct aircraft *trackCreateAircraft(struct modesMessage *mm) {
|
|||
a->fatsv_emitted_bds_30[0] = 0x30;
|
||||
a->fatsv_emitted_es_acas_ra[0] = 0xE2;
|
||||
|
||||
// defaults until we see an op status message
|
||||
a->adsb_version = -1;
|
||||
a->adsb_hrd = HEADING_MAGNETIC;
|
||||
a->adsb_tah = HEADING_GROUND_TRACK;
|
||||
|
||||
// Copy the first message so we can emit it later when a second message arrives.
|
||||
a->first_message = *mm;
|
||||
|
||||
|
@ -543,6 +548,10 @@ struct aircraft *trackUpdateFromMessage(struct modesMessage *mm)
|
|||
if (mm->addrtype < a->addrtype)
|
||||
a->addrtype = mm->addrtype;
|
||||
|
||||
// if we saw some direct ADS-B for the first time, assume version 0
|
||||
if (mm->source == SOURCE_ADSB && a->adsb_version < 0)
|
||||
a->adsb_version = 0;
|
||||
|
||||
if (mm->altitude_valid && mm->altitude_source == ALTITUDE_BARO && accept_data(&a->altitude_valid, mm->source, now)) {
|
||||
if (a->modeC_hit) {
|
||||
int new_modeC = (a->altitude + 49) / 100;
|
||||
|
@ -570,8 +579,21 @@ struct aircraft *trackUpdateFromMessage(struct modesMessage *mm)
|
|||
a->geom_delta = mm->geom_delta;
|
||||
}
|
||||
|
||||
if (mm->track_valid && accept_data(&a->track_valid, mm->source, now)) {
|
||||
a->track = mm->track;
|
||||
if (mm->heading_valid) {
|
||||
heading_type_t htype = mm->heading_type;
|
||||
if (htype == HEADING_MAGNETIC_OR_TRUE) {
|
||||
htype = a->adsb_hrd;
|
||||
} else if (htype == HEADING_TRACK_OR_HEADING) {
|
||||
htype = a->adsb_tah;
|
||||
}
|
||||
|
||||
if (htype == HEADING_GROUND_TRACK && accept_data(&a->track_valid, mm->source, now)) {
|
||||
a->track = mm->heading;
|
||||
} else if (htype == HEADING_MAGNETIC && accept_data(&a->mag_heading_valid, mm->source, now)) {
|
||||
a->mag_heading = mm->heading;
|
||||
} else if (htype == HEADING_TRUE && accept_data(&a->true_heading_valid, mm->source, now)) {
|
||||
a->true_heading = mm->heading;
|
||||
}
|
||||
}
|
||||
|
||||
if (mm->track_rate_valid && accept_data(&a->track_rate_valid, mm->source, now)) {
|
||||
|
@ -582,10 +604,6 @@ struct aircraft *trackUpdateFromMessage(struct modesMessage *mm)
|
|||
a->roll = mm->roll;
|
||||
}
|
||||
|
||||
if (mm->mag_heading_valid && accept_data(&a->mag_heading_valid, mm->source, now)) {
|
||||
a->mag_heading = mm->mag_heading;
|
||||
}
|
||||
|
||||
if (mm->gs_valid && accept_data(&a->gs_valid, mm->source, now)) {
|
||||
a->gs = mm->gs;
|
||||
}
|
||||
|
@ -654,6 +672,15 @@ struct aircraft *trackUpdateFromMessage(struct modesMessage *mm)
|
|||
a->cpr_odd_nuc = mm->cpr_nucp;
|
||||
}
|
||||
|
||||
// operational status message
|
||||
if (mm->opstatus.valid) {
|
||||
a->adsb_version = mm->opstatus.version;
|
||||
if (mm->opstatus.version > 0) {
|
||||
a->adsb_hrd = mm->opstatus.hrd;
|
||||
a->adsb_tah = mm->opstatus.tah;
|
||||
}
|
||||
}
|
||||
|
||||
// Now handle derived data
|
||||
|
||||
// derive geometric altitude if we have baro + delta
|
||||
|
|
12
track.h
12
track.h
|
@ -118,6 +118,9 @@ struct aircraft {
|
|||
data_validity mag_heading_valid;
|
||||
float mag_heading; // Magnetic heading
|
||||
|
||||
data_validity true_heading_valid;
|
||||
float true_heading; // True heading
|
||||
|
||||
data_validity baro_rate_valid;
|
||||
int baro_rate; // Vertical rate (barometric)
|
||||
|
||||
|
@ -158,6 +161,10 @@ struct aircraft {
|
|||
double lat, lon; // Coordinated obtained from CPR encoded data
|
||||
unsigned pos_nuc; // NUCp of last computed position
|
||||
|
||||
int adsb_version; // ADS-B version (from ADS-B operational status); -1 means no ADS-B messages seen
|
||||
heading_type_t adsb_hrd; // Heading Reference Direction setting (from ADS-B operational status)
|
||||
heading_type_t adsb_tah; // Track Angle / Heading setting (from ADS-B operational status)
|
||||
|
||||
int modeA_hit; // did our squawk match a possible mode A reply in the last check period?
|
||||
int modeC_hit; // did our altitude match a possible mode C reply in the last check period?
|
||||
|
||||
|
@ -165,9 +172,10 @@ struct aircraft {
|
|||
int fatsv_emitted_altitude_gnss; // -"- GNSS altitude
|
||||
int fatsv_emitted_baro_rate; // -"- barometric rate
|
||||
int fatsv_emitted_geom_rate; // -"- geometric rate
|
||||
float fatsv_emitted_heading; // -"- true track
|
||||
float fatsv_emitted_heading_magnetic; // -"- magnetic heading
|
||||
float fatsv_emitted_track; // -"- true track
|
||||
float fatsv_emitted_track_rate; // -"- track rate of change
|
||||
float fatsv_emitted_mag_heading; // -"- magnetic heading
|
||||
float fatsv_emitted_true_heading; // -"- true heading
|
||||
float fatsv_emitted_roll; // -"- roll angle
|
||||
unsigned fatsv_emitted_speed; // -"- groundspeed
|
||||
unsigned fatsv_emitted_speed_ias; // -"- IAS
|
||||
|
|
Loading…
Reference in a new issue