Main Content

GNSS Signal Transmission Using Software-Defined Radio

Since R2024b

This example shows how to generate a global positioning system (GPS) waveform and transmit using a software-defined radio (SDR). You can use this example to employ the generated GPS waveform to test your receiver. Though this example describes the generation of a GPS waveform, you can extend it to accommodate other global navigation satellite system (GNSS) technologies.

This example follows these steps.

  1. Use a GPS almanac file to simulate the satellite constellation.

  2. Specify the receiver position to create a realistic GPS waveform scenario.

  3. Simulate the satellite environment to calculate the relative positions of satellites to the modeled receiver.

  4. Compute the Doppler shift, delay, and power of the received signal in this scenario.

  5. Introduce impairments like Doppler shift and delay into the generated baseband signal using the results of the previous step.

  6. Transmit the impaired baseband waveform through an SDR.

This figure illustrates the waveform generation process.

WaveformGeneration.png

Using this example, you can save the GPS waveform to a file or transmit the signal over-the-air using a supported SDR.

GNSSSDRWorkFlow.png

Initialize and Configure Parameters

The GPS Waveform Generation example shows waveform generation from only one satellite without any impairments. In this example, you can generate a multi-satellite waveform by simulating a satellite scenario and transmit that waveform over-the-air using an SDR.

Specify the configuration parameters to generate the waveform.

useSDR            = false;                  % In the default case, do not use SDR
WriteWaveToFile   = false;
waveformFileName  = "gpsBBWaveform.bb"; % File extension is always .bb
signalType        = "GPS C/A"; % Possible values: GPS C/A, GPS L1C, and GPS L5
centerFrequency   = 1575.42e6; % Possible values: L1 (1575.42 MHz), L2 (1254.35 MHz), and L5 (1176.45 MHz)
sampleRate        = 5000000; % In Hz
rxlla             = [17.4349,78.3827,19]; % Receiver position in latitude (degrees), longitude (degrees), and altitude (m)
waveDuration      = 10; % Waveform duration in seconds
minElevationAngle = 10; % In degrees. Below this elevation angle satellites are not considered in simulation
seed              = 73; % Seed for getting reproducible results
useSEMAlmanac     = "stored"; % File to derive ephemeris data and satellite simulation
if useSEMAlmanac == "stored"
    % Provide the system effectiveness model (SEM) almanac file name
    almFileName   = "gpsAlmanac.txt"; % Almanac file name
    % Provide the startTime
    startTime = datetime(2021,6,24,0,0,48,TimeZone="UTC");
else
    % Download the latest SEM almanac file from the Navigation Center
    % website and store the file
    url = "https://www.navcen.uscg.gov/sites/default/files/gps/almanac/current_sem.al3";
    currentDay = string(datetime("today",TimeZone="UTC"));
    almFileName = "gps_SEM_" + currentDay + "_UTC.txt";
    websave(almFileName,url)

    % Uses the latest SEM almanac file. Set the startTime to current date
    % and time.
    startTime = datetime("now",TimeZone="UTC");
end

Based on the specified signalType, initialize few configuration parameters.

switch(signalType)
    case "GPS C/A"
        ibranch = "P+D";
        qbranch = "C/A+D";
        navDataType = "LNAV";
        stepTime = 20e-3;
    case "GPS L1C"
        ibranch = "l1C";
        qbranch = "None";
        navDataType = "CNAV2";
        stepTime = 10e-3;
    case "GPS L5"
        ibranch = "I5-of-L5";
        qbranch = "Q5-of-L5";
        navDataType = "L5";
        stepTime = 10e-3;
end

Calculate Doppler shift and latency for a given satellite scenario.

% Initialize satellite scenario
sc = satelliteScenario;
% Set up the satellites based on the RINEX data
sat = satellite(sc,almFileName,OrbitPropagator="gps");
rx = groundStation(sc,rxlla(1),rxlla(2),Altitude=rxlla(3)); % Set up the receiver which doesn't move
rx.MinElevationAngle = minElevationAngle;

sc.StartTime = startTime;
sc.StopTime = sc.StartTime + seconds(waveDuration-stepTime);
sc.SampleTime = stepTime;

% Calculate Doppler shift and latency over time for all the visible satellites
dopShifts = dopplershift(sat,rx,Frequency=centerFrequency);
ltncy = latency(sat,rx);

Initialize values that aid in the signal-to-noise ratio (SNR) calculation.

c = physconst("LightSpeed"); % Speed of light in m/sec
Pt = 44.8;                   % Typical transmission power of GPS satellite in watts
Dt = 12;                     % Directivity of the transmit antenna in dBi
DtLin = db2pow(Dt);
Dr = 4;                      % Directivity of the receive antenna in dBi
DrLin = db2pow(Dr);
k = physconst("boltzmann");  % Boltzmann constant in Joules/Kelvin
T = 300;                     % Room temperature in Kelvin
rxBW = 24e6;                 % Bandwidth in Hz

