mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-15 04:30:33 +00:00
Merge branch 'next' of https://github.com/gnss-sdr/gnss-sdr into fpga
This commit is contained in:
commit
bb0fae98c7
13
README.md
13
README.md
@ -2,18 +2,20 @@
|
||||
|
||||
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
|
||||
|
||||
|
||||
**Welcome to GNSS-SDR!**
|
||||
|
||||
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:
|
||||
- 🛰 BeiDou B1I (centered at 1561.098 MHz) :white_check_mark:
|
||||
- 🛰 GPS L1 C/A (centered at 1575.42 MHz) :white_check_mark:
|
||||
- 🛰 Galileo E1b/c (centered at 1575.42 MHz) :white_check_mark:
|
||||
- 🛰 GLONASS L1 C/A (centered at 1601.72 MHz) :white_check_mark:
|
||||
- 🛰 GLONASS L1 C/A (centered at 1602.00 MHz) :white_check_mark:
|
||||
|
||||
In the L2 band:
|
||||
- 🛰 GPS L2C (centered at 1227.60 MHz) :white_check_mark:
|
||||
- 🛰 GLONASS L2 C/A (centered at 1246 MHz) :white_check_mark:
|
||||
- 🛰 GLONASS L2 C/A (centered at 1246.00 MHz) :white_check_mark:
|
||||
|
||||
In the L5 band:
|
||||
- 🛰 GPS L5 (centered at 1176.45 MHz) :white_check_mark:
|
||||
@ -187,9 +189,9 @@ $ sudo apt-get install libblas-dev liblapack-dev # For Debian/Ubuntu/Linux
|
||||
$ sudo yum install lapack-devel blas-devel # For Fedora/CentOS/RHEL
|
||||
$ sudo zypper install lapack-devel blas-devel # For OpenSUSE
|
||||
$ sudo pacman -S blas lapack # For Arch Linux
|
||||
$ wget https://sourceforge.net/projects/arma/files/armadillo-9.100.5.tar.xz
|
||||
$ tar xvfz armadillo-9.100.5.tar.xz
|
||||
$ cd armadillo-9.100.5
|
||||
$ wget https://sourceforge.net/projects/arma/files/armadillo-9.200.7.tar.xz
|
||||
$ tar xvfz armadillo-9.200.7.tar.xz
|
||||
$ cd armadillo-9.200.7
|
||||
$ cmake .
|
||||
$ make
|
||||
$ sudo make install
|
||||
@ -1116,6 +1118,7 @@ Each channel must be assigned to a GNSS signal, according to the following ident
|
||||
| GPS L1 C/A | 1C |
|
||||
| Galileo E1b/c | 1B |
|
||||
| Glonass L1 C/A | 1G |
|
||||
| Beidou B1I | B1 |
|
||||
| GPS L2 L2C(M) | 2S |
|
||||
| Glonass L2 C/A | 2G |
|
||||
| GPS L5 | L5 |
|
||||
|
121
conf/gnss-sdr_BDS_B1I_byte.conf
Normal file
121
conf/gnss-sdr_BDS_B1I_byte.conf
Normal file
@ -0,0 +1,121 @@
|
||||
; This is a GNSS-SDR configuration file
|
||||
; The configuration API is described at https://gnss-sdr.org/docs/sp-blocks/
|
||||
|
||||
; You can define your own receiver and invoke it by doing
|
||||
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
|
||||
;
|
||||
|
||||
[GNSS-SDR]
|
||||
|
||||
;######### GLOBAL OPTIONS ##################
|
||||
;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second].
|
||||
GNSS-SDR.internal_fs_sps=25000000
|
||||
|
||||
;######### CONTROL_THREAD CONFIG ############
|
||||
ControlThread.wait_for_flowgraph=false
|
||||
|
||||
;######### SIGNAL_SOURCE CONFIG ############
|
||||
SignalSource.implementation=File_Signal_Source
|
||||
SignalSource.filename=/home/dmiralles/Documents/GNSS-Metadata-Standard/install/BdsB1IStr01.dat
|
||||
SignalSource.item_type=byte
|
||||
SignalSource.sampling_frequency=25000000
|
||||
SignalSource.samples=0
|
||||
SignalSource.repeat=false
|
||||
SignalSource.dump=false
|
||||
SignalSource.enable_throttle_control=false
|
||||
|
||||
;######### SIGNAL_CONDITIONER CONFIG ############
|
||||
SignalConditioner.implementation=Signal_Conditioner
|
||||
DataTypeAdapter.implementation=Byte_To_Short
|
||||
InputFilter.implementation=Freq_Xlating_Fir_Filter
|
||||
InputFilter.input_item_type=short
|
||||
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=25000000
|
||||
InputFilter.IF=6250000
|
||||
Resampler.implementation=Pass_Through
|
||||
Resampler.sample_freq_in=25000000
|
||||
Resampler.sample_freq_out=25000000
|
||||
Resampler.item_type=gr_complex
|
||||
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
Channels_B1.count=10
|
||||
Channels.in_acquisition=1
|
||||
Channel.signal=B1
|
||||
|
||||
Channel0.satellite = 6;
|
||||
Channel1.satellite = 8;
|
||||
Channel2.satellite = 9;
|
||||
Channel3.satellite = 13;
|
||||
Channel4.satellite = 17;
|
||||
Channel5.satellite = 1;
|
||||
Channel6.satellite = 2;
|
||||
Channel7.satellite = 3;
|
||||
Channel8.satellite = 4;
|
||||
Channel9.satellite = 5;
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
Acquisition_B1.implementation=BEIDOU_B1I_PCPS_Acquisition
|
||||
Acquisition_B1.item_type=gr_complex
|
||||
Acquisition_B1.coherent_integration_time_ms=1
|
||||
Acquisition_B1.threshold=0.0038
|
||||
;Acquisition_B1.pfa=0.0000001;
|
||||
Acquisition_B1.doppler_max=15000
|
||||
Acquisition_B1.doppler_step=100
|
||||
Acquisition_B1.dump=true
|
||||
Acquisition_B1.dump_filename=./bds_acq
|
||||
Acquisition_B1.blocking=false;
|
||||
Acquisition_B1.use_CFAR_algorithm=true;
|
||||
Acquisition_B1.bit_transition_flag = false;
|
||||
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
Tracking_B1.implementation=BEIDOU_B1I_DLL_PLL_Tracking
|
||||
Tracking_B1.item_type=gr_complex
|
||||
Tracking_B1.pll_bw_hz=25.0;
|
||||
Tracking_B1.dll_bw_hz=2.50;
|
||||
Tracking_B1.dump=true;
|
||||
Tracking_B1.dump_filename=./epl_tracking_ch_
|
||||
|
||||
|
||||
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||
TelemetryDecoder_B1.implementation=BEIDOU_B1I_Telemetry_Decoder
|
||||
TelemetryDecoder_B1.dump=false
|
||||
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
Observables.implementation=Hybrid_Observables
|
||||
Observables.dump=true
|
||||
Observables.dump_filename=./observables.dat
|
||||
|
||||
|
||||
;######### PVT CONFIG ############
|
||||
PVT.implementation=RTKLIB_PVT
|
||||
PVT.positioning_mode=Single ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic
|
||||
PVT.iono_model=OFF ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX
|
||||
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
|
||||
PVT.flag_rtcm_server=false
|
||||
PVT.flag_rtcm_tty_port=false
|
||||
PVT.rtcm_dump_devname=/dev/pts/1
|
||||
PVT.dump=true
|
100
conf/gnss-sdr_GLONASS_L1_ibyte.conf
Normal file
100
conf/gnss-sdr_GLONASS_L1_ibyte.conf
Normal file
@ -0,0 +1,100 @@
|
||||
; You can define your own receiver and invoke it by doing
|
||||
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
|
||||
;
|
||||
|
||||
[GNSS-SDR]
|
||||
|
||||
;######### GLOBAL OPTIONS ##################
|
||||
;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [Hz].
|
||||
GNSS-SDR.internal_fs_sps=6625000
|
||||
|
||||
;######### CONTROL_THREAD CONFIG ############
|
||||
ControlThread.wait_for_flowgraph=false
|
||||
|
||||
;######### SIGNAL_SOURCE CONFIG ############
|
||||
SignalSource.implementation=File_Signal_Source
|
||||
SignalSource.filename=/home/dmiralles/Documents/GSOC/GSOC2017/gnss-sdr/data/dmirallesNT1065_L2_20160831_fs6625e6_60e3_schar_1H.bin
|
||||
SignalSource.item_type=ibyte
|
||||
SignalSource.sampling_frequency=6625000
|
||||
SignalSource.freq=1602000000
|
||||
SignalSource.samples=0
|
||||
SignalSource.repeat=false
|
||||
SignalSource.sample_type=iq
|
||||
SignalSource.seconds_to_skip=0
|
||||
SignalSource.dump=false
|
||||
SignalSource.dump_filename=../data/signal_source.dat
|
||||
SignalSource.enable_throttle_control=false
|
||||
|
||||
|
||||
;######### SIGNAL_CONDITIONER CONFIG ############
|
||||
SignalConditioner.implementation=Signal_Conditioner
|
||||
|
||||
;DataTypeAdapter.implementation=Ishort_To_Complex
|
||||
DataTypeAdapter.implementation=Ibyte_To_Complex
|
||||
InputFilter.implementation=Pass_Through
|
||||
;InputFilter.input_item_type=gr_complex
|
||||
;InputFilter.output_item_type=gr_complex
|
||||
InputFilter.item_type=gr_complex
|
||||
;Resampler.implementation=Pass_Through
|
||||
;Resampler.item_type=gr_complex
|
||||
Resampler.implementation=Pass_Through
|
||||
;Resampler.sample_freq_in=4000000
|
||||
;Resampler.sample_freq_out=2000000
|
||||
;Resampler.item_type=gr_complex
|
||||
Resampler.item_type=gr_complex
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
Channels_1R.count=8 ;Assuming here that identifier `1r=R` defines GLONASS SP signals
|
||||
Channels.in_acquisition=1
|
||||
Channel.signal=1R
|
||||
;Channel.item_type=cshort
|
||||
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
Acquisition_1R.dump=false
|
||||
Acquisition_1R.dump_filename=./acq_dump.dat
|
||||
Acquisition_1R.item_type=cshort
|
||||
Acquisition_1R.sampled_ms=1
|
||||
Acquisition_1R.implementation=GLONASS_L1_CA_PCPS_Acquisition
|
||||
Acquisition_1R.threshold=0.008
|
||||
;Acquisition_1C.pfa=0.000001
|
||||
Acquisition_1R.doppler_max=10000
|
||||
Acquisition_1R.doppler_step=250
|
||||
Acquisition_1R.tong_init_val=2
|
||||
Acquisition_1R.tong_max_val=10
|
||||
Acquisition_1R.tong_max_dwells=20
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
Tracking_1R.implementation=GLONASS_L1_CA_DLL_PLL_C_Aid_Tracking
|
||||
Tracking_1R.item_type=cshort
|
||||
Tracking_1R.dump=false
|
||||
Tracking_1R.dump_filename=../data/epl_tracking_ch_
|
||||
Tracking_1R.pll_bw_hz=40.0;
|
||||
Tracking_1R.dll_bw_hz=4.0;
|
||||
Tracking_1R.order=3;
|
||||
|
||||
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||
TelemetryDecoder_1R.implementation=GLONASS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder_1R.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
|
||||
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.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
|
||||
PVT.flag_rtcm_server=false
|
||||
PVT.flag_rtcm_tty_port=false
|
||||
PVT.rtcm_dump_devname=/dev/pts/1
|
||||
PVT.dump=false
|
@ -1,3 +1,10 @@
|
||||
## [Unreleased](https://github.com/gnss-sdr/gnss-sdr/tree/next)
|
||||
|
||||
### Improvements in Interoperability:
|
||||
|
||||
- Added the BeiDou B1I receiver chain.
|
||||
|
||||
|
||||
## [0.0.10](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.10)
|
||||
|
||||
This release has several improvements in different dimensions, addition of new features and bug fixes:
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 88 KiB |
@ -170,6 +170,15 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration,
|
||||
* 26 | GPS L1 C/A + GLONASS L1 C/A
|
||||
* 27 | Galileo E1B + GLONASS L1 C/A
|
||||
* 28 | GPS L2C + GLONASS L1 C/A
|
||||
*
|
||||
*
|
||||
* Skipped previous values to avoid overlapping
|
||||
* 50 | Beidou B1I
|
||||
* 51 | Beidou B1I + GPS L1 C/A
|
||||
* 52 | Beidou B1I + Galileo E1B
|
||||
* 53 | Beidou B1I + GLONASS L1 C/A
|
||||
* 54 | Beidou B1I + GPS L1 C/A + Galileo E1B
|
||||
* 55 | Beidou B1I + GPS L1 C/A + GLONASS L1 C/A + Galileo E1B
|
||||
*/
|
||||
int gps_1C_count = configuration->property("Channels_1C.count", 0);
|
||||
int gps_2S_count = configuration->property("Channels_2S.count", 0);
|
||||
@ -179,42 +188,49 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration,
|
||||
int gal_E5b_count = configuration->property("Channels_7X.count", 0);
|
||||
int glo_1G_count = configuration->property("Channels_1G.count", 0);
|
||||
int glo_2G_count = configuration->property("Channels_2G.count", 0);
|
||||
int bds_B1_count = configuration->property("Channels_B1.count", 0);
|
||||
|
||||
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_2G_count == 0)) pvt_output_parameters.type_of_receiver = 1; // L1
|
||||
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_2G_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 3; // L5
|
||||
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_2G_count == 0)) pvt_output_parameters.type_of_receiver = 4; // E1
|
||||
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_2G_count == 0)) pvt_output_parameters.type_of_receiver = 5; // E5a
|
||||
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_2G_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.type_of_receiver = 1; // L1
|
||||
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_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.type_of_receiver = 3; // L5
|
||||
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_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.type_of_receiver = 4; // E1
|
||||
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_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.type_of_receiver = 5; // E5a
|
||||
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_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0)) pvt_output_parameters.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) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 8; // L1+L5
|
||||
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_2G_count == 0)) pvt_output_parameters.type_of_receiver = 9; // L1+E1
|
||||
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_2G_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 13; // L5+E5a
|
||||
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_2G_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0)) pvt_output_parameters.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) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.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) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.type_of_receiver = 8; // L1+L5
|
||||
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_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.type_of_receiver = 9; // L1+E1
|
||||
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_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.type_of_receiver = 13; // L5+E5a
|
||||
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_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.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)) pvt_output_parameters.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) && (glo_2G_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0)) pvt_output_parameters.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) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.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)) pvt_output_parameters.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)) pvt_output_parameters.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) && (glo_2G_count == 0)) pvt_output_parameters.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) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.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)) pvt_output_parameters.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)) pvt_output_parameters.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_2G_count != 0)) pvt_output_parameters.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_2G_count != 0)) pvt_output_parameters.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) && (glo_2G_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 28;
|
||||
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_2G_count != 0)) pvt_output_parameters.type_of_receiver = 29;
|
||||
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_2G_count != 0)) pvt_output_parameters.type_of_receiver = 30;
|
||||
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_2G_count != 0)) pvt_output_parameters.type_of_receiver = 31;
|
||||
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) && (bds_B1_count == 0)) pvt_output_parameters.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_2G_count != 0) && (bds_B1_count == 0)) pvt_output_parameters.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_2G_count != 0) && (bds_B1_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.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) && (glo_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.type_of_receiver = 28;
|
||||
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_2G_count != 0) && (bds_B1_count == 0)) pvt_output_parameters.type_of_receiver = 29;
|
||||
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_2G_count != 0) && (bds_B1_count == 0)) pvt_output_parameters.type_of_receiver = 30;
|
||||
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_2G_count != 0) && (bds_B1_count == 0)) pvt_output_parameters.type_of_receiver = 31;
|
||||
|
||||
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_2G_count == 0)) pvt_output_parameters.type_of_receiver = 32; // L1+E1+L5+E5a
|
||||
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_2G_count == 0)) pvt_output_parameters.type_of_receiver = 33; // L1+E1+E5a
|
||||
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_2G_count == 0) && (bds_B1_count == 0)) pvt_output_parameters.type_of_receiver = 32; // L1+E1+L5+E5a
|
||||
// BeiDou B1I Receiver
|
||||
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_2G_count == 0) && (bds_B1_count != 0)) pvt_output_parameters.type_of_receiver = 50;
|
||||
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_2G_count == 0) && (bds_B1_count != 0)) pvt_output_parameters.type_of_receiver = 51;
|
||||
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_2G_count == 0) && (bds_B1_count != 0)) pvt_output_parameters.type_of_receiver = 52;
|
||||
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_2G_count == 0) && (bds_B1_count != 0)) pvt_output_parameters.type_of_receiver = 53;
|
||||
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_2G_count == 0) && (bds_B1_count != 0)) pvt_output_parameters.type_of_receiver = 54;
|
||||
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_2G_count == 0) && (bds_B1_count != 0)) pvt_output_parameters.type_of_receiver = 55;
|
||||
|
||||
// RTKLIB PVT solver options
|
||||
// Settings 1
|
||||
@ -239,7 +255,7 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration,
|
||||
|
||||
int num_bands = 0;
|
||||
|
||||
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) || (bds_B1_count > 0)) num_bands = 1;
|
||||
if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gps_2S_count > 0) || (glo_2G_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) || (glo_2G_count > 0)) && ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0))) num_bands = 3;
|
||||
@ -326,6 +342,8 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration,
|
||||
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) || (glo_2G_count > 0)) nsys += SYS_GLO;
|
||||
if ((bds_B1_count > 0)) nsys += SYS_BDS;
|
||||
|
||||
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 */
|
||||
{
|
||||
|
@ -221,6 +221,45 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg)
|
||||
DLOG(INFO) << "New GLONASS GNAV Almanac has arrived "
|
||||
<< ", GLONASS GNAV Slot Number =" << glonass_gnav_almanac->d_n_A;
|
||||
}
|
||||
|
||||
// ************* BeiDou telemetry *****************
|
||||
if (pmt::any_ref(msg).type() == typeid(std::shared_ptr<Beidou_Dnav_Ephemeris>))
|
||||
{
|
||||
// ### Beidou EPHEMERIS ###
|
||||
std::shared_ptr<Beidou_Dnav_Ephemeris> bds_dnav_eph;
|
||||
bds_dnav_eph = boost::any_cast<std::shared_ptr<Beidou_Dnav_Ephemeris>>(pmt::any_ref(msg));
|
||||
DLOG(INFO) << "Ephemeris record has arrived from SAT ID "
|
||||
<< bds_dnav_eph->i_satellite_PRN << " (Block "
|
||||
<< bds_dnav_eph->satelliteBlock[bds_dnav_eph->i_satellite_PRN] << ")"
|
||||
<< "inserted with Toe=" << bds_dnav_eph->d_Toe << " and BDS Week="
|
||||
<< bds_dnav_eph->i_BEIDOU_week;
|
||||
// update/insert new ephemeris record to the global ephemeris map
|
||||
d_pvt_solver->beidou_dnav_ephemeris_map[bds_dnav_eph->i_satellite_PRN] = *bds_dnav_eph;
|
||||
}
|
||||
else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr<Beidou_Dnav_Iono>))
|
||||
{
|
||||
// ### BeiDou IONO ###
|
||||
std::shared_ptr<Beidou_Dnav_Iono> bds_dnav_iono;
|
||||
bds_dnav_iono = boost::any_cast<std::shared_ptr<Beidou_Dnav_Iono>>(pmt::any_ref(msg));
|
||||
d_pvt_solver->beidou_dnav_iono = *bds_dnav_iono;
|
||||
DLOG(INFO) << "New BeiDou DNAV IONO record has arrived ";
|
||||
}
|
||||
else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr<Beidou_Dnav_Utc_Model>))
|
||||
{
|
||||
// ### GPS UTC MODEL ###
|
||||
std::shared_ptr<Beidou_Dnav_Utc_Model> bds_dnav_utc_model;
|
||||
bds_dnav_utc_model = boost::any_cast<std::shared_ptr<Beidou_Dnav_Utc_Model>>(pmt::any_ref(msg));
|
||||
d_pvt_solver->beidou_dnav_utc_model = *bds_dnav_utc_model;
|
||||
DLOG(INFO) << "New BeiDou DNAV UTC record has arrived ";
|
||||
}
|
||||
else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr<Beidou_Dnav_Almanac>))
|
||||
{
|
||||
// ### GPS ALMANAC ###
|
||||
std::shared_ptr<Beidou_Dnav_Almanac> bds_dnav_almanac;
|
||||
bds_dnav_almanac = boost::any_cast<std::shared_ptr<Beidou_Dnav_Almanac>>(pmt::any_ref(msg));
|
||||
d_pvt_solver->beidou_dnav_almanac_map[bds_dnav_almanac->i_satellite_PRN] = *bds_dnav_almanac;
|
||||
DLOG(INFO) << "New BeiDou DNAV almanac record has arrived ";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << "msg_handler_telemetry unknown object type!";
|
||||
@ -257,12 +296,25 @@ std::map<int, Galileo_Almanac> rtklib_pvt_cc::get_galileo_almanac_map() const
|
||||
}
|
||||
|
||||
|
||||
std::map<int, Beidou_Dnav_Ephemeris> rtklib_pvt_cc::get_beidou_dnav_ephemeris_map() const
|
||||
{
|
||||
return d_pvt_solver->beidou_dnav_ephemeris_map;
|
||||
}
|
||||
|
||||
|
||||
std::map<int, Beidou_Dnav_Almanac> rtklib_pvt_cc::get_beidou_dnav_almanac_map() const
|
||||
{
|
||||
return d_pvt_solver->beidou_dnav_almanac_map;
|
||||
}
|
||||
|
||||
void rtklib_pvt_cc::clear_ephemeris()
|
||||
{
|
||||
d_pvt_solver->gps_ephemeris_map.clear();
|
||||
d_pvt_solver->gps_almanac_map.clear();
|
||||
d_pvt_solver->galileo_ephemeris_map.clear();
|
||||
d_pvt_solver->galileo_almanac_map.clear();
|
||||
d_pvt_solver->beidou_dnav_ephemeris_map.clear();
|
||||
d_pvt_solver->beidou_dnav_almanac_map.clear();
|
||||
}
|
||||
|
||||
|
||||
@ -832,6 +884,94 @@ rtklib_pvt_cc::~rtklib_pvt_cc()
|
||||
{
|
||||
LOG(INFO) << "Failed to save GLONASS GNAV ephemeris, not valid data";
|
||||
}
|
||||
|
||||
// save BeiDou DNAV ephemeris to XML file
|
||||
file_name = xml_base_path + "bds_dnav_ephemeris.xml";
|
||||
if (d_pvt_solver->beidou_dnav_ephemeris_map.empty() == false)
|
||||
{
|
||||
std::ofstream ofs;
|
||||
try
|
||||
{
|
||||
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
|
||||
boost::archive::xml_oarchive xml(ofs);
|
||||
xml << boost::serialization::make_nvp("GNSS-SDR_bds_dnav_ephemeris_map", d_pvt_solver->beidou_dnav_ephemeris_map);
|
||||
LOG(INFO) << "Saved BeiDou DNAV Ephemeris map data";
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG(WARNING) << e.what();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(INFO) << "Failed to save BeiDou DNAV Ephemeris, map is empty";
|
||||
}
|
||||
|
||||
// Save BeiDou DNAV iono parameters
|
||||
file_name = xml_base_path + "bds_dnav_iono.xml";
|
||||
if (d_pvt_solver->beidou_dnav_iono.valid)
|
||||
{
|
||||
std::ofstream ofs;
|
||||
try
|
||||
{
|
||||
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
|
||||
boost::archive::xml_oarchive xml(ofs);
|
||||
xml << boost::serialization::make_nvp("GNSS-SDR_bds_dnav_iono_model", d_pvt_solver->beidou_dnav_iono);
|
||||
LOG(INFO) << "Saved BeiDou DNAV ionospheric model parameters";
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LOG(WARNING) << e.what();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(INFO) << "Failed to save BeiDou DNAV ionospheric model parameters, not valid data";
|
||||
}
|
||||
|
||||
// save BeiDou DNAV almanac to XML file
|
||||
file_name = xml_base_path + "bds_dnav_almanac.xml";
|
||||
if (d_pvt_solver->beidou_dnav_almanac_map.empty() == false)
|
||||
{
|
||||
std::ofstream ofs;
|
||||
try
|
||||
{
|
||||
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
|
||||
boost::archive::xml_oarchive xml(ofs);
|
||||
xml << boost::serialization::make_nvp("GNSS-SDR_bds_dnav_almanac_map", d_pvt_solver->beidou_dnav_almanac_map);
|
||||
LOG(INFO) << "Saved BeiDou DNAV almanac map data";
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG(WARNING) << e.what();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(INFO) << "Failed to save BeiDou DNAV almanac, map is empty";
|
||||
}
|
||||
|
||||
// Save BeiDou UTC model parameters
|
||||
file_name = xml_base_path + "bds_dnav_utc_model.xml";
|
||||
if (d_pvt_solver->beidou_dnav_utc_model.valid)
|
||||
{
|
||||
std::ofstream ofs;
|
||||
try
|
||||
{
|
||||
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
|
||||
boost::archive::xml_oarchive xml(ofs);
|
||||
xml << boost::serialization::make_nvp("GNSS-SDR_bds_dnav_utc_model", d_pvt_solver->beidou_dnav_utc_model);
|
||||
LOG(INFO) << "Saved BeiDou DNAV UTC model parameters";
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LOG(WARNING) << e.what();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(INFO) << "Failed to save BeiDou DNAV UTC model parameters, not valid data";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -955,13 +1095,16 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
std::map<int, Galileo_Ephemeris>::const_iterator tmp_eph_iter_gal = d_pvt_solver->galileo_ephemeris_map.find(in[i][epoch].PRN);
|
||||
std::map<int, Gps_CNAV_Ephemeris>::const_iterator tmp_eph_iter_cnav = d_pvt_solver->gps_cnav_ephemeris_map.find(in[i][epoch].PRN);
|
||||
std::map<int, Glonass_Gnav_Ephemeris>::const_iterator tmp_eph_iter_glo_gnav = d_pvt_solver->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN);
|
||||
std::map<int, Beidou_Dnav_Ephemeris>::const_iterator tmp_eph_iter_bds_dnav = d_pvt_solver->beidou_dnav_ephemeris_map.find(in[i][epoch].PRN);
|
||||
|
||||
if (((tmp_eph_iter_gps->second.i_satellite_PRN == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal) == "1C")) or
|
||||
((tmp_eph_iter_cnav->second.i_satellite_PRN == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal) == "2S")) or
|
||||
((tmp_eph_iter_gal->second.i_satellite_PRN == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal) == "1B")) or
|
||||
((tmp_eph_iter_gal->second.i_satellite_PRN == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal) == "5X")) or
|
||||
((tmp_eph_iter_glo_gnav->second.i_satellite_PRN == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal) == "1G")) or
|
||||
((tmp_eph_iter_glo_gnav->second.i_satellite_PRN == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal) == "2G")) or
|
||||
((tmp_eph_iter_cnav->second.i_satellite_PRN == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal) == "L5")))
|
||||
((tmp_eph_iter_cnav->second.i_satellite_PRN == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal) == "L5")) or
|
||||
((tmp_eph_iter_bds_dnav->second.i_satellite_PRN == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal) == "B1")))
|
||||
{
|
||||
// store valid observables in a map.
|
||||
gnss_observables_map.insert(std::pair<int, Gnss_Synchro>(i, in[i][epoch]));
|
||||
@ -1170,12 +1313,14 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
std::map<int, Gps_Ephemeris>::const_iterator gps_ephemeris_iter;
|
||||
std::map<int, Gps_CNAV_Ephemeris>::const_iterator gps_cnav_ephemeris_iter;
|
||||
std::map<int, Glonass_Gnav_Ephemeris>::const_iterator glonass_gnav_ephemeris_iter;
|
||||
std::map<int, Beidou_Dnav_Ephemeris>::const_iterator beidou_dnav_ephemeris_iter;
|
||||
if (!b_rinex_header_written) // & we have utc data in nav message!
|
||||
{
|
||||
galileo_ephemeris_iter = d_pvt_solver->galileo_ephemeris_map.cbegin();
|
||||
gps_ephemeris_iter = d_pvt_solver->gps_ephemeris_map.cbegin();
|
||||
gps_cnav_ephemeris_iter = d_pvt_solver->gps_cnav_ephemeris_map.cbegin();
|
||||
glonass_gnav_ephemeris_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin();
|
||||
beidou_dnav_ephemeris_iter = d_pvt_solver->beidou_dnav_ephemeris_map.cbegin();
|
||||
switch (type_of_rx)
|
||||
{
|
||||
case 1: // GPS L1 C/A only
|
||||
@ -1420,6 +1565,15 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
b_rinex_header_written = true; // do not write header anymore
|
||||
}
|
||||
break;
|
||||
case 50: // BDS B1I only
|
||||
if (beidou_dnav_ephemeris_iter != d_pvt_solver->beidou_dnav_ephemeris_map.cend())
|
||||
{
|
||||
rp->rinex_obs_header(rp->obsFile, beidou_dnav_ephemeris_iter->second, d_rx_time, "B1");
|
||||
rp->rinex_nav_header(rp->navFile, d_pvt_solver->beidou_dnav_iono, d_pvt_solver->beidou_dnav_utc_model);
|
||||
b_rinex_header_written = true; // do not write header anymore
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1503,6 +1657,9 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
case 33: // L1+E1+E5a
|
||||
rp->log_rinex_nav(rp->navMixFile, d_pvt_solver->gps_ephemeris_map, d_pvt_solver->galileo_ephemeris_map);
|
||||
break;
|
||||
case 50: // BDS B1I only
|
||||
rp->log_rinex_nav(rp->navFile, d_pvt_solver->beidou_dnav_ephemeris_map);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1511,6 +1668,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
gps_ephemeris_iter = d_pvt_solver->gps_ephemeris_map.cbegin();
|
||||
gps_cnav_ephemeris_iter = d_pvt_solver->gps_cnav_ephemeris_map.cbegin();
|
||||
glonass_gnav_ephemeris_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin();
|
||||
beidou_dnav_ephemeris_iter = d_pvt_solver->beidou_dnav_ephemeris_map.cbegin();
|
||||
|
||||
// Log observables into the RINEX file
|
||||
if (flag_write_RINEX_obs_output)
|
||||
@ -1809,6 +1967,18 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
b_rinex_header_updated = true; // do not write header anymore
|
||||
}
|
||||
break;
|
||||
case 50: // BDS B1I only
|
||||
if (beidou_dnav_ephemeris_iter != d_pvt_solver->beidou_dnav_ephemeris_map.cend())
|
||||
{
|
||||
rp->log_rinex_obs(rp->obsFile, beidou_dnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "B1");
|
||||
}
|
||||
if (!b_rinex_header_updated and (d_pvt_solver->beidou_dnav_utc_model.d_A0_UTC != 0))
|
||||
{
|
||||
rp->update_obs_header(rp->obsFile, d_pvt_solver->beidou_dnav_utc_model);
|
||||
rp->update_nav_header(rp->navFile, d_pvt_solver->beidou_dnav_utc_model, d_pvt_solver->beidou_dnav_iono);
|
||||
b_rinex_header_updated = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1922,7 +2092,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
std::string system(&gnss_observables_iter->second.System, 1);
|
||||
if (gps_channel == 0)
|
||||
{
|
||||
if (system == "G")
|
||||
if (system.compare("G") == 0)
|
||||
{
|
||||
// This is a channel with valid GPS signal
|
||||
gps_eph_iter = d_pvt_solver->gps_ephemeris_map.find(gnss_observables_iter->second.PRN);
|
||||
@ -1934,7 +2104,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
}
|
||||
if (gal_channel == 0)
|
||||
{
|
||||
if (system == "E")
|
||||
if (system.compare("E") == 0)
|
||||
{
|
||||
gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN);
|
||||
if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend())
|
||||
|
@ -161,6 +161,10 @@ public:
|
||||
|
||||
std::map<int, Galileo_Almanac> get_galileo_almanac_map() const;
|
||||
|
||||
std::map<int, Beidou_Dnav_Ephemeris> get_beidou_dnav_ephemeris_map() const;
|
||||
|
||||
std::map<int, Beidou_Dnav_Almanac> get_beidou_dnav_almanac_map() const;
|
||||
|
||||
/*!
|
||||
* \brief Clear all ephemeris information and the almanacs for GPS and Galileo
|
||||
*
|
||||
|
@ -89,6 +89,7 @@ Rinex_Printer::Rinex_Printer(int32_t conf_version, const std::string& base_path)
|
||||
navGalfilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_GAL_NAV");
|
||||
navMixfilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_MIXED_NAV");
|
||||
navGlofilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_GLO_NAV");
|
||||
navBdsfilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_BDS_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);
|
||||
@ -96,6 +97,8 @@ Rinex_Printer::Rinex_Printer(int32_t conf_version, const std::string& base_path)
|
||||
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_Printer::navBdsFile.open(navBdsfilename, std::ios::out | std::ios::in | std::ios::app);
|
||||
|
||||
|
||||
if (!Rinex_Printer::navFile.is_open() or !Rinex_Printer::obsFile.is_open() or
|
||||
!Rinex_Printer::sbsFile.is_open() or !Rinex_Printer::navGalFile.is_open() or
|
||||
@ -167,6 +170,8 @@ Rinex_Printer::Rinex_Printer(int32_t conf_version, const std::string& base_path)
|
||||
observationCode["COMPASS_E6_I"] = "6I";
|
||||
observationCode["COMPASS_E6_Q"] = "6Q";
|
||||
observationCode["COMPASS_E6_IQ"] = "6X";
|
||||
observationCode["BEIDOU_B1_I"] = "1I";
|
||||
observationCode["BEIDOU_B1_Q"] = "1Q";
|
||||
|
||||
observationType["PSEUDORANGE"] = "C";
|
||||
observationType["CARRIER_PHASE"] = "L";
|
||||
@ -201,19 +206,21 @@ Rinex_Printer::Rinex_Printer(int32_t conf_version, const std::string& base_path)
|
||||
Rinex_Printer::~Rinex_Printer()
|
||||
{
|
||||
// close RINEX files
|
||||
int64_t posn, poso, poss, posng, posmn, posnr;
|
||||
int64_t posn, poso, poss, posng, posmn, posnr, posnc;
|
||||
posn = navFile.tellp();
|
||||
poso = obsFile.tellp();
|
||||
poss = sbsFile.tellp();
|
||||
posng = navGalFile.tellp();
|
||||
posmn = navMixFile.tellp();
|
||||
posnr = navGloFile.tellp();
|
||||
posnc = navBdsFile.tellp();
|
||||
|
||||
Rinex_Printer::navFile.close();
|
||||
Rinex_Printer::obsFile.close();
|
||||
Rinex_Printer::sbsFile.close();
|
||||
Rinex_Printer::navGalFile.close();
|
||||
Rinex_Printer::navGloFile.close();
|
||||
Rinex_Printer::navBdsFile.close();
|
||||
// If nothing written, erase the files.
|
||||
if (posn == 0)
|
||||
{
|
||||
@ -239,6 +246,10 @@ Rinex_Printer::~Rinex_Printer()
|
||||
{
|
||||
if (remove(navGlofilename.c_str()) != 0) LOG(INFO) << "Error deleting temporary file";
|
||||
}
|
||||
if (posnc == 0)
|
||||
{
|
||||
if (remove(navBdsfilename.c_str()) != 0) LOG(INFO) << "Error deleting temporary file";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -276,6 +287,8 @@ std::string Rinex_Printer::createFilename(const std::string& type)
|
||||
fileType.insert(std::pair<std::string, std::string>("RINEX_FILE_TYPE_SBAS", "B")); // B - SBAS broadcast data file.
|
||||
fileType.insert(std::pair<std::string, std::string>("RINEX_FILE_TYPE_CLK", "C")); // C - Clock file.
|
||||
fileType.insert(std::pair<std::string, std::string>("RINEX_FILE_TYPE_SUMMARY", "S")); // S - Summary file (used e.g., by IGS, not a standard!).
|
||||
fileType.insert(std::pair<std::string, std::string>("RINEX_FILE_TYPE_BDS_NAV", "F")); // G - GLONASS navigation file.
|
||||
|
||||
|
||||
boost::posix_time::ptime pt = boost::posix_time::second_clock::local_time();
|
||||
tm pt_tm = boost::posix_time::to_tm(pt);
|
||||
@ -1542,6 +1555,120 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono
|
||||
}
|
||||
|
||||
|
||||
void Rinex_Printer::rinex_nav_header(std::fstream& out, const Beidou_Dnav_Iono& iono, const Beidou_Dnav_Utc_Model& utc_model)
|
||||
{
|
||||
std::string line;
|
||||
|
||||
// -------- Line 1
|
||||
line = std::string(5, ' ');
|
||||
line += stringVersion;
|
||||
line += std::string(11, ' ');
|
||||
|
||||
if (version == 3)
|
||||
{
|
||||
line += std::string("N: GNSS NAV DATA");
|
||||
line += std::string(4, ' ');
|
||||
//! \todo Add here other systems...
|
||||
line += std::string("F: BDS");
|
||||
line += std::string(14, ' ');
|
||||
// ...
|
||||
}
|
||||
|
||||
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 3
|
||||
line.clear();
|
||||
line += Rinex_Printer::leftJustify("BDS 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 https://gnss-sdr.org", 60);
|
||||
line += Rinex_Printer::leftJustify("COMMENT", 20);
|
||||
Rinex_Printer::lengthCheck(line);
|
||||
out << line << std::endl;
|
||||
|
||||
// -------- Line ionospheric info 1, only version 3 supported
|
||||
line.clear();
|
||||
line += std::string("BDSA");
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha0, 10, 2), 12);
|
||||
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha1, 10, 2), 12);
|
||||
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha2, 10, 2), 12);
|
||||
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(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 ionospheric info 2
|
||||
line.clear();
|
||||
line += std::string("BDSB");
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta0, 10, 2), 12);
|
||||
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta1, 10, 2), 12);
|
||||
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta2, 10, 2), 12);
|
||||
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta3, 10, 2), 12);
|
||||
line += std::string(7, ' ');
|
||||
line += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20);
|
||||
|
||||
Rinex_Printer::lengthCheck(line);
|
||||
out << line << std::endl;
|
||||
|
||||
// -------- Line 5 system time correction
|
||||
line.clear();
|
||||
line += std::string("BDUT");
|
||||
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A0_UTC, 16, 2), 18);
|
||||
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A1_UTC, 15, 2), 16);
|
||||
line += std::string(22, ' ');
|
||||
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<std::string>(utc_model.d_DeltaT_LS), 6);
|
||||
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.d_DeltaT_LSF), 6);
|
||||
line += Rinex_Printer::rightJustify(std::to_string(utc_model.i_WN_LSF), 6);
|
||||
line += Rinex_Printer::rightJustify(std::to_string(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_sbs_header(std::fstream& out)
|
||||
{
|
||||
std::string line;
|
||||
@ -2643,6 +2770,98 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& gal
|
||||
}
|
||||
|
||||
|
||||
void Rinex_Printer::update_nav_header(std::fstream& out, const Beidou_Dnav_Utc_Model& utc_model, const Beidou_Dnav_Iono& iono)
|
||||
{
|
||||
std::vector<std::string> data;
|
||||
std::string line_aux;
|
||||
|
||||
int64_t 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("BDSA", 0) != std::string::npos)
|
||||
{
|
||||
line_aux += std::string("GPSA");
|
||||
line_aux += std::string(1, ' ');
|
||||
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha0, 10, 2), 12);
|
||||
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha1, 10, 2), 12);
|
||||
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha2, 10, 2), 12);
|
||||
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(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("BDSB", 0) != std::string::npos)
|
||||
{
|
||||
line_aux += std::string("GPSB");
|
||||
line_aux += std::string(1, ' ');
|
||||
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta0, 10, 2), 12);
|
||||
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta1, 10, 2), 12);
|
||||
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta2, 10, 2), 12);
|
||||
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta3, 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("BDUT", 0) != std::string::npos)
|
||||
{
|
||||
line_aux += std::string("GPUT");
|
||||
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A0_UTC, 16, 2), 18);
|
||||
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A1_UTC, 15, 2), 16);
|
||||
line_aux += std::string(22, ' ');
|
||||
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<std::string>(utc_model.d_DeltaT_LS), 6);
|
||||
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.d_DeltaT_LSF), 6);
|
||||
line_aux += Rinex_Printer::rightJustify(std::to_string(utc_model.i_WN_LSF), 6);
|
||||
line_aux += Rinex_Printer::rightJustify(std::to_string(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(navfilename, std::ios::out | std::ios::trunc);
|
||||
out.seekp(0);
|
||||
for (int32_t i = 0; i < static_cast<int32_t>(data.size()) - 1; i++)
|
||||
{
|
||||
out << data[i] << std::endl;
|
||||
}
|
||||
out.close();
|
||||
out.open(navfilename, 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<int32_t, Gps_Ephemeris>& eph_map)
|
||||
{
|
||||
std::string line;
|
||||
@ -3529,6 +3748,146 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map<int32_t, Gal
|
||||
}
|
||||
|
||||
|
||||
void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map<int32_t, Beidou_Dnav_Ephemeris>& eph_map)
|
||||
{
|
||||
std::string line;
|
||||
std::map<int32_t, Beidou_Dnav_Ephemeris>::const_iterator bds_ephemeris_iter;
|
||||
|
||||
for (bds_ephemeris_iter = eph_map.cbegin();
|
||||
bds_ephemeris_iter != eph_map.cend();
|
||||
bds_ephemeris_iter++)
|
||||
{
|
||||
// -------- SV / EPOCH / SV CLK
|
||||
boost::posix_time::ptime p_utc_time = Rinex_Printer::compute_BDS_time(bds_ephemeris_iter->second, bds_ephemeris_iter->second.d_Toc);
|
||||
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);
|
||||
|
||||
line += satelliteSystem["Beidou"];
|
||||
if (bds_ephemeris_iter->second.i_satellite_PRN < 10) line += std::string("0");
|
||||
line += std::to_string(bds_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(bds_ephemeris_iter->second.d_A_f0, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_A_f1, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_A_f2, 18, 2);
|
||||
Rinex_Printer::lengthCheck(line);
|
||||
out << line << std::endl;
|
||||
|
||||
// -------- BROADCAST ORBIT - 1
|
||||
line.clear();
|
||||
line += std::string(5, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_AODE, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_Crs, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_Delta_n, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_M_0, 18, 2);
|
||||
Rinex_Printer::lengthCheck(line);
|
||||
out << line << std::endl;
|
||||
|
||||
// -------- BROADCAST ORBIT - 2
|
||||
line.clear();
|
||||
line += std::string(5, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_Cuc, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_eccentricity, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_Cus, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_sqrt_A, 18, 2);
|
||||
Rinex_Printer::lengthCheck(line);
|
||||
out << line << std::endl;
|
||||
|
||||
// -------- BROADCAST ORBIT - 3
|
||||
line.clear();
|
||||
line += std::string(5, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_Toe, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_Cic, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_OMEGA0, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_Cis, 18, 2);
|
||||
Rinex_Printer::lengthCheck(line);
|
||||
out << line << std::endl;
|
||||
|
||||
// -------- BROADCAST ORBIT - 4
|
||||
line.clear();
|
||||
line += std::string(5, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_i_0, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_Crc, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_OMEGA, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_OMEGA_DOT, 18, 2);
|
||||
Rinex_Printer::lengthCheck(line);
|
||||
out << line << std::endl;
|
||||
|
||||
// -------- BROADCAST ORBIT - 5
|
||||
line.clear();
|
||||
line += std::string(5, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_IDOT, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += std::string(18, ' '); // spare
|
||||
line += std::string(1, ' ');
|
||||
auto BDS_week_continuous_number = static_cast<double>(bds_ephemeris_iter->second.i_BEIDOU_week);
|
||||
line += Rinex_Printer::doub2for(BDS_week_continuous_number, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += std::string(18, ' '); // spare
|
||||
Rinex_Printer::lengthCheck(line);
|
||||
out << line << std::endl;
|
||||
|
||||
|
||||
// -------- BROADCAST ORBIT - 6
|
||||
line.clear();
|
||||
line += std::string(5, ' ');
|
||||
line += Rinex_Printer::doub2for(static_cast<double>(bds_ephemeris_iter->second.i_SV_accuracy), 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(static_cast<double>(bds_ephemeris_iter->second.i_SV_health), 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_TGD1, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_TGD2, 18, 2);
|
||||
Rinex_Printer::lengthCheck(line);
|
||||
out << line << std::endl;
|
||||
|
||||
// -------- BROADCAST ORBIT - 7
|
||||
line.clear();
|
||||
line += std::string(5, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_TOW, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_AODC, 18, 2);
|
||||
line += std::string(1, ' ');
|
||||
line += std::string(18, ' '); // spare
|
||||
line += std::string(1, ' ');
|
||||
line += std::string(18, ' '); // spare
|
||||
Rinex_Printer::lengthCheck(line);
|
||||
out << line << std::endl;
|
||||
line.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
@ -6841,6 +7200,235 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps
|
||||
}
|
||||
|
||||
|
||||
void Rinex_Printer::rinex_obs_header(std::fstream& out, const Beidou_Dnav_Ephemeris& eph, const double d_TOW_first_observation, const std::string& bands)
|
||||
{
|
||||
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["Beidou"];
|
||||
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 C = BEIDOU 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("BEIDOU 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 https://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 OBSERVER / AGENCY
|
||||
line.clear();
|
||||
std::string username;
|
||||
char c_username[20] = {0};
|
||||
int32_t 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
|
||||
uint32_t number_of_observations = 0;
|
||||
std::string signal_("B1");
|
||||
std::size_t found_B1 = bands.find(signal_);
|
||||
if (found_B1 != std::string::npos)
|
||||
{
|
||||
number_of_observations = number_of_observations + 4;
|
||||
}
|
||||
signal_ = "B3";
|
||||
std::size_t found_B3 = bands.find(signal_);
|
||||
if (found_B3 != std::string::npos)
|
||||
{
|
||||
number_of_observations = number_of_observations + 4;
|
||||
}
|
||||
|
||||
line.clear();
|
||||
|
||||
line += satelliteSystem["Beidou"];
|
||||
line += std::string(2, ' ');
|
||||
line += Rinex_Printer::rightJustify(std::to_string(number_of_observations), 3);
|
||||
|
||||
if (found_B1 != std::string::npos)
|
||||
{
|
||||
line += std::string(1, ' ');
|
||||
line += observationType["PSEUDORANGE"];
|
||||
line += observationCode["BEIDOU_B1_I"];
|
||||
line += std::string(1, ' ');
|
||||
line += observationType["CARRIER_PHASE"];
|
||||
line += observationCode["BEIDOU_B1_I"];
|
||||
line += std::string(1, ' ');
|
||||
line += observationType["DOPPLER"];
|
||||
line += observationCode["BEIDOU_B1_I"];
|
||||
line += std::string(1, ' ');
|
||||
line += observationType["SIGNAL_STRENGTH"];
|
||||
line += observationCode["BEIDOU_B1_I"];
|
||||
}
|
||||
|
||||
if (found_B3 != std::string::npos)
|
||||
{
|
||||
line += std::string(1, ' ');
|
||||
line += observationType["PSEUDORANGE"];
|
||||
line += observationCode["BEIDOU_B3_I"];
|
||||
line += std::string(1, ' ');
|
||||
line += observationType["CARRIER_PHASE"];
|
||||
line += observationCode["BEIDOU_B3_I"];
|
||||
line += std::string(1, ' ');
|
||||
line += observationType["DOPPLER"];
|
||||
line += observationCode["BEIDOU_B3_I"];
|
||||
line += std::string(1, ' ');
|
||||
line += observationType["SIGNAL_STRENGTH"];
|
||||
line += observationCode["BEIDOU_B3_I"];
|
||||
}
|
||||
|
||||
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_bds_time = Rinex_Printer::compute_BDS_time(eph, d_TOW_first_observation);
|
||||
std::string timestring = boost::posix_time::to_iso_string(p_bds_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 beidou_t = d_TOW_first_observation;
|
||||
double seconds = fmod(beidou_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("BDT"), 8);
|
||||
line += std::string(9, ' ');
|
||||
line += Rinex_Printer::leftJustify("TIME OF FIRST OBS", 20);
|
||||
Rinex_Printer::lengthCheck(line);
|
||||
out << line << std::endl;
|
||||
|
||||
// -------- SYS /PHASE SHIFTS
|
||||
|
||||
// -------- 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::update_obs_header(std::fstream& out __attribute__((unused)), const Glonass_Gnav_Utc_Model& utc_model)
|
||||
{
|
||||
if (utc_model.d_N_4)
|
||||
@ -7050,6 +7638,65 @@ void Rinex_Printer::update_obs_header(std::fstream& out, const Galileo_Utc_Model
|
||||
}
|
||||
|
||||
|
||||
void Rinex_Printer::update_obs_header(std::fstream& out, const Beidou_Dnav_Utc_Model& utc_model)
|
||||
{
|
||||
std::vector<std::string> data;
|
||||
std::string line_aux;
|
||||
|
||||
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("TIME OF FIRST OBS", 59) != std::string::npos)
|
||||
{
|
||||
data.push_back(line_str);
|
||||
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.d_DeltaT_LS), 6);
|
||||
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.d_DeltaT_LSF), 6);
|
||||
line_aux += Rinex_Printer::rightJustify(std::to_string(utc_model.i_WN_LSF), 6);
|
||||
line_aux += Rinex_Printer::rightJustify(std::to_string(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(obsfilename, std::ios::out | std::ios::trunc);
|
||||
out.seekp(0);
|
||||
for (int32_t i = 0; i < static_cast<int32_t>(data.size()) - 1; i++)
|
||||
{
|
||||
out << data[i] << std::endl;
|
||||
}
|
||||
out.close();
|
||||
out.open(obsfilename, std::ios::out | std::ios::in | std::ios::app);
|
||||
out.seekp(0, std::ios_base::end);
|
||||
}
|
||||
|
||||
|
||||
void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeris& eph, const double obs_time, const std::map<int32_t, Gnss_Synchro>& observables, const std::string& glonass_band)
|
||||
{
|
||||
// RINEX observations timestamps are GPS timestamps.
|
||||
@ -9760,6 +10407,176 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep
|
||||
}
|
||||
|
||||
|
||||
void Rinex_Printer::log_rinex_obs(std::fstream& out, const Beidou_Dnav_Ephemeris& eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables, const std::string& bds_bands)
|
||||
{
|
||||
std::string line;
|
||||
|
||||
boost::posix_time::ptime p_bds_time = Rinex_Printer::compute_BDS_time(eph, obs_time);
|
||||
std::string timestring = boost::posix_time::to_iso_string(p_bds_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 bds_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);
|
||||
|
||||
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(bds_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 BeiDou observations
|
||||
std::map<int32_t, Gnss_Synchro> observablesB1I;
|
||||
std::map<int32_t, Gnss_Synchro> observablesB3I;
|
||||
|
||||
std::map<int32_t, Gnss_Synchro>::const_iterator observables_iter;
|
||||
|
||||
for (observables_iter = observables.cbegin();
|
||||
observables_iter != observables.cend();
|
||||
observables_iter++)
|
||||
{
|
||||
std::string system_(&observables_iter->second.System, 1);
|
||||
std::string sig_(observables_iter->second.Signal);
|
||||
if ((system_ == "C") && (sig_ == "B1"))
|
||||
{
|
||||
observablesB1I.insert(std::pair<int32_t, Gnss_Synchro>(observables_iter->first, observables_iter->second));
|
||||
}
|
||||
if ((system_ == "C") && (sig_ == "B3"))
|
||||
{
|
||||
observablesB3I.insert(std::pair<int32_t, Gnss_Synchro>(observables_iter->first, observables_iter->second));
|
||||
}
|
||||
}
|
||||
std::size_t found_B1 = bds_bands.find("B1");
|
||||
std::size_t found_B3 = bds_bands.find("B3");
|
||||
|
||||
std::multimap<uint32_t, Gnss_Synchro> total_map;
|
||||
std::set<uint32_t> available_prns;
|
||||
std::set<uint32_t>::iterator it;
|
||||
if (found_B1 != std::string::npos)
|
||||
{
|
||||
for (observables_iter = observablesB1I.cbegin();
|
||||
observables_iter != observablesB1I.cend();
|
||||
observables_iter++)
|
||||
{
|
||||
uint32_t prn_ = observables_iter->second.PRN;
|
||||
total_map.insert(std::pair<uint32_t, Gnss_Synchro>(prn_, observables_iter->second));
|
||||
it = available_prns.find(prn_);
|
||||
if (it == available_prns.end())
|
||||
{
|
||||
available_prns.insert(prn_);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found_B3 != std::string::npos)
|
||||
{
|
||||
for (observables_iter = observablesB3I.cbegin();
|
||||
observables_iter != observablesB3I.cend();
|
||||
observables_iter++)
|
||||
{
|
||||
uint32_t prn_ = observables_iter->second.PRN;
|
||||
it = available_prns.find(prn_);
|
||||
if (it == available_prns.end())
|
||||
{
|
||||
available_prns.insert(prn_);
|
||||
if (found_B1 != std::string::npos)
|
||||
{
|
||||
Gnss_Synchro gs = Gnss_Synchro();
|
||||
std::string sys = "C";
|
||||
gs.System = *sys.c_str();
|
||||
std::string sig = "B1";
|
||||
std::memcpy(static_cast<void*>(gs.Signal), sig.c_str(), 3);
|
||||
gs.PRN = prn_;
|
||||
total_map.insert(std::pair<uint32_t, Gnss_Synchro>(prn_, gs));
|
||||
}
|
||||
}
|
||||
total_map.insert(std::pair<uint32_t, Gnss_Synchro>(prn_, observables_iter->second));
|
||||
}
|
||||
}
|
||||
|
||||
int32_t numSatellitesObserved = available_prns.size();
|
||||
line += Rinex_Printer::rightJustify(std::to_string(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 lineObs;
|
||||
std::pair<std::multimap<uint32_t, Gnss_Synchro>::iterator, std::multimap<uint32_t, Gnss_Synchro>::iterator> ret;
|
||||
for (it = available_prns.begin();
|
||||
it != available_prns.end();
|
||||
it++)
|
||||
{
|
||||
lineObs.clear();
|
||||
lineObs += satelliteSystem["Beidou"];
|
||||
if (static_cast<int32_t>(*it) < 10) lineObs += std::string(1, '0');
|
||||
lineObs += std::to_string(static_cast<int32_t>(*it));
|
||||
ret = total_map.equal_range(*it);
|
||||
for (auto iter = ret.first; iter != ret.second; ++iter)
|
||||
{
|
||||
lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14);
|
||||
|
||||
//Loss of lock indicator (LLI)
|
||||
int32_t lli = 0; // Include in the observation!!
|
||||
if (lli == 0)
|
||||
{
|
||||
lineObs += std::string(1, ' ');
|
||||
}
|
||||
|
||||
// Signal Strength Indicator (SSI)
|
||||
int32_t ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz);
|
||||
lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString<int32_t>(ssi), 1);
|
||||
|
||||
// CARRIER PHASE
|
||||
lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (BEIDOU_TWO_PI), 3), 14);
|
||||
if (lli == 0)
|
||||
{
|
||||
lineObs += std::string(1, ' ');
|
||||
}
|
||||
lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString<int32_t>(ssi), 1);
|
||||
|
||||
// DOPPLER
|
||||
lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14);
|
||||
if (lli == 0)
|
||||
{
|
||||
lineObs += std::string(1, ' ');
|
||||
}
|
||||
lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString<int32_t>(ssi), 1);
|
||||
|
||||
// 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::to_date_time(int32_t gps_week, int32_t 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.
|
||||
@ -9932,6 +10749,19 @@ boost::posix_time::ptime Rinex_Printer::compute_UTC_time(const Gps_Navigation_Me
|
||||
}
|
||||
|
||||
|
||||
boost::posix_time::ptime Rinex_Printer::compute_BDS_time(const Beidou_Dnav_Ephemeris& eph, const double obs_time)
|
||||
{
|
||||
// The RINEX v2.11 v3.00 format uses GPS time for the observations epoch, not UTC time, thus, no leap seconds needed here.
|
||||
// (see Section 3 in http://igscb.jpl.nasa.gov/igscb/data/format/rinex211.txt)
|
||||
// (see Pag. 17 in http://igscb.jpl.nasa.gov/igscb/data/format/rinex300.pdf)
|
||||
// --??? No time correction here, since it will be done in the RINEX processor
|
||||
const double bds_t = obs_time;
|
||||
boost::posix_time::time_duration t = boost::posix_time::milliseconds(static_cast<int64_t>((bds_t + 604800 * static_cast<double>(eph.i_BEIDOU_week % 8192)) * 1000));
|
||||
boost::posix_time::ptime p_time(boost::gregorian::date(2006, 1, 1), t);
|
||||
return p_time;
|
||||
}
|
||||
|
||||
|
||||
boost::posix_time::ptime Rinex_Printer::compute_GPS_time(const Gps_Ephemeris& eph, const double obs_time)
|
||||
{
|
||||
// The RINEX v2.11 v3.00 format uses GPS time for the observations epoch, not UTC time, thus, no leap seconds needed here.
|
||||
|
@ -51,9 +51,11 @@
|
||||
#ifndef GNSS_SDR_RINEX_PRINTER_H_
|
||||
#define GNSS_SDR_RINEX_PRINTER_H_
|
||||
|
||||
#include "Beidou_B1I.h"
|
||||
#include "GLONASS_L1_L2_CA.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "Galileo_E1.h"
|
||||
#include "beidou_dnav_navigation_message.h"
|
||||
#include "galileo_navigation_message.h"
|
||||
#include "glonass_gnav_navigation_message.h"
|
||||
#include "gnss_synchro.h"
|
||||
@ -91,6 +93,7 @@ public:
|
||||
std::fstream sbsFile; //<! Output file stream for RINEX SBAS raw data file
|
||||
std::fstream navGalFile; //<! Output file stream for RINEX Galileo navigation data file
|
||||
std::fstream navGloFile; //<! Output file stream for RINEX GLONASS navigation data file
|
||||
std::fstream navBdsFile; //<! Output file stream for RINEX Galileo navigation data file
|
||||
std::fstream navMixFile; //<! Output file stream for RINEX Mixed navigation data file
|
||||
|
||||
/*!
|
||||
@ -138,6 +141,8 @@ public:
|
||||
*/
|
||||
void 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);
|
||||
|
||||
void rinex_nav_header(std::fstream& out, const Beidou_Dnav_Iono& iono, const Beidou_Dnav_Utc_Model& utc_model);
|
||||
|
||||
/*!
|
||||
* \brief Generates the GPS Observation data header
|
||||
*/
|
||||
@ -193,11 +198,25 @@ public:
|
||||
*/
|
||||
void rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris& gps_cnav_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double d_TOW_first_observation, const std::string& glo_bands = "1G");
|
||||
|
||||
/*!
|
||||
* \brief Generates the a Beidou B1I Observation data header. Example: beidou_bands("B1")
|
||||
*/
|
||||
void rinex_obs_header(std::fstream& out, const Beidou_Dnav_Ephemeris& eph, const double d_TOW_first_observation, const std::string& bands);
|
||||
|
||||
/*!
|
||||
* \brief Generates the SBAS raw data header
|
||||
*/
|
||||
void rinex_sbs_header(std::fstream& out);
|
||||
|
||||
/*!
|
||||
* \brief Computes the BDS Time and returns a boost::posix_time::ptime object
|
||||
* \details Function used to convert the observation time into BDT time which is used
|
||||
* as the default time for RINEX files
|
||||
* \param eph BeiDou DNAV Ephemeris object
|
||||
* \param obs_time Observation time in BDT seconds of week
|
||||
*/
|
||||
boost::posix_time::ptime compute_BDS_time(const Beidou_Dnav_Ephemeris& eph, const double obs_time);
|
||||
|
||||
/*!
|
||||
* \brief Computes the UTC time and returns a boost::posix_time::ptime object
|
||||
*/
|
||||
@ -279,6 +298,11 @@ public:
|
||||
*/
|
||||
void log_rinex_nav(std::fstream& out, const std::map<int32_t, Galileo_Ephemeris>& galileo_eph_map, const std::map<int32_t, Glonass_Gnav_Ephemeris>& glonass_gnav_eph_map);
|
||||
|
||||
/*!
|
||||
* \brief Writes data from the Beidou B1I navigation message into the RINEX file
|
||||
*/
|
||||
void log_rinex_nav(std::fstream& out, const std::map<int32_t, Beidou_Dnav_Ephemeris>& eph_map);
|
||||
|
||||
/*!
|
||||
* \brief Writes GPS L1 observables into the RINEX file
|
||||
*/
|
||||
@ -334,6 +358,12 @@ public:
|
||||
*/
|
||||
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<int32_t, Gnss_Synchro>& observables);
|
||||
|
||||
/*!
|
||||
* \brief Writes BDS B1I observables into the RINEX file
|
||||
*/
|
||||
void log_rinex_obs(std::fstream& out, const Beidou_Dnav_Ephemeris& eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables, const std::string& bds_bands);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Represents GPS time in the date time format. Leap years are considered, but leap seconds are not.
|
||||
*/
|
||||
@ -362,6 +392,8 @@ public:
|
||||
|
||||
void update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac);
|
||||
|
||||
void update_nav_header(std::fstream& out, const Beidou_Dnav_Utc_Model& beidou_dnav_utc, const Beidou_Dnav_Iono& beidou_dnav_iono);
|
||||
|
||||
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);
|
||||
@ -370,7 +402,9 @@ public:
|
||||
|
||||
void update_obs_header(std::fstream& out, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model);
|
||||
|
||||
std::map<std::string, std::string> satelliteSystem; //<! GPS, GLONASS, SBAS payload, Galileo or Compass
|
||||
void update_obs_header(std::fstream& out, const Beidou_Dnav_Utc_Model& utc_model);
|
||||
|
||||
std::map<std::string, std::string> satelliteSystem; //<! GPS, GLONASS, SBAS payload, Galileo or Beidou
|
||||
std::map<std::string, std::string> observationType; //<! PSEUDORANGE, CARRIER_PHASE, DOPPLER, SIGNAL_STRENGTH
|
||||
std::map<std::string, std::string> observationCode; //<! GNSS observation descriptors
|
||||
std::string stringVersion; //<! RINEX version (2.10/2.11 or 3.01/3.02)
|
||||
@ -380,6 +414,7 @@ public:
|
||||
std::string sbsfilename;
|
||||
std::string navGalfilename;
|
||||
std::string navGlofilename;
|
||||
std::string navBdsfilename;
|
||||
std::string navMixfilename;
|
||||
|
||||
private:
|
||||
|
@ -52,6 +52,7 @@
|
||||
* -----------------------------------------------------------------------*/
|
||||
|
||||
#include "rtklib_solver.h"
|
||||
#include "Beidou_B1I.h"
|
||||
#include "GLONASS_L1_L2_CA.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "Galileo_E1.h"
|
||||
@ -447,6 +448,8 @@ bool rtklib_solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
std::map<int, Gps_Ephemeris>::const_iterator gps_ephemeris_iter;
|
||||
std::map<int, Gps_CNAV_Ephemeris>::const_iterator gps_cnav_ephemeris_iter;
|
||||
std::map<int, Glonass_Gnav_Ephemeris>::const_iterator glonass_gnav_ephemeris_iter;
|
||||
std::map<int, Beidou_Dnav_Ephemeris>::const_iterator beidou_ephemeris_iter;
|
||||
|
||||
const Glonass_Gnav_Utc_Model gnav_utc = this->glonass_gnav_utc_model;
|
||||
|
||||
this->set_averaging_flag(flag_averaging);
|
||||
@ -756,6 +759,34 @@ bool rtklib_solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'C':
|
||||
{
|
||||
// BEIDOU B1I
|
||||
// - find the ephemeris for the current BEIDOU SV observation. The SV PRN ID is the map key
|
||||
std::string sig_(gnss_observables_iter->second.Signal);
|
||||
if (sig_ == "B1")
|
||||
{
|
||||
beidou_ephemeris_iter = beidou_dnav_ephemeris_map.find(gnss_observables_iter->second.PRN);
|
||||
if (beidou_ephemeris_iter != beidou_dnav_ephemeris_map.cend())
|
||||
{
|
||||
// convert ephemeris from GNSS-SDR class to RTKLIB structure
|
||||
eph_data[valid_obs] = eph_to_rtklib(beidou_ephemeris_iter->second);
|
||||
// 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,
|
||||
beidou_ephemeris_iter->second.i_BEIDOU_week + 1356,
|
||||
0);
|
||||
valid_obs++;
|
||||
}
|
||||
else // the ephemeris are not available for this SV
|
||||
{
|
||||
DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->first;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
DLOG(INFO) << "Hybrid observables: Unknown GNSS";
|
||||
break;
|
||||
|
@ -55,6 +55,7 @@
|
||||
#define GNSS_SDR_RTKLIB_SOLVER_H_
|
||||
|
||||
|
||||
#include "beidou_dnav_navigation_message.h"
|
||||
#include "galileo_almanac.h"
|
||||
#include "galileo_navigation_message.h"
|
||||
#include "glonass_gnav_navigation_message.h"
|
||||
@ -101,6 +102,7 @@ public:
|
||||
std::map<int, Gps_Ephemeris> gps_ephemeris_map; //!< Map storing new GPS_Ephemeris
|
||||
std::map<int, Gps_CNAV_Ephemeris> gps_cnav_ephemeris_map; //!< Map storing new GPS_CNAV_Ephemeris
|
||||
std::map<int, Glonass_Gnav_Ephemeris> glonass_gnav_ephemeris_map; //!< Map storing new GLONASS GNAV Ephemeris
|
||||
std::map<int, Beidou_Dnav_Ephemeris> beidou_dnav_ephemeris_map; //!< Map storing new GLONASS GNAV Ephmeris
|
||||
|
||||
Galileo_Utc_Model galileo_utc_model;
|
||||
Galileo_Iono galileo_iono;
|
||||
@ -116,6 +118,10 @@ public:
|
||||
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
|
||||
|
||||
Beidou_Dnav_Utc_Model beidou_dnav_utc_model;
|
||||
Beidou_Dnav_Iono beidou_dnav_iono;
|
||||
std::map<int, Beidou_Dnav_Almanac> beidou_dnav_almanac_map;
|
||||
|
||||
int count_valid_position;
|
||||
};
|
||||
|
||||
|
@ -34,6 +34,7 @@ set(ACQ_ADAPTER_SOURCES
|
||||
galileo_e5a_pcps_acquisition.cc
|
||||
glonass_l1_ca_pcps_acquisition.cc
|
||||
glonass_l2_ca_pcps_acquisition.cc
|
||||
beidou_b1i_pcps_acquisition.cc
|
||||
)
|
||||
|
||||
set(ACQ_ADAPTER_HEADERS
|
||||
|
@ -0,0 +1,342 @@
|
||||
/*!
|
||||
* \file beidou_b1i_pcps_acquisition.cc
|
||||
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||
* BeiDou B1I signals
|
||||
* \authors <ul>
|
||||
* <li> Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
|
||||
* </ul>
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "beidou_b1i_pcps_acquisition.h"
|
||||
#include "Beidou_B1I.h"
|
||||
#include "acq_conf.h"
|
||||
#include "beidou_b1i_signal_processing.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include <boost/math/distributions/exponential.hpp>
|
||||
#include <glog/logging.h>
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition(
|
||||
ConfigurationInterface* configuration,
|
||||
const std::string& role,
|
||||
unsigned int in_streams,
|
||||
unsigned int out_streams) : role_(role),
|
||||
in_streams_(in_streams),
|
||||
out_streams_(out_streams)
|
||||
{
|
||||
Acq_Conf acq_parameters = Acq_Conf();
|
||||
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);
|
||||
|
||||
int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||
acq_parameters.fs_in = fs_in_;
|
||||
dump_ = configuration_->property(role + ".dump", false);
|
||||
acq_parameters.dump = dump_;
|
||||
blocking_ = configuration_->property(role + ".blocking", true);
|
||||
acq_parameters.blocking = blocking_;
|
||||
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
|
||||
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
|
||||
acq_parameters.doppler_max = doppler_max_;
|
||||
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
|
||||
acq_parameters.sampled_ms = sampled_ms_;
|
||||
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
||||
acq_parameters.bit_transition_flag = bit_transition_flag_;
|
||||
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
|
||||
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
|
||||
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
|
||||
acq_parameters.max_dwells = max_dwells_;
|
||||
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
||||
acq_parameters.dump_filename = dump_filename_;
|
||||
//--- Find number of samples per spreading code -------------------------
|
||||
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (BEIDOU_B1I_CODE_RATE_HZ / BEIDOU_B1I_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_ == "cshort")
|
||||
{
|
||||
item_size_ = sizeof(lv_16sc_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
}
|
||||
acq_parameters.it_size = item_size_;
|
||||
acq_parameters.sampled_ms = sampled_ms_;
|
||||
acq_parameters.samples_per_ms = code_length_;
|
||||
acq_parameters.samples_per_code = code_length_;
|
||||
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
||||
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||
acquisition_ = pcps_make_acquisition(acq_parameters);
|
||||
DLOG(INFO) << "acquisition(" << acquisition_->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_ == "cbyte")
|
||||
{
|
||||
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_ = nullptr;
|
||||
if (in_streams_ > 1)
|
||||
{
|
||||
LOG(ERROR) << "This implementation only supports one input stream";
|
||||
}
|
||||
if (out_streams_ > 0)
|
||||
{
|
||||
LOG(ERROR) << "This implementation does not provide an output stream";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BeidouB1iPcpsAcquisition::~BeidouB1iPcpsAcquisition()
|
||||
{
|
||||
delete[] code_;
|
||||
}
|
||||
|
||||
|
||||
void BeidouB1iPcpsAcquisition::stop_acquisition()
|
||||
{
|
||||
}
|
||||
|
||||
void BeidouB1iPcpsAcquisition::set_channel(unsigned int channel)
|
||||
{
|
||||
channel_ = channel;
|
||||
acquisition_->set_channel(channel_);
|
||||
}
|
||||
|
||||
|
||||
void BeidouB1iPcpsAcquisition::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_;
|
||||
|
||||
acquisition_->set_threshold(threshold_);
|
||||
}
|
||||
|
||||
|
||||
void BeidouB1iPcpsAcquisition::set_doppler_max(unsigned int doppler_max)
|
||||
{
|
||||
doppler_max_ = doppler_max;
|
||||
|
||||
acquisition_->set_doppler_max(doppler_max_);
|
||||
}
|
||||
|
||||
|
||||
void BeidouB1iPcpsAcquisition::set_doppler_step(unsigned int doppler_step)
|
||||
{
|
||||
doppler_step_ = doppler_step;
|
||||
|
||||
acquisition_->set_doppler_step(doppler_step_);
|
||||
}
|
||||
|
||||
|
||||
void BeidouB1iPcpsAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
|
||||
{
|
||||
gnss_synchro_ = gnss_synchro;
|
||||
|
||||
acquisition_->set_gnss_synchro(gnss_synchro_);
|
||||
}
|
||||
|
||||
|
||||
signed int BeidouB1iPcpsAcquisition::mag()
|
||||
{
|
||||
return acquisition_->mag();
|
||||
}
|
||||
|
||||
|
||||
void BeidouB1iPcpsAcquisition::init()
|
||||
{
|
||||
acquisition_->init();
|
||||
set_local_code();
|
||||
}
|
||||
|
||||
|
||||
void BeidouB1iPcpsAcquisition::set_local_code()
|
||||
{
|
||||
auto* code = new std::complex<float>[code_length_];
|
||||
|
||||
beidou_b1i_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_);
|
||||
}
|
||||
|
||||
acquisition_->set_local_code(code_);
|
||||
delete[] code;
|
||||
}
|
||||
|
||||
|
||||
void BeidouB1iPcpsAcquisition::reset()
|
||||
{
|
||||
acquisition_->set_active(true);
|
||||
}
|
||||
|
||||
|
||||
void BeidouB1iPcpsAcquisition::set_state(int state)
|
||||
{
|
||||
acquisition_->set_state(state);
|
||||
}
|
||||
|
||||
|
||||
float BeidouB1iPcpsAcquisition::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<double>(ncells);
|
||||
double val = pow(1.0 - pfa, exponent);
|
||||
auto lambda = static_cast<double>(vector_length_);
|
||||
boost::math::exponential_distribution<double> mydist(lambda);
|
||||
auto threshold = static_cast<float>(quantile(mydist, val));
|
||||
|
||||
return threshold;
|
||||
}
|
||||
|
||||
|
||||
void BeidouB1iPcpsAcquisition::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (item_type_ == "gr_complex")
|
||||
{
|
||||
// nothing to connect
|
||||
}
|
||||
else if (item_type_ == "cshort")
|
||||
{
|
||||
// nothing to connect
|
||||
}
|
||||
else if (item_type_ == "cbyte")
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BeidouB1iPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (item_type_ == "gr_complex")
|
||||
{
|
||||
// nothing to disconnect
|
||||
}
|
||||
else if (item_type_ == "cshort")
|
||||
{
|
||||
// nothing to disconnect
|
||||
}
|
||||
else if (item_type_ == "cbyte")
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr BeidouB1iPcpsAcquisition::get_left_block()
|
||||
{
|
||||
if (item_type_ == "gr_complex")
|
||||
{
|
||||
return acquisition_;
|
||||
}
|
||||
else if (item_type_ == "cshort")
|
||||
{
|
||||
return acquisition_;
|
||||
}
|
||||
else if (item_type_ == "cbyte")
|
||||
{
|
||||
return cbyte_to_float_x2_;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr BeidouB1iPcpsAcquisition::get_right_block()
|
||||
{
|
||||
return acquisition_;
|
||||
}
|
||||
|
||||
void BeidouB1iPcpsAcquisition::set_resampler_latency(uint32_t latency_samples)
|
||||
{
|
||||
acquisition_->set_resampler_latency(latency_samples);
|
||||
}
|
@ -0,0 +1,180 @@
|
||||
/*!
|
||||
* \file beidou_bi1_pcps_acquisition.h
|
||||
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||
* Beidou B1I signals
|
||||
* \authors <ul>
|
||||
* <li> Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
|
||||
* </ul>
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_BEIDOU_B1I_PCPS_ACQUISITION_H_
|
||||
#define GNSS_SDR_BEIDOU_B1I_PCPS_ACQUISITION_H_
|
||||
|
||||
#include "acq_conf.h"
|
||||
#include "acquisition_interface.h"
|
||||
#include "complex_byte_to_float_x2.h"
|
||||
#include "gnss_synchro.h"
|
||||
#include "pcps_acquisition.h"
|
||||
#include <gnuradio/blocks/float_to_complex.h>
|
||||
#include <gnuradio/blocks/stream_to_vector.h>
|
||||
#include <volk_gnsssdr/volk_gnsssdr.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
* \brief This class adapts a PCPS acquisition block to an AcquisitionInterface
|
||||
* for GPS L1 C/A signals
|
||||
*/
|
||||
class BeidouB1iPcpsAcquisition : public AcquisitionInterface
|
||||
{
|
||||
public:
|
||||
BeidouB1iPcpsAcquisition(ConfigurationInterface* configuration,
|
||||
const std::string& role, unsigned int in_streams,
|
||||
unsigned int out_streams);
|
||||
|
||||
virtual ~BeidouB1iPcpsAcquisition();
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "BEIDOU_B1I_PCPS_Acquisition"
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "BEIDOU_B1I_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) override;
|
||||
|
||||
/*!
|
||||
* \brief Stop running acquisition
|
||||
*/
|
||||
void stop_acquisition() override;
|
||||
|
||||
/*!
|
||||
* \brief Sets the resampler latency to account it in the acquisition code delay estimation
|
||||
*/
|
||||
void set_resampler_latency(uint32_t latency_samples) override;
|
||||
|
||||
|
||||
private:
|
||||
ConfigurationInterface* configuration_;
|
||||
pcps_acquisition_sptr acquisition_;
|
||||
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_;
|
||||
bool dump_;
|
||||
bool blocking_;
|
||||
std::string dump_filename_;
|
||||
std::complex<float>* code_;
|
||||
Gnss_Synchro* gnss_synchro_;
|
||||
std::string role_;
|
||||
unsigned int in_streams_;
|
||||
unsigned int out_streams_;
|
||||
|
||||
float calculate_threshold(float pfa);
|
||||
};
|
||||
|
||||
#endif /* GNSS_SDR_BEIDOU_B1I_PCPS_ACQUISITION_H_ */
|
@ -30,6 +30,7 @@ set(GNSS_SPLIBS_SOURCES
|
||||
glonass_l2_signal_processing.cc
|
||||
pass_through.cc
|
||||
galileo_e5_signal_processing.cc
|
||||
beidou_b1i_signal_processing.cc
|
||||
complex_byte_to_float_x2.cc
|
||||
byte_x2_to_complex_byte.cc
|
||||
cshort_to_float_x2.cc
|
||||
@ -54,6 +55,7 @@ set(GNSS_SPLIBS_HEADERS
|
||||
glonass_l2_signal_processing.h
|
||||
pass_through.h
|
||||
galileo_e5_signal_processing.h
|
||||
beidou_b1i_signal_processing.h
|
||||
complex_byte_to_float_x2.h
|
||||
byte_x2_to_complex_byte.h
|
||||
cshort_to_float_x2.h
|
||||
|
189
src/algorithms/libs/beidou_b1i_signal_processing.cc
Normal file
189
src/algorithms/libs/beidou_b1i_signal_processing.cc
Normal file
@ -0,0 +1,189 @@
|
||||
/*!
|
||||
* \file beidou_b1i_signal_processing.cc
|
||||
* \brief This class implements various functions for BeiDou B1I signal
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "beidou_b1i_signal_processing.h"
|
||||
|
||||
auto auxCeil = [](float x) { return static_cast<int>(static_cast<long>((x) + 1)); };
|
||||
|
||||
void beidou_b1i_code_gen_int(int* _dest, signed int _prn, unsigned int _chip_shift)
|
||||
{
|
||||
const unsigned int _code_length = 2046;
|
||||
bool G1[_code_length];
|
||||
bool G2[_code_length];
|
||||
bool G1_register[11] = {false, true, false, true, false, true, false, true, false, true, false};
|
||||
bool G2_register[11] = {false, true, false, true, false, true, false, true, false, true, false};
|
||||
bool feedback1, feedback2;
|
||||
bool aux;
|
||||
unsigned int lcv, lcv2;
|
||||
unsigned int delay;
|
||||
signed int prn_idx;
|
||||
/* G2 Delays as defined in GPS-ISD-200D */
|
||||
const signed int delays[33] = {712 /*PRN1*/, 1581, 1414, 1550, 581, 771, 1311, 1043, 1549, 359, 710, 1579, 1548, 1103, 579, 769, 358, 709, 1411, 1547,
|
||||
1102, 578, 357, 1577, 1410, 1546, 1101, 707, 1576, 1409, 1545, 354 /*PRN32*/,
|
||||
705};
|
||||
const signed int phase1[37] = {1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 8, 8, 8, 9, 9, 10};
|
||||
const signed int phase2[37] = {3, 4, 5, 6, 8, 9, 10, 11, 7, 4, 5, 6, 8, 9, 10, 11, 5, 6, 8, 9, 10, 11, 6, 8, 9, 10, 11, 8, 9, 10, 11, 9, 10, 11, 10, 11, 11};
|
||||
|
||||
// compute delay array index for given PRN number
|
||||
prn_idx = _prn - 1;
|
||||
|
||||
/* A simple error check */
|
||||
if ((prn_idx < 0) || (prn_idx > 51))
|
||||
return;
|
||||
|
||||
/*for (lcv = 0; lcv < 11; lcv++)
|
||||
{
|
||||
G1_register[lcv] = 1;
|
||||
G2_register[lcv] = 1;
|
||||
}*/
|
||||
|
||||
/* Generate G1 & G2 Register */
|
||||
for (lcv = 0; lcv < _code_length; lcv++)
|
||||
{
|
||||
G1[lcv] = G1_register[0];
|
||||
G2[lcv] = G2_register[-(phase1[prn_idx] - 11)] ^ G2_register[-(phase2[prn_idx] - 11)];
|
||||
|
||||
feedback1 = (G1_register[0] + G1_register[1] + G1_register[2] + G1_register[3] + G1_register[4] + G1_register[10]) & 0x1;
|
||||
feedback2 = (G2_register[0] + G2_register[2] + G2_register[3] + G2_register[6] + G2_register[7] + G2_register[8] + G2_register[9] + G2_register[10]) & 0x1;
|
||||
|
||||
for (lcv2 = 0; lcv2 < 10; lcv2++)
|
||||
{
|
||||
G1_register[lcv2] = G1_register[lcv2 + 1];
|
||||
G2_register[lcv2] = G2_register[lcv2 + 1];
|
||||
}
|
||||
|
||||
G1_register[10] = feedback1;
|
||||
G2_register[10] = feedback2;
|
||||
}
|
||||
|
||||
/* Set the delay */
|
||||
delay = _code_length - delays[prn_idx] * 0; //**********************************
|
||||
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] ^ G2[delay];
|
||||
if (aux == true)
|
||||
{
|
||||
_dest[lcv] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_dest[lcv] = -1;
|
||||
}
|
||||
|
||||
delay++;
|
||||
//std::cout << _dest[lcv] << " ";
|
||||
delay %= _code_length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void beidou_b1i_code_gen_float(float* _dest, signed int _prn, unsigned int _chip_shift)
|
||||
{
|
||||
unsigned int _code_length = 2046;
|
||||
int b1i_code_int[_code_length];
|
||||
|
||||
beidou_b1i_code_gen_int(b1i_code_int, _prn, _chip_shift);
|
||||
|
||||
for (unsigned int ii = 0; ii < _code_length; ++ii)
|
||||
{
|
||||
_dest[ii] = static_cast<float>(b1i_code_int[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void beidou_b1i_code_gen_complex(std::complex<float>* _dest, signed int _prn, unsigned int _chip_shift)
|
||||
{
|
||||
unsigned int _code_length = 2046;
|
||||
int b1i_code_int[_code_length];
|
||||
|
||||
beidou_b1i_code_gen_int(b1i_code_int, _prn, _chip_shift);
|
||||
|
||||
for (unsigned int ii = 0; ii < _code_length; ++ii)
|
||||
{
|
||||
_dest[ii] = std::complex<float>(static_cast<float>(b1i_code_int[ii]), 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Generates complex GPS L1 C/A code for the desired SV ID and sampled to specific sampling frequency
|
||||
*/
|
||||
void beidou_b1i_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _prn, int _fs, unsigned int _chip_shift)
|
||||
{
|
||||
// This function is based on the GNU software GPS for MATLAB in the Kay Borre book
|
||||
std::complex<float> _code[2046];
|
||||
signed int _samplesPerCode, _codeValueIndex;
|
||||
float _ts;
|
||||
float _tc;
|
||||
float aux;
|
||||
const signed int _codeFreqBasis = 2046000; //Hz
|
||||
const signed int _codeLength = 2046;
|
||||
|
||||
//--- Find number of samples per spreading code ----------------------------
|
||||
_samplesPerCode = static_cast<signed int>(static_cast<double>(_fs) / static_cast<double>(_codeFreqBasis / _codeLength));
|
||||
|
||||
//--- Find time constants --------------------------------------------------
|
||||
_ts = 1.0 / static_cast<float>(_fs); // Sampling period in sec
|
||||
_tc = 1.0 / static_cast<float>(_codeFreqBasis); // C/A chip period in sec
|
||||
beidou_b1i_code_gen_complex(_code, _prn, _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
|
||||
}
|
||||
}
|
||||
}
|
54
src/algorithms/libs/beidou_b1i_signal_processing.h
Normal file
54
src/algorithms/libs/beidou_b1i_signal_processing.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*!
|
||||
* \file beidou_b1i_signal_processing.h
|
||||
* \brief This class implements various functions for BeiDou B1I signals
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef BEIDOU_B1I_SDR_SIGNAL_PROCESSING_H_
|
||||
#define BEIDOU_B1I_SDR_SIGNAL_PROCESSING_H_
|
||||
|
||||
#include <complex>
|
||||
#include <iostream>
|
||||
|
||||
//!Generates int GPS L1 C/A code for the desired SV ID and code shift
|
||||
void beidou_b1i_code_gen_int(int* _dest, signed int _prn, unsigned int _chip_shift);
|
||||
|
||||
//!Generates float GPS L1 C/A code for the desired SV ID and code shift
|
||||
void beidou_b1i_code_gen_float(float* _dest, signed int _prn, unsigned int _chip_shift);
|
||||
|
||||
//!Generates complex GPS L1 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency
|
||||
void beidou_b1i_code_gen_complex(std::complex<float>* _dest, signed int _prn, unsigned int _chip_shift);
|
||||
|
||||
//! Generates N complex GPS L1 C/A codes for the desired SV ID and code shift
|
||||
void beidou_b1i_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _prn, int _fs, unsigned int _chip_shift, unsigned int _ncodes);
|
||||
|
||||
//! Generates complex GPS L1 C/A code for the desired SV ID and code shift
|
||||
void beidou_b1i_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _prn, int _fs, unsigned int _chip_shift);
|
||||
|
||||
#endif /* BEIDOU_B1I_SDR_SIGNAL_PROCESSING_H_ */
|
@ -112,10 +112,12 @@ Pass_Through::Pass_Through(ConfigurationInterface* configuration, const std::str
|
||||
if (in_streams_ > 1)
|
||||
{
|
||||
LOG(ERROR) << "This implementation only supports one input stream";
|
||||
LOG(ERROR) << in_streams_;
|
||||
}
|
||||
if (out_streams_ > 1)
|
||||
{
|
||||
LOG(ERROR) << "This implementation only supports one output stream";
|
||||
LOG(ERROR) << out_streams_;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,10 +221,11 @@ const int NSATQZS = 0;
|
||||
const int NSYSQZS = 0;
|
||||
#endif
|
||||
|
||||
#define ENABDS
|
||||
#ifdef ENABDS
|
||||
const int MINPRNBDS = 1; //!< min satellite sat number of BeiDou
|
||||
const int MAXPRNBDS = 35; //!< max satellite sat number of BeiDou
|
||||
const int NSATBDS = (MAXPRNBDS - MINPRNCM + 1); //!< number of BeiDou satellites
|
||||
const int MINPRNBDS = 1; //!< min satellite sat number of BeiDou
|
||||
const int MAXPRNBDS = 35; //!< max satellite sat number of BeiDou
|
||||
const int NSATBDS = (MAXPRNBDS - MINPRNBDS + 1); //!< number of BeiDou satellites
|
||||
const int NSYSBDS = 1;
|
||||
#else
|
||||
const int MINPRNBDS = 0;
|
||||
|
@ -65,10 +65,25 @@ obsd_t insert_obs_to_rtklib(obsd_t& rtklib_obs, const Gnss_Synchro& gnss_synchro
|
||||
case 'R':
|
||||
rtklib_obs.sat = gnss_synchro.PRN + NSATGPS;
|
||||
break;
|
||||
case 'C':
|
||||
rtklib_obs.sat = gnss_synchro.PRN + NSATGPS + NSATGLO + NSATGAL + NSATQZS;
|
||||
break;
|
||||
|
||||
default:
|
||||
rtklib_obs.sat = gnss_synchro.PRN;
|
||||
}
|
||||
|
||||
// Mote that BeiDou week numbers do not need adjustment for foreseeable future. Consider change
|
||||
// to more elegant solution
|
||||
// if(gnss_synchro.System == 'C')
|
||||
// {
|
||||
// rtklib_obs.time = bdt2gpst(bdt2time(week, gnss_synchro.RX_time));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// rtklib_obs.time = gpst2time(adjgpsweek(week), gnss_synchro.RX_time);
|
||||
// }
|
||||
//
|
||||
rtklib_obs.time = gpst2time(adjgpsweek(week), gnss_synchro.RX_time);
|
||||
rtklib_obs.rcv = 1;
|
||||
return rtklib_obs;
|
||||
@ -227,6 +242,69 @@ eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph)
|
||||
return rtklib_sat;
|
||||
}
|
||||
|
||||
eph_t eph_to_rtklib(const Beidou_Dnav_Ephemeris& bei_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,
|
||||
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 = bei_eph.i_satellite_PRN + NSATGPS + NSATGLO + NSATGAL + NSATQZS;
|
||||
rtklib_sat.A = bei_eph.d_sqrt_A * bei_eph.d_sqrt_A;
|
||||
rtklib_sat.M0 = bei_eph.d_M_0;
|
||||
rtklib_sat.deln = bei_eph.d_Delta_n;
|
||||
rtklib_sat.OMG0 = bei_eph.d_OMEGA0;
|
||||
rtklib_sat.OMGd = bei_eph.d_OMEGA_DOT;
|
||||
rtklib_sat.omg = bei_eph.d_OMEGA;
|
||||
rtklib_sat.i0 = bei_eph.d_i_0;
|
||||
rtklib_sat.idot = bei_eph.d_IDOT;
|
||||
rtklib_sat.e = bei_eph.d_eccentricity;
|
||||
rtklib_sat.Adot = 0; //only in CNAV;
|
||||
rtklib_sat.ndot = 0; //only in CNAV;
|
||||
|
||||
rtklib_sat.code = bei_eph.i_sig_type; /*B1I data*/
|
||||
rtklib_sat.flag = bei_eph.i_nav_type; /*MEO/IGSO satellite*/
|
||||
rtklib_sat.iode = static_cast<int32_t>(bei_eph.d_AODE); /* AODE */
|
||||
rtklib_sat.iodc = static_cast<int32_t>(bei_eph.d_AODC); /* AODC */
|
||||
|
||||
rtklib_sat.week = bei_eph.i_BEIDOU_week; /* week of tow */
|
||||
rtklib_sat.cic = bei_eph.d_Cic;
|
||||
rtklib_sat.cis = bei_eph.d_Cis;
|
||||
rtklib_sat.cuc = bei_eph.d_Cuc;
|
||||
rtklib_sat.cus = bei_eph.d_Cus;
|
||||
rtklib_sat.crc = bei_eph.d_Crc;
|
||||
rtklib_sat.crs = bei_eph.d_Crs;
|
||||
rtklib_sat.f0 = bei_eph.d_A_f0;
|
||||
rtklib_sat.f1 = bei_eph.d_A_f1;
|
||||
rtklib_sat.f2 = bei_eph.d_A_f2;
|
||||
rtklib_sat.tgd[0] = bei_eph.d_TGD1;
|
||||
rtklib_sat.tgd[1] = bei_eph.d_TGD2;
|
||||
rtklib_sat.tgd[2] = 0.0;
|
||||
rtklib_sat.tgd[3] = 0.0;
|
||||
rtklib_sat.toes = bei_eph.d_Toe;
|
||||
rtklib_sat.toe = bdt2gpst(bdt2time(rtklib_sat.week, bei_eph.d_Toe));
|
||||
rtklib_sat.toc = bdt2gpst(bdt2time(rtklib_sat.week, bei_eph.d_Toc));
|
||||
rtklib_sat.ttr = bdt2gpst(bdt2time(rtklib_sat.week, bei_eph.d_TOW));
|
||||
/* adjustment for week handover */
|
||||
double tow, toc, toe;
|
||||
tow = time2gpst(rtklib_sat.ttr, &rtklib_sat.week);
|
||||
toc = time2gpst(rtklib_sat.toc, nullptr);
|
||||
toe = time2gpst(rtklib_sat.toe, nullptr);
|
||||
|
||||
if (rtklib_sat.toes < tow - 302400.0)
|
||||
{
|
||||
rtklib_sat.week++;
|
||||
tow -= 604800.0;
|
||||
}
|
||||
else if (rtklib_sat.toes > tow + 302400.0)
|
||||
{
|
||||
rtklib_sat.week--;
|
||||
tow += 604800.0;
|
||||
}
|
||||
rtklib_sat.toe = gpst2time(rtklib_sat.week, toe);
|
||||
rtklib_sat.toc = gpst2time(rtklib_sat.week, toc);
|
||||
rtklib_sat.ttr = gpst2time(rtklib_sat.week, tow);
|
||||
|
||||
return rtklib_sat;
|
||||
}
|
||||
|
||||
|
||||
eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris& gps_cnav_eph)
|
||||
{
|
||||
|
@ -31,6 +31,7 @@
|
||||
#ifndef GNSS_SDR_RTKLIB_CONVERSIONS_H_
|
||||
#define GNSS_SDR_RTKLIB_CONVERSIONS_H_
|
||||
|
||||
#include "beidou_dnav_ephemeris.h"
|
||||
#include "galileo_almanac.h"
|
||||
#include "galileo_ephemeris.h"
|
||||
#include "glonass_gnav_ephemeris.h"
|
||||
@ -44,6 +45,7 @@
|
||||
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);
|
||||
eph_t eph_to_rtklib(const Beidou_Dnav_Ephemeris& bei_eph);
|
||||
|
||||
alm_t alm_to_rtklib(const Gps_Almanac& gps_alm);
|
||||
alm_t alm_to_rtklib(const Galileo_Almanac& gal_alm);
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
|
||||
#include "signal_generator.h"
|
||||
#include "Beidou_B1I.h"
|
||||
#include "GLONASS_L1_L2_CA.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "Galileo_E1.h"
|
||||
@ -112,6 +113,12 @@ SignalGenerator::SignalGenerator(ConfigurationInterface* configuration,
|
||||
}
|
||||
}
|
||||
|
||||
else if (std::find(system.begin(), system.end(), "B") != system.end())
|
||||
{
|
||||
vector_length = round(static_cast<float>(fs_in) / (BEIDOU_B1I_CODE_RATE_HZ / BEIDOU_B1I_CODE_LENGTH_CHIPS));
|
||||
}
|
||||
|
||||
|
||||
if (item_type_ == "gr_complex")
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
|
@ -26,6 +26,7 @@ set(TELEMETRY_DECODER_ADAPTER_SOURCES
|
||||
galileo_e5a_telemetry_decoder.cc
|
||||
glonass_l1_ca_telemetry_decoder.cc
|
||||
glonass_l2_ca_telemetry_decoder.cc
|
||||
beidou_b1i_telemetry_decoder.cc
|
||||
)
|
||||
|
||||
set(TELEMETRY_DECODER_ADAPTER_HEADERS
|
||||
@ -37,6 +38,7 @@ set(TELEMETRY_DECODER_ADAPTER_HEADERS
|
||||
galileo_e5a_telemetry_decoder.h
|
||||
glonass_l1_ca_telemetry_decoder.h
|
||||
glonass_l2_ca_telemetry_decoder.h
|
||||
beidou_b1i_telemetry_decoder.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
@ -0,0 +1,110 @@
|
||||
/*!
|
||||
* \file beidou_b1i_telemetry_decoder.cc
|
||||
* \brief Implementation of an adapter of a Beidou B1I NAV data decoder block
|
||||
* to a TelemetryDecoderInterface
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2018 (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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "beidou_b1i_telemetry_decoder.h"
|
||||
#include "beidou_dnav_almanac.h"
|
||||
#include "beidou_dnav_ephemeris.h"
|
||||
#include "beidou_dnav_iono.h"
|
||||
#include "beidou_dnav_utc_model.h"
|
||||
#include "configuration_interface.h"
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
BeidouB1iTelemetryDecoder::BeidouB1iTelemetryDecoder(ConfigurationInterface* configuration,
|
||||
const 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_ = beidou_b1i_make_telemetry_decoder_cc(satellite_, dump_); // TODO fix me
|
||||
DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")";
|
||||
channel_ = 0;
|
||||
if (in_streams_ > 1)
|
||||
{
|
||||
LOG(ERROR) << "This implementation only supports one input stream";
|
||||
}
|
||||
if (out_streams_ > 1)
|
||||
{
|
||||
LOG(ERROR) << "This implementation only supports one output stream";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BeidouB1iTelemetryDecoder::~BeidouB1iTelemetryDecoder() = default;
|
||||
|
||||
|
||||
void BeidouB1iTelemetryDecoder::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 BeidouB1iTelemetryDecoder::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 BeidouB1iTelemetryDecoder::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (top_block)
|
||||
{ /* top_block is not null */
|
||||
};
|
||||
// Nothing to disconnect
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr BeidouB1iTelemetryDecoder::get_left_block()
|
||||
{
|
||||
return telemetry_decoder_;
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr BeidouB1iTelemetryDecoder::get_right_block()
|
||||
{
|
||||
return telemetry_decoder_;
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/*!
|
||||
* \file beidou_b1i_telemetry_decoder.h
|
||||
* \brief Interface of an adapter of a Beidou B1I NAV data decoder block
|
||||
* to a TelemetryDecoderInterface
|
||||
* \author Damian Miralles, 2018. dmiralles2009@gmail.com
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2018 (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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GNSS_SDR_BEIDOU_B1I_TELEMETRY_DECODER_H_
|
||||
#define GNSS_SDR_BEIDOU_B1I_TELEMETRY_DECODER_H_
|
||||
|
||||
#include "beidou_b1i_telemetry_decoder_cc.h"
|
||||
#include "telemetry_decoder_interface.h"
|
||||
#include <string>
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
* \brief This class implements a NAV data decoder for BEIDOU B1I
|
||||
*/
|
||||
class BeidouB1iTelemetryDecoder : public TelemetryDecoderInterface
|
||||
{
|
||||
public:
|
||||
BeidouB1iTelemetryDecoder(ConfigurationInterface* configuration,
|
||||
const std::string& role,
|
||||
unsigned int in_streams,
|
||||
unsigned int out_streams);
|
||||
|
||||
virtual ~BeidouB1iTelemetryDecoder();
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
//! Returns "BEIDOU_B1I_Telemetry_Decoder"
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "BEIDOU_B1I_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;
|
||||
inline void set_channel(int channel) override { telemetry_decoder_->set_channel(channel); }
|
||||
|
||||
inline void reset() override
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
beidou_b1i_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
|
@ -24,6 +24,7 @@ set(TELEMETRY_DECODER_GR_BLOCKS_SOURCES
|
||||
glonass_l1_ca_telemetry_decoder_cc.cc
|
||||
glonass_l2_ca_telemetry_decoder_cc.cc
|
||||
galileo_telemetry_decoder_cc.cc
|
||||
beidou_b1i_telemetry_decoder_cc.cc
|
||||
)
|
||||
|
||||
set(TELEMETRY_DECODER_GR_BLOCKS_HEADERS
|
||||
@ -34,6 +35,7 @@ set(TELEMETRY_DECODER_GR_BLOCKS_HEADERS
|
||||
glonass_l1_ca_telemetry_decoder_cc.h
|
||||
glonass_l2_ca_telemetry_decoder_cc.h
|
||||
galileo_telemetry_decoder_cc.h
|
||||
beidou_b1i_telemetry_decoder_cc.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
@ -0,0 +1,592 @@
|
||||
/*!
|
||||
* \file beidou_b1i_telemetry_decoder_cc.cc
|
||||
* \brief Implementation of an adapter of a BEIDOU BI1 DNAV data decoder block
|
||||
* to a TelemetryDecoderInterface
|
||||
* \note Code added as part of GSoC 2018 program
|
||||
* \author Damian Miralles, 2018. dmiralles2009(at)gmail.com
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.es
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "beidou_b1i_telemetry_decoder_cc.h"
|
||||
#include "control_message_factory.h"
|
||||
#include "convolutional.h"
|
||||
#include "display.h"
|
||||
#include "gnss_synchro.h"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <volk_gnsssdr/volk_gnsssdr.h>
|
||||
#include <iostream>
|
||||
|
||||
#define CRC_ERROR_LIMIT 8
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
|
||||
beidou_b1i_telemetry_decoder_cc_sptr
|
||||
beidou_b1i_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump)
|
||||
{
|
||||
return beidou_b1i_telemetry_decoder_cc_sptr(new beidou_b1i_telemetry_decoder_cc(satellite, dump));
|
||||
}
|
||||
|
||||
|
||||
beidou_b1i_telemetry_decoder_cc::beidou_b1i_telemetry_decoder_cc(
|
||||
const Gnss_Satellite &satellite,
|
||||
bool dump) : gr::block("beidou_b1i_telemetry_decoder_cc",
|
||||
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
|
||||
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
|
||||
{
|
||||
// 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 BeiDou B1i Telemetry Decoding for satellite " << this->d_satellite;
|
||||
|
||||
d_samples_per_symbol = (BEIDOU_B1I_CODE_RATE_HZ / BEIDOU_B1I_CODE_LENGTH_CHIPS) / BEIDOU_D1NAV_SYMBOL_RATE_SPS;
|
||||
d_symbols_per_preamble = BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS;
|
||||
d_samples_per_preamble = BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS * d_samples_per_symbol;
|
||||
d_secondary_code_symbols = static_cast<int32_t *>(volk_gnsssdr_malloc(BEIDOU_B1I_SECONDARY_CODE_LENGTH * sizeof(int32_t), volk_gnsssdr_get_alignment()));
|
||||
d_preamble_samples = static_cast<int32_t *>(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment()));
|
||||
d_preamble_period_samples = BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS * d_samples_per_symbol;
|
||||
d_subframe_length_symbols = BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS;
|
||||
|
||||
// Setting samples of secondary code
|
||||
for (int32_t i = 0; i < BEIDOU_B1I_SECONDARY_CODE_LENGTH; i++)
|
||||
{
|
||||
if (BEIDOU_B1I_SECONDARY_CODE.at(i) == '1')
|
||||
{
|
||||
d_secondary_code_symbols[i] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_secondary_code_symbols[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Setting samples of preamble code
|
||||
int32_t n = 0;
|
||||
for (int32_t i = 0; i < d_symbols_per_preamble; i++)
|
||||
{
|
||||
int32_t m = 0;
|
||||
if (BEIDOU_DNAV_PREAMBLE.at(i) == '1')
|
||||
{
|
||||
for (uint32_t j = 0; j < d_samples_per_symbol; j++)
|
||||
{
|
||||
d_preamble_samples[n] = d_secondary_code_symbols[m];
|
||||
n++;
|
||||
m++;
|
||||
m = m % BEIDOU_B1I_SECONDARY_CODE_LENGTH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t j = 0; j < d_samples_per_symbol; j++)
|
||||
{
|
||||
d_preamble_samples[n] = -d_secondary_code_symbols[m];
|
||||
n++;
|
||||
m++;
|
||||
m = m % BEIDOU_B1I_SECONDARY_CODE_LENGTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
d_subframe_symbols = static_cast<double *>(volk_gnsssdr_malloc(d_subframe_length_symbols * sizeof(double), volk_gnsssdr_get_alignment()));
|
||||
d_required_symbols = BEIDOU_DNAV_SUBFRAME_SYMBOLS * d_samples_per_symbol + d_samples_per_preamble;
|
||||
|
||||
// Generic settings
|
||||
d_sample_counter = 0;
|
||||
d_stat = 0;
|
||||
d_preamble_index = 0;
|
||||
d_flag_frame_sync = false;
|
||||
d_TOW_at_current_symbol_ms = 0;
|
||||
Flag_valid_word = false;
|
||||
d_CRC_error_counter = 0;
|
||||
d_flag_preamble = false;
|
||||
d_channel = 0;
|
||||
flag_SOW_set = false;
|
||||
}
|
||||
|
||||
|
||||
beidou_b1i_telemetry_decoder_cc::~beidou_b1i_telemetry_decoder_cc()
|
||||
{
|
||||
volk_gnsssdr_free(d_preamble_samples);
|
||||
volk_gnsssdr_free(d_secondary_code_symbols);
|
||||
volk_gnsssdr_free(d_subframe_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 beidou_b1i_telemetry_decoder_cc::decode_bch15_11_01(const int32_t *bits, int32_t *decbits)
|
||||
{
|
||||
int bit, err, reg[4] = {1, 1, 1, 1};
|
||||
int errind[15] = {14, 13, 10, 12, 6, 9, 4, 11, 0, 5, 7, 8, 1, 3, 2};
|
||||
|
||||
for (unsigned int i = 0; i < 15; i++)
|
||||
{
|
||||
decbits[i] = bits[i];
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < 15; i++)
|
||||
{
|
||||
bit = reg[3];
|
||||
reg[3] = reg[2];
|
||||
reg[2] = reg[1];
|
||||
reg[1] = reg[0];
|
||||
reg[0] = bits[i] * bit;
|
||||
reg[1] *= bit;
|
||||
}
|
||||
|
||||
err = errind[reg[0] + reg[1] * 2 + reg[2] * 4 + reg[3] * 8];
|
||||
|
||||
if (err > 0)
|
||||
{
|
||||
decbits[err - 1] *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
void beidou_b1i_telemetry_decoder_cc::decode_word(
|
||||
int32_t word_counter,
|
||||
const double *enc_word_symbols,
|
||||
int32_t *dec_word_symbols)
|
||||
{
|
||||
int32_t bitsbch[30], first_branch[15], second_branch[15];
|
||||
|
||||
if (word_counter == 1)
|
||||
{
|
||||
for (unsigned int j = 0; j < 30; j++)
|
||||
{
|
||||
dec_word_symbols[j] = (int32_t)(enc_word_symbols[j] > 0) ? (1) : (-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int r = 0; r < 2; r++)
|
||||
{
|
||||
for (unsigned int c = 0; c < 15; c++)
|
||||
{
|
||||
bitsbch[r * 15 + c] = (int32_t)(enc_word_symbols[c * 2 + r] > 0) ? (1) : (-1);
|
||||
}
|
||||
}
|
||||
|
||||
decode_bch15_11_01(&bitsbch[0], first_branch);
|
||||
decode_bch15_11_01(&bitsbch[15], second_branch);
|
||||
|
||||
for (unsigned int j = 0; j < 11; j++)
|
||||
{
|
||||
dec_word_symbols[j] = first_branch[j];
|
||||
dec_word_symbols[j + 11] = second_branch[j];
|
||||
}
|
||||
|
||||
for (unsigned int j = 0; j < 4; j++)
|
||||
{
|
||||
dec_word_symbols[j + 22] = first_branch[11 + j];
|
||||
dec_word_symbols[j + 26] = second_branch[11 + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void beidou_b1i_telemetry_decoder_cc::decode_subframe(double *frame_symbols, int32_t frame_length)
|
||||
{
|
||||
// 1. Transform from symbols to bits
|
||||
std::string data_bits;
|
||||
int32_t dec_word_bits[30];
|
||||
|
||||
// Decode each word in subframe
|
||||
for (uint32_t ii = 0; ii < BEIDOU_DNAV_WORDS_SUBFRAME; ii++)
|
||||
{
|
||||
// decode the word
|
||||
decode_word((ii + 1), &frame_symbols[ii * 30], dec_word_bits);
|
||||
|
||||
// Save word to string format
|
||||
for (uint32_t jj = 0; jj < (BEIDOU_DNAV_WORD_LENGTH_BITS); jj++)
|
||||
{
|
||||
data_bits.push_back((dec_word_bits[jj] > 0) ? ('1') : ('0'));
|
||||
}
|
||||
}
|
||||
|
||||
if (d_satellite.get_PRN() > 0 and d_satellite.get_PRN() < 6)
|
||||
{
|
||||
d_nav.d2_subframe_decoder(data_bits);
|
||||
}
|
||||
else
|
||||
{
|
||||
d_nav.d1_subframe_decoder(data_bits);
|
||||
}
|
||||
|
||||
|
||||
// 3. Check operation executed correctly
|
||||
if (d_nav.flag_crc_test == true)
|
||||
{
|
||||
LOG(INFO) << "BeiDou DNAV CRC correct in channel " << d_channel << " from satellite " << d_satellite;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(INFO) << "BeiDou DNAV CRC error in 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)
|
||||
std::shared_ptr<Beidou_Dnav_Ephemeris> tmp_obj = std::make_shared<Beidou_Dnav_Ephemeris>(d_nav.get_ephemeris());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "BEIDOU DNAV Ephemeris have been received in channel" << d_channel << " from satellite " << d_satellite;
|
||||
std::cout << "New BEIDOU B1I DNAV message received in channel " << d_channel << ": ephemeris from satellite " << d_satellite << std::endl;
|
||||
}
|
||||
if (d_nav.have_new_utc_model() == true)
|
||||
{
|
||||
// get object for this SV (mandatory)
|
||||
std::shared_ptr<Beidou_Dnav_Utc_Model> tmp_obj = std::make_shared<Beidou_Dnav_Utc_Model>(d_nav.get_utc_model());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "BEIDOU DNAV UTC Model have been received in channel" << d_channel << " from satellite " << d_satellite;
|
||||
std::cout << "New BEIDOU B1I DNAV utc model message received in channel " << d_channel << ": UTC model parameters from satellite " << d_satellite << std::endl;
|
||||
}
|
||||
if (d_nav.have_new_iono() == true)
|
||||
{
|
||||
// get object for this SV (mandatory)
|
||||
std::shared_ptr<Beidou_Dnav_Iono> tmp_obj = std::make_shared<Beidou_Dnav_Iono>(d_nav.get_iono());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "BEIDOU DNAV Iono have been received in channel" << d_channel << " from satellite " << d_satellite;
|
||||
std::cout << "New BEIDOU B1I DNAV Iono message received in channel " << d_channel << ": Iono model parameters from satellite " << d_satellite << std::endl;
|
||||
}
|
||||
if (d_nav.have_new_almanac() == true)
|
||||
{
|
||||
// unsigned int slot_nbr = d_nav.i_alm_satellite_PRN;
|
||||
// std::shared_ptr<Beidou_Dnav_Almanac> tmp_obj = std::make_shared<Beidou_Dnav_Almanac>(d_nav.get_almanac(slot_nbr));
|
||||
// this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "BEIDOU DNAV Almanac have been received in channel" << d_channel << " from satellite " << d_satellite << std::endl;
|
||||
std::cout << "New BEIDOU B1I DNAV almanac received in channel " << d_channel << " from satellite " << d_satellite << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void beidou_b1i_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satellite)
|
||||
{
|
||||
uint32_t sat_prn = 0;
|
||||
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;
|
||||
|
||||
// Update satellite information for DNAV decoder
|
||||
sat_prn = d_satellite.get_PRN();
|
||||
d_nav.i_satellite_PRN = sat_prn;
|
||||
|
||||
// Update tel dec parameters for D2 NAV Messages
|
||||
if (sat_prn > 0 and sat_prn < 6)
|
||||
{
|
||||
// Clear values from previous declaration
|
||||
volk_gnsssdr_free(d_preamble_samples);
|
||||
volk_gnsssdr_free(d_secondary_code_symbols);
|
||||
volk_gnsssdr_free(d_subframe_symbols);
|
||||
|
||||
d_samples_per_symbol = (BEIDOU_B1I_CODE_RATE_HZ / BEIDOU_B1I_CODE_LENGTH_CHIPS) / BEIDOU_D2NAV_SYMBOL_RATE_SPS;
|
||||
d_symbols_per_preamble = BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS;
|
||||
d_samples_per_preamble = BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS * d_samples_per_symbol;
|
||||
d_secondary_code_symbols = nullptr;
|
||||
d_preamble_samples = static_cast<int32_t *>(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment()));
|
||||
d_preamble_period_samples = BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS * d_samples_per_symbol;
|
||||
d_subframe_length_symbols = BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS;
|
||||
|
||||
// Setting samples of preamble code
|
||||
int32_t n = 0;
|
||||
for (int32_t i = 0; i < d_symbols_per_preamble; i++)
|
||||
{
|
||||
if (BEIDOU_DNAV_PREAMBLE.at(i) == '1')
|
||||
{
|
||||
for (uint32_t j = 0; j < d_samples_per_symbol; j++)
|
||||
{
|
||||
d_preamble_samples[n] = 1;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t j = 0; j < d_samples_per_symbol; j++)
|
||||
{
|
||||
d_preamble_samples[n] = -1;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
d_subframe_symbols = static_cast<double *>(volk_gnsssdr_malloc(d_subframe_length_symbols * sizeof(double), volk_gnsssdr_get_alignment()));
|
||||
d_required_symbols = BEIDOU_DNAV_SUBFRAME_SYMBOLS * d_samples_per_symbol + d_samples_per_preamble;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void beidou_b1i_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(std::to_string(d_channel));
|
||||
d_dump_filename.append(".dat");
|
||||
d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
|
||||
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 Beidou TLM dump file. " << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int beidou_b1i_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)
|
||||
{
|
||||
int32_t corr_value = 0;
|
||||
int32_t preamble_diff = 0;
|
||||
|
||||
auto **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]); // Get the output buffer pointer
|
||||
const auto **in = reinterpret_cast<const Gnss_Synchro **>(&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.Prompt_I); //add new symbol to the symbol queue
|
||||
d_sample_counter++; //count for the processed samples
|
||||
consume_each(1);
|
||||
|
||||
d_flag_preamble = false;
|
||||
|
||||
if (d_symbol_history.size() > d_required_symbols)
|
||||
{
|
||||
//******* preamble correlation ********
|
||||
for (int i = 0; i < d_samples_per_preamble; i++)
|
||||
{
|
||||
if (d_symbol_history.at(i) < 0) // symbols clipping
|
||||
{
|
||||
corr_value -= d_preamble_samples[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
corr_value += d_preamble_samples[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//******* frame sync ******************
|
||||
if (d_stat == 0) //no preamble information
|
||||
{
|
||||
if (abs(corr_value) >= d_samples_per_preamble)
|
||||
{
|
||||
// Record the preamble sample stamp
|
||||
d_preamble_index = d_sample_counter;
|
||||
LOG(INFO) << "Preamble detection for BEIDOU B1I SAT " << this->d_satellite;
|
||||
// Enter into frame pre-detection status
|
||||
d_stat = 1;
|
||||
}
|
||||
}
|
||||
else if (d_stat == 1) // possible preamble lock
|
||||
{
|
||||
if (abs(corr_value) >= d_samples_per_preamble)
|
||||
{
|
||||
//check preamble separation
|
||||
preamble_diff = static_cast<int32_t>(d_sample_counter - d_preamble_index);
|
||||
if (abs(preamble_diff - d_preamble_period_samples) == 0)
|
||||
{
|
||||
//try to decode frame
|
||||
LOG(INFO) << "Starting BeiDou DNAV frame decoding for BeiDou B1I SAT " << this->d_satellite;
|
||||
d_preamble_index = d_sample_counter; //record the preamble sample stamp
|
||||
d_stat = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (preamble_diff > d_preamble_period_samples)
|
||||
{
|
||||
d_stat = 0; // start again
|
||||
}
|
||||
DLOG(INFO) << "Failed BeiDou DNAV frame decoding for BeiDou B1I SAT " << this->d_satellite;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (d_stat == 2) // preamble acquired
|
||||
{
|
||||
if (d_sample_counter == d_preamble_index + static_cast<uint64_t>(d_preamble_period_samples))
|
||||
{
|
||||
//******* SAMPLES TO SYMBOLS *******
|
||||
if (corr_value > 0) //normal PLL lock
|
||||
{
|
||||
int k = 0;
|
||||
for (uint32_t i = 0; i < d_subframe_length_symbols; i++)
|
||||
{
|
||||
d_subframe_symbols[i] = 0;
|
||||
//integrate samples into symbols
|
||||
for (uint32_t m = 0; m < d_samples_per_symbol; m++)
|
||||
{
|
||||
if (d_satellite.get_PRN() > 0 and d_satellite.get_PRN() < 6)
|
||||
{
|
||||
// because last symbol of the preamble is just received now!
|
||||
d_subframe_symbols[i] += d_symbol_history.at(i * d_samples_per_symbol + m);
|
||||
}
|
||||
else
|
||||
{
|
||||
// because last symbol of the preamble is just received now!
|
||||
d_subframe_symbols[i] += static_cast<float>(d_secondary_code_symbols[k]) * d_symbol_history.at(i * d_samples_per_symbol + m);
|
||||
k++;
|
||||
k = k % BEIDOU_B1I_SECONDARY_CODE_LENGTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else //180 deg. inverted carrier phase PLL lock
|
||||
{
|
||||
int k = 0;
|
||||
for (uint32_t i = 0; i < d_subframe_length_symbols; i++)
|
||||
{
|
||||
d_subframe_symbols[i] = 0;
|
||||
//integrate samples into symbols
|
||||
for (uint32_t m = 0; m < d_samples_per_symbol; m++)
|
||||
{
|
||||
if (d_satellite.get_PRN() > 0 and d_satellite.get_PRN() < 6)
|
||||
{
|
||||
// because last symbol of the preamble is just received now!
|
||||
d_subframe_symbols[i] -= d_symbol_history.at(i * d_samples_per_symbol + m);
|
||||
}
|
||||
else
|
||||
{
|
||||
// because last symbol of the preamble is just received now!
|
||||
d_subframe_symbols[i] -= static_cast<float>(d_secondary_code_symbols[k]) * d_symbol_history.at(i * d_samples_per_symbol + m);
|
||||
k++;
|
||||
k = k % BEIDOU_B1I_SECONDARY_CODE_LENGTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//call the decoder
|
||||
decode_subframe(d_subframe_symbols, d_subframe_length_symbols);
|
||||
|
||||
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) << "BeiDou DNAV frame sync found for SAT " << this->d_satellite;
|
||||
}
|
||||
}
|
||||
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) << "BeiDou DNAV frame sync lost for SAT " << this->d_satellite;
|
||||
d_flag_frame_sync = false;
|
||||
d_stat = 0;
|
||||
flag_SOW_set = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UPDATE GNSS SYNCHRO DATA
|
||||
//2. Add the telemetry decoder information
|
||||
if (this->d_flag_preamble == true and d_nav.flag_new_SOW_available == true)
|
||||
//update TOW at the preamble instant
|
||||
{
|
||||
// Reporting sow as gps time of week
|
||||
d_TOW_at_Preamble_ms = static_cast<uint32_t>((d_nav.d_SOW + 14) * 1000.0);
|
||||
d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((d_required_symbols + 1) * BEIDOU_B1I_CODE_PERIOD_MS);
|
||||
flag_SOW_set = true;
|
||||
d_nav.flag_new_SOW_available = false;
|
||||
}
|
||||
else //if there is not a new preamble, we define the TOW of the current symbol
|
||||
{
|
||||
d_TOW_at_current_symbol_ms += static_cast<uint32_t>(BEIDOU_B1I_CODE_PERIOD_MS);
|
||||
}
|
||||
|
||||
|
||||
if (d_flag_frame_sync == true and flag_SOW_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_ms = d_TOW_at_current_symbol_ms;
|
||||
|
||||
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_ms;
|
||||
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
|
||||
tmp_ulong_int = current_symbol.Tracking_sample_counter;
|
||||
d_dump_file.write(reinterpret_cast<char *>(&tmp_ulong_int), sizeof(unsigned long int));
|
||||
tmp_double = 0;
|
||||
d_dump_file.write(reinterpret_cast<char *>(&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() > d_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;
|
||||
}
|
@ -0,0 +1,126 @@
|
||||
/*!
|
||||
* \file beidou_b1i_telemetry_decoder_cc.h
|
||||
* \brief Implementation of an adapter of a BEIDOU BI1 DNAV data decoder block
|
||||
* to a TelemetryDecoderInterface
|
||||
* \details Code added as part of GSoC 2018 program. However new modifications included to mimic
|
||||
* decoding of existing signals
|
||||
* \author Damian Miralles, 2018. dmiralles2009(at)gmail.com
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.es
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_BEIDOU_B1I_TELEMETRY_DECODER_CC_H
|
||||
#define GNSS_SDR_BEIDOU_B1I_TELEMETRY_DECODER_CC_H
|
||||
|
||||
#include "Beidou_B1I.h"
|
||||
#include "beidou_dnav_almanac.h"
|
||||
#include "beidou_dnav_ephemeris.h"
|
||||
#include "beidou_dnav_navigation_message.h"
|
||||
#include "beidou_dnav_utc_model.h"
|
||||
#include "gnss_satellite.h"
|
||||
#include "gnss_synchro.h"
|
||||
#include <gnuradio/block.h>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
|
||||
class beidou_b1i_telemetry_decoder_cc;
|
||||
|
||||
typedef boost::shared_ptr<beidou_b1i_telemetry_decoder_cc> beidou_b1i_telemetry_decoder_cc_sptr;
|
||||
|
||||
beidou_b1i_telemetry_decoder_cc_sptr beidou_b1i_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump);
|
||||
|
||||
//!!!! edit
|
||||
/*!
|
||||
* \brief This class implements a block that decodes the GNAV data defined in BEIDOU ICD v5.1
|
||||
* \note Code added as part of GSoC 2018 program
|
||||
* \see <a href="http://russianspacesystems.ru/wp-content/uploads/2016/08/ICD_GLONASS_eng_v5.1.pdf">GLONASS ICD</a>
|
||||
*
|
||||
*/
|
||||
class beidou_b1i_telemetry_decoder_cc : public gr::block
|
||||
{
|
||||
public:
|
||||
~beidou_b1i_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 beidou_b1i_telemetry_decoder_cc_sptr
|
||||
beidou_b1i_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump);
|
||||
beidou_b1i_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump);
|
||||
|
||||
void decode_subframe(double *symbols, int32_t frame_length);
|
||||
void decode_word(int32_t word_counter, const double *enc_word_symbols, int32_t *dec_word_symbols);
|
||||
void decode_bch15_11_01(const int32_t *bits, int32_t *decbits);
|
||||
|
||||
|
||||
//!< Preamble decoding
|
||||
unsigned short int d_preambles_symbols[BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS];
|
||||
int32_t *d_preamble_samples;
|
||||
int32_t *d_secondary_code_symbols;
|
||||
uint32_t d_samples_per_symbol;
|
||||
int32_t d_symbols_per_preamble;
|
||||
int32_t d_samples_per_preamble;
|
||||
int32_t d_preamble_period_samples;
|
||||
double *d_subframe_symbols;
|
||||
uint32_t d_subframe_length_symbols;
|
||||
uint32_t d_required_symbols;
|
||||
|
||||
//!< Storage for incoming data
|
||||
std::deque<float> d_symbol_history;
|
||||
|
||||
//!< Variables for internal functionality
|
||||
uint64_t d_sample_counter; //!< Sample counter as an index (1,2,3,..etc) indicating number of samples processed
|
||||
uint64_t d_preamble_index; //!< Index of sample number where preamble was found
|
||||
uint32_t d_stat; //!< Status of decoder
|
||||
bool d_flag_frame_sync; //!< Indicate when a frame sync is achieved
|
||||
bool d_flag_preamble; //!< Flag indicating when preamble was found
|
||||
int32_t d_CRC_error_counter; //!< Number of failed CRC operations
|
||||
bool flag_SOW_set; //!< Indicates when time of week is set
|
||||
|
||||
//!< Navigation Message variable
|
||||
Beidou_Dnav_Navigation_Message d_nav;
|
||||
|
||||
//!< Values to populate gnss synchronization structure
|
||||
uint32_t d_TOW_at_Preamble_ms;
|
||||
uint32_t d_TOW_at_current_symbol_ms;
|
||||
bool Flag_valid_word;
|
||||
|
||||
//!< Satellite Information and logging capacity
|
||||
Gnss_Satellite d_satellite;
|
||||
int32_t d_channel;
|
||||
bool d_dump;
|
||||
std::string d_dump_filename;
|
||||
std::ofstream d_dump_file;
|
||||
};
|
||||
|
||||
#endif
|
@ -65,6 +65,7 @@ set(TRACKING_ADAPTER_SOURCES
|
||||
gps_l5_dll_pll_tracking.cc
|
||||
glonass_l2_ca_dll_pll_tracking.cc
|
||||
glonass_l2_ca_dll_pll_c_aid_tracking.cc
|
||||
beidou_b1i_dll_pll_tracking.cc
|
||||
${OPT_TRACKING_ADAPTERS_SOURCES}
|
||||
)
|
||||
|
||||
@ -82,23 +83,24 @@ set(TRACKING_ADAPTER_HEADERS
|
||||
gps_l5_dll_pll_tracking.h
|
||||
glonass_l2_ca_dll_pll_tracking.h
|
||||
glonass_l2_ca_dll_pll_c_aid_tracking.h
|
||||
beidou_b1i_dll_pll_tracking.h
|
||||
${OPT_TRACKING_ADAPTERS_HEADERS}
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/src/core/system_parameters
|
||||
${CMAKE_SOURCE_DIR}/src/core/interfaces
|
||||
${CMAKE_SOURCE_DIR}/src/core/receiver
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/tracking/gnuradio_blocks
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/tracking/libs
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/libs
|
||||
${ARMADILLO_INCLUDE_DIRS}
|
||||
${GLOG_INCLUDE_DIRS}
|
||||
${GFlags_INCLUDE_DIRS}
|
||||
${GNURADIO_RUNTIME_INCLUDE_DIRS}
|
||||
${VOLK_GNSSSDR_INCLUDE_DIRS}
|
||||
${OPT_TRACKING_INCLUDE_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/src/core/system_parameters
|
||||
${CMAKE_SOURCE_DIR}/src/core/interfaces
|
||||
${CMAKE_SOURCE_DIR}/src/core/receiver
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/tracking/gnuradio_blocks
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/tracking/libs
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/libs
|
||||
${ARMADILLO_INCLUDE_DIRS}
|
||||
${GLOG_INCLUDE_DIRS}
|
||||
${GFlags_INCLUDE_DIRS}
|
||||
${GNURADIO_RUNTIME_INCLUDE_DIRS}
|
||||
${VOLK_GNSSSDR_INCLUDE_DIRS}
|
||||
${OPT_TRACKING_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
list(SORT TRACKING_ADAPTER_HEADERS)
|
||||
|
201
src/algorithms/tracking/adapters/beidou_b1i_dll_pll_tracking.cc
Normal file
201
src/algorithms/tracking/adapters/beidou_b1i_dll_pll_tracking.cc
Normal file
@ -0,0 +1,201 @@
|
||||
/*!
|
||||
* \file beidou_b1i_dll_pll_tracking.cc
|
||||
* \brief Implementation of an adapter of a DLL+PLL tracking loop block
|
||||
* for Beidou B1I to a TrackingInterface
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz@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, Birkhauser, 2007
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2018 (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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "beidou_b1i_dll_pll_tracking.h"
|
||||
#include "Beidou_B1I.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "display.h"
|
||||
#include "dll_pll_conf.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include <glog/logging.h>
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
BeidouB1iDllPllTracking::BeidouB1iDllPllTracking(
|
||||
ConfigurationInterface* configuration, const std::string& role,
|
||||
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
|
||||
{
|
||||
Dll_Pll_Conf trk_param = Dll_Pll_Conf();
|
||||
DLOG(INFO) << "role " << role;
|
||||
//################# CONFIGURATION PARAMETERS ########################
|
||||
std::string default_item_type = "gr_complex";
|
||||
std::string item_type = configuration->property(role + ".item_type", default_item_type);
|
||||
int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
|
||||
int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||
trk_param.fs_in = fs_in;
|
||||
bool dump = configuration->property(role + ".dump", false);
|
||||
trk_param.dump = dump;
|
||||
float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0);
|
||||
if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast<float>(FLAGS_pll_bw_hz);
|
||||
trk_param.pll_bw_hz = pll_bw_hz;
|
||||
float pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 20.0);
|
||||
trk_param.pll_bw_narrow_hz = pll_bw_narrow_hz;
|
||||
float dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 2.0);
|
||||
trk_param.dll_bw_narrow_hz = dll_bw_narrow_hz;
|
||||
float dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0);
|
||||
if (FLAGS_dll_bw_hz != 0.0) dll_bw_hz = static_cast<float>(FLAGS_dll_bw_hz);
|
||||
trk_param.dll_bw_hz = dll_bw_hz;
|
||||
float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5);
|
||||
trk_param.early_late_space_chips = early_late_space_chips;
|
||||
float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.5);
|
||||
trk_param.early_late_space_narrow_chips = early_late_space_narrow_chips;
|
||||
std::string default_dump_filename = "./track_ch";
|
||||
std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||
trk_param.dump_filename = dump_filename;
|
||||
int vector_length = std::round(fs_in / (BEIDOU_B1I_CODE_RATE_HZ / BEIDOU_B1I_CODE_LENGTH_CHIPS));
|
||||
trk_param.vector_length = vector_length;
|
||||
int symbols_extended_correlator = configuration->property(role + ".extend_correlation_symbols", 1);
|
||||
if (symbols_extended_correlator < 1)
|
||||
{
|
||||
symbols_extended_correlator = 1;
|
||||
std::cout << TEXT_RED << "WARNING: BEIDOU B1I. extend_correlation_symbols must be bigger than 1. Coherent integration has been set to 1 symbol (1 ms)" << TEXT_RESET << std::endl;
|
||||
}
|
||||
else if (symbols_extended_correlator > 20)
|
||||
{
|
||||
symbols_extended_correlator = 20;
|
||||
std::cout << TEXT_RED << "WARNING: BEIDOU B1I. extend_correlation_symbols must be lower than 21. Coherent integration has been set to 20 symbols (20 ms)" << TEXT_RESET << std::endl;
|
||||
}
|
||||
trk_param.extend_correlation_symbols = symbols_extended_correlator;
|
||||
bool track_pilot = configuration->property(role + ".track_pilot", false);
|
||||
if (track_pilot)
|
||||
{
|
||||
std::cout << TEXT_RED << "WARNING: BEIDOU B1I does not have pilot signal. Data tracking has been enabled" << TEXT_RESET << std::endl;
|
||||
}
|
||||
if ((symbols_extended_correlator > 1) and (pll_bw_narrow_hz > pll_bw_hz or dll_bw_narrow_hz > dll_bw_hz))
|
||||
{
|
||||
std::cout << TEXT_RED << "WARNING: BEIDOU B1I. PLL or DLL narrow tracking bandwidth is higher than wide tracking one" << TEXT_RESET << std::endl;
|
||||
}
|
||||
trk_param.very_early_late_space_chips = 0.0;
|
||||
trk_param.very_early_late_space_narrow_chips = 0.0;
|
||||
trk_param.track_pilot = false;
|
||||
trk_param.system = 'C';
|
||||
char sig_[3] = "B1";
|
||||
std::memcpy(trk_param.signal, sig_, 3);
|
||||
int cn0_samples = configuration->property(role + ".cn0_samples", 20);
|
||||
if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples;
|
||||
trk_param.cn0_samples = cn0_samples;
|
||||
int cn0_min = configuration->property(role + ".cn0_min", 25);
|
||||
if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min;
|
||||
trk_param.cn0_min = cn0_min;
|
||||
int max_lock_fail = configuration->property(role + ".max_lock_fail", 50);
|
||||
if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail;
|
||||
trk_param.max_lock_fail = max_lock_fail;
|
||||
double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85);
|
||||
if (FLAGS_carrier_lock_th != 0.85) carrier_lock_th = FLAGS_carrier_lock_th;
|
||||
trk_param.carrier_lock_th = carrier_lock_th;
|
||||
|
||||
//################# MAKE TRACKING GNURadio object ###################
|
||||
if (item_type == "gr_complex")
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
tracking_ = dll_pll_veml_make_tracking(trk_param);
|
||||
}
|
||||
else
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
LOG(WARNING) << item_type << " unknown tracking item type.";
|
||||
}
|
||||
channel_ = 0;
|
||||
DLOG(INFO) << "tracking(" << tracking_->unique_id() << ")";
|
||||
if (in_streams_ > 1)
|
||||
{
|
||||
LOG(ERROR) << "This implementation only supports one input stream";
|
||||
}
|
||||
if (out_streams_ > 1)
|
||||
{
|
||||
LOG(ERROR) << "This implementation only supports one output stream";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BeidouB1iDllPllTracking::~BeidouB1iDllPllTracking() = default;
|
||||
|
||||
|
||||
void BeidouB1iDllPllTracking::start_tracking()
|
||||
{
|
||||
tracking_->start_tracking();
|
||||
}
|
||||
|
||||
void BeidouB1iDllPllTracking::stop_tracking()
|
||||
{
|
||||
tracking_->stop_tracking();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set tracking channel unique ID
|
||||
*/
|
||||
void BeidouB1iDllPllTracking::set_channel(unsigned int channel)
|
||||
{
|
||||
channel_ = channel;
|
||||
tracking_->set_channel(channel);
|
||||
}
|
||||
|
||||
|
||||
void BeidouB1iDllPllTracking::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
|
||||
{
|
||||
tracking_->set_gnss_synchro(p_gnss_synchro);
|
||||
}
|
||||
|
||||
|
||||
void BeidouB1iDllPllTracking::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 BeidouB1iDllPllTracking::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 BeidouB1iDllPllTracking::get_left_block()
|
||||
{
|
||||
return tracking_;
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr BeidouB1iDllPllTracking::get_right_block()
|
||||
{
|
||||
return tracking_;
|
||||
}
|
106
src/algorithms/tracking/adapters/beidou_b1i_dll_pll_tracking.h
Normal file
106
src/algorithms/tracking/adapters/beidou_b1i_dll_pll_tracking.h
Normal file
@ -0,0 +1,106 @@
|
||||
/*!
|
||||
* \file beidou_b1i_dll_pll_tracking.h
|
||||
* \brief Interface of an adapter of a DLL+PLL tracking loop block
|
||||
* for Beidou B1I to a TrackingInterface
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(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, Birkhauser, 2007
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2018 (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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_BEIDOU_B1I_DLL_PLL_TRACKING_H_
|
||||
#define GNSS_SDR_BEIDOU_B1I_DLL_PLL_TRACKING_H_
|
||||
|
||||
#include "dll_pll_veml_tracking.h"
|
||||
#include "tracking_interface.h"
|
||||
#include <string>
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
* \brief This class implements a code DLL + carrier PLL tracking loop
|
||||
*/
|
||||
class BeidouB1iDllPllTracking : public TrackingInterface
|
||||
{
|
||||
public:
|
||||
BeidouB1iDllPllTracking(ConfigurationInterface* configuration,
|
||||
const std::string& role,
|
||||
unsigned int in_streams,
|
||||
unsigned int out_streams);
|
||||
|
||||
virtual ~BeidouB1iDllPllTracking();
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "BEIDOU_B1I_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;
|
||||
|
||||
/*!
|
||||
* \brief Stop running tracking
|
||||
*/
|
||||
void stop_tracking() override;
|
||||
|
||||
private:
|
||||
dll_pll_veml_tracking_sptr tracking_;
|
||||
size_t item_size_;
|
||||
unsigned int channel_;
|
||||
std::string role_;
|
||||
unsigned int in_streams_;
|
||||
unsigned int out_streams_;
|
||||
};
|
||||
|
||||
#endif // GNSS_SDR_BEIDOU_B1I_DLL_PLL_TRACKING_H_
|
@ -35,12 +35,14 @@
|
||||
*/
|
||||
|
||||
#include "dll_pll_veml_tracking.h"
|
||||
#include "Beidou_B1I.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "GPS_L2C.h"
|
||||
#include "GPS_L5.h"
|
||||
#include "Galileo_E1.h"
|
||||
#include "Galileo_E5a.h"
|
||||
#include "MATH_CONSTANTS.h"
|
||||
#include "beidou_b1i_signal_processing.h"
|
||||
#include "control_message_factory.h"
|
||||
#include "galileo_e1_signal_processing.h"
|
||||
#include "galileo_e5_signal_processing.h"
|
||||
@ -96,7 +98,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
|
||||
d_code_chip_rate = 0.0;
|
||||
d_secondary_code_length = 0U;
|
||||
d_secondary_code_string = nullptr;
|
||||
d_gps_l1ca_preambles_symbols = nullptr;
|
||||
d_preambles_symbols = nullptr;
|
||||
signal_type = std::string(trk_parameters.signal);
|
||||
|
||||
std::map<std::string, std::string> map_signal_pretty_name;
|
||||
@ -107,6 +109,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
|
||||
map_signal_pretty_name["2G"] = "L2 C/A";
|
||||
map_signal_pretty_name["5X"] = "E5a";
|
||||
map_signal_pretty_name["L5"] = "L5";
|
||||
map_signal_pretty_name["B1"] = "B1I";
|
||||
|
||||
signal_pretty_name = map_signal_pretty_name[signal_type];
|
||||
|
||||
@ -131,7 +134,8 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
|
||||
uint16_t preambles_bits[GPS_CA_PREAMBLE_LENGTH_BITS] = GPS_PREAMBLE;
|
||||
|
||||
// preamble bits to sampled symbols
|
||||
d_gps_l1ca_preambles_symbols = static_cast<int32_t *>(volk_gnsssdr_malloc(GPS_CA_PREAMBLE_LENGTH_SYMBOLS * sizeof(int32_t), volk_gnsssdr_get_alignment()));
|
||||
d_preamble_length_symbols = GPS_CA_PREAMBLE_LENGTH_SYMBOLS;
|
||||
d_preambles_symbols = static_cast<int32_t *>(volk_gnsssdr_malloc(GPS_CA_PREAMBLE_LENGTH_SYMBOLS * sizeof(int32_t), volk_gnsssdr_get_alignment()));
|
||||
int32_t n = 0;
|
||||
for (uint16_t preambles_bit : preambles_bits)
|
||||
{
|
||||
@ -139,11 +143,11 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
|
||||
{
|
||||
if (preambles_bit == 1)
|
||||
{
|
||||
d_gps_l1ca_preambles_symbols[n] = 1;
|
||||
d_preambles_symbols[n] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_gps_l1ca_preambles_symbols[n] = -1;
|
||||
d_preambles_symbols[n] = -1;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
@ -270,6 +274,40 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
|
||||
d_symbols_per_bit = 0;
|
||||
}
|
||||
}
|
||||
else if (trk_parameters.system == 'C')
|
||||
{
|
||||
systemName = "Beidou";
|
||||
if (signal_type == "B1")
|
||||
{
|
||||
// GEO Satellites use different secondary code
|
||||
d_signal_carrier_freq = BEIDOU_B1I_FREQ_HZ;
|
||||
d_code_period = BEIDOU_B1I_CODE_PERIOD;
|
||||
d_code_chip_rate = BEIDOU_B1I_CODE_RATE_HZ;
|
||||
d_code_length_chips = static_cast<unsigned int>(BEIDOU_B1I_CODE_LENGTH_CHIPS);
|
||||
d_symbols_per_bit = BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT;
|
||||
d_correlation_length_ms = 1;
|
||||
d_code_samples_per_chip = 1;
|
||||
d_secondary = true;
|
||||
trk_parameters.track_pilot = false;
|
||||
interchange_iq = false;
|
||||
d_secondary_code_length = static_cast<unsigned int>(BEIDOU_B1I_SECONDARY_CODE_LENGTH);
|
||||
d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B1I_SECONDARY_CODE_STR);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << "Invalid Signal argument when instantiating tracking blocks";
|
||||
std::cout << "Invalid Signal argument when instantiating tracking blocks" << std::endl;
|
||||
d_correlation_length_ms = 1;
|
||||
d_secondary = false;
|
||||
interchange_iq = false;
|
||||
d_signal_carrier_freq = 0.0;
|
||||
d_code_period = 0.0;
|
||||
d_code_length_chips = 0;
|
||||
d_code_samples_per_chip = 0;
|
||||
d_symbols_per_bit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << "Invalid System argument when instantiating tracking blocks";
|
||||
@ -533,6 +571,45 @@ void dll_pll_veml_tracking::start_tracking()
|
||||
}
|
||||
volk_gnsssdr_free(aux_code);
|
||||
}
|
||||
else if (systemName == "Beidou" and signal_type == "B1")
|
||||
{
|
||||
beidou_b1i_code_gen_float(d_tracking_code, d_acquisition_gnss_synchro->PRN, 0);
|
||||
// Update secondary code settings for geo satellites
|
||||
if (d_acquisition_gnss_synchro->PRN > 0 and d_acquisition_gnss_synchro->PRN < 6)
|
||||
{
|
||||
d_symbols_per_bit = 2;
|
||||
d_correlation_length_ms = 1;
|
||||
d_code_samples_per_chip = 1;
|
||||
d_secondary = false;
|
||||
trk_parameters.track_pilot = false;
|
||||
interchange_iq = false;
|
||||
d_secondary_code_length = 0;
|
||||
d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B1I_D2_SECONDARY_CODE_STR);
|
||||
|
||||
// preamble bits to sampled symbols
|
||||
d_preamble_length_symbols = 22;
|
||||
d_preambles_symbols = static_cast<int32_t *>(volk_gnsssdr_malloc(22 * sizeof(int32_t), volk_gnsssdr_get_alignment()));
|
||||
int32_t n = 0;
|
||||
uint16_t preambles_bits[BEIDOU_B1I_PREAMBLE_LENGTH_BITS] = {1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0};
|
||||
for (uint16_t preambles_bit : preambles_bits)
|
||||
{
|
||||
for (int32_t j = 0; j < d_symbols_per_bit; j++)
|
||||
{
|
||||
if (preambles_bit == 1)
|
||||
{
|
||||
d_preambles_symbols[n] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_preambles_symbols[n] = -1;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
d_symbol_history.resize(22); // Change fixed buffer size
|
||||
d_symbol_history.clear();
|
||||
}
|
||||
}
|
||||
|
||||
multicorrelator_cpu.set_local_code_and_taps(d_code_samples_per_chip * d_code_length_chips, d_tracking_code, d_local_code_shift_chips);
|
||||
std::fill_n(d_correlator_outs, d_n_correlator_taps, gr_complex(0.0, 0.0));
|
||||
@ -580,7 +657,7 @@ dll_pll_veml_tracking::~dll_pll_veml_tracking()
|
||||
{
|
||||
if (signal_type == "1C")
|
||||
{
|
||||
volk_gnsssdr_free(d_gps_l1ca_preambles_symbols);
|
||||
volk_gnsssdr_free(d_preambles_symbols);
|
||||
}
|
||||
|
||||
if (d_dump_file.is_open())
|
||||
@ -1414,6 +1491,8 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
|
||||
next_state = acquire_secondary();
|
||||
if (next_state)
|
||||
{
|
||||
LOG(INFO) << systemName << " " << signal_pretty_name << " secondary code locked in channel " << d_channel
|
||||
<< " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl;
|
||||
std::cout << systemName << " " << signal_pretty_name << " secondary code locked in channel " << d_channel
|
||||
<< " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl;
|
||||
}
|
||||
@ -1429,23 +1508,24 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
|
||||
d_symbol_history.push_back(d_Prompt->real());
|
||||
//******* preamble correlation ********
|
||||
int32_t corr_value = 0;
|
||||
if ((d_symbol_history.size() == GPS_CA_PREAMBLE_LENGTH_SYMBOLS)) // and (d_make_correlation or !d_flag_frame_sync))
|
||||
if ((static_cast<int32_t>(d_symbol_history.size()) == d_preamble_length_symbols)) // and (d_make_correlation or !d_flag_frame_sync))
|
||||
{
|
||||
for (uint32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++)
|
||||
for (int32_t i = 0; i < d_preamble_length_symbols; i++)
|
||||
{
|
||||
if (d_symbol_history.at(i) < 0) // symbols clipping
|
||||
{
|
||||
corr_value -= d_gps_l1ca_preambles_symbols[i];
|
||||
corr_value -= d_preambles_symbols[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
corr_value += d_gps_l1ca_preambles_symbols[i];
|
||||
corr_value += d_preambles_symbols[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (corr_value == GPS_CA_PREAMBLE_LENGTH_SYMBOLS)
|
||||
if (corr_value == d_preamble_length_symbols)
|
||||
{
|
||||
//std::cout << "Preamble detected at tracking!" << std::endl;
|
||||
LOG(INFO) << systemName << " " << signal_pretty_name << " tracking preamble detected in channel " << d_channel
|
||||
<< " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl;
|
||||
next_state = true;
|
||||
}
|
||||
else
|
||||
@ -1492,6 +1572,7 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
|
||||
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt).imag());
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -107,7 +107,8 @@ private:
|
||||
std::string *d_secondary_code_string;
|
||||
std::string signal_pretty_name;
|
||||
|
||||
int32_t *d_gps_l1ca_preambles_symbols;
|
||||
int32_t *d_preambles_symbols;
|
||||
int32_t d_preamble_length_symbols;
|
||||
boost::circular_buffer<float> d_symbol_history;
|
||||
|
||||
//tracking state machine
|
||||
|
@ -38,6 +38,9 @@
|
||||
#include "gnss_block_factory.h"
|
||||
#include "array_signal_conditioner.h"
|
||||
#include "beamformer_filter.h"
|
||||
#include "beidou_b1i_dll_pll_tracking.h"
|
||||
#include "beidou_b1i_pcps_acquisition.h"
|
||||
#include "beidou_b1i_telemetry_decoder.h"
|
||||
#include "byte_to_short.h"
|
||||
#include "channel.h"
|
||||
#include "configuration_interface.h"
|
||||
@ -279,15 +282,19 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetObservables(std::shared
|
||||
GPS_channels += configuration->property("Channels_2S.count", 0);
|
||||
GPS_channels += configuration->property("Channels_L5.count", 0);
|
||||
unsigned int Glonass_channels = configuration->property("Channels_1G.count", 0);
|
||||
Glonass_channels += configuration->property("Channels_2G.count", 0);
|
||||
unsigned int Beidou_channels = configuration->property("Channels_B1.count", 0);
|
||||
unsigned int extra_channels = 1; // For monitor channel sample counter
|
||||
return GetBlock(configuration, "Observables", implementation,
|
||||
Galileo_channels +
|
||||
GPS_channels +
|
||||
Glonass_channels +
|
||||
Beidou_channels +
|
||||
extra_channels,
|
||||
Galileo_channels +
|
||||
GPS_channels +
|
||||
Glonass_channels);
|
||||
Glonass_channels +
|
||||
Beidou_channels);
|
||||
}
|
||||
|
||||
|
||||
@ -302,7 +309,10 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetPVT(std::shared_ptr<Con
|
||||
GPS_channels += configuration->property("Channels_2S.count", 0);
|
||||
GPS_channels += configuration->property("Channels_L5.count", 0);
|
||||
unsigned int Glonass_channels = configuration->property("Channels_1G.count", 0);
|
||||
return GetBlock(configuration, "PVT", implementation, Galileo_channels + GPS_channels + Glonass_channels, 0);
|
||||
Glonass_channels += configuration->property("Channels_2G.count", 0);
|
||||
unsigned int Beidou_channels = configuration->property("Channels_B1.count", 0);
|
||||
return GetBlock(configuration, "PVT", implementation,
|
||||
Galileo_channels + GPS_channels + Glonass_channels + Beidou_channels, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -775,6 +785,72 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_L5(
|
||||
}
|
||||
|
||||
|
||||
//********* BeiDou B1I CHANNEL *****************
|
||||
std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_B1(
|
||||
std::shared_ptr<ConfigurationInterface> configuration,
|
||||
std::string acq, std::string trk, std::string tlm, int channel,
|
||||
gr::msg_queue::sptr queue)
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << channel;
|
||||
std::string id = stream.str();
|
||||
LOG(INFO) << "Instantiating Channel " << id << " with Acquisition Implementation: "
|
||||
<< acq << ", Tracking Implementation: " << trk << ", Telemetry Decoder implementation: " << tlm;
|
||||
std::string aux = configuration->property("Acquisition_B1" + std::to_string(channel) + ".implementation", std::string("W"));
|
||||
std::string appendix1;
|
||||
if (aux != "W")
|
||||
{
|
||||
appendix1 = std::to_string(channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
appendix1 = "";
|
||||
}
|
||||
aux = configuration->property("Tracking_B1" + std::to_string(channel) + ".implementation", std::string("W"));
|
||||
std::string appendix2;
|
||||
if (aux != "W")
|
||||
{
|
||||
appendix2 = std::to_string(channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
appendix2 = "";
|
||||
}
|
||||
aux = configuration->property("TelemetryDecoder_B1" + std::to_string(channel) + ".implementation", std::string("W"));
|
||||
std::string appendix3;
|
||||
if (aux != "W")
|
||||
{
|
||||
appendix3 = std::to_string(channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
appendix3 = "";
|
||||
}
|
||||
// Automatically detect input data type
|
||||
std::shared_ptr<InMemoryConfiguration> config;
|
||||
config = std::make_shared<InMemoryConfiguration>();
|
||||
std::string default_item_type = "gr_complex";
|
||||
std::string acq_item_type = configuration->property("Acquisition_B1" + appendix1 + ".item_type", default_item_type);
|
||||
std::string trk_item_type = configuration->property("Tracking_B1" + appendix2 + ".item_type", default_item_type);
|
||||
if (acq_item_type != 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<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_B1" + appendix1, acq, 1, 0);
|
||||
std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_B1" + appendix2, trk, 1, 1);
|
||||
std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_B1" + appendix3, tlm, 1, 1);
|
||||
|
||||
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel,
|
||||
std::move(acq_),
|
||||
std::move(trk_),
|
||||
std::move(tlm_),
|
||||
"Channel", "B1", queue));
|
||||
|
||||
return channel_;
|
||||
}
|
||||
|
||||
std::unique_ptr<std::vector<std::unique_ptr<GNSSBlockInterface>>> GNSSBlockFactory::GetChannels(
|
||||
std::shared_ptr<ConfigurationInterface> configuration, gr::msg_queue::sptr queue)
|
||||
{
|
||||
@ -792,6 +868,7 @@ std::unique_ptr<std::vector<std::unique_ptr<GNSSBlockInterface>>> GNSSBlockFacto
|
||||
unsigned int Channels_2S_count = configuration->property("Channels_2S.count", 0);
|
||||
unsigned int Channels_5X_count = configuration->property("Channels_5X.count", 0);
|
||||
unsigned int Channels_L5_count = configuration->property("Channels_L5.count", 0);
|
||||
unsigned int Channels_B1_count = configuration->property("Channels_B1.count", 0);
|
||||
|
||||
unsigned int total_channels = Channels_1C_count +
|
||||
Channels_1B_count +
|
||||
@ -799,7 +876,8 @@ std::unique_ptr<std::vector<std::unique_ptr<GNSSBlockInterface>>> GNSSBlockFacto
|
||||
Channels_2S_count +
|
||||
Channels_2G_count +
|
||||
Channels_5X_count +
|
||||
Channels_L5_count;
|
||||
Channels_L5_count +
|
||||
Channels_B1_count;
|
||||
|
||||
std::unique_ptr<std::vector<std::unique_ptr<GNSSBlockInterface>>> channels(new std::vector<std::unique_ptr<GNSSBlockInterface>>(total_channels));
|
||||
try
|
||||
@ -1009,6 +1087,36 @@ std::unique_ptr<std::vector<std::unique_ptr<GNSSBlockInterface>>> GNSSBlockFacto
|
||||
queue);
|
||||
channel_absolute_id++;
|
||||
}
|
||||
|
||||
//**************** BEIDOU B1I CHANNELS **********************
|
||||
LOG(INFO) << "Getting " << Channels_B1_count << " BEIDOU B1I channels";
|
||||
acquisition_implementation = configuration->property("Acquisition_B1.implementation", default_implementation);
|
||||
tracking_implementation = configuration->property("Tracking_B1.implementation", default_implementation);
|
||||
telemetry_decoder_implementation = configuration->property("TelemetryDecoder_B1.implementation", default_implementation);
|
||||
|
||||
for (unsigned int i = 0; i < Channels_B1_count; i++)
|
||||
{
|
||||
//(i.e. Acquisition_2G0.implementation=xxxx)
|
||||
std::string acquisition_implementation_specific = configuration->property(
|
||||
"Acquisition_B1" + std::to_string(channel_absolute_id) + ".implementation",
|
||||
acquisition_implementation);
|
||||
//(i.e. Tracking_2G0.implementation=xxxx)
|
||||
std::string tracking_implementation_specific = configuration->property(
|
||||
"Tracking_B1" + std::to_string(channel_absolute_id) + ".implementation",
|
||||
tracking_implementation);
|
||||
std::string telemetry_decoder_implementation_specific = configuration->property(
|
||||
"TelemetryDecoder_B1" + std::to_string(channel_absolute_id) + ".implementation",
|
||||
telemetry_decoder_implementation);
|
||||
|
||||
// Push back the channel to the vector of channels
|
||||
channels->at(channel_absolute_id) = GetChannel_B1(configuration,
|
||||
acquisition_implementation_specific,
|
||||
tracking_implementation_specific,
|
||||
telemetry_decoder_implementation_specific,
|
||||
channel_absolute_id,
|
||||
queue);
|
||||
channel_absolute_id++;
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
@ -1487,6 +1595,13 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation == "BEIDOU_B1I_PCPS_Acquisition")
|
||||
{
|
||||
std::unique_ptr<AcquisitionInterface> block_(new BeidouB1iPcpsAcquisition(configuration.get(), role, in_streams,
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
|
||||
// TRACKING BLOCKS -------------------------------------------------------------
|
||||
else if (implementation == "GPS_L1_CA_DLL_PLL_Tracking")
|
||||
{
|
||||
@ -1614,6 +1729,12 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation == "BEIDOU_B1I_DLL_PLL_Tracking")
|
||||
{
|
||||
std::unique_ptr<GNSSBlockInterface> block_(new BeidouB1iDllPllTracking(configuration.get(), role, in_streams,
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
// TELEMETRY DECODERS ----------------------------------------------------------
|
||||
else if (implementation == "GPS_L1_CA_Telemetry_Decoder")
|
||||
{
|
||||
@ -1663,6 +1784,13 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation == "BEIDOU_B1I_Telemetry_Decoder")
|
||||
{
|
||||
std::unique_ptr<GNSSBlockInterface> block_(new BeidouB1iTelemetryDecoder(configuration.get(), role, in_streams,
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
|
||||
// OBSERVABLES -----------------------------------------------------------------
|
||||
else if ((implementation == "Hybrid_Observables") || (implementation == "GPS_L1_CA_Observables") || (implementation == "GPS_L2C_Observables") ||
|
||||
(implementation == "Galileo_E5A_Observables"))
|
||||
@ -1851,6 +1979,13 @@ std::unique_ptr<AcquisitionInterface> GNSSBlockFactory::GetAcqBlock(
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation == "BEIDOU_B1I_PCPS_Acquisition")
|
||||
{
|
||||
std::unique_ptr<AcquisitionInterface> block_(new BeidouB1iPcpsAcquisition(configuration.get(), role, in_streams,
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// Log fatal. This causes execution to stop.
|
||||
@ -1995,6 +2130,13 @@ std::unique_ptr<TrackingInterface> GNSSBlockFactory::GetTrkBlock(
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation == "BEIDOU_B1I_DLL_PLL_Tracking")
|
||||
{
|
||||
std::unique_ptr<TrackingInterface> block_(new BeidouB1iDllPllTracking(configuration.get(), role, in_streams,
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// Log fatal. This causes execution to stop.
|
||||
@ -2061,6 +2203,14 @@ std::unique_ptr<TelemetryDecoderInterface> GNSSBlockFactory::GetTlmBlock(
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation == "BEIDOU_B1I_Telemetry_Decoder")
|
||||
{
|
||||
std::unique_ptr<TelemetryDecoderInterface> block_(new BeidouB1iTelemetryDecoder(configuration.get(), role, in_streams,
|
||||
out_streams));
|
||||
block = std::move(block_);
|
||||
}
|
||||
|
||||
|
||||
else
|
||||
{
|
||||
// Log fatal. This causes execution to stop.
|
||||
|
@ -106,6 +106,10 @@ private:
|
||||
std::string acq, std::string trk, std::string tlm, int channel,
|
||||
boost::shared_ptr<gr::msg_queue> queue);
|
||||
|
||||
std::unique_ptr<GNSSBlockInterface> GetChannel_B1(std::shared_ptr<ConfigurationInterface> configuration,
|
||||
std::string acq, std::string trk, std::string tlm, int channel,
|
||||
boost::shared_ptr<gr::msg_queue> queue);
|
||||
|
||||
std::unique_ptr<AcquisitionInterface> GetAcqBlock(
|
||||
std::shared_ptr<ConfigurationInterface> configuration,
|
||||
std::string role,
|
||||
|
@ -289,8 +289,7 @@ void GNSSFlowgraph::connect()
|
||||
std::cout << "Set GNSS-SDR.internal_fs_sps in configuration file" << std::endl;
|
||||
throw(std::invalid_argument("Set GNSS-SDR.internal_fs_sps in configuration"));
|
||||
}
|
||||
int observable_interval_ms = static_cast<double>(configuration_->property("GNSS-SDR.observable_interval_ms", 20));
|
||||
ch_out_sample_counter = gnss_sdr_make_sample_counter(fs, observable_interval_ms, sig_conditioner_.at(0)->get_right_block()->output_signature()->sizeof_stream_item(0));
|
||||
ch_out_sample_counter = gnss_sdr_make_sample_counter(fs, sig_conditioner_.at(0)->get_right_block()->output_signature()->sizeof_stream_item(0));
|
||||
top_block_->connect(sig_conditioner_.at(0)->get_right_block(), 0, ch_out_sample_counter, 0);
|
||||
top_block_->connect(ch_out_sample_counter, 0, observables_->get_left_block(), channels_count_); //extra port for the sample counter pulse
|
||||
}
|
||||
@ -403,6 +402,9 @@ void GNSSFlowgraph::connect()
|
||||
case evGLO_2G:
|
||||
acq_fs = fs;
|
||||
break;
|
||||
case evBDS_B1:
|
||||
acq_fs = fs;
|
||||
break;
|
||||
}
|
||||
|
||||
if (acq_fs < fs)
|
||||
@ -598,6 +600,12 @@ void GNSSFlowgraph::connect()
|
||||
available_GLO_2G_signals_.remove(signal_value);
|
||||
break;
|
||||
|
||||
case evBDS_B1:
|
||||
gnss_system = "Beidou";
|
||||
signal_value = Gnss_Signal(Gnss_Satellite(gnss_system, sat), gnss_signal);
|
||||
available_BDS_B1_signals_.remove(signal_value);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(ERROR) << "This should not happen :-(";
|
||||
gnss_system = "GPS";
|
||||
@ -1015,6 +1023,10 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
|
||||
available_GLO_2G_signals_.push_back(gs);
|
||||
break;
|
||||
|
||||
case evBDS_B1:
|
||||
available_BDS_B1_signals_.push_back(channels_[who]->get_signal());
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(ERROR) << "This should not happen :-(";
|
||||
break;
|
||||
@ -1083,6 +1095,10 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
|
||||
available_GLO_2G_signals_.remove(channels_[who]->get_signal());
|
||||
break;
|
||||
|
||||
case evBDS_B1:
|
||||
available_BDS_B1_signals_.remove(channels_[who]->get_signal());
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(ERROR) << "This should not happen :-(";
|
||||
break;
|
||||
@ -1163,6 +1179,10 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
|
||||
available_GLO_2G_signals_.push_back(channels_[who]->get_signal());
|
||||
break;
|
||||
|
||||
case evBDS_B1:
|
||||
available_BDS_B1_signals_.push_back(channels_[who]->get_signal());
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(ERROR) << "This should not happen :-(";
|
||||
break;
|
||||
@ -1492,6 +1512,7 @@ void GNSSFlowgraph::init()
|
||||
mapStringValues_["5X"] = evGAL_5X;
|
||||
mapStringValues_["1G"] = evGLO_1G;
|
||||
mapStringValues_["2G"] = evGLO_2G;
|
||||
mapStringValues_["B1"] = evBDS_B1;
|
||||
|
||||
// fill the signals queue with the satellites ID's to be searched by the acquisition
|
||||
set_signals_list();
|
||||
@ -1538,6 +1559,10 @@ void GNSSFlowgraph::set_signals_list()
|
||||
// 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<unsigned int> available_glonass_prn = {1, 2, 3, 4, 9, 10, 11, 12, 18, 19, 20, 21, 24};
|
||||
|
||||
std::set<unsigned int> available_beidou_prn = {1, 2, 3, 4, 5, 6, 7, 8, 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};
|
||||
|
||||
std::string sv_list = configuration_->property("Galileo.prns", std::string(""));
|
||||
|
||||
if (sv_list.length() > 0)
|
||||
@ -1601,6 +1626,23 @@ void GNSSFlowgraph::set_signals_list()
|
||||
available_glonass_prn = tmp_set;
|
||||
}
|
||||
}
|
||||
sv_list = configuration_->property("Beidou.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<unsigned int, std::string>);
|
||||
|
||||
if (tmp_set.size() > 0)
|
||||
{
|
||||
available_beidou_prn = tmp_set;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (configuration_->property("Channels_1C.count", 0) > 0)
|
||||
{
|
||||
@ -1705,6 +1747,21 @@ void GNSSFlowgraph::set_signals_list()
|
||||
std::string("2G")));
|
||||
}
|
||||
}
|
||||
|
||||
if (configuration_->property("Channels_B1.count", 0) > 0)
|
||||
{
|
||||
/*
|
||||
* Loop to create the list of BeiDou B1C signals
|
||||
*/
|
||||
for (available_gnss_prn_iter = available_beidou_prn.cbegin();
|
||||
available_gnss_prn_iter != available_beidou_prn.cend();
|
||||
available_gnss_prn_iter++)
|
||||
{
|
||||
available_BDS_B1_signals_.push_back(Gnss_Signal(
|
||||
Gnss_Satellite(std::string("Beidou"), *available_gnss_prn_iter),
|
||||
std::string("B1")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1934,6 +1991,32 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(const std::string& searched_signal
|
||||
}
|
||||
break;
|
||||
|
||||
case evBDS_B1:
|
||||
result = available_BDS_B1_signals_.front();
|
||||
available_BDS_B1_signals_.pop_front();
|
||||
if (!pop)
|
||||
{
|
||||
available_BDS_B1_signals_.push_back(result);
|
||||
}
|
||||
if (tracked)
|
||||
{
|
||||
// In the near future Beidou B2a will be added
|
||||
// if (configuration_->property("Channels_5C.count", 0) > 0)
|
||||
// {
|
||||
// for (unsigned int ch = 0; ch < channels_count_; ch++)
|
||||
// {
|
||||
// if ((channels_[ch]->get_signal().get_satellite() == result.get_satellite()) and (channels_[ch]->get_signal().get_signal_str().compare("5C") != 0)) untracked_satellite = false;
|
||||
// }
|
||||
// if (untracked_satellite)
|
||||
// {
|
||||
// Gnss_Signal gs = Gnss_Signal(result.get_satellite(), "5C");
|
||||
// available_BDS_5C_signals_.remove(gs);
|
||||
// available_BDS_5C_signals_.push_front(gs);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(ERROR) << "This should not happen :-(";
|
||||
result = available_GPS_1C_signals_.front();
|
||||
|
@ -55,7 +55,6 @@
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#if ENABLE_FPGA
|
||||
#include "gnss_sdr_fpga_sample_counter.h"
|
||||
@ -184,6 +183,7 @@ private:
|
||||
std::list<Gnss_Signal> available_GAL_5X_signals_;
|
||||
std::list<Gnss_Signal> available_GLO_1G_signals_;
|
||||
std::list<Gnss_Signal> available_GLO_2G_signals_;
|
||||
std::list<Gnss_Signal> available_BDS_B1_signals_;
|
||||
enum StringValue
|
||||
{
|
||||
evGPS_1C,
|
||||
@ -193,7 +193,8 @@ private:
|
||||
evGAL_1B,
|
||||
evGAL_5X,
|
||||
evGLO_1G,
|
||||
evGLO_2G
|
||||
evGLO_2G,
|
||||
evBDS_B1
|
||||
};
|
||||
std::map<std::string, StringValue> mapStringValues_;
|
||||
|
||||
|
346
src/core/system_parameters/Beidou_B1I.h
Normal file
346
src/core/system_parameters/Beidou_B1I.h
Normal file
@ -0,0 +1,346 @@
|
||||
/*!
|
||||
* \file beidou_b1I.h
|
||||
* \brief Defines system parameters for BeiDou B1I signal and DNAV data
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
|
||||
* \author Damian Miralles, 2018. dmiralles2009@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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GNSS_SDR_BEIDOU_B1I_H_
|
||||
#define GNSS_SDR_BEIDOU_B1I_H_
|
||||
|
||||
#include "MATH_CONSTANTS.h"
|
||||
#include <utility> // std::pair
|
||||
#include <vector>
|
||||
|
||||
// Physical constants
|
||||
const double BEIDOU_C_m_s = 299792458.0; //!< The speed of light, [m/s]
|
||||
const double BEIDOU_C_m_ms = 299792.4580; //!< The speed of light, [m/ms]
|
||||
const double BEIDOU_PI = 3.1415926535898; //!< Pi
|
||||
const double BEIDOU_TWO_PI = 6.283185307179586; //!< 2Pi
|
||||
const double BEIDOU_OMEGA_EARTH_DOT = 7.2921150e-5; //!< Earth rotation rate, [rad/s] as defined in CGCS2000
|
||||
const double BEIDOU_GM = 3.986004418e14; //!< Universal gravitational constant times the mass of the Earth, [m^3/s^2] as defined in CGCS2000
|
||||
const double BEIDOU_F = -4.442807309e-10; //!< Constant, [s/(m)^(1/2)] F=-2(GM)^.5/C^2
|
||||
|
||||
|
||||
// carrier and code frequencies
|
||||
const double BEIDOU_B1I_FREQ_HZ = 1.561098e9; //!< b1I [Hz]
|
||||
const double BEIDOU_B1I_CODE_RATE_HZ = 2.046e6; //!< beidou b1I code rate [chips/s]
|
||||
const double BEIDOU_B1I_CODE_LENGTH_CHIPS = 2046.0; //!< beidou b1I code length [chips]
|
||||
const double BEIDOU_B1I_CODE_PERIOD = 0.001; //!< beidou b1I code period [seconds]
|
||||
const unsigned int BEIDOU_B1I_CODE_PERIOD_MS = 1; //!< GPS L1 C/A code period [ms]
|
||||
const double BEIDOU_B1I_CHIP_PERIOD = 4.8875e-07; //!< beidou b1I chip period [seconds]
|
||||
const int BEIDOU_B1I_SECONDARY_CODE_LENGTH = 20;
|
||||
const std::string BEIDOU_B1I_SECONDARY_CODE = "00000100110101001110";
|
||||
const std::string BEIDOU_B1I_SECONDARY_CODE_STR = "00000100110101001110";
|
||||
const std::string BEIDOU_B1I_D2_SECONDARY_CODE_STR = "00";
|
||||
|
||||
/*!
|
||||
* \brief Maximum Time-Of-Arrival (TOA) difference between satellites for a receiver operated on Earth surface is 20 ms
|
||||
*
|
||||
* According to the GPS orbit model described in [1] Pag. 32.
|
||||
* It should be taken into account to set the buffer size for the PRN start timestamp in the pseudoranges block.
|
||||
* [1] J. Bao-Yen Tsui, Fundamentals of Global Positioning System Receivers. A Software Approach, John Wiley & Sons,
|
||||
* Inc., Hoboken, NJ, 2nd edition, 2005.
|
||||
*/
|
||||
const double BEIDOU_MAX_TOA_DELAY_MS = 20; //******************
|
||||
|
||||
//#define NAVIGATION_SOLUTION_RATE_MS 1000 // this cannot go here
|
||||
const double BEIDOU_STARTOFFSET_ms = 68.802; //**************[ms] Initial sign. travel time (this cannot go here)
|
||||
|
||||
|
||||
// OBSERVABLE HISTORY DEEP FOR INTERPOLATION
|
||||
const int BEIDOU_B1I_HISTORY_DEEP = 100; // ****************
|
||||
|
||||
// NAVIGATION MESSAGE DEMODULATION AND DECODING
|
||||
|
||||
const int BEIDOU_B1I_PREAMBLE_LENGTH_BITS = 11;
|
||||
const int BEIDOU_B1I_PREAMBLE_LENGTH_SYMBOLS = 220; // **************
|
||||
const double BEIDOU_B1I_PREAMBLE_DURATION_S = 0.220;
|
||||
const int BEIDOU_B1I_PREAMBLE_DURATION_MS = 220;
|
||||
const int BEIDOU_B1I_TELEMETRY_RATE_BITS_SECOND = 50; //!< D1 NAV message bit rate [bits/s]
|
||||
const int BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT = 20; // *************
|
||||
const int BEIDOU_B1I_TELEMETRY_RATE_SYMBOLS_SECOND = BEIDOU_B1I_TELEMETRY_RATE_BITS_SECOND * BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT; //************!< NAV message bit rate [symbols/s]
|
||||
const int BEIDOU_WORD_LENGTH = 4; //**************!< CRC + BEIDOU WORD (-2 -1 0 ... 29) Bits = 4 bytes
|
||||
const int BEIDOU_SUBFRAME_LENGTH = 40; //**************!< BEIDOU_WORD_LENGTH x 10 = 40 bytes
|
||||
const int BEIDOU_DNAV_SUBFRAME_DATA_BITS = 300; //!< Number of bits per subframe in the NAV message [bits]
|
||||
const int BEIDOU_SUBFRAME_SECONDS = 6; //!< Subframe duration [seconds]
|
||||
const int BEIDOU_SUBFRAME_MS = 6000; //!< Subframe duration [miliseconds]
|
||||
const int BEIDOU_WORD_BITS = 30; //!< Number of bits per word in the NAV message [bits]
|
||||
|
||||
const std::string BEIDOU_DNAV_PREAMBLE = "11100010010";
|
||||
const int BEIDOU_DNAV_PREAMBLE_LENGTH_BITS = 11;
|
||||
const int BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS = 11; // **************
|
||||
const double BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS = 300;
|
||||
const double BEIDOU_DNAV_SUBFRAME_SYMBOLS = 300;
|
||||
const double BEIDOU_DNAV_DATA_BITS = 300;
|
||||
const double BEIDOU_DNAV_WORDS_SUBFRAME = 10;
|
||||
const double BEIDOU_DNAV_WORD_LENGTH_BITS = 30;
|
||||
|
||||
const double BEIDOU_D1NAV_SYMBOL_RATE_SPS = 50;
|
||||
const double BEIDOU_D2NAV_SYMBOL_RATE_SPS = 500;
|
||||
const double BEIDOU_B1I_PREAMBLE_PERIOD_SYMBOLS = 300;
|
||||
|
||||
// BEIDOU D1 NAVIGATION MESSAGE STRUCTURE
|
||||
// GENERAL
|
||||
const std::vector<std::pair<int, int> > D1_PRE({{1, 11}});
|
||||
const std::vector<std::pair<int, int> > D1_FRAID({{16, 3}});
|
||||
const std::vector<std::pair<int, int> > D1_SOW({{19, 8}, {31, 12}});
|
||||
const std::vector<std::pair<int, int> > D1_PNUM({{44, 7}});
|
||||
|
||||
// DNAV SCALE FACTORS
|
||||
// EPH
|
||||
const double D1_TOC_LSB = TWO_P3;
|
||||
const double D1_TGD1_LSB = 0.1e-9;
|
||||
const double D1_TGD2_LSB = 0.1e-9;
|
||||
const double D1_ALPHA0_LSB = TWO_N30;
|
||||
const double D1_ALPHA1_LSB = TWO_N27;
|
||||
const double D1_ALPHA2_LSB = TWO_N24;
|
||||
const double D1_ALPHA3_LSB = TWO_N24;
|
||||
const double D1_BETA0_LSB = TWO_P11;
|
||||
const double D1_BETA1_LSB = TWO_P14;
|
||||
const double D1_BETA2_LSB = TWO_P16;
|
||||
const double D1_BETA3_LSB = TWO_P16;
|
||||
const double D1_A2_LSB = TWO_N66;
|
||||
const double D1_A0_LSB = TWO_N33;
|
||||
const double D1_A1_LSB = TWO_N50;
|
||||
const double D1_DELTA_N_LSB = PI_TWO_N43;
|
||||
const double D1_CUC_LSB = TWO_N31;
|
||||
const double D1_M0_LSB = PI_TWO_N31;
|
||||
const double D1_E_LSB = TWO_N33;
|
||||
const double D1_CUS_LSB = TWO_N31;
|
||||
const double D1_CRC_LSB = TWO_N6;
|
||||
const double D1_CRS_LSB = TWO_N6;
|
||||
const double D1_SQRT_A_LSB = TWO_N19;
|
||||
const double D1_TOE_LSB = TWO_P3;
|
||||
const double D1_I0_LSB = PI_TWO_N31;
|
||||
const double D1_CIC_LSB = TWO_N31;
|
||||
const double D1_OMEGA_DOT_LSB = PI_TWO_N43;
|
||||
const double D1_CIS_LSB = TWO_N31;
|
||||
const double D1_IDOT_LSB = PI_TWO_N43;
|
||||
const double D1_OMEGA0_LSB = PI_TWO_N31;
|
||||
const double D1_OMEGA_LSB = PI_TWO_N31;
|
||||
//ALM
|
||||
const double D1_SQRT_A_ALMANAC_LSB = TWO_N11;
|
||||
const double D1_A1_ALMANAC_LSB = TWO_N38;
|
||||
const double D1_A0_ALMANAC_LSB = TWO_N20;
|
||||
const double D1_OMEGA0_ALMANAC_LSB = PI_TWO_N23;
|
||||
const double D1_E_ALMANAC_LSB = TWO_N21;
|
||||
const double D1_DELTA_I_LSB = PI_TWO_N19;
|
||||
const double D1_TOA_LSB = TWO_P12;
|
||||
const double D1_OMEGA_DOT_ALMANAC_LSB = PI_TWO_N38;
|
||||
const double D1_OMEGA_ALMANAC_LSB = PI_TWO_N23;
|
||||
const double D1_M0_ALMANAC_LSB = PI_TWO_N23;
|
||||
const double D1_A0GPS_LSB = 0.1e-9;
|
||||
const double D1_A1GPS_LSB = 0.1e-9;
|
||||
const double D1_A0GAL_LSB = 0.1e-9;
|
||||
const double D1_A1GAL_LSB = 0.1e-9;
|
||||
const double D1_A0GLO_LSB = 0.1e-9;
|
||||
const double D1_A1GLO_LSB = 0.1e-9;
|
||||
const double D1_A0UTC_LSB = TWO_N30;
|
||||
const double D1_A1UTC_LSB = TWO_N50;
|
||||
|
||||
// SUBFRAME 1
|
||||
const std::vector<std::pair<int, int> > D1_SAT_H1({{43, 1}});
|
||||
const std::vector<std::pair<int, int> > D1_AODC({{44, 5}});
|
||||
const std::vector<std::pair<int, int> > D1_URAI({{49, 4}});
|
||||
const std::vector<std::pair<int, int> > D1_WN({{61, 13}});
|
||||
const std::vector<std::pair<int, int> > D1_TOC({{74, 9}, {91, 8}});
|
||||
const std::vector<std::pair<int, int> > D1_TGD1({{99, 10}});
|
||||
const std::vector<std::pair<int, int> > D1_TGD2({{121, 6}});
|
||||
const std::vector<std::pair<int, int> > D1_ALPHA0({{127, 8}});
|
||||
const std::vector<std::pair<int, int> > D1_ALPHA1({{135, 8}});
|
||||
const std::vector<std::pair<int, int> > D1_ALPHA2({{151, 8}});
|
||||
const std::vector<std::pair<int, int> > D1_ALPHA3({{159, 8}});
|
||||
const std::vector<std::pair<int, int> > D1_BETA0({{167, 6}, {181, 2}});
|
||||
const std::vector<std::pair<int, int> > D1_BETA1({{183, 8}});
|
||||
const std::vector<std::pair<int, int> > D1_BETA2({{191, 8}});
|
||||
const std::vector<std::pair<int, int> > D1_BETA3({{199, 4}, {211, 4}});
|
||||
const std::vector<std::pair<int, int> > D1_A2({{215, 11}});
|
||||
const std::vector<std::pair<int, int> > D1_A0({{226, 7}, {241, 17}});
|
||||
const std::vector<std::pair<int, int> > D1_A1({{258, 5}, {271, 17}});
|
||||
const std::vector<std::pair<int, int> > D1_AODE({{288, 5}});
|
||||
|
||||
//SUBFRAME 2
|
||||
const std::vector<std::pair<int, int> > D1_DELTA_N({{43, 10}, {61, 6}});
|
||||
const std::vector<std::pair<int, int> > D1_CUC({{67, 16}, {91, 2}});
|
||||
const std::vector<std::pair<int, int> > D1_M0({{93, 20}, {121, 12}});
|
||||
const std::vector<std::pair<int, int> > D1_E({{133, 10}, {151, 22}});
|
||||
const std::vector<std::pair<int, int> > D1_CUS({{181, 18}});
|
||||
const std::vector<std::pair<int, int> > D1_CRC({{199, 4}, {211, 14}});
|
||||
const std::vector<std::pair<int, int> > D1_CRS({{225, 8}, {241, 10}});
|
||||
const std::vector<std::pair<int, int> > D1_SQRT_A({{251, 12}, {271, 20}});
|
||||
const std::vector<std::pair<int, int> > D1_TOE_SF2({{291, 2}});
|
||||
|
||||
//SUBFRAME 3
|
||||
const std::vector<std::pair<int, int> > D1_TOE_SF3({{43, 10}, {61, 5}});
|
||||
const std::vector<std::pair<int, int> > D1_I0({{66, 17}, {91, 15}});
|
||||
const std::vector<std::pair<int, int> > D1_CIC({{106, 7}, {121, 11}});
|
||||
const std::vector<std::pair<int, int> > D1_OMEGA_DOT({{132, 11}, {151, 13}});
|
||||
const std::vector<std::pair<int, int> > D1_CIS({{164, 9}, {181, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_IDOT({{190, 13}, {211, 1}});
|
||||
const std::vector<std::pair<int, int> > D1_OMEGA0({{212, 21}, {241, 11}});
|
||||
const std::vector<std::pair<int, int> > D1_OMEGA({{252, 11}, {271, 21}});
|
||||
|
||||
//SUBFRAME 4 AND PAGES 1 THROUGH 6 IN SUBFRAME 5
|
||||
const std::vector<std::pair<int, int> > D1_SQRT_A_ALMANAC({{51, 2}, {61, 22}});
|
||||
const std::vector<std::pair<int, int> > D1_A1_ALMANAC({{91, 11}});
|
||||
const std::vector<std::pair<int, int> > D1_A0_ALMANAC({{102, 11}});
|
||||
const std::vector<std::pair<int, int> > D1_OMEGA0_ALMANAC({{121, 22}, {151, 2}});
|
||||
const std::vector<std::pair<int, int> > D1_E_ALMANAC({{153, 17}});
|
||||
const std::vector<std::pair<int, int> > D1_DELTA_I({{170, 3}, {181, 13}});
|
||||
const std::vector<std::pair<int, int> > D1_TOA({{194, 8}});
|
||||
const std::vector<std::pair<int, int> > D1_OMEGA_DOT_ALMANAC({{202, 1}, {211, 16}});
|
||||
const std::vector<std::pair<int, int> > D1_OMEGA_ALMANAC({{227, 6}, {241, 18}});
|
||||
const std::vector<std::pair<int, int> > D1_M0_ALMANAC({{259, 4}, {271, 20}});
|
||||
|
||||
//SUBFRAME 5 PAGE 7
|
||||
const std::vector<std::pair<int, int> > D1_HEA1({{51, 2}, {61, 7}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA2({{68, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA3({{77, 6}, {91, 3}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA4({{94, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA5({{103, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA6({{112, 1}, {121, 8}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA7({{129, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA8({{138, 5}, {151, 4}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA9({{155, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA10({{164, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA11({{181, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA12({{190, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA13({{199, 4}, {211, 5}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA14({{216, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA15({{225, 8}, {241, 1}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA16({{242, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA17({{251, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA18({{260, 3}, {271, 6}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA19({{277, 9}});
|
||||
|
||||
//SUBFRAME 5 PAGE 8
|
||||
const std::vector<std::pair<int, int> > D1_HEA20({{51, 2}, {61, 7}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA21({{68, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA22({{77, 6}, {91, 3}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA23({{94, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA24({{103, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA25({{112, 1}, {121, 8}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA26({{129, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA27({{138, 5}, {151, 4}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA28({{155, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA29({{164, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_HEA30({{181, 9}});
|
||||
const std::vector<std::pair<int, int> > D1_WNA({{190, 8}});
|
||||
const std::vector<std::pair<int, int> > D1_TOA2({{198, 5}, {211, 3}});
|
||||
|
||||
//SUBFRAME 5 PAGE 9
|
||||
const std::vector<std::pair<int, int> > D1_A0GPS({{97, 14}});
|
||||
const std::vector<std::pair<int, int> > D1_A1GPS({{111, 2}, {121, 14}});
|
||||
const std::vector<std::pair<int, int> > D1_A0GAL({{135, 8}, {151, 6}});
|
||||
const std::vector<std::pair<int, int> > D1_A1GAL({{157, 16}});
|
||||
const std::vector<std::pair<int, int> > D1_A0GLO({{181, 14}});
|
||||
const std::vector<std::pair<int, int> > D1_A1GLO({{195, 8}, {211, 8}});
|
||||
|
||||
//SUBFRAME 5 PAGE 10
|
||||
const std::vector<std::pair<int, int> > D1_DELTA_T_LS({{51, 2}, {61, 6}});
|
||||
const std::vector<std::pair<int, int> > D1_DELTA_T_LSF({{67, 8}});
|
||||
const std::vector<std::pair<int, int> > D1_WN_LSF({{75, 8}});
|
||||
const std::vector<std::pair<int, int> > D1_A0UTC({{91, 22}, {121, 10}});
|
||||
const std::vector<std::pair<int, int> > D1_A1UTC({{131, 12}, {151, 12}});
|
||||
const std::vector<std::pair<int, int> > D1_DN({{163, 8}});
|
||||
|
||||
// D2 NAV Message Decoding Information
|
||||
const std::vector<std::pair<int, int> > D2_PRE({{1, 11}});
|
||||
const std::vector<std::pair<int, int> > D2_FRAID({{16, 3}});
|
||||
const std::vector<std::pair<int, int> > D2_SOW({{19, 8}, {31, 12}});
|
||||
const std::vector<std::pair<int, int> > D2_PNUM({{43, 4}});
|
||||
|
||||
// D2 NAV, SUBFRAME 1, PAGE 1
|
||||
const std::vector<std::pair<int, int> > D2_SAT_H1({{47, 1}});
|
||||
const std::vector<std::pair<int, int> > D2_AODC({{48, 5}});
|
||||
const std::vector<std::pair<int, int> > D2_URAI({{61, 4}});
|
||||
const std::vector<std::pair<int, int> > D2_WN({{65, 13}});
|
||||
const std::vector<std::pair<int, int> > D2_TOC({{78, 5}, {91, 12}});
|
||||
const std::vector<std::pair<int, int> > D2_TGD1({{103, 10}});
|
||||
const std::vector<std::pair<int, int> > D2_TGD2({{121, 10}});
|
||||
|
||||
// D2 NAV, SUBFRAME 1, PAGE 2
|
||||
const std::vector<std::pair<int, int> > D2_ALPHA0({{47, 6}, {61, 2}});
|
||||
const std::vector<std::pair<int, int> > D2_ALPHA1({{63, 8}});
|
||||
const std::vector<std::pair<int, int> > D2_ALPHA2({{71, 8}});
|
||||
const std::vector<std::pair<int, int> > D2_ALPHA3({{79, 4}, {91, 4}});
|
||||
const std::vector<std::pair<int, int> > D2_BETA0({{95, 8}});
|
||||
const std::vector<std::pair<int, int> > D2_BETA1({{103, 8}});
|
||||
const std::vector<std::pair<int, int> > D2_BETA2({{111, 2}, {121, 6}});
|
||||
const std::vector<std::pair<int, int> > D2_BETA3({{127, 8}});
|
||||
|
||||
// D2 NAV, SUBFRAME 1, PAGE 3
|
||||
const std::vector<std::pair<int, int> > D2_A0({{101, 12}, {121, 12}});
|
||||
const std::vector<std::pair<int, int> > D2_A1_MSB({{133, 4}});
|
||||
const std::vector<std::pair<int, int> > D2_A1_LSB({{47, 6}, {61, 12}});
|
||||
const std::vector<std::pair<int, int> > D2_A1({{279, 22}});
|
||||
|
||||
// D2 NAV, SUBFRAME 1, PAGE 4
|
||||
const std::vector<std::pair<int, int> > D2_A2({{73, 10}, {91, 1}});
|
||||
const std::vector<std::pair<int, int> > D2_AODE({{92, 5}});
|
||||
const std::vector<std::pair<int, int> > D2_DELTA_N({{97, 16}});
|
||||
const std::vector<std::pair<int, int> > D2_CUC_MSB({{121, 14}});
|
||||
const std::vector<std::pair<int, int> > D2_CUC_LSB({{47, 4}});
|
||||
const std::vector<std::pair<int, int> > D2_CUC({{283, 18}});
|
||||
|
||||
// D2 NAV, SUBFRAME 1, PAGE 5
|
||||
const std::vector<std::pair<int, int> > D2_M0({{51, 2}, {61, 22}, {91, 8}});
|
||||
const std::vector<std::pair<int, int> > D2_CUS({{99, 14}, {121, 4}});
|
||||
const std::vector<std::pair<int, int> > D2_E_MSB({{125, 10}});
|
||||
|
||||
// D2 NAV, SUBFRAME 1, PAGE 6
|
||||
const std::vector<std::pair<int, int> > D2_E_LSB({{47, 6}, {61, 16}});
|
||||
const std::vector<std::pair<int, int> > D2_SQRT_A({{77, 6}, {91, 22}, {121, 4}});
|
||||
const std::vector<std::pair<int, int> > D2_CIC_MSB({{125, 10}});
|
||||
const std::vector<std::pair<int, int> > D2_CIC_LSB({{47, 6}, {61, 2}});
|
||||
const std::vector<std::pair<int, int> > D2_CIC({{283, 18}});
|
||||
|
||||
// D2 NAV, SUBFRAME 1, PAGE 7
|
||||
const std::vector<std::pair<int, int> > D2_CIS({{63, 18}});
|
||||
const std::vector<std::pair<int, int> > D2_TOE({{81, 2}, {91, 15}});
|
||||
const std::vector<std::pair<int, int> > D2_I0_MSB({{106, 7}, {121, 14}});
|
||||
const std::vector<std::pair<int, int> > D2_I0_LSB({{47, 6}, {61, 5}});
|
||||
const std::vector<std::pair<int, int> > D2_I0({{269, 32}});
|
||||
|
||||
// D2 NAV, SUBFRAME 1, PAGE 8
|
||||
const std::vector<std::pair<int, int> > D2_CRC({{66, 17}, {91, 1}});
|
||||
const std::vector<std::pair<int, int> > D2_CRS({{92, 18}});
|
||||
const std::vector<std::pair<int, int> > D2_OMEGA_DOT_MSB({{110, 3}, {121, 16}});
|
||||
const std::vector<std::pair<int, int> > D2_OMEGA_DOT_LSB({{47, 5}});
|
||||
const std::vector<std::pair<int, int> > D2_OMEGA_DOT({{277, 24}});
|
||||
|
||||
// D2 NAV, SUBFRAME 1, PAGE 9
|
||||
const std::vector<std::pair<int, int> > D2_OMEGA0({{52, 1}, {61, 22}, {91, 9}});
|
||||
const std::vector<std::pair<int, int> > D2_OMEGA_MSB({{100, 13}, {121, 14}});
|
||||
const std::vector<std::pair<int, int> > D2_OMEGA_LSB({{47, 5}});
|
||||
const std::vector<std::pair<int, int> > D2_OMEGA({{269, 32}});
|
||||
|
||||
// D2 NAV, SUBFRAME 1, PAGE 10
|
||||
const std::vector<std::pair<int, int> > D2_IDOT({{52, 1}, {61, 13}});
|
||||
|
||||
#endif /* GNSS_SDR_BEIDOU_B1I_H_ */
|
@ -34,6 +34,11 @@ set(SYSTEM_PARAMETERS_SOURCES
|
||||
galileo_almanac_helper.cc
|
||||
galileo_iono.cc
|
||||
galileo_navigation_message.cc
|
||||
beidou_dnav_navigation_message.cc
|
||||
beidou_dnav_ephemeris.cc
|
||||
beidou_dnav_iono.cc
|
||||
beidou_dnav_almanac.cc
|
||||
beidou_dnav_utc_model.cc
|
||||
sbas_ephemeris.cc
|
||||
galileo_fnav_message.cc
|
||||
gps_cnav_ephemeris.cc
|
||||
@ -75,6 +80,11 @@ set(SYSTEM_PARAMETERS_HEADERS
|
||||
glonass_gnav_almanac.h
|
||||
glonass_gnav_utc_model.h
|
||||
glonass_gnav_navigation_message.h
|
||||
beidou_dnav_navigation_message.h
|
||||
beidou_dnav_ephemeris.h
|
||||
beidou_dnav_iono.h
|
||||
beidou_dnav_almanac.h
|
||||
beidou_dnav_utc_model.h
|
||||
display.h
|
||||
Galileo_E1.h
|
||||
Galileo_E5a.h
|
||||
@ -86,6 +96,7 @@ set(SYSTEM_PARAMETERS_HEADERS
|
||||
GPS_L1_CA.h
|
||||
GPS_L2C.h
|
||||
GPS_L5.h
|
||||
Beidou_B1I.h
|
||||
MATH_CONSTANTS.h
|
||||
)
|
||||
|
||||
|
@ -98,7 +98,6 @@ const int32_t GALILEO_E1_CODE_PERIOD_MS = 4;
|
||||
|
||||
const std::vector<std::pair<int32_t, int32_t>> type({{1, 6}});
|
||||
const std::vector<std::pair<int32_t, int32_t>> PAGE_TYPE_bit({{1, 6}});
|
||||
;
|
||||
|
||||
/*Page 1 - Word type 1: Ephemeris (1/4)*/
|
||||
const std::vector<std::pair<int32_t, int32_t>> IOD_nav_1_bit({{7, 10}});
|
||||
|
@ -46,6 +46,7 @@
|
||||
const double PI = 3.1415926535897932; //!< pi
|
||||
const double PI_2 = 2.0 * PI; //!< 2 * pi
|
||||
|
||||
const double TWO_P3 = (8); //!< 2^3
|
||||
const double TWO_P4 = (16); //!< 2^4
|
||||
const double TWO_P11 = (2048); //!< 2^11
|
||||
const double TWO_P12 = (4096); //!< 2^12
|
||||
@ -91,13 +92,14 @@ const double TWO_N44 = (5.684341886080802e-14); //!< 2^-44
|
||||
const double TWO_N46 = (1.4210854715202e-014); //!< 2^-46
|
||||
const double TWO_N48 = (3.552713678800501e-15); //!< 2^-46
|
||||
|
||||
const double TWO_N50 = (8.881784197001252e-016); //!< 2^-50
|
||||
const double TWO_N51 = (4.44089209850063e-016); //!< 2^-51
|
||||
const double TWO_N55 = (2.775557561562891e-017); //!< 2^-55
|
||||
const double TWO_N57 = (6.938893903907228e-18); //!< 2^-57
|
||||
const double TWO_N59 = (1.73472347597681e-018); //!< 2^-59
|
||||
const double TWO_N60 = (8.673617379884036e-19); //!< 2^-60
|
||||
const double TWO_N68 = (3.388131789017201e-21); //!< 2^-68
|
||||
const double TWO_N50 = (8.881784197001252e-016); //!< 2^-50
|
||||
const double TWO_N51 = (4.44089209850063e-016); //!< 2^-51
|
||||
const double TWO_N55 = (2.775557561562891e-017); //!< 2^-55
|
||||
const double TWO_N57 = (6.938893903907228e-18); //!< 2^-57
|
||||
const double TWO_N59 = (1.73472347597681e-018); //!< 2^-59
|
||||
const double TWO_N60 = (8.673617379884036e-19); //!< 2^-60
|
||||
const double TWO_N66 = (1.3552527156068805425093160010874271392822265625e-20); //!< 2^-66
|
||||
const double TWO_N68 = (3.388131789017201e-21); //!< 2^-68
|
||||
|
||||
|
||||
const double PI_TWO_N19 = (5.992112452678286e-006); //!< Pi*2^-19
|
||||
|
49
src/core/system_parameters/beidou_dnav_almanac.cc
Normal file
49
src/core/system_parameters/beidou_dnav_almanac.cc
Normal file
@ -0,0 +1,49 @@
|
||||
/*!
|
||||
* \file beidou_dnav_almanac.cc
|
||||
* \brief Interface of a Beidou DNAV Almanac storage
|
||||
*
|
||||
* See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2018 (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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "beidou_dnav_almanac.h"
|
||||
|
||||
Beidou_Dnav_Almanac::Beidou_Dnav_Almanac()
|
||||
{
|
||||
i_satellite_PRN = 0;
|
||||
d_Delta_i = 0.0;
|
||||
d_Toa = 0.0;
|
||||
d_M_0 = 0.0;
|
||||
d_e_eccentricity = 0.0;
|
||||
d_sqrt_A = 0.0;
|
||||
d_OMEGA0 = 0.0;
|
||||
d_OMEGA = 0.0;
|
||||
d_OMEGA_DOT = 0.0;
|
||||
i_SV_health = 0;
|
||||
d_A_f0 = 0.0;
|
||||
d_A_f1 = 0.0;
|
||||
}
|
88
src/core/system_parameters/beidou_dnav_almanac.h
Normal file
88
src/core/system_parameters/beidou_dnav_almanac.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*!
|
||||
* \file beidou_dnav_almanac.h
|
||||
* \brief Interface of a Beidou DNAV Almanac storage
|
||||
*
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2018 (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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GNSS_SDR_BEIDOU_DNAV_ALMANAC_H_
|
||||
#define GNSS_SDR_BEIDOU_DNAV_ALMANAC_H_
|
||||
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
/*!
|
||||
* \brief This class is a storage for the BeiDou D1 almanac
|
||||
*/
|
||||
class Beidou_Dnav_Almanac
|
||||
{
|
||||
public:
|
||||
unsigned int i_satellite_PRN; //!< SV PRN NUMBER
|
||||
double d_Delta_i;
|
||||
double d_Toa; //!< Almanac data reference time of week [s]
|
||||
double d_M_0; //!< Mean Anomaly at Reference Time [semi-circles]
|
||||
double d_e_eccentricity; //!< Eccentricity [dimensionless]
|
||||
double d_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)]
|
||||
double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles]
|
||||
double d_OMEGA; //!< Argument of Perigee [semi-cicles]
|
||||
double d_OMEGA_DOT; //!< Rate of Right Ascension [semi-circles/s]
|
||||
int i_SV_health; // SV Health
|
||||
double d_A_f0; //!< Coefficient 0 of code phase offset model [s]
|
||||
double d_A_f1; //!< Coefficient 1 of code phase offset model [s/s]
|
||||
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
Beidou_Dnav_Almanac();
|
||||
|
||||
template <class Archive>
|
||||
|
||||
void serialize(Archive& ar, const unsigned int version)
|
||||
{
|
||||
if (version)
|
||||
{
|
||||
};
|
||||
ar& BOOST_SERIALIZATION_NVP(i_satellite_PRN);
|
||||
ar& BOOST_SERIALIZATION_NVP(d_Delta_i);
|
||||
ar& BOOST_SERIALIZATION_NVP(d_Toa);
|
||||
//ar& BOOST_SERIALIZATION_NVP(i_WNa);
|
||||
ar& BOOST_SERIALIZATION_NVP(d_M_0);
|
||||
ar& BOOST_SERIALIZATION_NVP(d_e_eccentricity);
|
||||
ar& BOOST_SERIALIZATION_NVP(d_sqrt_A);
|
||||
ar& BOOST_SERIALIZATION_NVP(d_OMEGA0);
|
||||
ar& BOOST_SERIALIZATION_NVP(d_OMEGA);
|
||||
ar& BOOST_SERIALIZATION_NVP(d_OMEGA_DOT);
|
||||
ar& BOOST_SERIALIZATION_NVP(i_SV_health);
|
||||
//ar& BOOST_SERIALIZATION_NVP(i_AS_status);
|
||||
ar& BOOST_SERIALIZATION_NVP(d_A_f0);
|
||||
ar& BOOST_SERIALIZATION_NVP(d_A_f1);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
282
src/core/system_parameters/beidou_dnav_ephemeris.cc
Normal file
282
src/core/system_parameters/beidou_dnav_ephemeris.cc
Normal file
@ -0,0 +1,282 @@
|
||||
/*!
|
||||
* \file beidou_ephemeris.cc
|
||||
* \brief Interface of a BeiDou EPHEMERIS storage and orbital model functions
|
||||
*
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "beidou_dnav_ephemeris.h"
|
||||
#include "Beidou_B1I.h"
|
||||
#include "gnss_satellite.h"
|
||||
#include <cmath>
|
||||
|
||||
Beidou_Dnav_Ephemeris::Beidou_Dnav_Ephemeris()
|
||||
{
|
||||
i_satellite_PRN = 0;
|
||||
d_TOW = 0;
|
||||
d_Crs = 0;
|
||||
d_Delta_n = 0;
|
||||
d_M_0 = 0;
|
||||
d_Cuc = 0;
|
||||
d_eccentricity = 0;
|
||||
d_Cus = 0;
|
||||
d_sqrt_A = 0;
|
||||
d_Toe = 0;
|
||||
d_Toc = 0;
|
||||
d_Cic = 0;
|
||||
d_OMEGA0 = 0;
|
||||
d_Cis = 0;
|
||||
d_i_0 = 0;
|
||||
d_Crc = 0;
|
||||
d_OMEGA = 0;
|
||||
d_OMEGA_DOT = 0;
|
||||
d_IDOT = 0;
|
||||
i_BEIDOU_week = 0;
|
||||
i_SV_accuracy = 0;
|
||||
i_SV_health = 0;
|
||||
d_AODE = 0;
|
||||
d_TGD1 = 0;
|
||||
d_TGD2 = 0;
|
||||
d_AODC = 0; // Issue of Data, Clock
|
||||
i_AODO = 0; // Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s]
|
||||
d_AODC = 0;
|
||||
b_fit_interval_flag = false; // indicates the curve-fit interval used by the CS (Block II/IIA/IIR/IIR-M/IIF) and SS (Block IIIA) in determining the ephemeris parameters, as follows: 0 = 4 hours, 1 = greater than 4 hours.
|
||||
d_spare1 = 0;
|
||||
d_spare2 = 0;
|
||||
|
||||
i_sig_type = 0;
|
||||
i_nav_type = 0;
|
||||
|
||||
d_A_f0 = 0; // Coefficient 0 of code phase offset model [s]
|
||||
d_A_f1 = 0; // Coefficient 1 of code phase offset model [s/s]
|
||||
d_A_f2 = 0; // Coefficient 2 of code phase offset model [s/s^2]
|
||||
|
||||
b_integrity_status_flag = false;
|
||||
b_alert_flag = false; // If true, indicates that the SV URA may be worse than indicated in d_SV_accuracy, use that SV at our own risk.
|
||||
b_antispoofing_flag = false; // If true, the AntiSpoofing mode is ON in that SV
|
||||
|
||||
auto gnss_sat = Gnss_Satellite();
|
||||
std::string _system("Beidou");
|
||||
for (unsigned int i = 1; i < 36; i++)
|
||||
{
|
||||
satelliteBlock[i] = gnss_sat.what_block(_system, i);
|
||||
}
|
||||
|
||||
d_satClkDrift = 0.0;
|
||||
d_dtr = 0.0;
|
||||
d_satpos_X = 0.0;
|
||||
d_satpos_Y = 0.0;
|
||||
d_satpos_Z = 0.0;
|
||||
d_satvel_X = 0.0;
|
||||
d_satvel_Y = 0.0;
|
||||
d_satvel_Z = 0.0;
|
||||
}
|
||||
|
||||
|
||||
double Beidou_Dnav_Ephemeris::check_t(double time)
|
||||
{
|
||||
double corrTime;
|
||||
double half_week = 302400.0; // seconds
|
||||
corrTime = time;
|
||||
if (time > half_week)
|
||||
{
|
||||
corrTime = time - 2.0 * half_week;
|
||||
}
|
||||
else if (time < -half_week)
|
||||
{
|
||||
corrTime = time + 2.0 * half_week;
|
||||
}
|
||||
return corrTime;
|
||||
}
|
||||
|
||||
|
||||
// 20.3.3.3.3.1 User Algorithm for SV Clock Correction.
|
||||
double Beidou_Dnav_Ephemeris::sv_clock_drift(double transmitTime)
|
||||
{
|
||||
double dt;
|
||||
dt = check_t(transmitTime - d_Toc);
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
dt -= d_A_f0 + d_A_f1 * dt + d_A_f2 * (dt * dt);
|
||||
}
|
||||
d_satClkDrift = d_A_f0 + d_A_f1 * dt + d_A_f2 * (dt * dt);
|
||||
|
||||
return d_satClkDrift;
|
||||
}
|
||||
|
||||
|
||||
// compute the relativistic correction term
|
||||
double Beidou_Dnav_Ephemeris::sv_clock_relativistic_term(double transmitTime)
|
||||
{
|
||||
double tk;
|
||||
double a;
|
||||
double n;
|
||||
double n0;
|
||||
double E;
|
||||
double E_old;
|
||||
double dE;
|
||||
double M;
|
||||
|
||||
// Restore semi-major axis
|
||||
a = d_sqrt_A * d_sqrt_A;
|
||||
|
||||
// Time from ephemeris reference epoch
|
||||
tk = check_t(transmitTime - d_Toe);
|
||||
|
||||
// Computed mean motion
|
||||
n0 = sqrt(BEIDOU_GM / (a * a * a));
|
||||
// Corrected mean motion
|
||||
n = n0 + d_Delta_n;
|
||||
// Mean anomaly
|
||||
M = d_M_0 + n * tk;
|
||||
|
||||
// Reduce mean anomaly to between 0 and 2pi
|
||||
M = fmod((M + 2.0 * BEIDOU_PI), (2.0 * BEIDOU_PI));
|
||||
|
||||
// Initial guess of eccentric anomaly
|
||||
E = M;
|
||||
|
||||
// --- Iteratively compute eccentric anomaly ----------------------------
|
||||
for (int ii = 1; ii < 20; ii++)
|
||||
{
|
||||
E_old = E;
|
||||
E = M + d_eccentricity * sin(E);
|
||||
dE = fmod(E - E_old, 2.0 * BEIDOU_PI);
|
||||
if (fabs(dE) < 1e-12)
|
||||
{
|
||||
//Necessary precision is reached, exit from the loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute relativistic correction term
|
||||
d_dtr = BEIDOU_F * d_eccentricity * d_sqrt_A * sin(E);
|
||||
return d_dtr;
|
||||
}
|
||||
|
||||
|
||||
double Beidou_Dnav_Ephemeris::satellitePosition(double transmitTime)
|
||||
{
|
||||
double tk;
|
||||
double a;
|
||||
double n;
|
||||
double n0;
|
||||
double M;
|
||||
double E;
|
||||
double E_old;
|
||||
double dE;
|
||||
double nu;
|
||||
double phi;
|
||||
double u;
|
||||
double r;
|
||||
double i;
|
||||
double Omega;
|
||||
|
||||
// Find satellite's position ----------------------------------------------
|
||||
|
||||
// Restore semi-major axis
|
||||
a = d_sqrt_A * d_sqrt_A;
|
||||
|
||||
// Time from ephemeris reference epoch
|
||||
tk = check_t(transmitTime - d_Toe);
|
||||
|
||||
// Computed mean motion
|
||||
n0 = sqrt(BEIDOU_GM / (a * a * a));
|
||||
|
||||
// Corrected mean motion
|
||||
n = n0 + d_Delta_n;
|
||||
|
||||
// Mean anomaly
|
||||
M = d_M_0 + n * tk;
|
||||
|
||||
// Reduce mean anomaly to between 0 and 2pi
|
||||
M = fmod((M + 2.0 * BEIDOU_PI), (2.0 * BEIDOU_PI));
|
||||
|
||||
// Initial guess of eccentric anomaly
|
||||
E = M;
|
||||
|
||||
// --- Iteratively compute eccentric anomaly ----------------------------
|
||||
for (int ii = 1; ii < 20; ii++)
|
||||
{
|
||||
E_old = E;
|
||||
E = M + d_eccentricity * sin(E);
|
||||
dE = fmod(E - E_old, 2.0 * BEIDOU_PI);
|
||||
if (fabs(dE) < 1e-12)
|
||||
{
|
||||
//Necessary precision is reached, exit from the loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the true anomaly
|
||||
double tmp_Y = sqrt(1.0 - d_eccentricity * d_eccentricity) * sin(E);
|
||||
double tmp_X = cos(E) - d_eccentricity;
|
||||
nu = atan2(tmp_Y, tmp_X);
|
||||
|
||||
// Compute angle phi (argument of Latitude)
|
||||
phi = nu + d_OMEGA;
|
||||
|
||||
// Reduce phi to between 0 and 2*pi rad
|
||||
phi = fmod((phi), (2.0 * BEIDOU_PI));
|
||||
|
||||
// Correct argument of latitude
|
||||
u = phi + d_Cuc * cos(2.0 * phi) + d_Cus * sin(2.0 * phi);
|
||||
|
||||
// Correct radius
|
||||
r = a * (1.0 - d_eccentricity * cos(E)) + d_Crc * cos(2.0 * phi) + d_Crs * sin(2.0 * phi);
|
||||
|
||||
// Correct inclination
|
||||
i = d_i_0 + d_IDOT * tk + d_Cic * cos(2.0 * phi) + d_Cis * sin(2.0 * phi);
|
||||
|
||||
// Compute the angle between the ascending node and the Greenwich meridian
|
||||
Omega = d_OMEGA0 + (d_OMEGA_DOT - BEIDOU_OMEGA_EARTH_DOT) * tk - BEIDOU_OMEGA_EARTH_DOT * d_Toe;
|
||||
|
||||
// Reduce to between 0 and 2*pi rad
|
||||
Omega = fmod((Omega + 2.0 * BEIDOU_PI), (2.0 * BEIDOU_PI));
|
||||
|
||||
// --- Compute satellite coordinates in Earth-fixed coordinates
|
||||
d_satpos_X = cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega);
|
||||
d_satpos_Y = cos(u) * r * sin(Omega) + sin(u) * r * cos(i) * cos(Omega);
|
||||
d_satpos_Z = sin(u) * r * sin(i);
|
||||
|
||||
// Satellite's velocity. Can be useful for Vector Tracking loops
|
||||
double Omega_dot = d_OMEGA_DOT - BEIDOU_OMEGA_EARTH_DOT;
|
||||
d_satvel_X = -Omega_dot * (cos(u) * r + sin(u) * r * cos(i)) + d_satpos_X * cos(Omega) - d_satpos_Y * cos(i) * sin(Omega);
|
||||
d_satvel_Y = Omega_dot * (cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega)) + d_satpos_X * sin(Omega) + d_satpos_Y * cos(i) * cos(Omega);
|
||||
d_satvel_Z = d_satpos_Y * sin(i);
|
||||
|
||||
// Time from ephemeris reference clock
|
||||
tk = check_t(transmitTime - d_Toc);
|
||||
|
||||
double dtr_s = d_A_f0 + d_A_f1 * tk + d_A_f2 * tk * tk;
|
||||
|
||||
/* relativity correction */
|
||||
dtr_s -= 2.0 * sqrt(BEIDOU_GM * a) * d_eccentricity * sin(E) / (BEIDOU_C_m_s * BEIDOU_C_m_s);
|
||||
|
||||
return dtr_s;
|
||||
}
|
208
src/core/system_parameters/beidou_dnav_ephemeris.h
Normal file
208
src/core/system_parameters/beidou_dnav_ephemeris.h
Normal file
@ -0,0 +1,208 @@
|
||||
/*!
|
||||
* \file beidou_ephemeris.h
|
||||
* \brief Interface of a BEIDOU EPHEMERIS storage
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GNSS_SDR_BEIDOU_DNAV_EPHEMERIS_H_
|
||||
#define GNSS_SDR_BEIDOU_DNAV_EPHEMERIS_H_
|
||||
|
||||
|
||||
#include "boost/assign.hpp"
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
|
||||
/*!
|
||||
* \brief This class is a storage and orbital model functions for the GPS SV ephemeris data as described in IS-GPS-200E
|
||||
*
|
||||
* See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
|
||||
*/
|
||||
class Beidou_Dnav_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:
|
||||
unsigned int i_satellite_PRN; // SV PRN NUMBER
|
||||
double d_TOW; //!< Time of BEIDOU Week of the ephemeris set (taken from subframes TOW) [s]
|
||||
double d_Crs; //!< Amplitude of the Sine Harmonic Correction Term to the Orbit Radius [m]
|
||||
double d_Delta_n; //!< Mean Motion Difference From Computed Value [semi-circles/s]
|
||||
double d_M_0; //!< Mean Anomaly at Reference Time [semi-circles]
|
||||
double d_Cuc; //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad]
|
||||
double d_eccentricity; //!< Eccentricity [dimensionless]
|
||||
double d_Cus; //!< Amplitude of the Sine Harmonic Correction Term to the Argument of Latitude [rad]
|
||||
double d_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)]
|
||||
double d_Toe; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s]
|
||||
double d_Toc; //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s]
|
||||
double d_Cic; //!< Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination [rad]
|
||||
double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles]
|
||||
double d_Cis; //!< Amplitude of the Sine Harmonic Correction Term to the Angle of Inclination [rad]
|
||||
double d_i_0; //!< Inclination Angle at Reference Time [semi-circles]
|
||||
double d_Crc; //!< Amplitude of the Cosine Harmonic Correction Term to the Orbit Radius [m]
|
||||
double d_OMEGA; //!< Argument of Perigee [semi-cicles]
|
||||
double d_OMEGA_DOT; //!< Rate of Right Ascension [semi-circles/s]
|
||||
double d_IDOT; //!< Rate of Inclination Angle [semi-circles/s]
|
||||
int i_BEIDOU_week; //!< BEIDOU week number, aka WN [week]
|
||||
int i_SV_accuracy; //!< User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200E)
|
||||
int i_SV_health;
|
||||
double d_TGD1; //!< Estimated Group Delay Differential on B1I [s]
|
||||
double d_TGD2; //!< Estimated Group Delay Differential on B2I [s]
|
||||
double d_AODC; //!< Age of Data, Clock
|
||||
double d_AODE; //!< Age of Data, Ephemeris
|
||||
int i_AODO; //!< Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s]
|
||||
|
||||
int i_sig_type; //!< BDS: data source (0:unknown,1:B1I,2:B1Q,3:B2I,4:B2Q,5:B3I,6:B3Q) */
|
||||
int i_nav_type; //!< BDS: nav type (0:unknown,1:IGSO/MEO,2:GEO) */
|
||||
|
||||
bool b_fit_interval_flag; //!< indicates the curve-fit interval used by the CS (Block II/IIA/IIR/IIR-M/IIF) and SS (Block IIIA) in determining the ephemeris parameters, as follows: 0 = 4 hours, 1 = greater than 4 hours.
|
||||
double d_spare1;
|
||||
double d_spare2;
|
||||
|
||||
double d_A_f0; //!< Coefficient 0 of code phase offset model [s]
|
||||
double d_A_f1; //!< Coefficient 1 of code phase offset model [s/s]
|
||||
double d_A_f2; //!< Coefficient 2 of code phase offset model [s/s^2]
|
||||
|
||||
/*! \brief If true, enhanced level of integrity assurance.
|
||||
*
|
||||
* If false, indicates that the conveying signal is provided with the legacy level of integrity assurance.
|
||||
* That is, the probability that the instantaneous URE of the conveying signal exceeds 4.42 times the upper bound
|
||||
* value of the current broadcast URA index, for more than 5.2 seconds, without an accompanying alert, is less
|
||||
* than 1E-5 per hour. If true, indicates that the conveying signal is provided with an enhanced level of
|
||||
* integrity assurance. That is, the probability that the instantaneous URE of the conveying signal exceeds 5.73
|
||||
* times the upper bound value of the current broadcast URA index, for more than 5.2 seconds, without an
|
||||
* accompanying alert, is less than 1E-8 per hour.
|
||||
*/
|
||||
bool b_integrity_status_flag;
|
||||
bool b_alert_flag; //!< If true, indicates that the SV URA may be worse than indicated in d_SV_accuracy, use that SV at our own risk.
|
||||
bool b_antispoofing_flag; //!< If true, the AntiSpoofing mode is ON in that SV
|
||||
|
||||
// clock terms derived from ephemeris data
|
||||
double d_satClkDrift; //!< GPS clock error
|
||||
double d_dtr; //!< relativistic clock correction term
|
||||
|
||||
// satellite positions
|
||||
double d_satpos_X; //!< Earth-fixed coordinate x of the satellite [m]. Intersection of the IERS Reference Meridian (IRM) and the plane passing through the origin and normal to the Z-axis.
|
||||
double d_satpos_Y; //!< Earth-fixed coordinate y of the satellite [m]. Completes a right-handed, Earth-Centered, Earth-Fixed orthogonal coordinate system.
|
||||
double d_satpos_Z; //!< Earth-fixed coordinate z of the satellite [m]. The direction of the IERS (International Earth Rotation and Reference Systems Service) Reference Pole (IRP).
|
||||
|
||||
// Satellite velocity
|
||||
double d_satvel_X; //!< Earth-fixed velocity coordinate x of the satellite [m]
|
||||
double d_satvel_Y; //!< Earth-fixed velocity coordinate y of the satellite [m]
|
||||
double d_satvel_Z; //!< Earth-fixed velocity coordinate z of the satellite [m]
|
||||
|
||||
std::map<int, std::string> satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus
|
||||
|
||||
template <class Archive>
|
||||
|
||||
/*!
|
||||
* \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_PRN", i_satellite_PRN); // SV PRN NUMBER
|
||||
archive& make_nvp("d_TOW", d_TOW); //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s]
|
||||
archive& make_nvp("d_AODE", d_AODE);
|
||||
archive& make_nvp("d_Crs", d_Crs); //!< Amplitude of the Sine Harmonic Correction Term to the Orbit Radius [m]
|
||||
archive& make_nvp("d_Delta_n", d_Delta_n); //!< Mean Motion Difference From Computed Value [semi-circles/s]
|
||||
archive& make_nvp("d_M_0", d_M_0); //!< Mean Anomaly at Reference Time [semi-circles]
|
||||
archive& make_nvp("d_Cuc", d_Cuc); //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad]
|
||||
archive& make_nvp("d_e_eccentricity", d_eccentricity); //!< Eccentricity [dimensionless]
|
||||
archive& make_nvp("d_Cus", d_Cus); //!< Amplitude of the Sine Harmonic Correction Term to the Argument of Latitude [rad]
|
||||
archive& make_nvp("d_sqrt_A", d_sqrt_A); //!< Square Root of the Semi-Major Axis [sqrt(m)]
|
||||
archive& make_nvp("d_Toe", d_Toe); //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s]
|
||||
archive& make_nvp("d_Toc", d_Toe); //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s]
|
||||
archive& make_nvp("d_Cic", d_Cic); //!< Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination [rad]
|
||||
archive& make_nvp("d_OMEGA0", d_OMEGA0); //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles]
|
||||
archive& make_nvp("d_Cis", d_Cis); //!< Amplitude of the Sine Harmonic Correction Term to the Angle of Inclination [rad]
|
||||
archive& make_nvp("d_i_0", d_i_0); //!< Inclination Angle at Reference Time [semi-circles]
|
||||
archive& make_nvp("d_Crc", d_Crc); //!< Amplitude of the Cosine Harmonic Correction Term to the Orbit Radius [m]
|
||||
archive& make_nvp("d_OMEGA", d_OMEGA); //!< Argument of Perigee [semi-cicles]
|
||||
archive& make_nvp("d_OMEGA_DOT", d_OMEGA_DOT); //!< Rate of Right Ascension [semi-circles/s]
|
||||
archive& make_nvp("d_IDOT", d_IDOT); //!< Rate of Inclination Angle [semi-circles/s]
|
||||
archive& make_nvp("i_BEIDOU_week", i_BEIDOU_week); //!< GPS week number, aka WN [week]
|
||||
archive& make_nvp("i_SV_accuracy", i_SV_accuracy); //!< User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200E)
|
||||
archive& make_nvp("i_SV_health", i_SV_health);
|
||||
archive& make_nvp("d_AODC", d_AODC); //!< Issue of Data, Clock
|
||||
archive& make_nvp("d_TGD1", d_TGD1); //!< Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s]
|
||||
archive& make_nvp("d_TGD2", d_TGD2); //!< Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s]
|
||||
archive& make_nvp("i_AODO", i_AODO); //!< Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s]
|
||||
|
||||
archive& make_nvp("b_fit_interval_flag", b_fit_interval_flag); //!< indicates the curve-fit interval used by the CS (Block II/IIA/IIR/IIR-M/IIF) and SS (Block IIIA) in determining the ephemeris parameters, as follows: 0 = 4 hours, 1 = greater than 4 hours.
|
||||
archive& make_nvp("d_spare1", d_spare1);
|
||||
archive& make_nvp("d_spare2", d_spare2);
|
||||
|
||||
archive& make_nvp("d_A_f0", d_A_f0); //!< Coefficient 0 of code phase offset model [s]
|
||||
archive& make_nvp("d_A_f1", d_A_f1); //!< Coefficient 1 of code phase offset model [s/s]
|
||||
archive& make_nvp("d_A_f2", d_A_f2); //!< Coefficient 2 of code phase offset model [s/s^2]
|
||||
|
||||
archive& make_nvp("b_integrity_status_flag", b_integrity_status_flag);
|
||||
archive& make_nvp("b_alert_flag", b_alert_flag); //!< If true, indicates that the SV URA may be worse than indicated in d_SV_accuracy, use that SV at our own risk.
|
||||
archive& make_nvp("b_antispoofing_flag", b_antispoofing_flag); //!< If true, the AntiSpoofing mode is ON in that SV
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compute the ECEF SV coordinates and ECEF velocity
|
||||
* Implementation of Table 20-IV (IS-GPS-200E)
|
||||
* and compute the clock bias term including relativistic effect (return value)
|
||||
*/
|
||||
double satellitePosition(double transmitTime);
|
||||
|
||||
/*!
|
||||
* \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);
|
||||
|
||||
/*!
|
||||
* \brief Sets (\a d_dtr) and returns the clock relativistic correction term in seconds according to the User Algorithm for SV Clock Correction
|
||||
* (IS-GPS-200E, 20.3.3.3.3.1)
|
||||
*/
|
||||
double sv_clock_relativistic_term(double transmitTime);
|
||||
|
||||
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
Beidou_Dnav_Ephemeris();
|
||||
};
|
||||
|
||||
#endif
|
45
src/core/system_parameters/beidou_dnav_iono.cc
Normal file
45
src/core/system_parameters/beidou_dnav_iono.cc
Normal file
@ -0,0 +1,45 @@
|
||||
/*!
|
||||
* \file beidou_iono.cc
|
||||
* \brief Interface of a BEIDOU IONOSPHERIC MODEL storage
|
||||
*
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "beidou_dnav_iono.h"
|
||||
|
||||
Beidou_Dnav_Iono::Beidou_Dnav_Iono()
|
||||
{
|
||||
valid = false;
|
||||
d_alpha0 = 0.0;
|
||||
d_alpha1 = 0.0;
|
||||
d_alpha2 = 0.0;
|
||||
d_alpha3 = 0.0;
|
||||
d_beta0 = 0.0;
|
||||
d_beta1 = 0.0;
|
||||
d_beta2 = 0.0;
|
||||
d_beta3 = 0.0;
|
||||
}
|
82
src/core/system_parameters/beidou_dnav_iono.h
Normal file
82
src/core/system_parameters/beidou_dnav_iono.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*!
|
||||
* \file beidou_iono.h
|
||||
* \brief Interface of a BEIDOU IONOSPHERIC MODEL storage
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GNSS_SDR_BEIDOU_DNAV_IONO_H_
|
||||
#define GNSS_SDR_BEIDOU_DNAV_IONO_H_
|
||||
|
||||
|
||||
#include "boost/assign.hpp"
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
|
||||
|
||||
/*!
|
||||
* \brief This class is a storage for the BEIDOU IONOSPHERIC data as described in ICD v2.1
|
||||
*
|
||||
*/
|
||||
class Beidou_Dnav_Iono
|
||||
{
|
||||
public:
|
||||
bool valid; //!< Valid flag
|
||||
// Ionospheric parameters
|
||||
double d_alpha0; //!< Coefficient 0 of a cubic equation representing the amplitude of the vertical delay [s]
|
||||
double d_alpha1; //!< Coefficient 1 of a cubic equation representing the amplitude of the vertical delay [s/semi-circle]
|
||||
double d_alpha2; //!< Coefficient 2 of a cubic equation representing the amplitude of the vertical delay [s(semi-circle)^2]
|
||||
double d_alpha3; //!< Coefficient 3 of a cubic equation representing the amplitude of the vertical delay [s(semi-circle)^3]
|
||||
double d_beta0; //!< Coefficient 0 of a cubic equation representing the period of the model [s]
|
||||
double d_beta1; //!< Coefficient 1 of a cubic equation representing the period of the model [s/semi-circle]
|
||||
double d_beta2; //!< Coefficient 2 of a cubic equation representing the period of the model [s(semi-circle)^2]
|
||||
double d_beta3; //!< Coefficient 3 of a cubic equation representing the period of the model [s(semi-circle)^3]
|
||||
|
||||
Beidou_Dnav_Iono(); //!< Default constructor
|
||||
|
||||
template <class Archive>
|
||||
|
||||
/*!
|
||||
* \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("d_alpha0", d_alpha0);
|
||||
archive& make_nvp("d_alpha1", d_alpha1);
|
||||
archive& make_nvp("d_alpha2", d_alpha2);
|
||||
archive& make_nvp("d_alpha3", d_alpha3);
|
||||
archive& make_nvp("d_beta0", d_beta0);
|
||||
archive& make_nvp("d_beta1", d_beta1);
|
||||
archive& make_nvp("d_beta2", d_beta2);
|
||||
archive& make_nvp("d_beta3", d_beta3);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
1219
src/core/system_parameters/beidou_dnav_navigation_message.cc
Normal file
1219
src/core/system_parameters/beidou_dnav_navigation_message.cc
Normal file
File diff suppressed because it is too large
Load Diff
328
src/core/system_parameters/beidou_dnav_navigation_message.h
Normal file
328
src/core/system_parameters/beidou_dnav_navigation_message.h
Normal file
@ -0,0 +1,328 @@
|
||||
/*!
|
||||
* \file beidou_navigation_message.h
|
||||
* \brief Interface of a BeiDou DNAV Data message decoder
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
|
||||
* \author Damian Miralles, 2018. dmiralles2009@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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GNSS_SDR_BEIDOU_DNAV_NAVIGATION_MESSAGE_H_
|
||||
#define GNSS_SDR_BEIDOU_DNAV_NAVIGATION_MESSAGE_H_
|
||||
|
||||
|
||||
#include "Beidou_B1I.h"
|
||||
#include "beidou_dnav_almanac.h"
|
||||
#include "beidou_dnav_ephemeris.h"
|
||||
#include "beidou_dnav_iono.h"
|
||||
#include "beidou_dnav_utc_model.h"
|
||||
#include <bitset>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
||||
/*!
|
||||
* \brief This class decodes a BeiDou D1 NAV Data message as described in IS-GPS-200E
|
||||
*
|
||||
* See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
|
||||
*/
|
||||
class Beidou_Dnav_Navigation_Message
|
||||
{
|
||||
private:
|
||||
unsigned long int read_navigation_unsigned(std::bitset<BEIDOU_DNAV_SUBFRAME_DATA_BITS> bits, const std::vector<std::pair<int, int>>& parameter);
|
||||
signed long int read_navigation_signed(std::bitset<BEIDOU_DNAV_SUBFRAME_DATA_BITS> bits, const std::vector<std::pair<int, int>>& parameter);
|
||||
bool read_navigation_bool(std::bitset<BEIDOU_DNAV_SUBFRAME_DATA_BITS> bits, const std::vector<std::pair<int, int>>& parameter);
|
||||
void print_beidou_word_bytes(unsigned int BEIDOU_word);
|
||||
/*
|
||||
* 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:
|
||||
// System flags for data processing
|
||||
bool flag_eph_valid;
|
||||
bool flag_utc_model_valid;
|
||||
bool flag_iono_valid;
|
||||
bool flag_d1_sf1;
|
||||
bool flag_d1_sf2;
|
||||
bool flag_d1_sf3;
|
||||
bool flag_d1_sf4;
|
||||
bool flag_d1_sf5;
|
||||
bool flag_new_SOW_available;
|
||||
bool flag_crc_test;
|
||||
double d_previous_aode;
|
||||
|
||||
bool flag_d1_sf5_p7; //!< D1 NAV Message, Subframe 5, Page 09 decoded indicator
|
||||
bool flag_d1_sf5_p8; //!< D1 NAV Message, Subframe 5, Page 09 decoded indicator
|
||||
bool flag_d1_sf5_p9; //!< D1 NAV Message, Subframe 5, Page 09 decoded indicator
|
||||
bool flag_d1_sf5_p10; //!< D1 NAV Message, Subframe 5, Page 10 decoded indicator
|
||||
|
||||
|
||||
bool flag_sf1_p1; //!< D2 NAV Message, Subframe 1, Page 1 decoded indicator
|
||||
bool flag_sf1_p2; //!< D2 NAV Message, Subframe 1, Page 2 decoded indicator
|
||||
bool flag_sf1_p3; //!< D2 NAV Message, Subframe 1, Page 3 decoded indicator
|
||||
bool flag_sf1_p4; //!< D2 NAV Message, Subframe 1, Page 4 decoded indicator
|
||||
bool flag_sf1_p5; //!< D2 NAV Message, Subframe 1, Page 5 decoded indicator
|
||||
bool flag_sf1_p6; //!< D2 NAV Message, Subframe 1, Page 6 decoded indicator
|
||||
bool flag_sf1_p7; //!< D2 NAV Message, Subframe 1, Page 7 decoded indicator
|
||||
bool flag_sf1_p8; //!< D2 NAV Message, Subframe 1, Page 8 decoded indicator
|
||||
bool flag_sf1_p9; //!< D2 NAV Message, Subframe 1, Page 9 decoded indicator
|
||||
bool flag_sf1_p10; //!< D2 NAV Message, Subframe 1, Page 10 decoded indicator
|
||||
|
||||
//broadcast orbit 1
|
||||
double d_SOW; //!< Time of BeiDou Week of the ephemeris set (taken from subframes SOW) [s]
|
||||
double d_SOW_SF1; //!< Time of BeiDou Week from HOW word of Subframe 1 [s]
|
||||
double d_SOW_SF2; //!< Time of BeiDou Week from HOW word of Subframe 2 [s]
|
||||
double d_SOW_SF3; //!< Time of BeiDou Week from HOW word of Subframe 3 [s]
|
||||
double d_SOW_SF4; //!< Time of BeiDou Week from HOW word of Subframe 4 [s]
|
||||
double d_SOW_SF5; //!< Time of BeiDou Week from HOW word of Subframe 5 [s]
|
||||
|
||||
double d_AODE;
|
||||
double d_Crs; //!< Amplitude of the Sine Harmonic Correction Term to the Orbit Radius [m]
|
||||
double d_Delta_n; //!< Mean Motion Difference From Computed Value [semi-circles/s]
|
||||
double d_M_0; //!< Mean Anomaly at Reference Time [semi-circles]
|
||||
//broadcast orbit 2
|
||||
double d_Cuc; //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad]
|
||||
double d_eccentricity; //!< Eccentricity [dimensionless]
|
||||
double d_Cus; //!< Amplitude of the Sine Harmonic Correction Term to the Argument of Latitude [rad]
|
||||
double d_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)]
|
||||
//broadcast orbit 3
|
||||
double d_Toe_sf2; //!< Ephemeris data reference time of week in subframe 2, D1 Message
|
||||
double d_Toe_sf3; //!< Ephemeris data reference time of week in subframe 3, D1 Message
|
||||
double d_Toe; //!< Ephemeris data reference time of week in subframe 1, D2 Message
|
||||
double d_Toc; //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s]
|
||||
double d_Cic; //!< Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination [rad]
|
||||
double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles]
|
||||
double d_Cis; //!< Amplitude of the Sine Harmonic Correction Term to the Angle of Inclination [rad]
|
||||
//broadcast orbit 4
|
||||
double d_i_0; //!< Inclination Angle at Reference Time [semi-circles]
|
||||
double d_Crc; //!< Amplitude of the Cosine Harmonic Correction Term to the Orbit Radius [m]
|
||||
double d_OMEGA; //!< Argument of Perigee [semi-cicles]
|
||||
double d_OMEGA_DOT; //!< Rate of Right Ascension [semi-circles/s]
|
||||
//broadcast orbit 5
|
||||
double d_IDOT; //!< Rate of Inclination Angle [semi-circles/s]
|
||||
int i_BEIDOU_week; //!< BeiDou week number, aka WN [week]
|
||||
//broadcast orbit 6
|
||||
int i_SV_accuracy; //!< User Range Accuracy (URA) index of the SV
|
||||
int i_SV_health;
|
||||
double d_TGD1; //!< Estimated Group Delay Differential in B1 [s]
|
||||
double d_TGD2; //!< Estimated Group Delay Differential in B2 [s]
|
||||
double d_AODC; //!< Age of Data, Clock
|
||||
//broadcast orbit 7
|
||||
// int i_AODO; //!< Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s]
|
||||
|
||||
bool b_fit_interval_flag; //!< indicates the curve-fit interval used by the CS (Block II/IIA/IIR/IIR-M/IIF) and SS (Block IIIA) in determining the ephemeris parameters, as follows: 0 = 4 hours, 1 = greater than 4 hours.
|
||||
double d_spare1;
|
||||
double d_spare2;
|
||||
|
||||
double d_A_f0; //!< Clock correction parameters. Coefficient 0 of code phase offset model [s]
|
||||
double d_A_f1; //!< Clock correction parameters. Coefficient 1 of code phase offset model [s/s]
|
||||
double d_A_f2; //!< Clock correction parameters. Coefficient 2 of code phase offset model [s/s^2]
|
||||
|
||||
// D2 NAV Message Decoding
|
||||
unsigned long int d_A_f1_msb_bits; //!< Clock correction parameters, D2 NAV MSB
|
||||
unsigned long int d_A_f1_lsb_bits; //!< Clock correction parameters, D2 NAV LSB
|
||||
unsigned long int d_Cuc_msb_bits; //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad]
|
||||
unsigned long int d_Cuc_lsb_bits; //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad]
|
||||
unsigned long int d_eccentricity_msb; //!< Eccentricity [dimensionless]
|
||||
unsigned long int d_eccentricity_lsb; //!< Eccentricity [dimensionless]
|
||||
unsigned long int d_Cic_msb_bits; //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad]
|
||||
unsigned long int d_Cic_lsb_bits; //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad]
|
||||
unsigned long int d_eccentricity_msb_bits; //!< Eccentricity [dimensionless]
|
||||
unsigned long int d_eccentricity_lsb_bits;
|
||||
unsigned long int d_i_0_msb_bits; //!< Inclination Angle at Reference Time [semi-circles]
|
||||
unsigned long int d_i_0_lsb_bits; //!< Inclination Angle at Reference Time [semi-circles]
|
||||
unsigned long int d_OMEGA_msb_bits; //!< Argument of Perigee [semi-cicles]
|
||||
unsigned long int d_OMEGA_lsb_bits; //!< Argument of Perigee [semi-cicles]
|
||||
unsigned long int d_OMEGA_DOT_msb_bits; //!< Rate of Right Ascension [semi-circles/s]
|
||||
unsigned long int d_OMEGA_DOT_lsb_bits; //!< Rate of Right Ascension [semi-circles/s]
|
||||
|
||||
// Almanac
|
||||
double d_Toa; //!< Almanac reference time [s]
|
||||
int i_WN_A; //!< Modulo 256 of the GPS week number to which the almanac reference time (d_Toa) is referenced
|
||||
std::map<int, int> almanacHealth; //!< Map that stores the health information stored in the almanac
|
||||
|
||||
std::map<int, std::string> satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus
|
||||
|
||||
// Flags
|
||||
|
||||
/*! \brief If true, enhanced level of integrity assurance.
|
||||
*
|
||||
* If false, indicates that the conveying signal is provided with the legacy level of integrity assurance.
|
||||
* That is, the probability that the instantaneous URE of the conveying signal exceeds 4.42 times the upper bound
|
||||
* value of the current broadcast URA index, for more than 5.2 seconds, without an accompanying alert, is less
|
||||
* than 1E-5 per hour. If true, indicates that the conveying signal is provided with an enhanced level of
|
||||
* integrity assurance. That is, the probability that the instantaneous URE of the conveying signal exceeds 5.73
|
||||
* times the upper bound value of the current broadcast URA index, for more than 5.2 seconds, without an
|
||||
* accompanying alert, is less than 1E-8 per hour.
|
||||
*/
|
||||
bool b_integrity_status_flag;
|
||||
bool b_alert_flag; //!< If true, indicates that the SV URA may be worse than indicated in d_SV_accuracy, use that SV at our own risk.
|
||||
bool b_antispoofing_flag; //!< If true, the AntiSpoofing mode is ON in that SV
|
||||
|
||||
// clock terms
|
||||
//double d_master_clock; // GPS transmission time
|
||||
double d_satClkCorr; // GPS clock error
|
||||
double d_dtr; // relativistic clock correction term
|
||||
double d_satClkDrift;
|
||||
|
||||
// satellite positions
|
||||
double d_satpos_X; //!< Earth-fixed coordinate x of the satellite [m]. Intersection of the IERS Reference Meridian (IRM) and the plane passing through the origin and normal to the Z-axis.
|
||||
double d_satpos_Y; //!< Earth-fixed coordinate y of the satellite [m]. Completes a right-handed, Earth-Centered, Earth-Fixed orthogonal coordinate system.
|
||||
double d_satpos_Z; //!< Earth-fixed coordinate z of the satellite [m]. The direction of the IERS (International Earth Rotation and Reference Systems Service) Reference Pole (IRP).
|
||||
|
||||
// satellite identification info
|
||||
int i_channel_ID;
|
||||
unsigned int i_satellite_PRN;
|
||||
|
||||
// time synchro
|
||||
double d_subframe_timestamp_ms; //[ms]
|
||||
|
||||
// Ionospheric parameters
|
||||
double d_alpha0; //!< Coefficient 0 of a cubic equation representing the amplitude of the vertical delay [s]
|
||||
double d_alpha1; //!< Coefficient 1 of a cubic equation representing the amplitude of the vertical delay [s/semi-circle]
|
||||
double d_alpha2; //!< Coefficient 2 of a cubic equation representing the amplitude of the vertical delay [s(semi-circle)^2]
|
||||
double d_alpha3; //!< Coefficient 3 of a cubic equation representing the amplitude of the vertical delay [s(semi-circle)^3]
|
||||
double d_beta0; //!< Coefficient 0 of a cubic equation representing the period of the model [s]
|
||||
double d_beta1; //!< Coefficient 1 of a cubic equation representing the period of the model [s/semi-circle]
|
||||
double d_beta2; //!< Coefficient 2 of a cubic equation representing the period of the model [s(semi-circle)^2]
|
||||
double d_beta3; //!< Coefficient 3 of a cubic equation representing the period of the model [s(semi-circle)^3]
|
||||
|
||||
// UTC parameters
|
||||
double d_A1UTC; //!< 1st order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s/s]
|
||||
double d_A0UTC; //!< Constant of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s]
|
||||
double d_DeltaT_LS; //!< delta time due to leap seconds [s]. Number of leap seconds since 6-Jan-1980 as transmitted by the GPS almanac.
|
||||
int i_WN_LSF; //!< Week number at the end of which the leap second becomes effective [weeks]
|
||||
int i_DN; //!< Day number (DN) at the end of which the leap second becomes effective [days]
|
||||
double d_DeltaT_LSF; //!< Scheduled future or recent past (relative to NAV message upload) value of the delta time due to leap seconds [s]
|
||||
double d_A1GPS;
|
||||
double d_A0GPS;
|
||||
double d_A1GAL;
|
||||
double d_A0GAL;
|
||||
double d_A1GLO;
|
||||
double d_A0GLO;
|
||||
|
||||
double d_SQRT_A_ALMANAC;
|
||||
double d_A1_ALMANAC;
|
||||
double d_A0_ALMANAC;
|
||||
double d_OMEGA0_ALMANAC;
|
||||
double d_E_ALMANAC;
|
||||
double d_DELTA_I;
|
||||
double d_TOA;
|
||||
double d_OMEGA_DOT_ALMANAC;
|
||||
double d_OMEGA_ALMANAC;
|
||||
double d_M0_ALMANAC;
|
||||
int almanac_WN;
|
||||
double d_toa2;
|
||||
|
||||
// Satellite velocity
|
||||
double d_satvel_X; //!< Earth-fixed velocity coordinate x of the satellite [m]
|
||||
double d_satvel_Y; //!< Earth-fixed velocity coordinate y of the satellite [m]
|
||||
double d_satvel_Z; //!< Earth-fixed velocity coordinate z of the satellite [m]
|
||||
|
||||
|
||||
// public functions
|
||||
void reset();
|
||||
|
||||
/*!
|
||||
* \brief Obtain a GPS SV Ephemeris class filled with current SV data
|
||||
*/
|
||||
Beidou_Dnav_Ephemeris get_ephemeris();
|
||||
|
||||
/*!
|
||||
* \brief Obtain a GPS ionospheric correction parameters class filled with current SV data
|
||||
*/
|
||||
Beidou_Dnav_Iono get_iono();
|
||||
|
||||
/*!
|
||||
* \brief Obtain a GPS UTC model parameters class filled with current SV data
|
||||
*/
|
||||
Beidou_Dnav_Utc_Model get_utc_model();
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Decodes the BDS D1 NAV message
|
||||
*/
|
||||
int d1_subframe_decoder(std::string const& subframe);
|
||||
|
||||
/*!
|
||||
* \brief Decodes the BDS D2 NAV message
|
||||
*/
|
||||
int d2_subframe_decoder(std::string const& subframe);
|
||||
|
||||
/*!
|
||||
* \brief Computes the position of the satellite
|
||||
*
|
||||
* Implementation of Table 20-IV (IS-GPS-200E)
|
||||
*/
|
||||
void satellitePosition(double transmitTime);
|
||||
|
||||
/*!
|
||||
* \brief Sets (\a d_satClkCorr) according to the User Algorithm for SV Clock Correction
|
||||
* and returns the corrected clock (IS-GPS-200E, 20.3.3.3.3.1)
|
||||
*/
|
||||
double sv_clock_correction(double transmitTime);
|
||||
|
||||
/*!
|
||||
* \brief Computes the Coordinated Universal Time (UTC) and
|
||||
* returns it in [s] (IS-GPS-200E, 20.3.3.5.2.4)
|
||||
*/
|
||||
double utc_time(const double gpstime_corrected) const;
|
||||
|
||||
bool satellite_validation();
|
||||
|
||||
/*
|
||||
* \brief Returns true if new Ephemeris has arrived. The flag is set to false when the function is executed
|
||||
*/
|
||||
bool have_new_ephemeris();
|
||||
|
||||
/*
|
||||
* \brief Returns true if new Iono model has arrived. The flag is set to false when the function is executed
|
||||
*/
|
||||
bool have_new_iono();
|
||||
|
||||
/*
|
||||
* \brief Returns true if new UTC model has arrived. The flag is set to false when the function is executed
|
||||
*/
|
||||
bool have_new_utc_model();
|
||||
|
||||
/*
|
||||
* \brief Returns true if new UTC model has arrived. The flag is set to false when the function is executed
|
||||
*/
|
||||
bool have_new_almanac();
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
Beidou_Dnav_Navigation_Message();
|
||||
};
|
||||
|
||||
#endif
|
51
src/core/system_parameters/beidou_dnav_utc_model.cc
Normal file
51
src/core/system_parameters/beidou_dnav_utc_model.cc
Normal file
@ -0,0 +1,51 @@
|
||||
/*!
|
||||
* \file beidou_dnav_utc_model.c
|
||||
* \brief Interface of a BeiDou UTC Model storage
|
||||
* \author Damian Miralles, 2018. dmiralles2009(at)gmail.com
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2018 (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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "beidou_dnav_utc_model.h"
|
||||
|
||||
|
||||
Beidou_Dnav_Utc_Model::Beidou_Dnav_Utc_Model()
|
||||
{
|
||||
valid = false;
|
||||
d_A1_UTC = 0;
|
||||
d_A0_UTC = 0;
|
||||
d_DeltaT_LS = 0;
|
||||
i_WN_LSF = 0;
|
||||
i_DN = 0;
|
||||
d_DeltaT_LSF = 0;
|
||||
|
||||
d_A0_GPS = 0;
|
||||
d_A1_GPS = 0;
|
||||
d_A0_GAL = 0;
|
||||
d_A1_GAL = 0;
|
||||
d_A0_GLO = 0;
|
||||
d_A1_GLO = 0;
|
||||
}
|
98
src/core/system_parameters/beidou_dnav_utc_model.h
Normal file
98
src/core/system_parameters/beidou_dnav_utc_model.h
Normal file
@ -0,0 +1,98 @@
|
||||
/*!
|
||||
* \file beidou_dnav_utc_model.h
|
||||
* \brief Interface of a BeiDou UTC MODEL storage
|
||||
* \author Damian Miralles, 2018. dmiralles2009@gmail.com
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2018 (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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GNSS_SDR_BEIDOU_DNAV_UTC_MODEL_H_
|
||||
#define GNSS_SDR_BEIDOU_DNAV_UTC_MODEL_H_
|
||||
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
|
||||
|
||||
/*!
|
||||
* \brief This class is a storage for the BeiDou DNAV UTC Model.
|
||||
* \details Implementation follows the interface described in the Open Service Signal (Version 2.1)
|
||||
*
|
||||
*/
|
||||
class Beidou_Dnav_Utc_Model
|
||||
{
|
||||
public:
|
||||
bool valid;
|
||||
|
||||
// BeiDou UTC parameters
|
||||
double d_A0_UTC; //!< BDT clock bias relative to UTC [s]
|
||||
double d_A1_UTC; //!< BDT clock rate relative to UTC [s/s]
|
||||
double d_DeltaT_LS; //!< Delta time due to leap seconds before the new leap second effective
|
||||
int i_WN_LSF; //!< Week number of the new leap second
|
||||
int i_DN; //!< Day number of week of the new leap second
|
||||
double d_DeltaT_LSF; //!< Delta time due to leap seconds after the new leap second effective [s]
|
||||
|
||||
// BeiDou to GPS time corrections
|
||||
double d_A0_GPS; //!< BDT clock bias relative to GPS time [s]
|
||||
double d_A1_GPS; //!< BDT clock rate relative to GPS time [s/s]
|
||||
|
||||
// BeiDou to Galileo time corrections
|
||||
double d_A0_GAL; //!< BDT clock bias relative to GAL time [s]
|
||||
double d_A1_GAL; //!< BDT clock rate relative to GAL time [s/s]
|
||||
|
||||
// BeiDou to GLONASS time corrections
|
||||
double d_A0_GLO; //!< BDT clock bias relative to GLO time [s]
|
||||
double d_A1_GLO; //!< BDT clock rate relative to GLO time [s/s]
|
||||
|
||||
Beidou_Dnav_Utc_Model();
|
||||
|
||||
template <class Archive>
|
||||
/*
|
||||
* \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.
|
||||
*/
|
||||
inline void serialize(Archive& archive, const unsigned int version)
|
||||
{
|
||||
using boost::serialization::make_nvp;
|
||||
if (version)
|
||||
{
|
||||
};
|
||||
archive& make_nvp("valid", valid);
|
||||
archive& make_nvp("d_A1", d_A1_UTC);
|
||||
archive& make_nvp("d_A0", d_A0_UTC);
|
||||
archive& make_nvp("d_DeltaT_LS", d_DeltaT_LS);
|
||||
archive& make_nvp("i_WN_LSF", i_WN_LSF);
|
||||
archive& make_nvp("i_DN", i_DN);
|
||||
archive& make_nvp("d_DeltaT_LSF", d_DeltaT_LSF);
|
||||
archive& make_nvp("d_A0_GPS", d_A0_GPS);
|
||||
archive& make_nvp("d_A0_GPS", d_A1_GPS);
|
||||
archive& make_nvp("d_A0_GPS", d_A0_GAL);
|
||||
archive& make_nvp("d_A0_GPS", d_A1_GAL);
|
||||
archive& make_nvp("d_A0_GPS", d_A0_GLO);
|
||||
archive& make_nvp("d_A0_GPS", d_A1_GLO);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@ -224,6 +224,19 @@ void Gnss_Satellite::set_PRN(uint32_t PRN_)
|
||||
PRN = PRN_;
|
||||
}
|
||||
}
|
||||
else if (system == "Beidou")
|
||||
{
|
||||
if (PRN_ < 1 or PRN_ > 37)
|
||||
{
|
||||
DLOG(INFO) << "This PRN is not defined";
|
||||
PRN = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
PRN = PRN_;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
DLOG(INFO) << "System " << system << " is not defined";
|
||||
@ -603,6 +616,57 @@ std::string Gnss_Satellite::what_block(const std::string& system_, uint32_t PRN_
|
||||
block_ = std::string("Unknown(Simulated)");
|
||||
}
|
||||
}
|
||||
if (system_ == "Beidou")
|
||||
{
|
||||
// Check https://en.wikipedia.org/wiki/List_of_BeiDou_satellites
|
||||
switch (PRN_)
|
||||
{
|
||||
case 19:
|
||||
block_ = std::string("BEIDOU-3 M1"); //!<Slot B-7; launched 2017/11/05
|
||||
break;
|
||||
case 20:
|
||||
block_ = std::string("BEIDOU-3 M2"); //!<Slot B-5; launched 2017/11/05
|
||||
break;
|
||||
case 21:
|
||||
block_ = std::string("BEIDOU 3M5"); //!<Slot B-?; launched 2018/02/12
|
||||
break;
|
||||
case 22:
|
||||
block_ = std::string("BEIDOU 3M6"); //!<Slot B-6; launched 2018/02/12
|
||||
break;
|
||||
case 23:
|
||||
block_ = std::string("BEIDOU 3M9"); //!<Slot C-7; launched 2018/07/29
|
||||
break;
|
||||
case 24:
|
||||
block_ = std::string("BEIDOU 3M10"); //!<Slot C-1; launched 2018/07/29
|
||||
break;
|
||||
case 25:
|
||||
block_ = std::string("BEIDOU 3M12"); //!<Slot C-8; launched 2018/08/24
|
||||
break;
|
||||
case 26:
|
||||
block_ = std::string("BEIDOU 3M11"); //!<Slot C-2; launched 2018/08/24
|
||||
break;
|
||||
case 27:
|
||||
block_ = std::string("BEIDOU 3M3"); //!<Slot A-?; launched 2018/01/11
|
||||
break;
|
||||
case 28:
|
||||
block_ = std::string("BEIDOU 3M4"); //!<Slot A-?; launched 2018/01/11
|
||||
break;
|
||||
case 29:
|
||||
block_ = std::string("BEIDOU 3M7"); //!<Slot A-?; launched 2018/03/29
|
||||
break;
|
||||
case 30:
|
||||
block_ = std::string("BEIDOU 3M8"); //!<Slot A-?; launched 2018/03/29
|
||||
break;
|
||||
case 32:
|
||||
block_ = std::string("BEIDOU 3M13"); //!<Slot B-1?; launched 2018/09/19
|
||||
break;
|
||||
case 33:
|
||||
block_ = std::string("BEIDOU 3M14"); //!<Slot B-3; launched 2018/09/19
|
||||
break;
|
||||
default:
|
||||
block_ = std::string("Unknown(Simulated)");
|
||||
}
|
||||
}
|
||||
return block_;
|
||||
}
|
||||
|
||||
|
@ -119,6 +119,7 @@ DECLARE_string(log_dir);
|
||||
#include "unit-tests/signal-processing-blocks/sources/gnss_sdr_valve_test.cc"
|
||||
#include "unit-tests/signal-processing-blocks/sources/unpack_2bit_samples_test.cc"
|
||||
// #include "unit-tests/signal-processing-blocks/acquisition/glonass_l2_ca_pcps_acquisition_test.cc"
|
||||
// #include "unit-tests/signal-processing-blocks/acquisition/beidou_b1i_pcps_acquisition_test.cc"
|
||||
|
||||
#if OPENCL_BLOCKS_TEST
|
||||
#include "unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc"
|
||||
|
@ -0,0 +1,350 @@
|
||||
/*!
|
||||
* \file beidou_b1i_pcps_acquisition_test.cc
|
||||
* \brief This class implements an acquisition test for
|
||||
* BeidouB1iPcpsAcquisition class based on some input parameters.
|
||||
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
|
||||
*
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2018 (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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "Beidou_B1I.h"
|
||||
#include "acquisition_dump_reader.h"
|
||||
#include "beidou_b1i_pcps_acquisition.h"
|
||||
#include "gnss_block_factory.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include "gnss_synchro.h"
|
||||
#include "gnuplot_i.h"
|
||||
#include "in_memory_configuration.h"
|
||||
#include "test_flags.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/analog/sig_source_c.h>
|
||||
#include <gnuradio/analog/sig_source_waveform.h>
|
||||
#include <gnuradio/blocks/file_source.h>
|
||||
#include <gnuradio/blocks/null_sink.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/top_block.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <chrono>
|
||||
|
||||
|
||||
// ######## GNURADIO BLOCK MESSAGE RECEVER #########
|
||||
class BeidouB1iPcpsAcquisitionTest_msg_rx;
|
||||
|
||||
typedef boost::shared_ptr<BeidouB1iPcpsAcquisitionTest_msg_rx> BeidouB1iPcpsAcquisitionTest_msg_rx_sptr;
|
||||
|
||||
BeidouB1iPcpsAcquisitionTest_msg_rx_sptr BeidouB1iPcpsAcquisitionTest_msg_rx_make();
|
||||
|
||||
class BeidouB1iPcpsAcquisitionTest_msg_rx : public gr::block
|
||||
{
|
||||
private:
|
||||
friend BeidouB1iPcpsAcquisitionTest_msg_rx_sptr BeidouB1iPcpsAcquisitionTest_msg_rx_make();
|
||||
void msg_handler_events(pmt::pmt_t msg);
|
||||
BeidouB1iPcpsAcquisitionTest_msg_rx();
|
||||
|
||||
public:
|
||||
int rx_message;
|
||||
~BeidouB1iPcpsAcquisitionTest_msg_rx(); //!< Default destructor
|
||||
};
|
||||
|
||||
|
||||
BeidouB1iPcpsAcquisitionTest_msg_rx_sptr BeidouB1iPcpsAcquisitionTest_msg_rx_make()
|
||||
{
|
||||
return BeidouB1iPcpsAcquisitionTest_msg_rx_sptr(new BeidouB1iPcpsAcquisitionTest_msg_rx());
|
||||
}
|
||||
|
||||
|
||||
void BeidouB1iPcpsAcquisitionTest_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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BeidouB1iPcpsAcquisitionTest_msg_rx::BeidouB1iPcpsAcquisitionTest_msg_rx() : gr::block("BeidouB1iPcpsAcquisitionTest_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(&BeidouB1iPcpsAcquisitionTest_msg_rx::msg_handler_events, this, _1));
|
||||
rx_message = 0;
|
||||
}
|
||||
|
||||
|
||||
BeidouB1iPcpsAcquisitionTest_msg_rx::~BeidouB1iPcpsAcquisitionTest_msg_rx()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// ###########################################################
|
||||
|
||||
class BeidouB1iPcpsAcquisitionTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
BeidouB1iPcpsAcquisitionTest()
|
||||
{
|
||||
factory = std::make_shared<GNSSBlockFactory>();
|
||||
config = std::make_shared<InMemoryConfiguration>();
|
||||
item_size = sizeof(gr_complex);
|
||||
gnss_synchro = Gnss_Synchro();
|
||||
doppler_max = 5000;
|
||||
doppler_step = 100;
|
||||
}
|
||||
|
||||
~BeidouB1iPcpsAcquisitionTest()
|
||||
{
|
||||
}
|
||||
|
||||
void init();
|
||||
void plot_grid();
|
||||
|
||||
gr::top_block_sptr top_block;
|
||||
std::shared_ptr<GNSSBlockFactory> factory;
|
||||
std::shared_ptr<InMemoryConfiguration> config;
|
||||
Gnss_Synchro gnss_synchro;
|
||||
size_t item_size;
|
||||
unsigned int doppler_max;
|
||||
unsigned int doppler_step;
|
||||
};
|
||||
|
||||
|
||||
void BeidouB1iPcpsAcquisitionTest::init()
|
||||
{
|
||||
gnss_synchro.Channel_ID = 0;
|
||||
gnss_synchro.System = 'C';
|
||||
std::string signal = "B1";
|
||||
signal.copy(gnss_synchro.Signal, 2, 0);
|
||||
gnss_synchro.PRN = 1;
|
||||
config->set_property("GNSS-SDR.internal_fs_sps", "25000000");
|
||||
config->set_property("Acquisition_B1.implementation", "BEIDOU_B1I_PCPS_Acquisition");
|
||||
config->set_property("Acquisition_B1.item_type", "gr_complex");
|
||||
config->set_property("Acquisition_B1.coherent_integration_time_ms", "1");
|
||||
if (FLAGS_plot_acq_grid == true)
|
||||
{
|
||||
config->set_property("Acquisition_B1.dump", "true");
|
||||
}
|
||||
else
|
||||
{
|
||||
config->set_property("Acquisition_B1.dump", "false");
|
||||
}
|
||||
config->set_property("Acquisition_B1.dump_filename", "./tmp-acq-beidou1/acquisition");
|
||||
config->set_property("Acquisition_B1.threshold", "0.00001");
|
||||
config->set_property("Acquisition_B1.doppler_max", std::to_string(doppler_max));
|
||||
config->set_property("Acquisition_B1.doppler_step", std::to_string(doppler_step));
|
||||
config->set_property("Acquisition_B1.repeat_satellite", "false");
|
||||
//config->set_property("Acquisition_B1.pfa", "0.0");
|
||||
}
|
||||
|
||||
|
||||
void BeidouB1iPcpsAcquisitionTest::plot_grid()
|
||||
{
|
||||
//load the measured values
|
||||
std::string basename = "./tmp-acq-beidou1/acquisition_C_B1";
|
||||
unsigned int sat = static_cast<unsigned int>(gnss_synchro.PRN);
|
||||
|
||||
unsigned int samples_per_code = static_cast<unsigned int>(round(4000000 / (BEIDOU_B1I_CODE_RATE_HZ / BEIDOU_B1I_CODE_LENGTH_CHIPS))); // !!
|
||||
acquisition_dump_reader acq_dump(basename, sat, doppler_max, doppler_step, samples_per_code);
|
||||
|
||||
if (!acq_dump.read_binary_acq()) std::cout << "Error reading files" << std::endl;
|
||||
|
||||
std::vector<int> *doppler = &acq_dump.doppler;
|
||||
std::vector<unsigned int> *samples = &acq_dump.samples;
|
||||
std::vector<std::vector<float> > *mag = &acq_dump.mag;
|
||||
|
||||
const std::string gnuplot_executable(FLAGS_gnuplot_executable);
|
||||
if (gnuplot_executable.empty())
|
||||
{
|
||||
std::cout << "WARNING: Although the flag plot_acq_grid has been set to TRUE," << std::endl;
|
||||
std::cout << "gnuplot has not been found in your system." << std::endl;
|
||||
std::cout << "Test results will not be plotted." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Plotting the acquisition grid. This can take a while..." << std::endl;
|
||||
try
|
||||
{
|
||||
boost::filesystem::path p(gnuplot_executable);
|
||||
boost::filesystem::path dir = p.parent_path();
|
||||
std::string gnuplot_path = dir.native();
|
||||
Gnuplot::set_GNUPlotPath(gnuplot_path);
|
||||
|
||||
Gnuplot g1("lines");
|
||||
g1.set_title("BeiDou signal acquisition for satellite PRN #" + std::to_string(gnss_synchro.PRN));
|
||||
g1.set_xlabel("Doppler [Hz]");
|
||||
g1.set_ylabel("Sample");
|
||||
//g1.cmd("set view 60, 105, 1, 1");
|
||||
g1.plot_grid3d(*doppler, *samples, *mag);
|
||||
|
||||
g1.savetops("BEIDOU_B1I_acq_grid");
|
||||
g1.savetopdf("BEIDOU_BI1_acq_grid");
|
||||
g1.showonscreen();
|
||||
}
|
||||
catch (const GnuplotException &ge)
|
||||
{
|
||||
std::cout << ge.what() << std::endl;
|
||||
}
|
||||
}
|
||||
std::string data_str = "./tmp-acq-beidou1";
|
||||
if (boost::filesystem::exists(data_str))
|
||||
{
|
||||
boost::filesystem::remove_all(data_str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_F(BeidouB1iPcpsAcquisitionTest, Instantiate)
|
||||
{
|
||||
init();
|
||||
boost::shared_ptr<BeidouB1iPcpsAcquisition> acquisition = boost::make_shared<BeidouB1iPcpsAcquisition>(config.get(), "Acquisition_B1", 1, 0);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(BeidouB1iPcpsAcquisitionTest, ConnectAndRun)
|
||||
{
|
||||
int fs_in = 25000000;
|
||||
int nsamples = 4000;
|
||||
std::chrono::time_point<std::chrono::system_clock> start, end;
|
||||
std::chrono::duration<double> 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<BeidouB1iPcpsAcquisition> acquisition = boost::make_shared<BeidouB1iPcpsAcquisition>(config.get(), "Acquisition_B1", 1, 0);
|
||||
boost::shared_ptr<BeidouB1iPcpsAcquisitionTest_msg_rx> msg_rx = BeidouB1iPcpsAcquisitionTest_msg_rx_make();
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
acquisition->connect(top_block);
|
||||
boost::shared_ptr<gr::analog::sig_source_c> source = gr::analog::sig_source_c::make(fs_in, gr::analog::GR_SIN_WAVE, 1000, 1, gr_complex(0));
|
||||
boost::shared_ptr<gr::block> 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({
|
||||
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.";
|
||||
|
||||
std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
TEST_F(BeidouB1iPcpsAcquisitionTest, ValidationOfResults)
|
||||
{
|
||||
std::chrono::time_point<std::chrono::system_clock> start, end;
|
||||
std::chrono::duration<double> elapsed_seconds(0.0);
|
||||
top_block = gr::make_top_block("Acquisition test");
|
||||
|
||||
double expected_delay_samples = 524;
|
||||
double expected_doppler_hz = 1680;
|
||||
|
||||
init();
|
||||
|
||||
if (FLAGS_plot_acq_grid == true)
|
||||
{
|
||||
std::string data_str = "./tmp-acq-beidou1";
|
||||
if (boost::filesystem::exists(data_str))
|
||||
{
|
||||
boost::filesystem::remove_all(data_str);
|
||||
}
|
||||
boost::filesystem::create_directory(data_str);
|
||||
}
|
||||
|
||||
std::shared_ptr<BeidouB1iPcpsAcquisition> acquisition = std::make_shared<BeidouB1iPcpsAcquisition>(config.get(), "Acquisition_B1", 1, 0);
|
||||
boost::shared_ptr<BeidouB1iPcpsAcquisitionTest_msg_rx> msg_rx = BeidouB1iPcpsAcquisitionTest_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.001);
|
||||
}) << "Failure setting threshold.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
acquisition->set_doppler_max(doppler_max);
|
||||
}) << "Failure setting doppler_max.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
acquisition->set_doppler_step(doppler_step);
|
||||
}) << "Failure setting doppler_step.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
acquisition->connect(top_block);
|
||||
}) << "Failure connecting acquisition to the top_block.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
std::string path = std::string(TEST_PATH);
|
||||
std::string file = path + "signal_samples/BEIDOU_B1I_ID_1_Fs_4Msps_2ms.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.";
|
||||
|
||||
acquisition->set_local_code();
|
||||
acquisition->set_state(1); // Ensure that acquisition starts at the first sample
|
||||
acquisition->init();
|
||||
|
||||
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.";
|
||||
|
||||
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<float>(delay_error_samples * 1023 / 4000);
|
||||
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";
|
||||
|
||||
if (FLAGS_plot_acq_grid == true)
|
||||
{
|
||||
plot_grid();
|
||||
}
|
||||
}
|
@ -31,7 +31,6 @@
|
||||
|
||||
#include "file_signal_source.h"
|
||||
#include "in_memory_configuration.h"
|
||||
#include <gnuradio/blocks/null_sink.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/top_block.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
@ -70,7 +70,7 @@
|
||||
#define FIVE_SECONDS 5000000 // five seconds in microseconds
|
||||
|
||||
void send_tracking_gps_input_samples(FILE *rx_signal_file,
|
||||
int num_remaining_samples, const gr::top_block_sptr& top_block)
|
||||
int num_remaining_samples, const gr::top_block_sptr &top_block)
|
||||
{
|
||||
int num_samples_transferred = 0; // number of samples that have been transferred to the DMA so far
|
||||
static int flowgraph_stopped = 0; // flag to indicate if the flowgraph is stopped already
|
||||
|
@ -30,7 +30,7 @@
|
||||
%clear all;
|
||||
samplingFreq = 64e6/16; %[Hz]
|
||||
channels=4;
|
||||
path='/home/javier/workspace/gnss-sdr-ref/trunk/install/';
|
||||
path='/home/sergi/gnss/gnss-sdr/install/';
|
||||
clear PRN_absolute_sample_start;
|
||||
for N=1:1:channels
|
||||
telemetry_log_path=[path 'telemetry' num2str(N-1) '.dat'];
|
||||
|
@ -28,13 +28,13 @@
|
||||
|
||||
%%%%%%%%% ?????? CONFIGURE !!! %%%%%%%%%%%%%
|
||||
|
||||
path = '/archive/';
|
||||
file = 'acq';
|
||||
path = '/home/dmiralles/Documents/gnss-sdr/';
|
||||
file = 'bds_acq';
|
||||
|
||||
sat = 7;
|
||||
sat = 32;
|
||||
|
||||
channel = 0;
|
||||
execution = 1;
|
||||
execution = 3;
|
||||
% Signal:
|
||||
% 1 GPS L1
|
||||
% 2 GPS L2M
|
||||
@ -42,10 +42,11 @@ execution = 1;
|
||||
% 4 Gal. E1B
|
||||
% 5 Gal. E5
|
||||
% 6 Glo. 1G
|
||||
% 7 BDS B1
|
||||
|
||||
signal_type = 1;
|
||||
signal_type = 7;
|
||||
|
||||
%%% True for light grid representation
|
||||
%%% True for light acq_grid representation
|
||||
lite_view = true;
|
||||
|
||||
%%% If lite_view, it sets the number of samples per chip in the graphical representation
|
||||
@ -78,21 +79,25 @@ switch(signal_type)
|
||||
n_chips = 511;
|
||||
system = 'R';
|
||||
signal = '1G';
|
||||
case 7
|
||||
n_chips = 2046;
|
||||
system = 'C';
|
||||
signal = 'B1';
|
||||
end
|
||||
filename = [path file '_' system '_' signal '_ch_' num2str(channel) '_' num2str(execution) '_sat_' num2str(sat) '.mat'];
|
||||
load(filename);
|
||||
[n_fft n_dop_bins] = size(grid);
|
||||
[d_max f_max] = find(grid == max(max(grid)));
|
||||
[n_fft n_dop_bins] = size(acq_grid);
|
||||
[d_max f_max] = find(acq_grid == max(max(acq_grid)));
|
||||
freq = (0 : n_dop_bins - 1) * doppler_step - doppler_max;
|
||||
delay = (0 : n_fft - 1) / n_fft * n_chips;
|
||||
figure(1)
|
||||
if(lite_view == false)
|
||||
surf(freq, delay, grid, 'FaceColor', 'interp', 'LineStyle', 'none')
|
||||
surf(freq, delay, acq_grid, 'FaceColor', 'interp', 'LineStyle', 'none')
|
||||
ylim([min(delay) max(delay)])
|
||||
else
|
||||
delay_interp = (0 : n_samples_per_chip * n_chips - 1) / n_samples_per_chip;
|
||||
grid_interp = spline(delay, grid', delay_interp)';
|
||||
surf(freq, delay_interp, grid_interp, 'FaceColor', 'interp', 'LineStyle', 'none')
|
||||
acq_grid_interp = spline(delay, acq_grid', delay_interp)';
|
||||
surf(freq, delay_interp, acq_grid_interp, 'FaceColor', 'interp', 'LineStyle', 'none')
|
||||
ylim([min(delay_interp) max(delay_interp)])
|
||||
end
|
||||
xlabel('Doppler shift / Hz')
|
||||
@ -101,14 +106,14 @@ ylabel('Code delay / chips')
|
||||
zlabel('Test statistics')
|
||||
figure(2)
|
||||
subplot(2,1,1)
|
||||
plot(freq, grid(d_max, :))
|
||||
plot(freq, acq_grid(d_max, :))
|
||||
xlim([min(freq) max(freq)])
|
||||
xlabel('Doppler shift / Hz')
|
||||
ylabel('Test statistics')
|
||||
title(['Fixed code delay to ' num2str((d_max - 1) / n_fft * n_chips) ' chips'])
|
||||
subplot(2,1,2)
|
||||
normalization = (d_samples_per_code^4) * input_power;
|
||||
plot(delay, acq_grid(:, f_max)./normalization)
|
||||
plot(delay, acq_acq_grid(:, f_max)./normalization)
|
||||
xlim([min(delay) max(delay)])
|
||||
xlabel('Code delay / chips')
|
||||
ylabel('Test statistics')
|
||||
|
Loading…
Reference in New Issue
Block a user