mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-01-12 02:10:34 +00:00
Progress in Galileo E1:
Bug fix in galileo tracking Several improvements in Galileo telemetry decoder. Code cleaning in observables Galileo PVT is able to decode Galileo time and get satellite ECEF positions Galileo PVT soluton is still under development git-svn-id: https://svn.code.sf.net/p/gnss-sdr/code/trunk@432 64b25241-fba3-4117-9849-534c7e92360d
This commit is contained in:
parent
4d66f6c6ab
commit
83a9d41b05
@ -7,7 +7,10 @@
|
||||
|
||||
;######### GLOBAL OPTIONS ##################
|
||||
;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz].
|
||||
;GNSS-SDR.internal_fs_hz=6826700
|
||||
GNSS-SDR.internal_fs_hz=2560000
|
||||
;GNSS-SDR.internal_fs_hz=4096000
|
||||
;GNSS-SDR.internal_fs_hz=5120000
|
||||
|
||||
;######### CONTROL_THREAD CONFIG ############
|
||||
ControlThread.wait_for_flowgraph=false
|
||||
@ -144,27 +147,11 @@ InputFilter.decimation_factor=8
|
||||
;#implementation: Use [Pass_Through] or [Direct_Resampler]
|
||||
;#[Pass_Through] disables this block
|
||||
;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation
|
||||
;Resampler.implementation=Direct_Resampler
|
||||
Resampler.implementation=Pass_Through
|
||||
|
||||
;#dump: Dump the resamplered data to a file.
|
||||
Resampler.dump=false
|
||||
;#dump_filename: Log path and filename.
|
||||
Resampler.dump_filename=../data/resampler.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Resampler.item_type=gr_complex
|
||||
|
||||
;#sample_freq_in: the sample frequency of the input signal
|
||||
Resampler.sample_freq_in=8000000
|
||||
|
||||
;#sample_freq_out: the desired sample frequency of the output signal
|
||||
Resampler.sample_freq_out=2048000
|
||||
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available satellite channels.
|
||||
Channels.count=8
|
||||
Channels.count=1
|
||||
;#in_acquisition: Number of channels simultaneously acquiring
|
||||
Channels.in_acquisition=1
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
@ -230,35 +217,6 @@ Channel.system=Galileo
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel.signal=1B
|
||||
|
||||
;Galileo FM3 -> PRN 19
|
||||
;Galileo FM4 -> PRN 20
|
||||
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
|
||||
;Channel0.system=Galileo
|
||||
;Channel0.signal=1B
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
;Channel0.satellite=20
|
||||
|
||||
;######### CHANNEL 1 CONFIG ############
|
||||
|
||||
;Channel1.system=Galileo
|
||||
;Channel1.signal=1B
|
||||
;Channel1.satellite=12
|
||||
|
||||
;######### CHANNEL 2 CONFIG ############
|
||||
|
||||
;Channel2.system=Galileo
|
||||
;Channel2.signal=1B
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
;Channel2.satellite=11
|
||||
|
||||
;######### CHANNEL 3 CONFIG ############
|
||||
|
||||
;Channel3.system=Galileo
|
||||
;Channel3.signal=1B
|
||||
;Channel3.satellite=19
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
@ -307,7 +265,7 @@ Tracking.item_type=gr_complex
|
||||
Tracking.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking.dump=true
|
||||
Tracking.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking.dump_filename=../data/veml_tracking_ch_
|
||||
@ -316,10 +274,7 @@ Tracking.dump_filename=../data/veml_tracking_ch_
|
||||
Tracking.pll_bw_hz=15.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking.dll_bw_hz=2.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking.fll_bw_hz=10.0;
|
||||
Tracking.dll_bw_hz=1.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking.order=3;
|
||||
|
@ -31,7 +31,7 @@ GNSS-SDR.SUPL_CI=0x31b0
|
||||
SignalSource.implementation=Nsr_File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
SignalSource.filename=/media/DATALOGGER_/signals/ION GNSS 2013/E1L1_FE0_Band0.stream
|
||||
SignalSource.filename=/media/DATALOGGER/ION GNSS 2013/E1L1_FE0_Band0.stream
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
SignalSource.item_type=byte
|
||||
|
@ -104,7 +104,7 @@ galileo_e1_pvt_cc::galileo_e1_pvt_cc(unsigned int nchannels, boost::shared_ptr<g
|
||||
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
|
||||
std::cout << "PVT dump enabled Log file: " << d_dump_filename.c_str() << std::endl;
|
||||
}
|
||||
catch (std::ifstream::failure e)
|
||||
catch (const std::ifstream::failure& e)
|
||||
{
|
||||
std::cout << "Exception opening PVT dump file " << e.what() << std::endl;
|
||||
}
|
||||
@ -169,14 +169,15 @@ int galileo_e1_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_it
|
||||
}
|
||||
|
||||
// ############ 2 COMPUTE THE PVT ################################
|
||||
// if (gnss_pseudoranges_map.size() > 0 and d_ls_pvt->gps_ephemeris_map.size() >0)
|
||||
// {
|
||||
// // compute on the fly PVT solution
|
||||
// //mod 8/4/2012 Set the PVT computation rate in this block
|
||||
// if ((d_sample_counter % d_output_rate_ms) == 0)
|
||||
// {
|
||||
// bool pvt_result;
|
||||
// pvt_result = d_ls_pvt->get_PVT(gnss_pseudoranges_map, d_rx_time, d_flag_averaging);
|
||||
if (gnss_pseudoranges_map.size() > 0 and d_ls_pvt->galileo_ephemeris_map.size() >0)
|
||||
{
|
||||
// compute on the fly PVT solution
|
||||
if ((d_sample_counter % d_output_rate_ms) == 0)
|
||||
{
|
||||
bool pvt_result;
|
||||
pvt_result = d_ls_pvt->get_PVT(gnss_pseudoranges_map, d_rx_time, d_flag_averaging);
|
||||
|
||||
//ToDo: Implement Galileo RINEX and Galileo NMEA outputs
|
||||
// if (pvt_result==true)
|
||||
// {
|
||||
// d_kml_dump.print_position(d_ls_pvt, d_flag_averaging);
|
||||
@ -210,42 +211,41 @@ int galileo_e1_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_it
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // DEBUG MESSAGE: Display position in console output
|
||||
// if (((d_sample_counter % d_display_rate_ms) == 0) and d_ls_pvt->b_valid_position == true)
|
||||
// {
|
||||
// std::cout << "Position at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time)
|
||||
// << " is Lat = " << d_ls_pvt->d_latitude_d << " [deg], Long = " << d_ls_pvt->d_longitude_d
|
||||
// << " [deg], Height= " << d_ls_pvt->d_height_m << " [m]" << std::endl;
|
||||
//
|
||||
// std::cout << "Dilution of Precision at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time)
|
||||
// << " is HDOP = " << d_ls_pvt->d_HDOP << " VDOP = " <<
|
||||
// d_ls_pvt->d_VDOP <<" TDOP = " << d_ls_pvt->d_TDOP <<
|
||||
// " GDOP = " << d_ls_pvt->d_GDOP <<std::endl;
|
||||
// }
|
||||
}
|
||||
|
||||
// DEBUG MESSAGE: Display position in console output
|
||||
if (((d_sample_counter % d_display_rate_ms) == 0) and d_ls_pvt->b_valid_position == true)
|
||||
{
|
||||
std::cout << "Position at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time)
|
||||
<< " is Lat = " << d_ls_pvt->d_latitude_d << " [deg], Long = " << d_ls_pvt->d_longitude_d
|
||||
<< " [deg], Height= " << d_ls_pvt->d_height_m << " [m]" << std::endl;
|
||||
|
||||
std::cout << "Dilution of Precision at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time)
|
||||
<< " is HDOP = " << d_ls_pvt->d_HDOP << " VDOP = " <<
|
||||
d_ls_pvt->d_VDOP <<" TDOP = " << d_ls_pvt->d_TDOP <<
|
||||
" GDOP = " << d_ls_pvt->d_GDOP <<std::endl;
|
||||
}
|
||||
// // MULTIPLEXED FILE RECORDING - Record results to file
|
||||
// if(d_dump == true)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// double tmp_double;
|
||||
// for (unsigned int i=0; i<d_nchannels ; i++)
|
||||
// {
|
||||
// tmp_double = in[i][0].Pseudorange_m;
|
||||
// d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// tmp_double = 0;
|
||||
// d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// d_dump_file.write((char*)&d_rx_time, sizeof(double));
|
||||
// }
|
||||
// }
|
||||
// catch (std::ifstream::failure e)
|
||||
// {
|
||||
// std::cout << "Exception writing observables dump file " << e.what() << std::endl;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
if(d_dump == true)
|
||||
{
|
||||
try
|
||||
{
|
||||
double tmp_double;
|
||||
for (unsigned int i=0; i<d_nchannels ; i++)
|
||||
{
|
||||
tmp_double = in[i][0].Pseudorange_m;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = 0;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
d_dump_file.write((char*)&d_rx_time, sizeof(double));
|
||||
}
|
||||
}
|
||||
catch (const std::ifstream::failure& e)
|
||||
{
|
||||
std::cout << "Exception writing observables dump file " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
consume_each(1); //one by one
|
||||
return 0;
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <armadillo>
|
||||
#include "galileo_e1_ls_pvt.h"
|
||||
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "Galileo_E1.h"
|
||||
#include <glog/log_severity.h>
|
||||
#include <glog/logging.h>
|
||||
#include "boost/date_time/posix_time/posix_time.hpp"
|
||||
@ -181,7 +181,7 @@ arma::vec galileo_e1_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arm
|
||||
(X(0, i) - pos(0)) + (X(1, i) - pos(1)) *
|
||||
(X(1, i) - pos(1)) + (X(2,i) - pos(2)) *
|
||||
(X(2,i) - pos(2));
|
||||
traveltime = sqrt(rho2) / GPS_C_m_s;
|
||||
traveltime = sqrt(rho2) / GALILEO_C_m_s;
|
||||
|
||||
//--- Correct satellite position (do to earth rotation) --------
|
||||
Rot_X = rotateSatellite(traveltime, X.col(i)); //armadillo
|
||||
@ -230,254 +230,264 @@ arma::vec galileo_e1_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arm
|
||||
|
||||
bool galileo_e1_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map, double galileo_current_time, bool flag_averaging)
|
||||
{
|
||||
// std::map<int,Gnss_Synchro>::iterator gnss_pseudoranges_iter;
|
||||
// std::map<int,Galileo_Ephemeris>::iterator galileo_ephemeris_iter;
|
||||
// int valid_pseudoranges = gnss_pseudoranges_map.size();
|
||||
//
|
||||
// arma::mat W = arma::eye(valid_pseudoranges,valid_pseudoranges); //channels weights matrix
|
||||
// arma::vec obs = arma::zeros(valid_pseudoranges); // pseudoranges observation vector
|
||||
// arma::mat satpos = arma::zeros(3,valid_pseudoranges); //satellite positions matrix
|
||||
//
|
||||
// int GPS_week = 0;
|
||||
// double utc = 0;
|
||||
// double SV_clock_drift_s = 0;
|
||||
// double SV_relativistic_clock_corr_s = 0;
|
||||
// double TX_time_corrected_s;
|
||||
// double SV_clock_bias_s = 0;
|
||||
//
|
||||
// d_flag_averaging = flag_averaging;
|
||||
//
|
||||
// // ********************************************************************************
|
||||
// // ****** PREPARE THE LEAST SQUARES DATA (SV POSITIONS MATRIX AND OBS VECTORS) ****
|
||||
// // ********************************************************************************
|
||||
// int valid_obs = 0; //valid observations counter
|
||||
// int obs_counter = 0;
|
||||
// for(gnss_pseudoranges_iter = gnss_pseudoranges_map.begin();
|
||||
// gnss_pseudoranges_iter != gnss_pseudoranges_map.end();
|
||||
// gnss_pseudoranges_iter++)
|
||||
// {
|
||||
// // 1- find the ephemeris for the current SV observation. The SV PRN ID is the map key
|
||||
// gps_ephemeris_iter = gps_ephemeris_map.find(gnss_pseudoranges_iter->first);
|
||||
// if (gps_ephemeris_iter != gps_ephemeris_map.end())
|
||||
// {
|
||||
// /*!
|
||||
// * \todo Place here the satellite CN0 (power level, or weight factor)
|
||||
// */
|
||||
// W(obs_counter, obs_counter) = 1;
|
||||
//
|
||||
// // COMMON RX TIME PVT ALGORITHM MODIFICATION (Like RINEX files)
|
||||
// // first estimate of transmit time
|
||||
// double Rx_time = GPS_current_time;
|
||||
// double Tx_time = Rx_time - gnss_pseudoranges_iter->second.Pseudorange_m/GPS_C_m_s;
|
||||
//
|
||||
// // 2- compute the clock drift using the clock model (broadcast) for this SV
|
||||
// SV_clock_drift_s = gps_ephemeris_iter->second.sv_clock_drift(Tx_time);
|
||||
//
|
||||
// // 3- compute the relativistic clock drift using the clock model (broadcast) for this SV
|
||||
// SV_relativistic_clock_corr_s = gps_ephemeris_iter->second.sv_clock_relativistic_term(Tx_time);
|
||||
//
|
||||
// // 4- compute the current ECEF position for this SV using corrected TX time
|
||||
// SV_clock_bias_s = SV_clock_drift_s + SV_relativistic_clock_corr_s - gps_ephemeris_iter->second.d_TGD;
|
||||
// TX_time_corrected_s = Tx_time - SV_clock_bias_s;
|
||||
// gps_ephemeris_iter->second.satellitePosition(TX_time_corrected_s);
|
||||
//
|
||||
// satpos(0,obs_counter) = gps_ephemeris_iter->second.d_satpos_X;
|
||||
// satpos(1,obs_counter) = gps_ephemeris_iter->second.d_satpos_Y;
|
||||
// satpos(2,obs_counter) = gps_ephemeris_iter->second.d_satpos_Z;
|
||||
//
|
||||
// // 5- fill the observations vector with the corrected pseudorranges
|
||||
// obs(obs_counter) = gnss_pseudoranges_iter->second.Pseudorange_m + SV_clock_bias_s*GPS_C_m_s;
|
||||
// d_visible_satellites_IDs[valid_obs] = gps_ephemeris_iter->second.i_satellite_PRN;
|
||||
// d_visible_satellites_CN0_dB[valid_obs] = gnss_pseudoranges_iter->second.CN0_dB_hz;
|
||||
// valid_obs++;
|
||||
//
|
||||
// // SV ECEF DEBUG OUTPUT
|
||||
// DLOG(INFO) << "(new)ECEF satellite SV ID=" << gps_ephemeris_iter->second.i_satellite_PRN
|
||||
// << " X=" << gps_ephemeris_iter->second.d_satpos_X
|
||||
// << " [m] Y=" << gps_ephemeris_iter->second.d_satpos_Y
|
||||
// << " [m] Z=" << gps_ephemeris_iter->second.d_satpos_Z
|
||||
// << " [m] PR_obs=" << obs(obs_counter) << " [m]" << std::endl;
|
||||
//
|
||||
// // compute the UTC time for this SV (just to print the asociated UTC timestamp)
|
||||
// GPS_week = gps_ephemeris_iter->second.i_GPS_week;
|
||||
// utc = gps_utc_model.utc_time(TX_time_corrected_s, GPS_week);
|
||||
//
|
||||
// }
|
||||
// else // the ephemeris are not available for this SV
|
||||
// {
|
||||
// // no valid pseudorange for the current SV
|
||||
// W(obs_counter, obs_counter) = 0; // SV de-activated
|
||||
// obs(obs_counter) = 1; // to avoid algorithm problems (divide by zero)
|
||||
// DLOG(INFO) << "No ephemeris data for SV "<< gnss_pseudoranges_iter->first << std::endl;
|
||||
// }
|
||||
// obs_counter++;
|
||||
// }
|
||||
std::map<int,Gnss_Synchro>::iterator gnss_pseudoranges_iter;
|
||||
std::map<int,Galileo_Ephemeris>::iterator galileo_ephemeris_iter;
|
||||
int valid_pseudoranges = gnss_pseudoranges_map.size();
|
||||
|
||||
arma::mat W = arma::eye(valid_pseudoranges,valid_pseudoranges); //channels weights matrix
|
||||
arma::vec obs = arma::zeros(valid_pseudoranges); // pseudoranges observation vector
|
||||
arma::mat satpos = arma::zeros(3,valid_pseudoranges); //satellite positions matrix
|
||||
|
||||
int Galileo_week_number = 0;
|
||||
double utc = 0;
|
||||
double SV_clock_drift_s = 0;
|
||||
double SV_relativistic_clock_corr_s = 0;
|
||||
double TX_time_corrected_s;
|
||||
double SV_clock_bias_s = 0;
|
||||
|
||||
double GST=0;
|
||||
|
||||
d_flag_averaging = flag_averaging;
|
||||
|
||||
// ********************************************************************************
|
||||
// ****** PREPARE THE LEAST SQUARES DATA (SV POSITIONS MATRIX AND OBS VECTORS) ****
|
||||
// ********************************************************************************
|
||||
int valid_obs = 0; //valid observations counter
|
||||
int obs_counter = 0;
|
||||
for(gnss_pseudoranges_iter = gnss_pseudoranges_map.begin();
|
||||
gnss_pseudoranges_iter != gnss_pseudoranges_map.end();
|
||||
gnss_pseudoranges_iter++)
|
||||
{
|
||||
// 1- find the ephemeris for the current SV observation. The SV PRN ID is the map key
|
||||
galileo_ephemeris_iter = galileo_ephemeris_map.find(gnss_pseudoranges_iter->first);
|
||||
if (galileo_ephemeris_iter != galileo_ephemeris_map.end())
|
||||
{
|
||||
/*!
|
||||
* \todo Place here the satellite CN0 (power level, or weight factor)
|
||||
*/
|
||||
W(obs_counter, obs_counter) = 1;
|
||||
|
||||
// COMMON RX TIME PVT ALGORITHM MODIFICATION (Like RINEX files)
|
||||
// first estimate of transmit time
|
||||
double Rx_time = galileo_current_time;
|
||||
double Tx_time = Rx_time - gnss_pseudoranges_iter->second.Pseudorange_m/GALILEO_C_m_s;
|
||||
|
||||
// 2- compute the clock drift using the clock model (broadcast) for this SV
|
||||
SV_clock_drift_s = galileo_ephemeris_iter->second.sv_clock_drift(Tx_time);
|
||||
|
||||
// 3- compute the relativistic clock drift using the clock model (broadcast) for this SV
|
||||
SV_relativistic_clock_corr_s = galileo_ephemeris_iter->second.sv_clock_relativistic_term(Tx_time);
|
||||
|
||||
// 4- compute the current ECEF position for this SV using corrected TX time
|
||||
SV_clock_bias_s = SV_clock_drift_s + SV_relativistic_clock_corr_s;
|
||||
TX_time_corrected_s = Tx_time - SV_clock_bias_s;
|
||||
galileo_ephemeris_iter->second.satellitePosition(TX_time_corrected_s);
|
||||
|
||||
satpos(0,obs_counter) = galileo_ephemeris_iter->second.d_satpos_X;
|
||||
satpos(1,obs_counter) = galileo_ephemeris_iter->second.d_satpos_Y;
|
||||
satpos(2,obs_counter) = galileo_ephemeris_iter->second.d_satpos_Z;
|
||||
|
||||
// 5- fill the observations vector with the corrected pseudorranges
|
||||
obs(obs_counter) = gnss_pseudoranges_iter->second.Pseudorange_m + SV_clock_bias_s*GALILEO_C_m_s;
|
||||
d_visible_satellites_IDs[valid_obs] = galileo_ephemeris_iter->second.i_satellite_PRN;
|
||||
d_visible_satellites_CN0_dB[valid_obs] = gnss_pseudoranges_iter->second.CN0_dB_hz;
|
||||
valid_obs++;
|
||||
|
||||
Galileo_week_number = galileo_ephemeris_iter->second.WN_5;//for GST
|
||||
|
||||
//debug
|
||||
double GST=galileo_ephemeris_iter->second.Galileo_System_Time(Galileo_week_number,galileo_current_time);
|
||||
utc = galileo_utc_model.GST_to_UTC_time(GST, Galileo_week_number);
|
||||
// get time string gregorian calendar
|
||||
boost::posix_time::time_duration t = boost::posix_time::seconds(utc);
|
||||
// 22 August 1999 00:00 last Galileo start GST epoch (ICD sec 5.1.2)
|
||||
boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t);
|
||||
d_position_UTC_time = p_time;
|
||||
std::cout << "Galileo RX time at " << boost::posix_time::to_simple_string(p_time)<<std::endl;
|
||||
//end debug
|
||||
|
||||
// SV ECEF DEBUG OUTPUT
|
||||
DLOG(INFO) << "ECEF satellite SV ID=" << galileo_ephemeris_iter->second.i_satellite_PRN
|
||||
<< " X=" << galileo_ephemeris_iter->second.d_satpos_X
|
||||
<< " [m] Y=" << galileo_ephemeris_iter->second.d_satpos_Y
|
||||
<< " [m] Z=" << galileo_ephemeris_iter->second.d_satpos_Z
|
||||
<< " [m] PR_obs=" << obs(obs_counter) << " [m]" << std::endl;
|
||||
}
|
||||
else // the ephemeris are not available for this SV
|
||||
{
|
||||
// no valid pseudorange for the current SV
|
||||
W(obs_counter, obs_counter) = 0; // SV de-activated
|
||||
obs(obs_counter) = 1; // to avoid algorithm problems (divide by zero)
|
||||
DLOG(INFO) << "No ephemeris data for SV "<< gnss_pseudoranges_iter->first << std::endl;
|
||||
}
|
||||
obs_counter++;
|
||||
}
|
||||
//
|
||||
// // ********************************************************************************
|
||||
// // ****** SOLVE LEAST SQUARES******************************************************
|
||||
// // ********************************************************************************
|
||||
// d_valid_observations = valid_obs;
|
||||
// DLOG(INFO) << "(new)PVT: valid observations=" << valid_obs << std::endl;
|
||||
//
|
||||
// if (valid_obs >= 4)
|
||||
// {
|
||||
// arma::vec mypos;
|
||||
// DLOG(INFO) << "satpos=" << satpos << std::endl;
|
||||
// DLOG(INFO) << "obs="<< obs << std::endl;
|
||||
// DLOG(INFO) << "W=" << W <<std::endl;
|
||||
// mypos = leastSquarePos(satpos, obs, W);
|
||||
// DLOG(INFO) << "(new)Position at TOW=" << GPS_current_time << " in ECEF (X,Y,Z) = " << mypos << std::endl;
|
||||
// gps_l1_ca_ls_pvt::cart2geo(mypos(0), mypos(1), mypos(2), 4);
|
||||
// //ToDo: Find an Observables/PVT random bug with some satellite configurations that gives an erratic PVT solution (i.e. height>50 km)
|
||||
// if (d_height_m>50000)
|
||||
// {
|
||||
// b_valid_position=false;
|
||||
// return false; //erratic PVT
|
||||
// }
|
||||
// // Compute UTC time and print PVT solution
|
||||
// double secondsperweek = 604800.0; // number of seconds in one week (7*24*60*60)
|
||||
// boost::posix_time::time_duration t = boost::posix_time::seconds(utc + secondsperweek*(double)GPS_week);
|
||||
// // 22 August 1999 last GPS time roll over
|
||||
// boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t);
|
||||
// d_position_UTC_time = p_time;
|
||||
//
|
||||
// DLOG(INFO) << "(new)Position at " << boost::posix_time::to_simple_string(p_time)
|
||||
// << " is Lat = " << d_latitude_d << " [deg], Long = " << d_longitude_d
|
||||
// << " [deg], Height= " << d_height_m << " [m]" << std::endl;
|
||||
//
|
||||
// // ###### Compute DOPs ########
|
||||
//
|
||||
// // 1- Rotation matrix from ECEF coordinates to ENU coordinates
|
||||
// // ref: http://www.navipedia.net/index.php/Transformations_between_ECEF_and_ENU_coordinates
|
||||
//
|
||||
// arma::mat F=arma::zeros(3,3);
|
||||
// F(0,0)=-sin(GPS_TWO_PI*(d_longitude_d/360.0));
|
||||
// F(0,1)=-sin(GPS_TWO_PI*(d_latitude_d/360.0))*cos(GPS_TWO_PI*(d_longitude_d/360.0));
|
||||
// F(0,2)=cos(GPS_TWO_PI*(d_latitude_d/360.0))*cos(GPS_TWO_PI*(d_longitude_d/360.0));
|
||||
//
|
||||
// F(1,0)=cos((GPS_TWO_PI*d_longitude_d)/360.0);
|
||||
// F(1,1)=-sin((GPS_TWO_PI*d_latitude_d)/360.0)*sin((GPS_TWO_PI*d_longitude_d)/360.0);
|
||||
// F(1,2)=cos((GPS_TWO_PI*d_latitude_d/360.0))*sin((GPS_TWO_PI*d_longitude_d)/360.0);
|
||||
//
|
||||
// F(2,0)=0;
|
||||
// F(2,1)=cos((GPS_TWO_PI*d_latitude_d)/360.0);
|
||||
// F(2,2)=sin((GPS_TWO_PI*d_latitude_d/360.0));
|
||||
//
|
||||
// // 2- Apply the rotation to the latest covariance matrix (available in ECEF from LS)
|
||||
//
|
||||
// arma::mat Q_ECEF=d_Q.submat( 0, 0, 2, 2);
|
||||
// arma::mat DOP_ENU=arma::zeros(3,3);
|
||||
//
|
||||
// try
|
||||
// {
|
||||
// DOP_ENU=arma::htrans(F)*Q_ECEF*F;
|
||||
// d_GDOP = sqrt(arma::trace(DOP_ENU)); // Geometric DOP
|
||||
// d_PDOP = sqrt(DOP_ENU(0,0) + DOP_ENU(1,1) + DOP_ENU(2,2)); // PDOP
|
||||
// d_HDOP = sqrt(DOP_ENU(0,0) + DOP_ENU(1,1)); // HDOP
|
||||
// d_VDOP = sqrt(DOP_ENU(2,2)); // VDOP
|
||||
// d_TDOP = sqrt(d_Q(3,3)); // TDOP
|
||||
// }catch(std::exception& ex)
|
||||
// {
|
||||
// d_GDOP = -1; // Geometric DOP
|
||||
// d_PDOP = -1; // PDOP
|
||||
// d_HDOP = -1; // HDOP
|
||||
// d_VDOP = -1; // VDOP
|
||||
// d_TDOP = -1; // TDOP
|
||||
// }
|
||||
//
|
||||
// // ######## LOG FILE #########
|
||||
// if(d_flag_dump_enabled == true)
|
||||
// {
|
||||
// // MULTIPLEXED FILE RECORDING - Record results to file
|
||||
// try
|
||||
// {
|
||||
// double tmp_double;
|
||||
// // PVT GPS time
|
||||
// tmp_double = GPS_current_time;
|
||||
// d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// // ECEF User Position East [m]
|
||||
// tmp_double = mypos(0);
|
||||
// d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// // ECEF User Position North [m]
|
||||
// tmp_double = mypos(1);
|
||||
// d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// // ECEF User Position Up [m]
|
||||
// tmp_double = mypos(2);
|
||||
// d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// // User clock offset [s]
|
||||
// tmp_double = mypos(3);
|
||||
// d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// // GEO user position Latitude [deg]
|
||||
// tmp_double = d_latitude_d;
|
||||
// d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// // GEO user position Longitude [deg]
|
||||
// tmp_double = d_longitude_d;
|
||||
// d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// // GEO user position Height [m]
|
||||
// tmp_double = d_height_m;
|
||||
// d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// }
|
||||
// catch (std::ifstream::failure e)
|
||||
// {
|
||||
// std::cout << "Exception writing PVT LS dump file "<< e.what() << std::endl;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // MOVING AVERAGE PVT
|
||||
// if (flag_averaging == true)
|
||||
// {
|
||||
// if (d_hist_longitude_d.size() == (unsigned int)d_averaging_depth)
|
||||
// {
|
||||
// // Pop oldest value
|
||||
// d_hist_longitude_d.pop_back();
|
||||
// d_hist_latitude_d.pop_back();
|
||||
// d_hist_height_m.pop_back();
|
||||
// // Push new values
|
||||
// d_hist_longitude_d.push_front(d_longitude_d);
|
||||
// d_hist_latitude_d.push_front(d_latitude_d);
|
||||
// d_hist_height_m.push_front(d_height_m);
|
||||
//
|
||||
// d_avg_latitude_d = 0;
|
||||
// d_avg_longitude_d = 0;
|
||||
// d_avg_height_m = 0;
|
||||
// for (unsigned int i=0; i<d_hist_longitude_d.size(); i++)
|
||||
// {
|
||||
// d_avg_latitude_d = d_avg_latitude_d + d_hist_latitude_d.at(i);
|
||||
// d_avg_longitude_d = d_avg_longitude_d + d_hist_longitude_d.at(i);
|
||||
// d_avg_height_m = d_avg_height_m + d_hist_height_m.at(i);
|
||||
// }
|
||||
// d_avg_latitude_d = d_avg_latitude_d / (double)d_averaging_depth;
|
||||
// d_avg_longitude_d = d_avg_longitude_d / (double)d_averaging_depth;
|
||||
// d_avg_height_m = d_avg_height_m / (double)d_averaging_depth;
|
||||
// b_valid_position = true;
|
||||
// return true; //indicates that the returned position is valid
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //int current_depth=d_hist_longitude_d.size();
|
||||
// // Push new values
|
||||
// d_hist_longitude_d.push_front(d_longitude_d);
|
||||
// d_hist_latitude_d.push_front(d_latitude_d);
|
||||
// d_hist_height_m.push_front(d_height_m);
|
||||
//
|
||||
// d_avg_latitude_d = d_latitude_d;
|
||||
// d_avg_longitude_d = d_longitude_d;
|
||||
// d_avg_height_m = d_height_m;
|
||||
// b_valid_position = false;
|
||||
// return false; //indicates that the returned position is not valid yet
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// b_valid_position = true;
|
||||
// return true; //indicates that the returned position is valid
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// b_valid_position = false;
|
||||
// return false;
|
||||
// }
|
||||
d_valid_observations = valid_obs;
|
||||
DLOG(INFO) << "Galileo PVT: valid observations=" << valid_obs << std::endl;
|
||||
|
||||
if (valid_obs >= 4)
|
||||
{
|
||||
arma::vec mypos;
|
||||
DLOG(INFO) << "satpos=" << satpos << std::endl;
|
||||
DLOG(INFO) << "obs="<< obs << std::endl;
|
||||
DLOG(INFO) << "W=" << W <<std::endl;
|
||||
mypos = leastSquarePos(satpos, obs, W);
|
||||
|
||||
// Compute GST and Gregorian time
|
||||
double GST=galileo_ephemeris_iter->second.Galileo_System_Time(Galileo_week_number,galileo_current_time);
|
||||
utc = galileo_utc_model.GST_to_UTC_time(GST, Galileo_week_number);
|
||||
// get time string gregorian calendar
|
||||
boost::posix_time::time_duration t = boost::posix_time::seconds(utc);
|
||||
// 22 August 1999 00:00 last Galileo start GST epoch (ICD sec 5.1.2)
|
||||
boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t);
|
||||
d_position_UTC_time = p_time;
|
||||
std::cout << "Galileo RX time at " << boost::posix_time::to_simple_string(p_time)<<std::endl;
|
||||
|
||||
DLOG(INFO) << "Galileo Position at TOW=" << galileo_current_time << " in ECEF (X,Y,Z) = " << mypos << std::endl;
|
||||
cart2geo((double)mypos(0), (double)mypos(1), (double)mypos(2), 4);
|
||||
// TODO: Compute UTC time and print PVT solution
|
||||
|
||||
DLOG(INFO) << "Galileo Position at " << boost::posix_time::to_simple_string(p_time)
|
||||
<< " is Lat = " << d_latitude_d << " [deg], Long = " << d_longitude_d
|
||||
<< " [deg], Height= " << d_height_m << " [m]" << std::endl;
|
||||
|
||||
// ###### Compute DOPs ########
|
||||
|
||||
// 1- Rotation matrix from ECEF coordinates to ENU coordinates
|
||||
// ref: http://www.navipedia.net/index.php/Transformations_between_ECEF_and_ENU_coordinates
|
||||
|
||||
arma::mat F=arma::zeros(3,3);
|
||||
F(0,0)=-sin(GPS_TWO_PI*(d_longitude_d/360.0));
|
||||
F(0,1)=-sin(GPS_TWO_PI*(d_latitude_d/360.0))*cos(GPS_TWO_PI*(d_longitude_d/360.0));
|
||||
F(0,2)=cos(GPS_TWO_PI*(d_latitude_d/360.0))*cos(GPS_TWO_PI*(d_longitude_d/360.0));
|
||||
|
||||
F(1,0)=cos((GPS_TWO_PI*d_longitude_d)/360.0);
|
||||
F(1,1)=-sin((GPS_TWO_PI*d_latitude_d)/360.0)*sin((GPS_TWO_PI*d_longitude_d)/360.0);
|
||||
F(1,2)=cos((GPS_TWO_PI*d_latitude_d/360.0))*sin((GPS_TWO_PI*d_longitude_d)/360.0);
|
||||
|
||||
F(2,0)=0;
|
||||
F(2,1)=cos((GPS_TWO_PI*d_latitude_d)/360.0);
|
||||
F(2,2)=sin((GPS_TWO_PI*d_latitude_d/360.0));
|
||||
|
||||
// 2- Apply the rotation to the latest covariance matrix (available in ECEF from LS)
|
||||
|
||||
arma::mat Q_ECEF=d_Q.submat( 0, 0, 2, 2);
|
||||
arma::mat DOP_ENU=arma::zeros(3,3);
|
||||
|
||||
try
|
||||
{
|
||||
DOP_ENU=arma::htrans(F)*Q_ECEF*F;
|
||||
d_GDOP = sqrt(arma::trace(DOP_ENU)); // Geometric DOP
|
||||
d_PDOP = sqrt(DOP_ENU(0,0) + DOP_ENU(1,1) + DOP_ENU(2,2)); // PDOP
|
||||
d_HDOP = sqrt(DOP_ENU(0,0) + DOP_ENU(1,1)); // HDOP
|
||||
d_VDOP = sqrt(DOP_ENU(2,2)); // VDOP
|
||||
d_TDOP = sqrt(d_Q(3,3)); // TDOP
|
||||
}catch(std::exception& ex)
|
||||
{
|
||||
d_GDOP = -1; // Geometric DOP
|
||||
d_PDOP = -1; // PDOP
|
||||
d_HDOP = -1; // HDOP
|
||||
d_VDOP = -1; // VDOP
|
||||
d_TDOP = -1; // TDOP
|
||||
}
|
||||
|
||||
// ######## LOG FILE #########
|
||||
if(d_flag_dump_enabled == true)
|
||||
{
|
||||
// MULTIPLEXED FILE RECORDING - Record results to file
|
||||
try
|
||||
{
|
||||
double tmp_double;
|
||||
// PVT GPS time
|
||||
tmp_double = galileo_current_time;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// ECEF User Position East [m]
|
||||
tmp_double = mypos(0);
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// ECEF User Position North [m]
|
||||
tmp_double = mypos(1);
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// ECEF User Position Up [m]
|
||||
tmp_double = mypos(2);
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// User clock offset [s]
|
||||
tmp_double = mypos(3);
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// GEO user position Latitude [deg]
|
||||
tmp_double = d_latitude_d;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// GEO user position Longitude [deg]
|
||||
tmp_double = d_longitude_d;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// GEO user position Height [m]
|
||||
tmp_double = d_height_m;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
}
|
||||
catch (const std::ifstream::failure& e)
|
||||
{
|
||||
std::cout << "Exception writing PVT LS dump file "<< e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// MOVING AVERAGE PVT
|
||||
if (flag_averaging == true)
|
||||
{
|
||||
if (d_hist_longitude_d.size() == (unsigned int)d_averaging_depth)
|
||||
{
|
||||
// Pop oldest value
|
||||
d_hist_longitude_d.pop_back();
|
||||
d_hist_latitude_d.pop_back();
|
||||
d_hist_height_m.pop_back();
|
||||
// Push new values
|
||||
d_hist_longitude_d.push_front(d_longitude_d);
|
||||
d_hist_latitude_d.push_front(d_latitude_d);
|
||||
d_hist_height_m.push_front(d_height_m);
|
||||
|
||||
d_avg_latitude_d = 0;
|
||||
d_avg_longitude_d = 0;
|
||||
d_avg_height_m = 0;
|
||||
for (unsigned int i=0; i<d_hist_longitude_d.size(); i++)
|
||||
{
|
||||
d_avg_latitude_d = d_avg_latitude_d + d_hist_latitude_d.at(i);
|
||||
d_avg_longitude_d = d_avg_longitude_d + d_hist_longitude_d.at(i);
|
||||
d_avg_height_m = d_avg_height_m + d_hist_height_m.at(i);
|
||||
}
|
||||
d_avg_latitude_d = d_avg_latitude_d / (double)d_averaging_depth;
|
||||
d_avg_longitude_d = d_avg_longitude_d / (double)d_averaging_depth;
|
||||
d_avg_height_m = d_avg_height_m / (double)d_averaging_depth;
|
||||
b_valid_position = true;
|
||||
return true; //indicates that the returned position is valid
|
||||
}
|
||||
else
|
||||
{
|
||||
//int current_depth=d_hist_longitude_d.size();
|
||||
// Push new values
|
||||
d_hist_longitude_d.push_front(d_longitude_d);
|
||||
d_hist_latitude_d.push_front(d_latitude_d);
|
||||
d_hist_height_m.push_front(d_height_m);
|
||||
|
||||
d_avg_latitude_d = d_latitude_d;
|
||||
d_avg_longitude_d = d_longitude_d;
|
||||
d_avg_height_m = d_height_m;
|
||||
b_valid_position = false;
|
||||
return false; //indicates that the returned position is not valid yet
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
b_valid_position = true;
|
||||
return true; //indicates that the returned position is valid
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
b_valid_position = false;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,6 @@ public:
|
||||
// new iono storage
|
||||
Galileo_Iono galileo_iono;
|
||||
|
||||
//double d_GPS_current_time;
|
||||
double d_galileo_current_time;
|
||||
boost::posix_time::ptime d_position_UTC_time;
|
||||
|
||||
|
@ -93,9 +93,11 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
|
||||
/ (Galileo_E1_CODE_CHIP_RATE_HZ
|
||||
/ Galileo_E1_B_CODE_LENGTH_CHIPS));
|
||||
|
||||
vector_length_ = code_length_ * (int)(sampled_ms_/4);
|
||||
|
||||
int samples_per_ms = code_length_ / 4;
|
||||
|
||||
int samples_per_ms = round(code_length_ / 4.0);
|
||||
|
||||
vector_length_ = sampled_ms_ * samples_per_ms;
|
||||
|
||||
code_ = new gr_complex[vector_length_];
|
||||
|
||||
|
@ -186,7 +186,7 @@ int galileo_e1_observables_cc::general_work (int noutput_items, gr_vector_int &n
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = current_gnss_synchro[i].Pseudorange_m;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = 0;
|
||||
tmp_double = (double)(current_gnss_synchro[i].Flag_valid_pseudorange==true);
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = current_gnss_synchro[i].PRN;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
|
@ -182,13 +182,13 @@ int gps_l1_ca_observables_cc::general_work (int noutput_items, gr_vector_int &ni
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = current_gnss_synchro[i].Pseudorange_m;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = 0;
|
||||
tmp_double = (double)(current_gnss_synchro[i].Flag_valid_pseudorange==true);
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = current_gnss_synchro[i].PRN;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
}
|
||||
}
|
||||
catch (std::ifstream::failure e)
|
||||
catch (const std::ifstream::failure& e)
|
||||
{
|
||||
std::cout << "Exception writing observables dump file " << e.what() << std::endl;
|
||||
}
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define CRC_ERROR_LIMIT 6
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
@ -178,17 +179,94 @@ galileo_e1b_telemetry_decoder_cc::galileo_e1b_telemetry_decoder_cc(
|
||||
d_TOW_at_Preamble= 0;
|
||||
d_TOW_at_current_symbol = 0;
|
||||
|
||||
d_CRC_error_counter=0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
galileo_e1b_telemetry_decoder_cc::~galileo_e1b_telemetry_decoder_cc()
|
||||
{
|
||||
delete d_preambles_symbols;
|
||||
d_dump_file.close();
|
||||
}
|
||||
|
||||
void galileo_e1b_telemetry_decoder_cc::decode_word(double *page_part_symbols,int frame_length)
|
||||
{
|
||||
double page_part_symbols_deint[frame_length];
|
||||
// 1. De-interleave
|
||||
deinterleaver(GALILEO_INAV_INTERLEAVER_ROWS,GALILEO_INAV_INTERLEAVER_COLS,page_part_symbols, page_part_symbols_deint);
|
||||
|
||||
// 2. Viterbi decoder
|
||||
// 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder)
|
||||
// 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180º
|
||||
for (int i=0;i<frame_length;i++)
|
||||
{
|
||||
if ((i+1)%2==0)
|
||||
{
|
||||
page_part_symbols_deint[i]=-page_part_symbols_deint[i];
|
||||
}
|
||||
}
|
||||
|
||||
int page_part_bits[frame_length/2];
|
||||
viterbi_decoder(page_part_symbols_deint, page_part_bits);
|
||||
|
||||
// 3. Call the Galileo page decoder
|
||||
|
||||
std::string page_String;
|
||||
|
||||
for(int i=0; i < (frame_length/2); i++)
|
||||
{
|
||||
if (page_part_bits[i]>0)
|
||||
{
|
||||
page_String.push_back('1');
|
||||
}else{
|
||||
page_String.push_back('0');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//std::cout<<"ch["<<d_channel<<"] frame part bits: "<<page_String<<std::endl;
|
||||
if (page_part_bits[0]==1)
|
||||
{
|
||||
// DECODE COMPLETE WORD (even + odd) and TEST CRC
|
||||
d_nav.split_page(page_String, flag_even_word_arrived);
|
||||
if(d_nav.flag_CRC_test==true)
|
||||
{
|
||||
std::cout<<"Galileo CRC correct on channel "<<d_channel<<std::endl;
|
||||
}else{
|
||||
std::cout<<"Galileo CRC error on channel "<<d_channel<<std::endl;
|
||||
}
|
||||
flag_even_word_arrived=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// STORE HALF WORD (even page)
|
||||
d_nav.split_page(page_String.c_str(), flag_even_word_arrived);
|
||||
flag_even_word_arrived=1;
|
||||
}
|
||||
|
||||
// 4. Push the new navigation data to the queues
|
||||
|
||||
if (d_nav.have_new_ephemeris()==true)
|
||||
{
|
||||
// get ephemeris object for this SV
|
||||
Galileo_Ephemeris ephemeris=d_nav.get_ephemeris();//notice that the read operation will clear the valid flag
|
||||
//std::cout<<"New Galileo Ephemeris received for SV "<<d_satellite.get_PRN()<<std::endl;
|
||||
d_ephemeris_queue->push(ephemeris);
|
||||
}
|
||||
if (d_nav.have_new_iono_and_GST()==true)
|
||||
{
|
||||
Galileo_Iono iono=d_nav.get_iono(); //notice that the read operation will clear the valid flag
|
||||
//std::cout<<"New Galileo IONO model (and UTC) received for SV "<<d_satellite.get_PRN()<<std::endl;
|
||||
d_iono_queue->push(iono);
|
||||
}
|
||||
if (d_nav.have_new_utc_model()==true)
|
||||
{
|
||||
Galileo_Utc_Model utc_model=d_nav.get_utc_model(); //notice that the read operation will clear the valid flag
|
||||
//std::cout<<"New Galileo UTC model received for SV "<<d_satellite.get_PRN()<<std::endl;
|
||||
d_utc_model_queue->push(utc_model);
|
||||
}
|
||||
}
|
||||
int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
|
||||
{
|
||||
@ -217,29 +295,42 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
|
||||
d_flag_preamble = false;
|
||||
|
||||
//******* frame sync ******************
|
||||
if (abs(corr_value) >= d_symbols_per_preamble)
|
||||
{
|
||||
//std::cout << "Positive preamble correlation for Galileo SAT " << this->d_satellite << std::endl;
|
||||
if (d_stat == 0)
|
||||
if (d_stat == 0) //no preamble information
|
||||
{
|
||||
d_preamble_index = d_sample_counter;//record the preamble sample stamp
|
||||
std::cout << "Preamble detection for Galileo SAT " << this->d_satellite << std::endl;
|
||||
d_stat = 1; // enter into frame pre-detection status
|
||||
if (abs(corr_value) >= d_symbols_per_preamble)
|
||||
{
|
||||
d_preamble_index = d_sample_counter;//record the preamble sample stamp
|
||||
std::cout << "Preamble detection for Galileo SAT " << this->d_satellite << std::endl;
|
||||
d_stat = 1; // enter into frame pre-detection status
|
||||
}
|
||||
}
|
||||
else if (d_stat == 1) //check preamble separation
|
||||
else if (d_stat == 1) // posible preamble lock
|
||||
{
|
||||
preamble_diff = abs(d_sample_counter - d_preamble_index);
|
||||
//std::cout << "preamble_diff="<< preamble_diff <<" for Galileo SAT " << this->d_satellite << std::endl;
|
||||
if (abs(preamble_diff - GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS) < 1)
|
||||
{
|
||||
|
||||
//std::cout<<"d_sample_counter="<<d_sample_counter<<std::endl;
|
||||
//std::cout<<"corr_value="<<corr_value<<std::endl;
|
||||
if (abs(corr_value) >= d_symbols_per_preamble)
|
||||
{
|
||||
//check preamble separation
|
||||
preamble_diff = abs(d_sample_counter - d_preamble_index);
|
||||
if (abs(preamble_diff - GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS) == 0)
|
||||
{
|
||||
//try to decode frame
|
||||
std::cout<<"Starting page decoder for Galileo SAT " << this->d_satellite<<std::endl;
|
||||
d_preamble_index=d_sample_counter;//record the preamble sample stamp
|
||||
d_stat=2;
|
||||
}
|
||||
}else{
|
||||
if (preamble_diff>GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS)
|
||||
{
|
||||
d_stat=0; // start again
|
||||
}
|
||||
}
|
||||
}else if (d_stat==2)
|
||||
{
|
||||
if (d_sample_counter==d_preamble_index+GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS)
|
||||
{
|
||||
// NEW Galileo page part is received
|
||||
// 0. fetch the symbols into an array
|
||||
int frame_length=GALILEO_INAV_PAGE_PART_SYMBOLS-d_symbols_per_preamble;
|
||||
double page_part_symbols[frame_length];
|
||||
double page_part_symbols_deint[frame_length];
|
||||
|
||||
for (int i=0;i<frame_length;i++)
|
||||
{
|
||||
@ -251,110 +342,45 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
|
||||
page_part_symbols[i]=-in[0][i+d_symbols_per_preamble].Prompt_I; // because last symbol of the preamble is just received now!
|
||||
}
|
||||
}
|
||||
// 1. De-interleave
|
||||
deinterleaver(GALILEO_INAV_INTERLEAVER_ROWS,GALILEO_INAV_INTERLEAVER_COLS,page_part_symbols, page_part_symbols_deint);
|
||||
|
||||
// 2. Viterbi decoder
|
||||
// 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder)
|
||||
// 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180º
|
||||
for (int i=0;i<frame_length;i++)
|
||||
//debug
|
||||
//std::cout<<"ch["<<d_channel<<"] Decoder call at preamble index "<<d_sample_counter<<std::endl;
|
||||
// std::cout<<"ch["<<d_channel<<"] frame symbols: ";
|
||||
// for (int j=0;j<frame_length;j++)
|
||||
// {
|
||||
// if (page_part_symbols[j]>0)
|
||||
// {
|
||||
// std::cout<<"1";
|
||||
// }else{
|
||||
// std::cout<<"0";
|
||||
// }
|
||||
// }
|
||||
// std::cout<<std::endl;
|
||||
//end debug
|
||||
//call the decoder
|
||||
decode_word(page_part_symbols,frame_length);
|
||||
if (d_nav.flag_CRC_test==true)
|
||||
{
|
||||
if ((i+1)%2==0)
|
||||
d_CRC_error_counter=0;
|
||||
d_flag_preamble = true; //valid preamble indicator (initialized to false every work())
|
||||
d_preamble_index = d_sample_counter; //record the preamble sample stamp (t_P)
|
||||
d_preamble_time_seconds = in[0][0].Tracking_timestamp_secs;// - d_preamble_duration_seconds; //record the PRN start sample index associated to the preamble
|
||||
if (!d_flag_frame_sync)
|
||||
{
|
||||
d_flag_frame_sync = true;
|
||||
std::cout <<" Frame sync SAT " << this->d_satellite << " with preamble start at " << d_preamble_time_seconds << " [s]" << std::endl;
|
||||
}
|
||||
}else{
|
||||
d_CRC_error_counter++;
|
||||
d_preamble_index = d_sample_counter; //record the preamble sample stamp
|
||||
if (d_CRC_error_counter>CRC_ERROR_LIMIT)
|
||||
{
|
||||
page_part_symbols_deint[i]=-page_part_symbols_deint[i];
|
||||
std::cout << "Lost of frame sync SAT " << this->d_satellite << std::endl;
|
||||
d_flag_frame_sync=false;
|
||||
d_stat=0;
|
||||
}
|
||||
}
|
||||
|
||||
int page_part_bits[frame_length/2];
|
||||
viterbi_decoder(page_part_symbols_deint, page_part_bits);
|
||||
|
||||
// 3. Call the Galileo page decoder
|
||||
|
||||
std::string page_String;
|
||||
|
||||
for(int i=0; i < (frame_length/2); i++)
|
||||
{
|
||||
if (page_part_bits[i]>0)
|
||||
{
|
||||
page_String.push_back('1');
|
||||
}else{
|
||||
page_String.push_back('0');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Galileo_Navigation_Message d_nav; // Now is a class member object, to store the intermediate results from call to call
|
||||
|
||||
if (page_part_bits[0]==1)
|
||||
{
|
||||
//std::cout<<"Page Odd"<<std::endl;
|
||||
d_nav.split_page(page_String.c_str(), flag_even_word_arrived);
|
||||
//decode_page.split_page(page_String, flag_even_word_arrived);
|
||||
flag_even_word_arrived=0;
|
||||
//std::cout << "page odd" << page_String << std::endl;
|
||||
DLOG(INFO) << "mara prova print page odd" << page_String;
|
||||
|
||||
//std::cout<<"Page type ="<< page_part_bits[1]<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
//std::cout<<"Page Even"<<std::endl;
|
||||
d_nav.split_page(page_String.c_str(), flag_even_word_arrived);
|
||||
flag_even_word_arrived=1;
|
||||
//std::cout << "page even" << std::endl << page_String << std::endl;
|
||||
DLOG(INFO) << "Page type =" << page_part_bits[1];
|
||||
//std::cout<<"Page type ="<< page_part_bits[1]<<std::endl;
|
||||
}
|
||||
|
||||
// 4. Push the new navigation data to the queues
|
||||
|
||||
if (d_nav.have_new_ephemeris()==true)
|
||||
{
|
||||
// get ephemeris object for this SV
|
||||
Galileo_Ephemeris ephemeris=d_nav.get_ephemeris();//notice that the read operation will clear the valid flag
|
||||
std::cout<<"New Galileo Ephemeris received for SV "<<d_satellite.get_PRN()<<std::endl;
|
||||
d_ephemeris_queue->push(ephemeris);
|
||||
}
|
||||
if (d_nav.have_new_iono_and_GST()==true)
|
||||
{
|
||||
Galileo_Iono iono=d_nav.get_iono(); //notice that the read operation will clear the valid flag
|
||||
std::cout<<"New Galileo IONO model (and UTC) received for SV "<<d_satellite.get_PRN()<<std::endl;
|
||||
d_iono_queue->push(iono);
|
||||
}
|
||||
if (d_nav.have_new_utc_model()==true)
|
||||
{
|
||||
Galileo_Utc_Model utc_model=d_nav.get_utc_model(); //notice that the read operation will clear the valid flag
|
||||
std::cout<<"New Galileo UTC model received for SV "<<d_satellite.get_PRN()<<std::endl;
|
||||
d_utc_model_queue->push(utc_model);
|
||||
}
|
||||
|
||||
d_flag_preamble = true;
|
||||
d_preamble_index = d_sample_counter; //record the preamble sample stamp (t_P)
|
||||
d_preamble_time_seconds = in[0][0].Tracking_timestamp_secs;// - d_preamble_duration_seconds; //record the PRN start sample index associated to the preamble
|
||||
|
||||
if (!d_flag_frame_sync)
|
||||
{
|
||||
d_flag_frame_sync = true;
|
||||
std::cout <<" Frame sync SAT " << this->d_satellite << " with preamble start at " << d_preamble_time_seconds << " [s]" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d_stat == 1)
|
||||
{
|
||||
preamble_diff = d_sample_counter - d_preamble_index;
|
||||
if (preamble_diff > GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS)
|
||||
{
|
||||
std::cout << "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff << std::endl;
|
||||
d_stat = 0; //lost of frame sync
|
||||
d_flag_frame_sync = false;
|
||||
//flag_TOW_set=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
consume_each(1); //one by one
|
||||
// UPDATE GNSS SYNCHRO DATA
|
||||
Gnss_Synchro current_synchro_data; //structure to save the synchronization information and send the output object to the next block
|
||||
@ -370,11 +396,9 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
|
||||
{
|
||||
//std::cout<< "Using TOW_5 for timestamping" << std::endl;
|
||||
d_TOW_at_Preamble = d_nav.TOW_5+GALILEO_PAGE_SECONDS; //TOW_5 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later
|
||||
std::cout << "d_TOW_at_Preamble="<< d_TOW_at_Preamble<< std::endl;
|
||||
/* 1 sec (GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD) is added because if we have a TOW value it means that we are at the and of the odd page*/
|
||||
d_TOW_at_current_symbol = d_TOW_at_Preamble + GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD;
|
||||
//std::cout << "d_TOW_at_current_symbol="<< d_TOW_at_current_symbol << std::endl;
|
||||
|
||||
d_nav.flag_TOW_5 = 0;
|
||||
}
|
||||
|
||||
@ -473,7 +497,7 @@ void galileo_e1b_telemetry_decoder_cc::set_channel(int channel)
|
||||
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
|
||||
std::cout << "Telemetry decoder dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str() << std::endl;
|
||||
}
|
||||
catch (std::ifstream::failure e)
|
||||
catch (const std::ifstream::failure& e)
|
||||
{
|
||||
std::cout << "channel " << d_channel << " Exception opening trk dump file " << e.what() << std::endl;
|
||||
}
|
||||
|
@ -99,6 +99,8 @@ private:
|
||||
|
||||
void deinterleaver(int rows, int cols, double *in, double *out);
|
||||
|
||||
void decode_word(double *symbols,int frame_length);
|
||||
|
||||
unsigned short int d_preambles_bits[GALILEO_INAV_PREAMBLE_LENGTH_BITS];
|
||||
|
||||
signed int *d_preambles_symbols;
|
||||
@ -112,6 +114,7 @@ private:
|
||||
|
||||
bool d_flag_parity;
|
||||
bool d_flag_preamble;
|
||||
int d_CRC_error_counter;
|
||||
|
||||
long d_fs_in;
|
||||
|
||||
|
@ -39,7 +39,6 @@
|
||||
#include "galileo_e1_signal_processing.h"
|
||||
#include "tracking_discriminators.h"
|
||||
#include "lock_detectors.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "Galileo_E1.h"
|
||||
#include "control_message_factory.h"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
@ -252,7 +251,7 @@ void galileo_e1_dll_pll_veml_tracking_cc::update_local_code()
|
||||
}
|
||||
memcpy(d_early_code, &d_very_early_code[very_early_late_spc_samples - early_late_spc_samples], d_current_prn_length_samples* sizeof(gr_complex));
|
||||
memcpy(d_prompt_code, &d_very_early_code[very_early_late_spc_samples], d_current_prn_length_samples* sizeof(gr_complex));
|
||||
memcpy(d_late_code, &d_very_early_code[2*very_early_late_spc_samples - early_late_spc_samples], d_current_prn_length_samples* sizeof(gr_complex));
|
||||
memcpy(d_late_code, &d_very_early_code[very_early_late_spc_samples + early_late_spc_samples], d_current_prn_length_samples* sizeof(gr_complex));
|
||||
memcpy(d_very_late_code, &d_very_early_code[2*very_early_late_spc_samples], d_current_prn_length_samples* sizeof(gr_complex));
|
||||
}
|
||||
|
||||
@ -491,6 +490,7 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items,gr_vect
|
||||
tmp_P = std::abs<float>(*d_Prompt);
|
||||
tmp_L = std::abs<float>(*d_Late);
|
||||
tmp_VL = std::abs<float>(*d_Very_Late);
|
||||
//std::cout<<"VE="<<tmp_VE<<",E="<<tmp_E<<",L="<<tmp_L<<",VL="<<tmp_VL<<std::endl;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -493,7 +493,7 @@ void ControlThread::galileo_ephemeris_data_collector()
|
||||
global_galileo_ephemeris_queue.wait_and_pop(galileo_eph);
|
||||
|
||||
// DEBUG MESSAGE
|
||||
std::cout << "Ephemeris record has arrived from SAT ID "
|
||||
std::cout << "Galileo Ephemeris record has arrived from SAT ID "
|
||||
<< galileo_eph.SV_ID_PRN_4 << std::endl;
|
||||
|
||||
// insert new ephemeris record to the global ephemeris map
|
||||
@ -502,26 +502,26 @@ void ControlThread::galileo_ephemeris_data_collector()
|
||||
// Check the EPHEMERIS timestamp. If it is newer, then update the ephemeris
|
||||
if (galileo_eph.WN_5 > galileo_eph_old.WN_5) //further check because it is not clear when IOD is reset
|
||||
{
|
||||
std::cout << "Ephemeris record in global map updated -- GALILEO Week Number ="<<galileo_eph.WN_5<<std::endl;
|
||||
std::cout << "Galileo Ephemeris record in global map updated -- GALILEO Week Number ="<<galileo_eph.WN_5<<std::endl;
|
||||
global_galileo_ephemeris_map.write(galileo_eph.SV_ID_PRN_4,galileo_eph);
|
||||
}else{
|
||||
if (galileo_eph.IOD_ephemeris > galileo_eph_old.IOD_ephemeris)
|
||||
{
|
||||
std::cout << "Ephemeris record updated in global map-- IOD_ephemeris ="<<galileo_eph.IOD_ephemeris<<std::endl;
|
||||
std::cout << "Galileo Ephemeris record updated in global map-- IOD_ephemeris ="<<galileo_eph.IOD_ephemeris<<std::endl;
|
||||
global_galileo_ephemeris_map.write(galileo_eph.SV_ID_PRN_4,galileo_eph);
|
||||
|
||||
std::cout << "IOD_ephemeris OLD: " << galileo_eph_old.IOD_ephemeris<<std::endl;
|
||||
std::cout << "satellite: " << galileo_eph.SV_ID_PRN_4<<std::endl;
|
||||
}
|
||||
else{
|
||||
std::cout<<"Not updating the existing ephemeris, IOD is not changing"<<std::endl;
|
||||
std::cout<<"Not updating the existing Galileo ephemeris, IOD is not changing"<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
}else{
|
||||
// insert new ephemeris record
|
||||
std::cout << "New Ephemeris record inserted in global map with TOW ="<<galileo_eph.TOW_5
|
||||
std::cout << "Galileo New Ephemeris record inserted in global map with TOW ="<<galileo_eph.TOW_5
|
||||
<<", GALILEO Week Number ="<< galileo_eph.WN_5
|
||||
<< " and Ephemeris IOD = " << galileo_eph.IOD_ephemeris << std::endl;
|
||||
global_galileo_ephemeris_map.write(galileo_eph.SV_ID_PRN_4, galileo_eph);
|
||||
|
@ -258,13 +258,13 @@ void Galileo_Ephemeris::satellitePosition(double transmitTime) //when this funct
|
||||
Omega = fmod((Omega + 2*GALILEO_PI), (2*GALILEO_PI));
|
||||
|
||||
// --- Compute satellite coordinates in Earth-fixed coordinates
|
||||
galileo_satpos_X = cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega);
|
||||
galileo_satpos_Y = cos(u) * r * sin(Omega) + sin(u) * r * cos(i) * cos(Omega); //***********************NOTE: in GALILEO ICD this expression is not correct because it has minus (- sin(u) * r * cos(i) * cos(Omega)) instead of plus
|
||||
galileo_satpos_Z = sin(u) * r * sin(i);
|
||||
d_satpos_X = cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega);
|
||||
d_satpos_Y = cos(u) * r * sin(Omega) + sin(u) * r * cos(i) * cos(Omega); //***********************NOTE: in GALILEO ICD this expression is not correct because it has minus (- sin(u) * r * cos(i) * cos(Omega)) instead of plus
|
||||
d_satpos_Z = sin(u) * r * sin(i);
|
||||
|
||||
// Satellite's velocity. Can be useful for Vector Tracking loops
|
||||
double Omega_dot = OMEGA_dot_3 - GALILEO_OMEGA_EARTH_DOT;
|
||||
galileo_satvel_X = - Omega_dot * (cos(u) * r + sin(u) * r * cos(i)) + galileo_satpos_X * cos(Omega) - galileo_satpos_Y * cos(i) * sin(Omega);
|
||||
galileo_satvel_Y = Omega_dot * (cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega)) + galileo_satpos_X * sin(Omega) + galileo_satpos_Y * cos(i) * cos(Omega);
|
||||
galileo_satvel_Z = galileo_satpos_Y * sin(i);
|
||||
d_satvel_X = - Omega_dot * (cos(u) * r + sin(u) * r * cos(i)) + d_satpos_X * cos(Omega) - d_satpos_Y * cos(i) * sin(Omega);
|
||||
d_satvel_Y = Omega_dot * (cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega)) + d_satpos_X * sin(Omega) + d_satpos_Y * cos(i) * cos(Omega);
|
||||
d_satvel_Z = d_satpos_Y * sin(i);
|
||||
}
|
||||
|
@ -87,17 +87,17 @@ public:
|
||||
double Galileo_dtr; // relativistic clock correction term
|
||||
|
||||
// satellite positions
|
||||
double galileo_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 galileo_satpos_Y; //!< Earth-fixed coordinate y of the satellite [m]. Completes a right-handed, Earth-Centered, Earth-Fixed orthogonal coordinate system.
|
||||
double galileo_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).
|
||||
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 velocity
|
||||
double galileo_satvel_X; //!< Earth-fixed velocity coordinate x of the satellite [m]
|
||||
double galileo_satvel_Y; //!< Earth-fixed velocity coordinate y of the satellite [m]
|
||||
double galileo_satvel_Z; //!< Earth-fixed velocity coordinate z of the satellite [m]
|
||||
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]
|
||||
|
||||
unsigned int i_satellite_PRN; // SV PRN NUMBER
|
||||
|
||||
/*The following parameters refers to GPS
|
||||
unsigned int i_satellite_PRN; // SV PRN NUMBER
|
||||
double d_TOW; //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s]
|
||||
double d_Crs; //!< Amplitude of the Sine Harmonic Correction Term to the Orbit Radius [m]
|
||||
double d_Delta_n; //!< Mean Motion Difference From Computed Value [semi-circles/s]
|
||||
|
@ -366,20 +366,13 @@ bool Galileo_Navigation_Message::read_navigation_bool(std::bitset<GALILEO_DATA_J
|
||||
}*/
|
||||
|
||||
|
||||
void Galileo_Navigation_Message::split_page(const char *page, int flag_even_word){
|
||||
void Galileo_Navigation_Message::split_page(std::string page_string, int flag_even_word){
|
||||
|
||||
// ToDo: Clean all the tests and create an independent google test code for the telemetry decoder.
|
||||
|
||||
|
||||
//std::cout << "Entered in Galileo_Navigation_Message::split_page(const char *page, int flag_even_word" << std::endl << std::endl;;
|
||||
std::string page_string = page;
|
||||
//char correct_tail[7]="011110"; //the viterbi decoder output change the tail to this value (why?)
|
||||
|
||||
char correct_tail[7]="000000";
|
||||
|
||||
int Page_type=0;
|
||||
static std::string page_Even; //declare in this way it can "remember the previous even page while reading the odd page..ok!
|
||||
|
||||
//std::cout << "Start decoding Galileo I/NAV " << std::endl;
|
||||
|
||||
if(page_string.at(0)=='1')// if page is odd
|
||||
@ -427,6 +420,7 @@ void Galileo_Navigation_Message::split_page(const char *page, int flag_even_word
|
||||
std::string TLM_word_for_CRC;
|
||||
TLM_word_for_CRC=TLM_word_for_CRC_stream.str().substr(0,GALILEO_DATA_FRAME_BITS);
|
||||
|
||||
//std::cout<<"Complete word for CRC test: "<<TLM_word_for_CRC<<std::endl;
|
||||
std::bitset<GALILEO_DATA_FRAME_BITS> TLM_word_for_CRC_bits(TLM_word_for_CRC);
|
||||
std::bitset<24> checksum(CRC_data);
|
||||
|
||||
@ -438,8 +432,6 @@ void Galileo_Navigation_Message::split_page(const char *page, int flag_even_word
|
||||
{
|
||||
flag_CRC_test = true;
|
||||
// CRC correct: Decode word
|
||||
std::cout<<"CRC correct!"<<std::endl;
|
||||
|
||||
std::string page_number_bits = Data_k.substr (0,6);
|
||||
//std::cout << "Page number bits from Data k" << std::endl << page_number_bits << std::endl;
|
||||
|
||||
@ -471,7 +463,6 @@ void Galileo_Navigation_Message::split_page(const char *page, int flag_even_word
|
||||
*/
|
||||
}else{
|
||||
// CRC wrong.. discard frame
|
||||
std::cout<<"CRC error!"<<std::endl;
|
||||
flag_CRC_test= false;
|
||||
}
|
||||
//********** end of CRC checksum control ***/
|
||||
@ -564,6 +555,7 @@ Galileo_Ephemeris Galileo_Navigation_Message::get_ephemeris()
|
||||
ephemeris.flag_all_ephemeris = flag_all_ephemeris;
|
||||
ephemeris.IOD_ephemeris = IOD_ephemeris;
|
||||
ephemeris.SV_ID_PRN_4 = SV_ID_PRN_4;
|
||||
ephemeris.i_satellite_PRN=SV_ID_PRN_4;
|
||||
ephemeris.M0_1 = M0_1; // Mean anomaly at reference time [semi-circles]
|
||||
ephemeris.delta_n_3 = delta_n_3; // Mean motion difference from computed value [semi-circles/sec]
|
||||
ephemeris.e_1 = e_1; // Eccentricity
|
||||
|
@ -73,6 +73,7 @@ private:
|
||||
public:
|
||||
int Page_type_time_stamp;
|
||||
int flag_even_word;
|
||||
std::string page_Even;
|
||||
bool flag_CRC_test;
|
||||
bool flag_all_ephemeris; // flag indicating that all words containing ephemeris have been received
|
||||
bool flag_ephemeris_1; // flag indicating that ephemeris 1/4 (word 1) have been received
|
||||
@ -248,7 +249,7 @@ public:
|
||||
/*
|
||||
* \brief Takes in input a page (Odd or Even) of 120 bit, split it according ICD 4.3.2.3 and join Data_k with Data_j
|
||||
*/
|
||||
void split_page(const char *page, int flag_even_word);
|
||||
void split_page(std::string page_string, int flag_even_word);
|
||||
/*
|
||||
* \brief Takes in input Data_jk (128 bit) and split it in ephemeris parameters according ICD 4.3.5
|
||||
*/
|
||||
|
17
src/utils/matlab/galileo_e1b_observables_plot_sample.m
Normal file
17
src/utils/matlab/galileo_e1b_observables_plot_sample.m
Normal file
@ -0,0 +1,17 @@
|
||||
% Read observables dump
|
||||
|
||||
clear all;
|
||||
close all;
|
||||
|
||||
%IFEN NSR Sampler Fs=20480000
|
||||
% GNSS-SDR decimation factor 8
|
||||
samplingFreq = 20480000/8; %[Hz]
|
||||
channels=8;
|
||||
path='/home/gnss/workspace/gnss-sdr/trunk/install/';
|
||||
observables_log_path=[path 'observables.dat'];
|
||||
GNSS_observables= gps_l1_ca_read_observables_dump(channels,observables_log_path);
|
||||
|
||||
|
||||
skip=10000;
|
||||
ref_channel=1;
|
||||
plot(GNSS_observables.d_TOW_at_current_symbol(ref_channel,skip:end),GNSS_observables.Pseudorange_m(1:6,skip:end).')
|
@ -4,6 +4,6 @@
|
||||
|
||||
samplingFreq = 64e6/16; %[Hz]
|
||||
channels=4;
|
||||
path='/home/javier/workspace/gnss-sdr-ref/trunk/install/';
|
||||
path='/home/gnss/workspace/gnss-sdr/trunk/install/';
|
||||
observables_log_path=[path 'observables.dat'];
|
||||
GNSS_observables= gps_l1_ca_read_observables_dump(channels,observables_log_path);
|
||||
|
@ -23,16 +23,16 @@ function [observables] = gps_l1_ca_read_observables_dump (channels, filename, co
|
||||
if (f < 0)
|
||||
else
|
||||
for N=1:1:channels
|
||||
observables.preamble_delay_ms(N,:) = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes);
|
||||
observables.d_TOW_at_current_symbol(N,:) = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes);
|
||||
bytes_shift=bytes_shift+double_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next interleaved
|
||||
observables.prn_delay_ms(N,:) = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes);
|
||||
observables.Prn_timestamp_ms(N,:) = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes);
|
||||
bytes_shift=bytes_shift+double_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next interleaved
|
||||
observables.Pseudorange_m(N,:) = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes);
|
||||
bytes_shift=bytes_shift+double_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next interleaved
|
||||
observables.Pseudorange_symbol_shift(N,:) = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes);
|
||||
observables.Flag_valid_pseudorange(N,:) = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes);
|
||||
bytes_shift=bytes_shift+double_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next interleaved
|
||||
observables.PRN(N,:) = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes);
|
||||
@ -43,18 +43,19 @@ function [observables] = gps_l1_ca_read_observables_dump (channels, filename, co
|
||||
fclose (f);
|
||||
|
||||
%%%%%%%% output vars %%%%%%%%
|
||||
% double tmp_double;
|
||||
% for (unsigned int i=0; i<d_nchannels ; i++)
|
||||
% {
|
||||
% tmp_double = current_gnss_synchro[i].Preamble_delay_ms;
|
||||
% tmp_double = current_gnss_synchro[i].d_TOW_at_current_symbol;
|
||||
% d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
% tmp_double = current_gnss_synchro[i].Prn_delay_ms;
|
||||
% tmp_double = current_gnss_synchro[i].Prn_timestamp_ms;
|
||||
% d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
% tmp_double = current_gnss_synchro[i].Pseudorange_m;
|
||||
% d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
% tmp_double = current_gnss_synchro[i].Pseudorange_symbol_shift;
|
||||
% tmp_double = (double)(current_gnss_synchro[i].Flag_valid_pseudorange==true);
|
||||
% d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
% tmp_double = current_gnss_synchro[i].PRN;
|
||||
% d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
% }
|
||||
% }
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user