From b4805ea7d4f330396cc85afc8cfedc113d1fe208 Mon Sep 17 00:00:00 2001 From: antirez Date: Fri, 18 Jan 2013 23:05:08 +0100 Subject: [PATCH] Two important fixes to CPR decoding: wrong cast and more precise timing. This commit address two issues with the implementation of CPR decoding: Fix #1: The two functions N() and DLon() used to have the latitude parameter as an integer (!), basically truncating the fractional part before calling the NL() function to perform the lookup. This resulted into random strange movements of aircrafts, especially jumps or shifted positions. Fix #2: Use milliseconds for CPR odd/even timestamps. Dump1090 already tried to use the most recent packet received among the odd and even packets currently available, however to do this correctly millisecond resolution should be used, otherwise many times the odd and even packet appear to have the same time in seconds and we don't always use the latest received. --- dump1090.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/dump1090.c b/dump1090.c index 7bb23a3..3c4ec96 100644 --- a/dump1090.c +++ b/dump1090.c @@ -114,7 +114,7 @@ struct aircraft { int even_cprlat; int even_cprlon; double lat, lon; /* Coordinated obtained from CPR encoded data. */ - time_t odd_cprtime, even_cprtime; + long long odd_cprtime, even_cprtime; struct aircraft *next; /* Next aircraft in our linked list. */ }; @@ -1463,14 +1463,14 @@ int cprNLFunction(double lat) { else return 1; } -int cprNFunction(int i, int isodd) { - int nl = cprNLFunction(i) - isodd; +int cprNFunction(double lat, int isodd) { + int nl = cprNLFunction(lat) - isodd; if (nl < 1) nl = 1; return nl; } -double cprDlonFunction(int i, int isodd) { - return 360.0 / cprNFunction(i, isodd); +double cprDlonFunction(double lat, int isodd) { + return 360.0 / cprNFunction(lat, isodd); } /* This algorithm comes from: @@ -1567,16 +1567,17 @@ void interactiveReceiveData(struct modesMessage *mm) { if (mm->fflag) { a->odd_cprlat = mm->raw_latitude; a->odd_cprlon = mm->raw_longitude; - a->odd_cprtime = a->seen; /* Current time. */ + a->odd_cprtime = mstime(); } else { a->even_cprlat = mm->raw_latitude; a->even_cprlon = mm->raw_longitude; - a->even_cprtime = a->seen; /* Current time. */ + a->even_cprtime = mstime(); } /* If the two data is less than 10 seconds apart, compute * the position. */ - if (abs(a->even_cprtime - a->odd_cprtime) <= 10) + if (abs(a->even_cprtime - a->odd_cprtime) <= 10000) { decodeCPR(a); + } } else if (mm->metype == 19) { if (mm->mesub == 1 || mm->mesub == 2) { a->speed = mm->velocity;