Skip to content

Instantly share code, notes, and snippets.

@dmiralles2009 dmiralles2009/

Last active Dec 20, 2017
What would you like to do?
GSoC 2017. Contribution to the GNSS-SDR platform


The current document provides a descrption of the work developed for GNSS-SDR during the GSoC 2017 program. This project intended to extend the capabilities of the GNSS-SDR software by providing a working implementation of GLONASS L1 SP signals.


Team Member Function
Damian Miralles Developer
Luis Esteve Mentor
Carles Fernandez Mentor
Jordi Vilà-Valls Mentor


This project helps to increase the number of signals capable of being processed by the GNSS-SDR software. Its objective was to expand the receiver to GLONASS signals, providing a working implementation ofthe GLONASS L1 SP signals, delivering RINEX files (the standard input of geodesic software libraries for high—accuracy positioning) and an on-the-fly navigation solution (that is, computation of position, velocity and time of the user’s receiver).

Given the project complexity and length, the original idea proposed here was divided in two modules:

  1. Implementation of acquisition algorithms for GLONASS, following the examples already implemented for GPS L1 C/A and Galileo E1. This would facilitate research on multi-constellation receivers (e.g., GPS + Galileo + GLONASS) working with real signals.
  2. Demodulation of the GNAV navigation message, opening the door to open innovation in multi-constellation receivers and addressing topics such as integrity, reliability, robustness, enhanced coverage, and high-accuracy positioning. Integration of GLONASS observables into the PVT position.

The work developed during the summer, and described here focuses in point 2 above.


GNSS-SDR provides an interface to different suitable Radio Frequency (RF) front-ends and implements all the receiver chain up to the navigation solution. Its design allows any kind of customization, including interchangeability of signal sources, signal processing algorithms, interoperability with other systems, output formats, and offers interfaces to all the intermediate signals, parameters and variables[1]. Code for the platform is mainly developed in C++ as an open source and uses a considerable part of the GNU Radio framework for all signal processing activities of the receivers. To that goal code is written efficiently to be reusable,easy to read,maintain and modify is required according to the user needs. In that sense, the challenge consists of defining a gentle balance within level of abstraction and performance. GNSS-SDR runs in a personal computer and provides interfaces through Universal Serial Bus (USB) and Ethernet buses to a variety of either commercially available or custom-made RF front-ends, adapting the processing algorithms to different sampling frequencies, intermediate frequencies and sample resolutions. This makes possible rapid prototyping of specific receivers intended, for instance, to geodetic applications, observation of the ionospheric impact on navigation signals, GNSS reflectometry, signal quality monitoring, or carrier-phase based navigation techniques. As an object oriented platform and with the idea of keeping a sense of abstraction in the blocks developed, GNSS-SDR is divided into several main blocks that participate in the whole process of navigation for receivers. These stages, see Figure 1 obtained from [2], called interfaces as part of the abstraction level in the software are divided as follows:

  1. Channel Interface: Encapsulates all signal processing devoted to a single satellite. It is a large composite object which encapsulates the acquisition, tracking and decoding modules.
  2. Acquisition Interface: Detect the presence or absence of in-view satellites. In addition it provides a coarse estimation of two signal parameters: the frequency shift f d with respect to the nominal Intermediate Frequency (IF) frequency, and a delay term which allow determine the shifted version of the local code replica.
  3. Tracking Interface:the parameters estimated for a present satellite by the acquisition module are then fed to the receiver tracking module, which represents the second stage of the signal processing unit, aiming to perform a local search for accurate estimates of code delay and carrier phase, and following their eventual variations
  4. Telemetry Decoder Interface: Detects and decodes the navigation message containing the time the message was transmitted,orbital parameters of satellites (ephemeris) and an almanac.
  5. Observables Interface: Collects all the data provided by every tracked channel, aligns all received data into a coherent set,and computes the observables(pseudorange, carrier phase,etc).
  6. PVT Interface: Computes the position solution of the receiver based on all the data generated by the previous block

GNSS-SDR Architecture

The work described here is only related to the Telemetry Decoding, Observables and PVT interface, and more information on it may be found a the next sections. It is outside the range of this report to explain the rest of the interfaces, however documentation for the platform is excellent, and further details on the rest of the main GNSS related interfaces may be found at [3],[1] and [4].

Description of Work


