Merge branch 'next' of git+ssh://github.com/gnss-sdr/gnss-sdr into next

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
This commit is contained in:
Carles Fernandez 2015-05-25 18:46:55 +02:00
commit 8d1879d2e8
12 changed files with 799 additions and 24 deletions

View File

@ -107,14 +107,14 @@ GpsL1CaPcpsQuickSyncAcquisition::GpsL1CaPcpsQuickSyncAcquisition(
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
int samples_per_ms = round(code_length_);
code_= new gr_complex[code_length_];
code_ = new gr_complex[code_length_]();
/*Object relevant information for debugging*/
LOG(INFO) <<"Implementation: "<<this->implementation()
<<", Vector Length: "<<vector_length_
<<", Samples per ms: "<<samples_per_ms
<<", Folding factor: "<<folding_factor_
<<", Sampled ms: "<<sampled_ms_
<<", Code Length: "<<code_length_;
LOG(INFO) << "Implementation: " << this->implementation()
<< ", Vector Length: " << vector_length_
<< ", Samples per ms: " << samples_per_ms
<< ", Folding factor: " << folding_factor_
<< ", Sampled ms: " << sampled_ms_
<< ", Code Length: " << code_length_;
if (item_type_.compare("gr_complex") == 0)
{
@ -168,7 +168,7 @@ void GpsL1CaPcpsQuickSyncAcquisition::set_threshold(float threshold)
if(pfa == 0.0)
{
pfa = configuration_->property(role_+".pfa", 0.0);
pfa = configuration_->property(role_ + ".pfa", 0.0);
}
if(pfa == 0.0)
{
@ -255,7 +255,7 @@ void GpsL1CaPcpsQuickSyncAcquisition::set_local_code()
{
if (item_type_.compare("gr_complex") == 0)
{
std::complex<float>* code = new std::complex<float>[code_length_];
std::complex<float>* code = new std::complex<float>[code_length_]();
gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0);

View File

@ -98,11 +98,10 @@ void galileo_e5_a_code_gen_complex_primary(std::complex<float>* _dest, signed in
void galileo_e5_a_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3],
unsigned int _prn, signed int _fs, unsigned int _chip_shift)
{
// This function is based on the GNU software GPS for MATLAB in the Kay Borre book
unsigned int _samplesPerCode;
unsigned int delay;
unsigned int _codeLength = Galileo_E5a_CODE_LENGTH_CHIPS;
const int _codeFreqBasis = Galileo_E5a_CODE_CHIP_RATE_HZ; //Hz
const unsigned int _codeLength = Galileo_E5a_CODE_LENGTH_CHIPS;
const int _codeFreqBasis = Galileo_E5a_CODE_CHIP_RATE_HZ;
std::complex<float>* _code = new std::complex<float>[_codeLength]();
@ -114,17 +113,23 @@ void galileo_e5_a_code_gen_complex_sampled(std::complex<float>* _dest, char _Sig
if (_fs != _codeFreqBasis)
{
std::complex<float>* _resampled_signal;
if (posix_memalign((void**)&_resampled_signal, 16, _samplesPerCode * sizeof(gr_complex)) == 0){};
resampler(_code, _resampled_signal, _codeFreqBasis, _fs, _codeLength, _samplesPerCode); //resamples code to fs
delete[] _code;
_code = _resampled_signal;
std::complex<float>* _resampled_signal;
if (posix_memalign((void**)&_resampled_signal, 16, _samplesPerCode * sizeof(gr_complex)) == 0){};
resampler(_code, _resampled_signal, _codeFreqBasis, _fs, _codeLength, _samplesPerCode); //resamples code to fs
delete[] _code;
_code = _resampled_signal;
}
for (unsigned int i = 0; i < _samplesPerCode; i++)
{
_dest[(i + delay) % _samplesPerCode] = _code[i];
}
delete[] _code;
if (_fs != _codeFreqBasis)
{
free(_code);
}
else
{
delete[] _code;
}
}

View File

@ -38,6 +38,9 @@ set(SYSTEM_PARAMETERS_SOURCES
sbas_telemetry_data.cc
galileo_fnav_message.cc
gps_cnav_ephemeris.cc
gps_cnav_navigation_message.cc
gps_cnav_iono.cc
gps_cnav_utc_model.cc
)

View File

@ -60,7 +60,6 @@ const double GPS_L2_L_CODE_RATE_HZ = 0.5115e6; //!< GPS L2 L code rate [chips/
const int GPS_L2_L_CODE_LENGTH_CHIPS = 767250; //!< GPS L2 L code length [chips]
const double GPS_L2_L_PERIOD = 1.5; //!< GPS L2 L code period [seconds]
const int32_t GPS_L2C_M_INIT_REG[115] =
{0742417664, 0756014035,0002747144,0066265724, // 1:4
0601403471, 0703232733, 0124510070,0617316361, // 5:8
@ -97,6 +96,8 @@ const int32_t GPS_L2C_M_INIT_REG[115] =
#define GPS_CNAV_PREAMBLE {1, 0, 0, 0, 1, 0, 1, 1}
const int GPS_L2_CNAV_DATA_PAGE_BITS = 300; //!< GPS L2 CNAV page length, including preamble and CRC [bits]
// 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} } );
@ -185,6 +186,7 @@ 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}});

View File

@ -43,7 +43,8 @@ Gps_CNAV_Ephemeris::Gps_CNAV_Ephemeris()
d_e_eccentricity = 0;
d_Cus = 0;
d_Toe = 0;
d_Toe1 = 0;
d_Toe2 = 0;
d_Toc = 0;
d_Cic = 0;
d_OMEGA0 = 0;

View File

@ -65,7 +65,8 @@ public:
double d_e_eccentricity; //!< Eccentricity
double d_OMEGA; //!< Argument of Perigee [semi-cicles]
double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-cicles]
double d_Toe; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s]
double d_Toe1; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s]
double d_Toe2; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s]
double d_DELTA_OMEGA_DOT; //!< Rate of Right Ascension difference [semi-circles/s]
double d_i_0; //!< Inclination Angle at Reference Time [semi-circles]
double d_IDOT; //!< Rate of Inclination Angle [semi-circles/s]
@ -109,6 +110,7 @@ public:
* accompanying alert, is less than 1E-8 per hour.
*/
bool b_integrity_status_flag;
bool b_l2c_phasing_flag;
bool b_alert_flag; //!< If true, indicates that the SV URA may be worse than indicated in d_SV_accuracy, use that SV at our own risk.
bool b_antispoofing_flag; //!< If true, the AntiSpoofing mode is ON in that SV
@ -143,8 +145,9 @@ public:
archive & make_nvp("d_Cuc", d_Cuc); //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad]
archive & make_nvp("d_e_eccentricity", d_e_eccentricity); //!< Eccentricity [dimensionless]
archive & make_nvp("d_Cus", d_Cus); //!< Amplitude of the Sine Harmonic Correction Term to the Argument of Latitude [rad]
archive & make_nvp("d_Toe", d_Toe); //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s]
archive & make_nvp("d_Toc", d_Toe); //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s]
archive & make_nvp("d_Toe1", d_Toe1); //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s]
archive & make_nvp("d_Toe2", d_Toe2); //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s]
archive & make_nvp("d_Toc", d_Toc); //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s]
archive & make_nvp("d_Cic", d_Cic); //!< Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination [rad]
archive & make_nvp("d_OMEGA0", d_OMEGA0); //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles]
archive & make_nvp("d_Cis", d_Cis); //!< Amplitude of the Sine Harmonic Correction Term to the Angle of Inclination [rad]

