Main Content

Galileo Waveform Generation

Since R2025a

This example shows how to generate Galileo F/NAV and I/NAV data, ranging codes, and E1/E5 complex baseband waveforms, as defined in the Galileo signal-in-space standard [1]. To design a Galileo receiver, you must use a signal. Because you cannot control real-world Galileo transmitter and channel parameters, you cannot use a signal received from a satellite to test a receiver. To test the receiver, you must use a waveform generated under a controlled set of parameters.

Select Workflow

This example supports these two workflows.

  • Satellite scenario workflow — Simulate a Galileo satellite scenario, and generate a realistic waveform for a specified receiver position. The process begins by simulating a Galileo satellite constellation using data from an almanac or RINEX file. Based on the location of the receiver, you identify the visible satellites. For these satellites, generate the navigation data, and produce a corresponding Galileo waveform. From the simulated satellite scenario, calculate the Doppler effects, latency, and signal-to-noise ratio (SNR), and optionally apply them to the waveform. This results in a realistic Galileo waveform that you can use to test your receiver. This figure shows the steps of the satellite scenario workflow.

  • Custom workflow — Use this workflow to generate Galileo waveforms for the satellites of your choice. In the custom workflow, you must specify the IDs for the satellites and their Doppler, latency, and SNR values, and generate the waveform. In this workflow, you have more control of which satellite ID waveforms you generate because you do not base them from receiver visibility in a satellite scenario. This figure shows the custom workflow.

Specify the workflow to use for this example.

workflow = "custom"; % Possible values are "scenario" | "custom"

Initialize Galileo Signal Parameters

In this section, you specify the configuration parameters used to generate the Galileo waveform.

This example enables you to generate both Galileo E1 and E5 signals. The E1 signal consists of the E1B and E1C while, the E5 signal consists of the E5a and E5b components. The example can generate a complete E1 or E5 waveform, or any individual component of either. Specify the signal type to generate in this example.

signalType = "E1"; % Possible values are "E1" | "E1B" | "E1C" | "E5" | "E5a" | "E5b"

Specify the sample rate of the waveform.

sampleRate = 20e6;     % In Hz

Generate a Galileo waveform with a duration that corresponds to the number of navigation data bits. Because F/NAV data has a transmission rate of 50 bits per second (bps), the waveform duration for n bits is n/50 seconds. Similarly for I/NAV data, because the bit rate is 250 bps the waveform duration for n bits is n/250 seconds.

numNavDataBits = 10; % Number of navigation data bits in the output waveform

When generating navigation data bits, you can source ephemeris information from either an almanac file or a RINEX file. By default, this example uses the almanac file to derive ephemeris data. However, if you have a Navigation Toolbox™ license, you can obtain ephemeris information from the RINEX file instead by specifying ephemerisSource as "rinex". In the satellite scenario workflow, this value also determines the source of satellite scenario parameters. For example, if ephemerisSource is set to "almanac", the example generates the satellite scenario using the parameters available in the almanac file.

ephemerisSource = "almanac";  % Possible values are "almanac" | "rinex"
if ephemerisSource == "rinex"
    rinexFileName = "GODS00USA_R_20211750000_01D_EN.rnx";
end

By default, the example does not use the propagation channel, and outputs a distinct waveform for each satellite. If you enable the propagation channel, the example instead superimposes the waveforms into a single multi-satellite waveform.

enablePropagationEffects = false;             % When set to true, waveform passes through the simulated channel

Initialize the receiver position for the satellite scenario workflow, or the satellite IDs, Doppler, latency, and SNR values for the custom workflow.

if workflow == "scenario"
    rxlat             = 71.123; % In degrees
    rxlon             = 21.123; % In degrees
    rxalt             = 100; % In meters
    minElevationAngle = 10; % In degrees
    centerFrequency = 1575.42e6;              % Needed for Doppler calculation. Units in Hz
else % workflow == "custom"
    satelliteIDs = [1; 2];

    % Initialize the channel parameters. These parameters are not valid
    % when enablePropagationEffects is set to false.
    dopplerVal = [1000 2000]; % In Hz. Length must be same as length of satelliteIDs variable
    latencyVal = [0.00123 0.00121]; % In sec. Length must be same as length of satelliteIDs variable
    snrval     = [-20 -22] ; % In dB. Length must be same as length of satelliteIDs variable
end

