Adding the path of Galileo E5 observations to RTKLIB solver. Some bug fixes. Work with Galileo in progress

This commit is contained in:
Javier Arribas 2017-05-12 17:58:04 +02:00
parent b2531cb926
commit 7a2a15b37d
10 changed files with 1237 additions and 1112 deletions

View File

@ -29,7 +29,7 @@ GNSS-SDR.SUPL_CI=0x31b0
SignalSource.implementation=Flexiband_Signal_Source
SignalSource.flag_read_file=true
SignalSource.signal_file=/home/javier/signals/L125_III1b_210s.usb ; <- PUT YOUR FILE HERE
SignalSource.signal_file=/media/javier/SISTEMA/signals/fraunhofer/L125_III1b_210s.usb ; <- PUT YOUR FILE HERE
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
SignalSource.item_type=gr_complex
@ -38,7 +38,7 @@ SignalSource.item_type=gr_complex
SignalSource.firmware_file=flexiband_III-1b.bit
;#RF_channels: Number of RF channels present in the frontend device, must agree the FPGA firmware file
SignalSource.RF_channels=3
SignalSource.RF_channels=1
;#frontend channels gain. Not usable yet!
SignalSource.gain1=0
@ -324,9 +324,10 @@ Resampler2.implementation=Pass_Through
;######### CHANNELS GLOBAL CONFIG ############
;#count: Number of available GPS satellite channels.
Channels_1C.count=1
Channels_2S.count=1
Channels_5X.count=2
Channels_1C.count=0
Channels_1B.count=10
Channels_2S.count=0
Channels_5X.count=0
;#GPS.prns=7,8
@ -343,30 +344,50 @@ Channels.in_acquisition=1
;# CHANNEL CONNECTION
Channel0.RF_channel_ID=0
Channel1.RF_channel_ID=1
Channel2.RF_channel_ID=2
Channel3.RF_channel_ID=2
Channel1.RF_channel_ID=0
Channel2.RF_channel_ID=0
Channel3.RF_channel_ID=0
Channel4.RF_channel_ID=0
Channel5.RF_channel_ID=0
Channel6.RF_channel_ID=0
Channel7.RF_channel_ID=0
Channel8.RF_channel_ID=0
Channel9.RF_channel_ID=0
Channel10.RF_channel_ID=1
Channel11.RF_channel_ID=1
Channel12.RF_channel_ID=1
Channel13.RF_channel_ID=1
Channel14.RF_channel_ID=1
Channel15.RF_channel_ID=1
Channel16.RF_channel_ID=1
Channel17.RF_channel_ID=1
Channel18.RF_channel_ID=1
Channel19.RF_channel_ID=1
Channel10.RF_channel_ID=0
Channel11.RF_channel_ID=0
Channel12.RF_channel_ID=0
Channel13.RF_channel_ID=0
Channel14.RF_channel_ID=0
Channel15.RF_channel_ID=0
Channel16.RF_channel_ID=0
Channel17.RF_channel_ID=0
Channel18.RF_channel_ID=0
Channel19.RF_channel_ID=0
Channel20.RF_channel_ID=0
Channel21.RF_channel_ID=0
Channel22.RF_channel_ID=0
Channel23.RF_channel_ID=0
Channel24.RF_channel_ID=0
Channel25.RF_channel_ID=0
Channel26.RF_channel_ID=0
Channel27.RF_channel_ID=0
Channel28.RF_channel_ID=0
Channel29.RF_channel_ID=0
Channel30.RF_channel_ID=2
Channel31.RF_channel_ID=2
Channel32.RF_channel_ID=2
Channel33.RF_channel_ID=2
Channel34.RF_channel_ID=2
Channel35.RF_channel_ID=2
Channel36.RF_channel_ID=2
Channel37.RF_channel_ID=2
Channel38.RF_channel_ID=2
Channel39.RF_channel_ID=2
;######### ACQUISITION GENERIC CONFIG ######
;#The following options are specific to each channel and overwrite the generic options
;# GPS L1 CA
Acquisition_1C.dump=false
Acquisition_1C.dump_filename=./acq_dump.dat
Acquisition_1C.item_type=gr_complex
@ -379,6 +400,30 @@ Acquisition_1C.doppler_step=250
Acquisition_1C.bit_transition_flag=false
Acquisition_1C.max_dwells=1
;# Galileo E1
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
Acquisition_1B.dump=false
;#filename: Log path and filename
Acquisition_1B.dump_filename=./acq_dump.dat
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
Acquisition_1B.item_type=gr_complex
;#if: Signal intermediate frequency in [Hz]
Acquisition_1B.if=0
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
Acquisition_1B.sampled_ms=4
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition
;#threshold: Acquisition threshold
;Acquisition_1B.threshold=0
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
Acquisition_1B.pfa=0.0000002
;#doppler_max: Maximum expected Doppler shift [Hz]
Acquisition_1B.doppler_max=5000
;#doppler_max: Doppler step in the grid search [Hz]
Acquisition_1B.doppler_step=125
;# GPS L2C M
Acquisition_2S.dump=false
Acquisition_2S.dump_filename=./acq_dump.dat
@ -399,16 +444,14 @@ Acquisition_5X.item_type=gr_complex
Acquisition_5X.if=0
Acquisition_5X.coherent_integration_time_ms=1
Acquisition_5X.implementation=Galileo_E5a_Noncoherent_IQ_Acquisition_CAF
Acquisition_5X.threshold=0.008
Acquisition_5X.doppler_max=10000
Acquisition_5X.doppler_step=250
Acquisition_5X.threshold=0.009
Acquisition_5X.doppler_max=5000
Acquisition_5X.doppler_step=125
Acquisition_5X.bit_transition_flag=false
Acquisition_5X.max_dwells=1
Acquisition_5X.CAF_window_hz=0 ; **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is desactivated. Recommended value 3000 Hz
Acquisition_5X.Zero_padding=0 ; **Only for E5a** Avoids power loss and doppler ambiguity in bit transitions by correlating one code with twice the input data length, ensuring that at least one full code is present without transitions. If set to 1 it is ON, if set to 0 it is OFF.
;######### TRACKING CONFIG ############
;######### GPS L1 C/A GENERIC TRACKING CONFIG ############
@ -422,6 +465,28 @@ Tracking_1C.dll_bw_hz=3.0;
Tracking_1C.order=3;
Tracking_1C.early_late_space_chips=0.5;
;######### GALILEO E1 TRK CONFIG ############
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
Tracking_1B.item_type=gr_complex
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
Tracking_1B.if=0
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
Tracking_1B.dump=false
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
Tracking_1B.dump_filename=../data/veml_tracking_ch_
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
Tracking_1B.pll_bw_hz=15.0;
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
Tracking_1B.dll_bw_hz=2.0;
;#order: PLL/DLL loop filter order [2] or [3]
Tracking_1B.order=3;
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo
Tracking_1B.early_late_space_chips=0.15;
;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6]
Tracking_1B.very_early_late_space_chips=0.6;
;######### GPS L2C GENERIC TRACKING CONFIG ############
Tracking_2S.implementation=GPS_L2_M_DLL_PLL_Tracking
@ -434,6 +499,7 @@ Tracking_2S.dll_bw_hz=0.25;
Tracking_2S.order=2;
Tracking_2S.early_late_space_chips=0.5;
;######### GALILEO E5 TRK CONFIG ############
Tracking_5X.implementation=Galileo_E5a_DLL_PLL_Tracking
Tracking_5X.item_type=gr_complex
Tracking_5X.if=0
@ -451,6 +517,9 @@ Tracking_5X.early_late_space_chips=0.5;
TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder
TelemetryDecoder_1C.dump=false
TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder
TelemetryDecoder_1B.dump=false
TelemetryDecoder_2S.implementation=GPS_L2C_Telemetry_Decoder
TelemetryDecoder_2S.dump=false

