Track CPR encoding type directly rather than inferring it from airground.

(airground can change even while airborne if SPI/Alert status gets set)
This commit is contained in:
Oliver Jowett 2016-10-02 00:16:29 +01:00
parent 617a71e36b
commit 52fe01c860
4 changed files with 31 additions and 12 deletions

View file

@ -198,6 +198,10 @@ typedef enum {
SIL_PER_SAMPLE, SIL_PER_HOUR SIL_PER_SAMPLE, SIL_PER_HOUR
} sil_type_t; } sil_type_t;
typedef enum {
CPR_SURFACE, CPR_AIRBORNE, CPR_COARSE
} cpr_type_t;
#define MODES_NON_ICAO_ADDRESS (1<<24) // Set on addresses to indicate they are not ICAO addresses #define MODES_NON_ICAO_ADDRESS (1<<24) // Set on addresses to indicate they are not ICAO addresses
#define MODES_DEBUG_DEMOD (1<<0) #define MODES_DEBUG_DEMOD (1<<0)
@ -461,6 +465,7 @@ struct modesMessage {
// valid if category_valid // valid if category_valid
unsigned category; // A0 - D7 encoded as a single hex byte unsigned category; // A0 - D7 encoded as a single hex byte
// valid if cpr_valid // valid if cpr_valid
cpr_type_t cpr_type; // The encoding type used (surface, airborne, coarse TIS-B)
unsigned cpr_lat; // Non decoded latitude. unsigned cpr_lat; // Non decoded latitude.
unsigned cpr_lon; // Non decoded longitude. unsigned cpr_lon; // Non decoded longitude.
unsigned cpr_nucp; // NUCp/NIC value implied by message type unsigned cpr_nucp; // NUCp/NIC value implied by message type

View file

@ -903,6 +903,7 @@ static void decodeESSurfacePosition(struct modesMessage *mm, int check_imf)
mm->cpr_odd = getbit(me, 22); mm->cpr_odd = getbit(me, 22);
mm->cpr_nucp = (14 - mm->metype); mm->cpr_nucp = (14 - mm->metype);
mm->cpr_valid = 1; mm->cpr_valid = 1;
mm->cpr_type = CPR_SURFACE;
unsigned movement = getbits(me, 6, 12); unsigned movement = getbits(me, 6, 12);
if (movement > 0 && movement < 125) { if (movement > 0 && movement < 125) {
@ -948,6 +949,7 @@ static void decodeESAirbornePosition(struct modesMessage *mm, int check_imf)
} else { } else {
// Otherwise, assume it's valid. // Otherwise, assume it's valid.
mm->cpr_valid = 1; mm->cpr_valid = 1;
mm->cpr_type = CPR_AIRBORNE;
mm->cpr_odd = getbit(me, 22); mm->cpr_odd = getbit(me, 22);
if (mm->metype == 18 || mm->metype == 22) if (mm->metype == 18 || mm->metype == 22)
@ -1386,6 +1388,19 @@ static const char *addrtype_to_string(addrtype_t type) {
} }
} }
static const char *cpr_type_to_string(cpr_type_t type) {
switch (type) {
case CPR_SURFACE:
return "Surface";
case CPR_AIRBORNE:
return "Airborne";
case CPR_COARSE:
return "TIS-B Coarse";
default:
return "unknown CPR type";
}
}
static void print_hex_bytes(unsigned char *data, size_t len) { static void print_hex_bytes(unsigned char *data, size_t len) {
size_t i; size_t i;
for (i = 0; i < len; ++i) { for (i = 0; i < len; ++i) {
@ -1676,12 +1691,11 @@ void displayModesMessage(struct modesMessage *mm) {
mm->category); mm->category);
} }
if (mm->msgtype == 17 || mm->msgtype == 18) {
}
if (mm->cpr_valid) { if (mm->cpr_valid) {
printf(" CPR odd flag: %s\n" printf(" CPR type: %s\n"
" CPR odd flag: %s\n"
" CPR NUCp/NIC: %u\n", " CPR NUCp/NIC: %u\n",
cpr_type_to_string(mm->cpr_type),
mm->cpr_odd ? "odd" : "even", mm->cpr_odd ? "odd" : "even",
mm->cpr_nucp); mm->cpr_nucp);

12
track.c
View file

@ -260,7 +260,7 @@ static int doGlobalCPR(struct aircraft *a, struct modesMessage *mm, uint64_t now
{ {
int result; int result;
int fflag = mm->cpr_odd; int fflag = mm->cpr_odd;
int surface = (mm->airground == AG_GROUND); int surface = (mm->cpr_type == CPR_SURFACE);
*nuc = (a->cpr_even_nuc < a->cpr_odd_nuc ? a->cpr_even_nuc : a->cpr_odd_nuc); // worst of the two positions *nuc = (a->cpr_even_nuc < a->cpr_odd_nuc ? a->cpr_even_nuc : a->cpr_odd_nuc); // worst of the two positions
@ -341,7 +341,7 @@ static int doLocalCPR(struct aircraft *a, struct modesMessage *mm, uint64_t now,
double range_limit = 0; double range_limit = 0;
int result; int result;
int fflag = mm->cpr_odd; int fflag = mm->cpr_odd;
int surface = (mm->airground == AG_GROUND); int surface = (mm->cpr_type == CPR_SURFACE);
*nuc = mm->cpr_nucp; *nuc = mm->cpr_nucp;
@ -426,7 +426,7 @@ static void updatePosition(struct aircraft *a, struct modesMessage *mm, uint64_t
unsigned new_nuc = 0; unsigned new_nuc = 0;
int surface; int surface;
surface = (mm->airground == AG_GROUND); surface = (mm->cpr_type == CPR_SURFACE);
if (surface) { if (surface) {
++Modes.stats_current.cpr_surface; ++Modes.stats_current.cpr_surface;
@ -446,7 +446,7 @@ static void updatePosition(struct aircraft *a, struct modesMessage *mm, uint64_t
// If we have enough recent data, try global CPR // If we have enough recent data, try global CPR
if (trackDataValid(&a->cpr_odd_valid) && trackDataValid(&a->cpr_even_valid) && if (trackDataValid(&a->cpr_odd_valid) && trackDataValid(&a->cpr_even_valid) &&
a->cpr_odd_valid.source == a->cpr_even_valid.source && a->cpr_odd_valid.source == a->cpr_even_valid.source &&
a->cpr_odd_airground == a->cpr_even_airground && a->cpr_odd_type == a->cpr_even_type &&
time_between(a->cpr_odd_valid.updated, a->cpr_even_valid.updated) <= max_elapsed) { time_between(a->cpr_odd_valid.updated, a->cpr_even_valid.updated) <= max_elapsed) {
location_result = doGlobalCPR(a, mm, now, &new_lat, &new_lon, &new_nuc); location_result = doGlobalCPR(a, mm, now, &new_lat, &new_lon, &new_nuc);
@ -607,7 +607,7 @@ struct aircraft *trackUpdateFromMessage(struct modesMessage *mm)
// CPR, even // CPR, even
if (mm->cpr_valid && !mm->cpr_odd && accept_data(&a->cpr_even_valid, mm->source, now)) { if (mm->cpr_valid && !mm->cpr_odd && accept_data(&a->cpr_even_valid, mm->source, now)) {
a->cpr_even_airground = mm->airground; a->cpr_even_type = mm->cpr_type;
a->cpr_even_lat = mm->cpr_lat; a->cpr_even_lat = mm->cpr_lat;
a->cpr_even_lon = mm->cpr_lon; a->cpr_even_lon = mm->cpr_lon;
a->cpr_even_nuc = mm->cpr_nucp; a->cpr_even_nuc = mm->cpr_nucp;
@ -615,7 +615,7 @@ struct aircraft *trackUpdateFromMessage(struct modesMessage *mm)
// CPR, odd // CPR, odd
if (mm->cpr_valid && mm->cpr_odd && accept_data(&a->cpr_odd_valid, mm->source, now)) { if (mm->cpr_valid && mm->cpr_odd && accept_data(&a->cpr_odd_valid, mm->source, now)) {
a->cpr_odd_airground = mm->airground; a->cpr_odd_type = mm->cpr_type;
a->cpr_odd_lat = mm->cpr_lat; a->cpr_odd_lat = mm->cpr_lat;
a->cpr_odd_lon = mm->cpr_lon; a->cpr_odd_lon = mm->cpr_lon;
a->cpr_odd_nuc = mm->cpr_nucp; a->cpr_odd_nuc = mm->cpr_nucp;

View file

@ -119,13 +119,13 @@ struct aircraft {
airground_t airground; // air/ground status airground_t airground; // air/ground status
data_validity cpr_odd_valid; // Last seen even CPR message data_validity cpr_odd_valid; // Last seen even CPR message
airground_t cpr_odd_airground; cpr_type_t cpr_odd_type;
unsigned cpr_odd_lat; unsigned cpr_odd_lat;
unsigned cpr_odd_lon; unsigned cpr_odd_lon;
unsigned cpr_odd_nuc; unsigned cpr_odd_nuc;
data_validity cpr_even_valid; // Last seen odd CPR message data_validity cpr_even_valid; // Last seen odd CPR message
airground_t cpr_even_airground; cpr_type_t cpr_even_type;
unsigned cpr_even_lat; unsigned cpr_even_lat;
unsigned cpr_even_lon; unsigned cpr_even_lon;
unsigned cpr_even_nuc; unsigned cpr_even_nuc;