% Initialize the constants used in the example
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 = sampleRate;                        % Bandwidth in Hz

Initialize the almanac file to use in the example. You can use the almanac file included with this example or get the most recent one from the web.

almanacSource     = "stored"; % Possible values are "stored" | "get latest"
if almanacSource == "stored"
    almFileName   = "galileoAlmanac.xml"; % Specify the almanac file name
    startTime = datetime(2024,11,29,0,0,48,TimeZone="UTC"); % The almanac file in the example folder was downloaded on November 29 2024
else
    disp("Attempting to fetch the Galileo almanac file from https://www.gsc-europa.eu/gsc-products/almanac")

    % Try retrieving the latest almanac. If not found, try to fetch an
    % almanac file up to 15 days earlier. Otherwise, use the default
    % almanac file included with the example.
    foundalmanac = false;
    for itry = 0:15
        try
            currentDay = string(datetime("today",TimeZone="UTC",Format="uuuu-MM-dd")-itry);
            url = "https://www.gsc-europa.eu/sites/default/files/sites/all/files/" + currentDay + ".xml";
            almFileName = "galileoAlmanac_" + currentDay + ".xml";
            websave(almFileName,url)
            foundalmanac = true;
            disp("Found Galileo almanac for the date: " + currentDay + ". Using this almanac file for Galileo waveform generation.")
            break
        catch ME
            if ME.identifier == "MATLAB:webservices:HTTP404StatusCodeError"
                continue
            else
                rethrow(ME)
            end
        end
    end
    if foundalmanac == false
        warning("No almanac file found within last 15 days.\n" + ...
            "Using the default almanac file instead.\n" + ...
            "To manually get the almanac file, see https://www.gsc-europa.eu/gsc-products/almanac")
        almFileName = "galileoAlmanac.xml";
        startTime = datetime(2021,6,24,0,0,48,TimeZone="UTC");
    else
        startTime = datetime("now",TimeZone="UTC");
    end
end

% Initialize the Galileo Waveform Generator object based on the specified
% signal type and sample rate.
waveobj = HelperGalileoWaveformGenerator(SignalType=signalType,SampleRate=sampleRate);

if ephemerisSource == "rinex"
    % Get the start time for simulation from the RINEX file. To select a
    % different start time, specify a custom value for startTime.
    rinexdata = rinexread(rinexFileName);
    startTime = HelperGPSConvertTime(rinexdata.Galileo.GALWeek(1),rinexdata.Galileo.TransmissionTime(1));
end

Generate Galileo Navigation Data

The Galileo standard specifies these navigation data formats: F/NAV, I/NAV, and C/NAV. E5a transmits F/NAV data, E5b and E1B transmit I/NAV data. For more information on Galileo navigation data, see section 4.2 of [1]. Using this section of code, you can generate the Galileo navigation data in MATLAB®.

Initialize the Galileo navigation data object from HelperGalileoNavigationData. This example does not support ISM, OSNMA, SAR, and reduced ephemeris data generation, and dummy and alert pages. For detailed information on these limitations, see HelperGalileoNavigationData.

if any(strcmp(signalType,{'E1','E1B','E1C'}))
    dataSignalType = 'E1B';
elseif any(strcmp(signalType,{'E5a'}))
    dataSignalType = 'E5a';
elseif any(strcmp(signalType,{'E5b'}))
    dataSignalType = 'E5b';
elseif any(strcmp(signalType,{'E5'}))
    dataSignalType = 'E5b';
end

[weeknum,inittow] = HelperGPSConvertTime(startTime);
if ephemerisSource == "almanac"
    dataobj = HelperGalileoNavigationData(almFileName,true,SignalType=dataSignalType);
else % ephemerisSource == "rinex"
    dataobj = HelperGalileoNavigationData(rinexdata,SignalType=dataSignalType);
    setnavdata(dataobj,almFileName,false);                                     % Initialize the almanac data without updating the ephemeris from the almanac file
end
dataobj.DisableWarnings = true                                                 % Disables all warnings from the data generator object
dataobj = 
  HelperGalileoNavigationData with properties:

                  SignalType: "E1B"
                   Ephemeris: [25×20 table]
                       Clock: [25×6 table]
        AdditionalParameters: [0×11 table]
                     Almanac: [25×16 table]
    AlmanacSatelliteSequence: [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25]
                  Ionosphere: [0×10 table]
                         UTC: [0×10 table]
                        GGTO: [0×6 table]
                 TextMessage: [0×2 table]
             DisableWarnings: 1
                     Default: [1×1 struct]

