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.
This commit is contained in:
antirez 2013-01-18 23:05:08 +01:00
parent 03759a3eb0
commit b4805ea7d4

View File

@ -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;