File diff suppressed because it is too large Load Diff

View File

@ -74,21 +74,21 @@ rtklib_solver::rtklib_solver(int nchannels, std::string dump_filename, bool flag
// ############# ENABLE DATA FILE LOG #################
if (d_flag_dump_enabled == true)
{
if (d_dump_file.is_open() == false)
{
if (d_dump_file.is_open() == false)
{
try
{
d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit);
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
LOG(INFO) << "PVT lib dump enabled Log file: " << d_dump_filename.c_str();
}
catch (const std::ifstream::failure &e)
{
LOG(WARNING) << "Exception opening PVT lib dump file " << e.what();
}
}
try
{
d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit);
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
LOG(INFO) << "PVT lib dump enabled Log file: " << d_dump_filename.c_str();
}
catch (const std::ifstream::failure &e)
{
LOG(WARNING) << "Exception opening PVT lib dump file " << e.what();
}
}
}
}
@ -118,194 +118,243 @@ bool rtklib_solver::get_PVT(std::map<int,Gnss_Synchro> gnss_observables_map, dou
for(gnss_observables_iter = gnss_observables_map.begin();
gnss_observables_iter != gnss_observables_map.end();
gnss_observables_iter++)
{
switch(gnss_observables_iter->second.System)
{
switch(gnss_observables_iter->second.System)
case 'E':
{
std::string sig_(gnss_observables_iter->second.Signal);
// Galileo E1
if(sig_.compare("1B") == 0)
{
case 'E':
// 1 Gal - find the ephemeris for the current GALILEO SV observation. The SV PRN ID is the map key
galileo_ephemeris_iter = galileo_ephemeris_map.find(gnss_observables_iter->second.PRN);
if (galileo_ephemeris_iter != galileo_ephemeris_map.end())
{
// 1 Gal - find the ephemeris for the current GALILEO SV observation. The SV PRN ID is the map key
galileo_ephemeris_iter = galileo_ephemeris_map.find(gnss_observables_iter->second.PRN);
if (galileo_ephemeris_iter != galileo_ephemeris_map.end())
//convert ephemeris from GNSS-SDR class to RTKLIB structure
eph_data[valid_obs] = eph_to_rtklib(galileo_ephemeris_iter->second);
//convert observation from GNSS-SDR class to RTKLIB structure
obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}};
obs_data[valid_obs] = insert_obs_to_rtklib(newobs,
gnss_observables_iter->second,
galileo_ephemeris_iter->second.WN_5,
0);
valid_obs++;
}
else // the ephemeris are not available for this SV
{
DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN;
}
}
// Galileo E5
if(sig_.compare("5X") == 0)
{
// 1 Gal - find the ephemeris for the current GALILEO SV observation. The SV PRN ID is the map key
galileo_ephemeris_iter = galileo_ephemeris_map.find(gnss_observables_iter->second.PRN);
if (galileo_ephemeris_iter != galileo_ephemeris_map.end())
{
bool found_E1_obs=false;
for (int i = 0; i < valid_obs; i++)
{
if (eph_data[i].sat == (static_cast<int>(gnss_observables_iter->second.PRN+NSATGPS+NSATGLO)))
{
//convert ephemeris from GNSS-SDR class to RTKLIB structure
eph_data[valid_obs] = eph_to_rtklib(galileo_ephemeris_iter->second);
//convert observation from GNSS-SDR class to RTKLIB structure
obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}};
obs_data[valid_obs] = insert_obs_to_rtklib(newobs,
obs_data[i] = insert_obs_to_rtklib(obs_data[i],
gnss_observables_iter->second,
galileo_ephemeris_iter->second.WN_5,
0);
valid_obs++;
2);//Band 3 (L5/E5)
found_E1_obs=true;
break;
}
else // the ephemeris are not available for this SV
{
DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN;
}
break;
}
if (!found_E1_obs)
{
//insert Galileo E5 obs as new obs and also insert its ephemeris
//convert ephemeris from GNSS-SDR class to RTKLIB structure
eph_data[valid_obs] = eph_to_rtklib(galileo_ephemeris_iter->second);
//convert observation from GNSS-SDR class to RTKLIB structure
obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}};
obs_data[valid_obs] = insert_obs_to_rtklib(newobs,
gnss_observables_iter->second,
galileo_ephemeris_iter->second.WN_5,
2); //Band 3 (L5/E5)
valid_obs++;
}
}
case 'G':
else // the ephemeris are not available for this SV
{
// 1 GPS - find the ephemeris for the current GPS SV observation. The SV PRN ID is the map key
std::string sig_(gnss_observables_iter->second.Signal);
if(sig_.compare("1C") == 0)
{
gps_ephemeris_iter = gps_ephemeris_map.find(gnss_observables_iter->second.PRN);
if (gps_ephemeris_iter != gps_ephemeris_map.end())
{
//convert ephemeris from GNSS-SDR class to RTKLIB structure
eph_data[valid_obs] = eph_to_rtklib(gps_ephemeris_iter->second);
//convert observation from GNSS-SDR class to RTKLIB structure
obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}};
obs_data[valid_obs] = insert_obs_to_rtklib(newobs,
gnss_observables_iter->second,
gps_ephemeris_iter->second.i_GPS_week,
0);
valid_obs++;
}
else // the ephemeris are not available for this SV
{
DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->first;
}
}
if(sig_.compare("2S") == 0)
{
gps_cnav_ephemeris_iter = gps_cnav_ephemeris_map.find(gnss_observables_iter->second.PRN);
if (gps_cnav_ephemeris_iter != gps_cnav_ephemeris_map.end())
{
// 1. Find the same satellite in GPS L1 band
gps_ephemeris_iter = gps_ephemeris_map.find(gnss_observables_iter->second.PRN);
if (gps_ephemeris_iter != gps_ephemeris_map.end())
{
// 2. If found, replace the existing GPS L1 ephemeris with the GPS L2 ephemeris
// (more precise!), and attach the L2 observation to the L1 observation in RTKLIB structure
for (int i = 0; i < valid_obs; i++)
{
if (eph_data[i].sat == static_cast<int>(gnss_observables_iter->second.PRN))
{
eph_data[i] = eph_to_rtklib(gps_cnav_ephemeris_iter->second);
obs_data[valid_obs] = insert_obs_to_rtklib(obs_data[valid_obs],
gnss_observables_iter->second,
gps_cnav_ephemeris_iter->second.i_GPS_week,
1);//Band 2 (L2)
break;
}
}
}
else
{
// 3. If not found, insert the GPS L2 ephemeris and the observation
//convert ephemeris from GNSS-SDR class to RTKLIB structure
eph_data[valid_obs] = eph_to_rtklib(gps_cnav_ephemeris_iter->second);
//convert observation from GNSS-SDR class to RTKLIB structure
obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}};
obs_data[valid_obs] = insert_obs_to_rtklib(newobs,
gnss_observables_iter->second,
gps_cnav_ephemeris_iter->second.i_GPS_week,
1);//Band 2 (L2)
valid_obs++;
}
}
else // the ephemeris are not available for this SV
{
DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN;
}
}
break;
DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN;
}
default :
DLOG(INFO) << "Hybrid observables: Unknown GNSS";
break;
}
break;
}
case 'G':
{
// GPS L1
// 1 GPS - find the ephemeris for the current GPS SV observation. The SV PRN ID is the map key
std::string sig_(gnss_observables_iter->second.Signal);
if(sig_.compare("1C") == 0)
{
gps_ephemeris_iter = gps_ephemeris_map.find(gnss_observables_iter->second.PRN);
if (gps_ephemeris_iter != gps_ephemeris_map.end())
{
//convert ephemeris from GNSS-SDR class to RTKLIB structure
eph_data[valid_obs] = eph_to_rtklib(gps_ephemeris_iter->second);
//convert observation from GNSS-SDR class to RTKLIB structure
obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}};
obs_data[valid_obs] = insert_obs_to_rtklib(newobs,
gnss_observables_iter->second,
gps_ephemeris_iter->second.i_GPS_week,
0);
valid_obs++;
}
else // the ephemeris are not available for this SV
{
DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->first;
}
}
//GPS L2
if(sig_.compare("2S") == 0)
{
gps_cnav_ephemeris_iter = gps_cnav_ephemeris_map.find(gnss_observables_iter->second.PRN);
if (gps_cnav_ephemeris_iter != gps_cnav_ephemeris_map.end())
{
// 1. Find the same satellite in GPS L1 band
gps_ephemeris_iter = gps_ephemeris_map.find(gnss_observables_iter->second.PRN);
if (gps_ephemeris_iter != gps_ephemeris_map.end())
{
// 2. If found, replace the existing GPS L1 ephemeris with the GPS L2 ephemeris
// (more precise!), and attach the L2 observation to the L1 observation in RTKLIB structure
for (int i = 0; i < valid_obs; i++)
{
if (eph_data[i].sat == static_cast<int>(gnss_observables_iter->second.PRN))
{
eph_data[i] = eph_to_rtklib(gps_cnav_ephemeris_iter->second);
obs_data[i] = insert_obs_to_rtklib(obs_data[i],
gnss_observables_iter->second,
gps_cnav_ephemeris_iter->second.i_GPS_week,
1);//Band 2 (L2)
break;
}
}
}
else
{
// 3. If not found, insert the GPS L2 ephemeris and the observation
//convert ephemeris from GNSS-SDR class to RTKLIB structure
eph_data[valid_obs] = eph_to_rtklib(gps_cnav_ephemeris_iter->second);
//convert observation from GNSS-SDR class to RTKLIB structure
obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}};
obs_data[valid_obs] = insert_obs_to_rtklib(newobs,
gnss_observables_iter->second,
gps_cnav_ephemeris_iter->second.i_GPS_week,
1);//Band 2 (L2)
valid_obs++;
}
}
else // the ephemeris are not available for this SV
{
DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN;
}
}
break;
}
default :
DLOG(INFO) << "Hybrid observables: Unknown GNSS";
break;
}
}
// **********************************************************************
// ****** SOLVE PVT******************************************************
// **********************************************************************
// **********************************************************************
// ****** SOLVE PVT******************************************************
// **********************************************************************
b_valid_position = false;
if (valid_obs > 0)
b_valid_position = false;
if (valid_obs > 0)
{
int result = 0;
nav_t nav_data;
nav_data.eph = eph_data;
nav_data.n = valid_obs;
for (int i = 0; i < MAXSAT; i++)
{
nav_data.lam[i][0] = SPEED_OF_LIGHT / FREQ1; /* L1/E1 */
nav_data.lam[i][1] = SPEED_OF_LIGHT / FREQ2; /* L2 */
nav_data.lam[i][2] = SPEED_OF_LIGHT / FREQ5; /* L2 */
}
{
nav_data.lam[i][0] = SPEED_OF_LIGHT / FREQ1; /* L1/E1 */
nav_data.lam[i][1] = SPEED_OF_LIGHT / FREQ2; /* L2 */
nav_data.lam[i][2] = SPEED_OF_LIGHT / FREQ5; /* L5/E5 */
}
result = rtkpos(&rtk_, obs_data, valid_obs, &nav_data);
if(result == 0)
{
LOG(INFO) << "RTKLIB rtkpos error message: " << rtk_.errbuf;
d_rx_dt_s = 0; //reset rx time estimation
d_valid_observations = 0;
}
{
LOG(INFO) << "RTKLIB rtkpos error message: " << rtk_.errbuf;
d_rx_dt_s = 0; //reset rx time estimation
d_valid_observations = 0;
}
else
{
d_valid_observations = rtk_.sol.ns; //record the number of valid satellites used by the PVT solver
pvt_sol = rtk_.sol;
b_valid_position = true;
arma::vec rx_position_and_time(4);
rx_position_and_time(0) = pvt_sol.rr[0];
rx_position_and_time(1) = pvt_sol.rr[1];
rx_position_and_time(2) = pvt_sol.rr[2];
rx_position_and_time(3) = pvt_sol.dtr[0];
d_rx_pos = rx_position_and_time.rows(0, 2); // save ECEF position for the next iteration
d_rx_dt_s += rx_position_and_time(3) / GPS_C_m_s; // accumulate the rx time error for the next iteration [meters]->[seconds]
DLOG(INFO) << "RTKLIB Position at TOW=" << Rx_time << " in ECEF (X,Y,Z,t[meters]) = " << rx_position_and_time;
boost::posix_time::ptime p_time;
gtime_t rtklib_utc_time = gpst2utc(pvt_sol.time);
p_time = boost::posix_time::from_time_t(rtklib_utc_time.time);
p_time+=boost::posix_time::microseconds(round(rtklib_utc_time.sec * 1e6));
d_position_UTC_time = p_time;
cart2geo(static_cast<double>(rx_position_and_time(0)), static_cast<double>(rx_position_and_time(1)), static_cast<double>(rx_position_and_time(2)), 4);
DLOG(INFO) << "RTKLIB 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]" << " RX time offset= " << d_rx_dt_s << " [s]";
// ######## LOG FILE #########
if(d_flag_dump_enabled == true)
{
d_valid_observations = rtk_.sol.ns; //record the number of valid satellites used by the PVT solver
pvt_sol = rtk_.sol;
b_valid_position = true;
arma::vec rx_position_and_time(4);
rx_position_and_time(0) = pvt_sol.rr[0];
rx_position_and_time(1) = pvt_sol.rr[1];
rx_position_and_time(2) = pvt_sol.rr[2];
rx_position_and_time(3) = pvt_sol.dtr[0];
d_rx_pos = rx_position_and_time.rows(0, 2); // save ECEF position for the next iteration
d_rx_dt_s += rx_position_and_time(3) / GPS_C_m_s; // accumulate the rx time error for the next iteration [meters]->[seconds]
DLOG(INFO) << "RTKLIB Position at TOW=" << Rx_time << " in ECEF (X,Y,Z,t[meters]) = " << rx_position_and_time;
boost::posix_time::ptime p_time;
gtime_t rtklib_utc_time = gpst2utc(pvt_sol.time);
p_time = boost::posix_time::from_time_t(rtklib_utc_time.time);
p_time+=boost::posix_time::microseconds(round(rtklib_utc_time.sec * 1e6));
d_position_UTC_time = p_time;
cart2geo(static_cast<double>(rx_position_and_time(0)), static_cast<double>(rx_position_and_time(1)), static_cast<double>(rx_position_and_time(2)), 4);
DLOG(INFO) << "RTKLIB 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]" << " RX time offset= " << d_rx_dt_s << " [s]";
// ######## LOG FILE #########
if(d_flag_dump_enabled == true)
{
// MULTIPLEXED FILE RECORDING - Record results to file
try
{
double tmp_double;
// PVT GPS time
tmp_double = Rx_time;
d_dump_file.write((char*)&tmp_double, sizeof(double));
// ECEF User Position East [m]
tmp_double = rx_position_and_time(0);
d_dump_file.write((char*)&tmp_double, sizeof(double));
// ECEF User Position North [m]
tmp_double = rx_position_and_time(1);
d_dump_file.write((char*)&tmp_double, sizeof(double));
// ECEF User Position Up [m]
tmp_double = rx_position_and_time(2);
d_dump_file.write((char*)&tmp_double, sizeof(double));
// User clock offset [s]
tmp_double = rx_position_and_time(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)
{
LOG(WARNING) << "Exception writing PVT LS dump file " << e.what();
}
}
// MULTIPLEXED FILE RECORDING - Record results to file
try
{
double tmp_double;
// PVT GPS time
tmp_double = Rx_time;
d_dump_file.write((char*)&tmp_double, sizeof(double));
// ECEF User Position East [m]
tmp_double = rx_position_and_time(0);
d_dump_file.write((char*)&tmp_double, sizeof(double));
// ECEF User Position North [m]
tmp_double = rx_position_and_time(1);
d_dump_file.write((char*)&tmp_double, sizeof(double));
// ECEF User Position Up [m]
tmp_double = rx_position_and_time(2);
d_dump_file.write((char*)&tmp_double, sizeof(double));
// User clock offset [s]
tmp_double = rx_position_and_time(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)
{
LOG(WARNING) << "Exception writing PVT LS dump file " << e.what();
}
}
}
}
return b_valid_position;
}
return b_valid_position;
}

