Tuesday, September 9, 2014

At ION GNSS+ 2014

To whom it may happen to be in Tampa these days: I will also be around.



Feel free to come and chat!

Tuesday, May 20, 2014

Galileo RTK with NV08C-CSM hw 4.1

Being European I am often subject to skepticism about Galileo and compelled to justify its delays and usefulness. Explaining why Galileo is better and needed is beyond the scope of my blog but IMHO there is one key selling point that not many people stress.

Galileo was designed from the ground up in close collaboration with the USA: GPS and Galileo share L1 (1575.42 MHz) and L5/E5a (1176.45 MHz). In the future, a dual frequency GPS+Galileo L1/L5 receiver will deliver products with an incredible ratio between (performance+availability)/silicon.
According to scheduled launches there could be 12+ satellites supporting open L1+L5 by the end of this year already.
In the meantime, NVS touches base first in the mass-market receiver domain by delivering consistent carrier-phase measurements for GPS+Glonass+Galileo.

I have recently run zero-baseline double-differences in static, perfect visibility conditions using a high-end survey antenna:
Figure 1: Galileo double differences in static zero-baseline (NV08C-CSM hw4.1)
Using E11 as reference, the carrier phase noise is well contained within 0.01 circles (2mm).
With RTKLIB I run a Galileo-only static IAR and the result is as expected:

Figure 2: Static IAR with Galileo only (4 IOVs)
The combined GPS+Galileo static IAR looks like this:

Figure 3: Static IAR with GPS+Galileo
Note the 12 satellites above the 10° elevation mask used in the computation of carrier ambiguities :)

Understandably, Skytraq is working on GPS+Beidou carrier phase and I may publish some results on that too although visibility of Beidou MEOs is not great from here.

In the meantime, for people who wonder where uBlox NEO6T stands in terms of GPS carrier phase noise in similar conditions to the above here it is my result:
Figure 4: GPS double differences in static zero-baseline (uBlox NEO6T)
Which shows similar noise levels to NV08C-CSM.

Monday, May 12, 2014

GNSS carrier phase, RTLSDR, and fractional PLLs (the necessary evil)

A mandatory principle when processing GNSS -in order to have high accuracy carrier phase- is to have a well defined frequency planning. This entails knowing precisely how the Local Oscillator (LO) frequency is generated.
With RTL-SDR it is not a trivial task given that both R820T and RTL2832U use fractional Phase Locked Loops (PLLs) in order to derive respectively the high-side mixing frequency and the Digital Down Conversion (DDC) carrier.
I guess most people use RTL-SDR with a 50ppm crystal so the kind of inaccuracies I am going to describe are buried under the crystal inaccuracy ..within reason.

Let us start from the common call

> rtl_sdr -f 1575420000

This means "set to 1575.42 MHz" but what is hidden is:
1) R820T, set to 1575.42e6 + your IF
2) RTL2832U, downconvert the R820T IF to baseband
.. there are approximations everywhere.

Now, the R820T has a 16 bit fractional PLL register meaning that it can only set to frequencies multiple of 439.45 Hz (exactly).
Instead, the RTL2832U has a 22 bit fractional PLL register meaning that is can recover IFs in steps of 6.8665 Hz (exactly).
Of course, nor 1575.42e6, nor 3.57e6 are exact multiples of either frequency so one always ends up with a mismatch between what he/she thinks he has set, and what really ends up with. Most of the times, this is fine. For GNSS it is not since carrier is accumulated over long intervals and even a few tenths of Hz will make it diverge from the truth.
So I went down the route of characterising the necessary evil of fractional PLLs.

The first test I did was to set the tuner to 1575421875, which leads to a -1875 Hz center frequency but is nicely represented in 16 bits using a 28.8 MHz reference (remember the R820T). In fact, 54 + 0.7021484375 = 54 + [1011001111000000]/2^16. ..ok well actually it fits on 10 :)

Here I found a small bug in the driver  and replaced the following messy (IMHO) code: 

