diff --git a/CMakeLists.txt b/CMakeLists.txt index 04377cc46..09e932f15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -326,6 +326,7 @@ set(GNSSSDR_ARMADILLO_LOCAL_VERSION "unstable") set(GNSSSDR_GTEST_LOCAL_VERSION "1.8.0") set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master") set(GNSSSDR_GPSTK_LOCAL_VERSION "2.10") +set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.11") @@ -1442,6 +1443,74 @@ endif(ENABLE_GPROF) +######################################################################## +# Matio (OPTIONAL) - https://github.com/tbeu/matio +######################################################################## +find_package(MATIO) +if(NOT MATIO_FOUND) + find_package(ZLIB) + if(ZLIB_FOUND) + get_filename_component(ZLIB_BASE_DIR ${ZLIB_INCLUDE_DIRS} DIRECTORY) + find_package(HDF5) + if(HDF5_FOUND) + list(GET HDF5_LIBRARIES 0 HDF5_FIRST_DIR) + get_filename_component(HDF5_BASE_DIR2 ${HDF5_FIRST_DIR} DIRECTORY) + get_filename_component(HDF5_BASE_DIR ${HDF5_BASE_DIR2} DIRECTORY) + if(OS_IS_MACOSX) + if(EXISTS /opt/local/include/hdf5.h) + set(HDF5_BASE_DIR /opt/local) + endif(EXISTS /opt/local/include/hdf5.h) + if(EXISTS /usr/local/include/hdf5.h) + set(HDF5_BASE_DIR /usr/local) + endif(EXISTS /usr/local/include/hdf5.h) + endif(OS_IS_MACOSX) + if(CMAKE_VERSION VERSION_LESS 3.2) + ExternalProject_Add( + matio-${GNSSSDR_MATIO_LOCAL_VERSION} + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/mati + GIT_REPOSITORY https://github.com/tbeu/matio + GIT_TAG v${GNSSSDR_MATIO_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION} + UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}/autogen.sh + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}/configure --with-hdf5=${HDF5_BASE_DIR} --with-zlib=${ZLIB_BASE_DIR} --with-default-file-ver=7.3 --enable-mat73=yes --prefix= + BUILD_COMMAND "${CMAKE_MAKE_PROGRAM}" + ) + else(CMAKE_VERSION VERSION_LESS 3.2) + ExternalProject_Add( + matio-${GNSSSDR_MATIO_LOCAL_VERSION} + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/matio + GIT_REPOSITORY https://github.com/tbeu/matio + GIT_TAG v${GNSSSDR_MATIO_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION} + UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}/autogen.sh + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}/configure --with-hdf5=${HDF5_BASE_DIR} --with-zlib=${ZLIB_BASE_DIR} --with-default-file-ver=7.3 --enable-mat73=yes --prefix= + BUILD_COMMAND "${CMAKE_MAKE_PROGRAM}" + BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/matio/lib/${CMAKE_FIND_LIBRARY_PREFIXES}matio${CMAKE_STATIC_LIBRARY_SUFFIX} + ) + endif(CMAKE_VERSION VERSION_LESS 3.2) + set(MATIO_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/matio/lib/${CMAKE_FIND_LIBRARY_PREFIXES}matio${CMAKE_STATIC_LIBRARY_SUFFIX} ${HDF5_LIBRARIES} ${ZLIB_LIBRARIES} ) + set(MATIO_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/matio/include ) + set(MATIO_LOCAL true) + else(HDF5_FOUND) + message(STATUS " The hdf5 library has not been found in your system.") + message(STATUS " Please try to install it by doing:") + if(OS_IS_MACOSX) + message(STATUS " $ sudo port install hdf5") + message(STATUS " or") + message(STATUS " $ brew install hdf5") + endif(OS_IS_MACOSX) + if(OS_IS_LINUX) + message(STATUS " $ sudo apt-get install libhdf5-dev") + endif(OS_IS_LINUX) + message(FATAL_ERROR "*** The hdf5 library is required to build gnss-sdr") + endif(HDF5_FOUND) + else(ZLIB_FOUND) + message(FATAL_ERROR "*** The zlib library is required to build gnss-sdr") + endif(ZLIB_FOUND) +endif(NOT MATIO_FOUND) + + + ######################################################################## # Set compiler flags ######################################################################## diff --git a/README.md b/README.md index e06525aef..1b513a25e 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -![](./docs/doxygen/images/gnss-sdr_logo.png) +[![](./docs/doxygen/images/gnss-sdr_logo.png)](http://gnss-sdr.org "GNSS-SDR website") + +[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) **Welcome to GNSS-SDR!** -Visit [gnss-sdr.org](http://gnss-sdr.org "GNSS-SDR's Homepage") for more information about this open source GNSS software defined receiver. - -If you have questions about GNSS-SDR, please [subscribe to the gnss-sdr-developers mailing list](http://lists.sourceforge.net/lists/listinfo/gnss-sdr-developers "Subscribe to the gnss-sdr-developers mailing list" ) and post your questions there. +Visit [http://gnss-sdr.org](http://gnss-sdr.org "GNSS-SDR website") for more information about this open source GNSS software defined receiver. @@ -47,7 +47,7 @@ $ sudo apt-get install build-essential cmake git libboost-dev libboost-date-time libboost-serialization-dev libboost-program-options-dev libboost-test-dev \ liblog4cpp5-dev libuhd-dev gnuradio-dev gr-osmosdr libblas-dev liblapack-dev \ libarmadillo-dev libgflags-dev libgoogle-glog-dev libgnutls-openssl-dev libgtest-dev \ - python-mako python-six + python-mako python-six libmatio-dev ~~~~~~ Alternatively, and starting from Ubuntu 16.04 LTS, you can install all the required dependencies by adding the line @@ -134,9 +134,9 @@ or manually as explained below, and then please follow instructions on how to [d $ sudo apt-get install libopenblas-dev liblapack-dev # For Debian/Ubuntu/LinuxMint $ sudo yum install lapack-devel blas-devel # For Fedora/CentOS/RHEL $ sudo zypper install lapack-devel blas-devel # For OpenSUSE -$ wget http://sourceforge.net/projects/arma/files/armadillo-7.800.2.tar.xz -$ tar xvfz armadillo-7.800.2.tar.xz -$ cd armadillo-7.800.2 +$ wget http://sourceforge.net/projects/arma/files/armadillo-8.200.2.tar.xz +$ tar xvfz armadillo-8.200.2.tar.xz +$ cd armadillo-8.200.2 $ cmake . $ make $ sudo make install @@ -149,9 +149,9 @@ The full stop separated from ```cmake``` by a space is important. [CMake](http:/ #### Install [Gflags](https://github.com/gflags/gflags "Gflags' Homepage"), a commandline flags processing module for C++: ~~~~~~ -$ wget https://github.com/gflags/gflags/archive/v2.2.0.tar.gz -$ tar xvfz v2.2.0.tar.gz -$ cd gflags-2.2.0 +$ wget https://github.com/gflags/gflags/archive/v2.2.1.tar.gz +$ tar xvfz v2.2.1.tar.gz +$ cd gflags-2.2.1 $ cmake -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=OFF -DBUILD_gflags_nothreads_LIB=OFF . $ make $ sudo make install @@ -163,9 +163,9 @@ $ sudo ldconfig #### Install [Glog](https://github.com/google/glog "Glog's Homepage"), a library that implements application-level logging: ~~~~~~ -$ wget https://github.com/google/glog/archive/v0.3.4.tar.gz -$ tar xvfz v0.3.4.tar.gz -$ cd glog-0.3.4 +$ wget https://github.com/google/glog/archive/v0.3.5.tar.gz +$ tar xvfz v0.3.5.tar.gz +$ cd glog-0.3.5 $ ./configure $ make $ sudo make install @@ -375,7 +375,7 @@ $ sudo make install ###### Build FMCOMMS2 based SDR Hardware support (OPTIONAL): -Install the [libiio](https://github.com/analogdevicesinc/libiio.git) (>=v0.11), [libad9361](https://github.com/analogdevicesinc/libad9361-iio.git) (>=v0.1-1) libraries and [gr-iio](https://github.com/analogdevicesinc/gr-iio.git) (>=v0.2) gnuradio block. For example in Ubuntu 16.04 follow these instructions (based on https://github.com/blurbdust/blurbdust.github.io): +Install the [libiio](https://github.com/analogdevicesinc/libiio.git) (>=v0.11), [libad9361](https://github.com/analogdevicesinc/libad9361-iio.git) (>=v0.1-1) libraries and [gr-iio](https://github.com/analogdevicesinc/gr-iio.git) (>v0.2) gnuradio block: ~~~~~~ $ sudo apt-get install libxml2-dev bison flex @@ -402,8 +402,10 @@ $ make && sudo make install && sudo ldconfig $ cd ../.. ~~~~~~ -Then configure the gnss-sdr to build the `Fmcomms2_Signal_Source` implementation: +Then configure GNSS-SDR to build the `Fmcomms2_Signal_Source` implementation: + ~~~~~~ +$ cd gnss-sdr/build $ cmake -DENABLE_FMCOMMS2=ON ../ $ make $ sudo make install @@ -416,7 +418,7 @@ $ make $ sudo make install ~~~~~~ -With `Fmcomms2_Signal_Source` you can use any SDR hardware based on fmcomms2, including the ADALM-PLUTO (PlutoSdr) by configuring correctly the .conf file. The `Plutosdr_Signal_Source` offers a simplier manner to use the ADALM-PLUTO because implements only a subset of fmcomms2's parameters valid for those devices. +With `Fmcomms2_Signal_Source` you can use any SDR hardware based on [FMCOMMS2](https://wiki.analog.com/resources/eval/user-guides/ad-fmcomms2-ebz), including the ADALM-PLUTO (PlutoSdr) by configuring correctly the .conf file. The `Plutosdr_Signal_Source` offers a simpler manner to use the ADALM-PLUTO because implements only a subset of FMCOMMS2's parameters valid for those devices. ###### Build OpenCL support (OPTIONAL): @@ -493,6 +495,7 @@ $ sudo port install gnutls $ sudo port install google-glog +gflags $ sudo port install py27-mako $ sudo port install py27-six +$ sudo port install matio ~~~~~~ You also might need to activate a Python installation. The list of installed versions can be retrieved with: @@ -509,15 +512,31 @@ $ sudo port select --set python python27 #### Homebrew -Instructions for installing GNU Radio using [homebrew](http://www.brew.sh) can be found [here](http://github.com/odrisci/homebrew-gnuradio) - please ensure to install all dependencies as required. +First, install [Homebrew](https://brew.sh/). Paste this in a terminal prompt: -Install Armadillo and dependencies: +~~~~~~ +$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" +~~~~~~ + +The script explains what it will do and then pauses before it does it. There are more installation options [here](https://docs.brew.sh/Installation.html). + +Install pip: + +~~~~~~ +$ sudo easy_install pip +~~~~~~ + +Install the required dependencies: ~~~~~~ $ brew tap homebrew/science $ brew install cmake hdf5 arpack superlu $ brew install armadillo $ brew install glog gflags gnutls +$ brew install gnuradio +$ brew install libmatio +$ pip install mako +$ pip install six ~~~~~~ #### Build GNSS-SDR diff --git a/cmake/Modules/FindGPSTK.cmake b/cmake/Modules/FindGPSTK.cmake index fffe17877..37ea1dbf0 100644 --- a/cmake/Modules/FindGPSTK.cmake +++ b/cmake/Modules/FindGPSTK.cmake @@ -7,10 +7,16 @@ # also defined, but not for general use are # GPSTK_LIBRARY, where to find the GPSTK library. -FIND_PATH(GPSTK_INCLUDE_DIR Rinex3ObsBase.hpp) +FIND_PATH(GPSTK_INCLUDE_DIR Rinex3ObsBase.hpp + HINTS /usr/include/gpstk + /usr/local/include/gpstk + /opt/local/include/gpstk ) SET(GPSTK_NAMES ${GPSTK_NAMES} gpstk libgpstk) -FIND_LIBRARY(GPSTK_LIBRARY NAMES ${GPSTK_NAMES} ) +FIND_LIBRARY(GPSTK_LIBRARY NAMES ${GPSTK_NAMES} + HINTS /usr/lib + /usr/local/lib + /opt/local/lib ) # handle the QUIETLY and REQUIRED arguments and set GPSTK_FOUND to TRUE if # all listed variables are TRUE diff --git a/cmake/Modules/FindMATIO.cmake b/cmake/Modules/FindMATIO.cmake new file mode 100644 index 000000000..e1cb458d8 --- /dev/null +++ b/cmake/Modules/FindMATIO.cmake @@ -0,0 +1,100 @@ +# FindMATIO +# +# Try to find MATIO library +# +# Once done this will define: +# +# MATIO_FOUND - True if MATIO found. +# MATIO_LIBRARIES - MATIO libraries. +# MATIO_INCLUDE_DIRS - where to find matio.h, etc.. +# MATIO_VERSION_STRING - version number as a string (e.g.: "1.3.4") +# +#============================================================================= +# Copyright 2015 Avtech Scientific +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the names of Kitware, Inc., the Insight Software Consortium, +# nor the names of their contributors may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= +# + +# Look for the header file. +find_path(MATIO_INCLUDE_DIR NAMES matio.h DOC "The MATIO include directory") + +# Look for the library. +find_library(MATIO_LIBRARY NAMES matio DOC "The MATIO library") + +if(MATIO_INCLUDE_DIR) + # --------------------------------------------------- + # Extract version information from MATIO + # --------------------------------------------------- + + # If the file is missing, set all values to 0 + set(MATIO_MAJOR_VERSION 0) + set(MATIO_MINOR_VERSION 0) + set(MATIO_RELEASE_LEVEL 0) + + # new versions of MATIO have `matio_pubconf.h` + if(EXISTS ${MATIO_INCLUDE_DIR}/matio_pubconf.h) + set(MATIO_CONFIG_FILE "matio_pubconf.h") + else() + set(MATIO_CONFIG_FILE "matioConfig.h") + endif() + + if(MATIO_CONFIG_FILE) + + # Read and parse MATIO config header file for version number + file(STRINGS "${MATIO_INCLUDE_DIR}/${MATIO_CONFIG_FILE}" _matio_HEADER_CONTENTS REGEX "#define MATIO_((MAJOR|MINOR)_VERSION)|(RELEASE_LEVEL) ") + + foreach(line ${_matio_HEADER_CONTENTS}) + if(line MATCHES "#define ([A-Z_]+) ([0-9]+)") + set("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}") + endif() + endforeach() + + unset(_matio_HEADER_CONTENTS) + endif() + + set(MATIO_VERSION_STRING "${MATIO_MAJOR_VERSION}.${MATIO_MINOR_VERSION}.${MATIO_RELEASE_LEVEL}") +endif () + +#================== + +mark_as_advanced(MATIO_INCLUDE_DIR MATIO_LIBRARY) + +# handle the QUIETLY and REQUIRED arguments and set MATIO_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(MATIO REQUIRED_VARS MATIO_LIBRARY MATIO_INCLUDE_DIR VERSION_VAR MATIO_VERSION_STRING) + +if(MATIO_FOUND) + set(MATIO_LIBRARIES ${MATIO_LIBRARY}) + set(MATIO_INCLUDE_DIRS ${MATIO_INCLUDE_DIR}) +else(MATIO_FOUND) + set(MATIO_LIBRARIES) + set(MATIO_INCLUDE_DIRS) +endif(MATIO_FOUND) \ No newline at end of file diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc index ec9501b12..afc50d17c 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc @@ -84,7 +84,7 @@ GalileoE5aNoncoherentIQAcquisitionCaf::GalileoE5aNoncoherentIQAcquisitionCaf( bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); //--- Find number of samples per spreading code (1ms)------------------------- - code_length_ = round(fs_in_ / Galileo_E5a_CODE_CHIP_RATE_HZ * Galileo_E5a_CODE_LENGTH_CHIPS); + code_length_ = round(static_cast(fs_in_) / Galileo_E5a_CODE_CHIP_RATE_HZ * static_cast(Galileo_E5a_CODE_LENGTH_CHIPS)); vector_length_ = code_length_ * sampled_ms_; diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h index ce23d5441..cfe7653d7 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h +++ b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h @@ -39,7 +39,6 @@ #define GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_H_ #include -#include #include "gnss_synchro.h" #include "acquisition_interface.h" #include "galileo_e5a_noncoherent_iq_acquisition_caf_cc.h" @@ -135,7 +134,6 @@ public: private: ConfigurationInterface* configuration_; galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr acquisition_cc_; - gr::blocks::stream_to_vector::sptr stream_to_vector_; size_t item_size_; std::string item_type_; unsigned int vector_length_; diff --git a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc index f20d39ff0..858a4117d 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc @@ -344,7 +344,7 @@ void galileo_e5a_noncoherentIQ_acquisition_caf_cc::set_state(int state) -int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items, +int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items __attribute__((unused))) { @@ -392,17 +392,17 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items { const gr_complex *in = reinterpret_cast(input_items[0]); //Get the input samples pointer unsigned int buff_increment; - if (ninput_items[0] + d_buffer_count <= d_fft_size) + if ((ninput_items[0] + d_buffer_count) <= d_fft_size) { buff_increment = ninput_items[0]; } else { - buff_increment = (d_fft_size - d_buffer_count); + buff_increment = d_fft_size - d_buffer_count; } memcpy(&d_inbuffer[d_buffer_count], in, sizeof(gr_complex) * buff_increment); // If buffer will be full in next iteration - if (d_buffer_count >= d_fft_size - d_gr_stream_buffer) + if (d_buffer_count >= (d_fft_size - d_gr_stream_buffer)) { d_state = 2; } @@ -419,7 +419,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items { memcpy(&d_inbuffer[d_buffer_count], in, sizeof(gr_complex)*(d_fft_size-d_buffer_count)); } - d_sample_counter += d_fft_size-d_buffer_count; // sample counter + d_sample_counter += (d_fft_size - d_buffer_count); // sample counter // initialize acquisition algorithm int doppler; @@ -810,6 +810,6 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items } } - return noutput_items; + return 0; } diff --git a/src/algorithms/data_type_adapter/adapters/CMakeLists.txt b/src/algorithms/data_type_adapter/adapters/CMakeLists.txt index a88ffd3e9..d18c83b04 100644 --- a/src/algorithms/data_type_adapter/adapters/CMakeLists.txt +++ b/src/algorithms/data_type_adapter/adapters/CMakeLists.txt @@ -31,6 +31,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/core/system_parameters ${CMAKE_SOURCE_DIR}/src/core/interfaces ${CMAKE_SOURCE_DIR}/src/algorithms/data_type_adapter/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/libs ${GLOG_INCLUDE_DIRS} ${GFlags_INCLUDE_DIRS} ${GNURADIO_RUNTIME_INCLUDE_DIRS} diff --git a/src/algorithms/data_type_adapter/adapters/ibyte_to_cbyte.cc b/src/algorithms/data_type_adapter/adapters/ibyte_to_cbyte.cc index 8dc47c8ad..e91455a23 100644 --- a/src/algorithms/data_type_adapter/adapters/ibyte_to_cbyte.cc +++ b/src/algorithms/data_type_adapter/adapters/ibyte_to_cbyte.cc @@ -51,6 +51,7 @@ IbyteToCbyte::IbyteToCbyte(ConfigurationInterface* configuration, std::string ro dump_ = config_->property(role_ + ".dump", false); dump_filename_ = config_->property(role_ + ".dump_filename", default_dump_filename); + inverted_spectrum = configuration->property(role + ".inverted_spectrum", false); size_t item_size = sizeof(lv_8sc_t); @@ -63,6 +64,10 @@ IbyteToCbyte::IbyteToCbyte(ConfigurationInterface* configuration, std::string ro DLOG(INFO) << "Dumping output into file " << dump_filename_; file_sink_ = gr::blocks::file_sink::make(item_size, dump_filename_.c_str()); } + if(inverted_spectrum) + { + conjugate_ic_ = make_conjugate_ic(); + } } @@ -74,7 +79,26 @@ void IbyteToCbyte::connect(gr::top_block_sptr top_block) { if (dump_) { - top_block->connect(ibyte_to_cbyte_, 0, file_sink_, 0); + if(inverted_spectrum) + { + top_block->connect(ibyte_to_cbyte_, 0, conjugate_ic_, 0); + top_block->connect(conjugate_ic_, 0, file_sink_, 0); + } + else + { + top_block->connect(ibyte_to_cbyte_, 0, file_sink_, 0); + } + } + else + { + if(inverted_spectrum) + { + top_block->connect(ibyte_to_cbyte_, 0, conjugate_ic_, 0); + } + else + { + DLOG(INFO) << "Nothing to connect internally"; + } } } @@ -83,21 +107,40 @@ void IbyteToCbyte::disconnect(gr::top_block_sptr top_block) { if (dump_) { - top_block->disconnect(ibyte_to_cbyte_, 0, file_sink_, 0); + if(inverted_spectrum) + { + top_block->disconnect(ibyte_to_cbyte_, 0, conjugate_ic_, 0); + top_block->disconnect(conjugate_ic_, 0, file_sink_, 0); + } + else + { + top_block->disconnect(ibyte_to_cbyte_, 0, file_sink_, 0); + } + } + else + { + if(inverted_spectrum) + { + top_block->disconnect(ibyte_to_cbyte_, 0, conjugate_ic_, 0); + } } } - gr::basic_block_sptr IbyteToCbyte::get_left_block() { return ibyte_to_cbyte_; } - gr::basic_block_sptr IbyteToCbyte::get_right_block() { - return ibyte_to_cbyte_; + if(inverted_spectrum) + { + return conjugate_ic_; + } + else + { + return ibyte_to_cbyte_; + } } - diff --git a/src/algorithms/data_type_adapter/adapters/ibyte_to_cbyte.h b/src/algorithms/data_type_adapter/adapters/ibyte_to_cbyte.h index 2aa0d1197..c40d85286 100644 --- a/src/algorithms/data_type_adapter/adapters/ibyte_to_cbyte.h +++ b/src/algorithms/data_type_adapter/adapters/ibyte_to_cbyte.h @@ -34,6 +34,7 @@ #include #include +#include "conjugate_ic.h" #include "gnss_block_interface.h" #include "interleaved_byte_to_complex_byte.h" @@ -85,6 +86,8 @@ private: unsigned int in_streams_; unsigned int out_streams_; gr::blocks::file_sink::sptr file_sink_; + conjugate_ic_sptr conjugate_ic_; + bool inverted_spectrum; }; #endif diff --git a/src/algorithms/data_type_adapter/adapters/ibyte_to_complex.cc b/src/algorithms/data_type_adapter/adapters/ibyte_to_complex.cc index 6119ebd9f..83b6fd6c5 100644 --- a/src/algorithms/data_type_adapter/adapters/ibyte_to_complex.cc +++ b/src/algorithms/data_type_adapter/adapters/ibyte_to_complex.cc @@ -49,6 +49,7 @@ IbyteToComplex::IbyteToComplex(ConfigurationInterface* configuration, std::strin dump_ = config_->property(role_ + ".dump", false); dump_filename_ = config_->property(role_ + ".dump_filename", default_dump_filename); + inverted_spectrum = configuration->property(role + ".inverted_spectrum", false); size_t item_size = sizeof(gr_complex); @@ -56,6 +57,10 @@ IbyteToComplex::IbyteToComplex(ConfigurationInterface* configuration, std::strin DLOG(INFO) << "data_type_adapter_(" << gr_interleaved_char_to_complex_->unique_id() << ")"; + if (inverted_spectrum) + { + conjugate_cc_ = make_conjugate_cc(); + } if (dump_) { DLOG(INFO) << "Dumping output into file " << dump_filename_; @@ -72,7 +77,26 @@ void IbyteToComplex::connect(gr::top_block_sptr top_block) { if (dump_) { - top_block->connect(gr_interleaved_char_to_complex_, 0, file_sink_, 0); + if(inverted_spectrum) + { + top_block->connect(gr_interleaved_char_to_complex_, 0, conjugate_cc_, 0); + top_block->connect(conjugate_cc_, 0, file_sink_, 0); + } + else + { + top_block->connect(gr_interleaved_char_to_complex_, 0, file_sink_, 0); + } + } + else + { + if(inverted_spectrum) + { + top_block->connect(gr_interleaved_char_to_complex_, 0, conjugate_cc_, 0); + } + else + { + DLOG(INFO) << "Nothing to connect internally"; + } } } @@ -81,22 +105,40 @@ void IbyteToComplex::disconnect(gr::top_block_sptr top_block) { if (dump_) { - top_block->disconnect(gr_interleaved_char_to_complex_, 0, file_sink_, 0); + if(inverted_spectrum) + { + top_block->disconnect(gr_interleaved_char_to_complex_, 0, conjugate_cc_, 0); + top_block->disconnect(conjugate_cc_, 0, file_sink_, 0); + } + else + { + top_block->disconnect(gr_interleaved_char_to_complex_, 0, file_sink_, 0); + } + } + else + { + if(inverted_spectrum) + { + top_block->disconnect(gr_interleaved_char_to_complex_, 0, conjugate_cc_, 0); + } } } - gr::basic_block_sptr IbyteToComplex::get_left_block() { return gr_interleaved_char_to_complex_; } - gr::basic_block_sptr IbyteToComplex::get_right_block() { - return gr_interleaved_char_to_complex_; + if(inverted_spectrum) + { + return conjugate_cc_; + } + else + { + return gr_interleaved_char_to_complex_; + } } - - diff --git a/src/algorithms/data_type_adapter/adapters/ibyte_to_complex.h b/src/algorithms/data_type_adapter/adapters/ibyte_to_complex.h index 50b38f37e..3c379d7ba 100644 --- a/src/algorithms/data_type_adapter/adapters/ibyte_to_complex.h +++ b/src/algorithms/data_type_adapter/adapters/ibyte_to_complex.h @@ -34,8 +34,9 @@ #include #include #include -#include "gnss_synchro.h" +#include "conjugate_cc.h" #include "gnss_block_interface.h" +#include "gnss_synchro.h" class ConfigurationInterface; @@ -85,6 +86,8 @@ private: unsigned int in_streams_; unsigned int out_streams_; gr::blocks::file_sink::sptr file_sink_; + conjugate_cc_sptr conjugate_cc_; + bool inverted_spectrum; }; #endif diff --git a/src/algorithms/data_type_adapter/adapters/ibyte_to_cshort.cc b/src/algorithms/data_type_adapter/adapters/ibyte_to_cshort.cc index 206f824cc..59ac82042 100644 --- a/src/algorithms/data_type_adapter/adapters/ibyte_to_cshort.cc +++ b/src/algorithms/data_type_adapter/adapters/ibyte_to_cshort.cc @@ -51,6 +51,7 @@ IbyteToCshort::IbyteToCshort(ConfigurationInterface* configuration, std::string dump_ = config_->property(role_ + ".dump", false); dump_filename_ = config_->property(role_ + ".dump_filename", default_dump_filename); + inverted_spectrum = configuration->property(role + ".inverted_spectrum", false); size_t item_size = sizeof(lv_16sc_t); @@ -63,6 +64,10 @@ IbyteToCshort::IbyteToCshort(ConfigurationInterface* configuration, std::string DLOG(INFO) << "Dumping output into file " << dump_filename_; file_sink_ = gr::blocks::file_sink::make(item_size, dump_filename_.c_str()); } + if(inverted_spectrum) + { + conjugate_sc_ = make_conjugate_sc(); + } } @@ -74,7 +79,22 @@ void IbyteToCshort::connect(gr::top_block_sptr top_block) { if (dump_) { - top_block->connect(interleaved_byte_to_complex_short_, 0, file_sink_, 0); + if(inverted_spectrum) + { + top_block->connect(interleaved_byte_to_complex_short_, 0, conjugate_sc_, 0); + top_block->connect(conjugate_sc_, 0, file_sink_, 0); + } + else + { + top_block->connect(interleaved_byte_to_complex_short_, 0, file_sink_, 0); + } + } + else + { + if(inverted_spectrum) + { + top_block->connect(interleaved_byte_to_complex_short_, 0, conjugate_sc_, 0); + } } } @@ -83,22 +103,40 @@ void IbyteToCshort::disconnect(gr::top_block_sptr top_block) { if (dump_) { - top_block->disconnect(interleaved_byte_to_complex_short_, 0, file_sink_, 0); + if(inverted_spectrum) + { + top_block->disconnect(interleaved_byte_to_complex_short_, 0, conjugate_sc_, 0); + top_block->disconnect(conjugate_sc_, 0, file_sink_, 0); + } + else + { + top_block->disconnect(interleaved_byte_to_complex_short_, 0, file_sink_, 0); + } + } + else + { + if(inverted_spectrum) + { + top_block->disconnect(interleaved_byte_to_complex_short_, 0, conjugate_sc_, 0); + } } } - gr::basic_block_sptr IbyteToCshort::get_left_block() { return interleaved_byte_to_complex_short_; } - gr::basic_block_sptr IbyteToCshort::get_right_block() { - return interleaved_byte_to_complex_short_; + if(inverted_spectrum) + { + return conjugate_sc_; + } + else + { + return interleaved_byte_to_complex_short_; + } } - - diff --git a/src/algorithms/data_type_adapter/adapters/ibyte_to_cshort.h b/src/algorithms/data_type_adapter/adapters/ibyte_to_cshort.h index 71829d6a3..2de7089ac 100644 --- a/src/algorithms/data_type_adapter/adapters/ibyte_to_cshort.h +++ b/src/algorithms/data_type_adapter/adapters/ibyte_to_cshort.h @@ -34,6 +34,7 @@ #include #include #include "gnss_block_interface.h" +#include "conjugate_sc.h" #include "interleaved_byte_to_complex_short.h" @@ -85,6 +86,8 @@ private: unsigned int in_streams_; unsigned int out_streams_; gr::blocks::file_sink::sptr file_sink_; + conjugate_sc_sptr conjugate_sc_; + bool inverted_spectrum; }; #endif diff --git a/src/algorithms/data_type_adapter/adapters/ishort_to_complex.cc b/src/algorithms/data_type_adapter/adapters/ishort_to_complex.cc index e87dc1f59..cb9d3c6df 100644 --- a/src/algorithms/data_type_adapter/adapters/ishort_to_complex.cc +++ b/src/algorithms/data_type_adapter/adapters/ishort_to_complex.cc @@ -49,6 +49,7 @@ IshortToComplex::IshortToComplex(ConfigurationInterface* configuration, std::str dump_ = config_->property(role_ + ".dump", false); dump_filename_ = config_->property(role_ + ".dump_filename", default_dump_filename); + inverted_spectrum = configuration->property(role + ".inverted_spectrum", false); size_t item_size = sizeof(gr_complex); @@ -56,6 +57,10 @@ IshortToComplex::IshortToComplex(ConfigurationInterface* configuration, std::str DLOG(INFO) << "data_type_adapter_(" << gr_interleaved_short_to_complex_->unique_id() << ")"; + if (inverted_spectrum) + { + conjugate_cc_ = make_conjugate_cc(); + } if (dump_) { DLOG(INFO) << "Dumping output into file " << dump_filename_; @@ -72,11 +77,26 @@ void IshortToComplex::connect(gr::top_block_sptr top_block) { if (dump_) { - top_block->connect(gr_interleaved_short_to_complex_, 0, file_sink_, 0); + if(inverted_spectrum) + { + top_block->connect(gr_interleaved_short_to_complex_, 0, conjugate_cc_, 0); + top_block->connect(conjugate_cc_, 0, file_sink_, 0); + } + else + { + top_block->connect(gr_interleaved_short_to_complex_, 0, file_sink_, 0); + } } else { - DLOG(INFO) << "Nothing to connect internally"; + if(inverted_spectrum) + { + top_block->connect(gr_interleaved_short_to_complex_, 0, conjugate_cc_, 0); + } + else + { + DLOG(INFO) << "Nothing to connect internally"; + } } } @@ -85,22 +105,40 @@ void IshortToComplex::disconnect(gr::top_block_sptr top_block) { if (dump_) { - top_block->disconnect(gr_interleaved_short_to_complex_, 0, file_sink_, 0); + if(inverted_spectrum) + { + top_block->disconnect(gr_interleaved_short_to_complex_, 0, conjugate_cc_, 0); + top_block->disconnect(conjugate_cc_, 0, file_sink_, 0); + } + else + { + top_block->disconnect(gr_interleaved_short_to_complex_, 0, file_sink_, 0); + } + } + else + { + if(inverted_spectrum) + { + top_block->disconnect(gr_interleaved_short_to_complex_, 0, conjugate_cc_, 0); + } } } - gr::basic_block_sptr IshortToComplex::get_left_block() { return gr_interleaved_short_to_complex_; } - gr::basic_block_sptr IshortToComplex::get_right_block() { - return gr_interleaved_short_to_complex_; + if(inverted_spectrum) + { + return conjugate_cc_; + } + else + { + return gr_interleaved_short_to_complex_; + } } - - diff --git a/src/algorithms/data_type_adapter/adapters/ishort_to_complex.h b/src/algorithms/data_type_adapter/adapters/ishort_to_complex.h index 79a2d7162..57cf7283e 100644 --- a/src/algorithms/data_type_adapter/adapters/ishort_to_complex.h +++ b/src/algorithms/data_type_adapter/adapters/ishort_to_complex.h @@ -34,6 +34,7 @@ #include #include #include +#include "conjugate_cc.h" #include "gnss_block_interface.h" @@ -84,6 +85,8 @@ private: unsigned int in_streams_; unsigned int out_streams_; gr::blocks::file_sink::sptr file_sink_; + conjugate_cc_sptr conjugate_cc_; + bool inverted_spectrum; }; #endif diff --git a/src/algorithms/data_type_adapter/adapters/ishort_to_cshort.cc b/src/algorithms/data_type_adapter/adapters/ishort_to_cshort.cc index 503341d08..96a87abe2 100644 --- a/src/algorithms/data_type_adapter/adapters/ishort_to_cshort.cc +++ b/src/algorithms/data_type_adapter/adapters/ishort_to_cshort.cc @@ -51,6 +51,7 @@ IshortToCshort::IshortToCshort(ConfigurationInterface* configuration, std::strin dump_ = config_->property(role_ + ".dump", false); dump_filename_ = config_->property(role_ + ".dump_filename", default_dump_filename); + inverted_spectrum = configuration->property(role + ".inverted_spectrum", false); size_t item_size = sizeof(lv_16sc_t); @@ -63,6 +64,10 @@ IshortToCshort::IshortToCshort(ConfigurationInterface* configuration, std::strin DLOG(INFO) << "Dumping output into file " << dump_filename_; file_sink_ = gr::blocks::file_sink::make(item_size, dump_filename_.c_str()); } + if(inverted_spectrum) + { + conjugate_sc_ = make_conjugate_sc(); + } } @@ -74,11 +79,26 @@ void IshortToCshort::connect(gr::top_block_sptr top_block) { if (dump_) { - top_block->connect(interleaved_short_to_complex_short_, 0, file_sink_, 0); + if(inverted_spectrum) + { + top_block->connect(interleaved_short_to_complex_short_, 0, conjugate_sc_, 0); + top_block->connect(conjugate_sc_, 0, file_sink_, 0); + } + else + { + top_block->connect(interleaved_short_to_complex_short_, 0, file_sink_, 0); + } } else { - DLOG(INFO) << "Nothing to connect internally"; + if(inverted_spectrum) + { + top_block->connect(interleaved_short_to_complex_short_, 0, conjugate_sc_, 0); + } + else + { + DLOG(INFO) << "Nothing to connect internally"; + } } } @@ -87,22 +107,40 @@ void IshortToCshort::disconnect(gr::top_block_sptr top_block) { if (dump_) { - top_block->disconnect(interleaved_short_to_complex_short_, 0, file_sink_, 0); + if(inverted_spectrum) + { + top_block->disconnect(interleaved_short_to_complex_short_, 0, conjugate_sc_, 0); + top_block->disconnect(conjugate_sc_, 0, file_sink_, 0); + } + else + { + top_block->disconnect(interleaved_short_to_complex_short_, 0, file_sink_, 0); + } + } + else + { + if(inverted_spectrum) + { + top_block->disconnect(interleaved_short_to_complex_short_, 0, conjugate_sc_, 0); + } } } - gr::basic_block_sptr IshortToCshort::get_left_block() { return interleaved_short_to_complex_short_; } - gr::basic_block_sptr IshortToCshort::get_right_block() { - return interleaved_short_to_complex_short_; + if(inverted_spectrum) + { + return conjugate_sc_; + } + else + { + return interleaved_short_to_complex_short_; + } } - - diff --git a/src/algorithms/data_type_adapter/adapters/ishort_to_cshort.h b/src/algorithms/data_type_adapter/adapters/ishort_to_cshort.h index cb8080e40..685373a6a 100644 --- a/src/algorithms/data_type_adapter/adapters/ishort_to_cshort.h +++ b/src/algorithms/data_type_adapter/adapters/ishort_to_cshort.h @@ -33,6 +33,7 @@ #include #include +#include "conjugate_sc.h" #include "gnss_block_interface.h" #include "interleaved_short_to_complex_short.h" @@ -85,6 +86,8 @@ private: unsigned int in_streams_; unsigned int out_streams_; gr::blocks::file_sink::sptr file_sink_; + conjugate_sc_sptr conjugate_sc_; + bool inverted_spectrum; }; #endif diff --git a/src/algorithms/libs/CMakeLists.txt b/src/algorithms/libs/CMakeLists.txt index 818c9d947..b5e1b4470 100644 --- a/src/algorithms/libs/CMakeLists.txt +++ b/src/algorithms/libs/CMakeLists.txt @@ -33,6 +33,9 @@ set(GNSS_SPLIBS_SOURCES cshort_to_float_x2.cc short_x2_to_cshort.cc complex_float_to_complex_byte.cc + conjugate_cc.cc + conjugate_sc.cc + conjugate_ic.cc ) diff --git a/src/algorithms/libs/conjugate_cc.cc b/src/algorithms/libs/conjugate_cc.cc new file mode 100644 index 000000000..60063473a --- /dev/null +++ b/src/algorithms/libs/conjugate_cc.cc @@ -0,0 +1,29 @@ +#include "conjugate_cc.h" +#include +#include + + +conjugate_cc_sptr make_conjugate_cc() +{ + return conjugate_cc_sptr(new conjugate_cc()); +} + + +conjugate_cc::conjugate_cc() : gr::sync_block("conjugate_cc", + gr::io_signature::make (1, 1, sizeof(gr_complex)), + gr::io_signature::make (1, 1, sizeof(gr_complex))) +{ + const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex); + set_alignment(std::max(1, alignment_multiple)); +} + + +int conjugate_cc::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const gr_complex *in = reinterpret_cast(input_items[0]); + gr_complex *out = reinterpret_cast(output_items[0]); + volk_32fc_conjugate_32fc(out, in, noutput_items); + return noutput_items; +} diff --git a/src/algorithms/libs/conjugate_cc.h b/src/algorithms/libs/conjugate_cc.h new file mode 100644 index 000000000..556f79c6d --- /dev/null +++ b/src/algorithms/libs/conjugate_cc.h @@ -0,0 +1,59 @@ +/*! + * \file conjugate_cc.h + * \brief Conjugate + * \author Carles Fernandez Prades, cfernandez(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_CONJUGATE_CC_H_ +#define GNSS_SDR_CONJUGATE_CC_H_ + +#include +#include + +class conjugate_cc; + +typedef boost::shared_ptr conjugate_cc_sptr; + +conjugate_cc_sptr make_conjugate_cc(); + +/*! + * \brief This class adapts a std::complex stream + * into two 32-bits (float) streams + */ +class conjugate_cc : public gr::sync_block +{ +private: + friend conjugate_cc_sptr make_conjugate_cc(); +public: + conjugate_cc(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif diff --git a/src/algorithms/libs/conjugate_ic.cc b/src/algorithms/libs/conjugate_ic.cc new file mode 100644 index 000000000..b1f85e39f --- /dev/null +++ b/src/algorithms/libs/conjugate_ic.cc @@ -0,0 +1,29 @@ +#include "conjugate_ic.h" +#include +#include + + +conjugate_ic_sptr make_conjugate_ic() +{ + return conjugate_ic_sptr(new conjugate_ic()); +} + + +conjugate_ic::conjugate_ic() : gr::sync_block("conjugate_ic", + gr::io_signature::make (1, 1, sizeof(lv_8sc_t)), + gr::io_signature::make (1, 1, sizeof(lv_8sc_t))) +{ + const int alignment_multiple = volk_gnsssdr_get_alignment() / sizeof(lv_8sc_t); + set_alignment(std::max(1, alignment_multiple)); +} + + +int conjugate_ic::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const lv_8sc_t *in = reinterpret_cast(input_items[0]); + lv_8sc_t *out = reinterpret_cast(output_items[0]); + volk_gnsssdr_8ic_conjugate_8ic(out, in, noutput_items); + return noutput_items; +} diff --git a/src/algorithms/libs/conjugate_ic.h b/src/algorithms/libs/conjugate_ic.h new file mode 100644 index 000000000..38eb21a35 --- /dev/null +++ b/src/algorithms/libs/conjugate_ic.h @@ -0,0 +1,59 @@ +/*! + * \file conjugate_ic.h + * \brief Adapts a std::complex stream into two float streams + * \author Carles Fernandez Prades, cfernandez(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_CONJUGATE_IC_H_ +#define GNSS_SDR_CONJUGATE_IC_H_ + +#include +#include + +class conjugate_ic; + +typedef boost::shared_ptr conjugate_ic_sptr; + +conjugate_ic_sptr make_conjugate_ic(); + +/*! + * \brief This class adapts a std::complex stream + * into two 32-bits (float) streams + */ +class conjugate_ic : public gr::sync_block +{ +private: + friend conjugate_ic_sptr make_conjugate_ic(); +public: + conjugate_ic(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif diff --git a/src/algorithms/libs/conjugate_sc.cc b/src/algorithms/libs/conjugate_sc.cc new file mode 100644 index 000000000..ac22d7723 --- /dev/null +++ b/src/algorithms/libs/conjugate_sc.cc @@ -0,0 +1,29 @@ +#include "conjugate_sc.h" +#include +#include + + +conjugate_sc_sptr make_conjugate_sc() +{ + return conjugate_sc_sptr(new conjugate_sc()); +} + + +conjugate_sc::conjugate_sc() : gr::sync_block("conjugate_sc", + gr::io_signature::make (1, 1, sizeof(lv_16sc_t)), + gr::io_signature::make (1, 1, sizeof(lv_16sc_t))) +{ + const int alignment_multiple = volk_gnsssdr_get_alignment() / sizeof(lv_16sc_t); + set_alignment(std::max(1, alignment_multiple)); +} + + +int conjugate_sc::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const lv_16sc_t *in = reinterpret_cast(input_items[0]); + lv_16sc_t *out = reinterpret_cast(output_items[0]); + volk_gnsssdr_16ic_conjugate_16ic(out, in, noutput_items); + return noutput_items; +} diff --git a/src/algorithms/libs/conjugate_sc.h b/src/algorithms/libs/conjugate_sc.h new file mode 100644 index 000000000..b26a66c79 --- /dev/null +++ b/src/algorithms/libs/conjugate_sc.h @@ -0,0 +1,59 @@ +/*! + * \file conjugate_sc.h + * \brief Adapts a std::complex stream into two float streams + * \author Carles Fernandez Prades, cfernandez(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_CONJUGATE_SC_H_ +#define GNSS_SDR_CONJUGATE_SC_H_ + +#include +#include + +class conjugate_sc; + +typedef boost::shared_ptr conjugate_sc_sptr; + +conjugate_sc_sptr make_conjugate_sc(); + +/*! + * \brief This class adapts a std::complex stream + * into two 32-bits (float) streams + */ +class conjugate_sc : public gr::sync_block +{ +private: + friend conjugate_sc_sptr make_conjugate_sc(); +public: + conjugate_sc(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif diff --git a/src/algorithms/libs/pass_through.cc b/src/algorithms/libs/pass_through.cc index 94394866e..87f2b1be6 100644 --- a/src/algorithms/libs/pass_through.cc +++ b/src/algorithms/libs/pass_through.cc @@ -57,7 +57,7 @@ Pass_Through::Pass_Through(ConfigurationInterface* configuration, std::string ro } item_type_ = configuration->property(role + ".item_type", input_type); - vector_size_ = configuration->property(role + ".vector_size", 1); + inverted_spectrum = configuration->property(role + ".inverted_spectrum", false); if(item_type_.compare("float") == 0) { @@ -66,6 +66,10 @@ Pass_Through::Pass_Through(ConfigurationInterface* configuration, std::string ro else if(item_type_.compare("gr_complex") == 0) { item_size_ = sizeof(gr_complex); + if(inverted_spectrum) + { + conjugate_cc_ = make_conjugate_cc(); + } } else if(item_type_.compare("short") == 0) { @@ -78,6 +82,10 @@ Pass_Through::Pass_Through(ConfigurationInterface* configuration, std::string ro else if(item_type_.compare("cshort") == 0) { item_size_ = sizeof(lv_16sc_t); + if(inverted_spectrum) + { + conjugate_sc_ = make_conjugate_sc(); + } } else if(item_type_.compare("byte") == 0) { @@ -90,12 +98,17 @@ Pass_Through::Pass_Through(ConfigurationInterface* configuration, std::string ro else if(item_type_.compare("cbyte") == 0) { item_size_ = sizeof(lv_8sc_t); + if(inverted_spectrum) + { + conjugate_ic_ = make_conjugate_ic(); + } } else { LOG(WARNING) << item_type_ << " unrecognized item type. Using float"; item_size_ = sizeof(float); } + kludge_copy_ = gr::blocks::copy::make(item_size_); DLOG(INFO) << "kludge_copy(" << kludge_copy_->unique_id() << ")"; } @@ -125,6 +138,27 @@ void Pass_Through::disconnect(gr::top_block_sptr top_block) gr::basic_block_sptr Pass_Through::get_left_block() { + if(inverted_spectrum) + { + if(item_type_.compare("gr_complex") == 0) + { + return conjugate_cc_; + } + else if(item_type_.compare("cshort") == 0) + { + return conjugate_sc_; + } + else if(item_type_.compare("cbyte") == 0) + { + return conjugate_ic_; + } + else + { + LOG(WARNING) << "Setting inverted_spectrum to true with item_type " + << item_type_ << " is not defined and has no effect."; + } + } + return kludge_copy_; } @@ -132,5 +166,26 @@ gr::basic_block_sptr Pass_Through::get_left_block() gr::basic_block_sptr Pass_Through::get_right_block() { + if(inverted_spectrum) + { + if(item_type_.compare("gr_complex") == 0) + { + return conjugate_cc_; + } + else if(item_type_.compare("cshort") == 0) + { + return conjugate_sc_; + } + else if(item_type_.compare("cbyte") == 0) + { + return conjugate_ic_; + } + else + { + DLOG(WARNING) << "Setting inverted_spectrum to true with item_type " + << item_type_ << " is not defined and has no effect."; + } + } + return kludge_copy_; } diff --git a/src/algorithms/libs/pass_through.h b/src/algorithms/libs/pass_through.h index 02cc1647f..39d4c5468 100644 --- a/src/algorithms/libs/pass_through.h +++ b/src/algorithms/libs/pass_through.h @@ -37,6 +37,10 @@ #include #include #include "gnss_block_interface.h" +#include "conjugate_cc.h" +#include "conjugate_sc.h" +#include "conjugate_ic.h" + class ConfigurationInterface; @@ -69,11 +73,6 @@ public: return item_type_; } - inline size_t vector_size() const - { - return vector_size_; - } - inline size_t item_size() override { return item_size_; @@ -86,13 +85,16 @@ public: private: std::string item_type_; - size_t vector_size_; std::string role_; unsigned int in_streams_; unsigned int out_streams_; //gr_kludge_copy_sptr kludge_copy_; gr::blocks::copy::sptr kludge_copy_; size_t item_size_; + conjugate_cc_sptr conjugate_cc_; + conjugate_sc_sptr conjugate_sc_; + conjugate_ic_sptr conjugate_ic_; + bool inverted_spectrum; }; #endif /*GNSS_SDR_PASS_THROUGH_H_*/ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/volk_gnsssdr_arch_defs.py b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/volk_gnsssdr_arch_defs.py index d1e656d70..cfce6d5b2 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/volk_gnsssdr_arch_defs.py +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/volk_gnsssdr_arch_defs.py @@ -82,7 +82,7 @@ for arch_xml in archs_xml: flags = dict() for flag_xml in arch_xml.getElementsByTagName("flag"): name = flag_xml.attributes["compiler"].value - if not flags.has_key(name): flags[name] = list() + if name not in flags: flags[name] = list() flags[name].append(flag_xml.firstChild.data) #force kwargs keys to be of type str, not unicode for py25 kwargs = dict((str(k), v) for k, v in six.iteritems(kwargs)) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_conjugate_16ic.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_conjugate_16ic.h new file mode 100644 index 000000000..5aae17266 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_conjugate_16ic.h @@ -0,0 +1,234 @@ +/*! + * \file volk_gnsssdr_16ic_conjugate_16ic.h + * \brief VOLK_GNSSSDR kernel: returns the conjugate of a 16 bits complex vector. + * \authors
    + *
  • Carles Fernandez Prades 2017 cfernandez at cttc dot cat + *
