mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-01-16 04:05:46 +00:00
Merge pull request #104 from antonioramosdet/TD_GPS_L5
Merge pull request #104
This commit is contained in:
commit
419957bec6
@ -141,14 +141,17 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration,
|
||||
*/
|
||||
int gps_1C_count = configuration->property("Channels_1C.count", 0);
|
||||
int gps_2S_count = configuration->property("Channels_2S.count", 0);
|
||||
int gps_L5_count = configuration->property("Channels_L5.count", 0);
|
||||
int gal_1B_count = configuration->property("Channels_1B.count", 0);
|
||||
int gal_E5a_count = configuration->property("Channels_5X.count", 0); // GPS L5 or Galileo E5a ?
|
||||
int gal_E5b_count = configuration->property("Channels_7X.count", 0);
|
||||
|
||||
unsigned int type_of_receiver = 0;
|
||||
// *******************WARNING!!!!!!!***********
|
||||
// GPS L5 only configurable for single frequency, single system at the moment!!!!!!
|
||||
if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 1;
|
||||
if( (gps_1C_count == 0) && (gps_2S_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 2;
|
||||
|
||||
if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 3;
|
||||
if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 4;
|
||||
if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0)) type_of_receiver = 5;
|
||||
if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0)) type_of_receiver = 6;
|
||||
@ -194,7 +197,7 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration,
|
||||
int num_bands = 0;
|
||||
if ((gps_1C_count > 0) || (gal_1B_count > 0)) num_bands = 1;
|
||||
if (gps_2S_count > 0) num_bands = 2;
|
||||
if ((gal_E5a_count > 0) || (gal_E5b_count > 0)) num_bands = 3;
|
||||
if ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0)) num_bands = 3;
|
||||
int number_of_frequencies = configuration->property(role + ".num_bands", num_bands); /* (1:L1, 2:L1+L2, 3:L1+L2+L5) */
|
||||
if( (number_of_frequencies < 1) || (number_of_frequencies > 3) )
|
||||
{
|
||||
@ -272,7 +275,7 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration,
|
||||
int earth_tide = configuration->property(role + ".earth_tide", 0);
|
||||
|
||||
int nsys = 0;
|
||||
if ((gps_1C_count > 0) || (gps_2S_count > 0)) nsys += SYS_GPS;
|
||||
if ((gps_1C_count > 0) || (gps_2S_count > 0) || (gps_L5_count > 0)) nsys += SYS_GPS;
|
||||
if ((gal_1B_count > 0) || (gal_E5a_count > 0) || (gal_E5b_count > 0)) nsys += SYS_GAL;
|
||||
int navigation_system = configuration->property(role + ".navigation_system", nsys); /* (SYS_XXX) see src/algorithms/libs/rtklib/rtklib.h */
|
||||
if( (navigation_system < 1) || (navigation_system > 255) ) /* GPS: 1 SBAS: 2 GPS+SBAS: 3 Galileo: 8 Galileo+GPS: 9 GPS+SBAS+Galileo: 11 All: 255 */
|
||||
|
@ -123,7 +123,7 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg)
|
||||
gps_cnav_ephemeris = boost::any_cast<std::shared_ptr<Gps_CNAV_Ephemeris>>(pmt::any_ref(msg));
|
||||
// update/insert new ephemeris record to the global ephemeris map
|
||||
d_ls_pvt->gps_cnav_ephemeris_map[gps_cnav_ephemeris->i_satellite_PRN] = *gps_cnav_ephemeris;
|
||||
LOG(INFO) << "New GPS CNAV ephemeris record has arrived ";
|
||||
DLOG(INFO) << "New GPS CNAV ephemeris record has arrived ";
|
||||
}
|
||||
else if(pmt::any_ref(msg).type() == typeid(std::shared_ptr<Gps_CNAV_Iono>) )
|
||||
{
|
||||
@ -335,7 +335,7 @@ rtklib_pvt_cc::~rtklib_pvt_cc()
|
||||
msgctl(sysv_msqid, IPC_RMID, NULL);
|
||||
|
||||
//save GPS L2CM ephemeris to XML file
|
||||
std::string file_name = "eph_GPS_L2CM.xml";
|
||||
std::string file_name = "eph_GPS_L2CM_L5.xml";
|
||||
|
||||
if (d_ls_pvt->gps_cnav_ephemeris_map.size() > 0)
|
||||
{
|
||||
@ -345,7 +345,7 @@ rtklib_pvt_cc::~rtklib_pvt_cc()
|
||||
boost::archive::xml_oarchive xml(ofs);
|
||||
xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->gps_cnav_ephemeris_map);
|
||||
ofs.close();
|
||||
LOG(INFO) << "Saved GPS L2CM Ephemeris map data";
|
||||
LOG(INFO) << "Saved GPS L2CM or L5 Ephemeris map data";
|
||||
}
|
||||
catch (const std::exception & e)
|
||||
{
|
||||
@ -354,7 +354,7 @@ rtklib_pvt_cc::~rtklib_pvt_cc()
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << "Failed to save GPS L2CM Ephemeris, map is empty";
|
||||
LOG(WARNING) << "Failed to save GPS L2CM or L5 Ephemeris, map is empty";
|
||||
}
|
||||
|
||||
//save GPS L1 CA ephemeris to XML file
|
||||
@ -470,7 +470,8 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite
|
||||
if(((tmp_eph_iter_gps->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("1C") == 0))
|
||||
|| ((tmp_eph_iter_cnav->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("2S") == 0))
|
||||
|| ((tmp_eph_iter_gal->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("1B") == 0))
|
||||
|| ((tmp_eph_iter_gal->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("5X") == 0)))
|
||||
|| ((tmp_eph_iter_gal->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("5X") == 0))
|
||||
|| ((tmp_eph_iter_cnav->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("L5") == 0)))
|
||||
{
|
||||
// store valid observables in a map.
|
||||
gnss_observables_map.insert(std::pair<int,Gnss_Synchro>(i, in[i][epoch]));
|
||||
@ -647,6 +648,15 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite
|
||||
b_rinex_header_written = true; // do not write header anymore
|
||||
}
|
||||
}
|
||||
if(type_of_rx == 3) // GPS L5 only
|
||||
{
|
||||
if (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())
|
||||
{
|
||||
rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time);
|
||||
rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model);
|
||||
b_rinex_header_written = true; // do not write header anymore
|
||||
}
|
||||
}
|
||||
if(type_of_rx == 4) // Galileo E1B only
|
||||
{
|
||||
if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())
|
||||
@ -749,6 +759,10 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite
|
||||
{
|
||||
rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_cnav_ephemeris_map);
|
||||
}
|
||||
if(type_of_rx == 3) // GPS L5 only
|
||||
{
|
||||
rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_cnav_ephemeris_map);
|
||||
}
|
||||
if( (type_of_rx == 4) || (type_of_rx == 5) || (type_of_rx == 6) ) // Galileo
|
||||
{
|
||||
rp->log_rinex_nav(rp->navGalFile, d_ls_pvt->galileo_ephemeris_map);
|
||||
@ -799,6 +813,19 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite
|
||||
b_rinex_header_updated = true;
|
||||
}
|
||||
}
|
||||
if(type_of_rx == 3) // GPS L5
|
||||
{
|
||||
if (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.end())
|
||||
{
|
||||
rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map);
|
||||
}
|
||||
if (!b_rinex_header_updated && (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0))
|
||||
{
|
||||
rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model);
|
||||
rp->update_nav_header(rp->navFile, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->gps_cnav_iono);
|
||||
b_rinex_header_updated = true;
|
||||
}
|
||||
}
|
||||
if(type_of_rx == 4) // Galileo E1B only
|
||||
{
|
||||
if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end())
|
||||
|
@ -258,7 +258,10 @@ bool rtklib_solver::get_PVT(const std::map<int,Gnss_Synchro> & gnss_observables_
|
||||
//convert ephemeris from GNSS-SDR class to RTKLIB structure
|
||||
eph_data[valid_obs] = eph_to_rtklib(gps_cnav_ephemeris_iter->second);
|
||||
//convert observation from GNSS-SDR class to RTKLIB structure
|
||||
obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}};
|
||||
unsigned char default_code_ = static_cast<unsigned char>(CODE_NONE);
|
||||
obsd_t newobs = {{0,0}, '0', '0', {}, {},
|
||||
{default_code_, default_code_, default_code_},
|
||||
{}, {0.0, 0.0, 0.0}, {}};
|
||||
obs_data[valid_obs] = insert_obs_to_rtklib(newobs,
|
||||
gnss_observables_iter->second,
|
||||
gps_cnav_ephemeris_iter->second.i_GPS_week,
|
||||
@ -271,6 +274,53 @@ bool rtklib_solver::get_PVT(const std::map<int,Gnss_Synchro> & gnss_observables_
|
||||
DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN;
|
||||
}
|
||||
}
|
||||
//GPS L5
|
||||
if(sig_.compare("L5") == 0)
|
||||
{
|
||||
gps_cnav_ephemeris_iter = gps_cnav_ephemeris_map.find(gnss_observables_iter->second.PRN);
|
||||
if (gps_cnav_ephemeris_iter != gps_cnav_ephemeris_map.cend())
|
||||
{
|
||||
// 1. Find the same satellite in GPS L1 band
|
||||
gps_ephemeris_iter = gps_ephemeris_map.find(gnss_observables_iter->second.PRN);
|
||||
if (gps_ephemeris_iter != gps_ephemeris_map.cend())
|
||||
{
|
||||
// 2. If found, replace the existing GPS L1 ephemeris with the GPS L5 ephemeris
|
||||
// (more precise!), and attach the L5 observation to the L1 observation in RTKLIB structure
|
||||
for (int i = 0; i < valid_obs; i++)
|
||||
{
|
||||
if (eph_data[i].sat == static_cast<int>(gnss_observables_iter->second.PRN))
|
||||
{
|
||||
eph_data[i] = eph_to_rtklib(gps_cnav_ephemeris_iter->second);
|
||||
obs_data[i] = insert_obs_to_rtklib(obs_data[i],
|
||||
gnss_observables_iter->second,
|
||||
gps_cnav_ephemeris_iter->second.i_GPS_week,
|
||||
2);//Band 3 (L5)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 3. If not found, insert the GPS L5 ephemeris and the observation
|
||||
//convert ephemeris from GNSS-SDR class to RTKLIB structure
|
||||
eph_data[valid_obs] = eph_to_rtklib(gps_cnav_ephemeris_iter->second);
|
||||
//convert observation from GNSS-SDR class to RTKLIB structure
|
||||
unsigned char default_code_ = static_cast<unsigned char>(CODE_NONE);
|
||||
obsd_t newobs = {{0,0}, '0', '0', {}, {},
|
||||
{default_code_, default_code_, default_code_},
|
||||
{}, {0.0, 0.0, 0.0}, {}};
|
||||
obs_data[valid_obs] = insert_obs_to_rtklib(newobs,
|
||||
gnss_observables_iter->second,
|
||||
gps_cnav_ephemeris_iter->second.i_GPS_week,
|
||||
2);//Band 3 (L5)
|
||||
valid_obs++;
|
||||
}
|
||||
}
|
||||
else // the ephemeris are not available for this SV
|
||||
{
|
||||
DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default :
|
||||
@ -296,7 +346,6 @@ bool rtklib_solver::get_PVT(const std::map<int,Gnss_Synchro> & gnss_observables_
|
||||
nav_data.lam[i][1] = SPEED_OF_LIGHT / FREQ2; /* L2 */
|
||||
nav_data.lam[i][2] = SPEED_OF_LIGHT / FREQ5; /* L5/E5 */
|
||||
}
|
||||
|
||||
result = rtkpos(&rtk_, obs_data, valid_obs, &nav_data);
|
||||
if(result == 0)
|
||||
{
|
||||
|
@ -186,7 +186,7 @@ void gps_l5i_code_gen_complex(std::complex<float>* _dest, unsigned int _prn)
|
||||
|
||||
if (_prn > 0 and _prn < 51)
|
||||
{
|
||||
make_l5i(_code, _prn);
|
||||
make_l5i(_code, _prn - 1);
|
||||
}
|
||||
|
||||
for (signed int i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++)
|
||||
@ -206,7 +206,7 @@ void gps_l5i_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _
|
||||
int32_t* _code = new int32_t[GPS_L5i_CODE_LENGTH_CHIPS];
|
||||
if (_prn > 0 and _prn < 51)
|
||||
{
|
||||
make_l5i(_code, _prn);
|
||||
make_l5i(_code, _prn - 1);
|
||||
}
|
||||
|
||||
signed int _samplesPerCode, _codeValueIndex;
|
||||
@ -253,7 +253,7 @@ void gps_l5q_code_gen_complex(std::complex<float>* _dest, unsigned int _prn)
|
||||
|
||||
if (_prn > 0 and _prn < 51)
|
||||
{
|
||||
make_l5q(_code, _prn);
|
||||
make_l5q(_code, _prn - 1);
|
||||
}
|
||||
|
||||
for (signed int i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++)
|
||||
@ -273,7 +273,7 @@ void gps_l5q_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _
|
||||
int32_t* _code = new int32_t[GPS_L5q_CODE_LENGTH_CHIPS];
|
||||
if (_prn > 0 and _prn < 51)
|
||||
{
|
||||
make_l5q(_code, _prn);
|
||||
make_l5q(_code, _prn - 1);
|
||||
}
|
||||
|
||||
signed int _samplesPerCode, _codeValueIndex;
|
||||
|
@ -35,7 +35,7 @@ obsd_t insert_obs_to_rtklib(obsd_t & rtklib_obs, const Gnss_Synchro & gnss_synch
|
||||
{
|
||||
rtklib_obs.D[band] = gnss_synchro.Carrier_Doppler_hz;
|
||||
rtklib_obs.P[band] = gnss_synchro.Pseudorange_m;
|
||||
rtklib_obs.L[band] = gnss_synchro.Carrier_phase_rads / (2.0 * PI);
|
||||
rtklib_obs.L[band] = gnss_synchro.Carrier_phase_rads / PI_2;
|
||||
switch(band)
|
||||
{
|
||||
case 0:
|
||||
@ -165,8 +165,6 @@ eph_t eph_to_rtklib(const Gps_Ephemeris & gps_eph)
|
||||
rtklib_sat.toc = gpst2time(rtklib_sat.week, toc);
|
||||
rtklib_sat.ttr = gpst2time(rtklib_sat.week, tow);
|
||||
|
||||
//printf("EPHEMERIS TIME [%i]: %s,%f\n\r",rtklib_sat.sat,time_str(rtklib_sat.toe,3),rtklib_sat.toe.sec);
|
||||
|
||||
return rtklib_sat;
|
||||
}
|
||||
|
||||
@ -183,7 +181,7 @@ eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris & gps_cnav_eph)
|
||||
rtklib_sat.OMG0 = gps_cnav_eph.d_OMEGA0;
|
||||
// Compute the angle between the ascending node and the Greenwich meridian
|
||||
const double OMEGA_DOT_REF = -2.6e-9; // semicircles / s, see IS-GPS-200H pp. 164
|
||||
double d_OMEGA_DOT = OMEGA_DOT_REF * GPS_L2_PI + gps_cnav_eph.d_DELTA_OMEGA_DOT;
|
||||
double d_OMEGA_DOT = OMEGA_DOT_REF * PI + gps_cnav_eph.d_DELTA_OMEGA_DOT;
|
||||
rtklib_sat.OMGd = d_OMEGA_DOT;
|
||||
rtklib_sat.omg = gps_cnav_eph.d_OMEGA;
|
||||
rtklib_sat.i0 = gps_cnav_eph.d_i_0;
|
||||
|
@ -97,7 +97,13 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
|
||||
|
||||
|
||||
/* L1-L2 for GPS/GLO/QZS, L1-L5 for GAL/SBS */
|
||||
if (NFREQ >= 3 && (sys & (SYS_GAL | SYS_SBS))) j = 2;
|
||||
if (sys & (SYS_GAL | SYS_SBS)) {j = 2;}
|
||||
|
||||
if (sys == SYS_GPS)
|
||||
{
|
||||
if(obs->code[1] != CODE_NONE) {j = 1;}
|
||||
else if(obs->code[2] != CODE_NONE) {j = 2;}
|
||||
}
|
||||
|
||||
if (NFREQ<2 || lam[i] == 0.0 || lam[j] == 0.0)
|
||||
{
|
||||
@ -132,7 +138,7 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
|
||||
P2_C2 = nav->cbias[obs->sat-1][2];
|
||||
|
||||
/* if no P1-P2 DCB, use TGD instead */
|
||||
if (P1_P2 == 0.0 && (sys & (SYS_GPS | SYS_GAL | SYS_QZS)))
|
||||
if (P1_P2 == 0.0 && (sys & (SYS_GPS | SYS_GAL | SYS_QZS))) //CHECK!
|
||||
{
|
||||
P1_P2 = (1.0 - gamma_) * gettgd(obs->sat, nav);
|
||||
}
|
||||
|
@ -18,7 +18,8 @@
|
||||
|
||||
set(TELEMETRY_DECODER_ADAPTER_SOURCES
|
||||
gps_l1_ca_telemetry_decoder.cc
|
||||
gps_l2c_telemetry_decoder.cc
|
||||
gps_l2c_telemetry_decoder.cc
|
||||
gps_l5_telemetry_decoder.cc
|
||||
galileo_e1b_telemetry_decoder.cc
|
||||
sbas_l1_telemetry_decoder.cc
|
||||
galileo_e5a_telemetry_decoder.cc
|
||||
|
@ -0,0 +1,99 @@
|
||||
/*!
|
||||
* \file gps_l5_telemetry_decoder.cc
|
||||
* \brief Implementation of an adapter of a GPS L5 NAV data decoder block
|
||||
* to a TelemetryDecoderInterface
|
||||
* \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2017 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "gps_l5_telemetry_decoder.h"
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <glog/logging.h>
|
||||
#include "concurrent_queue.h"
|
||||
#include "configuration_interface.h"
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
GpsL5TelemetryDecoder::GpsL5TelemetryDecoder(ConfigurationInterface* configuration,
|
||||
std::string role,
|
||||
unsigned int in_streams,
|
||||
unsigned int out_streams) :
|
||||
role_(role),
|
||||
in_streams_(in_streams),
|
||||
out_streams_(out_streams)
|
||||
{
|
||||
std::string default_dump_filename = "./navigation.dat";
|
||||
DLOG(INFO) << "role " << role;
|
||||
dump_ = configuration->property(role + ".dump", false);
|
||||
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||
// make telemetry decoder object
|
||||
telemetry_decoder_ = gps_l5_make_telemetry_decoder_cc(satellite_, dump_);
|
||||
DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")";
|
||||
|
||||
LOG(INFO) << "global navigation message queue assigned to telemetry_decoder (" << telemetry_decoder_->unique_id() << ")" << "role " << role;
|
||||
channel_ = 0;
|
||||
}
|
||||
|
||||
|
||||
GpsL5TelemetryDecoder::~GpsL5TelemetryDecoder()
|
||||
{}
|
||||
|
||||
|
||||
void GpsL5TelemetryDecoder::set_satellite(const Gnss_Satellite & satellite)
|
||||
{
|
||||
satellite_ = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
||||
telemetry_decoder_->set_satellite(satellite_);
|
||||
DLOG(INFO) << "TELEMETRY DECODER: satellite set to " << satellite_;
|
||||
}
|
||||
|
||||
|
||||
void GpsL5TelemetryDecoder::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if(top_block) { /* top_block is not null */};
|
||||
// Nothing to connect internally
|
||||
DLOG(INFO) << "nothing to connect internally";
|
||||
}
|
||||
|
||||
|
||||
void GpsL5TelemetryDecoder::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if(top_block) { /* top_block is not null */};
|
||||
// Nothing to disconnect
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr GpsL5TelemetryDecoder::get_left_block()
|
||||
{
|
||||
return telemetry_decoder_;
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr GpsL5TelemetryDecoder::get_right_block()
|
||||
{
|
||||
return telemetry_decoder_;
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/*!
|
||||
* \file gps_l5_telemetry_decoder.h
|
||||
* \brief Interface of an adapter of a GPS L5 (CNAV) data decoder block
|
||||
* to a TelemetryDecoderInterface
|
||||
* \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2017 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GNSS_SDR_GPS_L5_TELEMETRY_DECODER_H_
|
||||
#define GNSS_SDR_GPS_L5_TELEMETRY_DECODER_H_
|
||||
|
||||
#include <string>
|
||||
#include "telemetry_decoder_interface.h"
|
||||
#include "gps_l5_telemetry_decoder_cc.h"
|
||||
#include "gnss_satellite.h"
|
||||
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
* \brief This class implements a NAV data decoder for GPS L5
|
||||
*/
|
||||
class GpsL5TelemetryDecoder : public TelemetryDecoderInterface
|
||||
{
|
||||
public:
|
||||
GpsL5TelemetryDecoder(ConfigurationInterface* configuration,
|
||||
std::string role,
|
||||
unsigned int in_streams,
|
||||
unsigned int out_streams);
|
||||
|
||||
virtual ~GpsL5TelemetryDecoder();
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
//! Returns "GPS_L5_Telemetry_Decoder"
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "GPS_L5_Telemetry_Decoder";
|
||||
}
|
||||
|
||||
void connect(gr::top_block_sptr top_block) override;
|
||||
void disconnect(gr::top_block_sptr top_block) override;
|
||||
gr::basic_block_sptr get_left_block() override;
|
||||
gr::basic_block_sptr get_right_block() override;
|
||||
|
||||
void set_satellite(const Gnss_Satellite & satellite) override;
|
||||
inline void set_channel(int channel) override { telemetry_decoder_->set_channel(channel); }
|
||||
|
||||
inline void reset() override
|
||||
{
|
||||
return;
|
||||
}
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
gps_l5_telemetry_decoder_cc_sptr telemetry_decoder_;
|
||||
Gnss_Satellite satellite_;
|
||||
int channel_;
|
||||
bool dump_;
|
||||
std::string dump_filename_;
|
||||
std::string role_;
|
||||
unsigned int in_streams_;
|
||||
unsigned int out_streams_;
|
||||
};
|
||||
|
||||
#endif
|
@ -19,6 +19,7 @@
|
||||
set(TELEMETRY_DECODER_GR_BLOCKS_SOURCES
|
||||
gps_l1_ca_telemetry_decoder_cc.cc
|
||||
gps_l2c_telemetry_decoder_cc.cc
|
||||
gps_l5_telemetry_decoder_cc.cc
|
||||
galileo_e1b_telemetry_decoder_cc.cc
|
||||
sbas_l1_telemetry_decoder_cc.cc
|
||||
galileo_e5a_telemetry_decoder_cc.cc
|
||||
|
@ -297,14 +297,8 @@ int galileo_e5a_telemetry_decoder_cc::general_work (int noutput_items __attribut
|
||||
d_symbol_counter = 0;
|
||||
flag_bit_start = true;
|
||||
corr_value = 0;
|
||||
while(d_preamble_init.size() > 0)
|
||||
{ //Clear preamble correlating queue
|
||||
d_preamble_init.pop_front();
|
||||
}
|
||||
while(d_symbol_history.size() > 0)
|
||||
{ //Clear symbol queue in order to prevent possible symbol discontinuities
|
||||
d_symbol_history.pop_front();
|
||||
}
|
||||
d_preamble_init.clear();
|
||||
d_symbol_history.clear();
|
||||
LOG(INFO) << "Bit start sync for Galileo E5a satellite " << d_satellite;
|
||||
}
|
||||
else
|
||||
|
@ -170,12 +170,6 @@ int gps_l2c_telemetry_decoder_cc::general_work (int noutput_items __attribute__(
|
||||
current_synchro_data.TOW_at_current_symbol_s = d_TOW_at_current_symbol;
|
||||
current_synchro_data.Flag_valid_word = d_flag_valid_word;
|
||||
|
||||
// if (flag_PLL_180_deg_phase_locked == true)
|
||||
// {
|
||||
// //correct the accumulated phase for the Costas loop phase shift, if required
|
||||
// current_synchro_data.Carrier_phase_rads += GPS_PI;
|
||||
// }
|
||||
|
||||
if(d_dump == true)
|
||||
{
|
||||
// MULTIPLEXED FILE RECORDING - Record results to file
|
||||
@ -192,7 +186,7 @@ int gps_l2c_telemetry_decoder_cc::general_work (int noutput_items __attribute__(
|
||||
}
|
||||
catch (const std::ifstream::failure & e)
|
||||
{
|
||||
LOG(WARNING) << "Exception writing observables dump file " << e.what();
|
||||
LOG(WARNING) << "Exception writing Telemetry GPS L2 dump file " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,7 +224,7 @@ void gps_l2c_telemetry_decoder_cc::set_channel(int channel)
|
||||
}
|
||||
catch (const std::ifstream::failure &e)
|
||||
{
|
||||
LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what();
|
||||
LOG(WARNING) << "channel " << d_channel << " Exception opening Telemetry GPS L2 dump file " << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,271 @@
|
||||
/*!
|
||||
* \file gps_l5_telemetry_decoder_cc.cc
|
||||
* \brief Implementation of a NAV message demodulator block based on
|
||||
* Kay Borre book MATLAB-based GPS receiver
|
||||
* \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2017 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <bitset>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <glog/logging.h>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include "gnss_synchro.h"
|
||||
#include "gps_l5_telemetry_decoder_cc.h"
|
||||
#include "gps_cnav_ephemeris.h"
|
||||
#include "gps_cnav_iono.h"
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
gps_l5_telemetry_decoder_cc_sptr
|
||||
gps_l5_make_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump)
|
||||
{
|
||||
return gps_l5_telemetry_decoder_cc_sptr(new gps_l5_telemetry_decoder_cc(satellite, dump));
|
||||
}
|
||||
|
||||
|
||||
gps_l5_telemetry_decoder_cc::gps_l5_telemetry_decoder_cc(
|
||||
const Gnss_Satellite & satellite, bool dump) : gr::block("gps_l5_telemetry_decoder_cc",
|
||||
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
|
||||
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
|
||||
{
|
||||
// Telemetry Bit transition synchronization port out
|
||||
this->message_port_register_out(pmt::mp("preamble_timestamp_s"));
|
||||
// Ephemeris data port out
|
||||
this->message_port_register_out(pmt::mp("telemetry"));
|
||||
// initialize internal vars
|
||||
d_dump = dump;
|
||||
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
||||
DLOG(INFO) << "GPS L5 TELEMETRY PROCESSING: satellite " << d_satellite;
|
||||
d_channel = 0;
|
||||
d_flag_valid_word = false;
|
||||
d_TOW_at_current_symbol = 0.0;
|
||||
d_TOW_at_Preamble = 0.0;
|
||||
//initialize the CNAV frame decoder (libswiftcnav)
|
||||
cnav_msg_decoder_init(&d_cnav_decoder);
|
||||
for(int aux = 0; aux < GPS_L5_NH_CODE_LENGTH; aux++)
|
||||
{
|
||||
if(GPS_L5_NH_CODE[aux] == 0)
|
||||
{
|
||||
bits_NH[aux] = -1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bits_NH[aux] = 1.0;
|
||||
}
|
||||
}
|
||||
sync_NH = false;
|
||||
new_sym = false;
|
||||
}
|
||||
|
||||
|
||||
gps_l5_telemetry_decoder_cc::~gps_l5_telemetry_decoder_cc()
|
||||
{
|
||||
if(d_dump_file.is_open() == true)
|
||||
{
|
||||
try
|
||||
{
|
||||
d_dump_file.close();
|
||||
}
|
||||
catch(const std::exception & ex)
|
||||
{
|
||||
LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int gps_l5_telemetry_decoder_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
|
||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
|
||||
{
|
||||
// get pointers on in- and output gnss-synchro objects
|
||||
Gnss_Synchro *out = reinterpret_cast<Gnss_Synchro *>(output_items[0]); // Get the output buffer pointer
|
||||
const Gnss_Synchro *in = reinterpret_cast<const Gnss_Synchro *>(input_items[0]); // Get the input buffer pointer
|
||||
|
||||
// UPDATE GNSS SYNCHRO DATA
|
||||
Gnss_Synchro current_synchro_data; //structure to save the synchronization information and send the output object to the next block
|
||||
//1. Copy the current tracking output
|
||||
current_synchro_data = in[0];
|
||||
consume_each(1); //one by one
|
||||
sym_hist.push_back(in[0].Prompt_I);
|
||||
int corr_NH = 0;
|
||||
int symbol_value = 0;
|
||||
|
||||
//Search correlation with Neuman-Hofman Code (see IS-GPS-705D)
|
||||
if(sym_hist.size() == GPS_L5_NH_CODE_LENGTH)
|
||||
{
|
||||
for(int i = 0; i < GPS_L5_NH_CODE_LENGTH; i++)
|
||||
{
|
||||
if((bits_NH[i] * sym_hist.at(i)) > 0.0) {corr_NH += 1;}
|
||||
else {corr_NH -= 1;}
|
||||
}
|
||||
if(abs(corr_NH) == GPS_L5_NH_CODE_LENGTH)
|
||||
{
|
||||
sync_NH = true;
|
||||
if(corr_NH > 0) {symbol_value = 1;}
|
||||
else {symbol_value = -1;}
|
||||
new_sym = true;
|
||||
sym_hist.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
sym_hist.pop_front();
|
||||
sync_NH = false;
|
||||
new_sym = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool flag_new_cnav_frame = false;
|
||||
cnav_msg_t msg;
|
||||
u32 delay = 0;
|
||||
|
||||
//add the symbol to the decoder
|
||||
if(new_sym)
|
||||
{
|
||||
u8 symbol_clip = static_cast<u8>(symbol_value > 0) * 255;
|
||||
flag_new_cnav_frame = cnav_msg_decoder_add_symbol(&d_cnav_decoder, symbol_clip, &msg, &delay);
|
||||
new_sym = false;
|
||||
}
|
||||
//2. Add the telemetry decoder information
|
||||
//check if new CNAV frame is available
|
||||
if (flag_new_cnav_frame == true)
|
||||
{
|
||||
std::bitset<GPS_L5_CNAV_DATA_PAGE_BITS> raw_bits;
|
||||
//Expand packet bits to bitsets. Notice the reverse order of the bits sequence, required by the CNAV message decoder
|
||||
for (u32 i = 0; i < GPS_L5_CNAV_DATA_PAGE_BITS ; i++)
|
||||
{
|
||||
raw_bits[GPS_L5_CNAV_DATA_PAGE_BITS - 1 - i] = ((msg.raw_msg[i/8] >> (7 - i%8)) & 1u);
|
||||
}
|
||||
|
||||
d_CNAV_Message.decode_page(raw_bits);
|
||||
|
||||
//Push the new navigation data to the queues
|
||||
if (d_CNAV_Message.have_new_ephemeris() == true)
|
||||
{
|
||||
// get ephemeris object for this SV
|
||||
std::shared_ptr<Gps_CNAV_Ephemeris> tmp_obj = std::make_shared<Gps_CNAV_Ephemeris>(d_CNAV_Message.get_ephemeris());
|
||||
std::cout << "New GPS L5 CNAV message received: ephemeris from satellite " << d_satellite << std::endl;
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
|
||||
}
|
||||
if (d_CNAV_Message.have_new_iono() == true)
|
||||
{
|
||||
std::shared_ptr<Gps_CNAV_Iono> tmp_obj = std::make_shared<Gps_CNAV_Iono>(d_CNAV_Message.get_iono());
|
||||
std::cout << "New GPS L5 CNAV message received: iono model parameters from satellite " << d_satellite << std::endl;
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
}
|
||||
|
||||
if (d_CNAV_Message.have_new_utc_model() == true)
|
||||
{
|
||||
std::shared_ptr<Gps_CNAV_Utc_Model> tmp_obj = std::make_shared<Gps_CNAV_Utc_Model>(d_CNAV_Message.get_utc_model());
|
||||
std::cout << "New GPS L5 CNAV message received: UTC model parameters from satellite " << d_satellite << std::endl;
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
}
|
||||
|
||||
//update TOW at the preamble instant
|
||||
d_TOW_at_Preamble = static_cast<double>(msg.tow) * 6.0;
|
||||
//* The time of the last input symbol can be computed from the message ToW and
|
||||
//* delay by the formulae:
|
||||
//* \code
|
||||
//* symbolTime_ms = msg->tow * 6000 + *pdelay * 10
|
||||
d_TOW_at_current_symbol = (static_cast<double>(msg.tow) * 6.0) + (static_cast<double>(delay) + 12.0) * GPS_L5i_SYMBOL_PERIOD;
|
||||
d_TOW_at_current_symbol = floor(d_TOW_at_current_symbol * 1000.0) / 1000.0;
|
||||
d_flag_valid_word = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_TOW_at_current_symbol += GPS_L5i_PERIOD;
|
||||
if (current_synchro_data.Flag_valid_symbol_output == false)
|
||||
{
|
||||
d_flag_valid_word = false;
|
||||
}
|
||||
}
|
||||
current_synchro_data.TOW_at_current_symbol_s = d_TOW_at_current_symbol;
|
||||
current_synchro_data.Flag_valid_word = d_flag_valid_word;
|
||||
|
||||
if(d_dump == true)
|
||||
{
|
||||
// MULTIPLEXED FILE RECORDING - Record results to file
|
||||
try
|
||||
{
|
||||
double tmp_double;
|
||||
unsigned long int tmp_ulong_int;
|
||||
tmp_double = d_TOW_at_current_symbol;
|
||||
d_dump_file.write(reinterpret_cast<char*>(&tmp_double), sizeof(double));
|
||||
tmp_ulong_int = current_synchro_data.Tracking_sample_counter;
|
||||
d_dump_file.write(reinterpret_cast<char*>(&tmp_ulong_int), sizeof(unsigned long int));
|
||||
tmp_double = d_TOW_at_Preamble;
|
||||
d_dump_file.write(reinterpret_cast<char*>(&tmp_double), sizeof(double));
|
||||
}
|
||||
catch (const std::ifstream::failure & e)
|
||||
{
|
||||
LOG(WARNING) << "Exception writing Telemetry GPS L5 dump file " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
//3. Make the output (copy the object contents to the GNURadio reserved memory)
|
||||
out[0] = current_synchro_data;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void gps_l5_telemetry_decoder_cc::set_satellite(const Gnss_Satellite & satellite)
|
||||
{
|
||||
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
||||
LOG(INFO) << "GPS L5 CNAV telemetry decoder in channel " << this->d_channel << " set to satellite " << d_satellite;
|
||||
d_CNAV_Message.reset();
|
||||
}
|
||||
|
||||
|
||||
void gps_l5_telemetry_decoder_cc::set_channel(int channel)
|
||||
{
|
||||
d_channel = channel;
|
||||
d_CNAV_Message.reset();
|
||||
LOG(INFO) << "GPS L5 CNAV channel set to " << channel;
|
||||
// ############# ENABLE DATA FILE LOG #################
|
||||
if (d_dump == true)
|
||||
{
|
||||
if (d_dump_file.is_open() == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
d_dump_filename = "telemetry_L5_";
|
||||
d_dump_filename.append(boost::lexical_cast<std::string>(d_channel));
|
||||
d_dump_filename.append(".dat");
|
||||
d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
|
||||
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
|
||||
LOG(INFO) << "Telemetry decoder dump enabled on channel " << d_channel
|
||||
<< " Log file: " << d_dump_filename.c_str();
|
||||
}
|
||||
catch (const std::ifstream::failure &e)
|
||||
{
|
||||
LOG(WARNING) << "channel " << d_channel << " Exception opening Telemetry GPS L5 dump file " << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/*!
|
||||
* \file gps_l5_telemetry_decoder_cc.h
|
||||
* \brief Interface of a CNAV message demodulator block based on
|
||||
* Kay Borre book MATLAB-based GPS receiver
|
||||
* \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2017 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_GPS_L5_TELEMETRY_DECODER_CC_H
|
||||
#define GNSS_SDR_GPS_L5_TELEMETRY_DECODER_CC_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <deque>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <gnuradio/block.h>
|
||||
#include "gnss_satellite.h"
|
||||
#include "gps_cnav_navigation_message.h"
|
||||
#include "concurrent_queue.h"
|
||||
|
||||
extern "C" {
|
||||
#include "cnav_msg.h"
|
||||
#include "edc.h"
|
||||
#include "bits.h"
|
||||
}
|
||||
|
||||
#include "GPS_L5.h"
|
||||
|
||||
class gps_l5_telemetry_decoder_cc;
|
||||
|
||||
typedef boost::shared_ptr<gps_l5_telemetry_decoder_cc> gps_l5_telemetry_decoder_cc_sptr;
|
||||
|
||||
gps_l5_telemetry_decoder_cc_sptr
|
||||
gps_l5_make_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump);
|
||||
|
||||
/*!
|
||||
* \brief This class implements a GPS L5 Telemetry decoder
|
||||
*
|
||||
*/
|
||||
class gps_l5_telemetry_decoder_cc : public gr::block
|
||||
{
|
||||
public:
|
||||
~gps_l5_telemetry_decoder_cc();
|
||||
void set_satellite(const Gnss_Satellite & satellite); //!< Set satellite PRN
|
||||
void set_channel(int channel); //!< Set receiver's channel
|
||||
int general_work (int noutput_items, gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
|
||||
|
||||
|
||||
private:
|
||||
friend gps_l5_telemetry_decoder_cc_sptr
|
||||
gps_l5_make_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump);
|
||||
gps_l5_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump);
|
||||
|
||||
bool d_dump;
|
||||
Gnss_Satellite d_satellite;
|
||||
int d_channel;
|
||||
|
||||
std::string d_dump_filename;
|
||||
std::ofstream d_dump_file;
|
||||
|
||||
cnav_msg_decoder_t d_cnav_decoder;
|
||||
|
||||
double d_TOW_at_current_symbol;
|
||||
double d_TOW_at_Preamble;
|
||||
bool d_flag_valid_word;
|
||||
|
||||
Gps_CNAV_Navigation_Message d_CNAV_Message;
|
||||
double bits_NH[GPS_L5_NH_CODE_LENGTH];
|
||||
std::deque<double> sym_hist;
|
||||
bool sync_NH;
|
||||
bool new_sym;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -49,9 +49,9 @@
|
||||
*/
|
||||
/** Viterbi decoder reversed polynomial A */
|
||||
#define GPS_L2C_V27_POLY_A (0x4F) /* 0b01001111 - reversed 0171*/
|
||||
|
||||
/** Viterbi decoder reversed polynomial B */
|
||||
#define GPS_L2C_V27_POLY_B (0x6D) /* 0b01101101 - reversed 0133 */
|
||||
|
||||
/*
|
||||
* GPS L2C message constants.
|
||||
*/
|
||||
@ -67,7 +67,7 @@
|
||||
/** GPS LC2 CNAV CRC length in bits */
|
||||
#define GPS_CNAV_MSG_CRC_LENGTH (24)
|
||||
/** GPS L2C CNAV message payload length in bits */
|
||||
#define GPS_CNAV_MSG_DATA_LENGTH (GPS_CNAV_MSG_LENGTH-GPS_CNAV_MSG_CRC_LENGTH)
|
||||
#define GPS_CNAV_MSG_DATA_LENGTH (GPS_CNAV_MSG_LENGTH - GPS_CNAV_MSG_CRC_LENGTH)
|
||||
/** GPS L2C CNAV message lock detector threshold */
|
||||
#define GPS_CNAV_LOCK_MAX_CRC_FAILS (10)
|
||||
|
||||
@ -411,7 +411,8 @@ void cnav_msg_decoder_init(cnav_msg_decoder_t *dec)
|
||||
* The time of the last input symbol can be computed from the message ToW and
|
||||
* delay by the formulae:
|
||||
* \code
|
||||
* symbolTime_ms = msg->tow * 6000 + *pdelay * 20
|
||||
* symbolTime_ms = msg->tow * 6000 + *pdelay * 20 (L2)
|
||||
* symbolTime_ms = msg->tow * 6000 + *pdelay * 10 (L5)
|
||||
* \endcode
|
||||
*
|
||||
* \param[in,out] dec Decoder object.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* \file gps_l5idll_pll_tracking.cc
|
||||
* \file gps_l5i_dll_pll_tracking.cc
|
||||
* \brief Interface of an adapter of a DLL+PLL tracking loop block
|
||||
* for GPS L5i to a TrackingInterface
|
||||
* \author Javier Arribas, 2017. jarribas(at)cttc.es
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
return role_;
|
||||
}
|
||||
|
||||
//! Returns "GPS_L2_M_DLL_PLL_Tracking"
|
||||
//! Returns "GPS_L5i_DLL_PLL_Tracking"
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "GPS_L5i_DLL_PLL_Tracking";
|
||||
|
@ -642,8 +642,8 @@ int Galileo_E5a_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribute
|
||||
// The first Prompt output not equal to 0 is synchronized with the transition of a navigation data bit.
|
||||
if (d_secondary_lock && d_first_transition)
|
||||
{
|
||||
current_synchro_data.Prompt_I = static_cast<double>((d_Prompt_data).real());
|
||||
current_synchro_data.Prompt_Q = static_cast<double>((d_Prompt_data).imag());
|
||||
current_synchro_data.Prompt_I = static_cast<double>(d_Prompt_data.real());
|
||||
current_synchro_data.Prompt_Q = static_cast<double>(d_Prompt_data.imag());
|
||||
current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples;
|
||||
current_synchro_data.Code_phase_samples = d_rem_code_phase_samples;
|
||||
current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad;
|
||||
|
@ -257,14 +257,14 @@ void gps_l5i_dll_pll_tracking_cc::start_tracking()
|
||||
sys = sys_.substr(0,1);
|
||||
|
||||
// DEBUG OUTPUT
|
||||
std::cout << "Tracking of GPS L2CM signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl;
|
||||
LOG(INFO) << "Starting GPS L2CM tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel;
|
||||
std::cout << "Tracking of GPS L5i signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl;
|
||||
LOG(INFO) << "Starting GPS L5i tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel;
|
||||
|
||||
// enable tracking
|
||||
d_pull_in = true;
|
||||
d_enable_tracking = true;
|
||||
|
||||
LOG(INFO) << "GPS L2CM PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz
|
||||
LOG(INFO) << "GPS L5i PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz
|
||||
<< " Code Phase correction [samples]=" << delay_correction_samples
|
||||
<< " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples;
|
||||
}
|
||||
|
@ -90,6 +90,7 @@
|
||||
#include "gps_l5i_dll_pll_tracking.h"
|
||||
#include "gps_l1_ca_telemetry_decoder.h"
|
||||
#include "gps_l2c_telemetry_decoder.h"
|
||||
#include "gps_l5_telemetry_decoder.h"
|
||||
#include "galileo_e1b_telemetry_decoder.h"
|
||||
#include "galileo_e5a_telemetry_decoder.h"
|
||||
#include "sbas_l1_telemetry_decoder.h"
|
||||
@ -239,6 +240,7 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetObservables(std::shared
|
||||
Galileo_channels += configuration->property("Channels_5X.count", 0);
|
||||
unsigned int GPS_channels = configuration->property("Channels_1C.count", 0);
|
||||
GPS_channels += configuration->property("Channels_2S.count", 0);
|
||||
GPS_channels += configuration->property("Channels_L5.count", 0);
|
||||
return GetBlock(configuration, "Observables", implementation, Galileo_channels + GPS_channels, Galileo_channels + GPS_channels);
|
||||
}
|
||||
|
||||
@ -253,6 +255,7 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetPVT(std::shared_ptr<Con
|
||||
Galileo_channels += configuration->property("Channels_5X.count", 0);
|
||||
unsigned int GPS_channels = configuration->property("Channels_1C.count", 0);
|
||||
GPS_channels += configuration->property("Channels_2S.count", 0);
|
||||
GPS_channels += configuration->property("Channels_L5.count", 0);
|
||||
return GetBlock(configuration, "PVT", implementation, Galileo_channels + GPS_channels, 0);
|
||||
}
|
||||
|
||||
@ -524,6 +527,74 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_5X(
|
||||
return channel_;
|
||||
}
|
||||
|
||||
//********* GPS L5 CHANNEL *****************
|
||||
std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_L5(
|
||||
std::shared_ptr<ConfigurationInterface> configuration,
|
||||
std::string acq, std::string trk, std::string tlm, int channel,
|
||||
boost::shared_ptr<gr::msg_queue> queue)
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << channel;
|
||||
std::string id = stream.str();
|
||||
LOG(INFO) << "Instantiating Channel " << id << " with Acquisition Implementation: "
|
||||
<< acq << ", Tracking Implementation: " << trk << ", Telemetry Decoder implementation: " << tlm;
|
||||
std::string aux = configuration->property("Acquisition_L5" + boost::lexical_cast<std::string>(channel) + ".implementation", std::string("W"));
|
||||
std::string appendix1;
|
||||
if(aux.compare("W") != 0)
|
||||
{
|
||||
appendix1 = boost::lexical_cast<std::string>(channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
appendix1 = "";
|
||||
}
|
||||
aux = configuration->property("Tracking_L5" + boost::lexical_cast<std::string>(channel) + ".implementation", std::string("W"));
|
||||
std::string appendix2;
|
||||
if(aux.compare("W") != 0)
|
||||
{
|
||||
appendix2 = boost::lexical_cast<std::string>(channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
appendix2 = "";
|
||||
}
|
||||
aux = configuration->property("TelemetryDecoder_L5" + boost::lexical_cast<std::string>(channel) + ".implementation", std::string("W"));
|
||||
std::string appendix3;
|
||||
if(aux.compare("W") != 0)
|
||||
{
|
||||
appendix3 = boost::lexical_cast<std::string>(channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
appendix3 = "";
|
||||
}
|
||||
// Automatically detect input data type
|
||||
std::shared_ptr<InMemoryConfiguration> config;
|
||||
config = std::make_shared<InMemoryConfiguration>();
|
||||
std::string default_item_type = "gr_complex";
|
||||
std::string acq_item_type = configuration->property("Acquisition_L5" + appendix1 + ".item_type", default_item_type);
|
||||
std::string trk_item_type = configuration->property("Tracking_L5" + appendix2 + ".item_type", default_item_type);
|
||||
if(acq_item_type.compare(trk_item_type))
|
||||
{
|
||||
LOG(ERROR) << "Acquisition and Tracking blocks must have the same input data type!";
|
||||
}
|
||||
config->set_property("Channel.item_type", acq_item_type);
|
||||
|
||||
std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue);
|
||||
std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_L5" + appendix1, acq, 1, 0);
|
||||
std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_L5" + appendix2, trk, 1, 1);
|
||||
std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_L5" + appendix3, tlm, 1, 1);
|
||||
|
||||
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, std::move(pass_through_),
|
||||
std::move(acq_),
|
||||
std::move(trk_),
|
||||
std::move(tlm_),
|
||||
"Channel", "L5", queue));
|
||||
|
||||
return channel_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::unique_ptr<std::vector<std::unique_ptr<GNSSBlockInterface>>> GNSSBlockFactory::GetChannels(
|
||||
std::shared_ptr<ConfigurationInterface> configuration, boost::shared_ptr<gr::msg_queue> queue)
|
||||
@ -539,11 +610,13 @@ std::unique_ptr<std::vector<std::unique_ptr<GNSSBlockInterface>>> GNSSBlockFacto
|
||||
unsigned int Channels_2S_count = configuration->property("Channels_2S.count", 0);
|
||||
unsigned int Channels_1B_count = configuration->property("Channels_1B.count", 0);
|
||||
unsigned int Channels_5X_count = configuration->property("Channels_5X.count", 0);
|
||||
unsigned int Channels_L5_count = configuration->property("Channels_L5.count", 0);
|
||||
|
||||
unsigned int total_channels = Channels_1C_count +
|
||||
Channels_2S_count +
|
||||
Channels_1B_count +
|
||||
Channels_5X_count;
|
||||
Channels_5X_count +
|
||||
Channels_L5_count;
|
||||
std::unique_ptr<std::vector<std::unique_ptr<GNSSBlockInterface>>> channels(new std::vector<std::unique_ptr<GNSSBlockInterface>>(total_channels));
|
||||
|
||||
//**************** GPS L1 C/A CHANNELS **********************
|
||||
@ -606,7 +679,34 @@ std::unique_ptr<std::vector<std::unique_ptr<GNSSBlockInterface>>> GNSSBlockFacto
|
||||
queue));
|
||||
channel_absolute_id++;
|
||||
}
|
||||
//**************** GPS L5 CHANNELS **********************
|
||||
LOG(INFO)<< "Getting " << Channels_L5_count << " GPS L5 channels";
|
||||
tracking_implementation = configuration->property("Tracking_L5.implementation", default_implementation);
|
||||
telemetry_decoder_implementation = configuration->property("TelemetryDecoder_L5.implementation", default_implementation);
|
||||
acquisition_implementation = configuration->property("Acquisition_L5.implementation", default_implementation);
|
||||
for (unsigned int i = 0; i < Channels_L5_count; i++)
|
||||
{
|
||||
//(i.e. Acquisition_1C0.implementation=xxxx)
|
||||
std::string acquisition_implementation_specific = configuration->property(
|
||||
"Acquisition_L5" + boost::lexical_cast<std::string>(channel_absolute_id) + ".implementation",
|
||||
acquisition_implementation);
|
||||
//(i.e. Tracking_1C0.implementation=xxxx)
|
||||
std::string tracking_implementation_specific = configuration->property(
|
||||
"Tracking_L5" + boost::lexical_cast<std::string>(channel_absolute_id) + ".implementation",
|
||||
tracking_implementation);
|
||||
std::string telemetry_decoder_implementation_specific = configuration->property(
|
||||
"TelemetryDecoder_L5" + boost::lexical_cast<std::string>(channel_absolute_id) + ".implementation",
|
||||
telemetry_decoder_implementation);
|
||||
|
||||
// Push back the channel to the vector of channels
|
||||
channels->at(channel_absolute_id) = std::move(GetChannel_L5(configuration,
|
||||
acquisition_implementation_specific,
|
||||
tracking_implementation_specific,
|
||||
telemetry_decoder_implementation_specific,
|
||||
channel_absolute_id,
|
||||
queue));
|
||||
channel_absolute_id++;
|
||||
}
|
||||
//**************** GALILEO E1 B (I/NAV OS) CHANNELS **********************
|
||||
|
||||
LOG(INFO) << "Getting " << Channels_1B_count << " GALILEO E1 B (I/NAV OS) channels";
|
||||
@ -1114,6 +1214,12 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation.compare("GPS_L5_Telemetry_Decoder") == 0)
|
||||
{
|
||||
std::unique_ptr<GNSSBlockInterface> block_(new GpsL5TelemetryDecoder(configuration.get(), role, in_streams,
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation.compare("Galileo_E1B_Telemetry_Decoder") == 0)
|
||||
{
|
||||
std::unique_ptr<GNSSBlockInterface> block_(new GalileoE1BTelemetryDecoder(configuration.get(), role, in_streams,
|
||||
@ -1400,6 +1506,12 @@ std::unique_ptr<TelemetryDecoderInterface> GNSSBlockFactory::GetTlmBlock(
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation.compare("GPS_L5_Telemetry_Decoder") == 0)
|
||||
{
|
||||
std::unique_ptr<TelemetryDecoderInterface> block_(new GpsL5TelemetryDecoder(configuration.get(), role, in_streams,
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Log fatal. This causes execution to stop.
|
||||
|
@ -94,6 +94,10 @@ private:
|
||||
std::string acq, std::string trk, std::string tlm, int channel,
|
||||
boost::shared_ptr<gr::msg_queue> queue);
|
||||
|
||||
std::unique_ptr<GNSSBlockInterface> GetChannel_L5(std::shared_ptr<ConfigurationInterface> configuration,
|
||||
std::string acq, std::string trk, std::string tlm, int channel,
|
||||
boost::shared_ptr<gr::msg_queue> queue);
|
||||
|
||||
std::unique_ptr<AcquisitionInterface> GetAcqBlock(
|
||||
std::shared_ptr<ConfigurationInterface> configuration,
|
||||
std::string role,
|
||||
|
@ -579,7 +579,8 @@ void GNSSFlowgraph::set_signals_list()
|
||||
unsigned int total_channels = configuration_->property("Channels_1C.count", 0) +
|
||||
configuration_->property("Channels_2S.count", 0) +
|
||||
configuration_->property("Channels_1B.count", 0) +
|
||||
configuration_->property("Channels_5X.count", 0);
|
||||
configuration_->property("Channels_5X.count", 0) +
|
||||
configuration_->property("Channels_L5.count", 0);
|
||||
|
||||
/*
|
||||
* Loop to create the list of GNSS Signals
|
||||
@ -672,6 +673,19 @@ void GNSSFlowgraph::set_signals_list()
|
||||
}
|
||||
}
|
||||
|
||||
if (configuration_->property("Channels_L5.count", 0) > 0)
|
||||
{
|
||||
/*
|
||||
* Loop to create GPS L5 signals
|
||||
*/
|
||||
for (available_gnss_prn_iter = available_gps_prn.cbegin();
|
||||
available_gnss_prn_iter != available_gps_prn.cend();
|
||||
available_gnss_prn_iter++)
|
||||
{
|
||||
available_GNSS_signals_.push_back(Gnss_Signal(Gnss_Satellite(std::string("GPS"),
|
||||
*available_gnss_prn_iter), std::string("L5")));
|
||||
}
|
||||
}
|
||||
if (configuration_->property("Channels_SBAS.count", 0) > 0)
|
||||
{
|
||||
/*
|
||||
@ -725,7 +739,7 @@ void GNSSFlowgraph::set_signals_list()
|
||||
{
|
||||
std::string gnss_signal = (configuration_->property("Channel" + boost::lexical_cast<std::string>(i) + ".signal", std::string("1C")));
|
||||
std::string gnss_system;
|
||||
if((gnss_signal.compare("1C") == 0) or (gnss_signal.compare("2S") == 0) ) gnss_system = "GPS";
|
||||
if((gnss_signal.compare("1C") == 0) or (gnss_signal.compare("2S") == 0) or (gnss_signal.compare("L5") == 0)) gnss_system = "GPS";
|
||||
if((gnss_signal.compare("1B") == 0) or (gnss_signal.compare("5X") == 0) ) gnss_system = "Galileo";
|
||||
unsigned int sat = configuration_->property("Channel" + boost::lexical_cast<std::string>(i) + ".satellite", 0);
|
||||
LOG(INFO) << "Channel " << i << " system " << gnss_system << ", signal " << gnss_signal <<", sat "<<sat;
|
||||
|
183
src/core/system_parameters/GPS_CNAV.h
Normal file
183
src/core/system_parameters/GPS_CNAV.h
Normal file
@ -0,0 +1,183 @@
|
||||
/*!
|
||||
* \file GPS_CNAV.h
|
||||
* \brief Defines parameters for GPS CNAV
|
||||
* \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2017 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GNSS_SDR_GPS_CNAV_H_
|
||||
#define GNSS_SDR_GPS_CNAV_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <utility> // std::pair
|
||||
#include "MATH_CONSTANTS.h"
|
||||
|
||||
// CNAV GPS NAVIGATION MESSAGE STRUCTURE
|
||||
// NAVIGATION MESSAGE FIELDS POSITIONS (from IS-GPS-200E Appendix III)
|
||||
|
||||
#define GPS_CNAV_PREAMBLE {1, 0, 0, 0, 1, 0, 1, 1}
|
||||
#define GPS_CNAV_PREAMBLE_STR "10001011"
|
||||
#define GPS_CNAV_INV_PREAMBLE_STR "01110100"
|
||||
|
||||
const int GPS_CNAV_DATA_PAGE_BITS = 300;
|
||||
|
||||
// common to all messages
|
||||
const std::vector<std::pair<int,int> > CNAV_PRN( { {9,6} } );
|
||||
const std::vector<std::pair<int,int> > CNAV_MSG_TYPE( { {15,6} } );
|
||||
const std::vector<std::pair<int,int> > CNAV_TOW( { {21,17} } ); //GPS Time Of Week in seconds
|
||||
const double CNAV_TOW_LSB = 6.0;
|
||||
const std::vector<std::pair<int,int> > CNAV_ALERT_FLAG( { {38,1} } );
|
||||
|
||||
// MESSAGE TYPE 10 (Ephemeris 1)
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_WN({{39,13}});
|
||||
const std::vector<std::pair<int,int> > CNAV_HEALTH({{52,3}});
|
||||
const std::vector<std::pair<int,int> > CNAV_TOP1({{55,11}});
|
||||
const double CNAV_TOP1_LSB = 300.0;
|
||||
const std::vector<std::pair<int,int> > CNAV_URA({{66,5}});
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_TOE1({{71,11}});
|
||||
const double CNAV_TOE1_LSB = 300.0;
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_DELTA_A({{82,26}}); //Relative to AREF = 26,559,710 meters
|
||||
const double CNAV_DELTA_A_LSB = TWO_N9;
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_A_DOT({{108,25}});
|
||||
const double CNAV_A_DOT_LSB = TWO_N21;
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_DELTA_N0({{133,17}});
|
||||
const double CNAV_DELTA_N0_LSB = TWO_N44*PI; //semi-circles to radians
|
||||
const std::vector<std::pair<int,int> > CNAV_DELTA_N0_DOT({{150,23}});
|
||||
const double CNAV_DELTA_N0_DOT_LSB = TWO_N57*PI;//semi-circles to radians
|
||||
const std::vector<std::pair<int,int> > CNAV_M0({{173,33}});
|
||||
const double CNAV_M0_LSB = TWO_N32*PI;//semi-circles to radians
|
||||
const std::vector<std::pair<int,int> > CNAV_E_ECCENTRICITY({{206,33}});
|
||||
const double CNAV_E_ECCENTRICITY_LSB = TWO_N34;
|
||||
const std::vector<std::pair<int,int> > CNAV_OMEGA({{239,33}});
|
||||
const double CNAV_OMEGA_LSB = TWO_N32*PI;//semi-circles to radians
|
||||
const std::vector<std::pair<int,int> > CNAV_INTEGRITY_FLAG({{272,1}});
|
||||
const std::vector<std::pair<int,int> > CNAV_L2_PHASING_FLAG({{273,1}});
|
||||
|
||||
// MESSAGE TYPE 11 (Ephemeris 2)
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_TOE2({{39,11}});
|
||||
const double CNAV_TOE2_LSB = 300.0;
|
||||
const std::vector<std::pair<int,int> > CNAV_OMEGA0({{50,33}});
|
||||
const double CNAV_OMEGA0_LSB = TWO_N32*PI;//semi-circles to radians
|
||||
const std::vector<std::pair<int,int> > CNAV_I0({{83,33}});
|
||||
const double CNAV_I0_LSB = TWO_N32*PI;//semi-circles to radians
|
||||
const std::vector<std::pair<int,int> > CNAV_DELTA_OMEGA_DOT({{116,17}}); //Relative to REF = -2.6 x 10-9 semi-circles/second.
|
||||
const double CNAV_DELTA_OMEGA_DOT_LSB = TWO_N44*PI;//semi-circles to radians
|
||||
const std::vector<std::pair<int,int> > CNAV_I0_DOT({{133,15}});
|
||||
const double CNAV_I0_DOT_LSB = TWO_N44*PI;//semi-circles to radians
|
||||
const std::vector<std::pair<int,int> > CNAV_CIS({{148,16}});
|
||||
const double CNAV_CIS_LSB = TWO_N30;
|
||||
const std::vector<std::pair<int,int> > CNAV_CIC({{164,16}});
|
||||
const double CNAV_CIC_LSB = TWO_N30;
|
||||
const std::vector<std::pair<int,int> > CNAV_CRS({{180,24}});
|
||||
const double CNAV_CRS_LSB = TWO_N8;
|
||||
const std::vector<std::pair<int,int> > CNAV_CRC({{204,24}});
|
||||
const double CNAV_CRC_LSB = TWO_N8;
|
||||
const std::vector<std::pair<int,int> > CNAV_CUS({{228,21}});
|
||||
const double CNAV_CUS_LSB = TWO_N30;
|
||||
const std::vector<std::pair<int,int> > CNAV_CUC({{249,21}});
|
||||
const double CNAV_CUC_LSB = TWO_N30;
|
||||
|
||||
|
||||
// MESSAGE TYPE 30 (CLOCK, IONO, GRUP DELAY)
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_TOP2({{39,11}});
|
||||
const double CNAV_TOP2_LSB = 300.0;
|
||||
const std::vector<std::pair<int,int> > CNAV_URA_NED0({{50,5}});
|
||||
const std::vector<std::pair<int,int> > CNAV_URA_NED1({{55,3}});
|
||||
const std::vector<std::pair<int,int> > CNAV_URA_NED2({{58,3}});
|
||||
const std::vector<std::pair<int,int> > CNAV_TOC({{61,11}});
|
||||
const double CNAV_TOC_LSB = 300.0;
|
||||
const std::vector<std::pair<int,int> > CNAV_AF0({{72,26}});
|
||||
const double CNAV_AF0_LSB = TWO_N60;
|
||||
const std::vector<std::pair<int,int> > CNAV_AF1({{98,20}});
|
||||
const double CNAV_AF1_LSB = TWO_N48;
|
||||
const std::vector<std::pair<int,int> > CNAV_AF2({{118,10}});
|
||||
const double CNAV_AF2_LSB = TWO_N35;
|
||||
const std::vector<std::pair<int,int> > CNAV_TGD({{128,13}});
|
||||
const double CNAV_TGD_LSB = TWO_N35;
|
||||
const std::vector<std::pair<int,int> > CNAV_ISCL1({{141,13}});
|
||||
const double CNAV_ISCL1_LSB = TWO_N35;
|
||||
const std::vector<std::pair<int,int> > CNAV_ISCL2({{154,13}});
|
||||
const double CNAV_ISCL2_LSB = TWO_N35;
|
||||
const std::vector<std::pair<int,int> > CNAV_ISCL5I({{167,13}});
|
||||
const double CNAV_ISCL5I_LSB = TWO_N35;
|
||||
const std::vector<std::pair<int,int> > CNAV_ISCL5Q({{180,13}});
|
||||
const double CNAV_ISCL5Q_LSB = TWO_N35;
|
||||
//Ionospheric parameters
|
||||
const std::vector<std::pair<int,int> > CNAV_ALPHA0({{193,8}});
|
||||
const double CNAV_ALPHA0_LSB = TWO_N30;
|
||||
const std::vector<std::pair<int,int> > CNAV_ALPHA1({{201,8}});
|
||||
const double CNAV_ALPHA1_LSB = TWO_N27;
|
||||
const std::vector<std::pair<int,int> > CNAV_ALPHA2({{209,8}});
|
||||
const double CNAV_ALPHA2_LSB = TWO_N24;
|
||||
const std::vector<std::pair<int,int> > CNAV_ALPHA3({{217,8}});
|
||||
const double CNAV_ALPHA3_LSB = TWO_N24;
|
||||
const std::vector<std::pair<int,int> > CNAV_BETA0({{225,8}});
|
||||
const double CNAV_BETA0_LSB = TWO_P11;
|
||||
const std::vector<std::pair<int,int> > CNAV_BETA1({{233,8}});
|
||||
const double CNAV_BETA1_LSB = TWO_P14;
|
||||
const std::vector<std::pair<int,int> > CNAV_BETA2({{241,8}});
|
||||
const double CNAV_BETA2_LSB = TWO_P16;
|
||||
const std::vector<std::pair<int,int> > CNAV_BETA3({{249,8}});
|
||||
const double CNAV_BETA3_LSB = TWO_P16;
|
||||
const std::vector<std::pair<int,int> > CNAV_WNOP({{257,8}});
|
||||
|
||||
|
||||
// MESSAGE TYPE 33 (CLOCK and UTC)
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_A0({{128,16}});
|
||||
const double CNAV_A0_LSB = TWO_N35;
|
||||
const std::vector<std::pair<int,int> > CNAV_A1({{144,13}});
|
||||
const double CNAV_A1_LSB = TWO_N51;
|
||||
const std::vector<std::pair<int,int> > CNAV_A2({{157,7}});
|
||||
const double CNAV_A2_LSB = TWO_N68;
|
||||
const std::vector<std::pair<int,int> > CNAV_DELTA_TLS({{164,8}});
|
||||
const double CNAV_DELTA_TLS_LSB = 1;
|
||||
const std::vector<std::pair<int,int> > CNAV_TOT({{172,16}});
|
||||
const double CNAV_TOT_LSB = TWO_P4;
|
||||
const std::vector<std::pair<int,int> > CNAV_WN_OT({{188,13}});
|
||||
const double CNAV_WN_OT_LSB = 1;
|
||||
const std::vector<std::pair<int,int> > CNAV_WN_LSF({{201,13}});
|
||||
const double CNAV_WN_LSF_LSB = 1;
|
||||
const std::vector<std::pair<int,int> > CNAV_DN({{214,4}});
|
||||
const double CNAV_DN_LSB = 1;
|
||||
const std::vector<std::pair<int,int> > CNAV_DELTA_TLSF({{218,8}});
|
||||
const double CNAV_DELTA_TLSF_LSB = 1;
|
||||
|
||||
|
||||
// TODO: Add more frames (Almanac, etc...)
|
||||
|
||||
|
||||
|
||||
#endif /* GNSS_SDR_GPS_CNAV_H_ */
|
@ -37,6 +37,7 @@
|
||||
#include <utility> // std::pair
|
||||
#include "MATH_CONSTANTS.h"
|
||||
#include "gnss_frequencies.h"
|
||||
#include "GPS_CNAV.h"
|
||||
|
||||
// Physical constants
|
||||
const double GPS_L2_C_m_s = 299792458.0; //!< The speed of light, [m/s]
|
||||
@ -92,152 +93,10 @@ const int32_t GPS_L2C_M_INIT_REG[115] =
|
||||
0706202440, 0705056276, 0020373522, 0746013617,
|
||||
0132720621, 0434015513, 0566721727, 0140633660};
|
||||
|
||||
// CNAV GPS NAVIGATION MESSAGE STRUCTURE
|
||||
// NAVIGATION MESSAGE FIELDS POSITIONS (from IS-GPS-200E Appendix III)
|
||||
|
||||
#define GPS_CNAV_PREAMBLE {1, 0, 0, 0, 1, 0, 1, 1}
|
||||
#define GPS_CNAV_PREAMBLE_STR "10001011"
|
||||
#define GPS_CNAV_INV_PREAMBLE_STR "01110100"
|
||||
|
||||
const int GPS_L2_CNAV_DATA_PAGE_BITS = 300; //!< GPS L2 CNAV page length, including preamble and CRC [bits]
|
||||
const int GPS_L2_SYMBOLS_PER_BIT = 2;
|
||||
const int GPS_L2_SAMPLES_PER_SYMBOL = 1;
|
||||
const int GPS_L2_CNAV_DATA_PAGE_SYMBOLS = 600;
|
||||
const int GPS_L2_CNAV_DATA_PAGE_DURATION_S = 12;
|
||||
|
||||
// common to all messages
|
||||
const std::vector<std::pair<int,int> > CNAV_PRN( { {9,6} } );
|
||||
const std::vector<std::pair<int,int> > CNAV_MSG_TYPE( { {15,6} } );
|
||||
const std::vector<std::pair<int,int> > CNAV_TOW( { {21,17} } ); //GPS Time Of Week in seconds
|
||||
const double CNAV_TOW_LSB = 6.0;
|
||||
const std::vector<std::pair<int,int> > CNAV_ALERT_FLAG( { {38,1} } );
|
||||
|
||||
// MESSAGE TYPE 10 (Ephemeris 1)
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_WN({{39,13}});
|
||||
const std::vector<std::pair<int,int> > CNAV_HEALTH({{52,3}});
|
||||
const std::vector<std::pair<int,int> > CNAV_TOP1({{55,11}});
|
||||
const double CNAV_TOP1_LSB = 300.0;
|
||||
const std::vector<std::pair<int,int> > CNAV_URA({{66,5}});
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_TOE1({{71,11}});
|
||||
const double CNAV_TOE1_LSB = 300.0;
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_DELTA_A({{82,26}}); //Relative to AREF = 26,559,710 meters
|
||||
const double CNAV_DELTA_A_LSB = TWO_N9;
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_A_DOT({{108,25}});
|
||||
const double CNAV_A_DOT_LSB = TWO_N21;
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_DELTA_N0({{133,17}});
|
||||
const double CNAV_DELTA_N0_LSB = TWO_N44*GPS_L2_PI; //semi-circles to radians
|
||||
const std::vector<std::pair<int,int> > CNAV_DELTA_N0_DOT({{150,23}});
|
||||
const double CNAV_DELTA_N0_DOT_LSB = TWO_N57*GPS_L2_PI;//semi-circles to radians
|
||||
const std::vector<std::pair<int,int> > CNAV_M0({{173,33}});
|
||||
const double CNAV_M0_LSB = TWO_N32*GPS_L2_PI;//semi-circles to radians
|
||||
const std::vector<std::pair<int,int> > CNAV_E_ECCENTRICITY({{206,33}});
|
||||
const double CNAV_E_ECCENTRICITY_LSB = TWO_N34;
|
||||
const std::vector<std::pair<int,int> > CNAV_OMEGA({{239,33}});
|
||||
const double CNAV_OMEGA_LSB = TWO_N32*GPS_L2_PI;//semi-circles to radians
|
||||
const std::vector<std::pair<int,int> > CNAV_INTEGRITY_FLAG({{272,1}});
|
||||
const std::vector<std::pair<int,int> > CNAV_L2_PHASING_FLAG({{273,1}});
|
||||
|
||||
// MESSAGE TYPE 11 (Ephemeris 2)
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_TOE2({{39,11}});
|
||||
const double CNAV_TOE2_LSB = 300.0;
|
||||
const std::vector<std::pair<int,int> > CNAV_OMEGA0({{50,33}});
|
||||
const double CNAV_OMEGA0_LSB = TWO_N32*GPS_L2_PI;//semi-circles to radians
|
||||
const std::vector<std::pair<int,int> > CNAV_I0({{83,33}});
|
||||
const double CNAV_I0_LSB = TWO_N32*GPS_L2_PI;//semi-circles to radians
|
||||
const std::vector<std::pair<int,int> > CNAV_DELTA_OMEGA_DOT({{116,17}}); //Relative to REF = -2.6 x 10-9 semi-circles/second.
|
||||
const double CNAV_DELTA_OMEGA_DOT_LSB = TWO_N44*GPS_L2_PI;//semi-circles to radians
|
||||
const std::vector<std::pair<int,int> > CNAV_I0_DOT({{133,15}});
|
||||
const double CNAV_I0_DOT_LSB = TWO_N44*GPS_L2_PI;//semi-circles to radians
|
||||
const std::vector<std::pair<int,int> > CNAV_CIS({{148,16}});
|
||||
const double CNAV_CIS_LSB = TWO_N30;
|
||||
const std::vector<std::pair<int,int> > CNAV_CIC({{164,16}});
|
||||
const double CNAV_CIC_LSB = TWO_N30;
|
||||
const std::vector<std::pair<int,int> > CNAV_CRS({{180,24}});
|
||||
const double CNAV_CRS_LSB = TWO_N8;
|
||||
const std::vector<std::pair<int,int> > CNAV_CRC({{204,24}});
|
||||
const double CNAV_CRC_LSB = TWO_N8;
|
||||
const std::vector<std::pair<int,int> > CNAV_CUS({{228,21}});
|
||||
const double CNAV_CUS_LSB = TWO_N30;
|
||||
const std::vector<std::pair<int,int> > CNAV_CUC({{249,21}});
|
||||
const double CNAV_CUC_LSB = TWO_N30;
|
||||
|
||||
|
||||
// MESSAGE TYPE 30 (CLOCK, IONO, GRUP DELAY)
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_TOP2({{39,11}});
|
||||
const double CNAV_TOP2_LSB = 300.0;
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_URA_NED0({{50,5}});
|
||||
const std::vector<std::pair<int,int> > CNAV_URA_NED1({{55,3}});
|
||||
const std::vector<std::pair<int,int> > CNAV_URA_NED2({{58,3}});
|
||||
const std::vector<std::pair<int,int> > CNAV_TOC({{61,11}});
|
||||
const double CNAV_TOC_LSB = 300.0;
|
||||
const std::vector<std::pair<int,int> > CNAV_AF0({{72,26}});
|
||||
const double CNAV_AF0_LSB = TWO_N60;
|
||||
const std::vector<std::pair<int,int> > CNAV_AF1({{98,20}});
|
||||
const double CNAV_AF1_LSB = TWO_N48;
|
||||
const std::vector<std::pair<int,int> > CNAV_AF2({{118,10}});
|
||||
const double CNAV_AF2_LSB = TWO_N35;
|
||||
const std::vector<std::pair<int,int> > CNAV_TGD({{128,13}});
|
||||
const double CNAV_TGD_LSB = TWO_N35;
|
||||
const std::vector<std::pair<int,int> > CNAV_ISCL1({{141,13}});
|
||||
const double CNAV_ISCL1_LSB = TWO_N35;
|
||||
const std::vector<std::pair<int,int> > CNAV_ISCL2({{154,13}});
|
||||
const double CNAV_ISCL2_LSB = TWO_N35;
|
||||
const std::vector<std::pair<int,int> > CNAV_ISCL5I({{167,13}});
|
||||
const double CNAV_ISCL5I_LSB = TWO_N35;
|
||||
const std::vector<std::pair<int,int> > CNAV_ISCL5Q({{180,13}});
|
||||
const double CNAV_ISCL5Q_LSB = TWO_N35;
|
||||
//Ionospheric parameters
|
||||
const std::vector<std::pair<int,int> > CNAV_ALPHA0({{193,8}});
|
||||
const double CNAV_ALPHA0_LSB = TWO_N30;
|
||||
const std::vector<std::pair<int,int> > CNAV_ALPHA1({{201,8}});
|
||||
const double CNAV_ALPHA1_LSB = TWO_N27;
|
||||
const std::vector<std::pair<int,int> > CNAV_ALPHA2({{209,8}});
|
||||
const double CNAV_ALPHA2_LSB = TWO_N24;
|
||||
const std::vector<std::pair<int,int> > CNAV_ALPHA3({{217,8}});
|
||||
const double CNAV_ALPHA3_LSB = TWO_N24;
|
||||
const std::vector<std::pair<int,int> > CNAV_BETA0({{225,8}});
|
||||
const double CNAV_BETA0_LSB = TWO_P11;
|
||||
const std::vector<std::pair<int,int> > CNAV_BETA1({{233,8}});
|
||||
const double CNAV_BETA1_LSB = TWO_P14;
|
||||
const std::vector<std::pair<int,int> > CNAV_BETA2({{241,8}});
|
||||
const double CNAV_BETA2_LSB = TWO_P16;
|
||||
const std::vector<std::pair<int,int> > CNAV_BETA3({{249,8}});
|
||||
const double CNAV_BETA3_LSB = TWO_P16;
|
||||
const std::vector<std::pair<int,int> > CNAV_WNOP({{257,8}});
|
||||
|
||||
|
||||
// MESSAGE TYPE 33 (CLOCK and UTC)
|
||||
|
||||
const std::vector<std::pair<int,int> > CNAV_A0({{128,16}});
|
||||
const double CNAV_A0_LSB = TWO_N35;
|
||||
const std::vector<std::pair<int,int> > CNAV_A1({{144,13}});
|
||||
const double CNAV_A1_LSB = TWO_N51;
|
||||
const std::vector<std::pair<int,int> > CNAV_A2({{157,7}});
|
||||
const double CNAV_A2_LSB = TWO_N68;
|
||||
const std::vector<std::pair<int,int> > CNAV_DELTA_TLS({{164,8}});
|
||||
const double CNAV_DELTA_TLS_LSB = 1;
|
||||
const std::vector<std::pair<int,int> > CNAV_TOT({{172,16}});
|
||||
const double CNAV_TOT_LSB = TWO_P4;
|
||||
const std::vector<std::pair<int,int> > CNAV_WN_OT({{188,13}});
|
||||
const double CNAV_WN_OT_LSB = 1;
|
||||
const std::vector<std::pair<int,int> > CNAV_WN_LSF({{201,13}});
|
||||
const double CNAV_WN_LSF_LSB = 1;
|
||||
const std::vector<std::pair<int,int> > CNAV_DN({{214,4}});
|
||||
const double CNAV_DN_LSB = 1;
|
||||
const std::vector<std::pair<int,int> > CNAV_DELTA_TLSF({{218,8}});
|
||||
const double CNAV_DELTA_TLSF_LSB = 1;
|
||||
|
||||
|
||||
// TODO: Add more frames (Almanac, etc...)
|
||||
|
||||
|
||||
|
||||
#endif /* GNSS_SDR_GPS_L2C_H_ */
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <cstdint>
|
||||
#include "MATH_CONSTANTS.h"
|
||||
#include "gnss_frequencies.h"
|
||||
#include "GPS_CNAV.h"
|
||||
|
||||
// Physical constants
|
||||
const double GPS_L5_C_m_s = 299792458.0; //!< The speed of light, [m/s]
|
||||
@ -47,19 +48,21 @@ const double GPS_L5_F = -4.442807633e-10; //!< Constant, [s/(m)^(1
|
||||
|
||||
|
||||
// carrier and code frequencies
|
||||
const double GPS_L5_FREQ_HZ = FREQ5; //!< L2 [Hz]
|
||||
const double GPS_L5_FREQ_HZ = FREQ5; //!< L5 [Hz]
|
||||
|
||||
const double GPS_L5i_CODE_RATE_HZ = 10.23e6; //!< GPS L5i code rate [chips/s]
|
||||
const int GPS_L5i_CODE_LENGTH_CHIPS = 10230; //!< GPS L5i code length [chips]
|
||||
const double GPS_L5i_PERIOD = 0.001; //!< GPS L2 M code period [seconds]
|
||||
const double GPS_L5i_PERIOD = 0.001; //!< GPS L5 code period [seconds]
|
||||
const double GPS_L5i_SYMBOL_PERIOD = 0.01; //!< GPS L5 symbol period [seconds]
|
||||
|
||||
const double GPS_L5q_CODE_RATE_HZ = 10.23e6; //!< GPS L5i code rate [chips/s]
|
||||
const int GPS_L5q_CODE_LENGTH_CHIPS = 10230; //!< GPS L5i code length [chips]
|
||||
const double GPS_L5q_PERIOD = 0.001; //!< GPS L2 M code period [seconds]
|
||||
const int GPS_L5q_CODE_LENGTH_CHIPS = 10230; //!< GPS L5i code length [chips]
|
||||
const double GPS_L5q_PERIOD = 0.001; //!< GPS L5 code period [seconds]
|
||||
|
||||
const int GPS_L5_HISTORY_DEEP = 5;
|
||||
|
||||
const int32_t GPS_L5i_INIT_REG[210] =
|
||||
{266, 365, 804, 1138,
|
||||
{266, 365, 804, 1138,
|
||||
1509, 1559, 1756, 2084,
|
||||
2170, 2303, 2527, 2687,
|
||||
2930, 3471, 3940, 4132,
|
||||
@ -172,6 +175,12 @@ const int32_t GPS_L5q_INIT_REG[210] =
|
||||
2765, 37, 1943, 7977,
|
||||
2512, 4451, 4071};
|
||||
|
||||
|
||||
const int GPS_L5_CNAV_DATA_PAGE_BITS = 300; //!< GPS L5 CNAV page length, including preamble and CRC [bits]
|
||||
const int GPS_L5_SYMBOLS_PER_BIT = 2;
|
||||
const int GPS_L5_SAMPLES_PER_SYMBOL = 10;
|
||||
const int GPS_L5_CNAV_DATA_PAGE_SYMBOLS = 600;
|
||||
const int GPS_L5_CNAV_DATA_PAGE_DURATION_S = 6;
|
||||
const int GPS_L5_NH_CODE_LENGTH = 10;
|
||||
const int GPS_L5_NH_CODE[10] = {0, 0, 0, 0, 1, 1, 0, 1, 0, 1};
|
||||
|
||||
#endif /* GNSS_SDR_GPS_L5_H_ */
|
||||
|
@ -42,6 +42,7 @@
|
||||
*/
|
||||
|
||||
const double PI = 3.1415926535897932; //!< pi
|
||||
const double PI_2 = 2.0 * PI; //!< 2 * pi
|
||||
|
||||
const double TWO_P4 = (16); //!< 2^4
|
||||
const double TWO_P11 = (2048); //!< 2^11
|
||||
|
@ -32,7 +32,6 @@
|
||||
|
||||
#include "gps_cnav_ephemeris.h"
|
||||
#include <cmath>
|
||||
#include "GPS_L2C.h"
|
||||
#include <iostream>
|
||||
|
||||
Gps_CNAV_Ephemeris::Gps_CNAV_Ephemeris()
|
||||
@ -168,7 +167,7 @@ double Gps_CNAV_Ephemeris::sv_clock_relativistic_term(double transmitTime)
|
||||
{
|
||||
E_old = E;
|
||||
E = M + d_e_eccentricity * sin(E);
|
||||
dE = fmod(E - E_old, 2.0 * GPS_L2_PI);
|
||||
dE = fmod(E - E_old, 2.0 * PI);
|
||||
if (fabs(dE) < 1e-12)
|
||||
{
|
||||
//Necessary precision is reached, exit from the loop
|
||||
@ -239,7 +238,7 @@ double Gps_CNAV_Ephemeris::satellitePosition(double transmitTime)
|
||||
{
|
||||
E_old = E;
|
||||
E = M + d_e_eccentricity * sin(E);
|
||||
dE = fmod(E - E_old, 2 * GPS_L2_PI);
|
||||
dE = fmod(E - E_old, 2 * PI);
|
||||
if (fabs(dE) < 1e-12)
|
||||
{
|
||||
//Necessary precision is reached, exit from the loop
|
||||
@ -268,7 +267,7 @@ double Gps_CNAV_Ephemeris::satellitePosition(double transmitTime)
|
||||
i = d_i_0 + d_IDOT * tk + d_Cic * cos(2*phi) + d_Cis * sin(2*phi);
|
||||
|
||||
// Compute the angle between the ascending node and the Greenwich meridian
|
||||
double d_OMEGA_DOT = OMEGA_DOT_REF*GPS_L2_PI + d_DELTA_OMEGA_DOT;
|
||||
double d_OMEGA_DOT = OMEGA_DOT_REF*PI + d_DELTA_OMEGA_DOT;
|
||||
Omega = d_OMEGA0 + (d_OMEGA_DOT - OMEGA_EARTH_DOT)*tk - OMEGA_EARTH_DOT * d_Toe1;
|
||||
|
||||
// Reduce to between 0 and 2*pi rad
|
||||
@ -291,7 +290,7 @@ double Gps_CNAV_Ephemeris::satellitePosition(double transmitTime)
|
||||
double dtr_s = d_A_f0 + d_A_f1 * tk + d_A_f2 * tk * tk;
|
||||
|
||||
/* relativity correction */
|
||||
dtr_s -= 2.0 * sqrt(GM * a) * d_e_eccentricity * sin(E) / (GPS_L2_C_m_s * GPS_L2_C_m_s);
|
||||
dtr_s -= 2.0 * sqrt(GM * a) * d_e_eccentricity * sin(E) / (SPEED_OF_LIGHT * SPEED_OF_LIGHT);
|
||||
|
||||
return dtr_s;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
#ifndef GNSS_SDR_GPS_CNAV_EPHEMERIS_H_
|
||||
#define GNSS_SDR_GPS_CNAV_EPHEMERIS_H_
|
||||
|
||||
#include "GPS_L2C.h"
|
||||
#include "GPS_CNAV.h"
|
||||
#include "boost/assign.hpp"
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
|
||||
|
@ -40,6 +40,7 @@ void Gps_CNAV_Navigation_Message::reset()
|
||||
b_flag_ephemeris_1 = false;
|
||||
b_flag_ephemeris_2 = false;
|
||||
b_flag_iono_valid = false;
|
||||
b_flag_utc_valid = false;
|
||||
|
||||
// satellite positions
|
||||
d_satpos_X = 0;
|
||||
@ -73,11 +74,11 @@ Gps_CNAV_Navigation_Message::Gps_CNAV_Navigation_Message()
|
||||
|
||||
|
||||
|
||||
bool Gps_CNAV_Navigation_Message::read_navigation_bool(std::bitset<GPS_L2_CNAV_DATA_PAGE_BITS> bits, const std::vector<std::pair<int,int>> parameter)
|
||||
bool Gps_CNAV_Navigation_Message::read_navigation_bool(std::bitset<GPS_CNAV_DATA_PAGE_BITS> bits, const std::vector<std::pair<int,int>> parameter)
|
||||
{
|
||||
bool value;
|
||||
|
||||
if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1)
|
||||
if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1)
|
||||
{
|
||||
value = true;
|
||||
}
|
||||
@ -89,7 +90,7 @@ bool Gps_CNAV_Navigation_Message::read_navigation_bool(std::bitset<GPS_L2_CNAV_D
|
||||
}
|
||||
|
||||
|
||||
unsigned long int Gps_CNAV_Navigation_Message::read_navigation_unsigned(std::bitset<GPS_L2_CNAV_DATA_PAGE_BITS> bits, const std::vector<std::pair<int,int>> parameter)
|
||||
unsigned long int Gps_CNAV_Navigation_Message::read_navigation_unsigned(std::bitset<GPS_CNAV_DATA_PAGE_BITS> bits, const std::vector<std::pair<int,int>> parameter)
|
||||
{
|
||||
unsigned long int value = 0;
|
||||
int num_of_slices = parameter.size();
|
||||
@ -98,7 +99,7 @@ unsigned long int Gps_CNAV_Navigation_Message::read_navigation_unsigned(std::bit
|
||||
for (int j = 0; j < parameter[i].second; j++)
|
||||
{
|
||||
value <<= 1; //shift left
|
||||
if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1)
|
||||
if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1)
|
||||
{
|
||||
value += 1; // insert the bit
|
||||
}
|
||||
@ -108,7 +109,7 @@ unsigned long int Gps_CNAV_Navigation_Message::read_navigation_unsigned(std::bit
|
||||
}
|
||||
|
||||
|
||||
signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset<GPS_L2_CNAV_DATA_PAGE_BITS> bits, const std::vector<std::pair<int,int>> parameter)
|
||||
signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset<GPS_CNAV_DATA_PAGE_BITS> bits, const std::vector<std::pair<int,int>> parameter)
|
||||
{
|
||||
signed long int value = 0;
|
||||
int num_of_slices = parameter.size();
|
||||
@ -117,7 +118,7 @@ signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset<
|
||||
if (long_int_size_bytes == 8) // if a long int takes 8 bytes, we are in a 64 bits system
|
||||
{
|
||||
// read the MSB and perform the sign extension
|
||||
if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1)
|
||||
if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1)
|
||||
{
|
||||
value ^= 0xFFFFFFFFFFFFFFFF; //64 bits variable
|
||||
}
|
||||
@ -132,7 +133,7 @@ signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset<
|
||||
{
|
||||
value <<= 1; //shift left
|
||||
value &= 0xFFFFFFFFFFFFFFFE; //reset the corresponding bit (for the 64 bits variable)
|
||||
if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1)
|
||||
if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1)
|
||||
{
|
||||
value += 1; // insert the bit
|
||||
}
|
||||
@ -142,7 +143,7 @@ signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset<
|
||||
else // we assume we are in a 32 bits system
|
||||
{
|
||||
// read the MSB and perform the sign extension
|
||||
if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1)
|
||||
if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1)
|
||||
{
|
||||
value ^= 0xFFFFFFFF;
|
||||
}
|
||||
@ -157,7 +158,7 @@ signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset<
|
||||
{
|
||||
value <<= 1; //shift left
|
||||
value &= 0xFFFFFFFE; //reset the corresponding bit
|
||||
if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1)
|
||||
if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1)
|
||||
{
|
||||
value += 1; // insert the bit
|
||||
}
|
||||
@ -168,7 +169,7 @@ signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset<
|
||||
}
|
||||
|
||||
|
||||
void Gps_CNAV_Navigation_Message::decode_page(std::bitset<GPS_L2_CNAV_DATA_PAGE_BITS> data_bits)
|
||||
void Gps_CNAV_Navigation_Message::decode_page(std::bitset<GPS_CNAV_DATA_PAGE_BITS> data_bits)
|
||||
{
|
||||
int PRN;
|
||||
int page_type;
|
||||
@ -188,7 +189,6 @@ void Gps_CNAV_Navigation_Message::decode_page(std::bitset<GPS_L2_CNAV_DATA_PAGE_
|
||||
|
||||
page_type = static_cast<int>(read_navigation_unsigned(data_bits, CNAV_MSG_TYPE));
|
||||
|
||||
//std::cout << "PRN=" << PRN << " TOW=" << d_TOW << " alert_flag=" << alert_flag << " page_type= " << page_type << std::endl;
|
||||
switch(page_type)
|
||||
{
|
||||
case 10: // Ephemeris 1/2
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include "GPS_L2C.h"
|
||||
#include "GPS_CNAV.h"
|
||||
#include "gps_cnav_ephemeris.h"
|
||||
#include "gps_cnav_iono.h"
|
||||
#include "gps_cnav_utc_model.h"
|
||||
@ -55,9 +55,9 @@
|
||||
class Gps_CNAV_Navigation_Message
|
||||
{
|
||||
private:
|
||||
unsigned long int read_navigation_unsigned(std::bitset<GPS_L2_CNAV_DATA_PAGE_BITS> bits, const std::vector<std::pair<int,int>> parameter);
|
||||
signed long int read_navigation_signed(std::bitset<GPS_L2_CNAV_DATA_PAGE_BITS> bits, const std::vector<std::pair<int,int>> parameter);
|
||||
bool read_navigation_bool(std::bitset<GPS_L2_CNAV_DATA_PAGE_BITS> bits, const std::vector<std::pair<int,int>> parameter);
|
||||
unsigned long int read_navigation_unsigned(std::bitset<GPS_CNAV_DATA_PAGE_BITS> bits, const std::vector<std::pair<int,int>> parameter);
|
||||
signed long int read_navigation_signed(std::bitset<GPS_CNAV_DATA_PAGE_BITS> bits, const std::vector<std::pair<int,int>> parameter);
|
||||
bool read_navigation_bool(std::bitset<GPS_CNAV_DATA_PAGE_BITS> bits, const std::vector<std::pair<int,int>> parameter);
|
||||
|
||||
Gps_CNAV_Ephemeris ephemeris_record;
|
||||
Gps_CNAV_Iono iono_record;
|
||||
@ -89,7 +89,7 @@ public:
|
||||
// public functions
|
||||
void reset();
|
||||
|
||||
void decode_page(std::bitset<GPS_L2_CNAV_DATA_PAGE_BITS> data_bits);
|
||||
void decode_page(std::bitset<GPS_CNAV_DATA_PAGE_BITS> data_bits);
|
||||
/*!
|
||||
* \brief Obtain a GPS SV Ephemeris class filled with current SV data
|
||||
*/
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <boost/dynamic_bitset.hpp>
|
||||
#include <glog/logging.h>
|
||||
#include "Galileo_E1.h"
|
||||
#include "GPS_L2C.h"
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user