/* sdm calculator */
while (vco_fra > 1) {
    if (vco_fra > (2 * pll_ref_khz / n_sdm)) {
        sdm = sdm + 32768 / (n_sdm / 2);
        vco_fra = vco_fra - 2 * pll_ref_khz / n_sdm;
        if (n_sdm >= 0x8000)
            break;
    }
    n_sdm <<= 1;
}


with 

mysdm = (((vco_freq<<16)+pll_ref)/(2*pll_ref)) & 0xFFFF;

Then I modified the IF of the R820T from 3.57 MHz to 3.6 MHz, as it is only a few kHz away and it is nicely represented on 16 bit  ..ok well it actually fits in 3 :)
Modifying the IF also impacted the RTL2832U fractional register of course.
I still had a significant error (about 115 Hz) which I could measure comparing the scaled code rate and the carrier rate (which should be proportional of a factor 1540).
After a long time wondering what could be happening, I decided to start tweaking the bits of the R820T.
One in particular called PLL dithering seemed suspicious. Disabling it kind of doubled the error to about 220Hz. Sad.. but I did recall now the resolution of the tuner (439.45 Hz) and guessed that there is a hidden 17th bit which toggles randomly when "dithering" and is instead fixed to 1 when "not dithering". A couple of references which could explain why are here:
http://petrified.ucsd.edu/~ispg-adm/pubs/KWangDissertation.pdf
http://www.ece.rochester.edu/users/friedman/papers/ISCAS_04_PLL.pdf

How sneaky! But I could nicely recover that 17th bit with the RTL2832U (which has 22).
So I have now rock-solid code-carrier assistance ^_^
Figure 1: Code-carrier mismatch when tracking a satellite with RTL-SDR
One step closer to integer ambiguity resolution?

Cheers,
Mic

Monday, March 24, 2014

R820T with 28.8 MHz TCXO

I recently looked around for tools to use as low cost spectrum scanners, being the objective frequency range 400 MHz to 1.7 GHz (incidentally, DVB-T and GPS).
Of course rtl-sdr is an attractive option so I dusted off some dongles I had bought 6 months ago in China and played again with them, coming to the conclusion that I really like it especially after its main limitation is overcome :)

The 28.8 MHz crystal is quite poor. I asked Takuji for a TCXO but he said he emptied his stock rapidly. Of course a replacement is nowhere to be found on the big distribution (Digikey, Mouser, Farnell, RS, etc..), so I went to an old time acquaintance at Golledge and, despite having to order 100 pieces, my request was fulfilled. After all, dongles look quite good with the new crystal:
Figure 1: RTL-SDR with 28.8 MHz TCXO (Golledge GTXO-92)

I measured the frequency deviation with my simple GPS software receiver and I happy to report that it is within spec, bounded to 2ppm. By the way, I tried using other GNSS software receivers and will write about my experience in another post soon.

On the frequency plan side, the R820T combined with the RTL2832U is great for GPS. Most people would use it with an active antenna, where the LNA solves the problem of losses due to the impedance mismatch (50 against 75 ohm) and the noise figure of the tuner (3.5 dB according to datasheet).
The frequency plan with an IF of 3.57 MHz solves elegantly the problem of LO feedthrough and I/Q unbalance typical of ZIF tuner. The IF is recovered automatically in the digital domain by the demodulator so it does not appear in the recorded file. 8bit I/Q recording at 2.048 Msps is more than sufficient for GPS and I also tracked Galileo E1B/C with it (despite some obvious power loss due to the narrow filter band). In my tests, I used a Dafang technology DF5225 survey antenna and the signal time plot shows that 5 bits are actually exercised. I powered the antenna with 3.3V from a Skytraq Venus8 (Ducat10 with S1216F8) through an all-by-one DC blocked passive 4-way splitter/combiner (6 dB unavoidable loss) from ETL-systems.

Figure 2, 3 and 4: Power spectrum, histogram, and time series at L1.

I posted three GPS files here:
https://app.box.com/s/wxizs3p7zu8x2jmbnzod
https://app.box.com/s/xvfabkqfkmehg5osa3ra
https://app.box.com/s/dqrel15mwj73xijflkma

Since someone asked for it, here are the tracking results of Galileo E19 plotted after the fact with Matlab:





and Galileo E20:






More to come later,
Michele