GNSS-SDR operation with a Realtek RTL2832U USB dongle DVB-T receiver
Mục lục bài viết
Introduction
This article describes what is probably one of the cheapest ways for
experimenting with real-life signals and GNSS-SDR. This is a product from a
combined effort of many people, so let us only mention (to our knowledge) the
very original source, the V4L/DVB kernel developer Antti Palosaari, who
discovered
an undocumented operation mode for some USB DVB-T dongles based on the Realtek
RTL2832U
chipset,
enabling them to be used as a cheap Software Defined Radio (SDR) front-end. The
key feature is that the chip allows transferring raw I/Q samples to the host,
which in principle is responsible for DAB/DVB+/FM demodulation. This is great
news for a GNSS software receiver since it covers the targeted frequency bands.
The RTL2832U outputs 8-bit I/Q-samples with a baseband sample rate up to 3.2
MSPS, according to the specifications. However, the highest sample rate that has
been tested so far without losing samples is 2.8 MSPS. The frequency range is
highly dependent on the used tuner. Dongles that use Elonics E4000 offer the
widest possible range (64 – 1700 MHz with a gap from approx. 1100 – 1250 MHz).
When used out-of-spec, a tuning range of approx. 50 MHz – 2.2 GHz is possible
(with gap). More information about device compatibility is available at the
Osmocom rtl-sdr Wiki.
The GNSS Galileo E1 and GPS L1 links are centered at 1575.42 MHz, and this band
is covered by the E4000 tuner IC. The GNSS-SDR software receiver can be
configured to use the RTL2832U as a real-time signal source, thus providing a
low-cost option (about 20 € or $25) to build a real-time software-defined GPS L1
receiver. This article introduces the operation details and some performance
measurements regarding this GNSS-SDR feature.
OsmoSDR driver support
The GNSS-SDR support for Realtek RTL2832U dongles makes use of the OsmoSDR GNU
Radio source block and driver. We implemented a new GNSS-SDR Signal Source
adapter that instantiates OsmoSDR’s gr_hier_block2
, which associated GNSS-SDR
Signal Source name is Osmosdr_Signal_Source
. The adapter’s source code is
located at:
It makes use of the gr-osmosdr library,
including the following header:
#include <osmosdr/source.h>
Important:
The compilation of the RTL2832U support in GNSS-SDR is optional and it requires
the installation of the
gr-osmoSDR library.
See GNSS-SDR’s
README.md file for
step-by-step building instructions with the optional OsmoSDR
driver.
Configuring GNSS-SDR for GPS L1 real-time operation
In order to use a compatible USB DVB-T device, it is necessary to select the
Osmosdr_Signal_Source
implementation in the GNSS-SDR configuration file
(gnss-sdr.conf)
for the SignalSource
block. In addition, the following parameters should be
configured:
- the baseband sampling frequency,
- the RF center frequency,
- the RF gain, and
- the AGC operation.
Hereafter can be found a working configuration for the reception of a GPS L1 C/A
signal:
[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
GNSS-SDR.internal_fs_sps
=
2000000
;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation
=
Osmosdr_Signal_Source
SignalSource.item_type
=
gr_complex
SignalSource.sampling_frequency
=
2000000
SignalSource.freq
=
1575420000
SignalSource.gain
=
50
SignalSource.rf_gain
=
40
SignalSource.if_gain
=
30
SignalSource.AGC_enabled
=
true
SignalSource.samples
=
0
SignalSource.repeat
=
false
SignalSource.dump
=
false
SignalSource.dump_filename
=
../data/signal_source.dat
SignalSource.enable_throttle_control
=
false
The recommended sampling frequency is 2 MSPS. This configuration enables the
real-time receiver operation with 8 satellite channels in an Intel Core 2 quad
Q9400 @ 2.66 GHz with 4 GB of RAM. In addition, we obtained the best results
enabling the Automatic Gain Control (AGC) of the E4000 front-end.
RTL2832U oscillator accuracy and stability issues
It is known, as reported in Michele Bavaro’s GNSS
blog, that the crystal oscillator used by
the RTL2832U dongles has very low accuracy. Our experiments with two different
devices (EzCap 666 and Generic P160) confirm this issue. We used a high accuracy
signal generator to generate an unmodulated carrier at the GPS L1 link and we
measured the carrier frequency error in the captured signal. The resulting
deviations were in the order of 80 kHz for the EzCap and 14.8 kHz for the P160.
The local oscillator frequency inaccuracies cause two different effects in the
GNSS receiver:
-
The baseband signal is shifted to an Intermediate Frequency (IF), equal to
the VCO deviation. It can be seen as an apparent Doppler shift. If the
superposed Doppler shift (real signal Doppler + the parasitic IF) is beyond the
acquisition Doppler search margins, the acquisition will fail. -
A deviation in the sample clock since the local oscillator is used also for
the Analog-to-Digital Converter (ADC) sample clock reference. This issue
affects the tracking Delay Locked Loop (DLL) as there is a deviation in the
theoretical sample clock frequency set in the receiver configuration file and
the real sample frequency. If the deviation is high enough, the tracking DLL
will lose the lock.
Thanks to the GNSS-SDR flexibility, the software receiver can be configured to
overcome both effects. On the one hand, the parasitic IF frequency can be
canceled using the Signal Conditioner block by enabling the frequency
translating FIR filter as follows:
;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation
=
Signal_Conditioner
DataTypeAdapter.implementation
=
Pass_Through
;######### INPUT_FILTER CONFIG ############
InputFilter.implementation
=
Freq_Xlating_Fir_Filter
InputFilter.input_item_type
=
gr_complex
InputFilter.output_item_type
=
gr_complex
InputFilter.taps_item_type
=
float
InputFilter.number_of_taps
=
5
InputFilter.number_of_bands
=
2
InputFilter.band1_begin
=
0.0
InputFilter.band1_end
=
0.85
InputFilter.band2_begin
=
0.90
InputFilter.band2_end
=
1.0
InputFilter.ampl1_begin
=
1.0
InputFilter.ampl1_end
=
1.0
InputFilter.ampl2_begin
=
0.0
InputFilter.ampl2_end
=
0.0
InputFilter.band1_error
=
1.0
InputFilter.band2_error
=
1.0
InputFilter.filter_type
=
bandpass
InputFilter.grid_density
=
16
InputFilter.sampling_frequency
=
2000000
InputFilter.IF
=
14821
;######### RESAMPLER CONFIG ############
Resampler.implementation
=
Pass_Through
Resampler.dump
=
false
Resampler.item_type
=
gr_complex
On the other hand, the sample frequency error can be measured and taken into
account by setting the estimated sample clock frequency value in the internal
GNSS-SDR sampling frequency parameters as follows:
GNSS-SDR.internal_fs_sps
=
corrected_value
InputFilter.sampling_frequency
=
corrected_value
GPS active antenna
We used a ceramic patch antenna equipped with an internal Low Noise Amplifier
(LNA) to reduce the overall noise figure. The picture below shows a picture of
such Garmin GA27C GPS antenna exposing the ceramic patch over the LNA PCB.
Garmin GA-27 active antenna without the plastic cover.
In order to connect the antenna to a DVB-T dongle it is necessary some hardware
hacking:
-
Assuming that the GPS antenna is equipped with an SMA M connector, it is
required to build an RF cable to convert the SMA M connector to the MCX M
connector in order to plug the GPS antenna into the DVB-T dongle. -
We must feed the LNA using a Bias-T network.
Some performance measurements and conclusions
Two different setups were assessed to receive and process GPS signals in
real-time:
- In the first one, we connected the DVB dongle to an active patch antenna
using a custom 20 dB amplification and filtering circuit. The gain block
provides also the +5 DC voltage required to power the active antenna internal
LNA. More information on this circuit can be found at Arribas’ PhD
Thesis.
The following picture shows the DVB dongle (generic P160) + LNA + Active
antenna setup.
Generic P160 DVB-T dongle connected to a GA-27 antenna using an external LNA circuit.
- On the other hand, we also tested the direct connection of an active GPS
antenna to the DVB dongle as well, using a standard bias-T network. This setup
is shown in the following picture:
Generic P160 DVB-T dongle connected to a GA-27 antenna using a bias-T network.
In those experiments, we used a Dell XPS M1530 laptop equipped with an Intel
Core 2 Duo T9300 CPU with 4 GB of RAM. The operating system was Linux Ubuntu
12.04 and the GNU Radio version was 3.6.0.
GNSS-SDR was able to acquire, track, and obtain a position fix in both front-end
setups. The antenna was placed on the roof of the CTTC building and remained
static during the experiments.
The following pictures show some tracking data analysis using the GNSS-SDR
intermediate data extraction and dump feature:
Tracking.dump
=
true
Tracking.dump_filename
=
./tracking_ch_
As a sanity check, we did some post-processing analysis using the Matlab script
based on the ones on Key Borre’s book and available at
The figure clearly shows the GPS C/A navigation symbols, The PLL and DLL
discriminator outputs are quite noisy, tough:
Tracking data analysis.
Tracking data analysis.
Finally, the obtained KML position file can be displayed by Google Earth as
shown in the following picture. The yellow line represents the position
evolution for a 10 seconds time-lapse. The red arrow represents the true antenna
position. In addition, we plotted also the height evolution. Considering that
the Position Velocity and Time (PVT) solutions were estimated using 4 satellites
and a really low sampling frequency of 1.2 MSPS, the estimated position error
was in the order of 200 m.
GNSS-SDR estimated position analysis using Google Earth.
Summarizing this preliminary experiment, we can conclude that the GNSS
positioning using low cost Realtek-based DVB-T dongles is feasible, and to the
best of our knowledge, this is the first time that a GNSS software receiver
supports the real-time operation with RTLSDR-based devices. This milestone
enables access to the full potential of GNSS services using a standard laptop
and extremely low-cost hardware. Further measurements and improved support for
RTLSDR devices are planned.
Update: Those experiments and the results were finally published in a
paper presented at ION GNSS+ 2013.
Update 2: New RTL-SDR Blog
V3
dongles ship a < 1 PPM temperature compensated oscillator (TCXO), which is well
suited for GNSS signal processing, and a 4.5 V powered bias-tee to feed an
active antenna that can be enabled by software. Check out the
Osmosdr_Signal_Source documentation for more details.
Full configuration file (updated for the current GNSS-SDR version):
[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
GNSS-SDR.internal_fs_sps
=
2000000
;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation
=
Osmosdr_Signal_Source
SignalSource.item_type
=
gr_complex
SignalSource.sampling_frequency
=
2000000
SignalSource.freq
=
1575420000
SignalSource.gain
=
50
SignalSource.rf_gain
=
40
SignalSource.if_gain
=
30
SignalSource.AGC_enabled
=
true
SignalSource.samples
=
0
SignalSource.repeat
=
false
SignalSource.dump
=
false
SignalSource.dump_filename
=
../data/signal_source.dat
SignalSource.enable_throttle_control
=
false
;# Please note that the new RTL-SDR Blog V3 dongles ship a < 1 PPM
;# temperature compensated oscillator (TCXO), which is well suited for GNSS
;# signal processing, and a 4.5 V powered bias-tee to feed an active antenna.
;# Whether the bias-tee is turned off before reception depends on which version
;# of gr-osmosdr was used when compiling GNSS-SDR. With an old version
;# (for example, v0.1.4-8), the utility rtl_biast may be used to switch the
;# bias-tee, and then call gnss-sdr.
;# See https://github.com/rtlsdrblog/rtl_biast
;# After reception the bias-tee is switched off automatically by the program.
;# With newer versions of gr-osmosdr (>= 0.1.4-13), the bias-tee can be
;# activated by uncommenting the following line:
;SignalSource.osmosdr_args=rtl,bias=1
;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation
=
Pass_Through
;######### CHANNELS GLOBAL CONFIG ############
Channels_1C.count
=
8
Channels_1B.count
=
0
Channels.in_acquisition
=
1
Channel.signal
=
1C
;######### ACQUISITION GLOBAL CONFIG ############
Acquisition_1C.implementation
=
GPS_L1_CA_PCPS_Acquisition
Acquisition_1C.item_type
=
gr_complex
Acquisition_1C.coherent_integration_time_ms
=
1
Acquisition_1C.pfa
=
0.01
Acquisition_1C.doppler_max
=
5000
Acquisition_1C.doppler_step
=
250
Acquisition_1C.dump
=
false
Acquisition_1C.dump_filename
=
./acq_dump.dat
;######### TRACKING GPS CONFIG ############
Tracking_1C.implementation
=
GPS_L1_CA_DLL_PLL_Tracking
Tracking_1C.item_type
=
gr_complex
Tracking_1C.dump
=
false
Tracking_1C.dump_filename
=
./tracking_ch_
Tracking_1C.pll_bw_hz
=
35.0;
Tracking_1C.dll_bw_hz
=
1.5;
Tracking_1C.pll_bw_narrow_hz
=
2.5;
Tracking_1C.dll_bw_narrow_hz
=
0.5;
Tracking_1C.extend_correlation_symbols
=
1;
Tracking_1C.dll_filter_order
=
2;
Tracking_1C.pll_filter_order
=
3;
Tracking_1C.early_late_space_chips
=
0.5;
Tracking_1C.early_late_space_narrow_chips
=
0.25
;######### TELEMETRY DECODER GPS CONFIG ############
TelemetryDecoder_1C.implementation
=
GPS_L1_CA_Telemetry_Decoder
TelemetryDecoder_1C.dump
=
false
;######### OBSERVABLES CONFIG ############
Observables.implementation
=
Hybrid_Observables
Observables.dump
=
false
Observables.dump_filename
=
./observables.dat
Observables.enable_carrier_smoothing
=
false
Observables.smoothing_factor
=
200
;######### PVT CONFIG ############
PVT.implementation
=
RTKLIB_PVT
PVT.positioning_mode
=
PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic
PVT.iono_model
=
Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX
PVT.trop_model
=
Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad
PVT.enable_rx_clock_correction
=
false
PVT.output_rate_ms
=
100
PVT.rinexobs_rate_ms
=
100
PVT.display_rate_ms
=
500
PVT.dump_filename
=
./PVT
PVT.nmea_dump_filename
=
./gnss_sdr_pvt.nmea;
PVT.flag_nmea_tty_port
=
false;
PVT.nmea_dump_devname
=
/dev/pts/4
PVT.dump
=
false
PVT.flag_rtcm_server
=
true
PVT.flag_rtcm_tty_port
=
false
PVT.rtcm_dump_devname
=
/dev/pts/1