diff --git a/.gitignore b/.gitignore index 2d1eebded..a128f1558 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,10 @@ docs/latex docs/GNSS-SDR_manual.pdf src/tests/data/output.dat thirdparty/ +.settings .project .cproject +.idea +cmake-build-debug/ /install .DS_Store diff --git a/AUTHORS b/AUTHORS index 451c4a971..17aa5fa4b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -34,23 +34,25 @@ Contact Information List of authors ------------------------------------------------------------------------------ Carles Fernandez-Prades carles.fernandez@cttc.cat Project manager -Javier Arribas javier.arribas@cttc.cat Developer +Javier Arribas javier.arribas@cttc.es Developer Luis Esteve Elfau luis@epsilon-formacion.com Developer -Pau Closas pau.closas@cttc.cat Consultant -Carlos Aviles carlos.avilesr@googlemail.com Developer -David Pubill david.pubill@cttc.cat Developer -Mara Branzanti mara.branzanti@gmail.com Developer -Marc Molina marc.molina.pena@gmail.com Developer -Daniel Fehr daniel.co@bluewin.ch Developer -Marc Sales marcsales92@gmail.com Developer -Damian Miralles dmiralles2009@gmail.com Developer -Andres Cecilia Luque a.cecilia.luque@gmail.com Developer +Antonio Ramos antonio.ramos@cttc.es Developer +Marc Majoral marc.majoral@cttc.cat Developer +Pau Closas pau.closas@northeastern.edu Consultant +Jordi Vila-Valls jordi.vila@cttc.cat Consultant +Carlos Aviles carlos.avilesr@googlemail.com Contributor +David Pubill david.pubill@cttc.cat Contributor +Mara Branzanti mara.branzanti@gmail.com Contributor +Marc Molina marc.molina.pena@gmail.com Contributor +Daniel Fehr daniel.co@bluewin.ch Contributor +Marc Sales marcsales92@gmail.com Contributor +Damian Miralles dmiralles2009@gmail.com Contributor +Andres Cecilia Luque a.cecilia.luque@gmail.com Contributor Leonardo Tonetto tonetto.dev@gmail.com Contributor Anthony Arnold anthony.arnold@uqconnect.edu.au Contributor Fran Fabra fabra@ice.csic.es Contributor Cillian O'Driscoll cillian.odriscoll@gmail.com Contributor -Ignacio Paniego ignacio.paniego@gmail.com Web design -Eva Puchol eva.puchol@gmail.com Web developer +Gabriel Araujo gabriel.araujo.5000@gmail.com Contributor Carlos Paniego carpanie@hotmail.com Artwork diff --git a/README.md b/README.md index 06f884a00..f52363ebd 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,21 @@ **Welcome to GNSS-SDR!** -Visit [http://gnss-sdr.org](http://gnss-sdr.org "GNSS-SDR website") for more information about this open source GNSS software defined receiver. +This program is a software-defined receiver which is able to process (that is, to perform detection, synchronization, demodulation and decoding of the navigation message, computation of observables and, finally, computation of position fixes) the following Global Navigation Satellite System's signals: + +In the L1 band (centered at 1575.42 MHz): + - 🛰 GPS L1 C/A :white_check_mark: + - 🛰 Galileo E1b/c :white_check_mark: + - 🛰 GLONASS L1 C/A :white_check_mark: + +In the L2 band (centered at 1227.60 MHz): + - 🛰 GPS L2C :white_check_mark: + +In the L5 band (centered at 1176.45 MHz): + - 🛰 GPS L5 :white_check_mark: + - 🛰 Galileo E5a :white_check_mark: + +GNSS-SDR provides interfaces for a wide range of radio frequency front-ends, generates processing outputs in standard formats, allows for the full inspection of the whole signal processing chain, and offers a framework for the development of new features. Please visit [http://gnss-sdr.org](http://gnss-sdr.org "GNSS-SDR website") for more information about this open source software-defined GNSS receiver. @@ -593,6 +607,7 @@ The CMake script will create Makefiles that download, build and link Armadillo, Other builds --------- +* **Docker container**: A technology providing operating-system-level virtualization to build, ship, and run distributed applications, whether on laptops, data center VMs, or the cloud. Visit [https://github.com/carlesfernandez/docker-gnsssdr](https://github.com/carlesfernandez/docker-gnsssdr) or [https://github.com/carlesfernandez/docker-pybombs-gnsssdr](https://github.com/carlesfernandez/docker-pybombs-gnsssdr) for instructions. * **Snap packages**: [Snaps](http://snapcraft.io) are universal Linux packages aimed to work on any distribution or device, from IoT devices to servers, desktops to mobile devices. Visit [https://github.com/carlesfernandez/snapcraft-sandbox](https://github.com/carlesfernandez/snapcraft-sandbox) for instructions. @@ -767,14 +782,13 @@ The user can configure the receiver for reading from a file, setting in the conf SignalSource.implementation=File_Signal_Source SignalSource.filename=/home/user/gnss-sdr/data/my_capture.dat SignalSource.item_type=gr_complex -SignalSource.sampling_frequency=4000000 ; Sampling frequency in [Hz] -SignalSource.freq=1575420000 ; RF front-end center frequency in [Hz] +SignalSource.sampling_frequency=4000000 ; Sampling frequency in samples per second (Sps) ~~~~~~ Type ```gr_complex``` refers to a GNU Radio typedef equivalent to ```std::complex```. In order to save some storage space, you might wanted to store your signal in a more efficient format such as an I/Q interleaved ```short`` integer sample stream. In that case, change the corresponding line to: ~~~~~~ -SignalSource.item_type=short +SignalSource.item_type=ishort ~~~~~~ In this latter case, you will need to convert the interleaved I/Q samples to a complex stream via Data Type Adapter block (see below). @@ -874,7 +888,7 @@ SignalSource.freq=1575420000 SignalSource.rf_gain=40 SignalSource.if_gain=30 SignalSource.enable_throttle_control=false -SignalSource.osmosdr_args=rtl_tcp,offset_tune=1 +SignalSource.osmosdr_args=hackrf,bias=1 ~~~~~~ In case of using a Zarlink's RTL2832 based DVB-T receiver, you can even use the ```rtl_tcp``` I/Q server in order to use the USB dongle remotely. In a terminal, type: @@ -1046,12 +1060,14 @@ Each channel must be assigned to a GNSS signal, according to the following ident | **Signal** | **Identifier** | |:------------------|:---------------:| | GPS L1 C/A | 1C | +| Galileo E1b/c | 1B | +| Glonass L1 C/A | 1G | | GPS L2 L2C(M) | 2S | | GPS L5 | L5 | -| Galileo E1b/c | 1B | | Galileo E5a | 5X | + Example: Eight GPS L1 C/A channels. ~~~~~~ ;######### CHANNELS GLOBAL CONFIG ############ diff --git a/conf/front-end-cal.conf b/conf/front-end-cal.conf index 8b09a2065..72c9be845 100644 --- a/conf/front-end-cal.conf +++ b/conf/front-end-cal.conf @@ -42,16 +42,12 @@ GNSS-SDR.SUPL_CI=40184 ;######### SIGNAL_SOURCE CONFIG ############ SignalSource.implementation=Osmosdr_Signal_Source - ;#freq: RF front-end center frequency in [Hz] SignalSource.freq=1575420000 - ;#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] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=2000000 - ;#gain: Front-end Gain in [dB] SignalSource.gain=40 SignalSource.rf_gain=40 @@ -91,7 +87,7 @@ SignalSource.dump_filename=../data/signal_source.dat SignalConditioner.implementation=Pass_Through ;######### DATA_TYPE_ADAPTER CONFIG ############ -;## Changes the type of input data. Please disable it in this version. +;## Changes the type of input data. ;#implementation: Use [Ishort_To_Complex] or [Pass_Through] DataTypeAdapter.implementation=Pass_Through ;#dump: Dump the filtered data to a file. @@ -109,20 +105,15 @@ DataTypeAdapter.dump_filename=../data/data_type_adapter.dat InputFilter.implementation=Freq_Xlating_Fir_Filter -;#dump: Dump the filtered data to a file. -InputFilter.dump=false - -;#dump_filename: Log path and filename. -InputFilter.dump_filename=../data/input_filter.dat - ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -172,6 +163,12 @@ InputFilter.IF=0 InputFilter.decimation_factor=1 +;#dump: Dump the filtered data to a file. +InputFilter.dump=false + +;#dump_filename: Log path and filename. +InputFilter.dump_filename=../data/input_filter.dat + ;######### RESAMPLER CONFIG ############ ;## Resamples the input data. ;#implementation: Use [Pass_Through] or [Direct_Resampler] @@ -179,11 +176,7 @@ InputFilter.decimation_factor=1 Resampler.implementation=Pass_Through ;######### 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 +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler ;#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] @@ -200,4 +193,8 @@ Acquisition.doppler_min=-100000 Acquisition.doppler_step=500 ;#maximum dwells Acquisition.max_dwells=15 +;#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 diff --git a/conf/gnss-sdr.conf b/conf/gnss-sdr.conf index 6ffffd631..0c456f075 100644 --- a/conf/gnss-sdr.conf +++ b/conf/gnss-sdr.conf @@ -25,32 +25,18 @@ GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=File_Signal_Source - ;#filename: path to file with the captured GNSS signal samples to be processed SignalSource.filename=/datalogger/signals/CTTC/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ; <- PUT YOUR FILE HERE - ;#item_type: Type and resolution for each of the signal samples. SignalSource.item_type=ishort - -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=4000000 - -;#freq: RF front-end center frequency in [Hz] -SignalSource.freq=1575420000 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 - ;#repeat: Repeat the processing file. 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 - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false @@ -82,15 +68,10 @@ DataTypeAdapter.implementation=Ishort_To_Complex ;InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.implementation=Pass_Through -;#dump: Dump the filtered data to a file. -InputFilter.dump=false - -;#dump_filename: Log path and filename. -InputFilter.dump_filename=../data/input_filter.dat - ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of GNU Radio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, the desired response on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. ;#input_item_type: Type and resolution for input signal samples. InputFilter.input_item_type=gr_complex @@ -142,31 +123,31 @@ InputFilter.grid_density=16 InputFilter.sampling_frequency=4000000 InputFilter.IF=0 +;#dump: Dump the filtered data to a file. +InputFilter.dump=false + +;#dump_filename: Log path and filename. +InputFilter.dump_filename=../data/input_filter.dat ;######### RESAMPLER CONFIG ############ ;## Resamples the input data. - ;#implementation: Use [Pass_Through] or [Direct_Resampler] ;#[Pass_Through] disables this block ;#[Direct_Resampler] enables a resampler that implements a nearest neighborhood interpolation ;Resampler.implementation=Direct_Resampler Resampler.implementation=Pass_Through - +;#item_type: Type and resolution for each of the signal samples. +Resampler.item_type=gr_complex +;#sample_freq_in: the sample frequency of the input signal +Resampler.sample_freq_in=4000000 +;#sample_freq_out: the desired sample frequency of the output signal +Resampler.sample_freq_out=2000000 ;#dump: Dump the resampled data to a file. Resampler.dump=false ;#dump_filename: Log path and filename. Resampler.dump_filename=../data/resampler.dat -;#item_type: Type and resolution for each of the signal samples. -Resampler.item_type=gr_complex - -;#sample_freq_in: the sample frequency of the input signal -Resampler.sample_freq_in=4000000 - -;#sample_freq_out: the desired sample frequency of the output signal -Resampler.sample_freq_out=2000000 - ;######### CHANNELS GLOBAL CONFIG ############ ;#count: Number of available GPS L1 C/A satellite channels. @@ -194,19 +175,13 @@ Channel.signal=1C ;Channel1.satellite=18 ;######### ACQUISITION GLOBAL CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler ;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.sampled_ms=1 -;#implementation: Acquisition algorithm selection for this channel -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler ;#threshold: Acquisition threshold Acquisition_1C.threshold=0.005 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -219,46 +194,41 @@ Acquisition_1C.doppler_min=-10000 Acquisition_1C.doppler_step=500 ;#maximum dwells Acquisition_1C.max_dwells=5 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat + ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm: Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking ;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=45.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=3.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=../data/epl_tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=45.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=3.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;#decimation factor -TelemetryDecoder_1C.decimation_factor=1; + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat @@ -266,42 +236,30 @@ Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ ;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad PVT.AR_GPS=PPP-AR ; options: OFF, Continuous, Instantaneous, Fix-and-Hold, PPP-AR - ;#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=10 - ;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms <= display_rate_ms. PVT.display_rate_ms=500 - PVT.positioning_mode=PPP_Static - ;# KML, GeoJSON, NMEA and RTCM output configuration - +;#nmea_dump_filename: NMEA log path and filename +PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea +;#flag_nmea_tty_port: Enables or disables the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) +PVT.flag_nmea_tty_port=true +;#nmea_dump_devname: serial device descriptor for NMEA logging +PVT.nmea_dump_devname=/dev/pts/4 +;#flag_rtcm_server: Enables or disables a TCP/IP server transmitting RTCM 3.2 messages (accepts multiple clients, port 2101 by default) +PVT.flag_rtcm_server=true +;#flag_rtcm_tty_port: Enables or disables the RTCM log to a serial TTY port (Can be used with real hardware or virtual one) +PVT.flag_rtcm_tty_port=false +;#rtcm_dump_devname: serial device descriptor for RTCM logging +PVT.rtcm_dump_devname=/dev/pts/1 +;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] +PVT.dump=false ;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump, ".kml" and ".geojson" to GIS-friendly formats. PVT.dump_filename=./PVT -;#nmea_dump_filename: NMEA log path and filename -PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea - -;#flag_nmea_tty_port: Enables or disables the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) -PVT.flag_nmea_tty_port=true - -;#nmea_dump_devname: serial device descriptor for NMEA logging -PVT.nmea_dump_devname=/dev/pts/4 - -;#flag_rtcm_server: Enables or disables a TCP/IP server transmitting RTCM 3.2 messages (accepts multiple clients, port 2101 by default) -PVT.flag_rtcm_server=true - -;#flag_rtcm_tty_port: Enables or disables the RTCM log to a serial TTY port (Can be used with real hardware or virtual one) -PVT.flag_rtcm_tty_port=false - -;#rtcm_dump_devname: serial device descriptor for RTCM logging -PVT.rtcm_dump_devname=/dev/pts/1 - -;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] -PVT.dump=false diff --git a/conf/gnss-sdr_GLONASS_L1_CA_GPS_L1_CA_ibyte.conf b/conf/gnss-sdr_GLONASS_L1_CA_GPS_L1_CA_ibyte.conf new file mode 100644 index 000000000..aa37222fd --- /dev/null +++ b/conf/gnss-sdr_GLONASS_L1_CA_GPS_L1_CA_ibyte.conf @@ -0,0 +1,141 @@ +[GNSS-SDR] + +;######### GLOBAL OPTIONS ################## +GNSS-SDR.internal_fs_sps=6625000 +Receiver.sources_count=2 + +;######### SIGNAL_SOURCE CONFIG ############ +SignalSource0.implementation=File_Signal_Source +SignalSource0.filename=/archive/NT1065_L1_20160923_fs6625e6_if60e3_schar.bin ; <- PUT YOUR FILE HERE +SignalSource0.item_type=ibyte +SignalSource0.sampling_frequency=6625000 +SignalSource0.samples=0 +SignalSource0.dump=false; +SignalSource0.dump_filename=/archive/signal_glonass.bin + +SignalSource1.implementation=File_Signal_Source +SignalSource1.filename=/archive/NT1065_GLONASS_L1_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE +SignalSource1.item_type=ibyte +SignalSource1.sampling_frequency=6625000 +SignalSource1.samples=0 +SignalSource1.dump=false; +SignalSource1.dump_filename=/archive/signal_glonass.bin + +;######### SIGNAL_CONDITIONER CONFIG ############ +SignalConditioner0.implementation=Signal_Conditioner +DataTypeAdapter0.implementation=Ibyte_To_Complex +InputFilter0.implementation=Freq_Xlating_Fir_Filter +InputFilter0.item_type=gr_complex +InputFilter0.output_item_type=gr_complex +InputFilter0.taps_item_type=float +InputFilter0.number_of_taps=5 +InputFilter0.number_of_bands=2 +InputFilter0.band1_begin=0.0 +InputFilter0.band1_end=0.70 +InputFilter0.band2_begin=0.80 +InputFilter0.band2_end=1.0 +InputFilter0.ampl1_begin=1.0 +InputFilter0.ampl1_end=1.0 +InputFilter0.ampl2_begin=0.0 +InputFilter0.ampl2_end=0.0 +InputFilter0.band1_error=1.0 +InputFilter0.band2_error=1.0 +InputFilter0.filter_type=bandpass +InputFilter0.grid_density=16 +InputFilter0.sampling_frequency=6625000 +InputFilter0.IF=60000 +Resampler0.implementation=Direct_Resampler +Resampler0.sample_freq_in=6625000 +Resampler0.sample_freq_out=6625000 +Resampler0.item_type=gr_complex + +SignalConditioner1.implementation=Signal_Conditioner +DataTypeAdapter1.implementation=Ibyte_To_Complex +InputFilter1.implementation=Pass_Through +InputFilter1.item_type=gr_complex +Resampler1.implementation=Pass_Through +Resampler1.item_type=gr_complex + +;######### CHANNELS GLOBAL CONFIG ############ +Channels.in_acquisition=1 +Channels_1G.count=5 +Channels_1C.count=5 + +;# Defining GLONASS satellites +Channel0.RF_channel_ID=0 +Channel1.RF_channel_ID=0 +Channel2.RF_channel_ID=0 +Channel3.RF_channel_ID=0 +Channel4.RF_channel_ID=0 +Channel5.RF_channel_ID=1 +Channel6.RF_channel_ID=1 +Channel7.RF_channel_ID=1 +Channel8.RF_channel_ID=1 +Channel9.RF_channel_ID=1 + + +;######### ACQUISITION GLOBAL CONFIG ############ +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +Acquisition_1C.item_type=gr_complex +Acquisition_1C.threshold=0.0 +Acquisition_1C.pfa=0.00001 +Acquisition_1C.if=0 +Acquisition_1C.doppler_max=10000 +Acquisition_1C.doppler_step=250 +Acquisition_1C.dump=false; +Acquisition_1C.dump_filename=/archive/gps_acquisition.dat +;Acquisition_1C.coherent_integration_time_ms=10 + +Acquisition_1G.implementation=GLONASS_L1_CA_PCPS_Acquisition +Acquisition_1G.item_type=gr_complex +Acquisition_1G.threshold=0.0 +Acquisition_1G.pfa=0.00001 +Acquisition_1G.if=0 +Acquisition_1G.doppler_max=10000 +Acquisition_1G.doppler_step=250 +Acquisition_1G.dump=false; +Acquisition_1G.dump_filename=/archive/glo_acquisition.dat +;Acquisition_1G.coherent_integration_time_ms=10 + +;######### TRACKING GLOBAL CONFIG ############ +Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking +Tracking_1C.item_type=gr_complex +Tracking_1C.if=0 +Tracking_1C.early_late_space_chips=0.5 +Tracking_1C.pll_bw_hz=20.0; +Tracking_1C.dll_bw_hz=2.0; +Tracking_1C.dump=false; +Tracking_1C.dump_filename=/archive/gps_tracking_ch_ + +Tracking_1G.implementation=GLONASS_L1_CA_DLL_PLL_Tracking +Tracking_1G.item_type=gr_complex +Tracking_1G.if=0 +Tracking_1G.early_late_space_chips=0.5 +Tracking_1G.pll_bw_hz=25.0; +Tracking_1G.dll_bw_hz=3.0; +Tracking_1G.dump=false; +Tracking_1G.dump_filename=/archive/glo_tracking_ch_ + +;######### TELEMETRY DECODER GPS CONFIG ############ +TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder +TelemetryDecoder_1G.implementation=GLONASS_L1_CA_Telemetry_Decoder + +;######### OBSERVABLES CONFIG ############ +Observables.implementation=Hybrid_Observables +Observables.dump=false; +Observables.dump_filename=/archive/gnss_observables.dat + +;######### PVT CONFIG ############ +PVT.implementation=RTKLIB_PVT +PVT.output_rate_ms=100 +PVT.display_rate_ms=500 +PVT.trop_model=Saastamoinen +PVT.flag_rtcm_server=false +PVT.flag_rtcm_tty_port=false +PVT.rtcm_dump_devname=/dev/pts/1 +PVT.rtcm_tcp_port=2101 +PVT.rtcm_MT1019_rate_ms=5000 +PVT.rtcm_MT1045_rate_ms=5000 +PVT.rtcm_MT1097_rate_ms=1000 +PVT.rtcm_MT1077_rate_ms=1000 +PVT.rinex_version=3 diff --git a/conf/gnss-sdr_GLONASS_L1_CA_GPS_L2C_ibyte.conf b/conf/gnss-sdr_GLONASS_L1_CA_GPS_L2C_ibyte.conf new file mode 100644 index 000000000..cc9ba010f --- /dev/null +++ b/conf/gnss-sdr_GLONASS_L1_CA_GPS_L2C_ibyte.conf @@ -0,0 +1,142 @@ +[GNSS-SDR] + +;######### GLOBAL OPTIONS ################## +GNSS-SDR.internal_fs_sps=6625000 +Receiver.sources_count=2 + +;######### SIGNAL_SOURCE CONFIG ############ +SignalSource0.implementation=File_Signal_Source +SignalSource0.filename=/archive/NT1065_L2_20160923_fs6625e6_if60e3_schar.bin ; <- PUT YOUR FILE HERE +SignalSource0.item_type=ibyte +SignalSource0.sampling_frequency=6625000 +SignalSource0.samples=0 +SignalSource0.dump=false; +SignalSource0.dump_filename=/archive/signal_glonass.bin + +SignalSource1.implementation=File_Signal_Source +SignalSource1.filename=/archive/NT1065_GLONASS_L1_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE +SignalSource1.item_type=ibyte +SignalSource1.sampling_frequency=6625000 +SignalSource1.samples=0 +SignalSource1.dump=false; +SignalSource1.dump_filename=/archive/signal_glonass.bin + +;######### SIGNAL_CONDITIONER CONFIG ############ +SignalConditioner0.implementation=Signal_Conditioner +DataTypeAdapter0.implementation=Ibyte_To_Complex +InputFilter0.implementation=Freq_Xlating_Fir_Filter +InputFilter0.item_type=gr_complex +InputFilter0.output_item_type=gr_complex +InputFilter0.taps_item_type=float +InputFilter0.number_of_taps=5 +InputFilter0.number_of_bands=2 +InputFilter0.band1_begin=0.0 +InputFilter0.band1_end=0.70 +InputFilter0.band2_begin=0.80 +InputFilter0.band2_end=1.0 +InputFilter0.ampl1_begin=1.0 +InputFilter0.ampl1_end=1.0 +InputFilter0.ampl2_begin=0.0 +InputFilter0.ampl2_end=0.0 +InputFilter0.band1_error=1.0 +InputFilter0.band2_error=1.0 +InputFilter0.filter_type=bandpass +InputFilter0.grid_density=16 +InputFilter0.sampling_frequency=6625000 +InputFilter0.IF=60000 +Resampler0.implementation=Pass_Through +Resampler0.item_type=gr_complex + +SignalConditioner1.implementation=Signal_Conditioner +DataTypeAdapter1.implementation=Ibyte_To_Complex +InputFilter1.implementation=Pass_Through +InputFilter1.item_type=gr_complex +Resampler1.implementation=Pass_Through +Resampler1.item_type=gr_complex + +;######### CHANNELS GLOBAL CONFIG ############ +Channels.in_acquisition=5 +Channels_2S.count=5 +Channels_1G.count=5 + +;# Defining GLONASS satellites +Channel0.RF_channel_ID=0 +Channel0.signal=2S +Channel1.RF_channel_ID=0 +Channel1.signal=2S +Channel2.RF_channel_ID=0 +Channel2.signal=2S +Channel3.RF_channel_ID=0 +Channel3.signal=2S +Channel4.RF_channel_ID=0 +Channel4.signal=2S +Channel5.RF_channel_ID=1 +Channel6.RF_channel_ID=1 +Channel7.RF_channel_ID=1 +Channel8.RF_channel_ID=1 +Channel9.RF_channel_ID=1 + + +;######### ACQUISITION GLOBAL CONFIG ############ +Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition +Acquisition_2S.item_type=gr_complex +Acquisition_2S.threshold=0.0 +Acquisition_2S.pfa=0.00001 +Acquisition_2S.if=0 +Acquisition_2S.doppler_max=10000 +Acquisition_2S.doppler_step=60 +Acquisition_2S.max_dwells=1 + +Acquisition_1G.implementation=GLONASS_L1_CA_PCPS_Acquisition +Acquisition_1G.item_type=gr_complex +Acquisition_1G.threshold=0.0 +Acquisition_1G.pfa=0.00001 +Acquisition_1G.if=0 +Acquisition_1G.doppler_max=10000 +Acquisition_1G.doppler_step=250 +Acquisition_1G.dump=false; +Acquisition_1G.dump_filename=/archive/glo_acquisition.dat + +;######### TRACKING GLOBAL CONFIG ############ +Tracking_2S.implementation=GPS_L2_M_DLL_PLL_Tracking +Tracking_2S.item_type=gr_complex +Tracking_2S.if=0 +Tracking_2S.early_late_space_chips=0.5 +Tracking_2S.pll_bw_hz=2.0; +Tracking_2S.dll_bw_hz=0.250; +Tracking_2S.order=2; +Tracking_2S.dump=false; +Tracking_2S.dump_filename=/archive/gps_tracking_ch_ + +Tracking_1G.implementation=GLONASS_L1_CA_DLL_PLL_Tracking +Tracking_1G.item_type=gr_complex +Tracking_1G.if=0 +Tracking_1G.early_late_space_chips=0.5 +Tracking_1G.pll_bw_hz=25.0; +Tracking_1G.dll_bw_hz=3.0; +Tracking_1G.dump=false; +Tracking_1G.dump_filename=/archive/glo_tracking_ch_ + +;######### TELEMETRY DECODER GPS CONFIG ############ +TelemetryDecoder_2S.implementation=GPS_L2C_Telemetry_Decoder +TelemetryDecoder_1G.implementation=GLONASS_L1_CA_Telemetry_Decoder + +;######### OBSERVABLES CONFIG ############ +Observables.implementation=Hybrid_Observables +Observables.dump=false; +Observables.dump_filename=/archive/gnss_observables.dat + +;######### PVT CONFIG ############ +PVT.implementation=RTKLIB_PVT +PVT.output_rate_ms=100 +PVT.display_rate_ms=500 +PVT.trop_model=Saastamoinen +PVT.flag_rtcm_server=true +PVT.flag_rtcm_tty_port=false +PVT.rtcm_dump_devname=/dev/pts/1 +PVT.rtcm_tcp_port=2101 +PVT.rtcm_MT1019_rate_ms=5000 +PVT.rtcm_MT1045_rate_ms=5000 +PVT.rtcm_MT1097_rate_ms=1000 +PVT.rtcm_MT1077_rate_ms=1000 +PVT.rinex_version=3 diff --git a/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf b/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf new file mode 100644 index 000000000..a256bd370 --- /dev/null +++ b/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf @@ -0,0 +1,79 @@ +[GNSS-SDR] + +;######### GLOBAL OPTIONS ################## +GNSS-SDR.internal_fs_sps=6625000 + +;######### SIGNAL_SOURCE CONFIG ############ +SignalSource.implementation=File_Signal_Source +SignalSource.filename=/archive/NT1065_GLONASS_L1_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE +SignalSource.item_type=ibyte +SignalSource.sampling_frequency=6625000 +SignalSource.samples=0 +SignalSource.dump=false; +SignalSource.dump_filename=/archive/signal_glonass.bin + +;######### SIGNAL_CONDITIONER CONFIG ############ +SignalConditioner.implementation=Signal_Conditioner +DataTypeAdapter.implementation=Ibyte_To_Complex +InputFilter.implementation=Pass_Through +InputFilter.item_type=gr_complex +Resampler.implementation=Pass_Through +Resampler.item_type=gr_complex + +;######### CHANNELS GLOBAL CONFIG ############ +Channel.signal=1G +Channels.in_acquisition=1 +Channels_1G.count=5 + +;Channel0.satellite=24 ; k= +;Channel1.satellite=1 ; k=1 +;Channel2.satellite=2 ; k=-4 +;Channel3.satellite=20 ; k=-5 +;Channel4.satellite=21 ; k=4 + +;######### ACQUISITION GLOBAL CONFIG ############ +Acquisition_1G.implementation=GLONASS_L1_CA_PCPS_Acquisition +Acquisition_1G.item_type=gr_complex +Acquisition_1G.threshold=0.0 +Acquisition_1G.pfa=0.0001 +Acquisition_1G.if=0 +Acquisition_1G.doppler_max=10000 +Acquisition_1G.doppler_step=250 +Acquisition_1G.dump=false; +Acquisition_1G.dump_filename=/archive/glo_acquisition.dat +;Acquisition_1G.coherent_integration_time_ms=1 +;Acquisition_1G.max_dwells = 5 + +;######### TRACKING GLOBAL CONFIG ############ +Tracking_1G.implementation=GLONASS_L1_CA_DLL_PLL_Tracking +Tracking_1G.item_type=gr_complex +Tracking_1G.if=0 +Tracking_1G.early_late_space_chips=0.5 +Tracking_1G.pll_bw_hz=25.0; +Tracking_1G.dll_bw_hz=3.0; +Tracking_1G.dump=false; +Tracking_1G.dump_filename=/archive/glo_tracking_ch_ + +;######### TELEMETRY DECODER GPS CONFIG ############ +TelemetryDecoder_1G.implementation=GLONASS_L1_CA_Telemetry_Decoder + +;######### OBSERVABLES CONFIG ############ +Observables.implementation=Hybrid_Observables +Observables.dump=false; +Observables.dump_filename=/archive/glo_observables.dat + +;######### PVT CONFIG ############ +PVT.implementation=RTKLIB_PVT +PVT.positioning_mode=Single +PVT.output_rate_ms=100 +PVT.display_rate_ms=500 +PVT.trop_model=Saastamoinen +PVT.flag_rtcm_server=false +PVT.flag_rtcm_tty_port=false +PVT.rtcm_dump_devname=/dev/pts/1 +PVT.rtcm_tcp_port=2101 +PVT.rtcm_MT1019_rate_ms=5000 +PVT.rtcm_MT1045_rate_ms=5000 +PVT.rtcm_MT1097_rate_ms=1000 +PVT.rtcm_MT1077_rate_ms=1000 +PVT.rinex_version=3 diff --git a/conf/gnss-sdr_GLONASS_L1_CA_ibyte_coh_trk.conf b/conf/gnss-sdr_GLONASS_L1_CA_ibyte_coh_trk.conf new file mode 100644 index 000000000..0bdbe7739 --- /dev/null +++ b/conf/gnss-sdr_GLONASS_L1_CA_ibyte_coh_trk.conf @@ -0,0 +1,83 @@ +[GNSS-SDR] + +;######### GLOBAL OPTIONS ################## +GNSS-SDR.internal_fs_sps=6625000 + +;######### SIGNAL_SOURCE CONFIG ############ +SignalSource.implementation=File_Signal_Source +SignalSource.filename=/archive/NT1065_GLONASS_L1_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE +SignalSource.item_type=ibyte +SignalSource.sampling_frequency=6625000 +SignalSource.samples=0 +SignalSource.dump=false; +SignalSource.dump_filename=/archive/signal_glonass.bin + +;######### SIGNAL_CONDITIONER CONFIG ############ +SignalConditioner.implementation=Signal_Conditioner +DataTypeAdapter.implementation=Ibyte_To_Complex +InputFilter.implementation=Pass_Through +InputFilter.item_type=gr_complex +Resampler.implementation=Pass_Through +Resampler.item_type=gr_complex + +;######### CHANNELS GLOBAL CONFIG ############ +Channel.signal=1G +Channels.in_acquisition=2 +Channels_1G.count=8 + +;Channel0.satellite=24 ; k=2 +;Channel1.satellite=1 ; k=1 +;Channel2.satellite=2 ; k=-4 +;Channel3.satellite=20 ; k=-5 +;Channel4.satellite=21 ; k=4 + +;######### ACQUISITION GLOBAL CONFIG ############ +Acquisition_1G.implementation=GLONASS_L1_CA_PCPS_Acquisition +Acquisition_1G.item_type=gr_complex +Acquisition_1G.threshold=0.0 +Acquisition_1G.pfa=0.0001 +Acquisition_1G.if=0 +Acquisition_1G.doppler_max=10000 +Acquisition_1G.doppler_step=250 +Acquisition_1G.dump=false; +Acquisition_1G.dump_filename=/archive/glo_acquisition.dat +;Acquisition_1G.coherent_integration_time_ms=1 +;Acquisition_1G.max_dwells = 5 + +;######### TRACKING GLOBAL CONFIG ############ +Tracking_1G.implementation=GLONASS_L1_CA_DLL_PLL_C_Aid_Tracking +Tracking_1G.item_type=gr_complex +Tracking_1G.if=0 +Tracking_1G.early_late_space_chips=0.5 +Tracking_1G.pll_bw_hz=40.0; +Tracking_1G.dll_bw_hz=3.0; +Tracking_1G.pll_bw_narrow_hz = 25.0; +Tracking_1G.dll_bw_narrow_hz = 2.0; +Tracking_1G.extend_correlation_ms = 1; +Tracking_1G.dump=false; +Tracking_1G.dump_filename=/archive/glo_tracking_ch_ + + +;######### TELEMETRY DECODER GPS CONFIG ############ +TelemetryDecoder_1G.implementation=GLONASS_L1_CA_Telemetry_Decoder + +;######### OBSERVABLES CONFIG ############ +Observables.implementation=Hybrid_Observables +Observables.dump=false +Observables.dump_filename=/archive/glo_observables.dat + +;######### PVT CONFIG ############ +PVT.implementation=RTKLIB_PVT +PVT.positioning_mode=Single +PVT.output_rate_ms=100 +PVT.display_rate_ms=500 +PVT.trop_model=Saastamoinen +PVT.flag_rtcm_server=true +PVT.flag_rtcm_tty_port=false +PVT.rtcm_dump_devname=/dev/pts/1 +PVT.rtcm_tcp_port=2101 +PVT.rtcm_MT1019_rate_ms=5000 +PVT.rtcm_MT1045_rate_ms=5000 +PVT.rtcm_MT1097_rate_ms=1000 +PVT.rtcm_MT1077_rate_ms=1000 +PVT.rinex_version=2 diff --git a/conf/gnss-sdr_GPS_L1_CA_ibyte.conf b/conf/gnss-sdr_GPS_L1_CA_ibyte.conf new file mode 100644 index 000000000..8bef7d1c0 --- /dev/null +++ b/conf/gnss-sdr_GPS_L1_CA_ibyte.conf @@ -0,0 +1,91 @@ +[GNSS-SDR] + +;######### GLOBAL OPTIONS ################## +GNSS-SDR.internal_fs_sps=6625000 + +;######### SIGNAL_SOURCE CONFIG ############ +SignalSource.implementation=File_Signal_Source +SignalSource.filename=/archive/NT1065_L1_20160923_fs6625e6_if60e3_schar.bin ; <- PUT YOUR FILE HERE +SignalSource.item_type=ibyte +;SignalSource.samples=66250000 +SignalSource.samples=0 +SignalSource.dump=false; + +;######### SIGNAL_CONDITIONER CONFIG ############ +SignalConditioner.implementation=Signal_Conditioner +DataTypeAdapter.implementation=Ibyte_To_Complex +InputFilter.implementation=Freq_Xlating_Fir_Filter +InputFilter.item_type=gr_complex +InputFilter.output_item_type=gr_complex +InputFilter.taps_item_type=float +InputFilter.number_of_taps=5 +InputFilter.number_of_bands=2 +InputFilter.band1_begin=0.0 +InputFilter.band1_end=0.70 +InputFilter.band2_begin=0.80 +InputFilter.band2_end=1.0 +InputFilter.ampl1_begin=1.0 +InputFilter.ampl1_end=1.0 +InputFilter.ampl2_begin=0.0 +InputFilter.ampl2_end=0.0 +InputFilter.band1_error=1.0 +InputFilter.band2_error=1.0 +InputFilter.filter_type=bandpass +InputFilter.grid_density=16 +InputFilter.sampling_frequency=6625000 +InputFilter.IF=60000 +Resampler.implementation=Direct_Resampler +Resampler.sample_freq_in=6625000 +Resampler.sample_freq_out=6625000 +Resampler.item_type=gr_complex + +;######### CHANNELS GLOBAL CONFIG ############ +Channel.signal=1C +Channels.in_acquisition=1 +Channels_1C.count=6 + +;######### ACQUISITION GLOBAL CONFIG ############ +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +Acquisition_1C.item_type=gr_complex +Acquisition_1C.threshold=0.01 +;Acquisition_1C.pfa=0.00001 +Acquisition_1C.if=0 +Acquisition_1C.doppler_max=10000 +Acquisition_1C.doppler_step=250 +Acquisition_1C.dump=false; +Acquisition_1C.dump_filename=/archive/gps_acquisition.dat +;Acquisition_1C.coherent_integration_time_ms=10 + +;######### TRACKING GLOBAL CONFIG ############ +Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking +Tracking_1C.item_type=gr_complex +Tracking_1C.if=60000 +Tracking_1C.early_late_space_chips=0.5 +Tracking_1C.pll_bw_hz=25.0; +Tracking_1C.dll_bw_hz=3.0; +Tracking_1C.dump=false; +Tracking_1C.dump_filename=/archive/gps_tracking_ch_ + +;######### TELEMETRY DECODER GPS CONFIG ############ +TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder + +;######### OBSERVABLES CONFIG ############ +Observables.implementation=Hybrid_Observables +Observables.dump=true; +Observables.dump_filename=/archive/gps_observables.dat + +;######### PVT CONFIG ############ +PVT.implementation=RTKLIB_PVT +PVT.positioning_mode=PPP_Static +PVT.output_rate_ms=100 +PVT.display_rate_ms=500 +PVT.trop_model=Saastamoinen +PVT.flag_rtcm_server=true +PVT.flag_rtcm_tty_port=false +PVT.rtcm_dump_devname=/dev/pts/1 +PVT.rtcm_tcp_port=2101 +PVT.rtcm_MT1019_rate_ms=5000 +PVT.rtcm_MT1045_rate_ms=5000 +PVT.rtcm_MT1097_rate_ms=1000 +PVT.rtcm_MT1077_rate_ms=1000 +PVT.rinex_version=3 diff --git a/conf/gnss-sdr_GPS_L1_GN3S_realtime.conf b/conf/gnss-sdr_GPS_L1_GN3S_realtime.conf index e2c156cec..082a1b3f4 100644 --- a/conf/gnss-sdr_GPS_L1_GN3S_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_GN3S_realtime.conf @@ -10,7 +10,7 @@ GNSS-SDR.internal_fs_sps=2727933.33 ; 8183800/3 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation: ;#Notes for GN3S source: ; - The front-end sampling frequency is fixed to 8.1838 MSPS (8183800 Hz). ; - The baseband signal is shifted to an IF of 38400 Hz. It should be corrected with the signal conditioner block @@ -66,25 +66,25 @@ Channels.in_acquisition=1 Channel.signal=1C ;######### ACQUISITION GLOBAL CONFIG ############ -Acquisition_1C.dump=false -Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.item_type=gr_complex Acquisition_1C.if=0 Acquisition_1C.sampled_ms=1 -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.threshold=0.008 Acquisition_1C.doppler_max=10000 Acquisition_1C.doppler_step=500 +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking Tracking_1C.item_type=gr_complex Tracking_1C.if=0 -Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ Tracking_1C.pll_bw_hz=45.0; Tracking_1C.dll_bw_hz=2.0; Tracking_1C.order=3; +Tracking_1C.dump=false +Tracking_1C.dump_filename=../data/epl_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder diff --git a/conf/gnss-sdr_GPS_L1_SPIR.conf b/conf/gnss-sdr_GPS_L1_SPIR.conf index 0799f82c5..4df77678f 100644 --- a/conf/gnss-sdr_GPS_L1_SPIR.conf +++ b/conf/gnss-sdr_GPS_L1_SPIR.conf @@ -11,30 +11,18 @@ GNSS-SDR.internal_fs_sps=4000000 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=Spir_File_Signal_Source - ;#filename: path to file with the captured GNSS signal samples to be processed SignalSource.filename=/dtalogger/signals/spir/data/20Secs/20Secs_L1.dat ; <- PUT YOUR FILE HERE - ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource.item_type=int - -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=80000000 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 - -;#repeat: Repeat the processing file. Disable this option in this version +;#repeat: Repeat the processing file. 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 - - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false @@ -49,7 +37,7 @@ SignalSource.enable_throttle_control=false SignalConditioner.implementation=Signal_Conditioner ;######### DATA_TYPE_ADAPTER CONFIG ############ -;## Changes the type of input data. Please disable it in this version. +;## Changes the type of input data. ;#implementation: [Pass_Through] disables this block DataTypeAdapter.implementation=Pass_Through DataTypeAdapter.item_type=float @@ -74,12 +62,13 @@ InputFilter.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter.input_item_type=float -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -131,27 +120,22 @@ InputFilter.decimation_factor=20 ;######### RESAMPLER CONFIG ############ ;## Resamples the input data. - ;#implementation: Use [Pass_Through] or [Direct_Resampler] ;#[Pass_Through] disables this block ;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation ;Resampler.implementation=Direct_Resampler Resampler.implementation=Pass_Through - +;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Resampler.item_type=gr_complex +;#sample_freq_in: the sample frequency of the input signal +Resampler.sample_freq_in=80000000 +;#sample_freq_out: the desired sample frequency of the output signal +Resampler.sample_freq_out=4000000 ;#dump: Dump the resamplered data to a file. Resampler.dump=false ;#dump_filename: Log path and filename. Resampler.dump_filename=../data/resampler.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. -Resampler.item_type=gr_complex - -;#sample_freq_in: the sample frequency of the input signal -Resampler.sample_freq_in=80000000 - -;#sample_freq_out: the desired sample frequency of the output signal -Resampler.sample_freq_out=4000000 - ;######### CHANNELS GLOBAL CONFIG ############ ;#count: Number of available GPS satellite channels. @@ -189,19 +173,13 @@ Channel.signal=1C ;Channel3.satellite=19 ;######### ACQUISITION GLOBAL CONFIG ############ -_1C -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.sampled_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler ;#threshold: Acquisition threshold Acquisition_1C.threshold=0.005 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -214,95 +192,65 @@ Acquisition_1C.doppler_min=-10000 Acquisition_1C.doppler_step=500 ;#maximum dwells Acquisition_1C.max_dwells=5 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat -;######### ACQUISITION CHANNELS CONFIG ###### - -;######### ACQUISITION CH 0 CONFIG ############ - -;#repeat_satellite: Use only jointly with the satellite PRN ID option. The default value is false -;Acquisition0.repeat_satellite = true -;Acquisition1.repeat_satellite = true -;Acquisition2.repeat_satellite = true -;Acquisition3.repeat_satellite = true - -;#cboc: Only for [Galileo_E1_PCPS_Ambiguous_Acquisition]. This option allows you to choose between acquiring with CBOC signal [true] or sinboc(1,1) signal [false]. -;#Use only if GNSS-SDR.internal_fs_sps is greater than or equal to 6138000 -Acquisition0.cboc=false - - -;######### ACQUISITION CH 1 CONFIG ############ -Acquisition1.cboc=false ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=20.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1 +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=../data/epl_tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=20.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=2.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;#decimation factor -TelemetryDecoder_1C.decimation_factor=1; + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ -;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version. +;#implementation: Position Velocity and Time (PVT) implementation algorithm PVT.implementation=RTKLIB_PVT PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - -;#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] +;#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 1 ms) [ms] PVT.output_rate_ms=500 - ;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms. PVT.display_rate_ms=500 - ;# RINEX, KML, and NMEA output configuration - +;#nmea_dump_filename: NMEA log path and filename +PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; +;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) +PVT.flag_nmea_tty_port=true; +;#nmea_dump_devname: serial device descriptor for NMEA logging +PVT.nmea_dump_devname=/dev/pts/4 +;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] +PVT.dump=false ;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. PVT.dump_filename=./PVT -;#nmea_dump_filename: NMEA log path and filename -PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; -;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) -PVT.flag_nmea_tty_port=true; - -;#nmea_dump_devname: serial device descriptor for NMEA logging -PVT.nmea_dump_devname=/dev/pts/4 - - -;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] -PVT.dump=false diff --git a/conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf b/conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf index 094d1f1d8..aaef910d3 100644 --- a/conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf @@ -26,39 +26,28 @@ GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -; # implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +; # implementation: SignalSource.implementation=UHD_Signal_Source - ; # When left empty, the device discovery routines will search all vailable transports on the system (ethernet, usb...) SignalSource.device_address=192.168.40.2 ; <- PUT THE IP ADDRESS OF YOUR USRP HERE - -; # item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +; # item_type: Type and resolution for each of the signal samples. ;SignalSource.item_type=gr_complex SignalSource.item_type=cshort - -; # sampling_frequency: Original Signal sampling frequency in [Hz] +; # sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=4000000 - ; # freq: RF front-end center frequency in [Hz] SignalSource.freq=1575420000 - ; # gain: Front-end Gain in [dB] SignalSource.gain=40 - ; # subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0) SignalSource.subdevice=A:0 - ; # samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 - -; # repeat: Repeat the processing file. Disable this option in this version +; # repeat: Repeat the processing file. SignalSource.repeat=false - -; # dump: Dump the Signal source data to a file. Disable this option in this version +; # dump: Dump the Signal source data to a file. SignalSource.dump=false SignalSource.dump_filename=../data/signal_source.dat - - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false @@ -74,7 +63,7 @@ SignalConditioner.implementation=Signal_Conditioner ;SignalConditioner.implementation=Pass_Through ;######### DATA_TYPE_ADAPTER CONFIG ############ -;## Changes the type of input data. Please disable it in this version. +;## Changes the type of input data. ;#implementation: [Pass_Through] disables this block DataTypeAdapter.implementation=Pass_Through DataTypeAdapter.item_type=cshort @@ -92,20 +81,15 @@ InputFilter.implementation=Fir_Filter ;InputFilter.implementation=Freq_Xlating_Fir_Filter ;InputFilter.implementation=Pass_Through -;#dump: Dump the filtered data to a file. -InputFilter.dump=false - -;#dump_filename: Log path and filename. -InputFilter.dump_filename=../data/input_filter.dat - ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter.input_item_type=cshort -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -152,31 +136,31 @@ InputFilter.grid_density=16 InputFilter.sampling_frequency=4000000 InputFilter.IF=0 +;#dump: Dump the filtered data to a file. +InputFilter.dump=false + +;#dump_filename: Log path and filename. +InputFilter.dump_filename=../data/input_filter.dat ;######### RESAMPLER CONFIG ############ ;## Resamples the input data. - ;#implementation: Use [Pass_Through] or [Direct_Resampler] ;#[Pass_Through] disables this block ;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation ;Resampler.implementation=Direct_Resampler Resampler.implementation=Pass_Through - +;#item_type: Type and resolution for each of the signal samples. +Resampler.item_type=gr_complex +;#sample_freq_in: the sample frequency of the input signal +Resampler.sample_freq_in=4000000 +;#sample_freq_out: the desired sample frequency of the output signal +Resampler.sample_freq_out=4000000 ;#dump: Dump the resampled data to a file. Resampler.dump=false ;#dump_filename: Log path and filename. Resampler.dump_filename=../data/resampler.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. -Resampler.item_type=gr_complex - -;#sample_freq_in: the sample frequency of the input signal -Resampler.sample_freq_in=4000000 - -;#sample_freq_out: the desired sample frequency of the output signal -Resampler.sample_freq_out=4000000 - ;######### CHANNELS GLOBAL CONFIG ############ ;#count: Number of available GPS satellite channels. @@ -223,19 +207,13 @@ Channel.signal=1C ;######### ACQUISITION GLOBAL CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.coherent_integration_time_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold. It will be ignored if pfa is defined. Acquisition_1C.threshold=0.01 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -249,54 +227,42 @@ maximum test statistics. Only use with implementation: [GPS_L1_CA_PCPS_Acquisiti Acquisition_1C.bit_transition_flag=false ;#max_dwells: Maximum number of consecutive dwells to be processed. It will be ignored if bit_transition_flag=true Acquisition_1C.max_dwells=1 - - -;######### ACQUISITION CHANNELS CONFIG ###### -;#The following options are specific to each channel and overwrite the generic options +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking ;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=30.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=4.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; +;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] +Tracking_1C.early_late_space_chips=0.5; ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=./tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=30.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=4.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; - -;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] -Tracking_1C.early_late_space_chips=0.5; ;######### TELEMETRY DECODER GPS CONFIG ############ -;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;#decimation factor -TelemetryDecoder_1C.decimation_factor=1; + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat @@ -304,34 +270,24 @@ Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ ;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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 - ;# KML, GeoJSON, NMEA and RTCM output configuration - -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./PVT - ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; - ;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) PVT.flag_nmea_tty_port=false; - ;#nmea_dump_devname: serial device descriptor for NMEA logging PVT.nmea_dump_devname=/dev/pts/4 - PVT.flag_rtcm_server=true PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] PVT.dump=false +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_GPS_L1_USRP_realtime.conf b/conf/gnss-sdr_GPS_L1_USRP_realtime.conf index 64db841fa..72fa42adf 100644 --- a/conf/gnss-sdr_GPS_L1_USRP_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_USRP_realtime.conf @@ -25,39 +25,27 @@ GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=UHD_Signal_Source - ;#When left empty, the device discovery routines will search all available transports on the system (ethernet, usb...) ;SignalSource.device_address=192.168.40.2 ; <- PUT THE IP ADDRESS OF YOUR USRP HERE - -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +;#item_type: Type and resolution for each of the signal samples. SignalSource.item_type=gr_complex - -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=2000000 - ;#freq: RF front-end center frequency in [Hz] SignalSource.freq=1575420000 - ;#gain: Front-end Gain in [dB] SignalSource.gain=60 - ;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0) SignalSource.subdevice=A:0 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 - -;#repeat: Repeat the processing file. Disable this option in this version +;#repeat: Repeat the processing file. SignalSource.repeat=false - -;#dump: Dump the Signal source data to a file. Disable this option in this version +;#dump: Dump the Signal source data to a file. SignalSource.dump=false - SignalSource.dump_filename=../data/signal_source.dat - - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false @@ -89,20 +77,15 @@ DataTypeAdapter.implementation=Pass_Through ;InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.implementation=Pass_Through -;#dump: Dump the filtered data to a file. -InputFilter.dump=false - -;#dump_filename: Log path and filename. -InputFilter.dump_filename=../data/input_filter.dat - ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -149,31 +132,31 @@ InputFilter.grid_density=16 InputFilter.sampling_frequency=2000000 InputFilter.IF=0 +;#dump: Dump the filtered data to a file. +InputFilter.dump=false + +;#dump_filename: Log path and filename. +InputFilter.dump_filename=../data/input_filter.dat ;######### RESAMPLER CONFIG ############ ;## Resamples the input data. - ;#implementation: Use [Pass_Through] or [Direct_Resampler] ;#[Pass_Through] disables this block ;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation ;Resampler.implementation=Direct_Resampler Resampler.implementation=Pass_Through - +;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Resampler.item_type=gr_complex +;#sample_freq_in: the sample frequency of the input signal +Resampler.sample_freq_in=8000000 +;#sample_freq_out: the desired sample frequency of the output signal +Resampler.sample_freq_out=2000000 ;#dump: Dump the resamplered data to a file. Resampler.dump=false ;#dump_filename: Log path and filename. Resampler.dump_filename=../data/resampler.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. -Resampler.item_type=gr_complex - -;#sample_freq_in: the sample frequency of the input signal -Resampler.sample_freq_in=8000000 - -;#sample_freq_out: the desired sample frequency of the output signal -Resampler.sample_freq_out=2000000 - ;######### CHANNELS GLOBAL CONFIG ############ ;#count: Number of available GPS satellite channels. @@ -186,9 +169,11 @@ Channels.in_acquisition=1 ;#signal: ;# "1C" GPS L1 C/A -;# "2S" GPS L2 L2C (M) ;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL) +;# "1G" GLONASS L1 C/A +;# "2S" GPS L2 L2C (M) ;# "5X" GALILEO E5a I+Q +;# "L5" GPS L5 ;#if the option is disabled by default is assigned "1C" GPS L1 C/A Channel.signal=1C @@ -212,18 +197,13 @@ Channel.signal=1C ;######### ACQUISITION GLOBAL CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.coherent_integration_time_ms=1 -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold. It will be ignored if pfa is defined. Acquisition_1C.threshold=0.01 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -237,54 +217,43 @@ maximum test statistics. Only use with implementation: [GPS_L1_CA_PCPS_Acquisiti Acquisition_1C.bit_transition_flag=false ;#max_dwells: Maximum number of consecutive dwells to be processed. It will be ignored if bit_transition_flag=true Acquisition_1C.max_dwells=1 - - -;######### ACQUISITION CHANNELS CONFIG ###### -;#The following options are specific to each channel and overwrite the generic options +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking ;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=30.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=4.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; +;#early_late_space_chips: correlator early-late space [chips] +Tracking_1C.early_late_space_chips=0.5; ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=./tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=30.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=4.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; - -;#early_late_space_chips: correlator early-late space [chips] -Tracking_1C.early_late_space_chips=0.5; ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;#decimation factor -TelemetryDecoder_1C.decimation_factor=1; + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat @@ -292,35 +261,24 @@ Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ ;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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 - ;# KML, GeoJSON, NMEA and RTCM output configuration - -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./PVT - ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; - ;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) PVT.flag_nmea_tty_port=false; - ;#nmea_dump_devname: serial device descriptor for NMEA logging PVT.nmea_dump_devname=/dev/pts/4 - PVT.flag_rtcm_server=true PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - - ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] PVT.dump=false +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_GPS_L1_acq_QuickSync.conf b/conf/gnss-sdr_GPS_L1_acq_QuickSync.conf index 02fa2ff35..1cd08b216 100644 --- a/conf/gnss-sdr_GPS_L1_acq_QuickSync.conf +++ b/conf/gnss-sdr_GPS_L1_acq_QuickSync.conf @@ -11,36 +11,16 @@ GNSS-SDR.internal_fs_sps=4000000 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] or [Rtlsdr_Signal_Source] SignalSource.implementation=File_Signal_Source - ;#filename: path to file with the captured GNSS signal samples to be processed SignalSource.filename=/datalogger/signals/CTTC/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ; <- PUT YOUR FILE HERE - -;#item_type: Type and resolution for each of the signal samples. -;#Use gr_complex for 32 bits float I/Q or short for I/Q interleaved short integer. -;#If short is selected you should have to instantiate the Ishort_To_Complex data_type_adapter. - SignalSource.item_type=ishort - -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=4000000 - -;#freq: RF front-end center frequency in [Hz] -SignalSource.freq=1575420000 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 - -;#repeat: Repeat the processing file. Disable this option in this version +;#repeat: Repeat the processing file. 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 - - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false @@ -75,20 +55,15 @@ DataTypeAdapter.dump_filename=../data/data_type_adapter.dat ;InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.implementation=Pass_Through -;#dump: Dump the filtered data to a file. -InputFilter.dump=false - -;#dump_filename: Log path and filename. -InputFilter.dump_filename=../data/input_filter.dat - ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples InputFilter.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -136,6 +111,11 @@ InputFilter.grid_density=16 InputFilter.sampling_frequency=4000000 InputFilter.IF=0 +;#dump: Dump the filtered data to a file. +InputFilter.dump=false + +;#dump_filename: Log path and filename. +InputFilter.dump_filename=../data/input_filter.dat ;######### RESAMPLER CONFIG ############ @@ -146,21 +126,17 @@ InputFilter.IF=0 ;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation ;Resampler.implementation=Direct_Resampler Resampler.implementation=Pass_Through - +;#item_type: Type and resolution for each of the signal samples. +Resampler.item_type=gr_complex +;#sample_freq_in: the sample frequency of the input signal +Resampler.sample_freq_in=4000000 +;#sample_freq_out: the desired sample frequency of the output signal +Resampler.sample_freq_out=4000000 ;#dump: Dump the resamplered data to a file. Resampler.dump=false ;#dump_filename: Log path and filename. Resampler.dump_filename=../data/resampler.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. -Resampler.item_type=gr_complex - -;#sample_freq_in: the sample frequency of the input signal -Resampler.sample_freq_in=4000000 - -;#sample_freq_out: the desired sample frequency of the output signal -Resampler.sample_freq_out=4000000 - ;######### CHANNELS GLOBAL CONFIG ############ ;#count: Number of available satellite channels. @@ -195,22 +171,20 @@ Channel4.satellite=32 Channel4.repeat_satellite=false ;######### ACQUISITION GLOBAL CONFIG ############_1C - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=true -;#filename: Log path and filename -;Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_QuickSync_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.coherent-integration_time_ms=4 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=true +;#filename: Log path and filename +;Acquisition_1C.dump_filename=./acq_dump.dat -Acquisition_1C.implementation=GPS_L1_CA_PCPS_QuickSync_Acquisition ;######### ACQUISITION CHANNELS CONFIG ###### -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] Acquisition_1C.implementation=GPS_L1_CA_PCPS_QuickSync_Acquisition ;#threshold: Acquisition threshold Acquisition_1C.threshold=0.4 @@ -222,45 +196,36 @@ Acquisition_1C.doppler_step=250 ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=50.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=4.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; +;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] +Tracking_1C.early_late_space_chips=0.5 ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=./tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=50.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=4.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; - -;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] -Tracking_1C.early_late_space_chips=0.5; ;######### TELEMETRY DECODER CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A. TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat @@ -268,26 +233,20 @@ Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ ;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - -;#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] +;#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 1 ms) [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 - -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./PVT - PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea PVT.flag_nmea_tty_port=true PVT.nmea_dump_devname=/dev/pts/4 PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 +;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] +PVT.dump=false +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf b/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf index 6c8d8d85c..67fe037f8 100644 --- a/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf @@ -86,18 +86,18 @@ Channel.signal=1C ;######### ACQUISITION GLOBAL CONFIG ############ -Acquisition_1C.dump=false -Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler Acquisition_1C.item_type=gr_complex Acquisition_1C.if=0 Acquisition_1C.sampled_ms=1 -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler Acquisition_1C.threshold=0.015 ;Acquisition_1C.pfa=0.0001 Acquisition_1C.doppler_max=10000 Acquisition_1C.doppler_min=-10000 Acquisition_1C.doppler_step=500 Acquisition_1C.max_dwells=15 +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ @@ -111,11 +111,13 @@ Tracking_1C.dll_bw_hz=2.0; Tracking_1C.order=3; Tracking_1C.early_late_space_chips=0.5; + ;######### TELEMETRY DECODER GPS CONFIG ############ TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false TelemetryDecoder_1C.decimation_factor=1; + ;######### OBSERVABLES CONFIG ############ Observables.implementation=Hybrid_Observables Observables.dump=false diff --git a/conf/gnss-sdr_GPS_L1_gr_complex.conf b/conf/gnss-sdr_GPS_L1_gr_complex.conf index 662d42b12..99118a0c4 100644 --- a/conf/gnss-sdr_GPS_L1_gr_complex.conf +++ b/conf/gnss-sdr_GPS_L1_gr_complex.conf @@ -14,11 +14,8 @@ SignalSource.implementation=File_Signal_Source SignalSource.filename=/home/javier/gnss/gnss-simulator/build/signal_out.bin ; <- PUT YOUR FILE HERE SignalSource.item_type=byte SignalSource.sampling_frequency=2600000 -SignalSource.freq=1575420000 SignalSource.samples=0 SignalSource.repeat=false -SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat SignalSource.enable_throttle_control=false @@ -26,45 +23,56 @@ SignalSource.enable_throttle_control=false SignalConditioner.implementation=Signal_Conditioner ;######### DATA_TYPE_ADAPTER CONFIG ############ -;## Changes the type of input data. Please disable it in this version. +;## Changes the type of input data. ;#implementation: [Pass_Through] disables this block DataTypeAdapter.implementation=Ibyte_To_Complex DataTypeAdapter.dump=false ;#dump_filename: Log path and filename. DataTypeAdapter.dump_filename=../data/DataTypeAdapter.dat +InputFilter.implementation=Pass_Through +InputFilter.input_item_type=gr_complex +InputFilter.output_item_type=gr_complex + +Resampler.implementation=Pass_Through +Resampler.item_type=gr_complex + + ;######### CHANNELS GLOBAL CONFIG ############ -Channels_1C.count=8 +Channels_1C.count=5 Channels.in_acquisition=1 Channel.signal=1C ;######### ACQUISITION GLOBAL CONFIG ############ -Acquisition_1C.dump=false -Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.item_type=gr_complex Acquisition_1C.if=0 Acquisition_1C.sampled_ms=1 -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.threshold=0.05 ;Acquisition_1C.pfa=0.01 Acquisition_1C.doppler_max=10000 Acquisition_1C.doppler_step=250 +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat + ;######### TRACKING GLOBAL CONFIG ############ Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_C_Aid_Tracking Tracking_1C.item_type=gr_complex Tracking_1C.if=0 -Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ Tracking_1C.pll_bw_hz=25.0; Tracking_1C.dll_bw_hz=1.0; Tracking_1C.order=3; +Tracking_1C.dump=false +Tracking_1C.dump_filename=../data/epl_tracking_c + ;######### TELEMETRY DECODER GPS CONFIG ############ TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false + ;######### OBSERVABLES CONFIG ############ Observables.implementation=Hybrid_Observables Observables.dump=false diff --git a/conf/gnss-sdr_GPS_L1_gr_complex_gpu.conf b/conf/gnss-sdr_GPS_L1_gr_complex_gpu.conf index e7e8f4e62..0111fc5e9 100644 --- a/conf/gnss-sdr_GPS_L1_gr_complex_gpu.conf +++ b/conf/gnss-sdr_GPS_L1_gr_complex_gpu.conf @@ -13,8 +13,6 @@ GNSS-SDR.internal_fs_sps=4000000 SignalSource.implementation=File_Signal_Source SignalSource.filename=/datalogger/signals/Agilent/New York/4msps.dat ; <- PUT YOUR FILE HERE SignalSource.item_type=gr_complex -SignalSource.sampling_frequency=4000000 -SignalSource.freq=1575420000 SignalSource.samples=250000000 SignalSource.repeat=false SignalSource.dump=false @@ -33,16 +31,17 @@ Channel.signal=1C ;######### ACQUISITION GLOBAL CONFIG ############ -Acquisition_1C.dump=false -Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.item_type=gr_complex Acquisition_1C.if=0 Acquisition_1C.sampled_ms=1 -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.threshold=0.005 ;Acquisition_1C.pfa=0.01 Acquisition_1C.doppler_max=10000 Acquisition_1C.doppler_step=500 +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat + ;######### TRACKING GLOBAL CONFIG ############ Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking_GPU @@ -54,10 +53,12 @@ Tracking_1C.pll_bw_hz=45.0; Tracking_1C.dll_bw_hz=2.0; Tracking_1C.order=3; + ;######### TELEMETRY DECODER GPS CONFIG ############ TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false + ;######### OBSERVABLES CONFIG ############ Observables.implementation=Hybrid_Observables Observables.dump=false diff --git a/conf/gnss-sdr_GPS_L1_ishort.conf b/conf/gnss-sdr_GPS_L1_ishort.conf index a5cce5189..e3395c982 100644 --- a/conf/gnss-sdr_GPS_L1_ishort.conf +++ b/conf/gnss-sdr_GPS_L1_ishort.conf @@ -13,10 +13,9 @@ ControlThread.wait_for_flowgraph=false ;######### SIGNAL_SOURCE CONFIG ############ SignalSource.implementation=File_Signal_Source -SignalSource.filename=/Users/carlesfernandez/Documents/workspace/code2/trunk/data/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ;/datalogger/signals/CTTC/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ; <- PUT YOUR FILE HERE +SignalSource.filename=/archive/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ;/datalogger/signals/CTTC/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ; <- PUT YOUR FILE HERE SignalSource.item_type=ishort SignalSource.sampling_frequency=4000000 -SignalSource.freq=1575420000 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false @@ -45,16 +44,13 @@ Resampler.item_type=cshort Channels_1C.count=8 Channels.in_acquisition=1 Channel.signal=1C -;Channel.item_type=cshort ;######### ACQUISITION GLOBAL CONFIG ############ -Acquisition_1C.dump=false -Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.item_type=cshort Acquisition_1C.if=0 Acquisition_1C.sampled_ms=1 -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.threshold=0.008 ;Acquisition_1C.pfa=0.000001 Acquisition_1C.doppler_max=10000 @@ -62,6 +58,9 @@ Acquisition_1C.doppler_step=250 Acquisition_1C.tong_init_val=2 Acquisition_1C.tong_max_val=10 Acquisition_1C.tong_max_dwells=20 +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat + ;######### TRACKING GLOBAL CONFIG ############ Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_C_Aid_Tracking @@ -73,11 +72,13 @@ Tracking_1C.pll_bw_hz=40.0; Tracking_1C.dll_bw_hz=4.0; Tracking_1C.order=3; + ;######### TELEMETRY DECODER GPS CONFIG ############ TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false TelemetryDecoder_1C.decimation_factor=1; + ;######### OBSERVABLES CONFIG ############ Observables.implementation=Hybrid_Observables Observables.dump=false diff --git a/conf/gnss-sdr_GPS_L1_nsr.conf b/conf/gnss-sdr_GPS_L1_nsr.conf index 078f8e690..ec085add3 100644 --- a/conf/gnss-sdr_GPS_L1_nsr.conf +++ b/conf/gnss-sdr_GPS_L1_nsr.conf @@ -31,7 +31,6 @@ SignalSource.implementation=Nsr_File_Signal_Source SignalSource.filename=/home/javier/Descargas/RoofTop_FE0_Band1.stream ; <- PUT YOUR FILE HERE SignalSource.item_type=byte SignalSource.sampling_frequency=20480000 -SignalSource.freq=1575420000 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false @@ -89,71 +88,69 @@ Channels.in_acquisition=1 ;######### GPS ACQUISITION CONFIG ############ -Acquisition_1C.dump=false -Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.item_type=gr_complex Acquisition_1C.if=0 Acquisition_1C.sampled_ms=1 -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.threshold=0.0075 ;Acquisition_1C.pfa=0.01 Acquisition_1C.doppler_max=10000 Acquisition_1C.doppler_step=500 +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat -Acquisition_2S.dump=false -Acquisition_2S.dump_filename=./acq_dump.dat +Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition Acquisition_2S.item_type=gr_complex Acquisition_2S.if=0 Acquisition_2S.coherent_integration_time_ms=20 -Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition Acquisition_2S.threshold=0.00045 Acquisition_2S.doppler_max=5000 Acquisition_2S.doppler_step=100 Acquisition_2S.bit_transition_flag=false Acquisition_2S.max_dwells=1 +Acquisition_2S.dump=false +Acquisition_2S.dump_filename=./acq_dump.dat ;######### TRACKING GPS CONFIG ############ Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking Tracking_1C.item_type=gr_complex Tracking_1C.if=0 -Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ Tracking_1C.pll_bw_hz=45.0; Tracking_1C.dll_bw_hz=2.0; Tracking_1C.order=3; +Tracking_1C.dump=false +Tracking_1C.dump_filename=../data/epl_tracking_ch_ ;######### GPS L2C GENERIC TRACKING CONFIG ############ Tracking_2S.implementation=GPS_L2_M_DLL_PLL_Tracking Tracking_2S.item_type=gr_complex Tracking_2S.if=0 -Tracking_2S.dump=true -Tracking_2S.dump_filename=../data/epl_tracking_ch_ Tracking_2S.pll_bw_hz=1.5; Tracking_2S.dll_bw_hz=0.4; Tracking_2S.order=2; Tracking_2S.early_late_space_chips=0.5; +Tracking_2S.dump=true +Tracking_2S.dump_filename=../data/epl_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -TelemetryDecoder_1C.decimation_factor=1; TelemetryDecoder_2S.implementation=GPS_L2C_Telemetry_Decoder TelemetryDecoder_2S.dump=false -TelemetryDecoder_2S.decimation_factor=1; + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat + ;######### PVT CONFIG ############ PVT.implementation=RTKLIB_PVT PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic diff --git a/conf/gnss-sdr_GPS_L1_nsr_twobit_packed.conf b/conf/gnss-sdr_GPS_L1_nsr_twobit_packed.conf index f3bac7589..db5e6d23a 100644 --- a/conf/gnss-sdr_GPS_L1_nsr_twobit_packed.conf +++ b/conf/gnss-sdr_GPS_L1_nsr_twobit_packed.conf @@ -46,7 +46,6 @@ SignalSource.big_endian_bytes=false ; This setting specifies which of the three cases holds for this data file SignalSource.sample_type=real SignalSource.sampling_frequency=20480000 -SignalSource.freq=1575420000 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false @@ -102,37 +101,40 @@ Channel.signal=1C ;######### GPS ACQUISITION CONFIG ############ -Acquisition_1C.dump=false -Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.item_type=gr_complex Acquisition_1C.if=0 Acquisition_1C.sampled_ms=1 -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.threshold=0.0075 ;Acquisition_1C.pfa=0.01 Acquisition_1C.doppler_max=10000 Acquisition_1C.doppler_step=500 +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GPS CONFIG ############ Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking Tracking_1C.item_type=gr_complex Tracking_1C.if=0 -Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ Tracking_1C.pll_bw_hz=45.0; Tracking_1C.dll_bw_hz=2.0; Tracking_1C.order=3; +Tracking_1C.dump=false +Tracking_1C.dump_filename=../data/epl_tracking_ch_ + ;######### TELEMETRY DECODER GPS CONFIG ############ TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false + ;######### OBSERVABLES CONFIG ############ Observables.implementation=Hybrid_Observables Observables.dump=false Observables.dump_filename=./observables.dat + ;######### PVT CONFIG ############ PVT.implementation=RTKLIB_PVT PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic diff --git a/conf/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf b/conf/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf index 2ce06d573..8cd02bd32 100644 --- a/conf/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf +++ b/conf/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf @@ -25,42 +25,21 @@ GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=File_Signal_Source - -;#When left empty, the device discovery routines will search all vailable transports on the system (ethernet, usb...) -SignalSource.device_address=192.168.50.2 - ;#filename: path to file with the captured GNSS signal samples to be processed SignalSource.filename=/home/javier/signals/signal_source_int.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] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=2000000 - -;#freq: RF front-end center frequency in [Hz] -SignalSource.freq=1575420000 - -;#gain: Front-end Gain in [dB] -SignalSource.gain=40 - -;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0) -SignalSource.subdevice=A:0 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 - ;#repeat: Repeat the processing file. Disable this option in this version SignalSource.repeat=false - ;#dump: Dump the Signal source data to a file. Disable this option in this version SignalSource.dump=false - SignalSource.dump_filename=dump.dat - - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false @@ -100,12 +79,10 @@ Channel.signal=1C ;######### ACQUISITION GLOBAL CONFIG ############ -Acquisition_1C.dump=false -Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.item_type=gr_complex Acquisition_1C.if=0 Acquisition_1C.sampled_ms=1 -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#use_CFAR_algorithm: If enabled, acquisition estimates the input signal power to implement CFAR detection algorithms ;#notice that this affects the Acquisition threshold range! Acquisition_1C.use_CFAR_algorithm=false; @@ -114,50 +91,41 @@ Acquisition_1C.threshold=20 ;Acquisition_1C.pfa=0.01 Acquisition_1C.doppler_max=5000 Acquisition_1C.doppler_step=250 +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GPS CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_C_Aid_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1C.dump=true - -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1C.dump_filename=../data/epl_tracking_ch_ - ;# Extended correlation after telemetry bit synchronization ;# Valid values are: [1,2,4,5,10,20] (integer divisors of the GPS L1 CA bit period (20 ms) ) ;# Longer integration period require more stable front-end LO - Tracking_1C.extend_correlation_ms=10 - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1C.pll_bw_hz=35; Tracking_1C.pll_bw_narrow_hz=30; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1C.dll_bw_hz=2.0; - Tracking_1C.dll_bw_narrow_hz=1.5; - ;#fll_bw_hz: FLL loop filter bandwidth [Hz] Tracking_1C.fll_bw_hz=2.0; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_1C.order=3; +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1C.dump=true +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1C.dump_filename=../data/epl_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false + ;######### OBSERVABLES CONFIG ############ Observables.implementation=Hybrid_Observables Observables.dump=true diff --git a/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf b/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf index 468c44de7..944a1ba36 100644 --- a/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf @@ -27,44 +27,31 @@ GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] [Osmosdr_Signal_Source] +;#implementation SignalSource.implementation=RtlTcp_Signal_Source - ;#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] +;#sampling_frequency: Original Signal sampling frequency in samples per second ;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE ; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ SignalSource.sampling_frequency=1200000 - ;#freq: RF front-end center frequency in [Hz] SignalSource.freq=1575420000 - ;#gain: Front-end overall gain Gain in [dB] SignalSource.gain=40 - ;#rf_gain: Front-end RF stage gain in [dB] SignalSource.rf_gain=40 - ;#rf_gain: Front-end IF stage gain in [dB] SignalSource.if_gain=30 - ;#AGC_enabled: Front-end AGC enabled or disabled SignalSource.AGC_enabled = false - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 - ;#repeat: Repeat the processing file. Disable this option in this version 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 - - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false @@ -78,6 +65,7 @@ SignalSource.port=1234 ;# Set to true if I/Q samples come swapped SignalSource.swap_iq=false + ;######### SIGNAL_CONDITIONER CONFIG ############ ;## It holds blocks to change data type, filter and resample input data. @@ -87,7 +75,7 @@ SignalSource.swap_iq=false SignalConditioner.implementation=Signal_Conditioner ;######### DATA_TYPE_ADAPTER CONFIG ############ -;## Changes the type of input data. Please disable it in this version. +;## Changes the type of input data. ;#implementation: [Pass_Through] disables this block DataTypeAdapter.implementation=Pass_Through @@ -109,12 +97,13 @@ InputFilter.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -163,6 +152,7 @@ InputFilter.sampling_frequency=1200000 ;# IF deviation due to front-end LO inaccuracies [HZ] InputFilter.IF=80558 + ;######### RESAMPLER CONFIG ############ ;## Resamples the input data. ;# DISABLED IN THE RTL-SDR REALTIME @@ -170,6 +160,7 @@ InputFilter.IF=80558 ;#[Pass_Through] disables this block Resampler.implementation=Pass_Through + ;######### CHANNELS GLOBAL CONFIG ############ ;#count: Number of available GPS satellite channels. Channels_1C.count=4 @@ -180,19 +171,14 @@ Channel.signal=1C ;######### ACQUISITION GLOBAL CONFIG ############ - +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler ;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.sampled_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler ;#threshold: Acquisition threshold Acquisition_1C.threshold=0.015 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -205,50 +191,42 @@ Acquisition_1C.doppler_min=-10000 Acquisition_1C.doppler_step=500 ;#maximum dwells Acquisition_1C.max_dwells=15 +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] [GPS_L1_CA_DLL_PLL_Optim_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking ;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=40.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=2.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; +;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] +Tracking_1C.early_late_space_chips=0.5; ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=./tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=40.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=2.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; - -;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] -Tracking_1C.early_late_space_chips=0.5; ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;#decimation factor -TelemetryDecoder_1C.decimation_factor=1; + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat @@ -259,31 +237,21 @@ PVT.implementation=RTKLIB_PVT PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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 - ;# KML, GeoJSON, NMEA and RTCM output configuration - -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./PVT - ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; - ;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) PVT.flag_nmea_tty_port=false; - ;#nmea_dump_devname: serial device descriptor for NMEA logging PVT.nmea_dump_devname=/dev/pts/4 - PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - - ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] PVT.dump=true +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf b/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf index 2c10ea684..b4e025f6f 100644 --- a/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf @@ -101,18 +101,18 @@ Channel.signal=1C ;######### ACQUISITION GLOBAL CONFIG ############ -Acquisition_1C.dump=false -Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler Acquisition_1C.item_type=gr_complex Acquisition_1C.if=0 Acquisition_1C.sampled_ms=1 -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler Acquisition_1C.threshold=0.015 ;Acquisition_1C.pfa=0.0001 Acquisition_1C.doppler_max=10000 Acquisition_1C.doppler_min=-10000 Acquisition_1C.doppler_step=500 Acquisition_1C.max_dwells=15 +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ @@ -126,10 +126,11 @@ Tracking_1C.dll_bw_hz=2.0; Tracking_1C.order=3; Tracking_1C.early_late_space_chips=0.5; + ;######### TELEMETRY DECODER GPS CONFIG ############ TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -TelemetryDecoder_1C.decimation_factor=1; + ;######### OBSERVABLES CONFIG ############ Observables.implementation=Hybrid_Observables diff --git a/conf/gnss-sdr_GPS_L1_two_bits_cpx.conf b/conf/gnss-sdr_GPS_L1_two_bits_cpx.conf index a720b859b..f6e2ec730 100644 --- a/conf/gnss-sdr_GPS_L1_two_bits_cpx.conf +++ b/conf/gnss-sdr_GPS_L1_two_bits_cpx.conf @@ -28,7 +28,6 @@ SignalSource.implementation=Two_Bit_Cpx_File_Signal_Source SignalSource.filename=/datalogger/captures/ajith/test1_two_cpx_live.dat ; <- PUT YOUR FILE HERE SignalSource.item_type=byte SignalSource.sampling_frequency=19200000 -SignalSource.freq=1575420000 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false @@ -45,8 +44,6 @@ DataTypeAdapter.item_type=gr_complex ;######### INPUT_FILTER CONFIG ############ InputFilter.implementation=Freq_Xlating_Fir_Filter -InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat InputFilter.input_item_type=gr_complex InputFilter.output_item_type=gr_complex InputFilter.taps_item_type=float @@ -67,6 +64,9 @@ InputFilter.grid_density=16 InputFilter.sampling_frequency=19200000 InputFilter.IF=4024000 InputFilter.decimation_factor=6 +InputFilter.dump=false +InputFilter.dump_filename=../data/input_filter.dat + ;######### RESAMPLER CONFIG ############ Resampler.implementation=Pass_Through @@ -82,35 +82,35 @@ Channel.signal=1C ;######### GPS ACQUISITION CONFIG ############ -Acquisition_1C.dump=false -Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler Acquisition_1C.item_type=gr_complex Acquisition_1C.if=0 Acquisition_1C.sampled_ms=1 -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler Acquisition_1C.threshold=0.007 ;Acquisition_1C.pfa=0.0001 Acquisition_1C.doppler_max=10000 Acquisition_1C.doppler_min=-10000 Acquisition_1C.doppler_step=500 Acquisition_1C.max_dwells=15 +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GPS CONFIG ############ Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking Tracking_1C.item_type=gr_complex -Tracking_1C.if=0 -Tracking_1C.dump=true -Tracking_1C.dump_filename=./tracking_ch_ +Tracking_1C.if=0_ Tracking_1C.pll_bw_hz=40.0; Tracking_1C.dll_bw_hz=1.5; Tracking_1C.order=3; +Tracking_1C.dump=true +Tracking_1C.dump_filename=./tracking_ch ;######### TELEMETRY DECODER GPS CONFIG ############ TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -TelemetryDecoder_1C.decimation_factor=1; + ;######### OBSERVABLES CONFIG ############ Observables.implementation=Hybrid_Observables diff --git a/conf/gnss-sdr_GPS_L2C_USRP1_realtime.conf b/conf/gnss-sdr_GPS_L2C_USRP1_realtime.conf index 5c800efad..97710c4f0 100644 --- a/conf/gnss-sdr_GPS_L2C_USRP1_realtime.conf +++ b/conf/gnss-sdr_GPS_L2C_USRP1_realtime.conf @@ -55,21 +55,18 @@ DataTypeAdapter.item_type=gr_complex InputFilter.implementation=Freq_Xlating_Fir_Filter -;#dump: Dump the filtered data to a file. -InputFilter.dump=false - -;#dump_filename: Log path and filename. InputFilter.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, -;#the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. + +;#input_item_type: Type and resolution for input signal samples. InputFilter.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -120,6 +117,12 @@ InputFilter.IF=-1600000 ;# Decimation factor after the frequency tranaslating block InputFilter.decimation_factor=1 +;#dump: Dump the filtered data to a file. +InputFilter.dump=false + +;#dump_filename: Log path and filename. + + ;######### RESAMPLER CONFIG ############ Resampler.implementation=Pass_Through Resampler.dump=false @@ -151,41 +154,44 @@ Channel7.signal=2S ;Channel11.signal=2S - ;######### ACQUISITION GLOBAL CONFIG ############ - ;# GPS L2C M -Acquisition_2S.dump=false -Acquisition_2S.dump_filename=./acq_dump.dat +Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition Acquisition_2S.item_type=gr_complex Acquisition_2S.if=0 -Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition Acquisition_2S.threshold=0.0013 ;Acquisition_2S.pfa=0.001 Acquisition_2S.doppler_max=10000 Acquisition_2S.doppler_min=-10000 Acquisition_2S.doppler_step=100 Acquisition_2S.max_dwells=1 +Acquisition_2S.dump=false +Acquisition_2S.dump_filename=./acq_dump.dat + +;######### TRACKING GLOBAL CONFIG ############ Tracking_2S.implementation=GPS_L2_M_DLL_PLL_Tracking Tracking_2S.item_type=gr_complex Tracking_2S.if=0 -Tracking_2S.dump=true -Tracking_2S.dump_filename=./tracking_ch_ Tracking_2S.pll_bw_hz=1.5; Tracking_2S.dll_bw_hz=0.3; Tracking_2S.order=3; Tracking_2S.early_late_space_chips=0.5; +Tracking_2S.dump=true +Tracking_2S.dump_filename=./tracking_ch_ + ;######### TELEMETRY DECODER GPS CONFIG ############ TelemetryDecoder_2S.implementation=GPS_L2C_Telemetry_Decoder TelemetryDecoder_2S.dump=false + ;######### OBSERVABLES CONFIG ############. Observables.implementation=Hybrid_Observables Observables.dump=false Observables.dump_filename=./observables.dat + ;######### PVT CONFIG ############ PVT.implementation=RTKLIB_PVT PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic diff --git a/conf/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf b/conf/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf index 263f7cce2..caaf4536c 100644 --- a/conf/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf +++ b/conf/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf @@ -50,8 +50,6 @@ DataTypeAdapter.item_type=cshort ;######### INPUT_FILTER CONFIG ############ InputFilter.implementation=Fir_Filter -InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat InputFilter.input_item_type=cshort InputFilter.output_item_type=gr_complex InputFilter.taps_item_type=float @@ -76,6 +74,9 @@ InputFilter.grid_density=16 InputFilter.sampling_frequency=4000000 InputFilter.IF=0 +InputFilter.dump=false +InputFilter.dump_filename=../data/input_filter.dat + ;######### RESAMPLER CONFIG ############ Resampler.implementation=Pass_Through Resampler.dump=false @@ -106,42 +107,44 @@ Channel7.signal=2S ;Channel10.signal=2S ;Channel11.signal=2S - - ;######### ACQUISITION GLOBAL CONFIG ############ ;# GPS L2C M -Acquisition_2S.dump=false -Acquisition_2S.dump_filename=./acq_dump.dat +Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition Acquisition_2S.item_type=gr_complex Acquisition_2S.if=0 -Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition Acquisition_2S.threshold=0.0015 ;Acquisition_2S.pfa=0.001 Acquisition_2S.doppler_max=5000 Acquisition_2S.doppler_min=-5000 Acquisition_2S.doppler_step=60 Acquisition_2S.max_dwells=1 +Acquisition_2S.dump=false +Acquisition_2S.dump_filename=./acq_dump.dat + Tracking_2S.implementation=GPS_L2_M_DLL_PLL_Tracking Tracking_2S.item_type=gr_complex Tracking_2S.if=0 -Tracking_2S.dump=true -Tracking_2S.dump_filename=./tracking_ch_ Tracking_2S.pll_bw_hz=2.0; Tracking_2S.dll_bw_hz=0.25; Tracking_2S.order=2; Tracking_2S.early_late_space_chips=0.5; +Tracking_2S.dump=true +Tracking_2S.dump_filename=./tracking_ch_ + ;######### TELEMETRY DECODER GPS CONFIG ############ TelemetryDecoder_2S.implementation=GPS_L2C_Telemetry_Decoder TelemetryDecoder_2S.dump=true + ;######### OBSERVABLES CONFIG ############. Observables.implementation=Hybrid_Observables Observables.dump=false Observables.dump_filename=./observables.dat + ;######### PVT CONFIG ############ PVT.implementation=RTKLIB_PVT PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic @@ -149,7 +152,6 @@ PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad PVT.output_rate_ms=100 PVT.display_rate_ms=500 -PVT.dump_filename=./PVT PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; PVT.flag_nmea_tty_port=false; PVT.nmea_dump_devname=/dev/pts/4 @@ -157,3 +159,4 @@ PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 PVT.dump=false +PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_Galileo_E1_USRP_X300_realtime.conf b/conf/gnss-sdr_Galileo_E1_USRP_X300_realtime.conf index 6d82ad1e9..54e092708 100644 --- a/conf/gnss-sdr_Galileo_E1_USRP_X300_realtime.conf +++ b/conf/gnss-sdr_Galileo_E1_USRP_X300_realtime.conf @@ -24,48 +24,55 @@ SignalSource.dump=false SignalSource.dump_filename=../data/signal_source.dat SignalSource.enable_throttle_control=false + ;######### SIGNAL_CONDITIONER CONFIG ############ SignalConditioner.implementation=Pass_Through + ;######### CHANNELS GLOBAL CONFIG ###### Channels_1B.count=4 Channels.in_acquisition=1 Channel.signal=1B + ;######### ACQUISITION GLOBAL CONFIG ############ -Acquisition_1B.dump=false -Acquisition_1B.dump_filename=./acq_dump.dat +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition Acquisition_1B.item_type=gr_complex Acquisition_1B.if=0 Acquisition_1B.sampled_ms=4 -Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition ;Acquisition_1B.threshold=1 Acquisition_1B.pfa=0.000008 Acquisition_1B.doppler_max=6000 Acquisition_1B.doppler_step=250 Acquisition_1B.cboc=false +Acquisition_1B.dump=false +Acquisition_1B.dump_filename=./acq_dump.dat + ;######### TRACKING GLOBAL CONFIG ############ Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking Tracking_1B.item_type=gr_complex Tracking_1B.if=0 -Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ Tracking_1B.pll_bw_hz=20.0; Tracking_1B.dll_bw_hz=2.0; Tracking_1B.order=3; Tracking_1B.early_late_space_chips=0.15; Tracking_1B.very_early_late_space_chips=0.6; +Tracking_1B.dump=false +Tracking_1B.dump_filename=../data/veml_tracking_ch_ + ;######### TELEMETRY DECODER CONFIG ############ TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder TelemetryDecoder_1B.dump=false + ;######### OBSERVABLES CONFIG ############ Observables.implementation=Hybrid_Observables Observables.dump=false Observables.dump_filename=./observables.dat + ;######### PVT CONFIG ############ PVT.implementation=RTKLIB_PVT PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic @@ -73,11 +80,11 @@ PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad PVT.output_rate_ms=100; PVT.display_rate_ms=500; -PVT.dump=false -PVT.dump_filename=./PVT PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea PVT.flag_nmea_tty_port=true PVT.nmea_dump_devname=/dev/pts/4 PVT.flag_rtcm_server=true PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 +PVT.dump=false +PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_Galileo_E1_acq_QuickSync.conf b/conf/gnss-sdr_Galileo_E1_acq_QuickSync.conf index 52df58dc9..ab6802559 100644 --- a/conf/gnss-sdr_Galileo_E1_acq_QuickSync.conf +++ b/conf/gnss-sdr_Galileo_E1_acq_QuickSync.conf @@ -10,7 +10,7 @@ GNSS-SDR.internal_fs_sps=4000000 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] or [Rtlsdr_Signal_Source] +;#implementation: SignalSource.implementation=File_Signal_Source ;#filename: path to file with the captured GNSS signal samples to be processed @@ -21,22 +21,15 @@ SignalSource.filename=/datalogger/signals/CTTC/2013_04_04_GNSS_SIGNAL_at_CTTC_SP ;#If ishort is selected you should have to instantiate the Ishort_To_Complex data_type_adapter. SignalSource.item_type=ishort -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=4000000 -;#freq: RF front-end center frequency in [Hz] -SignalSource.freq=1575420000 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 -;#repeat: Repeat the processing file. Disable this option in this version +;#repeat: Repeat the processing file. 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 - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false @@ -71,20 +64,15 @@ DataTypeAdapter.dump_filename=../data/data_type_adapter.dat ;InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.implementation=Pass_Through -;#dump: Dump the filtered data to a file. -InputFilter.dump=false - -;#dump_filename: Log path and filename. -InputFilter.dump_filename=../data/input_filter.dat - ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -116,7 +104,6 @@ InputFilter.band2_end=1.0 ;#ampl: desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...]. ;#The number of ampl_begin and ampl_end elements must match the number of bands - InputFilter.ampl1_begin=1.0 InputFilter.ampl1_end=1.0 InputFilter.ampl2_begin=0.0 @@ -136,10 +123,14 @@ InputFilter.grid_density=16 ;#The following options are used only in Freq_Xlating_Fir_Filter implementation. ;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz - InputFilter.sampling_frequency=4000000 InputFilter.IF=0 +;#dump: Dump the filtered data to a file. +InputFilter.dump=false + +;#dump_filename: Log path and filename. +InputFilter.dump_filename=../data/input_filter.dat ;######### RESAMPLER CONFIG ############ @@ -156,7 +147,7 @@ Resampler.dump=false ;#dump_filename: Log path and filename. Resampler.dump_filename=../data/resampler.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +;#item_type: Type and resolution for each of the signal samples. Resampler.item_type=gr_complex ;#sample_freq_in: the sample frequency of the input signal @@ -175,19 +166,13 @@ Channel.signal=1B ;######### ACQUISITION GLOBAL CONFIG ############ -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1B.dump=false -;#filename: Log path and filename -Acquisition_1B.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1B.implementation=Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1B.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1B.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1B.coherent_integration_time_ms=4 - -Acquisition_1B.implementation=Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition - ;#threshold: Acquisition threshold Acquisition_1B.threshold=0.05 ;#doppler_max: Maximum expected Doppler shift [Hz] @@ -196,39 +181,33 @@ Acquisition_1B.doppler_max=15000 Acquisition_1B.doppler_step=125 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms]; Acquisition_1B.coherent_integration_time_ms=8 - Acquisition_1B.cboc=false +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1B.dump=false +;#filename: Log path and filename +Acquisition_1B.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm [Galileo_E1_DLL_PLL_VEML_Tracking] +;#implementation: Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1B.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1B.if=0 - -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1B.dump=true - -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1B.dump_filename=../data/veml_tracking_ch_ - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1B.pll_bw_hz=20.0; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1B.dll_bw_hz=2.0; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_1B.order=3; - ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo Tracking_1B.early_late_space_chips=0.15; - ;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] Tracking_1B.very_early_late_space_chips=0.6; +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1B.dump=true +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1B.dump_filename=../data/veml_tracking_ch_ ;######### TELEMETRY DECODER CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A or [Galileo_E1B_Telemetry_Decoder] for Galileo E1B diff --git a/conf/gnss-sdr_Galileo_E1_ishort.conf b/conf/gnss-sdr_Galileo_E1_ishort.conf index 208571be0..2f051700a 100644 --- a/conf/gnss-sdr_Galileo_E1_ishort.conf +++ b/conf/gnss-sdr_Galileo_E1_ishort.conf @@ -10,32 +10,17 @@ GNSS-SDR.internal_fs_sps=4000000 ;######### SIGNAL_SOURCE CONFIG ############ -;#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=/Users/carlesfernandez/Documents/workspace/code2/trunk/data/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ;/datalogger/signals/CTTC/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ; <- PUT YOUR FILE HERE - +SignalSource.filename=/datalogger/signals/CTTC/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ; <- PUT YOUR FILE HERE ;#item_type: Type and resolution for each of the signal samples. SignalSource.item_type=ishort - -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=4000000 - -;#freq: RF front-end center frequency in [Hz] -SignalSource.freq=1575420000 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 - -;#repeat: Repeat the processing file. Disable this option in this version +;#repeat: Repeat the processing file. 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 - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false @@ -57,24 +42,18 @@ DataTypeAdapter.implementation=Ishort_To_Complex ;######### INPUT_FILTER CONFIG ############ ;## Filter the input data. Can be combined with frequency translation for IF signals -;#implementation: Use [Pass_Through] or [Fir_Filter] or [Freq_Xlating_Fir_Filter] +;#implementation: ;#[Pass_Through] disables this block ;#[Fir_Filter] enables a FIR Filter ;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation that shifts IF down to zero Hz. - ;InputFilter.implementation=Fir_Filter ;InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.implementation=Pass_Through -;#dump: Dump the filtered data to a file. -InputFilter.dump=false - -;#dump_filename: Log path and filename. -InputFilter.dump_filename=../data/input_filter.dat - ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of GNU Radio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, the desired response on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. ;#input_item_type: Type and resolution for input signal samples. InputFilter.input_item_type=gr_complex @@ -125,7 +104,10 @@ InputFilter.grid_density=16 InputFilter.sampling_frequency=4000000 InputFilter.IF=0 - +;#dump: Dump the filtered data to a file. +InputFilter.dump=false +;#dump_filename: Log path and filename. +InputFilter.dump_filename=../data/input_filter.dat ;######### RESAMPLER CONFIG ############ @@ -136,21 +118,17 @@ InputFilter.IF=0 ;#[Direct_Resampler] enables a resampler that implements a nearest neighborhood interpolation ;Resampler.implementation=Direct_Resampler Resampler.implementation=Pass_Through - +;#item_type: Type and resolution for each of the signal samples. +Resampler.item_type=gr_complex +;#sample_freq_in: the sample frequency of the input signal +Resampler.sample_freq_in=4000000 +;#sample_freq_out: the desired sample frequency of the output signal +Resampler.sample_freq_out=4000000 ;#dump: Dump the resampled data to a file. Resampler.dump=false ;#dump_filename: Log path and filename. Resampler.dump_filename=../data/resampler.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. -Resampler.item_type=gr_complex - -;#sample_freq_in: the sample frequency of the input signal -Resampler.sample_freq_in=4000000 - -;#sample_freq_out: the desired sample frequency of the output signal -Resampler.sample_freq_out=4000000 - ;######### CHANNELS GLOBAL CONFIG ############ ;#count: Number of available Galileo satellite channels. @@ -159,20 +137,15 @@ Channels_1B.count=8 Channels.in_acquisition=1 Channel.signal=1B -;######### ACQUISITION GLOBAL CONFIG ############ -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1B.dump=false -;#filename: Log path and filename -Acquisition_1B.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +;######### ACQUISITION GLOBAL CONFIG ############ +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1B.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1B.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1B.sampled_ms=4 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition ;#threshold: Acquisition threshold ;Acquisition_1B.threshold=0 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -181,70 +154,59 @@ Acquisition_1B.pfa=0.000002 Acquisition_1B.doppler_max=15000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1B.doppler_step=125 +;#cboc: Only for [Galileo_E1_PCPS_Ambiguous_Acquisition]. This option allows you to choose between acquiring with CBOC signal [true] or sinboc(1,1) signal [false]. +;#Use only if GNSS-SDR.internal_fs_sps is greater than or equal to 6138000 +Acquisition_1B.cboc=false +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1B.dump=false +;#filename: Log path and filename +Acquisition_1B.dump_filename=./acq_dump.dat + ;######### ACQUISITION CHANNELS CONFIG ###### ;######### ACQUISITION CH 0 CONFIG ############ - ;#repeat_satellite: Use only jointly with the satellite PRN ID option. The default value is false ;Acquisition_1B0.repeat_satellite = true ;Acquisition_1B1.repeat_satellite = true ;Acquisition_1B2.repeat_satellite = true ;Acquisition_1B3.repeat_satellite = true -;#cboc: Only for [Galileo_E1_PCPS_Ambiguous_Acquisition]. This option allows you to choose between acquiring with CBOC signal [true] or sinboc(1,1) signal [false]. -;#Use only if GNSS-SDR.internal_fs_sps is greater than or equal to 6138000 -Acquisition_1B.cboc=false - - ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1B.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1B.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1B.pll_bw_hz=15.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1B.dll_bw_hz=2.0; +;#fll_bw_hz: FLL loop filter bandwidth [Hz] +Tracking_1B.fll_bw_hz=10.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1B.order=3; +;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo +Tracking_1B.early_late_space_chips=0.15; +;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] +Tracking_1B.very_early_late_space_chips=0.6; +Tracking_1B.track_pilot=true ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1B.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1B.dump_filename=../data/veml_tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1B.pll_bw_hz=15.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1B.dll_bw_hz=2.0; - -;#fll_bw_hz: FLL loop filter bandwidth [Hz] -Tracking_1B.fll_bw_hz=10.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1B.order=3; - -;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo -Tracking_1B.early_late_space_chips=0.15; - -;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] -Tracking_1B.very_early_late_space_chips=0.6; - ;######### TELEMETRY DECODER CONFIG ############ -;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A or [Galileo_E1B_Telemetry_Decoder] for Galileo E1B TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder TelemetryDecoder_1B.dump=false -;######### OBSERVABLES CONFIG ############ -;#implementation: -Observables.implementation=Hybrid_Observables +;######### OBSERVABLES CONFIG ############ +Observables.implementation=Hybrid_Observables ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat @@ -255,38 +217,27 @@ PVT.implementation=RTKLIB_PVT PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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 - ;# KML, GeoJSON, NMEA and RTCM output configuration - -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump, ".kml" and ".geojson" to GIS-friendly formats. -PVT.dump_filename=./PVT - ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; - ;#flag_nmea_tty_port: Enables or disables the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) -PVT.flag_nmea_tty_port=true; - +PVT.flag_nmea_tty_port=true ;#nmea_dump_devname: serial device descriptor for NMEA logging PVT.nmea_dump_devname=/dev/pts/4 - ;#flag_rtcm_server: Enables or disables a TCP/IP server transmitting RTCM 3.2 messages (accepts multiple clients, port 2101 by default) PVT.flag_rtcm_server=true; PVT.rtcm_tcp_port=2101 PVT.rtcm_MT1045_rate_ms=5000 PVT.rtcm_MSM_rate_ms=1000 - ;#flag_rtcm_tty_port: Enables or disables the RTCM log to a serial TTY port (Can be used with real hardware or virtual one) PVT.flag_rtcm_tty_port=false; - ;#rtcm_dump_devname: serial device descriptor for RTCM logging PVT.rtcm_dump_devname=/dev/pts/1 +;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] +PVT.dump=false +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump, ".kml" and ".geojson" to GIS-friendly formats. +PVT.dump_filename=./PVT \ No newline at end of file diff --git a/conf/gnss-sdr_Galileo_E1_nsr.conf b/conf/gnss-sdr_Galileo_E1_nsr.conf index 4cf3f213c..f7ca01480 100644 --- a/conf/gnss-sdr_Galileo_E1_nsr.conf +++ b/conf/gnss-sdr_Galileo_E1_nsr.conf @@ -17,7 +17,6 @@ SignalSource.implementation=Nsr_File_Signal_Source SignalSource.filename=/datalogger/signals/ifen/E1L1_FE0_Band0.stream ; <- PUT YOUR FILE HERE SignalSource.item_type=byte SignalSource.sampling_frequency=20480000 -SignalSource.freq=1575420000 SignalSource.samples=0 ; 0 means the entire file SignalSource.repeat=false SignalSource.dump=false @@ -31,7 +30,6 @@ SignalSource.enable_throttle_control=false ;######### SIGNAL_CONDITIONER CONFIG ############ ;## It holds blocks to change data type, filter and resample input data. - SignalConditioner.implementation=Signal_Conditioner ;######### DATA_TYPE_ADAPTER CONFIG ############ @@ -40,8 +38,6 @@ DataTypeAdapter.item_type=float ;######### INPUT_FILTER CONFIG ############ InputFilter.implementation=Freq_Xlating_Fir_Filter -InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat InputFilter.input_item_type=float InputFilter.output_item_type=gr_complex InputFilter.taps_item_type=float @@ -65,6 +61,8 @@ InputFilter.grid_density=16 InputFilter.sampling_frequency=20480000 InputFilter.IF=5499998.47412109 InputFilter.decimation_factor=8 +InputFilter.dump=false +InputFilter.dump_filename=../data/input_filter.dat ;######### RESAMPLER CONFIG ############ @@ -78,33 +76,36 @@ Channel.signal=1B ;######### ACQUISITION GLOBAL CONFIG ############ -Acquisition_1B.dump=false -Acquisition_1B.dump_filename=./acq_dump.dat +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition Acquisition_1B.item_type=gr_complex Acquisition_1B.if=0 Acquisition_1B.sampled_ms=4 -Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition Acquisition_1B.pfa=0.0000008 Acquisition_1B.doppler_max=15000 Acquisition_1B.doppler_step=125 Acquisition_1B.cboc=false ; This option allows you to choose between acquiring with CBOC signal [true] or sinboc(1,1) signal [false]. Use only if GNSS-SDR.internal_fs_sps is greater than or equal to 6138000 +Acquisition_1B.dump=false +Acquisition_1B.dump_filename=./acq_dump.dat + ;######### TRACKING GLOBAL CONFIG ############ Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking Tracking_1B.item_type=gr_complex Tracking_1B.if=0 -Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ Tracking_1B.pll_bw_hz=20.0; Tracking_1B.dll_bw_hz=2.0; Tracking_1B.order=3; Tracking_1B.early_late_space_chips=0.15; Tracking_1B.very_early_late_space_chips=0.6; +Tracking_1B.dump=false +Tracking_1B.dump_filename=../data/veml_tracking_ch_ + ;######### TELEMETRY DECODER CONFIG ############ TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder TelemetryDecoder_1B.dump=false + ;######### OBSERVABLES CONFIG ############ Observables.implementation=Hybrid_Observables Observables.dump=true diff --git a/conf/gnss-sdr_Galileo_E5a.conf b/conf/gnss-sdr_Galileo_E5a.conf index 0845e1dff..d2ac70fba 100644 --- a/conf/gnss-sdr_Galileo_E5a.conf +++ b/conf/gnss-sdr_Galileo_E5a.conf @@ -25,32 +25,18 @@ GNSS-SDR.internal_fs_sps=32000000 ;GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=File_Signal_Source - ;#filename: path to file with the captured GNSS signal samples to be processed SignalSource.filename=/datalogger/signals/ifen/32MS_complex.dat ; <- PUT YOUR FILE HERE - -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +;#item_type: Type and resolution for each of the signal samples. SignalSource.item_type=gr_complex - -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=32000000 - -;#freq: RF front-end center frequency in [Hz] -SignalSource.freq=1176450000 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 - -;#repeat: Repeat the processing file. Disable this option in this version +;#repeat: Repeat the processing file. 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 - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false @@ -73,7 +59,7 @@ DataTypeAdapter.implementation=Pass_Through ;######### INPUT_FILTER CONFIG ############ ;## Filter the input data. Can be combined with frequency translation for IF signals -;#implementation: Use [Pass_Through] or [Fir_Filter] or [Freq_Xlating_Fir_Filter] +;#implementation: ;#[Pass_Through] disables this block ;#[Fir_Filter] enables a FIR Filter ;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation that shifts IF down to zero Hz. @@ -82,20 +68,15 @@ DataTypeAdapter.implementation=Pass_Through ;InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.implementation=Pass_Through -;#dump: Dump the filtered data to a file. -InputFilter.dump=false - -;#dump_filename: Log path and filename. -InputFilter.dump_filename=../data/input_filter.dat - ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. ;#input_item_type: Type and resolution for input signal samples. InputFilter.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -142,6 +123,11 @@ InputFilter.grid_density=16 InputFilter.sampling_frequency=32000000 InputFilter.IF=0 +;#dump: Dump the filtered data to a file. +InputFilter.dump=false + +;#dump_filename: Log path and filename. +InputFilter.dump_filename=../data/input_filter.dat ;######### RESAMPLER CONFIG ############ @@ -152,21 +138,17 @@ InputFilter.IF=0 ;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation ;Resampler.implementation=Direct_Resampler Resampler.implementation=Pass_Through - +;#item_type: Type and resolution for each of the signal samples. +Resampler.item_type=gr_complex +;#sample_freq_in: the sample frequency of the input signal +Resampler.sample_freq_in=8000000 +;#sample_freq_out: the desired sample frequency of the output signal +Resampler.sample_freq_out=4000000 ;#dump: Dump the resamplered data to a file. Resampler.dump=false ;#dump_filename: Log path and filename. Resampler.dump_filename=../data/resampler.dat -;#item_type: Type and resolution for each of the signal samples. -Resampler.item_type=gr_complex - -;#sample_freq_in: the sample frequency of the input signal -Resampler.sample_freq_in=8000000 - -;#sample_freq_out: the desired sample frequency of the output signal -Resampler.sample_freq_out=4000000 - ;######### CHANNELS GLOBAL CONFIG ############ ;#count: Number of available satellite channels. @@ -181,11 +163,9 @@ Channel.signal=5X ;#The following options are specific to each channel and overwrite the generic options ;######### CHANNEL 0 CONFIG ############ - -Channel0.signal=5X - +;Channel0.signal=5X ;#satellite: Satellite PRN ID for this channel. Disable this option to random search -Channel0.satellite=19 +;Channel0.satellite=19 ;Channel0.repeat_satellite=true ;######### CHANNEL 1 CONFIG ############ @@ -207,19 +187,13 @@ Channel0.satellite=19 ;Channel3.satellite=20 ;######### ACQUISITION GLOBAL CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_5X.dump=true -;#filename: Log path and filename -Acquisition_5X.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_5X.implementation=Galileo_E5a_Noncoherent_IQ_Acquisition_CAF +;#item_type: Type and resolution for each of the signal samples. Acquisition_5X.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_5X.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_5X.coherent_integration_time_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_5X.implementation=Galileo_E5a_Noncoherent_IQ_Acquisition_CAF ;#threshold: Acquisition threshold. It will be ignored if pfa is defined. Acquisition_5X.threshold=0.001 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -233,30 +207,23 @@ Acquisition_5X.doppler_step=250 Acquisition_5X.bit_transition_flag=false ;#max_dwells: Maximum number of consecutive dwells to be processed. It will be ignored if bit_transition_flag=true Acquisition_5X.max_dwells=1 - ;#CAF filter: **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is desactivated. Recommended value 3000 Hz Acquisition_5X.CAF_window_hz=0 ;#Zero_padding: **Only for E5a** Avoids power loss and doppler ambiguity in bit transitions by correlating one code with twice the input data length, ensuring that at least one full code is present without transitions. ;#If set to 1 it is ON, if set to 0 it is OFF. Acquisition_5X.Zero_padding=0 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_5X.dump=true +;#filename: Log path and filename +Acquisition_5X.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm: Tracking_5X.implementation=Galileo_E5a_DLL_PLL_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_5X.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_5X.if=0 - -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_5X.dump=true - -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_5X.dump_filename=./tracking_ch_ - ;#pll_bw_hz_init: **Only for E5a** PLL loop filter bandwidth during initialization [Hz] Tracking_5X.pll_bw_hz_init=20.0; ;#dll_bw_hz_init: **Only for E5a** DLL loop filter bandwidth during initialization [Hz] @@ -264,33 +231,33 @@ Tracking_5X.dll_bw_hz_init=20.0; ;#dll_ti_ms: **Only for E5a** loop filter integration time after initialization (secondary code delay search)[ms] ;Tracking_5X.ti_ms=3; Tracking_5X.ti_ms=1; - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] ;Tracking.pll_bw_hz=5.0; Tracking_5X.pll_bw_hz=20.0; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] ;Tracking.dll_bw_hz=2.0; Tracking_5X.dll_bw_hz=20.0; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_5X.order=2; - ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] Tracking_5X.early_late_space_chips=0.5; +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_5X.dump=true +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_5X.dump_filename=./tracking_ch_ + ;######### TELEMETRY DECODER CONFIG ############ ;#implementation: TelemetryDecoder_5X.implementation=Galileo_E5a_Telemetry_Decoder TelemetryDecoder_5X.dump=false + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat @@ -298,34 +265,24 @@ Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ ;#implementation: Position Velocity and Time (PVT) implementation algorithm: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=Single ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time [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 - ;# KML, GeoJSON, NMEA and RTCM output configuration -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./PVT - ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; - ;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) PVT.flag_nmea_tty_port=true; - ;#nmea_dump_devname: serial device descriptor for NMEA logging PVT.nmea_dump_devname=/dev/pts/4 - PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - - ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] PVT.dump=false +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf b/conf/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf index 8d4e1bc0b..ba75ebdcd 100644 --- a/conf/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf +++ b/conf/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf @@ -28,7 +28,6 @@ SignalSource.implementation=File_Signal_Source SignalSource.filename=/datalogger/signals/ifen/Galileo_E5ab_IFEN_CTTC_run1.dat ; <- PUT YOUR FILE HERE SignalSource.item_type=gr_complex SignalSource.sampling_frequency=50000000 -SignalSource.freq=1176450000 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false @@ -44,8 +43,6 @@ DataTypeAdapter.implementation=Pass_Through ;######### INPUT_FILTER CONFIG ############ InputFilter.implementation=Freq_Xlating_Fir_Filter -InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat InputFilter.input_item_type=gr_complex InputFilter.output_item_type=gr_complex InputFilter.taps_item_type=float @@ -66,6 +63,8 @@ InputFilter.grid_density=16 InputFilter.sampling_frequency=50000000 InputFilter.IF=-15345000 InputFilter.decimation_factor=1 +InputFilter.dump=false +InputFilter.dump_filename=../data/input_filter.dat ;######### RESAMPLER CONFIG ############ @@ -89,23 +88,21 @@ Channel0.satellite=19 ;######### CHANNEL 1 CONFIG ############ Channel1.signal=5X -Channel1.satellite=12 +;Channel1.satellite=12 ;######### CHANNEL 2 CONFIG ############ Channel2.signal=5X -Channel2.satellite=11 +;Channel2.satellite=11 ;######### CHANNEL 3 CONFIG ############ Channel3.signal=5X -Channel3.satellite=20 +;Channel3.satellite=20 ;######### ACQUISITION GLOBAL CONFIG ############ -Acquisition_5X.dump=false -Acquisition_5X.dump_filename=./acq_dump.dat +Acquisition_5X.implementation=Galileo_E5a_Noncoherent_IQ_Acquisition_CAF Acquisition_5X.item_type=gr_complex Acquisition_5X.if=0 Acquisition_5X.coherent_integration_time_ms=1 -Acquisition_5X.implementation=Galileo_E5a_Noncoherent_IQ_Acquisition_CAF Acquisition_5X.threshold=0.002 Acquisition_5X.doppler_max=10000 Acquisition_5X.doppler_step=250 @@ -113,14 +110,14 @@ Acquisition_5X.bit_transition_flag=false Acquisition_5X.max_dwells=1 Acquisition_5X.CAF_window_hz=0 ; **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is desactivated. Recommended value 3000 Hz Acquisition_5X.Zero_padding=0 ; **Only for E5a** Avoids power loss and doppler ambiguity in bit transitions by correlating one code with twice the input data length, ensuring that at least one full code is present without transitions. If set to 1 it is ON, if set to 0 it is OFF. +Acquisition_5X.dump=false +Acquisition_5X.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ Tracking_5X.implementation=Galileo_E5a_DLL_PLL_Tracking Tracking_5X.item_type=gr_complex Tracking_5X.if=0 -Tracking_5X.dump=false -Tracking_5X.dump_filename=./tracking_ch_ Tracking_5X.pll_bw_hz_init=20.0; **Only for E5a** PLL loop filter bandwidth during initialization [Hz] Tracking_5X.dll_bw_hz_init=20.0; **Only for E5a** DLL loop filter bandwidth during initialization [Hz] Tracking_5X.ti_ms=1; **Only for E5a** loop filter integration time after initialization (secondary code delay search)[ms] @@ -128,11 +125,15 @@ Tracking_5X.pll_bw_hz=20.0; Tracking_5X.dll_bw_hz=20.0; Tracking_5X.order=2; Tracking_5X.early_late_space_chips=0.5; +Tracking_5X.dump=false +Tracking_5X.dump_filename=./tracking_ch_ + ;######### TELEMETRY DECODER CONFIG ############ TelemetryDecoder_5X.implementation=Galileo_E5a_Telemetry_Decoder TelemetryDecoder_5X.dump=false + ;######### OBSERVABLES CONFIG ############ Observables.implementation=Hybrid_Observables Observables.dump=false diff --git a/conf/gnss-sdr_Hybrid_byte.conf b/conf/gnss-sdr_Hybrid_byte.conf index 44aa298f6..aa7caae99 100644 --- a/conf/gnss-sdr_Hybrid_byte.conf +++ b/conf/gnss-sdr_Hybrid_byte.conf @@ -11,32 +11,17 @@ GNSS-SDR.internal_fs_sps=20000000 ;######### SIGNAL_SOURCE CONFIG ############ -;#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=/datalogger/signals/Fraunhofer/L125_III1b_210s_L1.bin ; <- PUT YOUR FILE HERE - -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +;#item_type: Type and resolution for each of the signal samples.. SignalSource.item_type=byte - -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=20000000 - -;#freq: RF front-end center frequency in [Hz] -SignalSource.freq=1575420000 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 - -;#repeat: Repeat the processing file. Disable this option in this version +;#repeat: Repeat the processing file. 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 - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false @@ -51,14 +36,12 @@ SignalSource.enable_throttle_control=false SignalConditioner.implementation=Signal_Conditioner ;######### DATA_TYPE_ADAPTER CONFIG ############ -;## Changes the type of input data. Please disable it in this version. +;## Changes the type of input data. ;#implementation: [Pass_Through] disables this block DataTypeAdapter.implementation=Ibyte_To_Complex ;######### INPUT_FILTER CONFIG ############ ;## Filter the input data. Can be combined with frequency translation for IF signals - -;#implementation: Use [Pass_Through] or [Fir_Filter] or [Freq_Xlating_Fir_Filter] ;#[Pass_Through] disables this block ;#[Fir_Filter] enables a FIR Filter ;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation that shifts IF down to zero Hz. @@ -67,20 +50,15 @@ DataTypeAdapter.implementation=Ibyte_To_Complex ;InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.implementation=Pass_Through -;#dump: Dump the filtered data to a file. -InputFilter.dump=false - -;#dump_filename: Log path and filename. -InputFilter.dump_filename=../data/input_filter.dat - ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples.. InputFilter.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -126,32 +104,30 @@ InputFilter.grid_density=16 InputFilter.sampling_frequency=20000000 InputFilter.IF=0 - +;#dump: Dump the filtered data to a file. +InputFilter.dump=false +;#dump_filename: Log path and filename. +InputFilter.dump_filename=../data/input_filter.dat ;######### RESAMPLER CONFIG ############ ;## Resamples the input data. - ;#implementation: Use [Pass_Through] or [Direct_Resampler] ;#[Pass_Through] disables this block ;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation ;Resampler.implementation=Direct_Resampler Resampler.implementation=Pass_Through - +;#item_type: Type and resolution for each of the signal samples. +Resampler.item_type=gr_complex +;#sample_freq_in: the sample frequency of the input signal +Resampler.sample_freq_in=20000000 +;#sample_freq_out: the desired sample frequency of the output signal +Resampler.sample_freq_out=20000000 ;#dump: Dump the resamplered data to a file. Resampler.dump=false ;#dump_filename: Log path and filename. Resampler.dump_filename=../data/resampler.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. -Resampler.item_type=gr_complex - -;#sample_freq_in: the sample frequency of the input signal -Resampler.sample_freq_in=20000000 - -;#sample_freq_out: the desired sample frequency of the output signal -Resampler.sample_freq_out=20000000 - ;######### CHANNELS GLOBAL CONFIG ############ ;#count: Number of available GPS satellite channels. @@ -181,19 +157,13 @@ Channel15.signal=1B ;######### GPS ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.sampled_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold Acquisition_1C.threshold=0.0060 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -202,22 +172,20 @@ Acquisition_1C.threshold=0.0060 Acquisition_1C.doppler_max=10000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1C.doppler_step=500 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### GALILEO ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1B.dump=false -;#filename: Log path and filename -Acquisition_1B.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1B.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1B.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1B.sampled_ms=4 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition ;#threshold: Acquisition threshold ;Acquisition_1B.threshold=0 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -226,83 +194,69 @@ Acquisition_1B.pfa=0.0000008 Acquisition_1B.doppler_max=15000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1B.doppler_step=125 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1B.dump=false +;#filename: Log path and filename +Acquisition_1B.dump_filename=./acq_dump.dat + ;######### TRACKING GPS CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=45.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=4.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=../data/epl_tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=45.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=4.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; ;######### TRACKING GALILEO CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking ;#item_type: Type and resolution for each of the signal samples. Tracking_1B.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1B.if=0 - -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1B.dump=false - -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1B.dump_filename=../data/veml_tracking_ch_ - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1B.pll_bw_hz=15.0; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1B.dll_bw_hz=2.0; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_1B.order=3; - ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo Tracking_1B.early_late_space_chips=0.15; - ;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] Tracking_1B.very_early_late_space_chips=0.6; +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1B.dump=false +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1B.dump_filename=../data/veml_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;#decimation factor -TelemetryDecoder_1C.decimation_factor=4; + ;######### TELEMETRY DECODER GALILEO CONFIG ############ ;#implementation: Use [Galileo_E1B_Telemetry_Decoder] for Galileo E1B TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder TelemetryDecoder_1B.dump=false + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat @@ -310,23 +264,17 @@ Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ ;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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 - PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - ;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_Hybrid_byte_sim.conf b/conf/gnss-sdr_Hybrid_byte_sim.conf index 5de0b699f..7df406547 100644 --- a/conf/gnss-sdr_Hybrid_byte_sim.conf +++ b/conf/gnss-sdr_Hybrid_byte_sim.conf @@ -12,33 +12,22 @@ GNSS-SDR.internal_fs_sps=2600000 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=File_Signal_Source - ;#filename: path to file with the captured GNSS signal samples to be processed ;#SignalSource.filename=/home/javier/Descargas/rtlsdr_tcxo_l1/rtlsdr_tcxo_l1.bin ; <- PUT YOUR FILE HERE SignalSource.filename=/Users/carlesfernandez/git/cttc/build/signal_out.bin ; <- PUT YOUR FILE HERE - -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +;#item_type: Type and resolution for each of the signal samples. SignalSource.item_type=byte - -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=4000000 - -;#freq: RF front-end center frequency in [Hz] -SignalSource.freq=1575420000 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 - -;#repeat: Repeat the processing file. Disable this option in this version +;#repeat: Repeat the processing file. SignalSource.repeat=false - -;#dump: Dump the Signal source data to a file. Disable this option in this version +;#dump: Dump the Signal source data to a file. SignalSource.dump=false - SignalSource.dump_filename=../data/signal_source.dat - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false @@ -80,12 +69,13 @@ InputFilter.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -136,10 +126,10 @@ InputFilter.IF=0 ;######### RESAMPLER CONFIG ############ ;## Resamples the input data. - Resampler.implementation=Pass_Through Resampler.item_type = gr_complex; + ;######### CHANNELS GLOBAL CONFIG ############ ;#count: Number of available GPS satellite channels. Channels_1C.count=11 @@ -148,10 +138,6 @@ Channels_1B.count=0 ;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver Channels.in_acquisition=1 - -;#IMPORTANT: When cshort is used as input type for Acq and Trk, please set the Channel type to cshort here -;#item_type: Type and resolution for each of the signal samples. -Channel.item_type=gr_complex ;#signal: ;#if the option is disabled by default is assigned "1C" GPS L1 C/A Channel1.signal=1C @@ -172,19 +158,14 @@ Channel15.signal=1B ;######### GPS ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.sampled_ms=1 ;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#use_CFAR_algorithm: If enabled, acquisition estimates the input signal power to implement CFAR detection algorithms ;#notice that this affects the Acquisition threshold range! Acquisition_1C.use_CFAR_algorithm=false; @@ -196,22 +177,20 @@ Acquisition_1C.threshold=15 Acquisition_1C.doppler_max=6000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1C.doppler_step=100 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### GALILEO ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1B.dump=false -;#filename: Log path and filename -Acquisition_1B.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1B.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1B.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1B.sampled_ms=4 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition ;#threshold: Acquisition threshold ;Acquisition_1B.threshold=0 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -220,108 +199,85 @@ Acquisition_1B.pfa=0.0000008 Acquisition_1B.doppler_max=15000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1B.doppler_step=125 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1B.dump=false +;#filename: Log path and filename +Acquisition_1B.dump_filename=./acq_dump.dat + ;######### TRACKING GPS CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1C.dump=false - -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1C.dump_filename=../data/epl_tracking_ch_ - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1C.pll_bw_hz=20.0; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1C.dll_bw_hz=1.5; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_1C.order=3; -;######### TRACKING GALILEO CONFIG ############ -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] +;######### TRACKING GALILEO CONFIG ############ Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking ;#item_type: Type and resolution for each of the signal samples. Tracking_1B.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1B.if=0 - ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1B.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1B.dump_filename=../data/veml_tracking_ch_ - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1B.pll_bw_hz=15.0; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1B.dll_bw_hz=2.0; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_1B.order=3; - ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo Tracking_1B.early_late_space_chips=0.15; - ;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] Tracking_1B.very_early_late_space_chips=0.6; +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1C.dump=false +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1C.dump_filename=../data/epl_tracking_ch_ + ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;#decimation factor -TelemetryDecoder_1C.decimation_factor=1; + ;######### TELEMETRY DECODER GALILEO CONFIG ############ ;#implementation: Use [Galileo_E1B_Telemetry_Decoder] for Galileo E1B TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder -TelemetryDecoder_1B.dump=false -TelemetryDecoder_1B.decimation_factor=1; + ;######### OBSERVABLES CONFIG ############ -;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ -;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version. PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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 - PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - +;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] +PVT.dump=false ;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_Hybrid_gr_complex.conf b/conf/gnss-sdr_Hybrid_gr_complex.conf index 684c24af7..63f92330e 100644 --- a/conf/gnss-sdr_Hybrid_gr_complex.conf +++ b/conf/gnss-sdr_Hybrid_gr_complex.conf @@ -10,32 +10,18 @@ GNSS-SDR.internal_fs_sps=4092000 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] [Nsr_File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=File_Signal_Source - ;#filename: path to file with the captured GNSS signal samples to be processed SignalSource.filename=/datalogger/signals/sim/GPS_sim1.dat ; <- PUT YOUR FILE HERE - -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +;#item_type: Type and resolution for each of the signal samples. SignalSource.item_type=gr_complex - -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=4092000 - -;#freq: RF front-end center frequency in [Hz] -SignalSource.freq=1575420000 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 - -;#repeat: Repeat the processing file. Disable this option in this version +;#repeat: Repeat the processing file. 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 - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false @@ -64,22 +50,15 @@ DataTypeAdapter.item_type=gr_complex InputFilter.implementation=Pass_Through -;#dump: Dump the filtered data to a file. -InputFilter.dump=false - -;#dump_filename: Log path and filename. -InputFilter.dump_filename=../data/input_filter.dat - ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse -;#reponse given a set of band edges, the desired reponse on those bands, -;#and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -131,15 +110,21 @@ InputFilter.IF=5499998.47412109 ;# Decimation factor after the frequency tranaslating block InputFilter.decimation_factor=8 +;#dump: Dump the filtered data to a file. +InputFilter.dump=false + +;#dump_filename: Log path and filename. +InputFilter.dump_filename=../data/input_filter.dat + ;######### RESAMPLER CONFIG ############ ;## Resamples the input data. - ;#implementation: Use [Pass_Through] or [Direct_Resampler] ;#[Pass_Through] disables this block ;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation Resampler.implementation=Pass_Through + ;######### CHANNELS GLOBAL CONFIG ############ ;#count: Number of available GPS satellite channels. Channels_1C.count=1 @@ -174,19 +159,13 @@ Channel15.signal=1B ;######### GPS ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.sampled_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.use_CFAR_algorithm=false; ;#threshold: Acquisition threshold Acquisition_1C.threshold=30 @@ -196,22 +175,20 @@ Acquisition_1C.threshold=30 Acquisition_1C.doppler_max=5000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1C.doppler_step=100 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### GALILEO ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1B.dump=false -;#filename: Log path and filename -Acquisition_1B.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1B.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1B.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1B.sampled_ms=4 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition ;#threshold: Acquisition threshold ;Acquisition_1B.threshold=0 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -220,98 +197,79 @@ Acquisition_1B.pfa=0.0000002 Acquisition_1B.doppler_max=15000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1B.doppler_step=125 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1B.dump=false +;#filename: Log path and filename +Acquisition_1B.dump_filename=./acq_dump.dat + ;######### TRACKING GPS CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_C_Aid_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1C.dump=true - -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1C.dump_filename=../data/epl_tracking_ch_ - ;# Extended correlation after telemetry bit synchronization ;# Valid values are: [1,2,4,5,10,20] (integer divisors of the GPS L1 CA bit period (20 ms) ) ;# Longer integration period require more stable front-end LO - Tracking_1C.extend_correlation_ms=10 - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1C.pll_bw_hz=40; Tracking_1C.pll_bw_narrow_hz=25; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1C.dll_bw_hz=2.0; - Tracking_1C.dll_bw_narrow_hz=2.0; - ;#fll_bw_hz: FLL loop filter bandwidth [Hz] Tracking_1C.fll_bw_hz=2.0; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_1C.order=3; +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1C.dump=true +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1C.dump_filename=../data/epl_tracking_ch_ + ;######### TRACKING GALILEO CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1B.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1B.if=0 - -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1B.dump=false - -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1B.dump_filename=../data/veml_tracking_ch_ - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1B.pll_bw_hz=15.0; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1B.dll_bw_hz=2.0; - ;#fll_bw_hz: FLL loop filter bandwidth [Hz] Tracking_1B.fll_bw_hz=10.0; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_1B.order=3; - ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo Tracking_1B.early_late_space_chips=0.15; - ;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] Tracking_1B.very_early_late_space_chips=0.6; +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1B.dump=false +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1B.dump_filename=../data/veml_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;#decimation factor -TelemetryDecoder_1C.decimation_factor=4; + ;######### TELEMETRY DECODER GALILEO CONFIG ############ ;#implementation: Use [Galileo_E1B_Telemetry_Decoder] for Galileo E1B TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder TelemetryDecoder_1B.dump=false + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat @@ -319,23 +277,17 @@ Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ ;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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=10; - ;#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 - PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - ;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_Hybrid_ishort.conf b/conf/gnss-sdr_Hybrid_ishort.conf index 8e4989aeb..6bfa9e8fa 100644 --- a/conf/gnss-sdr_Hybrid_ishort.conf +++ b/conf/gnss-sdr_Hybrid_ishort.conf @@ -26,32 +26,18 @@ GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=File_Signal_Source - ;#filename: path to file with the captured GNSS signal samples to be processed SignalSource.filename=/datalogger/signals/CTTC/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ; <- PUT YOUR FILE HERE - ;#item_type: Type and resolution for each of the signal samples. SignalSource.item_type=ishort - -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=4000000 - -;#freq: RF front-end center frequency in [Hz] -SignalSource.freq=1575420000 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 - -;#repeat: Repeat the processing file. Disable this option in this version +;#repeat: Repeat the processing file. 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 - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false @@ -82,20 +68,15 @@ DataTypeAdapter.implementation=Ishort_To_Complex ;InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.implementation=Pass_Through -;#dump: Dump the filtered data to a file. -InputFilter.dump=false - -;#dump_filename: Log path and filename. -InputFilter.dump_filename=../data/input_filter.dat - ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -142,31 +123,31 @@ InputFilter.grid_density=16 InputFilter.sampling_frequency=4000000 InputFilter.IF=0 +;#dump: Dump the filtered data to a file. +InputFilter.dump=false + +;#dump_filename: Log path and filename. +InputFilter.dump_filename=../data/input_filter.dat ;######### RESAMPLER CONFIG ############ ;## Resamples the input data. - ;#implementation: Use [Pass_Through] or [Direct_Resampler] ;#[Pass_Through] disables this block ;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation ;Resampler.implementation=Direct_Resampler Resampler.implementation=Pass_Through - +;#item_type: Type and resolution for each of the signal samples. +Resampler.item_type=gr_complex +;#sample_freq_in: the sample frequency of the input signalq +Resampler.sample_freq_in=4000000 +;#sample_freq_out: the desired sample frequency of the output signal +Resampler.sample_freq_out=4000000 ;#dump: Dump the resamplered data to a file. Resampler.dump=false ;#dump_filename: Log path and filename. Resampler.dump_filename=../data/resampler.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. -Resampler.item_type=gr_complex - -;#sample_freq_in: the sample frequency of the input signalq -Resampler.sample_freq_in=4000000 - -;#sample_freq_out: the desired sample frequency of the output signal -Resampler.sample_freq_out=4000000 - ;######### CHANNELS GLOBAL CONFIG ############ ;#count: Number of available GPS satellite channels. @@ -191,21 +172,14 @@ Channel6.signal=1B Channel7.signal=1B - ;######### GPS ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.sampled_ms=1 -;#implementation: Acquisition algorithm selection for this channel: -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold Acquisition_1C.threshold=0.0075 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -214,22 +188,21 @@ Acquisition_1C.threshold=0.0075 Acquisition_1C.doppler_max=10000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1C.doppler_step=500 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### GALILEO ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1B.dump=false -;#filename: Log path and filename -Acquisition_1B.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1B.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1B.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1B.sampled_ms=4 ;#implementation: Acquisition algorithm selection for this channel: -Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition ;#threshold: Acquisition threshold ;Acquisition_1B.threshold=0 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -239,84 +212,69 @@ Acquisition_1B.doppler_max=15000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1B.doppler_step=125 Acquisition_1B.cboc=false; +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1B.dump=false +;#filename: Log path and filename +Acquisition_1B.dump_filename=./acq_dump.dat + ;######### TRACKING GPS CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_C_Aid_Tracking ;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=50.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=5.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=../data/epl_tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=50.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=5.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; ;######### TRACKING GALILEO CONFIG ############ - -;#implementation: Selected tracking algorithm: Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking ;#item_type: Type and resolution for each of the signal samples. Tracking_1B.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1B.if=0 - -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1B.dump=false - -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1B.dump_filename=../data/veml_tracking_ch_ - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1B.pll_bw_hz=20.0; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1B.dll_bw_hz=2.0; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_1B.order=3; - ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo Tracking_1B.early_late_space_chips=0.15; - ;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] Tracking_1B.very_early_late_space_chips=0.6; +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1B.dump=false +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1B.dump_filename=../data/veml_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;#decimation factor -TelemetryDecoder_1C.decimation_factor=4; + ;######### TELEMETRY DECODER GALILEO CONFIG ############ ;#implementation: Use [Galileo_E1B_Telemetry_Decoder] for Galileo E1B TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder TelemetryDecoder_1B.dump=false -TelemetryDecoder_1B.decimation_factor=1; + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat @@ -324,20 +282,13 @@ Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ ;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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 - PVT.flag_rtcm_server=true PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 @@ -346,6 +297,7 @@ PVT.rtcm_MT1045_rate_ms=5000 ; Period (in ms) of Galileo ephemeris messages. 0 m PVT.rtcm_MT1045_rate_ms=5000 ; Period (in ms) of GPS ephemeris messages. 0 mutes this message PVT.rtcm_MT1097_rate_ms=1000 ; Period (in ms) of Galileo observables. 0 mutes this message PVT.rtcm_MT1077_rate_ms=1000 ; Period (in ms) of GPS observables. 0 mutes this message - +;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] +PVT.dump=false ;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_Hybrid_nsr.conf b/conf/gnss-sdr_Hybrid_nsr.conf index a65244110..2427aa101 100644 --- a/conf/gnss-sdr_Hybrid_nsr.conf +++ b/conf/gnss-sdr_Hybrid_nsr.conf @@ -13,33 +13,21 @@ GNSS-SDR.internal_fs_sps=2560000 ;GNSS-SDR.internal_fs_sps=5120000 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] [Nsr_File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=Nsr_File_Signal_Source - ;#filename: path to file with the captured GNSS signal samples to be processed SignalSource.filename=/media/javier/SISTEMA/signals/ifen/E1L1_FE0_Band0.stream ; <- PUT YOUR FILE HERE - ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource.item_type=byte - -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=20480000 - -;#freq: RF front-end center frequency in [Hz] -SignalSource.freq=1575420000 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 - -;#repeat: Repeat the processing file. Disable this option in this version +;#repeat: Repeat the processing file. SignalSource.repeat=false - -;#dump: Dump the Signal source data to a file. Disable this option in this version +;#dump: Dump the Signal source data to a file. SignalSource.dump=false - SignalSource.dump_filename=../data/signal_source.dat - - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false @@ -68,22 +56,15 @@ DataTypeAdapter.item_type=float InputFilter.implementation=Freq_Xlating_Fir_Filter -;#dump: Dump the filtered data to a file. -InputFilter.dump=false - -;#dump_filename: Log path and filename. -InputFilter.dump_filename=../data/input_filter.dat - ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse -;#reponse given a set of band edges, the desired reponse on those bands, -;#and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter.input_item_type=float -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -135,6 +116,12 @@ InputFilter.IF=5499998.47412109 ;# Decimation factor after the frequency tranaslating block InputFilter.decimation_factor=8 +;#dump: Dump the filtered data to a file. +InputFilter.dump=false + +;#dump_filename: Log path and filename. +InputFilter.dump_filename=../data/input_filter.dat + ;######### RESAMPLER CONFIG ############ ;## Resamples the input data. @@ -154,9 +141,11 @@ Channels.in_acquisition=1 ;#signal: ;# "1C" GPS L1 C/A -;# "2S" GPS L2 L2C (M) ;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL) +;# "1G" GLONASS L1 C/A +;# "2S" GPS L2 L2C (M) ;# "5X" GALILEO E5a I+Q +;# "L5" GPS L5 ;#if the option is disabled by default is assigned "1C" GPS L1 C/A Channel0.signal=1C @@ -178,19 +167,13 @@ Channel15.signal=1B ;######### GPS ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.sampled_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold Acquisition_1C.threshold=0.0075 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -199,22 +182,21 @@ Acquisition_1C.threshold=0.0075 Acquisition_1C.doppler_max=5000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1C.doppler_step=250 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### GALILEO ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1B.dump=false -;#filename: Log path and filename -Acquisition_1B.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1B.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1B.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1B.sampled_ms=4 ;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition ;#threshold: Acquisition threshold ;Acquisition_1B.threshold=0 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -223,118 +205,92 @@ Acquisition_1B.pfa=0.0000002 Acquisition_1B.doppler_max=15000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1B.doppler_step=125 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1B.dump=false +;#filename: Log path and filename +Acquisition_1B.dump_filename=./acq_dump.dat + ;######### TRACKING GPS CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_C_Aid_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1C.dump=true - -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1C.dump_filename=../data/epl_tracking_ch_ - ;# Extended correlation after telemetry bit synchronization ;# Valid values are: [1,2,4,5,10,20] (integer divisors of the GPS L1 CA bit period (20 ms) ) ;# Longer integration period require more stable front-end LO - Tracking_1C.extend_correlation_ms=1 - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] - Tracking_1C.pll_bw_hz=40; Tracking_1C.pll_bw_narrow_hz=20; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1C.dll_bw_hz=2.0; Tracking_1C.dll_bw_narrow_hz=1.0; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_1C.order=3; +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1C.dump=true +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1C.dump_filename=../data/epl_tracking_ch_ + ;######### TRACKING GALILEO CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1B.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1B.if=0 - -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1B.dump=false - -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1B.dump_filename=../data/veml_tracking_ch_ - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1B.pll_bw_hz=15.0; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1B.dll_bw_hz=2.0; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_1B.order=3; - ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo Tracking_1B.early_late_space_chips=0.15; - ;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] Tracking_1B.very_early_late_space_chips=0.6; +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1B.dump=false +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1B.dump_filename=../data/veml_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;#decimation factor -TelemetryDecoder_1C.decimation_factor=4; + ;######### TELEMETRY DECODER GALILEO CONFIG ############ ;#implementation: Use [Galileo_E1B_Telemetry_Decoder] for Galileo E1B TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder TelemetryDecoder_1B.dump=false -TelemetryDecoder_1B_factor=4; + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ -;#implementation: Position Velocity and Time (PVT) implementation algorithm. PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - - ;#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=10; - ;#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 - PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - +;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] +PVT.dump=false ;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_galileo_E1_extended_correlator_byte.conf b/conf/gnss-sdr_galileo_E1_extended_correlator_byte.conf index fb6a08fc0..e9e5eb0f8 100644 --- a/conf/gnss-sdr_galileo_E1_extended_correlator_byte.conf +++ b/conf/gnss-sdr_galileo_E1_extended_correlator_byte.conf @@ -11,34 +11,18 @@ GNSS-SDR.internal_fs_sps=20000000 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=File_Signal_Source - ;#filename: path to file with the captured GNSS signal samples to be processed -;SignalSource.filename=/home/javier/signals/L125_III1b_210s_L1_2msps.bin ; <- PUT YOUR FILE HERE - -SignalSource.filename=/media/javier/SISTEMA/signals/fraunhofer/L125_III1b_210s_L1.bin - -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +SignalSource.filename=/media/javier/SISTEMA/signals/fraunhofer/L125_III1b_210s_L1.bin ; <- PUT YOUR FILE HERE +;#item_type: Type and resolution for each of the signal samples. SignalSource.item_type=byte - -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=20000000 - -;#freq: RF front-end center frequency in [Hz] -SignalSource.freq=1575420000 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 - -;#repeat: Repeat the processing file. Disable this option in this version +;#repeat: Repeat the processing file. 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 - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false @@ -53,7 +37,7 @@ SignalSource.enable_throttle_control=false SignalConditioner.implementation=Signal_Conditioner ;######### DATA_TYPE_ADAPTER CONFIG ############ -;## Changes the type of input data. Please disable it in this version. +;## Changes the type of input data. ;#implementation: [Pass_Through] disables this block DataTypeAdapter.implementation=Ibyte_To_Complex @@ -68,7 +52,7 @@ InputFilter.implementation=Pass_Through ;#implementation: Use [Pass_Through] or [Direct_Resampler] ;#[Pass_Through] disables this block -;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation +;#[Direct_Resampler] enables a resampler that implements a nearest neighborhood interpolation ;Resampler.implementation=Direct_Resampler Resampler.implementation=Pass_Through @@ -101,19 +85,13 @@ Channel15.signal=1B ;######### GPS ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.sampled_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.use_CFAR_algorithm=false; ;#threshold: Acquisition threshold Acquisition_1C.threshold=18 @@ -121,22 +99,20 @@ Acquisition_1C.threshold=18 Acquisition_1C.doppler_max=5000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1C.doppler_step=500 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### GALILEO ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1B.dump=false -;#filename: Log path and filename -Acquisition_1B.dump_filename=../data/acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1B.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1B.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1B.sampled_ms=4 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition Acquisition_1B.acquire_pilot=true Acquisition_1B.use_CFAR_algorithm=false ;#threshold: Acquisition threshold @@ -146,100 +122,78 @@ Acquisition_1B.doppler_max=5000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1B.doppler_step=125 Acquisition_1B.bit_transition_flag=true +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1B.dump=false +;#filename: Log path and filename +Acquisition_1B.dump_filename=../data/acq_dump.dat + ;######### TRACKING GPS CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=30.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=2.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=../data/epl_tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=30.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=2.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; ;######### TRACKING GALILEO CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking ;#item_type: Type and resolution for each of the signal samples. Tracking_1B.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1B.if=0 - -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1B.dump=true - -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1B.dump_filename=../data/veml_tracking_ch_ - Tracking_1B.track_pilot=true - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1B.pll_bw_hz=4.0; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1B.dll_bw_hz=0.5; - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1B.pll_bw_narrow_hz=2.0; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1B.dll_bw_narrow_hz=0.25; - Tracking_1B.extend_correlation_symbols=4; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_1B.order=3; - ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo Tracking_1B.early_late_space_chips=0.15; - ;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] Tracking_1B.very_early_late_space_chips=0.6; - ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo Tracking_1B.early_late_space_narrow_chips=0.06; - ;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] Tracking_1B.very_early_late_space_narrow_chips=0.25; - +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1B.dump=true +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1B.dump_filename=../data/veml_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;#decimation factor -TelemetryDecoder_1C.decimation_factor=4; ;######### TELEMETRY DECODER GALILEO CONFIG ############ ;#implementation: Use [Galileo_E1B_Telemetry_Decoder] for Galileo E1B TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder TelemetryDecoder_1B.dump=false + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat @@ -247,23 +201,17 @@ Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ ;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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 - PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - +;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] +PVT.dump=false ;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_galileo_E1_extended_correlator_labsat.conf b/conf/gnss-sdr_galileo_E1_extended_correlator_labsat.conf index 094f15ebe..8b2f05195 100644 --- a/conf/gnss-sdr_galileo_E1_extended_correlator_labsat.conf +++ b/conf/gnss-sdr_galileo_E1_extended_correlator_labsat.conf @@ -7,46 +7,33 @@ ;######### GLOBAL OPTIONS ################## ;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz]. -GNSS-SDR.internal_fs_hz=5456000 +GNSS-SDR.internal_fs_sps=5456000 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] [Nsr_File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=Labsat_Signal_Source - SignalSource.selected_channel=1 - ;#filename: path to file with the captured GNSS signal samples to be processed -;# Labsat sile source automatically increments the file name when the signal is splitted in several files +;# Labsat sile source automatically increments the file name when the signal is split in several files ;# the adapter adds "_0000.LS3" to this base path and filename. Next file will be "_0001.LS3" and so on ;# in this example, the first file complete path will be ../signals/GPS_025_0000.LS3 - SignalSource.filename=../signals/GPS_025 ; <- PUT YOUR FILE HERE - ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource.item_type=gr_complex - -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource.sampling_frequency=16368000 - -;#freq: RF front-end center frequency in [Hz] -SignalSource.freq=1575420000 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 - -;#repeat: Repeat the processing file. Disable this option in this version +;#repeat: Repeat the processing file. SignalSource.repeat=false - -;#dump: Dump the Signal source data to a file. Disable this option in this version +;#dump: Dump the Signal source data to a file. SignalSource.dump=false - SignalSource.dump_filename=../data/signal_source.dat - - ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false + ;######### SIGNAL_CONDITIONER CONFIG ############ ;## It holds blocks to change data type, filter and resample input data. @@ -64,10 +51,9 @@ DataTypeAdapter.item_type=gr_complex ;######### INPUT_FILTER CONFIG ############ ;## Filter the input data. Can be combined with frequency translation for IF signals -;#implementation: Use [Pass_Through] or [Fir_Filter] or [Freq_Xlating_Fir_Filter] +;#implementation ;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation ;# that shifts IF down to zero Hz. - InputFilter.implementation=Freq_Xlating_Fir_Filter ;#dump: Dump the filtered data to a file. @@ -78,14 +64,13 @@ InputFilter.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse -;#reponse given a set of band edges, the desired reponse on those bands, -;#and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -167,19 +152,13 @@ Channel15.signal=1B ;######### GPS ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.sampled_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.use_CFAR_algorithm=false; ;#threshold: Acquisition threshold Acquisition_1C.threshold=22 @@ -187,22 +166,19 @@ Acquisition_1C.threshold=22 Acquisition_1C.doppler_max=5000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1C.doppler_step=250 - +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### GALILEO ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1B.dump=false -;#filename: Log path and filename -Acquisition_1B.dump_filename=../data/acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1B.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1B.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1B.sampled_ms=4 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition Acquisition_1B.acquire_pilot=true Acquisition_1B.use_CFAR_algorithm=false ;#threshold: Acquisition threshold @@ -212,79 +188,59 @@ Acquisition_1B.doppler_max=5000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1B.doppler_step=125 Acquisition_1B.bit_transition_flag=true +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1B.dump=false +;#filename: Log path and filename +Acquisition_1B.dump_filename=../data/acq_dump.dat + ;######### TRACKING GPS CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=40.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=2.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=true - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=../data/epl_tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=40.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=2.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; - ;######### TRACKING GALILEO CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking ;#item_type: Type and resolution for each of the signal samples. Tracking_1B.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1B.if=0 - -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1B.dump=true - -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1B.dump_filename=../data/veml_tracking_ch_ - Tracking_1B.track_pilot=true - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1B.pll_bw_hz=7.5; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1B.dll_bw_hz=0.5; - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1B.pll_bw_narrow_hz=2.5; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1B.dll_bw_narrow_hz=0.25; - Tracking_1B.extend_correlation_symbols=4; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_1B.order=3; - ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo Tracking_1B.early_late_space_chips=0.15; - ;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] Tracking_1B.very_early_late_space_chips=0.6; - ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo Tracking_1B.early_late_space_narrow_chips=0.15; - ;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] Tracking_1B.very_early_late_space_narrow_chips=0.30; - +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1B.dump=true +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1B.dump_filename=../data/veml_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ @@ -297,13 +253,12 @@ TelemetryDecoder_1C.dump=false TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder TelemetryDecoder_1B.dump=false + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat @@ -311,23 +266,17 @@ Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ ;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=Single ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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 - PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - +;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] +PVT.dump=false ;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf index 7cf44f53b..746dbdea9 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf @@ -24,29 +24,22 @@ GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=Flexiband_Signal_Source - SignalSource.flag_read_file=true SignalSource.signal_file=/datalogger/signals/Fraunhofer/L125_III1b_210s.usb ; <- PUT YOUR FILE HERE - ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource.item_type=gr_complex - ;# FPGA firmware file SignalSource.firmware_file=flexiband_III-1b.bit - ;#RF_channels: Number of RF channels present in the frontend device, must agree the FPGA firmware file SignalSource.RF_channels=1 - ;#frontend channels gain. Not usable yet! SignalSource.gain1=0 SignalSource.gain2=0 SignalSource.gain3=0 - ;#frontend channels AGC SignalSource.AGC=true - ;# USB 3.0 packet buffer size (number of SuperSpeed packets) SignalSource.usb_packet_buffer=128 @@ -76,13 +69,13 @@ InputFilter0.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, -;#the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter0.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter0.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -156,10 +149,10 @@ InputFilter1.dump=false ;#dump_filename: Log path and filename. InputFilter1.dump_filename=../data/input_filter.dat -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter1.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter1.output_item_type=gr_complex ;######### RESAMPLER CONFIG 1 ############ @@ -183,10 +176,10 @@ InputFilter2.dump=false ;#dump_filename: Log path and filename. InputFilter2.dump_filename=../data/input_filter.dat -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter2.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter2.output_item_type=gr_complex ;######### RESAMPLER CONFIG 2 ############ @@ -219,19 +212,13 @@ Channel.signal=1C ;######### ACQUISITION GLOBAL CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.coherent_integration_time_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.use_CFAR_algorithm=false; ;#threshold: Acquisition threshold. It will be ignored if pfa is defined. Acquisition_1C.threshold=15 @@ -247,91 +234,71 @@ Acquisition_1C.doppler_step=250 Acquisition_1C.bit_transition_flag=false ;#max_dwells: Maximum number of consecutive dwells to be processed. It will be ignored if bit_transition_flag=true Acquisition_1C.max_dwells=1 - - -;######### ACQUISITION CHANNELS CONFIG ###### -;#The following options are specific to each channel and overwrite the generic options +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_C_Aid_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1C.dump=true - -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1C.dump_filename=../data/epl_tracking_ch_ - Tracking_1C.extend_correlation_ms=10 - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1C.pll_bw_hz=40.0; Tracking_1C.pll_bw_narrow_hz=35; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1C.dll_bw_hz=2.0; Tracking_1C.dll_bw_narrow_hz=2.0; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_1C.order=3; - ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] Tracking_1C.early_late_space_chips=0.5; +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1C.dump=true +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1C.dump_filename=../data/epl_tracking_ch_ + ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ -;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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 - ;# KML, GeoJSON, NMEA and RTCM output configuration - -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./PVT - ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; - ;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) PVT.flag_nmea_tty_port=false; - ;#nmea_dump_devname: serial device descriptor for NMEA logging PVT.nmea_dump_devname=/dev/pts/4 - PVT.flag_rtcm_server=true PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] PVT.dump=false +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT + diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf index ef35f1207..dc80ecfd0 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf @@ -25,7 +25,7 @@ GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=Flexiband_Signal_Source ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. @@ -74,13 +74,13 @@ InputFilter0.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, -;#the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter0.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter0.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -153,10 +153,10 @@ InputFilter1.dump=false ;#dump_filename: Log path and filename. InputFilter1.dump_filename=../data/input_filter.dat -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter1.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter1.output_item_type=gr_complex ;######### RESAMPLER CONFIG 1 ############ @@ -180,10 +180,10 @@ InputFilter2.dump=false ;#dump_filename: Log path and filename. InputFilter2.dump_filename=../data/input_filter.dat -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter2.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter2.output_item_type=gr_complex ;######### RESAMPLER CONFIG 2 ############ @@ -197,12 +197,13 @@ Channels_1C.count=8 ;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver Channels.in_acquisition=1 - ;#signal: ;# "1C" GPS L1 C/A -;# "2S" GPS L2 L2C (M) ;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL) +;# "1G" GLONASS L1 C/A +;# "2S" GPS L2 L2C (M) ;# "5X" GALILEO E5a I+Q +;# "L5" GPS L5 ;# CHANNEL CONNECTION Channel0.RF_channel_ID=0 @@ -231,19 +232,13 @@ Channel7.signal=1C ;######### ACQUISITION GLOBAL CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.coherent_integration_time_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold. It will be ignored if pfa is defined. Acquisition_1C.threshold=0.012 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -258,89 +253,66 @@ Acquisition_1C.doppler_step=250 Acquisition_1C.bit_transition_flag=false ;#max_dwells: Maximum number of consecutive dwells to be processed. It will be ignored if bit_transition_flag=true Acquisition_1C.max_dwells=1 - - -;######### ACQUISITION CHANNELS CONFIG ###### -;#The following options are specific to each channel and overwrite the generic options +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking ;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=40.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=3.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; +;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] +Tracking_1C.early_late_space_chips=0.5; ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=./tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=40.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=3.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; - -;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] -Tracking_1C.early_late_space_chips=0.5; ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;#decimation factor -TelemetryDecoder_1C.decimation_factor=1; + ;######### OBSERVABLES CONFIG ############ -;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ -;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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 - ;# KML, GeoJSON, NMEA and RTCM output configuration - -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./PVT - ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; - ;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) PVT.flag_nmea_tty_port=false; - ;#nmea_dump_devname: serial device descriptor for NMEA logging PVT.nmea_dump_devname=/dev/pts/4 - PVT.flag_rtcm_server=true PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] PVT.dump=false +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT \ No newline at end of file diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf index 859c41ba2..9a184f66d 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf @@ -25,26 +25,20 @@ GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=Flexiband_Signal_Source - ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource.item_type=gr_complex - ;# FPGA firmware file SignalSource.firmware_file=flexiband_III-1b.bit - ;#RF_channels: Number of RF channels present in the frontend device, must agree the FPGA firmware file SignalSource.RF_channels=1 - ;#frontend channels gain. Not usable yet! SignalSource.gain1=0 SignalSource.gain2=0 SignalSource.gain3=0 - ;#frontend channels AGC SignalSource.AGC=true - ;# USB 3.0 packet buffer size (number of SuperSpeed packets) SignalSource.usb_packet_buffer=128 @@ -74,13 +68,13 @@ InputFilter0.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, -;#the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter0.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter0.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -153,10 +147,10 @@ InputFilter1.dump=false ;#dump_filename: Log path and filename. InputFilter1.dump_filename=../data/input_filter.dat -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter1.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter1.output_item_type=gr_complex ;######### RESAMPLER CONFIG 1 ############ @@ -180,10 +174,10 @@ InputFilter2.dump=false ;#dump_filename: Log path and filename. InputFilter2.dump_filename=../data/input_filter.dat -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter2.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter2.output_item_type=gr_complex ;######### RESAMPLER CONFIG 2 ############ @@ -196,12 +190,13 @@ Channels_1C.count=8 ;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver Channels.in_acquisition=1 - ;#signal: ;# "1C" GPS L1 C/A -;# "2S" GPS L2 L2C (M) ;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL) +;# "1G" GLONASS L1 C/A +;# "2S" GPS L2 L2C (M) ;# "5X" GALILEO E5a I+Q +;# "L5" GPS L5 ;# CHANNEL CONNECTION Channel0.RF_channel_ID=0 @@ -224,24 +219,15 @@ Channel5.signal=1C Channel6.signal=1C Channel7.signal=1C -;######### SPECIFIC CHANNELS CONFIG ###### -;#The following options are specific to each channel and overwrite the generic options - ;######### ACQUISITION GLOBAL CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.coherent_integration_time_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold. It will be ignored if pfa is defined. Acquisition_1C.threshold=0.012 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -256,87 +242,66 @@ Acquisition_1C.doppler_step=250 Acquisition_1C.bit_transition_flag=false ;#max_dwells: Maximum number of consecutive dwells to be processed. It will be ignored if bit_transition_flag=true Acquisition_1C.max_dwells=1 - - -;######### ACQUISITION CHANNELS CONFIG ###### -;#The following options are specific to each channel and overwrite the generic options +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking ;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=40.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=3.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; +;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] +Tracking_1C.early_late_space_chips=0.5; ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=./tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=40.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=3.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; - -;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] -Tracking_1C.early_late_space_chips=0.5; ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;######### OBSERVABLES CONFIG ############ -;#implementation: -Observables.implementation=Hybrid_Observables +;######### OBSERVABLES CONFIG ############ +Observables.implementation=Hybrid_Observables ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ -;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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 - ;# KML, GeoJSON, NMEA and RTCM output configuration - -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./PVT - ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; - ;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) PVT.flag_nmea_tty_port=false; - ;#nmea_dump_devname: serial device descriptor for NMEA logging PVT.nmea_dump_devname=/dev/pts/4 - PVT.flag_rtcm_server=true PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] PVT.dump=false +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT \ No newline at end of file diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf index f95cdba22..34c4e3142 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf @@ -25,26 +25,20 @@ GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=Flexiband_Signal_Source - ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource.item_type=gr_complex - ;# FPGA firmware file SignalSource.firmware_file=flexiband_II-3b.bit - ;#RF_channels: Number of RF channels present in the frontend device, must agree the FPGA firmware file SignalSource.RF_channels=1 - ;#frontend channels gain. Not usable yet! SignalSource.gain1=0 SignalSource.gain2=0 SignalSource.gain3=0 - ;#frontend channels AGC SignalSource.AGC=true - ;# USB 3.0 packet buffer size (number of SuperSpeed packets) SignalSource.usb_packet_buffer=128 @@ -74,16 +68,16 @@ InputFilter0.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, -;#the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter0.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter0.output_item_type=gr_complex -;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. +;#taps_item_type: Type and resolution for the taps of the filter. InputFilter0.taps_item_type=float ;#number_of_taps: Number of taps in the filter. Increasing this parameter increases the processing time @@ -123,8 +117,6 @@ InputFilter0.grid_density=16 ;#The following options are used only in Freq_Xlating_Fir_Filter implementation. ;#InputFilter0.IF is the intermediate frequency (in Hz) shifted down to zero Hz -;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE -; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ InputFilter0.sampling_frequency=40000000 ;# IF deviation due to front-end LO inaccuracies [HZ] InputFilter0.IF=-205000 @@ -153,10 +145,10 @@ InputFilter1.dump=false ;#dump_filename: Log path and filename. InputFilter1.dump_filename=../data/input_filter.dat -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter1.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter1.output_item_type=gr_complex ;######### RESAMPLER CONFIG 1 ############ @@ -180,10 +172,10 @@ InputFilter2.dump=false ;#dump_filename: Log path and filename. InputFilter2.dump_filename=../data/input_filter.dat -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter2.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter2.output_item_type=gr_complex ;######### RESAMPLER CONFIG 2 ############ @@ -197,11 +189,13 @@ Channels_1C.count=8 ;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver Channels.in_acquisition=1 -;# signal: +;#signal: ;# "1C" GPS L1 C/A -;# "2S" GPS L2 L2C (M) ;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL) +;# "1G" GLONASS L1 C/A +;# "2S" GPS L2 L2C (M) ;# "5X" GALILEO E5a I+Q +;# "L5" GPS L5 ;# CHANNEL CONNECTION Channel0.RF_channel_ID=0 @@ -225,24 +219,15 @@ Channel6.signal=1C Channel7.signal=1C -;######### SPECIFIC CHANNELS CONFIG ###### -;#The following options are specific to each channel and overwrite the generic options - ;######### ACQUISITION GLOBAL CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.coherent_integration_time_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold. It will be ignored if pfa is defined. Acquisition_1C.threshold=0.012 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -257,54 +242,43 @@ Acquisition_1C.doppler_step=250 Acquisition_1C.bit_transition_flag=false ;#max_dwells: Maximum number of consecutive dwells to be processed. It will be ignored if bit_transition_flag=true Acquisition_1C.max_dwells=1 - - -;######### ACQUISITION CHANNELS CONFIG ###### -;#The following options are specific to each channel and overwrite the generic options +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking ;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=40.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=3.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; +;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] +Tracking_1C.early_late_space_chips=0.5; ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=./tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=40.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=3.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; - -;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] -Tracking_1C.early_late_space_chips=0.5; ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;#decimation factor -TelemetryDecoder_1C.decimation_factor=1; + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat @@ -312,34 +286,24 @@ Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ ;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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 - ;# KML, GeoJSON, NMEA and RTCM output configuration - -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./PVT - ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; - ;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) PVT.flag_nmea_tty_port=false; - ;#nmea_dump_devname: serial device descriptor for NMEA logging PVT.nmea_dump_devname=/dev/pts/4 - PVT.flag_rtcm_server=true PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] PVT.dump=false +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT \ No newline at end of file diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf index 4860367dc..2bba3f755 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf @@ -25,26 +25,20 @@ GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=Flexiband_Signal_Source - ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource.item_type=gr_complex - ;# FPGA firmware file SignalSource.firmware_file=flexiband_I-1b.bit - ;#RF_channels: Number of RF channels present in the frontend device, must agree the FPGA firmware file SignalSource.RF_channels=1 - ;#frontend channels gain. Not usable yet! SignalSource.gain1=0 SignalSource.gain2=0 SignalSource.gain3=0 - ;#frontend channels AGC SignalSource.AGC=true - ;# USB 3.0 packet buffer size (number of SuperSpeed packets) SignalSource.usb_packet_buffer=128 @@ -74,13 +68,13 @@ InputFilter0.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, -;#the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter0.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter0.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -153,10 +147,10 @@ InputFilter1.dump=false ;#dump_filename: Log path and filename. InputFilter1.dump_filename=../data/input_filter.dat -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter1.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter1.output_item_type=gr_complex ;######### RESAMPLER CONFIG 1 ############ @@ -180,10 +174,10 @@ InputFilter2.dump=false ;#dump_filename: Log path and filename. InputFilter2.dump_filename=../data/input_filter.dat -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter2.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter2.output_item_type=gr_complex ;######### RESAMPLER CONFIG 2 ############ @@ -199,9 +193,11 @@ Channels.in_acquisition=1 ;#signal: ;# "1C" GPS L1 C/A -;# "2S" GPS L2 L2C (M) ;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL) +;# "1G" GLONASS L1 C/A +;# "2S" GPS L2 L2C (M) ;# "5X" GALILEO E5a I+Q +;# "L5" GPS L5 ;# CHANNEL CONNECTION Channel0.RF_channel_ID=0 @@ -220,24 +216,15 @@ Channel1.signal=1C Channel2.signal=1C Channel3.signal=1C -;######### SPECIFIC CHANNELS CONFIG ###### -;#The following options are specific to each channel and overwrite the generic options - ;######### ACQUISITION GLOBAL CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.coherent_integration_time_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold. It will be ignored if pfa is defined. Acquisition_1C.threshold=0.011 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -252,89 +239,65 @@ Acquisition_1C.doppler_step=250 Acquisition_1C.bit_transition_flag=false ;#max_dwells: Maximum number of consecutive dwells to be processed. It will be ignored if bit_transition_flag=true Acquisition_1C.max_dwells=1 - - -;######### ACQUISITION CHANNELS CONFIG ###### -;#The following options are specific to each channel and overwrite the generic options +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking ;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=40.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=3.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; +;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] +Tracking_1C.early_late_space_chips=0.5; ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=./tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=40.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=3.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; - -;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] -Tracking_1C.early_late_space_chips=0.5; ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;#decimation factor -TelemetryDecoder_1C.decimation_factor=1; + ;######### OBSERVABLES CONFIG ############ -;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ -;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version. PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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 - ;# KML, GeoJSON, NMEA and RTCM output configuration - -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./PVT - ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; - ;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) PVT.flag_nmea_tty_port=false; - ;#nmea_dump_devname: serial device descriptor for NMEA logging PVT.nmea_dump_devname=/dev/pts/4 - PVT.flag_rtcm_server=true PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] PVT.dump=false +PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf b/conf/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf index 37a7f89be..48c73a036 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf @@ -25,26 +25,20 @@ GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=Flexiband_Signal_Source - ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource.item_type=gr_complex - ;# FPGA firmware file SignalSource.firmware_file=flexiband_III-1b.bit - ;#RF_channels: Number of RF channels present in the frontend device, must agree the FPGA firmware file SignalSource.RF_channels=2 - ;#frontend channels gain. Not usable yet! SignalSource.gain1=0 SignalSource.gain2=0 SignalSource.gain3=0 - ;#frontend channels AGC SignalSource.AGC=true - ;# USB 3.0 packet buffer size (number of SuperSpeed packets) SignalSource.usb_packet_buffer=128 @@ -78,13 +72,13 @@ InputFilter0.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, -;#the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter0.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter0.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -172,13 +166,13 @@ InputFilter1.dump_filename=../data/input_filter_ch1.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, -;#the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter1.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter1.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -254,10 +248,10 @@ InputFilter2.dump=false ;#dump_filename: Log path and filename. InputFilter2.dump_filename=../data/input_filter.dat -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter2.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter2.output_item_type=gr_complex ;######### RESAMPLER CONFIG 2 ############ @@ -273,12 +267,13 @@ Channels_2S.count=8 ;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver Channels.in_acquisition=1 - ;#signal: ;# "1C" GPS L1 C/A -;# "2S" GPS L2 L2C (M) ;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL) +;# "1G" GLONASS L1 C/A +;# "2S" GPS L2 L2C (M) ;# "5X" GALILEO E5a I+Q +;# "L5" GPS L5 ;# CHANNEL CONNECTION @@ -359,19 +354,13 @@ Channel15.signal=2S ;######### SPECIFIC CHANNELS CONFIG ###### ;#The following options are specific to each channel and overwrite the generic options ;######### ACQUISITION GLOBAL CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.coherent_integration_time_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold. It will be ignored if pfa is defined. Acquisition_1C.threshold=0.008 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -386,112 +375,92 @@ Acquisition_1C.doppler_step=250 Acquisition_1C.bit_transition_flag=false ;#max_dwells: Maximum number of consecutive dwells to be processed. It will be ignored if bit_transition_flag=true Acquisition_1C.max_dwells=1 - - -;######### ACQUISITION CHANNELS CONFIG ###### -;#The following options are specific to each channel and overwrite the generic options +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] - Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking Tracking_1C.item_type=gr_complex Tracking_1C.if=0 -Tracking_1C.dump=true -Tracking_1C.dump_filename=./tracking_ch_ Tracking_1C.pll_bw_hz=40.0; Tracking_1C.dll_bw_hz=3.0; Tracking_1C.order=3; Tracking_1C.early_late_space_chips=0.5; +Tracking_1C.dump=true +Tracking_1C.dump_filename=./tracking_ch_ + ;# GPS L2C M -Acquisition_2S.dump=false -Acquisition_2S.dump_filename=./acq_dump.dat +Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition Acquisition_2S.item_type=gr_complex Acquisition_2S.if=0 -Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition Acquisition_2S.threshold=0.0005 ;Acquisition_2S.pfa=0.001 Acquisition_2S.doppler_max=5000 Acquisition_2S.doppler_min=-5000 Acquisition_2S.doppler_step=30 Acquisition_2S.max_dwells=1 +Acquisition_2S.dump=false +Acquisition_2S.dump_filename=./acq_dump.dat Tracking_2S.implementation=GPS_L2_M_DLL_PLL_Tracking Tracking_2S.item_type=gr_complex Tracking_2S.if=0 -Tracking_2S.dump=true -Tracking_2S.dump_filename=./tracking_ch_ Tracking_2S.pll_bw_hz=1.5; Tracking_2S.dll_bw_hz=0.3; Tracking_2S.order=3; Tracking_2S.early_late_space_chips=0.5; +Tracking_2S.dump=true +Tracking_2S.dump_filename=./tracking_ch_ + ;######### TELEMETRY DECODER GPS L1 CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -TelemetryDecoder_1C.decimation_factor=20; ;######### TELEMETRY DECODER GPS L2 CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L2 M TelemetryDecoder_2S.implementation=GPS_L2C_Telemetry_Decoder TelemetryDecoder_2S.dump=false -TelemetryDecoder_2S.decimation_factor=1; ;######### OBSERVABLES CONFIG ############ -;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ -;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#averaging_depth: Number of PVT observations in the moving average algorithm PVT.averaging_depth=10 - ;#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 - ;# KML, GeoJSON, NMEA and RTCM output configuration - -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./PVT - ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; - ;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) PVT.flag_nmea_tty_port=false; - ;#nmea_dump_devname: serial device descriptor for NMEA logging PVT.nmea_dump_devname=/dev/pts/4 - PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - - ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] PVT.dump=false +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf b/conf/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf index e3c724fad..44be57a15 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf @@ -25,7 +25,7 @@ GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=Flexiband_Signal_Source SignalSource.flag_read_file=true @@ -81,13 +81,13 @@ InputFilter0.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, -;#the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter0.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter0.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -175,13 +175,13 @@ InputFilter1.dump_filename=../data/input_filter_ch1.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, -;#the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter1.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter1.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -257,10 +257,10 @@ InputFilter2.dump=false ;#dump_filename: Log path and filename. InputFilter2.dump_filename=../data/input_filter.dat -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter2.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter2.output_item_type=gr_complex ;######### RESAMPLER CONFIG 2 ############ @@ -278,9 +278,11 @@ Channels.in_acquisition=1 ;#signal: ;# "1C" GPS L1 C/A -;# "2S" GPS L2 L2C (M) ;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL) +;# "1G" GLONASS L1 C/A +;# "2S" GPS L2 L2C (M) ;# "5X" GALILEO E5a I+Q +;# "L5" GPS L5 ;# CHANNEL CONNECTION @@ -305,19 +307,13 @@ Channel15.RF_channel_ID=1 ;######### SPECIFIC CHANNELS CONFIG ###### ;#The following options are specific to each channel and overwrite the generic options ;######### ACQUISITION GLOBAL CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples.. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.coherent_integration_time_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold. It will be ignored if pfa is defined. Acquisition_1C.threshold=0.008 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -332,16 +328,13 @@ Acquisition_1C.doppler_step=250 Acquisition_1C.bit_transition_flag=false ;#max_dwells: Maximum number of consecutive dwells to be processed. It will be ignored if bit_transition_flag=true Acquisition_1C.max_dwells=1 - - -;######### ACQUISITION CHANNELS CONFIG ###### -;#The following options are specific to each channel and overwrite the generic options +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] - Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking Tracking_1C.item_type=gr_complex Tracking_1C.if=0 @@ -353,44 +346,37 @@ Tracking_1C.order=3; Tracking_1C.early_late_space_chips=0.5; ;# GPS L2C M -Acquisition_2S.dump=false -Acquisition_2S.dump_filename=./acq_dump.dat +Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition Acquisition_2S.item_type=gr_complex Acquisition_2S.if=0 -Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition Acquisition_2S.threshold=0.0005 ;Acquisition_2S.pfa=0.001 Acquisition_2S.doppler_max=5000 Acquisition_2S.doppler_min=-5000 Acquisition_2S.doppler_step=30 Acquisition_2S.max_dwells=1 +Acquisition_2S.dump=false +Acquisition_2S.dump_filename=./acq_dump.dat Tracking_2S.implementation=GPS_L2_M_DLL_PLL_Tracking Tracking_2S.item_type=gr_complex Tracking_2S.if=0 -Tracking_2S.dump=true -Tracking_2S.dump_filename=../data/epl_tracking_ch_ Tracking_2S.pll_bw_hz=1.5; Tracking_2S.dll_bw_hz=0.3; Tracking_2S.order=3; Tracking_2S.early_late_space_chips=0.5; +Tracking_2S.dump=true +Tracking_2S.dump_filename=../data/epl_tracking_ch_ ;# GALILEO E1B - - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1B.dump=false -;#filename: Log path and filename -Acquisition_1B.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1B.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1B.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1B.sampled_ms=4 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition ;#threshold: Acquisition threshold ;Acquisition_1B.threshold=0 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -399,100 +385,80 @@ Acquisition_1B.pfa=0.0000005 Acquisition_1B.doppler_max=5000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1B.doppler_step=125 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1B.dump=false +;#filename: Log path and filename +Acquisition_1B.dump_filename=./acq_dump.dat + -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1B.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1B.if=0 - -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1B.dump=false - -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1B.dump_filename=./veml_tracking_ch_ - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1B.pll_bw_hz=15.0; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1B.dll_bw_hz=2.0; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_1B.order=3; - ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo Tracking_1B.early_late_space_chips=0.15; - ;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] Tracking_1B.very_early_late_space_chips=0.6; - +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1B.dump=false +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1B.dump_filename=./veml_tracking_ch_ ;######### TELEMETRY DECODER GPS L1 CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -TelemetryDecoder_1C.decimation_factor=20; ;######### TELEMETRY DECODER GPS L2 CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L2 M TelemetryDecoder_2S.implementation=GPS_L2C_Telemetry_Decoder TelemetryDecoder_2S.dump=false -TelemetryDecoder_2S.decimation_factor=1; ;######### TELEMETRY DECODER GALILEO E1B CONFIG ############ ;#implementation: Use [Galileo_E1B_Telemetry_Decoder] for Galileo E1B TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder TelemetryDecoder_1B.dump=false -TelemetryDecoder_1B.decimation_factor=5; ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ -;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version. PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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=100 - ;# KML, GeoJSON, NMEA and RTCM output configuration - -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./PVT - ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; - ;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) PVT.flag_nmea_tty_port=false; - ;#nmea_dump_devname: serial device descriptor for NMEA logging PVT.nmea_dump_devname=/dev/pts/4 - PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] PVT.dump=false +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT + diff --git a/conf/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf b/conf/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf index 541ef7b8b..c5f32b456 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf @@ -25,21 +25,16 @@ GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=UHD_Signal_Source - ;#When left empty, the device discovery routines will search all vailable transports on the system (ethernet, usb...) SignalSource.device_address=192.168.40.2 ; <- PUT THE IP ADDRESS OF YOUR USRP HERE - -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +;#item_type: Type and resolution for each of the signal samples. SignalSource.item_type=gr_complex - ;#RF_channels: Number of RF channels present in the frontend device (i.e. USRP with two frontends) SignalSource.RF_channels=2 - ;#sampling_frequency: Original Signal sampling frequency in [Hz] SignalSource.sampling_frequency=4000000 - ;#subdevice: UHD subdevice specification (for USRP dual frontend use A:0 or B:0 or A:0 B:0) SignalSource.subdevice=A:0 B:0 @@ -55,10 +50,6 @@ SignalSource.gain0=50 ;#samples: Number of samples to be processed. Notice that 0 indicates no limit SignalSource.samples0=0 -;#dump: Dump the Signal source RF channel data to a file. Disable this option in this version -SignalSource.dump0=false - -SignalSource.dump_filename0=../data/signal_source0.dat ;## RF CHANNEL 1 ## ;#freq: RF front-end center frequency in [Hz] @@ -70,11 +61,6 @@ SignalSource.gain1=50 ;#samples: Number of samples to be processed. Notice that 0 indicates no limit SignalSource.samples1=0 -;#dump: Dump the Signal source RF channel data to a file. Disable this option in this version -SignalSource.dump1=false - -SignalSource.dump_filename1=../data/signal_source1.dat - ;######### SIGNAL_CONDITIONER 0 CONFIG ############ ;## It holds blocks to change data type, filter and resample input data. @@ -107,14 +93,13 @@ InputFilter0.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse -;#reponse given a set of band edges, the desired reponse on those bands, -;#and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter0.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter0.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -199,14 +184,13 @@ InputFilter1.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse -;#reponse given a set of band edges, the desired reponse on those bands, -;#and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter1.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter1.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -276,9 +260,11 @@ Channels.in_acquisition=1 ;#signal: ;# "1C" GPS L1 C/A -;# "2S" GPS L2 L2C (M) ;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL) +;# "1G" GLONASS L1 C/A +;# "2S" GPS L2 L2C (M) ;# "5X" GALILEO E5a I+Q +;# "L5" GPS L5 ;# CHANNEL CONNECTION Channel0.RF_channel_ID=0 @@ -299,19 +285,14 @@ Channel3.signal=1C ;######### ACQUISITION GLOBAL CONFIG ############ - +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.coherent_integration_time_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold. It will be ignored if pfa is defined. Acquisition_1C.threshold=0.01 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -326,87 +307,65 @@ Acquisition_1C.doppler_step=500 Acquisition_1C.bit_transition_flag=false ;#max_dwells: Maximum number of consecutive dwells to be processed. It will be ignored if bit_transition_flag=true Acquisition_1C.max_dwells=1 - - -;######### ACQUISITION CHANNELS CONFIG ###### -;#The following options are specific to each channel and overwrite the generic options +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### TRACKING GLOBAL CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking ;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=40.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=4.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; +;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] +Tracking_1C.early_late_space_chips=0.5; ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=./tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=40.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=4.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; - -;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] -Tracking_1C.early_late_space_chips=0.5; ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;######### OBSERVABLES CONFIG ############ -;#implementation: -Observables.implementation=Hybrid_Observables +;######### OBSERVABLES CONFIG ############ +Observables.implementation=Hybrid_Observables ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ -;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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 - ;# KML, GeoJSON, NMEA and RTCM output configuration - -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./PVT - ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; - ;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) PVT.flag_nmea_tty_port=false; - ;#nmea_dump_devname: serial device descriptor for NMEA logging PVT.nmea_dump_devname=/dev/pts/4 - PVT.flag_rtcm_server=true PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] PVT.dump=false +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf b/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf index 50cd9d1cb..2f601ba41 100644 --- a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf @@ -25,29 +25,22 @@ GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=Flexiband_Signal_Source - SignalSource.flag_read_file=true SignalSource.signal_file=/media/javier/SISTEMA/signals/fraunhofer/L125_III1b_210s.usb ; <- PUT YOUR FILE HERE - ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource.item_type=gr_complex - ;# FPGA firmware file SignalSource.firmware_file=flexiband_III-1b.bit - ;#RF_channels: Number of RF channels present in the frontend device, must agree the FPGA firmware file SignalSource.RF_channels=1 - ;#frontend channels gain. Not usable yet! SignalSource.gain1=0 SignalSource.gain2=0 SignalSource.gain3=0 - ;#frontend channels AGC SignalSource.AGC=true - ;# USB 3.0 packet buffer size (number of SuperSpeed packets) SignalSource.usb_packet_buffer=128 @@ -81,13 +74,13 @@ InputFilter0.dump_filename=../data/input_filter_ch0.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, -;#the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter0.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter0.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -130,11 +123,7 @@ InputFilter0.grid_density=16 ;#The following options are used only in Freq_Xlating_Fir_Filter implementation. ;#InputFilter0.IF is the intermediate frequency (in Hz) shifted down to zero Hz -;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE -; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ InputFilter0.sampling_frequency=20000000 -;# IF deviation due to front-end LO inaccuracies [HZ] -;#InputFilter0.IF=-205000 InputFilter0.IF=0 ;# Decimation factor after the frequency tranaslating block @@ -174,13 +163,13 @@ InputFilter1.dump_filename=../data/input_filter_ch1.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, -;#the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter1.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter1.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -222,9 +211,6 @@ InputFilter1.filter_type=bandpass InputFilter1.grid_density=16 ;#The following options are used only in Freq_Xlating_Fir_Filter implementation. -;#InputFilter0.IF is the intermediate frequency (in Hz) shifted down to zero Hz -;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE -; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ InputFilter1.sampling_frequency=20000000 ;# IF deviation due to front-end LO inaccuracies [HZ] InputFilter1.IF=0 @@ -261,10 +247,10 @@ InputFilter2.dump=false ;#dump_filename: Log path and filename. InputFilter2.dump_filename=../data/input_filter_ch2.dat -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter2.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples.. InputFilter2.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -306,9 +292,6 @@ InputFilter2.filter_type=bandpass InputFilter2.grid_density=16 ;#The following options are used only in Freq_Xlating_Fir_Filter implementation. -;#InputFilter0.IF is the intermediate frequency (in Hz) shifted down to zero Hz -;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE -; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ InputFilter2.sampling_frequency=40000000 ;# IF deviation due to front-end LO inaccuracies [HZ] InputFilter2.IF=0 @@ -334,11 +317,13 @@ Channels_5X.count=0 ;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver Channels.in_acquisition=1 -;# signal: +;#signal: ;# "1C" GPS L1 C/A -;# "2S" GPS L2 L2C (M) ;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL) +;# "1G" GLONASS L1 C/A +;# "2S" GPS L2 L2C (M) ;# "5X" GALILEO E5a I+Q +;# "L5" GPS L5 ;# CHANNEL NUMBERING ORDER: GPS L1 C/A, GPS L2 L2C (M), GALILEO E1 B, GALILEO E5a ;# CHANNEL CONNECTION @@ -388,31 +373,26 @@ Channel39.RF_channel_ID=2 ;#The following options are specific to each channel and overwrite the generic options ;# GPS L1 CA -Acquisition_1C.dump=false -Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.item_type=gr_complex Acquisition_1C.if=0 Acquisition_1C.coherent_integration_time_ms=1 -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.threshold=0.005 Acquisition_1C.doppler_max=5000 Acquisition_1C.doppler_step=250 Acquisition_1C.bit_transition_flag=false Acquisition_1C.max_dwells=1 +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat ;# Galileo E1 -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1B.dump=false -;#filename: Log path and filename -Acquisition_1B.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1B.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1B.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1B.sampled_ms=4 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition ;#threshold: Acquisition threshold ;Acquisition_1B.threshold=0 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -421,29 +401,31 @@ Acquisition_1B.pfa=0.0000002 Acquisition_1B.doppler_max=5000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1B.doppler_step=125 - +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1B.dump=false +;#filename: Log path and filename +Acquisition_1B.dump_filename=./acq_dump.dat ;# GPS L2C M -Acquisition_2S.dump=false -Acquisition_2S.dump_filename=./acq_dump.dat +Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition Acquisition_2S.item_type=gr_complex Acquisition_2S.if=0 -Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition Acquisition_2S.threshold=0.00074 ;Acquisition_2S.pfa=0.001 Acquisition_2S.doppler_max=5000 Acquisition_2S.doppler_min=-5000 Acquisition_2S.doppler_step=60 Acquisition_2S.max_dwells=1 +Acquisition_2S.dump=false +Acquisition_2S.dump_filename=./acq_dump.dat + ;# GALILEO E5a -Acquisition_5X.dump=false -Acquisition_5X.dump_filename=./acq_dump.dat +Acquisition_5X.implementation=Galileo_E5a_Noncoherent_IQ_Acquisition_CAF Acquisition_5X.item_type=gr_complex Acquisition_5X.if=0 Acquisition_5X.coherent_integration_time_ms=1 -Acquisition_5X.implementation=Galileo_E5a_Noncoherent_IQ_Acquisition_CAF Acquisition_5X.threshold=0.009 Acquisition_5X.doppler_max=5000 Acquisition_5X.doppler_step=125 @@ -451,32 +433,29 @@ Acquisition_5X.bit_transition_flag=false Acquisition_5X.max_dwells=1 Acquisition_5X.CAF_window_hz=0 ; **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is desactivated. Recommended value 3000 Hz Acquisition_5X.Zero_padding=0 ; **Only for E5a** Avoids power loss and doppler ambiguity in bit transitions by correlating one code with twice the input data length, ensuring that at least one full code is present without transitions. If set to 1 it is ON, if set to 0 it is OFF. +Acquisition_5X.dump=false +Acquisition_5X.dump_filename=./acq_dump.dat + ;######### TRACKING CONFIG ############ - ;######### GPS L1 C/A GENERIC TRACKING CONFIG ############ Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking Tracking_1C.item_type=gr_complex Tracking_1C.if=0 -Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ Tracking_1C.pll_bw_hz=40.0; Tracking_1C.dll_bw_hz=3.0; Tracking_1C.order=3; Tracking_1C.early_late_space_chips=0.5; +Tracking_1C.dump=false +Tracking_1C.dump_filename=../data/epl_tracking_ch_ + ;######### GALILEO E1 TRK CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1B.item_type=gr_complex ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1B.if=0 -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1B.dump=false -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1B.dump_filename=../data/veml_tracking_ch_ ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1B.pll_bw_hz=15.0; ;#dll_bw_hz: DLL loop filter bandwidth [Hz] @@ -487,24 +466,28 @@ Tracking_1B.order=3; Tracking_1B.early_late_space_chips=0.15; ;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] Tracking_1B.very_early_late_space_chips=0.6; +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1B.dump=false +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1B.dump_filename=../data/veml_tracking_ch_ + ;######### GPS L2C GENERIC TRACKING CONFIG ############ Tracking_2S.implementation=GPS_L2_M_DLL_PLL_Tracking Tracking_2S.item_type=gr_complex Tracking_2S.if=0 -Tracking_2S.dump=false -Tracking_2S.dump_filename=./tracking_ch_ Tracking_2S.pll_bw_hz=2.0; Tracking_2S.dll_bw_hz=0.25; Tracking_2S.order=2; Tracking_2S.early_late_space_chips=0.5; +Tracking_2S.dump=false +Tracking_2S.dump_filename=./tracking_ch_ + ;######### GALILEO E5 TRK CONFIG ############ Tracking_5X.implementation=Galileo_E5a_DLL_PLL_Tracking Tracking_5X.item_type=gr_complex Tracking_5X.if=0 -Tracking_5X.dump=false -Tracking_5X.dump_filename=./tracking_ch_ Tracking_5X.pll_bw_hz_init=20.0; **Only for E5a** PLL loop filter bandwidth during initialization [Hz] Tracking_5X.dll_bw_hz_init=20.0; **Only for E5a** DLL loop filter bandwidth during initialization [Hz] Tracking_5X.ti_ms=1; **Only for E5a** loop filter integration time after initialization (secondary code delay search)[ms] @@ -512,6 +495,9 @@ Tracking_5X.pll_bw_hz=20.0; Tracking_5X.dll_bw_hz=20.0; Tracking_5X.order=2; Tracking_5X.early_late_space_chips=0.5; +Tracking_5X.dump=false +Tracking_5X.dump_filename=./tracking_ch_ + ;######### TELEMETRY DECODER CONFIG ############ TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder @@ -526,8 +512,8 @@ TelemetryDecoder_2S.dump=false TelemetryDecoder_5X.implementation=Galileo_E5a_Telemetry_Decoder TelemetryDecoder_5X.dump=false + ;######### OBSERVABLES CONFIG ############ -;#implementation: Observables.implementation=Hybrid_Observables ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false @@ -536,36 +522,25 @@ Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ -;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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=100 - ;# KML, GeoJSON, NMEA and RTCM output configuration - -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./PVT - ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; - ;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) PVT.flag_nmea_tty_port=false; - ;#nmea_dump_devname: serial device descriptor for NMEA logging PVT.nmea_dump_devname=/dev/pts/4 - PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] PVT.dump=false +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf b/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf index ce8f87a9f..669f734c3 100644 --- a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf +++ b/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf @@ -25,29 +25,22 @@ GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=Flexiband_Signal_Source - SignalSource.flag_read_file=true SignalSource.signal_file=/home/javier/signals/20140923_20-24-17_L125_roof_210s.usb ; <- PUT YOUR FILE HERE - ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource.item_type=gr_complex - ;# FPGA firmware file SignalSource.firmware_file=flexiband_III-1b.bit - ;#RF_channels: Number of RF channels present in the frontend device, must agree the FPGA firmware file SignalSource.RF_channels=2 - ;#frontend channels gain. Not usable yet! SignalSource.gain1=0 SignalSource.gain2=0 SignalSource.gain3=0 - ;#frontend channels AGC SignalSource.AGC=true - ;# USB 3.0 packet buffer size (number of SuperSpeed packets) SignalSource.usb_packet_buffer=128 @@ -81,13 +74,13 @@ InputFilter0.dump_filename=../data/input_filter_ch0.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, -;#the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter0.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter0.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -173,13 +166,13 @@ InputFilter1.dump_filename=../data/input_filter_ch1.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, -;#the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter1.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter1.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -253,10 +246,10 @@ InputFilter2.dump=false ;#dump_filename: Log path and filename. InputFilter2.dump_filename=../data/input_filter.dat -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter2.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter2.output_item_type=gr_complex ;######### RESAMPLER CONFIG 2 ############ @@ -274,11 +267,13 @@ Channels_2S.count=4 ;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver Channels.in_acquisition=1 -;# signal: +;#signal: ;# "1C" GPS L1 C/A -;# "2S" GPS L2 L2C (M) ;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL) +;# "1G" GLONASS L1 C/A +;# "2S" GPS L2 L2C (M) ;# "5X" GALILEO E5a I+Q +;# "L5" GPS L5 ;# CHANNEL NUMBERING ORDER: GPS L1 C/A, GPS L2 L2C (M), GALILEO E1 B, GALILEO E5a ;# CHANNEL CONNECTION @@ -304,108 +299,92 @@ Channel18.RF_channel_ID=1 Channel19.RF_channel_ID=1 -;######### ACQUISITION GENERIC CONFIG ###### -;#The following options are specific to each channel and overwrite the generic options - -Acquisition_1C.dump=false -Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.item_type=gr_complex Acquisition_1C.if=0 Acquisition_1C.coherent_integration_time_ms=1 -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.threshold=0.005 Acquisition_1C.doppler_max=5000 Acquisition_1C.doppler_step=250 Acquisition_1C.bit_transition_flag=false Acquisition_1C.max_dwells=1 +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat + ;# GPS L2C M -Acquisition_2S.dump=false -Acquisition_2S.dump_filename=./acq_dump.dat +Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition Acquisition_2S.item_type=gr_complex Acquisition_2S.if=0 -Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition Acquisition_2S.threshold=0.00074 ;Acquisition_2S.pfa=0.001 Acquisition_2S.doppler_max=5000 Acquisition_2S.doppler_min=-5000 Acquisition_2S.doppler_step=60 Acquisition_2S.max_dwells=1 +Acquisition_2S.dump=false +Acquisition_2S.dump_filename=./acq_dump.dat ;######### TRACKING CONFIG ############ - ;######### GPS L1 C/A GENERIC TRACKING CONFIG ############ Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking Tracking_1C.item_type=gr_complex Tracking_1C.if=0 -Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ Tracking_1C.pll_bw_hz=40.0; Tracking_1C.dll_bw_hz=3.0; Tracking_1C.order=3; Tracking_1C.early_late_space_chips=0.5; +Tracking_1C.dump=false +Tracking_1C.dump_filename=../data/epl_tracking_ch_ ;######### GPS L2C GENERIC TRACKING CONFIG ############ Tracking_2S.implementation=GPS_L2_M_DLL_PLL_Tracking Tracking_2S.item_type=gr_complex Tracking_2S.if=0 -Tracking_2S.dump=false -Tracking_2S.dump_filename=./tracking_ch_ Tracking_2S.pll_bw_hz=2.0; Tracking_2S.dll_bw_hz=0.25; Tracking_2S.order=2; Tracking_2S.early_late_space_chips=0.5; +Tracking_2S.dump=false +Tracking_2S.dump_filename=./tracking_ch_ ;######### TELEMETRY DECODER CONFIG ############ TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -TelemetryDecoder_1C.decimation_factor=20; + TelemetryDecoder_2S.implementation=GPS_L2C_Telemetry_Decoder TelemetryDecoder_2S.dump=false -TelemetryDecoder_2S.decimation_factor=1; ;######### OBSERVABLES CONFIG ############ -;#implementation: Observables.implementation=Hybrid_Observables ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=true - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ -;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - ;#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=100 - ;# KML, GeoJSON, NMEA and RTCM output configuration - -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./PVT - ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; - ;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) PVT.flag_nmea_tty_port=false; - ;#nmea_dump_devname: serial device descriptor for NMEA logging PVT.nmea_dump_devname=/dev/pts/4 - PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] PVT.dump=false +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT \ No newline at end of file diff --git a/conf/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf b/conf/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf index e03a01dbe..dece9c9e4 100644 --- a/conf/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf +++ b/conf/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf @@ -25,29 +25,22 @@ GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource.implementation=Flexiband_Signal_Source - SignalSource.flag_read_file=true SignalSource.signal_file=/media/javier/SISTEMA/signals/fraunhofer/L125_III1b_210s.usb ; <- PUT YOUR FILE HERE - ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource.item_type=gr_complex - ;# FPGA firmware file SignalSource.firmware_file=flexiband_III-1b.bit - ;#RF_channels: Number of RF channels present in the frontend device, must agree the FPGA firmware file SignalSource.RF_channels=3 - ;#frontend channels gain. Not usable yet! SignalSource.gain1=0 SignalSource.gain2=0 SignalSource.gain3=0 - ;#frontend channels AGC SignalSource.AGC=true - ;# USB 3.0 packet buffer size (number of SuperSpeed packets) SignalSource.usb_packet_buffer=128 @@ -81,13 +74,13 @@ InputFilter0.dump_filename=../data/input_filter_ch0.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, -;#the desired reponse on those bands, and the weight given to the error in those bands. +;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse reaponse given a set of band edges, +;#the desired reaponse on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter0.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter0.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -174,16 +167,16 @@ InputFilter1.dump_filename=../data/input_filter_ch1.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, -;#the desired reponse on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter1.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter1.output_item_type=gr_complex -;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. +;#taps_item_type: Type and resolution for the taps of the filter. InputFilter1.taps_item_type=float ;#number_of_taps: Number of taps in the filter. Increasing this parameter increases the processing time @@ -261,10 +254,10 @@ InputFilter2.dump=false ;#dump_filename: Log path and filename. InputFilter2.dump_filename=../data/input_filter_ch2.dat -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter2.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter2.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -334,12 +327,13 @@ Channels_5X.count=10 ;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver Channels.in_acquisition=1 -;# signal: +;#signal: ;# "1C" GPS L1 C/A -;# "2S" GPS L2 L2C (M) ;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL) +;# "1G" GLONASS L1 C/A +;# "2S" GPS L2 L2C (M) ;# "5X" GALILEO E5a I+Q -;# CHANNEL NUMBERING ORDER: GPS L1 C/A, GPS L2 L2C (M), GALILEO E1 B, GALILEO E5a +;# "L5" GPS L5 ;# CHANNEL CONNECTION @@ -388,31 +382,27 @@ Channel39.RF_channel_ID=2 ;#The following options are specific to each channel and overwrite the generic options ;# GPS L1 CA -Acquisition_1C.dump=false -Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.item_type=gr_complex Acquisition_1C.if=0 Acquisition_1C.coherent_integration_time_ms=1 -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.threshold=0.005 Acquisition_1C.doppler_max=5000 Acquisition_1C.doppler_step=250 Acquisition_1C.bit_transition_flag=false Acquisition_1C.max_dwells=1 +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat + ;# Galileo E1 -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1B.dump=false -;#filename: Log path and filename -Acquisition_1B.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1B.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1B.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1B.sampled_ms=4 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition ;#threshold: Acquisition threshold ;Acquisition_1B.threshold=0 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -421,29 +411,31 @@ Acquisition_1B.pfa=0.0000002 Acquisition_1B.doppler_max=5000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1B.doppler_step=125 - +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1B.dump=false +;#filename: Log path and filename +Acquisition_1B.dump_filename=./acq_dump.dat ;# GPS L2C M -Acquisition_2S.dump=false -Acquisition_2S.dump_filename=./acq_dump.dat +Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition Acquisition_2S.item_type=gr_complex Acquisition_2S.if=0 -Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition Acquisition_2S.threshold=0.00074 ;Acquisition_2S.pfa=0.001 Acquisition_2S.doppler_max=5000 Acquisition_2S.doppler_min=-5000 Acquisition_2S.doppler_step=60 Acquisition_2S.max_dwells=1 +Acquisition_2S.dump=false +Acquisition_2S.dump_filename=./acq_dump.dat + ;# GALILEO E5a -Acquisition_5X.dump=false -Acquisition_5X.dump_filename=./acq_dump.dat +Acquisition_5X.implementation=Galileo_E5a_Noncoherent_IQ_Acquisition_CAF Acquisition_5X.item_type=gr_complex Acquisition_5X.if=0 Acquisition_5X.coherent_integration_time_ms=1 -Acquisition_5X.implementation=Galileo_E5a_Noncoherent_IQ_Acquisition_CAF Acquisition_5X.threshold=0.009 Acquisition_5X.doppler_max=5000 Acquisition_5X.doppler_step=125 @@ -451,32 +443,28 @@ Acquisition_5X.bit_transition_flag=false Acquisition_5X.max_dwells=1 Acquisition_5X.CAF_window_hz=0 ; **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is desactivated. Recommended value 3000 Hz Acquisition_5X.Zero_padding=0 ; **Only for E5a** Avoids power loss and doppler ambiguity in bit transitions by correlating one code with twice the input data length, ensuring that at least one full code is present without transitions. If set to 1 it is ON, if set to 0 it is OFF. +Acquisition_5X.dump=false +Acquisition_5X.dump_filename=./acq_dump.dat + ;######### TRACKING CONFIG ############ - ;######### GPS L1 C/A GENERIC TRACKING CONFIG ############ Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking Tracking_1C.item_type=gr_complex Tracking_1C.if=0 -Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ Tracking_1C.pll_bw_hz=35.0; Tracking_1C.dll_bw_hz=2.0; Tracking_1C.order=3; Tracking_1C.early_late_space_chips=0.5; +Tracking_1C.dump=false +Tracking_1C.dump_filename=../data/epl_tracking_ch_ ;######### GALILEO E1 TRK CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1B.item_type=gr_complex ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1B.if=0 -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1B.dump=false -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1B.dump_filename=../data/veml_tracking_ch_ ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1B.pll_bw_hz=15.0; ;#dll_bw_hz: DLL loop filter bandwidth [Hz] @@ -487,24 +475,28 @@ Tracking_1B.order=3; Tracking_1B.early_late_space_chips=0.15; ;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] Tracking_1B.very_early_late_space_chips=0.6; +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1B.dump=false +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1B.dump_filename=../data/veml_tracking_ch_ + ;######### GPS L2C GENERIC TRACKING CONFIG ############ Tracking_2S.implementation=GPS_L2_M_DLL_PLL_Tracking Tracking_2S.item_type=gr_complex Tracking_2S.if=0 -Tracking_2S.dump=false -Tracking_2S.dump_filename=./tracking_ch_ Tracking_2S.pll_bw_hz=2.0; Tracking_2S.dll_bw_hz=0.25; Tracking_2S.order=2; Tracking_2S.early_late_space_chips=0.5; +Tracking_2S.dump=false +Tracking_2S.dump_filename=./tracking_ch_ + ;######### GALILEO E5 TRK CONFIG ############ Tracking_5X.implementation=Galileo_E5a_DLL_PLL_Tracking Tracking_5X.item_type=gr_complex Tracking_5X.if=0 -Tracking_5X.dump=false -Tracking_5X.dump_filename=./tracking_ch_ Tracking_5X.pll_bw_hz_init=20.0; **Only for E5a** PLL loop filter bandwidth during initialization [Hz] Tracking_5X.dll_bw_hz_init=20.0; **Only for E5a** DLL loop filter bandwidth during initialization [Hz] Tracking_5X.ti_ms=1; **Only for E5a** loop filter integration time after initialization (secondary code delay search)[ms] @@ -512,6 +504,9 @@ Tracking_5X.pll_bw_hz=20.0; Tracking_5X.dll_bw_hz=20.0; Tracking_5X.order=2; Tracking_5X.early_late_space_chips=0.5; +Tracking_5X.dump=false +Tracking_5X.dump_filename=./tracking_ch_ + ;######### TELEMETRY DECODER CONFIG ############ TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder @@ -526,6 +521,7 @@ TelemetryDecoder_2S.dump=false TelemetryDecoder_5X.implementation=Galileo_E5a_Telemetry_Decoder TelemetryDecoder_5X.dump=false + ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables @@ -538,34 +534,24 @@ Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ ;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad - ;#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=10 - ;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms. PVT.display_rate_ms=100 - ;# KML, GeoJSON, NMEA and RTCM output configuration - -;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./PVT - ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; - ;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one) PVT.flag_nmea_tty_port=false; - ;#nmea_dump_devname: serial device descriptor for NMEA logging PVT.nmea_dump_devname=/dev/pts/4 - PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] PVT.dump=false +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT diff --git a/conf/gnss-sdr_multisource_Hybrid_ishort.conf b/conf/gnss-sdr_multisource_Hybrid_ishort.conf index 71571955e..3aa7f840b 100644 --- a/conf/gnss-sdr_multisource_Hybrid_ishort.conf +++ b/conf/gnss-sdr_multisource_Hybrid_ishort.conf @@ -14,61 +14,35 @@ Receiver.sources_count=2 ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false - -;#repeat: Repeat the processing file. Disable this option in this version +;#repeat: Repeat the processing file. SignalSource.repeat=false ;######### SIGNAL_SOURCE 0 CONFIG ############ - -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) SignalSource0.implementation=File_Signal_Source - ;#filename: path to file with the captured GNSS signal samples to be processed SignalSource0.filename=/datalogger/signals/CTTC/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ; <- PUT YOUR FILE HERE - ;#item_type: Type and resolution for each of the signal samples. SignalSource0.item_type=ishort - -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource0.sampling_frequency=4000000 - -;#freq: RF front-end center frequency in [Hz] -SignalSource0.freq=1575420000 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource0.samples=0 -;#dump: Dump the Signal source data to a file. Disable this option in this version -SignalSource0.dump=false - -SignalSource0.dump_filename=../data/signal_source.dat ;######### SIGNAL_SOURCE 1 CONFIG ############ - -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) SignalSource1.implementation=File_Signal_Source - ;#filename: path to file with the captured GNSS signal samples to be processed SignalSource1.filename=/datalogger/signals/CTTC/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ; <- PUT YOUR FILE HERE - ;#item_type: Type and resolution for each of the signal samples. SignalSource1.item_type=ishort - ;#sampling_frequency: Original Signal sampling frequency in [Hz] SignalSource1.sampling_frequency=4000000 - ;#freq: RF front-end center frequency in [Hz] SignalSource1.freq=1575420000 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource1.samples=0 -;#dump: Dump the Signal source data to a file. Disable this option in this version -SignalSource1.dump=false - -SignalSource1.dump_filename=../data/signal_source.dat - ;######### SIGNAL_CONDITIONER 0 CONFIG ############ ;## It holds blocks to change data type, filter and resample input data. @@ -101,12 +75,13 @@ InputFilter0.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of GNU Radio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, the desired response on those bands, and the weight given to the error in those bands. +;;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter0.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter0.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -167,7 +142,7 @@ Resampler1.dump=false ;#dump_filename: Log path and filename. Resampler1.dump_filename=../data/resampler.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +;#item_type: Type and resolution for each of the signal samples. Resampler1.item_type=gr_complex ;#sample_freq_in: the sample frequency of the input signal @@ -185,7 +160,7 @@ Resampler1.sample_freq_out=4000000 SignalConditioner1.implementation=Signal_Conditioner ;######### DATA_TYPE_ADAPTER 1 CONFIG ############ -;## Changes the type of input data. Please disable it in this version. +;## Changes the type of input data. ;#implementation: [Pass_Through] disables this block DataTypeAdapter1.implementation=Ishort_To_Complex @@ -207,12 +182,13 @@ InputFilter1.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of GNU Radio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, the desired response on those bands, and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter1.input_item_type=gr_complex -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter1.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -273,7 +249,7 @@ Resampler1.dump=false ;#dump_filename: Log path and filename. Resampler1.dump_filename=../data/resampler.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +;#item_type: Type and resolution for each of the signal samples. Resampler1.item_type=gr_complex ;#sample_freq_in: the sample frequency of the input signal @@ -303,19 +279,13 @@ Channel.signal=1B ;######### GPS ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.sampled_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold Acquisition_1C.threshold=0.0075 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -324,22 +294,20 @@ Acquisition_1C.threshold=0.0075 Acquisition_1C.doppler_max=10000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1C.doppler_step=500 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### GALILEO ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1B.dump=false -;#filename: Log path and filename -Acquisition_1B.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1B.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1B.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1B.sampled_ms=4 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition ;#threshold: Acquisition threshold ;Acquisition_1B.threshold=0 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -348,70 +316,57 @@ Acquisition_1B.pfa=0.0000008 Acquisition_1B.doppler_max=15000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1B.doppler_step=125 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1B.dump=false +;#filename: Log path and filename +Acquisition_1B.dump_filename=./acq_dump.dat + ;######### TRACKING GPS CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=45.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=4.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=../data/epl_tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=45.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=4.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; ;######### TRACKING GALILEO CONFIG ############ - -;#implementation: Selected tracking algorithm: [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1B.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1B.if=0 - -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1B.dump=false - -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1B.dump_filename=../data/veml_tracking_ch_ - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1B.pll_bw_hz=15.0; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1B.dll_bw_hz=2.0; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_1B.order=3; - ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo Tracking_1B.early_late_space_chips=0.15; - ;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] Tracking_1B.very_early_late_space_chips=0.6; +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1B.dump=false +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1B.dump_filename=../data/veml_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;#decimation factor -TelemetryDecoder_1C.decimation_factor=4; + ;######### TELEMETRY DECODER GALILEO CONFIG ############ ;#implementation: Use [Galileo_E1B_Telemetry_Decoder] for Galileo E1B @@ -422,10 +377,8 @@ TelemetryDecoder_1B.dump=false ;######### OBSERVABLES CONFIG ############ ;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat @@ -433,19 +386,14 @@ Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ ;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - ;#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 - PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - ;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. PVT.dump_filename=./PVT +;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] +PVT.dump=false diff --git a/conf/gnss-sdr_multisource_Hybrid_nsr.conf b/conf/gnss-sdr_multisource_Hybrid_nsr.conf index deee952af..5a543018e 100644 --- a/conf/gnss-sdr_multisource_Hybrid_nsr.conf +++ b/conf/gnss-sdr_multisource_Hybrid_nsr.conf @@ -17,65 +17,35 @@ GNSS-SDR.internal_fs_sps=2560000 ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false - -;#repeat: Repeat the processing file. Disable this option in this version +;#repeat: Repeat the processing file. SignalSource.repeat=false ;######### SIGNAL_SOURCE 0 CONFIG ############ -;#implementation: Use [File_Signal_Source] [Nsr_File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +;#implementation SignalSource0.implementation=Nsr_File_Signal_Source - ;#filename: path to file with the captured GNSS signal samples to be processed SignalSource0.filename=/datalogger/signals/ifen/E1L1_FE0_Band0.stream ; <- PUT YOUR FILE HERE - ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource0.item_type=byte - -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource0.sampling_frequency=20480000 - -;#freq: RF front-end center frequency in [Hz] -SignalSource0.freq=1575420000 - -;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0) -SignalSource0.subdevice=B:0 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource0.samples=0 -;#dump: Dump the Signal source data to a file. Disable this option in this version -SignalSource0.dump=false - -SignalSource0.dump_filename=../data/signal_source.dat ;######### SIGNAL_SOURCE 1 CONFIG ############ ;#implementation: Use [File_Signal_Source] [Nsr_File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) SignalSource1.implementation=Nsr_File_Signal_Source - ;#filename: path to file with the captured GNSS signal samples to be processed SignalSource1.filename=/datalogger/signals/ifen/E1L1_FE0_Band0.stream - ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource1.item_type=byte - -;#sampling_frequency: Original Signal sampling frequency in [Hz] +;#sampling_frequency: Original Signal sampling frequency in samples per second SignalSource1.sampling_frequency=20480000 - -;#freq: RF front-end center frequency in [Hz] -SignalSource1.freq=1575420000 - -;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0) -SignalSource1.subdevice=B:0 - ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource1.samples=0 -;#dump: Dump the Signal source data to a file. Disable this option in this version -SignalSource1.dump=false - -SignalSource1.dump_filename=../data/signal_source.dat - ;######### SIGNAL_CONDITIONER 0 CONFIG ############ ;## It holds blocks to change data type, filter and resample input data. @@ -108,14 +78,13 @@ InputFilter0.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse -;#reponse given a set of band edges, the desired reponse on those bands, -;#and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter0.input_item_type=float -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter0.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -206,14 +175,13 @@ InputFilter1.dump_filename=../data/input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. -;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse -;#reponse given a set of band edges, the desired reponse on those bands, -;#and the weight given to the error in those bands. +;#This function calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response given a set of band edges, +;#the desired response on those bands, and the weight given to the error in those bands. -;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +;#input_item_type: Type and resolution for input signal samples. InputFilter1.input_item_type=float -;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +;#outut_item_type: Type and resolution for output filtered signal samples. InputFilter1.output_item_type=gr_complex ;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. @@ -284,9 +252,11 @@ Channels.in_acquisition=1 ;#signal: ;# "1C" GPS L1 C/A -;# "2S" GPS L2 L2C (M) ;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL) +;# "1G" GLONASS L1 C/A +;# "2S" GPS L2 L2C (M) ;# "5X" GALILEO E5a I+Q +;# "L5" GPS L5 ;# SOURCE CONNECTION Channel0.RF_channel_ID=0 @@ -328,19 +298,13 @@ Channel15.signal=1B ;######### GPS ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1C.dump=false -;#filename: Log path and filename -Acquisition_1C.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1C.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1C.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1C.sampled_ms=1 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold Acquisition_1C.threshold=0.0075 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -349,22 +313,20 @@ Acquisition_1C.threshold=0.0075 Acquisition_1C.doppler_max=10000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1C.doppler_step=500 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat ;######### GALILEO ACQUISITION CONFIG ############ - -;#dump: Enable or disable the acquisition internal data file logging [true] or [false] -Acquisition_1B.dump=false -;#filename: Log path and filename -Acquisition_1B.dump_filename=./acq_dump.dat -;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +;#item_type: Type and resolution for each of the signal samples. Acquisition_1B.item_type=gr_complex ;#if: Signal intermediate frequency in [Hz] Acquisition_1B.if=0 ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition_1B.sampled_ms=4 -;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] -Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition ;#threshold: Acquisition threshold ;Acquisition_1B.threshold=0 ;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] @@ -373,105 +335,81 @@ Acquisition_1B.pfa=0.0000002 Acquisition_1B.doppler_max=15000 ;#doppler_max: Doppler step in the grid search [Hz] Acquisition_1B.doppler_step=125 +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1B.dump=false +;#filename: Log path and filename +Acquisition_1B.dump_filename=./acq_dump.dat + ;######### TRACKING GPS CONFIG ############ - -;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking ;#item_type: Type and resolution for each of the signal samples. Tracking_1C.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1C.if=0 - +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=45.0; +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=2.0; +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; ;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] Tracking_1C.dump=false - ;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. Tracking_1C.dump_filename=../data/epl_tracking_ch_ -;#pll_bw_hz: PLL loop filter bandwidth [Hz] -Tracking_1C.pll_bw_hz=45.0; - -;#dll_bw_hz: DLL loop filter bandwidth [Hz] -Tracking_1C.dll_bw_hz=2.0; - -;#order: PLL/DLL loop filter order [2] or [3] -Tracking_1C.order=3; ;######### TRACKING GALILEO CONFIG ############ - -;#implementation: Selected tracking algorithm: [Galileo_E1_DLL_PLL_VEML_Tracking] Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking -;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +;#item_type: Type and resolution for each of the signal samples. Tracking_1B.item_type=gr_complex - ;#sampling_frequency: Signal Intermediate Frequency in [Hz] Tracking_1B.if=0 - -;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] -Tracking_1B.dump=false - -;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. -Tracking_1B.dump_filename=../data/veml_tracking_ch_ - ;#pll_bw_hz: PLL loop filter bandwidth [Hz] Tracking_1B.pll_bw_hz=15.0; - ;#dll_bw_hz: DLL loop filter bandwidth [Hz] Tracking_1B.dll_bw_hz=2.0; - ;#order: PLL/DLL loop filter order [2] or [3] Tracking_1B.order=3; - ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo Tracking_1B.early_late_space_chips=0.15; - ;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] Tracking_1B.very_early_late_space_chips=0.6; +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1B.dump=false +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1B.dump_filename=../data/veml_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false -;#decimation factor -TelemetryDecoder_1C.decimation_factor=1; + ;######### TELEMETRY DECODER GALILEO CONFIG ############ ;#implementation: Use [Galileo_E1B_Telemetry_Decoder] for Galileo E1B TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder -TelemetryDecoder_1B.dump=false -TelemetryDecoder_1B.decimation_factor=4; ;######### OBSERVABLES CONFIG ############ -;#implementation: Observables.implementation=Hybrid_Observables - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false - ;#dump_filename: Log path and filename. Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ -;#implementation: Position Velocity and Time (PVT) implementation: PVT.implementation=RTKLIB_PVT - ;#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=10; - ;#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 - PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 - ;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. PVT.dump_filename=./PVT +;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] +PVT.dump=false diff --git a/src/algorithms/PVT/adapters/rtklib_pvt.cc b/src/algorithms/PVT/adapters/rtklib_pvt.cc index e04dd0765..c21303ab3 100644 --- a/src/algorithms/PVT/adapters/rtklib_pvt.cc +++ b/src/algorithms/PVT/adapters/rtklib_pvt.cc @@ -84,17 +84,24 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, unsigned short rtcm_station_id = configuration->property(role + ".rtcm_station_id", 1234); // RTCM message rates: least common multiple with output_rate_ms int rtcm_MT1019_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1019_rate_ms", 5000), output_rate_ms); + int rtcm_MT1020_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1020_rate_ms", 5000), output_rate_ms); int rtcm_MT1045_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1045_rate_ms", 5000), output_rate_ms); int rtcm_MSM_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MSM_rate_ms", 1000), output_rate_ms); int rtcm_MT1077_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1077_rate_ms", rtcm_MSM_rate_ms), output_rate_ms); + int rtcm_MT1087_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1087_rate_ms", rtcm_MSM_rate_ms), output_rate_ms); int rtcm_MT1097_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1097_rate_ms", rtcm_MSM_rate_ms), output_rate_ms); std::map rtcm_msg_rate_ms; rtcm_msg_rate_ms[1019] = rtcm_MT1019_rate_ms; + rtcm_msg_rate_ms[1020] = rtcm_MT1020_rate_ms; rtcm_msg_rate_ms[1045] = rtcm_MT1045_rate_ms; for (int k = 1071; k < 1078; k++) // All GPS MSM { rtcm_msg_rate_ms[k] = rtcm_MT1077_rate_ms; } + for (int k = 1081; k < 1088; k++) // All GLONASS MSM + { + rtcm_msg_rate_ms[k] = rtcm_MT1087_rate_ms; + } for (int k = 1091; k < 1098; k++) // All Galileo MSM { rtcm_msg_rate_ms[k] = rtcm_MT1097_rate_ms; @@ -138,41 +145,54 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, * 20 | GPS L5 + Galileo E5b * 21 | GPS L1 C/A + Galileo E1B + GPS L2C * 22 | GPS L1 C/A + Galileo E1B + GPS L5 + * 23 | GLONASS L1 C/A + * 24 | GLONASS L2 C/A + * 25 | GLONASS L1 C/A + GLONASS L2 C/A + * 26 | GPS L1 C/A + GLONASS L1 C/A + * 27 | Galileo E1B + GLONASS L1 C/A + * 28 | GPS L2C + GLONASS L1 C/A */ int gps_1C_count = configuration->property("Channels_1C.count", 0); int gps_2S_count = configuration->property("Channels_2S.count", 0); int gps_L5_count = configuration->property("Channels_L5.count", 0); int gal_1B_count = configuration->property("Channels_1B.count", 0); - int gal_E5a_count = configuration->property("Channels_5X.count", 0); // GPS L5 or Galileo E5a ? + int gal_E5a_count = configuration->property("Channels_5X.count", 0); int gal_E5b_count = configuration->property("Channels_7X.count", 0); + int glo_1G_count = configuration->property("Channels_1G.count", 0); unsigned int type_of_receiver = 0; + // *******************WARNING!!!!!!!*********** // GPS L5 only configurable for single frequency, single system at the moment!!!!!! - if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 1; - if( (gps_1C_count == 0) && (gps_2S_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 2; - if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 3; - if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 4; - if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0)) type_of_receiver = 5; - if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0)) type_of_receiver = 6; + if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 1; + if( (gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 2; + if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 3; + if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 4; + if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 5; + if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0)) type_of_receiver = 6; - if( (gps_1C_count != 0) && (gps_2S_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 7; - //if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 8; - if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 9; - if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0)) type_of_receiver = 10; - if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0)) type_of_receiver = 11; - if( (gps_1C_count == 0) && (gps_2S_count != 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 12; + if( (gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 7; + //if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 8; + if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 9; + if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 10; + if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0)) type_of_receiver = 11; + if( (gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 12; //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 13; - if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count != 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0)) type_of_receiver = 14; - if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0)) type_of_receiver = 15; - //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 16; - if( (gps_1C_count == 0) && (gps_2S_count != 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0)) type_of_receiver = 17; - if( (gps_1C_count == 0) && (gps_2S_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0)) type_of_receiver = 18; - //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 19; - //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 20; - if( (gps_1C_count != 0) && (gps_2S_count != 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 21; - //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count = 0)) type_of_receiver = 22; - + if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 14; + if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0)) type_of_receiver = 15; + //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 16; + if( (gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 17; + if( (gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0)) type_of_receiver = 18; + //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 19; + //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 20; + if( (gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0)) type_of_receiver = 21; + //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count = 0)) type_of_receiver = 22; + if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) type_of_receiver = 23; + //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2R_count != 0)) type_of_receiver = 24; + //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_1G_count != 0)) type_of_receiver = 25; + if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) type_of_receiver = 26; + if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) type_of_receiver = 27; + if( (gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) type_of_receiver = 28; //RTKLIB PVT solver options // Settings 1 int positioning_mode = -1; @@ -195,9 +215,12 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, } int num_bands = 0; - if ((gps_1C_count > 0) || (gal_1B_count > 0)) num_bands = 1; - if (gps_2S_count > 0) num_bands = 2; - if ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0)) num_bands = 3; + + if ((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) num_bands = 1; + if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && (gps_2S_count > 0) ) num_bands = 2; + if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0))) num_bands = 2; + if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && (gps_2S_count > 0) && ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0))) num_bands = 3; + int number_of_frequencies = configuration->property(role + ".num_bands", num_bands); /* (1:L1, 2:L1+L2, 3:L1+L2+L5) */ if( (number_of_frequencies < 1) || (number_of_frequencies > 3) ) { @@ -209,6 +232,7 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, if( (elevation_mask < 0.0) || (elevation_mask > 90.0) ) { //warn user and set the default + LOG(WARNING) << "Erroneous Elevation Mask. Setting to default value of 15.0 degrees"; elevation_mask = 15.0; } @@ -216,6 +240,7 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, if( (dynamics_model < 0) || (dynamics_model > 2) ) { //warn user and set the default + LOG(WARNING) << "Erroneous Dynamics Model configuration. Setting to default value of (0:none)"; dynamics_model = 0; } @@ -277,10 +302,12 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, int nsys = 0; if ((gps_1C_count > 0) || (gps_2S_count > 0) || (gps_L5_count > 0)) nsys += SYS_GPS; if ((gal_1B_count > 0) || (gal_E5a_count > 0) || (gal_E5b_count > 0)) nsys += SYS_GAL; + if ((glo_1G_count > 0)) nsys += SYS_GLO; int navigation_system = configuration->property(role + ".navigation_system", nsys); /* (SYS_XXX) see src/algorithms/libs/rtklib/rtklib.h */ if( (navigation_system < 1) || (navigation_system > 255) ) /* GPS: 1 SBAS: 2 GPS+SBAS: 3 Galileo: 8 Galileo+GPS: 9 GPS+SBAS+Galileo: 11 All: 255 */ { //warn user and set the default + LOG(WARNING) << "Erroneous Navigation System. Setting to default value of (0:none)"; navigation_system = nsys; } @@ -307,6 +334,7 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, if( (integer_ambiguity_resolution_glo < 0) || (integer_ambiguity_resolution_glo > 3) ) { //warn user and set the default + LOG(WARNING) << "Erroneous Integer Ambiguity Resolution for GLONASS . Setting to default value of (1:on)"; integer_ambiguity_resolution_glo = 1; } @@ -314,6 +342,7 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, if( (integer_ambiguity_resolution_bds < 0) || (integer_ambiguity_resolution_bds > 1) ) { //warn user and set the default + LOG(WARNING) << "Erroneous Integer Ambiguity Resolution for BEIDOU . Setting to default value of (1:on)"; integer_ambiguity_resolution_bds = 1; } diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc index 5824e8493..85290da73 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc @@ -181,6 +181,38 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) DLOG(INFO) << "New Galileo Almanac has arrived "; } + //**************** GLONASS GNAV Telemetry ************************** + else if(pmt::any_ref(msg).type() == typeid(std::shared_ptr) ) + { + // ### GLONASS GNAV EPHEMERIS ### + std::shared_ptr glonass_gnav_eph; + glonass_gnav_eph = boost::any_cast>(pmt::any_ref(msg)); + // TODO Add GLONASS with gps week number and tow, + // insert new ephemeris record + DLOG(INFO) << "GLONASS GNAV New Ephemeris record inserted in global map with TOW =" << glonass_gnav_eph->d_TOW + << ", Week Number =" << glonass_gnav_eph->d_WN + << " and Ephemeris IOD in UTC = " << glonass_gnav_eph->compute_GLONASS_time(glonass_gnav_eph->d_t_b) + << " from SV = " << glonass_gnav_eph->i_satellite_slot_number; + // update/insert new ephemeris record to the global ephemeris map + d_ls_pvt->glonass_gnav_ephemeris_map[glonass_gnav_eph->i_satellite_PRN] = *glonass_gnav_eph; + } + else if(pmt::any_ref(msg).type() == typeid(std::shared_ptr) ) + { + // ### GLONASS GNAV UTC MODEL ### + std::shared_ptr glonass_gnav_utc_model; + glonass_gnav_utc_model = boost::any_cast>(pmt::any_ref(msg)); + d_ls_pvt->glonass_gnav_utc_model = *glonass_gnav_utc_model; + DLOG(INFO) << "New GLONASS GNAV UTC record has arrived "; + } + else if(pmt::any_ref(msg).type() == typeid(std::shared_ptr) ) + { + // ### GLONASS GNAV Almanac ### + std::shared_ptr glonass_gnav_almanac; + glonass_gnav_almanac = boost::any_cast>(pmt::any_ref(msg)); + d_ls_pvt->glonass_gnav_almanac = *glonass_gnav_almanac; + DLOG(INFO) << "New GLONASS GNAV Almanac has arrived " + << ", GLONASS GNAV Slot Number =" << glonass_gnav_almanac->d_n_A; + } else { LOG(WARNING) << "msg_handler_telemetry unknown object type!"; @@ -249,6 +281,14 @@ rtklib_pvt_cc::rtklib_pvt_cc(unsigned int nchannels, bool dump, std::string dump { d_rtcm_MT1019_rate_ms = boost::math::lcm(5000, d_output_rate_ms); // default value if not set } + if(rtcm_msg_rate_ms.find(1020) != rtcm_msg_rate_ms.end()) + { + d_rtcm_MT1020_rate_ms = rtcm_msg_rate_ms[1020]; + } + else + { + d_rtcm_MT1020_rate_ms = boost::math::lcm(5000, d_output_rate_ms); // default value if not set + } if(rtcm_msg_rate_ms.find(1045) != rtcm_msg_rate_ms.end()) { d_rtcm_MT1045_rate_ms = rtcm_msg_rate_ms[1045]; @@ -265,6 +305,14 @@ rtklib_pvt_cc::rtklib_pvt_cc(unsigned int nchannels, bool dump, std::string dump { d_rtcm_MT1077_rate_ms = boost::math::lcm(1000, d_output_rate_ms); // default value if not set } + if(rtcm_msg_rate_ms.find(1087) != rtcm_msg_rate_ms.end()) // whatever between 1081 and 1087 + { + d_rtcm_MT1087_rate_ms = rtcm_msg_rate_ms[1087]; + } + else + { + d_rtcm_MT1087_rate_ms = boost::math::lcm(1000, d_output_rate_ms); // default value if not set + } if(rtcm_msg_rate_ms.find(1097) != rtcm_msg_rate_ms.end()) // whatever between 1091 and 1097 { d_rtcm_MT1097_rate_ms = rtcm_msg_rate_ms[1097]; @@ -286,8 +334,10 @@ rtklib_pvt_cc::rtklib_pvt_cc(unsigned int nchannels, bool dump, std::string dump d_rx_time = 0.0; last_pvt_display_T_rx_s = 0.0; last_RTCM_1019_output_time = 0.0; + last_RTCM_1020_output_time = 0.0; last_RTCM_1045_output_time = 0.0; last_RTCM_1077_output_time = 0.0; + last_RTCM_1087_output_time = 0.0; last_RTCM_1097_output_time = 0.0; last_RTCM_MSM_output_time = 0.0; last_RINEX_obs_output_time = 0.0; @@ -295,7 +345,8 @@ rtklib_pvt_cc::rtklib_pvt_cc(unsigned int nchannels, bool dump, std::string dump b_rinex_header_written = false; b_rinex_header_updated = false; - rp = std::make_shared(rinex_version); + d_rinex_version = rinex_version; + rp = std::make_shared(d_rinex_version); d_last_status_print_seg = 0; @@ -347,7 +398,7 @@ rtklib_pvt_cc::~rtklib_pvt_cc() ofs.close(); LOG(INFO) << "Saved GPS L2CM or L5 Ephemeris map data"; } - catch (const std::exception & e) + catch (std::exception& e) { LOG(WARNING) << e.what(); } @@ -403,6 +454,28 @@ rtklib_pvt_cc::~rtklib_pvt_cc() LOG(WARNING) << "Failed to save Galileo E1 Ephemeris, map is empty"; } + //save GLONASS GNAV ephemeris to XML file + file_name = "eph_GLONASS_GNAV.xml"; + + if (d_ls_pvt->glonass_gnav_ephemeris_map.size() > 0) + { + try + { + std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->glonass_gnav_ephemeris_map); + ofs.close(); + LOG(INFO) << "Saved GLONASS GNAV Ephemeris map data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(WARNING) << "Failed to save GLONASS GNAV Ephemeris, map is empty"; + } if (d_dump_file.is_open() == true) { try @@ -447,12 +520,14 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite bool flag_display_pvt = false; bool flag_compute_pvt_output = false; bool flag_write_RTCM_1019_output = false; + bool flag_write_RTCM_1020_output = false; bool flag_write_RTCM_1045_output = false; bool flag_write_RTCM_MSM_output = false; bool flag_write_RINEX_obs_output = false; bool flag_write_RINEX_nav_output = false; unsigned int gps_channel = 0; unsigned int gal_channel = 0; + unsigned int glo_channel = 0; gnss_observables_map.clear(); const Gnss_Synchro **in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer @@ -465,10 +540,13 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite std::map::const_iterator tmp_eph_iter_gps = d_ls_pvt->gps_ephemeris_map.find(in[i][epoch].PRN); std::map::const_iterator tmp_eph_iter_gal = d_ls_pvt->galileo_ephemeris_map.find(in[i][epoch].PRN); std::map::const_iterator tmp_eph_iter_cnav = d_ls_pvt->gps_cnav_ephemeris_map.find(in[i][epoch].PRN); + std::map::const_iterator tmp_eph_iter_glo_gnav = d_ls_pvt->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN); if(((tmp_eph_iter_gps->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("1C") == 0)) || ((tmp_eph_iter_cnav->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("2S") == 0)) || ((tmp_eph_iter_gal->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("1B") == 0)) || ((tmp_eph_iter_gal->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("5X") == 0)) + || ((tmp_eph_iter_glo_gnav->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("1G") == 0)) + || ((tmp_eph_iter_glo_gnav->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("2G") == 0)) || ((tmp_eph_iter_cnav->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("L5") == 0))) { // store valid observables in a map. @@ -496,6 +574,14 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite d_rtcm_printer->lock_time(d_ls_pvt->gps_cnav_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time } } + if(d_ls_pvt->glonass_gnav_ephemeris_map.size() > 0) + { + if(tmp_eph_iter_glo_gnav != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + { + d_rtcm_printer->lock_time(d_ls_pvt->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time + } + } + } } @@ -528,7 +614,11 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite flag_write_RTCM_1019_output = true; last_RTCM_1019_output_time = current_RX_time; } - + if ((std::fabs(current_RX_time - last_RTCM_1020_output_time) * 1000.0 >= static_cast(d_rtcm_MT1020_rate_ms)) && (d_rtcm_MT1020_rate_ms != 0) ) // allows deactivating messages by setting rate = 0 + { + flag_write_RTCM_1020_output = true; + last_RTCM_1020_output_time = current_RX_time; + } if ((std::fabs(current_RX_time - last_RTCM_1045_output_time) * 1000.0 >= static_cast(d_rtcm_MT1045_rate_ms)) && (d_rtcm_MT1045_rate_ms != 0) ) { flag_write_RTCM_1045_output = true; @@ -539,7 +629,10 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite { last_RTCM_1077_output_time = current_RX_time; } - + if ((std::fabs(current_RX_time - last_RTCM_1087_output_time) * 1000.0 >= static_cast(d_rtcm_MT1087_rate_ms)) && (d_rtcm_MT1087_rate_ms != 0) ) + { + last_RTCM_1087_output_time = current_RX_time; + } if ((std::fabs(current_RX_time - last_RTCM_1097_output_time) * 1000.0 >= static_cast(d_rtcm_MT1097_rate_ms)) && (d_rtcm_MT1097_rate_ms != 0) ) { last_RTCM_1097_output_time = current_RX_time; @@ -571,8 +664,8 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite if(first_fix == true) { std::cout << "First position fix at " << boost::posix_time::to_simple_string(d_ls_pvt->get_position_UTC_time()) - << " UTC is Lat = " << d_ls_pvt->get_latitude() << " [deg], Long = " << d_ls_pvt->get_longitude() - << " [deg], Height= " << d_ls_pvt->get_height() << " [m]" << std::endl; + << " UTC is Lat = " << d_ls_pvt->get_latitude() << " [deg], Long = " << d_ls_pvt->get_longitude() + << " [deg], Height= " << d_ls_pvt->get_height() << " [m]" << std::endl; ttff_msgbuf ttff; ttff.mtype = 1; end = std::chrono::system_clock::now(); @@ -610,6 +703,12 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite * 20 | GPS L5 + Galileo E5b * 21 | GPS L1 C/A + Galileo E1B + GPS L2C * 22 | GPS L1 C/A + Galileo E1B + GPS L5 + * 23 | GLONASS L1 C/A + * 24 | GLONASS L2 C/A + * 25 | GLONASS L1 C/A + GLONASS L2 C/A + * 26 | GPS L1 C/A + GLONASS L1 C/A + * 27 | Galileo E1B + GLONASS L1 C/A + * 28 | GPS L2C + GLONASS L1 C/A */ // ####################### RINEX FILES ################# @@ -617,6 +716,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite std::map::const_iterator galileo_ephemeris_iter; std::map::const_iterator gps_ephemeris_iter; std::map::const_iterator gps_cnav_ephemeris_iter; + std::map::const_iterator glonass_gnav_ephemeris_iter; std::map::const_iterator gnss_observables_iter; if (!b_rinex_header_written) // & we have utc data in nav message! @@ -624,6 +724,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_cnav_ephemeris_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); + glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); if(type_of_rx == 1) // GPS L1 C/A only { @@ -742,6 +843,74 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite b_rinex_header_written = true; // do not write header anymore } } + if(type_of_rx == 23) // GLONASS L1 C/A only + { + std::string signal("1G"); + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); + b_rinex_header_written = true; // do not write header anymore + } + } + if(type_of_rx == 24) // GLONASS L2 C/A only + { + std::string signal("2G"); + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); + b_rinex_header_written = true; // do not write header anymore + } + } + if(type_of_rx == 25) // GLONASS L1 C/A + GLONASS L2 C/A + { + std::string signal("1G 2G"); + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); + b_rinex_header_written = true; // do not write header anymore + } + } + + if(type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A + { + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) && (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) ) + { + std::string glo_signal("1G"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); + if(d_rinex_version == 3) + rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + if(d_rinex_version == 2) + { + rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); + rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); + } + b_rinex_header_written = true; // do not write header anymore + } + } + if(type_of_rx == 27) // Galileo E1B + GLONASS L1 C/A + { + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) && (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) ) + { + std::string glo_signal("1G"); + std::string gal_signal("1B"); + rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal, gal_signal); + rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + b_rinex_header_written = true; // do not write header anymore + } + } + if(type_of_rx == 28) // GPS L2C + GLONASS L1 C/A + { + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) && (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend()) ) + { + std::string glo_signal("1G"); + rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); + rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + b_rinex_header_written = true; // do not write header anymore + } + } } if(b_rinex_header_written) // The header is already written, we can now log the navigation message data { @@ -775,10 +944,34 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite { rp->log_rinex_nav(rp->navGalFile, d_ls_pvt->galileo_ephemeris_map); } + if((type_of_rx == 23) || (type_of_rx == 24) || (type_of_rx == 25)) // GLONASS L1 C/A, GLONASS L2 C/A + { + rp->log_rinex_nav(rp->navGloFile, d_ls_pvt->glonass_gnav_ephemeris_map); + } + if(type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A + { + if(d_rinex_version == 3) + rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); + if(d_rinex_version == 2) + { + rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map); + rp->log_rinex_nav(rp->navGloFile, d_ls_pvt->glonass_gnav_ephemeris_map); + } + + } + if(type_of_rx == 27) // Galileo E1B + GLONASS L1 C/A + { + rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->galileo_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); + } + if(type_of_rx == 28) // GPS L2C + GLONASS L1 C/A + { + rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_cnav_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); + } } galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_cnav_ephemeris_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); + glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); // Log observables into the RINEX file if(flag_write_RINEX_obs_output) @@ -913,6 +1106,85 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite b_rinex_header_updated = true; } } + if(type_of_rx == 23) // GLONASS L1 C/A only + { + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + { + rp->log_rinex_obs(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1C"); + } + if (!b_rinex_header_updated && (d_ls_pvt->glonass_gnav_utc_model.d_tau_c != 0)) + { + rp->update_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + rp->update_obs_header(rp->obsFile, d_ls_pvt->glonass_gnav_utc_model); + b_rinex_header_updated = true; + } + } + if(type_of_rx == 24) // GLONASS L2 C/A only + { + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + { + rp->log_rinex_obs(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "2C"); + } + if (!b_rinex_header_updated && (d_ls_pvt->glonass_gnav_utc_model.d_tau_c != 0)) + { + rp->update_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + rp->update_obs_header(rp->obsFile, d_ls_pvt->glonass_gnav_utc_model); + b_rinex_header_updated = true; + } + } + if(type_of_rx == 25) // GLONASS L1 C/A + GLONASS L2 C/A + { + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + { + rp->log_rinex_obs(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1C 2C"); + } + if (!b_rinex_header_updated && (d_ls_pvt->glonass_gnav_utc_model.d_tau_c != 0)) + { + rp->update_nav_header(rp->navMixFile, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + rp->update_obs_header(rp->obsFile, d_ls_pvt->glonass_gnav_utc_model); + b_rinex_header_updated = true; + } + } + if(type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A + { + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) && (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end()) ) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated && (d_ls_pvt->gps_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); + rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + b_rinex_header_updated = true; // do not write header anymore + } + } + if(type_of_rx == 27) // Galileo E1B + GLONASS L1 C/A + { + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) && (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) ) + { + rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + + } + if (!b_rinex_header_updated && (d_ls_pvt->galileo_utc_model.A0_6 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); + rp->update_nav_header(rp->navMixFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + b_rinex_header_updated = true; // do not write header anymore + } + } + if(type_of_rx == 28) // GPS L2C + GLONASS L1 C/A + { + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) && (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.end()) ) + { + rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated && (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); + rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + b_rinex_header_updated = true; // do not write header anymore + } + } } } @@ -935,7 +1207,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } } @@ -954,7 +1226,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite gal_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); if (gal_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } } @@ -975,7 +1247,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite gps_cnav_ephemeris_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); if ((gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) && (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend()) ) { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } } @@ -1033,14 +1305,165 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } if(flag_write_RTCM_MSM_output == true) { if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + } + } + if((type_of_rx == 23) || (type_of_rx == 24) || (type_of_rx == 25)) // GLONASS + { + if(flag_write_RTCM_1020_output == true) + { + for(std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++ ) + { + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + } + } + + std::map::const_iterator glo_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); + + if (glo_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glo_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + b_rtcm_writing_started = true; + } + if(type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A + { + if(flag_write_RTCM_1019_output == true) + { + for(gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++ ) + { + d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + } + } + if(flag_write_RTCM_1020_output == true) + { + for(std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++ ) + { + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + } + } + if(flag_write_RTCM_MSM_output == true) + { + //gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); + //galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); + unsigned int i = 0; + for (gnss_observables_iter = gnss_observables_map.begin(); gnss_observables_iter != gnss_observables_map.end(); gnss_observables_iter++) + { + std::string system(&gnss_observables_iter->second.System, 1); + if(gps_channel == 0) + { + if(system.compare("G") == 0) + { + // This is a channel with valid GPS signal + gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + { + gps_channel = i; + } + } + } + if(glo_channel == 0) + { + if(system.compare("R") == 0) + { + glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + glo_channel = i; + } + } + } + i++; + } + if(flag_write_RTCM_MSM_output == true) + { + + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + if(flag_write_RTCM_MSM_output == true) + { + if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + } + } + if(type_of_rx == 27) // GLONASS L1 C/A + Galileo E1B + { + if(flag_write_RTCM_1020_output == true) + { + for(std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++ ) + { + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + } + } + if(flag_write_RTCM_1045_output == true) + { + for(galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend(); galileo_ephemeris_iter++ ) + { + d_rtcm_printer->Print_Rtcm_MT1045(galileo_ephemeris_iter->second); + } + } + if(flag_write_RTCM_MSM_output == true) + { + //gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); + //galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); + unsigned int i = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + { + std::string system(&gnss_observables_iter->second.System, 1); + if(gal_channel == 0) + { + if(system.compare("E") == 0) + { + // This is a channel with valid GPS signal + galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + gal_channel = i; + } + } + } + if(glo_channel == 0) + { + if(system.compare("R") == 0) + { + glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + { + glo_channel = i; + } + } + } + i++; + } + if(flag_write_RTCM_MSM_output == true) + { + + if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + if(flag_write_RTCM_MSM_output == true) + { + + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } } @@ -1060,11 +1483,10 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } b_rtcm_writing_started = true; } - if((type_of_rx == 4) || (type_of_rx == 5) || (type_of_rx == 6) || (type_of_rx == 14) || (type_of_rx == 15)) // Galileo { for(std::map::const_iterator gal_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_ephemeris_iter++ ) @@ -1076,7 +1498,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite if (gal_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } b_rtcm_writing_started = true; } @@ -1092,7 +1514,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite if ((gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) && (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } b_rtcm_writing_started = true; } @@ -1145,15 +1567,145 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end() && (d_rtcm_MT1077_rate_ms != 0)) { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end() && (d_rtcm_MT1097_rate_ms != 0) ) { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } b_rtcm_writing_started = true; } + if((type_of_rx == 23) || (type_of_rx == 24) || (type_of_rx == 25)) // GLONASS + { + for(std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++ ) + { + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + } + + std::map::const_iterator glo_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); + + if (glo_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glo_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + b_rtcm_writing_started = true; + } + if(type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A + { + if(d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 + { + for(gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++ ) + { + d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + } + } + if(d_rtcm_MT1020_rate_ms != 0) // allows deactivating messages by setting rate = 0 + { + for(std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++ ) + { + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + } + } + + //gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); + //galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); + unsigned int i = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + { + std::string system(&gnss_observables_iter->second.System, 1); + if(gps_channel == 0) + { + if(system.compare("G") == 0) + { + // This is a channel with valid GPS signal + gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + { + gps_channel = i; + } + } + } + if(glo_channel == 0) + { + if(system.compare("R") == 0) + { + glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + glo_channel = i; + } + } + } + i++; + } + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + + if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + + b_rtcm_writing_started = true; + } + if(type_of_rx == 27) // GLONASS L1 C/A + Galileo E1B + { + if(d_rtcm_MT1020_rate_ms != 0) // allows deactivating messages by setting rate = 0 + { + for(std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++ ) + { + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + } + } + if(d_rtcm_MT1045_rate_ms != 0) // allows deactivating messages by setting rate = 0 + { + for(galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend(); galileo_ephemeris_iter++ ) + { + d_rtcm_printer->Print_Rtcm_MT1045(galileo_ephemeris_iter->second); + } + } + + unsigned int i = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + { + std::string system(&gnss_observables_iter->second.System, 1); + if(gal_channel == 0) + { + if(system.compare("E") == 0) + { + // This is a channel with valid GPS signal + galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + { + gal_channel = i; + } + } + } + if(glo_channel == 0) + { + if(system.compare("R") == 0) + { + glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + { + glo_channel = i; + } + } + } + i++; + } + if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } } } } diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.h b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.h index a188c5809..7e71b21a0 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.h +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.h @@ -98,11 +98,14 @@ private: bool d_dump; bool b_rinex_header_written; bool b_rinex_header_updated; + double d_rinex_version; bool b_rtcm_writing_started; - int d_rtcm_MT1045_rate_ms; - int d_rtcm_MT1019_rate_ms; - int d_rtcm_MT1077_rate_ms; - int d_rtcm_MT1097_rate_ms; + int d_rtcm_MT1045_rate_ms; //!< Galileo Broadcast Ephemeris + int d_rtcm_MT1019_rate_ms; //!< GPS Broadcast Ephemeris (orbits) + int d_rtcm_MT1020_rate_ms; //!< GLONASS Broadcast Ephemeris (orbits) + int d_rtcm_MT1077_rate_ms; //!< The type 7 Multiple Signal Message format for the USA’s GPS system, popular + int d_rtcm_MT1087_rate_ms; //!< GLONASS MSM7. The type 7 Multiple Signal Message format for the Russian GLONASS system + int d_rtcm_MT1097_rate_ms; //!< Galileo MSM7. The type 7 Multiple Signal Message format for Europe’s Galileo system int d_rtcm_MSM_rate_ms; int d_last_status_print_seg; //for status printer @@ -122,8 +125,10 @@ private: double d_rx_time; double last_pvt_display_T_rx_s; double last_RTCM_1019_output_time; + double last_RTCM_1020_output_time; double last_RTCM_1045_output_time; double last_RTCM_1077_output_time; + double last_RTCM_1087_output_time; double last_RTCM_1097_output_time; double last_RTCM_MSM_output_time; double last_RINEX_obs_output_time; diff --git a/src/algorithms/PVT/libs/nmea_printer.cc b/src/algorithms/PVT/libs/nmea_printer.cc index 97ab793a7..b7d55d67f 100644 --- a/src/algorithms/PVT/libs/nmea_printer.cc +++ b/src/algorithms/PVT/libs/nmea_printer.cc @@ -727,6 +727,3 @@ std::string Nmea_Printer::get_GPGGA() return sentence_str.str(); //$GPGGA,104427.591,5920.7009,N,01803.2938,E,1,05,3.3,78.2,M,23.2,M,0.0,0000*4A } - - - diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index 8907e3df2..d3ca165ac 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -58,12 +58,14 @@ Rinex_Printer::Rinex_Printer(int conf_version) sbsfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_SBAS"); navGalfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_GAL_NAV"); navMixfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_MIXED_NAV"); + navGlofilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_GLO_NAV"); Rinex_Printer::navFile.open(navfilename, std::ios::out | std::ios::in | std::ios::app); Rinex_Printer::obsFile.open(obsfilename, std::ios::out | std::ios::in | std::ios::app); Rinex_Printer::sbsFile.open(sbsfilename, std::ios::out | std::ios::app); Rinex_Printer::navGalFile.open(navGalfilename, std::ios::out | std::ios::in | std::ios::app); Rinex_Printer::navMixFile.open(navMixfilename, std::ios::out | std::ios::in | std::ios::app); + Rinex_Printer::navGloFile.open(navGlofilename, std::ios::out | std::ios::in | std::ios::app); // RINEX v3.02 codes satelliteSystem["GPS"] = "G"; @@ -141,6 +143,7 @@ Rinex_Printer::Rinex_Printer(int conf_version) observationType["DOPPLER_v2"] = "D"; observationType["SIGNAL_STRENGTH_v2"] = "S"; observationCode["GPS_L1_CA_v2"] = "1"; + observationCode["GLONASS_G1_CA_v2"] = "1"; if ( FLAGS_RINEX_version.compare("3.01") == 0 ) { @@ -180,18 +183,18 @@ Rinex_Printer::Rinex_Printer(int conf_version) } if(conf_version != 0) - { - if(conf_version == 2) - { - version = 2; - stringVersion = "2.11"; - } - if(conf_version == 3) - { - version = 3; - stringVersion = "3.02"; - } - } + { + if(conf_version == 2) + { + version = 2; + stringVersion = "2.11"; + } + if(conf_version == 3) + { + version = 3; + stringVersion = "3.02"; + } + } numberTypesObservations = 4; // Number of available types of observable in the system fake_cnav_iode = 1; @@ -201,16 +204,19 @@ Rinex_Printer::Rinex_Printer(int conf_version) Rinex_Printer::~Rinex_Printer() { // close RINEX files - long posn, poso, poss, posng, posmn; + long posn, poso, poss, posng, posmn, posnr; posn = navFile.tellp(); poso = obsFile.tellp(); poss = sbsFile.tellp(); posng = navGalFile.tellp(); posmn = navMixFile.tellp(); + posnr = navGloFile.tellp(); + Rinex_Printer::navFile.close(); Rinex_Printer::obsFile.close(); Rinex_Printer::sbsFile.close(); Rinex_Printer::navGalFile.close(); + Rinex_Printer::navGloFile.close(); // If nothing written, erase the files. if (posn == 0) { @@ -232,6 +238,10 @@ Rinex_Printer::~Rinex_Printer() { if(remove(navMixfilename.c_str()) != 0) LOG(INFO) << "Error deleting temporary file"; } + if (posnr == 0) + { + if(remove(navGlofilename.c_str()) != 0) LOG(INFO) << "Error deleting temporary file"; + } } @@ -406,6 +416,464 @@ std::string Rinex_Printer::getLocalTime() } +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +{ + std::string line; + + // -------- Line 1 + line = std::string(5, ' '); + line += stringVersion; + line += std::string(11, ' '); + line += std::string("N: GNSS NAV DATA"); + line += std::string(4, ' '); + line += std::string("R: GLONASS"); + line += std::string(10, ' '); + line += std::string("RINEX VERSION / TYPE"); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 2 + line.clear(); + line += Rinex_Printer::getLocalTime(); + line += std::string("PGM / RUN BY / DATE"); + line += std::string(1, ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("GLONASS NAVIGATION MESSAGE FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + std::string gnss_sdr_version(GNSS_SDR_VERSION); + line += "GNSS-SDR VERSION "; + line += Rinex_Printer::leftJustify(gnss_sdr_version, 43); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("See http://gnss-sdr.org", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction + if (version == 3) + { + line.clear(); + line += std::string("GLUT"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 17); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction 2 + line.clear(); + line += std::string("GLGP"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_gps, 16, 2), 17); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + if (version == 2) + { + // Set reference time and its clock corrections + boost::posix_time::ptime p_utc_ref_time = glonass_gnav_eph.glot_to_utc(glonass_gnav_eph.d_t_b, 0.0); + std::string timestring = boost::posix_time::to_iso_string(p_utc_ref_time); + std::string year (timestring, 0, 4); + std::string month (timestring, 4, 2); + std::string day (timestring, 6, 2); + + line.clear(); + line += Rinex_Printer::rightJustify(year, 6); + line += Rinex_Printer::rightJustify(month, 6); + line += Rinex_Printer::rightJustify(day, 6); + line += std::string(3, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 19, 2), 19); + line += std::string(20, ' '); + line += Rinex_Printer::leftJustify("CORR TO SYSTEM TIME", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + + // -------- End of Header + line.clear(); + line += std::string(60, ' '); + line += Rinex_Printer::leftJustify("END OF HEADER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; +} + +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) +{ + if(glonass_gnav_almanac.i_satellite_freq_channel){} //Avoid compiler warning + std::string line; + stringVersion = "3.02"; + version = 3; + + // -------- Line 1 + line = std::string(5, ' '); + line += stringVersion; + line += std::string(11, ' '); + line += std::string("N: GNSS NAV DATA"); + line += std::string(4, ' '); + line += std::string("M: MIXED"); + line += std::string(12, ' '); + line += std::string("RINEX VERSION / TYPE"); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 2 + line.clear(); + line += Rinex_Printer::getLocalTime(); + line += std::string("PGM / RUN BY / DATE"); + line += std::string(1, ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("GNSS NAVIGATION MESSAGE FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + std::string gnss_sdr_version(GNSS_SDR_VERSION); + line += "GNSS-SDR VERSION "; + line += Rinex_Printer::leftJustify(gnss_sdr_version, 43); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("See http://gnss-sdr.org", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line ionospheric info 1 + line.clear(); + line += std::string("GPSA"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha0, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha1, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha2, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha3, 10, 2), 12); + line += std::string(7, ' '); + line += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction 1 + line.clear(); + line += std::string("GLUT"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 17); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction 2 + line.clear(); + line += std::string("GLGP"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_gps, 16, 2), 17); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction 3 + line.clear(); + line += std::string("GPUT"); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_utc_model.d_A0, 16, 2), 18); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_utc_model.d_A1, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_t_OT), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_WN_T + 1024), 5); // valid until 2019 + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 6 leap seconds + // For leap second information, see http://www.endruntechnologies.com/leap.htm + line.clear(); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_DeltaT_LS), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_DeltaT_LSF), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_WN_LSF), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_DN), 6); + line += std::string(36, ' '); + line += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- End of Header + line.clear(); + line += std::string(60, ' '); + line += Rinex_Printer::leftJustify("END OF HEADER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; +} + + +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono& gps_iono, const Gps_CNAV_Utc_Model& gps_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) +{ + if(glonass_gnav_almanac.i_satellite_freq_channel){} //Avoid compiler warning + std::string line; + stringVersion = "3.02"; + version = 3; + + // -------- Line 1 + line = std::string(5, ' '); + line += stringVersion; + line += std::string(11, ' '); + line += std::string("N: GNSS NAV DATA"); + line += std::string(4, ' '); + line += std::string("M: MIXED"); + line += std::string(12, ' '); + line += std::string("RINEX VERSION / TYPE"); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 2 + line.clear(); + line += Rinex_Printer::getLocalTime(); + line += std::string("PGM / RUN BY / DATE"); + line += std::string(1, ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("GNSS NAVIGATION MESSAGE FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + std::string gnss_sdr_version(GNSS_SDR_VERSION); + line += "GNSS-SDR VERSION "; + line += Rinex_Printer::leftJustify(gnss_sdr_version, 43); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("See http://gnss-sdr.org", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line ionospheric info 1 + line.clear(); + line += std::string("GPSA"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha0, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha1, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha2, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha3, 10, 2), 12); + line += std::string(7, ' '); + line += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction 1 + line.clear(); + line += std::string("GLUT"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 17); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction 2 + line.clear(); + line += std::string("GLGP"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_gps, 16, 2), 17); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction 3 + line.clear(); + line += std::string("GPUT"); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_utc_model.d_A0, 16, 2), 18); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_utc_model.d_A1, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_t_OT), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_WN_T + 1024), 5); // valid until 2019 + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 6 leap seconds + // For leap second information, see http://www.endruntechnologies.com/leap.htm + line.clear(); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_DeltaT_LS), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_DeltaT_LSF), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_WN_LSF), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_DN), 6); + line += std::string(36, ' '); + line += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- End of Header + line.clear(); + line += std::string(60, ' '); + line += Rinex_Printer::leftJustify("END OF HEADER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; +} + + +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) +{ + if(glonass_gnav_almanac.i_satellite_freq_channel){} //Avoid compiler warning + //Avoid compiler warning, there is not time system correction between Galileo and GLONASS + if(galileo_almanac.A_0G_10){} + std::string line; + + // -------- Line 1 + line = std::string(5, ' '); + line += stringVersion; + line += std::string(11, ' '); + line += std::string("N: GNSS NAV DATA"); + line += std::string(4, ' '); + line += std::string("M: MIXED"); + line += std::string(12, ' '); + line += std::string("RINEX VERSION / TYPE"); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 2 + line.clear(); + line += Rinex_Printer::getLocalTime(); + line += std::string("PGM / RUN BY / DATE"); + line += std::string(1, ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("GNSS NAVIGATION MESSAGE FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + std::string gnss_sdr_version(GNSS_SDR_VERSION); + line += "GNSS-SDR VERSION "; + line += Rinex_Printer::leftJustify(gnss_sdr_version, 43); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("See http://gnss-sdr.org", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line ionospheric info 1 + line.clear(); + line += std::string("GAL "); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai0_5, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai1_5, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai2_5, 10, 2), 12); + double zero = 0.0; + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(zero, 10, 2), 12); + line += std::string(7, ' '); + line += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction + line.clear(); + line += std::string("GAUT"); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A0_6, 16, 2), 18); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A1_6, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.t0t_6), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.WNot_6), 5); + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction 1 + line.clear(); + line += std::string("GLUT"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 17); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 6 leap seconds + // For leap second information, see http://www.endruntechnologies.com/leap.htm + line.clear(); + line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.Delta_tLS_6), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.Delta_tLSF_6), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.WN_LSF_6), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.DN_6), 6); + line += std::string(36, ' '); + line += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- End of Header + line.clear(); + line += std::string(60, ' '); + line += Rinex_Printer::leftJustify("END OF HEADER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; +} + + void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac) { std::string line; @@ -453,7 +921,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono Rinex_Printer::lengthCheck(line); out << line << std::endl; - // -------- Line ionospheric info 1 line.clear(); line += std::string("GAL "); @@ -468,7 +935,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono Rinex_Printer::lengthCheck(line); out << line << std::endl; - // -------- Line system time correction line.clear(); line += std::string("GAUT"); @@ -493,7 +959,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono Rinex_Printer::lengthCheck(line); out << line << std::endl; - // -------- Line 6 leap seconds // For leap second information, see http://www.endruntechnologies.com/leap.htm line.clear(); @@ -654,7 +1119,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, co line += std::string("G: GPS"); line += std::string(14, ' '); // ... - } line += std::string("RINEX VERSION / TYPE"); @@ -800,7 +1264,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, co Rinex_Printer::lengthCheck(line); out << line << std::endl; - // -------- End of Header line.clear(); line += std::string(60, ' '); @@ -857,7 +1320,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono Rinex_Printer::lengthCheck(line); out << line << std::endl; - // -------- Line ionospheric info 1 line.clear(); line += std::string("GAL "); @@ -921,7 +1383,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono Rinex_Printer::lengthCheck(line); out << line << std::endl; - // -------- Line 6 leap seconds // For leap second information, see http://www.endruntechnologies.com/leap.htm line.clear(); @@ -1051,6 +1512,80 @@ void Rinex_Printer::rinex_sbs_header(std::fstream& out) } +void Rinex_Printer::update_nav_header(std::fstream& out, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) +{ + if(glonass_gnav_almanac.i_satellite_freq_channel){} //Avoid compiler warning + std::vector data; + std::string line_aux; + + long pos = out.tellp(); + out.seekp(0); + data.clear(); + + bool no_more_finds = false; + std::string line_str; + + while(!out.eof()) + { + std::getline(out, line_str); + + if(!no_more_finds) + { + line_aux.clear(); + + if ((line_str.find("GLUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GLUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GLGP", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GLGP"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_gps, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if (line_str.find("END OF HEADER", 59) != std::string::npos) + { + data.push_back(line_str); + no_more_finds = true; + } + else + { + data.push_back(line_str); + } + + } + else + { + data.push_back(line_str); + } + } + + out.close(); + out.open(navGlofilename, std::ios::out | std::ios::trunc); + out.seekp(0); + for (int i = 0; i < static_cast(data.size()) - 1; i++) + { + out << data[i] << std::endl; + } + out.close(); + out.open(navGlofilename, std::ios::out | std::ios::app); + out.seekp(pos); + std::cout << "The RINEX Navigation file header has been updated with UTC info." << std::endl; +} + + void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac) { std::vector data; @@ -1136,7 +1671,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& gal out.close(); out.open(navGalfilename, std::ios::out | std::ios::trunc); out.seekp(0); - for (int i = 0; i < static_cast(data.size()) - 1; i++) + for (int i = 0; i < (int) data.size() - 1; i++) { out << data[i] << std::endl; } @@ -1502,7 +2037,6 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Iono& gps_ion { data.push_back(line_str); } - } else { @@ -1524,6 +2058,318 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Iono& gps_ion } +void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) +{ + if(glonass_gnav_almanac.i_satellite_freq_channel){} //Avoid compiler warning + std::vector data; + std::string line_aux; + + long pos = out.tellp(); + out.seekp(0); + data.clear(); + + bool no_more_finds = false; + std::string line_str; + + while(!out.eof()) + { + std::getline(out, line_str); + + if(!no_more_finds) + { + line_aux.clear(); + + if (line_str.find("GPSA", 0) != std::string::npos) + { + line_aux += std::string("GPSA"); + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha0, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha1, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha2, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha3, 10, 2), 12); + line_aux += std::string(7, ' '); + line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GPUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GPUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_utc_model.d_A0, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_utc_model.d_A1, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_t_OT), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_WN_T + 1024), 5); // valid until 2019 + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GLUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GLUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GLGP", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GLGP"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_gps, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if (line_str.find("LEAP SECONDS", 59) != std::string::npos) + { + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_DeltaT_LS), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_DeltaT_LSF), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_WN_LSF), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_DN), 6); + line_aux += std::string(36, ' '); + line_aux += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + data.push_back(line_aux); + } + else if (line_str.find("END OF HEADER", 59) != std::string::npos) + { + data.push_back(line_str); + no_more_finds = true; + } + else + { + data.push_back(line_str); + } + + } + else + { + data.push_back(line_str); + } + } + + out.close(); + out.open(navMixfilename, std::ios::out | std::ios::trunc); + out.seekp(0); + for (int i = 0; i < (int) data.size() - 1; i++) + { + out << data[i] << std::endl; + } + out.close(); + out.open(navMixfilename, std::ios::out | std::ios::app); + out.seekp(pos); + std::cout << "The RINEX Navigation file header has been updated with UTC and IONO info." << std::endl; +} + + +void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_CNAV_Iono& gps_iono, const Gps_CNAV_Utc_Model& gps_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) +{ + if(glonass_gnav_almanac.i_satellite_freq_channel){} //Avoid compiler warning + std::vector data; + std::string line_aux; + + long pos = out.tellp(); + out.seekp(0); + data.clear(); + + bool no_more_finds = false; + std::string line_str; + + while(!out.eof()) + { + std::getline(out, line_str); + + if(!no_more_finds) + { + line_aux.clear(); + + if (line_str.find("GPSA", 0) != std::string::npos) + { + line_aux += std::string("GPSA"); + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha0, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha1, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha2, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha3, 10, 2), 12); + line_aux += std::string(7, ' '); + line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GPUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GPUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_utc_model.d_A0, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_utc_model.d_A1, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_t_OT), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_WN_T + 1024), 5); // valid until 2019 + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GLUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GLUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GLGP", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GLGP"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_gps, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if (line_str.find("LEAP SECONDS", 59) != std::string::npos) + { + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_DeltaT_LS), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_DeltaT_LSF), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_WN_LSF), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_DN), 6); + line_aux += std::string(36, ' '); + line_aux += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + data.push_back(line_aux); + } + else if (line_str.find("END OF HEADER", 59) != std::string::npos) + { + data.push_back(line_str); + no_more_finds = true; + } + else + { + data.push_back(line_str); + } + } + else + { + data.push_back(line_str); + } + } + + out.close(); + out.open(navMixfilename, std::ios::out | std::ios::trunc); + out.seekp(0); + for (int i = 0; i < (int) data.size() - 1; i++) + { + out << data[i] << std::endl; + } + out.close(); + out.open(navMixfilename, std::ios::out | std::ios::app); + out.seekp(pos); + std::cout << "The RINEX Navigation file header has been updated with UTC and IONO info." << std::endl; +} + + +void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) +{ + if(glonass_gnav_almanac.i_satellite_freq_channel){} //Avoid compiler warning + //Avoid compiler warning, there is not time system correction between Galileo and GLONASS + if(galileo_almanac.A_0G_10){} + std::vector data; + std::string line_aux; + + long pos = out.tellp(); + out.seekp(0); + data.clear(); + + bool no_more_finds = false; + std::string line_str; + + while(!out.eof()) + { + std::getline(out, line_str); + + if(!no_more_finds) + { + line_aux.clear(); + + if ((line_str.find("GAL", 0) != std::string::npos) && (line_str.find("IONOSPHERIC CORR", 59) != std::string::npos)) + { + line_aux += std::string("GAL "); + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai0_5, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai1_5, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai2_5, 10, 2), 12); + double zero = 0.0; + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(zero, 10, 2), 12); + line_aux += std::string(7, ' '); + line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GAUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GAUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A0_6, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A1_6, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.t0t_6), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.WNot_6), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GLUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GLUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if (line_str.find("LEAP SECONDS", 59) != std::string::npos) + { + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.Delta_tLS_6), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.Delta_tLSF_6), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.WN_LSF_6), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.DN_6), 6); + line_aux += std::string(36, ' '); + line_aux += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + data.push_back(line_aux); + } + else if (line_str.find("END OF HEADER", 59) != std::string::npos) + { + data.push_back(line_str); + no_more_finds = true; + } + else + { + data.push_back(line_str); + } + + } + else + { + data.push_back(line_str); + } + } + + out.close(); + out.open(navMixfilename, std::ios::out | std::ios::trunc); + out.seekp(0); + for (int i = 0; i < (int) data.size() - 1; i++) + { + out << data[i] << std::endl; + } + out.close(); + out.open(navMixfilename, std::ios::out | std::ios::app); + out.seekp(pos); + std::cout << "The RINEX Navigation file header has been updated with UTC and IONO info." << std::endl; +} + + void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& eph_map) { std::string line; @@ -1532,7 +2378,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::mapsecond, gps_ephemeris_iter->second.d_Toc); std::string timestring = boost::posix_time::to_iso_string(p_utc_time); @@ -1640,7 +2486,6 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(galileo_ephemeris_iter->second.E5b_DVS_5) - + "11" + "1" + E1B_DVS + E1B_HS - + boost::lexical_cast(galileo_ephemeris_iter->second.E1B_DVS_5); + + "11" + "1" + E1B_DVS + E1B_HS + + boost::lexical_cast(galileo_ephemeris_iter->second.E1B_DVS_5); SVhealth_str = "000000000"; // *************** CHANGE THIS WHEN GALILEO SIGNAL IS VALID int SVhealth = Rinex_Printer::toInt(SVhealth_str, 9); line += Rinex_Printer::doub2for(static_cast(SVhealth), 18, 2); @@ -2179,7 +3003,6 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& eph_map) +{ + std::string line; + std::map::const_iterator glonass_gnav_ephemeris_iter; + + for(glonass_gnav_ephemeris_iter = eph_map.begin(); + glonass_gnav_ephemeris_iter != eph_map.end(); + glonass_gnav_ephemeris_iter++) + { + // -------- SV / EPOCH / SV CLK + boost::posix_time::ptime p_utc_time = glonass_gnav_ephemeris_iter->second.glot_to_utc(glonass_gnav_ephemeris_iter->second.d_t_b, 0.0); + std::string timestring = boost::posix_time::to_iso_string(p_utc_time); + std::string month (timestring, 4, 2); + std::string day (timestring, 6, 2); + std::string hour (timestring, 9, 2); + std::string minutes (timestring, 11, 2); + std::string seconds (timestring, 13, 2); + if (version == 2) + { + line += Rinex_Printer::rightJustify(boost::lexical_cast(glonass_gnav_ephemeris_iter->second.i_satellite_PRN), 2); + line += std::string(1, ' '); + std::string year (timestring, 2, 2); + line += year; + line += std::string(1, ' '); + if(boost::lexical_cast(month) < 10) + { + line += std::string(1, ' '); + line += std::string(month, 1, 1); + } + else + { + line += month; + } + line += std::string(1, ' '); + if(boost::lexical_cast(day) < 10) + { + line += std::string(1, ' '); + line += std::string(day, 1, 1); + } + else + { + line += day; + } + line += std::string(1, ' '); + if(boost::lexical_cast(hour) < 10) + { + line += std::string(1, ' '); + line += std::string(hour, 1, 1); + } + else + { + line += hour; + } + line += std::string(1, ' '); + if(boost::lexical_cast(minutes) < 10) + { + line += std::string(1, ' '); + line += std::string(minutes, 1, 1); + } + else + { + line += minutes; + } + line += std::string(1, ' '); + if(boost::lexical_cast(seconds) < 10) + { + line += std::string(1, ' '); + line += std::string(seconds, 1, 1); + } + else + { + line += seconds; + } + line += std::string(1, '.'); + std::string decimal = std::string("0"); + if (timestring.size() > 16) + { + std::string decimal (timestring, 16, 1); + } + line += decimal; + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(-glonass_gnav_ephemeris_iter->second.d_tau_c, 18, 2); + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_gamma_n, 18, 2); + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_t_k, 18, 2); + line += std::string(1, ' '); + } + if (version == 3) + { + line += satelliteSystem["GLONASS"]; + if (glonass_gnav_ephemeris_iter->second.i_satellite_PRN < 10) line += std::string("0"); + line += boost::lexical_cast(glonass_gnav_ephemeris_iter->second.i_satellite_PRN); + std::string year (timestring, 0, 4); + line += std::string(1, ' '); + line += year; + line += std::string(1, ' '); + line += month; + line += std::string(1, ' '); + line += day; + line += std::string(1, ' '); + line += hour; + line += std::string(1, ' '); + line += minutes; + line += std::string(1, ' '); + line += seconds; + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(-glonass_gnav_ephemeris_iter->second.d_tau_n, 18, 2); + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(+glonass_gnav_ephemeris_iter->second.d_gamma_n, 18, 2); + line += std::string(1, ' '); + //TODO need to define this here. what is nd + line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_t_k + p_utc_time.date().day_of_week()*86400, 18, 2); + } + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- BROADCAST ORBIT - 1 + line.clear(); + // TODO Why is this happening here?. The extra space maybe is intended to help with readability + if (version == 2) + { + line += std::string(3, ' '); + } + if (version == 3) + { + line += std::string(4, ' '); + } + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_Xn, 18, 2); + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_VXn, 18, 2); + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_AXn, 18, 2); + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_B_n, 18, 2); + if (version == 2) + { + line += std::string(1, ' '); + } + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- BROADCAST ORBIT - 2 + line.clear(); + if (version == 2) + { + line += std::string(3, ' '); + } + if (version == 3) + { + line += std::string(4, ' '); + } + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_Yn, 18, 2); + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_VYn, 18, 2); + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_AYn, 18, 2); + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.i_satellite_freq_channel, 18, 2); + if (version == 2) + { + line += std::string(1, ' '); + } + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- BROADCAST ORBIT - 3 + line.clear(); + if (version == 2) + { + line += std::string(3, ' '); + } + if (version == 3) + { + line += std::string(4, ' '); + } + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_Zn, 18, 2); + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_VZn, 18, 2); + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_AZn, 18, 2); + line += std::string(1, ' '); + line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_E_n, 18, 2); + if (version == 2) + { + line += std::string(1, ' '); + } + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + line.clear(); + } +} + + void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& galileo_eph_map) { version = 3; @@ -2206,6 +3226,1339 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& glonass_gnav_eph_map) +{ + Rinex_Printer::log_rinex_nav(out, gps_eph_map); + Rinex_Printer::log_rinex_nav(out, glonass_gnav_eph_map); +} + + +void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& glonass_gnav_eph_map) +{ + Rinex_Printer::log_rinex_nav(out, gps_eph_map); + Rinex_Printer::log_rinex_nav(out, glonass_gnav_eph_map); +} + + +void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& galileo_eph_map, const std::map& glonass_gnav_eph_map) +{ + version = 3; + stringVersion = "3.02"; + Rinex_Printer::log_rinex_nav(out, galileo_eph_map); + Rinex_Printer::log_rinex_nav(out, glonass_gnav_eph_map); +} + + +void Rinex_Printer::rinex_obs_header(std::fstream& out, const Glonass_Gnav_Ephemeris& eph, const double d_TOW_first_observation, const std::string glonass_bands) +{ + if(eph.d_m){} //Avoid compiler warning + std::string line; + std::map::const_iterator glonass_gnav_ephemeris_iter; + + // -------- Line 1 + line = std::string(5, ' '); + line += stringVersion; + line += std::string(11, ' '); + line += Rinex_Printer::leftJustify("OBSERVATION DATA", 20); + line += satelliteSystem["GLONASS"]; + line += std::string(19, ' '); + line += std::string("RINEX VERSION / TYPE"); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 2 + line.clear(); + if (version == 2) + { + line += Rinex_Printer::leftJustify("BLANK OR G = GPS, R = GLONASS, E = GALILEO, M = MIXED", 60); + } + if (version == 3) + { + line += Rinex_Printer::leftJustify("G = GPS R = GLONASS E = GALILEO S = GEO M = MIXED", 60); + } + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 3 + line.clear(); + line += Rinex_Printer::getLocalTime(); + line += std::string("PGM / RUN BY / DATE"); + line += std::string(1, ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("GLONASS OBSERVATION DATA FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + std::string gnss_sdr_version(GNSS_SDR_VERSION); + line += "GNSS-SDR VERSION "; + line += Rinex_Printer::leftJustify(gnss_sdr_version, 43); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("See http://gnss-sdr.org", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line MARKER NAME + line.clear(); + line += Rinex_Printer::leftJustify("DEFAULT MARKER NAME", 60); // put a flag or a property, + line += Rinex_Printer::leftJustify("MARKER NAME", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line MARKER TYPE + if (version == 2) + { + line.clear(); + line += Rinex_Printer::leftJustify("GROUND_CRAFT", 20); // put a flag or a property + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("MARKER NUMBER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + if (version == 3) + { + line.clear(); + line += Rinex_Printer::leftJustify("GROUND_CRAFT", 20); // put a flag or a property + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("MARKER TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + + // -------- Line OBSERVER / AGENCY + line.clear(); + std::string username; + char c_username[20] = {0}; + int nGet = getlogin_r(c_username, sizeof(c_username) - 1); + if (nGet == 0) + { + username = c_username; + } + else + { + username = "UNKNOWN USER"; + } + line += leftJustify(username, 20); + line += Rinex_Printer::leftJustify("CTTC", 40); // add flag and property + line += Rinex_Printer::leftJustify("OBSERVER / AGENCY", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line REC / TYPE VERS + line.clear(); + line += Rinex_Printer::leftJustify("GNSS-SDR", 20); // add flag and property + line += Rinex_Printer::leftJustify("Software Receiver", 20); // add flag and property + //line += Rinex_Printer::leftJustify(google::VersionString(), 20); // add flag and property + if(gnss_sdr_version.length() > 20) gnss_sdr_version.resize(9, ' '); + line += Rinex_Printer::leftJustify(gnss_sdr_version, 20); + line += Rinex_Printer::leftJustify("REC # / TYPE / VERS", 20); + lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA TYPE + line.clear(); + line += Rinex_Printer::leftJustify("Antenna number", 20); // add flag and property + line += Rinex_Printer::leftJustify("Antenna type", 20); // add flag and property + line += std::string(20, ' '); + line += Rinex_Printer::leftJustify("ANT # / TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- APPROX POSITION (optional for moving platforms) + // put here real data! + double antena_x = 0.0; + double antena_y = 0.0; + double antena_z = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_x, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_y, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_z, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("APPROX POSITION XYZ", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA: DELTA H/E/N + // put here real data! + double antena_h = 0.0; + double antena_e = 0.0; + double antena_n = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_h, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_e, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_n, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("ANTENNA: DELTA H/E/N", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- SYS / OBS TYPES + if (version == 3) + { + // -------- SYS / OBS TYPES + // one line per available system + line.clear(); + line += satelliteSystem["GLONASS"]; + line += std::string(2, ' '); + std::stringstream strm; + numberTypesObservations = 4; + strm << numberTypesObservations; + line += Rinex_Printer::rightJustify(strm.str(), 3); + + std::string signal_ = "1G"; + std::size_t found_1G = glonass_bands.find(signal_); + signal_ = "2G"; + std::size_t found_2G = glonass_bands.find(signal_); + + if(found_1G != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GLONASS_G1_CA"]; + } + + if(found_2G != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GLONASS_G2_CA"]; + } + + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + if (version == 2) + { + // -------- SYS / OBS TYPES + line.clear(); + std::stringstream strm; + strm << numberTypesObservations; + line += Rinex_Printer::rightJustify(strm.str(), 6); + // per type of observation + // GLONASS L1 C/A PSEUDORANGE + line += Rinex_Printer::rightJustify(observationType["PSEUDORANGE_CA_v2"], 5); + line += observationCode["GLONASS_G1_CA_v2"]; + // GLONASS L1 PHASE + line += Rinex_Printer::rightJustify(observationType["CARRIER_PHASE_CA_v2"], 5); + line += observationCode["GLONASS_G1_CA_v2"]; + // GLONASS DOPPLER L1 + line += Rinex_Printer::rightJustify(observationType["DOPPLER_v2"], 5); + line += observationCode["GLONASS_G1_CA_v2"]; + // GLONASS L1 SIGNAL STRENGTH + line += Rinex_Printer::rightJustify(observationType["SIGNAL_STRENGTH_v2"], 5); + line += observationCode["GLONASS_G1_CA_v2"]; + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("# / TYPES OF OBSERV", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + + // -------- Signal Strength units (Only version 3) + if (version == 3) + { + // -------- Signal Strength units + line.clear(); + line += Rinex_Printer::leftJustify("DBHZ", 20); + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("SIGNAL STRENGTH UNIT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + + // -------- TIME OF FIRST OBS + boost::posix_time::ptime p_utc_time = Rinex_Printer::compute_UTC_time(eph,d_TOW_first_observation); + std::string timestring = boost::posix_time::to_iso_string(p_utc_time); + std::string year (timestring, 0, 4); + std::string month (timestring, 4, 2); + std::string day (timestring, 6, 2); + std::string hour (timestring, 9, 2); + std::string minutes (timestring, 11, 2); + double intpart = 0; + double seconds = p_utc_time.time_of_day().seconds() + modf (d_TOW_first_observation , &intpart); + line.clear(); + line += Rinex_Printer::rightJustify(year, 6); + line += Rinex_Printer::rightJustify(month, 6); + line += Rinex_Printer::rightJustify(day, 6); + line += Rinex_Printer::rightJustify(hour, 6); + line += Rinex_Printer::rightJustify(minutes, 6); + line += Rinex_Printer::rightJustify(asString(seconds, 7), 13); + line += Rinex_Printer::rightJustify(std::string("GLO"), 8); + line += std::string(9, ' '); + line += Rinex_Printer::leftJustify("TIME OF FIRST OBS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- GLONASS SLOT / FRQ # (On;y version 3) + if (version == 3) + { + // -------- GLONASS SLOT / FRQ # + // TODO Need to provide system with list of all satellites and update this accordingly + line.clear(); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 3); // Number of satellites in list + line += std::string(1, ' '); + line += satelliteSystem["GLONASS"]; + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Slot Number + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Frequency Number + line += std::string(1, ' '); + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("GLONASS SLOT / FRQ #", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- GLONASS CODE/PHS/BIS + // No GLONASS Phase bias correction used to align code and phase observations. + line.clear(); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_P"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_P"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("GLONASS COD/PHS/BIS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + + // -------- END OF HEADER + line.clear(); + line += std::string(60, ' '); + line += Rinex_Printer::leftJustify("END OF HEADER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; +} + + +void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double d_TOW_first_observation, const std::string glonass_bands) +{ + if(glonass_gnav_eph.d_m){} // avoid warning, not needed + std::string line; + + // -------- Line 1 + line = std::string(5, ' '); + line += stringVersion; + line += std::string(11, ' '); + line += Rinex_Printer::leftJustify("OBSERVATION DATA", 20); + line += satelliteSystem["Mixed"]; + line += std::string(19, ' '); + line += std::string("RINEX VERSION / TYPE"); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 2 + line.clear(); + line += Rinex_Printer::leftJustify("G = GPS R = GLONASS E = GALILEO S = GEO M = MIXED", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 3 + line.clear(); + line += Rinex_Printer::getLocalTime(); + line += std::string("PGM / RUN BY / DATE"); + line += std::string(1, ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("MIXED (GPS/GLO) OBSERVATION DATA FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + std::string gnss_sdr_version(GNSS_SDR_VERSION); + line += "GNSS-SDR VERSION "; + line += Rinex_Printer::leftJustify(gnss_sdr_version, 43); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("See http://gnss-sdr.org", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line MARKER NAME / TYPE + if (version == 2) + { + line.clear(); + line += Rinex_Printer::leftJustify("GROUND_CRAFT", 20); // put a flag or a property + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("MARKER NUMBER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + if (version == 3) + { + line.clear(); + line += Rinex_Printer::leftJustify("GROUND_CRAFT", 20); // put a flag or a property + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("MARKER TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + + // -------- Line MARKER TYPE + line.clear(); + line += Rinex_Printer::leftJustify("NON_GEODETIC", 20); // put a flag or a property + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("MARKER TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line OBSERVER / AGENCY + line.clear(); + std::string username; + char c_username[20] = {0}; + int nGet = getlogin_r(c_username, sizeof(c_username) - 1); + if (nGet == 0) + { + username = c_username; + } + else + { + username = "UNKNOWN USER"; + } + line += leftJustify(username, 20); + line += Rinex_Printer::leftJustify("CTTC", 40); // add flag and property + line += Rinex_Printer::leftJustify("OBSERVER / AGENCY", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line REC / TYPE VERS + line.clear(); + line += Rinex_Printer::leftJustify("GNSS-SDR", 20); // add flag and property + line += Rinex_Printer::leftJustify("Software Receiver", 20); // add flag and property + //line += Rinex_Printer::leftJustify(google::VersionString(), 20); // add flag and property + if(gnss_sdr_version.length() > 20) gnss_sdr_version.resize(9, ' '); + line += Rinex_Printer::leftJustify(gnss_sdr_version, 20); + line += Rinex_Printer::leftJustify("REC # / TYPE / VERS", 20); + lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA TYPE + line.clear(); + line += Rinex_Printer::leftJustify("Antenna number", 20); // add flag and property + line += Rinex_Printer::leftJustify("Antenna type", 20); // add flag and property + line += std::string(20, ' '); + line += Rinex_Printer::leftJustify("ANT # / TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- APPROX POSITION (optional for moving platforms) + // put here real data! + double antena_x = 0.0; + double antena_y = 0.0; + double antena_z = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_x, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_y, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_z, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("APPROX POSITION XYZ", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA: DELTA H/E/N + // put here real data! + double antena_h = 0.0; + double antena_e = 0.0; + double antena_n = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_h, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_e, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_n, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("ANTENNA: DELTA H/E/N", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- SYS / OBS TYPES + if(version == 3) + { + // one line per available system + line.clear(); + line += satelliteSystem["GPS"]; + line += std::string(2, ' '); + std::stringstream strm; + numberTypesObservations = 4; + strm << numberTypesObservations; + line += Rinex_Printer::rightJustify(strm.str(), 3); + // per type of observation + // GPS L1 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L1_CA"]; + // GPS L1 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L1_CA"]; + // GPS DOPPLER L1 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L1_CA"]; + // GPS L1 CA SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L1_CA"]; + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // Find GLONASS Signal in Mixed file + unsigned int number_of_observations_glo = 0; + std::string signal_("1G"); + std::size_t found_1G = glonass_bands.find(signal_); + if(found_1G != std::string::npos) + { + number_of_observations_glo = number_of_observations_glo + 4; + } + signal_ = "2G"; + std::size_t found_2G = glonass_bands.find(signal_); + if(found_2G != std::string::npos) + { + number_of_observations_glo = number_of_observations_glo + 4; + } + line.clear(); + line += satelliteSystem["GLONASS"]; + line += std::string(2, ' '); + line += Rinex_Printer::rightJustify(std::to_string(number_of_observations_glo), 3); + if(found_1G != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GLONASS_G1_CA"]; + } + if(found_2G != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GLONASS_G2_CA"]; + } + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + if(version == 2) + { + // -------- SYS / OBS TYPES + line.clear(); + std::stringstream strm; + strm << numberTypesObservations; + line += Rinex_Printer::rightJustify(strm.str(), 6); + // per type of observation + // GLONASS L1 C/A PSEUDORANGE + line += Rinex_Printer::rightJustify(observationType["PSEUDORANGE_CA_v2"], 5); + line += observationCode["GLONASS_G1_CA_v2"]; + // GLONASS L1 PHASE + line += Rinex_Printer::rightJustify(observationType["CARRIER_PHASE_CA_v2"], 5); + line += observationCode["GLONASS_G1_CA_v2"]; + // GLONASS DOPPLER L1 + line += Rinex_Printer::rightJustify(observationType["DOPPLER_v2"], 5); + line += observationCode["GLONASS_G1_CA_v2"]; + // GLONASS L1 SIGNAL STRENGTH + line += Rinex_Printer::rightJustify(observationType["SIGNAL_STRENGTH_v2"], 5); + line += observationCode["GLONASS_G1_CA_v2"]; + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("# / TYPES OF OBSERV", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + + // -------- Signal Strength units (only version 3) + if(version == 3) + { + line.clear(); + line += Rinex_Printer::leftJustify("DBHZ", 20); + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("SIGNAL STRENGTH UNIT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + + // -------- TIME OF FIRST OBS + line.clear(); + boost::posix_time::ptime p_gps_time = Rinex_Printer::compute_GPS_time(gps_eph, d_TOW_first_observation); + std::string timestring=boost::posix_time::to_iso_string(p_gps_time); + std::string year (timestring, 0, 4); + std::string month (timestring, 4, 2); + std::string day (timestring, 6, 2); + std::string hour (timestring, 9, 2); + std::string minutes (timestring, 11, 2); + double gps_t = d_TOW_first_observation; + double seconds = fmod(gps_t, 60); + line += Rinex_Printer::rightJustify(year, 6); + line += Rinex_Printer::rightJustify(month, 6); + line += Rinex_Printer::rightJustify(day, 6); + line += Rinex_Printer::rightJustify(hour, 6); + line += Rinex_Printer::rightJustify(minutes, 6); + line += Rinex_Printer::rightJustify(asString(seconds, 7), 13); + line += Rinex_Printer::rightJustify(std::string("GPS"), 8); + line += std::string(9, ' '); + line += Rinex_Printer::leftJustify("TIME OF FIRST OBS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- GLONASS SLOT / FRQ # (On;y version 3) + if (version == 3) + { + // -------- GLONASS SLOT / FRQ # + // TODO Need to provide system with list of all satellites and update this accordingly + line.clear(); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 3); // Number of satellites in list + line += std::string(1, ' '); + line += satelliteSystem["GLONASS"]; + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Slot Number + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Frequency Number + line += std::string(1, ' '); + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("GLONASS SLOT / FRQ #", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- GLONASS CODE/PHS/BIS + // No GLONASS Phase bias correction used to align code and phase observations. + line.clear(); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_P"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_P"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("GLONASS COD/PHS/BIS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + + // -------- end of header + line.clear(); + line += std::string(60, ' '); + line += Rinex_Printer::leftJustify("END OF HEADER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; +} + + +void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double d_TOW_first_observation, const std::string glonass_bands) +{ + if(glonass_gnav_eph.d_m){} // avoid warning, not needed + std::string line; + + // -------- Line 1 + line = std::string(5, ' '); + line += stringVersion; + line += std::string(11, ' '); + line += Rinex_Printer::leftJustify("OBSERVATION DATA", 20); + line += satelliteSystem["Mixed"]; + line += std::string(19, ' '); + line += std::string("RINEX VERSION / TYPE"); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 2 + line.clear(); + line += Rinex_Printer::leftJustify("G = GPS R = GLONASS E = GALILEO S = GEO M = MIXED", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 3 + line.clear(); + line += Rinex_Printer::getLocalTime(); + line += std::string("PGM / RUN BY / DATE"); + line += std::string(1, ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("MIXED (GPS/GLO) OBSERVATION DATA FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + std::string gnss_sdr_version(GNSS_SDR_VERSION); + line += "GNSS-SDR VERSION "; + line += Rinex_Printer::leftJustify(gnss_sdr_version, 43); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("See http://gnss-sdr.org", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line MARKER NAME + if (version == 2) + { + line.clear(); + line += Rinex_Printer::leftJustify("GROUND_CRAFT", 20); // put a flag or a property + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("MARKER NUMBER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + if (version == 3) + { + line.clear(); + line += Rinex_Printer::leftJustify("GROUND_CRAFT", 20); // put a flag or a property + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("MARKER TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + + // -------- Line MARKER TYPE + line.clear(); + line += Rinex_Printer::leftJustify("NON_GEODETIC", 20); // put a flag or a property + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("MARKER TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line OBSERVER / AGENCY + line.clear(); + std::string username; + char c_username[20] = {0}; + int nGet = getlogin_r(c_username, sizeof(c_username) - 1); + if (nGet == 0) + { + username = c_username; + } + else + { + username = "UNKNOWN USER"; + } + line += leftJustify(username, 20); + line += Rinex_Printer::leftJustify("CTTC", 40); // add flag and property + line += Rinex_Printer::leftJustify("OBSERVER / AGENCY", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line REC / TYPE VERS + line.clear(); + line += Rinex_Printer::leftJustify("GNSS-SDR", 20); // add flag and property + line += Rinex_Printer::leftJustify("Software Receiver", 20); // add flag and property + //line += Rinex_Printer::leftJustify(google::VersionString(), 20); // add flag and property + if(gnss_sdr_version.length() > 20) gnss_sdr_version.resize(9, ' '); + line += Rinex_Printer::leftJustify(gnss_sdr_version, 20); + line += Rinex_Printer::leftJustify("REC # / TYPE / VERS", 20); + lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA TYPE + line.clear(); + line += Rinex_Printer::leftJustify("Antenna number", 20); // add flag and property + line += Rinex_Printer::leftJustify("Antenna type", 20); // add flag and property + line += std::string(20, ' '); + line += Rinex_Printer::leftJustify("ANT # / TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- APPROX POSITION (optional for moving platforms) + // put here real data! + double antena_x = 0.0; + double antena_y = 0.0; + double antena_z = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_x, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_y, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_z, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("APPROX POSITION XYZ", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA: DELTA H/E/N + // put here real data! + double antena_h = 0.0; + double antena_e = 0.0; + double antena_n = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_h, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_e, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_n, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("ANTENNA: DELTA H/E/N", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- SYS / OBS TYPES + // one line per available system + line.clear(); + line += satelliteSystem["GPS"]; + line += std::string(2, ' '); + std::stringstream strm; + numberTypesObservations = 4; + strm << numberTypesObservations; + line += Rinex_Printer::rightJustify(strm.str(), 3); + // per type of observation + // GPS L1 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L1 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS DOPPLER L1 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L1 CA SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L2_L2CM"]; + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // Find GLONASS Signal in Mixed file + unsigned int number_of_observations_glo = 0; + std::string signal_("1G"); + std::size_t found_1G = glonass_bands.find(signal_); + if(found_1G != std::string::npos) + { + number_of_observations_glo = number_of_observations_glo + 4; + } + signal_ = "2G"; + std::size_t found_2G = glonass_bands.find(signal_); + if(found_2G != std::string::npos) + { + number_of_observations_glo = number_of_observations_glo + 4; + } + line.clear(); + line += satelliteSystem["GLONASS"]; + line += std::string(2, ' '); + line += Rinex_Printer::rightJustify(std::to_string(number_of_observations_glo), 3); + if(found_1G != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GLONASS_G1_CA"]; + } + if(found_2G != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GLONASS_G2_CA"]; + } + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Signal Strength units (only version 3) + line.clear(); + line += Rinex_Printer::leftJustify("DBHZ", 20); + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("SIGNAL STRENGTH UNIT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- TIME OF FIRST OBS + line.clear(); + boost::posix_time::ptime p_gps_time = Rinex_Printer::compute_GPS_time(gps_eph, d_TOW_first_observation); + std::string timestring=boost::posix_time::to_iso_string(p_gps_time); + std::string year (timestring, 0, 4); + std::string month (timestring, 4, 2); + std::string day (timestring, 6, 2); + std::string hour (timestring, 9, 2); + std::string minutes (timestring, 11, 2); + double gps_t = d_TOW_first_observation; + double seconds = fmod(gps_t, 60); + line += Rinex_Printer::rightJustify(year, 6); + line += Rinex_Printer::rightJustify(month, 6); + line += Rinex_Printer::rightJustify(day, 6); + line += Rinex_Printer::rightJustify(hour, 6); + line += Rinex_Printer::rightJustify(minutes, 6); + line += Rinex_Printer::rightJustify(asString(seconds, 7), 13); + line += Rinex_Printer::rightJustify(std::string("GPS"), 8); + line += std::string(9, ' '); + line += Rinex_Printer::leftJustify("TIME OF FIRST OBS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- GLONASS SLOT / FRQ # + // TODO Need to provide system with list of all satellites and update this accordingly + line.clear(); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 3); // Number of satellites in list + line += std::string(1, ' '); + line += satelliteSystem["GLONASS"]; + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Slot Number + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Frequency Number + line += std::string(1, ' '); + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("GLONASS SLOT / FRQ #", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- GLONASS CODE/PHS/BIS + // No GLONASS Phase bias correction used to align code and phase observations. + line.clear(); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_P"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_P"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("GLONASS COD/PHS/BIS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- end of header + line.clear(); + line += std::string(60, ' '); + line += Rinex_Printer::leftJustify("END OF HEADER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; +} + + +void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris& galileo_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double d_TOW_first_observation, const std::string galileo_bands, const std::string glonass_bands) +{ + if(glonass_gnav_eph.d_m){} // avoid warning, not needed + std::string line; + version = 3; + + // -------- Line 1 + line = std::string(5, ' '); + line += "3.02"; + line += std::string(11, ' '); + line += Rinex_Printer::leftJustify("OBSERVATION DATA", 20); + line += satelliteSystem["Mixed"]; + line += std::string(19, ' '); + line += std::string("RINEX VERSION / TYPE"); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 2 + line.clear(); + line += Rinex_Printer::leftJustify("G = GPS R = GLONASS E = GALILEO S = GEO M = MIXED", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 3 + line.clear(); + line += Rinex_Printer::getLocalTime(); + line += std::string("PGM / RUN BY / DATE"); + line += std::string(1, ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("MIXED (GALILEO/GLONASS) OBSERVATION DATA FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + std::string gnss_sdr_version(GNSS_SDR_VERSION); + line += "GNSS-SDR VERSION "; + line += Rinex_Printer::leftJustify(gnss_sdr_version, 43); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("See http://gnss-sdr.org", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line MARKER NAME + line.clear(); + line += Rinex_Printer::leftJustify("DEFAULT MARKER NAME", 60); // put a flag or a property, + line += Rinex_Printer::leftJustify("MARKER TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line MARKER TYPE + line.clear(); + line += Rinex_Printer::leftJustify("NON_GEODETIC", 20); // put a flag or a property + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("MARKER TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line OBSERVER / AGENCY + line.clear(); + std::string username; + char c_username[20] = {0}; + int nGet = getlogin_r(c_username, sizeof(c_username) - 1); + if (nGet == 0) + { + username = c_username; + } + else + { + username = "UNKNOWN USER"; + } + line += leftJustify(username, 20); + line += Rinex_Printer::leftJustify("CTTC", 40); // add flag and property + line += Rinex_Printer::leftJustify("OBSERVER / AGENCY", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line REC / TYPE VERS + line.clear(); + line += Rinex_Printer::leftJustify("GNSS-SDR", 20); // add flag and property + line += Rinex_Printer::leftJustify("Software Receiver", 20); // add flag and property + //line += Rinex_Printer::leftJustify(google::VersionString(), 20); // add flag and property + if(gnss_sdr_version.length() > 20) gnss_sdr_version.resize(9, ' '); + line += Rinex_Printer::leftJustify(gnss_sdr_version, 20); + line += Rinex_Printer::leftJustify("REC # / TYPE / VERS", 20); + lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA TYPE + line.clear(); + line += Rinex_Printer::leftJustify("Antenna number", 20); // add flag and property + line += Rinex_Printer::leftJustify("Antenna type", 20); // add flag and property + line += std::string(20, ' '); + line += Rinex_Printer::leftJustify("ANT # / TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- APPROX POSITION (optional for moving platforms) + // put here real data! + double antena_x = 0.0; + double antena_y = 0.0; + double antena_z = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_x, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_y, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_z, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("APPROX POSITION XYZ", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA: DELTA H/E/N + // put here real data! + double antena_h = 0.0; + double antena_e = 0.0; + double antena_n = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_h, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_e, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_n, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("ANTENNA: DELTA H/E/N", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- SYS / OBS TYPES + line.clear(); + unsigned int number_of_observations_gal = 0; + std::string signal_("1B"); + std::size_t found_1B = galileo_bands.find(signal_); + if(found_1B != std::string::npos) + { + number_of_observations_gal = number_of_observations_gal + 4; + } + signal_ = "5X"; + std::size_t found_5X = galileo_bands.find(signal_); + if(found_5X != std::string::npos) + { + number_of_observations_gal = number_of_observations_gal + 4; + } + + line.clear(); + signal_ = "7X"; + std::size_t found_7X = galileo_bands.find(signal_); + if(found_7X != std::string::npos) + { + number_of_observations_gal = number_of_observations_gal + 4; + } + + + line += satelliteSystem["Galileo"]; + line += std::string(2, ' '); + line += Rinex_Printer::rightJustify(std::to_string(number_of_observations_gal), 3); + + if(found_1B != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GALILEO_E1_B"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GALILEO_E1_B"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GALILEO_E1_B"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GALILEO_E1_B"]; + } + + if(found_5X != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GALILEO_E5a_IQ"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GALILEO_E5a_IQ"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GALILEO_E5a_IQ"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GALILEO_E5a_IQ"]; + } + + if(found_7X != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GALILEO_E5b_IQ"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GALILEO_E5b_IQ"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GALILEO_E5b_IQ"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GALILEO_E5b_IQ"]; + } + + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + line.clear(); + unsigned int number_of_observations_glo = 0; + signal_ = "1G"; + std::size_t found_1G = glonass_bands.find(signal_); + if(found_1G != std::string::npos) + { + number_of_observations_glo = number_of_observations_glo + 4; + } + signal_ = "2G"; + std::size_t found_2G = glonass_bands.find(signal_); + if(found_2G != std::string::npos) + { + number_of_observations_glo = number_of_observations_glo + 4; + } + + line += satelliteSystem["GLONASS"]; + line += std::string(2, ' '); + line += Rinex_Printer::rightJustify(std::to_string(number_of_observations_glo), 3); + + if(found_1G != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_L1_CA"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GLONASS_L1_CA"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GLONASS_L1_CA"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GLONASS_L1_CA"]; + } + + if(found_2G != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_L2_CA"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GLONASS_L2_CA"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GLONASS_L2_CA"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GLONASS_L2_CA"]; + } + + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Signal Strength units + line.clear(); + line += Rinex_Printer::leftJustify("DBHZ", 20); + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("SIGNAL STRENGTH UNIT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- TIME OF FIRST OBS + line.clear(); + boost::posix_time::ptime p_galileo_time = Rinex_Printer::compute_Galileo_time(galileo_eph, d_TOW_first_observation); + std::string timestring=boost::posix_time::to_iso_string(p_galileo_time); + std::string year (timestring, 0, 4); + std::string month (timestring, 4, 2); + std::string day (timestring, 6, 2); + std::string hour (timestring, 9, 2); + std::string minutes (timestring, 11, 2); + double galileo_t = d_TOW_first_observation; + double seconds = fmod(galileo_t, 60); + line += Rinex_Printer::rightJustify(year, 6); + line += Rinex_Printer::rightJustify(month, 6); + line += Rinex_Printer::rightJustify(day, 6); + line += Rinex_Printer::rightJustify(hour, 6); + line += Rinex_Printer::rightJustify(minutes, 6); + line += Rinex_Printer::rightJustify(asString(seconds, 7), 13); + line += Rinex_Printer::rightJustify(std::string("Galileo"), 8); + line += std::string(9, ' '); + line += Rinex_Printer::leftJustify("TIME OF FIRST OBS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- end of header + line.clear(); + line += std::string(60, ' '); + line += Rinex_Printer::leftJustify("END OF HEADER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; +} + + void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph, const double d_TOW_first_observation) { std::string line; @@ -2905,10 +5258,11 @@ void Rinex_Printer::rinex_obs_header(std::fstream & out, const Gps_Ephemeris & e void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris& eph, const double d_TOW_first_observation, const std::string bands) { std::string line; + version = 3; // -------- Line 1 line = std::string(5, ' '); - line += stringVersion; + line += "3.02"; line += std::string(11, ' '); line += Rinex_Printer::leftJustify("OBSERVATION DATA", 20); line += satelliteSystem["Galileo"]; @@ -3166,10 +5520,11 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps { if(galileo_eph.e_1){} // avoid warning, not needed std::string line; + version = 3; // -------- Line 1 line = std::string(5, ' '); - line += stringVersion; + line += "3.02"; line += std::string(11, ' '); line += Rinex_Printer::leftJustify("OBSERVATION DATA", 20); line += satelliteSystem["Mixed"]; @@ -3352,7 +5707,6 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps number_of_observations_gal = number_of_observations_gal + 4; } - line += satelliteSystem["Galileo"]; line += std::string(2, ' '); line += Rinex_Printer::rightJustify(std::to_string(number_of_observations_gal), 3); @@ -3450,6 +5804,15 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps } +void Rinex_Printer::update_obs_header(std::fstream& out __attribute__((unused)), const Glonass_Gnav_Utc_Model& utc_model) +{ + if(utc_model.d_N_4) + { + // do nothing + } +} + + void Rinex_Printer::update_obs_header(std::fstream& out, const Gps_Utc_Model& utc_model) { std::vector data; @@ -3652,6 +6015,1037 @@ void Rinex_Printer::update_obs_header(std::fstream& out, const Galileo_Utc_Model } +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeris& eph, const double obs_time, const std::map& observables, const std::string glonass_band) +{ + // RINEX observations timestamps are GPS timestamps. + std::string line; + + // Avoid compiler warning + if(glonass_band.size()){} + + boost::posix_time::ptime p_glonass_time = Rinex_Printer::compute_UTC_time(eph, obs_time); + std::string timestring = boost::posix_time::to_iso_string(p_glonass_time); + //double utc_t = nav_msg.utc_time(nav_msg.sv_clock_correction(obs_time)); + //double gps_t = eph.sv_clock_correction(obs_time); + double glonass_t = obs_time; + + std::string month (timestring, 4, 2); + std::string day (timestring, 6, 2); + std::string hour (timestring, 9, 2); + std::string minutes (timestring, 11, 2); + + if (version == 2) + { + line.clear(); + std::string year (timestring, 2, 2); + line += std::string(1, ' '); + line += year; + line += std::string(1, ' '); + if (month.compare(0, 1 , "0") == 0) + { + line += std::string(1, ' '); + line += month.substr(1, 1); + } + else + { + line += month; + } + line += std::string(1, ' '); + if (day.compare(0, 1 , "0") == 0) + { + line += std::string(1, ' '); + line += day.substr(1, 1); + } + else + { + line += day; + } + line += std::string(1, ' '); + line += hour; + line += std::string(1, ' '); + line += minutes; + line += std::string(1, ' '); + double second_ = fmod(glonass_t, 60); + if (second_ < 10) + { + line += std::string(1, ' '); + } + line += Rinex_Printer::asString(second_, 7); + line += std::string(2, ' '); + // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event + line += std::string(1, '0'); + //Number of satellites observed in current epoch + int numSatellitesObserved = 0; + std::map::const_iterator observables_iter; + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + numSatellitesObserved++; + } + line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + line += satelliteSystem["GLONASS"]; + if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); + line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + } + // Receiver clock offset (optional) + //line += rightJustify(asString(clockOffset, 12), 15); + line += std::string(80 - line.size(), ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + std::string lineObs; + lineObs.clear(); + line.clear(); + // GLONASS L1 PSEUDORANGE + line += std::string(2, ' '); + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + // Signal Strength Indicator (SSI) + int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + // GLONASS L1 CA PHASE + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads/GLONASS_TWO_PI, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + // GLONASS L1 CA DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + //GLONASS L1 SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); + if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } + } + + if (version == 3) + { + std::string year (timestring, 0, 4); + line += std::string(1, '>'); + line += std::string(1, ' '); + line += year; + line += std::string(1, ' '); + line += month; + line += std::string(1, ' '); + line += day; + line += std::string(1, ' '); + line += hour; + line += std::string(1, ' '); + line += minutes; + + line += std::string(1, ' '); + double seconds = fmod(glonass_t, 60); + // Add extra 0 if seconds are < 10 + if (seconds < 10) + { + line += std::string(1, '0'); + } + line += Rinex_Printer::asString(seconds, 7); + line += std::string(2, ' '); + // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event + line += std::string(1, '0'); + + //Number of satellites observed in current epoch + int numSatellitesObserved = 0; + std::map::const_iterator observables_iter; + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + numSatellitesObserved++; + } + line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); + + // Receiver clock offset (optional) + //line += rightJustify(asString(clockOffset, 12), 15); + + line += std::string(80 - line.size(), ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + std::string lineObs; + lineObs.clear(); + lineObs += satelliteSystem["GLONASS"]; + if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + //lineObs += std::string(2, ' '); + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + // Signal Strength Indicator (SSI) + int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // GLONASS L1 CA PHASE + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads/GLONASS_TWO_PI, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // GLONASS L1 CA DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + //GLONASS L1 SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); + + if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } + } +} + + +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double gps_obs_time, const std::map& observables) +{ + if(glonass_gnav_eph.d_m){} // avoid warning, not needed + std::string line; + + // -------- EPOCH record + boost::posix_time::ptime p_gps_time = Rinex_Printer::compute_GPS_time(gps_eph, gps_obs_time); + std::string timestring = boost::posix_time::to_iso_string(p_gps_time); + //double utc_t = nav_msg.utc_time(nav_msg.sv_clock_correction(obs_time)); + //double gps_t = eph.sv_clock_correction(obs_time); + double gps_t = gps_obs_time; + + std::string month (timestring, 4, 2); + std::string day (timestring, 6, 2); + std::string hour (timestring, 9, 2); + std::string minutes (timestring, 11, 2); + + if (version == 2) + { + line.clear(); + std::string year (timestring, 2, 2); + line += std::string(1, ' '); + line += year; + line += std::string(1, ' '); + if (month.compare(0, 1 , "0") == 0) + { + line += std::string(1, ' '); + line += month.substr(1, 1); + } + else + { + line += month; + } + line += std::string(1, ' '); + if (day.compare(0, 1 , "0") == 0) + { + line += std::string(1, ' '); + line += day.substr(1, 1); + } + else + { + line += day; + } + line += std::string(1, ' '); + line += hour; + line += std::string(1, ' '); + line += minutes; + line += std::string(1, ' '); + double second_ = fmod(gps_t, 60); + if (second_ < 10) + { + line += std::string(1, ' '); + } + line += Rinex_Printer::asString(second_, 7); + line += std::string(2, ' '); + // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event + line += std::string(1, '0'); + } + if (version == 3) + { + std::string year (timestring, 0, 4); + line += std::string(1, '>'); + line += std::string(1, ' '); + line += year; + line += std::string(1, ' '); + line += month; + line += std::string(1, ' '); + line += day; + line += std::string(1, ' '); + line += hour; + line += std::string(1, ' '); + line += minutes; + + line += std::string(1, ' '); + double seconds = fmod(gps_t, 60); + // Add extra 0 if seconds are < 10 + if (seconds < 10) + { + line +=std::string(1, '0'); + } + line += Rinex_Printer::asString(seconds, 7); + line += std::string(2, ' '); + // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event + line += std::string(1, '0'); + } + + //Number of satellites observed in current epoch + //Get maps with observations + std::map observablesG1C; + std::map observablesR1C; + std::map observablesR2C; + std::map::const_iterator observables_iter; + + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + std::string system_(&observables_iter->second.System, 1); + std::string sig_(observables_iter->second.Signal); + if((system_.compare("R") == 0) && (sig_.compare("1G") == 0)) + { + observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if((system_.compare("R") == 0) && (sig_.compare("2G") == 0)) + { + observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if((system_.compare("G") == 0) && (sig_.compare("1C") == 0)) + { + observablesG1C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } + + std::multimap total_glo_map; + std::set available_glo_prns; + std::set::iterator it; + for(observables_iter = observablesR1C.begin(); + observables_iter != observablesR1C.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); + it = available_glo_prns.find(prn_); + if(it == available_glo_prns.end()) + { + available_glo_prns.insert(prn_); + } + } + + for(observables_iter = observablesR2C.begin(); + observables_iter != observablesR2C.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); + it = available_glo_prns.find(prn_); + if(it == available_glo_prns.end()) + { + available_glo_prns.insert(prn_); + } + } + + int numGloSatellitesObserved = available_glo_prns.size(); + int numGpsSatellitesObserved = observablesG1C.size(); + int numSatellitesObserved = numGloSatellitesObserved + numGpsSatellitesObserved; + line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); + if(version == 2) + { + // Add list of GPS satellites + for(observables_iter = observablesG1C.begin(); + observables_iter != observablesG1C.end(); + observables_iter++) + { + line += satelliteSystem["GPS"]; + if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); + line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + } + // Add list of GLONASS L1 satellites + for(observables_iter = observablesR1C.begin(); + observables_iter != observablesR1C.end(); + observables_iter++) + { + line += satelliteSystem["GLONASS"]; + if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); + line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + } + // Add list of GLONASS L2 satellites + for(observables_iter = observablesR2C.begin(); + observables_iter != observablesR2C.end(); + observables_iter++) + { + line += satelliteSystem["GLONASS"]; + if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); + line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + } + } + line += std::string(80 - line.size(), ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- OBSERVATION record + std::string s; + std::string lineObs; + for(observables_iter = observablesG1C.begin(); + observables_iter != observablesG1C.end(); + observables_iter++) + { + lineObs.clear(); + + s.assign(1, observables_iter->second.System); + if(version == 3) + { + // Specify system only if in version 3 + if(s.compare("G") == 0) lineObs += satelliteSystem["GPS"]; + if(s.compare("R") == 0) lineObs += satelliteSystem["GLONASS"]; // should not happen + if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + } + + // Pseudorange Measurements + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + // Signal Strength Indicator (SSI) + int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // PHASE + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads/GPS_TWO_PI, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); + + if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } + + std::pair ::iterator, std::multimap::iterator> ret; + for(it = available_glo_prns.begin(); + it != available_glo_prns.end(); + it++) + { + lineObs.clear(); + if(version == 3) + { + lineObs += satelliteSystem["GLONASS"]; + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); + } + ret = total_glo_map.equal_range(*it); + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + { + /// \todo Need to account for pseudorange correction for glonass + //double leap_seconds = Rinex_Printer::get_leap_second(glonass_gnav_eph, gps_obs_time); + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + // Signal Strength Indicator (SSI) + int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // GLONASS CARRIER PHASE + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GLONASS_TWO_PI), 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // GLONASS DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // GLONASS SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); + } + + if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } +} + + +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double gps_obs_time, const std::map& observables) +{ + if(glonass_gnav_eph.d_m){} // avoid warning, not needed + std::string line; + + // -------- EPOCH record + boost::posix_time::ptime p_gps_time = Rinex_Printer::compute_GPS_time(gps_eph, gps_obs_time); + std::string timestring = boost::posix_time::to_iso_string(p_gps_time); + //double utc_t = nav_msg.utc_time(nav_msg.sv_clock_correction(obs_time)); + //double gps_t = eph.sv_clock_correction(obs_time); + double gps_t = gps_obs_time; + + std::string month (timestring, 4, 2); + std::string day (timestring, 6, 2); + std::string hour (timestring, 9, 2); + std::string minutes (timestring, 11, 2); + + std::string year (timestring, 0, 4); + line += std::string(1, '>'); + line += std::string(1, ' '); + line += year; + line += std::string(1, ' '); + line += month; + line += std::string(1, ' '); + line += day; + line += std::string(1, ' '); + line += hour; + line += std::string(1, ' '); + line += minutes; + + line += std::string(1, ' '); + double seconds = fmod(gps_t, 60); + // Add extra 0 if seconds are < 10 + if (seconds < 10) + { + line +=std::string(1, '0'); + } + line += Rinex_Printer::asString(seconds, 7); + line += std::string(2, ' '); + // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event + line += std::string(1, '0'); + + //Number of satellites observed in current epoch + //Get maps with observations + std::map observablesG2S; + std::map observablesR1C; + std::map observablesR2C; + std::map::const_iterator observables_iter; + + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + std::string system_(&observables_iter->second.System, 1); + std::string sig_(observables_iter->second.Signal); + if((system_.compare("R") == 0) && (sig_.compare("1G") == 0)) + { + observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if((system_.compare("R") == 0) && (sig_.compare("2G") == 0)) + { + observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if((system_.compare("G") == 0) && (sig_.compare("2S") == 0)) + { + observablesG2S.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } + + std::multimap total_glo_map; + std::set available_glo_prns; + std::set::iterator it; + for(observables_iter = observablesR1C.begin(); + observables_iter != observablesR1C.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); + it = available_glo_prns.find(prn_); + if(it == available_glo_prns.end()) + { + available_glo_prns.insert(prn_); + } + } + + for(observables_iter = observablesR2C.begin(); + observables_iter != observablesR2C.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); + it = available_glo_prns.find(prn_); + if(it == available_glo_prns.end()) + { + available_glo_prns.insert(prn_); + } + } + + int numGloSatellitesObserved = available_glo_prns.size(); + int numGpsSatellitesObserved = observablesG2S.size(); + int numSatellitesObserved = numGloSatellitesObserved + numGpsSatellitesObserved; + line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); + + line += std::string(80 - line.size(), ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- OBSERVATION record + std::string s; + std::string lineObs; + for(observables_iter = observablesG2S.begin(); + observables_iter != observablesG2S.end(); + observables_iter++) + { + lineObs.clear(); + + s.assign(1, observables_iter->second.System); + // Specify system only if in version 3 + if(s.compare("G") == 0) lineObs += satelliteSystem["GPS"]; + if(s.compare("R") == 0) lineObs += satelliteSystem["GLONASS"]; // should not happen + if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + + // Pseudorange Measurements + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + // Signal Strength Indicator (SSI) + int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // PHASE + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads/GPS_TWO_PI, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); + + if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } + + std::pair ::iterator, std::multimap::iterator> ret; + for(it = available_glo_prns.begin(); + it != available_glo_prns.end(); + it++) + { + lineObs.clear(); + lineObs += satelliteSystem["GLONASS"]; + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); + + ret = total_glo_map.equal_range(*it); + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + { + /// \todo Need to account for pseudorange correction for glonass + //double leap_seconds = Rinex_Printer::get_leap_second(glonass_gnav_eph, gps_obs_time); + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + // Signal Strength Indicator (SSI) + int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // GLONASS CARRIER PHASE + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GLONASS_TWO_PI), 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // GLONASS DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // GLONASS SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); + } + + if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } +} + + +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& galileo_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double galileo_obs_time, const std::map& observables) +{ + if(glonass_gnav_eph.d_m){} // avoid warning, not needed + std::string line; + + boost::posix_time::ptime p_galileo_time = Rinex_Printer::compute_Galileo_time(galileo_eph, galileo_obs_time); + std::string timestring = boost::posix_time::to_iso_string(p_galileo_time); + //double utc_t = nav_msg.utc_time(nav_msg.sv_clock_correction(obs_time)); + //double gps_t = eph.sv_clock_correction(obs_time); + double galileo_t = galileo_obs_time; + + std::string month (timestring, 4, 2); + std::string day (timestring, 6, 2); + std::string hour (timestring, 9, 2); + std::string minutes (timestring, 11, 2); + + std::string year (timestring, 0, 4); + line += std::string(1, '>'); + line += std::string(1, ' '); + line += year; + line += std::string(1, ' '); + line += month; + line += std::string(1, ' '); + line += day; + line += std::string(1, ' '); + line += hour; + line += std::string(1, ' '); + line += minutes; + + line += std::string(1, ' '); + double seconds = fmod(galileo_t, 60); + // Add extra 0 if seconds are < 10 + if (seconds < 10) + { + line +=std::string(1, '0'); + } + line += Rinex_Printer::asString(seconds, 7); + line += std::string(2, ' '); + // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event + line += std::string(1, '0'); + + //Number of satellites observed in current epoch + + //Get maps with observations + std::map observablesE1B; + std::map observablesR1C; + std::map observablesR2C; + std::map::const_iterator observables_iter; + + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + std::string system_(&observables_iter->second.System, 1); + std::string sig_(observables_iter->second.Signal); + if((system_.compare("R") == 0) && (sig_.compare("1G") == 0)) + { + observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if((system_.compare("R") == 0) && (sig_.compare("2G") == 0)) + { + observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if((system_.compare("E") == 0) && (sig_.compare("1B") == 0)) + { + observablesE1B.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } + + std::multimap total_glo_map; + std::set available_glo_prns; + std::set::iterator it; + for(observables_iter = observablesR1C.begin(); + observables_iter != observablesR1C.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); + it = available_glo_prns.find(prn_); + if(it == available_glo_prns.end()) + { + available_glo_prns.insert(prn_); + } + } + for(observables_iter = observablesR2C.begin(); + observables_iter != observablesR2C.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); + it = available_glo_prns.find(prn_); + if(it == available_glo_prns.end()) + { + available_glo_prns.insert(prn_); + } + } + + int numGloSatellitesObserved = available_glo_prns.size(); + int numGalSatellitesObserved = observablesE1B.size(); + int numSatellitesObserved = numGalSatellitesObserved + numGloSatellitesObserved; + line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); + + // Receiver clock offset (optional) + //line += rightJustify(asString(clockOffset, 12), 15); + + line += std::string(80 - line.size(), ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + std::string s; + std::string lineObs; + for(observables_iter = observablesE1B.begin(); + observables_iter != observablesE1B.end(); + observables_iter++) + { + lineObs.clear(); + + s.assign(1, observables_iter->second.System); + if(s.compare("E") == 0) lineObs += satelliteSystem["Galileo"]; + if(s.compare("R") == 0) lineObs += satelliteSystem["GLONASS"]; // should not happen + if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + // Signal Strength Indicator (SSI) + int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // PHASE + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads/GPS_TWO_PI, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); + + if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } + + std::pair ::iterator, std::multimap::iterator> ret; + for(it = available_glo_prns.begin(); + it != available_glo_prns.end(); + it++) + { + lineObs.clear(); + lineObs += satelliteSystem["Galileo"]; + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); + ret = total_glo_map.equal_range(*it); + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + { + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + // Signal Strength Indicator (SSI) + int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // GLONASS CARRIER PHASE + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GLONASS_TWO_PI), 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // GLONASS DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // GLONASS SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); + } + + if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } +} + + void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, const double obs_time, const std::map& observables) { // RINEX observations timestamps are GPS timestamps. @@ -3732,7 +7126,6 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c Rinex_Printer::lengthCheck(line); out << line << std::endl; - for(observables_iter = observables.cbegin(); observables_iter != observables.cend(); observables_iter++) @@ -3750,10 +7143,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); @@ -3764,10 +7157,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + // else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS L1 CA DOPPLER lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); @@ -3775,10 +7168,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); //GPS L1 SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); @@ -3806,9 +7199,9 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c double seconds = fmod(gps_t, 60); // Add extra 0 if seconds are < 10 if (seconds < 10) - { - line += std::string(1, '0'); - } + { + line += std::string(1, '0'); + } line += Rinex_Printer::asString(seconds, 7); line += std::string(2, ' '); // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event @@ -3825,7 +7218,6 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c } line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); - // Receiver clock offset (optional) //line += rightJustify(asString(clockOffset, 12), 15); @@ -3851,10 +7243,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); @@ -3866,10 +7258,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS L1 CA DOPPLER @@ -3878,10 +7270,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); @@ -3973,10 +7365,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream & out, const Gps_CNAV_Ephemeris & { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); @@ -3988,10 +7380,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream & out, const Gps_CNAV_Ephemeris & { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS L2 DOPPLER @@ -4000,10 +7392,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream & out, const Gps_CNAV_Ephemeris & { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); @@ -4165,10 +7557,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream & out, const Gps_Ephemeris & eph, { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + // else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); @@ -4180,10 +7572,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream & out, const Gps_Ephemeris & eph, { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS DOPPLER @@ -4192,10 +7584,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream & out, const Gps_Ephemeris & eph, { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS SIGNAL STRENGTH @@ -4285,97 +7677,97 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep std::set available_prns; std::set::iterator it; if(found_1B != std::string::npos) - { - for(observables_iter = observablesE1B.begin(); - observables_iter != observablesE1B.end(); - observables_iter++) - { - unsigned int prn_ = observables_iter->second.PRN; - total_map.insert(std::pair(prn_, observables_iter->second)); - it = available_prns.find(prn_); - if(it == available_prns.end()) - { - available_prns.insert(prn_); - } - } - } - if(found_E5a != std::string::npos) - { - for(observables_iter = observablesE5A.cbegin(); - observables_iter != observablesE5A.cend(); - observables_iter++) - { - unsigned int prn_ = observables_iter->second.PRN; - it = available_prns.find(prn_); - if(it == available_prns.end()) - { - available_prns.insert(prn_); - if(found_1B != std::string::npos) + { + for(observables_iter = observablesE1B.begin(); + observables_iter != observablesE1B.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + total_map.insert(std::pair(prn_, observables_iter->second)); + it = available_prns.find(prn_); + if(it == available_prns.end()) { - Gnss_Synchro gs = Gnss_Synchro(); - std::string sys = "E"; - gs.System = *sys.c_str(); - std::string sig = "1B"; - std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); - gs.PRN = prn_; - total_map.insert(std::pair(prn_, gs)); + available_prns.insert(prn_); } - } - total_map.insert(std::pair(prn_, observables_iter->second)); - } - } + } + } + if(found_E5a != std::string::npos) + { + for(observables_iter = observablesE5A.cbegin(); + observables_iter != observablesE5A.cend(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + it = available_prns.find(prn_); + if(it == available_prns.end()) + { + available_prns.insert(prn_); + if(found_1B != std::string::npos) + { + Gnss_Synchro gs = Gnss_Synchro(); + std::string sys = "E"; + gs.System = *sys.c_str(); + std::string sig = "1B"; + std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); + gs.PRN = prn_; + total_map.insert(std::pair(prn_, gs)); + } + } + total_map.insert(std::pair(prn_, observables_iter->second)); + } + } if(found_E5b != std::string::npos) - { - for(observables_iter = observablesE5B.cbegin(); - observables_iter != observablesE5B.cend(); - observables_iter++) - { - unsigned int prn_ = observables_iter->second.PRN; - it = available_prns.find(prn_); - if(it == available_prns.end()) - { - available_prns.insert(prn_); - if(found_1B != std::string::npos) - { - Gnss_Synchro gs = Gnss_Synchro(); - std::string sys = "E"; - gs.System = *sys.c_str(); - std::string sig = "1B"; - std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); - gs.PRN = prn_; - total_map.insert(std::pair(prn_, gs)); - } - if(found_E5a != std::string::npos) - { - Gnss_Synchro gs = Gnss_Synchro(); - std::string sys = "E"; - gs.System = *sys.c_str(); - std::string sig = "5X"; - std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); - gs.PRN = prn_; - total_map.insert(std::pair(prn_, gs)); - } - } - else - { - // if 5X is listed but empty - if(found_E5a != std::string::npos) - { - if( (total_map.count(prn_)) == 1) - { - Gnss_Synchro gs = Gnss_Synchro(); - std::string sys = "E"; - gs.System = *sys.c_str(); - std::string sig = "5X"; - std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); - gs.PRN = prn_; - total_map.insert(std::pair(prn_, gs)); - } - } - } - total_map.insert(std::pair(prn_, observables_iter->second)); - } - } + { + for(observables_iter = observablesE5B.cbegin(); + observables_iter != observablesE5B.cend(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + it = available_prns.find(prn_); + if(it == available_prns.end()) + { + available_prns.insert(prn_); + if(found_1B != std::string::npos) + { + Gnss_Synchro gs = Gnss_Synchro(); + std::string sys = "E"; + gs.System = *sys.c_str(); + std::string sig = "1B"; + std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); + gs.PRN = prn_; + total_map.insert(std::pair(prn_, gs)); + } + if(found_E5a != std::string::npos) + { + Gnss_Synchro gs = Gnss_Synchro(); + std::string sys = "E"; + gs.System = *sys.c_str(); + std::string sig = "5X"; + std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); + gs.PRN = prn_; + total_map.insert(std::pair(prn_, gs)); + } + } + else + { + // if 5X is listed but empty + if(found_E5a != std::string::npos) + { + if( (total_map.count(prn_)) == 1) + { + Gnss_Synchro gs = Gnss_Synchro(); + std::string sys = "E"; + gs.System = *sys.c_str(); + std::string sig = "5X"; + std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); + gs.PRN = prn_; + total_map.insert(std::pair(prn_, gs)); + } + } + } + total_map.insert(std::pair(prn_, observables_iter->second)); + } + } int numSatellitesObserved = available_prns.size(); line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); // Receiver clock offset (optional) @@ -4405,10 +7797,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); @@ -4420,10 +7812,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // Galileo DOPPLER @@ -4432,10 +7824,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // Galileo SIGNAL STRENGTH @@ -4597,10 +7989,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); @@ -4612,10 +8004,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // DOPPLER @@ -4624,10 +8016,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // SIGNAL STRENGTH @@ -4657,10 +8049,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); @@ -4672,10 +8064,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // Galileo DOPPLER @@ -4684,10 +8076,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // Galileo SIGNAL STRENGTH @@ -4700,6 +8092,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } + void Rinex_Printer::to_date_time(int gps_week, int gps_tow, int &year, int &month, int &day, int &hour, int &minute, int &second) { // represents GPS time (week, TOW) in the date time format of the Gregorian calendar. @@ -4910,6 +8303,89 @@ boost::posix_time::ptime Rinex_Printer::compute_Galileo_time(const Galileo_Ephem } +boost::posix_time::ptime Rinex_Printer::compute_UTC_time(const Glonass_Gnav_Ephemeris& eph, const double obs_time) +{ + double tod = 0.0; + double glot2utc = 3*3600; + double obs_time_glot = 0.0; + int i = 0; + + // Get observation time in nearly GLONASS time. Correction for leap seconds done at the end + obs_time_glot = obs_time + glot2utc; + + // Get seconds of day in glonass time + tod = fmod (obs_time_glot, 86400); + + // Form date and time duration types + boost::posix_time::time_duration t1(0, 0, tod); + boost::gregorian::date d1(eph.d_yr, 1, 1); + boost::gregorian::days d2(eph.d_N_T-1); + boost::posix_time::ptime glo_time(d1 + d2, t1); + + // Convert to utc + boost::posix_time::time_duration t2(0, 0, glot2utc); + boost::posix_time::ptime utc_time = glo_time - t2; + + // Adjust for leap second correction + for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) + { + boost::posix_time::time_duration t3(GLONASS_LEAP_SECONDS[i][3], GLONASS_LEAP_SECONDS[i][4], GLONASS_LEAP_SECONDS[i][5]); + boost::gregorian::date d3(GLONASS_LEAP_SECONDS[i][0], GLONASS_LEAP_SECONDS[i][1], GLONASS_LEAP_SECONDS[i][2]); + boost::posix_time::ptime ls_time(d3, t3); + if (utc_time >= ls_time) + { + // We subtract the leap second when going from gpst to utc + utc_time = utc_time - boost::posix_time::time_duration(0,0,fabs(GLONASS_LEAP_SECONDS[i][6])); + break; + } + } + + return utc_time; +} + + +double Rinex_Printer::get_leap_second(const Glonass_Gnav_Ephemeris& eph, const double gps_obs_time) +{ + double tod = 0.0; + double glot2utc = 3*3600; + double obs_time_glot = 0.0; + int i = 0; + double leap_second = 0; + + // Get observation time in nearly GLONASS time. Correction for leap seconds done at the end + obs_time_glot = gps_obs_time + glot2utc; + + // Get seconds of day in glonass time + tod = fmod (obs_time_glot, 86400); + + // Form date and time duration types + boost::posix_time::time_duration t1(0, 0, tod); + boost::gregorian::date d1(eph.d_yr, 1, 1); + boost::gregorian::days d2(eph.d_N_T-1); + boost::posix_time::ptime glo_time(d1 + d2, t1); + + // Convert to utc + boost::posix_time::time_duration t2(0, 0, glot2utc); + boost::posix_time::ptime utc_time = glo_time - t2; + + // Adjust for leap second correction + for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) + { + boost::posix_time::time_duration t3(GLONASS_LEAP_SECONDS[i][3], GLONASS_LEAP_SECONDS[i][4], GLONASS_LEAP_SECONDS[i][5]); + boost::gregorian::date d3(GLONASS_LEAP_SECONDS[i][0], GLONASS_LEAP_SECONDS[i][1], GLONASS_LEAP_SECONDS[i][2]); + boost::posix_time::ptime ls_time(d3, t3); + if (utc_time >= ls_time) + { + // We subtract the leap second when going from gpst to utc + leap_second = fabs(GLONASS_LEAP_SECONDS[i][6]); + break; + } + } + + return leap_second; +} + + /* enum RINEX_enumMarkerType { diff --git a/src/algorithms/PVT/libs/rinex_printer.h b/src/algorithms/PVT/libs/rinex_printer.h index d9aee967e..8f4580208 100644 --- a/src/algorithms/PVT/libs/rinex_printer.h +++ b/src/algorithms/PVT/libs/rinex_printer.h @@ -61,8 +61,10 @@ #include "gps_navigation_message.h" #include "gps_cnav_navigation_message.h" #include "galileo_navigation_message.h" +#include "glonass_gnav_navigation_message.h" #include "GPS_L1_CA.h" #include "Galileo_E1.h" +#include "GLONASS_L1_CA.h" #include "gnss_synchro.h" class Sbas_Raw_Msg; @@ -88,6 +90,7 @@ public: std::fstream navFile ; // & gps_eph_map, const std::map & galileo_eph_map); + /*! + * \brief Writes data from the GLONASS GNAV navigation message into the RINEX file + */ + void log_rinex_nav(std::fstream & out, const std::map & eph_map); + + /*! + * \brief Writes data from the Mixed (GPS/GLONASS GNAV) navigation message into the RINEX file + */ + void log_rinex_nav(std::fstream & out, const std::map & gps_eph_map, const std::map & glonass_gnav_eph_map); + + /*! + * \brief Writes data from the Mixed (GPS/GLONASS GNAV) navigation message into the RINEX file + */ + void log_rinex_nav(std::fstream & out, const std::map & gps_cnav_eph_map, const std::map & glonass_gnav_eph_map); + + /*! + * \brief Writes data from the Mixed (Galileo/ GLONASS GNAV) navigation message into the RINEX file + */ + void log_rinex_nav(std::fstream & out, const std::map & galileo_eph_map, const std::map & glonass_gnav_eph_map); + /*! * \brief Writes GPS L1 observables into the RINEX file */ @@ -205,6 +284,26 @@ public: */ void log_rinex_obs(std::fstream & out, const Gps_Ephemeris & gps_eph, const Galileo_Ephemeris & galileo_eph, const double gps_obs_time, const std::map & observables); + /*! + * \brief Writes GLONASS GNAV observables into the RINEX file. Example: glonass_bands("1C"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B". + */ + void log_rinex_obs(std::fstream & out, const Glonass_Gnav_Ephemeris & eph, double obs_time, const std::map & observables, const std::string glonass_bands = "1C"); + + /*! + * \brief Writes Mixed GPS L1 C/A - GLONASS observables into the RINEX file + */ + void log_rinex_obs(std::fstream & out, const Gps_Ephemeris & gps_eph, const Glonass_Gnav_Ephemeris & glonass_gnav_eph, const double gps_obs_time, const std::map & observables); + + /*! + * \brief Writes Mixed GPS L2C - GLONASS observables into the RINEX file + */ + void log_rinex_obs(std::fstream & out, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Glonass_Gnav_Ephemeris & glonass_gnav_eph, const double gps_obs_time, const std::map & observables); + + /*! + * \brief Writes Mixed Galileo/GLONASS observables into the RINEX file + */ + void log_rinex_obs(std::fstream & out, const Galileo_Ephemeris & galileo_eph, const Glonass_Gnav_Ephemeris & glonass_gnav_eph, const double gps_obs_time, const std::map & observables); + /*! * \brief Represents GPS time in the date time format. Leap years are considered, but leap seconds are not. */ @@ -223,12 +322,22 @@ public: void update_nav_header(std::fstream & out, const Galileo_Iono & galileo_iono, const Galileo_Utc_Model & utc_model, const Galileo_Almanac & galileo_almanac); + void update_nav_header(std::fstream & out, const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model, const Glonass_Gnav_Almanac & glonass_gnav_almanac); + + void update_nav_header(std::fstream & out, const Gps_Iono & gps_iono, const Gps_Utc_Model & gps_utc, const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model, const Glonass_Gnav_Almanac & glonass_gnav_almanac); + + void update_nav_header(std::fstream & out, const Gps_CNAV_Iono & gps_cnav_iono, const Gps_CNAV_Utc_Model & gps_cnav_utc, const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model, const Glonass_Gnav_Almanac & glonass_gnav_almanac); + + void update_nav_header(std::fstream & out, const Galileo_Iono & galileo_iono, const Galileo_Utc_Model & galileo_utc_model, const Galileo_Almanac& galileo_almanac, const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model, const Glonass_Gnav_Almanac & glonass_gnav_almanac); + void update_obs_header(std::fstream & out, const Gps_Utc_Model & utc_model); void update_obs_header(std::fstream & out, const Gps_CNAV_Utc_Model & utc_model); void update_obs_header(std::fstream & out, const Galileo_Utc_Model & galileo_utc_model); + void update_obs_header(std::fstream & out, const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model); + std::map satelliteSystem; // observationType; // observationCode; // & observables) +{ + std::string m1009 = rtcm->print_MT1009(glonass_gnav_eph, obs_time, observables, station_id); + Rtcm_Printer::Print_Message(m1009); + return true; +} + + +bool Rtcm_Printer::Print_Rtcm_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map & observables) +{ + std::string m1010 = rtcm->print_MT1010(glonass_gnav_eph, obs_time, observables, station_id); + Rtcm_Printer::Print_Message(m1010); + return true; +} + + +bool Rtcm_Printer::Print_Rtcm_MT1011(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map & observables) +{ + std::string m1011 = rtcm->print_MT1011(glonass_gnav_ephL1, glonass_gnav_ephL2, obs_time, observables, station_id); + Rtcm_Printer::Print_Message(m1011); + return true; +} + + +bool Rtcm_Printer::Print_Rtcm_MT1012(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map & observables) +{ + std::string m1012 = rtcm->print_MT1012(glonass_gnav_ephL1, glonass_gnav_ephL2, obs_time, observables, station_id); + Rtcm_Printer::Print_Message(m1012); + return true; +} + + bool Rtcm_Printer::Print_Rtcm_MT1019(const Gps_Ephemeris & gps_eph) { std::string m1019 = rtcm->print_MT1019(gps_eph); @@ -194,6 +226,14 @@ bool Rtcm_Printer::Print_Rtcm_MT1019(const Gps_Ephemeris & gps_eph) } +bool Rtcm_Printer::Print_Rtcm_MT1020(const Glonass_Gnav_Ephemeris & glonass_gnav_eph, const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model) +{ + std::string m1020 = rtcm->print_MT1020(glonass_gnav_eph, glonass_gnav_utc_model); + Rtcm_Printer::Print_Message(m1020); + return true; +} + + bool Rtcm_Printer::Print_Rtcm_MT1045(const Galileo_Ephemeris & gal_eph) { std::string m1045 = rtcm->print_MT1045(gal_eph); @@ -205,6 +245,7 @@ bool Rtcm_Printer::Print_Rtcm_MT1045(const Galileo_Ephemeris & gal_eph) bool Rtcm_Printer::Print_Rtcm_MSM(unsigned int msm_number, const Gps_Ephemeris & gps_eph, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Galileo_Ephemeris & gal_eph, + const Glonass_Gnav_Ephemeris & glo_gnav_eph, double obs_time, const std::map & observables, unsigned int clock_steering_indicator, @@ -216,31 +257,31 @@ bool Rtcm_Printer::Print_Rtcm_MSM(unsigned int msm_number, const Gps_Ephemeris & std::string msm; if(msm_number == 1) { - msm = rtcm->print_MSM_1(gps_eph, gps_cnav_eph, gal_eph, obs_time, observables, station_id, clock_steering_indicator, external_clock_indicator, smooth_int, divergence_free, more_messages); + msm = rtcm->print_MSM_1(gps_eph, gps_cnav_eph, gal_eph, glo_gnav_eph, obs_time, observables, station_id, clock_steering_indicator, external_clock_indicator, smooth_int, divergence_free, more_messages); } else if(msm_number == 2) { - msm = rtcm->print_MSM_2(gps_eph, gps_cnav_eph, gal_eph, obs_time, observables, station_id, clock_steering_indicator, external_clock_indicator, smooth_int, divergence_free, more_messages); + msm = rtcm->print_MSM_2(gps_eph, gps_cnav_eph, gal_eph, glo_gnav_eph, obs_time, observables, station_id, clock_steering_indicator, external_clock_indicator, smooth_int, divergence_free, more_messages); } else if(msm_number == 3) { - msm = rtcm->print_MSM_3(gps_eph, gps_cnav_eph, gal_eph, obs_time, observables, station_id, clock_steering_indicator, external_clock_indicator, smooth_int, divergence_free, more_messages); + msm = rtcm->print_MSM_3(gps_eph, gps_cnav_eph, gal_eph, glo_gnav_eph, obs_time, observables, station_id, clock_steering_indicator, external_clock_indicator, smooth_int, divergence_free, more_messages); } else if(msm_number == 4) { - msm = rtcm->print_MSM_4(gps_eph, gps_cnav_eph, gal_eph, obs_time, observables, station_id, clock_steering_indicator, external_clock_indicator, smooth_int, divergence_free, more_messages); + msm = rtcm->print_MSM_4(gps_eph, gps_cnav_eph, gal_eph, glo_gnav_eph, obs_time, observables, station_id, clock_steering_indicator, external_clock_indicator, smooth_int, divergence_free, more_messages); } else if(msm_number == 5) { - msm = rtcm->print_MSM_5(gps_eph, gps_cnav_eph, gal_eph, obs_time, observables, station_id, clock_steering_indicator, external_clock_indicator, smooth_int, divergence_free, more_messages); + msm = rtcm->print_MSM_5(gps_eph, gps_cnav_eph, gal_eph, glo_gnav_eph, obs_time, observables, station_id, clock_steering_indicator, external_clock_indicator, smooth_int, divergence_free, more_messages); } else if(msm_number == 6) { - msm = rtcm->print_MSM_6(gps_eph, gps_cnav_eph, gal_eph, obs_time, observables, station_id, clock_steering_indicator, external_clock_indicator, smooth_int, divergence_free, more_messages); + msm = rtcm->print_MSM_6(gps_eph, gps_cnav_eph, gal_eph, glo_gnav_eph, obs_time, observables, station_id, clock_steering_indicator, external_clock_indicator, smooth_int, divergence_free, more_messages); } else if(msm_number == 7) { - msm = rtcm->print_MSM_7(gps_eph, gps_cnav_eph, gal_eph, obs_time, observables, station_id, clock_steering_indicator, external_clock_indicator, smooth_int, divergence_free, more_messages); + msm = rtcm->print_MSM_7(gps_eph, gps_cnav_eph, gal_eph, glo_gnav_eph, obs_time, observables, station_id, clock_steering_indicator, external_clock_indicator, smooth_int, divergence_free, more_messages); } else { @@ -348,3 +389,9 @@ unsigned int Rtcm_Printer::lock_time(const Galileo_Ephemeris& eph, double obs_ti { return rtcm->lock_time(eph, obs_time, gnss_synchro); } + + +unsigned int Rtcm_Printer::lock_time(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro & gnss_synchro) +{ + return rtcm->lock_time(eph, obs_time, gnss_synchro); +} diff --git a/src/algorithms/PVT/libs/rtcm_printer.h b/src/algorithms/PVT/libs/rtcm_printer.h index 0b59001e6..21fdaeddf 100644 --- a/src/algorithms/PVT/libs/rtcm_printer.h +++ b/src/algorithms/PVT/libs/rtcm_printer.h @@ -59,12 +59,66 @@ public: bool Print_Rtcm_MT1002(const Gps_Ephemeris& gps_eph, double obs_time, const std::map & observables); bool Print_Rtcm_MT1003(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map & observables); bool Print_Rtcm_MT1004(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map & observables); + /*! + * \brief Prints L1-Only GLONASS RTK Observables + * \details This GLONASS message type is not generally used or supported; type 1012 is to be preferred. + * \note Code added as part of GSoC 2017 program + * \param glonass_gnav_eph GLONASS GNAV Broadcast Ephemeris + * \param obs_time Time of observation at the moment of printing + * \param observables Set of observables as defined by the platform + * \return true or false upon operation success + */ + bool Print_Rtcm_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map & observables); + /*! + * \brief Prints Extended L1-Only GLONASS RTK Observables + * \details This GLONASS message type is used when only L1 data is present and bandwidth is very tight, often 1012 is used in such cases. + * \note Code added as part of GSoC 2017 program + * \param glonass_gnav_eph GLONASS GNAV Broadcast Ephemeris + * \param obs_time Time of observation at the moment of printing + * \param observables Set of observables as defined by the platform + * \return true or false upon operation success + */ + bool Print_Rtcm_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map & observables); + /*! + * \brief Prints L1&L2 GLONASS RTK Observables + * \details This GLONASS message type is not generally used or supported; type 1012 is to be preferred + * \note Code added as part of GSoC 2017 program + * \param glonass_gnav_ephL1 GLONASS L1 GNAV Broadcast Ephemeris for satellite + * \param glonass_gnav_ephL2 GLONASS L2 GNAV Broadcast Ephemeris for satellite + * \param obs_time Time of observation at the moment of printing + * \param observables Set of observables as defined by the platform + * \return true or false upon operation success + */ + bool Print_Rtcm_MT1011(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map & observables); + /*! + * \brief Prints Extended L1&L2 GLONASS RTK Observables + * \details This GLONASS message type is the most common observational message type, with L1/L2/SNR content. This is one of the most common messages found. + * \note Code added as part of GSoC 2017 program + * \param glonass_gnav_ephL1 GLONASS L1 GNAV Broadcast Ephemeris for satellite + * \param glonass_gnav_ephL2 GLONASS L2 GNAV Broadcast Ephemeris for satellite + * \param obs_time Time of observation at the moment of printing + * \param observables Set of observables as defined by the platform + * \return true or false upon operation success + */ + bool Print_Rtcm_MT1012(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map & observables); + bool Print_Rtcm_MT1019(const Gps_Ephemeris & gps_eph); // & observables, unsigned int clock_steering_indicator, @@ -77,6 +131,15 @@ public: unsigned int lock_time(const Gps_Ephemeris& eph, double obs_time, const Gnss_Synchro & gnss_synchro); unsigned int lock_time(const Gps_CNAV_Ephemeris& eph, double obs_time, const Gnss_Synchro & gnss_synchro); unsigned int lock_time(const Galileo_Ephemeris& eph, double obs_time, const Gnss_Synchro & gnss_synchro); + /*! + * \brief Locks time for logging given GLONASS GNAV Broadcast Ephemeris + * \note Code added as part of GSoC 2017 program + * \params glonass_gnav_eph GLONASS GNAV Broadcast Ephemeris + * \params obs_time Time of observation at the moment of printing + * \params observables Set of observables as defined by the platform + * \return locked time during logging process + */ + unsigned int lock_time(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro & gnss_synchro); private: std::string rtcm_filename; // String with the RTCM log filename diff --git a/src/algorithms/PVT/libs/rtklib_solver.cc b/src/algorithms/PVT/libs/rtklib_solver.cc index 93685eb24..897150a87 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.cc +++ b/src/algorithms/PVT/libs/rtklib_solver.cc @@ -56,6 +56,7 @@ #include "rtklib_conversions.h" #include "GPS_L1_CA.h" #include "Galileo_E1.h" +#include "GLONASS_L1_CA.h" using google::LogMessage; @@ -114,6 +115,8 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ std::map::const_iterator galileo_ephemeris_iter; std::map::const_iterator gps_ephemeris_iter; std::map::const_iterator gps_cnav_ephemeris_iter; + std::map::const_iterator glonass_gnav_ephemeris_iter; + const Glonass_Gnav_Utc_Model gnav_utc = this->glonass_gnav_utc_model; this->set_averaging_flag(flag_averaging); @@ -121,9 +124,11 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ // ****** PREPARE THE DATA (SV EPHEMERIS AND OBSERVATIONS) ************************ // ******************************************************************************** int valid_obs = 0; //valid observations counter + int glo_valid_obs = 0; //GLONASS L1/L2 valid observations counter obsd_t obs_data[MAXOBS]; eph_t eph_data[MAXOBS]; + geph_t geph_data[MAXOBS]; for(gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); @@ -145,7 +150,7 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ eph_data[valid_obs] = eph_to_rtklib(galileo_ephemeris_iter->second); //convert observation from GNSS-SDR class to RTKLIB structure obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}}; - obs_data[valid_obs] = insert_obs_to_rtklib(newobs, + obs_data[valid_obs+glo_valid_obs] = insert_obs_to_rtklib(newobs, gnss_observables_iter->second, galileo_ephemeris_iter->second.WN_5, 0); @@ -155,26 +160,25 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ { DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN; } - } - // Galileo E5 - if(sig_.compare("5X") == 0) - { + // Galileo E5 + if(sig_.compare("5X") == 0) + { // 1 Gal - find the ephemeris for the current GALILEO SV observation. The SV PRN ID is the map key galileo_ephemeris_iter = galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); if (galileo_ephemeris_iter != galileo_ephemeris_map.cend()) { - bool found_E1_obs=false; + bool found_E1_obs = false; for (int i = 0; i < valid_obs; i++) { if (eph_data[i].sat == (static_cast(gnss_observables_iter->second.PRN + NSATGPS + NSATGLO))) { - obs_data[i] = insert_obs_to_rtklib(obs_data[i], + obs_data[i + glo_valid_obs] = insert_obs_to_rtklib(obs_data[i + glo_valid_obs], gnss_observables_iter->second, galileo_ephemeris_iter->second.WN_5, 2);//Band 3 (L5/E5) - found_E1_obs=true; + found_E1_obs = true; break; } } @@ -188,7 +192,7 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ obsd_t newobs = {{0,0}, '0', '0', {}, {}, {default_code_, default_code_, default_code_}, {}, {0.0, 0.0, 0.0}, {}}; - obs_data[valid_obs] = insert_obs_to_rtklib(newobs, + obs_data[valid_obs+glo_valid_obs] = insert_obs_to_rtklib(newobs, gnss_observables_iter->second, galileo_ephemeris_iter->second.WN_5, 2); //Band 3 (L5/E5) @@ -216,7 +220,7 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ eph_data[valid_obs] = eph_to_rtklib(gps_ephemeris_iter->second); //convert observation from GNSS-SDR class to RTKLIB structure obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}}; - obs_data[valid_obs] = insert_obs_to_rtklib(newobs, + obs_data[valid_obs+glo_valid_obs] = insert_obs_to_rtklib(newobs, gnss_observables_iter->second, gps_ephemeris_iter->second.i_GPS_week, 0); @@ -244,7 +248,7 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ if (eph_data[i].sat == static_cast(gnss_observables_iter->second.PRN)) { eph_data[i] = eph_to_rtklib(gps_cnav_ephemeris_iter->second); - obs_data[i] = insert_obs_to_rtklib(obs_data[i], + obs_data[i+glo_valid_obs] = insert_obs_to_rtklib(obs_data[i+glo_valid_obs], gnss_observables_iter->second, gps_cnav_ephemeris_iter->second.i_GPS_week, 1);//Band 2 (L2) @@ -262,7 +266,7 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ obsd_t newobs = {{0,0}, '0', '0', {}, {}, {default_code_, default_code_, default_code_}, {}, {0.0, 0.0, 0.0}, {}}; - obs_data[valid_obs] = insert_obs_to_rtklib(newobs, + obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs, gnss_observables_iter->second, gps_cnav_ephemeris_iter->second.i_GPS_week, 1);//Band 2 (L2) @@ -291,7 +295,7 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ if (eph_data[i].sat == static_cast(gnss_observables_iter->second.PRN)) { eph_data[i] = eph_to_rtklib(gps_cnav_ephemeris_iter->second); - obs_data[i] = insert_obs_to_rtklib(obs_data[i], + obs_data[i+glo_valid_obs] = insert_obs_to_rtklib(obs_data[i], gnss_observables_iter->second, gps_cnav_ephemeris_iter->second.i_GPS_week, 2);//Band 3 (L5) @@ -309,7 +313,7 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ obsd_t newobs = {{0,0}, '0', '0', {}, {}, {default_code_, default_code_, default_code_}, {}, {0.0, 0.0, 0.0}, {}}; - obs_data[valid_obs] = insert_obs_to_rtklib(newobs, + obs_data[valid_obs+glo_valid_obs] = insert_obs_to_rtklib(newobs, gnss_observables_iter->second, gps_cnav_ephemeris_iter->second.i_GPS_week, 2);//Band 3 (L5) @@ -320,6 +324,75 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ { DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN; } + } + break; + } + case 'R': //TODO This should be using rtk lib nomenclature + { + std::string sig_(gnss_observables_iter->second.Signal); + // GLONASS GNAV L1 + if(sig_.compare("1G") == 0) + { + // 1 Glo - find the ephemeris for the current GLONASS SV observation. The SV Slot Number (PRN ID) is the map key + glonass_gnav_ephemeris_iter = glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_ephemeris_iter != glonass_gnav_ephemeris_map.cend()) + { + //convert ephemeris from GNSS-SDR class to RTKLIB structure + geph_data[glo_valid_obs] = eph_to_rtklib(glonass_gnav_ephemeris_iter->second, gnav_utc); + //convert observation from GNSS-SDR class to RTKLIB structure + obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}}; + obs_data[valid_obs+glo_valid_obs] = insert_obs_to_rtklib(newobs, + gnss_observables_iter->second, + glonass_gnav_ephemeris_iter->second.d_WN, + 0);//Band 0 (L1) + glo_valid_obs++; + } + else // the ephemeris are not available for this SV + { + DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN; + } + + } + // GLONASS GNAV L2 + if(sig_.compare("2G") == 0) + { + // 1 GLONASS - find the ephemeris for the current GLONASS SV observation. The SV PRN ID is the map key + glonass_gnav_ephemeris_iter = glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_ephemeris_iter != glonass_gnav_ephemeris_map.cend()) + { + bool found_L1_obs = false; + for (int i = 0; i < glo_valid_obs; i++) + { + if (geph_data[i].sat == (static_cast(gnss_observables_iter->second.PRN+NSATGPS))) + { + obs_data[i+valid_obs] = insert_obs_to_rtklib(obs_data[i+valid_obs], + gnss_observables_iter->second, + glonass_gnav_ephemeris_iter->second.d_WN, + 1);//Band 1 (L2) + found_L1_obs = true; + break; + } + } + if (!found_L1_obs) + { + //insert GLONASS GNAV L2 obs as new obs and also insert its ephemeris + //convert ephemeris from GNSS-SDR class to RTKLIB structure + geph_data[glo_valid_obs] = eph_to_rtklib(glonass_gnav_ephemeris_iter->second, gnav_utc); + //convert observation from GNSS-SDR class to RTKLIB structure + obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}}; + obs_data[valid_obs+glo_valid_obs] = insert_obs_to_rtklib(newobs, + gnss_observables_iter->second, + glonass_gnav_ephemeris_iter->second.d_WN, + 1); //Band 1 (L2) + glo_valid_obs++; + } + } + else // the ephemeris are not available for this SV + { + DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN; + } + + } break; } @@ -334,19 +407,24 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ // ********************************************************************** this->set_valid_position(false); - if (valid_obs > 0) + if (valid_obs > 0 || glo_valid_obs > 0) { int result = 0; nav_t nav_data; nav_data.eph = eph_data; + nav_data.geph = geph_data; nav_data.n = valid_obs; + nav_data.ng = glo_valid_obs; + for (int i = 0; i < MAXSAT; i++) { nav_data.lam[i][0] = SPEED_OF_LIGHT / FREQ1; /* L1/E1 */ nav_data.lam[i][1] = SPEED_OF_LIGHT / FREQ2; /* L2 */ nav_data.lam[i][2] = SPEED_OF_LIGHT / FREQ5; /* L5/E5 */ } - result = rtkpos(&rtk_, obs_data, valid_obs, &nav_data); + + result = rtkpos(&rtk_, obs_data, valid_obs + glo_valid_obs, &nav_data); + if(result == 0) { DLOG(INFO) << "RTKLIB rtkpos error message: " << rtk_.errbuf; @@ -416,7 +494,7 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ LOG(WARNING) << "Exception writing PVT LS dump file " << e.what(); } } - } - } - return this->is_valid_position(); -} + } + } + return this->is_valid_position(); + } diff --git a/src/algorithms/PVT/libs/rtklib_solver.h b/src/algorithms/PVT/libs/rtklib_solver.h index 6f441f4a6..d8703548e 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.h +++ b/src/algorithms/PVT/libs/rtklib_solver.h @@ -62,6 +62,7 @@ #include "galileo_navigation_message.h" #include "gps_navigation_message.h" #include "gps_cnav_navigation_message.h" +#include "glonass_gnav_navigation_message.h" #include "gnss_synchro.h" #include "pvt_solution.h" @@ -86,6 +87,7 @@ public: std::map galileo_ephemeris_map; //!< Map storing new Galileo_Ephemeris std::map gps_ephemeris_map; //!< Map storing new GPS_Ephemeris std::map gps_cnav_ephemeris_map; //!< Map storing new GPS_CNAV_Ephemeris + std::map glonass_gnav_ephemeris_map; //!< Map storing new GLONASS GNAV Ephmeris Galileo_Utc_Model galileo_utc_model; Galileo_Iono galileo_iono; @@ -97,6 +99,9 @@ public: Gps_CNAV_Iono gps_cnav_iono; Gps_CNAV_Utc_Model gps_cnav_utc_model; + Glonass_Gnav_Utc_Model glonass_gnav_utc_model; //!< Map storing GLONASS GNAV UTC Model + Glonass_Gnav_Almanac glonass_gnav_almanac; //!< Map storing GLONASS GNAV Almanac Model + int count_valid_position; }; diff --git a/src/algorithms/acquisition/adapters/CMakeLists.txt b/src/algorithms/acquisition/adapters/CMakeLists.txt index 8d2084d57..9b1889109 100644 --- a/src/algorithms/acquisition/adapters/CMakeLists.txt +++ b/src/algorithms/acquisition/adapters/CMakeLists.txt @@ -31,6 +31,7 @@ set(ACQ_ADAPTER_SOURCES galileo_e1_pcps_tong_ambiguous_acquisition.cc galileo_e1_pcps_8ms_ambiguous_acquisition.cc galileo_e5a_noncoherent_iq_acquisition_caf.cc + glonass_l1_ca_pcps_acquisition.cc ) if(ENABLE_FPGA) diff --git a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc new file mode 100644 index 000000000..e68379712 --- /dev/null +++ b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc @@ -0,0 +1,395 @@ +/*! + * \file glonass_l1_ca_pcps_acquisition.cc + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for + * Glonass L1 C/A signals + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "glonass_l1_ca_pcps_acquisition.h" +#include +#include +#include "glonass_l1_signal_processing.h" +#include "GLONASS_L1_CA.h" +#include "configuration_interface.h" + + +using google::LogMessage; + +GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( + ConfigurationInterface* configuration, std::string role, + unsigned int in_streams, unsigned int out_streams) : + role_(role), in_streams_(in_streams), out_streams_(out_streams) +{ + configuration_ = configuration; + std::string default_item_type = "gr_complex"; + std::string default_dump_filename = "./data/acquisition.dat"; + + DLOG(INFO) << "role " << role; + + item_type_ = configuration_->property(role + ".item_type", default_item_type); + + long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); + fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + if_ = configuration_->property(role + ".if", 0); + dump_ = configuration_->property(role + ".dump", false); + blocking_ = configuration_->property(role + ".blocking", true); + doppler_max_ = configuration_->property(role + ".doppler_max", 5000); + sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1); + + bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); + use_CFAR_algorithm_flag_=configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions + + max_dwells_ = configuration_->property(role + ".max_dwells", 1); + + dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); + + //--- Find number of samples per spreading code ------------------------- + code_length_ = round(fs_in_ / (GLONASS_L1_CA_CODE_RATE_HZ / GLONASS_L1_CA_CODE_LENGTH_CHIPS)); + + vector_length_ = code_length_ * sampled_ms_; + + if( bit_transition_flag_ ) + { + vector_length_ *= 2; + } + + code_ = new gr_complex[vector_length_]; + + if (item_type_.compare("cshort") == 0 ) + { + item_size_ = sizeof(lv_16sc_t); + acquisition_sc_ = pcps_make_acquisition_sc(sampled_ms_, max_dwells_, + doppler_max_, if_, fs_in_, code_length_, code_length_, + bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, blocking_, dump_filename_); + DLOG(INFO) << "acquisition(" << acquisition_sc_->unique_id() << ")"; + + } + else + { + item_size_ = sizeof(gr_complex); + acquisition_cc_ = pcps_make_acquisition_cc(sampled_ms_, max_dwells_, + doppler_max_, if_, fs_in_, code_length_, code_length_, + bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, blocking_, dump_filename_); + DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id() << ")"; + } + + stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); + DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; + + if (item_type_.compare("cbyte") == 0) + { + cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); + float_to_complex_ = gr::blocks::float_to_complex::make(); + } + + channel_ = 0; + threshold_ = 0.0; + doppler_step_ = 0; + gnss_synchro_ = 0; +} + + +GlonassL1CaPcpsAcquisition::~GlonassL1CaPcpsAcquisition() +{ + delete[] code_; +} + + +void GlonassL1CaPcpsAcquisition::set_channel(unsigned int channel) +{ + channel_ = channel; + if (item_type_.compare("cshort") == 0) + { + acquisition_sc_->set_channel(channel_); + } + else + { + acquisition_cc_->set_channel(channel_); + } +} + + +void GlonassL1CaPcpsAcquisition::set_threshold(float threshold) +{ + float pfa = configuration_->property(role_ + ".pfa", 0.0); + + if(pfa == 0.0) + { + threshold_ = threshold; + } + else + { + threshold_ = calculate_threshold(pfa); + } + + DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; + + if (item_type_.compare("cshort") == 0) + { + acquisition_sc_->set_threshold(threshold_); + } + else + { + acquisition_cc_->set_threshold(threshold_); + } +} + + +void GlonassL1CaPcpsAcquisition::set_doppler_max(unsigned int doppler_max) +{ + doppler_max_ = doppler_max; + + if (item_type_.compare("cshort") == 0) + { + acquisition_sc_->set_doppler_max(doppler_max_); + } + else + { + acquisition_cc_->set_doppler_max(doppler_max_); + } +} + + +void GlonassL1CaPcpsAcquisition::set_doppler_step(unsigned int doppler_step) +{ + doppler_step_ = doppler_step; + + if (item_type_.compare("cshort") == 0) + { + acquisition_sc_->set_doppler_step(doppler_step_); + } + else + { + acquisition_cc_->set_doppler_step(doppler_step_); + } +} + + +void GlonassL1CaPcpsAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro) +{ + gnss_synchro_ = gnss_synchro; + + if (item_type_.compare("cshort") == 0) + { + acquisition_sc_->set_gnss_synchro(gnss_synchro_); + } + else + { + acquisition_cc_->set_gnss_synchro(gnss_synchro_); + } +} + + +signed int GlonassL1CaPcpsAcquisition::mag() +{ + if (item_type_.compare("cshort") == 0) + { + return acquisition_sc_->mag(); + } + else + { + return acquisition_cc_->mag(); + } +} + + +void GlonassL1CaPcpsAcquisition::init() +{ + if (item_type_.compare("cshort") == 0) + { + acquisition_sc_->init(); + } + else + { + acquisition_cc_->init(); + } + + set_local_code(); +} + + +void GlonassL1CaPcpsAcquisition::set_local_code() +{ + std::complex* code = new std::complex[code_length_]; + + glonass_l1_ca_code_gen_complex_sampled(code,/* gnss_synchro_->PRN,*/ fs_in_, 0); + + for (unsigned int i = 0; i < sampled_ms_; i++) + { + memcpy(&(code_[i*code_length_]), code, + sizeof(gr_complex)*code_length_); + } + + if (item_type_.compare("cshort") == 0) + { + acquisition_sc_->set_local_code(code_); + } + else + { + acquisition_cc_->set_local_code(code_); + } + + delete[] code; +} + + +void GlonassL1CaPcpsAcquisition::reset() +{ + if (item_type_.compare("cshort") == 0) + { + acquisition_sc_->set_active(true); + } + else + { + acquisition_cc_->set_active(true); + } +} + + +void GlonassL1CaPcpsAcquisition::set_state(int state) +{ + if (item_type_.compare("cshort") == 0) + { + acquisition_sc_->set_state(state); + } + else + { + acquisition_cc_->set_state(state); + } +} + + +float GlonassL1CaPcpsAcquisition::calculate_threshold(float pfa) +{ + //Calculate the threshold + unsigned int frequency_bins = 0; + /* + for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_) + { + frequency_bins++; + } + */ + + frequency_bins = (2*doppler_max_ + doppler_step_)/doppler_step_; + + DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa; + unsigned int ncells = vector_length_ * frequency_bins; + double exponent = 1 / static_cast(ncells); + double val = pow(1.0 - pfa, exponent); + double lambda = static_cast(vector_length_); + boost::math::exponential_distribution mydist (lambda); + float threshold = static_cast(quantile(mydist,val)); + + return threshold; +} + + +void GlonassL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block) +{ + if (item_type_.compare("gr_complex") == 0) + { + top_block->connect(stream_to_vector_, 0, acquisition_cc_, 0); + } + else if (item_type_.compare("cshort") == 0) + { + top_block->connect(stream_to_vector_, 0, acquisition_sc_, 0); + } + else if (item_type_.compare("cbyte") == 0) + { + top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); + top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); + top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); + top_block->connect(stream_to_vector_, 0, acquisition_cc_, 0); + } + else + { + LOG(WARNING) << item_type_ << " unknown acquisition item type"; + } +} + + +void GlonassL1CaPcpsAcquisition::disconnect(gr::top_block_sptr top_block) +{ + if (item_type_.compare("gr_complex") == 0) + { + top_block->disconnect(stream_to_vector_, 0, acquisition_cc_, 0); + } + else if (item_type_.compare("cshort") == 0) + { + top_block->disconnect(stream_to_vector_, 0, acquisition_sc_, 0); + } + else if (item_type_.compare("cbyte") == 0) + { + // Since a byte-based acq implementation is not available, + // we just convert cshorts to gr_complex + top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); + top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); + top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); + top_block->disconnect(stream_to_vector_, 0, acquisition_cc_, 0); + } + else + { + LOG(WARNING) << item_type_ << " unknown acquisition item type"; + } +} + + +gr::basic_block_sptr GlonassL1CaPcpsAcquisition::get_left_block() +{ + if (item_type_.compare("gr_complex") == 0) + { + return stream_to_vector_; + } + else if (item_type_.compare("cshort") == 0) + { + return stream_to_vector_; + } + else if (item_type_.compare("cbyte") == 0) + { + return cbyte_to_float_x2_; + } + else + { + LOG(WARNING) << item_type_ << " unknown acquisition item type"; + return nullptr; + } +} + + +gr::basic_block_sptr GlonassL1CaPcpsAcquisition::get_right_block() +{ + if (item_type_.compare("cshort") == 0) + { + return acquisition_sc_; + } + else + { + return acquisition_cc_; + } +} diff --git a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h new file mode 100644 index 000000000..e45e35cb0 --- /dev/null +++ b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h @@ -0,0 +1,170 @@ +/*! + * \file glonass_l1_ca_pcps_acquisition.h + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for + * Glonass L1 C/A signals + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GLONASS_L1_CA_PCPS_ACQUISITION_H_ +#define GNSS_SDR_GLONASS_L1_CA_PCPS_ACQUISITION_H_ + +#include +#include +#include +#include "gnss_synchro.h" +#include "acquisition_interface.h" +#include "pcps_acquisition_cc.h" +#include "pcps_acquisition_sc.h" +#include "complex_byte_to_float_x2.h" + + +class ConfigurationInterface; + +/*! + * \brief This class adapts a PCPS acquisition block to an AcquisitionInterface + * for GPS L1 C/A signals + */ +class GlonassL1CaPcpsAcquisition: public AcquisitionInterface +{ +public: + GlonassL1CaPcpsAcquisition(ConfigurationInterface* configuration, + std::string role, unsigned int in_streams, + unsigned int out_streams); + + virtual ~GlonassL1CaPcpsAcquisition(); + + inline std::string role() override + { + return role_; + } + + /*! + * \brief Returns "GLONASS_L1_CA_PCPS_Acquisition" + */ + inline std::string implementation() override + { + return "GLONASS_L1_CA_PCPS_Acquisition"; + } + + inline size_t item_size() override + { + return item_size_; + } + + void connect(gr::top_block_sptr top_block) override; + void disconnect(gr::top_block_sptr top_block) override; + gr::basic_block_sptr get_left_block() override; + gr::basic_block_sptr get_right_block() override; + + /*! + * \brief Set acquisition/tracking common Gnss_Synchro object pointer + * to efficiently exchange synchronization data between acquisition and + * tracking blocks + */ + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; + + /*! + * \brief Set acquisition channel unique ID + */ + void set_channel(unsigned int channel) override; + + /*! + * \brief Set statistics threshold of PCPS algorithm + */ + void set_threshold(float threshold) override; + + /*! + * \brief Set maximum Doppler off grid search + */ + void set_doppler_max(unsigned int doppler_max) override; + + /*! + * \brief Set Doppler steps for the grid search + */ + void set_doppler_step(unsigned int doppler_step) override; + + /*! + * \brief Initializes acquisition algorithm. + */ + void init() override; + + /*! + * \brief Sets local code for GPS L1/CA PCPS acquisition algorithm. + */ + void set_local_code() override; + + /*! + * \brief Returns the maximum peak of grid search + */ + signed int mag() override; + + /*! + * \brief Restart acquisition algorithm + */ + void reset() override; + + /*! + * \brief If state = 1, it forces the block to start acquiring from the first sample + */ + void set_state(int state); + +private: + ConfigurationInterface* configuration_; + pcps_acquisition_cc_sptr acquisition_cc_; + pcps_acquisition_sc_sptr acquisition_sc_; + gr::blocks::stream_to_vector::sptr stream_to_vector_; + gr::blocks::float_to_complex::sptr float_to_complex_; + complex_byte_to_float_x2_sptr cbyte_to_float_x2_; + size_t item_size_; + std::string item_type_; + unsigned int vector_length_; + unsigned int code_length_; + bool bit_transition_flag_; + bool use_CFAR_algorithm_flag_; + unsigned int channel_; + float threshold_; + unsigned int doppler_max_; + unsigned int doppler_step_; + unsigned int sampled_ms_; + unsigned int max_dwells_; + long fs_in_; + long if_; + bool dump_; + bool blocking_; + std::string dump_filename_; + std::complex * code_; + Gnss_Synchro * gnss_synchro_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; + + float calculate_threshold(float pfa); +}; + +#endif /* GNSS_SDR_GLONASS_L1_CA_PCPS_ACQUISITION_H_ */ diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc index 897532983..726fd0d48 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc @@ -35,6 +35,7 @@ #include "pcps_acquisition_cc.h" #include +#include #include #include #include @@ -42,6 +43,7 @@ #include #include "control_message_factory.h" #include "GPS_L1_CA.h" //GPS_TWO_PI +#include "GLONASS_L1_CA.h" //GLONASS_TWO_PI using google::LogMessage; @@ -77,6 +79,7 @@ pcps_acquisition_cc::pcps_acquisition_cc( d_active = false; d_state = 0; d_freq = freq; + d_old_freq = freq; d_fs_in = fs_in; d_samples_per_ms = samples_per_ms; d_samples_per_code = samples_per_code; @@ -162,6 +165,13 @@ pcps_acquisition_cc::~pcps_acquisition_cc() void pcps_acquisition_cc::set_local_code(std::complex * code) { + // reset the intermediate frequency + d_freq = d_old_freq; + // This will check if it's fdma, if yes will update the intermediate frequency and the doppler grid + if( is_fdma() ) + { + update_grid_doppler_wipeoffs(); + } // COD // Here we want to create a buffer that looks like this: // [ 0 0 0 ... 0 c_0 c_1 ... c_L] @@ -172,8 +182,8 @@ void pcps_acquisition_cc::set_local_code(std::complex * code) int offset = d_fft_size / 2; std::fill_n( d_fft_if->get_inbuf(), offset, gr_complex( 0.0, 0.0 ) ); memcpy(d_fft_if->get_inbuf() + offset, code, sizeof(gr_complex) * offset); - } - else + } + else { memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_fft_size); } @@ -183,6 +193,22 @@ void pcps_acquisition_cc::set_local_code(std::complex * code) } +bool pcps_acquisition_cc::is_fdma() +{ + // Dealing with FDMA system + if( strcmp(d_gnss_synchro->Signal,"1G") == 0 ) + { + d_freq += DFRQ1_GLO * GLONASS_PRN.at(d_gnss_synchro->PRN); + LOG(INFO) << "Trying to acquire SV PRN " << d_gnss_synchro->PRN << " with freq " << d_freq << " in Glonass Channel " << GLONASS_PRN.at(d_gnss_synchro->PRN) << std::endl; + return true; + } + else + { + return false; + } +} + + void pcps_acquisition_cc::update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq) { float phase_step_rad = GPS_TWO_PI * freq / static_cast(d_fs_in); @@ -220,6 +246,20 @@ void pcps_acquisition_cc::init() } +void pcps_acquisition_cc::update_grid_doppler_wipeoffs() +{ + // Create the carrier Doppler wipeoff signals + d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins]; + + for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) + { + d_grid_doppler_wipeoffs[doppler_index] = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + int doppler = -static_cast(d_doppler_max) + d_doppler_step * doppler_index; + update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_freq + doppler); + } +} + + void pcps_acquisition_cc::set_state(int state) { gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h index 17fa90689..5a88aa6f1 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h @@ -58,7 +58,6 @@ #include #include #include "gnss_synchro.h" -#include class pcps_acquisition_cc; @@ -97,6 +96,8 @@ private: std::string dump_filename); void update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq); + void update_grid_doppler_wipeoffs(); + bool is_fdma(); void acquisition_core( unsigned long int samp_count ); @@ -104,6 +105,7 @@ private: void send_positive_acquisition(); long d_fs_in; long d_freq; + long d_old_freq; int d_samples_per_ms; int d_samples_per_code; //unsigned int d_doppler_resolution; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_sc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_sc.cc index 3946493ff..c7869741b 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_sc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_sc.cc @@ -42,6 +42,8 @@ #include #include "control_message_factory.h" #include "GPS_L1_CA.h" //GPS_TWO_PI +#include "GLONASS_L1_CA.h" //GLONASS_TWO_PI + using google::LogMessage; @@ -77,6 +79,7 @@ pcps_acquisition_sc::pcps_acquisition_sc( d_active = false; d_state = 0; d_freq = freq; + d_old_freq = freq; d_fs_in = fs_in; d_samples_per_ms = samples_per_ms; d_samples_per_code = samples_per_code; @@ -183,6 +186,13 @@ pcps_acquisition_sc::~pcps_acquisition_sc() void pcps_acquisition_sc::set_local_code(std::complex * code) { + // reset the intermediate frequency + d_freq = d_old_freq; + // This will check if it's fdma, if yes will update the intermediate frequency and the doppler grid + if( is_fdma() ) + { + update_grid_doppler_wipeoffs(); + } // COD // Here we want to create a buffer that looks like this: // [ 0 0 0 ... 0 c_0 c_1 ... c_L] @@ -204,6 +214,22 @@ void pcps_acquisition_sc::set_local_code(std::complex * code) } +bool pcps_acquisition_sc::is_fdma() +{ + // Dealing with FDMA system + if( strcmp(d_gnss_synchro->Signal,"1G") == 0 ) + { + d_freq += DFRQ1_GLO * GLONASS_PRN.at(d_gnss_synchro->PRN); + LOG(INFO) << "Trying to acquire SV PRN " << d_gnss_synchro->PRN << " with freq " << DFRQ1_GLO * GLONASS_PRN.at(d_gnss_synchro->PRN) << " in Channel " << GLONASS_PRN.at(d_gnss_synchro->PRN) << std::endl; + return true; + } + else + { + return false; + } +} + + void pcps_acquisition_sc::update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq) { float phase_step_rad = GPS_TWO_PI * freq / static_cast(d_fs_in); @@ -243,6 +269,19 @@ void pcps_acquisition_sc::init() d_worker_active = false; } +void pcps_acquisition_sc::update_grid_doppler_wipeoffs() +{ + // Create the carrier Doppler wipeoff signals + d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins]; + + for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) + { + d_grid_doppler_wipeoffs[doppler_index] = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + int doppler = -static_cast(d_doppler_max) + d_doppler_step * doppler_index; + update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_freq + doppler); + } +} + void pcps_acquisition_sc::set_state(int state) { diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_sc.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_sc.h index 7474b910b..068a9c1c7 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_sc.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_sc.h @@ -103,10 +103,15 @@ private: void acquisition_core( void ); + void update_grid_doppler_wipeoffs(); + bool is_fdma(); + void send_negative_acquisition(); void send_positive_acquisition(); + long d_fs_in; long d_freq; + long d_old_freq; int d_samples_per_ms; int d_samples_per_code; //unsigned int d_doppler_resolution; diff --git a/src/algorithms/libs/CMakeLists.txt b/src/algorithms/libs/CMakeLists.txt index dc1b27aac..6ce1d3987 100644 --- a/src/algorithms/libs/CMakeLists.txt +++ b/src/algorithms/libs/CMakeLists.txt @@ -26,6 +26,7 @@ set(GNSS_SPLIBS_SOURCES gnss_sdr_sample_counter.cc gnss_signal_processing.cc gps_sdr_signal_processing.cc + glonass_l1_signal_processing.cc pass_through.cc galileo_e5_signal_processing.cc complex_byte_to_float_x2.cc diff --git a/src/algorithms/libs/glonass_l1_signal_processing.cc b/src/algorithms/libs/glonass_l1_signal_processing.cc new file mode 100644 index 000000000..3ee50707a --- /dev/null +++ b/src/algorithms/libs/glonass_l1_signal_processing.cc @@ -0,0 +1,153 @@ +/*! + * \file glonass_l1_signal_processing.cc + * \brief This class implements various functions for GLONASS L1 CA signals + * \author Javier Arribas, 2011. jarribas(at)cttc.es + * + * Detailed description of the file here if needed. + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "glonass_l1_signal_processing.h" + +auto auxCeil = [](float x){ return static_cast(static_cast((x)+1)); }; + +void glonass_l1_ca_code_gen_complex(std::complex* _dest,/* signed int _prn,*/ unsigned int _chip_shift) +{ + const unsigned int _code_length = 511; + bool G1[_code_length]; + bool G1_register[9]; + bool feedback1; + bool aux; + unsigned int delay; + unsigned int lcv, lcv2; + + for(lcv = 0; lcv < 9; lcv++) + { + G1_register[lcv] = 1; + } + + /* Generate G1 Register */ + for(lcv = 0; lcv < _code_length; lcv++) + { + G1[lcv] = G1_register[2]; + + feedback1 = G1_register[4]^G1_register[0]; + + for(lcv2 = 0; lcv2 < 8; lcv2++) + { + G1_register[lcv2] = G1_register[lcv2 + 1]; + } + + G1_register[8] = feedback1; + } + + /* Generate PRN from G1 Register */ + for(lcv = 0; lcv < _code_length; lcv++) + { + aux = G1[lcv]; + if(aux == true) + { + _dest[lcv] = std::complex(1, 0); + } + else + { + _dest[lcv] = std::complex(-1, 0); + } + } + + /* Set the delay */ + delay = _code_length; + delay += _chip_shift; + delay %= _code_length; + + /* Generate PRN from G1 and G2 Registers */ + for(lcv = 0; lcv < _code_length; lcv++) + { + aux = G1[(lcv + _chip_shift) % _code_length]; + if(aux == true) + { + _dest[lcv] = std::complex(1, 0); + } + else + { + _dest[lcv] = std::complex(-1, 0); + } + delay++; + delay %= _code_length; + } +} + + +/* + * Generates complex GLONASS L1 C/A code for the desired SV ID and sampled to specific sampling frequency + */ +void glonass_l1_ca_code_gen_complex_sampled(std::complex* _dest,/* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift) +{ + // This function is based on the GNU software GPS for MATLAB in the Kay Borre book + std::complex _code[511]; + signed int _samplesPerCode, _codeValueIndex; + float _ts; + float _tc; + float aux; + const signed int _codeFreqBasis = 511000; //Hz + const signed int _codeLength = 511; + + //--- Find number of samples per spreading code ---------------------------- + _samplesPerCode = static_cast(static_cast(_fs) / static_cast(_codeFreqBasis / _codeLength)); + + //--- Find time constants -------------------------------------------------- + _ts = 1.0 / static_cast(_fs); // Sampling period in sec + _tc = 1.0 / static_cast(_codeFreqBasis); // C/A chip period in sec + glonass_l1_ca_code_gen_complex(_code, _chip_shift); //generate C/A code 1 sample per chip + + for (signed int i = 0; i < _samplesPerCode; i++) + { + //=== Digitizing ======================================================= + + //--- Make index array to read C/A code values ------------------------- + // The length of the index array depends on the sampling frequency - + // number of samples per millisecond (because one C/A code period is one + // millisecond). + + // _codeValueIndex = ceil((_ts * ((float)i + 1)) / _tc) - 1; + aux = (_ts * (i + 1)) / _tc; + _codeValueIndex = auxCeil( aux ) - 1; + + //--- Make the digitized version of the C/A code ----------------------- + // The "upsampled" code is made by selecting values form the CA code + // chip array (caCode) for the time instances of each sample. + if (i == _samplesPerCode - 1) + { + //--- Correct the last index (due to number rounding issues) ----------- + _dest[i] = _code[_codeLength - 1]; + + } + else + { + _dest[i] = _code[_codeValueIndex]; //repeat the chip -> upsample + } + } +} diff --git a/src/algorithms/libs/glonass_l1_signal_processing.h b/src/algorithms/libs/glonass_l1_signal_processing.h new file mode 100644 index 000000000..891febcb9 --- /dev/null +++ b/src/algorithms/libs/glonass_l1_signal_processing.h @@ -0,0 +1,47 @@ +/*! + * \file glonass_l1_signal_processing.h + * \brief This class implements various functions for GLONASS L1 CA signals + * \author Gabriel Araujo, 2017. gabriel.araujo(at)ieee.org + * + * Detailed description of the file here if needed. + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GLONASS_SDR_SIGNAL_PROCESSING_H_ +#define GNSS_SDR_GLONASS_SDR_SIGNAL_PROCESSING_H_ + +#include + +//!Generates complex GLONASS L1 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency +void glonass_l1_ca_code_gen_complex(std::complex* _dest, /*signed int _prn,*/ unsigned int _chip_shift); + +//! Generates N complex GLONASS L1 C/A codes for the desired SV ID and code shift +void glonass_l1_ca_code_gen_complex_sampled(std::complex* _dest,/* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift, unsigned int _ncodes); + +//! Generates complex GLONASS L1 C/A code for the desired SV ID and code shift +void glonass_l1_ca_code_gen_complex_sampled(std::complex* _dest,/* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift); + +#endif /* GNSS_SDR_GLONASS_SDR_SIGNAL_PROCESSING_H_ */ diff --git a/src/algorithms/libs/gnss_sdr_valve.cc b/src/algorithms/libs/gnss_sdr_valve.cc index 152bdbe84..0170d6cdc 100644 --- a/src/algorithms/libs/gnss_sdr_valve.cc +++ b/src/algorithms/libs/gnss_sdr_valve.cc @@ -35,6 +35,7 @@ #include // for memcpy #include #include "control_message_factory.h" +#include gnss_sdr_valve::gnss_sdr_valve (size_t sizeof_stream_item, unsigned long long nitems, @@ -61,6 +62,7 @@ int gnss_sdr_valve::work (int noutput_items, { ControlMessageFactory* cmf = new ControlMessageFactory(); d_queue->handle(cmf->GetQueueMessage(200,0)); + LOG(INFO) << "Stoping reciver, "<< d_ncopied_items << " samples processed"; delete cmf; return -1; // Done! } diff --git a/src/algorithms/libs/rtklib/rtklib.h b/src/algorithms/libs/rtklib/rtklib.h index ec0274b71..7aa7ddf5f 100644 --- a/src/algorithms/libs/rtklib/rtklib.h +++ b/src/algorithms/libs/rtklib/rtklib.h @@ -182,6 +182,7 @@ const int SYS_ALL = 0xFF; //!< navigation system: all +#define ENAGLO #ifdef ENAGLO const int MINPRNGLO = 1; //!< min satellite slot number of GLONASS const int MAXPRNGLO = 27; //!< max satellite slot number of GLONASS @@ -194,6 +195,12 @@ const int NSATGLO = 0; const int NSYSGLO = 0; #endif +/* +const int MINPRNGLO = 1; //!< min satellite slot number of GLONASS +const int MAXPRNGLO = 27; //!< max satellite slot number of GLONASS +const int NSATGLO = (MAXPRNGLO - MINPRNGLO + 1); //!< number of GLONASS satellites +const int NSYSGLO = 1; +*/ const int MINPRNGAL = 1; //!< min satellite PRN number of Galileo const int MAXPRNGAL = 30; //!< max satellite PRN number of Galileo const int NSATGAL = (MAXPRNGAL - MINPRNGAL + 1); //!< number of Galileo satellites diff --git a/src/algorithms/libs/rtklib/rtklib_conversions.cc b/src/algorithms/libs/rtklib/rtklib_conversions.cc index ec2e9df7e..7f1d933a6 100644 --- a/src/algorithms/libs/rtklib/rtklib_conversions.cc +++ b/src/algorithms/libs/rtklib/rtklib_conversions.cc @@ -62,6 +62,10 @@ obsd_t insert_obs_to_rtklib(obsd_t & rtklib_obs, const Gnss_Synchro & gnss_synch case 'E': rtklib_obs.sat = gnss_synchro.PRN+NSATGPS+NSATGLO; break; + case 'R': + rtklib_obs.sat = gnss_synchro.PRN+NSATGPS; + break; + default: rtklib_obs.sat = gnss_synchro.PRN; } @@ -70,6 +74,46 @@ obsd_t insert_obs_to_rtklib(obsd_t & rtklib_obs, const Gnss_Synchro & gnss_synch return rtklib_obs; } +geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris & glonass_gnav_eph, const Glonass_Gnav_Utc_Model & gnav_clock_model) +{ + double week, sec; + int adj_week; + geph_t rtklib_sat = {0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0.0, 0.0, 0.0}, {0.0, 0.0, + 0.0}, {0.0, 0.0, 0.0}, 0.0, 0.0, 0.0}; + + rtklib_sat.sat = glonass_gnav_eph.i_satellite_slot_number + NSATGPS; /* satellite number */ + rtklib_sat.iode = static_cast(glonass_gnav_eph.d_t_b); /* IODE (0-6 bit of tb field) */ + rtklib_sat.frq = glonass_gnav_eph.i_satellite_freq_channel; /* satellite frequency number */ + rtklib_sat.svh = glonass_gnav_eph.d_l3rd_n; /* satellite health*/ + rtklib_sat.sva = static_cast(glonass_gnav_eph.d_F_T); /* satellite accuracy*/ + rtklib_sat.age = static_cast(glonass_gnav_eph.d_E_n); /* satellite age*/ + rtklib_sat.pos[0] = glonass_gnav_eph.d_Xn*1000; /* satellite position (ecef) (m) */ + rtklib_sat.pos[1] = glonass_gnav_eph.d_Yn*1000; /* satellite position (ecef) (m) */ + rtklib_sat.pos[2] = glonass_gnav_eph.d_Zn*1000; /* satellite position (ecef) (m) */ + rtklib_sat.vel[0] = glonass_gnav_eph.d_VXn*1000; /* satellite velocity (ecef) (m/s) */ + rtklib_sat.vel[1] = glonass_gnav_eph.d_VYn*1000; /* satellite velocity (ecef) (m/s) */ + rtklib_sat.vel[2] = glonass_gnav_eph.d_VZn*1000; /* satellite velocity (ecef) (m/s) */ + rtklib_sat.acc[0] = glonass_gnav_eph.d_AXn*1000; /* satellite acceleration (ecef) (m/s^2) */ + rtklib_sat.acc[1] = glonass_gnav_eph.d_AYn*1000; /* satellite acceleration (ecef) (m/s^2) */ + rtklib_sat.acc[2] = glonass_gnav_eph.d_AZn*1000; /* satellite acceleration (ecef) (m/s^2) */ + rtklib_sat.taun = glonass_gnav_eph.d_tau_n; /* SV clock bias (s) */ + rtklib_sat.gamn = glonass_gnav_eph.d_gamma_n; /* SV relative freq bias */ + rtklib_sat.age = static_cast(glonass_gnav_eph.d_Delta_tau_n); /* delay between L1 and L2 (s) */ + + // Time expressed in GPS Time but using RTKLib format + glonass_gnav_eph.glot_to_gpst(glonass_gnav_eph.d_t_b, gnav_clock_model.d_tau_c, gnav_clock_model.d_tau_gps, &week, &sec); + adj_week = adjgpsweek(static_cast(week)); + rtklib_sat.toe = gpst2time(adj_week, sec); + + // Time expressed in GPS Time but using RTKLib format + glonass_gnav_eph.glot_to_gpst(glonass_gnav_eph.d_t_k, gnav_clock_model.d_tau_c, gnav_clock_model.d_tau_gps, &week, &sec); + adj_week = adjgpsweek(static_cast(week)); + rtklib_sat.tof = gpst2time(adj_week, sec); + + return rtklib_sat; +} + + eph_t eph_to_rtklib(const Galileo_Ephemeris & gal_eph) { eph_t rtklib_sat = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0, diff --git a/src/algorithms/libs/rtklib/rtklib_conversions.h b/src/algorithms/libs/rtklib/rtklib_conversions.h index 18336754f..e5a73e88d 100644 --- a/src/algorithms/libs/rtklib/rtklib_conversions.h +++ b/src/algorithms/libs/rtklib/rtklib_conversions.h @@ -36,10 +36,18 @@ #include "galileo_ephemeris.h" #include "gps_ephemeris.h" #include "gps_cnav_ephemeris.h" +#include "glonass_gnav_ephemeris.h" +#include "glonass_gnav_utc_model.h" eph_t eph_to_rtklib(const Galileo_Ephemeris & gal_eph); eph_t eph_to_rtklib(const Gps_Ephemeris & gps_eph); eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris & gps_cnav_eph); +/*! + * \brief Transforms a Glonass_Gnav_Ephemeris to its RTKLIB counterpart + * \param glonass_gnav_eph GLONASS GNAV Ephemeris structure + * \return Ephemeris structure for RTKLIB parsing + */ +geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris & glonass_gnav_eph, const Glonass_Gnav_Utc_Model & gnav_clock_model); obsd_t insert_obs_to_rtklib(obsd_t & rtklib_obs, const Gnss_Synchro & gnss_synchro, int week, int band); diff --git a/src/algorithms/libs/rtklib/rtklib_rtksvr.cc b/src/algorithms/libs/rtklib/rtklib_rtksvr.cc index 9026c5db2..6d7ce21ec 100644 --- a/src/algorithms/libs/rtklib/rtklib_rtksvr.cc +++ b/src/algorithms/libs/rtklib/rtklib_rtksvr.cc @@ -350,6 +350,12 @@ int decoderaw(rtksvr_t *svr, int index) /* decode download file ------------------------------------------------------*/ void decodefile(rtksvr_t *svr, int index) { + int i = 0; + char glo_fcn[MAXPRNGLO+1]; + + // Allocate space for GLONASS frequency channels depending on availability + for(i=0; i < MAXPRNGLO+1; i++) + glo_fcn[i]='0'; pcv_t pcvt0[MAXSAT] = { {0, {'0'}, {'0'}, {0, 0.0}, {0, 0.0}, {{0.0},{0.0}}, {{0.0},{0.0}} } }; sbsfcorr_t sbsfcorr0 = {{0, 0.0}, 0.0, 0.0, 0.0, 0, 0, 0}; sbslcorr_t sbslcorr0 = { {0, 0.0}, 0, {0.0}, {0.0}, 0.0, 0.0}; @@ -366,7 +372,7 @@ void decodefile(rtksvr_t *svr, int index) nav_t nav = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, (erpd_t *){0}}, {0.0}, {0.0}, {0.0}, {0.0}, {0.0}, {0.0}, {0.0}, {0.0}, {0.0}, {0.0}, {0.0}, {0.0}, 0, {{0.0},{0.0}}, {{0.0},{0.0}}, {{0.0}, {0.0}, {0.0}}, - {0.0}, {0.0}, {'0'}, {*pcvt0}, sbssat0, {*sbsion0}, {*dgps0}, {*ssr0}, {*lexeph0}, + {0.0}, {0.0}, {*glo_fcn}, {*pcvt0}, sbssat0, {*sbsion0}, {*dgps0}, {*ssr0}, {*lexeph0}, {{0,0.0}, 0.0, {0.0}, {{0.0},{0.0}} }, pppcorr0} ; char file[1024]; diff --git a/src/algorithms/signal_generator/adapters/signal_generator.cc b/src/algorithms/signal_generator/adapters/signal_generator.cc index 35ecfdddc..57e3c0aa0 100644 --- a/src/algorithms/signal_generator/adapters/signal_generator.cc +++ b/src/algorithms/signal_generator/adapters/signal_generator.cc @@ -36,6 +36,7 @@ #include "Galileo_E1.h" #include "GPS_L1_CA.h" #include "Galileo_E5a.h" +#include "GLONASS_L1_CA.h" using google::LogMessage; @@ -102,6 +103,11 @@ SignalGenerator::SignalGenerator(ConfigurationInterface* configuration, vector_length = round(static_cast(fs_in) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); } + else if (std::find(system.begin(), system.end(), "R") != system.end()) + { + vector_length = round((float)fs_in + / (GLONASS_L1_CA_CODE_RATE_HZ / GLONASS_L1_CA_CODE_LENGTH_CHIPS)); + } if (item_type_.compare("gr_complex") == 0) { diff --git a/src/algorithms/signal_generator/gnuradio_blocks/signal_generator_c.cc b/src/algorithms/signal_generator/gnuradio_blocks/signal_generator_c.cc index 86f488588..6d84c3084 100644 --- a/src/algorithms/signal_generator/gnuradio_blocks/signal_generator_c.cc +++ b/src/algorithms/signal_generator/gnuradio_blocks/signal_generator_c.cc @@ -34,11 +34,13 @@ #include #include #include "gps_sdr_signal_processing.h" +#include "glonass_l1_signal_processing.h" #include "galileo_e1_signal_processing.h" #include "galileo_e5_signal_processing.h" #include "Galileo_E1.h" #include "Galileo_E5a.h" #include "GPS_L1_CA.h" +#include "GLONASS_L1_CA.h" /* * Create a new instance of signal_generator_c and return @@ -107,6 +109,14 @@ void signal_generator_c::init() num_of_codes_per_vector_.push_back(galileo_signal ? 4 * static_cast(Galileo_E1_C_SECONDARY_CODE_LENGTH) : 1); data_bit_duration_ms_.push_back(1e3 / GPS_CA_TELEMETRY_RATE_BITS_SECOND); } + else if (system_[sat] == "R") + { + samples_per_code_.push_back(round(static_cast(fs_in_) + / (GLONASS_L1_CA_CODE_RATE_HZ / GLONASS_L1_CA_CODE_LENGTH_CHIPS))); + + num_of_codes_per_vector_.push_back(galileo_signal ? 4 * static_cast(Galileo_E1_C_SECONDARY_CODE_LENGTH) : 1); + data_bit_duration_ms_.push_back(1e3 / GLONASS_GNAV_TELEMETRY_RATE_BITS_SECOND); + } else if (system_[sat] == "E") { if (signal_[sat].at(0) == '5') @@ -160,6 +170,28 @@ void signal_generator_c::generate_codes() } } + // Concatenate "num_of_codes_per_vector_" codes + for (unsigned int i = 0; i < num_of_codes_per_vector_[sat]; i++) + { + memcpy(&(sampled_code_data_[sat][i * samples_per_code_[sat]]), + code, sizeof(gr_complex) * samples_per_code_[sat]); + } + } + else if (system_[sat] == "R") + { + // Generate one code-period of 1G signal + glonass_l1_ca_code_gen_complex_sampled(code, /*PRN_[sat],*/ fs_in_, + static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS) - delay_chips_[sat]); + + // Obtain the desired CN0 assuming that Pn = 1. + if (noise_flag_) + { + for (unsigned int i = 0; i < samples_per_code_[sat]; i++) + { + code[i] *= sqrt(pow(10,CN0_dB_[sat] / 10) / BW_BB_); + } + } + // Concatenate "num_of_codes_per_vector_" codes for (unsigned int i = 0; i < num_of_codes_per_vector_[sat]; i++) { @@ -261,6 +293,8 @@ int signal_generator_c::general_work (int noutput_items __attribute__((unused)), unsigned int out_idx = 0; unsigned int i = 0; unsigned int k = 0; + // the intermediate frequency must be set by the user + unsigned int freq = 4e6; for (out_idx = 0; out_idx < vector_length_; out_idx++) { @@ -311,6 +345,45 @@ int signal_generator_c::general_work (int noutput_items __attribute__((unused)), } } + else if (system_[sat] == "R") + { + phase_step_rad = -static_cast(GPS_TWO_PI) * (freq + (DFRQ1_GLO * GLONASS_PRN.at(PRN_[sat])) + doppler_Hz_[sat]) / static_cast(fs_in_); + // std::cout << "sat " << PRN_[sat] << " SG - Freq = " << (freq + (DFRQ1_GLO * GLONASS_PRN.at(PRN_[sat]))) << " Doppler = " << doppler_Hz_[sat] << std::endl; + _phase[0] = -start_phase_rad_[sat]; + volk_gnsssdr_s32f_sincos_32fc(complex_phase_, -phase_step_rad, _phase, vector_length_); + + unsigned int delay_samples = (delay_chips_[sat] % static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS)) + * samples_per_code_[sat] / GLONASS_L1_CA_CODE_LENGTH_CHIPS; + + for (i = 0; i < num_of_codes_per_vector_[sat]; i++) + { + for (k = 0; k < delay_samples; k++) + { + out[out_idx] += sampled_code_data_[sat][out_idx] + * current_data_bits_[sat] + * complex_phase_[out_idx]; + out_idx++; + } + + if (ms_counter_[sat] == 0 && data_flag_) + { + // New random data bit + current_data_bits_[sat] = gr_complex((uniform_dist(e1) % 2) == 0 ? 1 : -1, 0); + } + + for (k = delay_samples; k < samples_per_code_[sat]; k++) + { + out[out_idx] += sampled_code_data_[sat][out_idx] + * current_data_bits_[sat] + * complex_phase_[out_idx]; + out_idx++; + } + + ms_counter_[sat] = (ms_counter_[sat] + static_cast(round(1e3*GLONASS_L1_CA_CODE_PERIOD))) + % data_bit_duration_ms_[sat]; + } + } + else if (system_[sat] == "E") { if(signal_[sat].at(0)=='5') diff --git a/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt b/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt index 07dd84bea..cf09a7cde 100644 --- a/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt @@ -16,13 +16,15 @@ # along with GNSS-SDR. If not, see . # -set(TELEMETRY_DECODER_ADAPTER_SOURCES - gps_l1_ca_telemetry_decoder.cc + +set(TELEMETRY_DECODER_ADAPTER_SOURCES + gps_l1_ca_telemetry_decoder.cc gps_l2c_telemetry_decoder.cc gps_l5_telemetry_decoder.cc galileo_e1b_telemetry_decoder.cc sbas_l1_telemetry_decoder.cc galileo_e5a_telemetry_decoder.cc + glonass_l1_ca_telemetry_decoder.cc ) include_directories( diff --git a/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.cc new file mode 100644 index 000000000..5e4b5a4bc --- /dev/null +++ b/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.cc @@ -0,0 +1,102 @@ +/*! + * \file glonass_l1_ca_telemetry_decoder.cc + * \brief Implementation of an adapter of a GLONASS L1 C/A NAV data decoder block + * to a TelemetryDecoderInterface + * \note Code added as part of GSoC 2017 program + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (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 . + * + * ------------------------------------------------------------------------- + */ + + +#include "glonass_l1_ca_telemetry_decoder.h" +#include +#include +#include "concurrent_queue.h" +#include "glonass_gnav_ephemeris.h" +#include "glonass_gnav_almanac.h" +#include "glonass_gnav_utc_model.h" +#include "configuration_interface.h" + +using google::LogMessage; + +GlonassL1CaTelemetryDecoder::GlonassL1CaTelemetryDecoder(ConfigurationInterface* configuration, + std::string role, + unsigned int in_streams, + unsigned int out_streams) : + role_(role), + in_streams_(in_streams), + out_streams_(out_streams) +{ + std::string default_dump_filename = "./navigation.dat"; + DLOG(INFO) << "role " << role; + dump_ = configuration->property(role + ".dump", false); + dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + // make telemetry decoder object + telemetry_decoder_ = glonass_l1_ca_make_telemetry_decoder_cc(satellite_, dump_); + DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; + + DLOG(INFO) << "global navigation message queue assigned to telemetry_decoder ("<< telemetry_decoder_->unique_id() << ")"; + channel_ = 0; +} + + +GlonassL1CaTelemetryDecoder::~GlonassL1CaTelemetryDecoder() +{} + + +void GlonassL1CaTelemetryDecoder::set_satellite(const Gnss_Satellite & satellite) +{ + satellite_ = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); + telemetry_decoder_->set_satellite(satellite_); + DLOG(INFO) << "TELEMETRY DECODER: satellite set to " << satellite_; +} + + +void GlonassL1CaTelemetryDecoder::connect(gr::top_block_sptr top_block) +{ + if(top_block) { /* top_block is not null */}; + // Nothing to connect internally + DLOG(INFO) << "nothing to connect internally"; +} + + +void GlonassL1CaTelemetryDecoder::disconnect(gr::top_block_sptr top_block) +{ + if(top_block) { /* top_block is not null */}; + // Nothing to disconnect +} + + +gr::basic_block_sptr GlonassL1CaTelemetryDecoder::get_left_block() +{ + return telemetry_decoder_; +} + + +gr::basic_block_sptr GlonassL1CaTelemetryDecoder::get_right_block() +{ + return telemetry_decoder_; +} diff --git a/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.h new file mode 100644 index 000000000..6eef6e858 --- /dev/null +++ b/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.h @@ -0,0 +1,92 @@ +/*! + * \file glonass_l1_ca_telemetry_decoder.h + * \brief Interface of an adapter of a GLONASS L1 C/A NAV data decoder block + * to a TelemetryDecoderInterface + * \note Code added as part of GSoC 2017 program + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (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 . + * + * ------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_GLONASS_L1_CA_TELEMETRY_DECODER_H_ +#define GNSS_SDR_GLONASS_L1_CA_TELEMETRY_DECODER_H_ + +#include +#include "telemetry_decoder_interface.h" +#include "glonass_l1_ca_telemetry_decoder_cc.h" + + +class ConfigurationInterface; + +/*! + * \brief This class implements a NAV data decoder for GLONASS L1 C/A + */ +class GlonassL1CaTelemetryDecoder : public TelemetryDecoderInterface +{ +public: + GlonassL1CaTelemetryDecoder(ConfigurationInterface* configuration, + std::string role, + unsigned int in_streams, + unsigned int out_streams); + + virtual ~GlonassL1CaTelemetryDecoder(); + std::string role() override + { + return role_; + } + + //! Returns "GLONASS_L1_CA_Telemetry_Decoder" + std::string implementation() override + { + return "GLONASS_L1_CA_Telemetry_Decoder"; + } + void connect(gr::top_block_sptr top_block) override; + void disconnect(gr::top_block_sptr top_block) override; + gr::basic_block_sptr get_left_block() override; + gr::basic_block_sptr get_right_block() override; + void set_satellite(const Gnss_Satellite & satellite) override; + void set_channel(int channel) override {telemetry_decoder_->set_channel(channel);} + void reset() override + { + return; + } + size_t item_size() override + { + return 0; + } + +private: + glonass_l1_ca_telemetry_decoder_cc_sptr telemetry_decoder_; + Gnss_Satellite satellite_; + int channel_; + bool dump_; + std::string dump_filename_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; +}; + +#endif diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt b/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt index 80f4ae476..29e83b79c 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt @@ -16,15 +16,16 @@ # along with GNSS-SDR. If not, see . # -set(TELEMETRY_DECODER_GR_BLOCKS_SOURCES +set(TELEMETRY_DECODER_GR_BLOCKS_SOURCES gps_l1_ca_telemetry_decoder_cc.cc gps_l2c_telemetry_decoder_cc.cc gps_l5_telemetry_decoder_cc.cc galileo_e1b_telemetry_decoder_cc.cc sbas_l1_telemetry_decoder_cc.cc galileo_e5a_telemetry_decoder_cc.cc + glonass_l1_ca_telemetry_decoder_cc.cc ) - + include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/src/core/system_parameters @@ -41,4 +42,4 @@ file(GLOB TELEMETRY_DECODER_GR_BLOCKS_HEADERS "*.h") list(SORT TELEMETRY_DECODER_GR_BLOCKS_HEADERS) add_library(telemetry_decoder_gr_blocks ${TELEMETRY_DECODER_GR_BLOCKS_SOURCES} ${TELEMETRY_DECODER_GR_BLOCKS_HEADERS}) source_group(Headers FILES ${TELEMETRY_DECODER_GR_BLOCKS_HEADERS}) -target_link_libraries(telemetry_decoder_gr_blocks telemetry_decoder_libswiftcnav telemetry_decoder_lib gnss_system_parameters ${GNURADIO_RUNTIME_LIBRARIES}) \ No newline at end of file +target_link_libraries(telemetry_decoder_gr_blocks telemetry_decoder_libswiftcnav telemetry_decoder_lib gnss_system_parameters ${GNURADIO_RUNTIME_LIBRARIES}) diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc new file mode 100644 index 000000000..c5a69489a --- /dev/null +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc @@ -0,0 +1,453 @@ +/*! + * \file glonass_l1_ca_telemetry_decoder_cc.cc + * \brief Implementation of an adapter of a GLONASS L1 C/A NAV data decoder block + * to a TelemetryDecoderInterface + * \note Code added as part of GSoC 2017 program + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (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 . + * + * ------------------------------------------------------------------------- + */ + + +#include "glonass_l1_ca_telemetry_decoder_cc.h" +#include +#include +#include + + +#define CRC_ERROR_LIMIT 6 + +using google::LogMessage; + + +glonass_l1_ca_telemetry_decoder_cc_sptr +glonass_l1_ca_make_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump) +{ + return glonass_l1_ca_telemetry_decoder_cc_sptr(new glonass_l1_ca_telemetry_decoder_cc(satellite, dump)); +} + + +glonass_l1_ca_telemetry_decoder_cc::glonass_l1_ca_telemetry_decoder_cc( + const Gnss_Satellite & satellite, + bool dump) : + gr::block("glonass_l1_ca_telemetry_decoder_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) +{ + // Telemetry Bit transition synchronization port out + this->message_port_register_out(pmt::mp("preamble_timestamp_s")); + // Ephemeris data port out + this->message_port_register_out(pmt::mp("telemetry")); + // initialize internal vars + d_dump = dump; + d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); + LOG(INFO) << "Initializing GLONASS L1 CA TELEMETRY DECODING"; + // Define the number of sampes per symbol. Notice that GLONASS has 2 rates, + //one for the navigation data and the other for the preamble information + d_samples_per_symbol = ( GLONASS_L1_CA_CODE_RATE_HZ / GLONASS_L1_CA_CODE_LENGTH_CHIPS ) / GLONASS_L1_CA_SYMBOL_RATE_BPS; + + // Set the preamble information + unsigned short int preambles_bits[GLONASS_GNAV_PREAMBLE_LENGTH_BITS] = GLONASS_GNAV_PREAMBLE; + // Since preamble rate is different than navigation data rate we use a constant + d_symbols_per_preamble = GLONASS_GNAV_PREAMBLE_LENGTH_SYMBOLS; + + memcpy(static_cast(this->d_preambles_bits), static_cast(preambles_bits), GLONASS_GNAV_PREAMBLE_LENGTH_BITS * sizeof(unsigned short int)); + + // preamble bits to sampled symbols + d_preambles_symbols = static_cast(malloc(sizeof(signed int) * d_symbols_per_preamble)); + int n = 0; + for (int i = 0; i < GLONASS_GNAV_PREAMBLE_LENGTH_BITS; i++) + { + for (unsigned int j = 0; j < GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_PREAMBLE_BIT; j++) + { + if (d_preambles_bits[i] == 1) + { + d_preambles_symbols[n] = 1; + } + else + { + d_preambles_symbols[n] = -1; + } + n++; + } + } + d_sample_counter = 0; + d_stat = 0; + d_preamble_index = 0; + + d_flag_frame_sync = false; + + d_flag_parity = false; + d_TOW_at_current_symbol = 0; + Flag_valid_word = false; + delta_t = 0; + d_CRC_error_counter = 0; + d_flag_preamble = false; + d_channel = 0; + flag_TOW_set = false; + d_preamble_time_samples = 0; +} + + +glonass_l1_ca_telemetry_decoder_cc::~glonass_l1_ca_telemetry_decoder_cc() +{ + delete d_preambles_symbols; + if(d_dump_file.is_open() == true) + { + try + { + d_dump_file.close(); + } + catch(const std::exception & ex) + { + LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); + } + } +} + + +void glonass_l1_ca_telemetry_decoder_cc::decode_string(double *frame_symbols,int frame_length) +{ + double chip_acc = 0.0; + int chip_acc_counter = 0; + + // 1. Transform from symbols to bits + std::string bi_binary_code; + std::string relative_code; + std::string data_bits; + + // Group samples into bi-binary code + for(int i = 0; i < (frame_length); i++) + { + chip_acc += frame_symbols[i]; + chip_acc_counter += 1; + + if(chip_acc_counter == (GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_BIT)) + { + if (chip_acc > 0) + { + bi_binary_code.push_back('1'); + chip_acc_counter = 0; + chip_acc = 0; + } + else + { + bi_binary_code.push_back('0'); + chip_acc_counter = 0; + chip_acc = 0; + } + } + } + // Convert from bi-binary code to relative code + for(int i = 0; i < (GLONASS_GNAV_STRING_BITS); i++) + { + if(bi_binary_code[2*i] == '1' && bi_binary_code[2*i + 1] == '0') + { + relative_code.push_back('1'); + } + else + { + relative_code.push_back('0'); + } + } + // Convert from relative code to data bits + data_bits.push_back('0'); + for(int i = 1; i < (GLONASS_GNAV_STRING_BITS); i++) + { + data_bits.push_back(((relative_code[i-1]-'0') ^ (relative_code[i]-'0')) + '0'); + } + + // 2. Call the GLONASS GNAV string decoder + d_nav.string_decoder(data_bits); + + // 3. Check operation executed correctly + if(d_nav.flag_CRC_test == true) + { + LOG(INFO) << "GLONASS GNAV CRC correct on channel " << d_channel << " from satellite "<< d_satellite; + } + else + { + LOG(INFO) << "GLONASS GNAV CRC error on channel " << d_channel << " from satellite " << d_satellite; + } + // 4. Push the new navigation data to the queues + if (d_nav.have_new_ephemeris() == true) + { + // get object for this SV (mandatory) + d_nav.gnav_ephemeris.i_satellite_freq_channel = d_satellite.get_rf_link(); + std::shared_ptr tmp_obj = std::make_shared(d_nav.get_ephemeris()); + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + LOG(INFO) << "GLONASS GNAV Ephemeris have been received on channel" << d_channel << " from satellite " << d_satellite; + } + if (d_nav.have_new_utc_model() == true) + { + // get object for this SV (mandatory) + std::shared_ptr tmp_obj = std::make_shared(d_nav.get_utc_model()); + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + LOG(INFO) << "GLONASS GNAV UTC Model have been received on channel" << d_channel << " from satellite " << d_satellite; + } + if (d_nav.have_new_almanac() == true) + { + unsigned int slot_nbr = d_nav.i_alm_satellite_slot_number; + std::shared_ptr tmp_obj= std::make_shared(d_nav.get_almanac(slot_nbr)); + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + LOG(INFO) << "GLONASS GNAV Almanac have been received on channel" << d_channel << " in slot number " << slot_nbr; + } + // 5. Update satellite information on system + if(d_nav.flag_update_slot_number == true) + { + LOG(INFO) << "GLONASS GNAV Slot Number Identified on channel " << d_channel; + d_satellite.update_PRN(d_nav.gnav_ephemeris.d_n); + d_satellite.what_block(d_satellite.get_system(), d_nav.gnav_ephemeris.d_n); + d_nav.flag_update_slot_number = false; + } +} + + +int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) +{ + int corr_value = 0; + int preamble_diff = 0; + + Gnss_Synchro **out = reinterpret_cast(&output_items[0]); // Get the output buffer pointer + const Gnss_Synchro **in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer + + Gnss_Synchro current_symbol; //structure to save the synchronization information and send the output object to the next block + //1. Copy the current tracking output + current_symbol = in[0][0]; + d_symbol_history.push_back(current_symbol); //add new symbol to the symbol queue + d_sample_counter++; //count for the processed samples + consume_each(1); + + d_flag_preamble = false; + unsigned int required_symbols = GLONASS_GNAV_STRING_SYMBOLS; + + if (d_symbol_history.size()>required_symbols) + { + //******* preamble correlation ******** + for (int i = 0; i < d_symbols_per_preamble; i++) + { + if (d_symbol_history.at(i).Prompt_I < 0) // symbols clipping + { + corr_value -= d_preambles_symbols[i]; + } + else + { + corr_value += d_preambles_symbols[i]; + } + } + } + + //******* frame sync ****************** + if (d_stat == 0) //no preamble information + { + if (abs(corr_value) >= d_symbols_per_preamble) + { + // Record the preamble sample stamp + d_preamble_index = d_sample_counter; + LOG(INFO) << "Preamble detection for GLONASS L1 C/A SAT " << this->d_satellite; + // Enter into frame pre-detection status + d_stat = 1; + d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; // record the preamble sample stamp + } + } + else if (d_stat == 1) // posible preamble lock + { + if (abs(corr_value) >= d_symbols_per_preamble) + { + //check preamble separation + preamble_diff = d_sample_counter - d_preamble_index; + // Record the PRN start sample index associated to the preamble + d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; + if (abs(preamble_diff - GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS) == 0) + { + //try to decode frame + LOG(INFO) << "Starting string decoder for GLONASS L1 C/A SAT " << this->d_satellite; + d_preamble_index = d_sample_counter; //record the preamble sample stamp + d_stat = 2; + // send asynchronous message to tracking to inform of frame sync and extend correlation time + pmt::pmt_t value = pmt::from_double(static_cast(d_preamble_time_samples) / static_cast(d_symbol_history.at(0).fs) - 0.001); + this->message_port_pub(pmt::mp("preamble_timestamp_s"), value); + } + else + { + if (preamble_diff > GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS) + { + d_stat = 0; // start again + } + DLOG(INFO) << "Failed string decoder for GLONASS L1 C/A SAT " << this->d_satellite; + } + } + } + else if (d_stat == 2) + { + // FIXME: The preamble index marks the first symbol of the string count. Here I just wait for another full string to be received before processing + if (d_sample_counter == d_preamble_index + GLONASS_GNAV_STRING_SYMBOLS) + { + // NEW GLONASS string received + // 0. fetch the symbols into an array + int string_length = GLONASS_GNAV_STRING_SYMBOLS - d_symbols_per_preamble; + double string_symbols[GLONASS_GNAV_DATA_SYMBOLS] = {0}; + + //******* SYMBOL TO BIT ******* + for (int i = 0; i < string_length; i++) + { + if (corr_value > 0) + { + string_symbols[i] = d_symbol_history.at(i + d_symbols_per_preamble).Prompt_I; // because last symbol of the preamble is just received now! + + } + else + { + string_symbols[i] = -d_symbol_history.at(i + d_symbols_per_preamble).Prompt_I; // because last symbol of the preamble is just received now! + } + } + + //call the decoder + decode_string(string_symbols, string_length); + if (d_nav.flag_CRC_test == true) + { + d_CRC_error_counter = 0; + d_flag_preamble = true; //valid preamble indicator (initialized to false every work()) + d_preamble_index = d_sample_counter; //record the preamble sample stamp (t_P) + if (!d_flag_frame_sync) + { + d_flag_frame_sync = true; + DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at " + << d_symbol_history.at(0).Tracking_sample_counter << " [samples]"; + } + } + else + { + d_CRC_error_counter++; + d_preamble_index = d_sample_counter; //record the preamble sample stamp + if (d_CRC_error_counter > CRC_ERROR_LIMIT) + { + LOG(INFO) << "Lost of frame sync SAT " << this->d_satellite; + d_flag_frame_sync = false; + d_stat = 0; + } + } + } + } + + // UPDATE GNSS SYNCHRO DATA + //2. Add the telemetry decoder information + if (this->d_flag_preamble == true and d_nav.flag_TOW_new == true) + //update TOW at the preamble instant + { + d_TOW_at_current_symbol = floor((d_nav.gnav_ephemeris.d_TOW-GLONASS_GNAV_PREAMBLE_DURATION_S)*1000)/1000; + d_nav.flag_TOW_new = false; + + } + else //if there is not a new preamble, we define the TOW of the current symbol + { + d_TOW_at_current_symbol = d_TOW_at_current_symbol + GLONASS_L1_CA_CODE_PERIOD; + } + + //if (d_flag_frame_sync == true and d_nav.flag_TOW_set==true and d_nav.flag_CRC_test == true) + + // if(d_nav.flag_GGTO_1 == true and d_nav.flag_GGTO_2 == true and d_nav.flag_GGTO_3 == true and d_nav.flag_GGTO_4 == true) //all GGTO parameters arrived + // { + // delta_t = d_nav.A_0G_10 + d_nav.A_1G_10 * (d_TOW_at_current_symbol - d_nav.t_0G_10 + 604800.0 * (fmod((d_nav.WN_0 - d_nav.WN_0G_10), 64))); + // } + + if (d_flag_frame_sync == true and d_nav.flag_TOW_set == true) + { + current_symbol.Flag_valid_word = true; + } + else + { + current_symbol.Flag_valid_word = false; + } + + current_symbol.PRN = this->d_satellite.get_PRN(); + current_symbol.TOW_at_current_symbol_s = d_TOW_at_current_symbol; + current_symbol.TOW_at_current_symbol_s -= delta_t; // Galileo to GPS TOW + + if(d_dump == true) + { + // MULTIPLEXED FILE RECORDING - Record results to file + try + { + double tmp_double; + unsigned long int tmp_ulong_int; + tmp_double = d_TOW_at_current_symbol; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_ulong_int = current_symbol.Tracking_sample_counter; + d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(unsigned long int)); + tmp_double = 0; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + } + catch (const std::ifstream::failure & e) + { + LOG(WARNING) << "Exception writing observables dump file " << e.what(); + } + } + + // remove used symbols from history + if (d_symbol_history.size()>required_symbols) + { + d_symbol_history.pop_front(); + } + //3. Make the output (copy the object contents to the GNURadio reserved memory) + *out[0] = current_symbol; + + return 1; +} + + +void glonass_l1_ca_telemetry_decoder_cc::set_satellite(const Gnss_Satellite & satellite) +{ + d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); + DLOG(INFO) << "Setting decoder Finite State Machine to satellite "<< d_satellite; + DLOG(INFO) << "Navigation Satellite set to " << d_satellite; +} + + +void glonass_l1_ca_telemetry_decoder_cc::set_channel(int channel) +{ + d_channel = channel; + LOG(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(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); + LOG(INFO) << "Telemetry decoder dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str(); + } + catch (const std::ifstream::failure& e) + { + LOG(WARNING) << "channel " << d_channel << ": exception opening Glonass TLM dump file. " << e.what(); + } + } + } +} diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.h new file mode 100644 index 000000000..8973d7d95 --- /dev/null +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.h @@ -0,0 +1,120 @@ +/*! + * \file glonass_l1_ca_telemetry_decoder_cc.h + * \brief Implementation of an adapter of a GLONASS L1 C/A NAV data decoder block + * to a TelemetryDecoderInterface + * \note Code added as part of GSoC 2017 program + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (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 . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GLONASS_L1_CA_TELEMETRY_DECODER_CC_H +#define GNSS_SDR_GLONASS_L1_CA_TELEMETRY_DECODER_CC_H + +#include +#include +#include +#include "GLONASS_L1_CA.h" +#include "concurrent_queue.h" +#include "gnss_satellite.h" +#include "glonass_gnav_navigation_message.h" +#include "glonass_gnav_ephemeris.h" +#include "glonass_gnav_almanac.h" +#include "glonass_gnav_utc_model.h" +#include "gnss_synchro.h" + + + +class glonass_l1_ca_telemetry_decoder_cc; + +typedef boost::shared_ptr glonass_l1_ca_telemetry_decoder_cc_sptr; + +glonass_l1_ca_telemetry_decoder_cc_sptr glonass_l1_ca_make_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump); + +/*! + * \brief This class implements a block that decodes the GNAV data defined in GLONASS ICD v5.1 + * \note Code added as part of GSoC 2017 program + * \see GLONASS ICD + * + */ +class glonass_l1_ca_telemetry_decoder_cc : public gr::block +{ +public: + ~glonass_l1_ca_telemetry_decoder_cc(); //!< Class destructor + void set_satellite(const Gnss_Satellite & satellite); //!< Set satellite PRN + void set_channel(int channel); //!< Set receiver's channel + + /*! + * \brief This is where all signal processing takes place + */ + int general_work (int noutput_items, gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + +private: + friend glonass_l1_ca_telemetry_decoder_cc_sptr + glonass_l1_ca_make_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump); + glonass_l1_ca_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump); + + void decode_string(double *symbols, int frame_length); + + //!< Help with coherent tracking + double d_preamble_time_samples; + + //!< Preamble decoding + unsigned short int d_preambles_bits[GLONASS_GNAV_PREAMBLE_LENGTH_BITS]; + int *d_preambles_symbols; + unsigned int d_samples_per_symbol; + int d_symbols_per_preamble; + + //!< Storage for incoming data + std::deque d_symbol_history; + + //!< Variables for internal functionality + long unsigned int d_sample_counter; //!< Sample counter as an index (1,2,3,..etc) indicating number of samples processed + long unsigned int d_preamble_index; //!< Index of sample number where preamble was found + unsigned int d_stat; //!< Status of decoder + bool d_flag_frame_sync; //!< Indicate when a frame sync is achieved + bool d_flag_parity; //!< Flag indicating when parity check was achieved (crc check) + bool d_flag_preamble; //!< Flag indicating when preamble was found + int d_CRC_error_counter; //!< Number of failed CRC operations + bool flag_TOW_set; //!< Indicates when time of week is set + double delta_t; //!< GPS-GLONASS time offset + + //!< Navigation Message variable + Glonass_Gnav_Navigation_Message d_nav; + + //!< Values to populate gnss synchronization structure + double d_TOW_at_current_symbol; + bool Flag_valid_word; + + //!< Satellite Information and logging capacity + Gnss_Satellite d_satellite; + int d_channel; + bool d_dump; + std::string d_dump_filename; + std::ofstream d_dump_file; +}; + +#endif diff --git a/src/algorithms/tracking/adapters/CMakeLists.txt b/src/algorithms/tracking/adapters/CMakeLists.txt index 13d5536b4..92ffd3f2f 100644 --- a/src/algorithms/tracking/adapters/CMakeLists.txt +++ b/src/algorithms/tracking/adapters/CMakeLists.txt @@ -33,6 +33,8 @@ set(TRACKING_ADAPTER_SOURCES gps_l1_ca_tcp_connector_tracking.cc galileo_e5a_dll_pll_tracking.cc gps_l2_m_dll_pll_tracking.cc + glonass_l1_ca_dll_pll_tracking.cc + glonass_l1_ca_dll_pll_c_aid_tracking.cc gps_l5i_dll_pll_tracking.cc ${OPT_TRACKING_ADAPTERS} ) diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc new file mode 100644 index 000000000..2322626e8 --- /dev/null +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc @@ -0,0 +1,237 @@ +/*! + * \file glonass_l1_ca_dll_pll_c_aid_tracking.cc + * \brief Interface of an adapter of a DLL+PLL tracking loop block + * for Glonass L1 C/A to a TrackingInterface + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "glonass_l1_ca_dll_pll_c_aid_tracking.h" +#include +#include "GLONASS_L1_CA.h" +#include "configuration_interface.h" + + +using google::LogMessage; + +GlonassL1CaDllPllCAidTracking::GlonassL1CaDllPllCAidTracking( + ConfigurationInterface* configuration, std::string role, + unsigned int in_streams, unsigned int out_streams) : + role_(role), in_streams_(in_streams), out_streams_(out_streams) +{ + DLOG(INFO) << "role " << role; + //################# CONFIGURATION PARAMETERS ######################## + int fs_in; + int vector_length; + int f_if; + bool dump; + std::string dump_filename; + std::string default_item_type = "gr_complex"; + float pll_bw_hz; + float pll_bw_narrow_hz; + float dll_bw_hz; + float dll_bw_narrow_hz; + float early_late_space_chips; + item_type_ = configuration->property(role + ".item_type", default_item_type); + //vector_length = configuration->property(role + ".vector_length", 2048); + int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); + fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + f_if = configuration->property(role + ".if", 0); + dump = configuration->property(role + ".dump", false); + pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); + dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); + pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 20.0); + dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 2.0); + int extend_correlation_ms; + extend_correlation_ms = configuration->property(role + ".extend_correlation_ms", 1); + + early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); + std::string default_dump_filename = "./track_ch"; + dump_filename = configuration->property(role + ".dump_filename", + default_dump_filename); //unused! + vector_length = std::round(fs_in / (GLONASS_L1_CA_CODE_RATE_HZ / GLONASS_L1_CA_CODE_LENGTH_CHIPS)); + + //################# MAKE TRACKING GNURadio object ################### + if (item_type_.compare("gr_complex") == 0) + { + item_size_ = sizeof(gr_complex); + tracking_cc = glonass_l1_ca_dll_pll_c_aid_make_tracking_cc( + f_if, + fs_in, + vector_length, + dump, + dump_filename, + pll_bw_hz, + dll_bw_hz, + pll_bw_narrow_hz, + dll_bw_narrow_hz, + extend_correlation_ms, + early_late_space_chips); + DLOG(INFO) << "tracking(" << tracking_cc->unique_id() << ")"; + } + else if(item_type_.compare("cshort") == 0) + { + item_size_ = sizeof(lv_16sc_t); + tracking_sc = glonass_l1_ca_dll_pll_c_aid_make_tracking_sc( + f_if, + fs_in, + vector_length, + dump, + dump_filename, + pll_bw_hz, + dll_bw_hz, + pll_bw_narrow_hz, + dll_bw_narrow_hz, + extend_correlation_ms, + early_late_space_chips); + DLOG(INFO) << "tracking(" << tracking_sc->unique_id() << ")"; + } + else + { + item_size_ = sizeof(gr_complex); + LOG(WARNING) << item_type_ << " unknown tracking item type."; + } + channel_ = 0; +} + + +GlonassL1CaDllPllCAidTracking::~GlonassL1CaDllPllCAidTracking() +{} + + +void GlonassL1CaDllPllCAidTracking::start_tracking() +{ + + if (item_type_.compare("gr_complex") == 0) + { + tracking_cc->start_tracking(); + } + else if (item_type_.compare("cshort") == 0) + { + tracking_sc->start_tracking(); + } + else + { + LOG(WARNING) << item_type_ << " unknown tracking item type"; + } +} + + +/* + * Set tracking channel unique ID + */ +void GlonassL1CaDllPllCAidTracking::set_channel(unsigned int channel) +{ + channel_ = channel; + + if (item_type_.compare("gr_complex") == 0) + { + tracking_cc->set_channel(channel); + } + else if (item_type_.compare("cshort") == 0) + { + tracking_sc->set_channel(channel); + } + else + { + LOG(WARNING) << item_type_ << " unknown tracking item type"; + } +} + + +void GlonassL1CaDllPllCAidTracking::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) +{ + if (item_type_.compare("gr_complex") == 0) + { + tracking_cc->set_gnss_synchro(p_gnss_synchro); + } + else if (item_type_.compare("cshort") == 0) + { + tracking_sc->set_gnss_synchro(p_gnss_synchro); + } + else + { + LOG(WARNING) << item_type_ << " unknown tracking item type"; + } +} + + +void GlonassL1CaDllPllCAidTracking::connect(gr::top_block_sptr top_block) +{ + if(top_block) { /* top_block is not null */}; + //nothing to connect, now the tracking uses gr_sync_decimator +} + + +void GlonassL1CaDllPllCAidTracking::disconnect(gr::top_block_sptr top_block) +{ + if(top_block) { /* top_block is not null */}; + //nothing to disconnect, now the tracking uses gr_sync_decimator +} + + +gr::basic_block_sptr GlonassL1CaDllPllCAidTracking::get_left_block() +{ + if (item_type_.compare("gr_complex") == 0) + { + return tracking_cc; + } + else if (item_type_.compare("cshort") == 0) + { + return tracking_sc; + } + else + { + LOG(WARNING) << item_type_ << " unknown tracking item type"; + return nullptr; + } +} + + +gr::basic_block_sptr GlonassL1CaDllPllCAidTracking::get_right_block() +{ + if (item_type_.compare("gr_complex") == 0) + { + return tracking_cc; + } + else if (item_type_.compare("cshort") == 0) + { + return tracking_sc; + } + else + { + LOG(WARNING) << item_type_ << " unknown tracking item type"; + return nullptr; + } +} diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h new file mode 100644 index 000000000..b62729a5f --- /dev/null +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h @@ -0,0 +1,109 @@ +/*! + * \file glonass_l1_ca_dll_pll_c_aid_tracking.h + * \brief Interface of an adapter of a DLL+PLL tracking loop block + * for Glonass L1 C/A to a TrackingInterface + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_H_ +#define GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_H_ + +#include +#include "tracking_interface.h" +#include "glonass_l1_ca_dll_pll_c_aid_tracking_cc.h" +#include "glonass_l1_ca_dll_pll_c_aid_tracking_sc.h" + + +class ConfigurationInterface; + +/*! + * \brief This class implements a code DLL + carrier PLL tracking loop + */ +class GlonassL1CaDllPllCAidTracking : public TrackingInterface +{ +public: + GlonassL1CaDllPllCAidTracking(ConfigurationInterface* configuration, + std::string role, + unsigned int in_streams, + unsigned int out_streams); + + virtual ~GlonassL1CaDllPllCAidTracking(); + + inline std::string role() override + { + return role_; + } + + //! Returns "GLONASS_L1_CA_DLL_PLL_C_Aid_Tracking" + inline std::string implementation() override + { + return "GLONASS_L1_CA_DLL_PLL_C_Aid_Tracking"; + } + + inline size_t item_size() override + { + return item_size_; + } + + void connect(gr::top_block_sptr top_block) override; + void disconnect(gr::top_block_sptr top_block) override; + gr::basic_block_sptr get_left_block() override; + gr::basic_block_sptr get_right_block() override; + + /*! + * \brief Set tracking channel unique ID + */ + void set_channel(unsigned int channel) override; + + /*! + * \brief Set acquisition/tracking common Gnss_Synchro object pointer + * to efficiently exchange synchronization data between acquisition and tracking blocks + */ + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; + + void start_tracking() override; + +private: + glonass_l1_ca_dll_pll_c_aid_tracking_cc_sptr tracking_cc; + glonass_l1_ca_dll_pll_c_aid_tracking_sc_sptr tracking_sc; + size_t item_size_; + std::string item_type_; + unsigned int channel_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; +}; + +#endif // GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_H_ diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.cc new file mode 100644 index 000000000..7035a1411 --- /dev/null +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.cc @@ -0,0 +1,149 @@ +/*! + * \file glonass_l1_ca_dll_pll_tracking.cc + * \brief Interface of an adapter of a DLL+PLL tracking loop block + * for Glonass L1 C/A to a TrackingInterface + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "glonass_l1_ca_dll_pll_tracking.h" +#include +#include "GLONASS_L1_CA.h" +#include "configuration_interface.h" + + +using google::LogMessage; + +GlonassL1CaDllPllTracking::GlonassL1CaDllPllTracking( + ConfigurationInterface* configuration, std::string role, + unsigned int in_streams, unsigned int out_streams) : + role_(role), in_streams_(in_streams), out_streams_(out_streams) +{ + DLOG(INFO) << "role " << role; + //################# CONFIGURATION PARAMETERS ######################## + int fs_in; + int vector_length; + int f_if; + bool dump; + std::string dump_filename; + std::string item_type; + std::string default_item_type = "gr_complex"; + float pll_bw_hz; + float dll_bw_hz; + float early_late_space_chips; + item_type = configuration->property(role + ".item_type", default_item_type); + int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); + fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + f_if = configuration->property(role + ".if", 0); + dump = configuration->property(role + ".dump", false); + pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); + dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); + early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); + std::string default_dump_filename = "./track_ch"; + dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); //unused! + vector_length = std::round(fs_in / (GLONASS_L1_CA_CODE_RATE_HZ / GLONASS_L1_CA_CODE_LENGTH_CHIPS)); + + //################# MAKE TRACKING GNURadio object ################### + if (item_type.compare("gr_complex") == 0) + { + item_size_ = sizeof(gr_complex); + tracking_ = glonass_l1_ca_dll_pll_make_tracking_cc( + f_if, + fs_in, + vector_length, + dump, + dump_filename, + pll_bw_hz, + dll_bw_hz, + early_late_space_chips); + } + else + { + item_size_ = sizeof(gr_complex); + LOG(WARNING) << item_type << " unknown tracking item type."; + } + channel_ = 0; + DLOG(INFO) << "tracking(" << tracking_->unique_id() << ")"; +} + + +GlonassL1CaDllPllTracking::~GlonassL1CaDllPllTracking() +{} + + +void GlonassL1CaDllPllTracking::start_tracking() +{ + tracking_->start_tracking(); +} + + +/* + * Set tracking channel unique ID + */ +void GlonassL1CaDllPllTracking::set_channel(unsigned int channel) +{ + channel_ = channel; + tracking_->set_channel(channel); +} + + +void GlonassL1CaDllPllTracking::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) +{ + tracking_->set_gnss_synchro(p_gnss_synchro); +} + + +void GlonassL1CaDllPllTracking::connect(gr::top_block_sptr top_block) +{ + if(top_block) { /* top_block is not null */}; + //nothing to connect, now the tracking uses gr_sync_decimator +} + + +void GlonassL1CaDllPllTracking::disconnect(gr::top_block_sptr top_block) +{ + if(top_block) { /* top_block is not null */}; + //nothing to disconnect, now the tracking uses gr_sync_decimator +} + + +gr::basic_block_sptr GlonassL1CaDllPllTracking::get_left_block() +{ + return tracking_; +} + + +gr::basic_block_sptr GlonassL1CaDllPllTracking::get_right_block() +{ + return tracking_; +} diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.h b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.h new file mode 100644 index 000000000..ba476948a --- /dev/null +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.h @@ -0,0 +1,105 @@ +/*! + * \file glonass_l1_ca_dll_pll_tracking.h + * \brief Interface of an adapter of a DLL+PLL tracking loop block + * for Glonass L1 C/A to a TrackingInterface + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GLONASS_L1_CA_DLL_PLL_TRACKING_H_ +#define GNSS_SDR_GLONASS_L1_CA_DLL_PLL_TRACKING_H_ + +#include +#include "tracking_interface.h" +#include "glonass_l1_ca_dll_pll_tracking_cc.h" + + +class ConfigurationInterface; + +/*! + * \brief This class implements a code DLL + carrier PLL tracking loop + */ +class GlonassL1CaDllPllTracking : public TrackingInterface +{ +public: + GlonassL1CaDllPllTracking(ConfigurationInterface* configuration, + std::string role, + unsigned int in_streams, + unsigned int out_streams); + + virtual ~GlonassL1CaDllPllTracking(); + + inline std::string role() override + { + return role_; + } + + //! Returns "GLONASS_L1_CA_DLL_PLL_Tracking" + inline std::string implementation() override + { + return "GLONASS_L1_CA_DLL_PLL_Tracking"; + } + + inline size_t item_size() override + { + return item_size_; + } + + void connect(gr::top_block_sptr top_block) override; + void disconnect(gr::top_block_sptr top_block) override; + gr::basic_block_sptr get_left_block() override; + gr::basic_block_sptr get_right_block() override; + + /*! + * \brief Set tracking channel unique ID + */ + void set_channel(unsigned int channel) override; + + /*! + * \brief Set acquisition/tracking common Gnss_Synchro object pointer + * to efficiently exchange synchronization data between acquisition and tracking blocks + */ + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; + + void start_tracking() override; + +private: + glonass_l1_ca_dll_pll_tracking_cc_sptr tracking_; + size_t item_size_; + unsigned int channel_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; +}; + +#endif // GNSS_SDR_GLONASS_L1_CA_DLL_PLL_TRACKING_H_ diff --git a/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt b/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt index 72370aada..6ad6bf2db 100644 --- a/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt @@ -35,7 +35,10 @@ set(TRACKING_GR_BLOCKS_SOURCES gps_l2_m_dll_pll_tracking_cc.cc gps_l5i_dll_pll_tracking_cc.cc gps_l1_ca_dll_pll_c_aid_tracking_cc.cc - gps_l1_ca_dll_pll_c_aid_tracking_sc.cc + gps_l1_ca_dll_pll_c_aid_tracking_sc.cc + glonass_l1_ca_dll_pll_tracking_cc.cc + glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc + glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc ${OPT_TRACKING_BLOCKS} ) diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc new file mode 100644 index 000000000..107334df5 --- /dev/null +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc @@ -0,0 +1,932 @@ +/*! + * \file glonass_l1_ca_dll_pll_c_aid_tracking_cc.h + * \brief Implementation of a code DLL + carrier PLL tracking block + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "glonass_l1_ca_dll_pll_c_aid_tracking_cc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "glonass_l1_signal_processing.h" +#include "tracking_discriminators.h" +#include "lock_detectors.h" +#include "GLONASS_L1_CA.h" +#include "control_message_factory.h" + + +/*! + * \todo Include in definition header file + */ +#define CN0_ESTIMATION_SAMPLES 10 +#define MINIMUM_VALID_CN0 25 +#define MAXIMUM_LOCK_FAIL_COUNTER 50 +#define CARRIER_LOCK_THRESHOLD 0.85 + + +using google::LogMessage; + +glonass_l1_ca_dll_pll_c_aid_tracking_cc_sptr +glonass_l1_ca_dll_pll_c_aid_make_tracking_cc( + long if_freq, + long fs_in, + unsigned int vector_length, + bool dump, + std::string dump_filename, + float pll_bw_hz, + float dll_bw_hz, + float pll_bw_narrow_hz, + float dll_bw_narrow_hz, + int extend_correlation_ms, + float early_late_space_chips) +{ + return glonass_l1_ca_dll_pll_c_aid_tracking_cc_sptr(new glonass_l1_ca_dll_pll_c_aid_tracking_cc(if_freq, + fs_in, vector_length, dump, dump_filename, pll_bw_hz, dll_bw_hz,pll_bw_narrow_hz, dll_bw_narrow_hz, extend_correlation_ms, early_late_space_chips)); +} + + +void glonass_l1_ca_dll_pll_c_aid_tracking_cc::forecast (int noutput_items, + gr_vector_int &ninput_items_required) +{ + if (noutput_items != 0) + { + ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call + } +} + + +void glonass_l1_ca_dll_pll_c_aid_tracking_cc::msg_handler_preamble_index(pmt::pmt_t msg) +{ + //pmt::print(msg); + DLOG(INFO) << "Extended correlation enabled for Tracking CH " << d_channel << ": Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN); + if (d_enable_extended_integration == false) //avoid re-setting preamble indicator + { + d_preamble_timestamp_s = pmt::to_double(msg); + d_enable_extended_integration = true; + d_preamble_synchronized = false; + } +} + + +glonass_l1_ca_dll_pll_c_aid_tracking_cc::glonass_l1_ca_dll_pll_c_aid_tracking_cc( + long if_freq, + long fs_in, + unsigned int vector_length, + bool dump, + std::string dump_filename, + float pll_bw_hz, + float dll_bw_hz, + float pll_bw_narrow_hz, + float dll_bw_narrow_hz, + int extend_correlation_ms, + float early_late_space_chips) : + gr::block("glonass_l1_ca_dll_pll_c_aid_tracking_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) +{ + // Telemetry bit synchronization message port input + this->message_port_register_in(pmt::mp("preamble_timestamp_s")); + + this->set_msg_handler(pmt::mp("preamble_timestamp_s"), + boost::bind(&glonass_l1_ca_dll_pll_c_aid_tracking_cc::msg_handler_preamble_index, this, _1)); + + this->message_port_register_out(pmt::mp("events")); + // initialize internal vars + d_dump = dump; + d_if_freq = if_freq; + d_fs_in = fs_in; + d_vector_length = vector_length; + d_dump_filename = dump_filename; + d_correlation_length_samples = static_cast(d_vector_length); + + // Initialize tracking ========================================== + d_pll_bw_hz = pll_bw_hz; + d_dll_bw_hz = dll_bw_hz; + d_pll_bw_narrow_hz = pll_bw_narrow_hz; + d_dll_bw_narrow_hz = dll_bw_narrow_hz; + d_extend_correlation_ms = extend_correlation_ms; + d_code_loop_filter.set_DLL_BW(d_dll_bw_hz); + d_carrier_loop_filter.set_params(10.0, d_pll_bw_hz, 2); + + // --- DLL variables -------------------------------------------------------- + d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips) + + // Initialization of local code replica + // Get space for a vector with the C/A code replica sampled 1x/chip + d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + + // correlator outputs (scalar) + d_n_correlator_taps = 3; // Early, Prompt, and Late + d_correlator_outs = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps*sizeof(gr_complex), volk_gnsssdr_get_alignment())); + for (int n = 0; n < d_n_correlator_taps; n++) + { + d_correlator_outs[n] = gr_complex(0,0); + } + d_local_code_shift_chips = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps*sizeof(float), volk_gnsssdr_get_alignment())); + // Set TAPs delay values [chips] + d_local_code_shift_chips[0] = - d_early_late_spc_chips; + d_local_code_shift_chips[1] = 0.0; + d_local_code_shift_chips[2] = d_early_late_spc_chips; + + multicorrelator_cpu.init(2 * d_correlation_length_samples, d_n_correlator_taps); + + //--- Perform initializations ------------------------------ + // define initial code frequency basis of NCO + d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ; + // define residual code phase (in chips) + d_rem_code_phase_samples = 0.0; + // define residual carrier phase + d_rem_carrier_phase_rad = 0.0; + + // sample synchronization + d_sample_counter = 0; //(from trk to tlm) + d_acq_sample_stamp = 0; + d_enable_tracking = false; + d_pull_in = false; + + // CN0 estimation and lock detector buffers + d_cn0_estimation_counter = 0; + d_Prompt_buffer = new gr_complex[CN0_ESTIMATION_SAMPLES]; + d_carrier_lock_test = 1; + d_CN0_SNV_dB_Hz = 0; + d_carrier_lock_fail_counter = 0; + d_carrier_lock_threshold = CARRIER_LOCK_THRESHOLD; + + systemName["R"] = std::string("Glonass"); + + set_relative_rate(1.0 / static_cast(d_vector_length)); + + d_acquisition_gnss_synchro = 0; + d_channel = 0; + d_acq_code_phase_samples = 0.0; + d_acq_carrier_doppler_hz = 0.0; + d_carrier_doppler_hz = 0.0; + d_code_error_filt_chips_Ti = 0.0; + d_acc_carrier_phase_cycles = 0.0; + d_code_phase_samples = 0.0; + + d_pll_to_dll_assist_secs_Ti = 0.0; + d_rem_code_phase_chips = 0.0; + d_code_phase_step_chips = 0.0; + d_carrier_phase_step_rad = 0.0; + d_enable_extended_integration = false; + d_preamble_synchronized = false; + d_rem_code_phase_integer_samples = 0; + d_code_error_chips_Ti = 0.0; + d_code_error_filt_chips_s = 0.0; + d_carr_phase_error_secs_Ti = 0.0; + d_preamble_timestamp_s = 0.0; + + d_carrier_frequency_hz = 0.0; + d_carrier_doppler_old_hz = 0.0; + + d_glonass_freq_ch = 0; + + //set_min_output_buffer((long int)300); +} + + +void glonass_l1_ca_dll_pll_c_aid_tracking_cc::start_tracking() +{ + /* + * correct the code phase according to the delay between acq and trk + */ + d_acq_code_phase_samples = d_acquisition_gnss_synchro->Acq_delay_samples; + d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; + d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; + + long int acq_trk_diff_samples; + double acq_trk_diff_seconds; + acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp);//-d_vector_length; + DLOG(INFO) << "Number of samples between Acquisition and Tracking =" << acq_trk_diff_samples; + acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in); + // Doppler effect + // Fd=(C/(C+Vr))*F + d_glonass_freq_ch = GLONASS_L1_CA_FREQ_HZ + (DFRQ1_GLO * static_cast(GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN))); + double radial_velocity = (d_glonass_freq_ch + d_acq_carrier_doppler_hz) / d_glonass_freq_ch; + // new chip and prn sequence periods based on acq Doppler + double T_chip_mod_seconds; + double T_prn_mod_seconds; + double T_prn_mod_samples; + d_code_freq_chips = radial_velocity * GLONASS_L1_CA_CODE_RATE_HZ; + d_code_phase_step_chips = static_cast(d_code_freq_chips) / static_cast(d_fs_in); + T_chip_mod_seconds = 1.0 / d_code_freq_chips; + T_prn_mod_seconds = T_chip_mod_seconds * GLONASS_L1_CA_CODE_LENGTH_CHIPS; + T_prn_mod_samples = T_prn_mod_seconds * static_cast(d_fs_in); + + d_correlation_length_samples = round(T_prn_mod_samples); + + double T_prn_true_seconds = GLONASS_L1_CA_CODE_LENGTH_CHIPS / GLONASS_L1_CA_CODE_RATE_HZ; + double T_prn_true_samples = T_prn_true_seconds * static_cast(d_fs_in); + double T_prn_diff_seconds = T_prn_true_seconds - T_prn_mod_seconds; + double N_prn_diff = acq_trk_diff_seconds / T_prn_true_seconds; + 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 * static_cast(d_fs_in)), T_prn_true_samples); + if (corrected_acq_phase_samples < 0) + { + corrected_acq_phase_samples = T_prn_mod_samples + corrected_acq_phase_samples; + } + delay_correction_samples = d_acq_code_phase_samples - corrected_acq_phase_samples; + + d_acq_code_phase_samples = corrected_acq_phase_samples; + + // d_carrier_doppler_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)); + // d_carrier_doppler_hz = d_acq_carrier_doppler_hz; + // d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); + d_carrier_frequency_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * static_cast(GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN))); + d_carrier_doppler_hz = d_acq_carrier_doppler_hz; + d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_frequency_hz / static_cast(d_fs_in); + + + // DLL/PLL filter initialization + d_carrier_loop_filter.initialize(d_carrier_frequency_hz); // The carrier loop filter implements the Doppler accumulator + d_code_loop_filter.initialize(); // initialize the code filter + + // generate local reference ALWAYS starting at chip 1 (1 sample per chip) + glonass_l1_ca_code_gen_complex(d_ca_code, 0); + + multicorrelator_cpu.set_local_code_and_taps(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); + for (int n = 0; n < d_n_correlator_taps; n++) + { + d_correlator_outs[n] = gr_complex(0,0); + } + + d_carrier_lock_fail_counter = 0; + d_rem_code_phase_samples = 0.0; + d_rem_carrier_phase_rad = 0.0; + d_rem_code_phase_chips = 0.0; + d_acc_carrier_phase_cycles = 0.0; + d_pll_to_dll_assist_secs_Ti = 0.0; + d_code_phase_samples = d_acq_code_phase_samples; + + std::string sys_ = &d_acquisition_gnss_synchro->System; + sys = sys_.substr(0,1); + + // DEBUG OUTPUT + std::cout << "Tracking start on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl; + LOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel; + + // enable tracking + d_pull_in = true; + d_enable_tracking = true; + d_enable_extended_integration = false; + d_preamble_synchronized = false; + LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz + << " Code Phase correction [samples]=" << delay_correction_samples + << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples; +} + + +glonass_l1_ca_dll_pll_c_aid_tracking_cc::~glonass_l1_ca_dll_pll_c_aid_tracking_cc() +{ + if (d_dump_file.is_open()) + { + try + { + d_dump_file.close(); + } + catch(const std::exception & ex) + { + LOG(WARNING) << "Exception in destructor " << ex.what(); + } + } + + if(d_dump) + { + if(d_channel == 0) + { + std::cout << "Writing .mat files ..."; + } + glonass_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile(); + if(d_channel == 0) + { + std::cout << " done." << std::endl; + } + } + + try + { + volk_gnsssdr_free(d_local_code_shift_chips); + volk_gnsssdr_free(d_correlator_outs); + volk_gnsssdr_free(d_ca_code); + delete[] d_Prompt_buffer; + multicorrelator_cpu.free(); + } + catch(const std::exception & ex) + { + LOG(WARNING) << "Exception in destructor " << ex.what(); + } +} + + +int glonass_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() +{ + // READ DUMP FILE + std::ifstream::pos_type size; + int number_of_double_vars = 11; + int number_of_float_vars = 5; + int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(unsigned int); + std::ifstream dump_file; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + } + catch(const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return 1; + } + // count number of epochs and rewind + long int num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + float * abs_E = new float [num_epoch]; + float * abs_P = new float [num_epoch]; + float * abs_L = new float [num_epoch]; + float * Prompt_I = new float [num_epoch]; + float * Prompt_Q = new float [num_epoch]; + unsigned long int * PRN_start_sample_count = new unsigned long int [num_epoch]; + double * acc_carrier_phase_rad = new double [num_epoch]; + double * carrier_doppler_hz = new double [num_epoch]; + double * code_freq_chips = new double [num_epoch]; + double * carr_error_hz = new double [num_epoch]; + double * carr_error_filt_hz = new double [num_epoch]; + double * code_error_chips = new double [num_epoch]; + double * code_error_filt_chips = new double [num_epoch]; + double * CN0_SNV_dB_Hz = new double [num_epoch]; + double * carrier_lock_test = new double [num_epoch]; + double * aux1 = new double [num_epoch]; + double * aux2 = new double [num_epoch]; + unsigned int * PRN = new unsigned int [num_epoch]; + + try + { + if (dump_file.is_open()) + { + for(long int i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_filt_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_filt_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&CN0_SNV_dB_Hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = d_dump_filename; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if(reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, acc_carrier_phase_rad, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_doppler_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_freq_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_freq_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_filt_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_filt_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, CN0_SNV_dB_Hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_lock_test", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_lock_test, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux1", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux1, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 0; +} + + +int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) +{ + // Block input data and block output stream pointers + const gr_complex* in = reinterpret_cast(input_items[0]); // PRN start block alignment + Gnss_Synchro **out = reinterpret_cast(&output_items[0]); + + // GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder + Gnss_Synchro current_synchro_data = Gnss_Synchro(); + + // process vars + double code_error_filt_secs_Ti = 0.0; + double CURRENT_INTEGRATION_TIME_S = 0.0; + double CORRECTED_INTEGRATION_TIME_S = 0.0; + + if (d_enable_tracking == true) + { + // Fill the acquisition data + current_synchro_data = *d_acquisition_gnss_synchro; + // Receiver signal alignment + if (d_pull_in == true) + { + int samples_offset; + 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_correlation_length_samples - fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_correlation_length_samples)); + samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); + current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; + d_sample_counter += samples_offset; // count for the processed samples + d_pull_in = false; + d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * samples_offset / GLONASS_TWO_PI; + current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_cycles * GLONASS_TWO_PI; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.fs=d_fs_in; + *out[0] = current_synchro_data; + consume_each(samples_offset); // shift input to perform alignment with local replica + return 1; + } + + // ################# CARRIER WIPEOFF AND CORRELATORS ############################## + // perform carrier wipe-off and compute Early, Prompt and Late correlation + multicorrelator_cpu.set_input_output_vectors(d_correlator_outs,in); + multicorrelator_cpu.Carrier_wipeoff_multicorrelator_resampler(d_rem_carrier_phase_rad, + d_carrier_phase_step_rad, + d_rem_code_phase_chips, + d_code_phase_step_chips, + d_correlation_length_samples); + + // ####### coherent intergration extension + // keep the last symbols + d_E_history.push_back(d_correlator_outs[0]); // save early output + d_P_history.push_back(d_correlator_outs[1]); // save prompt output + d_L_history.push_back(d_correlator_outs[2]); // save late output + + if (static_cast(d_P_history.size()) > d_extend_correlation_ms) + { + d_E_history.pop_front(); + d_P_history.pop_front(); + d_L_history.pop_front(); + } + + bool enable_dll_pll; + if (d_enable_extended_integration == true) + { + long int symbol_diff = round(1000.0 * ((static_cast(d_sample_counter) + d_rem_code_phase_samples) / static_cast(d_fs_in) - d_preamble_timestamp_s)); + if (symbol_diff > 0 and symbol_diff % d_extend_correlation_ms == 0) + { + // compute coherent integration and enable tracking loop + // perform coherent integration using correlator output history + // std::cout<<"##### RESET COHERENT INTEGRATION ####"<PRN) + << " pll_bw = " << d_pll_bw_hz << " [Hz], pll_narrow_bw = " << d_pll_bw_narrow_hz << " [Hz]" << std::endl + << " dll_bw = " << d_dll_bw_hz << " [Hz], dll_narrow_bw = " << d_dll_bw_narrow_hz << " [Hz]" << std::endl; + } + // UPDATE INTEGRATION TIME + CURRENT_INTEGRATION_TIME_S = static_cast(d_extend_correlation_ms) * GLONASS_L1_CA_CODE_PERIOD; + d_code_loop_filter.set_pdi(CURRENT_INTEGRATION_TIME_S); + enable_dll_pll = true; + } + else + { + if(d_preamble_synchronized == true) + { + // continue extended coherent correlation + // Compute the next buffer length based on the period of the PRN sequence and the code phase error estimation + double T_chip_seconds = 1.0 / d_code_freq_chips; + double T_prn_seconds = T_chip_seconds * GLONASS_L1_CA_CODE_LENGTH_CHIPS; + double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); + int K_prn_samples = round(T_prn_samples); + double K_T_prn_error_samples = K_prn_samples - T_prn_samples; + + d_rem_code_phase_samples = d_rem_code_phase_samples - K_T_prn_error_samples; + d_rem_code_phase_integer_samples = round(d_rem_code_phase_samples); // round to a discrete number of samples + d_correlation_length_samples = K_prn_samples + d_rem_code_phase_integer_samples; + d_rem_code_phase_samples = d_rem_code_phase_samples - d_rem_code_phase_integer_samples; + // code phase step (Code resampler phase increment per sample) [chips/sample] + d_code_phase_step_chips = d_code_freq_chips / static_cast(d_fs_in); + // remnant code phase [chips] + d_rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / static_cast(d_fs_in)); + d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + d_carrier_phase_step_rad * static_cast(d_correlation_length_samples), GLONASS_TWO_PI); + + // UPDATE ACCUMULATED CARRIER PHASE + CORRECTED_INTEGRATION_TIME_S = (static_cast(d_correlation_length_samples) / static_cast(d_fs_in)); + d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / GLONASS_TWO_PI; + + // disable tracking loop and inform telemetry decoder + enable_dll_pll = false; + } + else + { + // perform basic (1ms) correlation + // UPDATE INTEGRATION TIME + CURRENT_INTEGRATION_TIME_S = static_cast(d_correlation_length_samples) / static_cast(d_fs_in); + d_code_loop_filter.set_pdi(CURRENT_INTEGRATION_TIME_S); + enable_dll_pll = true; + } + } + } + else + { + // UPDATE INTEGRATION TIME + CURRENT_INTEGRATION_TIME_S = static_cast(d_correlation_length_samples) / static_cast(d_fs_in); + enable_dll_pll = true; + } + + if (enable_dll_pll == true) + { + // ################## PLL ########################################################## + // Update PLL discriminator [rads/Ti -> Secs/Ti] + d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(d_correlator_outs[1]) / GLONASS_TWO_PI; // prompt output + d_carrier_doppler_old_hz = d_carrier_doppler_hz; + // Carrier discriminator filter + // NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan + // Input [s/Ti] -> output [Hz] + d_carrier_doppler_hz = d_carrier_loop_filter.get_carrier_error(0.0, d_carr_phase_error_secs_Ti, CURRENT_INTEGRATION_TIME_S); + // PLL to DLL assistance [Secs/Ti] + d_pll_to_dll_assist_secs_Ti = (d_carrier_doppler_hz * CURRENT_INTEGRATION_TIME_S) / d_glonass_freq_ch; + // code Doppler frequency update + d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ + (((d_carrier_doppler_hz - d_carrier_doppler_old_hz) * GLONASS_L1_CA_CODE_RATE_HZ) / d_glonass_freq_ch); + + // ################## DLL ########################################################## + // DLL discriminator + d_code_error_chips_Ti = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2]); // [chips/Ti] //early and late + // Code discriminator filter + d_code_error_filt_chips_s = d_code_loop_filter.get_code_nco(d_code_error_chips_Ti); // input [chips/Ti] -> output [chips/second] + d_code_error_filt_chips_Ti = d_code_error_filt_chips_s * CURRENT_INTEGRATION_TIME_S; + code_error_filt_secs_Ti = d_code_error_filt_chips_Ti / d_code_freq_chips; // [s/Ti] + + // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### + // keep alignment parameters for the next input buffer + // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation + double T_chip_seconds = 1.0 / d_code_freq_chips; + double T_prn_seconds = T_chip_seconds * GLONASS_L1_CA_CODE_LENGTH_CHIPS; + double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); + double K_prn_samples = round(T_prn_samples); + double K_T_prn_error_samples = K_prn_samples - T_prn_samples; + + d_rem_code_phase_samples = d_rem_code_phase_samples - K_T_prn_error_samples + code_error_filt_secs_Ti * static_cast(d_fs_in); //(code_error_filt_secs_Ti + d_pll_to_dll_assist_secs_Ti) * static_cast(d_fs_in); + d_rem_code_phase_integer_samples = round(d_rem_code_phase_samples); // round to a discrete number of samples + d_correlation_length_samples = K_prn_samples + d_rem_code_phase_integer_samples; + d_rem_code_phase_samples = d_rem_code_phase_samples - d_rem_code_phase_integer_samples; + + //################### PLL COMMANDS ################################################# + //carrier phase step (NCO phase increment per sample) [rads/sample] + d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); + d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / GLONASS_TWO_PI; + // UPDATE ACCUMULATED CARRIER PHASE + CORRECTED_INTEGRATION_TIME_S = (static_cast(d_correlation_length_samples) / static_cast(d_fs_in)); + //remnant carrier phase [rad] + d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + GLONASS_TWO_PI * d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S, GLONASS_TWO_PI); + + //################### DLL COMMANDS ################################################# + //code phase step (Code resampler phase increment per sample) [chips/sample] + d_code_phase_step_chips = d_code_freq_chips / static_cast(d_fs_in); + //remnant code phase [chips] + d_rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / static_cast(d_fs_in)); + + // ####### CN0 ESTIMATION AND LOCK DETECTORS ####################################### + if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES) + { + // fill buffer with prompt correlator output values + d_Prompt_buffer[d_cn0_estimation_counter] = d_correlator_outs[1]; // prompt + d_cn0_estimation_counter++; + } + else + { + d_cn0_estimation_counter = 0; + // Code lock indicator + d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, GLONASS_L1_CA_CODE_LENGTH_CHIPS); + // Carrier lock indicator + d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES); + // Loss of lock detection + if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < MINIMUM_VALID_CN0) + { + d_carrier_lock_fail_counter++; + } + else + { + if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--; + } + if (d_carrier_lock_fail_counter > MAXIMUM_LOCK_FAIL_COUNTER) + { + std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; + LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; + this->message_port_pub(pmt::mp("events"), pmt::from_long(3));//3 -> loss of lock + d_carrier_lock_fail_counter = 0; + d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine + } + } + // ########### Output the tracking data to navigation and PVT ########## + current_synchro_data.Prompt_I = static_cast((d_correlator_outs[1]).real()); + current_synchro_data.Prompt_Q = static_cast((d_correlator_outs[1]).imag()); + current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; + current_synchro_data.Carrier_phase_rads = GLONASS_TWO_PI * d_acc_carrier_phase_cycles; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; + current_synchro_data.Flag_valid_symbol_output = true; + if (d_preamble_synchronized == true) + { + current_synchro_data.correlation_length_ms = d_extend_correlation_ms; + } + else + { + current_synchro_data.correlation_length_ms = 1; + } + } + else + { + current_synchro_data.Prompt_I = static_cast((d_correlator_outs[1]).real()); + current_synchro_data.Prompt_Q = static_cast((d_correlator_outs[1]).imag()); + current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; + current_synchro_data.Carrier_phase_rads = GLONASS_TWO_PI * d_acc_carrier_phase_cycles; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;// todo: project the carrier doppler + current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; + } + } + else + { + for (int n = 0; n < d_n_correlator_taps; n++) + { + d_correlator_outs[n] = gr_complex(0,0); + } + + current_synchro_data.System = {'R'}; + current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + } + //assign the GNURadio block output data + current_synchro_data.fs=d_fs_in; + *out[0] = current_synchro_data; + if(d_dump) + { + // MULTIPLEXED FILE RECORDING - Record results to file + float prompt_I; + float prompt_Q; + float tmp_E, tmp_P, tmp_L; + double tmp_double; + prompt_I = d_correlator_outs[1].real(); + prompt_Q = d_correlator_outs[1].imag(); + tmp_E = std::abs(d_correlator_outs[0]); + tmp_P = std::abs(d_correlator_outs[1]); + tmp_L = std::abs(d_correlator_outs[2]); + try + { + // EPR + d_dump_file.write(reinterpret_cast(&tmp_E), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_P), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_L), sizeof(float)); + // PROMPT I and Q (to analyze navigation symbols) + d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); + d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); + // PRN start sample stamp + //tmp_float=(float)d_sample_counter; + d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + // accumulated carrier phase + d_dump_file.write(reinterpret_cast(&d_acc_carrier_phase_cycles), sizeof(double)); + + // carrier and code frequency + double if_freq_carrier = d_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * static_cast(GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN))); + d_dump_file.write(reinterpret_cast(&if_freq_carrier), sizeof(double)); + d_dump_file.write(reinterpret_cast(&d_code_freq_chips), sizeof(double)); + + //PLL commands + d_dump_file.write(reinterpret_cast(&d_carr_phase_error_secs_Ti), sizeof(double)); + d_dump_file.write(reinterpret_cast(&d_carrier_doppler_hz), sizeof(double)); + + //DLL commands + d_dump_file.write(reinterpret_cast(&d_code_error_chips_Ti), sizeof(double)); + d_dump_file.write(reinterpret_cast(&d_code_error_filt_chips_Ti), sizeof(double)); + + // CN0 and carrier lock test + d_dump_file.write(reinterpret_cast(&d_CN0_SNV_dB_Hz), sizeof(double)); + d_dump_file.write(reinterpret_cast(&d_carrier_lock_test), sizeof(double)); + + // AUX vars (for debug purposes) + tmp_double = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = static_cast(d_sample_counter + d_correlation_length_samples); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + + // PRN + unsigned int prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + } + catch (const std::ifstream::failure* e) + { + LOG(WARNING) << "Exception writing trk dump file " << e->what(); + } + } + + consume_each(d_correlation_length_samples); // this is necessary in gr::block derivates + d_sample_counter += d_correlation_length_samples; //count for the processed samples + + return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false +} + + +void glonass_l1_ca_dll_pll_c_aid_tracking_cc::set_channel(unsigned int channel) +{ + d_channel = channel; + LOG(INFO) << "Tracking Channel set to " << d_channel; + // ############# ENABLE DATA FILE LOG ################# + if (d_dump == true) + { + if (d_dump_file.is_open() == false) + { + try + { + d_dump_filename.append(boost::lexical_cast(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); + LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str() << std::endl; + } + catch (const std::ifstream::failure* e) + { + LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e->what() << std::endl; + } + } + } +} + + + +void glonass_l1_ca_dll_pll_c_aid_tracking_cc::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) +{ + d_acquisition_gnss_synchro = p_gnss_synchro; +} diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h new file mode 100644 index 000000000..d928beb29 --- /dev/null +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h @@ -0,0 +1,209 @@ +/*! + * \file glonass_l1_ca_dll_pll_c_aid_tracking_cc.h + * \brief Implementation of a code DLL + carrier PLL tracking block + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_CC_H +#define GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_CC_H + +#include +#include +#include +#include +#include +#include +#include "gnss_synchro.h" +#include "tracking_2nd_DLL_filter.h" +#include "tracking_FLL_PLL_filter.h" +//#include "tracking_loop_filter.h" +#include "cpu_multicorrelator.h" + +class glonass_l1_ca_dll_pll_c_aid_tracking_cc; + +typedef boost::shared_ptr + glonass_l1_ca_dll_pll_c_aid_tracking_cc_sptr; + +glonass_l1_ca_dll_pll_c_aid_tracking_cc_sptr +glonass_l1_ca_dll_pll_c_aid_make_tracking_cc(long if_freq, + long fs_in, unsigned + int vector_length, + bool dump, + std::string dump_filename, + float pll_bw_hz, + float dll_bw_hz, + float pll_bw_narrow_hz, + float dll_bw_narrow_hz, + int extend_correlation_ms, + float early_late_space_chips); + + + +/*! + * \brief This class implements a DLL + PLL tracking loop block + */ +class glonass_l1_ca_dll_pll_c_aid_tracking_cc: public gr::block +{ +public: + ~glonass_l1_ca_dll_pll_c_aid_tracking_cc(); + + void set_channel(unsigned int channel); + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro); + void start_tracking(); + + int general_work (int noutput_items, gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + + void forecast (int noutput_items, gr_vector_int &ninput_items_required); + +private: + friend glonass_l1_ca_dll_pll_c_aid_tracking_cc_sptr + glonass_l1_ca_dll_pll_c_aid_make_tracking_cc(long if_freq, + long fs_in, unsigned + int vector_length, + bool dump, + std::string dump_filename, + float pll_bw_hz, + float dll_bw_hz, + float pll_bw_narrow_hz, + float dll_bw_narrow_hz, + int extend_correlation_ms, + float early_late_space_chips); + + glonass_l1_ca_dll_pll_c_aid_tracking_cc(long if_freq, + long fs_in, unsigned + int vector_length, + bool dump, + std::string dump_filename, + float pll_bw_hz, + float dll_bw_hz, + float pll_bw_narrow_hz, + float dll_bw_narrow_hz, + int extend_correlation_ms, + float early_late_space_chips); + + // tracking configuration vars + unsigned int d_vector_length; + bool d_dump; + + Gnss_Synchro* d_acquisition_gnss_synchro; + unsigned int d_channel; + + long d_if_freq; + long d_fs_in; + double d_glonass_freq_ch; + + double d_early_late_spc_chips; + int d_n_correlator_taps; + + gr_complex* d_ca_code; + float* d_local_code_shift_chips; + gr_complex* d_correlator_outs; + cpu_multicorrelator multicorrelator_cpu; + + // remaining code phase and carrier phase between tracking loops + double d_rem_code_phase_samples; + double d_rem_code_phase_chips; + double d_rem_carrier_phase_rad; + int d_rem_code_phase_integer_samples; + + // PLL and DLL filter library + //Tracking_2nd_DLL_filter d_code_loop_filter; + Tracking_2nd_DLL_filter d_code_loop_filter; + Tracking_FLL_PLL_filter d_carrier_loop_filter; + + // acquisition + double d_acq_code_phase_samples; + double d_acq_carrier_doppler_hz; + + // tracking vars + float d_dll_bw_hz; + float d_pll_bw_hz; + float d_dll_bw_narrow_hz; + float d_pll_bw_narrow_hz; + double d_code_freq_chips; + double d_code_phase_step_chips; + double d_carrier_doppler_hz; + double d_carrier_frequency_hz; + double d_carrier_doppler_old_hz; + double d_carrier_phase_step_rad; + double d_acc_carrier_phase_cycles; + double d_code_phase_samples; + double d_pll_to_dll_assist_secs_Ti; + double d_code_error_chips_Ti; + double d_code_error_filt_chips_s; + double d_code_error_filt_chips_Ti; + double d_carr_phase_error_secs_Ti; + + // symbol history to detect bit transition + std::deque d_E_history; + std::deque d_P_history; + std::deque d_L_history; + double d_preamble_timestamp_s; + int d_extend_correlation_ms; + bool d_enable_extended_integration; + bool d_preamble_synchronized; + void msg_handler_preamble_index(pmt::pmt_t msg); + + //Integration period in samples + int d_correlation_length_samples; + + //processing samples counters + unsigned long int d_sample_counter; + unsigned long int d_acq_sample_stamp; + + // CN0 estimation and lock detector + int d_cn0_estimation_counter; + gr_complex* d_Prompt_buffer; + double d_carrier_lock_test; + double d_CN0_SNV_dB_Hz; + double d_carrier_lock_threshold; + int d_carrier_lock_fail_counter; + + // control vars + bool d_enable_tracking; + bool d_pull_in; + + // file dump + std::string d_dump_filename; + std::ofstream d_dump_file; + + std::map systemName; + std::string sys; + + int save_matfile(); +}; + +#endif //GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_CC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc new file mode 100644 index 000000000..7cf86026f --- /dev/null +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc @@ -0,0 +1,923 @@ +/*! + * \file glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc + * \brief Implementation of a code DLL + carrier PLL tracking block + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "glonass_l1_ca_dll_pll_c_aid_tracking_sc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gnss_synchro.h" +#include "glonass_l1_signal_processing.h" +#include "tracking_discriminators.h" +#include "lock_detectors.h" +#include "GLONASS_L1_CA.h" +#include "control_message_factory.h" + + +/*! + * \todo Include in definition header file + */ +#define CN0_ESTIMATION_SAMPLES 10 +#define MINIMUM_VALID_CN0 25 +#define MAXIMUM_LOCK_FAIL_COUNTER 50 +#define CARRIER_LOCK_THRESHOLD 0.85 + + +using google::LogMessage; + +glonass_l1_ca_dll_pll_c_aid_tracking_sc_sptr +glonass_l1_ca_dll_pll_c_aid_make_tracking_sc( + long if_freq, + long fs_in, + unsigned int vector_length, + bool dump, + std::string dump_filename, + float pll_bw_hz, + float dll_bw_hz, + float pll_bw_narrow_hz, + float dll_bw_narrow_hz, + int extend_correlation_ms, + float early_late_space_chips) +{ + return glonass_l1_ca_dll_pll_c_aid_tracking_sc_sptr(new glonass_l1_ca_dll_pll_c_aid_tracking_sc(if_freq, + fs_in, vector_length, dump, dump_filename, pll_bw_hz, dll_bw_hz, pll_bw_narrow_hz, dll_bw_narrow_hz, extend_correlation_ms, early_late_space_chips)); +} + + + +void glonass_l1_ca_dll_pll_c_aid_tracking_sc::forecast (int noutput_items, + gr_vector_int &ninput_items_required) +{ + if (noutput_items != 0) + { + ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call + } +} + + +void glonass_l1_ca_dll_pll_c_aid_tracking_sc::msg_handler_preamble_index(pmt::pmt_t msg) +{ + //pmt::print(msg); + DLOG(INFO) << "Extended correlation enabled for Tracking CH " << d_channel << ": Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN); + if (d_enable_extended_integration == false) //avoid re-setting preamble indicator + { + d_preamble_timestamp_s = pmt::to_double(msg); + d_enable_extended_integration = true; + d_preamble_synchronized = false; + } +} + +glonass_l1_ca_dll_pll_c_aid_tracking_sc::glonass_l1_ca_dll_pll_c_aid_tracking_sc( + long if_freq, + long fs_in, + unsigned int vector_length, + bool dump, + std::string dump_filename, + float pll_bw_hz, + float dll_bw_hz, + float pll_bw_narrow_hz, + float dll_bw_narrow_hz, + int extend_correlation_ms, + float early_late_space_chips) : + gr::block("glonass_l1_ca_dll_pll_c_aid_tracking_sc", gr::io_signature::make(1, 1, sizeof(lv_16sc_t)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) +{ + // Telemetry bit synchronization message port input + this->message_port_register_in(pmt::mp("preamble_timestamp_s")); + this->set_msg_handler(pmt::mp("preamble_timestamp_s"), + boost::bind(&glonass_l1_ca_dll_pll_c_aid_tracking_sc::msg_handler_preamble_index, this, _1)); + this->message_port_register_out(pmt::mp("events")); + // initialize internal vars + d_dump = dump; + d_if_freq = if_freq; + d_fs_in = fs_in; + d_vector_length = vector_length; + d_dump_filename = dump_filename; + d_correlation_length_samples = static_cast(d_vector_length); + + // Initialize tracking ========================================== + d_pll_bw_hz = pll_bw_hz; + d_dll_bw_hz = dll_bw_hz; + d_pll_bw_narrow_hz = pll_bw_narrow_hz; + d_dll_bw_narrow_hz = dll_bw_narrow_hz; + d_code_loop_filter.set_DLL_BW(d_dll_bw_hz); + d_carrier_loop_filter.set_params(10.0, d_pll_bw_hz, 2); + d_extend_correlation_ms = extend_correlation_ms; + + // --- DLL variables -------------------------------------------------------- + d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips) + + // Initialization of local code replica + // Get space for a vector with the C/A code replica sampled 1x/chip + d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_ca_code_16sc = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); + + // correlator outputs (scalar) + d_n_correlator_taps = 3; // Early, Prompt, and Late + + d_correlator_outs_16sc = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps*sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); + for (int n = 0; n < d_n_correlator_taps; n++) + { + d_correlator_outs_16sc[n] = lv_cmake(0,0); + } + + d_local_code_shift_chips = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps*sizeof(float), volk_gnsssdr_get_alignment())); + // Set TAPs delay values [chips] + d_local_code_shift_chips[0] = - d_early_late_spc_chips; + d_local_code_shift_chips[1] = 0.0; + d_local_code_shift_chips[2] = d_early_late_spc_chips; + + multicorrelator_cpu_16sc.init(2 * d_correlation_length_samples, d_n_correlator_taps); + + //--- Perform initializations ------------------------------ + // define initial code frequency basis of NCO + d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ; + // define residual code phase (in chips) + d_rem_code_phase_samples = 0.0; + // define residual carrier phase + d_rem_carrier_phase_rad = 0.0; + + // sample synchronization + d_sample_counter = 0; //(from trk to tlm) + d_acq_sample_stamp = 0; + d_enable_tracking = false; + d_pull_in = false; + + // CN0 estimation and lock detector buffers + d_cn0_estimation_counter = 0; + d_Prompt_buffer = new gr_complex[CN0_ESTIMATION_SAMPLES]; + d_carrier_lock_test = 1; + d_CN0_SNV_dB_Hz = 0; + d_carrier_lock_fail_counter = 0; + d_carrier_lock_threshold = CARRIER_LOCK_THRESHOLD; + + systemName["R"] = std::string("Glonass"); + + set_relative_rate(1.0 / static_cast(d_vector_length)); + + d_acquisition_gnss_synchro = 0; + d_channel = 0; + d_acq_code_phase_samples = 0.0; + d_acq_carrier_doppler_hz = 0.0; + d_carrier_doppler_hz = 0.0; + d_acc_carrier_phase_cycles = 0.0; + d_code_phase_samples = 0.0; + d_enable_extended_integration = false; + d_preamble_synchronized = false; + d_rem_code_phase_integer_samples = 0; + d_code_error_chips_Ti = 0.0; + d_pll_to_dll_assist_secs_Ti = 0.0; + d_rem_code_phase_chips = 0.0; + d_code_phase_step_chips = 0.0; + d_carrier_phase_step_rad = 0.0; + d_code_error_filt_chips_s = 0.0; + d_code_error_filt_chips_Ti = 0.0; + d_preamble_timestamp_s = 0.0; + d_carr_phase_error_secs_Ti = 0.0; + + d_carrier_frequency_hz = 0.0; + d_carrier_doppler_old_hz = 0.0; + + d_glonass_freq_ch = 0; + //set_min_output_buffer((long int)300); +} + + +void glonass_l1_ca_dll_pll_c_aid_tracking_sc::start_tracking() +{ + /* + * correct the code phase according to the delay between acq and trk + */ + d_acq_code_phase_samples = d_acquisition_gnss_synchro->Acq_delay_samples; + d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; + d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; + + long int acq_trk_diff_samples; + double acq_trk_diff_seconds; + acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp);//-d_vector_length; + DLOG(INFO) << "Number of samples between Acquisition and Tracking =" << acq_trk_diff_samples; + acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in); + // Doppler effect + // Fd=(C/(C+Vr))*F + d_glonass_freq_ch = GLONASS_L1_CA_FREQ_HZ + (GLONASS_L1_CA_FREQ_HZ * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)); + double radial_velocity = (d_glonass_freq_ch + d_acq_carrier_doppler_hz) / d_glonass_freq_ch; + // new chip and prn sequence periods based on acq Doppler + double T_chip_mod_seconds; + double T_prn_mod_seconds; + double T_prn_mod_samples; + d_code_freq_chips = radial_velocity * GLONASS_L1_CA_CODE_RATE_HZ; + d_code_phase_step_chips = static_cast(d_code_freq_chips) / static_cast(d_fs_in); + T_chip_mod_seconds = 1.0 / d_code_freq_chips; + T_prn_mod_seconds = T_chip_mod_seconds * GLONASS_L1_CA_CODE_LENGTH_CHIPS; + T_prn_mod_samples = T_prn_mod_seconds * static_cast(d_fs_in); + + d_correlation_length_samples = round(T_prn_mod_samples); + + double T_prn_true_seconds = GLONASS_L1_CA_CODE_LENGTH_CHIPS / GLONASS_L1_CA_CODE_RATE_HZ; + double T_prn_true_samples = T_prn_true_seconds * static_cast(d_fs_in); + double T_prn_diff_seconds = T_prn_true_seconds - T_prn_mod_seconds; + double N_prn_diff = acq_trk_diff_seconds / T_prn_true_seconds; + 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 * static_cast(d_fs_in)), T_prn_true_samples); + if (corrected_acq_phase_samples < 0) + { + corrected_acq_phase_samples = T_prn_mod_samples + corrected_acq_phase_samples; + } + delay_correction_samples = d_acq_code_phase_samples - corrected_acq_phase_samples; + + d_acq_code_phase_samples = corrected_acq_phase_samples; + + d_carrier_frequency_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * static_cast(GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)));; + d_carrier_doppler_hz = d_acq_carrier_doppler_hz; + + d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_frequency_hz / static_cast(d_fs_in); + + // DLL/PLL filter initialization + d_carrier_loop_filter.initialize(d_carrier_frequency_hz); // The carrier loop filter implements the Doppler accumulator + d_code_loop_filter.initialize(); // initialize the code filter + + // generate local reference ALWAYS starting at chip 1 (1 sample per chip) + glonass_l1_ca_code_gen_complex(d_ca_code, 0); + volk_gnsssdr_32fc_convert_16ic(d_ca_code_16sc, d_ca_code, static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS)); + + multicorrelator_cpu_16sc.set_local_code_and_taps(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code_16sc, d_local_code_shift_chips); + for (int n = 0; n < d_n_correlator_taps; n++) + { + d_correlator_outs_16sc[n] = lv_16sc_t(0,0); + } + + d_carrier_lock_fail_counter = 0; + d_rem_code_phase_samples = 0.0; + d_rem_carrier_phase_rad = 0.0; + d_rem_code_phase_chips = 0.0; + d_acc_carrier_phase_cycles = 0.0; + d_pll_to_dll_assist_secs_Ti = 0.0; + d_code_phase_samples = d_acq_code_phase_samples; + + std::string sys_ = &d_acquisition_gnss_synchro->System; + sys = sys_.substr(0,1); + + // DEBUG OUTPUT + std::cout << "Tracking start on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl; + LOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel; + + // enable tracking + d_pull_in = true; + d_enable_tracking = true; + d_enable_extended_integration = true; + d_preamble_synchronized = true; + + LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz + << " Code Phase correction [samples]=" << delay_correction_samples + << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples; +} + + +int glonass_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() +{ + // READ DUMP FILE + std::ifstream::pos_type size; + int number_of_double_vars = 11; + int number_of_float_vars = 5; + int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(unsigned int); + std::ifstream dump_file; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + } + catch(const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return 1; + } + // count number of epochs and rewind + long int num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + float * abs_E = new float [num_epoch]; + float * abs_P = new float [num_epoch]; + float * abs_L = new float [num_epoch]; + float * Prompt_I = new float [num_epoch]; + float * Prompt_Q = new float [num_epoch]; + unsigned long int * PRN_start_sample_count = new unsigned long int [num_epoch]; + double * acc_carrier_phase_rad = new double [num_epoch]; + double * carrier_doppler_hz = new double [num_epoch]; + double * code_freq_chips = new double [num_epoch]; + double * carr_error_hz = new double [num_epoch]; + double * carr_error_filt_hz = new double [num_epoch]; + double * code_error_chips = new double [num_epoch]; + double * code_error_filt_chips = new double [num_epoch]; + double * CN0_SNV_dB_Hz = new double [num_epoch]; + double * carrier_lock_test = new double [num_epoch]; + double * aux1 = new double [num_epoch]; + double * aux2 = new double [num_epoch]; + unsigned int * PRN = new unsigned int [num_epoch]; + + try + { + if (dump_file.is_open()) + { + for(long int i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_filt_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_filt_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&CN0_SNV_dB_Hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = d_dump_filename; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if(reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, acc_carrier_phase_rad, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_doppler_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_freq_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_freq_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_filt_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_filt_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, CN0_SNV_dB_Hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_lock_test", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_lock_test, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux1", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux1, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 0; +} + + +glonass_l1_ca_dll_pll_c_aid_tracking_sc::~glonass_l1_ca_dll_pll_c_aid_tracking_sc() +{ + if (d_dump_file.is_open()) + { + try + { + d_dump_file.close(); + } + catch(const std::exception & ex) + { + LOG(WARNING) << "Exception in destructor " << ex.what(); + } + } + + if(d_dump) + { + if(d_channel == 0) + { + std::cout << "Writing .mat files ..."; + } + glonass_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile(); + if(d_channel == 0) + { + std::cout << " done." << std::endl; + } + } + + volk_gnsssdr_free(d_local_code_shift_chips); + volk_gnsssdr_free(d_ca_code); + volk_gnsssdr_free(d_ca_code_16sc); + volk_gnsssdr_free(d_correlator_outs_16sc); + + delete[] d_Prompt_buffer; + multicorrelator_cpu_16sc.free(); +} + + + +int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) +{ + // Block input data and block output stream pointers + const lv_16sc_t* in = reinterpret_cast(input_items[0]); // PRN start block alignment + Gnss_Synchro **out = reinterpret_cast(&output_items[0]); + + // GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder + Gnss_Synchro current_synchro_data = Gnss_Synchro(); + + // process vars + double code_error_filt_secs_Ti = 0.0; + double CURRENT_INTEGRATION_TIME_S = 0.0; + double CORRECTED_INTEGRATION_TIME_S = 0.0; + + if (d_enable_tracking == true) + { + // Fill the acquisition data + current_synchro_data = *d_acquisition_gnss_synchro; + // Receiver signal alignment + if (d_pull_in == true) + { + int samples_offset; + 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_correlation_length_samples - fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_correlation_length_samples)); + samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); + current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; + d_sample_counter += samples_offset; // count for the processed samples + d_pull_in = false; + d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * samples_offset / GLONASS_TWO_PI; + current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_cycles * GLONASS_TWO_PI; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.fs=d_fs_in; + *out[0] = current_synchro_data; + consume_each(samples_offset); // shift input to perform alignment with local replica + return 1; + } + + // ################# CARRIER WIPEOFF AND CORRELATORS ############################## + // perform carrier wipe-off and compute Early, Prompt and Late correlation + multicorrelator_cpu_16sc.set_input_output_vectors(d_correlator_outs_16sc, in); + multicorrelator_cpu_16sc.Carrier_wipeoff_multicorrelator_resampler(d_rem_carrier_phase_rad, + d_carrier_phase_step_rad, + d_rem_code_phase_chips, + d_code_phase_step_chips, + d_correlation_length_samples); + + // ####### coherent intergration extension + // keep the last symbols + d_E_history.push_back(d_correlator_outs_16sc[0]); // save early output + d_P_history.push_back(d_correlator_outs_16sc[1]); // save prompt output + d_L_history.push_back(d_correlator_outs_16sc[2]); // save late output + + if (static_cast(d_P_history.size()) > d_extend_correlation_ms) + { + d_E_history.pop_front(); + d_P_history.pop_front(); + d_L_history.pop_front(); + } + + bool enable_dll_pll; + if (d_enable_extended_integration == true) + { + long int symbol_diff = round(1000.0 * ((static_cast(d_sample_counter) + d_rem_code_phase_samples) / static_cast(d_fs_in) - d_preamble_timestamp_s)); + if (symbol_diff > 0 and symbol_diff % d_extend_correlation_ms == 0) + { + // compute coherent integration and enable tracking loop + // perform coherent integration using correlator output history + // std::cout<<"##### RESET COHERENT INTEGRATION ####"<PRN) + << " pll_bw = " << d_pll_bw_hz << " [Hz], pll_narrow_bw = " << d_pll_bw_narrow_hz << " [Hz]" << std::endl + << " dll_bw = " << d_dll_bw_hz << " [Hz], dll_narrow_bw = " << d_dll_bw_narrow_hz << " [Hz]" << std::endl; + } + // UPDATE INTEGRATION TIME + CURRENT_INTEGRATION_TIME_S = static_cast(d_extend_correlation_ms) * GLONASS_L1_CA_CODE_PERIOD; + enable_dll_pll = true; + } + else + { + if(d_preamble_synchronized == true) + { + // continue extended coherent correlation + // Compute the next buffer length based on the period of the PRN sequence and the code phase error estimation + double T_chip_seconds = 1.0 / d_code_freq_chips; + double T_prn_seconds = T_chip_seconds * GLONASS_L1_CA_CODE_LENGTH_CHIPS; + double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); + int K_prn_samples = round(T_prn_samples); + double K_T_prn_error_samples = K_prn_samples - T_prn_samples; + + d_rem_code_phase_samples = d_rem_code_phase_samples - K_T_prn_error_samples; + d_rem_code_phase_integer_samples = round(d_rem_code_phase_samples); // round to a discrete number of samples + d_correlation_length_samples = K_prn_samples + d_rem_code_phase_integer_samples; + d_rem_code_phase_samples = d_rem_code_phase_samples - d_rem_code_phase_integer_samples; + // code phase step (Code resampler phase increment per sample) [chips/sample] + d_code_phase_step_chips = d_code_freq_chips / static_cast(d_fs_in); + // remnant code phase [chips] + d_rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / static_cast(d_fs_in)); + d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + d_carrier_phase_step_rad * static_cast(d_correlation_length_samples), GLONASS_TWO_PI); + + // UPDATE ACCUMULATED CARRIER PHASE + CORRECTED_INTEGRATION_TIME_S = (static_cast(d_correlation_length_samples) / static_cast(d_fs_in)); + d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / GLONASS_TWO_PI; + + // disable tracking loop and inform telemetry decoder + enable_dll_pll = false; + } + else + { + // perform basic (1ms) correlation + // UPDATE INTEGRATION TIME + CURRENT_INTEGRATION_TIME_S = static_cast(d_correlation_length_samples) / static_cast(d_fs_in); + enable_dll_pll = true; + } + } + } + else + { + // UPDATE INTEGRATION TIME + CURRENT_INTEGRATION_TIME_S = static_cast(d_correlation_length_samples) / static_cast(d_fs_in); + enable_dll_pll = true; + } + + if (enable_dll_pll == true) + { + // ################## PLL ########################################################## + // Update PLL discriminator [rads/Ti -> Secs/Ti] + d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(std::complex(d_correlator_outs_16sc[1].real(),d_correlator_outs_16sc[1].imag())) / GLONASS_TWO_PI; //prompt output + d_carrier_doppler_old_hz = d_carrier_doppler_hz; + // Carrier discriminator filter + // NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan + // Input [s/Ti] -> output [Hz] + d_carrier_doppler_hz = d_carrier_loop_filter.get_carrier_error(0.0, d_carr_phase_error_secs_Ti, CURRENT_INTEGRATION_TIME_S); + // PLL to DLL assistance [Secs/Ti] + d_pll_to_dll_assist_secs_Ti = (d_carrier_doppler_hz * CURRENT_INTEGRATION_TIME_S) / d_glonass_freq_ch; + // code Doppler frequency update + d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ + (((d_carrier_doppler_hz - d_carrier_doppler_old_hz) * GLONASS_L1_CA_CODE_RATE_HZ) / d_glonass_freq_ch); + + // ################## DLL ########################################################## + // DLL discriminator + d_code_error_chips_Ti = dll_nc_e_minus_l_normalized(std::complex(d_correlator_outs_16sc[0].real(),d_correlator_outs_16sc[0].imag()), std::complex(d_correlator_outs_16sc[2].real(),d_correlator_outs_16sc[2].imag())); // [chips/Ti] //early and late + // Code discriminator filter + d_code_error_filt_chips_s = d_code_loop_filter.get_code_nco(d_code_error_chips_Ti); // input [chips/Ti] -> output [chips/second] + d_code_error_filt_chips_Ti = d_code_error_filt_chips_s * CURRENT_INTEGRATION_TIME_S; + code_error_filt_secs_Ti = d_code_error_filt_chips_Ti / d_code_freq_chips; // [s/Ti] + + // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### + // keep alignment parameters for the next input buffer + // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation + double T_chip_seconds = 1.0 / d_code_freq_chips; + double T_prn_seconds = T_chip_seconds * GLONASS_L1_CA_CODE_LENGTH_CHIPS; + double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); + double K_prn_samples = round(T_prn_samples); + double K_T_prn_error_samples = K_prn_samples - T_prn_samples; + + d_rem_code_phase_samples = d_rem_code_phase_samples - K_T_prn_error_samples + code_error_filt_secs_Ti * static_cast(d_fs_in); //(code_error_filt_secs_Ti + d_pll_to_dll_assist_secs_Ti) * static_cast(d_fs_in); + d_rem_code_phase_integer_samples = round(d_rem_code_phase_samples); // round to a discrete number of samples + d_correlation_length_samples = K_prn_samples + d_rem_code_phase_integer_samples; + d_rem_code_phase_samples = d_rem_code_phase_samples - d_rem_code_phase_integer_samples; + + //################### PLL COMMANDS ################################################# + //carrier phase step (NCO phase increment per sample) [rads/sample] + d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); + d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / GLONASS_TWO_PI; + // UPDATE ACCUMULATED CARRIER PHASE + CORRECTED_INTEGRATION_TIME_S = (static_cast(d_correlation_length_samples) / static_cast(d_fs_in)); + //remnant carrier phase [rad] + d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + GLONASS_TWO_PI * d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S, GLONASS_TWO_PI); + + //################### DLL COMMANDS ################################################# + //code phase step (Code resampler phase increment per sample) [chips/sample] + d_code_phase_step_chips = d_code_freq_chips / static_cast(d_fs_in); + //remnant code phase [chips] + d_rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / static_cast(d_fs_in)); + + // ####### CN0 ESTIMATION AND LOCK DETECTORS ####################################### + if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES) + { + // fill buffer with prompt correlator output values + d_Prompt_buffer[d_cn0_estimation_counter] = lv_cmake(static_cast(d_correlator_outs_16sc[1].real()), static_cast(d_correlator_outs_16sc[1].imag()) ); // prompt + d_cn0_estimation_counter++; + } + else + { + d_cn0_estimation_counter = 0; + // Code lock indicator + d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, GLONASS_L1_CA_CODE_LENGTH_CHIPS); + // Carrier lock indicator + d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES); + // Loss of lock detection + if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < MINIMUM_VALID_CN0) + { + d_carrier_lock_fail_counter++; + } + else + { + if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--; + } + if (d_carrier_lock_fail_counter > MAXIMUM_LOCK_FAIL_COUNTER) + { + std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; + LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; + this->message_port_pub(pmt::mp("events"), pmt::from_long(3));//3 -> loss of lock + d_carrier_lock_fail_counter = 0; + d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine + } + } + // ########### Output the tracking data to navigation and PVT ########## + current_synchro_data.Prompt_I = static_cast((d_correlator_outs_16sc[1]).real()); + current_synchro_data.Prompt_Q = static_cast((d_correlator_outs_16sc[1]).imag()); + // Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!) + current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; + current_synchro_data.Carrier_phase_rads = GLONASS_TWO_PI * d_acc_carrier_phase_cycles; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; + current_synchro_data.Flag_valid_symbol_output = true; + if (d_preamble_synchronized == true) + { + current_synchro_data.correlation_length_ms = d_extend_correlation_ms; + } + else + { + current_synchro_data.correlation_length_ms = 1; + } + } + else + { + current_synchro_data.Prompt_I = static_cast((d_correlator_outs_16sc[1]).real()); + current_synchro_data.Prompt_Q = static_cast((d_correlator_outs_16sc[1]).imag()); + current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; + current_synchro_data.Carrier_phase_rads = GLONASS_TWO_PI * d_acc_carrier_phase_cycles; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;// todo: project the carrier doppler + current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; + } + } + else + { + for (int n = 0; n < d_n_correlator_taps; n++) + { + d_correlator_outs_16sc[n] = lv_cmake(0,0); + } + + current_synchro_data.System = {'R'}; + current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + } + current_synchro_data.fs=d_fs_in; + *out[0] = current_synchro_data; + if(d_dump) + { + // MULTIPLEXED FILE RECORDING - Record results to file + float prompt_I; + float prompt_Q; + float tmp_E, tmp_P, tmp_L; + double tmp_double; + prompt_I = d_correlator_outs_16sc[1].real(); + prompt_Q = d_correlator_outs_16sc[1].imag(); + tmp_E = std::abs(std::complex(d_correlator_outs_16sc[0].real(),d_correlator_outs_16sc[0].imag())); + tmp_P = std::abs(std::complex(d_correlator_outs_16sc[1].real(),d_correlator_outs_16sc[1].imag())); + tmp_L = std::abs(std::complex(d_correlator_outs_16sc[2].real(),d_correlator_outs_16sc[2].imag())); + try + { + // EPR + d_dump_file.write(reinterpret_cast(&tmp_E), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_P), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_L), sizeof(float)); + // PROMPT I and Q (to analyze navigation symbols) + d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); + d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); + // PRN start sample stamp + //tmp_float=(float)d_sample_counter; + d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + // accumulated carrier phase + d_dump_file.write(reinterpret_cast(&d_acc_carrier_phase_cycles), sizeof(double)); + + // carrier and code frequency + d_dump_file.write(reinterpret_cast(&d_carrier_doppler_hz), sizeof(double)); + d_dump_file.write(reinterpret_cast(&d_code_freq_chips), sizeof(double)); + + //PLL commands + d_dump_file.write(reinterpret_cast(&d_carr_phase_error_secs_Ti), sizeof(double)); + d_dump_file.write(reinterpret_cast(&d_carrier_doppler_hz), sizeof(double)); + + //DLL commands + d_dump_file.write(reinterpret_cast(&d_code_error_chips_Ti), sizeof(double)); + d_dump_file.write(reinterpret_cast(&d_code_error_filt_chips_Ti), sizeof(double)); + + // CN0 and carrier lock test + d_dump_file.write(reinterpret_cast(&d_CN0_SNV_dB_Hz), sizeof(double)); + d_dump_file.write(reinterpret_cast(&d_carrier_lock_test), sizeof(double)); + + // AUX vars (for debug purposes) + tmp_double = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = static_cast(d_sample_counter + d_correlation_length_samples); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + + // PRN + unsigned int prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + } + catch (const std::ifstream::failure* e) + { + LOG(WARNING) << "Exception writing trk dump file " << e->what(); + } + } + + consume_each(d_correlation_length_samples); // this is necessary in gr::block derivates + d_sample_counter += d_correlation_length_samples; //count for the processed samples + + return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false +} + + +void glonass_l1_ca_dll_pll_c_aid_tracking_sc::set_channel(unsigned int channel) +{ + d_channel = channel; + LOG(INFO) << "Tracking Channel set to " << d_channel; + // ############# ENABLE DATA FILE LOG ################# + if (d_dump == true) + { + if (d_dump_file.is_open() == false) + { + try + { + d_dump_filename.append(boost::lexical_cast(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); + LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str() << std::endl; + } + catch (const std::ifstream::failure* e) + { + LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e->what() << std::endl; + } + } + } +} + + +void glonass_l1_ca_dll_pll_c_aid_tracking_sc::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) +{ + d_acquisition_gnss_synchro = p_gnss_synchro; +} diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h new file mode 100644 index 000000000..e9424f9c7 --- /dev/null +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h @@ -0,0 +1,212 @@ +/*! + * \file glonass_l1_ca_dll_pll_c_aid_tracking_sc.h + * \brief Implementation of a code DLL + carrier PLL tracking block + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_SC_H +#define GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_SC_H + +#include +#include +#include +#include +#include +#include +#include +#include "glonass_l1_signal_processing.h" +#include "gnss_synchro.h" +#include "tracking_2nd_DLL_filter.h" +#include "tracking_FLL_PLL_filter.h" +#include "cpu_multicorrelator_16sc.h" + +class glonass_l1_ca_dll_pll_c_aid_tracking_sc; + +typedef boost::shared_ptr + glonass_l1_ca_dll_pll_c_aid_tracking_sc_sptr; + +glonass_l1_ca_dll_pll_c_aid_tracking_sc_sptr +glonass_l1_ca_dll_pll_c_aid_make_tracking_sc(long if_freq, + long fs_in, unsigned + int vector_length, + bool dump, + std::string dump_filename, + float pll_bw_hz, + float dll_bw_hz, + float pll_bw_narrow_hz, + float dll_bw_narrow_hz, + int extend_correlation_ms, + float early_late_space_chips); + + + +/*! + * \brief This class implements a DLL + PLL tracking loop block + */ +class glonass_l1_ca_dll_pll_c_aid_tracking_sc: public gr::block +{ +public: + ~glonass_l1_ca_dll_pll_c_aid_tracking_sc(); + + void set_channel(unsigned int channel); + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro); + void start_tracking(); + + int general_work (int noutput_items, gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + + void forecast (int noutput_items, gr_vector_int &ninput_items_required); + +private: + friend glonass_l1_ca_dll_pll_c_aid_tracking_sc_sptr + glonass_l1_ca_dll_pll_c_aid_make_tracking_sc(long if_freq, + long fs_in, unsigned + int vector_length, + bool dump, + std::string dump_filename, + float pll_bw_hz, + float dll_bw_hz, + float pll_bw_narrow_hz, + float dll_bw_narrow_hz, + int extend_correlation_ms, + float early_late_space_chips); + + glonass_l1_ca_dll_pll_c_aid_tracking_sc(long if_freq, + long fs_in, unsigned + int vector_length, + bool dump, + std::string dump_filename, + float pll_bw_hz, + float dll_bw_hz, + float pll_bw_narrow_hz, + float dll_bw_narrow_hz, + int extend_correlation_ms, + float early_late_space_chips); + + // tracking configuration vars + unsigned int d_vector_length; + bool d_dump; + + Gnss_Synchro* d_acquisition_gnss_synchro; + unsigned int d_channel; + + long d_if_freq; + long d_fs_in; + long d_glonass_freq_ch; + + double d_early_late_spc_chips; + int d_n_correlator_taps; + + gr_complex* d_ca_code; + lv_16sc_t* d_ca_code_16sc; + float* d_local_code_shift_chips; + //gr_complex* d_correlator_outs; + lv_16sc_t* d_correlator_outs_16sc; + //cpu_multicorrelator multicorrelator_cpu; + cpu_multicorrelator_16sc multicorrelator_cpu_16sc; + + // remaining code phase and carrier phase between tracking loops + double d_rem_code_phase_samples; + double d_rem_code_phase_chips; + double d_rem_carrier_phase_rad; + int d_rem_code_phase_integer_samples; + + // PLL and DLL filter library + Tracking_2nd_DLL_filter d_code_loop_filter; + Tracking_FLL_PLL_filter d_carrier_loop_filter; + + // acquisition + double d_acq_code_phase_samples; + double d_acq_carrier_doppler_hz; + + // tracking vars + float d_dll_bw_hz; + float d_pll_bw_hz; + float d_dll_bw_narrow_hz; + float d_pll_bw_narrow_hz; + double d_code_freq_chips; + double d_code_phase_step_chips; + double d_carrier_doppler_hz; + double d_carrier_frequency_hz; + double d_carrier_doppler_old_hz; + double d_carrier_phase_step_rad; + double d_acc_carrier_phase_cycles; + double d_code_phase_samples; + double d_pll_to_dll_assist_secs_Ti; + double d_carr_phase_error_secs_Ti; + double d_code_error_chips_Ti; + double d_preamble_timestamp_s; + int d_extend_correlation_ms; + bool d_enable_extended_integration; + bool d_preamble_synchronized; + double d_code_error_filt_chips_s; + double d_code_error_filt_chips_Ti; + void msg_handler_preamble_index(pmt::pmt_t msg); + + // symbol history to detect bit transition + std::deque d_E_history; + std::deque d_P_history; + std::deque d_L_history; + + //Integration period in samples + int d_correlation_length_samples; + + //processing samples counters + unsigned long int d_sample_counter; + unsigned long int d_acq_sample_stamp; + + // CN0 estimation and lock detector + int d_cn0_estimation_counter; + gr_complex* d_Prompt_buffer; + double d_carrier_lock_test; + double d_CN0_SNV_dB_Hz; + double d_carrier_lock_threshold; + int d_carrier_lock_fail_counter; + + // control vars + bool d_enable_tracking; + bool d_pull_in; + + // file dump + std::string d_dump_filename; + std::ofstream d_dump_file; + + std::map systemName; + std::string sys; + + int save_matfile(); +}; + +#endif //GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_SC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc new file mode 100644 index 000000000..c2b22a832 --- /dev/null +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc @@ -0,0 +1,775 @@ +/*! + * \file glonass_l1_ca_dll_pll_tracking_cc.cc + * \brief Implementation of a code DLL + carrier PLL tracking block + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "glonass_l1_ca_dll_pll_tracking_cc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "glonass_l1_signal_processing.h" +#include "tracking_discriminators.h" +#include "lock_detectors.h" +#include "GLONASS_L1_CA.h" +#include "control_message_factory.h" + + +#define CN0_ESTIMATION_SAMPLES 10 +#define MINIMUM_VALID_CN0 25 +#define MAXIMUM_LOCK_FAIL_COUNTER 50 +#define CARRIER_LOCK_THRESHOLD 0.85 + + +using google::LogMessage; + +glonass_l1_ca_dll_pll_tracking_cc_sptr +glonass_l1_ca_dll_pll_make_tracking_cc( + long if_freq, + long fs_in, + unsigned int vector_length, + bool dump, + std::string dump_filename, + float pll_bw_hz, + float dll_bw_hz, + float early_late_space_chips) +{ + return glonass_l1_ca_dll_pll_tracking_cc_sptr(new Glonass_L1_Ca_Dll_Pll_Tracking_cc(if_freq, + fs_in, vector_length, dump, dump_filename, pll_bw_hz, dll_bw_hz, early_late_space_chips)); +} + + + +void Glonass_L1_Ca_Dll_Pll_Tracking_cc::forecast (int noutput_items, + gr_vector_int &ninput_items_required) +{ + if (noutput_items != 0) + { + ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call + } +} + + + +Glonass_L1_Ca_Dll_Pll_Tracking_cc::Glonass_L1_Ca_Dll_Pll_Tracking_cc( + long if_freq, + long fs_in, + unsigned int vector_length, + bool dump, + std::string dump_filename, + float pll_bw_hz, + float dll_bw_hz, + float early_late_space_chips) : + gr::block("Glonass_L1_Ca_Dll_Pll_Tracking_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) +{ + // Telemetry bit synchronization message port input + this->message_port_register_in(pmt::mp("preamble_timestamp_s")); + this->message_port_register_out(pmt::mp("events")); + + // initialize internal vars + d_dump = dump; + d_if_freq = if_freq; + d_fs_in = fs_in; + d_vector_length = vector_length; + d_dump_filename = dump_filename; + + d_current_prn_length_samples = static_cast(d_vector_length); + + // Initialize tracking ========================================== + d_code_loop_filter.set_DLL_BW(dll_bw_hz); + d_carrier_loop_filter.set_PLL_BW(pll_bw_hz); + + //--- DLL variables -------------------------------------------------------- + d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips) + + // Initialization of local code replica + // Get space for a vector with the C/A code replica sampled 1x/chip + d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + + // correlator outputs (scalar) + d_n_correlator_taps = 3; // Early, Prompt, and Late + d_correlator_outs = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps*sizeof(gr_complex), volk_gnsssdr_get_alignment())); + for (int n = 0; n < d_n_correlator_taps; n++) + { + d_correlator_outs[n] = gr_complex(0,0); + } + d_local_code_shift_chips = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps*sizeof(float), volk_gnsssdr_get_alignment())); + // Set TAPs delay values [chips] + d_local_code_shift_chips[0] = - d_early_late_spc_chips; + d_local_code_shift_chips[1] = 0.0; + d_local_code_shift_chips[2] = d_early_late_spc_chips; + + multicorrelator_cpu.init(2 * d_current_prn_length_samples, d_n_correlator_taps); + + //--- Perform initializations ------------------------------ + // define initial code frequency basis of NCO + d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ; + // define residual code phase (in chips) + d_rem_code_phase_samples = 0.0; + // define residual carrier phase + d_rem_carr_phase_rad = 0.0; + + // sample synchronization + d_sample_counter = 0; + //d_sample_counter_seconds = 0; + d_acq_sample_stamp = 0; + + d_enable_tracking = false; + d_pull_in = false; + + // CN0 estimation and lock detector buffers + d_cn0_estimation_counter = 0; + d_Prompt_buffer = new gr_complex[CN0_ESTIMATION_SAMPLES]; + d_carrier_lock_test = 1; + d_CN0_SNV_dB_Hz = 0; + d_carrier_lock_fail_counter = 0; + d_carrier_lock_threshold = CARRIER_LOCK_THRESHOLD; + + systemName["R"] = std::string("Glonass"); + + d_acquisition_gnss_synchro = 0; + d_channel = 0; + d_acq_code_phase_samples = 0.0; + d_acq_carrier_doppler_hz = 0.0; + d_carrier_doppler_hz = 0.0; + d_carrier_doppler_phase_step_rad = 0.0; + d_carrier_frequency_hz = 0.0; + d_acc_carrier_phase_rad = 0.0; + d_code_phase_samples = 0.0; + d_rem_code_phase_chips = 0.0; + d_code_phase_step_chips = 0.0; + d_carrier_phase_step_rad = 0.0; + + d_glonass_freq_ch = 0; + + set_relative_rate(1.0 / static_cast(d_vector_length)); +} + + +void Glonass_L1_Ca_Dll_Pll_Tracking_cc::start_tracking() +{ + /* + * correct the code phase according to the delay between acq and trk + */ + d_acq_code_phase_samples = d_acquisition_gnss_synchro->Acq_delay_samples; + d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; + d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; + + long int acq_trk_diff_samples; + double acq_trk_diff_seconds; + acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; + DLOG(INFO) << "Number of samples between Acquisition and Tracking =" << acq_trk_diff_samples; + acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in); + // Doppler effect + // Fd=(C/(C+Vr))*F + d_glonass_freq_ch = GLONASS_L1_CA_FREQ_HZ + (DFRQ1_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)); + double radial_velocity = (d_glonass_freq_ch + d_acq_carrier_doppler_hz) / d_glonass_freq_ch; + // new chip and prn sequence periods based on acq Doppler + double T_chip_mod_seconds; + double T_prn_mod_seconds; + double T_prn_mod_samples; + d_code_freq_chips = radial_velocity * GLONASS_L1_CA_CODE_RATE_HZ; + d_code_phase_step_chips = static_cast(d_code_freq_chips) / static_cast(d_fs_in); + T_chip_mod_seconds = 1/d_code_freq_chips; + T_prn_mod_seconds = T_chip_mod_seconds * GLONASS_L1_CA_CODE_LENGTH_CHIPS; + T_prn_mod_samples = T_prn_mod_seconds * static_cast(d_fs_in); + + d_current_prn_length_samples = round(T_prn_mod_samples); + + double T_prn_true_seconds = GLONASS_L1_CA_CODE_LENGTH_CHIPS / GLONASS_L1_CA_CODE_RATE_HZ; + double T_prn_true_samples = T_prn_true_seconds * static_cast(d_fs_in); + double T_prn_diff_seconds = T_prn_true_seconds - T_prn_mod_seconds; + double N_prn_diff = acq_trk_diff_seconds / T_prn_true_seconds; + 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 * static_cast(d_fs_in)), T_prn_true_samples); + if (corrected_acq_phase_samples < 0) + { + corrected_acq_phase_samples = T_prn_mod_samples + corrected_acq_phase_samples; + } + delay_correction_samples = d_acq_code_phase_samples - corrected_acq_phase_samples; + + d_acq_code_phase_samples = corrected_acq_phase_samples; + + d_carrier_frequency_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)); + d_carrier_doppler_hz = d_acq_carrier_doppler_hz; + d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_frequency_hz / static_cast(d_fs_in); + d_carrier_doppler_phase_step_rad = GLONASS_TWO_PI * (d_carrier_doppler_hz) / static_cast(d_fs_in); + + // DLL/PLL filter initialization + d_carrier_loop_filter.initialize(); // initialize the carrier filter + d_code_loop_filter.initialize(); // initialize the code filter + + // generate local reference ALWAYS starting at chip 1 (1 sample per chip) + glonass_l1_ca_code_gen_complex(d_ca_code, 0); + + multicorrelator_cpu.set_local_code_and_taps(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); + for (int n = 0; n < d_n_correlator_taps; n++) + { + d_correlator_outs[n] = gr_complex(0,0); + } + + d_carrier_lock_fail_counter = 0; + d_rem_code_phase_samples = 0; + d_rem_carr_phase_rad = 0.0; + d_rem_code_phase_chips = 0.0; + d_acc_carrier_phase_rad = 0.0; + + d_code_phase_samples = d_acq_code_phase_samples; + + std::string sys_ = &d_acquisition_gnss_synchro->System; + sys = sys_.substr(0,1); + + // DEBUG OUTPUT + std::cout << "Tracking of GLONASS L1 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl; + LOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel; + + // enable tracking + d_pull_in = true; + d_enable_tracking = true; + + LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_frequency_hz + << " Code Phase correction [samples]=" << delay_correction_samples + << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples; +} + + +Glonass_L1_Ca_Dll_Pll_Tracking_cc::~Glonass_L1_Ca_Dll_Pll_Tracking_cc() +{ + if (d_dump_file.is_open()) + { + try + { + d_dump_file.close(); + } + catch(const std::exception & ex) + { + LOG(WARNING) << "Exception in destructor " << ex.what(); + } + } + if(d_dump) + { + if(d_channel == 0) + { + std::cout << "Writing .mat files ..."; + } + Glonass_L1_Ca_Dll_Pll_Tracking_cc::save_matfile(); + if(d_channel == 0) + { + std::cout << " done." << std::endl; + } + } + try + { + volk_gnsssdr_free(d_local_code_shift_chips); + volk_gnsssdr_free(d_correlator_outs); + volk_gnsssdr_free(d_ca_code); + delete[] d_Prompt_buffer; + multicorrelator_cpu.free(); + } + catch(const std::exception & ex) + { + LOG(WARNING) << "Exception in destructor " << ex.what(); + } +} + + +int Glonass_L1_Ca_Dll_Pll_Tracking_cc::save_matfile() +{ + // READ DUMP FILE + std::ifstream::pos_type size; + int number_of_double_vars = 11; + int number_of_float_vars = 5; + int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(unsigned int); + std::ifstream dump_file; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + } + catch(const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return 1; + } + // count number of epochs and rewind + long int num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + float * abs_E = new float [num_epoch]; + float * abs_P = new float [num_epoch]; + float * abs_L = new float [num_epoch]; + float * Prompt_I = new float [num_epoch]; + float * Prompt_Q = new float [num_epoch]; + unsigned long int * PRN_start_sample_count = new unsigned long int [num_epoch]; + double * acc_carrier_phase_rad = new double [num_epoch]; + double * carrier_doppler_hz = new double [num_epoch]; + double * code_freq_chips = new double [num_epoch]; + double * carr_error_hz = new double [num_epoch]; + double * carr_error_filt_hz = new double [num_epoch]; + double * code_error_chips = new double [num_epoch]; + double * code_error_filt_chips = new double [num_epoch]; + double * CN0_SNV_dB_Hz = new double [num_epoch]; + double * carrier_lock_test = new double [num_epoch]; + double * aux1 = new double [num_epoch]; + double * aux2 = new double [num_epoch]; + unsigned int * PRN = new unsigned int [num_epoch]; + + try + { + if (dump_file.is_open()) + { + for(long int i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_filt_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_filt_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&CN0_SNV_dB_Hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = d_dump_filename; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if(reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, acc_carrier_phase_rad, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_doppler_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_freq_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_freq_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_filt_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_filt_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, CN0_SNV_dB_Hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_lock_test", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_lock_test, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux1", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux1, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 0; +} + + +int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) +{ + // process vars + double carr_error_hz = 0.0; + double carr_error_filt_hz = 0.0; + double code_error_chips = 0.0; + double code_error_filt_chips = 0.0; + + // Block input data and block output stream pointers + const gr_complex* in = reinterpret_cast(input_items[0]); // PRN start block alignment + Gnss_Synchro **out = reinterpret_cast(&output_items[0]); + + // GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder + Gnss_Synchro current_synchro_data = Gnss_Synchro(); + + if (d_enable_tracking == true) + { + // Fill the acquisition data + current_synchro_data = *d_acquisition_gnss_synchro; + // Receiver signal alignment + if (d_pull_in == true) + { + int samples_offset; + 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_current_prn_length_samples - fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_current_prn_length_samples)); + samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); + current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; + d_sample_counter = d_sample_counter + samples_offset; // count for the processed samples + d_pull_in = false; + // take into account the carrier cycles accumulated in the pull in signal alignment + d_acc_carrier_phase_rad -= d_carrier_doppler_phase_step_rad * samples_offset; + current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.fs = d_fs_in; + current_synchro_data.correlation_length_ms = 1; + *out[0] = current_synchro_data; + consume_each(samples_offset); // shift input to perform alignment with local replica + return 1; + } + + // ################# CARRIER WIPEOFF AND CORRELATORS ############################## + // perform carrier wipe-off and compute Early, Prompt and Late correlation + multicorrelator_cpu.set_input_output_vectors(d_correlator_outs, in); + multicorrelator_cpu.Carrier_wipeoff_multicorrelator_resampler(d_rem_carr_phase_rad, + d_carrier_phase_step_rad, + d_rem_code_phase_chips, + d_code_phase_step_chips, + d_current_prn_length_samples); + + // ################## PLL ########################################################## + // PLL discriminator + // Update PLL discriminator [rads/Ti -> Secs/Ti] + carr_error_hz = pll_cloop_two_quadrant_atan(d_correlator_outs[1]) / GLONASS_TWO_PI; // prompt output + // Carrier discriminator filter + carr_error_filt_hz = d_carrier_loop_filter.get_carrier_nco(carr_error_hz); + // New carrier Doppler frequency estimation + d_carrier_frequency_hz += carr_error_filt_hz; + d_carrier_doppler_hz += carr_error_filt_hz; + d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GLONASS_L1_CA_CODE_RATE_HZ) / d_glonass_freq_ch); + + // ################## DLL ########################################################## + // DLL discriminator + code_error_chips = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2]); // [chips/Ti] //early and late + // Code discriminator filter + code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips); // [chips/second] + double T_chip_seconds = 1.0 / static_cast(d_code_freq_chips); + double T_prn_seconds = T_chip_seconds * GLONASS_L1_CA_CODE_LENGTH_CHIPS; + double code_error_filt_secs = (T_prn_seconds * code_error_filt_chips*T_chip_seconds); //[seconds] + //double code_error_filt_secs = (GPS_L1_CA_CODE_PERIOD * code_error_filt_chips) / GLONASS_L1_CA_CODE_RATE_HZ; // [seconds] + + // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### + // keep alignment parameters for the next input buffer + // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation + //double T_chip_seconds = 1.0 / static_cast(d_code_freq_chips); + //double T_prn_seconds = T_chip_seconds * GLONASS_L1_CA_CODE_LENGTH_CHIPS; + double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); + double K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * static_cast(d_fs_in); + d_current_prn_length_samples = round(K_blk_samples); // round to a discrete number of samples + + //################### PLL COMMANDS ################################################# + // carrier phase step (NCO phase increment per sample) [rads/sample] + d_carrier_doppler_phase_step_rad = GLONASS_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); + d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_frequency_hz / static_cast(d_fs_in); + // remnant carrier phase to prevent overflow in the code NCO + d_rem_carr_phase_rad = d_rem_carr_phase_rad + d_carrier_phase_step_rad * d_current_prn_length_samples; + d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, GLONASS_TWO_PI); + // carrier phase accumulator + d_acc_carrier_phase_rad -= d_carrier_doppler_phase_step_rad * d_current_prn_length_samples; + + //################### DLL COMMANDS ################################################# + // code phase step (Code resampler phase increment per sample) [chips/sample] + d_code_phase_step_chips = d_code_freq_chips / static_cast(d_fs_in); + // remnant code phase [chips] + d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; // rounding error < 1 sample + d_rem_code_phase_chips = d_code_freq_chips * (d_rem_code_phase_samples / static_cast(d_fs_in)); + + // ####### CN0 ESTIMATION AND LOCK DETECTORS ###### + if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES) + { + // fill buffer with prompt correlator output values + d_Prompt_buffer[d_cn0_estimation_counter] = d_correlator_outs[1]; //prompt + d_cn0_estimation_counter++; + } + else + { + d_cn0_estimation_counter = 0; + // Code lock indicator + d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, GLONASS_L1_CA_CODE_LENGTH_CHIPS); + // Carrier lock indicator + d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES); + // Loss of lock detection + if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < MINIMUM_VALID_CN0) + { + d_carrier_lock_fail_counter++; + } + else + { + if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--; + } + if (d_carrier_lock_fail_counter > MAXIMUM_LOCK_FAIL_COUNTER) + { + std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; + LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; + this->message_port_pub(pmt::mp("events"), pmt::from_long(3)); // 3 -> loss of lock + d_carrier_lock_fail_counter = 0; + d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine + } + } + // ########### Output the tracking data to navigation and PVT ########## + current_synchro_data.Prompt_I = static_cast((d_correlator_outs[1]).real()); + current_synchro_data.Prompt_Q = static_cast((d_correlator_outs[1]).imag()); + current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples; + current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; + current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; + current_synchro_data.Flag_valid_symbol_output = true; + current_synchro_data.correlation_length_ms = 1; + } + else + { + for (int n = 0; n < d_n_correlator_taps; n++) + { + d_correlator_outs[n] = gr_complex(0,0); + } + + current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples; + current_synchro_data.System = {'R'}; + current_synchro_data.correlation_length_ms = 1; + } + + //assign the GNURadio block output data + current_synchro_data.fs = d_fs_in; + *out[0] = current_synchro_data; + if(d_dump) + { + // MULTIPLEXED FILE RECORDING - Record results to file + float prompt_I; + float prompt_Q; + float tmp_E, tmp_P, tmp_L; + double tmp_double; + unsigned long int tmp_long; + prompt_I = d_correlator_outs[1].real(); + prompt_Q = d_correlator_outs[1].imag(); + tmp_E = std::abs(d_correlator_outs[0]); + tmp_P = std::abs(d_correlator_outs[1]); + tmp_L = std::abs(d_correlator_outs[2]); + try + { + // EPR + d_dump_file.write(reinterpret_cast(&tmp_E), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_P), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_L), sizeof(float)); + // PROMPT I and Q (to analyze navigation symbols) + d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); + d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); + // PRN start sample stamp + tmp_long = d_sample_counter + d_current_prn_length_samples; + d_dump_file.write(reinterpret_cast(&tmp_long), sizeof(unsigned long int)); + // accumulated carrier phase + d_dump_file.write(reinterpret_cast(&d_acc_carrier_phase_rad), sizeof(double)); + + // carrier and code frequency + d_dump_file.write(reinterpret_cast(&d_carrier_frequency_hz), sizeof(double)); + d_dump_file.write(reinterpret_cast(&d_code_freq_chips), sizeof(double)); + + // PLL commands + d_dump_file.write(reinterpret_cast(&carr_error_hz), sizeof(double)); + d_dump_file.write(reinterpret_cast(&carr_error_filt_hz), sizeof(double)); + + // DLL commands + d_dump_file.write(reinterpret_cast(&code_error_chips), sizeof(double)); + d_dump_file.write(reinterpret_cast(&code_error_filt_chips), sizeof(double)); + + // CN0 and carrier lock test + d_dump_file.write(reinterpret_cast(&d_CN0_SNV_dB_Hz), sizeof(double)); + d_dump_file.write(reinterpret_cast(&d_carrier_lock_test), sizeof(double)); + + // AUX vars (for debug purposes) + tmp_double = d_rem_code_phase_samples; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = static_cast(d_sample_counter); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + + // PRN + unsigned int prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "Exception writing trk dump file " << e.what(); + } + } + + consume_each(d_current_prn_length_samples); // this is necessary in gr::block derivates + 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 +} + + + +void Glonass_L1_Ca_Dll_Pll_Tracking_cc::set_channel(unsigned int channel) +{ + d_channel = channel; + LOG(INFO) << "Tracking Channel set to " << d_channel; + // ############# ENABLE DATA FILE LOG ################# + if (d_dump == true) + { + if (d_dump_file.is_open() == false) + { + try + { + d_dump_filename.append(boost::lexical_cast(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); + LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str(); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); + } + } + } +} + + +void Glonass_L1_Ca_Dll_Pll_Tracking_cc::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) +{ + d_acquisition_gnss_synchro = p_gnss_synchro; +} diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h new file mode 100644 index 000000000..641c6f04e --- /dev/null +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h @@ -0,0 +1,177 @@ +/*! + * \file glonass_l1_ca_dll_pll_tracking_cc.h + * \brief Implementation of a code DLL + carrier PLL tracking block + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GLONASS_L1_CA_DLL_PLL_TRACKING_CC_H +#define GNSS_SDR_GLONASS_L1_CA_DLL_PLL_TRACKING_CC_H + +#include +#include +#include +#include +#include "gnss_synchro.h" +#include "tracking_2nd_DLL_filter.h" +#include "tracking_2nd_PLL_filter.h" +#include "cpu_multicorrelator.h" + +class Glonass_L1_Ca_Dll_Pll_Tracking_cc; + +typedef boost::shared_ptr + glonass_l1_ca_dll_pll_tracking_cc_sptr; + +glonass_l1_ca_dll_pll_tracking_cc_sptr +glonass_l1_ca_dll_pll_make_tracking_cc(long if_freq, + long fs_in, unsigned + int vector_length, + bool dump, + std::string dump_filename, + float pll_bw_hz, + float dll_bw_hz, + float early_late_space_chips); + + + +/*! + * \brief This class implements a DLL + PLL tracking loop block + */ +class Glonass_L1_Ca_Dll_Pll_Tracking_cc: public gr::block +{ +public: + ~Glonass_L1_Ca_Dll_Pll_Tracking_cc(); + + void set_channel(unsigned int channel); + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro); + void start_tracking(); + + int general_work (int noutput_items, gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + + void forecast (int noutput_items, gr_vector_int &ninput_items_required); + +private: + friend glonass_l1_ca_dll_pll_tracking_cc_sptr + glonass_l1_ca_dll_pll_make_tracking_cc(long if_freq, + long fs_in, unsigned + int vector_length, + bool dump, + std::string dump_filename, + float pll_bw_hz, + float dll_bw_hz, + float early_late_space_chips); + + Glonass_L1_Ca_Dll_Pll_Tracking_cc(long if_freq, + long fs_in, unsigned + int vector_length, + bool dump, + std::string dump_filename, + float pll_bw_hz, + float dll_bw_hz, + float early_late_space_chips); + + // tracking configuration vars + unsigned int d_vector_length; + bool d_dump; + + Gnss_Synchro* d_acquisition_gnss_synchro; + unsigned int d_channel; + + long d_if_freq; + long d_fs_in; + long d_glonass_freq_ch; + + double d_early_late_spc_chips; + + // remaining code phase and carrier phase between tracking loops + double d_rem_code_phase_samples; + double d_rem_code_phase_chips; + double d_rem_carr_phase_rad; + + // PLL and DLL filter library + Tracking_2nd_DLL_filter d_code_loop_filter; + Tracking_2nd_PLL_filter d_carrier_loop_filter; + + // acquisition + double d_acq_code_phase_samples; + double d_acq_carrier_doppler_hz; + // correlator + int d_n_correlator_taps; + gr_complex* d_ca_code; + float* d_local_code_shift_chips; + gr_complex* d_correlator_outs; + cpu_multicorrelator multicorrelator_cpu; + + + // tracking vars + double d_code_freq_chips; + double d_code_phase_step_chips; + double d_carrier_doppler_hz; + double d_carrier_doppler_phase_step_rad; + double d_carrier_frequency_hz; + double d_carrier_phase_step_rad; + double d_acc_carrier_phase_rad; + double d_code_phase_samples; + + //PRN period in samples + int d_current_prn_length_samples; + + //processing samples counters + unsigned long int d_sample_counter; + unsigned long int d_acq_sample_stamp; + + // CN0 estimation and lock detector + int d_cn0_estimation_counter; + gr_complex* d_Prompt_buffer; + double d_carrier_lock_test; + double d_CN0_SNV_dB_Hz; + double d_carrier_lock_threshold; + int d_carrier_lock_fail_counter; + + // control vars + bool d_enable_tracking; + bool d_pull_in; + + // file dump + std::string d_dump_filename; + std::ofstream d_dump_file; + + std::map systemName; + std::string sys; + + int save_matfile(); +}; + +#endif //GNSS_SDR_GLONASS_L1_CA_DLL_PLL_TRACKING_CC_H diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 855b192a3..ac72a0549 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -53,7 +53,6 @@ #include "two_bit_packed_file_signal_source.h" #include "labsat_signal_source.h" #include "channel.h" - #include "signal_conditioner.h" #include "array_signal_conditioner.h" #include "byte_to_short.h" @@ -82,6 +81,7 @@ #include "galileo_e1_pcps_cccwsr_ambiguous_acquisition.h" #include "galileo_e1_pcps_quicksync_ambiguous_acquisition.h" #include "galileo_e5a_noncoherent_iq_acquisition_caf.h" +#include "glonass_l1_ca_pcps_acquisition.h" #include "gps_l1_ca_dll_pll_tracking.h" #include "gps_l1_ca_dll_pll_c_aid_tracking.h" #include "gps_l1_ca_tcp_connector_tracking.h" @@ -89,12 +89,15 @@ #include "galileo_e1_tcp_connector_tracking.h" #include "galileo_e5a_dll_pll_tracking.h" #include "gps_l2_m_dll_pll_tracking.h" +#include "glonass_l1_ca_dll_pll_tracking.h" +#include "glonass_l1_ca_dll_pll_c_aid_tracking.h" #include "gps_l5i_dll_pll_tracking.h" #include "gps_l1_ca_telemetry_decoder.h" #include "gps_l2c_telemetry_decoder.h" #include "gps_l5_telemetry_decoder.h" #include "galileo_e1b_telemetry_decoder.h" #include "galileo_e5a_telemetry_decoder.h" +#include "glonass_l1_ca_telemetry_decoder.h" #include "sbas_l1_telemetry_decoder.h" #include "hybrid_observables.h" #include "rtklib_pvt.h" @@ -232,7 +235,6 @@ std::unique_ptr GNSSBlockFactory::GetSignalConditioner( } - std::unique_ptr GNSSBlockFactory::GetObservables(std::shared_ptr configuration) { std::string default_implementation = "Hybrid_Observables"; @@ -243,11 +245,11 @@ std::unique_ptr GNSSBlockFactory::GetObservables(std::shared unsigned int GPS_channels = configuration->property("Channels_1C.count", 0); GPS_channels += configuration->property("Channels_2S.count", 0); GPS_channels += configuration->property("Channels_L5.count", 0); - return GetBlock(configuration, "Observables", implementation, Galileo_channels + GPS_channels, Galileo_channels + GPS_channels); + unsigned int Glonass_channels = configuration->property("Channels_1G.count", 0); + return GetBlock(configuration, "Observables", implementation, Galileo_channels + GPS_channels + Glonass_channels, Galileo_channels + GPS_channels + Glonass_channels); } - std::unique_ptr GNSSBlockFactory::GetPVT(std::shared_ptr configuration) { std::string default_implementation = "RTKLIB_PVT"; @@ -258,7 +260,8 @@ std::unique_ptr GNSSBlockFactory::GetPVT(std::shared_ptrproperty("Channels_1C.count", 0); GPS_channels += configuration->property("Channels_2S.count", 0); GPS_channels += configuration->property("Channels_L5.count", 0); - return GetBlock(configuration, "PVT", implementation, Galileo_channels + GPS_channels, 0); + unsigned int Glonass_channels = configuration->property("Channels_1G.count", 0); + return GetBlock(configuration, "PVT", implementation, Galileo_channels + GPS_channels + Glonass_channels, 0); } @@ -330,13 +333,13 @@ std::unique_ptr GNSSBlockFactory::GetChannel_1C( return channel_; } + //********* GPS L2C (M) CHANNEL ***************** std::unique_ptr GNSSBlockFactory::GetChannel_2S( std::shared_ptr configuration, std::string acq, std::string trk, std::string tlm, int channel, gr::msg_queue::sptr queue) { - LOG(INFO) << "Instantiating Channel " << channel << " with Acquisition Implementation: " << acq << ", Tracking Implementation: " << trk << ", Telemetry Decoder implementation: " << tlm; std::string aux = configuration->property("Acquisition_2S" + boost::lexical_cast(channel) + ".implementation", std::string("W")); @@ -395,6 +398,7 @@ std::unique_ptr GNSSBlockFactory::GetChannel_2S( return channel_; } + //********* GALILEO E1 B CHANNEL ***************** std::unique_ptr GNSSBlockFactory::GetChannel_1B( std::shared_ptr configuration, @@ -462,6 +466,7 @@ std::unique_ptr GNSSBlockFactory::GetChannel_1B( return channel_; } + //********* GALILEO E5a CHANNEL ***************** std::unique_ptr GNSSBlockFactory::GetChannel_5X( std::shared_ptr configuration, @@ -529,6 +534,76 @@ std::unique_ptr GNSSBlockFactory::GetChannel_5X( return channel_; } + +//********* GLONASS L1 C/A CHANNEL ***************** +std::unique_ptr GNSSBlockFactory::GetChannel_1G( + std::shared_ptr configuration, + std::string acq, std::string trk, std::string tlm, int channel, + boost::shared_ptr queue) +{ + std::stringstream stream; + stream << channel; + std::string id = stream.str(); + LOG(INFO) << "Instantiating Channel " << channel << " with Acquisition Implementation: " + << acq << ", Tracking Implementation: " << trk << ", Telemetry Decoder Implementation: " << tlm; + + std::string aux = configuration->property("Acquisition_1G" + boost::lexical_cast(channel) + ".implementation", std::string("W")); + std::string appendix1; + if(aux.compare("W") != 0) + { + appendix1 = boost::lexical_cast(channel); + } + else + { + appendix1 = ""; + } + aux = configuration->property("Tracking_1G" + boost::lexical_cast(channel) + ".implementation", std::string("W")); + std::string appendix2; + if(aux.compare("W") != 0) + { + appendix2 = boost::lexical_cast(channel); + } + else + { + appendix2 = ""; + } + aux = configuration->property("TelemetryDecoder_1G" + boost::lexical_cast(channel) + ".implementation", std::string("W")); + std::string appendix3; + if(aux.compare("W") != 0) + { + appendix3 = boost::lexical_cast(channel); + } + else + { + appendix3 = ""; + } + // Automatically detect input data type + std::shared_ptr config; + config = std::make_shared(); + std::string default_item_type = "gr_complex"; + std::string acq_item_type = configuration->property("Acquisition_1G" + appendix1 + ".item_type", default_item_type); + std::string trk_item_type = configuration->property("Tracking_1G" + appendix2 + ".item_type", default_item_type); + if(acq_item_type.compare(trk_item_type)) + { + LOG(ERROR) << "Acquisition and Tracking blocks must have the same input data type!"; + } + config->set_property("Channel.item_type", acq_item_type); + + std::unique_ptr pass_through_ = GetBlock(config, "Channel", "Pass_Through", 1, 1, queue); + std::unique_ptr acq_ = GetAcqBlock(configuration, "Acquisition_1G" + appendix1, acq, 1, 0); + std::unique_ptr trk_ = GetTrkBlock(configuration, "Tracking_1G"+ appendix2, trk, 1, 1); + std::unique_ptr tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_1G" + appendix3, tlm, 1, 1); + + std::unique_ptr channel_(new Channel(configuration.get(), channel, std::move(pass_through_), + std::move(acq_), + std::move(trk_), + std::move(tlm_), + "Channel", "1G", queue)); + + return channel_; +} + + //********* GPS L5 CHANNEL ***************** std::unique_ptr GNSSBlockFactory::GetChannel_L5( std::shared_ptr configuration, @@ -597,7 +672,6 @@ std::unique_ptr GNSSBlockFactory::GetChannel_L5( } - std::unique_ptr>> GNSSBlockFactory::GetChannels( std::shared_ptr configuration, gr::msg_queue::sptr queue) { @@ -612,45 +686,46 @@ std::unique_ptr>> GNSSBlockFacto unsigned int Channels_2S_count = configuration->property("Channels_2S.count", 0); unsigned int Channels_1B_count = configuration->property("Channels_1B.count", 0); unsigned int Channels_5X_count = configuration->property("Channels_5X.count", 0); + unsigned int Channels_1G_count = configuration->property("Channels_1G.count", 0); unsigned int Channels_L5_count = configuration->property("Channels_L5.count", 0); unsigned int total_channels = Channels_1C_count + Channels_2S_count + Channels_1B_count + Channels_5X_count + + Channels_1G_count + Channels_L5_count; + std::unique_ptr>> channels(new std::vector>(total_channels)); //**************** GPS L1 C/A CHANNELS ********************** - LOG(INFO) << "Getting " << Channels_1C_count << " GPS L1 C/A channels"; acquisition_implementation = configuration->property("Acquisition_1C.implementation", default_implementation); tracking_implementation = configuration->property("Tracking_1C.implementation", default_implementation); telemetry_decoder_implementation = configuration->property("TelemetryDecoder_1C.implementation", default_implementation); - for (unsigned int i = 0; i < Channels_1C_count; i++) { //(i.e. Acquisition_1C0.implementation=xxxx) std::string acquisition_implementation_specific = configuration->property( - "Acquisition_1C" + boost::lexical_cast(channel_absolute_id) + ".implementation", - acquisition_implementation); + "Acquisition_1C" + boost::lexical_cast(channel_absolute_id) + ".implementation", + acquisition_implementation); //(i.e. Tracking_1C0.implementation=xxxx) std::string tracking_implementation_specific = configuration->property( - "Tracking_1C" + boost::lexical_cast(channel_absolute_id) + ".implementation", - tracking_implementation); + "Tracking_1C" + boost::lexical_cast(channel_absolute_id) + ".implementation", + tracking_implementation); std::string telemetry_decoder_implementation_specific = configuration->property( - "TelemetryDecoder_1C" + boost::lexical_cast(channel_absolute_id) + ".implementation", - telemetry_decoder_implementation); + "TelemetryDecoder_1C" + boost::lexical_cast(channel_absolute_id) + ".implementation", + telemetry_decoder_implementation); // Push back the channel to the vector of channels - channels->at(channel_absolute_id) = std::move(GetChannel_1C(configuration, - acquisition_implementation_specific, - tracking_implementation_specific, - telemetry_decoder_implementation_specific, - channel_absolute_id, - queue)); - channel_absolute_id++; + channels->at(channel_absolute_id) = std::move(GetChannel_1C(configuration, + acquisition_implementation_specific, + tracking_implementation_specific, + telemetry_decoder_implementation_specific, + channel_absolute_id, + queue)); + channel_absolute_id++; } //**************** GPS L2C (M) CHANNELS ********************** @@ -662,25 +737,26 @@ std::unique_ptr>> GNSSBlockFacto { //(i.e. Acquisition_1C0.implementation=xxxx) std::string acquisition_implementation_specific = configuration->property( - "Acquisition_2S" + boost::lexical_cast(channel_absolute_id) + ".implementation", - acquisition_implementation); + "Acquisition_2S" + boost::lexical_cast(channel_absolute_id) + ".implementation", + acquisition_implementation); //(i.e. Tracking_1C0.implementation=xxxx) std::string tracking_implementation_specific = configuration->property( - "Tracking_2S" + boost::lexical_cast(channel_absolute_id) + ".implementation", - tracking_implementation); + "Tracking_2S" + boost::lexical_cast(channel_absolute_id) + ".implementation", + tracking_implementation); std::string telemetry_decoder_implementation_specific = configuration->property( - "TelemetryDecoder_2S" + boost::lexical_cast(channel_absolute_id) + ".implementation", - telemetry_decoder_implementation); + "TelemetryDecoder_2S" + boost::lexical_cast(channel_absolute_id) + ".implementation", + telemetry_decoder_implementation); // Push back the channel to the vector of channels - channels->at(channel_absolute_id) = std::move(GetChannel_2S(configuration, - acquisition_implementation_specific, - tracking_implementation_specific, - telemetry_decoder_implementation_specific, - channel_absolute_id, - queue)); - channel_absolute_id++; + channels->at(channel_absolute_id) = std::move(GetChannel_2S(configuration, + acquisition_implementation_specific, + tracking_implementation_specific, + telemetry_decoder_implementation_specific, + channel_absolute_id, + queue)); + channel_absolute_id++; } + //**************** GPS L5 CHANNELS ********************** LOG(INFO)<< "Getting " << Channels_L5_count << " GPS L5 channels"; tracking_implementation = configuration->property("Tracking_L5.implementation", default_implementation); @@ -690,88 +766,118 @@ std::unique_ptr>> GNSSBlockFacto { //(i.e. Acquisition_1C0.implementation=xxxx) std::string acquisition_implementation_specific = configuration->property( - "Acquisition_L5" + boost::lexical_cast(channel_absolute_id) + ".implementation", - acquisition_implementation); + "Acquisition_L5" + boost::lexical_cast(channel_absolute_id) + ".implementation", + acquisition_implementation); //(i.e. Tracking_1C0.implementation=xxxx) std::string tracking_implementation_specific = configuration->property( - "Tracking_L5" + boost::lexical_cast(channel_absolute_id) + ".implementation", - tracking_implementation); + "Tracking_L5" + boost::lexical_cast(channel_absolute_id) + ".implementation", + tracking_implementation); std::string telemetry_decoder_implementation_specific = configuration->property( - "TelemetryDecoder_L5" + boost::lexical_cast(channel_absolute_id) + ".implementation", - telemetry_decoder_implementation); + "TelemetryDecoder_L5" + boost::lexical_cast(channel_absolute_id) + ".implementation", + telemetry_decoder_implementation); // Push back the channel to the vector of channels - channels->at(channel_absolute_id) = std::move(GetChannel_L5(configuration, - acquisition_implementation_specific, - tracking_implementation_specific, - telemetry_decoder_implementation_specific, - channel_absolute_id, - queue)); - channel_absolute_id++; + channels->at(channel_absolute_id) = std::move(GetChannel_L5(configuration, + acquisition_implementation_specific, + tracking_implementation_specific, + telemetry_decoder_implementation_specific, + channel_absolute_id, + queue)); + channel_absolute_id++; } + //**************** GALILEO E1 B (I/NAV OS) CHANNELS ********************** - LOG(INFO) << "Getting " << Channels_1B_count << " GALILEO E1 B (I/NAV OS) channels"; - tracking_implementation = configuration->property("Tracking_1B.implementation", default_implementation); - telemetry_decoder_implementation = configuration->property("TelemetryDecoder_1B.implementation", default_implementation); - acquisition_implementation = configuration->property("Acquisition_1B.implementation", default_implementation); - for (unsigned int i = 0; i < Channels_1B_count; i++) - { - //(i.e. Acquisition_1C0.implementation=xxxx) - std::string acquisition_implementation_specific = configuration->property( - "Acquisition_1B" + boost::lexical_cast(channel_absolute_id) + ".implementation", - acquisition_implementation); - //(i.e. Tracking_1C0.implementation=xxxx) - std::string tracking_implementation_specific = configuration->property( - "Tracking_1B" + boost::lexical_cast(channel_absolute_id) + ".implementation", - tracking_implementation); - std::string telemetry_decoder_implementation_specific = configuration->property( - "TelemetryDecoder_1B" + boost::lexical_cast(channel_absolute_id) + ".implementation", - telemetry_decoder_implementation); - - // Push back the channel to the vector of channels - channels->at(channel_absolute_id) = std::move(GetChannel_1B(configuration, - acquisition_implementation_specific, - tracking_implementation_specific, - telemetry_decoder_implementation_specific, - channel_absolute_id, - queue)); - channel_absolute_id++; - } + tracking_implementation = configuration->property("Tracking_1B.implementation", default_implementation); + telemetry_decoder_implementation = configuration->property("TelemetryDecoder_1B.implementation", default_implementation); + acquisition_implementation = configuration->property("Acquisition_1B.implementation", default_implementation); + for (unsigned int i = 0; i < Channels_1B_count; i++) + { + //(i.e. Acquisition_1C0.implementation=xxxx) + std::string acquisition_implementation_specific = configuration->property( + "Acquisition_1B" + boost::lexical_cast(channel_absolute_id) + ".implementation", + acquisition_implementation); + //(i.e. Tracking_1C0.implementation=xxxx) + std::string tracking_implementation_specific = configuration->property( + "Tracking_1B" + boost::lexical_cast(channel_absolute_id) + ".implementation", + tracking_implementation); + std::string telemetry_decoder_implementation_specific = configuration->property( + "TelemetryDecoder_1B" + boost::lexical_cast(channel_absolute_id) + ".implementation", + telemetry_decoder_implementation); + // Push back the channel to the vector of channels + channels->at(channel_absolute_id) = std::move(GetChannel_1B(configuration, + acquisition_implementation_specific, + tracking_implementation_specific, + telemetry_decoder_implementation_specific, + channel_absolute_id, + queue)); + channel_absolute_id++; + } //**************** GALILEO E5a I (F/NAV OS) CHANNELS ********************** LOG(INFO) << "Getting " << Channels_5X_count << " GALILEO E5a I (F/NAV OS) channels"; - tracking_implementation = configuration->property("Tracking_5X.implementation", default_implementation); - telemetry_decoder_implementation = configuration->property("TelemetryDecoder_5X.implementation", default_implementation); - acquisition_implementation = configuration->property("Acquisition_5X.implementation", default_implementation); - for (unsigned int i = 0; i < Channels_5X_count; i++) - { - //(i.e. Acquisition_1C0.implementation=xxxx) - std::string acquisition_implementation_specific = configuration->property( - "Acquisition_5X" + boost::lexical_cast(channel_absolute_id) + ".implementation", - acquisition_implementation); - //(i.e. Tracking_1C0.implementation=xxxx) - std::string tracking_implementation_specific = configuration->property( - "Tracking_5X" + boost::lexical_cast(channel_absolute_id) + ".implementation", - tracking_implementation); - std::string telemetry_decoder_implementation_specific = configuration->property( - "TelemetryDecoder_5X" + boost::lexical_cast(channel_absolute_id) + ".implementation", - telemetry_decoder_implementation); + tracking_implementation = configuration->property("Tracking_5X.implementation", default_implementation); + telemetry_decoder_implementation = configuration->property("TelemetryDecoder_5X.implementation", default_implementation); + acquisition_implementation = configuration->property("Acquisition_5X.implementation", default_implementation); + for (unsigned int i = 0; i < Channels_5X_count; i++) + { + //(i.e. Acquisition_1C0.implementation=xxxx) + std::string acquisition_implementation_specific = configuration->property( + "Acquisition_5X" + boost::lexical_cast(channel_absolute_id) + ".implementation", + acquisition_implementation); + //(i.e. Tracking_1C0.implementation=xxxx) + std::string tracking_implementation_specific = configuration->property( + "Tracking_5X" + boost::lexical_cast(channel_absolute_id) + ".implementation", + tracking_implementation); + std::string telemetry_decoder_implementation_specific = configuration->property( + "TelemetryDecoder_5X" + boost::lexical_cast(channel_absolute_id) + ".implementation", + telemetry_decoder_implementation); - // Push back the channel to the vector of channels - channels->at(channel_absolute_id) = std::move(GetChannel_5X(configuration, - acquisition_implementation_specific, - tracking_implementation_specific, - telemetry_decoder_implementation_specific, - channel_absolute_id, - queue)); - channel_absolute_id++; - } + // Push back the channel to the vector of channels + channels->at(channel_absolute_id) = std::move(GetChannel_5X(configuration, + acquisition_implementation_specific, + tracking_implementation_specific, + telemetry_decoder_implementation_specific, + channel_absolute_id, + queue)); + channel_absolute_id++; + } + + //**************** GLONASS L1 C/A CHANNELS ********************** + LOG(INFO) << "Getting " << Channels_1G_count << " GLONASS L1 C/A channels"; + acquisition_implementation = configuration->property("Acquisition_1G.implementation", default_implementation); + tracking_implementation = configuration->property("Tracking_1G.implementation", default_implementation); + telemetry_decoder_implementation = configuration->property("TelemetryDecoder_1G.implementation", default_implementation); + + for (unsigned int i = 0; i < Channels_1G_count; i++) + { + //(i.e. Acquisition_1G0.implementation=xxxx) + std::string acquisition_implementation_specific = configuration->property( + "Acquisition_1G" + boost::lexical_cast(channel_absolute_id) + ".implementation", + acquisition_implementation); + //(i.e. Tracking_1G0.implementation=xxxx) + std::string tracking_implementation_specific = configuration->property( + "Tracking_1G" + boost::lexical_cast(channel_absolute_id) + ".implementation", + tracking_implementation); + std::string telemetry_decoder_implementation_specific = configuration->property( + "TelemetryDecoder_1G" + boost::lexical_cast(channel_absolute_id) + ".implementation", + telemetry_decoder_implementation); + + // Push back the channel to the vector of channels + channels->at(channel_absolute_id) = std::move(GetChannel_1G(configuration, + acquisition_implementation_specific, + tracking_implementation_specific, + telemetry_decoder_implementation_specific, + channel_absolute_id, + queue)); + channel_absolute_id++; + } return channels; } + /* * Returns the block with the required configuration and implementation * @@ -1056,7 +1162,6 @@ std::unique_ptr GNSSBlockFactory::GetBlock( block = std::move(block_); } - // RESAMPLER ------------------------------------------------------------------- else if (implementation.compare("Direct_Resampler") == 0) { @@ -1163,9 +1268,12 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams)); block = std::move(block_); } - - - + else if (implementation.compare("GLONASS_L1_CA_PCPS_Acquisition") == 0) + { + std::unique_ptr block_(new GlonassL1CaPcpsAcquisition(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } // TRACKING BLOCKS ------------------------------------------------------------- else if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking") == 0) @@ -1232,6 +1340,18 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams)); block = std::move(block_); } + else if (implementation.compare("GLONASS_L1_CA_DLL_PLL_Tracking") == 0) + { + std::unique_ptr block_(new GlonassL1CaDllPllTracking(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } + else if (implementation.compare("GLONASS_L1_CA_DLL_PLL_C_Aid_Tracking") == 0) + { + std::unique_ptr block_(new GlonassL1CaDllPllCAidTracking(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } // TELEMETRY DECODERS ---------------------------------------------------------- else if (implementation.compare("GPS_L1_CA_Telemetry_Decoder") == 0) @@ -1270,6 +1390,12 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams)); block = std::move(block_); } + else if (implementation.compare("GLONASS_L1_CA_Telemetry_Decoder") == 0) + { + std::unique_ptr block_(new GlonassL1CaTelemetryDecoder(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } // OBSERVABLES ----------------------------------------------------------------- else if ((implementation.compare("Hybrid_Observables") == 0) || (implementation.compare("GPS_L1_CA_Observables") == 0) || (implementation.compare("GPS_L2C_Observables") == 0) || @@ -1279,6 +1405,7 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams)); block = std::move(block_); } + // PVT ------------------------------------------------------------------------- else if ((implementation.compare("RTKLIB_PVT") == 0) || (implementation.compare("GPS_L1_CA_PVT") == 0) || (implementation.compare("Galileo_E1_PVT") == 0) || (implementation.compare("Hybrid_PVT") == 0)) { @@ -1408,6 +1535,12 @@ std::unique_ptr GNSSBlockFactory::GetAcqBlock( out_streams)); block = std::move(block_); } + else if (implementation.compare("GLONASS_L1_CA_PCPS_Acquisition") == 0) + { + std::unique_ptr block_(new GlonassL1CaPcpsAcquisition(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } else { // Log fatal. This causes execution to stop. @@ -1490,6 +1623,18 @@ std::unique_ptr GNSSBlockFactory::GetTrkBlock( block = std::move(block_); } #endif + else if (implementation.compare("GLONASS_L1_CA_DLL_PLL_Tracking") == 0) + { + std::unique_ptr block_(new GlonassL1CaDllPllTracking(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } + else if (implementation.compare("GLONASS_L1_CA_DLL_PLL_C_Aid_Tracking") == 0) + { + std::unique_ptr block_(new GlonassL1CaDllPllCAidTracking(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } else { // Log fatal. This causes execution to stop. @@ -1538,6 +1683,12 @@ std::unique_ptr GNSSBlockFactory::GetTlmBlock( out_streams)); block = std::move(block_); } + else if (implementation.compare("GLONASS_L1_CA_Telemetry_Decoder") == 0) + { + std::unique_ptr block_(new GlonassL1CaTelemetryDecoder(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } else if (implementation.compare("GPS_L5_Telemetry_Decoder") == 0) { std::unique_ptr block_(new GpsL5TelemetryDecoder(configuration.get(), role, in_streams, diff --git a/src/core/receiver/gnss_block_factory.h b/src/core/receiver/gnss_block_factory.h index bba584d7a..4aa852d74 100644 --- a/src/core/receiver/gnss_block_factory.h +++ b/src/core/receiver/gnss_block_factory.h @@ -98,6 +98,10 @@ private: std::string acq, std::string trk, std::string tlm, int channel, gr::msg_queue::sptr queue); + std::unique_ptr GetChannel_1G(std::shared_ptr configuration, + std::string acq, std::string trk, std::string tlm, int channel, + boost::shared_ptr queue); + std::unique_ptr GetAcqBlock( std::shared_ptr configuration, std::string role, diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index a59d4e5d1..1b4438cea 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -547,6 +547,8 @@ void GNSSFlowgraph::set_signals_list() unsigned int total_channels = configuration_->property("Channels_1C.count", 0) + configuration_->property("Channels_2S.count", 0) + configuration_->property("Channels_1B.count", 0) + + configuration_->property("Channels_5X.count", 0) + + configuration_->property("Channels_1G.count", 0) + configuration_->property("Channels_5X.count", 0) + configuration_->property("Channels_L5.count", 0); @@ -565,6 +567,9 @@ void GNSSFlowgraph::set_signals_list() 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36}; + // Removing satellites sharing same frequency number(1 and 5, 2 and 6, 3 and 7, 4 and 6, 11 and 15, 12 and 16, 14 and 18, 17 and 21 + std::set available_glonass_prn = { 1, 2, 3, 4, 9, 10, 11, 12, 18, 19, 20, 21, 24 }; + std::string sv_list = configuration_->property("Galileo.prns", std::string("") ); if( sv_list.length() > 0 ) @@ -613,6 +618,22 @@ void GNSSFlowgraph::set_signals_list() } } + sv_list = configuration_->property("Glonass.prns", std::string("") ); + + if( sv_list.length() > 0 ) + { + // Reset the available prns: + std::set< unsigned int > tmp_set; + boost::tokenizer<> tok( sv_list ); + std::transform( tok.begin(), tok.end(), std::inserter( tmp_set, tmp_set.begin() ), + boost::lexical_cast ); + + if( tmp_set.size() > 0 ) + { + available_glonass_prn = tmp_set; + } + } + if (configuration_->property("Channels_1C.count", 0) > 0 ) { /* @@ -696,6 +717,20 @@ void GNSSFlowgraph::set_signals_list() *available_gnss_prn_iter), std::string("5X"))); } } + + if (configuration_->property("Channels_1G.count", 0) > 0 ) + { + /* + * Loop to create the list of GLONASS L1 C/A signals + */ + for (available_gnss_prn_iter = available_glonass_prn.begin(); + available_gnss_prn_iter != available_glonass_prn.end(); + available_gnss_prn_iter++) + { + available_GNSS_signals_.push_back(Gnss_Signal(Gnss_Satellite(std::string("Glonass"), + *available_gnss_prn_iter), std::string("1G"))); + } + } /* * Ordering the list of signals from configuration file */ @@ -709,6 +744,7 @@ void GNSSFlowgraph::set_signals_list() std::string gnss_system; if((gnss_signal.compare("1C") == 0) or (gnss_signal.compare("2S") == 0) or (gnss_signal.compare("L5") == 0)) gnss_system = "GPS"; if((gnss_signal.compare("1B") == 0) or (gnss_signal.compare("5X") == 0) ) gnss_system = "Galileo"; + if((gnss_signal.compare("1G") == 0)/*or (gnss_signal.compare("") == 0)*/) gnss_system = "Glonass"; unsigned int sat = configuration_->property("Channel" + boost::lexical_cast(i) + ".satellite", 0); LOG(INFO) << "Channel " << i << " system " << gnss_system << ", signal " << gnss_signal <<", sat "<. + * + * ------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_GLONASS_L1_CA_H_ +#define GNSS_SDR_GLONASS_L1_CA_H_ + +#include +#include +#include // std::pair +#include "MATH_CONSTANTS.h" +#include "gnss_frequencies.h" + +// Physical constants +const double GLONASS_C_m_s = SPEED_OF_LIGHT; //!< The speed of light, [m/s] +const double GLONASS_C_m_ms = 299792.4580; //!< The speed of light, [m/ms] +const double GLONASS_PI = 3.1415926535898; //!< Pi as defined in IS-GPS-200E +const double GLONASS_TWO_PI = 6.283185307179586; //!< 2Pi as defined in IS-GPS-200E +const double GLONASS_OMEGA_EARTH_DOT = 7.292115e-5; //!< Earth rotation rate, [rad/s] +const double GLONASS_GM = 398600.4418e9; //!< Universal gravitational constant times the mass of the Earth, [m^3/s^2] +const double GLONASS_fM_a = 0.35e9; //!< Gravitational constant of atmosphere [m^3/s^2] +const double GLONASS_SEMI_MAJOR_AXIS = 6378136; //!< Semi-major axis of Earth [m] +const double GLONASS_FLATTENING = 1/29825784; //!< Flattening parameter +const double GLONASS_GRAVITY = 97803284; //!< Equatorial acceleration of gravity [mGal] +const double GLONASS_GRAVITY_CORRECTION = 0.87; //!< Correction to acceleration of gravity at sea-level due to Atmosphere[мGal] +const double GLONASS_J2 = 1082625.75e-9; //!< Second zonal harmonic of the geopotential +const double GLONASS_J4 = -2370.89e-9; //!< Fourth zonal harmonic of the geopotential +const double GLONASS_J6 = 6.08e-9; //!< Sixth zonal harmonic of the geopotential +const double GLONASS_J8 = 1.40e-11; //!< Eighth zonal harmonic of the geopotential +const double GLONASS_U0 = 62636861.4; //!< Normal potential at surface of common terrestrial ellipsoid [m^2/s^2] +const double GLONASS_C20 = -1082.63e-6; //!< Second zonal coefficient of spherical harmonic expansion +const double GLONASS_EARTH_RADIUS = 6378.136; //!< Equatorial radius of Earth [km] +const double GLONASS_EARTH_INCLINATION = 0.000409148809899e3; //!< Mean inclination of ecliptic to equator (23 deg 26 min 33 sec) [rad] + +const double GLONASS_TAU_0 = -0.005835151531174e3; //!< (-334 deg 19 min 46.40 sec) [rad]; +const double GLONASS_TAU_1 = 0.071018041257371e3; //!< (4069 deg 02 min 02.52 sec) [rad]; + +const double GLONASS_MOON_Q0 = -0.001115184961435e3; //!< (-63 deg 53 min 43.41 sec) [rad] +const double GLONASS_MOON_Q1 = 8.328691103668023e3; //!< (477198 deg 50 min 56.79 sec) [rad] +const double GLONASS_MOON_OMEGA_0 = 0.004523601514852e3; //!< (259 deg 10 min 59.79 sec) [rad] +const double GLONASS_MOON_OMEGA_1 = -0.033757146246552e3; //!< (-1934 deg 08 min 31.23 sec) [rad] +const double GLONASS_MOON_GM = 4902.835; //!< Lunar gravitational constant [km^3/s^2] +const double GLONASS_MOON_SEMI_MAJOR_AXIS = 3.84385243e5; //!< Semi-major axis of lunar orbit [km]; +const double GLONASS_MOON_ECCENTRICITY = 0.054900489; //!< Eccentricity of lunar orbit +const double GLONASS_MOON_INCLINATION = 0.000089803977407e3; //!< Inclination of lunar orbit to ecliptic plane (5 deg 08 min 43.4 sec) [rad] + +const double GLONASS_SUN_OMEGA = 0.004908229466869e3; //!< TODO What is this operation in the seconds with T?(281 deg 13 min 15.0 + 6189.03*Т sec) [rad] +const double GLONASS_SUN_Q0 = 0.006256583774423e3; //!< (358 deg 28 min 33.04 sec) [rad] +const double GLONASS_SUN_Q1 = 0e3; //!< TODO Why is the value greater than 60?(129596579.10 sec) [rad] +const double GLONASS_SUN_GM = 0.1325263e12; //!< Solar gravitational constant [km^3/s^2] +const double GLONASS_SUN_SEMI_MAJOR_AXIS = 1.49598e8; //!< Semi-major axis of solar orbit [km]; +const double GLONASS_SUN_ECCENTRICITY = 0.016719; //!< Eccentricity of solar orbit + +// carrier and code frequencies +const double GLONASS_L2_FREQ_HZ = FREQ2_GLO; //!< L1 [Hz] + +const double GLONASS_L1_CA_FREQ_HZ = FREQ1_GLO; //!< L1 [Hz] +const double GLONASS_L1_CA_DFREQ_HZ = DFRQ1_GLO; //!< Freq Bias for GLONASS L1 [Hz] +const double GLONASS_L1_CA_CODE_RATE_HZ = 0.511e6; //!< GLONASS L1 C/A code rate [chips/s] +const double GLONASS_L1_CA_CODE_LENGTH_CHIPS = 511.0; //!< GLONASS L1 C/A code length [chips] +const double GLONASS_L1_CA_CODE_PERIOD = 0.001; //!< GLONASS L1 C/A code period [seconds] +const double GLONASS_L1_CA_CHIP_PERIOD = 1.9569e-06; //!< GLONASS L1 C/A chip period [seconds] +const double GLONASS_L1_CA_SYMBOL_RATE_BPS = 1000; +const int GLONASS_L1_CA_NBR_SATS = 24; // STRING DATA WITHOUT PREAMBLE + +/*! + * \brief Record of leap seconds definition for GLOT to GPST conversion and vice versa + * \details Each entry is defined by an array of 7 elements consisting of yr,month,day,hr,min,sec,utc-gpst + * \note Ideally should use leap seconds definitions of rtklib + */ +const double GLONASS_LEAP_SECONDS[19][7] = { + {2017, 1, 1, 0, 0, 0, -18}, + {2015, 7, 1, 0, 0, 0, -17}, + {2012, 7, 1, 0, 0, 0, -16}, + {2009, 1, 1, 0, 0, 0, -15}, + {2006, 1, 1, 0, 0, 0, -14}, + {1999, 1, 1, 0, 0, 0, -13}, + {1997, 7, 1, 0, 0, 0, -12}, + {1996, 1, 1, 0, 0, 0, -11}, + {1994, 7, 1, 0, 0, 0, -10}, + {1993, 7, 1, 0, 0, 0, -9}, + {1992, 7, 1, 0, 0, 0, -8}, + {1991, 1, 1, 0, 0, 0, -7}, + {1990, 1, 1, 0, 0, 0, -6}, + {1988, 1, 1, 0, 0, 0, -5}, + {1985, 7, 1, 0, 0, 0, -4}, + {1983, 7, 1, 0, 0, 0, -3}, + {1982, 7, 1, 0, 0, 0, -2}, + {1981, 7, 1, 0, 0, 0, -1}, + {} +}; + +//!< GLONASS SV's orbital slots PRN = (orbital_slot - 1) +const std::map GLONASS_PRN = + {{ 0, 8,}, //For test + { 1, 1,}, //Plane 1 + { 2,-4,}, //Plane 1 + { 3, 5,}, //Plane 1 + { 4, 6,}, //Plane 1 + { 5, 1,}, //Plane 1 + { 6,-4,}, //Plane 1 + { 7, 5,}, //Plane 1 + { 8, 6,}, //Plane 1 + { 9,-2,}, //Plane 2 + {10,-7,}, //Plane 2 + {11, 0,}, //Plane 2 + {12,-1,}, //Plane 2 + {13,-2,}, //Plane 2 + {14,-7,}, //Plane 2 + {15, 0,}, //Plane 2 + {16,-1,}, //Plane 2 + {17, 4,}, //Plane 3 + {18,-3,}, //Plane 3 + {19, 3,}, //Plane 3 + {20,-5,}, //Plane 3 + {21, 4,}, //Plane 3 + {22,-3,}, //Plane 3 + {23, 3,}, //Plane 3 + {24, 2}}; //Plane 3 + +const double GLONASS_STARTOFFSET_ms = 68.802; //[ms] Initial sign. travel time (this cannot go here) + +// OBSERVABLE HISTORY DEEP FOR INTERPOLATION +const int GLONASS_L1_CA_HISTORY_DEEP = 100; + +// NAVIGATION MESSAGE DEMODULATION AND DECODING +#define GLONASS_GNAV_PREAMBLE {1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0} +const double GLONASS_GNAV_PREAMBLE_DURATION_S = 0.300; +const int GLONASS_GNAV_PREAMBLE_LENGTH_BITS = 30; +const int GLONASS_GNAV_PREAMBLE_LENGTH_SYMBOLS = 300; +const int GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS = 2000; +const int GLONASS_GNAV_TELEMETRY_RATE_BITS_SECOND = 50; //!< NAV message bit rate [bits/s] +const int GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_BIT = 10; +const int GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_PREAMBLE_BIT = 10; +const int GLONASS_GNAV_TELEMETRY_RATE_SYMBOLS_SECOND = GLONASS_GNAV_TELEMETRY_RATE_BITS_SECOND*GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_BIT; //!< NAV message bit rate [symbols/s] +const int GLONASS_GNAV_STRING_SYMBOLS = 2000; //!< Number of bits per string in the GNAV message (85 data bits + 30 time mark bits) [bits] +const int GLONASS_GNAV_STRING_BITS = 85; //!< Number of bits per string in the GNAV message (85 data bits + 30 time mark bits) [bits] +const int GLONASS_GNAV_HAMMING_CODE_BITS = 8; //!< Number of bits in hamming code sequence of GNAV message +const int GLONASS_GNAV_DATA_SYMBOLS = 1700; // STRING DATA WITHOUT PREAMBLE + +const std::vector GLONASS_GNAV_CRC_I_INDEX {9, 10, 12, 13, 15, 17, 19, 20, 22, 24, 26, 28, 30, 32, 34, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84}; +const std::vector GLONASS_GNAV_CRC_J_INDEX {9, 11, 12, 14, 15, 18, 19, 21, 22, 25, 26, 29, 30, 33, 34, 36, 37, 40, 41, 44, 45, 48, 49, 52, 53, 56, 57, 60, 61, 64, 65, 67, 68, 71, 72, 75, 76, 79, 80, 83, 84}; +const std::vector GLONASS_GNAV_CRC_K_INDEX {10, 11, 12, 16, 17, 18, 19, 23, 24, 25, 26, 31, 32, 33, 34, 38, 39, 40, 41, 46, 47, 48, 49, 54, 55, 56, 57, 62, 63, 64, 65, 69, 70, 71, 72, 77, 78, 79, 80, 85}; +const std::vector GLONASS_GNAV_CRC_L_INDEX {13, 14, 15, 16, 17, 18, 19, 27, 28, 29, 30, 31, 32, 33, 34, 42, 43, 44, 45, 46, 47, 48, 49, 58, 59, 60, 61, 62, 63, 64, 65, 73, 74, 75, 76, 77, 78, 79, 80}; +const std::vector GLONASS_GNAV_CRC_M_INDEX {20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 81, 82, 83, 84, 85}; +const std::vector GLONASS_GNAV_CRC_N_INDEX {35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65}; +const std::vector GLONASS_GNAV_CRC_P_INDEX {66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85}; +const std::vector GLONASS_GNAV_CRC_Q_INDEX {9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85}; + +// GLONASS GNAV NAVIGATION MESSAGE STRUCTURE +// NAVIGATION MESSAGE FIELDS POSITIONS (from IS-GPS-200E Appendix II) + +// FRAME 1-4 +// COMMON FIELDS +const std::vector> STRING_ID({{2,4}}); +const std::vector> KX({{78,8}}); +//STRING 1 +const std::vector> P1({{8,2}}); +const std::vector> T_K_HR({{10,5}}); +const std::vector> T_K_MIN({{15,6}}); +const std::vector> T_K_SEC({{21,1}}); +const std::vector> X_N_DOT ({{22,24}}); +const std::vector> X_N_DOT_DOT ({{46,5}}); +const std::vector> X_N({{51,27}}); + +//STRING 2 +const std::vector> B_N({{6,3}}); +const std::vector> P2({{9,1}}); +const std::vector> T_B({{10,7}}); +const std::vector> Y_N_DOT ({{22,24}}); +const std::vector> Y_N_DOT_DOT ({{46,5}}); +const std::vector> Y_N({{51,27}}); + +//STRING 3 +const std::vector> P3({{6,1}}); +const std::vector> GAMMA_N({{7,11}}); +const std::vector> P({{19,2}}); +const std::vector> EPH_L_N({{21,1}}); +const std::vector> Z_N_DOT ({{22,24}}); +const std::vector> Z_N_DOT_DOT ({{46,5}}); +const std::vector> Z_N({{51,27}}); + +// STRING 4 +const std::vector> TAU_N({{6,22}}); +const std::vector> DELTA_TAU_N({{28,5}}); +const std::vector> E_N({{33,5}}); +const std::vector> P4 ({{52,1}}); +const std::vector> F_T ({{53,4}}); +const std::vector> N_T({{60,11}}); +const std::vector> N({{71,5}}); +const std::vector> M({{76,2}}); + +// STRING 5 +const std::vector> N_A({{6,11}}); +const std::vector> TAU_C({{17,32}}); +const std::vector> N_4({{50,5}}); +const std::vector> TAU_GPS({{55,22}}); +const std::vector> ALM_L_N({{77,1}}); + +// STRING 6, 8, 10, 12, 14 +const std::vector> C_N({{6,1}}); +const std::vector> M_N_A({{7,2}}); +const std::vector> n_A({{9,5}}); +const std::vector> TAU_N_A({{14,10}}); +const std::vector> LAMBDA_N_A({{24,21}}); +const std::vector> DELTA_I_N_A({{45,18}}); +const std::vector> EPSILON_N_A({{63,15}}); + +//STRING 7, 9, 11, 13, 15 +const std::vector> OMEGA_N_A({{6,16}}); +const std::vector> T_LAMBDA_N_A({{22,21}}); +const std::vector> DELTA_T_N_A({{43,22}}); +const std::vector> DELTA_T_DOT_N_A({{65,7}}); +const std::vector> H_N_A({{72,5}}); + +// STRING 14 FRAME 5 +const std::vector> B1({{6,11}}); +const std::vector> B2({{17,10}}); + + +#endif /* GNSS_SDR_GLONASS_L1_CA_H_ */ diff --git a/src/core/system_parameters/MATH_CONSTANTS.h b/src/core/system_parameters/MATH_CONSTANTS.h index 2e080f5ae..8c8dfbbe5 100644 --- a/src/core/system_parameters/MATH_CONSTANTS.h +++ b/src/core/system_parameters/MATH_CONSTANTS.h @@ -66,6 +66,7 @@ const double TWO_N14 = (0.00006103515625); //!< 2^-14 const double TWO_N15 = (0.00003051757813); //!< 2^-15 const double TWO_N16 = (0.0000152587890625); //!< 2^-16 const double TWO_N17 = (7.629394531250000e-006); //!< 2^-17 +const double TWO_N18 = (3.814697265625000e-006); //!< 2^-18 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 diff --git a/src/core/system_parameters/glonass_gnav_almanac.cc b/src/core/system_parameters/glonass_gnav_almanac.cc new file mode 100644 index 000000000..297a1cb59 --- /dev/null +++ b/src/core/system_parameters/glonass_gnav_almanac.cc @@ -0,0 +1,55 @@ +/*! + * \file glonass_gnav_almanac.cc + * \brief Interface of a GLONASS GNAV ALMANAC storage as described in GLONASS ICD (Edition 5.1) + * \note Code added as part of GSoC 2017 program + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * \see GLONASS ICD + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "glonass_gnav_almanac.h" + +Glonass_Gnav_Almanac::Glonass_Gnav_Almanac() +{ + i_satellite_freq_channel = 0; + i_satellite_PRN = 0; + i_satellite_slot_number = 0; + + d_n_A = 0.0; + d_H_n_A = 0.0; + d_lambda_n_A = 0.0; + d_t_lambda_n_A = 0.0; + d_Delta_i_n_A = 0.0; + d_Delta_T_n_A = 0.0; + d_Delta_T_n_A_dot = 0.0; + d_epsilon_n_A = 0.0; + d_omega_n_A = 0.0; + d_M_n_A = 0.0; + d_KP = 0.0; + d_tau_n_A = 0.0; + d_C_n = false; + d_l_n = false; +} diff --git a/src/core/system_parameters/glonass_gnav_almanac.h b/src/core/system_parameters/glonass_gnav_almanac.h new file mode 100644 index 000000000..896c5cd62 --- /dev/null +++ b/src/core/system_parameters/glonass_gnav_almanac.h @@ -0,0 +1,101 @@ +/*! + * \file glonass_gnav_almanac.h + * \brief Interface of a GLONASS GNAV ALMANAC storage + * \note Code added as part of GSoC 2017 program + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * \see GLONASS ICD + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (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 . + * + * ------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_GLONASS_ALMANAC_H_ +#define GNSS_SDR_GLONASS_ALMANAC_H_ + +#include + +/*! + * \brief This class is a storage for the GLONASS SV ALMANAC data as described GLONASS ICD (Edition 5.1) + * \note Code added as part of GSoC 2017 program + * \see GLONASS ICD + */ +class Glonass_Gnav_Almanac +{ +public: + double d_n_A; //!< Conventional number of satellite within GLONASS space segment [dimensionless] + double d_H_n_A; //!< Carrier frequency number of navigation RF signal transmitted by d_nA satellite as table 4.10 (0-31) [dimensionless] + double d_lambda_n_A; //!< Longitude of the first (within the d_NA day) ascending node of d_nA [radians] + double d_t_lambda_n_A; //!< Time of first ascending node passage [s] + double d_Delta_i_n_A; //!< Correction of the mean value of inclination of d_n_A satellite at instant t_lambda_n_A [radians] + double d_Delta_T_n_A; //!< Correction to the mean value of Draconian period of d_n_A satellite at instant t_lambda_n_A [s / orbital period] + double d_Delta_T_n_A_dot; //!< Rate of change of Draconian period of d_n_A satellite at instant t_lambda_n_A [s / orbital period^2] + double d_epsilon_n_A; //!< Eccentricity of d_n_A satellite at instant t_lambda_n_A [dimensionless] + double d_omega_n_A; //!< Argument of perigee of d_n_A satellite at instant t_lambdan_A [radians] + double d_M_n_A; //!< Type of satellite n_A [dimensionless] + double d_KP; //!< Notification on forthcoming leap second correction of UTC [dimensionless] + double d_tau_n_A; //!< Coarse value of d_n_A satellite time correction to GLONASS time at instant t_lambdan_A[s] + bool d_C_n; //!< Generalized “unhealthy flag” of n_A satellite at instant of almanac upload [dimensionless] + bool d_l_n; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] + + // Satellite Identification Information + int i_satellite_freq_channel; //!< SV Frequency Channel Number + unsigned int i_satellite_PRN; //!< SV PRN Number, equivalent to slot number for compatibility with GPS + unsigned int i_satellite_slot_number; //!< SV Slot Number + + template + /*! + * \brief Serialize is a boost standard method to be called by the boost XML serialization. Here is used to save the almanac data on disk file. + */ + void serialize(Archive& archive, const unsigned int version) + { + using boost::serialization::make_nvp; + if(version){}; + + archive & make_nvp("i_satellite_freq_channel", i_satellite_freq_channel); + archive & make_nvp("i_satellite_PRN", i_satellite_PRN); + archive & make_nvp("i_satellite_slot_number", i_satellite_slot_number); + archive & make_nvp("d_n_A", d_n_A); + archive & make_nvp("d_H_n_A", d_H_n_A); + archive & make_nvp("d_lambda_n_A", d_lambda_n_A); + archive & make_nvp("d_t_lambda_n_A", d_t_lambda_n_A); + archive & make_nvp("d_Delta_i_n_A", d_Delta_i_n_A); + archive & make_nvp("d_Delta_T_n_A", d_Delta_T_n_A); + archive & make_nvp("d_Delta_T_n_A_dot", d_Delta_T_n_A_dot); + archive & make_nvp("d_epsilon_n_A", d_epsilon_n_A); + archive & make_nvp("d_omega_n_A", d_omega_n_A); + archive & make_nvp("d_M_n_A", d_M_n_A); + archive & make_nvp("d_KP", d_KP); + archive & make_nvp("d_tau_n_A", d_tau_n_A); + archive & make_nvp("d_C_n", d_C_n); + archive & make_nvp("d_l_n", d_l_n); + } + + /*! + * Default constructor + */ + Glonass_Gnav_Almanac(); +}; + +#endif diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.cc b/src/core/system_parameters/glonass_gnav_ephemeris.cc new file mode 100644 index 000000000..e899db773 --- /dev/null +++ b/src/core/system_parameters/glonass_gnav_ephemeris.cc @@ -0,0 +1,191 @@ +/*! + * \file glonass_gnav_ephemeris.cc + * \brief Interface of a GLONASS GNAV EPHEMERIS storage and orbital model functions + * \note Code added as part of GSoC 2017 program + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * \see GLONASS ICD + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "glonass_gnav_ephemeris.h" +#include +#include "GLONASS_L1_CA.h" +#include "gnss_satellite.h" + +Glonass_Gnav_Ephemeris::Glonass_Gnav_Ephemeris() +{ + d_m = 0.0; //!< String number within frame [dimensionless] + d_t_k = 0.0; //!< GLONASS Time (UTC(SU) + 3 h) referenced to the beginning of the frame within the current day [s] + d_t_b = 0.0; //!< Reference ephemeris relative time in GLONASS Time (UTC(SU) + 3 h). Index of a time interval within current day according to UTC(SU) + 03 hours 00 min. [s] + d_M = 0.0; //!< Type of satellite transmitting navigation signal [dimensionless] + d_gamma_n = 0.0; //!< Relative deviation of predicted carrier frequency value of n- satellite from nominal value at the instant tb [dimensionless] + d_tau_n = 0.0; //!< Correction to the nth satellite time (tn) relative to GLONASS time (te), + d_Xn = 0.0; //!< Earth-fixed coordinate x of the satellite in PZ-90.02 coordinate system [km]. + d_Yn = 0.0; //!< Earth-fixed coordinate y of the satellite in PZ-90.02 coordinate system [km] + d_Zn = 0.0; //!< Earth-fixed coordinate z of the satellite in PZ-90.02 coordinate system [km] + d_VXn = 0.0; //!< Earth-fixed velocity coordinate x of the satellite in PZ-90.02 coordinate system [km/s] + d_VYn = 0.0; //!< Earth-fixed velocity coordinate y of the satellite in PZ-90.02 coordinate system [km/s] + d_VZn = 0.0; //!< Earth-fixed velocity coordinate z of the satellite in PZ-90.02 coordinate system [km/s] + d_AXn = 0.0; //!< Earth-fixed acceleration coordinate x of the satellite in PZ-90.02 coordinate system [km/s^2] + d_AYn = 0.0; //!< Earth-fixed acceleration coordinate y of the satellite in PZ-90.02 coordinate system [km/s^2] + d_AZn = 0.0; //!< Earth-fixed acceleration coordinate z of the satellite in PZ-90.02 coordinate system [km/s^2] + d_B_n = 0.0; //!< Health flag [dimensionless] + d_P = 0.0; //!< Technological parameter of control segment, indication the satellite operation mode in respect of time parameters [dimensionless] + d_N_T = 0.0; //!< Current date, calendar number of day within four-year interval starting from the 1-st of January in a leap year [days] + d_F_T = 0.0; //!< Parameter that provides the predicted satellite user range accuracy at time tb [dimensionless] + d_n = 0.0; //!< Index of the satellite transmitting given navigation signal. It corresponds to a slot number within GLONASS constellation + d_Delta_tau_n = 0.0; //!< Time difference between navigation RF signal transmitted in L2 sub- band and aviation RF signal transmitted in L1 sub-band by nth satellite. [dimensionless] + d_E_n = 0.0; //!< Characterises "age" of a current information [days] + d_P_1 = 0.0; //!< Flag of the immediate data updating [minutes] + d_P_2 = false; //!< Flag of oddness ("1") or evenness ("0") of the value of (tb) [dimensionless] + d_P_3 = false; //!< Flag indicating a number of satellites for which almanac is transmitted within given frame: "1" corresponds to 5 satellites and "0" corresponds to 4 satellites [dimensionless] + d_P_4 = false; //!< Flag to show that ephemeris parameters are present. "1" indicates that updated ephemeris or frequency/time parameters have been uploaded by the control segment [dimensionless] + d_l3rd_n = false; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] + d_l5th_n = false; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] + + // Satellite Identification Information + i_satellite_freq_channel = 0; //!< SV Frequency Channel Number + i_satellite_PRN = 0; //!< SV PRN Number, equivalent to slot number for compatibility with GPS + i_satellite_slot_number = 0; //!< SV Slot Number + d_yr = 1972; //!< Current year, defaults to 1972 (UTC Epoch with leap seconds) + d_satClkDrift = 0.0; //!< GLONASS clock error + d_dtr = 0.0; //!< relativistic clock correction term + d_iode = 0.0; //!< Issue of data, ephemeris (Bit 0-6 of tb) + d_tau_c = 0.0; + d_TOW = 0.0; // tow of the start of frame + d_WN = 0.0; // week number of the start of frame + d_tod = 0.0; +} + + +boost::posix_time::ptime Glonass_Gnav_Ephemeris::compute_GLONASS_time(const double offset_time) const +{ + boost::posix_time::time_duration t(0, 0, offset_time + d_tau_c + d_tau_n); + boost::gregorian::date d1(d_yr, 1, 1); + boost::gregorian::days d2(d_N_T - 1); + boost::posix_time::ptime glonass_time(d1+d2, t); + + return glonass_time; +} + + +boost::posix_time::ptime Glonass_Gnav_Ephemeris::glot_to_utc(const double offset_time, const double glot2utc_corr) const +{ + double tod = 0.0; + double glot2utc = 3*3600; + + tod = offset_time - glot2utc + glot2utc_corr + d_tau_n; + boost::posix_time::time_duration t(0, 0, tod); + boost::gregorian::date d1(d_yr, 1, 1); + boost::gregorian::days d2(d_N_T - 1); + boost::posix_time::ptime utc_time(d1 + d2, t); + + return utc_time; +} + + +void Glonass_Gnav_Ephemeris::glot_to_gpst(double tod_offset, double glot2utc_corr, double glot2gpst_corr, double * wn, double * tow) const +{ + double tod = 0.0; + double glot2utc = 3*3600; + double days = 0.0; + double total_sec = 0.0, sec_of_day = 0.0; + int i = 0; + + boost::gregorian::date gps_epoch { 1980, 1, 6 }; + + // tk is relative to UTC(SU) + 3.00 hrs, so we need to convert to utc and add corrections + // tk plus 10 sec is the true tod since get_TOW is called when in str5 + tod = tod_offset - glot2utc ; + + boost::posix_time::time_duration t(0, 0, tod); + boost::gregorian::date d1(d_yr, 1, 1); + boost::gregorian::days d2(d_N_T-1); + boost::posix_time::ptime utc_time(d1+d2, t); + boost::gregorian::date utc_date = utc_time.date(); + boost::posix_time::ptime gps_time; + + // Adjust for leap second correction + for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) + { + boost::posix_time::time_duration t3(GLONASS_LEAP_SECONDS[i][3], GLONASS_LEAP_SECONDS[i][4], GLONASS_LEAP_SECONDS[i][5]); + boost::gregorian::date d3(GLONASS_LEAP_SECONDS[i][0], GLONASS_LEAP_SECONDS[i][1], GLONASS_LEAP_SECONDS[i][2]); + boost::posix_time::ptime ls_time(d3, t3); + if (utc_time >= ls_time) + { + // We add the leap second when going from utc to gpst + gps_time = utc_time + boost::posix_time::time_duration(0,0,fabs(GLONASS_LEAP_SECONDS[i][6])); + break; + } + } + + // Total number of days + std::string fdat = boost::posix_time::to_simple_string(gps_time); + days = static_cast((utc_date - gps_epoch).days()); + + // Total number of seconds + sec_of_day = static_cast((gps_time.time_of_day()).total_seconds()); + total_sec = days*86400 + sec_of_day; + + // Compute Week number + *wn = floor(total_sec/604800); + + // Compute the arithmetic modules to wrap around range + *tow = total_sec - 604800*floor(total_sec/604800); + // Perform corrections from fractional seconds + *tow += glot2utc_corr + glot2gpst_corr; +} + + +double Glonass_Gnav_Ephemeris::check_t(double time) +{ + double corrTime; + double half_day = 43200.0; // seconds + corrTime = time; + if (time > half_day) + { + corrTime = time - 2.0 * half_day; + } + else if (time < -half_day) + { + corrTime = time + 2.0 * half_day; + } + return corrTime; +} + + +// FIXME Fix reference here +// 20.3.3.3.3.1 User Algorithm for SV Clock Correction. +double Glonass_Gnav_Ephemeris::sv_clock_drift(double transmitTime, double timeCorrUTC) +{ + double dt; + dt = check_t(transmitTime - d_t_b); + d_satClkDrift = -(d_tau_n + timeCorrUTC - d_gamma_n * dt); + //Correct satellite group delay and missing relativistic term here + //d_satClkDrift-=d_TGD; + + return d_satClkDrift; +} diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.h b/src/core/system_parameters/glonass_gnav_ephemeris.h new file mode 100644 index 000000000..cf43566e2 --- /dev/null +++ b/src/core/system_parameters/glonass_gnav_ephemeris.h @@ -0,0 +1,185 @@ +/*! + * \file glonass_gnav_ephemeris.h + * \brief Interface of a GLONASS EPHEMERIS storage + * \note Code added as part of GSoC 2017 program + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * \see GLONASS ICD + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (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 . + * + * ------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_GLONASS_GNAV_EPHEMERIS_H_ +#define GNSS_SDR_GLONASS_GNAV_EPHEMERIS_H_ + + +#include +#include + + + +/*! + * \brief This class is a storage and orbital model functions for the GLONASS SV ephemeris data as described in GLONASS ICD (Edition 5.1) + * \note Code added as part of GSoC 2017 program + * \see GLONASS ICD + */ +class Glonass_Gnav_Ephemeris +{ +private: + /* + * Accounts for the beginning or end of week crossover + * + * See paragraph 20.3.3.3.3.1 (IS-GPS-200E) + * \param[in] - time in seconds + * \param[out] - corrected time, in seconds + */ + double check_t(double time); + +public: + double d_m; //!< String number within frame [dimensionless] + double d_t_k; //!< GLONASS Time (UTC(SU) + 3 h) referenced to the beginning of the frame within the current day [s] + double d_t_b; //!< Reference ephemeris relative time in GLONASS Time (UTC(SU) + 3 h). Index of a time interval within current day according to UTC(SU) + 03 hours 00 min. [s] + double d_M; //!< Type of satellite transmitting navigation signal [dimensionless] + double d_gamma_n; //!< Relative deviation of predicted carrier frequency value of n- satellite from nominal value at the instant tb [dimensionless] + double d_tau_n; //!< Correction to the nth satellite time (tn) relative to GLONASS time (te), + double d_Xn; //!< Earth-fixed coordinate x of the satellite in PZ-90.02 coordinate system [km]. + double d_Yn; //!< Earth-fixed coordinate y of the satellite in PZ-90.02 coordinate system [km] + double d_Zn; //!< Earth-fixed coordinate z of the satellite in PZ-90.02 coordinate system [km] + double d_VXn; //!< Earth-fixed velocity coordinate x of the satellite in PZ-90.02 coordinate system [km/s] + double d_VYn; //!< Earth-fixed velocity coordinate y of the satellite in PZ-90.02 coordinate system [km/s] + double d_VZn; //!< Earth-fixed velocity coordinate z of the satellite in PZ-90.02 coordinate system [km/s] + double d_AXn; //!< Earth-fixed acceleration coordinate x of the satellite in PZ-90.02 coordinate system [km/s^2] + double d_AYn; //!< Earth-fixed acceleration coordinate y of the satellite in PZ-90.02 coordinate system [km/s^2] + double d_AZn; //!< Earth-fixed acceleration coordinate z of the satellite in PZ-90.02 coordinate system [km/s^2] + double d_B_n; //!< Health flag [dimensionless] + double d_P; //!< Technological parameter of control segment, indication the satellite operation mode in respect of time parameters [dimensionless] + double d_N_T; //!< Current date, calendar number of day within four-year interval starting from the 1-st of January in a leap year [days] + double d_F_T; //!< Parameter that provides the predicted satellite user range accuracy at time tb [dimensionless] + double d_n; //!< Index of the satellite transmitting given navigation signal. It corresponds to a slot number within GLONASS constellation + double d_Delta_tau_n; //!< Time difference between navigation RF signal transmitted in L2 sub- band and aviation RF signal transmitted in L1 sub-band by nth satellite. [dimensionless] + double d_E_n; //!< Characterises "age" of a current information [days] + double d_P_1; //!< Flag of the immediate data updating [minutes] + bool d_P_2; //!< Flag of oddness ("1") or evenness ("0") of the value of (tb) [dimensionless] + bool d_P_3; //!< Flag indicating a number of satellites for which almanac is transmitted within given frame: "1" corresponds to 5 satellites and "0" corresponds to 4 satellites [dimensionless] + bool d_P_4; //!< Flag to show that ephemeris parameters are present. "1" indicates that updated ephemeris or frequency/time parameters have been uploaded by the control segment [dimensionless] + bool d_l3rd_n; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is healthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] + bool d_l5th_n; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is healthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] + + // Inmediate deliverables of ephemeris information + // Satellite Identification Information + int i_satellite_freq_channel; //!< SV Frequency Channel Number + unsigned int i_satellite_PRN; //!< SV PRN Number, equivalent to slot number for compatibility with GPS + unsigned int i_satellite_slot_number; //!< SV Slot Number + double d_yr; //!< Current year + double d_satClkDrift; //!< GLONASS clock error + double d_dtr; //!< relativistic clock correction term + double d_iode; //!< Issue of data, ephemeris (Bit 0-6 of tb) + double d_tau_c; //!< GLONASST 2 UTC correction (todo) may be eliminated + double d_TOW; //!< GLONASST IN GPST seconds of week + double d_WN; //!< GLONASST IN GPST week number of the start of frame + double d_tod; //!< Time of Day since ephemeris where decoded + + template + + /*! + * \brief Serialize is a boost standard method to be called by the boost XML serialization. Here is used to save the ephemeris data on disk file. + */ + void serialize(Archive& archive, const unsigned int version) + { + using boost::serialization::make_nvp; + if(version){}; + + archive & make_nvp("i_satellite_freq_channel", i_satellite_freq_channel); //!< SV PRN frequency channel number + archive & make_nvp("i_satellite_PRN", i_satellite_PRN); + archive & make_nvp("i_satellite_slot_number", i_satellite_slot_number); + archive & make_nvp("d_m", d_m); //!< String number within frame [dimensionless] + archive & make_nvp("d_t_k", d_t_k); //!< Time referenced to the beginning of the frame within the current day [hours, minutes, seconds] + archive & make_nvp("d_t_b", d_t_b); //!< Index of a time interval within current day according to UTC(SU) + 03 hours 00 min. [minutes] + archive & make_nvp("d_M", d_M); //!< Type of satellite transmitting navigation signal [dimensionless] + archive & make_nvp("d_gamma_n", d_gamma_n); //!< Relative deviation of predicted carrier frequency value of n- satellite from nominal value at the instant tb [dimensionless] + archive & make_nvp("d_tau_n", d_tau_n); //!< Correction to the nth satellite time (tn) relative to GLONASS time (te) + archive & make_nvp("d_Xn", d_Xn); //!< Earth-fixed coordinate x of the satellite in PZ-90.02 coordinate system [km]. + archive & make_nvp("d_Yn", d_Yn); //!< Earth-fixed coordinate y of the satellite in PZ-90.02 coordinate system [km] + archive & make_nvp("d_Zn", d_Zn); //!< Earth-fixed coordinate z of the satellite in PZ-90.02 coordinate system [km] + archive & make_nvp("d_VXn", d_VXn); //!< Earth-fixed velocity coordinate x of the satellite in PZ-90.02 coordinate system [km/s] + archive & make_nvp("d_VYn", d_VYn); //!< Earth-fixed velocity coordinate y of the satellite in PZ-90.02 coordinate system [km/s] + archive & make_nvp("d_VZn", d_VZn); //!< Earth-fixed velocity coordinate z of the satellite in PZ-90.02 coordinate system [km/s] + archive & make_nvp("d_AXn", d_AXn); //!< Earth-fixed acceleration coordinate x of the satellite in PZ-90.02 coordinate system [km/s^2] + archive & make_nvp("d_AYn", d_AYn); //!< Earth-fixed acceleration coordinate y of the satellite in PZ-90.02 coordinate system [km/s^2] + archive & make_nvp("d_AZn", d_AZn); //!< Earth-fixed acceleration coordinate z of the satellite in PZ-90.02 coordinate system [km/s^2] + archive & make_nvp("d_B_n", d_B_n); //!< Health flag [dimensionless] + archive & make_nvp("d_P", d_P); //!< Technological parameter of control segment, indication the satellite operation mode in respect of time parameters [dimensionless] + archive & make_nvp("d_N_T", d_N_T); //!< Current date, calendar number of day within four-year interval starting from the 1-st of January in a leap year [days] + archive & make_nvp("d_F_T", d_F_T); //!< Parameter that provides the predicted satellite user range accuracy at time tb [dimensionless] + archive & make_nvp("d_n", d_n); //!< Index of the satellite transmitting given navigation signal. It corresponds to a slot number within GLONASS constellation + archive & make_nvp("d_Delta_tau_n", d_Delta_tau_n); //!< Time difference between navigation RF signal transmitted in L2 sub- band and aviation RF signal transmitted in L1 sub-band by nth satellite. [dimensionless] + archive & make_nvp("d_E_n", d_E_n); //!< Characterises "age" of a current information [days] + archive & make_nvp("d_P_1", d_P_1); //!< Flag of the immediate data updating. + archive & make_nvp("d_P_2", d_P_2); //!< Flag of oddness ("1") or evenness ("0") of the value of (tb) [dimensionless] + archive & make_nvp("d_P_3", d_P_3); //!< Flag indicating a number of satellites for which almanac is transmitted within given frame: "1" corresponds to 5 satellites and "0" corresponds to 4 satellites [dimensionless] + archive & make_nvp("d_P_4", d_P_4); //!< Flag to show that ephemeris parameters are present. "1" indicates that updated ephemeris or frequency/time parameters have been uploaded by the control segment [dimensionless] + archive & make_nvp("d_l3rd_n", d_l3rd_n); //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] + archive & make_nvp("d_l5th_n", d_l5th_n); //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] + } + + /*! + * \brief Sets (\a d_satClkDrift)and returns the clock drift in seconds according to the User Algorithm for SV Clock Correction + * (IS-GPS-200E, 20.3.3.3.3.1) + */ + double sv_clock_drift(double transmitTime, double timeCorrUTC); + + /*! + * \brief Computes the GLONASS System Time and returns a boost::posix_time::ptime object + * \ param offset_time Is the start of day offset to compute the time + */ + boost::posix_time::ptime compute_GLONASS_time(const double offset_time) const; + + /*! + * \brief Converts from GLONASST to UTC + * \details The function simply adjust for the 6 hrs offset between GLONASST and UTC + * \param[in] offset_time Is the start of day offset + * \param[in] glot2utc_corr Correction from GLONASST to UTC + * \returns UTC time as a boost::posix_time::ptime object + */ + boost::posix_time::ptime glot_to_utc(const double offset_time, const double glot2utc_corr) const; + + /*! + * \brief Converts from GLONASST to GPST + * \details Converts from GLONASST to GPST in time of week (TOW) and week number (WN) format + * \param[in] tod_offset Is the start of day offset + * \param[in] glot2utc_corr Correction from GLONASST to UTC + * \param[in] glot2gpst_corr Correction from GLONASST to GPST + * \param[out] WN Week Number, not in mod(1024) format + * \param[out] TOW Time of Week in seconds of week + */ + void glot_to_gpst(double tod_offset, double glot2utc_corr, double glot2gpst_corr, double * WN, double * TOW) const; + + /*! + * Default constructor + */ + Glonass_Gnav_Ephemeris(); +}; + +#endif diff --git a/src/core/system_parameters/glonass_gnav_navigation_message.cc b/src/core/system_parameters/glonass_gnav_navigation_message.cc new file mode 100644 index 000000000..40301ea09 --- /dev/null +++ b/src/core/system_parameters/glonass_gnav_navigation_message.cc @@ -0,0 +1,791 @@ +/*! + * \file glonass_gnav_navigation_message.cc + * \brief Implementation of a GLONASS GNAV Data message decoder as described in GLONASS ICD (Edition 5.1) + * \note Code added as part of GSoC 2017 program + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * \see GLONASS ICD + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "glonass_gnav_navigation_message.h" +#include +#include + + +void Glonass_Gnav_Navigation_Message::reset() +{ + // Satellite Identification + i_satellite_PRN = 0; + i_alm_satellite_slot_number = 0; //!< SV Orbit Slot Number + flag_update_slot_number = false; + + // Ephmeris Flags + flag_all_ephemeris = false; + flag_ephemeris_str_1 = false; + flag_ephemeris_str_2 = false; + flag_ephemeris_str_3 = false; + flag_ephemeris_str_4 = false; + + // Almanac Flags + flag_all_almanac = false; + flag_almanac_str_6 = false; + flag_almanac_str_7 = false; + flag_almanac_str_8 = false; + flag_almanac_str_9 = false; + flag_almanac_str_10 = false; + flag_almanac_str_11 = false; + flag_almanac_str_12 = false; + flag_almanac_str_13 = false; + flag_almanac_str_14 = false; + flag_almanac_str_15 = false; + + // UTC and System Clocks Flags + flag_utc_model_valid = false; //!< If set, it indicates that the UTC model parameters are filled + flag_utc_model_str_5 = false; //!< Clock info send in string 5 of navigation data + flag_utc_model_str_15 = false; //!< Clock info send in string 15 of frame 5 of navigation data + + // broadcast orbit 1 + flag_TOW_set = false; + flag_TOW_new = false; + + flag_CRC_test = false; + d_frame_ID = 0; + d_string_ID = 0; + i_channel_ID = 0; + + // Clock terms + d_satClkCorr = 0.0; + d_dtr = 0.0; + d_satClkDrift = 0.0; + + // Data update information + d_previous_tb = 0.0; + for(unsigned int i = 0; i < GLONASS_L1_CA_NBR_SATS; i++) + d_previous_Na[i] = 0.0; + + std::map satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus + + auto gnss_sat = Gnss_Satellite(); + std::string _system ("GLONASS"); + //TODO SHould number of channels be hardcoded? + for(unsigned int i = 1; i < 14; i++) + { + satelliteBlock[i] = gnss_sat.what_block(_system, i); + } +} + + +Glonass_Gnav_Navigation_Message::Glonass_Gnav_Navigation_Message() +{ + reset(); +} + + +bool Glonass_Gnav_Navigation_Message::CRC_test(std::bitset bits) +{ + int sum_bits = 0; + int sum_hamming = 0; + int C1 = 0; + int C2 = 0; + int C3 = 0; + int C4 = 0; + int C5 = 0; + int C6 = 0; + int C7 = 0; + int C_Sigma = 0; + std::vector string_bits(GLONASS_GNAV_STRING_BITS); + + //!< Populate data and hamming code vectors + for(int i = 0; i < static_cast(GLONASS_GNAV_STRING_BITS); i++) + { + string_bits[i] = static_cast(bits[i]); + } + + //!< Compute C1 term + sum_bits = 0; + for(int i = 0; i < static_cast(GLONASS_GNAV_CRC_I_INDEX.size()); i++) + { + sum_bits += string_bits[GLONASS_GNAV_CRC_I_INDEX[i]-1]; + } + C1 = string_bits[0]^(sum_bits%2); + + //!< Compute C2 term + sum_bits = 0; + for(int j = 0; j < static_cast(GLONASS_GNAV_CRC_J_INDEX.size()); j++) + { + sum_bits += string_bits[GLONASS_GNAV_CRC_J_INDEX[j]-1]; + } + C2 = (string_bits[1])^(sum_bits%2); + + //!< Compute C3 term + sum_bits = 0; + for(int k = 0; k < static_cast(GLONASS_GNAV_CRC_K_INDEX.size()); k++) + { + sum_bits += string_bits[GLONASS_GNAV_CRC_K_INDEX[k]-1]; + } + C3 = string_bits[2]^(sum_bits%2); + + //!< Compute C4 term + sum_bits = 0; + for(int l = 0; l < static_cast(GLONASS_GNAV_CRC_L_INDEX.size()); l++) + { + sum_bits += string_bits[GLONASS_GNAV_CRC_L_INDEX[l]-1]; + } + C4 = string_bits[3]^(sum_bits%2); + + //!< Compute C5 term + sum_bits = 0; + for(int m = 0; m < static_cast(GLONASS_GNAV_CRC_M_INDEX.size()); m++) + { + sum_bits += string_bits[GLONASS_GNAV_CRC_M_INDEX[m]-1]; + } + C5 = string_bits[4]^(sum_bits%2); + + //!< Compute C6 term + sum_bits = 0; + for(int n = 0; n < static_cast(GLONASS_GNAV_CRC_N_INDEX.size()); n++) + { + sum_bits += string_bits[GLONASS_GNAV_CRC_N_INDEX[n]-1]; + } + C6 = string_bits[5]^(sum_bits%2); + + //!< Compute C7 term + sum_bits = 0; + for(int p = 0; p < static_cast(GLONASS_GNAV_CRC_P_INDEX.size()); p++) + { + sum_bits += string_bits[GLONASS_GNAV_CRC_P_INDEX[p]-1]; + } + C7 = string_bits[6]^(sum_bits%2); + + //!< Compute C_Sigma term + sum_bits = 0; + sum_hamming = 0; + for(int q = 0; q < static_cast(GLONASS_GNAV_CRC_Q_INDEX.size()); q++) + { + sum_bits += string_bits[GLONASS_GNAV_CRC_Q_INDEX[q]-1]; + } + for(int q = 0; q < 8; q++) + { + sum_hamming += string_bits[q]; + } + C_Sigma = (sum_hamming%2)^(sum_bits%2); + + //!< Verification of the data + // (a-i) All checksums (C1,...,C7 and C_Sigma) are equal to zero + if((C1 + C2 + C3 + C4 + C5 + C6 + C7 + C_Sigma) == 0 ) + { + return true; + } + // (a-ii) Only one of the checksums (C1,...,C7) is equal to zero but C_Sigma = 1 + else if(C_Sigma == 1 && C1+C2+C3+C4+C5+C6+C7 == 6) + { + return true; + } + else + // All other conditions are assumed errors. TODO: Add correction for case B + { + return false; + } +} + + +bool Glonass_Gnav_Navigation_Message::read_navigation_bool(std::bitset bits, const std::vector> parameter) +{ + bool value; + + if (bits[GLONASS_GNAV_STRING_BITS - parameter[0].first] == 1) + { + value = true; + } + else + { + value = false; + } + return value; +} + + +unsigned long int Glonass_Gnav_Navigation_Message::read_navigation_unsigned(std::bitset bits, const std::vector> parameter) +{ + unsigned long int value = 0; + int num_of_slices = parameter.size(); + for (int i = 0; i < num_of_slices; i++) + { + for (int j = 0; j < parameter[i].second; j++) + { + value <<= 1; //shift left + if (bits[GLONASS_GNAV_STRING_BITS - parameter[i].first - j] == 1) + { + value += 1; // insert the bit + } + } + } + return value; +} + + +signed long int Glonass_Gnav_Navigation_Message::read_navigation_signed(std::bitset bits, const std::vector> parameter) +{ + signed long int value = 0; + signed long int sign = 0; + int num_of_slices = parameter.size(); + // read the MSB and perform the sign extension + if (bits[GLONASS_GNAV_STRING_BITS - parameter[0].first] == 1) + { + sign = -1; + } + else + { + sign = 1; + } + for (int i = 0; i < num_of_slices; i++) + { + for (int j = 1; j < parameter[i].second; j++) + { + value <<= 1; //shift left + if (bits[GLONASS_GNAV_STRING_BITS - parameter[i].first - j] == 1) + { + value += 1; // insert the bit + } + } + } + return (sign*value); +} + + +unsigned int Glonass_Gnav_Navigation_Message::get_frame_number(unsigned int satellite_slot_number) +{ + unsigned int frame_ID = 0; + + if(satellite_slot_number >= 1 and satellite_slot_number <= 5 ) + { + frame_ID = 1; + } + else if(satellite_slot_number >= 6 and satellite_slot_number <= 10 ) + { + frame_ID = 2; + } + else if(satellite_slot_number >= 11 and satellite_slot_number <= 15 ) + { + frame_ID = 3; + } + else if(satellite_slot_number >= 16 and satellite_slot_number <= 20 ) + { + frame_ID = 4; + } + else if(satellite_slot_number >= 21 and satellite_slot_number <= 24 ) + { + frame_ID = 5; + } + else + { + LOG(WARNING) << "GLONASS GNAV: Invalid Satellite Slot Number"; + frame_ID = 0; + } + + return frame_ID; +} + + +int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) +{ + int J = 0; + d_string_ID = 0; + d_frame_ID = 0; + + // Unpack bytes to bits + std::bitset string_bits (frame_string); + + // Perform data verification and exit code if error in bit sequence + flag_CRC_test = CRC_test(string_bits); + if(flag_CRC_test == false) + return 0; + + // Decode all 15 string messages + d_string_ID = static_cast(read_navigation_unsigned(string_bits, STRING_ID)); + switch (d_string_ID) + { + case 1: + //--- It is string 1 ----------------------------------------------- + gnav_ephemeris.d_P_1 = (static_cast(read_navigation_unsigned(string_bits, P1)) + 1) * 15; + gnav_ephemeris.d_t_k = static_cast(read_navigation_unsigned(string_bits, T_K_HR)) * 3600 + + static_cast(read_navigation_unsigned(string_bits, T_K_MIN)) * 60 + + static_cast(read_navigation_unsigned(string_bits, T_K_SEC)) * 30; + gnav_ephemeris.d_VXn = static_cast(read_navigation_signed(string_bits, X_N_DOT)) * TWO_N20; + gnav_ephemeris.d_AXn = static_cast(read_navigation_signed(string_bits, X_N_DOT_DOT)) * TWO_N30; + gnav_ephemeris.d_Xn = static_cast(read_navigation_signed(string_bits, X_N)) * TWO_N11; + + flag_ephemeris_str_1 = true; + + break; + + case 2: + //--- It is string 2 ----------------------------------------------- + if (flag_ephemeris_str_1 == true) + { + gnav_ephemeris.d_B_n = static_cast(read_navigation_unsigned(string_bits, B_N)); + gnav_ephemeris.d_P_2 = static_cast(read_navigation_bool(string_bits, P2)); + gnav_ephemeris.d_t_b = static_cast(read_navigation_unsigned(string_bits, T_B)) * 15 * 60; + gnav_ephemeris.d_VYn = static_cast(read_navigation_signed(string_bits, Y_N_DOT)) * TWO_N20; + gnav_ephemeris.d_AYn = static_cast(read_navigation_signed(string_bits, Y_N_DOT_DOT)) * TWO_N30; + gnav_ephemeris.d_Yn = static_cast(read_navigation_signed(string_bits, Y_N)) * TWO_N11; + + gnav_ephemeris.d_iode = read_navigation_unsigned(string_bits, T_B); + flag_ephemeris_str_2 = true; + } + + break; + + case 3: + // --- It is string 3 ---------------------------------------------- + if (flag_ephemeris_str_2 == true) + { + gnav_ephemeris.d_P_3 = static_cast(read_navigation_bool(string_bits, P3)); + gnav_ephemeris.d_gamma_n = static_cast(read_navigation_signed(string_bits, GAMMA_N)) * TWO_N40; + gnav_ephemeris.d_P = static_cast(read_navigation_unsigned(string_bits, P)); + gnav_ephemeris.d_l3rd_n = static_cast(read_navigation_bool(string_bits, EPH_L_N)); + gnav_ephemeris.d_VZn = static_cast(read_navigation_signed(string_bits, Z_N_DOT)) * TWO_N20; + gnav_ephemeris.d_AZn = static_cast(read_navigation_signed(string_bits, Z_N_DOT_DOT)) * TWO_N30; + gnav_ephemeris.d_Zn = static_cast(read_navigation_signed(string_bits, Z_N)) * TWO_N11; + + flag_ephemeris_str_3 = true; + } + + break; + + case 4: + // --- It is string 4 ---------------------------------------------- + if (flag_ephemeris_str_3 == true) + { + gnav_ephemeris.d_tau_n = static_cast(read_navigation_signed(string_bits, TAU_N)) * TWO_N30; + gnav_ephemeris.d_Delta_tau_n = static_cast(read_navigation_signed(string_bits, DELTA_TAU_N)) * TWO_N30; + gnav_ephemeris.d_E_n = static_cast(read_navigation_unsigned(string_bits, E_N)); + gnav_ephemeris.d_P_4 = static_cast(read_navigation_bool(string_bits, P4)); + gnav_ephemeris.d_F_T = static_cast(read_navigation_unsigned(string_bits, F_T)); + gnav_ephemeris.d_N_T = static_cast(read_navigation_unsigned(string_bits, N_T)); + gnav_ephemeris.d_n = static_cast(read_navigation_unsigned(string_bits, N)); + gnav_ephemeris.d_M = static_cast(read_navigation_unsigned(string_bits, M)); + + // Fill in ephemeris deliverables in the code + flag_update_slot_number = true; + gnav_ephemeris.i_satellite_slot_number = static_cast(gnav_ephemeris.d_n); + gnav_ephemeris.i_satellite_PRN = static_cast(gnav_ephemeris.d_n); + + flag_ephemeris_str_4 = true; + } + + break; + + case 5: + // --- It is string 5 ---------------------------------------------- + if (flag_ephemeris_str_4 == true) + { + gnav_utc_model.d_N_A = static_cast(read_navigation_unsigned(string_bits, N_A)); + gnav_utc_model.d_tau_c = static_cast(read_navigation_signed(string_bits, TAU_C)) * TWO_N31; + gnav_utc_model.d_N_4 = static_cast(read_navigation_unsigned(string_bits, N_4)); + gnav_utc_model.d_tau_gps = static_cast(read_navigation_signed(string_bits, TAU_GPS)) * TWO_N30; + gnav_ephemeris.d_l5th_n = static_cast(read_navigation_bool(string_bits, ALM_L_N)); + + flag_utc_model_str_5 = true; + + // Compute Year and DoY based on Algorithm A3.11 of GLONASS ICD + // 1). Current year number J in the four-year interval is calculated + if (gnav_ephemeris.d_N_T >= 1 && gnav_ephemeris.d_N_T <= 366) + { + J = 1; + } + else if (gnav_ephemeris.d_N_T >= 367 && gnav_ephemeris.d_N_T <= 731) + { + J = 2; + } + else if (gnav_ephemeris.d_N_T >= 732 && gnav_ephemeris.d_N_T <= 1096) + { + J = 3; + } + else if (gnav_ephemeris.d_N_T >= 1097 && gnav_ephemeris.d_N_T <= 1461) + { + J = 4; + } + // 2). Current year in common form is calculated by the following formula: + gnav_ephemeris.d_yr = 1996 + 4.0 * (gnav_utc_model.d_N_4 - 1.0) + (J - 1.0); + gnav_ephemeris.d_tau_c = gnav_utc_model.d_tau_c; + + // 3). Set TOW once the year has been defined, it helps with leap second determination + if (flag_ephemeris_str_1 == true) + { + gnav_ephemeris.glot_to_gpst(gnav_ephemeris.d_t_k+10, gnav_utc_model.d_tau_c, gnav_utc_model.d_tau_gps, &gnav_ephemeris.d_WN, &gnav_ephemeris.d_TOW); + flag_TOW_set = true; + flag_TOW_new = true; + } + + // 4) Set time of day (tod) when ephemeris data is complety decoded + gnav_ephemeris.d_tod = gnav_ephemeris.d_t_k + 2*d_string_ID; + } + + break; + + case 6: + // --- It is string 6 ---------------------------------------------- + i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); + d_frame_ID = get_frame_number(i_alm_satellite_slot_number); + // Make sure a valid frame_ID or satellite slot number is returned + if(d_frame_ID == 0) + return 0; + + gnav_almanac[i_alm_satellite_slot_number - 1].d_C_n = static_cast(read_navigation_bool(string_bits, C_N)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_M_n_A = static_cast(read_navigation_unsigned(string_bits, M_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A = static_cast(read_navigation_unsigned(string_bits, n_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_tau_n_A = static_cast(read_navigation_unsigned(string_bits, TAU_N_A)) * TWO_N18; + gnav_almanac[i_alm_satellite_slot_number - 1].d_lambda_n_A = static_cast(read_navigation_signed(string_bits, LAMBDA_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_i_n_A = static_cast(read_navigation_signed(string_bits, DELTA_I_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_epsilon_n_A = static_cast(read_navigation_unsigned(string_bits, EPSILON_N_A)) * TWO_N20; + + flag_almanac_str_6 = true; + + break; + + case 7: + // --- It is string 7 ---------------------------------------------- + if (flag_almanac_str_6 == true) + { + gnav_almanac[i_alm_satellite_slot_number - 1].d_omega_n_A = static_cast(read_navigation_signed(string_bits, OMEGA_N_A)) * TWO_N15 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_t_lambda_n_A = static_cast(read_navigation_unsigned(string_bits, T_LAMBDA_N_A)) * TWO_N5; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A = static_cast(read_navigation_signed(string_bits, DELTA_T_N_A)) * TWO_N9; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A_dot = static_cast(read_navigation_signed(string_bits, DELTA_T_DOT_N_A)) * TWO_N14; + gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A = static_cast(read_navigation_unsigned(string_bits, H_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_l_n = static_cast(read_navigation_bool(string_bits, ALM_L_N)); + + // Set satellite information for redundancy purposes + if (gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A > 24) + { + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_freq_channel = gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A - 32.0; + } + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_slot_number = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_PRN = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + + if (i_alm_satellite_slot_number == gnav_ephemeris.i_satellite_slot_number) + { + gnav_ephemeris.i_satellite_freq_channel = gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_freq_channel; + } + flag_almanac_str_7 = true; + } + + break; + + case 8: + // --- It is string 8 ---------------------------------------------- + i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); + d_frame_ID = get_frame_number(i_alm_satellite_slot_number); + // Make sure a valid frame_ID or satellite slot number is returned + if(d_frame_ID == 0) + return 0; + + gnav_almanac[i_alm_satellite_slot_number - 1].d_C_n = static_cast(read_navigation_bool(string_bits, C_N)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_M_n_A = static_cast(read_navigation_unsigned(string_bits, M_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A = static_cast(read_navigation_unsigned(string_bits, n_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_tau_n_A = static_cast(read_navigation_unsigned(string_bits, TAU_N_A)) * TWO_N18; + gnav_almanac[i_alm_satellite_slot_number - 1].d_lambda_n_A = static_cast(read_navigation_signed(string_bits, LAMBDA_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_i_n_A = static_cast(read_navigation_signed(string_bits, DELTA_I_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_epsilon_n_A = static_cast(read_navigation_unsigned(string_bits, EPSILON_N_A)) * TWO_N20; + + flag_almanac_str_8 = true; + + break; + + case 9: + // --- It is string 9 ---------------------------------------------- + if (flag_almanac_str_8 == true) + { + gnav_almanac[i_alm_satellite_slot_number - 1].d_omega_n_A = static_cast(read_navigation_signed(string_bits, OMEGA_N_A)) * TWO_N15 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_t_lambda_n_A = static_cast(read_navigation_unsigned(string_bits, T_LAMBDA_N_A)) * TWO_N5; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A = static_cast(read_navigation_signed(string_bits, DELTA_T_N_A)) * TWO_N9; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A_dot = static_cast(read_navigation_signed(string_bits, DELTA_T_DOT_N_A)) * TWO_N14; + gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A = static_cast(read_navigation_unsigned(string_bits, H_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_l_n = static_cast(read_navigation_bool(string_bits, ALM_L_N)); + + // Set satellite information for redundancy purposes + if (gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A > 24) + { + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_freq_channel = gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A - 32.0; + } + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_slot_number = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_PRN = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + + flag_almanac_str_9 = true; + } + break; + + case 10: + // --- It is string 10 --------------------------------------------- + i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); + d_frame_ID = get_frame_number(i_alm_satellite_slot_number); + // Make sure a valid frame_ID or satellite slot number is returned + if(d_frame_ID == 0) + return 0; + + gnav_almanac[i_alm_satellite_slot_number - 1].d_C_n = static_cast(read_navigation_bool(string_bits, C_N)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_M_n_A = static_cast(read_navigation_unsigned(string_bits, M_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A = static_cast(read_navigation_unsigned(string_bits, n_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_tau_n_A = static_cast(read_navigation_unsigned(string_bits, TAU_N_A)) * TWO_N18; + gnav_almanac[i_alm_satellite_slot_number - 1].d_lambda_n_A = static_cast(read_navigation_signed(string_bits, LAMBDA_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_i_n_A = static_cast(read_navigation_signed(string_bits, DELTA_I_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_epsilon_n_A = static_cast(read_navigation_unsigned(string_bits, EPSILON_N_A)) * TWO_N20; + + flag_almanac_str_10 = true; + + break; + + case 11: + // --- It is string 11 --------------------------------------------- + if (flag_almanac_str_10 == true) + { + gnav_almanac[i_alm_satellite_slot_number - 1].d_omega_n_A = static_cast(read_navigation_signed(string_bits, OMEGA_N_A)) * TWO_N15 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_t_lambda_n_A = static_cast(read_navigation_unsigned(string_bits, T_LAMBDA_N_A)) * TWO_N5; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A = static_cast(read_navigation_signed(string_bits, DELTA_T_N_A)) * TWO_N9; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A_dot = static_cast(read_navigation_signed(string_bits, DELTA_T_DOT_N_A)) * TWO_N14; + gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A = static_cast(read_navigation_unsigned(string_bits, H_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_l_n = static_cast(read_navigation_bool(string_bits, ALM_L_N)); + + // Set satellite information for redundancy purposes + if (gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A > 24) + { + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_freq_channel = gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A - 32.0; + } + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_slot_number = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_PRN = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + + flag_almanac_str_11 = true; + } + break; + + case 12: + // --- It is string 12 --------------------------------------------- + i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); + d_frame_ID = get_frame_number(i_alm_satellite_slot_number); + // Make sure a valid frame_ID or satellite slot number is returned + if(d_frame_ID == 0) + return 0; + gnav_almanac[i_alm_satellite_slot_number - 1].d_C_n = static_cast(read_navigation_bool(string_bits, C_N)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_M_n_A = static_cast(read_navigation_unsigned(string_bits, M_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A = static_cast(read_navigation_unsigned(string_bits, n_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_tau_n_A = static_cast(read_navigation_unsigned(string_bits, TAU_N_A)) * TWO_N18; + gnav_almanac[i_alm_satellite_slot_number - 1].d_lambda_n_A = static_cast(read_navigation_signed(string_bits, LAMBDA_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_i_n_A = static_cast(read_navigation_signed(string_bits, DELTA_I_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_epsilon_n_A = static_cast(read_navigation_unsigned(string_bits, EPSILON_N_A)) * TWO_N20; + + flag_almanac_str_12 = true; + + break; + + case 13: + // --- It is string 13 --------------------------------------------- + if (flag_almanac_str_12 == true) + { + gnav_almanac[i_alm_satellite_slot_number - 1].d_omega_n_A = static_cast(read_navigation_signed(string_bits, OMEGA_N_A)) * TWO_N15 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_t_lambda_n_A = static_cast(read_navigation_unsigned(string_bits, T_LAMBDA_N_A)) * TWO_N5; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A = static_cast(read_navigation_signed(string_bits, DELTA_T_N_A)) * TWO_N9; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A_dot = static_cast(read_navigation_signed(string_bits, DELTA_T_DOT_N_A)) * TWO_N14; + gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A = static_cast(read_navigation_unsigned(string_bits, H_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_l_n = static_cast(read_navigation_bool(string_bits, ALM_L_N)); + + // Set satellite information for redundancy purposes + if (gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A > 24) + { + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_freq_channel = gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A - 32.0; + } + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_slot_number = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_PRN = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + + flag_almanac_str_13 = true; + } + break; + + case 14: + // --- It is string 14 --------------------------------------------- + if (d_frame_ID == 5) + { + gnav_utc_model.d_B1 = static_cast(read_navigation_unsigned(string_bits, B1)); + gnav_utc_model.d_B2 = static_cast(read_navigation_unsigned(string_bits, B2)); + } + else + { + i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); + d_frame_ID = get_frame_number(i_alm_satellite_slot_number); + // Make sure a valid frame_ID or satellite slot number is returned + if(d_frame_ID == 0) + return 0; + gnav_almanac[i_alm_satellite_slot_number - 1].d_C_n = static_cast(read_navigation_bool(string_bits, C_N)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_M_n_A = static_cast(read_navigation_unsigned(string_bits, M_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A = static_cast(read_navigation_unsigned(string_bits, n_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_tau_n_A = static_cast(read_navigation_unsigned(string_bits, TAU_N_A)) * TWO_N18; + gnav_almanac[i_alm_satellite_slot_number - 1].d_lambda_n_A = static_cast(read_navigation_signed(string_bits, LAMBDA_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_i_n_A = static_cast(read_navigation_signed(string_bits, DELTA_I_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_epsilon_n_A = static_cast(read_navigation_unsigned(string_bits, EPSILON_N_A)) * TWO_N20; + + flag_almanac_str_14 = true; + } + break; + + case 15: + // --- It is string 15 ---------------------------------------------- + if (d_frame_ID != 5 and flag_almanac_str_14 == true) { + gnav_almanac[i_alm_satellite_slot_number - 1].d_omega_n_A = static_cast(read_navigation_signed(string_bits, OMEGA_N_A)) * TWO_N15 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_t_lambda_n_A = static_cast(read_navigation_unsigned(string_bits, T_LAMBDA_N_A)) * TWO_N5; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A = static_cast(read_navigation_signed(string_bits, DELTA_T_N_A)) * TWO_N9; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A_dot = static_cast(read_navigation_signed(string_bits, DELTA_T_DOT_N_A)) * TWO_N14; + gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A = static_cast(read_navigation_unsigned(string_bits, H_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_l_n = static_cast(read_navigation_bool(string_bits, ALM_L_N)); + + // Set satellite information for redundancy purposes + if (gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A > 24) + { + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_freq_channel = gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A - 32.0; + } + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_slot_number = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_PRN = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + + flag_almanac_str_15 = true; + } + break; + default: + LOG(INFO) << "GLONASS GNAV: Invalid String ID of received. Received " << d_string_ID + << ", but acceptable range is from 1-15"; + + break; + } // switch string ID + + return d_string_ID; +} + + +Glonass_Gnav_Ephemeris Glonass_Gnav_Navigation_Message::get_ephemeris() +{ + return gnav_ephemeris; +} + + +Glonass_Gnav_Utc_Model Glonass_Gnav_Navigation_Message::get_utc_model() +{ + return gnav_utc_model; +} + + +Glonass_Gnav_Almanac Glonass_Gnav_Navigation_Message::get_almanac(unsigned int satellite_slot_number) +{ + return gnav_almanac[satellite_slot_number - 1]; +} + + +bool Glonass_Gnav_Navigation_Message::have_new_ephemeris() //Check if we have a new ephemeris stored in the galileo navigation class +{ + bool new_eph = false; + // We need to make sure we have received the ephemeris info plus the time info + if ((flag_ephemeris_str_1 == true) and (flag_ephemeris_str_2 == true) and + (flag_ephemeris_str_3 == true) and (flag_ephemeris_str_4 == true) and + (flag_utc_model_str_5 == true)) + { + if(d_previous_tb != gnav_ephemeris.d_t_b) + { + flag_ephemeris_str_1 = false;// clear the flag + flag_ephemeris_str_2 = false;// clear the flag + flag_ephemeris_str_3 = false;// clear the flag + flag_ephemeris_str_4 = false;// clear the flag + flag_all_ephemeris = true; + // Update the time of ephemeris information + d_previous_tb = gnav_ephemeris.d_t_b; + DLOG(INFO) << "GLONASS GNAV Ephemeris (1, 2, 3, 4) have been received and belong to the same batch" << std::endl; + new_eph = true; + } + } + + return new_eph; +} + + +bool Glonass_Gnav_Navigation_Message::have_new_utc_model() // Check if we have a new utc data set stored in the galileo navigation class +{ + if (flag_utc_model_str_5 == true) + { + flag_utc_model_str_5 = false; // clear the flag + return true; + } + else + return false; +} + + +bool Glonass_Gnav_Navigation_Message::have_new_almanac() //Check if we have a new almanac data set stored in the galileo navigation class +{ + bool new_alm = false; + if ((flag_almanac_str_6 == true) and (flag_almanac_str_7 == true)) + { + if (d_previous_Na[i_alm_satellite_slot_number] != gnav_utc_model.d_N_A) + { + //All almanac have been received for this satellite + flag_almanac_str_6 = false; + flag_almanac_str_7 = false; + new_alm = true; + } + } + if ((flag_almanac_str_8 == true) and (flag_almanac_str_9 == true)) + { + if (d_previous_Na[i_alm_satellite_slot_number] != gnav_utc_model.d_N_A) + { + flag_almanac_str_8 = false; + flag_almanac_str_9 = false; + new_alm = true; + } + } + if((flag_almanac_str_10 == true) and (flag_almanac_str_11 == true)) + { + if (d_previous_Na[i_alm_satellite_slot_number] != gnav_utc_model.d_N_A) + { + flag_almanac_str_10 = false; + flag_almanac_str_11 = false; + new_alm = true; + } + } + if((flag_almanac_str_12 == true) and (flag_almanac_str_13 == true)) + { + if (d_previous_Na[i_alm_satellite_slot_number] != gnav_utc_model.d_N_A) + { + flag_almanac_str_12 = false; + flag_almanac_str_13 = false; + new_alm = true; + } + } + if((flag_almanac_str_14 == true) and (flag_almanac_str_15 == true)) + { + if (d_previous_Na[i_alm_satellite_slot_number] != gnav_utc_model.d_N_A) + { + flag_almanac_str_14 = false; + flag_almanac_str_15 = false; + new_alm = true; + } + } + + return new_alm; +} diff --git a/src/core/system_parameters/glonass_gnav_navigation_message.h b/src/core/system_parameters/glonass_gnav_navigation_message.h new file mode 100644 index 000000000..6aef9ad51 --- /dev/null +++ b/src/core/system_parameters/glonass_gnav_navigation_message.h @@ -0,0 +1,170 @@ +/*! + * \file glonass_gnav_navigation_message.h + * \brief Interface of a GLONASS GNAV Data message decoder as described in GLONASS ICD (Edition 5.1) + * \note Code added as part of GSoC 2017 program + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * \see GLONASS ICD + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (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 . + * + * ------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_GLONASS_GNAV_NAVIGATION_MESSAGE_H_ +#define GNSS_SDR_GLONASS_GNAV_NAVIGATION_MESSAGE_H_ + + +#include +#include "GLONASS_L1_CA.h" +#include "glonass_gnav_ephemeris.h" +#include "glonass_gnav_almanac.h" +#include "glonass_gnav_utc_model.h" + + + +/*! + * \brief This class decodes a GLONASS GNAV Data message as described in GLONASS ICD (Edition 5.1) + * \note Code added as part of GSoC 2017 program + * \see GLONASS ICD + */ +class Glonass_Gnav_Navigation_Message +{ +private: + unsigned long int read_navigation_unsigned(std::bitset bits, const std::vector> parameter); + signed long int read_navigation_signed(std::bitset bits, const std::vector> parameter); + bool read_navigation_bool(std::bitset bits, const std::vector> parameter); + +public: + bool flag_CRC_test; + unsigned int d_frame_ID; + unsigned int d_string_ID; + bool flag_update_slot_number; + + int i_channel_ID; + unsigned int i_satellite_PRN; + + Glonass_Gnav_Ephemeris gnav_ephemeris; //!< Ephemeris information decoded + Glonass_Gnav_Utc_Model gnav_utc_model; //!< UTC model information + Glonass_Gnav_Almanac gnav_almanac[GLONASS_L1_CA_NBR_SATS]; //!< Almanac information for all 24 satellites + + // Ephemeris Flags and control variables + bool flag_all_ephemeris; //!< Flag indicating that all strings containing ephemeris have been received + bool flag_ephemeris_str_1; //!< Flag indicating that ephemeris 1/4 (string 1) have been received + bool flag_ephemeris_str_2; //!< Flag indicating that ephemeris 2/4 (string 2) have been received + bool flag_ephemeris_str_3; //!< Flag indicating that ephemeris 3/4 (string 3) have been received + bool flag_ephemeris_str_4; //!< Flag indicating that ephemeris 4/4 (string 4) have been received + + // Almanac Flags + bool flag_all_almanac; //!< Flag indicating that all almanac have been received + bool flag_almanac_str_6; //!< Flag indicating that almanac of string 6 have been received + bool flag_almanac_str_7; //!< Flag indicating that almanac of string 7 have been received + bool flag_almanac_str_8; //!< Flag indicating that almanac of string 8 have been received + bool flag_almanac_str_9; //!< Flag indicating that almanac of string 9 have been received + bool flag_almanac_str_10; //!< Flag indicating that almanac of string 10 have been received + bool flag_almanac_str_11; //!< Flag indicating that almanac of string 11 have been received + bool flag_almanac_str_12; //!< Flag indicating that almanac of string 12 have been received + bool flag_almanac_str_13; //!< Flag indicating that almanac of string 13 have been received + bool flag_almanac_str_14; //!< Flag indicating that almanac of string 14 have been received + bool flag_almanac_str_15; //!< Flag indicating that almanac of string 15 have been received + unsigned int i_alm_satellite_slot_number; //!< SV Orbit Slot Number + + // UTC and System Clocks Flags + bool flag_utc_model_valid; //!< If set, it indicates that the UTC model parameters are filled + bool flag_utc_model_str_5; //!< Clock info send in string 5 of navigation data + bool flag_utc_model_str_15; //!< Clock info send in string 15 of frame 5 of navigation data + + bool flag_TOW_set; //!< Flag indicating when the TOW has been set + bool flag_TOW_new; //!< Flag indicating when a new TOW has been computed + + double d_satClkCorr; //!< Satellite clock error + double d_dtr; //!< Relativistic clock correction term + double d_satClkDrift; //!< Satellite clock drift + + double d_previous_tb; //!< Previous iode for the Glonass_Gnav_Ephemeris object. Used to determine when new data arrives + double d_previous_Na[GLONASS_L1_CA_NBR_SATS]; //!< Previous time for almanac of the Glonass_Gnav_Almanac object + + /*! + * \brief Compute CRC for GLONASS GNAV strings + * \param bits Bits of the string message where to compute CRC + */ + bool CRC_test(std::bitset bits); + + /*! + * \brief Computes the frame number being decoded given the satellite slot number + * \param satellite_slot_number [in] Satellite slot number identifier + * \returns Frame number being decoded, 0 if operation was not successful. + */ + unsigned int get_frame_number(unsigned int satellite_slot_number); + + /*! + * \brief Reset GLONASS GNAV Navigation Information + */ + void reset(); + + /*! + * \brief Obtain a GLONASS GNAV SV Ephemeris class filled with current SV data + */ + Glonass_Gnav_Ephemeris get_ephemeris(); + + /*! + * \brief Obtain a GLONASS GNAV UTC model parameters class filled with current SV data + */ + Glonass_Gnav_Utc_Model get_utc_model(); + + /*! + * \brief Returns a Glonass_Gnav_Almanac object filled with the latest navigation data received + * \param satellite_slot_number Slot number identifier for the satellite + * \returns Returns the Glonass_Gnav_Almanac object for the input slot number + */ + Glonass_Gnav_Almanac get_almanac(unsigned int satellite_slot_number); + + /*! + * \brief Returns true if a new Glonass_Gnav_Ephemeris object has arrived. + */ + bool have_new_ephemeris(); + + /*! + * \brief Returns true if new Glonass_Gnav_Utc_Model object has arrived + */ + bool have_new_utc_model(); + + /*! + * \brief Returns true if new Glonass_Gnav_Almanac object has arrived. + */ + bool have_new_almanac(); + + /*! + * \brief Decodes the GLONASS GNAV string + * \param frame_string [in] is the string message within the parsed frame + * \returns Returns the ID of the decoded string + */ + int string_decoder(std::string frame_string); + + /*! + * Default constructor + */ + Glonass_Gnav_Navigation_Message(); +}; + +#endif diff --git a/src/core/system_parameters/glonass_gnav_utc_model.cc b/src/core/system_parameters/glonass_gnav_utc_model.cc new file mode 100644 index 000000000..ec9d5e20e --- /dev/null +++ b/src/core/system_parameters/glonass_gnav_utc_model.cc @@ -0,0 +1,55 @@ +/* + * \file glonass_gnav_utc_model.h + * \brief Interface of a GLONASS GNAV UTC MODEL storage + * \note Code added as part of GSoC 2017 program + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * \see GLONASS ICD + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "glonass_gnav_utc_model.h" +#include + +Glonass_Gnav_Utc_Model::Glonass_Gnav_Utc_Model() +{ + valid = false; + d_tau_c = 0.0; + d_tau_gps = 0.0; + d_N_4 = 0.0; + d_N_A = 0.0; + d_B1 = 0.0; + d_B2 = 0.0; +} + +double Glonass_Gnav_Utc_Model::utc_time(double glonass_time_corrected) +{ + double t_utc; + + // GLONASS Time is relative to UTC Moscow, so we simply add its time difference + t_utc = glonass_time_corrected + 3*3600 + d_tau_c; + + return t_utc; +} diff --git a/src/core/system_parameters/glonass_gnav_utc_model.h b/src/core/system_parameters/glonass_gnav_utc_model.h new file mode 100644 index 000000000..9e84762d6 --- /dev/null +++ b/src/core/system_parameters/glonass_gnav_utc_model.h @@ -0,0 +1,88 @@ +/*! + * \file glonass_gnav_utc_model.h + * \brief Interface of a GLONASS GNAV UTC MODEL storage + * \note Code added as part of GSoC 2017 program + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * \see GLONASS ICD + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (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 . + * + * ------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_GLONASS_GNAV_UTC_MODEL_H_ +#define GNSS_SDR_GLONASS_GNAV_UTC_MODEL_H_ + +#include "boost/assign.hpp" +#include +#include + +/*! + * \brief This class is a storage for the GLONASS GNAV UTC MODEL data as described in GLONASS ICD (Edition 5.1) + * \note Code added as part of GSoC 2017 program + * \see GLONASS ICD + */ +class Glonass_Gnav_Utc_Model +{ +public: + bool valid; + // Clock Parameters + double d_tau_c; //!< GLONASS time scale correction to UTC(SU) time. [s] + double d_tau_gps; //!< Correction to GPS time to GLONASS time [day] + double d_N_4; //!< Four year interval number starting from 1996 [4 year interval] + double d_N_A; //!< Calendar day number within the four-year period beginning since the leap year for Almanac data [days] + double d_B1; //!< Coefficient to determine DeltaUT1 [s] + double d_B2; //!< Coefficient to determine DeltaUT1 [s/msd] + + template + /*! + * \brief Serialize is a boost standard method to be called by the boost XML serialization. Here is used to save the almanac data on disk file. + */ + void serialize(Archive& archive, const unsigned int version) + { + using boost::serialization::make_nvp; + if(version){}; + archive & make_nvp("valid",valid); + archive & make_nvp("d_tau_c", d_tau_c); + archive & make_nvp("d_tau_gps", d_tau_gps); + archive & make_nvp("d_N_4", d_N_4); + archive & make_nvp("d_N_A", d_N_A); + archive & make_nvp("d_B1", d_B1); + archive & make_nvp("d_B2", d_B2); + } + + /*! + * Default constructor + */ + Glonass_Gnav_Utc_Model(); + + /*! + * \brief Computes the Coordinated Universal Time (UTC) and + * returns it in [s] (GLONASS ICD (Edition 5.1) Section 3.3.3 GLONASS Time) + */ + double utc_time(double glonass_time_corrected); + +}; + +#endif diff --git a/src/core/system_parameters/gnss_satellite.cc b/src/core/system_parameters/gnss_satellite.cc index 0538355b2..9970455be 100644 --- a/src/core/system_parameters/gnss_satellite.cc +++ b/src/core/system_parameters/gnss_satellite.cc @@ -61,9 +61,9 @@ Gnss_Satellite::~Gnss_Satellite() void Gnss_Satellite::reset() { - system_set = {"GPS", "GLONASS", "SBAS", "Galileo", "Beidou"}; + system_set = {"GPS", "Glonass", "SBAS", "Galileo", "Beidou"}; satelliteSystem["GPS"] = "G"; - satelliteSystem["GLONASS"] = "R"; + satelliteSystem["Glonass"] = "R"; satelliteSystem["SBAS"] = "S"; satelliteSystem["Galileo"] = "E"; satelliteSystem["Beidou"] = "C"; @@ -120,8 +120,8 @@ Gnss_Satellite& Gnss_Satellite::operator=(const Gnss_Satellite &rhs) { void Gnss_Satellite::set_system(const std::string& system_) { - // Set the satellite system {"GPS", "GLONASS", "SBAS", "Galileo", "Compass"} - std::set::const_iterator it = system_set.find(system_); + // Set the satellite system {"GPS", "Glonass", "SBAS", "Galileo", "Compass"} + std::set::iterator it = system_set.find(system_); if(it != system_set.cend()) { @@ -129,12 +129,33 @@ void Gnss_Satellite::set_system(const std::string& system_) } else { - DLOG(INFO) << "System " << system_ << " is not defined {GPS, GLONASS, SBAS, Galileo, Beidou}. Initialization?"; + DLOG(INFO) << "System " << system_ << " is not defined {GPS, Glonass, SBAS, Galileo, Beidou}. Initialization?"; system = std::string(""); } } +void Gnss_Satellite::update_PRN(unsigned int PRN_) +{ + if (system.compare("Glonass") != 0) + { + DLOG(INFO) << "Trying to update PRN for not GLONASS system"; + PRN = 0; + } + else + { + if (PRN_ < 1 or PRN_ > 24) + { + DLOG(INFO) << "This PRN is not defined"; + // Adjusting for PRN 26, now used in + PRN = PRN_; + } + else + { + PRN = PRN_; + } + } +} void Gnss_Satellite::set_PRN(unsigned int PRN_) @@ -202,7 +223,13 @@ void Gnss_Satellite::set_PRN(unsigned int PRN_) } - +signed int Gnss_Satellite::get_rf_link() const +{ + // Get satellite's rf link. Identifies the GLONASS Frequency Channel + signed int rf_link_; + rf_link_ = rf_link; + return rf_link_; +} unsigned int Gnss_Satellite::get_PRN() const @@ -220,7 +247,7 @@ unsigned int Gnss_Satellite::get_PRN() const std::string Gnss_Satellite::get_system() const { - // Get the satellite system {"GPS", "GLONASS", "SBAS", "Galileo", "Beidou"} + // Get the satellite system {"GPS", "Glonass", "SBAS", "Galileo", "Beidou"} std::string system_; system_ = system; return system_; @@ -569,6 +596,3 @@ void Gnss_Satellite::set_block(const std::string& system_, unsigned int PRN_) { block = what_block(system_, PRN_); } - - - diff --git a/src/core/system_parameters/gnss_satellite.h b/src/core/system_parameters/gnss_satellite.h index cfdf1369f..75ea70ac1 100644 --- a/src/core/system_parameters/gnss_satellite.h +++ b/src/core/system_parameters/gnss_satellite.h @@ -50,11 +50,13 @@ public: Gnss_Satellite(); //!< Default Constructor. Gnss_Satellite(const std::string& system_, unsigned int PRN_); //!< Concrete GNSS satellite Constructor. ~Gnss_Satellite(); //!< Default Destructor. + void update_PRN(unsigned int PRN); //!< Updates the PRN Number when information is decoded, only applies to GLONASS GNAV messages unsigned int get_PRN() const; //!< Gets satellite's PRN + signed int get_rf_link() const; //!< Gets the satellite's rf link std::string get_system() const; //!< Gets the satellite system {"GPS", "GLONASS", "SBAS", "Galileo", "Beidou"} std::string get_system_short() const; //!< Gets the satellite system {"G", "R", "SBAS", "E", "C"} std::string get_block() const; //!< Gets the satellite block. If GPS, returns {"IIA", "IIR", "IIR-M", "IIF"} - std::string what_block(const std::string& system_, unsigned int PRN_); //!< Gets the block of a given satellite + std::string what_block(const std::string& system_, unsigned int PRN_); //!< Gets the block of a given satellite friend bool operator== (const Gnss_Satellite &, const Gnss_Satellite &); //!< operator== for comparison friend std::ostream& operator<<(std::ostream &, const Gnss_Satellite &); //!< operator<< for pretty printing //Gnss_Satellite& operator=(const Gnss_Satellite &); diff --git a/src/core/system_parameters/gnss_signal.h b/src/core/system_parameters/gnss_signal.h index 25288a704..4645f17e9 100644 --- a/src/core/system_parameters/gnss_signal.h +++ b/src/core/system_parameters/gnss_signal.h @@ -51,7 +51,7 @@ public: Gnss_Signal(const std::string& signal_); Gnss_Signal(const Gnss_Satellite& satellite_, const std::string& signal_); ~Gnss_Signal(); - std::string get_signal_str() const; //!< Get the satellite signal {"1C" for GPS L1 C/A, "2S" for GPS L2C (M), "1B" for Galileo E1B, "5X" for Galileo E5a, "L5" for GPS L5} + std::string get_signal_str() const; //!< Get the satellite signal {"1C" for GPS L1 C/A, "2S" for GPS L2C (M), "L5" for GPS L5, "1G" for GLONASS L1 C/A, "1B" for Galileo E1B, "5X" for Galileo E5a. Gnss_Satellite get_satellite() const; //!< Get the Gnss_Satellite associated to the signal friend bool operator== (const Gnss_Signal &, const Gnss_Signal &); //!< operator== for comparison friend std::ostream& operator<<(std::ostream &, const Gnss_Signal &); //!< operator<< for pretty printing diff --git a/src/core/system_parameters/gps_ephemeris.h b/src/core/system_parameters/gps_ephemeris.h index 0a413a927..a08f34400 100644 --- a/src/core/system_parameters/gps_ephemeris.h +++ b/src/core/system_parameters/gps_ephemeris.h @@ -37,6 +37,7 @@ #include #include "boost/assign.hpp" #include +#include diff --git a/src/core/system_parameters/rtcm.cc b/src/core/system_parameters/rtcm.cc index 9a2b5f97f..ee5204b97 100644 --- a/src/core/system_parameters/rtcm.cc +++ b/src/core/system_parameters/rtcm.cc @@ -317,6 +317,41 @@ long int Rtcm::bin_to_int(const std::string& s) const } +long int Rtcm::bin_to_sint(const std::string& s) const +{ + if(s.length() > 32) + { + LOG(WARNING) << "Cannot convert to a long int"; + return 0; + } + long int reading; + long int sign; + + // Check for sign bit as defined RTCM doc + if(s.substr(0,1).compare("0") == 0) + { + sign = 1; + // Get the magnitude of the value + reading = strtol((s.substr (1)).c_str(), NULL, 2); + } + else + { + sign = -1; + // Get the magnitude of the value + reading = strtol((s.substr (1)).c_str(), NULL, 2); + } + return sign*reading; +} + +// Find the sign for glonass data fields (neg = 1, pos = 0) +static inline unsigned long glo_sgn(double val) +{ + if (val < 0) return 1; // If value is negative return 1 + if (val==0) return 0; // Positive or equal to zero return 0 + return 0; +} + + double Rtcm::bin_to_double(const std::string& s) const { double reading; @@ -1081,6 +1116,410 @@ std::string Rtcm::print_MT1008(unsigned int ref_id, const std::string & antenna_ } +// ******************************************************** +// +// MESSAGE TYPE 1009 (GLONASS L1 Basic RTK Observables) +// +// ******************************************************** +std::bitset<61> Rtcm::get_MT1009_12_header(unsigned int msg_number, double obs_time, const std::map & observables, + unsigned int ref_id, unsigned int smooth_int, bool sync_flag, bool divergence_free) +{ + unsigned int reference_station_id = ref_id; // Max: 4095 + const std::map observables_ = observables; + bool synchronous_GNSS_flag = sync_flag; + bool divergence_free_smoothing_indicator = divergence_free; + unsigned int smoothing_interval = smooth_int; + Rtcm::set_DF002(msg_number); + Rtcm::set_DF003(reference_station_id); + Rtcm::set_DF034(obs_time); + Rtcm::set_DF005(synchronous_GNSS_flag); + Rtcm::set_DF035(observables_); + Rtcm::set_DF036(divergence_free_smoothing_indicator); + Rtcm::set_DF037(smoothing_interval); + + std::string header = DF002.to_string() + + DF003.to_string() + + DF034.to_string() + + DF005.to_string() + + DF035.to_string() + + DF036.to_string() + + DF037.to_string(); + + std::bitset<61> header_msg(header); + return header_msg; +} + + +std::bitset<64> Rtcm::get_MT1009_sat_content(const Glonass_Gnav_Ephemeris & eph, double obs_time, const Gnss_Synchro & gnss_synchro) +{ + bool code_indicator = false; // code indicator 0: C/A code 1: P(Y) code direct + Rtcm::set_DF038(gnss_synchro); + Rtcm::set_DF039(code_indicator); + Rtcm::set_DF040(eph.i_satellite_freq_channel); + Rtcm::set_DF041(gnss_synchro); + Rtcm::set_DF042(gnss_synchro); + Rtcm::set_DF043(eph, obs_time, gnss_synchro); + + std::string content = DF038.to_string() + + DF039.to_string() + + DF040.to_string() + + DF041.to_string() + + DF042.to_string() + + DF043.to_string(); + + std::bitset<64> content_msg(content); + return content_msg; +} + + +std::string Rtcm::print_MT1009(const Glonass_Gnav_Ephemeris & glonass_gnav_eph, double obs_time, const std::map & observables, unsigned short station_id) +{ + unsigned int ref_id = static_cast(station_id); + unsigned int smooth_int = 0; + bool sync_flag = false; + bool divergence_free = false; + + //Get a map with GLONASS L1 only observations + std::map observablesL1; + std::map::const_iterator observables_iter; + + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + std::string system_(&observables_iter->second.System, 1); + std::string sig_(observables_iter->second.Signal); + if((system_.compare("R") == 0) && (sig_.compare("1C") == 0)) + { + observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } + + std::bitset<61> header = Rtcm::get_MT1009_12_header(1009, obs_time, observablesL1, ref_id, smooth_int, sync_flag, divergence_free); + std::string data = header.to_string(); + + for(observables_iter = observablesL1.begin(); + observables_iter != observablesL1.end(); + observables_iter++) + { + std::bitset<64> content = Rtcm::get_MT1009_sat_content(glonass_gnav_eph, obs_time, observables_iter->second); + data += content.to_string(); + } + + std::string msg = build_message(data); + if(server_is_running) + { + rtcm_message_queue->push(msg); + } + return msg; +} + + +// ******************************************************** +// +// MESSAGE TYPE 1010 (EXTENDED GLONASS L1 OBSERVATIONS) +// +// ******************************************************** + +std::string Rtcm::print_MT1010(const Glonass_Gnav_Ephemeris & glonass_gnav_eph, double obs_time, const std::map & observables, unsigned short station_id) +{ + unsigned int ref_id = static_cast(station_id); + unsigned int smooth_int = 0; + bool sync_flag = false; + bool divergence_free = false; + + //Get a map with GPS L1 only observations + std::map observablesL1; + std::map::const_iterator observables_iter; + + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + std::string system_(&observables_iter->second.System, 1); + std::string sig_(observables_iter->second.Signal); + if((system_.compare("R") == 0) && (sig_.compare("1C") == 0)) + { + observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } + + std::bitset<61> header = Rtcm::get_MT1009_12_header(1010, obs_time, observablesL1, ref_id, smooth_int, sync_flag, divergence_free); + std::string data = header.to_string(); + + for(observables_iter = observablesL1.begin(); + observables_iter != observablesL1.end(); + observables_iter++) + { + std::bitset<79> content = Rtcm::get_MT1010_sat_content(glonass_gnav_eph, obs_time, observables_iter->second); + data += content.to_string(); + } + + std::string msg = build_message(data); + if(server_is_running) + { + rtcm_message_queue->push(msg); + } + return msg; +} + + +std::bitset<79> Rtcm::get_MT1010_sat_content(const Glonass_Gnav_Ephemeris & eph, double obs_time, const Gnss_Synchro & gnss_synchro) +{ + bool code_indicator = false; // code indicator 0: C/A code 1: P(Y) code direct + Rtcm::set_DF038(gnss_synchro); + Rtcm::set_DF039(code_indicator); + Rtcm::set_DF040(eph.i_satellite_freq_channel); + Rtcm::set_DF041(gnss_synchro); + Rtcm::set_DF042(gnss_synchro); + Rtcm::set_DF043(eph, obs_time, gnss_synchro); + Rtcm::set_DF044(gnss_synchro); + Rtcm::set_DF045(gnss_synchro); + + std::string content = DF038.to_string() + + DF039.to_string() + + DF040.to_string() + + DF041.to_string() + + DF042.to_string() + + DF043.to_string() + + DF044.to_string() + + DF045.to_string(); + + std::bitset<79> content_msg(content); + return content_msg; +} + + + +// ******************************************************** +// +// MESSAGE TYPE 1011 (GLONASS L1 & L2 OBSERVATIONS) +// +// ******************************************************** + +std::string Rtcm::print_MT1011(const Glonass_Gnav_Ephemeris & ephL1, const Glonass_Gnav_Ephemeris & ephL2, double obs_time, const std::map & observables, unsigned short station_id) +{ + unsigned int ref_id = static_cast(station_id); + unsigned int smooth_int = 0; + bool sync_flag = false; + bool divergence_free = false; + + //Get maps with GPS L1 and L2 observations + std::map observablesL1; + std::map observablesL2; + std::map::const_iterator observables_iter; + std::map::const_iterator observables_iter2; + + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + std::string system_(&observables_iter->second.System, 1); + std::string sig_(observables_iter->second.Signal); + if((system_.compare("R") == 0) && (sig_.compare("1C") == 0)) + { + observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if((system_.compare("R") == 0) && (sig_.compare("2C") == 0)) + { + observablesL2.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } + + // Get common observables + std::vector< std::pair< Gnss_Synchro, Gnss_Synchro > > common_observables; + std::vector< std::pair< Gnss_Synchro, Gnss_Synchro > >::const_iterator common_observables_iter; + std::map observablesL1_with_L2; + + for(observables_iter = observablesL1.begin(); + observables_iter != observablesL1.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + for(observables_iter2 = observablesL2.begin(); + observables_iter2 != observablesL2.end(); + observables_iter2++) + { + if(observables_iter2->second.PRN == prn_) + { + std::pair p; + Gnss_Synchro pr1 = observables_iter->second; + Gnss_Synchro pr2 = observables_iter2->second; + p = std::make_pair(pr1, pr2); + common_observables.push_back(p); + observablesL1_with_L2.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } + } + + std::bitset<61> header = Rtcm::get_MT1009_12_header(1011, obs_time, observablesL1_with_L2, ref_id, smooth_int, sync_flag, divergence_free); + std::string data = header.to_string(); + + for(common_observables_iter = common_observables.begin(); + common_observables_iter != common_observables.end(); + common_observables_iter++) + { + std::bitset<107> content = Rtcm::get_MT1011_sat_content(ephL1, ephL2, obs_time, common_observables_iter->first, common_observables_iter->second); + data += content.to_string(); + } + + std::string msg = build_message(data); + if(server_is_running) + { + rtcm_message_queue->push(msg); + } + return msg; +} + + +std::bitset<107> Rtcm::get_MT1011_sat_content(const Glonass_Gnav_Ephemeris & ephL1, const Glonass_Gnav_Ephemeris & ephL2, double obs_time, const Gnss_Synchro & gnss_synchroL1, const Gnss_Synchro & gnss_synchroL2) +{ + bool code_indicator = false; // code indicator 0: C/A code 1: P(Y) code direct + Rtcm::set_DF038(gnss_synchroL1); + Rtcm::set_DF039(code_indicator); + Rtcm::set_DF040(ephL1.i_satellite_freq_channel); + Rtcm::set_DF041(gnss_synchroL1); + Rtcm::set_DF042(gnss_synchroL1); + Rtcm::set_DF043(ephL1, obs_time, gnss_synchroL1); + std::bitset<2> DF046_ = std::bitset<2>(0); // code indicator 0: C/A or L2C code 1: P(Y) code direct 2:P(Y) code cross-correlated 3: Correlated P/Y + Rtcm::set_DF047(gnss_synchroL1, gnss_synchroL2); + Rtcm::set_DF048(gnss_synchroL1, gnss_synchroL2); + Rtcm::set_DF049(ephL2, obs_time, gnss_synchroL2); + + std::string content = DF038.to_string() + + DF039.to_string() + + DF040.to_string() + + DF041.to_string() + + DF042.to_string() + + DF043.to_string() + + DF046_.to_string() + + DF047.to_string() + + DF048.to_string() + + DF049.to_string(); + + std::bitset<107> content_msg(content); + return content_msg; +} + + + +// ****************************************************************** +// +// MESSAGE TYPE 1004 (EXTENDED GLONASS L1 & L2 OBSERVATIONS) +// +// ****************************************************************** + +std::string Rtcm::print_MT1012(const Glonass_Gnav_Ephemeris & ephL1, const Glonass_Gnav_Ephemeris & ephL2, double obs_time, const std::map & observables, unsigned short station_id) +{ + unsigned int ref_id = static_cast(station_id); + unsigned int smooth_int = 0; + bool sync_flag = false; + bool divergence_free = false; + + //Get maps with GLONASS L1 and L2 observations + std::map observablesL1; + std::map observablesL2; + std::map::const_iterator observables_iter; + std::map::const_iterator observables_iter2; + + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + std::string system_(&observables_iter->second.System, 1); + std::string sig_(observables_iter->second.Signal); + if((system_.compare("R") == 0) && (sig_.compare("1C") == 0)) + { + observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if((system_.compare("R") == 0) && (sig_.compare("2C") == 0)) + { + observablesL2.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } + + // Get common observables + std::vector< std::pair< Gnss_Synchro, Gnss_Synchro > > common_observables; + std::vector< std::pair< Gnss_Synchro, Gnss_Synchro > >::const_iterator common_observables_iter; + std::map observablesL1_with_L2; + + for(observables_iter = observablesL1.begin(); + observables_iter != observablesL1.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + for(observables_iter2 = observablesL2.begin(); + observables_iter2 != observablesL2.end(); + observables_iter2++) + { + if(observables_iter2->second.PRN == prn_) + { + std::pair p; + Gnss_Synchro pr1 = observables_iter->second; + Gnss_Synchro pr2 = observables_iter2->second; + p = std::make_pair(pr1, pr2); + common_observables.push_back(p); + observablesL1_with_L2.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } + } + + std::bitset<61> header = Rtcm::get_MT1009_12_header(1012, obs_time, observablesL1_with_L2, ref_id, smooth_int, sync_flag, divergence_free); + std::string data = header.to_string(); + + for(common_observables_iter = common_observables.begin(); + common_observables_iter != common_observables.end(); + common_observables_iter++) + { + std::bitset<130> content = Rtcm::get_MT1012_sat_content(ephL1, ephL2, obs_time, common_observables_iter->first, common_observables_iter->second); + data += content.to_string(); + } + + std::string msg = build_message(data); + if(server_is_running) + { + rtcm_message_queue->push(msg); + } + return msg; +} + + +std::bitset<130> Rtcm::get_MT1012_sat_content(const Glonass_Gnav_Ephemeris & ephL1, const Glonass_Gnav_Ephemeris & ephL2, double obs_time, const Gnss_Synchro & gnss_synchroL1, const Gnss_Synchro & gnss_synchroL2) +{ + bool code_indicator = false; // code indicator 0: C/A code 1: P(Y) code direct + Rtcm::set_DF038(gnss_synchroL1); + Rtcm::set_DF039(code_indicator); + Rtcm::set_DF040(ephL1.i_satellite_freq_channel); + Rtcm::set_DF041(gnss_synchroL1); + Rtcm::set_DF042(gnss_synchroL1); + Rtcm::set_DF043(ephL1, obs_time, gnss_synchroL1); + Rtcm::set_DF044(gnss_synchroL1); + Rtcm::set_DF045(gnss_synchroL1); + std::bitset<2> DF046_ = std::bitset<2>(0); // code indicator 0: C/A or L2C code 1: P(Y) code direct 2:P(Y) code cross-correlated 3: Correlated P/Y + Rtcm::set_DF047(gnss_synchroL1, gnss_synchroL2); + Rtcm::set_DF048(gnss_synchroL1, gnss_synchroL2); + Rtcm::set_DF049(ephL2, obs_time, gnss_synchroL2); + Rtcm::set_DF050(gnss_synchroL2); + + std::string content = DF038.to_string() + + DF039.to_string() + + DF040.to_string() + + DF041.to_string() + + DF042.to_string() + + DF043.to_string() + + DF044.to_string() + + DF045.to_string() + + DF046_.to_string() + + DF047.to_string() + + DF048.to_string() + + DF049.to_string() + + DF050.to_string(); + + std::bitset<130> content_msg(content); + return content_msg; +} + + // ******************************************************** // // MESSAGE TYPE 1019 (GPS EPHEMERIS) @@ -1300,6 +1739,267 @@ int Rtcm::read_MT1019(const std::string & message, Gps_Ephemeris & gps_eph) } +// ******************************************************** +// +// MESSAGE TYPE 1020 (GLONASS EPHEMERIS) +// +// ******************************************************** + +std::string Rtcm::print_MT1020(const Glonass_Gnav_Ephemeris & glonass_gnav_eph, const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model) +{ + unsigned int msg_number = 1020; + unsigned int glonass_gnav_alm_health = 0; + unsigned int glonass_gnav_alm_health_ind = 0; + unsigned int fifth_str_additional_data_ind = 1; + + Rtcm::set_DF002(msg_number); + Rtcm::set_DF038(glonass_gnav_eph); + Rtcm::set_DF040(glonass_gnav_eph); + Rtcm::set_DF104(glonass_gnav_alm_health); + Rtcm::set_DF105(glonass_gnav_alm_health_ind); + Rtcm::set_DF106(glonass_gnav_eph); + Rtcm::set_DF107(glonass_gnav_eph); + Rtcm::set_DF108(glonass_gnav_eph); + Rtcm::set_DF109(glonass_gnav_eph); + Rtcm::set_DF110(glonass_gnav_eph); + Rtcm::set_DF111(glonass_gnav_eph); + Rtcm::set_DF112(glonass_gnav_eph); + Rtcm::set_DF113(glonass_gnav_eph); + Rtcm::set_DF114(glonass_gnav_eph); + Rtcm::set_DF115(glonass_gnav_eph); + Rtcm::set_DF116(glonass_gnav_eph); + Rtcm::set_DF117(glonass_gnav_eph); + Rtcm::set_DF118(glonass_gnav_eph); + Rtcm::set_DF119(glonass_gnav_eph); + Rtcm::set_DF120(glonass_gnav_eph); + Rtcm::set_DF121(glonass_gnav_eph); + Rtcm::set_DF122(glonass_gnav_eph); + Rtcm::set_DF123(glonass_gnav_eph); + Rtcm::set_DF124(glonass_gnav_eph); + Rtcm::set_DF125(glonass_gnav_eph); + Rtcm::set_DF126(glonass_gnav_eph); + Rtcm::set_DF127(glonass_gnav_eph); + Rtcm::set_DF128(glonass_gnav_eph); + Rtcm::set_DF129(glonass_gnav_eph); + Rtcm::set_DF130(glonass_gnav_eph); + Rtcm::set_DF131(fifth_str_additional_data_ind); + Rtcm::set_DF132(glonass_gnav_utc_model); + Rtcm::set_DF133(glonass_gnav_utc_model); + Rtcm::set_DF134(glonass_gnav_utc_model); + Rtcm::set_DF135(glonass_gnav_utc_model); + Rtcm::set_DF136(glonass_gnav_eph); + + std::string data; + data.clear(); + data = DF002.to_string() + + DF038.to_string() + + DF040.to_string() + + DF104.to_string() + + DF105.to_string() + + DF106.to_string() + + DF107.to_string() + + DF108.to_string() + + DF109.to_string() + + DF110.to_string() + + DF111.to_string() + + DF112.to_string() + + DF113.to_string() + + DF114.to_string() + + DF115.to_string() + + DF116.to_string() + + DF117.to_string() + + DF118.to_string() + + DF119.to_string() + + DF120.to_string() + + DF121.to_string() + + DF122.to_string() + + DF123.to_string() + + DF124.to_string() + + DF125.to_string() + + DF126.to_string() + + DF127.to_string() + + DF128.to_string() + + DF129.to_string() + + DF130.to_string() + + DF131.to_string() + + DF132.to_string() + + DF133.to_string() + + DF134.to_string() + + DF135.to_string() + + DF136.to_string() + + std::bitset<7>().to_string(); // Reserved bits + + if (data.length() != 360) + { + LOG(WARNING) << "Bad-formatted RTCM MT1020 (360 bits expected, found " << data.length() << ")"; + } + + std::string msg = build_message(data); + if(server_is_running) + { + rtcm_message_queue->push(msg); + } + return msg; +} + + +int Rtcm::read_MT1020(const std::string & message, Glonass_Gnav_Ephemeris & glonass_gnav_eph, Glonass_Gnav_Utc_Model & glonass_gnav_utc_model) +{ + // Convert message to binary + std::string message_bin = Rtcm::binary_data_to_bin(message); + int glonass_gnav_alm_health = 0; + int glonass_gnav_alm_health_ind = 0; + int fifth_str_additional_data_ind = 0; + + if(!Rtcm::check_CRC(message) ) + { + LOG(WARNING) << " Bad CRC detected in RTCM message MT1020"; + return 1; + } + + unsigned int preamble_length = 8; + unsigned int reserved_field_length = 6; + unsigned int index = preamble_length + reserved_field_length; + + unsigned int read_message_length = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 10))); + index += 10; + + if (read_message_length != 45) // 360 bits = 45 bytes + { + LOG(WARNING) << " Message MT1020 seems too long (61 bytes expected, " << read_message_length << " received)"; + return 1; + } + + // Check than the message number is correct + unsigned int read_msg_number = Rtcm::bin_to_uint(message_bin.substr(index, 12)); + index += 12; + + if (1020 != read_msg_number) + { + LOG(WARNING) << " This is not a MT1020 message"; + return 1; + } + + // Fill Gps Ephemeris with message data content + glonass_gnav_eph.i_satellite_slot_number = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 6))); + index += 6; + + glonass_gnav_eph.i_satellite_freq_channel = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 5)) - 7.0); + index += 5; + + glonass_gnav_alm_health = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); + index += 1; + if(glonass_gnav_alm_health){} //Avoid comiler warning + + glonass_gnav_alm_health_ind = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); + index += 1; + if(glonass_gnav_alm_health_ind){} //Avoid comiler warning + + glonass_gnav_eph.d_P_1 = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 2))); + glonass_gnav_eph.d_P_1 = (glonass_gnav_eph.d_P_1+1)*15; + index += 2; + + glonass_gnav_eph.d_t_k += static_cast(Rtcm::bin_to_int(message_bin.substr(index, 5)))*3600; + index += 5; + glonass_gnav_eph.d_t_k += static_cast(Rtcm::bin_to_int(message_bin.substr(index, 6)))*60; + index += 6; + glonass_gnav_eph.d_t_k += static_cast(Rtcm::bin_to_int(message_bin.substr(index, 1)))*30; + index += 1; + + glonass_gnav_eph.d_B_n = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); + index += 1; + + glonass_gnav_eph.d_P_2 = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); + index += 1; + + glonass_gnav_eph.d_t_b = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 7)))*15*60.0; + index += 7; + + // TODO Check for type spec for intS24 + glonass_gnav_eph.d_VXn = static_cast(Rtcm::bin_to_sint(message_bin.substr(index, 24)))*TWO_N20; + index += 24; + + glonass_gnav_eph.d_Xn = static_cast(Rtcm::bin_to_sint(message_bin.substr(index, 27)))*TWO_N11; + index += 27; + + glonass_gnav_eph.d_AXn = static_cast(Rtcm::bin_to_sint(message_bin.substr(index, 5)))*TWO_N30; + index += 5; + + glonass_gnav_eph.d_VYn = static_cast(Rtcm::bin_to_sint(message_bin.substr(index, 24)))*TWO_N20; + index += 24; + + glonass_gnav_eph.d_Yn = static_cast(Rtcm::bin_to_sint(message_bin.substr(index, 27)))*TWO_N11; + index += 27; + + glonass_gnav_eph.d_AYn = static_cast(Rtcm::bin_to_sint(message_bin.substr(index, 5)))*TWO_N30; + index += 5; + + glonass_gnav_eph.d_VZn = static_cast(Rtcm::bin_to_sint(message_bin.substr(index, 24)))*TWO_N20; + index += 24; + + glonass_gnav_eph.d_Zn = static_cast(Rtcm::bin_to_sint(message_bin.substr(index, 27)))*TWO_N11; + index += 27; + + glonass_gnav_eph.d_AZn = static_cast(Rtcm::bin_to_sint(message_bin.substr(index, 5)))*TWO_N30; + index += 5; + + glonass_gnav_eph.d_P_3 = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); + index += 1; + + glonass_gnav_eph.d_gamma_n = static_cast(Rtcm::bin_to_sint(message_bin.substr(index, 11)))*TWO_N30; + index += 11; + + glonass_gnav_eph.d_P = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 2))); + index += 2; + + glonass_gnav_eph.d_l3rd_n = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); + index += 1; + + glonass_gnav_eph.d_tau_n = static_cast(Rtcm::bin_to_sint(message_bin.substr(index, 22)))* TWO_N30; + index += 22; + + glonass_gnav_eph.d_Delta_tau_n = static_cast(Rtcm::bin_to_sint(message_bin.substr(index, 5)))* TWO_N30; + index += 5; + + glonass_gnav_eph.d_E_n = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 5))); + index += 5; + + glonass_gnav_eph.d_P_4 = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); + index += 1; + + glonass_gnav_eph.d_F_T = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 4))); + index += 4; + + glonass_gnav_eph.d_N_T = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 11))); + index += 11; + + glonass_gnav_eph.d_M = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 2))); + index += 2; + + fifth_str_additional_data_ind = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); + index += 1; + + if(fifth_str_additional_data_ind == true) + { + glonass_gnav_utc_model.d_N_A = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 11))); + index += 11; + + glonass_gnav_utc_model.d_tau_c = static_cast(Rtcm::bin_to_sint(message_bin.substr(index, 32)))* TWO_N31; + index += 32; + + glonass_gnav_utc_model.d_N_4 = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 5))); + index += 5; + + glonass_gnav_utc_model.d_tau_gps = static_cast(Rtcm::bin_to_sint(message_bin.substr(index, 22)))* TWO_N30; + index += 22; + + glonass_gnav_eph.d_l5th_n = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); + } + + return 0; +} + + // ******************************************************** // // MESSAGE TYPE 1029 (UNICODE TEXT STRING) @@ -1583,6 +2283,7 @@ int Rtcm::read_MT1045(const std::string & message, Galileo_Ephemeris & gal_eph) std::string Rtcm::print_MSM_1( const Gps_Ephemeris & gps_eph, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Galileo_Ephemeris & gal_eph, + const Glonass_Gnav_Ephemeris & glo_gnav_eph, double obs_time, const std::map & observables, unsigned int ref_id, @@ -1595,8 +2296,9 @@ std::string Rtcm::print_MSM_1( const Gps_Ephemeris & gps_eph, unsigned int msg_number = 0; if(gps_eph.i_satellite_PRN != 0) msg_number = 1071; if(gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1071; + if(glo_gnav_eph.i_satellite_PRN != 0) msg_number = 1081; if(gal_eph.i_satellite_PRN != 0) msg_number = 1091; - if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0)) + if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0) && (glo_gnav_eph.i_satellite_PRN != 0)) { LOG(WARNING) << "MSM messages for observables from different systems are not defined"; //print two messages? } @@ -1641,9 +2343,12 @@ std::string Rtcm::get_MSM_header(unsigned int msg_number, bool divergence_free, bool more_messages) { + // Find first element in observables block and define type of message + std::map::const_iterator observables_iter = observables.begin(); + std::string sys(observables_iter->second.System, 1); + Rtcm::set_DF002(msg_number); Rtcm::set_DF003(ref_id); - Rtcm::set_DF004(obs_time); Rtcm::set_DF393(more_messages); Rtcm::set_DF409(0); // Issue of Data Station. 0: not utilized std::bitset<7> DF001_ = std::bitset<7>("0000000"); @@ -1656,7 +2361,20 @@ std::string Rtcm::get_MSM_header(unsigned int msg_number, Rtcm::set_DF395(observables); std::string header = DF002.to_string() + DF003.to_string(); - header += DF004.to_string(); + // GNSS Epoch Time Specific to each constellation + if((sys.compare("R") == 0 )) + { + // GLONASS Epoch Time + Rtcm::set_DF034(obs_time); + header += DF034.to_string(); + } + else + { + // GPS, Galileo Epoch Time + Rtcm::set_DF004(obs_time); + header += DF004.to_string(); + } + header = header + DF393.to_string() + DF409.to_string() + DF001_.to_string() + @@ -1748,6 +2466,7 @@ std::string Rtcm::get_MSM_1_content_signal_data(const std::map & observables, unsigned int ref_id, @@ -1760,8 +2479,9 @@ std::string Rtcm::print_MSM_2( const Gps_Ephemeris & gps_eph, unsigned int msg_number = 0; if(gps_eph.i_satellite_PRN != 0) msg_number = 1072; if(gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1072; + if(glo_gnav_eph.i_satellite_PRN != 0) msg_number = 1082; if(gal_eph.i_satellite_PRN != 0) msg_number = 1092; - if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0)) + if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0) && (glo_gnav_eph.i_satellite_PRN != 0)) { LOG(WARNING) << "MSM messages for observables from different systems are not defined"; //print two messages? } @@ -1783,7 +2503,7 @@ std::string Rtcm::print_MSM_2( const Gps_Ephemeris & gps_eph, std::string sat_data = Rtcm::get_MSM_1_content_sat_data(observables); - std::string signal_data = Rtcm::get_MSM_2_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, obs_time, observables); + std::string signal_data = Rtcm::get_MSM_2_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, glo_gnav_eph, obs_time, observables); std::string message = build_message(header + sat_data + signal_data); if(server_is_running) @@ -1795,7 +2515,12 @@ std::string Rtcm::print_MSM_2( const Gps_Ephemeris & gps_eph, } -std::string Rtcm::get_MSM_2_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map & observables) +std::string Rtcm::get_MSM_2_content_signal_data(const Gps_Ephemeris & ephNAV, + const Gps_CNAV_Ephemeris & ephCNAV, + const Galileo_Ephemeris & ephFNAV, + const Glonass_Gnav_Ephemeris & ephGNAV, + double obs_time, + const std::map & observables) { std::string signal_data; std::string first_data_type; @@ -1821,7 +2546,7 @@ std::string Rtcm::get_MSM_2_content_signal_data(const Gps_Ephemeris & ephNAV, co for(unsigned int cell = 0; cell < Ncells ; cell++) { Rtcm::set_DF401(ordered_by_PRN_pos.at( cell ).second); - Rtcm::set_DF402(ephNAV, ephCNAV, ephFNAV, obs_time, ordered_by_PRN_pos.at( cell ).second); + Rtcm::set_DF402(ephNAV, ephCNAV, ephFNAV, ephGNAV, obs_time, ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF420(ordered_by_PRN_pos.at( cell ).second); first_data_type += DF401.to_string(); second_data_type += DF402.to_string(); @@ -1843,6 +2568,7 @@ std::string Rtcm::get_MSM_2_content_signal_data(const Gps_Ephemeris & ephNAV, co std::string Rtcm::print_MSM_3( const Gps_Ephemeris & gps_eph, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Galileo_Ephemeris & gal_eph, + const Glonass_Gnav_Ephemeris & glo_gnav_eph, double obs_time, const std::map & observables, unsigned int ref_id, @@ -1855,8 +2581,9 @@ std::string Rtcm::print_MSM_3( const Gps_Ephemeris & gps_eph, unsigned int msg_number = 0; if(gps_eph.i_satellite_PRN != 0) msg_number = 1073; if(gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1073; + if(glo_gnav_eph.i_satellite_PRN != 0) msg_number = 1083; if(gal_eph.i_satellite_PRN != 0) msg_number = 1093; - if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0)) + if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0) && (glo_gnav_eph.i_satellite_PRN != 0)) { LOG(WARNING) << "MSM messages for observables from different systems are not defined"; //print two messages? } @@ -1878,7 +2605,7 @@ std::string Rtcm::print_MSM_3( const Gps_Ephemeris & gps_eph, std::string sat_data = Rtcm::get_MSM_1_content_sat_data(observables); - std::string signal_data = Rtcm::get_MSM_3_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, obs_time, observables); + std::string signal_data = Rtcm::get_MSM_3_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, glo_gnav_eph, obs_time, observables); std::string message = build_message(header + sat_data + signal_data); if(server_is_running) @@ -1890,7 +2617,12 @@ std::string Rtcm::print_MSM_3( const Gps_Ephemeris & gps_eph, } -std::string Rtcm::get_MSM_3_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map & observables) +std::string Rtcm::get_MSM_3_content_signal_data(const Gps_Ephemeris & ephNAV, + const Gps_CNAV_Ephemeris & ephCNAV, + const Galileo_Ephemeris & ephFNAV, + const Glonass_Gnav_Ephemeris & ephGNAV, + double obs_time, + const std::map & observables) { std::string signal_data; std::string first_data_type; @@ -1918,7 +2650,7 @@ std::string Rtcm::get_MSM_3_content_signal_data(const Gps_Ephemeris & ephNAV, co { Rtcm::set_DF400(ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF401(ordered_by_PRN_pos.at( cell ).second); - Rtcm::set_DF402(ephNAV, ephCNAV, ephFNAV, obs_time, ordered_by_PRN_pos.at( cell ).second); + Rtcm::set_DF402(ephNAV, ephCNAV, ephFNAV, ephGNAV, obs_time, ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF420(ordered_by_PRN_pos.at( cell ).second); first_data_type += DF400.to_string(); second_data_type += DF401.to_string(); @@ -1940,6 +2672,7 @@ std::string Rtcm::get_MSM_3_content_signal_data(const Gps_Ephemeris & ephNAV, co std::string Rtcm::print_MSM_4( const Gps_Ephemeris & gps_eph, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Galileo_Ephemeris & gal_eph, + const Glonass_Gnav_Ephemeris & glo_gnav_eph, double obs_time, const std::map & observables, unsigned int ref_id, @@ -1952,8 +2685,9 @@ std::string Rtcm::print_MSM_4( const Gps_Ephemeris & gps_eph, unsigned int msg_number = 0; if(gps_eph.i_satellite_PRN != 0) msg_number = 1074; if(gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1074; + if(glo_gnav_eph.i_satellite_PRN != 0) msg_number = 1084; if(gal_eph.i_satellite_PRN != 0) msg_number = 1094; - if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0)) + if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0) && (glo_gnav_eph.i_satellite_PRN != 0)) { LOG(WARNING) << "MSM messages for observables from different systems are not defined"; //print two messages? } @@ -1975,7 +2709,7 @@ std::string Rtcm::print_MSM_4( const Gps_Ephemeris & gps_eph, std::string sat_data = Rtcm::get_MSM_4_content_sat_data(observables); - std::string signal_data = Rtcm::get_MSM_4_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, obs_time, observables); + std::string signal_data = Rtcm::get_MSM_4_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, glo_gnav_eph, obs_time, observables); std::string message = build_message(header + sat_data + signal_data); if(server_is_running) @@ -2027,7 +2761,12 @@ std::string Rtcm::get_MSM_4_content_sat_data(const std::map & } -std::string Rtcm::get_MSM_4_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map & observables) +std::string Rtcm::get_MSM_4_content_signal_data(const Gps_Ephemeris & ephNAV, + const Gps_CNAV_Ephemeris & ephCNAV, + const Galileo_Ephemeris & ephFNAV, + const Glonass_Gnav_Ephemeris & ephGNAV, + double obs_time, + const std::map & observables) { std::string signal_data; std::string first_data_type; @@ -2056,7 +2795,7 @@ std::string Rtcm::get_MSM_4_content_signal_data(const Gps_Ephemeris & ephNAV, co { Rtcm::set_DF400(ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF401(ordered_by_PRN_pos.at( cell ).second); - Rtcm::set_DF402(ephNAV, ephCNAV, ephFNAV, obs_time, ordered_by_PRN_pos.at( cell ).second); + Rtcm::set_DF402(ephNAV, ephCNAV, ephFNAV, ephGNAV, obs_time, ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF420(ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF403(ordered_by_PRN_pos.at( cell ).second); first_data_type += DF400.to_string(); @@ -2080,6 +2819,7 @@ std::string Rtcm::get_MSM_4_content_signal_data(const Gps_Ephemeris & ephNAV, co std::string Rtcm::print_MSM_5( const Gps_Ephemeris & gps_eph, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Galileo_Ephemeris & gal_eph, + const Glonass_Gnav_Ephemeris & glo_gnav_eph, double obs_time, const std::map & observables, unsigned int ref_id, @@ -2092,8 +2832,9 @@ std::string Rtcm::print_MSM_5( const Gps_Ephemeris & gps_eph, unsigned int msg_number = 0; if(gps_eph.i_satellite_PRN != 0) msg_number = 1075; if(gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1075; + if(glo_gnav_eph.i_satellite_PRN != 0) msg_number = 1085; if(gal_eph.i_satellite_PRN != 0) msg_number = 1095; - if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0)) + if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0) && (glo_gnav_eph.i_satellite_PRN != 0)) { LOG(WARNING) << "MSM messages for observables from different systems are not defined"; //print two messages? } @@ -2115,7 +2856,7 @@ std::string Rtcm::print_MSM_5( const Gps_Ephemeris & gps_eph, std::string sat_data = Rtcm::get_MSM_5_content_sat_data(observables); - std::string signal_data = Rtcm::get_MSM_5_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, obs_time, observables); + std::string signal_data = Rtcm::get_MSM_5_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, glo_gnav_eph, obs_time, observables); std::string message = build_message(header + sat_data + signal_data); if(server_is_running) @@ -2173,7 +2914,12 @@ std::string Rtcm::get_MSM_5_content_sat_data(const std::map & } -std::string Rtcm::get_MSM_5_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map & observables) +std::string Rtcm::get_MSM_5_content_signal_data(const Gps_Ephemeris & ephNAV, + const Gps_CNAV_Ephemeris & ephCNAV, + const Galileo_Ephemeris & ephFNAV, + const Glonass_Gnav_Ephemeris & ephGNAV, + double obs_time, + const std::map & observables) { std::string signal_data; std::string first_data_type; @@ -2203,7 +2949,7 @@ std::string Rtcm::get_MSM_5_content_signal_data(const Gps_Ephemeris & ephNAV, co { Rtcm::set_DF400(ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF401(ordered_by_PRN_pos.at( cell ).second); - Rtcm::set_DF402(ephNAV, ephCNAV, ephFNAV, obs_time, ordered_by_PRN_pos.at( cell ).second); + Rtcm::set_DF402(ephNAV, ephCNAV, ephFNAV, ephGNAV, obs_time, ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF420(ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF403(ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF404(ordered_by_PRN_pos.at( cell ).second); @@ -2230,6 +2976,7 @@ std::string Rtcm::get_MSM_5_content_signal_data(const Gps_Ephemeris & ephNAV, co std::string Rtcm::print_MSM_6( const Gps_Ephemeris & gps_eph, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Galileo_Ephemeris & gal_eph, + const Glonass_Gnav_Ephemeris & glo_gnav_eph, double obs_time, const std::map & observables, unsigned int ref_id, @@ -2242,8 +2989,9 @@ std::string Rtcm::print_MSM_6( const Gps_Ephemeris & gps_eph, unsigned int msg_number = 0; if(gps_eph.i_satellite_PRN != 0) msg_number = 1076; if(gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1076; + if(glo_gnav_eph.i_satellite_PRN != 0) msg_number = 1086; if(gal_eph.i_satellite_PRN != 0) msg_number = 1096; - if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0)) + if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0) && (glo_gnav_eph.i_satellite_PRN != 0)) { LOG(WARNING) << "MSM messages for observables from different systems are not defined"; //print two messages? } @@ -2265,7 +3013,7 @@ std::string Rtcm::print_MSM_6( const Gps_Ephemeris & gps_eph, std::string sat_data = Rtcm::get_MSM_4_content_sat_data(observables); - std::string signal_data = Rtcm::get_MSM_6_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, obs_time, observables); + std::string signal_data = Rtcm::get_MSM_6_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, glo_gnav_eph, obs_time, observables); std::string message = build_message(header + sat_data + signal_data); if(server_is_running) @@ -2277,7 +3025,12 @@ std::string Rtcm::print_MSM_6( const Gps_Ephemeris & gps_eph, } -std::string Rtcm::get_MSM_6_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map & observables) +std::string Rtcm::get_MSM_6_content_signal_data(const Gps_Ephemeris & ephNAV, + const Gps_CNAV_Ephemeris & ephCNAV, + const Galileo_Ephemeris & ephFNAV, + const Glonass_Gnav_Ephemeris & ephGNAV, + double obs_time, + const std::map & observables) { std::string signal_data; std::string first_data_type; @@ -2306,7 +3059,7 @@ std::string Rtcm::get_MSM_6_content_signal_data(const Gps_Ephemeris & ephNAV, co { Rtcm::set_DF405(ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF406(ordered_by_PRN_pos.at( cell ).second); - Rtcm::set_DF407(ephNAV, ephCNAV, ephFNAV, obs_time, ordered_by_PRN_pos.at( cell ).second); + Rtcm::set_DF407(ephNAV, ephCNAV, ephFNAV, ephGNAV, obs_time, ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF420(ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF408(ordered_by_PRN_pos.at( cell ).second); first_data_type += DF405.to_string(); @@ -2331,6 +3084,7 @@ std::string Rtcm::get_MSM_6_content_signal_data(const Gps_Ephemeris & ephNAV, co std::string Rtcm::print_MSM_7( const Gps_Ephemeris & gps_eph, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Galileo_Ephemeris & gal_eph, + const Glonass_Gnav_Ephemeris & glo_gnav_eph, double obs_time, const std::map & observables, unsigned int ref_id, @@ -2343,8 +3097,9 @@ std::string Rtcm::print_MSM_7( const Gps_Ephemeris & gps_eph, unsigned int msg_number = 0; if(gps_eph.i_satellite_PRN != 0) msg_number = 1077; if(gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1077; + if(glo_gnav_eph.i_satellite_PRN != 0) msg_number = 1087; if(gal_eph.i_satellite_PRN != 0) msg_number = 1097; - if(((gps_eph.i_satellite_PRN != 0) || (gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0)) + if(((gps_eph.i_satellite_PRN != 0) || (gps_cnav_eph.i_satellite_PRN != 0) ) && (glo_gnav_eph.i_satellite_PRN != 0) && (gal_eph.i_satellite_PRN != 0)) { LOG(WARNING) << "MSM messages for observables from different systems are not defined"; //print two messages? } @@ -2366,7 +3121,7 @@ std::string Rtcm::print_MSM_7( const Gps_Ephemeris & gps_eph, std::string sat_data = Rtcm::get_MSM_5_content_sat_data(observables); - std::string signal_data = Rtcm::get_MSM_7_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, obs_time, observables); + std::string signal_data = Rtcm::get_MSM_7_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, glo_gnav_eph, obs_time, observables); std::string message = build_message(header + sat_data + signal_data); if(server_is_running) @@ -2378,7 +3133,12 @@ std::string Rtcm::print_MSM_7( const Gps_Ephemeris & gps_eph, } -std::string Rtcm::get_MSM_7_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map & observables) +std::string Rtcm::get_MSM_7_content_signal_data(const Gps_Ephemeris & ephNAV, + const Gps_CNAV_Ephemeris & ephCNAV, + const Galileo_Ephemeris & ephFNAV, + const Glonass_Gnav_Ephemeris & ephGNAV, + double obs_time, + const std::map & observables) { std::string signal_data; std::string first_data_type; @@ -2408,7 +3168,7 @@ std::string Rtcm::get_MSM_7_content_signal_data(const Gps_Ephemeris & ephNAV, co { Rtcm::set_DF405(ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF406(ordered_by_PRN_pos.at( cell ).second); - Rtcm::set_DF407(ephNAV, ephCNAV, ephFNAV, obs_time, ordered_by_PRN_pos.at( cell ).second); + Rtcm::set_DF407(ephNAV, ephCNAV, ephFNAV, ephGNAV, obs_time, ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF420(ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF408(ordered_by_PRN_pos.at( cell ).second); Rtcm::set_DF404(ordered_by_PRN_pos.at( cell ).second); @@ -2588,6 +3348,13 @@ boost::posix_time::ptime Rtcm::compute_Galileo_time(const Galileo_Ephemeris & ep } +boost::posix_time::ptime Rtcm::compute_GLONASS_time(const Glonass_Gnav_Ephemeris & eph, double obs_time) const +{ + boost::posix_time::ptime p_time = eph.compute_GLONASS_time(obs_time); + return p_time; +} + + unsigned int Rtcm::lock_time(const Gps_Ephemeris & eph, double obs_time, const Gnss_Synchro & gnss_synchro) { unsigned int lock_time_in_seconds; @@ -2663,6 +3430,49 @@ unsigned int Rtcm::lock_time(const Galileo_Ephemeris & eph, double obs_time, con } +unsigned int Rtcm::lock_time(const Glonass_Gnav_Ephemeris & eph, double obs_time, const Gnss_Synchro & gnss_synchro) +{ + unsigned int lock_time_in_seconds; + boost::posix_time::ptime current_time = Rtcm::compute_GLONASS_time(eph, obs_time); + + boost::posix_time::ptime last_lock_time; + std::string sig_(gnss_synchro.Signal); + if(sig_.compare("1C") == 0) + { + last_lock_time = Rtcm::glo_L1_last_lock_time[65 - gnss_synchro.PRN]; + } + if(sig_.compare("2C") == 0) + { + last_lock_time = Rtcm::glo_L2_last_lock_time[65 - gnss_synchro.PRN]; + } + + if(last_lock_time.is_not_a_date_time() )// || CHECK LLI!!......) + { + if(sig_.compare("1C") == 0) + { + Rtcm::glo_L1_last_lock_time[65 - gnss_synchro.PRN] = current_time; + } + if(sig_.compare("2C") == 0) + { + Rtcm::glo_L2_last_lock_time[65 - gnss_synchro.PRN] = current_time; + } + } + + boost::posix_time::time_duration lock_duration = current_time - current_time; + if(sig_.compare("1C") == 0) + { + lock_duration = current_time - Rtcm::glo_L1_last_lock_time[65 - gnss_synchro.PRN]; + } + if(sig_.compare("2C") == 0) + { + lock_duration = current_time - Rtcm::glo_L2_last_lock_time[65 - gnss_synchro.PRN]; + } + + lock_time_in_seconds = static_cast(lock_duration.total_seconds()); + return lock_time_in_seconds; +} + + unsigned int Rtcm::lock_time_indicator(unsigned int lock_time_period_s) { // Table 3.4-2 @@ -3029,6 +3839,232 @@ int Rtcm::set_DF031(unsigned int antenna_setup_id) } +int Rtcm::set_DF034(double obs_time) +{ + // TOW in milliseconds from the beginning of the GLONASS day, measured in GLONASS time + unsigned long int tk = static_cast(std::round(obs_time * 1000)); + if(tk > 86400999) + { + LOG(WARNING) << "To large GLONASS Epoch Time (tk)! Set to the last millisecond of the day"; + tk = 86400999; + } + DF034 = std::bitset<27>(tk); + return 0; +} + + +int Rtcm::set_DF035(const std::map & observables) +{ + //Number of satellites observed in current epoch + unsigned short int nsats = 0; + std::map::const_iterator observables_iter; + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + nsats++; + } + if (nsats > 31) + { + LOG(WARNING) << "The number of processed GLONASS satellites must be between 0 and 31, but it seems that you are processing " << nsats; + nsats = 31; + } + DF035 = std::bitset<5>(nsats); + return 0; +} + + +int Rtcm::set_DF036(bool divergence_free_smoothing_indicator) +{ + // 0 - Divergence-free smoothing not used 1 - Divergence-free smoothing used + DF036 = std::bitset<1>(divergence_free_smoothing_indicator); + return 0; +} + + +int Rtcm::set_DF037(short int smoothing_interval) +{ + DF037 = std::bitset<3>(smoothing_interval); + return 0; +} + + +int Rtcm::set_DF038(const Gnss_Synchro & gnss_synchro) +{ + unsigned int prn_ = gnss_synchro.PRN; + if(prn_ > 24) + { + LOG(WARNING) << "GLONASS satellite ID (Slot Number) must be between 1 and 24, but PRN " << prn_ << " was found"; + } + DF038 = std::bitset<6>(prn_); + return 0; +} + + +int Rtcm::set_DF038(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + unsigned int prn_ = glonass_gnav_eph.i_satellite_slot_number; + if(prn_ > 24) + { + LOG(WARNING) << "GLONASS satellite ID (Slot Number) must be between 0 and 24, but PRN " << prn_ << " was found"; + } + DF038 = std::bitset<6>(prn_); + return 0; +} + + +int Rtcm::set_DF039(bool code_indicator) +{ + DF039 = std::bitset<1>(code_indicator); + return 0; +} + + +int Rtcm::set_DF040(int frequency_channel_number) +{ + unsigned int freq_ = frequency_channel_number + 7; + if(freq_ > 20) + { + LOG(WARNING) << "GLONASS Satellite Frequency Number Conversion Error." + << "Value must be between 0 and 20, but converted channel" + << "frequency number " << freq_ << " was found"; + } + + DF040 = std::bitset<5>(freq_); + return 0; +} + + +int Rtcm::set_DF040(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + unsigned int freq_ = glonass_gnav_eph.i_satellite_freq_channel + 7; + if(freq_ > 20) + { + LOG(WARNING) << "GLONASS Satellite Frequency Number Conversion Error." + << "Value must be between 0 and 20, but converted channel" + << "frequency number " << freq_ << " was found"; + } + + DF040 = std::bitset<5>(freq_); + return 0; +} + + +int Rtcm::set_DF041(const Gnss_Synchro & gnss_synchro) +{ + double ambiguity = std::floor( gnss_synchro.Pseudorange_m / 599584.92 ); + unsigned long int glonass_L1_pseudorange = static_cast(std::round(( gnss_synchro.Pseudorange_m - ambiguity * 599584.92) / 0.02 )); + DF041 = std::bitset<25>(glonass_L1_pseudorange); + return 0; +} + + +int Rtcm::set_DF042(const Gnss_Synchro & gnss_synchro) +{ + const double lambda = GLONASS_C_m_s / (GLONASS_L1_CA_FREQ_HZ + (GLONASS_L1_CA_DFREQ_HZ * GLONASS_PRN.at(gnss_synchro.PRN))); + double ambiguity = std::floor( gnss_synchro.Pseudorange_m / 599584.92 ); + double glonass_L1_pseudorange = std::round(( gnss_synchro.Pseudorange_m - ambiguity * 599584.92) / 0.02 ); + double glonass_L1_pseudorange_c = glonass_L1_pseudorange * 0.02 + ambiguity * 299792.458; + double L1_phaserange_c = gnss_synchro.Carrier_phase_rads / GLONASS_TWO_PI; + double L1_phaserange_c_r = std::fmod(L1_phaserange_c - glonass_L1_pseudorange_c / lambda + 1500.0, 3000.0) - 1500.0; + long int glonass_L1_phaserange_minus_L1_pseudorange = static_cast(std::round(L1_phaserange_c_r * lambda / 0.0005 )); + DF042 = std::bitset<20>(glonass_L1_phaserange_minus_L1_pseudorange); + return 0; +} + + +int Rtcm::set_DF043(const Glonass_Gnav_Ephemeris & eph, double obs_time, const Gnss_Synchro & gnss_synchro) +{ + unsigned int lock_time_indicator; + unsigned int lock_time_period_s = Rtcm::lock_time(eph, obs_time, gnss_synchro); + lock_time_indicator = Rtcm::lock_time_indicator(lock_time_period_s); + DF043 = std::bitset<7>(lock_time_indicator); + return 0; +} + + +int Rtcm::set_DF044(const Gnss_Synchro & gnss_synchro) +{ + unsigned int glonass_L1_pseudorange_ambiguity = static_cast(std::floor(gnss_synchro.Pseudorange_m / 599584.916)); + DF044 = std::bitset<7>(glonass_L1_pseudorange_ambiguity); + return 0; +} + + +int Rtcm::set_DF045(const Gnss_Synchro & gnss_synchro) +{ + double CN0_dB_Hz_est = gnss_synchro.CN0_dB_hz; + if (CN0_dB_Hz_est > 63.75) + { + LOG(WARNING) << "GLONASS L1 CNR must be between 0 and 63.75, but CNR " << CN0_dB_Hz_est << " was found. Setting to 63.75 dB-Hz"; + CN0_dB_Hz_est = 63.75; + } + unsigned int CN0_dB_Hz = static_cast(std::round(CN0_dB_Hz_est / 0.25 )); + DF045 = std::bitset<8>(CN0_dB_Hz); + return 0; +} + + +int Rtcm::set_DF047(const Gnss_Synchro & gnss_synchroL1, const Gnss_Synchro & gnss_synchroL2) +{ + double ambiguity = std::floor( gnss_synchroL1.Pseudorange_m / 599584.92 ); + double glonass_L1_pseudorange = std::round(( gnss_synchroL1.Pseudorange_m - ambiguity * 599584.92) / 0.02 ); + double glonass_L1_pseudorange_c = glonass_L1_pseudorange * 0.02 + ambiguity * 599584.92; + + double l2_l1_pseudorange = gnss_synchroL2.Pseudorange_m - glonass_L1_pseudorange_c; + int pseudorange_difference = 0xFFFFE000; // invalid value; + if(std::fabs(l2_l1_pseudorange) <= 163.82) + { + pseudorange_difference = static_cast(std::round(l2_l1_pseudorange / 0.02)); + } + DF047 = std::bitset<14>(pseudorange_difference); + return 0; +} + +//TODO Need to consider frequency channel in this fields +int Rtcm::set_DF048(const Gnss_Synchro & gnss_synchroL1, const Gnss_Synchro & gnss_synchroL2) +{ + const double lambda2 = GLONASS_C_m_s / GLONASS_L2_FREQ_HZ; + int l2_phaserange_minus_l1_pseudorange = 0xFFF80000; + double ambiguity = std::floor( gnss_synchroL1.Pseudorange_m / 599584.92 ); + double glonass_L1_pseudorange = std::round(( gnss_synchroL1.Pseudorange_m - ambiguity * 599584.92) / 0.02 ); + double glonass_L1_pseudorange_c = glonass_L1_pseudorange * 0.02 + ambiguity * 599584.92; + double L2_phaserange_c = gnss_synchroL2.Carrier_phase_rads / GLONASS_TWO_PI; + double L1_phaserange_c_r = std::fmod(L2_phaserange_c - glonass_L1_pseudorange_c / lambda2 + 1500.0, 3000.0) - 1500.0; + + if (std::fabs(L1_phaserange_c_r * lambda2) <= 262.1435 ) + { + l2_phaserange_minus_l1_pseudorange = static_cast(std::round(L1_phaserange_c_r * lambda2 / 0.0005)); + } + + DF048 = std::bitset<20>(l2_phaserange_minus_l1_pseudorange); + return 0; +} + + +int Rtcm::set_DF049(const Glonass_Gnav_Ephemeris & eph, double obs_time, const Gnss_Synchro & gnss_synchro) +{ + unsigned int lock_time_indicator; + unsigned int lock_time_period_s = Rtcm::lock_time(eph, obs_time, gnss_synchro); + lock_time_indicator = Rtcm::lock_time_indicator(lock_time_period_s); + DF049 = std::bitset<7>(lock_time_indicator); + return 0; +} + + +int Rtcm::set_DF050(const Gnss_Synchro & gnss_synchro) +{ + double CN0_dB_Hz_est = gnss_synchro.CN0_dB_hz; + if (CN0_dB_Hz_est > 63.75) + { + CN0_dB_Hz_est = 63.75; + } + unsigned int CN0_dB_Hz = static_cast(std::round(CN0_dB_Hz_est / 0.25 )); + DF050 = std::bitset<8>(CN0_dB_Hz); + return 0; +} + + int Rtcm::set_DF051(const Gps_Ephemeris & gps_eph, double obs_time) { const double gps_t = obs_time; @@ -3289,6 +4325,318 @@ int Rtcm::set_DF103(const Gps_Ephemeris & gps_eph) } +int Rtcm::set_DF104(unsigned int glonass_gnav_alm_health) +{ + DF104 = std::bitset<1>(glonass_gnav_alm_health); + return 0; +} + + +int Rtcm::set_DF105(unsigned int glonass_gnav_alm_health_ind) +{ + DF105 = std::bitset<1>(glonass_gnav_alm_health_ind); + return 0; +} + + +int Rtcm::set_DF106(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + // Convert the value from (15, 30, 45, 60) to (00, 01, 10, 11) + unsigned int P_1 = static_cast(std::round(glonass_gnav_eph.d_P_1/15.0 -1.0)); + DF106 = std::bitset<2>(P_1); + return 0; +} + + +int Rtcm::set_DF107(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + unsigned int hrs = 0; + unsigned int min = 0; + unsigned int sec = 0; + unsigned int tk = 0; + tk = static_cast(glonass_gnav_eph.d_t_k); + hrs = tk/3600; + min = (tk - hrs*3600)/60; + sec = (tk - hrs*3600 -min*60)/60; + + std::string _hrs = std::bitset< 5 >( hrs ).to_string(); // string conversion + std::string _min = std::bitset< 6 >( min ).to_string(); // string conversion + std::string _sec = std::bitset< 1 >( sec ).to_string(); // string conversion + + // Set hrs, min, sec in designed bit positions + DF107 = std::bitset<12>(_hrs + _min + _sec); + + return 0; +} + + +int Rtcm::set_DF108(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + DF108 = std::bitset<1>(glonass_gnav_eph.d_B_n); + return 0; +} + + +int Rtcm::set_DF109(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + DF109 = std::bitset<1>(glonass_gnav_eph.d_P_2); + return 0; +} + + +int Rtcm::set_DF110(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + unsigned int t_b = static_cast(std::round(glonass_gnav_eph.d_t_b/(15*60))); + DF110 = std::bitset<7>(t_b); + return 0; +} + + +int Rtcm::set_DF111(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + int VXn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_VXn/TWO_N20))); + unsigned int VXn_sgn = glo_sgn(glonass_gnav_eph.d_VXn); + + DF111 = std::bitset<24>(VXn_mag); + DF111.set(23,VXn_sgn); + return 0; +} + + +int Rtcm::set_DF112(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + int Xn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_Xn/TWO_N11))); + unsigned int Xn_sgn = glo_sgn(glonass_gnav_eph.d_Xn); + + DF112 = std::bitset<27>(Xn_mag); + DF112.set(26,Xn_sgn); + return 0; +} + + +int Rtcm::set_DF113(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + int AXn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_AXn/TWO_N30))); + unsigned int AXn_sgn = glo_sgn(glonass_gnav_eph.d_AXn); + + DF113 = std::bitset<5>(AXn_mag); + DF113.set(4,AXn_sgn); + return 0; +} + + +int Rtcm::set_DF114(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + int VYn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_VYn/TWO_N20))); + unsigned int VYn_sgn = glo_sgn(glonass_gnav_eph.d_VYn); + + DF114 = std::bitset<24>(VYn_mag); + DF114.set(23,VYn_sgn); + return 0; +} + + +int Rtcm::set_DF115(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + int Yn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_Yn/TWO_N11))); + unsigned int Yn_sgn = glo_sgn(glonass_gnav_eph.d_Yn); + + DF115 = std::bitset<27>(Yn_mag); + DF115.set(26,Yn_sgn); + return 0; +} + + +int Rtcm::set_DF116(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + int AYn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_AYn/TWO_N30))); + unsigned int AYn_sgn = glo_sgn(glonass_gnav_eph.d_AYn); + + DF116 = std::bitset<5>(AYn_mag); + DF116.set(4,AYn_sgn); + return 0; +} + + + +int Rtcm::set_DF117(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + int VZn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_VZn/TWO_N20))); + unsigned int VZn_sgn = glo_sgn(glonass_gnav_eph.d_VZn); + + DF117 = std::bitset<24>(VZn_mag); + DF117.set(23,VZn_sgn); + return 0; +} + + + +int Rtcm::set_DF118(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + int Zn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_Zn/TWO_N11))); + unsigned int Zn_sgn = glo_sgn(glonass_gnav_eph.d_Zn); + + DF118 = std::bitset<27>(Zn_mag); + DF118.set(26,Zn_sgn); + return 0; +} + + + +int Rtcm::set_DF119(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + int AZn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_AZn/TWO_N30))); + unsigned int AZn_sgn = glo_sgn(glonass_gnav_eph.d_AZn); + + DF119 = std::bitset<5>(AZn_mag); + DF119.set(4,AZn_sgn); + return 0; +} + + +int Rtcm::set_DF120(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + unsigned int P3 = static_cast(std::round(glonass_gnav_eph.d_P_3)); + DF120 = std::bitset<1>(P3); + return 0; +} + + +int Rtcm::set_DF121(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + int gamma_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_gamma_n/TWO_N40))); + unsigned int gamma_sgn = glo_sgn(glonass_gnav_eph.d_gamma_n); + + DF121 = std::bitset<11>(gamma_mag); + DF121.set(10,gamma_sgn); + return 0; +} + + +int Rtcm::set_DF122(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + unsigned int P = static_cast(std::round(glonass_gnav_eph.d_P)); + DF122 = std::bitset<2>(P); + return 0; +} + + +int Rtcm::set_DF123(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + unsigned int ln = static_cast((glonass_gnav_eph.d_l3rd_n)); + DF123 = std::bitset<1>(ln); + return 0; +} + + +int Rtcm::set_DF124(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + int tau_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_tau_n/TWO_N30))); + unsigned int tau_sgn = glo_sgn(glonass_gnav_eph.d_tau_n); + + DF124 = std::bitset<22>(tau_mag); + DF124.set(21,tau_sgn); + return 0; +} + + +int Rtcm::set_DF125(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + int delta_tau_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_Delta_tau_n/TWO_N30))); + unsigned int delta_tau_sgn = glo_sgn(glonass_gnav_eph.d_Delta_tau_n); + + DF125 = std::bitset<5>(delta_tau_mag); + DF125.set(4,delta_tau_sgn); + return 0; +} + + +int Rtcm::set_DF126(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + unsigned int ecc = static_cast(std::round(glonass_gnav_eph.d_E_n)); + DF126 = std::bitset<5>(ecc); + return 0; +} + + +int Rtcm::set_DF127(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + unsigned int P4= static_cast(std::round(glonass_gnav_eph.d_P_4)); + DF127 = std::bitset<1>(P4); + return 0; +} + + +int Rtcm::set_DF128(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + unsigned int F_t = static_cast(std::round(glonass_gnav_eph.d_F_T)); + DF128 = std::bitset<4>(F_t); + return 0; +} + + +int Rtcm::set_DF129(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + unsigned int N_t = static_cast(std::round(glonass_gnav_eph.d_N_T)); + DF129 = std::bitset<11>(N_t); + return 0; +} + + +int Rtcm::set_DF130(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + unsigned int M = static_cast(std::round(glonass_gnav_eph.d_M)); + DF130 = std::bitset<2>(M); + return 0; +} + + +int Rtcm::set_DF131(unsigned int fifth_str_additional_data_ind) +{ + unsigned int fith_str_data = static_cast(fifth_str_additional_data_ind); + DF131 = std::bitset<1>(fith_str_data); + return 0; +} + + +int Rtcm::set_DF132(const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model) +{ + unsigned int N_A = static_cast(std::round(glonass_gnav_utc_model.d_N_A)); + DF132 = std::bitset<11>(N_A); + return 0; +} + + +int Rtcm::set_DF133(const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model) +{ + int tau_c = static_cast(std::round(glonass_gnav_utc_model.d_tau_c/TWO_N31)); + DF133 = std::bitset<32>(tau_c); + return 0; +} + + +int Rtcm::set_DF134(const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model) +{ + unsigned int N_4 = static_cast(std::round(glonass_gnav_utc_model.d_N_4)); + DF134 = std::bitset<5>(N_4); + return 0; +} + + +int Rtcm::set_DF135(const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model) +{ + int tau_gps = static_cast(std::round(glonass_gnav_utc_model.d_tau_gps)/TWO_N30); + DF135 = std::bitset<22>(tau_gps); + return 0; +} + + +int Rtcm::set_DF136(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +{ + unsigned int l_n = static_cast(std::round(glonass_gnav_eph.d_l5th_n)); + DF136 = std::bitset<1>(l_n); + return 0; +} int Rtcm::set_DF137(const Gps_Ephemeris & gps_eph) @@ -3629,6 +4977,16 @@ int Rtcm::set_DF395(const std::map & gnss_synchro) mask_position = 32 - 16; DF395.set(mask_position, true); } + if ((sig.compare("1C") == 0) && (sys.compare("R") == 0 ) ) + { + mask_position = 32 - 2; + DF395.set(mask_position, true); + } + if ((sig.compare("2C") == 0) && (sys.compare("R") == 0 ) ) + { + mask_position = 32 - 8; + DF395.set(mask_position, true); + } } return 0; @@ -3889,27 +5247,37 @@ int Rtcm::set_DF401(const Gnss_Synchro & gnss_synchro) double lambda = 0.0; std::string sig_(gnss_synchro.Signal); std::string sig = sig_.substr(0,2); + std::string sys(&gnss_synchro.System, 1); - if (sig.compare("1C") == 0 ) + if ((sig.compare("1C") == 0) && (sys.compare("G") == 0 )) { lambda = GPS_C_m_s / GPS_L1_FREQ_HZ; } - if (sig.compare("2S") == 0 ) + if ((sig.compare("2S")) == 0 && (sys.compare("G") == 0 )) { lambda = GPS_C_m_s / GPS_L2_FREQ_HZ; } - if (sig.compare("5X") == 0 ) + if ((sig.compare("5X")) == 0 && (sys.compare("E") == 0 )) { lambda = GPS_C_m_s / Galileo_E5a_FREQ_HZ; } - if (sig.compare("1B") == 0 ) + if ((sig.compare("1B")) == 0 && (sys.compare("E") == 0 )) { lambda = GPS_C_m_s / Galileo_E1_FREQ_HZ; } - if (sig.compare("7X") == 0 ) + if ((sig.compare("7X")) == 0 && (sys.compare("E") == 0 )) { lambda = GPS_C_m_s / 1.207140e9; // Galileo_E1b_FREQ_HZ; } + if ((sig.compare("1C") == 0) && (sys.compare("R") == 0 )) + { + lambda = GLONASS_C_m_s / ((GLONASS_L1_CA_FREQ_HZ + (GLONASS_L1_CA_DFREQ_HZ * GLONASS_PRN.at(gnss_synchro.PRN)))); + } + if ((sig.compare("2C") == 0) && (sys.compare("R") == 0 )) + { + // TODO Need to add slot number and freq number to gnss_syncro + lambda = GLONASS_C_m_s / (GLONASS_L2_FREQ_HZ); + } phrng_m = (gnss_synchro.Carrier_phase_rads / GPS_TWO_PI ) * lambda - rough_range_m; @@ -3940,23 +5308,33 @@ int Rtcm::set_DF401(const Gnss_Synchro & gnss_synchro) } -int Rtcm::set_DF402(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const Gnss_Synchro & gnss_synchro) +int Rtcm::set_DF402(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, const Glonass_Gnav_Ephemeris & ephGNAV, double obs_time, const Gnss_Synchro & gnss_synchro) { unsigned int lock_time_period_s = 0; unsigned int lock_time_indicator; std::string sig_(gnss_synchro.Signal); - if(sig_.compare("1C")) + std::string sys(&gnss_synchro.System, 1); + if ((sig_.compare("1C") == 0) && (sys.compare("G") == 0 )) { lock_time_period_s = Rtcm::lock_time(ephNAV, obs_time, gnss_synchro); } - if(sig_.compare("2S")) + if ((sig_.compare("2S") == 0) && (sys.compare("G") == 0 )) { lock_time_period_s = Rtcm::lock_time(ephCNAV, obs_time, gnss_synchro); } + // TODO Should add system for galileo satellites if(sig_.compare("1B") || sig_.compare("5X") || sig_.compare("7X") || sig_.compare("8X")) { lock_time_period_s = Rtcm::lock_time(ephFNAV, obs_time, gnss_synchro); } + if ((sig_.compare("1C") == 0) && (sys.compare("R") == 0 )) + { + lock_time_period_s = Rtcm::lock_time(ephGNAV, obs_time, gnss_synchro); + } + if ((sig_.compare("2C") == 0) && (sys.compare("R") == 0 )) + { + lock_time_period_s = Rtcm::lock_time(ephGNAV, obs_time, gnss_synchro); + } lock_time_indicator = Rtcm::msm_lock_time_indicator(lock_time_period_s); DF402 = std::bitset<4>(lock_time_indicator); return 0; @@ -3978,28 +5356,37 @@ int Rtcm::set_DF404(const Gnss_Synchro & gnss_synchro) std::string sig_(gnss_synchro.Signal); std::string sig = sig_.substr(0,2); int fine_phaserange_rate; + std::string sys_(&gnss_synchro.System, 1); - if (sig.compare("1C") == 0 ) + if ((sig_.compare("1C") == 0) && (sys_.compare("G") == 0 )) { lambda = GPS_C_m_s / GPS_L1_FREQ_HZ; } - if (sig.compare("2S") == 0 ) + if ((sig_.compare("2S") == 0) && (sys_.compare("G") == 0 )) { lambda = GPS_C_m_s / GPS_L2_FREQ_HZ; } - if (sig.compare("5X") == 0 ) + if ((sig_.compare("5X") == 0) && (sys_.compare("E") == 0 )) { lambda = GPS_C_m_s / Galileo_E5a_FREQ_HZ; } - if (sig.compare("1B") == 0 ) + if ((sig_.compare("1B") == 0) && (sys_.compare("E") == 0 )) { lambda = GPS_C_m_s / Galileo_E1_FREQ_HZ; } - if (sig.compare("7X") == 0 ) + if ((sig_.compare("7X") == 0 ) && (sys_.compare("E") == 0 )) { lambda = GPS_C_m_s / 1.207140e9; // Galileo_E1b_FREQ_HZ; } - + if ((sig_.compare("1C") == 0) && (sys_.compare("R") == 0 )) + { + lambda = GLONASS_C_m_s / (GLONASS_L1_CA_FREQ_HZ + (GLONASS_L1_CA_DFREQ_HZ * GLONASS_PRN.at(gnss_synchro.PRN))); + } + if ((sig_.compare("2C") == 0) && (sys_.compare("R") == 0 )) + { + //TODO Need to add slot number and freq number to gnss syncro + lambda = GLONASS_C_m_s / (GLONASS_L2_FREQ_HZ); + } double rough_phase_range_rate = std::round(- gnss_synchro.Carrier_Doppler_hz * lambda ); double phrr = (- gnss_synchro.Carrier_Doppler_hz * lambda - rough_phase_range_rate); @@ -4056,29 +5443,38 @@ int Rtcm::set_DF406(const Gnss_Synchro & gnss_synchro) double phrng_m; double lambda = 0.0; std::string sig_(gnss_synchro.Signal); - std::string sig = sig_.substr(0,2); + sig_ = sig_.substr(0,2); + std::string sys_(&gnss_synchro.System, 1); - if (sig.compare("1C") == 0 ) + if ((sig_.compare("1C") == 0) && (sys_.compare("G") == 0 ) ) { lambda = GPS_C_m_s / GPS_L1_FREQ_HZ; } - if (sig.compare("2S") == 0 ) + if ((sig_.compare("2S") == 0) && (sys_.compare("G") == 0 ) ) { lambda = GPS_C_m_s / GPS_L2_FREQ_HZ; } - if (sig.compare("5X") == 0 ) + if ((sig_.compare("5X") == 0) && (sys_.compare("E") == 0 ) ) { lambda = GPS_C_m_s / Galileo_E5a_FREQ_HZ; } - if (sig.compare("1B") == 0 ) + if ((sig_.compare("1B") == 0) && (sys_.compare("E") == 0 ) ) { lambda = GPS_C_m_s / Galileo_E1_FREQ_HZ; } - if (sig.compare("7X") == 0 ) + if ((sig_.compare("7X") == 0 ) && (sys_.compare("E") == 0 ) ) { lambda = GPS_C_m_s / 1.207140e9; // Galileo_E1b_FREQ_HZ; } - + if ((sig_.compare("1C") == 0) && (sys_.compare("R") == 0 )) + { + lambda = GLONASS_C_m_s / (GLONASS_L1_CA_FREQ_HZ + (GLONASS_L1_CA_DFREQ_HZ * GLONASS_PRN.at(gnss_synchro.PRN))); + } + if ((sig_.compare("2C") == 0) && (sys_.compare("R") == 0 )) + { + //TODO Need to add slot number and freq number to gnss syncro + lambda = GLONASS_C_m_s / (GLONASS_L2_FREQ_HZ); + } phrng_m = (gnss_synchro.Carrier_phase_rads / GPS_TWO_PI ) * lambda - rough_range_m; /* Substract phase - pseudorange integer cycle offset */ @@ -4108,24 +5504,33 @@ int Rtcm::set_DF406(const Gnss_Synchro & gnss_synchro) } -int Rtcm::set_DF407(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const Gnss_Synchro & gnss_synchro) +int Rtcm::set_DF407(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, const Glonass_Gnav_Ephemeris & ephGNAV, double obs_time, const Gnss_Synchro & gnss_synchro) { unsigned int lock_time_indicator; unsigned int lock_time_period_s = 0; std::string sig_(gnss_synchro.Signal); - if(sig_.compare("1C")) + std::string sys_(&gnss_synchro.System, 1); + if((sig_.compare("1C")) && (sys_.compare("G") == 0 )) { lock_time_period_s = Rtcm::lock_time(ephNAV, obs_time, gnss_synchro); } - if(sig_.compare("2S")) + if((sig_.compare("2S")) && (sys_.compare("G") == 0 )) { lock_time_period_s = Rtcm::lock_time(ephCNAV, obs_time, gnss_synchro); } - if(sig_.compare("1B") || sig_.compare("5X") || sig_.compare("7X") || sig_.compare("8X")) + if((sig_.compare("1B") || sig_.compare("5X") || sig_.compare("7X") || sig_.compare("8X") ) && (sys_.compare("E") == 0 )) { lock_time_period_s = Rtcm::lock_time(ephFNAV, obs_time, gnss_synchro); } + if ((sig_.compare("1C") == 0) && (sys_.compare("R") == 0 )) + { + lock_time_period_s = Rtcm::lock_time(ephGNAV, obs_time, gnss_synchro); + } + if ((sig_.compare("2C") == 0) && (sys_.compare("R") == 0 )) + { + lock_time_period_s = Rtcm::lock_time(ephGNAV, obs_time, gnss_synchro); + } lock_time_indicator = Rtcm::msm_extended_lock_time_indicator(lock_time_period_s); DF407 = std::bitset<10>(lock_time_indicator); return 0; diff --git a/src/core/system_parameters/rtcm.h b/src/core/system_parameters/rtcm.h index 8b3333ffe..f19b71add 100644 --- a/src/core/system_parameters/rtcm.h +++ b/src/core/system_parameters/rtcm.h @@ -49,6 +49,7 @@ #include "galileo_fnav_message.h" #include "gps_navigation_message.h" #include "gps_cnav_navigation_message.h" +#include "glonass_gnav_navigation_message.h" /*! @@ -56,7 +57,7 @@ * defined in the RTCM 3.2 Standard, plus some utilities to handle messages. * * Generation of the following Message Types: - * 1001, 1002, 1003, 1004, 1005, 1006, 1008, 1019, 1029, 1045 + * 1001, 1002, 1003, 1004, 1005, 1006, 1008, 1019, 1020, 1029, 1045 * * Decoding of the following Message Types: * 1019, 1045 @@ -128,6 +129,47 @@ public: */ std::string print_MT1008(unsigned int ref_id, const std::string & antenna_descriptor, unsigned int antenna_setup_id, const std::string & antenna_serial_number); + /*! + * \brief Prints L1-Only GLONASS RTK Observables + * \details This GLONASS message type is not generally used or supported; type 1012 is to be preferred. + * \note Code added as part of GSoC 2017 program + * \param glonass_gnav_eph GLONASS GNAV Broadcast Ephemeris + * \param obs_time Time of observation at the moment of printing + * \param observables Set of observables as defined by the platform + * \return string with message contents + */ + std::string print_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map & observables, unsigned short station_id); + /*! + * \brief Prints Extended L1-Only GLONASS RTK Observables + * \details This GLONASS message type is used when only L1 data is present and bandwidth is very tight, often 1012 is used in such cases. + * \note Code added as part of GSoC 2017 program + * \param glonass_gnav_eph GLONASS GNAV Broadcast Ephemeris + * \param obs_time Time of observation at the moment of printing + * \param observables Set of observables as defined by the platform + * \return string with message contents + */ + std::string print_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map & observables, unsigned short station_id); + /*! + * \brief Prints L1&L2 GLONASS RTK Observables + * \details This GLONASS message type is not generally used or supported; type 1012 is to be preferred + * \note Code added as part of GSoC 2017 program + * \param glonass_gnav_eph GLONASS GNAV Broadcast Ephemeris + * \param obs_time Time of observation at the moment of printing + * \param observables Set of observables as defined by the platform + * \return string with message contents + */ + std::string print_MT1011(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map & observables, unsigned short station_id); + /*! + * \brief Prints Extended L1&L2 GLONASS RTK Observables + * \details This GLONASS message type is the most common observational message type, with L1/L2/SNR content. This is one of the most common messages found. + * \note Code added as part of GSoC 2017 program + * \param glonass_gnav_eph GLONASS GNAV Broadcast Ephemeris + * \param obs_time Time of observation at the moment of printing + * \param observables Set of observables as defined by the platform + * \return string with message contents + */ + std::string print_MT1012(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map & observables, unsigned short station_id); + /*! * \brief Prints message type 1019 (GPS Ephemeris), should be broadcast in the event that * the IODC does not match the IODE, and every 2 minutes. @@ -139,6 +181,25 @@ public: */ int read_MT1019(const std::string & message, Gps_Ephemeris & gps_eph); + /*! + * \brief Prints message type 1020 (GLONASS Ephemeris). + * \note Code added as part of GSoC 2017 program + * \param glonass_gnav_eph GLONASS GNAV Broadcast Ephemeris + * \param glonass_gnav_utc_model GLONASS GNAV Clock Information + * \return Returns message type as a string type + */ + std::string print_MT1020(const Glonass_Gnav_Ephemeris & glonass_gnav_eph, const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model); + + /*! + * \brief Verifies and reads messages of type 1020 (GLONASS Ephemeris). + * \note Code added as part of GSoC 2017 program + * \param message Message to read as a string type + * \param glonass_gnav_eph GLONASS GNAV Broadcast Ephemeris + * \param glonass_gnav_utc_model GLONASS GNAV Clock Information + * \return Returns 1 if anything goes wrong, 0 otherwise. + */ + int read_MT1020(const std::string & message, Glonass_Gnav_Ephemeris & glonass_gnav_eph, Glonass_Gnav_Utc_Model & glonass_gnav_utc_model); + /*! * \brief Prints message type 1029 (Unicode Text String) */ @@ -160,6 +221,7 @@ public: std::string print_MSM_1( const Gps_Ephemeris & gps_eph, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Galileo_Ephemeris & gal_eph, + const Glonass_Gnav_Ephemeris & glo_gnav_eph, double obs_time, const std::map & observables, unsigned int ref_id, @@ -175,6 +237,7 @@ public: std::string print_MSM_2( const Gps_Ephemeris & gps_eph, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Galileo_Ephemeris & gal_eph, + const Glonass_Gnav_Ephemeris & glo_gnav_eph, double obs_time, const std::map & observables, unsigned int ref_id, @@ -190,6 +253,7 @@ public: std::string print_MSM_3( const Gps_Ephemeris & gps_eph, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Galileo_Ephemeris & gal_eph, + const Glonass_Gnav_Ephemeris & glo_gnav_eph, double obs_time, const std::map & observables, unsigned int ref_id, @@ -205,6 +269,7 @@ public: std::string print_MSM_4( const Gps_Ephemeris & gps_eph, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Galileo_Ephemeris & gal_eph, + const Glonass_Gnav_Ephemeris & glo_gnav_eph, double obs_time, const std::map & observables, unsigned int ref_id, @@ -220,6 +285,7 @@ public: std::string print_MSM_5( const Gps_Ephemeris & gps_eph, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Galileo_Ephemeris & gal_eph, + const Glonass_Gnav_Ephemeris & glo_gnav_eph, double obs_time, const std::map & observables, unsigned int ref_id, @@ -235,6 +301,7 @@ public: std::string print_MSM_6( const Gps_Ephemeris & gps_eph, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Galileo_Ephemeris & gal_eph, + const Glonass_Gnav_Ephemeris & glo_gnav_eph, double obs_time, const std::map & observables, unsigned int ref_id, @@ -250,6 +317,7 @@ public: std::string print_MSM_7( const Gps_Ephemeris & gps_eph, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Galileo_Ephemeris & gal_eph, + const Glonass_Gnav_Ephemeris & glo_gnav_eph, double obs_time, const std::map & observables, unsigned int ref_id, @@ -262,6 +330,15 @@ public: unsigned int lock_time(const Gps_Ephemeris & eph, double obs_time, const Gnss_Synchro & gnss_synchro); // get_MT1005_test(); + /*! + * \brief Generates contents of message header for types 1009, 1010, 1011 and 1012. GLONASS RTK Message + * \note Code added as part of GSoC 2017 program + * \param msg_number Message type number, acceptable options include 1009 to 1012 + * \param obs_time Time of observation at the moment of printing + * \param observables Set of observables as defined by the platform + * \param ref_id + * \param smooth_int + * \param divergence_free + * \return Returns the message header content as set of bits + */ + std::bitset<61> get_MT1009_12_header(unsigned int msg_number, + double obs_time, + const std::map & observables, + unsigned int ref_id, + unsigned int smooth_int, + bool sync_flag, + bool divergence_free); + + /*! + * \brief Get the contents of the satellite specific portion of a type 1009 Message (GLONASS Basic RTK, L1 Only) + * \details Contents generated for each satellite. See table 3.5-11 + * \note Code added as part of GSoC 2017 program + * \param ephGNAV Ephemeris for GLONASS GNAV in L1 satellites + * \param obs_time Time of observation at the moment of printing + * \param gnss_synchro Information generated by channels while processing the satellite + * \return Returns the message content as set of bits + */ + std::bitset<64> get_MT1009_sat_content(const Glonass_Gnav_Ephemeris & ephGNAV, double obs_time, const Gnss_Synchro & gnss_synchro); + /*! + * \brief Get the contents of the satellite specific portion of a type 1010 Message (GLONASS Extended RTK, L1 Only) + * \details Contents generated for each satellite. See table 3.5-12 + * \note Code added as part of GSoC 2017 program + * \param ephGNAV Ephemeris for GLONASS GNAV in L1 satellites + * \param obs_time Time of observation at the moment of printing + * \param gnss_synchro Information generated by channels while processing the satellite + * \return Returns the message content as set of bits + */ + std::bitset<79> get_MT1010_sat_content(const Glonass_Gnav_Ephemeris & ephGNAV, double obs_time, const Gnss_Synchro & gnss_synchro); + /*! + * \brief Get the contents of the satellite specific portion of a type 1011 Message (GLONASS Basic RTK, L1 & L2) + * \details Contents generated for each satellite. See table 3.5-13 + * \note Code added as part of GSoC 2017 program + * \param ephGNAVL1 Ephemeris for GLONASS GNAV in L1 satellites + * \param ephGNAVL2 Ephemeris for GLONASS GNAV in L2 satellites + * \param obs_time Time of observation at the moment of printing + * \param gnss_synchroL1 Information generated by channels while processing the GLONASS GNAV L1 satellite + * \param gnss_synchroL2 Information generated by channels while processing the GLONASS GNAV L2 satellite + * \return Returns the message content as set of bits + */ + std::bitset<107> get_MT1011_sat_content(const Glonass_Gnav_Ephemeris & ephGNAVL1, const Glonass_Gnav_Ephemeris & ephGNAVL2, double obs_time, const Gnss_Synchro & gnss_synchroL1, const Gnss_Synchro & gnss_synchroL2); + /*! + * \brief Get the contents of the satellite specific portion of a type 1012 Message (GLONASS Extended RTK, L1 & L2) + * \details Contents generated for each satellite. See table 3.5-14 + * \note Code added as part of GSoC 2017 program + * \param ephGNAVL1 Ephemeris for GLONASS GNAV in L1 satellites + * \param ephGNAVL2 Ephemeris for GLONASS GNAV in L2 satellites + * \param obs_time Time of observation at the moment of printing + * \param gnss_synchroL1 Information generated by channels while processing the GLONASS GNAV L1 satellite + * \param gnss_synchroL2 Information generated by channels while processing the GLONASS GNAV L2 satellite + * \return Returns the message content as set of bits + */ + std::bitset<130> get_MT1012_sat_content(const Glonass_Gnav_Ephemeris & ephGNAVL1, const Glonass_Gnav_Ephemeris & ephGNAVL2, double obs_time, const Gnss_Synchro & gnss_synchroL1, const Gnss_Synchro & gnss_synchroL2); + std::string get_MSM_header(unsigned int msg_number, double obs_time, const std::map & observables, @@ -318,12 +467,12 @@ private: std::string get_MSM_5_content_sat_data(const std::map & observables); std::string get_MSM_1_content_signal_data(const std::map & observables); - std::string get_MSM_2_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map & observables); - std::string get_MSM_3_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map & observables); - std::string get_MSM_4_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map & observables); - std::string get_MSM_5_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map & observables); - std::string get_MSM_6_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map & observables); - std::string get_MSM_7_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map & observables); + std::string get_MSM_2_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, const Glonass_Gnav_Ephemeris & ephGNAV, double obs_time, const std::map & observables); + std::string get_MSM_3_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, const Glonass_Gnav_Ephemeris & ephGNAV, double obs_time, const std::map & observables); + std::string get_MSM_4_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, const Glonass_Gnav_Ephemeris & ephGNAV, double obs_time, const std::map & observables); + std::string get_MSM_5_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, const Glonass_Gnav_Ephemeris & ephGNAV, double obs_time, const std::map & observables); + std::string get_MSM_6_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, const Glonass_Gnav_Ephemeris & ephGNAV, double obs_time, const std::map & observables); + std::string get_MSM_7_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, const Glonass_Gnav_Ephemeris & ephGNAV, double obs_time, const std::map & observables); // // Utilities @@ -335,10 +484,13 @@ private: boost::posix_time::ptime compute_GPS_time(const Gps_Ephemeris& eph, double obs_time) const; boost::posix_time::ptime compute_GPS_time(const Gps_CNAV_Ephemeris & eph, double obs_time) const; boost::posix_time::ptime compute_Galileo_time(const Galileo_Ephemeris& eph, double obs_time) const; + boost::posix_time::ptime compute_GLONASS_time(const Glonass_Gnav_Ephemeris& eph, double obs_time) const; boost::posix_time::ptime gps_L1_last_lock_time[64]; boost::posix_time::ptime gps_L2_last_lock_time[64]; boost::posix_time::ptime gal_E1_last_lock_time[64]; boost::posix_time::ptime gal_E5_last_lock_time[64]; + boost::posix_time::ptime glo_L1_last_lock_time[64]; + boost::posix_time::ptime glo_L2_last_lock_time[64]; unsigned int lock_time_indicator(unsigned int lock_time_period_s); unsigned int msm_lock_time_indicator(unsigned int lock_time_period_s); unsigned int msm_extended_lock_time_indicator(unsigned int lock_time_period_s); @@ -870,6 +1022,65 @@ private: std::bitset<8> DF032; + /*! + * \brief Sets the Data Field value + * \note Code added as part of GSoC 2017 program + * \param obs_time Time of observation at the moment of printing + * \return returns 0 upon success + */ + int set_DF034(double obs_time); + std::bitset<27> DF034; //!< GLONASS Epoch Time (tk) + + std::bitset<5> DF035; //!< No. of GLONASS Satellite Signals Processed + int set_DF035(const std::map & observables); + + std::bitset<1> DF036; //!< GLONASS Divergence-free Smoothing Indicator + int set_DF036(bool divergence_free_smoothing_indicator); + + std::bitset<3> DF037; //!< GLONASS Smoothing Interval + int set_DF037(short int smoothing_interval); + + std::bitset<6> DF038; //!< GLONASS Satellite ID (Satellite Slot Number) + int set_DF038(const Gnss_Synchro & gnss_synchro); + int set_DF038(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<1> DF039; //!< GLONASS L1 Code Indicator + int set_DF039(bool code_indicator); + + std::bitset<5> DF040; //!< GLONASS Satellite Frequency Number + int set_DF040(int frequency_channel_number); + int set_DF040(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<25> DF041; //!< GLONASS L1 Pseudorange + int set_DF041(const Gnss_Synchro & gnss_synchro); + + std::bitset<20> DF042; //!< GLONASS L1 PhaseRange - L1 Pseudorange + int set_DF042(const Gnss_Synchro & gnss_synchro); + + std::bitset<7> DF043; //!< GLONASS L1 Lock Time Indicator + int set_DF043(const Glonass_Gnav_Ephemeris & eph, double obs_time, const Gnss_Synchro & gnss_synchro); + + std::bitset<7> DF044; //!< GLONASS Integer L1 Pseudorange Modulus Ambiguity + int set_DF044(const Gnss_Synchro & gnss_synchro); + + std::bitset<8> DF045; //!< GLONASS L1 CNR + int set_DF045(const Gnss_Synchro & gnss_synchro); + + std::bitset<2> DF046; //!< GLONASS L2 code indicator + int set_DF046(unsigned short code_indicator); + + std::bitset<14> DF047; //!< GLONASS L2 - L1 Pseudorange Difference + int set_DF047(const Gnss_Synchro & gnss_synchroL1, const Gnss_Synchro & gnss_synchroL2); + + std::bitset<20> DF048; //!< GLONASS L2 PhaseRange - L1 Pseudorange + int set_DF048(const Gnss_Synchro & gnss_synchroL1, const Gnss_Synchro & gnss_synchroL2); + + std::bitset<7> DF049; //!< GLONASS L2 Lock Time Indicator + int set_DF049(const Glonass_Gnav_Ephemeris & eph, double obs_time, const Gnss_Synchro & gnss_synchro); + + std::bitset<8> DF050; //!< GLONASS L2 CNR + int set_DF050(const Gnss_Synchro & gnss_synchro); + std::bitset<16> DF051; int set_DF051(const Gps_Ephemeris & gps_eph, double obs_time); @@ -964,6 +1175,105 @@ private: std::bitset<1> DF103; int set_DF103(const Gps_Ephemeris & gps_eph); + std::bitset<1> DF104; //!< GLONASS Almanac Health + int set_DF104(unsigned int glonass_gnav_alm_health); + + std::bitset<1> DF105; //!< GLONASS Almanac Health Availability Indicator + int set_DF105(unsigned int glonass_gnav_alm_health_ind); + + std::bitset<2> DF106; //!< GLONASS P1 Word + int set_DF106(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<12> DF107; //!< GLONASS Epoch (tk) + int set_DF107(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<1> DF108; //!< GLONASS MSB of Bn Word + int set_DF108(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<1> DF109; //!< GLONASS P2 Word + int set_DF109(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<7> DF110; //!< GLONASS Ephmeris Epoch (tb) + int set_DF110(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<24> DF111; //!< GLONASS Xn first derivative + int set_DF111(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<27> DF112; //!< GLONASS Xn + int set_DF112(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<5> DF113; //!< GLONASS Xn second derivative + int set_DF113(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<24> DF114; //!< GLONASS Yn first derivative + int set_DF114(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<27> DF115; //!< GLONASS Yn + int set_DF115(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<5> DF116; //!< GLONASS Yn second derivative + int set_DF116(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<24> DF117; //!< GLONASS Zn first derivative + int set_DF117(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<27> DF118; //!< GLONASS Zn + int set_DF118(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<5> DF119; //!< GLONASS Zn second derivative + int set_DF119(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<1> DF120; //!< GLONASS P3 + int set_DF120(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<11> DF121; //!< GLONASS GAMMA_N + int set_DF121(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<2> DF122; //!< GLONASS P + int set_DF122(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<1> DF123; //!< GLONASS ln (third string) + int set_DF123(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<22> DF124; //!< GLONASS TAU_N + int set_DF124(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<5> DF125; //!< GLONASS DELTA_TAU_N + int set_DF125(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<5> DF126; //!< GLONASS Eccentricity + int set_DF126(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<1> DF127; //!< GLONASS P4 + int set_DF127(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<4> DF128; //!< GLONASS F_T + int set_DF128(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<11> DF129; //!< GLONASS N_T + int set_DF129(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<2> DF130; //!< GLONASS M + int set_DF130(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + + std::bitset<1> DF131; //!< GLONASS Availability of additional data + int set_DF131(unsigned int fifth_str_additional_data_ind); + + std::bitset<11> DF132; //!< GLONASS N_A + int set_DF132(const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model); + + std::bitset<32> DF133; //!< GLONASS TAU_C + int set_DF133(const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model); + + std::bitset<5> DF134; //!< GLONASS N_4 + int set_DF134(const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model); + + std::bitset<22> DF135; //!< GLONASS TAU_GPS + int set_DF135(const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model); + + std::bitset<1> DF136; //!< GLONASS L_N (FIFTH STRING) + int set_DF136(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); + std::bitset<1> DF137; int set_DF137(const Gps_Ephemeris & gps_eph); @@ -1092,7 +1402,7 @@ private: int set_DF401(const Gnss_Synchro & gnss_synchro); std::bitset<4> DF402; - int set_DF402(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const Gnss_Synchro & gnss_synchro); + int set_DF402(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, const Glonass_Gnav_Ephemeris & ephGNAV, double obs_time, const Gnss_Synchro & gnss_synchro); std::bitset<6> DF403; int set_DF403(const Gnss_Synchro & gnss_synchro); @@ -1107,7 +1417,7 @@ private: int set_DF406(const Gnss_Synchro & gnss_synchro); std::bitset<10> DF407; - int set_DF407(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const Gnss_Synchro & gnss_synchro); + int set_DF407(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, const Glonass_Gnav_Ephemeris & ephGNAV, double obs_time, const Gnss_Synchro & gnss_synchro); std::bitset<10> DF408; int set_DF408(const Gnss_Synchro & gnss_synchro); diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 4fe2bac30..3394d8a2e 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -260,8 +260,15 @@ if(ENABLE_UNIT_TESTING_EXTRA) SHOW_PROGRESS EXPECTED_HASH MD5=a6fcbefe155137945d3c33c5ef7bd0f9 ) endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples/gps_l2c_m_prn7_5msps.dat) + if(NOT EXISTS ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat) + message(STATUS "Downloading some data files for testing...") + file(DOWNLOAD https://sourceforge.net/projects/gnss-sdr/files/data/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat + SHOW_PROGRESS + EXPECTED_HASH MD5=ffb72fc63c116be58d5e5ccb1daaed3a ) + endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat) if(ENABLE_INSTALL_TESTS) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/signal_samples/gps_l2c_m_prn7_5msps.dat DESTINATION share/gnss-sdr/signal_samples) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat DESTINATION share/gnss-sdr/signal_samples) endif(ENABLE_INSTALL_TESTS) endif(ENABLE_UNIT_TESTING_EXTRA) @@ -269,11 +276,13 @@ if(ENABLE_INSTALL_TESTS) install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GSoC_CTTC_capture_2012_07_26_4Msps_4ms.dat DESTINATION share/gnss-sdr/signal_samples) install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/Galileo_E1_ID_1_Fs_4Msps_8ms.dat DESTINATION share/gnss-sdr/signal_samples) install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat DESTINATION share/gnss-sdr/signal_samples) + install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin DESTINATION share/gnss-sdr/signal_samples) add_definitions(-DTEST_PATH="${CMAKE_INSTALL_PREFIX}/share/gnss-sdr/") else(ENABLE_INSTALL_TESTS) file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GSoC_CTTC_capture_2012_07_26_4Msps_4ms.dat DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/Galileo_E1_ID_1_Fs_4Msps_8ms.dat DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) + file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) add_definitions(-DTEST_PATH="${CMAKE_SOURCE_DIR}/thirdparty/") endif(ENABLE_INSTALL_TESTS) diff --git a/src/tests/common-files/gnuplot_i.h b/src/tests/common-files/gnuplot_i.h index 0996924d2..73e5f8251 100644 --- a/src/tests/common-files/gnuplot_i.h +++ b/src/tests/common-files/gnuplot_i.h @@ -941,7 +941,7 @@ bool Gnuplot::set_GNUPlotPath(const std::string &path) void Gnuplot::set_terminal_std(const std::string &type) { #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) - if (type.find("x11") != std::string::npos && getenv("DISPLAY") == NULL) + if (type.find("x11") != std::string::npos && std::getenv("DISPLAY") == NULL) { throw GnuplotException("Can't find DISPLAY variable"); } @@ -1808,7 +1808,7 @@ void Gnuplot::init() // whose name is specified as argument. If the requested variable is not // part of the environment list, the function returns a NULL pointer. #if ( defined(unix) || defined(__unix) || defined(__unix__) ) && !defined(__APPLE__) - if (getenv("DISPLAY") == NULL) + if (std::getenv("DISPLAY") == NULL) { valid = false; throw GnuplotException("Can't find DISPLAY variable"); @@ -1885,7 +1885,7 @@ bool Gnuplot::get_program_path() // char *path; // Retrieves a C string containing the value of environment variable PATH - path = getenv("PATH"); + path = std::getenv("PATH"); if (path == NULL) { @@ -1894,7 +1894,7 @@ bool Gnuplot::get_program_path() else { std::list ls; - std::string path_str = path; + std::string path_str(path); //split path (one long string) into list ls of strings #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) @@ -2007,10 +2007,9 @@ std::string Gnuplot::create_tmpfile(std::ofstream &tmp) { std::ostringstream except; except << "Maximum number of temporary files reached (" - << GP_MAX_TMP_FILES << "): cannot open more files" << std::endl; + << GP_MAX_TMP_FILES << "): cannot open more files" << std::endl; throw GnuplotException( except.str() ); - return ""; } // int mkstemp(char *name); diff --git a/src/tests/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin b/src/tests/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin new file mode 100644 index 000000000..bba434e4c Binary files /dev/null and b/src/tests/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin differ diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index efb2ee422..4f5fb78c1 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -59,6 +59,10 @@ #include "sbas_ephemeris.h" +#include "glonass_gnav_ephemeris.h" +#include "glonass_gnav_almanac.h" +#include "glonass_gnav_utc_model.h" + using google::LogMessage; DECLARE_string(log_dir); @@ -106,6 +110,7 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc" +#include "unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc" #if OPENCL_BLOCKS_TEST #include "unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc" @@ -113,6 +118,8 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc" +#include "unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc" +#include "unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc" #include "unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_test.cc" #include "unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc" @@ -133,6 +140,7 @@ DECLARE_string(log_dir); #if EXTRA_TESTS #include "unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc" +#include "unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc" #if MODERN_ARMADILLO #include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc" @@ -141,7 +149,8 @@ DECLARE_string(log_dir); #endif #endif - +#include "unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc" +#include "unit-tests/system-parameters/glonass_gnav_nav_message_test.cc" // For GPS NAVIGATION (L1) concurrent_queue global_gps_acq_assist_queue; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc new file mode 100644 index 000000000..47e56df36 --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc @@ -0,0 +1,661 @@ +/*! + * \file glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc + * \brief Tests a PCPS acquisition block for Glonass L1 C/A signals + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gnss_block_interface.h" +#include "in_memory_configuration.h" +#include "configuration_interface.h" +#include "gnss_synchro.h" +#include "glonass_l1_ca_pcps_acquisition.h" +#include "signal_generator.h" +#include "signal_generator_c.h" +#include "fir_filter.h" +#include "gen_signal_source.h" +#include "gnss_sdr_valve.h" +#include "boost/shared_ptr.hpp" +#include "pass_through.h" + + +// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +class GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx; + +typedef boost::shared_ptr GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx_sptr; + +GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx_sptr GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx_make(concurrent_queue& queue); + + +class GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx : public gr::block +{ +private: + friend GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx_sptr GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx_make(concurrent_queue& queue); + void msg_handler_events(pmt::pmt_t msg); + GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx(concurrent_queue& queue); + concurrent_queue& channel_internal_queue; +public: + int rx_message; + ~GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx(); //!< Default destructor +}; + + +GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx_sptr GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx_make(concurrent_queue& queue) +{ + return GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx_sptr(new GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx(queue)); +} + + +void GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx::msg_handler_events(pmt::pmt_t msg) +{ + try + { + long int message = pmt::to_long(msg); + rx_message = message; + channel_internal_queue.push(rx_message); + } + catch(boost::bad_any_cast& e) + { + LOG(WARNING) << "msg_handler_telemetry Bad any cast!"; + rx_message = 0; + } +} + + +GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx::GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx(concurrent_queue& queue) : + gr::block("GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)), channel_internal_queue(queue) +{ + this->message_port_register_in(pmt::mp("events")); + this->set_msg_handler(pmt::mp("events"), boost::bind(&GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx::msg_handler_events, this, _1)); + rx_message = 0; +} + + +GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx::~GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx() +{} + + +// ########################################################### + +class GlonassL1CaPcpsAcquisitionGSoC2017Test: public ::testing::Test +{ +protected: + GlonassL1CaPcpsAcquisitionGSoC2017Test() + { + item_size = sizeof(gr_complex); + stop = false; + message = 0; + gnss_synchro = Gnss_Synchro(); + acquisition = 0; + init(); + } + + ~GlonassL1CaPcpsAcquisitionGSoC2017Test() + { + } + + void init(); + void config_1(); + void config_2(); + void start_queue(); + void wait_message(); + void process_message(); + void stop_queue(); + + concurrent_queue channel_internal_queue; + + gr::msg_queue::sptr queue; + gr::top_block_sptr top_block; + GlonassL1CaPcpsAcquisition *acquisition; + std::shared_ptr config; + Gnss_Synchro gnss_synchro; + size_t item_size; + bool stop; + int message; + boost::thread ch_thread; + + unsigned int integration_time_ms = 0; + unsigned int fs_in = 0; + + double expected_delay_chips = 0.0; + double expected_doppler_hz = 0.0; + float max_doppler_error_hz = 0.0; + float max_delay_error_chips = 0.0; + + unsigned int num_of_realizations = 0; + unsigned int realization_counter; + unsigned int detection_counter; + unsigned int correct_estimation_counter; + unsigned int acquired_samples; + unsigned int mean_acq_time_us; + + double mse_doppler; + double mse_delay; + + double Pd; + double Pfa_p; + double Pfa_a; +}; + + +void GlonassL1CaPcpsAcquisitionGSoC2017Test::init() +{ + message = 0; + realization_counter = 0; + detection_counter = 0; + correct_estimation_counter = 0; + acquired_samples = 0; + mse_doppler = 0; + mse_delay = 0; + mean_acq_time_us = 0; + Pd = 0; + Pfa_p = 0; + Pfa_a = 0; +} + + +void GlonassL1CaPcpsAcquisitionGSoC2017Test::config_1() +{ + gnss_synchro.Channel_ID = 0; + gnss_synchro.System = 'R'; + std::string signal = "1G"; + signal.copy(gnss_synchro.Signal,2,0); + + integration_time_ms = 1; + fs_in = 31.75e6; + + expected_delay_chips = 255; + expected_doppler_hz = -1500; + max_doppler_error_hz = 2/(3*integration_time_ms*1e-3); + max_delay_error_chips = 0.50; + + num_of_realizations = 1; + + config = std::make_shared(); + + config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(fs_in)); + + config->set_property("SignalSource.fs_hz", std::to_string(fs_in)); + + config->set_property("SignalSource.item_type", "gr_complex"); + + config->set_property("SignalSource.num_satellites", "1"); + + config->set_property("SignalSource.system_0", "R"); + config->set_property("SignalSource.PRN_0", "10"); + config->set_property("SignalSource.CN0_dB_0", "44"); + config->set_property("SignalSource.doppler_Hz_0", std::to_string(expected_doppler_hz)); + config->set_property("SignalSource.delay_chips_0", std::to_string(expected_delay_chips)); + + config->set_property("SignalSource.noise_flag", "false"); + config->set_property("SignalSource.data_flag", "false"); + config->set_property("SignalSource.BW_BB", "0.97"); + + config->set_property("InputFilter.implementation", "Fir_Filter"); + config->set_property("InputFilter.input_item_type", "gr_complex"); + config->set_property("InputFilter.output_item_type", "gr_complex"); + config->set_property("InputFilter.taps_item_type", "float"); + config->set_property("InputFilter.number_of_taps", "11"); + config->set_property("InputFilter.number_of_bands", "2"); + config->set_property("InputFilter.band1_begin", "0.0"); + config->set_property("InputFilter.band1_end", "0.97"); + config->set_property("InputFilter.band2_begin", "0.98"); + config->set_property("InputFilter.band2_end", "1.0"); + config->set_property("InputFilter.ampl1_begin", "1.0"); + config->set_property("InputFilter.ampl1_end", "1.0"); + config->set_property("InputFilter.ampl2_begin", "0.0"); + config->set_property("InputFilter.ampl2_end", "0.0"); + config->set_property("InputFilter.band1_error", "1.0"); + config->set_property("InputFilter.band2_error", "1.0"); + config->set_property("InputFilter.filter_type", "bandpass"); + config->set_property("InputFilter.grid_density", "16"); + + config->set_property("Acquisition.item_type", "gr_complex"); + config->set_property("Acquisition.if", "4000000"); + config->set_property("Acquisition.coherent_integration_time_ms", + std::to_string(integration_time_ms)); + config->set_property("Acquisition.max_dwells", "1"); + config->set_property("Acquisition.implementation", "GLONASS_L1_CA_PCPS_Acquisition"); + config->set_property("Acquisition.threshold", "0.8"); + config->set_property("Acquisition.doppler_max", "10000"); + config->set_property("Acquisition.doppler_step", "250"); + config->set_property("Acquisition.bit_transition_flag", "false"); + config->set_property("Acquisition.dump", "false"); +} + + +void GlonassL1CaPcpsAcquisitionGSoC2017Test::config_2() +{ + gnss_synchro.Channel_ID = 0; + gnss_synchro.System = 'R'; + std::string signal = "1G"; + signal.copy(gnss_synchro.Signal,2,0); + + integration_time_ms = 1; + fs_in = 31.75e6; + + expected_delay_chips = 374; + expected_doppler_hz = -2000; + max_doppler_error_hz = 2/(3*integration_time_ms*1e-3); + max_delay_error_chips = 0.50; + + num_of_realizations = 100; + + config = std::make_shared(); + + config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(fs_in)); + + config->set_property("SignalSource.fs_hz", std::to_string(fs_in)); + + config->set_property("SignalSource.item_type", "gr_complex"); + + config->set_property("SignalSource.num_satellites", "4"); + + config->set_property("SignalSource.system_0", "R"); + config->set_property("SignalSource.PRN_0", "10"); + config->set_property("SignalSource.CN0_dB_0", "44"); + config->set_property("SignalSource.doppler_Hz_0", std::to_string(expected_doppler_hz)); + config->set_property("SignalSource.delay_chips_0", std::to_string(expected_delay_chips)); + + config->set_property("SignalSource.system_1", "R"); + config->set_property("SignalSource.PRN_1", "15"); + config->set_property("SignalSource.CN0_dB_1", "44"); + config->set_property("SignalSource.doppler_Hz_1", "1000"); + config->set_property("SignalSource.delay_chips_1", "100"); + + config->set_property("SignalSource.system_2", "R"); + config->set_property("SignalSource.PRN_2", "21"); + config->set_property("SignalSource.CN0_dB_2", "44"); + config->set_property("SignalSource.doppler_Hz_2", "2000"); + config->set_property("SignalSource.delay_chips_2", "200"); + + config->set_property("SignalSource.system_3", "R"); + config->set_property("SignalSource.PRN_3", "22"); + config->set_property("SignalSource.CN0_dB_3", "44"); + config->set_property("SignalSource.doppler_Hz_3", "3000"); + config->set_property("SignalSource.delay_chips_3", "300"); + + config->set_property("SignalSource.noise_flag", "true"); + config->set_property("SignalSource.data_flag", "true"); + config->set_property("SignalSource.BW_BB", "0.97"); + + config->set_property("InputFilter.implementation", "Fir_Filter"); + config->set_property("InputFilter.input_item_type", "gr_complex"); + config->set_property("InputFilter.output_item_type", "gr_complex"); + config->set_property("InputFilter.taps_item_type", "float"); + config->set_property("InputFilter.number_of_taps", "11"); + config->set_property("InputFilter.number_of_bands", "2"); + config->set_property("InputFilter.band1_begin", "0.0"); + config->set_property("InputFilter.band1_end", "0.97"); + config->set_property("InputFilter.band2_begin", "0.98"); + config->set_property("InputFilter.band2_end", "1.0"); + config->set_property("InputFilter.ampl1_begin", "1.0"); + config->set_property("InputFilter.ampl1_end", "1.0"); + config->set_property("InputFilter.ampl2_begin", "0.0"); + config->set_property("InputFilter.ampl2_end", "0.0"); + config->set_property("InputFilter.band1_error", "1.0"); + config->set_property("InputFilter.band2_error", "1.0"); + config->set_property("InputFilter.filter_type", "bandpass"); + config->set_property("InputFilter.grid_density", "16"); + + config->set_property("Acquisition.item_type", "gr_complex"); + config->set_property("Acquisition.if", "4000000"); + config->set_property("Acquisition.coherent_integration_time_ms", + std::to_string(integration_time_ms)); + config->set_property("Acquisition.max_dwells", "1"); + config->set_property("Acquisition.implementation", "GLONASS_L1_CA_PCPS_Acquisition"); + config->set_property("Acquisition.pfa", "0.1"); + config->set_property("Acquisition.doppler_max", "10000"); + config->set_property("Acquisition.doppler_step", "250"); + config->set_property("Acquisition.bit_transition_flag", "false"); + config->set_property("Acquisition.dump", "false"); +} + + +void GlonassL1CaPcpsAcquisitionGSoC2017Test::start_queue() +{ + stop = false; + ch_thread = boost::thread(&GlonassL1CaPcpsAcquisitionGSoC2017Test::wait_message, this); +} + + +void GlonassL1CaPcpsAcquisitionGSoC2017Test::wait_message() +{ + struct timeval tv; + long long int begin = 0; + long long int end = 0; + + while (!stop) + { + acquisition->reset(); + + gettimeofday(&tv, NULL); + begin = tv.tv_sec *1e6 + tv.tv_usec; + + channel_internal_queue.wait_and_pop(message); + + gettimeofday(&tv, NULL); + end = tv.tv_sec *1e6 + tv.tv_usec; + + mean_acq_time_us += (end-begin); + + process_message(); + } +} + + +void GlonassL1CaPcpsAcquisitionGSoC2017Test::process_message() +{ + if (message == 1) + { + detection_counter++; + + // The term -5 is here to correct the additional delay introduced by the FIR filter + // The value 511.0 must be a variable, chips/length + double delay_error_chips = std::abs(static_cast(expected_delay_chips) - (static_cast(gnss_synchro.Acq_delay_samples) - 5.0 ) * 511.0 / (static_cast(fs_in) * 1e-3)); + double doppler_error_hz = std::abs(expected_doppler_hz - gnss_synchro.Acq_doppler_hz); + + mse_delay += std::pow(delay_error_chips, 2); + mse_doppler += std::pow(doppler_error_hz, 2); + + if ((delay_error_chips < max_delay_error_chips) && (doppler_error_hz < max_doppler_error_hz)) + { + correct_estimation_counter++; + } + } + + realization_counter++; + + std::cout << "Progress: " << round(static_cast(realization_counter) / static_cast(num_of_realizations) * 100.0) << "% \r" << std::flush; + + if (realization_counter == num_of_realizations) + { + mse_delay /= num_of_realizations; + mse_doppler /= num_of_realizations; + + Pd = static_cast(correct_estimation_counter) / static_cast(num_of_realizations); + Pfa_a = static_cast(detection_counter) / static_cast(num_of_realizations); + Pfa_p = (static_cast(detection_counter) - static_cast( correct_estimation_counter)) / static_cast(num_of_realizations); + + mean_acq_time_us /= num_of_realizations; + + stop_queue(); + top_block->stop(); + } +} + + +void GlonassL1CaPcpsAcquisitionGSoC2017Test::stop_queue() +{ + stop = true; +} + + +TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, Instantiate) +{ + config_1(); + acquisition = new GlonassL1CaPcpsAcquisition(config.get(), "Acquisition", 1, 1); + delete acquisition; +} + + +TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, ConnectAndRun) +{ + int nsamples = floor(fs_in * integration_time_ms * 1e-3); + std::chrono::time_point begin, end; + std::chrono::duration elapsed_seconds(0); + queue = gr::msg_queue::make(0); + top_block = gr::make_top_block("Acquisition test"); + + config_1(); + acquisition = new GlonassL1CaPcpsAcquisition(config.get(), "Acquisition", 1, 1); + boost::shared_ptr msg_rx = GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx_make(channel_internal_queue); + + ASSERT_NO_THROW( { + acquisition->connect(top_block); + boost::shared_ptr source = gr::analog::sig_source_c::make(fs_in, gr::analog::GR_SIN_WAVE, 1000, 1, gr_complex(0)); + boost::shared_ptr valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue); + top_block->connect(source, 0, valve, 0); + top_block->connect(valve, 0, acquisition->get_left_block(), 0); + top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + }) << "Failure connecting the blocks of acquisition test."; + + EXPECT_NO_THROW( { + begin = std::chrono::system_clock::now(); + top_block->run(); // Start threads and wait + end = std::chrono::system_clock::now(); + elapsed_seconds = end - begin; + }) << "Failure running the top_block."; + + std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; + + delete acquisition; +} + + +TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, ValidationOfResults) +{ + config_1(); + queue = gr::msg_queue::make(0); + top_block = gr::make_top_block("Acquisition test"); + + acquisition = new GlonassL1CaPcpsAcquisition(config.get(), "Acquisition", 1, 1); + boost::shared_ptr msg_rx = GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx_make(channel_internal_queue); + + ASSERT_NO_THROW( { + acquisition->set_channel(1); + }) << "Failure setting channel."; + + ASSERT_NO_THROW( { + acquisition->set_gnss_synchro(&gnss_synchro); + }) << "Failure setting gnss_synchro."; + + ASSERT_NO_THROW( { + acquisition->set_doppler_max(10000); + }) << "Failure setting doppler_max."; + + ASSERT_NO_THROW( { + acquisition->set_doppler_step(500); + }) << "Failure setting doppler_step."; + + ASSERT_NO_THROW( { + acquisition->set_threshold(0.5); + }) << "Failure setting threshold."; + + ASSERT_NO_THROW( { + acquisition->connect(top_block); + top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + }) << "Failure connecting acquisition to the top_block."; + + acquisition->init(); + + ASSERT_NO_THROW( { + boost::shared_ptr signal_source; + SignalGenerator* signal_generator = new SignalGenerator(config.get(), "SignalSource", 0, 1, queue); + FirFilter* filter = new FirFilter(config.get(), "InputFilter", 1, 1); + signal_source.reset(new GenSignalSource(signal_generator, filter, "SignalSource", queue)); + signal_source->connect(top_block); + top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); + }) << "Failure connecting the blocks of acquisition test."; + + // i = 0 --> satellite in acquisition is visible + // i = 1 --> satellite in acquisition is not visible + for (unsigned int i = 0; i < 2; i++) + { + init(); + + if (i == 0) + { + gnss_synchro.PRN = 10; // This satellite is visible + } + else if (i == 1) + { + gnss_synchro.PRN = 20; // This satellite is not visible + } + + acquisition->set_local_code(); + acquisition->set_state(1); // Ensure that acquisition starts at the first sample + start_queue(); + + EXPECT_NO_THROW( { + top_block->run(); // Start threads and wait + }) << "Failure running the top_block."; + + if (i == 0) + { + EXPECT_EQ(1, message) << "Acquisition failure. Expected message: 1=ACQ SUCCESS."; + if (message == 1) + { + EXPECT_EQ(static_cast(1), correct_estimation_counter) << "Acquisition failure. Incorrect parameters estimation."; + } + + } + else if (i == 1) + { + EXPECT_EQ(2, message) << "Acquisition failure. Expected message: 2=ACQ FAIL."; + } +#ifdef OLD_BOOST + ASSERT_NO_THROW( { + ch_thread.timed_join(boost::posix_time::seconds(1)); + }) << "Failure while waiting the queue to stop."; +#endif +#ifndef OLD_BOOST + ASSERT_NO_THROW( { + ch_thread.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(50)); + }) << "Failure while waiting the queue to stop"; +#endif + } + + delete acquisition; +} + + +TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, ValidationOfResultsProbabilities) +{ + config_2(); + queue = gr::msg_queue::make(0); + top_block = gr::make_top_block("Acquisition test"); + acquisition = new GlonassL1CaPcpsAcquisition(config.get(), "Acquisition", 1, 1); + boost::shared_ptr msg_rx = GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx_make(channel_internal_queue); + + ASSERT_NO_THROW( { + acquisition->set_channel(1); + }) << "Failure setting channel."<< std::endl; + + ASSERT_NO_THROW( { + acquisition->set_gnss_synchro(&gnss_synchro); + }) << "Failure setting gnss_synchro."<< std::endl; + + ASSERT_NO_THROW( { + acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); + }) << "Failure setting doppler_max."<< std::endl; + + ASSERT_NO_THROW( { + acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); + }) << "Failure setting doppler_step."<< std::endl; + + ASSERT_NO_THROW( { + acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); + }) << "Failure setting threshold."<< std::endl; + + ASSERT_NO_THROW( { + acquisition->connect(top_block); + top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + }) << "Failure connecting acquisition to the top_block."<< std::endl; + + acquisition->init(); + + ASSERT_NO_THROW( { + boost::shared_ptr signal_source; + SignalGenerator* signal_generator = new SignalGenerator(config.get(), "SignalSource", 0, 1, queue); + FirFilter* filter = new FirFilter(config.get(), "InputFilter", 1, 1); + signal_source.reset(new GenSignalSource(signal_generator, filter, "SignalSource", queue)); + signal_source->connect(top_block); + top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); + }) << "Failure connecting the blocks of acquisition test." << std::endl; + + std::cout << "Probability of false alarm (target) = " << 0.1 << std::endl; + + // i = 0 --> satellite in acquisition is visible (prob of detection and prob of detection with wrong estimation) + // i = 1 --> satellite in acquisition is not visible (prob of false detection) + for (unsigned int i = 0; i < 2; i++) + { + init(); + + if (i == 0) + { + gnss_synchro.PRN = 10; // This satellite is visible + } + else if (i == 1) + { + gnss_synchro.PRN = 1; // This satellite is not visible + } + + acquisition->set_local_code(); + + start_queue(); + + EXPECT_NO_THROW( { + top_block->run(); // Start threads and wait + }) << "Failure running the top_block."<< std::endl; + + if (i == 0) + { + std::cout << "Estimated probability of detection = " << Pd << std::endl; + std::cout << "Estimated probability of false alarm (satellite present) = " << Pfa_p << std::endl; + std::cout << "Mean acq time = " << mean_acq_time_us << " microseconds." << std::endl; } + else if (i == 1) + { + std::cout << "Estimated probability of false alarm (satellite absent) = " << Pfa_a << std::endl; + std::cout << "Mean acq time = " << mean_acq_time_us << " microseconds." << std::endl; + } +#ifdef OLD_BOOST + ASSERT_NO_THROW( { + ch_thread.timed_join(boost::posix_time::seconds(1)); + }) << "Failure while waiting the queue to stop" << std::endl; +#endif +#ifndef OLD_BOOST + ASSERT_NO_THROW( { + ch_thread.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(50)); + }) << "Failure while waiting the queue to stop" << std::endl; +#endif + } + + delete acquisition; +} + diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc new file mode 100644 index 000000000..7cee76a52 --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc @@ -0,0 +1,262 @@ +/*! + * \file glonass_l1_ca_pcps_acquisition_test.cc + * \brief Tests a PCPS acquisition block for Glonass L1 C/A signals + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gnss_block_factory.h" +#include "gnss_block_interface.h" +#include "in_memory_configuration.h" +#include "gnss_sdr_valve.h" +#include "gnss_synchro.h" +#include "glonass_l1_ca_pcps_acquisition.h" + + +// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +class GlonassL1CaPcpsAcquisitionTest_msg_rx; + +typedef boost::shared_ptr GlonassL1CaPcpsAcquisitionTest_msg_rx_sptr; + +GlonassL1CaPcpsAcquisitionTest_msg_rx_sptr GlonassL1CaPcpsAcquisitionTest_msg_rx_make(); + +class GlonassL1CaPcpsAcquisitionTest_msg_rx : public gr::block +{ +private: + friend GlonassL1CaPcpsAcquisitionTest_msg_rx_sptr GlonassL1CaPcpsAcquisitionTest_msg_rx_make(); + void msg_handler_events(pmt::pmt_t msg); + GlonassL1CaPcpsAcquisitionTest_msg_rx(); +public: + int rx_message; + ~GlonassL1CaPcpsAcquisitionTest_msg_rx(); //!< Default destructor +}; + + +GlonassL1CaPcpsAcquisitionTest_msg_rx_sptr GlonassL1CaPcpsAcquisitionTest_msg_rx_make() +{ + return GlonassL1CaPcpsAcquisitionTest_msg_rx_sptr(new GlonassL1CaPcpsAcquisitionTest_msg_rx()); +} + + +void GlonassL1CaPcpsAcquisitionTest_msg_rx::msg_handler_events(pmt::pmt_t msg) +{ + try + { + long int message = pmt::to_long(msg); + rx_message = message; + } + catch(boost::bad_any_cast& e) + { + std::cout << "msg_handler_telemetry Bad any cast!" << std::endl; + rx_message = 0; + } +} + + +GlonassL1CaPcpsAcquisitionTest_msg_rx::GlonassL1CaPcpsAcquisitionTest_msg_rx() : + gr::block("GlonassL1CaPcpsAcquisitionTest_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) +{ + this->message_port_register_in(pmt::mp("events")); + this->set_msg_handler(pmt::mp("events"), boost::bind(&GlonassL1CaPcpsAcquisitionTest_msg_rx::msg_handler_events, this, _1)); + rx_message = 0; +} + + +GlonassL1CaPcpsAcquisitionTest_msg_rx::~GlonassL1CaPcpsAcquisitionTest_msg_rx() +{} + + +// ########################################################### + +class GlonassL1CaPcpsAcquisitionTest: public ::testing::Test +{ +protected: + GlonassL1CaPcpsAcquisitionTest() + { + factory = std::make_shared(); + config = std::make_shared(); + item_size = sizeof(gr_complex); + gnss_synchro = Gnss_Synchro(); + } + + ~GlonassL1CaPcpsAcquisitionTest() + {} + + void init(); + + gr::top_block_sptr top_block; + std::shared_ptr factory; + std::shared_ptr config; + Gnss_Synchro gnss_synchro; + size_t item_size; +}; + + +void GlonassL1CaPcpsAcquisitionTest::init() +{ + gnss_synchro.Channel_ID = 0; + gnss_synchro.System = 'R'; + std::string signal = "1G"; + signal.copy(gnss_synchro.Signal, 2, 0); + gnss_synchro.PRN = 1; + config->set_property("GNSS-SDR.internal_fs_sps", "62314000"); + config->set_property("Acquisition_1G.item_type", "gr_complex"); + config->set_property("Acquisition_1G.if", "9540000"); + config->set_property("Acquisition_1G.coherent_integration_time_ms", "1"); + config->set_property("Acquisition_1G.dump", "true"); + config->set_property("Acquisition_1G.dump_filename", "./acquisition.dat"); + config->set_property("Acquisition_1G.implementation", "Glonass_L1_CA_PCPS_Acquisition"); + config->set_property("Acquisition_1G.threshold", "0.001"); + config->set_property("Acquisition_1G.doppler_max", "5000"); + config->set_property("Acquisition_1G.doppler_step", "500"); + config->set_property("Acquisition_1G.repeat_satellite", "false"); + //config->set_property("Acquisition_1G.pfa", "0.0"); +} + + +TEST_F(GlonassL1CaPcpsAcquisitionTest, Instantiate) +{ + init(); + boost::shared_ptr acquisition = boost::make_shared(config.get(), "Acquisition_1G", 1, 1); +} + + +TEST_F(GlonassL1CaPcpsAcquisitionTest, ConnectAndRun) +{ + int fs_in = 62314000; + int nsamples = 62314; + std::chrono::time_point begin, end; + std::chrono::duration elapsed_seconds(0); + gr::msg_queue::sptr queue = gr::msg_queue::make(0); + + top_block = gr::make_top_block("Acquisition test"); + init(); + boost::shared_ptr acquisition = boost::make_shared(config.get(), "Acquisition_1G", 1, 1); + boost::shared_ptr msg_rx = GlonassL1CaPcpsAcquisitionTest_msg_rx_make(); + + ASSERT_NO_THROW( { + acquisition->connect(top_block); + boost::shared_ptr source = gr::analog::sig_source_c::make(fs_in, gr::analog::GR_SIN_WAVE, 1000, 1, gr_complex(0)); + boost::shared_ptr valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue); + top_block->connect(source, 0, valve, 0); + top_block->connect(valve, 0, acquisition->get_left_block(), 0); + top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + }) << "Failure connecting the blocks of acquisition test."; + + EXPECT_NO_THROW( { + begin = std::chrono::system_clock::now(); + top_block->run(); // Start threads and wait + end = std::chrono::system_clock::now(); + elapsed_seconds = end - begin; + }) << "Failure running the top_block."; + + std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; +} + + +TEST_F(GlonassL1CaPcpsAcquisitionTest, ValidationOfResults) +{ + std::chrono::time_point begin, end; + std::chrono::duration elapsed_seconds(0); + top_block = gr::make_top_block("Acquisition test"); + + double expected_delay_samples = 31874; + double expected_doppler_hz = -8000; + init(); + std::shared_ptr acquisition = std::make_shared(config.get(), "Acquisition_1G", 1, 1); + + boost::shared_ptr msg_rx = GlonassL1CaPcpsAcquisitionTest_msg_rx_make(); + + ASSERT_NO_THROW( { + acquisition->set_channel(1); + }) << "Failure setting channel."; + + ASSERT_NO_THROW( { + acquisition->set_gnss_synchro(&gnss_synchro); + }) << "Failure setting gnss_synchro."; + + ASSERT_NO_THROW( { + acquisition->set_threshold(0.005); + }) << "Failure setting threshold."; + + ASSERT_NO_THROW( { + acquisition->set_doppler_max(10000); + }) << "Failure setting doppler_max."; + + ASSERT_NO_THROW( { + acquisition->set_doppler_step(500); + }) << "Failure setting doppler_step."; + + ASSERT_NO_THROW( { + acquisition->connect(top_block); + }) << "Failure connecting acquisition to the top_block."; + + acquisition->set_local_code(); + acquisition->set_state(1); // Ensure that acquisition starts at the first sample + acquisition->init(); + + ASSERT_NO_THROW( { + std::string path = std::string(TEST_PATH); + std::string file = path + "signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat"; + const char * file_name = file.c_str(); + gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(gr_complex), file_name, false); + top_block->connect(file_source, 0, acquisition->get_left_block(), 0); + top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + }) << "Failure connecting the blocks of acquisition test."; + + EXPECT_NO_THROW( { + begin = std::chrono::system_clock::now(); + top_block->run(); // Start threads and wait + end = std::chrono::system_clock::now(); + elapsed_seconds = end - begin; + }) << "Failure running the top_block."; + + unsigned long int nsamples = gnss_synchro.Acq_samplestamp_samples; + std::cout << "Acquired " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; + + ASSERT_EQ(1, msg_rx->rx_message) << "Acquisition failure. Expected message: 1=ACQ SUCCESS."; + + double delay_error_samples = std::abs(expected_delay_samples - gnss_synchro.Acq_delay_samples); + float delay_error_chips = static_cast(delay_error_samples) * 511.0 / 62316.0; + double doppler_error_hz = std::abs(expected_doppler_hz - gnss_synchro.Acq_doppler_hz); + + EXPECT_LE(doppler_error_hz, 666) << "Doppler error exceeds the expected value: 666 Hz = 2/(3*integration period)"; + EXPECT_LT(delay_error_chips, 0.5) << "Delay error exceeds the expected value: 0.5 chips"; +} diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc index fdf1d7d2c..963ab0186 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc @@ -87,6 +87,36 @@ TEST(RinexPrinterTest, GalileoObsHeader) } +TEST(RinexPrinterTest, GlonassObsHeader) +{ + std::string line_aux; + std::string line_str; + bool no_more_finds = false; + const Glonass_Gnav_Ephemeris eph = Glonass_Gnav_Ephemeris(); + + std::shared_ptr rp1; + rp1 = std::make_shared(3); + const std::string bands = "1G"; + rp1->rinex_obs_header(rp1->obsFile, eph, 0.0, bands); + rp1->obsFile.seekp(0); + + while(!rp1->obsFile.eof()) + { + std::getline(rp1->obsFile, line_str); + if(!no_more_finds) + { + if (line_str.find("SYS / # / OBS TYPES", 59) != std::string::npos) + { + no_more_finds = true; + line_aux = std::string(line_str); + } + } + } + std::string expected_str("R 4 C1C L1C D1C S1C SYS / # / OBS TYPES "); + EXPECT_EQ(0, expected_str.compare(line_aux)); + if(remove(rp1->obsfilename.c_str()) != 0) LOG(INFO) << "Error deleting temporary file"; + line_aux.clear(); +} TEST(RinexPrinterTest, MixedObsHeader) @@ -133,6 +163,50 @@ TEST(RinexPrinterTest, MixedObsHeader) } +TEST(RinexPrinterTest, MixedObsHeaderGpsGlo) +{ + std::string line_aux; + std::string line_aux2; + std::string line_str; + bool no_more_finds = false; + const Glonass_Gnav_Ephemeris eph_glo = Glonass_Gnav_Ephemeris(); + const Gps_Ephemeris eph_gps = Gps_Ephemeris(); + + std::shared_ptr rp1; + rp1 = std::make_shared(); + rp1->rinex_obs_header(rp1->obsFile, eph_gps, eph_glo, 0.0, "1G"); + rp1->obsFile.seekp(0); + int systems_found = 0; + + while(!rp1->obsFile.eof()) + { + std::getline(rp1->obsFile, line_str); + if(!no_more_finds) + { + if (line_str.find("SYS / # / OBS TYPES", 59) != std::string::npos) + { + systems_found++; + if(systems_found == 1) + { + line_aux = std::string(line_str); + } + if(systems_found == 2) + { + line_aux2 = std::string(line_str); + no_more_finds = true; + } + } + } + } + + std::string expected_str("G 4 C1C L1C D1C S1C SYS / # / OBS TYPES "); + std::string expected_str2("R 4 C1C L1C D1C S1C SYS / # / OBS TYPES "); + EXPECT_EQ(0, expected_str.compare(line_aux)); + EXPECT_EQ(0, expected_str2.compare(line_aux2)); + if(remove(rp1->obsfilename.c_str()) != 0) LOG(INFO) << "Error deleting temporary file"; +} + + TEST(RinexPrinterTest, GalileoObsLog) { std::string line_aux; @@ -201,6 +275,74 @@ TEST(RinexPrinterTest, GalileoObsLog) } +TEST(RinexPrinterTest, GlonassObsLog) +{ + std::string line_aux; + std::string line_str; + bool no_more_finds = false; + const Glonass_Gnav_Ephemeris eph = Glonass_Gnav_Ephemeris(); + + std::shared_ptr rp; + rp = std::make_shared(); + rp->rinex_obs_header(rp->obsFile, eph, 0.0); + + std::map gnss_pseudoranges_map; + + Gnss_Synchro gs1 = Gnss_Synchro(); + Gnss_Synchro gs2 = Gnss_Synchro(); + Gnss_Synchro gs3 = Gnss_Synchro(); + Gnss_Synchro gs4 = Gnss_Synchro(); + + std::string sys = "R"; + gs1.System = *sys.c_str(); + gs2.System = *sys.c_str(); + gs3.System = *sys.c_str(); + gs4.System = *sys.c_str(); + + std::string sig = "1C"; + std::memcpy((void*)gs1.Signal, sig.c_str(), 3); + std::memcpy((void*)gs2.Signal, sig.c_str(), 3); + std::memcpy((void*)gs3.Signal, sig.c_str(), 3); + std::memcpy((void*)gs4.Signal, sig.c_str(), 3); + + gs1.PRN = 3; + gs2.PRN = 8; + gs3.PRN = 10; + gs4.PRN = 22; + + gs4.Pseudorange_m = 22000000; + gs4.Carrier_phase_rads = 23.4; + gs4.Carrier_Doppler_hz = 1534; + gs4.CN0_dB_hz = 42; + + gnss_pseudoranges_map.insert( std::pair(1,gs1) ); + gnss_pseudoranges_map.insert( std::pair(2,gs2) ); + gnss_pseudoranges_map.insert( std::pair(3,gs3) ); + gnss_pseudoranges_map.insert( std::pair(4,gs4) ); + + rp->log_rinex_obs(rp->obsFile, eph, 0.0, gnss_pseudoranges_map); + rp->obsFile.seekp(0); + + while(!rp->obsFile.eof()) + { + std::getline(rp->obsFile, line_str); + if(!no_more_finds) + { + if (line_str.find("R22", 0) != std::string::npos) + { + no_more_finds = true; + line_aux = std::string(line_str); + } + } + } + + std::string expected_str("R22 22000000.000 7 3.724 7 1534.000 7 42.000 "); + EXPECT_EQ(0, expected_str.compare(line_aux)); + + if(remove(rp->obsfilename.c_str()) != 0) LOG(INFO) << "Error deleting temporary file"; +} + + TEST(RinexPrinterTest, GpsObsLogDualBand) { std::string line_aux; @@ -473,3 +615,112 @@ TEST(RinexPrinterTest, MixedObsLog) if(remove(rp->obsfilename.c_str()) != 0) LOG(INFO) << "Error deleting temporary file"; } + + +TEST(RinexPrinterTest, MixedObsLogGpsGlo) +{ + std::string line_aux; + std::string line_str; + bool no_more_finds = false; + const Glonass_Gnav_Ephemeris eph_glo = Glonass_Gnav_Ephemeris(); + const Gps_Ephemeris eph_gps = Gps_Ephemeris(); + + std::shared_ptr rp; + rp = std::make_shared(); + rp->rinex_obs_header(rp->obsFile, eph_gps, eph_glo, 0.0, "1G"); + + std::map gnss_pseudoranges_map; + + Gnss_Synchro gs1 = Gnss_Synchro(); + Gnss_Synchro gs2 = Gnss_Synchro(); + Gnss_Synchro gs3 = Gnss_Synchro(); + Gnss_Synchro gs4 = Gnss_Synchro(); + Gnss_Synchro gs5 = Gnss_Synchro(); + Gnss_Synchro gs6 = Gnss_Synchro(); + Gnss_Synchro gs7 = Gnss_Synchro(); + Gnss_Synchro gs8 = Gnss_Synchro(); + + std::string sys = "G"; + gs1.System = *sys.c_str(); + gs2.System = *sys.c_str(); + gs3.System = *sys.c_str(); + gs4.System = *sys.c_str(); + + sys = "R"; + gs5.System = *sys.c_str(); + gs6.System = *sys.c_str(); + gs7.System = *sys.c_str(); + gs8.System = *sys.c_str(); + + std::string sig = "1C"; + std::memcpy((void*)gs1.Signal, sig.c_str(), 3); + std::memcpy((void*)gs2.Signal, sig.c_str(), 3); + std::memcpy((void*)gs3.Signal, sig.c_str(), 3); + std::memcpy((void*)gs4.Signal, sig.c_str(), 3); + + sig = "1G"; + std::memcpy((void*)gs5.Signal, sig.c_str(), 3); + std::memcpy((void*)gs6.Signal, sig.c_str(), 3); + std::memcpy((void*)gs7.Signal, sig.c_str(), 3); + std::memcpy((void*)gs8.Signal, sig.c_str(), 3); + + gs1.PRN = 3; + gs2.PRN = 8; + gs3.PRN = 14; + gs4.PRN = 16; + gs5.PRN = 3; + gs6.PRN = 16; + gs7.PRN = 14; + gs8.PRN = 16; + + gs2.Pseudorange_m = 22000002.1; + gs2.Carrier_phase_rads = 45.4; + gs2.Carrier_Doppler_hz = 321; + gs2.CN0_dB_hz = 39; + + gs4.Pseudorange_m = 22000000; + gs4.Carrier_phase_rads = 23.4; + gs4.Carrier_Doppler_hz = -1534; + gs4.CN0_dB_hz = 40; + + gs6.Pseudorange_m = 22000000; + gs6.Carrier_phase_rads = 52.1; + gs6.Carrier_Doppler_hz = 1534; + gs6.CN0_dB_hz = 41; + + gs8.Pseudorange_m = 22000000; + gs8.Carrier_phase_rads = 0.8; + gs8.Carrier_Doppler_hz = -20; + gs8.CN0_dB_hz = 42; + + gnss_pseudoranges_map.insert( std::pair(1,gs1) ); + gnss_pseudoranges_map.insert( std::pair(2,gs2) ); + gnss_pseudoranges_map.insert( std::pair(3,gs3) ); + gnss_pseudoranges_map.insert( std::pair(4,gs4) ); + gnss_pseudoranges_map.insert( std::pair(5,gs5) ); + gnss_pseudoranges_map.insert( std::pair(6,gs6) ); + gnss_pseudoranges_map.insert( std::pair(7,gs7) ); + gnss_pseudoranges_map.insert( std::pair(8,gs8) ); + + rp->log_rinex_obs(rp->obsFile, eph_gps, eph_glo, 0.0, gnss_pseudoranges_map); + + rp->obsFile.seekp(0); + + while(!rp->obsFile.eof()) + { + std::getline(rp->obsFile, line_str); + if(!no_more_finds) + { + if (line_str.find("R16", 0) != std::string::npos) + { + no_more_finds = true; + line_aux = std::string(line_str); + } + } + } + + std::string expected_str("R16 22000000.000 6 8.292 6 1534.000 6 41.000 22000000.000 7 0.127 7 -20.000 7 42.000"); + EXPECT_EQ(0, expected_str.compare(line_aux)); + + if(remove(rp->obsfilename.c_str()) != 0) LOG(INFO) << "Error deleting temporary file"; +} diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc index 11bd5d7cc..fdc7084a4 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc @@ -253,6 +253,7 @@ TEST(RtcmTest, MT1005) } + TEST(RtcmTest, MT1019) { auto rtcm = std::make_shared(); @@ -276,6 +277,40 @@ TEST(RtcmTest, MT1019) } +TEST(RtcmTest, MT1020) +{ + auto rtcm = std::make_shared(); + + // Objects to populate the ephemeris and utc fields + Glonass_Gnav_Ephemeris gnav_ephemeris = Glonass_Gnav_Ephemeris(); + Glonass_Gnav_Utc_Model gnav_utc_model = Glonass_Gnav_Utc_Model(); + // Objects read, used for comparison + Glonass_Gnav_Ephemeris gnav_ephemeris_read = Glonass_Gnav_Ephemeris(); + Glonass_Gnav_Utc_Model gnav_utc_model_read = Glonass_Gnav_Utc_Model(); + + // Perform data read and print of special values types + gnav_ephemeris.d_P_1 = 15; + // Bit distribution per fields + gnav_ephemeris.d_t_k = 7560; + // Glonass signed values + gnav_ephemeris.d_VXn = -0.490900039672852; + // Bit distribution per fields dependant on other factors + gnav_ephemeris.d_t_b = 8100; + // Binary flag representation + gnav_ephemeris.d_P_3 = 1; + + std::string tx_msg = rtcm->print_MT1020(gnav_ephemeris, gnav_utc_model); + + EXPECT_EQ(0, rtcm->read_MT1020(tx_msg, gnav_ephemeris_read, gnav_utc_model_read)); + EXPECT_EQ(gnav_ephemeris.d_P_1, gnav_ephemeris_read.d_P_1); + EXPECT_TRUE(gnav_ephemeris.d_t_b - gnav_ephemeris_read.d_t_b < FLT_EPSILON); + EXPECT_TRUE( gnav_ephemeris.d_VXn - gnav_ephemeris_read.d_VXn < FLT_EPSILON); + EXPECT_TRUE( gnav_ephemeris.d_t_k - gnav_ephemeris.d_t_k < FLT_EPSILON); + EXPECT_EQ(gnav_ephemeris.d_P_3, gnav_ephemeris_read.d_P_3); + EXPECT_EQ(1, rtcm->read_MT1020(rtcm->bin_to_binary_data(rtcm->hex_to_bin("FFFFFFFFFFF")), gnav_ephemeris_read, gnav_utc_model_read)); +} + + TEST(RtcmTest, MT1029) { auto rtcm = std::make_shared(); @@ -321,6 +356,7 @@ TEST(RtcmTest, MSMCell) auto rtcm = std::make_shared(); Gps_Ephemeris gps_eph = Gps_Ephemeris(); Galileo_Ephemeris gal_eph = Galileo_Ephemeris(); + //Glonass_Gnav_Ephemeris glo_gnav_eph = Glonass_Gnav_Ephemeris(); std::map pseudoranges; Gnss_Synchro gnss_synchro; @@ -328,15 +364,18 @@ TEST(RtcmTest, MSMCell) Gnss_Synchro gnss_synchro3; Gnss_Synchro gnss_synchro4; Gnss_Synchro gnss_synchro5; + Gnss_Synchro gnss_synchro6; gnss_synchro.PRN = 4; gnss_synchro2.PRN = 8; gnss_synchro3.PRN = 32; gnss_synchro4.PRN = 10; gnss_synchro5.PRN = 10; + gnss_synchro6.PRN = 10; std::string gps = "G"; std::string gal = "E"; + std::string glo = "R"; std::string c1 = "1C"; std::string s2 = "2S"; @@ -347,24 +386,28 @@ TEST(RtcmTest, MSMCell) gnss_synchro3.System = *gps.c_str(); gnss_synchro4.System = *gal.c_str(); gnss_synchro5.System = *gps.c_str(); + gnss_synchro6.System = *glo.c_str(); - std::memcpy(static_cast(gnss_synchro.Signal), x5.c_str(), 3); - std::memcpy(static_cast(gnss_synchro2.Signal), s2.c_str(), 3); - std::memcpy(static_cast(gnss_synchro3.Signal), c1.c_str(), 3); - std::memcpy(static_cast(gnss_synchro4.Signal), x5.c_str(), 3); - std::memcpy(static_cast(gnss_synchro5.Signal), c1.c_str(), 3); + std::memcpy((void*)gnss_synchro.Signal, x5.c_str(), 3); + std::memcpy((void*)gnss_synchro2.Signal, s2.c_str(), 3); + std::memcpy((void*)gnss_synchro3.Signal, c1.c_str(), 3); + std::memcpy((void*)gnss_synchro4.Signal, x5.c_str(), 3); + std::memcpy((void*)gnss_synchro5.Signal, c1.c_str(), 3); + std::memcpy((void*)gnss_synchro6.Signal, c1.c_str(), 3); gnss_synchro.Pseudorange_m = 20000000.0; gnss_synchro2.Pseudorange_m = 20001010.0; gnss_synchro3.Pseudorange_m = 24002020.0; gnss_synchro4.Pseudorange_m = 20003010.1; gnss_synchro5.Pseudorange_m = 22003010.1; + gnss_synchro6.Pseudorange_m = 22003010.1; pseudoranges.insert(std::pair(1, gnss_synchro)); pseudoranges.insert(std::pair(2, gnss_synchro2)); pseudoranges.insert(std::pair(3, gnss_synchro3)); pseudoranges.insert(std::pair(4, gnss_synchro4)); pseudoranges.insert(std::pair(5, gnss_synchro5)); + pseudoranges.insert(std::pair(6, gnss_synchro5)); unsigned int ref_id = 1234; unsigned int clock_steering_indicator = 0; @@ -376,10 +419,12 @@ TEST(RtcmTest, MSMCell) gps_eph.i_satellite_PRN = gnss_synchro2.PRN; gal_eph.i_satellite_PRN = gnss_synchro.PRN; + //glo_gnav_eph.i_satellite_PRN = gnss_synchro.PRN; std::string MSM1 = rtcm->print_MSM_1(gps_eph, {}, gal_eph, + {}, obs_time, pseudoranges, ref_id, @@ -397,14 +442,17 @@ TEST(RtcmTest, MSMCell) EXPECT_EQ(0, MSM1_bin.substr(size_header + size_msg_length + 169, Nsat * Nsig).compare("001010101100")); // check cell mask std::map pseudoranges2; + pseudoranges2.insert(std::pair(1, gnss_synchro6)); pseudoranges2.insert(std::pair(1, gnss_synchro5)); pseudoranges2.insert(std::pair(2, gnss_synchro4)); pseudoranges2.insert(std::pair(3, gnss_synchro3)); pseudoranges2.insert(std::pair(4, gnss_synchro2)); pseudoranges2.insert(std::pair(5, gnss_synchro)); + pseudoranges2.insert(std::pair(6, gnss_synchro)); std::string MSM1_2 = rtcm->print_MSM_1(gps_eph, {}, gal_eph, + {}, obs_time, pseudoranges2, ref_id, @@ -414,24 +462,25 @@ TEST(RtcmTest, MSMCell) divergence_free, more_messages); std::string MSM1_bin_2 = rtcm->binary_data_to_bin(MSM1_2); - EXPECT_EQ(0, MSM1_bin_2.substr(size_header + size_msg_length + 169, Nsat * Nsig).compare("001010101100")); // check cell mask + EXPECT_EQ(0, MSM1_bin_2.substr(size_header + size_msg_length + 169, Nsat * Nsig).compare("001010001100")); // check cell mask - Gnss_Synchro gnss_synchro6; - gnss_synchro6.PRN = 10; - gnss_synchro6.System = *gps.c_str(); - std::memcpy(static_cast(gnss_synchro6.Signal), s2.c_str(), 3); - gnss_synchro6.Pseudorange_m = 24000000.0; + Gnss_Synchro gnss_synchro7; + gnss_synchro7.PRN = 10; + gnss_synchro7.System = *gps.c_str(); + std::memcpy((void*)gnss_synchro7.Signal, s2.c_str(), 3); + gnss_synchro7.Pseudorange_m = 24000000.0; std::map pseudoranges3; pseudoranges3.insert(std::pair(1, gnss_synchro)); pseudoranges3.insert(std::pair(2, gnss_synchro2)); - pseudoranges3.insert(std::pair(3, gnss_synchro6)); + pseudoranges3.insert(std::pair(3, gnss_synchro7)); pseudoranges3.insert(std::pair(4, gnss_synchro4)); pseudoranges3.insert(std::pair(5, gnss_synchro5)); std::string MSM1_3 = rtcm->print_MSM_1(gps_eph, {}, gal_eph, + {}, obs_time, pseudoranges3, ref_id, @@ -498,7 +547,7 @@ TEST(RtcmTest, MSM1) gps_eph.i_satellite_PRN = gnss_synchro.PRN; std::string MSM1 = rtcm->print_MSM_1(gps_eph, - {}, {}, + {}, {}, {}, obs_time, pseudoranges, ref_id, @@ -545,7 +594,7 @@ TEST(RtcmTest, MSM1) pseudoranges2.insert(std::pair(3, gnss_synchro2)); pseudoranges2.insert(std::pair(4, gnss_synchro)); std::string MSM1_2 = rtcm->print_MSM_1(gps_eph, - {}, {}, + {}, {}, {}, obs_time, pseudoranges2, ref_id, diff --git a/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc b/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc index 5799a7beb..3f4587fae 100644 --- a/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc @@ -1,6 +1,6 @@ /*! * \file gps_l1_ca_dll_pll_tracking_test.cc - * \brief This class implements a tracking test for Galileo_E5a_DLL_PLL_Tracking + * \brief This class implements a telemetry decoder test for GPS_L1_CA_Telemetry_Decoder * implementation based on some input parameters. * \author Javier Arribas, 2015. jarribas(at)cttc.es * @@ -476,4 +476,3 @@ TEST_F(GpsL1CATelemetryDecoderTest, ValidationOfResults) std::cout << "Test completed in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } - diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc new file mode 100644 index 000000000..e845b0d22 --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc @@ -0,0 +1,208 @@ +/*! + * \file glonass_l1_ca_dll_pll_c_aid_tracking_test.cc + * \brief This class implements a tracking test for GLONASS_L1_CA_DLL_PLL_Tracking + * implementation based on some input parameters. + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2012-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gnss_block_factory.h" +#include "gnss_block_interface.h" +#include "tracking_interface.h" +#include "in_memory_configuration.h" +#include "gnss_sdr_valve.h" +#include "gnss_synchro.h" +#include "glonass_l1_ca_dll_pll_c_aid_tracking.h" + + +// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +class GlonassL1CaDllPllCAidTrackingTest_msg_rx; + +typedef boost::shared_ptr GlonassL1CaDllPllCAidTrackingTest_msg_rx_sptr; + +GlonassL1CaDllPllCAidTrackingTest_msg_rx_sptr GlonassL1CaDllPllCAidTrackingTest_msg_rx_make(); + +class GlonassL1CaDllPllCAidTrackingTest_msg_rx : public gr::block +{ +private: + friend GlonassL1CaDllPllCAidTrackingTest_msg_rx_sptr GlonassL1CaDllPllCAidTrackingTest_msg_rx_make(); + void msg_handler_events(pmt::pmt_t msg); + GlonassL1CaDllPllCAidTrackingTest_msg_rx(); + +public: + int rx_message; + ~GlonassL1CaDllPllCAidTrackingTest_msg_rx(); //!< Default destructor + +}; + +GlonassL1CaDllPllCAidTrackingTest_msg_rx_sptr GlonassL1CaDllPllCAidTrackingTest_msg_rx_make() +{ + return GlonassL1CaDllPllCAidTrackingTest_msg_rx_sptr(new GlonassL1CaDllPllCAidTrackingTest_msg_rx()); +} + +void GlonassL1CaDllPllCAidTrackingTest_msg_rx::msg_handler_events(pmt::pmt_t msg) +{ + try + { + long int message = pmt::to_long(msg); + rx_message = message; + } + catch(boost::bad_any_cast& e) + { + LOG(WARNING) << "msg_handler_telemetry Bad any cast!"; + rx_message = 0; + } +} + +GlonassL1CaDllPllCAidTrackingTest_msg_rx::GlonassL1CaDllPllCAidTrackingTest_msg_rx() : + gr::block("GlonassL1CaDllPllCAidTrackingTest_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) +{ + this->message_port_register_in(pmt::mp("events")); + this->set_msg_handler(pmt::mp("events"), boost::bind(&GlonassL1CaDllPllCAidTrackingTest_msg_rx::msg_handler_events, this, _1)); + rx_message = 0; +} + +GlonassL1CaDllPllCAidTrackingTest_msg_rx::~GlonassL1CaDllPllCAidTrackingTest_msg_rx() +{} + + +// ########################################################### + + +class GlonassL1CaDllPllCAidTrackingTest: public ::testing::Test +{ +protected: + GlonassL1CaDllPllCAidTrackingTest() + { + factory = std::make_shared(); + config = std::make_shared(); + item_size = sizeof(gr_complex); + gnss_synchro = Gnss_Synchro(); + } + + ~GlonassL1CaDllPllCAidTrackingTest() + {} + + void init(); + + gr::msg_queue::sptr queue; + gr::top_block_sptr top_block; + std::shared_ptr factory; + std::shared_ptr config; + Gnss_Synchro gnss_synchro; + size_t item_size; +}; + + +void GlonassL1CaDllPllCAidTrackingTest::init() +{ + gnss_synchro.Channel_ID = 0; + gnss_synchro.System = 'R'; + std::string signal = "1G"; + signal.copy(gnss_synchro.Signal, 2, 0); + gnss_synchro.PRN = 11; + + config->set_property("GNSS-SDR.internal_fs_sps", "6625000"); + config->set_property("Tracking_1G.item_type", "gr_complex"); + config->set_property("Tracking_1G.dump", "false"); + config->set_property("Tracking_1G.if", "0.0"); + config->set_property("Tracking_1G.dump_filename", "./tracking_ch_"); + config->set_property("Tracking_1G.implementation", "GLONASS_L1_CA_DLL_PLL_C_Aid_Tracking"); + config->set_property("Tracking_1G.early_late_space_chips", "0.5"); + config->set_property("Tracking_1G.order", "2"); + config->set_property("Tracking_1G.pll_bw_hz", "2"); + config->set_property("Tracking_1G.dll_bw_hz", "0.5"); +} + + +TEST_F(GlonassL1CaDllPllCAidTrackingTest, ValidationOfResults) +{ + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds(0); + int fs_in = 6625000; + int nsamples = fs_in*4e-3*2; + + init(); + queue = gr::msg_queue::make(0); + top_block = gr::make_top_block("Tracking test"); + std::shared_ptr tracking = std::make_shared(config.get(), "Tracking_1G", 1, 1); + boost::shared_ptr msg_rx = GlonassL1CaDllPllCAidTrackingTest_msg_rx_make(); + + gnss_synchro.Acq_delay_samples = 1343; + gnss_synchro.Acq_doppler_hz = -2750; + // gnss_synchro.Acq_doppler_hz = -2750; + gnss_synchro.Acq_samplestamp_samples = 0; + + ASSERT_NO_THROW( { + tracking->set_channel(gnss_synchro.Channel_ID); + }) << "Failure setting channel."; + + ASSERT_NO_THROW( { + tracking->set_gnss_synchro(&gnss_synchro); + }) << "Failure setting gnss_synchro."; + + ASSERT_NO_THROW( { + tracking->connect(top_block); + }) << "Failure connecting tracking to the top_block."; + + ASSERT_NO_THROW( { + gr::analog::sig_source_c::sptr sin_source = gr::analog::sig_source_c::make(fs_in, gr::analog::GR_SIN_WAVE, 1000, 1, gr_complex(0)); + std::string path = std::string(TEST_PATH); + std::string file = path + "signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin"; + const char * file_name = file.c_str(); + gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(gr_complex), file_name, false); + boost::shared_ptr valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue); + gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro)); + top_block->connect(file_source, 0, valve, 0); + top_block->connect(valve, 0, tracking->get_left_block(), 0); + top_block->connect(tracking->get_right_block(), 0, sink, 0); + top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + }) << "Failure connecting the blocks of tracking test."; + + tracking->start_tracking(); + + EXPECT_NO_THROW( { + start = std::chrono::system_clock::now(); + top_block->run(); // Start threads and wait + end = std::chrono::system_clock::now(); + elapsed_seconds = end - start; + }) << "Failure running the top_block."; + + // TODO: Verify tracking results + std::cout << "Tracked " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; +} diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc new file mode 100644 index 000000000..6625fda4f --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc @@ -0,0 +1,207 @@ +/*! + * \file glonass_l1_ca_dll_pll_tracking_test.cc + * \brief This class implements a tracking test for GLONASS_L1_CA_DLL_PLL_Tracking + * implementation based on some input parameters. + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2012-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gnss_block_factory.h" +#include "gnss_block_interface.h" +#include "tracking_interface.h" +#include "in_memory_configuration.h" +#include "gnss_sdr_valve.h" +#include "gnss_synchro.h" +#include "glonass_l1_ca_dll_pll_tracking.h" + + +// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +class GlonassL1CaDllPllTrackingTest_msg_rx; + +typedef boost::shared_ptr GlonassL1CaDllPllTrackingTest_msg_rx_sptr; + +GlonassL1CaDllPllTrackingTest_msg_rx_sptr GlonassL1CaDllPllTrackingTest_msg_rx_make(); + +class GlonassL1CaDllPllTrackingTest_msg_rx : public gr::block +{ +private: + friend GlonassL1CaDllPllTrackingTest_msg_rx_sptr GlonassL1CaDllPllTrackingTest_msg_rx_make(); + void msg_handler_events(pmt::pmt_t msg); + GlonassL1CaDllPllTrackingTest_msg_rx(); + +public: + int rx_message; + ~GlonassL1CaDllPllTrackingTest_msg_rx(); //!< Default destructor + +}; + +GlonassL1CaDllPllTrackingTest_msg_rx_sptr GlonassL1CaDllPllTrackingTest_msg_rx_make() +{ + return GlonassL1CaDllPllTrackingTest_msg_rx_sptr(new GlonassL1CaDllPllTrackingTest_msg_rx()); +} + +void GlonassL1CaDllPllTrackingTest_msg_rx::msg_handler_events(pmt::pmt_t msg) +{ + try + { + long int message = pmt::to_long(msg); + rx_message = message; + } + catch(boost::bad_any_cast& e) + { + LOG(WARNING) << "msg_handler_telemetry Bad any cast!"; + rx_message = 0; + } +} + +GlonassL1CaDllPllTrackingTest_msg_rx::GlonassL1CaDllPllTrackingTest_msg_rx() : + gr::block("GlonassL1CaDllPllTrackingTest_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) +{ + this->message_port_register_in(pmt::mp("events")); + this->set_msg_handler(pmt::mp("events"), boost::bind(&GlonassL1CaDllPllTrackingTest_msg_rx::msg_handler_events, this, _1)); + rx_message = 0; +} + +GlonassL1CaDllPllTrackingTest_msg_rx::~GlonassL1CaDllPllTrackingTest_msg_rx() +{} + + +// ########################################################### + + +class GlonassL1CaDllPllTrackingTest: public ::testing::Test +{ +protected: + GlonassL1CaDllPllTrackingTest() + { + factory = std::make_shared(); + config = std::make_shared(); + item_size = sizeof(gr_complex); + gnss_synchro = Gnss_Synchro(); + } + + ~GlonassL1CaDllPllTrackingTest() + {} + + void init(); + + gr::msg_queue::sptr queue; + gr::top_block_sptr top_block; + std::shared_ptr factory; + std::shared_ptr config; + Gnss_Synchro gnss_synchro; + size_t item_size; +}; + + +void GlonassL1CaDllPllTrackingTest::init() +{ + gnss_synchro.Channel_ID = 0; + gnss_synchro.System = 'R'; + std::string signal = "1G"; + signal.copy(gnss_synchro.Signal, 2, 0); + gnss_synchro.PRN = 11; + + config->set_property("GNSS-SDR.internal_fs_sps", "6625000"); + config->set_property("Tracking_1G.item_type", "gr_complex"); + config->set_property("Tracking_1G.dump", "false"); + config->set_property("Tracking_1G.if", "0.0"); + config->set_property("Tracking_1G.dump_filename", "./tracking_ch_"); + config->set_property("Tracking_1G.implementation", "GLONASS_L1_CA_DLL_PLL_Tracking"); + config->set_property("Tracking_1G.early_late_space_chips", "0.5"); + config->set_property("Tracking_1G.order", "2"); + config->set_property("Tracking_1G.pll_bw_hz", "2"); + config->set_property("Tracking_1G.dll_bw_hz", "0.5"); +} + +TEST_F(GlonassL1CaDllPllTrackingTest, ValidationOfResults) +{ + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds(0); + int fs_in = 6625000; + int nsamples = fs_in*4e-3*2; + + init(); + queue = gr::msg_queue::make(0); + top_block = gr::make_top_block("Tracking test"); + std::shared_ptr tracking = std::make_shared(config.get(), "Tracking_1G", 1, 1); + boost::shared_ptr msg_rx = GlonassL1CaDllPllTrackingTest_msg_rx_make(); + + gnss_synchro.Acq_delay_samples = 1343; + gnss_synchro.Acq_doppler_hz = -2750; + // gnss_synchro.Acq_doppler_hz = -2750; + gnss_synchro.Acq_samplestamp_samples = 0; + + ASSERT_NO_THROW( { + tracking->set_channel(gnss_synchro.Channel_ID); + }) << "Failure setting channel."; + + ASSERT_NO_THROW( { + tracking->set_gnss_synchro(&gnss_synchro); + }) << "Failure setting gnss_synchro."; + + ASSERT_NO_THROW( { + tracking->connect(top_block); + }) << "Failure connecting tracking to the top_block."; + + ASSERT_NO_THROW( { + gr::analog::sig_source_c::sptr sin_source = gr::analog::sig_source_c::make(fs_in, gr::analog::GR_SIN_WAVE, 1000, 1, gr_complex(0)); + std::string path = std::string(TEST_PATH); + std::string file = path + "signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin"; + const char * file_name = file.c_str(); + gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(gr_complex), file_name, false); + boost::shared_ptr valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue); + gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro)); + top_block->connect(file_source, 0, valve, 0); + top_block->connect(valve, 0, tracking->get_left_block(), 0); + top_block->connect(tracking->get_right_block(), 0, sink, 0); + top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + }) << "Failure connecting the blocks of tracking test."; + + tracking->start_tracking(); + + EXPECT_NO_THROW( { + start = std::chrono::system_clock::now(); + top_block->run(); // Start threads and wait + end = std::chrono::system_clock::now(); + elapsed_seconds = end - start; + }) << "Failure running the top_block."; + + // TODO: Verify tracking results + std::cout << "Tracked " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; +} diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc b/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc new file mode 100644 index 000000000..10f0cc28d --- /dev/null +++ b/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc @@ -0,0 +1,140 @@ +/*! + * \file glonass_gnav_ephemeris_test.cc.cc + * \note Code added as part of GSoC 2017 program + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * \see GLONASS ICD + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (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 . + * + * ------------------------------------------------------------------------- + */ + + +#include "gnss_signal_processing.h" +#include "glonass_gnav_ephemeris.h" + + +TEST(GlonassGnavEphemerisTest, ComputeGlonassTime) +{ + Glonass_Gnav_Ephemeris gnav_eph; + gnav_eph.d_yr = 2016; + gnav_eph.d_N_T = 367; + boost::posix_time::time_duration t(0, 0, 7560); + boost::gregorian::date d(gnav_eph.d_yr, 1, 1); + boost::gregorian::days d2(gnav_eph.d_N_T); + d = d + d2; + + boost::gregorian::date expected_gdate; + boost::posix_time::time_duration expected_gtime; + + boost::posix_time::ptime gtime = gnav_eph.compute_GLONASS_time(7560); + expected_gdate = gtime.date(); + expected_gtime = gtime.time_of_day(); + + // Perform assertions of decoded fields + ASSERT_TRUE(expected_gdate.year() - d.year() < FLT_EPSILON ); + ASSERT_TRUE(expected_gdate.month() - d.month() < FLT_EPSILON ); + ASSERT_TRUE(expected_gdate.day() - d.day() < FLT_EPSILON ); + ASSERT_TRUE(expected_gtime.hours() - t.hours() < FLT_EPSILON ); + ASSERT_TRUE(expected_gtime.minutes() - t.minutes() < FLT_EPSILON ); + ASSERT_TRUE(expected_gtime.seconds() - t.seconds() < FLT_EPSILON ); +} + + +/*! + * \brief Testing conversion from GLONASST to GPST + * \test Tests scenario for N_T when greater than 365 days. Possible values here from 1 to 365*4 + */ +TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT1) +{ + Glonass_Gnav_Ephemeris gnav_eph; + gnav_eph.d_yr = 2004; + gnav_eph.d_N_T = 366+28; + + double glo2utc = 3600*3; + double tod = 48600; + double week = 0.0; + double tow = 0.0; + double true_leap_sec = 13; + double true_week = 1307; + double true_tow = 480600+true_leap_sec; + + gnav_eph.glot_to_gpst(tod + glo2utc, 0.0, 0.0, &week, &tow); + + // Perform assertions of decoded fields + ASSERT_TRUE(week - true_week < FLT_EPSILON ); + ASSERT_TRUE(tow - true_tow < FLT_EPSILON ); +} + + +/*! + * \brief Testing conversion from GLONASST to GPST + * \test This version tests the conversion for offsets greater than 30 in a leap year + */ +TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT2) +{ + Glonass_Gnav_Ephemeris gnav_eph; + gnav_eph.d_yr = 2016; + gnav_eph.d_N_T = 268; + + double glo2utc = 3600*3; + double tod = 7560; + double week = 0.0; + double tow = 0.0; + double true_leap_sec = 17; + double true_week = 1915; + double true_tow = 518400+true_leap_sec+tod; + + gnav_eph.glot_to_gpst(tod + glo2utc, 0.0, 0.0, &week, &tow); + + // Perform assertions of decoded fields + ASSERT_TRUE(week - true_week < FLT_EPSILON ); + ASSERT_TRUE(tow - true_tow < FLT_EPSILON ); +} + + +/*! + * \brief Testing conversion from GLONASST to GPST + * \test This version tests the conversion around the vicinity of February 29 days when in leap year + */ +TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT3) +{ + Glonass_Gnav_Ephemeris gnav_eph; + gnav_eph.d_yr = 2016; + gnav_eph.d_N_T = 62; + + double glo2utc = 3600*3; + double tod = 7560; + double week = 0.0; + double tow = 0.0; + double true_leap_sec = 17; + double true_week = 1886; + double true_tow = 259200+true_leap_sec+tod; + + gnav_eph.glot_to_gpst(tod + glo2utc, 0.0, 0.0, &week, &tow); + + // Perform assertions of decoded fields + ASSERT_TRUE(week - true_week < FLT_EPSILON ); + ASSERT_TRUE(tow - true_tow < FLT_EPSILON ); +} diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc b/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc new file mode 100644 index 000000000..e613af58a --- /dev/null +++ b/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc @@ -0,0 +1,268 @@ +/*! + * \file glonass_gnav_navigation_message_test.cc + * \brief This file implements tests for the decoding of the GLONASS GNAV navigation message + * \note Code added as part of GSoC 2017 program + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * \see GLONASS ICD + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "gnss_signal_processing.h" +#include "glonass_gnav_navigation_message.h" + +/*! + * \brief Testing CRC computation for GLONASS GNAV data bits of a string + * \test The provided string was generated with a version of MATLAB GNSS-SDR that + * the author coded to perform proper decoding of GLONASS GNAV signals. + */ +TEST(GlonassGnavNavigationMessageTest, CRCTestSuccess) +{ + // Variables declarations in code + bool test_result; + std::bitset string_bits (std::string ("0010100100001100000000000000000000000000110011110001100000000000000001100100011000000")); + Glonass_Gnav_Navigation_Message gnav_nav_message; + gnav_nav_message.reset(); + + // Call function to test + test_result = gnav_nav_message.CRC_test(string_bits); + + // Check results in unit test assetions + ASSERT_TRUE(test_result); +} + + +/*! + * \brief Testing CRC computation for GLONASS GNAV data bits of a string + * \test The provided string was generated with a version of MATLAB GNSS-SDR that + * the author coded to perform proper decoding of GLONASS GNAV signals. + */ +TEST(GlonassGnavNavigationMessageTest, CRCTestFailure) +{ + // Variables declarations in code + bool test_result; + // Constructor of string to bitset will flip the order of the bits. Needed for CRC computation + std::bitset string_bits (std::string ("0111100100001100000000000000000000000000110011110001100000000000000001100100011000000")); + Glonass_Gnav_Navigation_Message gnav_nav_message; + gnav_nav_message.reset(); + + // Call function to test + test_result = gnav_nav_message.CRC_test(string_bits); + + // Check results in unit test assetions + ASSERT_FALSE(test_result); +} + + +/*! + * \brief Testing string decoding for GLONASS GNAV messages + * \test The provided string (str1.....str15) was generated with a version of + * MATLAB GNSS-SDR that the author coded to perform proper decoding of GLONASS + * GNAV signals. The same assumption is to be applied for ephemeris and almanac + * data provided. + */ +TEST(GlonassGnavNavigationMessageTest, String1Decoder) +{ + // Variable declarations + std::string str1("0000100000001000011001000011111011010101110100000010101011000100011010101011000101111"); + Glonass_Gnav_Navigation_Message gnav_nav_message; + Glonass_Gnav_Ephemeris gnav_ephemeris; + + // Fill out ephemeris values for truth + gnav_ephemeris.d_P_1 = 15; + gnav_ephemeris.d_t_k = 7560; + gnav_ephemeris.d_VXn = -0.490900039672852; + gnav_ephemeris.d_AXn = 0; + gnav_ephemeris.d_Xn = -11025.6669921875; + + // Call target test method + gnav_nav_message.string_decoder(str1); + + // Perform assertions of decoded fields + ASSERT_TRUE(gnav_ephemeris.d_P_1 - gnav_nav_message.gnav_ephemeris.d_P_1 < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_t_k - gnav_nav_message.gnav_ephemeris.d_t_k < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_VXn - gnav_nav_message.gnav_ephemeris.d_VXn < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_AXn - gnav_nav_message.gnav_ephemeris.d_AXn < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_Xn - gnav_nav_message.gnav_ephemeris.d_Xn < FLT_EPSILON ); +} + + +/*! + * \brief Testing string decoding for GLONASS GNAV messages + * \test The provided string (str1.....str15) was generated with a version of + * MATLAB GNSS-SDR that the author coded to perform proper decoding of GLONASS + * GNAV signals. The same assumption is to be applied for ephemeris and almanac + * data provided. + */ +TEST(GlonassGnavNavigationMessageTest, String2Decoder) +{ + // Variable declarations + std::string str2("0001000010001001000001010101100001011001011000000010101100110000001011110000110011110"); + Glonass_Gnav_Navigation_Message gnav_nav_message; + Glonass_Gnav_Ephemeris gnav_ephemeris; + + // Fill out ephemeris values for truth + gnav_ephemeris.d_B_n = 0; + gnav_ephemeris.d_P_2 = 1; + gnav_ephemeris.d_t_b = 8100; + gnav_ephemeris.d_VYn = -2.69022750854492; + gnav_ephemeris.d_AYn = 0; + gnav_ephemeris.d_Yn = -11456.7348632812; + + // Call target test method + gnav_nav_message.flag_ephemeris_str_1 = true; + gnav_nav_message.gnav_ephemeris.d_P_1 = 15; + gnav_nav_message.string_decoder(str2); + + // Perform assertions of decoded fields + ASSERT_TRUE(gnav_ephemeris.d_B_n - gnav_nav_message.gnav_ephemeris.d_B_n < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_P_2 - gnav_nav_message.gnav_ephemeris.d_P_2 < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_t_b - gnav_nav_message.gnav_ephemeris.d_t_b < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_VYn - gnav_nav_message.gnav_ephemeris.d_VYn < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_AYn - gnav_nav_message.gnav_ephemeris.d_AYn < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_Yn - gnav_nav_message.gnav_ephemeris.d_Yn < FLT_EPSILON ); +} + + +/*! + * \brief Testing string decoding for GLONASS GNAV messages + * \test The provided string (str1.....str15) was generated with a version of + * MATLAB GNSS-SDR that the author coded to perform proper decoding of GLONASS + * GNAV signals. The same assumption is to be applied for ephemeris and almanac + * data provided. + */ +TEST(GlonassGnavNavigationMessageTest, String3Decoder) +{ + // Variable declarations + std::string str3("0001110000000001001101001110100011111011010011001101001101110110010011110011100100011"); + Glonass_Gnav_Navigation_Message gnav_nav_message; + Glonass_Gnav_Ephemeris gnav_ephemeris; + + // Fill out ephemeris values for truth + gnav_ephemeris.d_P_3 = 1; + gnav_ephemeris.d_gamma_n = 1.81898940354586e-12; + gnav_ephemeris.d_P = 3; + gnav_ephemeris.d_l3rd_n = 0; + gnav_ephemeris.d_VZn = -1.82016849517822; + gnav_ephemeris.d_AZn = -2.79396772384644e-09; + gnav_ephemeris.d_Zn = 19929.2377929688; + + // Call target test method + gnav_nav_message.flag_ephemeris_str_2 = true; + gnav_nav_message.string_decoder(str3); + + // Perform assertions of decoded fields + ASSERT_TRUE(gnav_ephemeris.d_P_3 - gnav_nav_message.gnav_ephemeris.d_P_3 < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_gamma_n - gnav_nav_message.gnav_ephemeris.d_gamma_n < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_P - gnav_nav_message.gnav_ephemeris.d_P < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_l3rd_n - gnav_nav_message.gnav_ephemeris.d_l3rd_n < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_VZn - gnav_nav_message.gnav_ephemeris.d_VZn < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_AZn - gnav_nav_message.gnav_ephemeris.d_AZn < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_Zn - gnav_nav_message.gnav_ephemeris.d_Zn < FLT_EPSILON ); +} + + +/*! + * \brief Testing string decoding for GLONASS GNAV messages + * \test The provided string (str1.....str15) was generated with a version of + * MATLAB GNSS-SDR that the author coded to perform proper decoding of GLONASS + * GNAV signals. The same assumption is to be applied for ephemeris and almanac + * data provided. + */ +TEST(GlonassGnavNavigationMessageTest, String4Decoder) +{ + // Variable declarations + std::string str4("0010010000101011100100000100000100000000000000000000011000100100001100101010100011101"); + Glonass_Gnav_Navigation_Message gnav_nav_message; + Glonass_Gnav_Ephemeris gnav_ephemeris; + + // Fill out ephemeris values for truth + gnav_ephemeris.d_tau_n = -8.30907374620438e-05; + gnav_ephemeris.d_Delta_tau_n = 9.31322574615479e-10; + gnav_ephemeris.d_E_n = 0; + gnav_ephemeris.d_P_4 = 0; + gnav_ephemeris.d_F_T = 6; + gnav_ephemeris.d_N_T = 268; + gnav_ephemeris.d_n = 21; + gnav_ephemeris.d_M = 1; + + // Call target test method + gnav_nav_message.flag_ephemeris_str_3 = true; + gnav_nav_message.string_decoder(str4); + + // Perform assertions of decoded fields + ASSERT_TRUE(gnav_ephemeris.d_tau_n - gnav_nav_message.gnav_ephemeris.d_tau_n < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_Delta_tau_n - gnav_nav_message.gnav_ephemeris.d_Delta_tau_n < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_E_n - gnav_nav_message.gnav_ephemeris.d_E_n < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_P_4 - gnav_nav_message.gnav_ephemeris.d_P_4 < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_F_T - gnav_nav_message.gnav_ephemeris.d_F_T < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_N_T - gnav_nav_message.gnav_ephemeris.d_N_T < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_n - gnav_nav_message.gnav_ephemeris.d_n < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_M - gnav_nav_message.gnav_ephemeris.d_M < FLT_EPSILON ); +} + + +/*! + * \brief Testing string decoding for GLONASS GNAV messages + * \test The provided string (str1.....str15) was generated with a version of + * MATLAB GNSS-SDR that the author coded to perform proper decoding of GLONASS + * GNAV signals. The same assumption is to be applied for ephemeris and almanac + * data provided. + */ +TEST(GlonassGnavNavigationMessageTest, String5Decoder) +{ + // Variable declarations + std::string str5("0010100100001100000000000000000000000000110011110001100000000000000001100100011000000"); + Glonass_Gnav_Navigation_Message gnav_nav_message; + Glonass_Gnav_Utc_Model gnav_utc_model; + + // Fill out ephemeris values for truth + gnav_utc_model.d_N_A = 268; + gnav_utc_model.d_tau_c = 9.6391886472702e-08; + gnav_utc_model.d_N_4 = 6; + gnav_utc_model.d_tau_gps = 9.313225746154785e-08; + + // Call target test method + gnav_nav_message.flag_ephemeris_str_4 = true; + gnav_nav_message.string_decoder(str5); + + // Perform assertions of decoded fields + ASSERT_TRUE(gnav_utc_model.d_N_A - gnav_nav_message.gnav_utc_model.d_N_A < FLT_EPSILON ); + ASSERT_TRUE(gnav_utc_model.d_tau_c - gnav_nav_message.gnav_utc_model.d_tau_c < FLT_EPSILON ); + ASSERT_TRUE(gnav_utc_model.d_N_4 - gnav_nav_message.gnav_utc_model.d_N_4 < FLT_EPSILON ); + ASSERT_TRUE(gnav_utc_model.d_tau_gps - gnav_nav_message.gnav_utc_model.d_tau_gps < FLT_EPSILON ); +} + +std::string str6("0011010100110100001100111100011100001101011000000110101111001000000101100011111011001"); +std::string str7("0011101101010001000010000110101111110000101101001011111110101110100010111100010001101"); +std::string str8("0100010100111000000001111110001101000000110000001000100111011100001010101111010011010"); +std::string str9("0100111010001001011100010000010100010101111101001011111110101011100010100101000110101"); +std::string str10("0101010101000000000011101111111101111001011000001000101010001100001111000110101111110"); +std::string str11("0101110111011011011100011001111011101111001101001011111111000110100100000110010001111"); +std::string str12("0110010101001100000011110110100110100100010100001000111110000100001110001010111000001"); +std::string str13("0110111011100100111110100001000110100010011101001011111110100100101010011010001101001"); +std::string str14("0111010101010000000100011000011110100110111100001110110100001000001111001101010000101"); +std::string str15("0111101110101010001110101010100111101100001101001011111111100010101010011001010011101"); diff --git a/src/utils/matlab/galileo_e1_dll_pll_veml_plot_sample.m b/src/utils/matlab/galileo_e1_dll_pll_veml_plot_sample.m index 7e543b180..19bc3de13 100644 --- a/src/utils/matlab/galileo_e1_dll_pll_veml_plot_sample.m +++ b/src/utils/matlab/galileo_e1_dll_pll_veml_plot_sample.m @@ -68,6 +68,7 @@ for N=1:1:channels trackResults(N).Q_L = zeros(1,length(GNSS_tracking(N).L)); trackResults(N).Q_VL = zeros(1,length(GNSS_tracking(N).VL)); trackResults(N).PRN = GNSS_tracking(N).PRN.'; + trackResults(N).CNo = GNSS_tracking(N).CN0_SNV_dB_Hz.'; % Use original MATLAB tracking plot function settings.numberOfChannels = channels; diff --git a/src/utils/matlab/glonass_ca_dll_pll_plot_sample.m b/src/utils/matlab/glonass_ca_dll_pll_plot_sample.m new file mode 100644 index 000000000..7cb6753b4 --- /dev/null +++ b/src/utils/matlab/glonass_ca_dll_pll_plot_sample.m @@ -0,0 +1,74 @@ +% /*! +% * \file glonass_ca_dll_pll_plot_sample.m +% * \brief Read GNSS-SDR Tracking dump binary file using the provided +% function and plot some internal variables +% * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com +% * ------------------------------------------------------------------------- +% * +% * 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 . +% * +% * ------------------------------------------------------------------------- +% */ +close all; +clear all; + +if ~exist('glonass_ca_dll_pll_read_tracking_dump.m','file') + addpath('./libs') +end + + +samplingFreq = 6625000; %[Hz] +channels = 5; +first_channel = 0; + +path = '/archive/'; %% CHANGE THIS PATH + +for N=1:1:channels + tracking_log_path = [path 'glo_tracking_ch_' num2str(N+first_channel-1) '.dat']; %% CHANGE epl_tracking_ch_ BY YOUR dump_filename + GNSS_tracking(N)= glonass_ca_dll_pll_read_tracking_dump(tracking_log_path); +end + +% GNSS-SDR format conversion to MATLAB GPS receiver + +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_freq_hz.'; + trackResults(N).dllDiscr = GNSS_tracking(N).code_error.'; + trackResults(N).dllDiscrFilt = GNSS_tracking(N).code_nco.'; + trackResults(N).pllDiscr = GNSS_tracking(N).carr_error.'; + trackResults(N).pllDiscrFilt = GNSS_tracking(N).carr_nco.'; + + trackResults(N).I_P = GNSS_tracking(N).prompt_I.'; + trackResults(N).Q_P = GNSS_tracking(N).prompt_Q.'; + + 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).CNo = GNSS_tracking(N).CN0_SNV_dB_Hz.'; + trackResults(N).PRN = ones(1,length(GNSS_tracking(N).E)); + + % Use original MATLAB tracking plot function + settings.numberOfChannels = channels; + settings.msToProcess = length(GNSS_tracking(N).E); + plotTracking(N,trackResults,settings); +end diff --git a/src/utils/matlab/gps_l1_ca_dll_pll_plot_sample.m b/src/utils/matlab/gps_l1_ca_dll_pll_plot_sample.m index c1c884eaa..22ef63f79 100644 --- a/src/utils/matlab/gps_l1_ca_dll_pll_plot_sample.m +++ b/src/utils/matlab/gps_l1_ca_dll_pll_plot_sample.m @@ -35,14 +35,14 @@ if ~exist('gps_l1_ca_dll_pll_read_tracking_dump.m','file') end -samplingFreq = 2600000; %[Hz] -channels = 2; +samplingFreq = 6625000; %[Hz] +channels = 5; first_channel = 0; -path = '/home/javier/git/gnss-sdr/build/'; %% CHANGE THIS PATH +path = '/archive/'; %% CHANGE THIS PATH for N=1:1:channels - tracking_log_path = [path 'tracking_ch_' num2str(N+first_channel-1) '.dat']; %% CHANGE epl_tracking_ch_ BY YOUR dump_filename + tracking_log_path = [path 'glo_tracking_ch_' num2str(N+first_channel-1) '.dat']; %% CHANGE epl_tracking_ch_ BY YOUR dump_filename GNSS_tracking(N)= gps_l1_ca_dll_pll_read_tracking_dump(tracking_log_path); end @@ -65,6 +65,7 @@ for N=1:1:channels 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 = ones(1,length(GNSS_tracking(N).E)); + trackResults(N).CNo = GNSS_tracking(N).CN0_SNV_dB_Hz.'; % Use original MATLAB tracking plot function settings.numberOfChannels = channels; diff --git a/src/utils/matlab/hybrid_observables_plot_sample.m b/src/utils/matlab/hybrid_observables_plot_sample.m index 8857da352..45b6bf31d 100644 --- a/src/utils/matlab/hybrid_observables_plot_sample.m +++ b/src/utils/matlab/hybrid_observables_plot_sample.m @@ -4,19 +4,20 @@ clearvars; close all; addpath('./libs'); -samplingFreq = 2600000; %[Hz] -channels=2; -path='/home/javier/git/gnss-sdr/build/'; -observables_log_path=[path 'observables.dat']; +samplingFreq = 6625000; %[Hz] +channels=5; +path='/archive/'; +observables_log_path=[path 'glo_observables.dat']; GNSS_observables= read_hybrid_observables_dump(channels,observables_log_path); +%% %optional: %search all channels having good satellite simultaneously min_idx=1; for n=1:1:channels idx=find(GNSS_observables.valid(n,:)>0,1,'first'); if min_idx. +% * +% * ------------------------------------------------------------------------- +% */ +function [GNSS_tracking] = glonass_ca_dll_pll_read_tracking_dump (filename, count) + + %% usage: gps_l1_ca_dll_pll_read_tracking_dump_64bits (filename, [count]) + %% + %% open GNSS-SDR tracking binary log file .dat and return the contents + %% + + narginchk (1,2); + num_float_vars=5; + num_unsigned_long_int_vars=1; + num_double_vars=11; + num_unsigned_int_vars=1; + double_size_bytes=8; + unsigned_long_int_size_bytes=8; + float_size_bytes=4; + long_int_size_bytes=4; + + skip_bytes_each_read=float_size_bytes*num_float_vars+unsigned_long_int_size_bytes*num_unsigned_long_int_vars+double_size_bytes*num_double_vars+long_int_size_bytes*num_unsigned_int_vars; + bytes_shift=0; + + if (nargin < 2) + %count = Inf; + file_stats = dir(filename); + %round num bytes to read to integer number of samples (to protect the script from binary + %dump end file transitory) + count = (file_stats.bytes - mod(file_stats.bytes,skip_bytes_each_read))/skip_bytes_each_read; + end + %loops_counter = fread (f, count, 'uint32',4*12); + f = fopen (filename, 'rb'); + if (f < 0) + else + v1 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); + bytes_shift=bytes_shift+float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next interleaved float + v2 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); + bytes_shift=bytes_shift+float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next interleaved float + v3 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); + bytes_shift=bytes_shift+float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next interleaved float + v4 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); + bytes_shift=bytes_shift+float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next interleaved float + v5 = fread (f, count, 'float',skip_bytes_each_read-float_size_bytes); + bytes_shift=bytes_shift+float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next interleaved unsigned_long_int + v6 = fread (f, count, 'uint64',skip_bytes_each_read-unsigned_long_int_size_bytes); + bytes_shift=bytes_shift+unsigned_long_int_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next interleaved double + v7 = 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 double + v8 = 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 double + v9 = 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 double + v10 = 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 double + v11 = 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 double + v12 = 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 double + v13 = 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 double + v14 = 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 double + v15 = 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 double + v16 = 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 double + v17 = 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 double + v18 = fread (f, count, 'uint32',skip_bytes_each_read-double_size_bytes); + fclose (f); + + %%%%%%%% output vars %%%%%%%% + +% // EPR +% d_dump_file.write(reinterpret_cast(&tmp_E), sizeof(float)); +% d_dump_file.write(reinterpret_cast(&tmp_P), sizeof(float)); +% d_dump_file.write(reinterpret_cast(&tmp_L), sizeof(float)); +% // PROMPT I and Q (to analyze navigation symbols) +% d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); +% d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); +% // PRN start sample stamp +% //tmp_float=(float)d_sample_counter; +% d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); +% // accumulated carrier phase +% d_dump_file.write(reinterpret_cast(&d_acc_carrier_phase_rad), sizeof(double)); +% +% // carrier and code frequency +% d_dump_file.write(reinterpret_cast(&d_carrier_doppler_hz), sizeof(double)); +% d_dump_file.write(reinterpret_cast(&d_code_freq_chips), sizeof(double)); +% +% //PLL commands +% d_dump_file.write(reinterpret_cast(&carr_phase_error_secs_Ti), sizeof(double)); +% d_dump_file.write(reinterpret_cast(&d_carrier_doppler_hz), sizeof(double)); +% +% //DLL commands +% d_dump_file.write(reinterpret_cast(&code_error_chips_Ti), sizeof(double)); +% d_dump_file.write(reinterpret_cast(&code_error_filt_chips), sizeof(double)); +% +% // CN0 and carrier lock test +% d_dump_file.write(reinterpret_cast(&d_CN0_SNV_dB_Hz), sizeof(double)); +% d_dump_file.write(reinterpret_cast(&d_carrier_lock_test), sizeof(double)); +% +% // AUX vars (for debug purposes) +% tmp_double = d_rem_code_phase_samples; +% d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); +% tmp_double = static_cast(d_sample_counter + d_current_prn_length_samples); +% d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); +% // PRN +% unsigned int prn_ = d_acquisition_gnss_synchro->PRN; +% d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + E=v1; + P=v2; + L=v3; + prompt_I=v4; + prompt_Q=v5; + PRN_start_sample=v6; + acc_carrier_phase_rad=v7; + carrier_freq_hz=v8; + code_freq_hz=v9; + carr_error=v10; + carr_nco=v11; + code_error=v12; + code_nco=v13; + CN0_SNV_dB_Hz=v14; + carrier_lock_test=v15; + var1=v16; + var2=v17; + PRN=v18; + + GNSS_tracking.E=E; + GNSS_tracking.P=P; + GNSS_tracking.L=L; + GNSS_tracking.prompt_I=prompt_I; + GNSS_tracking.prompt_Q=prompt_Q; + GNSS_tracking.PRN_start_sample=PRN_start_sample; + GNSS_tracking.acc_carrier_phase_rad=acc_carrier_phase_rad; + GNSS_tracking.carrier_freq_hz=carrier_freq_hz; + GNSS_tracking.code_freq_hz=code_freq_hz; + GNSS_tracking.carr_error=carr_error; + GNSS_tracking.carr_nco=carr_nco; + GNSS_tracking.code_error=code_error; + GNSS_tracking.code_nco=code_nco; + GNSS_tracking.CN0_SNV_dB_Hz=CN0_SNV_dB_Hz; + GNSS_tracking.carrier_lock_test=carrier_lock_test; + GNSS_tracking.d_rem_code_phase_samples=var1; + GNSS_tracking.var2=var2; + GNSS_tracking.PRN=PRN; + end + diff --git a/src/utils/matlab/libs/plotTracking.m b/src/utils/matlab/libs/plotTracking.m index d2e31f537..9abe9c729 100644 --- a/src/utils/matlab/libs/plotTracking.m +++ b/src/utils/matlab/libs/plotTracking.m @@ -54,15 +54,20 @@ for channelNr = channelList %% Draw axes ============================================================== % Row 1 - handles(1, 1) = subplot(3, 3, 1); - handles(1, 2) = subplot(3, 3, [2 3]); + handles(1, 1) = subplot(4, 3, 1); + handles(1, 2) = subplot(4, 3, [2 3]); % Row 2 - handles(2, 1) = subplot(3, 3, 4); - handles(2, 2) = subplot(3, 3, [5 6]); + handles(2, 1) = subplot(4, 3, 4); + handles(2, 2) = subplot(4, 3, [5 6]); % Row 3 - handles(3, 1) = subplot(3, 3, 7); - handles(3, 2) = subplot(3, 3, 8); - handles(3, 3) = subplot(3, 3, 9); + handles(3, 1) = subplot(4, 3, 7); + handles(3, 2) = subplot(4, 3, 8); + handles(3, 3) = subplot(4, 3, 9); + % Row 4 + handles(4, 1) = subplot(4, 3, 10); + handles(4, 2) = subplot(4, 3, 11); + handles(4, 3) = subplot(4, 3, 12); + %% Plot all figures ======================================================= @@ -149,5 +154,36 @@ for channelNr = channelList xlabel(handles(3, 3), 'Time (s)'); ylabel(handles(3, 3), 'Amplitude'); title (handles(3, 3), 'Filtered DLL discriminator'); + + %----- CNo for signal---------------------------------- + plot (handles(4, 1), timeAxisInSeconds, ... + trackResults(channelNr).CNo(1:settings.msToProcess), 'b'); + + grid (handles(4, 1)); + axis (handles(4, 1), 'tight'); + xlabel(handles(4, 1), 'Time (s)'); + ylabel(handles(4, 1), 'CNo (dB-Hz)'); + title (handles(4, 1), 'Carrier to Noise Ratio'); + + %----- Carrier Frequency -------------------------------- + plot (handles(4, 2), timeAxisInSeconds(2:end), ... + trackResults(channelNr).carrFreq(2:settings.msToProcess), 'Color',[0.42 0.25 0.39]); + + grid (handles(4, 2)); + axis (handles(4, 2)); + xlabel(handles(4, 2), 'Time (s)'); + ylabel(handles(4, 2), 'Freq (hz)'); + title (handles(4, 2), 'Carrier Freq'); + + %----- Code Frequency---------------------------------- + %--- Skip sample 0 to help with results display + plot (handles(4, 3), timeAxisInSeconds(2:end), ... + trackResults(channelNr).codeFreq(2:settings.msToProcess), 'Color',[0.2 0.3 0.49]); + + grid (handles(4, 3)); + axis (handles(4, 3), 'tight'); + xlabel(handles(4, 3), 'Time (s)'); + ylabel(handles(4, 3), 'Freq (Hz)'); + title (handles(4, 3), 'Code Freq'); end % for channelNr = channelList diff --git a/src/utils/matlab/plot_acq_grid_gsoc_glonass.m b/src/utils/matlab/plot_acq_grid_gsoc_glonass.m new file mode 100644 index 000000000..9742e5107 --- /dev/null +++ b/src/utils/matlab/plot_acq_grid_gsoc_glonass.m @@ -0,0 +1,99 @@ +% /*! +% * \file plot_acq_grid_gsoc.m +% * \brief Read GNSS-SDR Acquisition dump binary file using the provided +% function and plot acquisition grid of acquisition statistic of PRN sat +% +% This function analyzes a experiment performed by Luis Esteve in the framework +% of the Google Summer of Code (GSoC) 2012, with the collaboration of Javier Arribas +% and Carles Fernández, related to the extension of GNSS-SDR to Galileo. +% +% * \author Luis Esteve, 2012. luis(at)epsilon-formacion.com +% * ------------------------------------------------------------------------- +% * +% * 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 . +% * +% * ------------------------------------------------------------------------- +% */ + +function plot_acq_grid_gsoc_glonass(sat) + +file=['/archive/acquisition_R_1G_sat_' num2str(sat) '_doppler_0.dat']; + +% sampling_freq_Hz=62316000 +sampling_freq_Hz=6.625e6 +Doppler_max_Hz = 10000 +Doppler_min_Hz = -10000 +Doppler_step_Hz = 250 + + +% read files + +x=read_complex_binary (file); + +l_y=length(x); + +Doppler_axes=Doppler_min_Hz:Doppler_step_Hz:Doppler_max_Hz; + +l_x=length(Doppler_axes); + +acq_grid = zeros(l_x,l_y); + +index=0; + +for k=Doppler_min_Hz:Doppler_step_Hz:Doppler_max_Hz + index=index+1; + filename=['acquisition_R_1G_sat_' num2str(sat) '_doppler_' num2str(k) '.dat']; + acq_grid(index,:)=abs(read_complex_binary (filename)); + end + + acq_grid = acq_grid.^2; + +maximum_correlation_peak = max(max(acq_grid)) + +[fila,col]=find(acq_grid==max(max(acq_grid))); + +delay_error_sps = col -1 + +Doppler_error_Hz = Doppler_axes(fila) + +noise_grid=acq_grid; +delay_span=floor(3*sampling_freq_Hz/(0.511e6)); +Doppler_span=floor(500/Doppler_step_Hz); +noise_grid(fila-Doppler_span:fila+Doppler_span,col-delay_span:col+delay_span)=0; + +n=numel(noise_grid)-(2*delay_span+1)*(2*Doppler_span+1); + +noise_floor= sum(sum(noise_grid))/n + +Gain_dbs = 10*log10(maximum_correlation_peak/noise_floor) + + +%% Plot 3D FULL RESOLUTION + + +[X,Y] = meshgrid(Doppler_axes,1:1:l_y); +figure; +surf(X,Y,acq_grid'); + +xlabel('Doppler(Hz)');ylabel('Code Delay(samples)');title(['GLRT statistic of Glonass Parallel Code Phase Search Acquisition. Local replica: L1 cboc PRN ' num2str(sat)]); + + +end