Code developed during the summer will be integrated into gnss-sdr as a single pull request. For inmediate inspection the reader is refered to the development branch for the project called glonass_dec. This branch is still under heavy development until all task in the to do list presented below is completed. The most significant commits in this project are highlighted below

  1. daba9496a4f : First commit of the project, journey begins 🚀 !
  2. 766accdf422 : Addition of fields of GLONASS GNAV message, ephemeris, almanac and clock information
  3. e0d92e4cb16 : Adding the RINEX parser, critical to share receiver processing results with third party software or equipment
  4. cca6f9aec9d : Adding the RTCM parser to share results
  5. dc16205bda2 : Unit testing correction, huge help here helping discover multiple bugs in code
  6. 841b234b72a : Because one detailed debug session is never enough, this extends the testing period :)
  7. f4c221609c5 : A bit unrelated to GLONASS processing but got the best time learning and doing this

GLONASS Navigation Data

The figure below perfectly illustrates the navigation message structue from GLONASS satellites. The superframe has duration 2.5 minutes and consists of 5 frames. Each frame has duration 30 seconds and consists of 15 strings. Each string has duration 2 seconds. Within each frame a total content of non-immediate data (almanac for 24 GLONASS system satellites) are transmitted The equivalent sequence to the preamble information common in use for GPS and Galileo satellites is called the time code. It is broadcast at the end of each string and is 0.3 s long and consists of 30 bits. This equals a bit rate of 100 bit/s, the same as the meander signal. The time code is a fixed but shortened pseudo-stochastic sequence, consisting of the characters: 111110001101110101000010010110 The first bit of the digital information of each line always is a 0 to complete the shortened sequence of the time code of the previous line. Details of this navigation message can be observed below:

GLONASS Navigation Message Structure

Telemetry Decoder

String Decoding

Once signal is properly tracked, the tracking block will start to populate the required fields in the gnss_syncro object. The symbols populated in the object will then be used to decode the Globalnaya Navigatsionnaya Sputnikovaya Sistema (GLONASS) navigation message, which was described above. Key to a successful decoding of the message is to keep a relation of the bit position for each of the fields to be decoded in the message.

In the implementation of this message, the decoded data was divided in three main objects, named glonass_gnav_ephemeris, glonass_gnav_utc_model and glonass_gnav_almanac. Inmediate information is stored in the glonass_gnav_ephemeris object and it ranges from string 1 to string 4, its fields and bit positions are shown below:

String 5 as shown below contains non inmediate information that is stored in the glonass_gnav_utc_model object. The naming convention of this object followed the previously developed code, however, a careful reader will notice that contents of this string contains more than UTC parameters.

Finally, string 6 and 7 showed below serves as a template since its content is repeated for the rest of the strings when in frames 1 to 4. The contents of these strings are stored in glonass_gnav_almanac objects.

When in frame 5, the contents of string 14 and 15 changes to provide additional information related to clock parameters [9], [10]. This case is illustrated below: Strings 14 and 15 when in frame 5

Ephemeris Implementation

GLONASS intermediate data includes the fields in Table 1 shown below. Note that even though the table provides information on the fields and its description, and all these are relative to the GLONASS ICD specification, however, items in the last column of the table with the Units fields are relative to the GNSS-SDR implementation

Table 1: (i) Ephemeris fields and descriptions

Table 1: (ii) Ephemeris fields and descriptions

Almanac Implementation

The GLONASS GNAV navigation message is deivided in inmediate and non inmediate information. The non inmediate portion of the GLONASS GNAV navigation message contains information regarding satellite almanac and clock correction information. Those parameters selected for almanac information are shown in Table 2.

Table 2: Almanac fields and descriptions

UTC Model Implementation

Following the pattern of developed code for other systems, the GLONASS system implementation also included a UTC model description. The reader is warned that although the object developed contains this name, its true development allows to do more than what the name encompass. In the case of GLONASS, the so called UTC Model object also contains correction information relative to GPS and UT, as such the object is more of a Clock Model. Detailed description of its implementation is provided in the following table

Table 3: UTC Model fields and descriptions

Missing Interfaces

The system parameters inside the GNSS-SDR platform for each signal define a fourth block that for GLONASS processing is missing. Such block is the block containing information about the Ionosphere. Contrary to its counter part systems, such as GPS or Galileo, GLONASS does not provides ionospheric correction information in its navigation message [5] and as such was not included in the GNSS-SDR platform