if workflow == "scenario"
    % Calculate the visible satellites, Doppler shift, latency, and SNR
    sampletime = 1e-3;
    sc = satelliteScenario;
    sc.StartTime = startTime;
    sc.SampleTime = sampletime;
    sc.StopTime = startTime + seconds(waveobj.BitDuration*numNavDataBits - sampletime);
    if ephemerisSource == "almanac"
        sat = HelperAddGalileoSatellitesToScenario(sc,almFileName);
    else
        rinexdata = rinexread(rinexFileName);
        sat = satellite(sc,rinexdata);
    end
    rx = groundStation(sc,rxlat,rxlon,"Altitude",rxalt,"MinElevationAngle",minElevationAngle);
    % Calculate Doppler shift and latency over time for all visible satellites
    dopplerVal = dopplershift(sat,rx,Frequency=centerFrequency);
    latencyVal = latency(sat,rx);
    Pr   = Pt*DtLin*DrLin./ ...
        ((4*pi*(centerFrequency+dopplerVal).*latencyVal).^2);
    snrval = 10*log10(Pr/(k*T*rxBW)) + 3;
    visiblesatindices = find(~isnan(latencyVal(:,1))).';
    satelliteIDs = dataobj.Ephemeris.PRNID(visiblesatindices);
    dopplerVal = dopplerVal(visiblesatindices,:);
    latencyVal = latencyVal(visiblesatindices,:);
    snrval = snrval(visiblesatindices,:);