View File

@ -0,0 +1,47 @@
/*!
* \file gps_cnav_iono.cc
* \brief Interface of a GPS CNAV IONOSPHERIC MODEL storage
*
* See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
* \author Javier Arribas, 2015. 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 <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "gps_cnav_iono.h"
Gps_CNAV_Iono::Gps_CNAV_Iono()
{
valid = false;
d_alpha0 = 0.0;
d_alpha1 = 0.0;
d_alpha2 = 0.0;
d_alpha3 = 0.0;
d_beta0 = 0.0;
d_beta1 = 0.0;
d_beta2 = 0.0;
d_beta3 = 0.0;
}

View File

@ -0,0 +1,81 @@
/*!
* \file gps_cnav_iono.h
* \brief Interface of a GPS CNAV IONOSPHERIC MODEL storage
* \author Javier Arribas, 2015. 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 <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_GPS_CNAV_IONO_H_
#define GNSS_SDR_GPS_CNAV_IONO_H_
#include "GPS_L2C.h"
#include "boost/assign.hpp"
#include <boost/serialization/nvp.hpp>
/*!
* \brief This class is a storage for the GPS IONOSPHERIC data as described in IS-GPS-200E
*
* See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
*/
class Gps_CNAV_Iono
{
public:
bool valid; //!< Valid flag
// Ionospheric parameters
double d_alpha0; //!< Coefficient 0 of a cubic equation representing the amplitude of the vertical delay [s]
double d_alpha1; //!< Coefficient 1 of a cubic equation representing the amplitude of the vertical delay [s/semi-circle]
double d_alpha2; //!< Coefficient 2 of a cubic equation representing the amplitude of the vertical delay [s(semi-circle)^2]
double d_alpha3; //!< Coefficient 3 of a cubic equation representing the amplitude of the vertical delay [s(semi-circle)^3]
double d_beta0; //!< Coefficient 0 of a cubic equation representing the period of the model [s]
double d_beta1; //!< Coefficient 1 of a cubic equation representing the period of the model [s/semi-circle]
double d_beta2; //!< Coefficient 2 of a cubic equation representing the period of the model [s(semi-circle)^2]
double d_beta3; //!< Coefficient 3 of a cubic equation representing the period of the model [s(semi-circle)^3]
Gps_CNAV_Iono(); //!< Default constructor
template<class Archive>
/*!
* \brief Serialize is a boost standard method to be called by the boost XML serialization. Here is used to save the ephemeris data on disk file.
*/
void serialize(Archive& archive, const unsigned int version)
{
using boost::serialization::make_nvp;
if(version){};
archive & make_nvp("d_alpha0",d_alpha0);
archive & make_nvp("d_alpha1",d_alpha1);
archive & make_nvp("d_alpha2",d_alpha2);
archive & make_nvp("d_alpha3",d_alpha3);
archive & make_nvp("d_beta0",d_beta0);
archive & make_nvp("d_beta1",d_beta1);
archive & make_nvp("d_beta2",d_beta2);
archive & make_nvp("d_beta3",d_beta3);
}
};
#endif

