diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 216eb79d6..c943e0f58 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -44,7 +44,7 @@ jobs: - name: install dependencies run: brew install clang-format - name: run clang-format - run: find . -iname \*.h -o -iname \*.c -o -iname \*.cpp | xargs clang-format -style=file -i + run: find . -iname \*.h -o -iname \*.c -o -iname \*.cc | xargs clang-format -style=file -i - name: check run: git diff > clang_format.patch && echo -e "if \n [ -s clang_format.patch ] \nthen \n echo "clang-format not applied:"; echo ""; more clang_format.patch; exit 1 \nfi \n" > detect && chmod +x ./detect && ./detect @@ -112,6 +112,10 @@ jobs: - name: test shell: powershell run: cd build; ctest -C Release + - name: install + run: cmake --install build + - name: run profile + run: cd 'C:\Program Files (x86)\volk_gnsssdr\bin'; .\volk_gnsssdr_profile.exe volk-gnsssdr-ubuntu: diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c0a2f896..d19c8dd8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) message(FATAL_ERROR "Prevented in-tree build, it is bad practice.\nTry 'cd build && cmake ..' instead.") endif() -cmake_minimum_required(VERSION 2.8.12...3.18) +cmake_minimum_required(VERSION 2.8.12...3.19) project(gnss-sdr CXX C) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) diff --git a/docs/changelog.md b/docs/changelog.md index d0e123d5e..892b05e50 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -57,6 +57,8 @@ SPDX-FileCopyrightText: 2011-2020 Carles Fernandez-Prades // for cout, cerr #include // for stringstream +// clang-format off #if HAS_STD_FILESYSTEM #include namespace errorlib = std; @@ -47,6 +48,7 @@ namespace fs = std::filesystem; namespace fs = boost::filesystem; namespace errorlib = boost::system; #endif +// clang-format on GeoJSON_Printer::GeoJSON_Printer(const std::string& base_path) { diff --git a/src/algorithms/PVT/libs/gpx_printer.cc b/src/algorithms/PVT/libs/gpx_printer.cc index c77400bcd..5cf791b38 100644 --- a/src/algorithms/PVT/libs/gpx_printer.cc +++ b/src/algorithms/PVT/libs/gpx_printer.cc @@ -29,6 +29,7 @@ #include // for cout, cerr #include // for stringstream +// clang-format off #if HAS_STD_FILESYSTEM #include namespace errorlib = std; @@ -47,6 +48,7 @@ namespace fs = std::filesystem; namespace fs = boost::filesystem; namespace errorlib = boost::system; #endif +// clang-format on Gpx_Printer::Gpx_Printer(const std::string& base_path) diff --git a/src/algorithms/PVT/libs/kml_printer.cc b/src/algorithms/PVT/libs/kml_printer.cc index 7ee5ad393..83b8a605e 100644 --- a/src/algorithms/PVT/libs/kml_printer.cc +++ b/src/algorithms/PVT/libs/kml_printer.cc @@ -31,6 +31,7 @@ #include // for S_IXUSR | S_IRWXG | S_IRWXO #include // for mode_t +// clang-format off #if HAS_STD_FILESYSTEM #include namespace errorlib = std; @@ -49,6 +50,7 @@ namespace fs = std::filesystem; namespace fs = boost::filesystem; namespace errorlib = boost::system; #endif +// clang-format on Kml_Printer::Kml_Printer(const std::string& base_path) diff --git a/src/algorithms/PVT/libs/nmea_printer.cc b/src/algorithms/PVT/libs/nmea_printer.cc index 92a0bb151..2da627251 100644 --- a/src/algorithms/PVT/libs/nmea_printer.cc +++ b/src/algorithms/PVT/libs/nmea_printer.cc @@ -34,6 +34,7 @@ #include #include +// clang-format off #if HAS_STD_FILESYSTEM #include namespace errorlib = std; @@ -52,6 +53,7 @@ namespace fs = std::filesystem; namespace fs = boost::filesystem; namespace errorlib = boost::system; #endif +// clang-format on Nmea_Printer::Nmea_Printer(const std::string& filename, bool flag_nmea_output_file, bool flag_nmea_tty_port, std::string nmea_dump_devname, const std::string& base_path) diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index 88a963a59..e84c2394f 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -56,6 +56,7 @@ #include #include +// clang-format off #if HAS_STD_FILESYSTEM #include namespace errorlib = std; @@ -74,6 +75,7 @@ namespace fs = std::filesystem; namespace fs = boost::filesystem; namespace errorlib = boost::system; #endif +// clang-format on Rinex_Printer::Rinex_Printer(int32_t conf_version, const std::string& base_path, const std::string& base_name) diff --git a/src/algorithms/PVT/libs/rtcm_printer.cc b/src/algorithms/PVT/libs/rtcm_printer.cc index 3857fea7d..2f9fa6931 100644 --- a/src/algorithms/PVT/libs/rtcm_printer.cc +++ b/src/algorithms/PVT/libs/rtcm_printer.cc @@ -38,6 +38,8 @@ #include // for cout, cerr #include // for tcgetattr #include // for close, write + +// clang-format off #if HAS_STD_FILESYSTEM #include namespace errorlib = std; @@ -56,6 +58,7 @@ namespace fs = std::filesystem; namespace fs = boost::filesystem; namespace errorlib = boost::system; #endif +// clang-format off Rtcm_Printer::Rtcm_Printer(const std::string& filename, bool flag_rtcm_file_dump, bool flag_rtcm_server, bool flag_rtcm_tty_port, uint16_t rtcm_tcp_port, uint16_t rtcm_station_id, const std::string& rtcm_dump_devname, bool time_tag_name, const std::string& base_path) diff --git a/src/algorithms/PVT/libs/rtklib_solver.cc b/src/algorithms/PVT/libs/rtklib_solver.cc index 6ae222120..a5ac7a566 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.cc +++ b/src/algorithms/PVT/libs/rtklib_solver.cc @@ -41,6 +41,7 @@ #include #include +// clang-format off #if HAS_STD_FILESYSTEM #include namespace errorlib = std; @@ -59,6 +60,7 @@ namespace fs = std::filesystem; namespace fs = boost::filesystem; namespace errorlib = boost::system; #endif +// clang-format on Rtklib_Solver::Rtklib_Solver(const rtk_t &rtk, int nchannels, const std::string &dump_filename, bool flag_dump_to_file, bool flag_dump_to_mat) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index 78df6b841..c4ec0cadb 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -659,8 +659,10 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) << ", doppler_step: " << d_doppler_step << ", use_CFAR_algorithm_flag: " << (d_use_CFAR_algorithm_flag ? "true" : "false"); - lk.unlock(); - + if (d_acq_parameters.blocking) + { + lk.unlock(); + } // Doppler frequency grid loop if (!d_step_two) { @@ -782,7 +784,11 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) } } - lk.lock(); + if (d_acq_parameters.blocking) + { + lk.lock(); + } + if (!d_acq_parameters.bit_transition_flag) { if (d_test_statistics > d_threshold) @@ -872,7 +878,6 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) send_negative_acquisition(); } } - d_worker_active = false; if ((d_num_noncoherent_integrations_counter == d_acq_parameters.max_dwells) or (d_positive_acq == 1)) { @@ -884,6 +889,8 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) d_num_noncoherent_integrations_counter = 0U; d_positive_acq = 0; } + + d_worker_active = false; } @@ -930,6 +937,7 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), * 6. Declare positive or negative acquisition using a message port */ gr::thread::scoped_lock lk(d_setlock); + if (!d_active or d_worker_active) { if (!d_acq_parameters.blocking_on_standby) @@ -1016,7 +1024,8 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), } else { - gr::thread::thread d_worker(&pcps_acquisition::acquisition_core, this, d_sample_counter); + d_worker = std::thread([&] { pcps_acquisition::acquisition_core(d_sample_counter); }); + d_worker.detach(); d_worker_active = true; } consume_each(0); diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index fedd18d18..c161cb063 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -61,8 +61,8 @@ #include #include #include +#include #include - #if HAS_STD_SPAN #include namespace own = std; @@ -259,6 +259,7 @@ private: arma::fmat d_narrow_grid; std::string d_dump_filename; + std::thread d_worker; int64_t d_dump_number; uint64_t d_sample_counter; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc index 2778ca7bc..4472dad08 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc @@ -81,8 +81,8 @@ pcps_opencl_acquisition_cc::pcps_opencl_acquisition_cc( bool dump, const std::string &dump_filename, bool enable_monitor_output) : gr::block("pcps_opencl_acquisition_cc", - gr::io_signature::make(1, 1, static_cast(sizeof(gr_complex) * sampled_ms * samples_per_ms)), - gr::io_signature::make(0, 1, sizeof(Gnss_Synchro))) + gr::io_signature::make(1, 1, static_cast(sizeof(gr_complex) * sampled_ms * samples_per_ms)), + gr::io_signature::make(0, 1, sizeof(Gnss_Synchro))) { this->message_port_register_out(pmt::mp("events")); d_sample_counter = 0ULL; // SAMPLE COUNTER diff --git a/src/algorithms/libs/gnss_sdr_create_directory.cc b/src/algorithms/libs/gnss_sdr_create_directory.cc index 7a32183b9..bf14a5881 100644 --- a/src/algorithms/libs/gnss_sdr_create_directory.cc +++ b/src/algorithms/libs/gnss_sdr_create_directory.cc @@ -22,6 +22,7 @@ #include // for exception #include // for ofstream +// clang-format off #if HAS_STD_FILESYSTEM #include namespace errorlib = std; @@ -40,6 +41,7 @@ namespace fs = std::filesystem; namespace fs = boost::filesystem; namespace errorlib = boost::system; #endif +// clang-format on bool gnss_sdr_create_directory(const std::string& foldername) { diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt index 68a16a26b..b30a166ba 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt @@ -247,7 +247,10 @@ if(CMAKE_VERSION VERSION_GREATER 3.0 AND SUPPORTED_CPU_FEATURES_ARCH) FORCE ) set(USE_CPU_FEATURES ON) + set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}") + set(BUILD_SHARED_LIBS OFF) add_subdirectory(cpu_features) + set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}") endif() # Python diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/README.md b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/README.md index cd2eec38e..46f1a8c62 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/README.md +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/README.md @@ -139,6 +139,24 @@ $ volk_gnsssdr_profile $ sudo ldconfig ``` +### Building on Microsoft Windows + +With Visual Studio 2019, in a Powershell run by administrator: + +``` +$ git clone https://github.com/gnss-sdr/gnss-sdr +$ cd gnss-sdr +$ git checkout next +$ cd build +$ cmake -G "Visual Studio 16 2019" ..\src\algorithms\libs\volk_gnsssdr_module\volk_gnsssdr +$ cd .. +$ cmake --build build --config Release +$ cd build +$ ctest -C Release +$ cd .. +$ cmake --install build +``` + ## References If you use VOLK_GNSSSDR in your research and/or software, please cite the diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/archs.xml b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/archs.xml index cde79793b..35d33f174 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/archs.xml +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/archs.xml @@ -68,7 +68,6 @@ -mmmx -mmmx - /arch:SSE 8 @@ -84,7 +83,6 @@ -msse -msse - /arch:SSE _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); xmmintrin.h 16 @@ -94,7 +92,6 @@ -msse2 -msse2 - /arch:SSE2 16 diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn.h index bb149a55c..2888cc679 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn.h @@ -63,7 +63,6 @@ #include #include #include -// #include #ifdef LV_HAVE_GENERIC @@ -74,7 +73,7 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_generic(lv_32f unsigned int n; for (n_vec = 0; n_vec < num_a_vectors; n_vec++) { - result[n_vec] = lv_cmake(0, 0); + result[n_vec] = lv_cmake(0.0f, 0.0f); } for (n = 0; n < num_points; n++) { @@ -115,7 +114,7 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_generic_reload unsigned int j; for (n_vec = 0; n_vec < num_a_vectors; n_vec++) { - result[n_vec] = lv_cmake(0, 0); + result[n_vec] = lv_cmake(0.0f, 0.0f); } for (n = 0; n < num_points / ROTATOR_RELOAD; n++) @@ -158,6 +157,7 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_generic_reload #include static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_u_avx(lv_32fc_t* result, const lv_32fc_t* in_common, const lv_32fc_t phase_inc, lv_32fc_t* phase, const float** in_a, int num_a_vectors, unsigned int num_points) { +#ifndef WIN32 unsigned int number = 0; int vec_ind = 0; unsigned int i = 0; @@ -287,7 +287,7 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_u_avx(lv_32fc_ _mm256_store_ps((float*)dotProductVector, dotProdVal0[vec_ind]); // Store the results back into the dot product vector - result[vec_ind] = lv_cmake(0, 0); + result[vec_ind] = lv_cmake(0.0f, 0.0f); for (i = 0; i < 4; ++i) { result[vec_ind] += dotProductVector[i]; @@ -312,6 +312,9 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_u_avx(lv_32fc_ } *phase = _phase; +#else + volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_generic_reload(result, in_common, phase_inc, phase, in_a, num_a_vectors, num_points); +#endif } #endif /* LV_HAVE_AVX */ @@ -322,6 +325,7 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_u_avx(lv_32fc_ #include static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_a_avx(lv_32fc_t* result, const lv_32fc_t* in_common, const lv_32fc_t phase_inc, lv_32fc_t* phase, const float** in_a, int num_a_vectors, unsigned int num_points) { +#ifndef WIN32 unsigned int number = 0; int vec_ind = 0; unsigned int i = 0; @@ -451,7 +455,7 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_a_avx(lv_32fc_ _mm256_store_ps((float*)dotProductVector, dotProdVal0[vec_ind]); // Store the results back into the dot product vector - result[vec_ind] = lv_cmake(0, 0); + result[vec_ind] = lv_cmake(0.0f, 0.0f); for (i = 0; i < 4; ++i) { result[vec_ind] += dotProductVector[i]; @@ -476,6 +480,9 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_a_avx(lv_32fc_ } *phase = _phase; +#else + volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_generic_reload(result, in_common, phase_inc, phase, in_a, num_a_vectors, num_points); +#endif } diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc.h index 85eb7bf5c..a73bac9cd 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc.h @@ -106,8 +106,11 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc_u_avx(lv_3 in_a[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); memcpy((float*)in_a[n], (float*)in, sizeof(float) * num_points); } +#ifndef WIN32 volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_u_avx(result, local_code, phase_inc[0], phase, (const float**)in_a, num_a_vectors, num_points); - +#else + volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_generic_reload(result, local_code, phase_inc[0], phase, (const float**)in_a, num_a_vectors, num_points); +#endif for (n = 0; n < num_a_vectors; n++) { volk_gnsssdr_free(in_a[n]); @@ -136,8 +139,11 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc_a_avx(lv_3 in_a[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); memcpy((float*)in_a[n], (float*)in, sizeof(float) * num_points); } +#ifndef WIN32 volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_a_avx(result, local_code, phase_inc[0], phase, (const float**)in_a, num_a_vectors, num_points); - +#else + volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_generic_reload(result, local_code, phase_inc[0], phase, (const float**)in_a, num_a_vectors, num_points); +#endif for (n = 0; n < num_a_vectors; n++) { volk_gnsssdr_free(in_a[n]); diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn.h index 9b9ced9b1..45f0b7452 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn.h @@ -74,7 +74,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_generic(lv_32fc unsigned int n; for (n_vec = 0; n_vec < num_a_vectors; n_vec++) { - result[n_vec] = lv_cmake(0, 0); + result[n_vec] = lv_cmake(0.0f, 0.0f); } for (n = 0; n < num_points; n++) { @@ -115,7 +115,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_generic_reload( unsigned int j; for (n_vec = 0; n_vec < num_a_vectors; n_vec++) { - result[n_vec] = lv_cmake(0, 0); + result[n_vec] = lv_cmake(0.0f, 0.0f); } for (n = 0; n < num_points / ROTATOR_RELOAD; n++) @@ -158,7 +158,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_generic_reload( #include static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_u_sse3(lv_32fc_t* result, const lv_32fc_t* in_common, const lv_32fc_t phase_inc, lv_32fc_t* phase, const lv_32fc_t** in_a, int num_a_vectors, unsigned int num_points) { - lv_32fc_t dotProduct = lv_cmake(0, 0); + lv_32fc_t dotProduct = lv_cmake(0.0f, 0.0f); lv_32fc_t tmp32_1, tmp32_2; const unsigned int sse_iters = num_points / 2; int n_vec; @@ -240,7 +240,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_u_sse3(lv_32fc_ for (n_vec = 0; n_vec < num_a_vectors; n_vec++) { _mm_store_ps((float*)dotProductVector, acc[n_vec]); // Store the results back into the dot product vector - dotProduct = lv_cmake(0, 0); + dotProduct = lv_cmake(0.0f, 0.0f); for (i = 0; i < 2; ++i) { dotProduct = dotProduct + dotProductVector[i]; @@ -270,7 +270,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_u_sse3(lv_32fc_ #include static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_a_sse3(lv_32fc_t* result, const lv_32fc_t* in_common, const lv_32fc_t phase_inc, lv_32fc_t* phase, const lv_32fc_t** in_a, int num_a_vectors, unsigned int num_points) { - lv_32fc_t dotProduct = lv_cmake(0, 0); + lv_32fc_t dotProduct = lv_cmake(0.0f, 0.0f); lv_32fc_t tmp32_1, tmp32_2; const unsigned int sse_iters = num_points / 2; int n_vec; @@ -352,7 +352,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_a_sse3(lv_32fc_ for (n_vec = 0; n_vec < num_a_vectors; n_vec++) { _mm_store_ps((float*)dotProductVector, acc[n_vec]); // Store the results back into the dot product vector - dotProduct = lv_cmake(0, 0); + dotProduct = lv_cmake(0.0f, 0.0f); for (i = 0; i < 2; ++i) { dotProduct = dotProduct + dotProductVector[i]; @@ -382,7 +382,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_a_sse3(lv_32fc_ #include static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_u_avx(lv_32fc_t* result, const lv_32fc_t* in_common, const lv_32fc_t phase_inc, lv_32fc_t* phase, const lv_32fc_t** in_a, int num_a_vectors, unsigned int num_points) { - lv_32fc_t dotProduct = lv_cmake(0, 0); + lv_32fc_t dotProduct = lv_cmake(0.0f, 0.0f); lv_32fc_t tmp32_1, tmp32_2; const unsigned int avx_iters = num_points / 4; int n_vec; @@ -401,13 +401,14 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_u_avx(lv_32fc_t for (n_vec = 0; n_vec < num_a_vectors; n_vec++) { acc[n_vec] = _mm256_setzero_ps(); - result[n_vec] = lv_cmake(0, 0); + result[n_vec] = lv_cmake(0.0f, 0.0f); } // phase rotation registers __m256 a, four_phase_acc_reg, yl, yh, tmp1, tmp1p, tmp2, tmp2p, z; - __attribute__((aligned(32))) lv_32fc_t four_phase_inc[4]; + __VOLK_ATTR_ALIGNED(32) + lv_32fc_t four_phase_inc[4]; const lv_32fc_t phase_inc2 = phase_inc * phase_inc; const lv_32fc_t phase_inc3 = phase_inc2 * phase_inc; const lv_32fc_t phase_inc4 = phase_inc3 * phase_inc; @@ -417,7 +418,8 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_u_avx(lv_32fc_t four_phase_inc[3] = phase_inc4; const __m256 four_phase_inc_reg = _mm256_load_ps((float*)four_phase_inc); - __attribute__((aligned(32))) lv_32fc_t four_phase_acc[4]; + __VOLK_ATTR_ALIGNED(32) + lv_32fc_t four_phase_acc[4]; four_phase_acc[0] = _phase; four_phase_acc[1] = _phase * phase_inc; four_phase_acc[2] = _phase * phase_inc2; @@ -472,7 +474,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_u_avx(lv_32fc_t for (n_vec = 0; n_vec < num_a_vectors; n_vec++) { _mm256_store_ps((float*)dotProductVector, acc[n_vec]); // Store the results back into the dot product vector - dotProduct = lv_cmake(0, 0); + dotProduct = lv_cmake(0.0f, 0.0f); for (i = 0; i < 4; ++i) { dotProduct = dotProduct + dotProductVector[i]; @@ -510,7 +512,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_u_avx(lv_32fc_t #include static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_a_avx(lv_32fc_t* result, const lv_32fc_t* in_common, const lv_32fc_t phase_inc, lv_32fc_t* phase, const lv_32fc_t** in_a, int num_a_vectors, unsigned int num_points) { - lv_32fc_t dotProduct = lv_cmake(0, 0); + lv_32fc_t dotProduct = lv_cmake(0.0f, 0.0f); lv_32fc_t tmp32_1, tmp32_2; const unsigned int avx_iters = num_points / 4; int n_vec; @@ -529,7 +531,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_a_avx(lv_32fc_t for (n_vec = 0; n_vec < num_a_vectors; n_vec++) { acc[n_vec] = _mm256_setzero_ps(); - result[n_vec] = lv_cmake(0, 0); + result[n_vec] = lv_cmake(0.0f, 0.0f); } // phase rotation registers @@ -602,7 +604,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_a_avx(lv_32fc_t for (n_vec = 0; n_vec < num_a_vectors; n_vec++) { _mm256_store_ps((float*)dotProductVector, acc[n_vec]); // Store the results back into the dot product vector - dotProduct = lv_cmake(0, 0); + dotProduct = lv_cmake(0.0f, 0.0f); for (i = 0; i < 4; ++i) { dotProduct = dotProduct + dotProductVector[i]; @@ -655,7 +657,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_neon(lv_32fc_t* if (neon_iters > 0) { - lv_32fc_t dotProduct = lv_cmake(0, 0); + lv_32fc_t dotProduct = lv_cmake(0.0f, 0.0f); float32_t arg_phase0 = cargf(_phase); float32_t arg_phase_inc = cargf(phase_inc); float32_t phase_est; @@ -760,7 +762,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn_neon(lv_32fc_t* for (n_vec = 0; n_vec < num_a_vectors; n_vec++) { vst2q_f32((float32_t*)dotProductVector, accumulator1[n_vec]); // Store the results back into the dot product vector - dotProduct = lv_cmake(0, 0); + dotProduct = lv_cmake(0.0f, 0.0f); for (i = 0; i < 4; ++i) { dotProduct = dotProduct + dotProductVector[i]; diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt index 68afbf718..2fe6e04ab 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt @@ -145,6 +145,11 @@ macro(OVERRULE_ARCH arch reason) list(REMOVE_ITEM available_archs ${arch}) endmacro() +macro(FORCE_ARCH arch reason) + message(STATUS "${reason}, Forced arch ${arch}") + list(APPEND available_archs ${arch}) +endmacro() + ######################################################################## # eliminate AVX on if not on x86, or if the compiler does not accept # the xgetbv instruction, or {if not cross-compiling and the xgetbv @@ -264,13 +269,13 @@ if(NOT CROSSCOMPILE_MULTILIB AND CPU_IS_x86) endif() # MSVC 64 bit does not have MMX, overrule it - if(${SIZEOF_CPU} EQUAL 64 AND MSVC) - overrule_arch(mmx "No MMX for Win64") - if(MSVC_VERSION GREATER 1700) - overrule_arch(sse "No SSE for Win64 Visual Studio 2013") + if(MSVC) + if(${SIZEOF_CPU} EQUAL 64) + overrule_arch(mmx "No MMX for Win64") endif() + force_arch(sse "Built-in for MSVC > 2013") + force_arch(sse2 "Built-in for MSVC > 2013") endif() - endif() ######################################################################## diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/volk_gnsssdr_rank_archs.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/volk_gnsssdr_rank_archs.c index db5b931d1..dca205524 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/volk_gnsssdr_rank_archs.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/volk_gnsssdr_rank_archs.c @@ -15,25 +15,10 @@ #include // clang-format on -#if __GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 4 -#define __popcnt __builtin_popcount -#else -inline unsigned __popcnt(unsigned num) -{ - unsigned pop = 0; - while (num) - { - if (num & 0x1) pop++; - num >>= 1; - } - return pop; -} -#endif - int volk_gnsssdr_get_index( - const char *impl_names[], //list of implementations by name - const size_t n_impls, //number of implementations available - const char *impl_name //the implementation name to find + const char *impl_names[], // list of implementations by name + const size_t n_impls, // number of implementations available + const char *impl_name // the implementation name to find ) { unsigned int i; @@ -44,20 +29,20 @@ int volk_gnsssdr_get_index( return i; } } - //TODO return -1; - //something terrible should happen here + // TODO return -1; + // something terrible should happen here fprintf(stderr, "VOLK_GNSSSDR warning: no arch found, returning generic impl\n"); return volk_gnsssdr_get_index(impl_names, n_impls, "generic"); //but we'll fake it for now } int volk_gnsssdr_rank_archs( - const char *kern_name, //name of the kernel to rank - const char *impl_names[], //list of implementations by name - const int *impl_deps, //requirement mask per implementation - const bool *alignment, //alignment status of each implementation - size_t n_impls, //number of implementations available - const bool align //if false, filter aligned implementations + const char *kern_name, // name of the kernel to rank + const char *impl_names[], // list of implementations by name + const int *impl_deps, // requirement mask per implementation + const bool *alignment, // alignment status of each implementation + size_t n_impls, // number of implementations available + const bool align // if false, filter aligned implementations ) { size_t i; @@ -78,7 +63,7 @@ int volk_gnsssdr_rank_archs( return volk_gnsssdr_get_index(impl_names, n_impls, "generic"); } - //now look for the function name in the prefs list + // now look for the function name in the prefs list for (i = 0; i < n_arch_prefs; i++) { if (!strncmp(kern_name, volk_gnsssdr_arch_prefs[i].name, sizeof(volk_gnsssdr_arch_prefs[i].name))) //found it @@ -88,14 +73,14 @@ int volk_gnsssdr_rank_archs( } } - //return the best index with the largest deps + // return the best index with the largest deps size_t best_index_a = 0; size_t best_index_u = 0; int best_value_a = -1; int best_value_u = -1; for (i = 0; i < n_impls; i++) { - const signed val = __popcnt(impl_deps[i]); + const signed val = impl_deps[i]; if (alignment[i] && val > best_value_a) { best_index_a = i; @@ -108,9 +93,9 @@ int volk_gnsssdr_rank_archs( } } - //when align and we found a best aligned, use it + // when align and we found a best aligned, use it if (align && best_value_a != -1) return best_index_a; - //otherwise return the best unaligned + // otherwise return the best unaligned return best_index_u; } diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_gs.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_gs.cc index 32edae891..b604ea3b9 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_gs.cc +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_gs.cc @@ -41,6 +41,7 @@ #include #endif +// clang-format off #if HAS_STD_FILESYSTEM #include namespace errorlib = std; @@ -59,6 +60,7 @@ namespace fs = std::filesystem; namespace fs = boost::filesystem; namespace errorlib = boost::system; #endif +// clang-format on hybrid_observables_gs_sptr hybrid_observables_gs_make(const Obs_Conf &conf_) diff --git a/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt b/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt index 0223bf737..5e2542ddd 100644 --- a/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt @@ -60,11 +60,11 @@ endif() target_link_libraries(telemetry_decoder_adapters PUBLIC telemetry_decoder_gr_blocks + telemetry_decoder_libs PRIVATE Gflags::gflags Glog::glog Gnuradio::runtime - telemetry_decoder_libs ) target_include_directories(telemetry_decoder_adapters diff --git a/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.cc index dff788834..2eaa17103 100644 --- a/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.cc @@ -32,12 +32,10 @@ BeidouB1iTelemetryDecoder::BeidouB1iTelemetryDecoder( in_streams_(in_streams), out_streams_(out_streams) { - const std::string default_dump_filename("./navigation.dat"); DLOG(INFO) << "role " << role; - dump_ = configuration->property(role + ".dump", false); - dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + tlm_parameters_.SetFromConfiguration(configuration, role); // make telemetry decoder object - telemetry_decoder_ = beidou_b1i_make_telemetry_decoder_gs(satellite_, dump_); // TODO fix me + telemetry_decoder_ = beidou_b1i_make_telemetry_decoder_gs(satellite_, tlm_parameters_); DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; channel_ = 0; if (in_streams_ > 1) diff --git a/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.h index c287d3677..dc20d3838 100644 --- a/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.h @@ -27,6 +27,7 @@ #include "gnss_satellite.h" // for Gnss_Satellite #include "gnss_synchro.h" #include "telemetry_decoder_interface.h" +#include "tlm_conf.h" #include // for basic_block_sptr, top_block_sptr #include // for size_t #include @@ -86,12 +87,11 @@ public: private: beidou_b1i_telemetry_decoder_gs_sptr telemetry_decoder_; Gnss_Satellite satellite_; - std::string dump_filename_; + Tlm_Conf tlm_parameters_; std::string role_; int channel_; unsigned int in_streams_; unsigned int out_streams_; - bool dump_; }; diff --git a/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.cc index e6c32b1ad..9dd220fe1 100644 --- a/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.cc @@ -27,13 +27,10 @@ BeidouB3iTelemetryDecoder::BeidouB3iTelemetryDecoder( unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - const std::string default_dump_filename("./navigation.dat"); DLOG(INFO) << "role " << role; - dump_ = configuration->property(role + ".dump", false); - dump_filename_ = - configuration->property(role + ".dump_filename", default_dump_filename); + tlm_parameters_.SetFromConfiguration(configuration, role); // make telemetry decoder object - telemetry_decoder_ = beidou_b3i_make_telemetry_decoder_gs(satellite_, dump_); + telemetry_decoder_ = beidou_b3i_make_telemetry_decoder_gs(satellite_, tlm_parameters_); DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; channel_ = 0; if (in_streams_ > 1) diff --git a/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.h index 998b1512e..40969f3ac 100644 --- a/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.h @@ -25,6 +25,7 @@ #include "gnss_satellite.h" // for Gnss_Satellite #include "gnss_synchro.h" #include "telemetry_decoder_interface.h" +#include "tlm_conf.h" #include // for basic_block_sptr, top_block_sptr #include // for size_t #include @@ -81,12 +82,11 @@ public: private: beidou_b3i_telemetry_decoder_gs_sptr telemetry_decoder_; Gnss_Satellite satellite_; - std::string dump_filename_; + Tlm_Conf tlm_parameters_; std::string role_; int channel_; unsigned int in_streams_; unsigned int out_streams_; - bool dump_; }; /** \} */ 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 b9f3fae18..bd5c5ff94 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc @@ -33,12 +33,10 @@ GalileoE1BTelemetryDecoder::GalileoE1BTelemetryDecoder( in_streams_(in_streams), out_streams_(out_streams) { - const std::string default_dump_filename("./navigation.dat"); DLOG(INFO) << "role " << role; - dump_ = configuration->property(role + ".dump", false); - dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + tlm_parameters_.SetFromConfiguration(configuration, role); // make telemetry decoder object - telemetry_decoder_ = galileo_make_telemetry_decoder_gs(satellite_, 1, dump_); // unified galileo decoder set to INAV (frame_type=1) + telemetry_decoder_ = galileo_make_telemetry_decoder_gs(satellite_, tlm_parameters_, 1); // 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 f2881b7e5..914baf31d 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.h @@ -28,6 +28,7 @@ #include "gnss_satellite.h" #include "gnss_synchro.h" #include "telemetry_decoder_interface.h" +#include "tlm_conf.h" #include // for basic_block_sptr, top_block_sptr #include // for size_t #include @@ -89,12 +90,11 @@ public: private: galileo_telemetry_decoder_gs_sptr telemetry_decoder_; Gnss_Satellite satellite_; - std::string dump_filename_; + Tlm_Conf tlm_parameters_; std::string role_; int channel_; unsigned int in_streams_; unsigned int out_streams_; - 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 254107487..b859b4eb3 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.cc @@ -36,12 +36,10 @@ GalileoE5aTelemetryDecoder::GalileoE5aTelemetryDecoder( in_streams_(in_streams), out_streams_(out_streams) { - const std::string default_dump_filename("./navigation.dat"); DLOG(INFO) << "role " << role; - dump_ = configuration->property(role + ".dump", false); - dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + tlm_parameters_.SetFromConfiguration(configuration, role); // make telemetry decoder object - telemetry_decoder_ = galileo_make_telemetry_decoder_gs(satellite_, 2, dump_); // unified galileo decoder set to FNAV (frame_type=2) + telemetry_decoder_ = galileo_make_telemetry_decoder_gs(satellite_, tlm_parameters_, 2); // 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 c1445c62d..52a3e8713 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.h @@ -30,6 +30,7 @@ #include "gnss_satellite.h" // for Gnss_Satellite #include "gnss_synchro.h" #include "telemetry_decoder_interface.h" +#include "tlm_conf.h" #include // for basic_block_sptr, top_block_sptr #include // for size_t #include @@ -91,12 +92,11 @@ public: private: galileo_telemetry_decoder_gs_sptr telemetry_decoder_; Gnss_Satellite satellite_; - std::string dump_filename_; + Tlm_Conf tlm_parameters_; std::string role_; int channel_; unsigned int in_streams_; unsigned int out_streams_; - bool dump_; }; diff --git a/src/algorithms/telemetry_decoder/adapters/galileo_e5b_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/galileo_e5b_telemetry_decoder.cc index 9021ddffc..d5666ce84 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e5b_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e5b_telemetry_decoder.cc @@ -34,12 +34,10 @@ GalileoE5bTelemetryDecoder::GalileoE5bTelemetryDecoder( in_streams_(in_streams), out_streams_(out_streams) { - const std::string default_dump_filename("./navigation.dat"); DLOG(INFO) << "role " << role; - dump_ = configuration->property(role + ".dump", false); - dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + tlm_parameters_.SetFromConfiguration(configuration, role); // make telemetry decoder object - telemetry_decoder_ = galileo_make_telemetry_decoder_gs(satellite_, 1, dump_); // unified galileo decoder set to INAV (frame_type=1) + telemetry_decoder_ = galileo_make_telemetry_decoder_gs(satellite_, tlm_parameters_, 1); // 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_e5b_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/galileo_e5b_telemetry_decoder.h index 1cb358f49..1331565de 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e5b_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e5b_telemetry_decoder.h @@ -28,6 +28,7 @@ #include "gnss_satellite.h" #include "gnss_synchro.h" #include "telemetry_decoder_interface.h" +#include "tlm_conf.h" #include // for basic_block_sptr, top_block_sptr #include // for size_t #include @@ -104,12 +105,11 @@ public: private: galileo_telemetry_decoder_gs_sptr telemetry_decoder_; Gnss_Satellite satellite_; - std::string dump_filename_; + Tlm_Conf tlm_parameters_; std::string role_; int channel_; unsigned int in_streams_; unsigned int out_streams_; - bool dump_; }; diff --git a/src/algorithms/telemetry_decoder/adapters/galileo_e6_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/galileo_e6_telemetry_decoder.cc index 26fa7d2b5..0dba7e238 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e6_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e6_telemetry_decoder.cc @@ -33,12 +33,10 @@ GalileoE6TelemetryDecoder::GalileoE6TelemetryDecoder( in_streams_(in_streams), out_streams_(out_streams) { - const std::string default_dump_filename("./navigation.dat"); DLOG(INFO) << "role " << role; - dump_ = configuration->property(role + ".dump", false); - dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + tlm_parameters_.SetFromConfiguration(configuration, role); // make telemetry decoder object - telemetry_decoder_ = galileo_make_telemetry_decoder_gs(satellite_, 3, dump_); // unified galileo decoder set to CNAV (frame_type=3) + telemetry_decoder_ = galileo_make_telemetry_decoder_gs(satellite_, tlm_parameters_, 3); // unified galileo decoder set to CNAV (frame_type=3) DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; channel_ = 0; if (in_streams_ > 1) diff --git a/src/algorithms/telemetry_decoder/adapters/galileo_e6_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/galileo_e6_telemetry_decoder.h index d254c86e6..34608ed13 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e6_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e6_telemetry_decoder.h @@ -27,6 +27,7 @@ #include "gnss_satellite.h" #include "gnss_synchro.h" #include "telemetry_decoder_interface.h" +#include "tlm_conf.h" #include // for basic_block_sptr, top_block_sptr #include // for size_t #include @@ -103,12 +104,11 @@ public: private: galileo_telemetry_decoder_gs_sptr telemetry_decoder_; Gnss_Satellite satellite_; - std::string dump_filename_; + Tlm_Conf tlm_parameters_; std::string role_; int channel_; unsigned int in_streams_; unsigned int out_streams_; - bool dump_; }; diff --git a/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.cc index b17f5bc2b..4ce135ee6 100644 --- a/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.cc @@ -33,12 +33,10 @@ GlonassL1CaTelemetryDecoder::GlonassL1CaTelemetryDecoder( in_streams_(in_streams), out_streams_(out_streams) { - const std::string default_dump_filename("./navigation.dat"); DLOG(INFO) << "role " << role; - dump_ = configuration->property(role + ".dump", false); - dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + tlm_parameters_.SetFromConfiguration(configuration, role); // make telemetry decoder object - telemetry_decoder_ = glonass_l1_ca_make_telemetry_decoder_gs(satellite_, dump_); + telemetry_decoder_ = glonass_l1_ca_make_telemetry_decoder_gs(satellite_, tlm_parameters_); DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; channel_ = 0; if (in_streams_ > 1) diff --git a/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.h index 42283657a..fddfd2fd6 100644 --- a/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.h @@ -27,6 +27,7 @@ #include "gnss_satellite.h" // for Gnss_Satellite #include "gnss_synchro.h" #include "telemetry_decoder_interface.h" +#include "tlm_conf.h" #include // for basic_block_sptr, top_block_sptr #include // for size_t #include @@ -85,12 +86,11 @@ public: private: glonass_l1_ca_telemetry_decoder_gs_sptr telemetry_decoder_; Gnss_Satellite satellite_; - std::string dump_filename_; + Tlm_Conf tlm_parameters_; std::string role_; int channel_; unsigned int in_streams_; unsigned int out_streams_; - bool dump_; }; diff --git a/src/algorithms/telemetry_decoder/adapters/glonass_l2_ca_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/glonass_l2_ca_telemetry_decoder.cc index 0bbbf5384..188f827c3 100644 --- a/src/algorithms/telemetry_decoder/adapters/glonass_l2_ca_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/glonass_l2_ca_telemetry_decoder.cc @@ -32,12 +32,10 @@ GlonassL2CaTelemetryDecoder::GlonassL2CaTelemetryDecoder( in_streams_(in_streams), out_streams_(out_streams) { - const std::string default_dump_filename("./navigation.dat"); DLOG(INFO) << "role " << role; - dump_ = configuration->property(role + ".dump", false); - dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + tlm_parameters_.SetFromConfiguration(configuration, role); // make telemetry decoder object - telemetry_decoder_ = glonass_l2_ca_make_telemetry_decoder_gs(satellite_, dump_); + telemetry_decoder_ = glonass_l2_ca_make_telemetry_decoder_gs(satellite_, tlm_parameters_); DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; channel_ = 0; if (in_streams_ > 1) diff --git a/src/algorithms/telemetry_decoder/adapters/glonass_l2_ca_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/glonass_l2_ca_telemetry_decoder.h index 5471c6f84..c0e535eca 100644 --- a/src/algorithms/telemetry_decoder/adapters/glonass_l2_ca_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/glonass_l2_ca_telemetry_decoder.h @@ -26,6 +26,7 @@ #include "gnss_satellite.h" // for Gnss_Satellite #include "gnss_synchro.h" #include "telemetry_decoder_interface.h" +#include "tlm_conf.h" #include // for basic_block_sptr, top_block_sptr #include // for size_t #include @@ -84,12 +85,11 @@ public: private: glonass_l2_ca_telemetry_decoder_gs_sptr telemetry_decoder_; Gnss_Satellite satellite_; - std::string dump_filename_; + Tlm_Conf tlm_parameters_; std::string role_; int channel_; unsigned int in_streams_; unsigned int out_streams_; - bool dump_; }; diff --git a/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.cc index a5aea9a8a..a707502d4 100644 --- a/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.cc @@ -32,12 +32,10 @@ GpsL1CaTelemetryDecoder::GpsL1CaTelemetryDecoder( in_streams_(in_streams), out_streams_(out_streams) { - const std::string default_dump_filename("./navigation.dat"); DLOG(INFO) << "role " << role; - dump_ = configuration->property(role + ".dump", false); - dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + tlm_parameters_.SetFromConfiguration(configuration, role); // make telemetry decoder object - telemetry_decoder_ = gps_l1_ca_make_telemetry_decoder_gs(satellite_, dump_); // TODO fix me + telemetry_decoder_ = gps_l1_ca_make_telemetry_decoder_gs(satellite_, tlm_parameters_); DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; channel_ = 0; if (in_streams_ > 1) diff --git a/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.h index 8ca2b3220..3bbe21f9c 100644 --- a/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.h @@ -26,6 +26,7 @@ #include "gnss_synchro.h" #include "gps_l1_ca_telemetry_decoder_gs.h" #include "telemetry_decoder_interface.h" +#include "tlm_conf.h" #include // for basic_block_sptr, top_block_sptr #include // for size_t #include @@ -88,12 +89,11 @@ public: private: gps_l1_ca_telemetry_decoder_gs_sptr telemetry_decoder_; Gnss_Satellite satellite_; - std::string dump_filename_; + Tlm_Conf tlm_parameters_; std::string role_; int channel_; unsigned int in_streams_; unsigned int out_streams_; - bool dump_; }; diff --git a/src/algorithms/telemetry_decoder/adapters/gps_l2c_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/gps_l2c_telemetry_decoder.cc index b88139aa6..7a5325f60 100644 --- a/src/algorithms/telemetry_decoder/adapters/gps_l2c_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/gps_l2c_telemetry_decoder.cc @@ -32,12 +32,10 @@ GpsL2CTelemetryDecoder::GpsL2CTelemetryDecoder( in_streams_(in_streams), out_streams_(out_streams) { - const std::string default_dump_filename("./navigation.dat"); DLOG(INFO) << "role " << role; - dump_ = configuration->property(role + ".dump", false); - dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + tlm_parameters_.SetFromConfiguration(configuration, role); // make telemetry decoder object - telemetry_decoder_ = gps_l2c_make_telemetry_decoder_gs(satellite_, dump_); // TODO fix me + telemetry_decoder_ = gps_l2c_make_telemetry_decoder_gs(satellite_, tlm_parameters_); DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; channel_ = 0; if (in_streams_ > 1) diff --git a/src/algorithms/telemetry_decoder/adapters/gps_l2c_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/gps_l2c_telemetry_decoder.h index 5d3b0d527..225c17278 100644 --- a/src/algorithms/telemetry_decoder/adapters/gps_l2c_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/gps_l2c_telemetry_decoder.h @@ -26,6 +26,7 @@ #include "gnss_synchro.h" #include "gps_l2c_telemetry_decoder_gs.h" #include "telemetry_decoder_interface.h" +#include "tlm_conf.h" #include // for basic_block_sptr, top_block_sptr #include // for size_t #include @@ -86,12 +87,11 @@ public: private: gps_l2c_telemetry_decoder_gs_sptr telemetry_decoder_; Gnss_Satellite satellite_; - std::string dump_filename_; + Tlm_Conf tlm_parameters_; std::string role_; int channel_; unsigned int in_streams_; unsigned int out_streams_; - bool dump_; }; diff --git a/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.cc index be5876f8c..a6d80ebe6 100644 --- a/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.cc @@ -32,12 +32,10 @@ GpsL5TelemetryDecoder::GpsL5TelemetryDecoder( in_streams_(in_streams), out_streams_(out_streams) { - const std::string default_dump_filename("./navigation.dat"); DLOG(INFO) << "role " << role; - dump_ = configuration->property(role + ".dump", false); - dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + tlm_parameters_.SetFromConfiguration(configuration, role); // make telemetry decoder object - telemetry_decoder_ = gps_l5_make_telemetry_decoder_gs(satellite_, dump_); + telemetry_decoder_ = gps_l5_make_telemetry_decoder_gs(satellite_, tlm_parameters_); DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; channel_ = 0; if (in_streams_ > 1) diff --git a/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.h index 12343841c..67e879d68 100644 --- a/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.h @@ -27,6 +27,7 @@ #include "gnss_synchro.h" #include "gps_l5_telemetry_decoder_gs.h" #include "telemetry_decoder_interface.h" +#include "tlm_conf.h" #include // for basic_block_sptr, top_block_sptr #include // for size_t #include @@ -86,12 +87,12 @@ public: private: gps_l5_telemetry_decoder_gs_sptr telemetry_decoder_; Gnss_Satellite satellite_; + Tlm_Conf tlm_parameters_; std::string dump_filename_; std::string role_; int channel_; unsigned int in_streams_; unsigned int out_streams_; - bool dump_; }; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt b/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt index 690c5af3d..d5d0d44b7 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt @@ -60,8 +60,19 @@ target_link_libraries(telemetry_decoder_gr_blocks PRIVATE Gflags::gflags Glog::glog + Matio::matio ) +if(FILESYSTEM_FOUND) + target_compile_definitions(telemetry_decoder_gr_blocks PRIVATE -DHAS_STD_FILESYSTEM=1) + if(find_experimental) + target_compile_definitions(telemetry_decoder_gr_blocks PRIVATE -DHAS_STD_FILESYSTEM_EXPERIMENTAL=1) + endif() + target_link_libraries(telemetry_decoder_gr_blocks PRIVATE std::filesystem) +else() + target_link_libraries(telemetry_decoder_gr_blocks PRIVATE Boost::filesystem Boost::system) +endif() + if(GNURADIO_USES_STD_POINTERS) target_compile_definitions(telemetry_decoder_gr_blocks PUBLIC -DGNURADIO_USES_STD_POINTERS=1 diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_gs.cc index ebdeb5caf..b0afae897 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_gs.cc @@ -29,27 +29,51 @@ #include "gnss_synchro.h" #include #include +#include // for Mat_VarCreate #include // for make_any #include // for mp +#include // for size_t #include // for abs #include // for exception #include // for cout #include // for shared_ptr, make_shared +#include + +// clang-format off +#if HAS_STD_FILESYSTEM +#include +namespace errorlib = std; +#if HAS_STD_FILESYSTEM_EXPERIMENTAL +#include +namespace fs = std::experimental::filesystem; +#else +#include +namespace fs = std::filesystem; +#endif +#else +#include // for remove +#include // for path, operator<< +#include // for filesystem +#include // for error_code +namespace fs = boost::filesystem; +namespace errorlib = boost::system; +#endif +// clang-format on #define CRC_ERROR_LIMIT 8 beidou_b1i_telemetry_decoder_gs_sptr -beidou_b1i_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, bool dump) +beidou_b1i_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, const Tlm_Conf &conf) { - return beidou_b1i_telemetry_decoder_gs_sptr(new beidou_b1i_telemetry_decoder_gs(satellite, dump)); + return beidou_b1i_telemetry_decoder_gs_sptr(new beidou_b1i_telemetry_decoder_gs(satellite, conf)); } beidou_b1i_telemetry_decoder_gs::beidou_b1i_telemetry_decoder_gs( const Gnss_Satellite &satellite, - bool dump) : gr::block("beidou_b1i_telemetry_decoder_gs", - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) + const Tlm_Conf &conf) : gr::block("beidou_b1i_telemetry_decoder_gs", + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { // prevent telemetry symbols accumulation in output buffers this->set_max_noutput_items(1); @@ -58,7 +82,9 @@ beidou_b1i_telemetry_decoder_gs::beidou_b1i_telemetry_decoder_gs( // Control messages to tracking block this->message_port_register_out(pmt::mp("telemetry_to_trk")); // initialize internal vars - d_dump = dump; + d_dump_filename = conf.dump_filename; + d_dump = conf.dump; + d_dump_mat = conf.dump_mat; d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); LOG(INFO) << "Initializing BeiDou B1I Telemetry Decoding for satellite " << this->d_satellite; @@ -104,8 +130,10 @@ beidou_b1i_telemetry_decoder_gs::beidou_b1i_telemetry_decoder_gs( beidou_b1i_telemetry_decoder_gs::~beidou_b1i_telemetry_decoder_gs() { DLOG(INFO) << "BeiDou B1I Telemetry decoder block (channel " << d_channel << ") destructor called."; + size_t pos = 0; if (d_dump_file.is_open() == true) { + pos = d_dump_file.tellp(); try { d_dump_file.close(); @@ -114,7 +142,127 @@ beidou_b1i_telemetry_decoder_gs::~beidou_b1i_telemetry_decoder_gs() { LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); } + if (pos == 0) + { + errorlib::error_code ec; + if (!fs::remove(fs::path(d_dump_filename), ec)) + { + LOG(WARNING) << "Error deleting temporary file"; + } + } } + if (d_dump && (pos != 0) && d_dump_mat) + { + try + { + save_matfile(); + } + catch (const std::exception &ex) + { + LOG(WARNING) << "Error saving the .mat file: " << ex.what(); + } + } +} + + +int32_t beidou_b1i_telemetry_decoder_gs::save_matfile() const +{ + std::ifstream::pos_type size; + const int32_t number_of_double_vars = 2; + const int32_t number_of_int_vars = 2; + const int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(int32_t) * number_of_int_vars; + std::ifstream dump_file; + std::string dump_filename_ = d_dump_filename; + + std::cout << "Generating .mat file for " << dump_filename_ << '\n'; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(dump_filename_.c_str(), std::ios::binary | std::ios::ate); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << '\n'; + return 1; + } + // count number of epochs and rewind + int64_t num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + if (num_epoch == 0LL) + { + // empty file, exit + return 1; + } + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + auto TOW_at_current_symbol_ms = std::vector(num_epoch); + auto tracking_sample_counter = std::vector(num_epoch); + auto TOW_at_Preamble_ms = std::vector(num_epoch); + auto nav_symbol = std::vector(num_epoch); + auto prn = std::vector(num_epoch); + + try + { + if (dump_file.is_open()) + { + for (int64_t i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&TOW_at_current_symbol_ms[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&tracking_sample_counter[i]), sizeof(uint64_t)); + dump_file.read(reinterpret_cast(&TOW_at_Preamble_ms[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&nav_symbol[i]), sizeof(int32_t)); + dump_file.read(reinterpret_cast(&prn[i]), sizeof(int32_t)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << '\n'; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = dump_filename_; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), nullptr, MAT_FT_MAT73); + if (reinterpret_cast(matfp) != nullptr) + { + std::array dims{1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("TOW_at_current_symbol_ms", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims.data(), TOW_at_current_symbol_ms.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("tracking_sample_counter", MAT_C_UINT64, MAT_T_UINT64, 2, dims.data(), tracking_sample_counter.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("TOW_at_Preamble_ms", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims.data(), TOW_at_Preamble_ms.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("nav_symbol", MAT_C_INT32, MAT_T_INT32, 2, dims.data(), nav_symbol.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_INT32, MAT_T_INT32, 2, dims.data(), prn.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + + return 0; } @@ -348,7 +496,6 @@ void beidou_b1i_telemetry_decoder_gs::set_channel(int32_t channel) { try { - d_dump_filename = "telemetry"; d_dump_filename.append(std::to_string(d_channel)); d_dump_filename.append(".dat"); d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); @@ -585,12 +732,17 @@ int beidou_b1i_telemetry_decoder_gs::general_work(int noutput_items __attribute_ { double tmp_double; uint64_t tmp_ulong_int; + int32_t tmp_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)); + tmp_int = (current_symbol.Prompt_I > 0.0 ? 1 : -1); + d_dump_file.write(reinterpret_cast(&tmp_int), sizeof(int32_t)); + tmp_int = static_cast(current_symbol.PRN); + d_dump_file.write(reinterpret_cast(&tmp_int), sizeof(int32_t)); } catch (const std::ifstream::failure &e) { diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_gs.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_gs.h index 658ec8e5e..a3db055fc 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_gs.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_gs.h @@ -26,6 +26,7 @@ #include "beidou_dnav_navigation_message.h" #include "gnss_block_interface.h" #include "gnss_satellite.h" +#include "tlm_conf.h" #include #include // for block #include // for gr_vector_const_void_star @@ -46,7 +47,7 @@ using beidou_b1i_telemetry_decoder_gs_sptr = gnss_shared_ptr #include +#include // for Mat_VarCreate #include // for make_any #include // for mp +#include // for size_t #include // for abs #include // for exception #include // for cout #include // for shared_ptr, make_shared +#include + +// clang-format off +#if HAS_STD_FILESYSTEM +#include +namespace errorlib = std; +#if HAS_STD_FILESYSTEM_EXPERIMENTAL +#include +namespace fs = std::experimental::filesystem; +#else +#include +namespace fs = std::filesystem; +#endif +#else +#include // for remove +#include // for path, operator<< +#include // for filesystem +#include // for error_code +namespace fs = boost::filesystem; +namespace errorlib = boost::system; +#endif +// clang-format on #define CRC_ERROR_LIMIT 8 beidou_b3i_telemetry_decoder_gs_sptr beidou_b3i_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, - bool dump) + const Tlm_Conf &conf) { - return beidou_b3i_telemetry_decoder_gs_sptr(new beidou_b3i_telemetry_decoder_gs(satellite, dump)); + return beidou_b3i_telemetry_decoder_gs_sptr(new beidou_b3i_telemetry_decoder_gs(satellite, conf)); } beidou_b3i_telemetry_decoder_gs::beidou_b3i_telemetry_decoder_gs( - const Gnss_Satellite &satellite, bool dump) + const Gnss_Satellite &satellite, const Tlm_Conf &conf) : gr::block("beidou_b3i_telemetry_decoder_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) @@ -58,7 +82,9 @@ beidou_b3i_telemetry_decoder_gs::beidou_b3i_telemetry_decoder_gs( // Control messages to tracking block this->message_port_register_out(pmt::mp("telemetry_to_trk")); // initialize internal vars - d_dump = dump; + d_dump_filename = conf.dump_filename; + d_dump = conf.dump; + d_dump_mat = conf.dump_mat; d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); LOG(INFO) << "Initializing BeiDou B3I Telemetry Decoding for satellite " << this->d_satellite; @@ -104,8 +130,10 @@ beidou_b3i_telemetry_decoder_gs::beidou_b3i_telemetry_decoder_gs( beidou_b3i_telemetry_decoder_gs::~beidou_b3i_telemetry_decoder_gs() { DLOG(INFO) << "BeiDou B3I Telemetry decoder block (channel " << d_channel << ") destructor called."; + size_t pos = 0; if (d_dump_file.is_open() == true) { + pos = d_dump_file.tellp(); try { d_dump_file.close(); @@ -114,7 +142,127 @@ beidou_b3i_telemetry_decoder_gs::~beidou_b3i_telemetry_decoder_gs() { LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); } + if (pos == 0) + { + errorlib::error_code ec; + if (!fs::remove(fs::path(d_dump_filename), ec)) + { + LOG(WARNING) << "Error deleting temporary file"; + } + } } + if (d_dump && (pos != 0) && d_dump_mat) + { + try + { + save_matfile(); + } + catch (const std::exception &ex) + { + LOG(WARNING) << "Error saving the .mat file: " << ex.what(); + } + } +} + + +int32_t beidou_b3i_telemetry_decoder_gs::save_matfile() const +{ + std::ifstream::pos_type size; + const int32_t number_of_double_vars = 2; + const int32_t number_of_int_vars = 2; + const int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(int32_t) * number_of_int_vars; + std::ifstream dump_file; + std::string dump_filename_ = d_dump_filename; + + std::cout << "Generating .mat file for " << dump_filename_ << '\n'; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(dump_filename_.c_str(), std::ios::binary | std::ios::ate); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << '\n'; + return 1; + } + // count number of epochs and rewind + int64_t num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + if (num_epoch == 0LL) + { + // empty file, exit + return 1; + } + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + auto TOW_at_current_symbol_ms = std::vector(num_epoch); + auto tracking_sample_counter = std::vector(num_epoch); + auto TOW_at_Preamble_ms = std::vector(num_epoch); + auto nav_symbol = std::vector(num_epoch); + auto prn = std::vector(num_epoch); + + try + { + if (dump_file.is_open()) + { + for (int64_t i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&TOW_at_current_symbol_ms[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&tracking_sample_counter[i]), sizeof(uint64_t)); + dump_file.read(reinterpret_cast(&TOW_at_Preamble_ms[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&nav_symbol[i]), sizeof(int32_t)); + dump_file.read(reinterpret_cast(&prn[i]), sizeof(int32_t)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << '\n'; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = dump_filename_; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), nullptr, MAT_FT_MAT73); + if (reinterpret_cast(matfp) != nullptr) + { + std::array dims{1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("TOW_at_current_symbol_ms", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims.data(), TOW_at_current_symbol_ms.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("tracking_sample_counter", MAT_C_UINT64, MAT_T_UINT64, 2, dims.data(), tracking_sample_counter.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("TOW_at_Preamble_ms", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims.data(), TOW_at_Preamble_ms.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("nav_symbol", MAT_C_INT32, MAT_T_INT32, 2, dims.data(), nav_symbol.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_INT32, MAT_T_INT32, 2, dims.data(), prn.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + + return 0; } @@ -365,7 +513,6 @@ void beidou_b3i_telemetry_decoder_gs::set_channel(int32_t channel) { try { - d_dump_filename = "telemetry"; d_dump_filename.append(std::to_string(d_channel)); d_dump_filename.append(".dat"); d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); @@ -615,12 +762,17 @@ int beidou_b3i_telemetry_decoder_gs::general_work( { double tmp_double; uint64_t tmp_ulong_int; + int32_t tmp_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)); + tmp_int = (current_symbol.Prompt_I > 0.0 ? 1 : -1); + d_dump_file.write(reinterpret_cast(&tmp_int), sizeof(int32_t)); + tmp_int = static_cast(current_symbol.PRN); + d_dump_file.write(reinterpret_cast(&tmp_int), sizeof(int32_t)); } catch (const std::ifstream::failure &e) { diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b3i_telemetry_decoder_gs.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b3i_telemetry_decoder_gs.h index d36131a82..d35b65ecb 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b3i_telemetry_decoder_gs.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b3i_telemetry_decoder_gs.h @@ -23,6 +23,7 @@ #include "beidou_dnav_navigation_message.h" #include "gnss_block_interface.h" #include "gnss_satellite.h" +#include "tlm_conf.h" #include #include // for block #include // for gr_vector_const_void_star @@ -45,7 +46,7 @@ using beidou_b3i_telemetry_decoder_gs_sptr = beidou_b3i_telemetry_decoder_gs_sptr beidou_b3i_make_telemetry_decoder_gs( const Gnss_Satellite &satellite, - bool dump); + const Tlm_Conf &conf); /*! * \brief This class implements a block that decodes the BeiDou DNAV data. @@ -68,9 +69,11 @@ public: private: friend beidou_b3i_telemetry_decoder_gs_sptr beidou_b3i_make_telemetry_decoder_gs( const Gnss_Satellite &satellite, - bool dump); + const Tlm_Conf &conf); - beidou_b3i_telemetry_decoder_gs(const Gnss_Satellite &satellite, bool dump); + beidou_b3i_telemetry_decoder_gs(const Gnss_Satellite &satellite, const Tlm_Conf &conf); + + int32_t save_matfile() const; void decode_subframe(float *symbols); void decode_word(int32_t word_counter, const float *enc_word_symbols, @@ -116,6 +119,7 @@ private: bool d_sent_tlm_failed_msg; bool Flag_valid_word; bool d_dump; + bool d_dump_mat; }; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc index 1625844f9..e149ddf00 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc @@ -34,29 +34,52 @@ #include "gnss_synchro.h" #include #include +#include // for Mat_VarCreate #include // for make_any #include // for mp #include // for fmod +#include // for size_t #include // for abs #include // for exception #include // for cout #include // for make_shared +// clang-format off +#if HAS_STD_FILESYSTEM +#include +namespace errorlib = std; +#if HAS_STD_FILESYSTEM_EXPERIMENTAL +#include +namespace fs = std::experimental::filesystem; +#else +#include +namespace fs = std::filesystem; +#endif +#else +#include // for remove +#include // for path, operator<< +#include // for filesystem +#include // for error_code +namespace fs = boost::filesystem; +namespace errorlib = boost::system; +#endif +// clang-format on #define CRC_ERROR_LIMIT 6 galileo_telemetry_decoder_gs_sptr -galileo_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, int frame_type, bool dump) +galileo_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, const Tlm_Conf &conf, int frame_type) { - return galileo_telemetry_decoder_gs_sptr(new galileo_telemetry_decoder_gs(satellite, frame_type, dump)); + return galileo_telemetry_decoder_gs_sptr(new galileo_telemetry_decoder_gs(satellite, conf, frame_type)); } galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs( - const Gnss_Satellite &satellite, int frame_type, - bool dump) : gr::block("galileo_telemetry_decoder_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) + const Gnss_Satellite &satellite, + const Tlm_Conf &conf, + int frame_type) : gr::block("galileo_telemetry_decoder_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { // prevent telemetry symbols accumulation in output buffers this->set_max_noutput_items(1); @@ -69,7 +92,9 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs( d_band = '1'; // initialize internal vars - d_dump = dump; + d_dump_filename = conf.dump_filename; + d_dump = conf.dump; + d_dump_mat = conf.dump_mat; d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); d_frame_type = frame_type; DLOG(INFO) << "Initializing GALILEO UNIFIED TELEMETRY DECODER"; @@ -213,8 +238,10 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs( galileo_telemetry_decoder_gs::~galileo_telemetry_decoder_gs() { DLOG(INFO) << "Galileo Telemetry decoder block (channel " << d_channel << ") destructor called."; + size_t pos = 0; if (d_dump_file.is_open() == true) { + pos = d_dump_file.tellp(); try { d_dump_file.close(); @@ -223,7 +250,127 @@ galileo_telemetry_decoder_gs::~galileo_telemetry_decoder_gs() { LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); } + if (pos == 0) + { + errorlib::error_code ec; + if (!fs::remove(fs::path(d_dump_filename), ec)) + { + LOG(WARNING) << "Error deleting temporary file"; + } + } } + if (d_dump && (pos != 0) && d_dump_mat) + { + try + { + save_matfile(); + } + catch (const std::exception &ex) + { + LOG(WARNING) << "Error saving the .mat file: " << ex.what(); + } + } +} + + +int32_t galileo_telemetry_decoder_gs::save_matfile() const +{ + std::ifstream::pos_type size; + const int32_t number_of_double_vars = 2; + const int32_t number_of_int_vars = 2; + const int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(int32_t) * number_of_int_vars; + std::ifstream dump_file; + std::string dump_filename_ = d_dump_filename; + + std::cout << "Generating .mat file for " << dump_filename_ << '\n'; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(dump_filename_.c_str(), std::ios::binary | std::ios::ate); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << '\n'; + return 1; + } + // count number of epochs and rewind + int64_t num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + if (num_epoch == 0LL) + { + // empty file, exit + return 1; + } + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + auto TOW_at_current_symbol_ms = std::vector(num_epoch); + auto tracking_sample_counter = std::vector(num_epoch); + auto TOW_at_Preamble_ms = std::vector(num_epoch); + auto nav_symbol = std::vector(num_epoch); + auto prn = std::vector(num_epoch); + + try + { + if (dump_file.is_open()) + { + for (int64_t i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&TOW_at_current_symbol_ms[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&tracking_sample_counter[i]), sizeof(uint64_t)); + dump_file.read(reinterpret_cast(&TOW_at_Preamble_ms[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&nav_symbol[i]), sizeof(int32_t)); + dump_file.read(reinterpret_cast(&prn[i]), sizeof(int32_t)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << '\n'; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = dump_filename_; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), nullptr, MAT_FT_MAT73); + if (reinterpret_cast(matfp) != nullptr) + { + std::array dims{1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("TOW_at_current_symbol_ms", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims.data(), TOW_at_current_symbol_ms.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("tracking_sample_counter", MAT_C_UINT64, MAT_T_UINT64, 2, dims.data(), tracking_sample_counter.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("TOW_at_Preamble_ms", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims.data(), TOW_at_Preamble_ms.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("nav_symbol", MAT_C_INT32, MAT_T_INT32, 2, dims.data(), nav_symbol.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_INT32, MAT_T_INT32, 2, dims.data(), prn.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + + return 0; } @@ -535,7 +682,6 @@ void galileo_telemetry_decoder_gs::set_channel(int32_t channel) { try { - d_dump_filename = "telemetry"; d_dump_filename.append(std::to_string(d_channel)); d_dump_filename.append(".dat"); d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); @@ -907,12 +1053,31 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__(( { double tmp_double; uint64_t tmp_ulong_int; + int32_t tmp_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)); + switch (d_frame_type) + { + case 1: + tmp_int = (current_symbol.Prompt_I > 0.0 ? 1 : -1); + break; + case 2: + tmp_int = (current_symbol.Prompt_Q > 0.0 ? 1 : -1); + break; + case 3: + tmp_int = (current_symbol.Prompt_I > 0.0 ? 1 : -1); + break; + default: + tmp_int = 0; + break; + } + d_dump_file.write(reinterpret_cast(&tmp_int), sizeof(int32_t)); + tmp_int = static_cast(current_symbol.PRN); + d_dump_file.write(reinterpret_cast(&tmp_int), sizeof(int32_t)); } catch (const std::ifstream::failure &e) { diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h index b3049c3a3..e94af2a73 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h @@ -28,6 +28,7 @@ #include "galileo_inav_message.h" #include "gnss_block_interface.h" #include "gnss_satellite.h" +#include "tlm_conf.h" #include #include // for block #include // for gr_vector_const_void_star @@ -49,8 +50,8 @@ using galileo_telemetry_decoder_gs_sptr = gnss_shared_ptr #include +#include // for Mat_VarCreate #include // for make_any #include // for mp #include // for floor, round +#include // for size_t #include // for abs #include // for exception #include // for cout #include // for shared_ptr, make_shared +#include + +// clang-format off +#if HAS_STD_FILESYSTEM +#include +namespace errorlib = std; +#if HAS_STD_FILESYSTEM_EXPERIMENTAL +#include +namespace fs = std::experimental::filesystem; +#else +#include +namespace fs = std::filesystem; +#endif +#else +#include // for remove +#include // for path, operator<< +#include // for filesystem +#include // for error_code +namespace fs = boost::filesystem; +namespace errorlib = boost::system; +#endif +// clang-format on #define CRC_ERROR_LIMIT 6 glonass_l1_ca_telemetry_decoder_gs_sptr -glonass_l1_ca_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, bool dump) +glonass_l1_ca_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, const Tlm_Conf &conf) { - return glonass_l1_ca_telemetry_decoder_gs_sptr(new glonass_l1_ca_telemetry_decoder_gs(satellite, dump)); + return glonass_l1_ca_telemetry_decoder_gs_sptr(new glonass_l1_ca_telemetry_decoder_gs(satellite, conf)); } glonass_l1_ca_telemetry_decoder_gs::glonass_l1_ca_telemetry_decoder_gs( const Gnss_Satellite &satellite, - bool dump) : gr::block("glonass_l1_ca_telemetry_decoder_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) + const Tlm_Conf &conf) : gr::block("glonass_l1_ca_telemetry_decoder_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { // prevent telemetry symbols accumulation in output buffers this->set_max_noutput_items(1); @@ -55,7 +79,9 @@ glonass_l1_ca_telemetry_decoder_gs::glonass_l1_ca_telemetry_decoder_gs( // Control messages to tracking block this->message_port_register_out(pmt::mp("telemetry_to_trk")); // initialize internal vars - d_dump = dump; + d_dump_filename = conf.dump_filename; + d_dump = conf.dump; + d_dump_mat = conf.dump_mat; d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); LOG(INFO) << "Initializing GLONASS L1 CA TELEMETRY DECODING"; @@ -97,8 +123,10 @@ glonass_l1_ca_telemetry_decoder_gs::glonass_l1_ca_telemetry_decoder_gs( glonass_l1_ca_telemetry_decoder_gs::~glonass_l1_ca_telemetry_decoder_gs() { DLOG(INFO) << "Glonass L1 Telemetry decoder block (channel " << d_channel << ") destructor called."; + size_t pos = 0; if (d_dump_file.is_open() == true) { + pos = d_dump_file.tellp(); try { d_dump_file.close(); @@ -107,7 +135,127 @@ glonass_l1_ca_telemetry_decoder_gs::~glonass_l1_ca_telemetry_decoder_gs() { LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); } + if (pos == 0) + { + errorlib::error_code ec; + if (!fs::remove(fs::path(d_dump_filename), ec)) + { + LOG(WARNING) << "Error deleting temporary file"; + } + } } + if (d_dump && (pos != 0)) + { + try + { + save_matfile(); + } + catch (const std::exception &ex) + { + LOG(WARNING) << "Error saving the .mat file: " << ex.what(); + } + } +} + + +int32_t glonass_l1_ca_telemetry_decoder_gs::save_matfile() const +{ + std::ifstream::pos_type size; + const int32_t number_of_double_vars = 2; + const int32_t number_of_int_vars = 2; + const int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(int32_t) * number_of_int_vars; + std::ifstream dump_file; + std::string dump_filename_ = d_dump_filename; + + std::cout << "Generating .mat file for " << dump_filename_ << '\n'; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(dump_filename_.c_str(), std::ios::binary | std::ios::ate); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << '\n'; + return 1; + } + // count number of epochs and rewind + int64_t num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + if (num_epoch == 0LL) + { + // empty file, exit + return 1; + } + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + auto TOW_at_current_symbol_ms = std::vector(num_epoch); + auto tracking_sample_counter = std::vector(num_epoch); + auto TOW_at_Preamble_ms = std::vector(num_epoch); + auto nav_symbol = std::vector(num_epoch); + auto prn = std::vector(num_epoch); + + try + { + if (dump_file.is_open()) + { + for (int64_t i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&TOW_at_current_symbol_ms[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&tracking_sample_counter[i]), sizeof(uint64_t)); + dump_file.read(reinterpret_cast(&TOW_at_Preamble_ms[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&nav_symbol[i]), sizeof(int32_t)); + dump_file.read(reinterpret_cast(&prn[i]), sizeof(int32_t)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << '\n'; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = dump_filename_; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), nullptr, MAT_FT_MAT73); + if (reinterpret_cast(matfp) != nullptr) + { + std::array dims{1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("TOW_at_current_symbol_ms", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims.data(), TOW_at_current_symbol_ms.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("tracking_sample_counter", MAT_C_UINT64, MAT_T_UINT64, 2, dims.data(), tracking_sample_counter.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("TOW_at_Preamble_ms", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims.data(), TOW_at_Preamble_ms.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("nav_symbol", MAT_C_INT32, MAT_T_INT32, 2, dims.data(), nav_symbol.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_INT32, MAT_T_INT32, 2, dims.data(), prn.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + + return 0; } @@ -234,7 +382,6 @@ void glonass_l1_ca_telemetry_decoder_gs::set_channel(int32_t channel) { try { - d_dump_filename = "telemetry"; d_dump_filename.append(std::to_string(d_channel)); d_dump_filename.append(".dat"); d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); @@ -414,12 +561,17 @@ int glonass_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribu { double tmp_double; uint64_t tmp_ulong_int; + int32_t tmp_int; tmp_double = d_TOW_at_current_symbol; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_ulong_int = current_symbol.Tracking_sample_counter; d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(uint64_t)); tmp_double = 0; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_int = (current_symbol.Prompt_I > 0.0 ? 1 : -1); + d_dump_file.write(reinterpret_cast(&tmp_int), sizeof(int32_t)); + tmp_int = static_cast(current_symbol.PRN); + d_dump_file.write(reinterpret_cast(&tmp_int), sizeof(int32_t)); } catch (const std::ifstream::failure &e) { diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_gs.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_gs.h index c7f523b7a..c87132069 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_gs.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_gs.h @@ -27,6 +27,7 @@ #include "gnss_block_interface.h" #include "gnss_satellite.h" #include "gnss_synchro.h" +#include "tlm_conf.h" #include #include // for block #include // for gr_vector_const_void_star @@ -47,7 +48,7 @@ using glonass_l1_ca_telemetry_decoder_gs_sptr = gnss_shared_ptr d_preambles_bits{GLONASS_GNAV_PREAMBLE}; const int32_t d_symbols_per_preamble = GLONASS_GNAV_PREAMBLE_LENGTH_SYMBOLS; + int32_t save_matfile() const; + void decode_string(const double *symbols, int32_t frame_length); // Help with coherent tracking @@ -118,6 +121,7 @@ private: bool flag_TOW_set; // Indicates when time of week is set bool Flag_valid_word; bool d_dump; + bool d_dump_mat; }; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_gs.cc index 09b4bf13c..c3dbfa685 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_gs.cc @@ -25,28 +25,52 @@ #include "glonass_gnav_utc_model.h" #include #include +#include // for Mat_VarCreate #include // for make_any #include // for mp #include // for floor, round +#include // for size_t #include // for abs #include // for exception #include // for cout #include // for shared_ptr, make_shared +#include + +// clang-format off +#if HAS_STD_FILESYSTEM +#include +namespace errorlib = std; +#if HAS_STD_FILESYSTEM_EXPERIMENTAL +#include +namespace fs = std::experimental::filesystem; +#else +#include +namespace fs = std::filesystem; +#endif +#else +#include // for remove +#include // for path, operator<< +#include // for filesystem +#include // for error_code +namespace fs = boost::filesystem; +namespace errorlib = boost::system; +#endif +// clang-format on #define CRC_ERROR_LIMIT 6 glonass_l2_ca_telemetry_decoder_gs_sptr -glonass_l2_ca_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, bool dump) +glonass_l2_ca_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, const Tlm_Conf &conf) { - return glonass_l2_ca_telemetry_decoder_gs_sptr(new glonass_l2_ca_telemetry_decoder_gs(satellite, dump)); + return glonass_l2_ca_telemetry_decoder_gs_sptr(new glonass_l2_ca_telemetry_decoder_gs(satellite, conf)); } glonass_l2_ca_telemetry_decoder_gs::glonass_l2_ca_telemetry_decoder_gs( const Gnss_Satellite &satellite, - bool dump) : gr::block("glonass_l2_ca_telemetry_decoder_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) + const Tlm_Conf &conf) : gr::block("glonass_l2_ca_telemetry_decoder_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { // prevent telemetry symbols accumulation in output buffers this->set_max_noutput_items(1); @@ -55,7 +79,9 @@ glonass_l2_ca_telemetry_decoder_gs::glonass_l2_ca_telemetry_decoder_gs( // Control messages to tracking block this->message_port_register_out(pmt::mp("telemetry_to_trk")); // initialize internal vars - d_dump = dump; + d_dump_filename = conf.dump_filename; + d_dump = conf.dump; + d_dump_mat = conf.dump_mat; d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); LOG(INFO) << "Initializing GLONASS L2 CA TELEMETRY DECODING"; @@ -97,8 +123,10 @@ glonass_l2_ca_telemetry_decoder_gs::glonass_l2_ca_telemetry_decoder_gs( glonass_l2_ca_telemetry_decoder_gs::~glonass_l2_ca_telemetry_decoder_gs() { DLOG(INFO) << "Glonass L2 Telemetry decoder block (channel " << d_channel << ") destructor called."; + size_t pos = 0; if (d_dump_file.is_open() == true) { + pos = d_dump_file.tellp(); try { d_dump_file.close(); @@ -107,7 +135,127 @@ glonass_l2_ca_telemetry_decoder_gs::~glonass_l2_ca_telemetry_decoder_gs() { LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); } + if (pos == 0) + { + errorlib::error_code ec; + if (!fs::remove(fs::path(d_dump_filename), ec)) + { + LOG(WARNING) << "Error deleting temporary file"; + } + } } + if (d_dump && (pos != 0) && d_dump_mat) + { + try + { + save_matfile(); + } + catch (const std::exception &ex) + { + LOG(WARNING) << "Error saving the .mat file: " << ex.what(); + } + } +} + + +int32_t glonass_l2_ca_telemetry_decoder_gs::save_matfile() const +{ + std::ifstream::pos_type size; + const int32_t number_of_double_vars = 2; + const int32_t number_of_int_vars = 2; + const int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(int32_t) * number_of_int_vars; + std::ifstream dump_file; + std::string dump_filename_ = d_dump_filename; + + std::cout << "Generating .mat file for " << dump_filename_ << '\n'; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(dump_filename_.c_str(), std::ios::binary | std::ios::ate); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << '\n'; + return 1; + } + // count number of epochs and rewind + int64_t num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + if (num_epoch == 0LL) + { + // empty file, exit + return 1; + } + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + auto TOW_at_current_symbol_ms = std::vector(num_epoch); + auto tracking_sample_counter = std::vector(num_epoch); + auto TOW_at_Preamble_ms = std::vector(num_epoch); + auto nav_symbol = std::vector(num_epoch); + auto prn = std::vector(num_epoch); + + try + { + if (dump_file.is_open()) + { + for (int64_t i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&TOW_at_current_symbol_ms[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&tracking_sample_counter[i]), sizeof(uint64_t)); + dump_file.read(reinterpret_cast(&TOW_at_Preamble_ms[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&nav_symbol[i]), sizeof(int32_t)); + dump_file.read(reinterpret_cast(&prn[i]), sizeof(int32_t)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << '\n'; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = dump_filename_; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), nullptr, MAT_FT_MAT73); + if (reinterpret_cast(matfp) != nullptr) + { + std::array dims{1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("TOW_at_current_symbol_ms", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims.data(), TOW_at_current_symbol_ms.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("tracking_sample_counter", MAT_C_UINT64, MAT_T_UINT64, 2, dims.data(), tracking_sample_counter.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("TOW_at_Preamble_ms", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims.data(), TOW_at_Preamble_ms.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("nav_symbol", MAT_C_INT32, MAT_T_INT32, 2, dims.data(), nav_symbol.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_INT32, MAT_T_INT32, 2, dims.data(), prn.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + + return 0; } @@ -233,7 +381,6 @@ void glonass_l2_ca_telemetry_decoder_gs::set_channel(int32_t channel) { try { - d_dump_filename = "telemetry"; d_dump_filename.append(std::to_string(d_channel)); d_dump_filename.append(".dat"); d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); @@ -413,12 +560,17 @@ int glonass_l2_ca_telemetry_decoder_gs::general_work(int noutput_items __attribu { double tmp_double; uint64_t tmp_ulong_int; + int32_t tmp_int; tmp_double = d_TOW_at_current_symbol; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_ulong_int = current_symbol.Tracking_sample_counter; d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(uint64_t)); tmp_double = 0; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_int = (current_symbol.Prompt_I > 0.0 ? 1 : -1); + d_dump_file.write(reinterpret_cast(&tmp_int), sizeof(int32_t)); + tmp_int = static_cast(current_symbol.PRN); + d_dump_file.write(reinterpret_cast(&tmp_int), sizeof(int32_t)); } catch (const std::ifstream::failure &e) { diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_gs.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_gs.h index b8cfc22fb..784bd4dfa 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_gs.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_gs.h @@ -26,6 +26,7 @@ #include "gnss_block_interface.h" #include "gnss_satellite.h" #include "gnss_synchro.h" +#include "tlm_conf.h" #include #include #include // for gr_vector_const_void_star @@ -46,7 +47,7 @@ using glonass_l2_ca_telemetry_decoder_gs_sptr = gnss_shared_ptr d_preambles_bits{GLONASS_GNAV_PREAMBLE}; const int32_t d_symbols_per_preamble = GLONASS_GNAV_PREAMBLE_LENGTH_SYMBOLS; + int32_t save_matfile() const; + void decode_string(const double *symbols, int32_t frame_length); // Storage for incoming data @@ -112,6 +115,7 @@ private: bool d_flag_preamble; // Flag indicating when preamble was found bool flag_TOW_set; // Indicates when time of week is set bool d_dump; + bool d_dump_mat; }; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.cc index 3d409149a..0501b60f9 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.cc @@ -24,14 +24,37 @@ #include "gps_utc_model.h" // for Gps_Utc_Model #include #include +#include // for Mat_VarCreate #include // for make_any #include // for mp #include // for round +#include // for size_t #include // for memcpy #include // for exception #include // for cout #include // for shared_ptr +#include +// clang-format off +#if HAS_STD_FILESYSTEM +#include +namespace errorlib = std; +#if HAS_STD_FILESYSTEM_EXPERIMENTAL +#include +namespace fs = std::experimental::filesystem; +#else +#include +namespace fs = std::filesystem; +#endif +#else +#include // for remove +#include // for path, operator<< +#include // for filesystem +#include // for error_code +namespace fs = boost::filesystem; +namespace errorlib = boost::system; +#endif +// clang-format on #ifdef COMPILER_HAS_ROTL #include @@ -49,16 +72,16 @@ auto rotl = [](uint32_t x, uint32_t n) { return (((x) << (n)) ^ ((x) >> (32 - (n gps_l1_ca_telemetry_decoder_gs_sptr -gps_l1_ca_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, bool dump) +gps_l1_ca_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, const Tlm_Conf &conf) { - return gps_l1_ca_telemetry_decoder_gs_sptr(new gps_l1_ca_telemetry_decoder_gs(satellite, dump)); + return gps_l1_ca_telemetry_decoder_gs_sptr(new gps_l1_ca_telemetry_decoder_gs(satellite, conf)); } gps_l1_ca_telemetry_decoder_gs::gps_l1_ca_telemetry_decoder_gs( const Gnss_Satellite &satellite, - bool dump) : gr::block("gps_navigation_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) + const Tlm_Conf &conf) : gr::block("gps_navigation_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { // prevent telemetry symbols accumulation in output buffers this->set_max_noutput_items(1); @@ -71,7 +94,10 @@ gps_l1_ca_telemetry_decoder_gs::gps_l1_ca_telemetry_decoder_gs( d_sent_tlm_failed_msg = false; // initialize internal vars - d_dump = dump; + d_dump_filename = conf.dump_filename; + d_dump = conf.dump; + d_dump_mat = conf.dump_mat; + d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); DLOG(INFO) << "Initializing GPS L1 TELEMETRY DECODER"; @@ -119,8 +145,10 @@ gps_l1_ca_telemetry_decoder_gs::gps_l1_ca_telemetry_decoder_gs( gps_l1_ca_telemetry_decoder_gs::~gps_l1_ca_telemetry_decoder_gs() { DLOG(INFO) << "GPS L1 C/A Telemetry decoder block (channel " << d_channel << ") destructor called."; + size_t pos = 0; if (d_dump_file.is_open() == true) { + pos = d_dump_file.tellp(); try { d_dump_file.close(); @@ -129,7 +157,127 @@ gps_l1_ca_telemetry_decoder_gs::~gps_l1_ca_telemetry_decoder_gs() { LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); } + if (pos == 0) + { + errorlib::error_code ec; + if (!fs::remove(fs::path(d_dump_filename), ec)) + { + LOG(WARNING) << "Error deleting temporary file"; + } + } } + if (d_dump && (pos != 0) && d_dump_mat) + { + try + { + save_matfile(); + } + catch (const std::exception &ex) + { + LOG(WARNING) << "Error saving the .mat file: " << ex.what(); + } + } +} + + +int32_t gps_l1_ca_telemetry_decoder_gs::save_matfile() const +{ + std::ifstream::pos_type size; + const int32_t number_of_double_vars = 2; + const int32_t number_of_int_vars = 2; + const int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(int32_t) * number_of_int_vars; + std::ifstream dump_file; + std::string dump_filename_ = d_dump_filename; + + std::cout << "Generating .mat file for " << dump_filename_ << '\n'; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(dump_filename_.c_str(), std::ios::binary | std::ios::ate); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << '\n'; + return 1; + } + // count number of epochs and rewind + int64_t num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + if (num_epoch == 0LL) + { + // empty file, exit + return 1; + } + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + auto TOW_at_current_symbol_ms = std::vector(num_epoch); + auto tracking_sample_counter = std::vector(num_epoch); + auto TOW_at_Preamble_ms = std::vector(num_epoch); + auto nav_symbol = std::vector(num_epoch); + auto prn = std::vector(num_epoch); + + try + { + if (dump_file.is_open()) + { + for (int64_t i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&TOW_at_current_symbol_ms[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&tracking_sample_counter[i]), sizeof(uint64_t)); + dump_file.read(reinterpret_cast(&TOW_at_Preamble_ms[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&nav_symbol[i]), sizeof(int32_t)); + dump_file.read(reinterpret_cast(&prn[i]), sizeof(int32_t)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << '\n'; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = dump_filename_; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), nullptr, MAT_FT_MAT73); + if (reinterpret_cast(matfp) != nullptr) + { + std::array dims{1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("TOW_at_current_symbol_ms", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims.data(), TOW_at_current_symbol_ms.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("tracking_sample_counter", MAT_C_UINT64, MAT_T_UINT64, 2, dims.data(), tracking_sample_counter.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("TOW_at_Preamble_ms", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims.data(), TOW_at_Preamble_ms.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("nav_symbol", MAT_C_INT32, MAT_T_INT32, 2, dims.data(), nav_symbol.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_INT32, MAT_T_INT32, 2, dims.data(), prn.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + + return 0; } @@ -181,7 +329,6 @@ void gps_l1_ca_telemetry_decoder_gs::set_channel(int32_t channel) { try { - d_dump_filename = "telemetry"; d_dump_filename.append(std::to_string(d_channel)); d_dump_filename.append(".dat"); d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); @@ -501,12 +648,17 @@ int gps_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribute__ { double tmp_double; uint64_t tmp_ulong_int; + int32_t tmp_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)); + tmp_int = (current_symbol.Prompt_I > 0.0 ? 1 : -1); + d_dump_file.write(reinterpret_cast(&tmp_int), sizeof(int32_t)); + tmp_int = static_cast(current_symbol.PRN); + d_dump_file.write(reinterpret_cast(&tmp_int), sizeof(int32_t)); } catch (const std::ifstream::failure &e) { diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.h index 566db3e98..3f72d117a 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.h @@ -25,6 +25,7 @@ #include "gnss_satellite.h" #include "gnss_synchro.h" #include "gps_navigation_message.h" +#include "tlm_conf.h" #include #include // for block #include // for gr_vector_const_void_star @@ -46,7 +47,7 @@ using gps_l1_ca_telemetry_decoder_gs_sptr = gnss_shared_ptr #include +#include // for Mat_VarCreate #include // for make_any #include // for mp #include // for bitset #include // for round +#include // for size_t #include // for exception #include // for cout #include // for shared_ptr, make_shared +#include +// clang-format off +#if HAS_STD_FILESYSTEM +#include +namespace errorlib = std; +#if HAS_STD_FILESYSTEM_EXPERIMENTAL +#include +namespace fs = std::experimental::filesystem; +#else +#include +namespace fs = std::filesystem; +#endif +#else +#include // for remove +#include // for path, operator<< +#include // for filesystem +#include // for error_code +namespace fs = boost::filesystem; +namespace errorlib = boost::system; +#endif +// clang-format on gps_l2c_telemetry_decoder_gs_sptr -gps_l2c_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, bool dump) +gps_l2c_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, const Tlm_Conf &conf) { - return gps_l2c_telemetry_decoder_gs_sptr(new gps_l2c_telemetry_decoder_gs(satellite, dump)); + return gps_l2c_telemetry_decoder_gs_sptr(new gps_l2c_telemetry_decoder_gs(satellite, conf)); } gps_l2c_telemetry_decoder_gs::gps_l2c_telemetry_decoder_gs( - const Gnss_Satellite &satellite, bool dump) : gr::block("gps_l2c_telemetry_decoder_gs", - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) + const Gnss_Satellite &satellite, + const Tlm_Conf &conf) : gr::block("gps_l2c_telemetry_decoder_gs", + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { // prevent telemetry symbols accumulation in output buffers this->set_max_noutput_items(1); @@ -59,7 +83,9 @@ gps_l2c_telemetry_decoder_gs::gps_l2c_telemetry_decoder_gs( d_max_symbols_without_valid_frame = GPS_L2_CNAV_DATA_PAGE_BITS * GPS_L2_SYMBOLS_PER_BIT * 5; // rise alarm if 5 consecutive subframes have no valid CRC // initialize internal vars - d_dump = dump; + d_dump_filename = conf.dump_filename; + d_dump = conf.dump; + d_dump_mat = conf.dump_mat; d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); DLOG(INFO) << "GPS L2C M TELEMETRY PROCESSING: satellite " << d_satellite; // set_output_multiple (1); @@ -81,8 +107,10 @@ gps_l2c_telemetry_decoder_gs::gps_l2c_telemetry_decoder_gs( gps_l2c_telemetry_decoder_gs::~gps_l2c_telemetry_decoder_gs() { DLOG(INFO) << "GPS L2C Telemetry decoder block (channel " << d_channel << ") destructor called."; + size_t pos = 0; if (d_dump_file.is_open() == true) { + pos = d_dump_file.tellp(); try { d_dump_file.close(); @@ -91,7 +119,127 @@ gps_l2c_telemetry_decoder_gs::~gps_l2c_telemetry_decoder_gs() { LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); } + if (pos == 0) + { + errorlib::error_code ec; + if (!fs::remove(fs::path(d_dump_filename), ec)) + { + LOG(WARNING) << "Error deleting temporary file"; + } + } } + if (d_dump && (pos != 0) && d_dump_mat) + { + try + { + save_matfile(); + } + catch (const std::exception &ex) + { + LOG(WARNING) << "Error saving the .mat file: " << ex.what(); + } + } +} + + +int32_t gps_l2c_telemetry_decoder_gs::save_matfile() const +{ + std::ifstream::pos_type size; + const int32_t number_of_double_vars = 2; + const int32_t number_of_int_vars = 2; + const int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(int32_t) * number_of_int_vars; + std::ifstream dump_file; + std::string dump_filename_ = d_dump_filename; + + std::cout << "Generating .mat file for " << dump_filename_ << '\n'; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(dump_filename_.c_str(), std::ios::binary | std::ios::ate); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << '\n'; + return 1; + } + // count number of epochs and rewind + int64_t num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + if (num_epoch == 0LL) + { + // empty file, exit + return 1; + } + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + auto TOW_at_current_symbol_ms = std::vector(num_epoch); + auto tracking_sample_counter = std::vector(num_epoch); + auto TOW_at_Preamble_ms = std::vector(num_epoch); + auto nav_symbol = std::vector(num_epoch); + auto prn = std::vector(num_epoch); + + try + { + if (dump_file.is_open()) + { + for (int64_t i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&TOW_at_current_symbol_ms[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&tracking_sample_counter[i]), sizeof(uint64_t)); + dump_file.read(reinterpret_cast(&TOW_at_Preamble_ms[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&nav_symbol[i]), sizeof(int32_t)); + dump_file.read(reinterpret_cast(&prn[i]), sizeof(int32_t)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << '\n'; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = dump_filename_; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), nullptr, MAT_FT_MAT73); + if (reinterpret_cast(matfp) != nullptr) + { + std::array dims{1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("TOW_at_current_symbol_ms", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims.data(), TOW_at_current_symbol_ms.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("tracking_sample_counter", MAT_C_UINT64, MAT_T_UINT64, 2, dims.data(), tracking_sample_counter.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("TOW_at_Preamble_ms", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims.data(), TOW_at_Preamble_ms.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("nav_symbol", MAT_C_INT32, MAT_T_INT32, 2, dims.data(), nav_symbol.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_INT32, MAT_T_INT32, 2, dims.data(), prn.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + + return 0; } @@ -113,7 +261,6 @@ void gps_l2c_telemetry_decoder_gs::set_channel(int channel) { try { - d_dump_filename = "telemetry_L2CM_"; d_dump_filename.append(std::to_string(d_channel)); d_dump_filename.append(".dat"); d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); @@ -252,12 +399,17 @@ int gps_l2c_telemetry_decoder_gs::general_work(int noutput_items __attribute__(( { double tmp_double; uint64_t tmp_ulong_int; + int32_t tmp_int; tmp_double = d_TOW_at_current_symbol; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_ulong_int = current_synchro_data.Tracking_sample_counter; d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(uint64_t)); tmp_double = d_TOW_at_Preamble; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_int = (current_synchro_data.Prompt_I > 0.0 ? 1 : -1); + d_dump_file.write(reinterpret_cast(&tmp_int), sizeof(int32_t)); + tmp_int = static_cast(current_synchro_data.PRN); + d_dump_file.write(reinterpret_cast(&tmp_int), sizeof(int32_t)); } catch (const std::ifstream::failure &e) { diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_gs.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_gs.h index d49faf7d3..b3bb750d5 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_gs.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_gs.h @@ -23,6 +23,7 @@ #include "gnss_block_interface.h" #include "gnss_satellite.h" #include "gps_cnav_navigation_message.h" +#include "tlm_conf.h" #include #include // for gr_vector_const_void_star #include @@ -46,7 +47,7 @@ using gps_l2c_telemetry_decoder_gs_sptr = gnss_shared_ptr #include +#include // for Mat_VarCreate #include // for make_any #include // for mp #include // for std::bitset +#include // for size_t #include // for std::llabs #include // for std::exception #include // for std::cout #include // for shared_ptr, make_shared +#include +// clang-format off +#if HAS_STD_FILESYSTEM +#include +namespace errorlib = std; +#if HAS_STD_FILESYSTEM_EXPERIMENTAL +#include +namespace fs = std::experimental::filesystem; +#else +#include +namespace fs = std::filesystem; +#endif +#else +#include // for remove +#include // for path, operator<< +#include // for filesystem +#include // for error_code +namespace fs = boost::filesystem; +namespace errorlib = boost::system; +#endif +// clang-format on gps_l5_telemetry_decoder_gs_sptr -gps_l5_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, bool dump) +gps_l5_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, const Tlm_Conf &conf) { - return gps_l5_telemetry_decoder_gs_sptr(new gps_l5_telemetry_decoder_gs(satellite, dump)); + return gps_l5_telemetry_decoder_gs_sptr(new gps_l5_telemetry_decoder_gs(satellite, conf)); } gps_l5_telemetry_decoder_gs::gps_l5_telemetry_decoder_gs( - const Gnss_Satellite &satellite, bool dump) : gr::block("gps_l5_telemetry_decoder_gs", - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) + const Gnss_Satellite &satellite, + const Tlm_Conf &conf) : gr::block("gps_l5_telemetry_decoder_gs", + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { // prevent telemetry symbols accumulation in output buffers this->set_max_noutput_items(1); @@ -58,7 +82,9 @@ gps_l5_telemetry_decoder_gs::gps_l5_telemetry_decoder_gs( d_max_symbols_without_valid_frame = GPS_L5_CNAV_DATA_PAGE_BITS * GPS_L5_SYMBOLS_PER_BIT * 10; // rise alarm if 20 consecutive subframes have no valid CRC // initialize internal vars - d_dump = dump; + d_dump_filename = conf.dump_filename; + d_dump = conf.dump; + d_dump_mat = conf.dump_mat; d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); DLOG(INFO) << "GPS L5 TELEMETRY PROCESSING: satellite " << d_satellite; d_channel = 0; @@ -76,8 +102,10 @@ gps_l5_telemetry_decoder_gs::gps_l5_telemetry_decoder_gs( gps_l5_telemetry_decoder_gs::~gps_l5_telemetry_decoder_gs() { DLOG(INFO) << "GPS L5 Telemetry decoder block (channel " << d_channel << ") destructor called."; + size_t pos = 0; if (d_dump_file.is_open() == true) { + pos = d_dump_file.tellp(); try { d_dump_file.close(); @@ -86,7 +114,127 @@ gps_l5_telemetry_decoder_gs::~gps_l5_telemetry_decoder_gs() { LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); } + if (pos == 0) + { + errorlib::error_code ec; + if (!fs::remove(fs::path(d_dump_filename), ec)) + { + LOG(WARNING) << "Error deleting temporary file"; + } + } } + if (d_dump && (pos != 0) && d_dump_mat) + { + try + { + save_matfile(); + } + catch (const std::exception &ex) + { + LOG(WARNING) << "Error saving the .mat file: " << ex.what(); + } + } +} + + +int32_t gps_l5_telemetry_decoder_gs::save_matfile() const +{ + std::ifstream::pos_type size; + const int32_t number_of_double_vars = 2; + const int32_t number_of_int_vars = 2; + const int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(int32_t) * number_of_int_vars; + std::ifstream dump_file; + std::string dump_filename_ = d_dump_filename; + + std::cout << "Generating .mat file for " << dump_filename_ << '\n'; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(dump_filename_.c_str(), std::ios::binary | std::ios::ate); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << '\n'; + return 1; + } + // count number of epochs and rewind + int64_t num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + if (num_epoch == 0LL) + { + // empty file, exit + return 1; + } + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + auto TOW_at_current_symbol_ms = std::vector(num_epoch); + auto tracking_sample_counter = std::vector(num_epoch); + auto TOW_at_Preamble_ms = std::vector(num_epoch); + auto nav_symbol = std::vector(num_epoch); + auto prn = std::vector(num_epoch); + + try + { + if (dump_file.is_open()) + { + for (int64_t i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&TOW_at_current_symbol_ms[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&tracking_sample_counter[i]), sizeof(uint64_t)); + dump_file.read(reinterpret_cast(&TOW_at_Preamble_ms[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&nav_symbol[i]), sizeof(int32_t)); + dump_file.read(reinterpret_cast(&prn[i]), sizeof(int32_t)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << '\n'; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = dump_filename_; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), nullptr, MAT_FT_MAT73); + if (reinterpret_cast(matfp) != nullptr) + { + std::array dims{1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("TOW_at_current_symbol_ms", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims.data(), TOW_at_current_symbol_ms.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("tracking_sample_counter", MAT_C_UINT64, MAT_T_UINT64, 2, dims.data(), tracking_sample_counter.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("TOW_at_Preamble_ms", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims.data(), TOW_at_Preamble_ms.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("nav_symbol", MAT_C_INT32, MAT_T_INT32, 2, dims.data(), nav_symbol.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_INT32, MAT_T_INT32, 2, dims.data(), prn.data(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + + return 0; } @@ -110,7 +258,6 @@ void gps_l5_telemetry_decoder_gs::set_channel(int32_t channel) { try { - d_dump_filename = "telemetry_L5_"; d_dump_filename.append(std::to_string(d_channel)); d_dump_filename.append(".dat"); d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); @@ -263,12 +410,17 @@ int gps_l5_telemetry_decoder_gs::general_work(int noutput_items __attribute__((u { double tmp_double; uint64_t tmp_ulong_int; + int32_t tmp_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_synchro_data.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)); + tmp_int = (current_synchro_data.Prompt_Q > 0.0 ? 1 : -1); + d_dump_file.write(reinterpret_cast(&tmp_int), sizeof(int32_t)); + tmp_int = static_cast(current_synchro_data.PRN); + d_dump_file.write(reinterpret_cast(&tmp_int), sizeof(int32_t)); } catch (const std::ifstream::failure &e) { diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_gs.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_gs.h index 3f283259a..43e58818e 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_gs.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_gs.h @@ -24,6 +24,7 @@ #include "gnss_block_interface.h" #include "gnss_satellite.h" // for Gnss_Satellite #include "gps_cnav_navigation_message.h" // for Gps_CNAV_Navigation_Message +#include "tlm_conf.h" #include #include #include // for gr_vector_const_void_star @@ -48,7 +49,7 @@ using gps_l5_telemetry_decoder_gs_sptr = gnss_shared_ptrproperty(role + ".dump_filename", default_dumpname); + dump = configuration->property(role + ".dump", false); + dump_mat = configuration->property(role + ".dump_mat", dump); +} diff --git a/src/algorithms/telemetry_decoder/libs/tlm_conf.h b/src/algorithms/telemetry_decoder/libs/tlm_conf.h new file mode 100644 index 000000000..156919fbe --- /dev/null +++ b/src/algorithms/telemetry_decoder/libs/tlm_conf.h @@ -0,0 +1,48 @@ +/*! + * \file tlm_conf.h + * \brief Class that contains all the configuration parameters for generic + * telemetry decoder block. + * \author Carles Fernandez, 2020. cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2020 (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. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_TLM_CONF_H +#define GNSS_SDR_TLM_CONF_H + +#include "configuration_interface.h" +#include + +/** \addtogroup Telemetry_Decoder + * \{ */ +/** \addtogroup Telemetry_Decoder_libs + * \{ */ + + +class Tlm_Conf +{ +public: + Tlm_Conf(); + + void SetFromConfiguration(const ConfigurationInterface *configuration, const std::string &role); + + std::string dump_filename; + bool dump; + bool dump_mat; +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_TLM_CONF_H diff --git a/src/core/monitor/gnss_synchro_monitor.cc b/src/core/monitor/gnss_synchro_monitor.cc index 876dfd404..e7b6dc448 100644 --- a/src/core/monitor/gnss_synchro_monitor.cc +++ b/src/core/monitor/gnss_synchro_monitor.cc @@ -56,7 +56,7 @@ gnss_synchro_monitor::gnss_synchro_monitor(int n_channels, udp_sink_ptr = std::make_unique(udp_addresses, udp_port, enable_protobuf); } -void gnss_synchro_monitor::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required) +void gnss_synchro_monitor::forecast(int noutput_items __attribute__((unused)), gr_vector_int& ninput_items_required) { for (int32_t channel_index = 0; channel_index < d_nchannels; channel_index++) { diff --git a/src/core/system_parameters/galileo_cnav_message.cc b/src/core/system_parameters/galileo_cnav_message.cc index 903f2894f..d35ef790e 100644 --- a/src/core/system_parameters/galileo_cnav_message.cc +++ b/src/core/system_parameters/galileo_cnav_message.cc @@ -213,9 +213,9 @@ void Galileo_Cnav_Message::read_MT1_body(const std::string& message_string) std::string msg = message.substr(0, HAS_MSG_SATELLITE_MASK_LENGTH); d_HAS_data.satellite_mask[i] = read_has_message_body_uint64(msg); int ones_in_satellite_mask = 0; - for (size_t i = 0; i < msg.length(); i++) + for (char c : msg) { - if (msg[i] == '1') + if (c == '1') { ones_in_satellite_mask++; } @@ -226,9 +226,9 @@ void Galileo_Cnav_Message::read_MT1_body(const std::string& message_string) msg = message.substr(0, HAS_MSG_SIGNAL_MASK_LENGTH); d_HAS_data.signal_mask[i] = read_has_message_body_uint16(msg); int ones_in_signal_mask = 0; - for (size_t i = 0; i < msg.length(); i++) + for (char c : msg) { - if (msg[i] == '1') + if (c == '1') { ones_in_signal_mask++; } diff --git a/src/main/main.cc b/src/main/main.cc index 9394b0980..1a521c7b2 100644 --- a/src/main/main.cc +++ b/src/main/main.cc @@ -49,6 +49,7 @@ #include #endif +// clang-format off #if HAS_STD_FILESYSTEM #include namespace errorlib = std; @@ -67,6 +68,8 @@ namespace fs = std::filesystem; namespace fs = boost::filesystem; namespace errorlib = boost::system; #endif +// clang-format on + #if GFLAGS_OLD_NAMESPACE namespace gflags { diff --git a/src/tests/unit-tests/arithmetic/matio_test.cc b/src/tests/unit-tests/arithmetic/matio_test.cc index 04f4767da..82f657f45 100644 --- a/src/tests/unit-tests/arithmetic/matio_test.cc +++ b/src/tests/unit-tests/arithmetic/matio_test.cc @@ -24,6 +24,7 @@ #include #include +// clang-format off #if HAS_STD_FILESYSTEM #include namespace errorlib = std; @@ -42,6 +43,7 @@ namespace fs = std::filesystem; namespace fs = boost::filesystem; namespace errorlib = boost::system; #endif +// clang-format on TEST(MatioTest, WriteAndReadDoubles) { diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.cc index caf7c1378..75ba85d3e 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.cc @@ -29,6 +29,8 @@ bool Tlm_Dump_Reader::read_binary_obs() d_dump_file.read(reinterpret_cast(&TOW_at_current_symbol), sizeof(double)); d_dump_file.read(reinterpret_cast(&Tracking_sample_counter), sizeof(uint64_t)); d_dump_file.read(reinterpret_cast(&d_TOW_at_Preamble), sizeof(double)); + d_dump_file.read(reinterpret_cast(&nav_symbol), sizeof(int32_t)); + d_dump_file.read(reinterpret_cast(&prn), sizeof(int32_t)); } catch (const std::ifstream::failure &e) { @@ -53,8 +55,9 @@ bool Tlm_Dump_Reader::restart() int64_t Tlm_Dump_Reader::num_epochs() { std::ifstream::pos_type size; - int number_of_vars_in_epoch = 2; - int epoch_size_bytes = sizeof(double) * number_of_vars_in_epoch + sizeof(uint64_t); + int number_of_double_vars_in_epoch = 2; + int number_of_int_vars_in_epoch = 2; + int epoch_size_bytes = sizeof(double) * number_of_double_vars_in_epoch + sizeof(uint64_t) + sizeof(int32_t) * number_of_int_vars_in_epoch; std::ifstream tmpfile(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); if (tmpfile.is_open()) { diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.h b/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.h index dcadc5bbd..382b316f8 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.h +++ b/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.h @@ -38,6 +38,8 @@ public: double TOW_at_current_symbol; uint64_t Tracking_sample_counter; double d_TOW_at_Preamble; + int32_t nav_symbol; + int32_t prn; private: std::string d_dump_filename; diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc index cef5323a8..59c7b2e80 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc @@ -24,6 +24,7 @@ #include #include +// clang-format off #if HAS_STD_FILESYSTEM #include namespace errorlib = std; @@ -42,6 +43,7 @@ namespace fs = std::filesystem; namespace fs = boost::filesystem; namespace errorlib = boost::system; #endif +// clang-format on class NmeaPrinterTest : public ::testing::Test { diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc index 50a2a937c..88d8cc70c 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc @@ -23,6 +23,7 @@ #include #include +// clang-format off #if HAS_STD_FILESYSTEM #include namespace errorlib = std; @@ -41,6 +42,7 @@ namespace fs = std::filesystem; namespace fs = boost::filesystem; namespace errorlib = boost::system; #endif +// clang-format on class RinexPrinterTest : public ::testing::Test { diff --git a/src/utils/matlab/libs/gps_l1_ca_read_telemetry_dump.m b/src/utils/matlab/libs/gps_l1_ca_read_telemetry_dump.m index b20af9b22..6057d3a83 100644 --- a/src/utils/matlab/libs/gps_l1_ca_read_telemetry_dump.m +++ b/src/utils/matlab/libs/gps_l1_ca_read_telemetry_dump.m @@ -21,9 +21,11 @@ function [telemetry] = gps_l1_ca_read_telemetry_dump (filename, count) %% m = nargchk (1,2,nargin); -num_double_vars=4; +num_double_vars=3; double_size_bytes=8; -skip_bytes_each_read=double_size_bytes*num_double_vars; +num_int_vars=2; +int_size_bytes=4; +skip_bytes_each_read=double_size_bytes*num_double_vars+num_int_vars*int_size_bytes; bytes_shift=0; if (m) usage (m); @@ -32,34 +34,27 @@ end if (nargin < 3) count = Inf; end -%loops_counter = fread (f, count, 'uint32',4*12); f = fopen (filename, 'rb'); if (f < 0) else - telemetry.tow_current_symbol_ms = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes); - bytes_shift=bytes_shift+double_size_bytes; - fseek(f,bytes_shift,'bof'); % move to next interleaved - telemetry.tracking_sample_counter = fread (f, count, 'uint64',skip_bytes_each_read-double_size_bytes); - bytes_shift=bytes_shift+double_size_bytes; - fseek(f,bytes_shift,'bof'); % move to next interleaved - telemetry.tow = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes); - bytes_shift=bytes_shift+double_size_bytes; - fseek(f,bytes_shift,'bof'); % move to next interleaved - telemetry.required_symbols = fread (f, count, 'uint64',skip_bytes_each_read-double_size_bytes); - bytes_shift=bytes_shift+double_size_bytes; - fseek(f,bytes_shift,'bof'); % move to next interleaved - + [x, loops_counter] = fread (f,skip_bytes_each_read); + fseek(f,0,-1); + for i=1:min(count, loops_counter), + telemetry(i).tow_current_symbol_ms = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes); + bytes_shift=bytes_shift+double_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next interleaved + telemetry(i).tracking_sample_counter = fread (f, count, 'uint64',skip_bytes_each_read-double_size_bytes); + bytes_shift=bytes_shift+double_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next interleaved + telemetry(i).tow = fread (f, count, 'float64',skip_bytes_each_read-double_size_bytes); + bytes_shift=bytes_shift+double_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next interleaved + telemetry(i).nav_simbols = fread (f, count, 'int32',skip_bytes_each_read-int_size_bytes); + bytes_shift=bytes_shift+int_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next interleaved + telemetry(i).prn = fread (f, count, 'int32',skip_bytes_each_read-int_size_bytes); + bytes_shift=bytes_shift+int_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next interleaved + end fclose (f); - - %%%%%%%% output vars %%%%%%%% - % { - % double tmp_double; - % tmp_double = current_synchro_data.Preamble_delay_ms; - % d_dump_file.write((char*)&tmp_double, sizeof(double)); - % tmp_double = current_synchro_data.Prn_delay_ms; - % d_dump_file.write((char*)&tmp_double, sizeof(double)); - % tmp_double = current_synchro_data.Preamble_symbol_counter; - % d_dump_file.write((char*)&tmp_double, sizeof(double)); - % } end -