From 44302bb1998ab75162de11387bc9ad3435ee3f83 Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Wed, 18 Feb 2015 01:53:47 +0000 Subject: [PATCH] Fix NaN in greatcircle calc if positions are identical. Bail out early if there's a global CPR decoding error so we don't try to do range/speed checks on a position of (0,0) --- track.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/track.c b/track.c index f1e1c07..1977ab8 100644 --- a/track.c +++ b/track.c @@ -120,6 +120,11 @@ static double greatcircle(double lat0, double lon0, double lat1, double lon1) lon0 = lon0 * M_PI / 180.0; lat1 = lat1 * M_PI / 180.0; lon1 = lon1 * M_PI / 180.0; + + // avoid NaN + if (fabs(lat0 - lat1) < 0.0001 && fabs(lon0 - lon1) < 0.0001) + return 0.0; + return 6371e3 * acos(sin(lat0) * sin(lat1) + cos(lat0) * cos(lat1) * cos(fabs(lon0 - lon1))); } @@ -131,6 +136,7 @@ static int speed_check(struct aircraft *a, double lat, double lon, uint64_t now, double distance; double range; int speed; + int inrange; if (!(a->bFlags & MODES_ACFLAGS_LATLON_VALID)) return 1; // no reference, assume OK @@ -164,14 +170,15 @@ static int speed_check(struct aircraft *a, double lat, double lon, uint64_t now, // find actual distance distance = greatcircle(a->lat, a->lon, lat, lon); + inrange = (distance <= range); #ifdef DEBUG_CPR_CHECKS - if (distance >= range) { + if (!inrange) { fprintf(stderr, "Speed check failed: %06x: %.3f,%.3f -> %.3f,%.3f in %.1f seconds, max speed %d kt, range %.1fkm, actual %.1fkm\n", a->addr, a->lat, a->lon, lat, lon, elapsed/1000.0, speed, range/1000.0, distance/1000.0); } #endif - return (distance < range); + return inrange; } static int doGlobalCPR(struct aircraft *a, int fflag, int surface, uint64_t now, double *lat, double *lon, unsigned *nuc) @@ -211,6 +218,9 @@ static int doGlobalCPR(struct aircraft *a, int fflag, int surface, uint64_t now, lat, lon); } + if (result < 0) + return result; + // check max range if (Modes.maxRange > 0 && (Modes.bUserFlags & MODES_USER_LATLON_VALID)) { double range = greatcircle(Modes.fUserLat, Modes.fUserLon, *lat, *lon);