Modular tracking algorithm for various GNSS Systems
Author JuliaGNSS
7 Stars
Updated Last
1 Year Ago
Started In
February 2019

DOI Build Status Coverage Status


This implements a basic tracking functionality for GNSS signals. The correlation is done in the interval of PRNs. Each call of the tracking function returns the current code phase, Doppler, the Carrier-to-Noise-Density-Ratio (CN0), data bits, number of data bits and the last correlator output.


  • Supports GPS L1 / L5 and Galileo E1B
  • CN0 estimation
  • Secondary code detection
  • Bit detection
  • Phased array tracking
  • GPU acceleration (CUDA)

Getting started


julia> ]
pkg> add Tracking


using GNSSSignals
using Tracking
using Tracking: Hz
carrier_doppler = 1000Hz
code_phase = 50
sampling_frequency = 2.5e6Hz
prn = 1
gpsl1 = GPSL1()
state = TrackingState(prn, gpsl1, carrier_doppler, code_phase)
results = track(signal, state, sampling_frequency)
next_results = track(next_signal, get_state(results), sampling_frequency)

If you'd like to track several signals at once (e.g. in the case of phased antenna arrays), you will have to specify the optional parameter num_ants::NumAnts{N} and pass a beamforming function to the track function:

state = TrackingState(prn, gpsl1, carrier_doppler, code_phase, num_ants = NumAnts(4)) # 4 antenna channels
results = track(signal, state, sampling_frequency, post_corr_filter = x -> x[1]) # Post corr filter is optional

Usage with CUDA.jl

This package supports accelerating the tracking loop by using the GPU. At the moment support is only provided for CUDA.jl. If you'd like to use this option, you'd have to opt-in by providing the following argument upon creating an AbstractGNSS:

gpsl1_gpu = GPSL1(use_gpu = Val(true))

Beware that num_samples must be provided explicitly upon creating a TrackingState:

state_gpu = TrackingState(prn, gpsl1_gpu, carrier_doppler, code_phase, num_samples = N)

Moreover, your signal must be a StructArray{ComplexF32} of CuArray{Float32} type:

using StructArrays
signal_cu = CuArray{ComplexF32}(signal_cpu)
signal_gpu = StructArray(signal_cu)

Otherwise the usage is identical to the example provided above, including the case for multi-antenna tracking:

results_gpu = track(signal_gpu, state_gpu, sampling_frequency)
next_results_gpu = track(next_signal_gpu, get_state(results_gpu), sampling_frequency)