From ad6bbee930e15336662cd34a56fa6bc2df87b9d1 Mon Sep 17 00:00:00 2001 From: Rodrigo Ventura Date: Sun, 19 Aug 2018 10:23:07 +0100 Subject: [PATCH 01/15] Fix build issue in OS X Define of thread_t to pthread_t in rtklib.h was colliding with system include in OS X. Not used elsewhere, so find&replaced with pthread_t. --- src/algorithms/libs/rtklib/rtklib.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/algorithms/libs/rtklib/rtklib.h b/src/algorithms/libs/rtklib/rtklib.h index 5cdd94726..14d90b902 100644 --- a/src/algorithms/libs/rtklib/rtklib.h +++ b/src/algorithms/libs/rtklib/rtklib.h @@ -71,7 +71,6 @@ #define socket_t int #define closesocket close #define lock_t pthread_mutex_t -#define thread_t pthread_t #define initlock(f) pthread_mutex_init(f, NULL) #define rtk_lock(f) pthread_mutex_lock(f) #define rtk_unlock(f) pthread_mutex_unlock(f) @@ -1211,7 +1210,7 @@ typedef struct char local[1024]; /* local file path */ int topts[4]; /* time options {poff,tint,toff,tretry} (s) */ gtime_t tnext; /* next retry time (gpst) */ - thread_t thread; /* download thread */ + pthread_t thread; /* download thread */ } ftp_t; @@ -1284,7 +1283,7 @@ typedef struct stream_t stream[8]; /* streams {rov,base,corr,sol1,sol2,logr,logb,logc} */ stream_t *moni; /* monitor stream */ unsigned int tick; /* start tick */ - thread_t thread; /* server thread */ + pthread_t thread; /* server thread */ int cputime; /* CPU time (ms) for a processing cycle */ int prcout; /* missing observation data count */ lock_t lock; /* lock flag */ From 587af5f61c38de305518cc24987f6a50b9cbc8be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Cebri=C3=A1n=20Juan?= Date: Thu, 23 Aug 2018 13:29:57 +0200 Subject: [PATCH 02/15] Add a decimator to the Monitor block --- src/core/monitor/gnss_synchro_monitor.cc | 21 +++++++++++---------- src/core/monitor/gnss_synchro_monitor.h | 2 ++ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/core/monitor/gnss_synchro_monitor.cc b/src/core/monitor/gnss_synchro_monitor.cc index bde09ef69..dada85d4a 100644 --- a/src/core/monitor/gnss_synchro_monitor.cc +++ b/src/core/monitor/gnss_synchro_monitor.cc @@ -61,6 +61,8 @@ gnss_synchro_monitor::gnss_synchro_monitor(unsigned int n_channels, d_nchannels = n_channels; udp_sink_ptr = std::unique_ptr(new Gnss_Synchro_Udp_Sink(udp_addresses, udp_port)); + + count = 0; } @@ -75,17 +77,16 @@ int gnss_synchro_monitor::work(int noutput_items, gr_vector_const_void_star& inp const Gnss_Synchro** in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer for (int epoch = 0; epoch < noutput_items; epoch++) { - // ############ 1. READ PSEUDORANGES #### - for (unsigned int i = 0; i < d_nchannels; i++) + count++; + if (count >= d_output_rate_ms) { - //if (in[i][epoch].Flag_valid_pseudorange) - // { - // } - //todo: send the gnss_synchro objects - - std::vector stocks; - stocks.push_back(in[i][epoch]); - udp_sink_ptr->write_gnss_synchro(stocks); + for (unsigned int i = 0; i < d_nchannels; i++) + { + std::vector stocks; + stocks.push_back(in[i][epoch]); + udp_sink_ptr->write_gnss_synchro(stocks); + } + count = 0; } } return noutput_items; diff --git a/src/core/monitor/gnss_synchro_monitor.h b/src/core/monitor/gnss_synchro_monitor.h index 36b6f1e3a..051c262cc 100644 --- a/src/core/monitor/gnss_synchro_monitor.h +++ b/src/core/monitor/gnss_synchro_monitor.h @@ -65,6 +65,8 @@ private: std::unique_ptr udp_sink_ptr; + unsigned int count; + public: gnss_synchro_monitor(unsigned int nchannels, From cafb3b0363840210910dfbf8e91be5ace1e6f711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Cebri=C3=A1n=20Juan?= Date: Thu, 23 Aug 2018 13:44:51 +0200 Subject: [PATCH 03/15] Fix Monitor block file header --- src/core/monitor/gnss_synchro_monitor.cc | 5 ++++- src/core/monitor/gnss_synchro_monitor.h | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/core/monitor/gnss_synchro_monitor.cc b/src/core/monitor/gnss_synchro_monitor.cc index dada85d4a..d788b52b0 100644 --- a/src/core/monitor/gnss_synchro_monitor.cc +++ b/src/core/monitor/gnss_synchro_monitor.cc @@ -1,6 +1,9 @@ /*! * \file gnss_synchro_monitor.cc - * \brief Interface of a Position Velocity and Time computation block + * \brief Implementation of a receiver monitoring block which allows sending + * a data stream with the receiver internal parameters (Gnss_Synchro objects) + * to local or remote clients over UDP. + * * \author Álvaro Cebrián Juan, 2018. acebrianjuan(at)gmail.com * * ------------------------------------------------------------------------- diff --git a/src/core/monitor/gnss_synchro_monitor.h b/src/core/monitor/gnss_synchro_monitor.h index 051c262cc..deaab7e2a 100644 --- a/src/core/monitor/gnss_synchro_monitor.h +++ b/src/core/monitor/gnss_synchro_monitor.h @@ -1,6 +1,9 @@ /*! * \file gnss_synchro_monitor.h - * \brief Interface of a Position Velocity and Time computation block + * \brief Interface of a receiver monitoring block which allows sending + * a data stream with the receiver internal parameters (Gnss_Synchro objects) + * to local or remote clients over UDP. + * * \author Álvaro Cebrián Juan, 2018. acebrianjuan(at)gmail.com * * ------------------------------------------------------------------------- From 3c3057ba0b8ccec33f24571fb98adab972aa4c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Cebri=C3=A1n=20Juan?= Date: Thu, 23 Aug 2018 14:47:24 +0200 Subject: [PATCH 04/15] Fix warning --- src/core/monitor/gnss_synchro_monitor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/monitor/gnss_synchro_monitor.h b/src/core/monitor/gnss_synchro_monitor.h index deaab7e2a..9547bf12d 100644 --- a/src/core/monitor/gnss_synchro_monitor.h +++ b/src/core/monitor/gnss_synchro_monitor.h @@ -68,7 +68,7 @@ private: std::unique_ptr udp_sink_ptr; - unsigned int count; + int count; public: From 41527fb92146e105e12f6683510cab555d29d5de Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 23 Aug 2018 19:39:41 +0200 Subject: [PATCH 05/15] Rename volk_gnsssdr_32f_xn_fast_resampler_32f_xn to volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xnn --- ...32f_high_dynamics_resamplerxnpuppet_32f.h} | 40 +++++++++---------- ...r_32f_xn_high_dynamics_resampler_32f_xn.h} | 28 ++++++------- .../volk_gnsssdr/lib/kernel_tests.h | 2 +- .../libs/cpu_multicorrelator_real_codes.cc | 15 +++---- .../libs/cpu_multicorrelator_real_codes.h | 6 +-- 5 files changed, 46 insertions(+), 45 deletions(-) rename src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/{volk_gnsssdr_32f_fast_resamplerxnpuppet_32f.h => volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f.h} (74%) rename src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/{volk_gnsssdr_32f_xn_fast_resampler_32f_xn.h => volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn.h} (91%) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_fast_resamplerxnpuppet_32f.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f.h similarity index 74% rename from src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_fast_resamplerxnpuppet_32f.h rename to src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f.h index d33629277..c6705adca 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_fast_resamplerxnpuppet_32f.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f.h @@ -1,6 +1,6 @@ /*! - * \file volk_gnsssdr_32f_fast_resamplerxnpuppet_32f.h - * \brief VOLK_GNSSSDR puppet for the multiple 32-bit float vector fast resampler kernel. + * \file volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f.h + * \brief VOLK_GNSSSDR puppet for the multiple 32-bit float vector high dynamics resampler kernel. * \authors
    *
  • Cillian O'Driscoll 2017 cillian.odriscoll at gmail dot com *
  • Javier Arribas, 2018. javiarribas(at)gmail.com @@ -33,10 +33,10 @@ * ------------------------------------------------------------------------- */ -#ifndef INCLUDED_volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_H -#define INCLUDED_volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_H +#ifndef INCLUDED_volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_H +#define INCLUDED_volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_H -#include "volk_gnsssdr/volk_gnsssdr_32f_xn_fast_resampler_32f_xn.h" +#include "volk_gnsssdr/volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn.h" #include #include #include @@ -44,7 +44,7 @@ #ifdef LV_HAVE_GENERIC -static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_generic(float* result, const float* local_code, unsigned int num_points) +static inline void volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_generic(float* result, const float* local_code, unsigned int num_points) { int code_length_chips = 2046; float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); @@ -60,7 +60,7 @@ static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_generic(float* re result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); } - volk_gnsssdr_32f_xn_fast_resampler_32f_xn_generic(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); + volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_generic(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); @@ -75,7 +75,7 @@ static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_generic(float* re #ifdef LV_HAVE_SSE3 -static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_a_sse3(float* result, const float* local_code, unsigned int num_points) +static inline void volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_a_sse3(float* result, const float* local_code, unsigned int num_points) { int code_length_chips = 2046; float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); @@ -91,7 +91,7 @@ static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_a_sse3(float* res result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); } - volk_gnsssdr_32f_xn_fast_resampler_32f_xn_a_sse3(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); + volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_a_sse3(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); @@ -106,7 +106,7 @@ static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_a_sse3(float* res #ifdef LV_HAVE_SSE3 -static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_u_sse3(float* result, const float* local_code, unsigned int num_points) +static inline void volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_u_sse3(float* result, const float* local_code, unsigned int num_points) { int code_length_chips = 2046; float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); @@ -122,7 +122,7 @@ static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_u_sse3(float* res result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); } - volk_gnsssdr_32f_xn_fast_resampler_32f_xn_u_sse3(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); + volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_u_sse3(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); @@ -137,7 +137,7 @@ static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_u_sse3(float* res #ifdef LV_HAVE_SSE4_1 -static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_u_sse4_1(float* result, const float* local_code, unsigned int num_points) +static inline void volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_u_sse4_1(float* result, const float* local_code, unsigned int num_points) { int code_length_chips = 2046; float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); @@ -153,7 +153,7 @@ static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_u_sse4_1(float* r result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); } - volk_gnsssdr_32f_xn_fast_resampler_32f_xn_u_sse4_1(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); + volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_u_sse4_1(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); @@ -168,7 +168,7 @@ static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_u_sse4_1(float* r #ifdef LV_HAVE_SSE4_1 -static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_a_sse4_1(float* result, const float* local_code, unsigned int num_points) +static inline void volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_a_sse4_1(float* result, const float* local_code, unsigned int num_points) { int code_length_chips = 2046; float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); @@ -184,7 +184,7 @@ static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_a_sse4_1(float* r result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); } - volk_gnsssdr_32f_xn_fast_resampler_32f_xn_a_sse4_1(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); + volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_a_sse4_1(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); @@ -199,7 +199,7 @@ static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_a_sse4_1(float* r #ifdef LV_HAVE_AVX -static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_a_avx(float* result, const float* local_code, unsigned int num_points) +static inline void volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_a_avx(float* result, const float* local_code, unsigned int num_points) { int code_length_chips = 2046; float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); @@ -215,7 +215,7 @@ static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_a_avx(float* resu result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); } - volk_gnsssdr_32f_xn_fast_resampler_32f_xn_a_avx(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); + volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_a_avx(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); @@ -229,7 +229,7 @@ static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_a_avx(float* resu #ifdef LV_HAVE_AVX -static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_u_avx(float* result, const float* local_code, unsigned int num_points) +static inline void volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_u_avx(float* result, const float* local_code, unsigned int num_points) { int code_length_chips = 2046; float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); @@ -245,7 +245,7 @@ static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_u_avx(float* resu result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); } - volk_gnsssdr_32f_xn_fast_resampler_32f_xn_u_avx(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); + volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_u_avx(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); @@ -285,4 +285,4 @@ static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_u_avx(float* resu //} //#endif -#endif // INCLUDED_volk_gnsssdr_32f_fast_resamplerpuppet_32f_H +#endif // INCLUDED_volk_gnsssdr_32f_high_dynamics_resamplerpuppet_32f_H diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_xn_fast_resampler_32f_xn.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn.h similarity index 91% rename from src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_xn_fast_resampler_32f_xn.h rename to src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn.h index 283454bb1..8b666908b 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_xn_fast_resampler_32f_xn.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn.h @@ -1,5 +1,5 @@ /*! - * \file volk_gnsssdr_32f_xn_fast_resampler_32f_xn.h + * \file volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn.h * \brief VOLK_GNSSSDR kernel: Resamples 1 complex 32-bit float vectors using zero hold resample algorithm * and produces the delayed replicas by copying and rotating the resulting resampled signal. * \authors
      @@ -38,7 +38,7 @@ */ /*! - * \page volk_gnsssdr_32f_xn_fast_resampler_32f_xn + * \page volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn * * \b Overview * @@ -46,7 +46,7 @@ * * Dispatcher Prototype * \code - * void volk_gnsssdr_32f_xn_fast_resampler_32f_xn(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) + * void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) * \endcode * * \b Inputs @@ -64,8 +64,8 @@ * */ -#ifndef INCLUDED_volk_gnsssdr_32f_xn_fast_resampler_32f_xn_H -#define INCLUDED_volk_gnsssdr_32f_xn_fast_resampler_32f_xn_H +#ifndef INCLUDED_volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_H +#define INCLUDED_volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_H #include #include @@ -78,7 +78,7 @@ #ifdef LV_HAVE_GENERIC -static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_generic(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) +static inline void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_generic(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) { int local_code_chip_index; int current_correlator_tap; @@ -109,7 +109,7 @@ static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_generic(float** res #ifdef LV_HAVE_SSE3 #include -static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_a_sse3(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) +static inline void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_a_sse3(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) { float** _result = result; const unsigned int quarterPoints = num_points / 4; @@ -194,7 +194,7 @@ static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_a_sse3(float** resu #ifdef LV_HAVE_SSE3 #include -static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_u_sse3(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) +static inline void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_u_sse3(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) { float** _result = result; const unsigned int quarterPoints = num_points / 4; @@ -280,7 +280,7 @@ static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_u_sse3(float** resu #ifdef LV_HAVE_SSE4_1 #include -static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_a_sse4_1(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) +static inline void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_a_sse4_1(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) { float** _result = result; const unsigned int quarterPoints = num_points / 4; @@ -362,7 +362,7 @@ static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_a_sse4_1(float** re #ifdef LV_HAVE_SSE4_1 #include -static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_u_sse4_1(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) +static inline void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_u_sse4_1(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) { float** _result = result; const unsigned int quarterPoints = num_points / 4; @@ -444,7 +444,7 @@ static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_u_sse4_1(float** re #ifdef LV_HAVE_AVX #include -static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_a_avx(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) +static inline void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_a_avx(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) { float** _result = result; const unsigned int avx_iters = num_points / 8; @@ -532,7 +532,7 @@ static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_a_avx(float** resul #ifdef LV_HAVE_AVX #include -static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_u_avx(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) +static inline void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_u_avx(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) { float** _result = result; const unsigned int avx_iters = num_points / 8; @@ -621,7 +621,7 @@ static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_u_avx(float** resul //#ifdef LV_HAVE_NEONV7 //#include // -//static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_neon(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) +//static inline void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_neon(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) //{ // float** _result = result; // const unsigned int neon_iters = num_points / 4; @@ -704,4 +704,4 @@ static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_u_avx(float** resul // //#endif -#endif /*INCLUDED_volk_gnsssdr_32f_xn_fast_resampler_32f_xn_H*/ +#endif /*INCLUDED_volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_H*/ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/kernel_tests.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/kernel_tests.h index 90281b32f..389e03b14 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/kernel_tests.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/kernel_tests.h @@ -93,7 +93,7 @@ std::vector init_test_list(volk_gnsssdr_test_params_t QA(VOLK_INIT_PUPP(volk_gnsssdr_16i_resamplerxnpuppet_16i, volk_gnsssdr_16i_xn_resampler_16i_xn, test_params)) QA(VOLK_INIT_PUPP(volk_gnsssdr_32fc_resamplerxnpuppet_32fc, volk_gnsssdr_32fc_xn_resampler_32fc_xn, test_params)) QA(VOLK_INIT_PUPP(volk_gnsssdr_32f_resamplerxnpuppet_32f, volk_gnsssdr_32f_xn_resampler_32f_xn, test_params)) - QA(VOLK_INIT_PUPP(volk_gnsssdr_32f_fast_resamplerxnpuppet_32f, volk_gnsssdr_32f_xn_fast_resampler_32f_xn, test_params)) + QA(VOLK_INIT_PUPP(volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f, volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn, test_params)) QA(VOLK_INIT_PUPP(volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic, volk_gnsssdr_16ic_x2_dot_prod_16ic_xn, test_params)) QA(VOLK_INIT_PUPP(volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic, volk_gnsssdr_16ic_x2_rotator_dot_prod_16ic_xn, test_params_int16)) QA(VOLK_INIT_PUPP(volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic, volk_gnsssdr_16ic_16i_rotator_dot_prod_16ic_xn, test_params_int16)) diff --git a/src/algorithms/tracking/libs/cpu_multicorrelator_real_codes.cc b/src/algorithms/tracking/libs/cpu_multicorrelator_real_codes.cc index b78b1a4c5..6222ddfb9 100644 --- a/src/algorithms/tracking/libs/cpu_multicorrelator_real_codes.cc +++ b/src/algorithms/tracking/libs/cpu_multicorrelator_real_codes.cc @@ -1,6 +1,6 @@ /*! * \file cpu_multicorrelator_real_codes.cc - * \brief High optimized CPU vector multiTAP correlator class with real-valued local codes + * \brief Highly optimized CPU vector multiTAP correlator class with real-valued local codes * \authors
        *
      • Javier Arribas, 2015. jarribas(at)cttc.es *
      • Cillian O'Driscoll, 2017. cillian.odriscoll(at)gmail.com @@ -46,7 +46,7 @@ cpu_multicorrelator_real_codes::cpu_multicorrelator_real_codes() d_local_codes_resampled = nullptr; d_code_length_chips = 0; d_n_correlators = 0; - d_use_fast_resampler = true; + d_use_high_dynamics_resampler = true; } @@ -100,9 +100,9 @@ bool cpu_multicorrelator_real_codes::set_input_output_vectors(std::complex *
      • Javier Arribas, 2015. jarribas(at)cttc.es *
      • Cillian O'Driscoll, 2017, cillian.odriscoll(at)gmail.com @@ -46,7 +46,7 @@ class cpu_multicorrelator_real_codes { public: cpu_multicorrelator_real_codes(); - void set_fast_resampler(bool use_fast_resampler); + void set_high_dynamics_resampler(bool use_high_dynamics_resampler); ~cpu_multicorrelator_real_codes(); bool init(int max_signal_length_samples, int n_correlators); bool set_local_code_and_taps(int code_length_chips, const float *local_code_in, float *shifts_chips); @@ -62,7 +62,7 @@ private: const float *d_local_code_in; std::complex *d_corr_out; float *d_shifts_chips; - bool d_use_fast_resampler; + bool d_use_high_dynamics_resampler; int d_code_length_chips; int d_n_correlators; }; From bbcc0bee36acc41fb6d87ab7f560187087c19622 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 23 Aug 2018 19:52:01 +0200 Subject: [PATCH 06/15] Rename volk_gnsssdr_32f_xn_fast_resampler_32f_xn to volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn --- .../tracking/gnuradio_blocks/dll_pll_veml_tracking.cc | 2 +- src/algorithms/tracking/libs/dll_pll_conf.cc | 2 +- src/algorithms/tracking/libs/dll_pll_conf.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc index 5b4d36581..815ff2c88 100755 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -362,7 +362,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl } // --- Initializations --- - multicorrelator_cpu.set_fast_resampler(trk_parameters.use_fast_resampler); + multicorrelator_cpu.set_high_dynamics_resampler(trk_parameters.use_high_dynamics_resampler); // Initial code frequency basis of NCO d_code_freq_chips = d_code_chip_rate; // Residual code phase (in chips) diff --git a/src/algorithms/tracking/libs/dll_pll_conf.cc b/src/algorithms/tracking/libs/dll_pll_conf.cc index 9eadfde8f..525adcceb 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf.cc +++ b/src/algorithms/tracking/libs/dll_pll_conf.cc @@ -36,7 +36,7 @@ Dll_Pll_Conf::Dll_Pll_Conf() { /* DLL/PLL tracking configuration */ - use_fast_resampler = true; + use_high_dynamics_resampler = true; fs_in = 0.0; vector_length = 0U; dump = false; diff --git a/src/algorithms/tracking/libs/dll_pll_conf.h b/src/algorithms/tracking/libs/dll_pll_conf.h index bda1853aa..d557b89c0 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf.h +++ b/src/algorithms/tracking/libs/dll_pll_conf.h @@ -56,7 +56,7 @@ public: float early_late_space_narrow_chips; float very_early_late_space_narrow_chips; int32_t extend_correlation_symbols; - bool use_fast_resampler; + bool use_high_dynamics_resampler; int32_t cn0_samples; int32_t carrier_lock_det_mav_samples; int32_t cn0_min; From 050543b42765564ab6f4988e3a7699fb263220f4 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 24 Aug 2018 12:34:36 +0200 Subject: [PATCH 07/15] Start at 30 dBHz by default --- .../acquisition/acq_performance_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc index 3099d950e..f61727542 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc @@ -64,7 +64,7 @@ DEFINE_int32(acq_test_second_doppler_step, 10, "If --acq_test_make_two_steps is DEFINE_int32(acq_test_signal_duration_s, 2, "Generated signal duration, in s"); DEFINE_int32(acq_test_num_meas, 0, "Number of measurements per run. 0 means the complete file."); -DEFINE_double(acq_test_cn0_init, 33.0, "Initial CN0, in dBHz."); +DEFINE_double(acq_test_cn0_init, 30.0, "Initial CN0, in dBHz."); DEFINE_double(acq_test_cn0_final, 45.0, "Final CN0, in dBHz."); DEFINE_double(acq_test_cn0_step, 3.0, "CN0 step, in dB."); From a7d28c20c1a498189e24208880f1ee43de7fa54c Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Sun, 26 Aug 2018 20:06:30 +0200 Subject: [PATCH 08/15] Adding Galileo INAV and FNAV page decoder unit test --- src/tests/test_main.cc | 1 + .../galileo_fnav_inav_decoder_test.cc | 288 ++++++++++++++++++ 2 files changed, 289 insertions(+) create mode 100644 src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/galileo_fnav_inav_decoder_test.cc diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index c89349d15..64920b9a1 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -158,6 +158,7 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc" #endif +#include "unit-tests/signal-processing-blocks/telemetry_decoder/galileo_fnav_inav_decoder_test.cc" #include "unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc" #include "unit-tests/system-parameters/glonass_gnav_nav_message_test.cc" diff --git a/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/galileo_fnav_inav_decoder_test.cc b/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/galileo_fnav_inav_decoder_test.cc new file mode 100644 index 000000000..070a76e42 --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/galileo_fnav_inav_decoder_test.cc @@ -0,0 +1,288 @@ +/*! + * \file galileo_fnav_inav_decoder_test.cc + * \brief This class implements the unit test for the Galileo FNAV and INAV frames + * according to the Galileo ICD + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2012-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 "galileo_navigation_message.h" +#include "galileo_fnav_message.h" +#include "convolutional.h" +#include +#include +#include +#include +#include +#include +#include + + +class Galileo_FNAV_INAV_test : public ::testing::Test +{ +public: + Galileo_Navigation_Message INAV_decoder; + Galileo_Fnav_Message FNAV_decoder; + // vars for Viterbi decoder + int32_t *out0, *out1, *state0, *state1; + int32_t g_encoder[2]; + const int32_t nn = 2; // Coding rate 1/n + const int32_t KK = 7; // Constraint Length + int32_t mm = KK - 1; + int32_t flag_even_word_arrived; + void viterbi_decoder(double *page_part_symbols, int32_t *page_part_bits, int32_t _datalength) + { + Viterbi(page_part_bits, out0, state0, out1, state1, + page_part_symbols, KK, nn, _datalength); + } + + + void deinterleaver(int32_t rows, int32_t cols, double *in, double *out) + { + for (int32_t r = 0; r < rows; r++) + { + for (int32_t c = 0; c < cols; c++) + { + out[c * rows + r] = in[r * cols + c]; + } + } + } + + + bool decode_INAV_word(double *page_part_symbols, int32_t frame_length) + { + // 1. De-interleave + double *page_part_symbols_deint = static_cast(volk_gnsssdr_malloc(frame_length * sizeof(double), volk_gnsssdr_get_alignment())); + deinterleaver(GALILEO_INAV_INTERLEAVER_ROWS, GALILEO_INAV_INTERLEAVER_COLS, page_part_symbols, page_part_symbols_deint); + + // 2. Viterbi decoder + // 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder) + // 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180º + for (int32_t i = 0; i < frame_length; i++) + { + if ((i + 1) % 2 == 0) + { + page_part_symbols_deint[i] = -page_part_symbols_deint[i]; + } + } + + int32_t *page_part_bits = static_cast(volk_gnsssdr_malloc((frame_length / 2) * sizeof(int32_t), volk_gnsssdr_get_alignment())); + + const int32_t CodeLength = 240; + int32_t DataLength = (CodeLength / nn) - mm; + viterbi_decoder(page_part_symbols_deint, page_part_bits, DataLength); + volk_gnsssdr_free(page_part_symbols_deint); + + // 3. Call the Galileo page decoder + std::string page_String; + for (int32_t i = 0; i < (frame_length / 2); i++) + { + if (page_part_bits[i] > 0) + { + page_String.push_back('1'); + } + else + { + page_String.push_back('0'); + } + } + + bool crc_ok = false; + if (page_part_bits[0] == 1) + { + // DECODE COMPLETE WORD (even + odd) and TEST CRC + INAV_decoder.split_page(page_String, flag_even_word_arrived); + if (INAV_decoder.flag_CRC_test == true) + { + std::cout << "Galileo E1 INAV PAGE CRC correct \n"; + //std::cout << "Galileo E1 CRC correct on channel " << d_channel << " from satellite " << d_satellite << std::endl; + crc_ok = true; + } + flag_even_word_arrived = 0; + } + else + { + // STORE HALF WORD (even page) + INAV_decoder.split_page(page_String.c_str(), flag_even_word_arrived); + flag_even_word_arrived = 1; + } + volk_gnsssdr_free(page_part_bits); + return crc_ok; + } + + bool decode_FNAV_word(double *page_symbols, int32_t frame_length) + { + // 1. De-interleave + double *page_symbols_deint = static_cast(volk_gnsssdr_malloc(frame_length * sizeof(double), volk_gnsssdr_get_alignment())); + deinterleaver(GALILEO_FNAV_INTERLEAVER_ROWS, GALILEO_FNAV_INTERLEAVER_COLS, page_symbols, page_symbols_deint); + + // 2. Viterbi decoder + // 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder) + // 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180 + for (int32_t i = 0; i < frame_length; i++) + { + if ((i + 1) % 2 == 0) + { + page_symbols_deint[i] = -page_symbols_deint[i]; + } + } + int32_t *page_bits = static_cast(volk_gnsssdr_malloc((frame_length / 2) * sizeof(int32_t), volk_gnsssdr_get_alignment())); + + const int32_t CodeLength = 488; + int32_t DataLength = (CodeLength / nn) - mm; + viterbi_decoder(page_symbols_deint, page_bits, DataLength); + + volk_gnsssdr_free(page_symbols_deint); + + // 3. Call the Galileo page decoder + std::string page_String; + for (int32_t i = 0; i < frame_length; i++) + { + if (page_bits[i] > 0) + { + page_String.push_back('1'); + } + else + { + page_String.push_back('0'); + } + } + volk_gnsssdr_free(page_bits); + + // DECODE COMPLETE WORD (even + odd) and TEST CRC + FNAV_decoder.split_page(page_String); + if (FNAV_decoder.flag_CRC_test == true) + { + std::cout << "Galileo E5a FNAV PAGE CRC correct \n"; + return true; + } + else + { + return false; + } + } + + Galileo_FNAV_INAV_test() + { + // vars for Viterbi decoder + int32_t max_states = 1 << mm; // 2^mm + g_encoder[0] = 121; // Polynomial G1 + g_encoder[1] = 91; // Polynomial G2 + out0 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); + out1 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); + state0 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); + state1 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); + // create appropriate transition matrices + nsc_transit(out0, state0, 0, g_encoder, KK, nn); + nsc_transit(out1, state1, 1, g_encoder, KK, nn); + flag_even_word_arrived = 0; + } + + ~Galileo_FNAV_INAV_test() + { + volk_gnsssdr_free(out0); + volk_gnsssdr_free(out1); + volk_gnsssdr_free(state0); + volk_gnsssdr_free(state1); + } +}; + +TEST_F(Galileo_FNAV_INAV_test, ValidationOfResults) +{ + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds(0); + + int repetitions = 10; + // FNAV FULLY ENCODED FRAME + double FNAV_frame[488] = {-1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, + -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, + -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, + -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, + -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, + -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, + -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, + 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, + -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, + 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, + -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, + 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, + 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1}; + + ASSERT_NO_THROW({ + for (int n = 0; n < repetitions; n++) + { + EXPECT_EQ(decode_FNAV_word(&FNAV_frame[0], 488), true); + } + }) << "Exception during FNAV frame decoding"; + + + // INAV FULLY ENCODED FRAME + double INAV_frame_even[240] = {-1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, + -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, + 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, + -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1}; + + double INAV_frame_odd[240] = {1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, + 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, + -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, + 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, + -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, + 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, + -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, + -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1}; + + ASSERT_NO_THROW({ + for (int n = 0; n < repetitions; n++) + { + decode_INAV_word(&INAV_frame_even[0], 240); + EXPECT_EQ(decode_INAV_word(&INAV_frame_odd[0], 240), true); + } + }) << "Exception during INAV frame decoding"; + + + std::cout << "Galileo FNAV/INAV Test completed in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; +} From 6d743708608a514cbc64f452b989effb7b5a02b9 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Mon, 27 Aug 2018 18:05:19 +0200 Subject: [PATCH 09/15] Joining Galileo FNAV and FNAV telemetry decoders in a single GNURadio block --- .../adapters/galileo_e1b_telemetry_decoder.cc | 2 +- .../adapters/galileo_e1b_telemetry_decoder.h | 5 +- .../adapters/galileo_e5a_telemetry_decoder.cc | 2 +- .../adapters/galileo_e5a_telemetry_decoder.h | 5 +- .../gnuradio_blocks/CMakeLists.txt | 3 +- .../galileo_e1b_telemetry_decoder_cc.cc | 501 ----------- .../galileo_e5a_telemetry_decoder_cc.cc | 513 ------------ .../galileo_e5a_telemetry_decoder_cc.h | 127 --- .../galileo_telemetry_decoder_cc.cc | 780 ++++++++++++++++++ ...er_cc.h => galileo_telemetry_decoder_cc.h} | 58 +- .../gnuradio_blocks/dll_pll_veml_tracking.cc | 9 +- src/core/system_parameters/Galileo_E1.h | 6 +- 12 files changed, 828 insertions(+), 1183 deletions(-) delete mode 100644 src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.cc delete mode 100644 src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc delete mode 100644 src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.h create mode 100644 src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.cc rename src/algorithms/telemetry_decoder/gnuradio_blocks/{galileo_e1b_telemetry_decoder_cc.h => galileo_telemetry_decoder_cc.h} (62%) diff --git a/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc index ab20cab1d..f7a663358 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc @@ -55,7 +55,7 @@ GalileoE1BTelemetryDecoder::GalileoE1BTelemetryDecoder(ConfigurationInterface* c dump_ = configuration->property(role + ".dump", false); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); // make telemetry decoder object - telemetry_decoder_ = galileo_e1b_make_telemetry_decoder_cc(satellite_, dump_); // TODO fix me + telemetry_decoder_ = galileo_make_telemetry_decoder_cc(satellite_, 1, dump_); //unified galileo decoder set to INAV (frame_type=1) DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; channel_ = 0; if (in_streams_ > 1) diff --git a/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.h index d762eabd8..119e294ad 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.h @@ -36,7 +36,7 @@ #include "telemetry_decoder_interface.h" -#include "galileo_e1b_telemetry_decoder_cc.h" +#include "galileo_telemetry_decoder_cc.h" #include "gnss_satellite.h" #include @@ -76,7 +76,6 @@ public: 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; @@ -88,7 +87,7 @@ public: } private: - galileo_e1b_telemetry_decoder_cc_sptr telemetry_decoder_; + galileo_telemetry_decoder_cc_sptr telemetry_decoder_; Gnss_Satellite satellite_; int channel_; bool dump_; diff --git a/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.cc index 48ed8b216..99ab590ea 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.cc @@ -58,7 +58,7 @@ GalileoE5aTelemetryDecoder::GalileoE5aTelemetryDecoder(ConfigurationInterface* c dump_ = configuration->property(role + ".dump", false); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); // make telemetry decoder object - telemetry_decoder_ = galileo_e5a_make_telemetry_decoder_cc(satellite_, dump_); // TODO fix me + telemetry_decoder_ = galileo_make_telemetry_decoder_cc(satellite_, 2, dump_); //unified galileo decoder set to FNAV (frame_type=2) DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; channel_ = 0; if (in_streams_ > 1) diff --git a/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.h index 4a4167bf5..022636384 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.h @@ -37,7 +37,7 @@ #ifndef GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_H_ #define GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_H_ -#include "galileo_e5a_telemetry_decoder_cc.h" +#include "galileo_telemetry_decoder_cc.h" #include "telemetry_decoder_interface.h" #include @@ -76,7 +76,6 @@ public: 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; @@ -88,7 +87,7 @@ public: } private: - galileo_e5a_telemetry_decoder_cc_sptr telemetry_decoder_; + galileo_telemetry_decoder_cc_sptr telemetry_decoder_; Gnss_Satellite satellite_; int channel_; bool dump_; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt b/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt index 3af26e46b..5a49bf03a 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt @@ -20,11 +20,10 @@ set(TELEMETRY_DECODER_GR_BLOCKS_SOURCES gps_l1_ca_telemetry_decoder_cc.cc gps_l2c_telemetry_decoder_cc.cc gps_l5_telemetry_decoder_cc.cc - galileo_e1b_telemetry_decoder_cc.cc sbas_l1_telemetry_decoder_cc.cc - galileo_e5a_telemetry_decoder_cc.cc glonass_l1_ca_telemetry_decoder_cc.cc glonass_l2_ca_telemetry_decoder_cc.cc + galileo_telemetry_decoder_cc.cc ) include_directories( diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.cc deleted file mode 100644 index 769902600..000000000 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.cc +++ /dev/null @@ -1,501 +0,0 @@ -/*! - * \file galileo_e1b_telemetry_decoder_cc.cc - * \brief Implementation of a Galileo INAV message demodulator block - * \author Mara Branzanti 2013. mara.branzanti(at)gmail.com - * \author Javier Arribas 2013. 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 "galileo_e1b_telemetry_decoder_cc.h" -#include "control_message_factory.h" -#include "convolutional.h" -#include "gnss_synchro.h" -#include -#include -#include -#include -#include - - -#define CRC_ERROR_LIMIT 6 - -using google::LogMessage; - - -galileo_e1b_telemetry_decoder_cc_sptr -galileo_e1b_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump) -{ - return galileo_e1b_telemetry_decoder_cc_sptr(new galileo_e1b_telemetry_decoder_cc(satellite, dump)); -} - - -void galileo_e1b_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols, int32_t *page_part_bits) -{ - Viterbi(page_part_bits, out0, state0, out1, state1, - page_part_symbols, KK, nn, DataLength); -} - - -void galileo_e1b_telemetry_decoder_cc::deinterleaver(int32_t rows, int32_t cols, double *in, double *out) -{ - for (int32_t r = 0; r < rows; r++) - { - for (int32_t c = 0; c < cols; c++) - { - out[c * rows + r] = in[r * cols + c]; - } - } -} - - -galileo_e1b_telemetry_decoder_cc::galileo_e1b_telemetry_decoder_cc( - const Gnss_Satellite &satellite, - bool dump) : gr::block("galileo_e1b_telemetry_decoder_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) -{ - // Ephemeris data port out - this->message_port_register_out(pmt::mp("telemetry")); - // initialize internal vars - d_dump = dump; - d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); - LOG(INFO) << "Initializing GALILEO E1B TELEMETRY PROCESSING"; - d_samples_per_symbol = (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS) / Galileo_E1_B_SYMBOL_RATE_BPS; - - // set the preamble - uint16_t preambles_bits[GALILEO_INAV_PREAMBLE_LENGTH_BITS] = GALILEO_INAV_PREAMBLE; - - d_symbols_per_preamble = GALILEO_INAV_PREAMBLE_LENGTH_BITS * d_samples_per_symbol; - - memcpy(static_cast(this->d_preambles_bits), static_cast(preambles_bits), GALILEO_INAV_PREAMBLE_LENGTH_BITS * sizeof(uint16_t)); - - // preamble bits to sampled symbols - d_preambles_symbols = static_cast(volk_gnsssdr_malloc(d_symbols_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment())); - int32_t n = 0; - for (int32_t i = 0; i < GALILEO_INAV_PREAMBLE_LENGTH_BITS; i++) - { - for (uint32_t j = 0; j < d_samples_per_symbol; j++) - { - if (d_preambles_bits[i] == 1) - { - d_preambles_symbols[n] = 1; - } - else - { - d_preambles_symbols[n] = -1; - } - n++; - } - } - d_sample_counter = 0ULL; - d_stat = 0; - d_preamble_index = 0ULL; - - d_flag_frame_sync = false; - - d_flag_parity = false; - d_TOW_at_current_symbol_ms = 0; - d_TOW_at_Preamble_ms = 0; - delta_t = 0; - d_CRC_error_counter = 0; - flag_even_word_arrived = 0; - d_flag_preamble = false; - d_channel = 0; - flag_TOW_set = false; - - // vars for Viterbi decoder - int32_t max_states = 1 << mm; // 2^mm - g_encoder[0] = 121; // Polynomial G1 - g_encoder[1] = 91; // Polynomial G2 - out0 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); - out1 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); - state0 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); - state1 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); - // create appropriate transition matrices - nsc_transit(out0, state0, 0, g_encoder, KK, nn); - nsc_transit(out1, state1, 1, g_encoder, KK, nn); -} - - -galileo_e1b_telemetry_decoder_cc::~galileo_e1b_telemetry_decoder_cc() -{ - volk_gnsssdr_free(d_preambles_symbols); - volk_gnsssdr_free(out0); - volk_gnsssdr_free(out1); - volk_gnsssdr_free(state0); - volk_gnsssdr_free(state1); - if (d_dump_file.is_open() == true) - { - try - { - d_dump_file.close(); - } - catch (const std::exception &ex) - { - LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); - } - } -} - - -void galileo_e1b_telemetry_decoder_cc::decode_word(double *page_part_symbols, int32_t frame_length) -{ - // 1. De-interleave - double *page_part_symbols_deint = static_cast(volk_gnsssdr_malloc(frame_length * sizeof(double), volk_gnsssdr_get_alignment())); - deinterleaver(GALILEO_INAV_INTERLEAVER_ROWS, GALILEO_INAV_INTERLEAVER_COLS, page_part_symbols, page_part_symbols_deint); - - // 2. Viterbi decoder - // 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder) - // 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180º - for (int32_t i = 0; i < frame_length; i++) - { - if ((i + 1) % 2 == 0) - { - page_part_symbols_deint[i] = -page_part_symbols_deint[i]; - } - } - - int32_t *page_part_bits = static_cast(volk_gnsssdr_malloc((frame_length / 2) * sizeof(int32_t), volk_gnsssdr_get_alignment())); - viterbi_decoder(page_part_symbols_deint, page_part_bits); - volk_gnsssdr_free(page_part_symbols_deint); - - // 3. Call the Galileo page decoder - std::string page_String; - for (int32_t i = 0; i < (frame_length / 2); i++) - { - if (page_part_bits[i] > 0) - { - page_String.push_back('1'); - } - else - { - page_String.push_back('0'); - } - } - - if (page_part_bits[0] == 1) - { - // DECODE COMPLETE WORD (even + odd) and TEST CRC - d_nav.split_page(page_String, flag_even_word_arrived); - if (d_nav.flag_CRC_test == true) - { - LOG(INFO) << "Galileo E1 CRC correct in channel " << d_channel << " from satellite " << d_satellite; - //std::cout << "Galileo E1 CRC correct on channel " << d_channel << " from satellite " << d_satellite << std::endl; - } - else - { - std::cout << "Galileo E1 CRC error in channel " << d_channel << " from satellite " << d_satellite << std::endl; - LOG(INFO) << "Galileo E1 CRC error in channel " << d_channel << " from satellite " << d_satellite; - } - flag_even_word_arrived = 0; - } - else - { - // STORE HALF WORD (even page) - d_nav.split_page(page_String.c_str(), flag_even_word_arrived); - flag_even_word_arrived = 1; - } - volk_gnsssdr_free(page_part_bits); - - // 4. Push the new navigation data to the queues - if (d_nav.have_new_ephemeris() == true) - { - // get object for this SV (mandatory) - std::shared_ptr tmp_obj = std::make_shared(d_nav.get_ephemeris()); - std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel << ": ephemeris from satellite " << d_satellite << std::endl; - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } - if (d_nav.have_new_iono_and_GST() == true) - { - // get object for this SV (mandatory) - std::shared_ptr tmp_obj = std::make_shared(d_nav.get_iono()); - std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel << ": iono/GST model parameters from satellite " << d_satellite << std::endl; - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } - if (d_nav.have_new_utc_model() == true) - { - // get object for this SV (mandatory) - std::shared_ptr tmp_obj = std::make_shared(d_nav.get_utc_model()); - std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel << ": UTC model parameters from satellite " << d_satellite << std::endl; - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } - if (d_nav.have_new_almanac() == true) - { - std::shared_ptr tmp_obj = std::make_shared(d_nav.get_almanac()); - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - //debug - std::cout << "Galileo E1 I/NAV almanac received in channel " << d_channel << " from satellite " << d_satellite << std::endl; - DLOG(INFO) << "GPS_to_Galileo time conversion:"; - DLOG(INFO) << "A0G=" << tmp_obj->A_0G_10; - DLOG(INFO) << "A1G=" << tmp_obj->A_1G_10; - DLOG(INFO) << "T0G=" << tmp_obj->t_0G_10; - DLOG(INFO) << "WN_0G_10=" << tmp_obj->WN_0G_10; - DLOG(INFO) << "Current parameters:"; - DLOG(INFO) << "d_TOW_at_current_symbol_ms=" << d_TOW_at_current_symbol_ms; - DLOG(INFO) << "d_nav.WN_0=" << d_nav.WN_0; - delta_t = tmp_obj->A_0G_10 + tmp_obj->A_1G_10 * (static_cast(d_TOW_at_current_symbol_ms) / 1000.0 - tmp_obj->t_0G_10 + 604800 * (fmod((d_nav.WN_0 - tmp_obj->WN_0G_10), 64))); - DLOG(INFO) << "delta_t=" << delta_t << "[s]"; - } -} - - -void galileo_e1b_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satellite) -{ - d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); - DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite; - DLOG(INFO) << "Navigation Satellite set to " << d_satellite; -} - - -void galileo_e1b_telemetry_decoder_cc::set_channel(int32_t channel) -{ - d_channel = channel; - LOG(INFO) << "Navigation channel set to " << channel; - // ############# ENABLE DATA FILE LOG ################# - if (d_dump == true) - { - if (d_dump_file.is_open() == false) - { - try - { - d_dump_filename = "telemetry"; - d_dump_filename.append(boost::lexical_cast(d_channel)); - d_dump_filename.append(".dat"); - d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); - d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "Telemetry decoder dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str(); - } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); - } - } - } -} - - -int galileo_e1b_telemetry_decoder_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), - gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) -{ - int32_t corr_value = 0; - int32_t preamble_diff = 0; - - Gnss_Synchro **out = reinterpret_cast(&output_items[0]); // Get the output buffer pointer - const Gnss_Synchro **in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer - - Gnss_Synchro current_symbol; // structure to save the synchronization information and send the output object to the next block - // 1. Copy the current tracking output - current_symbol = in[0][0]; - d_symbol_history.push_back(current_symbol); // add new symbol to the symbol queue - d_sample_counter++; // count for the processed samples - consume_each(1); - - d_flag_preamble = false; - uint32_t required_symbols = static_cast(GALILEO_INAV_PAGE_SYMBOLS) + static_cast(d_symbols_per_preamble); - - if (d_symbol_history.size() > required_symbols) - { - // TODO Optimize me! - // ******* preamble correlation ******** - for (int32_t i = 0; i < d_symbols_per_preamble; i++) - { - if (d_symbol_history.at(i).Prompt_I < 0) // symbols clipping - { - corr_value -= d_preambles_symbols[i]; - } - else - { - corr_value += d_preambles_symbols[i]; - } - } - } - - // ******* frame sync ****************** - if (d_stat == 0) // no preamble information - { - if (abs(corr_value) >= d_symbols_per_preamble) - { - d_preamble_index = d_sample_counter; // record the preamble sample stamp - LOG(INFO) << "Preamble detection for Galileo satellite " << this->d_satellite; - d_stat = 1; // enter into frame pre-detection status - } - } - else if (d_stat == 1) // possible preamble lock - { - if (abs(corr_value) >= d_symbols_per_preamble) - { - // check preamble separation - preamble_diff = static_cast(d_sample_counter - d_preamble_index); - if (abs(preamble_diff - GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS) == 0) - { - // try to decode frame - LOG(INFO) << "Starting page decoder for Galileo satellite " << this->d_satellite; - d_preamble_index = d_sample_counter; // record the preamble sample stamp - d_stat = 2; - } - else - { - if (preamble_diff > GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS) - { - d_stat = 0; // start again - } - } - } - } - else if (d_stat == 2) - { - if (d_sample_counter == d_preamble_index + static_cast(GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS)) - { - // NEW Galileo page part is received - // 0. fetch the symbols into an array - int32_t frame_length = GALILEO_INAV_PAGE_PART_SYMBOLS - d_symbols_per_preamble; - double *page_part_symbols = static_cast(volk_gnsssdr_malloc(frame_length * sizeof(double), volk_gnsssdr_get_alignment())); - - for (int32_t i = 0; i < frame_length; i++) - { - if (corr_value > 0) - { - page_part_symbols[i] = d_symbol_history.at(i + d_symbols_per_preamble).Prompt_I; // because last symbol of the preamble is just received now! - } - else - { - page_part_symbols[i] = -d_symbol_history.at(i + d_symbols_per_preamble).Prompt_I; // because last symbol of the preamble is just received now! - } - } - - // call the decoder - decode_word(page_part_symbols, frame_length); - if (d_nav.flag_CRC_test == true) - { - d_CRC_error_counter = 0; - d_flag_preamble = true; // valid preamble indicator (initialized to false every work()) - d_preamble_index = d_sample_counter; // record the preamble sample stamp (t_P) - if (!d_flag_frame_sync) - { - d_flag_frame_sync = true; - DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at " - << d_symbol_history.at(0).Tracking_sample_counter << " [samples]"; - } - } - else - { - d_CRC_error_counter++; - d_preamble_index = d_sample_counter; // record the preamble sample stamp - if (d_CRC_error_counter > CRC_ERROR_LIMIT) - { - LOG(INFO) << "Lost of frame sync SAT " << this->d_satellite; - d_flag_frame_sync = false; - d_stat = 0; - d_TOW_at_current_symbol_ms = 0; - d_TOW_at_Preamble_ms = 0; - d_nav.flag_TOW_set = false; - } - } - volk_gnsssdr_free(page_part_symbols); - } - } - - // UPDATE GNSS SYNCHRO DATA - // 2. Add the telemetry decoder information - if (this->d_flag_preamble == true and d_nav.flag_TOW_set == true) - // update TOW at the preamble instant - { - if (d_nav.flag_TOW_5 == true) // page 5 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec) - { - // TOW_5 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later plus the decoding delay - d_TOW_at_Preamble_ms = static_cast(d_nav.TOW_5 * 1000.0); - d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast(GALILEO_INAV_PAGE_PART_MS + (required_symbols + 1) * GALILEO_E1_CODE_PERIOD_MS); - d_nav.flag_TOW_5 = false; - } - - else if (d_nav.flag_TOW_6 == true) // page 6 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec) - { - // TOW_6 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later plus the decoding delay - d_TOW_at_Preamble_ms = static_cast(d_nav.TOW_6 * 1000.0); - d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast(GALILEO_INAV_PAGE_PART_MS + (required_symbols + 1) * GALILEO_E1_CODE_PERIOD_MS); - d_nav.flag_TOW_6 = false; - } - else - { - // this page has no timing information - d_TOW_at_current_symbol_ms += static_cast(GALILEO_E1_CODE_PERIOD_MS); // + GALILEO_INAV_PAGE_PART_SYMBOLS*GALILEO_E1_CODE_PERIOD; - } - } - else // if there is not a new preamble, we define the TOW of the current symbol - { - if (d_nav.flag_TOW_set == true) - { - d_TOW_at_current_symbol_ms += static_cast(GALILEO_E1_CODE_PERIOD_MS); - } - } - - // remove used symbols from history - // todo: Use circular buffer here - if (d_symbol_history.size() > required_symbols) - { - d_symbol_history.pop_front(); - } - - if (d_nav.flag_TOW_set) - { - if (d_nav.flag_GGTO_1 == true and d_nav.flag_GGTO_2 == true and d_nav.flag_GGTO_3 == true and d_nav.flag_GGTO_4 == true) // all GGTO parameters arrived - { - delta_t = d_nav.A_0G_10 + d_nav.A_1G_10 * (static_cast(d_TOW_at_current_symbol_ms) / 1000.0 - d_nav.t_0G_10 + 604800.0 * (fmod((d_nav.WN_0 - d_nav.WN_0G_10), 64.0))); - } - - current_symbol.Flag_valid_word = d_nav.flag_TOW_set; - current_symbol.TOW_at_current_symbol_ms = d_TOW_at_current_symbol_ms; - // todo: Galileo to GPS time conversion should be moved to observable block. - // current_symbol.TOW_at_current_symbol_ms -= delta_t; //Galileo to GPS TOW - - if (d_dump == true) - { - // MULTIPLEXED FILE RECORDING - Record results to file - try - { - double tmp_double; - uint64_t tmp_ulong_int; - tmp_double = static_cast(d_TOW_at_current_symbol_ms) / 1000.0; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_ulong_int = current_symbol.Tracking_sample_counter; - d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(uint64_t)); - tmp_double = static_cast(d_TOW_at_Preamble_ms) / 1000.0; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "Exception writing observables dump file " << e.what(); - } - } - // 3. Make the output (copy the object contents to the GNURadio reserved memory) - *out[0] = current_symbol; - return 1; - } - else - { - return 0; - } -} 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 deleted file mode 100644 index b033627e7..000000000 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc +++ /dev/null @@ -1,513 +0,0 @@ -/*! - * \file galileo_e5a_telemetry_decoder_cc.cc - * \brief Implementation of a Galileo FNAV message demodulator block - * \author Marc Sales, 2014. marcsales92(at)gmail.com - * Javier Arribas, 2017. jarribas(at)cttc.es - * \based on work from: - *
          - *
        • Javier Arribas, 2011. 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 "galileo_e5a_telemetry_decoder_cc.h" -#include "control_message_factory.h" -#include "convolutional.h" -#include "display.h" -#include -#include -#include -#include -#include -#include - - -#define GALILEO_E5a_CRC_ERROR_LIMIT 6 - -using google::LogMessage; - - -galileo_e5a_telemetry_decoder_cc_sptr -galileo_e5a_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump) -{ - return galileo_e5a_telemetry_decoder_cc_sptr(new galileo_e5a_telemetry_decoder_cc(satellite, dump)); -} - - -void galileo_e5a_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols, int32_t *page_part_bits) -{ - Viterbi(page_part_bits, out0, state0, out1, state1, - page_part_symbols, KK, nn, DataLength); -} - - -void galileo_e5a_telemetry_decoder_cc::deinterleaver(int32_t rows, int32_t cols, double *in, double *out) -{ - for (int32_t r = 0; r < rows; r++) - { - for (int32_t c = 0; c < cols; c++) - { - out[c * rows + r] = in[r * cols + c]; - } - } -} - - -void galileo_e5a_telemetry_decoder_cc::decode_word(double *page_symbols, int32_t frame_length) -{ - // 1. De-interleave - double *page_symbols_deint = static_cast(volk_gnsssdr_malloc(frame_length * sizeof(double), volk_gnsssdr_get_alignment())); - deinterleaver(GALILEO_FNAV_INTERLEAVER_ROWS, GALILEO_FNAV_INTERLEAVER_COLS, page_symbols, page_symbols_deint); - - // 2. Viterbi decoder - // 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder) - // 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180� - for (int32_t i = 0; i < frame_length; i++) - { - if ((i + 1) % 2 == 0) - { - page_symbols_deint[i] = -page_symbols_deint[i]; - } - } - int32_t *page_bits = static_cast(volk_gnsssdr_malloc((frame_length / 2) * sizeof(int32_t), volk_gnsssdr_get_alignment())); - viterbi_decoder(page_symbols_deint, page_bits); - volk_gnsssdr_free(page_symbols_deint); - - // 3. Call the Galileo page decoder - std::string page_String; - for (int32_t i = 0; i < frame_length; i++) - { - if (page_bits[i] > 0) - { - page_String.push_back('1'); - } - else - { - page_String.push_back('0'); - } - } - volk_gnsssdr_free(page_bits); - - // DECODE COMPLETE WORD (even + odd) and TEST CRC - d_nav.split_page(page_String); - if (d_nav.flag_CRC_test == true) - { - LOG(INFO) << "Galileo E5a CRC correct in channel " << d_channel << " from satellite " << d_satellite; - } - else - { - std::cout << "Galileo E5a CRC error in channel " << d_channel << " from satellite " << d_satellite << std::endl; - LOG(INFO) << "Galileo E5a CRC error in channel " << d_channel << " from satellite " << d_satellite; - } - - // 4. Push the new navigation data to the queues - if (d_nav.have_new_ephemeris() == true) - { - std::shared_ptr tmp_obj = std::make_shared(d_nav.get_ephemeris()); - std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " << d_channel << ": ephemeris from satellite " << d_satellite << TEXT_RESET << std::endl; - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } - if (d_nav.have_new_iono_and_GST() == true) - { - std::shared_ptr tmp_obj = std::make_shared(d_nav.get_iono()); - std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " << d_channel << ": iono/GST model parameters from satellite " << d_satellite << TEXT_RESET << std::endl; - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } - if (d_nav.have_new_utc_model() == true) - { - std::shared_ptr tmp_obj = std::make_shared(d_nav.get_utc_model()); - std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " << d_channel << ": UTC model parameters from satellite " << d_satellite << TEXT_RESET << std::endl; - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } -} - - -galileo_e5a_telemetry_decoder_cc::galileo_e5a_telemetry_decoder_cc( - const Gnss_Satellite &satellite, bool dump) : gr::block("galileo_e5a_telemetry_decoder_cc", - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) -{ - // Ephemeris data port out - this->message_port_register_out(pmt::mp("telemetry")); - // initialize internal vars - d_dump = dump; - d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); - - // set the preamble - for (int32_t i = 0; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++) - { - if (GALILEO_FNAV_PREAMBLE.at(i) == '0') - { - d_preambles_bits[i] = 1; - } - else - { - d_preambles_bits[i] = -1; - } - } - for (int32_t i = 0; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++) - { - for (int32_t k = 0; k < GALILEO_FNAV_CODES_PER_SYMBOL; k++) - { - d_preamble_samples[(i * GALILEO_FNAV_CODES_PER_SYMBOL) + k] = d_preambles_bits[i]; - } - } - - d_sample_counter = 0ULL; - d_stat = 0; - corr_value = 0; - d_flag_preamble = false; - d_preamble_index = 0ULL; - d_flag_frame_sync = false; - d_TOW_at_current_symbol_ms = 0; - d_TOW_at_Preamble_ms = 0; - flag_TOW_set = false; - d_CRC_error_counter = 0; - d_channel = 0; - delta_t = 0.0; - d_symbol_counter = 0; - d_prompt_acum = 0.0; - flag_bit_start = true; - new_symbol = false; - required_symbols = GALILEO_FNAV_SYMBOLS_PER_PAGE + GALILEO_FNAV_PREAMBLE_LENGTH_BITS; - - // vars for Viterbi decoder - int32_t max_states = 1 << mm; // 2^mm - g_encoder[0] = 121; // Polynomial G1 - g_encoder[1] = 91; // Polynomial G2 - out0 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); - out1 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); - state0 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); - state1 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); - // create appropriate transition matrices - nsc_transit(out0, state0, 0, g_encoder, KK, nn); - nsc_transit(out1, state1, 1, g_encoder, KK, nn); -} - - -galileo_e5a_telemetry_decoder_cc::~galileo_e5a_telemetry_decoder_cc() -{ - volk_gnsssdr_free(out0); - volk_gnsssdr_free(out1); - volk_gnsssdr_free(state0); - volk_gnsssdr_free(state1); - if (d_dump_file.is_open() == true) - { - try - { - d_dump_file.close(); - } - catch (const std::exception &ex) - { - LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); - } - } -} - - -void galileo_e5a_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satellite) -{ - d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); - DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite; - DLOG(INFO) << "Navigation Satellite set to " << d_satellite; -} - - -void galileo_e5a_telemetry_decoder_cc::set_channel(int32_t channel) -{ - d_channel = channel; - LOG(INFO) << "Navigation channel set to " << channel; - // Enable data file logging - if (d_dump == true) - { - if (d_dump_file.is_open() == false) - { - try - { - d_dump_filename = "telemetry"; - d_dump_filename.append(boost::lexical_cast(d_channel)); - d_dump_filename.append(".dat"); - d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); - d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "Telemetry decoder dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str(); - } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); - } - } - } -} - - -int galileo_e5a_telemetry_decoder_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), - gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) -{ - int32_t preamble_diff = 0; - - Gnss_Synchro *out = reinterpret_cast(output_items[0]); // Get the output buffer pointer - const Gnss_Synchro *in = reinterpret_cast(input_items[0]); // Get the input buffer pointer - - // 1. Copy the current tracking output - Gnss_Synchro current_sample = in[0]; - d_symbol_counter++; - if (flag_bit_start) - { - d_prompt_acum += current_sample.Prompt_I; - if (d_symbol_counter == GALILEO_FNAV_CODES_PER_SYMBOL) - { - current_sample.Prompt_I = d_prompt_acum / static_cast(GALILEO_FNAV_CODES_PER_SYMBOL); - d_symbol_history.push_back(current_sample); // add new symbol to the symbol queue - d_prompt_acum = 0.0; - d_symbol_counter = 0; - new_symbol = true; - } - } - else - { - if (current_sample.Prompt_I < 0.0) - { - d_preamble_init.push_back(1); - } - else - { - d_preamble_init.push_back(-1); - } - - if (d_preamble_init.size() == GALILEO_FNAV_CODES_PER_PREAMBLE) - { - std::deque::iterator iter; - int32_t k = 0; - corr_value = 0; - for (iter = d_preamble_init.begin(); iter != d_preamble_init.end(); iter++) - { - corr_value += *iter * d_preamble_samples[k]; - k++; - } - if (abs(corr_value) == GALILEO_FNAV_CODES_PER_PREAMBLE) - { - d_symbol_counter = 0; - flag_bit_start = true; - corr_value = 0; - d_preamble_init.clear(); - d_symbol_history.clear(); - LOG(INFO) << "Bit start sync for Galileo E5a satellite " << d_satellite; - } - else - { - d_preamble_init.pop_front(); - } - } - } - d_sample_counter++; // count for the processed samples - consume_each(1); - - d_flag_preamble = false; - - if ((d_symbol_history.size() > required_symbols) && new_symbol) - { - // ****************** Preamble orrelation ****************** - corr_value = 0; - for (int32_t i = 0; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++) - { - if (d_symbol_history.at(i).Prompt_I < 0.0) // symbols clipping - { - corr_value -= d_preambles_bits[i]; - } - else - { - corr_value += d_preambles_bits[i]; - } - } - } - // ****************** Frame sync ****************** - if ((d_stat == 0) && new_symbol) // no preamble information - { - if (abs(corr_value) == GALILEO_FNAV_PREAMBLE_LENGTH_BITS) - { - d_preamble_index = d_sample_counter; // record the preamble sample stamp - LOG(INFO) << "Preamble detection for Galileo E5a satellite " << d_satellite; - d_stat = 1; // enter into frame pre-detection status - } - } - else if ((d_stat == 1) && new_symbol) // possible preamble lock - { - if (abs(corr_value) == GALILEO_FNAV_PREAMBLE_LENGTH_BITS) - { - // check preamble separation - preamble_diff = static_cast(d_sample_counter - d_preamble_index); - if (preamble_diff == GALILEO_FNAV_CODES_PER_PAGE) - { - // try to decode frame - LOG(INFO) << "Starting page decoder for Galileo E5a satellite " << d_satellite; - d_preamble_index = d_sample_counter; // record the preamble sample stamp - d_stat = 2; - } - else if (preamble_diff > GALILEO_FNAV_CODES_PER_PAGE) - { - d_stat = 0; // start again - flag_bit_start = false; - LOG(INFO) << "Preamble diff = " << preamble_diff; - } - } - } - else if ((d_stat == 2) && new_symbol) - { - if (d_sample_counter == (d_preamble_index + static_cast(GALILEO_FNAV_CODES_PER_PAGE))) - { - // NEW Galileo page part is received - // 0. fetch the symbols into an array - int32_t frame_length = GALILEO_FNAV_SYMBOLS_PER_PAGE - GALILEO_FNAV_PREAMBLE_LENGTH_BITS; - double corr_sign = 0.0; - if (corr_value > 0) - { - corr_sign = -1.0; - } - else - { - corr_sign = 1.0; - } - for (int32_t i = 0; i < frame_length; i++) - { - page_symbols[i] = corr_sign * d_symbol_history.at(i + GALILEO_FNAV_PREAMBLE_LENGTH_BITS).Prompt_I; // because last symbol of the preamble is just received now! - } - - // call the decoder - decode_word(page_symbols, frame_length); - if (d_nav.flag_CRC_test == true) - { - d_CRC_error_counter = 0; - d_flag_preamble = true; // valid preamble indicator (initialized to false every work()) - d_preamble_index = d_sample_counter; // record the preamble sample stamp (t_P) - if (!d_flag_frame_sync) - { - d_flag_frame_sync = true; - DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at " - << d_symbol_history.at(0).Tracking_sample_counter << " [samples]"; - } - } - else - { - d_CRC_error_counter++; - d_preamble_index = d_sample_counter; // record the preamble sample stamp - if (d_CRC_error_counter > GALILEO_E5A_CRC_ERROR_LIMIT) - { - LOG(INFO) << "Lost of frame sync SAT " << this->d_satellite; - d_flag_frame_sync = false; - d_stat = 0; - flag_bit_start = false; - d_nav.flag_TOW_set = false; - d_TOW_at_current_symbol_ms = 0; - d_TOW_at_Preamble_ms = 0; - } - } - } - } - new_symbol = false; - - // UPDATE GNSS SYNCHRO DATA - // Add the telemetry decoder information - if (d_flag_preamble and d_nav.flag_TOW_set) - // update TOW at the preamble instant - // We expect a preamble each 10 seconds (FNAV page period) - { - if (d_nav.flag_TOW_1 == true) - { - d_TOW_at_Preamble_ms = static_cast(d_nav.FNAV_TOW_1 * 1000.0); - d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS); - d_nav.flag_TOW_1 = false; - } - else if (d_nav.flag_TOW_2 == true) - { - d_TOW_at_Preamble_ms = static_cast(d_nav.FNAV_TOW_2 * 1000.0); - d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS); - d_nav.flag_TOW_2 = false; - } - else if (d_nav.flag_TOW_3 == true) - { - d_TOW_at_Preamble_ms = static_cast(d_nav.FNAV_TOW_3 * 1000.0); - d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS); - d_nav.flag_TOW_3 = false; - } - else if (d_nav.flag_TOW_4 == true) - { - d_TOW_at_Preamble_ms = static_cast(d_nav.FNAV_TOW_4 * 1000.0); - d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS); - d_nav.flag_TOW_4 = false; - } - else - { - d_TOW_at_current_symbol_ms += static_cast(GALILEO_E5a_CODE_PERIOD_MS); - } - } - else // if there is not a new preamble, we define the TOW of the current symbol - { - if (d_nav.flag_TOW_set == true) - { - d_TOW_at_current_symbol_ms += static_cast(GALILEO_E5a_CODE_PERIOD_MS); - } - } - - // remove used symbols from history - // todo: Use circular buffer here - while (d_symbol_history.size() > required_symbols) - { - d_symbol_history.pop_front(); - } - - if (d_nav.flag_TOW_set) - { - current_sample.Flag_valid_word = true; - current_sample.TOW_at_current_symbol_ms = d_TOW_at_current_symbol_ms; - if (d_dump) - { - // MULTIPLEXED FILE RECORDING - Record results to file - try - { - double tmp_double; - uint64_t tmp_ulong_int; - tmp_double = static_cast(d_TOW_at_current_symbol_ms) / 1000.0; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_ulong_int = current_sample.Tracking_sample_counter; - d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(uint64_t)); - tmp_double = static_cast(d_TOW_at_Preamble_ms) / 1000.0; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "Exception writing Galileo E5a Telemetry Decoder dump file " << e.what(); - } - } - // 3. Make the output - out[0] = current_sample; - return 1; - } - else - { - return 0; - } -} diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.h deleted file mode 100644 index 522f5777e..000000000 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.h +++ /dev/null @@ -1,127 +0,0 @@ -/*! - * \file galileo_e5a_telemetry_decoder_cc.cc - * \brief Implementation of a Galileo FNAV message demodulator block - * \author Marc Sales, 2014. marcsales92(at)gmail.com - * Javier Arribas, 2017. jarribas(at)cttc.es - * \based on work from: - *
          - *
        • Javier Arribas, 2011. 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 GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_CC_H_ -#define GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_CC_H_ - -#include "Galileo_E5a.h" -#include "gnss_satellite.h" -#include "galileo_fnav_message.h" -#include "galileo_ephemeris.h" -#include "galileo_almanac.h" -#include "galileo_iono.h" -#include "galileo_utc_model.h" -#include "gnss_synchro.h" -#include -#include -#include -#include - - -class galileo_e5a_telemetry_decoder_cc; - -typedef boost::shared_ptr galileo_e5a_telemetry_decoder_cc_sptr; - -galileo_e5a_telemetry_decoder_cc_sptr galileo_e5a_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - - -/*! - * \brief This class implements a block that decodes the FNAV data defined in Galileo ICD - * - */ -class galileo_e5a_telemetry_decoder_cc : public gr::block -{ -public: - ~galileo_e5a_telemetry_decoder_cc(); - void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN - void set_channel(int32_t 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 galileo_e5a_telemetry_decoder_cc_sptr - galileo_e5a_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - galileo_e5a_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - - void viterbi_decoder(double *page_part_symbols, int32_t *page_part_bits); - - void deinterleaver(int32_t rows, int32_t cols, double *in, double *out); - - void decode_word(double *page_symbols, int32_t frame_length); - - int32_t d_preambles_bits[GALILEO_FNAV_PREAMBLE_LENGTH_BITS]; - int32_t d_preamble_samples[GALILEO_FNAV_CODES_PER_PREAMBLE]; - std::deque d_preamble_init; - int32_t d_stat; - int32_t d_CRC_error_counter; - int32_t d_channel; - int32_t d_symbol_counter; - int32_t corr_value; - uint32_t required_symbols; - uint64_t d_sample_counter; - uint64_t d_preamble_index; - bool d_flag_frame_sync; - bool d_flag_preamble; - bool d_dump; - bool flag_TOW_set; - bool flag_bit_start; - bool new_symbol; - double d_prompt_acum; - double page_symbols[GALILEO_FNAV_SYMBOLS_PER_PAGE - GALILEO_FNAV_PREAMBLE_LENGTH_BITS]; - uint32_t d_TOW_at_Preamble_ms; - uint32_t d_TOW_at_current_symbol_ms; - double delta_t; //GPS-GALILEO time offset - std::string d_dump_filename; - std::ofstream d_dump_file; - std::deque d_symbol_history; - Gnss_Satellite d_satellite; - // navigation message vars - Galileo_Fnav_Message d_nav; - - // vars for Viterbi decoder - int32_t *out0, *out1, *state0, *state1; - int32_t g_encoder[2]; - const int32_t nn = 2; // Coding rate 1/n - const int32_t KK = 7; // Constraint Length - int32_t mm = KK - 1; - const int32_t CodeLength = 488; - int32_t DataLength = (CodeLength / nn) - mm; -}; - -#endif /* GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_CC_H_ */ diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.cc new file mode 100644 index 000000000..aa53529fe --- /dev/null +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.cc @@ -0,0 +1,780 @@ +/*! + * \file galileo_telemetry_decoder_cc.cc + * \brief Implementation of a Galileo unified INAV and FNAV message demodulator block + * \author Javier Arribas 2018. 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 "galileo_telemetry_decoder_cc.h" +#include "control_message_factory.h" +#include "convolutional.h" +#include "display.h" +#include "gnss_synchro.h" +#include +#include +#include +#include +#include + + +#define CRC_ERROR_LIMIT 6 + +using google::LogMessage; + + +galileo_telemetry_decoder_cc_sptr +galileo_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, int frame_type, bool dump) +{ + return galileo_telemetry_decoder_cc_sptr(new galileo_telemetry_decoder_cc(satellite, frame_type, dump)); +} + + +void galileo_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols, int32_t *page_part_bits) +{ + Viterbi(page_part_bits, out0, state0, out1, state1, + page_part_symbols, KK, nn, DataLength); +} + + +void galileo_telemetry_decoder_cc::deinterleaver(int32_t rows, int32_t cols, double *in, double *out) +{ + for (int32_t r = 0; r < rows; r++) + { + for (int32_t c = 0; c < cols; c++) + { + out[c * rows + r] = in[r * cols + c]; + } + } +} + + +galileo_telemetry_decoder_cc::galileo_telemetry_decoder_cc( + const Gnss_Satellite &satellite, int frame_type, + bool dump) : gr::block("galileo_telemetry_decoder_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) +{ + // Ephemeris data port out + this->message_port_register_out(pmt::mp("telemetry")); + // initialize internal vars + d_dump = dump; + d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); + d_frame_type = frame_type; + LOG(INFO) << "Initializing GALILEO UNIFIED TELEMETRY DECODER"; + + switch (d_frame_type) + { + case 1: //INAV + { + d_PRN_code_period_ms = static_cast(GALILEO_E1_CODE_PERIOD_MS); + d_samples_per_symbol = Galileo_E1_B_SAMPLES_PER_SYMBOL; + d_bits_per_preamble = GALILEO_INAV_PREAMBLE_LENGTH_BITS; + // set the preamble + d_samples_per_preamble = GALILEO_INAV_PREAMBLE_LENGTH_BITS * d_samples_per_symbol; + d_preamble_period_symbols = GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS; + d_required_symbols = static_cast(GALILEO_INAV_PAGE_SYMBOLS) + d_samples_per_preamble; + // preamble bits to sampled symbols + d_preamble_samples = static_cast(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment())); + d_frame_length_symbols = GALILEO_INAV_PAGE_PART_SYMBOLS - GALILEO_INAV_PREAMBLE_LENGTH_BITS; + CodeLength = GALILEO_INAV_PAGE_PART_SYMBOLS - GALILEO_INAV_PREAMBLE_LENGTH_BITS; + DataLength = (CodeLength / nn) - mm; + break; + } + case 2: //FNAV + { + d_PRN_code_period_ms = static_cast(GALILEO_E5a_CODE_PERIOD_MS); + d_samples_per_symbol = GALILEO_FNAV_CODES_PER_SYMBOL; + d_bits_per_preamble = GALILEO_FNAV_PREAMBLE_LENGTH_BITS; + // set the preamble + d_samples_per_preamble = GALILEO_FNAV_PREAMBLE_LENGTH_BITS * d_samples_per_symbol; + d_preamble_period_symbols = GALILEO_FNAV_CODES_PER_PAGE; + d_required_symbols = static_cast(GALILEO_FNAV_SYMBOLS_PER_PAGE) * d_samples_per_symbol + d_samples_per_preamble; + // preamble bits to sampled symbols + d_preamble_samples = static_cast(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment())); + + d_secondary_code_samples = static_cast(volk_gnsssdr_malloc(Galileo_E5a_I_SECONDARY_CODE_LENGTH * sizeof(int32_t), volk_gnsssdr_get_alignment())); + d_frame_length_symbols = GALILEO_FNAV_SYMBOLS_PER_PAGE - GALILEO_FNAV_PREAMBLE_LENGTH_BITS; + CodeLength = GALILEO_FNAV_SYMBOLS_PER_PAGE - GALILEO_FNAV_PREAMBLE_LENGTH_BITS; + DataLength = (CodeLength / nn) - mm; + for (int32_t i = 0; i < Galileo_E5a_I_SECONDARY_CODE_LENGTH; i++) + { + if (Galileo_E5a_I_SECONDARY_CODE.at(i) == '1') + { + d_secondary_code_samples[i] = 1; + } + else + { + d_secondary_code_samples[i] = -1; + } + } + break; + } + default: + std::cout << "Galileo unified telemetry decoder error: Unknown frame type " << std::endl; + } + + d_page_part_symbols = static_cast(volk_gnsssdr_malloc(d_frame_length_symbols * sizeof(double), volk_gnsssdr_get_alignment())); + int32_t n = 0; + for (int32_t i = 0; i < d_bits_per_preamble; i++) + { + switch (d_frame_type) + { + case 1: //INAV + { + if (GALILEO_INAV_PREAMBLE.at(i) == '1') + { + for (uint32_t j = 0; j < d_samples_per_symbol; j++) + { + d_preamble_samples[n] = 1; + n++; + } + } + else + { + for (uint32_t j = 0; j < d_samples_per_symbol; j++) + { + d_preamble_samples[n] = -1; + n++; + } + } + break; + } + case 2: //FNAV for E5a-I + { + // Galileo E5a data channel (E5a-I) still has a secondary code + int m = 0; + if (GALILEO_FNAV_PREAMBLE.at(i) == '1') + { + for (uint32_t j = 0; j < d_samples_per_symbol; j++) + { + d_preamble_samples[n] = d_secondary_code_samples[m]; + n++; + m++; + m = m % Galileo_E5a_I_SECONDARY_CODE_LENGTH; + } + } + else + { + for (uint32_t j = 0; j < d_samples_per_symbol; j++) + { + d_preamble_samples[n] = -d_secondary_code_samples[m]; + n++; + m++; + m = m % Galileo_E5a_I_SECONDARY_CODE_LENGTH; + } + } + break; + } + } + } + d_sample_counter = 0ULL; + d_stat = 0; + d_preamble_index = 0ULL; + + d_flag_frame_sync = false; + + d_flag_parity = false; + d_TOW_at_current_symbol_ms = 0; + d_TOW_at_Preamble_ms = 0; + delta_t = 0; + d_CRC_error_counter = 0; + flag_even_word_arrived = 0; + d_flag_preamble = false; + d_channel = 0; + flag_TOW_set = false; + + // vars for Viterbi decoder + int32_t max_states = 1 << mm; // 2^mm + g_encoder[0] = 121; // Polynomial G1 + g_encoder[1] = 91; // Polynomial G2 + out0 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); + out1 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); + state0 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); + state1 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); + // create appropriate transition matrices + nsc_transit(out0, state0, 0, g_encoder, KK, nn); + nsc_transit(out1, state1, 1, g_encoder, KK, nn); +} + + +galileo_telemetry_decoder_cc::~galileo_telemetry_decoder_cc() +{ + volk_gnsssdr_free(d_preamble_samples); + if (d_frame_type == 2) + { + volk_gnsssdr_free(d_secondary_code_samples); + } + volk_gnsssdr_free(d_page_part_symbols); + volk_gnsssdr_free(out0); + volk_gnsssdr_free(out1); + volk_gnsssdr_free(state0); + volk_gnsssdr_free(state1); + if (d_dump_file.is_open() == true) + { + try + { + d_dump_file.close(); + } + catch (const std::exception &ex) + { + LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); + } + } +} + + +void galileo_telemetry_decoder_cc::decode_INAV_word(double *page_part_symbols, int32_t frame_length) +{ + // 1. De-interleave + double *page_part_symbols_deint = static_cast(volk_gnsssdr_malloc(frame_length * sizeof(double), volk_gnsssdr_get_alignment())); + deinterleaver(GALILEO_INAV_INTERLEAVER_ROWS, GALILEO_INAV_INTERLEAVER_COLS, page_part_symbols, page_part_symbols_deint); + + // 2. Viterbi decoder + // 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder) + // 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180º + for (int32_t i = 0; i < frame_length; i++) + { + if ((i + 1) % 2 == 0) + { + page_part_symbols_deint[i] = -page_part_symbols_deint[i]; + } + } + + int32_t *page_part_bits = static_cast(volk_gnsssdr_malloc((frame_length / 2) * sizeof(int32_t), volk_gnsssdr_get_alignment())); + viterbi_decoder(page_part_symbols_deint, page_part_bits); + volk_gnsssdr_free(page_part_symbols_deint); + + // 3. Call the Galileo page decoder + std::string page_String; + for (int32_t i = 0; i < (frame_length / 2); i++) + { + if (page_part_bits[i] > 0) + { + page_String.push_back('1'); + } + else + { + page_String.push_back('0'); + } + } + + if (page_part_bits[0] == 1) + { + // DECODE COMPLETE WORD (even + odd) and TEST CRC + d_inav_nav.split_page(page_String, flag_even_word_arrived); + if (d_inav_nav.flag_CRC_test == true) + { + LOG(INFO) << "Galileo E1 CRC correct in channel " << d_channel << " from satellite " << d_satellite; + } + else + { + LOG(INFO) << "Galileo E1 CRC error in channel " << d_channel << " from satellite " << d_satellite; + } + flag_even_word_arrived = 0; + } + else + { + // STORE HALF WORD (even page) + d_inav_nav.split_page(page_String.c_str(), flag_even_word_arrived); + flag_even_word_arrived = 1; + } + volk_gnsssdr_free(page_part_bits); + + // 4. Push the new navigation data to the queues + if (d_inav_nav.have_new_ephemeris() == true) + { + // get object for this SV (mandatory) + std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_ephemeris()); + std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel << ": ephemeris from satellite " << d_satellite << std::endl; + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + if (d_inav_nav.have_new_iono_and_GST() == true) + { + // get object for this SV (mandatory) + std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_iono()); + std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel << ": iono/GST model parameters from satellite " << d_satellite << std::endl; + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + if (d_inav_nav.have_new_utc_model() == true) + { + // get object for this SV (mandatory) + std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_utc_model()); + std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel << ": UTC model parameters from satellite " << d_satellite << std::endl; + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + if (d_inav_nav.have_new_almanac() == true) + { + std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_almanac()); + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + //debug + std::cout << "Galileo E1 I/NAV almanac received in channel " << d_channel << " from satellite " << d_satellite << std::endl; + DLOG(INFO) << "GPS_to_Galileo time conversion:"; + DLOG(INFO) << "A0G=" << tmp_obj->A_0G_10; + DLOG(INFO) << "A1G=" << tmp_obj->A_1G_10; + DLOG(INFO) << "T0G=" << tmp_obj->t_0G_10; + DLOG(INFO) << "WN_0G_10=" << tmp_obj->WN_0G_10; + DLOG(INFO) << "Current parameters:"; + DLOG(INFO) << "d_TOW_at_current_symbol_ms=" << d_TOW_at_current_symbol_ms; + DLOG(INFO) << "d_nav.WN_0=" << d_inav_nav.WN_0; + delta_t = tmp_obj->A_0G_10 + tmp_obj->A_1G_10 * (static_cast(d_TOW_at_current_symbol_ms) / 1000.0 - tmp_obj->t_0G_10 + 604800 * (fmod((d_inav_nav.WN_0 - tmp_obj->WN_0G_10), 64))); + DLOG(INFO) << "delta_t=" << delta_t << "[s]"; + } +} + + +void galileo_telemetry_decoder_cc::decode_FNAV_word(double *page_symbols, int32_t frame_length) +{ + // 1. De-interleave + double *page_symbols_deint = static_cast(volk_gnsssdr_malloc(frame_length * sizeof(double), volk_gnsssdr_get_alignment())); + deinterleaver(GALILEO_FNAV_INTERLEAVER_ROWS, GALILEO_FNAV_INTERLEAVER_COLS, page_symbols, page_symbols_deint); + + // 2. Viterbi decoder + // 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder) + // 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180� + for (int32_t i = 0; i < frame_length; i++) + { + if ((i + 1) % 2 == 0) + { + page_symbols_deint[i] = -page_symbols_deint[i]; + } + } + int32_t *page_bits = static_cast(volk_gnsssdr_malloc((frame_length / 2) * sizeof(int32_t), volk_gnsssdr_get_alignment())); + viterbi_decoder(page_symbols_deint, page_bits); + volk_gnsssdr_free(page_symbols_deint); + + // 3. Call the Galileo page decoder + std::string page_String; + for (int32_t i = 0; i < frame_length; i++) + { + if (page_bits[i] > 0) + { + page_String.push_back('1'); + } + else + { + page_String.push_back('0'); + } + } + volk_gnsssdr_free(page_bits); + + // DECODE COMPLETE WORD (even + odd) and TEST CRC + d_fnav_nav.split_page(page_String); + if (d_fnav_nav.flag_CRC_test == true) + { + LOG(INFO) << "Galileo E5a CRC correct in channel " << d_channel << " from satellite " << d_satellite; + } + else + { + LOG(INFO) << "Galileo E5a CRC error in channel " << d_channel << " from satellite " << d_satellite; + } + + // 4. Push the new navigation data to the queues + if (d_fnav_nav.have_new_ephemeris() == true) + { + std::shared_ptr tmp_obj = std::make_shared(d_fnav_nav.get_ephemeris()); + std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " << d_channel << ": ephemeris from satellite " << d_satellite << TEXT_RESET << std::endl; + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + if (d_fnav_nav.have_new_iono_and_GST() == true) + { + std::shared_ptr tmp_obj = std::make_shared(d_fnav_nav.get_iono()); + std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " << d_channel << ": iono/GST model parameters from satellite " << d_satellite << TEXT_RESET << std::endl; + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + if (d_fnav_nav.have_new_utc_model() == true) + { + std::shared_ptr tmp_obj = std::make_shared(d_fnav_nav.get_utc_model()); + std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " << d_channel << ": UTC model parameters from satellite " << d_satellite << TEXT_RESET << std::endl; + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } +} + +void galileo_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satellite) +{ + d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); + DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite; + DLOG(INFO) << "Navigation Satellite set to " << d_satellite; +} + + +void galileo_telemetry_decoder_cc::set_channel(int32_t channel) +{ + d_channel = channel; + LOG(INFO) << "Navigation channel set to " << channel; + // ############# ENABLE DATA FILE LOG ################# + if (d_dump == true) + { + if (d_dump_file.is_open() == false) + { + try + { + d_dump_filename = "telemetry"; + d_dump_filename.append(boost::lexical_cast(d_channel)); + d_dump_filename.append(".dat"); + d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "Telemetry decoder dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str(); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); + } + } + } +} + + +int galileo_telemetry_decoder_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) +{ + int32_t corr_value = 0; + int32_t preamble_diff = 0; + + Gnss_Synchro **out = reinterpret_cast(&output_items[0]); // Get the output buffer pointer + const Gnss_Synchro **in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer + + Gnss_Synchro current_symbol; // structure to save the synchronization information and send the output object to the next block + // 1. Copy the current tracking output + current_symbol = in[0][0]; + // add new symbol to the symbol queue + d_symbol_history.push_back(current_symbol.Prompt_I); + d_sample_counter++; // count for the processed samples + consume_each(1); + d_flag_preamble = false; + + if (d_symbol_history.size() > d_required_symbols) + { + // TODO Optimize me! + // ******* preamble correlation ******** + for (int32_t i = 0; i < d_samples_per_preamble; i++) + { + if (d_symbol_history.at(i) < 0.0) // symbols clipping + { + corr_value -= d_preamble_samples[i]; + } + else + { + corr_value += d_preamble_samples[i]; + } + } + } + + // ******* frame sync ****************** + switch (d_stat) + { + case 0: // no preamble information + { + if (abs(corr_value) >= d_samples_per_preamble) + { + d_preamble_index = d_sample_counter; // record the preamble sample stamp + LOG(INFO) << "Preamble detection for Galileo satellite " << this->d_satellite; + d_stat = 1; // enter into frame pre-detection status + } + break; + } + case 1: // possible preamble lock + { + if (abs(corr_value) >= d_samples_per_preamble) + { + // check preamble separation + preamble_diff = static_cast(d_sample_counter - d_preamble_index); + if (abs(preamble_diff - d_preamble_period_symbols) == 0) + { + // try to decode frame + LOG(INFO) << "Starting page decoder for Galileo satellite " << this->d_satellite; + d_preamble_index = d_sample_counter; // record the preamble sample stamp + d_stat = 2; + } + else + { + if (preamble_diff > d_preamble_period_symbols) + { + d_stat = 0; // start again + } + } + } + break; + } + case 2: //preamble acquired + { + if (d_sample_counter == d_preamble_index + static_cast(d_preamble_period_symbols)) + { + // call the decoder + switch (d_frame_type) + { + case 1: //INAV + // NEW Galileo page part is received + // 0. fetch the symbols into an array + if (corr_value > 0) //normal PLL lock + { + for (uint32_t i = 0; i < d_frame_length_symbols; i++) + { + d_page_part_symbols[i] = d_symbol_history.at(i + d_samples_per_preamble); // because last symbol of the preamble is just received now! + } + } + else //180 deg. inverted carrier phase PLL lock + { + for (uint32_t i = 0; i < d_frame_length_symbols; i++) + { + d_page_part_symbols[i] = d_symbol_history.at(i + d_samples_per_preamble); // because last symbol of the preamble is just received now! + } + } + decode_INAV_word(d_page_part_symbols, d_frame_length_symbols); + break; + case 2: //FNAV + // NEW Galileo page part is received + // 0. fetch the symbols into an array + if (corr_value > 0) //normal PLL lock + { + int k = 0; + for (uint32_t i = 0; i < d_frame_length_symbols; i++) + { + d_page_part_symbols[i] = 0; + for (uint32_t m = 0; m < d_samples_per_symbol; m++) + { + d_page_part_symbols[i] += static_cast(d_secondary_code_samples[k]) * d_symbol_history.at(i * d_samples_per_symbol + d_samples_per_preamble + m); // because last symbol of the preamble is just received now! + k++; + k = k % Galileo_E5a_I_SECONDARY_CODE_LENGTH; + } + } + } + else //180 deg. inverted carrier phase PLL lock + { + int k = 0; + for (uint32_t i = 0; i < d_frame_length_symbols; i++) + { + d_page_part_symbols[i] = 0; + for (uint32_t m = 0; m < d_samples_per_symbol; m++) //integrate samples into symbols + { + d_page_part_symbols[i] -= static_cast(d_secondary_code_samples[k]) * d_symbol_history.at(i * d_samples_per_symbol + d_samples_per_preamble + m); // because last symbol of the preamble is just received now! + k++; + k = k % Galileo_E5a_I_SECONDARY_CODE_LENGTH; + } + } + } + decode_FNAV_word(d_page_part_symbols, d_frame_length_symbols); + break; + default: + return -1; + break; + } + + if (d_inav_nav.flag_CRC_test == true or d_fnav_nav.flag_CRC_test == true) + { + d_CRC_error_counter = 0; + d_flag_preamble = true; // valid preamble indicator (initialized to false every work()) + d_preamble_index = d_sample_counter; // record the preamble sample stamp (t_P) + if (!d_flag_frame_sync) + { + d_flag_frame_sync = true; + DLOG(INFO) << " Frame sync SAT " << this->d_satellite; + } + } + else + { + d_CRC_error_counter++; + d_preamble_index = d_sample_counter; // record the preamble sample stamp + if (d_CRC_error_counter > CRC_ERROR_LIMIT) + { + LOG(INFO) << "Lost of frame sync SAT " << this->d_satellite; + d_flag_frame_sync = false; + d_stat = 0; + d_TOW_at_current_symbol_ms = 0; + d_TOW_at_Preamble_ms = 0; + d_fnav_nav.flag_TOW_set = false; + d_inav_nav.flag_TOW_set = false; + } + } + } + break; + } + } + + // UPDATE GNSS SYNCHRO DATA + // 2. Add the telemetry decoder information + if (this->d_flag_preamble == true) + // update TOW at the preamble instant + { + switch (d_frame_type) + { + case 1: //INAV + { + if (d_inav_nav.flag_TOW_set == true) + { + if (d_inav_nav.flag_TOW_5 == true) // page 5 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec) + { + // TOW_5 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later plus the decoding delay + d_TOW_at_Preamble_ms = static_cast(d_inav_nav.TOW_5 * 1000.0); + d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast(GALILEO_INAV_PAGE_PART_MS + (d_required_symbols + 1) * GALILEO_E1_CODE_PERIOD_MS); + d_inav_nav.flag_TOW_5 = false; + } + + else if (d_inav_nav.flag_TOW_6 == true) // page 6 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec) + { + // TOW_6 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later plus the decoding delay + d_TOW_at_Preamble_ms = static_cast(d_inav_nav.TOW_6 * 1000.0); + d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast(GALILEO_INAV_PAGE_PART_MS + (d_required_symbols + 1) * GALILEO_E1_CODE_PERIOD_MS); + d_inav_nav.flag_TOW_6 = false; + } + else + { + // this page has no timing information + d_TOW_at_current_symbol_ms += static_cast(GALILEO_E1_CODE_PERIOD_MS); // + GALILEO_INAV_PAGE_PART_SYMBOLS*GALILEO_E1_CODE_PERIOD; + } + } + break; + } + case 2: //FNAV + { + if (d_fnav_nav.flag_TOW_set == true) + { + if (d_fnav_nav.flag_TOW_1 == true) + { + d_TOW_at_Preamble_ms = static_cast(d_fnav_nav.FNAV_TOW_1 * 1000.0); + d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((d_required_symbols + 1) * GALILEO_E5a_CODE_PERIOD_MS); + //d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS); + d_fnav_nav.flag_TOW_1 = false; + } + else if (d_fnav_nav.flag_TOW_2 == true) + { + d_TOW_at_Preamble_ms = static_cast(d_fnav_nav.FNAV_TOW_2 * 1000.0); + //d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS); + d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((d_required_symbols + 1) * GALILEO_E5a_CODE_PERIOD_MS); + d_fnav_nav.flag_TOW_2 = false; + } + else if (d_fnav_nav.flag_TOW_3 == true) + { + d_TOW_at_Preamble_ms = static_cast(d_fnav_nav.FNAV_TOW_3 * 1000.0); + //d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS); + d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((d_required_symbols + 1) * GALILEO_E5a_CODE_PERIOD_MS); + d_fnav_nav.flag_TOW_3 = false; + } + else if (d_fnav_nav.flag_TOW_4 == true) + { + d_TOW_at_Preamble_ms = static_cast(d_fnav_nav.FNAV_TOW_4 * 1000.0); + //d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS); + d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((d_required_symbols + 1) * GALILEO_E5a_CODE_PERIOD_MS); + d_fnav_nav.flag_TOW_4 = false; + } + else + { + d_TOW_at_current_symbol_ms += static_cast(GALILEO_E5a_CODE_PERIOD_MS); + } + break; + } + } + } + } + else // if there is not a new preamble, we define the TOW of the current symbol + { + switch (d_frame_type) + { + case 1: //INAV + { + if (d_inav_nav.flag_TOW_set == true) + { + d_TOW_at_current_symbol_ms += d_PRN_code_period_ms; + } + break; + } + case 2: //FNAV + { + if (d_fnav_nav.flag_TOW_set == true) + { + d_TOW_at_current_symbol_ms += d_PRN_code_period_ms; + } + break; + } + } + } + + // remove used symbols from history + // todo: Use circular buffer here + if (d_symbol_history.size() > d_required_symbols) + { + d_symbol_history.pop_front(); + } + + switch (d_frame_type) + { + case 1: //INAV + { + if (d_inav_nav.flag_TOW_set) + { + if (d_inav_nav.flag_GGTO_1 == true and d_inav_nav.flag_GGTO_2 == true and d_inav_nav.flag_GGTO_3 == true and d_inav_nav.flag_GGTO_4 == true) // all GGTO parameters arrived + { + delta_t = d_inav_nav.A_0G_10 + d_inav_nav.A_1G_10 * (static_cast(d_TOW_at_current_symbol_ms) / 1000.0 - d_inav_nav.t_0G_10 + 604800.0 * (fmod((d_inav_nav.WN_0 - d_inav_nav.WN_0G_10), 64.0))); + } + + current_symbol.Flag_valid_word = true; + } + break; + } + + case 2: //FNAV + { + if (d_fnav_nav.flag_TOW_set) + { + current_symbol.Flag_valid_word = true; + } + break; + } + } + + if (d_inav_nav.flag_TOW_set or d_fnav_nav.flag_TOW_set) + { + current_symbol.TOW_at_current_symbol_ms = d_TOW_at_current_symbol_ms; + // todo: Galileo to GPS time conversion should be moved to observable block. + // current_symbol.TOW_at_current_symbol_ms -= delta_t; //Galileo to GPS TOW + + if (d_dump == true) + { + // MULTIPLEXED FILE RECORDING - Record results to file + try + { + double tmp_double; + uint64_t tmp_ulong_int; + tmp_double = static_cast(d_TOW_at_current_symbol_ms) / 1000.0; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_ulong_int = current_symbol.Tracking_sample_counter; + d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(uint64_t)); + tmp_double = static_cast(d_TOW_at_Preamble_ms) / 1000.0; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "Exception writing observables dump file " << e.what(); + } + } + // 3. Make the output (copy the object contents to the GNURadio reserved memory) + *out[0] = current_symbol; + return 1; + } + else + { + return 0; + } +} diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.h similarity index 62% rename from src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.h rename to src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.h index 663c365b2..f67418868 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.h @@ -1,8 +1,7 @@ /*! - * \file galileo_e1b_telemetry_decoder_cc.h - * \brief Interface of a Galileo INAV message demodulator block - * \author Javier Arribas 2013 jarribas(at)cttc.es, - * Mara Branzanti 2013 mara.branzanti(at)gmail.com + * \file galileo_telemetry_decoder_cc.h + * \brief Implementation of a Galileo unified INAV and FNAV message demodulator block + * \author Javier Arribas 2018. jarribas(at)cttc.es * * ------------------------------------------------------------------------- * @@ -29,12 +28,15 @@ * ------------------------------------------------------------------------- */ -#ifndef GNSS_SDR_GALILEO_E1B_TELEMETRY_DECODER_CC_H -#define GNSS_SDR_GALILEO_E1B_TELEMETRY_DECODER_CC_H + +#ifndef GNSS_SDR_galileo_telemetry_decoder_cc_H +#define GNSS_SDR_galileo_telemetry_decoder_cc_H #include "Galileo_E1.h" +#include "Galileo_E5a.h" #include "galileo_navigation_message.h" +#include "galileo_fnav_message.h" #include "galileo_ephemeris.h" #include "galileo_almanac.h" #include "galileo_iono.h" @@ -46,20 +48,20 @@ #include -class galileo_e1b_telemetry_decoder_cc; +class galileo_telemetry_decoder_cc; -typedef boost::shared_ptr galileo_e1b_telemetry_decoder_cc_sptr; +typedef boost::shared_ptr galileo_telemetry_decoder_cc_sptr; -galileo_e1b_telemetry_decoder_cc_sptr galileo_e1b_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); +galileo_telemetry_decoder_cc_sptr galileo_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, int frame_type, bool dump); /*! - * \brief This class implements a block that decodes the INAV data defined in Galileo ICD + * \brief This class implements a block that decodes the INAV and FNAV data defined in Galileo ICD * */ -class galileo_e1b_telemetry_decoder_cc : public gr::block +class galileo_telemetry_decoder_cc : public gr::block { public: - ~galileo_e1b_telemetry_decoder_cc(); + ~galileo_telemetry_decoder_cc(); void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN void set_channel(int32_t channel); //!< Set receiver's channel int32_t flag_even_word_arrived; @@ -71,23 +73,30 @@ public: gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); private: - friend galileo_e1b_telemetry_decoder_cc_sptr - galileo_e1b_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - galileo_e1b_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); + friend galileo_telemetry_decoder_cc_sptr + galileo_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, int frame_type, bool dump); + galileo_telemetry_decoder_cc(const Gnss_Satellite &satellite, int frame_type, bool dump); void viterbi_decoder(double *page_part_symbols, int32_t *page_part_bits); void deinterleaver(int32_t rows, int32_t cols, double *in, double *out); - void decode_word(double *symbols, int32_t frame_length); + void decode_INAV_word(double *symbols, int32_t frame_length); + void decode_FNAV_word(double *page_symbols, int32_t frame_length); - uint16_t d_preambles_bits[GALILEO_INAV_PREAMBLE_LENGTH_BITS]; - - int32_t *d_preambles_symbols; + int d_frame_type; + int32_t d_bits_per_preamble; + int32_t d_samples_per_preamble; + int32_t d_preamble_period_symbols; + int32_t *d_preamble_samples; + int32_t *d_secondary_code_samples; uint32_t d_samples_per_symbol; - int32_t d_symbols_per_preamble; + uint32_t d_PRN_code_period_ms; + uint32_t d_required_symbols; + uint32_t d_frame_length_symbols; + double *d_page_part_symbols; - std::deque d_symbol_history; + std::deque d_symbol_history; uint64_t d_sample_counter; uint64_t d_preamble_index; @@ -99,7 +108,8 @@ private: int32_t d_CRC_error_counter; // navigation message vars - Galileo_Navigation_Message d_nav; + Galileo_Navigation_Message d_inav_nav; + Galileo_Fnav_Message d_fnav_nav; bool d_dump; Gnss_Satellite d_satellite; @@ -120,8 +130,8 @@ private: const int32_t nn = 2; // Coding rate 1/n const int32_t KK = 7; // Constraint Length int32_t mm = KK - 1; - const int32_t CodeLength = 240; - int32_t DataLength = (CodeLength / nn) - mm; + int32_t CodeLength; + int32_t DataLength; }; #endif diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc index 815ff2c88..374cb910f 100755 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -238,17 +238,18 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl d_correlation_length_ms = 1; d_code_samples_per_chip = 1; d_code_length_chips = static_cast(Galileo_E5a_CODE_LENGTH_CHIPS); - d_secondary = true; + if (trk_parameters.track_pilot) { + d_secondary = true; d_secondary_code_length = static_cast(Galileo_E5a_Q_SECONDARY_CODE_LENGTH); signal_pretty_name = signal_pretty_name + "Q"; interchange_iq = true; } else { - d_secondary_code_length = static_cast(Galileo_E5a_I_SECONDARY_CODE_LENGTH); - d_secondary_code_string = const_cast(&Galileo_E5a_I_SECONDARY_CODE); + //Do not acquire secondary code in data component. It is done in telemetry decoder + d_secondary = false; signal_pretty_name = signal_pretty_name + "I"; interchange_iq = false; } @@ -497,7 +498,7 @@ void dll_pll_veml_tracking::start_tracking() for (uint32_t i = 0; i < d_code_length_chips; i++) { d_tracking_code[i] = aux_code[i].imag(); - d_data_code[i] = aux_code[i].real(); + d_data_code[i] = aux_code[i].real(); //the same because it is generated the full signal (E5aI + E5aQ) } d_Prompt_Data[0] = gr_complex(0.0, 0.0); correlator_data_cpu.set_local_code_and_taps(d_code_length_chips, d_data_code, d_prompt_data_shift); diff --git a/src/core/system_parameters/Galileo_E1.h b/src/core/system_parameters/Galileo_E1.h index b1d2e6191..e25501e08 100644 --- a/src/core/system_parameters/Galileo_E1.h +++ b/src/core/system_parameters/Galileo_E1.h @@ -59,6 +59,7 @@ const double Galileo_E1_SUB_CARRIER_A_RATE_HZ = 1.023e6; //!< Galileo E1 sub-ca 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 int32_t Galileo_E1_B_SAMPLES_PER_SYMBOL = 1; //!< (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS) / Galileo_E1_B_SYMBOL_RATE_BPS const int32_t Galileo_E1_C_SECONDARY_CODE_LENGTH = 25; //!< Galileo E1-C secondary code length [chips] const int32_t Galileo_E1_NUMBER_OF_CODES = 50; @@ -70,10 +71,7 @@ const int32_t GALILEO_E1_HISTORY_DEEP = 100; // Galileo INAV Telemetry structure -#define GALILEO_INAV_PREAMBLE \ - { \ - 0, 1, 0, 1, 1, 0, 0, 0, 0, 0 \ - } +const std::string GALILEO_INAV_PREAMBLE = {"0101100000"}; const int32_t GALILEO_INAV_PREAMBLE_LENGTH_BITS = 10; const double GALILEO_INAV_PAGE_PART_WITH_PREABLE_SECONDS = 2.0 + GALILEO_INAV_PREAMBLE_LENGTH_BITS * Galileo_E1_CODE_PERIOD; From da2c8f997764d2d3dc3c5b676cf0ad83875a2421 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Mon, 27 Aug 2018 18:06:20 +0200 Subject: [PATCH 10/15] Tunning GPS L5 default carrier lock threshold --- src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc index 8fbd56531..11e2572c3 100644 --- a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc @@ -110,7 +110,7 @@ GpsL5DllPllTracking::GpsL5DllPllTracking( int max_lock_fail = configuration->property(role + ".max_lock_fail", 50); if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail; trk_param.max_lock_fail = max_lock_fail; - double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85); + double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.75); if (FLAGS_carrier_lock_th != 0.85) carrier_lock_th = FLAGS_carrier_lock_th; trk_param.carrier_lock_th = carrier_lock_th; From 3f29d2787356497449fd4574d94713c8711d1989 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Mon, 27 Aug 2018 18:08:31 +0200 Subject: [PATCH 11/15] Improving observables unit test --- .../common-files/observable_tests_flags.h | 4 +- .../observables/hybrid_observables_test.cc | 78 +++++++++++-------- 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/src/tests/common-files/observable_tests_flags.h b/src/tests/common-files/observable_tests_flags.h index 594429f36..e20253f34 100644 --- a/src/tests/common-files/observable_tests_flags.h +++ b/src/tests/common-files/observable_tests_flags.h @@ -35,7 +35,7 @@ #include DEFINE_double(skip_obs_transitory_s, 30.0, "Skip the initial observable outputs to avoid transitory results [s]"); -DEFINE_bool(compute_single_diffs, false, "Compute also the signel difference errors for Accumulated Carrier Phase and Carrier Doppler (requires LO synchronization between receivers)"); - +DEFINE_bool(compute_single_diffs, false, "Compute also the single difference errors for Accumulated Carrier Phase and Carrier Doppler (requires LO synchronization between receivers)"); +DEFINE_bool(compare_with_5X, false, "Compare the E5a Doppler and Carrier Phases with the E5 full bw in RINEX (expect discrepancy due to the center frequencies differences"); #endif diff --git a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc b/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc index e3f915b90..7e086ce6b 100644 --- a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc @@ -53,7 +53,6 @@ #include "telemetry_decoder_interface.h" #include "in_memory_configuration.h" #include "gnss_synchro.h" -#include "gps_l1_ca_telemetry_decoder.h" #include "tracking_true_obs_reader.h" #include "true_observables_reader.h" #include "tracking_dump_reader.h" @@ -326,7 +325,8 @@ bool HybridObservablesTest::acquire_signal() { tmp_gnss_synchro.System = 'G'; std::string signal = "1C"; - signal.copy(tmp_gnss_synchro.Signal, 2, 0); + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "GPS L1 CA"; config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); @@ -337,7 +337,8 @@ bool HybridObservablesTest::acquire_signal() { tmp_gnss_synchro.System = 'E'; std::string signal = "1B"; - signal.copy(tmp_gnss_synchro.Signal, 2, 0); + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "Galileo E1B"; config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); @@ -347,7 +348,8 @@ bool HybridObservablesTest::acquire_signal() { tmp_gnss_synchro.System = 'G'; std::string signal = "2S"; - signal.copy(tmp_gnss_synchro.Signal, 2, 0); + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "GPS L2CM"; config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); @@ -357,7 +359,8 @@ bool HybridObservablesTest::acquire_signal() { tmp_gnss_synchro.System = 'E'; std::string signal = "5X"; - signal.copy(tmp_gnss_synchro.Signal, 2, 0); + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "Galileo E5a"; config->set_property("Acquisition_5X.coherent_integration_time_ms", "1"); @@ -372,7 +375,8 @@ bool HybridObservablesTest::acquire_signal() { tmp_gnss_synchro.System = 'E'; std::string signal = "5X"; - signal.copy(tmp_gnss_synchro.Signal, 2, 0); + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "Galileo E5a"; config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); @@ -382,7 +386,8 @@ bool HybridObservablesTest::acquire_signal() { tmp_gnss_synchro.System = 'G'; std::string signal = "L5"; - signal.copy(tmp_gnss_synchro.Signal, 2, 0); + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "GPS L5I"; config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); @@ -579,7 +584,7 @@ void HybridObservablesTest::configure_receiver( std::memcpy(static_cast(gnss_synchro_master.Signal), str, 3); // copy string into synchro char array: 2 char + null config->set_property("Tracking.early_late_space_chips", "0.5"); - config->set_property("Tracking.track_pilot", "false"); + config->set_property("Tracking.track_pilot", "true"); config->set_property("TelemetryDecoder.implementation", "GPS_L2C_Telemetry_Decoder"); } @@ -596,7 +601,7 @@ void HybridObservablesTest::configure_receiver( config->supersede_property("Tracking.implementation", std::string("Galileo_E5a_DLL_PLL_Tracking")); } config->set_property("Tracking.early_late_space_chips", "0.5"); - config->set_property("Tracking.track_pilot", "false"); + config->set_property("Tracking.track_pilot", "true"); config->set_property("Tracking.order", "2"); config->set_property("TelemetryDecoder.implementation", "Galileo_E5a_Telemetry_Decoder"); @@ -610,7 +615,7 @@ void HybridObservablesTest::configure_receiver( std::memcpy(static_cast(gnss_synchro_master.Signal), str, 3); // copy string into synchro char array: 2 char + null config->set_property("Tracking.early_late_space_chips", "0.5"); - config->set_property("Tracking.track_pilot", "false"); + config->set_property("Tracking.track_pilot", "true"); config->set_property("Tracking.order", "2"); config->set_property("TelemetryDecoder.implementation", "GPS_L5_Telemetry_Decoder"); @@ -888,9 +893,9 @@ void HybridObservablesTest::check_results_carrier_doppler_double_diff( ASSERT_LT(error_mean, 5); ASSERT_GT(error_mean, -5); //assuming PLL BW=35 - ASSERT_LT(error_var, 200); - ASSERT_LT(max_error, 70); - ASSERT_GT(min_error, -70); + ASSERT_LT(error_var, 250); + ASSERT_LT(max_error, 100); + ASSERT_GT(min_error, -100); ASSERT_LT(rmse, 30); } @@ -967,9 +972,9 @@ void HybridObservablesTest::check_results_carrier_doppler( ASSERT_LT(error_mean_ch0, 5); ASSERT_GT(error_mean_ch0, -5); //assuming PLL BW=35 - ASSERT_LT(error_var_ch0, 200); - ASSERT_LT(max_error_ch0, 70); - ASSERT_GT(min_error_ch0, -70); + ASSERT_LT(error_var_ch0, 250); + ASSERT_LT(max_error_ch0, 100); + ASSERT_GT(min_error_ch0, -100); ASSERT_LT(rmse_ch0, 30); } @@ -1195,7 +1200,7 @@ bool HybridObservablesTest::ReadRinexObs(std::vector* obs_vec, Gnss_S dataobj = r_ref_data.getObs(prn, "L5I", r_ref_header); obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 3) = dataobj.data; } - else if (strcmp("5X\0", gnss.Signal) == 0) //Simulator gives RINEX with E5a+E5b + else if (strcmp("5X\0", gnss.Signal) == 0) //Simulator gives RINEX with E5a+E5b. Doppler and accumulated Carrier phase WILL differ { obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 0) = sow; dataobj = r_ref_data.getObs(prn, "C8I", r_ref_header); @@ -1579,8 +1584,8 @@ TEST_F(HybridObservablesTest, ValidationOfResults) } arma::vec receiver_time_offset_ref_channel_s; - receiver_time_offset_ref_channel_s = true_obs_vec.at(min_pr_ch_id).col(1) / GPS_C_m_s - GPS_STARTOFFSET_ms / 1000.0; - std::cout << "Ref channel initial Receiver time offset " << receiver_time_offset_ref_channel_s(0) * 1e3 << " [ms]" << std::endl; + receiver_time_offset_ref_channel_s = (true_obs_vec.at(min_pr_ch_id).col(1)(0) - measured_obs_vec.at(min_pr_ch_id).col(4)(0)) / GPS_C_m_s; + std::cout << "Ref. channel initial Receiver time offset " << receiver_time_offset_ref_channel_s(0) * 1e3 << " [ms]" << std::endl; for (unsigned int n = 0; n < measured_obs_vec.size(); n++) { @@ -1624,21 +1629,28 @@ TEST_F(HybridObservablesTest, ValidationOfResults) measured_obs_vec.at(n), measured_obs_vec.at(min_pr_ch_id), "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); - check_results_carrier_phase_double_diff(true_obs_vec.at(n), - true_obs_vec.at(min_pr_ch_id), - true_TOW_ch_s, - true_TOW_ref_ch_s, - measured_obs_vec.at(n), - measured_obs_vec.at(min_pr_ch_id), - "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); - check_results_carrier_doppler_double_diff(true_obs_vec.at(n), - true_obs_vec.at(min_pr_ch_id), - true_TOW_ch_s, - true_TOW_ref_ch_s, - measured_obs_vec.at(n), - measured_obs_vec.at(min_pr_ch_id), - "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); + //Do not compare E5a with E5 RINEX due to the Doppler frequency discrepancy caused by the different center frequencies + //E5a_fc=1176.45e6, E5b_fc=1207.14e6, E5_fc=1191.795e6; + std::cout << "s:" << gnss_synchro_vec.at(n).Signal << std::endl; + if (strcmp("5X\0", gnss_synchro_vec.at(n).Signal) != 0 or FLAGS_compare_with_5X) + { + check_results_carrier_phase_double_diff(true_obs_vec.at(n), + true_obs_vec.at(min_pr_ch_id), + true_TOW_ch_s, + true_TOW_ref_ch_s, + measured_obs_vec.at(n), + measured_obs_vec.at(min_pr_ch_id), + "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); + + check_results_carrier_doppler_double_diff(true_obs_vec.at(n), + true_obs_vec.at(min_pr_ch_id), + true_TOW_ch_s, + true_TOW_ref_ch_s, + measured_obs_vec.at(n), + measured_obs_vec.at(min_pr_ch_id), + "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); + } } else { From d8d931febad5e4d9b9ef44f94c31e2a0db578fd9 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 28 Aug 2018 20:19:44 +0200 Subject: [PATCH 12/15] Remove outdated tap for homebrew --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9be84be8d..4d8d7cc94 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -523,7 +523,6 @@ if(NOT GNURADIO_RUNTIME_FOUND) message("You can install it easily via Macports:") message(" sudo port install gnuradio ") message("Alternatively, you can use homebrew:") - message(" brew tap odrisci/gnuradio") message(" brew install gnuradio" ) message(FATAL_ERROR "GNU Radio ${GNSSSDR_GNURADIO_MIN_VERSION} or later is required to build gnss-sdr") endif(OS_IS_MACOSX) From 8d195e325904b2bc6b9a423aedd018f8583f7b85 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 28 Aug 2018 20:20:34 +0200 Subject: [PATCH 13/15] Remove unused variables --- src/algorithms/libs/rtklib/rtklib_rtkcmn.cc | 32 --------------------- 1 file changed, 32 deletions(-) diff --git a/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc b/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc index 88cc2ca38..f7e4e76c5 100644 --- a/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc +++ b/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc @@ -89,38 +89,6 @@ double leaps[MAXLEAPS + 1][7] = {/* leap seconds (y,m,d,h,m,s,utc-gpst) */ {}}; -const prcopt_t prcopt_default = { /* defaults processing options */ - PMODE_SINGLE, 0, 2, SYS_GPS, /* mode, soltype, nf, navsys */ - 15.0 * D2R, {{}, {{}, {}}}, /* elmin, snrmask */ - 0, 1, 1, 1, /* sateph, modear, glomodear, bdsmodear */ - 5, 0, 10, 1, /* maxout, minlock, minfix, armaxiter */ - 0, 0, 0, 0, /* estion, esttrop, dynamics, tidecorr */ - 1, 0, 0, 0, 0, /* niter, codesmooth, intpref, sbascorr, sbassatsel */ - 0, 0, /* rovpos, refpos */ - {100.0, 100.0, 100.0}, /* eratio[] */ - {100.0, 0.003, 0.003, 0.0, 1.0}, /* err[] */ - {30.0, 0.03, 0.3}, /* std[] */ - {1e-4, 1e-3, 1e-4, 1e-1, 1e-2, 0.0}, /* prn[] */ - 5E-12, /* sclkstab */ - {3.0, 0.9999, 0.25, 0.1, 0.05, 0, 0, 0}, /* thresar */ - 0.0, 0.0, 0.05, /* elmaskar, almaskhold, thresslip */ - 30.0, 30.0, 30.0, /* maxtdif, maxinno, maxgdop */ - {}, {}, {}, /* baseline, ru, rb */ - {"", ""}, /* anttype */ - {}, {}, {}, /* antdel, pcv, exsats */ - 0, 0, 0, {"", ""}, {}, 0, {{}, {}}, {{}, {{}, {}}, {{}, {}}, {}, {}}, 0, {}}; - - -const solopt_t solopt_default = { - /* defaults solution output options */ - SOLF_LLH, TIMES_GPST, 1, 3, /* posf, times, timef, timeu */ - 0, 1, 0, 0, 0, 0, /* degf, outhead, outopt, datum, height, geoid */ - 0, 0, 0, /* solstatic, sstat, trace */ - {0.0, 0.0}, /* nmeaintv */ - " ", "", 0 /* separator/program name */ -}; - - const char *formatstrs[32] = {/* stream format strings */ "RTCM 2", /* 0 */ "RTCM 3", /* 1 */ From 4a0c2855b0450bc9c40b89685144e0dc9bbcf150 Mon Sep 17 00:00:00 2001 From: Marc L Date: Mon, 27 Aug 2018 17:50:13 -0400 Subject: [PATCH 14/15] Update MANIFEST.md fixed dependencies list so it parses nicely on cgran.org --- MANIFEST.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/MANIFEST.md b/MANIFEST.md index d98411e9f..560ef14b6 100644 --- a/MANIFEST.md +++ b/MANIFEST.md @@ -12,7 +12,12 @@ author: - et altri (see AUTHORS file for a list of contributors) copyright_owner: - The Authors -dependencies: gnuradio (>= 3.7.3), armadillo, gflags, glog, gnutls, matio +dependencies: + - gnuradio (>= 3.7.3) + - armadillo + - gflags + - glog + - gnutls license: GPLv3+ repo: https://github.com/gnss-sdr/gnss-sdr website: https://gnss-sdr.org From 79a2b68d8916a1fd1753e2a7eb328dc66dc159d1 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 28 Aug 2018 20:34:46 +0200 Subject: [PATCH 15/15] Update URLs --- MANIFEST.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MANIFEST.md b/MANIFEST.md index 560ef14b6..ea64ec678 100644 --- a/MANIFEST.md +++ b/MANIFEST.md @@ -18,10 +18,11 @@ dependencies: - gflags - glog - gnutls + - matio license: GPLv3+ repo: https://github.com/gnss-sdr/gnss-sdr website: https://gnss-sdr.org -icon: https://raw.githubusercontent.com/gnss-sdr/gnss-sdr/master/docs/doxygen/images/gnss-sdr_logo.png +icon: https://gnss-sdr.org/assets/images/logo400x400.jpg --- Global Navigation Satellite Systems receiver defined by software. It performs all the signal processing from raw signal samples up to the computation of the Position-Velocity-Time solution,