Calculate power at the receiver from the free space path-loss equation.

Pr   = Pt*DtLin*DrLin./ ...
    ((4*pi*(centerFrequency+dopShifts).*ltncy).^2);

Calculate the signal to noise ratio for each visible satellite. Add some signal power (here 3 dB) to account for losses when transmitting with an SDR.

snrs = 10*log10(Pr/(k*T*rxBW)) + 3;

Generate Waveform and Add Impairments

Initialize the configuration file from the almanac.

satIndices = find(~isnan(ltncy(:,1))).';
navcfg = HelperGPSAlmanac2Config(almFileName,navDataType,satIndices,startTime);
visiblesatPRN = [navcfg(:).PRNID]
visiblesatPRN = 1×8

    10    13    15    20    21    24    29    32

Generate the navigation data.

% Generate GPS navigation data
tempnavdata = HelperGPSNAVDataEncode(navcfg(1));
navdata = zeros(length(tempnavdata),length(navcfg));
navdata(:,1) = tempnavdata;
for isat = 2:length(navcfg)
    navdata(:,isat) = HelperGPSNAVDataEncode(navcfg(isat));
end

Configure the GPS waveform generation object.

wavegenobj = HelperGPSWaveformGenerator(PRNID=visiblesatPRN, ...
    FrequencyOffset=dopShifts(satIndices,1),SignalDelay=ltncy(satIndices,1), ...
    SignalToNoiseRatio=snrs(satIndices,1), ...
    InPhaseSignalType=ibranch,QuadraturePhaseSignalType=qbranch, ...
    SampleRate=sampleRate,RandomStream="mt19937ar with seed",Seed=seed);
numsteps = round(waveDuration/stepTime);
samplesPerStep = sampleRate*stepTime;

Initialize the waveform.

gpswaveform = zeros(numsteps*samplesPerStep,1);

Optionally, initialize the object that writes the waveform to a file.

if WriteWaveToFile == true
    bbwriter = comm.BasebandFileWriter(waveformFileName,sampleRate,0);
end

Generate the waveform.

for istep = 1:numsteps
    idx = (istep-1)*samplesPerStep + (1:samplesPerStep);
    navbit = navdata(istep,:);
    tempWaveform = wavegenobj(navbit);
     gpswaveform(idx) = tempWaveform;
    if WriteWaveToFile == true
        bbwriter(tempWaveform)
    end
    
    % Update the properties of the waveform generation object
    wavegenobj.SignalToNoiseRatio = snrs(satIndices,istep);
    wavegenobj.FrequencyOffset = dopShifts(satIndices,istep);
    wavegenobj.SignalDelay = ltncy(satIndices,istep);
end

Visualize the spectrum of the waveform.

scope = spectrumAnalyzer(SampleRate=sampleRate,AveragingMethod="exponential",ForgettingFactor=1);
scope.SpectrumUnits = "dBW";
% Plot only 1 sec of the waveform spectrum.
wlen = sampleRate; % Number of samples corresponding to one second
if length(gpswaveform) > wlen
    scope(gpswaveform(end-wlen+1:end))
else
    % If the length of the generated waveform is less than one second,
    % visualize the spectrum of the entire waveform
    scope(gpswaveform)
end

Set Up Radio

Call the radioConfigurations (Wireless Testbench) function. The function returns all available radio setup configurations that you saved using the Radio Setup (Wireless Testbench) wizard.

if useSDR == 1
    savedRadioConfigurations = radioConfigurations;

To update the drop-down menu with your saved radio setup configuration names, click Update. Then select the radio to use with this example.

    savedRadioConfigurationNames = [string({savedRadioConfigurations.Name})];
    if ~isempty(savedRadioConfigurationNames)
        radio = savedRadioConfigurationNames(1) ;
    end
end

Transmit Waveform over SDR

Once you connect an SDR, broadcast the GPS signal over-the-air.

if useSDR == 1 & ~isempty(savedRadioConfigurationNames) % Using SDR
    if ~exist("txradio","var")
        txradio = basebandTransmitter(radio);
        txradio.RadioGain = 10;
        txradio.CenterFrequency = centerFrequency;
        txradio.SampleRate = sampleRate
    end
    transmit(txradio,gpswaveform,"once")
end

Further Exploration

This example shows transmission of the signal using basebandTransmitter (Wireless Testbench) object. Alternatively, you can use comm.SDRuTransmitter object, which supports more USRP platforms.

You can transmit the waveform generated in this example over-the-air using an SDR. Then, try to receive that waveform using another SDR, and perform the GPS receiver algorithms on the captured signal.

For a demonstration of how to use the signal waveform directly to evaluate receiver performance without physical hardware connections, see

Supporting Files

This example uses these data and helper files.

Related Topics