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.
The old approach was to loop over a small circular buffer of recently
seen addresses recomputing the CRC every time: this prevented the use of
a big cache, and 20 entries was too small in case of high traffic and
big range antennas.
@prog on ##rtlsdr suggested to use an alternative algorithm where
instead we compute the CRC of the message, and xor it to obtain the
address, that is later checked in our list of recently seen addresses.
This is a lot better and allows for bigger tables in O(1) lookup time.
I used this idea to implement a larger 1024 elements table. Instead of
writing a proper hash table I used the fact we are just dealing with a
cache, so I just hash the ICAO addess and overwrite the old entry at
that idex with the address-timestamp pair, not caring about collisions.
The bigger table makes a huge difference:
In a test vector of 113 seconds recording with 76 simultaneous aircrafts
the new algorithm detected around 10k more messages (!).
As @keenerd noted on ##rtlsdr, using an 8 bit magnitude vector is not
enough in order to distinguish every different I/Q pair.
With this commit a few more messages with good CRC are detected.
The demodulation algorithm now only skips the current message if the
CRC is valid, this improves the amount of messages detected with good
CRC by ~ 4% since sometimes we are just a few samples out of sync.
This also improves the amount of messages that can be fixed.
The --stats option was added in order to better evaluate how the
algorithm performs on the same input after some change. So if you run
the program with both --ifile and --stats no Mode S message is logged
at all, but at the end of the processing the program shows you the
amount of messages decoded with good, bad crc, bit corrections, valid
preambles and so forth.