The current development was done against the next branch in GNSS-SDR, that branch is in the process of swapping the individual observables computation by a more generic module that it is independent of the signal being processed, named Hybrid Observables. As such work in this area was minimalistic and only consisted in making sure that the output from the telemetry decoder interface will meet the requirements of the observables block.

Based on this, the results of the observables block are shown below Accumulated Carrier Phase

Doppler Frequency


PVT Solution

The PVT solution in GNSS-SDR currently uses a module created based on the RTKLib library. As such, the GLONASS integration to this module was only in charge of providing the necessary conversion tools to translate from the GNSS-SDR modules to the RTKLib input. All conversion parameters were developed following the description of the RTKLib API library described in [6].

Initial results in this stage show the position solution when only using GLONASS L1 C/A signal, see below:

Current receiver time: 41 [s]
Position at 2016-Sep-23 20:06:16.435684 UTC using 5 observations is Lat = 40.0081 [deg], Long = -105.263 [deg], Height= 1745.96 [m]
Position at 2016-Sep-23 20:06:16.940684 UTC using 5 observations is Lat = 40.0082 [deg], Long = -105.263 [deg], Height= 1738.95 [m]
Current receiver time: 42 [s]
Position at 2016-Sep-23 20:06:17.445683 UTC using 5 observations is Lat = 40.0081 [deg], Long = -105.263 [deg], Height= 1729.1 [m]
Position at 2016-Sep-23 20:06:17.950683 UTC using 5 observations is Lat = 40.0081 [deg], Long = -105.263 [deg], Height= 1775.12 [m]
Current receiver time: 43 [s]
Position at 2016-Sep-23 20:06:18.455682 UTC using 5 observations is Lat = 40.0081 [deg], Long = -105.263 [deg], Height= 1713.96 [m]
Position at 2016-Sep-23 20:06:18.960682 UTC using 5 observations is Lat = 40.0081 [deg], Long = -105.263 [deg], Height= 1742.59 [m]
Current receiver time: 44 [s]
Position at 2016-Sep-23 20:06:19.465681 UTC using 5 observations is Lat = 40.008 [deg], Long = -105.263 [deg], Height= 1685.46 [m]
Position at 2016-Sep-23 20:06:19.970681 UTC using 5 observations is Lat = 40.0081 [deg], Long = -105.263 [deg], Height= 1683.35 [m]
Current receiver time: 45 [s]
Position at 2016-Sep-23 20:06:20.475680 UTC using 5 observations is Lat = 40.0081 [deg], Long = -105.263 [deg], Height= 1637.67 [m]
Position at 2016-Sep-23 20:06:20.980680 UTC using 5 observations is Lat = 40.0081 [deg], Long = -105.263 [deg], Height= 1765.84 [m]
Current receiver time: 46 [s]
Position at 2016-Sep-23 20:06:21.485679 UTC using 5 observations is Lat = 40.008 [deg], Long = -105.263 [deg], Height= 1698.75 [m]

GPS + GLONASS Position Fix

First GLONASS Position Fix

RTKLib Interface

The most significant portion of code to interact with the RTKLib API relates to the RTKLib version of the GLONASS ephemeris information. This ephemeris structure does not follows the conventional eph_t type that is shared between GPS and Galileo system because ephemeris for GLONASS system are different in nature to those specified for the aforemnetioned constellations. As such RTKLib defines a new type for such cases named geph_t and defined as follows:

typedef struct {        /* GLONASS broadcast ephemeris type */
    int sat;            /* satellite number */
    int iode;           /* IODE (0-6 bit of tb field) */
    int frq;            /* satellite frequency number */
    int svh,sva,age;    /* satellite health, accuracy, age of operation */
    gtime_t toe;        /* epoch of epherides (gpst) */
    gtime_t tof;        /* message frame time (gpst) */
    double pos[3];      /* satellite position (ecef) (m) */
    double vel[3];      /* satellite velocity (ecef) (m/s) */
    double acc[3];      /* satellite acceleration (ecef) (m/s^2) */
    double taun,gamn;   /* SV clock bias (s)/relative freq bias */
    double dtaun;       /* delay between L1 and L2 (s) */
} geph_t;

In order to be able to interact with the RTKLib, the glonass_gnav_eph, as defined above is converted to the RTKLib type following this convention:

geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris & glonass_gnav_eph)
    geph_t rtklib_sat = {0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0.0, 0.0, 0.0}, {0.0, 0.0,
        0.0}, {0.0, 0.0, 0.0}, 0.0, 0.0, 0.0};
    gtime_t t_utc;
    struct tm utcinfo;

    rtklib_sat.sat    = glonass_gnav_eph.i_satellite_slot_number;       /* satellite number */
    rtklib_sat.iode   = glonass_gnav_eph.d_t_b;                         /* IODE (0-6 bit of tb field) */
    rtklib_sat.frq    = glonass_gnav_eph.i_satellite_freq_channel;      /* satellite frequency number */
    rtklib_sat.svh    = glonass_gnav_eph.d_l3rd_n;                      /* satellite health*/
    rtklib_sat.sva    = glonass_gnav_eph.d_F_T;                         /* satellite accuracy*/
    rtklib_sat.age    = glonass_gnav_eph.d_E_n;                         /* satellite age*/
    rtklib_sat.pos[0] = glonass_gnav_eph.d_Xn*1000;                     /* satellite position (ecef) (m) */
    rtklib_sat.pos[1] = glonass_gnav_eph.d_Yn*1000;                     /* satellite position (ecef) (m) */
    rtklib_sat.pos[2] = glonass_gnav_eph.d_Zn*1000;                     /* satellite position (ecef) (m) */
    rtklib_sat.vel[0] = glonass_gnav_eph.d_VXn*1000;                    /* satellite velocity (ecef) (m/s) */
    rtklib_sat.vel[1] = glonass_gnav_eph.d_VYn*1000;                    /* satellite velocity (ecef) (m/s) */
    rtklib_sat.vel[2] = glonass_gnav_eph.d_VZn*1000;                    /* satellite velocity (ecef) (m/s) */
    rtklib_sat.acc[0] = glonass_gnav_eph.d_AXn*1000;                    /* satellite acceleration (ecef) (m/s^2) */
    rtklib_sat.acc[1] = glonass_gnav_eph.d_AYn*1000;                    /* satellite acceleration (ecef) (m/s^2) */
    rtklib_sat.acc[2] = glonass_gnav_eph.d_AZn*1000;                    /* satellite acceleration (ecef) (m/s^2) */
    rtklib_sat.taun   = glonass_gnav_eph.d_tau_n;                       /* SV clock bias (s) */
    rtklib_sat.gamn   = glonass_gnav_eph.d_gamma_n;                     /* SV relative freq bias */
    rtklib_sat.age    = glonass_gnav_eph.d_Delta_tau_n;                 /* delay between L1 and L2 (s) */

    utcinfo.tm_mon  = 0;
    utcinfo.tm_mday = glonass_gnav_eph.d_D4Y;
    utcinfo.tm_year = glonass_gnav_eph.d_yr - 1900;
    utcinfo.tm_hour = 0;
    utcinfo.tm_min  = 0;
    utcinfo.tm_sec  = glonass_gnav_eph.d_t_b;
    t_utc.time = mktime(&utcinfo);
    t_utc.sec = 0.0;
    rtklib_sat.toe    = utc2gpst(t_utc);      /* epoch of epherides (gpst) */

    utcinfo.tm_mon  = 0;
    utcinfo.tm_mday = glonass_gnav_eph.d_D4Y;
    utcinfo.tm_year = glonass_gnav_eph.d_yr - 1900;
    utcinfo.tm_hour = 0;
    utcinfo.tm_min  = 0;
    utcinfo.tm_sec  = glonass_gnav_eph.d_t_k;
    t_utc.time = mktime(&utcinfo);
    t_utc.sec = 0.0;
    rtklib_sat.tof    = utc2gpst(t_utc);      /* message frame time (gpst) */

    return rtklib_sat;

RINEX Message Generation

This work also adds GLONASS support to the existent RINEX [7] functionality of GNSS-SDR. The support to this type of message was added in such a way that when in the future GLONASS L2 C/A is added, the existent code will be able to handle the new addition seamlessly. Because RINEX files, either observations or navigation type are dependent on the receive signal type, this works also provides support to cases where GLONASS is combined with other constellations or signals. The set of available combinations or receiver types as defined by GNSS-SDR are:

Type Receiver
27 Galileo E1B + GLONASS L1 C/A