View File

@ -147,6 +147,7 @@ int hybrid_observables_cc::general_work (int noutput_items,
*/
for (unsigned int i = 0; i < d_nchannels; i++)
{
current_gnss_synchro[i].Flag_valid_pseudorange=false;
n_consume[i] = ninput_items[i];// full throttle
for (int j = 0; j < n_consume[i]; j++)
{
@ -186,7 +187,6 @@ int hybrid_observables_cc::general_work (int noutput_items,
gnss_synchro_map.insert(std::pair<int, Gnss_Synchro>(
d_gnss_synchro_history_queue[i].front().Channel_ID,
d_gnss_synchro_history_queue[i].front()));
}
gnss_synchro_map_iter = min_element(gnss_synchro_map.begin(),
gnss_synchro_map.end(),

View File

@ -188,10 +188,9 @@ void galileo_e5a_telemetry_decoder_cc::decode_word(double *page_symbols,int fram
}
galileo_e5a_telemetry_decoder_cc::galileo_e5a_telemetry_decoder_cc(
Gnss_Satellite satellite,
bool dump) :
gr::block("galileo_e5a_telemetry_decoder_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
Gnss_Satellite satellite, bool dump) : gr::block("galileo_e5a_telemetry_decoder_cc",
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{
// Telemetry Bit transition synchronization port out
this->message_port_register_out(pmt::mp("preamble_timestamp_s"));
@ -245,10 +244,8 @@ galileo_e5a_telemetry_decoder_cc::~galileo_e5a_telemetry_decoder_cc()
int galileo_e5a_telemetry_decoder_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
{
//
const Gnss_Synchro **in = (const Gnss_Synchro **) &input_items[0]; //Get the input samples pointer
Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0];
const Gnss_Synchro *in = (const Gnss_Synchro *) input_items[0]; // input
Gnss_Synchro *out = (Gnss_Synchro *) output_items[0]; // output
/* Terminology: Prompt: output from tracking Prompt correlator (Prompt samples)
* Symbol: encoded navigation bits. 1 symbol = 20 samples in E5a
* Bit: decoded navigation bits forming words as described in Galileo ICD
@ -260,9 +257,9 @@ int galileo_e5a_telemetry_decoder_cc::general_work (int noutput_items __attribut
{
case 0:
{
if (in[0][0].Prompt_I != 0)
if (in[0].Prompt_I != 0)
{
d_current_symbol += in[0][0].Prompt_I;
d_current_symbol += in[0].Prompt_I;
if (d_prompt_counter == GALILEO_FNAV_CODES_PER_SYMBOL - 1)
{
if (d_current_symbol > 0)
@ -290,7 +287,7 @@ int galileo_e5a_telemetry_decoder_cc::general_work (int noutput_items __attribut
}
case 1:
{
d_current_symbol += in[0][0].Prompt_I;
d_current_symbol += in[0].Prompt_I;
if (d_prompt_counter == GALILEO_FNAV_CODES_PER_SYMBOL - 1)
{
if (d_current_symbol > 0)
@ -354,7 +351,7 @@ int galileo_e5a_telemetry_decoder_cc::general_work (int noutput_items __attribut
}
case 2:
{
d_current_symbol += in[0][0].Prompt_I;
d_current_symbol += in[0].Prompt_I;
if (d_prompt_counter == GALILEO_FNAV_CODES_PER_SYMBOL - 1)
{
if (d_current_symbol > 0)
@ -415,7 +412,7 @@ int galileo_e5a_telemetry_decoder_cc::general_work (int noutput_items __attribut
{
d_flag_frame_sync = true;
DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at "
<< in[0][0].Tracking_sample_counter << " [samples]"; }
<< in[0].Tracking_sample_counter << " [samples]"; }
d_symbol_counter = 0; // d_page_symbols start right after preamble and finish at the end of next preamble.
}
else
@ -443,12 +440,12 @@ int galileo_e5a_telemetry_decoder_cc::general_work (int noutput_items __attribut
break;
}
}
consume_each(1);
// UPDATE GNSS SYNCHRO DATA
Gnss_Synchro current_synchro_data; //structure to save the synchronization information and send the output object to the next block
//1. Copy the current tracking output
current_synchro_data = in[0][0];
current_synchro_data = in[0];
//2. Add the telemetry decoder information
if (this->d_flag_preamble == true and d_nav.flag_TOW_set == true)
//update TOW at the preamble instant
@ -524,7 +521,8 @@ int galileo_e5a_telemetry_decoder_cc::general_work (int noutput_items __attribut
}
d_sample_counter++; //count for the processed samples
//3. Make the output (copy the object contents to the GNURadio reserved memory)
*out[0] = current_synchro_data;
out[0] = current_synchro_data;
consume_each(1);
return 1;
}

View File

@ -110,7 +110,7 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(
d_channel = 0;
flag_PLL_180_deg_phase_locked = false;
//set minimum output buffer to avoid deadlock when combined with other GNSS systems or signals with slower symbol rates
this->set_min_output_buffer(3000);
this->set_min_output_buffer(5000);
}

View File

@ -400,7 +400,7 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attri
current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;
current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz;
current_synchro_data.Flag_valid_symbol_output = true;
current_synchro_data.correlation_length_ms = 4;
current_synchro_data.correlation_length_ms = Galileo_E1_CODE_PERIOD_MS;
}
else

View File

@ -646,6 +646,7 @@ int Galileo_E5a_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribute
}
current_synchro_data.fs=d_fs_in;
current_synchro_data.correlation_length_ms=GALILEO_E5a_CODE_PERIOD_MS;
*out[0] = current_synchro_data;
if(d_dump)

View File

@ -52,6 +52,7 @@ const double GALILEO_F = -4.442807309e-10; //!< Constant, [s/(m)^(1/2)]
const double Galileo_E1_FREQ_HZ = FREQ1; //!< Galileo E1 carrier frequency [Hz]
const double Galileo_E1_CODE_CHIP_RATE_HZ = 1.023e6; //!< Galileo E1 code rate [chips/s]
const double Galileo_E1_CODE_PERIOD = 0.004; //!< Galileo E1 code period [s]
const int Galileo_E1_CODE_PERIOD_MS = 4; //!< Galileo E1 code period [ms]
const double Galileo_E1_SUB_CARRIER_A_RATE_HZ = 1.023e6; //!< Galileo E1 sub-carrier 'a' rate [Hz]
const double Galileo_E1_SUB_CARRIER_B_RATE_HZ = 6.138e6; //!< Galileo E1 sub-carrier 'b' rate [Hz]
const double Galileo_E1_B_CODE_LENGTH_CHIPS = 4092.0; //!< Galileo E1-B code length [chips]

View File

@ -46,7 +46,8 @@ const double Galileo_E5a_Q_TIERED_CODE_PERIOD = 0.100; //!< Galileo E5a-Q tie
const int Galileo_E5a_CODE_LENGTH_CHIPS = 10230; //!< Galileo E5a primary code length [chips]
const int Galileo_E5a_I_SECONDARY_CODE_LENGTH = 20; //!< Galileo E5a-I secondary code length [chips]
const int Galileo_E5a_Q_SECONDARY_CODE_LENGTH = 100; //!< Galileo E5a-Q secondary code length [chips]
const double GALILEO_E5a_CODE_PERIOD = 0.001;
const double GALILEO_E5a_CODE_PERIOD = 0.001; //!< Galileo E1 primary code period [s]
const int GALILEO_E5a_CODE_PERIOD_MS = 1; //!< Galileo E1 primary code period [ms]
const int Galileo_E5a_SYMBOL_RATE_BPS = 50; //!< Galileo E5a symbol rate [bits/second]
const int Galileo_E5a_NUMBER_OF_CODES = 50;