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)
diff --git a/MANIFEST.md b/MANIFEST.md
index d98411e9f..ea64ec678 100644
--- a/MANIFEST.md
+++ b/MANIFEST.md
@@ -12,11 +12,17 @@ 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
+ - 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,
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 */
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 */
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/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/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;
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..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;
}
@@ -362,7 +363,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)
@@ -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/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;
};
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;
diff --git a/src/core/monitor/gnss_synchro_monitor.cc b/src/core/monitor/gnss_synchro_monitor.cc
index bde09ef69..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
*
* -------------------------------------------------------------------------
@@ -61,6 +64,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 +80,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..9547bf12d 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
*
* -------------------------------------------------------------------------
@@ -65,6 +68,8 @@ private:
std::unique_ptr udp_sink_ptr;
+ int count;
+
public:
gnss_synchro_monitor(unsigned int nchannels,
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;
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/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/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.");
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
{
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;
+}