end
disp("This example generates Galileo waveform for satellite IDs: " + num2str(satelliteIDs.'))
This example generates Galileo waveform for satellite IDs: 1  2

Generate the navigation data bits.

if signalType=="E5a" % FNAV data
    numpages = ceil(numNavDataBits/500);
    fnavbits = navdata2bits(dataobj,satelliteIDs,inittow,numpages); % Generates the navigation data bits
    navbits = fnavbits(1:numNavDataBits,:);
else
    numpages = ceil(5*numNavDataBits/250);                          % The factor of 5 is because INAV will have 5 times more bits in the same duration
    inavbits = navdata2bits(dataobj,satelliteIDs,inittow,numpages); % Generates the navigation data bits
    if signalType=="E5"
        dataobj.SignalType = "E5a";
        numpages = ceil(numNavDataBits/500);
        fnavbits = navdata2bits(dataobj,satelliteIDs,inittow,numpages); % Generates the navigation data bits
        navbits = {fnavbits(1:numNavDataBits,:), inavbits(1:5*numNavDataBits,:)};
    else
        navbits = inavbits(1:numNavDataBits,:);
    end
end

Generate Galileo Waveform

To generate a Galileo E1 waveform, you must use the E1B and E1C components, both located on the in-phase branch.

  • E1B component — Consists of I/NAV data transmitted at 250 bps. Each bit is 4 milliseconds long.

  • E1C component — Contains no data and is a pilot signal.

  1. Generate the primary code for E1B at a frequency of 1.023 MHz, which results in 4092 chips per code block. Each code block has a 4 milliseconds duration.

  2. Generate the primary code for E1C, also at 1.023 MHz, which also results in 4092 chips per code block. Each code block has a 4 milliseconds duration.

  3. Spread the I/NAV data with the E1B primary code to produce spread symbols. Independently modulate these spread symbols using the BOC(1,1) and BOC(6,1) techniques. Form the E1B waveform by linearly combining the binary offset carrier (BOC) modulated signals for E1B with factors α and β, at values of sqrt(10/11) and sqrt(1/11) respectively.

  4. For E1C, use a secondary code at 250 chips per second, with each code block containing 25 chips. Spread the E1C secondary code with the primary code to produce spread symbols. Independently modulate these spread symbols using the BOC(1,1) and BOC(6,1) techniques. Form the E1C waveform by linearly combining the binary offset carrier (BOC) modulated signals for E1C with factors α and -β (values defined in previous point).

  5. Combine the E1B and E1C waveforms to produce the Galileo E1 waveform using this equation: E1=(E1B-E1C)/2.

To generate the Galileo E5 signal, with a center frequency of 1191.795 MHz, you must create F/NAV and I/NAV data in accordance with the Galileo standard [1]. The E5a component with a center frequency of 1176.45 MHz, and the E5b component with a center frequency of 1207.14 MHz, are complex baseband signals. To produce the E5 signal, you must combine them using AltBOC modulation. For more information on the AltBOC modulation, see section 2.3.1.2 of the Galileo standard [1].

The generation of E5a signal involves these steps.

  • The E5a signal consists of an in-phase component (E5aI) and a quadrature-phase component (E5aQ).

  • The chip rate of the primary ranging code for E5aI is 10.23 MHz and the code repeats after every 10230 chips. Thus, each code block of E5aI is of 1 millisecond duration.

  • The secondary code for E5aI is at 1 kilo baud rate. So, each chip of the secondary code is of 1 millisecond duration and the code repeats for every 20 chips.

  • Tiered code formation for E5aI — The primary ranging code is XORed with the secondary code. This results in an effective code block length of 20 milliseconds, matching the duration of one F/NAV data bit.

  • Data spreading for E5aI — The F/NAV data bit is spread using the tiered code formed by the E5aI primary and secondary codes. The F/NAV data rate is 50 bps, resulting in 20 milliseconds per bit.

  • E5aQ component waveform generation — The chip rate of the primary ranging code for E5aQ is 10.23 MHz and the code repeats after every 10230 chips. Thus, each code block of E5aI is of 1 millisecond duration. The secondary code for E5aQ is at 1 kilo baud rate. So, each chip of the secondary code is of 1 millisecond duration and the code repeats for every 100 chips. Because there is no data on E5aQ component, the output after creation of tiered code is mapped on the quadrature branch by mapping bit 0 to +1 and bit 1 to -1.

Similarly, the generation of E5b signal involves these steps.

  • The E5b signal consists of an in-phase component (E5bI) and a quadrature-phase component (E5bQ).

  • The chip rate of the primary ranging code for E5bI is 10.23 MHz and the code repeats after every 10230 chips. Thus, each code block of E5bI is of 1 millisecond duration.

  • The secondary code for E5bI is at 1 kilo baud rate. So, each chip of the secondary code is of 1 millisecond duration and the code repeats for every 4 chips.

  • Tiered code formation for E5bI — The primary ranging code is XORed with the secondary code. This results in an effective code block length of 4 milliseconds, matching the duration of one I/NAV data bit.

  • Data spreading for E5bI — The I/NAV data bit is spread using the tiered code formed by the E5bI primary and secondary codes. The I/NAV data rate is 250 bps, resulting in 4 milliseconds per bit.

  • E5bQ component waveform generation — The chip rate of the primary ranging code for E5bQ is 10.23 MHz and the code repeats after every 10230 chips. Thus, each code block of E5bI is of 1 millisecond duration. The secondary code for E5bQ is at 1 kilo baud rate. So, each chip of the secondary code is of 1 millisecond duration and the code repeats for every 100 chips. Because there is no data on E5bQ component, the output after creation of tiered code is mapped on the quadrature branch by mapping bit 0 to +1 and bit 1 to -1.

To generate a constant envelope E5 signal, you use the AltBOC technique to multiplex the E5a and E5b signals.

Update the waveform generator properties based on the calculations till now.

release(waveobj)
waveobj.CodeNumber = satelliteIDs;
waveobj.InitialTime = inittow;
galwaveforms = waveobj(navbits);
size(galwaveforms)
ans = 1×2

      800000           2

Optionally, pass the generated waveform through the propagation channel.

% Initialize channel object, if required
if enablePropagationEffects == 1
    gnssChannel = HelperGNSSChannel(SignalToNoiseRatio=snrval.', ...
        SignalDelay=latencyVal.',FrequencyOffset=dopplerVal.', ...
        RandomStream="mt19937ar with seed");
    bbwave = gnssChannel(galwaveforms);
end

Visualize the spectrum of the generated Galileo waveform before passing through the propagation channel.

scope = spectrumAnalyzer(SampleRate=sampleRate);
scope(galwaveforms)

Further Exploration

Supporting Files

This example uses these data and helper files:

References

[1] European GNSS Service Centre (GSC). Galileo Open Service Signal-In-Space Interface Control Document. OS SIS ICD v2.1. GSC, November 2023. https://www.gsc-europa.eu/sites/default/files/sites/all/files/Galileo_OS_SIS_ICD_v2.1.pdf.

See Also

Functions

Objects

Topics