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:
Javier Arribas 2012-04-11 10:43:35 +00:00
parent 89a67c93e8
commit 9d34147e0f
33 changed files with 932 additions and 502 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View 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

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

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

View File

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

View File

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

View 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

View 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

View 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