View File

@ -0,0 +1,382 @@
/*!
* \file Gps_CNAV_Navigation_Message.cc
* \brief Implementation of a GPS NAV Data message decoder as described in IS-GPS-200E
*
* See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
* \author Javier Arribas, 2011. 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 <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "gps_cnav_navigation_message.h"
#include <cmath>
#include "boost/date_time/posix_time/posix_time.hpp"
void Gps_CNAV_Navigation_Message::reset()
{
b_valid_ephemeris_set_flag = false;
// satellite positions
d_satpos_X = 0;
d_satpos_Y = 0;
d_satpos_Z = 0;
// info
i_channel_ID = 0;
i_satellite_PRN = 0;
// Satellite velocity
d_satvel_X = 0;
d_satvel_Y = 0;
d_satvel_Z = 0;
//Plane A (info from http://www.navcen.uscg.gov/?Do=constellationStatus)
satelliteBlock[9] = "IIA";
satelliteBlock[31] = "IIR-M";
satelliteBlock[8] = "IIA";
satelliteBlock[7] = "IIR-M";
satelliteBlock[27] = "IIA";
//Plane B
satelliteBlock[16] = "IIR";
satelliteBlock[25] = "IIF";
satelliteBlock[28] = "IIR";
satelliteBlock[12] = "IIR-M";
satelliteBlock[30] = "IIA";
//Plane C
satelliteBlock[29] = "IIR-M";
satelliteBlock[3] = "IIA";
satelliteBlock[19] = "IIR";
satelliteBlock[17] = "IIR-M";
satelliteBlock[6] = "IIA";
//Plane D
satelliteBlock[2] = "IIR";
satelliteBlock[1] = "IIF";
satelliteBlock[21] = "IIR";
satelliteBlock[4] = "IIA";
satelliteBlock[11] = "IIR";
satelliteBlock[24] = "IIA"; // Decommissioned from active service on 04 Nov 2011
//Plane E
satelliteBlock[20] = "IIR";
satelliteBlock[22] = "IIR";
satelliteBlock[5] = "IIR-M";
satelliteBlock[18] = "IIR";
satelliteBlock[32] = "IIA";
satelliteBlock[10] = "IIA";
//Plane F
satelliteBlock[14] = "IIR";
satelliteBlock[15] = "IIR-M";
satelliteBlock[13] = "IIR";
satelliteBlock[23] = "IIR";
satelliteBlock[26] = "IIA";
}
Gps_CNAV_Navigation_Message::Gps_CNAV_Navigation_Message()
{
reset();
}
void Gps_CNAV_Navigation_Message::print_gps_word_bytes(unsigned int GPS_word)
{
std::cout << " Word =";
std::cout << std::bitset<32>(GPS_word);
std::cout << std::endl;
}
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 value;
if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1)
{
value = true;
}
else
{
value = false;
}
return value;
}
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 value = 0;
int num_of_slices = parameter.size();
for (int i = 0; i < num_of_slices; i++)
{
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)
{
value += 1; // insert the bit
}
}
}
return value;
}
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 value = 0;
int num_of_slices = parameter.size();
// Discriminate between 64 bits and 32 bits compiler
int long_int_size_bytes = sizeof(signed long int);
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)
{
value ^= 0xFFFFFFFFFFFFFFFF; //64 bits variable
}
else
{
value &= 0;
}
for (int i = 0; i < num_of_slices; i++)
{
for (int j = 0; j < parameter[i].second; j++)
{
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)
{
value += 1; // insert the bit
}
}
}
}
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)
{
value ^= 0xFFFFFFFF;
}
else
{
value &= 0;
}
for (int i = 0; i < num_of_slices; i++)
{
for (int j = 0; j < parameter[i].second; j++)
{
value <<= 1; //shift left
value &= 0xFFFFFFFE; //reset the corresponding bit
if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1)
{
value += 1; // insert the bit
}
}
}
}
return value;
}
void Gps_CNAV_Navigation_Message::decode_page(std::string data)
{
std::bitset<GPS_L2_CNAV_DATA_PAGE_BITS> data_bits(data);
int PRN;
int page_type;
double TOW;
bool alert_flag;
// common to all messages
PRN = static_cast<int>(read_navigation_unsigned(data_bits, CNAV_PRN));
TOW = static_cast<double>(read_navigation_unsigned(data_bits, CNAV_TOW));
alert_flag= static_cast<bool>(read_navigation_bool(data_bits, CNAV_ALERT_FLAG));
page_type = static_cast<int>(read_navigation_unsigned(data_bits, CNAV_MSG_TYPE));
switch(page_type)
{
case 10: // Ephemeris 1/2
ephemeris_record.i_GPS_week=static_cast<int>(read_navigation_unsigned(data_bits, CNAV_WN));
ephemeris_record.i_signal_health=static_cast<int>(read_navigation_unsigned(data_bits, CNAV_HEALTH));
ephemeris_record.d_Top=static_cast<double>(read_navigation_unsigned(data_bits, CNAV_TOP1));
ephemeris_record.d_Top=ephemeris_record.d_Top*CNAV_TOP1_LSB;
ephemeris_record.d_URA0=static_cast<double>(read_navigation_signed(data_bits, CNAV_URA));
ephemeris_record.d_Toe1=static_cast<double>(read_navigation_unsigned(data_bits, CNAV_TOE1));
ephemeris_record.d_Toe1=ephemeris_record.d_Toe1*CNAV_TOE1_LSB;
ephemeris_record.d_DELTA_A=static_cast<double>(read_navigation_signed(data_bits, CNAV_DELTA_A));
ephemeris_record.d_DELTA_A=ephemeris_record.d_DELTA_A*CNAV_DELTA_A_LSB;
ephemeris_record.d_A_DOT=static_cast<double>(read_navigation_signed(data_bits, CNAV_A_DOT));
ephemeris_record.d_A_DOT=ephemeris_record.d_A_DOT*CNAV_A_DOT_LSB;
ephemeris_record.d_Delta_n=static_cast<double>(read_navigation_signed(data_bits, CNAV_DELTA_N0));
ephemeris_record.d_Delta_n=ephemeris_record.d_Delta_n*CNAV_DELTA_N0_LSB;
ephemeris_record.d_DELTA_DOT_N=static_cast<double>(read_navigation_signed(data_bits, CNAV_DELTA_N0_DOT));
ephemeris_record.d_DELTA_DOT_N=ephemeris_record.d_DELTA_DOT_N*CNAV_DELTA_N0_DOT_LSB;
ephemeris_record.d_M_0=static_cast<double>(read_navigation_signed(data_bits, CNAV_M0));
ephemeris_record.d_M_0=ephemeris_record.d_M_0*CNAV_M0_LSB;
ephemeris_record.d_e_eccentricity=static_cast<double>(read_navigation_signed(data_bits, CNAV_E_ECCENTRICITY));
ephemeris_record.d_e_eccentricity=ephemeris_record.d_e_eccentricity*CNAV_E_ECCENTRICITY_LSB;
ephemeris_record.d_OMEGA=static_cast<double>(read_navigation_signed(data_bits, CNAV_OMEGA));
ephemeris_record.d_OMEGA=ephemeris_record.d_OMEGA*CNAV_OMEGA_LSB;
ephemeris_record.b_integrity_status_flag=static_cast<bool>(read_navigation_bool(data_bits, CNAV_INTEGRITY_FLAG));
ephemeris_record.b_l2c_phasing_flag=static_cast<bool>(read_navigation_bool(data_bits, CNAV_L2_PHASING_FLAG));
break;
case 11: // Ephemeris 2/2
ephemeris_record.d_Toe2=static_cast<double>(read_navigation_unsigned(data_bits, CNAV_TOE2));
ephemeris_record.d_Toe2=ephemeris_record.d_Toe2*CNAV_TOE2_LSB;
ephemeris_record.d_OMEGA0=static_cast<double>(read_navigation_signed(data_bits, CNAV_OMEGA0));
ephemeris_record.d_OMEGA0=ephemeris_record.d_OMEGA0*CNAV_OMEGA0_LSB;
ephemeris_record.d_DELTA_OMEGA_DOT=static_cast<double>(read_navigation_signed(data_bits, CNAV_DELTA_OMEGA_DOT));
ephemeris_record.d_DELTA_OMEGA_DOT=ephemeris_record.d_DELTA_OMEGA_DOT*CNAV_DELTA_OMEGA_DOT_LSB;
ephemeris_record.d_i_0=static_cast<double>(read_navigation_signed(data_bits, CNAV_I0));
ephemeris_record.d_i_0=ephemeris_record.d_i_0*CNAV_I0_LSB;
ephemeris_record.d_IDOT=static_cast<double>(read_navigation_signed(data_bits, CNAV_I0_DOT));
ephemeris_record.d_IDOT=ephemeris_record.d_IDOT*CNAV_I0_DOT_LSB;
ephemeris_record.d_Cis=static_cast<double>(read_navigation_signed(data_bits, CNAV_CIS));
ephemeris_record.d_Cis=ephemeris_record.d_Cis*CNAV_CIS_LSB;
ephemeris_record.d_Cic=static_cast<double>(read_navigation_signed(data_bits, CNAV_CIC));
ephemeris_record.d_Cic=ephemeris_record.d_Cic*CNAV_CIC_LSB;
ephemeris_record.d_Crs=static_cast<double>(read_navigation_signed(data_bits, CNAV_CRS));
ephemeris_record.d_Crs=ephemeris_record.d_Crs*CNAV_CRS_LSB;
ephemeris_record.d_Crc=static_cast<double>(read_navigation_signed(data_bits, CNAV_CRC));
ephemeris_record.d_Cic=ephemeris_record.d_Cic*CNAV_CRC_LSB;
ephemeris_record.d_Cus=static_cast<double>(read_navigation_signed(data_bits, CNAV_CUS));
ephemeris_record.d_Cus=ephemeris_record.d_Cus*CNAV_CUS_LSB;
ephemeris_record.d_Cuc=static_cast<double>(read_navigation_signed(data_bits, CNAV_CUC));
ephemeris_record.d_Cuc=ephemeris_record.d_Cuc*CNAV_CUS_LSB;
break;
case 30: // (CLOCK, IONO, GRUP DELAY)
//clock
ephemeris_record.d_Toc=static_cast<double>(read_navigation_unsigned(data_bits, CNAV_TOC));
ephemeris_record.d_Toc=ephemeris_record.d_Toc*CNAV_TOC_LSB;
ephemeris_record.d_URA0 = static_cast<double>(read_navigation_signed(data_bits, CNAV_URA_NED0));
ephemeris_record.d_URA1 = static_cast<double>(read_navigation_unsigned(data_bits, CNAV_URA_NED1));
ephemeris_record.d_URA2 = static_cast<double>(read_navigation_unsigned(data_bits, CNAV_URA_NED2));
ephemeris_record.d_A_f0=static_cast<double>(read_navigation_signed(data_bits, CNAV_AF0));
ephemeris_record.d_A_f0=ephemeris_record.d_A_f0*CNAV_AF0_LSB;
ephemeris_record.d_A_f1=static_cast<double>(read_navigation_signed(data_bits, CNAV_AF1));
ephemeris_record.d_A_f1=ephemeris_record.d_A_f1*CNAV_AF1_LSB;
ephemeris_record.d_A_f2=static_cast<double>(read_navigation_signed(data_bits, CNAV_AF2));
ephemeris_record.d_A_f2=ephemeris_record.d_A_f2*CNAV_AF2_LSB;
//group delays
ephemeris_record.d_TGD=static_cast<double>(read_navigation_signed(data_bits, CNAV_TGD));
ephemeris_record.d_TGD=ephemeris_record.d_TGD*CNAV_TGD_LSB;
ephemeris_record.d_ISCL1=static_cast<double>(read_navigation_signed(data_bits, CNAV_ISCL1));
ephemeris_record.d_ISCL1=ephemeris_record.d_ISCL1*CNAV_ISCL1_LSB;
ephemeris_record.d_ISCL2=static_cast<double>(read_navigation_signed(data_bits, CNAV_ISCL2));
ephemeris_record.d_ISCL2=ephemeris_record.d_ISCL2*CNAV_ISCL2_LSB;
ephemeris_record.d_ISCL5I=static_cast<double>(read_navigation_signed(data_bits, CNAV_ISCL5I));
ephemeris_record.d_ISCL5I=ephemeris_record.d_ISCL5I*CNAV_ISCL5I_LSB;
ephemeris_record.d_ISCL5Q=static_cast<double>(read_navigation_signed(data_bits, CNAV_ISCL5Q));
ephemeris_record.d_ISCL5Q=ephemeris_record.d_ISCL5Q*CNAV_ISCL5Q_LSB;
//iono
iono_record.d_alpha0=static_cast<double>(read_navigation_signed(data_bits, CNAV_ALPHA0));
iono_record.d_alpha0=iono_record.d_alpha0*CNAV_ALPHA0_LSB;
iono_record.d_alpha1=static_cast<double>(read_navigation_signed(data_bits, CNAV_ALPHA1));
iono_record.d_alpha1=iono_record.d_alpha1*CNAV_ALPHA1_LSB;
iono_record.d_alpha2=static_cast<double>(read_navigation_signed(data_bits, CNAV_ALPHA2));
iono_record.d_alpha2=iono_record.d_alpha2*CNAV_ALPHA2_LSB;
iono_record.d_alpha3=static_cast<double>(read_navigation_signed(data_bits, CNAV_ALPHA3));
iono_record.d_alpha3=iono_record.d_alpha3*CNAV_ALPHA3_LSB;
iono_record.d_beta0=static_cast<double>(read_navigation_signed(data_bits, CNAV_BETA0));
iono_record.d_beta0=iono_record.d_beta0*CNAV_BETA0_LSB;
iono_record.d_beta1=static_cast<double>(read_navigation_signed(data_bits, CNAV_BETA1));
iono_record.d_beta1=iono_record.d_beta1*CNAV_BETA1_LSB;
iono_record.d_beta2=static_cast<double>(read_navigation_signed(data_bits, CNAV_BETA2));
iono_record.d_beta2=iono_record.d_beta2*CNAV_BETA2_LSB;
iono_record.d_beta3=static_cast<double>(read_navigation_signed(data_bits, CNAV_BETA3));
iono_record.d_beta3=iono_record.d_beta3*CNAV_BETA3_LSB;
break;
default:
break;
}
}
bool Gps_CNAV_Navigation_Message::have_new_ephemeris() //Check if we have a new ephemeris stored in the galileo navigation class
{
// if ((flag_ephemeris_1 == true) and (flag_ephemeris_2 == true) and (flag_ephemeris_3 == true) and (flag_iono_and_GST == true))
// {
// //if all ephemeris pages have the same IOD, then they belong to the same block
// if ((FNAV_IODnav_1 == FNAV_IODnav_2) and (FNAV_IODnav_3 == FNAV_IODnav_4) and (FNAV_IODnav_1 == FNAV_IODnav_3))
// {
// std::cout << "Ephemeris (1, 2, 3) have been received and belong to the same batch" << std::endl;
// flag_ephemeris_1 = false;// clear the flag
// flag_ephemeris_2 = false;// clear the flag
// flag_ephemeris_3 = false;// clear the flag
// flag_all_ephemeris = true;
// IOD_ephemeris = FNAV_IODnav_1;
// std::cout << "Batch number: "<< IOD_ephemeris << std::endl;
// return true;
// }
// else
// {
// return false;
// }
// }
// else
return false;
}
Gps_CNAV_Ephemeris Gps_CNAV_Navigation_Message::get_ephemeris()
{
return ephemeris_record;
}
Gps_CNAV_Iono Gps_CNAV_Navigation_Message::get_iono()
{
//WARNING: We clear flag_utc_model_valid in order to not re-send the same information to the ionospheric parameters queue
flag_iono_valid = false;
return iono_record;
}
Gps_CNAV_Utc_Model Gps_CNAV_Navigation_Message::get_utc_model()
{
return utc_model_record;
}
bool Gps_CNAV_Navigation_Message::satellite_validation()
{
bool flag_data_valid = false;
b_valid_ephemeris_set_flag = false;
// First Step:
// check Issue Of Ephemeris Data (IODE IODC..) to find a possible interrupted reception
// and check if the data have been filled (!=0)
// if (d_TOW_SF1 != 0 and d_TOW_SF2 != 0 and d_TOW_SF3 != 0)
// {
// if (d_IODE_SF2 == d_IODE_SF3 and d_IODC == d_IODE_SF2 and d_IODC!= -1)
// {
// flag_data_valid = true;
// b_valid_ephemeris_set_flag = true;
// }
// }
return flag_data_valid;
}

View File

@ -0,0 +1,121 @@
/*!
* \file Gps_CNAV_Navigation_Message.h
* \brief Interface of a GPS NAV Data message decoder
* \author Javier Arribas, 2015. 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 <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_Gps_CNAV_Navigation_Message_H_
#define GNSS_SDR_Gps_CNAV_Navigation_Message_H_
#include <algorithm>
#include <bitset>
#include <cmath>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <utility>
#include "boost/assign.hpp"
#include "GPS_L2C.h"
#include "gps_cnav_ephemeris.h"
#include "gps_cnav_iono.h"
#include "gps_cnav_utc_model.h"
//TODO: Create GPS CNAV almanac
//#include "gps_almanac.h"
/*!
* \brief This class decodes a GPS CNAV Data message as described in IS-GPS-200E
*
* See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
*/
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);
void print_gps_word_bytes(unsigned int GPS_word);
Gps_CNAV_Ephemeris ephemeris_record;
Gps_CNAV_Iono iono_record;
Gps_CNAV_Utc_Model utc_model_record;
public:
bool flag_iono_valid; //!< If set, it indicates that the ionospheric parameters are filled (page 18 has arrived and decoded)
bool b_valid_ephemeris_set_flag; // flag indicating that this ephemeris set have passed the validation check
std::map<int,std::string> satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus
// satellite positions
double d_satpos_X; //!< Earth-fixed coordinate x of the satellite [m]. Intersection of the IERS Reference Meridian (IRM) and the plane passing through the origin and normal to the Z-axis.
double d_satpos_Y; //!< Earth-fixed coordinate y of the satellite [m]. Completes a right-handed, Earth-Centered, Earth-Fixed orthogonal coordinate system.
double d_satpos_Z; //!< Earth-fixed coordinate z of the satellite [m]. The direction of the IERS (International Earth Rotation and Reference Systems Service) Reference Pole (IRP).
// satellite identification info
int i_channel_ID;
unsigned int i_satellite_PRN;
// Satellite velocity
double d_satvel_X; //!< Earth-fixed velocity coordinate x of the satellite [m]
double d_satvel_Y; //!< Earth-fixed velocity coordinate y of the satellite [m]
double d_satvel_Z; //!< Earth-fixed velocity coordinate z of the satellite [m]
// public functions
void reset();
void decode_page(std::string data);
/*!
* \brief Obtain a GPS SV Ephemeris class filled with current SV data
*/
Gps_CNAV_Ephemeris get_ephemeris();
/*!
* \brief Obtain a GPS ionospheric correction parameters class filled with current SV data
*/
Gps_CNAV_Iono get_iono();
/*!
* \brief Obtain a GPS UTC model parameters class filled with current SV data
*/
Gps_CNAV_Utc_Model get_utc_model();
bool satellite_validation();
bool have_new_ephemeris(); //Check if we have a new ephemeris stored in the galileo navigation class
/*!
* Default constructor
*/
Gps_CNAV_Navigation_Message();
};
#endif