+ * + * VOLK_GNSSSDR kernel that calculates the conjugate of a + * 16 bits complex vector (16 bits the real part and 16 bits the imaginary part) + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +/*! + * \page volk_gnsssdr_16ic_conjugate_16ic + * + * \b Overview + * + * Takes the conjugate of a complex signed 16-bit integer vector. + * + * Dispatcher Prototype + * \code + * void volk_gnsssdr_16ic_conjugate_16ic(lv_16sc_t* cVector, const lv_16sc_t* aVector, unsigned int num_points); + * \endcode + * + * \b Inputs + * \li aVector: Vector of complex items to be conjugated + * \li num_points: The number of complex data points. + * + * \b Outputs + * \li cVector: The vector where the result will be stored + * + */ + +#ifndef INCLUDED_volk_gnsssdr_16ic_conjugate_16ic_H +#define INCLUDED_volk_gnsssdr_16ic_conjugate_16ic_H + +#include + + +#ifdef LV_HAVE_GENERIC + +static inline void volk_gnsssdr_16ic_conjugate_16ic_generic(lv_16sc_t* cVector, const lv_16sc_t* aVector, unsigned int num_points) +{ + lv_16sc_t* cPtr = cVector; + const lv_16sc_t* aPtr = aVector; + unsigned int number; + + for(number = 0; number < num_points; number++) + { + *cPtr++ = lv_conj(*aPtr++); + } +} + +#endif /* LV_HAVE_GENERIC */ + + +#ifdef LV_HAVE_SSSE3 +#include + +static inline void volk_gnsssdr_16ic_conjugate_16ic_u_ssse3(lv_16sc_t* cVector, const lv_16sc_t* aVector, unsigned int num_points) +{ + const unsigned int sse_iters = num_points / 4; + unsigned int i; + lv_16sc_t* c = cVector; + const lv_16sc_t* a = aVector; + __m128i tmp; + + __m128i conjugator = _mm_setr_epi16(1, -1, 1, -1, 1, -1, 1, -1); + + for (i = 0; i < sse_iters; ++i) + { + tmp = _mm_lddqu_si128((__m128i*)a); + tmp = _mm_sign_epi16(tmp, conjugator); + _mm_storeu_si128((__m128i*)c, tmp); + a += 4; + c += 4; + } + + for (i = sse_iters * 4; i < num_points; ++i) + { + *c++ = lv_conj(*a++); + } +} + +#endif /* LV_HAVE_SSSE3 */ + + +#ifdef LV_HAVE_SSSE3 +#include + +static inline void volk_gnsssdr_16ic_conjugate_16ic_a_ssse3(lv_16sc_t* cVector, const lv_16sc_t* aVector, unsigned int num_points) +{ + const unsigned int sse_iters = num_points / 4; + unsigned int i; + lv_16sc_t* c = cVector; + const lv_16sc_t* a = aVector; + __m128i tmp; + __m128i conjugator = _mm_setr_epi16(1, -1, 1, -1, 1, -1, 1, -1); + + for (i = 0; i < sse_iters; ++i) + { + tmp = _mm_load_si128((__m128i*)a); + tmp = _mm_sign_epi16(tmp, conjugator); + _mm_store_si128((__m128i*)c, tmp); + a += 4; + c += 4; + } + + for (i = sse_iters * 4; i < num_points; ++i) + { + *c++ = lv_conj(*a++); + } +} + +#endif /* LV_HAVE_SSSE3 */ + + +#ifdef LV_HAVE_AVX2 +#include + +static inline void volk_gnsssdr_16ic_conjugate_16ic_a_avx2(lv_16sc_t* cVector, const lv_16sc_t* aVector, unsigned int num_points) +{ + const unsigned int avx2_iters = num_points / 8; + unsigned int i; + lv_16sc_t* c = cVector; + const lv_16sc_t* a = aVector; + + __m256i tmp; + __m256i conjugator = _mm256_setr_epi16(1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1); + + for (i = 0; i < avx2_iters; ++i) + { + tmp = _mm256_load_si256((__m256i*)a); + tmp = _mm256_sign_epi16(tmp, conjugator); + _mm256_store_si256((__m256i*)c, tmp); + + a += 8; + c += 8; + } + + for (i = avx2_iters * 8; i < num_points; ++i) + { + *c++ = lv_conj(*a++); + } +} + +#endif /* LV_HAVE_AVX2 */ + + +#ifdef LV_HAVE_AVX2 +#include + +static inline void volk_gnsssdr_16ic_conjugate_16ic_u_avx2(lv_16sc_t* cVector, const lv_16sc_t* aVector, unsigned int num_points) +{ + const unsigned int avx2_iters = num_points / 8; + unsigned int i; + lv_16sc_t* c = cVector; + const lv_16sc_t* a = aVector; + + __m256i tmp; + __m256i conjugator = _mm256_setr_epi16(1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1); + + for (i = 0; i < avx2_iters; ++i) + { + tmp = _mm256_loadu_si256((__m256i*)a); + tmp = _mm256_sign_epi16(tmp, conjugator); + _mm256_storeu_si256((__m256i*)c, tmp); + + a += 8; + c += 8; + } + + for (i = avx2_iters * 8; i < num_points; ++i) + { + *c++ = lv_conj(*a++); + } +} +#endif /* LV_HAVE_AVX2 */ + +// +// +//#ifdef LV_HAVE_NEON +//#include +// +//static inline void volk_gnsssdr_16ic_conjugate_16ic_neon(lv_16sc_t* cVector, const lv_16sc_t* aVector, unsigned int num_points) +//{ +// const unsigned int sse_iters = num_points / 4; +// unsigned int i; +// lv_16sc_t* c = cVector; +// const lv_16sc_t* a = aVector; +// int16x4x2_t a_val; +// +// for (i = 0; i < sse_iters; ++i) +// { +// a_val = vld2_s16((const int16_t*)a); +// __VOLK_GNSSSDR_PREFETCH(a + 4); +// a_val.val[1] = vneg_s16(a_val.val[1]); +// vst2_s16((int16_t*)c, a_val); +// a += 4; +// c += 4; +// } +// +// for (i = sse_iters * 4; i < num_points; ++i) +// { +// *c++ = lv_conj(*a++); +// } +//} +//#endif /* LV_HAVE_NEON */ + +#endif /* INCLUDED_volk_gnsssdr_16ic_conjugate_16ic_H */ + 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 544a83990..0a8674893 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 @@ -176,9 +176,10 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_u_avx(lv_32fc_ const float* aPtr = (float*)in_common; const float* bPtr[ num_a_vectors]; - for( vec_ind = 0; vec_ind < num_a_vectors; ++vec_ind ){ - bPtr[vec_ind] = in_a[vec_ind]; - } + for( vec_ind = 0; vec_ind < num_a_vectors; ++vec_ind ) + { + bPtr[vec_ind] = in_a[vec_ind]; + } lv_32fc_t _phase = (*phase); lv_32fc_t wo; @@ -193,20 +194,22 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_u_avx(lv_32fc_ __m256 dotProdVal2[num_a_vectors]; __m256 dotProdVal3[num_a_vectors]; - for( vec_ind = 0; vec_ind < num_a_vectors; vec_ind++ ){ - dotProdVal0[vec_ind] = _mm256_setzero_ps(); - dotProdVal1[vec_ind] = _mm256_setzero_ps(); - dotProdVal2[vec_ind] = _mm256_setzero_ps(); - dotProdVal3[vec_ind] = _mm256_setzero_ps(); - } + for( vec_ind = 0; vec_ind < num_a_vectors; vec_ind++ ) + { + dotProdVal0[vec_ind] = _mm256_setzero_ps(); + dotProdVal1[vec_ind] = _mm256_setzero_ps(); + dotProdVal2[vec_ind] = _mm256_setzero_ps(); + dotProdVal3[vec_ind] = _mm256_setzero_ps(); + } // Set up the complex rotator __m256 z0, z1, z2, z3; - __attribute__((aligned(32))) lv_32fc_t phase_vec[16]; - for( vec_ind = 0; vec_ind < 16; ++vec_ind ){ - phase_vec[vec_ind] = _phase; - _phase *= phase_inc; - } + __VOLK_ATTR_ALIGNED(32) lv_32fc_t phase_vec[16]; + for( vec_ind = 0; vec_ind < 16; ++vec_ind ) + { + phase_vec[vec_ind] = _phase; + _phase *= phase_inc; + } z0 = _mm256_load_ps( (float *)phase_vec ); z1 = _mm256_load_ps( (float *)(phase_vec + 4) ); @@ -215,104 +218,267 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_u_avx(lv_32fc_ lv_32fc_t dz = phase_inc; dz *= dz; dz *= dz; dz *= dz; dz *= dz; // dz = phase_inc^16; - for( vec_ind = 0; vec_ind < 4; ++vec_ind ){ - phase_vec[vec_ind] = dz; - } + for( vec_ind = 0; vec_ind < 4; ++vec_ind ) + { + phase_vec[vec_ind] = dz; + } __m256 dz_reg = _mm256_load_ps( (float *)phase_vec ); dz_reg = _mm256_complexnormalise_ps( dz_reg ); - for(;number < sixteenthPoints; number++){ - - a0Val = _mm256_loadu_ps(aPtr); - a1Val = _mm256_loadu_ps(aPtr+8); - a2Val = _mm256_loadu_ps(aPtr+16); - a3Val = _mm256_loadu_ps(aPtr+24); - - a0Val = _mm256_complexmul_ps( a0Val, z0 ); - a1Val = _mm256_complexmul_ps( a1Val, z1 ); - a2Val = _mm256_complexmul_ps( a2Val, z2 ); - a3Val = _mm256_complexmul_ps( a3Val, z3 ); - - z0 = _mm256_complexmul_ps( z0, dz_reg ); - z1 = _mm256_complexmul_ps( z1, dz_reg ); - z2 = _mm256_complexmul_ps( z2, dz_reg ); - z3 = _mm256_complexmul_ps( z3, dz_reg ); - - - for( vec_ind = 0; vec_ind < num_a_vectors; ++vec_ind ){ - x0Val[vec_ind] = _mm256_loadu_ps(bPtr[vec_ind]); // t0|t1|t2|t3|t4|t5|t6|t7 - x1Val[vec_ind] = _mm256_loadu_ps(bPtr[vec_ind]+8); - x0loVal[vec_ind] = _mm256_unpacklo_ps(x0Val[vec_ind], x0Val[vec_ind]); // t0|t0|t1|t1|t4|t4|t5|t5 - x0hiVal[vec_ind] = _mm256_unpackhi_ps(x0Val[vec_ind], x0Val[vec_ind]); // t2|t2|t3|t3|t6|t6|t7|t7 - x1loVal[vec_ind] = _mm256_unpacklo_ps(x1Val[vec_ind], x1Val[vec_ind]); - x1hiVal[vec_ind] = _mm256_unpackhi_ps(x1Val[vec_ind], x1Val[vec_ind]); - - // TODO: it may be possible to rearrange swizzling to better pipeline data - b0Val[vec_ind] = _mm256_permute2f128_ps(x0loVal[vec_ind], x0hiVal[vec_ind], 0x20); // t0|t0|t1|t1|t2|t2|t3|t3 - b1Val[vec_ind] = _mm256_permute2f128_ps(x0loVal[vec_ind], x0hiVal[vec_ind], 0x31); // t4|t4|t5|t5|t6|t6|t7|t7 - b2Val[vec_ind] = _mm256_permute2f128_ps(x1loVal[vec_ind], x1hiVal[vec_ind], 0x20); - b3Val[vec_ind] = _mm256_permute2f128_ps(x1loVal[vec_ind], x1hiVal[vec_ind], 0x31); - - c0Val[vec_ind] = _mm256_mul_ps(a0Val, b0Val[vec_ind]); - c1Val[vec_ind] = _mm256_mul_ps(a1Val, b1Val[vec_ind]); - c2Val[vec_ind] = _mm256_mul_ps(a2Val, b2Val[vec_ind]); - c3Val[vec_ind] = _mm256_mul_ps(a3Val, b3Val[vec_ind]); - - dotProdVal0[vec_ind] = _mm256_add_ps(c0Val[vec_ind], dotProdVal0[vec_ind]); - dotProdVal1[vec_ind] = _mm256_add_ps(c1Val[vec_ind], dotProdVal1[vec_ind]); - dotProdVal2[vec_ind] = _mm256_add_ps(c2Val[vec_ind], dotProdVal2[vec_ind]); - dotProdVal3[vec_ind] = _mm256_add_ps(c3Val[vec_ind], dotProdVal3[vec_ind]); - - bPtr[vec_ind] += 16; - } - - // Force the rotators back onto the unit circle - if ((number % 64) == 0) + for(;number < sixteenthPoints; number++) { - z0 = _mm256_complexnormalise_ps( z0 ); - z1 = _mm256_complexnormalise_ps( z1 ); - z2 = _mm256_complexnormalise_ps( z2 ); - z3 = _mm256_complexnormalise_ps( z3 ); - } + a0Val = _mm256_loadu_ps(aPtr); + a1Val = _mm256_loadu_ps(aPtr+8); + a2Val = _mm256_loadu_ps(aPtr+16); + a3Val = _mm256_loadu_ps(aPtr+24); - aPtr += 32; - } + a0Val = _mm256_complexmul_ps( a0Val, z0 ); + a1Val = _mm256_complexmul_ps( a1Val, z1 ); + a2Val = _mm256_complexmul_ps( a2Val, z2 ); + a3Val = _mm256_complexmul_ps( a3Val, z3 ); + + z0 = _mm256_complexmul_ps( z0, dz_reg ); + z1 = _mm256_complexmul_ps( z1, dz_reg ); + z2 = _mm256_complexmul_ps( z2, dz_reg ); + z3 = _mm256_complexmul_ps( z3, dz_reg ); + + for( vec_ind = 0; vec_ind < num_a_vectors; ++vec_ind ) + { + x0Val[vec_ind] = _mm256_loadu_ps(bPtr[vec_ind]); // t0|t1|t2|t3|t4|t5|t6|t7 + x1Val[vec_ind] = _mm256_loadu_ps(bPtr[vec_ind]+8); + x0loVal[vec_ind] = _mm256_unpacklo_ps(x0Val[vec_ind], x0Val[vec_ind]); // t0|t0|t1|t1|t4|t4|t5|t5 + x0hiVal[vec_ind] = _mm256_unpackhi_ps(x0Val[vec_ind], x0Val[vec_ind]); // t2|t2|t3|t3|t6|t6|t7|t7 + x1loVal[vec_ind] = _mm256_unpacklo_ps(x1Val[vec_ind], x1Val[vec_ind]); + x1hiVal[vec_ind] = _mm256_unpackhi_ps(x1Val[vec_ind], x1Val[vec_ind]); + + // TODO: it may be possible to rearrange swizzling to better pipeline data + b0Val[vec_ind] = _mm256_permute2f128_ps(x0loVal[vec_ind], x0hiVal[vec_ind], 0x20); // t0|t0|t1|t1|t2|t2|t3|t3 + b1Val[vec_ind] = _mm256_permute2f128_ps(x0loVal[vec_ind], x0hiVal[vec_ind], 0x31); // t4|t4|t5|t5|t6|t6|t7|t7 + b2Val[vec_ind] = _mm256_permute2f128_ps(x1loVal[vec_ind], x1hiVal[vec_ind], 0x20); + b3Val[vec_ind] = _mm256_permute2f128_ps(x1loVal[vec_ind], x1hiVal[vec_ind], 0x31); + + c0Val[vec_ind] = _mm256_mul_ps(a0Val, b0Val[vec_ind]); + c1Val[vec_ind] = _mm256_mul_ps(a1Val, b1Val[vec_ind]); + c2Val[vec_ind] = _mm256_mul_ps(a2Val, b2Val[vec_ind]); + c3Val[vec_ind] = _mm256_mul_ps(a3Val, b3Val[vec_ind]); + + dotProdVal0[vec_ind] = _mm256_add_ps(c0Val[vec_ind], dotProdVal0[vec_ind]); + dotProdVal1[vec_ind] = _mm256_add_ps(c1Val[vec_ind], dotProdVal1[vec_ind]); + dotProdVal2[vec_ind] = _mm256_add_ps(c2Val[vec_ind], dotProdVal2[vec_ind]); + dotProdVal3[vec_ind] = _mm256_add_ps(c3Val[vec_ind], dotProdVal3[vec_ind]); + + bPtr[vec_ind] += 16; + } + + // Force the rotators back onto the unit circle + if ((number % 64) == 0) + { + z0 = _mm256_complexnormalise_ps( z0 ); + z1 = _mm256_complexnormalise_ps( z1 ); + z2 = _mm256_complexnormalise_ps( z2 ); + z3 = _mm256_complexnormalise_ps( z3 ); + } + + aPtr += 32; + } __VOLK_ATTR_ALIGNED(32) lv_32fc_t dotProductVector[4]; - for( vec_ind = 0; vec_ind < num_a_vectors; ++vec_ind ){ - dotProdVal0[vec_ind] = _mm256_add_ps(dotProdVal0[vec_ind], dotProdVal1[vec_ind]); - dotProdVal0[vec_ind] = _mm256_add_ps(dotProdVal0[vec_ind], dotProdVal2[vec_ind]); - dotProdVal0[vec_ind] = _mm256_add_ps(dotProdVal0[vec_ind], dotProdVal3[vec_ind]); + for( vec_ind = 0; vec_ind < num_a_vectors; ++vec_ind ) + { + dotProdVal0[vec_ind] = _mm256_add_ps(dotProdVal0[vec_ind], dotProdVal1[vec_ind]); + dotProdVal0[vec_ind] = _mm256_add_ps(dotProdVal0[vec_ind], dotProdVal2[vec_ind]); + dotProdVal0[vec_ind] = _mm256_add_ps(dotProdVal0[vec_ind], dotProdVal3[vec_ind]); - _mm256_store_ps((float *)dotProductVector,dotProdVal0[vec_ind]); // Store the results back into the dot product vector + _mm256_store_ps((float *)dotProductVector, dotProdVal0[vec_ind]); // Store the results back into the dot product vector - result[ vec_ind ] = lv_cmake( 0, 0 ); - for( i = 0; i < 4; ++i ){ - result[vec_ind] += dotProductVector[i]; + result[ vec_ind ] = lv_cmake( 0, 0 ); + for( i = 0; i < 4; ++i ) + { + result[vec_ind] += dotProductVector[i]; + } } - } z0 = _mm256_complexnormalise_ps( z0 ); _mm256_store_ps((float*)phase_vec, z0); - _phase = phase_vec[0]; + _phase = phase_vec[0]; _mm256_zeroupper(); - number = sixteenthPoints*16; - for(;number < num_points; number++){ - wo = (*aPtr++)*_phase; - _phase *= phase_inc; + for(;number < num_points; number++) + { + wo = (*aPtr++)*_phase; + _phase *= phase_inc; - for( vec_ind = 0; vec_ind < num_a_vectors; ++vec_ind ){ - result[vec_ind] += wo * in_a[vec_ind][number]; + for( vec_ind = 0; vec_ind < num_a_vectors; ++vec_ind ) + { + result[vec_ind] += wo * in_a[vec_ind][number]; + } } - } *phase = _phase; - } +#endif /* LV_HAVE_AVX */ + + +#ifdef LV_HAVE_AVX +#include +#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) +{ + unsigned int number = 0; + unsigned int vec_ind = 0; + unsigned int i = 0; + const unsigned int sixteenthPoints = num_points / 16; + + const float* aPtr = (float*)in_common; + const float* bPtr[ num_a_vectors]; + for( vec_ind = 0; vec_ind < num_a_vectors; ++vec_ind ) + { + bPtr[vec_ind] = in_a[vec_ind]; + } + + lv_32fc_t _phase = (*phase); + lv_32fc_t wo; + + __m256 a0Val, a1Val, a2Val, a3Val; + __m256 b0Val[num_a_vectors], b1Val[num_a_vectors], b2Val[num_a_vectors], b3Val[num_a_vectors]; + __m256 x0Val[num_a_vectors], x1Val[num_a_vectors], x0loVal[num_a_vectors], x0hiVal[num_a_vectors], x1loVal[num_a_vectors], x1hiVal[num_a_vectors]; + __m256 c0Val[num_a_vectors], c1Val[num_a_vectors], c2Val[num_a_vectors], c3Val[num_a_vectors]; + + __m256 dotProdVal0[num_a_vectors]; + __m256 dotProdVal1[num_a_vectors]; + __m256 dotProdVal2[num_a_vectors]; + __m256 dotProdVal3[num_a_vectors]; + + for( vec_ind = 0; vec_ind < num_a_vectors; vec_ind++ ) + { + dotProdVal0[vec_ind] = _mm256_setzero_ps(); + dotProdVal1[vec_ind] = _mm256_setzero_ps(); + dotProdVal2[vec_ind] = _mm256_setzero_ps(); + dotProdVal3[vec_ind] = _mm256_setzero_ps(); + } + + // Set up the complex rotator + __m256 z0, z1, z2, z3; + __VOLK_ATTR_ALIGNED(32) lv_32fc_t phase_vec[16]; + for( vec_ind = 0; vec_ind < 16; ++vec_ind ) + { + phase_vec[vec_ind] = _phase; + _phase *= phase_inc; + } + + z0 = _mm256_load_ps( (float *)phase_vec ); + z1 = _mm256_load_ps( (float *)(phase_vec + 4) ); + z2 = _mm256_load_ps( (float *)(phase_vec + 8) ); + z3 = _mm256_load_ps( (float *)(phase_vec + 12) ); + + lv_32fc_t dz = phase_inc; dz *= dz; dz *= dz; dz *= dz; dz *= dz; // dz = phase_inc^16; + + for( vec_ind = 0; vec_ind < 4; ++vec_ind ) + { + phase_vec[vec_ind] = dz; + } + + __m256 dz_reg = _mm256_load_ps( (float *)phase_vec ); + dz_reg = _mm256_complexnormalise_ps( dz_reg ); + + for(;number < sixteenthPoints; number++) + { + + a0Val = _mm256_load_ps(aPtr); + a1Val = _mm256_load_ps(aPtr+8); + a2Val = _mm256_load_ps(aPtr+16); + a3Val = _mm256_load_ps(aPtr+24); + + a0Val = _mm256_complexmul_ps( a0Val, z0 ); + a1Val = _mm256_complexmul_ps( a1Val, z1 ); + a2Val = _mm256_complexmul_ps( a2Val, z2 ); + a3Val = _mm256_complexmul_ps( a3Val, z3 ); + + z0 = _mm256_complexmul_ps( z0, dz_reg ); + z1 = _mm256_complexmul_ps( z1, dz_reg ); + z2 = _mm256_complexmul_ps( z2, dz_reg ); + z3 = _mm256_complexmul_ps( z3, dz_reg ); + + for( vec_ind = 0; vec_ind < num_a_vectors; ++vec_ind ) + { + x0Val[vec_ind] = _mm256_loadu_ps(bPtr[vec_ind]); // t0|t1|t2|t3|t4|t5|t6|t7 + x1Val[vec_ind] = _mm256_loadu_ps(bPtr[vec_ind]+8); + x0loVal[vec_ind] = _mm256_unpacklo_ps(x0Val[vec_ind], x0Val[vec_ind]); // t0|t0|t1|t1|t4|t4|t5|t5 + x0hiVal[vec_ind] = _mm256_unpackhi_ps(x0Val[vec_ind], x0Val[vec_ind]); // t2|t2|t3|t3|t6|t6|t7|t7 + x1loVal[vec_ind] = _mm256_unpacklo_ps(x1Val[vec_ind], x1Val[vec_ind]); + x1hiVal[vec_ind] = _mm256_unpackhi_ps(x1Val[vec_ind], x1Val[vec_ind]); + + // TODO: it may be possible to rearrange swizzling to better pipeline data + b0Val[vec_ind] = _mm256_permute2f128_ps(x0loVal[vec_ind], x0hiVal[vec_ind], 0x20); // t0|t0|t1|t1|t2|t2|t3|t3 + b1Val[vec_ind] = _mm256_permute2f128_ps(x0loVal[vec_ind], x0hiVal[vec_ind], 0x31); // t4|t4|t5|t5|t6|t6|t7|t7 + b2Val[vec_ind] = _mm256_permute2f128_ps(x1loVal[vec_ind], x1hiVal[vec_ind], 0x20); + b3Val[vec_ind] = _mm256_permute2f128_ps(x1loVal[vec_ind], x1hiVal[vec_ind], 0x31); + + c0Val[vec_ind] = _mm256_mul_ps(a0Val, b0Val[vec_ind]); + c1Val[vec_ind] = _mm256_mul_ps(a1Val, b1Val[vec_ind]); + c2Val[vec_ind] = _mm256_mul_ps(a2Val, b2Val[vec_ind]); + c3Val[vec_ind] = _mm256_mul_ps(a3Val, b3Val[vec_ind]); + + dotProdVal0[vec_ind] = _mm256_add_ps(c0Val[vec_ind], dotProdVal0[vec_ind]); + dotProdVal1[vec_ind] = _mm256_add_ps(c1Val[vec_ind], dotProdVal1[vec_ind]); + dotProdVal2[vec_ind] = _mm256_add_ps(c2Val[vec_ind], dotProdVal2[vec_ind]); + dotProdVal3[vec_ind] = _mm256_add_ps(c3Val[vec_ind], dotProdVal3[vec_ind]); + + bPtr[vec_ind] += 16; + } + + // Force the rotators back onto the unit circle + if ((number % 64) == 0) + { + z0 = _mm256_complexnormalise_ps( z0 ); + z1 = _mm256_complexnormalise_ps( z1 ); + z2 = _mm256_complexnormalise_ps( z2 ); + z3 = _mm256_complexnormalise_ps( z3 ); + } + + aPtr += 32; + } + __VOLK_ATTR_ALIGNED(32) lv_32fc_t dotProductVector[4]; + + for( vec_ind = 0; vec_ind < num_a_vectors; ++vec_ind ) + { + dotProdVal0[vec_ind] = _mm256_add_ps(dotProdVal0[vec_ind], dotProdVal1[vec_ind]); + dotProdVal0[vec_ind] = _mm256_add_ps(dotProdVal0[vec_ind], dotProdVal2[vec_ind]); + dotProdVal0[vec_ind] = _mm256_add_ps(dotProdVal0[vec_ind], dotProdVal3[vec_ind]); + + _mm256_store_ps((float *)dotProductVector, dotProdVal0[vec_ind]); // Store the results back into the dot product vector + + result[ vec_ind ] = lv_cmake( 0, 0 ); + for( i = 0; i < 4; ++i ) + { + result[vec_ind] += dotProductVector[i]; + } + } + + z0 = _mm256_complexnormalise_ps( z0 ); + _mm256_store_ps((float*)phase_vec, z0); + _phase = phase_vec[0]; + _mm256_zeroupper(); + + number = sixteenthPoints*16; + for(;number < num_points; number++) + { + wo = (*aPtr++)*_phase; + _phase *= phase_inc; + + for( vec_ind = 0; vec_ind < num_a_vectors; ++vec_ind ) + { + result[vec_ind] += wo * in_a[vec_ind][number]; + } + } + + *phase = _phase; +} + + #endif /* LV_HAVE_AVX */ #endif /* INCLUDED_volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_H */ 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 a0284f65d..ca684e30b 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 @@ -128,5 +128,35 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc_u_avx(lv_3 #endif // AVX + +#ifdef LV_HAVE_AVX +static inline void volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc_a_avx(lv_32fc_t* result, const lv_32fc_t* local_code, const float* in, unsigned int num_points) +{ + // phases must be normalized. Phase rotator expects a complex exponential input! + float rem_carrier_phase_in_rad = 0.25; + float phase_step_rad = 0.1; + lv_32fc_t phase[1]; + phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); + lv_32fc_t phase_inc[1]; + phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); + unsigned int n; + int num_a_vectors = 3; + float ** in_a = (float **)volk_gnsssdr_malloc(sizeof(float *) * num_a_vectors, volk_gnsssdr_get_alignment()); + for(n = 0; n < num_a_vectors; n++) + { + 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); + } + 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); + + for(n = 0; n < num_a_vectors; n++) + { + volk_gnsssdr_free(in_a[n]); + } + volk_gnsssdr_free(in_a); +} + +#endif // AVX + #endif // INCLUDED_volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc_H diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/kernel_tests.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/kernel_tests.h index da0b2f0f8..e7fa4e62b 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/kernel_tests.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/kernel_tests.h @@ -84,6 +84,7 @@ std::vector init_test_list(volk_gnsssdr_test_params_t (VOLK_INIT_TEST(volk_gnsssdr_16ic_x2_dot_prod_16ic, test_params)) (VOLK_INIT_TEST(volk_gnsssdr_16ic_x2_multiply_16ic, test_params_more_iters)) (VOLK_INIT_TEST(volk_gnsssdr_16ic_convert_32fc, test_params_more_iters)) + (VOLK_INIT_TEST(volk_gnsssdr_16ic_conjugate_16ic, test_params_more_iters)) (VOLK_INIT_PUPP(volk_gnsssdr_s32f_sincospuppet_32fc, volk_gnsssdr_s32f_sincos_32fc, test_params_inacc2)) (VOLK_INIT_PUPP(volk_gnsssdr_16ic_rotatorpuppet_16ic, volk_gnsssdr_16ic_s32fc_x2_rotator_16ic, test_params_int1)) (VOLK_INIT_PUPP(volk_gnsssdr_16ic_resamplerfastpuppet_16ic, volk_gnsssdr_16ic_resampler_fast_16ic, test_params)) diff --git a/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt b/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt index d195adf03..74bb5280f 100644 --- a/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt @@ -31,6 +31,7 @@ include_directories( ${ARMADILLO_INCLUDE_DIRS} ${GLOG_INCLUDE_DIRS} ${GFlags_INCLUDE_DIRS} + ${MATIO_INCLUDE_DIRS} ) file(GLOB OBS_GR_BLOCKS_HEADERS "*.h") @@ -38,4 +39,4 @@ list(SORT OBS_GR_BLOCKS_HEADERS) add_library(obs_gr_blocks ${OBS_GR_BLOCKS_SOURCES} ${OBS_GR_BLOCKS_HEADERS}) source_group(Headers FILES ${OBS_GR_BLOCKS_HEADERS}) add_dependencies(obs_gr_blocks glog-${glog_RELEASE} armadillo-${armadillo_RELEASE}) -target_link_libraries(obs_gr_blocks ${GNURADIO_RUNTIME_LIBRARIES} ${ARMADILLO_LIBRARIES}) +target_link_libraries(obs_gr_blocks ${GNURADIO_RUNTIME_LIBRARIES} ${ARMADILLO_LIBRARIES} ${MATIO_LIBRARIES}) diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc index 9bc7f7e00..fb30b58ac 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc @@ -38,6 +38,7 @@ #include #include #include +#include #include "Galileo_E1.h" #include "GPS_L1_CA.h" @@ -104,6 +105,197 @@ hybrid_observables_cc::~hybrid_observables_cc() LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); } } + if(d_dump == true) + { + std::cout << "Writing observables .mat files ..."; + hybrid_observables_cc::save_matfile(); + std::cout << " done." << std::endl; + } +} + + +int hybrid_observables_cc::save_matfile() +{ + // READ DUMP FILE + std::ifstream::pos_type size; + int number_of_double_vars = 7; + int epoch_size_bytes = sizeof(double) * number_of_double_vars * d_nchannels; + std::ifstream dump_file; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + } + catch(const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return 1; + } + // count number of epochs and rewind + long int num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + double ** RX_time = new double * [d_nchannels]; + double ** TOW_at_current_symbol_s = new double * [d_nchannels]; + double ** Carrier_Doppler_hz = new double * [d_nchannels]; + double ** Carrier_phase_cycles = new double * [d_nchannels]; + double ** Pseudorange_m = new double * [d_nchannels]; + double ** PRN = new double * [d_nchannels]; + double ** Flag_valid_pseudorange = new double * [d_nchannels]; + + for(unsigned int i = 0; i < d_nchannels; i++) + { + RX_time[i] = new double [num_epoch]; + TOW_at_current_symbol_s[i] = new double[num_epoch]; + Carrier_Doppler_hz[i] = new double[num_epoch]; + Carrier_phase_cycles[i] = new double[num_epoch]; + Pseudorange_m[i] = new double[num_epoch]; + PRN[i] = new double[num_epoch]; + Flag_valid_pseudorange[i] = new double[num_epoch]; + } + + try + { + if (dump_file.is_open()) + { + for(long int i = 0; i < num_epoch; i++) + { + for(unsigned int chan = 0; chan < d_nchannels; chan++) + { + dump_file.read(reinterpret_cast(&RX_time[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&TOW_at_current_symbol_s[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&Carrier_Doppler_hz[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&Carrier_phase_cycles[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&Pseudorange_m[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&PRN[chan][i]), sizeof(double)); + dump_file.read(reinterpret_cast(&Flag_valid_pseudorange[chan][i]), sizeof(double)); + } + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + for(unsigned int i = 0; i < d_nchannels; i++) + { + delete[] RX_time[i]; + delete[] TOW_at_current_symbol_s[i]; + delete[] Carrier_Doppler_hz[i]; + delete[] Carrier_phase_cycles[i]; + delete[] Pseudorange_m[i]; + delete[] PRN[i]; + delete[] Flag_valid_pseudorange[i]; + } + delete[] RX_time; + delete[] TOW_at_current_symbol_s; + delete[] Carrier_Doppler_hz; + delete[] Carrier_phase_cycles; + delete[] Pseudorange_m; + delete[] PRN; + delete[] Flag_valid_pseudorange; + + return 1; + } + + double * RX_time_aux = new double [d_nchannels * num_epoch]; + double * TOW_at_current_symbol_s_aux = new double [d_nchannels * num_epoch]; + double * Carrier_Doppler_hz_aux = new double [d_nchannels * num_epoch]; + double * Carrier_phase_cycles_aux = new double [d_nchannels * num_epoch]; + double * Pseudorange_m_aux = new double [d_nchannels * num_epoch]; + double * PRN_aux = new double [d_nchannels * num_epoch]; + double * Flag_valid_pseudorange_aux = new double[d_nchannels * num_epoch]; + unsigned int k = 0; + for(long int j = 0; j < num_epoch; j++ ) + { + for(unsigned int i = 0; i < d_nchannels; i++ ) + { + RX_time_aux[k] = RX_time[i][j]; + TOW_at_current_symbol_s_aux[k] = TOW_at_current_symbol_s[i][j]; + Carrier_Doppler_hz_aux[k] = Carrier_Doppler_hz[i][j]; + Carrier_phase_cycles_aux[k] = Carrier_phase_cycles[i][j]; + Pseudorange_m_aux[k] = Pseudorange_m[i][j]; + PRN_aux[k] = PRN[i][j]; + Flag_valid_pseudorange_aux[k] = Flag_valid_pseudorange[i][j]; + k++; + } + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = d_dump_filename; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if(reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {static_cast(d_nchannels), static_cast(num_epoch)}; + matvar = Mat_VarCreate("RX_time", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, RX_time_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("TOW_at_current_symbol_s", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, TOW_at_current_symbol_s_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Carrier_Doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Carrier_Doppler_hz_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Carrier_phase_cycles", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Carrier_phase_cycles_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Pseudorange_m", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Pseudorange_m_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, PRN_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Flag_valid_pseudorange", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, Flag_valid_pseudorange_aux, MAT_F_DONT_COPY_DATA); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + + for(unsigned int i = 0; i < d_nchannels; i++) + { + delete[] RX_time[i]; + delete[] TOW_at_current_symbol_s[i]; + delete[] Carrier_Doppler_hz[i]; + delete[] Carrier_phase_cycles[i]; + delete[] Pseudorange_m[i]; + delete[] PRN[i]; + delete[] Flag_valid_pseudorange[i]; + + } + delete[] RX_time; + delete[] TOW_at_current_symbol_s; + delete[] Carrier_Doppler_hz; + delete[] Carrier_phase_cycles; + delete[] Pseudorange_m; + delete[] PRN; + delete[] Flag_valid_pseudorange; + + delete[] RX_time_aux; + delete[] TOW_at_current_symbol_s_aux; + delete[] Carrier_Doppler_hz_aux; + delete[] Carrier_phase_cycles_aux; + delete[] Pseudorange_m_aux; + delete[] PRN_aux; + delete[] Flag_valid_pseudorange_aux; + return 0; } @@ -149,7 +341,11 @@ int hybrid_observables_cc::general_work (int noutput_items __attribute__((unused double past_history_s = 100e-3; Gnss_Synchro current_gnss_synchro[d_nchannels]; - + Gnss_Synchro aux = Gnss_Synchro(); + for(unsigned int i = 0; i < d_nchannels; i++) + { + current_gnss_synchro[i] = aux; + } /* * 1. Read the GNSS SYNCHRO objects from available channels. * Multi-rate GNURADIO Block. Read how many input items are avaliable in each channel @@ -339,13 +535,13 @@ int hybrid_observables_cc::general_work (int noutput_items __attribute__((unused d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_double = current_gnss_synchro[i].Carrier_Doppler_hz; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = current_gnss_synchro[i].Carrier_phase_rads/GPS_TWO_PI; + tmp_double = current_gnss_synchro[i].Carrier_phase_rads / GPS_TWO_PI; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_double = current_gnss_synchro[i].Pseudorange_m; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_double = current_gnss_synchro[i].PRN; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = current_gnss_synchro[i].Flag_valid_pseudorange; + tmp_double = static_cast(current_gnss_synchro[i].Flag_valid_pseudorange); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); } } @@ -384,3 +580,4 @@ int hybrid_observables_cc::general_work (int noutput_items __attribute__((unused return n_outputs; } + diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h index 202a8582e..4d7e67338 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h @@ -72,6 +72,8 @@ private: unsigned int history_deep; std::string d_dump_filename; std::ofstream d_dump_file; + + int save_matfile(); }; #endif diff --git a/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt b/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt index 97e609a5f..6c4ff0c8a 100644 --- a/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt @@ -54,6 +54,7 @@ include_directories( ${GNURADIO_RUNTIME_INCLUDE_DIRS} ${VOLK_GNSSSDR_INCLUDE_DIRS} ${OPT_TRACKING_INCLUDES} + ${MATIO_INCLUDE_DIRS} ) if(ENABLE_GENERIC_ARCH) @@ -65,7 +66,7 @@ list(SORT TRACKING_GR_BLOCKS_HEADERS) add_library(tracking_gr_blocks ${TRACKING_GR_BLOCKS_SOURCES} ${TRACKING_GR_BLOCKS_HEADERS}) source_group(Headers FILES ${TRACKING_GR_BLOCKS_HEADERS}) -target_link_libraries(tracking_gr_blocks tracking_lib ${GNURADIO_RUNTIME_LIBRARIES} gnss_sp_libs ${Boost_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${OPT_TRACKING_LIBRARIES}) +target_link_libraries(tracking_gr_blocks tracking_lib ${GNURADIO_RUNTIME_LIBRARIES} gnss_sp_libs ${Boost_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${MATIO_LIBRARIES} ${OPT_TRACKING_LIBRARIES}) if(NOT VOLK_GNSSSDR_FOUND) add_dependencies(tracking_gr_blocks volk_gnsssdr_module) diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc index 9c23835dc..9250de398 100755 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.cc @@ -42,6 +42,7 @@ #include #include #include +#include #include #include "galileo_e1_signal_processing.h" #include "tracking_discriminators.h" @@ -262,6 +263,18 @@ galileo_e1_dll_pll_veml_tracking_cc::~galileo_e1_dll_pll_veml_tracking_cc() LOG(WARNING) << "Exception in destructor " << ex.what(); } } + if(d_dump) + { + if(d_channel == 0) + { + std::cout << "Writing .mat files ..."; + } + galileo_e1_dll_pll_veml_tracking_cc::save_matfile(); + if(d_channel == 0) + { + std::cout << " done." << std::endl; + } + } try { volk_gnsssdr_free(d_local_code_shift_chips); @@ -509,6 +522,228 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items __attri } +int galileo_e1_dll_pll_veml_tracking_cc::save_matfile() +{ + // READ DUMP FILE + std::ifstream::pos_type size; + int number_of_double_vars = 1; + int number_of_float_vars = 17; + int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(unsigned int); + std::ifstream dump_file; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + } + catch(const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return 1; + } + // count number of epochs and rewind + long int num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + float * abs_VE = new float [num_epoch]; + float * abs_E = new float [num_epoch]; + float * abs_P = new float [num_epoch]; + float * abs_L = new float [num_epoch]; + float * abs_VL = new float [num_epoch]; + float * Prompt_I = new float [num_epoch]; + float * Prompt_Q = new float [num_epoch]; + unsigned long int * PRN_start_sample_count = new unsigned long int [num_epoch]; + float * acc_carrier_phase_rad = new float [num_epoch]; + float * carrier_doppler_hz = new float [num_epoch]; + float * code_freq_chips = new float [num_epoch]; + float * carr_error_hz = new float [num_epoch]; + float * carr_error_filt_hz = new float [num_epoch]; + float * code_error_chips = new float [num_epoch]; + float * code_error_filt_chips = new float [num_epoch]; + float * CN0_SNV_dB_Hz = new float [num_epoch]; + float * carrier_lock_test = new float [num_epoch]; + float * aux1 = new float [num_epoch]; + double * aux2 = new double [num_epoch]; + unsigned int * PRN = new unsigned int [num_epoch]; + + try + { + if (dump_file.is_open()) + { + for(long int i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&abs_VE[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_VL[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carr_error_hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carr_error_filt_hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&code_error_chips[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&code_error_filt_chips[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&CN0_SNV_dB_Hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&aux1[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + delete[] abs_VE; + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] abs_VL; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = d_dump_filename; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if(reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("abs_VE", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_VL", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, acc_carrier_phase_rad, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carrier_doppler_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_freq_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_freq_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carr_error_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carr_error_filt_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_error_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_error_filt_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, CN0_SNV_dB_Hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_lock_test", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carrier_lock_test, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux1", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, aux1, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + delete[] abs_VE; + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] abs_VL; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 0; +} + void galileo_e1_dll_pll_veml_tracking_cc::set_channel(unsigned int channel) { diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.h index 09e6fffe6..2d1aef220 100755 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_dll_pll_veml_tracking_cc.h @@ -174,6 +174,8 @@ private: std::map systemName; std::string sys; + + int save_matfile(); }; #endif //GNSS_SDR_GALILEO_E1_DLL_PLL_VEML_TRACKING_CC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_pll_tracking_cc.cc index 45beca2bf..bdc4b7d00 100644 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_pll_tracking_cc.cc @@ -41,6 +41,7 @@ #include #include #include +#include #include #include "galileo_e5_signal_processing.h" #include "tracking_discriminators.h" @@ -224,6 +225,20 @@ Galileo_E5a_Dll_Pll_Tracking_cc::~Galileo_E5a_Dll_Pll_Tracking_cc() LOG(WARNING)<<"Exception in destructor "<(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + float * abs_E = new float [num_epoch]; + float * abs_P = new float [num_epoch]; + float * abs_L = new float [num_epoch]; + float * Prompt_I = new float [num_epoch]; + float * Prompt_Q = new float [num_epoch]; + unsigned long int * PRN_start_sample_count = new unsigned long int [num_epoch]; + double * acc_carrier_phase_rad = new double [num_epoch]; + double * carrier_doppler_hz = new double [num_epoch]; + double * code_freq_chips = new double [num_epoch]; + double * carr_error_hz = new double [num_epoch]; + double * carr_error_filt_hz = new double [num_epoch]; + double * code_error_chips = new double [num_epoch]; + double * code_error_filt_chips = new double [num_epoch]; + double * CN0_SNV_dB_Hz = new double [num_epoch]; + double * carrier_lock_test = new double [num_epoch]; + double * aux1 = new double [num_epoch]; + double * aux2 = new double [num_epoch]; + unsigned int * PRN = new unsigned int [num_epoch]; + + try + { + if (dump_file.is_open()) + { + for(long int i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_filt_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_filt_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&CN0_SNV_dB_Hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = d_dump_filename; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if(reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, acc_carrier_phase_rad, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_doppler_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_freq_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_freq_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_filt_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_filt_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, CN0_SNV_dB_Hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_lock_test", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_lock_test, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux1", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux1, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 0; +} + + void Galileo_E5a_Dll_Pll_Tracking_cc::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) { d_acquisition_gnss_synchro = p_gnss_synchro; diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_pll_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_pll_tracking_cc.h index 3d21bd7c0..b9bdb342a 100644 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_pll_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e5a_dll_pll_tracking_cc.h @@ -204,6 +204,8 @@ private: std::map systemName; std::string sys; + + int save_matfile(); }; #endif /* GNSS_SDR_GALILEO_E5A_DLL_PLL_TRACKING_CC_H_ */ diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.cc index 8f68d765d..4bab79242 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.cc @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -299,7 +300,6 @@ void gps_l1_ca_dll_pll_c_aid_tracking_cc::start_tracking() gps_l1_ca_dll_pll_c_aid_tracking_cc::~gps_l1_ca_dll_pll_c_aid_tracking_cc() { - if (d_dump_file.is_open()) { try @@ -311,6 +311,20 @@ gps_l1_ca_dll_pll_c_aid_tracking_cc::~gps_l1_ca_dll_pll_c_aid_tracking_cc() LOG(WARNING) << "Exception in destructor " << ex.what(); } } + + if(d_dump) + { + if(d_channel == 0) + { + std::cout << "Writing .mat files ..."; + } + gps_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile(); + if(d_channel == 0) + { + std::cout << " done." << std::endl; + } + } + try { volk_gnsssdr_free(d_local_code_shift_chips); @@ -326,6 +340,212 @@ gps_l1_ca_dll_pll_c_aid_tracking_cc::~gps_l1_ca_dll_pll_c_aid_tracking_cc() } +int gps_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() +{ + // READ DUMP FILE + std::ifstream::pos_type size; + int number_of_double_vars = 11; + int number_of_float_vars = 5; + int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(unsigned int); + std::ifstream dump_file; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + } + catch(const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return 1; + } + // count number of epochs and rewind + long int num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + float * abs_E = new float [num_epoch]; + float * abs_P = new float [num_epoch]; + float * abs_L = new float [num_epoch]; + float * Prompt_I = new float [num_epoch]; + float * Prompt_Q = new float [num_epoch]; + unsigned long int * PRN_start_sample_count = new unsigned long int [num_epoch]; + double * acc_carrier_phase_rad = new double [num_epoch]; + double * carrier_doppler_hz = new double [num_epoch]; + double * code_freq_chips = new double [num_epoch]; + double * carr_error_hz = new double [num_epoch]; + double * carr_error_filt_hz = new double [num_epoch]; + double * code_error_chips = new double [num_epoch]; + double * code_error_filt_chips = new double [num_epoch]; + double * CN0_SNV_dB_Hz = new double [num_epoch]; + double * carrier_lock_test = new double [num_epoch]; + double * aux1 = new double [num_epoch]; + double * aux2 = new double [num_epoch]; + unsigned int * PRN = new unsigned int [num_epoch]; + + try + { + if (dump_file.is_open()) + { + for(long int i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_filt_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_filt_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&CN0_SNV_dB_Hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = d_dump_filename; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if(reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, acc_carrier_phase_rad, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_doppler_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_freq_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_freq_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_filt_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_filt_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, CN0_SNV_dB_Hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_lock_test", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_lock_test, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux1", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux1, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 0; +} + int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.h index 8801a96fb..cf6f31b5f 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.h @@ -196,6 +196,8 @@ private: std::map systemName; std::string sys; + + int save_matfile(); }; #endif //GNSS_SDR_GPS_L1_CA_DLL_PLL_C_AID_TRACKING_CC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.cc index 22d504786..0b39b1ebe 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.cc @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -309,6 +310,20 @@ gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::~gps_l1_ca_dll_pll_c_aid_tracking_fpga LOG(WARNING)<< "Exception in destructor " << ex.what(); } } + + if(d_dump) + { + if(d_channel == 0) + { + std::cout << "Writing .mat files ..."; + } + gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::save_matfile(); + if(d_channel == 0) + { + std::cout << " done." << std::endl; + } + } + try { volk_gnsssdr_free(d_local_code_shift_chips); @@ -665,6 +680,10 @@ int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::general_work( d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_double = static_cast(d_sample_counter + d_correlation_length_samples); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + + // PRN + unsigned int prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); } catch (const std::ifstream::failure* e) { @@ -710,6 +729,212 @@ void gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::set_channel(unsigned int channel) } +int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::save_matfile() +{ + // READ DUMP FILE + std::ifstream::pos_type size; + int number_of_double_vars = 11; + int number_of_float_vars = 5; + int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(unsigned int); + std::ifstream dump_file; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + } + catch(const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return 1; + } + // count number of epochs and rewind + long int num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + float * abs_E = new float [num_epoch]; + float * abs_P = new float [num_epoch]; + float * abs_L = new float [num_epoch]; + float * Prompt_I = new float [num_epoch]; + float * Prompt_Q = new float [num_epoch]; + unsigned long int * PRN_start_sample_count = new unsigned long int [num_epoch]; + double * acc_carrier_phase_rad = new double [num_epoch]; + double * carrier_doppler_hz = new double [num_epoch]; + double * code_freq_chips = new double [num_epoch]; + double * carr_error_hz = new double [num_epoch]; + double * carr_error_filt_hz = new double [num_epoch]; + double * code_error_chips = new double [num_epoch]; + double * code_error_filt_chips = new double [num_epoch]; + double * CN0_SNV_dB_Hz = new double [num_epoch]; + double * carrier_lock_test = new double [num_epoch]; + double * aux1 = new double [num_epoch]; + double * aux2 = new double [num_epoch]; + unsigned int * PRN = new unsigned int [num_epoch]; + + try + { + if (dump_file.is_open()) + { + for(long int i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_filt_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_filt_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&CN0_SNV_dB_Hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = d_dump_filename; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if(reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, acc_carrier_phase_rad, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_doppler_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_freq_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_freq_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_filt_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_filt_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, CN0_SNV_dB_Hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_lock_test", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_lock_test, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux1", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux1, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 0; +} + void gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::set_gnss_synchro( Gnss_Synchro* p_gnss_synchro) { diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.h b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.h index 444ffbc72..9dded8939 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.h +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.h @@ -178,6 +178,8 @@ private: std::map systemName; std::string sys; + + int save_matfile(); }; #endif //GNSS_SDR_GPS_L1_CA_DLL_PLL_C_AID_TRACKING_FPGA_SC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.cc index 24e96ff02..8973bb6a4 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.cc @@ -39,6 +39,7 @@ #include #include #include +#include #include "gnss_synchro.h" #include "gps_sdr_signal_processing.h" #include "tracking_discriminators.h" @@ -313,6 +314,20 @@ gps_l1_ca_dll_pll_c_aid_tracking_sc::~gps_l1_ca_dll_pll_c_aid_tracking_sc() LOG(WARNING) << "Exception in destructor " << ex.what(); } } + + if(d_dump) + { + if(d_channel == 0) + { + std::cout << "Writing .mat files ..."; + } + gps_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile(); + if(d_channel == 0) + { + std::cout << " done." << std::endl; + } + } + try { volk_gnsssdr_free(d_local_code_shift_chips); @@ -330,6 +345,212 @@ gps_l1_ca_dll_pll_c_aid_tracking_sc::~gps_l1_ca_dll_pll_c_aid_tracking_sc() } +int gps_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() +{ + // READ DUMP FILE + std::ifstream::pos_type size; + int number_of_double_vars = 11; + int number_of_float_vars = 5; + int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(unsigned int); + std::ifstream dump_file; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + } + catch(const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return 1; + } + // count number of epochs and rewind + long int num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + float * abs_E = new float [num_epoch]; + float * abs_P = new float [num_epoch]; + float * abs_L = new float [num_epoch]; + float * Prompt_I = new float [num_epoch]; + float * Prompt_Q = new float [num_epoch]; + unsigned long int * PRN_start_sample_count = new unsigned long int [num_epoch]; + double * acc_carrier_phase_rad = new double [num_epoch]; + double * carrier_doppler_hz = new double [num_epoch]; + double * code_freq_chips = new double [num_epoch]; + double * carr_error_hz = new double [num_epoch]; + double * carr_error_filt_hz = new double [num_epoch]; + double * code_error_chips = new double [num_epoch]; + double * code_error_filt_chips = new double [num_epoch]; + double * CN0_SNV_dB_Hz = new double [num_epoch]; + double * carrier_lock_test = new double [num_epoch]; + double * aux1 = new double [num_epoch]; + double * aux2 = new double [num_epoch]; + unsigned int * PRN = new unsigned int [num_epoch]; + + try + { + if (dump_file.is_open()) + { + for(long int i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_filt_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_filt_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&CN0_SNV_dB_Hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = d_dump_filename; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if(reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, acc_carrier_phase_rad, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_doppler_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_freq_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_freq_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_filt_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_filt_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, CN0_SNV_dB_Hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_lock_test", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_lock_test, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux1", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux1, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 0; +} + int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.h b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.h index caf81d7c8..cd9753b6d 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.h +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.h @@ -200,6 +200,8 @@ private: std::map systemName; std::string sys; + + int save_matfile(); }; #endif //GNSS_SDR_GPS_L1_CA_DLL_PLL_C_AID_TRACKING_SC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc index 32d96c079..ec5004c56 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.cc @@ -43,6 +43,7 @@ #include #include #include +#include #include "gps_sdr_signal_processing.h" #include "tracking_discriminators.h" #include "lock_detectors.h" @@ -266,6 +267,213 @@ void Gps_L1_Ca_Dll_Pll_Tracking_cc::start_tracking() } +int Gps_L1_Ca_Dll_Pll_Tracking_cc::save_matfile() +{ + // READ DUMP FILE + std::ifstream::pos_type size; + int number_of_double_vars = 11; + int number_of_float_vars = 5; + int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(unsigned int); + std::ifstream dump_file; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + } + catch(const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return 1; + } + // count number of epochs and rewind + long int num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + float * abs_E = new float [num_epoch]; + float * abs_P = new float [num_epoch]; + float * abs_L = new float [num_epoch]; + float * Prompt_I = new float [num_epoch]; + float * Prompt_Q = new float [num_epoch]; + unsigned long int * PRN_start_sample_count = new unsigned long int [num_epoch]; + double * acc_carrier_phase_rad = new double [num_epoch]; + double * carrier_doppler_hz = new double [num_epoch]; + double * code_freq_chips = new double [num_epoch]; + double * carr_error_hz = new double [num_epoch]; + double * carr_error_filt_hz = new double [num_epoch]; + double * code_error_chips = new double [num_epoch]; + double * code_error_filt_chips = new double [num_epoch]; + double * CN0_SNV_dB_Hz = new double [num_epoch]; + double * carrier_lock_test = new double [num_epoch]; + double * aux1 = new double [num_epoch]; + double * aux2 = new double [num_epoch]; + unsigned int * PRN = new unsigned int [num_epoch]; + + try + { + if (dump_file.is_open()) + { + for(long int i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_filt_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_filt_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&CN0_SNV_dB_Hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = d_dump_filename; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if(reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, acc_carrier_phase_rad, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_doppler_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_freq_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_freq_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_filt_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_filt_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, CN0_SNV_dB_Hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_lock_test", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_lock_test, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux1", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux1, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 0; +} + + Gps_L1_Ca_Dll_Pll_Tracking_cc::~Gps_L1_Ca_Dll_Pll_Tracking_cc() { if (d_dump_file.is_open()) @@ -279,6 +487,20 @@ Gps_L1_Ca_Dll_Pll_Tracking_cc::~Gps_L1_Ca_Dll_Pll_Tracking_cc() LOG(WARNING) << "Exception in destructor " << ex.what(); } } + + if(d_dump) + { + if(d_channel == 0) + { + std::cout << "Writing .mat files ..."; + } + Gps_L1_Ca_Dll_Pll_Tracking_cc::save_matfile(); + if(d_channel == 0) + { + std::cout << " done." << std::endl; + } + } + try { volk_gnsssdr_free(d_local_code_shift_chips); @@ -291,6 +513,7 @@ Gps_L1_Ca_Dll_Pll_Tracking_cc::~Gps_L1_Ca_Dll_Pll_Tracking_cc() { LOG(WARNING) << "Exception in destructor " << ex.what(); } + } @@ -443,7 +666,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribute__ d_correlator_outs[n] = gr_complex(0,0); } - current_synchro_data.Tracking_sample_counter =d_sample_counter + d_current_prn_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples; current_synchro_data.System = {'G'}; current_synchro_data.correlation_length_ms = 1; } diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.h index 9fe80fec7..346f7076a 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_cc.h @@ -101,6 +101,7 @@ private: float dll_bw_hz, float early_late_space_chips); + int save_matfile(); // tracking configuration vars unsigned int d_vector_length; bool d_dump; diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l2_m_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l2_m_dll_pll_tracking_cc.cc index 18d6a2fc2..dfa1b6990 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l2_m_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l2_m_dll_pll_tracking_cc.cc @@ -42,6 +42,7 @@ #include #include #include +#include #include #include "gps_l2c_signal.h" #include "tracking_discriminators.h" @@ -269,6 +270,213 @@ void gps_l2_m_dll_pll_tracking_cc::start_tracking() } +int gps_l2_m_dll_pll_tracking_cc::save_matfile() +{ + // READ DUMP FILE + std::ifstream::pos_type size; + int number_of_double_vars = 11; + int number_of_float_vars = 5; + int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(unsigned int); + std::ifstream dump_file; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + } + catch(const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return 1; + } + // count number of epochs and rewind + long int num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + float * abs_E = new float [num_epoch]; + float * abs_P = new float [num_epoch]; + float * abs_L = new float [num_epoch]; + float * Prompt_I = new float [num_epoch]; + float * Prompt_Q = new float [num_epoch]; + unsigned long int * PRN_start_sample_count = new unsigned long int [num_epoch]; + double * acc_carrier_phase_rad = new double [num_epoch]; + double * carrier_doppler_hz = new double [num_epoch]; + double * code_freq_chips = new double [num_epoch]; + double * carr_error_hz = new double [num_epoch]; + double * carr_error_filt_hz = new double [num_epoch]; + double * code_error_chips = new double [num_epoch]; + double * code_error_filt_chips = new double [num_epoch]; + double * CN0_SNV_dB_Hz = new double [num_epoch]; + double * carrier_lock_test = new double [num_epoch]; + double * aux1 = new double [num_epoch]; + double * aux2 = new double [num_epoch]; + unsigned int * PRN = new unsigned int [num_epoch]; + + try + { + if (dump_file.is_open()) + { + for(long int i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carr_error_filt_hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&code_error_filt_chips[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&CN0_SNV_dB_Hz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = d_dump_filename; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if(reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, acc_carrier_phase_rad, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_doppler_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_freq_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_freq_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_filt_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_filt_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, CN0_SNV_dB_Hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_lock_test", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_lock_test, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux1", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux1, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 0; +} + + gps_l2_m_dll_pll_tracking_cc::~gps_l2_m_dll_pll_tracking_cc() { if (d_dump_file.is_open()) @@ -282,6 +490,18 @@ gps_l2_m_dll_pll_tracking_cc::~gps_l2_m_dll_pll_tracking_cc() LOG(WARNING) << "Exception in destructor " << ex.what(); } } + if(d_dump) + { + if(d_channel == 0) + { + std::cout << "Writing .mat files ..."; + } + gps_l2_m_dll_pll_tracking_cc::save_matfile(); + if(d_channel == 0) + { + std::cout << " done." << std::endl; + } + } try { volk_gnsssdr_free(d_local_code_shift_chips); diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l2_m_dll_pll_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/gps_l2_m_dll_pll_tracking_cc.h index 37942778b..cf46636e2 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l2_m_dll_pll_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l2_m_dll_pll_tracking_cc.h @@ -162,6 +162,8 @@ private: std::map systemName; std::string sys; + + int save_matfile(); }; #endif //GNSS_SDR_GPS_L2_M_DLL_PLL_TRACKING_CC_H diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 2dad13942..db052ce7b 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -161,6 +161,12 @@ if(GNUPLOT_FOUND) add_definitions(-DGNUPLOT_EXECUTABLE="${GNUPLOT_EXECUTABLE}") endif(GNUPLOT_FOUND) +if(MATIO_FOUND OR MATIO_LOCAL) + add_definitions(-DMATIO_TEST=1) + set(GNSS_SDR_TEST_OPTIONAL_LIBS "${GNSS_SDR_TEST_OPTIONAL_LIBS};${MATIO_LIBRARIES}") + set(GNSS_SDR_TEST_OPTIONAL_HEADERS "${GNSS_SDR_TEST_OPTIONAL_HEADERS};${MATIO_INCLUDE_DIRS}") +endif(MATIO_FOUND OR MATIO_LOCAL) + ################################################################################ # Optional generator ################################################################################ @@ -323,7 +329,6 @@ include_directories( ${VOLK_INCLUDE_DIRS} ${VOLK_GNSSSDR_INCLUDE_DIRS} ${GNSS_SDR_TEST_OPTIONAL_HEADERS} - ${GNSS_SDR_TEST_OPTIONAL_HEADERS} ) @@ -415,19 +420,19 @@ if(ENABLE_SYSTEM_TESTING) endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") add_definitions(-DHOST_SYSTEM="${HOST_SYSTEM}") set(TTFF_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/ttff_gps_l1.cc) - + # Ensure that ttff is rebuilt if it was previously built and then removed if(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/ttff) - execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${TTFF_SOURCES}) + execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${TTFF_SOURCES}) endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/ttff) - + add_executable(ttff ${TTFF_SOURCES} ) if(NOT ${GTEST_DIR_LOCAL}) add_dependencies(ttff gtest-${GNSSSDR_GTEST_LOCAL_VERSION}) else(NOT ${GTEST_DIR_LOCAL}) add_dependencies(ttff gtest) endif(NOT ${GTEST_DIR_LOCAL}) - + target_link_libraries(ttff ${Boost_LIBRARIES} ${GFlags_LIBS} @@ -458,7 +463,7 @@ if(ENABLE_SYSTEM_TESTING) set(POSITION_TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/position_test.cc) # Ensure that position_test is rebuilt if it was previously built and then removed if(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/position_test) - execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${POSITION_TEST_SOURCES}) + execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${POSITION_TEST_SOURCES}) endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/position_test) add_executable(position_test ${POSITION_TEST_SOURCES}) if(NOT ${GTEST_DIR_LOCAL}) @@ -496,17 +501,17 @@ if(ENABLE_SYSTEM_TESTING) set(OBS_GPS_L1_TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_gps_l1_system_test.cc) # Ensure that obs_gps_l1_system_test is rebuilt if it was previously built and then removed if(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) - execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${OBS_GPS_L1_TEST_SOURCES}) + execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${OBS_GPS_L1_TEST_SOURCES}) endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) add_executable(obs_gps_l1_system_test ${OBS_GPS_L1_TEST_SOURCES}) - + set(OBS_SYSTEM_TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_system_test.cc) # Ensure that obs_system_test is rebuilt if it was previously built and then removed if(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test) - execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${OBS_SYSTEM_TEST_SOURCES}) + execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${OBS_SYSTEM_TEST_SOURCES}) endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test) add_executable(obs_system_test ${OBS_SYSTEM_TEST_SOURCES}) - + if(NOT ${GTEST_DIR_LOCAL}) add_dependencies(obs_gps_l1_system_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION} ) add_dependencies(obs_system_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION} ) @@ -521,7 +526,7 @@ if(ENABLE_SYSTEM_TESTING) gnss_sp_libs gnss_rx ${gpstk_libs}) - + target_link_libraries(obs_system_test ${GFlags_LIBS} ${GLOG_LIBRARIES} ${GTEST_LIBRARIES} @@ -534,7 +539,7 @@ if(ENABLE_SYSTEM_TESTING) file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) install(TARGETS obs_gps_l1_system_test RUNTIME DESTINATION bin COMPONENT "obs_gps_l1_system_test") - + if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test) file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_system_test) endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test) @@ -565,7 +570,7 @@ else(ENABLE_SYSTEM_TESTING) # Avoid working with old executables if they were switched ON and then OFF if(EXISTS ${CMAKE_SOURCE_DIR}/install/ttff) file(REMOVE ${CMAKE_SOURCE_DIR}/install/ttff) - endif(EXISTS ${CMAKE_SOURCE_DIR}/install/ttff) + endif(EXISTS ${CMAKE_SOURCE_DIR}/install/ttff) if(EXISTS ${CMAKE_SOURCE_DIR}/install/position_test) file(REMOVE ${CMAKE_SOURCE_DIR}/install/position_test) endif(EXISTS ${CMAKE_SOURCE_DIR}/install/position_test) @@ -574,7 +579,7 @@ else(ENABLE_SYSTEM_TESTING) endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test) file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_system_test) - endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test) + endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test) endif(ENABLE_SYSTEM_TESTING) diff --git a/src/tests/common-files/gnuplot_i.h b/src/tests/common-files/gnuplot_i.h index 3627a38af..3e9b966c6 100644 --- a/src/tests/common-files/gnuplot_i.h +++ b/src/tests/common-files/gnuplot_i.h @@ -1895,12 +1895,13 @@ bool Gnuplot::get_program_path() else { std::list ls; + std::string path_str = path; //split path (one long string) into list ls of strings #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) - stringtok(ls,path,";"); + stringtok(ls,path_str,";"); #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) - stringtok(ls,path,":"); + stringtok(ls,path_str,":"); #endif // scan list for Gnuplot program files @@ -1921,10 +1922,8 @@ bool Gnuplot::get_program_path() tmp = "Can't find gnuplot neither in PATH nor in \"" + Gnuplot::m_sGNUPlotPath + "\""; - throw GnuplotException(tmp); - Gnuplot::m_sGNUPlotPath = ""; - return false; + throw GnuplotException(tmp); } } @@ -2046,7 +2045,6 @@ std::string Gnuplot::create_tmpfile(std::ofstream &tmp) std::ostringstream except; except << "Cannot create temporary file \"" << name << "\""; throw GnuplotException(except.str()); - return ""; } // @@ -2064,7 +2062,8 @@ void Gnuplot::remove_tmpfiles() if ((tmpfile_list).size() > 0) { for (unsigned int i = 0; i < tmpfile_list.size(); i++) - remove( tmpfile_list[i].c_str() ); + if(remove( tmpfile_list[i].c_str() ) != 0) + std::cout << "Problem closing files" << std::endl; Gnuplot::tmpfile_num -= tmpfile_list.size(); } diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index 82e88f9a4..21b3e8c9f 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -74,6 +74,9 @@ DECLARE_string(log_dir); #include "unit-tests/arithmetic/code_generation_test.cc" #include "unit-tests/arithmetic/fft_length_test.cc" #include "unit-tests/arithmetic/fft_speed_test.cc" +#if MATIO_TEST +#include "unit-tests/arithmetic/matio_test.cc" +#endif #include "unit-tests/control-plane/file_configuration_test.cc" #include "unit-tests/control-plane/in_memory_configuration_test.cc" diff --git a/src/tests/unit-tests/arithmetic/matio_test.cc b/src/tests/unit-tests/arithmetic/matio_test.cc new file mode 100644 index 000000000..552414d5d --- /dev/null +++ b/src/tests/unit-tests/arithmetic/matio_test.cc @@ -0,0 +1,159 @@ +/*! + * \file matio_test.cc + * \brief This file implements tests for the matio library + * in long arrays. + * \author Carles Fernandez-Prades, 2017. cfernandez(at)cttc.es + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include +#include +#include + +TEST(MatioTest, WriteAndReadDoubles) +{ + // Write a .mat file + mat_t *matfp; + matvar_t *matvar; + std::string filename = "./test.mat"; + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + ASSERT_FALSE(reinterpret_cast(matfp) == NULL) << "Error creating .mat file"; + + double x[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + size_t dims[2] = {10, 1}; + matvar = Mat_VarCreate("x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, x, 0); + ASSERT_FALSE(reinterpret_cast(matvar) == NULL) << "Error creating variable for ’x’"; + + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + Mat_Close(matfp); + + // Read a .mat file + mat_t *matfp_read; + matvar_t *matvar_read; + + matfp_read = Mat_Open(filename.c_str(), MAT_ACC_RDONLY); + ASSERT_FALSE(reinterpret_cast(matfp_read) == NULL) << "Error reading .mat file"; + + matvar_read = Mat_VarReadInfo(matfp_read, "x"); + ASSERT_FALSE(reinterpret_cast(matvar_read) == NULL) << "Error reading variable in .mat file"; + + matvar_read = Mat_VarRead(matfp_read, "x"); + double *x_read = reinterpret_cast(matvar_read->data); + Mat_Close(matfp_read); + + for(int i = 0; i < 10; i++) + { + EXPECT_DOUBLE_EQ(x[i], x_read[i]); + } + Mat_VarFree(matvar_read); + ASSERT_EQ(remove(filename.c_str()), 0); +} + + +TEST(MatioTest, WriteAndReadGrComplex) +{ + // Write a .mat file + mat_t *matfp; + matvar_t *matvar1; + std::string filename = "./test3.mat"; + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + ASSERT_FALSE(reinterpret_cast(matfp) == NULL) << "Error creating .mat file"; + + std::vector x_v = { {1, 10}, {2, 9}, {3, 8}, {4, 7}, {5, 6}, {6, -5}, {7, -4}, {8, 3}, {9, 2}, {10, 1}}; + const unsigned int size = x_v.size(); + float x_real[size]; + float x_imag[size]; + unsigned int i = 0; + for (std::vector::const_iterator it = x_v.cbegin(); it != x_v.cend(); it++) + { + x_real[i] = it->real(); + x_imag[i] = it->imag(); + i++; + } + + struct mat_complex_split_t x = {x_real, x_imag}; + size_t dims[2] = {static_cast(size), 1}; + matvar1 = Mat_VarCreate("x", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, &x, MAT_F_COMPLEX); + ASSERT_FALSE(reinterpret_cast(matvar1) == NULL) << "Error creating variable for ’x’"; + + std::vector x2 = { {1.1, -10}, {2, -9}, {3, -8}, {4, -7}, {5, 6}, {6, -5}, {7, -4}, {8, 3}, {9, 2}, {10, 1}}; + const unsigned int size_y = x2.size(); + float y_real[size_y]; + float y_imag[size_y]; + i = 0; + for (std::vector::const_iterator it = x2.cbegin(); it != x2.cend(); it++) + { + y_real[i] = it->real(); + y_imag[i] = it->imag(); + i++; + } + + struct mat_complex_split_t y = {y_real, y_imag}; + size_t dims_y[2] = {static_cast(size_y), 1}; + matvar_t *matvar2; + matvar2 = Mat_VarCreate("y", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims_y, &y, MAT_F_COMPLEX); + ASSERT_FALSE(reinterpret_cast(matvar2) == NULL) << "Error creating variable for ’y’"; + + Mat_VarWrite(matfp, matvar1, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarWrite(matfp, matvar2, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar1); + Mat_VarFree(matvar2); + + Mat_Close(matfp); + + // Read a .mat file + mat_t *matfp_read; + matvar_t *matvar_read; + + matfp_read = Mat_Open(filename.c_str(), MAT_ACC_RDONLY); + ASSERT_FALSE(reinterpret_cast(matfp_read) == NULL) << "Error reading .mat file"; + + matvar_read = Mat_VarReadInfo(matfp_read, "x"); + ASSERT_FALSE(reinterpret_cast(matvar_read) == NULL) << "Error reading variable in .mat file"; + + matvar_read = Mat_VarRead(matfp_read, "x"); + mat_complex_split_t *x_read_st = reinterpret_cast(matvar_read->data); + float * x_read_real = reinterpret_cast(x_read_st->Re); + float * x_read_imag = reinterpret_cast(x_read_st->Im); + std::vector x_v_read; + for(unsigned int i = 0; i < size; i++) + { + x_v_read.push_back(gr_complex(x_read_real[i], x_read_imag[i])); + } + + Mat_Close(matfp_read); + Mat_VarFree(matvar_read); + + for(unsigned int i = 0; i < size; i++) + { + EXPECT_FLOAT_EQ(x_v[i].real(), x_v_read[i].real()); + EXPECT_FLOAT_EQ(x_v[i].imag(), x_v_read[i].imag()); + } + ASSERT_EQ(remove(filename.c_str()), 0); +} diff --git a/src/tests/unit-tests/signal-processing-blocks/adapter/pass_through_test.cc b/src/tests/unit-tests/signal-processing-blocks/adapter/pass_through_test.cc index 656a0d688..070196fe6 100644 --- a/src/tests/unit-tests/signal-processing-blocks/adapter/pass_through_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/adapter/pass_through_test.cc @@ -41,9 +41,6 @@ TEST(PassThroughTest, Instantiate) { std::shared_ptr config = std::make_shared(); config->set_property("Test.item_type", "gr_complex"); - config->set_property("Test.vector_size", "2"); std::shared_ptr signal_conditioner = std::make_shared(config.get(), "Test", 1, 1); EXPECT_STREQ("gr_complex", signal_conditioner->item_type().c_str()); - unsigned int expected2 = 2; - EXPECT_EQ(expected2, signal_conditioner->vector_size()); } diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc b/src/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc index baa3feea0..3d5b4a1af 100644 --- a/src/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc @@ -192,14 +192,14 @@ TEST_F(FirFilterTest, ConnectAndRun) top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, filter->get_left_block(), 0); top_block->connect(filter->get_right_block(), 0, null_sink, 0); - }) << "Failure connecting the top_block."<< std::endl; + }) << "Failure connecting the top_block."; EXPECT_NO_THROW( { start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; std::cout << "Filtered " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -234,14 +234,14 @@ TEST_F(FirFilterTest, ConnectAndRunGrcomplex) top_block->connect(source->get_right_block(), 0, filter->get_left_block(), 0); top_block->connect(filter->get_right_block(), 0, null_sink, 0); - }) << "Failure connecting the top_block."<< std::endl; + }) << "Failure connecting the top_block."; EXPECT_NO_THROW( { start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; std::cout << "Filtered " << nsamples << " gr_complex samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -277,14 +277,14 @@ TEST_F(FirFilterTest, ConnectAndRunCshorts) top_block->connect(source->get_right_block(), 0, ishort_to_cshort_, 0); top_block->connect(ishort_to_cshort_, 0, filter->get_left_block(), 0); top_block->connect(filter->get_right_block(), 0, null_sink, 0); - }) << "Failure connecting the top_block."<< std::endl; + }) << "Failure connecting the top_block."; EXPECT_NO_THROW( { start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; std::cout << "Filtered " << nsamples << " std::complex samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -322,14 +322,14 @@ TEST_F(FirFilterTest, ConnectAndRunCbytes) top_block->connect(source->get_right_block(), 0, ibyte_to_cbyte_, 0); top_block->connect(ibyte_to_cbyte_, 0, filter->get_left_block(), 0); top_block->connect(filter->get_right_block(), 0, null_sink, 0); - }) << "Failure connecting the top_block."<< std::endl; + }) << "Failure connecting the top_block."; EXPECT_NO_THROW( { start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; std::cout << "Filtered " << nsamples << " std::complex samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -366,13 +366,13 @@ TEST_F(FirFilterTest, ConnectAndRunCbyteGrcomplex) top_block->connect(source->get_right_block(), 0, ibyte_to_cbyte_, 0); top_block->connect(ibyte_to_cbyte_, 0, filter->get_left_block(), 0); top_block->connect(filter->get_right_block(), 0, null_sink, 0); - }) << "Failure connecting the top_block."<< std::endl; + }) << "Failure connecting the top_block."; EXPECT_NO_THROW( { start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; std::cout << "Filtered " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc b/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc index 363ff89ce..13896442c 100644 --- a/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc @@ -116,14 +116,14 @@ TEST_F(NotchFilterLiteTest, ConnectAndRun) top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, filter->get_left_block(), 0); top_block->connect(filter->get_right_block(), 0, null_sink, 0); - }) << "Failure connecting the top_block."<< std::endl; + }) << "Failure connecting the top_block."; EXPECT_NO_THROW( { start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; std::cout << "Filtered " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -157,13 +157,13 @@ TEST_F(NotchFilterLiteTest, ConnectAndRunGrcomplex) top_block->connect(source->get_right_block(), 0, filter->get_left_block(), 0); top_block->connect(filter->get_right_block(), 0, null_sink, 0); - }) << "Failure connecting the top_block."<< std::endl; + }) << "Failure connecting the top_block."; EXPECT_NO_THROW( { start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; std::cout << "Filtered " << nsamples << " gr_complex samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc b/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc index f3997ecc2..a6a13dc42 100644 --- a/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc @@ -116,14 +116,14 @@ TEST_F(NotchFilterTest, ConnectAndRun) top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, filter->get_left_block(), 0); top_block->connect(filter->get_right_block(), 0, null_sink, 0); - }) << "Failure connecting the top_block."<< std::endl; + }) << "Failure connecting the top_block."; EXPECT_NO_THROW( { start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; std::cout << "Filtered " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -157,13 +157,13 @@ TEST_F(NotchFilterTest, ConnectAndRunGrcomplex) top_block->connect(source->get_right_block(), 0, filter->get_left_block(), 0); top_block->connect(filter->get_right_block(), 0, null_sink, 0); - }) << "Failure connecting the top_block."<< std::endl; + }) << "Failure connecting the top_block."; EXPECT_NO_THROW( { start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; std::cout << "Filtered " << nsamples << " gr_complex samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc b/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc index f157bf3a6..1b09b7367 100644 --- a/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc @@ -115,14 +115,14 @@ TEST_F(PulseBlankingFilterTest, ConnectAndRun) top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, filter->get_left_block(), 0); top_block->connect(filter->get_right_block(), 0, null_sink, 0); - }) << "Failure connecting the top_block."<< std::endl; + }) << "Failure connecting the top_block."; EXPECT_NO_THROW( { start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; std::cout << "Filtered " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -156,13 +156,13 @@ TEST_F(PulseBlankingFilterTest, ConnectAndRunGrcomplex) top_block->connect(source->get_right_block(), 0, filter->get_left_block(), 0); top_block->connect(filter->get_right_block(), 0, null_sink, 0); - }) << "Failure connecting the top_block."<< std::endl; + }) << "Failure connecting the top_block."; EXPECT_NO_THROW( { start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; std::cout << "Filtered " << nsamples << " gr_complex samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; }