mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-13 11:40:33 +00:00
Major update to improve the GNSS-SDR pseudorange precision and correct some PVT bugs:
- Updated all available trackings to generate the tracking_timestamp_secs taking into account the remainder code phase. - Updated the telemetry decoder to track the number of symbol shifted from the preamble start symbol (to be used in observables). - Updated observables to align the reference channel symbol with the corresponding symbols in the other channels and compute pseudorranges using the common transmission time algorithm. - Updated PVT to independize the display output rate from the RINEX and KML log files. New options available in config file! - Some minor improvements and code cleaning. git-svn-id: https://svn.code.sf.net/p/gnss-sdr/code/trunk@193 64b25241-fba3-4117-9849-534c7e92360d
This commit is contained in:
parent
89a67c93e8
commit
9d34147e0f
@ -3,29 +3,29 @@
|
||||
|
||||
;######### GLOBAL OPTIONS ##################
|
||||
;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz].
|
||||
GNSS-SDR.internal_fs_hz=2000000
|
||||
GNSS-SDR.internal_fs_hz=4000000
|
||||
|
||||
;######### CONTROL_THREAD CONFIG ############
|
||||
ControlThread.wait_for_flowgraph=false
|
||||
|
||||
;######### SIGNAL_SOURCE CONFIG ############
|
||||
;#implementation: Use File_Signal_Source or UHD_Signal_Source (experimental)
|
||||
SignalSource.implementation=UHD_Signal_Source
|
||||
;#implementation: Use File_Signal_Source or UHD_Signal_Source or GN3S_Signal_Source (experimental)
|
||||
SignalSource.implementation=File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
SignalSource.filename=/media/DATALOGGER/signals/Agilent GPS Generator/cap2/agilent_cap2.dat
|
||||
SignalSource.filename=/media/DATALOGGER/signals/Agilent GPS Generator/cap3/san_francisco_2msps_v2010.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
SignalSource.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Original Signal sampling frequency in [Hz]
|
||||
SignalSource.sampling_frequency=2000000
|
||||
SignalSource.sampling_frequency=4000000
|
||||
|
||||
;#freq: RF front-end center frequency in [Hz]
|
||||
SignalSource.freq=1575420000
|
||||
|
||||
;#gain: Front-end Gain in [dB]
|
||||
SignalSource.gain=50
|
||||
SignalSource.gain=60
|
||||
|
||||
;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0)
|
||||
SignalSource.subdevice=B:0
|
||||
@ -39,6 +39,8 @@ SignalSource.repeat=false
|
||||
;#dump: Dump the Signal source data to a file. Disable this option in this version
|
||||
SignalSource.dump=false
|
||||
|
||||
SignalSource.dump_filename=../data/signal_source.dat
|
||||
|
||||
SignalSource.dump_filename=../data/SignalSource.dat
|
||||
|
||||
;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing.
|
||||
@ -121,8 +123,8 @@ InputFilter.grid_density=16
|
||||
;## Resamples the input data.
|
||||
|
||||
;#implementation: Pass_Through disables this block
|
||||
Resampler.implementation=Direct_Resampler
|
||||
;Resampler.implementation=Pass_Through
|
||||
;Resampler.implementation=Direct_Resampler
|
||||
Resampler.implementation=Pass_Through
|
||||
|
||||
;#dump: Dump the filtered data to a file.
|
||||
InputFilter.dump=false
|
||||
@ -133,15 +135,15 @@ InputFilter.dump=../data/resampler.dat
|
||||
Resampler.item_type=gr_complex
|
||||
|
||||
;#sample_freq_in: the sample frequency of the input signal
|
||||
Resampler.sample_freq_in=2000000
|
||||
Resampler.sample_freq_in=4000000
|
||||
|
||||
;#sample_freq_out: the desired sample frequency of the output signal
|
||||
Resampler.sample_freq_out=2000000
|
||||
Resampler.sample_freq_out=4000000
|
||||
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available satellite channels.
|
||||
Channels.count=6
|
||||
Channels.count=5
|
||||
Channels.in_acquisition=1
|
||||
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
@ -209,42 +211,55 @@ Channel0.system=GPS
|
||||
Channel0.signal=1C
|
||||
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
Channel0.satellite=2
|
||||
Channel0.satellite=15
|
||||
Channel0.repeat_satellite=true
|
||||
|
||||
;######### CHANNEL 1 CONFIG ############
|
||||
|
||||
Channel1.system=GPS
|
||||
Channel1.signal=1C
|
||||
;Channel1.satellite=14
|
||||
Channel1.satellite=18
|
||||
Channel1.repeat_satellite=true
|
||||
|
||||
;######### CHANNEL 2 CONFIG ############
|
||||
|
||||
Channel2.system=GPS
|
||||
Channel2.signal=1C
|
||||
;Channel2.satellite=21
|
||||
Channel2.satellite=16
|
||||
Channel2.repeat_satellite=true
|
||||
|
||||
;######### CHANNEL 3 CONFIG ############
|
||||
|
||||
Channel3.system=GPS
|
||||
Channel3.signal=1C
|
||||
;Channel3.satellite=13
|
||||
Channel3.satellite=21
|
||||
Channel3.repeat_satellite=true
|
||||
|
||||
;######### CHANNEL 4 CONFIG ############
|
||||
|
||||
Channel4.system=GPS
|
||||
Channel4.signal=1C
|
||||
Channel4.satellite=3
|
||||
Channel4.repeat_satellite=true
|
||||
|
||||
;######### CHANNEL 3 CONFIG ############
|
||||
|
||||
Channel5.system=GPS
|
||||
Channel5.signal=1C
|
||||
;Channel5.satellite=21
|
||||
;Channel5.repeat_satellite=true
|
||||
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition.dump=false
|
||||
|
||||
;#filename: Log path and filename
|
||||
Acquisition.dump_filename=./acq_dump.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition.item_type=gr_complex
|
||||
|
||||
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition.if=0
|
||||
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition.sampled_ms=1
|
||||
|
||||
@ -253,75 +268,70 @@ Acquisition.sampled_ms=1
|
||||
;######### ACQUISITION CH 0 CONFIG ############
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition]
|
||||
Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
|
||||
;#threshold: Acquisition threshold
|
||||
Acquisition0.threshold=50
|
||||
|
||||
Acquisition0.threshold=70
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition0.doppler_max=10000
|
||||
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition0.doppler_step=250
|
||||
|
||||
;#repeat_satellite: Use only jointly with the satellte PRN ID option.
|
||||
;#Enable repeat_satellite to keep searching the same satellite during the runtime.
|
||||
;Acquisition0.repeat_satellite=true
|
||||
|
||||
|
||||
;######### ACQUISITION CH 1 CONFIG ############
|
||||
Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition1.threshold=50
|
||||
Acquisition1.threshold=70
|
||||
Acquisition1.doppler_max=10000
|
||||
Acquisition1.doppler_step=250
|
||||
;Acquisition1.repeat_satellite=true
|
||||
|
||||
|
||||
;######### ACQUISITION CH 2 CONFIG ############
|
||||
Acquisition2.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition2.threshold=50
|
||||
Acquisition2.threshold=70
|
||||
Acquisition2.doppler_max=10000
|
||||
Acquisition2.doppler_step=250
|
||||
;Acquisition2.repeat_satellite=true
|
||||
|
||||
|
||||
;######### ACQUISITION CH 3 CONFIG ############
|
||||
Acquisition3.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition3.threshold=50
|
||||
Acquisition3.threshold=70
|
||||
Acquisition3.doppler_max=10000
|
||||
Acquisition3.doppler_step=250
|
||||
;Acquisition3.repeat_satellite=true
|
||||
|
||||
|
||||
;######### ACQUISITION CH 4 CONFIG ############
|
||||
Acquisition4.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition4.threshold=50
|
||||
Acquisition4.threshold=70
|
||||
Acquisition4.doppler_max=10000
|
||||
Acquisition4.doppler_step=250
|
||||
;Acquisition4.repeat_satellite=true
|
||||
|
||||
|
||||
;######### ACQUISITION CH 5 CONFIG ############
|
||||
Acquisition5.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition5.threshold=50
|
||||
Acquisition5.threshold=70
|
||||
Acquisition5.doppler_max=10000
|
||||
Acquisition5.doppler_step=250
|
||||
;Acquisition5.repeat_satellite=true
|
||||
|
||||
|
||||
;######### ACQUISITION CH 6 CONFIG ############
|
||||
Acquisition6.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition6.threshold=50
|
||||
Acquisition6.threshold=70
|
||||
Acquisition6.doppler_max=10000
|
||||
Acquisition6.doppler_step=250
|
||||
;Acquisition6.repeat_satellite=true
|
||||
|
||||
|
||||
;######### ACQUISITION CH 7 CONFIG ############
|
||||
Acquisition7.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition7.threshold=50
|
||||
Acquisition7.threshold=70
|
||||
Acquisition7.doppler_max=10000
|
||||
Acquisition7.doppler_step=250
|
||||
;Acquisition7.repeat_satellite=true
|
||||
|
||||
|
||||
;######### ACQUISITION CH 8 CONFIG ############
|
||||
Acquisition8.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition8.threshold=50
|
||||
Acquisition8.threshold=70
|
||||
Acquisition8.doppler_max=10000
|
||||
Acquisition8.doppler_step=250
|
||||
;Acquisition8.repeat_satellite=true
|
||||
|
||||
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
@ -347,10 +357,10 @@ Tracking.pll_bw_hz=50.0;
|
||||
Tracking.dll_bw_hz=2.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking.fll_bw_hz=20.0;
|
||||
Tracking.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking.order=2;
|
||||
Tracking.order=3;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5]
|
||||
Tracking.early_late_space_chips=0.5;
|
||||
@ -358,14 +368,12 @@ Tracking.early_late_space_chips=0.5;
|
||||
;######### TELEMETRY DECODER CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A.
|
||||
TelemetryDecoder.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder.dump=false
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
||||
Observables.implementation=GPS_L1_CA_Observables
|
||||
|
||||
;#output_rate_ms: Period between two psudoranges outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms]
|
||||
Observables.output_rate_ms=100
|
||||
|
||||
;#dump: Enable or disable the Observables internal binary data file logging [true] or [false]
|
||||
Observables.dump=false
|
||||
|
||||
@ -378,11 +386,17 @@ Observables.dump_filename=./observables.dat
|
||||
PVT.implementation=GPS_L1_CA_PVT
|
||||
|
||||
;#averaging_depth: Number of PVT observations in the moving average algorithm
|
||||
PVT.averaging_depth=10
|
||||
PVT.averaging_depth=100
|
||||
|
||||
;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]
|
||||
PVT.flag_averaging=true
|
||||
|
||||
;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms]
|
||||
PVT.output_rate_ms=100;
|
||||
|
||||
;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms.
|
||||
PVT.display_rate_ms=500;
|
||||
|
||||
;#dump: Enable or disable the PVT internal binary data file logging [true] or [false]
|
||||
PVT.dump=false
|
||||
|
||||
|
@ -63,10 +63,15 @@ GpsL1CaPvt::GpsL1CaPvt(ConfigurationInterface* configuration,
|
||||
bool flag_averaging;
|
||||
flag_averaging = configuration->property(role + ".flag_averaging", false);
|
||||
|
||||
int output_rate_ms;
|
||||
output_rate_ms = configuration->property(role + ".output_rate_ms", 500);
|
||||
int display_rate_ms;
|
||||
display_rate_ms = configuration->property(role + ".display_rate_ms", 500);
|
||||
|
||||
dump_ = configuration->property(role + ".dump", false);
|
||||
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||
|
||||
pvt_ = gps_l1_ca_make_pvt_cc(in_streams_, queue_, dump_, dump_filename_, averaging_depth, flag_averaging);
|
||||
pvt_ = gps_l1_ca_make_pvt_cc(in_streams_, queue_, dump_, dump_filename_, averaging_depth, flag_averaging, output_rate_ms, display_rate_ms);
|
||||
|
||||
DLOG(INFO) << "pvt(" << pvt_->unique_id() << ")";
|
||||
// set the navigation msg queue;
|
||||
|
@ -40,41 +40,49 @@
|
||||
#include <glog/log_severity.h>
|
||||
#include <glog/logging.h>
|
||||
#include "control_message_factory.h"
|
||||
#include "boost/date_time/posix_time/posix_time.hpp"
|
||||
#include "gnss_synchro.h"
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
|
||||
gps_l1_ca_pvt_cc_sptr
|
||||
gps_l1_ca_make_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging)
|
||||
gps_l1_ca_make_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms)
|
||||
{
|
||||
return gps_l1_ca_pvt_cc_sptr(new gps_l1_ca_pvt_cc(nchannels, queue, dump, dump_filename, averaging_depth, flag_averaging));
|
||||
return gps_l1_ca_pvt_cc_sptr(new gps_l1_ca_pvt_cc(nchannels, queue, dump, dump_filename, averaging_depth, flag_averaging, output_rate_ms, display_rate_ms));
|
||||
}
|
||||
|
||||
|
||||
gps_l1_ca_pvt_cc::gps_l1_ca_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging) :
|
||||
gps_l1_ca_pvt_cc::gps_l1_ca_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms) :
|
||||
gr_block ("gps_l1_ca_pvt_cc", gr_make_io_signature (nchannels, nchannels, sizeof(Gnss_Synchro)),
|
||||
gr_make_io_signature(1, 1, sizeof(gr_complex)))
|
||||
{
|
||||
|
||||
d_output_rate_ms = output_rate_ms;
|
||||
d_display_rate_ms=display_rate_ms;
|
||||
d_queue = queue;
|
||||
d_dump = dump;
|
||||
d_nchannels = nchannels;
|
||||
d_dump_filename = dump_filename;
|
||||
std::string dump_ls_pvt_filename;
|
||||
dump_ls_pvt_filename=dump_filename;
|
||||
std::string kml_dump_filename;
|
||||
kml_dump_filename = d_dump_filename;
|
||||
kml_dump_filename.append(".kml");
|
||||
d_kml_dump.set_headers(kml_dump_filename);
|
||||
d_dump_filename.append(".dat");
|
||||
|
||||
d_dump_filename.append("_raw.dat");
|
||||
dump_ls_pvt_filename.append("_ls_pvt.dat");
|
||||
d_averaging_depth = averaging_depth;
|
||||
d_flag_averaging = flag_averaging;
|
||||
|
||||
d_ls_pvt = new gps_l1_ca_ls_pvt(nchannels,d_dump_filename,d_dump);
|
||||
d_ls_pvt = new gps_l1_ca_ls_pvt(nchannels,dump_ls_pvt_filename,d_dump);
|
||||
d_ls_pvt->set_averaging_depth(d_averaging_depth);
|
||||
d_ephemeris_clock_s = 0.0;
|
||||
|
||||
d_sample_counter = 0;
|
||||
|
||||
d_tx_time=0.0;
|
||||
|
||||
b_rinex_header_writen = false;
|
||||
rp = new Rinex_Printer();
|
||||
|
||||
@ -82,6 +90,24 @@ gps_l1_ca_pvt_cc::gps_l1_ca_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr que
|
||||
{
|
||||
nav_data_map[i] = Gps_Navigation_Message();
|
||||
}
|
||||
|
||||
// ############# ENABLE DATA FILE LOG #################
|
||||
if (d_dump == true)
|
||||
{
|
||||
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);
|
||||
std::cout << "PVT dump enabled Log file: " << d_dump_filename.c_str() << std::endl;
|
||||
}
|
||||
catch (std::ifstream::failure e) {
|
||||
std::cout << "Exception opening PVT dump file " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -127,8 +153,6 @@ int gps_l1_ca_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_ite
|
||||
{
|
||||
double pr = gnss_pseudoranges_iter->second.Pseudorange_m;
|
||||
pseudoranges[gnss_pseudoranges_iter->first] = pr;
|
||||
// std::cout << "Pseudoranges(SV ID,pseudorange [m]) =(" << gnss_pseudoranges_iter->first << ","
|
||||
// << gnss_pseudoranges_iter->second.pseudorange_m << ")" <<std::endl;
|
||||
}
|
||||
|
||||
// ############ 1. READ EPHEMERIS FROM QUEUE ######################
|
||||
@ -143,41 +167,86 @@ int gps_l1_ca_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_ite
|
||||
<< nav_msg.satelliteBlock[nav_msg.i_satellite_PRN]
|
||||
<< ")" << std::endl;
|
||||
d_last_nav_msg = nav_msg;
|
||||
d_ls_pvt->d_ephemeris[nav_msg.i_channel_ID] = nav_msg;
|
||||
nav_data_map[nav_msg.i_channel_ID] = nav_msg;
|
||||
|
||||
if (nav_msg.b_valid_ephemeris_set_flag==true)
|
||||
{
|
||||
d_ls_pvt->d_ephemeris[nav_msg.i_channel_ID] = nav_msg;
|
||||
nav_data_map[nav_msg.i_channel_ID] = nav_msg;
|
||||
}
|
||||
// **** update pseudoranges clock ****
|
||||
if (nav_msg.i_satellite_PRN == gnss_pseudoranges_iter->second.PRN)
|
||||
{
|
||||
d_ephemeris_clock_s = d_last_nav_msg.d_TOW;
|
||||
d_ephemeris_timestamp_ms = d_last_nav_msg.d_subframe1_timestamp_ms;
|
||||
d_ephemeris_timestamp_ms = d_last_nav_msg.d_subframe_timestamp_ms;
|
||||
}
|
||||
}
|
||||
|
||||
// ############ 2. COMPUTE THE PVT ################################
|
||||
// write the pseudoranges to RINEX OBS file
|
||||
// 1- need a valid clock
|
||||
if (d_ephemeris_clock_s > 0 and d_last_nav_msg.i_satellite_PRN > 0)
|
||||
if (d_ephemeris_clock_s > 0 and d_last_nav_msg.i_satellite_PRN > 0 and d_last_nav_msg.b_valid_ephemeris_set_flag==true)
|
||||
{
|
||||
// compute on the fly PVT solution
|
||||
//std::cout<<"diff_clock_ephemeris="<<(gnss_pseudoranges_iter->second.timestamp_ms-d_ephemeris_timestamp_ms)/1000.0<<"\r\n";
|
||||
if (d_ls_pvt->get_PVT(gnss_pseudoranges_map,
|
||||
d_ephemeris_clock_s + (gnss_pseudoranges_iter->second.Pseudorange_timestamp_ms - d_ephemeris_timestamp_ms)/1000.0,
|
||||
d_flag_averaging) == true)
|
||||
{
|
||||
d_kml_dump.print_position(d_ls_pvt, d_flag_averaging);
|
||||
if (!b_rinex_header_writen) // & we have utc data in nav message!
|
||||
{
|
||||
rp->rinex_nav_header(rp->navFile, d_last_nav_msg);
|
||||
rp->rinex_obs_header(rp->obsFile, d_last_nav_msg);
|
||||
b_rinex_header_writen = true; // do not write header anymore
|
||||
}
|
||||
if(b_rinex_header_writen) // Put here another condition to separate annotations (e.g 30 s)
|
||||
{
|
||||
rp->log_rinex_nav(rp->navFile, nav_data_map);
|
||||
rp->log_rinex_obs(rp->obsFile, d_last_nav_msg, pseudoranges);
|
||||
}
|
||||
}
|
||||
double clock_error;
|
||||
double satellite_tx_time_using_timestamps;
|
||||
//for GPS L1 C/A: t_tx=TOW+N_symbols_from_TOW*T_symbol
|
||||
//Notice that the TOW is decoded AFTER processing the subframe -> we ned to add ONE subframe duration to t_tx
|
||||
d_tx_time=d_ephemeris_clock_s + gnss_pseudoranges_iter->second.Pseudorange_symbol_shift/(double)GPS_CA_TELEMETRY_RATE_SYMBOLS_SECOND+GPS_SUBFRAME_SECONDS;
|
||||
//Perform an extra check to verify the TOW update (the ephemeris queue is ASYNCHRONOUS to the GNU Radio Gnss_Synchro sample stream)
|
||||
//-> compute the t_tx_timestamps using the symbols timestamp (it is affected by code Doppler, but it is not wrapped like N_symbols_from_TOW)
|
||||
satellite_tx_time_using_timestamps=d_ephemeris_clock_s + (gnss_pseudoranges_iter->second.Pseudorange_timestamp_ms-d_ephemeris_timestamp_ms)/1000.0;
|
||||
//->compute the absolute error between both T_tx
|
||||
clock_error=std::abs(d_tx_time-satellite_tx_time_using_timestamps);
|
||||
// -> The symbol conter N_symbols_from_TOW will be resetted every new received telemetry word, if the TOW is not uptated, both t_tx and t_tx_timestamps times will difer by more than 1 seconds.
|
||||
if (clock_error<1){
|
||||
// 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)
|
||||
{
|
||||
if (d_ls_pvt->get_PVT(gnss_pseudoranges_map,d_tx_time,d_flag_averaging) == true)
|
||||
{
|
||||
d_kml_dump.print_position(d_ls_pvt, d_flag_averaging);
|
||||
if (!b_rinex_header_writen) // & we have utc data in nav message!
|
||||
{
|
||||
rp->rinex_nav_header(rp->navFile, d_last_nav_msg);
|
||||
rp->rinex_obs_header(rp->obsFile, d_last_nav_msg);
|
||||
b_rinex_header_writen = true; // do not write header anymore
|
||||
}
|
||||
if(b_rinex_header_writen) // Put here another condition to separate annotations (e.g 30 s)
|
||||
{
|
||||
rp->log_rinex_nav(rp->navFile, nav_data_map);
|
||||
rp->log_rinex_obs(rp->obsFile, d_last_nav_msg, pseudoranges);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if(d_dump == true)
|
||||
{
|
||||
// MULTIPLEXED FILE RECORDING - Record results to file
|
||||
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 = in[i][0].Pseudorange_symbol_shift;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
d_dump_file.write((char*)&d_tx_time, sizeof(double));
|
||||
}
|
||||
}
|
||||
catch (std::ifstream::failure e)
|
||||
{
|
||||
std::cout << "Exception writing observables dump file " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
consume_each(1); //one by one
|
||||
|
@ -48,7 +48,7 @@ class gps_l1_ca_pvt_cc;
|
||||
typedef boost::shared_ptr<gps_l1_ca_pvt_cc> gps_l1_ca_pvt_cc_sptr;
|
||||
|
||||
gps_l1_ca_pvt_cc_sptr
|
||||
gps_l1_ca_make_pvt_cc(unsigned int n_channels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging);
|
||||
gps_l1_ca_make_pvt_cc(unsigned int n_channels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms);
|
||||
|
||||
/*!
|
||||
* \brief This class implements a block that computes the PVT solution
|
||||
@ -59,9 +59,9 @@ class gps_l1_ca_pvt_cc : public gr_block
|
||||
private:
|
||||
|
||||
friend gps_l1_ca_pvt_cc_sptr
|
||||
gps_l1_ca_make_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging);
|
||||
gps_l1_ca_make_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms);
|
||||
|
||||
gps_l1_ca_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging);
|
||||
gps_l1_ca_pvt_cc(unsigned int nchannels, gr_msg_queue_sptr queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms);
|
||||
|
||||
gr_msg_queue_sptr d_queue;
|
||||
bool d_dump;
|
||||
@ -75,7 +75,8 @@ private:
|
||||
|
||||
int d_averaging_depth;
|
||||
bool d_flag_averaging;
|
||||
|
||||
int d_output_rate_ms;
|
||||
int d_display_rate_ms;
|
||||
long unsigned int d_sample_counter;
|
||||
|
||||
Kml_Printer d_kml_dump;
|
||||
@ -85,6 +86,7 @@ private:
|
||||
|
||||
double d_ephemeris_clock_s;
|
||||
double d_ephemeris_timestamp_ms;
|
||||
double d_tx_time;
|
||||
gps_l1_ca_ls_pvt *d_ls_pvt;
|
||||
|
||||
std::map<int,Gps_Navigation_Message> nav_data_map;
|
||||
|
@ -47,7 +47,8 @@ gps_l1_ca_ls_pvt::gps_l1_ca_ls_pvt(int nchannels,std::string dump_filename, bool
|
||||
d_dump_filename = dump_filename;
|
||||
d_flag_dump_enabled = flag_dump_to_file;
|
||||
d_averaging_depth = 0;
|
||||
|
||||
d_GPS_current_time=0;;
|
||||
b_valid_position=false;
|
||||
// ############# ENABLE DATA FILE LOG #################
|
||||
if (d_flag_dump_enabled == true)
|
||||
{
|
||||
@ -277,7 +278,7 @@ bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map,
|
||||
obs(i) = 1; // to avoid algorithm problems (divide by zero)
|
||||
}
|
||||
}
|
||||
std::cout<<"PVT: valid observations="<<valid_obs<<std::endl;
|
||||
LOG_AT_LEVEL(INFO) <<"PVT: valid observations="<<valid_obs<<std::endl;
|
||||
if (valid_obs>=4)
|
||||
{
|
||||
arma::vec mypos;
|
||||
@ -286,11 +287,15 @@ bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map,
|
||||
cart2geo(mypos(0), mypos(1), mypos(2), 4);
|
||||
|
||||
// Compute UTC time and print PVT solution
|
||||
boost::posix_time::time_duration t = boost::posix_time::seconds(utc + 604800*(double)GPS_week);
|
||||
boost::posix_time::time_duration t = boost::posix_time::seconds(utc + 604800.0*(double)GPS_week);
|
||||
boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t);
|
||||
std::cout << "Position at " << boost::posix_time::to_simple_string(p_time)
|
||||
d_position_UTC_time = p_time;
|
||||
GPS_current_time=GPS_corrected_time;
|
||||
|
||||
LOG_AT_LEVEL(INFO) << "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;
|
||||
|
||||
// ######## LOG FILE #########
|
||||
if(d_flag_dump_enabled == true)
|
||||
{
|
||||
@ -355,6 +360,7 @@ bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map,
|
||||
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
|
||||
@ -368,6 +374,7 @@ bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map,
|
||||
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
|
||||
// output the average, although it will not have the full historic available
|
||||
// d_avg_latitude_d=0;
|
||||
@ -386,11 +393,13 @@ bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map,
|
||||
}
|
||||
else
|
||||
{
|
||||
b_valid_position=true;
|
||||
return true;//indicates that the returned position is valid
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
b_valid_position=false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "gps_navigation_message.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "armadillo"
|
||||
#include "boost/date_time/posix_time/posix_time.hpp"
|
||||
|
||||
#include "gnss_synchro.h"
|
||||
|
||||
@ -59,7 +60,11 @@ private:
|
||||
public:
|
||||
int d_nchannels; //! Number of available channels for positioning
|
||||
Gps_Navigation_Message* d_ephemeris;
|
||||
double d_pseudoranges_time_ms;
|
||||
double d_GPS_current_time;
|
||||
boost::posix_time::ptime d_position_UTC_time;
|
||||
|
||||
bool b_valid_position;
|
||||
|
||||
double d_latitude_d; //! Latitude in degrees
|
||||
double d_longitude_d; //! Longitude in degrees
|
||||
double d_height_m; //! Height [m]
|
||||
|
@ -41,11 +41,15 @@ bool Kml_Printer::set_headers(std::string filename)
|
||||
|
||||
time ( &rawtime );
|
||||
timeinfo = localtime ( &rawtime );
|
||||
|
||||
kml_file.open(filename.c_str());
|
||||
if (kml_file.is_open())
|
||||
{
|
||||
DLOG(INFO) << "KML printer writing on " << filename.c_str();
|
||||
|
||||
// Set iostream numeric format and precision
|
||||
kml_file.setf(kml_file.fixed,kml_file.floatfield);
|
||||
kml_file<<std::setprecision(14);
|
||||
|
||||
kml_file << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl
|
||||
<< "<kml xmlns=\"http://www.opengis.net/kml/2.2\">" << std::endl
|
||||
<< " <Document>" << std::endl
|
||||
|
@ -65,7 +65,7 @@ gps_l1_ca_observables_cc::gps_l1_ca_observables_cc(unsigned int nchannels, gr_ms
|
||||
d_dump = dump;
|
||||
d_nchannels = nchannels;
|
||||
d_output_rate_ms = output_rate_ms;
|
||||
d_history_prn_delay_ms = new std::deque<double>[d_nchannels];
|
||||
d_history_gnss_synchro_deque = new std::deque<Gnss_Synchro>[d_nchannels];
|
||||
d_dump_filename = dump_filename;
|
||||
d_flag_averaging = flag_averaging;
|
||||
|
||||
@ -90,13 +90,23 @@ gps_l1_ca_observables_cc::gps_l1_ca_observables_cc(unsigned int nchannels, gr_ms
|
||||
gps_l1_ca_observables_cc::~gps_l1_ca_observables_cc()
|
||||
{
|
||||
d_dump_file.close();
|
||||
delete[] d_history_prn_delay_ms;
|
||||
delete[] d_history_gnss_synchro_deque;
|
||||
}
|
||||
|
||||
|
||||
bool pairCompare_gnss_synchro( std::pair<int,Gnss_Synchro> a, std::pair<int,Gnss_Synchro> b)
|
||||
bool pairCompare_gnss_synchro_Prn_delay_ms( std::pair<int,Gnss_Synchro> a, std::pair<int,Gnss_Synchro> b)
|
||||
{
|
||||
return (a.second.Preamble_delay_ms) < (b.second.Preamble_delay_ms);
|
||||
return (a.second.Prn_timestamp_ms) < (b.second.Prn_timestamp_ms);
|
||||
}
|
||||
|
||||
bool pairCompare_gnss_synchro_preamble_symbol_count( std::pair<int,Gnss_Synchro> a, std::pair<int,Gnss_Synchro> b)
|
||||
{
|
||||
return (a.second.Preamble_symbol_counter) < (b.second.Preamble_symbol_counter);
|
||||
}
|
||||
|
||||
bool pairCompare_gnss_synchro_preamble_delay_ms( std::pair<int,Gnss_Synchro> a, std::pair<int,Gnss_Synchro> b)
|
||||
{
|
||||
return (a.second.Preamble_timestamp_ms) < (b.second.Preamble_timestamp_ms);
|
||||
}
|
||||
|
||||
|
||||
@ -121,30 +131,20 @@ int gps_l1_ca_observables_cc::general_work (int noutput_items, gr_vector_int &ni
|
||||
|
||||
Gnss_Synchro current_gnss_synchro[d_nchannels];
|
||||
|
||||
std::map<int,Gnss_Synchro> gps_words;
|
||||
std::map<int,Gnss_Synchro>::iterator gps_words_iter;
|
||||
std::map<int,double>::iterator current_prn_timestamps_ms_iter;
|
||||
std::map<int,double> current_prn_timestamps_ms;
|
||||
std::map<int,Gnss_Synchro> current_gnss_synchro_map;
|
||||
std::map<int,Gnss_Synchro> gnss_synchro_aligned_map;
|
||||
|
||||
std::map<int,Gnss_Synchro>::iterator gnss_synchro_iter;
|
||||
|
||||
|
||||
double min_preamble_delay_ms;
|
||||
double max_preamble_delay_ms;
|
||||
double pseudoranges_timestamp_ms;
|
||||
double traveltime_ms;
|
||||
double pseudorange_m;
|
||||
double delta_timestamp_ms;
|
||||
double min_delta_timestamp_ms;
|
||||
double actual_min_prn_delay_ms;
|
||||
double current_prn_delay_ms;
|
||||
|
||||
int history_shift = 0;
|
||||
int pseudoranges_reference_sat_ID = 0;
|
||||
unsigned int pseudoranges_reference_sat_channel_ID = 0;
|
||||
|
||||
d_sample_counter++; //count for the processed samples
|
||||
|
||||
bool flag_history_ok = true; //flag to indicate that all the queues have filled their timestamp history
|
||||
bool flag_history_ok = true; //flag to indicate that all the queues have filled their GNSS SYNCHRO history
|
||||
/*
|
||||
* 1. Read the GNSS SYNCHRO objects from available channels to obtain the preamble timestamp, current PRN start time and accumulated carrier phase
|
||||
* 1. Read the GNSS SYNCHRO objects from available channels
|
||||
*/
|
||||
for (unsigned int i=0; i<d_nchannels ; i++)
|
||||
{
|
||||
@ -153,18 +153,18 @@ int gps_l1_ca_observables_cc::general_work (int noutput_items, gr_vector_int &ni
|
||||
|
||||
if (current_gnss_synchro[i].Flag_valid_word) //if this channel have valid word
|
||||
{
|
||||
gps_words.insert(std::pair<int,Gnss_Synchro>(current_gnss_synchro[i].Channel_ID, current_gnss_synchro[i])); //record the word structure in a map for pseudoranges
|
||||
current_gnss_synchro_map.insert(std::pair<int,Gnss_Synchro>(current_gnss_synchro[i].Channel_ID, current_gnss_synchro[i])); //record the word structure in a map for pseudoranges
|
||||
// RECORD PRN start timestamps history
|
||||
if (d_history_prn_delay_ms[i].size()<MAX_TOA_DELAY_MS)
|
||||
if (d_history_gnss_synchro_deque[i].size()<MAX_TOA_DELAY_MS)
|
||||
{
|
||||
d_history_prn_delay_ms[i].push_front(current_gnss_synchro[i].Prn_delay_ms);
|
||||
d_history_gnss_synchro_deque[i].push_front(current_gnss_synchro[i]);
|
||||
flag_history_ok = false; // at least one channel need more samples
|
||||
}
|
||||
else
|
||||
{
|
||||
//clearQueue(d_history_prn_delay_ms[i]); //clear the queue as the preamble arrives
|
||||
d_history_prn_delay_ms[i].pop_back();
|
||||
d_history_prn_delay_ms[i].push_front(current_gnss_synchro[i].Prn_delay_ms);
|
||||
d_history_gnss_synchro_deque[i].pop_back();
|
||||
d_history_gnss_synchro_deque[i].push_front(current_gnss_synchro[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -176,80 +176,89 @@ int gps_l1_ca_observables_cc::general_work (int noutput_items, gr_vector_int &ni
|
||||
{
|
||||
current_gnss_synchro[i].Flag_valid_pseudorange = false;
|
||||
current_gnss_synchro[i].Pseudorange_m = 0.0;
|
||||
current_gnss_synchro[i].Pseudorange_timestamp_ms = 0.0;
|
||||
current_gnss_synchro[i].Pseudorange_symbol_shift = 0.0;
|
||||
}
|
||||
/*
|
||||
* 2. Compute RAW pseudorranges: Use only the valid channels (channels that are tracking a satellite)
|
||||
*/
|
||||
if(gps_words.size() > 0 and flag_history_ok == true)
|
||||
if(current_gnss_synchro_map.size() > 0 and flag_history_ok == true)
|
||||
{
|
||||
/*
|
||||
* 2.1 find the minimum preamble timestamp (nearest satellite, will be the reference)
|
||||
*/
|
||||
// The nearest satellite, first preamble to arrive
|
||||
gps_words_iter = min_element(gps_words.begin(), gps_words.end(), pairCompare_gnss_synchro);
|
||||
min_preamble_delay_ms = gps_words_iter->second.Preamble_delay_ms; //[ms]
|
||||
|
||||
pseudoranges_reference_sat_ID = gps_words_iter->second.PRN; // it is the reference!
|
||||
pseudoranges_reference_sat_channel_ID = gps_words_iter->second.Channel_ID;
|
||||
/*
|
||||
* 2.1 Find the correct symbol timestamp in the gnss_synchro history: we have to compare timestamps between channels on the SAME symbol
|
||||
* (common TX time algorithm)
|
||||
*/
|
||||
|
||||
// The farthest satellite, last preamble to arrive
|
||||
gps_words_iter = max_element(gps_words.begin(), gps_words.end(), pairCompare_gnss_synchro);
|
||||
max_preamble_delay_ms = gps_words_iter->second.Preamble_delay_ms;
|
||||
min_delta_timestamp_ms = gps_words_iter->second.Prn_delay_ms - max_preamble_delay_ms; //[ms]
|
||||
double min_preamble_delay_ms;
|
||||
double max_preamble_delay_ms;
|
||||
int current_symbol=0;
|
||||
int reference_channel;
|
||||
int history_shift;
|
||||
Gnss_Synchro tmp_gnss_synchro;
|
||||
|
||||
// check if this is a valid set of observations
|
||||
if ((max_preamble_delay_ms - min_preamble_delay_ms) < MAX_TOA_DELAY_MS)
|
||||
{
|
||||
// Now we have to determine were we are in time, compared with the last preamble! -> we select the corresponding history
|
||||
/*!
|
||||
* \todo Explain this better!
|
||||
*/
|
||||
//bool flag_preamble_navigation_now=true;
|
||||
// find again the minimum CURRENT minimum preamble time, taking into account the preamble timeshift
|
||||
for(gps_words_iter = gps_words.begin(); gps_words_iter != gps_words.end(); gps_words_iter++)
|
||||
{
|
||||
delta_timestamp_ms = (gps_words_iter->second.Prn_delay_ms - gps_words_iter->second.Preamble_delay_ms) - min_delta_timestamp_ms;
|
||||
history_shift = round(delta_timestamp_ms);
|
||||
//std::cout<<"history_shift="<<history_shift<<"\r\n";
|
||||
current_prn_timestamps_ms.insert(std::pair<int,double>(gps_words_iter->second.Channel_ID, d_history_prn_delay_ms[gps_words_iter->second.Channel_ID][history_shift]));
|
||||
// debug: preamble position test
|
||||
//if ((d_history_prn_delay_ms[gps_words_iter->second.channel_ID][history_shift]-gps_words_iter->second.preamble_delay_ms)<0.1)
|
||||
//{std::cout<<"ch "<<gps_words_iter->second.channel_ID<<" current_prn_time-last_preamble_prn_time="<<
|
||||
// d_history_prn_delay_ms[gps_words_iter->second.channel_ID][history_shift]-gps_words_iter->second.preamble_delay_ms<<"\r\n";
|
||||
//}else{
|
||||
// flag_preamble_navigation_now=false;
|
||||
//}
|
||||
}
|
||||
gnss_synchro_iter = min_element(current_gnss_synchro_map.begin(), current_gnss_synchro_map.end(), pairCompare_gnss_synchro_preamble_delay_ms);
|
||||
min_preamble_delay_ms = gnss_synchro_iter->second.Preamble_timestamp_ms; //[ms]
|
||||
|
||||
//if (flag_preamble_navigation_now==true)
|
||||
//{
|
||||
//std::cout<<"PREAMBLE NAVIGATION NOW!\r\n";
|
||||
//d_sample_counter=0;
|
||||
//}
|
||||
current_prn_timestamps_ms_iter = min_element(current_prn_timestamps_ms.begin(), current_prn_timestamps_ms.end(), pairCompare_double);
|
||||
gnss_synchro_iter = max_element(current_gnss_synchro_map.begin(), current_gnss_synchro_map.end(), pairCompare_gnss_synchro_preamble_delay_ms);
|
||||
max_preamble_delay_ms = gnss_synchro_iter->second.Preamble_timestamp_ms; //[ms]
|
||||
|
||||
actual_min_prn_delay_ms = current_prn_timestamps_ms_iter->second;
|
||||
if ((max_preamble_delay_ms-min_preamble_delay_ms)< MAX_TOA_DELAY_MS)
|
||||
{
|
||||
// we have a valid information set. Its time to align the symbols information
|
||||
// what is the most delayed symbol in the current set? -> this will be the reference symbol
|
||||
gnss_synchro_iter=min_element(current_gnss_synchro_map.begin(), current_gnss_synchro_map.end(), pairCompare_gnss_synchro_preamble_symbol_count);
|
||||
current_symbol=gnss_synchro_iter->second.Preamble_symbol_counter;
|
||||
reference_channel=gnss_synchro_iter->second.Channel_ID;
|
||||
// save it in the aligned symbols map
|
||||
gnss_synchro_aligned_map.insert(std::pair<int,Gnss_Synchro>(gnss_synchro_iter->second.Channel_ID, gnss_synchro_iter->second));
|
||||
|
||||
pseudoranges_timestamp_ms = actual_min_prn_delay_ms; //save the shortest pseudorange timestamp to compute the current GNSS timestamp
|
||||
/*
|
||||
* 2.2 compute the pseudoranges
|
||||
*/
|
||||
// Now find where the same symbols were in the rest of the channels searching in the symbol history
|
||||
for(gnss_synchro_iter = current_gnss_synchro_map.begin(); gnss_synchro_iter != current_gnss_synchro_map.end(); gnss_synchro_iter++)
|
||||
{
|
||||
//TODO: Replace the loop using current current_symbol-Preamble_symbol_counter
|
||||
if (reference_channel!=gnss_synchro_iter->second.Channel_ID)
|
||||
{
|
||||
// compute the required symbol history shift in order to match the reference symbol
|
||||
history_shift=gnss_synchro_iter->second.Preamble_symbol_counter-current_symbol;
|
||||
if (history_shift<(int)MAX_TOA_DELAY_MS)// and history_shift>=0)
|
||||
{
|
||||
tmp_gnss_synchro= d_history_gnss_synchro_deque[gnss_synchro_iter->second.Channel_ID][history_shift];
|
||||
gnss_synchro_aligned_map.insert(std::pair<int,Gnss_Synchro>(gnss_synchro_iter->second.Channel_ID,tmp_gnss_synchro));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(gps_words_iter = gps_words.begin(); gps_words_iter != gps_words.end(); gps_words_iter++)
|
||||
{
|
||||
// #### compute the pseudorange for this satellite ###
|
||||
/*
|
||||
* 3 Compute the pseudorranges using the aligned data map
|
||||
*/
|
||||
double min_symbol_timestamp_ms;
|
||||
double max_symbol_timestamp_ms;
|
||||
gnss_synchro_iter = min_element(gnss_synchro_aligned_map.begin(), gnss_synchro_aligned_map.end(), pairCompare_gnss_synchro_Prn_delay_ms);
|
||||
min_symbol_timestamp_ms = gnss_synchro_iter->second.Prn_timestamp_ms; //[ms]
|
||||
|
||||
current_prn_delay_ms = current_prn_timestamps_ms.at(gps_words_iter->second.Channel_ID);
|
||||
traveltime_ms = current_prn_delay_ms - actual_min_prn_delay_ms + GPS_STARTOFFSET_ms; //[ms]
|
||||
//std::cout<<"delta_time_ms="<<current_prn_delay_ms-actual_min_prn_delay_ms<<"\r\n";
|
||||
pseudorange_m = traveltime_ms*GPS_C_m_ms; // [m]
|
||||
// update the pseudorange object
|
||||
current_gnss_synchro[gps_words_iter->second.Channel_ID].Pseudorange_m = pseudorange_m;
|
||||
current_gnss_synchro[gps_words_iter->second.Channel_ID].Pseudorange_timestamp_ms = pseudoranges_timestamp_ms;
|
||||
current_gnss_synchro[gps_words_iter->second.Channel_ID].Flag_valid_pseudorange = true;
|
||||
}
|
||||
}
|
||||
gnss_synchro_iter = max_element(gnss_synchro_aligned_map.begin(), gnss_synchro_aligned_map.end(), pairCompare_gnss_synchro_Prn_delay_ms);
|
||||
max_symbol_timestamp_ms = gnss_synchro_iter->second.Prn_timestamp_ms; //[ms]
|
||||
|
||||
|
||||
// check again if this is a valid set of observations
|
||||
if ((max_symbol_timestamp_ms - min_symbol_timestamp_ms) < MAX_TOA_DELAY_MS)
|
||||
/*
|
||||
* 2.3 compute the pseudoranges
|
||||
*/
|
||||
{
|
||||
for(gnss_synchro_iter = gnss_synchro_aligned_map.begin(); gnss_synchro_iter != gnss_synchro_aligned_map.end(); gnss_synchro_iter++)
|
||||
{
|
||||
traveltime_ms = gnss_synchro_iter->second.Prn_timestamp_ms - min_symbol_timestamp_ms + GPS_STARTOFFSET_ms; //[ms]
|
||||
pseudorange_m = traveltime_ms*GPS_C_m_ms; // [m]
|
||||
// update the pseudorange object
|
||||
current_gnss_synchro[gnss_synchro_iter->second.Channel_ID]=gnss_synchro_iter->second;
|
||||
current_gnss_synchro[gnss_synchro_iter->second.Channel_ID].Pseudorange_m = pseudorange_m;
|
||||
current_gnss_synchro[gnss_synchro_iter->second.Channel_ID].Pseudorange_symbol_shift = (double)current_symbol; // number of symbols shifted from preamble start symbol
|
||||
current_gnss_synchro[gnss_synchro_iter->second.Channel_ID].Flag_valid_pseudorange = true;
|
||||
current_gnss_synchro[gnss_synchro_iter->second.Channel_ID].Pseudorange_timestamp_ms=max_symbol_timestamp_ms;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -261,13 +270,13 @@ int gps_l1_ca_observables_cc::general_work (int noutput_items, gr_vector_int &ni
|
||||
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].Preamble_timestamp_ms;
|
||||
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_timestamp_ms;
|
||||
tmp_double = current_gnss_synchro[i].Pseudorange_symbol_shift;
|
||||
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));
|
||||
@ -280,21 +289,19 @@ int gps_l1_ca_observables_cc::general_work (int noutput_items, gr_vector_int &ni
|
||||
}
|
||||
|
||||
consume_each(1); //one by one
|
||||
|
||||
|
||||
|
||||
if ((d_sample_counter % d_output_rate_ms) == 0)
|
||||
{
|
||||
// mod 8/4/2012: always make the observables output
|
||||
//if ((d_sample_counter % d_output_rate_ms) == 0)
|
||||
// {
|
||||
for (unsigned int i=0; i<d_nchannels ; i++)
|
||||
{
|
||||
*out[i] = current_gnss_synchro[i];
|
||||
}
|
||||
return 1; //Output the observables
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0; //hold on
|
||||
}
|
||||
// }
|
||||
//else
|
||||
// {
|
||||
// return 0; //hold on
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "gps_navigation_message.h"
|
||||
#include "rinex_printer.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "gnss_synchro.h"
|
||||
|
||||
class gps_l1_ca_observables_cc;
|
||||
|
||||
@ -83,7 +84,10 @@ private:
|
||||
std::string d_dump_filename;
|
||||
std::ofstream d_dump_file;
|
||||
|
||||
std::deque<double> *d_history_prn_delay_ms;
|
||||
//std::deque<double> *d_history_prn_delay_ms;
|
||||
|
||||
std::deque<Gnss_Synchro> *d_history_gnss_synchro_deque;
|
||||
|
||||
|
||||
concurrent_queue<Gps_Navigation_Message> *d_nav_queue; // Navigation ephemeris queue
|
||||
};
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <gnuradio/gr_io_signature.h>
|
||||
#include <glog/log_severity.h>
|
||||
#include <glog/logging.h>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include "control_message_factory.h"
|
||||
|
||||
#include "gnss_synchro.h"
|
||||
@ -92,7 +93,7 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(
|
||||
d_vector_length = vector_length;
|
||||
d_samples_per_bit = ( GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS ) / GPS_CA_TELEMETRY_RATE_BITS_SECOND;
|
||||
d_fs_in = fs_in;
|
||||
d_preamble_duration_seconds = (1.0 / GPS_CA_TELEMETRY_RATE_BITS_SECOND) * GPS_CA_PREAMBLE_LENGTH_BITS;
|
||||
//d_preamble_duration_seconds = (1.0 / GPS_CA_TELEMETRY_RATE_BITS_SECOND) * GPS_CA_PREAMBLE_LENGTH_BITS;
|
||||
//std::cout<<"d_preamble_duration_seconds="<<d_preamble_duration_seconds<<"\r\n";
|
||||
// set the preamble
|
||||
unsigned short int preambles_bits[GPS_CA_PREAMBLE_LENGTH_BITS] = GPS_PREAMBLE;
|
||||
@ -124,7 +125,7 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(
|
||||
d_symbol_accumulator=0;
|
||||
d_symbol_accumulator_counter = 0;
|
||||
d_frame_bit_index = 0;
|
||||
|
||||
d_preamble_time_seconds=0;
|
||||
d_flag_frame_sync = false;
|
||||
d_GPS_frame_4bytes = 0;
|
||||
d_prev_GPS_frame_4bytes = 0;
|
||||
@ -175,37 +176,19 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
|
||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
|
||||
{
|
||||
int corr_value = 0;
|
||||
int preamble_diff;
|
||||
int preamble_diff=0;
|
||||
|
||||
Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0];
|
||||
|
||||
|
||||
d_sample_counter++; //count for the processed samples
|
||||
|
||||
DLOG(INFO) << "Sample counter: " << d_sample_counter;
|
||||
|
||||
// ########### Output the tracking data to navigation and PVT ##########
|
||||
const Gnss_Synchro **in = (const Gnss_Synchro **) &input_items[0]; //Get the input samples pointer
|
||||
|
||||
/*!
|
||||
* \todo Check the HOW GPS time computation, taking into account that the preamble correlation last 160 symbols, which is 160 ms in GPS CA L1
|
||||
*/
|
||||
// FIFO history to get the exact timestamp of the first symbol of the preamble
|
||||
// if (d_prn_start_sample_history.size()<160)
|
||||
// {
|
||||
// // fill the queue
|
||||
// d_prn_start_sample_history.push_front(in[2][0]);
|
||||
// consume_each(1); //one by one
|
||||
// return 1;
|
||||
// }else{
|
||||
// d_prn_start_sample_history.pop_back();
|
||||
// d_prn_start_sample_history.push_front(in[2][0]);
|
||||
// }
|
||||
// TODO Optimize me!
|
||||
//******* preamble correlation ********
|
||||
for (unsigned int i=0; i<d_samples_per_bit*8; i++)
|
||||
{
|
||||
if (in[0][i].Prompt_Q < 0) // symbols clipping
|
||||
if (in[0][i].Prompt_I < 0) // symbols clipping
|
||||
{
|
||||
corr_value -= d_preambles_symbols[i];
|
||||
}
|
||||
@ -237,7 +220,7 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
|
||||
d_GPS_FSM.Event_gps_word_preamble();
|
||||
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
|
||||
d_preamble_time_seconds = in[0][0].Tracking_timestamp_secs;// - d_preamble_duration_seconds; //record the PRN start sample index associated to the preamble
|
||||
d_preamble_code_phase_seconds = in[0][0].Code_phase_secs;
|
||||
|
||||
if (!d_flag_frame_sync)
|
||||
@ -262,11 +245,9 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
|
||||
}
|
||||
}
|
||||
|
||||
//******* code error accumulator *****
|
||||
//d_preamble_phase-=in[3][0];
|
||||
//******* SYMBOL TO BIT *******
|
||||
|
||||
d_symbol_accumulator += in[0][d_samples_per_bit*8 - 1].Prompt_Q; // accumulate the input value in d_symbol_accumulator
|
||||
d_symbol_accumulator += in[0][d_samples_per_bit*8 - 1].Prompt_I; // accumulate the input value in d_symbol_accumulator
|
||||
d_symbol_accumulator_counter++;
|
||||
if (d_symbol_accumulator_counter == 20)
|
||||
{
|
||||
@ -324,7 +305,6 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
|
||||
|
||||
// output the frame
|
||||
consume_each(1); //one by one
|
||||
DLOG(INFO) << "TELEMETRY PROCESSED for satellite " << this->d_satellite;
|
||||
|
||||
Gnss_Synchro current_synchro_data; //structure to save the synchronization information and send the output object to the next block
|
||||
|
||||
@ -333,12 +313,28 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
|
||||
//2. Add the telemetry decoder information
|
||||
current_synchro_data.Flag_valid_word=(d_flag_frame_sync == true and d_flag_parity == true);
|
||||
current_synchro_data.Flag_preamble= d_flag_preamble;
|
||||
current_synchro_data.Preamble_delay_ms= d_preamble_time_seconds*1000.0;
|
||||
current_synchro_data.Prn_delay_ms = (in[0][0].Tracking_timestamp_secs - d_preamble_duration_seconds)*1000.0;
|
||||
current_synchro_data.Preamble_code_phase_ms = d_preamble_code_phase_seconds*1000.0;
|
||||
current_synchro_data.Preamble_code_phase_correction_ms = (in[0][0].Code_phase_secs - d_preamble_code_phase_seconds)*1000.0;
|
||||
//gps_synchro.satellite_PRN = this->d_satellite.get_PRN(); //is already filled...
|
||||
//gps_synchro.channel_ID = d_channel;
|
||||
current_synchro_data.Preamble_timestamp_ms= d_preamble_time_seconds*1000.0;
|
||||
current_synchro_data.Prn_timestamp_ms = in[0][0].Tracking_timestamp_secs*1000.0;
|
||||
current_synchro_data.Preamble_symbol_counter=fmod((double)(d_sample_counter - d_preamble_index),6000); //not corrected the preamble correlation lag! -> to be taken into account in TX Time
|
||||
|
||||
if(d_dump == true)
|
||||
{
|
||||
// MULTIPLEXED FILE RECORDING - Record results to file
|
||||
try
|
||||
{
|
||||
double tmp_double;
|
||||
tmp_double = current_synchro_data.Preamble_timestamp_ms;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = current_synchro_data.Prn_timestamp_ms;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = current_synchro_data.Preamble_symbol_counter;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
}
|
||||
catch (std::ifstream::failure e)
|
||||
{
|
||||
std::cout << "Exception writing observables dump file " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//3. Make the output (copy the object contents to the GNURadio reserved memory)
|
||||
*out[0] = current_synchro_data;
|
||||
@ -359,5 +355,25 @@ void gps_l1_ca_telemetry_decoder_cc::set_channel(int channel)
|
||||
d_channel = channel;
|
||||
d_GPS_FSM.i_channel_ID = channel;
|
||||
LOG_AT_LEVEL(INFO) << "Navigation channel set to " << channel;
|
||||
// ############# ENABLE DATA FILE LOG #################
|
||||
if (d_dump == true)
|
||||
{
|
||||
if (d_dump_file.is_open() == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
d_dump_filename="telemetry";
|
||||
d_dump_filename.append(boost::lexical_cast<std::string>(d_channel));
|
||||
d_dump_filename.append(".dat");
|
||||
d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
|
||||
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
|
||||
std::cout << "Telemetry decoder dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str() << std::endl;
|
||||
}
|
||||
catch (std::ifstream::failure e)
|
||||
{
|
||||
std::cout << "channel " << d_channel << " Exception opening trk dump file " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ private:
|
||||
int d_word_number;
|
||||
|
||||
long d_fs_in;
|
||||
double d_preamble_duration_seconds;
|
||||
//double d_preamble_duration_seconds;
|
||||
// navigation message vars
|
||||
Gps_Navigation_Message d_nav;
|
||||
GpsL1CaSubframeFsm d_GPS_FSM;
|
||||
|
@ -230,22 +230,23 @@ void GpsL1CaSubframeFsm::gps_subframe_to_nav_msg()
|
||||
std::cout << "NAVIGATION FSM: received subframe " << subframe_ID << " for satellite " << Gnss_Satellite(std::string("GPS"), i_satellite_PRN) << std::endl;
|
||||
d_nav.i_satellite_PRN = i_satellite_PRN;
|
||||
d_nav.i_channel_ID = i_channel_ID;
|
||||
if (subframe_ID == 1)
|
||||
{
|
||||
d_nav.d_subframe1_timestamp_ms = this->d_preamble_time_ms;
|
||||
//std::cout<<"NAVIGATION FSM: set subframe 1 preamble timestamp for satellite "<<d_nav.i_satellite_PRN<<std::endl;
|
||||
}
|
||||
d_nav.d_subframe_timestamp_ms = this->d_preamble_time_ms;
|
||||
d_nav.b_update_tow_flag=true;
|
||||
/*!
|
||||
* \todo change satellite validation to subframe 5 because it will have a complete set of ephemeris parameters
|
||||
*/
|
||||
if (subframe_ID == 3)
|
||||
{ // if the subframe is the 5th, then
|
||||
if (d_nav.satellite_validation()) // if all the satellite ephemeris parameters are good, then
|
||||
{
|
||||
// Send the procesed satellite ephemeris packet
|
||||
d_nav_queue->push(d_nav);
|
||||
}
|
||||
}
|
||||
// if (subframe_ID == 3)
|
||||
// { // if the subframe is the 5th, then
|
||||
// if (d_nav.satellite_validation()) // if all the satellite ephemeris parameters are good, then
|
||||
// {
|
||||
// // Send the procesed satellite ephemeris packet
|
||||
// d_nav_queue->push(d_nav);
|
||||
//
|
||||
// }
|
||||
// }
|
||||
d_nav.satellite_validation();
|
||||
d_nav_queue->push(d_nav);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -113,10 +113,10 @@ Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc(
|
||||
|
||||
d_acquisition_gnss_synchro=NULL;
|
||||
|
||||
d_if_freq = if_freq;
|
||||
d_fs_in = fs_in;
|
||||
d_if_freq = (double)if_freq;
|
||||
d_fs_in = (double)fs_in;
|
||||
d_vector_length = vector_length;
|
||||
d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips)
|
||||
d_early_late_spc_chips = (double)early_late_space_chips; // Define early-late offset (in chips)
|
||||
d_dump_filename = dump_filename;
|
||||
|
||||
// Initialize tracking variables ==========================================
|
||||
@ -144,10 +144,11 @@ Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc(
|
||||
|
||||
// sample synchronization
|
||||
d_sample_counter = 0;
|
||||
d_sample_counter_seconds = 0;
|
||||
d_acq_sample_stamp = 0;
|
||||
d_last_seg = 0;// this is for debug output only
|
||||
|
||||
d_code_phase_samples=0;
|
||||
|
||||
d_enable_tracking = false;
|
||||
|
||||
d_current_prn_length_samples = (int)d_vector_length;
|
||||
@ -181,31 +182,31 @@ void Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::start_tracking()
|
||||
d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples;
|
||||
|
||||
unsigned long int acq_trk_diff_samples;
|
||||
float acq_trk_diff_seconds;
|
||||
double acq_trk_diff_seconds;
|
||||
acq_trk_diff_samples = d_sample_counter - d_acq_sample_stamp;//-d_vector_length;
|
||||
acq_trk_diff_seconds = (float)acq_trk_diff_samples / (float)d_fs_in;
|
||||
acq_trk_diff_seconds = (double)acq_trk_diff_samples / d_fs_in;
|
||||
//doppler effect
|
||||
// Fd=(C/(C+Vr))*F
|
||||
float radial_velocity;
|
||||
double radial_velocity;
|
||||
radial_velocity = (GPS_L1_FREQ_HZ + d_acq_carrier_doppler_hz) / GPS_L1_FREQ_HZ;
|
||||
// new chip and prn sequence periods based on acq Doppler
|
||||
float T_chip_mod_seconds;
|
||||
float T_prn_mod_seconds;
|
||||
float T_prn_mod_samples;
|
||||
double T_chip_mod_seconds;
|
||||
double T_prn_mod_seconds;
|
||||
double T_prn_mod_samples;
|
||||
d_code_freq_hz = radial_velocity * GPS_L1_CA_CODE_RATE_HZ;
|
||||
T_chip_mod_seconds = 1 / d_code_freq_hz;
|
||||
T_prn_mod_seconds = T_chip_mod_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
|
||||
T_prn_mod_samples = T_prn_mod_seconds * (float)d_fs_in;
|
||||
d_next_prn_length_samples = round(T_prn_mod_samples);
|
||||
T_prn_mod_samples = T_prn_mod_seconds * d_fs_in;
|
||||
d_current_prn_length_samples = round(T_prn_mod_samples);
|
||||
|
||||
float T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS / GPS_L1_CA_CODE_RATE_HZ;
|
||||
float T_prn_true_samples = T_prn_true_seconds * (float)d_fs_in;
|
||||
float T_prn_diff_seconds;
|
||||
double T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS / GPS_L1_CA_CODE_RATE_HZ;
|
||||
double T_prn_true_samples = T_prn_true_seconds * d_fs_in;
|
||||
double T_prn_diff_seconds;
|
||||
T_prn_diff_seconds = T_prn_true_seconds - T_prn_mod_seconds;
|
||||
float N_prn_diff;
|
||||
double N_prn_diff;
|
||||
N_prn_diff = acq_trk_diff_seconds / T_prn_true_seconds;
|
||||
float corrected_acq_phase_samples, delay_correction_samples;
|
||||
corrected_acq_phase_samples = fmod((d_acq_code_phase_samples + T_prn_diff_seconds * N_prn_diff * (float)d_fs_in), T_prn_true_samples);
|
||||
double corrected_acq_phase_samples, delay_correction_samples;
|
||||
corrected_acq_phase_samples = fmod((d_acq_code_phase_samples + T_prn_diff_seconds * N_prn_diff * d_fs_in), T_prn_true_samples);
|
||||
|
||||
if (corrected_acq_phase_samples < 0)
|
||||
{
|
||||
@ -231,11 +232,8 @@ void Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::start_tracking()
|
||||
d_rem_carr_phase = 0;
|
||||
d_FLL_discriminator_hz = 0;
|
||||
d_rem_code_phase_samples = 0;
|
||||
d_next_rem_code_phase_samples = 0;
|
||||
d_acc_carrier_phase_rad = 0;
|
||||
|
||||
d_code_phase_samples = d_acq_code_phase_samples;
|
||||
|
||||
std::string sys_ = &d_acquisition_gnss_synchro->System;
|
||||
sys = sys_.substr(0,1);
|
||||
|
||||
@ -263,12 +261,12 @@ void Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::start_tracking()
|
||||
|
||||
void Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::update_local_code()
|
||||
{
|
||||
float tcode_chips;
|
||||
float rem_code_phase_chips;
|
||||
float code_phase_step_chips;
|
||||
double tcode_chips;
|
||||
double rem_code_phase_chips;
|
||||
double code_phase_step_chips;
|
||||
int associated_chip_index;
|
||||
int code_length_chips = (int)GPS_L1_CA_CODE_LENGTH_CHIPS;
|
||||
code_phase_step_chips = d_code_freq_hz / ((float)d_fs_in);
|
||||
code_phase_step_chips = d_code_freq_hz / d_fs_in;
|
||||
rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_hz / d_fs_in);
|
||||
// unified loop for E, P, L code vectors
|
||||
tcode_chips = -rem_code_phase_chips;
|
||||
@ -282,7 +280,6 @@ void Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::update_local_code()
|
||||
d_late_code[i] = d_ca_code[associated_chip_index];
|
||||
tcode_chips = tcode_chips + code_phase_step_chips;
|
||||
}
|
||||
//d_code_phase_samples=d_code_phase_samples+(float)d_fs_in*GPS_L1_CA_CODE_LENGTH_CHIPS*(1/d_code_freq_hz-1/GPS_L1_CA_CODE_RATE_HZ);
|
||||
}
|
||||
|
||||
|
||||
@ -291,8 +288,8 @@ void Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::update_local_code()
|
||||
|
||||
void Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::update_local_carrier()
|
||||
{
|
||||
float phase, phase_step;
|
||||
phase_step = (float)GPS_TWO_PI * d_carrier_doppler_hz / (float)d_fs_in;
|
||||
double phase, phase_step;
|
||||
phase_step = GPS_TWO_PI * d_carrier_doppler_hz / d_fs_in;
|
||||
phase = d_rem_carr_phase;
|
||||
for(int i = 0; i < d_current_prn_length_samples; i++)
|
||||
{
|
||||
@ -332,47 +329,52 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
|
||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
|
||||
{
|
||||
|
||||
float code_error_chips = 0;
|
||||
float correlation_time_s = 0;
|
||||
float PLL_discriminator_hz = 0;
|
||||
float carr_nco_hz = 0;
|
||||
double code_error_chips = 0;
|
||||
double correlation_time_s = 0;
|
||||
double PLL_discriminator_hz = 0;
|
||||
double carr_nco_hz = 0;
|
||||
// get the sample in and out pointers
|
||||
const gr_complex* in = (gr_complex*) input_items[0]; //block input samples pointer
|
||||
Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0]; //block output streams pointer
|
||||
|
||||
d_Prompt_prev = *d_Prompt; // for the FLL discriminator
|
||||
|
||||
if (d_enable_tracking == true)
|
||||
{
|
||||
// GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder
|
||||
Gnss_Synchro current_synchro_data;
|
||||
// Fill the acquisition data
|
||||
current_synchro_data=*d_acquisition_gnss_synchro;
|
||||
/*
|
||||
* Receiver signal alignment
|
||||
*/
|
||||
if (d_pull_in == true)
|
||||
{
|
||||
int samples_offset;
|
||||
float acq_trk_shif_correction_samples;
|
||||
double acq_trk_shif_correction_samples;
|
||||
int acq_to_trk_delay_samples;
|
||||
acq_to_trk_delay_samples = d_sample_counter-d_acq_sample_stamp;
|
||||
acq_trk_shif_correction_samples = d_next_prn_length_samples - fmod((float)acq_to_trk_delay_samples, (float)d_next_prn_length_samples);
|
||||
acq_trk_shif_correction_samples = d_current_prn_length_samples - fmod((double)acq_to_trk_delay_samples, (double)d_current_prn_length_samples);
|
||||
samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples);
|
||||
// /todo: Check if the sample counter sent to the next block as a time reference should be incremented AFTER sended or BEFORE
|
||||
d_sample_counter_seconds = d_sample_counter_seconds + (((double)samples_offset)/(double)d_fs_in);
|
||||
d_sample_counter = d_sample_counter + samples_offset; //count for the processed samples
|
||||
d_pull_in = false;
|
||||
consume_each(samples_offset); //shift input to perform alignment with local replica
|
||||
|
||||
// make an output to not stop the rest of the processing blocks
|
||||
current_synchro_data.Prompt_I=0.0;
|
||||
current_synchro_data.Prompt_Q=0.0;
|
||||
current_synchro_data.Tracking_timestamp_secs=(double)d_sample_counter/d_fs_in;
|
||||
current_synchro_data.Carrier_phase_rads=0.0;
|
||||
current_synchro_data.Code_phase_secs=0.0;
|
||||
current_synchro_data.CN0_dB_hz=0.0;
|
||||
current_synchro_data.Flag_valid_tracking=false;
|
||||
|
||||
*out[0] =current_synchro_data;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder
|
||||
Gnss_Synchro current_synchro_data;
|
||||
// Fill the acquisition data
|
||||
current_synchro_data=*d_acquisition_gnss_synchro;
|
||||
|
||||
// get the sample in and out pointers
|
||||
const gr_complex* in = (gr_complex*) input_items[0]; //block input samples pointer
|
||||
Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0]; //block output streams pointer
|
||||
|
||||
// Update the prn length based on code freq (variable) and
|
||||
// sampling frequency (fixed)
|
||||
// variable code PRN sample block size
|
||||
d_current_prn_length_samples = d_next_prn_length_samples;
|
||||
|
||||
update_local_code();
|
||||
update_local_carrier();
|
||||
@ -399,7 +401,7 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
|
||||
// make an output to not stop the rest of the processing blocks
|
||||
current_synchro_data.Prompt_I=0.0;
|
||||
current_synchro_data.Prompt_Q=0.0;
|
||||
current_synchro_data.Tracking_timestamp_secs=d_sample_counter_seconds;
|
||||
current_synchro_data.Tracking_timestamp_secs=(double)d_sample_counter/d_fs_in;
|
||||
current_synchro_data.Carrier_phase_rads=0.0;
|
||||
current_synchro_data.Code_phase_secs=0.0;
|
||||
current_synchro_data.CN0_dB_hz=0.0;
|
||||
@ -417,7 +419,7 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
|
||||
code_error_chips = dll_nc_e_minus_l_normalized(*d_Early,*d_Late);
|
||||
|
||||
//compute FLL error
|
||||
correlation_time_s = ((float)d_current_prn_length_samples) / (float)d_fs_in;
|
||||
correlation_time_s = ((double)d_current_prn_length_samples) / d_fs_in;
|
||||
if (d_FLL_wait == 1)
|
||||
{
|
||||
d_Prompt_prev = *d_Prompt;
|
||||
@ -425,18 +427,18 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
|
||||
}
|
||||
else
|
||||
{
|
||||
d_FLL_discriminator_hz = fll_four_quadrant_atan(d_Prompt_prev, *d_Prompt, 0, correlation_time_s) / (float)GPS_TWO_PI;
|
||||
d_FLL_discriminator_hz = fll_four_quadrant_atan(d_Prompt_prev, *d_Prompt, 0, correlation_time_s) / GPS_TWO_PI;
|
||||
d_Prompt_prev = *d_Prompt;
|
||||
d_FLL_wait = 1;
|
||||
}
|
||||
|
||||
// Compute PLL error
|
||||
PLL_discriminator_hz = pll_cloop_two_quadrant_atan(*d_Prompt) / (float)GPS_TWO_PI;
|
||||
PLL_discriminator_hz = pll_cloop_two_quadrant_atan(*d_Prompt) / GPS_TWO_PI;
|
||||
|
||||
/*
|
||||
* \todo Update FLL assistance algorithm!
|
||||
*/
|
||||
if ((((float)d_sample_counter - (float)d_acq_sample_stamp) / (float)d_fs_in) > 3)
|
||||
if ((((double)d_sample_counter - (double)d_acq_sample_stamp) / d_fs_in) > 3)
|
||||
{
|
||||
d_FLL_discriminator_hz = 0; //disconnect the FLL after the initial lock
|
||||
}
|
||||
@ -444,8 +446,8 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
|
||||
* DLL and FLL+PLL filter and get current carrier Doppler and code frequency
|
||||
*/
|
||||
carr_nco_hz = d_carrier_loop_filter.get_carrier_error(d_FLL_discriminator_hz, PLL_discriminator_hz, correlation_time_s);
|
||||
d_carrier_doppler_hz = (float)d_if_freq + carr_nco_hz;
|
||||
d_code_freq_hz = GPS_L1_CA_CODE_RATE_HZ - (((d_carrier_doppler_hz - (float)d_if_freq) * GPS_L1_CA_CODE_RATE_HZ) / GPS_L1_FREQ_HZ) - code_error_chips;
|
||||
d_carrier_doppler_hz = d_if_freq + carr_nco_hz;
|
||||
d_code_freq_hz = GPS_L1_CA_CODE_RATE_HZ - (((d_carrier_doppler_hz - d_if_freq) * GPS_L1_CA_CODE_RATE_HZ) / GPS_L1_FREQ_HZ) - code_error_chips;
|
||||
|
||||
/*!
|
||||
* \todo Improve the lock detection algorithm!
|
||||
@ -475,8 +477,6 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
|
||||
if (d_carrier_lock_fail_counter > MAXIMUM_LOCK_FAIL_COUNTER)
|
||||
{
|
||||
std::cout << "Channel " << d_channel << " loss of lock!" << std::endl;
|
||||
// tracking_message = 3; //loss of lock
|
||||
// d_channel_internal_queue->push(tracking_message);
|
||||
ControlMessageFactory* cmf = new ControlMessageFactory();
|
||||
if (d_queue != gr_msg_queue_sptr()) {
|
||||
d_queue->handle(cmf->GetQueueMessage(d_channel, 2));
|
||||
@ -487,16 +487,6 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
|
||||
}
|
||||
}
|
||||
|
||||
// ########### Output the tracking data to navigation and PVT ##########
|
||||
current_synchro_data.Prompt_I=(double)(*d_Prompt).real();
|
||||
current_synchro_data.Prompt_Q=(double)(*d_Prompt).imag();
|
||||
current_synchro_data.Tracking_timestamp_secs=d_sample_counter_seconds;
|
||||
current_synchro_data.Carrier_phase_rads=(double)d_acc_carrier_phase_rad;
|
||||
current_synchro_data.Code_phase_secs=(double)d_code_phase_samples * (1/(float)d_fs_in);
|
||||
current_synchro_data.CN0_dB_hz=(double)d_CN0_SNV_dB_Hz;
|
||||
|
||||
|
||||
*out[0] =current_synchro_data;
|
||||
// ########## DEBUG OUTPUT
|
||||
/*!
|
||||
* \todo The stop timer has to be moved to the signal source!
|
||||
@ -508,11 +498,7 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
|
||||
{
|
||||
d_last_seg = floor(d_sample_counter/d_fs_in);
|
||||
std::cout << "Current input signal time = " << d_last_seg << " [s]" << std::endl;
|
||||
//std::string sys = &d_acquisition_gnss_synchro->System;
|
||||
//std::cout << sys << ", " << sys.substr(0,1) << std::endl;
|
||||
std::cout << "Tracking CH " << d_channel << ": Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << ", CN0 = " << d_CN0_SNV_dB_Hz << " [dB-Hz]" << std::endl;
|
||||
//std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl;
|
||||
//if (d_last_seg==5) d_carrier_lock_fail_counter=500; //DEBUG: force unlock!
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -520,35 +506,33 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
|
||||
if (floor(d_sample_counter/d_fs_in) != d_last_seg)
|
||||
{
|
||||
d_last_seg = floor(d_sample_counter/d_fs_in);
|
||||
//std::string sys2 = &d_acquisition_gnss_synchro->System;
|
||||
//std::cout << sys2 << ", " << sys2.substr(0,1) << std::endl;
|
||||
std::cout << "Tracking CH " << d_channel << ": Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << ", CN0 = " << d_CN0_SNV_dB_Hz << " [dB-Hz]" << std::endl;
|
||||
//std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//predict the next loop PRN period length prediction
|
||||
float T_chip_seconds;
|
||||
float T_prn_seconds;
|
||||
float T_prn_samples;
|
||||
float K_blk_samples;
|
||||
double T_chip_seconds;
|
||||
double T_prn_seconds;
|
||||
double T_prn_samples;
|
||||
double K_blk_samples;
|
||||
T_chip_seconds = 1/d_code_freq_hz;
|
||||
T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
|
||||
T_prn_samples = T_prn_seconds * (float)d_fs_in;
|
||||
d_rem_code_phase_samples = d_next_rem_code_phase_samples;
|
||||
T_prn_samples = T_prn_seconds * d_fs_in;
|
||||
K_blk_samples = T_prn_samples + d_rem_code_phase_samples;
|
||||
d_current_prn_length_samples = round(K_blk_samples); //round to a discrete sample
|
||||
d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error
|
||||
|
||||
// Update the current PRN delay (code phase in samples)
|
||||
float T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS / GPS_L1_CA_CODE_RATE_HZ;
|
||||
float T_prn_true_samples = T_prn_true_seconds * (float)d_fs_in;
|
||||
d_code_phase_samples = d_code_phase_samples + T_prn_samples - T_prn_true_samples;
|
||||
if (d_code_phase_samples < 0)
|
||||
{
|
||||
d_code_phase_samples = T_prn_true_samples + d_code_phase_samples;
|
||||
}
|
||||
d_code_phase_samples = fmod(d_code_phase_samples, T_prn_true_samples);
|
||||
d_next_prn_length_samples = round(K_blk_samples); //round to a discrete sample
|
||||
d_next_rem_code_phase_samples = K_blk_samples - d_next_prn_length_samples; //rounding error
|
||||
// ########### Output the tracking data to navigation and PVT ##########
|
||||
current_synchro_data.Prompt_I=(double)(*d_Prompt).imag();
|
||||
current_synchro_data.Prompt_Q=(double)(*d_Prompt).real();
|
||||
// Tracking_timestamp_secs is aligned with the PRN start sample
|
||||
current_synchro_data.Tracking_timestamp_secs=((double)d_sample_counter+(double)d_current_prn_length_samples+d_rem_code_phase_samples)/d_fs_in;
|
||||
// This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, Code_phase_secs=0
|
||||
current_synchro_data.Code_phase_secs=0;
|
||||
current_synchro_data.Carrier_phase_rads=d_acc_carrier_phase_rad;
|
||||
current_synchro_data.CN0_dB_hz=d_CN0_SNV_dB_Hz;
|
||||
current_synchro_data.Flag_valid_tracking=true;
|
||||
*out[0] =current_synchro_data;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -567,6 +551,7 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
|
||||
float prompt_Q;
|
||||
float tmp_E, tmp_P, tmp_L;
|
||||
float tmp_float;
|
||||
double tmp_double;
|
||||
prompt_I = (*d_Prompt).imag();
|
||||
prompt_Q = (*d_Prompt).real();
|
||||
tmp_E=std::abs<float>(*d_Early);
|
||||
@ -585,28 +570,38 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
|
||||
//tmp_float=(float)d_sample_counter;
|
||||
d_dump_file.write((char*)&d_sample_counter, sizeof(unsigned long int));
|
||||
// accumulated carrier phase
|
||||
d_dump_file.write((char*)&d_acc_carrier_phase_rad, sizeof(float));
|
||||
tmp_float=(float)d_acc_carrier_phase_rad;
|
||||
d_dump_file.write((char*)&tmp_float, sizeof(float));
|
||||
|
||||
// carrier and code frequency
|
||||
d_dump_file.write((char*)&d_carrier_doppler_hz, sizeof(float));
|
||||
d_dump_file.write((char*)&d_code_freq_hz, sizeof(float));
|
||||
tmp_float=(float)d_carrier_doppler_hz;
|
||||
d_dump_file.write((char*)&tmp_float, sizeof(float));
|
||||
tmp_float=(float)d_code_freq_hz;
|
||||
d_dump_file.write((char*)&tmp_float, sizeof(float));
|
||||
|
||||
//PLL commands
|
||||
d_dump_file.write((char*)&PLL_discriminator_hz, sizeof(float));
|
||||
d_dump_file.write((char*)&carr_nco_hz, sizeof(float));
|
||||
tmp_float=(float)PLL_discriminator_hz;
|
||||
d_dump_file.write((char*)&tmp_float, sizeof(float));
|
||||
tmp_float=(float)carr_nco_hz;
|
||||
d_dump_file.write((char*)&tmp_float, sizeof(float));
|
||||
|
||||
//DLL commands
|
||||
d_dump_file.write((char*)&code_error_chips, sizeof(float));
|
||||
d_dump_file.write((char*)&d_code_phase_samples, sizeof(float));
|
||||
tmp_float=(float)code_error_chips;
|
||||
d_dump_file.write((char*)&tmp_float, sizeof(float));
|
||||
tmp_float=(float)d_code_phase_samples;
|
||||
d_dump_file.write((char*)&tmp_float, sizeof(float));
|
||||
|
||||
// CN0 and carrier lock test
|
||||
d_dump_file.write((char*)&d_CN0_SNV_dB_Hz, sizeof(float));
|
||||
d_dump_file.write((char*)&d_carrier_lock_test, sizeof(float));
|
||||
tmp_float=(float)d_CN0_SNV_dB_Hz;
|
||||
d_dump_file.write((char*)&tmp_float, sizeof(float));
|
||||
tmp_float=(float)d_carrier_lock_test;
|
||||
d_dump_file.write((char*)&tmp_float, sizeof(float));
|
||||
|
||||
// AUX vars (for debug purposes)
|
||||
tmp_float = 0;
|
||||
tmp_float = (float)d_rem_code_phase_samples;
|
||||
d_dump_file.write((char*)&tmp_float, sizeof(float));
|
||||
d_dump_file.write((char*)&d_sample_counter_seconds, sizeof(double));
|
||||
tmp_double=(double)(d_sample_counter+d_current_prn_length_samples);
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
}
|
||||
catch (std::ifstream::failure e)
|
||||
{
|
||||
@ -614,7 +609,6 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
|
||||
}
|
||||
}
|
||||
consume_each(d_current_prn_length_samples); // this is necesary in gr_block derivates
|
||||
d_sample_counter_seconds = d_sample_counter_seconds + (((double)d_current_prn_length_samples) / (double)d_fs_in);
|
||||
d_sample_counter += d_current_prn_length_samples; //count for the processed samples
|
||||
return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false
|
||||
}
|
||||
|
@ -142,8 +142,8 @@ private:
|
||||
bool d_dump;
|
||||
unsigned int d_channel;
|
||||
int d_last_seg;
|
||||
long d_if_freq;
|
||||
long d_fs_in;
|
||||
double d_if_freq;
|
||||
double d_fs_in;
|
||||
|
||||
gr_complex* d_ca_code;
|
||||
|
||||
@ -159,44 +159,43 @@ private:
|
||||
|
||||
gr_complex d_Prompt_prev;
|
||||
|
||||
float d_early_late_spc_chips;
|
||||
double d_early_late_spc_chips;
|
||||
|
||||
|
||||
float d_carrier_doppler_hz;
|
||||
float d_code_freq_hz;
|
||||
float d_code_phase_samples;
|
||||
double d_carrier_doppler_hz;
|
||||
double d_code_freq_hz;
|
||||
double d_code_phase_samples;
|
||||
int d_current_prn_length_samples;
|
||||
int d_next_prn_length_samples;
|
||||
//int d_next_prn_length_samples;
|
||||
int d_FLL_wait;
|
||||
float d_rem_carr_phase;
|
||||
float d_rem_code_phase_samples;
|
||||
float d_next_rem_code_phase_samples;
|
||||
double d_rem_carr_phase;
|
||||
double d_rem_code_phase_samples;
|
||||
//double d_next_rem_code_phase_samples;
|
||||
bool d_pull_in;
|
||||
|
||||
// acquisition
|
||||
float d_acq_code_phase_samples;
|
||||
float d_acq_carrier_doppler_hz;
|
||||
double d_acq_code_phase_samples;
|
||||
double d_acq_carrier_doppler_hz;
|
||||
|
||||
// correlator
|
||||
Correlator d_correlator;
|
||||
|
||||
// FLL + PLL filter
|
||||
float d_FLL_discriminator_hz; // This is a class variable because FLL needs to have memory
|
||||
double d_FLL_discriminator_hz; // This is a class variable because FLL needs to have memory
|
||||
Tracking_FLL_PLL_filter d_carrier_loop_filter;
|
||||
float d_acc_carrier_phase_rad;
|
||||
double d_acc_carrier_phase_rad;
|
||||
|
||||
unsigned long int d_sample_counter;
|
||||
double d_sample_counter_seconds;
|
||||
|
||||
unsigned long int d_acq_sample_stamp;
|
||||
|
||||
// CN0 estimation and lock detector
|
||||
int d_cn0_estimation_counter;
|
||||
gr_complex* d_Prompt_buffer;
|
||||
float d_carrier_lock_test;
|
||||
float d_CN0_SNV_dB_Hz;
|
||||
double d_carrier_lock_test;
|
||||
double d_CN0_SNV_dB_Hz;
|
||||
|
||||
float d_carrier_lock_threshold;
|
||||
double d_carrier_lock_threshold;
|
||||
|
||||
int d_carrier_lock_fail_counter;
|
||||
|
||||
|
@ -154,7 +154,7 @@ Gps_L1_Ca_Dll_Pll_Tracking_cc::Gps_L1_Ca_Dll_Pll_Tracking_cc(
|
||||
|
||||
// sample synchronization
|
||||
d_sample_counter = 0;
|
||||
d_sample_counter_seconds = 0;
|
||||
//d_sample_counter_seconds = 0;
|
||||
d_acq_sample_stamp = 0;
|
||||
|
||||
d_enable_tracking = false;
|
||||
@ -322,10 +322,6 @@ Gps_L1_Ca_Dll_Pll_Tracking_cc::~Gps_L1_Ca_Dll_Pll_Tracking_cc()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Tracking signal processing
|
||||
* Notice that this is a class derived from gr_sync_decimator, so each of the ninput_items has vector_length samples
|
||||
*/
|
||||
@ -357,7 +353,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in
|
||||
//std::cout<<"acq_trk_shif_correction="<<acq_trk_shif_correction_samples<<"\r\n";
|
||||
samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples);
|
||||
// /todo: Check if the sample counter sent to the next block as a time reference should be incremented AFTER sended or BEFORE
|
||||
d_sample_counter_seconds = d_sample_counter_seconds + (((double)samples_offset) / (double)d_fs_in);
|
||||
//d_sample_counter_seconds = d_sample_counter_seconds + (((double)samples_offset) / (double)d_fs_in);
|
||||
d_sample_counter = d_sample_counter + samples_offset; //count for the processed samples
|
||||
d_pull_in = false;
|
||||
//std::cout<<" samples_offset="<<samples_offset<<"\r\n";
|
||||
@ -403,7 +399,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in
|
||||
// make an output to not stop the rest of the processing blocks
|
||||
current_synchro_data.Prompt_I=0.0;
|
||||
current_synchro_data.Prompt_Q=0.0;
|
||||
current_synchro_data.Tracking_timestamp_secs=d_sample_counter_seconds;
|
||||
current_synchro_data.Tracking_timestamp_secs=(double)d_sample_counter/(double)d_fs_in;
|
||||
current_synchro_data.Carrier_phase_rads=0.0;
|
||||
current_synchro_data.Code_phase_secs=0.0;
|
||||
current_synchro_data.CN0_dB_hz=0.0;
|
||||
@ -441,17 +437,6 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in
|
||||
T_prn_samples = T_prn_seconds * d_fs_in;
|
||||
d_rem_code_phase_samples = d_next_rem_code_phase_samples;
|
||||
K_blk_samples = T_prn_samples + d_rem_code_phase_samples;
|
||||
|
||||
// Update the current PRN delay (code phase in samples)
|
||||
float T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS / GPS_L1_CA_CODE_RATE_HZ;
|
||||
float T_prn_true_samples = T_prn_true_seconds * (float)d_fs_in;
|
||||
d_code_phase_samples = d_code_phase_samples + T_prn_samples - T_prn_true_samples;
|
||||
if (d_code_phase_samples < 0)
|
||||
{
|
||||
d_code_phase_samples = T_prn_true_samples + d_code_phase_samples;
|
||||
}
|
||||
|
||||
d_code_phase_samples = fmod(d_code_phase_samples, T_prn_true_samples);
|
||||
d_next_prn_length_samples = round(K_blk_samples); //round to a discrete samples
|
||||
d_next_rem_code_phase_samples = K_blk_samples - d_next_prn_length_samples; //rounding error
|
||||
|
||||
@ -499,11 +484,13 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in
|
||||
|
||||
// ########### Output the tracking data to navigation and PVT ##########
|
||||
|
||||
current_synchro_data.Prompt_I = (double)(*d_Prompt).real();
|
||||
current_synchro_data.Prompt_Q = (double)(*d_Prompt).imag();
|
||||
current_synchro_data.Tracking_timestamp_secs = d_sample_counter_seconds;
|
||||
current_synchro_data.Prompt_I = (double)(*d_Prompt).imag();
|
||||
current_synchro_data.Prompt_Q = (double)(*d_Prompt).real();
|
||||
// Tracking_timestamp_secs is aligned with the PRN start sample
|
||||
current_synchro_data.Tracking_timestamp_secs=((double)d_sample_counter+(double)d_next_prn_length_samples+(double)d_next_rem_code_phase_samples)/(double)d_fs_in;
|
||||
// This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, thus, Code_phase_secs=0
|
||||
current_synchro_data.Code_phase_secs=0;
|
||||
current_synchro_data.Carrier_phase_rads = (double)d_acc_carrier_phase_rad;
|
||||
current_synchro_data.Code_phase_secs = (double)d_code_phase_samples * (1/(float)d_fs_in);
|
||||
current_synchro_data.CN0_dB_hz = (double)d_CN0_SNV_dB_Hz;
|
||||
*out[0] = current_synchro_data;
|
||||
|
||||
@ -554,6 +541,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in
|
||||
float prompt_Q;
|
||||
float tmp_E, tmp_P, tmp_L;
|
||||
float tmp_float;
|
||||
double tmp_double;
|
||||
prompt_I = (*d_Prompt).imag();
|
||||
prompt_Q = (*d_Prompt).real();
|
||||
tmp_E = std::abs<float>(*d_Early);
|
||||
@ -591,9 +579,10 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in
|
||||
d_dump_file.write((char*)&d_carrier_lock_test, sizeof(float));
|
||||
|
||||
// AUX vars (for debug purposes)
|
||||
tmp_float=0;
|
||||
tmp_float = d_rem_code_phase_samples;
|
||||
d_dump_file.write((char*)&tmp_float, sizeof(float));
|
||||
d_dump_file.write((char*)&d_sample_counter_seconds, sizeof(double));
|
||||
tmp_double=(double)(d_sample_counter+d_current_prn_length_samples);
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
}
|
||||
catch (std::ifstream::failure e)
|
||||
{
|
||||
@ -602,7 +591,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in
|
||||
}
|
||||
|
||||
consume_each(d_current_prn_length_samples); // this is necesary in gr_block derivates
|
||||
d_sample_counter_seconds = d_sample_counter_seconds + ( ((double)d_current_prn_length_samples) / (double)d_fs_in );
|
||||
//d_sample_counter_seconds = d_sample_counter_seconds + ( ((double)d_current_prn_length_samples) / (double)d_fs_in );
|
||||
d_sample_counter += d_current_prn_length_samples; //count for the processed samples
|
||||
return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ private:
|
||||
//PRN period in samples
|
||||
int d_current_prn_length_samples;
|
||||
int d_next_prn_length_samples;
|
||||
double d_sample_counter_seconds;
|
||||
//double d_sample_counter_seconds;
|
||||
|
||||
//processing samples counters
|
||||
unsigned long int d_sample_counter;
|
||||
|
@ -483,17 +483,6 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_vec
|
||||
T_prn_samples = T_prn_seconds * d_fs_in;
|
||||
d_rem_code_phase_samples = d_next_rem_code_phase_samples;
|
||||
K_blk_samples = T_prn_samples + d_rem_code_phase_samples;
|
||||
|
||||
// Update the current PRN delay (code phase in samples)
|
||||
float T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS / GPS_L1_CA_CODE_RATE_HZ;
|
||||
float T_prn_true_samples = T_prn_true_seconds * (float)d_fs_in;
|
||||
d_code_phase_samples = d_code_phase_samples + T_prn_samples - T_prn_true_samples;
|
||||
if (d_code_phase_samples < 0)
|
||||
{
|
||||
d_code_phase_samples = T_prn_true_samples + d_code_phase_samples;
|
||||
}
|
||||
|
||||
d_code_phase_samples = fmod(d_code_phase_samples, T_prn_true_samples);
|
||||
d_next_prn_length_samples = round(K_blk_samples); //round to a discrete samples
|
||||
d_next_rem_code_phase_samples = K_blk_samples - d_next_prn_length_samples; //rounding error
|
||||
|
||||
@ -539,16 +528,6 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_vec
|
||||
//std::cout<<"d_carrier_lock_fail_counter"<<d_carrier_lock_fail_counter<<"\r\n";
|
||||
}
|
||||
|
||||
// ########### Output the tracking data to navigation and PVT ##########
|
||||
|
||||
current_synchro_data.Prompt_I = (double)(*d_Prompt).real();
|
||||
current_synchro_data.Prompt_Q = (double)(*d_Prompt).imag();
|
||||
current_synchro_data.Tracking_timestamp_secs = d_sample_counter_seconds;
|
||||
current_synchro_data.Carrier_phase_rads = (double)d_acc_carrier_phase_rad;
|
||||
current_synchro_data.Code_phase_secs = (double)d_code_phase_samples * (1/(float)d_fs_in);
|
||||
current_synchro_data.CN0_dB_hz = (double)d_CN0_SNV_dB_Hz;
|
||||
*out[0] = current_synchro_data;
|
||||
|
||||
// ########## DEBUG OUTPUT
|
||||
/*!
|
||||
* \todo The stop timer has to be moved to the signal source!
|
||||
@ -576,6 +555,19 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_vec
|
||||
//std::cout<<"TRK CH "<<d_channel<<" Carrier_lock_test="<<d_carrier_lock_test<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// ########### Output the tracking data to navigation and PVT ##########
|
||||
|
||||
current_synchro_data.Prompt_I = (double)(*d_Prompt).real();
|
||||
current_synchro_data.Prompt_Q = (double)(*d_Prompt).imag();
|
||||
// Tracking_timestamp_secs is aligned with the PRN start sample
|
||||
current_synchro_data.Tracking_timestamp_secs=((double)d_sample_counter+(double)d_next_prn_length_samples+(double)d_next_rem_code_phase_samples)/(double)d_fs_in;
|
||||
// This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, Code_phase_secs=0
|
||||
current_synchro_data.Code_phase_secs=0;
|
||||
current_synchro_data.Tracking_timestamp_secs = d_sample_counter_seconds;
|
||||
current_synchro_data.Carrier_phase_rads = (double)d_acc_carrier_phase_rad;
|
||||
current_synchro_data.CN0_dB_hz = (double)d_CN0_SNV_dB_Hz;
|
||||
*out[0] = current_synchro_data;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -600,6 +592,7 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_vec
|
||||
float prompt_Q;
|
||||
float tmp_E, tmp_P, tmp_L;
|
||||
float tmp_float;
|
||||
double tmp_double;
|
||||
prompt_I = (*d_Prompt).imag();
|
||||
prompt_Q = (*d_Prompt).real();
|
||||
tmp_E = std::abs<float>(*d_Early);
|
||||
@ -637,9 +630,10 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_vec
|
||||
d_dump_file.write((char*)&d_carrier_lock_test, sizeof(float));
|
||||
|
||||
// AUX vars (for debug purposes)
|
||||
tmp_float=0;
|
||||
tmp_float = d_rem_code_phase_samples;
|
||||
d_dump_file.write((char*)&tmp_float, sizeof(float));
|
||||
d_dump_file.write((char*)&d_sample_counter_seconds, sizeof(double));
|
||||
tmp_double=(double)(d_sample_counter+d_current_prn_length_samples);
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
}
|
||||
catch (std::ifstream::failure e)
|
||||
{
|
||||
@ -648,7 +642,7 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_vec
|
||||
}
|
||||
|
||||
consume_each(d_current_prn_length_samples); // this is necesary in gr_block derivates
|
||||
d_sample_counter_seconds = d_sample_counter_seconds + ( ((double)d_current_prn_length_samples) / (double)d_fs_in );
|
||||
//d_sample_counter_seconds = d_sample_counter_seconds + ( ((double)d_current_prn_length_samples) / (double)d_fs_in );
|
||||
d_sample_counter += d_current_prn_length_samples; //count for the processed samples
|
||||
return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false
|
||||
}
|
||||
|
@ -62,8 +62,8 @@ const double MAX_TOA_DELAY_MS = 20;
|
||||
|
||||
|
||||
|
||||
#define NAVIGATION_SOLUTION_RATE_MS 1000 // this cannot go here
|
||||
const float GPS_STARTOFFSET_ms = 68.802; //[ms] Initial sign. travel time (this cannot go here)
|
||||
//#define NAVIGATION_SOLUTION_RATE_MS 1000 // this cannot go here
|
||||
const double GPS_STARTOFFSET_ms = 68.802; //[ms] Initial sign. travel time (this cannot go here)
|
||||
|
||||
|
||||
// NAVIGATION MESSAGE DEMODULATION AND DECODING
|
||||
@ -71,9 +71,11 @@ const float GPS_STARTOFFSET_ms = 68.802; //[ms] Initial sign. travel time (this
|
||||
#define GPS_PREAMBLE {1, 0, 0, 0, 1, 0, 1, 1}
|
||||
const int GPS_CA_PREAMBLE_LENGTH_BITS = 8;
|
||||
const int GPS_CA_TELEMETRY_RATE_BITS_SECOND = 50; //!< NAV message bit rate [bits/s]
|
||||
#define GPS_WORD_LENGTH 4 // CRC + GPS WORD (-2 -1 0 ... 29) Bits = 4 bytes
|
||||
#define GPS_SUBFRAME_LENGTH 40 // GPS_WORD_LENGTH x 10 = 40 bytes
|
||||
const int GPS_CA_TELEMETRY_RATE_SYMBOLS_SECOND = GPS_CA_TELEMETRY_RATE_BITS_SECOND*20; //!< NAV message bit rate [symbols/s]
|
||||
const int GPS_WORD_LENGTH = 4; // CRC + GPS WORD (-2 -1 0 ... 29) Bits = 4 bytes
|
||||
const int GPS_SUBFRAME_LENGTH=40; // GPS_WORD_LENGTH x 10 = 40 bytes
|
||||
const int GPS_SUBFRAME_BITS=300; //!< Number of bits per subframe in the NAV message [bits]
|
||||
const int GPS_SUBFRAME_SECONDS=6; //!< Subframe duration [seconds]
|
||||
const int GPS_WORD_BITS=30; //!< Number of bits per word in the NAV message [bits]
|
||||
|
||||
|
||||
@ -101,41 +103,41 @@ typedef struct bits_slice
|
||||
PI_TWO_PX ==> Pi*2^X
|
||||
ONE_PI_TWO_PX = (1/Pi)*2^X
|
||||
*/
|
||||
#define TWO_P4 (16) //!< 2^4
|
||||
#define TWO_P11 (2048) //!< 2^11
|
||||
#define TWO_P12 (4096) //!< 2^12
|
||||
#define TWO_P14 (16384) //!< 2^14
|
||||
#define TWO_P16 (65536) //!< 2^16
|
||||
#define TWO_P19 (524288) //!< 2^19
|
||||
#define TWO_P31 (2147483648.0) //!< 2^31
|
||||
#define TWO_P32 (4294967296.0) //!< 2^32 this is too big for an int so add the x.0
|
||||
#define TWO_P57 (1.441151880758559e+017) //!< 2^57
|
||||
const double TWO_P4 =(16); //!< 2^4
|
||||
const double TWO_P11 =(2048); //!< 2^11
|
||||
const double TWO_P12 =(4096); //!< 2^12
|
||||
const double TWO_P14 =(16384); //!< 2^14
|
||||
const double TWO_P16 =(65536); //!< 2^16
|
||||
const double TWO_P19 =(524288); //!< 2^19
|
||||
const double TWO_P31 =(2147483648.0); //!< 2^31
|
||||
const double TWO_P32 =(4294967296.0); //!< 2^32 this is too big for an int so add the x.0
|
||||
const double TWO_P56 =(7.205759403792794e+016); //!< 2^56
|
||||
const double TWO_P57 =(1.441151880758559e+017); //!< 2^57
|
||||
|
||||
#define TWO_N5 (0.03125) //!< 2^-5
|
||||
#define TWO_N11 (4.882812500000000e-004) //!< 2^-11
|
||||
#define TWO_N19 (1.907348632812500e-006) //!< 2^-19
|
||||
#define TWO_N20 (9.536743164062500e-007) //!< 2^-20
|
||||
#define TWO_N21 (4.768371582031250e-007) //!< 2^-21
|
||||
#define TWO_N24 (5.960464477539063e-008) //!< 2^-24
|
||||
#define TWO_N25 (2.980232238769531e-008) //!< 2^-25
|
||||
#define TWO_N27 (7.450580596923828e-009) //!< 2^-27
|
||||
#define TWO_N29 (1.862645149230957e-009) //!< 2^-29
|
||||
#define TWO_N30 (9.313225746154785e-010) //!< 2^-30
|
||||
#define TWO_N31 (4.656612873077393e-010) //!< 2^-31
|
||||
#define TWO_N32 (2.328306436538696e-010) //!< 2^-32
|
||||
#define TWO_N33 (1.164153218269348e-010) //!< 2^-33
|
||||
#define TWO_N38 (3.637978807091713e-012) //!< 2^-38
|
||||
#define TWO_N43 (1.136868377216160e-013) //!< 2^-43
|
||||
#define TWO_N50 (8.881784197001252e-016) //!< 2^-50
|
||||
#define TWO_N55 (2.775557561562891e-017) //!< 2^-55
|
||||
#define TWO_P56 (7.205759403792794e+016) //!< 2^56
|
||||
#define TWO_P57 (1.441151880758559e+017) //!< 2^57
|
||||
const double TWO_N5 =(0.03125); //!< 2^-5
|
||||
const double TWO_N11 =(4.882812500000000e-004); //!< 2^-11
|
||||
const double TWO_N19 =(1.907348632812500e-006); //!< 2^-19
|
||||
const double TWO_N20 =(9.536743164062500e-007); //!< 2^-20
|
||||
const double TWO_N21 =(4.768371582031250e-007); //!< 2^-21
|
||||
const double TWO_N24 =(5.960464477539063e-008); //!< 2^-24
|
||||
const double TWO_N25 =(2.980232238769531e-008); //!< 2^-25
|
||||
const double TWO_N27 =(7.450580596923828e-009); //!< 2^-27
|
||||
const double TWO_N29 =(1.862645149230957e-009); //!< 2^-29
|
||||
const double TWO_N30 =(9.313225746154785e-010); //!< 2^-30
|
||||
const double TWO_N31 =(4.656612873077393e-010); //!< 2^-31
|
||||
const double TWO_N32 =(2.328306436538696e-010); //!< 2^-32
|
||||
const double TWO_N33 =(1.164153218269348e-010); //!< 2^-33
|
||||
const double TWO_N38 =(3.637978807091713e-012); //!< 2^-38
|
||||
const double TWO_N43 =(1.136868377216160e-013); //!< 2^-43
|
||||
const double TWO_N50 =(8.881784197001252e-016); //!< 2^-50
|
||||
const double TWO_N55 =(2.775557561562891e-017); //!< 2^-55
|
||||
|
||||
#define PI_TWO_N19 (5.992112452678286e-006) //!< Pi*2^-19
|
||||
#define PI_TWO_N43 (3.571577341960839e-013) //!< Pi*2^-43
|
||||
#define PI_TWO_N31 (1.462918079267160e-009) //!< Pi*2^-31
|
||||
#define PI_TWO_N38 (1.142904749427469e-011) //!< Pi*2^-38
|
||||
#define PI_TWO_N23 (3.745070282923929e-007) //!< Pi*2^-23
|
||||
|
||||
const double PI_TWO_N19 =(5.992112452678286e-006); //!< Pi*2^-19
|
||||
const double PI_TWO_N43 =(3.571577341960839e-013); //!< Pi*2^-43
|
||||
const double PI_TWO_N31 =(1.462918079267160e-009); //!< Pi*2^-31
|
||||
const double PI_TWO_N38 =(1.142904749427469e-011); //!< Pi*2^-38
|
||||
const double PI_TWO_N23 =(3.745070282923929e-007); //!< Pi*2^-23
|
||||
|
||||
|
||||
|
||||
|
@ -48,16 +48,14 @@ Gnss_Synchro::Gnss_Synchro()
|
||||
CN0_dB_hz = 0.0;
|
||||
Flag_valid_tracking = false;
|
||||
//Telemetry Decoder
|
||||
Preamble_delay_ms = 0.0;
|
||||
Prn_delay_ms = 0.0;
|
||||
Preamble_code_phase_ms = 0.0;
|
||||
Preamble_code_phase_correction_ms = 0.0;
|
||||
Preamble_timestamp_ms = 0.0;
|
||||
Prn_timestamp_ms = 0.0;
|
||||
Channel_ID = 0;
|
||||
Flag_valid_word = false;
|
||||
Flag_preamble = false;
|
||||
// Pseudorange
|
||||
Pseudorange_m = 0.0;
|
||||
Pseudorange_timestamp_ms = 0.0;
|
||||
Pseudorange_symbol_shift = 0.0;
|
||||
Flag_valid_pseudorange = false;
|
||||
}
|
||||
|
||||
|
@ -61,14 +61,14 @@ public:
|
||||
double CN0_dB_hz; //!< Set by Tracking processing block
|
||||
bool Flag_valid_tracking;
|
||||
//Telemetry Decoder
|
||||
double Preamble_delay_ms;
|
||||
double Prn_delay_ms;
|
||||
double Preamble_code_phase_ms;
|
||||
double Preamble_code_phase_correction_ms;
|
||||
double Preamble_timestamp_ms;
|
||||
double Prn_timestamp_ms;
|
||||
int Preamble_symbol_counter; //n_pre
|
||||
bool Flag_valid_word;
|
||||
bool Flag_preamble;
|
||||
// Pseudorange
|
||||
double Pseudorange_m;
|
||||
double Pseudorange_symbol_shift;
|
||||
double Pseudorange_timestamp_ms;
|
||||
bool Flag_valid_pseudorange;
|
||||
};
|
||||
|
@ -39,7 +39,16 @@
|
||||
|
||||
void Gps_Navigation_Message::reset()
|
||||
{
|
||||
d_TOW = 0;
|
||||
|
||||
b_update_tow_flag=false;
|
||||
b_valid_ephemeris_set_flag=false;
|
||||
d_TOW=0;
|
||||
d_TOW_SF1 = 0;
|
||||
d_TOW_SF2 = 0;
|
||||
d_TOW_SF3 = 0;
|
||||
d_TOW_SF4 = 0;
|
||||
d_TOW_SF5 = 0;
|
||||
|
||||
d_IODE_SF2 = 0;
|
||||
d_IODE_SF3 = 0;
|
||||
d_Crs = 0;
|
||||
@ -91,7 +100,7 @@ void Gps_Navigation_Message::reset()
|
||||
i_satellite_PRN = 0;
|
||||
|
||||
// time synchro
|
||||
d_subframe1_timestamp_ms = 0;
|
||||
d_subframe_timestamp_ms = 0;
|
||||
|
||||
// flags
|
||||
b_alert_flag = false;
|
||||
@ -438,8 +447,10 @@ int Gps_Navigation_Message::subframe_decoder(char *subframe)
|
||||
// subframe and we need the TOW of the first subframe in this data block
|
||||
// (the variable subframe at this point contains bits of the last subframe).
|
||||
//TOW = bin2dec(subframe(31:47)) * 6 - 30;
|
||||
d_TOW = (double)read_navigation_unsigned(subframe_bits, TOW, num_of_slices(TOW));
|
||||
d_TOW = d_TOW*6-6; //we are in the first subframe (the transmitted TOW is the start time of the next subframe, thus we need to substract one subframe (6 seconds)) !
|
||||
d_TOW_SF1 = (double)read_navigation_unsigned(subframe_bits, TOW, num_of_slices(TOW));
|
||||
//we are in the first subframe (the transmitted TOW is the start time of the next subframe) !
|
||||
d_TOW_SF1 = d_TOW_SF1*6;
|
||||
d_TOW=d_TOW_SF5;// Set transmission time
|
||||
b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG);
|
||||
b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG);
|
||||
b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG);
|
||||
@ -463,6 +474,9 @@ int Gps_Navigation_Message::subframe_decoder(char *subframe)
|
||||
break;
|
||||
|
||||
case 2: //--- It is subframe 2 -------------------
|
||||
d_TOW_SF2 = (double)read_navigation_unsigned(subframe_bits, TOW, num_of_slices(TOW));
|
||||
d_TOW_SF2 = d_TOW_SF2*6;
|
||||
d_TOW=d_TOW_SF1;// Set transmission time
|
||||
b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG);
|
||||
b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG);
|
||||
b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG);
|
||||
@ -490,6 +504,9 @@ int Gps_Navigation_Message::subframe_decoder(char *subframe)
|
||||
break;
|
||||
|
||||
case 3: // --- It is subframe 3 -------------------------------------
|
||||
d_TOW_SF3 = (double)read_navigation_unsigned(subframe_bits, TOW, num_of_slices(TOW));
|
||||
d_TOW_SF3 = d_TOW_SF3*6;
|
||||
d_TOW=d_TOW_SF2;// Set transmission time
|
||||
b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG);
|
||||
b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG);
|
||||
b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG);
|
||||
@ -514,6 +531,9 @@ int Gps_Navigation_Message::subframe_decoder(char *subframe)
|
||||
break;
|
||||
|
||||
case 4: // --- It is subframe 4 ---------- Almanac, ionospheric model, UTC parameters, SV health (PRN: 25-32)
|
||||
d_TOW_SF4 = (double)read_navigation_unsigned(subframe_bits, TOW, num_of_slices(TOW));
|
||||
d_TOW_SF4 = d_TOW_SF4*6;
|
||||
d_TOW=d_TOW_SF3;// Set transmission time
|
||||
b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG);
|
||||
b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG);
|
||||
b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG);
|
||||
@ -574,6 +594,9 @@ int Gps_Navigation_Message::subframe_decoder(char *subframe)
|
||||
break;
|
||||
|
||||
case 5://--- It is subframe 5 -----------------almanac health (PRN: 1-24) and Almanac reference week number and time.
|
||||
d_TOW_SF5 = (double)read_navigation_unsigned(subframe_bits, TOW, num_of_slices(TOW));
|
||||
d_TOW_SF5 = d_TOW_SF5*6;
|
||||
d_TOW=d_TOW_SF4;// Set transmission time
|
||||
b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG);
|
||||
b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG);
|
||||
b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG);
|
||||
@ -678,7 +701,7 @@ double Gps_Navigation_Message::utc_time(double gpstime_corrected)
|
||||
/* 20.3.3.5.2.4c
|
||||
* Whenever the effectivity time of the leap second event, as indicated by the
|
||||
* WNLSF and DN values, is in the "past" (relative to the user's current time),
|
||||
* and the userÕs current time does not fall in the time span as given above
|
||||
* and the user<EFBFBD>s current time does not fall in the time span as given above
|
||||
* in 20.3.3.5.2.4b,*/
|
||||
Delta_t_UTC = d_DeltaT_LSF + d_A0 + d_A1 * (gpstime_corrected - d_t_OT + 604800 * (double)(i_GPS_week - i_WN_T));
|
||||
t_utc_daytime = fmod(gpstime_corrected - Delta_t_UTC, 86400);
|
||||
@ -697,13 +720,21 @@ bool Gps_Navigation_Message::satellite_validation()
|
||||
{
|
||||
|
||||
bool flag_data_valid = false;
|
||||
b_valid_ephemeris_set_flag=false;
|
||||
|
||||
// First Step:
|
||||
// check Issue Of Ephemeris Data (IODE IODC..) to find a possible interrupted reception
|
||||
// and check if the data have been filled (!=0)
|
||||
if (d_IODE_SF2 == d_IODE_SF3 and d_IODC == d_IODE_SF2 and d_IODC!=-1)
|
||||
if (d_TOW_SF1!=0 and d_TOW_SF2!=0 and d_TOW_SF3!=0)
|
||||
{
|
||||
|
||||
if (d_IODE_SF2 == d_IODE_SF3 and d_IODC == d_IODE_SF2 and d_IODC!=-1)
|
||||
{
|
||||
//std::cout<<"d_TOW_SF3-d_TOW_SF2="<<d_TOW_SF3-d_TOW_SF2<<std::endl;
|
||||
//std::cout<<"d_TOW_SF2-d_TOW_SF1="<<d_TOW_SF2-d_TOW_SF1<<std::endl;
|
||||
flag_data_valid = true;
|
||||
b_valid_ephemeris_set_flag=true;
|
||||
}
|
||||
}
|
||||
return flag_data_valid;
|
||||
}
|
||||
|
@ -69,8 +69,17 @@ private:
|
||||
double check_t(double time);
|
||||
|
||||
public:
|
||||
|
||||
bool b_update_tow_flag; // flag indicating that this ephemeris set have an updated TOW
|
||||
bool b_valid_ephemeris_set_flag; // flag indicating that this ephemeris set have passed the validation check
|
||||
//broadcast orbit 1
|
||||
double d_TOW; //!< Time of GPS Week [s]
|
||||
double d_TOW; //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s]
|
||||
double d_TOW_SF1; //!< Time of GPS Week from HOW word of Subframe 1 [s]
|
||||
double d_TOW_SF2; //!< Time of GPS Week from HOW word of Subframe 2 [s]
|
||||
double d_TOW_SF3; //!< Time of GPS Week from HOW word of Subframe 3 [s]
|
||||
double d_TOW_SF4; //!< Time of GPS Week from HOW word of Subframe 4 [s]
|
||||
double d_TOW_SF5; //!< Time of GPS Week from HOW word of Subframe 5 [s]
|
||||
|
||||
double d_IODE_SF2;
|
||||
double d_IODE_SF3;
|
||||
double d_Crs; //!< Amplitude of the Sine Harmonic Correction Term to the Orbit Radius [m]
|
||||
@ -155,7 +164,7 @@ public:
|
||||
unsigned int i_satellite_PRN;
|
||||
|
||||
// time synchro
|
||||
double d_subframe1_timestamp_ms; //[ms]
|
||||
double d_subframe_timestamp_ms; //[ms]
|
||||
|
||||
// Ionospheric parameters
|
||||
|
||||
|
@ -27,41 +27,46 @@
|
||||
% *
|
||||
% * -------------------------------------------------------------------------
|
||||
% */
|
||||
close all;
|
||||
clear all;
|
||||
%close all;
|
||||
%clear all;
|
||||
samplingFreq = 64e6/16; %[Hz]
|
||||
channels=6;
|
||||
path='/home/javier/workspace/gnss-sdr/trunk/install/';
|
||||
clear PRN_absolute_sample_start;
|
||||
channels=4;
|
||||
path='/home/javier/workspace/gnss-sdr-ref/trunk/install/';
|
||||
for N=1:1:channels
|
||||
tracking_log_path=[path 'tracking_ch_' num2str(N-1) '.dat'];
|
||||
GNSS_tracking(N)= gps_l1_ca_dll_fll_pll_read_tracking_dump(tracking_log_path);
|
||||
GNSS_tracking(N)= gps_l1_ca_dll_fll_pll_read_tracking_dump(tracking_log_path,samplingFreq);
|
||||
end
|
||||
|
||||
% GNSS-SDR format conversion to MATLAB GPS receiver
|
||||
|
||||
channel_PRN_ID=[32,14,20,11];
|
||||
tracking_loop_start=1;%10001;
|
||||
tracking_loop_end=70000;
|
||||
for N=1:1:channels
|
||||
trackResults(N).status='T'; %fake track
|
||||
trackResults(N).codeFreq=GNSS_tracking(N).code_freq_hz.';
|
||||
trackResults(N).carrFreq=GNSS_tracking(N).carrier_doppler_hz.';
|
||||
trackResults(N).dllDiscr = GNSS_tracking(N).code_error_chips.';
|
||||
trackResults(N).dllDiscrFilt = GNSS_tracking(N).code_phase_samples.';
|
||||
trackResults(N).pllDiscr = GNSS_tracking(N).PLL_discriminator_hz.';
|
||||
trackResults(N).pllDiscrFilt = GNSS_tracking(N).carr_nco.';
|
||||
trackResults_sdr(N).status='T'; %fake track
|
||||
trackResults_sdr(N).codeFreq=GNSS_tracking(N).code_freq_hz(tracking_loop_start:tracking_loop_end).';
|
||||
trackResults_sdr(N).carrFreq=GNSS_tracking(N).carrier_doppler_hz(tracking_loop_start:tracking_loop_end).';
|
||||
trackResults_sdr(N).dllDiscr = GNSS_tracking(N).code_error_chips(tracking_loop_start:tracking_loop_end).';
|
||||
trackResults_sdr(N).dllDiscrFilt = GNSS_tracking(N).code_phase_samples(tracking_loop_start:tracking_loop_end).';
|
||||
trackResults_sdr(N).pllDiscr = GNSS_tracking(N).PLL_discriminator_hz(tracking_loop_start:tracking_loop_end).';
|
||||
trackResults_sdr(N).pllDiscrFilt = GNSS_tracking(N).carr_nco(tracking_loop_start:tracking_loop_end).';
|
||||
trackResults_sdr(N).absoluteSample = (GNSS_tracking(N).var2(tracking_loop_start:tracking_loop_end)+GNSS_tracking(N).var1(tracking_loop_start:tracking_loop_end)).';
|
||||
|
||||
trackResults_sdr(N).prn_delay_ms = 1000*trackResults_sdr(N).absoluteSample/samplingFreq;
|
||||
%trackResults_sdr(N).absoluteSample = (GNSS_tracking(N).PRN_start_sample(tracking_loop_start:tracking_loop_end)+GNSS_tracking(N).var1(tracking_loop_start:tracking_loop_end)).';
|
||||
|
||||
trackResults(N).I_P=GNSS_tracking(N).prompt_I.';
|
||||
trackResults(N).Q_P=GNSS_tracking(N).prompt_Q.';
|
||||
trackResults_sdr(N).I_P=GNSS_tracking(N).prompt_I(tracking_loop_start:tracking_loop_end).';
|
||||
trackResults_sdr(N).Q_P=GNSS_tracking(N).prompt_Q(tracking_loop_start:tracking_loop_end).';
|
||||
|
||||
trackResults(N).I_E= GNSS_tracking(N).E.';
|
||||
trackResults(N).I_L = GNSS_tracking(N).L.';
|
||||
trackResults(N).Q_E = zeros(1,length(GNSS_tracking(N).E));
|
||||
trackResults(N).Q_L =zeros(1,length(GNSS_tracking(N).E));
|
||||
trackResults(N).PRN=N; %fake PRN
|
||||
trackResults_sdr(N).I_E= GNSS_tracking(N).E(tracking_loop_start:tracking_loop_end).';
|
||||
trackResults_sdr(N).I_L = GNSS_tracking(N).L(tracking_loop_start:tracking_loop_end).';
|
||||
trackResults_sdr(N).Q_E = zeros(1,tracking_loop_end-tracking_loop_start+1);
|
||||
trackResults_sdr(N).Q_L =zeros(1,tracking_loop_end-tracking_loop_start+1);
|
||||
trackResults_sdr(N).PRN=channel_PRN_ID(N);
|
||||
|
||||
% Use original MATLAB tracking plot function
|
||||
settings.numberOfChannels=channels;
|
||||
settings.msToProcess=length(GNSS_tracking(N).E);
|
||||
plotTracking(N,trackResults,settings)
|
||||
settings.msToProcess=tracking_loop_end-tracking_loop_start+1;
|
||||
%plotTracking(N,trackResults_sdr,settings)
|
||||
end
|
||||
|
||||
|
||||
|
9
src/utils/matlab/gps_l1_ca_observables_plot_sample.m
Normal file
9
src/utils/matlab/gps_l1_ca_observables_plot_sample.m
Normal file
@ -0,0 +1,9 @@
|
||||
% Read observables dump
|
||||
|
||||
%clear all;
|
||||
|
||||
samplingFreq = 64e6/16; %[Hz]
|
||||
channels=4;
|
||||
path='/home/javier/workspace/gnss-sdr-ref/trunk/install/';
|
||||
observables_log_path=[path 'observables.dat'];
|
||||
GNSS_observables= gps_l1_ca_read_observables_dump(channels,observables_log_path);
|
9
src/utils/matlab/gps_l1_ca_pvt_raw_plot_sample.m
Normal file
9
src/utils/matlab/gps_l1_ca_pvt_raw_plot_sample.m
Normal file
@ -0,0 +1,9 @@
|
||||
% Read PVG raw dump
|
||||
|
||||
%clear all;
|
||||
|
||||
samplingFreq = 64e6/16; %[Hz]
|
||||
channels=4;
|
||||
path='/home/javier/workspace/gnss-sdr-ref/trunk/install/';
|
||||
pvt_raw_log_path=[path 'PVT_raw.dat'];
|
||||
GNSS_PVT_raw= gps_l1_ca_read_pvt_raw_dump(channels,pvt_raw_log_path);
|
40
src/utils/matlab/gps_l1_ca_telemetry_plot_sample.m
Normal file
40
src/utils/matlab/gps_l1_ca_telemetry_plot_sample.m
Normal file
@ -0,0 +1,40 @@
|
||||
% /*!
|
||||
% * \file gps_l1_ca_dll_fll_pll_plot_sample.m
|
||||
% * \brief Read GNSS-SDR Tracking dump binary file using the provided
|
||||
% function and plot some internal variables
|
||||
% * \author Javier Arribas, 2011. jarribas(at)cttc.es
|
||||
% * -------------------------------------------------------------------------
|
||||
% *
|
||||
% * Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors)
|
||||
% *
|
||||
% * GNSS-SDR is a software defined Global Navigation
|
||||
% * Satellite Systems receiver
|
||||
% *
|
||||
% * This file is part of GNSS-SDR.
|
||||
% *
|
||||
% * GNSS-SDR is free software: you can redistribute it and/or modify
|
||||
% * it under the terms of the GNU General Public License as published by
|
||||
% * the Free Software Foundation, either version 3 of the License, or
|
||||
% * at your option) any later version.
|
||||
% *
|
||||
% * GNSS-SDR is distributed in the hope that it will be useful,
|
||||
% * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
% * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
% * GNU General Public License for more details.
|
||||
% *
|
||||
% * You should have received a copy of the GNU General Public License
|
||||
% * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
||||
% *
|
||||
% * -------------------------------------------------------------------------
|
||||
% */
|
||||
%close all;
|
||||
%clear all;
|
||||
samplingFreq = 64e6/16; %[Hz]
|
||||
channels=4;
|
||||
path='/home/javier/workspace/gnss-sdr-ref/trunk/install/';
|
||||
clear PRN_absolute_sample_start;
|
||||
for N=1:1:channels
|
||||
telemetry_log_path=[path 'telemetry' num2str(N-1) '.dat'];
|
||||
GNSS_telemetry(N)= gps_l1_ca_read_telemetry_dump(telemetry_log_path);
|
||||
end
|
||||
|
33
src/utils/matlab/help_script1.m
Normal file
33
src/utils/matlab/help_script1.m
Normal file
@ -0,0 +1,33 @@
|
||||
%help script to compare GNSS-SDR Preambles starts
|
||||
channel=3;
|
||||
% From GNSS_SDR telemetry decoder
|
||||
|
||||
% 1 find preambles indexes
|
||||
preambles_index=find(GNSS_telemetry(channel).Preamble_symbol_counter==0);
|
||||
|
||||
% 2 Get associated timestamp ms
|
||||
|
||||
preambles_timestamp_sdr_ms=GNSS_telemetry(channel).prn_delay_ms(preambles_index);
|
||||
|
||||
|
||||
% From Matlab receiver
|
||||
|
||||
[firstSubFrame, activeChnList, javi_subFrameStart_sample] = findPreambles(trackResults_sdr,settings);
|
||||
|
||||
preambles_timestamp_matlab_ms=trackResults_sdr(channel).prn_delay_ms(javi_subFrameStart_sample(channel,1:6));
|
||||
|
||||
|
||||
%Compare
|
||||
|
||||
common_start_index=max(find(abs(preambles_timestamp_sdr_ms-preambles_timestamp_matlab_ms(1))<2000));
|
||||
|
||||
error_ms=preambles_timestamp_sdr_ms(common_start_index:(common_start_index+length(preambles_timestamp_matlab_ms)-1))-preambles_timestamp_matlab_ms.'
|
||||
|
||||
% figure
|
||||
% stem(tracking_loop_start+javi_subFrameStart_sample(channel,:),1000*trackResults_sdr(channel).absoluteSample(javi_subFrameStart_sample(channel,:))/settings.samplingFreq);
|
||||
%
|
||||
% hold on;
|
||||
%
|
||||
% plot(GNSS_observables.preamble_delay_ms(channel,:));
|
||||
%
|
||||
% plot(GNSS_observables.prn_delay_ms(channel,:),'r')
|
9
src/utils/matlab/help_script2.m
Normal file
9
src/utils/matlab/help_script2.m
Normal file
@ -0,0 +1,9 @@
|
||||
% compare pseudoranges
|
||||
|
||||
close all;
|
||||
% GNSS SDR
|
||||
plot(GNSS_PVT_raw.tx_time(1,1:300).'-200/settings.samplingFreq,GNSS_PVT_raw.Pseudorange_m(1,1:300).')
|
||||
|
||||
% MATLAB
|
||||
hold on;
|
||||
plot(navSolutions.transmitTime,navSolutions.channel.rawP(1,:),'g')
|
@ -26,14 +26,14 @@
|
||||
% *
|
||||
% * -------------------------------------------------------------------------
|
||||
% */
|
||||
function [GNSS_tracking] = gps_l1_ca_dll_fll_pll_read_tracking_dump (filename, count)
|
||||
function [GNSS_tracking] = gps_l1_ca_dll_fll_pll_read_tracking_dump (filename, samplingFreq, count)
|
||||
|
||||
%% usage: gps_l1_ca_dll_fll_pll_read_tracking_dump (filename, [count])
|
||||
%%
|
||||
%% open GNSS-SDR tracking binary log file .dat and return the contents
|
||||
%%
|
||||
|
||||
m = nargchk (1,2,nargin);
|
||||
m = nargchk (1,3,nargin);
|
||||
num_float_vars=16;
|
||||
num_double_vars=1;
|
||||
double_size_bytes=8;
|
||||
@ -44,7 +44,7 @@ function [GNSS_tracking] = gps_l1_ca_dll_fll_pll_read_tracking_dump (filename, c
|
||||
usage (m);
|
||||
end
|
||||
|
||||
if (nargin < 2)
|
||||
if (nargin < 3)
|
||||
count = Inf;
|
||||
end
|
||||
%loops_counter = fread (f, count, 'uint32',4*12);
|
||||
@ -173,5 +173,6 @@ function [GNSS_tracking] = gps_l1_ca_dll_fll_pll_read_tracking_dump (filename, c
|
||||
GNSS_tracking.carrier_lock_test=carrier_lock_test;
|
||||
GNSS_tracking.var1=var1;
|
||||
GNSS_tracking.var2=var2;
|
||||
GNSS_tracking.prn_delay_ms=1000*(GNSS_tracking.var2+GNSS_tracking.var1)./samplingFreq;
|
||||
end
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
% Javier Arribas 2011
|
||||
function [preamble_delay_ms,prn_delay_ms] = gps_l1_ca_dll_pll_read_observables_dump (channels, filename, count)
|
||||
function [observables] = gps_l1_ca_dll_pll_read_observables_dump (channels, filename, count)
|
||||
|
||||
%% usage: read_tracking_dat (filename, [count])
|
||||
%%
|
||||
@ -7,7 +7,7 @@ function [preamble_delay_ms,prn_delay_ms] = gps_l1_ca_dll_pll_read_observables_d
|
||||
%%
|
||||
|
||||
m = nargchk (1,2,nargin);
|
||||
num_double_vars=2;
|
||||
num_double_vars=5;
|
||||
double_size_bytes=8;
|
||||
skip_bytes_each_read=double_size_bytes*num_double_vars*channels;
|
||||
bytes_shift=0;
|
||||
@ -23,10 +23,19 @@ function [preamble_delay_ms,prn_delay_ms] = gps_l1_ca_dll_pll_read_observables_d
|
||||
if (f < 0)
|
||||
else
|
||||
for N=1:1:channels
|
||||
preamble_delay_ms(N,:) = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes);
|
||||
observables.preamble_delay_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
|
||||
prn_delay_ms(N,:) = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes);
|
||||
observables.prn_delay_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);
|
||||
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);
|
||||
bytes_shift=bytes_shift+double_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next interleaved
|
||||
end
|
||||
@ -34,12 +43,18 @@ function [preamble_delay_ms,prn_delay_ms] = gps_l1_ca_dll_pll_read_observables_d
|
||||
fclose (f);
|
||||
|
||||
%%%%%%%% output vars %%%%%%%%
|
||||
% for (unsigned int i=0; i<d_nchannels ; i++)
|
||||
% {
|
||||
% tmp_double=in[i][0].preamble_delay_ms;
|
||||
% d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
% tmp_double=in[i][0].prn_delay_ms;
|
||||
% d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
% }
|
||||
% for (unsigned int i=0; i<d_nchannels ; i++)
|
||||
% {
|
||||
% tmp_double = current_gnss_synchro[i].Preamble_delay_ms;
|
||||
% d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
% tmp_double = current_gnss_synchro[i].Prn_delay_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;
|
||||
% 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
|
||||
|
||||
|
60
src/utils/matlab/libs/gps_l1_ca_read_observables_dump.m
Normal file
60
src/utils/matlab/libs/gps_l1_ca_read_observables_dump.m
Normal file
@ -0,0 +1,60 @@
|
||||
% Javier Arribas 2011
|
||||
function [observables] = gps_l1_ca_read_observables_dump (channels, filename, count)
|
||||
|
||||
%% usage: read_tracking_dat (filename, [count])
|
||||
%%
|
||||
%% open GNSS-SDR tracking binary log file .dat and return the contents
|
||||
%%
|
||||
|
||||
m = nargchk (1,2,nargin);
|
||||
num_double_vars=5;
|
||||
double_size_bytes=8;
|
||||
skip_bytes_each_read=double_size_bytes*num_double_vars*channels;
|
||||
bytes_shift=0;
|
||||
if (m)
|
||||
usage (m);
|
||||
end
|
||||
|
||||
if (nargin < 3)
|
||||
count = Inf;
|
||||
end
|
||||
%loops_counter = fread (f, count, 'uint32',4*12);
|
||||
f = fopen (filename, 'rb');
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
bytes_shift=bytes_shift+double_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next interleaved
|
||||
end
|
||||
|
||||
fclose (f);
|
||||
|
||||
%%%%%%%% output vars %%%%%%%%
|
||||
% for (unsigned int i=0; i<d_nchannels ; i++)
|
||||
% {
|
||||
% tmp_double = current_gnss_synchro[i].Preamble_delay_ms;
|
||||
% d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
% tmp_double = current_gnss_synchro[i].Prn_delay_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;
|
||||
% 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
|
||||
|
49
src/utils/matlab/libs/gps_l1_ca_read_pvt_raw_dump.m
Normal file
49
src/utils/matlab/libs/gps_l1_ca_read_pvt_raw_dump.m
Normal file
@ -0,0 +1,49 @@
|
||||
% Javier Arribas 2011
|
||||
function [pvt_raw] = gps_l1_ca_read_pvt_raw_dump (channels, filename, count)
|
||||
|
||||
%% usage: read_tracking_dat (filename, [count])
|
||||
%%
|
||||
%% open GNSS-SDR pvt binary log file .dat and return the contents
|
||||
%%
|
||||
|
||||
m = nargchk (1,2,nargin);
|
||||
num_double_vars=3;
|
||||
double_size_bytes=8;
|
||||
skip_bytes_each_read=double_size_bytes*num_double_vars*channels;
|
||||
bytes_shift=0;
|
||||
if (m)
|
||||
usage (m);
|
||||
end
|
||||
|
||||
if (nargin < 3)
|
||||
count = Inf;
|
||||
end
|
||||
%loops_counter = fread (f, count, 'uint32',4*12);
|
||||
f = fopen (filename, 'rb');
|
||||
if (f < 0)
|
||||
else
|
||||
for N=1:1:channels
|
||||
pvt_raw.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
|
||||
pvt_raw.Pseudorange_symbol_shift(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
|
||||
pvt_raw.tx_time(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
|
||||
end
|
||||
|
||||
fclose (f);
|
||||
|
||||
%%%%%%%% output vars %%%%%%%%
|
||||
% 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 = in[i][0].Pseudorange_symbol_shift;
|
||||
% d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
% d_dump_file.write((char*)&d_tx_time, sizeof(double));
|
||||
% }
|
||||
end
|
||||
|
48
src/utils/matlab/libs/gps_l1_ca_read_telemetry_dump.m
Normal file
48
src/utils/matlab/libs/gps_l1_ca_read_telemetry_dump.m
Normal file
@ -0,0 +1,48 @@
|
||||
% Javier Arribas 2011
|
||||
function [telemetry] = gps_l1_ca_read_telemetry_dump (filename, count)
|
||||
|
||||
%% usage: read_tracking_dat (filename, [count])
|
||||
%%
|
||||
%% open GNSS-SDR tracking binary log file .dat and return the contents
|
||||
%%
|
||||
|
||||
m = nargchk (1,2,nargin);
|
||||
num_double_vars=3;
|
||||
double_size_bytes=8;
|
||||
skip_bytes_each_read=double_size_bytes*num_double_vars;
|
||||
bytes_shift=0;
|
||||
if (m)
|
||||
usage (m);
|
||||
end
|
||||
|
||||
if (nargin < 3)
|
||||
count = Inf;
|
||||
end
|
||||
%loops_counter = fread (f, count, 'uint32',4*12);
|
||||
f = fopen (filename, 'rb');
|
||||
if (f < 0)
|
||||
else
|
||||
telemetry.preamble_delay_ms = 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
|
||||
telemetry.prn_delay_ms = 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
|
||||
telemetry.Preamble_symbol_counter = 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
|
||||
|
||||
fclose (f);
|
||||
|
||||
%%%%%%%% output vars %%%%%%%%
|
||||
% {
|
||||
% double tmp_double;
|
||||
% tmp_double = current_synchro_data.Preamble_delay_ms;
|
||||
% d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
% tmp_double = current_synchro_data.Prn_delay_ms;
|
||||
% d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
% tmp_double = current_synchro_data.Preamble_symbol_counter;
|
||||
% d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
% }
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user