From 67312f9f784d9b0e971fb163f1be8a5080d7245c Mon Sep 17 00:00:00 2001 From: Gastd Date: Wed, 13 Sep 2017 20:55:09 -0300 Subject: [PATCH 01/96] Add missing headers --- .../glonass_l1_ca_dll_pll_c_aid_tracking.cc | 39 +++++++++++++++++++ .../glonass_l1_ca_dll_pll_c_aid_tracking.h | 39 +++++++++++++++++++ ...glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc | 39 +++++++++++++++++++ .../glonass_l1_ca_dll_pll_c_aid_tracking_cc.h | 39 +++++++++++++++++++ ...glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc | 39 +++++++++++++++++++ .../glonass_l1_ca_dll_pll_c_aid_tracking_sc.h | 39 +++++++++++++++++++ .../glonass_l1_ca_dll_pll_tracking_cc.cc | 39 +++++++++++++++++++ .../glonass_l1_ca_dll_pll_tracking_cc.h | 39 +++++++++++++++++++ 8 files changed, 312 insertions(+) diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc index 7d52ff931..800d1d4bd 100644 --- a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc @@ -1,3 +1,42 @@ +/*! + * \file glonass_l1_ca_dll_pll_tracking.h + * \brief Interface of an adapter of a DLL+PLL tracking loop block + * for Glonass L1 C/A to a TrackingInterface + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + #include "glonass_l1_ca_dll_pll_c_aid_tracking.h" #include #include "GLONASS_L1_CA.h" diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h index 3da85c58e..4cdd59ce6 100644 --- a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h @@ -1,3 +1,42 @@ +/*! + * \file glonass_l1_ca_dll_pll_tracking.h + * \brief Interface of an adapter of a DLL+PLL tracking loop block + * for Glonass L1 C/A to a TrackingInterface + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + #ifndef GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_H_ #define GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_H_ diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc index 367bcb371..ac8e1bffe 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc @@ -1,3 +1,42 @@ +/*! + * \file glonass_l1_ca_dll_pll_tracking.h + * \brief Interface of an adapter of a DLL+PLL tracking loop block + * for Glonass L1 C/A to a TrackingInterface + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + #include "glonass_l1_ca_dll_pll_c_aid_tracking_cc.h" #include #include diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h index 262707535..320d51b0c 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h @@ -1,3 +1,42 @@ +/*! + * \file glonass_l1_ca_dll_pll_tracking.h + * \brief Interface of an adapter of a DLL+PLL tracking loop block + * for Glonass L1 C/A to a TrackingInterface + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + #ifndef GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_CC_H #define GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_CC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc index 37b9ebaa7..c4eff7003 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc @@ -1,3 +1,42 @@ +/*! + * \file glonass_l1_ca_dll_pll_tracking.h + * \brief Interface of an adapter of a DLL+PLL tracking loop block + * for Glonass L1 C/A to a TrackingInterface + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + #include "glonass_l1_ca_dll_pll_c_aid_tracking_sc.h" #include #include diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h index dbc0a084a..0e008e04c 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h @@ -1,3 +1,42 @@ +/*! + * \file glonass_l1_ca_dll_pll_tracking.h + * \brief Interface of an adapter of a DLL+PLL tracking loop block + * for Glonass L1 C/A to a TrackingInterface + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + #ifndef GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_SC_H #define GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_SC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc index 4bdb0abf3..b60a0ef67 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc @@ -1,3 +1,42 @@ +/*! + * \file glonass_l1_ca_dll_pll_tracking.h + * \brief Interface of an adapter of a DLL+PLL tracking loop block + * for Glonass L1 C/A to a TrackingInterface + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + #include "glonass_l1_ca_dll_pll_tracking_cc.h" #include #include diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h index 0c40ef9fd..57dd77176 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h @@ -1,3 +1,42 @@ +/*! + * \file glonass_l1_ca_dll_pll_tracking.h + * \brief Interface of an adapter of a DLL+PLL tracking loop block + * for Glonass L1 C/A to a TrackingInterface + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com + * + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkha user, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + #ifndef GNSS_SDR_GLONASS_L1_CA_DLL_PLL_TRACKING_CC_H #define GNSS_SDR_GLONASS_L1_CA_DLL_PLL_TRACKING_CC_H From 69e54c32c09498ae0d938680ff74d420d243104c Mon Sep 17 00:00:00 2001 From: Gastd Date: Thu, 14 Sep 2017 13:19:27 -0300 Subject: [PATCH 02/96] Add carrier frequency variable --- .../glonass_l1_ca_dll_pll_tracking_cc.cc | 18 ++++++++++-------- .../glonass_l1_ca_dll_pll_tracking_cc.h | 1 + 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc index b60a0ef67..0c1a0b724 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc @@ -174,6 +174,7 @@ Glonass_L1_Ca_Dll_Pll_Tracking_cc::Glonass_L1_Ca_Dll_Pll_Tracking_cc( d_acq_code_phase_samples = 0.0; d_acq_carrier_doppler_hz = 0.0; d_carrier_doppler_hz = 0.0; + d_carrier_frequency_hz = 0.0; d_acc_carrier_phase_rad = 0.0; d_code_phase_samples = 0.0; d_rem_code_phase_chips = 0.0; @@ -228,9 +229,9 @@ void Glonass_L1_Ca_Dll_Pll_Tracking_cc::start_tracking() d_acq_code_phase_samples = corrected_acq_phase_samples; - d_carrier_doppler_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)); - // d_carrier_doppler_hz = d_acq_carrier_doppler_hz; - d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); + d_carrier_frequency_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)); + d_carrier_doppler_hz = d_acq_carrier_doppler_hz; + d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_frequency_hz / static_cast(d_fs_in); // DLL/PLL filter initialization d_carrier_loop_filter.initialize(); // initialize the carrier filter @@ -264,7 +265,7 @@ void Glonass_L1_Ca_Dll_Pll_Tracking_cc::start_tracking() d_pull_in = true; d_enable_tracking = true; - LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz + LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_frequency_hz << " Code Phase correction [samples]=" << delay_correction_samples << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples; } @@ -334,7 +335,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribu // take into account the carrier cycles accumulated in the pull in signal alignment d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * samples_offset; current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; - current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.Carrier_Doppler_hz = d_carrier_frequency_hz; current_synchro_data.fs = d_fs_in; current_synchro_data.correlation_length_ms = 1; *out[0] = current_synchro_data; @@ -358,6 +359,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribu // Carrier discriminator filter carr_error_filt_hz = d_carrier_loop_filter.get_carrier_nco(carr_error_hz); // New carrier Doppler frequency estimation + d_carrier_frequency_hz += carr_error_filt_hz; d_carrier_doppler_hz = d_acq_carrier_doppler_hz + carr_error_filt_hz; d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GLONASS_L1_CA_CODE_RATE_HZ) / d_glonass_freq_ch); @@ -382,7 +384,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribu //################### PLL COMMANDS ################################################# // carrier phase step (NCO phase increment per sample) [rads/sample] - d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); + d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_frequency_hz / static_cast(d_fs_in); // remnant carrier phase to prevent overflow in the code NCO d_rem_carr_phase_rad = d_rem_carr_phase_rad + d_carrier_phase_step_rad * d_current_prn_length_samples; d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, GLONASS_TWO_PI); @@ -434,7 +436,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribu current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples; current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; - current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.Carrier_Doppler_hz = d_carrier_frequency_hz; current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; current_synchro_data.Flag_valid_symbol_output = true; current_synchro_data.correlation_length_ms = 1; @@ -483,7 +485,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribu d_dump_file.write(reinterpret_cast(&d_acc_carrier_phase_rad), sizeof(double)); // carrier and code frequency - d_dump_file.write(reinterpret_cast(&d_carrier_doppler_hz), sizeof(double)); + d_dump_file.write(reinterpret_cast(&d_carrier_frequency_hz), sizeof(double)); d_dump_file.write(reinterpret_cast(&d_code_freq_chips), sizeof(double)); // PLL commands diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h index 57dd77176..cf1923fb6 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h @@ -140,6 +140,7 @@ private: double d_code_freq_chips; double d_code_phase_step_chips; double d_carrier_doppler_hz; + double d_carrier_frequency_hz; double d_carrier_phase_step_rad; double d_acc_carrier_phase_rad; double d_code_phase_samples; From 7c8855b9acc9b992066397597ffb0fe9517c00c3 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Wed, 29 Nov 2017 15:51:30 +0100 Subject: [PATCH 03/96] Add GPS L5 files --- .../telemetry_decoder/adapters/CMakeLists.txt | 3 +- .../adapters/gps_l5_telemetry_decoder.cc | 103 ++++++++ .../adapters/gps_l5_telemetry_decoder.h | 95 +++++++ .../gnuradio_blocks/CMakeLists.txt | 1 + .../galileo_e5a_telemetry_decoder_cc.cc | 10 +- .../gps_l5_telemetry_decoder_cc.cc | 236 ++++++++++++++++++ .../gps_l5_telemetry_decoder_cc.h | 105 ++++++++ .../libs/libswiftcnav/cnav_msg.c | 6 +- .../libs/libswiftcnav/cnav_msg.h | 34 +++ src/core/receiver/gnss_block_factory.cc | 13 + 10 files changed, 595 insertions(+), 11 deletions(-) create mode 100644 src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.cc create mode 100644 src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.h create mode 100644 src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc create mode 100644 src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h diff --git a/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt b/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt index 974adfb53..07dd84bea 100644 --- a/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt @@ -18,7 +18,8 @@ set(TELEMETRY_DECODER_ADAPTER_SOURCES gps_l1_ca_telemetry_decoder.cc - gps_l2c_telemetry_decoder.cc + gps_l2c_telemetry_decoder.cc + gps_l5_telemetry_decoder.cc galileo_e1b_telemetry_decoder.cc sbas_l1_telemetry_decoder.cc galileo_e5a_telemetry_decoder.cc diff --git a/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.cc new file mode 100644 index 000000000..74f262bcf --- /dev/null +++ b/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.cc @@ -0,0 +1,103 @@ +/*! + * \file gps_l5_telemetry_decoder.cc + * \brief Implementation of an adapter of a GPS L5 NAV data decoder block + * to a TelemetryDecoderInterface + * \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#include "gps_l5_telemetry_decoder.h" +#include +#include +#include "concurrent_queue.h" +#include "gps_cnav_ephemeris.h" +#include "gps_almanac.h" +#include "gps_cnav_iono.h" +#include "gps_cnav_utc_model.h" +#include "configuration_interface.h" + + +using google::LogMessage; + +GpsL5TelemetryDecoder::GpsL5TelemetryDecoder(ConfigurationInterface* configuration, + std::string role, + unsigned int in_streams, + unsigned int out_streams) : + role_(role), + in_streams_(in_streams), + out_streams_(out_streams) +{ + std::string default_dump_filename = "./navigation.dat"; + DLOG(INFO) << "role " << role; + dump_ = configuration->property(role + ".dump", false); + dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + // make telemetry decoder object + telemetry_decoder_ = gps_l5_make_telemetry_decoder_cc(satellite_, dump_); + DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; + + LOG(INFO) << "global navigation message queue assigned to telemetry_decoder (" << telemetry_decoder_->unique_id() << ")" << "role " << role; + channel_ = 0; +} + + +GpsL5TelemetryDecoder::~GpsL5TelemetryDecoder() +{} + + +void GpsL5TelemetryDecoder::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 GpsL5TelemetryDecoder::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 GpsL5TelemetryDecoder::disconnect(gr::top_block_sptr top_block) +{ + if(top_block) { /* top_block is not null */}; + // Nothing to disconnect +} + + +gr::basic_block_sptr GpsL5TelemetryDecoder::get_left_block() +{ + return telemetry_decoder_; +} + + +gr::basic_block_sptr GpsL5TelemetryDecoder::get_right_block() +{ + return telemetry_decoder_; +} diff --git a/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.h new file mode 100644 index 000000000..49a18111c --- /dev/null +++ b/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.h @@ -0,0 +1,95 @@ +/*! + * \file gps_l5_telemetry_decoder.h + * \brief Interface of an adapter of a GPS L5 (CNAV) data decoder block + * to a TelemetryDecoderInterface + * \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_GPS_L5_TELEMETRY_DECODER_H_ +#define GNSS_SDR_GPS_L5_TELEMETRY_DECODER_H_ + +#include +#include "telemetry_decoder_interface.h" +#include "gps_l5_telemetry_decoder_cc.h" + + +class ConfigurationInterface; + +/*! + * \brief This class implements a NAV data decoder for GPS L5 + */ +class GpsL5TelemetryDecoder : public TelemetryDecoderInterface +{ +public: + GpsL5TelemetryDecoder(ConfigurationInterface* configuration, + std::string role, + unsigned int in_streams, + unsigned int out_streams); + + virtual ~GpsL5TelemetryDecoder(); + + inline std::string role() override + { + return role_; + } + + //! Returns "GPS_L5_Telemetry_Decoder" + inline std::string implementation() override + { + return "GPS_L5_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: + gps_l5_telemetry_decoder_cc_sptr telemetry_decoder_; + Gnss_Satellite satellite_; + int channel_; + bool dump_; + std::string dump_filename_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; +}; + +#endif diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt b/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt index 7de1a365b..80f4ae476 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt @@ -19,6 +19,7 @@ set(TELEMETRY_DECODER_GR_BLOCKS_SOURCES gps_l1_ca_telemetry_decoder_cc.cc gps_l2c_telemetry_decoder_cc.cc + gps_l5_telemetry_decoder_cc.cc galileo_e1b_telemetry_decoder_cc.cc sbas_l1_telemetry_decoder_cc.cc galileo_e5a_telemetry_decoder_cc.cc diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc index a058f169b..d390ee7ee 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc @@ -297,14 +297,8 @@ int galileo_e5a_telemetry_decoder_cc::general_work (int noutput_items __attribut d_symbol_counter = 0; flag_bit_start = true; corr_value = 0; - while(d_preamble_init.size() > 0) - { //Clear preamble correlating queue - d_preamble_init.pop_front(); - } - while(d_symbol_history.size() > 0) - { //Clear symbol queue in order to prevent possible symbol discontinuities - d_symbol_history.pop_front(); - } + d_preamble_init.clear(); + d_symbol_history.clear(); LOG(INFO) << "Bit start sync for Galileo E5a satellite " << d_satellite; } else diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc new file mode 100644 index 000000000..313322939 --- /dev/null +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc @@ -0,0 +1,236 @@ +/*! + * \file gps_l5_telemetry_decoder_cc.cc + * \brief Implementation of a NAV message demodulator block based on + * Kay Borre book MATLAB-based GPS receiver + * \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include "gnss_synchro.h" +#include "gps_l5_telemetry_decoder_cc.h" + +using google::LogMessage; + +gps_l5_telemetry_decoder_cc_sptr +gps_l5_make_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump) +{ + return gps_l5_telemetry_decoder_cc_sptr(new gps_l5_telemetry_decoder_cc(satellite, dump)); +} + + +gps_l5_telemetry_decoder_cc::gps_l5_telemetry_decoder_cc( + const Gnss_Satellite & satellite, bool dump) : gr::block("gps_l5_telemetry_decoder_cc", + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) +{ + // Telemetry Bit transition synchronization port out + this->message_port_register_out(pmt::mp("preamble_timestamp_s")); + // Ephemeris data port out + this->message_port_register_out(pmt::mp("telemetry")); + // initialize internal vars + d_dump = dump; + d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); + DLOG(INFO) << "GPS L5 TELEMETRY PROCESSING: satellite " << d_satellite; + //set_output_multiple (1); + d_channel = 0; + d_flag_valid_word = false; + d_TOW_at_current_symbol = 0; + d_TOW_at_Preamble = 0; + d_state = 0; //initial state + d_crc_error_count = 0; + + //initialize the CNAV frame decoder (libswiftcnav) + cnav_msg_decoder_init(&d_cnav_decoder); +} + + +gps_l5_telemetry_decoder_cc::~gps_l5_telemetry_decoder_cc() +{ + 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(); + } + } +} + + +int gps_l5_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) +{ + // get pointers on in- and output gnss-synchro objects + Gnss_Synchro *out = reinterpret_cast(output_items[0]); // Get the output buffer pointer + const Gnss_Synchro *in = reinterpret_cast(input_items[0]); // Get the input buffer pointer + + bool flag_new_cnav_frame = false; + cnav_msg_t msg; + u32 delay = 0; + + //add the symbol to the decoder + u8 symbol_clip = static_cast(in[0].Prompt_I > 0) * 255; + flag_new_cnav_frame = cnav_msg_decoder_add_symbol(&d_cnav_decoder, symbol_clip, &msg, &delay); + + consume_each(1); //one by one + + // UPDATE GNSS SYNCHRO DATA + Gnss_Synchro current_synchro_data; //structure to save the synchronization information and send the output object to the next block + + //1. Copy the current tracking output + current_synchro_data = in[0]; + + //2. Add the telemetry decoder information + //check if new CNAV frame is available + if (flag_new_cnav_frame == true) + { + std::bitset raw_bits; + //Expand packet bits to bitsets. Notice the reverse order of the bits sequence, required by the CNAV message decoder + for (u32 i = 0; i < GPS_L5_CNAV_DATA_PAGE_BITS ; i++) + { + raw_bits[GPS_L5_CNAV_DATA_PAGE_BITS - 1 - i] = ((msg.raw_msg[i/8] >> (7 - i%8)) & 1u); + } + + d_CNAV_Message.decode_page(raw_bits); + + //Push the new navigation data to the queues + if (d_CNAV_Message.have_new_ephemeris() == true) + { + // get ephemeris object for this SV + std::shared_ptr tmp_obj = std::make_shared(d_CNAV_Message.get_ephemeris()); + std::cout << "New GPS CNAV message received: ephemeris from satellite " << d_satellite << std::endl; + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + + } + if (d_CNAV_Message.have_new_iono() == true) + { + std::shared_ptr tmp_obj = std::make_shared(d_CNAV_Message.get_iono()); + std::cout << "New GPS CNAV message received: iono model parameters from satellite " << d_satellite << std::endl; + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + + if (d_CNAV_Message.have_new_utc_model() == true) + { + std::shared_ptr tmp_obj = std::make_shared(d_CNAV_Message.get_utc_model()); + std::cout << "New GPS CNAV message received: UTC model parameters from satellite " << d_satellite << std::endl; + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + + //update TOW at the preamble instant + d_TOW_at_Preamble = static_cast(msg.tow); + //* The time of the last input symbol can be computed from the message ToW and + //* delay by the formulae: + //* \code + //* symbolTime_ms = msg->tow * 6000 + *pdelay * 20 + d_TOW_at_current_symbol = static_cast(msg.tow) * 6.0 + static_cast(delay) * GPS_L5_PERIOD + 6 * GPS_L5_PERIOD; + d_TOW_at_current_symbol = floor(d_TOW_at_current_symbol * 1000.0) / 1000.0; + d_flag_valid_word = true; + } + else + { + d_TOW_at_current_symbol += GPS_L5_PERIOD; + if (current_synchro_data.Flag_valid_symbol_output == false) + { + d_flag_valid_word = false; + } + } + current_synchro_data.TOW_at_current_symbol_s = d_TOW_at_current_symbol; + current_synchro_data.Flag_valid_word = d_flag_valid_word; + + // if (flag_PLL_180_deg_phase_locked == true) + // { + // //correct the accumulated phase for the Costas loop phase shift, if required + // current_synchro_data.Carrier_phase_rads += GPS_PI; + // } + + if(d_dump == true) + { + // MULTIPLEXED FILE RECORDING - Record results to file + try + { + double tmp_double; + unsigned long int tmp_ulong_int; + tmp_double = d_TOW_at_current_symbol; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_ulong_int = current_synchro_data.Tracking_sample_counter; + d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(unsigned long int)); + tmp_double = d_TOW_at_Preamble; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + } + catch (const std::ifstream::failure & e) + { + LOG(WARNING) << "Exception writing observables dump file " << e.what(); + } + } + + //3. Make the output (copy the object contents to the GNURadio reserved memory) + out[0] = current_synchro_data; + return 1; +} + + +void gps_l5_telemetry_decoder_cc::set_satellite(const Gnss_Satellite & satellite) +{ + d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); + LOG(INFO) << "GPS L5 CNAV telemetry decoder in channel " << this->d_channel << " set to satellite " << d_satellite; +} + + +void gps_l5_telemetry_decoder_cc::set_channel(int channel) +{ + d_channel = channel; + LOG(INFO) << "GPS L5 CNAV channel set to " << channel; + // ############# ENABLE DATA FILE LOG ################# + if (d_dump == true) + { + if (d_dump_file.is_open() == false) + { + try + { + d_dump_filename = "telemetry_L5_"; + d_dump_filename.append(boost::lexical_cast(d_channel)); + d_dump_filename.append(".dat"); + d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit ); + d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "Telemetry decoder dump enabled on channel " << d_channel + << " Log file: " << d_dump_filename.c_str(); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); + } + } + } +} diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h new file mode 100644 index 000000000..bf45680d4 --- /dev/null +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h @@ -0,0 +1,105 @@ +/*! + * \file gps_l5_telemetry_decoder_cc.h + * \brief Interface of a CNAV message demodulator block based on + * Kay Borre book MATLAB-based GPS receiver + * \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GPS_L5_TELEMETRY_DECODER_CC_H +#define GNSS_SDR_GPS_L5_TELEMETRY_DECODER_CC_H + +#include // for copy +#include +#include +#include +#include // for pair +#include +#include +#include "gnss_satellite.h" +#include "gps_cnav_navigation_message.h" +#include "gps_cnav_ephemeris.h" +#include "gps_cnav_iono.h" +#include "concurrent_queue.h" + +extern "C" { + #include "cnav_msg.h" + #include "edc.h" + #include "bits.h" +} + +#include "GPS_L5.h" + +class gps_l5_telemetry_decoder_cc; + +typedef boost::shared_ptr gps_l5_telemetry_decoder_cc_sptr; + +gps_l5_telemetry_decoder_cc_sptr +gps_l5_make_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump); + +/*! + * \brief This class implements a block that decodes the SBAS integrity and corrections data defined in RTCA MOPS DO-229 + * + */ +class gps_l5_telemetry_decoder_cc : public gr::block +{ +public: + ~gps_l5_telemetry_decoder_cc(); + 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 gps_l5_telemetry_decoder_cc_sptr + gps_l5_make_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump); + gps_l5_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump); + + bool d_dump; + Gnss_Satellite d_satellite; + int d_channel; + + std::string d_dump_filename; + std::ofstream d_dump_file; + + cnav_msg_decoder_t d_cnav_decoder; + + int d_state; + int d_crc_error_count; + + double d_TOW_at_current_symbol; + double d_TOW_at_Preamble; + bool d_flag_valid_word; + + Gps_CNAV_Navigation_Message d_CNAV_Message; +}; + + +#endif diff --git a/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.c b/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.c index bbb9a92f6..fabf3195b 100644 --- a/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.c +++ b/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.c @@ -49,9 +49,11 @@ */ /** Viterbi decoder reversed polynomial A */ #define GPS_L2C_V27_POLY_A (0x4F) /* 0b01001111 - reversed 0171*/ +#define GPS_L5_V27_POLY_A (0x4F) /* 0b01001111 - reversed 0171*/ + /** Viterbi decoder reversed polynomial B */ #define GPS_L2C_V27_POLY_B (0x6D) /* 0b01101101 - reversed 0133 */ - +#define GPS_L5_V27_POLY_B (0x6D) /* 0b01101101 - reversed 0133 */ /* * GPS L2C message constants. */ @@ -67,7 +69,7 @@ /** GPS LC2 CNAV CRC length in bits */ #define GPS_CNAV_MSG_CRC_LENGTH (24) /** GPS L2C CNAV message payload length in bits */ -#define GPS_CNAV_MSG_DATA_LENGTH (GPS_CNAV_MSG_LENGTH-GPS_CNAV_MSG_CRC_LENGTH) +#define GPS_CNAV_MSG_DATA_LENGTH (GPS_CNAV_MSG_LENGTH - GPS_CNAV_MSG_CRC_LENGTH) /** GPS L2C CNAV message lock detector threshold */ #define GPS_CNAV_LOCK_MAX_CRC_FAILS (10) diff --git a/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.h b/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.h index 8b8141358..4b338a1ee 100644 --- a/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.h +++ b/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.h @@ -49,12 +49,16 @@ /** Size of the Viterbi decoder history. */ #define GPS_L2_V27_HISTORY_LENGTH_BITS 64 +#define GPS_L5_V27_HISTORY_LENGTH_BITS 64 /** Bits to accumulate before decoding starts. */ #define GPS_L2C_V27_INIT_BITS (32) +#define GPS_L5_V27_INIT_BITS (32) /** Bits to decode at a time. */ #define GPS_L2C_V27_DECODE_BITS (32) +#define GPS_L5_V27_DECODE_BITS (32) /** Bits in decoder tail. We ignore them. */ #define GPS_L2C_V27_DELAY_BITS (32) +#define GPS_L5_V27_DELAY_BITS (32) /** * GPS CNAV message container. * @@ -69,6 +73,15 @@ typedef struct u8 raw_msg[GPS_L2C_V27_DECODE_BITS + GPS_L2C_V27_DELAY_BITS]; /**< RAW MSG for GNSS-SDR */ } cnav_msg_t; +typedef struct +{ + u8 prn; /**< SV PRN. 0..31 */ + u8 msg_id; /**< Message id. 0..31 */ + u32 tow; /**< GPS ToW in 6-second units. Multiply to 6 to get seconds. */ + bool alert; /**< CNAV message alert flag */ + u8 raw_msg[GPS_L5_V27_DECODE_BITS + GPS_L5_V27_DELAY_BITS]; /**< RAW MSG for GNSS-SDR */ +} cnav_L5_msg_t; + /** * GPS CNAV decoder component. * This component controls symbol decoding string. @@ -96,6 +109,27 @@ typedef struct { * do not produce output. */ } cnav_v27_part_t; +typedef struct { + v27_t dec; /**< Viterbi block decoder object */ + v27_decision_t decisions[GPS_L5_V27_HISTORY_LENGTH_BITS]; + /**< Decision graph */ + unsigned char symbols[(GPS_L5_V27_INIT_BITS + GPS_L5_V27_DECODE_BITS) * 2]; + /**< Symbol buffer */ + size_t n_symbols; /**< Count of symbols in the symbol buffer */ + unsigned char decoded[GPS_L5_V27_DECODE_BITS + GPS_L5_V27_DELAY_BITS]; + /**< Decode buffer */ + size_t n_decoded; /**< Number of bits in the decode buffer */ + bool preamble_seen; /**< When true, the decode buffer is aligned on + * preamble. */ + bool invert; /**< When true, indicates the bits are inverted */ + bool message_lock; /**< When true, indicates the message boundary + * is found. */ + bool crc_ok; /**< Flag that the last message had good CRC */ + size_t n_crc_fail; /**< Counter for CRC failures */ + bool init; /**< Initial state flag. When true, initial bits + * do not produce output. */ +} cnav_L5_v27_part_t; + /** * GPS CNAV message lock and decoder object. * diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 6ec273785..db0103fc6 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -88,6 +88,7 @@ #include "gps_l2_m_dll_pll_tracking.h" #include "gps_l1_ca_telemetry_decoder.h" #include "gps_l2c_telemetry_decoder.h" +#include "gps_l5_telemetry_decoder.h" #include "galileo_e1b_telemetry_decoder.h" #include "galileo_e5a_telemetry_decoder.h" #include "sbas_l1_telemetry_decoder.h" @@ -1094,6 +1095,12 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams)); block = std::move(block_); } + else if (implementation.compare("GPS_L5_Telemetry_Decoder") == 0) + { + std::unique_ptr block_(new GpsL5TelemetryDecoder(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } else if (implementation.compare("Galileo_E1B_Telemetry_Decoder") == 0) { std::unique_ptr block_(new GalileoE1BTelemetryDecoder(configuration.get(), role, in_streams, @@ -1368,6 +1375,12 @@ std::unique_ptr GNSSBlockFactory::GetTlmBlock( out_streams)); block = std::move(block_); } + else if (implementation.compare("GPS_L5_Telemetry_Decoder") == 0) + { + std::unique_ptr block_(new GpsL5TelemetryDecoder(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } else { // Log fatal. This causes execution to stop. From 11486670ec198358da615b1475e63bd32c5520f7 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Thu, 30 Nov 2017 16:04:20 +0100 Subject: [PATCH 04/96] Modify CNAV message structure header --- src/algorithms/PVT/libs/rtklib_solver.cc | 52 ++++++++++++++++++- .../gps_l5_telemetry_decoder_cc.cc | 4 +- src/core/system_parameters/GPS_L5.h | 4 +- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/algorithms/PVT/libs/rtklib_solver.cc b/src/algorithms/PVT/libs/rtklib_solver.cc index 1d29e5a5a..622f7a1c4 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.cc +++ b/src/algorithms/PVT/libs/rtklib_solver.cc @@ -258,7 +258,10 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ //convert ephemeris from GNSS-SDR class to RTKLIB structure eph_data[valid_obs] = eph_to_rtklib(gps_cnav_ephemeris_iter->second); //convert observation from GNSS-SDR class to RTKLIB structure - obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}}; + unsigned char default_code_ = static_cast(CODE_NONE); + obsd_t newobs = {{0,0}, '0', '0', {}, {}, + {default_code_, default_code_, default_code_}, + {}, {0.0, 0.0, 0.0}, {}}; obs_data[valid_obs] = insert_obs_to_rtklib(newobs, gnss_observables_iter->second, gps_cnav_ephemeris_iter->second.i_GPS_week, @@ -271,6 +274,53 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN; } } + //GPS L5 + if(sig_.compare("5X") == 0) + { + gps_cnav_ephemeris_iter = gps_cnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_cnav_ephemeris_iter != gps_cnav_ephemeris_map.cend()) + { + // 1. Find the same satellite in GPS L1 band + gps_ephemeris_iter = gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_ephemeris_iter != gps_ephemeris_map.cend()) + { + // 2. If found, replace the existing GPS L1 ephemeris with the GPS L5 ephemeris + // (more precise!), and attach the L5 observation to the L1 observation in RTKLIB structure + for (int i = 0; i < valid_obs; i++) + { + if (eph_data[i].sat == static_cast(gnss_observables_iter->second.PRN)) + { + eph_data[i] = eph_to_rtklib(gps_cnav_ephemeris_iter->second); + obs_data[i] = insert_obs_to_rtklib(obs_data[i], + gnss_observables_iter->second, + gps_cnav_ephemeris_iter->second.i_GPS_week, + 2);//Band 3 (L5) + break; + } + } + } + else + { + // 3. If not found, insert the GPS L5 ephemeris and the observation + //convert ephemeris from GNSS-SDR class to RTKLIB structure + eph_data[valid_obs] = eph_to_rtklib(gps_cnav_ephemeris_iter->second); + //convert observation from GNSS-SDR class to RTKLIB structure + unsigned char default_code_ = static_cast(CODE_NONE); + obsd_t newobs = {{0,0}, '0', '0', {}, {}, + {default_code_, default_code_, default_code_}, + {}, {0.0, 0.0, 0.0}, {}}; + obs_data[valid_obs] = insert_obs_to_rtklib(newobs, + gnss_observables_iter->second, + gps_cnav_ephemeris_iter->second.i_GPS_week, + 2);//Band 3 (L5) + valid_obs++; + } + } + else // the ephemeris are not available for this SV + { + DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN; + } + } break; } default : diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc index 313322939..bb90434dc 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc @@ -154,13 +154,13 @@ int gps_l5_telemetry_decoder_cc::general_work (int noutput_items __attribute__(( //* delay by the formulae: //* \code //* symbolTime_ms = msg->tow * 6000 + *pdelay * 20 - d_TOW_at_current_symbol = static_cast(msg.tow) * 6.0 + static_cast(delay) * GPS_L5_PERIOD + 6 * GPS_L5_PERIOD; + d_TOW_at_current_symbol = static_cast(msg.tow) * 6.0 + static_cast(delay) * GPS_L5i_PERIOD + 6 * GPS_L5i_PERIOD; d_TOW_at_current_symbol = floor(d_TOW_at_current_symbol * 1000.0) / 1000.0; d_flag_valid_word = true; } else { - d_TOW_at_current_symbol += GPS_L5_PERIOD; + d_TOW_at_current_symbol += GPS_L5i_PERIOD; if (current_synchro_data.Flag_valid_symbol_output == false) { d_flag_valid_word = false; diff --git a/src/core/system_parameters/GPS_L5.h b/src/core/system_parameters/GPS_L5.h index f64b7f379..c053796c9 100644 --- a/src/core/system_parameters/GPS_L5.h +++ b/src/core/system_parameters/GPS_L5.h @@ -37,7 +37,7 @@ #include // std::pair #include "MATH_CONSTANTS.h" #include "gnss_frequencies.h" -#include "GPS_L2C.h" +#include "GPS_L2C.h" // CNAV GPS NAVIGATION MESSAGE STRUCTURE // Physical constants const double GPS_L5_C_m_s = 299792458.0; //!< The speed of light, [m/s] @@ -178,7 +178,7 @@ const int32_t GPS_L5q_INIT_REG[210] = const int GPS_L5_CNAV_DATA_PAGE_BITS = 300; //!< GPS L5 CNAV page length, including preamble and CRC [bits] const int GPS_L5_SYMBOLS_PER_BIT = 2; -const int GPS_L5_SAMPLES_PER_SYMBOL = 1; +const int GPS_L5_SAMPLES_PER_SYMBOL = 10; const int GPS_L5_CNAV_DATA_PAGE_SYMBOLS = 600; const int GPS_L5_CNAV_DATA_PAGE_DURATION_S = 6; From 6395f0e5fc4b88f611ea6c61f0b6802acf6a22a7 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Thu, 30 Nov 2017 17:42:19 +0100 Subject: [PATCH 05/96] Add GPS L5 Channel --- src/algorithms/PVT/adapters/rtklib_pvt.cc | 9 +- .../PVT/gnuradio_blocks/rtklib_pvt_cc.cc | 30 +++++- src/core/receiver/gnss_block_factory.cc | 99 ++++++++++++++++++- src/core/receiver/gnss_block_factory.h | 4 + src/core/receiver/gnss_flowgraph.cc | 18 +++- 5 files changed, 152 insertions(+), 8 deletions(-) diff --git a/src/algorithms/PVT/adapters/rtklib_pvt.cc b/src/algorithms/PVT/adapters/rtklib_pvt.cc index be1c9bd8d..e04dd0765 100644 --- a/src/algorithms/PVT/adapters/rtklib_pvt.cc +++ b/src/algorithms/PVT/adapters/rtklib_pvt.cc @@ -141,14 +141,17 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, */ int gps_1C_count = configuration->property("Channels_1C.count", 0); int gps_2S_count = configuration->property("Channels_2S.count", 0); + int gps_L5_count = configuration->property("Channels_L5.count", 0); int gal_1B_count = configuration->property("Channels_1B.count", 0); int gal_E5a_count = configuration->property("Channels_5X.count", 0); // GPS L5 or Galileo E5a ? int gal_E5b_count = configuration->property("Channels_7X.count", 0); unsigned int type_of_receiver = 0; + // *******************WARNING!!!!!!!*********** + // GPS L5 only configurable for single frequency, single system at the moment!!!!!! if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 1; if( (gps_1C_count == 0) && (gps_2S_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 2; - + if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 3; if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 4; if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0)) type_of_receiver = 5; if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0)) type_of_receiver = 6; @@ -194,7 +197,7 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, int num_bands = 0; if ((gps_1C_count > 0) || (gal_1B_count > 0)) num_bands = 1; if (gps_2S_count > 0) num_bands = 2; - if ((gal_E5a_count > 0) || (gal_E5b_count > 0)) num_bands = 3; + if ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0)) num_bands = 3; int number_of_frequencies = configuration->property(role + ".num_bands", num_bands); /* (1:L1, 2:L1+L2, 3:L1+L2+L5) */ if( (number_of_frequencies < 1) || (number_of_frequencies > 3) ) { @@ -272,7 +275,7 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, int earth_tide = configuration->property(role + ".earth_tide", 0); int nsys = 0; - if ((gps_1C_count > 0) || (gps_2S_count > 0)) nsys += SYS_GPS; + 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; 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 */ diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc index 152fc6f1d..4c1f4bf5d 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc @@ -345,7 +345,7 @@ rtklib_pvt_cc::~rtklib_pvt_cc() boost::archive::xml_oarchive xml(ofs); xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->gps_cnav_ephemeris_map); ofs.close(); - LOG(INFO) << "Saved GPS L2CM Ephemeris map data"; + LOG(INFO) << "Saved GPS L2CM or L5 Ephemeris map data"; } catch (const std::exception & e) { @@ -354,7 +354,7 @@ rtklib_pvt_cc::~rtklib_pvt_cc() } else { - LOG(WARNING) << "Failed to save GPS L2CM Ephemeris, map is empty"; + LOG(WARNING) << "Failed to save GPS L2CM or L5 Ephemeris, map is empty"; } //save GPS L1 CA ephemeris to XML file @@ -647,6 +647,15 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite b_rinex_header_written = true; // do not write header anymore } } + if(type_of_rx == 3) // GPS L5 only + { + if (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend()) + { + rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time); + rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + } if(type_of_rx == 4) // Galileo E1B only { if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) @@ -749,6 +758,10 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite { rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_cnav_ephemeris_map); } + if(type_of_rx == 3) // GPS L5 only + { + rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_cnav_ephemeris_map); + } if( (type_of_rx == 4) || (type_of_rx == 5) || (type_of_rx == 6) ) // Galileo { rp->log_rinex_nav(rp->navGalFile, d_ls_pvt->galileo_ephemeris_map); @@ -799,6 +812,19 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite b_rinex_header_updated = true; } } + if(type_of_rx == 3) // GPS L5 + { + if (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.end()) + { + rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated && (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); + rp->update_nav_header(rp->navFile, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->gps_cnav_iono); + b_rinex_header_updated = true; + } + } if(type_of_rx == 4) // Galileo E1B only { if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index db0103fc6..8248de9a2 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -523,6 +523,74 @@ std::unique_ptr GNSSBlockFactory::GetChannel_5X( return channel_; } +//********* GPS L5 CHANNEL ***************** +std::unique_ptr GNSSBlockFactory::GetChannel_L5( + std::shared_ptr configuration, + std::string acq, std::string trk, std::string tlm, int channel, + boost::shared_ptr queue) +{ + std::stringstream stream; + stream << channel; + std::string id = stream.str(); + LOG(INFO) << "Instantiating Channel " << id << " with Acquisition Implementation: " + << acq << ", Tracking Implementation: " << trk << ", Telemetry Decoder implementation: " << tlm; + std::string aux = configuration->property("Acquisition_L5" + boost::lexical_cast(channel) + ".implementation", std::string("W")); + std::string appendix1; + if(aux.compare("W") != 0) + { + appendix1 = boost::lexical_cast(channel); + } + else + { + appendix1 = ""; + } + aux = configuration->property("Tracking_L5" + boost::lexical_cast(channel) + ".implementation", std::string("W")); + std::string appendix2; + if(aux.compare("W") != 0) + { + appendix2 = boost::lexical_cast(channel); + } + else + { + appendix2 = ""; + } + aux = configuration->property("TelemetryDecoder_L5" + boost::lexical_cast(channel) + ".implementation", std::string("W")); + std::string appendix3; + if(aux.compare("W") != 0) + { + appendix3 = boost::lexical_cast(channel); + } + else + { + appendix3 = ""; + } + // Automatically detect input data type + std::shared_ptr config; + config = std::make_shared(); + std::string default_item_type = "gr_complex"; + std::string acq_item_type = configuration->property("Acquisition_L5" + appendix1 + ".item_type", default_item_type); + std::string trk_item_type = configuration->property("Tracking_L5" + appendix2 + ".item_type", default_item_type); + if(acq_item_type.compare(trk_item_type)) + { + LOG(ERROR) << "Acquisition and Tracking blocks must have the same input data type!"; + } + config->set_property("Channel.item_type", acq_item_type); + + std::unique_ptr pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue); + std::unique_ptr acq_ = GetAcqBlock(configuration, "Acquisition_L5" + appendix1, acq, 1, 0); + std::unique_ptr trk_ = GetTrkBlock(configuration, "Tracking_L5" + appendix2, trk, 1, 1); + std::unique_ptr tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_L5" + appendix3, tlm, 1, 1); + + std::unique_ptr channel_(new Channel(configuration.get(), channel, std::move(pass_through_), + std::move(acq_), + std::move(trk_), + std::move(tlm_), + "Channel", "L5", queue)); + + return channel_; +} + + std::unique_ptr>> GNSSBlockFactory::GetChannels( std::shared_ptr configuration, boost::shared_ptr queue) @@ -538,11 +606,13 @@ std::unique_ptr>> GNSSBlockFacto unsigned int Channels_2S_count = configuration->property("Channels_2S.count", 0); unsigned int Channels_1B_count = configuration->property("Channels_1B.count", 0); unsigned int Channels_5X_count = configuration->property("Channels_5X.count", 0); + unsigned int Channels_L5_count = configuration->property("Channels_L5.count", 0); unsigned int total_channels = Channels_1C_count + Channels_2S_count + Channels_1B_count + - Channels_5X_count; + Channels_5X_count + + Channels_L5_count; std::unique_ptr>> channels(new std::vector>(total_channels)); //**************** GPS L1 C/A CHANNELS ********************** @@ -605,7 +675,34 @@ std::unique_ptr>> GNSSBlockFacto queue)); channel_absolute_id++; } + //**************** GPS L5 CHANNELS ********************** + LOG(INFO)<< "Getting " << Channels_L5_count << " GPS L5 channels"; + tracking_implementation = configuration->property("Tracking_L5.implementation", default_implementation); + telemetry_decoder_implementation = configuration->property("TelemetryDecoder_L5.implementation", default_implementation); + acquisition_implementation = configuration->property("Acquisition_L5.implementation", default_implementation); + for (unsigned int i = 0; i < Channels_L5_count; i++) + { + //(i.e. Acquisition_1C0.implementation=xxxx) + std::string acquisition_implementation_specific = configuration->property( + "Acquisition_L5" + boost::lexical_cast(channel_absolute_id) + ".implementation", + acquisition_implementation); + //(i.e. Tracking_1C0.implementation=xxxx) + std::string tracking_implementation_specific = configuration->property( + "Tracking_L5" + boost::lexical_cast(channel_absolute_id) + ".implementation", + tracking_implementation); + std::string telemetry_decoder_implementation_specific = configuration->property( + "TelemetryDecoder_L5" + boost::lexical_cast(channel_absolute_id) + ".implementation", + telemetry_decoder_implementation); + // Push back the channel to the vector of channels + channels->at(channel_absolute_id) = std::move(GetChannel_L5(configuration, + acquisition_implementation_specific, + tracking_implementation_specific, + telemetry_decoder_implementation_specific, + channel_absolute_id, + queue)); + channel_absolute_id++; + } //**************** GALILEO E1 B (I/NAV OS) CHANNELS ********************** LOG(INFO) << "Getting " << Channels_1B_count << " GALILEO E1 B (I/NAV OS) channels"; diff --git a/src/core/receiver/gnss_block_factory.h b/src/core/receiver/gnss_block_factory.h index 13c614ee8..516b9e8e9 100644 --- a/src/core/receiver/gnss_block_factory.h +++ b/src/core/receiver/gnss_block_factory.h @@ -94,6 +94,10 @@ private: std::string acq, std::string trk, std::string tlm, int channel, boost::shared_ptr queue); + std::unique_ptr GetChannel_L5(std::shared_ptr configuration, + std::string acq, std::string trk, std::string tlm, int channel, + boost::shared_ptr queue); + std::unique_ptr GetAcqBlock( std::shared_ptr configuration, std::string role, diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index cf1788cc0..ed505b5f9 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -579,7 +579,8 @@ void GNSSFlowgraph::set_signals_list() unsigned int total_channels = configuration_->property("Channels_1C.count", 0) + configuration_->property("Channels_2S.count", 0) + configuration_->property("Channels_1B.count", 0) + - configuration_->property("Channels_5X.count", 0); + configuration_->property("Channels_5X.count", 0) + + configuration_->property("Channels_L5.count", 0); /* * Loop to create the list of GNSS Signals @@ -672,6 +673,19 @@ void GNSSFlowgraph::set_signals_list() } } + if (configuration_->property("Channels_L5.count", 0) > 0) + { + /* + * Loop to create GPS L5 signals + */ + for (available_gnss_prn_iter = available_gps_prn.cbegin(); + available_gnss_prn_iter != available_gps_prn.cend(); + available_gnss_prn_iter++) + { + available_GNSS_signals_.push_back(Gnss_Signal(Gnss_Satellite(std::string("GPS"), + *available_gnss_prn_iter), std::string("L5"))); + } + } if (configuration_->property("Channels_SBAS.count", 0) > 0) { /* @@ -725,7 +739,7 @@ void GNSSFlowgraph::set_signals_list() { std::string gnss_signal = (configuration_->property("Channel" + boost::lexical_cast(i) + ".signal", std::string("1C"))); std::string gnss_system; - if((gnss_signal.compare("1C") == 0) or (gnss_signal.compare("2S") == 0) ) gnss_system = "GPS"; + if((gnss_signal.compare("1C") == 0) or (gnss_signal.compare("2S") == 0) or (gnss_signal.compare("L5") == 0)) gnss_system = "GPS"; if((gnss_signal.compare("1B") == 0) or (gnss_signal.compare("5X") == 0) ) gnss_system = "Galileo"; unsigned int sat = configuration_->property("Channel" + boost::lexical_cast(i) + ".satellite", 0); LOG(INFO) << "Channel " << i << " system " << gnss_system << ", signal " << gnss_signal <<", sat "< Date: Wed, 6 Dec 2017 13:06:05 +0100 Subject: [PATCH 06/96] Fix bug that was preventing the PRN code to be loaded. Fixes #102 --- src/utils/front-end-cal/main.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/front-end-cal/main.cc b/src/utils/front-end-cal/main.cc index cc53987f4..f4c53cd00 100644 --- a/src/utils/front-end-cal/main.cc +++ b/src/utils/front-end-cal/main.cc @@ -422,6 +422,7 @@ int main(int argc, char** argv) gnss_synchro->PRN = PRN; acquisition->set_gnss_synchro(gnss_synchro); acquisition->init(); + acquisition->set_local_code(); acquisition->reset(); stop = false; try From 26a521907a6a47471bcee8bf7d52a47d308722a5 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 11 Dec 2017 12:17:01 +0100 Subject: [PATCH 07/96] Minor changes --- .../libs/rtklib/rtklib_conversions.cc | 6 +- .../adapters/gps_l5_telemetry_decoder.cc | 4 - .../adapters/gps_l5_telemetry_decoder.h | 1 + .../gps_l5_telemetry_decoder_cc.cc | 75 +++++-- .../gps_l5_telemetry_decoder_cc.h | 10 +- .../libs/libswiftcnav/cnav_msg.c | 2 - .../libs/libswiftcnav/cnav_msg.h | 34 ---- .../adapters/gps_l5i_dll_pll_tracking.cc | 2 +- .../adapters/gps_l5i_dll_pll_tracking.h | 2 +- .../galileo_e5a_dll_pll_tracking_cc.cc | 4 +- .../gps_l5i_dll_pll_tracking_cc.cc | 6 +- src/core/receiver/gnss_block_factory.cc | 2 + src/core/system_parameters/GPS_CNAV.h | 183 ++++++++++++++++++ src/core/system_parameters/GPS_L2C.h | 143 +------------- src/core/system_parameters/GPS_L5.h | 5 +- src/core/system_parameters/MATH_CONSTANTS.h | 1 + .../system_parameters/gps_cnav_ephemeris.cc | 9 +- .../system_parameters/gps_cnav_ephemeris.h | 2 +- .../gps_cnav_navigation_message.cc | 20 +- .../gps_cnav_navigation_message.h | 11 +- src/core/system_parameters/rtcm.cc | 1 + 21 files changed, 285 insertions(+), 238 deletions(-) create mode 100644 src/core/system_parameters/GPS_CNAV.h diff --git a/src/algorithms/libs/rtklib/rtklib_conversions.cc b/src/algorithms/libs/rtklib/rtklib_conversions.cc index ad8810fb3..ec2e9df7e 100644 --- a/src/algorithms/libs/rtklib/rtklib_conversions.cc +++ b/src/algorithms/libs/rtklib/rtklib_conversions.cc @@ -35,7 +35,7 @@ obsd_t insert_obs_to_rtklib(obsd_t & rtklib_obs, const Gnss_Synchro & gnss_synch { rtklib_obs.D[band] = gnss_synchro.Carrier_Doppler_hz; rtklib_obs.P[band] = gnss_synchro.Pseudorange_m; - rtklib_obs.L[band] = gnss_synchro.Carrier_phase_rads / (2.0 * PI); + rtklib_obs.L[band] = gnss_synchro.Carrier_phase_rads / PI_2; switch(band) { case 0: @@ -165,8 +165,6 @@ eph_t eph_to_rtklib(const Gps_Ephemeris & gps_eph) rtklib_sat.toc = gpst2time(rtklib_sat.week, toc); rtklib_sat.ttr = gpst2time(rtklib_sat.week, tow); - //printf("EPHEMERIS TIME [%i]: %s,%f\n\r",rtklib_sat.sat,time_str(rtklib_sat.toe,3),rtklib_sat.toe.sec); - return rtklib_sat; } @@ -183,7 +181,7 @@ eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris & gps_cnav_eph) rtklib_sat.OMG0 = gps_cnav_eph.d_OMEGA0; // Compute the angle between the ascending node and the Greenwich meridian const double OMEGA_DOT_REF = -2.6e-9; // semicircles / s, see IS-GPS-200H pp. 164 - double d_OMEGA_DOT = OMEGA_DOT_REF * GPS_L2_PI + gps_cnav_eph.d_DELTA_OMEGA_DOT; + double d_OMEGA_DOT = OMEGA_DOT_REF * PI + gps_cnav_eph.d_DELTA_OMEGA_DOT; rtklib_sat.OMGd = d_OMEGA_DOT; rtklib_sat.omg = gps_cnav_eph.d_OMEGA; rtklib_sat.i0 = gps_cnav_eph.d_i_0; diff --git a/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.cc index 74f262bcf..fe4f356f1 100644 --- a/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.cc @@ -34,10 +34,6 @@ #include #include #include "concurrent_queue.h" -#include "gps_cnav_ephemeris.h" -#include "gps_almanac.h" -#include "gps_cnav_iono.h" -#include "gps_cnav_utc_model.h" #include "configuration_interface.h" diff --git a/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.h index 49a18111c..4041e253e 100644 --- a/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.h @@ -36,6 +36,7 @@ #include #include "telemetry_decoder_interface.h" #include "gps_l5_telemetry_decoder_cc.h" +#include "gnss_satellite.h" class ConfigurationInterface; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc index bb90434dc..6bd77a4b5 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc @@ -37,6 +37,8 @@ #include #include "gnss_synchro.h" #include "gps_l5_telemetry_decoder_cc.h" +#include "gps_cnav_ephemeris.h" +#include "gps_cnav_iono.h" using google::LogMessage; @@ -70,6 +72,19 @@ gps_l5_telemetry_decoder_cc::gps_l5_telemetry_decoder_cc( //initialize the CNAV frame decoder (libswiftcnav) cnav_msg_decoder_init(&d_cnav_decoder); + for(int aux = 0; aux < GPS_L5_NH_CODE_LENGTH; aux++) + { + if(GPS_L5_NH_CODE[aux] == 0) + { + bits_NH[aux] = -1.0; + } + else + { + bits_NH[aux] = 1.0; + } + } + sync_NH = false; + new_sym = false; } @@ -96,26 +111,58 @@ int gps_l5_telemetry_decoder_cc::general_work (int noutput_items __attribute__(( Gnss_Synchro *out = reinterpret_cast(output_items[0]); // Get the output buffer pointer const Gnss_Synchro *in = reinterpret_cast(input_items[0]); // Get the input buffer pointer + // UPDATE GNSS SYNCHRO DATA + Gnss_Synchro current_synchro_data; //structure to save the synchronization information and send the output object to the next block + //1. Copy the current tracking output + current_synchro_data = in[0]; + consume_each(1); //one by one + sym_hist.push_back(in[0].Prompt_I); + double symbol_value = 0.0; + + if(sym_hist.size() == GPS_L5_NH_CODE_LENGTH) + { + std::deque::iterator it; + int corr_NH = 0; + it = sym_hist.begin(); + for(int i = 0; i < GPS_L5_NH_CODE_LENGTH; i++) + { + if((bits_NH[i] * (*it)) > 0.0){corr_NH += 1;} + else{corr_NH -= 1;} + it++; + } + if(abs(corr_NH) == GPS_L5_NH_CODE_LENGTH){sync_NH = true;} + else + { + sym_hist.pop_front(); + sync_NH = false; + } + if (sync_NH) + { + new_sym = true; + for(it = sym_hist.begin(); it != sym_hist.end(); it++) + { + symbol_value += (*it); + } + sym_hist.clear(); + } + } + bool flag_new_cnav_frame = false; cnav_msg_t msg; u32 delay = 0; //add the symbol to the decoder - u8 symbol_clip = static_cast(in[0].Prompt_I > 0) * 255; - flag_new_cnav_frame = cnav_msg_decoder_add_symbol(&d_cnav_decoder, symbol_clip, &msg, &delay); - - consume_each(1); //one by one - - // UPDATE GNSS SYNCHRO DATA - Gnss_Synchro current_synchro_data; //structure to save the synchronization information and send the output object to the next block - - //1. Copy the current tracking output - current_synchro_data = in[0]; - + if(new_sym) + { + u8 symbol_clip = static_cast(symbol_value > 0.0) * 255; + flag_new_cnav_frame = cnav_msg_decoder_add_symbol(&d_cnav_decoder, symbol_clip, &msg, &delay); + new_sym = false; + } //2. Add the telemetry decoder information //check if new CNAV frame is available if (flag_new_cnav_frame == true) { + std::cout << "NEW CNAV FRAME" << std::endl; std::bitset raw_bits; //Expand packet bits to bitsets. Notice the reverse order of the bits sequence, required by the CNAV message decoder for (u32 i = 0; i < GPS_L5_CNAV_DATA_PAGE_BITS ; i++) @@ -169,12 +216,6 @@ int gps_l5_telemetry_decoder_cc::general_work (int noutput_items __attribute__(( current_synchro_data.TOW_at_current_symbol_s = d_TOW_at_current_symbol; current_synchro_data.Flag_valid_word = d_flag_valid_word; - // if (flag_PLL_180_deg_phase_locked == true) - // { - // //correct the accumulated phase for the Costas loop phase shift, if required - // current_synchro_data.Carrier_phase_rads += GPS_PI; - // } - if(d_dump == true) { // MULTIPLEXED FILE RECORDING - Record results to file diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h index bf45680d4..77f91783b 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h @@ -31,17 +31,15 @@ #ifndef GNSS_SDR_GPS_L5_TELEMETRY_DECODER_CC_H #define GNSS_SDR_GPS_L5_TELEMETRY_DECODER_CC_H -#include // for copy +#include #include #include #include -#include // for pair +#include #include #include #include "gnss_satellite.h" #include "gps_cnav_navigation_message.h" -#include "gps_cnav_ephemeris.h" -#include "gps_cnav_iono.h" #include "concurrent_queue.h" extern "C" { @@ -99,6 +97,10 @@ private: bool d_flag_valid_word; Gps_CNAV_Navigation_Message d_CNAV_Message; + double bits_NH[GPS_L5_NH_CODE_LENGTH]; + std::deque sym_hist; + bool sync_NH; + bool new_sym; }; diff --git a/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.c b/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.c index fabf3195b..fbc3a22ab 100644 --- a/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.c +++ b/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.c @@ -49,11 +49,9 @@ */ /** Viterbi decoder reversed polynomial A */ #define GPS_L2C_V27_POLY_A (0x4F) /* 0b01001111 - reversed 0171*/ -#define GPS_L5_V27_POLY_A (0x4F) /* 0b01001111 - reversed 0171*/ /** Viterbi decoder reversed polynomial B */ #define GPS_L2C_V27_POLY_B (0x6D) /* 0b01101101 - reversed 0133 */ -#define GPS_L5_V27_POLY_B (0x6D) /* 0b01101101 - reversed 0133 */ /* * GPS L2C message constants. */ diff --git a/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.h b/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.h index 4b338a1ee..8b8141358 100644 --- a/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.h +++ b/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.h @@ -49,16 +49,12 @@ /** Size of the Viterbi decoder history. */ #define GPS_L2_V27_HISTORY_LENGTH_BITS 64 -#define GPS_L5_V27_HISTORY_LENGTH_BITS 64 /** Bits to accumulate before decoding starts. */ #define GPS_L2C_V27_INIT_BITS (32) -#define GPS_L5_V27_INIT_BITS (32) /** Bits to decode at a time. */ #define GPS_L2C_V27_DECODE_BITS (32) -#define GPS_L5_V27_DECODE_BITS (32) /** Bits in decoder tail. We ignore them. */ #define GPS_L2C_V27_DELAY_BITS (32) -#define GPS_L5_V27_DELAY_BITS (32) /** * GPS CNAV message container. * @@ -73,15 +69,6 @@ typedef struct u8 raw_msg[GPS_L2C_V27_DECODE_BITS + GPS_L2C_V27_DELAY_BITS]; /**< RAW MSG for GNSS-SDR */ } cnav_msg_t; -typedef struct -{ - u8 prn; /**< SV PRN. 0..31 */ - u8 msg_id; /**< Message id. 0..31 */ - u32 tow; /**< GPS ToW in 6-second units. Multiply to 6 to get seconds. */ - bool alert; /**< CNAV message alert flag */ - u8 raw_msg[GPS_L5_V27_DECODE_BITS + GPS_L5_V27_DELAY_BITS]; /**< RAW MSG for GNSS-SDR */ -} cnav_L5_msg_t; - /** * GPS CNAV decoder component. * This component controls symbol decoding string. @@ -109,27 +96,6 @@ typedef struct { * do not produce output. */ } cnav_v27_part_t; -typedef struct { - v27_t dec; /**< Viterbi block decoder object */ - v27_decision_t decisions[GPS_L5_V27_HISTORY_LENGTH_BITS]; - /**< Decision graph */ - unsigned char symbols[(GPS_L5_V27_INIT_BITS + GPS_L5_V27_DECODE_BITS) * 2]; - /**< Symbol buffer */ - size_t n_symbols; /**< Count of symbols in the symbol buffer */ - unsigned char decoded[GPS_L5_V27_DECODE_BITS + GPS_L5_V27_DELAY_BITS]; - /**< Decode buffer */ - size_t n_decoded; /**< Number of bits in the decode buffer */ - bool preamble_seen; /**< When true, the decode buffer is aligned on - * preamble. */ - bool invert; /**< When true, indicates the bits are inverted */ - bool message_lock; /**< When true, indicates the message boundary - * is found. */ - bool crc_ok; /**< Flag that the last message had good CRC */ - size_t n_crc_fail; /**< Counter for CRC failures */ - bool init; /**< Initial state flag. When true, initial bits - * do not produce output. */ -} cnav_L5_v27_part_t; - /** * GPS CNAV message lock and decoder object. * diff --git a/src/algorithms/tracking/adapters/gps_l5i_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l5i_dll_pll_tracking.cc index e15ff4bb1..be96227d8 100644 --- a/src/algorithms/tracking/adapters/gps_l5i_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l5i_dll_pll_tracking.cc @@ -1,5 +1,5 @@ /*! - * \file gps_l5idll_pll_tracking.cc + * \file gps_l5i_dll_pll_tracking.cc * \brief Interface of an adapter of a DLL+PLL tracking loop block * for GPS L5i to a TrackingInterface * \author Javier Arribas, 2017. jarribas(at)cttc.es diff --git a/src/algorithms/tracking/adapters/gps_l5i_dll_pll_tracking.h b/src/algorithms/tracking/adapters/gps_l5i_dll_pll_tracking.h index fcc4b3c81..681ddca42 100644 --- a/src/algorithms/tracking/adapters/gps_l5i_dll_pll_tracking.h +++ b/src/algorithms/tracking/adapters/gps_l5i_dll_pll_tracking.h @@ -62,7 +62,7 @@ public: return role_; } - //! Returns "GPS_L2_M_DLL_PLL_Tracking" + //! Returns "GPS_L5i_DLL_PLL_Tracking" inline std::string implementation() override { return "GPS_L5i_DLL_PLL_Tracking"; diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_pll_tracking_cc.cc index bdc4b7d00..f36dc1139 100644 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_pll_tracking_cc.cc @@ -642,8 +642,8 @@ int Galileo_E5a_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribute // The first Prompt output not equal to 0 is synchronized with the transition of a navigation data bit. if (d_secondary_lock && d_first_transition) { - current_synchro_data.Prompt_I = static_cast((d_Prompt_data).real()); - current_synchro_data.Prompt_Q = static_cast((d_Prompt_data).imag()); + current_synchro_data.Prompt_I = static_cast(d_Prompt_data.real()); + current_synchro_data.Prompt_Q = static_cast(d_Prompt_data.imag()); current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples; current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l5i_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l5i_dll_pll_tracking_cc.cc index a515093a3..3fd0a151c 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l5i_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l5i_dll_pll_tracking_cc.cc @@ -257,14 +257,14 @@ void gps_l5i_dll_pll_tracking_cc::start_tracking() sys = sys_.substr(0,1); // DEBUG OUTPUT - std::cout << "Tracking of GPS L2CM signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl; - LOG(INFO) << "Starting GPS L2CM tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel; + std::cout << "Tracking of GPS L5i signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl; + LOG(INFO) << "Starting GPS L5i tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel; // enable tracking d_pull_in = true; d_enable_tracking = true; - LOG(INFO) << "GPS L2CM PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz + LOG(INFO) << "GPS L5i PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz << " Code Phase correction [samples]=" << delay_correction_samples << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples; } diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 666abc9a1..c3e3889fb 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -240,6 +240,7 @@ std::unique_ptr GNSSBlockFactory::GetObservables(std::shared Galileo_channels += configuration->property("Channels_5X.count", 0); unsigned int GPS_channels = configuration->property("Channels_1C.count", 0); GPS_channels += configuration->property("Channels_2S.count", 0); + GPS_channels += configuration->property("Channels_L5.count", 0); return GetBlock(configuration, "Observables", implementation, Galileo_channels + GPS_channels, Galileo_channels + GPS_channels); } @@ -254,6 +255,7 @@ std::unique_ptr GNSSBlockFactory::GetPVT(std::shared_ptrproperty("Channels_5X.count", 0); unsigned int GPS_channels = configuration->property("Channels_1C.count", 0); GPS_channels += configuration->property("Channels_2S.count", 0); + GPS_channels += configuration->property("Channels_L5.count", 0); return GetBlock(configuration, "PVT", implementation, Galileo_channels + GPS_channels, 0); } diff --git a/src/core/system_parameters/GPS_CNAV.h b/src/core/system_parameters/GPS_CNAV.h new file mode 100644 index 000000000..d3f953f2b --- /dev/null +++ b/src/core/system_parameters/GPS_CNAV.h @@ -0,0 +1,183 @@ +/*! + * \file GPS_CNAV.h + * \brief Defines parameters for GPS CNAV + * \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_GPS_CNAV_H_ +#define GNSS_SDR_GPS_CNAV_H_ + +#include +#include +#include // std::pair +#include "MATH_CONSTANTS.h" + +// CNAV GPS NAVIGATION MESSAGE STRUCTURE +// NAVIGATION MESSAGE FIELDS POSITIONS (from IS-GPS-200E Appendix III) + +#define GPS_CNAV_PREAMBLE {1, 0, 0, 0, 1, 0, 1, 1} +#define GPS_CNAV_PREAMBLE_STR "10001011" +#define GPS_CNAV_INV_PREAMBLE_STR "01110100" + +const int GPS_CNAV_DATA_PAGE_BITS = 300; + +// common to all messages +const std::vector > CNAV_PRN( { {9,6} } ); +const std::vector > CNAV_MSG_TYPE( { {15,6} } ); +const std::vector > CNAV_TOW( { {21,17} } ); //GPS Time Of Week in seconds +const double CNAV_TOW_LSB = 6.0; +const std::vector > CNAV_ALERT_FLAG( { {38,1} } ); + +// MESSAGE TYPE 10 (Ephemeris 1) + +const std::vector > CNAV_WN({{39,13}}); +const std::vector > CNAV_HEALTH({{52,3}}); +const std::vector > CNAV_TOP1({{55,11}}); +const double CNAV_TOP1_LSB = 300.0; +const std::vector > CNAV_URA({{66,5}}); + +const std::vector > CNAV_TOE1({{71,11}}); +const double CNAV_TOE1_LSB = 300.0; + +const std::vector > CNAV_DELTA_A({{82,26}}); //Relative to AREF = 26,559,710 meters +const double CNAV_DELTA_A_LSB = TWO_N9; + +const std::vector > CNAV_A_DOT({{108,25}}); +const double CNAV_A_DOT_LSB = TWO_N21; + +const std::vector > CNAV_DELTA_N0({{133,17}}); +const double CNAV_DELTA_N0_LSB = TWO_N44*PI; //semi-circles to radians +const std::vector > CNAV_DELTA_N0_DOT({{150,23}}); +const double CNAV_DELTA_N0_DOT_LSB = TWO_N57*PI;//semi-circles to radians +const std::vector > CNAV_M0({{173,33}}); +const double CNAV_M0_LSB = TWO_N32*PI;//semi-circles to radians +const std::vector > CNAV_E_ECCENTRICITY({{206,33}}); +const double CNAV_E_ECCENTRICITY_LSB = TWO_N34; +const std::vector > CNAV_OMEGA({{239,33}}); +const double CNAV_OMEGA_LSB = TWO_N32*PI;//semi-circles to radians +const std::vector > CNAV_INTEGRITY_FLAG({{272,1}}); +const std::vector > CNAV_L2_PHASING_FLAG({{273,1}}); + +// MESSAGE TYPE 11 (Ephemeris 2) + +const std::vector > CNAV_TOE2({{39,11}}); +const double CNAV_TOE2_LSB = 300.0; +const std::vector > CNAV_OMEGA0({{50,33}}); +const double CNAV_OMEGA0_LSB = TWO_N32*PI;//semi-circles to radians +const std::vector > CNAV_I0({{83,33}}); +const double CNAV_I0_LSB = TWO_N32*PI;//semi-circles to radians +const std::vector > CNAV_DELTA_OMEGA_DOT({{116,17}}); //Relative to REF = -2.6 x 10-9 semi-circles/second. +const double CNAV_DELTA_OMEGA_DOT_LSB = TWO_N44*PI;//semi-circles to radians +const std::vector > CNAV_I0_DOT({{133,15}}); +const double CNAV_I0_DOT_LSB = TWO_N44*PI;//semi-circles to radians +const std::vector > CNAV_CIS({{148,16}}); +const double CNAV_CIS_LSB = TWO_N30; +const std::vector > CNAV_CIC({{164,16}}); +const double CNAV_CIC_LSB = TWO_N30; +const std::vector > CNAV_CRS({{180,24}}); +const double CNAV_CRS_LSB = TWO_N8; +const std::vector > CNAV_CRC({{204,24}}); +const double CNAV_CRC_LSB = TWO_N8; +const std::vector > CNAV_CUS({{228,21}}); +const double CNAV_CUS_LSB = TWO_N30; +const std::vector > CNAV_CUC({{249,21}}); +const double CNAV_CUC_LSB = TWO_N30; + + +// MESSAGE TYPE 30 (CLOCK, IONO, GRUP DELAY) + +const std::vector > CNAV_TOP2({{39,11}}); +const double CNAV_TOP2_LSB = 300.0; +const std::vector > CNAV_URA_NED0({{50,5}}); +const std::vector > CNAV_URA_NED1({{55,3}}); +const std::vector > CNAV_URA_NED2({{58,3}}); +const std::vector > CNAV_TOC({{61,11}}); +const double CNAV_TOC_LSB = 300.0; +const std::vector > CNAV_AF0({{72,26}}); +const double CNAV_AF0_LSB = TWO_N60; +const std::vector > CNAV_AF1({{98,20}}); +const double CNAV_AF1_LSB = TWO_N48; +const std::vector > CNAV_AF2({{118,10}}); +const double CNAV_AF2_LSB = TWO_N35; +const std::vector > CNAV_TGD({{128,13}}); +const double CNAV_TGD_LSB = TWO_N35; +const std::vector > CNAV_ISCL1({{141,13}}); +const double CNAV_ISCL1_LSB = TWO_N35; +const std::vector > CNAV_ISCL2({{154,13}}); +const double CNAV_ISCL2_LSB = TWO_N35; +const std::vector > CNAV_ISCL5I({{167,13}}); +const double CNAV_ISCL5I_LSB = TWO_N35; +const std::vector > CNAV_ISCL5Q({{180,13}}); +const double CNAV_ISCL5Q_LSB = TWO_N35; +//Ionospheric parameters +const std::vector > CNAV_ALPHA0({{193,8}}); +const double CNAV_ALPHA0_LSB = TWO_N30; +const std::vector > CNAV_ALPHA1({{201,8}}); +const double CNAV_ALPHA1_LSB = TWO_N27; +const std::vector > CNAV_ALPHA2({{209,8}}); +const double CNAV_ALPHA2_LSB = TWO_N24; +const std::vector > CNAV_ALPHA3({{217,8}}); +const double CNAV_ALPHA3_LSB = TWO_N24; +const std::vector > CNAV_BETA0({{225,8}}); +const double CNAV_BETA0_LSB = TWO_P11; +const std::vector > CNAV_BETA1({{233,8}}); +const double CNAV_BETA1_LSB = TWO_P14; +const std::vector > CNAV_BETA2({{241,8}}); +const double CNAV_BETA2_LSB = TWO_P16; +const std::vector > CNAV_BETA3({{249,8}}); +const double CNAV_BETA3_LSB = TWO_P16; +const std::vector > CNAV_WNOP({{257,8}}); + + +// MESSAGE TYPE 33 (CLOCK and UTC) + +const std::vector > CNAV_A0({{128,16}}); +const double CNAV_A0_LSB = TWO_N35; +const std::vector > CNAV_A1({{144,13}}); +const double CNAV_A1_LSB = TWO_N51; +const std::vector > CNAV_A2({{157,7}}); +const double CNAV_A2_LSB = TWO_N68; +const std::vector > CNAV_DELTA_TLS({{164,8}}); +const double CNAV_DELTA_TLS_LSB = 1; +const std::vector > CNAV_TOT({{172,16}}); +const double CNAV_TOT_LSB = TWO_P4; +const std::vector > CNAV_WN_OT({{188,13}}); +const double CNAV_WN_OT_LSB = 1; +const std::vector > CNAV_WN_LSF({{201,13}}); +const double CNAV_WN_LSF_LSB = 1; +const std::vector > CNAV_DN({{214,4}}); +const double CNAV_DN_LSB = 1; +const std::vector > CNAV_DELTA_TLSF({{218,8}}); +const double CNAV_DELTA_TLSF_LSB = 1; + + +// TODO: Add more frames (Almanac, etc...) + + + +#endif /* GNSS_SDR_GPS_CNAV_H_ */ diff --git a/src/core/system_parameters/GPS_L2C.h b/src/core/system_parameters/GPS_L2C.h index babbc59ce..70a8e5ff3 100644 --- a/src/core/system_parameters/GPS_L2C.h +++ b/src/core/system_parameters/GPS_L2C.h @@ -37,6 +37,7 @@ #include // std::pair #include "MATH_CONSTANTS.h" #include "gnss_frequencies.h" +#include "GPS_CNAV.h" // Physical constants const double GPS_L2_C_m_s = 299792458.0; //!< The speed of light, [m/s] @@ -92,152 +93,10 @@ const int32_t GPS_L2C_M_INIT_REG[115] = 0706202440, 0705056276, 0020373522, 0746013617, 0132720621, 0434015513, 0566721727, 0140633660}; -// CNAV GPS NAVIGATION MESSAGE STRUCTURE -// NAVIGATION MESSAGE FIELDS POSITIONS (from IS-GPS-200E Appendix III) - -#define GPS_CNAV_PREAMBLE {1, 0, 0, 0, 1, 0, 1, 1} -#define GPS_CNAV_PREAMBLE_STR "10001011" -#define GPS_CNAV_INV_PREAMBLE_STR "01110100" - const int GPS_L2_CNAV_DATA_PAGE_BITS = 300; //!< GPS L2 CNAV page length, including preamble and CRC [bits] const int GPS_L2_SYMBOLS_PER_BIT = 2; const int GPS_L2_SAMPLES_PER_SYMBOL = 1; const int GPS_L2_CNAV_DATA_PAGE_SYMBOLS = 600; const int GPS_L2_CNAV_DATA_PAGE_DURATION_S = 12; -// common to all messages -const std::vector > CNAV_PRN( { {9,6} } ); -const std::vector > CNAV_MSG_TYPE( { {15,6} } ); -const std::vector > CNAV_TOW( { {21,17} } ); //GPS Time Of Week in seconds -const double CNAV_TOW_LSB = 6.0; -const std::vector > CNAV_ALERT_FLAG( { {38,1} } ); - -// MESSAGE TYPE 10 (Ephemeris 1) - -const std::vector > CNAV_WN({{39,13}}); -const std::vector > CNAV_HEALTH({{52,3}}); -const std::vector > CNAV_TOP1({{55,11}}); -const double CNAV_TOP1_LSB = 300.0; -const std::vector > CNAV_URA({{66,5}}); - -const std::vector > CNAV_TOE1({{71,11}}); -const double CNAV_TOE1_LSB = 300.0; - -const std::vector > CNAV_DELTA_A({{82,26}}); //Relative to AREF = 26,559,710 meters -const double CNAV_DELTA_A_LSB = TWO_N9; - -const std::vector > CNAV_A_DOT({{108,25}}); -const double CNAV_A_DOT_LSB = TWO_N21; - -const std::vector > CNAV_DELTA_N0({{133,17}}); -const double CNAV_DELTA_N0_LSB = TWO_N44*GPS_L2_PI; //semi-circles to radians -const std::vector > CNAV_DELTA_N0_DOT({{150,23}}); -const double CNAV_DELTA_N0_DOT_LSB = TWO_N57*GPS_L2_PI;//semi-circles to radians -const std::vector > CNAV_M0({{173,33}}); -const double CNAV_M0_LSB = TWO_N32*GPS_L2_PI;//semi-circles to radians -const std::vector > CNAV_E_ECCENTRICITY({{206,33}}); -const double CNAV_E_ECCENTRICITY_LSB = TWO_N34; -const std::vector > CNAV_OMEGA({{239,33}}); -const double CNAV_OMEGA_LSB = TWO_N32*GPS_L2_PI;//semi-circles to radians -const std::vector > CNAV_INTEGRITY_FLAG({{272,1}}); -const std::vector > CNAV_L2_PHASING_FLAG({{273,1}}); - -// MESSAGE TYPE 11 (Ephemeris 2) - -const std::vector > CNAV_TOE2({{39,11}}); -const double CNAV_TOE2_LSB = 300.0; -const std::vector > CNAV_OMEGA0({{50,33}}); -const double CNAV_OMEGA0_LSB = TWO_N32*GPS_L2_PI;//semi-circles to radians -const std::vector > CNAV_I0({{83,33}}); -const double CNAV_I0_LSB = TWO_N32*GPS_L2_PI;//semi-circles to radians -const std::vector > CNAV_DELTA_OMEGA_DOT({{116,17}}); //Relative to REF = -2.6 x 10-9 semi-circles/second. -const double CNAV_DELTA_OMEGA_DOT_LSB = TWO_N44*GPS_L2_PI;//semi-circles to radians -const std::vector > CNAV_I0_DOT({{133,15}}); -const double CNAV_I0_DOT_LSB = TWO_N44*GPS_L2_PI;//semi-circles to radians -const std::vector > CNAV_CIS({{148,16}}); -const double CNAV_CIS_LSB = TWO_N30; -const std::vector > CNAV_CIC({{164,16}}); -const double CNAV_CIC_LSB = TWO_N30; -const std::vector > CNAV_CRS({{180,24}}); -const double CNAV_CRS_LSB = TWO_N8; -const std::vector > CNAV_CRC({{204,24}}); -const double CNAV_CRC_LSB = TWO_N8; -const std::vector > CNAV_CUS({{228,21}}); -const double CNAV_CUS_LSB = TWO_N30; -const std::vector > CNAV_CUC({{249,21}}); -const double CNAV_CUC_LSB = TWO_N30; - - -// MESSAGE TYPE 30 (CLOCK, IONO, GRUP DELAY) - -const std::vector > CNAV_TOP2({{39,11}}); -const double CNAV_TOP2_LSB = 300.0; - -const std::vector > CNAV_URA_NED0({{50,5}}); -const std::vector > CNAV_URA_NED1({{55,3}}); -const std::vector > CNAV_URA_NED2({{58,3}}); -const std::vector > CNAV_TOC({{61,11}}); -const double CNAV_TOC_LSB = 300.0; -const std::vector > CNAV_AF0({{72,26}}); -const double CNAV_AF0_LSB = TWO_N60; -const std::vector > CNAV_AF1({{98,20}}); -const double CNAV_AF1_LSB = TWO_N48; -const std::vector > CNAV_AF2({{118,10}}); -const double CNAV_AF2_LSB = TWO_N35; -const std::vector > CNAV_TGD({{128,13}}); -const double CNAV_TGD_LSB = TWO_N35; -const std::vector > CNAV_ISCL1({{141,13}}); -const double CNAV_ISCL1_LSB = TWO_N35; -const std::vector > CNAV_ISCL2({{154,13}}); -const double CNAV_ISCL2_LSB = TWO_N35; -const std::vector > CNAV_ISCL5I({{167,13}}); -const double CNAV_ISCL5I_LSB = TWO_N35; -const std::vector > CNAV_ISCL5Q({{180,13}}); -const double CNAV_ISCL5Q_LSB = TWO_N35; -//Ionospheric parameters -const std::vector > CNAV_ALPHA0({{193,8}}); -const double CNAV_ALPHA0_LSB = TWO_N30; -const std::vector > CNAV_ALPHA1({{201,8}}); -const double CNAV_ALPHA1_LSB = TWO_N27; -const std::vector > CNAV_ALPHA2({{209,8}}); -const double CNAV_ALPHA2_LSB = TWO_N24; -const std::vector > CNAV_ALPHA3({{217,8}}); -const double CNAV_ALPHA3_LSB = TWO_N24; -const std::vector > CNAV_BETA0({{225,8}}); -const double CNAV_BETA0_LSB = TWO_P11; -const std::vector > CNAV_BETA1({{233,8}}); -const double CNAV_BETA1_LSB = TWO_P14; -const std::vector > CNAV_BETA2({{241,8}}); -const double CNAV_BETA2_LSB = TWO_P16; -const std::vector > CNAV_BETA3({{249,8}}); -const double CNAV_BETA3_LSB = TWO_P16; -const std::vector > CNAV_WNOP({{257,8}}); - - -// MESSAGE TYPE 33 (CLOCK and UTC) - -const std::vector > CNAV_A0({{128,16}}); -const double CNAV_A0_LSB = TWO_N35; -const std::vector > CNAV_A1({{144,13}}); -const double CNAV_A1_LSB = TWO_N51; -const std::vector > CNAV_A2({{157,7}}); -const double CNAV_A2_LSB = TWO_N68; -const std::vector > CNAV_DELTA_TLS({{164,8}}); -const double CNAV_DELTA_TLS_LSB = 1; -const std::vector > CNAV_TOT({{172,16}}); -const double CNAV_TOT_LSB = TWO_P4; -const std::vector > CNAV_WN_OT({{188,13}}); -const double CNAV_WN_OT_LSB = 1; -const std::vector > CNAV_WN_LSF({{201,13}}); -const double CNAV_WN_LSF_LSB = 1; -const std::vector > CNAV_DN({{214,4}}); -const double CNAV_DN_LSB = 1; -const std::vector > CNAV_DELTA_TLSF({{218,8}}); -const double CNAV_DELTA_TLSF_LSB = 1; - - -// TODO: Add more frames (Almanac, etc...) - - - #endif /* GNSS_SDR_GPS_L2C_H_ */ diff --git a/src/core/system_parameters/GPS_L5.h b/src/core/system_parameters/GPS_L5.h index f8ad4413f..a65d3d3f6 100644 --- a/src/core/system_parameters/GPS_L5.h +++ b/src/core/system_parameters/GPS_L5.h @@ -35,7 +35,7 @@ #include #include "MATH_CONSTANTS.h" #include "gnss_frequencies.h" -#include "GPS_L2C.h" // CNAV GPS NAVIGATION MESSAGE STRUCTURE +#include "GPS_CNAV.h" // Physical constants const double GPS_L5_C_m_s = 299792458.0; //!< The speed of light, [m/s] @@ -179,6 +179,7 @@ const int GPS_L5_SYMBOLS_PER_BIT = 2; const int GPS_L5_SAMPLES_PER_SYMBOL = 10; const int GPS_L5_CNAV_DATA_PAGE_SYMBOLS = 600; const int GPS_L5_CNAV_DATA_PAGE_DURATION_S = 6; - +const int GPS_L5_NH_CODE_LENGTH = 10; +const int GPS_L5_NH_CODE[10] = {0, 0, 0, 0, 1, 1, 0, 1, 0, 1}; #endif /* GNSS_SDR_GPS_L5_H_ */ diff --git a/src/core/system_parameters/MATH_CONSTANTS.h b/src/core/system_parameters/MATH_CONSTANTS.h index 9be1a41cf..2e080f5ae 100644 --- a/src/core/system_parameters/MATH_CONSTANTS.h +++ b/src/core/system_parameters/MATH_CONSTANTS.h @@ -42,6 +42,7 @@ */ const double PI = 3.1415926535897932; //!< pi +const double PI_2 = 2.0 * PI; //!< 2 * pi const double TWO_P4 = (16); //!< 2^4 const double TWO_P11 = (2048); //!< 2^11 diff --git a/src/core/system_parameters/gps_cnav_ephemeris.cc b/src/core/system_parameters/gps_cnav_ephemeris.cc index 7669fb825..f46cfc310 100644 --- a/src/core/system_parameters/gps_cnav_ephemeris.cc +++ b/src/core/system_parameters/gps_cnav_ephemeris.cc @@ -32,7 +32,6 @@ #include "gps_cnav_ephemeris.h" #include -#include "GPS_L2C.h" #include Gps_CNAV_Ephemeris::Gps_CNAV_Ephemeris() @@ -168,7 +167,7 @@ double Gps_CNAV_Ephemeris::sv_clock_relativistic_term(double transmitTime) { E_old = E; E = M + d_e_eccentricity * sin(E); - dE = fmod(E - E_old, 2.0 * GPS_L2_PI); + dE = fmod(E - E_old, 2.0 * PI); if (fabs(dE) < 1e-12) { //Necessary precision is reached, exit from the loop @@ -239,7 +238,7 @@ double Gps_CNAV_Ephemeris::satellitePosition(double transmitTime) { E_old = E; E = M + d_e_eccentricity * sin(E); - dE = fmod(E - E_old, 2 * GPS_L2_PI); + dE = fmod(E - E_old, 2 * PI); if (fabs(dE) < 1e-12) { //Necessary precision is reached, exit from the loop @@ -268,7 +267,7 @@ double Gps_CNAV_Ephemeris::satellitePosition(double transmitTime) i = d_i_0 + d_IDOT * tk + d_Cic * cos(2*phi) + d_Cis * sin(2*phi); // Compute the angle between the ascending node and the Greenwich meridian - double d_OMEGA_DOT = OMEGA_DOT_REF*GPS_L2_PI + d_DELTA_OMEGA_DOT; + double d_OMEGA_DOT = OMEGA_DOT_REF*PI + d_DELTA_OMEGA_DOT; Omega = d_OMEGA0 + (d_OMEGA_DOT - OMEGA_EARTH_DOT)*tk - OMEGA_EARTH_DOT * d_Toe1; // Reduce to between 0 and 2*pi rad @@ -291,7 +290,7 @@ double Gps_CNAV_Ephemeris::satellitePosition(double transmitTime) double dtr_s = d_A_f0 + d_A_f1 * tk + d_A_f2 * tk * tk; /* relativity correction */ - dtr_s -= 2.0 * sqrt(GM * a) * d_e_eccentricity * sin(E) / (GPS_L2_C_m_s * GPS_L2_C_m_s); + dtr_s -= 2.0 * sqrt(GM * a) * d_e_eccentricity * sin(E) / (SPEED_OF_LIGHT * SPEED_OF_LIGHT); return dtr_s; } diff --git a/src/core/system_parameters/gps_cnav_ephemeris.h b/src/core/system_parameters/gps_cnav_ephemeris.h index 05f2c5029..b8f304951 100644 --- a/src/core/system_parameters/gps_cnav_ephemeris.h +++ b/src/core/system_parameters/gps_cnav_ephemeris.h @@ -32,7 +32,7 @@ #ifndef GNSS_SDR_GPS_CNAV_EPHEMERIS_H_ #define GNSS_SDR_GPS_CNAV_EPHEMERIS_H_ -#include "GPS_L2C.h" +#include "GPS_CNAV.h" #include "boost/assign.hpp" #include diff --git a/src/core/system_parameters/gps_cnav_navigation_message.cc b/src/core/system_parameters/gps_cnav_navigation_message.cc index a48ba348f..6ffe5cad1 100644 --- a/src/core/system_parameters/gps_cnav_navigation_message.cc +++ b/src/core/system_parameters/gps_cnav_navigation_message.cc @@ -73,11 +73,11 @@ Gps_CNAV_Navigation_Message::Gps_CNAV_Navigation_Message() -bool Gps_CNAV_Navigation_Message::read_navigation_bool(std::bitset bits, const std::vector> parameter) +bool Gps_CNAV_Navigation_Message::read_navigation_bool(std::bitset bits, const std::vector> parameter) { bool value; - if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1) + if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1) { value = true; } @@ -89,7 +89,7 @@ bool Gps_CNAV_Navigation_Message::read_navigation_bool(std::bitset bits, const std::vector> parameter) +unsigned long int Gps_CNAV_Navigation_Message::read_navigation_unsigned(std::bitset bits, const std::vector> parameter) { unsigned long int value = 0; int num_of_slices = parameter.size(); @@ -98,7 +98,7 @@ unsigned long int Gps_CNAV_Navigation_Message::read_navigation_unsigned(std::bit for (int j = 0; j < parameter[i].second; j++) { value <<= 1; //shift left - if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1) + if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1) { value += 1; // insert the bit } @@ -108,7 +108,7 @@ unsigned long int Gps_CNAV_Navigation_Message::read_navigation_unsigned(std::bit } -signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset bits, const std::vector> parameter) +signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset bits, const std::vector> parameter) { signed long int value = 0; int num_of_slices = parameter.size(); @@ -117,7 +117,7 @@ signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset< if (long_int_size_bytes == 8) // if a long int takes 8 bytes, we are in a 64 bits system { // read the MSB and perform the sign extension - if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1) + if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1) { value ^= 0xFFFFFFFFFFFFFFFF; //64 bits variable } @@ -132,7 +132,7 @@ signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset< { value <<= 1; //shift left value &= 0xFFFFFFFFFFFFFFFE; //reset the corresponding bit (for the 64 bits variable) - if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1) + if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1) { value += 1; // insert the bit } @@ -142,7 +142,7 @@ signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset< else // we assume we are in a 32 bits system { // read the MSB and perform the sign extension - if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1) + if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1) { value ^= 0xFFFFFFFF; } @@ -157,7 +157,7 @@ signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset< { value <<= 1; //shift left value &= 0xFFFFFFFE; //reset the corresponding bit - if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1) + if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1) { value += 1; // insert the bit } @@ -168,7 +168,7 @@ signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset< } -void Gps_CNAV_Navigation_Message::decode_page(std::bitset data_bits) +void Gps_CNAV_Navigation_Message::decode_page(std::bitset data_bits) { int PRN; int page_type; diff --git a/src/core/system_parameters/gps_cnav_navigation_message.h b/src/core/system_parameters/gps_cnav_navigation_message.h index a3710065c..3fd1fa913 100644 --- a/src/core/system_parameters/gps_cnav_navigation_message.h +++ b/src/core/system_parameters/gps_cnav_navigation_message.h @@ -38,8 +38,7 @@ #include #include #include -#include "GPS_L2C.h" -#include "GPS_L5.h" +#include "GPS_CNAV.h" #include "gps_cnav_ephemeris.h" #include "gps_cnav_iono.h" #include "gps_cnav_utc_model.h" @@ -56,9 +55,9 @@ class Gps_CNAV_Navigation_Message { private: - unsigned long int read_navigation_unsigned(std::bitset bits, const std::vector> parameter); - signed long int read_navigation_signed(std::bitset bits, const std::vector> parameter); - bool read_navigation_bool(std::bitset bits, const std::vector> parameter); + unsigned long int read_navigation_unsigned(std::bitset bits, const std::vector> parameter); + signed long int read_navigation_signed(std::bitset bits, const std::vector> parameter); + bool read_navigation_bool(std::bitset bits, const std::vector> parameter); Gps_CNAV_Ephemeris ephemeris_record; Gps_CNAV_Iono iono_record; @@ -90,7 +89,7 @@ public: // public functions void reset(); - void decode_page(std::bitset data_bits); + void decode_page(std::bitset data_bits); /*! * \brief Obtain a GPS SV Ephemeris class filled with current SV data */ diff --git a/src/core/system_parameters/rtcm.cc b/src/core/system_parameters/rtcm.cc index 9999b3671..9a2b5f97f 100644 --- a/src/core/system_parameters/rtcm.cc +++ b/src/core/system_parameters/rtcm.cc @@ -41,6 +41,7 @@ #include #include #include "Galileo_E1.h" +#include "GPS_L2C.h" using google::LogMessage; From 52aabf05c169ce115a7e3434d4fc147139dc982a Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Thu, 14 Dec 2017 16:39:34 +0100 Subject: [PATCH 08/96] Fix GPS L5 --- .../PVT/gnuradio_blocks/rtklib_pvt_cc.cc | 7 ++- src/algorithms/PVT/libs/rtklib_solver.cc | 3 +- src/algorithms/libs/gps_l5_signal.cc | 8 +-- src/algorithms/libs/rtklib/rtklib_pntpos.cc | 10 +++- .../gps_l2c_telemetry_decoder_cc.cc | 10 +--- .../gps_l5_telemetry_decoder_cc.cc | 60 +++++++++---------- .../gps_l5_telemetry_decoder_cc.h | 9 +-- .../libs/libswiftcnav/cnav_msg.c | 3 +- src/core/system_parameters/GPS_L5.h | 5 +- .../gps_cnav_navigation_message.cc | 1 + 10 files changed, 53 insertions(+), 63 deletions(-) diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc index 4c1f4bf5d..2b94ab34d 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc @@ -123,7 +123,7 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) gps_cnav_ephemeris = boost::any_cast>(pmt::any_ref(msg)); // update/insert new ephemeris record to the global ephemeris map d_ls_pvt->gps_cnav_ephemeris_map[gps_cnav_ephemeris->i_satellite_PRN] = *gps_cnav_ephemeris; - LOG(INFO) << "New GPS CNAV ephemeris record has arrived "; + DLOG(INFO) << "New GPS CNAV ephemeris record has arrived "; } else if(pmt::any_ref(msg).type() == typeid(std::shared_ptr) ) { @@ -335,7 +335,7 @@ rtklib_pvt_cc::~rtklib_pvt_cc() msgctl(sysv_msqid, IPC_RMID, NULL); //save GPS L2CM ephemeris to XML file - std::string file_name = "eph_GPS_L2CM.xml"; + std::string file_name = "eph_GPS_L2CM_L5.xml"; if (d_ls_pvt->gps_cnav_ephemeris_map.size() > 0) { @@ -470,7 +470,8 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite if(((tmp_eph_iter_gps->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("1C") == 0)) || ((tmp_eph_iter_cnav->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("2S") == 0)) || ((tmp_eph_iter_gal->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("1B") == 0)) - || ((tmp_eph_iter_gal->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("5X") == 0))) + || ((tmp_eph_iter_gal->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("5X") == 0)) + || ((tmp_eph_iter_cnav->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("L5") == 0))) { // store valid observables in a map. gnss_observables_map.insert(std::pair(i, in[i][epoch])); diff --git a/src/algorithms/PVT/libs/rtklib_solver.cc b/src/algorithms/PVT/libs/rtklib_solver.cc index 622f7a1c4..726225998 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.cc +++ b/src/algorithms/PVT/libs/rtklib_solver.cc @@ -275,7 +275,7 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ } } //GPS L5 - if(sig_.compare("5X") == 0) + if(sig_.compare("L5") == 0) { gps_cnav_ephemeris_iter = gps_cnav_ephemeris_map.find(gnss_observables_iter->second.PRN); if (gps_cnav_ephemeris_iter != gps_cnav_ephemeris_map.cend()) @@ -346,7 +346,6 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ nav_data.lam[i][1] = SPEED_OF_LIGHT / FREQ2; /* L2 */ nav_data.lam[i][2] = SPEED_OF_LIGHT / FREQ5; /* L5/E5 */ } - result = rtkpos(&rtk_, obs_data, valid_obs, &nav_data); if(result == 0) { diff --git a/src/algorithms/libs/gps_l5_signal.cc b/src/algorithms/libs/gps_l5_signal.cc index 33396ca23..5aa15b96c 100644 --- a/src/algorithms/libs/gps_l5_signal.cc +++ b/src/algorithms/libs/gps_l5_signal.cc @@ -186,7 +186,7 @@ void gps_l5i_code_gen_complex(std::complex* _dest, unsigned int _prn) if (_prn > 0 and _prn < 51) { - make_l5i(_code, _prn); + make_l5i(_code, _prn - 1); } for (signed int i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++) @@ -206,7 +206,7 @@ void gps_l5i_code_gen_complex_sampled(std::complex* _dest, unsigned int _ int32_t* _code = new int32_t[GPS_L5i_CODE_LENGTH_CHIPS]; if (_prn > 0 and _prn < 51) { - make_l5i(_code, _prn); + make_l5i(_code, _prn - 1); } signed int _samplesPerCode, _codeValueIndex; @@ -253,7 +253,7 @@ void gps_l5q_code_gen_complex(std::complex* _dest, unsigned int _prn) if (_prn > 0 and _prn < 51) { - make_l5q(_code, _prn); + make_l5q(_code, _prn - 1); } for (signed int i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++) @@ -273,7 +273,7 @@ void gps_l5q_code_gen_complex_sampled(std::complex* _dest, unsigned int _ int32_t* _code = new int32_t[GPS_L5q_CODE_LENGTH_CHIPS]; if (_prn > 0 and _prn < 51) { - make_l5q(_code, _prn); + make_l5q(_code, _prn - 1); } signed int _samplesPerCode, _codeValueIndex; diff --git a/src/algorithms/libs/rtklib/rtklib_pntpos.cc b/src/algorithms/libs/rtklib/rtklib_pntpos.cc index 056dc2901..4199dcb96 100644 --- a/src/algorithms/libs/rtklib/rtklib_pntpos.cc +++ b/src/algorithms/libs/rtklib/rtklib_pntpos.cc @@ -97,7 +97,13 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel, /* L1-L2 for GPS/GLO/QZS, L1-L5 for GAL/SBS */ - if (NFREQ >= 3 && (sys & (SYS_GAL | SYS_SBS))) j = 2; + if (sys & (SYS_GAL | SYS_SBS)) {j = 2;} + + if (sys == SYS_GPS) + { + if(obs->code[1] != CODE_NONE) {j = 1;} + else if(obs->code[2] != CODE_NONE) {j = 2;} + } if (NFREQ<2 || lam[i] == 0.0 || lam[j] == 0.0) { @@ -132,7 +138,7 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel, P2_C2 = nav->cbias[obs->sat-1][2]; /* if no P1-P2 DCB, use TGD instead */ - if (P1_P2 == 0.0 && (sys & (SYS_GPS | SYS_GAL | SYS_QZS))) + if (P1_P2 == 0.0 && (sys & (SYS_GPS | SYS_GAL | SYS_QZS))) //CHECK! { P1_P2 = (1.0 - gamma_) * gettgd(obs->sat, nav); } diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_cc.cc index 693990124..242aca3ac 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_cc.cc @@ -170,12 +170,6 @@ int gps_l2c_telemetry_decoder_cc::general_work (int noutput_items __attribute__( current_synchro_data.TOW_at_current_symbol_s = d_TOW_at_current_symbol; current_synchro_data.Flag_valid_word = d_flag_valid_word; - // if (flag_PLL_180_deg_phase_locked == true) - // { - // //correct the accumulated phase for the Costas loop phase shift, if required - // current_synchro_data.Carrier_phase_rads += GPS_PI; - // } - if(d_dump == true) { // MULTIPLEXED FILE RECORDING - Record results to file @@ -192,7 +186,7 @@ int gps_l2c_telemetry_decoder_cc::general_work (int noutput_items __attribute__( } catch (const std::ifstream::failure & e) { - LOG(WARNING) << "Exception writing observables dump file " << e.what(); + LOG(WARNING) << "Exception writing Telemetry GPS L2 dump file " << e.what(); } } @@ -230,7 +224,7 @@ void gps_l2c_telemetry_decoder_cc::set_channel(int channel) } catch (const std::ifstream::failure &e) { - LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); + LOG(WARNING) << "channel " << d_channel << " Exception opening Telemetry GPS L2 dump file " << e.what(); } } } diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc index 6bd77a4b5..30d549508 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc @@ -62,14 +62,10 @@ gps_l5_telemetry_decoder_cc::gps_l5_telemetry_decoder_cc( d_dump = dump; d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); DLOG(INFO) << "GPS L5 TELEMETRY PROCESSING: satellite " << d_satellite; - //set_output_multiple (1); d_channel = 0; d_flag_valid_word = false; - d_TOW_at_current_symbol = 0; - d_TOW_at_Preamble = 0; - d_state = 0; //initial state - d_crc_error_count = 0; - + d_TOW_at_current_symbol = 0.0; + d_TOW_at_Preamble = 0.0; //initialize the CNAV frame decoder (libswiftcnav) cnav_msg_decoder_init(&d_cnav_decoder); for(int aux = 0; aux < GPS_L5_NH_CODE_LENGTH; aux++) @@ -117,33 +113,30 @@ int gps_l5_telemetry_decoder_cc::general_work (int noutput_items __attribute__(( current_synchro_data = in[0]; consume_each(1); //one by one sym_hist.push_back(in[0].Prompt_I); - double symbol_value = 0.0; + int corr_NH = 0; + int symbol_value = 0; + //Search correlation with Neuman-Hofman Code (see IS-GPS-705D) if(sym_hist.size() == GPS_L5_NH_CODE_LENGTH) { - std::deque::iterator it; - int corr_NH = 0; - it = sym_hist.begin(); for(int i = 0; i < GPS_L5_NH_CODE_LENGTH; i++) { - if((bits_NH[i] * (*it)) > 0.0){corr_NH += 1;} - else{corr_NH -= 1;} - it++; + if((bits_NH[i] * sym_hist.at(i)) > 0.0) {corr_NH += 1;} + else {corr_NH -= 1;} + } + if(abs(corr_NH) == GPS_L5_NH_CODE_LENGTH) + { + sync_NH = true; + if(corr_NH > 0) {symbol_value = 1;} + else {symbol_value = -1;} + new_sym = true; + sym_hist.clear(); } - if(abs(corr_NH) == GPS_L5_NH_CODE_LENGTH){sync_NH = true;} else { sym_hist.pop_front(); sync_NH = false; - } - if (sync_NH) - { - new_sym = true; - for(it = sym_hist.begin(); it != sym_hist.end(); it++) - { - symbol_value += (*it); - } - sym_hist.clear(); + new_sym = false; } } @@ -154,7 +147,7 @@ int gps_l5_telemetry_decoder_cc::general_work (int noutput_items __attribute__(( //add the symbol to the decoder if(new_sym) { - u8 symbol_clip = static_cast(symbol_value > 0.0) * 255; + u8 symbol_clip = static_cast(symbol_value > 0) * 255; flag_new_cnav_frame = cnav_msg_decoder_add_symbol(&d_cnav_decoder, symbol_clip, &msg, &delay); new_sym = false; } @@ -162,7 +155,6 @@ int gps_l5_telemetry_decoder_cc::general_work (int noutput_items __attribute__(( //check if new CNAV frame is available if (flag_new_cnav_frame == true) { - std::cout << "NEW CNAV FRAME" << std::endl; std::bitset raw_bits; //Expand packet bits to bitsets. Notice the reverse order of the bits sequence, required by the CNAV message decoder for (u32 i = 0; i < GPS_L5_CNAV_DATA_PAGE_BITS ; i++) @@ -177,31 +169,31 @@ int gps_l5_telemetry_decoder_cc::general_work (int noutput_items __attribute__(( { // get ephemeris object for this SV std::shared_ptr tmp_obj = std::make_shared(d_CNAV_Message.get_ephemeris()); - std::cout << "New GPS CNAV message received: ephemeris from satellite " << d_satellite << std::endl; + std::cout << "New GPS L5 CNAV message received: ephemeris from satellite " << d_satellite << std::endl; this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); } if (d_CNAV_Message.have_new_iono() == true) { std::shared_ptr tmp_obj = std::make_shared(d_CNAV_Message.get_iono()); - std::cout << "New GPS CNAV message received: iono model parameters from satellite " << d_satellite << std::endl; + std::cout << "New GPS L5 CNAV message received: iono model parameters from satellite " << d_satellite << std::endl; this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); } if (d_CNAV_Message.have_new_utc_model() == true) { std::shared_ptr tmp_obj = std::make_shared(d_CNAV_Message.get_utc_model()); - std::cout << "New GPS CNAV message received: UTC model parameters from satellite " << d_satellite << std::endl; + std::cout << "New GPS L5 CNAV message received: UTC model parameters from satellite " << d_satellite << std::endl; this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); } //update TOW at the preamble instant - d_TOW_at_Preamble = static_cast(msg.tow); + d_TOW_at_Preamble = static_cast(msg.tow) * 6.0; //* The time of the last input symbol can be computed from the message ToW and //* delay by the formulae: //* \code - //* symbolTime_ms = msg->tow * 6000 + *pdelay * 20 - d_TOW_at_current_symbol = static_cast(msg.tow) * 6.0 + static_cast(delay) * GPS_L5i_PERIOD + 6 * GPS_L5i_PERIOD; + //* symbolTime_ms = msg->tow * 6000 + *pdelay * 10 + d_TOW_at_current_symbol = (static_cast(msg.tow) * 6.0) + (static_cast(delay) + 12.0) * GPS_L5i_SYMBOL_PERIOD; d_TOW_at_current_symbol = floor(d_TOW_at_current_symbol * 1000.0) / 1000.0; d_flag_valid_word = true; } @@ -232,7 +224,7 @@ int gps_l5_telemetry_decoder_cc::general_work (int noutput_items __attribute__(( } catch (const std::ifstream::failure & e) { - LOG(WARNING) << "Exception writing observables dump file " << e.what(); + LOG(WARNING) << "Exception writing Telemetry GPS L5 dump file " << e.what(); } } @@ -246,12 +238,14 @@ void gps_l5_telemetry_decoder_cc::set_satellite(const Gnss_Satellite & satellite { d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); LOG(INFO) << "GPS L5 CNAV telemetry decoder in channel " << this->d_channel << " set to satellite " << d_satellite; + d_CNAV_Message.reset(); } void gps_l5_telemetry_decoder_cc::set_channel(int channel) { d_channel = channel; + d_CNAV_Message.reset(); LOG(INFO) << "GPS L5 CNAV channel set to " << channel; // ############# ENABLE DATA FILE LOG ################# if (d_dump == true) @@ -270,7 +264,7 @@ void gps_l5_telemetry_decoder_cc::set_channel(int channel) } catch (const std::ifstream::failure &e) { - LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); + LOG(WARNING) << "channel " << d_channel << " Exception opening Telemetry GPS L5 dump file " << e.what(); } } } diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h index 77f91783b..3d60b95ce 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h @@ -58,7 +58,7 @@ gps_l5_telemetry_decoder_cc_sptr gps_l5_make_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump); /*! - * \brief This class implements a block that decodes the SBAS integrity and corrections data defined in RTCA MOPS DO-229 + * \brief This class implements a GPS L5 Telemetry decoder * */ class gps_l5_telemetry_decoder_cc : public gr::block @@ -67,10 +67,6 @@ public: ~gps_l5_telemetry_decoder_cc(); 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); @@ -89,9 +85,6 @@ private: cnav_msg_decoder_t d_cnav_decoder; - int d_state; - int d_crc_error_count; - double d_TOW_at_current_symbol; double d_TOW_at_Preamble; bool d_flag_valid_word; diff --git a/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.c b/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.c index fbc3a22ab..e1e62da30 100644 --- a/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.c +++ b/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.c @@ -411,7 +411,8 @@ void cnav_msg_decoder_init(cnav_msg_decoder_t *dec) * The time of the last input symbol can be computed from the message ToW and * delay by the formulae: * \code - * symbolTime_ms = msg->tow * 6000 + *pdelay * 20 + * symbolTime_ms = msg->tow * 6000 + *pdelay * 20 (L2) + * symbolTime_ms = msg->tow * 6000 + *pdelay * 10 (L5) * \endcode * * \param[in,out] dec Decoder object. diff --git a/src/core/system_parameters/GPS_L5.h b/src/core/system_parameters/GPS_L5.h index a65d3d3f6..1c6ceb8ff 100644 --- a/src/core/system_parameters/GPS_L5.h +++ b/src/core/system_parameters/GPS_L5.h @@ -51,8 +51,9 @@ const double GPS_L5_F = -4.442807633e-10; //!< Constant, [s/(m)^(1 const double GPS_L5_FREQ_HZ = FREQ5; //!< L5 [Hz] const double GPS_L5i_CODE_RATE_HZ = 10.23e6; //!< GPS L5i code rate [chips/s] -const int GPS_L5i_CODE_LENGTH_CHIPS = 10230; //!< GPS L5i code length [chips] -const double GPS_L5i_PERIOD = 0.001; //!< GPS L5 code period [seconds] +const int GPS_L5i_CODE_LENGTH_CHIPS = 10230; //!< GPS L5i code length [chips] +const double GPS_L5i_PERIOD = 0.001; //!< GPS L5 code period [seconds] +const double GPS_L5i_SYMBOL_PERIOD = 0.01; //!< GPS L5 symbol period [seconds] const double GPS_L5q_CODE_RATE_HZ = 10.23e6; //!< GPS L5i code rate [chips/s] const int GPS_L5q_CODE_LENGTH_CHIPS = 10230; //!< GPS L5i code length [chips] diff --git a/src/core/system_parameters/gps_cnav_navigation_message.cc b/src/core/system_parameters/gps_cnav_navigation_message.cc index 6ffe5cad1..a78ade0c7 100644 --- a/src/core/system_parameters/gps_cnav_navigation_message.cc +++ b/src/core/system_parameters/gps_cnav_navigation_message.cc @@ -40,6 +40,7 @@ void Gps_CNAV_Navigation_Message::reset() b_flag_ephemeris_1 = false; b_flag_ephemeris_2 = false; b_flag_iono_valid = false; + b_flag_utc_valid = false; // satellite positions d_satpos_X = 0; From b2b889ec79445be41d48c12d256b6faf82755836 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 18 Dec 2017 11:07:29 +0100 Subject: [PATCH 09/96] Minor changes in Telemetry comments --- .../gnuradio_blocks/gps_l2c_telemetry_decoder_cc.cc | 2 +- .../gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_cc.cc index 242aca3ac..01b4bed0b 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_cc.cc @@ -154,7 +154,7 @@ int gps_l2c_telemetry_decoder_cc::general_work (int noutput_items __attribute__( //* The time of the last input symbol can be computed from the message ToW and //* delay by the formulae: //* \code - //* symbolTime_ms = msg->tow * 6000 + *pdelay * 20 + //* symbolTime_ms = msg->tow * 6000 + *pdelay * 20 + (12 * 20); 12 symbols of the encoder's transitory d_TOW_at_current_symbol = static_cast(msg.tow) * 6.0 + static_cast(delay) * GPS_L2_M_PERIOD + 12 * GPS_L2_M_PERIOD; d_TOW_at_current_symbol = floor(d_TOW_at_current_symbol * 1000.0) / 1000.0; d_flag_valid_word = true; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc index 30d549508..2d604b221 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc @@ -192,7 +192,7 @@ int gps_l5_telemetry_decoder_cc::general_work (int noutput_items __attribute__(( //* The time of the last input symbol can be computed from the message ToW and //* delay by the formulae: //* \code - //* symbolTime_ms = msg->tow * 6000 + *pdelay * 10 + //* symbolTime_ms = msg->tow * 6000 + *pdelay * 10 + (12 * 10); 12 symbols of the encoder's transitory d_TOW_at_current_symbol = (static_cast(msg.tow) * 6.0) + (static_cast(delay) + 12.0) * GPS_L5i_SYMBOL_PERIOD; d_TOW_at_current_symbol = floor(d_TOW_at_current_symbol * 1000.0) / 1000.0; d_flag_valid_word = true; From cef7ae5f7bacfbf523d5bcb63c33cd42d6cba62e Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 18 Dec 2017 15:40:14 +0100 Subject: [PATCH 10/96] Add LOG lines in channel_fsm --- src/algorithms/channel/libs/channel_fsm.cc | 5 ++ src/core/receiver/gnss_flowgraph.cc | 61 +++++++++++----------- src/core/system_parameters/gnss_signal.h | 2 +- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/src/algorithms/channel/libs/channel_fsm.cc b/src/algorithms/channel/libs/channel_fsm.cc index 187d419f4..44ee7bce5 100644 --- a/src/algorithms/channel/libs/channel_fsm.cc +++ b/src/algorithms/channel/libs/channel_fsm.cc @@ -150,23 +150,27 @@ void ChannelFsm::Event_start_acquisition() { this->process_event(Ev_channel_start_acquisition()); //std::cout<<"Ev_channel_start_acquisition launched"<process_event(Ev_channel_valid_acquisition()); + DLOG(INFO) << "CH = " << channel_ << ". Ev valid acquisition"; } void ChannelFsm::Event_failed_acquisition_repeat() { this->process_event(Ev_channel_failed_acquisition_repeat()); + DLOG(INFO) << "CH = " << channel_ << ". Ev failed acquisition repeat"; } void ChannelFsm::Event_failed_acquisition_no_repeat() { this->process_event(Ev_channel_failed_acquisition_no_repeat()); + DLOG(INFO) << "CH = " << channel_ << ". Ev failed acquisition no repeat"; } @@ -174,6 +178,7 @@ void ChannelFsm::Event_failed_acquisition_no_repeat() void ChannelFsm::Event_failed_tracking_standby() { this->process_event(Ev_channel_failed_tracking_standby()); + DLOG(INFO) << "CH = " << channel_ << ". Ev failed tracking standby"; } //void ChannelFsm::Event_failed_tracking_reacq() { diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index ed505b5f9..a535c90fd 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -374,11 +374,10 @@ bool GNSSFlowgraph::send_telemetry_msg(pmt::pmt_t msg) void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) { DLOG(INFO) << "received " << what << " from " << who; - switch (what) { case 0: - LOG(INFO) << "Channel " << who << " ACQ FAILED satellite " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); + DLOG(INFO) << "Channel " << who << " ACQ FAILED satellite " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); available_GNSS_signals_.push_back(channels_.at(who)->get_signal()); //TODO: Optimize the channel and signal matching! while ( channels_.at(who)->get_signal().get_signal_str().compare(available_GNSS_signals_.front().get_signal_str()) != 0 ) @@ -388,15 +387,33 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) } channels_.at(who)->set_signal(available_GNSS_signals_.front()); available_GNSS_signals_.pop_front(); - usleep(100); - LOG(INFO) << "Channel "<< who << " Starting acquisition " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); + DLOG(INFO) << "Channel "<< who << " Starting acquisition " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); channels_.at(who)->start_acquisition(); break; + case 1: - LOG(INFO) << "Channel " << who << " ACQ SUCCESS satellite " << channels_.at(who)->get_signal().get_satellite(); + DLOG(INFO) << "Channel " << who << " ACQ SUCCESS satellite " << channels_.at(who)->get_signal().get_satellite(); channels_state_[who] = 2; acq_channels_count_--; - if (!available_GNSS_signals_.empty() && acq_channels_count_ < max_acq_channels_) + for (unsigned int i = 0; i < channels_count_; i++) + { + if(!available_GNSS_signals_.empty() && (acq_channels_count_ < max_acq_channels_) && (channels_state_[i] == 0)) + { + channels_state_[i] = 1; + while (channels_.at(i)->get_signal().get_signal_str().compare(available_GNSS_signals_.front().get_signal_str()) != 0) + { + available_GNSS_signals_.push_back(available_GNSS_signals_.front()); + available_GNSS_signals_.pop_front(); + } + channels_.at(i)->set_signal(available_GNSS_signals_.front()); + available_GNSS_signals_.pop_front(); + acq_channels_count_++; + channels_.at(i)->start_acquisition(); + } + DLOG(INFO) << "Channel " << i << " in state " << channels_state_[i]; + } + /* + if (!available_GNSS_signals_.empty() && (acq_channels_count_ < max_acq_channels_)) { for (unsigned int i = 0; i < channels_count_; i++) { @@ -417,11 +434,12 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) DLOG(INFO) << "Channel " << i << " in state " << channels_state_[i]; } } - + */ break; case 2: - LOG(INFO) << "Channel " << who << " TRK FAILED satellite " << channels_.at(who)->get_signal().get_satellite(); + DLOG(INFO) << "Channel " << who << " TRK FAILED satellite " << channels_.at(who)->get_signal().get_satellite(); + DLOG(INFO) << "Number of channels in acquisition = " << acq_channels_count_; if (acq_channels_count_ < max_acq_channels_) { channels_state_[who] = 1; @@ -433,17 +451,13 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) channels_state_[who] = 0; available_GNSS_signals_.push_back( channels_.at(who)->get_signal() ); } - - // for (unsigned int i = 0; i < channels_count_; i++) - // { - // LOG(INFO) << "Channel " << i << " in state " << channels_state_[i] << std::endl; - // } break; default: break; } DLOG(INFO) << "Number of available signals: " << available_GNSS_signals_.size(); + applied_actions_++; } @@ -555,7 +569,6 @@ void GNSSFlowgraph::init() set_signals_list(); set_channels_state(); applied_actions_ = 0; - DLOG(INFO) << "Blocks instantiated. " << channels_count_ << " channels."; } @@ -704,7 +717,7 @@ void GNSSFlowgraph::set_signals_list() if (configuration_->property("Channels_1B.count", 0) > 0) { /* - * Loop to create the list of Galileo E1 B signals + * Loop to create the list of Galileo E1B signals */ for (available_gnss_prn_iter = available_galileo_prn.cbegin(); available_gnss_prn_iter != available_galileo_prn.cend(); @@ -718,7 +731,7 @@ void GNSSFlowgraph::set_signals_list() if (configuration_->property("Channels_5X.count", 0) > 0 ) { /* - * Loop to create the list of Galileo E1 B signals + * Loop to create the list of Galileo E5a signals */ for (available_gnss_prn_iter = available_galileo_prn.cbegin(); available_gnss_prn_iter != available_galileo_prn.cend(); @@ -754,14 +767,6 @@ void GNSSFlowgraph::set_signals_list() gnss_it = available_GNSS_signals_.insert(gnss_it, signal_value); } } - - // **** FOR DEBUGGING THE LIST OF GNSS SIGNALS **** - // std::list::const_iterator available_gnss_list_iter; - // for (available_gnss_list_iter = available_GNSS_signals_.cbegin(); available_gnss_list_iter - // != available_GNSS_signals_.cend(); available_gnss_list_iter++) - // { - // std::cout << *available_gnss_list_iter << std::endl; - // } } @@ -776,12 +781,8 @@ void GNSSFlowgraph::set_channels_state() channels_state_.reserve(channels_count_); for (unsigned int i = 0; i < channels_count_; i++) { - if (i < max_acq_channels_) - { - channels_state_.push_back(1); - } - else - channels_state_.push_back(0); + if (i < max_acq_channels_) {channels_state_.push_back(1);} + else {channels_state_.push_back(0);} DLOG(INFO) << "Channel " << i << " in state " << channels_state_[i]; } acq_channels_count_ = max_acq_channels_; diff --git a/src/core/system_parameters/gnss_signal.h b/src/core/system_parameters/gnss_signal.h index 4922e5399..25288a704 100644 --- a/src/core/system_parameters/gnss_signal.h +++ b/src/core/system_parameters/gnss_signal.h @@ -51,7 +51,7 @@ public: Gnss_Signal(const std::string& signal_); Gnss_Signal(const Gnss_Satellite& satellite_, const std::string& signal_); ~Gnss_Signal(); - std::string get_signal_str() const; //!< Get the satellite signal {"1C" for GPS L1 C/A, "2S" for GPS L2C (M), "1B" for Galileo E1B, "5X" for Galileo E5a} + std::string get_signal_str() const; //!< Get the satellite signal {"1C" for GPS L1 C/A, "2S" for GPS L2C (M), "1B" for Galileo E1B, "5X" for Galileo E5a, "L5" for GPS L5} Gnss_Satellite get_satellite() const; //!< Get the Gnss_Satellite associated to the signal friend bool operator== (const Gnss_Signal &, const Gnss_Signal &); //!< operator== for comparison friend std::ostream& operator<<(std::ostream &, const Gnss_Signal &); //!< operator<< for pretty printing From 8bb0c880c032c2a4045058203cf17947d18624b2 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Wed, 20 Dec 2017 16:12:08 +0100 Subject: [PATCH 11/96] Minor changes in DLOG lines --- src/algorithms/PVT/libs/rtklib_solver.cc | 2 +- src/algorithms/channel/libs/channel_fsm.cc | 3 +-- .../channel/libs/channel_msg_receiver_cc.cc | 4 ---- src/core/receiver/gnss_flowgraph.cc | 15 ++++++++------- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/algorithms/PVT/libs/rtklib_solver.cc b/src/algorithms/PVT/libs/rtklib_solver.cc index 726225998..93685eb24 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.cc +++ b/src/algorithms/PVT/libs/rtklib_solver.cc @@ -349,7 +349,7 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ result = rtkpos(&rtk_, obs_data, valid_obs, &nav_data); if(result == 0) { - LOG(INFO) << "RTKLIB rtkpos error message: " << rtk_.errbuf; + DLOG(INFO) << "RTKLIB rtkpos error message: " << rtk_.errbuf; this->set_time_offset_s(0.0); //reset rx time estimation this->set_num_valid_observations(0); } diff --git a/src/algorithms/channel/libs/channel_fsm.cc b/src/algorithms/channel/libs/channel_fsm.cc index 44ee7bce5..85905bfd8 100644 --- a/src/algorithms/channel/libs/channel_fsm.cc +++ b/src/algorithms/channel/libs/channel_fsm.cc @@ -115,8 +115,7 @@ public: typedef sc::transition reactions; - channel_waiting_fsm_S3(my_context ctx) : - my_base(ctx) + channel_waiting_fsm_S3(my_context ctx) : my_base(ctx) { //std::cout << "Enter Channel_waiting_S3 " << std::endl; context ().request_satellite(); diff --git a/src/algorithms/channel/libs/channel_msg_receiver_cc.cc b/src/algorithms/channel/libs/channel_msg_receiver_cc.cc index 573c1aa84..d22f2dd73 100644 --- a/src/algorithms/channel/libs/channel_msg_receiver_cc.cc +++ b/src/algorithms/channel/libs/channel_msg_receiver_cc.cc @@ -50,13 +50,9 @@ void channel_msg_receiver_cc::msg_handler_events(pmt::pmt_t msg) switch (message) { case 1: //positive acquisition - //DLOG(INFO) << "Channel " << channel_ << " ACQ SUCCESS satellite " << - // gnss_synchro_.System << " " << gnss_synchro_.PRN; d_channel_fsm->Event_valid_acquisition(); break; case 2: //negative acquisition - //DLOG(INFO) << "Channel " << channel_ - // << " ACQ FAILED satellite " << gnss_synchro_.System << " " << gnss_synchro_.PRN; if (d_repeat == true) { d_channel_fsm->Event_failed_acquisition_repeat(); diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index a535c90fd..609908097 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -91,12 +91,6 @@ void GNSSFlowgraph::start() void GNSSFlowgraph::stop() { - // for (unsigned int i = 0; i < channels_count_; i++) - // { - // channels_.at(i)->stop_channel(); - // LOG(INFO) << "Channel " << i << " in state " << channels_state_[i]; - // } - // LOG(INFO) << "Threads finished. Return to main program."; top_block_->stop(); running_ = false; } @@ -373,11 +367,13 @@ bool GNSSFlowgraph::send_telemetry_msg(pmt::pmt_t msg) */ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) { - DLOG(INFO) << "received " << what << " from " << who; + DLOG(INFO) << "Received " << what << " from " << who << ". Number of applied actions = " << applied_actions_; + VLOG(-100) << "Received " << what << " from " << who << ". Number of applied actions = " << applied_actions_; switch (what) { case 0: DLOG(INFO) << "Channel " << who << " ACQ FAILED satellite " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); + VLOG(-100) << "Channel " << who << " ACQ FAILED satellite " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); available_GNSS_signals_.push_back(channels_.at(who)->get_signal()); //TODO: Optimize the channel and signal matching! while ( channels_.at(who)->get_signal().get_signal_str().compare(available_GNSS_signals_.front().get_signal_str()) != 0 ) @@ -388,11 +384,13 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) channels_.at(who)->set_signal(available_GNSS_signals_.front()); available_GNSS_signals_.pop_front(); DLOG(INFO) << "Channel "<< who << " Starting acquisition " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); + VLOG(-100) << "Channel "<< who << " Starting acquisition " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); channels_.at(who)->start_acquisition(); break; case 1: DLOG(INFO) << "Channel " << who << " ACQ SUCCESS satellite " << channels_.at(who)->get_signal().get_satellite(); + VLOG(-100) << "Channel " << who << " ACQ SUCCESS satellite " << channels_.at(who)->get_signal().get_satellite(); channels_state_[who] = 2; acq_channels_count_--; for (unsigned int i = 0; i < channels_count_; i++) @@ -440,6 +438,9 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) case 2: DLOG(INFO) << "Channel " << who << " TRK FAILED satellite " << channels_.at(who)->get_signal().get_satellite(); DLOG(INFO) << "Number of channels in acquisition = " << acq_channels_count_; + VLOG(-100) << "Channel " << who << " TRK FAILED satellite " << channels_.at(who)->get_signal().get_satellite(); + VLOG(-100) << "Number of channels in acquisition = " << acq_channels_count_; + if (acq_channels_count_ < max_acq_channels_) { channels_state_[who] = 1; From 2d8141d9b518853e02cb3fb5883f78b115c34e24 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Thu, 21 Dec 2017 13:05:21 +0100 Subject: [PATCH 12/96] Migrate msg_queue boost smart pointers to gr sptr --- src/algorithms/channel/adapters/channel.cc | 2 +- src/algorithms/channel/adapters/channel.h | 2 +- src/algorithms/channel/libs/channel_fsm.cc | 2 +- src/algorithms/channel/libs/channel_fsm.h | 4 ++-- src/core/receiver/control_message_factory.cc | 6 +++--- src/core/receiver/control_message_factory.h | 2 +- src/core/receiver/control_thread.cc | 4 ++-- src/core/receiver/control_thread.h | 4 ++-- src/core/receiver/gnss_flowgraph.cc | 3 +-- src/core/receiver/gnss_flowgraph.h | 2 +- 10 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/algorithms/channel/adapters/channel.cc b/src/algorithms/channel/adapters/channel.cc index 425dbb968..f66353f7e 100644 --- a/src/algorithms/channel/adapters/channel.cc +++ b/src/algorithms/channel/adapters/channel.cc @@ -40,7 +40,7 @@ using google::LogMessage; Channel::Channel(ConfigurationInterface *configuration, unsigned int channel, std::shared_ptr pass_through, std::shared_ptr acq, std::shared_ptr trk, std::shared_ptr nav, - std::string role, std::string implementation, boost::shared_ptr queue) + std::string role, std::string implementation, gr::msg_queue::sptr queue) { pass_through_ = pass_through; acq_ = acq; diff --git a/src/algorithms/channel/adapters/channel.h b/src/algorithms/channel/adapters/channel.h index a05697eed..8e0893843 100644 --- a/src/algorithms/channel/adapters/channel.h +++ b/src/algorithms/channel/adapters/channel.h @@ -105,7 +105,7 @@ private: bool connected_; bool repeat_; ChannelFsm channel_fsm_; - boost::shared_ptr queue_; + gr::msg_queue::sptr queue_; }; #endif /*GNSS_SDR_CHANNEL_H_*/ diff --git a/src/algorithms/channel/libs/channel_fsm.cc b/src/algorithms/channel/libs/channel_fsm.cc index 85905bfd8..f147a57ef 100644 --- a/src/algorithms/channel/libs/channel_fsm.cc +++ b/src/algorithms/channel/libs/channel_fsm.cc @@ -194,7 +194,7 @@ void ChannelFsm::set_tracking(std::shared_ptr tracking) trk_ = tracking; } -void ChannelFsm::set_queue(boost::shared_ptr queue) +void ChannelFsm::set_queue(gr::msg_queue::sptr queue) { queue_ = queue; } diff --git a/src/algorithms/channel/libs/channel_fsm.h b/src/algorithms/channel/libs/channel_fsm.h index 868388b7b..997056723 100644 --- a/src/algorithms/channel/libs/channel_fsm.h +++ b/src/algorithms/channel/libs/channel_fsm.h @@ -59,7 +59,7 @@ public: void set_acquisition(std::shared_ptr acquisition); void set_tracking(std::shared_ptr tracking); - void set_queue(boost::shared_ptr queue); + void set_queue(gr::msg_queue::sptr queue); void set_channel(unsigned int channel); void start_acquisition(); void start_tracking(); @@ -77,7 +77,7 @@ public: private: std::shared_ptr acq_; std::shared_ptr trk_; - boost::shared_ptr queue_; + gr::msg_queue::sptr queue_; unsigned int channel_; }; diff --git a/src/core/receiver/control_message_factory.cc b/src/core/receiver/control_message_factory.cc index 6f7994c29..a7da90ab1 100644 --- a/src/core/receiver/control_message_factory.cc +++ b/src/core/receiver/control_message_factory.cc @@ -44,18 +44,18 @@ ControlMessageFactory::~ControlMessageFactory() {} -boost::shared_ptr ControlMessageFactory::GetQueueMessage(unsigned int who, unsigned int what) +gr::message::sptr ControlMessageFactory::GetQueueMessage(unsigned int who, unsigned int what) { std::shared_ptr control_message = std::make_shared(); control_message->who = who; control_message->what = what; - boost::shared_ptr queue_message = gr::message::make(0, 0, 0, sizeof(ControlMessage)); + gr::message::sptr queue_message = gr::message::make(0, 0, 0, sizeof(ControlMessage)); memcpy(queue_message->msg(), control_message.get(), sizeof(ControlMessage)); return queue_message; } -std::shared_ptr>> ControlMessageFactory::GetControlMessages(boost::shared_ptr queue_message) +std::shared_ptr>> ControlMessageFactory::GetControlMessages(gr::message::sptr queue_message) { std::shared_ptr>> control_messages = std::make_shared>>(); unsigned int control_messages_count = queue_message->length() / sizeof(ControlMessage); diff --git a/src/core/receiver/control_message_factory.h b/src/core/receiver/control_message_factory.h index 2ff294a8c..9bdd49d32 100644 --- a/src/core/receiver/control_message_factory.h +++ b/src/core/receiver/control_message_factory.h @@ -58,7 +58,7 @@ public: //! Virtual destructor virtual ~ControlMessageFactory(); - boost::shared_ptr GetQueueMessage(unsigned int who, unsigned int what); + gr::message::sptr GetQueueMessage(unsigned int who, unsigned int what); std::shared_ptr>> GetControlMessages(gr::message::sptr queue_message); }; diff --git a/src/core/receiver/control_thread.cc b/src/core/receiver/control_thread.cc index 44cdc36d3..73b05651c 100644 --- a/src/core/receiver/control_thread.cc +++ b/src/core/receiver/control_thread.cc @@ -158,7 +158,7 @@ void ControlThread::run() } -void ControlThread::set_control_queue(boost::shared_ptr control_queue) +void ControlThread::set_control_queue(gr::msg_queue::sptr control_queue) { if (flowgraph_->running()) { @@ -445,7 +445,7 @@ void ControlThread::init() void ControlThread::read_control_messages() { DLOG(INFO) << "Reading control messages from queue"; - boost::shared_ptr queue_message = control_queue_->delete_head(); + gr::message::sptr queue_message = control_queue_->delete_head(); if (queue_message != 0) { control_messages_ = control_message_factory_->GetControlMessages(queue_message); diff --git a/src/core/receiver/control_thread.h b/src/core/receiver/control_thread.h index 1580695df..ea0decec8 100644 --- a/src/core/receiver/control_thread.h +++ b/src/core/receiver/control_thread.h @@ -89,7 +89,7 @@ public: * * \param[in] boost::shared_ptr control_queue */ - void set_control_queue(boost::shared_ptr control_queue); + void set_control_queue(gr::msg_queue::sptr control_queue); unsigned int processed_control_messages() @@ -146,7 +146,7 @@ private: void apply_action(unsigned int what); std::shared_ptr flowgraph_; std::shared_ptr configuration_; - boost::shared_ptr control_queue_; + gr::msg_queue::sptr control_queue_; std::shared_ptr control_message_factory_; std::shared_ptr>> control_messages_; bool stop_; diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index 609908097..8bbd9a20c 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -51,8 +51,7 @@ using google::LogMessage; -GNSSFlowgraph::GNSSFlowgraph(std::shared_ptr configuration, - boost::shared_ptr queue) +GNSSFlowgraph::GNSSFlowgraph(std::shared_ptr configuration, gr::msg_queue::sptr queue) { connected_ = false; running_ = false; diff --git a/src/core/receiver/gnss_flowgraph.h b/src/core/receiver/gnss_flowgraph.h index d765d3cf4..4998d7170 100644 --- a/src/core/receiver/gnss_flowgraph.h +++ b/src/core/receiver/gnss_flowgraph.h @@ -139,7 +139,7 @@ private: std::vector> channels_; gnss_sdr_sample_counter_sptr ch_out_sample_counter; gr::top_block_sptr top_block_; - boost::shared_ptr queue_; + gr::msg_queue::sptr queue_; std::list available_GNSS_signals_; std::vector channels_state_; }; From 8932e9a51bcf6ce68fbf1d51027e4837eb95147c Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Thu, 21 Dec 2017 16:20:11 +0100 Subject: [PATCH 13/96] Clean acquisition interface --- src/core/interfaces/acquisition_interface.h | 1 - src/core/receiver/gnss_block_factory.cc | 16 ++++++++-------- src/core/receiver/gnss_block_factory.h | 18 +++++++++--------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/core/interfaces/acquisition_interface.h b/src/core/interfaces/acquisition_interface.h index 722b99777..b6d9e4e72 100644 --- a/src/core/interfaces/acquisition_interface.h +++ b/src/core/interfaces/acquisition_interface.h @@ -53,7 +53,6 @@ templateclass concurrent_queue; class AcquisitionInterface: public GNSSBlockInterface { public: - //virtual void set_active(bool active) = 0; virtual void set_gnss_synchro(Gnss_Synchro* gnss_synchro) = 0; virtual void set_channel(unsigned int channel) = 0; virtual void set_threshold(float threshold) = 0; diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index c3e3889fb..bdf34dc22 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -151,7 +151,7 @@ GNSSBlockFactory::~GNSSBlockFactory() std::unique_ptr GNSSBlockFactory::GetSignalSource( - std::shared_ptr configuration, boost::shared_ptr queue, int ID) + std::shared_ptr configuration, gr::msg_queue::sptr queue, int ID) { std::string default_implementation = "File_Signal_Source"; std::string role = "SignalSource"; //backwards compatibility for old conf files @@ -264,7 +264,7 @@ std::unique_ptr GNSSBlockFactory::GetPVT(std::shared_ptr GNSSBlockFactory::GetChannel_1C( std::shared_ptr configuration, std::string acq, std::string trk, std::string tlm, int channel, - boost::shared_ptr queue) + gr::msg_queue::sptr queue) { //"appendix" is added to the "role" with the aim of Acquisition, Tracking and Telemetry Decoder adapters //can find their specific configurations when they read the config @@ -332,7 +332,7 @@ std::unique_ptr GNSSBlockFactory::GetChannel_1C( std::unique_ptr GNSSBlockFactory::GetChannel_2S( std::shared_ptr configuration, std::string acq, std::string trk, std::string tlm, int channel, - boost::shared_ptr queue) + gr::msg_queue::sptr queue) { LOG(INFO) << "Instantiating Channel " << channel << " with Acquisition Implementation: " @@ -397,7 +397,7 @@ std::unique_ptr GNSSBlockFactory::GetChannel_2S( std::unique_ptr GNSSBlockFactory::GetChannel_1B( std::shared_ptr configuration, std::string acq, std::string trk, std::string tlm, int channel, - boost::shared_ptr queue) + gr::msg_queue::sptr queue) { std::stringstream stream; stream << channel; @@ -464,7 +464,7 @@ std::unique_ptr GNSSBlockFactory::GetChannel_1B( std::unique_ptr GNSSBlockFactory::GetChannel_5X( std::shared_ptr configuration, std::string acq, std::string trk, std::string tlm, int channel, - boost::shared_ptr queue) + gr::msg_queue::sptr queue) { std::stringstream stream; stream << channel; @@ -531,7 +531,7 @@ std::unique_ptr GNSSBlockFactory::GetChannel_5X( std::unique_ptr GNSSBlockFactory::GetChannel_L5( std::shared_ptr configuration, std::string acq, std::string trk, std::string tlm, int channel, - boost::shared_ptr queue) + gr::msg_queue::sptr queue) { std::stringstream stream; stream << channel; @@ -597,7 +597,7 @@ std::unique_ptr GNSSBlockFactory::GetChannel_L5( std::unique_ptr>> GNSSBlockFactory::GetChannels( - std::shared_ptr configuration, boost::shared_ptr queue) + std::shared_ptr configuration, gr::msg_queue::sptr queue) { std::string default_implementation = "Pass_Through"; std::string tracking_implementation; @@ -783,7 +783,7 @@ std::unique_ptr GNSSBlockFactory::GetBlock( std::shared_ptr configuration, std::string role, std::string implementation, unsigned int in_streams, - unsigned int out_streams, boost::shared_ptr queue) + unsigned int out_streams, gr::msg_queue::sptr queue) { std::unique_ptr block; diff --git a/src/core/receiver/gnss_block_factory.h b/src/core/receiver/gnss_block_factory.h index 516b9e8e9..bba584d7a 100644 --- a/src/core/receiver/gnss_block_factory.h +++ b/src/core/receiver/gnss_block_factory.h @@ -57,7 +57,7 @@ public: GNSSBlockFactory(); virtual ~GNSSBlockFactory(); std::unique_ptr GetSignalSource(std::shared_ptr configuration, - boost::shared_ptr queue, int ID = -1); + gr::msg_queue::sptr queue, int ID = -1); std::unique_ptr GetSignalConditioner(std::shared_ptr configuration, int ID = -1); @@ -66,7 +66,7 @@ public: std::unique_ptr GetObservables(std::shared_ptr configuration); std::unique_ptr>> GetChannels(std::shared_ptr configuration, - boost::shared_ptr queue); + gr::msg_queue::sptr queue); /* * \brief Returns the block with the required configuration and implementation @@ -74,29 +74,29 @@ public: std::unique_ptr GetBlock(std::shared_ptr configuration, std::string role, std::string implementation, unsigned int in_streams, unsigned int out_streams, - boost::shared_ptr queue = nullptr); + gr::msg_queue::sptr queue = nullptr); private: std::unique_ptr GetChannel_1C(std::shared_ptr configuration, std::string acq, std::string trk, std::string tlm, int channel, - boost::shared_ptr queue); + gr::msg_queue::sptr queue); std::unique_ptr GetChannel_2S(std::shared_ptr configuration, std::string acq, std::string trk, std::string tlm, int channel, - boost::shared_ptr queue); + gr::msg_queue::sptr queue); std::unique_ptr GetChannel_1B(std::shared_ptr configuration, std::string acq, std::string trk, std::string tlm, int channel, - boost::shared_ptr queue); + gr::msg_queue::sptr queue); std::unique_ptr GetChannel_5X(std::shared_ptr configuration, std::string acq, std::string trk, std::string tlm, int channel, - boost::shared_ptr queue); + gr::msg_queue::sptr queue); std::unique_ptr GetChannel_L5(std::shared_ptr configuration, - std::string acq, std::string trk, std::string tlm, int channel, - boost::shared_ptr queue); + std::string acq, std::string trk, std::string tlm, int channel, + gr::msg_queue::sptr queue); std::unique_ptr GetAcqBlock( std::shared_ptr configuration, From 3eafe2047aa2753d66d23bc4edbb1763eb9b74df Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Tue, 2 Jan 2018 12:29:15 +0100 Subject: [PATCH 14/96] Fix deadlock flowgraph --- src/algorithms/channel/libs/channel_fsm.cc | 19 +++++-------------- .../gps_l1_ca_telemetry_decoder_cc.cc | 2 +- src/core/receiver/gnss_flowgraph.cc | 18 +++++++----------- 3 files changed, 13 insertions(+), 26 deletions(-) diff --git a/src/algorithms/channel/libs/channel_fsm.cc b/src/algorithms/channel/libs/channel_fsm.cc index f147a57ef..daef2f9ad 100644 --- a/src/algorithms/channel/libs/channel_fsm.cc +++ b/src/algorithms/channel/libs/channel_fsm.cc @@ -62,10 +62,8 @@ struct channel_idle_fsm_S0: public sc::state public: // sc::transition(event, next state) typedef sc::transition reactions; - channel_idle_fsm_S0(my_context ctx) : my_base(ctx) - { - //std::cout << "Enter Channel_Idle_S0 " << std::endl; - } + channel_idle_fsm_S0(my_context ctx) : my_base(ctx){} + }; @@ -78,13 +76,10 @@ public: channel_acquiring_fsm_S1(my_context ctx) : my_base(ctx) { - //std::cout << "Enter Channel_Acq_S1 " << std::endl; context ().start_acquisition(); } - ~channel_acquiring_fsm_S1() - { - //std::cout << "Exit Channel_Acq_S1 " << std::endl; - } + ~channel_acquiring_fsm_S1(){} + }; @@ -96,13 +91,11 @@ public: channel_tracking_fsm_S2(my_context ctx) : my_base(ctx) { - //std::cout << "Enter Channel_tracking_S2 " << std::endl; context ().start_tracking(); } ~channel_tracking_fsm_S2() { - //std::cout << "Exit Channel_tracking_S2 " << std::endl; context ().notify_stop_tracking(); } @@ -117,10 +110,9 @@ public: channel_waiting_fsm_S3(my_context ctx) : my_base(ctx) { - //std::cout << "Enter Channel_waiting_S3 " << std::endl; context ().request_satellite(); } - // ~channel_waiting_fsm_S3(){} + ~channel_waiting_fsm_S3(){} }; @@ -148,7 +140,6 @@ ChannelFsm::ChannelFsm(std::shared_ptr acquisition) : void ChannelFsm::Event_start_acquisition() { this->process_event(Ev_channel_start_acquisition()); - //std::cout<<"Ev_channel_start_acquisition launched"<start_acquisition(); available_GNSS_signals_.pop_front(); - LOG(INFO) << "Channel " << i << " assigned to " << available_GNSS_signals_.front(); + LOG(INFO) << "Channel " << i << " assigned to " << channels_.at(i)->get_signal(); LOG(INFO) << "Channel " << i << " connected to observables and ready for acquisition"; } else @@ -367,12 +367,10 @@ bool GNSSFlowgraph::send_telemetry_msg(pmt::pmt_t msg) void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) { DLOG(INFO) << "Received " << what << " from " << who << ". Number of applied actions = " << applied_actions_; - VLOG(-100) << "Received " << what << " from " << who << ". Number of applied actions = " << applied_actions_; switch (what) { case 0: - DLOG(INFO) << "Channel " << who << " ACQ FAILED satellite " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); - VLOG(-100) << "Channel " << who << " ACQ FAILED satellite " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); + LOG(INFO) << "Channel " << who << " ACQ FAILED satellite " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); available_GNSS_signals_.push_back(channels_.at(who)->get_signal()); //TODO: Optimize the channel and signal matching! while ( channels_.at(who)->get_signal().get_signal_str().compare(available_GNSS_signals_.front().get_signal_str()) != 0 ) @@ -382,14 +380,12 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) } channels_.at(who)->set_signal(available_GNSS_signals_.front()); available_GNSS_signals_.pop_front(); - DLOG(INFO) << "Channel "<< who << " Starting acquisition " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); - VLOG(-100) << "Channel "<< who << " Starting acquisition " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); + LOG(INFO) << "Channel "<< who << " Starting acquisition " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); channels_.at(who)->start_acquisition(); break; case 1: - DLOG(INFO) << "Channel " << who << " ACQ SUCCESS satellite " << channels_.at(who)->get_signal().get_satellite(); - VLOG(-100) << "Channel " << who << " ACQ SUCCESS satellite " << channels_.at(who)->get_signal().get_satellite(); + LOG(INFO) << "Channel " << who << " ACQ SUCCESS satellite " << channels_.at(who)->get_signal().get_satellite(); channels_state_[who] = 2; acq_channels_count_--; for (unsigned int i = 0; i < channels_count_; i++) @@ -435,20 +431,20 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) break; case 2: - DLOG(INFO) << "Channel " << who << " TRK FAILED satellite " << channels_.at(who)->get_signal().get_satellite(); + LOG(INFO) << "Channel " << who << " TRK FAILED satellite " << channels_.at(who)->get_signal().get_satellite(); DLOG(INFO) << "Number of channels in acquisition = " << acq_channels_count_; - VLOG(-100) << "Channel " << who << " TRK FAILED satellite " << channels_.at(who)->get_signal().get_satellite(); - VLOG(-100) << "Number of channels in acquisition = " << acq_channels_count_; if (acq_channels_count_ < max_acq_channels_) { channels_state_[who] = 1; acq_channels_count_++; + LOG(INFO) << "Channel "<< who << " Starting acquisition " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); channels_.at(who)->start_acquisition(); } else { channels_state_[who] = 0; + LOG(INFO) << "Channel "<< who << " Idle state"; available_GNSS_signals_.push_back( channels_.at(who)->get_signal() ); } break; From b28c244df5cea69f9f1d8236271d14d7001979d9 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Wed, 3 Jan 2018 11:40:17 +0100 Subject: [PATCH 15/96] Debug log lines --- .../acquisition/gnuradio_blocks/pcps_acquisition_cc.cc | 4 +++- .../acquisition/gnuradio_blocks/pcps_acquisition_cc.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc index a0461f9c5..fdcd895b4 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc @@ -329,6 +329,7 @@ int pcps_acquisition_cc::general_work(int noutput_items, d_input_power = 0.0; d_test_statistics = 0.0; d_state = 1; + LOG(INFO) << "ACQ. general_work changing to state 1 (active)"; } d_sample_counter += d_fft_size * ninput_items[0]; // sample counter @@ -368,8 +369,9 @@ int pcps_acquisition_cc::general_work(int noutput_items, if( d_blocking ) { + LOG(INFO) << "ACQ. general_work waiting for acquisition_core"; d_cond.wait( lk, [&]{ return !this->d_new_data_available; } ); - + LOG(INFO) << "ACQ. Exiting general_work"; } } diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h index 486468379..1c6162492 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h @@ -60,6 +60,7 @@ #include #include #include "gnss_synchro.h" +#include class pcps_acquisition_cc; @@ -194,6 +195,7 @@ public: { gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler d_active = active; + LOG(INFO) << "ACQ RESET"; } /*! From 47c752c141ba95bb3c25c424c7d6f5c4c8ea1e5b Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Wed, 3 Jan 2018 12:44:58 +0100 Subject: [PATCH 16/96] More debug lines --- src/algorithms/channel/adapters/channel.cc | 1 + src/algorithms/channel/libs/channel_fsm.cc | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/algorithms/channel/adapters/channel.cc b/src/algorithms/channel/adapters/channel.cc index f66353f7e..ed8832c3f 100644 --- a/src/algorithms/channel/adapters/channel.cc +++ b/src/algorithms/channel/adapters/channel.cc @@ -202,5 +202,6 @@ void Channel::set_signal(const Gnss_Signal& gnss_signal) void Channel::start_acquisition() { channel_fsm_.Event_start_acquisition(); + LOG(INFO) << "Channel start_acquisition()"; } diff --git a/src/algorithms/channel/libs/channel_fsm.cc b/src/algorithms/channel/libs/channel_fsm.cc index daef2f9ad..0d5a1606e 100644 --- a/src/algorithms/channel/libs/channel_fsm.cc +++ b/src/algorithms/channel/libs/channel_fsm.cc @@ -140,6 +140,7 @@ ChannelFsm::ChannelFsm(std::shared_ptr acquisition) : void ChannelFsm::Event_start_acquisition() { this->process_event(Ev_channel_start_acquisition()); + LOG(INFO) << "FSM Event_start_acquisition" DLOG(INFO) << "CH = " << channel_ << ". Ev start acquisition"; } @@ -198,6 +199,7 @@ void ChannelFsm::set_channel(unsigned int channel) void ChannelFsm::start_acquisition() { acq_->reset(); + LOG(INFO) << "FSM. start_acquisition()"; } void ChannelFsm::start_tracking() From 3ddea680ad9ad9437e5420b3f2489c263e26154b Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Wed, 3 Jan 2018 12:48:04 +0100 Subject: [PATCH 17/96] debug1 --- src/algorithms/channel/libs/channel_fsm.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/algorithms/channel/libs/channel_fsm.cc b/src/algorithms/channel/libs/channel_fsm.cc index 0d5a1606e..dd3dbbd29 100644 --- a/src/algorithms/channel/libs/channel_fsm.cc +++ b/src/algorithms/channel/libs/channel_fsm.cc @@ -140,7 +140,7 @@ ChannelFsm::ChannelFsm(std::shared_ptr acquisition) : void ChannelFsm::Event_start_acquisition() { this->process_event(Ev_channel_start_acquisition()); - LOG(INFO) << "FSM Event_start_acquisition" + LOG(INFO) << "FSM Event_start_acquisition"; DLOG(INFO) << "CH = " << channel_ << ". Ev start acquisition"; } From 6dd3abfdea8e0bf6cbb2ef4fbf5000a95f015c04 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Wed, 3 Jan 2018 15:47:16 +0100 Subject: [PATCH 18/96] debug2 --- src/algorithms/channel/libs/channel_fsm.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/algorithms/channel/libs/channel_fsm.cc b/src/algorithms/channel/libs/channel_fsm.cc index dd3dbbd29..68e0798aa 100644 --- a/src/algorithms/channel/libs/channel_fsm.cc +++ b/src/algorithms/channel/libs/channel_fsm.cc @@ -139,6 +139,7 @@ ChannelFsm::ChannelFsm(std::shared_ptr acquisition) : void ChannelFsm::Event_start_acquisition() { + initiate(); this->process_event(Ev_channel_start_acquisition()); LOG(INFO) << "FSM Event_start_acquisition"; DLOG(INFO) << "CH = " << channel_ << ". Ev start acquisition"; From 540221e227d0cba95bed6a6f6d1504801e6d9b6d Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Thu, 4 Jan 2018 10:51:47 +0100 Subject: [PATCH 19/96] New Channel FSM --- src/algorithms/channel/adapters/channel.cc | 6 +-- src/algorithms/channel/libs/channel_fsm.cc | 49 ++++++++++++---------- src/algorithms/channel/libs/channel_fsm.h | 30 ++++++------- 3 files changed, 42 insertions(+), 43 deletions(-) diff --git a/src/algorithms/channel/adapters/channel.cc b/src/algorithms/channel/adapters/channel.cc index ed8832c3f..8689a8d94 100644 --- a/src/algorithms/channel/adapters/channel.cc +++ b/src/algorithms/channel/adapters/channel.cc @@ -103,10 +103,7 @@ Channel::Channel(ConfigurationInterface *configuration, unsigned int channel, // Destructor -Channel::~Channel() -{ - channel_fsm_.terminate(); -} +Channel::~Channel(){} void Channel::connect(gr::top_block_sptr top_block) @@ -139,7 +136,6 @@ void Channel::connect(gr::top_block_sptr top_block) top_block->msg_connect(nav_->get_left_block(), pmt::mp("preamble_timestamp_s"), trk_->get_right_block(), pmt::mp("preamble_timestamp_s")); DLOG(INFO) << "MSG FEEDBACK CHANNEL telemetry_decoder -> tracking"; - //std::cout<<"has port: "<get_right_block()->has_msg_port(pmt::mp("events"))<msg_connect(acq_->get_right_block(), pmt::mp("events"), channel_msg_rx, pmt::mp("events")); top_block->msg_connect(trk_->get_right_block(), pmt::mp("events"), channel_msg_rx, pmt::mp("events")); diff --git a/src/algorithms/channel/libs/channel_fsm.cc b/src/algorithms/channel/libs/channel_fsm.cc index 68e0798aa..e5cb34493 100644 --- a/src/algorithms/channel/libs/channel_fsm.cc +++ b/src/algorithms/channel/libs/channel_fsm.cc @@ -30,15 +30,10 @@ #include "channel_fsm.h" #include -#include -#include -#include -#include -#include #include #include "control_message_factory.h" - +/* struct Ev_channel_start_acquisition: sc::event {}; @@ -53,10 +48,9 @@ struct Ev_channel_failed_acquisition_no_repeat: sc::event {}; +*/ -//struct Ev_channel_failed_tracking_reacq: sc::event -//{}; - +/* struct channel_idle_fsm_S0: public sc::state { public: @@ -114,7 +108,7 @@ public: } ~channel_waiting_fsm_S3(){} }; - +*/ ChannelFsm::ChannelFsm() @@ -122,7 +116,7 @@ ChannelFsm::ChannelFsm() acq_ = nullptr; trk_ = nullptr; channel_ = 0; - initiate(); //start the FSM + d_state = 0; } @@ -132,51 +126,60 @@ ChannelFsm::ChannelFsm(std::shared_ptr acquisition) : { trk_ = nullptr; channel_ = 0; - initiate(); //start the FSM + d_state = 0; } void ChannelFsm::Event_start_acquisition() { - initiate(); - this->process_event(Ev_channel_start_acquisition()); + mx.lock(); + d_state = 1; + start_acquisition(); LOG(INFO) << "FSM Event_start_acquisition"; DLOG(INFO) << "CH = " << channel_ << ". Ev start acquisition"; + mx.unlock(); } void ChannelFsm::Event_valid_acquisition() { - this->process_event(Ev_channel_valid_acquisition()); + mx.lock(); + d_state = 2; + start_tracking(); DLOG(INFO) << "CH = " << channel_ << ". Ev valid acquisition"; + mx.unlock(); } void ChannelFsm::Event_failed_acquisition_repeat() { - this->process_event(Ev_channel_failed_acquisition_repeat()); + mx.lock(); + d_state = 1; + start_acquisition(); DLOG(INFO) << "CH = " << channel_ << ". Ev failed acquisition repeat"; + mx.unlock(); } void ChannelFsm::Event_failed_acquisition_no_repeat() { - this->process_event(Ev_channel_failed_acquisition_no_repeat()); + mx.lock(); + d_state = 3; + request_satellite(); DLOG(INFO) << "CH = " << channel_ << ". Ev failed acquisition no repeat"; + mx.unlock(); } -// Something is wrong here, we are using a memory after it ts freed void ChannelFsm::Event_failed_tracking_standby() { - this->process_event(Ev_channel_failed_tracking_standby()); + mx.lock(); + d_state = 0; + notify_stop_tracking(); DLOG(INFO) << "CH = " << channel_ << ". Ev failed tracking standby"; + mx.unlock(); } -//void ChannelFsm::Event_failed_tracking_reacq() { -// this->process_event(Ev_channel_failed_tracking_reacq()); -//} - void ChannelFsm::set_acquisition(std::shared_ptr acquisition) { acq_ = acquisition; diff --git a/src/algorithms/channel/libs/channel_fsm.h b/src/algorithms/channel/libs/channel_fsm.h index 997056723..02be4f1fc 100644 --- a/src/algorithms/channel/libs/channel_fsm.h +++ b/src/algorithms/channel/libs/channel_fsm.h @@ -1,12 +1,12 @@ /*! * \file channel_fsm.h - * \brief Interface of the State Machine for channel using boost::statechart - * \author Luis Esteve, 2011. luis(at)epsilon-formacion.com + * \brief Interface of the State Machine for channel + * \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es * * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -32,26 +32,23 @@ #ifndef GNSS_SDR_CHANNEL_FSM_H #define GNSS_SDR_CHANNEL_FSM_H - -#include +#include #include #include "acquisition_interface.h" #include "tracking_interface.h" #include "telemetry_decoder_interface.h" - -namespace sc = boost::statechart; -namespace mpl = boost::mpl; - +/* struct channel_idle_fsm_S0; struct channel_acquiring_fsm_S1; struct channel_tracking_fsm_S2; struct channel_waiting_fsm_S3; +*/ /*! * \brief This class implements a State Machine for channel using boost::statechart */ -class ChannelFsm: public sc::state_machine +class ChannelFsm { public: ChannelFsm(); @@ -61,24 +58,27 @@ public: void set_tracking(std::shared_ptr tracking); void set_queue(gr::msg_queue::sptr queue); void set_channel(unsigned int channel); - void start_acquisition(); - void start_tracking(); - void request_satellite(); - void notify_stop_tracking(); //FSM EVENTS void Event_start_acquisition(); void Event_valid_acquisition(); void Event_failed_acquisition_repeat(); void Event_failed_acquisition_no_repeat(); - //void Event_gps_failed_tracking_reacq(); void Event_failed_tracking_standby(); private: + + void start_acquisition(); + void start_tracking(); + void request_satellite(); + void notify_stop_tracking(); + std::shared_ptr acq_; std::shared_ptr trk_; gr::msg_queue::sptr queue_; unsigned int channel_; + unsigned int d_state; + std::mutex mx; }; #endif /*GNSS_SDR_CHANNEL_FSM_H*/ From bbf8587970d6bfd4ac2d0b9a7df238b80a441d98 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Thu, 4 Jan 2018 12:16:12 +0100 Subject: [PATCH 20/96] Clean code --- .../gnuradio_blocks/pcps_acquisition_cc.cc | 3 - .../gnuradio_blocks/pcps_acquisition_cc.h | 1 - src/algorithms/channel/libs/channel_fsm.cc | 85 +------------------ src/algorithms/channel/libs/channel_fsm.h | 9 +- src/core/receiver/gnss_flowgraph.cc | 23 ----- 5 files changed, 4 insertions(+), 117 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc index fdcd895b4..60ad2e82c 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc @@ -329,7 +329,6 @@ int pcps_acquisition_cc::general_work(int noutput_items, d_input_power = 0.0; d_test_statistics = 0.0; d_state = 1; - LOG(INFO) << "ACQ. general_work changing to state 1 (active)"; } d_sample_counter += d_fft_size * ninput_items[0]; // sample counter @@ -369,9 +368,7 @@ int pcps_acquisition_cc::general_work(int noutput_items, if( d_blocking ) { - LOG(INFO) << "ACQ. general_work waiting for acquisition_core"; d_cond.wait( lk, [&]{ return !this->d_new_data_available; } ); - LOG(INFO) << "ACQ. Exiting general_work"; } } diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h index 1c6162492..e33746f2b 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h @@ -195,7 +195,6 @@ public: { gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler d_active = active; - LOG(INFO) << "ACQ RESET"; } /*! diff --git a/src/algorithms/channel/libs/channel_fsm.cc b/src/algorithms/channel/libs/channel_fsm.cc index e5cb34493..75ac0e3da 100644 --- a/src/algorithms/channel/libs/channel_fsm.cc +++ b/src/algorithms/channel/libs/channel_fsm.cc @@ -1,11 +1,11 @@ /*! * \file channel_fsm.cc - * \brief Implementation of a State Machine for channel using boost::statechart - * \author Luis Esteve, 2011. luis(at)epsilon-formacion.com + * \brief Implementation of a State Machine for channel + * \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -33,83 +33,6 @@ #include #include "control_message_factory.h" -/* -struct Ev_channel_start_acquisition: sc::event -{}; - -struct Ev_channel_valid_acquisition: sc::event -{}; - -struct Ev_channel_failed_acquisition_repeat: sc::event -{}; - -struct Ev_channel_failed_acquisition_no_repeat: sc::event -{}; - -struct Ev_channel_failed_tracking_standby: sc::event -{}; -*/ - -/* -struct channel_idle_fsm_S0: public sc::state -{ -public: - // sc::transition(event, next state) - typedef sc::transition reactions; - channel_idle_fsm_S0(my_context ctx) : my_base(ctx){} - -}; - - -struct channel_acquiring_fsm_S1: public sc::state -{ -public: - typedef mpl::list, - sc::transition, - sc::transition > reactions; - - channel_acquiring_fsm_S1(my_context ctx) : my_base(ctx) - { - context ().start_acquisition(); - } - ~channel_acquiring_fsm_S1(){} - -}; - - -struct channel_tracking_fsm_S2: public sc::state -{ -public: - typedef mpl::list, - sc::transition> reactions; - - channel_tracking_fsm_S2(my_context ctx) : my_base(ctx) - { - context ().start_tracking(); - } - - ~channel_tracking_fsm_S2() - { - context ().notify_stop_tracking(); - } - -}; - - -struct channel_waiting_fsm_S3: public sc::state -{ -public: - typedef sc::transition reactions; - - channel_waiting_fsm_S3(my_context ctx) : my_base(ctx) - { - context ().request_satellite(); - } - ~channel_waiting_fsm_S3(){} -}; -*/ - ChannelFsm::ChannelFsm() { @@ -136,7 +59,6 @@ void ChannelFsm::Event_start_acquisition() mx.lock(); d_state = 1; start_acquisition(); - LOG(INFO) << "FSM Event_start_acquisition"; DLOG(INFO) << "CH = " << channel_ << ". Ev start acquisition"; mx.unlock(); } @@ -203,7 +125,6 @@ void ChannelFsm::set_channel(unsigned int channel) void ChannelFsm::start_acquisition() { acq_->reset(); - LOG(INFO) << "FSM. start_acquisition()"; } void ChannelFsm::start_tracking() diff --git a/src/algorithms/channel/libs/channel_fsm.h b/src/algorithms/channel/libs/channel_fsm.h index 02be4f1fc..55068dc85 100644 --- a/src/algorithms/channel/libs/channel_fsm.h +++ b/src/algorithms/channel/libs/channel_fsm.h @@ -38,15 +38,8 @@ #include "tracking_interface.h" #include "telemetry_decoder_interface.h" -/* -struct channel_idle_fsm_S0; -struct channel_acquiring_fsm_S1; -struct channel_tracking_fsm_S2; -struct channel_waiting_fsm_S3; -*/ - /*! - * \brief This class implements a State Machine for channel using boost::statechart + * \brief This class implements a State Machine for channel */ class ChannelFsm { diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index ed47b1a3e..c63b56435 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -405,29 +405,6 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) } DLOG(INFO) << "Channel " << i << " in state " << channels_state_[i]; } - /* - if (!available_GNSS_signals_.empty() && (acq_channels_count_ < max_acq_channels_)) - { - for (unsigned int i = 0; i < channels_count_; i++) - { - if (channels_state_[i] == 0) - { - channels_state_[i] = 1; - while (channels_.at(i)->get_signal().get_signal_str().compare(available_GNSS_signals_.front().get_signal_str()) != 0 ) - { - available_GNSS_signals_.push_back(available_GNSS_signals_.front()); - available_GNSS_signals_.pop_front(); - } - channels_.at(i)->set_signal(available_GNSS_signals_.front()); - available_GNSS_signals_.pop_front(); - acq_channels_count_++; - channels_.at(i)->start_acquisition(); - break; - } - DLOG(INFO) << "Channel " << i << " in state " << channels_state_[i]; - } - } - */ break; case 2: From 3a37345d4c4bf8269f192ff30de10d82529e8e2e Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Thu, 4 Jan 2018 12:33:13 +0100 Subject: [PATCH 21/96] Minor changes --- src/algorithms/channel/adapters/channel.cc | 2 +- src/algorithms/channel/libs/channel_fsm.cc | 3 ++- src/algorithms/channel/libs/channel_fsm.h | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/algorithms/channel/adapters/channel.cc b/src/algorithms/channel/adapters/channel.cc index 8689a8d94..f4c7fa77d 100644 --- a/src/algorithms/channel/adapters/channel.cc +++ b/src/algorithms/channel/adapters/channel.cc @@ -198,6 +198,6 @@ void Channel::set_signal(const Gnss_Signal& gnss_signal) void Channel::start_acquisition() { channel_fsm_.Event_start_acquisition(); - LOG(INFO) << "Channel start_acquisition()"; + DLOG(INFO) << "Channel start_acquisition()"; } diff --git a/src/algorithms/channel/libs/channel_fsm.cc b/src/algorithms/channel/libs/channel_fsm.cc index 75ac0e3da..f218981c6 100644 --- a/src/algorithms/channel/libs/channel_fsm.cc +++ b/src/algorithms/channel/libs/channel_fsm.cc @@ -1,7 +1,8 @@ /*! * \file channel_fsm.cc * \brief Implementation of a State Machine for channel - * \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es + * \authors Antonio Ramos, 2017. antonio.ramos(at)cttc.es + * Luis Esteve, 2011. luis(at)epsilon-formacion.com * * ------------------------------------------------------------------------- * diff --git a/src/algorithms/channel/libs/channel_fsm.h b/src/algorithms/channel/libs/channel_fsm.h index 55068dc85..5cca3b53e 100644 --- a/src/algorithms/channel/libs/channel_fsm.h +++ b/src/algorithms/channel/libs/channel_fsm.h @@ -1,8 +1,8 @@ /*! * \file channel_fsm.h * \brief Interface of the State Machine for channel - * \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es - * + * \authors Antonio Ramos, 2017. antonio.ramos(at)cttc.es + * Luis Esteve, 2011. luis(at)epsilon-formacion.com * * ------------------------------------------------------------------------- * From cfc0a4a498b856060933426d1408b96fe3ead774 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Fri, 5 Jan 2018 11:50:52 +0100 Subject: [PATCH 22/96] Clean flowgraph --- src/algorithms/channel/libs/channel_fsm.cc | 1 - src/algorithms/channel/libs/channel_fsm.h | 1 + src/core/receiver/gnss_flowgraph.cc | 41 +++++++++------------- src/core/receiver/gnss_flowgraph.h | 4 +-- 4 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/algorithms/channel/libs/channel_fsm.cc b/src/algorithms/channel/libs/channel_fsm.cc index f218981c6..499d55881 100644 --- a/src/algorithms/channel/libs/channel_fsm.cc +++ b/src/algorithms/channel/libs/channel_fsm.cc @@ -30,7 +30,6 @@ */ #include "channel_fsm.h" -#include #include #include "control_message_factory.h" diff --git a/src/algorithms/channel/libs/channel_fsm.h b/src/algorithms/channel/libs/channel_fsm.h index 5cca3b53e..29f741bfc 100644 --- a/src/algorithms/channel/libs/channel_fsm.h +++ b/src/algorithms/channel/libs/channel_fsm.h @@ -33,6 +33,7 @@ #define GNSS_SDR_CHANNEL_FSM_H #include +#include #include #include "acquisition_interface.h" #include "tracking_interface.h" diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index c63b56435..cf1226102 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -33,7 +33,6 @@ */ #include "gnss_flowgraph.h" -#include #include #include #include @@ -284,12 +283,7 @@ void GNSSFlowgraph::connect() } std::string gnss_signal = channels_.at(i)->get_signal().get_signal_str(); // use channel's implicit signal! - while (gnss_signal.compare(available_GNSS_signals_.front().get_signal_str()) != 0 ) - { - available_GNSS_signals_.push_back(available_GNSS_signals_.front()); - available_GNSS_signals_.pop_front(); - } - channels_.at(i)->set_signal(available_GNSS_signals_.front()); + channels_.at(i)->set_signal(search_next_signal(gnss_signal, false)); if (channels_state_[i] == 1) { @@ -370,17 +364,10 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) switch (what) { case 0: - LOG(INFO) << "Channel " << who << " ACQ FAILED satellite " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); + DLOG(INFO) << "Channel " << who << " ACQ FAILED satellite " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); available_GNSS_signals_.push_back(channels_.at(who)->get_signal()); - //TODO: Optimize the channel and signal matching! - while ( channels_.at(who)->get_signal().get_signal_str().compare(available_GNSS_signals_.front().get_signal_str()) != 0 ) - { - available_GNSS_signals_.push_back(available_GNSS_signals_.front()); - available_GNSS_signals_.pop_front(); - } - channels_.at(who)->set_signal(available_GNSS_signals_.front()); - available_GNSS_signals_.pop_front(); - LOG(INFO) << "Channel "<< who << " Starting acquisition " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); + channels_.at(who)->set_signal(search_next_signal(channels_.at(who)->get_signal().get_signal_str(), true)); + DLOG(INFO) << "Channel "<< who << " Starting acquisition " << channels_.at(who)->get_signal().get_satellite() << ", Signal " << channels_.at(who)->get_signal().get_signal_str(); channels_.at(who)->start_acquisition(); break; @@ -393,13 +380,7 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) if(!available_GNSS_signals_.empty() && (acq_channels_count_ < max_acq_channels_) && (channels_state_[i] == 0)) { channels_state_[i] = 1; - while (channels_.at(i)->get_signal().get_signal_str().compare(available_GNSS_signals_.front().get_signal_str()) != 0) - { - available_GNSS_signals_.push_back(available_GNSS_signals_.front()); - available_GNSS_signals_.pop_front(); - } - channels_.at(i)->set_signal(available_GNSS_signals_.front()); - available_GNSS_signals_.pop_front(); + channels_.at(i)->set_signal(search_next_signal(channels_.at(i)->get_signal().get_signal_str(), true)); acq_channels_count_++; channels_.at(i)->start_acquisition(); } @@ -761,3 +742,15 @@ void GNSSFlowgraph::set_channels_state() acq_channels_count_ = max_acq_channels_; DLOG(INFO) << acq_channels_count_ << " channels in acquisition state"; } + +Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool pop) +{ + while(searched_signal.compare(available_GNSS_signals_.front().get_signal_str()) != 0) + { + available_GNSS_signals_.push_back(available_GNSS_signals_.front()); + available_GNSS_signals_.pop_front(); + } + Gnss_Signal result = available_GNSS_signals_.front(); + if(pop){available_GNSS_signals_.pop_front();} + return result; +} diff --git a/src/core/receiver/gnss_flowgraph.h b/src/core/receiver/gnss_flowgraph.h index 4998d7170..abb4a6ef5 100644 --- a/src/core/receiver/gnss_flowgraph.h +++ b/src/core/receiver/gnss_flowgraph.h @@ -63,8 +63,7 @@ public: /*! * \brief Constructor that initializes the receiver flowgraph */ - GNSSFlowgraph(std::shared_ptr configuration, - boost::shared_ptr queue); + GNSSFlowgraph(std::shared_ptr configuration, gr::msg_queue::sptr queue); /*! * \brief Virtual destructor @@ -119,6 +118,7 @@ private: void set_signals_list(); void set_channels_state(); // Initializes the channels state (start acquisition or keep standby) // using the configuration parameters (number of channels and max channels in acquisition) + Gnss_Signal search_next_signal(std::string searched_signal, bool pop); bool connected_; bool running_; int sources_count_; From 74a1f76282fee1b42407820b3cf18deb09bf7052 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 8 Jan 2018 10:57:01 +0100 Subject: [PATCH 23/96] Avoid multithreading collision --- src/algorithms/channel/adapters/channel.cc | 8 +- src/algorithms/channel/libs/channel_fsm.cc | 103 ++++++++++++------ src/algorithms/channel/libs/channel_fsm.h | 10 +- .../channel/libs/channel_msg_receiver_cc.cc | 13 ++- 4 files changed, 90 insertions(+), 44 deletions(-) diff --git a/src/algorithms/channel/adapters/channel.cc b/src/algorithms/channel/adapters/channel.cc index f4c7fa77d..353f5a080 100644 --- a/src/algorithms/channel/adapters/channel.cc +++ b/src/algorithms/channel/adapters/channel.cc @@ -197,7 +197,13 @@ void Channel::set_signal(const Gnss_Signal& gnss_signal) void Channel::start_acquisition() { - channel_fsm_.Event_start_acquisition(); + bool result = false; + result = channel_fsm_.Event_start_acquisition(); + if(!result) + { + LOG(WARNING) << "Invalid channel event"; + return; + } DLOG(INFO) << "Channel start_acquisition()"; } diff --git a/src/algorithms/channel/libs/channel_fsm.cc b/src/algorithms/channel/libs/channel_fsm.cc index 499d55881..935c696ce 100644 --- a/src/algorithms/channel/libs/channel_fsm.cc +++ b/src/algorithms/channel/libs/channel_fsm.cc @@ -53,53 +53,88 @@ ChannelFsm::ChannelFsm(std::shared_ptr acquisition) : } - -void ChannelFsm::Event_start_acquisition() +bool ChannelFsm::Event_start_acquisition() { - mx.lock(); - d_state = 1; - start_acquisition(); - DLOG(INFO) << "CH = " << channel_ << ". Ev start acquisition"; - mx.unlock(); + std::lock_guard lk(mx); + if((d_state == 1) || (d_state == 2)) + { + return false; + } + else + { + d_state = 1; + start_acquisition(); + DLOG(INFO) << "CH = " << channel_ << ". Ev start acquisition"; + return true; + } } -void ChannelFsm::Event_valid_acquisition() +bool ChannelFsm::Event_valid_acquisition() { - mx.lock(); - d_state = 2; - start_tracking(); - DLOG(INFO) << "CH = " << channel_ << ". Ev valid acquisition"; - mx.unlock(); + std::lock_guard lk(mx); + if(d_state != 1) + { + return false; + } + else + { + d_state = 2; + start_tracking(); + DLOG(INFO) << "CH = " << channel_ << ". Ev valid acquisition"; + return true; + } } -void ChannelFsm::Event_failed_acquisition_repeat() +bool ChannelFsm::Event_failed_acquisition_repeat() { - mx.lock(); - d_state = 1; - start_acquisition(); - DLOG(INFO) << "CH = " << channel_ << ". Ev failed acquisition repeat"; - mx.unlock(); -} - -void ChannelFsm::Event_failed_acquisition_no_repeat() -{ - mx.lock(); - d_state = 3; - request_satellite(); - DLOG(INFO) << "CH = " << channel_ << ". Ev failed acquisition no repeat"; - mx.unlock(); + std::lock_guard lk(mx); + if(d_state != 1) + { + return false; + } + else + { + d_state = 1; + start_acquisition(); + DLOG(INFO) << "CH = " << channel_ << ". Ev failed acquisition repeat"; + return true; + } } -void ChannelFsm::Event_failed_tracking_standby() +bool ChannelFsm::Event_failed_acquisition_no_repeat() { - mx.lock(); - d_state = 0; - notify_stop_tracking(); - DLOG(INFO) << "CH = " << channel_ << ". Ev failed tracking standby"; - mx.unlock(); + std::lock_guard lk(mx); + if(d_state != 1) + { + return false; + } + else + { + d_state = 3; + request_satellite(); + DLOG(INFO) << "CH = " << channel_ << ". Ev failed acquisition no repeat"; + return true; + } +} + + +bool ChannelFsm::Event_failed_tracking_standby() +{ + std::lock_guard lk(mx); + if(d_state != 2) + { + return false; + } + else + { + d_state = 0; + notify_stop_tracking(); + DLOG(INFO) << "CH = " << channel_ << ". Ev failed tracking standby"; + return true; + } } void ChannelFsm::set_acquisition(std::shared_ptr acquisition) diff --git a/src/algorithms/channel/libs/channel_fsm.h b/src/algorithms/channel/libs/channel_fsm.h index 29f741bfc..23b92c394 100644 --- a/src/algorithms/channel/libs/channel_fsm.h +++ b/src/algorithms/channel/libs/channel_fsm.h @@ -54,11 +54,11 @@ public: void set_channel(unsigned int channel); //FSM EVENTS - void Event_start_acquisition(); - void Event_valid_acquisition(); - void Event_failed_acquisition_repeat(); - void Event_failed_acquisition_no_repeat(); - void Event_failed_tracking_standby(); + bool Event_start_acquisition(); + bool Event_valid_acquisition(); + bool Event_failed_acquisition_repeat(); + bool Event_failed_acquisition_no_repeat(); + bool Event_failed_tracking_standby(); private: diff --git a/src/algorithms/channel/libs/channel_msg_receiver_cc.cc b/src/algorithms/channel/libs/channel_msg_receiver_cc.cc index d22f2dd73..a88fc6d88 100644 --- a/src/algorithms/channel/libs/channel_msg_receiver_cc.cc +++ b/src/algorithms/channel/libs/channel_msg_receiver_cc.cc @@ -44,26 +44,27 @@ channel_msg_receiver_cc_sptr channel_msg_receiver_make_cc(ChannelFsm* channel_fs void channel_msg_receiver_cc::msg_handler_events(pmt::pmt_t msg) { + bool result = false; try { long int message = pmt::to_long(msg); switch (message) { case 1: //positive acquisition - d_channel_fsm->Event_valid_acquisition(); + result = d_channel_fsm->Event_valid_acquisition(); break; case 2: //negative acquisition if (d_repeat == true) { - d_channel_fsm->Event_failed_acquisition_repeat(); + result = d_channel_fsm->Event_failed_acquisition_repeat(); } else { - d_channel_fsm->Event_failed_acquisition_no_repeat(); + result = d_channel_fsm->Event_failed_acquisition_no_repeat(); } break; case 3: // tracking loss of lock event - d_channel_fsm->Event_failed_tracking_standby(); + result = d_channel_fsm->Event_failed_tracking_standby(); break; default: LOG(WARNING) << "Default case, invalid message."; @@ -74,6 +75,10 @@ void channel_msg_receiver_cc::msg_handler_events(pmt::pmt_t msg) { LOG(WARNING) << "msg_handler_telemetry Bad any cast!"; } + if(!result) + { + LOG(WARNING) << "msg_handler_telemetry invalid event"; + } } From 320b4e2d7bc9e7a9510df1458c14b1066399e1de Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 8 Jan 2018 12:03:32 +0100 Subject: [PATCH 24/96] Migrate channel_fsm pointer to std::shared_ptr --- src/algorithms/channel/adapters/channel.cc | 13 +++++++------ src/algorithms/channel/adapters/channel.h | 2 +- .../channel/libs/channel_msg_receiver_cc.cc | 4 ++-- .../channel/libs/channel_msg_receiver_cc.h | 8 ++++---- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/algorithms/channel/adapters/channel.cc b/src/algorithms/channel/adapters/channel.cc index 353f5a080..45e2c0833 100644 --- a/src/algorithms/channel/adapters/channel.cc +++ b/src/algorithms/channel/adapters/channel.cc @@ -50,6 +50,7 @@ Channel::Channel(ConfigurationInterface *configuration, unsigned int channel, implementation_ = implementation; channel_ = channel; queue_ = queue; + channel_fsm_ = std::make_shared(); flag_enable_fpga = configuration->property("Channel.enable_FPGA", false); acq_->set_channel(channel_); @@ -89,16 +90,16 @@ Channel::Channel(ConfigurationInterface *configuration, unsigned int channel, repeat_ = configuration->property("Acquisition_" + implementation_ + boost::lexical_cast(channel_) + ".repeat_satellite", false); DLOG(INFO) << "Channel " << channel_ << " satellite repeat = " << repeat_; - channel_fsm_.set_acquisition(acq_); - channel_fsm_.set_tracking(trk_); - channel_fsm_.set_channel(channel_); - channel_fsm_.set_queue(queue_); + channel_fsm_->set_acquisition(acq_); + channel_fsm_->set_tracking(trk_); + channel_fsm_->set_channel(channel_); + channel_fsm_->set_queue(queue_); connected_ = false; gnss_signal_ = Gnss_Signal(implementation_); - channel_msg_rx = channel_msg_receiver_make_cc(&channel_fsm_, repeat_); + channel_msg_rx = channel_msg_receiver_make_cc(channel_fsm_, repeat_); } @@ -198,7 +199,7 @@ void Channel::set_signal(const Gnss_Signal& gnss_signal) void Channel::start_acquisition() { bool result = false; - result = channel_fsm_.Event_start_acquisition(); + result = channel_fsm_->Event_start_acquisition(); if(!result) { LOG(WARNING) << "Invalid channel event"; diff --git a/src/algorithms/channel/adapters/channel.h b/src/algorithms/channel/adapters/channel.h index 8e0893843..405385814 100644 --- a/src/algorithms/channel/adapters/channel.h +++ b/src/algorithms/channel/adapters/channel.h @@ -104,7 +104,7 @@ private: Gnss_Signal gnss_signal_; bool connected_; bool repeat_; - ChannelFsm channel_fsm_; + std::shared_ptr channel_fsm_; gr::msg_queue::sptr queue_; }; diff --git a/src/algorithms/channel/libs/channel_msg_receiver_cc.cc b/src/algorithms/channel/libs/channel_msg_receiver_cc.cc index a88fc6d88..7a80cfceb 100644 --- a/src/algorithms/channel/libs/channel_msg_receiver_cc.cc +++ b/src/algorithms/channel/libs/channel_msg_receiver_cc.cc @@ -37,7 +37,7 @@ using google::LogMessage; -channel_msg_receiver_cc_sptr channel_msg_receiver_make_cc(ChannelFsm* channel_fsm, bool repeat) +channel_msg_receiver_cc_sptr channel_msg_receiver_make_cc(std::shared_ptr channel_fsm, bool repeat) { return channel_msg_receiver_cc_sptr(new channel_msg_receiver_cc(channel_fsm, repeat)); } @@ -82,7 +82,7 @@ void channel_msg_receiver_cc::msg_handler_events(pmt::pmt_t msg) } -channel_msg_receiver_cc::channel_msg_receiver_cc(ChannelFsm* channel_fsm, bool repeat) : +channel_msg_receiver_cc::channel_msg_receiver_cc(std::shared_ptr channel_fsm, bool repeat) : gr::block("channel_msg_receiver_cc", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) { this->message_port_register_in(pmt::mp("events")); diff --git a/src/algorithms/channel/libs/channel_msg_receiver_cc.h b/src/algorithms/channel/libs/channel_msg_receiver_cc.h index 195d41e7c..77a91379a 100644 --- a/src/algorithms/channel/libs/channel_msg_receiver_cc.h +++ b/src/algorithms/channel/libs/channel_msg_receiver_cc.h @@ -38,7 +38,7 @@ class channel_msg_receiver_cc; typedef boost::shared_ptr channel_msg_receiver_cc_sptr; -channel_msg_receiver_cc_sptr channel_msg_receiver_make_cc(ChannelFsm* channel_fsm, bool repeat); +channel_msg_receiver_cc_sptr channel_msg_receiver_make_cc(std::shared_ptr channel_fsm, bool repeat); /*! * \brief GNU Radio block that receives asynchronous channel messages from acquisition and tracking blocks @@ -46,11 +46,11 @@ channel_msg_receiver_cc_sptr channel_msg_receiver_make_cc(ChannelFsm* channel_fs class channel_msg_receiver_cc : public gr::block { private: - ChannelFsm* d_channel_fsm; + std::shared_ptr d_channel_fsm; bool d_repeat; // todo: change FSM to include repeat value - friend channel_msg_receiver_cc_sptr channel_msg_receiver_make_cc(ChannelFsm* channel_fsm, bool repeat); + friend channel_msg_receiver_cc_sptr channel_msg_receiver_make_cc(std::shared_ptr channel_fsm, bool repeat); void msg_handler_events(pmt::pmt_t msg); - channel_msg_receiver_cc(ChannelFsm* channel_fsm, bool repeat); + channel_msg_receiver_cc(std::shared_ptr channel_fsm, bool repeat); public: ~channel_msg_receiver_cc (); //!< Default destructor From a90edd025cf12d6eeff9492be177370a33b249dc Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 8 Jan 2018 12:54:35 +0100 Subject: [PATCH 25/96] Minor changes --- src/algorithms/channel/adapters/channel.cc | 2 ++ src/algorithms/channel/adapters/channel.h | 6 ++++-- src/algorithms/channel/libs/channel_fsm.cc | 4 ++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/algorithms/channel/adapters/channel.cc b/src/algorithms/channel/adapters/channel.cc index 45e2c0833..e66074b7a 100644 --- a/src/algorithms/channel/adapters/channel.cc +++ b/src/algorithms/channel/adapters/channel.cc @@ -184,6 +184,7 @@ gr::basic_block_sptr Channel::get_right_block() void Channel::set_signal(const Gnss_Signal& gnss_signal) { + std::lock_guard lk(mx); gnss_signal_ = gnss_signal; std::string str_aux = gnss_signal_.get_signal_str(); const char * str = str_aux.c_str(); // get a C style null terminated string @@ -198,6 +199,7 @@ void Channel::set_signal(const Gnss_Signal& gnss_signal) void Channel::start_acquisition() { + std::lock_guard lk(mx); bool result = false; result = channel_fsm_->Event_start_acquisition(); if(!result) diff --git a/src/algorithms/channel/adapters/channel.h b/src/algorithms/channel/adapters/channel.h index 405385814..8740b5ad9 100644 --- a/src/algorithms/channel/adapters/channel.h +++ b/src/algorithms/channel/adapters/channel.h @@ -37,6 +37,7 @@ #include #include +#include #include #include #include "channel_interface.h" @@ -63,8 +64,7 @@ public: Channel(ConfigurationInterface *configuration, unsigned int channel, std::shared_ptr pass_through, std::shared_ptr acq, std::shared_ptr trk, std::shared_ptr nav, - std::string role, std::string implementation, - boost::shared_ptr queue); + std::string role, std::string implementation, gr::msg_queue::sptr queue); //! Virtual destructor virtual ~Channel(); @@ -79,6 +79,7 @@ public: inline std::string implementation() override { return implementation_; } inline size_t item_size() override { return 0; } + inline Gnss_Signal get_signal() const override { return gnss_signal_; } void start_acquisition() override; //!< Start the State Machine @@ -106,6 +107,7 @@ private: bool repeat_; std::shared_ptr channel_fsm_; gr::msg_queue::sptr queue_; + std::mutex mx; }; #endif /*GNSS_SDR_CHANNEL_H_*/ diff --git a/src/algorithms/channel/libs/channel_fsm.cc b/src/algorithms/channel/libs/channel_fsm.cc index 935c696ce..b6f23cbeb 100644 --- a/src/algorithms/channel/libs/channel_fsm.cc +++ b/src/algorithms/channel/libs/channel_fsm.cc @@ -139,21 +139,25 @@ bool ChannelFsm::Event_failed_tracking_standby() void ChannelFsm::set_acquisition(std::shared_ptr acquisition) { + std::lock_guard lk(mx); acq_ = acquisition; } void ChannelFsm::set_tracking(std::shared_ptr tracking) { + std::lock_guard lk(mx); trk_ = tracking; } void ChannelFsm::set_queue(gr::msg_queue::sptr queue) { + std::lock_guard lk(mx); queue_ = queue; } void ChannelFsm::set_channel(unsigned int channel) { + std::lock_guard lk(mx); channel_ = channel; } From 188df6c5b8c425fe8a76a0649e6fc29161c78ef1 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Tue, 9 Jan 2018 16:43:38 +0100 Subject: [PATCH 26/96] Clean pcps acquisition --- .../gnuradio_blocks/pcps_acquisition_cc.cc | 387 +++++++----------- .../gnuradio_blocks/pcps_acquisition_cc.h | 22 +- 2 files changed, 149 insertions(+), 260 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc index a0461f9c5..df8ff2a1f 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc @@ -127,13 +127,9 @@ pcps_acquisition_cc::pcps_acquisition_cc( // For dumping samples into a file d_dump = dump; d_dump_filename = dump_filename; - d_gnss_synchro = 0; d_grid_doppler_wipeoffs = 0; - - d_done = false; d_blocking = blocking; - d_new_data_available = false; d_worker_active = false; d_data_buffer = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); } @@ -160,19 +156,6 @@ pcps_acquisition_cc::~pcps_acquisition_cc() { d_dump_file.close(); } - - // Let the worker thread know that we are done and then wait to join - if( d_worker_thread.joinable() ) - { - { - std::lock_guard lk( d_mutex ); - d_done = true; - d_cond.notify_one(); - } - - d_worker_thread.join(); - } - volk_gnsssdr_free( d_data_buffer ); } @@ -233,9 +216,6 @@ void pcps_acquisition_cc::init() int doppler = -static_cast(d_doppler_max) + d_doppler_step * doppler_index; update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_freq + doppler); } - - d_new_data_available = false; - d_done = false; d_worker_active = false; } @@ -253,6 +233,7 @@ void pcps_acquisition_cc::set_state(int state) d_mag = 0.0; d_input_power = 0.0; d_test_statistics = 0.0; + d_active = true; } else if (d_state == 0) {} @@ -299,7 +280,7 @@ void pcps_acquisition_cc::send_negative_acquisition() } -int pcps_acquisition_cc::general_work(int noutput_items, +int pcps_acquisition_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items __attribute__((unused))) { @@ -314,193 +295,157 @@ int pcps_acquisition_cc::general_work(int noutput_items, * 6. Declare positive or negative acquisition using a message port */ - switch (d_state) + gr::thread::scoped_lock lk(d_setlock); + if(!d_active || d_worker_active) + { + d_sample_counter += d_fft_size * ninput_items[0]; + consume_each(ninput_items[0]); + return 0; + } + + switch(d_state) { case 0: { - if (d_active) - { - //restart acquisition variables - d_gnss_synchro->Acq_delay_samples = 0.0; - d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; - d_well_count = 0; - d_mag = 0.0; - d_input_power = 0.0; - d_test_statistics = 0.0; - d_state = 1; - } - + //restart acquisition variables + d_gnss_synchro->Acq_delay_samples = 0.0; + d_gnss_synchro->Acq_doppler_hz = 0.0; + d_gnss_synchro->Acq_samplestamp_samples = 0; + d_well_count = 0; + d_mag = 0.0; + d_input_power = 0.0; + d_test_statistics = 0.0; + d_state = 1; d_sample_counter += d_fft_size * ninput_items[0]; // sample counter consume_each(ninput_items[0]); - break; } case 1: { - std::unique_lock lk( d_mutex ); - - int num_items_consumed = 1; - - if( d_worker_active ) + // Copy the data to the core and let it know that new data is available + memcpy(d_data_buffer, input_items[0], d_fft_size * sizeof(gr_complex)); + if(d_blocking) { - if( d_blocking ) - { - // Should never get here: - std::string msg = "pcps_acquisition_cc: Entered general work with worker active in blocking mode, should never happen"; - LOG(WARNING) << msg; - std::cout << msg << std::endl; - d_cond.wait( lk, [&]{ return !this->d_worker_active; } ); - } - else - { - num_items_consumed = ninput_items[0]; - d_sample_counter += d_fft_size * num_items_consumed; - } + lk.unlock(); + acquisition_core(); } else { - // Copy the data to the core and let it know that new data is available - memcpy( d_data_buffer, input_items[0], d_fft_size * sizeof( gr_complex ) ); - d_new_data_available = true; - d_cond.notify_one(); - - if( d_blocking ) - { - d_cond.wait( lk, [&]{ return !this->d_new_data_available; } ); - - } + gr::thread::thread d_worker(&pcps_acquisition_cc::acquisition_core, this); + d_worker_active = true; } - - consume_each(num_items_consumed); - + consume_each(1); break; - } // case 1, switch d_state - - } // switch d_state - - return noutput_items; + } + } + return 0; } void pcps_acquisition_cc::acquisition_core( void ) { - d_worker_active = false; - while( 1 ) + gr::thread::scoped_lock lk(d_setlock); + + unsigned long int sample_counter = d_sample_counter; // sample counter + // initialize acquisition algorithm + int doppler; + uint32_t indext = 0; + float magt = 0.0; + const gr_complex *in = d_data_buffer; //Get the input samples pointer + + int effective_fft_size = ( d_bit_transition_flag ? d_fft_size/2 : d_fft_size ); + + float fft_normalization_factor = static_cast(d_fft_size) * static_cast(d_fft_size); + + d_input_power = 0.0; + d_mag = 0.0; + d_well_count++; + + DLOG(INFO) << "Channel: " << d_channel + << " , doing acquisition of satellite: " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN + << " ,sample stamp: " << sample_counter << ", threshold: " + << d_threshold << ", doppler_max: " << d_doppler_max + << ", doppler_step: " << d_doppler_step + << ", use_CFAR_algorithm_flag: " << ( d_use_CFAR_algorithm_flag ? "true" : "false" ); + + lk.unlock(); + if (d_use_CFAR_algorithm_flag) { - std::unique_lock lk( d_mutex ); - d_cond.wait( lk, [&]{ return this->d_new_data_available or this->d_done; } ); - d_worker_active = !d_done; - unsigned long int sample_counter = d_sample_counter; // sample counter - lk.unlock(); + // 1- (optional) Compute the input signal power estimation + volk_32fc_magnitude_squared_32f(d_magnitude, in, d_fft_size); + volk_32f_accumulator_s32f(&d_input_power, d_magnitude, d_fft_size); + d_input_power /= static_cast(d_fft_size); + } + // 2- Doppler frequency search loop + for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) + { + // doppler search steps + doppler = -static_cast(d_doppler_max) + d_doppler_step * doppler_index; - if( d_done ) + volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index], d_fft_size); + + // 3- Perform the FFT-based convolution (parallel time search) + // Compute the FFT of the carrier wiped--off incoming signal + d_fft_if->execute(); + + // Multiply carrier wiped--off, Fourier transformed incoming signal + // with the local FFT'd code reference using SIMD operations with VOLK library + volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(), d_fft_if->get_outbuf(), d_fft_codes, d_fft_size); + + // compute the inverse FFT + d_ifft->execute(); + + // Search maximum + size_t offset = ( d_bit_transition_flag ? effective_fft_size : 0 ); + volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf() + offset, effective_fft_size); + volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude, effective_fft_size); + magt = d_magnitude[indext]; + + if (d_use_CFAR_algorithm_flag) { - break; + // Normalize the maximum value to correct the scale factor introduced by FFTW + magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor); } - - // initialize acquisition algorithm - int doppler; - uint32_t indext = 0; - float magt = 0.0; - const gr_complex *in = d_data_buffer; //Get the input samples pointer - - int effective_fft_size = ( d_bit_transition_flag ? d_fft_size/2 : d_fft_size ); - - float fft_normalization_factor = static_cast(d_fft_size) * static_cast(d_fft_size); - - d_input_power = 0.0; - d_mag = 0.0; - d_well_count++; - - DLOG(INFO) << "Channel: " << d_channel - << " , doing acquisition of satellite: " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN - << " ,sample stamp: " << sample_counter << ", threshold: " - << d_threshold << ", doppler_max: " << d_doppler_max - << ", doppler_step: " << d_doppler_step - << ", use_CFAR_algorithm_flag: " << ( d_use_CFAR_algorithm_flag ? "true" : "false" ); - - if (d_use_CFAR_algorithm_flag == true) + // 4- record the maximum peak and the associated synchronization parameters + if (d_mag < magt) { - // 1- (optional) Compute the input signal power estimation - volk_32fc_magnitude_squared_32f(d_magnitude, in, d_fft_size); - volk_32f_accumulator_s32f(&d_input_power, d_magnitude, d_fft_size); - d_input_power /= static_cast(d_fft_size); - } - // 2- Doppler frequency search loop - for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) - { - // doppler search steps - doppler = -static_cast(d_doppler_max) + d_doppler_step * doppler_index; + d_mag = magt; - volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, - d_grid_doppler_wipeoffs[doppler_index], d_fft_size); - - // 3- Perform the FFT-based convolution (parallel time search) - // Compute the FFT of the carrier wiped--off incoming signal - d_fft_if->execute(); - - // Multiply carrier wiped--off, Fourier transformed incoming signal - // with the local FFT'd code reference using SIMD operations with VOLK library - volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(), - d_fft_if->get_outbuf(), d_fft_codes, d_fft_size); - - // compute the inverse FFT - d_ifft->execute(); - - // Search maximum - size_t offset = ( d_bit_transition_flag ? effective_fft_size : 0 ); - volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf() + offset, effective_fft_size); - volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude, effective_fft_size); - magt = d_magnitude[indext]; - - if (d_use_CFAR_algorithm_flag == true) + if (!d_use_CFAR_algorithm_flag) { - // Normalize the maximum value to correct the scale factor introduced by FFTW - magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor); - } - // 4- record the maximum peak and the associated synchronization parameters - if (d_mag < magt) - { - d_mag = magt; - - if (d_use_CFAR_algorithm_flag == false) - { - // Search grid noise floor approximation for this doppler line - volk_32f_accumulator_s32f(&d_input_power, d_magnitude, effective_fft_size); - d_input_power = (d_input_power - d_mag) / (effective_fft_size - 1); - } - - // In case that d_bit_transition_flag = true, we compare the potentially - // new maximum test statistics (d_mag/d_input_power) with the value in - // d_test_statistics. When the second dwell is being processed, the value - // of d_mag/d_input_power could be lower than d_test_statistics (i.e, - // the maximum test statistics in the previous dwell is greater than - // current d_mag/d_input_power). Note that d_test_statistics is not - // restarted between consecutive dwells in multidwell operation. - - if (d_test_statistics < (d_mag / d_input_power) || !d_bit_transition_flag) - { - d_gnss_synchro->Acq_delay_samples = static_cast(indext % d_samples_per_code); - d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); - d_gnss_synchro->Acq_samplestamp_samples = sample_counter; - - // 5- Compute the test statistics and compare to the threshold - //d_test_statistics = 2 * d_fft_size * d_mag / d_input_power; - d_test_statistics = d_mag / d_input_power; - } + // Search grid noise floor approximation for this doppler line + volk_32f_accumulator_s32f(&d_input_power, d_magnitude, effective_fft_size); + d_input_power = (d_input_power - d_mag) / (effective_fft_size - 1); } - // Record results to file if required - if (d_dump) - { - std::stringstream filename; - std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write - filename.str(""); + // In case that d_bit_transition_flag = true, we compare the potentially + // new maximum test statistics (d_mag/d_input_power) with the value in + // d_test_statistics. When the second dwell is being processed, the value + // of d_mag/d_input_power could be lower than d_test_statistics (i.e, + // the maximum test statistics in the previous dwell is greater than + // current d_mag/d_input_power). Note that d_test_statistics is not + // restarted between consecutive dwells in multidwell operation. - boost::filesystem::path p = d_dump_filename; - filename << p.parent_path().string() + if (d_test_statistics < (d_mag / d_input_power) || !d_bit_transition_flag) + { + d_gnss_synchro->Acq_delay_samples = static_cast(indext % d_samples_per_code); + d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); + d_gnss_synchro->Acq_samplestamp_samples = sample_counter; + + // 5- Compute the test statistics and compare to the threshold + //d_test_statistics = 2 * d_fft_size * d_mag / d_input_power; + d_test_statistics = d_mag / d_input_power; + } + } + // Record results to file if required + if (d_dump) + { + std::stringstream filename; + std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write + filename.str(""); + boost::filesystem::path p = d_dump_filename; + filename << p.parent_path().string() << boost::filesystem::path::preferred_separator << p.stem().string() << "_" << d_gnss_synchro->System @@ -509,15 +454,32 @@ void pcps_acquisition_cc::acquisition_core( void ) << doppler << p.extension().string(); - DLOG(INFO) << "Writing ACQ out to " << filename.str(); + DLOG(INFO) << "Writing ACQ out to " << filename.str(); - d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary); - d_dump_file.write(reinterpret_cast(d_ifft->get_outbuf()), n); //write directly |abs(x)|^2 in this Doppler bin? - d_dump_file.close(); - } + d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary); + d_dump_file.write(reinterpret_cast(d_ifft->get_outbuf()), n); //write directly |abs(x)|^2 in this Doppler bin? + d_dump_file.close(); } - - if (!d_bit_transition_flag) + } + lk.lock(); + if (!d_bit_transition_flag) + { + if (d_test_statistics > d_threshold) + { + d_state = 0; // Positive acquisition + d_active = false; + send_positive_acquisition(); + } + else if (d_well_count == d_max_dwells) + { + d_state = 0; + d_active = false; + send_negative_acquisition(); + } + } + else + { + if (d_well_count == d_max_dwells) // d_max_dwells = 2 { if (d_test_statistics > d_threshold) { @@ -525,66 +487,13 @@ void pcps_acquisition_cc::acquisition_core( void ) d_active = false; send_positive_acquisition(); } - else if (d_well_count == d_max_dwells) + else { - d_state = 0; + d_state = 0; // Negative acquisition d_active = false; send_negative_acquisition(); } } - else - { - if (d_well_count == d_max_dwells) // d_max_dwells = 2 - { - if (d_test_statistics > d_threshold) - { - d_state = 0; // Positive acquisition - d_active = false; - send_positive_acquisition(); - } - else - { - d_state = 0; // Negative acquisition - d_active = false; - send_negative_acquisition(); - } - } - } - - lk.lock(); - d_worker_active = false; - d_new_data_available = false; - lk.unlock(); - d_cond.notify_one(); } -} - - -bool pcps_acquisition_cc::start( void ) -{ d_worker_active = false; - d_done = false; - - // Start the worker thread and wait for it to acknowledge: - d_worker_thread = std::move( std::thread( &pcps_acquisition_cc::acquisition_core, this ) ); - - return gr::block::start(); } - - -bool pcps_acquisition_cc::stop( void ) -{ - // Let the worker thread know that we are done and then wait to join - if( d_worker_thread.joinable() ) - { - { - std::lock_guard lk( d_mutex ); - d_done = true; - d_cond.notify_one(); - } - - d_worker_thread.join(); - } - return gr::block::stop(); -} - diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h index 486468379..3408a01f4 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h @@ -21,6 +21,7 @@ *
  • Luis Esteve, 2012. luis(at)epsilon-formacion.com *
  • Marc Molina, 2013. marc.molina.pena@gmail.com *
  • Cillian O'Driscoll, 2017. cillian(at)ieee.org + *
  • Antonio Ramos, 2017. antonio.ramos@cttc.es * * * ------------------------------------------------------------------------- @@ -53,9 +54,6 @@ #include #include -#include -#include -#include #include #include #include @@ -109,7 +107,6 @@ private: int d_samples_per_code; //unsigned int d_doppler_resolution; float d_threshold; - std::string d_satellite_str; unsigned int d_doppler_max; unsigned int d_doppler_step; unsigned int d_sampled_ms; @@ -137,16 +134,8 @@ private: bool d_dump; unsigned int d_channel; std::string d_dump_filename; - - std::thread d_worker_thread; - std::mutex d_mutex; - - std::condition_variable d_cond; - bool d_done; - bool d_new_data_available; bool d_worker_active; bool d_blocking; - gr_complex *d_data_buffer; public: @@ -251,15 +240,6 @@ public: gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); - /*! - * Called by the flowgraph when processing is about to start. - */ - bool start( void ); - - /*! - * Called by the flowgraph when processing is done. - */ - bool stop( void ); }; #endif /* GNSS_SDR_PCPS_ACQUISITION_CC_H_*/ From 2749d2518bf8caddd82a5c405f79fdec5f31d384 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Wed, 10 Jan 2018 11:08:06 +0100 Subject: [PATCH 27/96] Fix sample counting --- .../gnuradio_blocks/pcps_acquisition_cc.cc | 12 ++++++------ .../gnuradio_blocks/pcps_acquisition_cc.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc index df8ff2a1f..897532983 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.cc @@ -328,13 +328,14 @@ int pcps_acquisition_cc::general_work(int noutput_items __attribute__((unused)), if(d_blocking) { lk.unlock(); - acquisition_core(); + acquisition_core(d_sample_counter); } else { - gr::thread::thread d_worker(&pcps_acquisition_cc::acquisition_core, this); + gr::thread::thread d_worker(&pcps_acquisition_cc::acquisition_core, this, d_sample_counter); d_worker_active = true; } + d_sample_counter += d_fft_size; consume_each(1); break; } @@ -343,11 +344,10 @@ int pcps_acquisition_cc::general_work(int noutput_items __attribute__((unused)), } -void pcps_acquisition_cc::acquisition_core( void ) +void pcps_acquisition_cc::acquisition_core( unsigned long int samp_count ) { gr::thread::scoped_lock lk(d_setlock); - unsigned long int sample_counter = d_sample_counter; // sample counter // initialize acquisition algorithm int doppler; uint32_t indext = 0; @@ -364,7 +364,7 @@ void pcps_acquisition_cc::acquisition_core( void ) DLOG(INFO) << "Channel: " << d_channel << " , doing acquisition of satellite: " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN - << " ,sample stamp: " << sample_counter << ", threshold: " + << " ,sample stamp: " << samp_count << ", threshold: " << d_threshold << ", doppler_max: " << d_doppler_max << ", doppler_step: " << d_doppler_step << ", use_CFAR_algorithm_flag: " << ( d_use_CFAR_algorithm_flag ? "true" : "false" ); @@ -431,7 +431,7 @@ void pcps_acquisition_cc::acquisition_core( void ) { d_gnss_synchro->Acq_delay_samples = static_cast(indext % d_samples_per_code); d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); - d_gnss_synchro->Acq_samplestamp_samples = sample_counter; + d_gnss_synchro->Acq_samplestamp_samples = samp_count; // 5- Compute the test statistics and compare to the threshold //d_test_statistics = 2 * d_fft_size * d_mag / d_input_power; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h index 3408a01f4..bb3db1e43 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_cc.h @@ -97,7 +97,7 @@ private: void update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq); - void acquisition_core( void ); + void acquisition_core( unsigned long int samp_count ); void send_negative_acquisition(); void send_positive_acquisition(); From c46345692416d89c0f1e7c3a9f451f0d706af626 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Wed, 10 Jan 2018 11:30:16 +0100 Subject: [PATCH 28/96] Adding pilot signal acquisition option for Galileo E1 --- .../galileo_e1_pcps_ambiguous_acquisition.cc | 15 +++++++++++++-- .../galileo_e1_pcps_ambiguous_acquisition.h | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc index f9712824c..b0f64a25b 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc @@ -70,6 +70,7 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions + acquire_pilot_= configuration_->property(role + ".acquire_pilot", false); //will be true in future versions max_dwells_ = configuration_->property(role + ".max_dwells", 1); @@ -252,8 +253,18 @@ void GalileoE1PcpsAmbiguousAcquisition::set_local_code() std::complex * code = new std::complex[code_length_]; - galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, - cboc, gnss_synchro_->PRN, fs_in_, 0, false); + if (acquire_pilot_==true) + { + //set local signal generator to Galileo E1 pilot component (1C) + char pilot_signal[3]="1C"; + galileo_e1_code_gen_complex_sampled(code, pilot_signal, + cboc, gnss_synchro_->PRN, fs_in_, 0, false); + }else + { + galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, + cboc, gnss_synchro_->PRN, fs_in_, 0, false); + } + for (unsigned int i = 0; i < sampled_ms_ / 4; i++) { diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.h index da8d2e742..71727cecd 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.h @@ -146,6 +146,7 @@ private: unsigned int code_length_; bool bit_transition_flag_; bool use_CFAR_algorithm_flag_; + bool acquire_pilot_; unsigned int channel_; float threshold_; unsigned int doppler_max_; From 0e9113fdcb1b37fe90af46883eeddbe7070521aa Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Wed, 10 Jan 2018 12:37:13 +0100 Subject: [PATCH 29/96] Adding new advanced features to Galileo E1 tracking: Pilot tracking, Extended coherent correlation, narrow DLL/PLL bandwidth and narrow correlator spacings --- ...r_galileo_E1_extended_correlator_byte.conf | 269 ++++ .../galileo_e1_dll_pll_veml_tracking.cc | 34 +- .../galileo_e1_dll_pll_veml_tracking_cc.cc | 1212 +++++++++++------ .../galileo_e1_dll_pll_veml_tracking_cc.h | 84 +- src/core/system_parameters/Galileo_E1.h | 2 +- 5 files changed, 1200 insertions(+), 401 deletions(-) create mode 100644 conf/gnss-sdr_galileo_E1_extended_correlator_byte.conf diff --git a/conf/gnss-sdr_galileo_E1_extended_correlator_byte.conf b/conf/gnss-sdr_galileo_E1_extended_correlator_byte.conf new file mode 100644 index 000000000..fb6a08fc0 --- /dev/null +++ b/conf/gnss-sdr_galileo_E1_extended_correlator_byte.conf @@ -0,0 +1,269 @@ +; Default configuration file +; 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=20000000 + + +;######### SIGNAL_SOURCE CONFIG ############ +;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +SignalSource.implementation=File_Signal_Source + +;#filename: path to file with the captured GNSS signal samples to be processed +;SignalSource.filename=/home/javier/signals/L125_III1b_210s_L1_2msps.bin ; <- PUT YOUR FILE HERE + +SignalSource.filename=/media/javier/SISTEMA/signals/fraunhofer/L125_III1b_210s_L1.bin + +;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +SignalSource.item_type=byte + +;#sampling_frequency: Original Signal sampling frequency in [Hz] +SignalSource.sampling_frequency=20000000 + +;#freq: RF front-end center frequency in [Hz] +SignalSource.freq=1575420000 + +;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. +SignalSource.samples=0 + +;#repeat: Repeat the processing file. Disable this option in this version +SignalSource.repeat=false + +;#dump: Dump the Signal source data to a file. Disable this option in this version +SignalSource.dump=false + +SignalSource.dump_filename=../data/signal_source.dat + +;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. +; it helps to not overload the CPU, but the processing time will be longer. +SignalSource.enable_throttle_control=false + + +;######### SIGNAL_CONDITIONER CONFIG ############ +;## It holds blocks to change data type, filter and resample input data. + +;#implementation: Use [Pass_Through] or [Signal_Conditioner] +;#[Pass_Through] disables this block and the [DataTypeAdapter], [InputFilter] and [Resampler] blocks +;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks +SignalConditioner.implementation=Signal_Conditioner + +;######### DATA_TYPE_ADAPTER CONFIG ############ +;## Changes the type of input data. Please disable it in this version. +;#implementation: [Pass_Through] disables this block +DataTypeAdapter.implementation=Ibyte_To_Complex + +;######### INPUT_FILTER CONFIG ############ +;## Filter the input data. Can be combined with frequency translation for IF signals + +InputFilter.implementation=Pass_Through + + +;######### RESAMPLER CONFIG ############ +;## Resamples the input data. + +;#implementation: Use [Pass_Through] or [Direct_Resampler] +;#[Pass_Through] disables this block +;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation +;Resampler.implementation=Direct_Resampler +Resampler.implementation=Pass_Through + + +;######### CHANNELS GLOBAL CONFIG ############ +;#count: Number of available GPS satellite channels. +Channels_1C.count=0 +;#count: Number of available Galileo satellite channels. +Channels_1B.count=1 +;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver +Channels.in_acquisition=1 + +;#signal: +;#if the option is disabled by default is assigned "1C" GPS L1 C/A +Channel1.signal=1B +Channel2.signal=1B +Channel3.signal=1B +Channel4.signal=1B +Channel5.signal=1B +Channel6.signal=1B +Channel7.signal=1B +Channel8.signal=1B +Channel9.signal=1B +Channel10.signal=1B +Channel11.signal=1B +Channel12.signal=1B +Channel13.signal=1B +Channel14.signal=1B +Channel15.signal=1B + + +;######### GPS ACQUISITION CONFIG ############ + +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat +;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.item_type=gr_complex +;#if: Signal intermediate frequency in [Hz] +Acquisition_1C.if=0 +;#sampled_ms: Signal block duration for the acquisition signal detection [ms] +Acquisition_1C.sampled_ms=1 +;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +Acquisition_1C.use_CFAR_algorithm=false; +;#threshold: Acquisition threshold +Acquisition_1C.threshold=18 +;#doppler_max: Maximum expected Doppler shift [Hz] +Acquisition_1C.doppler_max=5000 +;#doppler_max: Doppler step in the grid search [Hz] +Acquisition_1C.doppler_step=500 + + +;######### GALILEO ACQUISITION CONFIG ############ + +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1B.dump=false +;#filename: Log path and filename +Acquisition_1B.dump_filename=../data/acq_dump.dat +;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1B.item_type=gr_complex +;#if: Signal intermediate frequency in [Hz] +Acquisition_1B.if=0 +;#sampled_ms: Signal block duration for the acquisition signal detection [ms] +Acquisition_1B.sampled_ms=4 +;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +Acquisition_1B.acquire_pilot=true +Acquisition_1B.use_CFAR_algorithm=false +;#threshold: Acquisition threshold +Acquisition_1B.threshold=21 +;#doppler_max: Maximum expected Doppler shift [Hz] +Acquisition_1B.doppler_max=5000 +;#doppler_max: Doppler step in the grid search [Hz] +Acquisition_1B.doppler_step=125 +Acquisition_1B.bit_transition_flag=true + +;######### TRACKING GPS CONFIG ############ + +;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] +Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking +;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +Tracking_1C.item_type=gr_complex + +;#sampling_frequency: Signal Intermediate Frequency in [Hz] +Tracking_1C.if=0 + +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1C.dump=false + +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1C.dump_filename=../data/epl_tracking_ch_ + +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=30.0; + +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=2.0; + +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; + +;######### TRACKING GALILEO CONFIG ############ + +;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] +Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking +;#item_type: Type and resolution for each of the signal samples. +Tracking_1B.item_type=gr_complex + +;#sampling_frequency: Signal Intermediate Frequency in [Hz] +Tracking_1B.if=0 + +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1B.dump=true + +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1B.dump_filename=../data/veml_tracking_ch_ + +Tracking_1B.track_pilot=true + +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1B.pll_bw_hz=4.0; + +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1B.dll_bw_hz=0.5; + +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1B.pll_bw_narrow_hz=2.0; + +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1B.dll_bw_narrow_hz=0.25; + +Tracking_1B.extend_correlation_symbols=4; + +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1B.order=3; + +;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo +Tracking_1B.early_late_space_chips=0.15; + +;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] +Tracking_1B.very_early_late_space_chips=0.6; + +;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo +Tracking_1B.early_late_space_narrow_chips=0.06; + +;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] +Tracking_1B.very_early_late_space_narrow_chips=0.25; + + + +;######### TELEMETRY DECODER GPS CONFIG ############ +;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A +TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder +TelemetryDecoder_1C.dump=false +;#decimation factor +TelemetryDecoder_1C.decimation_factor=4; + +;######### TELEMETRY DECODER GALILEO CONFIG ############ +;#implementation: Use [Galileo_E1B_Telemetry_Decoder] for Galileo E1B +TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder +TelemetryDecoder_1B.dump=false + +;######### OBSERVABLES CONFIG ############ +;#implementation: +Observables.implementation=Hybrid_Observables + +;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] +Observables.dump=false + +;#dump_filename: Log path and filename. +Observables.dump_filename=./observables.dat + + +;######### PVT CONFIG ############ +;#implementation: Position Velocity and Time (PVT) implementation: +PVT.implementation=RTKLIB_PVT + +PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic +PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX +PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad + +;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms] +PVT.output_rate_ms=100; + +;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms. +PVT.display_rate_ms=500; + +;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] +PVT.dump=false + +PVT.flag_rtcm_server=false +PVT.flag_rtcm_tty_port=false +PVT.rtcm_dump_devname=/dev/pts/1 + +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc index c3a37b548..b47e26a68 100755 --- a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc @@ -57,19 +57,31 @@ GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( std::string item_type; std::string default_item_type = "gr_complex"; float pll_bw_hz; + float pll_bw_narrow_hz; float dll_bw_hz; + float dll_bw_narrow_hz; float early_late_space_chips; float very_early_late_space_chips; + float early_late_space_narrow_chips; + float very_early_late_space_narrow_chips; item_type = configuration->property(role + ".item_type", default_item_type); int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); f_if = configuration->property(role + ".if", 0); dump = configuration->property(role + ".dump", false); - pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); - dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); + pll_bw_hz = configuration->property(role + ".pll_bw_hz", 5.0); + dll_bw_hz = configuration->property(role + ".dll_bw_hz", 0.5); + pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 2.0); + dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 0.25); + int extend_correlation_symbols; + extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1); early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.15); very_early_late_space_chips = configuration->property(role + ".very_early_late_space_chips", 0.6); + early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.15); + very_early_late_space_narrow_chips = configuration->property(role + ".very_early_late_space_narrow_chips", 0.6); + + bool track_pilot=configuration->property(role + ".track_pilot", false); std::string default_dump_filename = "./track_ch"; dump_filename = configuration->property(role + ".dump_filename", @@ -88,8 +100,24 @@ GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( dump_filename, pll_bw_hz, dll_bw_hz, + pll_bw_narrow_hz, + dll_bw_narrow_hz, early_late_space_chips, - very_early_late_space_chips); + very_early_late_space_chips, + early_late_space_narrow_chips, + very_early_late_space_narrow_chips, + extend_correlation_symbols, + track_pilot); +// tracking_ = galileo_e1_dll_pll_veml_make_tracking_cc( +// f_if, +// fs_in, +// vector_length, +// dump, +// dump_filename, +// pll_bw_hz, +// dll_bw_hz, +// early_late_space_chips, +// very_early_late_space_chips); } else { diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc index 9250de398..a21865500 100755 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc @@ -72,21 +72,40 @@ galileo_e1_dll_pll_veml_make_tracking_cc( std::string dump_filename, float pll_bw_hz, float dll_bw_hz, + float pll_bw_narrow_hz, + float dll_bw_narrow_hz, float early_late_space_chips, - float very_early_late_space_chips) + float very_early_late_space_chips, + float early_late_space_narrow_chips, + float very_early_late_space_narrow_chips, + int extend_correlation_symbols, + bool track_pilot) { return galileo_e1_dll_pll_veml_tracking_cc_sptr(new galileo_e1_dll_pll_veml_tracking_cc(if_freq, - fs_in, vector_length, dump, dump_filename, pll_bw_hz, dll_bw_hz, early_late_space_chips, very_early_late_space_chips)); + fs_in, + vector_length, + dump, + dump_filename, + pll_bw_hz, + dll_bw_hz, + pll_bw_narrow_hz, + dll_bw_narrow_hz, + early_late_space_chips, + very_early_late_space_chips, + early_late_space_narrow_chips, + very_early_late_space_narrow_chips, + extend_correlation_symbols, + track_pilot)); } void galileo_e1_dll_pll_veml_tracking_cc::forecast (int noutput_items, - gr_vector_int &ninput_items_required) + gr_vector_int &ninput_items_required) { if (noutput_items != 0) - { - ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call - } + { + ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call + } } @@ -98,10 +117,16 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc( std::string dump_filename, float pll_bw_hz, float dll_bw_hz, + float pll_bw_narrow_hz, + float dll_bw_narrow_hz, float early_late_space_chips, - float very_early_late_space_chips): - gr::block("galileo_e1_dll_pll_veml_tracking_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) + float very_early_late_space_chips, + float early_late_space_narrow_chips, + float very_early_late_space_narrow_chips, + int extend_correlation_symbols, + bool track_pilot): + gr::block("galileo_e1_dll_pll_veml_tracking_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { // Telemetry bit synchronization message port input this->message_port_register_in(pmt::mp("preamble_timestamp_s")); @@ -121,24 +146,31 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc( // Initialize tracking ========================================== // Set bandwidth of code and carrier loop filters - d_code_loop_filter.set_DLL_BW(dll_bw_hz); - d_carrier_loop_filter.set_PLL_BW(pll_bw_hz); + d_dll_bw_hz=dll_bw_hz; + d_pll_bw_hz=pll_bw_hz; + d_dll_bw_narrow_hz=dll_bw_narrow_hz; + d_pll_bw_narrow_hz=pll_bw_narrow_hz; + + d_code_loop_filter.set_DLL_BW(d_dll_bw_hz); + d_carrier_loop_filter.set_PLL_BW(d_pll_bw_hz); // Correlator spacing d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips) d_very_early_late_spc_chips = very_early_late_space_chips; // Define very-early-late offset (in chips) + d_early_late_spc_narrow_chips = early_late_space_narrow_chips; // Define narrow early-late offset (in chips) + d_very_early_late_spc_narrow_chips = very_early_late_space_narrow_chips; // Define narrow very-early-late offset (in chips) // Initialization of local code replica // Get space for a vector with the sinboc(1,1) replica sampled 2x/chip - d_ca_code = static_cast(volk_gnsssdr_malloc((2 * Galileo_E1_B_CODE_LENGTH_CHIPS) * sizeof(float), volk_gnsssdr_get_alignment())); + d_tracking_code = static_cast(volk_gnsssdr_malloc((2 * Galileo_E1_B_CODE_LENGTH_CHIPS) * sizeof(float), volk_gnsssdr_get_alignment())); // correlator outputs (scalar) d_n_correlator_taps = 5; // Very-Early, Early, Prompt, Late, Very-Late d_correlator_outs = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment())); for (int n = 0; n < d_n_correlator_taps; n++) - { - d_correlator_outs[n] = gr_complex(0,0); - } + { + d_correlator_outs[n] = gr_complex(0,0); + } // map memory pointers of correlator outputs d_Very_Early = &d_correlator_outs[0]; d_Early = &d_correlator_outs[1]; @@ -155,9 +187,32 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc( d_local_code_shift_chips[4] = d_very_early_late_spc_chips; d_correlation_length_samples = d_vector_length; - multicorrelator_cpu.init(2 * d_correlation_length_samples, d_n_correlator_taps); + d_extend_correlation_symbols=extend_correlation_symbols; + // Enable Data component prompt correlator (slave to Pilot prompt) if tracking uses Pilot signal + d_track_pilot=track_pilot; + if (d_track_pilot) + { + //extended integration control + if (d_extend_correlation_symbols>1) + { + d_enable_extended_integration=true; + }else{ + d_enable_extended_integration=false; + } + //Extra correlator for the data component + d_local_code_data_shift_chips=static_cast(volk_gnsssdr_malloc(sizeof(float), volk_gnsssdr_get_alignment())); + d_local_code_data_shift_chips[0]=0.0; + correlator_data_cpu.init(2 * d_correlation_length_samples, 1); + d_Prompt_Data = static_cast(volk_gnsssdr_malloc(sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_Prompt_Data[0] = gr_complex(0,0); + d_data_code = static_cast(volk_gnsssdr_malloc((2 * Galileo_E1_B_CODE_LENGTH_CHIPS) * sizeof(float), volk_gnsssdr_get_alignment())); + }else{ + // Disable extended integration if data component tracking is selected + d_enable_extended_integration=false; + } + //--- Initializations ------------------------------ // Initial code frequency basis of NCO d_code_freq_chips = static_cast(Galileo_E1_CODE_CHIP_RATE_HZ); @@ -171,9 +226,6 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc( //d_sample_counter_seconds = 0; d_acq_sample_stamp = 0; - d_enable_tracking = false; - d_pull_in = false; - d_current_prn_length_samples = static_cast(d_vector_length); // CN0 estimation and lock detector buffers @@ -185,11 +237,8 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc( d_carrier_lock_threshold = CARRIER_LOCK_THRESHOLD; systemName["E"] = std::string("Galileo"); - *d_Very_Early = gr_complex(0,0); - *d_Early = gr_complex(0,0); - *d_Prompt = gr_complex(0,0); - *d_Late = gr_complex(0,0); - *d_Very_Late = gr_complex(0,0); + + clear_tracking_vars(); d_acquisition_gnss_synchro = 0; d_channel = 0; @@ -197,106 +246,391 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc( d_acq_carrier_doppler_hz = 0.0; d_carrier_doppler_hz = 0.0; d_acc_carrier_phase_rad = 0.0; - d_acc_code_phase_secs = 0.0; + + d_state=0;// intial state: stanby } void galileo_e1_dll_pll_veml_tracking_cc::start_tracking() { + /* + * correct the code phase according to the delay between acq and trk + */ d_acq_code_phase_samples = d_acquisition_gnss_synchro->Acq_delay_samples; d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; + long int acq_trk_diff_samples; + double acq_trk_diff_seconds; + acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; + DLOG(INFO) << "Number of samples between Acquisition and Tracking = " << acq_trk_diff_samples; + acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in); + // Doppler effect + // Fd=(C/(C+Vr))*F + double radial_velocity = (Galileo_E1_FREQ_HZ + d_acq_carrier_doppler_hz) / Galileo_E1_FREQ_HZ; + // new chip and prn sequence periods based on acq Doppler + double T_chip_mod_seconds; + double T_prn_mod_seconds; + double T_prn_mod_samples; + d_code_freq_chips = radial_velocity * Galileo_E1_CODE_CHIP_RATE_HZ; + d_code_phase_step_chips = static_cast(d_code_freq_chips) / static_cast(d_fs_in); + T_chip_mod_seconds = 1/d_code_freq_chips; + T_prn_mod_seconds = T_chip_mod_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS; + T_prn_mod_samples = T_prn_mod_seconds * static_cast(d_fs_in); + + d_current_prn_length_samples = round(T_prn_mod_samples); + + double T_prn_true_seconds = Galileo_E1_B_CODE_LENGTH_CHIPS / Galileo_E1_CODE_CHIP_RATE_HZ; + double T_prn_true_samples = T_prn_true_seconds * static_cast(d_fs_in); + double T_prn_diff_seconds = T_prn_true_seconds - T_prn_mod_seconds; + double N_prn_diff = acq_trk_diff_seconds / T_prn_true_seconds; + double corrected_acq_phase_samples, delay_correction_samples; + corrected_acq_phase_samples = fmod((d_acq_code_phase_samples + T_prn_diff_seconds * N_prn_diff * static_cast(d_fs_in)), T_prn_true_samples); + if (corrected_acq_phase_samples < 0) + { + corrected_acq_phase_samples = T_prn_mod_samples + corrected_acq_phase_samples; + } + delay_correction_samples = d_acq_code_phase_samples - corrected_acq_phase_samples; + + d_acq_code_phase_samples = corrected_acq_phase_samples; + + d_carrier_doppler_hz = d_acq_carrier_doppler_hz; + d_carrier_phase_step_rad = GALILEO_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); + // DLL/PLL filter initialization d_carrier_loop_filter.initialize(); // initialize the carrier filter d_code_loop_filter.initialize(); // initialize the code filter - // generate local reference ALWAYS starting at chip 1 (2 samples per chip) - galileo_e1_code_gen_float_sampled(d_ca_code, - d_acquisition_gnss_synchro->Signal, - false, - d_acquisition_gnss_synchro->PRN, - 2 * Galileo_E1_CODE_CHIP_RATE_HZ, - 0); - multicorrelator_cpu.set_local_code_and_taps(static_cast(2 * Galileo_E1_B_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); + if (d_track_pilot) + { + char pilot_signal[3]="1C"; + galileo_e1_code_gen_float_sampled(d_tracking_code, + pilot_signal, + false, + d_acquisition_gnss_synchro->PRN, + Galileo_E1_CODE_CHIP_RATE_HZ, + 0); + galileo_e1_code_gen_float_sampled(d_data_code, + d_acquisition_gnss_synchro->Signal, + false, + d_acquisition_gnss_synchro->PRN, + Galileo_E1_CODE_CHIP_RATE_HZ, + 0); + d_Prompt_Data[0]=gr_complex(0,0); //clean data correlator output + correlator_data_cpu.set_local_code_and_taps(static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS), + d_data_code, + d_local_code_shift_chips); + }else{ + galileo_e1_code_gen_float_sampled(d_tracking_code, + d_acquisition_gnss_synchro->Signal, + false, + d_acquisition_gnss_synchro->PRN, + Galileo_E1_CODE_CHIP_RATE_HZ, + 0); + } + + multicorrelator_cpu.set_local_code_and_taps(static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS), d_tracking_code, d_local_code_shift_chips); for (int n = 0; n < d_n_correlator_taps; n++) - { - d_correlator_outs[n] = gr_complex(0,0); - } + { + d_correlator_outs[n] = gr_complex(0,0); + } d_carrier_lock_fail_counter = 0; - d_rem_code_phase_samples = 0.0; + d_rem_code_phase_samples = 0; d_rem_carr_phase_rad = 0.0; + d_rem_code_phase_chips = 0.0; d_acc_carrier_phase_rad = 0.0; - d_acc_code_phase_secs = 0.0; - d_carrier_doppler_hz = d_acq_carrier_doppler_hz; - d_current_prn_length_samples = d_vector_length; + d_code_phase_samples = d_acq_code_phase_samples; std::string sys_ = &d_acquisition_gnss_synchro->System; - sys = sys_.substr(0, 1); + sys = sys_.substr(0,1); // DEBUG OUTPUT std::cout << "Tracking of Galileo E1 signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl; LOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel; - // enable tracking - d_pull_in = true; - d_enable_tracking = true; + // enable tracking pull-in + d_state=1; LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz - << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples; + << " Code Phase correction [samples]=" << delay_correction_samples + << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples; + + } galileo_e1_dll_pll_veml_tracking_cc::~galileo_e1_dll_pll_veml_tracking_cc() { if (d_dump_file.is_open()) + { + try { - try - { - d_dump_file.close(); - } - catch(const std::exception & ex) - { - LOG(WARNING) << "Exception in destructor " << ex.what(); - } + d_dump_file.close(); } + catch(const std::exception & ex) + { + LOG(WARNING) << "Exception in destructor " << ex.what(); + } + } if(d_dump) + { + if(d_channel == 0) { - if(d_channel == 0) - { - std::cout << "Writing .mat files ..."; - } - galileo_e1_dll_pll_veml_tracking_cc::save_matfile(); - if(d_channel == 0) - { - std::cout << " done." << std::endl; - } + std::cout << "Writing .mat files ..."; } + galileo_e1_dll_pll_veml_tracking_cc::save_matfile(); + if(d_channel == 0) + { + std::cout << " done." << std::endl; + } + } try { - volk_gnsssdr_free(d_local_code_shift_chips); - volk_gnsssdr_free(d_correlator_outs); - volk_gnsssdr_free(d_ca_code); - delete[] d_Prompt_buffer; - multicorrelator_cpu.free(); + volk_gnsssdr_free(d_local_code_shift_chips); + volk_gnsssdr_free(d_correlator_outs); + volk_gnsssdr_free(d_tracking_code); + if (d_track_pilot) + { + volk_gnsssdr_free(d_Prompt_Data); + volk_gnsssdr_free(d_data_code); + volk_gnsssdr_free(d_local_code_data_shift_chips); + correlator_data_cpu.free(); + } + delete[] d_Prompt_buffer; + multicorrelator_cpu.free(); } catch(const std::exception & ex) { - LOG(WARNING) << "Exception in destructor " << ex.what(); + LOG(WARNING) << "Exception in destructor " << ex.what(); } } - -int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), - gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) +bool galileo_e1_dll_pll_veml_tracking_cc::acquire_secondary() +{ + //******* preamble correlation ******** + int corr_value=0; + for (unsigned int i = 0; i < Galileo_E1_C_SECONDARY_CODE_LENGTH; i++) + { + if (d_Prompt_buffer_deque.at(i).real() < 0) // symbols clipping + { + if (Galileo_E1_C_SECONDARY_CODE.at(i) == '0') + { + corr_value++; + } + else + { + corr_value--; + } + } + else + { + if (Galileo_E1_C_SECONDARY_CODE.at(i) == '0') + { + corr_value--; + } + else + { + corr_value++; + } + } + } + + if (abs(corr_value) == Galileo_E1_C_SECONDARY_CODE_LENGTH) + { + return true; + }else + { + return false; + } +} + +bool galileo_e1_dll_pll_veml_tracking_cc::cn0_and_tracking_lock_status() +{ + // ####### CN0 ESTIMATION AND LOCK DETECTORS ###### + if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES) + { + // fill buffer with prompt correlator output values + d_Prompt_buffer[d_cn0_estimation_counter] = d_P_accu; + d_cn0_estimation_counter++; + return true; + } + else + { + d_cn0_estimation_counter = 0; + // Code lock indicator + d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, Galileo_E1_B_CODE_LENGTH_CHIPS); + // Carrier lock indicator + d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES); + // Loss of lock detection + if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < MINIMUM_VALID_CN0) + { + d_carrier_lock_fail_counter++; + } + else + { + if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--; + } + if (d_carrier_lock_fail_counter > MAXIMUM_LOCK_FAIL_COUNTER) + { + std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; + LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; + this->message_port_pub(pmt::mp("events"), pmt::from_long(3));//3 -> loss of lock + d_carrier_lock_fail_counter = 0; + return false; + }else{ + return true; + } + } +} +// correlation requires: +// - updated remnant carrier phase in radians (rem_carr_phase_rad) +// - updated remnant code phase in samples (d_rem_code_phase_samples) +// - d_code_freq_chips +// - d_carrier_doppler_hz +void galileo_e1_dll_pll_veml_tracking_cc::do_correlation_step(const gr_complex* input_samples) +{ + // ################# CARRIER WIPEOFF AND CORRELATORS ############################## + // perform carrier wipe-off and compute Early, Prompt and Late correlation + multicorrelator_cpu.set_input_output_vectors(d_correlator_outs,input_samples); + multicorrelator_cpu.Carrier_wipeoff_multicorrelator_resampler( + d_rem_carr_phase_rad, + d_carrier_phase_step_rad, + d_rem_code_phase_chips, + d_code_phase_step_chips, + d_correlation_length_samples); + + // DATA CORRELATOR (if tracking tracks the pilot signal) + if (d_track_pilot) + { + correlator_data_cpu.set_input_output_vectors(d_Prompt_Data,input_samples); + correlator_data_cpu.Carrier_wipeoff_multicorrelator_resampler( + d_rem_carr_phase_rad, + d_carrier_phase_step_rad, + d_rem_code_phase_chips, + d_code_phase_step_chips, + d_correlation_length_samples); + } +} + +void galileo_e1_dll_pll_veml_tracking_cc::run_dll_pll(bool disable_costas_loop) +{ + // ################## PLL ########################################################## + // PLL discriminator + if (disable_costas_loop==true) + { + //Secondary code acquired. No symbols transition should be present in the signal + d_carr_error_hz = pll_four_quadrant_atan(d_P_accu) / GALILEO_TWO_PI; + }else{ + // Costas loop discriminator, insensitive to 180 deg phase transitions + d_carr_error_hz = pll_cloop_two_quadrant_atan(d_P_accu) / GALILEO_TWO_PI; + } + + // Carrier discriminator filter + d_carr_error_filt_hz = d_carrier_loop_filter.get_carrier_nco(d_carr_error_hz); + // New carrier Doppler frequency estimation + d_carrier_doppler_hz = d_acq_carrier_doppler_hz + d_carr_error_filt_hz; + // New code Doppler frequency estimation + d_code_freq_chips = Galileo_E1_CODE_CHIP_RATE_HZ + ((d_carrier_doppler_hz * Galileo_E1_CODE_CHIP_RATE_HZ) / Galileo_E1_FREQ_HZ); + + // ################## DLL ########################################################## + // DLL discriminator + d_code_error_chips = dll_nc_vemlp_normalized(d_VE_accu, d_E_accu, d_L_accu, d_VL_accu); //[chips/Ti] + // Code discriminator filter + d_code_error_filt_chips = d_code_loop_filter.get_code_nco(d_code_error_chips); //[chips/second] + +} + +void galileo_e1_dll_pll_veml_tracking_cc::clear_tracking_vars() +{ + *d_Very_Early = gr_complex(0,0); + *d_Early = gr_complex(0,0); + *d_Prompt = gr_complex(0,0); + *d_Late = gr_complex(0,0); + *d_Very_Late= gr_complex(0,0); + d_carr_error_hz =0.0; + d_carr_error_filt_hz =0.0; + d_code_error_chips =0.0; + d_code_error_filt_chips =0.0; + d_current_symbol=0; +} + +void galileo_e1_dll_pll_veml_tracking_cc::log_data() +{ + if(d_dump) + { + // Dump results to file + float prompt_I; + float prompt_Q; + float tmp_VE, tmp_E, tmp_P, tmp_L, tmp_VL; + float tmp_float; + double tmp_double; + + prompt_I = static_cast(d_P_accu.real()); + prompt_Q = static_cast(d_P_accu.imag()); + + tmp_VE = std::abs(d_VE_accu); + tmp_E = std::abs(d_E_accu); + tmp_P = std::abs(d_P_accu); + tmp_L = std::abs(d_L_accu); + tmp_VL = std::abs(d_VL_accu); + + try + { + // Dump correlators output + d_dump_file.write(reinterpret_cast(&tmp_VE), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_E), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_P), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_L), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_VL), sizeof(float)); + // PROMPT I and Q (to analyze navigation symbols) + d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); + d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); + // PRN start sample stamp + d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + // accumulated carrier phase + tmp_float = d_acc_carrier_phase_rad; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + // carrier and code frequency + tmp_float = d_carrier_doppler_hz; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_float = d_code_freq_chips; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + //PLL commands + tmp_float = d_carr_error_hz; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_float = d_carr_error_filt_hz; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + //DLL commands + tmp_float = d_code_error_chips; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_float = d_code_error_filt_chips; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + // CN0 and carrier lock test + tmp_float = d_CN0_SNV_dB_Hz; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_float = d_carrier_lock_test; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + // AUX vars (for debug purposes) + tmp_float = d_rem_code_phase_samples; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_double = static_cast(d_sample_counter + d_current_prn_length_samples); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + // PRN + unsigned int prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "Exception writing trk dump file " << e.what(); + } + } +} +int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - double carr_error_hz = 0.0; - double carr_error_filt_hz = 0.0; - double code_error_chips = 0.0; - double code_error_filt_chips = 0.0; // Block input data and block output stream pointers const gr_complex* in = reinterpret_cast(input_items[0]); @@ -304,123 +638,208 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attri // GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder Gnss_Synchro current_synchro_data = Gnss_Synchro(); - if (d_enable_tracking == true) + switch(d_state) + { + case 0: //standby - bypass + { + current_synchro_data.Tracking_sample_counter = d_sample_counter; + break; + } + case 1: // pull-in + { + /* + * Signal alignment (skip samples until the incoming signal is aligned with local replica) + */ + // Fill the acquisition data + current_synchro_data = *d_acquisition_gnss_synchro; + int samples_offset; + double acq_trk_shif_correction_samples; + int acq_to_trk_delay_samples; + acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; + acq_trk_shif_correction_samples = d_current_prn_length_samples - std::fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_current_prn_length_samples)); + samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); + current_synchro_data.Tracking_sample_counter = d_sample_counter; + current_synchro_data.fs = d_fs_in; + *out[0] = current_synchro_data; + d_sample_counter = d_sample_counter + samples_offset; //count for the processed samples + consume_each(samples_offset); //shift input to perform alignment with local replica + d_state=2; //next state is the symbol synchronization + return 0; + } + case 2: // wide tracking and symbol synchronization { // Fill the acquisition data current_synchro_data = *d_acquisition_gnss_synchro; - if (d_pull_in == true) + //Current NCO and code generator parameters + d_carrier_phase_step_rad = GALILEO_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); + d_code_phase_step_chips = d_code_freq_chips / static_cast(d_fs_in); + d_rem_code_phase_chips = d_rem_code_phase_samples * d_code_freq_chips / d_fs_in; + // perform a correlation step + do_correlation_step(in); + // save single correlation step variables + d_VE_accu=*d_Very_Early; + d_E_accu=*d_Early; + d_P_accu=*d_Prompt; + d_L_accu=*d_Late; + d_VL_accu=*d_Very_Late; + //check lock status + if (cn0_and_tracking_lock_status()==false) + { + clear_tracking_vars(); + d_state=0; //loss-of-lock detected + }else{ + + //perform DLL/PLL tracking loop computations + run_dll_pll(false); + + // ################## PLL COMMANDS ################################################# + //carrier phase accumulator for (K) Doppler estimation- + d_acc_carrier_phase_rad -= GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / static_cast(d_fs_in); + //remnant carrier phase to prevent overflow in the code NCO + d_rem_carr_phase_rad = d_rem_carr_phase_rad + GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / static_cast(d_fs_in); + d_rem_carr_phase_rad = std::fmod(d_rem_carr_phase_rad, GALILEO_TWO_PI); + + // ################## DLL COMMANDS ################################################# + + //Code error from DLL + double code_error_filt_secs; + code_error_filt_secs = (Galileo_E1_CODE_PERIOD * d_code_error_filt_chips) / Galileo_E1_CODE_CHIP_RATE_HZ; //[seconds] + + // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### + // keep alignment parameters for the next input buffer + // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation + double T_chip_seconds = 1.0 / d_code_freq_chips; + double T_prn_seconds = T_chip_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS; + double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); + double K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * static_cast(d_fs_in); + d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples + + // ########### Output the tracking results to Telemetry block ########## + if (d_track_pilot) { - /* - * Signal alignment (skip samples until the incoming signal is aligned with local replica) - */ - int samples_offset; - double acq_trk_shif_correction_samples; - int acq_to_trk_delay_samples; - acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; - acq_trk_shif_correction_samples = d_current_prn_length_samples - std::fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_current_prn_length_samples)); - samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); - current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; - current_synchro_data.fs = d_fs_in; - *out[0] = current_synchro_data; - d_sample_counter = d_sample_counter + samples_offset; //count for the processed samples - d_pull_in = false; - consume_each(samples_offset); //shift input to perform alignment with local replica - return 1; + current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); + }else{ + current_synchro_data.Prompt_I = static_cast((*d_Prompt).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt).imag()); } + current_synchro_data.Tracking_sample_counter = d_sample_counter; + current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; + //compute remnant code phase samples AFTER the Tracking timestamp + d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample + current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; + current_synchro_data.Flag_valid_symbol_output = true; + current_synchro_data.correlation_length_ms = Galileo_E1_CODE_PERIOD_MS; - // ################# CARRIER WIPEOFF AND CORRELATORS ############################## - // perform carrier wipe-off and compute Early, Prompt and Late correlation - multicorrelator_cpu.set_input_output_vectors(d_correlator_outs,in); + //enable write dump file this cycle (valid DLL/PLL cycle) + log_data(); - double carr_phase_step_rad = GALILEO_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); - double code_phase_step_half_chips = (2.0 * d_code_freq_chips) / (static_cast(d_fs_in)); - double rem_code_phase_half_chips = d_rem_code_phase_samples * (2.0*d_code_freq_chips / d_fs_in); - multicorrelator_cpu.Carrier_wipeoff_multicorrelator_resampler( - d_rem_carr_phase_rad, - carr_phase_step_rad, - rem_code_phase_half_chips, - code_phase_step_half_chips, - d_correlation_length_samples); + //std::cout<<(d_Prompt->real()>0); + if (d_enable_extended_integration) + { + // ####### SECONDARY CODE LOCK ##### + d_Prompt_buffer_deque.push_back(*d_Prompt); + if (d_Prompt_buffer_deque.size()==Galileo_E1_C_SECONDARY_CODE_LENGTH) + { + if (acquire_secondary()==true) + { + d_extend_correlation_symbols_count=0; + //reset extended correlator + d_VE_accu=gr_complex(0,0); + d_E_accu=gr_complex(0,0); + d_P_accu=gr_complex(0,0); + d_L_accu=gr_complex(0,0); + d_VL_accu=gr_complex(0,0); + d_Prompt_buffer_deque.clear(); + d_current_symbol=0; + d_code_loop_filter.set_DLL_BW(d_dll_bw_narrow_hz); + d_carrier_loop_filter.set_PLL_BW(d_pll_bw_narrow_hz); + + // Set TAPs delay values [chips] + d_local_code_shift_chips[0] = - d_very_early_late_spc_narrow_chips; + d_local_code_shift_chips[1] = - d_early_late_spc_narrow_chips; + d_local_code_shift_chips[2] = 0.0; + d_local_code_shift_chips[3] = d_early_late_spc_narrow_chips; + d_local_code_shift_chips[4] = d_very_early_late_spc_narrow_chips; + + + LOG(INFO) << "Enabled " << d_extend_correlation_symbols << " [symbols] extended correlator for CH " + << d_channel + << " : Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN); + std::cout<< "Enabled " << d_extend_correlation_symbols << " [symbols] extended correlator for CH " + << d_channel + << " : Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN)<(d_extend_correlation_symbols) * Galileo_E1_CODE_PERIOD; + d_carrier_loop_filter.set_pdi(new_correlation_time_s); + d_code_loop_filter.set_pdi(new_correlation_time_s); + + d_state=3; // next state is the extended correlator integrator + } + + d_Prompt_buffer_deque.pop_front(); + } + } + } + break; + } + case 3: // coherent integration (correlation time extension) + { + // Fill the acquisition data + current_synchro_data = *d_acquisition_gnss_synchro; + //Current NCO and code generator parameters + d_carrier_phase_step_rad = GALILEO_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); + d_code_phase_step_chips = d_code_freq_chips / static_cast(d_fs_in); + d_rem_code_phase_chips = d_rem_code_phase_samples * d_code_freq_chips / d_fs_in; + // perform a correlation step + do_correlation_step(in); + //correct the integration sign using the current symbol of the secondary code + if (Galileo_E1_C_SECONDARY_CODE.at(d_current_symbol) == '0') + { + d_VE_accu+=*d_Very_Early; + d_E_accu+=*d_Early; + d_P_accu+=*d_Prompt; + d_L_accu+=*d_Late; + d_VL_accu+=*d_Very_Late; + }else{ + d_VE_accu-=*d_Very_Early; + d_E_accu-=*d_Early; + d_P_accu-=*d_Prompt; + d_L_accu-=*d_Late; + d_VL_accu-=*d_Very_Late; + } + d_current_symbol++; + //secondary code roll-up + d_current_symbol=d_current_symbol%Galileo_E1_C_SECONDARY_CODE_LENGTH; + + // PLL/DLL not enabled, we are in the middle of a coherent integration + // keep alignment parameters for the next input buffer + // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation // ################## PLL ########################################################## - // PLL discriminator - carr_error_hz = pll_cloop_two_quadrant_atan(*d_Prompt) / GALILEO_TWO_PI; - // Carrier discriminator filter - carr_error_filt_hz = d_carrier_loop_filter.get_carrier_nco(carr_error_hz); - // New carrier Doppler frequency estimation - d_carrier_doppler_hz = d_acq_carrier_doppler_hz + carr_error_filt_hz; - // New code Doppler frequency estimation - d_code_freq_chips = Galileo_E1_CODE_CHIP_RATE_HZ + ((d_carrier_doppler_hz * Galileo_E1_CODE_CHIP_RATE_HZ) / Galileo_E1_FREQ_HZ); //carrier phase accumulator for (K) Doppler estimation- d_acc_carrier_phase_rad -= GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / static_cast(d_fs_in); //remnant carrier phase to prevent overflow in the code NCO d_rem_carr_phase_rad = d_rem_carr_phase_rad + GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / static_cast(d_fs_in); d_rem_carr_phase_rad = std::fmod(d_rem_carr_phase_rad, GALILEO_TWO_PI); - // ################## DLL ########################################################## - // DLL discriminator - code_error_chips = dll_nc_vemlp_normalized(*d_Very_Early, *d_Early, *d_Late, *d_Very_Late); //[chips/Ti] - // Code discriminator filter - code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips); //[chips/second] - //Code phase accumulator - double code_error_filt_secs; - code_error_filt_secs = (Galileo_E1_CODE_PERIOD * code_error_filt_chips) / Galileo_E1_CODE_CHIP_RATE_HZ; //[seconds] - d_acc_code_phase_secs = d_acc_code_phase_secs + code_error_filt_secs; - // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### // keep alignment parameters for the next input buffer - double T_chip_seconds; - double T_prn_seconds; - double T_prn_samples; - double K_blk_samples; // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation - T_chip_seconds = 1.0 / d_code_freq_chips; - T_prn_seconds = T_chip_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS; - T_prn_samples = T_prn_seconds * static_cast(d_fs_in); - K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * static_cast(d_fs_in); + double T_chip_seconds = 1.0 / d_code_freq_chips; + double T_prn_seconds = T_chip_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS; + double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); + double K_blk_samples = T_prn_samples + d_rem_code_phase_samples; d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples - // ####### CN0 ESTIMATION AND LOCK DETECTORS ###### - if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES) - { - // fill buffer with prompt correlator output values - d_Prompt_buffer[d_cn0_estimation_counter] = *d_Prompt; - d_cn0_estimation_counter++; - } - else - { - d_cn0_estimation_counter = 0; - - // Code lock indicator - d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, Galileo_E1_B_CODE_LENGTH_CHIPS); - - // Carrier lock indicator - d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES); - - // Loss of lock detection - if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < MINIMUM_VALID_CN0) - { - d_carrier_lock_fail_counter++; - } - else - { - if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--; - } - if (d_carrier_lock_fail_counter > MAXIMUM_LOCK_FAIL_COUNTER) - { - std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; - LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; - this->message_port_pub(pmt::mp("events"), pmt::from_long(3));//3 -> loss of lock - d_carrier_lock_fail_counter = 0; - d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine - } - } - // ########### Output the tracking results to Telemetry block ########## - - current_synchro_data.Prompt_I = static_cast((*d_Prompt).real()); - current_synchro_data.Prompt_Q = static_cast((*d_Prompt).imag()); - // Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!) + current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); current_synchro_data.Tracking_sample_counter = d_sample_counter; current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; //compute remnant code phase samples AFTER the Tracking timestamp @@ -431,94 +850,113 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attri current_synchro_data.Flag_valid_symbol_output = true; current_synchro_data.correlation_length_ms = Galileo_E1_CODE_PERIOD_MS; + d_extend_correlation_symbols_count++; + if (d_extend_correlation_symbols_count>=(d_extend_correlation_symbols-1)) + { + d_extend_correlation_symbols_count=0; + d_state=4; + } + break; + } + case 4: // narrow tracking + { + // Fill the acquisition data + current_synchro_data = *d_acquisition_gnss_synchro; + // perform a correlation step + do_correlation_step(in); + + //correct the integration using the current symbol + if (Galileo_E1_C_SECONDARY_CODE.at(d_current_symbol) == '0') + { + d_VE_accu+=*d_Very_Early; + d_E_accu+=*d_Early; + d_P_accu+=*d_Prompt; + d_L_accu+=*d_Late; + d_VL_accu+=*d_Very_Late; + }else{ + d_VE_accu-=*d_Very_Early; + d_E_accu-=*d_Early; + d_P_accu-=*d_Prompt; + d_L_accu-=*d_Late; + d_VL_accu-=*d_Very_Late; + } + d_current_symbol++; + //secondary code roll-up + d_current_symbol=d_current_symbol%Galileo_E1_C_SECONDARY_CODE_LENGTH; + + //check lock status + if (cn0_and_tracking_lock_status()==false) + { + clear_tracking_vars(); + d_state=0; //loss-of-lock detected + }else{ + run_dll_pll(true);//Costas loop disabled, use four quadrant atan + + // ################## PLL ########################################################## + //carrier phase accumulator for (K) Doppler estimation- + d_acc_carrier_phase_rad -= GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / static_cast(d_fs_in); + //remnant carrier phase to prevent overflow in the code NCO + d_rem_carr_phase_rad = d_rem_carr_phase_rad + GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / static_cast(d_fs_in); + d_rem_carr_phase_rad = std::fmod(d_rem_carr_phase_rad, GALILEO_TWO_PI); + + // ################## DLL ########################################################## + + //Code phase accumulator + double code_error_filt_secs; + code_error_filt_secs = (Galileo_E1_CODE_PERIOD * d_code_error_filt_chips) / Galileo_E1_CODE_CHIP_RATE_HZ; //[seconds] + + // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### + // keep alignment parameters for the next input buffer + // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation + double T_chip_seconds = 1.0 / d_code_freq_chips; + double T_prn_seconds = T_chip_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS; + double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); + double K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * static_cast(d_fs_in); + d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples + + // ########### Output the tracking results to Telemetry block ########## + current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); + current_synchro_data.Tracking_sample_counter = d_sample_counter; + current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; + //compute remnant code phase samples AFTER the Tracking timestamp + d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample + current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; + current_synchro_data.Flag_valid_symbol_output = true; + current_synchro_data.correlation_length_ms = Galileo_E1_CODE_PERIOD_MS; + //enable write dump file this cycle (valid DLL/PLL cycle) + log_data(); + //reset extended correlator + d_VE_accu=gr_complex(0,0); + d_E_accu=gr_complex(0,0); + d_P_accu=gr_complex(0,0); + d_L_accu=gr_complex(0,0); + d_VL_accu=gr_complex(0,0); + d_state=3; //new coherent integration (correlation time extension) cycle + } } - else - { - *d_Early = gr_complex(0,0); - *d_Prompt = gr_complex(0,0); - *d_Late = gr_complex(0,0); - // GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder - current_synchro_data.Tracking_sample_counter = d_sample_counter; } + //assign the GNURadio block output data - current_synchro_data.System = {'E'}; - std::string str_aux = "1B"; - const char * str = str_aux.c_str(); // get a C style null terminated string - std::memcpy(static_cast(current_synchro_data.Signal), str, 3); +// current_synchro_data.System = {'E'}; +// std::string str_aux = "1B"; +// const char * str = str_aux.c_str(); // get a C style null terminated string +// std::memcpy(static_cast(current_synchro_data.Signal), str, 3); current_synchro_data.fs = d_fs_in; *out[0] = current_synchro_data; - if(d_dump) - { - // Dump results to file - float prompt_I; - float prompt_Q; - float tmp_VE, tmp_E, tmp_P, tmp_L, tmp_VL; - float tmp_float; - double tmp_double; - prompt_I = (*d_Prompt).real(); - prompt_Q = (*d_Prompt).imag(); - tmp_VE = std::abs(*d_Very_Early); - tmp_E = std::abs(*d_Early); - tmp_P = std::abs(*d_Prompt); - tmp_L = std::abs(*d_Late); - tmp_VL = std::abs(*d_Very_Late); - - try - { - // Dump correlators output - d_dump_file.write(reinterpret_cast(&tmp_VE), sizeof(float)); - d_dump_file.write(reinterpret_cast(&tmp_E), sizeof(float)); - d_dump_file.write(reinterpret_cast(&tmp_P), sizeof(float)); - d_dump_file.write(reinterpret_cast(&tmp_L), sizeof(float)); - d_dump_file.write(reinterpret_cast(&tmp_VL), sizeof(float)); - // PROMPT I and Q (to analyze navigation symbols) - d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); - d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); - // PRN start sample stamp - d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); - // accumulated carrier phase - tmp_float = d_acc_carrier_phase_rad; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - // carrier and code frequency - tmp_float = d_carrier_doppler_hz; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - tmp_float = d_code_freq_chips; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - //PLL commands - tmp_float = carr_error_hz; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - tmp_float = carr_error_filt_hz; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - //DLL commands - tmp_float = code_error_chips; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - tmp_float = code_error_filt_chips; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - // CN0 and carrier lock test - tmp_float = d_CN0_SNV_dB_Hz; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - tmp_float = d_carrier_lock_test; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - // AUX vars (for debug purposes) - tmp_float = d_rem_code_phase_samples; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - tmp_double = static_cast(d_sample_counter + d_current_prn_length_samples); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - // PRN - unsigned int prn_ = d_acquisition_gnss_synchro->PRN; - d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); - } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "Exception writing trk dump file " << e.what(); - } - } consume_each(d_current_prn_length_samples); // this is required for gr_block derivates d_sample_counter += d_current_prn_length_samples; //count for the processed samples - return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false + if (current_synchro_data.Flag_valid_symbol_output) + { + return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false + }else{ + return 0; + } } @@ -534,25 +972,25 @@ int galileo_e1_dll_pll_veml_tracking_cc::save_matfile() dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { - dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); } catch(const std::ifstream::failure &e) { - std::cerr << "Problem opening dump file:" << e.what() << std::endl; - return 1; + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return 1; } // count number of epochs and rewind long int num_epoch = 0; if (dump_file.is_open()) - { - size = dump_file.tellg(); - num_epoch = static_cast(size) / static_cast(epoch_size_bytes); - dump_file.seekg(0, std::ios::beg); - } + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } else - { - return 1; - } + { + return 1; + } float * abs_VE = new float [num_epoch]; float * abs_E = new float [num_epoch]; float * abs_P = new float [num_epoch]; @@ -576,58 +1014,58 @@ int galileo_e1_dll_pll_veml_tracking_cc::save_matfile() try { - if (dump_file.is_open()) - { - for(long int i = 0; i < num_epoch; i++) - { - dump_file.read(reinterpret_cast(&abs_VE[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&abs_VL[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); - dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&carr_error_hz[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&carr_error_filt_hz[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&code_error_chips[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&code_error_filt_chips[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&CN0_SNV_dB_Hz[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&aux1[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); - dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); - } - } - dump_file.close(); + if (dump_file.is_open()) + { + for(long int i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&abs_VE[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_VL[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carr_error_hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carr_error_filt_hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&code_error_chips[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&code_error_filt_chips[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&CN0_SNV_dB_Hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&aux1[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + } + } + dump_file.close(); } catch (const std::ifstream::failure &e) { - std::cerr << "Problem reading dump file:" << e.what() << std::endl; - delete[] abs_VE; - delete[] abs_E; - delete[] abs_P; - delete[] abs_L; - delete[] abs_VL; - delete[] Prompt_I; - delete[] Prompt_Q; - delete[] PRN_start_sample_count; - delete[] acc_carrier_phase_rad; - delete[] carrier_doppler_hz; - delete[] code_freq_chips; - delete[] carr_error_hz; - delete[] carr_error_filt_hz; - delete[] code_error_chips; - delete[] code_error_filt_chips; - delete[] CN0_SNV_dB_Hz; - delete[] carrier_lock_test; - delete[] aux1; - delete[] aux2; - delete[] PRN; - return 1; + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + delete[] abs_VE; + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] abs_VL; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 1; } // WRITE MAT FILE @@ -638,88 +1076,88 @@ int galileo_e1_dll_pll_veml_tracking_cc::save_matfile() filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); if(reinterpret_cast(matfp) != NULL) - { - size_t dims[2] = {1, static_cast(num_epoch)}; - matvar = Mat_VarCreate("abs_VE", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + { + size_t dims[2] = {1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("abs_VE", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("abs_VL", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("abs_VL", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, acc_carrier_phase_rad, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, acc_carrier_phase_rad, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carrier_doppler_hz, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carrier_doppler_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("code_freq_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_freq_chips, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("code_freq_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_freq_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("carr_error_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carr_error_hz, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("carr_error_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carr_error_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carr_error_filt_hz, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carr_error_filt_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("code_error_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_error_chips, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("code_error_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_error_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_error_filt_chips, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_error_filt_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, CN0_SNV_dB_Hz, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, CN0_SNV_dB_Hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("carrier_lock_test", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carrier_lock_test, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("carrier_lock_test", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carrier_lock_test, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("aux1", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, aux1, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("aux1", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, aux1, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); - } + matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } Mat_Close(matfp); delete[] abs_VE; delete[] abs_E; @@ -751,23 +1189,23 @@ void galileo_e1_dll_pll_veml_tracking_cc::set_channel(unsigned int channel) LOG(INFO) << "Tracking Channel set to " << d_channel; // ############# ENABLE DATA FILE LOG ################# if (d_dump == true) + { + if (d_dump_file.is_open() == false) { - if (d_dump_file.is_open() == false) - { - try - { - d_dump_filename.append(boost::lexical_cast(d_channel)); - d_dump_filename.append(".dat"); - d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit); - d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str(); - } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); - } - } + try + { + d_dump_filename.append(boost::lexical_cast(d_channel)); + d_dump_filename.append(".dat"); + d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit); + d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str(); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); + } } + } } diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.h index 2d1aef220..f02c51b8e 100755 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.h @@ -53,8 +53,14 @@ galileo_e1_dll_pll_veml_make_tracking_cc(long if_freq, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, + float pll_bw_narrow_hz, + float dll_bw_narrow_hz, float early_late_space_chips, - float very_early_late_space_chips); + float very_early_late_space_chips, + float early_late_space_narrow_chips, + float very_early_late_space_narrow_chips, + int extend_correlation_symbols, + bool track_pilot); /*! * \brief This class implements a code DLL + carrier PLL VEML (Very Early @@ -88,8 +94,14 @@ private: std::string dump_filename, float pll_bw_hz, float dll_bw_hz, + float pll_bw_narrow_hz, + float dll_bw_narrow_hz, float early_late_space_chips, - float very_early_late_space_chips); + float very_early_late_space_chips, + float early_late_space_narrow_chips, + float very_early_late_space_narrow_chips, + int extend_correlation_symbols, + bool track_pilot); galileo_e1_dll_pll_veml_tracking_cc(long if_freq, long fs_in, unsigned @@ -98,12 +110,25 @@ private: std::string dump_filename, float pll_bw_hz, float dll_bw_hz, + float pll_bw_narrow_hz, + float dll_bw_narrow_hz, float early_late_space_chips, - float very_early_late_space_chips); + float very_early_late_space_chips, + float early_late_space_narrow_chips, + float very_early_late_space_narrow_chips, + int extend_correlation_symbols, + bool track_pilot); + bool cn0_and_tracking_lock_status(); + void do_correlation_step(const gr_complex* input_samples); + void run_dll_pll(bool disable_costas_loop); void update_local_code(); - void update_local_carrier(); + bool acquire_secondary(); + + void clear_tracking_vars(); + + void log_data(); // tracking configuration vars unsigned int d_vector_length; @@ -114,16 +139,29 @@ private: long d_if_freq; long d_fs_in; + //tracking state machine + int d_state; + //Integration period in samples int d_correlation_length_samples; int d_n_correlator_taps; double d_early_late_spc_chips; double d_very_early_late_spc_chips; - float* d_ca_code; + double d_early_late_spc_narrow_chips; + double d_very_early_late_spc_narrow_chips; + + float* d_tracking_code; + float* d_data_code; float* d_local_code_shift_chips; gr_complex* d_correlator_outs; cpu_multicorrelator_real_codes multicorrelator_cpu; + //todo: currently the multicorrelator does not support adding extra correlator + //with different local code, thus we need extra multicorrelator instance. + //Implement this functionality inside multicorrelator class + //as an enhancement to increase the performance + float* d_local_code_data_shift_chips; + cpu_multicorrelator_real_codes correlator_data_cpu; //for data channel gr_complex *d_Very_Early; gr_complex *d_Early; @@ -131,6 +169,22 @@ private: gr_complex *d_Late; gr_complex *d_Very_Late; + int d_extend_correlation_symbols; + int d_extend_correlation_symbols_count; + bool d_enable_extended_integration; + int d_current_symbol; + + gr_complex d_VE_accu; + gr_complex d_E_accu; + gr_complex d_P_accu; + gr_complex d_L_accu; + gr_complex d_VL_accu; + + bool d_track_pilot; + gr_complex *d_Prompt_Data; + + double d_code_phase_step_chips; + double d_carrier_phase_step_rad; // remaining code phase and carrier phase between tracking loops double d_rem_code_phase_samples; double d_rem_carr_phase_rad; @@ -143,11 +197,24 @@ private: double d_acq_code_phase_samples; double d_acq_carrier_doppler_hz; + // tracking parameters + float d_dll_bw_hz; + float d_pll_bw_hz; + float d_dll_bw_narrow_hz; + float d_pll_bw_narrow_hz; // tracking vars + double d_carr_error_hz; + double d_carr_error_filt_hz; + double d_code_error_chips; + double d_code_error_filt_chips; + + double d_K_blk_samples; + double d_code_freq_chips; double d_carrier_doppler_hz; double d_acc_carrier_phase_rad; - double d_acc_code_phase_secs; + double d_rem_code_phase_chips; + double d_code_phase_samples; //PRN period in samples int d_current_prn_length_samples; @@ -158,16 +225,13 @@ private: // CN0 estimation and lock detector int d_cn0_estimation_counter; + std::deque d_Prompt_buffer_deque; gr_complex* d_Prompt_buffer; double d_carrier_lock_test; double d_CN0_SNV_dB_Hz; double d_carrier_lock_threshold; int d_carrier_lock_fail_counter; - // control vars - bool d_enable_tracking; - bool d_pull_in; - // file dump std::string d_dump_filename; std::ofstream d_dump_file; diff --git a/src/core/system_parameters/Galileo_E1.h b/src/core/system_parameters/Galileo_E1.h index a95afd1ca..be5704a6e 100644 --- a/src/core/system_parameters/Galileo_E1.h +++ b/src/core/system_parameters/Galileo_E1.h @@ -57,7 +57,7 @@ const double Galileo_E1_SUB_CARRIER_A_RATE_HZ = 1.023e6; //!< Galileo E1 sub-car const double Galileo_E1_SUB_CARRIER_B_RATE_HZ = 6.138e6; //!< Galileo E1 sub-carrier 'b' rate [Hz] const double Galileo_E1_B_CODE_LENGTH_CHIPS = 4092.0; //!< Galileo E1-B code length [chips] const double Galileo_E1_B_SYMBOL_RATE_BPS = 250.0; //!< Galileo E1-B symbol rate [bits/second] -const double Galileo_E1_C_SECONDARY_CODE_LENGTH = 25.0; //!< Galileo E1-C secondary code length [chips] +const int Galileo_E1_C_SECONDARY_CODE_LENGTH = 25; //!< Galileo E1-C secondary code length [chips] const int Galileo_E1_NUMBER_OF_CODES = 50; const double GALILEO_STARTOFFSET_ms = 68.802; //[ms] Initial sign. travel time (this cannot go here) From 25127a0b273ac96f7381fe2256724cc88cccbf41 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Wed, 10 Jan 2018 16:24:09 +0100 Subject: [PATCH 30/96] Minor changes --- .../tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc | 2 ++ src/core/receiver/gnss_flowgraph.cc | 1 + 2 files changed, 3 insertions(+) diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc index ec5004c56..8911db3db 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc @@ -185,6 +185,7 @@ Gps_L1_Ca_Dll_Pll_Tracking_cc::Gps_L1_Ca_Dll_Pll_Tracking_cc( void Gps_L1_Ca_Dll_Pll_Tracking_cc::start_tracking() { + gr::thread::scoped_lock lk(d_setlock); /* * correct the code phase according to the delay between acq and trk */ @@ -521,6 +522,7 @@ Gps_L1_Ca_Dll_Pll_Tracking_cc::~Gps_L1_Ca_Dll_Pll_Tracking_cc() int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { + gr::thread::scoped_lock lk(d_setlock); // process vars double carr_error_hz = 0.0; double carr_error_filt_hz = 0.0; diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index cf1226102..a59d4e5d1 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -382,6 +382,7 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) channels_state_[i] = 1; channels_.at(i)->set_signal(search_next_signal(channels_.at(i)->get_signal().get_signal_str(), true)); acq_channels_count_++; + DLOG(INFO) << "Channel "<< i << " Starting acquisition " << channels_.at(i)->get_signal().get_satellite() << ", Signal " << channels_.at(i)->get_signal().get_signal_str(); channels_.at(i)->start_acquisition(); } DLOG(INFO) << "Channel " << i << " in state " << channels_state_[i]; From 81179a9f38d5f9a6f26b412bd15b473b61ff6af3 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Wed, 10 Jan 2018 16:26:05 +0100 Subject: [PATCH 31/96] Removing gnuradio output buffer request on observables and disabling the gnss_synchro output for all trackings that are not tracking any satellite. This is a bug fix to avoid gnuradio flowgraph deadlocks when different GNSS integration times are used in satellite channels --- .../gnuradio_blocks/hybrid_observables_cc.cc | 28 ++++++++++++++----- .../gnuradio_blocks/hybrid_observables_cc.h | 3 +- .../galileo_e1_dll_pll_veml_tracking_cc.cc | 2 +- .../galileo_e1_tcp_connector_tracking_cc.cc | 7 ++++- .../galileo_e5a_dll_pll_tracking_cc.cc | 8 +++++- .../gps_l1_ca_dll_pll_c_aid_tracking_cc.cc | 7 ++++- ...ps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.cc | 7 ++++- .../gps_l1_ca_dll_pll_c_aid_tracking_sc.cc | 7 ++++- .../gps_l1_ca_dll_pll_tracking_cc.cc | 8 +++++- .../gps_l1_ca_dll_pll_tracking_gpu_cc.cc | 7 ++++- .../gps_l1_ca_tcp_connector_tracking_cc.cc | 7 ++++- .../gps_l2_m_dll_pll_tracking_cc.cc | 7 ++++- .../gps_l5i_dll_pll_tracking_cc.cc | 7 ++++- 13 files changed, 85 insertions(+), 20 deletions(-) diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc index d63570996..bb548e25d 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc @@ -66,11 +66,6 @@ hybrid_observables_cc::hybrid_observables_cc(unsigned int nchannels, bool dump, { d_gnss_synchro_history_queue.push_back(std::deque()); } - // todo: this is a gnuradio scheduler hack. - // Migrate the queues to gnuradio set_history to see if the scheduler can handle - // the multiple output flow - d_max_noutputs = 100; - this->set_min_noutput_items(100); // ############# ENABLE DATA FILE LOG ################# if (d_dump == true) @@ -328,8 +323,15 @@ bool Hybrid_valueCompare_gnss_synchro_d_TOW(const Gnss_Synchro& a, double b) return (a.TOW_at_current_symbol_s) < (b); } +void hybrid_observables_cc::forecast (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required) +{ + for(unsigned int i = 0; i < d_nchannels; i++) + { + ninput_items_required[i] = 0; //set the required available samples in each call + } +} -int hybrid_observables_cc::general_work (int noutput_items __attribute__((unused)), +int hybrid_observables_cc::general_work (int noutput_items , gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) @@ -351,15 +353,27 @@ int hybrid_observables_cc::general_work (int noutput_items __attribute__((unused * Multi-rate GNURADIO Block. Read how many input items are avaliable in each channel * Record all synchronization data into queues */ + bool zero_samples=true; for (unsigned int i = 0; i < d_nchannels; i++) { n_consume[i] = ninput_items[i];// full throttle for (int j = 0; j < n_consume[i]; j++) { d_gnss_synchro_history_queue[i].push_back(in[i][j]); + zero_samples=false; } } + //check if there are new channel data available + //This is required because the combination of several GNSS tracking signals + //leads to a multirrate inputs that can not warantee that every channel will have new data + //and forecast method is set to zero samples for each channel to avoid blockings + if (zero_samples==true) + { + usleep(500); // run this task at up to 2 kHz rate + return 0; // No new samples in this call, thus, return. + } + bool channel_history_ok; do { @@ -561,7 +575,7 @@ int hybrid_observables_cc::general_work (int noutput_items __attribute__((unused } } } - } while(channel_history_ok == true && d_max_noutputs > n_outputs); + } while(channel_history_ok == true && noutput_items > n_outputs); // Multi-rate consume! for (unsigned int i = 0; i < d_nchannels; i++) diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h index 4d7e67338..494f84e75 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h @@ -55,7 +55,7 @@ public: ~hybrid_observables_cc (); int general_work (int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); - + void forecast (int noutput_items, gr_vector_int &ninput_items_required); private: friend hybrid_observables_cc_sptr hybrid_make_observables_cc(unsigned int nchannels, bool dump, std::string dump_filename, unsigned int deep_history); @@ -66,7 +66,6 @@ private: double T_rx_s; double T_rx_step_s; - int d_max_noutputs; bool d_dump; unsigned int d_nchannels; unsigned int history_deep; diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc index a21865500..cd6b9764c 100755 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc @@ -953,7 +953,7 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attri if (current_synchro_data.Flag_valid_symbol_output) { - return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false + return 1; }else{ return 0; } diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.cc index 6204215a5..995941285 100644 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.cc @@ -513,7 +513,12 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work (int noutput_items __attr consume_each(d_current_prn_length_samples); // this is needed in gr::block derivates d_sample_counter += d_current_prn_length_samples; //count for the processed samples - return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false + if (d_enable_tracking) + { + return 1; + }else{ + return 0; + } } diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_pll_tracking_cc.cc index f36dc1139..fd4ab4864 100644 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_pll_tracking_cc.cc @@ -733,7 +733,13 @@ int Galileo_E5a_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribute d_secondary_delay = (d_secondary_delay + 1) % Galileo_E5a_Q_SECONDARY_CODE_LENGTH; d_sample_counter += d_current_prn_length_samples; //count for the processed samples consume_each(d_current_prn_length_samples); // this is necessary in gr::block derivates - return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false + + if (current_synchro_data.Flag_valid_symbol_output) + { + return 1; + }else{ + return 0; + } } diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.cc index 4bab79242..5264b141a 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.cc @@ -875,7 +875,12 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items __attri consume_each(d_correlation_length_samples); // this is necessary in gr::block derivates d_sample_counter += d_correlation_length_samples; //count for the processed samples - return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false + if (d_enable_tracking) + { + return 1; + }else{ + return 0; + } } diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.cc index 0b39b1ebe..464ef6493 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.cc @@ -694,7 +694,12 @@ int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::general_work( //consume_each(d_correlation_length_samples); // this is necessary in gr::block derivates d_sample_counter += d_correlation_length_samples; //count for the processed samples - return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false + if (d_enable_tracking) + { + return 1; + }else{ + return 0; + } } diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.cc index 8973bb6a4..2d7aa4102 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.cc @@ -879,7 +879,12 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work (int noutput_items __attri consume_each(d_correlation_length_samples); // this is necessary in gr::block derivates d_sample_counter += d_correlation_length_samples; //count for the processed samples - return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false + if (d_enable_tracking) + { + return 1; + }else{ + return 0; + } } diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc index ec5004c56..b90860ada 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc @@ -736,7 +736,13 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribute__ consume_each(d_current_prn_length_samples); // this is necessary in gr::block derivates d_sample_counter += d_current_prn_length_samples; // count for the processed samples - return 1; // output tracking result ALWAYS even in the case of d_enable_tracking==false + + if (d_enable_tracking) + { + return 1; + }else{ + return 0; + } } diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc index cbd835b86..b79479d68 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc @@ -536,7 +536,12 @@ int Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::general_work (int noutput_items __attribu consume_each(d_correlation_length_samples); // this is necessary in gr::block derivates d_sample_counter += d_correlation_length_samples; //count for the processed samples - return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false + if (d_enable_tracking) + { + return 1; + }else{ + return 0; + } } diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.cc index 9bb40eefa..219aaff76 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.cc @@ -549,7 +549,12 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work (int noutput_items __attri d_sample_counter_seconds = d_sample_counter_seconds + ( static_cast(d_current_prn_length_samples) / static_cast(d_fs_in) ); d_sample_counter += d_current_prn_length_samples; //count for the processed samples - return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false + if (d_enable_tracking) + { + return 1; + }else{ + return 0; + } } diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l2_m_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l2_m_dll_pll_tracking_cc.cc index dfa1b6990..24224ede0 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l2_m_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l2_m_dll_pll_tracking_cc.cc @@ -729,7 +729,12 @@ int gps_l2_m_dll_pll_tracking_cc::general_work (int noutput_items __attribute__( } consume_each(d_current_prn_length_samples); // this is necessary in gr::block derivates d_sample_counter += d_current_prn_length_samples; // count for the processed samples - return 1; // output tracking result ALWAYS even in the case of d_enable_tracking==false + if (d_enable_tracking) + { + return 1; + }else{ + return 0; + } } diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l5i_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l5i_dll_pll_tracking_cc.cc index 3fd0a151c..100f8c62f 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l5i_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l5i_dll_pll_tracking_cc.cc @@ -729,7 +729,12 @@ int gps_l5i_dll_pll_tracking_cc::general_work (int noutput_items __attribute__(( } consume_each(d_current_prn_length_samples); // this is necessary in gr::block derivates d_sample_counter += d_current_prn_length_samples; // count for the processed samples - return 1; // output tracking result ALWAYS even in the case of d_enable_tracking==false + if (d_enable_tracking) + { + return 1; + }else{ + return 0; + } } From 184bd0d1de98482dc15cbe4ebaa16077365f4181 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Wed, 10 Jan 2018 18:13:46 +0100 Subject: [PATCH 32/96] A smarter way of handling the multirrate input of observables block --- .../gnuradio_blocks/hybrid_observables_cc.cc | 688 +++++++++--------- 1 file changed, 345 insertions(+), 343 deletions(-) diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc index bb548e25d..f9fb4a936 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include #include #include "Galileo_E1.h" @@ -52,8 +54,8 @@ hybrid_observables_cc_sptr hybrid_make_observables_cc(unsigned int nchannels, bo hybrid_observables_cc::hybrid_observables_cc(unsigned int nchannels, bool dump, std::string dump_filename, unsigned int deep_history) : - gr::block("hybrid_observables_cc", gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)), - gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro))) + gr::block("hybrid_observables_cc", gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)), + gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro))) { // initialize internal vars d_dump = dump; @@ -63,49 +65,49 @@ hybrid_observables_cc::hybrid_observables_cc(unsigned int nchannels, bool dump, T_rx_s = 0.0; T_rx_step_s = 1e-3; // todo: move to gnss-sdr config for (unsigned int i = 0; i < d_nchannels; i++) - { - d_gnss_synchro_history_queue.push_back(std::deque()); - } + { + d_gnss_synchro_history_queue.push_back(std::deque()); + } // ############# ENABLE DATA FILE LOG ################# if (d_dump == true) + { + if (d_dump_file.is_open() == false) { - if (d_dump_file.is_open() == false) - { - try - { - d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit ); - d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "Observables dump enabled Log file: " << d_dump_filename.c_str(); - } - catch (const std::ifstream::failure & e) - { - LOG(WARNING) << "Exception opening observables dump file " << e.what(); - } - } + try + { + d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit ); + d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "Observables dump enabled Log file: " << d_dump_filename.c_str(); + } + catch (const std::ifstream::failure & e) + { + LOG(WARNING) << "Exception opening observables dump file " << e.what(); + } } + } } hybrid_observables_cc::~hybrid_observables_cc() { if (d_dump_file.is_open() == true) + { + try { - try - { - d_dump_file.close(); - } - catch(const std::exception & ex) - { - LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); - } + d_dump_file.close(); } + catch(const std::exception & ex) + { + LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); + } + } if(d_dump == true) - { - std::cout << "Writing observables .mat files ..."; - hybrid_observables_cc::save_matfile(); - std::cout << " done." << std::endl; - } + { + std::cout << "Writing observables .mat files ..."; + hybrid_observables_cc::save_matfile(); + std::cout << " done." << std::endl; + } } @@ -119,25 +121,25 @@ int hybrid_observables_cc::save_matfile() dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { - dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); } catch(const std::ifstream::failure &e) { - std::cerr << "Problem opening dump file:" << e.what() << std::endl; - return 1; + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return 1; } // count number of epochs and rewind long int num_epoch = 0; if (dump_file.is_open()) - { - size = dump_file.tellg(); - num_epoch = static_cast(size) / static_cast(epoch_size_bytes); - dump_file.seekg(0, std::ios::beg); - } + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } else - { - return 1; - } + { + return 1; + } double ** RX_time = new double * [d_nchannels]; double ** TOW_at_current_symbol_s = new double * [d_nchannels]; double ** Carrier_Doppler_hz = new double * [d_nchannels]; @@ -147,58 +149,58 @@ int hybrid_observables_cc::save_matfile() double ** Flag_valid_pseudorange = new double * [d_nchannels]; for(unsigned int i = 0; i < d_nchannels; i++) - { - RX_time[i] = new double [num_epoch]; - TOW_at_current_symbol_s[i] = new double[num_epoch]; - Carrier_Doppler_hz[i] = new double[num_epoch]; - Carrier_phase_cycles[i] = new double[num_epoch]; - Pseudorange_m[i] = new double[num_epoch]; - PRN[i] = new double[num_epoch]; - Flag_valid_pseudorange[i] = new double[num_epoch]; - } + { + RX_time[i] = new double [num_epoch]; + TOW_at_current_symbol_s[i] = new double[num_epoch]; + Carrier_Doppler_hz[i] = new double[num_epoch]; + Carrier_phase_cycles[i] = new double[num_epoch]; + Pseudorange_m[i] = new double[num_epoch]; + PRN[i] = new double[num_epoch]; + Flag_valid_pseudorange[i] = new double[num_epoch]; + } try { - if (dump_file.is_open()) + if (dump_file.is_open()) + { + for(long int i = 0; i < num_epoch; i++) + { + for(unsigned int chan = 0; chan < d_nchannels; chan++) { - for(long int i = 0; i < num_epoch; i++) - { - for(unsigned int chan = 0; chan < d_nchannels; chan++) - { - dump_file.read(reinterpret_cast(&RX_time[chan][i]), sizeof(double)); - dump_file.read(reinterpret_cast(&TOW_at_current_symbol_s[chan][i]), sizeof(double)); - dump_file.read(reinterpret_cast(&Carrier_Doppler_hz[chan][i]), sizeof(double)); - dump_file.read(reinterpret_cast(&Carrier_phase_cycles[chan][i]), sizeof(double)); - dump_file.read(reinterpret_cast(&Pseudorange_m[chan][i]), sizeof(double)); - dump_file.read(reinterpret_cast(&PRN[chan][i]), sizeof(double)); - dump_file.read(reinterpret_cast(&Flag_valid_pseudorange[chan][i]), sizeof(double)); - } - } + dump_file.read(reinterpret_cast(&RX_time[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&TOW_at_current_symbol_s[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&Carrier_Doppler_hz[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&Carrier_phase_cycles[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&Pseudorange_m[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&PRN[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&Flag_valid_pseudorange[chan][i]), sizeof(double)); } - dump_file.close(); + } + } + dump_file.close(); } catch (const std::ifstream::failure &e) { - std::cerr << "Problem reading dump file:" << e.what() << std::endl; - for(unsigned int i = 0; i < d_nchannels; i++) - { - delete[] RX_time[i]; - delete[] TOW_at_current_symbol_s[i]; - delete[] Carrier_Doppler_hz[i]; - delete[] Carrier_phase_cycles[i]; - delete[] Pseudorange_m[i]; - delete[] PRN[i]; - delete[] Flag_valid_pseudorange[i]; - } - delete[] RX_time; - delete[] TOW_at_current_symbol_s; - delete[] Carrier_Doppler_hz; - delete[] Carrier_phase_cycles; - delete[] Pseudorange_m; - delete[] PRN; - delete[] Flag_valid_pseudorange; + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + for(unsigned int i = 0; i < d_nchannels; i++) + { + delete[] RX_time[i]; + delete[] TOW_at_current_symbol_s[i]; + delete[] Carrier_Doppler_hz[i]; + delete[] Carrier_phase_cycles[i]; + delete[] Pseudorange_m[i]; + delete[] PRN[i]; + delete[] Flag_valid_pseudorange[i]; + } + delete[] RX_time; + delete[] TOW_at_current_symbol_s; + delete[] Carrier_Doppler_hz; + delete[] Carrier_phase_cycles; + delete[] Pseudorange_m; + delete[] PRN; + delete[] Flag_valid_pseudorange; - return 1; + return 1; } double * RX_time_aux = new double [d_nchannels * num_epoch]; @@ -210,19 +212,19 @@ int hybrid_observables_cc::save_matfile() double * Flag_valid_pseudorange_aux = new double[d_nchannels * num_epoch]; unsigned int k = 0; for(long int j = 0; j < num_epoch; j++ ) + { + for(unsigned int i = 0; i < d_nchannels; i++ ) { - for(unsigned int i = 0; i < d_nchannels; i++ ) - { - RX_time_aux[k] = RX_time[i][j]; - TOW_at_current_symbol_s_aux[k] = TOW_at_current_symbol_s[i][j]; - Carrier_Doppler_hz_aux[k] = Carrier_Doppler_hz[i][j]; - Carrier_phase_cycles_aux[k] = Carrier_phase_cycles[i][j]; - Pseudorange_m_aux[k] = Pseudorange_m[i][j]; - PRN_aux[k] = PRN[i][j]; - Flag_valid_pseudorange_aux[k] = Flag_valid_pseudorange[i][j]; - k++; - } + RX_time_aux[k] = RX_time[i][j]; + TOW_at_current_symbol_s_aux[k] = TOW_at_current_symbol_s[i][j]; + Carrier_Doppler_hz_aux[k] = Carrier_Doppler_hz[i][j]; + Carrier_phase_cycles_aux[k] = Carrier_phase_cycles[i][j]; + Pseudorange_m_aux[k] = Pseudorange_m[i][j]; + PRN_aux[k] = PRN[i][j]; + Flag_valid_pseudorange_aux[k] = Flag_valid_pseudorange[i][j]; + k++; } + } // WRITE MAT FILE mat_t *matfp; @@ -232,49 +234,49 @@ int hybrid_observables_cc::save_matfile() filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); if(reinterpret_cast(matfp) != NULL) - { - size_t dims[2] = {static_cast(d_nchannels), static_cast(num_epoch)}; - matvar = Mat_VarCreate("RX_time", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, RX_time_aux, MAT_F_DONT_COPY_DATA); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + { + size_t dims[2] = {static_cast(d_nchannels), static_cast(num_epoch)}; + matvar = Mat_VarCreate("RX_time", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, RX_time_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("TOW_at_current_symbol_s", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, TOW_at_current_symbol_s_aux, MAT_F_DONT_COPY_DATA); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("TOW_at_current_symbol_s", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, TOW_at_current_symbol_s_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("Carrier_Doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Carrier_Doppler_hz_aux, MAT_F_DONT_COPY_DATA); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("Carrier_Doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Carrier_Doppler_hz_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("Carrier_phase_cycles", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Carrier_phase_cycles_aux, MAT_F_DONT_COPY_DATA); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("Carrier_phase_cycles", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Carrier_phase_cycles_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("Pseudorange_m", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Pseudorange_m_aux, MAT_F_DONT_COPY_DATA); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("Pseudorange_m", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Pseudorange_m_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("PRN", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, PRN_aux, MAT_F_DONT_COPY_DATA); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("PRN", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, PRN_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("Flag_valid_pseudorange", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Flag_valid_pseudorange_aux, MAT_F_DONT_COPY_DATA); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); - } + matvar = Mat_VarCreate("Flag_valid_pseudorange", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Flag_valid_pseudorange_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } Mat_Close(matfp); for(unsigned int i = 0; i < d_nchannels; i++) - { - delete[] RX_time[i]; - delete[] TOW_at_current_symbol_s[i]; - delete[] Carrier_Doppler_hz[i]; - delete[] Carrier_phase_cycles[i]; - delete[] Pseudorange_m[i]; - delete[] PRN[i]; - delete[] Flag_valid_pseudorange[i]; + { + delete[] RX_time[i]; + delete[] TOW_at_current_symbol_s[i]; + delete[] Carrier_Doppler_hz[i]; + delete[] Carrier_phase_cycles[i]; + delete[] Pseudorange_m[i]; + delete[] PRN[i]; + delete[] Flag_valid_pseudorange[i]; - } + } delete[] RX_time; delete[] TOW_at_current_symbol_s; delete[] Carrier_Doppler_hz; @@ -325,16 +327,28 @@ bool Hybrid_valueCompare_gnss_synchro_d_TOW(const Gnss_Synchro& a, double b) void hybrid_observables_cc::forecast (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required) { + + bool zero_samples=true; for(unsigned int i = 0; i < d_nchannels; i++) + { + int items=detail()->input(i)->items_available(); + if (items>0) zero_samples=false; + ninput_items_required[i] = items; //set the required available samples in each call + } + + if (zero_samples==true) + { + for(unsigned int i = 0; i < d_nchannels; i++) { - ninput_items_required[i] = 0; //set the required available samples in each call + ninput_items_required[i] = 1; //set the required available samples in each call } + } } int hybrid_observables_cc::general_work (int noutput_items , - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { const Gnss_Synchro **in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer Gnss_Synchro **out = reinterpret_cast(&output_items[0]); // Get the output buffer pointer @@ -345,243 +359,231 @@ int hybrid_observables_cc::general_work (int noutput_items , Gnss_Synchro current_gnss_synchro[d_nchannels]; Gnss_Synchro aux = Gnss_Synchro(); for(unsigned int i = 0; i < d_nchannels; i++) - { - current_gnss_synchro[i] = aux; - } + { + current_gnss_synchro[i] = aux; + } /* * 1. Read the GNSS SYNCHRO objects from available channels. * Multi-rate GNURADIO Block. Read how many input items are avaliable in each channel * Record all synchronization data into queues */ - bool zero_samples=true; for (unsigned int i = 0; i < d_nchannels; i++) + { + n_consume[i] = ninput_items[i];// full throttle + for (int j = 0; j < n_consume[i]; j++) { - n_consume[i] = ninput_items[i];// full throttle - for (int j = 0; j < n_consume[i]; j++) - { - d_gnss_synchro_history_queue[i].push_back(in[i][j]); - zero_samples=false; - } - } - - //check if there are new channel data available - //This is required because the combination of several GNSS tracking signals - //leads to a multirrate inputs that can not warantee that every channel will have new data - //and forecast method is set to zero samples for each channel to avoid blockings - if (zero_samples==true) - { - usleep(500); // run this task at up to 2 kHz rate - return 0; // No new samples in this call, thus, return. + d_gnss_synchro_history_queue[i].push_back(in[i][j]); } + } bool channel_history_ok; do + { + channel_history_ok = true; + for (unsigned int i = 0; i < d_nchannels; i++) { - channel_history_ok = true; + if (d_gnss_synchro_history_queue[i].size() < history_deep) + { + channel_history_ok = false; + } + } + if (channel_history_ok == true) + { + std::map::const_iterator gnss_synchro_map_iter; + std::deque::const_iterator gnss_synchro_deque_iter; + + // 1. If the RX time is not set, set the Rx time + if (T_rx_s == 0) + { + // 0. Read a gnss_synchro snapshot from the queue and store it in a map + std::map gnss_synchro_map; + for (unsigned int i = 0; i < d_nchannels; i++) + { + gnss_synchro_map.insert(std::pair(d_gnss_synchro_history_queue[i].front().Channel_ID, + d_gnss_synchro_history_queue[i].front())); + } + gnss_synchro_map_iter = min_element(gnss_synchro_map.cbegin(), + gnss_synchro_map.cend(), + Hybrid_pairCompare_gnss_synchro_sample_counter); + T_rx_s = static_cast(gnss_synchro_map_iter->second.Tracking_sample_counter) / static_cast(gnss_synchro_map_iter->second.fs); + T_rx_s = floor(T_rx_s * 1000.0) / 1000.0; // truncate to ms + T_rx_s += past_history_s; // increase T_rx to have a minimum past history to interpolate + } + + // 2. Realign RX time in all valid channels + std::map realigned_gnss_synchro_map; // container for the aligned set of observables for the selected T_rx + std::map adjacent_gnss_synchro_map; // container for the previous observable values to interpolate + // shift channels history to match the reference TOW for (unsigned int i = 0; i < d_nchannels; i++) + { + gnss_synchro_deque_iter = std::lower_bound(d_gnss_synchro_history_queue[i].cbegin(), + d_gnss_synchro_history_queue[i].cend(), + T_rx_s, + Hybrid_valueCompare_gnss_synchro_receiver_time); + if (gnss_synchro_deque_iter != d_gnss_synchro_history_queue[i].cend()) { - if (d_gnss_synchro_history_queue[i].size() < history_deep) + if (gnss_synchro_deque_iter->Flag_valid_word == true) + { + double T_rx_channel = static_cast(gnss_synchro_deque_iter->Tracking_sample_counter) / static_cast(gnss_synchro_deque_iter->fs); + double delta_T_rx_s = T_rx_channel - T_rx_s; + + // check that T_rx difference is less than a threshold (the correlation interval) + if (delta_T_rx_s * 1000.0 < static_cast(gnss_synchro_deque_iter->correlation_length_ms)) { - channel_history_ok = false; - } - } - if (channel_history_ok == true) - { - std::map::const_iterator gnss_synchro_map_iter; - std::deque::const_iterator gnss_synchro_deque_iter; - - // 1. If the RX time is not set, set the Rx time - if (T_rx_s == 0) - { - // 0. Read a gnss_synchro snapshot from the queue and store it in a map - std::map gnss_synchro_map; - for (unsigned int i = 0; i < d_nchannels; i++) + // record the word structure in a map for pseudorange computation + // save the previous observable + int distance = std::distance(d_gnss_synchro_history_queue[i].cbegin(), gnss_synchro_deque_iter); + if (distance > 0) + { + if (d_gnss_synchro_history_queue[i].at(distance - 1).Flag_valid_word) { - gnss_synchro_map.insert(std::pair(d_gnss_synchro_history_queue[i].front().Channel_ID, - d_gnss_synchro_history_queue[i].front())); - } - gnss_synchro_map_iter = min_element(gnss_synchro_map.cbegin(), - gnss_synchro_map.cend(), - Hybrid_pairCompare_gnss_synchro_sample_counter); - T_rx_s = static_cast(gnss_synchro_map_iter->second.Tracking_sample_counter) / static_cast(gnss_synchro_map_iter->second.fs); - T_rx_s = floor(T_rx_s * 1000.0) / 1000.0; // truncate to ms - T_rx_s += past_history_s; // increase T_rx to have a minimum past history to interpolate - } - - // 2. Realign RX time in all valid channels - std::map realigned_gnss_synchro_map; // container for the aligned set of observables for the selected T_rx - std::map adjacent_gnss_synchro_map; // container for the previous observable values to interpolate - // shift channels history to match the reference TOW - for (unsigned int i = 0; i < d_nchannels; i++) - { - gnss_synchro_deque_iter = std::lower_bound(d_gnss_synchro_history_queue[i].cbegin(), - d_gnss_synchro_history_queue[i].cend(), - T_rx_s, - Hybrid_valueCompare_gnss_synchro_receiver_time); - if (gnss_synchro_deque_iter != d_gnss_synchro_history_queue[i].cend()) - { - if (gnss_synchro_deque_iter->Flag_valid_word == true) - { - double T_rx_channel = static_cast(gnss_synchro_deque_iter->Tracking_sample_counter) / static_cast(gnss_synchro_deque_iter->fs); - double delta_T_rx_s = T_rx_channel - T_rx_s; - - // check that T_rx difference is less than a threshold (the correlation interval) - if (delta_T_rx_s * 1000.0 < static_cast(gnss_synchro_deque_iter->correlation_length_ms)) - { - // record the word structure in a map for pseudorange computation - // save the previous observable - int distance = std::distance(d_gnss_synchro_history_queue[i].cbegin(), gnss_synchro_deque_iter); - if (distance > 0) - { - if (d_gnss_synchro_history_queue[i].at(distance - 1).Flag_valid_word) - { - double T_rx_channel_prev = static_cast(d_gnss_synchro_history_queue[i].at(distance - 1).Tracking_sample_counter) / static_cast(gnss_synchro_deque_iter->fs); - double delta_T_rx_s_prev = T_rx_channel_prev - T_rx_s; - if (fabs(delta_T_rx_s_prev) < fabs(delta_T_rx_s)) - { - realigned_gnss_synchro_map.insert(std::pair(d_gnss_synchro_history_queue[i].at(distance - 1).Channel_ID, - d_gnss_synchro_history_queue[i].at(distance - 1))); - adjacent_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); - } - else - { - realigned_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); - adjacent_gnss_synchro_map.insert(std::pair(d_gnss_synchro_history_queue[i].at(distance - 1).Channel_ID, - d_gnss_synchro_history_queue[i].at(distance - 1))); - } - } - } - else - { - realigned_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); - } - - } - } - } - } - - if(!realigned_gnss_synchro_map.empty()) - { - /* - * 2.1 Use CURRENT set of measurements and find the nearest satellite - * common RX time algorithm - */ - // what is the most recent symbol TOW in the current set? -> this will be the reference symbol - gnss_synchro_map_iter = max_element(realigned_gnss_synchro_map.cbegin(), - realigned_gnss_synchro_map.cend(), - Hybrid_pairCompare_gnss_synchro_d_TOW); - double ref_fs_hz = static_cast(gnss_synchro_map_iter->second.fs); - - // compute interpolated TOW value at T_rx_s - int ref_channel_key = gnss_synchro_map_iter->second.Channel_ID; - Gnss_Synchro adj_obs = adjacent_gnss_synchro_map.at(ref_channel_key); - double ref_adj_T_rx_s = static_cast(adj_obs.Tracking_sample_counter) / ref_fs_hz + adj_obs.Code_phase_samples / ref_fs_hz; - - double d_TOW_reference = gnss_synchro_map_iter->second.TOW_at_current_symbol_s; - double d_ref_T_rx_s = static_cast(gnss_synchro_map_iter->second.Tracking_sample_counter) / ref_fs_hz + gnss_synchro_map_iter->second.Code_phase_samples / ref_fs_hz; - - double selected_T_rx_s = T_rx_s; - // two points linear interpolation using adjacent (adj) values: y=y1+(x-x1)*(y2-y1)/(x2-x1) - double ref_TOW_at_T_rx_s = adj_obs.TOW_at_current_symbol_s + - (selected_T_rx_s - ref_adj_T_rx_s) * (d_TOW_reference - adj_obs.TOW_at_current_symbol_s) / (d_ref_T_rx_s - ref_adj_T_rx_s); - - // Now compute RX time differences due to the PRN alignment in the correlators - double traveltime_ms; - double pseudorange_m; - double channel_T_rx_s; - double channel_fs_hz; - double channel_TOW_s; - for(gnss_synchro_map_iter = realigned_gnss_synchro_map.cbegin(); gnss_synchro_map_iter != realigned_gnss_synchro_map.cend(); gnss_synchro_map_iter++) - { - channel_fs_hz = static_cast(gnss_synchro_map_iter->second.fs); - channel_TOW_s = gnss_synchro_map_iter->second.TOW_at_current_symbol_s; - channel_T_rx_s = static_cast(gnss_synchro_map_iter->second.Tracking_sample_counter) / channel_fs_hz + gnss_synchro_map_iter->second.Code_phase_samples / channel_fs_hz; - // compute interpolated observation values - // two points linear interpolation using adjacent (adj) values: y=y1+(x-x1)*(y2-y1)/(x2-x1) - // TOW at the selected receiver time T_rx_s - int element_key = gnss_synchro_map_iter->second.Channel_ID; - adj_obs = adjacent_gnss_synchro_map.at(element_key); - - double adj_T_rx_s = static_cast(adj_obs.Tracking_sample_counter) / channel_fs_hz + adj_obs.Code_phase_samples / channel_fs_hz; - - double channel_TOW_at_T_rx_s = adj_obs.TOW_at_current_symbol_s + (selected_T_rx_s - adj_T_rx_s) * (channel_TOW_s - adj_obs.TOW_at_current_symbol_s) / (channel_T_rx_s - adj_T_rx_s); - - // Doppler and Accumulated carrier phase - double Carrier_phase_lin_rads = adj_obs.Carrier_phase_rads + (selected_T_rx_s - adj_T_rx_s) * (gnss_synchro_map_iter->second.Carrier_phase_rads - adj_obs.Carrier_phase_rads) / (channel_T_rx_s - adj_T_rx_s); - double Carrier_Doppler_lin_hz = adj_obs.Carrier_Doppler_hz + (selected_T_rx_s - adj_T_rx_s) * (gnss_synchro_map_iter->second.Carrier_Doppler_hz - adj_obs.Carrier_Doppler_hz) / (channel_T_rx_s - adj_T_rx_s); - - // compute the pseudorange (no rx time offset correction) - traveltime_ms = (ref_TOW_at_T_rx_s - channel_TOW_at_T_rx_s) * 1000.0 + GPS_STARTOFFSET_ms; - // convert to meters - pseudorange_m = traveltime_ms * GPS_C_m_ms; // [m] - // update the pseudorange object - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID] = gnss_synchro_map_iter->second; - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Pseudorange_m = pseudorange_m; - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Flag_valid_pseudorange = true; - // Save the estimated RX time (no RX clock offset correction yet!) - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].RX_time = ref_TOW_at_T_rx_s + GPS_STARTOFFSET_ms / 1000.0; - - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Carrier_phase_rads = Carrier_phase_lin_rads; - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Carrier_Doppler_hz = Carrier_Doppler_lin_hz; - } - - if(d_dump == true) - { - // MULTIPLEXED FILE RECORDING - Record results to file - try + double T_rx_channel_prev = static_cast(d_gnss_synchro_history_queue[i].at(distance - 1).Tracking_sample_counter) / static_cast(gnss_synchro_deque_iter->fs); + double delta_T_rx_s_prev = T_rx_channel_prev - T_rx_s; + if (fabs(delta_T_rx_s_prev) < fabs(delta_T_rx_s)) { - double tmp_double; - for (unsigned int i = 0; i < d_nchannels; i++) - { - tmp_double = current_gnss_synchro[i].RX_time; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = current_gnss_synchro[i].TOW_at_current_symbol_s; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = current_gnss_synchro[i].Carrier_Doppler_hz; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = current_gnss_synchro[i].Carrier_phase_rads / GPS_TWO_PI; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = current_gnss_synchro[i].Pseudorange_m; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = current_gnss_synchro[i].PRN; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = static_cast(current_gnss_synchro[i].Flag_valid_pseudorange); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - } + realigned_gnss_synchro_map.insert(std::pair(d_gnss_synchro_history_queue[i].at(distance - 1).Channel_ID, + d_gnss_synchro_history_queue[i].at(distance - 1))); + adjacent_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); } - catch (const std::ifstream::failure& e) + else { - LOG(WARNING) << "Exception writing observables dump file " << e.what(); + realigned_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); + adjacent_gnss_synchro_map.insert(std::pair(d_gnss_synchro_history_queue[i].at(distance - 1).Channel_ID, + d_gnss_synchro_history_queue[i].at(distance - 1))); } } + } + else + { + realigned_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); + } - for (unsigned int i = 0; i < d_nchannels; i++) - { - out[i][n_outputs] = current_gnss_synchro[i]; - } - - n_outputs++; - } - - // Move RX time - T_rx_s = T_rx_s + T_rx_step_s; - // pop old elements from queue - for (unsigned int i = 0; i < d_nchannels; i++) - { - while (static_cast(d_gnss_synchro_history_queue[i].front().Tracking_sample_counter) / static_cast(d_gnss_synchro_history_queue[i].front().fs) < (T_rx_s - past_history_s)) - { - d_gnss_synchro_history_queue[i].pop_front(); - } } + } } - } while(channel_history_ok == true && noutput_items > n_outputs); + } + + if(!realigned_gnss_synchro_map.empty()) + { + /* + * 2.1 Use CURRENT set of measurements and find the nearest satellite + * common RX time algorithm + */ + // what is the most recent symbol TOW in the current set? -> this will be the reference symbol + gnss_synchro_map_iter = max_element(realigned_gnss_synchro_map.cbegin(), + realigned_gnss_synchro_map.cend(), + Hybrid_pairCompare_gnss_synchro_d_TOW); + double ref_fs_hz = static_cast(gnss_synchro_map_iter->second.fs); + + // compute interpolated TOW value at T_rx_s + int ref_channel_key = gnss_synchro_map_iter->second.Channel_ID; + Gnss_Synchro adj_obs = adjacent_gnss_synchro_map.at(ref_channel_key); + double ref_adj_T_rx_s = static_cast(adj_obs.Tracking_sample_counter) / ref_fs_hz + adj_obs.Code_phase_samples / ref_fs_hz; + + double d_TOW_reference = gnss_synchro_map_iter->second.TOW_at_current_symbol_s; + double d_ref_T_rx_s = static_cast(gnss_synchro_map_iter->second.Tracking_sample_counter) / ref_fs_hz + gnss_synchro_map_iter->second.Code_phase_samples / ref_fs_hz; + + double selected_T_rx_s = T_rx_s; + // two points linear interpolation using adjacent (adj) values: y=y1+(x-x1)*(y2-y1)/(x2-x1) + double ref_TOW_at_T_rx_s = adj_obs.TOW_at_current_symbol_s + + (selected_T_rx_s - ref_adj_T_rx_s) * (d_TOW_reference - adj_obs.TOW_at_current_symbol_s) / (d_ref_T_rx_s - ref_adj_T_rx_s); + + // Now compute RX time differences due to the PRN alignment in the correlators + double traveltime_ms; + double pseudorange_m; + double channel_T_rx_s; + double channel_fs_hz; + double channel_TOW_s; + for(gnss_synchro_map_iter = realigned_gnss_synchro_map.cbegin(); gnss_synchro_map_iter != realigned_gnss_synchro_map.cend(); gnss_synchro_map_iter++) + { + channel_fs_hz = static_cast(gnss_synchro_map_iter->second.fs); + channel_TOW_s = gnss_synchro_map_iter->second.TOW_at_current_symbol_s; + channel_T_rx_s = static_cast(gnss_synchro_map_iter->second.Tracking_sample_counter) / channel_fs_hz + gnss_synchro_map_iter->second.Code_phase_samples / channel_fs_hz; + // compute interpolated observation values + // two points linear interpolation using adjacent (adj) values: y=y1+(x-x1)*(y2-y1)/(x2-x1) + // TOW at the selected receiver time T_rx_s + int element_key = gnss_synchro_map_iter->second.Channel_ID; + adj_obs = adjacent_gnss_synchro_map.at(element_key); + + double adj_T_rx_s = static_cast(adj_obs.Tracking_sample_counter) / channel_fs_hz + adj_obs.Code_phase_samples / channel_fs_hz; + + double channel_TOW_at_T_rx_s = adj_obs.TOW_at_current_symbol_s + (selected_T_rx_s - adj_T_rx_s) * (channel_TOW_s - adj_obs.TOW_at_current_symbol_s) / (channel_T_rx_s - adj_T_rx_s); + + // Doppler and Accumulated carrier phase + double Carrier_phase_lin_rads = adj_obs.Carrier_phase_rads + (selected_T_rx_s - adj_T_rx_s) * (gnss_synchro_map_iter->second.Carrier_phase_rads - adj_obs.Carrier_phase_rads) / (channel_T_rx_s - adj_T_rx_s); + double Carrier_Doppler_lin_hz = adj_obs.Carrier_Doppler_hz + (selected_T_rx_s - adj_T_rx_s) * (gnss_synchro_map_iter->second.Carrier_Doppler_hz - adj_obs.Carrier_Doppler_hz) / (channel_T_rx_s - adj_T_rx_s); + + // compute the pseudorange (no rx time offset correction) + traveltime_ms = (ref_TOW_at_T_rx_s - channel_TOW_at_T_rx_s) * 1000.0 + GPS_STARTOFFSET_ms; + // convert to meters + pseudorange_m = traveltime_ms * GPS_C_m_ms; // [m] + // update the pseudorange object + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID] = gnss_synchro_map_iter->second; + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Pseudorange_m = pseudorange_m; + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Flag_valid_pseudorange = true; + // Save the estimated RX time (no RX clock offset correction yet!) + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].RX_time = ref_TOW_at_T_rx_s + GPS_STARTOFFSET_ms / 1000.0; + + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Carrier_phase_rads = Carrier_phase_lin_rads; + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Carrier_Doppler_hz = Carrier_Doppler_lin_hz; + } + + if(d_dump == true) + { + // MULTIPLEXED FILE RECORDING - Record results to file + try + { + double tmp_double; + for (unsigned int i = 0; i < d_nchannels; i++) + { + tmp_double = current_gnss_synchro[i].RX_time; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = current_gnss_synchro[i].TOW_at_current_symbol_s; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = current_gnss_synchro[i].Carrier_Doppler_hz; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = current_gnss_synchro[i].Carrier_phase_rads / GPS_TWO_PI; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = current_gnss_synchro[i].Pseudorange_m; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = current_gnss_synchro[i].PRN; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = static_cast(current_gnss_synchro[i].Flag_valid_pseudorange); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + } + } + catch (const std::ifstream::failure& e) + { + LOG(WARNING) << "Exception writing observables dump file " << e.what(); + } + } + + for (unsigned int i = 0; i < d_nchannels; i++) + { + out[i][n_outputs] = current_gnss_synchro[i]; + } + + n_outputs++; + } + + // Move RX time + T_rx_s = T_rx_s + T_rx_step_s; + // pop old elements from queue + for (unsigned int i = 0; i < d_nchannels; i++) + { + while (static_cast(d_gnss_synchro_history_queue[i].front().Tracking_sample_counter) / static_cast(d_gnss_synchro_history_queue[i].front().fs) < (T_rx_s - past_history_s)) + { + d_gnss_synchro_history_queue[i].pop_front(); + } + } + } + } while(channel_history_ok == true && noutput_items > n_outputs); // Multi-rate consume! for (unsigned int i = 0; i < d_nchannels; i++) - { - consume(i, n_consume[i]); // which input, how many items - } + { + consume(i, n_consume[i]); // which input, how many items + } return n_outputs; } From 29b8643def49d7d15cd6a632bfd2353745c4bb44 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Fri, 12 Jan 2018 13:15:20 +0100 Subject: [PATCH 33/96] Added Spirent GSS6450 file signal source --- .../signal_source/adapters/CMakeLists.txt | 1 + .../spir_gss6450_file_signal_source.cc | 261 ++++++++++++++++++ .../spir_gss6450_file_signal_source.h | 130 +++++++++ .../gnuradio_blocks/CMakeLists.txt | 1 + .../unpack_spir_gss6450_samples.cc | 75 +++++ .../unpack_spir_gss6450_samples.h | 62 +++++ 6 files changed, 530 insertions(+) create mode 100644 src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc create mode 100644 src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h create mode 100644 src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc create mode 100644 src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index bac9aee3d..3d786bb46 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -139,6 +139,7 @@ set(SIGNAL_SOURCE_ADAPTER_SOURCES file_signal_source.cc gen_signal_source.cc nsr_file_signal_source.cc spir_file_signal_source.cc + spir_gss6450_file_signal_source.cc rtl_tcp_signal_source.cc ${OPT_DRIVER_SOURCES} ) diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc new file mode 100644 index 000000000..6e577810a --- /dev/null +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc @@ -0,0 +1,261 @@ +/*! + * \file spir_file_signal_source.cc + * \brief Implementation of a class that reads signals samples from a SPIR file + * and adapts it to a SignalSourceInterface. + * \author Fran Fabra, 2014 fabra(at)ice.csic.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 not part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "spir_gss6450_file_signal_source.h" +#include +#include +#include +#include +#include +#include +#include +#include "configuration_interface.h" + + +using google::LogMessage; + +DEFINE_string(spir_gss6450_signal_source, "-", + "If defined, path to the file containing the Spirent GSS6450 signal samples (overrides the configuration file)"); + + +SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* configuration, + std::string role, unsigned int in_streams, unsigned int out_streams, gr::msg_queue::sptr queue) : + role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(queue) +{ + std::string default_filename = "../data/my_capture.dat"; + std::string default_dump_filename = "../data/my_capture_dump.dat"; + item_type_ = "int"; + + samples_ = configuration->property(role + ".samples", 0); + sampling_frequency_ = configuration->property(role + ".sampling_frequency", 0); + filename_ = configuration->property(role + ".filename", default_filename); + + // override value with commandline flag, if present + if (FLAGS_spir_gss6450_signal_source.compare("-") != 0) filename_= FLAGS_spir_gss6450_signal_source; + + repeat_ = configuration->property(role + ".repeat", false); + dump_ = configuration->property(role + ".dump", false); + dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + enable_throttle_control_ = configuration->property(role + ".enable_throttle_control", false); + adc_bits_ = configuration->property(role + ".adc_bits", 4); + n_channels_ = configuration->property(role + ".RF_channels", 1); + sel_ch_ = configuration->property(role + ".sel_ch", 1); + item_size_ = sizeof(int); + long bytes_seek = 65536; + double sample_size_byte = static_cast(adc_bits_) / 4.0; + int samples_per_item = 16 / adc_bits_; + + if(sel_ch_ > n_channels_) { LOG(WARNING) << "Invalid RF channel selection"; } + try + { + file_source_ = gr::blocks::file_source::make(item_size_, filename_.c_str(), repeat_); + file_source_->seek(bytes_seek, SEEK_SET); + unpack_ii_ = gr::blocks::packed_to_unpacked_ii::make(2 * adc_bits_, gr::GR_MSB_FIRST); + unpack_spir_ = make_unpack_spir_gss6450_samples(n_channels_, sel_ch_, item_size_); + } + catch (const std::exception &e) + { + std::cerr + << "The receiver was configured to work with a file signal source " + << std::endl + << "but the specified file is unreachable by GNSS-SDR." + << std::endl + << "Please modify your configuration file" + << std::endl + << "and point SignalSource.filename to a valid raw data file. Then:" + << std::endl + << "$ gnss-sdr --config_file=/path/to/my_GNSS_SDR_configuration.conf" + << std::endl + << "Examples of configuration files available at:" + << std::endl + << GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/" + << std::endl; + + LOG(WARNING) << "file_signal_source: Unable to open the samples file " + << filename_.c_str() << ", exiting the program."; + throw(e); + } + + DLOG(INFO) << "file_source(" << file_source_->unique_id() << ")"; + + if(samples_ == 0) // read all file + { + /*! + * BUG workaround: The GNU Radio file source does not stop the receiver after reaching the End of File. + * A possible solution is to compute the file length in samples using file size, excluding the last 100 milliseconds, and enable always the + * valve block + */ + std::ifstream file (filename_.c_str(), std::ios::in | std::ios::binary | std::ios::ate); + std::ifstream::pos_type size; + + if (file.is_open()) + { + size = file.tellg(); + LOG(INFO) << "Total samples in the file= " << floor(static_cast(size) / static_cast(item_size())); + } + else + { + std::cout << "file_signal_source: Unable to open the samples file " << filename_.c_str() << std::endl; + LOG(ERROR) << "file_signal_source: Unable to open the samples file " << filename_.c_str(); + } + std::streamsize ss = std::cout.precision(); + std::cout << std::setprecision(16); + std::cout << "Processing file " << filename_ << ", which contains " << size << " [bytes]" << std::endl; + std::cout.precision (ss); + + if(size > 0) + { + samples_ = floor(static_cast(size - bytes_seek) / (sample_size_byte * static_cast(n_channels_))); + samples_ = samples_- ceil(0.002 * static_cast(sampling_frequency_)); //process all the samples available in the file excluding the last 2 ms + } + } + + CHECK(samples_ > 0) << "File does not contain enough samples to process."; + double signal_duration_s; + signal_duration_s = static_cast(samples_) * ( 1 /static_cast(sampling_frequency_)); + LOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]"; + std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]" << std::endl; + + valve_ = gnss_sdr_make_valve(sizeof(gr_complex), samples_, queue_); + DLOG(INFO) << "valve(" << valve_->unique_id() << ")"; + + if (dump_) + { + sink_ = gr::blocks::file_sink::make(sizeof(gr_complex), dump_filename_.c_str()); + DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")"; + } + + if (enable_throttle_control_) + { + throttle_ = gr::blocks::throttle::make(sizeof(gr_complex), sampling_frequency_); + } + DLOG(INFO) << "File source filename " << filename_; + DLOG(INFO) << "Samples " << samples_; + DLOG(INFO) << "Sampling frequency " << sampling_frequency_; + DLOG(INFO) << "Item type " << item_type_; + DLOG(INFO) << "Item size " << item_size_; + DLOG(INFO) << "Repeat " << repeat_; + DLOG(INFO) << "Dump " << dump_; + DLOG(INFO) << "Dump filename " << dump_filename_; +} + + + + +SpirGSS6450FileSignalSource::~SpirGSS6450FileSignalSource() +{} + + + + +void SpirGSS6450FileSignalSource::connect(gr::top_block_sptr top_block) +{ + if (samples_ > 0) + { + if (enable_throttle_control_) + { + top_block->connect(file_source_, 0, unpack_ii_, 0); + top_block->connect(unpack_ii_, 0, unpack_spir_, 0); + top_block->connect(unpack_spir_, 0, throttle_, 0); + top_block->connect(throttle_, 0, valve_, 0); + } + else + { + top_block->connect(file_source_, 0, unpack_ii_, 0); + top_block->connect(unpack_ii_, 0, unpack_spir_, 0); + top_block->connect(unpack_spir_, 0, valve_, 0); + } + if(dump_) + { + top_block->connect(valve_, 0, sink_, 0); + DLOG(INFO) << "connected valve to file sink"; + } + } + else + { + LOG(WARNING) << "0 samples to read"; + } +} + + + + + + +void SpirGSS6450FileSignalSource::disconnect(gr::top_block_sptr top_block) +{ + if (samples_ > 0) + { + if (enable_throttle_control_) + { + top_block->disconnect(file_source_, 0, unpack_ii_, 0); + top_block->disconnect(unpack_ii_, 0, unpack_spir_, 0); + top_block->disconnect(unpack_spir_, 0, throttle_, 0); + top_block->disconnect(throttle_, 0, valve_, 0); + if (dump_) + { + top_block->disconnect(valve_, 0, sink_, 0); + } + } + else + { + top_block->disconnect(file_source_, 0, unpack_ii_, 0); + top_block->disconnect(unpack_ii_, 0, unpack_spir_, 0); + top_block->disconnect(unpack_spir_, 0, valve_, 0); + if (dump_) + { + top_block->disconnect(valve_, 0, sink_, 0); + } + } + } + else + { + LOG(WARNING) << "Nothing to disconnect"; + } +} + + +gr::basic_block_sptr SpirGSS6450FileSignalSource::get_left_block() +{ + LOG(WARNING) << "Left block of a signal source should not be retrieved"; + return gr::blocks::file_source::sptr(); +} + + +gr::basic_block_sptr SpirGSS6450FileSignalSource::get_right_block() +{ + if(samples_ > 0) { return valve_; } + else + { + if(enable_throttle_control_) { return throttle_; } + else { return unpack_spir_; } + } +} diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h new file mode 100644 index 000000000..346ebdc79 --- /dev/null +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h @@ -0,0 +1,130 @@ +/*! + * \file spir_file_signal_source.h + * \brief Implementation of a class that reads signals samples from a SPIR file + * and adapts it to a SignalSourceInterface. + * \author Fran Fabra, 2014 fabra(at)ice.csic.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 not part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_SPIR_GSS6450_FILE_SIGNAL_SOURCE_H_ +#define GNSS_SDR_SPIR_GSS6450_FILE_SIGNAL_SOURCE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include "gnss_block_interface.h" +#include "gnss_sdr_valve.h" +#include "unpack_spir_gss6450_samples.h" + + +class ConfigurationInterface; + +/*! + * \brief Class that reads signals samples from a file + * and adapts it to a SignalSourceInterface + */ +class SpirGSS6450FileSignalSource: public GNSSBlockInterface +{ +public: + SpirGSS6450FileSignalSource(ConfigurationInterface* configuration, std::string role, + unsigned int in_streams, unsigned int out_streams, gr::msg_queue::sptr queue); + + virtual ~SpirGSS6450FileSignalSource(); + inline std::string role() override + { + return role_; + } + + inline std::string implementation() override + { + return "Spir_GSS6450_File_Signal_Source"; + } + + 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; + + inline std::string filename() const + { + return filename_; + } + + inline std::string item_type() const + { + return item_type_; + } + + inline bool repeat() const + { + return repeat_; + } + + inline long sampling_frequency() const + { + return sampling_frequency_; + } + + inline long samples() const + { + return samples_; + } + +private: + unsigned long long samples_; + long sampling_frequency_; + std::string filename_; + bool repeat_; + bool dump_; + std::string dump_filename_; + std::string role_; + std::string item_type_; + unsigned int in_streams_; + unsigned int out_streams_; + unsigned int adc_bits_; + unsigned int n_channels_; + unsigned int sel_ch_; + gr::blocks::file_source::sptr file_source_; + gr::blocks::packed_to_unpacked_ii::sptr unpack_ii_; + unpack_spir_gss6450_samples_sptr unpack_spir_; + boost::shared_ptr valve_; + gr::blocks::file_sink::sptr sink_; + gr::blocks::throttle::sptr throttle_; + gr::msg_queue::sptr queue_; + size_t item_size_; + bool enable_throttle_control_; +}; + +#endif /*GNSS_SDR_SPIR_GSS6450_FILE_SIGNAL_SOURCE_H_*/ diff --git a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt index 4159321f3..67b9f3162 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt @@ -23,6 +23,7 @@ set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES unpack_intspir_1bit_samples.cc rtl_tcp_signal_source_c.cc unpack_2bit_samples.cc + unpack_spir_gss6450_samples.cc ) include_directories( diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc new file mode 100644 index 000000000..8d7d4e3fc --- /dev/null +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc @@ -0,0 +1,75 @@ +/*! + * \file unpack_intspir_1bit_samples.cc + * + * \brief Unpacks SPIR int samples to NSR 1 bit samples + * \author Fran Fabra fabra (at) ice.csic.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 not part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#include "unpack_spir_gss6450_samples.h" +#include + + + +unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, size_t item_size) +{ + return unpack_spir_gss6450_samples_sptr(new unpack_spir_gss6450_samples(n_chann, sel_ch, item_size)); +} + + +unpack_spir_gss6450_samples::unpack_spir_gss6450_samples( + unsigned int n_chann, unsigned int sel_ch, size_t item_size) : gr::block("unpack_spir_gss6450_samples", + gr::io_signature::make(1, 1, sizeof(int)), + gr::io_signature::make(1, 1, sizeof(gr_complex))) +{ + d_channels = n_chann; + d_sel_ch = sel_ch; + item_size_ = item_size; + ch_processing = 1; +} + +void unpack_spir_gss6450_samples::forecast(int noutput_items, gr_vector_int &ninput_items_required) +{ + ninput_items_required[0] = d_channels * noutput_items; +} + + +unpack_spir_gss6450_samples::~unpack_spir_gss6450_samples() +{} + + +int unpack_spir_gss6450_samples::general_work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const int *in = reinterpret_cast(input_items[0]); + gr_complex *out = reinterpret_cast(output_items[0]); + + + + + return noutput_items; +} diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h new file mode 100644 index 000000000..6e83c88e2 --- /dev/null +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h @@ -0,0 +1,62 @@ +/*! + * \file unpack_intspir_1bit_samples.h + * + * \brief Unpacks SPIR int samples to NSR 1 bit samples + * \author Fran Fabra fabra (at) ice.csic.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 not part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_UNPACK_SPIR_GSS6450_SAMPLES_H +#define GNSS_SDR_UNPACK_SPIR_GSS6450_SAMPLES_H + +#include + +class unpack_spir_gss6450_samples; + +typedef boost::shared_ptr unpack_spir_gss6450_samples_sptr; + +unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, size_t item_size); + + +class unpack_spir_gss6450_samples: public gr::block +{ +public: + int general_work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + ~unpack_spir_gss6450_samples(); + +private: + unsigned int d_channels; + unsigned int d_sel_ch; + unsigned int ch_processing; + size_t item_size_; + friend unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples_sptr(unsigned int n_chann, unsigned int sel_ch, size_t item_size); + unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, size_t item_size); + +}; + +#endif From 282c3d865998ae49e076aea79505175c80d13555 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Tue, 16 Jan 2018 17:20:55 +0100 Subject: [PATCH 34/96] Implement Spirent GSS6450 file signal source --- .../spir_gss6450_file_signal_source.cc | 7 +- .../unpack_spir_gss6450_samples.cc | 111 +++++++++++++++--- .../unpack_spir_gss6450_samples.h | 18 ++- src/core/receiver/gnss_block_factory.cc | 16 +++ 4 files changed, 128 insertions(+), 24 deletions(-) diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc index 6e577810a..ede0abb72 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc @@ -78,8 +78,8 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* { file_source_ = gr::blocks::file_source::make(item_size_, filename_.c_str(), repeat_); file_source_->seek(bytes_seek, SEEK_SET); - unpack_ii_ = gr::blocks::packed_to_unpacked_ii::make(2 * adc_bits_, gr::GR_MSB_FIRST); - unpack_spir_ = make_unpack_spir_gss6450_samples(n_channels_, sel_ch_, item_size_); + unpack_ii_ = gr::blocks::packed_to_unpacked_ii::make(adc_bits_, gr::GR_MSB_FIRST); + unpack_spir_ = make_unpack_spir_gss6450_samples(n_channels_, sel_ch_, samples_per_item, item_size_); } catch (const std::exception &e) { @@ -139,8 +139,7 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* } CHECK(samples_ > 0) << "File does not contain enough samples to process."; - double signal_duration_s; - signal_duration_s = static_cast(samples_) * ( 1 /static_cast(sampling_frequency_)); + double signal_duration_s = static_cast(samples_) * ( 1 /static_cast(sampling_frequency_)); LOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]"; std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]" << std::endl; diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc index 8d7d4e3fc..d8ae66e39 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc @@ -34,14 +34,14 @@ -unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, size_t item_size) +unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size) { - return unpack_spir_gss6450_samples_sptr(new unpack_spir_gss6450_samples(n_chann, sel_ch, item_size)); + return unpack_spir_gss6450_samples_sptr(new unpack_spir_gss6450_samples(n_chann, sel_ch, samp_item, item_size)); } unpack_spir_gss6450_samples::unpack_spir_gss6450_samples( - unsigned int n_chann, unsigned int sel_ch, size_t item_size) : gr::block("unpack_spir_gss6450_samples", + unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size) : gr::block("unpack_spir_gss6450_samples", gr::io_signature::make(1, 1, sizeof(int)), gr::io_signature::make(1, 1, sizeof(gr_complex))) { @@ -49,27 +49,108 @@ unpack_spir_gss6450_samples::unpack_spir_gss6450_samples( d_sel_ch = sel_ch; item_size_ = item_size; ch_processing = 1; -} - -void unpack_spir_gss6450_samples::forecast(int noutput_items, gr_vector_int &ninput_items_required) -{ - ninput_items_required[0] = d_channels * noutput_items; + d_samp_item = samp_item; + samp_frame = 0; + adc_bits = 16 / d_samp_item; + i_ = true; + new_sample = false; + i_data = 0; + q_data = 0; } unpack_spir_gss6450_samples::~unpack_spir_gss6450_samples() {} +void unpack_spir_gss6450_samples::process_sample(gr_complex* out) +{ + gr_complex result = gr_complex(0.5, 0.5); + compute_two_complement(i_data); + compute_two_complement(q_data); + result += gr_complex(static_cast(i_data), static_cast(q_data)); + *out = result; +} int unpack_spir_gss6450_samples::general_work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - const int *in = reinterpret_cast(input_items[0]); - gr_complex *out = reinterpret_cast(output_items[0]); - - - - - return noutput_items; + const int* in = reinterpret_cast(input_items[0]); + gr_complex* out = reinterpret_cast(output_items[0]); + int samples_produced = 0; + for(int i = 0; i < noutput_items; i++) + { + if(ch_processing == d_sel_ch) + { + if(i_) + { + i_data = in[i]; + swap_data(i_data); + i_ = false; + } + else + { + q_data = in[i]; + swap_data(q_data); + i_ = true; + process_sample(out); + out++; + samples_produced++; + new_sample = true; + } + } + else + { + if(i_) { i_ = false;} + else + { + i_ = true; + new_sample = true; + } + } + if(new_sample) + { + new_sample = false; + samp_frame++; + if(samp_frame == d_samp_item) + { + samp_frame = 0; + ch_processing++; + if(ch_processing > d_channels) { ch_processing = 1; } + } + } + } + consume_each(noutput_items); + return samples_produced; +} + +void unpack_spir_gss6450_samples::swap_data(int& data) +{ + int result = 0; + int aux = data; + int mask = 1; + for (int i = 0; i < adc_bits; i++) + { + result = result << 1; + result += (aux & mask); + aux = aux >> 1; + } + data = result; +} + +void unpack_spir_gss6450_samples::compute_two_complement(int& data) +{ + int result = 0; + int mask = 1; + for(int i = 0; i < (adc_bits - 1); i++) + { + result = result << 1; + result += (data >> i) & mask; + } + if((data >> (adc_bits - 1)) == 1) + { + if(adc_bits == 2) { result -= 2; } + else { result -= 8; } + } + data = result; } diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h index 6e83c88e2..1077fcc73 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h @@ -37,7 +37,7 @@ class unpack_spir_gss6450_samples; typedef boost::shared_ptr unpack_spir_gss6450_samples_sptr; -unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, size_t item_size); +unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size); class unpack_spir_gss6450_samples: public gr::block @@ -46,17 +46,25 @@ public: int general_work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); - void forecast(int noutput_items, gr_vector_int &ninput_items_required); + friend unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples_sptr(unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size); + unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size); ~unpack_spir_gss6450_samples(); private: unsigned int d_channels; unsigned int d_sel_ch; unsigned int ch_processing; + int d_samp_item; + int samp_frame; + int adc_bits; size_t item_size_; - friend unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples_sptr(unsigned int n_chann, unsigned int sel_ch, size_t item_size); - unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, size_t item_size); - + void process_sample(gr_complex* out); + void swap_data(int& data); + void compute_two_complement(int& data); + bool i_; + bool new_sample; + int i_data; + int q_data; }; #endif diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index bdf34dc22..322577e62 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -48,6 +48,7 @@ #include "nsr_file_signal_source.h" #include "two_bit_cpx_file_signal_source.h" #include "spir_file_signal_source.h" +#include "spir_gss6450_file_signal_source.h" #include "rtl_tcp_signal_source.h" #include "two_bit_packed_file_signal_source.h" #include "channel.h" @@ -864,6 +865,21 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams, queue)); block = std::move(block_); + } + catch (const std::exception &e) + { + std::cout << "GNSS-SDR program ended." << std::endl; + exit(1); + } + } + else if (implementation.compare("Spir_GSS6450_File_Signal_Source") == 0) + { + try + { + std::unique_ptr block_(new SpirGSS6450FileSignalSource(configuration.get(), role, in_streams, + out_streams, queue)); + block = std::move(block_); + } catch (const std::exception &e) { From 6af85275182c9a31062c35f0889d324f19776d49 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 16 Jan 2018 23:10:04 +0100 Subject: [PATCH 35/96] Add block identifier to Galileo satellites launched on Dec. 12, 2017 --- src/core/system_parameters/gnss_satellite.cc | 34 +++++++++++++------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/core/system_parameters/gnss_satellite.cc b/src/core/system_parameters/gnss_satellite.cc index 2e2e18f00..a146b3451 100644 --- a/src/core/system_parameters/gnss_satellite.cc +++ b/src/core/system_parameters/gnss_satellite.cc @@ -492,34 +492,34 @@ std::string Gnss_Satellite::what_block(const std::string& system_, unsigned int switch ( PRN_ ) { case 1: - block_ = std::string("FOC-FM10"); // Galileo Full Operational Capability (FOC) satellite FM10 / GSAT-0210, launched on May 24, 2016 + block_ = std::string("FOC-FM10"); // Galileo Full Operational Capability (FOC) satellite FM10 / GSAT-0210, launched on May 24, 2016. break; case 2: - block_ = std::string("FOC-FM11"); // Galileo Full Operational Capability (FOC) satellite FM11 / GSAT-0211, launched on May 24, 2016 + block_ = std::string("FOC-FM11"); // Galileo Full Operational Capability (FOC) satellite FM11 / GSAT-0211, launched on May 24, 2016. break; case 3: - block_ = std::string("FOC-FM12"); // Galileo Full Operational Capability (FOC) satellite FM12 / GSAT-0212, launched on November 17, 2016 + block_ = std::string("FOC-FM12"); // Galileo Full Operational Capability (FOC) satellite FM12 / GSAT-0212, launched on November 17, 2016. break; case 4: - block_ = std::string("FOC-FM13"); // Galileo Full Operational Capability (FOC) satellite FM13 / GSAT-0213, launched on November 17, 2016 + block_ = std::string("FOC-FM13"); // Galileo Full Operational Capability (FOC) satellite FM13 / GSAT-0213, launched on November 17, 2016. break; case 5: - block_ = std::string("FOC-FM14"); // Galileo Full Operational Capability (FOC) satellite FM14 / GSAT-0214, launched on November 17, 2016 + block_ = std::string("FOC-FM14"); // Galileo Full Operational Capability (FOC) satellite FM14 / GSAT-0214, launched on November 17, 2016. break; case 7: - block_ = std::string("FOC-FM7"); // Galileo Full Operational Capability (FOC) satellite FM7 / GSAT-0207, launched on November 17, 2016 + block_ = std::string("FOC-FM7"); // Galileo Full Operational Capability (FOC) satellite FM7 / GSAT-0207, launched on November 17, 2016. break; case 8: - block_ = std::string("FOC-FM8"); // Galileo Full Operational Capability (FOC) satellite FM8 / GSAT0208, launched on December 17, 2015 + block_ = std::string("FOC-FM8"); // Galileo Full Operational Capability (FOC) satellite FM8 / GSAT0208, launched on December 17, 2015. break; case 9: - block_ = std::string("FOC-FM9"); // Galileo Full Operational Capability (FOC) satellite FM9 / GSAT0209, launched on December 17, 2015 + block_ = std::string("FOC-FM9"); // Galileo Full Operational Capability (FOC) satellite FM9 / GSAT0209, launched on December 17, 2015. break; case 11 : - block_ = std::string("IOV-PFM"); // PFM, the ProtoFlight Model / GSAT0101, launched from French Guiana at 10:30 GMT on October 21, 2011 + block_ = std::string("IOV-PFM"); // PFM, the ProtoFlight Model / GSAT0101, launched from French Guiana at 10:30 GMT on October 21, 2011. break; case 12 : - block_ = std::string("IOV-FM2**"); // Galileo In-Orbit Validation (IOV) satellite FM2 (Flight Model 2) also known as GSAT0102, from French Guiana at 10:30 GMT on October 21, 2011 + block_ = std::string("IOV-FM2**"); // Galileo In-Orbit Validation (IOV) satellite FM2 (Flight Model 2) also known as GSAT0102, from French Guiana at 10:30 GMT on October 21, 2011. break; case 14 : block_ = std::string("FOC-FM2*"); // Galileo Full Operational Capability (FOC) satellite FM2 / GSAT0202, launched into incorrect orbit on August 22, 2014. Moved to usable orbit in March, 2015. @@ -528,23 +528,35 @@ std::string Gnss_Satellite::what_block(const std::string& system_, unsigned int block_ = std::string("FOC-FM1*"); // Galileo Full Operational Capability (FOC) satellite FM1 / GSAT0201, launched into incorrect orbit on August 22, 2014. Moved to usable orbit in December, 2014. break; case 19 : - block_ = std::string("IOV-FM3"); // Galileo In-Orbit Validation (IOV) satellite FM3 (Flight Model 3) / GSAT0103, launched on October 12, 2012 + block_ = std::string("IOV-FM3"); // Galileo In-Orbit Validation (IOV) satellite FM3 (Flight Model 3) / GSAT0103, launched on October 12, 2012. break; case 20 : block_ = std::string("IOV-FM4**"); // Galileo In-Orbit Validation (IOV) satellite FM4 (Flight Model 4) / GSAT0104, launched on October 12, 2012. Partially unavailable: Payload power problem beginning May 27, 2014 led to permanent loss of E5 and E6 transmissions, E1 transmission restored. break; + case 21 : + block_ = std::string("FOC-FM15"); // Galileo Full Operational Capability (FOC) satellite FM15 / GSAT0215, launched on Dec. 12, 2017. + break; case 22 : block_ = std::string("FOC-FM4"); // Galileo Full Operational Capability (FOC) satellite FM4 / GSAT0204, launched on March 27, 2015. break; case 24 : block_ = std::string("FOC-FM5"); // Galileo Full Operational Capability (FOC) satellite FM5 / GSAT0205, launched on Sept. 11, 2015. break; + case 25 : + block_ = std::string("FOC-FM16"); // Galileo Full Operational Capability (FOC) satellite FM16 / GSAT0216, launched on Dec. 12, 2017. + break; case 26 : block_ = std::string("FOC-FM3"); // Galileo Full Operational Capability (FOC) satellite FM3 / GSAT0203, launched on March 27, 2015. break; + case 27 : + block_ = std::string("FOC-FM17"); // Galileo Full Operational Capability (FOC) satellite FM17 / GSAT0217, launched on Dec. 12, 2017. + break; case 30 : block_ = std::string("FOC-FM6"); // Galileo Full Operational Capability (FOC) satellite FM6 / GSAT0206, launched on Sept. 11, 2015. break; + case 31 : + block_ = std::string("FOC-FM18"); // Galileo Full Operational Capability (FOC) satellite FM18 / GSAT0218, launched on Dec. 12, 2017. + break; default: block_ = std::string("Unknown(Simulated)"); } From 27baa7e45db5c4b74077c57d06f3c87295e875da Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 17 Jan 2018 08:42:50 +0100 Subject: [PATCH 36/96] Apply coding style --- .../galileo_e1_dll_pll_veml_tracking.cc | 19 +- .../galileo_e1_dll_pll_veml_tracking_cc.cc | 863 +++++++++--------- .../gps_l5i_dll_pll_tracking_cc.cc | 12 +- 3 files changed, 457 insertions(+), 437 deletions(-) diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc index b47e26a68..3289b3ecf 100755 --- a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc @@ -81,7 +81,7 @@ GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.15); very_early_late_space_narrow_chips = configuration->property(role + ".very_early_late_space_narrow_chips", 0.6); - bool track_pilot=configuration->property(role + ".track_pilot", false); + bool track_pilot = configuration->property(role + ".track_pilot", false); std::string default_dump_filename = "./track_ch"; dump_filename = configuration->property(role + ".dump_filename", @@ -108,16 +108,6 @@ GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( very_early_late_space_narrow_chips, extend_correlation_symbols, track_pilot); -// tracking_ = galileo_e1_dll_pll_veml_make_tracking_cc( -// f_if, -// fs_in, -// vector_length, -// dump, -// dump_filename, -// pll_bw_hz, -// dll_bw_hz, -// early_late_space_chips, -// very_early_late_space_chips); } else { @@ -130,14 +120,17 @@ GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( DLOG(INFO) << "tracking(" << tracking_->unique_id() << ")"; } + GalileoE1DllPllVemlTracking::~GalileoE1DllPllVemlTracking() {} + void GalileoE1DllPllVemlTracking::start_tracking() { tracking_->start_tracking(); } + /* * Set tracking channel unique ID */ @@ -153,23 +146,27 @@ void GalileoE1DllPllVemlTracking::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) tracking_->set_gnss_synchro(p_gnss_synchro); } + void GalileoE1DllPllVemlTracking::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 GalileoE1DllPllVemlTracking::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 GalileoE1DllPllVemlTracking::get_left_block() { return tracking_; } + gr::basic_block_sptr GalileoE1DllPllVemlTracking::get_right_block() { return tracking_; diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc index cd6b9764c..0fd20887b 100755 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc @@ -82,30 +82,30 @@ galileo_e1_dll_pll_veml_make_tracking_cc( bool track_pilot) { return galileo_e1_dll_pll_veml_tracking_cc_sptr(new galileo_e1_dll_pll_veml_tracking_cc(if_freq, - fs_in, - vector_length, - dump, - dump_filename, - pll_bw_hz, - dll_bw_hz, - pll_bw_narrow_hz, - dll_bw_narrow_hz, - early_late_space_chips, - very_early_late_space_chips, - early_late_space_narrow_chips, - very_early_late_space_narrow_chips, - extend_correlation_symbols, - track_pilot)); + fs_in, + vector_length, + dump, + dump_filename, + pll_bw_hz, + dll_bw_hz, + pll_bw_narrow_hz, + dll_bw_narrow_hz, + early_late_space_chips, + very_early_late_space_chips, + early_late_space_narrow_chips, + very_early_late_space_narrow_chips, + extend_correlation_symbols, + track_pilot)); } void galileo_e1_dll_pll_veml_tracking_cc::forecast (int noutput_items, - gr_vector_int &ninput_items_required) + gr_vector_int &ninput_items_required) { if (noutput_items != 0) - { - ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call - } + { + ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call + } } @@ -125,8 +125,8 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc( float very_early_late_space_narrow_chips, int extend_correlation_symbols, bool track_pilot): - gr::block("galileo_e1_dll_pll_veml_tracking_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) + gr::block("galileo_e1_dll_pll_veml_tracking_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { // Telemetry bit synchronization message port input this->message_port_register_in(pmt::mp("preamble_timestamp_s")); @@ -146,10 +146,10 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc( // Initialize tracking ========================================== // Set bandwidth of code and carrier loop filters - d_dll_bw_hz=dll_bw_hz; - d_pll_bw_hz=pll_bw_hz; - d_dll_bw_narrow_hz=dll_bw_narrow_hz; - d_pll_bw_narrow_hz=pll_bw_narrow_hz; + d_dll_bw_hz = dll_bw_hz; + d_pll_bw_hz = pll_bw_hz; + d_dll_bw_narrow_hz = dll_bw_narrow_hz; + d_pll_bw_narrow_hz = pll_bw_narrow_hz; d_code_loop_filter.set_DLL_BW(d_dll_bw_hz); d_carrier_loop_filter.set_PLL_BW(d_pll_bw_hz); @@ -168,9 +168,9 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc( d_n_correlator_taps = 5; // Very-Early, Early, Prompt, Late, Very-Late d_correlator_outs = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment())); for (int n = 0; n < d_n_correlator_taps; n++) - { - d_correlator_outs[n] = gr_complex(0,0); - } + { + d_correlator_outs[n] = gr_complex(0,0); + } // map memory pointers of correlator outputs d_Very_Early = &d_correlator_outs[0]; d_Early = &d_correlator_outs[1]; @@ -189,29 +189,33 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc( d_correlation_length_samples = d_vector_length; multicorrelator_cpu.init(2 * d_correlation_length_samples, d_n_correlator_taps); - d_extend_correlation_symbols=extend_correlation_symbols; + d_extend_correlation_symbols = extend_correlation_symbols; // Enable Data component prompt correlator (slave to Pilot prompt) if tracking uses Pilot signal - d_track_pilot=track_pilot; + d_track_pilot = track_pilot; if (d_track_pilot) - { - //extended integration control - if (d_extend_correlation_symbols>1) { - d_enable_extended_integration=true; - }else{ - d_enable_extended_integration=false; + //extended integration control + if (d_extend_correlation_symbols > 1) + { + d_enable_extended_integration = true; + } + else + { + d_enable_extended_integration = false; + } + //Extra correlator for the data component + d_local_code_data_shift_chips = static_cast(volk_gnsssdr_malloc(sizeof(float), volk_gnsssdr_get_alignment())); + d_local_code_data_shift_chips[0] = 0.0; + correlator_data_cpu.init(2 * d_correlation_length_samples, 1); + d_Prompt_Data = static_cast(volk_gnsssdr_malloc(sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_Prompt_Data[0] = gr_complex(0,0); + d_data_code = static_cast(volk_gnsssdr_malloc((2 * Galileo_E1_B_CODE_LENGTH_CHIPS) * sizeof(float), volk_gnsssdr_get_alignment())); + } + else + { + // Disable extended integration if data component tracking is selected + d_enable_extended_integration = false; } - //Extra correlator for the data component - d_local_code_data_shift_chips=static_cast(volk_gnsssdr_malloc(sizeof(float), volk_gnsssdr_get_alignment())); - d_local_code_data_shift_chips[0]=0.0; - correlator_data_cpu.init(2 * d_correlation_length_samples, 1); - d_Prompt_Data = static_cast(volk_gnsssdr_malloc(sizeof(gr_complex), volk_gnsssdr_get_alignment())); - d_Prompt_Data[0] = gr_complex(0,0); - d_data_code = static_cast(volk_gnsssdr_malloc((2 * Galileo_E1_B_CODE_LENGTH_CHIPS) * sizeof(float), volk_gnsssdr_get_alignment())); - }else{ - // Disable extended integration if data component tracking is selected - d_enable_extended_integration=false; - } //--- Initializations ------------------------------ // Initial code frequency basis of NCO @@ -247,7 +251,7 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc( d_carrier_doppler_hz = 0.0; d_acc_carrier_phase_rad = 0.0; - d_state=0;// intial state: stanby + d_state = 0;// intial state: stanby } @@ -287,9 +291,9 @@ void galileo_e1_dll_pll_veml_tracking_cc::start_tracking() double corrected_acq_phase_samples, delay_correction_samples; corrected_acq_phase_samples = fmod((d_acq_code_phase_samples + T_prn_diff_seconds * N_prn_diff * static_cast(d_fs_in)), T_prn_true_samples); if (corrected_acq_phase_samples < 0) - { - corrected_acq_phase_samples = T_prn_mod_samples + corrected_acq_phase_samples; - } + { + corrected_acq_phase_samples = T_prn_mod_samples + corrected_acq_phase_samples; + } delay_correction_samples = d_acq_code_phase_samples - corrected_acq_phase_samples; d_acq_code_phase_samples = corrected_acq_phase_samples; @@ -301,40 +305,41 @@ void galileo_e1_dll_pll_veml_tracking_cc::start_tracking() d_carrier_loop_filter.initialize(); // initialize the carrier filter d_code_loop_filter.initialize(); // initialize the code filter - if (d_track_pilot) - { - char pilot_signal[3]="1C"; - galileo_e1_code_gen_float_sampled(d_tracking_code, - pilot_signal, - false, - d_acquisition_gnss_synchro->PRN, - Galileo_E1_CODE_CHIP_RATE_HZ, - 0); - galileo_e1_code_gen_float_sampled(d_data_code, - d_acquisition_gnss_synchro->Signal, - false, - d_acquisition_gnss_synchro->PRN, - Galileo_E1_CODE_CHIP_RATE_HZ, - 0); - d_Prompt_Data[0]=gr_complex(0,0); //clean data correlator output - correlator_data_cpu.set_local_code_and_taps(static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS), - d_data_code, - d_local_code_shift_chips); - }else{ - galileo_e1_code_gen_float_sampled(d_tracking_code, - d_acquisition_gnss_synchro->Signal, - false, - d_acquisition_gnss_synchro->PRN, - Galileo_E1_CODE_CHIP_RATE_HZ, - 0); - } + { + char pilot_signal[3] = "1C"; + galileo_e1_code_gen_float_sampled(d_tracking_code, + pilot_signal, + false, + d_acquisition_gnss_synchro->PRN, + Galileo_E1_CODE_CHIP_RATE_HZ, + 0); + galileo_e1_code_gen_float_sampled(d_data_code, + d_acquisition_gnss_synchro->Signal, + false, + d_acquisition_gnss_synchro->PRN, + Galileo_E1_CODE_CHIP_RATE_HZ, + 0); + d_Prompt_Data[0] = gr_complex(0,0); //clean data correlator output + correlator_data_cpu.set_local_code_and_taps(static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS), + d_data_code, + d_local_code_shift_chips); + } + else + { + galileo_e1_code_gen_float_sampled(d_tracking_code, + d_acquisition_gnss_synchro->Signal, + false, + d_acquisition_gnss_synchro->PRN, + Galileo_E1_CODE_CHIP_RATE_HZ, + 0); + } multicorrelator_cpu.set_local_code_and_taps(static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS), d_tracking_code, d_local_code_shift_chips); for (int n = 0; n < d_n_correlator_taps; n++) - { - d_correlator_outs[n] = gr_complex(0,0); - } + { + d_correlator_outs[n] = gr_complex(0,0); + } d_carrier_lock_fail_counter = 0; d_rem_code_phase_samples = 0; @@ -352,139 +357,144 @@ void galileo_e1_dll_pll_veml_tracking_cc::start_tracking() LOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel; // enable tracking pull-in - d_state=1; + d_state = 1; LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz - << " Code Phase correction [samples]=" << delay_correction_samples - << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples; - - + << " Code Phase correction [samples]=" << delay_correction_samples + << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples; } galileo_e1_dll_pll_veml_tracking_cc::~galileo_e1_dll_pll_veml_tracking_cc() { if (d_dump_file.is_open()) - { - try { - d_dump_file.close(); + try + { + d_dump_file.close(); + } + catch(const std::exception & ex) + { + LOG(WARNING) << "Exception in destructor " << ex.what(); + } } - catch(const std::exception & ex) - { - LOG(WARNING) << "Exception in destructor " << ex.what(); - } - } if(d_dump) - { - if(d_channel == 0) { - std::cout << "Writing .mat files ..."; + if(d_channel == 0) + { + std::cout << "Writing .mat files ..."; + } + galileo_e1_dll_pll_veml_tracking_cc::save_matfile(); + if(d_channel == 0) + { + std::cout << " done." << std::endl; + } } - galileo_e1_dll_pll_veml_tracking_cc::save_matfile(); - if(d_channel == 0) - { - std::cout << " done." << std::endl; - } - } try { - volk_gnsssdr_free(d_local_code_shift_chips); - volk_gnsssdr_free(d_correlator_outs); - volk_gnsssdr_free(d_tracking_code); - if (d_track_pilot) - { - volk_gnsssdr_free(d_Prompt_Data); - volk_gnsssdr_free(d_data_code); - volk_gnsssdr_free(d_local_code_data_shift_chips); - correlator_data_cpu.free(); - } - delete[] d_Prompt_buffer; - multicorrelator_cpu.free(); + volk_gnsssdr_free(d_local_code_shift_chips); + volk_gnsssdr_free(d_correlator_outs); + volk_gnsssdr_free(d_tracking_code); + if (d_track_pilot) + { + volk_gnsssdr_free(d_Prompt_Data); + volk_gnsssdr_free(d_data_code); + volk_gnsssdr_free(d_local_code_data_shift_chips); + correlator_data_cpu.free(); + } + delete[] d_Prompt_buffer; + multicorrelator_cpu.free(); } catch(const std::exception & ex) { - LOG(WARNING) << "Exception in destructor " << ex.what(); + LOG(WARNING) << "Exception in destructor " << ex.what(); } } + bool galileo_e1_dll_pll_veml_tracking_cc::acquire_secondary() { //******* preamble correlation ******** - int corr_value=0; + int corr_value = 0; for (unsigned int i = 0; i < Galileo_E1_C_SECONDARY_CODE_LENGTH; i++) - { - if (d_Prompt_buffer_deque.at(i).real() < 0) // symbols clipping { - if (Galileo_E1_C_SECONDARY_CODE.at(i) == '0') - { - corr_value++; - } + if (d_Prompt_buffer_deque.at(i).real() < 0) // symbols clipping + { + if (Galileo_E1_C_SECONDARY_CODE.at(i) == '0') + { + corr_value++; + } + else + { + corr_value--; + } + } else - { - corr_value--; - } + { + if (Galileo_E1_C_SECONDARY_CODE.at(i) == '0') + { + corr_value--; + } + else + { + corr_value++; + } + } } - else - { - if (Galileo_E1_C_SECONDARY_CODE.at(i) == '0') - { - corr_value--; - } - else - { - corr_value++; - } - } - } if (abs(corr_value) == Galileo_E1_C_SECONDARY_CODE_LENGTH) - { - return true; - }else - { - return false; - } + { + return true; + } + else + { + return false; + } } + bool galileo_e1_dll_pll_veml_tracking_cc::cn0_and_tracking_lock_status() { // ####### CN0 ESTIMATION AND LOCK DETECTORS ###### if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES) - { - // fill buffer with prompt correlator output values - d_Prompt_buffer[d_cn0_estimation_counter] = d_P_accu; - d_cn0_estimation_counter++; - return true; - } - else - { - d_cn0_estimation_counter = 0; - // Code lock indicator - d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, Galileo_E1_B_CODE_LENGTH_CHIPS); - // Carrier lock indicator - d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES); - // Loss of lock detection - if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < MINIMUM_VALID_CN0) { - d_carrier_lock_fail_counter++; - } - else - { - if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--; - } - if (d_carrier_lock_fail_counter > MAXIMUM_LOCK_FAIL_COUNTER) - { - std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; - LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; - this->message_port_pub(pmt::mp("events"), pmt::from_long(3));//3 -> loss of lock - d_carrier_lock_fail_counter = 0; - return false; - }else{ + // fill buffer with prompt correlator output values + d_Prompt_buffer[d_cn0_estimation_counter] = d_P_accu; + d_cn0_estimation_counter++; return true; } - } + else + { + d_cn0_estimation_counter = 0; + // Code lock indicator + d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, Galileo_E1_B_CODE_LENGTH_CHIPS); + // Carrier lock indicator + d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES); + // Loss of lock detection + if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < MINIMUM_VALID_CN0) + { + d_carrier_lock_fail_counter++; + } + else + { + if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--; + } + if (d_carrier_lock_fail_counter > MAXIMUM_LOCK_FAIL_COUNTER) + { + std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; + LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; + this->message_port_pub(pmt::mp("events"), pmt::from_long(3)); // 3 -> loss of lock + d_carrier_lock_fail_counter = 0; + return false; + } + else + { + return true; + } + } } + + // correlation requires: // - updated remnant carrier phase in radians (rem_carr_phase_rad) // - updated remnant code phase in samples (d_rem_code_phase_samples) @@ -504,29 +514,32 @@ void galileo_e1_dll_pll_veml_tracking_cc::do_correlation_step(const gr_complex* // DATA CORRELATOR (if tracking tracks the pilot signal) if (d_track_pilot) - { - correlator_data_cpu.set_input_output_vectors(d_Prompt_Data,input_samples); - correlator_data_cpu.Carrier_wipeoff_multicorrelator_resampler( - d_rem_carr_phase_rad, - d_carrier_phase_step_rad, - d_rem_code_phase_chips, - d_code_phase_step_chips, - d_correlation_length_samples); - } + { + correlator_data_cpu.set_input_output_vectors(d_Prompt_Data,input_samples); + correlator_data_cpu.Carrier_wipeoff_multicorrelator_resampler( + d_rem_carr_phase_rad, + d_carrier_phase_step_rad, + d_rem_code_phase_chips, + d_code_phase_step_chips, + d_correlation_length_samples); + } } + void galileo_e1_dll_pll_veml_tracking_cc::run_dll_pll(bool disable_costas_loop) { // ################## PLL ########################################################## // PLL discriminator - if (disable_costas_loop==true) - { - //Secondary code acquired. No symbols transition should be present in the signal - d_carr_error_hz = pll_four_quadrant_atan(d_P_accu) / GALILEO_TWO_PI; - }else{ - // Costas loop discriminator, insensitive to 180 deg phase transitions - d_carr_error_hz = pll_cloop_two_quadrant_atan(d_P_accu) / GALILEO_TWO_PI; - } + if (disable_costas_loop == true) + { + // Secondary code acquired. No symbols transition should be present in the signal + d_carr_error_hz = pll_four_quadrant_atan(d_P_accu) / GALILEO_TWO_PI; + } + else + { + // Costas loop discriminator, insensitive to 180 deg phase transitions + d_carr_error_hz = pll_cloop_two_quadrant_atan(d_P_accu) / GALILEO_TWO_PI; + } // Carrier discriminator filter d_carr_error_filt_hz = d_carrier_loop_filter.get_carrier_nco(d_carr_error_hz); @@ -537,12 +550,12 @@ void galileo_e1_dll_pll_veml_tracking_cc::run_dll_pll(bool disable_costas_loop) // ################## DLL ########################################################## // DLL discriminator - d_code_error_chips = dll_nc_vemlp_normalized(d_VE_accu, d_E_accu, d_L_accu, d_VL_accu); //[chips/Ti] + d_code_error_chips = dll_nc_vemlp_normalized(d_VE_accu, d_E_accu, d_L_accu, d_VL_accu); // [chips/Ti] // Code discriminator filter - d_code_error_filt_chips = d_code_loop_filter.get_code_nco(d_code_error_chips); //[chips/second] - + d_code_error_filt_chips = d_code_loop_filter.get_code_nco(d_code_error_chips); // [chips/second] } + void galileo_e1_dll_pll_veml_tracking_cc::clear_tracking_vars() { *d_Very_Early = gr_complex(0,0); @@ -550,13 +563,14 @@ void galileo_e1_dll_pll_veml_tracking_cc::clear_tracking_vars() *d_Prompt = gr_complex(0,0); *d_Late = gr_complex(0,0); *d_Very_Late= gr_complex(0,0); - d_carr_error_hz =0.0; - d_carr_error_filt_hz =0.0; - d_code_error_chips =0.0; - d_code_error_filt_chips =0.0; - d_current_symbol=0; + d_carr_error_hz = 0.0; + d_carr_error_filt_hz = 0.0; + d_code_error_chips = 0.0; + d_code_error_filt_chips = 0.0; + d_current_symbol = 0; } + void galileo_e1_dll_pll_veml_tracking_cc::log_data() { if(d_dump) @@ -598,12 +612,12 @@ void galileo_e1_dll_pll_veml_tracking_cc::log_data() d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); tmp_float = d_code_freq_chips; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - //PLL commands + // PLL commands tmp_float = d_carr_error_hz; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); tmp_float = d_carr_error_filt_hz; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - //DLL commands + // DLL commands tmp_float = d_code_error_chips; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); tmp_float = d_code_error_filt_chips; @@ -628,10 +642,11 @@ void galileo_e1_dll_pll_veml_tracking_cc::log_data() } } } -int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), - gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) -{ + +int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) +{ // Block input data and block output stream pointers const gr_complex* in = reinterpret_cast(input_items[0]); Gnss_Synchro **out = reinterpret_cast(&output_items[0]); @@ -640,12 +655,12 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attri switch(d_state) { - case 0: //standby - bypass + case 0: // standby - bypass { current_synchro_data.Tracking_sample_counter = d_sample_counter; break; } - case 1: // pull-in + case 1: // pull-in { /* * Signal alignment (skip samples until the incoming signal is aligned with local replica) @@ -661,12 +676,12 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attri current_synchro_data.Tracking_sample_counter = d_sample_counter; current_synchro_data.fs = d_fs_in; *out[0] = current_synchro_data; - d_sample_counter = d_sample_counter + samples_offset; //count for the processed samples - consume_each(samples_offset); //shift input to perform alignment with local replica - d_state=2; //next state is the symbol synchronization + d_sample_counter = d_sample_counter + samples_offset; // count for the processed samples + consume_each(samples_offset); // shift input to perform alignment with local replica + d_state = 2; // next state is the symbol synchronization return 0; } - case 2: // wide tracking and symbol synchronization + case 2: // wide tracking and symbol synchronization { // Fill the acquisition data current_synchro_data = *d_acquisition_gnss_synchro; @@ -677,154 +692,157 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attri // perform a correlation step do_correlation_step(in); // save single correlation step variables - d_VE_accu=*d_Very_Early; - d_E_accu=*d_Early; - d_P_accu=*d_Prompt; - d_L_accu=*d_Late; - d_VL_accu=*d_Very_Late; + d_VE_accu = *d_Very_Early; + d_E_accu = *d_Early; + d_P_accu = *d_Prompt; + d_L_accu = *d_Late; + d_VL_accu = *d_Very_Late; //check lock status - if (cn0_and_tracking_lock_status()==false) - { - clear_tracking_vars(); - d_state=0; //loss-of-lock detected - }else{ - - //perform DLL/PLL tracking loop computations - run_dll_pll(false); - - // ################## PLL COMMANDS ################################################# - //carrier phase accumulator for (K) Doppler estimation- - d_acc_carrier_phase_rad -= GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / static_cast(d_fs_in); - //remnant carrier phase to prevent overflow in the code NCO - d_rem_carr_phase_rad = d_rem_carr_phase_rad + GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / static_cast(d_fs_in); - d_rem_carr_phase_rad = std::fmod(d_rem_carr_phase_rad, GALILEO_TWO_PI); - - // ################## DLL COMMANDS ################################################# - - //Code error from DLL - double code_error_filt_secs; - code_error_filt_secs = (Galileo_E1_CODE_PERIOD * d_code_error_filt_chips) / Galileo_E1_CODE_CHIP_RATE_HZ; //[seconds] - - // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### - // keep alignment parameters for the next input buffer - // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation - double T_chip_seconds = 1.0 / d_code_freq_chips; - double T_prn_seconds = T_chip_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS; - double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); - double K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * static_cast(d_fs_in); - d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples - - // ########### Output the tracking results to Telemetry block ########## - if (d_track_pilot) + if (cn0_and_tracking_lock_status() == false) { - current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).real()); - current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); - }else{ - current_synchro_data.Prompt_I = static_cast((*d_Prompt).real()); - current_synchro_data.Prompt_Q = static_cast((*d_Prompt).imag()); + clear_tracking_vars(); + d_state = 0; // loss-of-lock detected } - current_synchro_data.Tracking_sample_counter = d_sample_counter; - current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; - //compute remnant code phase samples AFTER the Tracking timestamp - d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample - current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; - current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; - current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; - current_synchro_data.Flag_valid_symbol_output = true; - current_synchro_data.correlation_length_ms = Galileo_E1_CODE_PERIOD_MS; - - //enable write dump file this cycle (valid DLL/PLL cycle) - log_data(); - - //std::cout<<(d_Prompt->real()>0); - if (d_enable_extended_integration) + else { - // ####### SECONDARY CODE LOCK ##### - d_Prompt_buffer_deque.push_back(*d_Prompt); - if (d_Prompt_buffer_deque.size()==Galileo_E1_C_SECONDARY_CODE_LENGTH) - { - if (acquire_secondary()==true) + // perform DLL/PLL tracking loop computations + run_dll_pll(false); + + // ################## PLL COMMANDS ################################################# + // carrier phase accumulator for (K) Doppler estimation- + d_acc_carrier_phase_rad -= GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / static_cast(d_fs_in); + // remnant carrier phase to prevent overflow in the code NCO + d_rem_carr_phase_rad = d_rem_carr_phase_rad + GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / static_cast(d_fs_in); + d_rem_carr_phase_rad = std::fmod(d_rem_carr_phase_rad, GALILEO_TWO_PI); + + // ################## DLL COMMANDS ################################################# + // Code error from DLL + double code_error_filt_secs; + code_error_filt_secs = (Galileo_E1_CODE_PERIOD * d_code_error_filt_chips) / Galileo_E1_CODE_CHIP_RATE_HZ; // [seconds] + + // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### + // keep alignment parameters for the next input buffer + // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation + double T_chip_seconds = 1.0 / d_code_freq_chips; + double T_prn_seconds = T_chip_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS; + double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); + double K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * static_cast(d_fs_in); + d_current_prn_length_samples = round(K_blk_samples); // round to a discrete samples + + // ########### Output the tracking results to Telemetry block ########## + if (d_track_pilot) { - d_extend_correlation_symbols_count=0; - //reset extended correlator - d_VE_accu=gr_complex(0,0); - d_E_accu=gr_complex(0,0); - d_P_accu=gr_complex(0,0); - d_L_accu=gr_complex(0,0); - d_VL_accu=gr_complex(0,0); - d_Prompt_buffer_deque.clear(); - d_current_symbol=0; - d_code_loop_filter.set_DLL_BW(d_dll_bw_narrow_hz); - d_carrier_loop_filter.set_PLL_BW(d_pll_bw_narrow_hz); - - // Set TAPs delay values [chips] - d_local_code_shift_chips[0] = - d_very_early_late_spc_narrow_chips; - d_local_code_shift_chips[1] = - d_early_late_spc_narrow_chips; - d_local_code_shift_chips[2] = 0.0; - d_local_code_shift_chips[3] = d_early_late_spc_narrow_chips; - d_local_code_shift_chips[4] = d_very_early_late_spc_narrow_chips; - - - LOG(INFO) << "Enabled " << d_extend_correlation_symbols << " [symbols] extended correlator for CH " - << d_channel - << " : Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN); - std::cout<< "Enabled " << d_extend_correlation_symbols << " [symbols] extended correlator for CH " - << d_channel - << " : Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN)<(d_extend_correlation_symbols) * Galileo_E1_CODE_PERIOD; - d_carrier_loop_filter.set_pdi(new_correlation_time_s); - d_code_loop_filter.set_pdi(new_correlation_time_s); - - d_state=3; // next state is the extended correlator integrator + current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); } + else + { + current_synchro_data.Prompt_I = static_cast((*d_Prompt).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt).imag()); + } + current_synchro_data.Tracking_sample_counter = d_sample_counter; + current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; + // compute remnant code phase samples AFTER the Tracking timestamp + d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; // rounding error < 1 sample + current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; + current_synchro_data.Flag_valid_symbol_output = true; + current_synchro_data.correlation_length_ms = Galileo_E1_CODE_PERIOD_MS; - d_Prompt_buffer_deque.pop_front(); - } + // enable write dump file this cycle (valid DLL/PLL cycle) + log_data(); + + //std::cout<<(d_Prompt->real()>0); + if (d_enable_extended_integration) + { + // ####### SECONDARY CODE LOCK ##### + d_Prompt_buffer_deque.push_back(*d_Prompt); + if (d_Prompt_buffer_deque.size() == Galileo_E1_C_SECONDARY_CODE_LENGTH) + { + if (acquire_secondary() == true) + { + d_extend_correlation_symbols_count = 0; + //reset extended correlator + d_VE_accu = gr_complex(0,0); + d_E_accu = gr_complex(0,0); + d_P_accu = gr_complex(0,0); + d_L_accu = gr_complex(0,0); + d_VL_accu = gr_complex(0,0); + d_Prompt_buffer_deque.clear(); + d_current_symbol = 0; + d_code_loop_filter.set_DLL_BW(d_dll_bw_narrow_hz); + d_carrier_loop_filter.set_PLL_BW(d_pll_bw_narrow_hz); + + // Set TAPs delay values [chips] + d_local_code_shift_chips[0] = - d_very_early_late_spc_narrow_chips; + d_local_code_shift_chips[1] = - d_early_late_spc_narrow_chips; + d_local_code_shift_chips[2] = 0.0; + d_local_code_shift_chips[3] = d_early_late_spc_narrow_chips; + d_local_code_shift_chips[4] = d_very_early_late_spc_narrow_chips; + + LOG(INFO) << "Enabled " << d_extend_correlation_symbols << " [symbols] extended correlator for CH " + << d_channel + << " : Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN); + std::cout << "Enabled " << d_extend_correlation_symbols << " [symbols] extended correlator for CH " + << d_channel + << " : Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl; + //std::cout << " pll_bw = " << d_pll_bw_hz << " [Hz], pll_narrow_bw = " << d_pll_bw_narrow_hz << " [Hz]" << std::endl; + //std::cout << " dll_bw = " << d_dll_bw_hz << " [Hz], dll_narrow_bw = " << d_dll_bw_narrow_hz << " [Hz]" << std::endl; + + // UPDATE INTEGRATION TIME + double new_correlation_time_s = static_cast(d_extend_correlation_symbols) * Galileo_E1_CODE_PERIOD; + d_carrier_loop_filter.set_pdi(new_correlation_time_s); + d_code_loop_filter.set_pdi(new_correlation_time_s); + + d_state = 3; // next state is the extended correlator integrator + } + + d_Prompt_buffer_deque.pop_front(); + } + } } - } break; } - case 3: // coherent integration (correlation time extension) + case 3: // coherent integration (correlation time extension) { // Fill the acquisition data current_synchro_data = *d_acquisition_gnss_synchro; - //Current NCO and code generator parameters + // Current NCO and code generator parameters d_carrier_phase_step_rad = GALILEO_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); d_code_phase_step_chips = d_code_freq_chips / static_cast(d_fs_in); d_rem_code_phase_chips = d_rem_code_phase_samples * d_code_freq_chips / d_fs_in; // perform a correlation step do_correlation_step(in); - //correct the integration sign using the current symbol of the secondary code + // correct the integration sign using the current symbol of the secondary code if (Galileo_E1_C_SECONDARY_CODE.at(d_current_symbol) == '0') - { - d_VE_accu+=*d_Very_Early; - d_E_accu+=*d_Early; - d_P_accu+=*d_Prompt; - d_L_accu+=*d_Late; - d_VL_accu+=*d_Very_Late; - }else{ - d_VE_accu-=*d_Very_Early; - d_E_accu-=*d_Early; - d_P_accu-=*d_Prompt; - d_L_accu-=*d_Late; - d_VL_accu-=*d_Very_Late; - } + { + d_VE_accu += *d_Very_Early; + d_E_accu += *d_Early; + d_P_accu += *d_Prompt; + d_L_accu += *d_Late; + d_VL_accu += *d_Very_Late; + } + else + { + d_VE_accu -= *d_Very_Early; + d_E_accu -= *d_Early; + d_P_accu -= *d_Prompt; + d_L_accu -= *d_Late; + d_VL_accu -= *d_Very_Late; + } d_current_symbol++; - //secondary code roll-up - d_current_symbol=d_current_symbol%Galileo_E1_C_SECONDARY_CODE_LENGTH; + // secondary code roll-up + d_current_symbol = d_current_symbol % Galileo_E1_C_SECONDARY_CODE_LENGTH; // PLL/DLL not enabled, we are in the middle of a coherent integration // keep alignment parameters for the next input buffer // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation // ################## PLL ########################################################## - //carrier phase accumulator for (K) Doppler estimation- + // carrier phase accumulator for (K) Doppler estimation- d_acc_carrier_phase_rad -= GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / static_cast(d_fs_in); - //remnant carrier phase to prevent overflow in the code NCO + // remnant carrier phase to prevent overflow in the code NCO d_rem_carr_phase_rad = d_rem_carr_phase_rad + GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / static_cast(d_fs_in); d_rem_carr_phase_rad = std::fmod(d_rem_carr_phase_rad, GALILEO_TWO_PI); @@ -842,7 +860,7 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attri current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); current_synchro_data.Tracking_sample_counter = d_sample_counter; current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; - //compute remnant code phase samples AFTER the Tracking timestamp + // compute remnant code phase samples AFTER the Tracking timestamp d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; @@ -851,112 +869,117 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attri current_synchro_data.correlation_length_ms = Galileo_E1_CODE_PERIOD_MS; d_extend_correlation_symbols_count++; - if (d_extend_correlation_symbols_count>=(d_extend_correlation_symbols-1)) - { - d_extend_correlation_symbols_count=0; - d_state=4; - } + if (d_extend_correlation_symbols_count >= (d_extend_correlation_symbols - 1)) + { + d_extend_correlation_symbols_count = 0; + d_state = 4; + } break; } - case 4: // narrow tracking + case 4: // narrow tracking { // Fill the acquisition data current_synchro_data = *d_acquisition_gnss_synchro; // perform a correlation step do_correlation_step(in); - //correct the integration using the current symbol + // correct the integration using the current symbol if (Galileo_E1_C_SECONDARY_CODE.at(d_current_symbol) == '0') - { - d_VE_accu+=*d_Very_Early; - d_E_accu+=*d_Early; - d_P_accu+=*d_Prompt; - d_L_accu+=*d_Late; - d_VL_accu+=*d_Very_Late; - }else{ - d_VE_accu-=*d_Very_Early; - d_E_accu-=*d_Early; - d_P_accu-=*d_Prompt; - d_L_accu-=*d_Late; - d_VL_accu-=*d_Very_Late; - } + { + d_VE_accu += *d_Very_Early; + d_E_accu += *d_Early; + d_P_accu += *d_Prompt; + d_L_accu += *d_Late; + d_VL_accu += *d_Very_Late; + } + else + { + d_VE_accu -= *d_Very_Early; + d_E_accu -= *d_Early; + d_P_accu -= *d_Prompt; + d_L_accu -= *d_Late; + d_VL_accu -= *d_Very_Late; + } d_current_symbol++; - //secondary code roll-up - d_current_symbol=d_current_symbol%Galileo_E1_C_SECONDARY_CODE_LENGTH; + // secondary code roll-up + d_current_symbol = d_current_symbol % Galileo_E1_C_SECONDARY_CODE_LENGTH; - //check lock status - if (cn0_and_tracking_lock_status()==false) - { - clear_tracking_vars(); - d_state=0; //loss-of-lock detected - }else{ - run_dll_pll(true);//Costas loop disabled, use four quadrant atan + // check lock status + if (cn0_and_tracking_lock_status() == false) + { + clear_tracking_vars(); + d_state = 0; // loss-of-lock detected + } + else + { + run_dll_pll(true); // Costas loop disabled, use four quadrant atan - // ################## PLL ########################################################## - //carrier phase accumulator for (K) Doppler estimation- - d_acc_carrier_phase_rad -= GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / static_cast(d_fs_in); - //remnant carrier phase to prevent overflow in the code NCO - d_rem_carr_phase_rad = d_rem_carr_phase_rad + GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / static_cast(d_fs_in); - d_rem_carr_phase_rad = std::fmod(d_rem_carr_phase_rad, GALILEO_TWO_PI); + // ################## PLL ########################################################## + // carrier phase accumulator for (K) Doppler estimation- + d_acc_carrier_phase_rad -= GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / static_cast(d_fs_in); + // remnant carrier phase to prevent overflow in the code NCO + d_rem_carr_phase_rad = d_rem_carr_phase_rad + GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / static_cast(d_fs_in); + d_rem_carr_phase_rad = std::fmod(d_rem_carr_phase_rad, GALILEO_TWO_PI); - // ################## DLL ########################################################## + // ################## DLL ########################################################## + // Code phase accumulator + double code_error_filt_secs; + code_error_filt_secs = (Galileo_E1_CODE_PERIOD * d_code_error_filt_chips) / Galileo_E1_CODE_CHIP_RATE_HZ; //[seconds] - //Code phase accumulator - double code_error_filt_secs; - code_error_filt_secs = (Galileo_E1_CODE_PERIOD * d_code_error_filt_chips) / Galileo_E1_CODE_CHIP_RATE_HZ; //[seconds] + // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### + // keep alignment parameters for the next input buffer + // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation + double T_chip_seconds = 1.0 / d_code_freq_chips; + double T_prn_seconds = T_chip_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS; + double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); + double K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * static_cast(d_fs_in); + d_current_prn_length_samples = round(K_blk_samples); // round to a discrete number of samples - // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### - // keep alignment parameters for the next input buffer - // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation - double T_chip_seconds = 1.0 / d_code_freq_chips; - double T_prn_seconds = T_chip_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS; - double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); - double K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * static_cast(d_fs_in); - d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples - - // ########### Output the tracking results to Telemetry block ########## - current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).real()); - current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); - current_synchro_data.Tracking_sample_counter = d_sample_counter; - current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; - //compute remnant code phase samples AFTER the Tracking timestamp - d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample - current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; - current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; - current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; - current_synchro_data.Flag_valid_symbol_output = true; - current_synchro_data.correlation_length_ms = Galileo_E1_CODE_PERIOD_MS; - //enable write dump file this cycle (valid DLL/PLL cycle) - log_data(); - //reset extended correlator - d_VE_accu=gr_complex(0,0); - d_E_accu=gr_complex(0,0); - d_P_accu=gr_complex(0,0); - d_L_accu=gr_complex(0,0); - d_VL_accu=gr_complex(0,0); - d_state=3; //new coherent integration (correlation time extension) cycle - } + // ########### Output the tracking results to Telemetry block ########## + current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); + current_synchro_data.Tracking_sample_counter = d_sample_counter; + current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; + // compute remnant code phase samples AFTER the Tracking timestamp + d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample + current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; + current_synchro_data.Flag_valid_symbol_output = true; + current_synchro_data.correlation_length_ms = Galileo_E1_CODE_PERIOD_MS; + // enable write dump file this cycle (valid DLL/PLL cycle) + log_data(); + // reset extended correlator + d_VE_accu = gr_complex(0,0); + d_E_accu = gr_complex(0,0); + d_P_accu = gr_complex(0,0); + d_L_accu = gr_complex(0,0); + d_VL_accu = gr_complex(0,0); + d_state = 3; //new coherent integration (correlation time extension) cycle + } } } //assign the GNURadio block output data -// current_synchro_data.System = {'E'}; -// std::string str_aux = "1B"; -// const char * str = str_aux.c_str(); // get a C style null terminated string -// std::memcpy(static_cast(current_synchro_data.Signal), str, 3); + // current_synchro_data.System = {'E'}; + // std::string str_aux = "1B"; + // const char * str = str_aux.c_str(); // get a C style null terminated string + // std::memcpy(static_cast(current_synchro_data.Signal), str, 3); current_synchro_data.fs = d_fs_in; *out[0] = current_synchro_data; consume_each(d_current_prn_length_samples); // this is required for gr_block derivates - d_sample_counter += d_current_prn_length_samples; //count for the processed samples + d_sample_counter += d_current_prn_length_samples; // count for the processed samples if (current_synchro_data.Flag_valid_symbol_output) - { - return 1; - }else{ - return 0; - } + { + return 1; + } + else + { + return 0; + } } @@ -982,15 +1005,15 @@ int galileo_e1_dll_pll_veml_tracking_cc::save_matfile() // count number of epochs and rewind long int num_epoch = 0; if (dump_file.is_open()) - { - size = dump_file.tellg(); - num_epoch = static_cast(size) / static_cast(epoch_size_bytes); - dump_file.seekg(0, std::ios::beg); - } + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } else - { - return 1; - } + { + return 1; + } float * abs_VE = new float [num_epoch]; float * abs_E = new float [num_epoch]; float * abs_P = new float [num_epoch]; @@ -1209,8 +1232,6 @@ void galileo_e1_dll_pll_veml_tracking_cc::set_channel(unsigned int channel) } - - void galileo_e1_dll_pll_veml_tracking_cc::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) { d_acquisition_gnss_synchro = p_gnss_synchro; diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l5i_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l5i_dll_pll_tracking_cc.cc index 100f8c62f..ba174dbea 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l5i_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l5i_dll_pll_tracking_cc.cc @@ -730,11 +730,13 @@ int gps_l5i_dll_pll_tracking_cc::general_work (int noutput_items __attribute__(( consume_each(d_current_prn_length_samples); // this is necessary in gr::block derivates d_sample_counter += d_current_prn_length_samples; // count for the processed samples if (d_enable_tracking) - { - return 1; - }else{ - return 0; - } + { + return 1; + } + else + { + return 0; + } } From 1b5a3b6fa4ad16704f7eb1542af746667515547f Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 17 Jan 2018 17:55:46 +0100 Subject: [PATCH 37/96] Apply coding style --- .../galileo_e1_pcps_ambiguous_acquisition.cc | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc index b0f64a25b..5ac10bcd8 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc @@ -70,7 +70,7 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions - acquire_pilot_= configuration_->property(role + ".acquire_pilot", false); //will be true in future versions + acquire_pilot_ = configuration_->property(role + ".acquire_pilot", false); //will be true in future versions max_dwells_ = configuration_->property(role + ".max_dwells", 1); @@ -96,7 +96,6 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, blocking_, dump_filename_); DLOG(INFO) << "acquisition(" << acquisition_sc_->unique_id() << ")"; - } else { @@ -253,17 +252,18 @@ void GalileoE1PcpsAmbiguousAcquisition::set_local_code() std::complex * code = new std::complex[code_length_]; - if (acquire_pilot_==true) - { - //set local signal generator to Galileo E1 pilot component (1C) - char pilot_signal[3]="1C"; - galileo_e1_code_gen_complex_sampled(code, pilot_signal, - cboc, gnss_synchro_->PRN, fs_in_, 0, false); - }else - { - galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, - cboc, gnss_synchro_->PRN, fs_in_, 0, false); - } + if (acquire_pilot_ == true) + { + //set local signal generator to Galileo E1 pilot component (1C) + char pilot_signal[3] = "1C"; + galileo_e1_code_gen_complex_sampled(code, pilot_signal, + cboc, gnss_synchro_->PRN, fs_in_, 0, false); + } + else + { + galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, + cboc, gnss_synchro_->PRN, fs_in_, 0, false); + } for (unsigned int i = 0; i < sampled_ms_ / 4; i++) From 7e97d00a4f91dba3a28df2415a4e1ebc60be4a0c Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 17 Jan 2018 19:02:52 +0100 Subject: [PATCH 38/96] Apply project's coding style --- .../gnuradio_blocks/hybrid_observables_cc.cc | 676 +++++++++--------- 1 file changed, 339 insertions(+), 337 deletions(-) diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc index f9fb4a936..40b18599d 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc @@ -65,49 +65,49 @@ hybrid_observables_cc::hybrid_observables_cc(unsigned int nchannels, bool dump, T_rx_s = 0.0; T_rx_step_s = 1e-3; // todo: move to gnss-sdr config for (unsigned int i = 0; i < d_nchannels; i++) - { - d_gnss_synchro_history_queue.push_back(std::deque()); - } + { + d_gnss_synchro_history_queue.push_back(std::deque()); + } // ############# ENABLE DATA FILE LOG ################# if (d_dump == true) - { - if (d_dump_file.is_open() == false) { - try - { - d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit ); - d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "Observables dump enabled Log file: " << d_dump_filename.c_str(); - } - catch (const std::ifstream::failure & e) - { - LOG(WARNING) << "Exception opening observables dump file " << e.what(); - } + if (d_dump_file.is_open() == false) + { + try + { + d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit ); + d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "Observables dump enabled Log file: " << d_dump_filename.c_str(); + } + catch (const std::ifstream::failure & e) + { + LOG(WARNING) << "Exception opening observables dump file " << e.what(); + } + } } - } } hybrid_observables_cc::~hybrid_observables_cc() { if (d_dump_file.is_open() == true) - { - try { - d_dump_file.close(); + try + { + d_dump_file.close(); + } + catch(const std::exception & ex) + { + LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); + } } - catch(const std::exception & ex) - { - LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); - } - } if(d_dump == true) - { - std::cout << "Writing observables .mat files ..."; - hybrid_observables_cc::save_matfile(); - std::cout << " done." << std::endl; - } + { + std::cout << "Writing observables .mat files ..."; + hybrid_observables_cc::save_matfile(); + std::cout << " done." << std::endl; + } } @@ -121,25 +121,25 @@ int hybrid_observables_cc::save_matfile() dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { - dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); } catch(const std::ifstream::failure &e) { - std::cerr << "Problem opening dump file:" << e.what() << std::endl; - return 1; + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return 1; } // count number of epochs and rewind long int num_epoch = 0; if (dump_file.is_open()) - { - size = dump_file.tellg(); - num_epoch = static_cast(size) / static_cast(epoch_size_bytes); - dump_file.seekg(0, std::ios::beg); - } + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } else - { - return 1; - } + { + return 1; + } double ** RX_time = new double * [d_nchannels]; double ** TOW_at_current_symbol_s = new double * [d_nchannels]; double ** Carrier_Doppler_hz = new double * [d_nchannels]; @@ -149,58 +149,58 @@ int hybrid_observables_cc::save_matfile() double ** Flag_valid_pseudorange = new double * [d_nchannels]; for(unsigned int i = 0; i < d_nchannels; i++) - { - RX_time[i] = new double [num_epoch]; - TOW_at_current_symbol_s[i] = new double[num_epoch]; - Carrier_Doppler_hz[i] = new double[num_epoch]; - Carrier_phase_cycles[i] = new double[num_epoch]; - Pseudorange_m[i] = new double[num_epoch]; - PRN[i] = new double[num_epoch]; - Flag_valid_pseudorange[i] = new double[num_epoch]; - } + { + RX_time[i] = new double [num_epoch]; + TOW_at_current_symbol_s[i] = new double[num_epoch]; + Carrier_Doppler_hz[i] = new double[num_epoch]; + Carrier_phase_cycles[i] = new double[num_epoch]; + Pseudorange_m[i] = new double[num_epoch]; + PRN[i] = new double[num_epoch]; + Flag_valid_pseudorange[i] = new double[num_epoch]; + } try { - if (dump_file.is_open()) - { - for(long int i = 0; i < num_epoch; i++) - { - for(unsigned int chan = 0; chan < d_nchannels; chan++) + if (dump_file.is_open()) { - dump_file.read(reinterpret_cast(&RX_time[chan][i]), sizeof(double)); - dump_file.read(reinterpret_cast(&TOW_at_current_symbol_s[chan][i]), sizeof(double)); - dump_file.read(reinterpret_cast(&Carrier_Doppler_hz[chan][i]), sizeof(double)); - dump_file.read(reinterpret_cast(&Carrier_phase_cycles[chan][i]), sizeof(double)); - dump_file.read(reinterpret_cast(&Pseudorange_m[chan][i]), sizeof(double)); - dump_file.read(reinterpret_cast(&PRN[chan][i]), sizeof(double)); - dump_file.read(reinterpret_cast(&Flag_valid_pseudorange[chan][i]), sizeof(double)); + for(long int i = 0; i < num_epoch; i++) + { + for(unsigned int chan = 0; chan < d_nchannels; chan++) + { + dump_file.read(reinterpret_cast(&RX_time[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&TOW_at_current_symbol_s[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&Carrier_Doppler_hz[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&Carrier_phase_cycles[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&Pseudorange_m[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&PRN[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&Flag_valid_pseudorange[chan][i]), sizeof(double)); + } + } } - } - } - dump_file.close(); + dump_file.close(); } catch (const std::ifstream::failure &e) { - std::cerr << "Problem reading dump file:" << e.what() << std::endl; - for(unsigned int i = 0; i < d_nchannels; i++) - { - delete[] RX_time[i]; - delete[] TOW_at_current_symbol_s[i]; - delete[] Carrier_Doppler_hz[i]; - delete[] Carrier_phase_cycles[i]; - delete[] Pseudorange_m[i]; - delete[] PRN[i]; - delete[] Flag_valid_pseudorange[i]; - } - delete[] RX_time; - delete[] TOW_at_current_symbol_s; - delete[] Carrier_Doppler_hz; - delete[] Carrier_phase_cycles; - delete[] Pseudorange_m; - delete[] PRN; - delete[] Flag_valid_pseudorange; + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + for(unsigned int i = 0; i < d_nchannels; i++) + { + delete[] RX_time[i]; + delete[] TOW_at_current_symbol_s[i]; + delete[] Carrier_Doppler_hz[i]; + delete[] Carrier_phase_cycles[i]; + delete[] Pseudorange_m[i]; + delete[] PRN[i]; + delete[] Flag_valid_pseudorange[i]; + } + delete[] RX_time; + delete[] TOW_at_current_symbol_s; + delete[] Carrier_Doppler_hz; + delete[] Carrier_phase_cycles; + delete[] Pseudorange_m; + delete[] PRN; + delete[] Flag_valid_pseudorange; - return 1; + return 1; } double * RX_time_aux = new double [d_nchannels * num_epoch]; @@ -212,19 +212,19 @@ int hybrid_observables_cc::save_matfile() double * Flag_valid_pseudorange_aux = new double[d_nchannels * num_epoch]; unsigned int k = 0; for(long int j = 0; j < num_epoch; j++ ) - { - for(unsigned int i = 0; i < d_nchannels; i++ ) { - RX_time_aux[k] = RX_time[i][j]; - TOW_at_current_symbol_s_aux[k] = TOW_at_current_symbol_s[i][j]; - Carrier_Doppler_hz_aux[k] = Carrier_Doppler_hz[i][j]; - Carrier_phase_cycles_aux[k] = Carrier_phase_cycles[i][j]; - Pseudorange_m_aux[k] = Pseudorange_m[i][j]; - PRN_aux[k] = PRN[i][j]; - Flag_valid_pseudorange_aux[k] = Flag_valid_pseudorange[i][j]; - k++; + for(unsigned int i = 0; i < d_nchannels; i++ ) + { + RX_time_aux[k] = RX_time[i][j]; + TOW_at_current_symbol_s_aux[k] = TOW_at_current_symbol_s[i][j]; + Carrier_Doppler_hz_aux[k] = Carrier_Doppler_hz[i][j]; + Carrier_phase_cycles_aux[k] = Carrier_phase_cycles[i][j]; + Pseudorange_m_aux[k] = Pseudorange_m[i][j]; + PRN_aux[k] = PRN[i][j]; + Flag_valid_pseudorange_aux[k] = Flag_valid_pseudorange[i][j]; + k++; + } } - } // WRITE MAT FILE mat_t *matfp; @@ -234,49 +234,49 @@ int hybrid_observables_cc::save_matfile() filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); if(reinterpret_cast(matfp) != NULL) - { - size_t dims[2] = {static_cast(d_nchannels), static_cast(num_epoch)}; - matvar = Mat_VarCreate("RX_time", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, RX_time_aux, MAT_F_DONT_COPY_DATA); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + { + size_t dims[2] = {static_cast(d_nchannels), static_cast(num_epoch)}; + matvar = Mat_VarCreate("RX_time", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, RX_time_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("TOW_at_current_symbol_s", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, TOW_at_current_symbol_s_aux, MAT_F_DONT_COPY_DATA); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("TOW_at_current_symbol_s", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, TOW_at_current_symbol_s_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("Carrier_Doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Carrier_Doppler_hz_aux, MAT_F_DONT_COPY_DATA); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("Carrier_Doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Carrier_Doppler_hz_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("Carrier_phase_cycles", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Carrier_phase_cycles_aux, MAT_F_DONT_COPY_DATA); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("Carrier_phase_cycles", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Carrier_phase_cycles_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("Pseudorange_m", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Pseudorange_m_aux, MAT_F_DONT_COPY_DATA); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("Pseudorange_m", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Pseudorange_m_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("PRN", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, PRN_aux, MAT_F_DONT_COPY_DATA); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("PRN", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, PRN_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("Flag_valid_pseudorange", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Flag_valid_pseudorange_aux, MAT_F_DONT_COPY_DATA); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); - } + matvar = Mat_VarCreate("Flag_valid_pseudorange", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Flag_valid_pseudorange_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } Mat_Close(matfp); for(unsigned int i = 0; i < d_nchannels; i++) - { - delete[] RX_time[i]; - delete[] TOW_at_current_symbol_s[i]; - delete[] Carrier_Doppler_hz[i]; - delete[] Carrier_phase_cycles[i]; - delete[] Pseudorange_m[i]; - delete[] PRN[i]; - delete[] Flag_valid_pseudorange[i]; + { + delete[] RX_time[i]; + delete[] TOW_at_current_symbol_s[i]; + delete[] Carrier_Doppler_hz[i]; + delete[] Carrier_phase_cycles[i]; + delete[] Pseudorange_m[i]; + delete[] PRN[i]; + delete[] Flag_valid_pseudorange[i]; - } + } delete[] RX_time; delete[] TOW_at_current_symbol_s; delete[] Carrier_Doppler_hz; @@ -325,30 +325,32 @@ bool Hybrid_valueCompare_gnss_synchro_d_TOW(const Gnss_Synchro& a, double b) return (a.TOW_at_current_symbol_s) < (b); } + void hybrid_observables_cc::forecast (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required) { - bool zero_samples=true; + bool zero_samples = true; for(unsigned int i = 0; i < d_nchannels; i++) - { - int items=detail()->input(i)->items_available(); - if (items>0) zero_samples=false; - ninput_items_required[i] = items; //set the required available samples in each call - } - - if (zero_samples==true) - { - for(unsigned int i = 0; i < d_nchannels; i++) { - ninput_items_required[i] = 1; //set the required available samples in each call + int items=detail()->input(i)->items_available(); + if (items>0) zero_samples = false; + ninput_items_required[i] = items; // set the required available samples in each call + } + + if (zero_samples == true) + { + for(unsigned int i = 0; i < d_nchannels; i++) + { + ninput_items_required[i] = 1; // set the required available samples in each call + } } - } } + int hybrid_observables_cc::general_work (int noutput_items , - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { const Gnss_Synchro **in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer Gnss_Synchro **out = reinterpret_cast(&output_items[0]); // Get the output buffer pointer @@ -359,231 +361,231 @@ int hybrid_observables_cc::general_work (int noutput_items , Gnss_Synchro current_gnss_synchro[d_nchannels]; Gnss_Synchro aux = Gnss_Synchro(); for(unsigned int i = 0; i < d_nchannels; i++) - { - current_gnss_synchro[i] = aux; - } + { + current_gnss_synchro[i] = aux; + } /* * 1. Read the GNSS SYNCHRO objects from available channels. * Multi-rate GNURADIO Block. Read how many input items are avaliable in each channel * Record all synchronization data into queues */ for (unsigned int i = 0; i < d_nchannels; i++) - { - n_consume[i] = ninput_items[i];// full throttle - for (int j = 0; j < n_consume[i]; j++) { - d_gnss_synchro_history_queue[i].push_back(in[i][j]); + n_consume[i] = ninput_items[i]; // full throttle + for (int j = 0; j < n_consume[i]; j++) + { + d_gnss_synchro_history_queue[i].push_back(in[i][j]); + } } - } bool channel_history_ok; do - { - channel_history_ok = true; - for (unsigned int i = 0; i < d_nchannels; i++) { - if (d_gnss_synchro_history_queue[i].size() < history_deep) - { - channel_history_ok = false; - } - } - if (channel_history_ok == true) - { - std::map::const_iterator gnss_synchro_map_iter; - std::deque::const_iterator gnss_synchro_deque_iter; - - // 1. If the RX time is not set, set the Rx time - if (T_rx_s == 0) - { - // 0. Read a gnss_synchro snapshot from the queue and store it in a map - std::map gnss_synchro_map; - for (unsigned int i = 0; i < d_nchannels; i++) - { - gnss_synchro_map.insert(std::pair(d_gnss_synchro_history_queue[i].front().Channel_ID, - d_gnss_synchro_history_queue[i].front())); - } - gnss_synchro_map_iter = min_element(gnss_synchro_map.cbegin(), - gnss_synchro_map.cend(), - Hybrid_pairCompare_gnss_synchro_sample_counter); - T_rx_s = static_cast(gnss_synchro_map_iter->second.Tracking_sample_counter) / static_cast(gnss_synchro_map_iter->second.fs); - T_rx_s = floor(T_rx_s * 1000.0) / 1000.0; // truncate to ms - T_rx_s += past_history_s; // increase T_rx to have a minimum past history to interpolate - } - - // 2. Realign RX time in all valid channels - std::map realigned_gnss_synchro_map; // container for the aligned set of observables for the selected T_rx - std::map adjacent_gnss_synchro_map; // container for the previous observable values to interpolate - // shift channels history to match the reference TOW + channel_history_ok = true; for (unsigned int i = 0; i < d_nchannels; i++) - { - gnss_synchro_deque_iter = std::lower_bound(d_gnss_synchro_history_queue[i].cbegin(), - d_gnss_synchro_history_queue[i].cend(), - T_rx_s, - Hybrid_valueCompare_gnss_synchro_receiver_time); - if (gnss_synchro_deque_iter != d_gnss_synchro_history_queue[i].cend()) { - if (gnss_synchro_deque_iter->Flag_valid_word == true) - { - double T_rx_channel = static_cast(gnss_synchro_deque_iter->Tracking_sample_counter) / static_cast(gnss_synchro_deque_iter->fs); - double delta_T_rx_s = T_rx_channel - T_rx_s; - - // check that T_rx difference is less than a threshold (the correlation interval) - if (delta_T_rx_s * 1000.0 < static_cast(gnss_synchro_deque_iter->correlation_length_ms)) + if (d_gnss_synchro_history_queue[i].size() < history_deep) { - // record the word structure in a map for pseudorange computation - // save the previous observable - int distance = std::distance(d_gnss_synchro_history_queue[i].cbegin(), gnss_synchro_deque_iter); - if (distance > 0) - { - if (d_gnss_synchro_history_queue[i].at(distance - 1).Flag_valid_word) + channel_history_ok = false; + } + } + if (channel_history_ok == true) + { + std::map::const_iterator gnss_synchro_map_iter; + std::deque::const_iterator gnss_synchro_deque_iter; + + // 1. If the RX time is not set, set the Rx time + if (T_rx_s == 0) + { + // 0. Read a gnss_synchro snapshot from the queue and store it in a map + std::map gnss_synchro_map; + for (unsigned int i = 0; i < d_nchannels; i++) { - double T_rx_channel_prev = static_cast(d_gnss_synchro_history_queue[i].at(distance - 1).Tracking_sample_counter) / static_cast(gnss_synchro_deque_iter->fs); - double delta_T_rx_s_prev = T_rx_channel_prev - T_rx_s; - if (fabs(delta_T_rx_s_prev) < fabs(delta_T_rx_s)) + gnss_synchro_map.insert(std::pair(d_gnss_synchro_history_queue[i].front().Channel_ID, + d_gnss_synchro_history_queue[i].front())); + } + gnss_synchro_map_iter = min_element(gnss_synchro_map.cbegin(), + gnss_synchro_map.cend(), + Hybrid_pairCompare_gnss_synchro_sample_counter); + T_rx_s = static_cast(gnss_synchro_map_iter->second.Tracking_sample_counter) / static_cast(gnss_synchro_map_iter->second.fs); + T_rx_s = floor(T_rx_s * 1000.0) / 1000.0; // truncate to ms + T_rx_s += past_history_s; // increase T_rx to have a minimum past history to interpolate + } + + // 2. Realign RX time in all valid channels + std::map realigned_gnss_synchro_map; // container for the aligned set of observables for the selected T_rx + std::map adjacent_gnss_synchro_map; // container for the previous observable values to interpolate + // shift channels history to match the reference TOW + for (unsigned int i = 0; i < d_nchannels; i++) + { + gnss_synchro_deque_iter = std::lower_bound(d_gnss_synchro_history_queue[i].cbegin(), + d_gnss_synchro_history_queue[i].cend(), + T_rx_s, + Hybrid_valueCompare_gnss_synchro_receiver_time); + if (gnss_synchro_deque_iter != d_gnss_synchro_history_queue[i].cend()) + { + if (gnss_synchro_deque_iter->Flag_valid_word == true) + { + double T_rx_channel = static_cast(gnss_synchro_deque_iter->Tracking_sample_counter) / static_cast(gnss_synchro_deque_iter->fs); + double delta_T_rx_s = T_rx_channel - T_rx_s; + + // check that T_rx difference is less than a threshold (the correlation interval) + if (delta_T_rx_s * 1000.0 < static_cast(gnss_synchro_deque_iter->correlation_length_ms)) + { + // record the word structure in a map for pseudorange computation + // save the previous observable + int distance = std::distance(d_gnss_synchro_history_queue[i].cbegin(), gnss_synchro_deque_iter); + if (distance > 0) + { + if (d_gnss_synchro_history_queue[i].at(distance - 1).Flag_valid_word) + { + double T_rx_channel_prev = static_cast(d_gnss_synchro_history_queue[i].at(distance - 1).Tracking_sample_counter) / static_cast(gnss_synchro_deque_iter->fs); + double delta_T_rx_s_prev = T_rx_channel_prev - T_rx_s; + if (fabs(delta_T_rx_s_prev) < fabs(delta_T_rx_s)) + { + realigned_gnss_synchro_map.insert(std::pair(d_gnss_synchro_history_queue[i].at(distance - 1).Channel_ID, + d_gnss_synchro_history_queue[i].at(distance - 1))); + adjacent_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); + } + else + { + realigned_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); + adjacent_gnss_synchro_map.insert(std::pair(d_gnss_synchro_history_queue[i].at(distance - 1).Channel_ID, + d_gnss_synchro_history_queue[i].at(distance - 1))); + } + } + } + else + { + realigned_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); + } + + } + } + } + } + + if(!realigned_gnss_synchro_map.empty()) + { + /* + * 2.1 Use CURRENT set of measurements and find the nearest satellite + * common RX time algorithm + */ + // what is the most recent symbol TOW in the current set? -> this will be the reference symbol + gnss_synchro_map_iter = max_element(realigned_gnss_synchro_map.cbegin(), + realigned_gnss_synchro_map.cend(), + Hybrid_pairCompare_gnss_synchro_d_TOW); + double ref_fs_hz = static_cast(gnss_synchro_map_iter->second.fs); + + // compute interpolated TOW value at T_rx_s + int ref_channel_key = gnss_synchro_map_iter->second.Channel_ID; + Gnss_Synchro adj_obs = adjacent_gnss_synchro_map.at(ref_channel_key); + double ref_adj_T_rx_s = static_cast(adj_obs.Tracking_sample_counter) / ref_fs_hz + adj_obs.Code_phase_samples / ref_fs_hz; + + double d_TOW_reference = gnss_synchro_map_iter->second.TOW_at_current_symbol_s; + double d_ref_T_rx_s = static_cast(gnss_synchro_map_iter->second.Tracking_sample_counter) / ref_fs_hz + gnss_synchro_map_iter->second.Code_phase_samples / ref_fs_hz; + + double selected_T_rx_s = T_rx_s; + // two points linear interpolation using adjacent (adj) values: y=y1+(x-x1)*(y2-y1)/(x2-x1) + double ref_TOW_at_T_rx_s = adj_obs.TOW_at_current_symbol_s + + (selected_T_rx_s - ref_adj_T_rx_s) * (d_TOW_reference - adj_obs.TOW_at_current_symbol_s) / (d_ref_T_rx_s - ref_adj_T_rx_s); + + // Now compute RX time differences due to the PRN alignment in the correlators + double traveltime_ms; + double pseudorange_m; + double channel_T_rx_s; + double channel_fs_hz; + double channel_TOW_s; + for(gnss_synchro_map_iter = realigned_gnss_synchro_map.cbegin(); gnss_synchro_map_iter != realigned_gnss_synchro_map.cend(); gnss_synchro_map_iter++) + { + channel_fs_hz = static_cast(gnss_synchro_map_iter->second.fs); + channel_TOW_s = gnss_synchro_map_iter->second.TOW_at_current_symbol_s; + channel_T_rx_s = static_cast(gnss_synchro_map_iter->second.Tracking_sample_counter) / channel_fs_hz + gnss_synchro_map_iter->second.Code_phase_samples / channel_fs_hz; + // compute interpolated observation values + // two points linear interpolation using adjacent (adj) values: y=y1+(x-x1)*(y2-y1)/(x2-x1) + // TOW at the selected receiver time T_rx_s + int element_key = gnss_synchro_map_iter->second.Channel_ID; + adj_obs = adjacent_gnss_synchro_map.at(element_key); + + double adj_T_rx_s = static_cast(adj_obs.Tracking_sample_counter) / channel_fs_hz + adj_obs.Code_phase_samples / channel_fs_hz; + + double channel_TOW_at_T_rx_s = adj_obs.TOW_at_current_symbol_s + (selected_T_rx_s - adj_T_rx_s) * (channel_TOW_s - adj_obs.TOW_at_current_symbol_s) / (channel_T_rx_s - adj_T_rx_s); + + // Doppler and Accumulated carrier phase + double Carrier_phase_lin_rads = adj_obs.Carrier_phase_rads + (selected_T_rx_s - adj_T_rx_s) * (gnss_synchro_map_iter->second.Carrier_phase_rads - adj_obs.Carrier_phase_rads) / (channel_T_rx_s - adj_T_rx_s); + double Carrier_Doppler_lin_hz = adj_obs.Carrier_Doppler_hz + (selected_T_rx_s - adj_T_rx_s) * (gnss_synchro_map_iter->second.Carrier_Doppler_hz - adj_obs.Carrier_Doppler_hz) / (channel_T_rx_s - adj_T_rx_s); + + // compute the pseudorange (no rx time offset correction) + traveltime_ms = (ref_TOW_at_T_rx_s - channel_TOW_at_T_rx_s) * 1000.0 + GPS_STARTOFFSET_ms; + // convert to meters + pseudorange_m = traveltime_ms * GPS_C_m_ms; // [m] + // update the pseudorange object + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID] = gnss_synchro_map_iter->second; + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Pseudorange_m = pseudorange_m; + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Flag_valid_pseudorange = true; + // Save the estimated RX time (no RX clock offset correction yet!) + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].RX_time = ref_TOW_at_T_rx_s + GPS_STARTOFFSET_ms / 1000.0; + + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Carrier_phase_rads = Carrier_phase_lin_rads; + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Carrier_Doppler_hz = Carrier_Doppler_lin_hz; + } + + if(d_dump == true) + { + // MULTIPLEXED FILE RECORDING - Record results to file + try { - realigned_gnss_synchro_map.insert(std::pair(d_gnss_synchro_history_queue[i].at(distance - 1).Channel_ID, - d_gnss_synchro_history_queue[i].at(distance - 1))); - adjacent_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); + double tmp_double; + for (unsigned int i = 0; i < d_nchannels; i++) + { + tmp_double = current_gnss_synchro[i].RX_time; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = current_gnss_synchro[i].TOW_at_current_symbol_s; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = current_gnss_synchro[i].Carrier_Doppler_hz; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = current_gnss_synchro[i].Carrier_phase_rads / GPS_TWO_PI; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = current_gnss_synchro[i].Pseudorange_m; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = current_gnss_synchro[i].PRN; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = static_cast(current_gnss_synchro[i].Flag_valid_pseudorange); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + } } - else + catch (const std::ifstream::failure& e) { - realigned_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); - adjacent_gnss_synchro_map.insert(std::pair(d_gnss_synchro_history_queue[i].at(distance - 1).Channel_ID, - d_gnss_synchro_history_queue[i].at(distance - 1))); + LOG(WARNING) << "Exception writing observables dump file " << e.what(); } } - } - else - { - realigned_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); - } + for (unsigned int i = 0; i < d_nchannels; i++) + { + out[i][n_outputs] = current_gnss_synchro[i]; + } + + n_outputs++; } - } - } - } - if(!realigned_gnss_synchro_map.empty()) - { - /* - * 2.1 Use CURRENT set of measurements and find the nearest satellite - * common RX time algorithm - */ - // what is the most recent symbol TOW in the current set? -> this will be the reference symbol - gnss_synchro_map_iter = max_element(realigned_gnss_synchro_map.cbegin(), - realigned_gnss_synchro_map.cend(), - Hybrid_pairCompare_gnss_synchro_d_TOW); - double ref_fs_hz = static_cast(gnss_synchro_map_iter->second.fs); - - // compute interpolated TOW value at T_rx_s - int ref_channel_key = gnss_synchro_map_iter->second.Channel_ID; - Gnss_Synchro adj_obs = adjacent_gnss_synchro_map.at(ref_channel_key); - double ref_adj_T_rx_s = static_cast(adj_obs.Tracking_sample_counter) / ref_fs_hz + adj_obs.Code_phase_samples / ref_fs_hz; - - double d_TOW_reference = gnss_synchro_map_iter->second.TOW_at_current_symbol_s; - double d_ref_T_rx_s = static_cast(gnss_synchro_map_iter->second.Tracking_sample_counter) / ref_fs_hz + gnss_synchro_map_iter->second.Code_phase_samples / ref_fs_hz; - - double selected_T_rx_s = T_rx_s; - // two points linear interpolation using adjacent (adj) values: y=y1+(x-x1)*(y2-y1)/(x2-x1) - double ref_TOW_at_T_rx_s = adj_obs.TOW_at_current_symbol_s + - (selected_T_rx_s - ref_adj_T_rx_s) * (d_TOW_reference - adj_obs.TOW_at_current_symbol_s) / (d_ref_T_rx_s - ref_adj_T_rx_s); - - // Now compute RX time differences due to the PRN alignment in the correlators - double traveltime_ms; - double pseudorange_m; - double channel_T_rx_s; - double channel_fs_hz; - double channel_TOW_s; - for(gnss_synchro_map_iter = realigned_gnss_synchro_map.cbegin(); gnss_synchro_map_iter != realigned_gnss_synchro_map.cend(); gnss_synchro_map_iter++) - { - channel_fs_hz = static_cast(gnss_synchro_map_iter->second.fs); - channel_TOW_s = gnss_synchro_map_iter->second.TOW_at_current_symbol_s; - channel_T_rx_s = static_cast(gnss_synchro_map_iter->second.Tracking_sample_counter) / channel_fs_hz + gnss_synchro_map_iter->second.Code_phase_samples / channel_fs_hz; - // compute interpolated observation values - // two points linear interpolation using adjacent (adj) values: y=y1+(x-x1)*(y2-y1)/(x2-x1) - // TOW at the selected receiver time T_rx_s - int element_key = gnss_synchro_map_iter->second.Channel_ID; - adj_obs = adjacent_gnss_synchro_map.at(element_key); - - double adj_T_rx_s = static_cast(adj_obs.Tracking_sample_counter) / channel_fs_hz + adj_obs.Code_phase_samples / channel_fs_hz; - - double channel_TOW_at_T_rx_s = adj_obs.TOW_at_current_symbol_s + (selected_T_rx_s - adj_T_rx_s) * (channel_TOW_s - adj_obs.TOW_at_current_symbol_s) / (channel_T_rx_s - adj_T_rx_s); - - // Doppler and Accumulated carrier phase - double Carrier_phase_lin_rads = adj_obs.Carrier_phase_rads + (selected_T_rx_s - adj_T_rx_s) * (gnss_synchro_map_iter->second.Carrier_phase_rads - adj_obs.Carrier_phase_rads) / (channel_T_rx_s - adj_T_rx_s); - double Carrier_Doppler_lin_hz = adj_obs.Carrier_Doppler_hz + (selected_T_rx_s - adj_T_rx_s) * (gnss_synchro_map_iter->second.Carrier_Doppler_hz - adj_obs.Carrier_Doppler_hz) / (channel_T_rx_s - adj_T_rx_s); - - // compute the pseudorange (no rx time offset correction) - traveltime_ms = (ref_TOW_at_T_rx_s - channel_TOW_at_T_rx_s) * 1000.0 + GPS_STARTOFFSET_ms; - // convert to meters - pseudorange_m = traveltime_ms * GPS_C_m_ms; // [m] - // update the pseudorange object - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID] = gnss_synchro_map_iter->second; - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Pseudorange_m = pseudorange_m; - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Flag_valid_pseudorange = true; - // Save the estimated RX time (no RX clock offset correction yet!) - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].RX_time = ref_TOW_at_T_rx_s + GPS_STARTOFFSET_ms / 1000.0; - - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Carrier_phase_rads = Carrier_phase_lin_rads; - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Carrier_Doppler_hz = Carrier_Doppler_lin_hz; - } - - if(d_dump == true) - { - // MULTIPLEXED FILE RECORDING - Record results to file - try - { - double tmp_double; - for (unsigned int i = 0; i < d_nchannels; i++) + // Move RX time + T_rx_s = T_rx_s + T_rx_step_s; + // pop old elements from queue + for (unsigned int i = 0; i < d_nchannels; i++) { - tmp_double = current_gnss_synchro[i].RX_time; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = current_gnss_synchro[i].TOW_at_current_symbol_s; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = current_gnss_synchro[i].Carrier_Doppler_hz; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = current_gnss_synchro[i].Carrier_phase_rads / GPS_TWO_PI; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = current_gnss_synchro[i].Pseudorange_m; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = current_gnss_synchro[i].PRN; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = static_cast(current_gnss_synchro[i].Flag_valid_pseudorange); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + while (static_cast(d_gnss_synchro_history_queue[i].front().Tracking_sample_counter) / static_cast(d_gnss_synchro_history_queue[i].front().fs) < (T_rx_s - past_history_s)) + { + d_gnss_synchro_history_queue[i].pop_front(); + } } - } - catch (const std::ifstream::failure& e) - { - LOG(WARNING) << "Exception writing observables dump file " << e.what(); - } } - - for (unsigned int i = 0; i < d_nchannels; i++) - { - out[i][n_outputs] = current_gnss_synchro[i]; - } - - n_outputs++; - } - - // Move RX time - T_rx_s = T_rx_s + T_rx_step_s; - // pop old elements from queue - for (unsigned int i = 0; i < d_nchannels; i++) - { - while (static_cast(d_gnss_synchro_history_queue[i].front().Tracking_sample_counter) / static_cast(d_gnss_synchro_history_queue[i].front().fs) < (T_rx_s - past_history_s)) - { - d_gnss_synchro_history_queue[i].pop_front(); - } - } - } - } while(channel_history_ok == true && noutput_items > n_outputs); + } while(channel_history_ok == true && noutput_items > n_outputs); // Multi-rate consume! for (unsigned int i = 0; i < d_nchannels; i++) - { - consume(i, n_consume[i]); // which input, how many items - } + { + consume(i, n_consume[i]); // which input, how many items + } return n_outputs; } From 59c153846c6fd10e730d8db43eddbc1859fd231e Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 17 Jan 2018 19:06:39 +0100 Subject: [PATCH 39/96] Remove blank line --- .../observables/gnuradio_blocks/hybrid_observables_cc.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc index 40b18599d..0afa10b52 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc @@ -328,7 +328,6 @@ bool Hybrid_valueCompare_gnss_synchro_d_TOW(const Gnss_Synchro& a, double b) void hybrid_observables_cc::forecast (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required) { - bool zero_samples = true; for(unsigned int i = 0; i < d_nchannels; i++) { From bc922404438afc6cc7a9c36012266bf8e4830589 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 17 Jan 2018 19:11:42 +0100 Subject: [PATCH 40/96] Replace C-style cast by C++ casts --- .../observables/gnuradio_blocks/hybrid_observables_cc.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc index 0afa10b52..efd29e092 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc @@ -310,7 +310,7 @@ bool Hybrid_valueCompare_gnss_synchro_sample_counter(const Gnss_Synchro& a, unsi bool Hybrid_valueCompare_gnss_synchro_receiver_time(const Gnss_Synchro& a, double b) { - return (((double)a.Tracking_sample_counter+a.Code_phase_samples)/(double)a.fs) < (b); + return ((static_cast(a.Tracking_sample_counter) + static_cast(a.Code_phase_samples)) / static_cast(a.fs) ) < (b); } @@ -331,8 +331,8 @@ void hybrid_observables_cc::forecast (int noutput_items __attribute__((unused)), bool zero_samples = true; for(unsigned int i = 0; i < d_nchannels; i++) { - int items=detail()->input(i)->items_available(); - if (items>0) zero_samples = false; + int items = detail()->input(i)->items_available(); + if (items > 0) zero_samples = false; ninput_items_required[i] = items; // set the required available samples in each call } From dc717db61e5e4ab8048c1d8cb57b9501bd70d6ad Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 18 Jan 2018 15:27:38 +0100 Subject: [PATCH 41/96] Minor fixes --- .../galileo_e1_dll_pll_veml_tracking_cc.cc | 406 +++++++++--------- 1 file changed, 203 insertions(+), 203 deletions(-) diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc index 0fd20887b..a818da13d 100755 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc @@ -194,7 +194,7 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc( d_track_pilot = track_pilot; if (d_track_pilot) { - //extended integration control + // extended integration control if (d_extend_correlation_symbols > 1) { d_enable_extended_integration = true; @@ -203,7 +203,7 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc( { d_enable_extended_integration = false; } - //Extra correlator for the data component + // Extra correlator for the data component d_local_code_data_shift_chips = static_cast(volk_gnsssdr_malloc(sizeof(float), volk_gnsssdr_get_alignment())); d_local_code_data_shift_chips[0] = 0.0; correlator_data_cpu.init(2 * d_correlation_length_samples, 1); @@ -251,7 +251,7 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc( d_carrier_doppler_hz = 0.0; d_acc_carrier_phase_rad = 0.0; - d_state = 0;// intial state: stanby + d_state = 0; // initial state: standby } @@ -320,7 +320,7 @@ void galileo_e1_dll_pll_veml_tracking_cc::start_tracking() d_acquisition_gnss_synchro->PRN, Galileo_E1_CODE_CHIP_RATE_HZ, 0); - d_Prompt_Data[0] = gr_complex(0,0); //clean data correlator output + d_Prompt_Data[0] = gr_complex(0,0); // clean data correlator output correlator_data_cpu.set_local_code_and_taps(static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS), d_data_code, d_local_code_shift_chips); @@ -574,73 +574,73 @@ void galileo_e1_dll_pll_veml_tracking_cc::clear_tracking_vars() void galileo_e1_dll_pll_veml_tracking_cc::log_data() { if(d_dump) - { - // Dump results to file - float prompt_I; - float prompt_Q; - float tmp_VE, tmp_E, tmp_P, tmp_L, tmp_VL; - float tmp_float; - double tmp_double; - - prompt_I = static_cast(d_P_accu.real()); - prompt_Q = static_cast(d_P_accu.imag()); - - tmp_VE = std::abs(d_VE_accu); - tmp_E = std::abs(d_E_accu); - tmp_P = std::abs(d_P_accu); - tmp_L = std::abs(d_L_accu); - tmp_VL = std::abs(d_VL_accu); - - try { - // Dump correlators output - d_dump_file.write(reinterpret_cast(&tmp_VE), sizeof(float)); - d_dump_file.write(reinterpret_cast(&tmp_E), sizeof(float)); - d_dump_file.write(reinterpret_cast(&tmp_P), sizeof(float)); - d_dump_file.write(reinterpret_cast(&tmp_L), sizeof(float)); - d_dump_file.write(reinterpret_cast(&tmp_VL), sizeof(float)); - // PROMPT I and Q (to analyze navigation symbols) - d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); - d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); - // PRN start sample stamp - d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); - // accumulated carrier phase - tmp_float = d_acc_carrier_phase_rad; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - // carrier and code frequency - tmp_float = d_carrier_doppler_hz; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - tmp_float = d_code_freq_chips; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - // PLL commands - tmp_float = d_carr_error_hz; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - tmp_float = d_carr_error_filt_hz; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - // DLL commands - tmp_float = d_code_error_chips; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - tmp_float = d_code_error_filt_chips; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - // CN0 and carrier lock test - tmp_float = d_CN0_SNV_dB_Hz; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - tmp_float = d_carrier_lock_test; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - // AUX vars (for debug purposes) - tmp_float = d_rem_code_phase_samples; - d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - tmp_double = static_cast(d_sample_counter + d_current_prn_length_samples); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - // PRN - unsigned int prn_ = d_acquisition_gnss_synchro->PRN; - d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + // Dump results to file + float prompt_I; + float prompt_Q; + float tmp_VE, tmp_E, tmp_P, tmp_L, tmp_VL; + float tmp_float; + double tmp_double; + + prompt_I = static_cast(d_P_accu.real()); + prompt_Q = static_cast(d_P_accu.imag()); + + tmp_VE = std::abs(d_VE_accu); + tmp_E = std::abs(d_E_accu); + tmp_P = std::abs(d_P_accu); + tmp_L = std::abs(d_L_accu); + tmp_VL = std::abs(d_VL_accu); + + try + { + // Dump correlators output + d_dump_file.write(reinterpret_cast(&tmp_VE), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_E), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_P), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_L), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_VL), sizeof(float)); + // PROMPT I and Q (to analyze navigation symbols) + d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); + d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); + // PRN start sample stamp + d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + // accumulated carrier phase + tmp_float = d_acc_carrier_phase_rad; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + // carrier and code frequency + tmp_float = d_carrier_doppler_hz; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_float = d_code_freq_chips; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + // PLL commands + tmp_float = d_carr_error_hz; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_float = d_carr_error_filt_hz; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + // DLL commands + tmp_float = d_code_error_chips; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_float = d_code_error_filt_chips; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + // CN0 and carrier lock test + tmp_float = d_CN0_SNV_dB_Hz; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_float = d_carrier_lock_test; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + // AUX vars (for debug purposes) + tmp_float = d_rem_code_phase_samples; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_double = static_cast(d_sample_counter + d_current_prn_length_samples); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + // PRN + unsigned int prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "Exception writing trk dump file " << e.what(); + } } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "Exception writing trk dump file " << e.what(); - } - } } @@ -685,7 +685,7 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attri { // Fill the acquisition data current_synchro_data = *d_acquisition_gnss_synchro; - //Current NCO and code generator parameters + // Current NCO and code generator parameters d_carrier_phase_step_rad = GALILEO_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); d_code_phase_step_chips = d_code_freq_chips / static_cast(d_fs_in); d_rem_code_phase_chips = d_rem_code_phase_samples * d_code_freq_chips / d_fs_in; @@ -697,7 +697,7 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attri d_P_accu = *d_Prompt; d_L_accu = *d_Late; d_VL_accu = *d_Very_Late; - //check lock status + // check lock status if (cn0_and_tracking_lock_status() == false) { clear_tracking_vars(); @@ -727,7 +727,7 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attri double T_prn_seconds = T_chip_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS; double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); double K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * static_cast(d_fs_in); - d_current_prn_length_samples = round(K_blk_samples); // round to a discrete samples + d_current_prn_length_samples = round(K_blk_samples); // round to a discrete number of samples // ########### Output the tracking results to Telemetry block ########## if (d_track_pilot) @@ -763,7 +763,7 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attri if (acquire_secondary() == true) { d_extend_correlation_symbols_count = 0; - //reset extended correlator + // reset extended correlator d_VE_accu = gr_complex(0,0); d_E_accu = gr_complex(0,0); d_P_accu = gr_complex(0,0); @@ -995,12 +995,12 @@ int galileo_e1_dll_pll_veml_tracking_cc::save_matfile() dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { - dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); } catch(const std::ifstream::failure &e) { - std::cerr << "Problem opening dump file:" << e.what() << std::endl; - return 1; + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return 1; } // count number of epochs and rewind long int num_epoch = 0; @@ -1037,58 +1037,58 @@ int galileo_e1_dll_pll_veml_tracking_cc::save_matfile() try { - if (dump_file.is_open()) - { - for(long int i = 0; i < num_epoch; i++) - { - dump_file.read(reinterpret_cast(&abs_VE[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&abs_VL[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); - dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&carr_error_hz[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&carr_error_filt_hz[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&code_error_chips[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&code_error_filt_chips[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&CN0_SNV_dB_Hz[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&aux1[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); - dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); - } - } - dump_file.close(); + if (dump_file.is_open()) + { + for(long int i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&abs_VE[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_VL[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carr_error_hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carr_error_filt_hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&code_error_chips[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&code_error_filt_chips[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&CN0_SNV_dB_Hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&aux1[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + } + } + dump_file.close(); } catch (const std::ifstream::failure &e) { - std::cerr << "Problem reading dump file:" << e.what() << std::endl; - delete[] abs_VE; - delete[] abs_E; - delete[] abs_P; - delete[] abs_L; - delete[] abs_VL; - delete[] Prompt_I; - delete[] Prompt_Q; - delete[] PRN_start_sample_count; - delete[] acc_carrier_phase_rad; - delete[] carrier_doppler_hz; - delete[] code_freq_chips; - delete[] carr_error_hz; - delete[] carr_error_filt_hz; - delete[] code_error_chips; - delete[] code_error_filt_chips; - delete[] CN0_SNV_dB_Hz; - delete[] carrier_lock_test; - delete[] aux1; - delete[] aux2; - delete[] PRN; - return 1; + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + delete[] abs_VE; + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] abs_VL; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 1; } // WRITE MAT FILE @@ -1099,88 +1099,88 @@ int galileo_e1_dll_pll_veml_tracking_cc::save_matfile() filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); if(reinterpret_cast(matfp) != NULL) - { - size_t dims[2] = {1, static_cast(num_epoch)}; - matvar = Mat_VarCreate("abs_VE", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + { + size_t dims[2] = {1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("abs_VE", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("abs_VL", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("abs_VL", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, acc_carrier_phase_rad, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, acc_carrier_phase_rad, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carrier_doppler_hz, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carrier_doppler_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("code_freq_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_freq_chips, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("code_freq_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_freq_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("carr_error_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carr_error_hz, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("carr_error_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carr_error_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carr_error_filt_hz, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carr_error_filt_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("code_error_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_error_chips, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("code_error_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_error_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_error_filt_chips, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_error_filt_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, CN0_SNV_dB_Hz, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, CN0_SNV_dB_Hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("carrier_lock_test", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carrier_lock_test, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("carrier_lock_test", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carrier_lock_test, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("aux1", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, aux1, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("aux1", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, aux1, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); - } + matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } Mat_Close(matfp); delete[] abs_VE; delete[] abs_E; @@ -1212,23 +1212,23 @@ void galileo_e1_dll_pll_veml_tracking_cc::set_channel(unsigned int channel) LOG(INFO) << "Tracking Channel set to " << d_channel; // ############# ENABLE DATA FILE LOG ################# if (d_dump == true) - { - if (d_dump_file.is_open() == false) { - try - { - d_dump_filename.append(boost::lexical_cast(d_channel)); - d_dump_filename.append(".dat"); - d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit); - d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str(); - } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); - } + if (d_dump_file.is_open() == false) + { + try + { + d_dump_filename.append(boost::lexical_cast(d_channel)); + d_dump_filename.append(".dat"); + d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit); + d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str(); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); + } + } } - } } From 4bbd994f6079a4ae9522ff214845a243af901c69 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 18 Jan 2018 15:49:05 +0100 Subject: [PATCH 42/96] Add a note explaining how to activate the bias-tee in a RTL-SDR Blog V3 dongle, so it can feed an active antenna (see #77) The activation is done by adding SignalSource.osmosdr_args=rtl,bias=1 to the configuration file, if using gr-osmosdr >= 0.1.4-13 For older versions of gr-osmosdr, you can use https://github.com/rtlsdrblog/rtl_biast --- conf/front-end-cal.conf | 31 ++++++++++++----------- conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf | 16 ++++++++++-- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/conf/front-end-cal.conf b/conf/front-end-cal.conf index af9221936..8b09a2065 100644 --- a/conf/front-end-cal.conf +++ b/conf/front-end-cal.conf @@ -41,17 +41,10 @@ GNSS-SDR.SUPL_LAC=861 GNSS-SDR.SUPL_CI=40184 ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] or [Osmosdr_Signal_Source] SignalSource.implementation=Osmosdr_Signal_Source -SignalSource.AGC_enabled=false - -;#filename: path to file with the captured GNSS signal samples to be processed -;SignalSource.filename=/datalogger/signals/RTL-SDR/cap_-90dBm_IF15_RF40_EzCap.dat -SignalSource.filename=/datalogger/signals/Agilent/New York/2msps.dat -;SignalSource.filename=/datalogger/signals/RTL-SDR/geo/pmt4_no_amp.dat -;SignalSource.filename=/datalogger/signals/RTL-SDR/geo/pmt4_no_amp_mini.dat -;SignalSource.filename=/datalogger/signals/RTL-SDR/mozoncillo/cap_mozon_ezcap.dat +;#freq: RF front-end center frequency in [Hz] +SignalSource.freq=1575420000 ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource.item_type=gr_complex @@ -59,18 +52,26 @@ SignalSource.item_type=gr_complex ;#sampling_frequency: Original Signal sampling frequency in [Hz] SignalSource.sampling_frequency=2000000 -;#freq: RF front-end center frequency in [Hz] -SignalSource.freq=1575420000 - ;#gain: Front-end Gain in [dB] SignalSource.gain=40 SignalSource.rf_gain=40 SignalSource.if_gain=30 +SignalSource.AGC_enabled=false -;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0) -SignalSource.subdevice=B:0 +;# Please note that the new RTL-SDR Blog V3 dongles ship a < 1 PPM +;# temperature compensated oscillator (TCXO), which is well suited for GNSS +;# signal processing, and a 4.5 V powered bias-tee to feed an active antenna. +;# Whether the bias-tee is turned off before reception depends on which version +;# of gr-osmosdr was used when compiling GNSS-SDR. With an old version +;# (for example, v0.1.4-8), the utility rtl_biast may be used to switch the +;# bias-tee, and then call gnss-sdr. +;# See https://github.com/rtlsdrblog/rtl_biast +;# After reception the bias-tee is switched off automatically by the program. +;# With newer versions of gr-osmosdr (>= 0.1.4-13), the bias-tee can be +;# activated by uncommenting the following line: +;SignalSource.osmosdr_args=rtl,bias=1 -;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. +;#samples: Number of samples to be processed. Notice that 0 means infinite samples. SignalSource.samples=0 ;#repeat: Repeat the processing file. diff --git a/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf b/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf index 8c5f9022a..2c10ea684 100644 --- a/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf @@ -27,9 +27,8 @@ GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ SignalSource.implementation=Osmosdr_Signal_Source -;SignalSource.filename=/media/DATALOGGER_/signals/RTL-SDR/geo/pmt4.dat SignalSource.item_type=gr_complex -;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE +; FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE ; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ SignalSource.sampling_frequency=2000000 SignalSource.freq=1575420000 @@ -43,6 +42,19 @@ SignalSource.dump=false SignalSource.dump_filename=../data/signal_source.dat SignalSource.enable_throttle_control=false +;# Please note that the new RTL-SDR Blog V3 dongles ship a < 1 PPM +;# temperature compensated oscillator (TCXO), which is well suited for GNSS +;# signal processing, and a 4.5 V powered bias-tee to feed an active antenna. +;# Whether the bias-tee is turned off before reception depends on which version +;# of gr-osmosdr was used when compiling GNSS-SDR. With an old version +;# (for example, v0.1.4-8), the utility rtl_biast may be used to switch the +;# bias-tee, and then call gnss-sdr. +;# See https://github.com/rtlsdrblog/rtl_biast +;# After reception the bias-tee is switched off automatically by the program. +;# With newer versions of gr-osmosdr (>= 0.1.4-13), the bias-tee can be +;# activated by uncommenting the following line: +;SignalSource.osmosdr_args=rtl,bias=1 + ;######### SIGNAL_CONDITIONER CONFIG ############ SignalConditioner.implementation=Signal_Conditioner From 4873ea2b88720f4091b1f8a92bda3f7c9e5ede7f Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Thu, 18 Jan 2018 16:57:15 +0100 Subject: [PATCH 43/96] Fix GSS6450 signal source --- .../spir_gss6450_file_signal_source.cc | 141 ++++++++++-------- .../spir_gss6450_file_signal_source.h | 19 ++- .../unpack_spir_gss6450_samples.cc | 133 +++++++---------- .../unpack_spir_gss6450_samples.h | 33 ++-- 4 files changed, 153 insertions(+), 173 deletions(-) diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc index ede0abb72..590c60c33 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc @@ -1,12 +1,12 @@ /*! - * \file spir_file_signal_source.cc + * \file spir_gss6450_file_signal_source.cc * \brief Implementation of a class that reads signals samples from a SPIR file * and adapts it to a SignalSourceInterface. - * \author Fran Fabra, 2014 fabra(at)ice.csic.es + * \author Antonio Ramos, 2017 antonio.ramos(at)cttc.es * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -35,16 +35,11 @@ #include #include #include -#include #include #include "configuration_interface.h" - using google::LogMessage; -DEFINE_string(spir_gss6450_signal_source, "-", - "If defined, path to the file containing the Spirent GSS6450 signal samples (overrides the configuration file)"); - SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams, gr::msg_queue::sptr queue) : @@ -55,31 +50,35 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* item_type_ = "int"; samples_ = configuration->property(role + ".samples", 0); - sampling_frequency_ = configuration->property(role + ".sampling_frequency", 0); + sampling_frequency_ = configuration->property(role + ".sampling_frequency", 0.0); filename_ = configuration->property(role + ".filename", default_filename); - - // override value with commandline flag, if present - if (FLAGS_spir_gss6450_signal_source.compare("-") != 0) filename_= FLAGS_spir_gss6450_signal_source; - repeat_ = configuration->property(role + ".repeat", false); dump_ = configuration->property(role + ".dump", false); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); enable_throttle_control_ = configuration->property(role + ".enable_throttle_control", false); adc_bits_ = configuration->property(role + ".adc_bits", 4); - n_channels_ = configuration->property(role + ".RF_channels", 1); + n_channels_ = configuration->property(role + ".total_channels", 1); sel_ch_ = configuration->property(role + ".sel_ch", 1); item_size_ = sizeof(int); - long bytes_seek = 65536; + long bytes_seek = configuration->property(role + ".bytes_to_skip", 65536); double sample_size_byte = static_cast(adc_bits_) / 4.0; - int samples_per_item = 16 / adc_bits_; if(sel_ch_ > n_channels_) { LOG(WARNING) << "Invalid RF channel selection"; } + if(n_channels_ > 1) + { + for(unsigned int i = 0; i < (n_channels_ - 1); i++) + { + null_sinks_.push_back(gr::blocks::null_sink::make(item_size_)); + } + std::cout << "NUMBER OF NULL SINKS = " << null_sinks_.size() << std::endl; + } try { - file_source_ = gr::blocks::file_source::make(item_size_, filename_.c_str(), repeat_); - file_source_->seek(bytes_seek, SEEK_SET); - unpack_ii_ = gr::blocks::packed_to_unpacked_ii::make(adc_bits_, gr::GR_MSB_FIRST); - unpack_spir_ = make_unpack_spir_gss6450_samples(n_channels_, sel_ch_, samples_per_item, item_size_); + file_source_ = gr::blocks::file_source::make(item_size_, filename_.c_str(), repeat_); + file_source_->seek(bytes_seek / item_size_, SEEK_SET); + unpack_spir_ = make_unpack_spir_gss6450_samples(adc_bits_); + deint_ = gr::blocks::deinterleave::make(item_size_); + endian_ = gr::blocks::endian_swap::make(item_size_); } catch (const std::exception &e) { @@ -103,14 +102,13 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* << filename_.c_str() << ", exiting the program."; throw(e); } - DLOG(INFO) << "file_source(" << file_source_->unique_id() << ")"; if(samples_ == 0) // read all file { /*! * BUG workaround: The GNU Radio file source does not stop the receiver after reaching the End of File. - * A possible solution is to compute the file length in samples using file size, excluding the last 100 milliseconds, and enable always the + * A possible solution is to compute the file length in samples using file size, excluding the last 2 milliseconds, and enable always the * valve block */ std::ifstream file (filename_.c_str(), std::ios::in | std::ios::binary | std::ios::ate); @@ -119,7 +117,7 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* if (file.is_open()) { size = file.tellg(); - LOG(INFO) << "Total samples in the file= " << floor(static_cast(size) / static_cast(item_size())); + LOG(INFO) << "Total samples in the file= " << floor(static_cast(size) / static_cast(item_size_)); } else { @@ -133,13 +131,13 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* if(size > 0) { - samples_ = floor(static_cast(size - bytes_seek) / (sample_size_byte * static_cast(n_channels_))); - samples_ = samples_- ceil(0.002 * static_cast(sampling_frequency_)); //process all the samples available in the file excluding the last 2 ms + samples_ = static_cast(floor(static_cast(size - bytes_seek) / (sample_size_byte * static_cast(n_channels_)))); + samples_ = samples_- static_cast(ceil(0.002 * sampling_frequency_)); //process all the samples available in the file excluding the last 2 ms } } CHECK(samples_ > 0) << "File does not contain enough samples to process."; - double signal_duration_s = static_cast(samples_) * ( 1 /static_cast(sampling_frequency_)); + double signal_duration_s = static_cast(samples_) / sampling_frequency_; LOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]"; std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]" << std::endl; @@ -149,9 +147,9 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* if (dump_) { sink_ = gr::blocks::file_sink::make(sizeof(gr_complex), dump_filename_.c_str()); + //sink_test = gr::blocks::file_sink::make(sizeof(int), "/home/aramos/Escritorio/test_int.dat"); DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")"; } - if (enable_throttle_control_) { throttle_ = gr::blocks::throttle::make(sizeof(gr_complex), sampling_frequency_); @@ -167,36 +165,46 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* } - - SpirGSS6450FileSignalSource::~SpirGSS6450FileSignalSource() {} - - void SpirGSS6450FileSignalSource::connect(gr::top_block_sptr top_block) { if (samples_ > 0) { + top_block->connect(file_source_, 0, deint_, 0); + /* + top_block->connect(deint_, sel_ch_ - 1, endian_ ,0); + top_block->connect(endian_, 0, unpack_spir_, 0); + */ + top_block->connect(deint_, sel_ch_ - 1, unpack_spir_, 0); + if(n_channels_ > 1) + { + unsigned int aux = 0; + for(unsigned int i = 0; i < n_channels_; i++) + { + if(i != (sel_ch_ - 1)) + { + top_block->connect(deint_, i, null_sinks_.at(aux), 0); + aux++; + } + } + } if (enable_throttle_control_) { - top_block->connect(file_source_, 0, unpack_ii_, 0); - top_block->connect(unpack_ii_, 0, unpack_spir_, 0); top_block->connect(unpack_spir_, 0, throttle_, 0); top_block->connect(throttle_, 0, valve_, 0); } else { - top_block->connect(file_source_, 0, unpack_ii_, 0); - top_block->connect(unpack_ii_, 0, unpack_spir_, 0); top_block->connect(unpack_spir_, 0, valve_, 0); } if(dump_) - { - top_block->connect(valve_, 0, sink_, 0); - DLOG(INFO) << "connected valve to file sink"; - } + { + top_block->connect(valve_, 0, sink_, 0); + //top_block->connect(deint_, sel_ch_ - 1, sink_test, 0); + } } else { @@ -205,40 +213,43 @@ void SpirGSS6450FileSignalSource::connect(gr::top_block_sptr top_block) } - - - - void SpirGSS6450FileSignalSource::disconnect(gr::top_block_sptr top_block) { if (samples_ > 0) + { + top_block->disconnect(file_source_, 0, deint_, 0); + top_block->disconnect(deint_, sel_ch_ - 1, unpack_spir_, 0); + if(n_channels_ > 1) { - if (enable_throttle_control_) + unsigned int aux = 0; + for(unsigned int i = 0; i < n_channels_; i++) + { + if(i != (sel_ch_ - 1)) { - top_block->disconnect(file_source_, 0, unpack_ii_, 0); - top_block->disconnect(unpack_ii_, 0, unpack_spir_, 0); - top_block->disconnect(unpack_spir_, 0, throttle_, 0); - top_block->disconnect(throttle_, 0, valve_, 0); - if (dump_) - { - top_block->disconnect(valve_, 0, sink_, 0); - } - } - else - { - top_block->disconnect(file_source_, 0, unpack_ii_, 0); - top_block->disconnect(unpack_ii_, 0, unpack_spir_, 0); - top_block->disconnect(unpack_spir_, 0, valve_, 0); - if (dump_) - { - top_block->disconnect(valve_, 0, sink_, 0); - } + top_block->disconnect(deint_, i, null_sinks_.at(aux), 0); + aux++; } + } } + if (enable_throttle_control_) + { + top_block->disconnect(unpack_spir_, 0, throttle_, 0); + top_block->disconnect(throttle_, 0, valve_, 0); + } + else + { + top_block->disconnect(unpack_spir_, 0, valve_, 0); + } + if(dump_) + { + top_block->disconnect(valve_, 0, sink_, 0); + //top_block->disconnect(deint_, sel_ch_ - 1, sink_test, 0); + } + } else - { - LOG(WARNING) << "Nothing to disconnect"; - } + { + LOG(WARNING) << "Nothing to disconnect"; + } } diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h index 346ebdc79..e8387dbd7 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h @@ -1,12 +1,12 @@ /*! - * \file spir_file_signal_source.h + * \file spir_gss6450_file_signal_source.h * \brief Implementation of a class that reads signals samples from a SPIR file * and adapts it to a SignalSourceInterface. - * \author Fran Fabra, 2014 fabra(at)ice.csic.es + * \author Antonio Ramos, 2017 antonio.ramos(at)cttc.es * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -33,10 +33,14 @@ #define GNSS_SDR_SPIR_GSS6450_FILE_SIGNAL_SOURCE_H_ #include +#include #include #include #include #include +#include +#include +#include #include #include #include "gnss_block_interface.h" @@ -104,10 +108,11 @@ public: private: unsigned long long samples_; - long sampling_frequency_; + double sampling_frequency_; std::string filename_; bool repeat_; bool dump_; + bool enable_throttle_control_; std::string dump_filename_; std::string role_; std::string item_type_; @@ -117,14 +122,16 @@ private: unsigned int n_channels_; unsigned int sel_ch_; gr::blocks::file_source::sptr file_source_; - gr::blocks::packed_to_unpacked_ii::sptr unpack_ii_; + gr::blocks::deinterleave::sptr deint_; + gr::blocks::endian_swap::sptr endian_; + std::vector null_sinks_; unpack_spir_gss6450_samples_sptr unpack_spir_; boost::shared_ptr valve_; gr::blocks::file_sink::sptr sink_; + gr::blocks::file_sink::sptr sink_test; gr::blocks::throttle::sptr throttle_; gr::msg_queue::sptr queue_; size_t item_size_; - bool enable_throttle_control_; }; #endif /*GNSS_SDR_SPIR_GSS6450_FILE_SIGNAL_SOURCE_H_*/ diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc index d8ae66e39..5992c7025 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc @@ -34,123 +34,90 @@ -unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size) +unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int adc_nbit) { - return unpack_spir_gss6450_samples_sptr(new unpack_spir_gss6450_samples(n_chann, sel_ch, samp_item, item_size)); + return unpack_spir_gss6450_samples_sptr(new unpack_spir_gss6450_samples(adc_nbit)); } -unpack_spir_gss6450_samples::unpack_spir_gss6450_samples( - unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size) : gr::block("unpack_spir_gss6450_samples", +unpack_spir_gss6450_samples::unpack_spir_gss6450_samples(unsigned int adc_nbit) : gr::sync_interpolator("unpack_spir_gss6450_samples", gr::io_signature::make(1, 1, sizeof(int)), - gr::io_signature::make(1, 1, sizeof(gr_complex))) + gr::io_signature::make(1, 1, sizeof(gr_complex)), 16 / adc_nbit) { - d_channels = n_chann; - d_sel_ch = sel_ch; - item_size_ = item_size; - ch_processing = 1; - d_samp_item = samp_item; - samp_frame = 0; - adc_bits = 16 / d_samp_item; - i_ = true; - new_sample = false; + adc_bits = adc_nbit; i_data = 0; q_data = 0; + samples_per_int = 16 / adc_bits; + if(adc_bits == 2) + { + mask_data = 0x00000003; + map_ = {0, 1, -2, -1}; + } + else + { + mask_data = 0x0000000F; + map_ = {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}; + } } unpack_spir_gss6450_samples::~unpack_spir_gss6450_samples() {} -void unpack_spir_gss6450_samples::process_sample(gr_complex* out) +void unpack_spir_gss6450_samples::process_sample(gr_complex& out) { - gr_complex result = gr_complex(0.5, 0.5); + out = gr_complex(0.5, 0.5); compute_two_complement(i_data); compute_two_complement(q_data); - result += gr_complex(static_cast(i_data), static_cast(q_data)); - *out = result; + out += gr_complex(static_cast(i_data), static_cast(q_data)); } -int unpack_spir_gss6450_samples::general_work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) + +int unpack_spir_gss6450_samples::work(int noutput_items, + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { const int* in = reinterpret_cast(input_items[0]); gr_complex* out = reinterpret_cast(output_items[0]); - int samples_produced = 0; + unsigned int n_sample = 0; + unsigned int in_counter = 0; for(int i = 0; i < noutput_items; i++) { - if(ch_processing == d_sel_ch) + int sample_aux = in[in_counter]; + //reverse_bits(sample_aux); + int aux_i = sample_aux; + int aux_q = sample_aux; + int i_shift = adc_bits * 2 * (samples_per_int - n_sample - 1) + adc_bits; + int q_shift = adc_bits * 2 * (samples_per_int - n_sample - 1); + i_data = (aux_i >> i_shift) & mask_data; + q_data = (aux_q >> q_shift) & mask_data; + process_sample(out[samples_per_int * in_counter + samples_per_int - n_sample - 1]); + n_sample++; + if(n_sample == samples_per_int) { - if(i_) - { - i_data = in[i]; - swap_data(i_data); - i_ = false; - } - else - { - q_data = in[i]; - swap_data(q_data); - i_ = true; - process_sample(out); - out++; - samples_produced++; - new_sample = true; - } - } - else - { - if(i_) { i_ = false;} - else - { - i_ = true; - new_sample = true; - } - } - if(new_sample) - { - new_sample = false; - samp_frame++; - if(samp_frame == d_samp_item) - { - samp_frame = 0; - ch_processing++; - if(ch_processing > d_channels) { ch_processing = 1; } - } + n_sample = 0; + in_counter++; } } - consume_each(noutput_items); - return samples_produced; + return noutput_items; } -void unpack_spir_gss6450_samples::swap_data(int& data) +void unpack_spir_gss6450_samples::reverse_bits(int& data) { - int result = 0; - int aux = data; - int mask = 1; - for (int i = 0; i < adc_bits; i++) + unsigned int v = data; // input bits to be reversed + unsigned int r = v; // r will be reversed bits of v; first get LSB of v + int s = sizeof(v) * CHAR_BIT - 1; // extra shift needed at end + + for (v >>= 1; v; v >>= 1) { - result = result << 1; - result += (aux & mask); - aux = aux >> 1; + r <<= 1; + r |= v & 1; + s--; } - data = result; + r <<= s; // shift when v's highest bits are zero + data = r; } void unpack_spir_gss6450_samples::compute_two_complement(int& data) { - int result = 0; - int mask = 1; - for(int i = 0; i < (adc_bits - 1); i++) - { - result = result << 1; - result += (data >> i) & mask; - } - if((data >> (adc_bits - 1)) == 1) - { - if(adc_bits == 2) { result -= 2; } - else { result -= 8; } - } - data = result; + data = map_[data]; } diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h index 1077fcc73..df890fc74 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h @@ -31,40 +31,35 @@ #ifndef GNSS_SDR_UNPACK_SPIR_GSS6450_SAMPLES_H #define GNSS_SDR_UNPACK_SPIR_GSS6450_SAMPLES_H -#include +#include +#include class unpack_spir_gss6450_samples; typedef boost::shared_ptr unpack_spir_gss6450_samples_sptr; -unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size); +unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int adc_nbit); -class unpack_spir_gss6450_samples: public gr::block +class unpack_spir_gss6450_samples: public gr::sync_interpolator { public: - int general_work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - friend unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples_sptr(unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size); - unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size); + int work(int noutput_items, + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + friend unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples_sptr(unsigned int adc_nbit); + unpack_spir_gss6450_samples(unsigned int adc_nbit); ~unpack_spir_gss6450_samples(); private: - unsigned int d_channels; - unsigned int d_sel_ch; - unsigned int ch_processing; - int d_samp_item; - int samp_frame; - int adc_bits; - size_t item_size_; - void process_sample(gr_complex* out); - void swap_data(int& data); + unsigned int adc_bits; + unsigned int samples_per_int; + void process_sample(gr_complex& out); void compute_two_complement(int& data); - bool i_; - bool new_sample; + void reverse_bits(int& data); int i_data; int q_data; + int mask_data; + std::vector map_; }; #endif From f6be0943343811a7de8317e1243cfbbc7a62d1f6 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 18 Jan 2018 19:39:21 +0100 Subject: [PATCH 44/96] Initialize all class members in the constructor --- .../gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc index a818da13d..ecc7df1be 100755 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc @@ -251,6 +251,13 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc( d_carrier_doppler_hz = 0.0; d_acc_carrier_phase_rad = 0.0; + d_extend_correlation_symbols_count = 0; + d_code_phase_step_chips = 0.0; + d_carrier_phase_step_rad = 0.0; + d_rem_code_phase_chips = 0.0; + d_K_blk_samples = 0.0; + d_code_phase_samples = 0.0; + d_state = 0; // initial state: standby } From 1095bd0b48406a63bb5485dea85d76c99a834c8c Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 19 Jan 2018 09:46:44 +0100 Subject: [PATCH 45/96] Update satellite info --- src/core/system_parameters/gnss_satellite.cc | 160 +++++++++---------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/src/core/system_parameters/gnss_satellite.cc b/src/core/system_parameters/gnss_satellite.cc index a146b3451..0538355b2 100644 --- a/src/core/system_parameters/gnss_satellite.cc +++ b/src/core/system_parameters/gnss_satellite.cc @@ -252,103 +252,103 @@ std::string Gnss_Satellite::what_block(const std::string& system_, unsigned int { switch ( PRN_ ) { - // info from http://www.navcen.uscg.gov/?Do=constellationStatus + // info from https://www.navcen.uscg.gov/?Do=constellationStatus case 1 : - block_ = std::string("IIF"); //Plane D + block_ = std::string("IIF"); // Plane D break; case 2 : - block_ = std::string("IIR"); //Plane D + block_ = std::string("IIR"); // Plane D break; case 3 : - block_ = std::string("IIF"); //Plane E + block_ = std::string("IIF"); // Plane E break; case 4 : block_ = std::string("Unknown"); break; case 5 : - block_ = std::string("IIR-M"); //Plane E + block_ = std::string("IIR-M"); // Plane E break; case 6 : - block_ = std::string("IIF"); //Plane D + block_ = std::string("IIF"); // Plane D break; case 7 : - block_ = std::string("IIR-M"); //Plane A + block_ = std::string("IIR-M"); // Plane A break; case 8 : - block_ = std::string("IIF"); //Plane C + block_ = std::string("IIF"); // Plane C break; case 9 : - block_ = std::string("IIF"); //Plane F + block_ = std::string("IIF"); // Plane F break; case 10 : - block_ = std::string("IIF"); //Plane E + block_ = std::string("IIF"); // Plane E break; case 11 : - block_ = std::string("IIR"); //Plane D + block_ = std::string("IIR"); // Plane D break; case 12 : - block_ = std::string("IIR-M"); //Plane B + block_ = std::string("IIR-M"); // Plane B break; case 13 : - block_ = std::string("IIR"); //Plane F + block_ = std::string("IIR"); // Plane F break; case 14 : - block_ = std::string("IIR"); //Plane F + block_ = std::string("IIR"); // Plane F break; case 15 : - block_ = std::string("IIR-M"); //Plane F + block_ = std::string("IIR-M"); // Plane F break; case 16 : - block_ = std::string("IIR"); //Plane B + block_ = std::string("IIR"); // Plane B break; case 17 : - block_ = std::string("IIR-M"); //Plane C + block_ = std::string("IIR-M"); // Plane C break; case 18 : - block_ = std::string("IIR"); //Plane E + block_ = std::string("IIR"); // Plane E break; case 19 : - block_ = std::string("IIR"); //Plane D + block_ = std::string("IIR"); // Plane D break; case 20 : - block_ = std::string("IIR"); //Plane B + block_ = std::string("IIR"); // Plane B break; case 21 : - block_ = std::string("IIR"); //Plane D + block_ = std::string("IIR"); // Plane D break; case 22 : - block_ = std::string("IIR"); //Plane E + block_ = std::string("IIR"); // Plane E break; case 23 : - block_ = std::string("IIR"); //Plane F + block_ = std::string("IIR"); // Plane F break; case 24 : - block_ = std::string("IIF"); //Plane A + block_ = std::string("IIF"); // Plane A break; case 25 : - block_ = std::string("IIF"); //Plane B + block_ = std::string("IIF"); // Plane B break; case 26 : - block_ = std::string("IIF"); //Plane B + block_ = std::string("IIF"); // Plane B break; case 27 : - block_ = std::string("IIF"); //Plane C + block_ = std::string("IIF"); // Plane C break; case 28 : - block_ = std::string("IIR"); //Plane B + block_ = std::string("IIR"); // Plane B break; case 29 : - block_ = std::string("IIR-M"); //Plane C + block_ = std::string("IIR-M"); // Plane C break; case 30 : - block_ = std::string("IIF"); //Plane A + block_ = std::string("IIF"); // Plane A break; case 31 : - block_ = std::string("IIR-M"); //Plane A + block_ = std::string("IIR-M"); // Plane A break; case 32 : - block_ = std::string("IIF"); //Plane F + block_ = std::string("IIF"); // Plane F break; default : block_ = std::string("Unknown"); @@ -360,103 +360,103 @@ std::string Gnss_Satellite::what_block(const std::string& system_, unsigned int { switch ( PRN_ ) { - // info from http://www.sdcm.ru/smglo/grupglo?version=eng&site=extern + // Info from http://www.sdcm.ru/smglo/grupglo?version=eng&site=extern // See also http://www.glonass-center.ru/en/GLONASS/ case 1 : - block_ = std::string("1"); //Plane 1 + block_ = std::string("1"); // Plane 1 rf_link = 1; break; case 2 : - block_ = std::string("-4"); //Plane 1 + block_ = std::string("-4"); // Plane 1 rf_link = -4; break; case 3 : - block_ = std::string("5"); //Plane 1 + block_ = std::string("5"); // Plane 1 rf_link = 5; break; case 4 : - block_ = std::string("6"); //Plane 1 + block_ = std::string("6"); // Plane 1 rf_link = 6; break; case 5 : - block_ = std::string("1"); //Plane 1 + block_ = std::string("1"); // Plane 1 rf_link = 1; break; case 6 : - block_ = std::string("-4"); //Plane 1 + block_ = std::string("-4"); // Plane 1 rf_link = -4; break; case 7 : - block_ = std::string("5"); //Plane 1 + block_ = std::string("5"); // Plane 1 rf_link = 5; break; case 8 : - block_ = std::string("6"); //Plane 1 + block_ = std::string("6"); // Plane 1 rf_link = 6; break; case 9 : - block_ = std::string("-2"); //Plane 2 + block_ = std::string("-2"); // Plane 2 rf_link = -2; break; case 10 : - block_ = std::string("-7"); //Plane 2 + block_ = std::string("-7"); // Plane 2 rf_link = -7; break; case 11 : - block_ = std::string("0"); //Plane 2 + block_ = std::string("0"); // Plane 2 rf_link = 0; break; case 12 : - block_ = std::string("-1"); //Plane 2 + block_ = std::string("-1"); // Plane 2 rf_link = -1; break; case 13 : - block_ = std::string("-2"); //Plane 2 + block_ = std::string("-2"); // Plane 2 rf_link = -2; break; case 14 : - block_ = std::string("-7"); //Plane 2 + block_ = std::string("-7"); // Plane 2 rf_link = -7; break; case 15 : - block_ = std::string("0"); //Plane 2 + block_ = std::string("0"); // Plane 2 rf_link = 0; break; case 16 : - block_ = std::string("-1"); //Plane 2 + block_ = std::string("-1"); // Plane 2 rf_link = -1; break; case 17 : - block_ = std::string("4"); //Plane 3 + block_ = std::string("4"); // Plane 3 rf_link = 4; break; case 18 : - block_ = std::string("-3"); //Plane 3 + block_ = std::string("-3"); // Plane 3 rf_link = -3; break; case 19 : - block_ = std::string("3"); //Plane 3 + block_ = std::string("3"); // Plane 3 rf_link = 3; break; case 20 : - block_ = std::string("2"); //Plane 3 + block_ = std::string("2"); // Plane 3 rf_link = 2; break; case 21 : - block_ = std::string("4"); //Plane 3 + block_ = std::string("4"); // Plane 3 rf_link = 4; break; case 22 : - block_ = std::string("-3"); //Plane 3 + block_ = std::string("-3"); // Plane 3 rf_link = -3; break; case 23 : - block_ = std::string("3"); //Plane 3 + block_ = std::string("3"); // Plane 3 rf_link = 3; break; case 24 : - block_ = std::string("2"); //Plane 3 + block_ = std::string("2"); // Plane 3 rf_link = 2; break; default : @@ -488,74 +488,74 @@ std::string Gnss_Satellite::what_block(const std::string& system_, unsigned int } if (system_.compare("Galileo") == 0) { - // Check http://en.wikipedia.org/wiki/List_of_Galileo_satellites + // Check http://en.wikipedia.org/wiki/List_of_Galileo_satellites and https://www.gsc-europa.eu/system-status/Constellation-Information switch ( PRN_ ) { case 1: - block_ = std::string("FOC-FM10"); // Galileo Full Operational Capability (FOC) satellite FM10 / GSAT-0210, launched on May 24, 2016. + block_ = std::string("FOC-FM10"); // Galileo Full Operational Capability (FOC) satellite FM10 / GSAT-0210, launched on May 24, 2016. break; case 2: - block_ = std::string("FOC-FM11"); // Galileo Full Operational Capability (FOC) satellite FM11 / GSAT-0211, launched on May 24, 2016. + block_ = std::string("FOC-FM11"); // Galileo Full Operational Capability (FOC) satellite FM11 / GSAT-0211, launched on May 24, 2016. break; case 3: - block_ = std::string("FOC-FM12"); // Galileo Full Operational Capability (FOC) satellite FM12 / GSAT-0212, launched on November 17, 2016. + block_ = std::string("FOC-FM12"); // Galileo Full Operational Capability (FOC) satellite FM12 / GSAT-0212, launched on November 17, 2016. break; case 4: - block_ = std::string("FOC-FM13"); // Galileo Full Operational Capability (FOC) satellite FM13 / GSAT-0213, launched on November 17, 2016. + block_ = std::string("FOC-FM13"); // Galileo Full Operational Capability (FOC) satellite FM13 / GSAT-0213, launched on November 17, 2016. break; case 5: - block_ = std::string("FOC-FM14"); // Galileo Full Operational Capability (FOC) satellite FM14 / GSAT-0214, launched on November 17, 2016. + block_ = std::string("FOC-FM14"); // Galileo Full Operational Capability (FOC) satellite FM14 / GSAT-0214, launched on November 17, 2016. break; case 7: - block_ = std::string("FOC-FM7"); // Galileo Full Operational Capability (FOC) satellite FM7 / GSAT-0207, launched on November 17, 2016. + block_ = std::string("FOC-FM7"); // Galileo Full Operational Capability (FOC) satellite FM7 / GSAT-0207, launched on November 17, 2016. break; case 8: - block_ = std::string("FOC-FM8"); // Galileo Full Operational Capability (FOC) satellite FM8 / GSAT0208, launched on December 17, 2015. + block_ = std::string("FOC-FM8"); // Galileo Full Operational Capability (FOC) satellite FM8 / GSAT0208, launched on December 17, 2015. break; case 9: - block_ = std::string("FOC-FM9"); // Galileo Full Operational Capability (FOC) satellite FM9 / GSAT0209, launched on December 17, 2015. + block_ = std::string("FOC-FM9"); // Galileo Full Operational Capability (FOC) satellite FM9 / GSAT0209, launched on December 17, 2015. break; case 11 : - block_ = std::string("IOV-PFM"); // PFM, the ProtoFlight Model / GSAT0101, launched from French Guiana at 10:30 GMT on October 21, 2011. + block_ = std::string("IOV-PFM"); // PFM, the ProtoFlight Model / GSAT0101, launched from French Guiana at 10:30 GMT on October 21, 2011. break; case 12 : - block_ = std::string("IOV-FM2**"); // Galileo In-Orbit Validation (IOV) satellite FM2 (Flight Model 2) also known as GSAT0102, from French Guiana at 10:30 GMT on October 21, 2011. + block_ = std::string("IOV-FM2"); // Galileo In-Orbit Validation (IOV) satellite FM2 (Flight Model 2) also known as GSAT0102, from French Guiana at 10:30 GMT on October 21, 2011. break; case 14 : - block_ = std::string("FOC-FM2*"); // Galileo Full Operational Capability (FOC) satellite FM2 / GSAT0202, launched into incorrect orbit on August 22, 2014. Moved to usable orbit in March, 2015. + block_ = std::string("FOC-FM2*"); // Galileo Full Operational Capability (FOC) satellite FM2 / GSAT0202, launched into incorrect orbit on August 22, 2014. Moved to usable orbit in March, 2015. UNDER TESTING. break; case 18 : - block_ = std::string("FOC-FM1*"); // Galileo Full Operational Capability (FOC) satellite FM1 / GSAT0201, launched into incorrect orbit on August 22, 2014. Moved to usable orbit in December, 2014. + block_ = std::string("FOC-FM1*"); // Galileo Full Operational Capability (FOC) satellite FM1 / GSAT0201, launched into incorrect orbit on August 22, 2014. Moved to usable orbit in December, 2014. UNDER TESTING. break; case 19 : - block_ = std::string("IOV-FM3"); // Galileo In-Orbit Validation (IOV) satellite FM3 (Flight Model 3) / GSAT0103, launched on October 12, 2012. + block_ = std::string("IOV-FM3"); // Galileo In-Orbit Validation (IOV) satellite FM3 (Flight Model 3) / GSAT0103, launched on October 12, 2012. break; case 20 : - block_ = std::string("IOV-FM4**"); // Galileo In-Orbit Validation (IOV) satellite FM4 (Flight Model 4) / GSAT0104, launched on October 12, 2012. Partially unavailable: Payload power problem beginning May 27, 2014 led to permanent loss of E5 and E6 transmissions, E1 transmission restored. + block_ = std::string("IOV-FM4**"); // Galileo In-Orbit Validation (IOV) satellite FM4 (Flight Model 4) / GSAT0104, launched on October 12, 2012. Payload power problem beginning May 27, 2014 led to permanent loss of E5 and E6 transmissions, E1 transmission restored. UNAVAILABLE FROM 2014-05-27 UNTIL FURTHER NOTICE break; case 21 : - block_ = std::string("FOC-FM15"); // Galileo Full Operational Capability (FOC) satellite FM15 / GSAT0215, launched on Dec. 12, 2017. + block_ = std::string("FOC-FM15"); // Galileo Full Operational Capability (FOC) satellite FM15 / GSAT0215, launched on Dec. 12, 2017. UNDER COMMISIONING. break; case 22 : - block_ = std::string("FOC-FM4"); // Galileo Full Operational Capability (FOC) satellite FM4 / GSAT0204, launched on March 27, 2015. + block_ = std::string("FOC-FM4**"); // Galileo Full Operational Capability (FOC) satellite FM4 / GSAT0204, launched on March 27, 2015. REMOVED FROM ACTIVE SERVICE ON 2017-12-08 UNTIL FURTHER NOTICE FOR CONSTELLATION MANAGEMENT PURPOSES. break; case 24 : - block_ = std::string("FOC-FM5"); // Galileo Full Operational Capability (FOC) satellite FM5 / GSAT0205, launched on Sept. 11, 2015. + block_ = std::string("FOC-FM5"); // Galileo Full Operational Capability (FOC) satellite FM5 / GSAT0205, launched on Sept. 11, 2015. break; case 25 : - block_ = std::string("FOC-FM16"); // Galileo Full Operational Capability (FOC) satellite FM16 / GSAT0216, launched on Dec. 12, 2017. + block_ = std::string("FOC-FM16"); // Galileo Full Operational Capability (FOC) satellite FM16 / GSAT0216, launched on Dec. 12, 2017. UNDER COMMISIONING. break; case 26 : - block_ = std::string("FOC-FM3"); // Galileo Full Operational Capability (FOC) satellite FM3 / GSAT0203, launched on March 27, 2015. + block_ = std::string("FOC-FM3"); // Galileo Full Operational Capability (FOC) satellite FM3 / GSAT0203, launched on March 27, 2015. break; case 27 : - block_ = std::string("FOC-FM17"); // Galileo Full Operational Capability (FOC) satellite FM17 / GSAT0217, launched on Dec. 12, 2017. + block_ = std::string("FOC-FM17"); // Galileo Full Operational Capability (FOC) satellite FM17 / GSAT0217, launched on Dec. 12, 2017. UNDER COMMISIONING. break; case 30 : - block_ = std::string("FOC-FM6"); // Galileo Full Operational Capability (FOC) satellite FM6 / GSAT0206, launched on Sept. 11, 2015. + block_ = std::string("FOC-FM6"); // Galileo Full Operational Capability (FOC) satellite FM6 / GSAT0206, launched on Sept. 11, 2015. break; case 31 : - block_ = std::string("FOC-FM18"); // Galileo Full Operational Capability (FOC) satellite FM18 / GSAT0218, launched on Dec. 12, 2017. + block_ = std::string("FOC-FM18"); // Galileo Full Operational Capability (FOC) satellite FM18 / GSAT0218, launched on Dec. 12, 2017. UNDER COMMISIONING. break; default: block_ = std::string("Unknown(Simulated)"); From 079f31a624881ac9130c9866eb5a7eb295d2c36f Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 19 Jan 2018 12:05:53 +0100 Subject: [PATCH 46/96] Add GPS L5 --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1b513a25e..2c101387c 100644 --- a/README.md +++ b/README.md @@ -1047,8 +1047,9 @@ Each channel must be assigned to a GNSS signal, according to the following ident |:------------------|:---------------:| | GPS L1 C/A | 1C | | GPS L2 L2C(M) | 2S | -| Galileo E1B | 1B | -| Galileo E5a (I+Q) | 5X | +| GPS L5 | L5 | +| Galileo E1b/c | 1B | +| Galileo E5a | 5X | Example: Eight GPS L1 C/A channels. From 3ca7d0d08a965861d8dbfa4a07ac41a58b20a8fa Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 19 Jan 2018 12:09:40 +0100 Subject: [PATCH 47/96] Remove unused include --- .../adapters/file_signal_source.cc | 53 ++++++------------- 1 file changed, 17 insertions(+), 36 deletions(-) diff --git a/src/algorithms/signal_source/adapters/file_signal_source.cc b/src/algorithms/signal_source/adapters/file_signal_source.cc index 42591ec79..ea2bd190f 100644 --- a/src/algorithms/signal_source/adapters/file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/file_signal_source.cc @@ -37,7 +37,6 @@ #include #include #include -#include #include "gnss_sdr_valve.h" #include "configuration_interface.h" @@ -51,7 +50,7 @@ DEFINE_string(signal_source, "-", FileSignalSource::FileSignalSource(ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams, boost::shared_ptr queue) : - role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(queue) + role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(queue) { std::string default_filename = "./example_capture.dat"; std::string default_item_type = "short"; @@ -71,8 +70,7 @@ FileSignalSource::FileSignalSource(ConfigurationInterface* configuration, dump_ = configuration->property(role + ".dump", false); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); enable_throttle_control_ = configuration->property(role + ".enable_throttle_control", false); - std::string s = "InputFilter"; - //double IF = configuration->property(s + ".IF", 0.0); + double seconds_to_skip = configuration->property(role + ".seconds_to_skip", default_seconds_to_skip ); header_size = configuration->property( role + ".header_size", 0 ); long samples_to_skip = 0; @@ -116,29 +114,27 @@ FileSignalSource::FileSignalSource(ConfigurationInterface* configuration, file_source_ = gr::blocks::file_source::make(item_size_, filename_.c_str(), repeat_); if( seconds_to_skip > 0 ) - { - samples_to_skip = static_cast< long >( - seconds_to_skip * sampling_frequency_ ); - - if( is_complex ) { - samples_to_skip *= 2; + samples_to_skip = static_cast< long >( seconds_to_skip * sampling_frequency_ ); + + if( is_complex ) + { + samples_to_skip *= 2; + } } - } if( header_size > 0 ) - { - samples_to_skip += header_size; - } + { + samples_to_skip += header_size; + } if( samples_to_skip > 0 ) - { - LOG(INFO) << "Skipping " << samples_to_skip << " samples of the input file"; - if( not file_source_->seek( samples_to_skip, SEEK_SET ) ) { - LOG(INFO) << "Error skipping bytes!"; + LOG(INFO) << "Skipping " << samples_to_skip << " samples of the input file"; + if( not file_source_->seek( samples_to_skip, SEEK_SET ) ) + { + LOG(INFO) << "Error skipping bytes!"; + } } - } - } catch (const std::exception &e) { @@ -171,7 +167,6 @@ FileSignalSource::FileSignalSource(ConfigurationInterface* configuration, << std::endl << GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/" << std::endl; - } LOG(INFO) << "file_signal_source: Unable to open the samples file " @@ -238,8 +233,8 @@ FileSignalSource::FileSignalSource(ConfigurationInterface* configuration, if (enable_throttle_control_) { throttle_ = gr::blocks::throttle::make(item_size_, sampling_frequency_); - } + DLOG(INFO) << "File source filename " << filename_; DLOG(INFO) << "Samples " << samples_; DLOG(INFO) << "Sampling frequency " << sampling_frequency_; @@ -251,14 +246,10 @@ FileSignalSource::FileSignalSource(ConfigurationInterface* configuration, } - - FileSignalSource::~FileSignalSource() {} - - void FileSignalSource::connect(gr::top_block_sptr top_block) { if (samples_ > 0) @@ -310,10 +301,6 @@ void FileSignalSource::connect(gr::top_block_sptr top_block) } - - - - void FileSignalSource::disconnect(gr::top_block_sptr top_block) { if (samples_ > 0) @@ -365,9 +352,6 @@ void FileSignalSource::disconnect(gr::top_block_sptr top_block) } - - - gr::basic_block_sptr FileSignalSource::get_left_block() { LOG(WARNING) << "Left block of a signal source should not be retrieved"; @@ -375,9 +359,6 @@ gr::basic_block_sptr FileSignalSource::get_left_block() } - - - gr::basic_block_sptr FileSignalSource::get_right_block() { if (samples_ > 0) From 7a2a02252a3385011c16a1455bf8e2b255ca9822 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Fri, 19 Jan 2018 13:50:33 +0100 Subject: [PATCH 48/96] Minor changes --- .../spir_gss6450_file_signal_source.cc | 56 ++++++++++++++----- .../spir_gss6450_file_signal_source.h | 4 +- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc index 590c60c33..81a7d33e6 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc @@ -54,6 +54,8 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* filename_ = configuration->property(role + ".filename", default_filename); repeat_ = configuration->property(role + ".repeat", false); dump_ = configuration->property(role + ".dump", false); + dump_test_ = configuration->property(role + ".dump_test", false); + endian_swap_ = configuration->property(role + ".endian", false); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); enable_throttle_control_ = configuration->property(role + ".enable_throttle_control", false); adc_bits_ = configuration->property(role + ".adc_bits", 4); @@ -70,7 +72,7 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* { null_sinks_.push_back(gr::blocks::null_sink::make(item_size_)); } - std::cout << "NUMBER OF NULL SINKS = " << null_sinks_.size() << std::endl; + DLOG(INFO)<< "NUMBER OF NULL SINKS = " << null_sinks_.size(); } try { @@ -78,7 +80,6 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* file_source_->seek(bytes_seek / item_size_, SEEK_SET); unpack_spir_ = make_unpack_spir_gss6450_samples(adc_bits_); deint_ = gr::blocks::deinterleave::make(item_size_); - endian_ = gr::blocks::endian_swap::make(item_size_); } catch (const std::exception &e) { @@ -147,13 +148,20 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* if (dump_) { sink_ = gr::blocks::file_sink::make(sizeof(gr_complex), dump_filename_.c_str()); - //sink_test = gr::blocks::file_sink::make(sizeof(int), "/home/aramos/Escritorio/test_int.dat"); DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")"; } + if (dump_test_) + { + sink_test = gr::blocks::file_sink::make(sizeof(int), (dump_filename_ + "int").c_str()); + } if (enable_throttle_control_) { throttle_ = gr::blocks::throttle::make(sizeof(gr_complex), sampling_frequency_); } + if (endian_swap_) + { + endian_ = gr::blocks::endian_swap::make(item_size_); + } DLOG(INFO) << "File source filename " << filename_; DLOG(INFO) << "Samples " << samples_; DLOG(INFO) << "Sampling frequency " << sampling_frequency_; @@ -174,11 +182,15 @@ void SpirGSS6450FileSignalSource::connect(gr::top_block_sptr top_block) if (samples_ > 0) { top_block->connect(file_source_, 0, deint_, 0); - /* - top_block->connect(deint_, sel_ch_ - 1, endian_ ,0); - top_block->connect(endian_, 0, unpack_spir_, 0); - */ - top_block->connect(deint_, sel_ch_ - 1, unpack_spir_, 0); + if(endian_swap_) + { + top_block->connect(deint_, sel_ch_ - 1, endian_ ,0); + top_block->connect(endian_, 0, unpack_spir_, 0); + } + else + { + top_block->connect(deint_, sel_ch_ - 1, unpack_spir_, 0); + } if(n_channels_ > 1) { unsigned int aux = 0; @@ -203,7 +215,11 @@ void SpirGSS6450FileSignalSource::connect(gr::top_block_sptr top_block) if(dump_) { top_block->connect(valve_, 0, sink_, 0); - //top_block->connect(deint_, sel_ch_ - 1, sink_test, 0); + } + if(dump_test_) + { + if(endian_swap_) top_block->connect(endian_, 0, sink_test, 0); + else top_block->connect(deint_, sel_ch_ - 1, sink_test, 0); } } else @@ -218,7 +234,15 @@ void SpirGSS6450FileSignalSource::disconnect(gr::top_block_sptr top_block) if (samples_ > 0) { top_block->disconnect(file_source_, 0, deint_, 0); - top_block->disconnect(deint_, sel_ch_ - 1, unpack_spir_, 0); + if(endian_swap_) + { + top_block->disconnect(deint_, sel_ch_ - 1, endian_ ,0); + top_block->disconnect(endian_, 0, unpack_spir_, 0); + } + else + { + top_block->disconnect(deint_, sel_ch_ - 1, unpack_spir_, 0); + } if(n_channels_ > 1) { unsigned int aux = 0; @@ -241,10 +265,14 @@ void SpirGSS6450FileSignalSource::disconnect(gr::top_block_sptr top_block) top_block->disconnect(unpack_spir_, 0, valve_, 0); } if(dump_) - { - top_block->disconnect(valve_, 0, sink_, 0); - //top_block->disconnect(deint_, sel_ch_ - 1, sink_test, 0); - } + { + top_block->disconnect(valve_, 0, sink_, 0); + } + if(dump_test_) + { + if(endian_swap_) top_block->disconnect(endian_, 0, sink_test, 0); + else top_block->disconnect(deint_, sel_ch_ - 1, sink_test, 0); + } } else { diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h index e8387dbd7..411d04069 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h @@ -111,8 +111,10 @@ private: double sampling_frequency_; std::string filename_; bool repeat_; - bool dump_; + bool dump_; //Enables dumping the gr_complex sample output + bool dump_test_; //Enables dumping the raw 32-bits deinterleaved (and endian swapped if enabled) words bool enable_throttle_control_; + bool endian_swap_; std::string dump_filename_; std::string role_; std::string item_type_; From 03157464292625ad87eff3b6d5d1467d6d8c9c75 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sat, 20 Jan 2018 04:17:50 +0100 Subject: [PATCH 49/96] Fix warning --- src/core/libs/supl/asn-supl/GeneralizedTime.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/libs/supl/asn-supl/GeneralizedTime.c b/src/core/libs/supl/asn-supl/GeneralizedTime.c index 9d683efe4..c3e01f99e 100644 --- a/src/core/libs/supl/asn-supl/GeneralizedTime.c +++ b/src/core/libs/supl/asn-supl/GeneralizedTime.c @@ -3,7 +3,9 @@ * Redistribution and modifications are permitted subject to BSD license. */ #define _POSIX_PTHREAD_SEMANTICS /* for Sun */ +#ifdef _REENTRANT #define _REENTRANT /* for Sun */ +#endif #include #include #include From db938bb047d2eba5a3eed4ee293f28803ebe5667 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sat, 20 Jan 2018 11:56:17 +0100 Subject: [PATCH 50/96] Build fix due to a change in the gr-iio v0.3 API A change in the API has removed the decimation parameter from sources (see https://github.com/analogdevicesinc/gr-iio/issues/15 ) This commit fixes the build against the current master of https://github.com/analogdevicesinc/gr-iio but it breaks compatibility with older versions. Users with gr-iio already installed will need to update it. --- README.md | 2 +- conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf | 2 -- conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf | 2 -- .../signal_source/adapters/fmcomms2_signal_source.cc | 3 +-- src/algorithms/signal_source/adapters/fmcomms2_signal_source.h | 1 - .../signal_source/adapters/plutosdr_signal_source.cc | 3 +-- src/algorithms/signal_source/adapters/plutosdr_signal_source.h | 1 - 7 files changed, 3 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 2c101387c..06f884a00 100644 --- a/README.md +++ b/README.md @@ -375,7 +375,7 @@ $ sudo make install ###### Build FMCOMMS2 based SDR Hardware support (OPTIONAL): -Install the [libiio](https://github.com/analogdevicesinc/libiio.git) (>=v0.11), [libad9361](https://github.com/analogdevicesinc/libad9361-iio.git) (>=v0.1-1) libraries and [gr-iio](https://github.com/analogdevicesinc/gr-iio.git) (>v0.2) gnuradio block: +Install the [libiio](https://github.com/analogdevicesinc/libiio.git) (>=v0.11), [libad9361](https://github.com/analogdevicesinc/libad9361-iio.git) (>=v0.1-1) libraries and [gr-iio](https://github.com/analogdevicesinc/gr-iio.git) (>v0.3) gnuradio block: ~~~~~~ $ sudo apt-get install libxml2-dev bison flex diff --git a/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf b/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf index ae832f901..6c8d8d85c 100644 --- a/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf @@ -27,13 +27,11 @@ GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ SignalSource.implementation=Fmcomms2_Signal_Source -;SignalSource.filename=/media/DATALOGGER_/signals/RTL-SDR/geo/pmt4.dat SignalSource.item_type=gr_complex SignalSource.device_address=10.42.0.196 SignalSource.sampling_frequency=2000000 SignalSource.freq=1575420000 SignalSource.bandwidth=2000000 -SignalSource.decimation=0 SignalSource.rx1_enable=true SignalSource.gain_mode_rx1=manual SignalSource.rf_port_select=A_BALANCED diff --git a/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf b/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf index 97c9deded..83f808645 100644 --- a/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf @@ -27,13 +27,11 @@ GNSS-SDR.SUPL_CI=0x31b0 ;######### SIGNAL_SOURCE CONFIG ############ SignalSource.implementation=Plutosdr_Signal_Source -;SignalSource.filename=/media/DATALOGGER_/signals/RTL-SDR/geo/pmt4.dat SignalSource.item_type=gr_complex SignalSource.device_address=192.168.2.1 SignalSource.sampling_frequency=3000000 SignalSource.freq=1575420000 SignalSource.bandwidth=2600000 -SignalSource.decimation=0 SignalSource.gain_mode=manual SignalSource.gain=30 SignalSource.samples=0 diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc index 5c354e500..52916a19e 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc @@ -53,7 +53,6 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration rx1_en_ = configuration->property(role + ".rx1_enable", true); rx2_en_ = configuration->property(role + ".rx2_enable", false); buffer_size_ = configuration->property(role + ".buffer_size", 0xA0000); - decimation_ = configuration->property(role + ".decimation", 1); quadrature_ = configuration->property(role + ".quadrature", true); rf_dc_ = configuration->property(role + ".rf_dc", true); bb_dc_ = configuration->property(role + ".bb_dc", true); @@ -79,7 +78,7 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration { fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make( uri_.c_str(), freq_, sample_rate_, - decimation_, bandwidth_, + bandwidth_, rx1_en_, rx2_en_, buffer_size_, quadrature_, rf_dc_, bb_dc_, gain_mode_rx1_.c_str(), rf_gain_rx1_, diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h index fb62a12cb..78f3ebb58 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h @@ -83,7 +83,6 @@ private: unsigned long sample_rate_; unsigned long bandwidth_; unsigned long buffer_size_; //reception buffer - unsigned int decimation_; bool rx1_en_; bool rx2_en_; bool quadrature_; diff --git a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc index 34526f6a5..4e7e37b3e 100644 --- a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc +++ b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc @@ -52,7 +52,6 @@ PlutosdrSignalSource::PlutosdrSignalSource(ConfigurationInterface* configuration sample_rate_ = configuration->property(role + ".sampling_frequency", 3000000); bandwidth_ = configuration->property(role + ".bandwidth", 2000000); buffer_size_ = configuration->property(role + ".buffer_size", 0xA0000); - decimation_ = configuration->property(role + ".decimation", 1); quadrature_ = configuration->property(role + ".quadrature", true); rf_dc_ = configuration->property(role + ".rf_dc", true); bb_dc_ = configuration->property(role + ".bb_dc", true); @@ -81,7 +80,7 @@ PlutosdrSignalSource::PlutosdrSignalSource(ConfigurationInterface* configuration std::cout << "item type: " << item_type_ << std::endl; plutosdr_source_ = gr::iio::pluto_source::make(uri_, freq_, sample_rate_, - decimation_, bandwidth_, buffer_size_, quadrature_, rf_dc_, bb_dc_, + bandwidth_, buffer_size_, quadrature_, rf_dc_, bb_dc_, gain_mode_.c_str(), rf_gain_,filter_file_.c_str(), filter_auto_); if (samples_ != 0) diff --git a/src/algorithms/signal_source/adapters/plutosdr_signal_source.h b/src/algorithms/signal_source/adapters/plutosdr_signal_source.h index 9bbdb4511..56c2334c8 100644 --- a/src/algorithms/signal_source/adapters/plutosdr_signal_source.h +++ b/src/algorithms/signal_source/adapters/plutosdr_signal_source.h @@ -83,7 +83,6 @@ private: unsigned long sample_rate_; unsigned long bandwidth_; unsigned long buffer_size_; // reception buffer - unsigned int decimation_; bool quadrature_; bool rf_dc_; bool bb_dc_; From 5acef7a9bcc8a3b76f037d3e2bd17c52f4ba3e56 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sat, 20 Jan 2018 12:24:38 +0100 Subject: [PATCH 51/96] Remove warnings of unused variables --- src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc index 2b94ab34d..5824e8493 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc @@ -448,8 +448,6 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite bool flag_compute_pvt_output = false; bool flag_write_RTCM_1019_output = false; bool flag_write_RTCM_1045_output = false; - bool flag_write_RTCM_1077_output = false; - bool flag_write_RTCM_1097_output = false; bool flag_write_RTCM_MSM_output = false; bool flag_write_RINEX_obs_output = false; bool flag_write_RINEX_nav_output = false; @@ -539,13 +537,11 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite if ((std::fabs(current_RX_time - last_RTCM_1077_output_time) * 1000.0 >= static_cast(d_rtcm_MT1077_rate_ms)) && (d_rtcm_MT1077_rate_ms != 0) ) { - flag_write_RTCM_1077_output = true; last_RTCM_1077_output_time = current_RX_time; } if ((std::fabs(current_RX_time - last_RTCM_1097_output_time) * 1000.0 >= static_cast(d_rtcm_MT1097_rate_ms)) && (d_rtcm_MT1097_rate_ms != 0) ) { - flag_write_RTCM_1097_output = true; last_RTCM_1097_output_time = current_RX_time; } From 1b4c217d88c13871ce39c430947508ee3b6a8dfa Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sat, 20 Jan 2018 12:29:21 +0100 Subject: [PATCH 52/96] Fix redefinition warning --- src/core/libs/supl/asn-supl/GeneralizedTime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/libs/supl/asn-supl/GeneralizedTime.c b/src/core/libs/supl/asn-supl/GeneralizedTime.c index c3e01f99e..2fd63f262 100644 --- a/src/core/libs/supl/asn-supl/GeneralizedTime.c +++ b/src/core/libs/supl/asn-supl/GeneralizedTime.c @@ -3,7 +3,7 @@ * Redistribution and modifications are permitted subject to BSD license. */ #define _POSIX_PTHREAD_SEMANTICS /* for Sun */ -#ifdef _REENTRANT +#ifndef _REENTRANT #define _REENTRANT /* for Sun */ #endif #include From fcd24c69daddee9a7b7e8a91b2d18b84173a4404 Mon Sep 17 00:00:00 2001 From: Gastd Date: Sun, 21 Jan 2018 00:30:31 -0200 Subject: [PATCH 53/96] fixbug: initialize the carrier track filter with proper value --- .../glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc | 8 +++++--- .../glonass_l1_ca_dll_pll_c_aid_tracking_cc.h | 1 + .../glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc | 16 ++++++++++------ .../glonass_l1_ca_dll_pll_c_aid_tracking_sc.h | 2 ++ 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc index d6569fb81..adedc967a 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc @@ -218,6 +218,7 @@ glonass_l1_ca_dll_pll_c_aid_tracking_cc::glonass_l1_ca_dll_pll_c_aid_tracking_cc d_preamble_timestamp_s = 0.0; d_carrier_frequency_hz = 0.0; + d_carrier_doppler_old_hz = 0.0; //set_min_output_buffer((long int)300); } @@ -270,13 +271,13 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_cc::start_tracking() // d_carrier_doppler_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)); // d_carrier_doppler_hz = d_acq_carrier_doppler_hz; // d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); - d_carrier_frequency_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)); + d_carrier_frequency_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * static_cast(GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN))); d_carrier_doppler_hz = d_acq_carrier_doppler_hz; d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_frequency_hz / static_cast(d_fs_in); // DLL/PLL filter initialization - d_carrier_loop_filter.initialize(d_acq_carrier_doppler_hz); // The carrier loop filter implements the Doppler accumulator + d_carrier_loop_filter.initialize(d_carrier_frequency_hz); // The carrier loop filter implements the Doppler accumulator d_code_loop_filter.initialize(); // initialize the code filter // generate local reference ALWAYS starting at chip 1 (1 sample per chip) @@ -709,6 +710,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items __a // ################## PLL ########################################################## // Update PLL discriminator [rads/Ti -> Secs/Ti] d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(d_correlator_outs[1]) / GLONASS_TWO_PI; // prompt output + d_carrier_doppler_old_hz = d_carrier_doppler_hz; // Carrier discriminator filter // NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan // Input [s/Ti] -> output [Hz] @@ -716,7 +718,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items __a // PLL to DLL assistance [Secs/Ti] d_pll_to_dll_assist_secs_Ti = (d_carrier_doppler_hz * CURRENT_INTEGRATION_TIME_S) / d_glonass_freq_ch; // code Doppler frequency update - d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GLONASS_L1_CA_CODE_RATE_HZ) / d_glonass_freq_ch); + d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ + (((d_carrier_doppler_hz - d_carrier_doppler_old_hz) * GLONASS_L1_CA_CODE_RATE_HZ) / d_glonass_freq_ch); // ################## DLL ########################################################## // DLL discriminator diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h index 1aa7b72bd..fd8c3f181 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h @@ -158,6 +158,7 @@ private: double d_code_phase_step_chips; double d_carrier_doppler_hz; double d_carrier_frequency_hz; + double d_carrier_doppler_old_hz; double d_carrier_phase_step_rad; double d_acc_carrier_phase_cycles; double d_code_phase_samples; diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc index 197e46379..99ce87e3b 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc @@ -217,6 +217,10 @@ glonass_l1_ca_dll_pll_c_aid_tracking_sc::glonass_l1_ca_dll_pll_c_aid_tracking_sc d_code_error_filt_chips_Ti = 0.0; d_preamble_timestamp_s = 0.0; d_carr_phase_error_secs_Ti = 0.0; + + d_carrier_frequency_hz = 0.0; + d_carrier_doppler_old_hz = 0.0; + //set_min_output_buffer((long int)300); } @@ -265,13 +269,13 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_sc::start_tracking() d_acq_code_phase_samples = corrected_acq_phase_samples; - d_carrier_doppler_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)); - // d_carrier_doppler_hz = d_acq_carrier_doppler_hz; + d_carrier_frequency_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * static_cast(GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)));; + d_carrier_doppler_hz = d_acq_carrier_doppler_hz; - d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); + d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_frequency_hz / static_cast(d_fs_in); // DLL/PLL filter initialization - d_carrier_loop_filter.initialize(d_acq_carrier_doppler_hz); // The carrier loop filter implements the Doppler accumulator + d_carrier_loop_filter.initialize(d_carrier_frequency_hz); // The carrier loop filter implements the Doppler accumulator d_code_loop_filter.initialize(); // initialize the code filter // generate local reference ALWAYS starting at chip 1 (1 sample per chip) @@ -700,7 +704,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work (int noutput_items __a // ################## PLL ########################################################## // Update PLL discriminator [rads/Ti -> Secs/Ti] d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(std::complex(d_correlator_outs_16sc[1].real(),d_correlator_outs_16sc[1].imag())) / GLONASS_TWO_PI; //prompt output - + d_carrier_doppler_old_hz = d_carrier_doppler_hz; // Carrier discriminator filter // NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan // Input [s/Ti] -> output [Hz] @@ -708,7 +712,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work (int noutput_items __a // PLL to DLL assistance [Secs/Ti] d_pll_to_dll_assist_secs_Ti = (d_carrier_doppler_hz * CURRENT_INTEGRATION_TIME_S) / d_glonass_freq_ch; // code Doppler frequency update - d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GLONASS_L1_CA_CODE_RATE_HZ) / d_glonass_freq_ch); + d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ + (((d_carrier_doppler_hz - d_carrier_doppler_old_hz) * GLONASS_L1_CA_CODE_RATE_HZ) / d_glonass_freq_ch); // ################## DLL ########################################################## // DLL discriminator diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h index 6f83bac0d..5fe82b1b9 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h @@ -160,6 +160,8 @@ private: double d_code_freq_chips; double d_code_phase_step_chips; double d_carrier_doppler_hz; + double d_carrier_frequency_hz; + double d_carrier_doppler_old_hz; double d_carrier_phase_step_rad; double d_acc_carrier_phase_cycles; double d_code_phase_samples; From 786f68a9ca907ab9675c8e3b74902dcf6f156155 Mon Sep 17 00:00:00 2001 From: Gastd Date: Sun, 21 Jan 2018 00:48:57 -0200 Subject: [PATCH 54/96] clean code --- .../gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc | 2 +- src/core/system_parameters/GLONASS_L1_CA.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc index c7926ac3b..3b898754f 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc @@ -580,7 +580,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribu carr_error_filt_hz = d_carrier_loop_filter.get_carrier_nco(carr_error_hz); // New carrier Doppler frequency estimation d_carrier_frequency_hz += carr_error_filt_hz; - d_carrier_doppler_hz = d_acq_carrier_doppler_hz + carr_error_filt_hz; + d_carrier_doppler_hz += carr_error_filt_hz; d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GLONASS_L1_CA_CODE_RATE_HZ) / d_glonass_freq_ch); // ################## DLL ########################################################## diff --git a/src/core/system_parameters/GLONASS_L1_CA.h b/src/core/system_parameters/GLONASS_L1_CA.h index 28c634ff3..06f1112f3 100644 --- a/src/core/system_parameters/GLONASS_L1_CA.h +++ b/src/core/system_parameters/GLONASS_L1_CA.h @@ -50,7 +50,7 @@ const double GLONASS_FLATTENING = 1/29825784; //!< Flatten const double GLONASS_GRAVITY = 97803284; //!< Equatorial acceleration of gravity [mGal] const double GLONASS_GRAVITY_CORRECTION = 0.87; //!< Correction to acceleration of gravity at sea-level due to Atmosphere[мGal] const double GLONASS_J2 = 1082625.75e-9; //!< Second zonal harmonic of the geopotential -const double GLONASS_J4 = -2370.89e-9; //! Date: Sun, 21 Jan 2018 00:56:46 -0200 Subject: [PATCH 55/96] Fix headers --- .../adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc | 2 +- .../tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h | 2 +- .../glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc | 5 ++--- .../glonass_l1_ca_dll_pll_c_aid_tracking_cc.h | 3 +-- .../glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc | 5 ++--- .../glonass_l1_ca_dll_pll_c_aid_tracking_sc.h | 5 ++--- .../gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc | 5 ++--- .../gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h | 5 ++--- 8 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc index 800d1d4bd..2322626e8 100644 --- a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc @@ -1,5 +1,5 @@ /*! - * \file glonass_l1_ca_dll_pll_tracking.h + * \file glonass_l1_ca_dll_pll_c_aid_tracking.cc * \brief Interface of an adapter of a DLL+PLL tracking loop block * for Glonass L1 C/A to a TrackingInterface * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h index 4cdd59ce6..b62729a5f 100644 --- a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h @@ -1,5 +1,5 @@ /*! - * \file glonass_l1_ca_dll_pll_tracking.h + * \file glonass_l1_ca_dll_pll_c_aid_tracking.h * \brief Interface of an adapter of a DLL+PLL tracking loop block * for Glonass L1 C/A to a TrackingInterface * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc index adedc967a..3fd0e74cd 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc @@ -1,7 +1,6 @@ /*! - * \file glonass_l1_ca_dll_pll_tracking.h - * \brief Interface of an adapter of a DLL+PLL tracking loop block - * for Glonass L1 C/A to a TrackingInterface + * \file glonass_l1_ca_dll_pll_c_aid_tracking_cc.h + * \brief Implementation of a code DLL + carrier PLL tracking block * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h index fd8c3f181..d928beb29 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h @@ -1,7 +1,6 @@ /*! * \file glonass_l1_ca_dll_pll_c_aid_tracking_cc.h - * \brief Interface of an adapter of a DLL+PLL tracking loop block - * for Glonass L1 C/A to a TrackingInterface + * \brief Implementation of a code DLL + carrier PLL tracking block * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc index 99ce87e3b..9619167f4 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc @@ -1,7 +1,6 @@ /*! - * \file glonass_l1_ca_dll_pll_tracking.h - * \brief Interface of an adapter of a DLL+PLL tracking loop block - * for Glonass L1 C/A to a TrackingInterface + * \file glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc + * \brief Implementation of a code DLL + carrier PLL tracking block * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h index 5fe82b1b9..e9424f9c7 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h @@ -1,7 +1,6 @@ /*! - * \file glonass_l1_ca_dll_pll_tracking.h - * \brief Interface of an adapter of a DLL+PLL tracking loop block - * for Glonass L1 C/A to a TrackingInterface + * \file glonass_l1_ca_dll_pll_c_aid_tracking_sc.h + * \brief Implementation of a code DLL + carrier PLL tracking block * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc index 3b898754f..c2b22a832 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc @@ -1,7 +1,6 @@ /*! - * \file glonass_l1_ca_dll_pll_tracking.h - * \brief Interface of an adapter of a DLL+PLL tracking loop block - * for Glonass L1 C/A to a TrackingInterface + * \file glonass_l1_ca_dll_pll_tracking_cc.cc + * \brief Implementation of a code DLL + carrier PLL tracking block * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h index 3e7a0cb14..641c6f04e 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h @@ -1,7 +1,6 @@ /*! - * \file glonass_l1_ca_dll_pll_tracking.h - * \brief Interface of an adapter of a DLL+PLL tracking loop block - * for Glonass L1 C/A to a TrackingInterface + * \file glonass_l1_ca_dll_pll_tracking_cc.h + * \brief Implementation of a code DLL + carrier PLL tracking block * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com From dd77cd10dfc23e4f92a300f7a15e7e0b229118c5 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 22 Jan 2018 12:21:28 +0100 Subject: [PATCH 56/96] Remove debug lines --- .../adapters/spir_gss6450_file_signal_source.cc | 15 --------------- .../adapters/spir_gss6450_file_signal_source.h | 2 -- .../unpack_spir_gss6450_samples.cc | 17 ----------------- .../unpack_spir_gss6450_samples.h | 1 - 4 files changed, 35 deletions(-) diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc index 81a7d33e6..f19d9d3d6 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc @@ -54,7 +54,6 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* filename_ = configuration->property(role + ".filename", default_filename); repeat_ = configuration->property(role + ".repeat", false); dump_ = configuration->property(role + ".dump", false); - dump_test_ = configuration->property(role + ".dump_test", false); endian_swap_ = configuration->property(role + ".endian", false); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); enable_throttle_control_ = configuration->property(role + ".enable_throttle_control", false); @@ -150,10 +149,6 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* sink_ = gr::blocks::file_sink::make(sizeof(gr_complex), dump_filename_.c_str()); DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")"; } - if (dump_test_) - { - sink_test = gr::blocks::file_sink::make(sizeof(int), (dump_filename_ + "int").c_str()); - } if (enable_throttle_control_) { throttle_ = gr::blocks::throttle::make(sizeof(gr_complex), sampling_frequency_); @@ -216,11 +211,6 @@ void SpirGSS6450FileSignalSource::connect(gr::top_block_sptr top_block) { top_block->connect(valve_, 0, sink_, 0); } - if(dump_test_) - { - if(endian_swap_) top_block->connect(endian_, 0, sink_test, 0); - else top_block->connect(deint_, sel_ch_ - 1, sink_test, 0); - } } else { @@ -268,11 +258,6 @@ void SpirGSS6450FileSignalSource::disconnect(gr::top_block_sptr top_block) { top_block->disconnect(valve_, 0, sink_, 0); } - if(dump_test_) - { - if(endian_swap_) top_block->disconnect(endian_, 0, sink_test, 0); - else top_block->disconnect(deint_, sel_ch_ - 1, sink_test, 0); - } } else { diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h index 411d04069..caa26c8fb 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h @@ -112,7 +112,6 @@ private: std::string filename_; bool repeat_; bool dump_; //Enables dumping the gr_complex sample output - bool dump_test_; //Enables dumping the raw 32-bits deinterleaved (and endian swapped if enabled) words bool enable_throttle_control_; bool endian_swap_; std::string dump_filename_; @@ -130,7 +129,6 @@ private: unpack_spir_gss6450_samples_sptr unpack_spir_; boost::shared_ptr valve_; gr::blocks::file_sink::sptr sink_; - gr::blocks::file_sink::sptr sink_test; gr::blocks::throttle::sptr throttle_; gr::msg_queue::sptr queue_; size_t item_size_; diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc index 5992c7025..7bbb2cb75 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc @@ -83,7 +83,6 @@ int unpack_spir_gss6450_samples::work(int noutput_items, for(int i = 0; i < noutput_items; i++) { int sample_aux = in[in_counter]; - //reverse_bits(sample_aux); int aux_i = sample_aux; int aux_q = sample_aux; int i_shift = adc_bits * 2 * (samples_per_int - n_sample - 1) + adc_bits; @@ -101,22 +100,6 @@ int unpack_spir_gss6450_samples::work(int noutput_items, return noutput_items; } -void unpack_spir_gss6450_samples::reverse_bits(int& data) -{ - unsigned int v = data; // input bits to be reversed - unsigned int r = v; // r will be reversed bits of v; first get LSB of v - int s = sizeof(v) * CHAR_BIT - 1; // extra shift needed at end - - for (v >>= 1; v; v >>= 1) - { - r <<= 1; - r |= v & 1; - s--; - } - r <<= s; // shift when v's highest bits are zero - data = r; -} - void unpack_spir_gss6450_samples::compute_two_complement(int& data) { data = map_[data]; diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h index df890fc74..a592c2aee 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h @@ -55,7 +55,6 @@ private: unsigned int samples_per_int; void process_sample(gr_complex& out); void compute_two_complement(int& data); - void reverse_bits(int& data); int i_data; int q_data; int mask_data; From 0dab500fb0483bcb1e082a5b122976e96b98d8f6 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 22 Jan 2018 12:38:38 +0100 Subject: [PATCH 57/96] Update author --- .../gnuradio_blocks/unpack_spir_gss6450_samples.cc | 8 ++++---- .../gnuradio_blocks/unpack_spir_gss6450_samples.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc index 7bbb2cb75..6a7bf869a 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc @@ -1,11 +1,11 @@ /*! - * \file unpack_intspir_1bit_samples.cc + * \file unpack_spir_gss6450_samples.cc * - * \brief Unpacks SPIR int samples to NSR 1 bit samples - * \author Fran Fabra fabra (at) ice.csic.es + * \brief Unpacks SPIR int samples + * \author Antonio Ramos, antonio(at)cttc.es * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h index a592c2aee..25db1a9d6 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h @@ -1,11 +1,11 @@ /*! - * \file unpack_intspir_1bit_samples.h + * \file unpack_spir_gss6450_samples.h * - * \brief Unpacks SPIR int samples to NSR 1 bit samples - * \author Fran Fabra fabra (at) ice.csic.es + * \brief Unpacks SPIR int samples + * \author Antonio Ramos, antonio.ramos(at)cttc.es * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver From 84fe651f0d67216e9e051bf0b32dcfd4f94a856d Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Tue, 23 Jan 2018 17:31:42 +0100 Subject: [PATCH 58/96] Adding Labsat v2 and v3 single channel signal recorder file source --- ...galileo_E1_extended_correlator_labsat.conf | 333 ++++++++++++ .../signal_source/adapters/CMakeLists.txt | 1 + .../adapters/labsat_signal_source.cc | 122 +++++ .../adapters/labsat_signal_source.h | 94 ++++ .../gnuradio_blocks/CMakeLists.txt | 1 + .../gnuradio_blocks/labsat23_source.cc | 474 ++++++++++++++++++ .../gnuradio_blocks/labsat23_source.h | 75 +++ src/core/receiver/gnss_block_factory.cc | 16 + 8 files changed, 1116 insertions(+) create mode 100644 conf/gnss-sdr_galileo_E1_extended_correlator_labsat.conf create mode 100644 src/algorithms/signal_source/adapters/labsat_signal_source.cc create mode 100644 src/algorithms/signal_source/adapters/labsat_signal_source.h create mode 100644 src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc create mode 100644 src/algorithms/signal_source/gnuradio_blocks/labsat23_source.h diff --git a/conf/gnss-sdr_galileo_E1_extended_correlator_labsat.conf b/conf/gnss-sdr_galileo_E1_extended_correlator_labsat.conf new file mode 100644 index 000000000..094f15ebe --- /dev/null +++ b/conf/gnss-sdr_galileo_E1_extended_correlator_labsat.conf @@ -0,0 +1,333 @@ +; Default configuration file +; 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_hz: Internal signal sampling frequency after the signal conditioning stage [Hz]. +GNSS-SDR.internal_fs_hz=5456000 + +;######### SIGNAL_SOURCE CONFIG ############ +;#implementation: Use [File_Signal_Source] [Nsr_File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) +SignalSource.implementation=Labsat_Signal_Source + +SignalSource.selected_channel=1 + +;#filename: path to file with the captured GNSS signal samples to be processed +;# Labsat sile source automatically increments the file name when the signal is splitted in several files +;# the adapter adds "_0000.LS3" to this base path and filename. Next file will be "_0001.LS3" and so on +;# in this example, the first file complete path will be ../signals/GPS_025_0000.LS3 + +SignalSource.filename=../signals/GPS_025 ; <- PUT YOUR FILE HERE + +;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +SignalSource.item_type=gr_complex + +;#sampling_frequency: Original Signal sampling frequency in [Hz] +SignalSource.sampling_frequency=16368000 + +;#freq: RF front-end center frequency in [Hz] +SignalSource.freq=1575420000 + +;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. +SignalSource.samples=0 + +;#repeat: Repeat the processing file. Disable this option in this version +SignalSource.repeat=false + +;#dump: Dump the Signal source data to a file. Disable this option in this version +SignalSource.dump=false + +SignalSource.dump_filename=../data/signal_source.dat + + +;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. +; it helps to not overload the CPU, but the processing time will be longer. +SignalSource.enable_throttle_control=false + +;######### SIGNAL_CONDITIONER CONFIG ############ +;## It holds blocks to change data type, filter and resample input data. + +;#implementation: Use [Pass_Through] or [Signal_Conditioner] +;#[Pass_Through] disables this block and the [DataTypeAdapter], [InputFilter] and [Resampler] blocks +;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks +SignalConditioner.implementation=Signal_Conditioner + +;######### DATA_TYPE_ADAPTER CONFIG ############ +;## Changes the type of input data. +;#implementation: [Pass_Through] disables this block +DataTypeAdapter.implementation=Pass_Through +DataTypeAdapter.item_type=gr_complex + +;######### INPUT_FILTER CONFIG ############ +;## Filter the input data. Can be combined with frequency translation for IF signals + +;#implementation: Use [Pass_Through] or [Fir_Filter] or [Freq_Xlating_Fir_Filter] +;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation +;# that shifts IF down to zero Hz. + +InputFilter.implementation=Freq_Xlating_Fir_Filter + +;#dump: Dump the filtered data to a file. +InputFilter.dump=false + +;#dump_filename: Log path and filename. +InputFilter.dump_filename=../data/input_filter.dat + +;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. +;#These options are based on parameters of gnuradio's function: gr_remez. +;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse +;#reponse given a set of band edges, the desired reponse on those bands, +;#and the weight given to the error in those bands. + +;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +InputFilter.input_item_type=gr_complex + +;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +InputFilter.output_item_type=gr_complex + +;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. +InputFilter.taps_item_type=float + +;#number_of_taps: Number of taps in the filter. Increasing this parameter increases the processing time +InputFilter.number_of_taps=5 + +;#number_of _bands: Number of frequency bands in the filter. +InputFilter.number_of_bands=2 + +;#bands: frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...]. +;#Frequency is in the range [0, 1], with 1 being the Nyquist frequency (Fs/2) +;#The number of band_begin and band_end elements must match the number of bands + +InputFilter.band1_begin=0.0 +InputFilter.band1_end=0.45 +InputFilter.band2_begin=0.55 +InputFilter.band2_end=1.0 + +;#ampl: desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...]. +;#The number of ampl_begin and ampl_end elements must match the number of bands + +InputFilter.ampl1_begin=1.0 +InputFilter.ampl1_end=1.0 +InputFilter.ampl2_begin=0.0 +InputFilter.ampl2_end=0.0 + +;#band_error: weighting applied to each band (usually 1). +;#The number of band_error elements must match the number of bands +InputFilter.band1_error=1.0 +InputFilter.band2_error=1.0 + +;#filter_type: one of "bandpass", "hilbert" or "differentiator" +InputFilter.filter_type=bandpass + +;#grid_density: determines how accurately the filter will be constructed. +;The minimum value is 16; higher values are slower to compute the filter. +InputFilter.grid_density=16 + +;# Original sampling frequency stored in the signal file +InputFilter.sampling_frequency=16368000 + +;#The following options are used only in Freq_Xlating_Fir_Filter implementation. +;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz + +InputFilter.IF=0 + +;# Decimation factor after the frequency tranaslating block +InputFilter.decimation_factor=3 + + +;######### CHANNELS GLOBAL CONFIG ############ +;#count: Number of available GPS satellite channels. +Channels_1C.count=0 +;#count: Number of available Galileo satellite channels. +Channels_1B.count=6 +;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver +Channels.in_acquisition=1 + +;#signal: +;#if the option is disabled by default is assigned "1C" GPS L1 C/A +Channel0.signal=1B +Channel1.signal=1B +Channel2.signal=1B +Channel3.signal=1B +Channel4.signal=1B +Channel5.signal=1B +Channel6.signal=1B +Channel7.signal=1B +Channel8.signal=1B +Channel9.signal=1B +Channel10.signal=1B +Channel11.signal=1B +Channel12.signal=1B +Channel13.signal=1B +Channel14.signal=1B +Channel15.signal=1B + + +;######### GPS ACQUISITION CONFIG ############ + +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1C.dump=false +;#filename: Log path and filename +Acquisition_1C.dump_filename=./acq_dump.dat +;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1C.item_type=gr_complex +;#if: Signal intermediate frequency in [Hz] +Acquisition_1C.if=0 +;#sampled_ms: Signal block duration for the acquisition signal detection [ms] +Acquisition_1C.sampled_ms=1 +;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +Acquisition_1C.use_CFAR_algorithm=false; +;#threshold: Acquisition threshold +Acquisition_1C.threshold=22 +;#doppler_max: Maximum expected Doppler shift [Hz] +Acquisition_1C.doppler_max=5000 +;#doppler_max: Doppler step in the grid search [Hz] +Acquisition_1C.doppler_step=250 + + +;######### GALILEO ACQUISITION CONFIG ############ + +;#dump: Enable or disable the acquisition internal data file logging [true] or [false] +Acquisition_1B.dump=false +;#filename: Log path and filename +Acquisition_1B.dump_filename=../data/acq_dump.dat +;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +Acquisition_1B.item_type=gr_complex +;#if: Signal intermediate frequency in [Hz] +Acquisition_1B.if=0 +;#sampled_ms: Signal block duration for the acquisition signal detection [ms] +Acquisition_1B.sampled_ms=4 +;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition] +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +Acquisition_1B.acquire_pilot=true +Acquisition_1B.use_CFAR_algorithm=false +;#threshold: Acquisition threshold +Acquisition_1B.threshold=22 +;#doppler_max: Maximum expected Doppler shift [Hz] +Acquisition_1B.doppler_max=5000 +;#doppler_max: Doppler step in the grid search [Hz] +Acquisition_1B.doppler_step=125 +Acquisition_1B.bit_transition_flag=true + +;######### TRACKING GPS CONFIG ############ + +;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] +Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking +;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version. +Tracking_1C.item_type=gr_complex + +;#sampling_frequency: Signal Intermediate Frequency in [Hz] +Tracking_1C.if=0 + +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1C.dump=true + +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1C.dump_filename=../data/epl_tracking_ch_ + +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1C.pll_bw_hz=40.0; + +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1C.dll_bw_hz=2.0; + +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1C.order=3; + +;######### TRACKING GALILEO CONFIG ############ + +;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_PLL_C_Aid_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking] +Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking +;#item_type: Type and resolution for each of the signal samples. +Tracking_1B.item_type=gr_complex + +;#sampling_frequency: Signal Intermediate Frequency in [Hz] +Tracking_1B.if=0 + +;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false] +Tracking_1B.dump=true + +;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number. +Tracking_1B.dump_filename=../data/veml_tracking_ch_ + +Tracking_1B.track_pilot=true + +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1B.pll_bw_hz=7.5; + +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1B.dll_bw_hz=0.5; + +;#pll_bw_hz: PLL loop filter bandwidth [Hz] +Tracking_1B.pll_bw_narrow_hz=2.5; + +;#dll_bw_hz: DLL loop filter bandwidth [Hz] +Tracking_1B.dll_bw_narrow_hz=0.25; + +Tracking_1B.extend_correlation_symbols=4; + +;#order: PLL/DLL loop filter order [2] or [3] +Tracking_1B.order=3; + +;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo +Tracking_1B.early_late_space_chips=0.15; + +;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] +Tracking_1B.very_early_late_space_chips=0.6; + +;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo +Tracking_1B.early_late_space_narrow_chips=0.15; + +;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6] +Tracking_1B.very_early_late_space_narrow_chips=0.30; + + + +;######### TELEMETRY DECODER GPS CONFIG ############ +;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A +TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder +TelemetryDecoder_1C.dump=false + +;######### TELEMETRY DECODER GALILEO CONFIG ############ +;#implementation: Use [Galileo_E1B_Telemetry_Decoder] for Galileo E1B +TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder +TelemetryDecoder_1B.dump=false + +;######### OBSERVABLES CONFIG ############ +;#implementation: +Observables.implementation=Hybrid_Observables + +;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] +Observables.dump=false + +;#dump_filename: Log path and filename. +Observables.dump_filename=./observables.dat + + +;######### PVT CONFIG ############ +;#implementation: Position Velocity and Time (PVT) implementation: +PVT.implementation=RTKLIB_PVT + +PVT.positioning_mode=Single ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic +PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX +PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad + +;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms] +PVT.output_rate_ms=100; + +;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms. +PVT.display_rate_ms=500; + +;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] +PVT.dump=false + +PVT.flag_rtcm_server=false +PVT.flag_rtcm_tty_port=false +PVT.rtcm_dump_devname=/dev/pts/1 + +;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. +PVT.dump_filename=./PVT diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index 3d786bb46..2fb8f4be8 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -141,6 +141,7 @@ set(SIGNAL_SOURCE_ADAPTER_SOURCES file_signal_source.cc spir_file_signal_source.cc spir_gss6450_file_signal_source.cc rtl_tcp_signal_source.cc + labsat_signal_source.cc ${OPT_DRIVER_SOURCES} ) diff --git a/src/algorithms/signal_source/adapters/labsat_signal_source.cc b/src/algorithms/signal_source/adapters/labsat_signal_source.cc new file mode 100644 index 000000000..ead38e585 --- /dev/null +++ b/src/algorithms/signal_source/adapters/labsat_signal_source.cc @@ -0,0 +1,122 @@ +/*! + * \file labsat_signal_source.cc + * \brief Labsat 2 and 3 front-end signal sampler driver + * \author Javier Arribas, jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * 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 . + * + * ------------------------------------------------------------------------- + */ + +#include "labsat_signal_source.h" +#include +#include +#include +#include +#include "labsat23_source.h" +#include "configuration_interface.h" + + +using google::LogMessage; + +LabsatSignalSource::LabsatSignalSource(ConfigurationInterface* configuration, + std::string role, unsigned int in_stream, unsigned int out_stream, gr::msg_queue::sptr queue) : + role_(role), in_stream_(in_stream), out_stream_(out_stream), queue_(queue) +{ + std::string default_item_type = "gr_complex"; + std::string default_dump_file = "./data/source.bin"; + item_type_ = configuration->property(role + ".item_type", default_item_type); + dump_ = configuration->property(role + ".dump", false); + dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); + + int channel_selector=configuration->property(role + ".selected_channel", 1); + std::string default_filename = "./example_capture.LS3"; + + samples_ = configuration->property(role + ".samples", 0); + filename_ = configuration->property(role + ".filename", default_filename); + + if (item_type_.compare("gr_complex") == 0) + { + item_size_ = sizeof(gr_complex); + labsat23_source_ = labsat23_make_source(filename_.c_str(),channel_selector); + DLOG(INFO) << "Item size " << item_size_; + DLOG(INFO) << "labsat23_source_(" << labsat23_source_->unique_id() << ")"; + }else + { + LOG(WARNING) << item_type_ + << " unrecognized item type for LabSat source"; + item_size_ = sizeof(short); + } + if (dump_) + { + DLOG(INFO) << "Dumping output into file " << dump_filename_; + file_sink_ = gr::blocks::file_sink::make(item_size_, dump_filename_.c_str()); + } + if (dump_) + { + DLOG(INFO) << "file_sink(" << file_sink_->unique_id() << ")"; + } +} + + + +LabsatSignalSource::~LabsatSignalSource() +{} + + + +void LabsatSignalSource::connect(gr::top_block_sptr top_block) +{ + if (dump_) + { + top_block->connect(labsat23_source_, 0, file_sink_, 0); + DLOG(INFO) << "connected labsat23_source_ to file sink"; + } + else + { + DLOG(INFO) << "nothing to connect internally"; + } +} + + + +void LabsatSignalSource::disconnect(gr::top_block_sptr top_block) +{ + if (dump_) + { + top_block->disconnect(labsat23_source_, 0, file_sink_, 0); + } +} + + +gr::basic_block_sptr LabsatSignalSource::get_left_block() +{ + LOG(WARNING) << "Left block of a signal source should not be retrieved"; + return gr::block_sptr(); +} + + +gr::basic_block_sptr LabsatSignalSource::get_right_block() +{ + return labsat23_source_; +} diff --git a/src/algorithms/signal_source/adapters/labsat_signal_source.h b/src/algorithms/signal_source/adapters/labsat_signal_source.h new file mode 100644 index 000000000..6909acefc --- /dev/null +++ b/src/algorithms/signal_source/adapters/labsat_signal_source.h @@ -0,0 +1,94 @@ +/*! + * \file labsat_signal_source.h + * \brief Labsat 2 and 3 front-end signal sampler driver + * \author Javier Arribas, jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * 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 . + * + * ------------------------------------------------------------------------- + */ + + +#ifndef LABSAT_SIGNAL_SOURCE_H_ +#define LABSAT_SIGNAL_SOURCE_H_ + +#include +#include +#include +#include +#include "gnss_block_interface.h" + + +class ConfigurationInterface; + +/*! + * \brief This class reads samples from a GN3S USB dongle, a RF front-end signal sampler + */ +class LabsatSignalSource: public GNSSBlockInterface +{ +public: + LabsatSignalSource(ConfigurationInterface* configuration, + std::string role, unsigned int in_stream, + unsigned int out_stream, gr::msg_queue::sptr queue); + + virtual ~LabsatSignalSource(); + + inline std::string role() override + { + return role_; + } + + /*! + * \brief Returns "LabsatSignalSource". + */ + inline std::string implementation() override + { + return "Labsat_Signal_Source"; + } + + 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; + +private: + std::string role_; + unsigned int in_stream_; + unsigned int out_stream_; + std::string item_type_; + size_t item_size_; + long samples_; + std::string filename_; + bool dump_; + std::string dump_filename_; + gr::block_sptr labsat23_source_; + gr::blocks::file_sink::sptr file_sink_; + boost::shared_ptr queue_; +}; + +#endif /*LABSAT_SIGNAL_SOURCE_H_*/ diff --git a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt index 67b9f3162..a9252edb0 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt @@ -24,6 +24,7 @@ set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES rtl_tcp_signal_source_c.cc unpack_2bit_samples.cc unpack_spir_gss6450_samples.cc + labsat23_source.cc ) include_directories( diff --git a/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc b/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc new file mode 100644 index 000000000..375d246ab --- /dev/null +++ b/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc @@ -0,0 +1,474 @@ +/*! + * \file labsat23_source.cc + * + * \brief Unpacks the Labsat 2 (ls2) and (ls3) capture files + * \author Javier Arribas jarribas (at) cttc.es + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#include "labsat23_source.h" +#include +#include + +labsat23_source_sptr labsat23_make_source(const char *signal_file_basename, int channel_selector) +{ + return labsat23_source_sptr(new labsat23_source(signal_file_basename, channel_selector)); +} + +std::string labsat23_source::generate_filename() +{ + std::ostringstream ss; + ss << std::setw(4) << std::setfill('0') << d_current_file_number; + return d_signal_file_basename + "_" + ss.str()+".LS3"; + +} + +labsat23_source::labsat23_source(const char *signal_file_basename, int channel_selector) : gr::block("labsat23_source", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(1, 1, sizeof(gr_complex))) +{ + if (channel_selector<1 or channel_selector>2) + { + std::cout<<"Labsat source config error: channel selection out of bounds, check gnss-sdr config file"<set_output_multiple(8); + signal_file=generate_filename(); + binary_input_file = new std::ifstream (signal_file.c_str(), std::ios::in|std::ios::binary); + + if (binary_input_file->is_open()) + { + std::cout<<"Labsat file source is reading samples from "<is_open()) + { + binary_input_file->close(); + } + delete binary_input_file; +} + +int labsat23_source::getBit(uint8_t byte, int position) +{ + return (byte >> position) & 0x01; +} + +void labsat23_source::decode_samples_one_channel(int16_t input_short, gr_complex* out, int type) +{ + std::bitset<16> bs(input_short); + switch(type) + { + case 2: + //two bits per sample, 8 samples per int16 + for (int i=0;i<8;i++) + { + out[i]=gr_complex(static_cast(bs[15-(2*i)]), + static_cast(bs[14-(2*i)])); + out[i]=out[i]*gr_complex(2,0)-gr_complex(1,1); + } + break; + case 4: + //four bits per sample, 4 samples per int16 + for (int i=0;i<4;i++) + { + out[i]=gr_complex(0.0,0.0); + //In-Phase + if (bs[15-4*i]) + { + if (bs[13-4*i]) //11 + { + out[i]+=gr_complex(-1,0); + } + else //10 + { + out[i]+=gr_complex(-2,0); + } + } + else{ + if (bs[13-4*i]) //01 + { + out[i]+=gr_complex(1,0); + } + } + + //Quadrature + if (bs[14-4*i]) + { + if (bs[12-4*i]) //11 + { + out[i]+=gr_complex(0,-1); + } + else //10 + { + out[i]+=gr_complex(0,-2); + } + } + else{ + if (bs[12-4*i]) //01 + { + out[i]+=gr_complex(0,1); + } + } + out[i]+=gr_complex(0.5,0.5); + } + break; + } +} + +int labsat23_source::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) +{ + + gr_complex *out = reinterpret_cast(output_items[0]); + + if (d_header_parsed==false) + { + + if (binary_input_file->eof()==false) + { + char memblock[1024]; + binary_input_file->read(memblock,1024); + //parse Labsat header + //check preamble + int byte_counter=0; + bool preamble_ok=true; + for (int i=0;i<8;i++) + { + if (memblock[byte_counter]!=0x00) preamble_ok=false; + //std::cout<<"H["<clear(); + binary_input_file->seekg(header_bytes, binary_input_file->beg); + return 0; + }else{ + std::cout<<"Labsat file header error: section 2 is not available."<0) + { + int16_t memblock[n_int16_to_read]; + binary_input_file->read((char*)memblock,n_int16_to_read*2); + n_int16_to_read=binary_input_file->gcount()/2; //from bytes to int16 + if (n_int16_to_read>0) + { + int output_pointer=0; + for (int i=0;iclose(); + binary_input_file->open(generate_filename().c_str(), std::ios::in|std::ios::binary); + if (binary_input_file->is_open()) + { + std::cout<<"Labsat file source is reading samples from "<0) + { + int16_t memblock[n_int16_to_read]; + binary_input_file->read((char*)memblock,n_int16_to_read*2); + n_int16_to_read=binary_input_file->gcount()/2; //from bytes to int16 + if (n_int16_to_read>0) + { + int output_pointer=0; + for (int i=0;iclose(); + binary_input_file->open(generate_filename().c_str(), std::ios::in|std::ios::binary); + if (binary_input_file->is_open()) + { + std::cout<<"Labsat file source is reading samples from "<. + * + * ------------------------------------------------------------------------- + */ + +#ifndef LABSAT23_SOURCE_H +#define LABSAT23_SOURCE_H + +#include +#include +#include +#include +#include + +class labsat23_source; + +typedef boost::shared_ptr labsat23_source_sptr; + +labsat23_source_sptr labsat23_make_source(const char *signal_file_basename, int channel_selector); + +/*! + * \brief This class implements conversion between Labsat2 and 3 format byte packet samples to gr_complex + */ +class labsat23_source: public gr::block +{ +private: + friend labsat23_source_sptr labsat23_make_source_sptr(const char *signal_file_basename, int channel_selector); + std::string generate_filename(); + void decode_samples_one_channel(int16_t input_short, gr_complex* out, int type); + int getBit(uint8_t byte, int position); + bool d_header_parsed; + uint8_t d_channel_selector; + int d_channel_selector_config; + int d_current_file_number; + uint8_t d_labsat_version; + std::string d_signal_file_basename; + std::ifstream *binary_input_file; + uint8_t d_ref_clock; + uint8_t d_bits_per_sample; + +public: + labsat23_source(const char *signal_file_basename, int channel_selector); + ~labsat23_source(); + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 322577e62..855b192a3 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -51,6 +51,7 @@ #include "spir_gss6450_file_signal_source.h" #include "rtl_tcp_signal_source.h" #include "two_bit_packed_file_signal_source.h" +#include "labsat_signal_source.h" #include "channel.h" #include "signal_conditioner.h" @@ -896,6 +897,21 @@ std::unique_ptr GNSSBlockFactory::GetBlock( block = std::move(block_); } + catch (const std::exception &e) + { + std::cout << "GNSS-SDR program ended." << std::endl; + exit(1); + } + } + else if (implementation.compare("Labsat_Signal_Source") == 0) + { + try + { + std::unique_ptr block_(new LabsatSignalSource(configuration.get(), role, in_streams, + out_streams, queue)); + block = std::move(block_); + } + catch (const std::exception &e) { std::cout << "GNSS-SDR program ended." << std::endl; From a5d65f3424537e9e432cc32768fdb4a299fc75c3 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Tue, 23 Jan 2018 17:33:06 +0100 Subject: [PATCH 59/96] Bug fix: adding exception control to std::map access in observables block --- .../gnuradio_blocks/hybrid_observables_cc.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc index efd29e092..66cd0fce0 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc @@ -453,6 +453,7 @@ int hybrid_observables_cc::general_work (int noutput_items , d_gnss_synchro_history_queue[i].at(distance - 1))); } } + } else { @@ -478,7 +479,8 @@ int hybrid_observables_cc::general_work (int noutput_items , // compute interpolated TOW value at T_rx_s int ref_channel_key = gnss_synchro_map_iter->second.Channel_ID; - Gnss_Synchro adj_obs = adjacent_gnss_synchro_map.at(ref_channel_key); + Gnss_Synchro adj_obs; + adj_obs = adjacent_gnss_synchro_map.at(ref_channel_key); double ref_adj_T_rx_s = static_cast(adj_obs.Tracking_sample_counter) / ref_fs_hz + adj_obs.Code_phase_samples / ref_fs_hz; double d_TOW_reference = gnss_synchro_map_iter->second.TOW_at_current_symbol_s; @@ -504,7 +506,12 @@ int hybrid_observables_cc::general_work (int noutput_items , // two points linear interpolation using adjacent (adj) values: y=y1+(x-x1)*(y2-y1)/(x2-x1) // TOW at the selected receiver time T_rx_s int element_key = gnss_synchro_map_iter->second.Channel_ID; - adj_obs = adjacent_gnss_synchro_map.at(element_key); + try{ + adj_obs = adjacent_gnss_synchro_map.at(element_key); + }catch(const std::exception & ex) + { + continue; + } double adj_T_rx_s = static_cast(adj_obs.Tracking_sample_counter) / channel_fs_hz + adj_obs.Code_phase_samples / channel_fs_hz; From 114121ef510b4f52cedf4519b79db204a65a9164 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Tue, 23 Jan 2018 17:36:32 +0100 Subject: [PATCH 60/96] Addign some useful matlab binary file reading functions --- src/utils/matlab/libs/read_complex_binary.m | 57 +++++++++++++++++++ .../matlab/libs/read_complex_char_binary.m | 48 ++++++++++++++++ .../matlab/libs/read_complex_short_binary.m | 48 ++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 src/utils/matlab/libs/read_complex_binary.m create mode 100644 src/utils/matlab/libs/read_complex_char_binary.m create mode 100644 src/utils/matlab/libs/read_complex_short_binary.m diff --git a/src/utils/matlab/libs/read_complex_binary.m b/src/utils/matlab/libs/read_complex_binary.m new file mode 100644 index 000000000..a201b99bb --- /dev/null +++ b/src/utils/matlab/libs/read_complex_binary.m @@ -0,0 +1,57 @@ +% +% Copyright 2001 Free Software Foundation, Inc. +% +% This file is part of GNU Radio +% +% GNU Radio 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, or (at your option) +% any later version. +% +% GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +% the Free Software Foundation, Inc., 51 Franklin Street, +% Boston, MA 02110-1301, USA. +% + +function v = read_complex_binary (filename, count, start_sample) + + %% usage: read_complex_binary (filename, [count], [start_sample]) + %% + %% open filename and return the contents as a column vector, + %% treating them as 32 bit complex numbers + %% + + m = nargchk (1,2,nargin); + if (m) + %usage (m); + end + + if (nargin < 2) + count = Inf; + start_sample=0; + end + + if (nargin < 3) + start_sample=0; + end + + f = fopen (filename, 'rb'); + if (f < 0) + v = 0; + else + if (start_sample>0) + bytes_per_sample=4; + fseek(f,start_sample*bytes_per_sample,'bof'); + end + t = fread (f, [2, count], 'float'); + fclose (f); + v = t(1,:) + t(2,:)*i; + [r, c] = size (v); + v = reshape (v, c, r); + end diff --git a/src/utils/matlab/libs/read_complex_char_binary.m b/src/utils/matlab/libs/read_complex_char_binary.m new file mode 100644 index 000000000..cafaedcc7 --- /dev/null +++ b/src/utils/matlab/libs/read_complex_char_binary.m @@ -0,0 +1,48 @@ +% +% Copyright 2001 Free Software Foundation, Inc. +% +% This file is part of GNU Radio +% +% GNU Radio 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, or (at your option) +% any later version. +% +% GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +% the Free Software Foundation, Inc., 51 Franklin Street, +% Boston, MA 02110-1301, USA. +% + +function v = read_complex_char_binary (filename, count) + + %% usage: read_complex_binary (filename, [count]) + %% + %% open filename and return the contents as a column vector, + %% treating them as 32 bit complex numbers + %% + + m = nargchk (1,2,nargin); + if (m) + usage (m); + end + + if (nargin < 2) + count = Inf; + end + + f = fopen (filename, 'rb'); + if (f < 0) + v = 0; + else + t = fread (f, [2, count], 'int8'); + fclose (f); + v = t(1,:) + t(2,:)*i; + [r, c] = size (v); + v = reshape (v, c, r); + end diff --git a/src/utils/matlab/libs/read_complex_short_binary.m b/src/utils/matlab/libs/read_complex_short_binary.m new file mode 100644 index 000000000..55118528b --- /dev/null +++ b/src/utils/matlab/libs/read_complex_short_binary.m @@ -0,0 +1,48 @@ +% +% Copyright 2001 Free Software Foundation, Inc. +% +% This file is part of GNU Radio +% +% GNU Radio 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, or (at your option) +% any later version. +% +% GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +% the Free Software Foundation, Inc., 51 Franklin Street, +% Boston, MA 02110-1301, USA. +% + +function v = read_complex_short_binary (filename, count) + + %% usage: read_complex_binary (filename, [count]) + %% + %% open filename and return the contents as a column vector, + %% treating them as 32 bit complex numbers + %% + + m = nargchk (1,2,nargin); + if (m) + usage (m); + end + + if (nargin < 2) + count = Inf; + end + + f = fopen (filename, 'rb'); + if (f < 0) + v = 0; + else + t = fread (f, [2, count], 'short'); + fclose (f); + v = t(1,:) + t(2,:)*i; + [r, c] = size (v); + v = reshape (v, c, r); + end From ef2c2bcf6bdd53f6e2d0e60939b428bada8b519d Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 23 Jan 2018 19:51:36 +0100 Subject: [PATCH 61/96] Fix building with Clang --- .../signal_source/adapters/spir_gss6450_file_signal_source.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc index f19d9d3d6..75d30b9f5 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc @@ -131,7 +131,7 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* if(size > 0) { - samples_ = static_cast(floor(static_cast(size - bytes_seek) / (sample_size_byte * static_cast(n_channels_)))); + samples_ = static_cast(floor(static_cast(static_cast(size) - static_cast(bytes_seek)) / (sample_size_byte * static_cast(n_channels_)))); samples_ = samples_- static_cast(ceil(0.002 * sampling_frequency_)); //process all the samples available in the file excluding the last 2 ms } } From 2a9d6975e0279d745e7d43659726aab139cbede0 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 23 Jan 2018 20:07:43 +0100 Subject: [PATCH 62/96] Apply coding style --- .../gnuradio_blocks/labsat23_source.cc | 701 +++++++++--------- 1 file changed, 361 insertions(+), 340 deletions(-) diff --git a/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc b/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc index 375d246ab..d5bfea224 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc @@ -36,439 +36,460 @@ #include #include + labsat23_source_sptr labsat23_make_source(const char *signal_file_basename, int channel_selector) { return labsat23_source_sptr(new labsat23_source(signal_file_basename, channel_selector)); } + std::string labsat23_source::generate_filename() { std::ostringstream ss; ss << std::setw(4) << std::setfill('0') << d_current_file_number; return d_signal_file_basename + "_" + ss.str()+".LS3"; - } + labsat23_source::labsat23_source(const char *signal_file_basename, int channel_selector) : gr::block("labsat23_source", - gr::io_signature::make(0, 0, 0), - gr::io_signature::make(1, 1, sizeof(gr_complex))) + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(1, 1, sizeof(gr_complex))) { - if (channel_selector<1 or channel_selector>2) - { - std::cout<<"Labsat source config error: channel selection out of bounds, check gnss-sdr config file"< 2) + { + std::cout << "Labsat source config error: channel selection out of bounds, check gnss-sdr config file" << std::endl; + exit(1); + } + d_channel_selector_config = channel_selector; + d_header_parsed = false; + d_bits_per_sample = 0; + d_current_file_number = 0; + d_labsat_version = 0; + d_signal_file_basename = std::string(signal_file_basename); std::string signal_file; this->set_output_multiple(8); - signal_file=generate_filename(); + signal_file = generate_filename(); binary_input_file = new std::ifstream (signal_file.c_str(), std::ios::in|std::ios::binary); if (binary_input_file->is_open()) - { - std::cout<<"Labsat file source is reading samples from "<is_open()) - { - binary_input_file->close(); - } + { + binary_input_file->close(); + } delete binary_input_file; } + int labsat23_source::getBit(uint8_t byte, int position) { return (byte >> position) & 0x01; } + void labsat23_source::decode_samples_one_channel(int16_t input_short, gr_complex* out, int type) { std::bitset<16> bs(input_short); switch(type) { - case 2: - //two bits per sample, 8 samples per int16 - for (int i=0;i<8;i++) + case 2: + //two bits per sample, 8 samples per int16 + for (int i = 0; i < 8; i++) { - out[i]=gr_complex(static_cast(bs[15-(2*i)]), - static_cast(bs[14-(2*i)])); - out[i]=out[i]*gr_complex(2,0)-gr_complex(1,1); + out[i] = gr_complex(static_cast(bs[15-(2*i)]), + static_cast(bs[14-(2*i)])); + out[i] = out[i]*gr_complex(2,0)-gr_complex(1,1); } - break; - case 4: - //four bits per sample, 4 samples per int16 - for (int i=0;i<4;i++) + break; + case 4: + //four bits per sample, 4 samples per int16 + for (int i = 0; i < 4; i++) { - out[i]=gr_complex(0.0,0.0); + out[i] = gr_complex(0.0,0.0); //In-Phase if (bs[15-4*i]) - { - if (bs[13-4*i]) //11 { - out[i]+=gr_complex(-1,0); + if (bs[13-4*i]) //11 + { + out[i] += gr_complex(-1,0); + } + else //10 + { + out[i] += gr_complex(-2,0); + } } - else //10 + else { - out[i]+=gr_complex(-2,0); + if (bs[13-4*i]) //01 + { + out[i] += gr_complex(1,0); + } } - } - else{ - if (bs[13-4*i]) //01 - { - out[i]+=gr_complex(1,0); - } - } //Quadrature if (bs[14-4*i]) - { - if (bs[12-4*i]) //11 { - out[i]+=gr_complex(0,-1); + if (bs[12-4*i]) //11 + { + out[i] += gr_complex(0,-1); + } + else //10 + { + out[i] += gr_complex(0,-2); + } } - else //10 + else { - out[i]+=gr_complex(0,-2); + if (bs[12-4*i]) //01 + { + out[i] += gr_complex(0,1); + } } - } - else{ - if (bs[12-4*i]) //01 - { - out[i]+=gr_complex(0,1); - } - } - out[i]+=gr_complex(0.5,0.5); + out[i] += gr_complex(0.5,0.5); } - break; + break; } } -int labsat23_source::general_work(int noutput_items, - __attribute__((unused)) gr_vector_int &ninput_items, - __attribute__((unused)) gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ +int labsat23_source::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) +{ gr_complex *out = reinterpret_cast(output_items[0]); - if (d_header_parsed==false) - { - - if (binary_input_file->eof()==false) + if (d_header_parsed == false) { - char memblock[1024]; - binary_input_file->read(memblock,1024); - //parse Labsat header - //check preamble - int byte_counter=0; - bool preamble_ok=true; - for (int i=0;i<8;i++) - { - if (memblock[byte_counter]!=0x00) preamble_ok=false; - //std::cout<<"H["<read(memblock, 1024); + //parse Labsat header + //check preamble + int byte_counter = 0; + bool preamble_ok = true; + for (int i = 0; i < 8; i++) + { + if (memblock[byte_counter] != 0x00) preamble_ok = false; + //std::cout << "H[" << i << "]:" << (int)memblock[byte_counter] << std::endl; + byte_counter++; + } + + if (preamble_ok == false) + { + std::cout << "Labsat source do not detect the preamble in the selected file" << std::endl; + return -1; + } + + // check Labsat version + if (memblock[byte_counter] == 0x4C and memblock[byte_counter+1] == 0x53 and memblock[byte_counter+2] == 0x32) + { + d_labsat_version = 2; + std::cout << "Labsat file version 2 detected" << std::endl; + } + + if (memblock[byte_counter] == 0x4C and memblock[byte_counter+1] == 0x53 and memblock[byte_counter+2] == 0x33) + { + d_labsat_version = 3; + std::cout << "Labsat file version 3 detected" << std::endl; + } + + if (d_labsat_version == 0) + { + std::cout << "Labsat source do not detect the labsat version in file header" << std::endl; + return -1; + } + + byte_counter += 3; + + int sub_version = static_cast(memblock[byte_counter]); + + std::cout << "Labsat file sub version " << sub_version << std::endl; + + byte_counter++; + + int header_bytes = 0; + header_bytes += memblock[byte_counter] | (memblock[byte_counter+1] << 8) | (memblock[byte_counter+2] << 16) | (memblock[byte_counter+3] << 24); + + byte_counter += 4; + //std::cout << "header_bytes=" << header_bytes << std::endl; + + // read first section + // section ID (little-endian) + uint8_t section_id = static_cast(memblock[byte_counter]) + static_cast(memblock[byte_counter+1]) * 256; + //std::cout << "Section ID: " << (int)section_id << std::endl; + byte_counter += 2; + + uint8_t section_lenght_bytes = 0; + section_lenght_bytes += memblock[byte_counter] | (memblock[byte_counter+1] << 8) | (memblock[byte_counter+2] << 16) | (memblock[byte_counter+3] << 24); + //std::cout << "section_lenght_bytes=" << (int)section_lenght_bytes << std::endl; + + byte_counter += 4; + if (section_id == 2) + { + d_ref_clock = static_cast(memblock[byte_counter]); + switch(d_ref_clock) + { + case 0: + std::cout << "Labsat reference clock: internal OXCO" << std::endl; + break; + case 1: + std::cout << "Labsat reference clock: internal TXCO" << std::endl; + break; + case 2: + std::cout << "Labsat reference clock: external 10 MHz" << std::endl; + break; + case 3: + std::cout << "Labsat reference clock: external 16.386 MHz" << std::endl; + break; + default: + std::cout << "Labsat Unknown reference clock ID " << static_cast(d_ref_clock) << std::endl; + } + byte_counter++; + d_bits_per_sample = static_cast(memblock[byte_counter]); + switch(d_bits_per_sample) + { + case 2: + std::cout << "Labsat is using 2 bits per sample" << std::endl; + break; + case 4: + std::cout << "Labsat is using 4 bits per sample" << std::endl; + break; + default: + std::cout << "Labsat Unknown bits per sample ID " << static_cast(d_bits_per_sample) << std::endl; + return -1; + } + + byte_counter++; + d_channel_selector = static_cast(memblock[byte_counter]); + switch(d_channel_selector) + { + case 0: + std::cout << "Available channels: Channel A + B, 1 bit quantisation" << std::endl; + break; + case 1: + std::cout << "Available channels: Channel A, 1 bit quantisation" << std::endl; + break; + case 2: + std::cout << "Available channels: Channel B, 1 bit quantisation" << std::endl; + break; + case 3: + std::cout << "Available channels: Channel A, 2 bit quantisation" << std::endl; + break; + case 4: + std::cout << "Available channels: Channel B, 2 bit quantisation" << std::endl; + break; + default: + std::cout << "Unknown channel selection ID " << static_cast(d_channel_selector) << std::endl; + return -1; + } + + //check if the selected channel in config file match the file encoding + if (d_channel_selector_config == 2 and d_channel_selector != 0) + { + std::cout << "Labsat source channel config inconsistency: channel 2 is selected but the file has only one channel" << std::endl; + return -1; + } + + //todo: Add support for dual channel files + if (d_channel_selector == 0) + { + std::cout << "ERROR: Labsat file contains more than one channel and it is not currently supported by Labsat signal source." << std::endl; + return -1; + } + byte_counter++; + uint8_t quantization = static_cast(memblock[byte_counter]); + switch(quantization) + { + case 1: + std::cout << "1 bit per sample" << std::endl; + break; + case 2: + std::cout << "2 bit per sample" << std::endl; + break; + default: + std::cout << "Unknown quantization ID " << static_cast(quantization) << std::endl; + } + byte_counter++; + uint8_t channel_a_constellation = static_cast(memblock[byte_counter]); + switch(channel_a_constellation) + { + case 0: + std::cout << "Labsat Channel A is GPS" << std::endl; + break; + case 1: + std::cout << "Labsat Channel A is GLONASS" << std::endl; + break; + case 2: + std::cout << "Labsat Channel A is BDS" << std::endl; + break; + default: + std::cout << "Unknown channel A constellation ID " << static_cast(channel_a_constellation) << std::endl; + } + byte_counter++; + uint8_t channel_b_constellation = static_cast(memblock[byte_counter]); + switch(channel_b_constellation) + { + case 0: + std::cout << "Labsat Channel B is GPS" << std::endl; + break; + case 1: + std::cout << "Labsat Channel B is GLONASS" << std::endl; + break; + case 2: + std::cout << "Labsat Channel B is BDS" << std::endl; + break; + default: + std::cout << "Unknown channel B constellation ID " << static_cast(channel_b_constellation) << std::endl; + } + + //end of header + d_header_parsed = true; + //seek file to the first signal sample + binary_input_file->clear(); + binary_input_file->seekg(header_bytes, binary_input_file->beg); + return 0; + } + else + { + std::cout << "Labsat file header error: section 2 is not available." << std::endl; + return -1; + } } - byte_counter++; - d_bits_per_sample=(uint8_t)memblock[byte_counter]; - switch(d_bits_per_sample) + else { - case 2: - std::cout<<"Labsat is using 2 bits per sample"<clear(); - binary_input_file->seekg(header_bytes, binary_input_file->beg); - return 0; - }else{ - std::cout<<"Labsat file header error: section 2 is not available."<0) - { - int16_t memblock[n_int16_to_read]; - binary_input_file->read((char*)memblock,n_int16_to_read*2); - n_int16_to_read=binary_input_file->gcount()/2; //from bytes to int16 - if (n_int16_to_read>0) + int n_int16_to_read = noutput_items / 8; + if (n_int16_to_read > 0) { - int output_pointer=0; - for (int i=0;iread(reinterpret_cast(memblock), n_int16_to_read * 2); + n_int16_to_read = binary_input_file->gcount() / 2; //from bytes to int16 + if (n_int16_to_read > 0) + { + int output_pointer = 0; + for (int i = 0; i < n_int16_to_read; i++) + { + decode_samples_one_channel(memblock[i], &out[output_pointer], d_bits_per_sample); + output_pointer += 8; + } + return output_pointer; + } + else + { + //trigger the read of the next file in the sequence + std::cout << "End of current file, reading the next Labsat file in sequence: " << generate_filename() << std::endl; - d_current_file_number++; - binary_input_file->close(); - binary_input_file->open(generate_filename().c_str(), std::ios::in|std::ios::binary); - if (binary_input_file->is_open()) - { - std::cout<<"Labsat file source is reading samples from "<close(); + binary_input_file->open(generate_filename().c_str(), std::ios::in|std::ios::binary); + if (binary_input_file->is_open()) + { + std::cout << "Labsat file source is reading samples from " << generate_filename() << std::endl; + } + else + { + std::cout << "Last file reached, LabSat source stop" << std::endl; + return -1; + } + } } - }else{ - return 0; - } - }; - break; - } + else + { + return 0; + } + }; + break; + } case 4: - { - switch(d_channel_selector) { + switch(d_channel_selector) + { case 0: // dual channel break; default: //single channel 4 bits per complex sample (2 bit I + 2 bit Q, 4 samples per int16) - int n_int16_to_read=noutput_items/4; - if (n_int16_to_read>0) - { - int16_t memblock[n_int16_to_read]; - binary_input_file->read((char*)memblock,n_int16_to_read*2); - n_int16_to_read=binary_input_file->gcount()/2; //from bytes to int16 - if (n_int16_to_read>0) + int n_int16_to_read = noutput_items / 4; + if (n_int16_to_read > 0) { - int output_pointer=0; - for (int i=0;iread(reinterpret_cast(memblock), n_int16_to_read * 2); + n_int16_to_read = binary_input_file->gcount() / 2; //from bytes to int16 + if (n_int16_to_read > 0) + { + int output_pointer = 0; + for (int i = 0; i < n_int16_to_read; i++) + { + decode_samples_one_channel(memblock[i], &out[output_pointer], d_bits_per_sample); + output_pointer += 4; + } + return output_pointer; + } + else + { + //trigger the read of the next file in the sequence + std::cout << "End of current file, reading the next Labsat file in sequence: " << generate_filename() << std::endl; - d_current_file_number++; - binary_input_file->close(); - binary_input_file->open(generate_filename().c_str(), std::ios::in|std::ios::binary); - if (binary_input_file->is_open()) - { - std::cout<<"Labsat file source is reading samples from "<close(); + binary_input_file->open(generate_filename().c_str(), std::ios::in|std::ios::binary); + if (binary_input_file->is_open()) + { + std::cout << "Labsat file source is reading samples from " << generate_filename() << std::endl; + } + else + { + std::cout << "Last file reached, LabSat source stop" << std::endl; + return -1; + } + } } - }else{ - return 0; - } + else + { + return 0; + } + } + break; } - break; - } default: - { - return -1; + { + return -1; + } } } - } - std::cout<<"Warning!!"< Date: Tue, 23 Jan 2018 20:09:39 +0100 Subject: [PATCH 63/96] Apply coding style --- .../signal_source/adapters/labsat_signal_source.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/algorithms/signal_source/adapters/labsat_signal_source.cc b/src/algorithms/signal_source/adapters/labsat_signal_source.cc index ead38e585..d71922955 100644 --- a/src/algorithms/signal_source/adapters/labsat_signal_source.cc +++ b/src/algorithms/signal_source/adapters/labsat_signal_source.cc @@ -61,10 +61,10 @@ LabsatSignalSource::LabsatSignalSource(ConfigurationInterface* configuration, labsat23_source_ = labsat23_make_source(filename_.c_str(),channel_selector); DLOG(INFO) << "Item size " << item_size_; DLOG(INFO) << "labsat23_source_(" << labsat23_source_->unique_id() << ")"; - }else + } + else { - LOG(WARNING) << item_type_ - << " unrecognized item type for LabSat source"; + LOG(WARNING) << item_type_ << " unrecognized item type for LabSat source"; item_size_ = sizeof(short); } if (dump_) From f6f14f246b30a893e192056582ad93d25455fb20 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 23 Jan 2018 21:23:02 +0100 Subject: [PATCH 64/96] Remove repeated and unrequired includes --- .../signal_source/adapters/labsat_signal_source.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/algorithms/signal_source/adapters/labsat_signal_source.cc b/src/algorithms/signal_source/adapters/labsat_signal_source.cc index d71922955..ddd0805c2 100644 --- a/src/algorithms/signal_source/adapters/labsat_signal_source.cc +++ b/src/algorithms/signal_source/adapters/labsat_signal_source.cc @@ -29,9 +29,6 @@ */ #include "labsat_signal_source.h" -#include -#include -#include #include #include "labsat23_source.h" #include "configuration_interface.h" @@ -49,7 +46,7 @@ LabsatSignalSource::LabsatSignalSource(ConfigurationInterface* configuration, dump_ = configuration->property(role + ".dump", false); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); - int channel_selector=configuration->property(role + ".selected_channel", 1); + int channel_selector = configuration->property(role + ".selected_channel", 1); std::string default_filename = "./example_capture.LS3"; samples_ = configuration->property(role + ".samples", 0); From 9b7ce39c57b2242dc1a9b1bc28db768e19c043b2 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 23 Jan 2018 21:41:19 +0100 Subject: [PATCH 65/96] Fix wrong comments and add consistency in header guard name --- .../signal_source/adapters/gn3s_signal_source.h | 6 +++--- .../signal_source/adapters/labsat_signal_source.h | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/algorithms/signal_source/adapters/gn3s_signal_source.h b/src/algorithms/signal_source/adapters/gn3s_signal_source.h index af6ab2714..b8b61cbdb 100644 --- a/src/algorithms/signal_source/adapters/gn3s_signal_source.h +++ b/src/algorithms/signal_source/adapters/gn3s_signal_source.h @@ -29,8 +29,8 @@ */ -#ifndef GN3S_SIGNAL_SOURCE_H_ -#define GN3S_SIGNAL_SOURCE_H_ +#ifndef GNSS_SDR_GN3S_SIGNAL_SOURCE_H_ +#define GNSS_SDR_GN3S_SIGNAL_SOURCE_H_ #include #include @@ -90,4 +90,4 @@ private: boost::shared_ptr queue_; }; -#endif /*GN3S_SIGNAL_SOURCE_H_*/ +#endif /*GNSS_SDR_GN3S_SIGNAL_SOURCE_H_*/ diff --git a/src/algorithms/signal_source/adapters/labsat_signal_source.h b/src/algorithms/signal_source/adapters/labsat_signal_source.h index 6909acefc..43821e8e8 100644 --- a/src/algorithms/signal_source/adapters/labsat_signal_source.h +++ b/src/algorithms/signal_source/adapters/labsat_signal_source.h @@ -29,8 +29,8 @@ */ -#ifndef LABSAT_SIGNAL_SOURCE_H_ -#define LABSAT_SIGNAL_SOURCE_H_ +#ifndef GNSS_SDR_LABSAT_SIGNAL_SOURCE_H_ +#define GNSS_SDR_LABSAT_SIGNAL_SOURCE_H_ #include #include @@ -42,7 +42,7 @@ class ConfigurationInterface; /*! - * \brief This class reads samples from a GN3S USB dongle, a RF front-end signal sampler + * \brief This class reads samples stored by a LabSat 2 or LabSat 3 device */ class LabsatSignalSource: public GNSSBlockInterface { @@ -59,7 +59,7 @@ public: } /*! - * \brief Returns "LabsatSignalSource". + * \brief Returns "Labsat_Signal_Source". */ inline std::string implementation() override { @@ -91,4 +91,4 @@ private: boost::shared_ptr queue_; }; -#endif /*LABSAT_SIGNAL_SOURCE_H_*/ +#endif /*GNSS_SDR_LABSAT_SIGNAL_SOURCE_H_*/ From 80edc4313f3d4a8ea3ef9c91b8a155772029fb53 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 23 Jan 2018 21:48:42 +0100 Subject: [PATCH 66/96] Change header guard name for consistency --- .../signal_source/gnuradio_blocks/labsat23_source.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.h b/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.h index 66e6135a1..ffc1b440b 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.h +++ b/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.h @@ -28,8 +28,8 @@ * ------------------------------------------------------------------------- */ -#ifndef LABSAT23_SOURCE_H -#define LABSAT23_SOURCE_H +#ifndef GNSS_SDR_LABSAT23_SOURCE_H +#define GNSS_SDR_LABSAT23_SOURCE_H #include #include From 8386289984edc40eb9ce376f21a045704e41d2c0 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 23 Jan 2018 22:52:15 +0100 Subject: [PATCH 67/96] Initialize all members in the constructor --- src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc b/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc index d5bfea224..fe9a9c4f7 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc @@ -65,6 +65,8 @@ labsat23_source::labsat23_source(const char *signal_file_basename, int channel_s d_bits_per_sample = 0; d_current_file_number = 0; d_labsat_version = 0; + d_ref_clock = 0; + d_channel_selector = 0; d_signal_file_basename = std::string(signal_file_basename); std::string signal_file; From 00a0b2ae2dc4039733b42eed1bdbb7af1d1b77b3 Mon Sep 17 00:00:00 2001 From: Gastd Date: Tue, 23 Jan 2018 20:23:28 -0200 Subject: [PATCH 68/96] Update values --- conf/gnss-sdr_GLONASS_L1_CA_ibyte_coh_trk.conf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/conf/gnss-sdr_GLONASS_L1_CA_ibyte_coh_trk.conf b/conf/gnss-sdr_GLONASS_L1_CA_ibyte_coh_trk.conf index ad49d03e0..7e9a9d279 100644 --- a/conf/gnss-sdr_GLONASS_L1_CA_ibyte_coh_trk.conf +++ b/conf/gnss-sdr_GLONASS_L1_CA_ibyte_coh_trk.conf @@ -26,10 +26,10 @@ Resampler.item_type=gr_complex ;######### CHANNELS GLOBAL CONFIG ############ Channel.signal=1G -Channels.in_acquisition=1 +Channels.in_acquisition=2 Channels_1G.count=8 -Channel0.satellite=24 ; k= +Channel0.satellite=24 ; k=2 Channel1.satellite=1 ; k=1 Channel2.satellite=2 ; k=-4 Channel3.satellite=20 ; k=-5 @@ -53,9 +53,9 @@ Tracking_1G.implementation=GLONASS_L1_CA_DLL_PLL_C_Aid_Tracking Tracking_1G.item_type=gr_complex Tracking_1G.if=0 Tracking_1G.early_late_space_chips=0.5 -Tracking_1G.pll_bw_hz=25.0; +Tracking_1G.pll_bw_hz=40.0; Tracking_1G.dll_bw_hz=3.0; -Tracking_1G.pll_bw_narrow_hz = 20.0; +Tracking_1G.pll_bw_narrow_hz = 25.0; Tracking_1G.dll_bw_narrow_hz = 2.0; Tracking_1G.extend_correlation_ms = 1; Tracking_1G.dump=true; From 0159fd8dfce350b1c05177da71e6eff63d434a5a Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jan 2018 01:00:40 +0100 Subject: [PATCH 69/96] Document Glonass l1 C/A signal identifier --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 06f884a00..554a9428a 100644 --- a/README.md +++ b/README.md @@ -1046,12 +1046,14 @@ Each channel must be assigned to a GNSS signal, according to the following ident | **Signal** | **Identifier** | |:------------------|:---------------:| | GPS L1 C/A | 1C | +| Galileo E1b/c | 1B | +| Glonass L1 C/A | 1G | | GPS L2 L2C(M) | 2S | | GPS L5 | L5 | -| Galileo E1b/c | 1B | | Galileo E5a | 5X | + Example: Eight GPS L1 C/A channels. ~~~~~~ ;######### CHANNELS GLOBAL CONFIG ############ From c9790a65495b20eeeed623f4a5d763672813839d Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jan 2018 17:38:57 +0100 Subject: [PATCH 70/96] Fix typos --- .../glonass_l1_ca_pcps_acquisition_test.cc | 60 +++++++++---------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc index a49aa3952..0ed0d1a71 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc @@ -105,24 +105,24 @@ void GlonassL1CaPcpsAcquisitionTest::init() signal.copy(gnss_synchro.Signal, 2, 0); gnss_synchro.PRN = 1; config->set_property("GNSS-SDR.internal_fs_sps", "62314000"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "9540000"); - config->set_property("Acquisition.coherent_integration_time_ms", "1"); - config->set_property("Acquisition.dump", "true"); - config->set_property("Acquisition.dump_filename", "./acquisition.dat"); - config->set_property("Acquisition.implementation", "Glonass_L1_CA_PCPS_Acquisition"); - config->set_property("Acquisition.threshold", "0.001"); - config->set_property("Acquisition.doppler_max", "5000"); - config->set_property("Acquisition.doppler_step", "500"); - config->set_property("Acquisition.repeat_satellite", "false"); - config->set_property("Acquisition.pfa", "0.0"); + config->set_property("Acquisition_1G.item_type", "gr_complex"); + config->set_property("Acquisition_1G.if", "9540000"); + config->set_property("Acquisition_1G.coherent_integration_time_ms", "1"); + config->set_property("Acquisition_1G.dump", "true"); + config->set_property("Acquisition_1G.dump_filename", "./acquisition.dat"); + config->set_property("Acquisition_1G.implementation", "Glonass_L1_CA_PCPS_Acquisition"); + config->set_property("Acquisition_1G.threshold", "0.001"); + config->set_property("Acquisition_1G.doppler_max", "5000"); + config->set_property("Acquisition_1G.doppler_step", "500"); + config->set_property("Acquisition_1G.repeat_satellite", "false"); + //config->set_property("Acquisition_1G.pfa", "0.0"); } TEST_F(GlonassL1CaPcpsAcquisitionTest, Instantiate) { init(); - boost::shared_ptr acquisition = boost::make_shared(config.get(), "Acquisition", 1, 1); + boost::shared_ptr acquisition = boost::make_shared(config.get(), "Acquisition_1G", 1, 1); } @@ -136,7 +136,7 @@ TEST_F(GlonassL1CaPcpsAcquisitionTest, ConnectAndRun) top_block = gr::make_top_block("Acquisition test"); init(); - boost::shared_ptr acquisition = boost::make_shared(config.get(), "Acquisition", 1, 1); + boost::shared_ptr acquisition = boost::make_shared(config.get(), "Acquisition_1G", 1, 1); boost::shared_ptr msg_rx = GlonassL1CaPcpsAcquisitionTest_msg_rx_make(); ASSERT_NO_THROW( { @@ -146,15 +146,14 @@ TEST_F(GlonassL1CaPcpsAcquisitionTest, ConnectAndRun) 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." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; EXPECT_NO_THROW( { begin = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - begin; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -169,33 +168,37 @@ TEST_F(GlonassL1CaPcpsAcquisitionTest, ValidationOfResults) double expected_delay_samples = 31874; double expected_doppler_hz = -9500; init(); - std::shared_ptr acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + std::shared_ptr acquisition = std::make_shared(config.get(), "Acquisition_1G", 1, 1); boost::shared_ptr msg_rx = GlonassL1CaPcpsAcquisitionTest_msg_rx_make(); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_threshold(0.001); - }) << "Failure setting threshold." << std::endl; + acquisition->set_threshold(0.0001); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->set_doppler_max(10000); - }) << "Failure setting doppler_max." << std::endl; + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { acquisition->set_doppler_step(250); - }) << "Failure setting doppler_step." << std::endl; + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; + + acquisition->set_local_code(); + acquisition->set_state(1); // Ensure that acquisition starts at the first sample + acquisition->init(); ASSERT_NO_THROW( { std::string path = std::string(TEST_PATH); @@ -204,19 +207,14 @@ TEST_F(GlonassL1CaPcpsAcquisitionTest, ValidationOfResults) 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." << std::endl; - - - acquisition->set_state(1); // Ensure that acquisition starts at the first sample - acquisition->init(); + }) << "Failure connecting the blocks of acquisition test."; EXPECT_NO_THROW( { begin = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - begin; - }) << "Failure running the top_block." << std::endl; - + }) << "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; From 9ff66b3377ffdab886a2e024b31fc3990cb3906b Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jan 2018 18:06:03 +0100 Subject: [PATCH 71/96] Fix tests --- ...ss_l1_ca_pcps_acquisition_gsoc2017_test.cc | 24 +++++++++---------- .../glonass_l1_ca_pcps_acquisition_test.cc | 6 ++--- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc index abc2bedb3..ec77c5951 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc @@ -420,14 +420,14 @@ TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, ConnectAndRun) 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."<< std::endl; + }) << "Failure connecting the blocks of acquisition test."; EXPECT_NO_THROW( { begin = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - begin; - }) << "Failure running the top_block."<< std::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; @@ -446,28 +446,28 @@ TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, ValidationOfResults) ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel."<< std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro."<< std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { acquisition->set_doppler_max(10000); - }) << "Failure setting doppler_max."<< std::endl; + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { acquisition->set_doppler_step(500); - }) << "Failure setting doppler_step."<< std::endl; + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { acquisition->set_threshold(0.5); - }) << "Failure setting threshold."<< std::endl; + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting acquisition to the top_block."<< std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); @@ -478,7 +478,7 @@ TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, ValidationOfResults) signal_source.reset(new GenSignalSource(signal_generator, filter, "SignalSource", queue)); signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; // i = 0 --> satellite in acquisition is visible // i = 1 --> satellite in acquisition is not visible @@ -501,7 +501,7 @@ TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, ValidationOfResults) EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block."<< std::endl; + }) << "Failure running the top_block."; if (i == 0) { @@ -519,12 +519,12 @@ TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, ValidationOfResults) #ifdef OLD_BOOST ASSERT_NO_THROW( { ch_thread.timed_join(boost::posix_time::seconds(1)); - }) << "Failure while waiting the queue to stop" << std::endl; + }) << "Failure while waiting the queue to stop."; #endif #ifndef OLD_BOOST ASSERT_NO_THROW( { ch_thread.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(50)); - }) << "Failure while waiting the queue to stop" << std::endl; + }) << "Failure while waiting the queue to stop"; #endif } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc index 0ed0d1a71..592350300 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc @@ -166,7 +166,7 @@ TEST_F(GlonassL1CaPcpsAcquisitionTest, ValidationOfResults) top_block = gr::make_top_block("Acquisition test"); double expected_delay_samples = 31874; - double expected_doppler_hz = -9500; + double expected_doppler_hz = -8000; init(); std::shared_ptr acquisition = std::make_shared(config.get(), "Acquisition_1G", 1, 1); @@ -181,7 +181,7 @@ TEST_F(GlonassL1CaPcpsAcquisitionTest, ValidationOfResults) }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_threshold(0.0001); + acquisition->set_threshold(0.0005); }) << "Failure setting threshold."; ASSERT_NO_THROW( { @@ -189,7 +189,7 @@ TEST_F(GlonassL1CaPcpsAcquisitionTest, ValidationOfResults) }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(250); + acquisition->set_doppler_step(500); }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { From c62e7a683db0e7dac199689ef77a4f1402879037 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jan 2018 18:16:01 +0100 Subject: [PATCH 72/96] Fix warning of unused parameters --- src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc index 9fe1b4f6a..85290da73 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc @@ -522,9 +522,6 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite bool flag_write_RTCM_1019_output = false; bool flag_write_RTCM_1020_output = false; bool flag_write_RTCM_1045_output = false; - bool flag_write_RTCM_1077_output = false; - bool flag_write_RTCM_1087_output = false; - bool flag_write_RTCM_1097_output = false; bool flag_write_RTCM_MSM_output = false; bool flag_write_RINEX_obs_output = false; bool flag_write_RINEX_nav_output = false; @@ -634,7 +631,6 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite } if ((std::fabs(current_RX_time - last_RTCM_1087_output_time) * 1000.0 >= static_cast(d_rtcm_MT1087_rate_ms)) && (d_rtcm_MT1087_rate_ms != 0) ) { - flag_write_RTCM_1087_output = true; last_RTCM_1087_output_time = current_RX_time; } if ((std::fabs(current_RX_time - last_RTCM_1097_output_time) * 1000.0 >= static_cast(d_rtcm_MT1097_rate_ms)) && (d_rtcm_MT1097_rate_ms != 0) ) From 1cf8f93a52dd2ec6cab7f6bc0b50832590bca691 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jan 2018 18:19:15 +0100 Subject: [PATCH 73/96] Fix warning of unused variables --- src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc index 839df16dc..2478539a5 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc @@ -280,7 +280,6 @@ TEST(RtcmTest, MT1019) TEST(RtcmTest, MT1020) { auto rtcm = std::make_shared(); - bool expected_true = true; // Objects to populate the ephemeris and utc fields Glonass_Gnav_Ephemeris gnav_ephemeris = Glonass_Gnav_Ephemeris(); @@ -357,7 +356,7 @@ TEST(RtcmTest, MSMCell) auto rtcm = std::make_shared(); Gps_Ephemeris gps_eph = Gps_Ephemeris(); Galileo_Ephemeris gal_eph = Galileo_Ephemeris(); - Glonass_Gnav_Ephemeris glo_gnav_eph = Glonass_Gnav_Ephemeris(); + // Glonass_Gnav_Ephemeris glo_gnav_eph = Glonass_Gnav_Ephemeris(); std::map pseudoranges; Gnss_Synchro gnss_synchro; From 2685dd0dfa453ec2e2aa3b651cb8f82634fabb32 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jan 2018 18:21:45 +0100 Subject: [PATCH 74/96] Fix typo --- src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc index 2478539a5..4e60b7360 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc @@ -356,7 +356,7 @@ TEST(RtcmTest, MSMCell) auto rtcm = std::make_shared(); Gps_Ephemeris gps_eph = Gps_Ephemeris(); Galileo_Ephemeris gal_eph = Galileo_Ephemeris(); - // Glonass_Gnav_Ephemeris glo_gnav_eph = Glonass_Gnav_Ephemeris(); + Glonass_Gnav_Ephemeris glo_gnav_eph = Glonass_Gnav_Ephemeris(); std::map pseudoranges; Gnss_Synchro gnss_synchro; From 5296c5e81fa881f4e2802a55eae755db52109f54 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jan 2018 18:25:06 +0100 Subject: [PATCH 75/96] Fix warning --- .../unit-tests/signal-processing-blocks/pvt/rtcm_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc index 4e60b7360..9e367c85e 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc @@ -356,7 +356,7 @@ TEST(RtcmTest, MSMCell) auto rtcm = std::make_shared(); Gps_Ephemeris gps_eph = Gps_Ephemeris(); Galileo_Ephemeris gal_eph = Galileo_Ephemeris(); - Glonass_Gnav_Ephemeris glo_gnav_eph = Glonass_Gnav_Ephemeris(); + //Glonass_Gnav_Ephemeris glo_gnav_eph = Glonass_Gnav_Ephemeris(); std::map pseudoranges; Gnss_Synchro gnss_synchro; @@ -419,7 +419,7 @@ TEST(RtcmTest, MSMCell) gps_eph.i_satellite_PRN = gnss_synchro2.PRN; gal_eph.i_satellite_PRN = gnss_synchro.PRN; - glo_gnav_eph.i_satellite_PRN = gnss_synchro.PRN; + //glo_gnav_eph.i_satellite_PRN = gnss_synchro.PRN; std::string MSM1 = rtcm->print_MSM_1(gps_eph, {}, From 5c78778a93510dd40118fcb2771f97e5ab92b821 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jan 2018 18:32:11 +0100 Subject: [PATCH 76/96] Add header --- .../glonass_l1_ca_pcps_acquisition.cc | 52 ++++++++++++++++--- .../adapters/glonass_l1_ca_pcps_acquisition.h | 32 ++++++++++++ 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc index 5afc7e073..9bbc9475f 100644 --- a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc @@ -1,3 +1,36 @@ +/*! + * \file glonass_l1_ca_pcps_acquisition.cc + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for + * Glonass L1 C/A signals + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + #include "glonass_l1_ca_pcps_acquisition.h" #include #include @@ -7,10 +40,11 @@ using google::LogMessage; + GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : - role_(role), in_streams_(in_streams), out_streams_(out_streams) + role_(role), in_streams_(in_streams), out_streams_(out_streams) { configuration_ = configuration; std::string default_item_type = "gr_complex"; @@ -55,12 +89,14 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, blocking_, dump_filename_); DLOG(INFO) << "acquisition(" << acquisition_sc_->unique_id() << ")"; - }else{ - item_size_ = sizeof(gr_complex); - acquisition_cc_ = pcps_make_acquisition_cc(sampled_ms_, max_dwells_, - doppler_max_, if_, fs_in_, code_length_, code_length_, - bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, blocking_, dump_filename_); - DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id() << ")"; + } + else + { + item_size_ = sizeof(gr_complex); + acquisition_cc_ = pcps_make_acquisition_cc(sampled_ms_, max_dwells_, + doppler_max_, if_, fs_in_, code_length_, code_length_, + bit_transition_flag_, use_CFAR_algorithm_flag_, dump_, blocking_, dump_filename_); + DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id() << ")"; } stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); @@ -260,7 +296,7 @@ float GlonassL1CaPcpsAcquisition::calculate_threshold(float pfa) { frequency_bins++; } - */ + */ frequency_bins = (2*doppler_max_ + doppler_step_)/doppler_step_; diff --git a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h index 65f6b9874..f338a1504 100644 --- a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h @@ -1,3 +1,35 @@ +/*! + * \file glonass_l1_ca_pcps_acquisition.h + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for + * Glonass L1 C/A signals + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ #ifndef GNSS_SDR_GLONASS_L1_CA_PCPS_ACQUISITION_H_ #define GNSS_SDR_GLONASS_L1_CA_PCPS_ACQUISITION_H_ From d6044c0ece0548d65e9e4d04d899e2c0573311a5 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jan 2018 18:36:36 +0100 Subject: [PATCH 77/96] Fix indentation --- .../glonass_l1_ca_telemetry_decoder_cc.cc | 104 +++++++++--------- 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc index 8ba984873..22aa23538 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc @@ -150,39 +150,39 @@ void glonass_l1_ca_telemetry_decoder_cc::decode_string(double *frame_symbols,int chip_acc_counter += 1; if(chip_acc_counter == (GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_BIT)) - { - if (chip_acc > 0) - { - bi_binary_code.push_back('1'); - chip_acc_counter = 0; - chip_acc = 0; - } - else - { - bi_binary_code.push_back('0'); - chip_acc_counter = 0; - chip_acc = 0; - } - } + { + if (chip_acc > 0) + { + bi_binary_code.push_back('1'); + chip_acc_counter = 0; + chip_acc = 0; + } + else + { + bi_binary_code.push_back('0'); + chip_acc_counter = 0; + chip_acc = 0; + } + } } // Convert from bi-binary code to relative code for(int i = 0; i < (GLONASS_GNAV_STRING_BITS); i++) { if(bi_binary_code[2*i] == '1' && bi_binary_code[2*i + 1] == '0') - { - relative_code.push_back('1'); - } + { + relative_code.push_back('1'); + } else - { - relative_code.push_back('0'); - } + { + relative_code.push_back('0'); + } } // Convert from relative code to data bits data_bits.push_back('0'); for(int i = 1; i < (GLONASS_GNAV_STRING_BITS); i++) - { - data_bits.push_back(((relative_code[i-1]-'0') ^ (relative_code[i]-'0')) + '0'); - } + { + data_bits.push_back(((relative_code[i-1]-'0') ^ (relative_code[i]-'0')) + '0'); + } // 2. Call the GLONASS GNAV string decoder d_nav.string_decoder(data_bits); @@ -203,7 +203,6 @@ void glonass_l1_ca_telemetry_decoder_cc::decode_string(double *frame_symbols,int std::shared_ptr tmp_obj = std::make_shared(d_nav.get_ephemeris()); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); LOG(INFO) << "GLONASS GNAV Ephemeris have been received on channel" << d_channel << " from satellite " << d_satellite; - } if (d_nav.have_new_utc_model() == true) { @@ -250,20 +249,20 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib unsigned int required_symbols=GLONASS_GNAV_STRING_SYMBOLS; if (d_symbol_history.size()>required_symbols) - { - //******* preamble correlation ******** - for (int i = 0; i < d_symbols_per_preamble; i++) - { - if (d_symbol_history.at(i).Prompt_I < 0) // symbols clipping - { - corr_value -= d_preambles_symbols[i]; - } - else - { - corr_value += d_preambles_symbols[i]; - } - } - } + { + //******* preamble correlation ******** + for (int i = 0; i < d_symbols_per_preamble; i++) + { + if (d_symbol_history.at(i).Prompt_I < 0) // symbols clipping + { + corr_value -= d_preambles_symbols[i]; + } + else + { + corr_value += d_preambles_symbols[i]; + } + } + } //******* frame sync ****************** if (d_stat == 0) //no preamble information @@ -276,7 +275,6 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib // Enter into frame pre-detection status d_stat = 1; d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; // record the preamble sample stamp - } } else if (d_stat == 1) // posible preamble lock @@ -294,8 +292,8 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib d_preamble_index = d_sample_counter; //record the preamble sample stamp d_stat = 2; // send asynchronous message to tracking to inform of frame sync and extend correlation time - pmt::pmt_t value = pmt::from_double(static_cast(d_preamble_time_samples) / static_cast(d_symbol_history.at(0).fs) - 0.001); - this->message_port_pub(pmt::mp("preamble_timestamp_s"), value); + pmt::pmt_t value = pmt::from_double(static_cast(d_preamble_time_samples) / static_cast(d_symbol_history.at(0).fs) - 0.001); + this->message_port_pub(pmt::mp("preamble_timestamp_s"), value); } else { @@ -309,7 +307,7 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib } else if (d_stat == 2) { - // FIXME: The preamble index marks the first symbol of the string count. Here I just wait for another full string to be received before processing + // FIXME: The preamble index marks the first symbol of the string count. Here I just wait for another full string to be received before processing if (d_sample_counter == d_preamble_index + GLONASS_GNAV_STRING_SYMBOLS) { // NEW GLONASS string received @@ -398,14 +396,14 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib // MULTIPLEXED FILE RECORDING - Record results to file try { - double tmp_double; - unsigned long int tmp_ulong_int; - tmp_double = d_TOW_at_current_symbol; - d_dump_file.write((char*)&tmp_double, sizeof(double)); - tmp_ulong_int = current_symbol.Tracking_sample_counter; - d_dump_file.write((char*)&tmp_ulong_int, sizeof(unsigned long int)); - tmp_double = 0; - d_dump_file.write((char*)&tmp_double, sizeof(double)); + double tmp_double; + unsigned long int tmp_ulong_int; + tmp_double = d_TOW_at_current_symbol; + d_dump_file.write((char*)&tmp_double, sizeof(double)); + tmp_ulong_int = current_symbol.Tracking_sample_counter; + d_dump_file.write((char*)&tmp_ulong_int, sizeof(unsigned long int)); + tmp_double = 0; + d_dump_file.write((char*)&tmp_double, sizeof(double)); } catch (const std::ifstream::failure & e) { @@ -415,9 +413,9 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib // remove used symbols from history if (d_symbol_history.size()>required_symbols) - { - d_symbol_history.pop_front(); - } + { + d_symbol_history.pop_front(); + } //3. Make the output (copy the object contents to the GNURadio reserved memory) *out[0] = current_symbol; From 9b28aa9e6bda2205850deb39b941e3b91a28c8ee Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jan 2018 19:08:08 +0100 Subject: [PATCH 78/96] Fix test --- .../pvt/rinex_printer_test.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc index ceb2d8373..963ab0186 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc @@ -174,7 +174,7 @@ TEST(RinexPrinterTest, MixedObsHeaderGpsGlo) std::shared_ptr rp1; rp1 = std::make_shared(); - rp1->rinex_obs_header(rp1->obsFile, eph_gps, eph_glo, 0.0, "1C"); + rp1->rinex_obs_header(rp1->obsFile, eph_gps, eph_glo, 0.0, "1G"); rp1->obsFile.seekp(0); int systems_found = 0; @@ -200,7 +200,7 @@ TEST(RinexPrinterTest, MixedObsHeaderGpsGlo) } std::string expected_str("G 4 C1C L1C D1C S1C SYS / # / OBS TYPES "); - std::string expected_str2("R 8 C1C L1C D1C S1C SYS / # / OBS TYPES "); + std::string expected_str2("R 4 C1C L1C D1C S1C SYS / # / OBS TYPES "); EXPECT_EQ(0, expected_str.compare(line_aux)); EXPECT_EQ(0, expected_str2.compare(line_aux2)); if(remove(rp1->obsfilename.c_str()) != 0) LOG(INFO) << "Error deleting temporary file"; @@ -627,7 +627,7 @@ TEST(RinexPrinterTest, MixedObsLogGpsGlo) std::shared_ptr rp; rp = std::make_shared(); - rp->rinex_obs_header(rp->obsFile, eph_gps, eph_glo, 0.0, "1C"); + rp->rinex_obs_header(rp->obsFile, eph_gps, eph_glo, 0.0, "1G"); std::map gnss_pseudoranges_map; @@ -658,7 +658,7 @@ TEST(RinexPrinterTest, MixedObsLogGpsGlo) std::memcpy((void*)gs3.Signal, sig.c_str(), 3); std::memcpy((void*)gs4.Signal, sig.c_str(), 3); - sig = "1C"; + sig = "1G"; std::memcpy((void*)gs5.Signal, sig.c_str(), 3); std::memcpy((void*)gs6.Signal, sig.c_str(), 3); std::memcpy((void*)gs7.Signal, sig.c_str(), 3); @@ -718,7 +718,8 @@ TEST(RinexPrinterTest, MixedObsLogGpsGlo) } } } - std::string expected_str("R16 22000000.000 7 0.127 7 -20.000 7 42.000 22000000.000 6 8.292 6 1534.000 6 41.000"); + + std::string expected_str("R16 22000000.000 6 8.292 6 1534.000 6 41.000 22000000.000 7 0.127 7 -20.000 7 42.000"); EXPECT_EQ(0, expected_str.compare(line_aux)); if(remove(rp->obsfilename.c_str()) != 0) LOG(INFO) << "Error deleting temporary file"; From d33f5e1772781d903baeec076806b481ed6e2b4b Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jan 2018 19:22:32 +0100 Subject: [PATCH 79/96] Fix test --- src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc index 9e367c85e..fdc7084a4 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc @@ -462,7 +462,7 @@ TEST(RtcmTest, MSMCell) divergence_free, more_messages); std::string MSM1_bin_2 = rtcm->binary_data_to_bin(MSM1_2); - EXPECT_EQ(0, MSM1_bin_2.substr(size_header + size_msg_length + 169, Nsat * Nsig).compare("001010101100")); // check cell mask + EXPECT_EQ(0, MSM1_bin_2.substr(size_header + size_msg_length + 169, Nsat * Nsig).compare("001010001100")); // check cell mask Gnss_Synchro gnss_synchro7; gnss_synchro7.PRN = 10; From df4e93b59f3fd2dd20c68fba12a7f4b1414b0ed4 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jan 2018 19:23:45 +0100 Subject: [PATCH 80/96] Initialize all members in the constructor --- .../gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc index 3fd0e74cd..107334df5 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc @@ -219,6 +219,8 @@ glonass_l1_ca_dll_pll_c_aid_tracking_cc::glonass_l1_ca_dll_pll_c_aid_tracking_cc d_carrier_frequency_hz = 0.0; d_carrier_doppler_old_hz = 0.0; + d_glonass_freq_ch = 0; + //set_min_output_buffer((long int)300); } From 831bc2ae2d6c298851ac9e47a9aaf6cb6e4790aa Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jan 2018 19:25:03 +0100 Subject: [PATCH 81/96] Initialize all members in the constructor --- .../gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc index 9619167f4..7cf86026f 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc @@ -220,6 +220,7 @@ glonass_l1_ca_dll_pll_c_aid_tracking_sc::glonass_l1_ca_dll_pll_c_aid_tracking_sc d_carrier_frequency_hz = 0.0; d_carrier_doppler_old_hz = 0.0; + d_glonass_freq_ch = 0; //set_min_output_buffer((long int)300); } From e7ba7ef23deed1af0475d81d7a94dce7dc72bcd8 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jan 2018 21:27:15 +0100 Subject: [PATCH 82/96] Fix warning --- src/algorithms/PVT/libs/rinex_printer.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index 4a53b2525..1f39acac7 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -8307,7 +8307,7 @@ boost::posix_time::ptime Rinex_Printer::compute_UTC_time(const Glonass_Gnav_Ephe { double tod = 0.0; double glot2utc = 3*3600; - double obs_time_utc = 0.0, obs_time_glot = 0.0; + double obs_time_glot = 0.0; int i = 0; // Get observation time in nearly GLONASS time. Correction for leap seconds done at the end @@ -8347,7 +8347,7 @@ double Rinex_Printer::get_leap_second(const Glonass_Gnav_Ephemeris& eph, const d { double tod = 0.0; double glot2utc = 3*3600; - double obs_time_utc = 0.0, obs_time_glot = 0.0; + double obs_time_glot = 0.0; int i = 0; double leap_second = 0; From 6f3e43ec087686e89bf9685d95384516569a49e2 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 25 Jan 2018 15:07:13 +0100 Subject: [PATCH 83/96] Initialize all members in the cosntructor --- .../glonass_gnav_navigation_message.cc | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/core/system_parameters/glonass_gnav_navigation_message.cc b/src/core/system_parameters/glonass_gnav_navigation_message.cc index 102b57dfb..abc13409d 100644 --- a/src/core/system_parameters/glonass_gnav_navigation_message.cc +++ b/src/core/system_parameters/glonass_gnav_navigation_message.cc @@ -43,7 +43,7 @@ void Glonass_Gnav_Navigation_Message::reset() { //!< Satellite Identification - i_satellite_PRN = 0; + i_satellite_PRN = 0; i_alm_satellite_slot_number = 0; //!< SV Orbit Slot Number flag_update_slot_number = false; @@ -79,6 +79,7 @@ void Glonass_Gnav_Navigation_Message::reset() flag_CRC_test = false; d_frame_ID = 0; d_string_ID = 0; + i_channel_ID = 0; // Clock terms d_satClkCorr = 0.0; @@ -88,8 +89,7 @@ void Glonass_Gnav_Navigation_Message::reset() // Data update information d_previous_tb = 0.0; for(unsigned int i = 0; i < GLONASS_L1_CA_NBR_SATS; i++) - d_previous_Na[i] = 0.0; - + d_previous_Na[i] = 0.0; std::map satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus @@ -97,9 +97,9 @@ void Glonass_Gnav_Navigation_Message::reset() std::string _system ("GLONASS"); //TODO SHould number of channels be hardcoded? for(unsigned int i = 1; i < 14; i++) - { - satelliteBlock[i] = gnss_sat.what_block(_system, i); - } + { + satelliteBlock[i] = gnss_sat.what_block(_system, i); + } } @@ -129,7 +129,6 @@ bool Glonass_Gnav_Navigation_Message::CRC_test(std::bitset(bits[i]); } - //!< Compute C1 term sum_bits = 0; for(int i = 0; i < static_cast(GLONASS_GNAV_CRC_I_INDEX.size()); i++) @@ -330,7 +329,6 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) if(flag_CRC_test == false) return 0; - // Decode all 15 string messages d_string_ID = static_cast(read_navigation_unsigned(string_bits, STRING_ID)); switch (d_string_ID) { @@ -441,18 +439,16 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) // 3). Set TOW once the year has been defined, it helps with leap second determination if (flag_ephemeris_str_1 == true) - { - gnav_ephemeris.glot_to_gpst(gnav_ephemeris.d_t_k+10, gnav_utc_model.d_tau_c, gnav_utc_model.d_tau_gps, &gnav_ephemeris.d_WN, &gnav_ephemeris.d_TOW); - flag_TOW_set = true; - flag_TOW_new = true; - } + { + gnav_ephemeris.glot_to_gpst(gnav_ephemeris.d_t_k+10, gnav_utc_model.d_tau_c, gnav_utc_model.d_tau_gps, &gnav_ephemeris.d_WN, &gnav_ephemeris.d_TOW); + flag_TOW_set = true; + flag_TOW_new = true; + } // 4) Set time of day (tod) when ephemeris data is complety decoded gnav_ephemeris.d_tod = gnav_ephemeris.d_t_k + 2*d_string_ID; - } - break; case 6: @@ -678,11 +674,9 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) LOG(INFO) << "GLONASS GNAV: Invalid String ID of received. Received " << d_string_ID << ", but acceptable range is from 1-15"; - break; } // switch string ID ... - return d_string_ID; } @@ -755,7 +749,6 @@ bool Glonass_Gnav_Navigation_Message::have_new_almanac() //Check if we have a ne flag_almanac_str_7 = false; new_alm = true; } - } if ((flag_almanac_str_8 == true) and (flag_almanac_str_9 == true)) { From b6fcc4d21870fc72f48e2f7acaa9b22878d9cf09 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 25 Jan 2018 19:35:28 +0100 Subject: [PATCH 84/96] Remove warning of unused parameter and dead code, fix indentation --- src/algorithms/PVT/libs/rinex_printer.cc | 2129 +++++++++++----------- src/algorithms/PVT/libs/rinex_printer.h | 26 +- 2 files changed, 1060 insertions(+), 1095 deletions(-) diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index 1f39acac7..f48ba8ab5 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -465,52 +465,52 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Glonass_Gnav_Utc_M // -------- Line system time correction if (version == 3) - { - line.clear(); - line += std::string("GLUT"); - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 17); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); - line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); - line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); - line += std::string(10, ' '); - line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; + { + line.clear(); + line += std::string("GLUT"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 17); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; - // -------- Line system time correction 2 - line.clear(); - line += std::string("GLGP"); - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_gps, 16, 2), 17); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); - line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); - line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); - line += std::string(10, ' '); - line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; - } + // -------- Line system time correction 2 + line.clear(); + line += std::string("GLGP"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_gps, 16, 2), 17); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } if (version == 2) - { - // Set reference time and its clock corrections - boost::posix_time::ptime p_utc_ref_time = glonass_gnav_eph.glot_to_utc(glonass_gnav_eph.d_t_b, 0.0); - std::string timestring = boost::posix_time::to_iso_string(p_utc_ref_time); - std::string year (timestring, 0, 4); - std::string month (timestring, 4, 2); - std::string day (timestring, 6, 2); + { + // Set reference time and its clock corrections + boost::posix_time::ptime p_utc_ref_time = glonass_gnav_eph.glot_to_utc(glonass_gnav_eph.d_t_b, 0.0); + std::string timestring = boost::posix_time::to_iso_string(p_utc_ref_time); + std::string year (timestring, 0, 4); + std::string month (timestring, 4, 2); + std::string day (timestring, 6, 2); - line.clear(); - line += Rinex_Printer::rightJustify(year, 6); - line += Rinex_Printer::rightJustify(month, 6); - line += Rinex_Printer::rightJustify(day, 6); - line += std::string(3, ' '); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 19); - line += std::string(20, ' '); - line += Rinex_Printer::leftJustify("CORR TO SYSTEM TIME", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; - } + line.clear(); + line += Rinex_Printer::rightJustify(year, 6); + line += Rinex_Printer::rightJustify(month, 6); + line += Rinex_Printer::rightJustify(day, 6); + line += std::string(3, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 19); + line += std::string(20, ' '); + line += Rinex_Printer::leftJustify("CORR TO SYSTEM TIME", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } // -------- End of Header line.clear(); @@ -621,7 +621,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono Rinex_Printer::lengthCheck(line); out << line << std::endl; - // -------- Line 6 leap seconds // For leap second information, see http://www.endruntechnologies.com/leap.htm line.clear(); @@ -642,6 +641,7 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono out << line << std::endl; } + void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono& gps_iono, const Gps_CNAV_Utc_Model& gps_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) { if(glonass_gnav_almanac.i_satellite_freq_channel){} //Avoid compiler warning @@ -743,7 +743,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono& gps 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(); @@ -764,6 +763,7 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono& gps out << line << std::endl; } + void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) { if(glonass_gnav_almanac.i_satellite_freq_channel){} //Avoid compiler warning @@ -828,7 +828,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& gali Rinex_Printer::lengthCheck(line); out << line << std::endl; - // -------- Line system time correction line.clear(); line += std::string("GAUT"); @@ -874,6 +873,7 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& gali out << line << std::endl; } + void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac) { std::string line; @@ -921,7 +921,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono Rinex_Printer::lengthCheck(line); out << line << std::endl; - // -------- Line ionospheric info 1 line.clear(); line += std::string("GAL "); @@ -936,7 +935,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono Rinex_Printer::lengthCheck(line); out << line << std::endl; - // -------- Line system time correction line.clear(); line += std::string("GAUT"); @@ -961,7 +959,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono Rinex_Printer::lengthCheck(line); out << line << std::endl; - // -------- Line 6 leap seconds // For leap second information, see http://www.endruntechnologies.com/leap.htm line.clear(); @@ -982,6 +979,7 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono out << line << std::endl; } + void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono & iono, const Gps_CNAV_Utc_Model & utc_model) { std::string line; @@ -1097,6 +1095,7 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono & io out << line << std::endl; } + void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, const Gps_Utc_Model& utc_model) { std::string line; @@ -1120,7 +1119,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, co line += std::string("G: GPS"); line += std::string(14, ' '); // ... - } line += std::string("RINEX VERSION / TYPE"); @@ -1266,7 +1264,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, co Rinex_Printer::lengthCheck(line); out << line << std::endl; - // -------- End of Header line.clear(); line += std::string(60, ' '); @@ -1275,6 +1272,7 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, co out << line << std::endl; } + void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac) { std::string line; @@ -1322,7 +1320,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono Rinex_Printer::lengthCheck(line); out << line << std::endl; - // -------- Line ionospheric info 1 line.clear(); line += std::string("GAL "); @@ -1386,7 +1383,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono Rinex_Printer::lengthCheck(line); out << line << std::endl; - // -------- Line 6 leap seconds // For leap second information, see http://www.endruntechnologies.com/leap.htm line.clear(); @@ -1589,6 +1585,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Glonass_Gnav_Utc_ std::cout << "The RINEX Navigation file header has been updated with UTC info." << std::endl; } + void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac) { std::vector data; @@ -1684,6 +1681,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& gal std::cout << "The RINEX Navigation file header has been updated with UTC and IONO info." << std::endl; } + void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Utc_Model& utc_model, const Gps_Iono& iono) { std::vector data; @@ -2039,7 +2037,6 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Iono& gps_ion { data.push_back(line_str); } - } else { @@ -2253,7 +2250,6 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_CNAV_Iono& gp { data.push_back(line_str); } - } else { @@ -2274,11 +2270,12 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_CNAV_Iono& gp std::cout << "The RINEX Navigation file header has been updated with UTC and IONO info." << std::endl; } + void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) { if(glonass_gnav_almanac.i_satellite_freq_channel){} //Avoid compiler warning //Avoid compiler warning, there is not time system correction between Galileo and GLONASS - if(galileo_almanac.A_0G_10){} + if(galileo_almanac.A_0G_10){} std::vector data; std::string line_aux; @@ -2373,7 +2370,6 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& gal } - void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& eph_map) { std::string line; @@ -2382,7 +2378,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::mapsecond, gps_ephemeris_iter->second.d_Toc); std::string timestring = boost::posix_time::to_iso_string(p_utc_time); @@ -2490,7 +2486,6 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::mapsecond.glot_to_utc(glonass_gnav_ephemeris_iter->second.d_t_b, 0.0); std::string timestring = boost::posix_time::to_iso_string(p_utc_time); @@ -3111,23 +3084,23 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(seconds) < 10) - { - line += std::string(1, ' '); - line += std::string(seconds, 1, 1); - } - else - { - line += seconds; - } - line += std::string(1, '.'); - std::string decimal = std::string("0"); - if (timestring.size() > 16) - { - std::string decimal (timestring, 16, 1); - } - line += decimal; - line += std::string(1, ' '); + if(boost::lexical_cast(seconds) < 10) + { + line += std::string(1, ' '); + line += std::string(seconds, 1, 1); + } + else + { + line += seconds; + } + line += std::string(1, '.'); + std::string decimal = std::string("0"); + if (timestring.size() > 16) + { + std::string decimal (timestring, 16, 1); + } + line += decimal; + line += std::string(1, ' '); line += Rinex_Printer::doub2for(-glonass_gnav_ephemeris_iter->second.d_tau_c, 18, 2); line += std::string(1, ' '); line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_gamma_n, 18, 2); @@ -3164,7 +3137,6 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& galileo_eph_map) { version = 3; @@ -3262,12 +3232,14 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& glonass_gnav_eph_map) { Rinex_Printer::log_rinex_nav(out, gps_eph_map); Rinex_Printer::log_rinex_nav(out, glonass_gnav_eph_map); } + void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& galileo_eph_map, const std::map& glonass_gnav_eph_map) { version = 3; @@ -3277,7 +3249,6 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(0), 3); // Number of satellites in list - line += std::string(1, ' '); - line += satelliteSystem["GLONASS"]; - line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Slot Number - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Frequency Number - line += std::string(1, ' '); - line += std::string(60-line.size(), ' '); - line += Rinex_Printer::leftJustify("GLONASS SLOT / FRQ #", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; + // -------- GLONASS SLOT / FRQ # + // TODO Need to provide system with list of all satellites and update this accordingly + line.clear(); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 3); // Number of satellites in list + line += std::string(1, ' '); + line += satelliteSystem["GLONASS"]; + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Slot Number + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Frequency Number + line += std::string(1, ' '); + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("GLONASS SLOT / FRQ #", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; - // -------- GLONASS CODE/PHS/BIS - // No GLONASS Phase bias correction used to align code and phase observations. - line.clear(); - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GLONASS_G1_CA"]; - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GLONASS_G1_P"]; - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GLONASS_G2_CA"]; - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GLONASS_G2_P"]; - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); - line += std::string(60-line.size(), ' '); - line += Rinex_Printer::leftJustify("GLONASS COD/PHS/BIS", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; + // -------- GLONASS CODE/PHS/BIS + // No GLONASS Phase bias correction used to align code and phase observations. + line.clear(); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_P"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_P"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("GLONASS COD/PHS/BIS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; } // -------- end of header @@ -4070,96 +4041,95 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris // -------- SYS / OBS TYPES // one line per available system - line.clear(); - line += satelliteSystem["GPS"]; - line += std::string(2, ' '); - std::stringstream strm; - numberTypesObservations = 4; - strm << numberTypesObservations; - line += Rinex_Printer::rightJustify(strm.str(), 3); - // per type of observation - // GPS L1 PSEUDORANGE - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GPS_L2_L2CM"]; - // GPS L1 PHASE - line += std::string(1, ' '); - line += observationType["CARRIER_PHASE"]; - line += observationCode["GPS_L2_L2CM"]; - // GPS DOPPLER L1 - line += std::string(1, ' '); - line += observationType["DOPPLER"]; - line += observationCode["GPS_L2_L2CM"]; - // GPS L1 CA SIGNAL STRENGTH - line += std::string(1, ' '); - line += observationType["SIGNAL_STRENGTH"]; - line += observationCode["GPS_L2_L2CM"]; - line += std::string(60-line.size(), ' '); - line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; + line.clear(); + line += satelliteSystem["GPS"]; + line += std::string(2, ' '); + std::stringstream strm; + numberTypesObservations = 4; + strm << numberTypesObservations; + line += Rinex_Printer::rightJustify(strm.str(), 3); + // per type of observation + // GPS L1 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L1 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS DOPPLER L1 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L1 CA SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L2_L2CM"]; + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; - // Find GLONASS Signal in Mixed file - unsigned int number_of_observations_glo = 0; - std::string signal_("1G"); - std::size_t found_1G = glonass_bands.find(signal_); - if(found_1G != std::string::npos) - { - number_of_observations_glo = number_of_observations_glo + 4; - } - signal_ = "2G"; - std::size_t found_2G = glonass_bands.find(signal_); - if(found_2G != std::string::npos) - { - number_of_observations_glo = number_of_observations_glo + 4; - } - line.clear(); - line += satelliteSystem["GLONASS"]; - line += std::string(2, ' '); - line += Rinex_Printer::rightJustify(std::to_string(number_of_observations_glo), 3); - if(found_1G != std::string::npos) - { - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GLONASS_G1_CA"]; - line += std::string(1, ' '); - line += observationType["CARRIER_PHASE"]; - line += observationCode["GLONASS_G1_CA"]; - line += std::string(1, ' '); - line += observationType["DOPPLER"]; - line += observationCode["GLONASS_G1_CA"]; - line += std::string(1, ' '); - line += observationType["SIGNAL_STRENGTH"]; - line += observationCode["GLONASS_G1_CA"]; - } - if(found_2G != std::string::npos) - { - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GLONASS_G2_CA"]; - line += std::string(1, ' '); - line += observationType["CARRIER_PHASE"]; - line += observationCode["GLONASS_G2_CA"]; - line += std::string(1, ' '); - line += observationType["DOPPLER"]; - line += observationCode["GLONASS_G2_CA"]; - line += std::string(1, ' '); - line += observationType["SIGNAL_STRENGTH"]; - line += observationCode["GLONASS_G2_CA"]; - } - line += std::string(60-line.size(), ' '); - line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; + // Find GLONASS Signal in Mixed file + unsigned int number_of_observations_glo = 0; + std::string signal_("1G"); + std::size_t found_1G = glonass_bands.find(signal_); + if(found_1G != std::string::npos) + { + number_of_observations_glo = number_of_observations_glo + 4; + } + signal_ = "2G"; + std::size_t found_2G = glonass_bands.find(signal_); + if(found_2G != std::string::npos) + { + number_of_observations_glo = number_of_observations_glo + 4; + } + line.clear(); + line += satelliteSystem["GLONASS"]; + line += std::string(2, ' '); + line += Rinex_Printer::rightJustify(std::to_string(number_of_observations_glo), 3); + if(found_1G != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GLONASS_G1_CA"]; + } + if(found_2G != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GLONASS_G2_CA"]; + } + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; // -------- Signal Strength units (only version 3) line.clear(); - line += Rinex_Printer::leftJustify("DBHZ", 20); - line += std::string(40, ' '); - line += Rinex_Printer::leftJustify("SIGNAL STRENGTH UNIT", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; - + 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(); @@ -4185,48 +4155,47 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris out << line << std::endl; // -------- GLONASS SLOT / FRQ # - // TODO Need to provide system with list of all satellites and update this accordingly - line.clear(); - line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 3); // Number of satellites in list - line += std::string(1, ' '); - line += satelliteSystem["GLONASS"]; - line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Slot Number - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Frequency Number - line += std::string(1, ' '); - line += std::string(60-line.size(), ' '); - line += Rinex_Printer::leftJustify("GLONASS SLOT / FRQ #", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; - - // -------- GLONASS CODE/PHS/BIS - // No GLONASS Phase bias correction used to align code and phase observations. - line.clear(); - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GLONASS_G1_CA"]; - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GLONASS_G1_P"]; - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GLONASS_G2_CA"]; - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GLONASS_G2_P"]; - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); - line += std::string(60-line.size(), ' '); - line += Rinex_Printer::leftJustify("GLONASS COD/PHS/BIS", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; + // TODO Need to provide system with list of all satellites and update this accordingly + line.clear(); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 3); // Number of satellites in list + line += std::string(1, ' '); + line += satelliteSystem["GLONASS"]; + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Slot Number + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Frequency Number + line += std::string(1, ' '); + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("GLONASS SLOT / FRQ #", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + // -------- GLONASS CODE/PHS/BIS + // No GLONASS Phase bias correction used to align code and phase observations. + line.clear(); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_P"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_P"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("GLONASS COD/PHS/BIS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; // -------- end of header line.clear(); @@ -4236,6 +4205,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris out << line << std::endl; } + void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris& galileo_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double d_TOW_first_observation, const std::string galileo_bands, const std::string glonass_bands) { if(glonass_gnav_eph.d_m){} // avoid warning, not needed @@ -4811,6 +4781,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph out << line << std::endl; } + void Rinex_Printer::rinex_obs_header(std::fstream & out, const Gps_CNAV_Ephemeris & eph, const double d_TOW_first_observation) { std::string line; @@ -5698,7 +5669,6 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps number_of_observations_gal = number_of_observations_gal + 4; } - line += satelliteSystem["Galileo"]; line += std::string(2, ' '); line += Rinex_Printer::rightJustify(std::to_string(number_of_observations_gal), 3); @@ -5796,12 +5766,11 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps } - -void Rinex_Printer::update_obs_header(std::fstream& out, const Glonass_Gnav_Utc_Model& utc_model) +void Rinex_Printer::update_obs_header(std::fstream& out __attribute__((unused)), const Glonass_Gnav_Utc_Model& utc_model) { if(utc_model.d_N_4) { - + // do nothing } } @@ -6008,7 +5977,6 @@ void Rinex_Printer::update_obs_header(std::fstream& out, const Galileo_Utc_Model } - void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeris& eph, const double obs_time, const std::map& observables, const std::string glonass_band) { // RINEX observations timestamps are GPS timestamps. @@ -6092,7 +6060,6 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri Rinex_Printer::lengthCheck(line); out << line << std::endl; - for(observables_iter = observables.begin(); observables_iter != observables.end(); observables_iter++) @@ -6110,10 +6077,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); @@ -6124,10 +6091,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS L1 CA DOPPLER lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); @@ -6135,10 +6102,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); //GLONASS L1 SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); @@ -6210,10 +6177,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); @@ -6225,10 +6192,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS L1 CA DOPPLER @@ -6237,10 +6204,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); @@ -6313,261 +6280,260 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep line += std::string(1, '0'); } if (version == 3) - { - std::string year (timestring, 0, 4); - line += std::string(1, '>'); - line += std::string(1, ' '); - line += year; - line += std::string(1, ' '); - line += month; - line += std::string(1, ' '); - line += day; - line += std::string(1, ' '); - line += hour; - line += std::string(1, ' '); - line += minutes; + { + std::string year (timestring, 0, 4); + line += std::string(1, '>'); + line += std::string(1, ' '); + line += year; + line += std::string(1, ' '); + line += month; + line += std::string(1, ' '); + line += day; + line += std::string(1, ' '); + line += hour; + line += std::string(1, ' '); + line += minutes; - line += std::string(1, ' '); - double seconds = fmod(gps_t, 60); - // Add extra 0 if seconds are < 10 - if (seconds < 10) - { - line +=std::string(1, '0'); - } - line += Rinex_Printer::asString(seconds, 7); - line += std::string(2, ' '); - // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event - line += std::string(1, '0'); + line += std::string(1, ' '); + double seconds = fmod(gps_t, 60); + // Add extra 0 if seconds are < 10 + if (seconds < 10) + { + line +=std::string(1, '0'); + } + line += Rinex_Printer::asString(seconds, 7); + line += std::string(2, ' '); + // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event + line += std::string(1, '0'); + } - } - //Number of satellites observed in current epoch - //Get maps with observations - std::map observablesG1C; - std::map observablesR1C; - std::map observablesR2C; - std::map::const_iterator observables_iter; + //Number of satellites observed in current epoch + //Get maps with observations + std::map observablesG1C; + std::map observablesR1C; + std::map observablesR2C; + std::map::const_iterator observables_iter; - for(observables_iter = observables.begin(); - observables_iter != observables.end(); - observables_iter++) - { - std::string system_(&observables_iter->second.System, 1); - std::string sig_(observables_iter->second.Signal); - if((system_.compare("R") == 0) && (sig_.compare("1G") == 0)) - { - observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); - } - if((system_.compare("R") == 0) && (sig_.compare("2G") == 0)) - { - observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); - } - if((system_.compare("G") == 0) && (sig_.compare("1C") == 0)) - { - observablesG1C.insert(std::pair(observables_iter->first, observables_iter->second)); - } - } + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + std::string system_(&observables_iter->second.System, 1); + std::string sig_(observables_iter->second.Signal); + if((system_.compare("R") == 0) && (sig_.compare("1G") == 0)) + { + observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if((system_.compare("R") == 0) && (sig_.compare("2G") == 0)) + { + observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if((system_.compare("G") == 0) && (sig_.compare("1C") == 0)) + { + observablesG1C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } - std::multimap total_glo_map; - std::set available_glo_prns; - std::set::iterator it; - for(observables_iter = observablesR1C.begin(); - observables_iter != observablesR1C.end(); - observables_iter++) - { - unsigned int prn_ = observables_iter->second.PRN; - total_glo_map.insert(std::pair(prn_, observables_iter->second)); - it = available_glo_prns.find(prn_); - if(it == available_glo_prns.end()) - { - available_glo_prns.insert(prn_); - } - } + std::multimap total_glo_map; + std::set available_glo_prns; + std::set::iterator it; + for(observables_iter = observablesR1C.begin(); + observables_iter != observablesR1C.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); + it = available_glo_prns.find(prn_); + if(it == available_glo_prns.end()) + { + available_glo_prns.insert(prn_); + } + } - for(observables_iter = observablesR2C.begin(); - observables_iter != observablesR2C.end(); - observables_iter++) - { - unsigned int prn_ = observables_iter->second.PRN; - total_glo_map.insert(std::pair(prn_, observables_iter->second)); - it = available_glo_prns.find(prn_); - if(it == available_glo_prns.end()) - { - available_glo_prns.insert(prn_); - } - } + for(observables_iter = observablesR2C.begin(); + observables_iter != observablesR2C.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); + it = available_glo_prns.find(prn_); + if(it == available_glo_prns.end()) + { + available_glo_prns.insert(prn_); + } + } - int numGloSatellitesObserved = available_glo_prns.size(); - int numGpsSatellitesObserved = observablesG1C.size(); - int numSatellitesObserved = numGloSatellitesObserved + numGpsSatellitesObserved; - line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); - if(version == 2) - { - // Add list of GPS satellites - for(observables_iter = observablesG1C.begin(); - observables_iter != observablesG1C.end(); - observables_iter++) - { - line += satelliteSystem["GPS"]; - if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); - line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); - } - // Add list of GLONASS L1 satellites - for(observables_iter = observablesR1C.begin(); - observables_iter != observablesR1C.end(); - observables_iter++) - { - line += satelliteSystem["GLONASS"]; - if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); - line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); - } - // Add list of GLONASS L2 satellites - for(observables_iter = observablesR2C.begin(); - observables_iter != observablesR2C.end(); - observables_iter++) - { - line += satelliteSystem["GLONASS"]; - if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); - line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); - } - } - line += std::string(80 - line.size(), ' '); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; + int numGloSatellitesObserved = available_glo_prns.size(); + int numGpsSatellitesObserved = observablesG1C.size(); + int numSatellitesObserved = numGloSatellitesObserved + numGpsSatellitesObserved; + line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); + if(version == 2) + { + // Add list of GPS satellites + for(observables_iter = observablesG1C.begin(); + observables_iter != observablesG1C.end(); + observables_iter++) + { + line += satelliteSystem["GPS"]; + if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); + line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + } + // Add list of GLONASS L1 satellites + for(observables_iter = observablesR1C.begin(); + observables_iter != observablesR1C.end(); + observables_iter++) + { + line += satelliteSystem["GLONASS"]; + if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); + line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + } + // Add list of GLONASS L2 satellites + for(observables_iter = observablesR2C.begin(); + observables_iter != observablesR2C.end(); + observables_iter++) + { + line += satelliteSystem["GLONASS"]; + if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); + line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + } + } + line += std::string(80 - line.size(), ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; - // -------- OBSERVATION record - std::string s; - std::string lineObs; - for(observables_iter = observablesG1C.begin(); - observables_iter != observablesG1C.end(); - observables_iter++) - { - lineObs.clear(); + // -------- OBSERVATION record + std::string s; + std::string lineObs; + for(observables_iter = observablesG1C.begin(); + observables_iter != observablesG1C.end(); + observables_iter++) + { + lineObs.clear(); - s.assign(1, observables_iter->second.System); - if(version == 3) - { - // Specify system only if in version 3 - if(s.compare("G") == 0) lineObs += satelliteSystem["GPS"]; - if(s.compare("R") == 0) lineObs += satelliteSystem["GLONASS"]; // should not happen - if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); - } + s.assign(1, observables_iter->second.System); + if(version == 3) + { + // Specify system only if in version 3 + if(s.compare("G") == 0) lineObs += satelliteSystem["GPS"]; + if(s.compare("R") == 0) lineObs += satelliteSystem["GLONASS"]; // should not happen + if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + } - // Pseudorange Measurements - lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); + // Pseudorange Measurements + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); - //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //Loss of lock indicator (LLI) + int lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } - // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + // Signal Strength Indicator (SSI) + int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - // PHASE - lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads/GPS_TWO_PI, 3), 14); - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + // PHASE + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads/GPS_TWO_PI, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - // DOPPLER - lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + // DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - // SIGNAL STRENGTH - lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); + // SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); - if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); - out << lineObs << std::endl; - } + if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } - std::pair ::iterator, std::multimap::iterator> ret; - for(it = available_glo_prns.begin(); - it != available_glo_prns.end(); - it++) - { - lineObs.clear(); - if(version == 3) - { - lineObs += satelliteSystem["GLONASS"]; - if (static_cast(*it) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(*it)); - } - ret = total_glo_map.equal_range(*it); - for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) - { - /// \todo Need to account for pseudorange correction for glonass - double leap_seconds = Rinex_Printer::get_leap_second(glonass_gnav_eph, gps_obs_time); - lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); + std::pair ::iterator, std::multimap::iterator> ret; + for(it = available_glo_prns.begin(); + it != available_glo_prns.end(); + it++) + { + lineObs.clear(); + if(version == 3) + { + lineObs += satelliteSystem["GLONASS"]; + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); + } + ret = total_glo_map.equal_range(*it); + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + { + /// \todo Need to account for pseudorange correction for glonass + double leap_seconds = Rinex_Printer::get_leap_second(glonass_gnav_eph, gps_obs_time); + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); - //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //Loss of lock indicator (LLI) + int lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } - // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + // Signal Strength Indicator (SSI) + int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - // GLONASS CARRIER PHASE - lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GLONASS_TWO_PI), 3), 14); - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + // GLONASS CARRIER PHASE + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GLONASS_TWO_PI), 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - // GLONASS DOPPLER - lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + // GLONASS DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - // GLONASS SIGNAL STRENGTH - lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); - } - - if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); - out << lineObs << std::endl; - } + // GLONASS SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); + } + if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } } @@ -6589,228 +6555,226 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g 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, '>'); + line += std::string(1, ' '); + line += year; + line += std::string(1, ' '); + line += month; + line += std::string(1, ' '); + line += day; + line += std::string(1, ' '); + line += hour; + line += std::string(1, ' '); + line += minutes; - line += std::string(1, ' '); - double seconds = fmod(gps_t, 60); - // Add extra 0 if seconds are < 10 - if (seconds < 10) - { - line +=std::string(1, '0'); - } - line += Rinex_Printer::asString(seconds, 7); - line += std::string(2, ' '); - // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event - line += std::string(1, '0'); + line += std::string(1, ' '); + double seconds = fmod(gps_t, 60); + // Add extra 0 if seconds are < 10 + if (seconds < 10) + { + line +=std::string(1, '0'); + } + line += Rinex_Printer::asString(seconds, 7); + line += std::string(2, ' '); + // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event + line += std::string(1, '0'); + //Number of satellites observed in current epoch + //Get maps with observations + std::map observablesG2S; + std::map observablesR1C; + std::map observablesR2C; + std::map::const_iterator observables_iter; - //Number of satellites observed in current epoch - //Get maps with observations - std::map observablesG2S; - std::map observablesR1C; - std::map observablesR2C; - std::map::const_iterator observables_iter; + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + std::string system_(&observables_iter->second.System, 1); + std::string sig_(observables_iter->second.Signal); + if((system_.compare("R") == 0) && (sig_.compare("1G") == 0)) + { + observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if((system_.compare("R") == 0) && (sig_.compare("2G") == 0)) + { + observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if((system_.compare("G") == 0) && (sig_.compare("2S") == 0)) + { + observablesG2S.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } - for(observables_iter = observables.begin(); - observables_iter != observables.end(); - observables_iter++) - { - std::string system_(&observables_iter->second.System, 1); - std::string sig_(observables_iter->second.Signal); - if((system_.compare("R") == 0) && (sig_.compare("1G") == 0)) - { - observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); - } - if((system_.compare("R") == 0) && (sig_.compare("2G") == 0)) - { - observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); - } - if((system_.compare("G") == 0) && (sig_.compare("2S") == 0)) - { - observablesG2S.insert(std::pair(observables_iter->first, observables_iter->second)); - } - } + std::multimap total_glo_map; + std::set available_glo_prns; + std::set::iterator it; + for(observables_iter = observablesR1C.begin(); + observables_iter != observablesR1C.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); + it = available_glo_prns.find(prn_); + if(it == available_glo_prns.end()) + { + available_glo_prns.insert(prn_); + } + } - std::multimap total_glo_map; - std::set available_glo_prns; - std::set::iterator it; - for(observables_iter = observablesR1C.begin(); - observables_iter != observablesR1C.end(); - observables_iter++) - { - unsigned int prn_ = observables_iter->second.PRN; - total_glo_map.insert(std::pair(prn_, observables_iter->second)); - it = available_glo_prns.find(prn_); - if(it == available_glo_prns.end()) - { - available_glo_prns.insert(prn_); - } - } + for(observables_iter = observablesR2C.begin(); + observables_iter != observablesR2C.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); + it = available_glo_prns.find(prn_); + if(it == available_glo_prns.end()) + { + available_glo_prns.insert(prn_); + } + } - for(observables_iter = observablesR2C.begin(); - observables_iter != observablesR2C.end(); - observables_iter++) - { - unsigned int prn_ = observables_iter->second.PRN; - total_glo_map.insert(std::pair(prn_, observables_iter->second)); - it = available_glo_prns.find(prn_); - if(it == available_glo_prns.end()) - { - available_glo_prns.insert(prn_); - } - } + int numGloSatellitesObserved = available_glo_prns.size(); + int numGpsSatellitesObserved = observablesG2S.size(); + int numSatellitesObserved = numGloSatellitesObserved + numGpsSatellitesObserved; + line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); - int numGloSatellitesObserved = available_glo_prns.size(); - int numGpsSatellitesObserved = observablesG2S.size(); - int numSatellitesObserved = numGloSatellitesObserved + numGpsSatellitesObserved; - line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); + line += std::string(80 - line.size(), ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; - line += std::string(80 - line.size(), ' '); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; + // -------- OBSERVATION record + std::string s; + std::string lineObs; + for(observables_iter = observablesG2S.begin(); + observables_iter != observablesG2S.end(); + observables_iter++) + { + lineObs.clear(); - // -------- OBSERVATION record - std::string s; - std::string lineObs; - for(observables_iter = observablesG2S.begin(); - observables_iter != observablesG2S.end(); - observables_iter++) - { - lineObs.clear(); + s.assign(1, observables_iter->second.System); + // Specify system only if in version 3 + if(s.compare("G") == 0) lineObs += satelliteSystem["GPS"]; + if(s.compare("R") == 0) lineObs += satelliteSystem["GLONASS"]; // should not happen + if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); - s.assign(1, observables_iter->second.System); - // Specify system only if in version 3 - if(s.compare("G") == 0) lineObs += satelliteSystem["GPS"]; - if(s.compare("R") == 0) lineObs += satelliteSystem["GLONASS"]; // should not happen - if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + // Pseudorange Measurements + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); + //Loss of lock indicator (LLI) + int lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } - // Pseudorange Measurements - lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); + // Signal Strength Indicator (SSI) + int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + // PHASE + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads/GPS_TWO_PI, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + // DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - // PHASE - lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads/GPS_TWO_PI, 3), 14); - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + // SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); - // DOPPLER - lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } - // SIGNAL STRENGTH - lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); + std::pair ::iterator, std::multimap::iterator> ret; + for(it = available_glo_prns.begin(); + it != available_glo_prns.end(); + it++) + { + lineObs.clear(); + lineObs += satelliteSystem["GLONASS"]; + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); - if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); - out << lineObs << std::endl; - } + ret = total_glo_map.equal_range(*it); + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + { + /// \todo Need to account for pseudorange correction for glonass + double leap_seconds = Rinex_Printer::get_leap_second(glonass_gnav_eph, gps_obs_time); + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); - std::pair ::iterator, std::multimap::iterator> ret; - for(it = available_glo_prns.begin(); - it != available_glo_prns.end(); - it++) - { - lineObs.clear(); - lineObs += satelliteSystem["GLONASS"]; - if (static_cast(*it) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(*it)); + //Loss of lock indicator (LLI) + int lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } - ret = total_glo_map.equal_range(*it); - for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) - { - /// \todo Need to account for pseudorange correction for glonass - double leap_seconds = Rinex_Printer::get_leap_second(glonass_gnav_eph, gps_obs_time); - lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); + // Signal Strength Indicator (SSI) + int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + // GLONASS CARRIER PHASE + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GLONASS_TWO_PI), 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + // GLONASS DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - // GLONASS CARRIER PHASE - lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GLONASS_TWO_PI), 3), 14); - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - - // GLONASS DOPPLER - lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - - // GLONASS SIGNAL STRENGTH - lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); - } - - if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); - out << lineObs << std::endl; - } + // GLONASS SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); + } + if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } } + void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& galileo_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double galileo_obs_time, const std::map& observables) { if(glonass_gnav_eph.d_m){} // avoid warning, not needed @@ -6941,10 +6905,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); @@ -6956,10 +6920,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // DOPPLER @@ -6968,10 +6932,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // SIGNAL STRENGTH @@ -7001,10 +6965,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); @@ -7016,10 +6980,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS DOPPLER @@ -7028,10 +6992,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS SIGNAL STRENGTH @@ -7124,7 +7088,6 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c Rinex_Printer::lengthCheck(line); out << line << std::endl; - for(observables_iter = observables.cbegin(); observables_iter != observables.cend(); observables_iter++) @@ -7142,10 +7105,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); @@ -7156,10 +7119,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + // else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS L1 CA DOPPLER lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); @@ -7167,10 +7130,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); //GPS L1 SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); @@ -7198,9 +7161,9 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c double seconds = fmod(gps_t, 60); // Add extra 0 if seconds are < 10 if (seconds < 10) - { - line += std::string(1, '0'); - } + { + line += std::string(1, '0'); + } line += Rinex_Printer::asString(seconds, 7); line += std::string(2, ' '); // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event @@ -7217,7 +7180,6 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c } line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); - // Receiver clock offset (optional) //line += rightJustify(asString(clockOffset, 12), 15); @@ -7243,10 +7205,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); @@ -7258,10 +7220,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS L1 CA DOPPLER @@ -7270,10 +7232,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); @@ -7365,10 +7327,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream & out, const Gps_CNAV_Ephemeris & { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); @@ -7380,10 +7342,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream & out, const Gps_CNAV_Ephemeris & { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS L2 DOPPLER @@ -7392,10 +7354,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream & out, const Gps_CNAV_Ephemeris & { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); @@ -7557,10 +7519,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream & out, const Gps_Ephemeris & eph, { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + // else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); @@ -7572,10 +7534,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream & out, const Gps_Ephemeris & eph, { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS DOPPLER @@ -7584,10 +7546,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream & out, const Gps_Ephemeris & eph, { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS SIGNAL STRENGTH @@ -7677,97 +7639,97 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep std::set available_prns; std::set::iterator it; if(found_1B != std::string::npos) - { - for(observables_iter = observablesE1B.begin(); - observables_iter != observablesE1B.end(); - observables_iter++) - { - unsigned int prn_ = observables_iter->second.PRN; - total_map.insert(std::pair(prn_, observables_iter->second)); - it = available_prns.find(prn_); - if(it == available_prns.end()) - { - available_prns.insert(prn_); - } - } - } - if(found_E5a != std::string::npos) - { - for(observables_iter = observablesE5A.cbegin(); - observables_iter != observablesE5A.cend(); - observables_iter++) - { - unsigned int prn_ = observables_iter->second.PRN; - it = available_prns.find(prn_); - if(it == available_prns.end()) - { - available_prns.insert(prn_); - if(found_1B != std::string::npos) + { + for(observables_iter = observablesE1B.begin(); + observables_iter != observablesE1B.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + total_map.insert(std::pair(prn_, observables_iter->second)); + it = available_prns.find(prn_); + if(it == available_prns.end()) { - Gnss_Synchro gs = Gnss_Synchro(); - std::string sys = "E"; - gs.System = *sys.c_str(); - std::string sig = "1B"; - std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); - gs.PRN = prn_; - total_map.insert(std::pair(prn_, gs)); + available_prns.insert(prn_); } - } - total_map.insert(std::pair(prn_, observables_iter->second)); - } - } + } + } + if(found_E5a != std::string::npos) + { + for(observables_iter = observablesE5A.cbegin(); + observables_iter != observablesE5A.cend(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + it = available_prns.find(prn_); + if(it == available_prns.end()) + { + available_prns.insert(prn_); + if(found_1B != std::string::npos) + { + Gnss_Synchro gs = Gnss_Synchro(); + std::string sys = "E"; + gs.System = *sys.c_str(); + std::string sig = "1B"; + std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); + gs.PRN = prn_; + total_map.insert(std::pair(prn_, gs)); + } + } + total_map.insert(std::pair(prn_, observables_iter->second)); + } + } if(found_E5b != std::string::npos) - { - for(observables_iter = observablesE5B.cbegin(); - observables_iter != observablesE5B.cend(); - observables_iter++) - { - unsigned int prn_ = observables_iter->second.PRN; - it = available_prns.find(prn_); - if(it == available_prns.end()) - { - available_prns.insert(prn_); - if(found_1B != std::string::npos) - { - Gnss_Synchro gs = Gnss_Synchro(); - std::string sys = "E"; - gs.System = *sys.c_str(); - std::string sig = "1B"; - std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); - gs.PRN = prn_; - total_map.insert(std::pair(prn_, gs)); - } - if(found_E5a != std::string::npos) - { - Gnss_Synchro gs = Gnss_Synchro(); - std::string sys = "E"; - gs.System = *sys.c_str(); - std::string sig = "5X"; - std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); - gs.PRN = prn_; - total_map.insert(std::pair(prn_, gs)); - } - } - else - { - // if 5X is listed but empty - if(found_E5a != std::string::npos) - { - if( (total_map.count(prn_)) == 1) - { - Gnss_Synchro gs = Gnss_Synchro(); - std::string sys = "E"; - gs.System = *sys.c_str(); - std::string sig = "5X"; - std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); - gs.PRN = prn_; - total_map.insert(std::pair(prn_, gs)); - } - } - } - total_map.insert(std::pair(prn_, observables_iter->second)); - } - } + { + for(observables_iter = observablesE5B.cbegin(); + observables_iter != observablesE5B.cend(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + it = available_prns.find(prn_); + if(it == available_prns.end()) + { + available_prns.insert(prn_); + if(found_1B != std::string::npos) + { + Gnss_Synchro gs = Gnss_Synchro(); + std::string sys = "E"; + gs.System = *sys.c_str(); + std::string sig = "1B"; + std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); + gs.PRN = prn_; + total_map.insert(std::pair(prn_, gs)); + } + if(found_E5a != std::string::npos) + { + Gnss_Synchro gs = Gnss_Synchro(); + std::string sys = "E"; + gs.System = *sys.c_str(); + std::string sig = "5X"; + std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); + gs.PRN = prn_; + total_map.insert(std::pair(prn_, gs)); + } + } + else + { + // if 5X is listed but empty + if(found_E5a != std::string::npos) + { + if( (total_map.count(prn_)) == 1) + { + Gnss_Synchro gs = Gnss_Synchro(); + std::string sys = "E"; + gs.System = *sys.c_str(); + std::string sig = "5X"; + std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); + gs.PRN = prn_; + total_map.insert(std::pair(prn_, gs)); + } + } + } + total_map.insert(std::pair(prn_, observables_iter->second)); + } + } int numSatellitesObserved = available_prns.size(); line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); // Receiver clock offset (optional) @@ -7797,10 +7759,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); @@ -7812,10 +7774,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // Galileo DOPPLER @@ -7824,10 +7786,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // Galileo SIGNAL STRENGTH @@ -7989,10 +7951,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); @@ -8004,10 +7966,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // DOPPLER @@ -8016,10 +7978,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // SIGNAL STRENGTH @@ -8049,10 +8011,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); @@ -8064,10 +8026,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // Galileo DOPPLER @@ -8076,10 +8038,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep { lineObs += std::string(1, ' '); } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // Galileo SIGNAL STRENGTH @@ -8306,83 +8268,86 @@ boost::posix_time::ptime Rinex_Printer::compute_Galileo_time(const Galileo_Ephem boost::posix_time::ptime Rinex_Printer::compute_UTC_time(const Glonass_Gnav_Ephemeris& eph, const double obs_time) { double tod = 0.0; - double glot2utc = 3*3600; - double obs_time_glot = 0.0; - int i = 0; + double glot2utc = 3*3600; + double obs_time_glot = 0.0; + int i = 0; - // Get observation time in nearly GLONASS time. Correction for leap seconds done at the end - obs_time_glot = obs_time + glot2utc; + // Get observation time in nearly GLONASS time. Correction for leap seconds done at the end + obs_time_glot = obs_time + glot2utc; - // Get seconds of day in glonass time - tod = fmod (obs_time_glot, 86400); + // Get seconds of day in glonass time + tod = fmod (obs_time_glot, 86400); - // Form date and time duration types - boost::posix_time::time_duration t1(0, 0, tod); - boost::gregorian::date d1(eph.d_yr, 1, 1); - boost::gregorian::days d2(eph.d_N_T-1); - boost::posix_time::ptime glo_time(d1 + d2, t1); + // Form date and time duration types + boost::posix_time::time_duration t1(0, 0, tod); + boost::gregorian::date d1(eph.d_yr, 1, 1); + boost::gregorian::days d2(eph.d_N_T-1); + boost::posix_time::ptime glo_time(d1 + d2, t1); - // Convert to utc - boost::posix_time::time_duration t2(0, 0, glot2utc); - boost::posix_time::ptime utc_time = glo_time - t2; + // Convert to utc + boost::posix_time::time_duration t2(0, 0, glot2utc); + boost::posix_time::ptime utc_time = glo_time - t2; - // Adjust for leap second correction - for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) - { - boost::posix_time::time_duration t3(GLONASS_LEAP_SECONDS[i][3], GLONASS_LEAP_SECONDS[i][4], GLONASS_LEAP_SECONDS[i][5]); - boost::gregorian::date d3(GLONASS_LEAP_SECONDS[i][0], GLONASS_LEAP_SECONDS[i][1], GLONASS_LEAP_SECONDS[i][2]); - boost::posix_time::ptime ls_time(d3, t3); - if (utc_time >= ls_time) - { - // We subtract the leap second when going from gpst to utc - utc_time = utc_time - boost::posix_time::time_duration(0,0,fabs(GLONASS_LEAP_SECONDS[i][6])); - break; - } - } + // Adjust for leap second correction + for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) + { + boost::posix_time::time_duration t3(GLONASS_LEAP_SECONDS[i][3], GLONASS_LEAP_SECONDS[i][4], GLONASS_LEAP_SECONDS[i][5]); + boost::gregorian::date d3(GLONASS_LEAP_SECONDS[i][0], GLONASS_LEAP_SECONDS[i][1], GLONASS_LEAP_SECONDS[i][2]); + boost::posix_time::ptime ls_time(d3, t3); + if (utc_time >= ls_time) + { + // We subtract the leap second when going from gpst to utc + utc_time = utc_time - boost::posix_time::time_duration(0,0,fabs(GLONASS_LEAP_SECONDS[i][6])); + break; + } + } - return utc_time; + return utc_time; } + double Rinex_Printer::get_leap_second(const Glonass_Gnav_Ephemeris& eph, const double gps_obs_time) { double tod = 0.0; - double glot2utc = 3*3600; - double obs_time_glot = 0.0; - int i = 0; - double leap_second = 0; + double glot2utc = 3*3600; + double obs_time_glot = 0.0; + int i = 0; + double leap_second = 0; - // Get observation time in nearly GLONASS time. Correction for leap seconds done at the end - obs_time_glot = gps_obs_time + glot2utc; + // Get observation time in nearly GLONASS time. Correction for leap seconds done at the end + obs_time_glot = gps_obs_time + glot2utc; - // Get seconds of day in glonass time - tod = fmod (obs_time_glot, 86400); + // Get seconds of day in glonass time + tod = fmod (obs_time_glot, 86400); - // Form date and time duration types - boost::posix_time::time_duration t1(0, 0, tod); - boost::gregorian::date d1(eph.d_yr, 1, 1); - boost::gregorian::days d2(eph.d_N_T-1); - boost::posix_time::ptime glo_time(d1 + d2, t1); + // Form date and time duration types + boost::posix_time::time_duration t1(0, 0, tod); + boost::gregorian::date d1(eph.d_yr, 1, 1); + boost::gregorian::days d2(eph.d_N_T-1); + boost::posix_time::ptime glo_time(d1 + d2, t1); - // Convert to utc - boost::posix_time::time_duration t2(0, 0, glot2utc); - boost::posix_time::ptime utc_time = glo_time - t2; + // Convert to utc + boost::posix_time::time_duration t2(0, 0, glot2utc); + boost::posix_time::ptime utc_time = glo_time - t2; - // Adjust for leap second correction - for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) - { - boost::posix_time::time_duration t3(GLONASS_LEAP_SECONDS[i][3], GLONASS_LEAP_SECONDS[i][4], GLONASS_LEAP_SECONDS[i][5]); - boost::gregorian::date d3(GLONASS_LEAP_SECONDS[i][0], GLONASS_LEAP_SECONDS[i][1], GLONASS_LEAP_SECONDS[i][2]); - boost::posix_time::ptime ls_time(d3, t3); - if (utc_time >= ls_time) - { - // We subtract the leap second when going from gpst to utc - leap_second = fabs(GLONASS_LEAP_SECONDS[i][6]); - break; - } - } + // Adjust for leap second correction + for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) + { + boost::posix_time::time_duration t3(GLONASS_LEAP_SECONDS[i][3], GLONASS_LEAP_SECONDS[i][4], GLONASS_LEAP_SECONDS[i][5]); + boost::gregorian::date d3(GLONASS_LEAP_SECONDS[i][0], GLONASS_LEAP_SECONDS[i][1], GLONASS_LEAP_SECONDS[i][2]); + boost::posix_time::ptime ls_time(d3, t3); + if (utc_time >= ls_time) + { + // We subtract the leap second when going from gpst to utc + leap_second = fabs(GLONASS_LEAP_SECONDS[i][6]); + break; + } + } - return leap_second; + return leap_second; } + + /* enum RINEX_enumMarkerType { diff --git a/src/algorithms/PVT/libs/rinex_printer.h b/src/algorithms/PVT/libs/rinex_printer.h index ee90ef3a4..8f4580208 100644 --- a/src/algorithms/PVT/libs/rinex_printer.h +++ b/src/algorithms/PVT/libs/rinex_printer.h @@ -204,20 +204,20 @@ public: boost::posix_time::ptime compute_Galileo_time(const Galileo_Ephemeris & eph, const double obs_time); /*! - * \brief Computes the UTC Time and returns a boost::posix_time::ptime object - * \details Function used as a method to convert the observation time into UTC time which is used - * as the default time for RINEX files - * \param eph GLONASS GNAV Ephemeris object - * \param obs_time Observation time in GPS seconds of week - */ - boost::posix_time::ptime compute_UTC_time(const Glonass_Gnav_Ephemeris & eph, const double obs_time); + * \brief Computes the UTC Time and returns a boost::posix_time::ptime object + * \details Function used as a method to convert the observation time into UTC time which is used + * as the default time for RINEX files + * \param eph GLONASS GNAV Ephemeris object + * \param obs_time Observation time in GPS seconds of week + */ + boost::posix_time::ptime compute_UTC_time(const Glonass_Gnav_Ephemeris & eph, const double obs_time); - /*! - * \brief Computes number of leap seconds of GPS relative to UTC - * \param eph GLONASS GNAV Ephemeris object - * \param gps_obs_time Observation time in GPS seconds of week - */ - double get_leap_second(const Glonass_Gnav_Ephemeris& eph, const double gps_obs_time); + /*! + * \brief Computes number of leap seconds of GPS relative to UTC + * \param eph GLONASS GNAV Ephemeris object + * \param gps_obs_time Observation time in GPS seconds of week + */ + double get_leap_second(const Glonass_Gnav_Ephemeris& eph, const double gps_obs_time); /*! * \brief Writes data from the GPS L1 C/A navigation message into the RINEX file From f600f958643c1dac72f06ee1293daa9e07228b9c Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 25 Jan 2018 19:39:42 +0100 Subject: [PATCH 85/96] Remove unused variables --- src/algorithms/PVT/libs/rinex_printer.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index f48ba8ab5..26e101e85 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -6485,7 +6485,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) { /// \todo Need to account for pseudorange correction for glonass - double leap_seconds = Rinex_Printer::get_leap_second(glonass_gnav_eph, gps_obs_time); + //double leap_seconds = Rinex_Printer::get_leap_second(glonass_gnav_eph, gps_obs_time); lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) @@ -6723,7 +6723,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) { /// \todo Need to account for pseudorange correction for glonass - double leap_seconds = Rinex_Printer::get_leap_second(glonass_gnav_eph, gps_obs_time); + //double leap_seconds = Rinex_Printer::get_leap_second(glonass_gnav_eph, gps_obs_time); lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) From 30988b8e144db8ac91c716e381607c712da124ef Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 26 Jan 2018 12:40:58 +0100 Subject: [PATCH 86/96] Remove unrequired includes. Remove tabs. Fix indentation --- src/core/system_parameters/GLONASS_L1_CA.h | 1 + .../system_parameters/glonass_gnav_almanac.cc | 39 +- .../system_parameters/glonass_gnav_almanac.h | 7 +- .../glonass_gnav_ephemeris.cc | 185 +++--- .../glonass_gnav_ephemeris.h | 31 +- .../glonass_gnav_navigation_message.cc | 628 +++++++++--------- .../glonass_gnav_navigation_message.h | 39 +- 7 files changed, 459 insertions(+), 471 deletions(-) diff --git a/src/core/system_parameters/GLONASS_L1_CA.h b/src/core/system_parameters/GLONASS_L1_CA.h index 06f1112f3..af0bd0227 100644 --- a/src/core/system_parameters/GLONASS_L1_CA.h +++ b/src/core/system_parameters/GLONASS_L1_CA.h @@ -32,6 +32,7 @@ #ifndef GNSS_SDR_GLONASS_L1_CA_H_ #define GNSS_SDR_GLONASS_L1_CA_H_ +#include #include #include // std::pair #include "MATH_CONSTANTS.h" diff --git a/src/core/system_parameters/glonass_gnav_almanac.cc b/src/core/system_parameters/glonass_gnav_almanac.cc index 3b5ca7014..297a1cb59 100644 --- a/src/core/system_parameters/glonass_gnav_almanac.cc +++ b/src/core/system_parameters/glonass_gnav_almanac.cc @@ -29,30 +29,27 @@ * * ------------------------------------------------------------------------- */ + #include "glonass_gnav_almanac.h" -#include -#include "GLONASS_L1_CA.h" -#include "gnss_satellite.h" Glonass_Gnav_Almanac::Glonass_Gnav_Almanac() { - i_satellite_freq_channel = 0; - i_satellite_PRN = 0; - i_satellite_slot_number = 0; - - d_n_A = 0.0; - d_H_n_A = 0.0; - d_lambda_n_A = 0.0; - d_t_lambda_n_A = 0.0; - d_Delta_i_n_A = 0.0; - d_Delta_T_n_A = 0.0; - d_Delta_T_n_A_dot = 0.0; - d_epsilon_n_A = 0.0; - d_omega_n_A = 0.0; - d_M_n_A = 0.0; - d_KP = 0.0; - d_tau_n_A = 0.0; - d_C_n = false; - d_l_n = false; + i_satellite_freq_channel = 0; + i_satellite_PRN = 0; + i_satellite_slot_number = 0; + d_n_A = 0.0; + d_H_n_A = 0.0; + d_lambda_n_A = 0.0; + d_t_lambda_n_A = 0.0; + d_Delta_i_n_A = 0.0; + d_Delta_T_n_A = 0.0; + d_Delta_T_n_A_dot = 0.0; + d_epsilon_n_A = 0.0; + d_omega_n_A = 0.0; + d_M_n_A = 0.0; + d_KP = 0.0; + d_tau_n_A = 0.0; + d_C_n = false; + d_l_n = false; } diff --git a/src/core/system_parameters/glonass_gnav_almanac.h b/src/core/system_parameters/glonass_gnav_almanac.h index 3fc255118..896c5cd62 100644 --- a/src/core/system_parameters/glonass_gnav_almanac.h +++ b/src/core/system_parameters/glonass_gnav_almanac.h @@ -34,9 +34,6 @@ #ifndef GNSS_SDR_GLONASS_ALMANAC_H_ #define GNSS_SDR_GLONASS_ALMANAC_H_ -#include -#include -#include "boost/assign.hpp" #include /*! @@ -59,8 +56,8 @@ public: double d_M_n_A; //!< Type of satellite n_A [dimensionless] double d_KP; //!< Notification on forthcoming leap second correction of UTC [dimensionless] double d_tau_n_A; //!< Coarse value of d_n_A satellite time correction to GLONASS time at instant t_lambdan_A[s] - bool d_C_n; //!< Generalized “unhealthy flag” of n_A satellite at instant of almanac upload [dimensionless] - bool d_l_n; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] + bool d_C_n; //!< Generalized “unhealthy flag” of n_A satellite at instant of almanac upload [dimensionless] + bool d_l_n; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] // Satellite Identification Information int i_satellite_freq_channel; //!< SV Frequency Channel Number diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.cc b/src/core/system_parameters/glonass_gnav_ephemeris.cc index 6cd530c59..e899db773 100644 --- a/src/core/system_parameters/glonass_gnav_ephemeris.cc +++ b/src/core/system_parameters/glonass_gnav_ephemeris.cc @@ -32,56 +32,55 @@ #include "glonass_gnav_ephemeris.h" #include -#include - #include "GLONASS_L1_CA.h" #include "gnss_satellite.h" Glonass_Gnav_Ephemeris::Glonass_Gnav_Ephemeris() { - d_m = 0.0; //!< String number within frame [dimensionless] - d_t_k = 0.0; //!< GLONASS Time (UTC(SU) + 3 h) referenced to the beginning of the frame within the current day [s] - d_t_b = 0.0; //!< Reference ephemeris relative time in GLONASS Time (UTC(SU) + 3 h). Index of a time interval within current day according to UTC(SU) + 03 hours 00 min. [s] - d_M = 0.0; //!< Type of satellite transmitting navigation signal [dimensionless] - d_gamma_n = 0.0; //!< Relative deviation of predicted carrier frequency value of n- satellite from nominal value at the instant tb [dimensionless] - d_tau_n = 0.0; //!< Correction to the nth satellite time (tn) relative to GLONASS time (te), - d_Xn = 0.0; //!< Earth-fixed coordinate x of the satellite in PZ-90.02 coordinate system [km]. - d_Yn = 0.0; //!< Earth-fixed coordinate y of the satellite in PZ-90.02 coordinate system [km] - d_Zn = 0.0; //!< Earth-fixed coordinate z of the satellite in PZ-90.02 coordinate system [km] - d_VXn = 0.0; //!< Earth-fixed velocity coordinate x of the satellite in PZ-90.02 coordinate system [km/s] - d_VYn = 0.0; //!< Earth-fixed velocity coordinate y of the satellite in PZ-90.02 coordinate system [km/s] - d_VZn = 0.0; //!< Earth-fixed velocity coordinate z of the satellite in PZ-90.02 coordinate system [km/s] - d_AXn = 0.0; //!< Earth-fixed acceleration coordinate x of the satellite in PZ-90.02 coordinate system [km/s^2] - d_AYn = 0.0; //!< Earth-fixed acceleration coordinate y of the satellite in PZ-90.02 coordinate system [km/s^2] - d_AZn = 0.0; //!< Earth-fixed acceleration coordinate z of the satellite in PZ-90.02 coordinate system [km/s^2] - d_B_n = 0.0; //!< Health flag [dimensionless] - d_P = 0.0; //!< Technological parameter of control segment, indication the satellite operation mode in respect of time parameters [dimensionless] - d_N_T = 0.0; //!< Current date, calendar number of day within four-year interval starting from the 1-st of January in a leap year [days] - d_F_T = 0.0; //!< Parameter that provides the predicted satellite user range accuracy at time tb [dimensionless] - d_n = 0.0; //!< Index of the satellite transmitting given navigation signal. It corresponds to a slot number within GLONASS constellation - d_Delta_tau_n = 0.0; //!< Time difference between navigation RF signal transmitted in L2 sub- band and aviation RF signal transmitted in L1 sub-band by nth satellite. [dimensionless] - d_E_n = 0.0; //!< Characterises "age" of a current information [days] - d_P_1 = 0.0; //!< Flag of the immediate data updating [minutes] - d_P_2 = false; //!< Flag of oddness ("1") or evenness ("0") of the value of (tb) [dimensionless] - d_P_3 = false; //!< Flag indicating a number of satellites for which almanac is transmitted within given frame: "1" corresponds to 5 satellites and "0" corresponds to 4 satellites [dimensionless] - d_P_4 = false; //!< Flag to show that ephemeris parameters are present. "1" indicates that updated ephemeris or frequency/time parameters have been uploaded by the control segment [dimensionless] - d_l3rd_n = false; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] - d_l5th_n = false; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] + d_m = 0.0; //!< String number within frame [dimensionless] + d_t_k = 0.0; //!< GLONASS Time (UTC(SU) + 3 h) referenced to the beginning of the frame within the current day [s] + d_t_b = 0.0; //!< Reference ephemeris relative time in GLONASS Time (UTC(SU) + 3 h). Index of a time interval within current day according to UTC(SU) + 03 hours 00 min. [s] + d_M = 0.0; //!< Type of satellite transmitting navigation signal [dimensionless] + d_gamma_n = 0.0; //!< Relative deviation of predicted carrier frequency value of n- satellite from nominal value at the instant tb [dimensionless] + d_tau_n = 0.0; //!< Correction to the nth satellite time (tn) relative to GLONASS time (te), + d_Xn = 0.0; //!< Earth-fixed coordinate x of the satellite in PZ-90.02 coordinate system [km]. + d_Yn = 0.0; //!< Earth-fixed coordinate y of the satellite in PZ-90.02 coordinate system [km] + d_Zn = 0.0; //!< Earth-fixed coordinate z of the satellite in PZ-90.02 coordinate system [km] + d_VXn = 0.0; //!< Earth-fixed velocity coordinate x of the satellite in PZ-90.02 coordinate system [km/s] + d_VYn = 0.0; //!< Earth-fixed velocity coordinate y of the satellite in PZ-90.02 coordinate system [km/s] + d_VZn = 0.0; //!< Earth-fixed velocity coordinate z of the satellite in PZ-90.02 coordinate system [km/s] + d_AXn = 0.0; //!< Earth-fixed acceleration coordinate x of the satellite in PZ-90.02 coordinate system [km/s^2] + d_AYn = 0.0; //!< Earth-fixed acceleration coordinate y of the satellite in PZ-90.02 coordinate system [km/s^2] + d_AZn = 0.0; //!< Earth-fixed acceleration coordinate z of the satellite in PZ-90.02 coordinate system [km/s^2] + d_B_n = 0.0; //!< Health flag [dimensionless] + d_P = 0.0; //!< Technological parameter of control segment, indication the satellite operation mode in respect of time parameters [dimensionless] + d_N_T = 0.0; //!< Current date, calendar number of day within four-year interval starting from the 1-st of January in a leap year [days] + d_F_T = 0.0; //!< Parameter that provides the predicted satellite user range accuracy at time tb [dimensionless] + d_n = 0.0; //!< Index of the satellite transmitting given navigation signal. It corresponds to a slot number within GLONASS constellation + d_Delta_tau_n = 0.0; //!< Time difference between navigation RF signal transmitted in L2 sub- band and aviation RF signal transmitted in L1 sub-band by nth satellite. [dimensionless] + d_E_n = 0.0; //!< Characterises "age" of a current information [days] + d_P_1 = 0.0; //!< Flag of the immediate data updating [minutes] + d_P_2 = false; //!< Flag of oddness ("1") or evenness ("0") of the value of (tb) [dimensionless] + d_P_3 = false; //!< Flag indicating a number of satellites for which almanac is transmitted within given frame: "1" corresponds to 5 satellites and "0" corresponds to 4 satellites [dimensionless] + d_P_4 = false; //!< Flag to show that ephemeris parameters are present. "1" indicates that updated ephemeris or frequency/time parameters have been uploaded by the control segment [dimensionless] + d_l3rd_n = false; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] + d_l5th_n = false; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] - // Satellite Identification Information - i_satellite_freq_channel = 0; //!< SV Frequency Channel Number - i_satellite_PRN = 0; //!< SV PRN Number, equivalent to slot number for compatibility with GPS - i_satellite_slot_number = 0; //!< SV Slot Number - d_yr = 1972; //!< Current year, defaults to 1972 (UTC Epoch with leap seconds) - d_satClkDrift = 0.0; //!< GLONASS clock error - d_dtr = 0.0; //!< relativistic clock correction term - d_iode = 0.0; //!< Issue of data, ephemeris (Bit 0-6 of tb) - d_tau_c = 0.0; - d_TOW = 0.0; // tow of the start of frame - d_WN = 0.0; // week number of the start of frame - d_tod = 0.0; + // Satellite Identification Information + i_satellite_freq_channel = 0; //!< SV Frequency Channel Number + i_satellite_PRN = 0; //!< SV PRN Number, equivalent to slot number for compatibility with GPS + i_satellite_slot_number = 0; //!< SV Slot Number + d_yr = 1972; //!< Current year, defaults to 1972 (UTC Epoch with leap seconds) + d_satClkDrift = 0.0; //!< GLONASS clock error + d_dtr = 0.0; //!< relativistic clock correction term + d_iode = 0.0; //!< Issue of data, ephemeris (Bit 0-6 of tb) + d_tau_c = 0.0; + d_TOW = 0.0; // tow of the start of frame + d_WN = 0.0; // week number of the start of frame + d_tod = 0.0; } + boost::posix_time::ptime Glonass_Gnav_Ephemeris::compute_GLONASS_time(const double offset_time) const { boost::posix_time::time_duration t(0, 0, offset_time + d_tau_c + d_tau_n); @@ -92,74 +91,75 @@ boost::posix_time::ptime Glonass_Gnav_Ephemeris::compute_GLONASS_time(const doub return glonass_time; } + boost::posix_time::ptime Glonass_Gnav_Ephemeris::glot_to_utc(const double offset_time, const double glot2utc_corr) const { - double tod = 0.0; - double glot2utc = 3*3600; + double tod = 0.0; + double glot2utc = 3*3600; - tod = offset_time - glot2utc + glot2utc_corr + d_tau_n; - boost::posix_time::time_duration t(0, 0, tod); - boost::gregorian::date d1(d_yr, 1, 1); - boost::gregorian::days d2(d_N_T - 1); - boost::posix_time::ptime utc_time(d1+d2, t); + tod = offset_time - glot2utc + glot2utc_corr + d_tau_n; + boost::posix_time::time_duration t(0, 0, tod); + boost::gregorian::date d1(d_yr, 1, 1); + boost::gregorian::days d2(d_N_T - 1); + boost::posix_time::ptime utc_time(d1 + d2, t); - return utc_time; + return utc_time; } + void Glonass_Gnav_Ephemeris::glot_to_gpst(double tod_offset, double glot2utc_corr, double glot2gpst_corr, double * wn, double * tow) const { - double tod = 0.0; - double glot2utc = 3*3600; - double days = 0.0; - double total_sec = 0.0, sec_of_day = 0.0; - int i = 0; + double tod = 0.0; + double glot2utc = 3*3600; + double days = 0.0; + double total_sec = 0.0, sec_of_day = 0.0; + int i = 0; - boost::gregorian::date gps_epoch { 1980, 1, 6 }; + boost::gregorian::date gps_epoch { 1980, 1, 6 }; - // tk is relative to UTC(SU) + 3.00 hrs, so we need to convert to utc and add corrections - // tk plus 10 sec is the true tod since get_TOW is called when in str5 - tod = tod_offset - glot2utc ; + // tk is relative to UTC(SU) + 3.00 hrs, so we need to convert to utc and add corrections + // tk plus 10 sec is the true tod since get_TOW is called when in str5 + tod = tod_offset - glot2utc ; + boost::posix_time::time_duration t(0, 0, tod); + boost::gregorian::date d1(d_yr, 1, 1); + boost::gregorian::days d2(d_N_T-1); + boost::posix_time::ptime utc_time(d1+d2, t); + boost::gregorian::date utc_date = utc_time.date(); + boost::posix_time::ptime gps_time; - boost::posix_time::time_duration t(0, 0, tod); - boost::gregorian::date d1(d_yr, 1, 1); - boost::gregorian::days d2(d_N_T-1); - boost::posix_time::ptime utc_time(d1+d2, t); - boost::gregorian::date utc_date = utc_time.date(); - boost::posix_time::ptime gps_time; + // Adjust for leap second correction + for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) + { + boost::posix_time::time_duration t3(GLONASS_LEAP_SECONDS[i][3], GLONASS_LEAP_SECONDS[i][4], GLONASS_LEAP_SECONDS[i][5]); + boost::gregorian::date d3(GLONASS_LEAP_SECONDS[i][0], GLONASS_LEAP_SECONDS[i][1], GLONASS_LEAP_SECONDS[i][2]); + boost::posix_time::ptime ls_time(d3, t3); + if (utc_time >= ls_time) + { + // We add the leap second when going from utc to gpst + gps_time = utc_time + boost::posix_time::time_duration(0,0,fabs(GLONASS_LEAP_SECONDS[i][6])); + break; + } + } - // Adjust for leap second correction - for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) - { - boost::posix_time::time_duration t3(GLONASS_LEAP_SECONDS[i][3], GLONASS_LEAP_SECONDS[i][4], GLONASS_LEAP_SECONDS[i][5]); - boost::gregorian::date d3(GLONASS_LEAP_SECONDS[i][0], GLONASS_LEAP_SECONDS[i][1], GLONASS_LEAP_SECONDS[i][2]); - boost::posix_time::ptime ls_time(d3, t3); - if (utc_time >= ls_time) - { - // We add the leap second when going from utc to gpst - gps_time = utc_time + boost::posix_time::time_duration(0,0,fabs(GLONASS_LEAP_SECONDS[i][6])); - break; - } - } + // Total number of days + std::string fdat = boost::posix_time::to_simple_string(gps_time); + days = static_cast((utc_date - gps_epoch).days()); - // Total number of days - std::string fdat = boost::posix_time::to_simple_string(gps_time); - days = static_cast((utc_date - gps_epoch).days()); + // Total number of seconds + sec_of_day = static_cast((gps_time.time_of_day()).total_seconds()); + total_sec = days*86400 + sec_of_day; - // Total number of seconds - sec_of_day = static_cast((gps_time.time_of_day()).total_seconds()); - total_sec = days*86400 + sec_of_day; - - // Compute Week number - *wn = floor(total_sec/604800); - - // Compute the arithmetic modules to wrap around range - *tow = total_sec - 604800*floor(total_sec/604800); - // Perform corrections from fractional seconds - *tow += glot2utc_corr + glot2gpst_corr; + // Compute Week number + *wn = floor(total_sec/604800); + // Compute the arithmetic modules to wrap around range + *tow = total_sec - 604800*floor(total_sec/604800); + // Perform corrections from fractional seconds + *tow += glot2utc_corr + glot2gpst_corr; } + double Glonass_Gnav_Ephemeris::check_t(double time) { double corrTime; @@ -176,6 +176,7 @@ double Glonass_Gnav_Ephemeris::check_t(double time) return corrTime; } + // FIXME Fix reference here // 20.3.3.3.3.1 User Algorithm for SV Clock Correction. double Glonass_Gnav_Ephemeris::sv_clock_drift(double transmitTime, double timeCorrUTC) diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.h b/src/core/system_parameters/glonass_gnav_ephemeris.h index 5400e890f..cf43566e2 100644 --- a/src/core/system_parameters/glonass_gnav_ephemeris.h +++ b/src/core/system_parameters/glonass_gnav_ephemeris.h @@ -35,9 +35,6 @@ #define GNSS_SDR_GLONASS_GNAV_EPHEMERIS_H_ -#include -#include -#include "boost/assign.hpp" #include #include @@ -64,7 +61,7 @@ public: double d_m; //!< String number within frame [dimensionless] double d_t_k; //!< GLONASS Time (UTC(SU) + 3 h) referenced to the beginning of the frame within the current day [s] double d_t_b; //!< Reference ephemeris relative time in GLONASS Time (UTC(SU) + 3 h). Index of a time interval within current day according to UTC(SU) + 03 hours 00 min. [s] - double d_M; //!< Type of satellite transmitting navigation signal [dimensionless] + double d_M; //!< Type of satellite transmitting navigation signal [dimensionless] double d_gamma_n; //!< Relative deviation of predicted carrier frequency value of n- satellite from nominal value at the instant tb [dimensionless] double d_tau_n; //!< Correction to the nth satellite time (tn) relative to GLONASS time (te), double d_Xn; //!< Earth-fixed coordinate x of the satellite in PZ-90.02 coordinate system [km]. @@ -84,25 +81,25 @@ public: double d_Delta_tau_n; //!< Time difference between navigation RF signal transmitted in L2 sub- band and aviation RF signal transmitted in L1 sub-band by nth satellite. [dimensionless] double d_E_n; //!< Characterises "age" of a current information [days] double d_P_1; //!< Flag of the immediate data updating [minutes] - bool d_P_2; //!< Flag of oddness ("1") or evenness ("0") of the value of (tb) [dimensionless] - bool d_P_3; //!< Flag indicating a number of satellites for which almanac is transmitted within given frame: "1" corresponds to 5 satellites and "0" corresponds to 4 satellites [dimensionless] - bool d_P_4; //!< Flag to show that ephemeris parameters are present. "1" indicates that updated ephemeris or frequency/time parameters have been uploaded by the control segment [dimensionless] - bool d_l3rd_n; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] - bool d_l5th_n; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] + bool d_P_2; //!< Flag of oddness ("1") or evenness ("0") of the value of (tb) [dimensionless] + bool d_P_3; //!< Flag indicating a number of satellites for which almanac is transmitted within given frame: "1" corresponds to 5 satellites and "0" corresponds to 4 satellites [dimensionless] + bool d_P_4; //!< Flag to show that ephemeris parameters are present. "1" indicates that updated ephemeris or frequency/time parameters have been uploaded by the control segment [dimensionless] + bool d_l3rd_n; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is healthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] + bool d_l5th_n; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is healthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] // Inmediate deliverables of ephemeris information // Satellite Identification Information - int i_satellite_freq_channel; //!< SV Frequency Channel Number + int i_satellite_freq_channel; //!< SV Frequency Channel Number unsigned int i_satellite_PRN; //!< SV PRN Number, equivalent to slot number for compatibility with GPS unsigned int i_satellite_slot_number; //!< SV Slot Number double d_yr; //!< Current year double d_satClkDrift; //!< GLONASS clock error double d_dtr; //!< relativistic clock correction term double d_iode; //!< Issue of data, ephemeris (Bit 0-6 of tb) - double d_tau_c; //!< GLONASST 2 UTC correction (todo) may be eliminated - double d_TOW; //!< GLONASST IN GPST seconds of week - double d_WN; //!< GLONASST IN GPST week number of the start of frame - double d_tod; //!< Time of Day since ephemeris where decoded + double d_tau_c; //!< GLONASST 2 UTC correction (todo) may be eliminated + double d_TOW; //!< GLONASST IN GPST seconds of week + double d_WN; //!< GLONASST IN GPST week number of the start of frame + double d_tod; //!< Time of Day since ephemeris where decoded template @@ -137,14 +134,14 @@ public: archive & make_nvp("d_N_T", d_N_T); //!< Current date, calendar number of day within four-year interval starting from the 1-st of January in a leap year [days] archive & make_nvp("d_F_T", d_F_T); //!< Parameter that provides the predicted satellite user range accuracy at time tb [dimensionless] archive & make_nvp("d_n", d_n); //!< Index of the satellite transmitting given navigation signal. It corresponds to a slot number within GLONASS constellation - archive & make_nvp("d_Delta_tau_n", d_Delta_tau_n);//!< Time difference between navigation RF signal transmitted in L2 sub- band and aviation RF signal transmitted in L1 sub-band by nth satellite. [dimensionless] + archive & make_nvp("d_Delta_tau_n", d_Delta_tau_n); //!< Time difference between navigation RF signal transmitted in L2 sub- band and aviation RF signal transmitted in L1 sub-band by nth satellite. [dimensionless] archive & make_nvp("d_E_n", d_E_n); //!< Characterises "age" of a current information [days] archive & make_nvp("d_P_1", d_P_1); //!< Flag of the immediate data updating. archive & make_nvp("d_P_2", d_P_2); //!< Flag of oddness ("1") or evenness ("0") of the value of (tb) [dimensionless] archive & make_nvp("d_P_3", d_P_3); //!< Flag indicating a number of satellites for which almanac is transmitted within given frame: "1" corresponds to 5 satellites and "0" corresponds to 4 satellites [dimensionless] archive & make_nvp("d_P_4", d_P_4); //!< Flag to show that ephemeris parameters are present. "1" indicates that updated ephemeris or frequency/time parameters have been uploaded by the control segment [dimensionless] - archive & make_nvp("d_l3rd_n", d_l3rd_n); //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] - archive & make_nvp("d_l5th_n", d_l5th_n); //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] + archive & make_nvp("d_l3rd_n", d_l3rd_n); //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] + archive & make_nvp("d_l5th_n", d_l5th_n); //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] } /*! diff --git a/src/core/system_parameters/glonass_gnav_navigation_message.cc b/src/core/system_parameters/glonass_gnav_navigation_message.cc index abc13409d..40301ea09 100644 --- a/src/core/system_parameters/glonass_gnav_navigation_message.cc +++ b/src/core/system_parameters/glonass_gnav_navigation_message.cc @@ -31,30 +31,25 @@ */ #include "glonass_gnav_navigation_message.h" -#include -#include -#include -#include -#include #include #include void Glonass_Gnav_Navigation_Message::reset() { - //!< Satellite Identification + // Satellite Identification i_satellite_PRN = 0; i_alm_satellite_slot_number = 0; //!< SV Orbit Slot Number flag_update_slot_number = false; - //!< Ephmeris Flags + // Ephmeris Flags flag_all_ephemeris = false; flag_ephemeris_str_1 = false; flag_ephemeris_str_2 = false; flag_ephemeris_str_3 = false; flag_ephemeris_str_4 = false; - //!< Almanac Flags + // Almanac Flags flag_all_almanac = false; flag_almanac_str_6 = false; flag_almanac_str_7 = false; @@ -67,12 +62,12 @@ void Glonass_Gnav_Navigation_Message::reset() flag_almanac_str_14 = false; flag_almanac_str_15 = false; - //!< UTC and System Clocks Flags + // UTC and System Clocks Flags flag_utc_model_valid = false; //!< If set, it indicates that the UTC model parameters are filled flag_utc_model_str_5 = false; //!< Clock info send in string 5 of navigation data flag_utc_model_str_15 = false; //!< Clock info send in string 15 of frame 5 of navigation data - //broadcast orbit 1 + // broadcast orbit 1 flag_TOW_set = false; flag_TOW_new = false; @@ -89,7 +84,7 @@ void Glonass_Gnav_Navigation_Message::reset() // Data update information d_previous_tb = 0.0; for(unsigned int i = 0; i < GLONASS_L1_CA_NBR_SATS; i++) - d_previous_Na[i] = 0.0; + d_previous_Na[i] = 0.0; std::map satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus @@ -97,9 +92,9 @@ void Glonass_Gnav_Navigation_Message::reset() std::string _system ("GLONASS"); //TODO SHould number of channels be hardcoded? for(unsigned int i = 1; i < 14; i++) - { - satelliteBlock[i] = gnss_sat.what_block(_system, i); - } + { + satelliteBlock[i] = gnss_sat.what_block(_system, i); + } } @@ -123,11 +118,11 @@ bool Glonass_Gnav_Navigation_Message::CRC_test(std::bitset string_bits(GLONASS_GNAV_STRING_BITS); - //!< Populate data and hamming code vectors - for(int i = 0; i < static_cast(GLONASS_GNAV_STRING_BITS); i++) - { - string_bits[i] = static_cast(bits[i]); - } + //!< Populate data and hamming code vectors + for(int i = 0; i < static_cast(GLONASS_GNAV_STRING_BITS); i++) + { + string_bits[i] = static_cast(bits[i]); + } //!< Compute C1 term sum_bits = 0; @@ -210,7 +205,7 @@ bool Glonass_Gnav_Navigation_Message::CRC_test(std::bitset(read_navigation_unsigned(string_bits, STRING_ID)); - switch (d_string_ID) { - case 1: - //--- It is string 1 ----------------------------------------------- - gnav_ephemeris.d_P_1 = (static_cast(read_navigation_unsigned(string_bits, P1)) + 1) * 15; - gnav_ephemeris.d_t_k = static_cast(read_navigation_unsigned(string_bits, T_K_HR)) * 3600 + - static_cast(read_navigation_unsigned(string_bits, T_K_MIN)) * 60 + - static_cast(read_navigation_unsigned(string_bits, T_K_SEC)) * 30; - gnav_ephemeris.d_VXn = static_cast(read_navigation_signed(string_bits, X_N_DOT)) * TWO_N20; - gnav_ephemeris.d_AXn = static_cast(read_navigation_signed(string_bits, X_N_DOT_DOT)) * TWO_N30; - gnav_ephemeris.d_Xn = static_cast(read_navigation_signed(string_bits, X_N)) * TWO_N11; + switch (d_string_ID) + { + case 1: + //--- It is string 1 ----------------------------------------------- + gnav_ephemeris.d_P_1 = (static_cast(read_navigation_unsigned(string_bits, P1)) + 1) * 15; + gnav_ephemeris.d_t_k = static_cast(read_navigation_unsigned(string_bits, T_K_HR)) * 3600 + + static_cast(read_navigation_unsigned(string_bits, T_K_MIN)) * 60 + + static_cast(read_navigation_unsigned(string_bits, T_K_SEC)) * 30; + gnav_ephemeris.d_VXn = static_cast(read_navigation_signed(string_bits, X_N_DOT)) * TWO_N20; + gnav_ephemeris.d_AXn = static_cast(read_navigation_signed(string_bits, X_N_DOT_DOT)) * TWO_N30; + gnav_ephemeris.d_Xn = static_cast(read_navigation_signed(string_bits, X_N)) * TWO_N11; - flag_ephemeris_str_1 = true; + flag_ephemeris_str_1 = true; - break; + break; - case 2: - //--- It is string 2 ----------------------------------------------- - if (flag_ephemeris_str_1 == true) - { - gnav_ephemeris.d_B_n = static_cast(read_navigation_unsigned(string_bits, B_N)); - gnav_ephemeris.d_P_2 = static_cast(read_navigation_bool(string_bits, P2)); - gnav_ephemeris.d_t_b = static_cast(read_navigation_unsigned(string_bits, T_B)) * 15 * 60; - gnav_ephemeris.d_VYn = static_cast(read_navigation_signed(string_bits, Y_N_DOT)) * TWO_N20; - gnav_ephemeris.d_AYn = static_cast(read_navigation_signed(string_bits, Y_N_DOT_DOT)) * TWO_N30; - gnav_ephemeris.d_Yn = static_cast(read_navigation_signed(string_bits, Y_N)) * TWO_N11; + case 2: + //--- It is string 2 ----------------------------------------------- + if (flag_ephemeris_str_1 == true) + { + gnav_ephemeris.d_B_n = static_cast(read_navigation_unsigned(string_bits, B_N)); + gnav_ephemeris.d_P_2 = static_cast(read_navigation_bool(string_bits, P2)); + gnav_ephemeris.d_t_b = static_cast(read_navigation_unsigned(string_bits, T_B)) * 15 * 60; + gnav_ephemeris.d_VYn = static_cast(read_navigation_signed(string_bits, Y_N_DOT)) * TWO_N20; + gnav_ephemeris.d_AYn = static_cast(read_navigation_signed(string_bits, Y_N_DOT_DOT)) * TWO_N30; + gnav_ephemeris.d_Yn = static_cast(read_navigation_signed(string_bits, Y_N)) * TWO_N11; - gnav_ephemeris.d_iode = read_navigation_unsigned(string_bits, T_B); - flag_ephemeris_str_2 = true; - } + gnav_ephemeris.d_iode = read_navigation_unsigned(string_bits, T_B); + flag_ephemeris_str_2 = true; + } - break; + break; - case 3: - // --- It is string 3 ---------------------------------------------- - if (flag_ephemeris_str_2 == true) - { - gnav_ephemeris.d_P_3 = static_cast(read_navigation_bool(string_bits, P3)); - gnav_ephemeris.d_gamma_n = static_cast(read_navigation_signed(string_bits, GAMMA_N)) * TWO_N40; - gnav_ephemeris.d_P = static_cast(read_navigation_unsigned(string_bits, P)); - gnav_ephemeris.d_l3rd_n = static_cast(read_navigation_bool(string_bits, EPH_L_N)); - gnav_ephemeris.d_VZn = static_cast(read_navigation_signed(string_bits, Z_N_DOT)) * TWO_N20; - gnav_ephemeris.d_AZn = static_cast(read_navigation_signed(string_bits, Z_N_DOT_DOT)) * TWO_N30; - gnav_ephemeris.d_Zn = static_cast(read_navigation_signed(string_bits, Z_N)) * TWO_N11; + case 3: + // --- It is string 3 ---------------------------------------------- + if (flag_ephemeris_str_2 == true) + { + gnav_ephemeris.d_P_3 = static_cast(read_navigation_bool(string_bits, P3)); + gnav_ephemeris.d_gamma_n = static_cast(read_navigation_signed(string_bits, GAMMA_N)) * TWO_N40; + gnav_ephemeris.d_P = static_cast(read_navigation_unsigned(string_bits, P)); + gnav_ephemeris.d_l3rd_n = static_cast(read_navigation_bool(string_bits, EPH_L_N)); + gnav_ephemeris.d_VZn = static_cast(read_navigation_signed(string_bits, Z_N_DOT)) * TWO_N20; + gnav_ephemeris.d_AZn = static_cast(read_navigation_signed(string_bits, Z_N_DOT_DOT)) * TWO_N30; + gnav_ephemeris.d_Zn = static_cast(read_navigation_signed(string_bits, Z_N)) * TWO_N11; - flag_ephemeris_str_3 = true; - } + flag_ephemeris_str_3 = true; + } - break; + break; - case 4: - // --- It is string 4 ---------------------------------------------- - if (flag_ephemeris_str_3 == true) - { - gnav_ephemeris.d_tau_n = static_cast(read_navigation_signed(string_bits, TAU_N)) * TWO_N30; - gnav_ephemeris.d_Delta_tau_n = static_cast(read_navigation_signed(string_bits, DELTA_TAU_N)) * TWO_N30; - gnav_ephemeris.d_E_n = static_cast(read_navigation_unsigned(string_bits, E_N)); - gnav_ephemeris.d_P_4 = static_cast(read_navigation_bool(string_bits, P4)); - gnav_ephemeris.d_F_T = static_cast(read_navigation_unsigned(string_bits, F_T)); - gnav_ephemeris.d_N_T = static_cast(read_navigation_unsigned(string_bits, N_T)); - gnav_ephemeris.d_n = static_cast(read_navigation_unsigned(string_bits, N)); - gnav_ephemeris.d_M = static_cast(read_navigation_unsigned(string_bits, M)); + case 4: + // --- It is string 4 ---------------------------------------------- + if (flag_ephemeris_str_3 == true) + { + gnav_ephemeris.d_tau_n = static_cast(read_navigation_signed(string_bits, TAU_N)) * TWO_N30; + gnav_ephemeris.d_Delta_tau_n = static_cast(read_navigation_signed(string_bits, DELTA_TAU_N)) * TWO_N30; + gnav_ephemeris.d_E_n = static_cast(read_navigation_unsigned(string_bits, E_N)); + gnav_ephemeris.d_P_4 = static_cast(read_navigation_bool(string_bits, P4)); + gnav_ephemeris.d_F_T = static_cast(read_navigation_unsigned(string_bits, F_T)); + gnav_ephemeris.d_N_T = static_cast(read_navigation_unsigned(string_bits, N_T)); + gnav_ephemeris.d_n = static_cast(read_navigation_unsigned(string_bits, N)); + gnav_ephemeris.d_M = static_cast(read_navigation_unsigned(string_bits, M)); - // Fill in ephemeris deliverables in the code - flag_update_slot_number = true; - gnav_ephemeris.i_satellite_slot_number = static_cast(gnav_ephemeris.d_n); - gnav_ephemeris.i_satellite_PRN = static_cast(gnav_ephemeris.d_n); + // Fill in ephemeris deliverables in the code + flag_update_slot_number = true; + gnav_ephemeris.i_satellite_slot_number = static_cast(gnav_ephemeris.d_n); + gnav_ephemeris.i_satellite_PRN = static_cast(gnav_ephemeris.d_n); - flag_ephemeris_str_4 = true; - } + flag_ephemeris_str_4 = true; + } - break; + break; - case 5: - // --- It is string 5 ---------------------------------------------- - if (flag_ephemeris_str_4 == true) - { - gnav_utc_model.d_N_A = static_cast(read_navigation_unsigned(string_bits, N_A)); - gnav_utc_model.d_tau_c = static_cast(read_navigation_signed(string_bits, TAU_C)) * TWO_N31; - gnav_utc_model.d_N_4 = static_cast(read_navigation_unsigned(string_bits, N_4)); - gnav_utc_model.d_tau_gps = static_cast(read_navigation_signed(string_bits, TAU_GPS)) * TWO_N30; - gnav_ephemeris.d_l5th_n = static_cast(read_navigation_bool(string_bits, ALM_L_N)); + case 5: + // --- It is string 5 ---------------------------------------------- + if (flag_ephemeris_str_4 == true) + { + gnav_utc_model.d_N_A = static_cast(read_navigation_unsigned(string_bits, N_A)); + gnav_utc_model.d_tau_c = static_cast(read_navigation_signed(string_bits, TAU_C)) * TWO_N31; + gnav_utc_model.d_N_4 = static_cast(read_navigation_unsigned(string_bits, N_4)); + gnav_utc_model.d_tau_gps = static_cast(read_navigation_signed(string_bits, TAU_GPS)) * TWO_N30; + gnav_ephemeris.d_l5th_n = static_cast(read_navigation_bool(string_bits, ALM_L_N)); - flag_utc_model_str_5 = true; + flag_utc_model_str_5 = true; - // Compute Year and DoY based on Algorithm A3.11 of GLONASS ICD - // 1). Current year number J in the four-year interval is calculated - if (gnav_ephemeris.d_N_T >= 1 && gnav_ephemeris.d_N_T <= 366) - { - J = 1; - } - else if (gnav_ephemeris.d_N_T >= 367 && gnav_ephemeris.d_N_T <= 731) - { - J = 2; - } - else if (gnav_ephemeris.d_N_T >= 732 && gnav_ephemeris.d_N_T <= 1096) - { - J = 3; - } - else if (gnav_ephemeris.d_N_T >= 1097 && gnav_ephemeris.d_N_T <= 1461) - { - J = 4; - } - // 2). Current year in common form is calculated by the following formula: - gnav_ephemeris.d_yr = 1996 + 4.0 * (gnav_utc_model.d_N_4 - 1.0) + (J - 1.0); - gnav_ephemeris.d_tau_c = gnav_utc_model.d_tau_c; + // Compute Year and DoY based on Algorithm A3.11 of GLONASS ICD + // 1). Current year number J in the four-year interval is calculated + if (gnav_ephemeris.d_N_T >= 1 && gnav_ephemeris.d_N_T <= 366) + { + J = 1; + } + else if (gnav_ephemeris.d_N_T >= 367 && gnav_ephemeris.d_N_T <= 731) + { + J = 2; + } + else if (gnav_ephemeris.d_N_T >= 732 && gnav_ephemeris.d_N_T <= 1096) + { + J = 3; + } + else if (gnav_ephemeris.d_N_T >= 1097 && gnav_ephemeris.d_N_T <= 1461) + { + J = 4; + } + // 2). Current year in common form is calculated by the following formula: + gnav_ephemeris.d_yr = 1996 + 4.0 * (gnav_utc_model.d_N_4 - 1.0) + (J - 1.0); + gnav_ephemeris.d_tau_c = gnav_utc_model.d_tau_c; - // 3). Set TOW once the year has been defined, it helps with leap second determination - if (flag_ephemeris_str_1 == true) - { - gnav_ephemeris.glot_to_gpst(gnav_ephemeris.d_t_k+10, gnav_utc_model.d_tau_c, gnav_utc_model.d_tau_gps, &gnav_ephemeris.d_WN, &gnav_ephemeris.d_TOW); - flag_TOW_set = true; - flag_TOW_new = true; - } + // 3). Set TOW once the year has been defined, it helps with leap second determination + if (flag_ephemeris_str_1 == true) + { + gnav_ephemeris.glot_to_gpst(gnav_ephemeris.d_t_k+10, gnav_utc_model.d_tau_c, gnav_utc_model.d_tau_gps, &gnav_ephemeris.d_WN, &gnav_ephemeris.d_TOW); + flag_TOW_set = true; + flag_TOW_new = true; + } - // 4) Set time of day (tod) when ephemeris data is complety decoded - gnav_ephemeris.d_tod = gnav_ephemeris.d_t_k + 2*d_string_ID; - } + // 4) Set time of day (tod) when ephemeris data is complety decoded + gnav_ephemeris.d_tod = gnav_ephemeris.d_t_k + 2*d_string_ID; + } - break; + break; - case 6: - // --- It is string 6 ---------------------------------------------- - i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); - d_frame_ID = get_frame_number(i_alm_satellite_slot_number); - // Make sure a valid frame_ID or satellite slot number is returned - if(d_frame_ID == 0) - return 0; + case 6: + // --- It is string 6 ---------------------------------------------- + i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); + d_frame_ID = get_frame_number(i_alm_satellite_slot_number); + // Make sure a valid frame_ID or satellite slot number is returned + if(d_frame_ID == 0) + return 0; - gnav_almanac[i_alm_satellite_slot_number - 1].d_C_n = static_cast(read_navigation_bool(string_bits, C_N)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_M_n_A = static_cast(read_navigation_unsigned(string_bits, M_N_A)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A = static_cast(read_navigation_unsigned(string_bits, n_A)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_tau_n_A = static_cast(read_navigation_unsigned(string_bits, TAU_N_A)) * TWO_N18; - gnav_almanac[i_alm_satellite_slot_number - 1].d_lambda_n_A = static_cast(read_navigation_signed(string_bits, LAMBDA_N_A)) * TWO_N20 * GLONASS_PI; - gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_i_n_A = static_cast(read_navigation_signed(string_bits, DELTA_I_N_A)) * TWO_N20 * GLONASS_PI; - gnav_almanac[i_alm_satellite_slot_number - 1].d_epsilon_n_A = static_cast(read_navigation_unsigned(string_bits, EPSILON_N_A)) * TWO_N20; + gnav_almanac[i_alm_satellite_slot_number - 1].d_C_n = static_cast(read_navigation_bool(string_bits, C_N)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_M_n_A = static_cast(read_navigation_unsigned(string_bits, M_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A = static_cast(read_navigation_unsigned(string_bits, n_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_tau_n_A = static_cast(read_navigation_unsigned(string_bits, TAU_N_A)) * TWO_N18; + gnav_almanac[i_alm_satellite_slot_number - 1].d_lambda_n_A = static_cast(read_navigation_signed(string_bits, LAMBDA_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_i_n_A = static_cast(read_navigation_signed(string_bits, DELTA_I_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_epsilon_n_A = static_cast(read_navigation_unsigned(string_bits, EPSILON_N_A)) * TWO_N20; - flag_almanac_str_6 = true; + flag_almanac_str_6 = true; - break; + break; - case 7: - // --- It is string 7 ---------------------------------------------- - if (flag_almanac_str_6 == true) - { - gnav_almanac[i_alm_satellite_slot_number - 1].d_omega_n_A = static_cast(read_navigation_signed(string_bits, OMEGA_N_A)) * TWO_N15 * GLONASS_PI; - gnav_almanac[i_alm_satellite_slot_number - 1].d_t_lambda_n_A = static_cast(read_navigation_unsigned(string_bits, T_LAMBDA_N_A)) * TWO_N5; - gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A = static_cast(read_navigation_signed(string_bits, DELTA_T_N_A)) * TWO_N9; - gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A_dot = static_cast(read_navigation_signed(string_bits, DELTA_T_DOT_N_A)) * TWO_N14; - gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A = static_cast(read_navigation_unsigned(string_bits, H_N_A)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_l_n = static_cast(read_navigation_bool(string_bits, ALM_L_N)); + case 7: + // --- It is string 7 ---------------------------------------------- + if (flag_almanac_str_6 == true) + { + gnav_almanac[i_alm_satellite_slot_number - 1].d_omega_n_A = static_cast(read_navigation_signed(string_bits, OMEGA_N_A)) * TWO_N15 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_t_lambda_n_A = static_cast(read_navigation_unsigned(string_bits, T_LAMBDA_N_A)) * TWO_N5; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A = static_cast(read_navigation_signed(string_bits, DELTA_T_N_A)) * TWO_N9; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A_dot = static_cast(read_navigation_signed(string_bits, DELTA_T_DOT_N_A)) * TWO_N14; + gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A = static_cast(read_navigation_unsigned(string_bits, H_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_l_n = static_cast(read_navigation_bool(string_bits, ALM_L_N)); - // Set satellite information for redundancy purposes - if (gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A > 24) - { - gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_freq_channel = gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A - 32.0; - } - gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_slot_number = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; - gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_PRN = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + // Set satellite information for redundancy purposes + if (gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A > 24) + { + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_freq_channel = gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A - 32.0; + } + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_slot_number = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_PRN = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; - if (i_alm_satellite_slot_number == gnav_ephemeris.i_satellite_slot_number) - { - gnav_ephemeris.i_satellite_freq_channel = gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_freq_channel; - } - flag_almanac_str_7 = true; - } + if (i_alm_satellite_slot_number == gnav_ephemeris.i_satellite_slot_number) + { + gnav_ephemeris.i_satellite_freq_channel = gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_freq_channel; + } + flag_almanac_str_7 = true; + } + break; - break; - case 8: - // --- It is string 8 ---------------------------------------------- - i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); - d_frame_ID = get_frame_number(i_alm_satellite_slot_number); - // Make sure a valid frame_ID or satellite slot number is returned - if(d_frame_ID == 0) - return 0; + case 8: + // --- It is string 8 ---------------------------------------------- + i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); + d_frame_ID = get_frame_number(i_alm_satellite_slot_number); + // Make sure a valid frame_ID or satellite slot number is returned + if(d_frame_ID == 0) + return 0; - gnav_almanac[i_alm_satellite_slot_number - 1].d_C_n = static_cast(read_navigation_bool(string_bits, C_N)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_M_n_A = static_cast(read_navigation_unsigned(string_bits, M_N_A)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A = static_cast(read_navigation_unsigned(string_bits, n_A)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_tau_n_A = static_cast(read_navigation_unsigned(string_bits, TAU_N_A)) * TWO_N18; - gnav_almanac[i_alm_satellite_slot_number - 1].d_lambda_n_A = static_cast(read_navigation_signed(string_bits, LAMBDA_N_A)) * TWO_N20 * GLONASS_PI; - gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_i_n_A = static_cast(read_navigation_signed(string_bits, DELTA_I_N_A)) * TWO_N20 * GLONASS_PI; - gnav_almanac[i_alm_satellite_slot_number - 1].d_epsilon_n_A = static_cast(read_navigation_unsigned(string_bits, EPSILON_N_A)) * TWO_N20; + gnav_almanac[i_alm_satellite_slot_number - 1].d_C_n = static_cast(read_navigation_bool(string_bits, C_N)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_M_n_A = static_cast(read_navigation_unsigned(string_bits, M_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A = static_cast(read_navigation_unsigned(string_bits, n_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_tau_n_A = static_cast(read_navigation_unsigned(string_bits, TAU_N_A)) * TWO_N18; + gnav_almanac[i_alm_satellite_slot_number - 1].d_lambda_n_A = static_cast(read_navigation_signed(string_bits, LAMBDA_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_i_n_A = static_cast(read_navigation_signed(string_bits, DELTA_I_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_epsilon_n_A = static_cast(read_navigation_unsigned(string_bits, EPSILON_N_A)) * TWO_N20; - flag_almanac_str_8 = true; + flag_almanac_str_8 = true; - break; - case 9: - // --- It is string 9 ---------------------------------------------- - if (flag_almanac_str_8 == true) - { - gnav_almanac[i_alm_satellite_slot_number - 1].d_omega_n_A = static_cast(read_navigation_signed(string_bits, OMEGA_N_A)) * TWO_N15 * GLONASS_PI; - gnav_almanac[i_alm_satellite_slot_number - 1].d_t_lambda_n_A = static_cast(read_navigation_unsigned(string_bits, T_LAMBDA_N_A)) * TWO_N5; - gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A = static_cast(read_navigation_signed(string_bits, DELTA_T_N_A)) * TWO_N9; - gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A_dot = static_cast(read_navigation_signed(string_bits, DELTA_T_DOT_N_A)) * TWO_N14; - gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A = static_cast(read_navigation_unsigned(string_bits, H_N_A)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_l_n = static_cast(read_navigation_bool(string_bits, ALM_L_N)); + break; - // Set satellite information for redundancy purposes - if (gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A > 24) - { - gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_freq_channel = gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A - 32.0; - } - gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_slot_number = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; - gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_PRN = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + case 9: + // --- It is string 9 ---------------------------------------------- + if (flag_almanac_str_8 == true) + { + gnav_almanac[i_alm_satellite_slot_number - 1].d_omega_n_A = static_cast(read_navigation_signed(string_bits, OMEGA_N_A)) * TWO_N15 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_t_lambda_n_A = static_cast(read_navigation_unsigned(string_bits, T_LAMBDA_N_A)) * TWO_N5; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A = static_cast(read_navigation_signed(string_bits, DELTA_T_N_A)) * TWO_N9; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A_dot = static_cast(read_navigation_signed(string_bits, DELTA_T_DOT_N_A)) * TWO_N14; + gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A = static_cast(read_navigation_unsigned(string_bits, H_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_l_n = static_cast(read_navigation_bool(string_bits, ALM_L_N)); - flag_almanac_str_9 = true; - } - break; - case 10: - // --- It is string 10 --------------------------------------------- - i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); - d_frame_ID = get_frame_number(i_alm_satellite_slot_number); - // Make sure a valid frame_ID or satellite slot number is returned - if(d_frame_ID == 0) - return 0; + // Set satellite information for redundancy purposes + if (gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A > 24) + { + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_freq_channel = gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A - 32.0; + } + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_slot_number = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_PRN = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; - gnav_almanac[i_alm_satellite_slot_number - 1].d_C_n = static_cast(read_navigation_bool(string_bits, C_N)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_M_n_A = static_cast(read_navigation_unsigned(string_bits, M_N_A)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A = static_cast(read_navigation_unsigned(string_bits, n_A)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_tau_n_A = static_cast(read_navigation_unsigned(string_bits, TAU_N_A)) * TWO_N18; - gnav_almanac[i_alm_satellite_slot_number - 1].d_lambda_n_A = static_cast(read_navigation_signed(string_bits, LAMBDA_N_A)) * TWO_N20 * GLONASS_PI; - gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_i_n_A = static_cast(read_navigation_signed(string_bits, DELTA_I_N_A)) * TWO_N20 * GLONASS_PI; - gnav_almanac[i_alm_satellite_slot_number - 1].d_epsilon_n_A = static_cast(read_navigation_unsigned(string_bits, EPSILON_N_A)) * TWO_N20; + flag_almanac_str_9 = true; + } + break; - flag_almanac_str_10 = true; + case 10: + // --- It is string 10 --------------------------------------------- + i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); + d_frame_ID = get_frame_number(i_alm_satellite_slot_number); + // Make sure a valid frame_ID or satellite slot number is returned + if(d_frame_ID == 0) + return 0; - break; + gnav_almanac[i_alm_satellite_slot_number - 1].d_C_n = static_cast(read_navigation_bool(string_bits, C_N)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_M_n_A = static_cast(read_navigation_unsigned(string_bits, M_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A = static_cast(read_navigation_unsigned(string_bits, n_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_tau_n_A = static_cast(read_navigation_unsigned(string_bits, TAU_N_A)) * TWO_N18; + gnav_almanac[i_alm_satellite_slot_number - 1].d_lambda_n_A = static_cast(read_navigation_signed(string_bits, LAMBDA_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_i_n_A = static_cast(read_navigation_signed(string_bits, DELTA_I_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_epsilon_n_A = static_cast(read_navigation_unsigned(string_bits, EPSILON_N_A)) * TWO_N20; - case 11: - // --- It is string 11 --------------------------------------------- - if (flag_almanac_str_10 == true) - { - gnav_almanac[i_alm_satellite_slot_number - 1].d_omega_n_A = static_cast(read_navigation_signed(string_bits, OMEGA_N_A)) * TWO_N15 * GLONASS_PI; - gnav_almanac[i_alm_satellite_slot_number - 1].d_t_lambda_n_A = static_cast(read_navigation_unsigned(string_bits, T_LAMBDA_N_A)) * TWO_N5; - gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A = static_cast(read_navigation_signed(string_bits, DELTA_T_N_A)) * TWO_N9; - gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A_dot = static_cast(read_navigation_signed(string_bits, DELTA_T_DOT_N_A)) * TWO_N14; - gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A = static_cast(read_navigation_unsigned(string_bits, H_N_A)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_l_n = static_cast(read_navigation_bool(string_bits, ALM_L_N)); + flag_almanac_str_10 = true; - // Set satellite information for redundancy purposes - if (gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A > 24) - { - gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_freq_channel = gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A - 32.0; - } - gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_slot_number = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; - gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_PRN = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + break; - flag_almanac_str_11 = true; - } - break; - case 12: - // --- It is string 12 --------------------------------------------- - i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); - d_frame_ID = get_frame_number(i_alm_satellite_slot_number); - // Make sure a valid frame_ID or satellite slot number is returned - if(d_frame_ID == 0) - return 0; - gnav_almanac[i_alm_satellite_slot_number - 1].d_C_n = static_cast(read_navigation_bool(string_bits, C_N)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_M_n_A = static_cast(read_navigation_unsigned(string_bits, M_N_A)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A = static_cast(read_navigation_unsigned(string_bits, n_A)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_tau_n_A = static_cast(read_navigation_unsigned(string_bits, TAU_N_A)) * TWO_N18; - gnav_almanac[i_alm_satellite_slot_number - 1].d_lambda_n_A = static_cast(read_navigation_signed(string_bits, LAMBDA_N_A)) * TWO_N20 * GLONASS_PI; - gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_i_n_A = static_cast(read_navigation_signed(string_bits, DELTA_I_N_A)) * TWO_N20 * GLONASS_PI; - gnav_almanac[i_alm_satellite_slot_number - 1].d_epsilon_n_A = static_cast(read_navigation_unsigned(string_bits, EPSILON_N_A)) * TWO_N20; + case 11: + // --- It is string 11 --------------------------------------------- + if (flag_almanac_str_10 == true) + { + gnav_almanac[i_alm_satellite_slot_number - 1].d_omega_n_A = static_cast(read_navigation_signed(string_bits, OMEGA_N_A)) * TWO_N15 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_t_lambda_n_A = static_cast(read_navigation_unsigned(string_bits, T_LAMBDA_N_A)) * TWO_N5; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A = static_cast(read_navigation_signed(string_bits, DELTA_T_N_A)) * TWO_N9; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A_dot = static_cast(read_navigation_signed(string_bits, DELTA_T_DOT_N_A)) * TWO_N14; + gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A = static_cast(read_navigation_unsigned(string_bits, H_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_l_n = static_cast(read_navigation_bool(string_bits, ALM_L_N)); - flag_almanac_str_12 = true; + // Set satellite information for redundancy purposes + if (gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A > 24) + { + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_freq_channel = gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A - 32.0; + } + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_slot_number = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_PRN = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; - break; + flag_almanac_str_11 = true; + } + break; - case 13: - // --- It is string 13 --------------------------------------------- - if (flag_almanac_str_12 == true) - { - gnav_almanac[i_alm_satellite_slot_number - 1].d_omega_n_A = static_cast(read_navigation_signed(string_bits, OMEGA_N_A)) * TWO_N15 * GLONASS_PI; - gnav_almanac[i_alm_satellite_slot_number - 1].d_t_lambda_n_A = static_cast(read_navigation_unsigned(string_bits, T_LAMBDA_N_A)) * TWO_N5; - gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A = static_cast(read_navigation_signed(string_bits, DELTA_T_N_A)) * TWO_N9; - gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A_dot = static_cast(read_navigation_signed(string_bits, DELTA_T_DOT_N_A)) * TWO_N14; - gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A = static_cast(read_navigation_unsigned(string_bits, H_N_A)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_l_n = static_cast(read_navigation_bool(string_bits, ALM_L_N)); + case 12: + // --- It is string 12 --------------------------------------------- + i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); + d_frame_ID = get_frame_number(i_alm_satellite_slot_number); + // Make sure a valid frame_ID or satellite slot number is returned + if(d_frame_ID == 0) + return 0; + gnav_almanac[i_alm_satellite_slot_number - 1].d_C_n = static_cast(read_navigation_bool(string_bits, C_N)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_M_n_A = static_cast(read_navigation_unsigned(string_bits, M_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A = static_cast(read_navigation_unsigned(string_bits, n_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_tau_n_A = static_cast(read_navigation_unsigned(string_bits, TAU_N_A)) * TWO_N18; + gnav_almanac[i_alm_satellite_slot_number - 1].d_lambda_n_A = static_cast(read_navigation_signed(string_bits, LAMBDA_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_i_n_A = static_cast(read_navigation_signed(string_bits, DELTA_I_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_epsilon_n_A = static_cast(read_navigation_unsigned(string_bits, EPSILON_N_A)) * TWO_N20; - // Set satellite information for redundancy purposes - if (gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A > 24) - { - gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_freq_channel = gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A - 32.0; - } - gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_slot_number = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; - gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_PRN = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + flag_almanac_str_12 = true; - flag_almanac_str_13 = true; - } - break; - case 14: - // --- It is string 14 --------------------------------------------- - if (d_frame_ID == 5) - { - gnav_utc_model.d_B1 = static_cast(read_navigation_unsigned(string_bits, B1)); - gnav_utc_model.d_B2 = static_cast(read_navigation_unsigned(string_bits, B2)); - } - else - { - i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); - d_frame_ID = get_frame_number(i_alm_satellite_slot_number); - // Make sure a valid frame_ID or satellite slot number is returned - if(d_frame_ID == 0) - return 0; - gnav_almanac[i_alm_satellite_slot_number - 1].d_C_n = static_cast(read_navigation_bool(string_bits, C_N)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_M_n_A = static_cast(read_navigation_unsigned(string_bits, M_N_A)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A = static_cast(read_navigation_unsigned(string_bits, n_A)); - gnav_almanac[i_alm_satellite_slot_number - 1].d_tau_n_A = static_cast(read_navigation_unsigned(string_bits, TAU_N_A)) * TWO_N18; - gnav_almanac[i_alm_satellite_slot_number - 1].d_lambda_n_A = static_cast(read_navigation_signed(string_bits, LAMBDA_N_A)) * TWO_N20 * GLONASS_PI; - gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_i_n_A = static_cast(read_navigation_signed(string_bits, DELTA_I_N_A)) * TWO_N20 * GLONASS_PI; - gnav_almanac[i_alm_satellite_slot_number - 1].d_epsilon_n_A = static_cast(read_navigation_unsigned(string_bits, EPSILON_N_A)) * TWO_N20; + break; - flag_almanac_str_14 = true; - } - break; + case 13: + // --- It is string 13 --------------------------------------------- + if (flag_almanac_str_12 == true) + { + gnav_almanac[i_alm_satellite_slot_number - 1].d_omega_n_A = static_cast(read_navigation_signed(string_bits, OMEGA_N_A)) * TWO_N15 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_t_lambda_n_A = static_cast(read_navigation_unsigned(string_bits, T_LAMBDA_N_A)) * TWO_N5; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A = static_cast(read_navigation_signed(string_bits, DELTA_T_N_A)) * TWO_N9; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A_dot = static_cast(read_navigation_signed(string_bits, DELTA_T_DOT_N_A)) * TWO_N14; + gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A = static_cast(read_navigation_unsigned(string_bits, H_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_l_n = static_cast(read_navigation_bool(string_bits, ALM_L_N)); - case 15: - // --- It is string 15 ---------------------------------------------- - if (d_frame_ID != 5 and flag_almanac_str_14 == true) { + // Set satellite information for redundancy purposes + if (gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A > 24) + { + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_freq_channel = gnav_almanac[i_alm_satellite_slot_number - 1].d_H_n_A - 32.0; + } + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_slot_number = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_PRN = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; + + flag_almanac_str_13 = true; + } + break; + + case 14: + // --- It is string 14 --------------------------------------------- + if (d_frame_ID == 5) + { + gnav_utc_model.d_B1 = static_cast(read_navigation_unsigned(string_bits, B1)); + gnav_utc_model.d_B2 = static_cast(read_navigation_unsigned(string_bits, B2)); + } + else + { + i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); + d_frame_ID = get_frame_number(i_alm_satellite_slot_number); + // Make sure a valid frame_ID or satellite slot number is returned + if(d_frame_ID == 0) + return 0; + gnav_almanac[i_alm_satellite_slot_number - 1].d_C_n = static_cast(read_navigation_bool(string_bits, C_N)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_M_n_A = static_cast(read_navigation_unsigned(string_bits, M_N_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A = static_cast(read_navigation_unsigned(string_bits, n_A)); + gnav_almanac[i_alm_satellite_slot_number - 1].d_tau_n_A = static_cast(read_navigation_unsigned(string_bits, TAU_N_A)) * TWO_N18; + gnav_almanac[i_alm_satellite_slot_number - 1].d_lambda_n_A = static_cast(read_navigation_signed(string_bits, LAMBDA_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_i_n_A = static_cast(read_navigation_signed(string_bits, DELTA_I_N_A)) * TWO_N20 * GLONASS_PI; + gnav_almanac[i_alm_satellite_slot_number - 1].d_epsilon_n_A = static_cast(read_navigation_unsigned(string_bits, EPSILON_N_A)) * TWO_N20; + + flag_almanac_str_14 = true; + } + break; + + case 15: + // --- It is string 15 ---------------------------------------------- + if (d_frame_ID != 5 and flag_almanac_str_14 == true) { gnav_almanac[i_alm_satellite_slot_number - 1].d_omega_n_A = static_cast(read_navigation_signed(string_bits, OMEGA_N_A)) * TWO_N15 * GLONASS_PI; gnav_almanac[i_alm_satellite_slot_number - 1].d_t_lambda_n_A = static_cast(read_navigation_unsigned(string_bits, T_LAMBDA_N_A)) * TWO_N5; gnav_almanac[i_alm_satellite_slot_number - 1].d_Delta_T_n_A = static_cast(read_navigation_signed(string_bits, DELTA_T_N_A)) * TWO_N9; @@ -668,14 +668,14 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) gnav_almanac[i_alm_satellite_slot_number - 1].i_satellite_PRN = gnav_almanac[i_alm_satellite_slot_number - 1].d_n_A; flag_almanac_str_15 = true; - } - break; - default: - LOG(INFO) << "GLONASS GNAV: Invalid String ID of received. Received " << d_string_ID - << ", but acceptable range is from 1-15"; + } + break; + default: + LOG(INFO) << "GLONASS GNAV: Invalid String ID of received. Received " << d_string_ID + << ", but acceptable range is from 1-15"; - break; - } // switch string ID ... + break; + } // switch string ID return d_string_ID; } @@ -704,8 +704,8 @@ bool Glonass_Gnav_Navigation_Message::have_new_ephemeris() //Check if we have a bool new_eph = false; // We need to make sure we have received the ephemeris info plus the time info if ((flag_ephemeris_str_1 == true) and (flag_ephemeris_str_2 == true) and - (flag_ephemeris_str_3 == true) and (flag_ephemeris_str_4 == true) and - (flag_utc_model_str_5 == true)) + (flag_ephemeris_str_3 == true) and (flag_ephemeris_str_4 == true) and + (flag_utc_model_str_5 == true)) { if(d_previous_tb != gnav_ephemeris.d_t_b) { @@ -729,7 +729,7 @@ bool Glonass_Gnav_Navigation_Message::have_new_utc_model() // Check if we have a { if (flag_utc_model_str_5 == true) { - flag_utc_model_str_5 = false; // clear the flag + flag_utc_model_str_5 = false; // clear the flag return true; } else diff --git a/src/core/system_parameters/glonass_gnav_navigation_message.h b/src/core/system_parameters/glonass_gnav_navigation_message.h index 159a212f2..6aef9ad51 100644 --- a/src/core/system_parameters/glonass_gnav_navigation_message.h +++ b/src/core/system_parameters/glonass_gnav_navigation_message.h @@ -36,10 +36,6 @@ #include -#include -#include -#include -#include #include "GLONASS_L1_CA.h" #include "glonass_gnav_ephemeris.h" #include "glonass_gnav_almanac.h" @@ -70,16 +66,16 @@ public: Glonass_Gnav_Ephemeris gnav_ephemeris; //!< Ephemeris information decoded Glonass_Gnav_Utc_Model gnav_utc_model; //!< UTC model information - Glonass_Gnav_Almanac gnav_almanac[GLONASS_L1_CA_NBR_SATS]; //!< Almanac information for all 24 satellites + Glonass_Gnav_Almanac gnav_almanac[GLONASS_L1_CA_NBR_SATS]; //!< Almanac information for all 24 satellites - //!< Ephmeris Flags and control variables + // Ephemeris Flags and control variables bool flag_all_ephemeris; //!< Flag indicating that all strings containing ephemeris have been received bool flag_ephemeris_str_1; //!< Flag indicating that ephemeris 1/4 (string 1) have been received bool flag_ephemeris_str_2; //!< Flag indicating that ephemeris 2/4 (string 2) have been received bool flag_ephemeris_str_3; //!< Flag indicating that ephemeris 3/4 (string 3) have been received bool flag_ephemeris_str_4; //!< Flag indicating that ephemeris 4/4 (string 4) have been received - //!< Almanac Flags + // Almanac Flags bool flag_all_almanac; //!< Flag indicating that all almanac have been received bool flag_almanac_str_6; //!< Flag indicating that almanac of string 6 have been received bool flag_almanac_str_7; //!< Flag indicating that almanac of string 7 have been received @@ -91,23 +87,22 @@ public: bool flag_almanac_str_13; //!< Flag indicating that almanac of string 13 have been received bool flag_almanac_str_14; //!< Flag indicating that almanac of string 14 have been received bool flag_almanac_str_15; //!< Flag indicating that almanac of string 15 have been received - unsigned int i_alm_satellite_slot_number; //!< SV Orbit Slot Number + unsigned int i_alm_satellite_slot_number; //!< SV Orbit Slot Number - //!< UTC and System Clocks Flags - bool flag_utc_model_valid; //!< If set, it indicates that the UTC model parameters are filled - bool flag_utc_model_str_5; //!< Clock info send in string 5 of navigation data - bool flag_utc_model_str_15; //!< Clock info send in string 15 of frame 5 of navigation data + // UTC and System Clocks Flags + bool flag_utc_model_valid; //!< If set, it indicates that the UTC model parameters are filled + bool flag_utc_model_str_5; //!< Clock info send in string 5 of navigation data + bool flag_utc_model_str_15; //!< Clock info send in string 15 of frame 5 of navigation data bool flag_TOW_set; //!< Flag indicating when the TOW has been set bool flag_TOW_new; //!< Flag indicating when a new TOW has been computed - double d_satClkCorr; //!< Satellite clock error - double d_dtr; //!< Relativistic clock correction term - double d_satClkDrift; //!< Satellite clock drift - - double d_previous_tb; //!< Previous iode for the Glonass_Gnav_Ephemeris object. Used to determine when new data arrives - double d_previous_Na[GLONASS_L1_CA_NBR_SATS]; //!< Previous time for almanac of the Glonass_Gnav_Almanac object + double d_satClkCorr; //!< Satellite clock error + double d_dtr; //!< Relativistic clock correction term + double d_satClkDrift; //!< Satellite clock drift + double d_previous_tb; //!< Previous iode for the Glonass_Gnav_Ephemeris object. Used to determine when new data arrives + double d_previous_Na[GLONASS_L1_CA_NBR_SATS]; //!< Previous time for almanac of the Glonass_Gnav_Almanac object /*! * \brief Compute CRC for GLONASS GNAV strings @@ -116,10 +111,10 @@ public: bool CRC_test(std::bitset bits); /*! - * \brief Computes the frame number being decoded given the satellite slot number - * \param satellite_slot_number [in] Satellite slot number identifier - * \returns Frame number being decoded, 0 if operation was not successful. - */ + * \brief Computes the frame number being decoded given the satellite slot number + * \param satellite_slot_number [in] Satellite slot number identifier + * \returns Frame number being decoded, 0 if operation was not successful. + */ unsigned int get_frame_number(unsigned int satellite_slot_number); /*! From 2f8be49d0a47fca8a63098ff42c3194c703d8e14 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 26 Jan 2018 12:49:04 +0100 Subject: [PATCH 87/96] Fix indentation --- src/core/receiver/gnss_block_factory.cc | 224 ++++++++++++------------ 1 file changed, 110 insertions(+), 114 deletions(-) diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 6efb3ec0e..ac72a0549 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -53,7 +53,6 @@ #include "two_bit_packed_file_signal_source.h" #include "labsat_signal_source.h" #include "channel.h" - #include "signal_conditioner.h" #include "array_signal_conditioner.h" #include "byte_to_short.h" @@ -236,7 +235,6 @@ std::unique_ptr GNSSBlockFactory::GetSignalConditioner( } - std::unique_ptr GNSSBlockFactory::GetObservables(std::shared_ptr configuration) { std::string default_implementation = "Hybrid_Observables"; @@ -252,7 +250,6 @@ std::unique_ptr GNSSBlockFactory::GetObservables(std::shared } - std::unique_ptr GNSSBlockFactory::GetPVT(std::shared_ptr configuration) { std::string default_implementation = "RTKLIB_PVT"; @@ -336,13 +333,13 @@ std::unique_ptr GNSSBlockFactory::GetChannel_1C( return channel_; } + //********* GPS L2C (M) CHANNEL ***************** std::unique_ptr GNSSBlockFactory::GetChannel_2S( std::shared_ptr configuration, std::string acq, std::string trk, std::string tlm, int channel, gr::msg_queue::sptr queue) { - LOG(INFO) << "Instantiating Channel " << channel << " with Acquisition Implementation: " << acq << ", Tracking Implementation: " << trk << ", Telemetry Decoder implementation: " << tlm; std::string aux = configuration->property("Acquisition_2S" + boost::lexical_cast(channel) + ".implementation", std::string("W")); @@ -401,6 +398,7 @@ std::unique_ptr GNSSBlockFactory::GetChannel_2S( return channel_; } + //********* GALILEO E1 B CHANNEL ***************** std::unique_ptr GNSSBlockFactory::GetChannel_1B( std::shared_ptr configuration, @@ -468,6 +466,7 @@ std::unique_ptr GNSSBlockFactory::GetChannel_1B( return channel_; } + //********* GALILEO E5a CHANNEL ***************** std::unique_ptr GNSSBlockFactory::GetChannel_5X( std::shared_ptr configuration, @@ -535,6 +534,7 @@ std::unique_ptr GNSSBlockFactory::GetChannel_5X( return channel_; } + //********* GLONASS L1 C/A CHANNEL ***************** std::unique_ptr GNSSBlockFactory::GetChannel_1G( std::shared_ptr configuration, @@ -699,7 +699,6 @@ std::unique_ptr>> GNSSBlockFacto std::unique_ptr>> channels(new std::vector>(total_channels)); //**************** GPS L1 C/A CHANNELS ********************** - LOG(INFO) << "Getting " << Channels_1C_count << " GPS L1 C/A channels"; acquisition_implementation = configuration->property("Acquisition_1C.implementation", default_implementation); tracking_implementation = configuration->property("Tracking_1C.implementation", default_implementation); @@ -709,24 +708,24 @@ std::unique_ptr>> GNSSBlockFacto { //(i.e. Acquisition_1C0.implementation=xxxx) std::string acquisition_implementation_specific = configuration->property( - "Acquisition_1C" + boost::lexical_cast(channel_absolute_id) + ".implementation", - acquisition_implementation); + "Acquisition_1C" + boost::lexical_cast(channel_absolute_id) + ".implementation", + acquisition_implementation); //(i.e. Tracking_1C0.implementation=xxxx) std::string tracking_implementation_specific = configuration->property( - "Tracking_1C" + boost::lexical_cast(channel_absolute_id) + ".implementation", - tracking_implementation); + "Tracking_1C" + boost::lexical_cast(channel_absolute_id) + ".implementation", + tracking_implementation); std::string telemetry_decoder_implementation_specific = configuration->property( - "TelemetryDecoder_1C" + boost::lexical_cast(channel_absolute_id) + ".implementation", - telemetry_decoder_implementation); + "TelemetryDecoder_1C" + boost::lexical_cast(channel_absolute_id) + ".implementation", + telemetry_decoder_implementation); // Push back the channel to the vector of channels - channels->at(channel_absolute_id) = std::move(GetChannel_1C(configuration, - acquisition_implementation_specific, - tracking_implementation_specific, - telemetry_decoder_implementation_specific, - channel_absolute_id, - queue)); - channel_absolute_id++; + channels->at(channel_absolute_id) = std::move(GetChannel_1C(configuration, + acquisition_implementation_specific, + tracking_implementation_specific, + telemetry_decoder_implementation_specific, + channel_absolute_id, + queue)); + channel_absolute_id++; } //**************** GPS L2C (M) CHANNELS ********************** @@ -738,25 +737,26 @@ std::unique_ptr>> GNSSBlockFacto { //(i.e. Acquisition_1C0.implementation=xxxx) std::string acquisition_implementation_specific = configuration->property( - "Acquisition_2S" + boost::lexical_cast(channel_absolute_id) + ".implementation", - acquisition_implementation); + "Acquisition_2S" + boost::lexical_cast(channel_absolute_id) + ".implementation", + acquisition_implementation); //(i.e. Tracking_1C0.implementation=xxxx) std::string tracking_implementation_specific = configuration->property( - "Tracking_2S" + boost::lexical_cast(channel_absolute_id) + ".implementation", - tracking_implementation); + "Tracking_2S" + boost::lexical_cast(channel_absolute_id) + ".implementation", + tracking_implementation); std::string telemetry_decoder_implementation_specific = configuration->property( - "TelemetryDecoder_2S" + boost::lexical_cast(channel_absolute_id) + ".implementation", - telemetry_decoder_implementation); + "TelemetryDecoder_2S" + boost::lexical_cast(channel_absolute_id) + ".implementation", + telemetry_decoder_implementation); // Push back the channel to the vector of channels - channels->at(channel_absolute_id) = std::move(GetChannel_2S(configuration, - acquisition_implementation_specific, - tracking_implementation_specific, - telemetry_decoder_implementation_specific, - channel_absolute_id, - queue)); - channel_absolute_id++; + channels->at(channel_absolute_id) = std::move(GetChannel_2S(configuration, + acquisition_implementation_specific, + tracking_implementation_specific, + telemetry_decoder_implementation_specific, + channel_absolute_id, + queue)); + channel_absolute_id++; } + //**************** GPS L5 CHANNELS ********************** LOG(INFO)<< "Getting " << Channels_L5_count << " GPS L5 channels"; tracking_implementation = configuration->property("Tracking_L5.implementation", default_implementation); @@ -766,85 +766,83 @@ std::unique_ptr>> GNSSBlockFacto { //(i.e. Acquisition_1C0.implementation=xxxx) std::string acquisition_implementation_specific = configuration->property( - "Acquisition_L5" + boost::lexical_cast(channel_absolute_id) + ".implementation", - acquisition_implementation); + "Acquisition_L5" + boost::lexical_cast(channel_absolute_id) + ".implementation", + acquisition_implementation); //(i.e. Tracking_1C0.implementation=xxxx) std::string tracking_implementation_specific = configuration->property( - "Tracking_L5" + boost::lexical_cast(channel_absolute_id) + ".implementation", - tracking_implementation); + "Tracking_L5" + boost::lexical_cast(channel_absolute_id) + ".implementation", + tracking_implementation); std::string telemetry_decoder_implementation_specific = configuration->property( - "TelemetryDecoder_L5" + boost::lexical_cast(channel_absolute_id) + ".implementation", - telemetry_decoder_implementation); + "TelemetryDecoder_L5" + boost::lexical_cast(channel_absolute_id) + ".implementation", + telemetry_decoder_implementation); // Push back the channel to the vector of channels - channels->at(channel_absolute_id) = std::move(GetChannel_L5(configuration, - acquisition_implementation_specific, - tracking_implementation_specific, - telemetry_decoder_implementation_specific, - channel_absolute_id, - queue)); - channel_absolute_id++; + channels->at(channel_absolute_id) = std::move(GetChannel_L5(configuration, + acquisition_implementation_specific, + tracking_implementation_specific, + telemetry_decoder_implementation_specific, + channel_absolute_id, + queue)); + channel_absolute_id++; } + //**************** GALILEO E1 B (I/NAV OS) CHANNELS ********************** - LOG(INFO) << "Getting " << Channels_1B_count << " GALILEO E1 B (I/NAV OS) channels"; - tracking_implementation = configuration->property("Tracking_1B.implementation", default_implementation); - telemetry_decoder_implementation = configuration->property("TelemetryDecoder_1B.implementation", default_implementation); - acquisition_implementation = configuration->property("Acquisition_1B.implementation", default_implementation); - for (unsigned int i = 0; i < Channels_1B_count; i++) - { - //(i.e. Acquisition_1C0.implementation=xxxx) - std::string acquisition_implementation_specific = configuration->property( - "Acquisition_1B" + boost::lexical_cast(channel_absolute_id) + ".implementation", - acquisition_implementation); - //(i.e. Tracking_1C0.implementation=xxxx) - std::string tracking_implementation_specific = configuration->property( - "Tracking_1B" + boost::lexical_cast(channel_absolute_id) + ".implementation", - tracking_implementation); - std::string telemetry_decoder_implementation_specific = configuration->property( - "TelemetryDecoder_1B" + boost::lexical_cast(channel_absolute_id) + ".implementation", - telemetry_decoder_implementation); - - // Push back the channel to the vector of channels - channels->at(channel_absolute_id) = std::move(GetChannel_1B(configuration, - acquisition_implementation_specific, - tracking_implementation_specific, - telemetry_decoder_implementation_specific, - channel_absolute_id, - queue)); - channel_absolute_id++; - } + tracking_implementation = configuration->property("Tracking_1B.implementation", default_implementation); + telemetry_decoder_implementation = configuration->property("TelemetryDecoder_1B.implementation", default_implementation); + acquisition_implementation = configuration->property("Acquisition_1B.implementation", default_implementation); + for (unsigned int i = 0; i < Channels_1B_count; i++) + { + //(i.e. Acquisition_1C0.implementation=xxxx) + std::string acquisition_implementation_specific = configuration->property( + "Acquisition_1B" + boost::lexical_cast(channel_absolute_id) + ".implementation", + acquisition_implementation); + //(i.e. Tracking_1C0.implementation=xxxx) + std::string tracking_implementation_specific = configuration->property( + "Tracking_1B" + boost::lexical_cast(channel_absolute_id) + ".implementation", + tracking_implementation); + std::string telemetry_decoder_implementation_specific = configuration->property( + "TelemetryDecoder_1B" + boost::lexical_cast(channel_absolute_id) + ".implementation", + telemetry_decoder_implementation); + // Push back the channel to the vector of channels + channels->at(channel_absolute_id) = std::move(GetChannel_1B(configuration, + acquisition_implementation_specific, + tracking_implementation_specific, + telemetry_decoder_implementation_specific, + channel_absolute_id, + queue)); + channel_absolute_id++; + } //**************** GALILEO E5a I (F/NAV OS) CHANNELS ********************** LOG(INFO) << "Getting " << Channels_5X_count << " GALILEO E5a I (F/NAV OS) channels"; - tracking_implementation = configuration->property("Tracking_5X.implementation", default_implementation); - telemetry_decoder_implementation = configuration->property("TelemetryDecoder_5X.implementation", default_implementation); - acquisition_implementation = configuration->property("Acquisition_5X.implementation", default_implementation); - for (unsigned int i = 0; i < Channels_5X_count; i++) - { - //(i.e. Acquisition_1C0.implementation=xxxx) - std::string acquisition_implementation_specific = configuration->property( - "Acquisition_5X" + boost::lexical_cast(channel_absolute_id) + ".implementation", - acquisition_implementation); - //(i.e. Tracking_1C0.implementation=xxxx) - std::string tracking_implementation_specific = configuration->property( - "Tracking_5X" + boost::lexical_cast(channel_absolute_id) + ".implementation", - tracking_implementation); - std::string telemetry_decoder_implementation_specific = configuration->property( - "TelemetryDecoder_5X" + boost::lexical_cast(channel_absolute_id) + ".implementation", - telemetry_decoder_implementation); - - // Push back the channel to the vector of channels - channels->at(channel_absolute_id) = std::move(GetChannel_5X(configuration, - acquisition_implementation_specific, - tracking_implementation_specific, - telemetry_decoder_implementation_specific, - channel_absolute_id, - queue)); - channel_absolute_id++; - } + tracking_implementation = configuration->property("Tracking_5X.implementation", default_implementation); + telemetry_decoder_implementation = configuration->property("TelemetryDecoder_5X.implementation", default_implementation); + acquisition_implementation = configuration->property("Acquisition_5X.implementation", default_implementation); + for (unsigned int i = 0; i < Channels_5X_count; i++) + { + //(i.e. Acquisition_1C0.implementation=xxxx) + std::string acquisition_implementation_specific = configuration->property( + "Acquisition_5X" + boost::lexical_cast(channel_absolute_id) + ".implementation", + acquisition_implementation); + //(i.e. Tracking_1C0.implementation=xxxx) + std::string tracking_implementation_specific = configuration->property( + "Tracking_5X" + boost::lexical_cast(channel_absolute_id) + ".implementation", + tracking_implementation); + std::string telemetry_decoder_implementation_specific = configuration->property( + "TelemetryDecoder_5X" + boost::lexical_cast(channel_absolute_id) + ".implementation", + telemetry_decoder_implementation); + // Push back the channel to the vector of channels + channels->at(channel_absolute_id) = std::move(GetChannel_5X(configuration, + acquisition_implementation_specific, + tracking_implementation_specific, + telemetry_decoder_implementation_specific, + channel_absolute_id, + queue)); + channel_absolute_id++; + } //**************** GLONASS L1 C/A CHANNELS ********************** LOG(INFO) << "Getting " << Channels_1G_count << " GLONASS L1 C/A channels"; @@ -856,29 +854,30 @@ std::unique_ptr>> GNSSBlockFacto { //(i.e. Acquisition_1G0.implementation=xxxx) std::string acquisition_implementation_specific = configuration->property( - "Acquisition_1G" + boost::lexical_cast(channel_absolute_id) + ".implementation", - acquisition_implementation); + "Acquisition_1G" + boost::lexical_cast(channel_absolute_id) + ".implementation", + acquisition_implementation); //(i.e. Tracking_1G0.implementation=xxxx) std::string tracking_implementation_specific = configuration->property( - "Tracking_1G" + boost::lexical_cast(channel_absolute_id) + ".implementation", - tracking_implementation); + "Tracking_1G" + boost::lexical_cast(channel_absolute_id) + ".implementation", + tracking_implementation); std::string telemetry_decoder_implementation_specific = configuration->property( - "TelemetryDecoder_1G" + boost::lexical_cast(channel_absolute_id) + ".implementation", - telemetry_decoder_implementation); + "TelemetryDecoder_1G" + boost::lexical_cast(channel_absolute_id) + ".implementation", + telemetry_decoder_implementation); // Push back the channel to the vector of channels - channels->at(channel_absolute_id) = std::move(GetChannel_1G(configuration, - acquisition_implementation_specific, - tracking_implementation_specific, - telemetry_decoder_implementation_specific, - channel_absolute_id, - queue)); - channel_absolute_id++; + channels->at(channel_absolute_id) = std::move(GetChannel_1G(configuration, + acquisition_implementation_specific, + tracking_implementation_specific, + telemetry_decoder_implementation_specific, + channel_absolute_id, + queue)); + channel_absolute_id++; } return channels; } + /* * Returns the block with the required configuration and implementation * @@ -1163,7 +1162,6 @@ std::unique_ptr GNSSBlockFactory::GetBlock( block = std::move(block_); } - // RESAMPLER ------------------------------------------------------------------- else if (implementation.compare("Direct_Resampler") == 0) { @@ -1277,9 +1275,6 @@ std::unique_ptr GNSSBlockFactory::GetBlock( block = std::move(block_); } - - - // TRACKING BLOCKS ------------------------------------------------------------- else if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking") == 0) { @@ -1410,6 +1405,7 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams)); block = std::move(block_); } + // PVT ------------------------------------------------------------------------- else if ((implementation.compare("RTKLIB_PVT") == 0) || (implementation.compare("GPS_L1_CA_PVT") == 0) || (implementation.compare("Galileo_E1_PVT") == 0) || (implementation.compare("Hybrid_PVT") == 0)) { From a6e292d532aac0e344e1e55db07ea4a91a3855a6 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 26 Jan 2018 13:02:23 +0100 Subject: [PATCH 88/96] Remove unrequired includes --- .../gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc index 22aa23538..230493060 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc @@ -32,15 +32,9 @@ #include "glonass_l1_ca_telemetry_decoder_cc.h" -#include -#include -#include #include #include #include -#include "control_message_factory.h" -#include "gnss_synchro.h" -#include "convolutional.h" #define CRC_ERROR_LIMIT 6 From d12aa2858903499c5b55009c70bd7bbd5da26d12 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 26 Jan 2018 13:15:56 +0100 Subject: [PATCH 89/96] Replace C-style casts by C++ style --- .../glonass_l1_ca_telemetry_decoder_cc.cc | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc index 230493060..e3404a458 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc @@ -72,10 +72,10 @@ glonass_l1_ca_telemetry_decoder_cc::glonass_l1_ca_telemetry_decoder_cc( // Since preamble rate is different than navigation data rate we use a constant d_symbols_per_preamble = GLONASS_GNAV_PREAMBLE_LENGTH_SYMBOLS; - memcpy((unsigned short int*)this->d_preambles_bits, (unsigned short int*)preambles_bits, GLONASS_GNAV_PREAMBLE_LENGTH_BITS*sizeof(unsigned short int)); + memcpy(static_cast(this->d_preambles_bits), static_cast(preambles_bits), GLONASS_GNAV_PREAMBLE_LENGTH_BITS * sizeof(unsigned short int)); // preamble bits to sampled symbols - d_preambles_symbols = (signed int*)malloc(sizeof(signed int) * d_symbols_per_preamble); + d_preambles_symbols = static_cast(malloc(sizeof(signed int) * d_symbols_per_preamble)); int n = 0; for (int i = 0; i < GLONASS_GNAV_PREAMBLE_LENGTH_BITS; i++) { @@ -229,8 +229,8 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib int corr_value = 0; int preamble_diff = 0; - Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0]; - const Gnss_Synchro **in = (const Gnss_Synchro **) &input_items[0]; //Get the input samples pointer + Gnss_Synchro **out = reinterpret_cast(&output_items[0]); // Get the output buffer pointer + const Gnss_Synchro **in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer Gnss_Synchro current_symbol; //structure to save the synchronization information and send the output object to the next block //1. Copy the current tracking output @@ -240,7 +240,7 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib consume_each(1); d_flag_preamble = false; - unsigned int required_symbols=GLONASS_GNAV_STRING_SYMBOLS; + unsigned int required_symbols = GLONASS_GNAV_STRING_SYMBOLS; if (d_symbol_history.size()>required_symbols) { @@ -334,7 +334,7 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib { d_flag_frame_sync = true; DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at " - << d_symbol_history.at(0).Tracking_sample_counter << " [samples]"; + << d_symbol_history.at(0).Tracking_sample_counter << " [samples]"; } } else @@ -383,7 +383,7 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib current_symbol.PRN = this->d_satellite.get_PRN(); current_symbol.TOW_at_current_symbol_s = d_TOW_at_current_symbol; - current_symbol.TOW_at_current_symbol_s -=delta_t; //Galileo to GPS TOW + current_symbol.TOW_at_current_symbol_s -= delta_t; // Galileo to GPS TOW if(d_dump == true) { @@ -393,11 +393,11 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib double tmp_double; unsigned long int tmp_ulong_int; tmp_double = d_TOW_at_current_symbol; - d_dump_file.write((char*)&tmp_double, sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_ulong_int = current_symbol.Tracking_sample_counter; - d_dump_file.write((char*)&tmp_ulong_int, sizeof(unsigned long int)); + d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(unsigned long int)); tmp_double = 0; - d_dump_file.write((char*)&tmp_double, sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); } catch (const std::ifstream::failure & e) { @@ -445,7 +445,7 @@ void glonass_l1_ca_telemetry_decoder_cc::set_channel(int channel) } catch (const std::ifstream::failure& e) { - LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); + LOG(WARNING) << "channel " << d_channel << ": exception opening Glonass TLM dump file. " << e.what(); } } } From 2a20976b0c7019f6c14ea26cc52d7e98901bf74d Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 26 Jan 2018 13:40:52 +0100 Subject: [PATCH 90/96] Remove big sample file and move GlonassL1CaPcpsAcquisitionTest to extra unit tests --- src/tests/CMakeLists.txt | 9 +++++++-- .../Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat | Bin 1994068 -> 0 bytes src/tests/test_main.cc | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) delete mode 100644 src/tests/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 0c86b84a5..3394d8a2e 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -260,8 +260,15 @@ if(ENABLE_UNIT_TESTING_EXTRA) SHOW_PROGRESS EXPECTED_HASH MD5=a6fcbefe155137945d3c33c5ef7bd0f9 ) endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples/gps_l2c_m_prn7_5msps.dat) + if(NOT EXISTS ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat) + message(STATUS "Downloading some data files for testing...") + file(DOWNLOAD https://sourceforge.net/projects/gnss-sdr/files/data/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat + SHOW_PROGRESS + EXPECTED_HASH MD5=ffb72fc63c116be58d5e5ccb1daaed3a ) + endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat) if(ENABLE_INSTALL_TESTS) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/signal_samples/gps_l2c_m_prn7_5msps.dat DESTINATION share/gnss-sdr/signal_samples) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat DESTINATION share/gnss-sdr/signal_samples) endif(ENABLE_INSTALL_TESTS) endif(ENABLE_UNIT_TESTING_EXTRA) @@ -269,14 +276,12 @@ if(ENABLE_INSTALL_TESTS) install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GSoC_CTTC_capture_2012_07_26_4Msps_4ms.dat DESTINATION share/gnss-sdr/signal_samples) install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/Galileo_E1_ID_1_Fs_4Msps_8ms.dat DESTINATION share/gnss-sdr/signal_samples) install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat DESTINATION share/gnss-sdr/signal_samples) - install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat DESTINATION share/gnss-sdr/signal_samples) install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin DESTINATION share/gnss-sdr/signal_samples) add_definitions(-DTEST_PATH="${CMAKE_INSTALL_PREFIX}/share/gnss-sdr/") else(ENABLE_INSTALL_TESTS) file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GSoC_CTTC_capture_2012_07_26_4Msps_4ms.dat DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/Galileo_E1_ID_1_Fs_4Msps_8ms.dat DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) - file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) add_definitions(-DTEST_PATH="${CMAKE_SOURCE_DIR}/thirdparty/") endif(ENABLE_INSTALL_TESTS) diff --git a/src/tests/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat b/src/tests/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat deleted file mode 100644 index 8d7b27c2543daf5f94bb45fc6bee9707d85deded..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1994068 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 XRP(mSnH$NdTFHf(||3W7IU?}TBO!jBdxz? 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�(Az@z#BkFjDV`eyuX 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 kr==W5I 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%0A^&TqAzB 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¥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 z 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

    d^7LyIim0d3f*)^8CEmGG7lq z&)IEXUY9{|_Cn2RNeV^#SO3{XlG4Pw;d#s({Dq4dC(mgYbyg zBf#VJ3Gf6ThrD!*&FdG?@p=YyyuJY)uYW+t>mktb`UrTuUV?cyUOxek*HZ*#eFZ$h zbI&rm#^&`G=y*K_^~mcp(DAwrbiAHpiJsSYz~l8Ev1R=SJYEk1kJpF56a1rXfNN}C zKN6j+Cqc*SOVIK96Lh>D1s$(Xfye7rg0g-E9x+U)F#WT1F0VV<>zbqn%5h$g zgpSuIQ4hRs2_3IzLdWZymhgDJ6Fgr36q|TG6g*xZ1y6A7r3VhLn_3xe__>0ja_UDCP3HFm$|5 zEGX;9(DAx5biB?i_e1fzGkClX4IZycJHqF6YVdg7T5Kg)?@M9V*u1U{9j|jk$LrqE z@w&L^h}X%XGsx@b;PZMq_`JRjKCicf&+G4kO0YuSEUvM6eI7bquZND;@6n!keIGhr z?}v`p|G{H_0Pxs9z>@1=e*y5=e*iqe8l68m#%BKl;fcQibnJfs9s4Cf$Nmb?vHt>i z?9U)P#r_T8vA+X&?Ee6sVAy|49AmS81nPtRC7@$J3PJI&fR6nwpkx0F)Cc=xfXDtB z;IY4kBYgJX08g-Fhu1Oe*Wom37vu`^Y4P`fj{QHNW4{pS*k1%X_8$R{{Yk)M{}S-n z-vm7NKM|hzp}74vZI58T6sOC+oUWjh&;BaVvHuEm?B62SOYH9g9s9osia!i^>>mRj z`^(7xPwYPfo?!M4Gc5M2acd2Y;|hw7{cS8k_P>FS{c^+>e;w%9f5+p^S`Hrj_Xtn1 zzYloq{{x=j^?J`O_6u?cblmO;3XlDTpkx0b=-8hKI`%h$j{T3oV}B&n7yBoH$Nox! z;=cr*U;>UklC;zyw`j|}j-Zs!{!XYr_J4wo{h^>^e^}t_`%{Un*uM%q_O}9$ z{jk7ezbxU2f0n!dO5q4&v)>kU?8gNi`*lIbeqYeB9~gA(7bYlvV&Jjg7^dimMxujr1Sm2aP* z@Y##6lEZ$EL(Yt7fEhyK+`wXDteFxC-egsSOyiWl--nSq&@jeFdcwYl} zyw3qV-uECpB^W1TmKfd-Va3YjYYU2w_ens<`zD~{{S?sgJ`3o0--RIYJ`C`9Uj}%* zPXqBvdEW+jg16rHb$CCAT_J8#TTpbo&jUK%_W>R619AAU;(a2}@xBr8cpr%zC*D^A z9`7>&kN2H`C%D1)io^R+>_L@ISc1ameJarLz7^5QeirC>p9^%n?*%;G2ZMUxeKFwi zJ{dvTHv=B;qXAFwMEZu7v3Z{j>Vfy&K*#%VpyPcymgsrk4s^VaM{L>G10L`50gw0n zfXDlQz!RK1{%x4Cd7lt;yl)6P-bVx-?=ymq_Z^8&@jfK*cwZ8DyiW-{-oGT*r+7aT zc!C3$R&tEZ`<>)C@%|_1cs~?$ykAQ0hwPt%j`vf6$NQ@s;q!hg@Ob}~*s>oBJi+H* z4>`u>{aVoR{w?TuKbPo;_jy6b`@f*m`@qb;Fw*|t)2mE{_*p>Z$u?G1#df%Vf2S|EfAnARBO7A07dS9W^ z`wY##L(=;YmEM;KJa#t7mHmowe{OR0zD0G|+s8<#J`e<;%UXfKra$he>*0Ch2{eW*?{0`#Q}&PtyB7N$&$Cy)RVheWJji z897{I>wTo8_mz^~XG(e>s?z&X%|2D7_pO?JtY%-U()(P2_RB!m*m@tV()(gb?~|pI z-acBT_th%B&(`d_CA|-q^uAoB_vr%PH3)Hyt@rUNy|0(_K3}sBSm}MiO79a^dfzbV zeZ;cA810Go8(VU}1v@YFb&bvYk)?gf{$#W>-mfe?;(g4}@&0B(+3ySEEcZD=62=`@}`3c;7g5yq_F8-e(RS?>k37#rx2~<9+FZ#QW62 z<9+Mk3640^)ZzW?5yP^Fx`I+J?{kNa_rF8O`{6Co^FDd#c;CF(iucij$NTER<9+tv z@xFWT1moVX7|r|ft-hNJx`LwPefrSxzJ2I;A3t=w&tG)1?;kvl0{|Y!1ptrZ1jzMC z+yL+dci$>&aXbOr?=t6GXXMioX8<~mI{+QWA&~naaSEX0xCP*G90N!A9M=Fmj&mTk z#619y;~;=1ct6)|$JiVv0XmMGAUcVs03F9!fR5uXK*wD$8jT|<2VwiFODk#9>?;0b0< z(>2D}9H&CgD~?+M9mlbNj^kWF$8j%2Cvh;q=n zbE7yO3UnMVMNs0WKxdHSs({aNR!|=tcLjWo!va3XWwAsjIPh0?o8z_EALpNs5#+;) z{ZwbnA zj-vw|$JKGzlz2PPaU348iR1Es$8mbV@8y7hHH_35t&6|A5c& zfWYVYK;U!yAVK1ILf~aodcpR?^JdR%l9>=o+kK?htB*EsB(%Kxq%f5Fo4N#7ATrcQ2&X?Q|#qqzOs4Xbvb9^=EIPRLD#AAbw@!I6R z5XWx=kK?(4$MM}9;d8t<@B|D6}AOM$MNBy<9Kn)2cBT`jdzx@IX<88h~xD^$MO51p(A{be+Zu7_0~5cjLq>8<-Ej8gpT7ULdS6xq2qXq&~f}l@HieLcpRS*JdW20 z9>;GKp2Tr>wotWcrTuL|Kd@Nf~bR4hJ66E-m&~aQ#u@%R=gpT81g2(YN!Q=Rt!jrg};Bg#H z@C4I-edQG0+0rdtY_laOJdV2w9mnB>j^lGe$8kHM<2at+aa_-E;d7i%@HpHIc}&U$Z|k((zbd z((!vq$MaP>zAvzlUC=eQj{j@o0h5joY~lwi9Z%TA7gjpnFzNWiq~j4Q9iJF@J5{J_ zY#qPY#4{!x-3GSc<0q4jr>t~*W#EcUh25PTce!Ay6ON!fk2)SR z>G;f~<2RFz=WOCTD;@8dbo^)1@t{e^hgO0mC;7M%H#*DfBtR*Dk{3^!5_|EbP5f!n z@u-!KPi^8=la60aI-WIgoNH-UN-%KC2Z!TdTUpZix`J|?<6@(oahz-Nb6jueIL^1A!~utngN3L{ya;4*yn|S6l)ANT>I^Ma7 ze{SNTla7yW;-!<0pRNS0;GC|pb$oTDj@#RU!n^!viywdULm5xtu;?R&@G$%pXIpv11ui(v93D4jQfbY2B|Z+YLVI`4wgc^H(=%Ro9$1L?dC zz>Bf3TawQqY5Aj$&g-Cbo(HA#J|G{2vcyV-!S<(IN?eK^b0zF2kCqsO6T`bI^PHB{2!$AfdD_>sBIZr=L=DhUj7i|6_NX+ z^Nof%$qlfZET&dMd|!4O6PMi`Cd%^7t;A)l+F*MbiNp+^T&|RCj(UT^V!DM z`DT>PKcjR$8k4Vvbp9HX&xUk<8>REzD4qX?bUqwlf|Mb)v30&2lRro4d^*UpBlV#3 z?~u;NLpnc?$=9QF{vOi#e1MfAgKWw3vo>J6rStum{69+P145o4DPQLgGWmo|ej%mv z4VnByO6MaY!B+=!+LEWJRfjl0DM#loQaYcJ$#-P(ACb<7Wbz{^oi9o0{7FjZQzF5m zD$#ryHR?^D5Me{8oTUsS&q zLAK5tW%5Xo&MRf|PMJJZr1Mgd&QoRbR+&6jO6RpAo#zU;Fp#>-=4$^LdfZ@1=CUFQxN=DV-n8HKD-^PQReXG-ToQ#wDI z$(KfwH|=Qse=MCpjdVUWlV6P_?;2OX$;W2$vysl%Mmm3+$>(PByP14%BzfN|EUIJa z{BNZ5!I}JUBzfbce4S5D>HKn}^UaaYKSw$roznT~)KJggg#Rh*UK0(s?1xe={H2DaX&QECa z6_U?Gb)|8QO$_-<_QE#t}P#7Y@O$kblykOc_5X}6KV2BDxF7?bY4l)c_x+4JE?RY zO5lnlIUHl_Je8#LR+7$RsdS!8rSo3?A9X%V()lq-=gU+&f2Pv;G=U8gZgq^U^KFvO zzezeDr_%X4mCoO3@_CZZ?`iUVlFt9BbUskvqKUCxW9xjOr1OW8&L?W}jVhggROx)A zr1O)K&R0r0f2q>>Oo6Sl$Mm4RR$VsyS%lfRX8K3CHDUX{-Os&qbBlONXPi#7RUmCh#%ELuFol{~Y# z+b(u=zFCuhmUKQ^()ntY&R?r^K3k>p+mg3qPX^8=I4 zAFOmfVWsm6lg>9xI{z@~e8fuUCk8fLQP?%M&R?u_K4X*b*yKM}Iv=vq`H_{*mrOc; zGI3sI^uwHI8Q-yj-_nG-#^yZC_j=SR1MKeM7&AA%Lz zHICst>ejFW0j?mQmi+3_alUovI1f8?C!0e@oUa``&fg9m=W_>-^Sgt``QB~$9l;mH zd@RlbZ}(r7$rY6HIX^sfoG%_a&LfX?AcwrZV z!0Y#SN4sv`xsITedwBO2d0te*<#>M7nEokUwkdgs^x)6h(ht1AnLTj-|5%LYQ{9~E z4_>!9FD>C``vcFl5*%0ec#N?dx2Y-T)r=)ggs)ott^nPqW^184rsKb?u{VKNGj4hC zmV}|*(e@l=!3#>|wHv{Wm#;+_JJ{zvbVEuNgzm;UZ~b(_$_Tk$Dtrq40L^%o(U#w@ zeLER={W}g6q_D*&2B}2e6tw-FEp%#1)kuD8SgA(w{PUF&m0fTjQ?jt70l184s*Tr zoH^~h^_?Npd!qdO5z$!xxi_VkEx%VJo3}o6I!ip1FZkq4W_#1l!ETCasU1P#?Vk+) z7j&+5@t^Ls^XWgQ;{T2DsR>@s_TKu|kd@wgm!Ms*u)Qz-aJSut zArXRHJ{4aFzZW$oTQTU0r}x&=PRF^2`&=ROAn^PP;|h zj!^sT^KNe1Q-4^3a{gs9Z@sTWIrzP(3JcL+)A?!ed!a+SyzjD*9A#1dl0)9Q;*F19 zJO6QNh1_2fJieo#{r9CxZv3NnEI~P*J8fg=LLR{HMYVbAJ=cSqdFz}VcNPZEr;oP| zdZye|xnA{L^|u9!#!f3pf~Rh$u{YgK?e6T67AVK<+x=1g+j0x!eyCv&IziWCXA$V; zKl0XXyQlNo@8k-tP!FXVH3ILjulo0x>k`b zpevR;2)Y!l(NELm4e)zWrQ_xYuV}aK;2q2R7X6o?PySHb*gJ;zapnKG-!zM$T2b0t z7vI|%{WMko`U3U0d~kd4hNdkJ-fQ0ra^Ka2JYGFKtT9?_60DoHux;!)i|atw?O9Fe zmNtani`o(8wWCS1;P*nqYlMOKv{_s5{4*p%`5n3sw&izDRQCJ|1UpvCY#X~)k{r<8 zh}|2y@lA^2{qs0OPv|!H$s2Mj(ucGjTYS8sL?e!ZG6^N|PZsQGV()A>jS>&g+*1 z54W9fxy#*{zj}t)f>M5o)LuU}D{cyxP4(tX2IwXPq2H$W8|tDy-c<4W#h?m>z)QN( z^E(+^-s@Kd&t$z2@nn1@>-3<TsfsHKwWX>D>dbU*5mk^K<#(`MuE4PwT;3ki+ZO z+cf}RCHY=ijw`>qUi%SjmHb@HmH2P07wK}?f>Q30iMSqGmk-ycPETqq*Q>@>$MvhM zqwxRG!aDf>=-D^#J(YMzwEX|7OXiOFe+7R$o9ATzH`p#qv1~ypKX$%bj$p}|UVG}8 zxtG`~f2;=3jjfIPpgx~aKlI7-d!d7^;rF5@wnhD_=OaP!RXjr%$9h1YIw4_OM{ z?x*PYlwkUcx12k98`c`7d8G z3sTxWc>mJKxPzc;lL7uOs;iCnwc388D0n67!~cc)|MJ>TqgTq2as*SiFYFFjP}hDJ z>y#rX$D2K<0bQZ3(}YK}=Aa(Qzr``=at;dzFXI%9KWJ?1l;Ev8j`0b#I2G5Ga;ik; z1W)kEhNP~s*Yv=6hd%gEhX3!vEj@)#>9gd9uJ)7I(5)yQB}h|aGFpPaM`L_NeZNJ3 z_q*yLIj#g-jq`PlU2wbCo&sLXg6{0>>cXcgm+L_nP-_r$@lOns^3{WS@PDC0HABHm z8v_3q)oa3O)Pvy1+99s7^9>&e-Ro)af1x->Ug}My9pMS?{S@dLds3HX&=vTn9CT4{HVKb%d;Tw~!g~0>sBtALf;X{y z6Y##CuLWMV87QBYyncc51sko+;l{e;Z{JT64=BI8dSDmm2KMeJ*GunD_HzZVWlAr| z|3^wWuR2W_0N(r)f6M)#m6tk#cX?V6c!H;I@?PXBcP-n^1r*)FHn_j^y$1YWDC}bc z=suLG3LT>@yvtP<;W|s*@cN5tx$&JuwI|}ciH@vm37%k!dYhepe)>8Kj|I7cqHpy& z3g!Kg58q`JD^)(>Q`{!#w^hY+f1-a2+|nDov2C*nQuA~P!F%_8kf0JQ8J@-2x1FpC zr-EHUIliiHJLo=MF9F^8zGvh(WohWO_w*IUgV#7uZSb;m1X826^CBSv7ahLIbQ1w4H;(ZiQ z#Ctyt>Wu$e2`<=`$TfE7Cchl{o&0gpZ`1431;nOay>MUY$bY!cs!gSR;3d4{wf8H2 zi@|IB9rFs5IJ6<|li-)?haF=d8Ql@O8uh*YWpGx^Q&7L~AmLNr_~@_Ip&aYcE^2r6 z-v9aYro#OkvNs)g(J%U;e8I7;Dm%t*b9{*057oX(7vZaF1p}aao$ZAsWHl}1vUY%{%CLiQsUE?-=Vxey?PJ~o%~;zv0IVYRX^5b#q()H?g+JRRbK|Za1C7vZb z75TTPX#(NH4pDQUgEvVkyD~~Zr(VdpD6Ra(Z^0O7&2A$>kzfjT^tDwtJ2jd9J zG`cZ(o!2x3FWDLIIi7V1;}G)8f^i8jASAAB?90b6Zcz)@jg#wDy({*||8e^7w1Si* zB(;=FpVE8nEbXnOaz9kYDPBA5S~C#5Yh4~V!V`=goXa-$hXAh~A69MUymB9T?fzq+ z*AFybyac*oPrZI({ymKM)XB{l|EUjWTcG@NcLKl@{BuT-ZS1fJuOB*-^#{r?)y`M= ziuQJg?(n9|=-1*{7@tzJI9XjeUt($^@UkrM`o%*N-=n?+zrPE%jom*>d*M^3)y1JZ zyXu@J`ca`?`@j7d<7v*@S_iys?Q4P8bpJ%~o_7OJmCkfZY!Vz*G@tz-rlcG6=CdUz z$6v*?g>J&xc+ll4GuYhaI`f^@EZcJO9Z>+TXXmH695z+8Dy@XC7HqMh>oL}m<23PKuid=8JRiJiiK~IPqI3iB z1Yfs0YQ3q|!)acuh%G3(J!8Cf^z7>`=xPoLhVElke2)>ME4;%=_TWCxyXlPs5^PTa zUhzB`ula>hqvgOvz6nwxH-kPAt+xhAMzHu z%&!ZA=QFS?%Kuic8rsFul(>Gi$Umbizc2V-bSm4}ZYW1Z0a$a5iw;FhY|Mt0R89P~RSGUen)I-)Q+FZydW{avuwD!zXU@C5g# z+U`srTgJVz^tmM{{6C|1LRamr*Z!|2Uk+W_$jZ>AnA-@v%26%A`xqbfO#62~0x!IE z5%2^bHHqVvNZZ*RcVLDkDCIXCG&oe_ekdnsMl-mEgVWFJp|IF7;RFM()TDU7if+x7F412~dx3 zj-lUHb(Z8v+bv=tgSMB0OOZ0bAdi9ZV z+(@z2uUvKIygJjWCV1O@rh*qX!D~P99{dB|>{nsn34Y1($uV~OH*KKXurDceC;vph zO%WsF*;4M-gE^pcc3_-CaZ`SlaS!G1gmDn1cXNa18x$Kn!Fx%vxW-PVlMNzL-$4R7-|c*3T9U zK9XKg31%Od+HH_7rThJKI-nd+y?+374cqLH`$5%*dhfMH`GcWbar(9+yf}k#KdHjl zZer7$5#D>V+o7u934ZK)-Knu_ffIhHkSi#h;YD;0tE%72q2C-P&5hSF7&UhVJEwF~Xz2 zEa)iN*?*xs|D`y1cOSO{FCgeM>LKrTv}bx(&>NQt{uwWmYwY5!vO*W03H<>T`f*JD zKWg&;{RI_F;%l?1hClPhfe8zszo8VV{2k$)Ow>}&)A6>Y!4vGIUOL8p7qdrrs`?|Z z9qozv6S_o$y>V*K)eWH=S+zZQSHit^Q)vEu@QSVsMEMt*cLGnaZ=BhVv8#_;DbI~s z7K-Ocb-a+umFpRuJRNjlzUaqQpWmb9eyA0n(9f&#M+3k+``0r|_%j@@-3Y!JiIZoZzczD425pP znGVqXzIGAyP-WLZ=ooQ)HOD^SVpO?zndG>N-Nmb?d#MY6A6&z$N5O4h##+WsQ`M_y zyTwQR-kMw9b1^Zsh3mU^uNlg(7g!GE=UTS~ytm)I=WN|8@45SYx*~Xjl@{K!j6L|h z_nao}S`WI!TfOHxS&io?zt0Hoxqs_}{#qqTIa01y)k@~Iliy9eb`xie*Ny}~WKL%r zJ8liHogMGLTAn+Vs+iX99BV96nB`Dthg>#oi8Lt95<7c0O~P*Y0;E_WA+A zX>AJG^Y0ILyX{^VE-3n1-S$G4DxcS{ye{VTGw&A{MEQF&di_wQDL=tGeJGzTzvCMp z{WS%Yh(a^}3M|x(ojd5~LYf;r~J#W4wO!N{JG} zSJ`uW{p^|l@pRSkStCt&ahC#x(iYbOZ7D6@CdHvR#ogU0T4XukaOmOg?s{08;9m4_ zJ=_j={brtJzQ3N|B+s*N-mE0qot>#<>S353YcZek$&mni`}(?WY4VX_cpj}DWu8+VcbVr_*SBV#wf*&IT>mit{J2j~?&Ch{9bw`8JBqPni&s{< zpRvy7UIlGNK3@K+>Hj;r&WEnU1oNB?-`Nm4m9;x~+j^PtT zM{VPFq8OctA-34H)|ltMSG)AMKCi)`0 z1@N6rrvDs!W8SYA^|&0i*k9@v#_v2o-W}Js(AP$PN`EoRrk~f_u6Qx3M{m=Bccd-G z5B>Dt6X-u9I(7nY>Gu%u7(W$Jw%E)3%=_ao$MmP=V+T51?u;xApj%YiypP)PGx@mM zy~p&Q&V3Jp7h25%uT0H0D4(&5&j#z#6mMq}y<;)5&aXDwi7GhCyf1GXVBVj5jW_Sp zZ`5(TUvHSz$7TNGRJj=S!=g!0{)??>w~DdO`3%;?qG>I6NU+Vw{Nsn)Lf0oC6uJu~ z%=>@*RMdy+bk2Mq{N-o97Ya2t-wz2djAXq&mfX}Ef%D@W{d)qMH5>eC=4^HsMFgQ2Tuy+Hk?8`A+gLLASX zxD4MeRqkin|AFF3ZMr$2H^iF9qDf$40o92E7SoWZq@Z zIndRgQvEEQq@7()03(7xQxId%*98!0~#MZlYR`L#vIRo3!mJe}`fm2J(K zJ}$`pJgu2KrrBPHk&h?7Y{ug>|7?KnkCZ{U<^9 zEuap{U)&V^N#!qQ=Izr2fTxDly#O9#hOm6D*hM;`f9m#?(O;G4lGmt*Tw~08Sj_Dd z_#MG-yM6IH5zR1et5JRLq5r&_-IIB$+xi0FGroJ5+!g!L;BO9{)}b{qZmZpqMcG!9 zmbQeh+RJj#B?{gR-h=0+{{+-o0$#x9YT#AK+88{>Q}quz%RJgT-47LY8M*vzc}#yQ zpXniVLsOae;b}X%K-cLN{9tsIpBT4w#gQ3YzK(otGokzpZ3ckHSoKat=la}e^0B@&{fzp)aKtAHQ*C?Aszj|tG2%fc+Ee1qTZUP zivo{vz`3SY*duQ{pn7_jk;^}MIu&%OeqsDj<(uC|f7(&4BXpssOMv%r#AS#1t-hQ7 zb9%pKTkTvO37)=O3p~bcGcGw|*S-@2-ILj-KV2+#47$`)LZQn&sx5RoTcroD<(VNa z|4#Vs#Efe4;9TJS)5(0NGFGVE#}PYk*OBZ8qZjV!4c)sGd7vBrJt1_yA<>L_SZgnf zF=tF0@HRaQ18>B@LwsB%-){O3W8D#{~2r^SNH3 z>)^F&ZN5{#_;o`0`zoD5J)9mr$mZW+Jp9Gq5<7BO8a}RXR?Uj?*RG9%&a*}d)I*=2 z-J$#Rq!4(4&)zxAZ}7|Xn^pD7v8_f8Yz`jdkg~fiv3>Sbgl>cH7U(|wF#YKA@HNoY zs#XO$LYK>_)V3+3_6@9SF*ccL+VP_!FW6R%!-C!i0^uT)ir!I?7))Z~=5lZ<+r$_R~J_F3iLCl&-tD6?luA76gy+ z&f#MAq<7J-e>Y_@Qh93EkDt&zp%~Cy{<^vtw^f#dOEIo(+}#(vly$Q+QofPo;NAIX z#>Zxjl*Q#Rwm1`PS8dteJr}>+V&vmTPnCx5-r_UN)7=`F@!0hm58bn%y5LP~3e?+U z#(@`6$F$F+xz2(YI3MLG#=0xMSYqcJj^ELphyO%9%z2FK(y2S(I@QFixNeo{EdGc7 zW5zl>k77#wem*tE|5o9na36qY%Vo30POQ-GbhbWz4qyL^p}4QQ`U%`;6%d8{uBzWL z{XNZ3)QjGn0`;UL3ZmXr&%2#j4;(SHs4e#QMrM2oe}{IU8`ng;&^x}H=X;}@@PkoJ z`g(DJjMuvL$gKQ3it%C!4|_=YH15!RS%7?e$4rdZ zdeXpi=tm1ubz;8un^qh;!N1mBbC{p?qUk>s;)bxTUoEW<{+0Ne;4|KucEw6rYKAj? zu)od7y6Kxue|k?bf>~F0Ul?>lwzh#Tyjm9U2IY@-nO~@MB1Ww*<_2%>dGj94xaMVl zt65m+z9f`qoss!9>hyuG=9XO0-HuKS-H@9@7*&~p9u{Nqwr#;X92W{++?Jz!Twj}y z`cRA$!gGdg@A#MX>xjS2$hx~5YC+fbY$SAfN@?iQeZ;t}bEqreot#$!ypf$df_Jsh zP1MJNmxFBnohQjsGb+YsyRz6~C)(r<-LkwGw{?;>-l&g^t9n4^J>L(yf4_coSU+Wt z=|AoJmtkA?Xwm|_>vPR_D&vDIPc5;Fwc8HeqtB*4jSN}|U0my`&}|vm1m$;2+!(wZ z=ZCrcJ3H4u1uxP+5WFa-D|n1u7Q|R$_vkpDuUFlwiT5A1a(*V(>t{r7J0{P&jwuf^e(;7tw-1kWmG`VZp`uTODeUwQuxx-h?dY``oc#M8?mO8$(OWASxzFCZ{i#vDTVO$$* z>Y?x6F>LGR#p*$qym1}ymi#vnyrI2Jzsd6Q6nNj_%Yest|H>yPV0$}z#hR5CBbR%v zNK)uLs|<13e)2Raqb@xt2Xut6zuM;c^SW~fJdf&MHqWPHiSmJW;;;gbapH1c_tfTS z_uo;8Ek-VP_@vzUon;MLGoKQb+t6j(?%+CCo;BBdSe-CJ=x(-jhScPn?Fb?tBqOHL~?9i*bExjMq9t_v&ox)A^c#SD<-i@bXl` z_o%w|d!NSh#v8#ay0#K{jG>JmIbxUD1-)A9RR!fAD2eh_?#MULjZ^r2ouwD9hxSj^ zM1Sa>1=p=Mdwbb@9npWMMfr?x`e$~K-HZ!29oC;* zh5M-9eCWrvS~9l*pI3Viq8@aDsk6ajeCF#zcF$M zqb@rsrNuZWs2zCor<4V6(c=?*TrCaS^@UEgxOfq|K zx6`(^pUcR)Q?E_`DSmG$bSL^(gKpG>#?TSE%qwuErNwwB1;$MsJLM7EDxz;uKCiZ= z>PqJHab+ z-`tM_kMJB*?X#Bv@6|+e|2{pz{H$i|+d8`|cE~YvzlWtY_dkb|9Q`8OSyMmDr}*Ii z2m7SL|9lc?>eu`A1Jw7U7pDHhTbuU4xZ%ZjN9?S>{;~Lf+)8WO&y=Qru&rtojl_LQ z5NX=m{i;*JTRzdW&%L`b|E;F{EDPSqhj{PMj2o}7cEo<tXssf=i}< zeBWsLOZghl`8`L6^)dbH*M>a&e^i&s2~qy^=FyCr@ldN2j@YkO`Z#=iW8pT;*F6TA z{(SV+0Y0wY#hU(Jrv5DOy63}toL+C4@nT{B0pJbVWyTZ6Wj|xWimkojG~G%0)d{)W zO()Ixvu3mzkDhKmhI&|8*Nj(-{mpomda)O-W6k3zMs;d*1=K^DO=dh~yq#x))$z~5 z?tkNxx{O@@p#EZsR`Y;f#!MO8}<^qr4jxpzrw+8;GNvwg|AmL zQ5`Rs9z4c*hdu4Qdk4CO&XjN%nRj{B4!$2c|JcsZjmr`Y-N#RN9M%i=9fN9?S!uv6xfDK6Gh>TR-4jC?l6+jf{gXT{?V6X`iI#`Ft&NKIpc` zqn)V866X2-*GTicAHTpn|EEQa#dwyYe_xcxSZQ5nOKkg7c0R6;^-spvqr>x}-Kv?3 z6IuNGm49N~RwY`L0WY&}JRjGM+oNBobQLp>p<==_iTR~dH(fVcGAGmCls_L=@uRySZ< zF~)=k*WiI5_@0Se7<*)4A1G+Zr@}fU|Yk=`UuPo%vdbRPd)O=ojK8Eo_ zFG&qQ8122KBgzjcPy#&0Ia_{O&kJ33!Xon8jI2xc8249~dOM75y}NLI=tfnq1zqoD z@Pkp#3e#`C>LcJiC=v!<4$rpWG44va&Z?Lwlk>HHu+7Nj`~Dc>GG2U{h*94O%ne=k zte9U^-NIr^^LfFlDf)n4seW$ohaOD?e)FW!jA~3=CQC4XonTw+*Y%bU6zh zVV*9&+VrRS-={&hEU*@MDJ$0p?`qj$;H|wk+-81heHA=LztFt4*g2DyfNt2~j?k5u zbqV!xBX$sUzjmANRgWaz;3aGy1>Wv?1u&i^ZDhVrb?HLPrynY02ewFNi#=)V2ZxV; zzi#?dy1&EN*3Qf3D8EGRiqKWOycN8S-%S50a&Q%R8*WwsFW2KH;4$8@9ZT$N$Lm8E zxO14xzZ0JKIdto$1wgkXLpSIipZWv+=}bnv*Qk3{JejXs&h-HAWtD;8F&3It)+(}Z zRanTf5Sx+9JrZudR})p`p~29_w*7+o3p?H(x;cKO!OLFjoWuNN z6-_<(M2=-!7u!=8JjPcy&pKx>)UjW#KW{NIKWW1W&}D7|ovPC}9=cbdWuRM|5x=7z zK1c{&X>Zeib}UTha`{azWCxG&d!Dpzj?sPXltnsQj9h+|B9r-ls`nFnF<%W>nGd>I zX%uvYFGqv7@LWEN&)0c{`>6Z^!ofS`7stnS?<=O?Fy2pmI#ldiVe_F|JEuDHRj)M- zp_>ua9lC0LQO{a%W{tbxKm1S({PXiVgMTh?JGU2IeiPag(6@F;N9?t=)7xBru1T4p zYrLXAbR(B{M}0imjP|O__wWbr#MA#A=En?2`_{kK)?!xg~u-^$P( z*|`?FG{58Fm3X`fy2iOHLANLm`kxwltpa#ey-fdUdi*VTQSAzY#~8LGsVnvuw>!$; zG$Wj^SG~T5@j#tF?B(+H3`v?6x(qEaeyCabPw@RvQ+s#f^XmKa5b*r!->}HkjLQz? zam6keYx+~IA_MunT9~&1bW_XKgwFap6S^~dO@F#w`5<^-8e8C{E|2k2-+As09;09W zV0T4iv_1b`3Wt$@_gT+`j4FOy9_U(+?9HfmAHIlnpr}QCz+3PoCwM<9CIPR&MzmYq z;9?qw`HX3Y1-skMwzc@W%cc z3EsJs;HeGuFM-FH_&{E_qg~Q&=ljE9CX-TU9>Wg86E1 zf(p>B_u0wEb)pZZKgIW34&L>*Rly7R))>4@3z~t)xFKIGf$tLRt@~e$HS!`psg{z3hzVo!Z~j%meH%V7^n+HSY;tvSgp|o?U86KbNm-Q3+p0&G>CbI#=w_ zE-9I>eOeEOuHmTXsK+5wJ3x2zT}kNH4m0x_8*-ZZ`1o#=#pOost_R+SGqu5EOuqS| zBX*{3lbNSC4LAMC%Q^{NOwY2=Rjkquy1&n-059*LAvW`Oe-8_oFj zT6gE}tU|HdN*8w-nP0MCZ|D}(&I{e^sR^KKIXaqAe|%=tZxvnO7I=Szgn+mEb|>&+ zvL4{}qyEV@$Q3L&rkFM1R$8}NyUZ>lmw(}X7U+KE?GN3z*gB|(WG&2hYwJ8k!1GaN zo^OqX_N{81H}in$7dPYcit)9z*UEIPl6y4oBZra8Z>%=r{=WMC-Fk7MnRje&Rff*j zf?iMC9$|P*O#j)k-OOYDxe33ohGfF^XvRwclN_-(4{grZtG_hG_3I)n@PE|o!Rb(b ziB|)09r-Qz!RYbfT6!TDc>b%S`8pKigQQ6;vHSg}__#iC2kl26 zd1Ss<+pKJYe&iPI3mqZtNhg{U0aA@2p+e4m`$(_g7kC=YLrS zI(POdT<7e*=DG`3odn&6&^pi+uUQYgS*^_c{mVepK4;{=0N(HcrNCo6(%_pV_VcnG zpi9*34YxbpZo*)fG4^B%Mm6)4FLd7{`+;|Pb3K zJ=&stM#n8`|CxWdo$T|*Fh(j*6@F&cYlip+q5O~Q%=>Ys^^4Fi1|%K`-lrZJ@H=(; zX990yQ;gdx_3a7#|A9TvhuG`ZceVAk7>kjQFRdL2-P=Y_9Wr&;74v@5Io7OCU1`|_ zyhOvRg4g-#3h;t{uWvQlx1DXpIB&b3JtVq&}~_F*@<*Tca3vFs2Z*Y~%Yev@O`4DcAA_wu*JzPz<2 zbU9ShkSN9u$L&f>oInPBeot}ba%9%Gh_ zS!}U)G|LLzzGbG~zFZ7JJvK~c>b1|6LeNdg_#VF(`^~h2QXj){J%dIy=kq%Cx{Ba2 z_D=o8x> zk&fNKV|4pZvC_326!*`g5Sx+9&vFgl32OH{PnS&n<5_y>Iu1AeEIM){-w##vX=gsK zyn7V`@7SV$Ei!eT7N*}a-dVCdZ1?Og)|05BHY4+orELUVgZ$N@i(0V&x|6reII;iK zKJeYo{?YG?#mM|uC(k&HyCTi_+v)i@ zw)J4UF8Il60##ZE$5q05rd@vj0G)2P9_8q9{ZPJQY(8zdC3awG{Jz@u0@tH**Twbe z)J1T;dhsz_zuLKcHUA&=IvoE`ZLf^~t35a1|Lfb|aDNnI;&Z>k#E!`1hx^lETr2$V zvwLuV_2Rmqc6ZO|`KeCkl(U0`kc@ zowXsx31Eb87B^$eAiM1#e~Xd%Rbw%(s5noIGiut%;w~N5ewQ!~>8s~VKT6Pc2d-l)oFhWrQ6!J#8E#A0K??5Olt$!k}xpstt4vS7m`NX<@Vz z{V{JM=BqUibAz|wg!w*Aa3m7nr;MM=7I*VE?qfeY)W>1u^3yKL1)YjX4Bhc7Ll|{B zZx4qts7G7yZf^_)&*$b*KCULtL%-0|OaBEP@g=VIgG3?bTAUSZ5=dp zMLuJ^R$VS#hOWx`65!b_&G+e#hc{6VUhfCF{5v734PoFD&;2zCO)3^+Jd% zcIEm5pc^_a6Qf$!Gy`%)Fn@}WgD0_ zwx}z164e+wPtOSGj(=PX-OgvIKXrb>Zs;bTEeGD=-7UeZIxi5s@JgoN+&=XUJjQ?G zv$@yC7O)ScNCD*E{jsJebOrvpiTCUEHTt=HeF3+988soF*N^{B0eksWGd{ldgddFR z6NL9%b>`1f;4vNy`{u0scHVI!^0|zxj}J1}on$iJqtyw!9`jYxh&s?c^u~L)PSwY> z&ld;rUamZDmjSQ)ns(qZRyw-UDL5gilW1MA%gE&?t6|#z(@RNRE_dmK9MH8WWu7~J zV_V@lH08E=E}eLj7rY$T6nMkdM>A^1c1IFBF@d?Q>2Hg(3p51pU9#Tb?Vo7I6UOOv=7ssMylq_$&f_w2xz`s4LszI2 z#%;CjkG<#@O`e+Pe#Xh^Y~}?;WC3q;8;sj(;rkZc&Q$AE-TAzF;1&UovDW@1uGm>8 zymIKYuGIqLwz`P|KT#riM5!a`GRIH7DQ8GKOUmr;3(-}1`_u`Bp}ndv0Vy5k_XY(Ek-<-o@$c0W)77+JUC(-$5u^x#O0A9`5n zg3xUX`ikGX-hC)|cIjYTPrHgO`Mmzvxjc9iFJhieG4`(JXICXZm>Y?P$1*Z+>Q2nd z=^CS}LHA);W9SkGw?g?xQ)B#8f46^x@*9jQ3SPkkUBQd@zxx=oi&4_p|x>-bVW{s&@f+{;E-hFkb7F#UG&Gg?++! zt^cWQ+QWT6%s(r}_s8LHc?9}bs0CoB@>2UjxfFZ}?_Z>!{!!Bf2^9|!Nx zw4vb5zmE40m3=@OJ`QX?BG?wY^%~RuGc`%#a{09%oBmOHmFYjj$KB!gA60v>>0giM z0>Ccfq2brhu?KAy9tiUYj zh6m$)POS_wad>PVyWx!xcT`0MBqx8taX7LCmK zmB!nQXRo%J@h$#t6s|umb$Qf7;$3Dud>K_3|AWzUW>WjvqPI?sIXQq_{y85rp57{6 z(IHdM%hH_rx>=AJj|uTVzwOnvjC6?NfzYwut{v@dw^53+;DxH4;6TWn{1GU%)vL!h(DC$hNQFUi|Om$7CU=t8Q*^KrGit?BO# zMoj=O=tv##wj8Ys9^>)@XDzXJ(& z{hJf_QN6BM4!jkfd%^qs!1Q;r>uVM7 zgXeiPh|jA55naHW@(X@2`f@q6BjBHx%R0L^c(@6Zd)kc5KOEu-U4%ErYkgqsD83)M zRtmIJeP?+9czwSPbkAaB{>GWBpzCP- zU{w2r+n~#wu_AO!zBUIhrb!rhHLqa2R+qPY0PjVCLf|o$@0`rN+^UEB-`=qnBbPrp zcYf5LY7u3#eItuEqi(b^HFSiqyB)+hqPo|;41UeM9r?Ukm$?LZ(;L9gLorCLq zCBQhV85>8Zb;MqCJ(117lc9WW=t4aDKzA$SSbsXK$>#H#&VxsM@JJ6HmGAI*`aSR% z^Aud?h)vf69bF&u6kRWLbp6oL|ACJFA9(bC!K44rJVo~fJi1@tF;+kR(-E8QCv&kZTruWaYe=%8FyqHl5t7KDH*q99FuWP#yv)x*6?^d?4Knokg8S7 zI4R?%jH5EH$~Y_Iu8hMnF3Y&h=yUA6!{d3*Apx$8>oU&ExG&EEc`gXb^Fp2<@;s5} zi#&hidBixscyU*3d0xr$OP*))e3R#$Jpbf*D9=ZEe#-NdvA~`puGsRtmFKTKkLCF+ z&ue*p%kx~G@ACYY_W{OI`#fE-<$XckALM;P-Y?{RL*75+eMH_*Aeg*#`H-hIAYU#8=f=t9tR!0 z*D=z*z_ifOdmnW49?0W~ruRbd=zS49dVj?DMDLa0F{T(26G!ixPUM3?myvb!9ts`3 zmqJJHsnF4TE9(@!$AU-iwcycvE_n3*3m&}}gU48OX$p(pm))0NeOyK^pWdUPqxWj) z=sg?jLiFAZ9leKxNAKm}(R(_0^xkgq@6&rdc#I*RS6lSH@1}hH!C~a`={taVn!XF5 zqwfUh=(_Q3g`{zZR*z_I7=QVwoK}X+d(9w4r zbo3nuoqW&9_nmz2$@iapAIkS453-kE7-BJU`7}=i9nBj-NApO~(Y%tw=V_h^Jeqd`kLIEHxTbk2@Mzu&JjQQX z{B4@gvVGTHvlv-V^IXu;yccvd55_u8^J37^JQ;X2Zw4OCqoH5Wyc&2k@5adUZ|>^u znQfYnvsaw+0P=B~r-P2>?a=RN9uK+?9z~#|c|MDIH17u<%>%N{^Ml~gydiirk7ym5 zT*zi*KFu$JPxFo7)BGd&G#?2*%};_y^Oej~G=B*m&1Zr~^PS+){3l-*&x3}g`W#}5 zP4lDB(R?YRrukFoXg(D>nqTGn!1Js?ns)`C=3&97d0B^bG+zro&EvAI7-Is9+G5i@ zFLX5T3mwe^Lr3$%tkX143?0oIgGcko;L*G?cr@P(9?e5DDn`HgzP8vjPYoT-TSG_l z*!W(hd2Q%uo*O!v_XdyV!NH?>af^SS=F7pOd35j?r@Nmlv1y*2d5Y%Up`&?t=xAOZ zI+~}4j^^#bqj`MhDVo;@kLLTqqjdoA7#j{*YSH>Y*sG7hHY4+C-2ggTM_}Z21?XhG zLDnB+J%ZOMm?!HOvYx>>Vdlp$Ugvl=shBP69kTu*>mjl}BI_lxej@8Bvc4kgEwUcN zxToL7I9{j8oj12F>ou}|BkMV`z9Z{Bvi>9ML9#w1>qWAj#Q0%vjKk|pZL=k|WxYw( zpJY8s)~95>O4hGrJxkWNWW7t)!x$UAdFt>wSI>$I|NE9`x zxN_qaM{HR~mUU%WXO?wmS%;Q&X<4V1b!%DImUV8%a~VBcUjLqOwSgt;;Ib|*>*TU- zF6-#Bt}g5BvhFVH^0H3PxGh&9m)Gx~KR8xa*70RsU)K3${a^e6#6Lj%1;l?q{0YS0 zfbrbJ5SRTB#^0^xh(Ch(Cy2j-_%Db*gZMXyzk~Qch(Cn*OEB&jRMcfZiZ5dhJK|3v z{uSbHA^sQQk0JgU;;$k88{*F){vM2DOJ{T04 zpNWqv@^j+nh$8{S)?T}xZmH0=H%gB84SA&lH*PtVRHt5K|4Lb67KQIC;tuTl_Y~k5l|Q#m`gxKE)4I{6fV~RQyQAuaxms zOjAc}@jDeiRPjp{KUMKt6+c$-YZX6N@q-n=SjGY#!LeeC->mr2ieIhx*^1w-_~D9Q zuK4MSAFufJGIq{U$r4-qe#H-1{DQ?#Sp0?w(Z0x^810Sxiydx%&TB9Jo2vw zkMZWuF>NB-x~kv}@~6#1uvNB-*Ik^ee)?@IdCbI8D_Myl=71_7KIHpI4Ew=1yk$o<*??v{($i5iaCnNi2WFL*} zvypu_jC0-@So3XN)&8 zj|}B~X|ul;wq<{s>{pZhYqFnB_PNQvH`xa#`{HDuob02MeRYhpnrE`bmVI}!4^Q^x z$v!>Vw_7TdyLfL01`wnFvqU=lL{faz}$v#He z*T|S}${0&*+4m^>Aj5y}il{?^O1o%DzoV+19kb7d*ze zQp%-$zxILW^DIW@(SBfluT-=@7&_W7%&2MqFm$w^7(Civ%+F6n`;Eb){m0k1J7OyV`M(8ZsUm85xKMfx3uLh5C z#K<6*_FdZpo1Khfq+&Jg$A*sfXG2H(wV|W^+j!p7es1t+e>bC|{odfw{%`PTe>net zP5Z^cWBj+xY)5R`PYxaJFLzi^`^}-Fedug!+LsO;?NbMj_N{|Q``DSMXrDWHwC^1} z#xet5Ibzekc<5-KJan{g9y;1b&!}l%J#@6s9z5E2k9lm`hYud@&j*k8?SsddV^>yJ zY}(fk9qseC__4c27pI#1i+*C0^m{H0q_{>oD6Wqrnm&G z(-fxwI*MBW9mO$#j^Y}i9w^QMcog@5QBfQO@F-3Kcoa7Q?{SPX0*kw1Q(Oh;D9!?O z6nDX4J;h;wj^Z+~ttn0ecoeq*Jc{E09>sS6kK#Un$Jnh!5trgY*tdq=au``paU!6j zxDn7%90}GbiYoyf#hCz);!c1^aVWUmD2h)39>uL-Ha$| zjKqnNxG@q(M&imyoEeEjBXMaMi5wUIbC68EOm?>IOT7f0gcNE{uB ztHbD1V4)+n#NClNJQ9~j;`B(|9*N^4aeX-654Sss10->Q82x76j}u$s21y(ti7O;= zh9vHg#37QnL=vY+;uuL>BgPa{_lI%3Bi}T+T#0)magZb~lEg`pxJeR6N#ZI=oF$3F zBypJ-FXozQalEGCQ3+j%+az(EB(9Uhd6KwK5(i4+LP?w`i5n$xr5NYW{m$##SsIK;)*e9iZcct#T^5W;*# zjdhyhwn0bn+@PcQZs1Y8H#~e$v4zYaW#YX=_1y91B0;@d*D*c1u9>wJYkK*<5^>N(3xX5J1ZHnXP9`%W|82LEG_hZx)?+-eP{|6n# z1LXUmC_W%~6fY1wiXUh(f6y-6Pet(t*#qfhkK!dVa@<6_b0S}x;wZXNO;Z8+IK@|lj^Zt1pB=?t zgpT4dLPzl#`Mjcdjo?xIMu$v}>j)mjdjya1kK`XMiUaAC-kaZMWF5tagpT4xLPzl< zp`&<`&@hs!IW(~0!nNM*pp`*B$jGE$L zLPv2ip`$pNs1J&p2_D7K1drlsTFj@oo8VC#PPRE7r!}#0Fs;hR^rhzu5Xst;yAUT zsY7guS1a*rC7!Lsw>|1>>Otb)N<3VNk1O$WC7v$hjbFiW9A~%Hr2MwT+m-mc5|3Bn z^Gdv4iQg;nd?miG#QT+az>L{v3~@M4@X2(kY>5{v@q;Cvu*4V6^*i3M#2=P;#1fxa z;uT9gW5$6~t~ng%`1Z+Tmc%=j_{S0tS>hv0ykv==Eb){jzOuwymUzsJ?okhy<1}|@ zQP+}q%@V&^;yFuvXNmVL@t*}HF0{mnmblRpS6bpsGmd(Atc=(ahg#xNOPp$nTP<;{ zC9bu^xt6%s5)WJAV>7mGRm%}u;%7@dZHccf@wO%Yw&&zv^ry+c<8w>AZi(kD@x2+( z4?XILE%Co49=OB@mw4e4KV0I8OMG#OH!ktWB|bT0#i=P>u_b=F#50%p<`VCm;-K?& zYl@4G>!&#B7hO1%MKmIX@`#DwnIm8 z+@Yhm?#$B^=N&wX`wkw(g9ne|#A6&|{P;fDrTFpos5-eEM%GbWc}7KX=Aomw^UzTo zdVH@^Tzc>*PCa-Ox87ks#jyvE;@q>X8IMdY=2HB7yT#mX4kI6@xcJafoP6kfo|)$n z#nFe3;_8D(arVKZxclHy9DbL7hvM{u$2h%kZkOWs+YOE+1akQl*B?5H^Uve3qPYLi zQ62zBO?d(Myrw(>;8ETHz8{M62!Ka<2Eb!HQ82Mf`3J22<#Pd9M|laLqdWx`>nLvl zbd<*cI?8Ln$2H|SV4kMD2jEd21n?+N0(g`+0X)XPLW;R!Q(gt=D9-|Ply?C-%EJI1 z&*C6>DB%g!idyxDOj12-qT(KoTgyf5m{1K8*Lh?&Uz6r@cA^9k-%{T2) z@>ehhB`@HLE%_}Z--YDAkbD@DA4BqGNd64Try=<^B>x8E%WJ7zu_Zr;r(3Siml5a%vk4Qce$x|YEOC*m8=QrVY z(fW7Z6Ul?Z7~<8?;ruAQ(ie9nPm1JCkvuArS4HxyH2j@+Me?vnUX~KS^R_hqy>8Fw zQTp6I&hJt#q_8V_UL@~}s${ zw@32$NM0Yw^E3N*9w5mJ#2Dl;(h*zo21y5jp}c6|QJyqLO?lJ6qdaQhQJytCw-~F|39%{vnmx#wZ!vQDl$Q-U%G2hsp7ORq zM|s@XR+QHbJj(M19_4)lkMh7VPg9;a@EDW)QNX7Badu$ZcNQb-bH=oRj`GYwM|tO< zqdatsit^HdM|tYNqr7#zPeW54JMbva9e9-Y4m`#JU%hRyDK8#$lqb((9p%k~j`HY1 zM|t)5xS~9J;8ET^@F))-c$B9PJj&Y#9%F?rfwtI`*N=6I^87(ZdH(-R#5j@KO$jEsh-5HxR+G10FNa!eEBy^NNlJASAe3H;neo5#k-=xKQ%0CGn z<)dUc|gIV zyrAGwo=}JRlt&ai#(^(7g;9P{XW!2Nn~}?>yra-j9#ZHiFDZ1Cr<8S?@|J=}c}&5h zyr$q$o>TBB4=Q+!A#1WYlpobyozvT9iNI?98KdZ4_x;8DI@ z@F;(-!+grC3m&7Ma4t-2%Dc-Jj&|}9_9H3kMjS5 zM|pw4V_dcLVw~8NHyAp~BMcqo6^4%T4D{+(?}MiN z#^5u)8#&hzoAMt+NBNK~)>D3D=qO(@+nVwxLr3|P!K3`j;8DJ1=BXED_k&m86ZNba z^OSt!P~K+Od(K9Sk$IHQ89K`E3?1crX4I7bna^v=2Mr$OherRQe9_=h9%=9>zchG^ zc^i1Uly}-KoGY`%$mLT$YKM{XQ$t7js-dI&)qGqB4;uj<<+lcp@?C>R`LDsF{Mg_z zF7XO#AUT(?LEqS{okGJIcW?WdHxXby!{k%sz zk_TM!f=ixo$r~h1|?l@vgUUSKFE_u%-54z+4OCER0>n?fTCGWfBftNh-k~f|)+rGlC z*nNKIm6ts8l6PM6&`Vx=$x|m`r9k8hY|`p+A69C2ZKjW_*k+kiaK6&#fi<@?n({qfQiZ(L8Anr-;J3aw^=$LI`x z>vZmW(8{!?fXm3`@7`ms+m4?J-J;qxp_`G#j2Fwt4g_zQW5$zZept^?OTU}(W<*Cb z9x>iYG2eOm?};$0X^6|nq|zkr{|D?6SyE@W57ku~s=fwVz(`DrHVut&p+}*3Xf#1}pCts)fw64F)=ruSq zqxNc-9=uv>%=4*w)HeR#YQ>7q;CVbO1|H+;&ktSu>u49c>)T(@b=;K? z*R^_7FX(b)i^2QA>WO`AzMcnec1E>kYclYHJ<(1zWB*bDyL`=;OQO1TL9>DwdtykZ>I z?v}MKs*!vBz#)f`4(pbCJ3@E5is?tgU*9vo^Vqxxdz9<~-iZOLx&7$Gwa}h)qCY)s zF85bcPn6HNDk!5}C(Qu2L(ZxWBlAHEoBD;IrXZ8(GRT222@9K2iWu3F3=aM$#o6?ccSt%^q0M|q6nTkIwY%=c-xu+TC@ z(@Asnfo^TK+|Yebm>9ajpG|+ty(*)_yn;E~f|nv&7DCk0p36 z+|Nh;wix;N`S+No)=QgigYM#2(~s7Nu7d7B@~YsaKG+21SGm~$ylKubo8|WR0=b`FxGj#)k^2#Zyi}u%x2{Bllz(bIpW!O=nAJQz~$<;56t&!k?+Sa zzJ+G(hyPKkbv8!*wr~pY^6ePRs2EqB%wYu-`xKYpX|T=6$Nzn7#?uR*@gA(xoHgU^ zD$Dfu|4#ntFmL6*by5D?wPyT&b<2$BA3K=#`04d&@E9%6{I=MQdYI?Iw0G@rUC+NK zVxA87GwuIe8}oeGk|GDnkM3cfKYuqFjpxz%73TT0u$OsWF&?ay(iVG5gn};WL^R5O zzb7y5(=dJn(uPGSAo7BO8Lp*!$8EOYF*Hdq9_H zh#6m&$KQdjalv4eUvrpwzBg*S6a6B?e)Ifq=$YQ8pVPrdGK1GMra#JOOmw$~CHC{O zoly@xPhq@PwM+X$cc>%$VD!c)jMu8`%$g2g|JIvL`Mj#S)4a#LEwhe~>-N9DPZ`@k ztg>%J+f7bj$3iwE^PAQ-??sb;HADIHURH$eT5goD6W1{BS+`~vM){sAyMuS-dquuJ zJ@O^SXJE3M^_&8eyxhtYJ#0oUzi7F%(7mW`-t+!?f0XZs-a4fdpVvt!XASeVUo`KH zzB^67DepbN;`5uUHvo@ue4pb^<197ZelM?DjI1j@au)McLdW!@Qil&fmv5W}o#2q1 z7`N4jgudV>YlC*73KUCdlU!$Z&HFNAeCchiHXYy9&Mc$6=h&M-CKcTMvDUaT;hZ z+u?})>0){4wk_TX-R5_uKYjmi8FW*!SL5?~%caKPUEbUryegkDZmXRW9)tHVRZ;L5 z%g#vTihZa8#%;Cy75rdS%o2>-s^GGWHkbRYTt?^;?#KI%YC3Ng-w#zfQ&&E(LfaGt zZ~yK`4w;&<&&gb_*dLM(XT7Qx-IC9%bh8^nSD{li=&q$*23?IerXChW{|(+>W6Oh= z)W0Qof4vO`kFiA8V(x~hp{{3-*Kv$gtd6TZx=U*)E2j2Rh zK8$Maij?4Gt1}q9$a+svUyQlahPazIb#RkrTH-LWe)YkU(1rZGXtDmBx2cD5-A1vk zTi>k*-j0>E!P`@M3V0bunf}u<_5^s0uczgA7cDC57M%alVPw6Vza4bZPg6p-{m&sb z|IW0BNf>p8PC3ErcoXkCs^J?i{$FZocyI8cvgQSkagcW^H~w@2H-K_JF|yu&U^Jup zbupX6*y>4Z=vH2~pc8ELY(JmZfrm{0Nz-;V_}9+W0DtwQ2H-QUeRRxeQa8$pP(@uv z))iZe`qtUk+=OmX#}Mca@9zX%Z1qFvPelR;xy*mFEG?s2;O_VvUw z!s4#jK7+bL=l!ZMbjyamu~=U{1npfnjIGSJu6d{#cxC5R0)_lFnvlp&kmCBpN z=IdZgKt2j$C)<$@x;eK7LU%aT9=;#yL-o$gSG9)*L-*{K?G)1P{cb)cKK)rPJ{1nOOPeVQA*EIZIHbl)w?j!aV zz$=&aG#^*bdyHVdW*k4VTwJsL6RqA&16)QvzP&>o=Ia-E(XZ5<$77%yRUA5Xb|w5^ zbeGkoz#HI;eyR>le204Qoriv{7$>F6WtEEkG27o_*-8l58%f~R@>q5SP;Lo`9)M8zlGp7GAb{h~E zCwA90jrhFII=Tt-b(VTnp-bIzC3MyoQy$>do${JKB>XW_7vlX+S=;|`p<#B z<~xfq?~R3)*wrVLfbO3{R~**AerNjA^pu)yHRom|%KyHo7I+t?{{>#Yg{J?s7;_Z7 zweg|gF&;kg-V(c1BfO93cK>)lSLoj%F8|KHPKg=S#Dlq@>s=M^H+uWdyzu{>eyuln zjSl1nuVu|d;4vPZ;bV*aBv&*a*M2WDTZ}Ve+dwyZeHe5-@|o}GPMb`B`k8VDc$aR} z1n=UE`rwW7iss{raqsp(yUC^Dc69j(VT^qI^N4HEIm?PeH#h;_Bh{H==TQ&!<_`kz zdO#XR9Wo;;cn>E>F{=69ilQDE3wji{Kj-RUr<*>`V&wDJmKB0-$<+4_nfl>t)1U6& zwb@qHS2qXm;?RoVwTa&XUOtKg!{<}RuLh5CSLwobgV9y&;B5CTMn0c4s3~-F7T1F= zaM>`{=~vlbKv$!10C*iDx`EgB#8AFo9s8m`ctiJkGAhPjDx+O6pNAb5;R)p9b-NFQ z?oiJ4d_Qzl(k{^T4=o1WkZkuX=GAI|`>BtN?#wpD4{QWplW!5=T`9B>JjRfrMQpK? z-!=WHZPk6y9l06~U7tR!pnDbX2c2NS#HK%WZTb`Z!Cmu%A5gRx_%+9D4CU)#j1MYq zi#_f#zV}p$WZ7-Lz7KsCQq@jrBx^NaX@>cma)zjXo++y^x#znOP!{VE#QfBZ)Qi+M-Z;eP76 z6LEhPW74}XEwO9liDjM&ziIl@<%k8)y)R$gWqsKX4H?z9T3x}L-`4b>$`Sv9cR2>_ zL9e*f89YY64YRDdCpU$?m=VK#f7HY3L1?ck z!6kq27QaG!*4d|_eJjS96^?~{xlqR`)g#DeM1N4@%AkMf%Inwgah>P){CxE5 z&EWYRugK-9N!`%@bcW64zjDA!K>{&&vP);VlO=0|@;e^wJebjNiC9xln( zt7mS(c%T!N!1$nE#bCTp`A1;<(0wMv^Z(bGLd~pv zjq^hJ%S)kssJc%Q;(uiJ%>&*1tr(xxd;iJ!K3&tR51&^NoiLv3mZvek>y;;lFkdnL zoZw-JJvL!_hmU(r!Sg}o8jk0O_HTKNkLww;&>s{b$}O@j2G`U4K`oRwa9$*%Zv0a7 zaXsLtxets%U38q-Wg1+DZpY0M&~>*vLf1CS9o*+X5)ZanpJ`7jM)mo#H+bcen|jKv zGojuRoWMA(|Hso+#|d#W(ctdx?%V+<`0e8E?(P(K?%<}y-5mM+DyXto^BCQ|MatZwg(#>!^1sPt3>AJ?>Kox{GtW zfw!vRL^)qIpz}aq@Kddnf;44ja_|Hn&PwU0`83dNe#LPFg|{;pelV(_hkjc{d?^fF zW9Pmj`fFKnf7SWzZN*l%ay60tYUkss;N6T^0-j*3^acIF&m!H1Gbim8WE!Q5vlF`I z-^)VxVpc2YdTuHVUGci;ujyf(uiynmlOfXjdP=8Lle(u`?Z9G9K zzxB$Df~x(Sc+lO5)cs`6`!DhQuGHxW-sOhH!Rrul))Rh#g8DgZk2y+g5=;`KkRPW@ zJ$L+&Q=Xt~uad0}bZeJRgl_EsT|ZlwJq}&9#HGN?Ft$B-375tJ?^H8g|L@F;?MpeQ z_h)g#7A5ip#SYKb7yRS5YvO$r_)))~j_k<^e!A4rz#IL0ICx&#Y!2(x)8E?2el?-J z3*LdYzHBGK#Od<-*8Xr@x1W9==0Z27ZVl-2Mr#CJm-Kz0D>*~ApXj;a|Dv*R>@g|7 zdwTTK6o30(v=_k(14DdkKl!5H`wQwNafP30L>lPE)I>i`Cnq+={kOO_x9$%QPbdif z#n`Vr(dDm?dQAzwRuvn#eSHz%+8r7-7e39;S_!&gAJ#$lP0ur`eXG_(_vT(j@NSF- zUp*RE1-vm8b-PKp0mmc3!cFN z(O)ZnsW10Mt$c(2S|v{r;>&po_Bf;bW)at&uAOoKWqXQ6x*dg$h5w7{ce0`IRiW{C zE_ApYo)hKzTeq8Lkc2eDzON)KAr^C+aH+HfxvK3rG{sn>at%7nJfJ zw?O@-$XcbKn>h0y+~4itk#Zfhr12#1dOWF(^O(H|?ML0OH4?n>Il)tcUdA3_FZ2B8 z9ZR3f7Zm-llxUx{bST=Zs`>dDp2O~LXwUq8A0NlL+Z^qkwnw7Kh@u-`4=ZfyV&F_tgo7S4?E4Dil{gzlZmecYc3 zdV7LWe%`RX_+E{errX!-4j3P)PIIE8{Poqs!8=wYy(9dNP1;JiG`xf(s9r5PAlrfa z{>bAl*%|2u)`$}&$eYPoG7GwOE%o>6xcIui_;63ZXA9jQ zm0I)x<8C4Qvkf+ z3>e>1P%_=0Zp&KU6TV=|Cq>-FrCPYx{@LjW%J$kZb$`6t#dw;I>hZPu&|(dAZGP(h zeEMRH$Ej(%+OnN8kJ9zH$L#0eU7r$w@&wbBh~-*))FO=ksmP38a=tWk^8h)2O57>6 zpc*|eDRhmO>i5*4otx!;(11U?fLH3A{yq)(akw4_d`L6{{aV0`zOI~K&kdOcY2o2G;N?$>`l^cLkM7BS!7B%YU2Dh6*8#ev z8B0R<+utXJN5@;DJ*bXf$3bT?=8HPu2mM|b{2Lp_fIp)$_>}e2Y48ObF3jbotj2kP zGk$Rd<@g!4;&{~Q68vH4^GQ7poBVfNU-rM*n+d#f?{GcTt;#OEk7gvs_0pToxiycm z%*1%^mmS}o+}$$)MgK=i^gEQdYypQ&>Q^53mwr!O7P=hscFT74@Q!Xj@2+D$fnM*& z`~tn}+!#E;d)E&-NmF-rT23kK3W{!IHQkNRxO#{>? zwX$zASN5mxnF_prV-H06g1y>QaSAo~HEQ9_5LZyjcXOe>s#3i%-$IuL!4HP+{Hfd1 zrz8zMRO zy&UN3-9f)iuR`8~x2#2e@LE^wAxQBjB4FD7-ZUGr8#=yq&I z|3Qbdzz>ElU+N@$igiB}Iy!&J5q;Sky8ZMT6(Ke?Xwv|^-6?8;CwMjCMaSCv8_j@j z`5N7x%KV4j+5>87=pBNaCY#zenx++1aoii?^ruY z;3V;bQP1-Bfv#VI?9k;(qrX?rz18jMN0k(w@Cp@Z2VTKMVc?y(cv!ZRvlP!k3EoJQ zA7jW43SxWSxBB~ZZNU#Xuh0{^ z9wewx8s}3gb4&09gVyZu*55Dhj%@PS5tQRZjot#?m@m5C}pTw9zFX9{o2B;82`}fn!4XR?ZyM|-Je6it25{Wo_E(by5AHG30Ue` zd(xxgu9O?|%fFuB#nSpYj9xTaY|8YquI#7U3w6I;GQkA!rgzr$^TOd1;0+w6`+vd4 zbw7F5zWS&=$}ih2CUj1quKyQn#=-ez&6ow{Kk2C7KbO1wiuX~P4f_4Gx}|-ooGp2IexKAslhus zZUD-Uf2b3lgW#w){C#We+2_z-)7Lx!&~=&m!V`UqKB(suTB4@dbpKH^*-w2|>hVnd z&hUd#!_4<-nWBG!CwR4ce!p?6itfQn4?IE9jeOf2<$tJF5#=|_t=rM$>~ElBbc9!b zO#xpp{lZ@a)$RV3&@P(1M?av-4oQph1cPQJ^Zf>i{o2b@14UQ368aTYw8Rm)UbSm( zXB@Zbnh@xMe_X}!ye-2~{ylF1&S!IzhTxTpR}(zJ9PuuDh5wxGQD}fKDCH;hQSWH= z-2Kp9o8v%NF;!dWzO>E=-jI&rzVPp5iY}-Mp2-1TvbMd!6Kvmnh?$Y10zu%Z8_k;XQ-DE!n)+r3$ z{yPsG;m41u+pS=!0^6dj-8D-q*-!J9HGyt#ld8}SE4385e_re7u%h-3@UG1+2VR40 zt-vc@I|RJxgV8@L!PSpnhDGf7?A$Gu*%y@Z*Z0f|-P#i9uhm~2qT%`FT!;QzMSqsT z6<(X2@xeP(4gIyMJ?9agSMpsQWxo>4_F=J8VM{UB9q`Q)6kWW0=RCoSY4vkR=!_6s z{q?*abQWLD(ch^rI!y+D^hn))GEO@N{^CDNfiJlCw-3&}4DH>Il~#FzQvRMw37{J{ z0sS_OI1|g4<8&FK=XExo!#Ib+lcd1=XkV4yvY$G{$q8Pn+tH*PCAcRbqkE`txH~It zTu)GVYEULeaN%3@+w}g31Ko>M`(?Yze?YgVw4rmr`*5R%?5FjS4Z&kaB=F{~!}C^x zlV{Bcv-Zki*PyFCCExTB4UI|HIpYC_m;a{T^x2qMe*C9U7qDJ0+5( z@#Q?|XcF)Q`*Q9BYj3|eNVZe;Iy>cl(8Y%Oy*8$MFm#o2>i1soNZp=(dEe6!-iTWI zz1j4eevkeaL%&xA>s>79TD#X7-JbR}_n<4X-<5Ldt)t)5jVk4k?W*lg)CZMep?=SM zd2)ew^>8no$Do3JFfI@*R4mjDsNL7yalfl0DEdzIvk21tWO`gtFbwromFOD__i4l5 zsL$&7hLYfQt)Ry(O@4_)`Ke~;agE@&R)KEIes$cRUC%m#QhssngH$(fuP}~Gtp$pzw9=yY4TY@(@uoQUl_oLsY z?yEn5Cs_MTX4l$HynN72ovFWbdezN@c5x)AzsrZEU&p2wRMiV51aINp!Gbh)+Z8oU6L2@ zgP|8o&|g#W42fLf#aWdOyqBZ(!c;-}Q6FaRo*9apybS zr}EErJL);o6`P80Z2?_Wj|$*T_`C_cXJ%ex#u7bGl6;1qHxVoqqS@AW*)_|kzW-(u#n=(knQvcu)PRfV_cw^gTAseCqReDP%9SL`&% zt<<2TBPhJUj%%e}sv=3d3QtWd5Cr~~%6A+#X>mQ=UzH(W7qQjRvW>xu{=6D^OByc% z@1XX3A;C=vw(hm|tc-i0a~_p}?tRDB(Cy2gAG)e>bvv3?sk9~YHU~C`|0_|<4trs+F$h)blIPwTvAnW9F;zKG}*3V zMAPl2XEdA_#Tb|w8tqOEOHdBHUt{Zb(`}CaA0T+KOBVlof&%WF zi?M-H{?cc^;Jm7oE`jzl{4ewaDqjxt3p8#y`Ux5~1pS7}efk92O`y}+XT8eph6YCwTT_9N*ga{{HBQe)CH7J8I_2;$o{lGg}H@ z-K>fCJ^kix125@E-F|k}TMpi>HC4bHU7{(<7p!=~_Zt7()EShzh%d;+P}5t(TtWBB zBj^&0CWIdgs$))-HrlMABV14=2Fnr9o8PaMnB_#_gCwo zuIO%ziY=&u&Se4bLb|@-2}WDo-Lv-hpOxi0srAoZ&>dWp6S{8sqd`|_emHcD*nfOa zRvf4J!AMdsH_+xXS+tyltuR8A3&P_+tFah+8Nv=u3SgT*=e9VUJ3oSx}36!)HCH3 z(*0ulp#{O~T=!m zpT6(G^{BLIaeb;wLR>#Jc<9Ofp!wg>Z&TywAwJvc=t|r_U~uak?vnY#-9Djnq6CG1 zykK8Pu>BR>e~J@<=b^Ur!t+s?j_LZj;U1nREe*l*rBloCyw$B}c>che(SzOaY2j|; zTCp8LE?32`9}UOZISTU~v^NR*Yt^E3X^acT#Mk45H=nYAceZ70U(RPlSM=BF!LGP? z4uVG(2D>{uw|8F+TImQ%`Tdiys!Tl{dG*a}cL;gw7<@r<_ywIujz-t~c61)Mq z!J{PK&w?koDqAl1LeApumXlu{K`AG=cSqXkqA{U+D_n3bjD$ zjbfDRQ-klLe^y;jp}(dssnCDZw4noC*&ln{Wbg&I9}jV@Jt+eHzpAzZ?*r;G8t(^c z`vC6?Rc>rEoZo`1c)zIBN2}mGrhi_B^Q!m(^^E4s!TU)GR-c{EwRW#Ucz>y%>+n9K zZqJKBmwK_je_#KoZddhWa@ybUpR{dqSK?|<6Xx4!JBhlzB36a19- zyt6z1RPXbH09R0SQyuO{K<{3Uvjg{4w)%`x;y?2Xsr9I z_=^S}J0SOuM*pSTyI{9Qal=aYo8@e19N-E{`G0kHf6VA&iS@QRNo0pQ^maxLFCdnfTDL_Ra1XSF5FZoJ|u8 zuaWyr0f{R^SARw`lt03&E!$PwvHE=w^$W)Jl=qJS@aoLOxL*m5xHieLcI*Uw)iK~Ttg7p0=98zv ztJACmc!D=$e(}bx?%*%~zSI$va*NIQiu;`Dzag&JYqrG|q@kxXL3i;Pu0yS8yhE-_ zeNT<+RH>Kb2JiCC@1F1l@3qV1k4_rlCn)nhOi=hO?&X*L>O(EuSCv0bS?Jy$+6`UM z9o^mwZC(Ukt$#6}s7g0)4Boyzoxu~FKcTQ+vgUBV4Cg!&n|=uv^bV(kjx3Eo)o$g_5$<1L`0 z;|_FR?xVj}ixa$uF1TlYU4Ciw*Q#)gf_Prv2lsd7d{&=GCrEGJVm=XAv|1Y9+F92R zM)~7A{3rKA#k`CDS`9oG3SBmJ*%N*IYq+1PSpEpH)u0{?Q2xPKwZJ<&Vg`7EXC?;t z*1oh>x1&?54ndbPA`H3<*V{sO{ah;O3Z@MAXI|3x zc}*kz90YsJNaKHLm)`w-T2i3sZkN%|?OfTcc#g3~=;u1+Hr~thtl68M7JB~QA)WFD#aJwuG;0( z?JQ2RWpY0#PaoY5>-<&(yg|?Jdcv<$Ot)LX%s19X#hux~8@HygFDSad_vvI8ZvI2vPn77i3%rHD>3-zTH?2_q%zpyF%TYx4J1gdX15fbO@=U(9&v0xYIZpro zdP4Wd^^@q=KIiG@%lV}#rTe{g_2YrJf6Wl^dhdOY=k@ZN?l&u4DlU8yoOSq%XYDUJ z&p5I@Rw>gD_Z}^_n)$6R%3n9R4s;`nPXMn#SMX@-{1citN%#9XZnOtaFlo>V&)T#8 ziV0oGU|s*Om5Ad?`I7^)p!_DS&|lMsml1dmHQTP=OPj0f_f(gD3cQ#5bbAy$JuHT2 z?Yt_d$Hh_UyltdhYH`a&`K@AlvRxJVPq(8PE$4&x;AVC3!n!m9ucgxyyeyHr-3TUn zxG>Dxp9kNB?oHKT=w^5A0$qd4JEY#IhsRNm1hKuxizMKcc&f(GG z#~FfYA5L^uqz-Tsj*aCDa&Z)Y_X`{^e$QdPl>g&e4V+(^_svlLyg8M?+d2dPQE8_6 zPW=(@Pw?vZs0f~5a{qxd_f$7N5R zRYtoA_@>8gO*^Ia<$P*&NsRIZ6D~;Y_AN8mogS@-Cn)7#8FpCe9r;W3IB~<=5a>4L z#eZqlded<5Mz$Z|2yb)8hO(dXf2{#tzN@okyAqsRIKa)YFVgKCQ-ul2_S8N0LpODm z16|_yZK32Hk%rJAzjx+e18ugk^^Ka-63(;|r<{M>2pXc;`$K z*V>bJ^@FZj!UNuT_rDGv)k% z&Vdlu+W9x2zgFAAQ@Cw{qKN#C67_0M@zpX77}rTpuu^?6T8Iznt-=T#5am4Cdh zf7xd0`uJfKc(e11Ld)?lezmJCUoAeA9R6o;Ya$cqmb_K=0@I%ixmH$h(;}K_0|1Ej<~wt_`X5+BL(a0enoKS+#Ig8e~!`p&cXG%9~yQ5 z{x7tpr0%D#hUG7vUzPl!-#Z_#==ad+Gy1(G7^dc)VeA6o!0(}`>XEH>nXNs+q@BYSzlBKZ(HH{;MF~=`vbx3zh2s# zw6N#=Rw1t|D7vHny3oxH#`7k3Sq|vd>_xqx17nmcyqzU-fwwTK7s@Z5c#za9I@qYM z><2De+12}6CX0LTej-;;bhmTGfi9#t>M1=;8OsxX*Z)wj|Bss%l>~oEuM@Ig9qbk< zIy%`AelQgC*E+Hvc%#-?FK+yLZo(3$9YNu5FE<*xA|;?x&ugE-aef>v4qd-EXs>E= zwD))(6PKest1+G9;W(r6W&%&JSJEVYgF^k>qQl!cf>M6dQ~#nJefbCdg<4i74|Lml zeRFs>1%#r%Q4RA1imfs}M1Q1WOfL&w^OC#36I}E@ukSpHbbrmgu(Y7?pOs$>-RWA@ zgs=LZYz$r1;vJwH7oywK{51E#Yu={_c&CSU1+QJhrBYw0Ob*m1V5ziWp0ztCO72Rz z>CdNxZg$Cm(7g{DBlm-5T|s|M|9uVwuX?^Gp78G+)$OP4t43negN03HKk(6G&$IT? zkSfq+{A&et4?pYY@ao1E=vp2v58cbqmf)!grNBFKD8iTH1VnxS@7?Kq;0aD$9LKlz zi3vTRTXrlnp5M6={h{*)q!*+wnT>sl1N;&jmwzF>n+ zIelxdd#T&g%~p}JU;X@0AG*RLYC)Ia#Wd)4EY|I5Zr~B{dOj}=Ua_+6z}q@GIe3Co zTLt?go(y&0?oZ+g%5nR;`g=3l!)(xPDc%PF?PC17d)8AZ<8! zAB&{+q#VH>m4f{PXWP2D_pJ2A>^O-8i4nX@ zyVAk_7^$CA!|(v`HwNqHxIZ#Kc!HM-$MI|2dFNHkmjx*0EPkx(#iu+j&M$}GLilP$ zs|wI<&9xc#VUzZQQ5pKL0`JrxmBAa5wi$SW?N3E{CmPrHYBVh33rhKuR_l7*`8fPw z)X|!{-d`w&ew*&?jFj`Ge?IH?POX`#d^!G;>d8=k@iw}h&0e!c>KO^{Ss3D5`&qiK z!l!lVgP?oV=Z+)#7qxXe?sc-W*z{X1-OktC(Cxm<$VK2q+}8cVkypFH6HLAW=RB1YfO5 z>|6WLlDN>hmxiGH*tNdl`Mp`x0lM+sN(fShrKdf?)YWx+Ulez&*s8#Yy5I%H1Cn3? z_l#%leM`ncH@KOupBpltg09v#l&hLLI1UZ&6%D-Pv4_feP~>y{J{dMPGs+KHit8Z3 zVTC$-f4rPqI%`O%FDU%Y-Sqn^;JJQ(r62s$k@JiGFdXNfvO*rQX~llrN2>M+UeWDc@Y&{rdxKvuaIP-qJnM|2o77srZ`WLHB8mA&zCQqfO^gO-RpRAKFPZ|nF@d>`0t6>?q7F*@jrJP=Lw3g z&9;(gC!M_h(A7+uPEcjviGD+!?T3DZuB132*GCnrbOvusAo?8@W9=23SFgk9r%3SA zok>yFo;`1{?57^D(67<{AvIBciAuAe>$XGJ&#&(efcGt(gYvicM8Byv4oU~!`m*R} zm0+ny@f~a5@T2=ue$z5Jpqugs`e`+7`|>@!T~&=lKd$z14ng6~eHRnFz_Y(b5^;hr~Mc4H+ z>gRdzmV7S?p5Tt~?~b)E|Ld^yEAQUr){K-d`HwhnIg6B`7*ot+?!`5=&Z2xwP8BdtXiJz74u{ zA9Q=qoqIWW5j!z%pkx6}g|BKBYzCg-)8s|mR(FT_-7fD66O{c8H$8%`;LJiO|NAJ6 zTU6M|Npij_r2jzh=H*Q(NZIxz2XEt3{oUGlum1lkcx!uz+w@FVfA#Dcj-cp=Tq+D* z#B}}tHeUwajzfR6ab$l=w+VPhPE-Z2^o1p|o#sE+&!ODLzrYh*QXrq(C}TPQdfjJ^ zpy<~PZw1|ju0^2B(-i$R-Tmj|$_Ui}VTK$`$X^r2bTe!KXqDBGa!1Z<1776{E_exc z`Ldmo|AXhC7B8F&o?ywJ1zl_3?4iF`>ppAtK{WDK`3R zdQ?FBd(4hK*p=hVFOWn~31)XvyVj1kCJl6n%Amidy9*oPIh-l}3v@rb6ol?W(^sD8 zTh>6mrigM?#ikWKn}c^OdL{4#4@BK}tevg)dgz$y3*Xpe_FKI&<=OI;IUbqglQ|zH z_;Bk4N6s_+TZn7USDEuy=6dY)lDU3m?uRn>N16L&?;n}_sRY05niD4X`BR3%uDRdJ z+<#@B2bt$%pC6g$sm$}W&zsEiCsQAQ*Am9|c5^)m=#$YEl>2Jxk23X%O#LEL|7?A< z^;4PpN~Zpjsn5X1%~pC+&u>-y=$QJhO#N4;J&XM(+`vBmu)|-OuudWaWefnnSLI) zr2aI|+6DA`z`hrhc~6jekJ$GLnfHt`?;T~{L-xI7-&4Sd-cLO9-m>p8Ubv0-nlkS> z`yRCKMKbS6W!{_0yhoLJuabGs0wZ6f@#Xz{V`U!4yoZ%}FDvt&R_47;=DkklJ+I7r z-;M*685fWlCjcwo3Gik75HKuvlo?0ZafLGD3_A`XGcF-BPO;+_JC3pA8ZzS?;F40I zzKnn7b{gcFagZGsDKk#O_(|%k8CQ`RXOS6qDKidJW?V*QoCX}%BEXmNTkqgYo*Bp4 zah)>bJY~jxc3enioM^|5%8VoJxYCX@$&5RJ>nkSnt!>7o%8XN$8MoSTEtzpHnQ^Z& z<6vdR#de%bJbsq<2e5&Y-?ui8uhB2@cw6=>9)C-FmT@`SHILV!GvjtL<9IUTdOOZn zX53HaI{+@zU&Yn$&h``xC@cbqccdCGkE+3!Fy z--XJ2C))2uWxgXxFf7GqPrfgEJ;>#o?@Th^oyvTND)U`xzgx+C$J*~&`<<)Icds(v z!6eu*!!l34kB?mm_RV)PneS#Y-_iCvTbb`}GT-53zRSscrz`W_uFQ8l36|v;tnz)| za9faXzVpd^_mi0i;5_b_Cs1bIfXqAsnRx{}&!Eh_gPn%}-YB{c?vsk zL1rF9nRyLm<~{5@2$^{iJ5Qp_yooaND0W_jWPWAd-k83bXCX81V&`F$nU_&!-bR^u z95VAdWafFu%=_4RAZ6x-NU+$HzdUQ3c_TZIL^8i5?ajx zeqYDhJP!#S&r3qb^OVr>{G})7!}FTZ@jNGZJnt#niRVGV<9Si=c%BqI!IVWWI6Qyq z#^6|yg2KPqDiS)LXBC~yze30Jve5B7EqFX{i}5ngQ@jN$lJns!1&x=FH^W?%)JZ}yj&!dCK^XlO7JiDBq5{z~+#O3*S_hsu! zj-YJkd3izNd3xx0-X1!h*O&XDc%C0Tp7#fj{{wi!=l=rW@qYrb<-dX3{rdq&P;CC6 z06za;0H6Oi2%q>r1o-@a0zCd-0UrOq0FVD?fXDwgz~lcN;0ZPijptgM|A#=w|3~&p zx%|HbI{uF$DF0WW@&6&{_{^@uOF_r~sRW7tTS3SFwV>nw zTykB?BLDvapZ|w}&;Q53=l^Bk^ZzqX_=2Aw2D#Se|7+0k|2F9O|C{iL|I0zg|LdUR z|99Z=|2**c{~mb!zfX9?|Np=fJd-+y%l`%4r1hc!<+%L65IX*UDD{T;eh`=45*P6C_4V%2_66cbl4>R9||4+FNKc( zpUQT{|5Jsh`2Q++{J#}E{{IS|;Jb~x9R4rsME+aE6%;=IuZ52P-$KX#bD`t^z0mRh zUpZf17>V;&{C`;Z#Q%%I#Nq$SQFA(mxPl_%|INZz{Qns`{vYkJN&LSW zI{tqxw&MTU;PL-$@c4f>c>MoccqCZv-S@rxU)(EsE{`iHI{se{9sfUvj{m1a$N$-( z_;Hm75f!{$9@LjvEKoB?1uoJ;M3|S9c#0n0(9)RAUef<4A8NE19a^703G{5;5o2g z1bFNxAxP{u0UrBNfG4;vUMt7i>}P@Jz4lO|1WkAj)IE6kIR+so=Qmw<1XF$0FB9?AHRG zVDd#}J@$8THx*3j3d;Gh9}INt7Xuyp$;kB)`_Vwhel_5+pAD{u{cgZxKO9^y`{jTq zxbne1kNtJrJBe>Of>J*F@j%CZJ)%?W=K~%40YS%pLEy2U5P0l21RnblfyaJD;0f;S z7}sZiBe&$+k&d90$9_n79_*I{9s4N>iXRhn?AHVy`#H(|Q0(^v9{WLo$9_?c@C8@h z&FQnhlsl{IfG|Pfvmcf0SL{~>9s5~9$9`DQv0s+(i2by{W4|r%*pCZ5_Ui&qaOBuv zpZ&euy-iYjf}&$TFhP~{cimptPYgQtBSU*)zcTRH&kQ{FJCps2{m{T;zci0cVm~$T z1WO-Z?^&Du*q~#-HsLAubAyik-=Jf^IOy0<4m|do1CRaags0fA4m|d=15a=g`%GG! z{qUe;zdSq#_S1uo{r3ck{raF|KR@u;?+?#`{Q$vZzd-QVPtXy*;JLrD_||4WLg?79 zQ1&bKGlY))520hfMCjO05j^%=1dsg~!DGKh&AX=id-iv9N=+}~3(E1>4^njE7YQBv zNkYf|lhCnWrJOIZpCx$gcPXgY4--7&pGn4F6Zrf${*TIjoCQD6@r*ww8UIdY{5_TN z|0Lrd`hPTjqh$O@mGLXJex}O!os!_@YI%L}M=kXBrDyz7t)Hqgeybe!0`){0KUXq- zuVnmSmGO&J#!uGz&64=fmU)%P7k}EoyXk;(AB>-^GJdzp_~ELV+E3T|?UM21RmQJZ z89!g^_eEgXauR>?M0Zm9#;=@=pSkrrSH=%r89#Mp z{MO0%v6Jy@SH{oX`n@aT2Ty|8e%|)1ZT#e|-#i&VdS(3Vt=~NvKYTKN`PNTg8NYpH z{P;<*o;${~w(;|~e*Yxv0i->dbppz)8z8fez^*H>>kO1xcVO2ckgP}eI(cN2tWW4O zx{z`F9T6i|^Ue^IWuk!$(*L{G`>p;-o@VXH21rID*>+pIJ|L5+v zo}iS^>qyWpcwGr}yv_tVUWWo5uS)@s*QtQV>sEwEyp9DtUe^MiV9Y!}9bWI^znHqv z6BHh=gF*ks>tdkebuxmojs`kjR|6ievyuLt#+KIqQ+XW@c)Tvh6TV=LY*}1huj5CH zaXU&-_`Hrs_7kt`5kB!cALw`;5OlmQ2)sWk!~cbN-4J-ZjtD$nR|FofGZLPxH}c!$ zI2dMaUWbJ8d0i58yiN%^UdJTot9V@#biB?yqrv{#2s#57(Yx6ob=y+Y5etxSv zK*#IfpyPFMp6Gd<9C*BLPHf_Jbl~y2I`DX%9e9EnCI-6J=5=_YQ@kz@I$oy-9k1Ji zj@R`;$LsvS<8^<6#OnaT<8^`H@j5}dE+yD2B-G{ggMPkZzD#hoRd)d7UPX%j-4;mEiJOsa#&q>E7Rx94Om)ohNj>?o;X=@j6iG zc%3M8ylxcN!|O=F<8`ID4qj&p9ROxE*+R$bZUu?g;X=pjbD`sP zyK+Aiuj2)e*Y$$O>wG=o^SWQ~cpb3VO0f93Law!WoiKE~ZWuaVM+_aWFBYAwJBE(e zA%n;3lELG3%HZ+3W$<_%v!D`ue<_1&ZC>XL9j|+aj@Lnp|BI}XhK|=wL&xi=!Q*w+ z;PE)gTPb?=_= zc^y1>f}A>*}H7b@$NmI(+bWT|RicP9Hp8w+|k# z;}@Q+=l9))yP|k~zc*n}Hdj!}=XL+kaU1~XI4*#kufz?2j^hXjN?ZZ(IL-igCjJ1K zcm%)_gJ*aWr{I067_Ny|piKM%W#So-iEltA{=xsz#6?ghPJ%LV6O@UgVB;zP=M{hE zNxX%;9kx0q?t(IL7?g?2fOrjZ9VU*0jq9LHoCjs%KG--AHZBC2I1x%PQ<@x(wM`re z8&^V^I1@Gw1(~=M%EYNqCT@i?aV*HhwICDc0(iAZi70EEI2blAhB9$7$i&eg6IX*w zoDF5-ZYUFngG^iw8>a)f>_oU{;&zaU<6+}^C==&{Zs|B6HZF*b6QWGq5F1B?Ok5Eg zX9Tz?#TC!Q9kFppl!;5COq>!M$Hc}pv2jk6iF;z>pxC%5Hckq#;HPB1iJM~Ms3;Rx zMVUA&HV%u8%R(kji!yOrl!@bF5FTk?P^ZOG2Wo!9SB}^O`W#Ymp6DP*Tks%XT z#>SZ;6L&_LI5ajc4VgGKzy)7Je2HJP;rH5}iDP5q+9(s}Mwz%bWa8qGiIYPnZjLf> zbd-s!Lnh7+@IjWszQo_j9QUYa;_#4(%cD%39%bV8sLndB4?WRwe)vCO8?0 zCeD+M`=m@9C>tk=Ox!3kaiqw^m9lZBl!-enlf?Gl!=>0CXO1JxN0`envJ`rOdK{6-25<)C-K>8<__^qoHiS` zjZ7Rj8|O`#xNl_Qz}dKPWa7jr6F1Jrkprgcmn%%-%bk3f+c$CM$i$r^6NgTjxO6sd zosDB>8=s6xDbQ~X1Y~px{;Bov!@Hn0# zcpP65Ji&4^SMISk$6thw<1s?V@fo4x_>ItUJV((fj_(K_$9n{i<3EDO@gU{=Bt9f~ zf`e{VbF9trBW1h9lZ1}rOG3wSC*^)fJWA*|J|%b@uhJ7f$FBsB<5`NWIKCx#f)Cyw za;(kqFQJQ-c_DNhA5(M^KNC8RrwLur9j(FRc$?sH{7vvU9w&GlpA$U6;h*BU9JkXQ zI)FSuDUaiMVji30dqT(YJ_QxW1BH&`gM!ELLLK3A{7~>Xo+x-6UsSd$!Cg0Vxg2-Y z%@MtJl%ViA9w~GjpA-NbJ9Vq2?2tgeOQB zv%1#ic)ZYYd|ug49IqETj^hg*$M=QKBFFs|zT!B*;B#DH@HtK}_&rCu;0un97vx%- z;|fE^afYGexWmwKJYwiLPBES%$1Mhr;}{D{Tx0M!&M|l#_gLlReRMJZ0!O&a&8Q$Cw7-aU5pwI4(1I9H&`$#BrO!6U@^tk85p?>kJ*od4`VT zK10XxprPY9(Si~;8a$384PN}fMEE}CIMd*9+-dLxPxnaZay)9cLaq!z(Q}+?=s0e* z!zOVYYv?%6HFO;JTDD6ZZ16ZPHh3H-8$6Di4W8iK7RQ|!yCa<(!wb2BqT@K*qEj4q z8#<1|4IRhnhK}QQ<2i5~Z}2#-x1hxN29M)@gD1FedQ*qvfk%Bw7wQU1xf~}PI*uC- z9mf&(M9*=?q2svYVk?eA4j#uP2an^FgU4~p!4u5WHG64}XYLiH0_wK?uT&X4l|K*xCjpyPZ2&~Y9C(Glkr z0FUzwfX8_Uz~ejw;Bj68@C08xPwQEm^A^Z<$zuQ==QV(i^Bv%Q#CZ^)7vR`pt4Cpvd26UW913J#DAw1$d z8{l!?4e(l?2A?=D2Y7-NPZsexUx(|5T!<1B9p~|Yj`Mmz$9X;kiSvM0JxcFeoAbax$9Z8KIUmjw10Cm&fsXUa$adm9GvIOF8Spp{4S1ZF z20YGJ1D;^Qz(T&YFQ$b~^4mbi`EH=&JUGyCejGdplP8Bv-W;1p$L7^hCeIF;ygR_e zxk7zwo4h$jFic1q)eV8oA-z$|54?lDSgR@6q!z=oTtf?q)grdZSUmYCPx4Xq%Mt3Eyi{cJRFTPBW%F7oljn*|-YYVBu*l@avU#%9 z?c}naz8q zOdd34@}wz~H;qglH8OeC$mCg5ChwZf!$y*it#rTnp2^EbCQqBq+eVVljq8=o^QKJR zH!^wPY+g825sI!n}^WmB?N|EdFfo| ze1$&>Z}bG^{+T?6WbztPqSi|8k1}}>mC1`pCQl-nyoqG;C@Paz5!m)hI#=>7*4muT zGkF)uKLIQ7H4RkM-j`Yv|-a1TB&eP

    P;Y4dK{JeyEWe9#1lPJ;~(xME*~?K9d*J<_RT}H#{lD|<^S8p=6tYt&YT|>^_BC*O8q3x zBP*ylzpT8U1)(>2XKfx@o0pbMo?2z{)&l2@FXT!-+jH@bJ0`EKGI?&vqtJ~kG1l+CaR*X zlsw3_w#oBs^FEWw18ws}v!Bu`Pwu11BdttcX)<}HZQf~{hgwNK>fc^ubxmGso2T05 zttOMlnoOQ+oA=u0!B!?OHkmxxHg7hWJlaYyq*8R(+9uDo&AUw|54X+JZS!_3lgHcU z^;Ra&x6S))^MEVK2cDtXX2;|OS0+!m%^R*HpE%zRGI_?ydC!%}gKqPr(~Qcx-!*yEmC38FOrCWzdDm?|cHoqI)uSX& z`}w!IT$8U|nf&d_byn8!sd{e?>ME2<7oY4Cnc@V9Iy!J6lC`_>Ma zhViJH_I(O;Q5p1iYwwPjXQYVbIu6X9*x*s|weW*cqciL8)Z(czuSh3j+`)4Y{5NZe zUn%_%H#AosPf(5<&@F+Wx>P=coR8Y~v>(nZ|Kh}W4yT`DUXh+B!n~sDQ~`c4s?vf8 z@Xk&xCijg5SJVjd5B}BCog1{>6O`>CSuxM379WHkjJoz-x1(<-;0HsDxc)!SS3!9> zQZ^M-A@`c$y4yY0^>}EDN8kx&jLhbD*-^;ve=-J8j+3EZH|S1Pm?GD!p3*=$zA73$ zr66s*om}>ldlU1J>UD+ra(!y}y{_Q(+EExh!2#J~`12mz_a42>1{7V-RJt8cs?ym$w!YBU*P-!W;6*D{4!kyL-#Vze~#$K=hXG)eyx#W)9gj{WIy$IqU+g`#*@I?9;AM%&_Xb&Zl>waox%p^FUSEn$asKy5k zzVEXmxGG}PjnU0zKfSr9 z``vx3)`R!We4h$#Egx(5un+5;q}%iRg2JDlRrl*18bPlTe60#y{`$K8T#Sw5(cuX= zKCR7-^HC=!HkI>JV`}33f#+M*b~24f;~q|x+!vJc7u3V`(vvUxJr#fZUb!Etd-^W2 z|Noff-(c{g=f2_bW-2*Dx0^2M`-rXbMr#DVV8v%goH2E4xZT=c@dSn6?*pD2eK@Y$ z(Sf!;bQ9X+Ijg6?;klESHXF(x{d>4Cx^$^gPt=h;s7JuS-SOSPkGdrjWQ+28t>MbQ)8pjcShOwyER4s8S@LHEWF5A`G0g)(A@L28A zQUAA>PK2&XwmQP6I9<@L)b^O8pes-iI@KZKEO?h2qFvIJI%uaV=Y5^W>_(*iPas&g zL3YR5?cc=1aa*rMKR|QZpGpIpVhMCRAEUohw{kTB@BH?*;9bkA+fQTXK6nvd z(4Q*7o^PYO)-LFwzonhQi_o6ZeA54grp!$4%XxjOh5lL%=sXbRuWC3E?dRfL^zZbz zPa*K~#C+@sU+}*++1z^9hq-%h?~W4W&D5%YQ`t|SDmE29m0y7Oi>em69J;Y}I zVjFlVTb2iJ)!3H0{1_#4`HZW|1i9gBBi!DlABPEYd1~9@kI+qNkPo_O$9h1Qol>Gb zm5tjUyicFf3sTBm3Bda;<`D4OrMZdrBbX&`i2IA%$&K6RcSjKAUn>e-$%Yp^(GUEg z+fkDjB(@qfzdm>^?$rXX;FhW2&77^A;({sXusy4i&@m z5FE~9PHRti{|j{CU-CnDa^G7|^v|LXgD&~TvSO==-CKZ{@9zrWg}>SeUJjFIw9>lO z;0ZR(T)?&V*pii@o6xfvbf3@GfiClOluwIaK7%gW`2g@%4ek!!;JyRoeCh4+0lwgs zbg2cEVDW#GyVfprC@FMZ#}9&T-amiJ{h;ONyFhngY7lgls@--(zn~rNCw;BeO>8Rl zz7cru%2fwXuzvGv&V_0VovpJ9x`LuBb4|CW8aehtS9d}g=nk)K4c*`0^MKdpCF+A3 zmHQ`n(URo`FJ`k|;0gXQlbp(DelI;dIMfxC@{4Tl>k5u(pIMMvriu&Qo3FY(?b)V0 z*}tNG2k_osEdk!y{-{;@a?E#??4QvR?zI1gatubI5}gX8*s!*s5olpik+&RdPWfa{=| zqc+HOQD9+QHx22A`=Git`{4*bZ%p(v^zvjrv8hiV+(+Pr`YEdtUY&eJ=w3)6=?=t!;zJti+^$zbh*Ck>uY;*6L|kcQ~Td&2*3W&`NXU#$t=kN7iXyXyR> zuAe<}!4HN;t_uTC@N4h4-psvi-KX!@I)cK__bfGZkFtgPVz;UpLy#Kp&ko&;%e}$d zx;-bpPkUGC1KxxK*}&V=IVO05t1@Qr^WProPOgyD5tQ=UpG$`ORJ^hNUR`stG;}RT z9g*#nYmsj6XJoV6e z;XI@+%oyT^FYIAYyF12#V)^d%f%L69_rZa`R_rkN^~-amQP%TnwIG*ZjrV-&UxMRc zl;w?s(Mel!+zWNiZ~5JH^{d+NHvi*5;mO3R3zNHi zq$|1kYsX=GRo^ND$(`Dm2C9<;ry>U(cPNc(${*6QzgB5({fYe{*Xu6yb+1#DzU$rY zTksowSBU#n9n|fxT)7Xu_Wr)8*Zx~9TudICJh*_w8TQJ2#KFaAJ5HP)+nTWoUB6xJ)J*I38OS~9N- zmDPH}S+704zC4${sflaSx2#+v`d-!TMQ+y^ul+pze2ZM2VL{~H*YK|A(0k!?oP$Yr zh4mU9>_SohoSQtKbb@UuY-~@-oayNE>*d`)^t<1h$065e@BU)J-2&tu7Juo0_i4}b zTSH$AJsn&3XbmTLK~WbftM$?h&A@A)Zk6dfmVO<5C%pU`s@QKE$d#E_iCnD%w>OSz`(zxswHt97w8UOQ@1uRqFa)x?JMT|3L; zp_8?pO|I|(uiZ3$x|iIF%NDs-k9oW`G-Zwrjw%1VkcGa2gLr=EQzzrtsK0-Pob)Xz z>)lTqZS*=l+f&CIeZc8dowAXi_TU%tTgULc)zCJX{Tx${e3IA!@8;%tt`{vTLto37 zV_2?Ij~W5L-c@Qcxos=zV7+dAhwVs>>o$tq*^J~A^kU7vVWu4X;{tuF_Lrb<(?+&i z6<+@dk4KieY}ab;^2Gd|bw4tZd%leQfVy(^C)-cu^6WPhwDhdemMOn&o|nFxQiQ(k;~zQjSNY_%r^}m~qpUYyiokk3*}odO zZ~rbO2W@dSzrE@02zS}7)}c`NqZezO*VFND6-<9NMOeyKi_`*nL> zayirWWc}AFCE)RbJ_-o2UmfY^M$~9wK~aDGC7GbQZ-ONB)eIRzU*Nh2*dJ=*-45i| z_AWuL=EaK^_&dJdaqu1YE6VCeKsY(*=+7rDQ$F3g4t?7)O`)&Mc&|PEa{nlOGhdXU zufr?ef9Umll9D^IXsC_f2^;wfR7LO4MhX?Hso@Rv&fY^xDU$}wDG1xrpsYXNk z%4Zx%pQr_Y=Ivg;vh~8>DC=K#d;QRs$zH$o$GgMauh0XngKblOUc>9hij?#EwLBBO zes1K8{x0gh@~t9|qu&azU%WZn>nG#ae8cU!7U1=(^IlZs_CN!!7qv}!($8kx-llcD zetAUOjr6tuuit)CdM$lbw|o8imK#m^e|DW&i`<6(-g$hW;|p@oz3sBubxIYqNA>xI zitX%qq8okB%5=u|>Yh`*>rT+2wERCB`T24?Qtcf?u5sJ#*dMx9RA;Q$5qX2iL6Z-N zV=p^(+xn?;P-VS}H`Hs#mB;q5z`q*lT{n9is6k)t9rLhUJ-z6ipYPYlk{j{UX8lnq zz3VhIZ|zOiyInc054VfiQ26>Ei?pGet9#e^g}rjocW!wv*8f+N(d^eEd-V0VL|LKw zY?}n+$_5T42krhQgZ1oNJg3O6ARCH$r@du=ts3_zP2a~?-hIo54m{7)%bVlLy;)Ni z>(z>X>XG~R_!unLD=l(5*_pHCpuL9XvQ7E?r;_yj^Qb+2g^GRTamcmJyAOMl-@7j> z**Xik&tpT8(f1~H7nZA94|yE)uGmH75)G|RuJ@|O|w{&k@%xm_2&c>fA)a{J=vBiFZ&_naDBEC<`gyV~A!Dzx8>2&YF_ zMtkcDUmJ?;i90+geWOneX8q@nT;cJ4u%aW@>zERJzo^Qos}A^}C&S5gs5KmAJ;~pD zPKB0!aop+Cq_(|&%w-D-zR7@T^o>~NouBR3AEGZ&mN3?zH(OhB0V`9J8}i9J|G&kJ z&)->-C4d}sWrd`!Pxd}`pU8d|6!muv3uRoGCUMx0tAQN@=&KVQkG@ZdBgrkx=x2fd z{I(6&tM1Li$Zh#?5X&`mO4U4W&((4q{`L!lg4+~0oxV-kYtvUGya9d7?+l}F;2p0& zxw-Z#x#{mi$gMx!k=)Pg7kM12?-*>i+?wBk;`dgaObS&M-((;kw;TIueK%Dg_kU3B z9^_Kj$Vbj@`Q8D)`qnV;dO|7-Wqti_b8^r)rFJ-`+@NSh`U2K&q3`uquidYGv68-z zr}#cm4}IH&T+;3h$R&>U&fjFUpONb~(mTJQljp^EP5E^u_R}hf@2}WiRX3T}UVb+9 z+E2VODY;$oYkTeM*uYiT4=QB|ul>Dz($!+ zUVERuwYm#_M`Eu(n0wD_KXrTTCYLg|*MGb$;q@nP7v^XE(68%?xu(23z1My+O#V*a zsROxDugc@Yep(kQ6~q3_=(?}$uXUHTS-8LY+(=0N!qFkzo@rUW@VG&r-U)Iy#J0Dy z>|g3YvAtJHm7*_e4zJ%mUCBEhQF^R{^;_4~BiHqg*KhC0>-FP(Tai;;7oH*q9s4Dh zd#pfdd-m~94ix?ffBue|I5sXg73Al&qt#oy>&kuCpWLbm-gPHymZ`iBts3QBmpbn7 zu2aypITE{F-~6;vf6Pop{q3(ua{HqS=H~u-e2@EAZ3`>wVttAqF<7q4U-jC}wyyKZ zbr|nmSIcg1L=L*MgY*Fzx?B00%009we9^tUc64{(9r{u}@ZL8sU+!JkYxIxC`J-#E z_OAQs+xc>P(ho_Cdez6Z16V(_#+@2Y(@Z^M_x&5}LgCxFlIN?QI=mo#nfLzdz;|^d z&v#wWrw+>c%(|vnucy88?qgd1zJ}bh|K88{PQ8g7v`?LUt|>Q6?cEnGF3k3*GDKCN z&q?F8rz5Yu`>fCP^0WSDN4s-77G}1weaiO&+rNswlHSGdL&vpC>6-GxH_7Nb)Rz5+ zdh*XP><=}fV<+%x$+uwomIiwFjZu!*ewK|LWMTb`bPdTZs#A*`bjhfzjw#!xW`ff@ zcX{opbKm{+g;ulZD_x8IroJ>eBe}pjJRfx4QE_e5A3ZP!xn95bX8q9q0fQY=eyxu3 zd(iq>eZcESNwU-TpvW)uJ>SCfRZl3A+`;;z2iubCQz(?&`Qk^hT%DT2_MoBN<_E@h zIy=Q_{HmY}h3}6*?>RMJL^yqM&yS?F%v-&W06Va3AtQl zn~`ht+&hoQ7kf-@^pV2kpz-&|vsZQLYUkVZhXY0ZGu2eKi;80hx+uqcnHs9zy-P)3 zyldWbZ0PTEah~bqFW7JE&MTzN%HIm#hnCSEkF(p8Qw_I&&fF3U1;68IE3DTS+DCxb zb(U14&u+eizR;Kd9f$lo$Th59p4`r6Ey+C`QHWdhKQV;3B*p`DXLl*Qz!-$t{nJ!}_7m8)vpn z*&P?j`d?MaYGJ#Y?P(2OH}JFRdtSzSAC>=z*WNGt%^}xdPEB$n_j>)shI@UnTtRdC z7O_V!9&R@)Fe?m-<HlY`fH|4GOC59c2M zRiA?E^Eg0L{|vUjhj+JEH=bZYvHo~)0s3ZMe&t9}XDILWr}GO|MOhjBG_4u=_?NwY zIN8PZVM%d(Q}6y*r<+3s<(g_I_YNQBS$*^y@l}tJ62Rk=LFo-h9d5$+M8# zp{8fyc4;?$GiRi`*PwPze+RqE8w}tg7lQ$yQqymqNg2ows-D;j=u2uV00UHYcgOgr+%2eE? zFMmHCXT4w$kGtADAUnD1OC$OJ9*M*AMjt!H^GJVr;oS$!J`m3K18r0?#5QIBz`pc# z-;@=qA8g=xs_!-Ad8_tSOyFQU?oH!)txEmy?n|b2KY`^sp#KQ`AF9iMiR7RmRSVgs z{IyVB*1xzZ+m+5;>^J(76{1f^)jLmLfsSmKs(od)TkZGfD;|gJzj^mzQ*R~W??BUR zPj8#@*PZMKRP|=;7xbvUciEoa&St-%yRFMZ-@_qaEo^6KE%rNlXLu2m^~5FYmvprk z<;X!7E_`m8a=f6O^xc2vwWmUL|D>&iE`vZ76(Q>Ni2XYWYN7XY}=T%jvuD(K`;E z9&II8wR;6}H-_;#rgya}MXtg|UgtFQ@y^GwqXvF-{MY!~P}CdT(fi(3ZEp|wb@NYt zJbukn^vCvVQ7#XAn344#KbZu}Rg#~BxxRe!TjaM@>qrjj8@|X1Jz3oLKk(gxg8wk$ zGJmhtx8d}i+^e~L+gF9tr!UtgSLgOra*t+YxKoV?6+0Ut|M{ZqZaOBzpdUT;(e0-{aaktpE)>^ z^+7wWPhy#JRO|E>eA%Y9aiJTZhC%g+K?ks0C*10__dM&|hXv@U*s_7z`p(67DxTvP5mn*Fs(l7i!4RJYsguhr)fd@j*r`~PFX|Dl!F zj+?#hg0hMmw=wEfD}!sW{*{9kkb^FmTEO+WIl^ArFE$1$m>&Ca4}It7@i|J>TilAi z#ZB|lH}Ngc554324|0zKa}&t*)6s#V{>1hCp^|qb zA$_+$c>QFv#>&C^sx8}-JA9%Pxx0%`W4Y?q&^r!p`rpYxe=IEIJ}p|$9{cZE2MYhR zrc||c>NxtU*QHPSWIscn(Zcgtzs@zBzo$A6|H0!i=MlF@C6(Cos1LfhWd?Ub27f#K zgyd8#PjiO=LEZ^+_bNE{Xd*CCAaU7Q-1h=Rndn7_XtCYY8$=Ft!IhYXIAe8u57*IMv*1PpbG5wlDp7LPgZ8o6TqY zQ;ovPk{kVw?Ne3h_>T2MbC=8NnsVE1Y|lDF2KL)3=3Y@AziTttAE?$N*+1x^<=J28 zZ8O<_sELElVt=RwN!Y)rz-b};f1&e!`{|hSA8W5!*scs0y!KQfb|}i~dGna zxixV~_IG;vCa?Xx`^^4O)!P$>dezV^>@PL6M(TA=*=p&mly;B{mDPH1Zm&J%D;1CX zS6>LAZ|*tozPedhD4$bn*6oA!y4Gg)=jv7@`*$_;#!&DYdi^(Fr}Utd&gKq5E)>f{ z+Vc9K561HPp<*{5#&UISzSo|%cKn0fo%Ou_=(cBgJyJPJ^7^DweBkwpnswN(VOiA` zr%_~17mE6i&*Sw?kL=9rpSqgw29Lvn7lZkKJWi05+ZS(RMsEMooV=c@U)p5kaY((g z2RZ1917oa=^8?-Jy$M_>>i_4<2MaoR*D&~1`vIjNV@F(_*-Zi@meSNK>^nILp-+@0*0q$r0BWF95 zb-TBX$&JZTom}eUi^*kr>h)*Pdyi&@n(|+N?WC{Z-g5M{IM|ZDNnwTQv&wnx>B_sW zeBb;zZ2*i*2`;8>0X?m@9U}3 z^cC9Lj@-2ZKIHtW47Kq)kDvHJRjI*Q$w7}EPG*0x`?{Cfb#5>= z@p933?4Y9W#HL7c!zTtf;FdOQO-?Pf$z|E@*S!@31)qHFT>1{B zuSws&;70WITi=U5>vyj`O*(UnoZqA%a=zs|lM6kv3+IV~{yQw#9&&GxyEbu%1;z5o zf2M%ykP_+WYu9-IeZO~a#p6&RZg+C!&J`dxvh_;~{JPdWuT`qT(}r5ar^$9+Yr3oy}u@Xai+|sujs)M;FRm|{eupFXpzf) zvo*ONMf}M@!%_sU6TE_DssV}_XU~mv)@*G8e}84`13EQ zSN}b7C{&f1nAkBoCRV7fR4qeR&7^8YO#*^G^3~IK+jXo0=G^!c%4@7rme# zIs5T9{9pP`^`7KP)yPW@I{lA?_R@r3tR;E;sqi1{&3;=ynHglkx4mRb`YH}CPv5Ln ze_^>g@ruVmhumF4?%058wJ`xc=u zIx+iem8Q{bwu?%K2ioBG6iN-%ZMLT-S9ab&sDj>FSl+rDG%fb>pLldx%5sMNwO%$klUwOk z3LA=ggEA!{|F|&wX`S)aee4JQ@HzWwUAA=zav6SJw7}m??(P4{O@BpM*DMl_^*T;? z9dgjzOD|fce6Q*h`j$=b+RyHtN9mjVqYQl`AGD=U)JFXe(1GdbJaqd{_5^kmZ!?$;IdynYHAZ5MG&d2vCnA4|G8J?mfni1(-Z#OMk5Dwul-$DCwa9%P03#zA8AIttM(SW|>?2rEBjtodZu53=8uX^Un^iA7Qmt6jf^~i;P8bhvMS#m1P^0Va9 zCMrb^+9v9YW6F(hwx=)gza0Of!gsNsR;kk`a`F3z`(~l<@09GPRj(w6c>THZoc*+F z^f@=V&Z)m!;Gx+jW^qmVQ%?5Ns`|D9Sg#uUwF0kNHYi8m$tN8DqKz(p;I*eOQx}o% zIj%bSee)WV4_(!PzXNTysEBLIb8N3Y#p`vCzTDgSo>Ap$(1pGi6;`l4#gyUsq<#0M zw6Pt_v-`3BgW1?$>-iNp?uFXy?_k%Izx-r>ty6C=MBkFLPaXLC?eW@E8Ql^d>`&C6Nw2Uy zW!&5myb8`!oW5uIu3F#{JmUUTCErA$taj#aKyFlx+T@^PmRxpvFP&yN%L}?t_?+cl zd-|de(RaT<7=2m&*l+8K@zRjX{C%hm{=$oRP<6X-06G5*eV`f|w7Z|vEi7hNNN9)) z#qz3&`p{RYK>&Tj4#%Ufxlbg0zs06;z$N_IhTN>0VdS#qJA~ybWR=%`pkWWv#?JpX z%_%a!pbLd>Y2n)RC9d3nzN=-T=v#AlxC?(NeU)4`pW@`A4t6A0eAXo%hreS6ll!?d zDO5wZbx7x$a>`#a(igXVfBJUL%fsW~)3^tHx>P>;CXRh?!T;^L*M3s`6^62MUNk3H zJfI>u=+HNh9aFA&c?*3TzIyGb!2Xr=t-n!)zU+^h(3j0$wq-}G*DXgjrY~qkb^3;uSVUj-`(AsBEVrB7$dGd6 zx)f+dF6K*qa_2I8?FZWYudiXnJA8LmMrLuLsDIU^-1P1G-jlvpfo=@8D|NhnF7)>7 zEKnW(Dj~VG2ZoS~Y5SSSE$nD}a?r-hms)cIOSwU{zBo|${A-`Jpb08^$0JktSd>+< zUG?ZYbG|M)pGM=!rENn_*X?_X+{@6?KUr&1w|93gT<$TtH?K2&XA5t|d85j2a;alvU!LO|f3>|EDs!L)+JoOZMOMY4JxJ$wdTI zA_whbKe9}DQ4Y38J?vTq`l_b)+Ede`Z|LjaEWC6~SJQEpfF$=-H`E}O#bfyRGd&~8_vj-BD^MGK1h|EV5M-`Jlc={uX)J3rSq zxI|w^y9BxEaoBI`Pebl;zh=rc#1*@aE}sOdphr`sx65|PWRHyROU3ejH~X>vRU4D= zIOhA#ep^p}>OHS+o%P8Aw`e;1ZN2D9ag=rCGc8#E?l=`#KQzVVr`Ebm+pXoJ18pdL z@!osw|5U$a^j&{bmA*n>Bj`)Bpc%QAFTL}4PQu6J7F{h&u4wD7!UPr?#c2OD0TB-{JGT|53l4nuGnJ7JOuXty;|}LT+Q}hYt94DZF-j zYjP`;71ZZu5!;kI^oank&P=OD-=lF$=sWPzI}ZBiU-YePQl4D$x-H2~zfp|bi_Yw? z_1>mm$U&Q=^SA%MoF^}RDVnpt)(H}PWWQE&GW%=2sCZ@-FKcCCEW1`F*oYc}>&>3;y-lyyNiU?I@IW_|E$Dy+2)tzBJL3$ZZ@>PNlbw zlbhPJ47rL`+L41spIvF0@?Yl?(U)`ZP#eFqBfAe&CoGbUKK-^2eRpQ%<8`P+-rnRE z)X7Qi)s#5oT8@q+2i>14fn~}cp87keck$uY^sW2FrtkMod$C*>KJ2w4QLcaR*n3|! zcx6r2H)(4_sFsL){D0mq8BRa+^s1S$k$G-fXZz={q4=F&gM;bYd8-qBQ#0)2e!iGx zFn!~1CWor?@6wU`nR5WSuQ7FTp6LWFyysNt!;%x6);S8;HFEjbQ1~*b*ZhB0TT%4Y zJXeMPhwtKMSg+F@@t#v7)CO`d|9eiouy7r@_Eu$b&_#_NIGL?xc845$EGX)qwzazF zYr^`~=B+R38?%wWuZO1L_Nh(7nzLPeZp!Uf1zPa`(X)r7VExdG>C?K!UkJvk6SkSi2^MCh@9{n#`aaZUf2{{R@^Ro>v(S4^&HbV@Id}F6ELXGpjsUOoR-H(0 zeP~^**UHuzN&23Z=|C=Cv)4Qh?Z&geRx!uD z=hT@eGLwV;S|NpN%HP8K(RX>|ZTz2V$e%r3=(4$ap!(j@uNKs<#{OEx`B)fb6}X`# zx#zdak$cv1CpqYb)Pb%k*Y?K2sK^|D(zn#7I(;jWvcJ|ndbFi)Om43o<$rpg+|bNL z$$ePsJ)fpow}|Zqx_@)9J23tr`)Cu(fnxhU_DBU)^#-J&Z$s08P@VMFc(x;>Yu9xp zzobrK@^2bHao`KP;;b4rWCnE(d@TXomwBsLGy3%cdrf#wD(_5Kt=tNcX-dOvwElFaU7Vo zzbnh-K`pMwU|Mbu7KUDT5H?d#Tm++3{_U|c94*KZ&cW3k3%T~SLbGlIYt9-&ST)x3=$=!?bB?s-?HOMvPG#A)! z>uk&8+o=EagzWVFXvKb8uc+B=k1W=U_VvbkefnbnxxK#e$W1F83DsTWrFV=5ln!!D zx$J!2cj<@M!|40I^Z+<@Z;RKSvQC>p-{md5uhZFL8jy?i8A@)(>EZkx=jSzY(23u2 zxTgHMcL;cWBWox6;>J0{|HK87T)8_F0N9SMgoWAiN3({AhV>kLzv>lA?)#(tNb<(y8s@G+ zuK)4{m$z(W%SX-ALLI5 z=O$mfS}*dCqL=gjAkW^uF18DLu2@HFqUG=YIxx8l#qX2|OGw}G*F)%g`}QY~6^Ky6uFnjPg~%3gtJ|!PS3`ntR&hNIcUxEXRQRa>bbr<&N@)=$sKY!ZhiXnxA&|^ zwOhw})wq8A9bLE-e^*C8=XU6TdfYCRv;enLEk45kLqnIm?ckX5_GPQ^f9h9d`G4!J zmAN03-+JyBb?Ynlm#&^Bko&2_xK=j!GrPEd)u+YW-)h1wul+z%Ro@k3%H_`Sck`J&nk=J`ZTIlYu+%58t} zeA6rL@ch#&ZV$lrsjJt9@Hjkg&hu5BOjwBfvu9tP&-&gndO zmMLHA$o8V&=3@KNe|YUlCmz7|rM}FohVm|u=J)tN22bG}_`wNwND*F#zHHQ6(j`d^zqNj}v;r|jlTyKdU&0!qH!=+!1}q zC11q;T&t<<-}TWeL-9K*MaGnD571G!{GFUd2A1A zdMRFS{$Ka+=5#9EeI6cl!eSRaayL#yFf#6k!oFARyyZmh^ z$|tuEgHK;cUm9g?cWA+S*Nx}(UR9dH>%W@h-4Eyw@mG**)2k}Eirt#9-fpdVf1#kW za~8Etx$wm()UPg$K7G3&d-ncY5M4g#XMfypYnL= zbK`lRr=S}o#;Yk$I>Y-wb#P}()?alV?-O;|N?tpe|>mtpEG!p5*fUafA2Q z>uT~oR2RCH*~b3?tz9aGZOV`SN<`nXDMRRc<@biitxwSo;PvS-CFxuH^&F4asiIzg z_RA#RH|t||eR55!*ChvSvgf?@Amc=*VZA~&6u+CKkJpZ#@8^BGPI;>|ece~Lqc87x z-q))HHHW(3pIq{R>Luf|l50`2FFEMlrCqJSv8_TMlnAk*;3wbeMc=X4IqA!KP0<&% zE|R{fg#)m^)yLL+PEj4E+2oGia(EnKPkZeKdhWuV(7>pDxQOYd-~7+#+{79l_ISTMZHC< zr=xFE8}B)F;ky<*4y}{$IZzwD?-n4RVLYD~RqYl$zx9O_H5{o%zc1Ph>#6_Rdz{L( zD%`r4n*yQ+8@ul+0zt^>raX2Y-w&ucD;v@`ZyS$`ez%A36Lir-UVF+leJ_uP`e2d! z=bZO^`el+o>;F1}=Y@urY>>b)y?b@D`?di<3K3K2Ymd{3R zT{51hDozy7Tm89EV(eetE0pIowX)0!Hsx8v%g}ct)p2ktj~>DLYu=tjU-5l)SpUXD zY*#Ak@F;S-{mH4(t1po2e6IvKXjH*(&b_%E>=SkVw4kWB@llR{QAeAyU8@99iTOL9 zbFd%K181^dP|H7lX8Rcu&VEBhmC8#ly66{6s?pHlS^eGX-G|wa`n?W=qJFzn5Z0@9 z71=MT51q@?H{rrx^i}o7zo;qOmyoMDx*FE2_fZk#;s>=N2VH%qh0U(HL-=%rtJ@^{)5Pt5jH z?Q%aCzxyUK6I8z~#Oo~eN~ZL#DUZrGgucWf91o+yKJq=Ix>%h*6) z3jT_+niCez`hzOfA?G`A3OVTJ&jnpmPB_VHPrW7`rEg5~Q2ORy=lzHFADE23)~kow z_?~wUYNYdic28d_IK+lnHT7xz3Q@^gWuFgTA#*5QNP+a z{BQai{T)nh!BFq{v~0JdJPs`y4sF6@N!}`d;+UPv6r;Z!B4?&t{4ucQd3S%4%M^=H!|ctwaubG}j~N>+X%#g{Jvj zD0~IH??Nj7-8J;RI$xQ-iU*t0ccxZta#bQ(zwV#<1-UoP3X)5=s~b7!l{S-{mHE4c zZFm{%LQ(&Yg#&D8-oKAdLvRW^g--y2FD{IgfKjnP-=3n;uwci@@yPjU?UzXfoUs{pd(=Qjf zSLb*>DCpWjajo~+mD}ZEW*3V3M^Dd1U)dSG=<88tdY5BI^&SD{GEslrO2N+&)?I~KgKL|O!@w*PdpylVY}AB@e|qDuJGTo&^I_S`vtu@ z<9_^qy4rj88+yc}+~n$pes{n>$j1IgL$d^ZjWy-bjSFDC{wEvvuYOgr9DU3EcGLIC z`@XHqv|mK-+^p(YuTxHLOzvIWj^rAZ_u3D1_sP{^rhKj9J^K6(7o~4t^)B>H{<(tf z>2f)qPip7-lrHK$80<%`dPer=YTwvVY(KRV@qAU#8>^;Rx0e-iFOQ1vLgDNC<*5a& zztd|^1#>n;SslLK1nX6+XI02;n7NW%M{it$ZXY+AT-wwX$w7Z6d1C$frMZi5L{PCy zdet!cYF**=PG8>qp1$XK^3iv>RS$BL0&??ssTOSi`tNiZZTx=Y6-miKZ}d!OciTVM zy;n5914aGa>s`kF(6x4V1h3boEl%I`hF2Xat84eUe|4hSQ7G%XB^!{N9#)&&m^0JJ zK|d`nXn$QX!tL}jT^JPp$qf(D=Y)pQ=a;xGeH~h-p)WR$*Pd2i_nuEvl@A~noRar9 zYF3Sz8&D6lcxZ?%%iXu1`dLsc7app`PoLBWRZ_nNmER*LzfVrK2g|i=A351>a`OL> zgSL#hY?-qBzx2ufPoL}$__XXF`ec96C;N|_>`xvC*}vpuzeANA4|320yL@d^mg7aA z96ufhIiB>%@ug3Ww*$XXISzk#+X%XvqioQL$uc}bs~ zr}W8rOP`#_;FO%#1W7E zze7&?C34Vvqq5l2U%6YlC8FYYr5~eD`ZeBXOFu`S^m|Yx{UFxMK(8U>q@Uz*lYWz& z^sD5cH9CB;q`!6Ij>~03;gf!tKIxZH*3wVYC;c~l(w~!){vDi>{+^ul|K#NQKn~h* z&vHwy8_tl}AR7u^t|#=#^#!WsdPARFf9R9z5%06*`b18ySLEdSMNY1367azIk~=)lj|)xx&D%q>oPbk*K2an?r#EYQ67~bsFM2wa&o^wPVOIg9OS-&oZN4agT8P2i*3qsKjOeI_b2qp z{R+xj?qBGW`x*M={)U{~?|@Ts|3gmhi^$3S5;^F(Y`ZK|misCC-2JPKVJ7kQrp~@oBMQg z-)`>X&3(PO&o}q|<~hJT7ntV;Xtvmk4xT3_?muan=L++jVV*n8bBK8^G0!RHxy3xk znCBYv+yia@C54OUp&lojTjsgQJSUmwCi5I+p0CXFmU;d%&tvBK?0=u%@LYFdd_<^u zzBA8z=K0S&51Qvg^So%DAIBypXPZKn(S72$CS}~YSmflr7CCv( zMNZy(x!~o!7&&O1VL4oRUuKuvsHn19%X>8XgDV+0DBerT`%3Hl(xNUDK6#G`pO*KU^vQcp`sBSQeeyn(*CTm9N>1LFLY2Hf zB`5Dy$;taxUXP$%BZFO2miMvr$@^LQ67>4^vU~j3qE;&PM^F_r%&FmW4V_1?d0VBJ2`nTPfp&~lY_24aoRCu zd7n?8yx)gU%lm%%&zAKQE?+xUjA9WkYl;wK_+mU>q zpijP6&?nz79QfsX27N~5I|r6)`R+kpzJrjL?;_;oy9s${+zZoV&_F7At&E$$jNsca`IgV=Z})_KIEXoGFX;;4{}FDr*WaOTFZAL z`sBM2eexX%`$frjCHmw$6FK?rWPz9OP~_yh6v|4zTakn2Xy#h-J>mdTUcPhD zC*Qr`)AAjRKKU+2pL{1HC*RG;$#*nz@?DLbd~YKM-F+f~E#KkX9m~f!P}C>i=Xf0D zdmVl9{SK<+dmerAeUF@c@5BDk^8JsTd=Dfi-w7S?^8L{5@Nr};6r6ll#Bwd)8Oh6c zNAmJLlDvGM1gGSCB{}(iNlw0Jl9TV80 zU-`aDpL}m6C*NPm$@f@t@}1Vg@5}dFa?mwJ)>)=3-*@Sg@4eu(eE+3Sz6aAM--qdw z@5SWg`!PBBo(xXQcV=?({h1uJ^unK(Da-e1`s8~x_rH9(K$UR^ypzzDM4fyX|`?OAO%lHy^M5hc?ESGU7^vO6B9!D9MLZ6INp-;xGIN)R)3pp9r zg0hxzF63nV3ppsp!N~X+r~lGIHWWS?Hv^xNaWwSFxElIooDF?4?uN%f#^I2YaXC;e z<8;W$_#JXGt_S~@f?g^XVwi#(Cw26*OKE=#%kh^vQTMaxy-RoQzjv{W5-yoQ!WH2VMMfoF(Jl zV!tF0v7x9}#>3Gk>$sStrQ~FsDUXMYJ0&OMQOU{pR13U}TO|i=8S*&Hlx18i z)+-t3N}r5-rBBAe(kJ6$>63A?)_sak=!#I9>W= z+%A1Gju+djWqdDvGTs-eWc)8V84pZO#tGy9*D`*X9JHbD49ApZd@+48-q?X(#vjus z#eCnqQ4%gM?3b8^tbH4C{iF5TYN&WeS?FXPqelkw~H$#{19WPCe) zGTxn>jDLqJ84piR#>bPB@$bIx_g%o8y42FyGHGq1qRGcfZG%sd1$FTu=H z_}_U9nBNc?n94Qt9L&52GY`Vdi!k#f%)E)0|IMQ?^D4|d3o{SH%*%jUd-J)bZ02p4 zc^qb5hneSL=6#rXAZA{OnJ0qzBiNs2UJ3NypTVvvn|UW@9*UWlV&k%P9n z|G|-YOHQc~xm~DWdgJgB^vV1t`eeQneKP-vKA8_iPUc5}(=uO*oXnphC-bYwLD%>A z(~)^sv0W1eyHM~lAB#Sjp9NJiUyDAOzeS(S=feM`WqudAy?OGIllfm3c$ptY4qE%; z>sXmLW_{{g%!R@y^U3Iw`DOIUw?z76{uzBTAB~*MPa`Mu)yT>GHF7e)4V;3O&lnvh z^WLmice1-s)Gzbl=#%+z^vQfV_D?c@jy^Mw&djSb^X$yLJ2MaOf9L68{@#qg;<;uX zpPAQZ=J}aW*(uLXK3afLT`WC=9sdXmuTiGnt6+69;2DpXy!SZ zd5@S6iTz{dNt$_+(BGEjc1+pKt2Fa0&Adx957W%cH1jmgyiGHY)6DZU^FE^J%$%WPUBrCz*ds4jQrOs%6SDKbJn4uS=iI--S=hd|vuwey`{2?LDW; z{9l}BTIK_jllj3=CG&^LL5K86Y0JD~x9t3I2MS*18?)WX{A2oLJ~DkWKiPp_<|~tv z`O7G4na@m4<~Ng*`OoB_IU44(WnQ$q@2$;te2 zax$OX0x$E+$;rHPlob^7&t+b^yL#jy3yS43U!6XgzfPabXNOPA{C4_`%Di{-G7p}- z%!?;4^W@3P{CTL7dG+L=eG4VFOGC-FPTNqi4-&~lk~SQ7WcNtmIS z4FxapK{aaXL|<@4B3_#_?+ zeG;FAK8e>tpTuvWPvW^imBe=;C-Gj$bq|XvC5sUkhMdHUAqUM+DyePC5>JLci7!K+ z#G7&8llU|ANjw_*j7pputXC4ZhP=eFAusW5$V=QC^3X-+k6WfJadGIAI63esiJL>8 z#L=No;_A>Radvn-B<>D5iN^y)d>(QVw}%|`MuP~;lqIeYkB7whp-57Nn9iNw8S|g zCvlI+NgO0{5*G>ErzLI@IcQkxDvl{jTqP`55@(4%iMvFf#9_kz&=Qx4K8e#rPU1E> z;OE%fpIYKNp{ynD6FKO%9tRwW2W8KRzG*?hOPnbBByN<8vc!?1PvT3_C-J7pN&G2t z5|4_U#HS)B@vF!|FSbtPN?a?uc;K%V6!l5Gs~D)nzoJj#VL`RT$D&W-Ws#HkSv+16 zPm7$y*CHqJw=D3`QW7If;&R!ICbS5HqF#yDh4o6}chM*Dyy%noUi3w@_u7-h{~{;x zz{p8_Fme(%j2sm4!z8YlJuWDt1C?sE#2bSui9bf4#3Q3m;*;V3(h{$XoWw69C-Kb4 zNqjSM68FpjC-Kn8LF;wfu2KpnYe!@E+8~#t6uBOUO8iG2XNd>N^F`uA@;s1ukvyLyek9f_i7!bGn&{R^N8(O84Js6Np{QTtQNpJs zJ|%q;uaZ8AUrC?Dvt<7y@h!L&#AtfjANuh{SYFG71FQrf7nbIfmP1)Wg-YI<& z|CBz7hw8vD@lnZ1yi}Bx#8D+D@m0w|Q?0!1n6kuQrBC9q!lxxZD}55Ll|G5zN}o}Q z>q=hYyposrujC~jEP06&OCDNc&}he$C5|lnHHj-rpTwDkDv3KwpTwc1PvX+@cuAaE zauTi z*un2-zsdfZ+NkUXOX3gP+eW^2pr~Ks5`)tcr6VKVidxloI zlGR2W=24}@_Qzrg7w2@Cn+muaw zbQ3S##7{Tz)J=SKQJyancb(^f#9`<8Byrh!o=BW_sFFDDi3?Ak#EEA=C2`})NgR2ombmidB+fiJi9;WX-+^AvA7V>qL#S!^hun1l$FH2Cns_6$w^#%auO$>TbDc@pT8{0ZbFp8`3_uRu=nEs&Eu4CJ85#~^tcV(m;JHWc+r{s#Iap954& zeh2y_-vfP;{{j0$Nj?a2k{^Pc ztCAOpoa71OeSzc+V*Qd&2#WkdSWiWsA;~{v_b;2pf}(!OOT^xdP$%jNv@+6Uy{7K+6^t@laSW}k#O7uy-CHf@)5`B`7i9X5CM4#kq zf-1@1L{9QKk&`@6ypNOoPvoG7w`#|fB|j8>k}t}EU-C!MC;6mM){61KyP$hW<>HGhDga73pH2DZkenOM4(Bv~T`3<4V!-~14Z1NwP ze2AU?%a3^Bqt~8H{zQ{c(d1V&`4&w+Mw6crYBkC3nzG5?X!1Fl{EjByqsjkh@7x`)Z`&Gc}k&fldv%4FHKM{w`=m4n!Kha&*}f?J#9FY=atEe+I>@2 zo_8j1s>!2j@~lFCJv_`p{?&n-61yf3tI5l1^0b<~ttOAF$?KZwzdWxGPI~RfYuF11&^6r{Eye3bt$=eGZ|DZ}~Q#N^hO`czq_t)eBHu-@~zF?C-*yIy7 z`G!sYVd%GobuCji`H4-wVw1nv1C+>eq+9AyQ)GoY9) z`Ni!di?&)&ESJ3F^!3ZXgFeYiPM_o{r%&>hlaoB=tia!}+!m;C7V z`vUQ(s9*A?(o?+(1OJhP-f@U~ek95&Uqm>$KLYEJ>vWdyxAmzh-uZaG_)&7usrZ`4;xq`azLjT-5(4Np^DUXL;XIU#p`W_uK3D-dL}r2j(CLZ8tQD zZOVB^#icK>P9#)cnw-&smaf%?zR+qGeVzMq9E{qzi^oCRr)H8{RHqiX8R;65gZ_5s zsI_eDAgkJq!ZuXuQ&G-v8@e>`Z~B&e3#M;G$4>M;`G@0R)SP_UH{qT+#bX0}k%C!7_jdLY#ej5tkv{#ksJF~7SeFc5$(06qt>(`=Oo_X)T z7Wk>d3%byqD|!E~n`Y|CcJXm7pAR&&#+@2Y`XOoU@WrWYDERd4_wf`p2Bk7x0To4p_{K)4>RQ* zdHMZRb-hy;yxO|19(_@IEPbaddFN-=9A{bol~Se1ZHVRX=xJHL@HkvJI>g5BK$jl& zcTBm@jf7aPx~$DY-@32-KXjo|F??>#ps(vH+enls%{mcRn&Ho{rn>aekE}vsJI#$7@H+?+im(8!Zyvfc&QHwaIS^oKC*yYOnol`EihZ_vT@Ct>wU8KA-5(=0J(2*z2{Ttx+?$2 z(^ZCPjdRi9zPP*V3^Ft5OpCj_ySv*A5ZoOW_r+mx7Fec5m&F%%cXzk%p40UEb)MUv zlecfv+@{IROQIjBs%~Lv zcpdMn(_ic0LRnc4z!oV(T;J~9i{r+6fAl;yuD^XWjw`FDr@eMGb!n)B>u-^y8P4l7 z@5_+4tnpSHSLeQZ?Ph)GD)N9!I_GtLdw=YT)Wtv0h`I{b>rpqu8R9~Jdeu|v%KZ~a z-inW%$?NlL6s}j5$jN?=8ueRp@HH@^VN$o_xx{wd56Or)zAR(_b=AiGf%~D(HR}Yv z3i+cTb@}Gqv&7VwLcRCjh$`)1tDdVHkQZlgW%7XUPTX*IM=rMBRmDI5{EdBwkO!>!=y;@Wcb;7h=k=EBjZv)wk5$n3I>f91AJNvUl7et}ZIk@vg`{k59@{vZ5*wPi{NoF}%JKHrM5C)keLRJlMothb%J<^a>} z;Qdvl)AWa}HdU!dUBi^s$O{?%J9$wZ@A)ixXg_(`$64e7m!x=W4bIfcUNvol14OwW zqNbxRRx3UqI%lD%F3L~gW~DAyr=H|RPxOiNK+X>OYrXYACi23D#~=?lenlGl_~OBK zg^NiYAj;qHcYF)j?lt|jp8c`}busS$i{q-qgkj`uPdk;oQ!Q)Yy#ASm(%p7Im3#dI)mz;0 zyHYL|>jC&EONgBcV4^s{$e?KQ!-Q{4``RUZTa@*3k|8exTz_16+Y8n>m3swQTHHT0qT4_ScZOE zuXr^B*R7{5rQg=MmM3*_J>NVol63}Ohqfv}-M(E9 zE$BbQq~F$+!kfd^3FkBx`?P#%`fYXT@-O-`;H>N+wr@XQ(Z|O1t^b)8sOS9=m*uCg zNx!Y?)PBNx-1KKV@>U-xLSFFCa}N0brSa-xT$hos74S&z{C3ORwe7PbPFg@5-@dX2 zb-RmAp)To2uRS&2dz8Axi%XE_=Ahr!;ZNd{w`~mlwx01IhKq85aR#QblXS>r53v&v zalHL?_J4H!H>vnOT2`_r__}ZEY}B1R5ryRk3!wz4nx#^&IN1{8yE_)syN`*Qi!s@(QhGJ*y0Bu9LU8eK2{4_H`f+ zxcuupYj2fPOwzx>Z>ZX$N}Wr)gg0C2x7e z8wdOonBSRO`u$*`+*r z%TtrDYyMk>yqImh_VcjtEAoJkLNnREz3^^6>au_7!t(pvZ;9*G$$Rknb1;h_S0jmL;n0NHu+U6v)&c3;@&?k-|qY*3w0^C^EpwyH!B;zb1->! z>QbNT0aV*7cVT;)Rl(~ooN1SlyhlG`l9#14pIZeyu_2Y^+Y?U5aG-w~$>&_%k1S4I zsnlNopbdMc%x-yKr0$ed4vBW{Z}P_n}~AoR|FP zmEDCkZ#wS725#u#0~QecLz;0g>V2Tsp00Lb9E|Q-!|M;Hn$n59WH%WHqdunK^Q7Vh zC$UlP$v=~^eBiTjN!{KR`n%4pauyKfFIYE@?djqX`hArrU4H6jU3h}~rxTp=+EeE> z4PdL(qZ;A7N?E%idGVVw?nMLVj?U{^UxvB4XXe-o6q?RZWE*v{)|R1eel@<&^s6() zS$?%hzVGzvGv4>go(;LltFx#Z%P(;yE$eGX-o7jkSmSIX$G6KYNQ2{Qe%kodrGG;I zp||w7#`d(oxA%QjWkO-{&gZ#gf&coQ*M4Tk_2v`jUa!OQfq4fWcYOQ%;_B3$ojIMl z?2Ej1)NJ%Wu=U!Lq0|*^!2XA7b3QS7dF~9h@jHKahz`^f4`e0}Sbt!A*SC9CWPe9( z+mVg)sWY$iq^`mKEYvlx=6&A^(te!TYmd2~r{M3*+S>}{s!{91fVx}uL%c5FgpLxI zZ0rtyde{9k?kwsqT&qUixmk6o8<{Gcx<(hg`|^3%74n?rA><8;(t*5Fh0gH40>@Me zc740{0`IxL&pQx%b|Q*puAF`CQo(v;10Jy>@mm z(|X(w)i)5wFKhe74-{c*>ToUD~UcFkdeBi|go1IrDb6Yoe7jl8n<%;h4q0WteQa7k`4(b96 z&|m9nqc_s8jl0;}20u=$3_$f^U~KY+-1Yq8l7l~3U%>SjgIwRQ5RpHEHzK5bW_TEcT67zp+;FcG0T;Cp@ai4XOG8u;SMA;-7BRqssQ zg4SL;Dqr~ybr+}cxln&x@ZRq}&O7!eo*&(50-qg~{TSbs@I-Q?t4dG_*b@PJ@G?VUPt~z zMR0v;_GY$!;)vAstZ0Q(yH3HxE)eCunnr)2a}1;ZP`xIc#Qjjog6VJ6!5Sgt-LHGq z0zc+4ul)qp90XfczDWN?Ox5M6b$WI+_sx$>4iNmn=k#|v?{=>}{i<@1y1rk-a9;fy zMgOU%My6u$=emQ2=_zhb2{O?j`&)Dyav_-2Ylea z39{I}eLWNJufDLO70&D1*&9-~>q#Z*ZbdAmPLS6*@VWQ@QpaL{Pyg|Q{XhM3c5@fy zci&uqJYelnh3ulWBJ6STK7;{r{!z_uIIjyu<^*4NncAJYz%~!)-{!Pt|5UYDl@5H} z=4~AEZVvP6H`{|(tZ(3d--GO{HQU+eGcB`#!dF-76{W6i#93Uo&YRC`|2v|yKdoYQ ztW93U%r(hdw|o+L>-u@mXNywDVJqOu2084?zm>3O_5Wl6aXjs~Hq^ym9*eqDjlJjp z?!1^T&Y#|&k-YHCy~#U%ryAc!fuFqh(?5TE->JaBJ#p>SDWcflho>V#KW1?_bxx|x zmYDk4h?Xc?f+H1yjl?vA}|7f-)>@Ban0`5mXzk4#D4*lP6G>g1$GtOwxkufeu& zugl^2$HS6SOfFMjiuu|B=BeZP(|F%1!B%bSH^F%|KNG)0^^lM2$@^~d3G7?Ffjr=f z#d&PsetW+hbvMUQuOE-ENZr_SEMLdp$lp_i%JcWt>&mkV7?Iav?q zb^Zz7cPjAL=PQ2%dpZxY@q55H4YN8cO2xHvk4t3(QU1Lq>8RT= ztPgcZvcK62e&KH2sVfyd7kL*qe09K2*eZg&B3TQ;)-5|UCl8o*_%iPCnRjL$6~ z_-z~fMcuZS!>F5`e;IYBHqrm-k_{V@H@SRE^13Idzf|)c(x2)cJLzBb(EFY2qm5=- zK$QEY?0mKl`&NIHt2W)CpVoz=(r@c$ntoiJDmxYTL8a|OKd(CO;HaY1$EcG_!qt8Am2+WI1}Gf>fm2|kLk11 zijY@+0sXQD4z2tw(zn}}{mk-TB;b2doqpDh<>y)Q8|!V~Gx}+LxlCIA-+<11&#Lli z=%@9`XpDc+MN{xSO}z4WvE$ogG8Cb%=(-CI{>R@jz55^W$8gxXXS+H$uOrjeAaDAQ zspJJrCr=HJ_b+*Etx)oSvsQg@eEa%t_CwUZ$-hyzX{YzxpG+6SMY#nsupguEPGP@B zicq@`3&0hPcVnd~!}X{_iTT{=?U~B(`j(VvN?wiV<;YuOZzAu=Pp_SSY`WI_AA*fz z=XG2DD)0Ut^S%Q_`7@R@rmj)z8q{SN?LF7set$vTji~|Tjb7A+yn-`(;Cj`pE&XiZ zZ|ze6H8B0!B<`60iQITgk`r;f!SVsr9on@8_e1sjvmKz;HuMpPkh!kh)<0e`N|=lXWiE8g>2`|Muo!m5>|ZrJ4()HRuqgSrJb!(IH& z>Z8BNt9vv%c@4sQkoPgcO!_b2-rx||w*zMOrmp+O3_!K;a4hQbBpOUz!8}ndlp7;= zTk@8tD^A{se^27LI^N8yhj!n_lLuTfHqiC$=r3zhS7>o9>TYgi{EM1dfjX7x^J(gm zRW3$e+HL$D)&4T$U(}bA^wVm}zp-sx2QYu3)UI#8-J71e((m~{ROgDj@junf-}t}P z+bub$`?~Xo1O2jO^wTO=sl2dNpEA6UYH^BEleBorBx5p`VIF}2A?$KSZ{lCAl zh`KlXD}%4zcW6Leq7)s-8&#S0tgHWXm%OW=3zF9~pc8pOd%!mK$M@d zE}tX4s&`@+<)-PLoVx#F_NOj?-QjFUc6L6exKSE|9&+BUzc<%P?sa^YU+Z%d-Wj5<3ERN!FB6iCB5&{_ZOSmVyjp^EF4$0 z?|SzSxN6Luu-CyKoI0s9xt(z`FqA8;!*P*=MhpS+!0 z29kF;<9Yl)b>(t<@_=9dTxi935aKpU_{#x8r!QQ_b?Z_$>8DhW(Gjp!-IjH!+mp09 zdHd_nB=3*4-t$@V+#&Kxbqyo$$z%FW4Q#5{IljGrKyvD4CZwO$nHNX1QU0odS*Yvu zg??Hm44hnC4(sQ+df~k86E6#S*;7U*@BF*LKn<*ICv<%KXT_urj_1$Yn!0=m!l*lO z=`fBfYq{6nOIDmgUb7C~_i2m7b;+ByW+-{ho_YQRxGCxAFyEei;SzPFD;8$?n-=gr zsG^R%%z8+0j{aKJ?;PL7bp+Q;L*DZW^w%oJp3JO=(81ksUIB|YA8Yw`u6N$|>biU% zE$Bl|L_n|Nl?{chN@U=BUTt{5_r8uCvz5HDU%lrnXQEZ)^+?Hng97GDeb?Hsqmf%` zi{k*L7+t$)ed;#tAHwVV8u666{t~l+->LG#`#!Dw_h?+N-V)%olh)so@p_zxUONI# zdX~%{nSX#geNLzY1b_XB6}TUIXa}!dmYM0b)7l5`IdWVjEAF-9e_pkPt zm05oOr;Eu0{#!Ah{o&y-w^+@kp+M+U%-Bs`P#@2)g#Bzz-Pvvd)TIpY+R@DY-^u%x zE+@|G=hxW3RF9t@qaOo)36S{FOnuyA-&h!iPk57JFl)UI)|Ksmn3iYmY%%U;89^mb3fp+>=we0OZPFq0eYb>luUGaDmshiQk zdp<87K0#goA;rnN_P7msr5Z;k&kFRO|4Y?kxhN-7x{Txj7ko`%`}Wgz{9e#kIt~vN znohaV`(9nsEIV}xS}5uY9S#TTgw3*9z#Hkj@6(sBZ1UD!j>K^Vyj3%o?b`{@d+op1 zg!$C1J5vRGow8qj>dxNnM%~N^&!5y-af`eh#e&G|)2AbO7t`R(V&%*<3 z{O;W-iGaGugse@N8J$fy;`#HpVT#I?tPz*de?-!kCn@j*Ek2u*Hf~*B@g(1Q%1Ya z+PwDMJ~4^--82ikQg^3sd0ek<_<{afml~AH#d){xZ#b_Cl&8Peg^T@z`=NKw?SS*T z(b{10fG0XAJLu;%EB@-NMChEYyubRs)6W8bOT&89m5x)5x&nXxj^iqk>-mW_bN7>X zeU3$5x#V6y7x;GL2J35!bXM$iK{gP&LGAc_sQc-o+G6T_XS{xN;#Tz6>Tahfc)rw- z$X+d|nlBM9O4V@8oenq zL9a%=oI>8b?lo{;ZA$KaM@-u>g1kFP$kV_aefmcZU3=cydp(;C1V8EUBGeVU+>Ygk zw13EY*jRiJ%GaCT#pQXmJuPgtZy)`Do^dh;dH-gl-_WO4&$0NZ#ItmB<@XVmW!oym%K43>(vH zuWzrcv6H&%zn7-2Zsz9H6|E6W-Hd^J&*_MrU&!0gJr{ZFighRNueMQeeLCCvKDLjk zDm8a}JL>baIIddmic8(0%3i(JnDdzRmt?nB?`5}o&q18r-g9v&mG|7lw?;ZB_pcYV zSw65uhm+3hIW_E@Y0q0gl>f55_Z*HH>y=p#8HRg)aNUi(yq-*}-Z*kzoh{(`QPr|MY~Ad16P5>@c4D{V+hr$uet6)P zjnw^Z{B-x{p5MMV$n)cZ{M~*DngG?LY*qPxT6AE4M^#Sn3by|EE+2WoX^UgHz8(EF zzXMd$rmgXR)uDdzGk0hjS$0hc6RF#^$@c-1MdL79d+a-v+^4V_j{{WL^ z$m;rb(5Ru%tF9lq^M8!2UZ1)~->Xn}F4}zRdYs{NruQ{*$Sb(tChwiqlDzumvyul~ z{O<|8okMDUne7Z4-$Ldr}@GLlUJ;F z3=2HqEtsfQrE0cP4dE1)+VoV@-gH!DMFsQ zHTVp9z#=WOyW9UN>Tdk-)dAvnKO}BP-P-c+Sr7G=46^Y%EyKNj*_-6)$=g_%{#qq; z&*6Wmp$F)%RqxtfzYo|uPaO9^`R`7N9qEZe(;>y^uT`>9fev)zuQg}+9ha2?>hRyZ ze&(&mtOvES=MwVTl=S+ksjoI54_Nok0cY&>HqOV*1zaHX`wFt2_1~rLQ`fd-L6+Zl zR43~8&RfQIkuE)-BfTe65*OF;et$CZVwCDn9`I7e^3KthW5XU@2zG%ezwjCQYyB&3 ze(HMudSXHUl0oLD|IMTP@-0;4)|9eu+(~Yf5-Tpq|C{O) z@h|G-Qu=9Pxt;l}qG=P@*Ndcdfw-Pnt5Z|=YD{112E7YpeO$=X4d+$$>3PWew2SdC zy37l&{d6B?Iesyx_ z)r6vnsVmoh0C|D!*5Uco1rv3`c|AREA@a6XxNCtA%sVrSy`=U~d+^qkkwEa$=I)5| z`ben;)J1(!nYyJ77EyQ5i+@qG)BR1J^|&N?AKJAbZ(p7~3|9UvKobaebrTrw8gAlVX$C;>IBI&c|l_i)uWxEqTD~#a39p zePD1g>XHvQ?LdFNs^{0fg^Yu({^(bWx+5uwx=Ww&rkc@^=dFY=Lt1sqm6Om8ga{o;&cGcik~EEF`aVE${u>=W%`V z=CA9_@`2%<3fR6K*3R=UQ8V44Zp*SlEdTm(@BN-*%qF&rj??J3)sfAKT>So%d@0Cl zaoFoGto_;t&zS;VcoJ;i8Q#S`lX{8;#PK}`1E{N)`h_K?zB6SA^y*yyny}S>gBz2# zKW_!{wqII9UJWxoU+K^$@_>tq=CMOAm35c6k1QbcvsyHzZb-b+)D4fx@^$Aq@2L9` zFE4q^pLZp%VrVh8i=ltfZ|mGyQ`;y9xT8d3d;A{>-2R_Z5OI9SAo^{c z=^%B*;#$;Q8`O%rC23NVmn)3VgGzNis*CcA24*Gi_q9FAJNRbq-#bc#*g%v!Xh1LU zRE&C=$&a`lo&0Bq29w`lWkL(*O zwmNl1C)c6wUfSW*O;FV7h&&gm%lo1*d09f}r}eP2w|M_Q#u;Secbcw@2UNgL4^rB` zy)|B1>asPE|uRbO}-pKsqcbVFm zd|;Z8>6UNzPCOactuA)!PuLk?Nf7743*aH{hzNmvo=&x1ylLF**>G;3` zKYE6tv*_y6{2`!B-`(RibXn+NIRRec{zd;I+TV`x(D9dDSK~ zCogM)g5(vfM}Mt>f#cpsKFs;en)))m4Me%0PvxZU&Y14hU8?gK{#xJd)W-%Mn3)c! zLSn`xZ|-3FYh5r8<6d-)Chf=rev7)y8C9;Ry>HPs3kY51)n^@G`8-~Il)f|yw(i!i zHg&U-)+F!A=}F`j7~r*=fE35cYn-73dB76QKRLCAw6XVwuCjnAxBjnK)cw_BunYU< z=$JrV=zK=%E~f5H-j81u_#SHU%X=>!T$_!&&UvDc2b?`9otuAtxZU!23=4?zj{lv> z0v4Up5`6Wvj!j*M$&7o^F}%1JHR0%7^0v3AN}lz;9(i~A^}=zzZ8qzfINX{W>Dvpw z-JtH~?I7xgB4)lj>@Hy9q7FU9;N4IW5-PXkA$@?$M2J(KH^%=dwY3p0>%8>^gbLoNO z+Xn_yuYw*{r0!isuN{pT$=}oS8u0h^-BP?h^*mcWwwr3jc>U_f-~2y1RVw~JV($tm zT;J{(pZ{OgedMqm&HvuP#s6p!H5jOmtm6IqKQ5i`wWs6x82_T$TxC6|SP`rjy|oAH ziC7?dfSdm4Fnei@7khyyZ{vN|t6Cn+dRC|YV7=?xQTQC_@af^?#jV5VM(rBS=Sb~M z*pt`OG&Gd$2biN+h&wiJZ##PWt_~38zx~YTQk`wa=TwdC#OGE&+#Q?sv8w~0Yu(o> z0lqrq9^-v2Ja`z(Z<}W_dB8g%fo{&vHSC+sWN&OilpivU?MgL?U^`R&a!{ud{$M-Q z7qhWl>Y$!%x2pX17p#w%J=w0+g#fm54a_w?l{>0?I(tC>ghZ6zYasoC${O;L?dhL> z^c!l}Tlx`wxl?!KU)KDBxm_T1IbX6K z)RU;oV5=$){hnH1g?>=CUfzTG-)sWsOoowepS7=NO@l^NS+nrC1Vy>ri27 zKeK$`t#KJ#-=33^??;{SUN`7f=ah+9fA`+@p)O0ov_SoM2;aZ@a?WlMM_d|`# z#P_vI_FED1fcM+{aD4mQ`3n~G8>4&m@V-Ca|7v@0_6O9X1U0DJlZX8WJz)lUI`B68 z7pi{sP@GpU|78C|150*acalCUheg;)uaMzai3MdZxzS`ZhC&t zsxz~(Yi-@@08#!(rv`Ys)i{=~BfGLcuW~J8|6bLc)rGv6@p|EUb^cxbY+$rH{9aIR z$0uU>Efx+S4;YcCsN>tAKQ`lj=(4*yQrGriA)xAiobfLzqBHNWKGUiT@8^wE^~t-` ztqOT94l({k-Sy&Kh#USn9O~OMSMhsEA8J~Xx}+ytP*?0x4wR=(-{te6?k?r`m@aiK zJ9#ns^dRrV&)Ivy+d99u>*I><9W3AeI6ni9>nT@aQI|0upIdd|L=@iN%|UIc8x+4d zdGp?#8eq%kPKgV{h*KUt(K`fizjcbG zIjFmG>xTpVm_+nDy6OEqu=U64ypK9htWxBCIJAd6U`{ueT}a|ylHC1sFA)6vTNY7Q z{lCiK>(C|*sN2`819gIy99PAw(Qm7C3prk)55_4({mQKL+v?|wHEb8aw2Oo7+>Hm= z2`&`3fY4WJk(lL&3{Os7bw$6eYR%Pn&eWv9F62dR!SNQoY}qqj*Y5R0z*qOS)#3F3 zuhlAOXOG|5KKwM&0^Q@&S(d9&ttzT5sS$3L+Q75foS>IE`AK`i|f*BPNW8^x9{S!{7f4Lviu2c z&#}Iv-}An+`kxOWFSFu!nF2=1na%d?xYv1qb&)&~7RnvatuFZbV2tY2ogFz7$JOO^ z-t&2CHOKFCvWPJ9F5YNG-i`Cg$phY~7-ai)zGUGx^l!&U1M2e=vQRhRO;74NhV4cC zi~6rXFY-!!$xL3=ywS_m+y68yOkMx!?WrqhU12@Ux=eqq z*Vd2k;`+a~PD9?El6}cLUn&#pA;!pVIIpMP$xR+`Z$Gd1(Sm;1zY)}peN+Or zPLZb>b)zqqq3+UF#=oedUi^z*es3jt>2g#gukzYPRTBK7qo#W|JWh= zYn8RmQ|eYe4y5kQz0TBS8ZZXetFi_6w}IBiVF z_}`wK@6ofqd;WR-l$u_7f_s9_TE0E1DCdh*-cDY7+BW|L%F(kX7YAQwz1fDk*?&c6 z`Ne|<+xVU9#bN>Vl)#MSHEd2lt$2Nbk4u&g6F*U1MJoHVyJJ=Y&M^|hqt`xncIWf0e_pQ&Tc`Zc808SdPyOxq_PjaeS^l<}>!_P$ z^1%Fz^Cxw6x|O4D(4!{g)m&YUysNpr_LJhv8}g3q$x9xvYsZ*w`k7tbl6ry##PvLV zUIEvu0>0B9s7CEm*<$MI9e<;)cS-sWb#=&L+z;h0?|}1aipEM&32;QhR{cv7wX;+WBJm0EPm;2i9)TQ0$wWAc>_LDblwME`s~sTpi%ylGZdUQ5yv}xGz3Z;Ce+qT2BWjS> zJa!%O63H5Wlz%&!_k8|2^gMZkrxzg)7 z>Nb7aLEZkh!)%;)XDughO^Hh6t=Zd+Ru5`8xwTCMB=$Ht#$2ZkE~j{~8#3f3WM@WpZ`~UuUojP`5w+ zBS&nNE{fNV#~y43TW8taki4MEmB`E3aXEPv-g@=0KI=~MfCXCRc6~ehs?yXgOWvHi zo9lzA>lZ919k8&O$bjknTYtA`#739eWl$|>XtYqsEd`D{#t)o5s$oP(+1n%_lb-FRC_08BJbmgUO){z zkgU72I3U5^A;m*nAdcUt>9wyqAH4R~t-?pNyc4tN)T(qHQ`e|hbBWGSzG zXWj3$8(``8KlWyhJ;&LUH^2o#m-vO}A2#>){6*H-p8xo<(eo#Qw(wNGI@kF>evJ+0 z?;hOHf!8tQ0OMiQ*5U)nyB7W%Py>%lPvQD@uR5uyQ_=cS_oi(n)?>yAU8yT}A}@6d zPru=HH3%3&-r8v8VXLm!nvhpDq8xd^mMb4RzP@y5ja)=}qGlh%m`gAoRb*Ik^ zpzgm}f8jaPyIOR_c^%m}h`goM8TYBy4d?yT!0D|QM*8-HdEG7WTQ#XqU8a{+sM}s( zK8~weXT9e$Q2~d%Bmddt%?;wXqOw^zLRlkFx_7kzk5oL8~q)+TR9=`rLLEJmJwQR57GKaUh854ilsSF2B~cJ}-? z%N!ueof72(>tWI#^w)Z9hd3_E9i1yZb#?R8U+YGv{^NV->oNLky`p4J^0xQ*Zh;Ss zu`#_J5E5Y@TK+i_D2H{uoPjv6(>-bqzK%Ad6m?CC@21Xr%zDtz%Pb-9boI*Q^*-5v zyh=sek_Rlgv4A~3c&Oc{_4+WNl&9vWyiZ+|UInQ;J-8Eft?MnvbE8UT<#VJuBuE0j zPIDm{dA}F$Pu_<@WAXph?5mya$dc16AnbEr0?DtE`>7+QzI()LKdoNZhpiqiY($=q zM}jMopYE@f?3vWPv@rY z#KdmotvH&2^>w~jUl-Tq^h*O&UrWa)4>)CEO53+n-=rVW&Awd0{m`Lfz3! z)crUWPTiR+^w-+WbA`GG2SdmUc+sA`YHQE39>%R2=;C*NkCgzZfN@Htv@h>YZC`wr zh=}8#hOvLD>xBof9ySGaqi+AOJk(Xa``!X?$rG>Le9mdZ)>+-A;A4`VcYKn+d%M-ed$MC^;yY*`e~KK)D>+xfV$t;uEqUO&r^3IZ+)6V+e|16VMpSP=-P)U#sp~ju5p@xFJb(7jYj2!u$ET9y z^>5sQys2aJkk=``*KT&k{>k!y%NnP*eY@zC9MrYT*n_%T?YFT%(CI;M7uTomrU%Nx z01po>jZMCNc@X(AtAA&`ymAf3bW!?Q(B?Fhv#5uPur_&O-TlN7kaQ zP#mJ#x6~Vd9N5@vKN~ZgBCq;)ma7|C{2c{+m*Wr1w+Hs{#y6A1^xD&~7vA^k5Sfd> z?*uRB|53|c&BgyyTRQXqs(=^SZJbXt@E7k_)JIR*I<*K#U>a+a9F}tw*n;pFN0}PnDEHd)LZRf$sEH)7Q zNn81RsKf_4Qn$5~Hy+*gcRo+L*`h=)c%SSPEdO7pA9+_s^kzMznaJl=1M_~H?DXCm z;OZZyNNveVOf-; ziK`wt^XoKq$4uX40l|ONp)_?#<9h8WdiQtK4Naeyy1(vqC9mc7;%qp8R#DWJJ156{HsYB|DwuO^uAZe28K`e-QndE>?avdBE{a1KiF#hqz>izP+zB{kxj`p8j41?&I^Sb5u-d z$BN?vHWWJ8dKN&-Vj`euD98n@60zVKg<6yn*9|Wc9L-~#2Y7q z-Qd3c-J2Q8IzZ^=L(4v6|2j`E_DfYZ$%%sVG1J6l`8E3u zA}_SZOV-zccI|Lp1%?zQ54dN?Hz(liS!YzP>@E=c=D9q-c6#k7*y`+v+SJ{QQIooy zKPHj4eW2HVzC1lfUdO-^ zQkqrebFLyvS8`D9%I-~A{?VxAsS{-RnQLs|b;?ijys?!z4;^{HqFeSjzAfcaC%?n; zQdkR$gaa(|y-7YLo)C+g(BQ78A2 z|3~gKb#mWfqaMhUdLd8hi9D${@KAql)Dq7^r9PcG@pHLA=%k*hlX|C4o&)OSIiYTk z6$Pl}IU-MbljoE=d2Xqb=h%|tN}g}(p|Kz zdD6~-X!qm+D|St2i$8F~%C>ZXC{O$Z{wMqfb>dH`6aV5sFMfwS@k6k+_$BhhPmw2n zi#+jT3SO#m`YEevdlwgVc$Cq)z-Mbnv6(iC-m8{49CmciAq)50eL!rK6T_ zi=W1E_-*RMk5eap9`{3u-={9`to-E3d%*%<-V@}>djmG!Bjf?cKXxtOmiG*G^4_6N z-b2vgJw=_ox2Ti%7x+C}sLp#6ksvZ1lIf z9$askewW`5^ZRAm^wX5-$NBv_W%_yA^!xmNpf>$N1+Vm^6 z>1X==P`_WQOg~kdeycY9SZ(^X3i#iNm^S*m2YY5DqI}a2)}~*qO+VS|Kg)U3ulD=d z+Vs2qez@N+SEirtVc&wbZ<~I+->=uEpU?h3e&2i-DD$1*e>eEw5!!rLDD#~`Ogt^v z_HFYW;(wQD^PQs2cZ@RMHU4*wGT%MgdySAVPgpJl#VmHCcU=DSvz?_6!Zd$sv4R)TEb^1V#|Cg0C&=kh%b#CJB% zYx(Xb4|wupTT8yjLsJwCv4N;h`A(-!zT2sj?|Awj`Oc?KzWeEaWE_Az85bZ=#tF!i zaRc&zcRy|pmGK1YQ?GnB5ar7_19dX)K%I<3P$%OP&}kXBAWz0I$dhpm@?@NY{!GR_ z$OEpMRos#B5W7K<NM^PsV9rYZ z@_=>gjkA1P#;I6;GHykkjAsEc&PAP!dr>FjV7MRh+_ooA#>vQ&aWe~i8Al@zn5)?M zFyEGOHk`+}8+9@cN1cq%Q77Ye&}kXRBTvTl$dhqC@?_kPJQ)Wh54a>af%AX6Uo;%Y zxFK~ij!2!1D>4s^j5|^%wOCE50t)Gr>%Q!7{GH%Oyka1ks`s<%J{N9X~lyuAg)8kopD~tI5c%KE=`?` zTT|zwjAxTC)XDfe zu3O7^Jb5xc55#yqc`|-ao{Z<(C-Y;}$$S}gGN0z)_ho*KJehAJPv+ln9P@GH$^0C7 zz#3=sxxOv)cht#z9(6LmN1e>~L8oLskUE(kBv0lG$&>j*JU2?_6UmeLMW63J=W2uw*S@LAQmOPoiB~Rva$&>kA@_=!cOmJl0H!M~35EqDY zWj>fXnI8r!nJ=bJ=98&2^UB)HGix*Ntj#>MKQFD!JhcXXOEfc5=CQ51pYyvw{Ep0T zvpkvaX8AJz&FhqTaT~uY^X25p{5g3tpH804uahV9?c@PtHI8k`JiJ{#dpZ}0@@0OW zI+?GhPUi2~FOYeC>SVs3JemI|PvQZ{llTA!zc29uA5$Ysv zggl8OAy48;$dfn|@+9sAJj9>a{Wfh6^KFSsp-$pdsFS!A>LiYZ?Lp#PsFS!CAmU)i zleif2Bu)nZUrF2ydBBYAXIQ>1aW&LQoQ(s$#NALQaX7G*#OY8caXTJw)^hSBt_M6V zaX#cp+z)xcYjvMl5)Wh#=(ybhf+ul8)JfbBbrMHJox~YYCvivQNgNXEOX8BqlQ<LhN9I*H?=PU5?$^HJiz$d`C9AmYQwmv}MqO&pm5 zE-M~lBfjk2yg`X3Ok5&ybgw+NZ=1M9ZQ>ZUiEH%Z9+ioM^y4CxiIdbO zZc>{#N@e0IiGAM%+rDk$F8w%6ZQ?ThxJ_l^IF*U(R3^?-o48Lu4pf=AP-65l1#I6o zaihw_k!llH>c^e>aj1S=sxon^+QhAD6UVAeT&n^`Kb+1+ylcg_afzr$69=nJT&y;6 zvVI(`A6KhPoUJx-w|*S1AD62TpPRVYXAAMV)3fBTP28>@$E!_TuQqYMejKpM;Kc>| zal*>P4QmretW8|80(MNe+(Nu@v=>3Pi91#%4%v@O)+SDw@yqysCazhTIA>+zp0$aC z)+R1m0Tbl-5{7u`ObZIxCT?1pIBGwxTAMg)ZQ`(%AltFTXS01vyf)jf#BZ}bOFTFI zfy8%%hj?#0!_9S(68~*gtdzwD;yNWRoH~gUr%vL=>8B)~oH~g!2O{pAJc&amPvX+) z2PICOJc(N;57@ANblbNjuHAuN;@qi|xOdoE;^C>2IC<(MZk{}eqX$n(Ts?UbXHTBQ z-IE9GGHIvf+Y*;goy6%=Cvp4KNgO|Q66a5y#Qo!Xm8=6GPu2whu}*+ISvNo)@Je7F z%eQ4+0q%#Abq3VQx&!KD9fAeDtW%&))-AwRvW|f~S=T_GtaBhw);)lyfzeW>i}Y<- z7eSq@lb}x4O;9K6D5#Tl7SzeQ3!sv9805*i4DvdJ?L{1nmUSEC0dKzR>&SWzyL|Nc zHV`^l=RuvU`=CzNfjH2~IuYt*-3WQIjs(ZCu7o^UXF{H=J0TCaA?GDW)}z>iDju_d z;LAD{>SWytbXd^bA#lmLP+ z>x8J2bwkw2IwI<1eGzrC?g%`rLn2SsC6OoVl*p5HOSnD_Tzfm%mGw;az@-%(AdbsA zCm_~6Q77x5sFU?kxF1^9O_68TPx$X_FtmEQ! z%DOI;t7N?w|A(vtqfXX^ktgfK$dh$r2ZdBD_j;<&yo>&~c?b!hBg%epk` zWW5>?>)5E1b#3IyIyct0ta~F**1?e{>*5^nfvHzycYRyd%~2=o=x|=ix;pA)ogHSP@tP|3PL>SUcDb+V2S|4Yld zLh@vtA$hXy&;no9A(AKS5@BoLk<*1-S+D3u|FOvd;`pJaC8?8jjnv6HN9tr9Bz3Yb zk~~=_NuI2mBu~~+f`@gLoBR4b(w4zvQCpaS;q;)x=x(O zI#2Rs-6!io)`5~I>q5x`o(zcL%6d_!(2Pt(=wux!b+WG15nIVRQ|e^>DRr_g700no z6+En4B~R9|k|*n0$paSpbC)CQT^;*HK^F+Vtb?Ua*2PjM>tv~u^|RE;x>~jiS!YY0 zth)s&S%*uWtji@2*#CQ=BkOg;-qsIxfhb?r@lq%2da09jz83Vd{+Bvg7YrNggvpb2 z!{o_2V)A5NF?dSW8IuR>ydbCR+p-RsI$4)Yovc%)PS!6|C+nJl+DBRMOunptCSTS= zBVU)2_0iSW!u1D&kLrcTyrQzz@TaUAQo$&+>6%ys%b>h%zSvO9dtRtsR)|pc$>&{spvJRa*S(gq}vQC{mS+`Ce zaQLYvj&IAlcGicibEi($y;CRa;4SE7oji4&Ulf6@WgR_vvaX&yS!Yk4th*-<82w&_ zy}m8$@~M+``qas~ed=T#KXtOsA3Ci2Cr|PKkSBQo$dfz)xIW|!AP>0fW*JNJ3D|iq z%0BCYavFICsFS<{)U8zBe5~Xtpic4@kSBQz9PlNt0eO<=05@OpqseCoJ%Rt21Y}B_D;ICTZ75 zpd8kcrvm4Zw}Lv!V?mwdx1dh)UVw)@801M_4DuvT26>V_>6ml7|PjlDs_R zNuD0^BySISlE();EqQ&&1D;Eg%YItNw&$OFZ2_T|JV4Y*ULfiuPY`vIKM1HKuMl~X zXNWw>JH+-Qd5Fl9yhP*yFU?3`OTHpIZ=p0q=p~O4b&}V}5>rc_BkCmo5p|Lm3CES> zNg_}3CXpw3l*p63O5_1^Ha}%az9p-5to$|*I?2NX9r7|!CwZEvll)E8NnR(`gXDQ4 zPx3wikq3%A$qPlE`+6H&@<>r9d8Me6JW~$zl7EUi$x8)WNuDb5BySaY zlE;cX$!kTPUIQo4pdBLbN`N8~rVantW(Kmcl*!wsOddC7^1AtX-n7a4rhpIs9TtXsaJO3Kw@qF+W%9%+lQ&MA zJaT@XIc@UJDU*lJ&r7FGo;q#v))C8|NbDe=-Oa~oY?If{&vWPJz0)QSo;LaM{Cs(S z{yft#^=zZ}0WDmdVGbOnyE;U!OMl`?SgL=jZ!VCjXzG4^Wx> zfPTI};>vHo9OMzKJYs=m@(C)FU(nAtsE~&c&y&eds7<~?W%3s)lh06@{DywMLv8XO zD&VzN*Ta0<eQCjX)``568DjN0UD^z%0oXB{~bY4SO0li$(L z_oz(%M{V*$YLhS0&mZaMlT;?Zq&E2`waGt8?04*U$G1&>N@em@DwDrbn|zkqF3Mz^Jfy1eR=7ae44tjmtRwve4EPT-&7_ar#AUI|Boh*r!sjx{XCz@ z|H*oje4z9Tz*iGeyS^>?LUCM4{!j}j`9#4-o>A%~|0s@Y$wx|_Lh@|BV&`Af-@ ze5T|9i){~dCC{n-qI?zjgSL!7HD{L+KV9AsGu;fX;Sn?!)EP0Yo zmONmJ0r_0XGiyKja@_$!FZpMwlYF$)Nq$=BkhhjP$!ANRA^6^^WNq%1PBwsIVCHZ^FlYG8F zE%|+|e0E+J2>ZD=-h({Aj`)( zafs{NlDC*T$zu#ulGm6z$$Lzlt?S#8H<~)h zBTZf0zy!=!DtV@&!T`L(slx2;Y7ZDsOt`+2%G@^$BkT;w2s_oG6=uF2!==k?Ym z&$lvpzm>@gu1%hBZSsa|lSkaoE3QnQaShCz^I;_Nj}Hkf+Ts*Okf3?&oRu^R{b~ z$6cAc?#kqOC%zg#%R>J5Qh!EuO&)kZFT9^8UYWe{%H)+-CeOS!dFQpsL+|IMS0+zA zaYx!07V_7(XtC8XdF-{xYwzc|*9Rp3J)RSj7vIm5uT9>3ZSv@AlULu*v#(6veGQy- zDwE^eCNICAr(c`A{eE75)uf2$Z%y8RZT11sW?ukh_6hL!4ImDjSUSw?BcRN_0@~~| zpv}Gm%Irg+%svIm>|3DCJ_i222FmPnpv=Ap#MM8CSiWucMez4Y&}QERW%f}}@2r+= zCuZLTe;)>I_GM6Jp9W?2Z6KbHdd>1}v#*0T`#fl~?}Ik`Kq#|MguicuHv33uv#*3U z`%L)zP7p8FOk!g{iY2$IIc8r9ZT6|qX5R{bUkiVq3n1%V_P=2Jmi;hbYuO(I|4*BJ zGnCm!gE;PD9vk~>tS%FygxP09nSD33*@wg5r$aVmD9`fEJ|4>K>!Hm)AKL8uq0BxY z#PZQXZ0ry6>3S{8>=UBQz9IfTBHHXLqRhS{%Irg;%)TVr>{H_JTcXT9Cd8WG^V`_p zq)*g;Ewj&wGW(urvk!_k`=V&GZ;CSes3^0qiZ=VKXtVE%zYmMTek^|nq_eRpV4cPLFl>^z>9$K}Y$rEHXKd7Ic(fi*3%g1s>(!0*~@>fk*kd zn8$g#>|JsGv6Q#VDzK@5&B!{+=LH?*_kxb{eL+Wgz@Vf2V2qqE3_Qvo1|H=T!}yx= zi-E`3uGwIR@{Za0E2pp-Sx5QEpria`&{4iJhc;`eW90m9;8DIe z@EEHstZ#`;`QY#zC_fx@ls67K$|Gm7p7P5G=j4yK5a>S;5 ze7v3W^Fc@X`k%4Y~(s#c0oQ@%s+7{@kA?ou8^iuEwu zV&w8DKO*MgC|@FUls^$V%C86=D2@laEt-@^xxY{!Yo~sXX~TCEus=WCRDOP*{HfZLPgU}(O1@Re zzp6d?Sb+`l7k9<>^5-f~K3(O> zud6)ycO@UMC>Ep|QMvWcLv-~wf3D=WvS@JJSK4#^~&n)?yHRW%%`8p}DGuk)hc}DxC zyw7OQlm{B^JIFI1!npm`m;IbK`j0w=T~GdK$tNxOrIjb&wB(~!p8V93uUdQZS1V6G zYvsvrE%~lB=e_>VH-qcRe=Yg2B|o#BUt98RYft`d<;lk_`MH%RU$?5w{vV) z-mbHBH}B`7%kF|#?jOu2D#q|F@$CMaqwI+Ma~wwIAKCLa-uI1{oA>|N0cJdqx}zB% z%>3Jo9|C9e#CT%NA~U|YHPwtay3hU(?SXONgj{xxF~jWf5hr6Ax%?(=>+pU(eTf;r zwEktrGas9;gYLK|9?V*M3wU)Bn(@(+a%gvIN3M$CF=l)gXctd6%-(e6dMG26tAc#q zK{qtajK6MPFypZaD?|Bw6(L`r3OLixWt>iHfe3WHJMf3m1EL0@oN|j!f#0J!{9hE~ zci#n;*p*YkA4X^W1%DWQ{=jhPKHeLM^ZPS-LzKUvMJ<$XErmafUb@HB$JdMC52J>c zvA|;-IsL6Ac8AC|(47p-itE`J9&Ph^cAOKRQO$0j7rLQ;^#ZS8Xbk(o=zCM(2cwJS z$PHdxwnX4DJ~^A!7JJLCA-JU%bR$!oaQHYy|1#t3zkW<*TgUp; z0k2nw2=Iok90?wy-5|ggdw*gxzAL>RelU7$j#AK-&V>0|6_?;1o~qh%L-$`Q_`&FomEZ@Xt1Li&tu9W3AB;M@y9Ic` zxhgX1C5Pb$qi=q|b5P&U!0!cka%W+C^W|!8;$wF$Mm~Ptj7^{megHoh-S(-e$3vPw z;pd{FcA5X5K7Gyq(6g1M^7-oLdVtMXGJZxz#dzjU27Al@(!0BQW(4wf`;Phl`lix+ zz8`w{gU-J{aaL$|Ms`ChH{Q#|l;OpXTc z>B^kA4zI1PdB6Ui&jydNVvaYK*tOCg!1d)nVb1$Vg}KlLOsEN6-#F7>gpTh6UWP@c zKWRGj7I^711cSHwt?7>#kF=X-iR~_Tai7biH~rVlglTL(pVwzILpPy#e@69gV+7YT z^*X#8?^ngE6ag>grq>RcdR%49D=Nmb*)N5P{p8PTykFfO+YGw54=O`e<(UIFIBzWBB@Y*Q`-|9>DL<<~ljg2e}nhJe!frk6+-n z#aMO*?yru@+M8`%FkU0*#?`~~P<=n*`KXVcd{&3rxZq7}hv%yqx9xlFJpZG$TdB}y zi;>H9vgAhjV;4u;Y){zzz^Z`;gw_ZGaXEzcx$xg5q( zZ?d}KopRexHl_sf_O(4R&Qb4+PKN*Qg1^yEt4!H2F4Fa$#7FrnN=M^7rp9KmNT+^{ z#<)uL`x=V!83%lL>-?&5*lIoA*Jb4L3-7>lQ2sAwLU(RfE#|B6D-EFYuR9pL#HUO@ z@}L36f$DIb65wSFMnA0?+b&(;^qvqG`k`L1%gE&y7=eCTznX?|r%F)L8@gFr`=R`R zBc<>hCVnveVD#5QHXlFkz&nTWMSRnbrr%PYZOypvW1uVcq^`}Gul-I`f-d^?7U=SN z{LHItSPR|wvQ@#G*rO?UUoO@KFUNG0ua>-e0Ul%Ix?HZ<@h%sIZq1;s&<*O-pU+pl zJ8j-G*S#~je0;%xBWc0!JOTZ+ns;h5-v_nwGWu(EWm<9Y8RKrnbH%O_{y&S$S6;tLnG#^_Z4awUHC%q!fu-OQ!{T2c=aZRfp>I$EASXwHrVQjed32Nbgf^Z zp6D?JenA&6T>mD-lEXjnJcixFd8rSBaGp9@5}dale+Ac}YK_^1_mF=v z^Il@CUu>i`xJvQ$T{+p2eO+*ft1e8yiYgB|mtzdNpVb%&ApZBGv6`=L98qrU2zh5ey> zl>_x#1uRE>*K?QDcbMlLi1wfxjz;@X$>Y}Wc9s8!c@B&vCjVPb>^5;*p}RD+5|^uM ztU>!z_wU-!J$yYB=eKm~d+@F;M|;+vb9cviEa+Mc&+Fl2w135TvvDI!?BJQ`AM|y9 z^cTAR0`wp1Z1D?xKh)rOW?bkjFTuyrpGRD?7@J%+?PgS#Xtvd*ndrZOe|$J;iGBG7 z`ZxVEIr=-@X|riZ-SZ!TZuEvwoWJ1A81sGV_aYOH^CWjPUx#j4D*>*j@xeUcGmd?b z!WMhRH8Y;xzB3=bS9?|K4c$cg_s8eAzZ3d>Rp@_1Sg+gtlg?o*-5Bo)y)F*#4b@`I zG2RYbliJtLzi5QpwPem%M&@6f@fUR87vnvo=ibD7NzF)(_m+D74(~DbPob;e)tG?y zoIcpce4qZ^^9G&=V~)UJJNwf??x=2l79$^bzE4UVr{aRFHXmJyFPH@2ju~> z?!7;V1`>F3=|`zh~z z20X@5B@5VMKZq?0-OJc^&`mg(2<7LgFvRBLJpPfGQC;Ye6TF#K`+&D2yenUq_CDJa zyu)7k!DAdZI=L-&pREeI%sZl?>+&>@!@8Q`t)ZL$w+)?O&v6d#R};^h_Veb-Jn*L_ zuL=H&@{Pb}eAW7x^}23Pr$wn^HY4lyjy3J+*_YeU)fpND-G>@c&>cy!m+Oz3dkghR zCE1b2B~zEqml-^-o|souj3aZ_w)#G39a{Edu+7N2{9n21iD8hUs+`8#O+bv zRoxRc*jCHEn}L_OYZdTLX4wGVY0o+h#?B?5?khfKlNJ3(A)AqP<>pt0uGV4bb)%Rn z(A5Yw?P>YYH{fM`RTw;23 z2|)j$V`?1c`=O5<=*0W=;*P=KuVSe#-ru{Uj*N<(zW>Q1&7}q^I?p!-x(>~w# zn#IWcRBh)#7jW3Lr^e3?K)33O1zoErc<$=grR?Ap9f*3N;?Bf#x%__K`M_Hi)(hn^ z&Tcrw61&lxEND+1Z}w)sO5Z6LbkiRuf^Pd*)LY8uo!sL6ZUNM5wRmwk@LI;4v^!sLpEmYG zKcoM88^pFwTonBh@Ibm9j@W;Vs{q~N=v~m&d}G?twbaX@tJtYJ@7HPOM1og6x+QoY z5}S5&V9z7)LfRAqkMU8{1g_X+GIoKk>HOJTZ&dsP16;;$ ztLfk$u4wcRQ<(C1PI!#tF z-kIy$wqz%GpDvl}ANsZh&g1C85-6WhH=}jEo-rV0mcAER0FSEJ- z*D5DLyLf%vJfHf@%=7A#Bn6kNYL+n1*Kfl^Ja5KHnSo}+E4KRE!f$#uS{-Uo6GSn9v|f~-b<0q z6+20rXq5jUel~}XGbC3V=BxbUO?xhVdh)MkE@RU=rvDw$7Je|Qy{Er^ zTXsEojQd{{a>cH;)Aa9u-)zcy)n!&Kl)tH;c^@3^2tOEIr%X|l-{Z7-e>^W2#pkPf zOzY3*uY!(dV$_T|2c>t#Zse5~y7ULk`>JuyhSt+5K=0@EAXIyW!N{J>LmAT*PH$-816{qd#nng>J+z8|4p6XWr9YRlBmROilvcky#+@c#F>J$U}bKjFUS-!a&waunn0Q#q}-g_F696M4Ig zTz=`+*`W*Z?h9R!@5lMNRNDtVpevlh7rYVAzFW*s>SxB;Y0?#CTb)kU3cQo;%7e$) zTmR>X{Wf+lbhRFhu$jL%b}@9xhJ-`cYfWS5{;1IbysII@nWu})yANK;m4V=0YS9@y z#(oKAIbzouzY^_aS&4zrMO{kAs79yug07q|`fJ_y*J!>Udc{Zd*ShjCfAG$&e&#TL zx`X~%GrmiHAXesJp~bp($wSLH>P*fFI_LRVh>Yq37)DekZ8P-{5bYI2SS(DiOo8@wj{r-L_Q z1)i5~zwsz|$+Cxn$9TT>d#hlswr==;>l{WdH_z$}&<*~K{#t*JpU~#=*JaNGUE?7CYMAG2xBP(XS$o^mi;3wiw$=4}&B1FBScy^RS^qb9Z@!uKzW$}Dcc0>_g2z~G z!97dtA@58*P1&shbji1wdY!8FbClnAq^b9Be7d6i6lwq9^VM}znRfE4scAO}#->C0 zjPJ90*F>4&_h`~WZRZ~>Q(V-bofyohrf2_(=eH@=^rKhHl;QiJbLKVu z?AglZISkX|9Og4VIqGkVy?sMH=BqAu>q57?py|i^w1Q4|SriA|$s*=G5SatV(UZo- z=j}SkYY3l*Ui-Isk1*EQ>}@}AbJ+F#Qv>G zI~zf#yt{$7t*2=>_XgYrFWtl9;H_L41s>!4igT$)=svCQ4;>+IS519-fWK$88D~rzZpIzi4*ZAX{X23Pc#Qh$$sWb)2ilCR zKewSN%A5YW3ZriM=Q`+~8-EzxE5jD>8fGx#q$L5(!Sfzg5j-a&%Gbx=ytVZBoHiqu z`=y>4e?328#$$`J*=P@GFPZV%wyRliUXR|U!tsx`HRHXf|2xU`OONPi#)Heg2ZP7> zsfe=0UhZeckHZ{{fAorR10B}Q%-oRqdU2gv(Ajabc)QxO*VN0XK8L^yscwN+wifzJ ziqF)>?(DPC68rL$tkC(@LI0`>jxyurZ3FT`*YnR_DF2N*f${am+33I3;}p4FKK{dE zW<37lZ}j(yvF?TRme>=ErMCFIP8`AeLG|_zf$m~SGyad8YT9|H^XB{DFTXmxUlocp z-w*LGj%2+)p48Ms#yiWSW5w<};xfwr-)|86THg6sNcU&4<4g$$Bb@*YXj^pK4BIk^Fscd z$M-{}eu;isMXf3Z-Kw;YEZVH6q&Mw%_p?@Pt4r-8dB3W&tU7ph^JU;MUj0?r4S6-f zK3;fK3?tEW-@?10YZzVux;@QWLicDyap(vg=KX4K?%$bFU)fgiGMW3kqJ0mP6P4+G z4D%Ql`Ic}$jqU4ZAKS`de|6P-})B(V04->9l*~#^}%DD@H);Bd)rM@|89()3|-JL=u|}KQ_ziXSq{1^_1mHRKK+t` zSEaA1{|8GXw)s3aWzPj3V{qqGuGj(JO#9h6s2E?TN}J2HuQhG*LANqG9(3;bXh!wA zYEFl-*?u#>)WFLI??t%-yj?S1|KjV4UHG_Z|5v=`Lf2q!P3EhS2TXsl>3$#RMlUh_ z$%}foz&n-K^gmmlnEt3>%L8Z^jG1}{yJ9EFV*0PNZ&Ks@?)@(_%0E`PKhEoOaDA?4 z`bUK64^IUb0dLlo*A}0LcLmdrE+|@!ZOxcAHqiY%y_q|v**=Gnw9}d2%(>NTwDUHl~pwg{ZD4%g3JpkiNQ77Y2f7I8PJ#k)h4o9FJjq!&7~j21>Wckn@HdCAC!`ko9knN-7~5*nvX;zO)nAr}EryCq{#9p4REp*%Rn)Xy7Bm7|0&=i5tP2bTOx=yd) z2cxV0M8B;ojZE+I@$Z3P5xSd0TR^wB zRT=0iZXRm$aYhaJ1YU4QKk%v_=nh`<&t7<5&C~P)k8!~HrdH^qthRrRv@Ro;f9gyM z=u-Sb|Dh^0zm4{^qk2c^Le7)~@8gIo4)a@mH|^)l0nN7Bxh4WU#!in;Tlz|Ed)v&* z4kPpH+?fX5lR2h6T`GPYx|CBwpvyC=EqFUyr3J6$*�L!uBL&RFeni29L4Ra*9XV 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 X#5|I2c+?VY-GG3jUS}(gfza8#v1~n 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


    JH6seOqi{we%Me-yLBY6^+kvxgh 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%0Aw0$7 z3-EZn0UnP(z!Tg%VU@+>66;8xU|Uf5JYIp0$1j4!;~D69d;=YicVwT2;_(o8JU#-C z$4lVx_z670@W)9l9#=U*0l~JQ=y<#Z9gn}D?R>p^UZ|Af1IMIw7%{Y?uxYCR>NyeXY9eP}9#;K&ot)$1Xq{p>N@XU#X zwz2iNSLtyu>2a|cCzBpGD?P4OdYnyq+-=6;W?Zghe7^D29!rnYl^(a7alF#wdNa-^ zJ?>ZfyTE)WDE-}Fz9Y`uhm@eA9tF#@63Y=6g!%?<>;ZTcp3gNPnLx{k^92_Z#W&Inv*Ez#+vtI>y%D ze@cH3D*b&(`g@V|_anY5rM~s|rqbV^q`yZ=f1d)2*k>L2ZcSO`jHSO{mHwVp`ukSt z?_JX0zxXbe^7Z$!(%;YKd)jB@Ka$&c+U{r#=<_qfvE=jMBz^!GdI?|G%a z_m%$sS9(5x^!xxY?ao53%p2VOxG_S{A8?*s%qJ*4zo7Jd1L^q(((@6d=PS(og_+MF zJ--3mJuk$Sd5<+SOF4S}!_0@6`4Oe(OGwY3ke*K=J>O#HUzDDYAw54sdcFqO_EfB6 zY(1Z&^gNH!^FC%Ci1fUWnKx2;9!cqWC8g(?%)Aruzko!po`*8?QcBNLDLrpx=CMf6 zYhk`i>RHc&@$=dN{ga+2BRy{he3L7`YivEQru00U((`U+9**?99O-#G((`y`UQg+H zKGO4k!0r`-U1RHcK{HQi<_*m}BI$WWLBxgOc}Mi8JRgbc=lMzWhdf^?NIZXuepYa5 zi(uE-JiiGY&v!z{^PlLac|H_6o*#vd=S#uk`BdxUNDD%JI@q93NJU=Y&PsQ`a;PL!1c!EX`Do~Pei}NSua@J)^V#6>{5E(z-whtme}gCZ_=)52ytuV6 zD9{xY9nY7Gj(GkYI-XC5j_22*H?|D8RJf5EyR6Jh~9?#!{Cm5bN(&2gi*zh$W zuAr35^Zn5A{6BQO9^il38C;dcBGCdKBsPDYIUs z^!k<3>schYbVX;!*m}K-^!gX+^)RzOru2Fl>Gd?y>uaRf+mv2^Q+hp)1oIC6Z;!F{ zdYxInBfXxd^!lFC>wW)6y$(ovozScsD!q=V^tvK2_(Z5B>x~(oW^nboqgjU}y)LQr zI;GO>I;hg?qQGyPc3ZMuI_BbiN3WZbUPmRpu1b2HRq1tCvo1?| zoz|?|l3vGEdR-T2^Bx6R?@h9Byrb8BNv{KwUKcjeIln{{Q<>&&Frok_1ln{{d6 zj@kKaS+D+d}y(}Axt2HUdEo~TJ; zORu*pz5Y&mJ)ZRXywdCSO0VCW^?kG6PkQ}dX@3CrkHb6+a8$dMma(<}0BL^$<6oe( zzk$;J2gW~vw7-J!Um)$zptOGju;8Tcma(<}18Khq(tZ-gZ$fE53iww@f1v#?Nc&-s z_RBDS8o+p^bK2T(Luo$_(taJJ{XC4{hthr^O8beB_8TGXM`HX+l=d?L=6w}l8(aIK zDD9VG{8WtJiqd{8O8d1KzZc^NWBg*2_LBix`$KH;pUKr>x~2VSl=iD3?Po*U??!1q z96|K6?4N`Fl>K)EiT!!d-?D!X`cwAz0Z%Y{$HF%I0om8;J+lPmIb{DJ=-6KfI`$ue zj{S+CWB(%X*#8JT_D90|g#DAiV}B(_i-UL{N^ie-m`pf;py=2?OLU6;wV-4FE$G;v z3p)1i0+0Q_z+-`w?D z`xlB$>~9Dj`yYZQnAUx08C&})8ox!-evHPik+h$q(teP}FH&hgN#i$3+K*BRW_~o$ zGPd@!RNC*-_+c8qOwxXuO8adp?boTapQrKrG=88;{6SMZninblq4CQF*xFB2X}?jW z{YXjsm6G-|h5xDCAMKZF{8UN%t&;X*1)d%f&k_ID_=mFF+RxSay(;YoOWH4%w4baX z?mPR>3M%%m#rY(M$%t@u}G-01DLD8}QE}j?m=Y@{_d!b{0 zU+CEX7d-Y429N!Pg{Rnm7(DhT22XI-p|1}68QYywEwKcJ$NtCi+$r`)hK~J{1&RHY zp=1AL@Yugu<`u=?89erX29N!rE#V8ET9(6QKWRHf!7q`5!e{?!Ij`8C8ano`hK~KM zp=1AR@YpXKJoeWHkNvm7V}EY&*uPtN;^%GWytyXU*zEre9s7er$Nu5avA;Ol1^bUf z$A0C4iv7*OWB+sT*dHD3j{VcY6D*o{s$*>SUx$wU*&Wfde>-&S?=Cj6|2uT-7Y`o$ z%Y(=M^THEy^n(Qz6#E_gZV_I_hBf#FM~RI`!s;Q5uvW^-?;g% zucP;In0*~)pNG=>K1lBaA-yle>>DxrNX)(x()&z+XD9l(vj1eA&t*sNLoxeOl-{Re z_N^$rkA)2C{Vityi_-gHl-?g>_REm$n<-u;lPmjZF5XEElzP(pYn0w^qsDssZ^~yC zA4%!`NoKzi>HSN<)we@jW9$7*X1|l!|77+zyFO4A57`}VP?OW()-6q@P3;duCew0GSd6al-_@4_M<7; zr-t^#`_=^Yem14|w<*2fP3iq_BzPH`6BH!gHz?yB;(dkS@jgTFc;6xV z8QzBoo?zeJaU9;C=o~p6#NAmtkr})LZuAr39`!1p5eVEYkzD)FMyiXH4-nS_z`#QnneV*X)zEA1b z74HKDPjJNbNfz%9bx-;wa0Nxj`$jE6-bV@@?<*Bs@jg@N4D$X{@OghK_`F|L__BW$ zeBRFrzF@0~k1XEj>IVJ2!x0o7?|+4k_rpTR`(vTw{j$*U{#o#NU#(m>@qSzIc>k@S z;{CYb@%~)!1p9yYcZ|*ZcjdmweqQK!e=l^r-`5d6@Bf94_XmqD`-Q>d{lnn#eq!)= zf3fhCV3!7oBaO}bkD=rJ$k6frWaxOmGIYFu89LtAEGYY(!Q=hU;PHNFtON1>Xz&DY zR_SFKoA*yc$NQ1!Q=hi;0b;%bkQ<4 z@BfC5_k%;n`@=;i`^BN-{o~N_zH;z*zd7oG_n(8u`_Tmz?@tF$@O<9Xwy}BtI&{3B z9reKb+o9wA?$Gi6cSrQRAKv4=C?PiS{(10tKRtN7zaBins(%!=dEdPo|6avCg2Ly0 z`Oxt`edu`KK6Jc~A3EOGFFe`z4<5$>0FUDWfX8tH{g5~X;BnjnLE<9 zoCg_)O56wNI1YrM((xdajt_yj5yI2)Busn>6K}%Ap8&4RQ^3~oC`^0`((x)t$FDH) zER>FKp>+HU6A#10$1w3Sl#ZVPJUlPhHnxthVd8C=_!}l3htlymO#BWL&x3S)4-@Z0 z-S*;t0ISChwvDahgP3?Bq~nK}cp^&27cuciOgs|O@kva)5);2fNgR{lmicTQ&&0$x zG4W1F$3HRgP)OpW@O?M&Q%pP+((zSHycH9FMM)f%b@39~Iv$JC@mZ9P*Frje3+Z?+ zq~p7o_%BMwgCQLshIG6b6F){t9GOEWcUclw=EsIWTgR6%@n)2cKSMem4e9taO2?~F zI-ZS*Z)4)!kdA+&1iv2%wj@4IwSFPCj+0~J<|rLU$Hdhk9cM@BxI0S69|0o;{=h88>DnxA*JICk&Zh=It~#q&cd#a z#3#BuJ%z2~6q&e1O2;uG9oNXjIU*hRNa?spO2N1NlAPqpBASq9cM}D zxJxDulhSdSOq?dtahnt)+Be5_LjT6`p74Be{3k);cu;blI6f43f^$Z+vW(5~qww9z z@uZ;R_)^euyeafQ9DfQrj!T99hvQX&$MLJc<9Jr!aeOQA1bYmd5MgYNe+3=K!-9_E zV?oF9vY_MmS)!A;THtZKE$}%07I++wOZs2p_*~!#F3D;;#^(54a$IpdFX%YF7jzu& zOYR48{4eM@E*N+mFU%1>#}5OK8f^(mc^pp-^~dqmpyPOJg2eIH zpyPOK;BmY*xgUz-w}Hp;+`!}bZkF%`?FIQ=j{9am{C8NSpzt{!oSau29}YT>7Y7~3 zkAsfm$qA1*-W+%we-1p3M+Y9qrvpzgs&}x9mm0w z@ei+yV>~2r^T6Xcdf;(fJ@7cro+CWLjX}XK$KSIvtXS&^%5jd%2OY=h6Q1I@eb8|n zKj=8FA9x(^4?K*yJkK-5O{&PG-@HoC9cpUH0629Q&PPtrTb38=oI6k7BR~#=9I*y+R9mi9IPRCUw z9d}XbIE+fiWi)XbNylvj&hHiI8e7M8Bpv6`#C#E~>{C6$gdNjmN% zkfw#W#@2BuNyn*FI&P(jV@W!$CF!`Aq~l;J9T!vSIGHAHCQ1Cvh_QuS9Y@o|)iiN7 zm5#e<;&3V*my>jyP7}vd>A0Rs$N4mIKS|<$&S{v^m3W}9#%BRa{pdKMO2-W~aYU7l zD@r=fDCsz)O2;KtI!>vHTS^kYw08S5j>Iz!+v@M?xTYq~De1VUO2Xz|=~d|F$cUyfIc=au8wg2!=f!Q(i$ zXcrv!7CgZU^-5VB57$0kI)f`H_n+hBLdS7)q2oBZXm=b}7dno&3m(Vcb%f7xdBNj2 zy<#hl+Y27Y@dZyXJl;LW*c|5!+u&4r@LV6d`HLYCLO<GT92ee_>*P4`cuqNPyx5B4$m99t`0|3pap%F~IP`dqIW9eT9H$;U z!EM=ISjOf!_Rw)$d+0dMJ#_mke20$X;6ump@xkM``S?ENIQrmmTzx^sarVIzymcqD zZETLi4;{zlN4w)V{m^mTe&{%kza#plCA{{|asS1ZJOJQvUI6eoPXKs=-&^?G#^yW% zuIM?h0Cb#Z06NY)03GKcfX*Q2DFC1I7YIr|1MoS&0r;Hn0OM)FVkJUtV{<+P=r}(D zbet~%I?kT}9p_W9-UjjVNHzCLYI#bzE?=sk&hr+#7D=kot zbAAfwI9~5cr&rNcfVM$PO>EHJ0-fSugkJu?6LKIDZjzoX-e4&Tk~w zO`PutI?jJ2DEX1V<9tcrasDK^55)PDz!O|nak|5Kmh8i0oL@_9$+ra_=idU4^KpSExF(Um%Xzx&e@^r7@ zLC1N`z~g*pa$Ir#Gw=fbh98XNM*~kVUy>`1v2`9brSqzpJZmQJ8tFW2CQqBvdE1oE z<7V=@nLKa6pjl~Lo%hY;fm1p!oYHyXOx`%sdE`jvnNvFNoErJAsa(I(dFe>!sRLf? z>gyU?=dn{dubt9)?o8f0(s}Sqo;=cd^GqH+rSs~M&a(#`^)|#cw$8(6^75HHeI{=o z={$b_N1fk~bpAh8)5`~_bbdh6`2vCWDg?NaN3ijmLypcTNIJiu()k8W{z0Yl5t@93 zCV!#Q`3#lLZ>UnVRH%2smM62jk_T~g3obz z=Vw$pUn2=Nto_-MJdTgE6?AnzN7DHnmCpC5bpA)B^Ffl%4{7p8lFlcobbd*t^G%Xq zh~E-N@=(Tm7VPSLl%(@hntYWef2Gp-EJ^3LB%S|~bUsX_^J6NVFOzisOyIluoJZWt zr%5`$Ch2^eO6T7+`8Y}E=QQ~{O+HVh^Lv_npGxQdB*9I!^18;>`9V#-P^I&SntY;4 z@{CG7>HMQ6AF0y$NtMo5s&xKR65QE3zH4lq-;{LTQ>F8un!Kn==Sd}Go=Dfw}u3i-G?Pp-+E zYx3wSomW@sJiCI@UnJ)` zFNTiu8H1HImj(?TK`D>( zFU$LrI3F`~oSzvw&ev>-p7S?@$9bK_CeHT^9_N1skMlu;7p&vJ2yVIYWw)_8e>8NQ zPZ~PTFAW{%n}&|_Puuc4oR=Cr&Q}c{=dT8j^I7Bl&iSpu6YSZll4Wepe=Wx)A2xKH z9~(N(mo4{0asF)RIKMV{oNwC^KIh*CkMnVhE%~{@6TE-pfMsmX-whq-^M;P|dy7u; zeM86jzoFy&;NWq-aPT;PICz{-96Zi14xV7?iAii@a~^W&I4?QI37n@KI?h`zs5p-~ zbe!iLJkEQL`r9?j|D0D{&J*WZhmP~EL&tg8p*!9j zJjHq2!Q(vc;Bj7e@Ho#qc!F0C1lyed-F{vonBYe(F4<6^K7h4GqITvJe{(Ae~tqqo-9Ou0D&~cu7=+b$9Flzjt@PiS= z_2r7Git8{z=vcl!P9eYYOmu?hFN z;gSLP-O>G1<2q7y$cXZ1Zo+pS1^0(GKr< zd_8|Zc!GNu``E@F8fHP)zENxFjs|9hZe5jVn~S3kf5sJ5f3(X7Ud*&!;1!D8gLp7^ zC-(*~AZH%%1n*u-ZX5e#_5{#v_-8P5dncuIq}=N}+d$XOihyo-vVY~c@|)(h_h~<- zfESysCV0Kt*9A{7S+5h8v167Ehi-R5ub(fu<|1^XbC!UvWJdJY>SVmTsD}z!2f6s2 zF3AMxzjE2Y+xx7Kpc4Fq{k1wb zwS?H}!1m^HUWMc?2j0R1Tfw{j!E5h=Uy@gg_Vk4k@wn;j6SvaYf>Qp5J87Y_ zZ+YLVZ_3Y=`$0qRqrVnJc|HFL0B_DiZ~eAM2Cp4Ys?ZA8Q@T+j@C38`yU#hbp|YDV z@|GnizcZ`YVqE7I&mTs$Yq%Y{IN@cXYt^v@cqQ@$ftRYacmFP}`wCu}_};ug@$Nm` zyx&Gxf>Q300&iqqL~R@9)ziJE*=;syX_=%bcUKp$UaNn3j(T1)xV@ZLL(-Q7@0HJa zNBHCOd(VlWlf8SSu^-eJDd*K6^Xov@{i*ldEowLkx^2@@F>}=?YjrZoS`keIoiO8{0 z;H8`I^&?GUZh)6IU5J!Jg5A$5*VrrGdi{{Q#6^1uOY8MpGvlYi^}Rlo3A*t?{cs)c z*40HlysqN)gFzLFf|q>#Ye&i#T=p@SJLb0`?x`H-BL(HUACIdf=he;8O@*)C-uL?9 zy(`y2_g&8?4*9qiyt%o(e!N`+@G051%HRoZTNmj1)*a%uN_jR`kc*?s3Gw^t&;(qM zT2m0$M<*vXMtc}j9oJ7eM&SQZf7QYNr=EWG-b+ch?UDbV1TXaual2;iO?Ffqg+3%=-Xkc;kfA z`*MLN7&$+Mdv{JkyG!A$K+&CQG8nq#OA_ICvW;ykd{rf7ICL$`9LII8>E~Vdnk5s# ztCXh}c!@gI0dHIUQQ!%tidW1vc9Ejq^Vu%u9CTOemxS(Wt@hC6f8gaeyE$x-E!Wfb zZ4yD%az%FV{%q3+JpZ;2!Nv;(|>&xe6`D`pXRf(fz~b&b8_NoDA67ia|C#ci#jyPkWf=u|`N0dz56 z1Hdclpr2Jcg6E@MWcrMLSWTIUewhRx%}VbY`*RKS+tjaPf0Vzn{zQ51)aBXe_tlf$ zcn^?I{3jM4raCw9o=`3NHWpib{tfRDRqn4!ay=wC!k_aP3|nS(UsS{ul;cr4KVQFe zcu%SH&GFt+E63tJMn3Vvz>8jkewwx}{DktS)WdsF#W~s?5#Js0CaWtbGj^@j_iLov|HE5HkWbUEst1HeMYekF$p86F=uXe7F6UL1OZC8G zw1wwiYmi(wB|PTcm;3duimeXR^uABihjau_u+5^s9Aoz$e-ih(;IM%x@72^4f+}9| zEW%f_HhT3`>|hDh+k_9@z>EIs3*O1So}c&gxOmP;aN2|GvBpljp$z_yiCvpPSNPxZ z&_%!Afd40-_A{@rb`^MIOL^a?6M8fO@5{Mb;N_g|J;#Ex${mR`_QF@sp^J0T59O~M z*cG~gQT^n4)w|>UY{9EpG73_$gQ>ymJbnOpbB_Hj|G!#xu@iWLh1dOI8T-=IAm}Po zx#NibuQpyg{#K)l*ed)(1L)qDtqR_yD)YcAeckIPs^!}QUhN5`!4ph)`=xbgO-s8) zy^W5bl>6@wALv@Wigv{wRS@50Do&b$(8X_p{+cSDU4VWqa8nd`W7_5vRLwIa22U`< z?^*1(-v-&GBCH_`2SdJiPxTHFRWt;KT9Cm1Jxgi_MwuV#C#5Ldsq?M*ad!g_0js| zM(EDRl$YzGsw>g{)Vz^BQi&etps;% zDP|k{{7m#`>f*KP(EUt06S|Ind+n)vfrHSETpKCp)yzGu!7KbcBY2PVM7w;LT2zlG zs00ts%w{*-m)9PBKN(Pt&$!YHx-HxC!*8)yrQXm@*q;Zw-5oI>seJDY2CwafG#1OK zWWzS#tv(q6p5Vcw@2%#e4qGcz`q+X}eu4R@2Rb)n8g$ z{srI5;8h)89K3x|9l#UJe{H_CspqxGoPi;>pzw1%83^6nY{>=rJ)RZ1ZAJP*7k(uh z>Y?uZ?%?fOR~WpNXFoc^uO92QAHgka9!9=8Tgn+57-S1d`E#o`hc40Ta?s^0u?0HI zi)*fuw^$BdraG0t%QCVtcwJUC1TV#@A+G$6VAuY!u`@3|ajuriV+%_8zS)aGcj-tM z=>A$WR<4(#Dq{RYC;v__dX+3BEqEU@4gfFx%|-J6Q|8H?->@ttvPV_)qG zKN$7iANQ9IQd>*-?!$)AeF&@qUGw=1<+vL9#A`Qm?(P8Z_{K8ey+7RoJi(SRn=NCX zz3mTOc%;{kPUV0f43%!@1D)E{13E@q%0IZ_68g7z7RINlS-c$Jg-uB!=PCQ#LEs5a zOqItn_JIlSP~ZKtWBjW+uPh1O>E&l}og+fM>%R2}<7v*{T1U>SE$wT8*L3d$@Sb(| zo=3rP!^^}PyG)i7_&@H)mV)kOY+LBYpH2W>-m>2F|L8|TTgpA#J{Nd1D|+vrtyQ|> zeU#;t_kI$z_6~83eIP>t=%O|%=rV1M7Njmu@;ZXmsv~ps7lqb0Q;StB! zSI(e*REjo#LRaj7_ug&zbT4$v*MgEyJcjyhcL4PDxfxuKi>Ab~CVEu- zI0?R-wUR(Z}V~WtxP&W zDzqe>oTsUa(4VWNucpiWPzTDPzgG{E1%M|QJ~N)XZTutW^0GWY(N+A6_lLT)p_wDP zjTalC{K+{hL-+l~5;@L(DPBEnUbqdsPv^^m7xNbHFA}tuY;_Lp3w5YzkSi#YpSz2n=985l_(i_)k4u
  • T?1)RcbA4E>f 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

    w$nA&SkcjT%dHZ2Wp zA?K;KkJtXLwKs!z-1B=O!JYG_?ElzeozpB)QCCp-ZGL&}`^=@yP=3>PwV}%~#(R%@ z&V2#i&1t?Uf6S8Z;04U;CD*5BZyn$oY`Uzvm7-GyH~YFYuAr1Zc3>*#8ZRFN-H|<8 z<$kCEe|CW`^im*rzJJ`YgrBLWSC6~Kb{AWvI@Aa}!DCgAS~;Vty93_*>j(;e;yn1l zP}*x=J5ldq40K^N%R(1@wKaInCl)~Yi*Dh4pfx9cf!E+fe()Mc_Hut^Bu7xn{g`|f z+B4r-eQmKLHsughi;pG*zep;)rxZ{mt|RB;7w!Pw@@%ES8~N86Ij&B%L_HwEX%DK$ z8oT4S3DEhxtOH%(?{%TOwP_r5vnoTU4CeZL4*Yc0N`aqsJAO}fx(YuS_2mreGjPe6 z9G0=C{*}m;>w6oM9lG-G@qbjeDtqxAnw0|oSH0a@0KBieeptf)BVCm6RiSc4#a8_) z;64JgHrr|$`}Yjxpv${pA9RoIdG+Z1%_Y#iIap23tM{E7gO@5pXYfW>^Xg5lWB0(j z{y6|V!Qk+?wy|6IqP?aLfooBZGB&__M63Izwx!%G5$T~jpI{)$FWz7T>W!Tr?}7!`cr{I+UGH9$yL#;1FhMR)y$*)|3$18T1iIFh&|a$~lZv1o z#p#Q7Kn=Q`S@=}*PBQRzZAH7Gj^>2F3vgrkVEfwDPVSdK7h8f-e*A|a(9u6vEzy^| z<<+BJW1_@X4casSZ(mw(Ja@3sEbvyY^Xg66zmI??_^DPwyIhYjcg^4LEJ4vfd5m_G z4h~8W-K><6HXo+kzsD0)s|V)+uj?1I%aqb@iuk|K^Fn>V>z6bSc!GholG*t)`nYNB ztU%FUdgs-rpHMEW?^1laz*Qi@EK?<&u1-$2#`wQ~= zb#8eNfr&DO*v2k1v?p|h-W7&!eKGjIP{?Vo9wn_<#uA;u&>Stn-}tZs__1TR$$1** z`N61ysaAt8n6P(I+t|G_R`GN@n?hHwWFzP{9~@?j{%h1z=muW#1F!mvZs1khKSr*b zw)&#KL+!q$6TTAkYnRqGw)0(b~9lT%J3WE3i-w5yoJ9HjtJ$`;N=8JELEhyzL&ehKqTw61{Af2-lL-+pA zA<)$s^byao>)Q_CO?g}rJfE-UE#Y4&(0M^wxE=o{Z(D)YA>z> zUFoEgpqts*t527Yo(6B=u+rfD`?x)L<(m0`XZa1a<#z;YZO!alshQAjdp)x)DCOtM zmJ_@_*C$x|7PdqE87ma z{>l=R^4DLD6`o4z`M*$~i3_1yf1$dZr;Gy{fp_s_3PIK zJi+JJ=UK+SoPC$PH|pn6yhrL@oK&uq``gtF&>f%PjZc#t>4fJn_fmH`uf7%Z1+UBW zmzMBb^uc?r1j}|m9cJv1QZ?ngdib~*bbVHbLs!2u{9tI9j(bA(?Es9=AaX z@cqLFgI}T){9$PC{LXS7Sf<}X$JkBR1w$9~^Iu2w&Ni<;J#YqyOMoUo2{n|PkbVEAgJy8#`$91LrVi)p4 zm%43l@a}bugZeWpwvU`w?Y86sug;wK;0az`n8p3MV5mJZV>(Mvczs(XvjnSrYX{xJ zTcOa^OnE|%(}nTT;EjGc6}$xzwZYq*zCL)TaXpy+*1G=a`Z+7i0ZZ^K;qo&9YdLH8w_KX{c&cLT4(hFNmG>eg!XYt*Z$ zX@yUv8>R(MuyToXuCZhGqFqx6CCrfsB7$#Z@lNQs`f7EZphl&o9m1j^I_? z_8WMK3tw`CeGt5B~n}q~K4OG}M*f8+9SRAPG8@#qBaAmz^vmIZ%#ozJz{{icFan{p%PsnL_44 z_wiN@=r%?-gwEaAAG`${@VsgDup8jj9uy4T(OsRv6Fik^p_4t~kud+x!LFc`|2lZE zE!cTl3PCllY$oU~Bpv|WryJGqJaUZa0p9wXMZwFp`i&#}i~e}ONze_x9IM)dJC)7^ zxPp9|TAphTUByY2pc}k(6LkCa{9?rO_2Atf5)R&gaAKA{vOYv;ZoFV)h04A ze&F3hjhec9lpmSG>u=tE>|OV&-b?X6+Lx^co?!J7x2(+98`}-;9&!X(PUCL0$NxDH zFx(Y;f4K+Hb!Za+UH{Qu|2SsBAE+1EvJV1pU#>KQ>ixlV;0apMY3=ys2HID0hC6~% z-iepv;3Bq{?C__!@%oQqp{e;iFf5Z^{!9_yg3tBfhSmkirTZj zMB4?s<|!k{Je4TvcIblkRDkYixt7ok_6vnB$wBY_bzkd^TbelDIA;3np5XPWn;rE+ z@N4D}`&eLq`@qbmmY|eBVtf`ss$M*q@M-b=!O)H0aUIY5S5znPP7Nsm-nfR|IPB~j z+)ov6U$i6ToOx0oJi+-bPFcpzIHMMHuMW%*9!31_y`SHj9)oW3%`(uHs^N_rCkLbf z@5)2({hwFg$CdJrU&;-h;JKd3Y-7(X+Xv+*_Dc>w;K_HWEeBwUjjx>sZSLpS7| zAD+WMMS9A4Rcl5O@ILK%kNZ^NMHF}uqiwO3;Ml~0wy{fYZvkCw&x+7Z`mzPO=Xzdb z)-rFNB+abK;GN9Z47}~%>VemKmG?a;_Q9Kn5u_`*?1^Rk?AOPAfbzRJ%AviceC3AA z^-{%mXs@Z$n)I%mH#o6mYWz;6PH4Buuj6{TFBFiftMF(>(LnG8`{a#lZ>xOIDmp6< zP|8_a5BHg}7VcsR|9H8^(8YaG4Z3BGm&kE-_>Nb9=49Isp7ppacpo~p22b!w+^yDu zB1Nn$y8~@O(N#_4)u$N&KcQzhMR zzTo&n*{w^7e#Gv(8e|Jf`ORi^umukdEhR|l2YK^@muh(J+P9GLj+|dPpe}gFGXSZ3 zKX2agR1>fM9ISd4Ji)!U^V`PG^Bm>!AHnZXmNapMNAco#^(i6_u2aPum;>c+U*~;) z2HaVM?@^0(-uEffFYkLLIQ(;B+t_t$d-Jb>&%FBdYFRHF1ecua= z-7N2o>N4H?{vY3x3itC#u?$i!wLUrkOUG_Jyut<`<6W z?oP$~uKpfaM{IR|DC&bcSQPbxc3fEtUTr-;FIax|>ix#9dSo+nAy+C&xoUQ6)IS=Q zv^;bp5_t8g+dOYQ;78J;;4OdN1J_ZdOewiO8onF#A9(&+1E+A_%CpZ5wia|Hr__h;e%2AtO;q0d8CB#mctu~7 z054An+HH!ycpLZiW8xuF9tm!JRM0VYi&aVGxZ0L9D|Gqdc+c&>glX{{_gp}`O;5@f z2JgXNpB&+DU5$2|X0I+OHuag^66Fi#p0Lv~_U)P#pc`rLfG*W1um10?w-UNL>#9IE zwp3H_8lP_pUei0?du(5S3|`Vv#laJdc@@t!cK2!BpzE7@id?U{+;gBScp@~NAYEIN z2D%4t(BDys1}~QTp$;EMd#xg$_=DHI%R@`}g7p&QagFVh!>h*$nzfblDl)JM$}jtG zRp_R!TLxW{7v6L5`*$~ZKa-UQuja&7;N?vo0G?o<5rM9;0~(^ervD0lgYNU$g3#R^ z8v)&w`j64B-Rp|}DIJ=X&6ev3Nst7*`9slO^Lo%LJTJk+KZD%b%{$uP;{M?XGMz?O zDhXY+H5VPxhZpglL-{MC#ipJE>VY>qZ5{BQoSO`u{~+*`Z-!Ig36^VBz-^Wz)DCU+ z$q^KN-C^yaYxFB2bh}#*b>(+%jY%L#ftPZEcR6!k@P7QNjPFqEUudt@;dS2lRPete zN!)Hl;@ESBWCM!6_`*o&PVLWSNx3Dbwvlqx)B3g`G0J)BJjKOz#`pYT)Wj3>aXmX) z*MQ!7@6Bro=16qhxjUeb^IuMXS5WlZ=L|=Ai@x22?$(_k=!T{0g7SyUaGs0M?V z)lMm>(#_2X-l^~b;9X1CBy7>QU{_Geb&B@@zx~i+;CJ?aZHew^?P1^_`Ms*xG^Sm1 z@V2E62k(5Ijo|&#`|J8d!Y09TD~q_szWuHebccpQuY&%o0^PeRC|`{nh2NtEjq&?* zuNqV4F6j-c;v`^Pz%3feo-}!8;t*P zd^PSHEnA5Ds7@8@>j@uCQKn1`pQdq1`a<{ib57_k zwoCxssIF+I>A$^+6k@JaCBfKss?icGQYhWNRHa=hT@ z+R%keuLoW8sL{|3C;**G`QsvZm-CebFQ|7%@WOYzz;j5@8|}0b%$_l?^^b27yU>hG zuAr1ZIwBi%eFpb~E^o+7`CsbTfCxFSqTdz-@8&;W9X2UjOSIE!+_3<$Rl)xs@EeTU4PC*Pcn<0bw;`gd?o@?tL-i)$wOif>yqcN3`Z77@A$S9h z`-3O=A$>gi#r3Wn8+Mi>DCMtGi{!nb!4J_+Q`fU;Tq(ax`gG7S!k#hIJD*^}RPd)n zp`E8{tMDCAUB=?O0Gu=^x83%?VXob9Z>*q{Uw(WuT;HNx_^wcf<5f`p%r7f&os~X% z|8L$re3z(KaeSxf*9LsYRJRwuftO*acmD)`9(x*Q?69n#QU1J~_%2e;`}j_(ZW&Xd zUfh4{J)b-QS#dp&hb5KYr>p6_=ex7YT|Dpcx$vD-uvly2mK1ws8$*91k+9ZU>W=6pXi6syQe9j z>%HH5|Fu5P-3;ce^E%55s;Cgw%TfQMK$`|}_HLGoG-|$H2 zVlSazMN`|OpG8h#^t;r+6Nlvfsj<7g`d+5r9I-cM<(#9AMG!w1{N!W z=O9=rX^4I5dJp%^gb9|Qod4-p6uKo9-&t(Z%H&>qTI)!8vDK2wEx@btp(1# zx%Mlc?7t2?!5hho+P*0&yPKciw**CBe^xW-Mme>iYdhZi9>n%|0bQX#e8H@Zq*J_S*@m+?8|E1Lb(@#e<+L^J9zL530DQi}0z#;XvpH zp1R`*FRGhYk1w?CE;ijf+X%cXJ*$H!_$uiQtM!pZ&dZg>Y(df8yXMuSS*v59JJO;o zbZO7DhOX430^l)P!asK}636c?!#Iq}{hQzA!xX{f>|f~*~VV{ ztqydXr+ed7``>ZUHLU8rpE=H8oU7_ID+S*8wfG(SZPqv3*X(}}apk(!?MNi31k;CR zwv9dXTz2TLJjef_RgHJa|D+!o@V_a;vI5XuyZr6(};ZutT7}wLsTCL?g6-ihQ zJi*!-Us}fgaAY5Jfu0`>72mo6*i(e3fnSJ@5`E4n+B@ z@_PMZ!FhY9=ciz?X{{qpX7e1$$s6zi`&`{ zyg&YU<_Lf92DHyguua~>VfVM!cmAy#U<-;af3jxKjo(t)(^ba&4)ycqd+1u-t>8_r zT@k$Gr&@qVr!18J^ǥ{wh?ZtT*eADkMwbJ~JZeo#aaulzD-ugO1NF+9H?gZsOD zn%17qEU4bTO9o!9je`YgVu!!w|C7&swAa9w(-%7fFNL^11%FwBqRXu?f2NY$!2PA) zibPqW8`QIboTtO_Yk_xh)GRr!uCDjm^|Nb^fR`>R3_QVK``$U1Z?<(0Em>~~3jgM% z^w1Sc=hdUP6XMx?m@ZAs1KprEy}|1e7K1o2=l%Q0c@_F4H+VIQ`hZvLl~->BS5QjJ z*w>z=afBaSq8)U#ew2YOC?4iJ>Dw}|9vLiHPqZ587z`BO#G5adoZCckTnJd@xwOtnQ?v_QnO_$2$!t;nf zs;8VM!Fu*M$Jo>E7KZM5!;hBeqyO^i)3`^WVpE19EukB8xdM1sw!sfZmGt~zX!-qB z;AJaN1w6srzwSE5uC}fzbj@csLis0;4725T^45O}-Kxia(7n0e4ZK`~#>(}oe8B_3 zvmU1tq_kgCgD05$UOKm3;X&@BD`hM};U`QDKNwZ8Pgm&bj0}Ko(2M(y=PVo z?jW}M>p)}hO0}#8USP(h;0Z3SP|RKUDB5im`g@F^=u36l3*F+8<)HiXZ7b+zpY(+; zZ-7^yR?UYWjJn{5{-x^wcLaEU+&qJRwcs@05cf;Le(s3ac8;KwpD{GMpxRJBvGCQw zbwi-*9rFRt@74DX;Dui;3EtOy7cAk$5B2&nIeL#3n*__<@pET?uj{sLaLy5w;~S>d zfo^okNzfJT>eZ+13r|BgdrE2W^4@9>-kjY&;FS&M%_`JwC5Psw?Dbs!SFLMorbwklJo4R|f?*xVO<(Q*V2lBE@!k?kG>4P4c^PI=$|o-b3na$TjKWq>aGD6jueutrBb2gX>rzSx^+w`o-dU+|Lbdx_sm z5;08l^z%jyT#sPr%mCNe89y`=J}sCR4&C-ySVvW}y>(UfGx49$)$dseydjU8gI8xw zC6s@?Fv?dMzPtfX@Y3#_uCb5rD+*oqSv{b8`nb|FmnQEx0UkTtQX#eqQK4 zH|Z@%2dgJUzaaD|+HFepdoJ+Wt&0zy-yF2tBpA~qol_!CGH3MoAXiZIg%h+FJ}o&L z3f=6|C*-*5I1cX_)jv2DymnEw!E2SMK6t6_j|A^dI`EX>oUQ}H{v3YES#v+1D=6g- zo$(uVf1l|HUD@1^@Enqr9pcLGJiDDlkTxC53f|Pc{lKf%&xASbdUMjK)?KSO)Ol!+^4C;~= zy#CwK-yy*?OUgOMzL#f?+z+Zyu$%BHhwTsD!DNpd(PxX})#Gu8TZ&D2wlo1Rs9II< za&}n`Ugfvma}aFWqGuUnZ^*j~y8NrlL-$8|wAbp^hG6IhM4`P_j3}?;6z_g^An*Pr z4e;)NoSSj+JeqCuo{!*$#H}o2H@W6LzXGSd=h?NA_k63|@Sb=7!`}11^N067+^p}t zA2&02*F7!OC|pm{Z}o5;g3qd-v5Z}0qWAvgp6$JlAICsP*E)Ld>ry8ax`e5{_xa0; zr1;-0r+e>zzgVw6#7y$)hv1?j$?cD)``CxlML2?Te}DH)j{0=7j#t0xfAH#C^AB-Q zev^nu@P1{^ZVCVL&o-`Lh236#9#zh(--4wt6}0mnjJC_a{}Cf7yxfWAL6`c4*FJ3N z>$Mko6M5~&k4;{CQmnq$zWf^JwLgb9dhOA$L-2c1g7Z2C+uKSHwu_e!umrh$^>3ut zp7p8kwQnlk0J%Q(rbAVE&s5HdUVB*TwAVf^KKBOqsj;uup00}*F18YkJ|AHB__w+J ze)C>SP>$D#^4jB=o136ptJ~|;2fX&%9q+a0mE(X<$H;5{cXji=2OI8t--p`qz3+u! zty%GHW8eMH`<_&|)E@PsZxpVdO8?A&|MBU1N?gae3xfpd{OsNGUecb{UF1B)HVXo8 zSuOazD8UOE^4i8;KLYoc9xjN$b7R$BPiB$d$c*oD%;LQ)h z^H%nXyx<9bc@$_HdtD6P4|QmqvTcwin7TnPQN z7hDqWt9q0!z9Z)a_iPKYjotNcyx(felG4yk>vdXqbhulz=+&8ylb|!`Gop_0RH7uP zSG2SISnvZ%fln`LUjSb)VW<4Iv40*f30=R0sJApV&Ide?$tzK>X*&d8HMt*DW}G)}t=6>!bS3GECHf7oy!vyyRkYaj>tlVC z??0**c!KFlT(*pz^yLibb}jYl(|o^U&_%o`1Kn@s+CjH{Y8voHJsoPx@AS2O1S!s= z+~931*#|tqoNiys*iMaS`-DI8NpI-lEXf1ip#kxrJCrFBx=#Ta9N`_h*cQD1CWV35 zEb53Hrz9J_`Xe|lCQX>J?`@d{-KkGCp_@0f0dzmkMnZSt+HhC&Zjo!?JvcQX%P8m?lG4|Yq$>q4Zx;Ha)pQ8Ii*D%r-&tY>=Pv{tN{9tqu@M_$9 zkKbGR#Cs1u7qoFbdEFM^3H~;1x3j8MMZ3=A$CjY{&i4FUq1&S8N3!AmNI3u1iS%fEHEZ>E@L2}=17_C(A7RVTlA-Ww;rL*w za6O;w3{tN8%Nc<3uZ`@B`!9I$DX*t$JIf@zpVW7oFLX&Nyl_Ofd=lPo+L#6YFO+5+ z-hcX>4fR3g@>vJoP|yEGrJui9Y!Yl>6>;tVD%xuGBL~RG7uHApQ;#~Ahc0arum1Q% zyn~L>68-S(MRC2m@Ats~cN zaF$ok1$~DVh`rl*x>fm}uPZ3JRI0XI4}FTp_eu4rIs&>SalQ95_SZk)E&EXdyvs%K zy;F;(+`)6`l5z;HXT^-9xE{giml<7Sch8X(y7*uF397ZzQsX)FxQ=#Ol?%Z4n9{uc zc<%LPe^cC{TYt2!_L6}g@XGJ#Q#`OC>{Ps?)_`wUO+odL$3OR7d7*tCFK{+>eX98|HNBjjUDo{jhv@+b`z9;>~vM= z%3NLs-9pd*MU~&Y8@xu@%7eFIcq{NOcMSlqU{kcqO7No3`>^{zzgqh~W_Jap{Mb7M zp=&Ta0=nT9pP^kV(#IR8<{OdC7G8oZNx-W!0PVCY)9WRk*P)K+-zve}50_bfAtmj7 zJHI)CqVv6Y(GhG_$ZLnsts5=2x;V0)oc}-GieCr(fjo7Kxzyy~9vf?5lke2&$R?<%F(yn!e!q<|vQv(A0#z!E@&2 z18=_-2RuRFKH2Qcb0X~<$r3n%Qr_iOxh%oa3)(5Wh8K57VF;|qPj6a1Xj-!3|TxcznSyf8u02VS@d-QqVvD1S-QW54k4;}YqHkFP@4JdBUsY_i zDxx`bC*p>Km%H{x@R;h#d2K6w9(XABp=E5XCtaQ?pY-o3{rgH^59#YAef{SDDExC9!ftSVCi4QY-8)^r}XnA{d~>yR{HrX z{XVFD-upuO{UQB6DgAx{->F*Kg@00m{neQ3t@0HZh#{+Q{XDcxT){W+!kcclA!r2Bus&-bRpO207A zoxHa0A1d8nH2p`?{YlfmBUk;ufQ+eCOFcsJ%2iZt^2o1_jeWd zgV8Q?zZl;M?k7vR#QkQJ&;4mRuDG8K9{0P!<9;}Jg2yi2cesD7>>G7=6 z<6AS{HRE5><6))8$x4r#l^#cv9#;cjuS?+?TaUYy9)~MEE;r+JGj1n6j#qk|Z^r#f z&jXO27XYT&TgWxGo;TopyO>8%dR{^4c?Qz+4y5NHFh3#pNzYrDc?{C?8o>RFgI$^L zSU&-0jhAJX$cr00p0o;Ol@9!cqWB@(PuIHxP~O;`OB0{QQfo`+IAKZX7p&sU)y z^86L*8_#D+JtUsr5>!0@h5jGUhk?iQW8evHvVJ){Z)Uy8na>pz9nYsh$Mb8b*F4__ z9nZf(r|02F&&!#4JJR!bO3&+=c|Owfe!!mLL9Vg&yddd$LZ#;o%{(Hx-n=5|c}6o2 zY33!Bo~I-|ZwZ{za9A((}Md&kHL(PptI3F~?&sY)@aB&^5N6S0+8r%n89m z9eJL59@@-Hlb)w0J&&#QytbL=HuK&j^WTr3IF6nNCp|B2=E+IVo11xbGp|m1o}KhO zyqT9b^Ymuko@D+$G*g%(^ZB9cgIztZPkNr8^t`{)>i}k5fb=?nSw|qfuAuZfgIRX~ zjwrCWjI2j2`B2E!>k?+2!mL{;y^dklHI%G($a}5VK}fHQD7{Xi^tuVK#PD{Otf%x! zmD1JgDrTL9^ty}E>o7{M%P750W7cst$q6 zucMJ(XCuAtrt~_TS(hVOpUX4iYK&f|BfV}%dL57Sx}MVOd`hqTVLecuhh8T%>xN3N zBPzYF2n;$MVi{YnJDPP!((95+uTv_$ZmIM-Ch2uf((9f|uY)SRE(-j%b-!h7y>3c+ z9hLODD(Q7rv+k<&IxOjRTGH#bq}OqkUe^WMyjQ{4dfk`wIxy*VVbbfwX5Conb!5`( z%%s($><&5G6Q)}+_5Nv~^@UguVN-COB(aHZGD&APc+M^}1X z9r!9kkS*)&37aLd^t!v!>+q!4v8E4^;7^g6!M>-?nG{Ym=)DD4*jJT)=M7Jq>; z9oAUdZ$N230^?Ue+Rs2~zXPTH5IFuU=6^{0Es*wOAnn(n1gAgEXN$i>fhpfD?f0Ox z9|UQ?2-1EMr2Qt8_M=eRuY$DS1!+GF(ta6A`)L5^}k?`;&mj{w3hCzX^DPd0zS3#%6yM(JA&%fsXxEpkx0P=-8hH z-+S%XqO_lj@q;mbF~(0uX}=kubtu?2w)U%0+Rw)L-H`UfQQ9v@X+IsM{dh?G^^o@S zA?^301haK6Y#Uqq1sOjf(tbn6kI48HDeY&Zv>y^_za-LrO2%(ViT~2Q3n^{w$7KAP zl=gEX?e|3556bvODeWf(|0#JM+OLYVpA~7pD9^|qtgD6O8Z9|e@Wv%sl<;m)1%3j_NP?Zzf!T^CF&LXVWOU~U#2bZ z3HxaZD)!q%ePh2)@Yv52JofuU{bWB-@C1`TS{!C<_7g?@X1`JB*pC!C_A7;s{Y*ti z2HF1$L8Uo+Mp*xwmE z_J0PC{h=-43!Yt>-DN*%J9&XGVS-XV`%lYx#s1XLv41sm>~9Sn`(J~{e%au$zczU6 zzYQMybAu;1VV%Fre%^MDTkB&5xmaTVZ|K+`96I(7hmQTl<^3V{9|w>9$_2TV3w=FF8it5#qvyd1m!sUuS3WF?2hQ!za2XEcNd%3{~bK`hX;@S<-ueB zdEqJcrw31P?&ZQR``O!Z`aW?4MbG~C(6K*0bnKrG9sBD;$Nu}^u|Gd}?C+1~#s2@` z@qPe7*&hI&V9!|@U1Rh90qA%?f!q(p`wO7s{RYtS{sT+&ydMEP-mf6G;{6NY@qPyI zcz*+Uf(f_#y2j@H527R97XcmblYox*O+d%{D4^qg72xr{3qje30Uqzm0IzdcjQG2d zV39H*uCaL^2Xwrz13KR40UhuAfR6WpIHEJi`$NFzeIwxWeiAt^`%A#*{U+cGUYP9b z8k_f{K*#%2pyT~2(DD8i(aC-m=y-n%c)b4wJl+q3=fV49z~lWgf+Sd?T1J=m(b)go zO$C(WyuSuI-fx5FF}_Ss=y*R4bi6;u5+3i{0gw0dh^=^k4|u%a2Ry-Bs~$VN56F7v zQ^XY%9q$i~!?a(O=*bi6-JQ1-8Z$NSm9hJl_8Xp5Setua2>K zf1D+H-Y*9o@1GM}@qRk!cz+#qyx$Hy-j63d;{AEx@qRtf-Ff~za8bd1gW`=I0f ze$es$KS9O&0iomlfza`OLHS>@pAbCWUkD!WH*|#0`wzhr?B6GjV{E-ok@UVrI^ykP zRC-^d+2=@l-y`XLk!GKy()%XOK1yJ0l0U-qzDlL{S(<&9W*?@~`!dZw&Htn9KleC#zboneuVz0i>HV>0zpT>xXG!m`CB5I)?7vldKQ1u-!wk0U z(;fKT&(ZsJN$=k!y`Pu#{$8`+SLyw~r1uA#{laGdu+sa9ftwop+Op5MTcbo_dcU#R ze{A+6oBhd3?^jlO|FY8inMv<=CcXbz>HW~aiJ>93?32D#t+%E3OPl@Er1w*k-e0Zs zeru)oUz`2er1xu+-oLH%er~hB8~C}?@b|Nbff{ z`_D=5M^}1(I`Hp2scd8G{p+Onvzz_xr1!fkz5iY5{qUss%bWf4W zAgDMF0opZ=OCaYJ$14Dj;~1cw;kX9iahwCRPl6dP`r91;z%BdWpd~0ej*9>t$4P*W z<0gns;wV68kmDgf38~#@!p!^QUcYu!LJ)ob> z@gJb$co2e$<3q@Ki5meP$CJSKh~rCu$MGh>6Wn&@o5gV`oHe=g+k&Fw_!Q7_yb7_2 z<5xh(@hqU@_!i)C+za6;j)wsr$HxGV<7I#+_O2m09@uLC@e=K&ta_W+OMeSjy}xK;w|PMlm;&A36fAeSfcL7?M!A<%LB z5IHXKM4;pNBH(en5%4%333wcz1U!ycB0S>wCEy7Lwa#lBo8y~6$MH^}JK$BO}vjLmUzRh;;lR zV4S7h9f?bHWoB|)$0suJij*csdf)W=A|A*rw;kr3)68;CrQ36kJ zFXues_)2cUR%b0i(Q(`*=r|6O=oH6gf{x=fLC0~Mz~gvMxUU@N2|SMbBq(v9z!S{W zE~U%yq1*+d+E{{89>)o@gwJuqz~eY#ViU&|15dEh zY1c6}#~p)?rz89mlZ~R2

    Lr*!;36Aw`7_<$s6Kg#P$+`v`eemOdRpou4_bbLV*Z_vaaB#uLf z>)^PAxL%H1D5yA&A)Xt@HI(y;;~at~`1VQym*XE=SGwc`@@e9@h|qDIMESoGHxW9H zqX-?xRm6SZIE&zM97gasE+cpxrx85CoX=t$j^Ai4=^fw-O8FeuQFO#{9--s7kI-=( zNa#2&BLdS6{9no_fOXxVR zrP#!AF2UnCnBZ|-Oz=2PrtlcpUdrkOUVrPT?AxzR>tnxpJ<9V zkK@LIC%7f)_85*Q>tq;I%oP+J$C-tW#N?RNc*F9A>y(`G4C0;Ic96uL2j;Aa4L*nZ~$8mST<2byQ@Hsv&cpR@+ zY{l_=!4r(LE!N_=zHVqd_7h_iKF9loj^qD|jyN7LbQ~WTIvpoi>A1n9;|P)B|dRr|M8BFQ%pK;G3hwQCa$rGbF6gSW72VuNykYh9XDC&ILaojGD&>p zi?I`8b)03=ahGYA7l)a2TxO-?G%FpqS?M^=CeE{o`>b>vXr<#q11r8uW*J+@jW%(l zNyn8|NxV4IO2?fxaj8kisU{t_TIo2}O2@SZjvutnGPaI;O*#&?iHogtoNT4zW}CR$ zq~mOpj=N1d4!6>Axq%-`{j`j&<93sd<89)4n>gPl?zhr$z)8mmCmlDObR2P|5vPTmk~OT7126J}dF?z_@);7we3(sAOI zjvKFZ9C@YV%#)5gPdW}g>A3VtaK*Pmw#2L7ne~OG$0S@IqtrF`)($n9Oroa&~bczw3{5SA3BcT z51m1d>yLWg{5P-Oa~=S(B`*N@oF@Q$&KqETZ{=qTO8J~mz!v2E0^oDL0q{Bh0Qj7b z06fl503PQr5R`ld;BkHf@HpQAzC(h=e+#jV&G`_Zr{tD{c%1hIJkAFL9_NR# z;Bnp>@UCP6PjQ|b z@Hp=cc!KtT?+)j~adUrMY6(iYoF@m*f%E3rVsjoHLE^kR&~cs}@N~W%rStD7ou5bP zd_5+A59xe9N^tFyS7FB1`F@nn|D$w1Akz7PNaqVuI)9MKFJ$r!kC_uOgtd{Dqqq0by+>wHm4=Z`Y^q?FDtW%5mt&OfDeek!H&Rhj%% zCZ84XM~O_X>xj z>AZ4E=bckJ51rC^=}70P1OD5+h-++}$4=?Ic1q{DGkNd0A5atR0;40>!};-0&pCgd z*pg3A>c8UrdV<9H_N4sMesQ9B6ysS(Gec!X9SP) zHG(JDxbA0%^Ef(>vleg#nMR!75jxKI2p#8tgpTt;LdW?b!Mjq%`yO#VN$@zoBzT-} z59C3u_<6Fkn3X$hb6 zWr8QzVBMEk&ZB9)Tf+In8AZqWHKF5to6vFoP3SluCv=>j6Fkn_2_EP31dsE3g2(wj zg(rDG?c+_?hjAWIYipf6uAr39`9Y!Me4)^B{!o06IG-qVoL^K>@{fYY`AEUz{G{^# z73V7jPjF$p=@#cPwfDC5aRo)k`Ar=`&UXqO=RXx&ZQR)uI?j&@9_LF1kMpStk2t@o z$9q@-JkGxgo?zg*U5>FiKPz;cw-q|h;|d+;b%l=eyh6u$U-7&+FD!VRCst5#-dONB zk1TkCzxOKQ7@PCV%KaeDI}07>p@oj~(psYDJhjm2e6^(W*OJa}Yx3PHo&VP4!v)?- zo;6J8$5lFCF6sQaCZDd-`E^acT_t&V<$82}UX!m^>HNJ)=ko;?*xBDQw$ArUI{z=} ze85WQ2R8YFmChebI=?XKe8WoTA67aaG4S7HyceTQ12=nzla9_;OgewD$!APDzp=@8 ztaSck()p1|=Sw#ElauVjmdL*rfAgE1fS}>HOJB=hG&gZ<}=fZKd;Z16xk>wVba;5W^oBZaa^PQ87$5W^D?AeO;t?_bi+&XrkH-DX?QwH#6Z^bx|0%r9> zdp2f?H%`4d&6^Jw%v>tI-E-~>YtY18K>2?;#$a4YP21JB*rb_Do4JB*etF~8k1f{8 zadlkJ&#$#NgIC+f8>cP}Z6SOmc;n=76_skM}+b`qfAn`+CVC=fEEYZ9&lu zFJ(d3u}NF#P6T9uZeumPAJl1HTvvE=JLCl~YDRDH3WdcW{>#0oedIj(=g1A7;JwSq zY-69v=8ao7?-~l-fhj30;osQX4!RCj8R$kN{Y#E3-x*%NV8)MW;KgS3#;LtK)(1~8 zY46jPv7=UwfNp;R=v2w|UObqwIlOUe$qe}JsWb8J;W>n7@y4mX-IC&Zu2#s3>p1YN zAIcZ}nY@K%>>^83;5nRohVQU?ksRM;>QwQwBmX0OQ519+r~f9lI=ma-c@>-s-+fwo zcn5elKHxbh!7s^blri@A(<`9+^B?phRNi#xS5WYSX3({Jf_?`X9NOYB_+54tm+Mzq z`=S3rXDd#V>!fFd{ta;Y?-d+lmxzo0kJ@}U4RrSHfr9j=;zGGEH2eYjPt3O0z|4Ogbk1(B>gEl*Z3zm0PI36dsO_FVjOx%B{xB3L zv^;ceI-@_Re#;w(@>8}&|507u2tODq=Titg!N#$P+!8$_+&te#S%Omj@%(Sl&)yl0 z{;9g(Je$pjX+^mt(CzCs1iYGGp5wVKAKFpQt6}L%g7=EoeG?(^Pwv~v4)(derFnj7dE~xcxjj5Ijd$- zp5I2Aw87vB_Pn56W3PVO89H~lEANdem1eLlINK+sAiX}D5xR+i7~iRP8|&jaysp** zyuk2c;3eDi+7Z6s%8xl+V~?wZ_gy`nP({wGTVtC;_x3?0=nkye2;FxbuXNbQ4d5-z z6%Jm9M&MJ@Z&kq)+_^EpHFlBuUVXZf0Kcz}PQvx5^#yQ!bY^l>xn3Gq6W34KN8$gd zMfLFi)YGpRS5T6jG4lU`mk08=R@>dPbaCZ)&htTnDsF*WmSE{wUOnoP1%5DOuuz;v z;E$_|=c4+3#B)*~J%1Q=sI4n{5=@b~kUOcp?QYxm+7XoF&qjLVRwq+#{La|lBW?M; z%o*_B(6Rk^kI3(nH%>iuwfFJc!Y9G7CCS};3wVvYa2B8(KidrNtxC2$ zq1;cEbv)j4RV_s*bgj#slH;^~K(t(sTEBcUcvW)O!F43;f_g-P6Nj92cKVEQQpPLp z3W~01G3cm6l;@9jts&~Ex?TtMmhwIH@|)d?M!lx?ZxiEpTCYaESM%DT9U#GXhuS!P z?H`tjUnIm8l=8bz^Tw@#u?3-fROg!|*IBYI+8v76;x9J6oP&0WR{kglUgm^*z#IJB zt3S7+mVqZ2KT9#!*n6I!-J?7Cn?U!^&bH9q$mP|i#unO9iu#Inm5MoNXVspdC8$3c zKcgL1(`Ki!ytkC4p2d#Cywar-Sp~D ztNu;JR-Y?1m2y>uMfkpu;3&Vlj{4O4qUibZf@rdqxH0l>#qv zJ-&CeW9cW9Kdpf`PK|S-C$3-czsh4BW9OlCs88h*^_T0X&!4jhs&sqt{Z%7D3>>fUXp4>?SWs&eNcU=pS(2lv>ag+cq7#*>myy zly9r!;N>1(M$S{Fspx;GadA_Dx9SA?Cra?=#MD-+(?0g7H(6Xk;aBUN8@jc<(BDz- zeWytOM=jdgTh9LXYB|+0dPvQ&Y~XYL^>;=T~P4cnMApm-6XB1M~~k;o9gY0#iKrWu*)5 zY`0ss$PpA?pNVJiJPJe)hVIpL^g~s=5}D<^nzN-pc*T$WChsRr`p^Ts$gf2N)tLk6 z=K`O!$!R~2JItQ(@J6hl@Y8HAX9-U3-U7P9e^rDo@-_O^DzAY5;iGGh@6!#gC){ zuj|A?;4L`$r~GfV@}Dl?2^QWs*E06y>49>b!mHhN1Q)f#eO2FTbrV~KerN>U`|{Pn zyIgHCcx7*R^`=JN81U*&Dhr-qf;%rQV;^1L8oIxJ6ojtLE4&vprU1rcDo*MG(D^j$ z1zzO~zsJaR1Z?f=3XW@^Lr}F$p9nm`^dmFd#(w+Ft4I5HC`UV(d!@s4VyV(D% z99P*IqdriE@Co2G%~uz^Y+Zn=N&E5O37*{SXB&HZE$CFr8t0(lw{9S;-QN`@0->TWsw{KX2qE8ai zSdfm6?gCw{hF<*{njQWx%HV)9cpp^%1YN;DoNEK>P2C=NpQup&)UK2#7*;L49knmL z{Y#|<%JG=zcps_Vi73>gj@9tKQjMa1(7nom_gNKR?$w+5OY7mjW)46-poXJSFO*O zea_tz*CCj4)_7}CcmJ?LsY7f*DgWUVv;!)5HrfTc?uT}Q>McUMq0RodM3gWQQ4A0P6@^{w z?(W78P%#i4uX^pcc6WDP3wG^puHBv2?)=Vq*YiE!bHBe{&hGopZ`qxhot-&z4*D^5 z@jCi7{WBfynx5c%pZdSZj`E-6i^Kohx|R$655^Nf_(v*}%Rk>K4|vn7IPahB)w|<; zhX0w7W$9AWEc6;h$QE|Fv^|pLo&)s5z*LyVlVAS|?PJ4fI zX%2W(($xfyvC5Ncme|Y6HHPkW-QLVoyZ?0hmuFvYL04x;FmxYkIPdpE>35@D%)aTo z|5IRuVV;~wk4WBhckuziyJU%Hljx`&Zyy2Pjr(3PEA3A$Pbq1TNQDnnNz z#Cabq9r6Y|uUAFD^B&j(<$rBh6YYXACV8m6I7@#sa6vtbk;|W7%!5(AS(*vDqJhph zFQLXkz90I~KJ?dmVN?isxmVw?m|tQI?x${6uOHjM>Z-WCYC1z)3N)P1Y zOCp`|bmKQ3Xh%^uqM^&$IWKgCCiA8~ObL72pM!Be?rAz)kL}li&#Q$C%Yw&PXx>Mw zb;5D$^;AEbk@apPoa^2lHVL}zE9yYk_D+51#&jP6-Z?L)eun(SypdXUpcHtUHg*E9 zLH(z=uZ%vKLTs^f)g5H>@61__c`3E-r#Eyjmi2}1@|9oVe7I(0wcC#;6M|bpvn8V)W-~ z*{i91Kh(hr=v+Ta>UFxqP=V=&!YV)-TZgv7-=lzB$le z>#LPg~F<5^mi}M_^jQN9Y{nMubpVw#F)&Xz3_hj(Ojss6Iu02>RBISc)#^!B)HY4+A zyetb{r`H&dsP%g@KzDK>`fC+2Jf+FJtp}X;VeN3*ONuO?@O@gStJ9ts&*vOuWT)&T zr|YD*8Ch4bL~@j$x?LQj`j9-Q#W*-`J3g-pjB(m?=|lVZxK3_4?Iv{iOz@iK!1zru z_I-K9*i@sDIX3#3#mM~fUa`>S+~M>u+mfzBmvWEO|7@Am8NdJ6`y;rYFKP^gu6Vgj z`2B(tJovmC{<0r?$k8I4nCaSrqjBydlu-j?i&DIllD9KeyCdUUHH6e zS|}L2Wv6c&WNMeePW!Dqx+mM}_3*~vG4{E5*buwt!5Yxj-Z>Y#XO91i{;)m~x?#Ue z=;B@5g7<#6FL?cq$C>;)o2x5EwV-za@E8x&PG^dJetB=`{%$rB{aIYk7)O^j4|M0+ zrG_rjAN{m`{@umma;LsSKdqbeECb%B*QfZnVl>?S%#WRh+4;6rPGn^MtDEDXd%LDC z^Yx0m^`QIr#GlZuG{93C&z=MC!spW9-F@5Vzvwjn=%-a?*J1|q7!NNlVV+Fe z#;*H(i^0gpk9Q~s-P=U?zvxAw=|}*0XIDP6n9pcu%V&x`)pFWVl^c!tyv}f-8T0l2G*zKn7rqiYLR@E(lTTGG zX}*)g*Mmygixr&u4Xi;3L-3-T)dsIw|Eb^&Tjtcqj_VJD$9R`=ql%q2R|Is0^0tT0XQdl-gFZX;|9kQj zHkZF9mk)TU@(g~J zI_-q9Q{Jl9ujcOd${;tBk;`}a(-q~XsO_|~-2lkH_||tbZii=i_qlj zpPK6{p7(~tjyQffEDXFn`Oo3^&Qx-)lQC1T<`H7Y>(RKrZR_em*X>SS=ynzw2VG1X zr+#)@a2mYhMazKKG&g=nPZ*sXykPgiCjUQ-7e9JgVz1tknvbgoc5diajd#9R^W>V6 z!2DGsdP5hrvjBMA-a7NG9k0bPU&j~ovlyS;Zv!6V{sWsVvA0J=LYMhx0`pY)D^C00 z-fbRqoyOIGE^>$SeX2ZrfVZ``)1Tany#t=>!xG>zu3DDNUcS7GIk&f*WMR}EgR(>SX>EV-ntS)cbJ(@AJ9txu76UKmzJCqoGba3z*S<15-qe?m zM=)}E#ZuMb^Xlxn=Fm-jT^YL8W8wdzpZ}hh@8h-!yhd)7z*`j95!){* z^ZyStnuplKqB@(m)6TOP`S_CWAZP@^F!BrY#)^WMjgZW zdi~63n}6qV`h1M~VeypUF&am_Y_VT#LH$+Zi)S*Jf9z0u=%NF{p}SDh8SkH-jP{^9 zpL4zs{_?K_Ug4$Cs>7`xg9P7;&Gs z=0W?`eHy0+Z$e{lldo&;gT9RVsb5AsH^x19{wx~wP;-HI%aEapwh>a^pX&)Tr9k~%g8ug;Qc;4!vqa@#UnF0n5EDq=IT zF8r0#PxLLa6S_v#%R{%TMQi9D4J!fOuZ}}(=ARnz6})8G3xT(+V=wR+{k=w7U9!JV zSWqz3W@P@SKl?&gu3An;72PNublp3lzt;7Q7kGY|M|A?vCq-%SPS;N|m_Oggc@B(i z{dy(#$~V$j>=9@)(rNu+ZGGsr-f-&Q^^p^y3yyc{XM?UMz#G%LEO;LEJD~iSerdt0 z+}Ek^`$JQizKy(WMlN?lF6TQn@SD?ab_^`e|BuR&*J)R)+WCUFJT4i^wa3Jv+}Bm| zSj=m&w=JJn4c$%f81t8UV~PEu>^|n{B1fHef609|bPZ?Mgl_mgr=QqxKL)&!i=2Ms zMZKHgoyhO>Gn=0{{SM>1;d3mp3$@dDa@AWfsya=o^Kmt)F~&PUJ?>nD*cETSg0A3#qR>st)dM;^MGLft zat-_2tS`_f2c!0k$_$?C2aI>roG*L%|5HtTyMV`d z-sb-Kpu4s-4!Wbsk};~|r+uOO`m#58vko>0XMS#fjCXX8O?kk3xFHpIjH~i`nfDtF zwnJ9uuo#)YzhY{O@%~ijdo}E58R(|;ILXJAPe125bnQO@yl(+@`Mh4#ygqn-B}ReA zxc6s(nK59PJ>W&>2u9Y&*Si2+(WuhUb*$V8I`_q|@f`AvLO-ph+)B%Q{cTrH@T#{! zKdnZ@+~fZX7*{ydd^f8X<+mMSF!J&4>zwb^M}xi@Wa{u*=%>}L2F2M{6PC0FuiDFU zDBmS`7kCez<2lfNxW(WFe69u_Jgq!S6*^`H6m7R~(+zJ-9VrOj^i}J6{8PE4ams{G6`T9uPK7h&i zYan#xTi!xDB7}Z>wJ019KUEUEkHaqE_u70%Kc!CX)3_eS3S9%u9jh9cogbYv82NYf zrP|QdxjhBCC$pUTnN;E^bQvavgXc4%J$O6XWC5@B8K=HS?n+^EIgACrdYKakd-%|8$Oq&bQm}vSjK7yZbO-ze}4Ry0PDr^Ldps#A%Q5Z9NP=pLa?-@HRe+0FN;+ z(>r6>fP+TLKMICpYNtQK@7k2i!acHJQGYM(+qQ}qj91FucnQ1HI^ zcLtAfpf%6fTj@+h)w&@jBbR?_q;uaJ#Ah_g)HkYnLbqm(^PJpkmc(<2{^|6GpPm#3 zFYwtri}{UyIrV_Ca@U&?E9;lD?tBR{8M*us16nd)dGB_hYt)FTi8WxFxSCcI8LKpzGedJ9L$v#q#y)KQExa)+bVB zxB2&H(cTlrE+f%j>-3p7^8c^9-$s9}zYHq@9%J{X$xN|F_q%Jb?qeIL9k+Pbm2I6o zc@yUAl_52tTRC7pc&TnW{lw@`d%?RfHxj&hi`sz4I4F9vA@-u?g`k`84)sIr{P7dI zCq91At*wXtTID#f1pV5ET`?wKPr7=!87aR=8t`s^boxcc>hU=Zv0F4z7W1pN?g-tH zlVQ-^TXcqx>+X%5=U{t`1@Bol>qk;@O9 zhjLYcq4*u$W#~^lhuM#DU78TTo1s%0lt11xx6Qh2XJZ)k@ab!L+@q(I?hPJekn3=3 zR#QK-*MYPqBl9Ci{KW62P^fo0SF}H_@5PWd(A7BZe4hsN+Y4Te+s<`o{5c=IO=)X@ z$C&N#4Xb*gCgzu}hYUt8zt^2E(0y;>^e>U`?n2kJRte~~fA0cblN<1VQO#op*sMF^ z>dL79I_(Y~W8|l-cF?2#=Gev63`XWHtQW`iPOWLs9lDHO0nlx(`of^Y`p3d}@P<^V z&$j9u(Hy*){i}dC>87=4rW`wTGEiu120`YZi#*QbS>!8m7WgWv`tR^ zeE;PjboKT|KsR`c^L-jwEeCi5{o-u?ox))*j9Mr8fXDdqYIqbLYYjZy6ZpEd5Zt#u4;FTHRYA`>veS7c@C5D5SxcLYl*Nj1F3ff{{o#(XwZBc(g zcV~TV=-Quc0A2pl8oJCMo&F?`x(wclxh26H-X#jWD}`_1IWRT~46*0G9BA$?;%_nX z?>61@y4B5EvCyrUmyJ=ksFIb-)u*$d-&Wmy z;0L32&*}D$2|TXlGcep~&SzdCeoCl>K> z?fuMYKY#y?@t!KS592@8>QHO&7+cNRYE7g)Nrxwwuo+orlylnC<@Xp*s*JG(ab0># zFX&%ga#I|1 zLnrv~eN#&twPim2VM3Q{o5jcVinC7p$+Q;VKkBeYP4M=IGzO3H{E#D-*nQXchRzu4 zw5N$@Z=rnmiNVliDet`B!;kJpdm3~f^+-=zoY~}`4=t4gybfKQ@d9J}HnlCW$M$H0 z=Taeg59aG~=Ziu&ye+;L)w;H*=Q?YT8Wx{FRiFiU1zY0#Q{}I;j*qLW&i5&B#KWUy zo;TfK!`%5|P$fv;@@Wv?ozRuAb*Q36ls)csbBL}Wu zF?MQI&)DSUVcSPsZALCX?(a+}Kgu8dhiX3M0N)RF;6!IW|G)UWQ3&|cFWfNbus*TU zX+Lj1^krKup3?|?##<+j8hZ}ZvE_+GKlg!@P`Y(U+9a zT_28mtIJMEXYu*jL8#Yy-lVeNEqr{OkE?~lhcRC>UjG%GDE5d9lc0;;R)_gIO%mFb za+xy%x+6KEQ>~Jcz)O=<3cTve(N0z4jL+~q`ZYqkR*dUf_!?rLpOOy0+rSn5fZjSE z{em)|d`Ek_Qyu+=3ae2FyrpTr8hjmx`kwa+B z)4vT`@_8L}uPO8O&&<`Jo9(p>y8Q2*=dh*k4)Ds{FAv`SM|gj!j=4*M$2h(z`FD;V zV)tnJZv-R%?x!c8p$j=$2)g)8y-BFUr#HJ+PHuN`$qD3grnQV?y?(XA+hW{Mq#blU2O7{F zd9|O9t9J=bdn(g#CU`vx)B-ID6Xz^ibeJ9sCyb>-{T*=F@O83VRvXH<;;(j1W3#|mYE&UeoM=q|0? z&i6z6jqU>7m>j{-ef)IWVtvd2+)ur;NKdx)(MgTLE4BmQJ&JMA=<9~qg&)j??%+kI zJsHCjq05{(5<2fxZBhQ!>;=Hvb{h3TH7KcUF8{CL1;86Szc+Y{vr7&$rdA)Fa4$5} zWaR5g+dqc+%KVfYx}*J5Ll^0bdaGtEaxwUP<)0nEE7__Hc-eEF=Ht3)N3;vYm?p7G z#InufjD`IJOh(pC-B}m9BLCEbuEFO&q3at7ozAxW9C+E&hJn}QW=HVS{rd^ep}}sn zYt6W7Y#z(aBds|ulc&kZJR5^b5Lo`osKx>B}$BZ|KHf{J`tt_QPWSXJ7O) zy88B_Z0jcOZTLK}>X|K8>xSjbd2{|X7@2?S>2BzjKXlsB*C`93>oul2bb|ZmHUU3; zRVVOgn@;<2>3tu3za2r~7iicOJjSGaGYqj`R#?IHMz}?ZwLB7m)jHL8`Ui$A&k#gO&bkfrG`F?ddLwM@EE(b^R`>2iZhd!$z(7x ze^g>NgE7socF@hN83A41!iV{|4qfH6r+MF}g10oVHhAeOHw5oW*?906bIl91*W4Rw z_V*i|$jJIIeFeI_sY*f@e<%vNk~1&jIb2T|2;Q$<85osoN-yw|ckBn=uDJ!d9%{zs z?xA+7COyq_S4Ufnd|ZbWhHk>>4;JgcUvt`1=D#D@*4E3G;Fa{L2wufYTfp1k_`&F+ z2Udc|*rs_Ad;N_nX651cEJoJnd)y4VT*n$h7q}zd=HH3*eGc8)sR7_E&e|Qk$0y+j zqt3WtT%+z)ac916J;&7?;_7ZQvi-8k0Pu_MU5WN{II=7Al*{EH@Yj3YH<%}wwG!^9 zTH88`kE_! zX-6eH{Qz&(ML+O%|L6tYYkwQ#X~yY+p|;p=E`3eD&fBwcF{%cy(?GZO;2`J{+JC|G zi#XO1yxIO?;N`A;&SHM*icUY~-C#7^nz8PQ09))5yX!%B_Cj6gQZ*h2UG{cPJE|LV z8oF2EWx!kGhTl;SA0!7a%*$yv+ZUv^xqQYvJ3Vc&n_b8aU7nFKD8EY4i5OqMAK#n# zDt1Ky=w@bA;1#*#w3`Lz3K)F8?kn6!R?r>lrogfcNl23GmL(?E)U--FCCAbAj6;s*MY=8M*xO z8&RM1nmSobzOH-|vP0K&d4K4JFYAHl@MII}sV?8M7U+f+zf8+E>zFzhED*6F+{*Z^wyuqn5ftR%v`VBSH z?>PVeYI2{>d>**}`CQ}s^AJ0+w6YoLu=a0w-C!(~;IyOKMF+607Wg)DbmeM+XMCLj z-kCj4ySY{Q0C-=T8sKFpkA6}!?kTg6qdL=ix{L^FdL)UhAACynX z$Mx<*Nf=-ETZsNz&;ODaydM=)@_AKo!(i|jCueoD#BP-2jN`YSZO?oipF147eC?g@ zfF6^a>keP$d?$1$RR_Gg)f<2}`qyy$Kj+dp^^vjZoWT)duWxt}|3{Qr3c6{@&|j<1 zgYM%#dlwjF^7U;kpPo@icJ&6Y@6Eo9YSqT{cy5J%pnq131tyI$#Gdxd`HtE))A_Di zI1T-^T6npn#rn!;TcP|t$ts}yb>7Z*o685My`S#ueAiujTNOOUgum_>0pFUMuxsLs&pDR@EB*d z%w`_B5Np0_5os|pf7I#Od_VO3Pw2OGo9V@&+gRoi-#@i3v(t`mO=`oo?iAgW&+D^O ztAY1;%o6YzXMHVV9(*;-yq`fIhXx%1t> zuV5kYGPgv3tx~7{gno=MSHV!T^rXJ#p2}?uMlOG0$()QjylXn>yxXF`R*gqI$MYLJ zxf6It-jxDxO}sOYu|BW!96r7qVR1Q(FKDk~gI)E_JQq(JjC}mVnL5yA+d7eXdgD;& zw1;s5x+%TNf>*Ih2k`zrpB6mdfrD-4@64BqQKc!K7d*yetuvZp>vz%6-JV$(@1;_O zoc1-pjxThtCntlh^~gBzK0b5ikro|k%jfmFlqPs%J3I4EjI-YrG{p`);zG zfh%i5H*uTOUwE6&JQpGUpLa`!qP)0*H}QY`5fWnZ@9etOnNdyg+>iUpII3reDfU0P z20}OPW+p~`;e8J1e);x??ps1#u4gKBs~+IB&0iEeZ}rAt{%Rv0yqf2$u&o&D?F%x+ z&a$WlblHwN->Xg42IyY>{$5R5unxM8MrH7F8sO`x+p0UfW+-28-u4PS#?b}xntyIA zYL7pe63D+hI2*1{ZyM4P?cz&wT)!^b3jdFqH7GO6FZpT!qxLiQ^8L`|1G<=u3pNHb zD#q10l9?w5-?H4w<_Gfe$Vs@rI;KM(i%k95t1)!`p*5kaPdCbG)v&~cJUbS zQZL8@-jn^Q!24Ji{k39j`80>o|8Xkg!m41Ck#%bpbb!w9Wf|z~Stt3po)t5U^{PbHmx17E#^d**5~urJFrHQ@U^23PXl!Zdo|o+eolA>1cn%%L zp}*D%C(@eCn{hHHc;6fJ1@F@E+x&m&L5q9wdA)2-LGT!F{7hqteShgUi}hwT^w&Ds zr$Dx~|AyAky|`5ly63HTfmi!Eo`a6dzZkrwsj7pwA_Mwo#rUkx0YmJbJ=;U~r=Qb~ ziadJ&-Qb)-(0yFn73F7Jw~*_NicNufq(1e`YV&o}>z@t04b5Z0W9*Wrk|B16TjThC zsI}|5F<&jI6A0bgCQl7Ab;M<-9TDPumxQLcp3AM9p*)wNRT*`cE6Z_RLBH3z7z?@v zCy3o-?>6WL$Km~@GDWw7u3ADEbZNIb_peT^PvBh{;E(br?Zo?1&+L-}?IJci#yy(x z)s*IzPV%zLHOgW#^7ZRGc>hwqg@GtP-;$en-d`KweXS4dEeYP{wU-R$SNS>=yvS*q zZT)(C13nMDe&VFH^jK|s{-%otBlBZ2`~_XvIZpi?nEEJm9~Xo}S9l=CAL@QW7Vxqq zIrTs9@)Y=;Gvo7t$M|qo2K#55Xxn2{w86;buc+A_>#7U)V?3nJeDZ;AUlteWrUp9g zv73vB#r(*5?fATUbS(nBA4?DNam~0ouAqH?%P@QN*o+a3%*!)%I&_z|)PgQ=LPO{h zQw@f0`WdG`v3^|z?@OOh@NVQmf31@zJB#PQIJb6)9X)QKoo#n9i;;hKXV;93YI_S$ z==Lt{$Ed#~h2S|fPTdo{=*xw{o8ft%7|FICIHDzZjK^~Cvc%4?wjy*l zs&0nv(C>BoPW4wqm$hjX=zcV64xTZ-9(Yq{JN3B8e8*2<+^1sTF_!y~!WO$|RCnky zw;#yYt8!d*-Z#76xtn}lKb~cQE^4UL&f*$u;QOJ9KSh77yn2@a@94t27V{aWZT7Ln zuG`9K$Gc{A<@4%jrY6i+jr?jr*KfJwXK~`D(@*R>xfi^8Ya_wCF|7@F{dX2Z`HcAv zl(5DA`xEMie*Di*=+1=rL07vP`fL4o>vHsKgcu(b+!urLCK$QFD;1H(=Ic4}W)P!( z_wE;-H)CIlK_>RoE*+tpu{R95S0~Qk_jWdLuDkQ|F}S`#WK6ox3HNYF|-2^M z=$_45k9N^+-~f~P?SE!rR4eYdgSX;#fAAQ`-l=9?xjHEE+`|x?k@+uLc8Bg%ngHl} z#k{ase{5bnbgduPV_R>l)*QTxQB}ZuS70@GfBp6&OV@uhc#K=~6}H9xI=3Qp-6pq$ z?%142=<Z7(uGqD}V_dP}vL&{A zr|HloY{v7`gU%d;F6YSz=vuFIzFQlw%mH4iBB&4gqpyp}<*$C|1K#}OeNaAQqhhg^ z*vSqzC`&Z$*EE{>I@7{@(5WdYpgVSXFm#!{TrEBy)U!Q!w>E@>=Y8V{A6Mh&qCIHF zHP!PaiajmtFX#^JsSRD>0}Y_t+DSuK^t02S2zI@A3H&PSN`h~;jspJ&#nj^8@pzAZ z8u;>AAtU5{dOOwr95y4J)(7`_K{qiM`fYXQi3gs?g^lR9)!?!I;CcFfGMImA2l{Pw z*`o~G%IwsN&jWjX-(jp9SHW)b=BdR=ilUGJ*URqWmjyzXtA zf*1Htyve$Y!!aIFaYi6`jO}x!FthCFW`Ec-#bRV$gb&6ux^hE|cl3}k*;udEHqQ#( zvUKRT^}eV@d_Q!vC0+Tv9#AX@ysY~$zEX@nzCLCX|DpEoz8ex5nOEvK#$!6AY6_jZ zJH~J7*vCZ{omV@a;W?`F<1pUS6VGD&rw{FFjq+}-*Y0oeyrP3T@p;AAc<>TK z>@$CshHmY*^SHmKgPiA(aw5jl>bO}Sy5`mEg7?sC0(j}8o%ZwM0LJIa^;Q}17^m5v z46%Ex?f_k(aTwq0)HMg2e4S4(reah}#^r&oRp}V;{71LJ`)JZF=lyj2jW2k4t}5^t z{paO0#g1PW2i=rFAHLuEQ(Jt$=uT5j=#Jg8@Ej7)IPJ+l9^XIuvtLa4Borc z_+CdV(%O8w5MV#ZlU~Z3xc65T-tfRZ~bEr+EKHos7K0eVrHAm4XU04yiM(# z@xp@lt?(Qe(|-;z+otbfPpUP+U?e{6FDwe3=Qw;n>e{VP&s9?98hpPQ@qc^>YQg2I z%C#z^{2|fna9t0b`9;07=mzi@4^Av>=HFGx{KI%;FtW~X9rXHJzbep`EbF`%7Wuz% z%6BaaUY4jHDE~*rI%pTAay##x{i!`{E{AdXIakx=L?&}pkL*A`zA!)fZT;b&{rvxG z>mT&nx>ThQ=+gYSVKA@la`fAJ^jypj=-De9@p(OWdrj~dbFR5+yx%*^_?DxX$;i5( z!%qDyFl`^(T75L2yL-MZbYCZ8{z82l7H2ZQ?DAxcdP;;ZcrA;g-&SdM_+nhZcq=T_ z6#MLR^xLX^`Ml7r%a{tfWbx>?)t7*DxKF*qJMeimb7)!cZe+!LjV`E%F<;fZJrO*{ z*!%&e*d_PZfo|jB`q0H6!TgZklN&lca&;1PUGA3x@BSRjFX<-7;0L3RH6O&~>(ue- z7!{*mPY+YA4~H_$17?sj7}2jGnv$^K-i9$ZF7ih;IsAieSv=sUsQioYmhQAEEq4 zBZ`ApC>i=^#n|`fR7333u9z=Wqff<}e0_tx-5B-kV{XvBoEFQd@(lb7?QVDDZs6^F z8VKI9TaWqv>85W{uNC8niaR5ceQsfSCJQndS-<%u`fJrQSvBZ_t1N?Vy5k3}2rLOmymJ?}^92`!iEGc#P>@f3W6VYj1{pUS%+H z`MF~=Lf3Y+Q~$FyOKH<#UFWgWKEhTy?Pchg+dS@3bp|=@>+#(D;H_<*9OdV18fO+? zlGb2k-s7s?2II|=7;mZVU7U8@z#Hob`rclroktX$3Et4)T3nu55#;m}AJ4_|aeaQb z(~mHw9Xusb?2SXOL)ZAa)9=h5?DRvC-H)MPYSqN)r!snF!u7n`;(_u{-@*7)CuS&* z`=4T`(+@IcNjc6E`(?i(&^=rD*5d0r=k4^PH$yA3t>@-w$>(*8AgAB`wg>Azs_5^2 zy2!mX;Jv=!^y7?1!v~hw6%RE>`Dbg@M)_6Zoci3)?ImtgE1lrGTiOce}WWuH3+>u>jS+Hb*g zJ=j+B=QRfJ#mXAsrEr}G9%I4XMeTW)hM5aI&m=IiepI7G=oaLTgzoRJZJ^uRw*Yjn z&!ax*5BU`H)yQcDz>A#T8@!%n$D#jXoEI8u&lnP8`giYQF>?8*ALNG48k-tABM<7S zHp;tLeEv(Cj^Me~Dg$0fmD7A&?P`y9pc{?AIw>&k-~c=5a9z{;=y{8g^_!2>gKlR5 zth*|sJao!y&^eS(i2tLhXPC|WlNUNNst2n+b3LOM;2`KjQaIx>#{M}x?FOTA*(S|p zGcs*pI`j)_v)2J0|EOvo&~K<=kNsG$>xTcp?>)?men*XL0zVjaH*Xu1|GHv1@E8wn z{nuLVzQ^izxsc7s`p*xX>n_`IA=~QwOlO?xI;jbC?~_M?*SP#poB3BO-UrY9ND#`8 zt=<*9Nx$Ilq8TSG3$ew%RBixtyVkohszV`|A5qo4(2wi=qer0K)lSE3% z%wT@~UGXM?F6P^aZD5*;LAKaOt~G+%qjf9KNX58yGjPL{_O`$fUR&|PZN6S|2$et3SWRX^yi=kQ|GO;%(8uls?4 z;Pt3?3GJ@do+$9vW-kdIV~t}!EwQIHx?-{Z>I2+gm3CG<+v;BFhR{ums14npXQzVq zZG}@mCp9_@o)sPeo_jj<%bGENp|w`0w%M$|>Id75Tz+D*IGb_xH5W#ewY(2>A+FJk z`sI>z8yU$4kIsWfeDFvQ9%IwEOkBS4yL^Ln^t;f}^*~40$Hx_2FLZSM;L-mB9{qpd z(fLFwK&i4$i zpJiHFmefp1`aS6vrJt03Q~FWq zSEZk&{uj@Q`eW25>Ywo(8JF!pYluz#Hy`JI9rcR(d)8^{|DmJz0d(|!0FT}m;L-a7 zJbIrnDtfU$G@gNu#yil__=k0x#zWB2_y{~2FM&tnC-7)I1s;vBz+$v9BPg)&Z*aUrk5&XsX5CqqZy&1@_Bjs}mutHGo1 zZ1Cv2n|Ye?y35c6`X0CXRP#3(Sx4XL(9w51bo5;h9ew9RN8kP6(L4ZnG%o-i%@d#> zqj>}H7#pT;W6^wq?Yk(m$;jo?JOgwz4*?y`OW^s@JOy+#Zvh_7V;Ib*c@6Mro`Y>o z^B&;QJP3Go--B^B%?Ck8^Fz?ld=Ydse*_)PCs}+QG`|EM%{PHZ^G|$S(|i7 zah`{Rj^^i}qxm{K51PM&?t^Pl@MwO|U_Q~LNysgaR$~>>k`^r49%nQprvCJFGJhIFyGfsP3!shwr4u?}% zGVd(&&@xXg^VTwtE%Vwk&n@%bG7m2E;*2h9gKeHKuXJRECG+Mok1q4ti z^Yk)rFZ1{^uP^ibj0YmVSz^mNfUFb9x`C`C$hv~8GswDwtV77Ugsf9A{&PB)Ew-#< z$U29td&oM7tcwWBdWo!`$a;#bugH1}W2S`Sw%D>BBkMJ?ek1ESvc4nhJ+l5I>p`+U zB!PwwD(j|<&kjagyq@~GY^W{ks#(ve zE9&~(cE$h;Ys}@+E zD7N@Zh(Cq+SBSrb_+N-WhWKZQzlQj4h(8BoigUjr#Ad$_e*cL-i1>$yzlivch(C$= zmx#ZK_@9VB3S-Nu%Z&f}tB5~~__v6^i}=5YKaBXth`)^Z&xk(_>U;_cr+f;k`|ML3qD2Mg-+D$zRBv?XN6GzCYwgg!@E( zM$nPp5p?8-1ReP$fk%Ey;E~@Fc;v?f9{Dwa$M~dQag+R=%-f5XMKDtNiu|CUBR?tV z$ZrZd@}uH$j3U1(@P0hY!l=pb3Ow?|0+0N%c$}ojPYXOoyZ`merzb8 z{Mw)+KR58m?+xQR@`D49{NflD`N@IDn8PiHDK`1hK}Y^|7}t^C9dzV}2Oat48LTHi zJ@CkHk8MqUeBhB^A9&>F2Oi_|-o;F@$q$fqiu?niBfmlD$d3>@@+*W+{0qh3Q2Y;;$+G zo8r$Y{+;6QDgK}04=Vnl;xEdW??evxk^WzQQt>wx|5Nct75`N6R~7$N@n;qPR`GXb zJf7~E!G5rFxA~jm4=et$;y)|?wBlbY{#o$Zx_##QD2>6kUwu? zuk#@$BR^;I^Tl%|KVU{pe!3YEB~UGcbPdGk}ivA3#U@5}>1f3h19`-vV^BkAYFq zz6S7Up96Tb?*Y$)_CbKhcrjptMf)Vo-}@w>qx};W>t8iPf6e;L*MlMos%rz+-IDA-hfcQ_Mo6N*IjHr+q7YKNRh2fsXdMKu7yt3_7f79}IZ1 zKSuV;$o?7GPs5nrt(eXGY^GAAN3tJD_9w}HCE33u`KPCIA zWPg?Hx03x=vL8$KXEA=8p4k>#_HW7lF4^xT`@dvAnCuUe{bI6zO!kw>{xZh+3jVg( zvj0r>r^$Xb*}o?H*<^p4?01v>Z?Ydw_Qx?k+!JE|cmJI1uao_Dvj0x@;}N3W(LO!Y zFWR?<`bPWsxSlE6*T?mY_xYjTF|JP$WYhjXdz`Zm5IWi)2p#PkgpT$RvQE*yLg;9p zA$YX!5Iow42p;WA1dsM9g2%YDPi~v`FWMIa(g6AQXy^+0QNeyJf$(?EhxWS*O(h+aE6b z$7Mgc>@S!7=Cc1>_M^-GblI;i`_~!or#Kb<-~H{f|6TUO%l>%TFHea2Mf>O(HSMcM z{i1#LjEeT%W8Rwf;e*GRu4os7_UGH*^JlUdSx5W!p`(5M(9u4BgY~rUA3BNy03O8! z;NzO&1b|0z1He0b0qduV@#VVn2E`Y!U)?xsF*2Xx4nRk730S8oP62cjw}8(piemsC z#Wg_xL~#zlqqql*isB%E$N2L?CX?bL*w?>wuo&sIrnm|Ge`<=W03F3yfR5rWSgfZw z4B$~*2DUZDX#kJnHh@QQ9KfTv4&X7)S++VsY>N8;9mR!!j^ac>M{y&dqc{?*QxsPM zJc>5~9>t#kkK$3Ff1>yl;4v1SS=JDn;#cr-O>r%tqc|7PQQQmke-sA;I*N+{9>vKp zm``ytz@s=CY%7YZ0UqOR(=x=SxEs(>JPzn6P6z8W#qEHO;&?zuaXrAJI3M6q+z;?5 z4hVP@7X&=Uz*ebEu_tS#gPGz;>sAz zWBl4M*ra$f_Re%`4MsjracH2UI5o`E6t@OCiem$v#Iuq3HWKef;@?O-9Ep#^7*XBV z4dnkr;sHs# zApJXjki-*`_(BqINa7DkJR*rtB=L$Er$h#sVoN+DiFYLNk0c(F#7B~NNfJLv;wedd zC5gAh_;`7UDYnF8l6XxLze(abNqi@X_ayP3BrcT1iITWcj00{KGR2m-QWAGc;!sIk zDv47iajPVbmBh7@I9C$)igD=UOs3cp7fa%1NgOSSt0i%^B<_~P;gYyq5~oYzb}?4E zcis?N;(9fucwhXyB@URx1(P^o5;siZh)G;Ai8Cf~#~3TE?ehQPl1bb$iDM>l%_Pp5 z#66QZXc8Aq;-pF3G{%Mj=fXLjS_!MDDRI>#&YHwwlelaWr%mFvNgOwc>n3sDB<>qy z;WH&Ijt4jQkh>{y;UrF+#F3M@auR1wP~y)?JUWR_C-LeeejVfM{0SDvwaeY>fg$nj zB;K9G!;|=U5-(5U=Se(0iLWQ|_9XtE#N%VUm4BQew#4gO{X3qY#P^eUe-i&s;sHv0 zK#3P9@dF3`jwi^t^yicau_fN1#3PjWgc7e%;ulIhLy2!F@eU>ap~OREJlH0!B{s)R z-+M^fTSN}NfF zJ1KD}B`zi7`WN3Vu_bP$#I=+-mlF3<;$TW#Oo@{zaWf^3ro`1`jA@(O{%_n(iOVT* zIwfwW#PO84o)YI%;(kgTP>Bo5IPynvo8yJn-S>B*#0`}=q7r9R;*LrjQi)3{aY`j_ zsl+jrxTcJ)6GLo{clz`8R7>KXN*q*)lPYmjC621ZRh2la5_eVNuu5E3#`bmmZI0Jk zaL;o~;ua$VV z65sYnPG>wL@oyy_uEfWcc)5&MatGLAFQmA-)Eu0FOFUwUPb~3@8K31WW{WNHj3wT& z#6OmJ$Pyn};w4KQWr?dSah4_SGUJ>6*=?~UF0;gKmN?E5*ID8`OWbFP11)i(B~G-& zjb;pQ`pEikTxp3rEpezNF15s|mbldt$6DfAOPp(od(Bw6#{`SxVdwu8VoO|XiIXjH zv?Z>##Mzd(+Y*Oc;&MxzZi(B?=zei-BFFO{5M11rxZV=yTjGFATyTjKE^)&pj=01X zmpJ1RcbxI=h!h6LBOkvkr!8^GB~H1-F_*aJ66ZW@U>+WSXo-U^anU7Cy2MSFIO>e| zFMqPcmN@GYhh5^bOPqFz+fIn~Lh;-&E~ohJ_+5(kj&V7~f9Lax;=zN*=s$ajB{s#2 z$9E6KlZTGt%QGs9HxC`fpNEd((c?Rn;?sji@#?{&`1Ka^DV{xejMqIrC5lb)?)ki? zIQY;}e0=CAUOsdbKOZ`Zrw<;**9VW{?Sn`0_rarh{LE8~-CnJa5S!xmLq~D^p`-Zz z&{4d9{!UXA{~tQa2f(N)KLB`?F91BsAHe^=qI?42F?O9l#SokF4nRkF2n^O!egfzy zUjf^S@)tly`3%6L{087r-UH@o%7XwNYqr3~y zQ62{9C@%wel&1mDi}E&rM|m6=73FmRkMY^g946&^uz%-$fR6G(@cqz~CjvUk8vz~V zk+4`#c_qN3JQHkd$~yrb<)HwN@=}1u`0H>n^Xj}|_PEHr5sa*-JQmPVo(t$G?*(*} z2Ln3Fivb?x$zar!Hv>G%qX8b})xf?w#+2cqCgt0(SHJ9UFmm~nhXXpw(*Ygj?SPK* zco=-1@_K+rc|O3SydQjAPut{t2T)!R@F-7+eRJw%gOPQVKLmWrF9JU08!=f&`A5K~ zd?eseeiHB~UkUC%x`JJan^7cp`AIa+@d43qrmdl0wKmRumkmL#a<9FU5$s;6rg(T0AZ3ziSi*qNBNPUqkKu=QT`<6Daxk= z9_3d8kMb>n$9V4aGK2Ck8LiF)n~cn-{7leM{w79E`JAAm{7%qOz9-C^QvN6KC?6Df zlpo4sKIMx7kFi*HWl$a|>-M1%CL@knjnj`X_RF~}k@8?!&vyElj9fnD$AXUXXF*5#w9qanzm`p>HRao4RFr=UJj%xf z9_8o4bD(@(;8FfA@EE75l&08^4!9pwvyj`D|r_rZyyq$s}_ zc$9ApJjy=?9^>G$y9}`@KN)nCx6I_FCKK1C(mFV<;{bR^5}s_dG+|XqC9)xQQkf9C=VZaj9aH) zv?xEH{X0(|bd7|Dfb2lzfGfzfkfSN`6DhcPRM}B_AT=z776%66HzEU$#^@BbP7v6D7Z*d zi;|B~@-s@lM#CvBPg3$rO1??SKPmYr zB|jzO$%Y3ku_b?{ppqYyF>6EtTWrZ6D)~hv->Bptm3*XvlBZPimP#H|$!jWk zP8k=k2)4zRJgAZm$lytb0(R`T9T9$d+bD|vDm zk6ub?bN<{tl*?H1=t^E)$-66gcqK2d69JAN=)^2hxr%eqJaEKNuYy5Dwn4L(cc<_~MyR|6Xiy z>N{iI^H~kC9~MuE-+7$g`CeT=(`i3%)G>Uo_8#lBudT89!7DT(Im-916UV47PVz#% zD^tt)K4t9cz1|QzyqW=BmzV?0)4O&%?cY2-1GIh_7t+2{e_#am8)vef@N zcuT%J{SD)%qRJF|Sd`NrJ-v&#`1){rr~i8N*7U`yufMs7}j+{bMbbkBb}&#U#=HQ-Hs zT^YQy>zbqdVyWtY$LKRO$Q1j^aFnld?)w+IDMO1vw`*m0=$d=?;_Fp{pVs!b+4dNe zol$#q$O3-t)dRq<(Qj)6pJ%kjhnUNkcd_SIm}M~Xao2|>pt~1)#~@R0?T!0PiAZ~} zts-|c2Cvh&8sKg3HV?e=SDbNc=AQ}RF>dNz$lM+gX_spC%3x&ullyI;i!bH}UB_#v zC%W6)U(iMEECAlB5xv37lWPk4vsL3`Op@ydc5X(Bqn6vO7m&$Zy(P6>W1}aKj|aP> z9_tCClUro!rnx&pcf4pB=(;U9&Bs+t8|QiKEHnb!e~*lS;|gzn8Z=Q;SS-2z?1po-94yNC9t#%DFaTYYPY&A(%| z{s5j^4a_^~;MzS=KI68}qYbg|W%bANOWqy*fvWh{ll6MlsSGH;`cCv8>esb@_Hk}hrsXAG6MWB@6eCxWnS*!e@+)?^6xRO`<&6Lv(?4?(bd~zxvNk$V~2xs!Nh9cuPVDfLCkG zaWS+|CeSgR5H{)zq~iSABI|te0)Lg0*8j(iMw;;A?(R;Z&_WGs zo8a#54#nMDU~qSLI}Sfwj%yQ~!w+|Nceiim$?o^p^PA*(_RX8kZZ^BKGp>{)`2AEm zH|TJBJIA2ZKsnxHdViGvJhT(qQ;!o}g|BLr^n>nT$5)o{Hub~vuDZ;rA-39jqbYcm zcUA=NU8(ip3I6lK*EM!~9baI0+rOY|TB`zdQ+_vtZsDu)&|S^#wWqk%-+^~?ULo+( zt;YN!UH(yCt`9gieu!)A5wFl6kk90dwp>@yGRdKPQ4ReE&G>Kx?P=@O2suyj_6CEu z{rq)D_*r*)?Wb(!0b-M2;}=C-V{fk30J_E*YCsn!M5&b^?EoAR^FGb(3iZ{e$L2XaCeJ|Z4? zCzj&5RU7|FYRUNyZ`y)4=T#_pf?slea*Q4C!N05Y z$BzW>PD=2o`h^SNt?yMFyvg@EfG0@9mN^ACJPe6y<-95vQ3brK$yb6`{jFCYOCxuI zH)C8`@Z$TmboZs&;Rv#fX1ogme`7zq_h|aVap;17dGi_nW%lY}eAiKql-v4F zUGR3St_9xTC8x@9m1dOJZUirX3=B7R%jjd!EnON4otxjAe~EmW7`p9ahq$7j`7oX! zrH=6Cb2{F@xJEU6n-Syd6{UNDCpfpk5X;#8GUbKt)X7-3==}yp3aa1dvsr?zp0tK; z^(70uM$f$Ys3Hfwc9X2_Jn*jmR~}zj8x3pt0 zbcgnN->1>l4$AXFg^LWb1>derE~pm!Wdu*~N^~lFdCLB7ktKB;LE(L?Umf+3Wl%Th zGQTba-O8x9j_9ie<2k2>(G|s}8V8$!7rL+lc!6U!fhQO_($_x0`|G+Cd%9Op_{TD0 z-yOy8S`oUHnV?s-|E&gH{PtcudQ|K+%3pl1FnIaCc18JpAGDV1Q-Y;F1>5O*_IF3* zsA&nx@e+A62vUL_DWIEwb0Bnwk|6KA`dFeZ$9nDMP3@jyE5R1U zi`uKoG<09LK4J;V@#%?CKlJv}0_Z0F=e3`n;~eM=F5GH^U%e{oow_{D4St3lkv11Y zeYPk;CHQiGgxF)9Id~ryW(hqCL&7)Can=9dbbT_-A}MuX2~gb4wG? z#B+rIDhAIrJ%}j=$NzLPAgD#GRenB1DdawAd9lD1qe$CdTftB35xw}Y2pT{-X;*1&s92_`AF%X)pblruhn^Q<$9 zu0{;rduq+uPtfh%SP;5;OS+@{(5qQce>)5HbA?}SQD#9}m?bHA*`A{RP=cen6|}bY zydIuCAlMcZ{{B84p{q8r7<3nWFI%F2^WJMuvl5foYW|IS;Qd%y6TEY?W`LJ(iPwGv zyB5n4(_+jKYfW+=TTpcCPK7~Nq7lX+)b2tm=zQ-EvH3Lp6A@QXO*)VZyk3|bj5?fGoEo;Pq?n$mlK`Qtny(2g~8sjV)y&)VtM)11l z^S+-W{_?K-SK`^Yo{QIOK!1LAeeeWFemrIwdsN0q{GTQlz5DWIIQ(JASs4P|;8^Il z)#<>qxUY2=dH4OAe==LHCwO)y@E%U_>PhfMqlT8T7j-R)di;{htJkY5eW6=E?F0VL z!#Cb@aQ}`iwyL(Kxtv$$qsoKV=F}GO@_F$qlwin|E1||td}l2L=;kl0 z3tf?w-gEpq`wQ@@7xD+MLsj(K)b?1ETpvZh@ZK|m<62j7j2*Q%oh#QU8tk z*}g-~TFz7N-mSoUeX1aM1>$=BP?x5^z#H5pKX`%*cPDcFi}rNu z79C*;O8GU$Y(l>_{!$-X>_iE&3)06y385Q$Z!mbv4*o=a?H}JBysr~Wf|sKD8Aten z&3Nu|dd=Z(mhcAQf>K`NcH`x|%G#+8bWQRCDSgEW&}D4|9-ZrV8oZC!QLb8D55GhI z>`>qdRy-NxzWYAdEftp45#(a2MLJxk8rKfjtpc{Pr<`_spgas(G0X4 z9jq0C|No%=HA}85{&BB8`PUvSHdVcZ{*2DdLI0-wU!cEJg?4!D=XbS(;0d-K@8kCS z7VZxC_|6d&{qNCjQ2w--j3|Fq2|OpN&Xd^qAL+B^0dLV(Z(RMsZwl6d*7ocz=T+5+ zT;K^l*_hOAc`~j$>TPDAl)w7e5Yek~u~RyN8K<^|F4wRy==@q9mE$yfF4~1Eylpyo z%^%bRZ{Wgu;0eBqb<%14ik#FPinxNJ8}MtGD_E+*CFpkCC7T{J^CH; ziBnQ+S~I={cxhXd1FwIY9pLr(?6n`k>>Wa*s}BFe>b|^?D=4~hiz-9+r9uAa($|Qg!ldVrDj^;lVI52X5?x(uAvyIs5PQJ$A?Ri=SJi+uAZaK!j9km>~ zK`&5$lqta;=>GUw2D(>sT0&>A$Cjetm#BmH9X+o79sIx;AMm?Q>jA#tk71)6WBa#z z7%kT~uWesfu+^Vg1y#FuiJ-eRd@yu*AHGJtU8~&zysHgLfY(0ioF)81g}wR^%=4*J zjInpd9V6!{L8rRVRnAo#y7en3L$|)a*PdFHIRRePOr^;ccm-;U;X(m0_6!FYPY~LcIq_2a-5n* z-E;)gEb-b?`1n3ztG=fiKv!fU>VpoKMg35|f4%loBjrBue&j`cD#3Eu-&)2_w*~c2 zPyfh)^0QBgl_ot99N9E&Yh9obuVu;1=rL4SuOnT+$D7d)x(;j z!4s^Pwuo))iFv)}^R>@;=!T{(0o}?W9iXf675*@4ZUwb zuZG)leom1U;0b1kSJ*zixr&=7{I(@1=Sw$k4BeE9t)c6Y&U-&Ec=Qmup1X>IH|#-Y z@ZOeRh<0J$9$>SaHs4Jxs04TQOlud5oz^{hI}K2dKPU9tbh`XBdG07n-!9N~+EoO) zANq$|DKvyv{`fGJ6&ONywszmyZa$b$iUL3p<>n~bt(m(ONdWiaCgxE^Zu3yA9 zcCQZgpo_^;3%VIUr$Og813DU!JjWrVKC$$o;$;KV<|Q6D$Xdi`Ql=|bQKWqEIj zE-;nXj|y(ObS>Q2J93tj^J-aWbK$F6alL+dt-Tq#qrbd*{M39Mc&&eX{rb#hO;LW6 zwza^^J_hBJ;P`sSV!F?LX$_p1(-xF+Z%*?=`D2!Jg)U%LPq|*2y|uqBn7m_pK{a+j zO7I%3^xjj4_H32=K>h#f1fF2MeDj>p3xRgk&9Q7j(fO^o;|ON#j{8iVW4ek>DGzw> z%^XqHz?(R45qN2?di_}4bJ5_1*C>th1p~^zc7|VRW#7NO*%Fj;n@!9Q-J)A~PSl!X zzoDytEFW}@B71`ODcLNH3;brG-&Q>~Wq0K|79UOkp5TDhnOxtLL+lsDvsi*set>Um zOE6x+_QF>yvzCHxo@@1S_>~5@YO~ z>?0%Prmb2Mx-8rAJJj*YH`K$|Q{Fgi>c0tX;k}E_242|@_#f1z^51wL%}S2{NrI;~ zj&O|qZfkz%zU}(yh<-&{^gC3bOd+wUZ#mpYTAIELczG7=1@G}aul;V=% z63kNNreo|65sjcrnLYx#(N(?nRP)F^=&pSUfUdb;XYkqwu9fFTWvGwmNd4I-l`G|D z?vV~W!IwU1Tx0(ie*knv>W`57q3nEkPE}|xf9S3Zd~S*U-d|oj`jVo)*y_LEP2{{P z?N$OWf0i}i3688)$TfD*53gQ+4c!V|@6zR=`)~>EjuP~=pks8nII4TkyMJ$jKZ>nZ zHTSgzTU9{6O^GM@qFo4nOT+P)`}A|WG;HJuGK~h_&V=%7+(`=EuC0Rv>2MDC!_d_$ z=(j1}L+?A4E?&WPmAU1;2YZf*!u1F?T2;iY-@3k=t^ILFP|DexrY6eY-*6Umf2{MK z&(h})L06_*ICxK=wDEWY(}6cDMWoGom1}7nK@yzWCyV>%pxo}&}XVc@lR?)4{gE?x$&Y~^AofAgY_;Kd$wC8k)3 zU{_GeO?DprH8t##)RpT9uALeD7nS;fA8&6idA=xYNOw6;1>P3~Z++oUmheMPVw^)s z%7=*!te-E?HFjwB7SL^cSPr_FvD=^<=lQ>oPs%@`>zSdl$J^;WpLI(#1aI^Hp|o8`4f!NrqeyT-12@V+DZw57cEd*pR{u~oJmUi)6zwJORV@N6k~A3gsUNy0{{!X!&gz5z{o=a!o%-a(ar9@4b7GuB zYioG@-5EO(cpv^6jPeCnCCTa39{4Fd&hsEwP_Do8JFowo@}z_-*B|%Wf0p3oFt42( z9J^$!9H(rry?(mZ;@aSsN-_!jnGs&Q5iGf`LinY_C#@%0^1Fhf8!*&+4_trJ4!SZ; z<3eZo50UFrmuqtAai2UbiyzZ)i7p zd)N^a{<(YIp_>)uwWC_AZbO&9WDv^l+t+)qU&^*io*(*k*n98aiplg04|ZZ(KC`eKVB*scHr2n&$V~)70GWz^k{e5X#TI zxEpwP`&E?dQ;k2O{R1m5u4@^)%;1c+T#s8nIdnxUqW@6EO2Yp|{XIWI&Z{Qtg24;= zb=?uZv(0Ni51jsDtF4V2fG2pQ!M~QV%O>*1qecIk3tdXrd*7~|zaP3A^DO8pq-%rn zzqQH=-rx>+9_T?fZ+u+%tT$d3%vT|aZR}KSyz%tC&au#*hQ{=E<@(xg@xE7U&xwcf ze=WfCN_|=;wd8!|?`^?bcq>#;)ktwnjsx>=%5R??KiuAR%0EVs57X#ZQ=wbX!~0&? zoX-1xn7(r)bazvOr-rS&0A89A#Zi91l@2IBq~jyhgW#rg!S<$7gYERo^I3xOyPMx9 z#_zDB4RrhVp_(W_Do(#Uxg{Wtn^T6$}a+!u1Q zp}!~p+C{+=Y~3-Az5m`L>(zl=K+z?RI}GJ_&e75m-GWt(g-_9qt3Wq2bfp|u$36cS zwYt_W@NUd43ts(PEx{{MD;PY%$`OIKv1bm7vPB=Y>nn5{dwBBz>r3{4Zg=}wsK>k; z`hpkxMHWG7y(h7pr$bc-gI8}aq3WSwygJV9EJ-!}HLze1sVkfj}T|5Qu@-GoU)T=|_* zXX6Q~PJ?rTxA_9bH58d5O_-eDSGgB>?Gxk$PcUD;B(|~B-Hip^p+1pfmi0-T*wozOnzc+>QOL+CPfef}&fn0rjl@ z9C`z~S_6ZjJG?6bx@-v!p&s4@53+?HF)g_ujVqlIyt9e=gD3d;Mjh+(jjAyfysF7wTf+bJzOXA8_l@@+Y2Li8{69L> z-+RvpF1uaBDVZvReW`Y8TTu9PGzD}!FMIE;YPI*s|D($dI-&e=U4y`@nAdyn1&v0( zP2E2B!1au(>AfcflU6w5H2G1@z7YGmB`D>ekK?^(d!8MR-`Us9fi7Ubjq=}H-g~-X z#XNFcwb>I1UY5n)d)@Kz-t*TF_e6PuYkm#2j6JY$Z;TWCYW0DxW4#=L^e~k-t|%Oi zep{976A$-k)4$$0Y>3h^wT6b`*cpn*sUYI@!H#T*`V804E;8x zaL?m?H0%KSYwAss&orLp6E&rF})9lD-%vZ4Nt1oi`O#Q4mDs#=kx za$YUIKM1_>JFdz9C&9;o!S3&7*&<+s`UKAqks4tRp4CTDSt-7s6E99OBP zrFR539&ID#s$Gl11?fTULvox-ZSvat+nck%`|l~nacbAN`rz&F8wsA^s?9}QW6!

    }`OejX2V=7o;Ym*Z`yhjv?~Ke!z2+vYuy&?l;w6}%b+ z5`ZUIdT2)f=DVSO^%0pJK{-x~CJM)?+PWijNB=AZ-R-5Pah^RI>GSq8`~u$NV)ekA z(HuxSri}+ru=&Oyzk1zKe$9}EF@kb_@p7DjuE;`^tMZJ*aj5IaZ}ObcyazZBO414E zsU~K`d8;&M@H=SqtPSXorj^wFlVGuwqdjZSZHnul%8vQw$nS}(@Z3?Beg(v)r^DOe zJZc;-E2x47>;tdHO|ImV`CH6HIgDx@Ya``I|u3`&L)zzBJM8OWD`|Lf5ob zFmyY==>ELP^^K?(%_DXHe>7!ESI%SlskGn;mVKYfw|24n15y5xdQoyc)cOWJgs+kY z1VOj8>Qj$R`nqHUc*85y7h83SXb#?-fmOg8^>HnDg5^RB`POdvRo{o=%eO-JaAHO1 zS}be{UE_$d(2aeA_L{16egj_nodvXMVN2xtFzEvQ`^xQeL1gT z<Ub2i#*nl$*VTn}25xQpzk0yDzEo4(3~S#Wyu&f! zf+X0Ob4tZ*J?a%pkk1#C?N=A#KByg?r$cvZQ*G$lpJ@Ocqc6N%CDBh&@^|{WWK);% zJ5DS>Kc_}_MZZUaIX*7-t`xi;(WpqMFDUv&&-8VF7(WThkMnDQl&eC;kB;kKj*5B@>8E!3SOqix}Es#H;ngG;C_t%RI9_S!4qsXf4gVx$-Guc%6H1? zcIfgOj3-snLHTfAw5>OEgO*)IyVkT)e^>ZNUt|_kDOV;0@765cE((sRo5QpAwX?5q z|K8;71YPF2C83Ksd(IR6`Vf5|B7ettnpy_e2QNX>y5KGQZz6cZ`{?IUaQ@)35$T`( z>E(^c>kD!*^!Ze2=z?~1fbLr1c+jP-qM!eVkK*~lD>Wn=c%R%z@LqK7gnp>uCEYIx zo*zBJITk06UvX+8Ur=<%4=d>Y+!6)d$VoXJ-mX?OYAgHs9~ZnVJ3QG=tIz2Ao@@i& zf7Fo-HNg|ybLyINAhfZ6Zun78Q26~f^?}a$Mc1RrXZ}I?X(xw3m!dq{YYIOGKNuQ% z2hR~rS(e8o``~o&C9p_#a7GaHv&)apA*L%YyW-__lIIloeN#D z!@3^%-hSvB+;^bMaRc|8z7@?1-t4F-SB~@39{qkgrciG11WzPS>{^>jqP?b~7qX%r zWx9*@n)Wr!E_$`};}6jNJsQs|m6?>tlXB-3!}ClFr<4J2$%EsvT?w|Cl-K>gJsS6c z#w3{n-Jl(Hgii@BpgyTM^Wp!Zj%Ef=wYqQtyaX3YfLDDL>ZfX)^fB&(V0e;HcR-_| z{>B!$9YHznxoL?6sXB}6>rvS4<&azM#~u>~FU#HOeo$U=Vn> zLuSbJAh#CUcRKS4?Y$D*vNVpndFKPK_Tn5s(bs*e>(74;T6&@@cDt#ROW%@LL;3Rp zR?2pj>y5q-+xqVUuk@Yr;2pS+{z?hv@OL^LvljOzHVt+KMfZFn`aAXh;RonKkL8DM zM6%u}Kbw~T_m5G2pUQGZ-=CFJGJzM8DY4I+>0uFlKLcLe1z)gx#!%PV_n+$Lp=?|I zd}RFo7mjx$nLh6+&40xC)GXQn$BorMKW}%cVt$)eP6UsB-}47}f~9`X>soutw=&R; zzK8J$-OrE|<{`29 z<=7~HX3Ho+dcHc7Be=OxJK;H!CS6;Iz<*ys7+oMNYj^RG6uBY3prGdKrO0rb9XX_pe5WW&T znyG>F=hzA{4dREng0em7ueyEg{Bt4vjv)hIdAyk#Wz+3x_>78TtJ#TL%6`?NtZsk3 zDZheO&9u*gXD2r;Gd0-;ui~qMuAuO<9MpRcCN1Ky5Pcpg-P;<`VdK3ezhg5N46@_$*>$Ddbxlp`qR&!|2Q?OMWt zk*?V8`>cX=Y+!uZPi1rCc~!HQ#_?o-&UU)u@1dG1JG&MQuz zJK*KrRSZ1Akpp7;*3Q$g8+6YqtVX?vE;AUq6#G*O(yAP3p*x%%?YUZ5VXQo7>eF|$ z_bT(B+ZyPyYCi=U z6SN(?H*qS0NAX&Lm*Q(Uc!I^U1^bIH40j96z7r$J#Zk6vZ=q|Ft{`-)yY_;v-GGNFFJ*3NFGe2YCn*&dp&ICM`6Uhza9 z{{gNqm3%cqY}!+(A$VhI)CRBbiW%T}tMv2viH?9LSSKu>f46Xi8(jR2Cn)-CY0+M* zigD6Fm-(xH{x3X>+T7 zT_zy!rk3%dp!+E%jU)U7-_c&HIW;4o%Ux{cYX8l%gxpWsg@Jx)FyvLsxvxMcjwKqtRZ|_dQ8mIggY-1b`R2Bid`) zvmhVtgJAQtVZOEFHR&aMqEZE+n>6mNC;BhfbUjM`TZGtT(R+q=n~LYG2!6#&+rZ!a zS=XP!2iJfv*rs_Q-`bn5>v@zM51K)j<&TEY71=eym*bVq{RFxVGlFD4ElY)VTRr&m zM>%hGI`ts%ZdXYwNP?}(r1q`ddVWgio>f7+tqSj3BiBV8DccRYIG6SN>ZX7@j_6ZW z!gW;}T6Y#(wI1CBypYw^QNG}f5jVVHC6+inS{3#MMOXcaqg17c!UhwvQ?G2t_+$W>G7X|$ASw+HpK`B3V9E^YH=G-iXee~i?LXo^M*PuH_S3uqrNGNt`>ZGY_!aei5IjG)MNFm!Y2k)&1 z-I?>c{f^gIx992FL8t0Q>h}M6xb6?ur^a#Ay}PkdeyIRme*~j<1vonw$M>`C&gctD z`OVH}Mfusr>i(xn;mPQa-b~c})1cM5|C*Cj_h*GJMdADxpZ#A?*B#$Q@w7K|0wNHQ z-b)BAL_$yQ0@9@lfzX>EO7D;etRkWyMMAGqr3fO3)ZEdfNbiC{1VoB}ApM8F^E~Ig ze?6bM@AGV~?cVO}%p~~UwYbmwXn+e>eCtG1jPq*_zwZIj{*j2_dpYoY(4T&ZozMHb zdQR|t9k8kmc{7Ig#c|tcFrTxX+2mL9ZajVyznhcug6}!-YPZ>*+9x76;k~hS*7H5G ztD9%%`4#)(4eAn>4`cfuE$hqY@W;2o{Gv|3V7_ta)}Opj)5h?Am>(@F!G32xy!aM*4f6*51{it#VyxQj z4+itCp*_m6{pWsPpjkg74(DqgT;zBFzQpS(vy0xKPJZf^w@UJHez*Il0h*(qm7uQcM+3>*w(m6efrc*PxNR3aFG}94 zy6MRSCa2_g!`CIcQ*(xSK(rTs`ZWi*@pyOe?dZZW)D`P~5XVj5DM5daSvHlt9@UzY zceQaV@+SQI5qZF$-i~xngpPF+<|f7hq5r1!S?YSZ)u>Aj;ka#{jk<>S%oHd!ioA_= zvH)$|`vu4w^2-pQ`Fed8J_lgUVpZI-ull*Ari^!h_&xb{u%6m9D_CDGO6It27M%~) zU-gf7B5!-hTR^+EK(KyG`#9+DM~4LKJK%s_vJd&Np}X_TUmYOYulO>7x?Br7c+hvg zAH3IdGW`MDEV>X$UR2i)$ZNlI8qU|wo6Par9=jCggI7IM7&@ zK8548SyZ*4i}Q(jKa{!xT{&KxHskK_`6W*6iQmnEN7cw%Jv#7bd{Z=d4o@D9^YAMQ)IB~HtXFewoD7~_KPKo$d7Z=53GzCo^{<7$Z|XMa0kl7y%#7o<0C+XG(dl;2f5Q>CE4*hfMCxiYIP=h@ZD1pRA4^ODp(m>RFb~V7w^c4k7Q+l3+YZ z3jc+?kE4U}W@~CN9s!GeHP@MzZ+FW0e$g%v?Vl+Wj9(Lf3C6Qif9GNQ|CSua^Ln|n z1>Q50u~T0k*tJA?peN}Y*qa_P*ev3@1`HY`X7EC{@%2qWw?T^L$KVE}ozL z_QQ_s7th=C{B8M8ydE=q)az`&>irQskJ8Q#T)(YTv9}9cxV|#b09WM+an(MOnCjtp z+!WqlJGjR{*!EfeHq=E_;qx$WwU|rZsiVRBIV994@6gA5zV_|DeBK7Q;obF)+DlFq zqprf&NjNVv%hpzDbvHO1?!1L<1q8;8Z<5wC?UdDw*$opeA-%tCb1>aW#?074W zqxP_y864~sj@#LT$Flu04Zk4oo0t}Cze>}0$eYz=JbCvb$+N&i zzx7H{dq(L~)QuTlow_@(iM>3X=D~Rzt`;_t6#hn^9l& zcX2+z-{Qu3YA>4`j^pOq(w834ZN%}~hCGdgZ6nrorcRLU-A%0xG^h z;wxUq(hR|T6*zuzs<$F*f`5D99tQ|rzkc0$J)f55_-V@B4)$jf3r4a1Cu=y~np|ra zv0n^NH^PPPX}_F6+j3Yg@_=_&g!${*5BGZ)spkN}%bGe7@10q*mgB!!(wyG|`>^dT zUQg`#V4l)@X98?XapLR?`w%_~0a`J$iXO{D$WS=WMN9CPBq1(1QHc^+D#P65M zHi+Ld+h}JE>N0N(?qBn!PszJ5B7*Ht*~0Imoi#8I`vq`x!7BdnH-`H6r?vNhXy2aB z50rn<#P6^C|Ampz+hR+8;q!jcDp+Uj*-@3e4QtLh;5T@|`)T8nEo}SX`&MiZczCBknj5^IBQyR;-IIke)Ri5{`G>i-Gdp>?P6zLQ(dFq}w0~?;G4g;n zW@q)){-?_zw!flDAIyKuqTL*?&9SG&soRx3Ep^i)gZ}tI+Pofkaq~I9GQa;EOWv!c zdvV+XS0#n}YG3;<=>J8g&!FzycTK@JMR&HQE+s=Ebu*3yfgoZ?mom{2rGZZlG>o5C>y>zO#zDoCyucdllcF?K_iN zk~e)$@I5HE;4XQX4&q_#t|L3hYq=(lyvxa5$OBHFvcVg+rHof>&zn9Fx*wkMJ+U{> z{6pQb=+e|RYs7Ke-rTsH<6HPHj@$MNr?8K|UoAEhd58ZB#z$a#ub}tn(Z8`nq!t+v z?ceJCF8FrljvCb6KYYxAeoHI%3;W)k&tTh8ZcFkqHYJ*D9*>(e?~rHy_xPA|c3&wU z2!4;XY|nl+gzcNi8vJ`^<6WMQDc+LjXS0^)`P#)l2H%~{%f9A!=s{fYUD{Ni*K2`s zM>G3s=l+KG!=}FE{V|PmMezRg{HzPF`}j8AU;At^@3)LIyf3!f$l$x*{U5$hX2q|3 z&&-M|!*D(p`1!AmJhd-e9L4*8wA!w2HJ^0nbOVZ)|z+%OGya$GSfxjD|5 z=^s@gFXAl6A$#FO&|gBjbDT1nzHN=)i4oo*=YrqVU9s-G2Soe1dvct!J2wR1pHas+ zE}DWzVyP4Kq3^u18_>2{nTPLRhH^>NKPj1(yj3@flLw4Hp2b~oXrLcoVYml`E@Xcz z?hBPp7(`vRMa8Hy)6!9Q@O&b9ujkK!_rON=>rP(kx)|~bTt2|}1Gp_D+?_OUtiQT( zu@oTq$u+*DZqN2+)Ro=Sin@(GEp_Fe1^4Csv**Zbu(m3BZs%U)y}EH3@0kHktPt(y z{d=T;?{*mnh~v?JX93#1yYf>vxlr)jj{T9B&+*jy;JGG#9zkBdl20A*f7%?p2j}zF zgl*iOo!B0*|Nk~SYOkI67IpQeZlZ4Tv!LHUNwd40d=v(C$eAEZ#~?_`F;3VE}&V{J|}g{LW6#`tJh-O58H0Z z`{a$N5Jg_jUDrMEfyGM}chzni5%l9~hq~i;o8BZ)mpgZ3>JC0xOx@<&!8mbp;#Tq| zAFoZ`zO9|fYdDYdLIb@0#hb3$arHj*@pn^?a2{zdP6(&&)vEr~g@1XOo~d|tr&Pb#~EqI&vm5|=nYw14c=>eQ`ydD4OYXjJeV(og0* z+8lD~26*tT(r%8_ntrnX)B&RXzN>mrS7svT^)_RZ zL>GVO*4Yd|vt(is@;X%?OkTuC0j#*dg^kO=+gwMo=X zi!9Fj`?PCUv}=1#cY#I_zng=p9vVS5!;q*C|u!phW@t=^lujUR94eQtMa1bJbTUkBQ##(Bv5wj2G523UJ> zGiTx7ol>$qi*|u%ziXDh)Lr+>Q!b1MZz%)>XU2)_T;HUQ4}wIh1iQwrVZ5Zx=`W6||p&f8S*9#q+VR>NaP; zs8%@ei|)>tm*)dqejWeB`}zD#spMVMnI{f)S5J0j`!6OJChz6g zBo}|D*76Xbofcb?ypEMPJ{#b&Q;Ck+nKqY<0sr`&LDY4xQ3uVtVvWOO3XJg*q) z0SCnNAaB-~TI5~MNk5GZw`0izUddb~w#k*r-tZC?T_AK-cQ>bQ{r-2T8+~9Lj@#{p zsk5J~I!#{hYt_iRHn%5vZ4WXI#vW`x$_F2~FMmldztg z^s||UK^%;ox|x1C+vJl*)IA=ZKwi4aUD*DCtUXk-E6qWaoh9@X+&M+2Fs|M5yZpTZyRhTFX>?&wx8}& zC-TxH(f?`>PUSdFe01h+irVM=XVhK4P=>m*={auO9#uoxpBkMT;>(}650eT2&7+FJ z`gB}bj@vf0%60ai*ryz)EpSzx#h%({npdOlS_J*i=0etBT+347V+ZZdiEYL9E7xmI zUiRViZ<|b$gZ?u>Vn@LHG+PXLz|aSeJ+bX~=9+vIAO-i5CD&7#!R zSUHHiF`r%G`n36|V10UXUJ3Hnv`<4G@ZO68zS;#7lBm1cumJDVFIBsNZ@%yCP}i!! z9vrv7?Fjl)Z1^nl##9d0rz@i3$$N5QIC;QU*CYLt+s62r6Q`vBp9 z-IZMTSm28#m%Ma2=6m7W%KJd*=AR43wej&O)GaI=N8JxEy0HBnLrRhN;3VG%`?#3# z(f%jNrO1n$F@U^&wI*_20GwZ?im&#}4}*Eb(d&h&^FGf=ol}JGt99z6b#NZfGrf!7 zZCKNqu&?L;gLuPSfZy#|ty|W@%SU z+al(b2fR^~GZF$({YEj-t^Pp~R@_>6c{^_Z`Jok3$o?Q?6QLT3uQFn4yWAIIm zDQ&6yJ54Y0+SCd9&BeOc$jf~oioD^C-zN`PDQ>2x_LP4a|6bJw z4@A3n!^={4u1i0*Ke>2mK0nimK>$8XBhUwe#9Q#ev?Y;230p`lQ z&{^|FRrl?K|9C*?lH)IUz>C*;e@*7uqhXuhs<);tIkp*jpB|r1-pdt1znK!hpFA%n zmOS9}LVr8CL%X{r%B=B#Xt!tAT-2q61pR2$&uM+MpR-PJ>Y{USUSsd&2wxAr*!bPb z@8k)eJkbL!Fd-?Mr?#~3;JExf>f}7Alk>xIBj-zp(C4m^|s% zu&wlS@}%FBC*uHlzUsFQJqIvIDUlW~YV8JEbDaf&<{ zx5$%mjPq$=WMmar#y5A~_8txp?aR0av@#A-C*ve_GH&wu$v8@$jH~3yIO~Bg<1TqJ z4#PIUAC6UYWqfv*?LO`Raa_i2>SP?JPR4oYtc?5A$#;M}`7V$r--)38B8lY5cLZpF z5B+?ud|%uZ`LYplT)sQh$#;nJYxz!5C*LjVjbuhhwRmpb_lQzzeL@Qi$?$&>FkdGZ}6PrmDTPYm$%XVI?O z^4+IS<^w>?52%xQ19dWw;B!!v`33nh-ymP+A0BivA0c1nC$J6h(kD@_+A@EkPUbVz z$vlTTng2j%Wj;im%#X;E`4V|De6~iacPGIYnHxW&TB-%*Uvcc^b~!%KVKw zna=?wA21tvGT$Rl=6|>^R_24`$^4K!;JCWRRa@qd4)ijgq)z6Uu&vBLsgwCAbuvFC zPv)!O8JWM5C-YhIWPVE?Ftp7#j?8jwc``pI4|uFqm?QIcujAOtE)Y7I&r>J!d+KEVkK1Jud-fIL|*kSFU0 z@?lZ!;S>l>hv^$vNm{vl7+ zLwpXhJ|YiTZoqg?)=mDY8kt-mbh4gufU>@#PS#(rt*pnWll2*SvR)%k)^Fs=dX79< z-;pQlJ@SADhV63Hmh~WYvOa{)$hwg_Sx-_Y>r3iny@~TRvi>Ab)}ufx>s0b&-AW#? z{DL?~ZCTgiei&KjQYY(Q>SSH)K`-lM>SWyv+sHbaJXu$hC+lqTWZey(1zt)!W~bV+ zE~ie`>D0;kojO_9Qzz?u>J(-DPrmpA$QSncfhvd{~!;zaobT(ZSjv#C;k%Z#E$}<5&sHx z;%}i&{4eB*KZZQ<&yXkn8lV;b4SB#0t>ypE+!^FQ%G=KYqCN5VaGovxAL_(EM4kAH zs1yGYdE!sCZ&4@yF6zYp z1)ddu7Q7xX(6-|hi%T>OR9iT{u~@h?&*{zmG=|45$r zBgqs0BzfYm1kZ^7l05Ne`ptHw_kn0v{G8;A-;@1F{GsHFpA=}tZ%Ur{QOOg(D*KK2 zS;-T>D|zCF^}q+7t6aiYTl}=tiQg8#8}a8-Cw^Y)#P3U;_<_N*;uj`Q{l)4(R(~=u z`Qe+s+UjqH9~$kee_H+3>c3Whw)(f#->v>{^@jt~uBq&+t^RWLpR0de{q5?17vyz_ zU!K<`etMu0zdf%<{P;XS@#~WZ^ct7))fT@$b+QjYo$L?rKFhuVb+V5Dw6d>2p6oM_ zC;JYZ*U3Hvd9p7-9&m5w%)abbIA@L)B0?|w7}UwWhJ*8yeGlqnAA~yD7r}8W`y}Ma zz6p7SW)BI@!mePWE-!A7r10JlXdF z8rcUTPxgh#15W5t&y)S4l&PnpeIVMEeI)8+Ux_-|ck-Z@eJJW=UkbLBeJb)~--a6^{A8mKHLu@`+(HRz94zBPw0Rz`-bGnJ|b)* z`-SQ02I@#BxPWCy;lYLL}WFHi0WM7m#*(W6r zczf?4Pi@&pgvved~wtp}d$+mfgIxw^lr`@O)Fwd8A z59|K1?kDU1vhFwQ{;AOvR|C6`tl+4v``Nm`t^41)AFli3in?#E`{=r_uKVn| z?+(nBW~+n!_)Mk$@N{2Z_vv-tUibBNpI`U=H4Z@I0yIuQ;|75DZ>4h)Pta|~6i?#{ zG|oWd4m2)7;}kS*LE{)Su0i7*H0}XdYjtrK@emD5El<(72#u4_xCxD`&^QZ?yU;ic zjmywD4UO9XcJtqK5zmqC#J{l`*P(G98uy`bAsQ#5aU&W>qH!e}XQFW@zzL@+yNE~W zIDMI;aVZ+7qH!x4&!X`y8thL`ypG22 zXgrU`_h`J2#{U3gqYAldYkZK#3u!!&#usV4k;WfsJd(yIX}prgF9H7;TFF&gLec015e^3$&+|V@+5u|$F0Ouk_SA{ zx_GR_S$czyS8##QN&F>s5|2rp#A{L~@te?DiRUCw;ycNccu(>q{*%u^;z7xi_)s9? zMEzoi^SJ+SpUzL6#FJ7dai)9@5`Rja#G_It@u?2<60b_0#IM4(63LgBYCl*^Rp7)OrFF$lc#ae8W*i`(!i=YpQIpuI{mpquEtSoT(!noYaF)5Wow+a z#%*gHx5jmAoHy_zsiBJa@BQ&F9gPFmxNwaV*En*GD;MN-NxV7FU*gYsJra-Zf{0AzJBUS9J_nt+6o5j%1z-9Q)W$pFGJ2AW!lG$dh~l z@_?(#Rq`c|z|HZ~+!P@6l3zfbG&D5#VC3fNZiEvS?H3-Tl%Bj5%8L?ihcVPRReZH2KZrWX7otw`hp3bM zBI+dH$b(MukI0jJB=R&*N%NL8j|mu7rlODhrcB?S_B78)^PV&hO7o;NZ%Xs1G_OkY ztTgXR^RR$rhUfK>pY?La>qMNN=51*nm*#nC-q-)*fB9gVAEx< zV>N$P^Jz7|cItomwwiyd`M8>&3+(@RYAo`0m+md$YyPh0^J;#t=KpFwu;vGAzOd#G zOI|U@G08LLH~_5u`{$12AN#RiW$=OMZ<3eHaYyo$IUYzJGsh>%Yo<=}oXL~CXYwQu znmoyiCQtID$pdz(dEJrxY5!`+ogNVFOI|f~l4lK_l{{?fBrlsf&Ck|+ZOz}-d~VI} z)_iZ^+3#|@$OA9fyqc%^;F=$<`Qn;SuKDGfZ?5_0nvbse>6)*u`Rl-I>3)h)Tl3pB z-yM1Iay>@#<27Gi^XE06Ui0fU-(K_YfuZGlJ8ElwzUJ#|KELMoYrenc|7$$}tq-8} z0!j@nvZKosWo24IJiWn8tjzJu0#(0UMBA42OzX#EJSC!zHvwBCf)p8!TL zjdoF&qU@|%j@GBpdKFr~LhD;-y$h{>q4hAdK8DuI(E1s`u??bJ)YZ7+dXCoD(0UtM ze?#kYXuS@t-=Xz9w7!Sd{m?ofzz&&4bc@Qa z+FHK_bzS7Ltk!$c`Y-+ds|Ta?VYFV1){oJ8GFo2-_@Z@XS8c67qxERCUX8bWEc>meCk zwYC0_)&tUdL0UgZ>j`OnA+0y0^@p?`k=7>yCXe(SwY7ec)-%$2M_T_#>mg}%olGaxOUVS6RLEWXB%cbA_SAR+CF=>4!t>2{eoV31^)_cq7zWj#|DG zb)!c7QpVN#QCd$*>q}|dX!_xX# zT0cwcX=!~et+%E1x1=r?zl&0*3-6l+#;-i?N&POr-ft%zAo{b^_2Tz3;oac7D|NuA lle%EkNu4nAq;42_Qb){%PU?yQt<)JKPwI~O_15%u{tvULMaKXD diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index ee86e63da..fbc9c3a10 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -110,7 +110,7 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc" -#include "unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc" + #include "unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc" #if OPENCL_BLOCKS_TEST @@ -139,6 +139,7 @@ DECLARE_string(log_dir); #if EXTRA_TESTS #include "unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc" +#include "unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc" From 36ae812e17487fb4de8c3a9dfb84864ca35a6b98 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 26 Jan 2018 14:09:33 +0100 Subject: [PATCH 91/96] Remove blank line --- src/tests/test_main.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index fbc9c3a10..dff856808 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -110,7 +110,6 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc" - #include "unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc" #if OPENCL_BLOCKS_TEST From 77ab00698c598de0b603962abcfd28b542160a33 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 26 Jan 2018 14:21:24 +0100 Subject: [PATCH 92/96] Add copyright header --- ...ss_l1_ca_pcps_acquisition_gsoc2017_test.cc | 33 ++++++++++++++++++ .../glonass_l1_ca_pcps_acquisition_test.cc | 34 ++++++++++++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc index ec77c5951..47e56df36 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc @@ -1,3 +1,36 @@ +/*! + * \file glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc + * \brief Tests a PCPS acquisition block for Glonass L1 C/A signals + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + #include #include #include diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc index 592350300..7cee76a52 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc @@ -1,3 +1,35 @@ +/*! + * \file glonass_l1_ca_pcps_acquisition_test.cc + * \brief Tests a PCPS acquisition block for Glonass L1 C/A signals + * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com + * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + #include #include #include @@ -181,7 +213,7 @@ TEST_F(GlonassL1CaPcpsAcquisitionTest, ValidationOfResults) }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_threshold(0.0005); + acquisition->set_threshold(0.005); }) << "Failure setting threshold."; ASSERT_NO_THROW( { From 386514390939b0839632a34bf795ae69d25c7e01 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 26 Jan 2018 14:48:44 +0100 Subject: [PATCH 93/96] Replace library by --- ...onass_l1_ca_dll_pll_c_aid_tracking_test.cc | 27 +++++++++---------- .../glonass_l1_ca_dll_pll_tracking_test.cc | 26 +++++++++--------- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc index 9876b63f3..e845b0d22 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc @@ -31,7 +31,7 @@ */ -#include +#include #include #include #include @@ -149,11 +149,11 @@ void GlonassL1CaDllPllCAidTrackingTest::init() config->set_property("Tracking_1G.dll_bw_hz", "0.5"); } + TEST_F(GlonassL1CaDllPllCAidTrackingTest, ValidationOfResults) { - struct timeval tv; - long long int begin = 0; - long long int end = 0; + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds(0); int fs_in = 6625000; int nsamples = fs_in*4e-3*2; @@ -170,15 +170,15 @@ TEST_F(GlonassL1CaDllPllCAidTrackingTest, ValidationOfResults) ASSERT_NO_THROW( { tracking->set_channel(gnss_synchro.Channel_ID); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { tracking->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { tracking->connect(top_block); - }) << "Failure connecting tracking to the top_block." << std::endl; + }) << "Failure connecting tracking to the top_block."; ASSERT_NO_THROW( { gr::analog::sig_source_c::sptr sin_source = gr::analog::sig_source_c::make(fs_in, gr::analog::GR_SIN_WAVE, 1000, 1, gr_complex(0)); @@ -192,18 +192,17 @@ TEST_F(GlonassL1CaDllPllCAidTrackingTest, ValidationOfResults) top_block->connect(valve, 0, tracking->get_left_block(), 0); top_block->connect(tracking->get_right_block(), 0, sink, 0); top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of tracking test." << std::endl; + }) << "Failure connecting the blocks of tracking test."; tracking->start_tracking(); EXPECT_NO_THROW( { - gettimeofday(&tv, NULL); - begin = tv.tv_sec *1000000 + tv.tv_usec; + start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait - gettimeofday(&tv, NULL); - end = tv.tv_sec *1000000 + tv.tv_usec; - }) << "Failure running the top_block." << std::endl; + end = std::chrono::system_clock::now(); + elapsed_seconds = end - start; + }) << "Failure running the top_block."; // TODO: Verify tracking results - std::cout << "Tracked " << nsamples << " samples in " << (end - begin) << " microseconds" << std::endl; + std::cout << "Tracked " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc index 1158f368c..6625fda4f 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc @@ -31,7 +31,7 @@ */ -#include +#include #include #include #include @@ -151,9 +151,8 @@ void GlonassL1CaDllPllTrackingTest::init() TEST_F(GlonassL1CaDllPllTrackingTest, ValidationOfResults) { - struct timeval tv; - long long int begin = 0; - long long int end = 0; + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds(0); int fs_in = 6625000; int nsamples = fs_in*4e-3*2; @@ -170,15 +169,15 @@ TEST_F(GlonassL1CaDllPllTrackingTest, ValidationOfResults) ASSERT_NO_THROW( { tracking->set_channel(gnss_synchro.Channel_ID); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { tracking->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { tracking->connect(top_block); - }) << "Failure connecting tracking to the top_block." << std::endl; + }) << "Failure connecting tracking to the top_block."; ASSERT_NO_THROW( { gr::analog::sig_source_c::sptr sin_source = gr::analog::sig_source_c::make(fs_in, gr::analog::GR_SIN_WAVE, 1000, 1, gr_complex(0)); @@ -192,18 +191,17 @@ TEST_F(GlonassL1CaDllPllTrackingTest, ValidationOfResults) top_block->connect(valve, 0, tracking->get_left_block(), 0); top_block->connect(tracking->get_right_block(), 0, sink, 0); top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of tracking test." << std::endl; + }) << "Failure connecting the blocks of tracking test."; tracking->start_tracking(); EXPECT_NO_THROW( { - gettimeofday(&tv, NULL); - begin = tv.tv_sec *1000000 + tv.tv_usec; + start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait - gettimeofday(&tv, NULL); - end = tv.tv_sec *1000000 + tv.tv_usec; - }) << "Failure running the top_block." << std::endl; + end = std::chrono::system_clock::now(); + elapsed_seconds = end - start; + }) << "Failure running the top_block."; // TODO: Verify tracking results - std::cout << "Tracked " << nsamples << " samples in " << (end - begin) << " microseconds" << std::endl; + std::cout << "Tracked " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } From 1b65cd9f8a76da9b87ef32b2cdd43bc4957b20fa Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 26 Jan 2018 14:52:57 +0100 Subject: [PATCH 94/96] Fix header --- .../glonass_gnav_ephemeris_test.cc | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc b/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc index 7026903e2..9ef819052 100644 --- a/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc +++ b/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc @@ -1,5 +1,5 @@ /*! - * \file code_generation_test.cc + * \file glonass_gnav_ephemeris_test.cc.cc * \note Code added as part of GSoC 2017 program * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com * \see GLONASS ICD @@ -7,7 +7,7 @@ * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -32,7 +32,6 @@ #include -#include #include #include "gnss_signal_processing.h" #include "glonass_gnav_ephemeris.h" @@ -49,19 +48,19 @@ TEST(GlonassGnavEphemerisTest, ComputeGlonassTime) d = d + d2; boost::gregorian::date expected_gdate; - boost::posix_time::time_duration expected_gtime; + boost::posix_time::time_duration expected_gtime; - boost::posix_time::ptime gtime = gnav_eph.compute_GLONASS_time(7560); - expected_gdate = gtime.date(); - expected_gtime = gtime.time_of_day(); + boost::posix_time::ptime gtime = gnav_eph.compute_GLONASS_time(7560); + expected_gdate = gtime.date(); + expected_gtime = gtime.time_of_day(); // Perform assertions of decoded fields - ASSERT_TRUE(expected_gdate.year() - d.year() < FLT_EPSILON ); - ASSERT_TRUE(expected_gdate.month() - d.month() < FLT_EPSILON ); - ASSERT_TRUE(expected_gdate.day() - d.day() < FLT_EPSILON ); - ASSERT_TRUE(expected_gtime.hours() - t.hours() < FLT_EPSILON ); - ASSERT_TRUE(expected_gtime.minutes() - t.minutes() < FLT_EPSILON ); - ASSERT_TRUE(expected_gtime.seconds() - t.seconds() < FLT_EPSILON ); + ASSERT_TRUE(expected_gdate.year() - d.year() < FLT_EPSILON ); + ASSERT_TRUE(expected_gdate.month() - d.month() < FLT_EPSILON ); + ASSERT_TRUE(expected_gdate.day() - d.day() < FLT_EPSILON ); + ASSERT_TRUE(expected_gtime.hours() - t.hours() < FLT_EPSILON ); + ASSERT_TRUE(expected_gtime.minutes() - t.minutes() < FLT_EPSILON ); + ASSERT_TRUE(expected_gtime.seconds() - t.seconds() < FLT_EPSILON ); } /*! @@ -82,11 +81,11 @@ TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT1) double true_week = 1307; double true_tow = 480600+true_leap_sec; - gnav_eph.glot_to_gpst(tod + glo2utc, 0.0, 0.0, &week, &tow); + gnav_eph.glot_to_gpst(tod + glo2utc, 0.0, 0.0, &week, &tow); // Perform assertions of decoded fields - ASSERT_TRUE(week - true_week < FLT_EPSILON ); - ASSERT_TRUE(tow - true_tow < FLT_EPSILON ); + ASSERT_TRUE(week - true_week < FLT_EPSILON ); + ASSERT_TRUE(tow - true_tow < FLT_EPSILON ); } /*! @@ -107,11 +106,11 @@ TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT2) double true_week = 1915; double true_tow = 518400+true_leap_sec+tod; - gnav_eph.glot_to_gpst(tod + glo2utc, 0.0, 0.0, &week, &tow); + gnav_eph.glot_to_gpst(tod + glo2utc, 0.0, 0.0, &week, &tow); // Perform assertions of decoded fields - ASSERT_TRUE(week - true_week < FLT_EPSILON ); - ASSERT_TRUE(tow - true_tow < FLT_EPSILON ); + ASSERT_TRUE(week - true_week < FLT_EPSILON ); + ASSERT_TRUE(tow - true_tow < FLT_EPSILON ); } /*! @@ -132,9 +131,9 @@ TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT3) double true_week = 1886; double true_tow = 259200+true_leap_sec+tod; - gnav_eph.glot_to_gpst(tod + glo2utc, 0.0, 0.0, &week, &tow); + gnav_eph.glot_to_gpst(tod + glo2utc, 0.0, 0.0, &week, &tow); // Perform assertions of decoded fields - ASSERT_TRUE(week - true_week < FLT_EPSILON ); - ASSERT_TRUE(tow - true_tow < FLT_EPSILON ); + ASSERT_TRUE(week - true_week < FLT_EPSILON ); + ASSERT_TRUE(tow - true_tow < FLT_EPSILON ); } From 301a35b2e2fa1b329ee136b1c487365d7600c56b Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 26 Jan 2018 15:07:53 +0100 Subject: [PATCH 95/96] Move Glonass Tracking tests from extra to regular unit tests --- src/tests/test_main.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index dff856808..4f5fb78c1 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -118,6 +118,8 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc" +#include "unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc" +#include "unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc" #include "unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_test.cc" #include "unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc" @@ -140,8 +142,6 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc" -#include "unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc" -#include "unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc" #if MODERN_ARMADILLO #include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc" #include "unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc" From 749771ac3b17ad3c518f20178f0a348bd1b91670 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 26 Jan 2018 15:12:55 +0100 Subject: [PATCH 96/96] Remove unrequired includes --- .../system-parameters/glonass_gnav_ephemeris_test.cc | 5 +++-- .../glonass_gnav_nav_message_test.cc | 11 ++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc b/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc index 9ef819052..10f0cc28d 100644 --- a/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc +++ b/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc @@ -31,8 +31,6 @@ */ -#include -#include #include "gnss_signal_processing.h" #include "glonass_gnav_ephemeris.h" @@ -63,6 +61,7 @@ TEST(GlonassGnavEphemerisTest, ComputeGlonassTime) ASSERT_TRUE(expected_gtime.seconds() - t.seconds() < FLT_EPSILON ); } + /*! * \brief Testing conversion from GLONASST to GPST * \test Tests scenario for N_T when greater than 365 days. Possible values here from 1 to 365*4 @@ -88,6 +87,7 @@ TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT1) ASSERT_TRUE(tow - true_tow < FLT_EPSILON ); } + /*! * \brief Testing conversion from GLONASST to GPST * \test This version tests the conversion for offsets greater than 30 in a leap year @@ -113,6 +113,7 @@ TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT2) ASSERT_TRUE(tow - true_tow < FLT_EPSILON ); } + /*! * \brief Testing conversion from GLONASST to GPST * \test This version tests the conversion around the vicinity of February 29 days when in leap year diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc b/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc index 595b1fa2f..e613af58a 100644 --- a/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc +++ b/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc @@ -31,11 +31,6 @@ * ------------------------------------------------------------------------- */ - -#include -#include -#include -#include #include "gnss_signal_processing.h" #include "glonass_gnav_navigation_message.h" @@ -59,6 +54,7 @@ TEST(GlonassGnavNavigationMessageTest, CRCTestSuccess) ASSERT_TRUE(test_result); } + /*! * \brief Testing CRC computation for GLONASS GNAV data bits of a string * \test The provided string was generated with a version of MATLAB GNSS-SDR that @@ -80,6 +76,7 @@ TEST(GlonassGnavNavigationMessageTest, CRCTestFailure) ASSERT_FALSE(test_result); } + /*! * \brief Testing string decoding for GLONASS GNAV messages * \test The provided string (str1.....str15) was generated with a version of @@ -112,6 +109,7 @@ TEST(GlonassGnavNavigationMessageTest, String1Decoder) ASSERT_TRUE(gnav_ephemeris.d_Xn - gnav_nav_message.gnav_ephemeris.d_Xn < FLT_EPSILON ); } + /*! * \brief Testing string decoding for GLONASS GNAV messages * \test The provided string (str1.....str15) was generated with a version of @@ -148,6 +146,7 @@ TEST(GlonassGnavNavigationMessageTest, String2Decoder) ASSERT_TRUE(gnav_ephemeris.d_Yn - gnav_nav_message.gnav_ephemeris.d_Yn < FLT_EPSILON ); } + /*! * \brief Testing string decoding for GLONASS GNAV messages * \test The provided string (str1.....str15) was generated with a version of @@ -185,6 +184,7 @@ TEST(GlonassGnavNavigationMessageTest, String3Decoder) ASSERT_TRUE(gnav_ephemeris.d_Zn - gnav_nav_message.gnav_ephemeris.d_Zn < FLT_EPSILON ); } + /*! * \brief Testing string decoding for GLONASS GNAV messages * \test The provided string (str1.....str15) was generated with a version of @@ -224,6 +224,7 @@ TEST(GlonassGnavNavigationMessageTest, String4Decoder) ASSERT_TRUE(gnav_ephemeris.d_M - gnav_nav_message.gnav_ephemeris.d_M < FLT_EPSILON ); } + /*! * \brief Testing string decoding for GLONASS GNAV messages * \test The provided string (str1.....str15) was generated with a version of

    >Ek9rflohrmN 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 ?@(R?a&+YTy36X);GJ7}!C^jQ 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¦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 z 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