View File

@ -0,0 +1,45 @@
/*
* \file gps_cnav_utc_model.h
* \brief Interface of a GPS CNAV UTC MODEL storage
* \author Javier Arribas, 2015. 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 <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "gps_cnav_utc_model.h"
#include <cmath>
Gps_CNAV_Utc_Model::Gps_CNAV_Utc_Model()
{
valid = false;
d_A1 = 0;
d_A0 = 0;
d_t_OT = 0;
i_WN_T = 0;
d_DeltaT_LS = 0;
i_WN_LSF = 0;
i_DN = 0;
d_DeltaT_LSF = 0;
}

View File

@ -0,0 +1,85 @@
/*!
* \file gps_utc_model.h
* \brief Interface of a GPS UTC MODEL storage
* \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 <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_GPS_CNAV_UTC_MODEL_H_
#define GNSS_SDR_GPS_CNAV_UTC_MODEL_H_
#include "GPS_L2C.h"
#include "boost/assign.hpp"
#include <boost/serialization/nvp.hpp>
/*!
* \brief This class is a storage for the GPS UTC MODEL data as described in IS-GPS-200E
*
* See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
*/
class Gps_CNAV_Utc_Model
{
public:
bool valid;
// UTC parameters
double d_A1; //!< 1st order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s/s]
double d_A0; //!< Constant of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s]
double d_t_OT; //!< Reference time for UTC data (reference 20.3.4.5 and 20.3.3.5.2.4 IS-GPS-200E) [s]
int i_WN_T; //!< UTC reference week number [weeks]
double d_DeltaT_LS; //!< delta time due to leap seconds [s]. Number of leap seconds since 6-Jan-1980 as transmitted by the GPS almanac.
int i_WN_LSF; //!< Week number at the end of which the leap second becomes effective [weeks]
int i_DN; //!< Day number (DN) at the end of which the leap second becomes effective [days]
double d_DeltaT_LSF; //!< Scheduled future or recent past (relative to NAV message upload) value of the delta time due to leap seconds [s]
/*!
* Default constructor
*/
Gps_CNAV_Utc_Model();
template<class Archive>
/*
* \brief Serialize is a boost standard method to be called by the boost XML serialization. Here is used to save the ephemeris data on disk file.
*/
void serialize(Archive& archive, const unsigned int version)
{
using boost::serialization::make_nvp;
if(version){};
archive & make_nvp("valid",valid);
archive & make_nvp("d_A1",d_A1);
archive & make_nvp("d_A0",d_A0);
archive & make_nvp("d_t_OT",d_t_OT);
archive & make_nvp("i_WN_T",i_WN_T);
archive & make_nvp("d_DeltaT_LS",d_DeltaT_LS);
archive & make_nvp("i_WN_LSF",i_WN_LSF);
archive & make_nvp("i_DN",i_DN);
archive & make_nvp("d_DeltaT_LSF",d_DeltaT_LSF);
}
};
#endif