RTCM DGNSS Message Generation

This work also adds GLONASS support to the RTCM DGNSS standard. The support to this type of message was added in such a way that when in the future GLONASS L2 C/A is added, the existent code will be able to handle the new addition seamlessly. Support for RCTM DGNSS can be enclosed in the following additions:

  1. intSnn Data Type: Adds code to parse intSnn data types as defined by [8]. This data type were required since GLONASS encodes signed value with a notation where the MSB works as the sign of the number, while the magnitude is stored in the remaining bits
  2. GLONASS Data Fields: Adds new data fields to process GLONASS GNAV data. Data fields in the block range from DF038 to DF050 and DF104 to DF136.
  3. Legacy messages: Adds support to legacy messages MT1009 to MT1012. Note that in its latest format this type of message has been replaced by the generic MSM message style format.
  4. Ephemeris Messages: Adds support to MT1020, which transmit GLONASS GNAV ephemeris.
  5. MSM Messages: Modifies code structure to add a new message type , the MSM range (1 - 7) and provides support with MT1087.

Results and Future work

The code is in its final stages and only needs now to integrate the work developed by @Gastd. Upon integration, a period of testing will be initiated to check the correct functionality of the receiver. These steps, are under development at the moment of this writing, however it was important to highlight the milestone of the project achieved during the summer thanks to the sponsorship of the GSoC 2017 program.

To Do

  • Integrate work developed for the acquisition and tracking modules, developed by @Gastd with efforts of hereby documented
  • Test the code extensively, in a real processing scenario and from collection stored in file
  • Test output of RINEX generated messages with third-party software
  • Test output of RTCM generated messages with third-party software


This was an incredible experience for a summer project, and even though this is not my first time contributing to an open source project, it was the first time that I felt confortable with the process. I gained considerable more experience working with the git and the workflow used for GitHub and its open source groups. I also become a more experience developer with the GNSS-SDR platform, and I plan to put this experience to value by continue my work fro open source projects, specifically for GNSS-SDR. All this was achieved thanks to the GSoC 2017 program, thanks Google for making this happen and your commitment with open source development :bowtie:


[1] C. Fernández–Prades, C. Avilés, L. Esteve, J. Arribas, and P. Closas, “Design patterns for GNSS software receivers,” in Proc. of the 5th ESA Workshop on Satellite Navigation Technologies (NAVITEC’2010), (ESTEC, Noordwijk, The Netherlands), Dec. 2010. DOI:10.1109/NAVITEC.2010.5707981.

[2] C. Fernández–Prades, J. Arribas, P. Closas, C. Avilés, and L. Esteve, “GNSS-SDR: An open source tool for researchers and developers,” in Proc. of the ION GNSS 2011 Conference, (Portland, Oregon),Sept. 2011.

[3] J. Arribas, GNSS Array-based Acquisition: Theory and Implementation. PhD thesis, Universitat Politècnica de Catalunya, Barcelona, Spain, June 2012.

[4] L. Esteve Elfau, “Contribucion al Diseno de GNSS-SDR.Un Receptor GNSS de Codigo Abierto,” Proyecto final de carrera, Universitat Politecnica de Catalunya, Julio 2013.

[5] u-blox AG, “GLONASS & GPS HW designs Recommendations with u-blox 6 GPS receivers. Application Note,” tech. rep., u-blox AG, Thalwil.

[6] T. Takasu and A. Yasuda, “RTKLIB ver. 2.4.2 Manual,” no. C, p. 181, 2013.

[7] International GNSS Service and RINEX Working Group and Radio Techincal Commission for Maritime Services Special Committee, “RINEX The Receiver Independant Exchange Format,” 2013.

[8] RTCM Special Committee No. 104, “RTCM Standard 10403.2 Differential GNSS ( GLOBAL NAVIGATION SATELLITE SYSTEMS ),” 2013.

[9] Russian Institute of Space Device Engineering, “Global Navigation Satellite System GLONASS Interface Control Document, Navigational radiosignal in bands L1, L2,” Moscow, Edition 5.1, 2008.

[10] U. Roßbach, “Positioning and navigation using the Russian satellite system GLONASS,” p. 167, 2000.


This comment has been minimized.

Copy link
Owner Author

dmiralles2009 commented Dec 20, 2017

Updating gist to reflect position fix results for GLONASS L1 C/A

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.