1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-06-14 17:19:58 +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:
Javier Arribas 2013-10-30 18:08:25 +00:00
parent 4d66f6c6ab
commit 83a9d41b05
19 changed files with 510 additions and 506 deletions

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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_];

View File

@ -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));

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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
{

View File

@ -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);

View File

@ -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);
}

View File

@ -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]

View File

@ -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

View File

@ -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
*/

View 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).')

View File

@ -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);

View File

@ -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