diff --git a/src/core/system_parameters/GLONASS_L1_CA.h b/src/core/system_parameters/GLONASS_L1_CA.h
new file mode 100644
index 000000000..d3c234801
--- /dev/null
+++ b/src/core/system_parameters/GLONASS_L1_CA.h
@@ -0,0 +1,176 @@
+/*!
+ * \file GLONASS_L1_CA.h
+ * \brief Defines system parameters for GLONASS L1 C/A signal and NAV data
+ * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+
+#ifndef GNSS_SDR_GLONASS_L1_CA_H_
+#define GNSS_SDR_GLONASS_L1_CA_H_
+
+#include
+#include // std::pair
+#include "MATH_CONSTANTS.h"
+#include "gnss_frequencies.h"
+
+// Physical constants
+const double GLONASS_C_m_s = SPEED_OF_LIGHT; //!< The speed of light, [m/s]
+const double GLONASS_C_m_ms = 299792.4580; //!< The speed of light, [m/ms]
+const double GLONASS_PI = 3.1415926535898; //!< Pi as defined in IS-GPS-200E
+const double GLONASS_TWO_PI = 6.283185307179586; //!< 2Pi as defined in IS-GPS-200E
+const double GLONASS_OMEGA_EARTH_DOT = 7.292115e-5; //!< Earth rotation rate, [rad/s]
+const double GLONASS_GM = 398600.4418e9; //!< Universal gravitational constant times the mass of the Earth, [km^3/s^2]
+const double GLONASS_fM_a = 0.35e9; //!< Gravitational constant of atmosphere [m^3/s^2]
+const double GLONASS_SEMI_MAJOR_AXIS = 6378136; //!< Semi-major axis of Earth [m]
+const double GLONASS_FLATTENING = 1/29825784; //!< Flattening parameter
+const double GLONASS_GRAVITY = 97803284; //!< Equatorial acceleration of gravity [mGal]
+const double GLONASS_GRAVITY_CORRECTION = 0.87; //!< Correction to acceleration of gravity at sea-level due to Atmosphere[мGal]
+const double GLONASS_J2 = 1082625.75e-9; //!< Second zonal harmonic of the geopotential
+const double GLONASS_J4 = -2370.89e-9; //!> STRING_ID({{2,4}});
+const std::vector> KX({{78,8}});
+//STRING 1
+const std::vector> P1({{8,2}});
+const std::vector> T_K({{10,12}});
+const std::vector> X_N_DOT ({{22,24}});
+const std::vector> X_N_DOT_DOT ({{46,5}});
+const std::vector> X_N({{51,27}});
+
+//STRING 2
+const std::vector> B_N({{6,3}});
+const std::vector> P2({{9,1}});
+const std::vector> T_B({{10,7}});
+const std::vector> Y_N_DOT ({{22,24}});
+const std::vector> Y_N_DOT_DOT ({{46,5}});
+const std::vector> Y_N({{51,27}});
+
+//STRING 3
+const std::vector> P3({{6,1}});
+const std::vector> GAMMA_N({{7,11}});
+const std::vector> P({{19,2}});
+const std::vector> L_N({{21,1}});
+const std::vector> Z_N_DOT ({{22,24}});
+const std::vector> Z_N_DOT_DOT ({{46,5}});
+const std::vector> Z_N({{51,27}});
+
+// STRING 4
+const std::vector> TAU_N({{6,22}});
+const std::vector> DELTA_TAU_N({{28,5}});
+const std::vector> E_N({{33,5}});
+const std::vector> P4 ({{52,1}});
+const std::vector> F_T ({{53,4}});
+const std::vector> N_T({{60,11}});
+const std::vector> N({{71,5}});
+const std::vector> M({{76,2}});
+
+// STRING 5
+const std::vector> N_A({{6,11}});
+const std::vector> TAU_C({{17,32}});
+const std::vector> N_4({{50,5}});
+const std::vector> TAU_GPS({{55,22}});
+const std::vector> L_N({{77,1}});
+
+// STRING 6, 8, 10, 12, 14
+const std::vector> C_N({{6,1}});
+const std::vector> M_N_A({{7,2}});
+const std::vector> n_A({{9,5}});
+const std::vector> TAU_N_A({{14,10}});
+const std::vector> LAMBDA_N_A({{24,21}});
+const std::vector> DELTA_I_N_A({{45,18}});
+const std::vector> EPSILON_N_A({{63,15}});
+
+//STRING 7, 9, 11, 13, 15
+const std::vector> OMEGA_N_A({{6,16}});
+const std::vector> T_LAMBDA_N_A({{22,21}});
+const std::vector> DELTA_T_N_A({{43,22}});
+const std::vector> DELTA_T_DOT_N_A({{65,7}});
+const std::vector> H_N_A({{72,5}});
+const std::vector> L_N({{77,1}});
+
+
+#endif /* GNSS_SDR_GLONASS_L1_CA_H_ */
diff --git a/src/core/system_parameters/glonass_gnav_almanac.cc b/src/core/system_parameters/glonass_gnav_almanac.cc
new file mode 100644
index 000000000..45174cabb
--- /dev/null
+++ b/src/core/system_parameters/glonass_gnav_almanac.cc
@@ -0,0 +1,57 @@
+/*!
+ * \file glonass_gnav_almanac.cc
+ * \brief Interface of a GLONASS GNAV ALMANAC storage
+ *
+ * See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
+ * \author Damian Miralles , 2017. dmiralles2009(at)gmail.com
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#include "glonass_gnav_almanac.h"
+
+Glonass_Gnav_Almanac::Glonass_Gnav_Almanac()
+{
+ int i_satellite_freq_channel = 0;
+ double d_tau_c = 0.0;
+ double d_tau_gps = 0.0;
+ double d_N_4 = 0.0;
+ double d_N_A = 0.0;
+ double d_n_A = 0.0;
+ double d_H_n_A = 0.0;
+ double d_lambda_n_A = 0.0;
+ double d_t_lambda_n_A = 0.0;
+ double d_Delta_i_n_A = 0.0;
+ double d_Delta_T_n_A = 0.0;
+ double d_Delta_T_n_A_dot = 0.0;
+ double d_epsilon_n_A = 0.0;
+ double d_omega_n_A = 0.0;
+ double d_M_n_A = 0.0;
+ double d_B1 = 0.0;
+ double d_B2 = 0.0;
+ double d_KP = 0.0;
+ double d_tau_n_A = 0.0;
+ double d_C_n_A = 0.0;
+}
diff --git a/src/core/system_parameters/glonass_gnav_almanac.h b/src/core/system_parameters/glonass_gnav_almanac.h
new file mode 100644
index 000000000..3e13802fc
--- /dev/null
+++ b/src/core/system_parameters/glonass_gnav_almanac.h
@@ -0,0 +1,70 @@
+/*!
+ * \file glonass_gnav_almanac.h
+ * \brief Interface of a GLONASS GNAV ALMANAC storage
+ * \author Damian Miralles, 2017. dmiralles2009@gmail.com
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+
+#ifndef GNSS_SDR_GLONASS_ALMANAC_H_
+#define GNSS_SDR_GLONASS_ALMANAC_H_
+
+
+/*!
+ * \brief This class is a storage for the GLONASS SV ALMANAC data as described in IS-GPS-200E
+ * \todo Add proper links for GLONASS ICD
+ * See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
+ */
+class Glonass_Gnav_Almanac
+{
+public:
+ int i_satellite_freq_channel; //!< SV PRN NUMBER
+ double d_tau_c; //!< GLONASS time scale correction to UTC(SU) time. [s]
+ double d_tau_gps; //!< Correction to GPS time to GLONASS time [day]
+ double d_N_4; //!< Four year interval number starting from 1996 [4 year interval]
+ double d_N_A; //!< Calendar day number within the four-year period beginning since the leap year [days]
+ double d_n_A; //!< Conventional number of satellite within GLONASS space segment [dimensionless]
+ double d_H_n_A; //!< Carrier frequency number of navigation RF signal transmitted by d_nA satellite [dimensionless]
+ double d_lambda_n_A; //!< Longitude of the first (within the d_NA day) ascending node of d_nA [semi-circles]
+ double d_t_lambda_n_A; //!< Time of first ascending node passage [s]
+ double d_Delta_i_n_A //!< Correction of the mean value of inclination of d_n_A satellite at instant t_lambda_n_A [semi-circles]
+ double d_Delta_T_n_A; //!< Correction to the mean value of Draconian period of d_n_A satellite at instant t_lambda_n_A[s / orbital period]
+ double d_Delta_T_n_A_dot; //!< Rate of change of Draconian period of d_n_A satellite at instant t_lambda_n_A [s / orbital period^2]
+ double d_epsilon_n_A; //!< Eccentricity of d_n_A satellite at instant t_lambda_n_A [dimensionless]
+ double d_omega_n_A; //!< Argument of preigree of d_n_A satellite at instant t_lambdan_A [semi-circles]
+ double d_M_n_A; //!< Type of satellite n_A [dimensionless]
+ double d_B1; //!< Coefficient to determine DeltaUT1 [s]
+ double d_B2; //!< Coefficient to determine DeltaUT1 [s/msd]
+ double d_KP; //!< Notification on forthcoming leap second correction of UTC [dimensionless]
+ double d_tau_n_A; //!< Coarse value of d_n_A satellite time correction to GLONASS time at instant t_lambdan_A[s]
+ double d_C_n_A; //!< Generalized “unhealthy flag” of n_A satellite at instant of almanac upload [dimensionless]
+ /*!
+ * Default constructor
+ */
+ Glonass_Gnav_Almanac();
+};
+
+#endif
diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.cc b/src/core/system_parameters/glonass_gnav_ephemeris.cc
new file mode 100644
index 000000000..a6e6436c2
--- /dev/null
+++ b/src/core/system_parameters/glonass_gnav_ephemeris.cc
@@ -0,0 +1,600 @@
+/*!
+ * \file gps_ephemeris.cc
+ * \brief Interface of a GPS EPHEMERIS storage and orbital model functions
+ *
+ * See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
+ * \author Javier Arribas, 2013. jarribas(at)cttc.es
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#include "gps_ephemeris.h"
+#include
+#include "GLONASS_L1_CA.h"
+#include "gnss_satellite.h"
+
+Gps_Ephemeris::Gps_Ephemeris()
+{
+ i_satellite_freq_channel = 0;
+ d_m = 0.0; //!< String number within frame [dimensionless]
+ d_t_k = 0.0; //!< Time referenced to the beginning of the frame within the current day [hours, minutes, seconds]
+ d_t_b = 0.0; //!< Index of a time interval within current day according to UTC(SU) + 03 hours 00 min. [minutes]
+ d_M = 0.0; //!< Type of satellite transmitting navigation signal [dimensionless]
+ d_gamma_n = 0.0; //!< Relative deviation of predicted carrier frequency value of n- satellite from nominal value at the instant tb [dimensionless]
+ d_tau_n = 0.0; //!< Correction to the nth satellite time (tn) relative to GLONASS time (te),
+ // satellite positions
+ d_satpos_X = 0.0; //!< Earth-fixed coordinate x of the satellite in PZ-90.02 coordinate system [km].
+ d_satpos_Y = 0.0; //!< Earth-fixed coordinate y of the satellite in PZ-90.02 coordinate system [km]
+ d_satpos_Z = 0.0; //!< Earth-fixed coordinate z of the satellite in PZ-90.02 coordinate system [km]
+ // Satellite velocity
+ d_satvel_X = 0.0; //!< Earth-fixed velocity coordinate x of the satellite in PZ-90.02 coordinate system [km/s]
+ d_satvel_Y = 0.0; //!< Earth-fixed velocity coordinate y of the satellite in PZ-90.02 coordinate system [km/s]
+ d_satvel_Z = 0.0; //!< Earth-fixed velocity coordinate z of the satellite in PZ-90.02 coordinate system [km/s]
+ // Satellite acceleration
+ d_satacc_X = 0.0; //!< Earth-fixed acceleration coordinate x of the satellite in PZ-90.02 coordinate system [km/s^2]
+ d_satacc_Y = 0.0; //!< Earth-fixed acceleration coordinate y of the satellite in PZ-90.02 coordinate system [km/s^2]
+ d_satacc_Z = 0.0; //!< Earth-fixed acceleration coordinate z of the satellite in PZ-90.02 coordinate system [km/s^2]
+ d_B_n = 0.0; //!< Health flag [dimensionless]
+ d_P = 0.0; //!< Technological parameter of control segment, indication the satellite operation mode in respect of time parameters [dimensionless]
+ d_N_T = 0.0; //!< Current date, calendar number of day within four-year interval starting from the 1-st of January in a leap year [days]
+ d_F_T = 0.0; //!< Parameter that provides the predicted satellite user range accuracy at time tb [dimensionless]
+ d_n = 0.0; //!< Index of the satellite transmitting given navigation signal. It corresponds to a slot number within GLONASS constellation
+ d_Delta_tau_n = 0.0; //!< Time difference between navigation RF signal transmitted in L2 sub- band and aviation RF signal transmitted in L1 sub-band by nth satellite. [dimensionless]
+ d_E_n = 0.0; //!< Characterises "age" of a current information [days]
+ d_P_1 = 0.0; //!< Flag of the immediate data updating.
+ d_P_2 = 0.0; //!< Flag of oddness ("1") or evenness ("0") of the value of (tb) [dimensionless]
+ d_P_3 = 0.0; //!< Flag indicating a number of satellites for which almanac is transmitted within given frame: "1" corresponds to 5 satellites and "0" corresponds to 4 satellites [dimensionless]
+ d_P_4 = 0.0; //!< Flag to show that ephemeris parameters are present. "1" indicates that updated ephemeris or frequency/time parameters have been uploaded by the control segment [dimensionless]
+ d_l_n = 0.0; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless]
+
+ // clock terms derived from ephemeris data
+ d_satClkDrift = 0.0; //!< GLONASS clock error
+ d_dtr = 0.0;
+}
+
+
+void Glonass_GNAV_Ephemeris::gravitational_perturbations()
+{
+ double T;
+ double sigma_days;
+ double tau_prime;
+ double Omega_moon;
+ double q_moon;
+ double q_sun;
+ double Tau_11; double Tau_12;
+ double Eta_11; double Eta_12;
+ double xi_11; double xi_12;
+ double xi_star;
+ double eta_star;
+ double zeta_star;
+ double E_moon;
+ double E_sun;
+ double xi_11;
+ double xi_12;
+ double eta_11;
+ double eta_12;
+ double zeta_11;
+ double zeta_12;
+
+ double sin_theta_moon;
+ double cos_theta_moon;
+ double theta_moon;
+ double xi_moon_e;
+ double eta_moon_e;
+ double zeta_moon_e;
+
+ double sin_theta_sun;
+ double cos_theta_sun;
+ double theta_sun;
+ double xi_sun_e;
+ double eta_sun_e;
+ double zeta_sun_e;
+
+ double r_moon_e;
+ double mu_bar_moon;
+ double x_bar_moon;
+ double y_bar_moon;
+ double Delta_o_moon;
+ double mu_bar_sun;
+ double x_bar_sun;
+ double y_bar_sun;
+ double Delta_o_sun;
+
+
+ // half_day)
+ {
+ corrTime = time - 2.0 * half_day;
+ }
+ else if (time < -half_day)
+ {
+ corrTime = time + 2.0 * half_day;
+ }
+ return corrTime;
+}
+
+
+// 20.3.3.3.3.1 User Algorithm for SV Clock Correction.
+double Glonass_GNAV_Ephemeris::sv_clock_drift(double transmitTime, double timeCorrUTC)
+{
+ double dt;
+ dt = check_t(transmitTime - d_t_b);
+ d_satClkDrift = -(d_tau_n + timeCorrUTC - d_gamma_n * dt);
+ //Correct satellite group delay and missing relativistic term here
+ //d_satClkDrift-=d_TGD;
+
+ return d_satClkDrift;
+}
+
+
+// compute the relativistic correction term
+double Glonass_GNAV_Ephemeris::sv_clock_relativistic_term(double transmitTime)
+{
+ double tk;
+ double a;
+ double n;
+ double n0;
+ double E;
+ double E_old;
+ double dE;
+ double M;
+
+ // Restore semi-major axis
+ a = d_sqrt_A * d_sqrt_A;
+
+ // Time from ephemeris reference epoch
+ tk = check_t(transmitTime - d_Toe);
+
+ // Computed mean motion
+ n0 = sqrt(GM / (a * a * a));
+ // Corrected mean motion
+ n = n0 + d_Delta_n;
+ // Mean anomaly
+ M = d_M_0 + n * tk;
+
+ // Reduce mean anomaly to between 0 and 2pi
+ //M = fmod((M + 2.0 * GPS_PI), (2.0 * GPS_PI));
+
+ // Initial guess of eccentric anomaly
+ E = M;
+
+ // --- Iteratively compute eccentric anomaly ----------------------------
+ for (int ii = 1; ii < 20; ii++)
+ {
+ E_old = E;
+ E = M + d_e_eccentricity * sin(E);
+ dE = fmod(E - E_old, 2.0 * GPS_PI);
+ if (fabs(dE) < 1e-12)
+ {
+ //Necessary precision is reached, exit from the loop
+ break;
+ }
+ }
+
+ // Compute relativistic correction term
+ d_dtr = F * d_e_eccentricity * d_sqrt_A * sin(E);
+ return d_dtr;
+}
+
+
+double Glonass_GNAV_Ephemeris::simplifiedSatellitePosition(double transmitTime)
+{
+ double dt = 0.0;
+ double tk = 0.0;
+ int numberOfIntegrations = 0;
+
+ // Find time difference
+ dt = check_t(transmitTime - d_t_b);
+
+ // Calculate clock correction
+ satClkCorr = -(d_tau_n + d_tau_c - d_gamma_n * dt);
+
+ // Find integration time
+ tk = dt - satClkCorr;
+
+ // Check if to integrate forward or backward
+ if tk < 0
+ tau = -60;
+ else
+ tau = 60;
+ end
+
+ // x,y,z coordinates to meters
+ x0 = d_satpos_X * 1e3;
+ y0 = d_satpos_Y * 1e3;
+ z0 = d_satpos_Z * 1e3;
+
+ // x,y,z velocities to meters/s
+ Vx0 = d_satvel_X * 1e3;
+ Vy0 = d_satvel_Y * 1e3;
+ Vz0 = d_satvel_Z * 1e3;
+
+ // x,y,z accelerations to meters/sec^2
+ Ax0 = d_satacc_X * 1e3;
+ Ay0 = d_satacc_Y * 1e3;
+ Az0 = d_satacc_Z * 1e3;
+
+ for(numberOfIntegrations = tau; numberOfIntegrations < tk+tau; numberOfIntegrations += tau)
+ {
+ // Check if last integration step. If last integration step, make one more step that has the remaining time length...
+ if(fabs(numberOfIntegrations) > fabs(tk))
+ {
+ // if there is more time left to integrate...
+ if mod(tk,tau) ~= 0
+ {
+ tau = mod(time,tau);
+ }
+ else // otherwise make a zero step.
+ {
+ tau = 0;
+ }
+ }
+
+ // Runge-Kutta Integration Stage K1
+ r0 = sqrt(x0*x0 + y0*y0 + z0*z0);
+ r0_2 = r0*r0;
+ r0_3 = r0*r0*r0;
+ r0_5 = r0*r0*r0*r0*r0;
+
+ dVx_1 = - GLONASS_GM / r0_3 * x0 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a * GLONASS_a) / r0_5 * x0 * (1 - 5 * (z0*z0) / r0_2) + (GLONASS_OMEGA_EARTH_DOT*GLONASS_OMEGA_EARTH_DOT) * x0 + 2 * GLONASS_OMEGA_EARTH_DOT * Vy0 + Ax0;
+ dVy_1 = - GLONASS_GM / r0_3 * y0 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a * GLONASS_a) / r0_5 * y0 * (1 - 5 * (z0*z0) / r0_2) + (GLONASS_OMEGA_EARTH_DOT*GLONASS_OMEGA_EARTH_DOT) * y0 - 2 * GLONASS_OMEGA_EARTH_DOT * Vx0 + Ay0;
+ dVz_1 = - GLONASS_GM / r0_3 * z0 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a * GLONASS_a) / r0_5 * z0 * (3 - 5 * (z0*z0) / r0_2) + Az0;
+
+ dx_1 = Vx0;
+ dy_1 = Vy0;
+ dz_1 = Vz0;
+
+ // Runge-Kutta Integration Stage K2
+ Vx_1 = Vx0 + 1/2 * tau * dVx_1;
+ Vy_1 = Vy0 + 1/2 * tau * dVy_1;
+ Vz_1 = Vz0 + 1/2 * tau * dVz_1;
+
+ x_1 = x0 + 1/2 * tau * dx_1;
+ y_1 = y0 + 1/2 * tau * dy_1;
+ z_1 = z0 + 1/2 * tau * dz_1;
+
+ r1 = sqrt( x_1*x_1 + y_1*y_1 + z_1*z_1 );
+ r1_2 = r1*r1;
+ r1_3 = r1*r1*r1;
+ r1_5 = r1*r1*r1*r1*r1;
+
+ dVx_2 = - GLONASS_GM / r1_3 * x_1 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r1_5 * x_1 * (1 - 5 * (z_1*z_1) / r1_2) + (GLONASS_OMEGA_EARTH_DOT * GLONASS_OMEGA_EARTH_DOT) * x_1 + 2 * GLONASS_OMEGA_EARTH_DOT * Vy_1 + Ax0;
+ dVy_2 = - GLONASS_GM / r1_3 * y_1 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r1_5 * y_1 * (1 - 5 * (z_1*z_1) / r1_2) + (GLONASS_OMEGA_EARTH_DOT * GLONASS_OMEGA_EARTH_DOT) * y_1 - 2 * GLONASS_OMEGA_EARTH_DOT * Vx_1 + Ay0;
+ dVz_2 = - GLONASS_GM / r1_3 * z_1 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r1_5 * z_1 * (3 - 5 * (z_1*z_1) / r1_2) + Az0;
+
+ dx_2 = Vx_1;
+ dy_2 = Vy_1;
+ dz_2 = Vz_1;
+
+ // Runge-Kutta Integration Stage K2
+ Vx_2 = Vx0 + 1/2 * tau * dVx_2;
+ Vy_2 = Vy0 + 1/2 * tau * dVy_2;
+ Vz_2 = Vz0 + 1/2 * tau * dVz_2;
+
+ x_2 = x0 + 1/2 * tau * dx_2;
+ y_2 = y0 + 1/2 * tau * dy_2;
+ z_2 = z0 + 1/2 * tau * dz_2;
+
+ r2 = sqrt( x_2*x_2 + y_2*y_2 + z_2*z_2 );
+ r2_2 = r2*r2;
+ r2_3 = r2*r2*r2;
+ r2_5 = r2*r2*r2*r2*r2;
+
+
+ dVx_3 = - GLONASS_GM / r2_3 * x_2 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r2_5 * x_2 * (1 - 5 * (z_2*z_2) / r2_2) + (GLONASS_OMEGA_EARTH_DOT * GLONASS_OMEGA_EARTH_DOT) * x_2 + 2 * GLONASS_OMEGA_EARTH_DOT * Vy_2 + Ax0;
+ dVy_3 = - GLONASS_GM / r2_3 * y_2 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r2_5 * y_2 * (1 - 5 * (z_2*z_2) / r2_2) + (GLONASS_OMEGA_EARTH_DOT * GLONASS_OMEGA_EARTH_DOT) * y_2 - 2 * GLONASS_OMEGA_EARTH_DOT * Vx_2 + Ay0;
+ dVz_3 = - GLONASS_GM / r2_3 * z_2 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r2_5 * z_2 * (3 - 5 * (z_2*z_2) / r2_2) + Az0;
+
+ dx_3 = Vx_2;
+ dy_3 = Vy_2;
+ dz_3 = Vz_2;
+
+ // Runge-Kutta Integration Stage K3
+ Vx_3 = Vx0 + tau * dVx_3;
+ Vy_3 = Vy0 + tau * dVy_3;
+ Vz_3 = Vz0 + tau * dVz_3;
+
+ x_3 = x0 + tau * dx_3;
+ y_3 = y0 + tau * dy_3;
+ z_3 = z0 + tau * dz_3;
+
+ r3 = sqrt( x_3*x_3 + y_3*y_3 + z_3*z_3 );
+ r3_2 = r3*r3;
+ r3_3 = r3*r3*r3;
+ r3_5 = r3*r3*r3*r3*r3;
+
+ dVx_4 = - GLONASS_GM / r3_3 * x_3 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r3_5 * x_3 * (1 - 5 * (z_3*z_3) / r3_2) + (GLONASS_OMEGA_EARTH_DOT * GLONASS_OMEGA_EARTH_DOT) * x_3 + 2 * GLONASS_OMEGA_EARTH_DOT * Vy_3 + Ax0;
+ dVy_4 = - GLONASS_GM / r3_3 * y_3 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r3_5 * y_3 * (1 - 5 * (z_3*z_3) / r3_2) + (GLONASS_OMEGA_EARTH_DOT * GLONASS_OMEGA_EARTH_DOT) * y_3 - 2 * GLONASS_OMEGA_EARTH_DOT * Vx_3 + Ay0;
+ dVz_4 = - GLONASS_GM / r3_3 * z_3 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r3_5 * z_3 * (3 - 5 * (z_3*z_3) / r3_2) + Az0;
+
+ dx_4 = Vx_3;
+ dy_4 = Vy_3;
+ dz_4 = Vz_3;
+
+ // Final results showcased here
+ Vx0 = Vx0 + 1/6 * tau * ( dVx_1 + 2 * dVx_2 + 2 * dVx_3 + dVx_4 );
+ Vy0 = Vy0 + 1/6 * tau * ( dVy_1 + 2 * dVy_2 + 2 * dVy_3 + dVy_4 );
+ Vz0 = Vz0 + 1/6 * tau * ( dVz_1 + 2 * dVz_2 + 2 * dVz_3 + dVz_4 );
+
+ x0 = x0 + 1/6 * tau * ( dx_1 + 2 * dx_2 + 2 * dx_3 + dx_4 );
+ y0 = y0 + 1/6 * tau * ( dy_1 + 2 * dy_2 + 2 * dy_3 + dy_4 );
+ z0 = z0 + 1/6 * tau * ( dz_1 + 2 * dz_2 + 2 * dz_3 + dz_4 );
+
+ }
+
+ // Reasign position, velocities and accelerations for next integration
+ d_satpos_X = x0;
+ d_satpos_Y = y0;
+ d_satpos_Z = z0;
+
+ d_satvel_X = Vx0;
+ d_satvel_Y = Vy0;
+ d_satvel_Z = Vz0;
+
+ d_satacc_X = d_satacc_X; // No change in accelerations reported over interval
+ d_satacc_Y = d_satacc_Y; // No change in accelerations reported over interval
+ d_satacc_Z = d_satacc_Z; // No change in accelerations reported over interval
+
+ // Time from ephemeris reference clock
+ tk = check_t(transmitTime - d_Toc);
+
+ double dtr_s = d_A_f0 + d_A_f1 * tk + d_A_f2 * tk * tk;
+
+ /* relativity correction */
+ dtr_s -= 2.0 * sqrt(GM * GLONASS_a) * d_e_eccentricity * sin(E) / (GPS_C_m_s * GPS_C_m_s);
+
+ return dtr_s;
+}
+
+
+double Glonass_GNAV_Ephemeris::satellitePosition(double transmitTime)
+{
+ double dt = 0.0;
+ double tk = 0.0;
+ int numberOfIntegrations = 0;
+
+ // Find time difference
+ dt = check_t(transmitTime - d_t_b);
+
+ // Calculate clock correction
+ satClkCorr = -(d_tau_n + d_tau_c - d_gamma_n * dt);
+
+ // Find integration time
+ tk = dt - satClkCorr;
+
+ // Check if to integrate forward or backward
+ if tk < 0
+ tau = -60;
+ else
+ tau = 60;
+ end
+
+ // Coordinates transformation to an inertial reference frame
+ // x,y,z coordinates to meters
+ x0 = d_satpos_X * 1e3;
+ y0 = d_satpos_Y * 1e3;
+ z0 = d_satpos_Z * 1e3;
+
+ // x,y,z velocities to meters/s
+ Vx0 = d_satvel_X * 1e3;
+ Vy0 = d_satvel_Y * 1e3;
+ Vz0 = d_satvel_Z * 1e3;
+
+ // x,y,z accelerations to meters/sec^2
+ Ax0 = d_satacc_X * 1e3;
+ Ay0 = d_satacc_Y * 1e3;
+ Az0 = d_satacc_Z * 1e3;
+
+ for(numberOfIntegrations = tau; numberOfIntegrations < tk+tau; numberOfIntegrations += tau)
+ {
+ // Check if last integration step. If last integration step, make one more step that has the remaining time length...
+ if(fabs(numberOfIntegrations) > fabs(tk))
+ {
+ // if there is more time left to integrate...
+ if mod(tk,tau) ~= 0
+ {
+ tau = mod(time,tau);
+ }
+ else // otherwise make a zero step.
+ {
+ tau = 0;
+ }
+ }
+
+ // Runge-Kutta Integration Stage K1
+ r0 = sqrt(x0*x0 + y0*y0 + z0*z0);
+ r0_2 = r0*r0;
+ r0_3 = r0*r0*r0;
+ r0_5 = r0*r0*r0*r0*r0;
+
+ dx_1 = Vx0;
+ dy_1 = Vy0;
+ dz_1 = Vz0;
+
+ dVx_1 = - GLONASS_GM / r0_3 * x0 + 3/2 * GLONASS_C20 * GLONASS_GM * (GLONASS_EARTH_RADIUS * GLONASS_EARTH_RADIUS) / r0_5 * x0 * (1 - 5 * 1 / (z0*z0)) + Jx_moon + Jx_sun;
+ dVy_1 = - GLONASS_GM / r0_3 * y0 + 3/2 * GLONASS_C20 * GLONASS_GM * (GLONASS_EARTH_RADIUS * GLONASS_EARTH_RADIUS) / r0_5 * y0 * (1 - 5 * 1 / (z0*z0)) + Jy_moon + Jy_sun;
+ dVz_1 = - GLONASS_GM / r0_3 * z0 + 3/2 * GLONASS_C20 * GLONASS_GM * (GLONASS_EARTH_RADIUS * GLONASS_EARTH_RADIUS) / r0_5 * z0 * (3 - 5 * 1 / (z0*z0)) + Jz_moon + Jz_sun;
+
+ dx_1 = Vx0;
+ dy_1 = Vy0;
+ dz_1 = Vz0;
+
+ // Runge-Kutta Integration Stage K2
+ Vx_1 = Vx0 + 1/2 * tau * dVx_1;
+ Vy_1 = Vy0 + 1/2 * tau * dVy_1;
+ Vz_1 = Vz0 + 1/2 * tau * dVz_1;
+
+ x_1 = x0 + 1/2 * tau * dx_1;
+ y_1 = y0 + 1/2 * tau * dy_1;
+ z_1 = z0 + 1/2 * tau * dz_1;
+
+ r1 = sqrt( x_1*x_1 + y_1*y_1 + z_1*z_1 );
+ r1_2 = r1*r1;
+ r1_3 = r1*r1*r1;
+ r1_5 = r1*r1*r1*r1*r1;
+
+ dVx_2 = - GLONASS_GM / r1_3 * x_1 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r1_5 * x_1 * (1 - 5 * (z_1*z_1) / r1_2) + (GLONASS_OMEGA_EARTH_DOT * GLONASS_OMEGA_EARTH_DOT) * x_1 + 2 * GLONASS_OMEGA_EARTH_DOT * Vy_1 + Ax0;
+ dVy_2 = - GLONASS_GM / r1_3 * y_1 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r1_5 * y_1 * (1 - 5 * (z_1*z_1) / r1_2) + (GLONASS_OMEGA_EARTH_DOT * GLONASS_OMEGA_EARTH_DOT) * y_1 - 2 * GLONASS_OMEGA_EARTH_DOT * Vx_1 + Ay0;
+ dVz_2 = - GLONASS_GM / r1_3 * z_1 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r1_5 * z_1 * (3 - 5 * (z_1*z_1) / r1_2) + Az0;
+
+ dx_2 = Vx_1;
+ dy_2 = Vy_1;
+ dz_2 = Vz_1;
+
+ // Runge-Kutta Integration Stage K2
+ Vx_2 = Vx0 + 1/2 * tau * dVx_2;
+ Vy_2 = Vy0 + 1/2 * tau * dVy_2;
+ Vz_2 = Vz0 + 1/2 * tau * dVz_2;
+
+ x_2 = x0 + 1/2 * tau * dx_2;
+ y_2 = y0 + 1/2 * tau * dy_2;
+ z_2 = z0 + 1/2 * tau * dz_2;
+
+ r2 = sqrt( x_2*x_2 + y_2*y_2 + z_2*z_2 );
+ r2_2 = r2*r2;
+ r2_3 = r2*r2*r2;
+ r2_5 = r2*r2*r2*r2*r2;
+
+
+ dVx_3 = - GLONASS_GM / r2_3 * x_2 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r2_5 * x_2 * (1 - 5 * (z_2*z_2) / r2_2) + (GLONASS_OMEGA_EARTH_DOT * GLONASS_OMEGA_EARTH_DOT) * x_2 + 2 * GLONASS_OMEGA_EARTH_DOT * Vy_2 + Ax0;
+ dVy_3 = - GLONASS_GM / r2_3 * y_2 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r2_5 * y_2 * (1 - 5 * (z_2*z_2) / r2_2) + (GLONASS_OMEGA_EARTH_DOT * GLONASS_OMEGA_EARTH_DOT) * y_2 - 2 * GLONASS_OMEGA_EARTH_DOT * Vx_2 + Ay0;
+ dVz_3 = - GLONASS_GM / r2_3 * z_2 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r2_5 * z_2 * (3 - 5 * (z_2*z_2) / r2_2) + Az0;
+
+ dx_3 = Vx_2;
+ dy_3 = Vy_2;
+ dz_3 = Vz_2;
+
+ // Runge-Kutta Integration Stage K3
+ Vx_3 = Vx0 + tau * dVx_3;
+ Vy_3 = Vy0 + tau * dVy_3;
+ Vz_3 = Vz0 + tau * dVz_3;
+
+ x_3 = x0 + tau * dx_3;
+ y_3 = y0 + tau * dy_3;
+ z_3 = z0 + tau * dz_3;
+
+ r3 = sqrt( x_3*x_3 + y_3*y_3 + z_3*z_3 );
+ r3_2 = r3*r3;
+ r3_3 = r3*r3*r3;
+ r3_5 = r3*r3*r3*r3*r3;
+
+ dVx_4 = - GLONASS_GM / r3_3 * x_3 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r3_5 * x_3 * (1 - 5 * (z_3*z_3) / r3_2) + (GLONASS_OMEGA_EARTH_DOT * GLONASS_OMEGA_EARTH_DOT) * x_3 + 2 * GLONASS_OMEGA_EARTH_DOT * Vy_3 + Ax0;
+ dVy_4 = - GLONASS_GM / r3_3 * y_3 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r3_5 * y_3 * (1 - 5 * (z_3*z_3) / r3_2) + (GLONASS_OMEGA_EARTH_DOT * GLONASS_OMEGA_EARTH_DOT) * y_3 - 2 * GLONASS_OMEGA_EARTH_DOT * Vx_3 + Ay0;
+ dVz_4 = - GLONASS_GM / r3_3 * z_3 - 3/2 * GLONASS_J2 * GLONASS_GM * (GLONASS_a*GLONASS_a) / r3_5 * z_3 * (3 - 5 * (z_3*z_3) / r3_2) + Az0;
+
+ dx_4 = Vx_3;
+ dy_4 = Vy_3;
+ dz_4 = Vz_3;
+
+ // Final results showcased here
+ Vx0 = Vx0 + 1/6 * tau * ( dVx_1 + 2 * dVx_2 + 2 * dVx_3 + dVx_4 );
+ Vy0 = Vy0 + 1/6 * tau * ( dVy_1 + 2 * dVy_2 + 2 * dVy_3 + dVy_4 );
+ Vz0 = Vz0 + 1/6 * tau * ( dVz_1 + 2 * dVz_2 + 2 * dVz_3 + dVz_4 );
+
+ x0 = x0 + 1/6 * tau * ( dx_1 + 2 * dx_2 + 2 * dx_3 + dx_4 );
+ y0 = y0 + 1/6 * tau * ( dy_1 + 2 * dy_2 + 2 * dy_3 + dy_4 );
+ z0 = z0 + 1/6 * tau * ( dz_1 + 2 * dz_2 + 2 * dz_3 + dz_4 );
+
+ }
+
+ // Time from ephemeris reference clock
+ tk = check_t(transmitTime - d_Toc);
+
+ double dtr_s = d_A_f0 + d_A_f1 * tk + d_A_f2 * tk * tk;
+
+ /* relativity correction */
+ dtr_s -= 2.0 * sqrt(GM * GLONASS_a) * d_e_eccentricity * sin(E) / (GPS_C_m_s * GPS_C_m_s);
+
+ return dtr_s;
+}
diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.h b/src/core/system_parameters/glonass_gnav_ephemeris.h
new file mode 100644
index 000000000..6a2ab046d
--- /dev/null
+++ b/src/core/system_parameters/glonass_gnav_ephemeris.h
@@ -0,0 +1,170 @@
+/*!
+ * \file glonass_gnav_ephemeris.h
+ * \brief Interface of a GLONASS EPHEMERIS storage
+ * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+
+#ifndef GNSS_SDR_GLONASS_GNAV_EPHEMERIS_H_
+#define GNSS_SDR_GLONASS_GNAV_EPHEMERIS_H_
+
+
+#include