mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-03-14 07:28:17 +00:00
Bumping version 0.0.4
This commit is contained in:
commit
eb52b1428c
4
.gitignore
vendored
4
.gitignore
vendored
@ -5,4 +5,6 @@ docs/latex
|
||||
docs/GNSS-SDR_manual.pdf
|
||||
src/tests/data/output.dat
|
||||
thirdparty/
|
||||
.project
|
||||
.project
|
||||
.cproject
|
||||
/install
|
||||
|
2
AUTHORS
2
AUTHORS
@ -42,6 +42,8 @@ David Pubill david.pubill@cttc.cat Developer
|
||||
Mara Branzanti mara.branzanti@gmail.com Developer
|
||||
Marc Molina marc.molina.pena@gmail.com Developer
|
||||
Daniel Fehr daniel.co@bluewin.ch Developer
|
||||
Marc Sales marcsales92@gmail.com Developer
|
||||
Damian Miralles dmiralles2009@gmail.com Developer
|
||||
Leonardo Tonetto tonetto.dev@gmail.com Contributor
|
||||
Ignacio Paniego ignacio.paniego@gmail.com Web design
|
||||
Eva Puchol eva.puchol@gmail.com Web developer
|
||||
|
408
CMakeLists.txt
408
CMakeLists.txt
@ -16,26 +16,38 @@
|
||||
# along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
########################################################################
|
||||
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||
message(FATAL_ERROR "Prevented in-tree build. This is bad practice. Try 'cd build && cmake ../' ")
|
||||
endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||
|
||||
########################################################################
|
||||
# Project setup
|
||||
########################################################################
|
||||
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||
message(FATAL_ERROR "Prevented in-tree build. This is bad practice. Try 'cd build && cmake ../' ")
|
||||
endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(gnss-sdr CXX C)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
|
||||
file(RELATIVE_PATH RELATIVE_CMAKE_CALL ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
|
||||
########################################################################
|
||||
# Determine optional blocks/libraries to be built (default: not built)
|
||||
# Enable them here or at the command line by doing 'cmake -DENABLE_XXX=ON ../'
|
||||
########################################################################
|
||||
|
||||
option(ENABLE_GN3S "Enable the use of the GN3S dongle as signal source (experimental)" OFF)
|
||||
option(ENABLE_ARRAY "Enable the use of CTTC's antenna array front-end as signal source (experimental)" OFF)
|
||||
option(ENABLE_RTLSDR "Enable the use of RTL dongles as signal source (experimental)" OFF)
|
||||
option(ENABLE_OPENCL "Enable building of processing blocks implemented with OpenCL (experimental)" OFF)
|
||||
option(ENABLE_GPERFTOOLS "Enable linking to Gperftools libraries (tcmalloc and profiler)" OFF)
|
||||
option(ENABLE_GENERIC_ARCH "Builds a portable binary" OFF)
|
||||
|
||||
|
||||
# Set the version information here
|
||||
set(VERSION_INFO_MAJOR_VERSION 0)
|
||||
set(VERSION_INFO_API_COMPAT 0)
|
||||
set(VERSION_INFO_MINOR_VERSION 3)
|
||||
set(VERSION_INFO_API_COMPAT 0)
|
||||
set(VERSION_INFO_MINOR_VERSION 4)
|
||||
set(VERSION ${VERSION_INFO_MAJOR_VERSION}.${VERSION_INFO_API_COMPAT}.${VERSION_INFO_MINOR_VERSION})
|
||||
|
||||
file(RELATIVE_PATH RELATIVE_CMAKE_CALL ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
########################################################################
|
||||
# Environment setup
|
||||
@ -156,10 +168,16 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
endif(${DARWIN_VERSION} MATCHES "10")
|
||||
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
|
||||
|
||||
#select the release build type by default to get optimization flags
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
message(STATUS "Build type not specified: defaulting to Release.")
|
||||
if(ENABLE_GPERFTOOLS)
|
||||
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
|
||||
message(STATUS "Build type not specified: defaulting to RelWithDebInfo.")
|
||||
else(ENABLE_GPERFTOOLS)
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
message(STATUS "Build type not specified: defaulting to Release.")
|
||||
endif(ENABLE_GPERFTOOLS)
|
||||
endif(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
|
||||
|
||||
@ -182,6 +200,7 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
|
||||
endif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
|
||||
|
||||
################################################################################
|
||||
# Googletest - http://code.google.com/p/googletest/
|
||||
################################################################################
|
||||
@ -203,7 +222,6 @@ endif(GTEST_DIR)
|
||||
################################################################################
|
||||
# Boost - http://www.boost.org
|
||||
################################################################################
|
||||
|
||||
if(UNIX AND EXISTS "/usr/lib64")
|
||||
list(APPEND BOOST_LIBRARYDIR "/usr/lib64") # Fedora 64-bit fix
|
||||
endif(UNIX AND EXISTS "/usr/lib64")
|
||||
@ -231,9 +249,7 @@ endif(NOT Boost_FOUND)
|
||||
################################################################################
|
||||
# GNU Radio - http://gnuradio.org/redmine/projects/gnuradio/wiki
|
||||
################################################################################
|
||||
|
||||
find_package(Gnuradio)
|
||||
|
||||
if(NOT GNURADIO_RUNTIME_FOUND)
|
||||
message(STATUS "CMake cannot find GNU Radio >= 3.7")
|
||||
if(OS_IS_LINUX)
|
||||
@ -356,7 +372,6 @@ endif(NOT GFlags_FOUND OR LOCAL_GLOG)
|
||||
################################################################################
|
||||
# glog - http://code.google.com/p/google-glog/
|
||||
################################################################################
|
||||
|
||||
find_package(GLOG)
|
||||
set(glog_RELEASE 0.3.3)
|
||||
if (NOT GLOG_FOUND OR LOCAL_GFLAGS)
|
||||
@ -458,97 +473,14 @@ endif(NOT GLOG_FOUND OR LOCAL_GFLAGS)
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# GPerftools - http://code.google.com/p/gperftools/
|
||||
################################################################################
|
||||
|
||||
set(GCC_GPERFTOOLS_FLAGS "")
|
||||
find_package(Gperftools)
|
||||
if ( NOT GPERFTOOLS_FOUND )
|
||||
message(STATUS "The optional library GPerftools has not been found.")
|
||||
else( NOT GPERFTOOLS_FOUND )
|
||||
message (STATUS "GPerftools library found." )
|
||||
link_libraries(${GPERFTOOLS_PROFILER} ${GPERFTOOLS_TCMALLOC})
|
||||
endif( NOT GPERFTOOLS_FOUND )
|
||||
list(APPEND CMAKE_CXX_FLAGS ${GCC_GPERFTOOLS_FLAGS})
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# Doxygen - http://www.stack.nl/~dimitri/doxygen/index.html
|
||||
################################################################################
|
||||
|
||||
find_package(Doxygen)
|
||||
if(DOXYGEN_FOUND)
|
||||
message(STATUS "Doxygen found.")
|
||||
message(STATUS "You can build the documentation with 'make doc'." )
|
||||
message(STATUS "When done, point your browser to ${CMAKE_SOURCE_DIR}/html/index.html")
|
||||
set(HAVE_DOT ${DOXYGEN_DOT_FOUND})
|
||||
file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} top_srcdir)
|
||||
file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} top_builddir)
|
||||
find_package(LATEX)
|
||||
if (PDFLATEX_COMPILER)
|
||||
set(GENERATE_PDF_DOCUMENTATION "YES")
|
||||
set(GNSSSDR_USE_MATHJAX "NO")
|
||||
else(PDFLATEX_COMPILER)
|
||||
set(GENERATE_PDF_DOCUMENTATION "NO")
|
||||
set(GNSSSDR_USE_MATHJAX "YES")
|
||||
endif(PDFLATEX_COMPILER)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile.in
|
||||
${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile
|
||||
@ONLY
|
||||
)
|
||||
add_custom_target(doc
|
||||
${DOXYGEN_EXECUTABLE} ${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
COMMENT "Generating API documentation with Doxygen." VERBATIM
|
||||
)
|
||||
if(LATEX_COMPILER)
|
||||
message(STATUS "'make pdfmanual' will generate a manual at ${CMAKE_SOURCE_DIR}/docs/GNSS-SDR_manual.pdf")
|
||||
add_custom_target(pdfmanual
|
||||
COMMAND ${CMAKE_MAKE_PROGRAM}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy refman.pdf ${CMAKE_SOURCE_DIR}/docs/GNSS-SDR_manual.pdf
|
||||
COMMAND ${CMAKE_MAKE_PROGRAM} clean
|
||||
DEPENDS doc
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/latex
|
||||
COMMENT "Generating PDF manual with Doxygen." VERBATIM
|
||||
)
|
||||
endif(LATEX_COMPILER)
|
||||
message(STATUS "'make doc-clean' will clean the documentation.")
|
||||
add_custom_target(doc-clean
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/docs/html
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/docs/latex
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_SOURCE_DIR}/docs/GNSS-SDR_manual.pdf
|
||||
COMMENT "Cleaning documentation." VERBATIM
|
||||
)
|
||||
else(DOXYGEN_FOUND)
|
||||
message(STATUS " Doxygen has not been found in your system.")
|
||||
message(STATUS " You can get nice code documentation by using it!")
|
||||
message(STATUS " Get it from http://www.stack.nl/~dimitri/doxygen/index.html")
|
||||
if(OS_IS_LINUX)
|
||||
if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||
message(" or simply by doing 'sudo yum install doxygen-latex'.")
|
||||
else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||
message(" or simply by doing 'sudo apt-get install doxygen-latex'.")
|
||||
endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||
endif(OS_IS_LINUX)
|
||||
if(OS_IS_MACOSX)
|
||||
message(STATUS " or simply by doing 'sudo port install doxygen +latex'.")
|
||||
endif(OS_IS_MACOSX)
|
||||
endif(DOXYGEN_FOUND)
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# Armadillo - http://arma.sourceforge.net/
|
||||
################################################################################
|
||||
|
||||
if(OS_IS_LINUX)
|
||||
#############################################
|
||||
#############################################################################
|
||||
# Check that LAPACK is found in the system
|
||||
#############################################
|
||||
# LAPACK is required for matrix decompositions (eg. SVD) and matrix inverse.
|
||||
#############################################################################
|
||||
find_library(LAPACK lapack)
|
||||
if(NOT LAPACK)
|
||||
message(" The LAPACK library has not been found.")
|
||||
@ -562,9 +494,11 @@ if(OS_IS_LINUX)
|
||||
endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||
message(FATAL_ERROR "LAPACK is required to build gnss-sdr")
|
||||
endif(NOT LAPACK)
|
||||
#############################################
|
||||
#############################################################################
|
||||
# Check that BLAS is found in the system
|
||||
#############################################
|
||||
# BLAS is used for matrix multiplication.
|
||||
# Without BLAS, matrix multiplication will still work, but might be slower.
|
||||
#############################################################################
|
||||
find_library(BLAS blas)
|
||||
if(NOT BLAS)
|
||||
message(" The BLAS library has not been found.")
|
||||
@ -641,31 +575,22 @@ if(NOT ARMADILLO_FOUND)
|
||||
endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||
message(FATAL_ERROR "The patch command is required to download and build armadillo")
|
||||
endif(NOT PATCH_EXECUTABLE)
|
||||
set(armadillo_RELEASE 4.300.9)
|
||||
set(armadillo_MD5 "d51d1beb2a335f3002702d112c4814f3")
|
||||
set(armadillo_RELEASE 4.400.2)
|
||||
set(armadillo_MD5 "1f7e14d14e5636286f6e001a98a1735a")
|
||||
if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/download/armadillo-${armadillo_RELEASE}/armadillo-${armadillo_RELEASE}.tar.gz)
|
||||
set(ARMADILLO_PATCH_FILE ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/armadillo_no.patch)
|
||||
file(WRITE ${ARMADILLO_PATCH_FILE} "")
|
||||
set(ARMADILLO_PATCH_FILE2 ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/armadillo_no2.patch)
|
||||
file(WRITE ${ARMADILLO_PATCH_FILE2} "")
|
||||
else(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/download/armadillo-${armadillo_RELEASE}/armadillo-${armadillo_RELEASE}.tar.gz)
|
||||
set(ARMADILLO_PATCH_FILE ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/armadillo_staticlib.patch)
|
||||
set(ARMADILLO_PATCH_FILE2 ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/armadillo_enable_lapack.patch)
|
||||
set(ARMADILLO_PATCH_FILE ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/armadillo_enable_lapack.patch)
|
||||
file(WRITE ${ARMADILLO_PATCH_FILE}
|
||||
"30c30
|
||||
< set(ARMA_USE_LAPACK false)
|
||||
---
|
||||
> set(ARMA_USE_LAPACK true)
|
||||
312c312
|
||||
< add_library( armadillo SHARED \${PROJECT_SOURCE_DIR}/src/wrapper.cpp )
|
||||
---
|
||||
> add_library( armadillo STATIC \${PROJECT_SOURCE_DIR}/src/wrapper.cpp )
|
||||
")
|
||||
file(WRITE ${ARMADILLO_PATCH_FILE2}
|
||||
"12c12
|
||||
< // #define ARMA_USE_LAPACK
|
||||
---
|
||||
> #define ARMA_USE_LAPACK
|
||||
> #define ARMA_USE_LAPACK
|
||||
19c19
|
||||
< // #define ARMA_USE_BLAS
|
||||
---
|
||||
> #define ARMA_USE_BLAS
|
||||
")
|
||||
endif(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/download/armadillo-${armadillo_RELEASE}/armadillo-${armadillo_RELEASE}.tar.gz)
|
||||
ExternalProject_Add(
|
||||
@ -673,9 +598,9 @@ if(NOT ARMADILLO_FOUND)
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}
|
||||
URL http://sourceforge.net/projects/arma/files/armadillo-${armadillo_RELEASE}.tar.gz
|
||||
DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR}/download/armadillo-${armadillo_RELEASE}
|
||||
URL_MD5 ${armadillo_MD5}
|
||||
PATCH_COMMAND patch -N <BINARY_DIR>/CMakeLists.txt ${ARMADILLO_PATCH_FILE} && patch -N <BINARY_DIR>/include/armadillo_bits/config.hpp ${ARMADILLO_PATCH_FILE2}
|
||||
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
URL_MD5 ${armadillo_MD5}
|
||||
PATCH_COMMAND patch -N <BINARY_DIR>/include/armadillo_bits/config.hpp ${ARMADILLO_PATCH_FILE}
|
||||
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DBUILD_SHARED_LIBS=OFF
|
||||
BUILD_IN_SOURCE 1
|
||||
BUILD_COMMAND make
|
||||
UPDATE_COMMAND ""
|
||||
@ -686,7 +611,14 @@ if(NOT ARMADILLO_FOUND)
|
||||
ExternalProject_Get_Property(armadillo-${armadillo_RELEASE} binary_dir)
|
||||
set(ARMADILLO_INCLUDE_DIRS ${binary_dir}/include )
|
||||
find_library(LAPACK NAMES lapack HINTS /usr/lib /usr/local/lib /usr/lib64)
|
||||
set(ARMADILLO_LIBRARIES ${LAPACK} ${GFORTRAN} ${binary_dir}/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo.a)
|
||||
if(OS_IS_MACOSX)
|
||||
find_library(BLAS blas)
|
||||
endif(OS_IS_MACOSX)
|
||||
find_package(OpenBLAS)
|
||||
if(OPENBLAS_FOUND)
|
||||
set(BLAS ${OPENBLAS})
|
||||
endif(OPENBLAS_FOUND)
|
||||
set(ARMADILLO_LIBRARIES ${BLAS} ${LAPACK} ${GFORTRAN} ${binary_dir}/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo.a)
|
||||
set(LOCAL_ARMADILLO true CACHE STRING "Armadillo downloaded and built automatically" FORCE)
|
||||
# Save a copy at the thirdparty folder
|
||||
file(COPY ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}
|
||||
@ -700,27 +632,6 @@ endif(NOT ARMADILLO_FOUND)
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# OpenCL
|
||||
###############################################################################
|
||||
find_package(OpenCL)
|
||||
if($ENV{DISABLE_OPENCL})
|
||||
set(DISABLE_OPENCL TRUE)
|
||||
endif($ENV{DISABLE_OPENCL})
|
||||
if(DISABLE_OPENCL)
|
||||
set(OPENCL_FOUND FALSE)
|
||||
else(DISABLE_OPENCL)
|
||||
if(OPENCL_FOUND)
|
||||
message(STATUS "OpenCL has been found and will be used by some processing blocks")
|
||||
message(STATUS "You can disable OpenCL use by doing 'cmake -DDISABLE_OPENCL=1 ../' ")
|
||||
endif(OPENCL_FOUND)
|
||||
endif(DISABLE_OPENCL)
|
||||
if(NOT OPENCL_FOUND)
|
||||
message(STATUS "Processing blocks using OpenCL will not be built.")
|
||||
endif(NOT OPENCL_FOUND)
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# OpenSSL - http://www.openssl.org
|
||||
################################################################################
|
||||
@ -742,41 +653,173 @@ if(NOT OPENSSL_FOUND)
|
||||
endif(NOT OPENSSL_FOUND)
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# Doxygen - http://www.stack.nl/~dimitri/doxygen/index.html (OPTIONAL)
|
||||
################################################################################
|
||||
find_package(Doxygen)
|
||||
if(DOXYGEN_FOUND)
|
||||
message(STATUS "Doxygen found.")
|
||||
message(STATUS "You can build the documentation with 'make doc'." )
|
||||
message(STATUS "When done, point your browser to ${CMAKE_SOURCE_DIR}/html/index.html")
|
||||
set(HAVE_DOT ${DOXYGEN_DOT_FOUND})
|
||||
file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} top_srcdir)
|
||||
file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} top_builddir)
|
||||
find_package(LATEX)
|
||||
if (PDFLATEX_COMPILER)
|
||||
set(GENERATE_PDF_DOCUMENTATION "YES")
|
||||
set(GNSSSDR_USE_MATHJAX "NO")
|
||||
else(PDFLATEX_COMPILER)
|
||||
set(GENERATE_PDF_DOCUMENTATION "NO")
|
||||
set(GNSSSDR_USE_MATHJAX "YES")
|
||||
endif(PDFLATEX_COMPILER)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile.in
|
||||
${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile
|
||||
@ONLY
|
||||
)
|
||||
add_custom_target(doc
|
||||
${DOXYGEN_EXECUTABLE} ${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
COMMENT "Generating API documentation with Doxygen." VERBATIM
|
||||
)
|
||||
if(LATEX_COMPILER)
|
||||
message(STATUS "'make pdfmanual' will generate a manual at ${CMAKE_SOURCE_DIR}/docs/GNSS-SDR_manual.pdf")
|
||||
add_custom_target(pdfmanual
|
||||
COMMAND ${CMAKE_MAKE_PROGRAM}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy refman.pdf ${CMAKE_SOURCE_DIR}/docs/GNSS-SDR_manual.pdf
|
||||
COMMAND ${CMAKE_MAKE_PROGRAM} clean
|
||||
DEPENDS doc
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/latex
|
||||
COMMENT "Generating PDF manual with Doxygen." VERBATIM
|
||||
)
|
||||
endif(LATEX_COMPILER)
|
||||
message(STATUS "'make doc-clean' will clean the documentation.")
|
||||
add_custom_target(doc-clean
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/docs/html
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/docs/latex
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_SOURCE_DIR}/docs/GNSS-SDR_manual.pdf
|
||||
COMMENT "Cleaning documentation." VERBATIM
|
||||
)
|
||||
else(DOXYGEN_FOUND)
|
||||
message(STATUS " Doxygen has not been found in your system.")
|
||||
message(STATUS " You can get nice code documentation by using it!")
|
||||
message(STATUS " Get it from http://www.stack.nl/~dimitri/doxygen/index.html")
|
||||
if(OS_IS_LINUX)
|
||||
if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||
message(" or simply by doing 'sudo yum install doxygen-latex'.")
|
||||
else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||
message(" or simply by doing 'sudo apt-get install doxygen-latex'.")
|
||||
endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||
endif(OS_IS_LINUX)
|
||||
if(OS_IS_MACOSX)
|
||||
message(STATUS " or simply by doing 'sudo port install doxygen +latex'.")
|
||||
endif(OS_IS_MACOSX)
|
||||
endif(DOXYGEN_FOUND)
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# OpenCL (OPTIONAL)
|
||||
###############################################################################
|
||||
if(ENABLE_OPENCL)
|
||||
find_package(OpenCL)
|
||||
if($ENV{DISABLE_OPENCL})
|
||||
set(DISABLE_OPENCL TRUE)
|
||||
endif($ENV{DISABLE_OPENCL})
|
||||
if(DISABLE_OPENCL)
|
||||
set(OPENCL_FOUND FALSE)
|
||||
else(DISABLE_OPENCL)
|
||||
if(OPENCL_FOUND)
|
||||
message(STATUS "OpenCL has been found and will be used by some processing blocks")
|
||||
message(STATUS "You can disable OpenCL use by doing 'cmake -DENABLE_OPENCL=OFF ../' ")
|
||||
endif(OPENCL_FOUND)
|
||||
endif(DISABLE_OPENCL)
|
||||
if(ENABLE_GENERIC_ARCH)
|
||||
set(OPENCL_FOUND FALSE)
|
||||
message(STATUS "ENABLE_GENERIC_ARCH is set to ON so the use of OpenCL has been disabled.")
|
||||
endif(ENABLE_GENERIC_ARCH)
|
||||
if(NOT OPENCL_FOUND)
|
||||
message(STATUS "Processing blocks using OpenCL will not be built.")
|
||||
endif(NOT OPENCL_FOUND)
|
||||
else(ENABLE_OPENCL)
|
||||
set(OPENCL_FOUND FALSE)
|
||||
endif(ENABLE_OPENCL)
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# GPerftools - http://code.google.com/p/gperftools/ (OPTIONAL)
|
||||
################################################################################
|
||||
|
||||
if(ENABLE_GPERFTOOLS)
|
||||
find_package(Gperftools)
|
||||
if ( NOT GPERFTOOLS_FOUND )
|
||||
message(STATUS "Although ENABLE_GPERFTOOLS has been set to ON, GPerftools has not been found.")
|
||||
message(STATUS "Binaries will be compiled without 'tcmalloc' and 'profiler' libraries.")
|
||||
message(STATUS "You can install GPerftools from http://code.google.com/p/gperftools/")
|
||||
else( NOT GPERFTOOLS_FOUND )
|
||||
message(STATUS "GPerftools libraries found." )
|
||||
message(STATUS "Binaries will be compiled with 'tcmalloc' and 'profiler' libraries.")
|
||||
endif( NOT GPERFTOOLS_FOUND )
|
||||
endif(ENABLE_GPERFTOOLS)
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# Setup of optional drivers
|
||||
################################################################################
|
||||
if( $ENV{GN3S_DRIVER} )
|
||||
message(STATUS "GN3S_DRIVER variable found." )
|
||||
# copy firmware to install folder
|
||||
# Build project gr-gn3s
|
||||
else( $ENV{GN3S_DRIVER} )
|
||||
if( GN3S_DRIVER )
|
||||
message(STATUS "GN3S driver will be compiled")
|
||||
else( GNSS_DRIVER )
|
||||
message(STATUS "GN3S_DRIVER is not defined." )
|
||||
message(STATUS "Define it with 'export GN3S_DRIVER=1' to add support for the GN3S dongle." )
|
||||
endif( GN3S_DRIVER )
|
||||
endif($ENV{GN3S_DRIVER} )
|
||||
|
||||
if( $ENV{RAW_ARRAY_DRIVER} )
|
||||
message(STATUS "RAW_ARRAY_DRIVER variable found." )
|
||||
if($ENV{GN3S_DRIVER})
|
||||
message(STATUS "GN3S_DRIVER environment variable found." )
|
||||
set(ENABLE_GN3S ON)
|
||||
endif($ENV{GN3S_DRIVER})
|
||||
if(GN3S_DRIVER)
|
||||
set(ENABLE_GN3S ON)
|
||||
endif(GN3S_DRIVER)
|
||||
if(ENABLE_GN3S)
|
||||
message(STATUS "The GN3S driver will be compiled.")
|
||||
message(STATUS "You can disable it with 'cmake -DENABLE_GN3S=OFF ../'" )
|
||||
else(ENABLE_GN3S)
|
||||
message(STATUS "The (optional and experimental) GN3S driver is not enabled." )
|
||||
message(STATUS "Enable it with 'cmake -DENABLE_GN3S=ON ../' to add support for the GN3S dongle." )
|
||||
endif(ENABLE_GN3S)
|
||||
|
||||
|
||||
if($ENV{RAW_ARRAY_DRIVER})
|
||||
message(STATUS "RAW_ARRAY_DRIVER environment variable found." )
|
||||
set(ENABLE_ARRAY ON)
|
||||
endif($ENV{RAW_ARRAY_DRIVER})
|
||||
if(RAW_ARRAY_DRIVER)
|
||||
set(ENABLE_ARRAY ON)
|
||||
endif(RAW_ARRAY_DRIVER)
|
||||
if(ENABLE_ARRAY)
|
||||
message(STATUS "CTTC's Antenna Array front-end driver will be compiled." )
|
||||
message(STATUS "You can disable it with 'cmake -DENABLE_ARRAY=OFF ../'" )
|
||||
# copy firmware to install folder
|
||||
# Build project gr-dbfcttc
|
||||
else( $ENV{RAW_ARRAY_DRIVER} )
|
||||
if( RAW_ARRAY_DRIVER )
|
||||
message(STATUS "RAW_ARRAY_DRIVER driver will be compiled")
|
||||
else( RAW_ARRAY_DRIVER )
|
||||
message(STATUS "RAW_ARRAY_DRIVER is not defined." )
|
||||
message(STATUS "Define it with 'export RAW_ARRAY_DRIVER=1' to add support for the CTTC experimental array front-end." )
|
||||
endif( RAW_ARRAY_DRIVER )
|
||||
endif($ENV{RAW_ARRAY_DRIVER} )
|
||||
else(ENABLE_ARRAY)
|
||||
message(STATUS "The (optional) CTTC's Antenna Array front-end driver is not enabled." )
|
||||
message(STATUS "Enable it with 'cmake -DENABLE_ARRAY=ON ../' to add support for the CTTC experimental array front-end." )
|
||||
endif(ENABLE_ARRAY)
|
||||
|
||||
if( $ENV{RTLSDR_DRIVER} )
|
||||
message(STATUS "RTLSDR_DRIVER variable found." )
|
||||
|
||||
if($ENV{RTLSDR_DRIVER})
|
||||
message(STATUS "RTLSDR_DRIVER environment variable found." )
|
||||
set(ENABLE_RTLSDR ON)
|
||||
endif($ENV{RTLSDR_DRIVER})
|
||||
if(RAW_ARRAY_DRIVER)
|
||||
set(ENABLE_RTLSDR ON)
|
||||
endif(RAW_ARRAY_DRIVER)
|
||||
if(ENABLE_RTLSDR)
|
||||
message(STATUS "The driver for RTL-based dongles will be compiled." )
|
||||
message(STATUS "You can disable it with 'cmake -DENABLE_RTLSDR=OFF ../'" )
|
||||
# find libosmosdr (done in src/algorithms/signal_sources/adapters)
|
||||
# find gr-osmosdr (done in src/algorithms/signal_sources/adapters)
|
||||
endif($ENV{RTLSDR_DRIVER} )
|
||||
|
||||
else(ENABLE_RTLSDR)
|
||||
message(STATUS "The (optional) driver for RTL-based dongles is not enabled." )
|
||||
message(STATUS "Enable it with 'cmake -DENABLE_RTLSDR=ON ../' to add support for Realtek's RTL2832U-based USB dongles." )
|
||||
endif(ENABLE_RTLSDR)
|
||||
|
||||
|
||||
########################################################################
|
||||
@ -802,7 +845,11 @@ if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
|
||||
if(OS_IS_MACOSX)
|
||||
set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -march=corei7 -mfpmath=sse")
|
||||
else(OS_IS_MACOSX)
|
||||
set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -march=native -mfpmath=sse")
|
||||
if(ENABLE_GENERIC_ARCH)
|
||||
set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -mtune=generic")
|
||||
else(ENABLE_GENERIC_ARCH)
|
||||
set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -march=native -mfpmath=sse")
|
||||
endif(ENABLE_GENERIC_ARCH)
|
||||
endif(OS_IS_MACOSX)
|
||||
endif(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
|
||||
|
||||
@ -811,13 +858,18 @@ if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
|
||||
add_definitions(-fvisibility=hidden)
|
||||
endif()
|
||||
|
||||
# Set GPerftools related flags if it is available
|
||||
# See http://gperftools.googlecode.com/svn/trunk/README
|
||||
if(GPERFTOOLS_FOUND)
|
||||
if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
|
||||
set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free")
|
||||
endif(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
|
||||
endif(GPERFTOOLS_FOUND)
|
||||
if(ENABLE_GPERFTOOLS)
|
||||
# Set GPerftools related flags if it is available
|
||||
# See http://gperftools.googlecode.com/svn/trunk/README
|
||||
if(GPERFTOOLS_FOUND)
|
||||
if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
|
||||
set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free")
|
||||
endif(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -fno-builtin")
|
||||
endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
endif(GPERFTOOLS_FOUND)
|
||||
endif(ENABLE_GPERFTOOLS)
|
||||
|
||||
list(APPEND CMAKE_CXX_FLAGS ${MY_CXX_FLAGS})
|
||||
|
||||
|
214
README.md
214
README.md
@ -13,7 +13,7 @@ If you have questions about GNSS-SDR, please [subscribe to the gnss-sdr-develope
|
||||
# How to build GNSS-SDR
|
||||
|
||||
|
||||
This section describes how to set up the compilation environment in GNU/Linux or Mac OS X, and to build GNSS-SDR. See also [our Building Guide](http://gnss-sdr.org/documentation/building-guide "GNSS-SDR's Building Guide").
|
||||
This section describes how to set up the compilation environment in GNU/Linux or [Mac OS X](#macosx)t, and to build GNSS-SDR. See also [our Building Guide](http://gnss-sdr.org/documentation/building-guide "GNSS-SDR's Building Guide").
|
||||
|
||||
GNU/Linux
|
||||
----------
|
||||
@ -74,9 +74,9 @@ $ sudo apt-get install libopenblas-dev liblapack-dev gfortran # For Debian/Ubu
|
||||
$ sudo yum install lapack-devel blas-devel gcc-fortran # For Fedora/CentOS/RHEL
|
||||
$ sudo zypper install lapack-devel blas-devel gcc-fortran # For OpenSUSE
|
||||
|
||||
$ wget http://sourceforge.net/projects/arma/files/armadillo-4.300.9.tar.gz
|
||||
$ tar xvfz armadillo-4.300.9.tar.gz
|
||||
$ cd armadillo-4.300.9
|
||||
$ wget http://sourceforge.net/projects/arma/files/armadillo-4.400.2.tar.gz
|
||||
$ tar xvfz armadillo-4.400.2.tar.gz
|
||||
$ cd armadillo-4.400.2
|
||||
$ cmake .
|
||||
$ make
|
||||
$ sudo make install
|
||||
@ -127,10 +127,10 @@ $ make
|
||||
Please **DO NOT install** gtest (do *not* type ```sudo make install```). Every user needs to compile his tests using the same compiler flags used to compile the installed Google Test libraries; otherwise he may run into undefined behaviors (i.e. the tests can behave strangely and may even crash for no obvious reasons). The reason is that C++ has this thing called the One-Definition Rule: if two C++ source files contain different definitions of the same class/function/variable, and you link them together, you violate the rule. The linker may or may not catch the error (in many cases it is not required by the C++ standard to catch the violation). If it does not, you get strange run-time behaviors that are unexpected and hard to debug. If you compile Google Test and your test code using different compiler flags, they may see different definitions of the same class/function/variable (e.g. due to the use of ```#if``` in Google Test). Therefore, for your sanity, we recommend to avoid installing pre-compiled Google Test libraries. Instead, each project should compile Google Test itself such that it can be sure that the same flags are used for both Google Test and the tests. The building system of GNSS-SDR does the compilation and linking of gtest its own tests; it is only required that you tell the system where the gtest folder that you downloaded resides. Just add to your ```$HOME/.bashrc``` file the following line:
|
||||
|
||||
~~~~~~
|
||||
$ export GTEST_DIR=/home/username/gtest-1.7.0
|
||||
export GTEST_DIR=/home/username/gtest-1.7.0
|
||||
~~~~~~
|
||||
|
||||
changing /home/username/gtest-1.7.0 by the actual directory where you downloaded gtest. Again, it is recommended to add this line to your ```$HOME/.bashrc``` file.
|
||||
changing /home/username/gtest-1.7.0 by the actual directory where you downloaded gtest.
|
||||
|
||||
|
||||
|
||||
@ -170,13 +170,72 @@ Cloning the GNSS-SDR repository as in the line above will create a folder named
|
||||
~~~~~~
|
||||
|
||||
|
||||
|
||||
### Build GNSS-SDR
|
||||
|
||||
Go to GNSS-SDR's build directory:
|
||||
|
||||
~~~~~~
|
||||
$ cd gnss-sdr/build
|
||||
~~~~~~
|
||||
|
||||
Configure and build the application:
|
||||
|
||||
~~~~~~
|
||||
$ cmake ../
|
||||
$ make
|
||||
$ make install
|
||||
~~~~~~
|
||||
|
||||
By default, CMake will build the Release version, meaning that the compiler will generate a fast, optimized executable. This is the recommended build type when using a RF front-end and you need to attain real time. If working with a file (and thus without real-time constraints), you may want to obtain more information about the internals of the receiver, as well as more fine-grained logging. This can be done by building the Debug version, by doing:
|
||||
|
||||
~~~~~~
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Debug ../
|
||||
$ make
|
||||
$ make install
|
||||
~~~~~~
|
||||
|
||||
If everything goes well, two new executables will be created at gnss-sdr/install, namely ```gnss-sdr``` and ```run_tests```.
|
||||
|
||||
You can create the documentation by doing:
|
||||
|
||||
~~~~~~
|
||||
$ make doc
|
||||
~~~~~~
|
||||
|
||||
from the gnss-sdr/build folder. This will generate HTML documentation that can be retrieved pointing your browser of preference to gnss-sdr/docs/html/index.html.
|
||||
If a LaTeX installation is detected in your system,
|
||||
|
||||
~~~~~~
|
||||
$ make pdfmanual
|
||||
~~~~~~
|
||||
|
||||
will create a PDF manual at gnss-sdr/docs/GNSS-SDR_manual.pdf. Finally,
|
||||
|
||||
~~~~~~
|
||||
$ make doc-clean
|
||||
~~~~~~
|
||||
|
||||
will remove the content of previously-generated documentation.
|
||||
|
||||
|
||||
If you are using Eclipse as your development environment, CMake can create the project for you. Type:
|
||||
|
||||
~~~~~~
|
||||
$ cmake -G "Eclipse CDT4 - Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DECLIPSE_CDT4_GENERATE_SOURCE_PROJECT=TRUE -DCMAKE_ECLIPSE_VERSION=3.7 -DCMAKE_ECLIPSE_MAKE_ARGUMENTS=-j8 ../
|
||||
~~~~~~
|
||||
|
||||
and then import the created project file into Eclipse:
|
||||
|
||||
1. Import project using Menu File -> Import.
|
||||
2. Select General -> Existing projects into workspace.
|
||||
3. Browse where your build tree is and select the root build tree directory. Keep "Copy projects into workspace" unchecked.
|
||||
4. You get a fully functional Eclipse project.
|
||||
|
||||
|
||||
###### Build GN3S V2 Custom firmware and driver (OPTIONAL):
|
||||
|
||||
Go to GR-GN3S root directory, compile and install the driver (read the drivers/gr-gn3s/README for more information):
|
||||
|
||||
|
||||
~~~~~~
|
||||
$ cd gnss-sdr/drivers/gr-gn3s
|
||||
$ cd build
|
||||
@ -186,18 +245,17 @@ $ sudo make install
|
||||
$ sudo ldconfig
|
||||
~~~~~~
|
||||
|
||||
|
||||
Set the environment variable ```GN3S_DRIVER=1``` in order to enable the GN3S_Signal_Source in GNSS-SDR:
|
||||
|
||||
Then configure GNSS-SDR to build the GN3S_Signal_Source by:
|
||||
|
||||
~~~~~~
|
||||
$ export GN3S_DRIVER=1
|
||||
$ cmake -DENABLE_GN3S=ON ../
|
||||
$ make && make install
|
||||
~~~~~~
|
||||
|
||||
In order to gain access to USB ports, gnss-sdr should be used as root. In addition, the driver requires access to the GN3S firmware binary file. It should be available in the same path where the application is called.
|
||||
GNSS-SDR comes with a pre-compiled custom GN3S firmware available at gnss-sdr/firmware/GN3S_v2/bin/gn3s_firmware.ihx. Please copy this file to the application path. The GNSS-SDR default path is gnss-sdr/install
|
||||
|
||||
(in order to disable the GN3S_Signal_Source compilation, you should remove the GN3S_DRIVER variable and build again GNSS-SDR).
|
||||
(in order to disable the GN3S_Signal_Source compilation, you can pass -DENABLE_GN3S=OFF to cmake and build GNSS-SDR again).
|
||||
|
||||
|
||||
|
||||
@ -227,109 +285,41 @@ $ sudo ldconfig
|
||||
~~~~~~
|
||||
|
||||
|
||||
Set the environment variable ```RTLSDR_DRIVER=1``` in order to enable the Rtlsdr_Signal_Source in GNSS-SDR:
|
||||
|
||||
Then configure GNSS-SDR to build the Rtlsdr_Signal_Source by:
|
||||
|
||||
~~~~~~
|
||||
$ export RTLSDR_DRIVER=1
|
||||
$ cmake -DENABLE_RTLSDR=ON ../
|
||||
$ make && make install
|
||||
~~~~~~
|
||||
|
||||
(in order to disable the Rtlsdr_Signal_Source compilation, you can pass -DENABLE_RTLSDR=OFF to cmake and build GNSS-SDR again).
|
||||
|
||||
|
||||
|
||||
###### Build OpenCL support (OPTIONAL):
|
||||
|
||||
In order to enable the building of blocks that use OpenCL, type:
|
||||
|
||||
~~~~~~
|
||||
$ cmake -DENABLE_OPENCL=ON ../
|
||||
$ make && make install
|
||||
~~~~~~
|
||||
|
||||
|
||||
In order to compile the RTLSDR adapter you should also provide the path to the gr-osmosdr source code using:
|
||||
###### Build a portable binary
|
||||
|
||||
In order to build an executable that not depends on the specific SIMD instruction set that is present in the processor of the compiling machine, so other users can execute it in other machines without those particular sets, use:
|
||||
|
||||
~~~~~~
|
||||
$ export OSMOSDR_ROOT=/path/to/gr-osmosdr
|
||||
$ cmake -DENABLE_GENERIC_ARCH=ON ../
|
||||
$ make && make install
|
||||
~~~~~~
|
||||
|
||||
Using this option, all SIMD instructions are accessed via VOLK, which automatically includes versions of each function for different SIMD instruction sets, then detects at runtime which to use, or if there are none, substitutes a generic, non-SIMD implementation.
|
||||
|
||||
The default will be ```OSMOSDR_ROOT=/usr/local```
|
||||
|
||||
(in order to disable the Rtlsdr_Signal_Source compilation, you should remove the RTLSDR_DRIVER variable and build again GNSS-SDR).
|
||||
|
||||
|
||||
|
||||
### Build GNSS-SDR
|
||||
|
||||
Go to GNSS-SDR's build directory:
|
||||
|
||||
~~~~~~
|
||||
$ cd gnss-sdr/build
|
||||
~~~~~~
|
||||
|
||||
Configure and build the application:
|
||||
|
||||
~~~~~~
|
||||
$ cmake ../
|
||||
$ make
|
||||
~~~~~~
|
||||
|
||||
By default, CMake is configured to build the release version. If you want to build the debug version, please use:
|
||||
|
||||
~~~~~~
|
||||
$ cmake ../ -DCMAKE_BUILD_TYPE=Debug
|
||||
~~~~~~
|
||||
|
||||
Move the executables to the install folder:
|
||||
|
||||
~~~~~~
|
||||
$ make install
|
||||
~~~~~~
|
||||
|
||||
If everything goes well, two new executables will be created at gnss-sdr/install, namely ```gnss-sdr``` and ```run_tests```.
|
||||
|
||||
You can create the documentation by doing:
|
||||
|
||||
~~~~~~
|
||||
$ make doc
|
||||
~~~~~~
|
||||
|
||||
from the gnss-sdr/build folder. This will generate HTML documentation that can be retrieved pointing your browser of preference to gnss-sdr/docs/html/index.html.
|
||||
If a LaTeX installation is detected in your system,
|
||||
|
||||
~~~~~~
|
||||
$ make pdfmanual
|
||||
~~~~~~
|
||||
|
||||
will create a PDF manual at gnss-sdr/docs/GNSS-SDR_manual.pdf. Please note that the PDF generation requires some fonts to be installed on the host system. In Ubuntu 12.10, those fonts do not come by default. You can install them by doing:
|
||||
|
||||
~~~~~~
|
||||
$ sudo apt-get install texlive-fonts-recommended
|
||||
~~~~~~
|
||||
|
||||
and then run ```cmake ../``` and make pdfmanual again. Finally,
|
||||
|
||||
~~~~~~
|
||||
$ make doc-clean
|
||||
~~~~~~
|
||||
|
||||
will remove the content of previously-generated documentation.
|
||||
|
||||
By default, CMake will build the Release version, meaning that the compiler will generate a faster, optimized executable. This is the recommended build type when using a RF front-end and you need to attain real time. If you are working with a file (and thus without real-time constraints), you may want to obtain more information about the internals of the receiver, as well as more fine-grained logging. This can be done by building the Debug version, by doing:
|
||||
|
||||
~~~~~~
|
||||
$ cd gnss-sdr/build
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Debug ../
|
||||
$ make
|
||||
$ make install
|
||||
~~~~~~
|
||||
|
||||
If you are using Eclipse as your development environment, CMake can create the project for you. Type:
|
||||
|
||||
~~~~~~
|
||||
$ cmake -G "Eclipse CDT4 - Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DECLIPSE_CDT4_GENERATE_SOURCE_PROJECT=TRUE -DCMAKE_ECLIPSE_VERSION=3.7 -DCMAKE_ECLIPSE_MAKE_ARGUMENTS=-j8 ../
|
||||
~~~~~~
|
||||
|
||||
and then import the created project file into Eclipse:
|
||||
|
||||
1. Import project using Menu File -> Import.
|
||||
2. Select General -> Existing projects into workspace.
|
||||
3. Browse where your build tree is and select the root build tree directory. Keep "Copy projects into workspace" unchecked.
|
||||
4. You get a fully functional Eclipse project.
|
||||
|
||||
|
||||
|
||||
Mac OS X
|
||||
<a name="macosx">Mac OS X</a>
|
||||
---------
|
||||
|
||||
Tested versions: 10.8 (Mountain Lion) and 10.9 (Mavericks).
|
||||
@ -338,7 +328,17 @@ Tested versions: 10.8 (Mountain Lion) and 10.9 (Mavericks).
|
||||
|
||||
### Mac OS X 10.9 Mavericks
|
||||
|
||||
If you still have not installed [Xcode](http://developer.apple.com/xcode/), do it now from the App Store (it's free).
|
||||
If you still have not installed [Xcode](http://developer.apple.com/xcode/), do it now from the App Store (it's free). You will also need the Xcode Command Line Tools. Launch the Terminal, found in /Applications/Utilities/, and type:
|
||||
|
||||
~~~~~~
|
||||
$ xcode-select --install
|
||||
~~~~~~
|
||||
|
||||
Agree to Xcode license:
|
||||
|
||||
~~~~~~
|
||||
$ sudo xcodebuild -license
|
||||
~~~~~~
|
||||
|
||||
Then, [install Macports](http://www.macports.org/install.php). If you are upgrading from a previous installation, please follow the [migration rules](http://trac.macports.org/wiki/Migration).
|
||||
|
||||
@ -348,7 +348,7 @@ In a terminal, type:
|
||||
$ sudo port selfupdate
|
||||
$ sudo port upgrade outdated
|
||||
$ sudo port install doxygen +latex
|
||||
$ sudo port install uhd gnuradio
|
||||
$ sudo port install gnuradio
|
||||
$ sudo port install armadillo
|
||||
$ sudo port install google-glog +gflags
|
||||
~~~~~~
|
||||
@ -358,7 +358,7 @@ Finally, you are ready to clone the GNSS-SDR repository and build the software:
|
||||
~~~~~~
|
||||
$ git clone git://git.code.sf.net/p/gnss-sdr/cttc gnss-sdr
|
||||
$ cd gnss-sdr/build
|
||||
$ cmake ../ -DCMAKE_CXX_COMPILER=/usr/bin/clang++
|
||||
$ cmake -DCMAKE_CXX_COMPILER=/usr/bin/clang++ ../
|
||||
$ make
|
||||
$ make install
|
||||
~~~~~~
|
||||
@ -416,7 +416,7 @@ Then, you are ready to clone the GNSS-SDR repository and build the software:
|
||||
~~~~~~
|
||||
$ git clone git://git.code.sf.net/p/gnss-sdr/cttc gnss-sdr
|
||||
$ cd gnss-sdr/build
|
||||
$ cmake ../ -DCMAKE_CXX_COMPILER=g++
|
||||
$ cmake -DCMAKE_CXX_COMPILER=g++ ../
|
||||
$ make
|
||||
$ make install
|
||||
~~~~~~
|
||||
|
25
cmake/Modules/FindOpenBLAS.cmake
Normal file
25
cmake/Modules/FindOpenBLAS.cmake
Normal file
@ -0,0 +1,25 @@
|
||||
# - Try to find OpenBLAS library (not headers!)
|
||||
#
|
||||
# The following environment variable is optionally searched
|
||||
# OPENBLAS_HOME: Base directory where all OpenBlas components are found
|
||||
|
||||
SET(OPEN_BLAS_SEARCH_PATHS /lib/
|
||||
/lib64/
|
||||
/usr/lib
|
||||
/usr/lib64
|
||||
/usr/local/lib
|
||||
/usr/local/lib64
|
||||
/opt/OpenBLAS/lib
|
||||
/opt/local/lib
|
||||
/usr/lib/openblas-base
|
||||
$ENV{OPENBLAS_HOME}/lib
|
||||
)
|
||||
|
||||
FIND_LIBRARY(OPENBLAS NAMES openblas PATHS ${OPEN_BLAS_SEARCH_PATHS})
|
||||
|
||||
IF (OPENBLAS)
|
||||
SET(OPENBLAS_FOUND ON)
|
||||
MESSAGE(STATUS "Found OpenBLAS")
|
||||
ENDIF (OPENBLAS)
|
||||
|
||||
MARK_AS_ADVANCED(OPENBLAS)
|
@ -29,10 +29,10 @@ GNSS-SDR.SUPL_CI=0x31b0
|
||||
SignalSource.implementation=File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
SignalSource.filename=/media/DATALOGGER/Agilent GPS Generator/cap2/agilent_cap2.dat
|
||||
SignalSource.filename=../data/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
SignalSource.item_type=gr_complex
|
||||
SignalSource.item_type=short
|
||||
|
||||
;#sampling_frequency: Original Signal sampling frequency in [Hz]
|
||||
SignalSource.sampling_frequency=4000000
|
||||
@ -69,13 +69,13 @@ SignalSource.enable_throttle_control=false
|
||||
;#implementation: Use [Pass_Through] or [Signal_Conditioner]
|
||||
;#[Pass_Through] disables this block and the [DataTypeAdapter], [InputFilter] and [Resampler] blocks
|
||||
;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks
|
||||
;SignalConditioner.implementation=Signal_Conditioner
|
||||
SignalConditioner.implementation=Pass_Through
|
||||
SignalConditioner.implementation=Signal_Conditioner
|
||||
;SignalConditioner.implementation=Pass_Through
|
||||
|
||||
;######### DATA_TYPE_ADAPTER CONFIG ############
|
||||
;## Changes the type of input data. Please disable it in this version.
|
||||
;#implementation: [Pass_Through] disables this block
|
||||
DataTypeAdapter.implementation=Pass_Through
|
||||
DataTypeAdapter.implementation=Ishort_To_Complex
|
||||
|
||||
;######### INPUT_FILTER CONFIG ############
|
||||
;## Filter the input data. Can be combined with frequency translation for IF signals
|
||||
@ -176,175 +176,98 @@ Resampler.sample_freq_out=4000000
|
||||
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available satellite channels.
|
||||
Channels.count=6
|
||||
;#in_acquisition: Number of channels simultaneously acquiring
|
||||
;#count: Number of available GPS satellite channels.
|
||||
Channels_GPS.count=6
|
||||
;#count: Number of available Galileo satellite channels.
|
||||
Channels_Galileo.count=0
|
||||
;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
|
||||
Channels.in_acquisition=1
|
||||
;#system: GPS, GLONASS, Galileo, SBAS or Compass
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
Channel.system=GPS
|
||||
|
||||
;#signal:
|
||||
;# "1C" GPS L1 C/A
|
||||
;# "1P" GPS L1 P
|
||||
;# "1W" GPS L1 Z-tracking and similar (AS on)
|
||||
;# "1Y" GPS L1 Y
|
||||
;# "1M" GPS L1 M
|
||||
;# "1N" GPS L1 codeless
|
||||
;# "2C" GPS L2 C/A
|
||||
;# "2D" GPS L2 L1(C/A)+(P2-P1) semi-codeless
|
||||
;# "2S" GPS L2 L2C (M)
|
||||
;# "2L" GPS L2 L2C (L)
|
||||
;# "2X" GPS L2 L2C (M+L)
|
||||
;# "2P" GPS L2 P
|
||||
;# "2W" GPS L2 Z-tracking and similar (AS on)
|
||||
;# "2Y" GPS L2 Y
|
||||
;# "2M" GPS GPS L2 M
|
||||
;# "2N" GPS L2 codeless
|
||||
;# "5I" GPS L5 I
|
||||
;# "5Q" GPS L5 Q
|
||||
;# "5X" GPS L5 I+Q
|
||||
;# "1C" GLONASS G1 C/A
|
||||
;# "1P" GLONASS G1 P
|
||||
;# "2C" GLONASS G2 C/A (Glonass M)
|
||||
;# "2P" GLONASS G2 P
|
||||
;# "1A" GALILEO E1 A (PRS)
|
||||
;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL)
|
||||
;# "1C" GALILEO E1 C (no data)
|
||||
;# "1X" GALILEO E1 B+C
|
||||
;# "1Z" GALILEO E1 A+B+C
|
||||
;# "5I" GALILEO E5a I (F/NAV OS)
|
||||
;# "5Q" GALILEO E5a Q (no data)
|
||||
;# "5X" GALILEO E5a I+Q
|
||||
;# "7I" GALILEO E5b I
|
||||
;# "7Q" GALILEO E5b Q
|
||||
;# "7X" GALILEO E5b I+Q
|
||||
;# "8I" GALILEO E5 I
|
||||
;# "8Q" GALILEO E5 Q
|
||||
;# "8X" GALILEO E5 I+Q
|
||||
;# "6A" GALILEO E6 A
|
||||
;# "6B" GALILEO E6 B
|
||||
;# "6C" GALILEO E6 C
|
||||
;# "6X" GALILEO E6 B+C
|
||||
;# "6Z" GALILEO E6 A+B+C
|
||||
;# "1C" SBAS L1 C/A
|
||||
;# "5I" SBAS L5 I
|
||||
;# "5Q" SBAS L5 Q
|
||||
;# "5X" SBAS L5 I+Q
|
||||
;# "2I" COMPASS E2 I
|
||||
;# "2Q" COMPASS E2 Q
|
||||
;# "2X" COMPASS E2 IQ
|
||||
;# "7I" COMPASS E5b I
|
||||
;# "7Q" COMPASS E5b Q
|
||||
;# "7X" COMPASS E5b IQ
|
||||
;# "6I" COMPASS E6 I
|
||||
;# "6Q" COMPASS E6 Q
|
||||
;# "6X" COMPASS E6 IQ
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel.signal=1C
|
||||
|
||||
|
||||
;######### SPECIFIC CHANNELS CONFIG ######
|
||||
;#The following options are specific to each channel and overwrite the generic options
|
||||
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
|
||||
Channel0.system=GPS
|
||||
Channel0.signal=1C
|
||||
;Channel0.system=GPS
|
||||
;Channel0.signal=1C
|
||||
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
Channel0.satellite=11
|
||||
;Channel0.satellite=11
|
||||
|
||||
;######### CHANNEL 1 CONFIG ############
|
||||
|
||||
Channel1.system=GPS
|
||||
Channel1.signal=1C
|
||||
Channel1.satellite=18
|
||||
|
||||
;Channel1.system=GPS
|
||||
;Channel1.signal=1C
|
||||
;Channel1.satellite=18
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition.dump=false
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition_GPS.dump=false
|
||||
;#filename: Log path and filename
|
||||
Acquisition.dump_filename=./acq_dump.dat
|
||||
Acquisition_GPS.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition.if=0
|
||||
Acquisition_GPS.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition_GPS.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition.coherent_integration_time_ms=1
|
||||
Acquisition_GPS.sampled_ms=1
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
;#threshold: Acquisition threshold. It will be ignored if pfa is defined.
|
||||
Acquisition.threshold=0.005
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition.pfa=0.0001
|
||||
Acquisition_GPS.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler
|
||||
;#threshold: Acquisition threshold
|
||||
Acquisition_GPS.threshold=0.005
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
;Acquisition_GPS.pfa=0.0001
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition.doppler_max=10000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition.doppler_step=500
|
||||
;#bit_transition_flag: Enable or disable a strategy to deal with bit transitions in GPS signals: process two dwells and take
|
||||
maximum test statistics. Only use with implementation: [GPS_L1_CA_PCPS_Acquisition] (should not be used for Galileo_E1_PCPS_Ambiguous_Acquisition])
|
||||
Acquisition.bit_transition_flag=false
|
||||
;#max_dwells: Maximum number of consecutive dwells to be processed. It will be ignored if bit_transition_flag=true
|
||||
Acquisition.max_dwells=1
|
||||
|
||||
;######### ACQUISITION CHANNELS CONFIG ######
|
||||
;#The following options are specific to each channel and overwrite the generic options
|
||||
|
||||
;######### ACQUISITION CH 0 CONFIG ############
|
||||
;Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
;Acquisition0.threshold=0.005
|
||||
;Acquisition0.pfa=0.001
|
||||
;Acquisition0.doppler_max=10000
|
||||
;Acquisition0.doppler_step=250
|
||||
|
||||
;#repeat_satellite: Use only jointly with the satellite PRN ID option. The default value is false
|
||||
;Acquisition0.repeat_satellite = false
|
||||
|
||||
;######### ACQUISITION CH 1 CONFIG ############
|
||||
;Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
;Acquisition1.threshold=0.005
|
||||
;Acquisition1.pfa=0.001
|
||||
;Acquisition1.doppler_max=10000
|
||||
;Acquisition1.doppler_step=250
|
||||
;Acquisition1.repeat_satellite = false
|
||||
Acquisition_GPS.doppler_max=10000
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition_GPS.doppler_min=-10000
|
||||
;#doppler_step Doppler step in the grid search [Hz]
|
||||
Acquisition_GPS.doppler_step=500
|
||||
;#maximum dwells
|
||||
Acquisition_GPS.max_dwells=5
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking]
|
||||
Tracking.implementation=GPS_L1_CA_DLL_PLL_Optim_Tracking
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
|
||||
Tracking_GPS.implementation=GPS_L1_CA_DLL_PLL_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking.item_type=gr_complex
|
||||
Tracking_GPS.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking.if=0
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking_GPS.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking.dump=false
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking_GPS.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking.dump_filename=./tracking_ch_
|
||||
Tracking_GPS.dump_filename=../data/epl_tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking.pll_bw_hz=50.0;
|
||||
Tracking_GPS.pll_bw_hz=45.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking.dll_bw_hz=2.0;
|
||||
Tracking_GPS.dll_bw_hz=3.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking.fll_bw_hz=10.0;
|
||||
Tracking_GPS.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking.order=3;
|
||||
Tracking_GPS.order=3;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5]
|
||||
Tracking.early_late_space_chips=0.5;
|
||||
|
||||
;######### TELEMETRY DECODER CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A.
|
||||
TelemetryDecoder.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder.dump=false
|
||||
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A
|
||||
TelemetryDecoder_GPS.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder_GPS.dump=false
|
||||
;#decimation factor
|
||||
TelemetryDecoder_GPS.decimation_factor=1;
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
||||
@ -362,13 +285,13 @@ Observables.dump_filename=./observables.dat
|
||||
PVT.implementation=GPS_L1_CA_PVT
|
||||
|
||||
;#averaging_depth: Number of PVT observations in the moving average algorithm
|
||||
PVT.averaging_depth=10
|
||||
PVT.averaging_depth=100
|
||||
|
||||
;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]
|
||||
PVT.flag_averaging=true
|
||||
|
||||
;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms]
|
||||
PVT.output_rate_ms=100
|
||||
PVT.output_rate_ms=10
|
||||
|
||||
;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms.
|
||||
PVT.display_rate_ms=500
|
||||
@ -395,4 +318,4 @@ PVT.dump=false
|
||||
;# Receiver output filter: Leave this block disabled in this version
|
||||
OutputFilter.implementation=Null_Sink_Output_Filter
|
||||
OutputFilter.filename=data/gnss-sdr.dat
|
||||
OutputFilter.item_type=gr_complex
|
||||
OutputFilter.item_type=gr_complex
|
||||
|
@ -172,15 +172,15 @@ Resampler.sample_freq_out=2727933.33
|
||||
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available satellite channels.
|
||||
Channels.count=1
|
||||
;#in_acquisition: Number of channels simultaneously acquiring
|
||||
;#count: Number of available GPS satellite channels.
|
||||
Channels_GPS.count=4
|
||||
;#count: Number of available Galileo satellite channels.
|
||||
Channels_Galileo.count=0
|
||||
;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
|
||||
Channels.in_acquisition=1
|
||||
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
Channel0.system=GPS
|
||||
Channel.system=GPS
|
||||
|
||||
;#signal:
|
||||
;# "1C" GPS L1 C/A
|
||||
@ -283,123 +283,66 @@ Channel5.signal=1C
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition.dump=false
|
||||
Acquisition_GPS.dump=false
|
||||
;#filename: Log path and filename
|
||||
Acquisition.dump_filename=./acq_dump.dat
|
||||
Acquisition_GPS.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition.item_type=gr_complex
|
||||
Acquisition_GPS.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition.if=0
|
||||
Acquisition_GPS.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition.sampled_ms=1
|
||||
|
||||
;######### ACQUISITION CHANNELS CONFIG ######
|
||||
|
||||
;######### ACQUISITION CH 0 CONFIG ############
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition]
|
||||
Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition_GPS.sampled_ms=1
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition_GPS.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
;#threshold: Acquisition threshold
|
||||
Acquisition0.threshold=50
|
||||
Acquisition_GPS.threshold=0.008
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
;Acquisition_GPS.pfa=0.01
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition0.doppler_max=10000
|
||||
Acquisition_GPS.doppler_max=10000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition0.doppler_step=250
|
||||
;#repeat_satellite: Use only jointly with the satellte PRN ID option.
|
||||
|
||||
|
||||
;######### ACQUISITION CH 1 CONFIG ############
|
||||
Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition1.threshold=30
|
||||
Acquisition1.doppler_max=10000
|
||||
Acquisition1.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 2 CONFIG ############
|
||||
Acquisition2.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition2.threshold=30
|
||||
Acquisition2.doppler_max=10000
|
||||
Acquisition2.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 3 CONFIG ############
|
||||
Acquisition3.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition3.threshold=30
|
||||
Acquisition3.doppler_max=10000
|
||||
Acquisition3.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 4 CONFIG ############
|
||||
Acquisition4.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition4.threshold=70
|
||||
Acquisition4.doppler_max=10000
|
||||
Acquisition4.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 5 CONFIG ############
|
||||
Acquisition5.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition5.threshold=70
|
||||
Acquisition5.doppler_max=10000
|
||||
Acquisition5.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 6 CONFIG ############
|
||||
Acquisition6.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition6.threshold=70
|
||||
Acquisition6.doppler_max=10000
|
||||
Acquisition6.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 7 CONFIG ############
|
||||
Acquisition7.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition7.threshold=70
|
||||
Acquisition7.doppler_max=10000
|
||||
Acquisition7.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 8 CONFIG ############
|
||||
Acquisition8.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition8.threshold=70
|
||||
Acquisition8.doppler_max=10000
|
||||
Acquisition8.doppler_step=250
|
||||
|
||||
Acquisition_GPS.doppler_step=500
|
||||
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking]
|
||||
Tracking.implementation=GPS_L1_CA_DLL_PLL_Optim_Tracking
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] [GPS_L1_CA_DLL_PLL_Optim_Tracking]
|
||||
Tracking_GPS.implementation=GPS_L1_CA_DLL_PLL_Optim_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking.item_type=gr_complex
|
||||
Tracking_GPS.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking.if=0
|
||||
Tracking_GPS.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking.dump=false
|
||||
Tracking_GPS.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking.dump_filename=./tracking_ch_
|
||||
Tracking_GPS.dump_filename=./tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking.pll_bw_hz=50.0;
|
||||
Tracking_GPS.pll_bw_hz=40.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking.dll_bw_hz=4.0;
|
||||
Tracking_GPS.dll_bw_hz=2.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking.fll_bw_hz=10.0;
|
||||
Tracking_GPS.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking.order=3;
|
||||
Tracking_GPS.order=3;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5]
|
||||
Tracking.early_late_space_chips=0.5;
|
||||
Tracking_GPS.early_late_space_chips=0.5;
|
||||
|
||||
;######### TELEMETRY DECODER CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A.
|
||||
TelemetryDecoder.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder.dump=false
|
||||
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A
|
||||
TelemetryDecoder_GPS.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder_GPS.dump=false
|
||||
;#decimation factor
|
||||
TelemetryDecoder_GPS.decimation_factor=1;
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
@ -176,11 +176,13 @@ Resampler.sample_freq_out=2000000
|
||||
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available satellite channels.
|
||||
Channels.count=6
|
||||
;#in_acquisition: Number of channels simultaneously acquiring
|
||||
;#count: Number of available GPS satellite channels.
|
||||
Channels_GPS.count=6
|
||||
;#count: Number of available Galileo satellite channels.
|
||||
Channels_Galileo.count=0
|
||||
;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
|
||||
Channels.in_acquisition=1
|
||||
;#system: GPS, GLONASS, Galileo, SBAS or Compass
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
Channel.system=GPS
|
||||
|
||||
@ -264,30 +266,31 @@ Channel1.satellite=18
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition.dump=false
|
||||
Acquisition_GPS.dump=false
|
||||
;#filename: Log path and filename
|
||||
Acquisition.dump_filename=./acq_dump.dat
|
||||
Acquisition_GPS.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition.item_type=gr_complex
|
||||
Acquisition_GPS.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition.if=0
|
||||
Acquisition_GPS.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition.coherent_integration_time_ms=1
|
||||
Acquisition_GPS.coherent_integration_time_ms=1
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition_GPS.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
;#threshold: Acquisition threshold. It will be ignored if pfa is defined.
|
||||
Acquisition.threshold=0.01
|
||||
Acquisition_GPS.threshold=0.01
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
;Acquisition.pfa=0.0001
|
||||
;Acquisition_GPS.pfa=0.0001
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition.doppler_max=10000
|
||||
Acquisition_GPS.doppler_max=10000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition.doppler_step=500
|
||||
Acquisition_GPS.doppler_step=500
|
||||
;#bit_transition_flag: Enable or disable a strategy to deal with bit transitions in GPS signals: process two dwells and take
|
||||
maximum test statistics. Only use with implementation: [GPS_L1_CA_PCPS_Acquisition] (should not be used for Galileo_E1_PCPS_Ambiguous_Acquisition])
|
||||
Acquisition.bit_transition_flag=false
|
||||
Acquisition_GPS.bit_transition_flag=false
|
||||
;#max_dwells: Maximum number of consecutive dwells to be processed. It will be ignored if bit_transition_flag=true
|
||||
Acquisition.max_dwells=1
|
||||
Acquisition_GPS.max_dwells=1
|
||||
|
||||
|
||||
;######### ACQUISITION CHANNELS CONFIG ######
|
||||
;#The following options are specific to each channel and overwrite the generic options
|
||||
@ -296,38 +299,40 @@ Acquisition.max_dwells=1
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking]
|
||||
Tracking.implementation=GPS_L1_CA_DLL_PLL_Optim_Tracking
|
||||
Tracking_GPS.implementation=GPS_L1_CA_DLL_PLL_Optim_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking.item_type=gr_complex
|
||||
Tracking_GPS.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking.if=0
|
||||
Tracking_GPS.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking.dump=false
|
||||
Tracking_GPS.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking.dump_filename=./tracking_ch_
|
||||
Tracking_GPS.dump_filename=./tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking.pll_bw_hz=50.0;
|
||||
Tracking_GPS.pll_bw_hz=50.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking.dll_bw_hz=2.0;
|
||||
Tracking_GPS.dll_bw_hz=2.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking.fll_bw_hz=10.0;
|
||||
Tracking_GPS.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking.order=3;
|
||||
Tracking_GPS.order=3;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5]
|
||||
Tracking.early_late_space_chips=0.5;
|
||||
Tracking_GPS.early_late_space_chips=0.5;
|
||||
|
||||
;######### TELEMETRY DECODER CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A.
|
||||
TelemetryDecoder.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder.dump=false
|
||||
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A
|
||||
TelemetryDecoder_GPS.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder_GPS.dump=false
|
||||
;#decimation factor
|
||||
TelemetryDecoder_GPS.decimation_factor=1;
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
@ -13,14 +13,18 @@ GNSS-SDR.internal_fs_hz=4000000
|
||||
ControlThread.wait_for_flowgraph=false
|
||||
|
||||
;######### SIGNAL_SOURCE CONFIG ############
|
||||
;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental)
|
||||
;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] or [Rtlsdr_Signal_Source]
|
||||
SignalSource.implementation=File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
SignalSource.filename=/media/DATALOGGER/spirent scenario 1/data/sc1_d16.dat
|
||||
SignalSource.filename=../data/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
SignalSource.item_type=gr_complex
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples.
|
||||
;#Use gr_complex for 32 bits float I/Q or short for I/Q interleaved short integer.
|
||||
;#If short is selected you should have to instantiate the Ishort_To_Complex data_type_adapter.
|
||||
|
||||
SignalSource.item_type=short
|
||||
|
||||
;#sampling_frequency: Original Signal sampling frequency in [Hz]
|
||||
SignalSource.sampling_frequency=4000000
|
||||
@ -31,11 +35,15 @@ SignalSource.freq=1575420000
|
||||
;#gain: Front-end Gain in [dB]
|
||||
SignalSource.gain=60
|
||||
|
||||
;#AGC_enabled: RTLSDR AGC enabled [true or false]
|
||||
|
||||
SignalSource.AGC_enabled=true
|
||||
|
||||
;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0)
|
||||
SignalSource.subdevice=B:0
|
||||
|
||||
;#samples: Number of samples to be processed. Notice that 0 indicates the entire file.
|
||||
SignalSource.samples=250000000
|
||||
SignalSource.samples=0
|
||||
|
||||
;#repeat: Repeat the processing file. Disable this option in this version
|
||||
SignalSource.repeat=false
|
||||
@ -57,13 +65,16 @@ SignalSource.enable_throttle_control=false
|
||||
;#implementation: Use [Pass_Through] or [Signal_Conditioner]
|
||||
;#[Pass_Through] disables this block and the [DataTypeAdapter], [InputFilter] and [Resampler] blocks
|
||||
;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks
|
||||
;SignalConditioner.implementation=Signal_Conditioner
|
||||
SignalConditioner.implementation=Pass_Through
|
||||
SignalConditioner.implementation=Signal_Conditioner
|
||||
|
||||
;######### DATA_TYPE_ADAPTER CONFIG ############
|
||||
;## Changes the type of input data. Please disable it in this version.
|
||||
;#implementation: [Pass_Through] disables this block
|
||||
DataTypeAdapter.implementation=Pass_Through
|
||||
;#implementation: Use [Ishort_To_Complex] or [Pass_Through]
|
||||
DataTypeAdapter.implementation=Ishort_To_Complex
|
||||
;#dump: Dump the filtered data to a file.
|
||||
DataTypeAdapter.dump=false
|
||||
;#dump_filename: Log path and filename.
|
||||
DataTypeAdapter.dump_filename=../data/data_type_adapter.dat
|
||||
|
||||
;######### INPUT_FILTER CONFIG ############
|
||||
;## Filter the input data. Can be combined with frequency translation for IF signals
|
||||
@ -107,8 +118,9 @@ InputFilter.number_of_bands=2
|
||||
;#The number of band_begin and band_end elements must match the number of bands
|
||||
|
||||
InputFilter.band1_begin=0.0
|
||||
InputFilter.band1_end=0.45
|
||||
InputFilter.band2_begin=0.55
|
||||
;InputFilter.band1_end=0.8
|
||||
InputFilter.band1_end=0.85
|
||||
InputFilter.band2_begin=0.90
|
||||
InputFilter.band2_end=1.0
|
||||
|
||||
;#ampl: desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...].
|
||||
@ -157,7 +169,7 @@ Resampler.dump_filename=../data/resampler.dat
|
||||
Resampler.item_type=gr_complex
|
||||
|
||||
;#sample_freq_in: the sample frequency of the input signal
|
||||
Resampler.sample_freq_in=8000000
|
||||
Resampler.sample_freq_in=4000000
|
||||
|
||||
;#sample_freq_out: the desired sample frequency of the output signal
|
||||
Resampler.sample_freq_out=4000000
|
||||
@ -165,7 +177,8 @@ Resampler.sample_freq_out=4000000
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available satellite channels.
|
||||
Channels.count=5
|
||||
Channels_GPS.count=5
|
||||
Channels_Galileo.count=0
|
||||
;#in_acquisition: Number of channels simultaneously acquiring
|
||||
Channels.in_acquisition=1
|
||||
|
||||
@ -231,167 +244,106 @@ Channel0.system=GPS
|
||||
;# "6Q" COMPASS E6 Q
|
||||
;# "6X" COMPASS E6 IQ
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel0.signal=1C
|
||||
|
||||
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
Channel0.satellite=15
|
||||
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
Channel0.system=GPS
|
||||
Channel0.signal=1C
|
||||
Channel0.satellite=1
|
||||
Channel0.repeat_satellite=false
|
||||
|
||||
;######### CHANNEL 1 CONFIG ############
|
||||
|
||||
Channel1.system=GPS
|
||||
Channel1.signal=1C
|
||||
Channel1.satellite=18
|
||||
Channel1.satellite=11
|
||||
Channel1.repeat_satellite=false
|
||||
|
||||
;######### CHANNEL 2 CONFIG ############
|
||||
|
||||
Channel2.system=GPS
|
||||
Channel2.signal=1C
|
||||
Channel2.satellite=16
|
||||
Channel2.satellite=17
|
||||
Channel2.repeat_satellite=false
|
||||
|
||||
;######### CHANNEL 3 CONFIG ############
|
||||
|
||||
Channel3.system=GPS
|
||||
Channel3.signal=1C
|
||||
Channel3.satellite=21
|
||||
Channel3.satellite=20
|
||||
Channel3.repeat_satellite=false
|
||||
|
||||
;######### CHANNEL 4 CONFIG ############
|
||||
|
||||
Channel4.system=GPS
|
||||
Channel4.signal=1C
|
||||
Channel4.satellite=3
|
||||
Channel4.satellite=32
|
||||
Channel4.repeat_satellite=false
|
||||
|
||||
;######### CHANNEL 5 CONFIG ############
|
||||
|
||||
Channel5.system=GPS
|
||||
Channel5.signal=1C
|
||||
;Channel5.satellite=21
|
||||
;Channel5.repeat_satellite=false
|
||||
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition.dump=false
|
||||
Acquisition_GPS.dump=true
|
||||
;#filename: Log path and filename
|
||||
Acquisition.dump_filename=./acq_dump.dat
|
||||
;Acquisition_GPS.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition.item_type=gr_complex
|
||||
Acquisition_GPS.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition.if=0
|
||||
Acquisition_GPS.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition.sampled_ms=1
|
||||
Acquisition_GPS.coherent-integration_time_ms=4
|
||||
|
||||
Acquisition_GPS.implementation=GPS_L1_CA_PCPS_QuickSync_Acquisition
|
||||
|
||||
;######### ACQUISITION CHANNELS CONFIG ######
|
||||
|
||||
;######### ACQUISITION CH 0 CONFIG ############
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition]
|
||||
Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition.implementation=GPS_L1_CA_PCPS_QuickSync_Acquisition
|
||||
;#threshold: Acquisition threshold
|
||||
Acquisition0.threshold=70
|
||||
Acquisition_GPS.threshold=0.4
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition0.doppler_max=10000
|
||||
Acquisition_GPS.doppler_max=10000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition0.doppler_step=250
|
||||
Acquisition_GPS.doppler_step=250
|
||||
;#repeat_satellite: Use only jointly with the satellte PRN ID option.
|
||||
|
||||
|
||||
;######### ACQUISITION CH 1 CONFIG ############
|
||||
Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition1.threshold=70
|
||||
Acquisition1.doppler_max=10000
|
||||
Acquisition1.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 2 CONFIG ############
|
||||
Acquisition2.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition2.threshold=70
|
||||
Acquisition2.doppler_max=10000
|
||||
Acquisition2.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 3 CONFIG ############
|
||||
Acquisition3.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition3.threshold=70
|
||||
Acquisition3.doppler_max=10000
|
||||
Acquisition3.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 4 CONFIG ############
|
||||
Acquisition4.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition4.threshold=70
|
||||
Acquisition4.doppler_max=10000
|
||||
Acquisition4.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 5 CONFIG ############
|
||||
Acquisition5.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition5.threshold=50
|
||||
Acquisition5.doppler_max=10000
|
||||
Acquisition5.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 6 CONFIG ############
|
||||
Acquisition6.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition6.threshold=70
|
||||
Acquisition6.doppler_max=10000
|
||||
Acquisition6.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 7 CONFIG ############
|
||||
Acquisition7.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition7.threshold=70
|
||||
Acquisition7.doppler_max=10000
|
||||
Acquisition7.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 8 CONFIG ############
|
||||
Acquisition8.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition8.threshold=70
|
||||
Acquisition8.doppler_max=10000
|
||||
Acquisition8.doppler_step=250
|
||||
|
||||
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking]
|
||||
Tracking.implementation=GPS_L1_CA_DLL_PLL_Optim_Tracking
|
||||
Tracking_GPS.implementation=GPS_L1_CA_DLL_PLL_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking.item_type=gr_complex
|
||||
Tracking_GPS.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking.if=0
|
||||
Tracking_GPS.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking.dump=false
|
||||
Tracking_GPS.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking.dump_filename=./tracking_ch_
|
||||
Tracking_GPS.dump_filename=./tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking.pll_bw_hz=50.0;
|
||||
Tracking_GPS.pll_bw_hz=50.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking.dll_bw_hz=2.0;
|
||||
Tracking_GPS.dll_bw_hz=4.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking.fll_bw_hz=10.0;
|
||||
Tracking_GPS.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking.order=3;
|
||||
Tracking_GPS.order=3;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5]
|
||||
Tracking.early_late_space_chips=0.5;
|
||||
Tracking_GPS.early_late_space_chips=0.5;
|
||||
|
||||
;######### TELEMETRY DECODER CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A.
|
||||
TelemetryDecoder.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder.dump=false
|
||||
TelemetryDecoder_GPS.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder_GPS.dump=false
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
305
conf/gnss-sdr_GPS_L1_gr_complex.conf
Normal file
305
conf/gnss-sdr_GPS_L1_gr_complex.conf
Normal file
@ -0,0 +1,305 @@
|
||||
; Default configuration file
|
||||
; You can define your own receiver and invoke it by doing
|
||||
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
|
||||
;
|
||||
|
||||
[GNSS-SDR]
|
||||
|
||||
;######### GLOBAL OPTIONS ##################
|
||||
;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz].
|
||||
GNSS-SDR.internal_fs_hz=4000000
|
||||
|
||||
;######### CONTROL_THREAD CONFIG ############
|
||||
ControlThread.wait_for_flowgraph=false
|
||||
|
||||
;######### SIGNAL_SOURCE CONFIG ############
|
||||
;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental)
|
||||
SignalSource.implementation=File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
SignalSource.filename=../data/agilent_cap2.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
SignalSource.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Original Signal sampling frequency in [Hz]
|
||||
SignalSource.sampling_frequency=4000000
|
||||
|
||||
;#freq: RF front-end center frequency in [Hz]
|
||||
SignalSource.freq=1575420000
|
||||
|
||||
;#gain: Front-end Gain in [dB]
|
||||
SignalSource.gain=60
|
||||
|
||||
;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0)
|
||||
SignalSource.subdevice=B:0
|
||||
|
||||
;#samples: Number of samples to be processed. Notice that 0 indicates the entire file.
|
||||
SignalSource.samples=250000000
|
||||
|
||||
;#repeat: Repeat the processing file. Disable this option in this version
|
||||
SignalSource.repeat=false
|
||||
|
||||
;#dump: Dump the Signal source data to a file. Disable this option in this version
|
||||
SignalSource.dump=false
|
||||
|
||||
SignalSource.dump_filename=../data/signal_source.dat
|
||||
|
||||
|
||||
;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing.
|
||||
; it helps to not overload the CPU, but the processing time will be longer.
|
||||
SignalSource.enable_throttle_control=false
|
||||
|
||||
|
||||
;######### SIGNAL_CONDITIONER CONFIG ############
|
||||
;## It holds blocks to change data type, filter and resample input data.
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Signal_Conditioner]
|
||||
;#[Pass_Through] disables this block and the [DataTypeAdapter], [InputFilter] and [Resampler] blocks
|
||||
;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks
|
||||
;SignalConditioner.implementation=Signal_Conditioner
|
||||
SignalConditioner.implementation=Pass_Through
|
||||
|
||||
;######### DATA_TYPE_ADAPTER CONFIG ############
|
||||
;## Changes the type of input data. Please disable it in this version.
|
||||
;#implementation: [Pass_Through] disables this block
|
||||
DataTypeAdapter.implementation=Pass_Through
|
||||
|
||||
;######### INPUT_FILTER CONFIG ############
|
||||
;## Filter the input data. Can be combined with frequency translation for IF signals
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Fir_Filter] or [Freq_Xlating_Fir_Filter]
|
||||
;#[Pass_Through] disables this block
|
||||
;#[Fir_Filter] enables a FIR Filter
|
||||
;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation that shifts IF down to zero Hz.
|
||||
|
||||
;InputFilter.implementation=Fir_Filter
|
||||
;InputFilter.implementation=Freq_Xlating_Fir_Filter
|
||||
InputFilter.implementation=Pass_Through
|
||||
|
||||
;#dump: Dump the filtered data to a file.
|
||||
InputFilter.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename.
|
||||
InputFilter.dump_filename=../data/input_filter.dat
|
||||
|
||||
;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation.
|
||||
;#These options are based on parameters of gnuradio's function: gr_remez.
|
||||
;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands.
|
||||
|
||||
;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version.
|
||||
InputFilter.input_item_type=gr_complex
|
||||
|
||||
;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version.
|
||||
InputFilter.output_item_type=gr_complex
|
||||
|
||||
;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version.
|
||||
InputFilter.taps_item_type=float
|
||||
|
||||
;#number_of_taps: Number of taps in the filter. Increasing this parameter increases the processing time
|
||||
InputFilter.number_of_taps=5
|
||||
|
||||
;#number_of _bands: Number of frequency bands in the filter.
|
||||
InputFilter.number_of_bands=2
|
||||
|
||||
;#bands: frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...].
|
||||
;#Frequency is in the range [0, 1], with 1 being the Nyquist frequency (Fs/2)
|
||||
;#The number of band_begin and band_end elements must match the number of bands
|
||||
|
||||
InputFilter.band1_begin=0.0
|
||||
InputFilter.band1_end=0.45
|
||||
InputFilter.band2_begin=0.55
|
||||
InputFilter.band2_end=1.0
|
||||
|
||||
;#ampl: desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...].
|
||||
;#The number of ampl_begin and ampl_end elements must match the number of bands
|
||||
|
||||
InputFilter.ampl1_begin=1.0
|
||||
InputFilter.ampl1_end=1.0
|
||||
InputFilter.ampl2_begin=0.0
|
||||
InputFilter.ampl2_end=0.0
|
||||
|
||||
;#band_error: weighting applied to each band (usually 1).
|
||||
;#The number of band_error elements must match the number of bands
|
||||
InputFilter.band1_error=1.0
|
||||
InputFilter.band2_error=1.0
|
||||
|
||||
;#filter_type: one of "bandpass", "hilbert" or "differentiator"
|
||||
InputFilter.filter_type=bandpass
|
||||
|
||||
;#grid_density: determines how accurately the filter will be constructed.
|
||||
;The minimum value is 16; higher values are slower to compute the filter.
|
||||
InputFilter.grid_density=16
|
||||
|
||||
;#The following options are used only in Freq_Xlating_Fir_Filter implementation.
|
||||
;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz
|
||||
|
||||
InputFilter.sampling_frequency=4000000
|
||||
InputFilter.IF=0
|
||||
|
||||
|
||||
|
||||
;######### RESAMPLER CONFIG ############
|
||||
;## Resamples the input data.
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Direct_Resampler]
|
||||
;#[Pass_Through] disables this block
|
||||
;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation
|
||||
;Resampler.implementation=Direct_Resampler
|
||||
Resampler.implementation=Pass_Through
|
||||
|
||||
;#dump: Dump the resamplered data to a file.
|
||||
Resampler.dump=false
|
||||
;#dump_filename: Log path and filename.
|
||||
Resampler.dump_filename=../data/resampler.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Resampler.item_type=gr_complex
|
||||
|
||||
;#sample_freq_in: the sample frequency of the input signal
|
||||
Resampler.sample_freq_in=8000000
|
||||
|
||||
;#sample_freq_out: the desired sample frequency of the output signal
|
||||
Resampler.sample_freq_out=4000000
|
||||
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available GPS satellite channels.
|
||||
Channels_GPS.count=8
|
||||
;#count: Number of available Galileo satellite channels.
|
||||
Channels_Galileo.count=0
|
||||
;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
|
||||
Channels.in_acquisition=1
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
Channel.system=GPS
|
||||
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel.signal=1C
|
||||
|
||||
|
||||
;######### SPECIFIC CHANNELS CONFIG ######
|
||||
;#The following options are specific to each channel and overwrite the generic options
|
||||
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
|
||||
;Channel0.system=GPS
|
||||
;Channel0.signal=1C
|
||||
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
;Channel0.satellite=11
|
||||
|
||||
;######### CHANNEL 1 CONFIG ############
|
||||
|
||||
;Channel1.system=GPS
|
||||
;Channel1.signal=1C
|
||||
;Channel1.satellite=18
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition_GPS.dump=false
|
||||
;#filename: Log path and filename
|
||||
Acquisition_GPS.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition_GPS.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition_GPS.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition_GPS.sampled_ms=1
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition_GPS.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
;#threshold: Acquisition threshold
|
||||
Acquisition_GPS.threshold=0.008
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
;Acquisition_GPS.pfa=0.01
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition_GPS.doppler_max=10000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition_GPS.doppler_step=500
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
|
||||
Tracking_GPS.implementation=GPS_L1_CA_DLL_PLL_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking_GPS.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking_GPS.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking_GPS.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking_GPS.dump_filename=../data/epl_tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking_GPS.pll_bw_hz=45.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking_GPS.dll_bw_hz=2.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking_GPS.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking_GPS.order=3;
|
||||
|
||||
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A
|
||||
TelemetryDecoder_GPS.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder_GPS.dump=false
|
||||
;#decimation factor
|
||||
TelemetryDecoder_GPS.decimation_factor=1;
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
||||
Observables.implementation=GPS_L1_CA_Observables
|
||||
|
||||
;#dump: Enable or disable the Observables internal binary data file logging [true] or [false]
|
||||
Observables.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename.
|
||||
Observables.dump_filename=./observables.dat
|
||||
|
||||
|
||||
;######### PVT CONFIG ############
|
||||
;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version.
|
||||
PVT.implementation=GPS_L1_CA_PVT
|
||||
|
||||
;#averaging_depth: Number of PVT observations in the moving average algorithm
|
||||
PVT.averaging_depth=100
|
||||
|
||||
;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]
|
||||
PVT.flag_averaging=false
|
||||
|
||||
;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms]
|
||||
PVT.output_rate_ms=10
|
||||
|
||||
;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms.
|
||||
PVT.display_rate_ms=500
|
||||
|
||||
;# RINEX, KML, and NMEA output configuration
|
||||
|
||||
;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump.
|
||||
PVT.dump_filename=./PVT
|
||||
|
||||
;#nmea_dump_filename: NMEA log path and filename
|
||||
PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea;
|
||||
|
||||
;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one)
|
||||
PVT.flag_nmea_tty_port=true;
|
||||
|
||||
;#nmea_dump_devname: serial device descriptor for NMEA logging
|
||||
PVT.nmea_dump_devname=/dev/pts/4
|
||||
|
||||
|
||||
;#dump: Enable or disable the PVT internal binary data file logging [true] or [false]
|
||||
PVT.dump=false
|
||||
|
||||
;######### OUTPUT_FILTER CONFIG ############
|
||||
;# Receiver output filter: Leave this block disabled in this version
|
||||
OutputFilter.implementation=Null_Sink_Output_Filter
|
||||
OutputFilter.filename=data/gnss-sdr.dat
|
||||
OutputFilter.item_type=gr_complex
|
335
conf/gnss-sdr_GPS_L1_gr_complex_optim_trk.conf
Normal file
335
conf/gnss-sdr_GPS_L1_gr_complex_optim_trk.conf
Normal file
@ -0,0 +1,335 @@
|
||||
; Default configuration file
|
||||
; You can define your own receiver and invoke it by doing
|
||||
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
|
||||
;
|
||||
|
||||
[GNSS-SDR]
|
||||
|
||||
;######### GLOBAL OPTIONS ##################
|
||||
;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz].
|
||||
GNSS-SDR.internal_fs_hz=4000000
|
||||
|
||||
;######### CONTROL_THREAD CONFIG ############
|
||||
ControlThread.wait_for_flowgraph=false
|
||||
|
||||
;######### SIGNAL_SOURCE CONFIG ############
|
||||
;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental)
|
||||
SignalSource.implementation=File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
SignalSource.filename=../data/agilent_cap2.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
SignalSource.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Original Signal sampling frequency in [Hz]
|
||||
SignalSource.sampling_frequency=4000000
|
||||
|
||||
;#freq: RF front-end center frequency in [Hz]
|
||||
SignalSource.freq=1575420000
|
||||
|
||||
;#gain: Front-end Gain in [dB]
|
||||
SignalSource.gain=60
|
||||
|
||||
;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0)
|
||||
SignalSource.subdevice=B:0
|
||||
|
||||
;#samples: Number of samples to be processed. Notice that 0 indicates the entire file.
|
||||
SignalSource.samples=250000000
|
||||
|
||||
;#repeat: Repeat the processing file. Disable this option in this version
|
||||
SignalSource.repeat=false
|
||||
|
||||
;#dump: Dump the Signal source data to a file. Disable this option in this version
|
||||
SignalSource.dump=false
|
||||
|
||||
SignalSource.dump_filename=../data/signal_source.dat
|
||||
|
||||
|
||||
;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing.
|
||||
; it helps to not overload the CPU, but the processing time will be longer.
|
||||
SignalSource.enable_throttle_control=false
|
||||
|
||||
|
||||
;######### SIGNAL_CONDITIONER CONFIG ############
|
||||
;## It holds blocks to change data type, filter and resample input data.
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Signal_Conditioner]
|
||||
;#[Pass_Through] disables this block and the [DataTypeAdapter], [InputFilter] and [Resampler] blocks
|
||||
;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks
|
||||
;SignalConditioner.implementation=Signal_Conditioner
|
||||
SignalConditioner.implementation=Pass_Through
|
||||
|
||||
;######### DATA_TYPE_ADAPTER CONFIG ############
|
||||
;## Changes the type of input data. Please disable it in this version.
|
||||
;#implementation: [Pass_Through] disables this block
|
||||
DataTypeAdapter.implementation=Pass_Through
|
||||
|
||||
;######### INPUT_FILTER CONFIG ############
|
||||
;## Filter the input data. Can be combined with frequency translation for IF signals
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Fir_Filter] or [Freq_Xlating_Fir_Filter]
|
||||
;#[Pass_Through] disables this block
|
||||
;#[Fir_Filter] enables a FIR Filter
|
||||
;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation that shifts IF down to zero Hz.
|
||||
|
||||
;InputFilter.implementation=Fir_Filter
|
||||
;InputFilter.implementation=Freq_Xlating_Fir_Filter
|
||||
InputFilter.implementation=Pass_Through
|
||||
|
||||
;#dump: Dump the filtered data to a file.
|
||||
InputFilter.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename.
|
||||
InputFilter.dump_filename=../data/input_filter.dat
|
||||
|
||||
;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation.
|
||||
;#These options are based on parameters of gnuradio's function: gr_remez.
|
||||
;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands.
|
||||
|
||||
;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version.
|
||||
InputFilter.input_item_type=gr_complex
|
||||
|
||||
;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version.
|
||||
InputFilter.output_item_type=gr_complex
|
||||
|
||||
;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version.
|
||||
InputFilter.taps_item_type=float
|
||||
|
||||
;#number_of_taps: Number of taps in the filter. Increasing this parameter increases the processing time
|
||||
InputFilter.number_of_taps=5
|
||||
|
||||
;#number_of _bands: Number of frequency bands in the filter.
|
||||
InputFilter.number_of_bands=2
|
||||
|
||||
;#bands: frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...].
|
||||
;#Frequency is in the range [0, 1], with 1 being the Nyquist frequency (Fs/2)
|
||||
;#The number of band_begin and band_end elements must match the number of bands
|
||||
|
||||
InputFilter.band1_begin=0.0
|
||||
InputFilter.band1_end=0.45
|
||||
InputFilter.band2_begin=0.55
|
||||
InputFilter.band2_end=1.0
|
||||
|
||||
;#ampl: desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...].
|
||||
;#The number of ampl_begin and ampl_end elements must match the number of bands
|
||||
|
||||
InputFilter.ampl1_begin=1.0
|
||||
InputFilter.ampl1_end=1.0
|
||||
InputFilter.ampl2_begin=0.0
|
||||
InputFilter.ampl2_end=0.0
|
||||
|
||||
;#band_error: weighting applied to each band (usually 1).
|
||||
;#The number of band_error elements must match the number of bands
|
||||
InputFilter.band1_error=1.0
|
||||
InputFilter.band2_error=1.0
|
||||
|
||||
;#filter_type: one of "bandpass", "hilbert" or "differentiator"
|
||||
InputFilter.filter_type=bandpass
|
||||
|
||||
;#grid_density: determines how accurately the filter will be constructed.
|
||||
;The minimum value is 16; higher values are slower to compute the filter.
|
||||
InputFilter.grid_density=16
|
||||
|
||||
;#The following options are used only in Freq_Xlating_Fir_Filter implementation.
|
||||
;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz
|
||||
|
||||
InputFilter.sampling_frequency=4000000
|
||||
InputFilter.IF=0
|
||||
|
||||
|
||||
|
||||
;######### RESAMPLER CONFIG ############
|
||||
;## Resamples the input data.
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Direct_Resampler]
|
||||
;#[Pass_Through] disables this block
|
||||
;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation
|
||||
;Resampler.implementation=Direct_Resampler
|
||||
Resampler.implementation=Pass_Through
|
||||
|
||||
;#dump: Dump the resamplered data to a file.
|
||||
Resampler.dump=false
|
||||
;#dump_filename: Log path and filename.
|
||||
Resampler.dump_filename=../data/resampler.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Resampler.item_type=gr_complex
|
||||
|
||||
;#sample_freq_in: the sample frequency of the input signal
|
||||
Resampler.sample_freq_in=8000000
|
||||
|
||||
;#sample_freq_out: the desired sample frequency of the output signal
|
||||
Resampler.sample_freq_out=4000000
|
||||
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available GPS satellite channels.
|
||||
Channels_GPS.count=8
|
||||
;#count: Number of available Galileo satellite channels.
|
||||
Channels_Galileo.count=0
|
||||
;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
|
||||
Channels.in_acquisition=1
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
Channel.system=GPS
|
||||
|
||||
;#signal:
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel.signal=1C
|
||||
Channel0.signal=1C
|
||||
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
Channel0.satellite=15
|
||||
Channel0.repeat_satellite=false
|
||||
|
||||
;######### CHANNEL 1 CONFIG ############
|
||||
|
||||
Channel1.system=GPS
|
||||
Channel1.signal=1C
|
||||
Channel1.satellite=18
|
||||
Channel1.repeat_satellite=false
|
||||
|
||||
;######### CHANNEL 2 CONFIG ############
|
||||
|
||||
Channel2.system=GPS
|
||||
Channel2.signal=1C
|
||||
Channel2.satellite=16
|
||||
Channel2.repeat_satellite=false
|
||||
|
||||
;######### CHANNEL 3 CONFIG ############
|
||||
|
||||
Channel3.system=GPS
|
||||
Channel3.signal=1C
|
||||
Channel3.satellite=21
|
||||
Channel3.repeat_satellite=false
|
||||
|
||||
;######### CHANNEL 4 CONFIG ############
|
||||
|
||||
Channel4.system=GPS
|
||||
Channel4.signal=1C
|
||||
Channel4.satellite=3
|
||||
Channel4.repeat_satellite=false
|
||||
|
||||
;######### CHANNEL 5 CONFIG ############
|
||||
|
||||
Channel5.system=GPS
|
||||
Channel5.signal=1C
|
||||
;Channel5.satellite=21
|
||||
;Channel5.repeat_satellite=false
|
||||
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition_GPS.dump=false
|
||||
;#filename: Log path and filename
|
||||
Acquisition_GPS.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition_GPS.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition_GPS.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition_GPS.sampled_ms=1
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition_GPS.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
;#threshold: Acquisition threshold
|
||||
Acquisition_GPS.threshold=0.008
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
;Acquisition_GPS.pfa=0.01
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition_GPS.doppler_max=10000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition_GPS.doppler_step=500
|
||||
|
||||
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking]
|
||||
Tracking_GPS.implementation=GPS_L1_CA_DLL_PLL_Optim_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking_GPS.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking_GPS.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking_GPS.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking_GPS.dump_filename=./tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking_GPS.pll_bw_hz=50.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking_GPS.dll_bw_hz=2.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking_GPS.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking_GPS.order=3;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5]
|
||||
Tracking_GPS.early_late_space_chips=0.5;
|
||||
|
||||
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A
|
||||
TelemetryDecoder_GPS.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder_GPS.dump=false
|
||||
;#decimation factor
|
||||
TelemetryDecoder_GPS.decimation_factor=1;
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
||||
Observables.implementation=GPS_L1_CA_Observables
|
||||
|
||||
;#dump: Enable or disable the Observables internal binary data file logging [true] or [false]
|
||||
Observables.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename.
|
||||
Observables.dump_filename=./observables.dat
|
||||
|
||||
|
||||
;######### PVT CONFIG ############
|
||||
;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version.
|
||||
PVT.implementation=GPS_L1_CA_PVT
|
||||
|
||||
;#averaging_depth: Number of PVT observations in the moving average algorithm
|
||||
PVT.averaging_depth=100
|
||||
|
||||
;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]
|
||||
PVT.flag_averaging=false
|
||||
|
||||
;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms]
|
||||
PVT.output_rate_ms=10
|
||||
|
||||
;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms.
|
||||
PVT.display_rate_ms=500
|
||||
|
||||
;# RINEX, KML, and NMEA output configuration
|
||||
|
||||
;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump.
|
||||
PVT.dump_filename=./PVT
|
||||
|
||||
;#nmea_dump_filename: NMEA log path and filename
|
||||
PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea;
|
||||
|
||||
;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one)
|
||||
PVT.flag_nmea_tty_port=false;
|
||||
|
||||
;#nmea_dump_devname: serial device descriptor for NMEA logging
|
||||
PVT.nmea_dump_devname=/dev/pts/4
|
||||
|
||||
|
||||
;#dump: Enable or disable the PVT internal binary data file logging [true] or [false]
|
||||
PVT.dump=true
|
||||
|
||||
;######### OUTPUT_FILTER CONFIG ############
|
||||
;# Receiver output filter: Leave this block disabled in this version
|
||||
OutputFilter.implementation=Null_Sink_Output_Filter
|
||||
OutputFilter.filename=data/gnss-sdr.dat
|
||||
OutputFilter.item_type=gr_complex
|
@ -31,7 +31,7 @@ GNSS-SDR.SUPL_CI=0x31b0
|
||||
SignalSource.implementation=Nsr_File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
SignalSource.filename=/media/DATALOGGER/ION GNSS 2013/E1L1_FE0_Band0.stream
|
||||
SignalSource.filename=../data/E1L1_FE0_Band0.stream
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
SignalSource.item_type=byte
|
||||
@ -178,167 +178,82 @@ Resampler.sample_freq_out=2048000
|
||||
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available satellite channels.
|
||||
Channels.count=8
|
||||
;#in_acquisition: Number of channels simultaneously acquiring
|
||||
;#count: Number of available GPS satellite channels.
|
||||
Channels_GPS.count=8
|
||||
;#count: Number of available Galileo satellite channels.
|
||||
Channels_Galileo.count=0
|
||||
;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
|
||||
Channels.in_acquisition=1
|
||||
;#system: GPS, GLONASS, Galileo, SBAS or Compass
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
Channel.system=GPS
|
||||
|
||||
;#signal:
|
||||
;# "1C" GPS L1 C/A
|
||||
;# "1P" GPS L1 P
|
||||
;# "1W" GPS L1 Z-tracking and similar (AS on)
|
||||
;# "1Y" GPS L1 Y
|
||||
;# "1M" GPS L1 M
|
||||
;# "1N" GPS L1 codeless
|
||||
;# "2C" GPS L2 C/A
|
||||
;# "2D" GPS L2 L1(C/A)+(P2-P1) semi-codeless
|
||||
;# "2S" GPS L2 L2C (M)
|
||||
;# "2L" GPS L2 L2C (L)
|
||||
;# "2X" GPS L2 L2C (M+L)
|
||||
;# "2P" GPS L2 P
|
||||
;# "2W" GPS L2 Z-tracking and similar (AS on)
|
||||
;# "2Y" GPS L2 Y
|
||||
;# "2M" GPS GPS L2 M
|
||||
;# "2N" GPS L2 codeless
|
||||
;# "5I" GPS L5 I
|
||||
;# "5Q" GPS L5 Q
|
||||
;# "5X" GPS L5 I+Q
|
||||
;# "1C" GLONASS G1 C/A
|
||||
;# "1P" GLONASS G1 P
|
||||
;# "2C" GLONASS G2 C/A (Glonass M)
|
||||
;# "2P" GLONASS G2 P
|
||||
;# "1A" GALILEO E1 A (PRS)
|
||||
;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL)
|
||||
;# "1C" GALILEO E1 C (no data)
|
||||
;# "1X" GALILEO E1 B+C
|
||||
;# "1Z" GALILEO E1 A+B+C
|
||||
;# "5I" GALILEO E5a I (F/NAV OS)
|
||||
;# "5Q" GALILEO E5a Q (no data)
|
||||
;# "5X" GALILEO E5a I+Q
|
||||
;# "7I" GALILEO E5b I
|
||||
;# "7Q" GALILEO E5b Q
|
||||
;# "7X" GALILEO E5b I+Q
|
||||
;# "8I" GALILEO E5 I
|
||||
;# "8Q" GALILEO E5 Q
|
||||
;# "8X" GALILEO E5 I+Q
|
||||
;# "6A" GALILEO E6 A
|
||||
;# "6B" GALILEO E6 B
|
||||
;# "6C" GALILEO E6 C
|
||||
;# "6X" GALILEO E6 B+C
|
||||
;# "6Z" GALILEO E6 A+B+C
|
||||
;# "1C" SBAS L1 C/A
|
||||
;# "5I" SBAS L5 I
|
||||
;# "5Q" SBAS L5 Q
|
||||
;# "5X" SBAS L5 I+Q
|
||||
;# "2I" COMPASS E2 I
|
||||
;# "2Q" COMPASS E2 Q
|
||||
;# "2X" COMPASS E2 IQ
|
||||
;# "7I" COMPASS E5b I
|
||||
;# "7Q" COMPASS E5b Q
|
||||
;# "7X" COMPASS E5b IQ
|
||||
;# "6I" COMPASS E6 I
|
||||
;# "6Q" COMPASS E6 Q
|
||||
;# "6X" COMPASS E6 IQ
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel.signal=1C
|
||||
|
||||
;######### SPECIFIC CHANNELS CONFIG ######
|
||||
;#The following options are specific to each channel and overwrite the generic options
|
||||
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
|
||||
Channel0.system=GPS
|
||||
Channel0.signal=1C
|
||||
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
Channel0.satellite=11
|
||||
|
||||
;######### CHANNEL 1 CONFIG ############
|
||||
|
||||
Channel1.system=GPS
|
||||
Channel1.signal=1C
|
||||
Channel1.satellite=18
|
||||
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
;######### GPS ACQUISITION CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition.dump=false
|
||||
Acquisition_GPS.dump=false
|
||||
;#filename: Log path and filename
|
||||
Acquisition.dump_filename=./acq_dump.dat
|
||||
Acquisition_GPS.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition.item_type=gr_complex
|
||||
Acquisition_GPS.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition.if=0
|
||||
Acquisition_GPS.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition.sampled_ms=1
|
||||
Acquisition_GPS.sampled_ms=1
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler
|
||||
Acquisition_GPS.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
;#threshold: Acquisition threshold
|
||||
Acquisition.threshold=0.010
|
||||
Acquisition_GPS.threshold=0.0075
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
;Acquisition.pfa=0.0001
|
||||
;Acquisition_GPS.pfa=0.01
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition.doppler_max=10000
|
||||
Acquisition.doppler_min=-10000
|
||||
Acquisition_GPS.doppler_max=10000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition.doppler_step=500
|
||||
;#maximum dwells
|
||||
Acquisition.max_dwells=15
|
||||
Acquisition_GPS.doppler_step=500
|
||||
|
||||
;######### ACQUISITION CHANNELS CONFIG ######
|
||||
;#The following options are specific to each channel and overwrite the generic options
|
||||
|
||||
|
||||
;######### ACQUISITION CH 0 CONFIG ############
|
||||
;Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
;Acquisition0.threshold=0.005
|
||||
;Acquisition0.pfa=0.001
|
||||
;Acquisition0.doppler_max=10000
|
||||
;Acquisition0.doppler_step=250
|
||||
;######### TRACKING GPS CONFIG ############
|
||||
|
||||
;#repeat_satellite: Use only jointly with the satellite PRN ID option. The default value is false
|
||||
;Acquisition0.repeat_satellite = false
|
||||
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] [GPS_L1_CA_DLL_PLL_Optim_Tracking]
|
||||
Tracking.implementation=GPS_L1_CA_DLL_PLL_Optim_Tracking
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
|
||||
Tracking_GPS.implementation=GPS_L1_CA_DLL_PLL_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking.item_type=gr_complex
|
||||
Tracking_GPS.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking.if=0
|
||||
Tracking_GPS.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking.dump=false
|
||||
Tracking_GPS.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking.dump_filename=./tracking_ch_
|
||||
Tracking_GPS.dump_filename=../data/epl_tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking.pll_bw_hz=50.0;
|
||||
Tracking_GPS.pll_bw_hz=45.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking.dll_bw_hz=2.0;
|
||||
Tracking_GPS.dll_bw_hz=2.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking.fll_bw_hz=10.0;
|
||||
Tracking_GPS.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking.order=3;
|
||||
Tracking_GPS.order=3;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5]
|
||||
Tracking.early_late_space_chips=0.5;
|
||||
|
||||
;######### TELEMETRY DECODER CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A.
|
||||
TelemetryDecoder.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder.dump=false
|
||||
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A
|
||||
TelemetryDecoder_GPS.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder_GPS.dump=false
|
||||
;#decimation factor
|
||||
TelemetryDecoder_GPS.decimation_factor=1;
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
||||
@ -359,10 +274,10 @@ PVT.implementation=GPS_L1_CA_PVT
|
||||
PVT.averaging_depth=100
|
||||
|
||||
;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]
|
||||
PVT.flag_averaging=true
|
||||
PVT.flag_averaging=false
|
||||
|
||||
;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms]
|
||||
PVT.output_rate_ms=100
|
||||
PVT.output_rate_ms=10
|
||||
|
||||
;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms.
|
||||
PVT.display_rate_ms=500
|
||||
@ -383,7 +298,7 @@ PVT.nmea_dump_devname=/dev/pts/4
|
||||
|
||||
|
||||
;#dump: Enable or disable the PVT internal binary data file logging [true] or [false]
|
||||
PVT.dump=false
|
||||
PVT.dump=true
|
||||
|
||||
;######### OUTPUT_FILTER CONFIG ############
|
||||
;# Receiver output filter: Leave this block disabled in this version
|
@ -166,56 +166,48 @@ InputFilter.IF=80558
|
||||
Resampler.implementation=Pass_Through
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available satellite channels.
|
||||
Channels.count=4
|
||||
;#in_acquisition: Number of channels simultaneously acquiring
|
||||
;#count: Number of available GPS satellite channels.
|
||||
Channels_GPS.count=4
|
||||
;#count: Number of available Galileo satellite channels.
|
||||
Channels_Galileo.count=0
|
||||
;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
|
||||
Channels.in_acquisition=1
|
||||
;#system: GPS, GLONASS, Galileo, SBAS or Compass
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
Channel.system=GPS
|
||||
|
||||
;#signal:
|
||||
;# "1C" GPS L1 C/A
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel.signal=1C
|
||||
|
||||
;######### SPECIFIC CHANNELS CONFIG ######
|
||||
;#The following options are specific to each channel and overwrite the generic options
|
||||
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
|
||||
Channel0.system=GPS
|
||||
Channel0.signal=1C
|
||||
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
Channel0.satellite=11
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition.dump=false
|
||||
Acquisition_GPS.dump=false
|
||||
;#filename: Log path and filename
|
||||
Acquisition.dump_filename=./acq_dump.dat
|
||||
Acquisition_GPS.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition.item_type=gr_complex
|
||||
Acquisition_GPS.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition.if=0
|
||||
Acquisition_GPS.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition.sampled_ms=1
|
||||
Acquisition_GPS.sampled_ms=1
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler
|
||||
Acquisition_GPS.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler
|
||||
;#threshold: Acquisition threshold
|
||||
Acquisition.threshold=0.015
|
||||
Acquisition_GPS.threshold=0.015
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
;Acquisition.pfa=0.0001
|
||||
;Acquisition_GPS.pfa=0.0001
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition.doppler_max=10000
|
||||
Acquisition_GPS.doppler_max=10000
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition.doppler_min=-10000
|
||||
Acquisition_GPS.doppler_min=-10000
|
||||
;#doppler_step Doppler step in the grid search [Hz]
|
||||
Acquisition.doppler_step=500
|
||||
Acquisition_GPS.doppler_step=500
|
||||
;#maximum dwells
|
||||
Acquisition.max_dwells=15
|
||||
Acquisition_GPS.max_dwells=15
|
||||
|
||||
;######### ACQUISITION CHANNELS CONFIG ######
|
||||
;#The following options are specific to each channel and overwrite the generic options
|
||||
@ -226,38 +218,40 @@ Acquisition.max_dwells=15
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] [GPS_L1_CA_DLL_PLL_Optim_Tracking]
|
||||
Tracking.implementation=GPS_L1_CA_DLL_PLL_Optim_Tracking
|
||||
Tracking_GPS.implementation=GPS_L1_CA_DLL_PLL_Optim_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking.item_type=gr_complex
|
||||
Tracking_GPS.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking.if=0
|
||||
Tracking_GPS.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking.dump=false
|
||||
Tracking_GPS.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking.dump_filename=./tracking_ch_
|
||||
Tracking_GPS.dump_filename=./tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking.pll_bw_hz=40.0;
|
||||
Tracking_GPS.pll_bw_hz=40.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking.dll_bw_hz=2.0;
|
||||
Tracking_GPS.dll_bw_hz=2.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking.fll_bw_hz=10.0;
|
||||
Tracking_GPS.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking.order=3;
|
||||
Tracking_GPS.order=3;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5]
|
||||
Tracking.early_late_space_chips=0.5;
|
||||
Tracking_GPS.early_late_space_chips=0.5;
|
||||
|
||||
;######### TELEMETRY DECODER CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A.
|
||||
TelemetryDecoder.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder.dump=false
|
||||
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A
|
||||
TelemetryDecoder_GPS.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder_GPS.dump=false
|
||||
;#decimation factor
|
||||
TelemetryDecoder_GPS.decimation_factor=1;
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
@ -13,13 +13,17 @@ GNSS-SDR.internal_fs_hz=4000000
|
||||
ControlThread.wait_for_flowgraph=false
|
||||
|
||||
;######### SIGNAL_SOURCE CONFIG ############
|
||||
;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental)
|
||||
;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] or [Rtlsdr_Signal_Source]
|
||||
SignalSource.implementation=File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
SignalSource.filename=/media/DATALOGGER/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat
|
||||
SignalSource.filename=../data/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat
|
||||
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples.
|
||||
;#Use gr_complex for 32 bits float I/Q or short for I/Q interleaved short integer.
|
||||
;#If short is selected you should have to instantiate the Ishort_To_Complex data_type_adapter.
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
SignalSource.item_type=short
|
||||
|
||||
;#sampling_frequency: Original Signal sampling frequency in [Hz]
|
||||
@ -31,6 +35,10 @@ SignalSource.freq=1575420000
|
||||
;#gain: Front-end Gain in [dB]
|
||||
SignalSource.gain=60
|
||||
|
||||
;#AGC_enabled: RTLSDR AGC enabled [true or false]
|
||||
|
||||
SignalSource.AGC_enabled=true
|
||||
|
||||
;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0)
|
||||
SignalSource.subdevice=B:0
|
||||
|
||||
@ -42,7 +50,6 @@ SignalSource.repeat=false
|
||||
|
||||
;#dump: Dump the Signal source data to a file. Disable this option in this version
|
||||
SignalSource.dump=false
|
||||
|
||||
SignalSource.dump_filename=../data/signal_source.dat
|
||||
|
||||
|
||||
@ -61,8 +68,12 @@ SignalConditioner.implementation=Signal_Conditioner
|
||||
|
||||
;######### DATA_TYPE_ADAPTER CONFIG ############
|
||||
;## Changes the type of input data. Please disable it in this version.
|
||||
;#implementation: [Pass_Through] disables this block
|
||||
;#implementation: Use [Ishort_To_Complex] or [Pass_Through]
|
||||
DataTypeAdapter.implementation=Ishort_To_Complex
|
||||
;#dump: Dump the filtered data to a file.
|
||||
DataTypeAdapter.dump=false
|
||||
;#dump_filename: Log path and filename.
|
||||
DataTypeAdapter.dump_filename=../data/data_type_adapter.dat
|
||||
|
||||
;######### INPUT_FILTER CONFIG ############
|
||||
;## Filter the input data. Can be combined with frequency translation for IF signals
|
||||
@ -105,7 +116,16 @@ InputFilter.number_of_bands=2
|
||||
;#Frequency is in the range [0, 1], with 1 being the Nyquist frequency (Fs/2)
|
||||
;#The number of band_begin and band_end elements must match the number of bands
|
||||
|
||||
#used for gps
|
||||
InputFilter.band1_begin=0.0
|
||||
;InputFilter.band1_end=0.8
|
||||
InputFilter.band1_end=0.85
|
||||
InputFilter.band2_begin=0.90
|
||||
InputFilter.band2_end=1.0
|
||||
|
||||
#used for galileo
|
||||
InputFilter.band1_begin=0.0
|
||||
;InputFilter.band1_end=0.8
|
||||
InputFilter.band1_end=0.45
|
||||
InputFilter.band2_begin=0.55
|
||||
InputFilter.band2_end=1.0
|
||||
@ -164,13 +184,19 @@ Resampler.sample_freq_out=4000000
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available satellite channels.
|
||||
Channels.count=4
|
||||
Channels_Galileo.count=4
|
||||
Channels_GPS.count=0
|
||||
;#in_acquisition: Number of channels simultaneously acquiring
|
||||
Channels.in_acquisition=1
|
||||
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
Channel.system=Galileo
|
||||
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel.signal=1B
|
||||
|
||||
;#signal:
|
||||
;# "1C" GPS L1 C/A
|
||||
;# "1P" GPS L1 P
|
||||
@ -228,117 +254,73 @@ Channel.system=Galileo
|
||||
;# "6Q" COMPASS E6 Q
|
||||
;# "6X" COMPASS E6 IQ
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel.signal=1B
|
||||
|
||||
|
||||
|
||||
;Galileo FM3 -> PRN 19
|
||||
;Galileo FM4 -> PRN 20
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
|
||||
;Channel0.system=Galileo
|
||||
;Channel0.signal=1B
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
Channel0.satellite=20
|
||||
|
||||
;######### CHANNEL 1 CONFIG ############
|
||||
|
||||
;Channel1.system=Galileo
|
||||
;Channel1.signal=1B
|
||||
Channel1.satellite=12
|
||||
|
||||
;######### CHANNEL 2 CONFIG ############
|
||||
|
||||
;Channel2.system=Galileo
|
||||
;Channel2.signal=1B
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
Channel2.satellite=11
|
||||
|
||||
;######### CHANNEL 3 CONFIG ############
|
||||
|
||||
;Channel3.system=Galileo
|
||||
;Channel3.signal=1B
|
||||
Channel3.satellite=19
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition.dump=false
|
||||
Acquisition_Galileo.dump=false
|
||||
;#filename: Log path and filename
|
||||
Acquisition.dump_filename=./acq_dump.dat
|
||||
Acquisition_Galileo.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition.item_type=gr_complex
|
||||
Acquisition_Galileo.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition.if=0
|
||||
Acquisition_Galileo.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition.sampled_ms=4
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition
|
||||
Acquisition_Galileo.coherent_integration_time_ms=4
|
||||
|
||||
Acquisition_Galileo.implementation=Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition
|
||||
|
||||
;#threshold: Acquisition threshold
|
||||
;Acquisition.threshold=0
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition.pfa=0.00003
|
||||
Acquisition_Galileo.threshold=0.05
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition.doppler_max=15000
|
||||
Acquisition_Galileo.doppler_max=15000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition.doppler_step=125
|
||||
Acquisition_Galileo.doppler_step=125
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms];
|
||||
Acquisition_Galileo.coherent_integration_time_ms=8
|
||||
|
||||
;######### ACQUISITION CHANNELS CONFIG ######
|
||||
|
||||
;######### ACQUISITION CH 0 CONFIG ############
|
||||
|
||||
;#repeat_satellite: Use only jointly with the satellite PRN ID option. The default value is false
|
||||
Acquisition0.repeat_satellite = true
|
||||
Acquisition1.repeat_satellite = true
|
||||
Acquisition2.repeat_satellite = true
|
||||
Acquisition3.repeat_satellite = true
|
||||
|
||||
;#cboc: Only for [Galileo_E1_PCPS_Ambiguous_Acquisition]. This option allows you to choose between acquiring with CBOC signal [true] or sinboc(1,1) signal [false].
|
||||
;#Use only if GNSS-SDR.internal_fs_hz is greater than or equal to 6138000
|
||||
Acquisition0.cboc=false
|
||||
|
||||
|
||||
;######### ACQUISITION CH 1 CONFIG ############
|
||||
Acquisition1.cboc=false
|
||||
Acquisition_Galileo.cboc=false
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
|
||||
Tracking.implementation=Galileo_E1_DLL_PLL_VEML_Tracking
|
||||
Tracking_Galileo.implementation=Galileo_E1_DLL_PLL_VEML_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking.item_type=gr_complex
|
||||
Tracking_Galileo.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking.if=0
|
||||
Tracking_Galileo.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking.dump=true
|
||||
Tracking_Galileo.dump=true
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking.dump_filename=../data/veml_tracking_ch_
|
||||
Tracking_Galileo.dump_filename=../data/veml_tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking.pll_bw_hz=20.0;
|
||||
Tracking_Galileo.pll_bw_hz=20.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking.dll_bw_hz=2.0;
|
||||
Tracking_Galileo.dll_bw_hz=2.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking.fll_bw_hz=10.0;
|
||||
Tracking_Galileo.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking.order=3;
|
||||
Tracking_Galileo.order=3;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo
|
||||
Tracking.early_late_space_chips=0.15;
|
||||
Tracking_Galileo.early_late_space_chips=0.15;
|
||||
|
||||
;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6]
|
||||
Tracking.very_early_late_space_chips=0.6;
|
||||
Tracking_Galileo.very_early_late_space_chips=0.6;
|
||||
|
||||
;######### TELEMETRY DECODER CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A or [Galileo_E1B_Telemetry_Decoder] for Galileo E1B
|
||||
TelemetryDecoder.implementation=Galileo_E1B_Telemetry_Decoder
|
||||
TelemetryDecoder.dump=false
|
||||
TelemetryDecoder_Galileo.implementation=Galileo_E1B_Telemetry_Decoder
|
||||
TelemetryDecoder_Galileo.dump=false
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
@ -19,7 +19,7 @@ ControlThread.wait_for_flowgraph=false
|
||||
SignalSource.implementation=Nsr_File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
SignalSource.filename=/media/DATALOGGER/ION GNSS 2013/E1L1_FE0_Band0.stream
|
||||
SignalSource.filename=../data/E1L1_FE0_Band0.stream
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
SignalSource.item_type=byte
|
||||
@ -148,11 +148,12 @@ InputFilter.decimation_factor=8
|
||||
;#[Pass_Through] disables this block
|
||||
;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation
|
||||
Resampler.implementation=Pass_Through
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available satellite channels.
|
||||
Channels.count=6
|
||||
;#in_acquisition: Number of channels simultaneously acquiring
|
||||
;#count: Number of available GPS satellite channels.
|
||||
Channels_GPS.count=0
|
||||
;#count: Number of available Galileo satellite channels.
|
||||
Channels_Galileo.count=8
|
||||
;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
|
||||
Channels.in_acquisition=1
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
@ -217,78 +218,115 @@ Channel.system=Galileo
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel.signal=1B
|
||||
|
||||
|
||||
|
||||
;Galileo FM3 -> PRN 19
|
||||
;Galileo FM4 -> PRN 20
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
|
||||
;Channel0.system=Galileo
|
||||
;Channel0.signal=1B
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
;Channel0.satellite=20
|
||||
|
||||
;######### CHANNEL 1 CONFIG ############
|
||||
|
||||
;Channel1.system=Galileo
|
||||
;Channel1.signal=1B
|
||||
;Channel1.satellite=12
|
||||
|
||||
;######### CHANNEL 2 CONFIG ############
|
||||
|
||||
;Channel2.system=Galileo
|
||||
;Channel2.signal=1B
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
;Channel2.satellite=11
|
||||
|
||||
;######### CHANNEL 3 CONFIG ############
|
||||
|
||||
;Channel3.system=Galileo
|
||||
;Channel3.signal=1B
|
||||
;Channel3.satellite=19
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition.dump=false
|
||||
;#filename: Log path and filename
|
||||
Acquisition.dump_filename=./acq_dump.dat
|
||||
Acquisition_Galileo.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition.item_type=gr_complex
|
||||
Acquisition_Galileo.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition.if=0
|
||||
Acquisition_Galileo.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition.sampled_ms=4
|
||||
Acquisition_Galileo.sampled_ms=4
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition
|
||||
Acquisition_Galileo.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition
|
||||
;#threshold: Acquisition threshold
|
||||
;Acquisition.threshold=0
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition.pfa=0.00001
|
||||
Acquisition_Galileo.pfa=0.0000008
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition.doppler_max=10000
|
||||
Acquisition_Galileo.doppler_max=15000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition.doppler_step=125
|
||||
Acquisition_Galileo.doppler_step=125
|
||||
|
||||
;######### ACQUISITION CHANNELS CONFIG ######
|
||||
|
||||
;######### ACQUISITION CH 0 CONFIG ############
|
||||
|
||||
;#repeat_satellite: Use only jointly with the satellite PRN ID option. The default value is false
|
||||
;Acquisition0.repeat_satellite = false
|
||||
;Acquisition_Galileo0.repeat_satellite = true
|
||||
;Acquisition_Galileo1.repeat_satellite = true
|
||||
;Acquisition_Galileo2.repeat_satellite = true
|
||||
;Acquisition_Galileo3.repeat_satellite = true
|
||||
|
||||
;#cboc: Only for [Galileo_E1_PCPS_Ambiguous_Acquisition]. This option allows you to choose between acquiring with CBOC signal [true] or sinboc(1,1) signal [false].
|
||||
;#Use only if GNSS-SDR.internal_fs_hz is greater than or equal to 6138000
|
||||
Acquisition0.cboc=false
|
||||
Acquisition_Galileo0.cboc=false
|
||||
|
||||
|
||||
;######### ACQUISITION CH 1 CONFIG ############
|
||||
Acquisition1.cboc=false
|
||||
Acquisition_Galileo1.cboc=false
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
|
||||
Tracking.implementation=Galileo_E1_DLL_PLL_VEML_Tracking
|
||||
Tracking_Galileo.implementation=Galileo_E1_DLL_PLL_VEML_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking.item_type=gr_complex
|
||||
Tracking_Galileo.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking.if=0
|
||||
Tracking_Galileo.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking.dump=false
|
||||
Tracking_Galileo.dump=true
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking.dump_filename=../data/veml_tracking_ch_
|
||||
Tracking_Galileo.dump_filename=../data/veml_tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking.pll_bw_hz=20.0;
|
||||
Tracking_Galileo.pll_bw_hz=20.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking.dll_bw_hz=2.0;
|
||||
Tracking_Galileo.dll_bw_hz=2.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking_Galileo.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking.order=3;
|
||||
Tracking_Galileo.order=3;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo
|
||||
Tracking.early_late_space_chips=0.15;
|
||||
Tracking_Galileo.early_late_space_chips=0.15;
|
||||
|
||||
;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6]
|
||||
Tracking.very_early_late_space_chips=0.6;
|
||||
Tracking_Galileo.very_early_late_space_chips=0.6;
|
||||
|
||||
;######### TELEMETRY DECODER CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A or [Galileo_E1B_Telemetry_Decoder] for Galileo E1B
|
||||
TelemetryDecoder.implementation=Galileo_E1B_Telemetry_Decoder
|
||||
TelemetryDecoder.dump=false
|
||||
TelemetryDecoder_Galileo.implementation=Galileo_E1B_Telemetry_Decoder
|
||||
TelemetryDecoder_Galileo.dump=false
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
||||
@ -306,19 +344,19 @@ Observables.dump_filename=./observables.dat
|
||||
PVT.implementation=GALILEO_E1_PVT
|
||||
|
||||
;#averaging_depth: Number of PVT observations in the moving average algorithm
|
||||
PVT.averaging_depth=100
|
||||
PVT.averaging_depth=10
|
||||
|
||||
;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]
|
||||
PVT.flag_averaging=true
|
||||
PVT.flag_averaging=false
|
||||
|
||||
;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms]
|
||||
PVT.output_rate_ms=100;
|
||||
PVT.output_rate_ms=10
|
||||
|
||||
;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms.
|
||||
PVT.display_rate_ms=500;
|
||||
PVT.display_rate_ms=500
|
||||
|
||||
;#dump: Enable or disable the PVT internal binary data file logging [true] or [false]
|
||||
PVT.dump=false
|
||||
PVT.dump=true
|
||||
|
||||
;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump.
|
||||
PVT.dump_filename=./PVT
|
297
conf/gnss-sdr_Galileo_E1_short.conf
Normal file
297
conf/gnss-sdr_Galileo_E1_short.conf
Normal file
@ -0,0 +1,297 @@
|
||||
; Default configuration file
|
||||
; You can define your own receiver and invoke it by doing
|
||||
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
|
||||
;
|
||||
|
||||
[GNSS-SDR]
|
||||
|
||||
;######### GLOBAL OPTIONS ##################
|
||||
;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz].
|
||||
GNSS-SDR.internal_fs_hz=4000000
|
||||
|
||||
;######### CONTROL_THREAD CONFIG ############
|
||||
ControlThread.wait_for_flowgraph=false
|
||||
|
||||
;######### SIGNAL_SOURCE CONFIG ############
|
||||
;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental)
|
||||
SignalSource.implementation=File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
SignalSource.filename=../data/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
SignalSource.item_type=short
|
||||
|
||||
;#sampling_frequency: Original Signal sampling frequency in [Hz]
|
||||
SignalSource.sampling_frequency=4000000
|
||||
|
||||
;#freq: RF front-end center frequency in [Hz]
|
||||
SignalSource.freq=1575420000
|
||||
|
||||
;#gain: Front-end Gain in [dB]
|
||||
SignalSource.gain=60
|
||||
|
||||
;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0)
|
||||
SignalSource.subdevice=B:0
|
||||
|
||||
;#samples: Number of samples to be processed. Notice that 0 indicates the entire file.
|
||||
SignalSource.samples=0
|
||||
|
||||
;#repeat: Repeat the processing file. Disable this option in this version
|
||||
SignalSource.repeat=false
|
||||
|
||||
;#dump: Dump the Signal source data to a file. Disable this option in this version
|
||||
SignalSource.dump=false
|
||||
|
||||
SignalSource.dump_filename=../data/signal_source.dat
|
||||
|
||||
|
||||
;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing.
|
||||
; it helps to not overload the CPU, but the processing time will be longer.
|
||||
SignalSource.enable_throttle_control=false
|
||||
|
||||
|
||||
;######### SIGNAL_CONDITIONER CONFIG ############
|
||||
;## It holds blocks to change data type, filter and resample input data.
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Signal_Conditioner]
|
||||
;#[Pass_Through] disables this block and the [DataTypeAdapter], [InputFilter] and [Resampler] blocks
|
||||
;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks
|
||||
SignalConditioner.implementation=Signal_Conditioner
|
||||
|
||||
;######### DATA_TYPE_ADAPTER CONFIG ############
|
||||
;## Changes the type of input data. Please disable it in this version.
|
||||
;#implementation: [Pass_Through] disables this block
|
||||
DataTypeAdapter.implementation=Ishort_To_Complex
|
||||
|
||||
;######### INPUT_FILTER CONFIG ############
|
||||
;## Filter the input data. Can be combined with frequency translation for IF signals
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Fir_Filter] or [Freq_Xlating_Fir_Filter]
|
||||
;#[Pass_Through] disables this block
|
||||
;#[Fir_Filter] enables a FIR Filter
|
||||
;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation that shifts IF down to zero Hz.
|
||||
|
||||
;InputFilter.implementation=Fir_Filter
|
||||
;InputFilter.implementation=Freq_Xlating_Fir_Filter
|
||||
InputFilter.implementation=Pass_Through
|
||||
|
||||
;#dump: Dump the filtered data to a file.
|
||||
InputFilter.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename.
|
||||
InputFilter.dump_filename=../data/input_filter.dat
|
||||
|
||||
;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation.
|
||||
;#These options are based on parameters of gnuradio's function: gr_remez.
|
||||
;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands.
|
||||
|
||||
;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version.
|
||||
InputFilter.input_item_type=gr_complex
|
||||
|
||||
;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version.
|
||||
InputFilter.output_item_type=gr_complex
|
||||
|
||||
;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version.
|
||||
InputFilter.taps_item_type=float
|
||||
|
||||
;#number_of_taps: Number of taps in the filter. Increasing this parameter increases the processing time
|
||||
InputFilter.number_of_taps=5
|
||||
|
||||
;#number_of _bands: Number of frequency bands in the filter.
|
||||
InputFilter.number_of_bands=2
|
||||
|
||||
;#bands: frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...].
|
||||
;#Frequency is in the range [0, 1], with 1 being the Nyquist frequency (Fs/2)
|
||||
;#The number of band_begin and band_end elements must match the number of bands
|
||||
|
||||
InputFilter.band1_begin=0.0
|
||||
InputFilter.band1_end=0.45
|
||||
InputFilter.band2_begin=0.55
|
||||
InputFilter.band2_end=1.0
|
||||
|
||||
;#ampl: desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...].
|
||||
;#The number of ampl_begin and ampl_end elements must match the number of bands
|
||||
|
||||
InputFilter.ampl1_begin=1.0
|
||||
InputFilter.ampl1_end=1.0
|
||||
InputFilter.ampl2_begin=0.0
|
||||
InputFilter.ampl2_end=0.0
|
||||
|
||||
;#band_error: weighting applied to each band (usually 1).
|
||||
;#The number of band_error elements must match the number of bands
|
||||
InputFilter.band1_error=1.0
|
||||
InputFilter.band2_error=1.0
|
||||
|
||||
;#filter_type: one of "bandpass", "hilbert" or "differentiator"
|
||||
InputFilter.filter_type=bandpass
|
||||
|
||||
;#grid_density: determines how accurately the filter will be constructed.
|
||||
;The minimum value is 16; higher values are slower to compute the filter.
|
||||
InputFilter.grid_density=16
|
||||
|
||||
;#The following options are used only in Freq_Xlating_Fir_Filter implementation.
|
||||
;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz
|
||||
|
||||
InputFilter.sampling_frequency=4000000
|
||||
InputFilter.IF=0
|
||||
|
||||
|
||||
|
||||
;######### RESAMPLER CONFIG ############
|
||||
;## Resamples the input data.
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Direct_Resampler]
|
||||
;#[Pass_Through] disables this block
|
||||
;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation
|
||||
;Resampler.implementation=Direct_Resampler
|
||||
Resampler.implementation=Pass_Through
|
||||
|
||||
;#dump: Dump the resamplered data to a file.
|
||||
Resampler.dump=false
|
||||
;#dump_filename: Log path and filename.
|
||||
Resampler.dump_filename=../data/resampler.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Resampler.item_type=gr_complex
|
||||
|
||||
;#sample_freq_in: the sample frequency of the input signal
|
||||
Resampler.sample_freq_in=4000000
|
||||
|
||||
;#sample_freq_out: the desired sample frequency of the output signal
|
||||
Resampler.sample_freq_out=4000000
|
||||
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available GPS satellite channels.
|
||||
Channels_GPS.count=0
|
||||
;#count: Number of available Galileo satellite channels.
|
||||
Channels_Galileo.count=4
|
||||
;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
|
||||
Channels.in_acquisition=1
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
Channel.system=Galileo
|
||||
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel.signal=1B
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition_Galileo.dump=false
|
||||
;#filename: Log path and filename
|
||||
Acquisition_Galileo.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition_Galileo.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition_Galileo.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition_Galileo.sampled_ms=4
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition_Galileo.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition
|
||||
;#threshold: Acquisition threshold
|
||||
;Acquisition_Galileo.threshold=0
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition_Galileo.pfa=0.0000002
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition_Galileo.doppler_max=15000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition_Galileo.doppler_step=125
|
||||
|
||||
;######### ACQUISITION CHANNELS CONFIG ######
|
||||
|
||||
;######### ACQUISITION CH 0 CONFIG ############
|
||||
|
||||
;#repeat_satellite: Use only jointly with the satellite PRN ID option. The default value is false
|
||||
;Acquisition_Galileo0.repeat_satellite = true
|
||||
;Acquisition_Galileo1.repeat_satellite = true
|
||||
;Acquisition_Galileo2.repeat_satellite = true
|
||||
;Acquisition_Galileo3.repeat_satellite = true
|
||||
|
||||
;#cboc: Only for [Galileo_E1_PCPS_Ambiguous_Acquisition]. This option allows you to choose between acquiring with CBOC signal [true] or sinboc(1,1) signal [false].
|
||||
;#Use only if GNSS-SDR.internal_fs_hz is greater than or equal to 6138000
|
||||
Acquisition_Galileo0.cboc=false
|
||||
|
||||
|
||||
;######### ACQUISITION CH 1 CONFIG ############
|
||||
Acquisition_Galileo1.cboc=false
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
|
||||
Tracking_Galileo.implementation=Galileo_E1_DLL_PLL_VEML_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking_Galileo.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking_Galileo.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking_Galileo.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking_Galileo.dump_filename=../data/veml_tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking_Galileo.pll_bw_hz=15.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking_Galileo.dll_bw_hz=2.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking_Galileo.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking_Galileo.order=3;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo
|
||||
Tracking_Galileo.early_late_space_chips=0.15;
|
||||
|
||||
;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6]
|
||||
Tracking_Galileo.very_early_late_space_chips=0.6;
|
||||
|
||||
|
||||
;######### TELEMETRY DECODER CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A or [Galileo_E1B_Telemetry_Decoder] for Galileo E1B
|
||||
TelemetryDecoder_Galileo.implementation=Galileo_E1B_Telemetry_Decoder
|
||||
TelemetryDecoder_Galileo.dump=false
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
||||
Observables.implementation=Galileo_E1B_Observables
|
||||
|
||||
;#dump: Enable or disable the Observables internal binary data file logging [true] or [false]
|
||||
Observables.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename.
|
||||
Observables.dump_filename=./observables.dat
|
||||
|
||||
|
||||
;######### PVT CONFIG ############
|
||||
;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version.
|
||||
PVT.implementation=GALILEO_E1_PVT
|
||||
|
||||
;#averaging_depth: Number of PVT observations in the moving average algorithm
|
||||
PVT.averaging_depth=100
|
||||
|
||||
;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]
|
||||
PVT.flag_averaging=false
|
||||
|
||||
;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms]
|
||||
PVT.output_rate_ms=100;
|
||||
|
||||
;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms.
|
||||
PVT.display_rate_ms=500;
|
||||
|
||||
;#dump: Enable or disable the PVT internal binary data file logging [true] or [false]
|
||||
PVT.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump.
|
||||
PVT.dump_filename=./PVT
|
||||
|
||||
;######### OUTPUT_FILTER CONFIG ############
|
||||
;# Receiver output filter: Leave this block disabled in this version
|
||||
OutputFilter.implementation=Null_Sink_Output_Filter
|
||||
OutputFilter.filename=data/gnss-sdr.dat
|
||||
OutputFilter.item_type=gr_complex
|
414
conf/gnss-sdr_Galileo_E5a.conf
Normal file
414
conf/gnss-sdr_Galileo_E5a.conf
Normal file
@ -0,0 +1,414 @@
|
||||
; Default configuration file
|
||||
; You can define your own receiver and invoke it by doing
|
||||
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
|
||||
;
|
||||
|
||||
[GNSS-SDR]
|
||||
|
||||
;######### GLOBAL OPTIONS ##################
|
||||
;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz].
|
||||
GNSS-SDR.internal_fs_hz=32000000
|
||||
|
||||
;######### CONTROL_THREAD CONFIG ############
|
||||
ControlThread.wait_for_flowgraph=false
|
||||
|
||||
;######### SUPL RRLP GPS assistance configuration #####
|
||||
;GNSS-SDR.SUPL_gps_enabled=false
|
||||
;GNSS-SDR.SUPL_read_gps_assistance_xml=false
|
||||
;GNSS-SDR.SUPL_gps_ephemeris_server=supl.nokia.com
|
||||
;GNSS-SDR.SUPL_gps_ephemeris_port=7275
|
||||
;GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com
|
||||
;GNSS-SDR.SUPL_gps_acquisition_port=7275
|
||||
;GNSS-SDR.SUPL_MCC=244
|
||||
;GNSS-SDR.SUPL_MNS=5
|
||||
;GNSS-SDR.SUPL_LAC=0x59e2
|
||||
;GNSS-SDR.SUPL_CI=0x31b0
|
||||
|
||||
;######### SIGNAL_SOURCE CONFIG ############
|
||||
;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental)
|
||||
SignalSource.implementation=File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
;SignalSource.filename=/home/marc/E5a_acquisitions/signal_source_5X_primary.dat
|
||||
;SignalSource.filename=/home/marc/E5a_acquisitions/galileo_E5_8M_r2_upsampled_12.dat
|
||||
;SignalSource.filename=/home/marc/E5a_acquisitions/Tiered_sim_4sat_stup4_2s_up.dat
|
||||
;SignalSource.filename=/home/marc/E5a_acquisitions/signal_source_sec21M_long.dat
|
||||
SignalSource.filename=../data/32MS_complex.dat;
|
||||
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
SignalSource.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Original Signal sampling frequency in [Hz]
|
||||
SignalSource.sampling_frequency=32000000
|
||||
|
||||
;#freq: RF front-end center frequency in [Hz]
|
||||
SignalSource.freq=1176450000
|
||||
|
||||
;#gain: Front-end Gain in [dB]
|
||||
SignalSource.gain=50
|
||||
|
||||
;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0)
|
||||
SignalSource.subdevice=B:0
|
||||
|
||||
;#samples: Number of samples to be processed. Notice that 0 indicates the entire file.
|
||||
SignalSource.samples=0
|
||||
|
||||
;#repeat: Repeat the processing file. Disable this option in this version
|
||||
SignalSource.repeat=false
|
||||
|
||||
;#dump: Dump the Signal source data to a file. Disable this option in this version
|
||||
SignalSource.dump=false
|
||||
|
||||
SignalSource.dump_filename=../data/signal_source.dat
|
||||
|
||||
|
||||
;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing.
|
||||
; it helps to not overload the CPU, but the processing time will be longer.
|
||||
SignalSource.enable_throttle_control=false
|
||||
|
||||
|
||||
;######### SIGNAL_CONDITIONER CONFIG ############
|
||||
;## It holds blocks to change data type, filter and resample input data.
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Signal_Conditioner]
|
||||
;#[Pass_Through] disables this block and the [DataTypeAdapter], [InputFilter] and [Resampler] blocks
|
||||
;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks
|
||||
;SignalConditioner.implementation=Signal_Conditioner
|
||||
SignalConditioner.implementation=Pass_Through
|
||||
|
||||
;######### DATA_TYPE_ADAPTER CONFIG ############
|
||||
;## Changes the type of input data. Please disable it in this version.
|
||||
;#implementation: [Pass_Through] disables this block
|
||||
DataTypeAdapter.implementation=Pass_Through
|
||||
|
||||
;######### INPUT_FILTER CONFIG ############
|
||||
;## Filter the input data. Can be combined with frequency translation for IF signals
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Fir_Filter] or [Freq_Xlating_Fir_Filter]
|
||||
;#[Pass_Through] disables this block
|
||||
;#[Fir_Filter] enables a FIR Filter
|
||||
;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation that shifts IF down to zero Hz.
|
||||
|
||||
;InputFilter.implementation=Fir_Filter
|
||||
;InputFilter.implementation=Freq_Xlating_Fir_Filter
|
||||
InputFilter.implementation=Pass_Through
|
||||
|
||||
;#dump: Dump the filtered data to a file.
|
||||
InputFilter.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename.
|
||||
InputFilter.dump_filename=../data/input_filter.dat
|
||||
|
||||
;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation.
|
||||
;#These options are based on parameters of gnuradio's function: gr_remez.
|
||||
;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands.
|
||||
|
||||
;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version.
|
||||
InputFilter.input_item_type=gr_complex
|
||||
|
||||
;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version.
|
||||
InputFilter.output_item_type=gr_complex
|
||||
|
||||
;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version.
|
||||
InputFilter.taps_item_type=float
|
||||
|
||||
;#number_of_taps: Number of taps in the filter. Increasing this parameter increases the processing time
|
||||
InputFilter.number_of_taps=5
|
||||
|
||||
;#number_of _bands: Number of frequency bands in the filter.
|
||||
InputFilter.number_of_bands=2
|
||||
|
||||
;#bands: frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...].
|
||||
;#Frequency is in the range [0, 1], with 1 being the Nyquist frequency (Fs/2)
|
||||
;#The number of band_begin and band_end elements must match the number of bands
|
||||
|
||||
InputFilter.band1_begin=0.0
|
||||
InputFilter.band1_end=0.45
|
||||
InputFilter.band2_begin=0.55
|
||||
InputFilter.band2_end=1.0
|
||||
|
||||
;#ampl: desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...].
|
||||
;#The number of ampl_begin and ampl_end elements must match the number of bands
|
||||
|
||||
InputFilter.ampl1_begin=1.0
|
||||
InputFilter.ampl1_end=1.0
|
||||
InputFilter.ampl2_begin=0.0
|
||||
InputFilter.ampl2_end=0.0
|
||||
|
||||
;#band_error: weighting applied to each band (usually 1).
|
||||
;#The number of band_error elements must match the number of bands
|
||||
InputFilter.band1_error=1.0
|
||||
InputFilter.band2_error=1.0
|
||||
|
||||
;#filter_type: one of "bandpass", "hilbert" or "differentiator"
|
||||
InputFilter.filter_type=bandpass
|
||||
|
||||
;#grid_density: determines how accurately the filter will be constructed.
|
||||
;The minimum value is 16; higher values are slower to compute the filter.
|
||||
InputFilter.grid_density=16
|
||||
|
||||
;#The following options are used only in Freq_Xlating_Fir_Filter implementation.
|
||||
;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz
|
||||
|
||||
InputFilter.sampling_frequency=32000000
|
||||
InputFilter.IF=0
|
||||
|
||||
|
||||
|
||||
;######### RESAMPLER CONFIG ############
|
||||
;## Resamples the input data.
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Direct_Resampler]
|
||||
;#[Pass_Through] disables this block
|
||||
;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation
|
||||
;Resampler.implementation=Direct_Resampler
|
||||
Resampler.implementation=Pass_Through
|
||||
|
||||
;#dump: Dump the resamplered data to a file.
|
||||
Resampler.dump=false
|
||||
;#dump_filename: Log path and filename.
|
||||
Resampler.dump_filename=../data/resampler.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Resampler.item_type=gr_complex
|
||||
|
||||
;#sample_freq_in: the sample frequency of the input signal
|
||||
Resampler.sample_freq_in=8000000
|
||||
|
||||
;#sample_freq_out: the desired sample frequency of the output signal
|
||||
Resampler.sample_freq_out=4000000
|
||||
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available satellite channels.
|
||||
Channels_Galileo.count=1
|
||||
;#in_acquisition: Number of channels simultaneously acquiring
|
||||
Channels.in_acquisition=1
|
||||
;#system: GPS, GLONASS, Galileo, SBAS or Compass
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
Channel.system=Galileo
|
||||
|
||||
;#signal:
|
||||
;# "1C" GPS L1 C/A
|
||||
;# "1P" GPS L1 P
|
||||
;# "1W" GPS L1 Z-tracking and similar (AS on)
|
||||
;# "1Y" GPS L1 Y
|
||||
;# "1M" GPS L1 M
|
||||
;# "1N" GPS L1 codeless
|
||||
;# "2C" GPS L2 C/A
|
||||
;# "2D" GPS L2 L1(C/A)+(P2-P1) semi-codeless
|
||||
;# "2S" GPS L2 L2C (M)
|
||||
;# "2L" GPS L2 L2C (L)
|
||||
;# "2X" GPS L2 L2C (M+L)
|
||||
;# "2P" GPS L2 P
|
||||
;# "2W" GPS L2 Z-tracking and similar (AS on)
|
||||
;# "2Y" GPS L2 Y
|
||||
;# "2M" GPS GPS L2 M
|
||||
;# "2N" GPS L2 codeless
|
||||
;# "5I" GPS L5 I
|
||||
;# "5Q" GPS L5 Q
|
||||
;# "5X" GPS L5 I+Q
|
||||
;# "1C" GLONASS G1 C/A
|
||||
;# "1P" GLONASS G1 P
|
||||
;# "2C" GLONASS G2 C/A (Glonass M)
|
||||
;# "2P" GLONASS G2 P
|
||||
;# "1A" GALILEO E1 A (PRS)
|
||||
;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL)
|
||||
;# "1C" GALILEO E1 C (no data)
|
||||
;# "1X" GALILEO E1 B+C
|
||||
;# "1Z" GALILEO E1 A+B+C
|
||||
;# "5I" GALILEO E5a I (F/NAV OS)
|
||||
;# "5Q" GALILEO E5a Q (no data)
|
||||
;# "5X" GALILEO E5a I+Q
|
||||
;# "7I" GALILEO E5b I
|
||||
;# "7Q" GALILEO E5b Q
|
||||
;# "7X" GALILEO E5b I+Q
|
||||
;# "8I" GALILEO E5 I
|
||||
;# "8Q" GALILEO E5 Q
|
||||
;# "8X" GALILEO E5 I+Q
|
||||
;# "6A" GALILEO E6 A
|
||||
;# "6B" GALILEO E6 B
|
||||
;# "6C" GALILEO E6 C
|
||||
;# "6X" GALILEO E6 B+C
|
||||
;# "6Z" GALILEO E6 A+B+C
|
||||
;# "1C" SBAS L1 C/A
|
||||
;# "5I" SBAS L5 I
|
||||
;# "5Q" SBAS L5 Q
|
||||
;# "5X" SBAS L5 I+Q
|
||||
;# "2I" COMPASS E2 I
|
||||
;# "2Q" COMPASS E2 Q
|
||||
;# "2X" COMPASS E2 IQ
|
||||
;# "7I" COMPASS E5b I
|
||||
;# "7Q" COMPASS E5b Q
|
||||
;# "7X" COMPASS E5b IQ
|
||||
;# "6I" COMPASS E6 I
|
||||
;# "6Q" COMPASS E6 Q
|
||||
;# "6X" COMPASS E6 IQ
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel.signal=5X
|
||||
|
||||
;######### SPECIFIC CHANNELS CONFIG ######
|
||||
;#The following options are specific to each channel and overwrite the generic options
|
||||
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
|
||||
Channel0.system=Galileo
|
||||
Channel0.signal=5X
|
||||
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
Channel0.satellite=19
|
||||
;Channel0.repeat_satellite=true
|
||||
|
||||
;######### CHANNEL 1 CONFIG ############
|
||||
|
||||
;Channel1.system=Galileo
|
||||
;Channel1.signal=5Q
|
||||
;Channel1.satellite=12
|
||||
|
||||
;######### CHANNEL 2 CONFIG ############
|
||||
|
||||
;Channel2.system=Galileo
|
||||
;Channel2.signal=5Q
|
||||
;Channel2.satellite=11
|
||||
|
||||
;######### CHANNEL 3 CONFIG ############
|
||||
|
||||
;Channel3.system=Galileo
|
||||
;Channel3.signal=5Q
|
||||
;Channel3.satellite=20
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition_Galileo.dump=true
|
||||
;#filename: Log path and filename
|
||||
Acquisition_Galileo.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition_Galileo.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition_Galileo.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition_Galileo.coherent_integration_time_ms=1
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition_Galileo.implementation=Galileo_E5a_Noncoherent_IQ_Acquisition_CAF
|
||||
;#threshold: Acquisition threshold. It will be ignored if pfa is defined.
|
||||
Acquisition_Galileo.threshold=0.001
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition_Galileo.pfa=0.0003
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition_Galileo.doppler_max=10000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition_Galileo.doppler_step=250
|
||||
;#bit_transition_flag: Enable or disable a strategy to deal with bit transitions in GPS signals: process two dwells and take
|
||||
;maximum test statistics. Only use with implementation: [GPS_L1_CA_PCPS_Acquisition] (should not be used for Galileo_E1_PCPS_Ambiguous_Acquisition])
|
||||
Acquisition_Galileo.bit_transition_flag=false
|
||||
;#max_dwells: Maximum number of consecutive dwells to be processed. It will be ignored if bit_transition_flag=true
|
||||
Acquisition_Galileo.max_dwells=1
|
||||
|
||||
;#CAF filter: **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is desactivated. Recommended value 3000 Hz
|
||||
Acquisition_Galileo.CAF_window_hz=0
|
||||
;#Zero_padding: **Only for E5a** Avoids power loss and doppler ambiguity in bit transitions by correlating one code with twice the input data length, ensuring that at least one full code is present without transitions.
|
||||
;#If set to 1 it is ON, if set to 0 it is OFF.
|
||||
Acquisition_Galileo.Zero_padding=0
|
||||
|
||||
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking]
|
||||
Tracking_Galileo.implementation=Galileo_E5a_DLL_PLL_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking_Galileo.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking_Galileo.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking_Galileo.dump=true
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking_Galileo.dump_filename=./tracking_ch_
|
||||
|
||||
;#pll_bw_hz_init: **Only for E5a** PLL loop filter bandwidth during initialization [Hz]
|
||||
Tracking_Galileo.pll_bw_hz_init=20.0;
|
||||
;#dll_bw_hz_init: **Only for E5a** DLL loop filter bandwidth during initialization [Hz]
|
||||
Tracking_Galileo.dll_bw_hz_init=20.0;
|
||||
;#dll_ti_ms: **Only for E5a** loop filter integration time after initialization (secondary code delay search)[ms]
|
||||
;Tracking_Galileo.ti_ms=3;
|
||||
Tracking_Galileo.ti_ms=1;
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
;Tracking.pll_bw_hz=5.0;
|
||||
Tracking_Galileo.pll_bw_hz=20.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
;Tracking.dll_bw_hz=2.0;
|
||||
Tracking_Galileo.dll_bw_hz=20.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
;Tracking_Galileo.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking_Galileo.order=2;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5]
|
||||
Tracking_Galileo.early_late_space_chips=0.5;
|
||||
|
||||
;######### TELEMETRY DECODER CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A.
|
||||
TelemetryDecoder_Galileo.implementation=Galileo_E5a_Telemetry_Decoder
|
||||
TelemetryDecoder_Galileo.dump=false
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
||||
;Use [Galileo_E1B_Observables] for E5a also.
|
||||
Observables.implementation=Galileo_E1B_Observables
|
||||
|
||||
;#dump: Enable or disable the Observables internal binary data file logging [true] or [false]
|
||||
Observables.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename.
|
||||
Observables.dump_filename=./observables.dat
|
||||
|
||||
|
||||
;######### PVT CONFIG ############
|
||||
;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version.
|
||||
;Use [GALILEO_E1_PVT] for E5a also.
|
||||
PVT.implementation=GALILEO_E1_PVT
|
||||
|
||||
;#averaging_depth: Number of PVT observations in the moving average algorithm
|
||||
PVT.averaging_depth=100
|
||||
|
||||
;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]
|
||||
PVT.flag_averaging=true
|
||||
|
||||
;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms]
|
||||
PVT.output_rate_ms=100
|
||||
|
||||
;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms.
|
||||
PVT.display_rate_ms=500
|
||||
|
||||
;# RINEX, KML, and NMEA output configuration
|
||||
|
||||
;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump.
|
||||
PVT.dump_filename=./PVT
|
||||
|
||||
;#nmea_dump_filename: NMEA log path and filename
|
||||
PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea;
|
||||
|
||||
;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one)
|
||||
PVT.flag_nmea_tty_port=true;
|
||||
|
||||
;#nmea_dump_devname: serial device descriptor for NMEA logging
|
||||
PVT.nmea_dump_devname=/dev/pts/4
|
||||
|
||||
|
||||
;#dump: Enable or disable the PVT internal binary data file logging [true] or [false]
|
||||
PVT.dump=false
|
||||
|
||||
;######### OUTPUT_FILTER CONFIG ############
|
||||
;# Receiver output filter: Leave this block disabled in this version
|
||||
OutputFilter.implementation=Null_Sink_Output_Filter
|
||||
OutputFilter.filename=data/gnss-sdr.dat
|
||||
OutputFilter.item_type=gr_complex
|
328
conf/gnss-sdr_Hybrid_nsr.conf
Normal file
328
conf/gnss-sdr_Hybrid_nsr.conf
Normal file
@ -0,0 +1,328 @@
|
||||
; Default configuration file
|
||||
; You can define your own receiver and invoke it by doing
|
||||
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
|
||||
;
|
||||
|
||||
[GNSS-SDR]
|
||||
|
||||
;######### GLOBAL OPTIONS ##################
|
||||
;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz].
|
||||
;GNSS-SDR.internal_fs_hz=6826700
|
||||
GNSS-SDR.internal_fs_hz=2560000
|
||||
;GNSS-SDR.internal_fs_hz=4096000
|
||||
;GNSS-SDR.internal_fs_hz=5120000
|
||||
|
||||
;######### CONTROL_THREAD CONFIG ############
|
||||
ControlThread.wait_for_flowgraph=false
|
||||
;######### SIGNAL_SOURCE CONFIG ############
|
||||
;#implementation: Use [File_Signal_Source] [Nsr_File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental)
|
||||
SignalSource.implementation=Nsr_File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
SignalSource.filename=../../../Documents/workspace/code2/trunk/data/E1L1_FE0_Band0.stream
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
SignalSource.item_type=byte
|
||||
|
||||
;#sampling_frequency: Original Signal sampling frequency in [Hz]
|
||||
SignalSource.sampling_frequency=20480000
|
||||
|
||||
;#freq: RF front-end center frequency in [Hz]
|
||||
SignalSource.freq=1575420000
|
||||
|
||||
;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0)
|
||||
SignalSource.subdevice=B:0
|
||||
|
||||
;#samples: Number of samples to be processed. Notice that 0 indicates the entire file.
|
||||
SignalSource.samples=0
|
||||
|
||||
;#repeat: Repeat the processing file. Disable this option in this version
|
||||
SignalSource.repeat=false
|
||||
|
||||
;#dump: Dump the Signal source data to a file. Disable this option in this version
|
||||
SignalSource.dump=false
|
||||
|
||||
SignalSource.dump_filename=../data/signal_source.dat
|
||||
|
||||
|
||||
;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing.
|
||||
; it helps to not overload the CPU, but the processing time will be longer.
|
||||
SignalSource.enable_throttle_control=false
|
||||
|
||||
|
||||
;######### SIGNAL_CONDITIONER CONFIG ############
|
||||
;## It holds blocks to change data type, filter and resample input data.
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Signal_Conditioner]
|
||||
;#[Pass_Through] disables this block and the [DataTypeAdapter], [InputFilter] and [Resampler] blocks
|
||||
;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks
|
||||
SignalConditioner.implementation=Signal_Conditioner
|
||||
|
||||
;######### DATA_TYPE_ADAPTER CONFIG ############
|
||||
;## Changes the type of input data.
|
||||
;#implementation: [Pass_Through] disables this block
|
||||
DataTypeAdapter.implementation=Pass_Through
|
||||
DataTypeAdapter.item_type=float
|
||||
|
||||
;######### INPUT_FILTER CONFIG ############
|
||||
;## Filter the input data. Can be combined with frequency translation for IF signals
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Fir_Filter] or [Freq_Xlating_Fir_Filter]
|
||||
;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation
|
||||
;# that shifts IF down to zero Hz.
|
||||
|
||||
InputFilter.implementation=Freq_Xlating_Fir_Filter
|
||||
|
||||
;#dump: Dump the filtered data to a file.
|
||||
InputFilter.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename.
|
||||
InputFilter.dump_filename=../data/input_filter.dat
|
||||
|
||||
;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation.
|
||||
;#These options are based on parameters of gnuradio's function: gr_remez.
|
||||
;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse
|
||||
;#reponse given a set of band edges, the desired reponse on those bands,
|
||||
;#and the weight given to the error in those bands.
|
||||
|
||||
;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version.
|
||||
InputFilter.input_item_type=float
|
||||
|
||||
;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version.
|
||||
InputFilter.output_item_type=gr_complex
|
||||
|
||||
;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version.
|
||||
InputFilter.taps_item_type=float
|
||||
|
||||
;#number_of_taps: Number of taps in the filter. Increasing this parameter increases the processing time
|
||||
InputFilter.number_of_taps=5
|
||||
|
||||
;#number_of _bands: Number of frequency bands in the filter.
|
||||
InputFilter.number_of_bands=2
|
||||
|
||||
;#bands: frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...].
|
||||
;#Frequency is in the range [0, 1], with 1 being the Nyquist frequency (Fs/2)
|
||||
;#The number of band_begin and band_end elements must match the number of bands
|
||||
|
||||
InputFilter.band1_begin=0.0
|
||||
InputFilter.band1_end=0.45
|
||||
InputFilter.band2_begin=0.55
|
||||
InputFilter.band2_end=1.0
|
||||
|
||||
;#ampl: desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...].
|
||||
;#The number of ampl_begin and ampl_end elements must match the number of bands
|
||||
|
||||
InputFilter.ampl1_begin=1.0
|
||||
InputFilter.ampl1_end=1.0
|
||||
InputFilter.ampl2_begin=0.0
|
||||
InputFilter.ampl2_end=0.0
|
||||
|
||||
;#band_error: weighting applied to each band (usually 1).
|
||||
;#The number of band_error elements must match the number of bands
|
||||
InputFilter.band1_error=1.0
|
||||
InputFilter.band2_error=1.0
|
||||
|
||||
;#filter_type: one of "bandpass", "hilbert" or "differentiator"
|
||||
InputFilter.filter_type=bandpass
|
||||
|
||||
;#grid_density: determines how accurately the filter will be constructed.
|
||||
;The minimum value is 16; higher values are slower to compute the filter.
|
||||
InputFilter.grid_density=16
|
||||
|
||||
;# Original sampling frequency stored in the signal file
|
||||
InputFilter.sampling_frequency=20480000
|
||||
|
||||
;#The following options are used only in Freq_Xlating_Fir_Filter implementation.
|
||||
;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz
|
||||
|
||||
InputFilter.IF=5499998.47412109
|
||||
|
||||
;# Decimation factor after the frequency tranaslating block
|
||||
InputFilter.decimation_factor=8
|
||||
|
||||
|
||||
;######### RESAMPLER CONFIG ############
|
||||
;## Resamples the input data.
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Direct_Resampler]
|
||||
;#[Pass_Through] disables this block
|
||||
;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation
|
||||
Resampler.implementation=Pass_Through
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available GPS satellite channels.
|
||||
Channels_GPS.count=8
|
||||
;#count: Number of available Galileo satellite channels.
|
||||
Channels_Galileo.count=8
|
||||
;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
|
||||
Channels.in_acquisition=1
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
Channel.system=GPS, Galileo
|
||||
|
||||
;#signal:
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel.signal=1B
|
||||
|
||||
|
||||
;######### GPS ACQUISITION CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition_GPS.dump=false
|
||||
;#filename: Log path and filename
|
||||
Acquisition_GPS.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition_GPS.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition_GPS.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition_GPS.sampled_ms=1
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition_GPS.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
;#threshold: Acquisition threshold
|
||||
Acquisition_GPS.threshold=0.0075
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
;Acquisition_GPS.pfa=0.01
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition_GPS.doppler_max=10000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition_GPS.doppler_step=500
|
||||
|
||||
|
||||
;######### GALILEO ACQUISITION CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition_Galileo.dump=false
|
||||
;#filename: Log path and filename
|
||||
Acquisition_Galileo.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition_Galileo.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition_Galileo.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition_Galileo.sampled_ms=4
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition_Galileo.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition
|
||||
;#threshold: Acquisition threshold
|
||||
;Acquisition_Galileo.threshold=0
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition_Galileo.pfa=0.0000002
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition_Galileo.doppler_max=15000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition_Galileo.doppler_step=125
|
||||
|
||||
;######### TRACKING GPS CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
|
||||
Tracking_GPS.implementation=GPS_L1_CA_DLL_PLL_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking_GPS.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking_GPS.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking_GPS.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking_GPS.dump_filename=../data/epl_tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking_GPS.pll_bw_hz=45.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking_GPS.dll_bw_hz=2.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking_GPS.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking_GPS.order=3;
|
||||
|
||||
;######### TRACKING GALILEO CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
|
||||
Tracking_Galileo.implementation=Galileo_E1_DLL_PLL_VEML_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking_Galileo.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking_Galileo.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking_Galileo.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking_Galileo.dump_filename=../data/veml_tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking_Galileo.pll_bw_hz=15.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking_Galileo.dll_bw_hz=2.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking_Galileo.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking_Galileo.order=3;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo
|
||||
Tracking_Galileo.early_late_space_chips=0.15;
|
||||
|
||||
;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6]
|
||||
Tracking_Galileo.very_early_late_space_chips=0.6;
|
||||
|
||||
|
||||
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A
|
||||
TelemetryDecoder_GPS.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder_GPS.dump=false
|
||||
;#decimation factor
|
||||
TelemetryDecoder_GPS.decimation_factor=4;
|
||||
|
||||
;######### TELEMETRY DECODER GALILEO CONFIG ############
|
||||
;#implementation: Use [Galileo_E1B_Telemetry_Decoder] for Galileo E1B
|
||||
TelemetryDecoder_Galileo.implementation=Galileo_E1B_Telemetry_Decoder
|
||||
TelemetryDecoder_Galileo.dump=false
|
||||
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
||||
Observables.implementation=Hybrid_Observables
|
||||
|
||||
;#dump: Enable or disable the Observables internal binary data file logging [true] or [false]
|
||||
Observables.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename.
|
||||
Observables.dump_filename=./observables.dat
|
||||
|
||||
|
||||
;######### PVT CONFIG ############
|
||||
;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version.
|
||||
PVT.implementation=Hybrid_PVT
|
||||
|
||||
;#averaging_depth: Number of PVT observations in the moving average algorithm
|
||||
PVT.averaging_depth=10
|
||||
|
||||
;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]
|
||||
PVT.flag_averaging=false
|
||||
|
||||
;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms]
|
||||
PVT.output_rate_ms=10;
|
||||
|
||||
;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms.
|
||||
PVT.display_rate_ms=500;
|
||||
|
||||
;#dump: Enable or disable the PVT internal binary data file logging [true] or [false]
|
||||
PVT.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump.
|
||||
PVT.dump_filename=./PVT
|
||||
|
||||
;######### OUTPUT_FILTER CONFIG ############
|
||||
;# Receiver output filter: Leave this block disabled in this version
|
||||
OutputFilter.implementation=Null_Sink_Output_Filter
|
||||
OutputFilter.filename=data/gnss-sdr.dat
|
||||
OutputFilter.item_type=gr_complex
|
341
conf/gnss-sdr_Hybrid_short.conf
Normal file
341
conf/gnss-sdr_Hybrid_short.conf
Normal file
@ -0,0 +1,341 @@
|
||||
; Default configuration file
|
||||
; You can define your own receiver and invoke it by doing
|
||||
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
|
||||
;
|
||||
|
||||
[GNSS-SDR]
|
||||
|
||||
;######### GLOBAL OPTIONS ##################
|
||||
;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz].
|
||||
GNSS-SDR.internal_fs_hz=4000000
|
||||
|
||||
;######### CONTROL_THREAD CONFIG ############
|
||||
ControlThread.wait_for_flowgraph=false
|
||||
|
||||
;######### SIGNAL_SOURCE CONFIG ############
|
||||
;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental)
|
||||
SignalSource.implementation=File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
SignalSource.filename=../data/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
SignalSource.item_type=short
|
||||
|
||||
;#sampling_frequency: Original Signal sampling frequency in [Hz]
|
||||
SignalSource.sampling_frequency=4000000
|
||||
|
||||
;#freq: RF front-end center frequency in [Hz]
|
||||
SignalSource.freq=1575420000
|
||||
|
||||
;#gain: Front-end Gain in [dB]
|
||||
SignalSource.gain=60
|
||||
|
||||
;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0)
|
||||
SignalSource.subdevice=B:0
|
||||
|
||||
;#samples: Number of samples to be processed. Notice that 0 indicates the entire file.
|
||||
SignalSource.samples=0
|
||||
|
||||
;#repeat: Repeat the processing file. Disable this option in this version
|
||||
SignalSource.repeat=false
|
||||
|
||||
;#dump: Dump the Signal source data to a file. Disable this option in this version
|
||||
SignalSource.dump=false
|
||||
|
||||
SignalSource.dump_filename=../data/signal_source.dat
|
||||
|
||||
|
||||
;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing.
|
||||
; it helps to not overload the CPU, but the processing time will be longer.
|
||||
SignalSource.enable_throttle_control=false
|
||||
|
||||
|
||||
;######### SIGNAL_CONDITIONER CONFIG ############
|
||||
;## It holds blocks to change data type, filter and resample input data.
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Signal_Conditioner]
|
||||
;#[Pass_Through] disables this block and the [DataTypeAdapter], [InputFilter] and [Resampler] blocks
|
||||
;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks
|
||||
SignalConditioner.implementation=Signal_Conditioner
|
||||
|
||||
;######### DATA_TYPE_ADAPTER CONFIG ############
|
||||
;## Changes the type of input data. Please disable it in this version.
|
||||
;#implementation: [Pass_Through] disables this block
|
||||
DataTypeAdapter.implementation=Ishort_To_Complex
|
||||
|
||||
;######### INPUT_FILTER CONFIG ############
|
||||
;## Filter the input data. Can be combined with frequency translation for IF signals
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Fir_Filter] or [Freq_Xlating_Fir_Filter]
|
||||
;#[Pass_Through] disables this block
|
||||
;#[Fir_Filter] enables a FIR Filter
|
||||
;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation that shifts IF down to zero Hz.
|
||||
|
||||
;InputFilter.implementation=Fir_Filter
|
||||
;InputFilter.implementation=Freq_Xlating_Fir_Filter
|
||||
InputFilter.implementation=Pass_Through
|
||||
|
||||
;#dump: Dump the filtered data to a file.
|
||||
InputFilter.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename.
|
||||
InputFilter.dump_filename=../data/input_filter.dat
|
||||
|
||||
;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation.
|
||||
;#These options are based on parameters of gnuradio's function: gr_remez.
|
||||
;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands.
|
||||
|
||||
;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version.
|
||||
InputFilter.input_item_type=gr_complex
|
||||
|
||||
;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version.
|
||||
InputFilter.output_item_type=gr_complex
|
||||
|
||||
;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version.
|
||||
InputFilter.taps_item_type=float
|
||||
|
||||
;#number_of_taps: Number of taps in the filter. Increasing this parameter increases the processing time
|
||||
InputFilter.number_of_taps=5
|
||||
|
||||
;#number_of _bands: Number of frequency bands in the filter.
|
||||
InputFilter.number_of_bands=2
|
||||
|
||||
;#bands: frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...].
|
||||
;#Frequency is in the range [0, 1], with 1 being the Nyquist frequency (Fs/2)
|
||||
;#The number of band_begin and band_end elements must match the number of bands
|
||||
|
||||
InputFilter.band1_begin=0.0
|
||||
InputFilter.band1_end=0.45
|
||||
InputFilter.band2_begin=0.55
|
||||
InputFilter.band2_end=1.0
|
||||
|
||||
;#ampl: desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...].
|
||||
;#The number of ampl_begin and ampl_end elements must match the number of bands
|
||||
|
||||
InputFilter.ampl1_begin=1.0
|
||||
InputFilter.ampl1_end=1.0
|
||||
InputFilter.ampl2_begin=0.0
|
||||
InputFilter.ampl2_end=0.0
|
||||
|
||||
;#band_error: weighting applied to each band (usually 1).
|
||||
;#The number of band_error elements must match the number of bands
|
||||
InputFilter.band1_error=1.0
|
||||
InputFilter.band2_error=1.0
|
||||
|
||||
;#filter_type: one of "bandpass", "hilbert" or "differentiator"
|
||||
InputFilter.filter_type=bandpass
|
||||
|
||||
;#grid_density: determines how accurately the filter will be constructed.
|
||||
;The minimum value is 16; higher values are slower to compute the filter.
|
||||
InputFilter.grid_density=16
|
||||
|
||||
;#The following options are used only in Freq_Xlating_Fir_Filter implementation.
|
||||
;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz
|
||||
|
||||
InputFilter.sampling_frequency=4000000
|
||||
InputFilter.IF=0
|
||||
|
||||
|
||||
|
||||
;######### RESAMPLER CONFIG ############
|
||||
;## Resamples the input data.
|
||||
|
||||
;#implementation: Use [Pass_Through] or [Direct_Resampler]
|
||||
;#[Pass_Through] disables this block
|
||||
;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation
|
||||
;Resampler.implementation=Direct_Resampler
|
||||
Resampler.implementation=Pass_Through
|
||||
|
||||
;#dump: Dump the resamplered data to a file.
|
||||
Resampler.dump=false
|
||||
;#dump_filename: Log path and filename.
|
||||
Resampler.dump_filename=../data/resampler.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Resampler.item_type=gr_complex
|
||||
|
||||
;#sample_freq_in: the sample frequency of the input signal
|
||||
Resampler.sample_freq_in=4000000
|
||||
|
||||
;#sample_freq_out: the desired sample frequency of the output signal
|
||||
Resampler.sample_freq_out=4000000
|
||||
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available GPS satellite channels.
|
||||
Channels_GPS.count=2
|
||||
;#count: Number of available Galileo satellite channels.
|
||||
Channels_Galileo.count=2
|
||||
;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
|
||||
Channels.in_acquisition=1
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
Channel.system=GPS, Galileo
|
||||
|
||||
;#signal:
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel.signal=1B
|
||||
|
||||
|
||||
;######### GPS ACQUISITION CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition_GPS.dump=false
|
||||
;#filename: Log path and filename
|
||||
Acquisition_GPS.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition_GPS.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition_GPS.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition_GPS.sampled_ms=1
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition_GPS.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
;#threshold: Acquisition threshold
|
||||
Acquisition_GPS.threshold=0.0075
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
;Acquisition_GPS.pfa=0.01
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition_GPS.doppler_max=10000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition_GPS.doppler_step=500
|
||||
|
||||
|
||||
;######### GALILEO ACQUISITION CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition_Galileo.dump=false
|
||||
;#filename: Log path and filename
|
||||
Acquisition_Galileo.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition_Galileo.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition_Galileo.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition_Galileo.sampled_ms=4
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition_Galileo.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition
|
||||
;#threshold: Acquisition threshold
|
||||
;Acquisition_Galileo.threshold=0
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition_Galileo.pfa=0.0000008
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition_Galileo.doppler_max=15000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition_Galileo.doppler_step=125
|
||||
|
||||
;######### TRACKING GPS CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
|
||||
Tracking_GPS.implementation=GPS_L1_CA_DLL_PLL_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking_GPS.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking_GPS.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking_GPS.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking_GPS.dump_filename=../data/epl_tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking_GPS.pll_bw_hz=45.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking_GPS.dll_bw_hz=4.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking_GPS.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking_GPS.order=3;
|
||||
|
||||
;######### TRACKING GALILEO CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
|
||||
Tracking_Galileo.implementation=Galileo_E1_DLL_PLL_VEML_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking_Galileo.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking_Galileo.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking_Galileo.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking_Galileo.dump_filename=../data/veml_tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking_Galileo.pll_bw_hz=15.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking_Galileo.dll_bw_hz=2.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking_Galileo.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking_Galileo.order=3;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo
|
||||
Tracking_Galileo.early_late_space_chips=0.15;
|
||||
|
||||
;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6]
|
||||
Tracking_Galileo.very_early_late_space_chips=0.6;
|
||||
|
||||
|
||||
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A
|
||||
TelemetryDecoder_GPS.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder_GPS.dump=false
|
||||
;#decimation factor
|
||||
TelemetryDecoder_GPS.decimation_factor=4;
|
||||
|
||||
;######### TELEMETRY DECODER GALILEO CONFIG ############
|
||||
;#implementation: Use [Galileo_E1B_Telemetry_Decoder] for Galileo E1B
|
||||
TelemetryDecoder_Galileo.implementation=Galileo_E1B_Telemetry_Decoder
|
||||
TelemetryDecoder_Galileo.dump=false
|
||||
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
||||
Observables.implementation=Hybrid_Observables
|
||||
|
||||
;#dump: Enable or disable the Observables internal binary data file logging [true] or [false]
|
||||
Observables.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename.
|
||||
Observables.dump_filename=./observables.dat
|
||||
|
||||
|
||||
;######### PVT CONFIG ############
|
||||
;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version.
|
||||
PVT.implementation=Hybrid_PVT
|
||||
|
||||
;#averaging_depth: Number of PVT observations in the moving average algorithm
|
||||
PVT.averaging_depth=10
|
||||
|
||||
;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]
|
||||
PVT.flag_averaging=false
|
||||
|
||||
;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms]
|
||||
PVT.output_rate_ms=100;
|
||||
|
||||
;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms.
|
||||
PVT.display_rate_ms=500;
|
||||
|
||||
;#dump: Enable or disable the PVT internal binary data file logging [true] or [false]
|
||||
PVT.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump.
|
||||
PVT.dump_filename=./PVT
|
||||
|
||||
;######### OUTPUT_FILTER CONFIG ############
|
||||
;# Receiver output filter: Leave this block disabled in this version
|
||||
OutputFilter.implementation=Null_Sink_Output_Filter
|
||||
OutputFilter.filename=data/gnss-sdr.dat
|
||||
OutputFilter.item_type=gr_complex
|
@ -17,7 +17,7 @@ ControlThread.wait_for_flowgraph=false
|
||||
SignalSource.implementation=File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
SignalSource.filename=/Users/fehrdan/GNSS/dev/data/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat
|
||||
SignalSource.filename=../data/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples.
|
||||
;#Use gr_complex for 32 bits float I/Q or short for I/Q interleaved short integer.
|
||||
@ -175,70 +175,16 @@ Resampler.sample_freq_out=4000000
|
||||
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available satellite channels.
|
||||
Channels.count=3
|
||||
;#in_acquisition: Number of channels simultaneously acquiring
|
||||
Channels.in_acquisition=3
|
||||
;#system: GPS, GLONASS, Galileo, SBAS or Compass
|
||||
;#count: Number of available GPS satellite channels.
|
||||
Channels_GPS.count=6
|
||||
;#count: Number of available Galileo satellite channels.
|
||||
Channels_Galileo.count=0
|
||||
;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
|
||||
Channels.in_acquisition=1
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
Channel.system=GPS
|
||||
Channel.system=GPS, SBAS
|
||||
|
||||
;#signal:
|
||||
;# "1C" GPS L1 C/A
|
||||
;# "1P" GPS L1 P
|
||||
;# "1W" GPS L1 Z-tracking and similar (AS on)
|
||||
;# "1Y" GPS L1 Y
|
||||
;# "1M" GPS L1 M
|
||||
;# "1N" GPS L1 codeless
|
||||
;# "2C" GPS L2 C/A
|
||||
;# "2D" GPS L2 L1(C/A)+(P2-P1) semi-codeless
|
||||
;# "2S" GPS L2 L2C (M)
|
||||
;# "2L" GPS L2 L2C (L)
|
||||
;# "2X" GPS L2 L2C (M+L)
|
||||
;# "2P" GPS L2 P
|
||||
;# "2W" GPS L2 Z-tracking and similar (AS on)
|
||||
;# "2Y" GPS L2 Y
|
||||
;# "2M" GPS GPS L2 M
|
||||
;# "2N" GPS L2 codeless
|
||||
;# "5I" GPS L5 I
|
||||
;# "5Q" GPS L5 Q
|
||||
;# "5X" GPS L5 I+Q
|
||||
;# "1C" GLONASS G1 C/A
|
||||
;# "1P" GLONASS G1 P
|
||||
;# "2C" GLONASS G2 C/A (Glonass M)
|
||||
;# "2P" GLONASS G2 P
|
||||
;# "1A" GALILEO E1 A (PRS)
|
||||
;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL)
|
||||
;# "1C" GALILEO E1 C (no data)
|
||||
;# "1X" GALILEO E1 B+C
|
||||
;# "1Z" GALILEO E1 A+B+C
|
||||
;# "5I" GALILEO E5a I (F/NAV OS)
|
||||
;# "5Q" GALILEO E5a Q (no data)
|
||||
;# "5X" GALILEO E5a I+Q
|
||||
;# "7I" GALILEO E5b I
|
||||
;# "7Q" GALILEO E5b Q
|
||||
;# "7X" GALILEO E5b I+Q
|
||||
;# "8I" GALILEO E5 I
|
||||
;# "8Q" GALILEO E5 Q
|
||||
;# "8X" GALILEO E5 I+Q
|
||||
;# "6A" GALILEO E6 A
|
||||
;# "6B" GALILEO E6 B
|
||||
;# "6C" GALILEO E6 C
|
||||
;# "6X" GALILEO E6 B+C
|
||||
;# "6Z" GALILEO E6 A+B+C
|
||||
;# "1C" SBAS L1 C/A
|
||||
;# "5I" SBAS L5 I
|
||||
;# "5Q" SBAS L5 Q
|
||||
;# "5X" SBAS L5 I+Q
|
||||
;# "2I" COMPASS E2 I
|
||||
;# "2Q" COMPASS E2 Q
|
||||
;# "2X" COMPASS E2 IQ
|
||||
;# "7I" COMPASS E5b I
|
||||
;# "7Q" COMPASS E5b Q
|
||||
;# "7X" COMPASS E5b IQ
|
||||
;# "6I" COMPASS E6 I
|
||||
;# "6Q" COMPASS E6 Q
|
||||
;# "6X" COMPASS E6 IQ
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel.signal=1C
|
||||
|
||||
@ -291,140 +237,66 @@ Channel5.signal=1C
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition.dump=false
|
||||
Acquisition_GPS.dump=false
|
||||
;#filename: Log path and filename
|
||||
Acquisition.dump_filename=../data/acq_dump.dat
|
||||
Acquisition_GPS.dump_filename=../data/acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition.item_type=gr_complex
|
||||
Acquisition_GPS.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition.if=0
|
||||
Acquisition_GPS.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition.sampled_ms=1
|
||||
Acquisition_GPS.sampled_ms=1
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition_GPS.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
;#threshold: Acquisition threshold
|
||||
Acquisition.threshold=0.005
|
||||
Acquisition_GPS.threshold=0.005
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition.pfa=0.0001
|
||||
Acquisition_GPS.pfa=0.0001
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition.doppler_max=10000
|
||||
Acquisition_GPS.doppler_max=10000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition.doppler_step=500
|
||||
Acquisition_GPS.doppler_step=500
|
||||
|
||||
|
||||
;######### ACQUISITION CHANNELS CONFIG ######
|
||||
;#The following options are specific to each channel and overwrite the generic options
|
||||
|
||||
|
||||
;######### ACQUISITION CH 0 CONFIG ############
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition]
|
||||
Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition0.threshold=0.005
|
||||
Acquisition0.pfa=0.00001
|
||||
Acquisition0.doppler_max=10000
|
||||
Acquisition0.doppler_step=250
|
||||
;#repeat_satellite: Use only jointly with the satellte PRN ID option.
|
||||
Acquisition0.repeat_satellite=false
|
||||
|
||||
;######### ACQUISITION CH 1 CONFIG ############
|
||||
Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition1.threshold=0.005
|
||||
Acquisition1.pfa=0.00001
|
||||
Acquisition1.doppler_max=10000
|
||||
Acquisition1.doppler_step=250
|
||||
Acquisition1.repeat_satellite=true
|
||||
|
||||
;######### ACQUISITION CH 2 CONFIG ############
|
||||
Acquisition2.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition2.threshold=0.005
|
||||
Acquisition2.pfa=0.00001
|
||||
Acquisition2.doppler_max=10000
|
||||
Acquisition2.doppler_step=250
|
||||
Acquisition2.repeat_satellite=true
|
||||
|
||||
;######### ACQUISITION CH 3 CONFIG ############
|
||||
Acquisition3.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition3.threshold=0.005
|
||||
Acquisition3.pfa=0.001
|
||||
Acquisition3.doppler_max=10000
|
||||
Acquisition3.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 4 CONFIG ############
|
||||
Acquisition4.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition4.threshold=0.005
|
||||
Acquisition4.pfa=0.001
|
||||
Acquisition4.doppler_max=10000
|
||||
Acquisition4.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 5 CONFIG ############
|
||||
Acquisition5.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition5.threshold=60
|
||||
Acquisition5.doppler_max=10000
|
||||
Acquisition5.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 6 CONFIG ############
|
||||
Acquisition6.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition6.threshold=0.005
|
||||
Acquisition6.pfa=0.001
|
||||
Acquisition6.doppler_max=10000
|
||||
Acquisition6.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 7 CONFIG ############
|
||||
Acquisition7.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition7.threshold=0.005
|
||||
Acquisition7.pfa=0.001
|
||||
Acquisition7.doppler_max=10000
|
||||
Acquisition7.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 8 CONFIG ############
|
||||
Acquisition8.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition8.threshold=0.005
|
||||
Acquisition8.pfa=0.001
|
||||
Acquisition8.doppler_max=10000
|
||||
Acquisition8.doppler_step=250
|
||||
|
||||
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking]
|
||||
Tracking.implementation=GPS_L1_CA_DLL_PLL_Optim_Tracking
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
|
||||
Tracking_GPS.implementation=GPS_L1_CA_DLL_PLL_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking.item_type=gr_complex
|
||||
Tracking_GPS.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking.if=0
|
||||
Tracking_GPS.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking.dump=true
|
||||
Tracking_GPS.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking.dump_filename=../data/tracking/tracking_ch_
|
||||
Tracking_GPS.dump_filename=../data/epl_tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking.pll_bw_hz=25.0;
|
||||
Tracking_GPS.pll_bw_hz=45.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking.dll_bw_hz=2.0;
|
||||
Tracking_GPS.dll_bw_hz=3.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking.fll_bw_hz=5.0;
|
||||
Tracking_GPS.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking.order=3;
|
||||
Tracking_GPS.order=2;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5]
|
||||
Tracking.early_late_space_chips=0.5;
|
||||
|
||||
;######### TELEMETRY DECODER CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A.
|
||||
TelemetryDecoder.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder.dump=false
|
||||
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A
|
||||
TelemetryDecoder_GPS.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder_GPS.dump=false
|
||||
;#decimation factor
|
||||
TelemetryDecoder_GPS.decimation_factor=1;
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
@ -176,10 +176,19 @@ Resampler.sample_freq_out=4000000
|
||||
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available satellite channels.
|
||||
Channels.count=5
|
||||
;#in_acquisition: Number of channels simultaneously acquiring
|
||||
;#count: Number of available GPS satellite channels.
|
||||
Channels_GPS.count=8
|
||||
;#count: Number of available Galileo satellite channels.
|
||||
Channels_Galileo.count=0
|
||||
;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
|
||||
Channels.in_acquisition=1
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
Channel.system=GPS
|
||||
|
||||
;#signal:
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel.signal=1C
|
||||
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
@ -286,124 +295,66 @@ Channel5.signal=1C
|
||||
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
;######### GPS ACQUISITION CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition.dump=false
|
||||
Acquisition_GPS.dump=false
|
||||
;#filename: Log path and filename
|
||||
Acquisition.dump_filename=./acq_dump.dat
|
||||
Acquisition_GPS.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition.item_type=gr_complex
|
||||
Acquisition_GPS.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition.if=0
|
||||
Acquisition_GPS.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition.sampled_ms=1
|
||||
|
||||
;######### ACQUISITION CHANNELS CONFIG ######
|
||||
|
||||
;######### ACQUISITION CH 0 CONFIG ############
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition]
|
||||
Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition_GPS.sampled_ms=1
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
Acquisition_GPS.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
;#threshold: Acquisition threshold
|
||||
Acquisition0.threshold=50
|
||||
Acquisition_GPS.threshold=0.0075
|
||||
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
|
||||
;Acquisition_GPS.pfa=0.01
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition0.doppler_max=10000
|
||||
Acquisition_GPS.doppler_max=10000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition0.doppler_step=250
|
||||
;#repeat_satellite: Use only jointly with the satellte PRN ID option.
|
||||
Acquisition_GPS.doppler_step=500
|
||||
;######### ACQUISITION CHANNELS CONFIG ######
|
||||
;#The following options are specific to each channel and overwrite the generic options
|
||||
|
||||
|
||||
;######### ACQUISITION CH 1 CONFIG ############
|
||||
Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition1.threshold=50
|
||||
Acquisition1.doppler_max=10000
|
||||
Acquisition1.doppler_step=250
|
||||
;######### TRACKING GPS CONFIG ############
|
||||
|
||||
|
||||
;######### ACQUISITION CH 2 CONFIG ############
|
||||
Acquisition2.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition2.threshold=50
|
||||
Acquisition2.doppler_max=10000
|
||||
Acquisition2.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 3 CONFIG ############
|
||||
Acquisition3.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition3.threshold=50
|
||||
Acquisition3.doppler_max=10000
|
||||
Acquisition3.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 4 CONFIG ############
|
||||
Acquisition4.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition4.threshold=50
|
||||
Acquisition4.doppler_max=10000
|
||||
Acquisition4.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 5 CONFIG ############
|
||||
Acquisition5.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition5.threshold=50
|
||||
Acquisition5.doppler_max=10000
|
||||
Acquisition5.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 6 CONFIG ############
|
||||
Acquisition6.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition6.threshold=70
|
||||
Acquisition6.doppler_max=10000
|
||||
Acquisition6.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 7 CONFIG ############
|
||||
Acquisition7.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition7.threshold=70
|
||||
Acquisition7.doppler_max=10000
|
||||
Acquisition7.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 8 CONFIG ############
|
||||
Acquisition8.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition8.threshold=70
|
||||
Acquisition8.doppler_max=10000
|
||||
Acquisition8.doppler_step=250
|
||||
|
||||
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking]
|
||||
Tracking.implementation=GPS_L1_CA_DLL_FLL_PLL_Tracking
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
|
||||
Tracking_GPS.implementation=GPS_L1_CA_DLL_PLL_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking.item_type=gr_complex
|
||||
Tracking_GPS.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking.if=0
|
||||
Tracking_GPS.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking.dump=false
|
||||
Tracking_GPS.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking.dump_filename=./tracking_ch_
|
||||
Tracking_GPS.dump_filename=../data/epl_tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking.pll_bw_hz=50.0;
|
||||
Tracking_GPS.pll_bw_hz=45.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking.dll_bw_hz=2.0;
|
||||
Tracking_GPS.dll_bw_hz=2.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking.fll_bw_hz=10.0;
|
||||
Tracking_GPS.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking.order=3;
|
||||
Tracking_GPS.order=3;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5]
|
||||
Tracking.early_late_space_chips=0.5;
|
||||
|
||||
;######### TELEMETRY DECODER CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A.
|
||||
TelemetryDecoder.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder.dump=false
|
||||
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A
|
||||
TelemetryDecoder_GPS.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder_GPS.dump=false
|
||||
;#decimation factor
|
||||
TelemetryDecoder_GPS.decimation_factor=1;
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
||||
@ -421,13 +372,13 @@ Observables.dump_filename=./observables.dat
|
||||
PVT.implementation=GPS_L1_CA_PVT
|
||||
|
||||
;#averaging_depth: Number of PVT observations in the moving average algorithm
|
||||
PVT.averaging_depth=10
|
||||
PVT.averaging_depth=100
|
||||
|
||||
;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]
|
||||
PVT.flag_averaging=true
|
||||
PVT.flag_averaging=false
|
||||
|
||||
;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms]
|
||||
PVT.output_rate_ms=100
|
||||
PVT.output_rate_ms=10
|
||||
|
||||
;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms.
|
||||
PVT.display_rate_ms=500
|
||||
@ -441,7 +392,7 @@ PVT.dump_filename=./PVT
|
||||
PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea;
|
||||
|
||||
;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one)
|
||||
PVT.flag_nmea_tty_port=true;
|
||||
PVT.flag_nmea_tty_port=false;
|
||||
|
||||
;#nmea_dump_devname: serial device descriptor for NMEA logging
|
||||
PVT.nmea_dump_devname=/dev/pts/4
|
@ -24,9 +24,9 @@
|
||||
All the current GPS Interface Control Documents can be downloaded from <a href="http://www.gps.gov" target="_blank">GPS.gov</a>, the official U.S. Government webpage for GPS.
|
||||
|
||||
|
||||
\li GPS L1 and L2C: Global Positioning System Directorate, <a href="http://www.gps.gov/technical/icwg/IS-GPS-200G.pdf" target="_blank"><b>Interface Specification IS-GPS-200 Revision G</b></a>. January, 2013.
|
||||
\li GPS L1C (available with first Block III launch, currently scheduled for 2013): Global Positioning System Directorate, <a href="http://www.gps.gov/technical/icwg/IS-GPS-800C.pdf" target="_blank"><b>Interface Specification IS-GPS-800 Revision C</b></a>. January, 2013.
|
||||
\li GPS L5 (first Block IIF satellite launched on May, 2010): Global Positioning System Directorate, <a href="http://www.gps.gov/technical/icwg/IS-GPS-705C.pdf" target="_blank"><b>Interface Specification IS-GPS-705 Revision C</b></a>. January, 2013.
|
||||
\li GPS L1 and L2C: Global Positioning System Directorate, <a href="http://www.gps.gov/technical/icwg/IS-GPS-200H.pdf" target="_blank"><b>Interface Specification IS-GPS-200 Revision H</b></a>. September, 2013.
|
||||
\li GPS L1C (available with first Block III launch): Global Positioning System Directorate, <a href="http://www.gps.gov/technical/icwg/IS-GPS-800D.pdf" target="_blank"><b>Interface Specification IS-GPS-800 Revision D</b></a>. September, 2013.
|
||||
\li GPS L5 (first Block IIF satellite launched on May, 2010): Global Positioning System Directorate, <a href="http://www.gps.gov/technical/icwg/IS-GPS-705D.pdf" target="_blank"><b>Interface Specification IS-GPS-705 Revision D</b></a>. September, 2013.
|
||||
|
||||
|
||||
|
||||
|
@ -1,29 +0,0 @@
|
||||
#define MUL_RE(a,b) (a.x*b.x - a.y*b.y)
|
||||
#define MUL_IM(a,b) (a.x*b.y + a.y*b.x)
|
||||
#define SUM_RE(a,b) (a.x + b.x)
|
||||
#define SUM_IM(a,b) (a.y + b.y)
|
||||
|
||||
__kernel void add_vectors(__global const float2* src1, __global const float2* src2, __global float2* dest)
|
||||
{
|
||||
int gid = get_global_id(0);
|
||||
dest[gid] = (float2)(SUM_RE(src1[gid],src2[gid]),SUM_IM(src1[gid],src2[gid]));
|
||||
}
|
||||
|
||||
__kernel void mult_vectors(__global const float2* src1, __global const float2* src2, __global float2* dest)
|
||||
{
|
||||
int gid = get_global_id(0);
|
||||
dest[gid] = (float2)(MUL_RE(src1[gid],src2[gid]),MUL_IM(src1[gid],src2[gid]));
|
||||
}
|
||||
|
||||
__kernel void conj_vector(__global const float2* src, __global float2* dest)
|
||||
{
|
||||
int gid = get_global_id(0);
|
||||
dest[gid] = ((float2)(1,-1)) * src[gid];
|
||||
}
|
||||
|
||||
__kernel void magnitude_squared(__global const float2* src, __global float* dest)
|
||||
{
|
||||
int gid = get_global_id(0);
|
||||
dest[gid] = src[gid].x*src[gid].x + src[gid].y*src[gid].y;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
set(PVT_ADAPTER_SOURCES
|
||||
gps_l1_ca_pvt.cc
|
||||
galileo_e1_pvt.cc
|
||||
hybrid_pvt.cc
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
109
src/algorithms/PVT/adapters/hybrid_pvt.cc
Normal file
109
src/algorithms/PVT/adapters/hybrid_pvt.cc
Normal file
@ -0,0 +1,109 @@
|
||||
/*!
|
||||
* \file hybrid_pvt.cc
|
||||
* \brief Implementation of an adapter of a GALILEO E1 PVT solver block to a
|
||||
* PvtInterface
|
||||
* \author Javier Arribas, 2011. jarribas(at)cttc.es
|
||||
*
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2012 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "hybrid_pvt.h"
|
||||
#include <glog/logging.h>
|
||||
#include "configuration_interface.h"
|
||||
#include "hybrid_pvt_cc.h"
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
HybridPvt::HybridPvt(ConfigurationInterface* configuration,
|
||||
std::string role,
|
||||
unsigned int in_streams,
|
||||
unsigned int out_streams,
|
||||
boost::shared_ptr<gr::msg_queue> queue) :
|
||||
role_(role),
|
||||
in_streams_(in_streams),
|
||||
out_streams_(out_streams),
|
||||
queue_(queue)
|
||||
{
|
||||
// dump parameters
|
||||
std::string default_dump_filename = "./pvt.dat";
|
||||
std::string default_nmea_dump_filename = "./nmea_pvt.nmea";
|
||||
std::string default_nmea_dump_devname = "/dev/tty1";
|
||||
DLOG(INFO) << "role " << role;
|
||||
dump_ = configuration->property(role + ".dump", false);
|
||||
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||
// moving average depth parameters
|
||||
int averaging_depth;
|
||||
averaging_depth = configuration->property(role + ".averaging_depth", 10);
|
||||
bool flag_averaging;
|
||||
flag_averaging = configuration->property(role + ".flag_averaging", false);
|
||||
// output rate
|
||||
int output_rate_ms;
|
||||
output_rate_ms = configuration->property(role + ".output_rate_ms", 500);
|
||||
// display rate
|
||||
int display_rate_ms;
|
||||
display_rate_ms = configuration->property(role + ".display_rate_ms", 500);
|
||||
// NMEA Printer settings
|
||||
bool flag_nmea_tty_port;
|
||||
flag_nmea_tty_port = configuration->property(role + ".flag_nmea_tty_port", false);
|
||||
std::string nmea_dump_filename;
|
||||
nmea_dump_filename = configuration->property(role + ".nmea_dump_filename", default_nmea_dump_filename);
|
||||
std::string nmea_dump_devname;
|
||||
nmea_dump_devname = configuration->property(role + ".nmea_dump_devname", default_nmea_dump_devname);
|
||||
// make PVT object
|
||||
pvt_ = hybrid_make_pvt_cc(in_streams_, queue_, dump_, dump_filename_, averaging_depth, flag_averaging, output_rate_ms, display_rate_ms, flag_nmea_tty_port, nmea_dump_filename, nmea_dump_devname);
|
||||
DLOG(INFO) << "pvt(" << pvt_->unique_id() << ")";
|
||||
}
|
||||
|
||||
|
||||
HybridPvt::~HybridPvt()
|
||||
{}
|
||||
|
||||
|
||||
void HybridPvt::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
// Nothing to connect internally
|
||||
DLOG(INFO) << "nothing to connect internally";
|
||||
}
|
||||
|
||||
|
||||
void HybridPvt::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
// Nothing to disconnect
|
||||
}
|
||||
|
||||
gr::basic_block_sptr HybridPvt::get_left_block()
|
||||
{
|
||||
return pvt_;
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr HybridPvt::get_right_block()
|
||||
{
|
||||
return pvt_;
|
||||
}
|
||||
|
97
src/algorithms/PVT/adapters/hybrid_pvt.h
Normal file
97
src/algorithms/PVT/adapters/hybrid_pvt.h
Normal file
@ -0,0 +1,97 @@
|
||||
/*!
|
||||
* \file hybrid_pvt.h
|
||||
* \brief Interface of an adapter of a GALILEO E1 PVT solver block to a
|
||||
* PvtInterface.
|
||||
* \author Javier Arribas, 2013. jarribas(at)cttc.es
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef GNSS_SDR_HYBRID_PVT_H_
|
||||
#define GNSS_SDR_HYBRID_PVT_H_
|
||||
|
||||
#include <string>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include "pvt_interface.h"
|
||||
#include "hybrid_pvt_cc.h"
|
||||
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
* \brief This class implements a PvtInterface for Galileo E1
|
||||
*/
|
||||
class HybridPvt : public PvtInterface
|
||||
{
|
||||
public:
|
||||
HybridPvt(ConfigurationInterface* configuration,
|
||||
std::string role,
|
||||
unsigned int in_streams,
|
||||
unsigned int out_streams,
|
||||
boost::shared_ptr<gr::msg_queue> queue);
|
||||
|
||||
virtual ~HybridPvt();
|
||||
|
||||
std::string role()
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
//! Returns "Hybrid_Pvt"
|
||||
std::string implementation()
|
||||
{
|
||||
return "Hybrid_PVT";
|
||||
}
|
||||
|
||||
void connect(gr::top_block_sptr top_block);
|
||||
void disconnect(gr::top_block_sptr top_block);
|
||||
gr::basic_block_sptr get_left_block();
|
||||
gr::basic_block_sptr get_right_block();
|
||||
|
||||
void reset()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//! All blocks must have an item_size() function implementation. Returns sizeof(gr_complex)
|
||||
size_t item_size()
|
||||
{
|
||||
return sizeof(gr_complex);
|
||||
}
|
||||
|
||||
private:
|
||||
hybrid_pvt_cc_sptr pvt_;
|
||||
bool dump_;
|
||||
unsigned int fs_in_;
|
||||
std::string dump_filename_;
|
||||
std::string role_;
|
||||
unsigned int in_streams_;
|
||||
unsigned int out_streams_;
|
||||
boost::shared_ptr<gr::msg_queue> queue_;
|
||||
};
|
||||
|
||||
#endif
|
@ -19,6 +19,7 @@
|
||||
set(PVT_GR_BLOCKS_SOURCES
|
||||
gps_l1_ca_pvt_cc.cc
|
||||
galileo_e1_pvt_cc.cc
|
||||
hybrid_pvt_cc.cc
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
@ -48,6 +48,7 @@ using google::LogMessage;
|
||||
extern concurrent_map<Galileo_Ephemeris> global_galileo_ephemeris_map;
|
||||
extern concurrent_map<Galileo_Iono> global_galileo_iono_map;
|
||||
extern concurrent_map<Galileo_Utc_Model> global_galileo_utc_model_map;
|
||||
extern concurrent_map<Galileo_Almanac> global_galileo_almanac_map;
|
||||
|
||||
galileo_e1_pvt_cc_sptr
|
||||
galileo_e1_make_pvt_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms, bool flag_nmea_tty_port, std::string nmea_dump_filename, std::string nmea_dump_devname)
|
||||
@ -73,17 +74,17 @@ galileo_e1_pvt_cc::galileo_e1_pvt_cc(unsigned int nchannels, boost::shared_ptr<g
|
||||
std::string kml_dump_filename;
|
||||
kml_dump_filename = d_dump_filename;
|
||||
kml_dump_filename.append(".kml");
|
||||
d_kml_dump.set_headers(kml_dump_filename);
|
||||
d_kml_dump = std::make_shared<Kml_Printer>();
|
||||
d_kml_dump->set_headers(kml_dump_filename);
|
||||
|
||||
//initialize nmea_printer
|
||||
d_nmea_printer = new Nmea_Printer(nmea_dump_filename, flag_nmea_tty_port, nmea_dump_devname);
|
||||
|
||||
d_nmea_printer = std::make_shared<Nmea_Printer>(nmea_dump_filename, flag_nmea_tty_port, nmea_dump_devname);
|
||||
d_dump_filename.append("_raw.dat");
|
||||
dump_ls_pvt_filename.append("_ls_pvt.dat");
|
||||
d_averaging_depth = averaging_depth;
|
||||
d_flag_averaging = flag_averaging;
|
||||
|
||||
d_ls_pvt = new galileo_e1_ls_pvt(nchannels, dump_ls_pvt_filename, d_dump);
|
||||
d_ls_pvt = std::make_shared<galileo_e1_ls_pvt>(nchannels, dump_ls_pvt_filename, d_dump);
|
||||
d_ls_pvt->set_averaging_depth(d_averaging_depth);
|
||||
|
||||
d_sample_counter = 0;
|
||||
@ -91,7 +92,7 @@ galileo_e1_pvt_cc::galileo_e1_pvt_cc(unsigned int nchannels, boost::shared_ptr<g
|
||||
d_rx_time = 0.0;
|
||||
|
||||
b_rinex_header_writen = false;
|
||||
rp = new Rinex_Printer();
|
||||
rp = std::make_shared<Rinex_Printer>();
|
||||
|
||||
// ############# ENABLE DATA FILE LOG #################
|
||||
if (d_dump == true)
|
||||
@ -115,12 +116,7 @@ galileo_e1_pvt_cc::galileo_e1_pvt_cc(unsigned int nchannels, boost::shared_ptr<g
|
||||
|
||||
|
||||
galileo_e1_pvt_cc::~galileo_e1_pvt_cc()
|
||||
{
|
||||
d_kml_dump.close_file();
|
||||
delete d_ls_pvt;
|
||||
delete rp;
|
||||
delete d_nmea_printer;
|
||||
}
|
||||
{}
|
||||
|
||||
|
||||
|
||||
@ -168,6 +164,12 @@ int galileo_e1_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_it
|
||||
global_galileo_iono_map.read(0, d_ls_pvt->galileo_iono);
|
||||
}
|
||||
|
||||
if (global_galileo_almanac_map.size() > 0)
|
||||
{
|
||||
// Almanac data is shared for all the Galileo satellites. Read always at ID=0
|
||||
global_galileo_almanac_map.read(0, d_ls_pvt->galileo_almanac);
|
||||
}
|
||||
|
||||
// ############ 2 COMPUTE THE PVT ################################
|
||||
if (gnss_pseudoranges_map.size() > 0 and d_ls_pvt->galileo_ephemeris_map.size() > 0)
|
||||
{
|
||||
@ -177,40 +179,39 @@ int galileo_e1_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_it
|
||||
bool pvt_result;
|
||||
pvt_result = d_ls_pvt->get_PVT(gnss_pseudoranges_map, d_rx_time, d_flag_averaging);
|
||||
|
||||
|
||||
if (pvt_result == true)
|
||||
{
|
||||
d_kml_dump.print_position_galileo(d_ls_pvt, d_flag_averaging);
|
||||
d_kml_dump->print_position_galileo(d_ls_pvt, d_flag_averaging);
|
||||
//ToDo: Implement Galileo RINEX and Galileo NMEA outputs
|
||||
// d_nmea_printer->Print_Nmea_Line(d_ls_pvt, d_flag_averaging);
|
||||
// d_nmea_printer->Print_Nmea_Line(d_ls_pvt, d_flag_averaging);
|
||||
//
|
||||
// if (!b_rinex_header_writen) // & we have utc data in nav message!
|
||||
// {
|
||||
// std::map<int,Gps_Ephemeris>::iterator gps_ephemeris_iter;
|
||||
// gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.begin();
|
||||
// if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end())
|
||||
// {
|
||||
// rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second,d_rx_time);
|
||||
// rp->rinex_nav_header(rp->navFile,d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model);
|
||||
// b_rinex_header_writen = true; // do not write header anymore
|
||||
// }
|
||||
// }
|
||||
// if(b_rinex_header_writen) // Put here another condition to separate annotations (e.g 30 s)
|
||||
// {
|
||||
// // Limit the RINEX navigation output rate to 1/6 seg
|
||||
// // Notice that d_sample_counter period is 1ms (for GPS correlators)
|
||||
// if ((d_sample_counter-d_last_sample_nav_output)>=6000)
|
||||
// {
|
||||
// rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map);
|
||||
// d_last_sample_nav_output=d_sample_counter;
|
||||
// }
|
||||
// std::map<int,Gps_Ephemeris>::iterator gps_ephemeris_iter;
|
||||
// gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.begin();
|
||||
// if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end())
|
||||
// {
|
||||
// rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, d_rx_time, gnss_pseudoranges_map);
|
||||
// }
|
||||
// }
|
||||
if (!b_rinex_header_writen) // & we have utc data in nav message!
|
||||
{
|
||||
std::map<int,Galileo_Ephemeris>::iterator galileo_ephemeris_iter;
|
||||
galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.begin();
|
||||
if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end())
|
||||
{
|
||||
rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time);
|
||||
rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac);
|
||||
b_rinex_header_writen = true; // do not write header anymore
|
||||
}
|
||||
}
|
||||
if(b_rinex_header_writen) // Put here another condition to separate annotations (e.g 30 s)
|
||||
{
|
||||
// Limit the RINEX navigation output rate to 1/6 seg
|
||||
// Notice that d_sample_counter period is 4ms (for Galileo correlators)
|
||||
if ((d_sample_counter - d_last_sample_nav_output) >= 6000)
|
||||
{
|
||||
rp->log_rinex_nav(rp->navGalFile, d_ls_pvt->galileo_ephemeris_map);
|
||||
d_last_sample_nav_output = d_sample_counter;
|
||||
}
|
||||
std::map<int, Galileo_Ephemeris>::iterator galileo_ephemeris_iter;
|
||||
galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.begin();
|
||||
if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end())
|
||||
{
|
||||
rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_pseudoranges_map);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ private:
|
||||
boost::shared_ptr<gr::msg_queue> d_queue;
|
||||
bool d_dump;
|
||||
bool b_rinex_header_writen;
|
||||
Rinex_Printer *rp;
|
||||
std::shared_ptr<Rinex_Printer> rp;
|
||||
unsigned int d_nchannels;
|
||||
std::string d_dump_filename;
|
||||
std::ofstream d_dump_file;
|
||||
@ -106,10 +106,10 @@ private:
|
||||
int d_display_rate_ms;
|
||||
long unsigned int d_sample_counter;
|
||||
long unsigned int d_last_sample_nav_output;
|
||||
Kml_Printer d_kml_dump;
|
||||
Nmea_Printer *d_nmea_printer;
|
||||
std::shared_ptr<Kml_Printer> d_kml_dump;
|
||||
std::shared_ptr<Nmea_Printer> d_nmea_printer;
|
||||
double d_rx_time;
|
||||
galileo_e1_ls_pvt *d_ls_pvt;
|
||||
std::shared_ptr<galileo_e1_ls_pvt> d_ls_pvt;
|
||||
bool pseudoranges_pairCompare_min(std::pair<int,Gnss_Synchro> a, std::pair<int,Gnss_Synchro> b);
|
||||
|
||||
public:
|
||||
|
@ -87,17 +87,18 @@ gps_l1_ca_pvt_cc::gps_l1_ca_pvt_cc(unsigned int nchannels,
|
||||
std::string kml_dump_filename;
|
||||
kml_dump_filename = d_dump_filename;
|
||||
kml_dump_filename.append(".kml");
|
||||
d_kml_dump.set_headers(kml_dump_filename);
|
||||
d_kml_dump = std::make_shared<Kml_Printer>();
|
||||
d_kml_dump->set_headers(kml_dump_filename);
|
||||
|
||||
//initialize nmea_printer
|
||||
d_nmea_printer = new Nmea_Printer(nmea_dump_filename, flag_nmea_tty_port, nmea_dump_devname);
|
||||
d_nmea_printer = std::make_shared<Nmea_Printer>(nmea_dump_filename, flag_nmea_tty_port, nmea_dump_devname);
|
||||
|
||||
d_dump_filename.append("_raw.dat");
|
||||
dump_ls_pvt_filename.append("_ls_pvt.dat");
|
||||
d_averaging_depth = averaging_depth;
|
||||
d_flag_averaging = flag_averaging;
|
||||
|
||||
d_ls_pvt = new gps_l1_ca_ls_pvt(nchannels,dump_ls_pvt_filename,d_dump);
|
||||
d_ls_pvt = std::make_shared<gps_l1_ca_ls_pvt>((int)nchannels, dump_ls_pvt_filename, d_dump);
|
||||
d_ls_pvt->set_averaging_depth(d_averaging_depth);
|
||||
|
||||
d_sample_counter = 0;
|
||||
@ -106,7 +107,7 @@ gps_l1_ca_pvt_cc::gps_l1_ca_pvt_cc(unsigned int nchannels,
|
||||
|
||||
b_rinex_header_writen = false;
|
||||
b_rinex_sbs_header_writen = false;
|
||||
rp = new Rinex_Printer();
|
||||
rp = std::make_shared<Rinex_Printer>();
|
||||
|
||||
// ############# ENABLE DATA FILE LOG #################
|
||||
if (d_dump == true)
|
||||
@ -130,12 +131,7 @@ gps_l1_ca_pvt_cc::gps_l1_ca_pvt_cc(unsigned int nchannels,
|
||||
|
||||
|
||||
gps_l1_ca_pvt_cc::~gps_l1_ca_pvt_cc()
|
||||
{
|
||||
d_kml_dump.close_file();
|
||||
delete d_ls_pvt;
|
||||
delete rp;
|
||||
delete d_nmea_printer;
|
||||
}
|
||||
{}
|
||||
|
||||
|
||||
|
||||
@ -237,7 +233,7 @@ int gps_l1_ca_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_ite
|
||||
pvt_result = d_ls_pvt->get_PVT(gnss_pseudoranges_map, d_rx_time, d_flag_averaging);
|
||||
if (pvt_result == true)
|
||||
{
|
||||
d_kml_dump.print_position(d_ls_pvt, d_flag_averaging);
|
||||
d_kml_dump->print_position(d_ls_pvt, d_flag_averaging);
|
||||
d_nmea_printer->Print_Nmea_Line(d_ls_pvt, d_flag_averaging);
|
||||
|
||||
if (!b_rinex_header_writen) // & we have utc data in nav message!
|
||||
|
@ -96,7 +96,7 @@ private:
|
||||
bool d_dump;
|
||||
bool b_rinex_header_writen;
|
||||
bool b_rinex_sbs_header_writen;
|
||||
Rinex_Printer *rp;
|
||||
std::shared_ptr<Rinex_Printer> rp;
|
||||
unsigned int d_nchannels;
|
||||
std::string d_dump_filename;
|
||||
std::ofstream d_dump_file;
|
||||
@ -106,10 +106,10 @@ private:
|
||||
int d_display_rate_ms;
|
||||
long unsigned int d_sample_counter;
|
||||
long unsigned int d_last_sample_nav_output;
|
||||
Kml_Printer d_kml_dump;
|
||||
Nmea_Printer *d_nmea_printer;
|
||||
std::shared_ptr<Kml_Printer> d_kml_dump;
|
||||
std::shared_ptr<Nmea_Printer> d_nmea_printer;
|
||||
double d_rx_time;
|
||||
gps_l1_ca_ls_pvt *d_ls_pvt;
|
||||
std::shared_ptr<gps_l1_ca_ls_pvt> d_ls_pvt;
|
||||
|
||||
public:
|
||||
~gps_l1_ca_pvt_cc (); //!< Default destructor
|
||||
|
300
src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.cc
Normal file
300
src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.cc
Normal file
@ -0,0 +1,300 @@
|
||||
/*!
|
||||
* \file hybrid_pvt_cc.cc
|
||||
* \brief Implementation of a Position Velocity and Time computation block for GPS L1 C/A
|
||||
* \author Javier Arribas, 2013. jarribas(at)cttc.es
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "hybrid_pvt_cc.h"
|
||||
#include <algorithm>
|
||||
#include <bitset>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <gnuradio/gr_complex.h>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <glog/logging.h>
|
||||
#include "control_message_factory.h"
|
||||
#include "gnss_synchro.h"
|
||||
#include "concurrent_map.h"
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
extern concurrent_map<Galileo_Ephemeris> global_galileo_ephemeris_map;
|
||||
extern concurrent_map<Galileo_Iono> global_galileo_iono_map;
|
||||
extern concurrent_map<Galileo_Utc_Model> global_galileo_utc_model_map;
|
||||
extern concurrent_map<Galileo_Almanac> global_galileo_almanac_map;
|
||||
|
||||
extern concurrent_map<Gps_Ephemeris> global_gps_ephemeris_map;
|
||||
extern concurrent_map<Gps_Iono> global_gps_iono_map;
|
||||
extern concurrent_map<Gps_Utc_Model> global_gps_utc_model_map;
|
||||
|
||||
hybrid_pvt_cc_sptr
|
||||
hybrid_make_pvt_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms, bool flag_nmea_tty_port, std::string nmea_dump_filename, std::string nmea_dump_devname)
|
||||
{
|
||||
return hybrid_pvt_cc_sptr(new hybrid_pvt_cc(nchannels, queue, dump, dump_filename, averaging_depth, flag_averaging, output_rate_ms, display_rate_ms, flag_nmea_tty_port, nmea_dump_filename, nmea_dump_devname));
|
||||
}
|
||||
|
||||
|
||||
hybrid_pvt_cc::hybrid_pvt_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms, bool flag_nmea_tty_port, std::string nmea_dump_filename, std::string nmea_dump_devname) :
|
||||
gr::block("hybrid_pvt_cc", gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)),
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex)))
|
||||
{
|
||||
|
||||
d_output_rate_ms = output_rate_ms;
|
||||
d_display_rate_ms = display_rate_ms;
|
||||
d_queue = queue;
|
||||
d_dump = dump;
|
||||
d_nchannels = nchannels;
|
||||
d_dump_filename = dump_filename;
|
||||
std::string dump_ls_pvt_filename = dump_filename;
|
||||
|
||||
//initialize kml_printer
|
||||
std::string kml_dump_filename;
|
||||
kml_dump_filename = d_dump_filename;
|
||||
kml_dump_filename.append(".kml");
|
||||
d_kml_dump = std::make_shared<Kml_Printer>();
|
||||
d_kml_dump->set_headers(kml_dump_filename);
|
||||
|
||||
//initialize nmea_printer
|
||||
d_nmea_printer = std::make_shared<Nmea_Printer>(nmea_dump_filename, flag_nmea_tty_port, nmea_dump_devname);
|
||||
|
||||
d_dump_filename.append("_raw.dat");
|
||||
dump_ls_pvt_filename.append("_ls_pvt.dat");
|
||||
d_averaging_depth = averaging_depth;
|
||||
d_flag_averaging = flag_averaging;
|
||||
|
||||
d_ls_pvt = std::make_shared<hybrid_ls_pvt>((int)nchannels, dump_ls_pvt_filename, d_dump);
|
||||
d_ls_pvt->set_averaging_depth(d_averaging_depth);
|
||||
|
||||
d_sample_counter = 0;
|
||||
valid_solution_counter = 0;
|
||||
d_last_sample_nav_output = 0;
|
||||
d_rx_time = 0.0;
|
||||
d_TOW_at_curr_symbol_constellation = 0.0;
|
||||
b_rinex_header_writen = false;
|
||||
rp = std::make_shared<Rinex_Printer>();
|
||||
|
||||
// ############# ENABLE DATA FILE LOG #################
|
||||
if (d_dump == true)
|
||||
{
|
||||
if (d_dump_file.is_open() == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit );
|
||||
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
|
||||
LOG(INFO) << "PVT dump enabled Log file: " << d_dump_filename.c_str();
|
||||
}
|
||||
catch (const std::ifstream::failure& e)
|
||||
{
|
||||
LOG(WARNING) << "Exception opening PVT dump file " << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
hybrid_pvt_cc::~hybrid_pvt_cc()
|
||||
{}
|
||||
|
||||
|
||||
|
||||
bool hybrid_pvt_cc::pseudoranges_pairCompare_min( std::pair<int,Gnss_Synchro> a, std::pair<int,Gnss_Synchro> b)
|
||||
{
|
||||
return (a.second.Pseudorange_m) < (b.second.Pseudorange_m);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int hybrid_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
|
||||
{
|
||||
d_sample_counter++;
|
||||
bool arrived_galileo_almanac = false;
|
||||
|
||||
std::map<int,Gnss_Synchro> gnss_pseudoranges_map;
|
||||
|
||||
Gnss_Synchro **in = (Gnss_Synchro **) &input_items[0]; //Get the input pointer
|
||||
|
||||
for (unsigned int i = 0; i < d_nchannels; i++)
|
||||
{
|
||||
if (in[i][0].Flag_valid_pseudorange == true)
|
||||
{
|
||||
gnss_pseudoranges_map.insert(std::pair<int,Gnss_Synchro>(in[i][0].PRN, in[i][0])); // store valid pseudoranges in a map
|
||||
//d_rx_time = in[i][0].d_TOW_at_current_symbol; // all the channels have the same RX timestamp (common RX time pseudoranges)
|
||||
d_TOW_at_curr_symbol_constellation = in[i][0].d_TOW_at_current_symbol; // d_TOW_at_current_symbol not corrected by delta t (just for debug)
|
||||
d_rx_time = in[i][0].d_TOW_hybrid_at_current_symbol; // hybrid rx time, all the channels have the same RX timestamp (common RX time pseudoranges)
|
||||
}
|
||||
}
|
||||
|
||||
// ############ 1. READ GALILEO EPHEMERIS/UTC_MODE/IONO FROM GLOBAL MAPS ####
|
||||
|
||||
if (global_galileo_ephemeris_map.size() > 0)
|
||||
{
|
||||
d_ls_pvt->galileo_ephemeris_map = global_galileo_ephemeris_map.get_map_copy();
|
||||
}
|
||||
|
||||
if (global_galileo_utc_model_map.size() > 0)
|
||||
{
|
||||
// UTC MODEL data is shared for all the Galileo satellites. Read always at ID=0
|
||||
global_galileo_utc_model_map.read(0, d_ls_pvt->galileo_utc_model);
|
||||
}
|
||||
|
||||
if (global_galileo_iono_map.size() > 0)
|
||||
{
|
||||
// IONO data is shared for all the Galileo satellites. Read always at ID=0
|
||||
global_galileo_iono_map.read(0, d_ls_pvt->galileo_iono);
|
||||
}
|
||||
|
||||
if (global_galileo_almanac_map.size() > 0)
|
||||
{
|
||||
// Almanac data is shared for all the Galileo satellites. Read always at ID=0
|
||||
arrived_galileo_almanac = global_galileo_almanac_map.read(0, d_ls_pvt->galileo_almanac);
|
||||
}
|
||||
|
||||
// ############ 1. READ GPS EPHEMERIS/UTC_MODE/IONO FROM GLOBAL MAPS ####
|
||||
|
||||
if (global_gps_ephemeris_map.size() > 0)
|
||||
{
|
||||
d_ls_pvt->gps_ephemeris_map = global_gps_ephemeris_map.get_map_copy();
|
||||
}
|
||||
|
||||
if (global_gps_utc_model_map.size() > 0)
|
||||
{
|
||||
// UTC MODEL data is shared for all the Galileo satellites. Read always at ID=0
|
||||
global_gps_utc_model_map.read(0, d_ls_pvt->gps_utc_model);
|
||||
}
|
||||
|
||||
if (global_gps_iono_map.size() > 0)
|
||||
{
|
||||
// IONO data is shared for all the Galileo satellites. Read always at ID=0
|
||||
global_gps_iono_map.read(0, d_ls_pvt->gps_iono);
|
||||
}
|
||||
|
||||
|
||||
// ############ 2 COMPUTE THE PVT ################################
|
||||
// ToDo: relax this condition because the receiver should work even with NO GALILEO SATELLITES
|
||||
//if (gnss_pseudoranges_map.size() > 0 and d_ls_pvt->galileo_ephemeris_map.size() > 0 and d_ls_pvt->gps_ephemeris_map.size() > 0)
|
||||
if (gnss_pseudoranges_map.size() > 0)
|
||||
{
|
||||
//std::cout << "Both GPS and Galileo ephemeris map have been filled " << std::endl;
|
||||
// compute on the fly PVT solution
|
||||
if ((d_sample_counter % d_output_rate_ms) == 0)
|
||||
{
|
||||
bool pvt_result;
|
||||
pvt_result = d_ls_pvt->get_PVT(gnss_pseudoranges_map, d_rx_time, d_flag_averaging);
|
||||
|
||||
if (pvt_result == true)
|
||||
{
|
||||
d_kml_dump->print_position_hybrid(d_ls_pvt, d_flag_averaging);
|
||||
//ToDo: Implement Galileo RINEX and Galileo NMEA outputs
|
||||
// d_nmea_printer->Print_Nmea_Line(d_ls_pvt, d_flag_averaging);
|
||||
//
|
||||
if (!b_rinex_header_writen) // & we have utc data in nav message!
|
||||
{
|
||||
std::map<int, Galileo_Ephemeris>::iterator galileo_ephemeris_iter;
|
||||
galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.begin();
|
||||
std::map<int, Gps_Ephemeris>::iterator gps_ephemeris_iter;
|
||||
gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.begin();
|
||||
if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) && (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end()) )
|
||||
{
|
||||
if (arrived_galileo_almanac)
|
||||
{
|
||||
rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time);
|
||||
rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac);
|
||||
b_rinex_header_writen = true; // do not write header anymore
|
||||
}
|
||||
}
|
||||
}
|
||||
if(b_rinex_header_writen) // Put here another condition to separate annotations (e.g 30 s)
|
||||
{
|
||||
// Limit the RINEX navigation output rate to 1/6 seg
|
||||
// Notice that d_sample_counter period is 4ms (for Galileo correlators)
|
||||
if ((d_sample_counter - d_last_sample_nav_output) >= 6000)
|
||||
{
|
||||
rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_ephemeris_map, d_ls_pvt->galileo_ephemeris_map);
|
||||
d_last_sample_nav_output = d_sample_counter;
|
||||
}
|
||||
std::map<int, Galileo_Ephemeris>::iterator galileo_ephemeris_iter;
|
||||
galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.begin();
|
||||
std::map<int, Gps_Ephemeris>::iterator gps_ephemeris_iter;
|
||||
gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.begin();
|
||||
if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) || (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end()) )
|
||||
{
|
||||
rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gnss_pseudoranges_map);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DEBUG MESSAGE: Display position in console output
|
||||
if (((d_sample_counter % d_display_rate_ms) == 0) and d_ls_pvt->b_valid_position == true)
|
||||
{
|
||||
std::cout << "Position at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time)
|
||||
<< " using "<<d_ls_pvt->d_valid_observations<<" observations is Lat = " << d_ls_pvt->d_latitude_d << " [deg], Long = " << d_ls_pvt->d_longitude_d
|
||||
<< " [deg], Height= " << d_ls_pvt->d_height_m << " [m]" << std::endl;
|
||||
|
||||
LOG(INFO) << "Position at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time)
|
||||
<< " using "<<d_ls_pvt->d_valid_observations<<" observations is Lat = " << d_ls_pvt->d_latitude_d << " [deg], Long = " << d_ls_pvt->d_longitude_d
|
||||
<< " [deg], Height= " << d_ls_pvt->d_height_m << " [m]";
|
||||
|
||||
LOG(INFO) << "Dilution of Precision at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time)
|
||||
<< " using "<<d_ls_pvt->d_valid_observations<<" observations is HDOP = " << d_ls_pvt->d_HDOP << " VDOP = "
|
||||
<< d_ls_pvt->d_VDOP <<" TDOP = " << d_ls_pvt->d_TDOP
|
||||
<< " GDOP = " << d_ls_pvt->d_GDOP;
|
||||
}
|
||||
|
||||
// MULTIPLEXED FILE RECORDING - Record results to file
|
||||
if(d_dump == true)
|
||||
{
|
||||
try
|
||||
{
|
||||
double tmp_double;
|
||||
for (unsigned int i = 0; i < d_nchannels; i++)
|
||||
{
|
||||
tmp_double = in[i][0].Pseudorange_m;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = 0;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
d_dump_file.write((char*)&d_rx_time, sizeof(double));
|
||||
}
|
||||
}
|
||||
catch (const std::ifstream::failure& e)
|
||||
{
|
||||
LOG(WARNING) << "Exception writing observables dump file " << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
consume_each(1); //one by one
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
129
src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.h
Normal file
129
src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.h
Normal file
@ -0,0 +1,129 @@
|
||||
/*!
|
||||
* \file hybrid_pvt_cc.h
|
||||
* \brief Interface of a Position Velocity and Time computation block for Galileo E1
|
||||
* \author Javier Arribas, 2013. jarribas(at)cttc.es
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_HYBRID_PVT_CC_H
|
||||
#define GNSS_SDR_HYBRID_PVT_CC_H
|
||||
|
||||
#include <fstream>
|
||||
#include <queue>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include "galileo_navigation_message.h"
|
||||
#include "galileo_ephemeris.h"
|
||||
#include "galileo_utc_model.h"
|
||||
#include "galileo_iono.h"
|
||||
#include "gps_navigation_message.h"
|
||||
#include "gps_ephemeris.h"
|
||||
#include "gps_utc_model.h"
|
||||
#include "gps_iono.h"
|
||||
#include "nmea_printer.h"
|
||||
#include "kml_printer.h"
|
||||
#include "rinex_printer.h"
|
||||
#include "hybrid_ls_pvt.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "Galileo_E1.h"
|
||||
|
||||
class hybrid_pvt_cc;
|
||||
|
||||
typedef boost::shared_ptr<hybrid_pvt_cc> hybrid_pvt_cc_sptr;
|
||||
|
||||
hybrid_pvt_cc_sptr hybrid_make_pvt_cc(unsigned int n_channels,
|
||||
boost::shared_ptr<gr::msg_queue> queue,
|
||||
bool dump,
|
||||
std::string dump_filename,
|
||||
int averaging_depth,
|
||||
bool flag_averaging,
|
||||
int output_rate_ms,
|
||||
int display_rate_ms,
|
||||
bool flag_nmea_tty_port,
|
||||
std::string nmea_dump_filename,
|
||||
std::string nmea_dump_devname);
|
||||
|
||||
/*!
|
||||
* \brief This class implements a block that computes the PVT solution with Galileo E1 signals
|
||||
*/
|
||||
class hybrid_pvt_cc : public gr::block
|
||||
{
|
||||
private:
|
||||
friend hybrid_pvt_cc_sptr hybrid_make_pvt_cc(unsigned int nchannels,
|
||||
boost::shared_ptr<gr::msg_queue> queue,
|
||||
bool dump,
|
||||
std::string dump_filename,
|
||||
int averaging_depth,
|
||||
bool flag_averaging,
|
||||
int output_rate_ms,
|
||||
int display_rate_ms,
|
||||
bool flag_nmea_tty_port,
|
||||
std::string nmea_dump_filename,
|
||||
std::string nmea_dump_devname);
|
||||
hybrid_pvt_cc(unsigned int nchannels,
|
||||
boost::shared_ptr<gr::msg_queue> queue,
|
||||
bool dump, std::string dump_filename,
|
||||
int averaging_depth,
|
||||
bool flag_averaging,
|
||||
int output_rate_ms,
|
||||
int display_rate_ms,
|
||||
bool flag_nmea_tty_port,
|
||||
std::string nmea_dump_filename,
|
||||
std::string nmea_dump_devname);
|
||||
boost::shared_ptr<gr::msg_queue> d_queue;
|
||||
bool d_dump;
|
||||
bool b_rinex_header_writen;
|
||||
std::shared_ptr<Rinex_Printer> rp;
|
||||
unsigned int d_nchannels;
|
||||
std::string d_dump_filename;
|
||||
std::ofstream d_dump_file;
|
||||
int d_averaging_depth;
|
||||
bool d_flag_averaging;
|
||||
int d_output_rate_ms;
|
||||
int d_display_rate_ms;
|
||||
long unsigned int d_sample_counter;
|
||||
long unsigned int valid_solution_counter;
|
||||
long unsigned int valid_solution_16_sat_counter;
|
||||
long unsigned int d_last_sample_nav_output;
|
||||
std::shared_ptr<Kml_Printer> d_kml_dump;
|
||||
std::shared_ptr<Nmea_Printer> d_nmea_printer;
|
||||
double d_rx_time;
|
||||
double d_TOW_at_curr_symbol_constellation;
|
||||
std::shared_ptr<hybrid_ls_pvt> d_ls_pvt;
|
||||
bool pseudoranges_pairCompare_min(std::pair<int,Gnss_Synchro> a, std::pair<int,Gnss_Synchro> b);
|
||||
|
||||
public:
|
||||
~hybrid_pvt_cc (); //!< Default destructor
|
||||
|
||||
int general_work (int noutput_items, gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); //!< PVT Signal Processing
|
||||
};
|
||||
|
||||
#endif
|
@ -16,9 +16,12 @@
|
||||
# along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
add_definitions( -DGNSS_SDR_VERSION="${VERSION}" )
|
||||
|
||||
set(PVT_LIB_SOURCES
|
||||
gps_l1_ca_ls_pvt.cc
|
||||
galileo_e1_ls_pvt.cc
|
||||
hybrid_ls_pvt.cc
|
||||
kml_printer.cc
|
||||
rinex_printer.cc
|
||||
nmea_printer.cc
|
||||
|
@ -95,7 +95,7 @@ arma::vec galileo_e1_ls_pvt::rotateSatellite(double traveltime, arma::vec X_sat)
|
||||
|
||||
//--- Find rotation angle --------------------------------------------------
|
||||
double omegatau;
|
||||
omegatau = OMEGA_EARTH_DOT * traveltime;
|
||||
omegatau = GALILEO_OMEGA_EARTH_DOT * traveltime;
|
||||
|
||||
//--- Build a rotation matrix ----------------------------------------------
|
||||
arma::mat R3 = arma::zeros(3,3);
|
||||
@ -147,6 +147,9 @@ arma::vec galileo_e1_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arm
|
||||
double rho2;
|
||||
double traveltime;
|
||||
double trop;
|
||||
double dlambda;
|
||||
double dphi;
|
||||
double h;
|
||||
arma::mat mat_tmp;
|
||||
arma::vec x;
|
||||
|
||||
@ -179,6 +182,15 @@ arma::vec galileo_e1_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arm
|
||||
&d_visible_satellites_Distance[i],
|
||||
pos.subvec(0,2),
|
||||
Rot_X - pos.subvec(0, 2));
|
||||
if(traveltime < 0.1 && nmbOfSatellites > 3)
|
||||
{
|
||||
//--- Find receiver's height
|
||||
togeod(&dphi, &dlambda, &h, 6378137.0, 298.257223563, pos(0), pos(1), pos(2));
|
||||
|
||||
//--- Find delay due to troposphere (in meters)
|
||||
tropo(&trop, sin(d_visible_satellites_El[i] * GALILEO_PI/180.0), h/1000, 1013.0, 293.0, 50.0, 0.0, 0.0, 0.0);
|
||||
if(trop > 50.0 ) trop = 0.0;
|
||||
}
|
||||
}
|
||||
//--- Apply the corrections ----------------------------------------
|
||||
omc(i) = (obs(i) - norm(Rot_X - pos.subvec(0, 2), 2) - pos(3) - trop); // Armadillo
|
||||
@ -221,14 +233,12 @@ bool galileo_e1_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map
|
||||
std::map<int,Galileo_Ephemeris>::iterator galileo_ephemeris_iter;
|
||||
int valid_pseudoranges = gnss_pseudoranges_map.size();
|
||||
|
||||
arma::mat W = arma::eye(valid_pseudoranges, valid_pseudoranges); //channels weights matrix
|
||||
arma::mat W = arma::eye(valid_pseudoranges, valid_pseudoranges); // channels weights matrix
|
||||
arma::vec obs = arma::zeros(valid_pseudoranges); // pseudoranges observation vector
|
||||
arma::mat satpos = arma::zeros(3, valid_pseudoranges); //satellite positions matrix
|
||||
arma::mat satpos = arma::zeros(3, valid_pseudoranges); // satellite positions matrix
|
||||
|
||||
int Galileo_week_number = 0;
|
||||
double utc = 0;
|
||||
double SV_clock_drift_s = 0;
|
||||
double SV_relativistic_clock_corr_s = 0;
|
||||
double TX_time_corrected_s;
|
||||
double SV_clock_bias_s = 0;
|
||||
|
||||
@ -265,16 +275,12 @@ bool galileo_e1_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map
|
||||
//to compute satellite position we need GST = WN+TOW (everything expressed in seconds)
|
||||
//double Rx_time = galileo_current_time + Galileo_week_number*sec_in_day*day_in_week;
|
||||
|
||||
double Tx_time = Rx_time - gnss_pseudoranges_iter->second.Pseudorange_m/GALILEO_C_m_s;
|
||||
double Tx_time = Rx_time - gnss_pseudoranges_iter->second.Pseudorange_m / GALILEO_C_m_s;
|
||||
|
||||
// 2- compute the clock drift using the clock model (broadcast) for this SV
|
||||
SV_clock_drift_s = galileo_ephemeris_iter->second.sv_clock_drift(Tx_time);
|
||||
// 2- compute the clock drift using the clock model (broadcast) for this SV, including relativistic effect
|
||||
SV_clock_bias_s = galileo_ephemeris_iter->second.sv_clock_drift(Tx_time);
|
||||
|
||||
// 3- compute the relativistic clock drift using the clock model (broadcast) for this SV
|
||||
SV_relativistic_clock_corr_s = galileo_ephemeris_iter->second.sv_clock_relativistic_term(Tx_time);
|
||||
|
||||
// 4- compute the current ECEF position for this SV using corrected TX time
|
||||
SV_clock_bias_s = SV_clock_drift_s + SV_relativistic_clock_corr_s;
|
||||
// 3- compute the current ECEF position for this SV using corrected TX time
|
||||
TX_time_corrected_s = Tx_time - SV_clock_bias_s;
|
||||
galileo_ephemeris_iter->second.satellitePosition(TX_time_corrected_s);
|
||||
|
||||
@ -282,8 +288,8 @@ bool galileo_e1_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map
|
||||
satpos(1,obs_counter) = galileo_ephemeris_iter->second.d_satpos_Y;
|
||||
satpos(2,obs_counter) = galileo_ephemeris_iter->second.d_satpos_Z;
|
||||
|
||||
// 5- fill the observations vector with the corrected pseudoranges
|
||||
obs(obs_counter) = gnss_pseudoranges_iter->second.Pseudorange_m + SV_clock_bias_s*GALILEO_C_m_s;
|
||||
// 4- fill the observations vector with the corrected pseudoranges
|
||||
obs(obs_counter) = gnss_pseudoranges_iter->second.Pseudorange_m + SV_clock_bias_s * GALILEO_C_m_s;
|
||||
d_visible_satellites_IDs[valid_obs] = galileo_ephemeris_iter->second.i_satellite_PRN;
|
||||
d_visible_satellites_CN0_dB[valid_obs] = gnss_pseudoranges_iter->second.CN0_dB_hz;
|
||||
valid_obs++;
|
||||
@ -530,8 +536,8 @@ void galileo_e1_ls_pvt::cart2geo(double X, double Y, double Z, int elipsoid_sele
|
||||
}
|
||||
}
|
||||
while (abs(h - oldh) > 1.0e-12);
|
||||
d_latitude_d = phi * 180.0 / GPS_PI;
|
||||
d_longitude_d = lambda * 180 / GPS_PI;
|
||||
d_latitude_d = phi * 180.0 / GALILEO_PI;
|
||||
d_longitude_d = lambda * 180 / GALILEO_PI;
|
||||
d_height_m = h;
|
||||
}
|
||||
|
||||
@ -672,7 +678,7 @@ void galileo_e1_ls_pvt::topocent(double *Az, double *El, double *D, arma::vec x,
|
||||
double lambda;
|
||||
double phi;
|
||||
double h;
|
||||
double dtr = GPS_PI/180.0;
|
||||
double dtr = GALILEO_PI/180.0;
|
||||
double a = 6378137.0; // semi-major axis of the reference ellipsoid WGS-84
|
||||
double finv = 298.257223563; // inverse of flattening of the reference ellipsoid WGS-84
|
||||
|
||||
@ -727,3 +733,103 @@ void galileo_e1_ls_pvt::topocent(double *Az, double *El, double *D, arma::vec x,
|
||||
|
||||
*D = sqrt(dx(0)*dx(0) + dx(1)*dx(1) + dx(2)*dx(2));
|
||||
}
|
||||
|
||||
void galileo_e1_ls_pvt::tropo(double *ddr_m, double sinel, double hsta_km, double p_mb, double t_kel, double hum, double hp_km, double htkel_km, double hhum_km)
|
||||
{
|
||||
/* Inputs:
|
||||
sinel - sin of elevation angle of satellite
|
||||
hsta_km - height of station in km
|
||||
p_mb - atmospheric pressure in mb at height hp_km
|
||||
t_kel - surface temperature in degrees Kelvin at height htkel_km
|
||||
hum - humidity in % at height hhum_km
|
||||
hp_km - height of pressure measurement in km
|
||||
htkel_km - height of temperature measurement in km
|
||||
hhum_km - height of humidity measurement in km
|
||||
|
||||
Outputs:
|
||||
ddr_m - range correction (meters)
|
||||
|
||||
Reference
|
||||
Goad, C.C. & Goodman, L. (1974) A Modified Hopfield Tropospheric
|
||||
Refraction Correction Model. Paper presented at the
|
||||
American Geophysical Union Annual Fall Meeting, San
|
||||
Francisco, December 12-17
|
||||
|
||||
Translated to C++ by Carles Fernandez from a Matlab implementation by Kai Borre
|
||||
*/
|
||||
|
||||
const double a_e = 6378.137; // semi-major axis of earth ellipsoid
|
||||
const double b0 = 7.839257e-5;
|
||||
const double tlapse = -6.5;
|
||||
const double em = -978.77 / (2.8704e6 * tlapse * 1.0e-5);
|
||||
|
||||
double tkhum = t_kel + tlapse * (hhum_km - htkel_km);
|
||||
double atkel = 7.5*(tkhum - 273.15) / (237.3 + tkhum - 273.15);
|
||||
double e0 = 0.0611 * hum * pow(10, atkel);
|
||||
double tksea = t_kel - tlapse * htkel_km;
|
||||
double tkelh = tksea + tlapse * hhum_km;
|
||||
double e0sea = e0 * pow((tksea / tkelh), (4 * em));
|
||||
double tkelp = tksea + tlapse * hp_km;
|
||||
double psea = p_mb * pow((tksea / tkelp), em);
|
||||
|
||||
if(sinel < 0) { sinel = 0.0; }
|
||||
|
||||
double tropo_delay = 0.0;
|
||||
bool done = false;
|
||||
double refsea = 77.624e-6 / tksea;
|
||||
double htop = 1.1385e-5 / refsea;
|
||||
refsea = refsea * psea;
|
||||
double ref = refsea * pow(((htop - hsta_km) / htop), 4);
|
||||
|
||||
double a;
|
||||
double b;
|
||||
double rtop;
|
||||
|
||||
while(1)
|
||||
{
|
||||
rtop = pow((a_e + htop), 2) - pow((a_e + hsta_km), 2) * (1 - pow(sinel, 2));
|
||||
|
||||
// check to see if geometry is crazy
|
||||
if(rtop < 0) { rtop = 0; }
|
||||
|
||||
rtop = sqrt(rtop) - (a_e + hsta_km) * sinel;
|
||||
|
||||
a = -sinel / (htop - hsta_km);
|
||||
b = -b0 * (1 - pow(sinel,2)) / (htop - hsta_km);
|
||||
|
||||
arma::vec rn = arma::vec(8);
|
||||
rn.zeros();
|
||||
|
||||
for(int i = 0; i<8; i++)
|
||||
{
|
||||
rn(i) = pow(rtop, (i+1+1));
|
||||
|
||||
}
|
||||
|
||||
arma::rowvec alpha = {2 * a, 2 * pow(a, 2) + 4 * b /3, a * (pow(a, 2) + 3 * b),
|
||||
pow(a, 4)/5 + 2.4 * pow(a, 2) * b + 1.2 * pow(b, 2), 2 * a * b * (pow(a, 2) + 3 * b)/3,
|
||||
pow(b, 2) * (6 * pow(a, 2) + 4 * b) * 1.428571e-1, 0, 0};
|
||||
|
||||
if(pow(b, 2) > 1.0e-35)
|
||||
{
|
||||
alpha(6) = a * pow(b, 3) /2;
|
||||
alpha(7) = pow(b, 4) / 9;
|
||||
}
|
||||
|
||||
double dr = rtop;
|
||||
arma::mat aux_ = alpha * rn;
|
||||
dr = dr + aux_(0, 0);
|
||||
tropo_delay = tropo_delay + dr * ref * 1000;
|
||||
|
||||
if(done == true)
|
||||
{
|
||||
*ddr_m = tropo_delay;
|
||||
break;
|
||||
}
|
||||
|
||||
done = true;
|
||||
refsea = (371900.0e-6 / tksea - 12.92e-6) / tksea;
|
||||
htop = 1.1385e-5 * (1255 / tksea + 0.05) / refsea;
|
||||
ref = refsea * e0sea * pow(((htop - hsta_km) / htop), 4);
|
||||
}
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ private:
|
||||
arma::vec rotateSatellite(double traveltime, arma::vec X_sat);
|
||||
void topocent(double *Az, double *El, double *D, arma::vec x, arma::vec dx);
|
||||
void togeod(double *dphi, double *dlambda, double *h, double a, double finv, double X, double Y, double Z);
|
||||
void tropo(double *ddr_m, double sinel, double hsta_km, double p_mb, double t_kel, double hum, double hp_km, double htkel_km, double hhum_km);
|
||||
public:
|
||||
int d_nchannels; //!< Number of available channels for positioning
|
||||
int d_valid_observations; //!< Number of valid pseudorange observations (valid satellites)
|
||||
@ -76,6 +77,7 @@ public:
|
||||
std::map<int,Galileo_Ephemeris> galileo_ephemeris_map; //!< Map storing new Galileo_Ephemeris
|
||||
Galileo_Utc_Model galileo_utc_model;
|
||||
Galileo_Iono galileo_iono;
|
||||
Galileo_Almanac galileo_almanac;
|
||||
|
||||
double d_galileo_current_time;
|
||||
boost::posix_time::ptime d_position_UTC_time;
|
||||
|
@ -27,14 +27,16 @@
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
#define GLOG_NO_ABBREVIATED_SEVERITIES
|
||||
|
||||
|
||||
#include "gps_l1_ca_ls_pvt.h"
|
||||
#include <gflags/gflags.h>
|
||||
#include <glog/logging.h>
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
DEFINE_bool(tropo, true, "Apply tropospheric correction");
|
||||
|
||||
gps_l1_ca_ls_pvt::gps_l1_ca_ls_pvt(int nchannels,std::string dump_filename, bool flag_dump_to_file)
|
||||
{
|
||||
@ -107,7 +109,7 @@ arma::vec gps_l1_ca_ls_pvt::rotateSatellite(double traveltime, arma::vec X_sat)
|
||||
R3(1, 2) = 0.0;
|
||||
R3(2, 0) = 0.0;
|
||||
R3(2, 1) = 0.0;
|
||||
R3(2, 2) = 1;
|
||||
R3(2, 2) = 1.0;
|
||||
|
||||
//--- Do the rotation ------------------------------------------------------
|
||||
arma::vec X_sat_rot;
|
||||
@ -147,6 +149,9 @@ arma::vec gps_l1_ca_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arma
|
||||
double rho2;
|
||||
double traveltime;
|
||||
double trop;
|
||||
double dlambda;
|
||||
double dphi;
|
||||
double h;
|
||||
arma::mat mat_tmp;
|
||||
arma::vec x;
|
||||
|
||||
@ -164,21 +169,33 @@ arma::vec gps_l1_ca_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arma
|
||||
else
|
||||
{
|
||||
//--- Update equations -----------------------------------------
|
||||
rho2 = (X(0, i) - pos(0)) *
|
||||
(X(0, i) - pos(0)) + (X(1, i) - pos(1)) *
|
||||
(X(1, i) - pos(1)) + (X(2,i) - pos(2)) *
|
||||
(X(2,i) - pos(2));
|
||||
rho2 = (X(0, i) - pos(0)) * (X(0, i) - pos(0))
|
||||
+ (X(1, i) - pos(1)) * (X(1, i) - pos(1))
|
||||
+ (X(2, i) - pos(2)) * (X(2, i) - pos(2));
|
||||
traveltime = sqrt(rho2) / GPS_C_m_s;
|
||||
|
||||
//--- Correct satellite position (do to earth rotation) --------
|
||||
Rot_X = rotateSatellite(traveltime, X.col(i)); //armadillo
|
||||
|
||||
//--- Find DOA and range of satellites
|
||||
//--- Find satellites' DOA
|
||||
topocent(&d_visible_satellites_Az[i], &d_visible_satellites_El[i],
|
||||
&d_visible_satellites_Distance[i], pos.subvec(0,2), Rot_X - pos.subvec(0,2));
|
||||
//[az(i), el(i), dist] = topocent(pos(1:3, :), Rot_X - pos(1:3, :));
|
||||
|
||||
if(FLAGS_tropo)
|
||||
{
|
||||
if(traveltime < 0.1 && nmbOfSatellites > 3)
|
||||
{
|
||||
//--- Find receiver's height
|
||||
togeod(&dphi, &dlambda, &h, 6378137.0, 298.257223563, pos(0), pos(1), pos(2));
|
||||
|
||||
//--- Find delay due to troposphere (in meters)
|
||||
tropo(&trop, sin(d_visible_satellites_El[i] * GPS_PI / 180.0), h / 1000, 1013.0, 293.0, 50.0, 0.0, 0.0, 0.0);
|
||||
if(trop > 50.0 ) trop = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--- Apply the corrections ----------------------------------------
|
||||
omc(i) = (obs(i) - norm(Rot_X - pos.subvec(0,2),2) - pos(3) - trop); // Armadillo
|
||||
|
||||
@ -189,16 +206,16 @@ arma::vec gps_l1_ca_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arma
|
||||
A(i,2) = (-(Rot_X(2) - pos(2))) / obs(i);
|
||||
A(i,3) = 1.0;
|
||||
}
|
||||
|
||||
|
||||
//--- Find position update ---------------------------------------------
|
||||
x = arma::solve(w*A, w*omc); // Armadillo
|
||||
|
||||
//--- Apply position update --------------------------------------------
|
||||
pos = pos + x;
|
||||
if (arma::norm(x, 2) < 1e-4)
|
||||
{
|
||||
break; // exit the loop because we assume that the LS algorithm has converged (err < 0.1 cm)
|
||||
}
|
||||
{
|
||||
break; // exit the loop because we assume that the LS algorithm has converged (err < 0.1 cm)
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
@ -221,13 +238,11 @@ bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map,
|
||||
int valid_pseudoranges = gnss_pseudoranges_map.size();
|
||||
|
||||
arma::mat W = arma::eye(valid_pseudoranges, valid_pseudoranges); //channels weights matrix
|
||||
arma::vec obs = arma::zeros(valid_pseudoranges); // pseudoranges observation vector
|
||||
arma::mat satpos = arma::zeros(3, valid_pseudoranges); //satellite positions matrix
|
||||
arma::vec obs = arma::zeros(valid_pseudoranges); // pseudoranges observation vector
|
||||
arma::mat satpos = arma::zeros(3, valid_pseudoranges); //satellite positions matrix
|
||||
|
||||
int GPS_week = 0;
|
||||
double utc = 0;
|
||||
double SV_clock_drift_s = 0;
|
||||
double SV_relativistic_clock_corr_s = 0;
|
||||
double TX_time_corrected_s;
|
||||
double SV_clock_bias_s = 0;
|
||||
|
||||
@ -254,16 +269,12 @@ bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map,
|
||||
// COMMON RX TIME PVT ALGORITHM MODIFICATION (Like RINEX files)
|
||||
// first estimate of transmit time
|
||||
double Rx_time = GPS_current_time;
|
||||
double Tx_time = Rx_time - gnss_pseudoranges_iter->second.Pseudorange_m/GPS_C_m_s;
|
||||
double Tx_time = Rx_time - gnss_pseudoranges_iter->second.Pseudorange_m / GPS_C_m_s;
|
||||
|
||||
// 2- compute the clock drift using the clock model (broadcast) for this SV
|
||||
SV_clock_drift_s = gps_ephemeris_iter->second.sv_clock_drift(Tx_time);
|
||||
// 2- compute the clock drift using the clock model (broadcast) for this SV, including relativistic effect
|
||||
SV_clock_bias_s = gps_ephemeris_iter->second.sv_clock_drift(Tx_time); //- gps_ephemeris_iter->second.d_TGD;
|
||||
|
||||
// 3- compute the relativistic clock drift using the clock model (broadcast) for this SV
|
||||
SV_relativistic_clock_corr_s = gps_ephemeris_iter->second.sv_clock_relativistic_term(Tx_time);
|
||||
|
||||
// 4- compute the current ECEF position for this SV using corrected TX time
|
||||
SV_clock_bias_s = SV_clock_drift_s + SV_relativistic_clock_corr_s - gps_ephemeris_iter->second.d_TGD;
|
||||
// 3- compute the current ECEF position for this SV using corrected TX time
|
||||
TX_time_corrected_s = Tx_time - SV_clock_bias_s;
|
||||
gps_ephemeris_iter->second.satellitePosition(TX_time_corrected_s);
|
||||
|
||||
@ -271,8 +282,8 @@ bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map,
|
||||
satpos(1, obs_counter) = gps_ephemeris_iter->second.d_satpos_Y;
|
||||
satpos(2, obs_counter) = gps_ephemeris_iter->second.d_satpos_Z;
|
||||
|
||||
// 5- fill the observations vector with the corrected pseudorranges
|
||||
obs(obs_counter) = gnss_pseudoranges_iter->second.Pseudorange_m + SV_clock_bias_s*GPS_C_m_s;
|
||||
// 4- fill the observations vector with the corrected pseudoranges
|
||||
obs(obs_counter) = gnss_pseudoranges_iter->second.Pseudorange_m + SV_clock_bias_s * GPS_C_m_s;
|
||||
d_visible_satellites_IDs[valid_obs] = gps_ephemeris_iter->second.i_satellite_PRN;
|
||||
d_visible_satellites_CN0_dB[valid_obs] = gnss_pseudoranges_iter->second.CN0_dB_hz;
|
||||
valid_obs++;
|
||||
@ -284,7 +295,7 @@ bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map,
|
||||
<< " [m] Z=" << gps_ephemeris_iter->second.d_satpos_Z
|
||||
<< " [m] PR_obs=" << obs(obs_counter) << " [m]";
|
||||
|
||||
// compute the UTC time for this SV (just to print the asociated UTC timestamp)
|
||||
// compute the UTC time for this SV (just to print the associated UTC timestamp)
|
||||
GPS_week = gps_ephemeris_iter->second.i_GPS_week;
|
||||
utc = gps_utc_model.utc_time(TX_time_corrected_s, GPS_week);
|
||||
}
|
||||
@ -566,7 +577,7 @@ void gps_l1_ca_ls_pvt::togeod(double *dphi, double *dlambda, double *h, double a
|
||||
{
|
||||
*dlambda = *dlambda + 360.0;
|
||||
}
|
||||
double r = sqrt(P*P + Z*Z); // r is distance from origin (0,0,0)
|
||||
double r = sqrt(P * P + Z * Z); // r is distance from origin (0,0,0)
|
||||
|
||||
double sinphi;
|
||||
if (r > 1.0E-20)
|
||||
@ -587,7 +598,7 @@ void gps_l1_ca_ls_pvt::togeod(double *dphi, double *dlambda, double *h, double a
|
||||
return;
|
||||
}
|
||||
|
||||
*h = r - a*(1-sinphi*sinphi/finv);
|
||||
*h = r - a * (1 - sinphi * sinphi / finv);
|
||||
|
||||
// iterate
|
||||
double cosphi;
|
||||
@ -602,18 +613,18 @@ void gps_l1_ca_ls_pvt::togeod(double *dphi, double *dlambda, double *h, double a
|
||||
cosphi = cos(*dphi);
|
||||
|
||||
// compute radius of curvature in prime vertical direction
|
||||
N_phi = a / sqrt(1 - esq*sinphi*sinphi);
|
||||
N_phi = a / sqrt(1 - esq * sinphi * sinphi);
|
||||
|
||||
// compute residuals in P and Z
|
||||
dP = P - (N_phi + (*h)) * cosphi;
|
||||
dZ = Z - (N_phi*oneesq + (*h)) * sinphi;
|
||||
|
||||
// update height and latitude
|
||||
*h = *h + (sinphi*dZ + cosphi*dP);
|
||||
*dphi = *dphi + (cosphi*dZ - sinphi*dP)/(N_phi + (*h));
|
||||
*h = *h + (sinphi * dZ + cosphi * dP);
|
||||
*dphi = *dphi + (cosphi * dZ - sinphi * dP)/(N_phi + (*h));
|
||||
|
||||
// test for convergence
|
||||
if ((dP*dP + dZ*dZ) < tolsq)
|
||||
if ((dP * dP + dZ * dZ) < tolsq)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -645,9 +656,9 @@ void gps_l1_ca_ls_pvt::topocent(double *Az, double *El, double *D, arma::vec x,
|
||||
double lambda;
|
||||
double phi;
|
||||
double h;
|
||||
double dtr = GPS_PI/180.0;
|
||||
double a = 6378137.0; // semi-major axis of the reference ellipsoid WGS-84
|
||||
double finv = 298.257223563; // inverse of flattening of the reference ellipsoid WGS-84
|
||||
double dtr = GPS_PI / 180.0;
|
||||
double a = 6378137.0; // semi-major axis of the reference ellipsoid WGS-84
|
||||
double finv = 298.257223563; // inverse of flattening of the reference ellipsoid WGS-84
|
||||
|
||||
// Transform x into geodetic coordinates
|
||||
togeod(&phi, &lambda, &h, a, finv, x(0), x(1), x(2));
|
||||
@ -660,12 +671,12 @@ void gps_l1_ca_ls_pvt::topocent(double *Az, double *El, double *D, arma::vec x,
|
||||
arma::mat F = arma::zeros(3,3);
|
||||
|
||||
F(0,0) = -sl;
|
||||
F(0,1) = -sb*cl;
|
||||
F(0,2) = cb*cl;
|
||||
F(0,1) = -sb * cl;
|
||||
F(0,2) = cb * cl;
|
||||
|
||||
F(1,0) = cl;
|
||||
F(1,1) = -sb*sl;
|
||||
F(1,2) = cb*sl;
|
||||
F(1,1) = -sb * sl;
|
||||
F(1,2) = cb * sl;
|
||||
|
||||
F(2,0) = 0;
|
||||
F(2,1) = cb;
|
||||
@ -680,7 +691,7 @@ void gps_l1_ca_ls_pvt::topocent(double *Az, double *El, double *D, arma::vec x,
|
||||
double U = local_vector(2);
|
||||
|
||||
double hor_dis;
|
||||
hor_dis = sqrt(E*E + N*N);
|
||||
hor_dis = sqrt(E * E + N * N);
|
||||
|
||||
if (hor_dis < 1.0E-20)
|
||||
{
|
||||
@ -689,8 +700,8 @@ void gps_l1_ca_ls_pvt::topocent(double *Az, double *El, double *D, arma::vec x,
|
||||
}
|
||||
else
|
||||
{
|
||||
*Az = atan2(E, N)/dtr;
|
||||
*El = atan2(U, hor_dis)/dtr;
|
||||
*Az = atan2(E, N) / dtr;
|
||||
*El = atan2(U, hor_dis) / dtr;
|
||||
}
|
||||
|
||||
if (*Az < 0)
|
||||
@ -698,5 +709,106 @@ void gps_l1_ca_ls_pvt::topocent(double *Az, double *El, double *D, arma::vec x,
|
||||
*Az = *Az + 360.0;
|
||||
}
|
||||
|
||||
*D = sqrt(dx(0)*dx(0) + dx(1)*dx(1) + dx(2)*dx(2));
|
||||
*D = sqrt(dx(0) * dx(0) + dx(1) * dx(1) + dx(2) * dx(2));
|
||||
}
|
||||
|
||||
|
||||
void gps_l1_ca_ls_pvt::tropo(double *ddr_m, double sinel, double hsta_km, double p_mb, double t_kel, double hum, double hp_km, double htkel_km, double hhum_km)
|
||||
{
|
||||
/* Inputs:
|
||||
sinel - sin of elevation angle of satellite
|
||||
hsta_km - height of station in km
|
||||
p_mb - atmospheric pressure in mb at height hp_km
|
||||
t_kel - surface temperature in degrees Kelvin at height htkel_km
|
||||
hum - humidity in % at height hhum_km
|
||||
hp_km - height of pressure measurement in km
|
||||
htkel_km - height of temperature measurement in km
|
||||
hhum_km - height of humidity measurement in km
|
||||
|
||||
Outputs:
|
||||
ddr_m - range correction (meters)
|
||||
|
||||
Reference
|
||||
Goad, C.C. & Goodman, L. (1974) A Modified Hopfield Tropospheric
|
||||
Refraction Correction Model. Paper presented at the
|
||||
American Geophysical Union Annual Fall Meeting, San
|
||||
Francisco, December 12-17
|
||||
|
||||
Translated to C++ by Carles Fernandez from a Matlab implementation by Kai Borre
|
||||
*/
|
||||
|
||||
const double a_e = 6378.137; // semi-major axis of earth ellipsoid
|
||||
const double b0 = 7.839257e-5;
|
||||
const double tlapse = -6.5;
|
||||
const double em = -978.77 / (2.8704e6 * tlapse * 1.0e-5);
|
||||
|
||||
double tkhum = t_kel + tlapse * (hhum_km - htkel_km);
|
||||
double atkel = 7.5 * (tkhum - 273.15) / (237.3 + tkhum - 273.15);
|
||||
double e0 = 0.0611 * hum * pow(10, atkel);
|
||||
double tksea = t_kel - tlapse * htkel_km;
|
||||
double tkelh = tksea + tlapse * hhum_km;
|
||||
double e0sea = e0 * pow((tksea / tkelh), (4 * em));
|
||||
double tkelp = tksea + tlapse * hp_km;
|
||||
double psea = p_mb * pow((tksea / tkelp), em);
|
||||
|
||||
if(sinel < 0) { sinel = 0.0; }
|
||||
|
||||
double tropo_delay = 0.0;
|
||||
bool done = false;
|
||||
double refsea = 77.624e-6 / tksea;
|
||||
double htop = 1.1385e-5 / refsea;
|
||||
refsea = refsea * psea;
|
||||
double ref = refsea * pow(((htop - hsta_km) / htop), 4);
|
||||
|
||||
double a;
|
||||
double b;
|
||||
double rtop;
|
||||
|
||||
while(1)
|
||||
{
|
||||
rtop = pow((a_e + htop), 2) - pow((a_e + hsta_km), 2) * (1 - pow(sinel, 2));
|
||||
|
||||
// check to see if geometry is crazy
|
||||
if(rtop < 0) { rtop = 0; }
|
||||
|
||||
rtop = sqrt(rtop) - (a_e + hsta_km) * sinel;
|
||||
|
||||
a = -sinel / (htop - hsta_km);
|
||||
b = -b0 * (1 - pow(sinel,2)) / (htop - hsta_km);
|
||||
|
||||
arma::vec rn = arma::vec(8);
|
||||
rn.zeros();
|
||||
|
||||
for(int i = 0; i<8; i++)
|
||||
{
|
||||
rn(i) = pow(rtop, (i+1+1));
|
||||
|
||||
}
|
||||
|
||||
arma::rowvec alpha = {2 * a, 2 * pow(a, 2) + 4 * b /3, a * (pow(a, 2) + 3 * b),
|
||||
pow(a, 4)/5 + 2.4 * pow(a, 2) * b + 1.2 * pow(b, 2), 2 * a * b * (pow(a, 2) + 3 * b)/3,
|
||||
pow(b, 2) * (6 * pow(a, 2) + 4 * b) * 1.428571e-1, 0, 0};
|
||||
|
||||
if(pow(b, 2) > 1.0e-35)
|
||||
{
|
||||
alpha(6) = a * pow(b, 3) /2;
|
||||
alpha(7) = pow(b, 4) / 9;
|
||||
}
|
||||
|
||||
double dr = rtop;
|
||||
arma::mat aux_ = alpha * rn;
|
||||
dr = dr + aux_(0, 0);
|
||||
tropo_delay = tropo_delay + dr * ref * 1000;
|
||||
|
||||
if(done == true)
|
||||
{
|
||||
*ddr_m = tropo_delay;
|
||||
break;
|
||||
}
|
||||
|
||||
done = true;
|
||||
refsea = (371900.0e-6 / tksea - 12.92e-6) / tksea;
|
||||
htop = 1.1385e-5 * (1255 / tksea + 0.05) / refsea;
|
||||
ref = refsea * e0sea * pow(((htop - hsta_km) / htop), 4);
|
||||
}
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ private:
|
||||
arma::vec rotateSatellite(double traveltime, arma::vec X_sat);
|
||||
void topocent(double *Az, double *El, double *D, arma::vec x, arma::vec dx);
|
||||
void togeod(double *dphi, double *dlambda, double *h, double a, double finv, double X, double Y, double Z);
|
||||
void tropo(double *ddr_m, double sinel, double hsta_km, double p_mb, double t_kel, double hum, double hp_km, double htkel_km, double hhum_km);
|
||||
public:
|
||||
int d_nchannels; //!< Number of available channels for positioning
|
||||
int d_valid_observations; //!< Number of valid pseudorange observations (valid satellites)
|
||||
|
910
src/algorithms/PVT/libs/hybrid_ls_pvt.cc
Normal file
910
src/algorithms/PVT/libs/hybrid_ls_pvt.cc
Normal file
@ -0,0 +1,910 @@
|
||||
/*!
|
||||
* \file galileo_e1_ls_pvt.cc
|
||||
* \brief Implementation of a Least Squares Position, Velocity, and Time
|
||||
* (PVT) solver, based on K.Borre's Matlab receiver.
|
||||
* \author Javier Arribas, 2011. jarribas(at)cttc.es
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "hybrid_ls_pvt.h"
|
||||
#include <glog/logging.h>
|
||||
#include "Galileo_E1.h"
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
hybrid_ls_pvt::hybrid_ls_pvt(int nchannels, std::string dump_filename, bool flag_dump_to_file)
|
||||
{
|
||||
// init empty ephemeris for all the available GNSS channels
|
||||
d_nchannels = nchannels;
|
||||
d_Gal_ephemeris = new Galileo_Navigation_Message[nchannels];
|
||||
d_GPS_ephemeris = new Gps_Navigation_Message[nchannels];
|
||||
d_dump_filename = dump_filename;
|
||||
d_flag_dump_enabled = flag_dump_to_file;
|
||||
d_averaging_depth = 0;
|
||||
d_galileo_current_time = 0;
|
||||
b_valid_position = false;
|
||||
// ############# ENABLE DATA FILE LOG #################
|
||||
if (d_flag_dump_enabled == true)
|
||||
{
|
||||
if (d_dump_file.is_open() == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit);
|
||||
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
|
||||
LOG(INFO) << "PVT lib dump enabled Log file: " << d_dump_filename.c_str();
|
||||
}
|
||||
catch (std::ifstream::failure e)
|
||||
{
|
||||
LOG(WARNING) << "Exception opening PVT lib dump file " << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void hybrid_ls_pvt::set_averaging_depth(int depth)
|
||||
{
|
||||
d_averaging_depth = depth;
|
||||
}
|
||||
|
||||
|
||||
hybrid_ls_pvt::~hybrid_ls_pvt()
|
||||
{
|
||||
d_dump_file.close();
|
||||
delete[] d_Gal_ephemeris;
|
||||
delete[] d_GPS_ephemeris;
|
||||
}
|
||||
|
||||
|
||||
arma::vec hybrid_ls_pvt::rotateSatellite(double traveltime, arma::vec X_sat)
|
||||
{
|
||||
/*
|
||||
* Returns rotated satellite ECEF coordinates due to Earth
|
||||
* rotation during signal travel time
|
||||
*
|
||||
* Inputs:
|
||||
* travelTime - signal travel time
|
||||
* X_sat - satellite's ECEF coordinates
|
||||
*
|
||||
* Returns:
|
||||
* X_sat_rot - rotated satellite's coordinates (ECEF)
|
||||
*/
|
||||
|
||||
//--- Find rotation angle --------------------------------------------------
|
||||
double omegatau;
|
||||
omegatau = OMEGA_EARTH_DOT * traveltime;
|
||||
|
||||
//--- Build a rotation matrix ----------------------------------------------
|
||||
arma::mat R3 = arma::zeros(3,3);
|
||||
R3(0, 0) = cos(omegatau);
|
||||
R3(0, 1) = sin(omegatau);
|
||||
R3(0, 2) = 0.0;
|
||||
R3(1, 0) = -sin(omegatau);
|
||||
R3(1, 1) = cos(omegatau);
|
||||
R3(1, 2) = 0.0;
|
||||
R3(2, 0) = 0.0;
|
||||
R3(2, 1) = 0.0;
|
||||
R3(2, 2) = 1;
|
||||
|
||||
//--- Do the rotation ------------------------------------------------------
|
||||
arma::vec X_sat_rot;
|
||||
X_sat_rot = R3 * X_sat;
|
||||
return X_sat_rot;
|
||||
}
|
||||
|
||||
|
||||
arma::vec hybrid_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arma::mat w)
|
||||
{
|
||||
/* Computes the Least Squares Solution.
|
||||
* Inputs:
|
||||
* satpos - Satellites positions in ECEF system: [X; Y; Z;]
|
||||
* obs - Observations - the pseudorange measurements to each satellite
|
||||
* w - weigths vector
|
||||
*
|
||||
* Returns:
|
||||
* pos - receiver position and receiver clock error
|
||||
* (in ECEF system: [X, Y, Z, dt])
|
||||
*/
|
||||
|
||||
//=== Initialization =======================================================
|
||||
int nmbOfIterations = 10; // TODO: include in config
|
||||
int nmbOfSatellites;
|
||||
nmbOfSatellites = satpos.n_cols; //Armadillo
|
||||
arma::vec pos = "0.0 0.0 0.0 0.0";
|
||||
arma::mat A;
|
||||
arma::mat omc;
|
||||
arma::mat az;
|
||||
arma::mat el;
|
||||
A = arma::zeros(nmbOfSatellites, 4);
|
||||
omc = arma::zeros(nmbOfSatellites, 1);
|
||||
az = arma::zeros(1, nmbOfSatellites);
|
||||
el = arma::zeros(1, nmbOfSatellites);
|
||||
arma::mat X = satpos;
|
||||
arma::vec Rot_X;
|
||||
double rho2;
|
||||
double traveltime;
|
||||
double trop;
|
||||
double dlambda;
|
||||
double dphi;
|
||||
double h;
|
||||
arma::mat mat_tmp;
|
||||
arma::vec x;
|
||||
|
||||
//=== Iteratively find receiver position ===================================
|
||||
for (int iter = 0; iter < nmbOfIterations; iter++)
|
||||
{
|
||||
for (int i = 0; i < nmbOfSatellites; i++)
|
||||
{
|
||||
if (iter == 0)
|
||||
{
|
||||
//--- Initialize variables at the first iteration --------------
|
||||
Rot_X = X.col(i); //Armadillo
|
||||
trop = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- Update equations -----------------------------------------
|
||||
rho2 = (X(0, i) - pos(0)) *
|
||||
(X(0, i) - pos(0)) + (X(1, i) - pos(1)) *
|
||||
(X(1, i) - pos(1)) + (X(2, i) - pos(2)) *
|
||||
(X(2, i) - pos(2));
|
||||
traveltime = sqrt(rho2) / GALILEO_C_m_s;
|
||||
|
||||
//--- Correct satellite position (do to earth rotation) --------
|
||||
Rot_X = rotateSatellite(traveltime, X.col(i)); //armadillo
|
||||
|
||||
//--- Find DOA and range of satellites
|
||||
topocent(&d_visible_satellites_Az[i],
|
||||
&d_visible_satellites_El[i],
|
||||
&d_visible_satellites_Distance[i],
|
||||
pos.subvec(0,2),
|
||||
Rot_X - pos.subvec(0, 2));
|
||||
if(traveltime < 0.1 && nmbOfSatellites > 3)
|
||||
{
|
||||
//--- Find receiver's height
|
||||
togeod(&dphi, &dlambda, &h, 6378137.0, 298.257223563, pos(0), pos(1), pos(2));
|
||||
|
||||
//--- Find delay due to troposphere (in meters)
|
||||
tropo(&trop, sin(d_visible_satellites_El[i] * GALILEO_PI/180.0), h/1000, 1013.0, 293.0, 50.0, 0.0, 0.0, 0.0);
|
||||
if(trop > 50.0 ) trop = 0.0;
|
||||
}
|
||||
}
|
||||
//--- Apply the corrections ----------------------------------------
|
||||
omc(i) = (obs(i) - norm(Rot_X - pos.subvec(0, 2), 2) - pos(3) - trop); // Armadillo
|
||||
|
||||
//--- Construct the A matrix ---------------------------------------
|
||||
//Armadillo
|
||||
A(i,0) = (-(Rot_X(0) - pos(0))) / obs(i);
|
||||
A(i,1) = (-(Rot_X(1) - pos(1))) / obs(i);
|
||||
A(i,2) = (-(Rot_X(2) - pos(2))) / obs(i);
|
||||
A(i,3) = 1.0;
|
||||
}
|
||||
|
||||
//--- Find position update ---------------------------------------------
|
||||
x = arma::solve(w*A, w*omc); // Armadillo
|
||||
|
||||
//--- Apply position update --------------------------------------------
|
||||
pos = pos + x;
|
||||
if (arma::norm(x,2) < 1e-4)
|
||||
{
|
||||
break; // exit the loop because we assume that the LS algorithm has converged (err < 0.1 cm)
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//-- compute the Dilution Of Precision values
|
||||
d_Q = arma::inv(arma::htrans(A)*A);
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
d_Q = arma::zeros(4,4);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
bool hybrid_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map, double hybrid_current_time, bool flag_averaging)
|
||||
{
|
||||
std::map<int,Gnss_Synchro>::iterator gnss_pseudoranges_iter;
|
||||
std::map<int,Galileo_Ephemeris>::iterator galileo_ephemeris_iter;
|
||||
std::map<int,Gps_Ephemeris>::iterator gps_ephemeris_iter;
|
||||
int valid_pseudoranges = gnss_pseudoranges_map.size();
|
||||
|
||||
arma::mat W = arma::eye(valid_pseudoranges, valid_pseudoranges); // channels weights matrix
|
||||
arma::vec obs = arma::zeros(valid_pseudoranges); // pseudoranges observation vector
|
||||
arma::mat satpos = arma::zeros(3, valid_pseudoranges); // satellite positions matrix
|
||||
|
||||
int Galileo_week_number = 0;
|
||||
int GPS_week;
|
||||
double utc = 0;
|
||||
double utc_tx_corrected = 0; //utc computed at tx_time_corrected, added for Galileo constellation (in GPS utc is directly computed at TX_time_corrected_s)
|
||||
double TX_time_corrected_s;
|
||||
double SV_clock_bias_s = 0;
|
||||
|
||||
d_flag_averaging = flag_averaging;
|
||||
|
||||
// ********************************************************************************
|
||||
// ****** PREPARE THE LEAST SQUARES DATA (SV POSITIONS MATRIX AND OBS VECTORS) ****
|
||||
// ********************************************************************************
|
||||
int valid_obs = 0; //valid observations counter
|
||||
int obs_counter = 0;
|
||||
int valid_obs_GPS_counter = 0;
|
||||
int valid_obs_GALILEO_counter = 0;
|
||||
for(gnss_pseudoranges_iter = gnss_pseudoranges_map.begin();
|
||||
gnss_pseudoranges_iter != gnss_pseudoranges_map.end();
|
||||
gnss_pseudoranges_iter++)
|
||||
{
|
||||
|
||||
if (gnss_pseudoranges_iter->second.System == 'E')
|
||||
{
|
||||
//std::cout << "Satellite System: " << gnss_pseudoranges_iter->second.System <<std::endl;
|
||||
// 1 Gal - find the ephemeris for the current GALILEO SV observation. The SV PRN ID is the map key
|
||||
galileo_ephemeris_iter = galileo_ephemeris_map.find(gnss_pseudoranges_iter->first);
|
||||
if (galileo_ephemeris_iter != galileo_ephemeris_map.end())
|
||||
{
|
||||
/*!
|
||||
* \todo Place here the satellite CN0 (power level, or weight factor)
|
||||
*/
|
||||
W(obs_counter, obs_counter) = 1;
|
||||
|
||||
// COMMON RX TIME PVT ALGORITHM MODIFICATION (Like RINEX files)
|
||||
// first estimate of transmit time
|
||||
//Galileo_week_number = galileo_ephemeris_iter->second.WN_5;//for GST
|
||||
//double sec_in_day = 86400;
|
||||
//double day_in_week = 7;
|
||||
// t = WN*sec_in_day*day_in_week + TOW; // t is Galileo System Time to use to compute satellite positions
|
||||
|
||||
double Rx_time = hybrid_current_time;
|
||||
double Tx_time = Rx_time - gnss_pseudoranges_iter->second.Pseudorange_m/GALILEO_C_m_s;
|
||||
|
||||
// 2- compute the clock drift using the clock model (broadcast) for this SV
|
||||
SV_clock_bias_s = galileo_ephemeris_iter->second.sv_clock_drift(Tx_time);
|
||||
|
||||
// 3- compute the current ECEF position for this SV using corrected TX time
|
||||
TX_time_corrected_s = Tx_time - SV_clock_bias_s;
|
||||
galileo_ephemeris_iter->second.satellitePosition(TX_time_corrected_s);
|
||||
|
||||
satpos(0,obs_counter) = galileo_ephemeris_iter->second.d_satpos_X;
|
||||
satpos(1,obs_counter) = galileo_ephemeris_iter->second.d_satpos_Y;
|
||||
satpos(2,obs_counter) = galileo_ephemeris_iter->second.d_satpos_Z;
|
||||
|
||||
// 5- fill the observations vector with the corrected pseudoranges
|
||||
obs(obs_counter) = gnss_pseudoranges_iter->second.Pseudorange_m + SV_clock_bias_s*GALILEO_C_m_s;
|
||||
d_visible_satellites_IDs[valid_obs] = galileo_ephemeris_iter->second.i_satellite_PRN;
|
||||
d_visible_satellites_CN0_dB[valid_obs] = gnss_pseudoranges_iter->second.CN0_dB_hz;
|
||||
valid_obs++;
|
||||
valid_obs_GALILEO_counter ++;
|
||||
Galileo_week_number = galileo_ephemeris_iter->second.WN_5; //for GST
|
||||
|
||||
//debug
|
||||
double GST = galileo_ephemeris_iter->second.Galileo_System_Time(Galileo_week_number, hybrid_current_time);
|
||||
utc = galileo_utc_model.GST_to_UTC_time(GST, Galileo_week_number); // this shoud be removed and it should be considered the utc_tx_corrected
|
||||
utc_tx_corrected = galileo_utc_model.GST_to_UTC_time(TX_time_corrected_s, Galileo_week_number);
|
||||
//std::cout<<"Gal UTC at TX_time_corrected_s = "<<utc_tx_corrected<< std::endl;
|
||||
//std::cout<<"Gal_week = "<<Galileo_week_number<< std::endl;
|
||||
//std::cout << "Gal UTC = " << utc << std::endl;
|
||||
// get time string gregorian calendar
|
||||
boost::posix_time::time_duration t = boost::posix_time::seconds(utc);
|
||||
// 22 August 1999 00:00 last Galileo start GST epoch (ICD sec 5.1.2)
|
||||
boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t);
|
||||
d_position_UTC_time = p_time;
|
||||
LOG(INFO) << "Galileo RX time at " << boost::posix_time::to_simple_string(p_time);
|
||||
//end debug
|
||||
|
||||
// SV ECEF DEBUG OUTPUT
|
||||
LOG(INFO) << "ECEF satellite SV ID=" << galileo_ephemeris_iter->second.i_satellite_PRN
|
||||
<< " X=" << galileo_ephemeris_iter->second.d_satpos_X
|
||||
<< " [m] Y=" << galileo_ephemeris_iter->second.d_satpos_Y
|
||||
<< " [m] Z=" << galileo_ephemeris_iter->second.d_satpos_Z
|
||||
<< " [m] PR_obs=" << obs(obs_counter) << " [m]";
|
||||
}
|
||||
|
||||
else // the ephemeris are not available for this SV
|
||||
{
|
||||
// no valid pseudorange for the current SV
|
||||
W(obs_counter, obs_counter) = 0; // SV de-activated
|
||||
obs(obs_counter) = 1; // to avoid algorithm problems (divide by zero)
|
||||
DLOG(INFO) << "No ephemeris data for SV " << gnss_pseudoranges_iter->first;
|
||||
}
|
||||
}
|
||||
|
||||
else if (gnss_pseudoranges_iter->second.System == 'G')
|
||||
{
|
||||
//std::cout << "Satellite System: " << gnss_pseudoranges_iter->second.System <<std::endl;
|
||||
// 1 GPS - find the ephemeris for the current GPS SV observation. The SV PRN ID is the map key
|
||||
gps_ephemeris_iter = gps_ephemeris_map.find(gnss_pseudoranges_iter->first);
|
||||
if (gps_ephemeris_iter != gps_ephemeris_map.end())
|
||||
{
|
||||
/*!
|
||||
* \todo Place here the satellite CN0 (power level, or weight factor)
|
||||
*/
|
||||
W(obs_counter, obs_counter) = 1;
|
||||
|
||||
// COMMON RX TIME PVT ALGORITHM MODIFICATION (Like RINEX files)
|
||||
// first estimate of transmit time
|
||||
double Rx_time = hybrid_current_time;
|
||||
double Tx_time = Rx_time - gnss_pseudoranges_iter->second.Pseudorange_m/GPS_C_m_s;
|
||||
|
||||
// 2- compute the clock drift using the clock model (broadcast) for this SV
|
||||
SV_clock_bias_s = gps_ephemeris_iter->second.sv_clock_drift(Tx_time);
|
||||
|
||||
// 3- compute the current ECEF position for this SV using corrected TX time
|
||||
TX_time_corrected_s = Tx_time - SV_clock_bias_s;
|
||||
gps_ephemeris_iter->second.satellitePosition(TX_time_corrected_s);
|
||||
|
||||
satpos(0, obs_counter) = gps_ephemeris_iter->second.d_satpos_X;
|
||||
satpos(1, obs_counter) = gps_ephemeris_iter->second.d_satpos_Y;
|
||||
satpos(2, obs_counter) = gps_ephemeris_iter->second.d_satpos_Z;
|
||||
|
||||
// 5- fill the observations vector with the corrected pseudorranges
|
||||
obs(obs_counter) = gnss_pseudoranges_iter->second.Pseudorange_m + SV_clock_bias_s*GPS_C_m_s;
|
||||
d_visible_satellites_IDs[valid_obs] = gps_ephemeris_iter->second.i_satellite_PRN;
|
||||
d_visible_satellites_CN0_dB[valid_obs] = gnss_pseudoranges_iter->second.CN0_dB_hz;
|
||||
valid_obs++;
|
||||
valid_obs_GPS_counter++;
|
||||
// SV ECEF DEBUG OUTPUT
|
||||
LOG(INFO) << "(new)ECEF satellite SV ID=" << gps_ephemeris_iter->second.i_satellite_PRN
|
||||
<< " X=" << gps_ephemeris_iter->second.d_satpos_X
|
||||
<< " [m] Y=" << gps_ephemeris_iter->second.d_satpos_Y
|
||||
<< " [m] Z=" << gps_ephemeris_iter->second.d_satpos_Z
|
||||
<< " [m] PR_obs=" << obs(obs_counter) << " [m]";
|
||||
|
||||
// compute the UTC time for this SV (just to print the asociated UTC timestamp)
|
||||
GPS_week = gps_ephemeris_iter->second.i_GPS_week;
|
||||
utc = gps_utc_model.utc_time(TX_time_corrected_s, GPS_week);
|
||||
}
|
||||
else // the ephemeris are not available for this SV
|
||||
{
|
||||
// no valid pseudorange for the current SV
|
||||
W(obs_counter, obs_counter) = 0; // SV de-activated
|
||||
obs(obs_counter) = 1; // to avoid algorithm problems (divide by zero)
|
||||
DLOG(INFO) << "No ephemeris data for SV " << gnss_pseudoranges_iter->first;
|
||||
}
|
||||
}
|
||||
obs_counter++;
|
||||
}
|
||||
|
||||
// ********************************************************************************
|
||||
// ****** SOLVE LEAST SQUARES******************************************************
|
||||
// ********************************************************************************
|
||||
d_valid_observations = valid_obs;
|
||||
d_valid_GPS_obs = valid_obs_GPS_counter;
|
||||
d_valid_GAL_obs = valid_obs_GALILEO_counter;
|
||||
LOG(INFO) << "HYBRID PVT: valid observations=" << valid_obs;
|
||||
|
||||
if (valid_obs >= 4)
|
||||
{
|
||||
arma::vec mypos;
|
||||
DLOG(INFO) << "satpos=" << satpos;
|
||||
DLOG(INFO) << "obs="<< obs;
|
||||
DLOG(INFO) << "W=" << W;
|
||||
mypos = leastSquarePos(satpos, obs, W);
|
||||
|
||||
// Compute GST and Gregorian time
|
||||
double GST = galileo_ephemeris_iter->second.Galileo_System_Time(Galileo_week_number, hybrid_current_time);
|
||||
utc = galileo_utc_model.GST_to_UTC_time(GST, Galileo_week_number);
|
||||
// get time string Gregorian calendar
|
||||
boost::posix_time::time_duration t = boost::posix_time::seconds(utc);
|
||||
// 22 August 1999 00:00 last Galileo start GST epoch (ICD sec 5.1.2)
|
||||
boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t);
|
||||
d_position_UTC_time = p_time;
|
||||
LOG(INFO) << "HYBRID Position at TOW=" << hybrid_current_time << " in ECEF (X,Y,Z) = " << mypos;
|
||||
|
||||
cart2geo((double)mypos(0), (double)mypos(1), (double)mypos(2), 4);
|
||||
//ToDo: Find an Observables/PVT random bug with some satellite configurations that gives an erratic PVT solution (i.e. height>50 km)
|
||||
if (d_height_m > 50000)
|
||||
{
|
||||
b_valid_position = false;
|
||||
LOG(INFO) << "Hybrid Position at " << boost::posix_time::to_simple_string(p_time)
|
||||
<< " is Lat = " << d_latitude_d << " [deg], Long = " << d_longitude_d
|
||||
<< " [deg], Height= " << d_height_m << " [m]";
|
||||
|
||||
//std::cout << "Hybrid Position at " << boost::posix_time::to_simple_string(p_time)
|
||||
// << " is Lat = " << d_latitude_d << " [deg], Long = " << d_longitude_d
|
||||
// << " [deg], Height= " << d_height_m << " [m]" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG(INFO) << "Hybrid Position at " << boost::posix_time::to_simple_string(p_time)
|
||||
<< " is Lat = " << d_latitude_d << " [deg], Long = " << d_longitude_d
|
||||
<< " [deg], Height= " << d_height_m << " [m]";
|
||||
|
||||
|
||||
// ###### Compute DOPs ########
|
||||
// 1- Rotation matrix from ECEF coordinates to ENU coordinates
|
||||
// ref: http://www.navipedia.net/index.php/Transformations_between_ECEF_and_ENU_coordinates
|
||||
arma::mat F = arma::zeros(3,3);
|
||||
F(0,0) = -sin(GPS_TWO_PI*(d_longitude_d/360.0));
|
||||
F(0,1) = -sin(GPS_TWO_PI*(d_latitude_d/360.0))*cos(GPS_TWO_PI*(d_longitude_d/360.0));
|
||||
F(0,2) = cos(GPS_TWO_PI*(d_latitude_d/360.0))*cos(GPS_TWO_PI*(d_longitude_d/360.0));
|
||||
|
||||
F(1,0) = cos((GPS_TWO_PI*d_longitude_d)/360.0);
|
||||
F(1,1) = -sin((GPS_TWO_PI*d_latitude_d)/360.0)*sin((GPS_TWO_PI*d_longitude_d)/360.0);
|
||||
F(1,2) = cos((GPS_TWO_PI*d_latitude_d/360.0))*sin((GPS_TWO_PI*d_longitude_d)/360.0);
|
||||
|
||||
F(2,0) = 0;
|
||||
F(2,1) = cos((GPS_TWO_PI*d_latitude_d)/360.0);
|
||||
F(2,2) = sin((GPS_TWO_PI*d_latitude_d/360.0));
|
||||
|
||||
// 2- Apply the rotation to the latest covariance matrix (available in ECEF from LS)
|
||||
arma::mat Q_ECEF = d_Q.submat(0, 0, 2, 2);
|
||||
arma::mat DOP_ENU = arma::zeros(3, 3);
|
||||
|
||||
try
|
||||
{
|
||||
DOP_ENU = arma::htrans(F)*Q_ECEF*F;
|
||||
d_GDOP = sqrt(arma::trace(DOP_ENU)); // Geometric DOP
|
||||
d_PDOP = sqrt(DOP_ENU(0,0) + DOP_ENU(1,1) + DOP_ENU(2,2)); // PDOP
|
||||
d_HDOP = sqrt(DOP_ENU(0,0) + DOP_ENU(1,1)); // HDOP
|
||||
d_VDOP = sqrt(DOP_ENU(2,2)); // VDOP
|
||||
d_TDOP = sqrt(d_Q(3,3)); // TDOP
|
||||
}
|
||||
catch(std::exception& ex)
|
||||
{
|
||||
d_GDOP = -1; // Geometric DOP
|
||||
d_PDOP = -1; // PDOP
|
||||
d_HDOP = -1; // HDOP
|
||||
d_VDOP = -1; // VDOP
|
||||
d_TDOP = -1; // TDOP
|
||||
}
|
||||
|
||||
// ######## LOG FILE #########
|
||||
if(d_flag_dump_enabled == true)
|
||||
{
|
||||
// MULTIPLEXED FILE RECORDING - Record results to file
|
||||
try
|
||||
{
|
||||
double tmp_double;
|
||||
// PVT GPS time
|
||||
tmp_double = hybrid_current_time;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// ECEF User Position East [m]
|
||||
tmp_double = mypos(0);
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// ECEF User Position North [m]
|
||||
tmp_double = mypos(1);
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// ECEF User Position Up [m]
|
||||
tmp_double = mypos(2);
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// User clock offset [s]
|
||||
tmp_double = mypos(3);
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// GEO user position Latitude [deg]
|
||||
tmp_double = d_latitude_d;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// GEO user position Longitude [deg]
|
||||
tmp_double = d_longitude_d;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
// GEO user position Height [m]
|
||||
tmp_double = d_height_m;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
}
|
||||
catch (const std::ifstream::failure& e)
|
||||
{
|
||||
LOG(WARNING) << "Exception writing PVT LS dump file "<< e.what();
|
||||
}
|
||||
}
|
||||
|
||||
// MOVING AVERAGE PVT
|
||||
if (flag_averaging == true)
|
||||
{
|
||||
if (d_hist_longitude_d.size() == (unsigned int)d_averaging_depth)
|
||||
{
|
||||
// Pop oldest value
|
||||
d_hist_longitude_d.pop_back();
|
||||
d_hist_latitude_d.pop_back();
|
||||
d_hist_height_m.pop_back();
|
||||
// Push new values
|
||||
d_hist_longitude_d.push_front(d_longitude_d);
|
||||
d_hist_latitude_d.push_front(d_latitude_d);
|
||||
d_hist_height_m.push_front(d_height_m);
|
||||
|
||||
d_avg_latitude_d = 0;
|
||||
d_avg_longitude_d = 0;
|
||||
d_avg_height_m = 0;
|
||||
for (unsigned int i = 0; i < d_hist_longitude_d.size(); i++)
|
||||
{
|
||||
d_avg_latitude_d = d_avg_latitude_d + d_hist_latitude_d.at(i);
|
||||
d_avg_longitude_d = d_avg_longitude_d + d_hist_longitude_d.at(i);
|
||||
d_avg_height_m = d_avg_height_m + d_hist_height_m.at(i);
|
||||
}
|
||||
d_avg_latitude_d = d_avg_latitude_d / (double)d_averaging_depth;
|
||||
d_avg_longitude_d = d_avg_longitude_d / (double)d_averaging_depth;
|
||||
d_avg_height_m = d_avg_height_m / (double)d_averaging_depth;
|
||||
b_valid_position = true;
|
||||
return true; //indicates that the returned position is valid
|
||||
}
|
||||
else
|
||||
{
|
||||
// int current_depth=d_hist_longitude_d.size();
|
||||
// Push new values
|
||||
d_hist_longitude_d.push_front(d_longitude_d);
|
||||
d_hist_latitude_d.push_front(d_latitude_d);
|
||||
d_hist_height_m.push_front(d_height_m);
|
||||
|
||||
d_avg_latitude_d = d_latitude_d;
|
||||
d_avg_longitude_d = d_longitude_d;
|
||||
d_avg_height_m = d_height_m;
|
||||
b_valid_position = false;
|
||||
return false; //indicates that the returned position is not valid yet
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
b_valid_position = true;
|
||||
return true; //indicates that the returned position is valid
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
b_valid_position = false;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void hybrid_ls_pvt::cart2geo(double X, double Y, double Z, int elipsoid_selection)
|
||||
{
|
||||
/* Conversion of Cartesian coordinates (X,Y,Z) to geographical
|
||||
coordinates (latitude, longitude, h) on a selected reference ellipsoid.
|
||||
|
||||
Choices of Reference Ellipsoid for Geographical Coordinates
|
||||
0. International Ellipsoid 1924
|
||||
1. International Ellipsoid 1967
|
||||
2. World Geodetic System 1972
|
||||
3. Geodetic Reference System 1980
|
||||
4. World Geodetic System 1984
|
||||
*/
|
||||
|
||||
const double a[5] = {6378388, 6378160, 6378135, 6378137, 6378137};
|
||||
const double f[5] = {1/297, 1/298.247, 1/298.26, 1/298.257222101, 1/298.257223563};
|
||||
|
||||
double lambda = atan2(Y, X);
|
||||
double ex2 = (2 - f[elipsoid_selection]) * f[elipsoid_selection] / ((1 - f[elipsoid_selection])*(1 - f[elipsoid_selection]));
|
||||
double c = a[elipsoid_selection] * sqrt(1+ex2);
|
||||
double phi = atan(Z / ((sqrt(X*X + Y*Y)*(1 - (2 - f[elipsoid_selection])) * f[elipsoid_selection])));
|
||||
|
||||
double h = 0.1;
|
||||
double oldh = 0;
|
||||
double N;
|
||||
int iterations = 0;
|
||||
do
|
||||
{
|
||||
oldh = h;
|
||||
N = c / sqrt(1 + ex2 * (cos(phi) * cos(phi)));
|
||||
phi = atan(Z / ((sqrt(X*X + Y*Y) * (1 - (2 - f[elipsoid_selection]) * f[elipsoid_selection] *N / (N + h) ))));
|
||||
h = sqrt(X*X + Y*Y) / cos(phi) - N;
|
||||
iterations = iterations + 1;
|
||||
if (iterations > 100)
|
||||
{
|
||||
LOG(WARNING) << "Failed to approximate h with desired precision. h-oldh= " << h - oldh;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (abs(h - oldh) > 1.0e-12);
|
||||
d_latitude_d = phi * 180.0 / GPS_PI;
|
||||
d_longitude_d = lambda * 180 / GPS_PI;
|
||||
d_height_m = h;
|
||||
}
|
||||
|
||||
|
||||
void hybrid_ls_pvt::togeod(double *dphi, double *dlambda, double *h, double a, double finv, double X, double Y, double Z)
|
||||
{
|
||||
/* Subroutine to calculate geodetic coordinates latitude, longitude,
|
||||
height given Cartesian coordinates X,Y,Z, and reference ellipsoid
|
||||
values semi-major axis (a) and the inverse of flattening (finv).
|
||||
|
||||
The output units of angular quantities will be in decimal degrees
|
||||
(15.5 degrees not 15 deg 30 min). The output units of h will be the
|
||||
same as the units of X,Y,Z,a.
|
||||
|
||||
Inputs:
|
||||
a - semi-major axis of the reference ellipsoid
|
||||
finv - inverse of flattening of the reference ellipsoid
|
||||
X,Y,Z - Cartesian coordinates
|
||||
|
||||
Outputs:
|
||||
dphi - latitude
|
||||
dlambda - longitude
|
||||
h - height above reference ellipsoid
|
||||
|
||||
Based in a Matlab function by Kai Borre
|
||||
*/
|
||||
|
||||
*h = 0;
|
||||
double tolsq = 1.e-10; // tolerance to accept convergence
|
||||
int maxit = 10; // max number of iterations
|
||||
double rtd = 180/GPS_PI;
|
||||
|
||||
// compute square of eccentricity
|
||||
double esq;
|
||||
if (finv < 1.0E-20)
|
||||
{
|
||||
esq = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
esq = (2 - 1/finv) / finv;
|
||||
}
|
||||
|
||||
// first guess
|
||||
double P = sqrt(X*X + Y*Y); // P is distance from spin axis
|
||||
|
||||
//direct calculation of longitude
|
||||
if (P > 1.0E-20)
|
||||
{
|
||||
*dlambda = atan2(Y, X) * rtd;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dlambda = 0;
|
||||
}
|
||||
|
||||
// correct longitude bound
|
||||
if (*dlambda < 0)
|
||||
{
|
||||
*dlambda = *dlambda + 360.0;
|
||||
}
|
||||
|
||||
double r = sqrt(P*P + Z*Z); // r is distance from origin (0,0,0)
|
||||
|
||||
double sinphi;
|
||||
if (r > 1.0E-20)
|
||||
{
|
||||
sinphi = Z/r;
|
||||
}
|
||||
else
|
||||
{
|
||||
sinphi = 0;
|
||||
}
|
||||
*dphi = asin(sinphi);
|
||||
|
||||
// initial value of height = distance from origin minus
|
||||
// approximate distance from origin to surface of ellipsoid
|
||||
if (r < 1.0E-20)
|
||||
{
|
||||
*h = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
*h = r - a*(1 - sinphi*sinphi/finv);
|
||||
|
||||
// iterate
|
||||
double cosphi;
|
||||
double N_phi;
|
||||
double dP;
|
||||
double dZ;
|
||||
double oneesq = 1 - esq;
|
||||
|
||||
for (int i = 0; i < maxit; i++)
|
||||
{
|
||||
sinphi = sin(*dphi);
|
||||
cosphi = cos(*dphi);
|
||||
|
||||
// compute radius of curvature in prime vertical direction
|
||||
N_phi = a / sqrt(1 - esq*sinphi*sinphi);
|
||||
|
||||
// compute residuals in P and Z
|
||||
dP = P - (N_phi + (*h)) * cosphi;
|
||||
dZ = Z - (N_phi*oneesq + (*h)) * sinphi;
|
||||
|
||||
// update height and latitude
|
||||
*h = *h + (sinphi*dZ + cosphi*dP);
|
||||
*dphi = *dphi + (cosphi*dZ - sinphi*dP)/(N_phi + (*h));
|
||||
|
||||
// test for convergence
|
||||
if ((dP*dP + dZ*dZ) < tolsq)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (i == (maxit - 1))
|
||||
{
|
||||
LOG(WARNING) << "The computation of geodetic coordinates did not converge";
|
||||
}
|
||||
}
|
||||
*dphi = (*dphi) * rtd;
|
||||
}
|
||||
|
||||
|
||||
void hybrid_ls_pvt::topocent(double *Az, double *El, double *D, arma::vec x, arma::vec dx)
|
||||
{
|
||||
/* Transformation of vector dx into topocentric coordinate
|
||||
system with origin at x
|
||||
Inputs:
|
||||
x - vector origin coordinates (in ECEF system [X; Y; Z;])
|
||||
dx - vector ([dX; dY; dZ;]).
|
||||
|
||||
Outputs:
|
||||
D - vector length. Units like the input
|
||||
Az - azimuth from north positive clockwise, degrees
|
||||
El - elevation angle, degrees
|
||||
|
||||
Based on a Matlab function by Kai Borre
|
||||
*/
|
||||
double lambda;
|
||||
double phi;
|
||||
double h;
|
||||
double dtr = GPS_PI/180.0;
|
||||
double a = 6378137.0; // semi-major axis of the reference ellipsoid WGS-84
|
||||
double finv = 298.257223563; // inverse of flattening of the reference ellipsoid WGS-84
|
||||
|
||||
// Transform x into geodetic coordinates
|
||||
togeod(&phi, &lambda, &h, a, finv, x(0), x(1), x(2));
|
||||
|
||||
double cl = cos(lambda * dtr);
|
||||
double sl = sin(lambda * dtr);
|
||||
double cb = cos(phi * dtr);
|
||||
double sb = sin(phi * dtr);
|
||||
|
||||
arma::mat F = arma::zeros(3,3);
|
||||
|
||||
F(0,0) = -sl;
|
||||
F(0,1) = -sb*cl;
|
||||
F(0,2) = cb*cl;
|
||||
|
||||
F(1,0) = cl;
|
||||
F(1,1) = -sb*sl;
|
||||
F(1,2) = cb*sl;
|
||||
|
||||
F(2,0) = 0;
|
||||
F(2,1) = cb;
|
||||
F(2,2) = sb;
|
||||
|
||||
arma::vec local_vector;
|
||||
|
||||
local_vector = arma::htrans(F) * dx;
|
||||
|
||||
double E = local_vector(0);
|
||||
double N = local_vector(1);
|
||||
double U = local_vector(2);
|
||||
|
||||
double hor_dis;
|
||||
hor_dis = sqrt(E*E + N*N);
|
||||
|
||||
if (hor_dis < 1.0E-20)
|
||||
{
|
||||
*Az = 0;
|
||||
*El = 90;
|
||||
}
|
||||
else
|
||||
{
|
||||
*Az = atan2(E, N)/dtr;
|
||||
*El = atan2(U, hor_dis)/dtr;
|
||||
}
|
||||
|
||||
if (*Az < 0)
|
||||
{
|
||||
*Az = *Az + 360.0;
|
||||
}
|
||||
|
||||
*D = sqrt(dx(0)*dx(0) + dx(1)*dx(1) + dx(2)*dx(2));
|
||||
}
|
||||
|
||||
|
||||
void hybrid_ls_pvt::tropo(double *ddr_m, double sinel, double hsta_km, double p_mb, double t_kel, double hum, double hp_km, double htkel_km, double hhum_km)
|
||||
{
|
||||
/* Inputs:
|
||||
sinel - sin of elevation angle of satellite
|
||||
hsta_km - height of station in km
|
||||
p_mb - atmospheric pressure in mb at height hp_km
|
||||
t_kel - surface temperature in degrees Kelvin at height htkel_km
|
||||
hum - humidity in % at height hhum_km
|
||||
hp_km - height of pressure measurement in km
|
||||
htkel_km - height of temperature measurement in km
|
||||
hhum_km - height of humidity measurement in km
|
||||
|
||||
Outputs:
|
||||
ddr_m - range correction (meters)
|
||||
|
||||
Reference
|
||||
Goad, C.C. & Goodman, L. (1974) A Modified Hopfield Tropospheric
|
||||
Refraction Correction Model. Paper presented at the
|
||||
American Geophysical Union Annual Fall Meeting, San
|
||||
Francisco, December 12-17
|
||||
|
||||
Translated to C++ by Carles Fernandez from a Matlab implementation by Kai Borre
|
||||
*/
|
||||
|
||||
const double a_e = 6378.137; // semi-major axis of earth ellipsoid
|
||||
const double b0 = 7.839257e-5;
|
||||
const double tlapse = -6.5;
|
||||
const double em = -978.77 / (2.8704e6 * tlapse * 1.0e-5);
|
||||
|
||||
double tkhum = t_kel + tlapse * (hhum_km - htkel_km);
|
||||
double atkel = 7.5*(tkhum - 273.15) / (237.3 + tkhum - 273.15);
|
||||
double e0 = 0.0611 * hum * pow(10, atkel);
|
||||
double tksea = t_kel - tlapse * htkel_km;
|
||||
double tkelh = tksea + tlapse * hhum_km;
|
||||
double e0sea = e0 * pow((tksea / tkelh), (4 * em));
|
||||
double tkelp = tksea + tlapse * hp_km;
|
||||
double psea = p_mb * pow((tksea / tkelp), em);
|
||||
|
||||
if(sinel < 0) { sinel = 0.0; }
|
||||
|
||||
double tropo_delay = 0.0;
|
||||
bool done = false;
|
||||
double refsea = 77.624e-6 / tksea;
|
||||
double htop = 1.1385e-5 / refsea;
|
||||
refsea = refsea * psea;
|
||||
double ref = refsea * pow(((htop - hsta_km) / htop), 4);
|
||||
|
||||
double a;
|
||||
double b;
|
||||
double rtop;
|
||||
|
||||
while(1)
|
||||
{
|
||||
rtop = pow((a_e + htop), 2) - pow((a_e + hsta_km), 2) * (1 - pow(sinel, 2));
|
||||
|
||||
// check to see if geometry is crazy
|
||||
if(rtop < 0) { rtop = 0; }
|
||||
|
||||
rtop = sqrt(rtop) - (a_e + hsta_km) * sinel;
|
||||
|
||||
a = -sinel / (htop - hsta_km);
|
||||
b = -b0 * (1 - pow(sinel,2)) / (htop - hsta_km);
|
||||
|
||||
arma::vec rn = arma::vec(8);
|
||||
rn.zeros();
|
||||
|
||||
for(int i = 0; i<8; i++)
|
||||
{
|
||||
rn(i) = pow(rtop, (i+1+1));
|
||||
|
||||
}
|
||||
|
||||
arma::rowvec alpha = {2 * a, 2 * pow(a, 2) + 4 * b /3, a * (pow(a, 2) + 3 * b),
|
||||
pow(a, 4)/5 + 2.4 * pow(a, 2) * b + 1.2 * pow(b, 2), 2 * a * b * (pow(a, 2) + 3 * b)/3,
|
||||
pow(b, 2) * (6 * pow(a, 2) + 4 * b) * 1.428571e-1, 0, 0};
|
||||
|
||||
if(pow(b, 2) > 1.0e-35)
|
||||
{
|
||||
alpha(6) = a * pow(b, 3) /2;
|
||||
alpha(7) = pow(b, 4) / 9;
|
||||
}
|
||||
|
||||
double dr = rtop;
|
||||
arma::mat aux_ = alpha * rn;
|
||||
dr = dr + aux_(0, 0);
|
||||
tropo_delay = tropo_delay + dr * ref * 1000;
|
||||
|
||||
if(done == true)
|
||||
{
|
||||
*ddr_m = tropo_delay;
|
||||
break;
|
||||
}
|
||||
|
||||
done = true;
|
||||
refsea = (371900.0e-6 / tksea - 12.92e-6) / tksea;
|
||||
htop = 1.1385e-5 * (1255 / tksea + 0.05) / refsea;
|
||||
ref = refsea * e0sea * pow(((htop - hsta_km) / htop), 4);
|
||||
}
|
||||
}
|
153
src/algorithms/PVT/libs/hybrid_ls_pvt.h
Normal file
153
src/algorithms/PVT/libs/hybrid_ls_pvt.h
Normal file
@ -0,0 +1,153 @@
|
||||
/*!
|
||||
* \file galileo_e1_ls_pvt.h
|
||||
* \brief Interface of a Least Squares Position, Velocity, and Time (PVT)
|
||||
* solver, based on K.Borre's Matlab receiver.
|
||||
* \author Javier Arribas, 2011. jarribas(at)cttc.es
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_HYBRID_LS_PVT_H_
|
||||
#define GNSS_SDR_HYBRID_LS_PVT_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <deque>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <armadillo>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "galileo_navigation_message.h"
|
||||
#include "gps_navigation_message.h"
|
||||
#include "gnss_synchro.h"
|
||||
#include "galileo_ephemeris.h"
|
||||
#include "galileo_utc_model.h"
|
||||
#include "gps_ephemeris.h"
|
||||
#include "gps_utc_model.h"
|
||||
|
||||
#define PVT_MAX_CHANNELS 24
|
||||
|
||||
/*!
|
||||
* \brief This class implements a simple PVT Least Squares solution
|
||||
*/
|
||||
class hybrid_ls_pvt
|
||||
{
|
||||
private:
|
||||
arma::vec leastSquarePos(arma::mat satpos, arma::vec obs, arma::mat w);
|
||||
arma::vec rotateSatellite(double traveltime, arma::vec X_sat);
|
||||
void topocent(double *Az, double *El, double *D, arma::vec x, arma::vec dx);
|
||||
void togeod(double *dphi, double *dlambda, double *h, double a, double finv, double X, double Y, double Z);
|
||||
void tropo(double *ddr_m, double sinel, double hsta_km, double p_mb, double t_kel, double hum, double hp_km, double htkel_km, double hhum_km);
|
||||
public:
|
||||
int d_nchannels; //!< Number of available channels for positioning
|
||||
int d_valid_observations; //!< Number of valid pseudorange observations (valid satellites)
|
||||
int d_valid_GPS_obs; //!< Number of valid GPS pseudorange observations (valid GPS satellites) -- used for hybrid configuration
|
||||
int d_valid_GAL_obs; //!< Number of valid GALILEO pseudorange observations (valid GALILEO satellites) -- used for hybrid configuration
|
||||
int d_visible_satellites_IDs[PVT_MAX_CHANNELS]; //!< Array with the IDs of the valid satellites
|
||||
double d_visible_satellites_El[PVT_MAX_CHANNELS]; //!< Array with the LOS Elevation of the valid satellites
|
||||
double d_visible_satellites_Az[PVT_MAX_CHANNELS]; //!< Array with the LOS Azimuth of the valid satellites
|
||||
double d_visible_satellites_Distance[PVT_MAX_CHANNELS]; //!< Array with the LOS Distance of the valid satellites
|
||||
double d_visible_satellites_CN0_dB[PVT_MAX_CHANNELS]; //!< Array with the IDs of the valid satellites
|
||||
|
||||
Galileo_Navigation_Message* d_Gal_ephemeris;
|
||||
Gps_Navigation_Message* d_GPS_ephemeris;
|
||||
|
||||
std::map<int,Galileo_Ephemeris> galileo_ephemeris_map; //!< Map storing new Galileo_Ephemeris
|
||||
std::map<int,Gps_Ephemeris> gps_ephemeris_map; //!< Map storing new Galileo_Ephemeris
|
||||
Galileo_Utc_Model galileo_utc_model;
|
||||
Galileo_Iono galileo_iono;
|
||||
Galileo_Almanac galileo_almanac;
|
||||
|
||||
Gps_Utc_Model gps_utc_model;
|
||||
Gps_Iono gps_iono;
|
||||
|
||||
double d_galileo_current_time;
|
||||
boost::posix_time::ptime d_position_UTC_time;
|
||||
bool b_valid_position;
|
||||
int count_valid_position;
|
||||
double d_latitude_d; //!< Latitude in degrees
|
||||
double d_longitude_d; //!< Longitude in degrees
|
||||
double d_height_m; //!< Height [m]
|
||||
//averaging
|
||||
std::deque<double> d_hist_latitude_d;
|
||||
std::deque<double> d_hist_longitude_d;
|
||||
std::deque<double> d_hist_height_m;
|
||||
int d_averaging_depth; //!< Length of averaging window
|
||||
double d_avg_latitude_d; //!< Averaged latitude in degrees
|
||||
double d_avg_longitude_d; //!< Averaged longitude in degrees
|
||||
double d_avg_height_m; //!< Averaged height [m]
|
||||
|
||||
double d_x_m;
|
||||
double d_y_m;
|
||||
double d_z_m;
|
||||
|
||||
// DOP estimations
|
||||
arma::mat d_Q;
|
||||
double d_GDOP;
|
||||
double d_PDOP;
|
||||
double d_HDOP;
|
||||
double d_VDOP;
|
||||
double d_TDOP;
|
||||
|
||||
bool d_flag_dump_enabled;
|
||||
bool d_flag_averaging;
|
||||
|
||||
std::string d_dump_filename;
|
||||
std::ofstream d_dump_file;
|
||||
|
||||
void set_averaging_depth(int depth);
|
||||
|
||||
hybrid_ls_pvt(int nchannels,std::string dump_filename, bool flag_dump_to_file);
|
||||
|
||||
~hybrid_ls_pvt();
|
||||
|
||||
bool get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map, double hybrid_current_time, bool flag_averaging);
|
||||
|
||||
/*!
|
||||
* \brief Conversion of Cartesian coordinates (X,Y,Z) to geographical
|
||||
* coordinates (d_latitude_d, d_longitude_d, d_height_m) on a selected reference ellipsoid.
|
||||
*
|
||||
* \param[in] X [m] Cartesian coordinate
|
||||
* \param[in] Y [m] Cartesian coordinate
|
||||
* \param[in] Z [m] Cartesian coordinate
|
||||
* \param[in] elipsoid_selection. Choices of Reference Ellipsoid for Geographical Coordinates:
|
||||
* 0 - International Ellipsoid 1924.
|
||||
* 1 - International Ellipsoid 1967.
|
||||
* 2 - World Geodetic System 1972.
|
||||
* 3 - Geodetic Reference System 1980.
|
||||
* 4 - World Geodetic System 1984.
|
||||
*
|
||||
*/
|
||||
void cart2geo(double X, double Y, double Z, int elipsoid_selection);
|
||||
};
|
||||
|
||||
#endif
|
@ -82,22 +82,25 @@ bool Kml_Printer::set_headers(std::string filename)
|
||||
|
||||
|
||||
|
||||
bool Kml_Printer::print_position(gps_l1_ca_ls_pvt* position,bool print_average_values)
|
||||
bool Kml_Printer::print_position(const std::shared_ptr<gps_l1_ca_ls_pvt>& position, bool print_average_values)
|
||||
{
|
||||
double latitude;
|
||||
double longitude;
|
||||
double height;
|
||||
|
||||
std::shared_ptr<gps_l1_ca_ls_pvt> position_ = position;
|
||||
|
||||
if (print_average_values == false)
|
||||
{
|
||||
latitude = position->d_latitude_d;
|
||||
longitude = position->d_longitude_d;
|
||||
height = position->d_height_m;
|
||||
latitude = position_->d_latitude_d;
|
||||
longitude = position_->d_longitude_d;
|
||||
height = position_->d_height_m;
|
||||
}
|
||||
else
|
||||
{
|
||||
latitude = position->d_avg_latitude_d;
|
||||
longitude = position->d_avg_longitude_d;
|
||||
height = position->d_avg_height_m;
|
||||
latitude = position_->d_avg_latitude_d;
|
||||
longitude = position_->d_avg_longitude_d;
|
||||
height = position_->d_avg_height_m;
|
||||
}
|
||||
|
||||
if (kml_file.is_open())
|
||||
@ -113,7 +116,37 @@ bool Kml_Printer::print_position(gps_l1_ca_ls_pvt* position,bool print_average_v
|
||||
|
||||
//ToDo: make the class ls_pvt generic and heritate the particular gps/gal/glo ls_pvt in order to
|
||||
// reuse kml_printer functions
|
||||
bool Kml_Printer::print_position_galileo(galileo_e1_ls_pvt* position,bool print_average_values)
|
||||
bool Kml_Printer::print_position_galileo(const std::shared_ptr<galileo_e1_ls_pvt>& position, bool print_average_values)
|
||||
{
|
||||
double latitude;
|
||||
double longitude;
|
||||
double height;
|
||||
std::shared_ptr<galileo_e1_ls_pvt> position_ = position;
|
||||
if (print_average_values == false)
|
||||
{
|
||||
latitude = position_->d_latitude_d;
|
||||
longitude = position_->d_longitude_d;
|
||||
height = position_->d_height_m;
|
||||
}
|
||||
else
|
||||
{
|
||||
latitude = position_->d_avg_latitude_d;
|
||||
longitude = position_->d_avg_longitude_d;
|
||||
height = position_->d_avg_height_m;
|
||||
}
|
||||
|
||||
if (kml_file.is_open())
|
||||
{
|
||||
kml_file << longitude << "," << latitude << "," << height << std::endl;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Kml_Printer::print_position_hybrid(const std::shared_ptr<hybrid_ls_pvt>& position, bool print_average_values)
|
||||
{
|
||||
double latitude;
|
||||
double longitude;
|
||||
@ -142,7 +175,6 @@ bool Kml_Printer::print_position_galileo(galileo_e1_ls_pvt* position,bool print_
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Kml_Printer::close_file()
|
||||
{
|
||||
if (kml_file.is_open())
|
||||
@ -167,5 +199,8 @@ Kml_Printer::Kml_Printer () {}
|
||||
|
||||
|
||||
|
||||
Kml_Printer::~Kml_Printer () {}
|
||||
Kml_Printer::~Kml_Printer ()
|
||||
{
|
||||
close_file();
|
||||
}
|
||||
|
||||
|
@ -35,10 +35,11 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "gps_l1_ca_ls_pvt.h"
|
||||
#include "galileo_e1_ls_pvt.h"
|
||||
|
||||
#include "hybrid_ls_pvt.h"
|
||||
|
||||
/*!
|
||||
* \brief Prints PVT information to OGC KML format file (can be viewed with Google Earth)
|
||||
@ -51,8 +52,9 @@ private:
|
||||
std::ofstream kml_file;
|
||||
public:
|
||||
bool set_headers(std::string filename);
|
||||
bool print_position(gps_l1_ca_ls_pvt* position, bool print_average_values);
|
||||
bool print_position_galileo(galileo_e1_ls_pvt* position, bool print_average_values);
|
||||
bool print_position(const std::shared_ptr<gps_l1_ca_ls_pvt>& position, bool print_average_values);
|
||||
bool print_position_galileo(const std::shared_ptr<galileo_e1_ls_pvt>& position, bool print_average_values);
|
||||
bool print_position_hybrid(const std::shared_ptr<hybrid_ls_pvt>& position, bool print_average_values);
|
||||
bool close_file();
|
||||
Kml_Printer();
|
||||
~Kml_Printer();
|
||||
|
@ -132,7 +132,7 @@ void Nmea_Printer::close_serial ()
|
||||
}
|
||||
|
||||
|
||||
bool Nmea_Printer::Print_Nmea_Line(gps_l1_ca_ls_pvt* pvt_data, bool print_average_values)
|
||||
bool Nmea_Printer::Print_Nmea_Line(const std::shared_ptr<gps_l1_ca_ls_pvt>& pvt_data, bool print_average_values)
|
||||
{
|
||||
std::string GPRMC;
|
||||
std::string GPGGA;
|
||||
|
@ -60,7 +60,7 @@ public:
|
||||
/*!
|
||||
* \brief Print NMEA PVT and satellite info to the initialized device
|
||||
*/
|
||||
bool Print_Nmea_Line(gps_l1_ca_ls_pvt* position, bool print_average_values);
|
||||
bool Print_Nmea_Line(const std::shared_ptr<gps_l1_ca_ls_pvt>& position, bool print_average_values);
|
||||
|
||||
/*!
|
||||
* \brief Default destructor.
|
||||
@ -72,9 +72,9 @@ private:
|
||||
std::ofstream nmea_file_descriptor; // Output file stream for NMEA log file
|
||||
std::string nmea_devname;
|
||||
int nmea_dev_descriptor; // NMEA serial device descriptor (i.e. COM port)
|
||||
gps_l1_ca_ls_pvt* d_PVT_data;
|
||||
int init_serial (std::string serial_device); //serial port control
|
||||
void close_serial ();
|
||||
std::shared_ptr<gps_l1_ca_ls_pvt> d_PVT_data;
|
||||
int init_serial(std::string serial_device); //serial port control
|
||||
void close_serial();
|
||||
std::string get_GPGGA(); // fix data
|
||||
std::string get_GPGSV(); // satellite data
|
||||
std::string get_GPGSA(); // overall satellite reception data
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -35,7 +35,7 @@
|
||||
* 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.
|
||||
* (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
|
||||
@ -57,9 +57,12 @@
|
||||
#include <sstream> // for stringstream
|
||||
#include <iomanip> // for setprecision
|
||||
#include <map>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include "gps_navigation_message.h"
|
||||
#include "boost/date_time/posix_time/posix_time.hpp"
|
||||
#include "galileo_navigation_message.h"
|
||||
#include "sbas_telemetry_data.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "Galileo_E1.h"
|
||||
#include "gnss_synchro.h"
|
||||
|
||||
class Sbas_Raw_Msg;
|
||||
@ -84,17 +87,39 @@ public:
|
||||
std::ofstream obsFile ; //<! Output file stream for RINEX observation file
|
||||
std::ofstream navFile ; //<! Output file stream for RINEX navigation data file
|
||||
std::ofstream sbsFile ; //<! Output file stream for RINEX SBAS raw data file
|
||||
std::ofstream navGalFile ; //<! Output file stream for RINEX Galileo navigation data file
|
||||
std::ofstream navMixFile ; //<! Output file stream for RINEX Mixed navigation data file
|
||||
|
||||
/*!
|
||||
* \brief Generates the Navigation Data header
|
||||
* \brief Generates the GPS Navigation Data header
|
||||
*/
|
||||
void rinex_nav_header(std::ofstream& out, Gps_Iono iono, Gps_Utc_Model utc_model);
|
||||
|
||||
/*!
|
||||
* \brief Generates the Observation data header
|
||||
* \brief Generates the Galileo Navigation Data header
|
||||
*/
|
||||
void rinex_nav_header(std::ofstream& out, Galileo_Iono iono, Galileo_Utc_Model utc_model, Galileo_Almanac galileo_almanac);
|
||||
|
||||
/*!
|
||||
* \brief Generates the Mixed (GPS/Galileo) Navigation Data header
|
||||
*/
|
||||
void rinex_nav_header(std::ofstream& out, Gps_Iono gps_iono, Gps_Utc_Model gps_utc_model, Galileo_Iono galileo_iono, Galileo_Utc_Model galileo_utc_model, Galileo_Almanac galileo_almanac);
|
||||
|
||||
/*!
|
||||
* \brief Generates the GPS Observation data header
|
||||
*/
|
||||
void rinex_obs_header(std::ofstream& out, Gps_Ephemeris eph, double d_TOW_first_observation);
|
||||
|
||||
/*!
|
||||
* \brief Generates the Galileo Observation data header
|
||||
*/
|
||||
void rinex_obs_header(std::ofstream& out, Galileo_Ephemeris eph, double d_TOW_first_observation);
|
||||
|
||||
/*!
|
||||
* \brief Generates the Mixed (GPS/Galileo) Observation data header
|
||||
*/
|
||||
void rinex_obs_header(std::ofstream& out, Gps_Ephemeris gps_eph, Galileo_Ephemeris galileo_eph, double d_TOW_first_observation);
|
||||
|
||||
/*!
|
||||
* \brief Generates the SBAS raw data header
|
||||
*/
|
||||
@ -110,17 +135,41 @@ public:
|
||||
*/
|
||||
boost::posix_time::ptime compute_GPS_time(Gps_Ephemeris eph, double obs_time);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Writes data from the navigation message into the RINEX file
|
||||
* \brief Computes the Galileo time and returns a boost::posix_time::ptime object
|
||||
*/
|
||||
void log_rinex_nav(std::ofstream& out, std::map<int,Gps_Ephemeris> eph_map);
|
||||
boost::posix_time::ptime compute_Galileo_time(Galileo_Ephemeris eph, double obs_time);
|
||||
|
||||
/*!
|
||||
* \brief Writes observables into the RINEX file
|
||||
* \brief Writes data from the GPS navigation message into the RINEX file
|
||||
*/
|
||||
void log_rinex_nav(std::ofstream& out, std::map<int,Gps_Ephemeris> eph_map);
|
||||
|
||||
/*!
|
||||
* \brief Writes data from the Galileo navigation message into the RINEX file
|
||||
*/
|
||||
void log_rinex_nav(std::ofstream& out, std::map<int, Galileo_Ephemeris> eph_map);
|
||||
|
||||
/*!
|
||||
* \brief Writes data from the Mixed (GPS/Galileo) navigation message into the RINEX file
|
||||
*/
|
||||
void log_rinex_nav(std::ofstream& out, std::map<int, Gps_Ephemeris> gps_eph_map, std::map<int, Galileo_Ephemeris> galileo_eph_map);
|
||||
|
||||
/*!
|
||||
* \brief Writes GPS observables into the RINEX file
|
||||
*/
|
||||
void log_rinex_obs(std::ofstream& out, Gps_Ephemeris eph, double obs_time, std::map<int,Gnss_Synchro> pseudoranges);
|
||||
|
||||
/*!
|
||||
* \brief Writes Galileo observables into the RINEX file
|
||||
*/
|
||||
void log_rinex_obs(std::ofstream& out, Galileo_Ephemeris eph, double obs_time, std::map<int,Gnss_Synchro> pseudoranges);
|
||||
|
||||
/*!
|
||||
* \brief Writes Galileo observables into the RINEX file
|
||||
*/
|
||||
void log_rinex_obs(std::ofstream& out, Gps_Ephemeris gps_eph, Galileo_Ephemeris galileo_eph, double gps_obs_time, std::map<int,Gnss_Synchro> pseudoranges);
|
||||
|
||||
/*!
|
||||
* \brief Represents GPS time in the date time format. Leap years are considered, but leap seconds are not.
|
||||
*/
|
||||
@ -165,6 +214,8 @@ private:
|
||||
std::string navfilename;
|
||||
std::string obsfilename;
|
||||
std::string sbsfilename;
|
||||
std::string navGalfilename;
|
||||
std::string navMixfilename;
|
||||
|
||||
/*
|
||||
* Generates the data for the PGM / RUN BY / DATE line
|
||||
@ -304,6 +355,9 @@ private:
|
||||
inline double asDouble(const std::string& s)
|
||||
{ return strtod(s.c_str(), 0); }
|
||||
|
||||
|
||||
inline int toInt(std::string bitString, int sLength);
|
||||
|
||||
/*
|
||||
* Convert a string to an integer.
|
||||
* @param s string containing a number.
|
||||
@ -313,7 +367,6 @@ private:
|
||||
{ return strtol(s.c_str(), 0, 10); }
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Convert a double to a string in fixed notation.
|
||||
* @param x double.
|
||||
@ -551,6 +604,22 @@ inline std::string Rinex_Printer::asFixWidthString(const int x, const int width,
|
||||
return ss.str().substr(ss.str().size() - width);
|
||||
}
|
||||
|
||||
inline long asInt(const std::string& s)
|
||||
{ return strtol(s.c_str(), 0, 10); }
|
||||
|
||||
|
||||
inline int Rinex_Printer::toInt(std::string bitString, int sLength)
|
||||
{
|
||||
int tempInt;
|
||||
int num = 0;
|
||||
for(int i=0; i < sLength; i++)
|
||||
{
|
||||
tempInt = bitString[i]-'0';
|
||||
num |= (1 << (sLength-1-i)) * tempInt;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
template<class X>
|
||||
inline std::string Rinex_Printer::asString(const X x)
|
||||
|
@ -23,11 +23,14 @@ if(OPENCL_FOUND)
|
||||
gps_l1_ca_pcps_assisted_acquisition.cc
|
||||
gps_l1_ca_pcps_acquisition_fine_doppler.cc
|
||||
gps_l1_ca_pcps_tong_acquisition.cc
|
||||
gps_l1_ca_pcps_quicksync_acquisition.cc
|
||||
gps_l1_ca_pcps_opencl_acquisition.cc
|
||||
galileo_e1_pcps_ambiguous_acquisition.cc
|
||||
galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc
|
||||
galileo_e1_pcps_quicksync_ambiguous_acquisition.cc
|
||||
galileo_e1_pcps_tong_ambiguous_acquisition.cc
|
||||
galileo_e1_pcps_8ms_ambiguous_acquisition.cc
|
||||
galileo_e5a_noncoherent_iq_acquisition_caf.cc
|
||||
)
|
||||
else(OPENCL_FOUND)
|
||||
set(ACQ_ADAPTER_SOURCES
|
||||
@ -36,10 +39,13 @@ else(OPENCL_FOUND)
|
||||
gps_l1_ca_pcps_assisted_acquisition.cc
|
||||
gps_l1_ca_pcps_acquisition_fine_doppler.cc
|
||||
gps_l1_ca_pcps_tong_acquisition.cc
|
||||
gps_l1_ca_pcps_quicksync_acquisition.cc
|
||||
galileo_e1_pcps_ambiguous_acquisition.cc
|
||||
galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc
|
||||
galileo_e1_pcps_quicksync_ambiguous_acquisition.cc
|
||||
galileo_e1_pcps_tong_ambiguous_acquisition.cc
|
||||
galileo_e1_pcps_8ms_ambiguous_acquisition.cc
|
||||
galileo_e5a_noncoherent_iq_acquisition_caf.cc
|
||||
)
|
||||
endif(OPENCL_FOUND)
|
||||
|
||||
|
@ -0,0 +1,348 @@
|
||||
/*!
|
||||
* \file galileo_e1_pcps_quicksync_ambiguous_acquisition.cc
|
||||
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||
* Galileo E1 Signals using the QuickSync Algorithm
|
||||
* \author Damian Miralles, 2014. dmiralles2009@gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "galileo_e1_pcps_quicksync_ambiguous_acquisition.h"
|
||||
#include <iostream>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/math/distributions/exponential.hpp>
|
||||
#include <glog/logging.h>
|
||||
#include <cmath>
|
||||
#include "galileo_e1_signal_processing.h"
|
||||
#include "Galileo_E1.h"
|
||||
#include "configuration_interface.h"
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::GalileoE1PcpsQuickSyncAmbiguousAcquisition(
|
||||
ConfigurationInterface* configuration, std::string role,
|
||||
unsigned int in_streams, unsigned int out_streams,
|
||||
boost::shared_ptr<gr::msg_queue> queue) :
|
||||
role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(queue)
|
||||
{
|
||||
configuration_ = configuration;
|
||||
std::string default_item_type = "gr_complex";
|
||||
std::string default_dump_filename = "../data/acquisition.dat";
|
||||
|
||||
DLOG(INFO) << "role " << role;
|
||||
|
||||
item_type_ = configuration_->property(role + ".item_type",
|
||||
default_item_type);
|
||||
|
||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000);
|
||||
if_ = configuration_->property(role + ".ifreq", 0);
|
||||
dump_ = configuration_->property(role + ".dump", false);
|
||||
shift_resolution_ = configuration_->property(role + ".doppler_max", 15);
|
||||
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 8);
|
||||
|
||||
/*--- Find number of samples per spreading code (4 ms) -----------------*/
|
||||
code_length_ = round(
|
||||
fs_in_
|
||||
/ (Galileo_E1_CODE_CHIP_RATE_HZ
|
||||
/ Galileo_E1_B_CODE_LENGTH_CHIPS));
|
||||
|
||||
int samples_per_ms = round(code_length_ / 4.0);
|
||||
|
||||
|
||||
/*Calculate the folding factor value based on the formula described in the paper.
|
||||
This may be a bug, but acquisition also work by variying the folding factor at va-
|
||||
lues different that the expressed in the paper. In adition, it is important to point
|
||||
out that by making the folding factor smaller we were able to get QuickSync work with
|
||||
Galileo. Future work should be directed to test this asumption statistically.*/
|
||||
|
||||
//folding_factor_ = (unsigned int)ceil(sqrt(log2(code_length_)));
|
||||
folding_factor_ = configuration_->property(role + ".folding_factor", 2);
|
||||
|
||||
if (sampled_ms_ % (folding_factor_*4) != 0)
|
||||
{
|
||||
LOG(WARNING) << "QuickSync Algorithm requires a coherent_integration_time"
|
||||
<< " multiple of "<<(folding_factor_*4)<<"ms, Value entered "
|
||||
<<sampled_ms_<<" ms";
|
||||
|
||||
if(sampled_ms_ < (folding_factor_*4))
|
||||
{
|
||||
sampled_ms_ = (int) (folding_factor_*4);
|
||||
}
|
||||
else
|
||||
{
|
||||
sampled_ms_ = (int)(sampled_ms_/(folding_factor_*4)) * (folding_factor_*4);
|
||||
}
|
||||
LOG(WARNING) << "coherent_integration_time should be multiple of "
|
||||
<< "Galileo code length (4 ms). coherent_integration_time = "
|
||||
<< sampled_ms_ << " ms will be used.";
|
||||
|
||||
}
|
||||
// vector_length_ = (sampled_ms_/folding_factor_) * code_length_;
|
||||
vector_length_ = sampled_ms_ * samples_per_ms;
|
||||
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
||||
|
||||
if (!bit_transition_flag_)
|
||||
{
|
||||
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
max_dwells_ = 2;
|
||||
}
|
||||
|
||||
dump_filename_ = configuration_->property(role + ".dump_filename",
|
||||
default_dump_filename);
|
||||
|
||||
code_ = new gr_complex[code_length_];
|
||||
LOG(INFO) <<"Vector Length: "<<vector_length_
|
||||
<<", Samples per ms: "<<samples_per_ms
|
||||
<<", Folding factor: "<<folding_factor_
|
||||
<<", Sampled ms: "<<sampled_ms_
|
||||
<<", Code Length: "<<code_length_;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
acquisition_cc_ = pcps_quicksync_make_acquisition_cc(folding_factor_,
|
||||
sampled_ms_, max_dwells_, shift_resolution_, if_, fs_in_,
|
||||
samples_per_ms, code_length_, bit_transition_flag_, queue_,
|
||||
dump_, dump_filename_);
|
||||
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_,
|
||||
vector_length_);
|
||||
DLOG(INFO) << "stream_to_vector_quicksync("
|
||||
<< stream_to_vector_->unique_id() << ")";
|
||||
DLOG(INFO) << "acquisition_quicksync(" << acquisition_cc_->unique_id()
|
||||
<< ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << item_type_
|
||||
<< " unknown acquisition item type";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::~GalileoE1PcpsQuickSyncAmbiguousAcquisition()
|
||||
{
|
||||
delete[] code_;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_channel(unsigned int channel)
|
||||
{
|
||||
channel_ = channel;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_channel(channel_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_threshold(float threshold)
|
||||
{
|
||||
|
||||
float pfa = configuration_->property(role_+ boost::lexical_cast<std::string>(channel_) + ".pfa", 0.0);
|
||||
|
||||
if(pfa==0.0) pfa = configuration_->property(role_+".pfa", 0.0);
|
||||
|
||||
if(pfa==0.0)
|
||||
{
|
||||
threshold_ = threshold;
|
||||
}
|
||||
else
|
||||
{
|
||||
threshold_ = calculate_threshold(pfa);
|
||||
}
|
||||
|
||||
DLOG(INFO) <<"Channel "<<channel_<<" Threshold = " << threshold_;
|
||||
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_threshold(threshold_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_doppler_max(unsigned int doppler_max)
|
||||
{
|
||||
doppler_max_ = doppler_max;
|
||||
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_doppler_max(doppler_max_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_doppler_step(unsigned int doppler_step)
|
||||
{
|
||||
doppler_step_ = doppler_step;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_doppler_step(doppler_step_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_channel_queue(
|
||||
concurrent_queue<int> *channel_internal_queue)
|
||||
{
|
||||
channel_internal_queue_ = channel_internal_queue;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_channel_queue(channel_internal_queue_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_gnss_synchro(
|
||||
Gnss_Synchro* gnss_synchro)
|
||||
{
|
||||
gnss_synchro_ = gnss_synchro;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_gnss_synchro(gnss_synchro_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
signed int
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::mag()
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
return acquisition_cc_->mag();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::init()
|
||||
{
|
||||
acquisition_cc_->init();
|
||||
set_local_code();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_local_code()
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
bool cboc = configuration_->property(
|
||||
"Acquisition" + boost::lexical_cast<std::string>(channel_)
|
||||
+ ".cboc", false);
|
||||
|
||||
std::complex<float> * code = new std::complex<float>[code_length_];
|
||||
|
||||
galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal,
|
||||
cboc, gnss_synchro_->PRN, fs_in_, 0, false);
|
||||
|
||||
|
||||
for (unsigned int i = 0; i < (sampled_ms_/(folding_factor_*4)); i++)
|
||||
{
|
||||
memcpy(&(code_[i*code_length_]), code,
|
||||
sizeof(gr_complex)*code_length_);
|
||||
}
|
||||
|
||||
// memcpy(code_, code,sizeof(gr_complex)*code_length_);
|
||||
acquisition_cc_->set_local_code(code_);
|
||||
|
||||
delete[] code;
|
||||
code = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::reset()
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_active(true);
|
||||
}
|
||||
}
|
||||
|
||||
float GalileoE1PcpsQuickSyncAmbiguousAcquisition::calculate_threshold(float pfa)
|
||||
{
|
||||
unsigned int frequency_bins = 0;
|
||||
for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_)
|
||||
{
|
||||
frequency_bins++;
|
||||
}
|
||||
|
||||
DLOG(INFO) <<"Channel "<<channel_<<" Pfa = "<< pfa;
|
||||
|
||||
unsigned int ncells = code_length_/folding_factor_ * frequency_bins;
|
||||
double exponent = 1 / (double)ncells;
|
||||
double val = pow(1.0 - pfa, exponent);
|
||||
double lambda = double(code_length_/folding_factor_);
|
||||
boost::math::exponential_distribution<double> mydist (lambda);
|
||||
float threshold = (float)quantile(mydist,val);
|
||||
|
||||
return threshold;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
top_block->connect(stream_to_vector_, 0, acquisition_cc_, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
top_block->disconnect(stream_to_vector_, 0, acquisition_cc_, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr GalileoE1PcpsQuickSyncAmbiguousAcquisition::get_left_block()
|
||||
{
|
||||
return stream_to_vector_;
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr GalileoE1PcpsQuickSyncAmbiguousAcquisition::get_right_block()
|
||||
{
|
||||
return acquisition_cc_;
|
||||
}
|
||||
|
@ -0,0 +1,163 @@
|
||||
/*!
|
||||
* \file galileo_e1_pcps_quicksync_ambiguous_acquisition.h
|
||||
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for Galileo E1 Signals
|
||||
* \date June, 2014
|
||||
* \author Damian Miralles Sanchez. dmiralles2009@gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_GALILEO_E1_PCPS_QUICKSYNC_AMBIGUOUS_ACQUISITION_H_
|
||||
#define GNSS_SDR_GALILEO_E1_PCPS_QUICKSYNC_AMBIGUOUS_ACQUISITION_H_
|
||||
|
||||
#include <string>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/blocks/stream_to_vector.h>
|
||||
#include "gnss_synchro.h"
|
||||
#include "acquisition_interface.h"
|
||||
#include "pcps_quicksync_acquisition_cc.h"
|
||||
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
* \brief This class adapts a PCPS acquisition block to an
|
||||
* AcquisitionInterface for Galileo E1 Signals
|
||||
*/
|
||||
class GalileoE1PcpsQuickSyncAmbiguousAcquisition: public AcquisitionInterface
|
||||
{
|
||||
public:
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition(ConfigurationInterface* configuration,
|
||||
std::string role, unsigned int in_streams,
|
||||
unsigned int out_streams, boost::shared_ptr<gr::msg_queue> queue);
|
||||
|
||||
virtual ~GalileoE1PcpsQuickSyncAmbiguousAcquisition();
|
||||
|
||||
std::string role()
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Galileo_E1_PCPS_Ambiguous_Acquisition"
|
||||
*/
|
||||
std::string implementation()
|
||||
{
|
||||
return "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition";
|
||||
}
|
||||
size_t item_size()
|
||||
{
|
||||
return item_size_;
|
||||
}
|
||||
|
||||
void connect(gr::top_block_sptr top_block);
|
||||
void disconnect(gr::top_block_sptr top_block);
|
||||
gr::basic_block_sptr get_left_block();
|
||||
gr::basic_block_sptr get_right_block();
|
||||
|
||||
/*!
|
||||
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
|
||||
* to efficiently exchange synchronization data between acquisition and
|
||||
* tracking blocks
|
||||
*/
|
||||
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro);
|
||||
|
||||
/*!
|
||||
* \brief Set acquisition channel unique ID
|
||||
*/
|
||||
void set_channel(unsigned int channel);
|
||||
|
||||
/*!
|
||||
* \brief Set statistics threshold of PCPS algorithm
|
||||
*/
|
||||
void set_threshold(float threshold);
|
||||
|
||||
/*!
|
||||
* \brief Set maximum Doppler off grid search
|
||||
*/
|
||||
void set_doppler_max(unsigned int doppler_max);
|
||||
|
||||
/*!
|
||||
* \brief Set Doppler steps for the grid search
|
||||
*/
|
||||
void set_doppler_step(unsigned int doppler_step);
|
||||
|
||||
/*!
|
||||
* \brief Set tracking channel internal queue
|
||||
*/
|
||||
void set_channel_queue(concurrent_queue<int> *channel_internal_queue);
|
||||
|
||||
/*!
|
||||
* \brief Initializes acquisition algorithm.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/*!
|
||||
* \brief Sets local code for Galileo E1 PCPS acquisition algorithm.
|
||||
*/
|
||||
void set_local_code();
|
||||
|
||||
/*!
|
||||
* \brief Returns the maximum peak of grid search
|
||||
*/
|
||||
signed int mag();
|
||||
|
||||
/*!
|
||||
* \brief Restart acquisition algorithm
|
||||
*/
|
||||
void reset();
|
||||
|
||||
private:
|
||||
ConfigurationInterface* configuration_;
|
||||
pcps_quicksync_acquisition_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_;
|
||||
unsigned int code_length_;
|
||||
bool bit_transition_flag_;
|
||||
unsigned int channel_;
|
||||
float threshold_;
|
||||
unsigned int doppler_max_;
|
||||
unsigned int doppler_step_;
|
||||
unsigned int shift_resolution_;
|
||||
unsigned int sampled_ms_;
|
||||
unsigned int max_dwells_;
|
||||
unsigned int folding_factor_;
|
||||
long fs_in_;
|
||||
long if_;
|
||||
bool dump_;
|
||||
std::string dump_filename_;
|
||||
std::complex<float> * code_;
|
||||
Gnss_Synchro * gnss_synchro_;
|
||||
std::string role_;
|
||||
unsigned int in_streams_;
|
||||
unsigned int out_streams_;
|
||||
boost::shared_ptr<gr::msg_queue> queue_;
|
||||
concurrent_queue<int> *channel_internal_queue_;
|
||||
float calculate_threshold(float pfa);
|
||||
};
|
||||
|
||||
#endif /* GNSS_SDR_GALILEO_E1_PCPS_QUICKSYNC_AMBIGUOUS_ACQUISITION_H_ */
|
@ -0,0 +1,328 @@
|
||||
/*!
|
||||
* \file galileo_e5a_noncoherent_iq_acquisition_caf.cc
|
||||
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||
* Galileo E5a data and pilot Signals
|
||||
* \author Marc Sales, 2014. marcsales92(at)gmail.com
|
||||
* \based on work from:
|
||||
* <ul>
|
||||
* <li> Javier Arribas, 2011. jarribas(at)cttc.es
|
||||
* <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com
|
||||
* <li> Marc Molina, 2013. marc.molina.pena@gmail.com
|
||||
* </ul>
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "galileo_e5a_noncoherent_iq_acquisition_caf.h"
|
||||
#include <iostream>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <stdexcept>
|
||||
#include <boost/math/distributions/exponential.hpp>
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include "galileo_e5_signal_processing.h"
|
||||
#include "Galileo_E5a.h"
|
||||
#include "configuration_interface.h"
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
GalileoE5aNoncoherentIQAcquisitionCaf::GalileoE5aNoncoherentIQAcquisitionCaf(
|
||||
ConfigurationInterface* configuration, std::string role,
|
||||
unsigned int in_streams, unsigned int out_streams,
|
||||
boost::shared_ptr<gr::msg_queue> queue) :
|
||||
role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(queue)
|
||||
{
|
||||
configuration_ = configuration;
|
||||
std::string default_item_type = "gr_complex";
|
||||
std::string default_dump_filename = "../data/acquisition.dat";
|
||||
|
||||
DLOG(INFO) << "role " << role;
|
||||
|
||||
item_type_ = configuration_->property(role + ".item_type",
|
||||
default_item_type);
|
||||
|
||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000);
|
||||
if_ = configuration_->property(role + ".ifreq", 0);
|
||||
dump_ = configuration_->property(role + ".dump", false);
|
||||
shift_resolution_ = configuration_->property(role + ".doppler_max", 15);
|
||||
CAF_window_hz_ = configuration_->property(role + ".CAF_window_hz",0);
|
||||
Zero_padding = configuration_->property(role + ".Zero_padding",0);
|
||||
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
|
||||
if (sampled_ms_ > 3)
|
||||
{
|
||||
sampled_ms_=3;
|
||||
DLOG(INFO) << "Coherent integration time should be 3 ms or less. Changing to 3ms ";
|
||||
std::cout<<"Too high coherent integration time. Changing to 3ms" << std::endl;
|
||||
}
|
||||
if (Zero_padding > 0)
|
||||
{
|
||||
sampled_ms_ = 2;
|
||||
DLOG(INFO) << "Zero padding activated. Changing to 1ms code + 1ms zero padding ";
|
||||
std::cout<<"Zero padding activated. Changing to 1ms code + 1ms zero padding" << std::endl;
|
||||
}
|
||||
|
||||
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
|
||||
|
||||
dump_filename_ = configuration_->property(role + ".dump_filename",
|
||||
default_dump_filename);
|
||||
|
||||
//--- Find number of samples per spreading code (1ms)-------------------------
|
||||
code_length_ = round(fs_in_/ Galileo_E5a_CODE_CHIP_RATE_HZ*Galileo_E5a_CODE_LENGTH_CHIPS);
|
||||
|
||||
vector_length_=code_length_ * sampled_ms_;
|
||||
|
||||
codeI_= new gr_complex[vector_length_];
|
||||
codeQ_= new gr_complex[vector_length_];
|
||||
both_signal_components = false;
|
||||
|
||||
std::string sig_ = configuration_->property("Channel.signal", std::string("5X"));
|
||||
if (sig_.at(0) == '5' && sig_.at(1) == 'X')
|
||||
{
|
||||
both_signal_components = true;
|
||||
}
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
acquisition_cc_ = galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(sampled_ms_, max_dwells_,
|
||||
shift_resolution_, if_, fs_in_, code_length_, code_length_,
|
||||
bit_transition_flag_, queue_, dump_, dump_filename_, both_signal_components, CAF_window_hz_,Zero_padding);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << item_type_
|
||||
<< " unknown acquisition item type";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GalileoE5aNoncoherentIQAcquisitionCaf::~GalileoE5aNoncoherentIQAcquisitionCaf()
|
||||
{
|
||||
delete[] codeI_;
|
||||
delete[] codeQ_;
|
||||
}
|
||||
|
||||
void GalileoE5aNoncoherentIQAcquisitionCaf::set_channel(unsigned int channel)
|
||||
{
|
||||
channel_ = channel;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_channel(channel_);
|
||||
}
|
||||
}
|
||||
|
||||
void GalileoE5aNoncoherentIQAcquisitionCaf::set_threshold(float threshold)
|
||||
{
|
||||
|
||||
float pfa = configuration_->property(role_+ boost::lexical_cast<std::string>(channel_) + ".pfa", 0.0);
|
||||
|
||||
if(pfa==0.0) pfa = configuration_->property(role_+".pfa", 0.0);
|
||||
|
||||
if(pfa==0.0)
|
||||
{
|
||||
threshold_ = threshold;
|
||||
}
|
||||
else
|
||||
{
|
||||
threshold_ = calculate_threshold(pfa);
|
||||
}
|
||||
|
||||
DLOG(INFO) <<"Channel "<<channel_<<" Threshold = " << threshold_;
|
||||
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_threshold(threshold_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GalileoE5aNoncoherentIQAcquisitionCaf::set_doppler_max(unsigned int doppler_max)
|
||||
{
|
||||
doppler_max_ = doppler_max;
|
||||
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_doppler_max(doppler_max_);
|
||||
}
|
||||
}
|
||||
|
||||
void GalileoE5aNoncoherentIQAcquisitionCaf::set_doppler_step(unsigned int doppler_step)
|
||||
{
|
||||
doppler_step_ = doppler_step;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_doppler_step(doppler_step_);
|
||||
}
|
||||
}
|
||||
|
||||
void GalileoE5aNoncoherentIQAcquisitionCaf::set_channel_queue(
|
||||
concurrent_queue<int> *channel_internal_queue)
|
||||
{
|
||||
channel_internal_queue_ = channel_internal_queue;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_channel_queue(channel_internal_queue_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GalileoE5aNoncoherentIQAcquisitionCaf::set_gnss_synchro(
|
||||
Gnss_Synchro* gnss_synchro)
|
||||
{
|
||||
gnss_synchro_ = gnss_synchro;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_gnss_synchro(gnss_synchro_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
signed int GalileoE5aNoncoherentIQAcquisitionCaf::mag()
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
return acquisition_cc_->mag();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GalileoE5aNoncoherentIQAcquisitionCaf::init()
|
||||
{
|
||||
acquisition_cc_->init();
|
||||
set_local_code();
|
||||
}
|
||||
|
||||
void GalileoE5aNoncoherentIQAcquisitionCaf::set_local_code()
|
||||
{
|
||||
if (item_type_.compare("gr_complex")==0)
|
||||
{
|
||||
|
||||
std::complex<float>* codeI = new std::complex<float>[code_length_];
|
||||
std::complex<float>* codeQ = new std::complex<float>[code_length_];
|
||||
|
||||
if (gnss_synchro_->Signal[0] == '5' && gnss_synchro_->Signal[1] == 'X')
|
||||
{
|
||||
char a[3];
|
||||
strcpy(a,"5I");
|
||||
galileo_e5_a_code_gen_complex_sampled(codeI, a,
|
||||
gnss_synchro_->PRN, fs_in_, 0);
|
||||
|
||||
strcpy(a,"5Q");
|
||||
galileo_e5_a_code_gen_complex_sampled(codeQ, a,
|
||||
gnss_synchro_->PRN, fs_in_, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
galileo_e5_a_code_gen_complex_sampled(codeI, gnss_synchro_->Signal,
|
||||
gnss_synchro_->PRN, fs_in_, 0);
|
||||
}
|
||||
// WARNING: 3ms are coherently integrated. Secondary sequence (1,1,1)
|
||||
// is generated, and modulated in the 'block'.
|
||||
if (Zero_padding == 0) // if no zero_padding
|
||||
{
|
||||
for (unsigned int i = 0; i < sampled_ms_; i++)
|
||||
{
|
||||
memcpy(&(codeI_[i*code_length_]), codeI,
|
||||
sizeof(gr_complex)*code_length_);
|
||||
if (gnss_synchro_->Signal[0] == '5' && gnss_synchro_->Signal[1] == 'X')
|
||||
{
|
||||
memcpy(&(codeQ_[i*code_length_]), codeQ,
|
||||
sizeof(gr_complex)*code_length_);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 1ms code + 1ms zero padding
|
||||
memcpy(&(codeI_[0]), codeI,
|
||||
sizeof(gr_complex)*code_length_);
|
||||
if (gnss_synchro_->Signal[0] == '5' && gnss_synchro_->Signal[1] == 'X')
|
||||
{
|
||||
memcpy(&(codeQ_[0]), codeQ,
|
||||
sizeof(gr_complex)*code_length_);
|
||||
}
|
||||
}
|
||||
|
||||
acquisition_cc_->set_local_code(codeI_,codeQ_);
|
||||
delete[] codeI;
|
||||
delete[] codeQ;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GalileoE5aNoncoherentIQAcquisitionCaf::reset()
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_active(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float GalileoE5aNoncoherentIQAcquisitionCaf::calculate_threshold(float pfa)
|
||||
{
|
||||
//Calculate the threshold
|
||||
unsigned int frequency_bins = 0;
|
||||
for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_)
|
||||
{
|
||||
frequency_bins++;
|
||||
}
|
||||
DLOG(INFO) << "Channel " << channel_<< " Pfa = " << pfa;
|
||||
unsigned int ncells = vector_length_*frequency_bins;
|
||||
double exponent = 1/(double)ncells;
|
||||
double val = pow(1.0 - pfa, exponent);
|
||||
double lambda = double(vector_length_);
|
||||
boost::math::exponential_distribution<double> mydist (lambda);
|
||||
float threshold = (float)quantile(mydist,val);
|
||||
|
||||
return threshold;
|
||||
}
|
||||
|
||||
|
||||
void GalileoE5aNoncoherentIQAcquisitionCaf::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
// Nothing to connect internally
|
||||
}
|
||||
|
||||
|
||||
void GalileoE5aNoncoherentIQAcquisitionCaf::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
// Nothing to disconnect internally
|
||||
}
|
||||
|
||||
gr::basic_block_sptr GalileoE5aNoncoherentIQAcquisitionCaf::get_left_block()
|
||||
{
|
||||
return acquisition_cc_;
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr GalileoE5aNoncoherentIQAcquisitionCaf::get_right_block()
|
||||
{
|
||||
return acquisition_cc_;
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
/*!
|
||||
* \file galileo_e5a_noncoherent_iq_acquisition_caf.h
|
||||
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||
* Galileo E5a data and pilot Signals
|
||||
* \author Marc Sales, 2014. marcsales92(at)gmail.com
|
||||
* \based on work from:
|
||||
* <ul>
|
||||
* <li> Javier Arribas, 2011. jarribas(at)cttc.es
|
||||
* <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com
|
||||
* <li> Marc Molina, 2013. marc.molina.pena@gmail.com
|
||||
* </ul>
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_H_
|
||||
#define GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_H_
|
||||
|
||||
#include <string>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/blocks/stream_to_vector.h>
|
||||
#include "gnss_synchro.h"
|
||||
#include "acquisition_interface.h"
|
||||
#include "galileo_e5a_noncoherent_iq_acquisition_caf_cc.h"
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
class GalileoE5aNoncoherentIQAcquisitionCaf: public AcquisitionInterface
|
||||
{
|
||||
public:
|
||||
GalileoE5aNoncoherentIQAcquisitionCaf(ConfigurationInterface* configuration,
|
||||
std::string role, unsigned int in_streams,
|
||||
unsigned int out_streams, boost::shared_ptr<gr::msg_queue> queue);
|
||||
|
||||
virtual ~GalileoE5aNoncoherentIQAcquisitionCaf();
|
||||
|
||||
std::string role()
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
/*!
|
||||
* \brief Returns "Galileo_E5a_Noncoherent_IQ_Acquisition_CAF"
|
||||
*/
|
||||
std::string implementation()
|
||||
{
|
||||
return "Galileo_E5a_Noncoherent_IQ_Acquisition_CAF";
|
||||
}
|
||||
size_t item_size()
|
||||
{
|
||||
return item_size_;
|
||||
}
|
||||
|
||||
void connect(gr::top_block_sptr top_block);
|
||||
void disconnect(gr::top_block_sptr top_block);
|
||||
gr::basic_block_sptr get_left_block();
|
||||
gr::basic_block_sptr get_right_block();
|
||||
|
||||
/*!
|
||||
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
|
||||
* to efficiently exchange synchronization data between acquisition and
|
||||
* tracking blocks
|
||||
*/
|
||||
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro);
|
||||
|
||||
/*!
|
||||
* \brief Set acquisition channel unique ID
|
||||
*/
|
||||
void set_channel(unsigned int channel);
|
||||
|
||||
/*!
|
||||
* \brief Set statistics threshold of PCPS algorithm
|
||||
*/
|
||||
void set_threshold(float threshold);
|
||||
|
||||
/*!
|
||||
* \brief Set maximum Doppler off grid search
|
||||
*/
|
||||
void set_doppler_max(unsigned int doppler_max);
|
||||
|
||||
/*!
|
||||
* \brief Set Doppler steps for the grid search
|
||||
*/
|
||||
void set_doppler_step(unsigned int doppler_step);
|
||||
|
||||
/*!
|
||||
* \brief Set tracking channel internal queue
|
||||
*/
|
||||
void set_channel_queue(concurrent_queue<int> *channel_internal_queue);
|
||||
|
||||
/*!
|
||||
* \brief Initializes acquisition algorithm.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/*!
|
||||
* \brief Sets local Galileo E5a code for PCPS acquisition algorithm.
|
||||
*/
|
||||
void set_local_code();
|
||||
|
||||
/*!
|
||||
* \brief Returns the maximum peak of grid search
|
||||
*/
|
||||
signed int mag();
|
||||
|
||||
/*!
|
||||
* \brief Restart acquisition algorithm
|
||||
*/
|
||||
void reset();
|
||||
|
||||
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_;
|
||||
unsigned int code_length_;
|
||||
bool bit_transition_flag_;
|
||||
unsigned int channel_;
|
||||
float threshold_;
|
||||
unsigned int doppler_max_;
|
||||
unsigned int doppler_step_;
|
||||
unsigned int shift_resolution_;
|
||||
unsigned int sampled_ms_;
|
||||
unsigned int max_dwells_;
|
||||
long fs_in_;
|
||||
long if_;
|
||||
bool dump_;
|
||||
std::string dump_filename_;
|
||||
int Zero_padding;
|
||||
int CAF_window_hz_;
|
||||
std::complex<float> * codeI_;
|
||||
std::complex<float> * codeQ_;
|
||||
bool both_signal_components;
|
||||
Gnss_Synchro * gnss_synchro_;
|
||||
std::string role_;
|
||||
unsigned int in_streams_;
|
||||
unsigned int out_streams_;
|
||||
boost::shared_ptr<gr::msg_queue> queue_;
|
||||
concurrent_queue<int> *channel_internal_queue_;
|
||||
float calculate_threshold(float pfa);
|
||||
};
|
||||
#endif /* GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_H_ */
|
@ -0,0 +1,330 @@
|
||||
/*!
|
||||
* \file gps_l1_ca_pcps_quicksync_acquisition.cc
|
||||
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||
* GPS L1 C/A signals using the QuickSync Algorithm
|
||||
* \author Damian Miralles, 2014. dmiralles2009@gmail.com
|
||||
*
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "gps_l1_ca_pcps_quicksync_acquisition.h"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <stdexcept>
|
||||
#include <boost/math/distributions/exponential.hpp>
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include "gps_sdr_signal_processing.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "configuration_interface.h"
|
||||
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
GpsL1CaPcpsQuickSyncAcquisition::GpsL1CaPcpsQuickSyncAcquisition(
|
||||
ConfigurationInterface* configuration, std::string role,
|
||||
unsigned int in_streams, unsigned int out_streams,
|
||||
gr::msg_queue::sptr queue) :
|
||||
role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(queue)
|
||||
{
|
||||
configuration_ = configuration;
|
||||
std::string default_item_type = "gr_complex";
|
||||
std::string default_dump_filename = "./data/acquisition.dat";
|
||||
|
||||
DLOG(INFO) << "role " << role;
|
||||
|
||||
item_type_ = configuration_->property(role + ".item_type", default_item_type);
|
||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000);
|
||||
if_ = configuration_->property(role + ".ifreq", 0);
|
||||
dump_ = configuration_->property(role + ".dump", false);
|
||||
shift_resolution_ = configuration_->property(role + ".doppler_max", 15);
|
||||
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 4);
|
||||
|
||||
|
||||
//--- Find number of samples per spreading code -------------------------
|
||||
code_length_ = round(fs_in_
|
||||
/ (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
|
||||
|
||||
|
||||
/*Calculate the folding factor value based on the calculations*/
|
||||
unsigned int temp = (unsigned int)ceil(sqrt(log2(code_length_)));
|
||||
folding_factor_ = configuration_->property(role + ".folding_factor", temp);
|
||||
|
||||
if ( sampled_ms_ % folding_factor_ != 0)
|
||||
{
|
||||
LOG(WARNING) << "QuickSync Algorithm requires a coherent_integration_time"
|
||||
<< " multiple of " << folding_factor_ << "ms, Value entered "
|
||||
<< sampled_ms_ << " ms";
|
||||
if(sampled_ms_ < folding_factor_)
|
||||
{
|
||||
sampled_ms_ = (int) folding_factor_;
|
||||
}
|
||||
else
|
||||
{
|
||||
sampled_ms_ = (int)(sampled_ms_/folding_factor_) * folding_factor_;
|
||||
}
|
||||
|
||||
LOG(WARNING) <<" Coherent_integration_time of "
|
||||
<< sampled_ms_ << " ms will be used instead.";
|
||||
|
||||
}
|
||||
vector_length_ = code_length_ * sampled_ms_;
|
||||
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
||||
|
||||
if (!bit_transition_flag_)
|
||||
{
|
||||
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
max_dwells_ = 2;
|
||||
}
|
||||
|
||||
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
||||
|
||||
int samples_per_ms = round(code_length_);
|
||||
code_= new gr_complex[code_length_];
|
||||
/*Object relevant information for debugging*/
|
||||
LOG(INFO) <<"Implementation: "<<this->implementation()
|
||||
<<", Vector Length: "<<vector_length_
|
||||
<<", Samples per ms: "<<samples_per_ms
|
||||
<<", Folding factor: "<<folding_factor_
|
||||
<<", Sampled ms: "<<sampled_ms_
|
||||
<<", Code Length: "<<code_length_;
|
||||
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
acquisition_cc_ = pcps_quicksync_make_acquisition_cc(folding_factor_,
|
||||
sampled_ms_, max_dwells_,shift_resolution_, if_, fs_in_,
|
||||
samples_per_ms, code_length_,bit_transition_flag_, queue_,
|
||||
dump_, dump_filename_);
|
||||
|
||||
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_,
|
||||
code_length_*folding_factor_);
|
||||
|
||||
DLOG(INFO) << "stream_to_vector_quicksync(" << stream_to_vector_->unique_id() << ")";
|
||||
DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id() << ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
GpsL1CaPcpsQuickSyncAcquisition::~GpsL1CaPcpsQuickSyncAcquisition()
|
||||
{
|
||||
delete[] code_;
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::set_channel(unsigned int channel)
|
||||
{
|
||||
channel_ = channel;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_channel(channel_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::set_threshold(float threshold)
|
||||
{
|
||||
float pfa = configuration_->property(role_ +
|
||||
boost::lexical_cast<std::string>(channel_) + ".pfa", 0.0);
|
||||
|
||||
if(pfa == 0.0)
|
||||
{
|
||||
pfa = configuration_->property(role_+".pfa", 0.0);
|
||||
}
|
||||
if(pfa == 0.0)
|
||||
{
|
||||
threshold_ = threshold;
|
||||
}
|
||||
else
|
||||
{
|
||||
threshold_ = calculate_threshold(pfa);
|
||||
}
|
||||
|
||||
DLOG(INFO) <<"Channel "<<channel_<<" Threshold = " << threshold_;
|
||||
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_threshold(threshold_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::set_doppler_max(unsigned int doppler_max)
|
||||
{
|
||||
doppler_max_ = doppler_max;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_doppler_max(doppler_max_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::set_doppler_step(unsigned int doppler_step)
|
||||
{
|
||||
doppler_step_ = doppler_step;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_doppler_step(doppler_step_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::set_channel_queue(
|
||||
concurrent_queue<int> *channel_internal_queue)
|
||||
{
|
||||
channel_internal_queue_ = channel_internal_queue;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_channel_queue(channel_internal_queue_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
|
||||
{
|
||||
gnss_synchro_ = gnss_synchro;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_gnss_synchro(gnss_synchro_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
signed int GpsL1CaPcpsQuickSyncAcquisition::mag()
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
return acquisition_cc_->mag();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::init()
|
||||
{
|
||||
acquisition_cc_->init();
|
||||
set_local_code();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::set_local_code()
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
std::complex<float>* code = new std::complex<float>[code_length_];
|
||||
|
||||
gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0);
|
||||
|
||||
|
||||
for (unsigned int i = 0; i < (sampled_ms_/folding_factor_); i++)
|
||||
{
|
||||
memcpy(&(code_[i*code_length_]), code,
|
||||
sizeof(gr_complex)*code_length_);
|
||||
}
|
||||
|
||||
//memcpy(code_, code,sizeof(gr_complex)*code_length_);
|
||||
acquisition_cc_->set_local_code(code_);
|
||||
|
||||
delete[] code;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::reset()
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_active(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float GpsL1CaPcpsQuickSyncAcquisition::calculate_threshold(float pfa)
|
||||
{
|
||||
//Calculate the threshold
|
||||
unsigned int frequency_bins = 0;
|
||||
for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_)
|
||||
{
|
||||
frequency_bins++;
|
||||
}
|
||||
DLOG(INFO) << "Channel " << channel_<< " Pfa = " << pfa;
|
||||
unsigned int ncells = (code_length_/folding_factor_)*frequency_bins;
|
||||
double exponent = 1/(double)ncells;
|
||||
double val = pow(1.0 - pfa, exponent);
|
||||
double lambda = double((code_length_/folding_factor_));
|
||||
boost::math::exponential_distribution<double> mydist (lambda);
|
||||
float threshold = (float)quantile(mydist,val);
|
||||
|
||||
return threshold;
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
top_block->connect(stream_to_vector_, 0, acquisition_cc_, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
top_block->disconnect(stream_to_vector_, 0, acquisition_cc_, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr GpsL1CaPcpsQuickSyncAcquisition::get_left_block()
|
||||
{
|
||||
return stream_to_vector_;
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr GpsL1CaPcpsQuickSyncAcquisition::get_right_block()
|
||||
{
|
||||
return acquisition_cc_;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,169 @@
|
||||
/*!
|
||||
* \file gps_l1_ca_pcps_quicksync_acquisition.h
|
||||
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for GPS L1 C/A signals implementing the QuickSync Algorithm.
|
||||
* \date June, 2014
|
||||
* \author Damian Miralles Sanchez. dmiralles2009@gmail.com
|
||||
*
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_GPS_L1_CA_PCPS_QUICKSYNC_ACQUISITION_H_
|
||||
#define GNSS_SDR_GPS_L1_CA_PCPS_QUICKSYNC_ACQUISITION_H_
|
||||
|
||||
#include <string>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/blocks/stream_to_vector.h>
|
||||
#include "gnss_synchro.h"
|
||||
#include "acquisition_interface.h"
|
||||
#include "pcps_quicksync_acquisition_cc.h"
|
||||
#include "configuration_interface.h"
|
||||
|
||||
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
* \brief This class adapts a PCPS acquisition block to an AcquisitionInterface
|
||||
* for GPS L1 C/A signals
|
||||
*/
|
||||
class GpsL1CaPcpsQuickSyncAcquisition: public AcquisitionInterface
|
||||
{
|
||||
public:
|
||||
GpsL1CaPcpsQuickSyncAcquisition(ConfigurationInterface* configuration,
|
||||
std::string role, unsigned int in_streams,
|
||||
unsigned int out_streams, boost::shared_ptr<gr::msg_queue> queue);
|
||||
|
||||
virtual ~GpsL1CaPcpsQuickSyncAcquisition();
|
||||
|
||||
std::string role()
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "GPS_L1_CA_PCPS_QuickSync_Acquisition"
|
||||
*/
|
||||
std::string implementation()
|
||||
{
|
||||
return "GPS_L1_CA_PCPS_QuickSync_Acquisition";
|
||||
}
|
||||
size_t item_size()
|
||||
{
|
||||
return item_size_;
|
||||
}
|
||||
|
||||
void connect(gr::top_block_sptr top_block);
|
||||
void disconnect(gr::top_block_sptr top_block);
|
||||
gr::basic_block_sptr get_left_block();
|
||||
gr::basic_block_sptr get_right_block();
|
||||
|
||||
/*!
|
||||
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
|
||||
* to efficiently exchange synchronization data between acquisition and
|
||||
* tracking blocks
|
||||
*/
|
||||
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro);
|
||||
|
||||
/*!
|
||||
* \brief Set acquisition channel unique ID
|
||||
*/
|
||||
void set_channel(unsigned int channel);
|
||||
|
||||
/*!
|
||||
* \brief Set statistics threshold of PCPS algorithm
|
||||
*/
|
||||
void set_threshold(float threshold);
|
||||
|
||||
/*!
|
||||
* \brief Set maximum Doppler off grid search
|
||||
*/
|
||||
void set_doppler_max(unsigned int doppler_max);
|
||||
|
||||
/*!
|
||||
* \brief Set Doppler steps for the grid search
|
||||
*/
|
||||
void set_doppler_step(unsigned int doppler_step);
|
||||
|
||||
/*!
|
||||
* \brief Set tracking channel internal queue
|
||||
*/
|
||||
void set_channel_queue(concurrent_queue<int> *channel_internal_queue);
|
||||
|
||||
/*!
|
||||
* \brief Initializes acquisition algorithm.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/*!
|
||||
* \brief Sets local code for GPS L1/CA PCPS acquisition algorithm.
|
||||
*/
|
||||
void set_local_code();
|
||||
|
||||
/*!
|
||||
* \brief Returns the maximum peak of grid search
|
||||
*/
|
||||
signed int mag();
|
||||
|
||||
/*!
|
||||
* \brief Restart acquisition algorithm
|
||||
*/
|
||||
void reset();
|
||||
|
||||
|
||||
private:
|
||||
ConfigurationInterface* configuration_;
|
||||
pcps_quicksync_acquisition_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_;
|
||||
unsigned int code_length_;
|
||||
bool bit_transition_flag_;
|
||||
unsigned int channel_;
|
||||
float threshold_;
|
||||
unsigned int doppler_max_;
|
||||
unsigned int doppler_step_;
|
||||
unsigned int shift_resolution_;
|
||||
unsigned int sampled_ms_;
|
||||
unsigned int max_dwells_;
|
||||
unsigned int folding_factor_;
|
||||
long fs_in_;
|
||||
long if_;
|
||||
bool dump_;
|
||||
std::string dump_filename_;
|
||||
std::complex<float> * code_;
|
||||
Gnss_Synchro * gnss_synchro_;
|
||||
std::string role_;
|
||||
unsigned int in_streams_;
|
||||
unsigned int out_streams_;
|
||||
boost::shared_ptr<gr::msg_queue> queue_;
|
||||
concurrent_queue<int> *channel_internal_queue_;
|
||||
|
||||
float calculate_threshold(float pfa);
|
||||
|
||||
};
|
||||
|
||||
#endif /* GNSS_SDR_GPS_L1_CA_PCPS_QUICKSYNC_ACQUISITION_H_ */
|
@ -24,7 +24,9 @@ if(OPENCL_FOUND)
|
||||
pcps_acquisition_fine_doppler_cc.cc
|
||||
pcps_tong_acquisition_cc.cc
|
||||
pcps_cccwsr_acquisition_cc.cc
|
||||
pcps_quicksync_acquisition_cc.cc
|
||||
galileo_pcps_8ms_acquisition_cc.cc
|
||||
galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc
|
||||
pcps_opencl_acquisition_cc.cc # Needs OpenCL
|
||||
)
|
||||
else(OPENCL_FOUND)
|
||||
@ -35,7 +37,9 @@ else(OPENCL_FOUND)
|
||||
pcps_acquisition_fine_doppler_cc.cc
|
||||
pcps_tong_acquisition_cc.cc
|
||||
pcps_cccwsr_acquisition_cc.cc
|
||||
pcps_quicksync_acquisition_cc.cc
|
||||
galileo_pcps_8ms_acquisition_cc.cc
|
||||
galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc
|
||||
)
|
||||
endif(OPENCL_FOUND)
|
||||
|
||||
|
@ -0,0 +1,781 @@
|
||||
/*!
|
||||
* \file galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc
|
||||
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||
* Galileo E5a data and pilot Signals
|
||||
* \author Marc Sales, 2014. marcsales92(at)gmail.com
|
||||
* \based on work from:
|
||||
* <ul>
|
||||
* <li> Javier Arribas, 2011. jarribas(at)cttc.es
|
||||
* <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com
|
||||
* <li> Marc Molina, 2013. marc.molina.pena@gmail.com
|
||||
* </ul>
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "galileo_e5a_noncoherent_iq_acquisition_caf_cc.h"
|
||||
#include <sys/time.h>
|
||||
#include <sstream>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <glog/logging.h>
|
||||
#include <volk/volk.h>
|
||||
#include "gnss_signal_processing.h"
|
||||
#include "control_message_factory.h"
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(
|
||||
unsigned int sampled_ms,
|
||||
unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag,
|
||||
gr::msg_queue::sptr queue, bool dump,
|
||||
std::string dump_filename,
|
||||
bool both_signal_components_,
|
||||
int CAF_window_hz_,
|
||||
int Zero_padding_)
|
||||
{
|
||||
|
||||
return galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr(
|
||||
new galileo_e5a_noncoherentIQ_acquisition_caf_cc(sampled_ms, max_dwells, doppler_max, freq, fs_in, samples_per_ms,
|
||||
samples_per_code, bit_transition_flag, queue, dump, dump_filename, both_signal_components_, CAF_window_hz_, Zero_padding_));
|
||||
}
|
||||
|
||||
galileo_e5a_noncoherentIQ_acquisition_caf_cc::galileo_e5a_noncoherentIQ_acquisition_caf_cc(
|
||||
unsigned int sampled_ms,
|
||||
unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag,
|
||||
gr::msg_queue::sptr queue, bool dump,
|
||||
std::string dump_filename,
|
||||
bool both_signal_components_,
|
||||
int CAF_window_hz_,
|
||||
int Zero_padding_) :
|
||||
gr::block("galileo_e5a_noncoherentIQ_acquisition_caf_cc",
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
||||
gr::io_signature::make(0, 0, sizeof(gr_complex)))
|
||||
{
|
||||
d_sample_counter = 0; // SAMPLE COUNTER
|
||||
d_active = false;
|
||||
d_state = 0;
|
||||
d_queue = queue;
|
||||
d_freq = freq;
|
||||
d_fs_in = fs_in;
|
||||
d_samples_per_ms = samples_per_ms;
|
||||
d_samples_per_code = samples_per_code;
|
||||
d_max_dwells = max_dwells;
|
||||
d_well_count = 0;
|
||||
d_doppler_max = doppler_max;
|
||||
if (Zero_padding_ > 0)
|
||||
{
|
||||
d_sampled_ms = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_sampled_ms = sampled_ms;
|
||||
}
|
||||
d_fft_size = sampled_ms * d_samples_per_ms;
|
||||
d_mag = 0;
|
||||
d_input_power = 0.0;
|
||||
d_num_doppler_bins = 0;
|
||||
d_bit_transition_flag = bit_transition_flag;
|
||||
d_buffer_count=0;
|
||||
d_both_signal_components = both_signal_components_;
|
||||
d_CAF_window_hz = CAF_window_hz_;
|
||||
|
||||
//todo: do something if posix_memalign fails
|
||||
if (posix_memalign((void**)&d_inbuffer, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_fft_code_I_A, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitudeIA, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
if (posix_memalign((void**)&d_fft_code_Q_A, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitudeQA, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
}
|
||||
// IF COHERENT INTEGRATION TIME > 1
|
||||
if (d_sampled_ms > 1)
|
||||
{
|
||||
if (posix_memalign((void**)&d_fft_code_I_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitudeIB, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
if (posix_memalign((void**)&d_fft_code_Q_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitudeQB, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
}
|
||||
}
|
||||
|
||||
// if (posix_memalign((void**)&d_fft_code_Q_A, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
// if (posix_memalign((void**)&d_magnitudeQA, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
// if (posix_memalign((void**)&d_fft_code_I_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
// if (posix_memalign((void**)&d_magnitudeIB, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
// if (posix_memalign((void**)&d_fft_code_Q_B, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
// if (posix_memalign((void**)&d_magnitudeQB, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
|
||||
// Direct FFT
|
||||
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
||||
|
||||
// Inverse FFT
|
||||
d_ifft = new gr::fft::fft_complex(d_fft_size, false);
|
||||
|
||||
// For dumping samples into a file
|
||||
d_dump = dump;
|
||||
d_dump_filename = dump_filename;
|
||||
}
|
||||
|
||||
galileo_e5a_noncoherentIQ_acquisition_caf_cc::~galileo_e5a_noncoherentIQ_acquisition_caf_cc()
|
||||
{
|
||||
if (d_num_doppler_bins > 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
free(d_grid_doppler_wipeoffs[i]);
|
||||
}
|
||||
delete[] d_grid_doppler_wipeoffs;
|
||||
}
|
||||
|
||||
free(d_fft_code_I_A);
|
||||
free(d_magnitudeIA);
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
free(d_fft_code_Q_A);
|
||||
free(d_magnitudeQA);
|
||||
}
|
||||
// IF INTEGRATION TIME > 1
|
||||
if (d_sampled_ms > 1)
|
||||
{
|
||||
free(d_fft_code_I_B);
|
||||
free(d_magnitudeIB);
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
free(d_fft_code_Q_B);
|
||||
free(d_magnitudeQB);
|
||||
}
|
||||
}
|
||||
|
||||
delete d_fft_if;
|
||||
delete d_ifft;
|
||||
|
||||
|
||||
if (d_dump)
|
||||
{
|
||||
d_dump_file.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void galileo_e5a_noncoherentIQ_acquisition_caf_cc::set_local_code(std::complex<float> * codeI, std::complex<float> * codeQ )
|
||||
{
|
||||
// DATA SIGNAL
|
||||
// Three replicas of data primary code. CODE A: (1,1,1)
|
||||
memcpy(d_fft_if->get_inbuf(), codeI, sizeof(gr_complex)*d_fft_size);
|
||||
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_code_I_A,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_code_I_A,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
// SAME FOR PILOT SIGNAL
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
// Three replicas of pilot primary code. CODE A: (1,1,1)
|
||||
memcpy(d_fft_if->get_inbuf(), codeQ, sizeof(gr_complex)*d_fft_size);
|
||||
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_code_Q_A,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_code_Q_A,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
}
|
||||
// IF INTEGRATION TIME > 1 code, we need to evaluate the other possible combination
|
||||
// Note: max integration time allowed = 3ms (dealt in adapter)
|
||||
if (d_sampled_ms > 1)
|
||||
{
|
||||
// DATA CODE B: First replica is inverted (0,1,1)
|
||||
volk_32fc_s32fc_multiply_32fc_a(&(d_fft_if->get_inbuf())[0],
|
||||
&codeI[0], gr_complex(-1,0),
|
||||
d_samples_per_code);
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_code_I_B,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_code_I_B,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
// PILOT CODE B: First replica is inverted (0,1,1)
|
||||
volk_32fc_s32fc_multiply_32fc_a(&(d_fft_if->get_inbuf())[0],
|
||||
&codeQ[0], gr_complex(-1,0),
|
||||
d_samples_per_code);
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_code_Q_B,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_code_Q_B,d_fft_if->get_outbuf(),d_fft_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void galileo_e5a_noncoherentIQ_acquisition_caf_cc::init()
|
||||
{
|
||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
||||
d_mag = 0.0;
|
||||
d_input_power = 0.0;
|
||||
|
||||
// Count the number of bins
|
||||
d_num_doppler_bins = 0;
|
||||
for (int doppler = (int)(-d_doppler_max);
|
||||
doppler <= (int)d_doppler_max;
|
||||
doppler += d_doppler_step)
|
||||
{
|
||||
d_num_doppler_bins++;
|
||||
}
|
||||
|
||||
// Create the carrier Doppler wipeoff signals
|
||||
d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
|
||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
if (posix_memalign((void**)&(d_grid_doppler_wipeoffs[doppler_index]), 16,
|
||||
d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
|
||||
int doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
|
||||
complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index],
|
||||
d_freq + doppler, d_fs_in, d_fft_size);
|
||||
}
|
||||
|
||||
/* CAF Filtering to resolve doppler ambiguity. Phase and quadrature must be processed
|
||||
* separately before non-coherent integration */
|
||||
// if (d_CAF_filter)
|
||||
if (d_CAF_window_hz > 0)
|
||||
{
|
||||
if (posix_memalign((void**)&d_CAF_vector, 16, d_num_doppler_bins * sizeof(float)) == 0){};
|
||||
if (posix_memalign((void**)&d_CAF_vector_I, 16, d_num_doppler_bins * sizeof(float)) == 0){};
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
if (posix_memalign((void**)&d_CAF_vector_Q, 16, d_num_doppler_bins * sizeof(float)) == 0){};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items,
|
||||
gr_vector_int &ninput_items, gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
/*
|
||||
* By J.Arribas, L.Esteve, M.Molina and M.Sales
|
||||
* Acquisition strategy (Kay Borre book + CFAR threshold):
|
||||
* 1. Compute the input signal power estimation
|
||||
* 2. Doppler serial search loop
|
||||
* 3. Perform the FFT-based circular convolution (parallel time search)
|
||||
* 4. OPTIONAL: CAF filter to avoid doppler ambiguity
|
||||
* 5. Record the maximum peak and the associated synchronization parameters
|
||||
* 6. Compute the test statistics and compare to the threshold
|
||||
* 7. Declare positive or negative acquisition using a message queue
|
||||
*/
|
||||
|
||||
int acquisition_message = -1; //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
||||
/* States: 0 Stop Channel
|
||||
* 1 Load the buffer until it reaches fft_size
|
||||
* 2 Acquisition algorithm
|
||||
* 3 Positive acquisition
|
||||
* 4 Negative acquisition
|
||||
*/
|
||||
switch (d_state)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (d_active)
|
||||
{
|
||||
//restart acquisition variables
|
||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
||||
d_well_count = 0;
|
||||
d_mag = 0.0;
|
||||
d_input_power = 0.0;
|
||||
d_test_statistics = 0.0;
|
||||
d_state = 1;
|
||||
}
|
||||
d_sample_counter += ninput_items[0]; // sample counter
|
||||
consume_each(ninput_items[0]);
|
||||
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
|
||||
unsigned int buff_increment;
|
||||
if (ninput_items[0]+d_buffer_count <= d_fft_size)
|
||||
{
|
||||
buff_increment = ninput_items[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
d_state=2;
|
||||
}
|
||||
d_buffer_count += buff_increment;
|
||||
d_sample_counter += buff_increment; // sample counter
|
||||
consume_each(buff_increment);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// Fill last part of the buffer and reset counter
|
||||
const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
|
||||
if (d_buffer_count < d_fft_size)
|
||||
{
|
||||
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
|
||||
|
||||
// initialize acquisition algorithm
|
||||
int doppler;
|
||||
unsigned int indext = 0;
|
||||
unsigned int indext_IA = 0;
|
||||
unsigned int indext_IB = 0;
|
||||
unsigned int indext_QA = 0;
|
||||
unsigned int indext_QB = 0;
|
||||
float magt = 0.0;
|
||||
float magt_IA = 0.0;
|
||||
float magt_IB = 0.0;
|
||||
float magt_QA = 0.0;
|
||||
float magt_QB = 0.0;
|
||||
float fft_normalization_factor = (float)d_fft_size * (float)d_fft_size;
|
||||
d_input_power = 0.0;
|
||||
d_mag = 0.0;
|
||||
d_well_count++;
|
||||
|
||||
DLOG(INFO) << "Channel: " << d_channel
|
||||
<< " , doing acquisition of satellite: " << d_gnss_synchro->System << " "<< d_gnss_synchro->PRN
|
||||
<< " ,sample stamp: " << d_sample_counter << ", threshold: "
|
||||
<< d_threshold << ", doppler_max: " << d_doppler_max
|
||||
<< ", doppler_step: " << d_doppler_step;
|
||||
|
||||
// 1- Compute the input signal power estimation
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitudeIA, d_inbuffer, d_fft_size);
|
||||
volk_32f_accumulator_s32f_a(&d_input_power, d_magnitudeIA, d_fft_size);
|
||||
d_input_power /= (float)d_fft_size;
|
||||
|
||||
// 2- Doppler frequency search loop
|
||||
for (unsigned int doppler_index=0;doppler_index<d_num_doppler_bins;doppler_index++)
|
||||
{
|
||||
// doppler search steps
|
||||
|
||||
doppler=-(int)d_doppler_max+d_doppler_step*doppler_index;
|
||||
|
||||
volk_32fc_x2_multiply_32fc_a(d_fft_if->get_inbuf(), d_inbuffer,
|
||||
d_grid_doppler_wipeoffs[doppler_index], d_fft_size);
|
||||
|
||||
// 3- Perform the FFT-based convolution (parallel time search)
|
||||
// Compute the FFT of the carrier wiped--off incoming signal
|
||||
d_fft_if->execute();
|
||||
|
||||
// CODE IA
|
||||
// Multiply carrier wiped--off, Fourier transformed incoming signal
|
||||
// with the local FFT'd code reference using SIMD operations with VOLK library
|
||||
volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_code_I_A, d_fft_size);
|
||||
|
||||
// compute the inverse FFT
|
||||
d_ifft->execute();
|
||||
|
||||
// Search maximum
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitudeIA, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext_IA, d_magnitudeIA, d_fft_size);
|
||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
||||
magt_IA = d_magnitudeIA[indext_IA] / (fft_normalization_factor * fft_normalization_factor);
|
||||
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
// REPEAT FOR ALL CODES. CODE_QA
|
||||
volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_code_Q_A, d_fft_size);
|
||||
d_ifft->execute();
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitudeQA, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext_QA, d_magnitudeQA, d_fft_size);
|
||||
magt_QA = d_magnitudeQA[indext_QA] / (fft_normalization_factor * fft_normalization_factor);
|
||||
}
|
||||
if (d_sampled_ms > 1) // If Integration time > 1 code
|
||||
{
|
||||
// REPEAT FOR ALL CODES. CODE_IB
|
||||
volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_code_I_B, d_fft_size);
|
||||
d_ifft->execute();
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitudeIB, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext_IB, d_magnitudeIB, d_fft_size);
|
||||
magt_IB = d_magnitudeIB[indext_IB] / (fft_normalization_factor * fft_normalization_factor);
|
||||
|
||||
if (d_both_signal_components == true)
|
||||
{
|
||||
// REPEAT FOR ALL CODES. CODE_QB
|
||||
volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_code_Q_B, d_fft_size);
|
||||
d_ifft->execute();
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitudeQB, d_ifft->get_outbuf(), d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext_QB, d_magnitudeQB, d_fft_size);
|
||||
magt_QB = d_magnitudeIB[indext_QB] / (fft_normalization_factor * fft_normalization_factor);
|
||||
}
|
||||
}
|
||||
|
||||
// Integrate noncoherently the two best combinations (I² + Q²)
|
||||
// and store the result in the I channel.
|
||||
// If CAF filter to resolve doppler ambiguity is needed,
|
||||
// peak is stored before non-coherent integration.
|
||||
if (d_sampled_ms > 1) // T_integration > 1 code
|
||||
{
|
||||
if (magt_IA >= magt_IB)
|
||||
{
|
||||
// if (d_CAF_filter) {d_CAF_vector_I[doppler_index] = magt_IA;}
|
||||
if (d_CAF_window_hz > 0) {d_CAF_vector_I[doppler_index] = d_magnitudeIA[indext_IA];}
|
||||
if (d_both_signal_components)
|
||||
{
|
||||
// Integrate non-coherently I+Q
|
||||
if (magt_QA >= magt_QB)
|
||||
{
|
||||
// if (d_CAF_filter) {d_CAF_vector_Q[doppler_index] = magt_QA;}
|
||||
if (d_CAF_window_hz > 0) {d_CAF_vector_Q[doppler_index] = d_magnitudeQA[indext_QA];}
|
||||
for (unsigned int i=0; i<d_fft_size; i++)
|
||||
{
|
||||
d_magnitudeIA[i] += d_magnitudeQA[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if (d_CAF_filter) {d_CAF_vector_Q[doppler_index] = magt_QB;}
|
||||
if (d_CAF_window_hz > 0) {d_CAF_vector_Q[doppler_index] = d_magnitudeQB[indext_QB];}
|
||||
for (unsigned int i=0; i<d_fft_size; i++)
|
||||
{
|
||||
d_magnitudeIA[i] += d_magnitudeQB[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
volk_32f_index_max_16u_a(&indext, d_magnitudeIA, d_fft_size);
|
||||
magt = d_magnitudeIA[indext] / (fft_normalization_factor * fft_normalization_factor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if (d_CAF_filter) {d_CAF_vector_I[doppler_index] = magt_IB;}
|
||||
if (d_CAF_window_hz > 0) {d_CAF_vector_I[doppler_index] = d_magnitudeIB[indext_IB];}
|
||||
if (d_both_signal_components)
|
||||
{
|
||||
// Integrate non-coherently I+Q
|
||||
if (magt_QA >= magt_QB)
|
||||
{
|
||||
//if (d_CAF_filter) {d_CAF_vector_Q[doppler_index] = magt_QA;}
|
||||
if (d_CAF_window_hz > 0) {d_CAF_vector_Q[doppler_index] = d_magnitudeQA[indext_QA];}
|
||||
for (unsigned int i=0; i<d_fft_size; i++)
|
||||
{
|
||||
d_magnitudeIB[i] += d_magnitudeQA[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if (d_CAF_filter) {d_CAF_vector_Q[doppler_index] = magt_QB;}
|
||||
if (d_CAF_window_hz > 0) {d_CAF_vector_Q[doppler_index] = d_magnitudeQB[indext_QB];}
|
||||
for (unsigned int i=0; i<d_fft_size; i++)
|
||||
{
|
||||
d_magnitudeIB[i] += d_magnitudeQB[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
volk_32f_index_max_16u_a(&indext, d_magnitudeIB, d_fft_size);
|
||||
magt = d_magnitudeIB[indext] / (fft_normalization_factor * fft_normalization_factor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if (d_CAF_filter) {d_CAF_vector_I[doppler_index] = magt_IA;}
|
||||
if (d_CAF_window_hz > 0) {d_CAF_vector_I[doppler_index] = d_magnitudeIA[indext_IA];}
|
||||
if (d_both_signal_components)
|
||||
{
|
||||
// if (d_CAF_filter) {d_CAF_vector_Q[doppler_index] = magt_QA;}
|
||||
if (d_CAF_window_hz > 0) {d_CAF_vector_Q[doppler_index] = d_magnitudeQA[indext_QA];}
|
||||
// NON-Coherent integration of only 1 code
|
||||
for (unsigned int i=0; i<d_fft_size; i++)
|
||||
{
|
||||
d_magnitudeIA[i] += d_magnitudeQA[i];
|
||||
}
|
||||
}
|
||||
volk_32f_index_max_16u_a(&indext, d_magnitudeIA, d_fft_size);
|
||||
magt = d_magnitudeIA[indext] / (fft_normalization_factor * fft_normalization_factor);
|
||||
}
|
||||
|
||||
// 4- record the maximum peak and the associated synchronization parameters
|
||||
if (d_mag < magt)
|
||||
{
|
||||
d_mag = magt;
|
||||
// In case that d_bit_transition_flag = true, we compare the potentially
|
||||
// new maximum test statistics (d_mag/d_input_power) with the value in
|
||||
// d_test_statistics. When the second dwell is being processed, the value
|
||||
// of d_mag/d_input_power could be lower than d_test_statistics (i.e,
|
||||
// the maximum test statistics in the previous dwell is greater than
|
||||
// current d_mag/d_input_power). Note that d_test_statistics is not
|
||||
// restarted between consecutive dwells in multidwell operation.
|
||||
if (d_test_statistics < (d_mag / d_input_power) || !d_bit_transition_flag)
|
||||
{
|
||||
d_gnss_synchro->Acq_delay_samples = (double)(indext % d_samples_per_code);
|
||||
d_gnss_synchro->Acq_doppler_hz = (double)doppler;
|
||||
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
||||
|
||||
// 5- Compute the test statistics and compare to the threshold
|
||||
d_test_statistics = d_mag / d_input_power;
|
||||
}
|
||||
}
|
||||
|
||||
// Record results to file if required
|
||||
if (d_dump)
|
||||
{
|
||||
std::stringstream filename;
|
||||
std::streamsize n = sizeof(float) * (d_fft_size); // noncomplex file write
|
||||
filename.str("");
|
||||
filename << "../data/test_statistics_E5a_sat_"
|
||||
<< d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat";
|
||||
d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
|
||||
if (d_sampled_ms > 1) // If integration time > 1 code
|
||||
{
|
||||
if (magt_IA >= magt_IB)
|
||||
{
|
||||
d_dump_file.write((char*)d_magnitudeIA, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
d_dump_file.write((char*)d_magnitudeIB, n);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
d_dump_file.write((char*)d_magnitudeIA, n);
|
||||
}
|
||||
d_dump_file.close();
|
||||
}
|
||||
}
|
||||
// std::cout << "d_mag " << d_mag << ".d_sample_counter " << d_sample_counter << ". acq delay " << d_gnss_synchro->Acq_delay_samples<< " indext "<< indext << std::endl;
|
||||
// 6 OPTIONAL: CAF filter to avoid Doppler ambiguity in bit transition.
|
||||
if (d_CAF_window_hz > 0)
|
||||
{
|
||||
int CAF_bins_half;
|
||||
float* accum;
|
||||
// double* accum;
|
||||
if (posix_memalign((void**)&accum, 16, sizeof(float)) == 0){};
|
||||
CAF_bins_half = d_CAF_window_hz/(2*d_doppler_step);
|
||||
float weighting_factor;
|
||||
weighting_factor = 0.5/(float)CAF_bins_half;
|
||||
// weighting_factor = 0;
|
||||
// std::cout << "weighting_factor " << weighting_factor << std::endl;
|
||||
// Initialize first iterations
|
||||
for (int doppler_index=0;doppler_index<CAF_bins_half;doppler_index++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&d_CAF_vector[doppler_index], d_CAF_vector_I, CAF_bins_half+doppler_index+1);
|
||||
for (int i = 0; i < CAF_bins_half+doppler_index+1; i++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] += d_CAF_vector_I[i] * (1-weighting_factor*(unsigned int)(abs(doppler_index - i)));
|
||||
}
|
||||
// d_CAF_vector[doppler_index] /= CAF_bins_half+doppler_index+1;
|
||||
d_CAF_vector[doppler_index] /= 1+CAF_bins_half+doppler_index - weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2 - weighting_factor*doppler_index*(doppler_index+1)/2; // triangles = [n*(n+1)/2]
|
||||
if (d_both_signal_components)
|
||||
{
|
||||
accum[0] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&accum[0], d_CAF_vector_Q, CAF_bins_half+doppler_index+1);
|
||||
for (int i = 0; i < CAF_bins_half+doppler_index+1; i++)
|
||||
{
|
||||
accum[0] += d_CAF_vector_Q[i] * (1-weighting_factor*(unsigned int)(abs(doppler_index - i)));
|
||||
}
|
||||
// accum[0] /= CAF_bins_half+doppler_index+1;
|
||||
accum[0] /= 1+CAF_bins_half+doppler_index - weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2 - weighting_factor*doppler_index*(doppler_index+1)/2; // triangles = [n*(n+1)/2]
|
||||
d_CAF_vector[doppler_index] += accum[0];
|
||||
}
|
||||
}
|
||||
// Body loop
|
||||
for (unsigned int doppler_index=CAF_bins_half;doppler_index<d_num_doppler_bins-CAF_bins_half;doppler_index++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&d_CAF_vector[doppler_index], &d_CAF_vector_I[doppler_index-CAF_bins_half], 2*CAF_bins_half+1);
|
||||
for (int i = doppler_index-CAF_bins_half; i < doppler_index+CAF_bins_half+1; i++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] += d_CAF_vector_I[i] * (1-weighting_factor*(unsigned int)(abs(doppler_index - i)));
|
||||
}
|
||||
// d_CAF_vector[doppler_index] /= 2*CAF_bins_half+1;
|
||||
d_CAF_vector[doppler_index] /= 1+2*CAF_bins_half - 2*weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2;
|
||||
if (d_both_signal_components)
|
||||
{
|
||||
accum[0] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&accum[0], &d_CAF_vector_Q[doppler_index-CAF_bins_half], 2*CAF_bins_half);
|
||||
for (int i = doppler_index-CAF_bins_half; i < doppler_index+CAF_bins_half+1; i++)
|
||||
{
|
||||
accum[0] += d_CAF_vector_Q[i] * (1-weighting_factor*(unsigned int)(abs(doppler_index - i)));
|
||||
}
|
||||
// accum[0] /= 2*CAF_bins_half+1;
|
||||
accum[0] /= 1+2*CAF_bins_half - 2*weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2;
|
||||
d_CAF_vector[doppler_index] += accum[0];
|
||||
}
|
||||
}
|
||||
// Final iterations
|
||||
for (unsigned int doppler_index=d_num_doppler_bins-CAF_bins_half;doppler_index<d_num_doppler_bins;doppler_index++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&d_CAF_vector[doppler_index], &d_CAF_vector_I[doppler_index-CAF_bins_half], CAF_bins_half + (d_num_doppler_bins-doppler_index));
|
||||
for (int i = doppler_index-CAF_bins_half; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
d_CAF_vector[doppler_index] += d_CAF_vector_I[i] * (1-weighting_factor*(abs(doppler_index - i)));
|
||||
}
|
||||
// d_CAF_vector[doppler_index] /= CAF_bins_half+(d_num_doppler_bins-doppler_index);
|
||||
d_CAF_vector[doppler_index] /= 1+CAF_bins_half+(d_num_doppler_bins-doppler_index-1) -weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2 -weighting_factor*(d_num_doppler_bins-doppler_index-1)*(d_num_doppler_bins-doppler_index)/2;
|
||||
if (d_both_signal_components)
|
||||
{
|
||||
accum[0] = 0;
|
||||
// volk_32f_accumulator_s32f_a(&accum[0], &d_CAF_vector_Q[doppler_index-CAF_bins_half], CAF_bins_half + (d_num_doppler_bins-doppler_index));
|
||||
for (int i = doppler_index-CAF_bins_half; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
accum[0] += d_CAF_vector_Q[i] * (1-weighting_factor*(abs(doppler_index - i)));
|
||||
}
|
||||
// accum[0] /= CAF_bins_half+(d_num_doppler_bins-doppler_index);
|
||||
accum[0] /= 1+CAF_bins_half+(d_num_doppler_bins-doppler_index-1) -weighting_factor*CAF_bins_half*(CAF_bins_half+1)/2 -weighting_factor*(d_num_doppler_bins-doppler_index-1)*(d_num_doppler_bins-doppler_index)/2;
|
||||
d_CAF_vector[doppler_index] += accum[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Recompute the maximum doppler peak
|
||||
volk_32f_index_max_16u_a(&indext, d_CAF_vector, d_num_doppler_bins);
|
||||
doppler=-(int)d_doppler_max+d_doppler_step*indext;
|
||||
d_gnss_synchro->Acq_doppler_hz = (double)doppler;
|
||||
// Dump if required, appended at the end of the file
|
||||
if (d_dump)
|
||||
{
|
||||
std::stringstream filename;
|
||||
std::streamsize n = sizeof(float) * (d_num_doppler_bins); // noncomplex file write
|
||||
filename.str("");
|
||||
filename << "../data/test_statistics_E5a_sat_"
|
||||
<< d_gnss_synchro->PRN << "_CAF.dat";
|
||||
d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
|
||||
d_dump_file.write((char*)d_CAF_vector, n);
|
||||
d_dump_file.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (d_well_count == d_max_dwells)
|
||||
{
|
||||
if (d_test_statistics > d_threshold)
|
||||
{
|
||||
d_state = 3; // Positive acquisition
|
||||
}
|
||||
else
|
||||
{
|
||||
d_state = 4; // Negative acquisition
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
d_state = 1;
|
||||
}
|
||||
|
||||
consume_each(d_fft_size-d_buffer_count);
|
||||
d_buffer_count = 0;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
// 7.1- Declare positive acquisition using a message queue
|
||||
DLOG(INFO) << "positive acquisition";
|
||||
DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
|
||||
DLOG(INFO) << "sample_stamp " << d_sample_counter;
|
||||
DLOG(INFO) << "test statistics value " << d_test_statistics;
|
||||
DLOG(INFO) << "test statistics threshold " << d_threshold;
|
||||
DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
|
||||
DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
|
||||
DLOG(INFO) << "magnitude " << d_mag;
|
||||
DLOG(INFO) << "input signal power " << d_input_power;
|
||||
|
||||
d_active = false;
|
||||
d_state = 0;
|
||||
|
||||
|
||||
acquisition_message = 1;
|
||||
d_channel_internal_queue->push(acquisition_message);
|
||||
d_sample_counter += ninput_items[0]; // sample counter
|
||||
consume_each(ninput_items[0]);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
// 7.2- Declare negative acquisition using a message queue
|
||||
DLOG(INFO) << "negative acquisition";
|
||||
DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
|
||||
DLOG(INFO) << "sample_stamp " << d_sample_counter;
|
||||
DLOG(INFO) << "test statistics value " << d_test_statistics;
|
||||
DLOG(INFO) << "test statistics threshold " << d_threshold;
|
||||
DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
|
||||
DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
|
||||
DLOG(INFO) << "magnitude " << d_mag;
|
||||
DLOG(INFO) << "input signal power " << d_input_power;
|
||||
|
||||
d_active = false;
|
||||
d_state = 0;
|
||||
|
||||
d_sample_counter += ninput_items[0]; // sample counter
|
||||
consume_each(ninput_items[0]);
|
||||
acquisition_message = 2;
|
||||
d_channel_internal_queue->push(acquisition_message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,261 @@
|
||||
/*!
|
||||
* \file galileo_e5a_noncoherent_iq_acquisition_caf_cc.h
|
||||
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||
* Galileo E5a data and pilot Signals
|
||||
* \author Marc Sales, 2014. marcsales92(at)gmail.com
|
||||
* \based on work from:
|
||||
* <ul>
|
||||
* <li> Javier Arribas, 2011. jarribas(at)cttc.es
|
||||
* <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com
|
||||
* <li> Marc Molina, 2013. marc.molina.pena@gmail.com
|
||||
* </ul>
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_CC_H_
|
||||
#define GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_CC_H_
|
||||
|
||||
#include <fstream>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/gr_complex.h>
|
||||
#include <gnuradio/fft/fft.h>
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_synchro.h"
|
||||
|
||||
class galileo_e5a_noncoherentIQ_acquisition_caf_cc;
|
||||
|
||||
typedef boost::shared_ptr<galileo_e5a_noncoherentIQ_acquisition_caf_cc> galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr;
|
||||
|
||||
galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr
|
||||
galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(unsigned int sampled_ms,
|
||||
unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag,
|
||||
gr::msg_queue::sptr queue, bool dump,
|
||||
std::string dump_filename,
|
||||
bool both_signal_components_,
|
||||
int CAF_window_hz_,
|
||||
int Zero_padding_);
|
||||
|
||||
/*!
|
||||
* \brief This class implements a Parallel Code Phase Search Acquisition.
|
||||
*
|
||||
* Check \ref Navitec2012 "An Open Source Galileo E1 Software Receiver",
|
||||
* Algorithm 1, for a pseudocode description of this implementation.
|
||||
*/
|
||||
class galileo_e5a_noncoherentIQ_acquisition_caf_cc: public gr::block
|
||||
{
|
||||
private:
|
||||
friend galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr
|
||||
galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(
|
||||
unsigned int sampled_ms,
|
||||
unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag,
|
||||
gr::msg_queue::sptr queue, bool dump,
|
||||
std::string dump_filename,
|
||||
bool both_signal_components_,
|
||||
int CAF_window_hz_,
|
||||
int Zero_padding_);
|
||||
|
||||
galileo_e5a_noncoherentIQ_acquisition_caf_cc(
|
||||
unsigned int sampled_ms,
|
||||
unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag,
|
||||
gr::msg_queue::sptr queue, bool dump,
|
||||
std::string dump_filename,
|
||||
bool both_signal_components_,
|
||||
int CAF_window_hz_,
|
||||
int Zero_padding_);
|
||||
|
||||
void calculate_magnitudes(gr_complex* fft_begin, int doppler_shift,
|
||||
int doppler_offset);
|
||||
float estimate_input_power(gr_complex *in );
|
||||
|
||||
long d_fs_in;
|
||||
long d_freq;
|
||||
int d_samples_per_ms;
|
||||
int d_sampled_ms;
|
||||
int d_samples_per_code;
|
||||
unsigned int d_doppler_resolution;
|
||||
float d_threshold;
|
||||
std::string d_satellite_str;
|
||||
unsigned int d_doppler_max;
|
||||
unsigned int d_doppler_step;
|
||||
unsigned int d_max_dwells;
|
||||
unsigned int d_well_count;
|
||||
unsigned int d_fft_size;
|
||||
unsigned long int d_sample_counter;
|
||||
gr_complex** d_grid_doppler_wipeoffs;
|
||||
unsigned int d_num_doppler_bins;
|
||||
gr_complex* d_fft_code_I_A;
|
||||
gr_complex* d_fft_code_I_B;
|
||||
gr_complex* d_fft_code_Q_A;
|
||||
gr_complex* d_fft_code_Q_B;
|
||||
gr_complex* d_inbuffer;
|
||||
gr::fft::fft_complex* d_fft_if;
|
||||
gr::fft::fft_complex* d_ifft;
|
||||
Gnss_Synchro *d_gnss_synchro;
|
||||
unsigned int d_code_phase;
|
||||
float d_doppler_freq;
|
||||
float d_mag;
|
||||
float* d_magnitudeIA;
|
||||
float* d_magnitudeIB;
|
||||
float* d_magnitudeQA;
|
||||
float* d_magnitudeQB;
|
||||
float d_input_power;
|
||||
float d_test_statistics;
|
||||
bool d_bit_transition_flag;
|
||||
gr::msg_queue::sptr d_queue;
|
||||
concurrent_queue<int> *d_channel_internal_queue;
|
||||
std::ofstream d_dump_file;
|
||||
bool d_active;
|
||||
int d_state;
|
||||
bool d_dump;
|
||||
bool d_both_signal_components;
|
||||
// bool d_CAF_filter;
|
||||
int d_CAF_window_hz;
|
||||
float* d_CAF_vector;
|
||||
float* d_CAF_vector_I;
|
||||
float* d_CAF_vector_Q;
|
||||
// double* d_CAF_vector;
|
||||
// double* d_CAF_vector_I;
|
||||
// double* d_CAF_vector_Q;
|
||||
unsigned int d_channel;
|
||||
std::string d_dump_filename;
|
||||
unsigned int d_buffer_count;
|
||||
unsigned int d_gr_stream_buffer;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Default destructor.
|
||||
*/
|
||||
~galileo_e5a_noncoherentIQ_acquisition_caf_cc();
|
||||
|
||||
/*!
|
||||
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
|
||||
* to exchange synchronization data between acquisition and tracking blocks.
|
||||
* \param p_gnss_synchro Satellite information shared by the processing blocks.
|
||||
*/
|
||||
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
|
||||
{
|
||||
d_gnss_synchro = p_gnss_synchro;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the maximum peak of grid search.
|
||||
*/
|
||||
unsigned int mag()
|
||||
{
|
||||
return d_mag;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Initializes acquisition algorithm.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/*!
|
||||
* \brief Sets local code for PCPS acquisition algorithm.
|
||||
* \param code - Pointer to the PRN code.
|
||||
*/
|
||||
void set_local_code(std::complex<float> * code, std::complex<float> * codeQ);
|
||||
|
||||
/*!
|
||||
* \brief Starts acquisition algorithm, turning from standby mode to
|
||||
* active mode
|
||||
* \param active - bool that activates/deactivates the block.
|
||||
*/
|
||||
void set_active(bool active)
|
||||
{
|
||||
d_active = active;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Set acquisition channel unique ID
|
||||
* \param channel - receiver channel.
|
||||
*/
|
||||
void set_channel(unsigned int channel)
|
||||
{
|
||||
d_channel = channel;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Set statistics threshold of PCPS algorithm.
|
||||
* \param threshold - Threshold for signal detection (check \ref Navitec2012,
|
||||
* Algorithm 1, for a definition of this threshold).
|
||||
*/
|
||||
void set_threshold(float threshold)
|
||||
{
|
||||
d_threshold = threshold;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Set maximum Doppler grid search
|
||||
* \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
|
||||
*/
|
||||
void set_doppler_max(unsigned int doppler_max)
|
||||
{
|
||||
d_doppler_max = doppler_max;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Set Doppler steps for the grid search
|
||||
* \param doppler_step - Frequency bin of the search grid [Hz].
|
||||
*/
|
||||
void set_doppler_step(unsigned int doppler_step)
|
||||
{
|
||||
d_doppler_step = doppler_step;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Set tracking channel internal queue.
|
||||
* \param channel_internal_queue - Channel's internal blocks information queue.
|
||||
*/
|
||||
void set_channel_queue(concurrent_queue<int> *channel_internal_queue)
|
||||
{
|
||||
d_channel_internal_queue = channel_internal_queue;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Parallel Code Phase Search Acquisition signal processing.
|
||||
*/
|
||||
int general_work(int noutput_items, gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items);
|
||||
|
||||
};
|
||||
#endif /* GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_CC_H_ */
|
@ -0,0 +1,596 @@
|
||||
/*!
|
||||
* \file pcps_quicksync_acquisition_cc.cc
|
||||
* \brief This class implements a Parallel Code Phase Search Acquisition
|
||||
* \author Damian Miralles Sanchez, 2014. dmiralles2009(at)gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "pcps_quicksync_acquisition_cc.h"
|
||||
#include <ctime>
|
||||
#include <cmath>
|
||||
#include <sstream>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <glog/logging.h>
|
||||
#include <volk/volk.h>
|
||||
#include "control_message_factory.h"
|
||||
#include "gnss_signal_processing.h"
|
||||
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
pcps_quicksync_acquisition_cc_sptr pcps_quicksync_make_acquisition_cc(
|
||||
unsigned int folding_factor,
|
||||
unsigned int sampled_ms, unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag,
|
||||
gr::msg_queue::sptr queue, bool dump,
|
||||
std::string dump_filename)
|
||||
{
|
||||
|
||||
return pcps_quicksync_acquisition_cc_sptr(
|
||||
new pcps_quicksync_acquisition_cc(
|
||||
folding_factor,
|
||||
sampled_ms, max_dwells, doppler_max,
|
||||
freq, fs_in, samples_per_ms,
|
||||
samples_per_code,
|
||||
bit_transition_flag,
|
||||
queue, dump, dump_filename));
|
||||
}
|
||||
|
||||
pcps_quicksync_acquisition_cc::pcps_quicksync_acquisition_cc(
|
||||
unsigned int folding_factor,
|
||||
unsigned int sampled_ms, unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag,
|
||||
gr::msg_queue::sptr queue, bool dump,
|
||||
std::string dump_filename):
|
||||
gr::block("pcps_quicksync_acquisition_cc",
|
||||
gr::io_signature::make(1, 1, (sizeof(gr_complex)*sampled_ms * samples_per_ms )),
|
||||
gr::io_signature::make(0, 0, (sizeof(gr_complex)*sampled_ms * samples_per_ms )))
|
||||
{
|
||||
//DLOG(INFO) << "START CONSTRUCTOR";
|
||||
|
||||
d_sample_counter = 0; // SAMPLE COUNTER
|
||||
d_active = false;
|
||||
d_state = 0;
|
||||
d_queue = queue;
|
||||
d_freq = freq;
|
||||
d_fs_in = fs_in;
|
||||
d_samples_per_ms = samples_per_ms;
|
||||
d_samples_per_code = samples_per_code;
|
||||
d_sampled_ms = sampled_ms;
|
||||
d_max_dwells = max_dwells;
|
||||
d_well_count = 0;
|
||||
d_doppler_max = doppler_max;
|
||||
d_mag = 0;
|
||||
d_input_power = 0.0;
|
||||
d_num_doppler_bins = 0;
|
||||
d_bit_transition_flag = bit_transition_flag;
|
||||
d_folding_factor = folding_factor;
|
||||
|
||||
//fft size is reduced.
|
||||
d_fft_size = (d_samples_per_code) / d_folding_factor;
|
||||
|
||||
|
||||
//todo: do something if posix_memalign fails
|
||||
if (posix_memalign((void**)&d_fft_codes, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitude, 16, d_samples_per_code * d_folding_factor * sizeof(float)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitude_folded, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
|
||||
d_possible_delay = new unsigned int[d_folding_factor];
|
||||
d_corr_output_f = new float[d_folding_factor];
|
||||
|
||||
/*Create the d_code signal , which would store the values of the code in its
|
||||
original form to perform later correlation in time domain*/
|
||||
d_code = new gr_complex[d_samples_per_code]();
|
||||
|
||||
|
||||
// Direct FFT
|
||||
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
||||
// Inverse FFT
|
||||
d_ifft = new gr::fft::fft_complex(d_fft_size, false);
|
||||
|
||||
// For dumping samples into a file
|
||||
d_dump = dump;
|
||||
d_dump_filename = dump_filename;
|
||||
|
||||
// DLOG(INFO) << "END CONSTRUCTOR";
|
||||
}
|
||||
|
||||
pcps_quicksync_acquisition_cc::~pcps_quicksync_acquisition_cc()
|
||||
{
|
||||
//DLOG(INFO) << "START DESTROYER";
|
||||
if (d_num_doppler_bins > 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
free(d_grid_doppler_wipeoffs[i]);
|
||||
}
|
||||
delete[] d_grid_doppler_wipeoffs;
|
||||
}
|
||||
|
||||
free(d_fft_codes);
|
||||
free(d_magnitude);
|
||||
free(d_magnitude_folded);
|
||||
|
||||
delete d_ifft;
|
||||
d_ifft = NULL;
|
||||
delete d_fft_if;
|
||||
d_fft_if = NULL;
|
||||
delete d_code;
|
||||
d_code = NULL;
|
||||
delete d_possible_delay;
|
||||
d_possible_delay = NULL;
|
||||
delete d_corr_output_f;
|
||||
d_corr_output_f = NULL;
|
||||
if (d_dump)
|
||||
{
|
||||
d_dump_file.close();
|
||||
}
|
||||
// DLOG(INFO) << "END DESTROYER";
|
||||
}
|
||||
|
||||
void pcps_quicksync_acquisition_cc::set_local_code(std::complex<float> * code)
|
||||
{
|
||||
// DLOG(INFO) << "START LOCAL CODE";
|
||||
|
||||
|
||||
/*save a local copy of the code without the folding process to perform corre-
|
||||
lation in time in the final steps of the acquisition stage*/
|
||||
memcpy(d_code, code, sizeof(gr_complex)*d_samples_per_code);
|
||||
|
||||
d_code_folded = new gr_complex[d_fft_size]();
|
||||
memcpy(d_fft_if->get_inbuf(), d_code_folded, sizeof(gr_complex)*(d_fft_size));
|
||||
|
||||
/*perform folding of the code by the factorial factor parameter. Notice that
|
||||
folding of the code in the time stage would result in a downsampled spectrum
|
||||
in the frequency domain after applying the fftw operation*/
|
||||
for (unsigned int i = 0; i < d_folding_factor; i++)
|
||||
{
|
||||
std::transform ((code + i*d_fft_size), (code + ((i+1)*d_fft_size)) ,
|
||||
d_fft_if->get_inbuf(), d_fft_if->get_inbuf(),
|
||||
std::plus<gr_complex>());
|
||||
}
|
||||
|
||||
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_codes,d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_codes,d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
// DLOG(INFO) << "END LOCAL CODE";
|
||||
|
||||
}
|
||||
|
||||
void pcps_quicksync_acquisition_cc::init()
|
||||
{
|
||||
//DLOG(INFO) << "START init";
|
||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
||||
d_mag = 0.0;
|
||||
d_input_power = 0.0;
|
||||
|
||||
// Count the number of bins
|
||||
d_num_doppler_bins = 0;
|
||||
for (int doppler = (int)(-d_doppler_max);
|
||||
doppler <= (int)(d_doppler_max);
|
||||
doppler += d_doppler_step)
|
||||
{
|
||||
d_num_doppler_bins++;
|
||||
}
|
||||
|
||||
// Create the carrier Doppler wipeoff signals
|
||||
d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
|
||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
if (posix_memalign((void**)&(d_grid_doppler_wipeoffs[doppler_index]), 16,
|
||||
d_samples_per_code * d_folding_factor * sizeof(gr_complex)) == 0){};
|
||||
|
||||
int doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
|
||||
complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index],
|
||||
d_freq + doppler, d_fs_in,
|
||||
d_samples_per_code * d_folding_factor);
|
||||
}
|
||||
// DLOG(INFO) << "end init";
|
||||
}
|
||||
|
||||
int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
|
||||
gr_vector_int &ninput_items, gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
/*
|
||||
* By J.Arribas, L.Esteve and M.Molina
|
||||
* Acquisition strategy (Kay Borre book + CFAR threshold):
|
||||
* 1. Compute the input signal power estimation
|
||||
* 2. Doppler serial search loop
|
||||
* 3. Perform the FFT-based circular convolution (parallel time search)
|
||||
* 4. Record the maximum peak and the associated synchronization parameters
|
||||
* 5. Compute the test statistics and compare to the threshold
|
||||
* 6. Declare positive or negative acquisition using a message queue
|
||||
*/
|
||||
//DLOG(INFO) << "START GENERAL WORK";
|
||||
int acquisition_message = -1; //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
||||
//std::cout<<"general_work in quicksync gnuradio block"<<std::endl;
|
||||
switch (d_state)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
//DLOG(INFO) << "START CASE 0";
|
||||
if (d_active)
|
||||
{
|
||||
//restart acquisition variables
|
||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
||||
d_well_count = 0;
|
||||
d_mag = 0.0;
|
||||
d_input_power = 0.0;
|
||||
d_test_statistics = 0.0;
|
||||
|
||||
d_state = 1;
|
||||
}
|
||||
|
||||
d_sample_counter += d_sampled_ms * d_samples_per_ms * ninput_items[0]; // sample counter
|
||||
consume_each(ninput_items[0]);
|
||||
//DLOG(INFO) << "END CASE 0";
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
/* initialize acquisition implementing the QuickSync algorithm*/
|
||||
//DLOG(INFO) << "START CASE 1";
|
||||
int doppler;
|
||||
unsigned int indext = 0;
|
||||
float magt = 0.0;
|
||||
const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
|
||||
|
||||
gr_complex *in_temp;
|
||||
if (posix_memalign((void**)&(in_temp), 16,d_samples_per_code * d_folding_factor * sizeof(gr_complex)) == 0){};
|
||||
|
||||
|
||||
gr_complex *in_temp_folded;
|
||||
if (posix_memalign((void**)&(in_temp_folded), 16,d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
|
||||
/*Create a signal to store a signal of size 1ms, to perform correlation
|
||||
in time. No folding on this data is required*/
|
||||
gr_complex *in_1code;
|
||||
if (posix_memalign((void**)&(in_1code), 16,d_samples_per_code * sizeof(gr_complex)) == 0){};
|
||||
|
||||
/*Stores the values of the correlation output between the local code
|
||||
and the signal with doppler shift corrected */
|
||||
gr_complex *corr_output;
|
||||
if (posix_memalign((void**)&(corr_output), 16,d_samples_per_code * sizeof(gr_complex)) == 0){};
|
||||
|
||||
/*Stores a copy of the folded version of the signal.This is used for
|
||||
the FFT operations in future steps of excecution*/
|
||||
// gr_complex in_folded[d_fft_size];
|
||||
float fft_normalization_factor = (float)d_fft_size * (float)d_fft_size;
|
||||
|
||||
d_input_power = 0.0;
|
||||
d_mag = 0.0;
|
||||
d_test_statistics = 0.0;
|
||||
d_noise_floor_power = 0.0;
|
||||
|
||||
d_sample_counter += d_sampled_ms * d_samples_per_ms; // sample counter
|
||||
|
||||
d_well_count++;
|
||||
|
||||
DLOG(INFO) << "Channel: " << d_channel
|
||||
<< " , doing acquisition of satellite: "
|
||||
<< d_gnss_synchro->System << " "<< d_gnss_synchro->PRN
|
||||
<< " ,algorithm: pcps_quicksync_acquisition"
|
||||
<< " ,folding factor: " << d_folding_factor
|
||||
<< " ,sample stamp: " << d_sample_counter << ", threshold: "
|
||||
<< d_threshold << ", doppler_max: " << d_doppler_max
|
||||
<< ", doppler_step: " << d_doppler_step << ", Signal Size: "
|
||||
<< d_samples_per_code * d_folding_factor;
|
||||
|
||||
|
||||
/* 1- Compute the input signal power estimation. This operation is
|
||||
being performed in a signal of size nxp */
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, in, d_samples_per_code * d_folding_factor);
|
||||
volk_32f_accumulator_s32f_a(&d_input_power, d_magnitude, d_samples_per_code * d_folding_factor);
|
||||
d_input_power /= (float)(d_samples_per_code * d_folding_factor);
|
||||
|
||||
|
||||
|
||||
for (unsigned int doppler_index=0;doppler_index<d_num_doppler_bins;doppler_index++)
|
||||
{
|
||||
/*Ensure that the signal is going to start with all samples
|
||||
at zero. This is done to avoid over acumulation when performing
|
||||
the folding process to be stored in d_fft_if->get_inbuf()*/
|
||||
d_signal_folded = new gr_complex[d_fft_size]();
|
||||
memcpy( d_fft_if->get_inbuf(),d_signal_folded,
|
||||
sizeof(gr_complex)*(d_fft_size));
|
||||
|
||||
/*Doppler search steps and then multiplication of the incoming
|
||||
signal with the doppler wipeoffs to eliminate frequency offset
|
||||
*/
|
||||
doppler=-(int)d_doppler_max+d_doppler_step*doppler_index;
|
||||
|
||||
/*Perform multiplication of the incoming signal with the
|
||||
complex exponential vector. This removes the frequency doppler
|
||||
shift offset*/
|
||||
volk_32fc_x2_multiply_32fc_a(in_temp, in,
|
||||
d_grid_doppler_wipeoffs[doppler_index],
|
||||
d_samples_per_code * d_folding_factor);
|
||||
|
||||
/*Perform folding of the carrier wiped-off incoming signal. Since
|
||||
superlinear method is being used the folding factor in the
|
||||
incoming raw data signal is of d_folding_factor^2*/
|
||||
for ( int i = 0; i < (int)(d_folding_factor*d_folding_factor); i++)
|
||||
{
|
||||
std::transform ((in_temp+i*d_fft_size),
|
||||
(in_temp+((i+1)*d_fft_size)) ,
|
||||
d_fft_if->get_inbuf(),
|
||||
d_fft_if->get_inbuf(),
|
||||
std::plus<gr_complex>());
|
||||
}
|
||||
|
||||
/* 3- Perform the FFT-based convolution (parallel time search)
|
||||
Compute the FFT of the carrier wiped--off incoming signal*/
|
||||
d_fft_if->execute();
|
||||
|
||||
/*Multiply carrier wiped--off, Fourier transformed incoming
|
||||
signal with the local FFT'd code reference using SIMD
|
||||
operations with VOLK library*/
|
||||
volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_codes, d_fft_size);
|
||||
|
||||
/* compute the inverse FFT of the aliased signal*/
|
||||
d_ifft->execute();
|
||||
|
||||
/* Compute the magnitude and get the maximum value with its
|
||||
index position*/
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude_folded,
|
||||
d_ifft->get_outbuf(), d_fft_size);
|
||||
|
||||
/* Normalize the maximum value to correct the scale factor
|
||||
introduced by FFTW*/
|
||||
//volk_32f_s32f_multiply_32f_a(d_magnitude_folded,d_magnitude_folded,
|
||||
// (1 / (fft_normalization_factor * fft_normalization_factor)), d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext, d_magnitude_folded, d_fft_size);
|
||||
|
||||
magt = d_magnitude_folded[indext]/ (fft_normalization_factor * fft_normalization_factor);
|
||||
|
||||
delete d_signal_folded;
|
||||
|
||||
// 4- record the maximum peak and the associated synchronization parameters
|
||||
if (d_mag < magt)
|
||||
{
|
||||
d_mag = magt;
|
||||
|
||||
/* In case that d_bit_transition_flag = true, we compare the potentially
|
||||
new maximum test statistics (d_mag/d_input_power) with the value in
|
||||
d_test_statistics. When the second dwell is being processed, the value
|
||||
of d_mag/d_input_power could be lower than d_test_statistics (i.e,
|
||||
the maximum test statistics in the previous dwell is greater than
|
||||
current d_mag/d_input_power). Note that d_test_statistics is not
|
||||
restarted between consecutive dwells in multidwell operation.*/
|
||||
if (d_test_statistics < (d_mag / d_input_power) || !d_bit_transition_flag)
|
||||
{
|
||||
unsigned int detected_delay_samples_folded = 0;
|
||||
detected_delay_samples_folded = (indext % d_samples_per_code);
|
||||
//float d_corr_output_f[d_folding_factor];
|
||||
gr_complex complex_acumulator[100];
|
||||
//gr_complex complex_acumulator[d_folding_factor];
|
||||
//const int ff = d_folding_factor;
|
||||
//gr_complex complex_acumulator[ff];
|
||||
//gr_complex complex_acumulator[];
|
||||
//complex_acumulator = new gr_complex[d_folding_factor]();
|
||||
|
||||
for (int i = 0; i < (int)d_folding_factor; i++)
|
||||
{
|
||||
d_possible_delay[i]= detected_delay_samples_folded+
|
||||
(i)*d_fft_size;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < (int)d_folding_factor; i++)
|
||||
{
|
||||
|
||||
/*Copy a signal of 1 code length into suggested buffer.
|
||||
The copied signal must have doppler effect corrected*/
|
||||
memcpy(in_1code,&in_temp[d_possible_delay[i]],
|
||||
sizeof(gr_complex)*(d_samples_per_code));
|
||||
|
||||
/*Perform multiplication of the unmodified local
|
||||
generated code with the incoming signal with doppler
|
||||
effect corrected and accumulates its value. This
|
||||
is indeed correlation in time for an specific value
|
||||
of a shift*/
|
||||
volk_32fc_x2_multiply_32fc_a(corr_output, in_1code,
|
||||
d_code, d_samples_per_code);
|
||||
|
||||
for(int j=0; j < (d_samples_per_code); j++)
|
||||
{
|
||||
complex_acumulator[i] += (corr_output[j]);
|
||||
}
|
||||
|
||||
}
|
||||
/*Obtain maximun value of correlation given the
|
||||
possible delay selected */
|
||||
volk_32fc_magnitude_squared_32f_a(d_corr_output_f,
|
||||
complex_acumulator, d_folding_factor);
|
||||
volk_32f_index_max_16u_a(&indext, d_corr_output_f,
|
||||
d_folding_factor);
|
||||
|
||||
/*Now save the real code phase in the gnss_syncro
|
||||
block for use in other stages*/
|
||||
d_gnss_synchro->Acq_delay_samples = (double)
|
||||
(d_possible_delay[indext]);
|
||||
d_gnss_synchro->Acq_doppler_hz = (double)doppler;
|
||||
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
||||
|
||||
|
||||
/* 5- Compute the test statistics and compare to the threshold
|
||||
d_test_statistics = 2 * d_fft_size * d_mag / d_input_power;*/
|
||||
d_test_statistics = d_mag / d_input_power;
|
||||
//delete complex_acumulator;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Record results to file if required
|
||||
if (d_dump)
|
||||
{
|
||||
/*
|
||||
std::stringstream filename;
|
||||
std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write
|
||||
filename.str("");
|
||||
filename << "../data/test_statistics_" << d_gnss_synchro->System
|
||||
<<"_" << d_gnss_synchro->Signal << "_sat_"
|
||||
<< d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat";
|
||||
d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
|
||||
d_dump_file.write((char*)d_ifft->get_outbuf(), n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
d_dump_file.close();
|
||||
*/
|
||||
/*Since QuickSYnc performs a folded correlation in frequency by means
|
||||
of the FFT, it is esential to also keep the values obtained from the
|
||||
possible delay to show how it is maximize*/
|
||||
std::stringstream filename;
|
||||
std::streamsize n = sizeof(float) * (d_fft_size); // complex file write
|
||||
filename.str("");
|
||||
filename << "../data/test_statistics_" << d_gnss_synchro->System
|
||||
<<"_" << d_gnss_synchro->Signal << "_sat_"
|
||||
<< d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat";
|
||||
d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
|
||||
d_dump_file.write((char*)d_magnitude_folded, n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
d_dump_file.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (!d_bit_transition_flag)
|
||||
{
|
||||
if (d_test_statistics > d_threshold)
|
||||
{
|
||||
d_state = 2; // Positive acquisition
|
||||
|
||||
}
|
||||
else if (d_well_count == d_max_dwells)
|
||||
{
|
||||
d_state = 3; // Negative acquisition
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d_well_count == d_max_dwells) // d_max_dwells = 2
|
||||
{
|
||||
if (d_test_statistics > d_threshold)
|
||||
{
|
||||
d_state = 2; // Positive acquisition
|
||||
}
|
||||
else
|
||||
{
|
||||
d_state = 3; // Negative acquisition
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
consume_each(1);
|
||||
|
||||
delete d_code_folded;
|
||||
d_code_folded = NULL;
|
||||
|
||||
free(in_temp);
|
||||
free(in_1code);
|
||||
free(corr_output);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
//DLOG(INFO) << "START CASE 2";
|
||||
// 6.1- Declare positive acquisition using a message queue
|
||||
DLOG(INFO) << "positive acquisition";
|
||||
DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
|
||||
DLOG(INFO) << "sample_stamp " << d_sample_counter;
|
||||
DLOG(INFO) << "test statistics value " << d_test_statistics;
|
||||
DLOG(INFO) << "test statistics threshold " << d_threshold;
|
||||
DLOG(INFO) << "folding factor " << d_folding_factor;
|
||||
DLOG(INFO) << "possible delay correlation output";
|
||||
for (int i = 0; i < (int)d_folding_factor; i++) DLOG(INFO) << d_possible_delay[i] <<"\t\t\t"<<d_corr_output_f[i];
|
||||
DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
|
||||
DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
|
||||
DLOG(INFO) << "magnitude folded " << d_mag;
|
||||
DLOG(INFO) << "input signal power " << d_input_power;
|
||||
|
||||
d_active = false;
|
||||
d_state = 0;
|
||||
|
||||
d_sample_counter += d_sampled_ms * d_samples_per_ms * ninput_items[0]; // sample counter
|
||||
consume_each(ninput_items[0]);
|
||||
|
||||
acquisition_message = 1;
|
||||
d_channel_internal_queue->push(acquisition_message);
|
||||
//DLOG(INFO) << "END CASE 2";
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
//DLOG(INFO) << "START CASE 3";
|
||||
// 6.2- Declare negative acquisition using a message queue
|
||||
DLOG(INFO) << "negative acquisition";
|
||||
DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
|
||||
DLOG(INFO) << "sample_stamp " << d_sample_counter;
|
||||
DLOG(INFO) << "test statistics value " << d_test_statistics;
|
||||
DLOG(INFO) << "test statistics threshold " << d_threshold;
|
||||
DLOG(INFO) << "folding factor "<<d_folding_factor;
|
||||
DLOG(INFO) << "possible delay corr output";
|
||||
for (int i = 0; i < (int)d_folding_factor; i++) DLOG(INFO) << d_possible_delay[i] <<"\t\t\t"<<d_corr_output_f[i];
|
||||
DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
|
||||
DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
|
||||
DLOG(INFO) << "magnitude folded " << d_mag;
|
||||
DLOG(INFO) << "input signal power " << d_input_power;
|
||||
|
||||
d_active = false;
|
||||
d_state = 0;
|
||||
|
||||
d_sample_counter += d_sampled_ms * d_samples_per_ms * ninput_items[0]; // sample counter
|
||||
consume_each(ninput_items[0]);
|
||||
|
||||
acquisition_message = 2;
|
||||
d_channel_internal_queue->push(acquisition_message);
|
||||
//DLOG(INFO) << "END CASE 3";
|
||||
break;
|
||||
}
|
||||
}
|
||||
//DLOG(INFO) << "END GENERAL WORK";
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,260 @@
|
||||
/*!
|
||||
* \file pcps_quicksync_acquisition_cc.h
|
||||
* \brief This class implements a Parallel Code Phase Search Acquisition with the
|
||||
* QuickSync Algorithm
|
||||
*
|
||||
* Acquisition strategy (Kay Borre book CFAR + threshold).
|
||||
* <ol>
|
||||
* <li> Compute the input signal power estimation
|
||||
* <li> Doppler serial search loop
|
||||
* <li> Perform folding of the incoming signal and local generated code
|
||||
* <li> Perform the FFT-based circular convolution (parallel time search)
|
||||
* <li> Record the maximum peak and the associated synchronization parameters
|
||||
* <li> Compute the test statistics and compare to the threshold
|
||||
* <li> Declare positive or negative acquisition using a message queue
|
||||
* <li> Obtain the adequate acquisition parameters by correlating the incoming
|
||||
* signal shifted by the possible folded delays
|
||||
* </ol>
|
||||
*
|
||||
* Kay Borre book: K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
|
||||
* "A Software-Defined GPS and Galileo Receiver. A Single-Frequency
|
||||
* Approach", Birkha user, 2007. pp 81-84
|
||||
*
|
||||
* \date Jun2 2014
|
||||
* \author Damian Miralles Sanchez, dmiralles2009@gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_PCPS_QUICKSYNC_ACQUISITION_CC_H_
|
||||
#define GNSS_SDR_PCPS_QUICKSYNC_ACQUISITION_CC_H_
|
||||
|
||||
#include <fstream>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <assert.h>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/gr_complex.h>
|
||||
#include <gnuradio/fft/fft.h>
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_synchro.h"
|
||||
|
||||
class pcps_quicksync_acquisition_cc;
|
||||
|
||||
typedef boost::shared_ptr<pcps_quicksync_acquisition_cc>
|
||||
pcps_quicksync_acquisition_cc_sptr;
|
||||
|
||||
pcps_quicksync_acquisition_cc_sptr
|
||||
pcps_quicksync_make_acquisition_cc(unsigned int folding_factor,
|
||||
unsigned int sampled_ms, unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag,
|
||||
gr::msg_queue::sptr queue, bool dump,
|
||||
std::string dump_filename);
|
||||
|
||||
/*!
|
||||
* \brief This class implements a Parallel Code Phase Search Acquisition with
|
||||
* the implementation of the Sparse QuickSync Algorithm.
|
||||
*
|
||||
* Check \ref Navitec2012 "Faster GPS via the Sparse Fourier Transform",
|
||||
* for details of its implementation and functionality.
|
||||
*/
|
||||
class pcps_quicksync_acquisition_cc: public gr::block
|
||||
{
|
||||
private:
|
||||
friend pcps_quicksync_acquisition_cc_sptr
|
||||
pcps_quicksync_make_acquisition_cc(unsigned int folding_factor,
|
||||
unsigned int sampled_ms, unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag,
|
||||
gr::msg_queue::sptr queue, bool dump,
|
||||
std::string dump_filename);
|
||||
|
||||
pcps_quicksync_acquisition_cc(unsigned int folding_factor,
|
||||
unsigned int sampled_ms, unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag,
|
||||
gr::msg_queue::sptr queue, bool dump,
|
||||
std::string dump_filename);
|
||||
|
||||
void calculate_magnitudes(gr_complex* fft_begin, int doppler_shift,
|
||||
int doppler_offset);
|
||||
|
||||
gr_complex* d_code;
|
||||
unsigned int d_folding_factor; // also referred in the paper as 'p'
|
||||
float * d_corr_acumulator;
|
||||
unsigned int *d_possible_delay;
|
||||
float *d_corr_output_f;
|
||||
float * d_magnitude_folded;
|
||||
gr_complex *d_signal_folded;
|
||||
gr_complex *d_code_folded;
|
||||
float d_noise_floor_power;
|
||||
|
||||
long d_fs_in;
|
||||
long d_freq;
|
||||
int d_samples_per_ms;
|
||||
int d_samples_per_code;
|
||||
unsigned int d_doppler_resolution;
|
||||
float d_threshold;
|
||||
std::string d_satellite_str;
|
||||
unsigned int d_doppler_max;
|
||||
unsigned int d_doppler_step;
|
||||
unsigned int d_sampled_ms;
|
||||
unsigned int d_max_dwells;
|
||||
unsigned int d_well_count;
|
||||
unsigned int d_fft_size;
|
||||
unsigned long int d_sample_counter;
|
||||
gr_complex** d_grid_doppler_wipeoffs;
|
||||
unsigned int d_num_doppler_bins;
|
||||
gr_complex* d_fft_codes;
|
||||
gr::fft::fft_complex* d_fft_if;
|
||||
gr::fft::fft_complex* d_fft_if2;
|
||||
gr::fft::fft_complex* d_ifft;
|
||||
Gnss_Synchro *d_gnss_synchro;
|
||||
unsigned int d_code_phase;
|
||||
float d_doppler_freq;
|
||||
float d_mag;
|
||||
float* d_magnitude;
|
||||
float d_input_power;
|
||||
float d_test_statistics;
|
||||
bool d_bit_transition_flag;
|
||||
gr::msg_queue::sptr d_queue;
|
||||
concurrent_queue<int> *d_channel_internal_queue;
|
||||
std::ofstream d_dump_file;
|
||||
bool d_active;
|
||||
int d_state;
|
||||
bool d_dump;
|
||||
unsigned int d_channel;
|
||||
std::string d_dump_filename;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Default destructor.
|
||||
*/
|
||||
~pcps_quicksync_acquisition_cc();
|
||||
|
||||
/*!
|
||||
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
|
||||
* to exchange synchronization data between acquisition and tracking blocks.
|
||||
* \param p_gnss_synchro Satellite information shared by the processing blocks.
|
||||
*/
|
||||
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
|
||||
{
|
||||
d_gnss_synchro = p_gnss_synchro;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the maximum peak of grid search.
|
||||
*/
|
||||
unsigned int mag()
|
||||
{
|
||||
return d_mag;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Initializes acquisition algorithm.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/*!
|
||||
* \brief Sets local code for PCPS acquisition algorithm.
|
||||
* \param code - Pointer to the PRN code.
|
||||
*/
|
||||
void set_local_code(std::complex<float> * code);
|
||||
|
||||
/*!
|
||||
* \brief Starts acquisition algorithm, turning from standby mode to
|
||||
* active mode
|
||||
* \param active - bool that activates/deactivates the block.
|
||||
*/
|
||||
void set_active(bool active)
|
||||
{
|
||||
d_active = active;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Set acquisition channel unique ID
|
||||
* \param channel - receiver channel.
|
||||
*/
|
||||
void set_channel(unsigned int channel)
|
||||
{
|
||||
d_channel = channel;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Set statistics threshold of PCPS algorithm.
|
||||
* \param threshold - Threshold for signal detection (check \ref Navitec2012,
|
||||
* Algorithm 1, for a definition of this threshold).
|
||||
*/
|
||||
void set_threshold(float threshold)
|
||||
{
|
||||
d_threshold = threshold;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Set maximum Doppler grid search
|
||||
* \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
|
||||
*/
|
||||
void set_doppler_max(unsigned int doppler_max)
|
||||
{
|
||||
d_doppler_max = doppler_max;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Set Doppler steps for the grid search
|
||||
* \param doppler_step - Frequency bin of the search grid [Hz].
|
||||
*/
|
||||
void set_doppler_step(unsigned int doppler_step)
|
||||
{
|
||||
d_doppler_step = doppler_step;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Set tracking channel internal queue.
|
||||
* \param channel_internal_queue - Channel's internal blocks information queue.
|
||||
*/
|
||||
void set_channel_queue(concurrent_queue<int> *channel_internal_queue)
|
||||
{
|
||||
d_channel_internal_queue = channel_internal_queue;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Parallel Code Phase Search Acquisition signal processing.
|
||||
*/
|
||||
int general_work(int noutput_items, gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items);
|
||||
};
|
||||
|
||||
#endif /* GNSS_SDR_PCPS_ACQUISITION_CC_H_*/
|
@ -68,26 +68,26 @@ Channel::Channel(ConfigurationInterface *configuration, unsigned int channel,
|
||||
|
||||
// IMPORTANT: Do not change the order between set_doppler_max, set_doppler_step and set_threshold
|
||||
|
||||
unsigned int doppler_max = configuration->property("Acquisition" + boost::lexical_cast<std::string>(channel_) + ".doppler_max", 0);
|
||||
if(doppler_max == 0) doppler_max = configuration->property("Acquisition.doppler_max", 0);
|
||||
unsigned int doppler_max = configuration->property("Acquisition_"+implementation_ + boost::lexical_cast<std::string>(channel_) + ".doppler_max", 0);
|
||||
if(doppler_max == 0) doppler_max = configuration->property("Acquisition_"+implementation_+".doppler_max", 0);
|
||||
DLOG(INFO) << "Channel "<< channel_ << " Doppler_max = " << doppler_max;
|
||||
|
||||
acq_->set_doppler_max(doppler_max);
|
||||
|
||||
unsigned int doppler_step = configuration->property("Acquisition" + boost::lexical_cast<std::string>(channel_) + ".doppler_step" ,0);
|
||||
if(doppler_step == 0) doppler_step = configuration->property("Acquisition.doppler_step", 500);
|
||||
unsigned int doppler_step = configuration->property("Acquisition_"+implementation_ + boost::lexical_cast<std::string>(channel_) + ".doppler_step" ,0);
|
||||
if(doppler_step == 0) doppler_step = configuration->property("Acquisition_"+implementation_+".doppler_step", 500);
|
||||
DLOG(INFO) << "Channel "<< channel_ << " Doppler_step = " << doppler_step;
|
||||
|
||||
acq_->set_doppler_step(doppler_step);
|
||||
|
||||
float threshold = configuration->property("Acquisition" + boost::lexical_cast<std::string>(channel_) + ".threshold", 0.0);
|
||||
if(threshold == 0.0) threshold = configuration->property("Acquisition.threshold", 0.0);
|
||||
float threshold = configuration->property("Acquisition_"+implementation_+ boost::lexical_cast<std::string>(channel_) + ".threshold", 0.0);
|
||||
if(threshold == 0.0) threshold = configuration->property("Acquisition_"+implementation_+".threshold", 0.0);
|
||||
|
||||
acq_->set_threshold(threshold);
|
||||
|
||||
acq_->init();
|
||||
|
||||
repeat_ = configuration->property("Acquisition" + boost::lexical_cast<std::string>(channel_) + ".repeat_satellite", false);
|
||||
repeat_ = configuration->property("Acquisition_"+implementation_+ boost::lexical_cast<std::string>(channel_) + ".repeat_satellite", false);
|
||||
DLOG(INFO) << "Channel " << channel_ << " satellite repeat = " << repeat_;
|
||||
|
||||
acq_->set_channel_queue(&channel_internal_queue_);
|
||||
|
@ -74,7 +74,7 @@ public:
|
||||
std::string role(){ return role_; }
|
||||
|
||||
//! Returns "Channel"
|
||||
std::string implementation(){ return "Channel"; }
|
||||
std::string implementation(){ return implementation_; }
|
||||
size_t item_size(){ return 0; }
|
||||
Gnss_Signal get_signal() const { return gnss_signal_; }
|
||||
AcquisitionInterface* acquisition(){ return acq_; }
|
||||
|
@ -27,6 +27,7 @@ if(OPENCL_FOUND)
|
||||
fft_execute.cc # Needs OpenCL
|
||||
fft_setup.cc # Needs OpenCL
|
||||
fft_kernelstring.cc # Needs OpenCL
|
||||
galileo_e5_signal_processing.cc
|
||||
)
|
||||
else(OPENCL_FOUND)
|
||||
set(GNSS_SPLIBS_SOURCES
|
||||
@ -36,6 +37,7 @@ else(OPENCL_FOUND)
|
||||
gps_sdr_signal_processing.cc
|
||||
nco_lib.cc
|
||||
pass_through.cc
|
||||
galileo_e5_signal_processing.cc
|
||||
)
|
||||
endif(OPENCL_FOUND)
|
||||
|
||||
|
145
src/algorithms/libs/galileo_e5_signal_processing.cc
Normal file
145
src/algorithms/libs/galileo_e5_signal_processing.cc
Normal file
@ -0,0 +1,145 @@
|
||||
/*!
|
||||
* \file galileo_e5_signal_processing.cc
|
||||
* \brief This library implements various functions for Galileo E5 signals such
|
||||
* as replica code generation
|
||||
* \author Marc Sales, 2014. marcsales92(at)gmail.com
|
||||
*
|
||||
* Detailed description of the file here if needed.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "galileo_e5_signal_processing.h"
|
||||
|
||||
void galileo_e5_a_code_gen_complex_primary(std::complex<float>* _dest, signed int _prn, char _Signal[3])
|
||||
{
|
||||
unsigned int prn=_prn-1;
|
||||
unsigned int index=0;
|
||||
int a[4];
|
||||
if ((_prn < 1) || (_prn > 50))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_Signal[0]=='5' && _Signal[1]=='Q')
|
||||
{
|
||||
for (size_t i = 0; i < Galileo_E5a_Q_PRIMARY_CODE[prn].length()-1; i++)
|
||||
{
|
||||
hex_to_binary_converter(a,
|
||||
Galileo_E5a_Q_PRIMARY_CODE[prn].at(i));
|
||||
_dest[index]=std::complex<float>(0.0,float(a[0]));
|
||||
_dest[index+1]=std::complex<float>(0.0,float(a[1]));
|
||||
_dest[index+2]=std::complex<float>(0.0,float(a[2]));
|
||||
_dest[index+3]=std::complex<float>(0.0,float(a[3]));
|
||||
index = index + 4;
|
||||
}
|
||||
// last 2 bits are filled up zeros
|
||||
hex_to_binary_converter(a,
|
||||
Galileo_E5a_Q_PRIMARY_CODE[prn].at(Galileo_E5a_Q_PRIMARY_CODE[prn].length()-1));
|
||||
_dest[index]=std::complex<float>(float(0.0),a[0]);
|
||||
_dest[index+1]=std::complex<float>(float(0.0),a[1]);
|
||||
}
|
||||
else if (_Signal[0]=='5' && _Signal[1]=='I')
|
||||
{
|
||||
for (size_t i = 0; i < Galileo_E5a_I_PRIMARY_CODE[prn].length()-1; i++)
|
||||
{
|
||||
hex_to_binary_converter(a,
|
||||
Galileo_E5a_I_PRIMARY_CODE[prn].at(i));
|
||||
_dest[index]=std::complex<float>(float(a[0]),0.0);
|
||||
_dest[index+1]=std::complex<float>(float(a[1]),0.0);
|
||||
_dest[index+2]=std::complex<float>(float(a[2]),0.0);
|
||||
_dest[index+3]=std::complex<float>(float(a[3]),0.0);
|
||||
index = index + 4;
|
||||
}
|
||||
// last 2 bits are filled up zeros
|
||||
hex_to_binary_converter(a,
|
||||
Galileo_E5a_I_PRIMARY_CODE[prn].at(Galileo_E5a_I_PRIMARY_CODE[prn].length()-1));
|
||||
_dest[index]=std::complex<float>(float(a[0]),0.0);
|
||||
_dest[index+1]=std::complex<float>(float(a[1]),0.0);
|
||||
}
|
||||
else if (_Signal[0]=='5' && _Signal[1]=='X')
|
||||
{
|
||||
int b[4];
|
||||
for (size_t i = 0; i < Galileo_E5a_I_PRIMARY_CODE[prn].length()-1; i++)
|
||||
{
|
||||
hex_to_binary_converter(a,
|
||||
Galileo_E5a_I_PRIMARY_CODE[prn].at(i));
|
||||
hex_to_binary_converter(b,
|
||||
Galileo_E5a_Q_PRIMARY_CODE[prn].at(i));
|
||||
_dest[index]=std::complex<float>(float(a[0]),float(b[0]));
|
||||
_dest[index+1]=std::complex<float>(float(a[1]),float(b[1]));
|
||||
_dest[index+2]=std::complex<float>(float(a[2]),float(b[2]));
|
||||
_dest[index+3]=std::complex<float>(float(a[3]),float(b[3]));
|
||||
index = index + 4;
|
||||
}
|
||||
// last 2 bits are filled up zeros
|
||||
hex_to_binary_converter(a,
|
||||
Galileo_E5a_I_PRIMARY_CODE[prn].at(Galileo_E5a_I_PRIMARY_CODE[prn].length()-1));
|
||||
hex_to_binary_converter(b,
|
||||
Galileo_E5a_Q_PRIMARY_CODE[prn].at(Galileo_E5a_Q_PRIMARY_CODE[prn].length()-1));
|
||||
_dest[index]=std::complex<float>(float(a[0]),float(b[0]));
|
||||
_dest[index+1]=std::complex<float>(float(a[1]),float(b[1]));
|
||||
}
|
||||
}
|
||||
|
||||
void galileo_e5_a_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3],
|
||||
unsigned int _prn, signed int _fs, unsigned int _chip_shift)
|
||||
{
|
||||
// This function is based on the GNU software GPS for MATLAB in the Kay Borre book
|
||||
|
||||
unsigned int _samplesPerCode;
|
||||
unsigned int delay;
|
||||
unsigned int _codeLength = Galileo_E5a_CODE_LENGTH_CHIPS;
|
||||
const int _codeFreqBasis = Galileo_E5a_CODE_CHIP_RATE_HZ; //Hz
|
||||
|
||||
|
||||
std::complex<float>* _code;
|
||||
_code=new std::complex<float>[_codeLength];
|
||||
|
||||
galileo_e5_a_code_gen_complex_primary(_code , _prn , _Signal);
|
||||
|
||||
_samplesPerCode = round(_fs / (_codeFreqBasis / _codeLength));
|
||||
|
||||
delay = ((_codeLength - _chip_shift)
|
||||
% _codeLength) * _samplesPerCode / _codeLength;
|
||||
|
||||
|
||||
if (_fs != _codeFreqBasis)
|
||||
{
|
||||
std::complex<float>* _resampled_signal;
|
||||
if (posix_memalign((void**)&_resampled_signal, 16, _samplesPerCode * sizeof(gr_complex)) == 0){};
|
||||
resampler(_code, _resampled_signal, _codeFreqBasis, _fs,
|
||||
_codeLength, _samplesPerCode); //resamples code to fs
|
||||
delete[] _code;
|
||||
_code = _resampled_signal;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < _samplesPerCode; i++)
|
||||
{
|
||||
_dest[(i+delay)%_samplesPerCode] = _code[i];
|
||||
}
|
||||
|
||||
free(_code);
|
||||
|
||||
}
|
60
src/algorithms/libs/galileo_e5_signal_processing.h
Normal file
60
src/algorithms/libs/galileo_e5_signal_processing.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*!
|
||||
* \file galileo_e5_signal_processing.cc
|
||||
* \brief This library implements various functions for Galileo E5 signals such
|
||||
* as replica code generation
|
||||
* \author Marc Sales, 2014. marcsales92(at)gmail.com
|
||||
*
|
||||
* Detailed description of the file here if needed.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_GALILEO_E5_SIGNAL_PROCESSING_H_
|
||||
#define GNSS_SDR_GALILEO_E5_SIGNAL_PROCESSING_H_
|
||||
|
||||
#include <complex>
|
||||
#include <iostream>
|
||||
#include <gnuradio/math.h>
|
||||
#include "Galileo_E5a.h"
|
||||
#include "gnss_signal_processing.h"
|
||||
|
||||
/*!
|
||||
* \brief Generates Galileo E5a code at 1 sample/chip
|
||||
* bool _pilot generates E5aQ code if true and E5aI (data signal) if false.
|
||||
*/
|
||||
void galileo_e5_a_code_gen_complex_primary(std::complex<float>* _dest, signed int _prn, char _Signal[3]);
|
||||
|
||||
|
||||
void galileo_e5_a_code_gen_tiered(std::complex<float>* _dest,std::complex<float>* _primary ,unsigned int _prn, char _Signal[3]);
|
||||
|
||||
/*!
|
||||
* \brief Generates Galileo E5a complex code, shifted to the desired chip and sampled at a frequency fs
|
||||
* bool _pilot generates E5aQ code if true and E5aI (data signal) if false.
|
||||
*/
|
||||
void galileo_e5_a_code_gen_complex_sampled(std::complex<float>* _dest,
|
||||
char _Signal[3], unsigned int _prn, signed int _fs, unsigned int _chip_shift);
|
||||
|
||||
|
||||
#endif /* GNSS_SDR_GALILEO_E5_SIGNAL_PROCESSING_H_ */
|
@ -180,20 +180,14 @@ void resampler(std::complex<float>* _from, std::complex<float>* _dest, float _fs
|
||||
//--- Find time constants --------------------------------------------------
|
||||
const float _t_in = 1/_fs_in; // Incoming sampling period in sec
|
||||
const float _t_out = 1/_fs_out; // Out sampling period in sec
|
||||
for (unsigned int i=0; i<_length_out; i++)
|
||||
for (unsigned int i=0; i<_length_out-1; i++)
|
||||
{
|
||||
//=== Digitizing =======================================================
|
||||
//--- compute index array to read sampled values -------------------------
|
||||
_codeValueIndex = ceil((_t_out * ((float)i + 1)) / _t_in) - 1;
|
||||
if (i == _length_out - 1)
|
||||
{
|
||||
//--- Correct the last index (due to number rounding issues) -----------
|
||||
_dest[i] = _from[_length_in - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
//if repeat the chip -> upsample by nearest neighborhood interpolation
|
||||
_dest[i] = _from[_codeValueIndex];
|
||||
}
|
||||
//if repeat the chip -> upsample by nearest neighborhood interpolation
|
||||
_dest[i] = _from[_codeValueIndex];
|
||||
}
|
||||
//--- Correct the last index (due to number rounding issues) -----------
|
||||
_dest[_length_out-1] = _from[_length_in - 1];
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
|
||||
* Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
|
||||
*
|
||||
* GNSS-SDR is a software defined Global Navigation
|
||||
* Satellite Systems receiver
|
||||
@ -19,7 +19,7 @@
|
||||
* 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.
|
||||
* (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
|
||||
@ -35,56 +35,6 @@
|
||||
#include "nco_lib.h"
|
||||
|
||||
|
||||
typedef ALIGN16_BEG union {
|
||||
float f[4];
|
||||
int i[4];
|
||||
v4sf v;
|
||||
} ALIGN16_END V4SF;
|
||||
|
||||
void sse_nco(std::complex<float> *dest, int n_samples, float start_phase_rad, float phase_step_rad)
|
||||
{
|
||||
//SSE NCO
|
||||
int sse_loops_four_op;
|
||||
int remnant_ops;
|
||||
sse_loops_four_op = (int)n_samples/4;
|
||||
remnant_ops = n_samples%4;
|
||||
V4SF vx, sin4, cos4;
|
||||
float phase_rad;
|
||||
phase_rad = start_phase_rad;
|
||||
|
||||
int index = 0;
|
||||
for(int i = 0;i<sse_loops_four_op;i++)
|
||||
{
|
||||
vx.f[0] = phase_rad;
|
||||
phase_rad = phase_rad+phase_step_rad;
|
||||
vx.f[1] = phase_rad;
|
||||
phase_rad = phase_rad+phase_step_rad;
|
||||
vx.f[2] = phase_rad;
|
||||
phase_rad = phase_rad+phase_step_rad;
|
||||
vx.f[3] = phase_rad;
|
||||
phase_rad = phase_rad+phase_step_rad;
|
||||
sincos_ps(vx.v, &sin4.v, &cos4.v);
|
||||
dest[index] = std::complex<float>(cos4.f[0], -sin4.f[0]);
|
||||
index++;
|
||||
dest[index] = std::complex<float>(cos4.f[1], -sin4.f[1]);
|
||||
index++;
|
||||
dest[index] = std::complex<float>(cos4.f[2], -sin4.f[2]);
|
||||
index++;
|
||||
dest[index] = std::complex<float>(cos4.f[3], -sin4.f[3]);
|
||||
index++;
|
||||
}
|
||||
for(int i = 0;i<remnant_ops;i++)
|
||||
{
|
||||
vx.f[i] = phase_rad;
|
||||
phase_rad = phase_rad+phase_step_rad;
|
||||
}
|
||||
sincos_ps(vx.v, &sin4.v, &cos4.v);
|
||||
for(int i = 0;i<remnant_ops;i++)
|
||||
{
|
||||
dest[index] = std::complex<float>(cos4.f[i], -sin4.f[i]);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
void fxp_nco(std::complex<float> *dest, int n_samples, float start_phase_rad, float phase_step_rad)
|
||||
{
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
|
||||
* Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
|
||||
*
|
||||
* GNSS-SDR is a software defined Global Navigation
|
||||
* Satellite Systems receiver
|
||||
@ -19,7 +19,7 @@
|
||||
* 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.
|
||||
* (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
|
||||
@ -37,10 +37,11 @@
|
||||
#ifndef GNSS_SDR_NCO_LIB_CC_H_
|
||||
#define GNSS_SDR_NCO_LIB_CC_H_
|
||||
|
||||
#include <gnuradio/fxpt.h>
|
||||
#include <xmmintrin.h>
|
||||
#include <sse_mathfun.h>
|
||||
#include <cmath>
|
||||
#include <gnuradio/fxpt.h>
|
||||
//#include <xmmintrin.h>
|
||||
//#include <sse_mathfun.h>
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Implements a complex conjugate exponential vector in std::complex<float> *d_carr_sign
|
||||
|
@ -1,776 +0,0 @@
|
||||
/*!
|
||||
* \file sse_mathfun.h
|
||||
* \brief SIMD (SSE1+MMX or SSE2) implementation of sin, cos, exp and log
|
||||
*
|
||||
* The default is to use the SSE1 version. If you define USE_SSE2 the
|
||||
* SSE2 intrinsics will be used in place of the MMX intrinsics. Do
|
||||
* not expect any significant performance improvement with SSE2.
|
||||
* Copyright (C) 2007 Julien Pommier
|
||||
*/
|
||||
|
||||
/* SIMD (SSE1+MMX or SSE2) implementation of sin, cos, exp and log
|
||||
|
||||
Inspired by Intel Approximate Math library, and based on the
|
||||
corresponding algorithms of the cephes math library
|
||||
|
||||
The default is to use the SSE1 version. If you define USE_SSE2 the
|
||||
the SSE2 intrinsics will be used in place of the MMX intrinsics. Do
|
||||
not expect any significant performance improvement with SSE2.
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2007 Julien Pommier
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
(this is the zlib license)
|
||||
*/
|
||||
|
||||
#ifndef SSE_MATHFUN_H
|
||||
#define SSE_MATHFUN_H
|
||||
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#define USE_SSE2
|
||||
/* yes I know, the top of this file is quite ugly */
|
||||
|
||||
#ifdef _MSC_VER /* visual c++ */
|
||||
# define ALIGN16_BEG __declspec(align(16))
|
||||
# define ALIGN16_END
|
||||
#else /* gcc or icc */
|
||||
# define ALIGN16_BEG
|
||||
# define ALIGN16_END __attribute__((aligned(16)))
|
||||
#endif
|
||||
|
||||
/* __m128 is ugly to write */
|
||||
typedef __m128 v4sf; // vector of 4 float (sse1)
|
||||
|
||||
#ifdef USE_SSE2
|
||||
# include <emmintrin.h>
|
||||
typedef __m128i v4si; // vector of 4 int (sse2)
|
||||
#else
|
||||
typedef __m64 v2si; // vector of 2 int (mmx)
|
||||
#endif
|
||||
|
||||
/* declare some SSE constants -- why can't I figure a better way to do that? */
|
||||
#define _PS_CONST(Name, Val) \
|
||||
static const ALIGN16_BEG float _ps_##Name[4] ALIGN16_END = { Val, Val, Val, Val }
|
||||
#define _PI32_CONST(Name, Val) \
|
||||
static const ALIGN16_BEG int _pi32_##Name[4] ALIGN16_END = { Val, Val, Val, Val }
|
||||
#define _PS_CONST_TYPE(Name, Type, Val) \
|
||||
static const ALIGN16_BEG Type _ps_##Name[4] ALIGN16_END = { Val, Val, Val, Val }
|
||||
|
||||
_PS_CONST(1 , 1.0f);
|
||||
_PS_CONST(0p5, 0.5f);
|
||||
/* the smallest non denormalized float number */
|
||||
_PS_CONST_TYPE(min_norm_pos, int, 0x00800000);
|
||||
_PS_CONST_TYPE(mant_mask, int, 0x7f800000);
|
||||
_PS_CONST_TYPE(inv_mant_mask, int, ~0x7f800000);
|
||||
|
||||
_PS_CONST_TYPE(sign_mask, int, 0x80000000);
|
||||
_PS_CONST_TYPE(inv_sign_mask, int, ~0x80000000);
|
||||
|
||||
_PI32_CONST(1, 1);
|
||||
_PI32_CONST(inv1, ~1);
|
||||
_PI32_CONST(2, 2);
|
||||
_PI32_CONST(4, 4);
|
||||
_PI32_CONST(0x7f, 0x7f);
|
||||
|
||||
_PS_CONST(cephes_SQRTHF, 0.707106781186547524);
|
||||
_PS_CONST(cephes_log_p0, 7.0376836292E-2);
|
||||
_PS_CONST(cephes_log_p1, - 1.1514610310E-1);
|
||||
_PS_CONST(cephes_log_p2, 1.1676998740E-1);
|
||||
_PS_CONST(cephes_log_p3, - 1.2420140846E-1);
|
||||
_PS_CONST(cephes_log_p4, + 1.4249322787E-1);
|
||||
_PS_CONST(cephes_log_p5, - 1.6668057665E-1);
|
||||
_PS_CONST(cephes_log_p6, + 2.0000714765E-1);
|
||||
_PS_CONST(cephes_log_p7, - 2.4999993993E-1);
|
||||
_PS_CONST(cephes_log_p8, + 3.3333331174E-1);
|
||||
_PS_CONST(cephes_log_q1, -2.12194440e-4);
|
||||
_PS_CONST(cephes_log_q2, 0.693359375);
|
||||
|
||||
#if defined (__MINGW32__)
|
||||
|
||||
/* the ugly part below: many versions of gcc used to be completely buggy with respect to some intrinsics
|
||||
The movehl_ps is fixed in mingw 3.4.5, but I found out that all the _mm_cmp* intrinsics were completely
|
||||
broken on my mingw gcc 3.4.5 ...
|
||||
|
||||
Note that the bug on _mm_cmp* does occur only at -O0 optimization level
|
||||
*/
|
||||
|
||||
inline __m128 my_movehl_ps(__m128 a, const __m128 b) {
|
||||
asm (
|
||||
"movhlps %2,%0\n\t"
|
||||
: "=x" (a)
|
||||
: "0" (a), "x"(b)
|
||||
);
|
||||
return a; }
|
||||
#warning "redefined _mm_movehl_ps (see gcc bug 21179)"
|
||||
#define _mm_movehl_ps my_movehl_ps
|
||||
|
||||
inline __m128 my_cmplt_ps(__m128 a, const __m128 b) {
|
||||
asm (
|
||||
"cmpltps %2,%0\n\t"
|
||||
: "=x" (a)
|
||||
: "0" (a), "x"(b)
|
||||
);
|
||||
return a;
|
||||
}
|
||||
inline __m128 my_cmpgt_ps(__m128 a, const __m128 b) {
|
||||
asm (
|
||||
"cmpnleps %2,%0\n\t"
|
||||
: "=x" (a)
|
||||
: "0" (a), "x"(b)
|
||||
);
|
||||
return a;
|
||||
}
|
||||
inline __m128 my_cmpeq_ps(__m128 a, const __m128 b) {
|
||||
asm (
|
||||
"cmpeqps %2,%0\n\t"
|
||||
: "=x" (a)
|
||||
: "0" (a), "x"(b)
|
||||
);
|
||||
return a;
|
||||
}
|
||||
#warning "redefined _mm_cmpxx_ps functions..."
|
||||
#define _mm_cmplt_ps my_cmplt_ps
|
||||
#define _mm_cmpgt_ps my_cmpgt_ps
|
||||
#define _mm_cmpeq_ps my_cmpeq_ps
|
||||
#endif
|
||||
|
||||
#ifndef USE_SSE2
|
||||
typedef union xmm_mm_union {
|
||||
__m128 xmm;
|
||||
__m64 mm[2];
|
||||
} xmm_mm_union;
|
||||
|
||||
#define COPY_XMM_TO_MM(xmm_, mm0_, mm1_) { \
|
||||
xmm_mm_union u; u.xmm = xmm_; \
|
||||
mm0_ = u.mm[0]; \
|
||||
mm1_ = u.mm[1]; \
|
||||
}
|
||||
|
||||
#define COPY_MM_TO_XMM(mm0_, mm1_, xmm_) { \
|
||||
xmm_mm_union u; u.mm[0]=mm0_; u.mm[1]=mm1_; xmm_ = u.xmm; \
|
||||
}
|
||||
|
||||
#endif // USE_SSE2
|
||||
|
||||
/* natural logarithm computed for 4 simultaneous float
|
||||
return NaN for x <= 0
|
||||
*/
|
||||
inline v4sf log_ps(v4sf x) {
|
||||
#ifdef USE_SSE2
|
||||
v4si emm0;
|
||||
#else
|
||||
v2si mm0, mm1;
|
||||
#endif
|
||||
v4sf one = *(v4sf*)_ps_1;
|
||||
|
||||
v4sf invalid_mask = _mm_cmple_ps(x, _mm_setzero_ps());
|
||||
|
||||
x = _mm_max_ps(x, *(v4sf*)_ps_min_norm_pos); /* cut off denormalized stuff */
|
||||
|
||||
#ifndef USE_SSE2
|
||||
/* part 1: x = frexpf(x, &e); */
|
||||
COPY_XMM_TO_MM(x, mm0, mm1);
|
||||
mm0 = _mm_srli_pi32(mm0, 23);
|
||||
mm1 = _mm_srli_pi32(mm1, 23);
|
||||
#else
|
||||
emm0 = _mm_srli_epi32(_mm_castps_si128(x), 23);
|
||||
#endif
|
||||
/* keep only the fractional part */
|
||||
x = _mm_and_ps(x, *(v4sf*)_ps_inv_mant_mask);
|
||||
x = _mm_or_ps(x, *(v4sf*)_ps_0p5);
|
||||
|
||||
#ifndef USE_SSE2
|
||||
/* now e=mm0:mm1 contain the really base-2 exponent */
|
||||
mm0 = _mm_sub_pi32(mm0, *(v2si*)_pi32_0x7f);
|
||||
mm1 = _mm_sub_pi32(mm1, *(v2si*)_pi32_0x7f);
|
||||
v4sf e = _mm_cvtpi32x2_ps(mm0, mm1);
|
||||
_mm_empty(); /* bye bye mmx */
|
||||
#else
|
||||
emm0 = _mm_sub_epi32(emm0, *(v4si*)_pi32_0x7f);
|
||||
v4sf e = _mm_cvtepi32_ps(emm0);
|
||||
#endif
|
||||
|
||||
e = _mm_add_ps(e, one);
|
||||
|
||||
/* part2:
|
||||
if( x < SQRTHF ) {
|
||||
e -= 1;
|
||||
x = x + x - 1.0;
|
||||
} else { x = x - 1.0; }
|
||||
*/
|
||||
v4sf mask = _mm_cmplt_ps(x, *(v4sf*)_ps_cephes_SQRTHF);
|
||||
v4sf tmp = _mm_and_ps(x, mask);
|
||||
x = _mm_sub_ps(x, one);
|
||||
e = _mm_sub_ps(e, _mm_and_ps(one, mask));
|
||||
x = _mm_add_ps(x, tmp);
|
||||
|
||||
|
||||
v4sf z = _mm_mul_ps(x,x);
|
||||
|
||||
v4sf y = *(v4sf*)_ps_cephes_log_p0;
|
||||
y = _mm_mul_ps(y, x);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p1);
|
||||
y = _mm_mul_ps(y, x);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p2);
|
||||
y = _mm_mul_ps(y, x);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p3);
|
||||
y = _mm_mul_ps(y, x);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p4);
|
||||
y = _mm_mul_ps(y, x);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p5);
|
||||
y = _mm_mul_ps(y, x);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p6);
|
||||
y = _mm_mul_ps(y, x);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p7);
|
||||
y = _mm_mul_ps(y, x);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p8);
|
||||
y = _mm_mul_ps(y, x);
|
||||
|
||||
y = _mm_mul_ps(y, z);
|
||||
|
||||
|
||||
tmp = _mm_mul_ps(e, *(v4sf*)_ps_cephes_log_q1);
|
||||
y = _mm_add_ps(y, tmp);
|
||||
|
||||
|
||||
tmp = _mm_mul_ps(z, *(v4sf*)_ps_0p5);
|
||||
y = _mm_sub_ps(y, tmp);
|
||||
|
||||
tmp = _mm_mul_ps(e, *(v4sf*)_ps_cephes_log_q2);
|
||||
x = _mm_add_ps(x, y);
|
||||
x = _mm_add_ps(x, tmp);
|
||||
x = _mm_or_ps(x, invalid_mask); // negative arg will be NAN
|
||||
return x;
|
||||
}
|
||||
|
||||
_PS_CONST(exp_hi, 88.3762626647949f);
|
||||
_PS_CONST(exp_lo, -88.3762626647949f);
|
||||
|
||||
_PS_CONST(cephes_LOG2EF, 1.44269504088896341);
|
||||
_PS_CONST(cephes_exp_C1, 0.693359375);
|
||||
_PS_CONST(cephes_exp_C2, -2.12194440e-4);
|
||||
|
||||
_PS_CONST(cephes_exp_p0, 1.9875691500E-4);
|
||||
_PS_CONST(cephes_exp_p1, 1.3981999507E-3);
|
||||
_PS_CONST(cephes_exp_p2, 8.3334519073E-3);
|
||||
_PS_CONST(cephes_exp_p3, 4.1665795894E-2);
|
||||
_PS_CONST(cephes_exp_p4, 1.6666665459E-1);
|
||||
_PS_CONST(cephes_exp_p5, 5.0000001201E-1);
|
||||
|
||||
inline v4sf exp_ps(v4sf x) {
|
||||
v4sf tmp = _mm_setzero_ps(), fx;
|
||||
#ifdef USE_SSE2
|
||||
v4si emm0;
|
||||
#else
|
||||
v2si mm0, mm1;
|
||||
#endif
|
||||
v4sf one = *(v4sf*)_ps_1;
|
||||
|
||||
x = _mm_min_ps(x, *(v4sf*)_ps_exp_hi);
|
||||
x = _mm_max_ps(x, *(v4sf*)_ps_exp_lo);
|
||||
|
||||
/* express exp(x) as exp(g + n*log(2)) */
|
||||
fx = _mm_mul_ps(x, *(v4sf*)_ps_cephes_LOG2EF);
|
||||
fx = _mm_add_ps(fx, *(v4sf*)_ps_0p5);
|
||||
|
||||
/* how to perform a floorf with SSE: just below */
|
||||
#ifndef USE_SSE2
|
||||
/* step 1 : cast to int */
|
||||
tmp = _mm_movehl_ps(tmp, fx);
|
||||
mm0 = _mm_cvttps_pi32(fx);
|
||||
mm1 = _mm_cvttps_pi32(tmp);
|
||||
/* step 2 : cast back to float */
|
||||
tmp = _mm_cvtpi32x2_ps(mm0, mm1);
|
||||
#else
|
||||
emm0 = _mm_cvttps_epi32(fx);
|
||||
tmp = _mm_cvtepi32_ps(emm0);
|
||||
#endif
|
||||
/* if greater, substract 1 */
|
||||
v4sf mask = _mm_cmpgt_ps(tmp, fx);
|
||||
mask = _mm_and_ps(mask, one);
|
||||
fx = _mm_sub_ps(tmp, mask);
|
||||
|
||||
tmp = _mm_mul_ps(fx, *(v4sf*)_ps_cephes_exp_C1);
|
||||
v4sf z = _mm_mul_ps(fx, *(v4sf*)_ps_cephes_exp_C2);
|
||||
x = _mm_sub_ps(x, tmp);
|
||||
x = _mm_sub_ps(x, z);
|
||||
|
||||
z = _mm_mul_ps(x,x);
|
||||
|
||||
v4sf y = *(v4sf*)_ps_cephes_exp_p0;
|
||||
y = _mm_mul_ps(y, x);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p1);
|
||||
y = _mm_mul_ps(y, x);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p2);
|
||||
y = _mm_mul_ps(y, x);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p3);
|
||||
y = _mm_mul_ps(y, x);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p4);
|
||||
y = _mm_mul_ps(y, x);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p5);
|
||||
y = _mm_mul_ps(y, z);
|
||||
y = _mm_add_ps(y, x);
|
||||
y = _mm_add_ps(y, one);
|
||||
|
||||
/* build 2^n */
|
||||
#ifndef USE_SSE2
|
||||
z = _mm_movehl_ps(z, fx);
|
||||
mm0 = _mm_cvttps_pi32(fx);
|
||||
mm1 = _mm_cvttps_pi32(z);
|
||||
mm0 = _mm_add_pi32(mm0, *(v2si*)_pi32_0x7f);
|
||||
mm1 = _mm_add_pi32(mm1, *(v2si*)_pi32_0x7f);
|
||||
mm0 = _mm_slli_pi32(mm0, 23);
|
||||
mm1 = _mm_slli_pi32(mm1, 23);
|
||||
|
||||
v4sf pow2n;
|
||||
COPY_MM_TO_XMM(mm0, mm1, pow2n);
|
||||
_mm_empty();
|
||||
#else
|
||||
emm0 = _mm_cvttps_epi32(fx);
|
||||
emm0 = _mm_add_epi32(emm0, *(v4si*)_pi32_0x7f);
|
||||
emm0 = _mm_slli_epi32(emm0, 23);
|
||||
v4sf pow2n = _mm_castsi128_ps(emm0);
|
||||
#endif
|
||||
y = _mm_mul_ps(y, pow2n);
|
||||
return y;
|
||||
}
|
||||
|
||||
_PS_CONST(minus_cephes_DP1, -0.78515625);
|
||||
_PS_CONST(minus_cephes_DP2, -2.4187564849853515625e-4);
|
||||
_PS_CONST(minus_cephes_DP3, -3.77489497744594108e-8);
|
||||
_PS_CONST(sincof_p0, -1.9515295891E-4);
|
||||
_PS_CONST(sincof_p1, 8.3321608736E-3);
|
||||
_PS_CONST(sincof_p2, -1.6666654611E-1);
|
||||
_PS_CONST(coscof_p0, 2.443315711809948E-005);
|
||||
_PS_CONST(coscof_p1, -1.388731625493765E-003);
|
||||
_PS_CONST(coscof_p2, 4.166664568298827E-002);
|
||||
_PS_CONST(cephes_FOPI, 1.27323954473516); // 4 / M_PI
|
||||
|
||||
|
||||
/* evaluation of 4 sines at onces, using only SSE1+MMX intrinsics so
|
||||
it runs also on old athlons XPs and the pentium III of your grand
|
||||
mother.
|
||||
|
||||
The code is the exact rewriting of the cephes sinf function.
|
||||
Precision is excellent as long as x < 8192 (I did not bother to
|
||||
take into account the special handling they have for greater values
|
||||
-- it does not return garbage for arguments over 8192, though, but
|
||||
the extra precision is missing).
|
||||
|
||||
Note that it is such that sinf((float)M_PI) = 8.74e-8, which is the
|
||||
surprising but correct result.
|
||||
|
||||
Performance is also surprisingly good, 1.33 times faster than the
|
||||
macos vsinf SSE2 function, and 1.5 times faster than the
|
||||
__vrs4_sinf of amd's ACML (which is only available in 64 bits). Not
|
||||
too bad for an SSE1 function (with no special tuning) !
|
||||
However the latter libraries probably have a much better handling of NaN,
|
||||
Inf, denormalized and other special arguments..
|
||||
|
||||
On my core 1 duo, the execution of this function takes approximately 95 cycles.
|
||||
|
||||
From what I have observed on the experiments with Intel AMath lib, switching to an
|
||||
SSE2 version would improve the perf by only 10%.
|
||||
|
||||
Since it is based on SSE intrinsics, it has to be compiled at -O2 to
|
||||
deliver full speed.
|
||||
*/
|
||||
inline v4sf sin_ps(v4sf x) { // any x
|
||||
v4sf xmm1, xmm2 = _mm_setzero_ps(), xmm3, sign_bit, y;
|
||||
|
||||
#ifdef USE_SSE2
|
||||
v4si emm0, emm2;
|
||||
#else
|
||||
v2si mm0, mm1, mm2, mm3;
|
||||
#endif
|
||||
sign_bit = x;
|
||||
/* take the absolute value */
|
||||
x = _mm_and_ps(x, *(v4sf*)_ps_inv_sign_mask);
|
||||
/* extract the sign bit (upper one) */
|
||||
sign_bit = _mm_and_ps(sign_bit, *(v4sf*)_ps_sign_mask);
|
||||
|
||||
/* scale by 4/Pi */
|
||||
y = _mm_mul_ps(x, *(v4sf*)_ps_cephes_FOPI);
|
||||
|
||||
//printf("plop:"); print4(y);
|
||||
#ifdef USE_SSE2
|
||||
/* store the integer part of y in mm0 */
|
||||
emm2 = _mm_cvttps_epi32(y);
|
||||
/* j=(j+1) & (~1) (see the cephes sources) */
|
||||
emm2 = _mm_add_epi32(emm2, *(v4si*)_pi32_1);
|
||||
emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_inv1);
|
||||
y = _mm_cvtepi32_ps(emm2);
|
||||
/* get the swap sign flag */
|
||||
emm0 = _mm_and_si128(emm2, *(v4si*)_pi32_4);
|
||||
emm0 = _mm_slli_epi32(emm0, 29);
|
||||
/* get the polynom selection mask
|
||||
there is one polynom for 0 <= x <= Pi/4
|
||||
and another one for Pi/4<x<=Pi/2
|
||||
|
||||
Both branches will be computed.
|
||||
*/
|
||||
emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_2);
|
||||
emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128());
|
||||
|
||||
v4sf swap_sign_bit = _mm_castsi128_ps(emm0);
|
||||
v4sf poly_mask = _mm_castsi128_ps(emm2);
|
||||
sign_bit = _mm_xor_ps(sign_bit, swap_sign_bit);
|
||||
#else
|
||||
/* store the integer part of y in mm0:mm1 */
|
||||
xmm2 = _mm_movehl_ps(xmm2, y);
|
||||
mm2 = _mm_cvttps_pi32(y);
|
||||
mm3 = _mm_cvttps_pi32(xmm2);
|
||||
/* j=(j+1) & (~1) (see the cephes sources) */
|
||||
mm2 = _mm_add_pi32(mm2, *(v2si*)_pi32_1);
|
||||
mm3 = _mm_add_pi32(mm3, *(v2si*)_pi32_1);
|
||||
mm2 = _mm_and_si64(mm2, *(v2si*)_pi32_inv1);
|
||||
mm3 = _mm_and_si64(mm3, *(v2si*)_pi32_inv1);
|
||||
y = _mm_cvtpi32x2_ps(mm2, mm3);
|
||||
/* get the swap sign flag */
|
||||
mm0 = _mm_and_si64(mm2, *(v2si*)_pi32_4);
|
||||
mm1 = _mm_and_si64(mm3, *(v2si*)_pi32_4);
|
||||
mm0 = _mm_slli_pi32(mm0, 29);
|
||||
mm1 = _mm_slli_pi32(mm1, 29);
|
||||
/* get the polynom selection mask */
|
||||
mm2 = _mm_and_si64(mm2, *(v2si*)_pi32_2);
|
||||
mm3 = _mm_and_si64(mm3, *(v2si*)_pi32_2);
|
||||
mm2 = _mm_cmpeq_pi32(mm2, _mm_setzero_si64());
|
||||
mm3 = _mm_cmpeq_pi32(mm3, _mm_setzero_si64());
|
||||
v4sf swap_sign_bit, poly_mask;
|
||||
COPY_MM_TO_XMM(mm0, mm1, swap_sign_bit);
|
||||
COPY_MM_TO_XMM(mm2, mm3, poly_mask);
|
||||
sign_bit = _mm_xor_ps(sign_bit, swap_sign_bit);
|
||||
_mm_empty(); /* good-bye mmx */
|
||||
#endif
|
||||
|
||||
/* The magic pass: "Extended precision modular arithmetic"
|
||||
x = ((x - y * DP1) - y * DP2) - y * DP3; */
|
||||
xmm1 = *(v4sf*)_ps_minus_cephes_DP1;
|
||||
xmm2 = *(v4sf*)_ps_minus_cephes_DP2;
|
||||
xmm3 = *(v4sf*)_ps_minus_cephes_DP3;
|
||||
xmm1 = _mm_mul_ps(y, xmm1);
|
||||
xmm2 = _mm_mul_ps(y, xmm2);
|
||||
xmm3 = _mm_mul_ps(y, xmm3);
|
||||
x = _mm_add_ps(x, xmm1);
|
||||
x = _mm_add_ps(x, xmm2);
|
||||
x = _mm_add_ps(x, xmm3);
|
||||
|
||||
/* Evaluate the first polynom (0 <= x <= Pi/4) */
|
||||
y = *(v4sf*)_ps_coscof_p0;
|
||||
v4sf z = _mm_mul_ps(x,x);
|
||||
|
||||
y = _mm_mul_ps(y, z);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_coscof_p1);
|
||||
y = _mm_mul_ps(y, z);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_coscof_p2);
|
||||
y = _mm_mul_ps(y, z);
|
||||
y = _mm_mul_ps(y, z);
|
||||
v4sf tmp = _mm_mul_ps(z, *(v4sf*)_ps_0p5);
|
||||
y = _mm_sub_ps(y, tmp);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_1);
|
||||
|
||||
/* Evaluate the second polynom (Pi/4 <= x <= 0) */
|
||||
|
||||
v4sf y2 = *(v4sf*)_ps_sincof_p0;
|
||||
y2 = _mm_mul_ps(y2, z);
|
||||
y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p1);
|
||||
y2 = _mm_mul_ps(y2, z);
|
||||
y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p2);
|
||||
y2 = _mm_mul_ps(y2, z);
|
||||
y2 = _mm_mul_ps(y2, x);
|
||||
y2 = _mm_add_ps(y2, x);
|
||||
|
||||
/* select the correct result from the two polynoms */
|
||||
xmm3 = poly_mask;
|
||||
y2 = _mm_and_ps(xmm3, y2); //, xmm3);
|
||||
y = _mm_andnot_ps(xmm3, y);
|
||||
y = _mm_add_ps(y,y2);
|
||||
/* update the sign */
|
||||
y = _mm_xor_ps(y, sign_bit);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/* almost the same as sin_ps */
|
||||
inline v4sf cos_ps(v4sf x) { // any x
|
||||
v4sf xmm1, xmm2 = _mm_setzero_ps(), xmm3, y;
|
||||
#ifdef USE_SSE2
|
||||
v4si emm0, emm2;
|
||||
#else
|
||||
v2si mm0, mm1, mm2, mm3;
|
||||
#endif
|
||||
/* take the absolute value */
|
||||
x = _mm_and_ps(x, *(v4sf*)_ps_inv_sign_mask);
|
||||
|
||||
/* scale by 4/Pi */
|
||||
y = _mm_mul_ps(x, *(v4sf*)_ps_cephes_FOPI);
|
||||
|
||||
#ifdef USE_SSE2
|
||||
/* store the integer part of y in mm0 */
|
||||
emm2 = _mm_cvttps_epi32(y);
|
||||
/* j=(j+1) & (~1) (see the cephes sources) */
|
||||
emm2 = _mm_add_epi32(emm2, *(v4si*)_pi32_1);
|
||||
emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_inv1);
|
||||
y = _mm_cvtepi32_ps(emm2);
|
||||
|
||||
emm2 = _mm_sub_epi32(emm2, *(v4si*)_pi32_2);
|
||||
|
||||
/* get the swap sign flag */
|
||||
emm0 = _mm_andnot_si128(emm2, *(v4si*)_pi32_4);
|
||||
emm0 = _mm_slli_epi32(emm0, 29);
|
||||
/* get the polynom selection mask */
|
||||
emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_2);
|
||||
emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128());
|
||||
|
||||
v4sf sign_bit = _mm_castsi128_ps(emm0);
|
||||
v4sf poly_mask = _mm_castsi128_ps(emm2);
|
||||
#else
|
||||
/* store the integer part of y in mm0:mm1 */
|
||||
xmm2 = _mm_movehl_ps(xmm2, y);
|
||||
mm2 = _mm_cvttps_pi32(y);
|
||||
mm3 = _mm_cvttps_pi32(xmm2);
|
||||
|
||||
/* j=(j+1) & (~1) (see the cephes sources) */
|
||||
mm2 = _mm_add_pi32(mm2, *(v2si*)_pi32_1);
|
||||
mm3 = _mm_add_pi32(mm3, *(v2si*)_pi32_1);
|
||||
mm2 = _mm_and_si64(mm2, *(v2si*)_pi32_inv1);
|
||||
mm3 = _mm_and_si64(mm3, *(v2si*)_pi32_inv1);
|
||||
|
||||
y = _mm_cvtpi32x2_ps(mm2, mm3);
|
||||
|
||||
|
||||
mm2 = _mm_sub_pi32(mm2, *(v2si*)_pi32_2);
|
||||
mm3 = _mm_sub_pi32(mm3, *(v2si*)_pi32_2);
|
||||
|
||||
/* get the swap sign flag in mm0:mm1 and the
|
||||
polynom selection mask in mm2:mm3 */
|
||||
|
||||
mm0 = _mm_andnot_si64(mm2, *(v2si*)_pi32_4);
|
||||
mm1 = _mm_andnot_si64(mm3, *(v2si*)_pi32_4);
|
||||
mm0 = _mm_slli_pi32(mm0, 29);
|
||||
mm1 = _mm_slli_pi32(mm1, 29);
|
||||
|
||||
mm2 = _mm_and_si64(mm2, *(v2si*)_pi32_2);
|
||||
mm3 = _mm_and_si64(mm3, *(v2si*)_pi32_2);
|
||||
|
||||
mm2 = _mm_cmpeq_pi32(mm2, _mm_setzero_si64());
|
||||
mm3 = _mm_cmpeq_pi32(mm3, _mm_setzero_si64());
|
||||
|
||||
v4sf sign_bit, poly_mask;
|
||||
COPY_MM_TO_XMM(mm0, mm1, sign_bit);
|
||||
COPY_MM_TO_XMM(mm2, mm3, poly_mask);
|
||||
_mm_empty(); /* good-bye mmx */
|
||||
#endif
|
||||
/* The magic pass: "Extended precision modular arithmetic"
|
||||
x = ((x - y * DP1) - y * DP2) - y * DP3; */
|
||||
xmm1 = *(v4sf*)_ps_minus_cephes_DP1;
|
||||
xmm2 = *(v4sf*)_ps_minus_cephes_DP2;
|
||||
xmm3 = *(v4sf*)_ps_minus_cephes_DP3;
|
||||
xmm1 = _mm_mul_ps(y, xmm1);
|
||||
xmm2 = _mm_mul_ps(y, xmm2);
|
||||
xmm3 = _mm_mul_ps(y, xmm3);
|
||||
x = _mm_add_ps(x, xmm1);
|
||||
x = _mm_add_ps(x, xmm2);
|
||||
x = _mm_add_ps(x, xmm3);
|
||||
|
||||
/* Evaluate the first polynom (0 <= x <= Pi/4) */
|
||||
y = *(v4sf*)_ps_coscof_p0;
|
||||
v4sf z = _mm_mul_ps(x,x);
|
||||
|
||||
y = _mm_mul_ps(y, z);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_coscof_p1);
|
||||
y = _mm_mul_ps(y, z);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_coscof_p2);
|
||||
y = _mm_mul_ps(y, z);
|
||||
y = _mm_mul_ps(y, z);
|
||||
v4sf tmp = _mm_mul_ps(z, *(v4sf*)_ps_0p5);
|
||||
y = _mm_sub_ps(y, tmp);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_1);
|
||||
|
||||
/* Evaluate the second polynom (Pi/4 <= x <= 0) */
|
||||
|
||||
v4sf y2 = *(v4sf*)_ps_sincof_p0;
|
||||
y2 = _mm_mul_ps(y2, z);
|
||||
y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p1);
|
||||
y2 = _mm_mul_ps(y2, z);
|
||||
y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p2);
|
||||
y2 = _mm_mul_ps(y2, z);
|
||||
y2 = _mm_mul_ps(y2, x);
|
||||
y2 = _mm_add_ps(y2, x);
|
||||
|
||||
/* select the correct result from the two polynoms */
|
||||
xmm3 = poly_mask;
|
||||
y2 = _mm_and_ps(xmm3, y2); //, xmm3);
|
||||
y = _mm_andnot_ps(xmm3, y);
|
||||
y = _mm_add_ps(y,y2);
|
||||
/* update the sign */
|
||||
y = _mm_xor_ps(y, sign_bit);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/* since sin_ps and cos_ps are almost identical, sincos_ps could replace both of them..
|
||||
it is almost as fast, and gives you a free cosine with your sine */
|
||||
inline void sincos_ps(v4sf x, v4sf *s, v4sf *c) {
|
||||
v4sf xmm1, xmm2, xmm3 = _mm_setzero_ps(), sign_bit_sin, y;
|
||||
#ifdef USE_SSE2
|
||||
v4si emm0, emm2, emm4;
|
||||
#else
|
||||
v2si mm0, mm1, mm2, mm3, mm4, mm5;
|
||||
#endif
|
||||
sign_bit_sin = x;
|
||||
/* take the absolute value */
|
||||
x = _mm_and_ps(x, *(v4sf*)_ps_inv_sign_mask);
|
||||
/* extract the sign bit (upper one) */
|
||||
sign_bit_sin = _mm_and_ps(sign_bit_sin, *(v4sf*)_ps_sign_mask);
|
||||
|
||||
/* scale by 4/Pi */
|
||||
y = _mm_mul_ps(x, *(v4sf*)_ps_cephes_FOPI);
|
||||
|
||||
#ifdef USE_SSE2
|
||||
/* store the integer part of y in emm2 */
|
||||
emm2 = _mm_cvttps_epi32(y);
|
||||
|
||||
/* j=(j+1) & (~1) (see the cephes sources) */
|
||||
emm2 = _mm_add_epi32(emm2, *(v4si*)_pi32_1);
|
||||
emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_inv1);
|
||||
y = _mm_cvtepi32_ps(emm2);
|
||||
|
||||
emm4 = emm2;
|
||||
|
||||
/* get the swap sign flag for the sine */
|
||||
emm0 = _mm_and_si128(emm2, *(v4si*)_pi32_4);
|
||||
emm0 = _mm_slli_epi32(emm0, 29);
|
||||
v4sf swap_sign_bit_sin = _mm_castsi128_ps(emm0);
|
||||
|
||||
/* get the polynom selection mask for the sine*/
|
||||
emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_2);
|
||||
emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128());
|
||||
v4sf poly_mask = _mm_castsi128_ps(emm2);
|
||||
#else
|
||||
/* store the integer part of y in mm2:mm3 */
|
||||
xmm3 = _mm_movehl_ps(xmm3, y);
|
||||
mm2 = _mm_cvttps_pi32(y);
|
||||
mm3 = _mm_cvttps_pi32(xmm3);
|
||||
|
||||
/* j=(j+1) & (~1) (see the cephes sources) */
|
||||
mm2 = _mm_add_pi32(mm2, *(v2si*)_pi32_1);
|
||||
mm3 = _mm_add_pi32(mm3, *(v2si*)_pi32_1);
|
||||
mm2 = _mm_and_si64(mm2, *(v2si*)_pi32_inv1);
|
||||
mm3 = _mm_and_si64(mm3, *(v2si*)_pi32_inv1);
|
||||
|
||||
y = _mm_cvtpi32x2_ps(mm2, mm3);
|
||||
|
||||
mm4 = mm2;
|
||||
mm5 = mm3;
|
||||
|
||||
/* get the swap sign flag for the sine */
|
||||
mm0 = _mm_and_si64(mm2, *(v2si*)_pi32_4);
|
||||
mm1 = _mm_and_si64(mm3, *(v2si*)_pi32_4);
|
||||
mm0 = _mm_slli_pi32(mm0, 29);
|
||||
mm1 = _mm_slli_pi32(mm1, 29);
|
||||
v4sf swap_sign_bit_sin;
|
||||
COPY_MM_TO_XMM(mm0, mm1, swap_sign_bit_sin);
|
||||
|
||||
/* get the polynom selection mask for the sine */
|
||||
|
||||
mm2 = _mm_and_si64(mm2, *(v2si*)_pi32_2);
|
||||
mm3 = _mm_and_si64(mm3, *(v2si*)_pi32_2);
|
||||
mm2 = _mm_cmpeq_pi32(mm2, _mm_setzero_si64());
|
||||
mm3 = _mm_cmpeq_pi32(mm3, _mm_setzero_si64());
|
||||
v4sf poly_mask;
|
||||
COPY_MM_TO_XMM(mm2, mm3, poly_mask);
|
||||
#endif
|
||||
|
||||
/* The magic pass: "Extended precision modular arithmetic"
|
||||
x = ((x - y * DP1) - y * DP2) - y * DP3; */
|
||||
xmm1 = *(v4sf*)_ps_minus_cephes_DP1;
|
||||
xmm2 = *(v4sf*)_ps_minus_cephes_DP2;
|
||||
xmm3 = *(v4sf*)_ps_minus_cephes_DP3;
|
||||
xmm1 = _mm_mul_ps(y, xmm1);
|
||||
xmm2 = _mm_mul_ps(y, xmm2);
|
||||
xmm3 = _mm_mul_ps(y, xmm3);
|
||||
x = _mm_add_ps(x, xmm1);
|
||||
x = _mm_add_ps(x, xmm2);
|
||||
x = _mm_add_ps(x, xmm3);
|
||||
|
||||
#ifdef USE_SSE2
|
||||
emm4 = _mm_sub_epi32(emm4, *(v4si*)_pi32_2);
|
||||
emm4 = _mm_andnot_si128(emm4, *(v4si*)_pi32_4);
|
||||
emm4 = _mm_slli_epi32(emm4, 29);
|
||||
v4sf sign_bit_cos = _mm_castsi128_ps(emm4);
|
||||
#else
|
||||
/* get the sign flag for the cosine */
|
||||
mm4 = _mm_sub_pi32(mm4, *(v2si*)_pi32_2);
|
||||
mm5 = _mm_sub_pi32(mm5, *(v2si*)_pi32_2);
|
||||
mm4 = _mm_andnot_si64(mm4, *(v2si*)_pi32_4);
|
||||
mm5 = _mm_andnot_si64(mm5, *(v2si*)_pi32_4);
|
||||
mm4 = _mm_slli_pi32(mm4, 29);
|
||||
mm5 = _mm_slli_pi32(mm5, 29);
|
||||
v4sf sign_bit_cos;
|
||||
COPY_MM_TO_XMM(mm4, mm5, sign_bit_cos);
|
||||
_mm_empty(); /* good-bye mmx */
|
||||
#endif
|
||||
|
||||
sign_bit_sin = _mm_xor_ps(sign_bit_sin, swap_sign_bit_sin);
|
||||
|
||||
|
||||
/* Evaluate the first polynom (0 <= x <= Pi/4) */
|
||||
v4sf z = _mm_mul_ps(x,x);
|
||||
y = *(v4sf*)_ps_coscof_p0;
|
||||
|
||||
y = _mm_mul_ps(y, z);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_coscof_p1);
|
||||
y = _mm_mul_ps(y, z);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_coscof_p2);
|
||||
y = _mm_mul_ps(y, z);
|
||||
y = _mm_mul_ps(y, z);
|
||||
v4sf tmp = _mm_mul_ps(z, *(v4sf*)_ps_0p5);
|
||||
y = _mm_sub_ps(y, tmp);
|
||||
y = _mm_add_ps(y, *(v4sf*)_ps_1);
|
||||
|
||||
/* Evaluate the second polynom (Pi/4 <= x <= 0) */
|
||||
|
||||
v4sf y2 = *(v4sf*)_ps_sincof_p0;
|
||||
y2 = _mm_mul_ps(y2, z);
|
||||
y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p1);
|
||||
y2 = _mm_mul_ps(y2, z);
|
||||
y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p2);
|
||||
y2 = _mm_mul_ps(y2, z);
|
||||
y2 = _mm_mul_ps(y2, x);
|
||||
y2 = _mm_add_ps(y2, x);
|
||||
|
||||
/* select the correct result from the two polynoms */
|
||||
xmm3 = poly_mask;
|
||||
v4sf ysin2 = _mm_and_ps(xmm3, y2);
|
||||
v4sf ysin1 = _mm_andnot_ps(xmm3, y);
|
||||
y2 = _mm_sub_ps(y2,ysin2);
|
||||
y = _mm_sub_ps(y, ysin1);
|
||||
|
||||
xmm1 = _mm_add_ps(ysin1,ysin2);
|
||||
xmm2 = _mm_add_ps(y,y2);
|
||||
|
||||
/* update the sign */
|
||||
*s = _mm_xor_ps(xmm1, sign_bit_sin);
|
||||
*c = _mm_xor_ps(xmm2, sign_bit_cos);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@ -19,6 +19,7 @@
|
||||
set(OBS_ADAPTER_SOURCES
|
||||
gps_l1_ca_observables.cc
|
||||
galileo_e1_observables.cc
|
||||
hybrid_observables.cc
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
101
src/algorithms/observables/adapters/hybrid_observables.cc
Normal file
101
src/algorithms/observables/adapters/hybrid_observables.cc
Normal file
@ -0,0 +1,101 @@
|
||||
/*!
|
||||
* \file hybrid_observables.cc
|
||||
* \brief Implementation of an adapter of a Galileo E1 observables block
|
||||
* to a ObservablesInterface
|
||||
* \author Javier Arribas, 2011. jarribas(at)cttc.es
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2012 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "hybrid_observables.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "hybrid_observables_cc.h"
|
||||
#include <glog/logging.h>
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
HybridObservables::HybridObservables(ConfigurationInterface* configuration,
|
||||
std::string role,
|
||||
unsigned int in_streams,
|
||||
unsigned int out_streams,
|
||||
boost::shared_ptr<gr::msg_queue> queue) :
|
||||
role_(role),
|
||||
in_streams_(in_streams),
|
||||
out_streams_(out_streams),
|
||||
queue_(queue)
|
||||
{
|
||||
int output_rate_ms;
|
||||
output_rate_ms = configuration->property(role + ".output_rate_ms", 500);
|
||||
std::string default_dump_filename = "./observables.dat";
|
||||
DLOG(INFO) << "role " << role;
|
||||
bool flag_averaging;
|
||||
flag_averaging = configuration->property(role + ".flag_averaging", false);
|
||||
dump_ = configuration->property(role + ".dump", false);
|
||||
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||
fs_in_ = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
|
||||
observables_ = hybrid_make_observables_cc(in_streams_, queue_, dump_, dump_filename_, output_rate_ms, flag_averaging);
|
||||
observables_->set_fs_in(fs_in_);
|
||||
DLOG(INFO) << "pseudorange(" << observables_->unique_id() << ")";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
HybridObservables::~HybridObservables()
|
||||
{}
|
||||
|
||||
|
||||
|
||||
|
||||
void HybridObservables::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
// Nothing to connect internally
|
||||
DLOG(INFO) << "nothing to connect internally";
|
||||
}
|
||||
|
||||
|
||||
|
||||
void HybridObservables::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
// Nothing to disconnect
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
gr::basic_block_sptr HybridObservables::get_left_block()
|
||||
{
|
||||
return observables_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
gr::basic_block_sptr HybridObservables::get_right_block()
|
||||
{
|
||||
return observables_;
|
||||
}
|
||||
|
93
src/algorithms/observables/adapters/hybrid_observables.h
Normal file
93
src/algorithms/observables/adapters/hybrid_observables.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*!
|
||||
* \file hybrid_observables.h
|
||||
* \brief Implementation of an adapter of a Galileo E1 observables block
|
||||
* to a ObservablesInterface
|
||||
* \author Mara Branzanti 2013. mara.branzanti(at)gmail.com
|
||||
* \author Javier Arribas 2013. jarribas(at)cttc.es
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GNSS_SDR_hybrid_observables_H_
|
||||
#define GNSS_SDR_hybrid_observables_H_
|
||||
|
||||
#include <string>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include "observables_interface.h"
|
||||
#include "hybrid_observables_cc.h"
|
||||
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
* \brief This class implements an ObservablesInterface for Galileo E1B
|
||||
*/
|
||||
class HybridObservables : public ObservablesInterface
|
||||
{
|
||||
public:
|
||||
HybridObservables(ConfigurationInterface* configuration,
|
||||
std::string role,
|
||||
unsigned int in_streams,
|
||||
unsigned int out_streams,
|
||||
boost::shared_ptr<gr::msg_queue> queue);
|
||||
virtual ~HybridObservables();
|
||||
std::string role()
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
//! Returns "Hybrid_Observables"
|
||||
std::string implementation()
|
||||
{
|
||||
return "Hybrid_Observables";
|
||||
}
|
||||
void connect(gr::top_block_sptr top_block);
|
||||
void disconnect(gr::top_block_sptr top_block);
|
||||
gr::basic_block_sptr get_left_block();
|
||||
gr::basic_block_sptr get_right_block();
|
||||
void reset()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//! All blocks must have an item_size() function implementation
|
||||
size_t item_size()
|
||||
{
|
||||
return sizeof(gr_complex);
|
||||
}
|
||||
|
||||
private:
|
||||
hybrid_observables_cc_sptr observables_;
|
||||
bool dump_;
|
||||
unsigned int fs_in_;
|
||||
std::string dump_filename_;
|
||||
std::string role_;
|
||||
unsigned int in_streams_;
|
||||
unsigned int out_streams_;
|
||||
boost::shared_ptr<gr::msg_queue> queue_;
|
||||
};
|
||||
|
||||
#endif
|
@ -19,6 +19,7 @@
|
||||
set(OBS_GR_BLOCKS_SOURCES
|
||||
gps_l1_ca_observables_cc.cc
|
||||
galileo_e1_observables_cc.cc
|
||||
hybrid_observables_cc.cc
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
@ -0,0 +1,234 @@
|
||||
/*!
|
||||
* \file hybrid_observables_cc.cc
|
||||
* \brief Implementation of the pseudorange computation block for Galileo E1
|
||||
* \author Mara Branzanti 2013. mara.branzanti(at)gmail.com
|
||||
* \author Javier Arribas 2013. jarribas(at)cttc.es
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2013 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "hybrid_observables_cc.h"
|
||||
#include <algorithm>
|
||||
#include <bitset>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <glog/logging.h>
|
||||
#include "control_message_factory.h"
|
||||
#include "gnss_synchro.h"
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
|
||||
hybrid_observables_cc_sptr
|
||||
hybrid_make_observables_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging)
|
||||
{
|
||||
return hybrid_observables_cc_sptr(new hybrid_observables_cc(nchannels, queue, dump, dump_filename, output_rate_ms, flag_averaging));
|
||||
}
|
||||
|
||||
|
||||
hybrid_observables_cc::hybrid_observables_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging) :
|
||||
gr::block("hybrid_observables_cc", gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)),
|
||||
gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)))
|
||||
{
|
||||
// initialize internal vars
|
||||
d_queue = queue;
|
||||
d_dump = dump;
|
||||
d_nchannels = nchannels;
|
||||
d_output_rate_ms = output_rate_ms;
|
||||
d_dump_filename = dump_filename;
|
||||
d_flag_averaging = flag_averaging;
|
||||
|
||||
// ############# ENABLE DATA FILE LOG #################
|
||||
if (d_dump == true)
|
||||
{
|
||||
if (d_dump_file.is_open() == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit );
|
||||
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
|
||||
LOG(INFO) << "Observables dump enabled Log file: " << d_dump_filename.c_str();
|
||||
}
|
||||
catch (std::ifstream::failure e)
|
||||
{
|
||||
LOG(WARNING) << "Exception opening observables dump file " << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
hybrid_observables_cc::~hybrid_observables_cc()
|
||||
{
|
||||
d_dump_file.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Hybrid_pairCompare_gnss_synchro_Prn_delay_ms( std::pair<int,Gnss_Synchro> a, std::pair<int,Gnss_Synchro> b)
|
||||
{
|
||||
return (a.second.Prn_timestamp_ms) < (b.second.Prn_timestamp_ms);
|
||||
}
|
||||
|
||||
|
||||
bool Hybrid_pairCompare_gnss_synchro_d_TOW_hybrid_at_current_symbol( std::pair<int,Gnss_Synchro> a, std::pair<int,Gnss_Synchro> b)
|
||||
{
|
||||
return (a.second.d_TOW_hybrid_at_current_symbol) < (b.second.d_TOW_hybrid_at_current_symbol);
|
||||
}
|
||||
|
||||
bool Hybrid_pairCompare_gnss_synchro_d_TOW_at_current_symbol( std::pair<int,Gnss_Synchro> a, std::pair<int,Gnss_Synchro> b)
|
||||
{
|
||||
return (a.second.d_TOW_at_current_symbol) < (b.second.d_TOW_at_current_symbol);
|
||||
}
|
||||
|
||||
|
||||
int hybrid_observables_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
|
||||
{
|
||||
Gnss_Synchro **in = (Gnss_Synchro **) &input_items[0]; // Get the input pointer
|
||||
Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0]; // Get the output pointer
|
||||
|
||||
Gnss_Synchro current_gnss_synchro[d_nchannels];
|
||||
std::map<int,Gnss_Synchro> current_gnss_synchro_map;
|
||||
std::map<int,Gnss_Synchro> current_gnss_synchro_map_gps_only;
|
||||
std::map<int,Gnss_Synchro>::iterator gnss_synchro_iter;
|
||||
d_sample_counter++; //count for the processed samples
|
||||
/*
|
||||
* 1. Read the GNSS SYNCHRO objects from available channels
|
||||
*/
|
||||
for (unsigned int i = 0; i < d_nchannels; i++)
|
||||
{
|
||||
//Copy the telemetry decoder data to local copy
|
||||
current_gnss_synchro[i] = in[i][0];
|
||||
/*
|
||||
* 1.2 Assume no valid pseudoranges
|
||||
*/
|
||||
current_gnss_synchro[i].Flag_valid_pseudorange = false;
|
||||
current_gnss_synchro[i].Pseudorange_m = 0.0;
|
||||
if (current_gnss_synchro[i].Flag_valid_word)
|
||||
{
|
||||
//record the word structure in a map for pseudorange computation
|
||||
current_gnss_synchro_map.insert(std::pair<int, Gnss_Synchro>(current_gnss_synchro[i].Channel_ID, current_gnss_synchro[i]));
|
||||
if (current_gnss_synchro[i].System=='G')
|
||||
{
|
||||
current_gnss_synchro_map_gps_only.insert(std::pair<int, Gnss_Synchro>(current_gnss_synchro[i].Channel_ID, current_gnss_synchro[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 2. Compute RAW pseudoranges using COMMON RECEPTION TIME algorithm. Use only the valid channels (channels that are tracking a satellite)
|
||||
*/
|
||||
DLOG(INFO)<<"gnss_synchro set size="<<current_gnss_synchro_map.size()<<std::endl;
|
||||
|
||||
if(current_gnss_synchro_map.size() > 0)// and current_gnss_synchro_map_gps_only.size()>0)
|
||||
{
|
||||
/*
|
||||
* 2.1 Use CURRENT set of measurements and find the nearest satellite
|
||||
* common RX time algorithm
|
||||
*/
|
||||
// what is the most recent symbol TOW in the current set? -> this will be the reference symbol
|
||||
gnss_synchro_iter = max_element(current_gnss_synchro_map.begin(), current_gnss_synchro_map.end(), Hybrid_pairCompare_gnss_synchro_d_TOW_hybrid_at_current_symbol);
|
||||
//gnss_synchro_iter = max_element(current_gnss_synchro_map_gps_only.begin(), current_gnss_synchro_map_gps_only.end(), Hybrid_pairCompare_gnss_synchro_d_TOW_hybrid_at_current_symbol);
|
||||
double d_TOW_reference = gnss_synchro_iter->second.d_TOW_hybrid_at_current_symbol;
|
||||
char ref_sat_system=gnss_synchro_iter->second.System;
|
||||
DLOG(INFO)<<"d_TOW_hybrid_reference [ms] = "<< d_TOW_reference*1000 <<std::endl;
|
||||
double d_ref_PRN_rx_time_ms = gnss_synchro_iter->second.Prn_timestamp_ms;
|
||||
DLOG(INFO)<<"ref_PRN_rx_time_ms [ms] = "<< d_ref_PRN_rx_time_ms <<std::endl;
|
||||
//int reference_channel= gnss_synchro_iter->second.Channel_ID;
|
||||
|
||||
// Now compute RX time differences due to the PRN alignment in the correlators
|
||||
double traveltime_ms;
|
||||
double pseudorange_m;
|
||||
double delta_rx_time_ms;
|
||||
double delta_TOW_ms;
|
||||
//std::cout<<"d_sample_counter="<<d_sample_counter<<std::endl;
|
||||
for(gnss_synchro_iter = current_gnss_synchro_map.begin(); gnss_synchro_iter != current_gnss_synchro_map.end(); gnss_synchro_iter++)
|
||||
{
|
||||
// check and correct synchronization in cross-system pseudoranges!
|
||||
delta_rx_time_ms = gnss_synchro_iter->second.Prn_timestamp_ms-d_ref_PRN_rx_time_ms;
|
||||
delta_TOW_ms = (d_TOW_reference - gnss_synchro_iter->second.d_TOW_hybrid_at_current_symbol)*1000.0;
|
||||
//std::cout<<"delta_rx_time_ms["<<gnss_synchro_iter->second.Channel_ID<<","<<gnss_synchro_iter->second.System<<"]="<<delta_rx_time_ms<<std::endl;
|
||||
//std::cout<<"delta_TOW_ms["<<gnss_synchro_iter->second.Channel_ID<<","<<gnss_synchro_iter->second.System<<"]="<<delta_TOW_ms<<std::endl;
|
||||
//compute the pseudorange
|
||||
traveltime_ms = delta_TOW_ms + delta_rx_time_ms + GALILEO_STARTOFFSET_ms;
|
||||
pseudorange_m = traveltime_ms * GALILEO_C_m_ms; // [m]
|
||||
DLOG(INFO)<<"CH "<<gnss_synchro_iter->second.Channel_ID<<" tracking GNSS System "<<gnss_synchro_iter->second.System<<" has PRN start at= "<<gnss_synchro_iter->second.Prn_timestamp_ms<<" [ms], d_TOW_at_current_symbol = "<<(gnss_synchro_iter->second.d_TOW_at_current_symbol)*1000<<" [ms], d_TOW_hybrid_at_current_symbol = "<<(gnss_synchro_iter->second.d_TOW_hybrid_at_current_symbol)*1000<<"[ms], delta_rx_time_ms = "<< delta_rx_time_ms << "[ms], travel_time = " << traveltime_ms << ", pseudorange[m] = "<< pseudorange_m << std::endl;
|
||||
|
||||
// update the pseudorange object
|
||||
//current_gnss_synchro[gnss_synchro_iter->second.Channel_ID] = gnss_synchro_iter->second;
|
||||
current_gnss_synchro[gnss_synchro_iter->second.Channel_ID].Pseudorange_m = pseudorange_m;
|
||||
current_gnss_synchro[gnss_synchro_iter->second.Channel_ID].Flag_valid_pseudorange = true;
|
||||
current_gnss_synchro[gnss_synchro_iter->second.Channel_ID].d_TOW_hybrid_at_current_symbol = round(d_TOW_reference*1000)/1000 + GALILEO_STARTOFFSET_ms/1000.0;
|
||||
|
||||
}
|
||||
//std::cout<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
if(d_dump == true)
|
||||
{
|
||||
// MULTIPLEXED FILE RECORDING - Record results to file
|
||||
try
|
||||
{
|
||||
double tmp_double;
|
||||
for (unsigned int i = 0; i < d_nchannels ; i++)
|
||||
{
|
||||
tmp_double = current_gnss_synchro[i].d_TOW_at_current_symbol;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = current_gnss_synchro[i].d_TOW_hybrid_at_current_symbol;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = current_gnss_synchro[i].Prn_timestamp_ms;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = current_gnss_synchro[i].Pseudorange_m;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = (double)(current_gnss_synchro[i].Flag_valid_pseudorange==true);
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = current_gnss_synchro[i].PRN;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
}
|
||||
}
|
||||
catch (const std::ifstream::failure& e)
|
||||
{
|
||||
LOG(WARNING) << "Exception writing observables dump file " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
consume_each(1); //consume one by one
|
||||
|
||||
for (unsigned int i = 0; i < d_nchannels ; i++)
|
||||
{
|
||||
*out[i] = current_gnss_synchro[i];
|
||||
}
|
||||
//todo: enable output when the hybrid algorithm is completed
|
||||
return 1; //Output the observables
|
||||
}
|
||||
|
@ -0,0 +1,85 @@
|
||||
/*!
|
||||
* \file hybrid_observables_cc.h
|
||||
* \brief Interface of the observables computation block for Galileo E1
|
||||
* \author Mara Branzanti 2013. mara.branzanti(at)gmail.com
|
||||
* \author Javier Arribas 2013. jarribas(at)cttc.es
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GNSS_SDR_hybrid_observables_CC_H
|
||||
#define GNSS_SDR_hybrid_observables_CC_H
|
||||
|
||||
#include <fstream>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include "concurrent_queue.h"
|
||||
#include "galileo_navigation_message.h"
|
||||
#include "rinex_printer.h"
|
||||
#include "Galileo_E1.h"
|
||||
#include "gnss_synchro.h"
|
||||
|
||||
class hybrid_observables_cc;
|
||||
|
||||
typedef boost::shared_ptr<hybrid_observables_cc> hybrid_observables_cc_sptr;
|
||||
|
||||
hybrid_observables_cc_sptr
|
||||
hybrid_make_observables_cc(unsigned int n_channels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging);
|
||||
|
||||
/*!
|
||||
* \brief This class implements a block that computes Galileo observables
|
||||
*/
|
||||
class hybrid_observables_cc : public gr::block
|
||||
{
|
||||
public:
|
||||
~hybrid_observables_cc ();
|
||||
void set_fs_in(unsigned long int fs_in) {d_fs_in = fs_in;};
|
||||
int general_work (int noutput_items, gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
|
||||
|
||||
private:
|
||||
friend hybrid_observables_cc_sptr
|
||||
hybrid_make_observables_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging);
|
||||
hybrid_observables_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging);
|
||||
|
||||
// class private vars
|
||||
boost::shared_ptr<gr::msg_queue> d_queue;
|
||||
bool d_dump;
|
||||
bool d_flag_averaging;
|
||||
long int d_sample_counter;
|
||||
unsigned int d_nchannels;
|
||||
unsigned long int d_fs_in;
|
||||
int d_output_rate_ms;
|
||||
std::string d_dump_filename;
|
||||
std::ofstream d_dump_file;
|
||||
};
|
||||
|
||||
#endif
|
@ -29,11 +29,13 @@
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "signal_generator.h"
|
||||
#include <glog/logging.h>
|
||||
#include "configuration_interface.h"
|
||||
#include "Galileo_E1.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "Galileo_E5a.h"
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
@ -46,6 +48,7 @@ SignalGenerator::SignalGenerator(ConfigurationInterface* configuration,
|
||||
std::string default_item_type = "gr_complex";
|
||||
std::string default_dump_file = "./data/gen_source.dat";
|
||||
std::string default_system = "G";
|
||||
std::string default_signal = "1C";
|
||||
|
||||
item_type_ = configuration->property(role + ".item_type", default_item_type);
|
||||
dump_ = configuration->property(role + ".dump", false);
|
||||
@ -57,30 +60,42 @@ SignalGenerator::SignalGenerator(ConfigurationInterface* configuration,
|
||||
float BW_BB = configuration->property("SignalSource.BW_BB", 1.0);
|
||||
unsigned int num_satellites = configuration->property("SignalSource.num_satellites", 1);
|
||||
|
||||
std::vector<std::string> signal1;
|
||||
std::vector<std::string> system;
|
||||
std::vector<unsigned int> PRN;
|
||||
std::vector<float> CN0_dB;
|
||||
std::vector<float> doppler_Hz;
|
||||
std::vector<unsigned int> delay_chips;
|
||||
std::vector<unsigned int> delay_sec;
|
||||
|
||||
for (unsigned int sat_idx = 0; sat_idx < num_satellites; sat_idx++)
|
||||
{
|
||||
std::string sat = std::to_string(sat_idx);
|
||||
signal1.push_back(configuration->property("SignalSource.signal_" + sat, default_signal));
|
||||
system.push_back(configuration->property("SignalSource.system_" + sat, default_system));
|
||||
PRN.push_back(configuration->property("SignalSource.PRN_" + sat, 1));
|
||||
CN0_dB.push_back(configuration->property("SignalSource.CN0_dB_" + sat, 10));
|
||||
doppler_Hz.push_back(configuration->property("SignalSource.doppler_Hz_" + sat, 0));
|
||||
delay_chips.push_back(configuration->property("SignalSource.delay_chips_" + sat, 0));
|
||||
delay_sec.push_back(configuration->property("SignalSource.delay_sec_" + sat, 0));
|
||||
}
|
||||
|
||||
// If Galileo signal is present -> vector duration = 100 ms (25 * 4 ms)
|
||||
// If Galileo signal is present -> vector duration = 100 ms (25 * 4 ms)
|
||||
// If there is only GPS signal (Galileo signal not present) -> vector duration = 1 ms
|
||||
unsigned int vector_length = 0;
|
||||
if (std::find(system.begin(), system.end(), "E") != system.end())
|
||||
{
|
||||
vector_length = round((float)fs_in / (Galileo_E1_CODE_CHIP_RATE_HZ
|
||||
/ Galileo_E1_B_CODE_LENGTH_CHIPS))
|
||||
* Galileo_E1_C_SECONDARY_CODE_LENGTH;
|
||||
if (signal1[0].at(0)=='5')
|
||||
{
|
||||
vector_length = round((float) fs_in / (Galileo_E5a_CODE_CHIP_RATE_HZ
|
||||
/ Galileo_E5a_CODE_LENGTH_CHIPS));
|
||||
}
|
||||
else
|
||||
{
|
||||
vector_length = round((float)fs_in / (Galileo_E1_CODE_CHIP_RATE_HZ
|
||||
/ Galileo_E1_B_CODE_LENGTH_CHIPS))
|
||||
* Galileo_E1_C_SECONDARY_CODE_LENGTH;
|
||||
}
|
||||
}
|
||||
else if (std::find(system.begin(), system.end(), "G") != system.end())
|
||||
{
|
||||
@ -92,7 +107,7 @@ SignalGenerator::SignalGenerator(ConfigurationInterface* configuration,
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
DLOG(INFO) << "Item size " << item_size_;
|
||||
gen_source_ = signal_make_generator_c(system, PRN, CN0_dB, doppler_Hz, delay_chips,
|
||||
gen_source_ = signal_make_generator_c(signal1, system, PRN, CN0_dB, doppler_Hz, delay_chips, delay_sec,
|
||||
data_flag, noise_flag, fs_in, vector_length, BW_BB);
|
||||
|
||||
vector_to_stream_ = gr::blocks::vector_to_stream::make(item_size_, vector_length);
|
||||
|
@ -33,6 +33,7 @@
|
||||
#ifndef GNSS_SDR_SIGNAL_GENERATOR_H_
|
||||
#define GNSS_SDR_SIGNAL_GENERATOR_H_
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
@ -45,9 +46,9 @@
|
||||
class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
* \brief This class generates synthesized GNSS signal.
|
||||
*
|
||||
*/
|
||||
* \brief This class generates synthesized GNSS signal.
|
||||
*
|
||||
*/
|
||||
class SignalGenerator: public GNSSBlockInterface
|
||||
{
|
||||
public:
|
||||
@ -62,8 +63,8 @@ public:
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "GNSSSignalGenerator".
|
||||
*/
|
||||
* \brief Returns "GNSSSignalGenerator".
|
||||
*/
|
||||
std::string implementation()
|
||||
{
|
||||
return "GNSSSignalGenerator";
|
||||
@ -91,5 +92,4 @@ private:
|
||||
gr::blocks::file_sink::sptr file_sink_;
|
||||
boost::shared_ptr<gr::msg_queue> queue_;
|
||||
};
|
||||
|
||||
#endif /*GNSS_SDR_SIGNAL_GENERATOR_H_*/
|
||||
|
@ -1,32 +1,32 @@
|
||||
/*!
|
||||
* \file signal_generator_c.cc
|
||||
* \brief GNU Radio source block that generates synthesized GNSS signal.
|
||||
* \author Marc Molina, 2013. marc.molina.pena@gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
* \file signal_generator_c.cc
|
||||
* \brief GNU Radio source block that generates synthesized GNSS signal.
|
||||
* \author Marc Molina, 2013. marc.molina.pena@gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <volk/volk.h>
|
||||
@ -34,37 +34,41 @@
|
||||
#include "gps_sdr_signal_processing.h"
|
||||
#include "galileo_e1_signal_processing.h"
|
||||
#include "nco_lib.h"
|
||||
|
||||
|
||||
#include "galileo_e5_signal_processing.h"
|
||||
#include "Galileo_E5a.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
/*
|
||||
* Create a new instance of signal_generator_c and return
|
||||
* a boost shared_ptr. This is effectively the public constructor.
|
||||
*/
|
||||
* Create a new instance of signal_generator_c and return
|
||||
* a boost shared_ptr. This is effectively the public constructor.
|
||||
*/
|
||||
signal_generator_c_sptr
|
||||
signal_make_generator_c (std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
signal_make_generator_c (std::vector<std::string> signal1, std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz,
|
||||
const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag,
|
||||
const std::vector<unsigned int> &delay_chips, const std::vector<unsigned int> &delay_sec,bool data_flag, bool noise_flag,
|
||||
unsigned int fs_in, unsigned int vector_length, float BW_BB)
|
||||
{
|
||||
return gnuradio::get_initial_sptr(new signal_generator_c(system, PRN, CN0_dB, doppler_Hz, delay_chips,
|
||||
return gnuradio::get_initial_sptr(new signal_generator_c(signal1, system, PRN, CN0_dB, doppler_Hz, delay_chips,delay_sec,
|
||||
data_flag, noise_flag, fs_in, vector_length, BW_BB));
|
||||
}
|
||||
|
||||
/*
|
||||
* The private constructor
|
||||
*/
|
||||
signal_generator_c::signal_generator_c (std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
* The private constructor
|
||||
*/
|
||||
signal_generator_c::signal_generator_c (std::vector<std::string> signal1, std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz,
|
||||
const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag,
|
||||
const std::vector<unsigned int> &delay_chips,const std::vector<unsigned int> &delay_sec ,bool data_flag, bool noise_flag,
|
||||
unsigned int fs_in, unsigned int vector_length, float BW_BB) :
|
||||
|
||||
gr::block ("signal_gen_cc", gr::io_signature::make(0, 0, sizeof(gr_complex)),
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex)*vector_length)),
|
||||
signal_(signal1),
|
||||
system_(system),
|
||||
PRN_(PRN),
|
||||
CN0_dB_(CN0_dB),
|
||||
doppler_Hz_(doppler_Hz),
|
||||
delay_chips_(delay_chips),
|
||||
delay_sec_(delay_sec),
|
||||
data_flag_(data_flag),
|
||||
noise_flag_(noise_flag),
|
||||
fs_in_(fs_in),
|
||||
@ -78,6 +82,8 @@ signal_generator_c::signal_generator_c (std::vector<std::string> system, const s
|
||||
|
||||
void signal_generator_c::init()
|
||||
{
|
||||
work_counter_ = 0;
|
||||
|
||||
if (posix_memalign((void**)&complex_phase_, 16, vector_length_ * sizeof(gr_complex)) == 0){};
|
||||
|
||||
// True if Galileo satellites are present
|
||||
@ -86,8 +92,12 @@ void signal_generator_c::init()
|
||||
for (unsigned int sat = 0; sat < num_sats_; sat++)
|
||||
{
|
||||
start_phase_rad_.push_back(0);
|
||||
current_data_bit_int_.push_back(1);
|
||||
current_data_bits_.push_back(gr_complex(1, 0));
|
||||
ms_counter_.push_back(0);
|
||||
data_modulation_.push_back((Galileo_E5a_I_SECONDARY_CODE.at(0)=='0' ? 1 : -1));
|
||||
pilot_modulation_.push_back((Galileo_E5a_Q_SECONDARY_CODE[PRN_[sat]].at(0)=='0' ? 1 : -1));
|
||||
|
||||
|
||||
if (system_[sat] == "G")
|
||||
{
|
||||
@ -99,35 +109,47 @@ void signal_generator_c::init()
|
||||
}
|
||||
else if (system_[sat] == "E")
|
||||
{
|
||||
samples_per_code_.push_back(round((float)fs_in_ / (Galileo_E1_CODE_CHIP_RATE_HZ
|
||||
/ Galileo_E1_B_CODE_LENGTH_CHIPS)));
|
||||
if (signal_[sat].at(0)=='5')
|
||||
{
|
||||
int codelen = (int)Galileo_E5a_CODE_LENGTH_CHIPS;
|
||||
samples_per_code_.push_back(round((float)fs_in_ / (Galileo_E5a_CODE_CHIP_RATE_HZ
|
||||
/ codelen)));
|
||||
num_of_codes_per_vector_.push_back(1);
|
||||
|
||||
num_of_codes_per_vector_.push_back((int)Galileo_E1_C_SECONDARY_CODE_LENGTH);
|
||||
data_bit_duration_ms_.push_back(1e3/Galileo_E1_B_SYMBOL_RATE_BPS);
|
||||
data_bit_duration_ms_.push_back(1e3/Galileo_E5a_SYMBOL_RATE_BPS);
|
||||
}
|
||||
else
|
||||
{
|
||||
samples_per_code_.push_back(round((float)fs_in_ / (Galileo_E1_CODE_CHIP_RATE_HZ
|
||||
/ Galileo_E1_B_CODE_LENGTH_CHIPS)));
|
||||
|
||||
num_of_codes_per_vector_.push_back((int)Galileo_E1_C_SECONDARY_CODE_LENGTH);
|
||||
data_bit_duration_ms_.push_back(1e3/Galileo_E1_B_SYMBOL_RATE_BPS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
random_ = new gr::random();
|
||||
|
||||
// std::cout << "fs_in: " << fs_in_ << std::endl;
|
||||
// std::cout << "data_flag: " << data_flag_ << std::endl;
|
||||
// std::cout << "noise_flag_: " << noise_flag_ << std::endl;
|
||||
// std::cout << "num_sats_: " << num_sats_ << std::endl;
|
||||
// std::cout << "vector_length_: " << vector_length_ << std::endl;
|
||||
// std::cout << "BW_BB_: " << BW_BB_ << std::endl;
|
||||
// std::cout << "fs_in: " << fs_in_ << std::endl;
|
||||
// std::cout << "data_flag: " << data_flag_ << std::endl;
|
||||
// std::cout << "noise_flag_: " << noise_flag_ << std::endl;
|
||||
// std::cout << "num_sats_: " << num_sats_ << std::endl;
|
||||
// std::cout << "vector_length_: " << vector_length_ << std::endl;
|
||||
// std::cout << "BW_BB_: " << BW_BB_ << std::endl;
|
||||
|
||||
// for (unsigned int i = 0; i < num_sats_; i++)
|
||||
// {
|
||||
// std::cout << "Sat " << i << ": " << std::endl;
|
||||
// std::cout << " System " << system_[i] << ": " << std::endl;
|
||||
// std::cout << " PRN: " << PRN_[i] << std::endl;
|
||||
// std::cout << " CN0: " << CN0_dB_[i] << std::endl;
|
||||
// std::cout << " Doppler: " << doppler_Hz_[i] << std::endl;
|
||||
// std::cout << " Delay: " << delay_chips_[i] << std::endl;
|
||||
// std::cout << " Samples per code = " << samples_per_code_[i] << std::endl;
|
||||
// std::cout << " codes per vector = " << num_of_codes_per_vector_[i] << std::endl;
|
||||
// std::cout << " data_bit_duration = " << data_bit_duration_ms_[i] << std::endl;
|
||||
// }
|
||||
// for (unsigned int i = 0; i < num_sats_; i++)
|
||||
// {
|
||||
// std::cout << "Sat " << i << ": " << std::endl;
|
||||
// std::cout << " System " << system_[i] << ": " << std::endl;
|
||||
// std::cout << " PRN: " << PRN_[i] << std::endl;
|
||||
// std::cout << " CN0: " << CN0_dB_[i] << std::endl;
|
||||
// std::cout << " Doppler: " << doppler_Hz_[i] << std::endl;
|
||||
// std::cout << " Delay: " << delay_chips_[i] << std::endl;
|
||||
// std::cout << " Samples per code = " << samples_per_code_[i] << std::endl;
|
||||
// std::cout << " codes per vector = " << num_of_codes_per_vector_[i] << std::endl;
|
||||
// std::cout << " data_bit_duration = " << data_bit_duration_ms_[i] << std::endl;
|
||||
// }
|
||||
}
|
||||
|
||||
void signal_generator_c::generate_codes()
|
||||
@ -166,61 +188,87 @@ void signal_generator_c::generate_codes()
|
||||
}
|
||||
else if (system_[sat] == "E")
|
||||
{
|
||||
// Generate one code-period of E1B signal
|
||||
bool cboc = true;
|
||||
char signal[3];
|
||||
strcpy(signal, "1B");
|
||||
if(signal_[sat].at(0)=='5')
|
||||
{
|
||||
char signal[3];
|
||||
strcpy(signal,"5X");
|
||||
|
||||
galileo_e1_code_gen_complex_sampled(code, signal, cboc, PRN_[sat], fs_in_,
|
||||
(int)Galileo_E1_B_CODE_LENGTH_CHIPS - delay_chips_[sat]);
|
||||
if (posix_memalign((void**)&(sampled_code_data_[sat]), 16,
|
||||
vector_length_ * sizeof(gr_complex)) == 0){};
|
||||
|
||||
// Obtain the desired CN0 assuming that Pn = 1.
|
||||
if (noise_flag_)
|
||||
{
|
||||
for (unsigned int i = 0; i < samples_per_code_[sat]; i++)
|
||||
{
|
||||
code[i] *= sqrt(pow(10, CN0_dB_[sat] / 10) / BW_BB_ / 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Concatenate "num_of_codes_per_vector_" codes
|
||||
for (unsigned int i = 0; i < num_of_codes_per_vector_[sat]; i++)
|
||||
{
|
||||
memcpy(&(sampled_code_data_[sat][i*samples_per_code_[sat]]),
|
||||
code, sizeof(gr_complex)*samples_per_code_[sat]);
|
||||
}
|
||||
galileo_e5_a_code_gen_complex_sampled(sampled_code_data_[sat] , signal, PRN_[sat], fs_in_,
|
||||
(int)Galileo_E5a_CODE_LENGTH_CHIPS-delay_chips_[sat]);
|
||||
|
||||
// Generate E1C signal (25 code-periods, with secondary code)
|
||||
if (posix_memalign((void**)&(sampled_code_pilot_[sat]), 16,
|
||||
vector_length_ * sizeof(gr_complex)) == 0){};
|
||||
|
||||
strcpy(signal, "1C");
|
||||
//noise
|
||||
if (noise_flag_)
|
||||
{
|
||||
for (unsigned int i = 0; i < vector_length_; i++)
|
||||
{
|
||||
sampled_code_data_[sat][i] *= sqrt(pow(10, CN0_dB_[sat] / 10) / BW_BB_ / 2);
|
||||
}
|
||||
}
|
||||
|
||||
galileo_e1_code_gen_complex_sampled(sampled_code_pilot_[sat], signal, cboc, PRN_[sat], fs_in_,
|
||||
(int)Galileo_E1_B_CODE_LENGTH_CHIPS-delay_chips_[sat], true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Generate one code-period of E1B signal
|
||||
bool cboc = true;
|
||||
char signal[3];
|
||||
strcpy(signal, "1B");
|
||||
|
||||
// Obtain the desired CN0 assuming that Pn = 1.
|
||||
if (noise_flag_)
|
||||
{
|
||||
for (unsigned int i = 0; i < vector_length_; i++)
|
||||
{
|
||||
sampled_code_pilot_[sat][i] *= sqrt(pow(10, CN0_dB_[sat] / 10) / BW_BB_ / 2);
|
||||
}
|
||||
}
|
||||
galileo_e1_code_gen_complex_sampled(code, signal, cboc, PRN_[sat], fs_in_,
|
||||
(int)Galileo_E1_B_CODE_LENGTH_CHIPS - delay_chips_[sat]);
|
||||
|
||||
// Obtain the desired CN0 assuming that Pn = 1.
|
||||
if (noise_flag_)
|
||||
{
|
||||
for (unsigned int i = 0; i < samples_per_code_[sat]; i++)
|
||||
{
|
||||
code[i] *= sqrt(pow(10, CN0_dB_[sat] / 10) / BW_BB_ / 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Concatenate "num_of_codes_per_vector_" codes
|
||||
for (unsigned int i = 0; i < num_of_codes_per_vector_[sat]; i++)
|
||||
{
|
||||
memcpy(&(sampled_code_data_[sat][i*samples_per_code_[sat]]),
|
||||
code, sizeof(gr_complex)*samples_per_code_[sat]);
|
||||
}
|
||||
|
||||
// Generate E1C signal (25 code-periods, with secondary code)
|
||||
if (posix_memalign((void**)&(sampled_code_pilot_[sat]), 16,
|
||||
vector_length_ * sizeof(gr_complex)) == 0){};
|
||||
|
||||
strcpy(signal, "1C");
|
||||
|
||||
galileo_e1_code_gen_complex_sampled(sampled_code_pilot_[sat], signal, cboc, PRN_[sat], fs_in_,
|
||||
(int)Galileo_E1_B_CODE_LENGTH_CHIPS-delay_chips_[sat], true);
|
||||
|
||||
// Obtain the desired CN0 assuming that Pn = 1.
|
||||
if (noise_flag_)
|
||||
{
|
||||
for (unsigned int i = 0; i < vector_length_; i++)
|
||||
{
|
||||
sampled_code_pilot_[sat][i] *= sqrt(pow(10, CN0_dB_[sat] / 10) / BW_BB_ / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
signal_generator_c::~signal_generator_c()
|
||||
{
|
||||
for (unsigned int sat = 0; sat < num_sats_; sat++)
|
||||
{
|
||||
free(sampled_code_data_[sat]);
|
||||
if (system_[sat] == "E")
|
||||
if (system_[sat] == "E" && signal_[sat].at(0)!='5')
|
||||
{
|
||||
free(sampled_code_pilot_[sat]);
|
||||
}
|
||||
@ -232,11 +280,13 @@ signal_generator_c::~signal_generator_c()
|
||||
|
||||
int signal_generator_c::general_work (int noutput_items,
|
||||
gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
gr_complex *out = (gr_complex *) output_items[0];
|
||||
|
||||
work_counter_++;
|
||||
|
||||
unsigned int out_idx = 0;
|
||||
unsigned int i = 0;
|
||||
unsigned int k = 0;
|
||||
@ -290,36 +340,74 @@ int signal_generator_c::general_work (int noutput_items,
|
||||
|
||||
else if (system_[sat] == "E")
|
||||
{
|
||||
unsigned int delay_samples = (delay_chips_[sat] % (int)Galileo_E1_B_CODE_LENGTH_CHIPS)
|
||||
* samples_per_code_[sat] / Galileo_E1_B_CODE_LENGTH_CHIPS;
|
||||
if(signal_[sat].at(0)=='5')
|
||||
{
|
||||
// EACH WORK outputs 1 modulated primary code
|
||||
int codelen = (int)Galileo_E5a_CODE_LENGTH_CHIPS;
|
||||
unsigned int delay_samples = (delay_chips_[sat] % codelen)
|
||||
* samples_per_code_[sat] / codelen;
|
||||
for (k = 0; k < delay_samples; k++)
|
||||
{
|
||||
out[out_idx] += (gr_complex(sampled_code_data_[sat][out_idx].real()*data_modulation_[sat] ,
|
||||
sampled_code_data_[sat][out_idx].imag()*pilot_modulation_[sat]) )
|
||||
* complex_phase_[out_idx];
|
||||
out_idx++;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_of_codes_per_vector_[sat]; i++)
|
||||
{
|
||||
for (k = 0; k < delay_samples; k++)
|
||||
{
|
||||
out[out_idx] += (sampled_code_data_[sat][out_idx] * current_data_bits_[sat]
|
||||
- sampled_code_pilot_[sat][out_idx])
|
||||
* complex_phase_[out_idx];
|
||||
out_idx++;
|
||||
}
|
||||
if (ms_counter_[sat]%data_bit_duration_ms_[sat] == 0 && data_flag_)
|
||||
{
|
||||
// New random data bit
|
||||
current_data_bit_int_[sat] = (rand()%2) == 0 ? 1 : -1;
|
||||
}
|
||||
data_modulation_[sat] = current_data_bit_int_[sat] * (Galileo_E5a_I_SECONDARY_CODE.at((ms_counter_[sat]+delay_sec_[sat])%20)=='0' ? 1 : -1);
|
||||
pilot_modulation_[sat] = (Galileo_E5a_Q_SECONDARY_CODE[PRN_[sat]-1].at((ms_counter_[sat]+delay_sec_[sat])%100)=='0' ? 1 : -1);
|
||||
|
||||
if (ms_counter_[sat] == 0 && data_flag_)
|
||||
{
|
||||
// New random data bit
|
||||
current_data_bits_[sat] = gr_complex((rand()%2) == 0 ? 1 : -1, 0);
|
||||
}
|
||||
ms_counter_[sat] = ms_counter_[sat] + (int)round(1e3*GALILEO_E5a_CODE_PERIOD);
|
||||
|
||||
for (k = delay_samples; k < samples_per_code_[sat]; k++)
|
||||
{
|
||||
out[out_idx] += (sampled_code_data_[sat][out_idx] * current_data_bits_[sat]
|
||||
- sampled_code_pilot_[sat][out_idx])
|
||||
* complex_phase_[out_idx];
|
||||
out_idx++;
|
||||
}
|
||||
for (k = delay_samples; k < samples_per_code_[sat]; k++)
|
||||
{
|
||||
out[out_idx] += (gr_complex(sampled_code_data_[sat][out_idx].real()*data_modulation_[sat] ,
|
||||
sampled_code_data_[sat][out_idx].imag()*pilot_modulation_[sat]) )
|
||||
* complex_phase_[out_idx];
|
||||
out_idx++;
|
||||
}
|
||||
|
||||
ms_counter_[sat] = (ms_counter_[sat] + (int)round(1e3*Galileo_E1_CODE_PERIOD))
|
||||
% data_bit_duration_ms_[sat];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int delay_samples = (delay_chips_[sat] % (int)Galileo_E1_B_CODE_LENGTH_CHIPS)
|
||||
* samples_per_code_[sat] / Galileo_E1_B_CODE_LENGTH_CHIPS;
|
||||
|
||||
for (i = 0; i < num_of_codes_per_vector_[sat]; i++)
|
||||
{
|
||||
for (k = 0; k < delay_samples; k++)
|
||||
{
|
||||
out[out_idx] += (sampled_code_data_[sat][out_idx] * current_data_bits_[sat]
|
||||
- sampled_code_pilot_[sat][out_idx])
|
||||
* complex_phase_[out_idx];
|
||||
out_idx++;
|
||||
}
|
||||
|
||||
if (ms_counter_[sat] == 0 && data_flag_)
|
||||
{
|
||||
// New random data bit
|
||||
current_data_bits_[sat] = gr_complex((rand()%2) == 0 ? 1 : -1, 0);
|
||||
}
|
||||
|
||||
for (k = delay_samples; k < samples_per_code_[sat]; k++)
|
||||
{
|
||||
out[out_idx] += (sampled_code_data_[sat][out_idx] * current_data_bits_[sat]
|
||||
- sampled_code_pilot_[sat][out_idx])
|
||||
* complex_phase_[out_idx];
|
||||
out_idx++;
|
||||
}
|
||||
|
||||
|
||||
ms_counter_[sat] = (ms_counter_[sat] + (int)round(1e3*Galileo_E1_CODE_PERIOD))
|
||||
% data_bit_duration_ms_[sat];
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -334,4 +422,3 @@ int signal_generator_c::general_work (int noutput_items,
|
||||
// Tell runtime system how many output items we produced.
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -38,42 +38,39 @@
|
||||
#include <gnuradio/block.h>
|
||||
#include "gnss_signal.h"
|
||||
|
||||
|
||||
|
||||
|
||||
class signal_generator_c;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* to gr_blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues.
|
||||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
*/
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* to gr_blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues.
|
||||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<signal_generator_c> signal_generator_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of gen_source.
|
||||
*
|
||||
* To avoid accidental use of raw pointers, gen_source's
|
||||
* constructor is private. signal_make_generator_c is the public
|
||||
* interface for creating new instances.
|
||||
*/
|
||||
* \brief Return a shared_ptr to a new instance of gen_source.
|
||||
*
|
||||
* To avoid accidental use of raw pointers, gen_source's
|
||||
* constructor is private. signal_make_generator_c is the public
|
||||
* interface for creating new instances.
|
||||
*/
|
||||
signal_generator_c_sptr
|
||||
signal_make_generator_c (std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
signal_make_generator_c (std::vector<std::string> signal1, std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz,
|
||||
const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag,
|
||||
const std::vector<unsigned int> &delay_chips,const std::vector<unsigned int> &delay_sec, bool data_flag, bool noise_flag,
|
||||
unsigned int fs_in, unsigned int vector_length, float BW_BB);
|
||||
|
||||
/*!
|
||||
* \brief This class generates synthesized GNSS signal.
|
||||
* \ingroup block
|
||||
*
|
||||
* \sa gen_source for a version that subclasses gr_block.
|
||||
*/
|
||||
* \brief This class generates synthesized GNSS signal.
|
||||
* \ingroup block
|
||||
*
|
||||
* \sa gen_source for a version that subclasses gr_block.
|
||||
*/
|
||||
class signal_generator_c : public gr::block
|
||||
{
|
||||
private:
|
||||
@ -82,24 +79,26 @@ private:
|
||||
|
||||
/* Create the signal_generator_c object*/
|
||||
friend signal_generator_c_sptr
|
||||
signal_make_generator_c (std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
signal_make_generator_c (std::vector<std::string> signal1, std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz,
|
||||
const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag,
|
||||
const std::vector<unsigned int> &delay_chips,const std::vector<unsigned int> &delay_sec, bool data_flag, bool noise_flag,
|
||||
unsigned int fs_in, unsigned int vector_length, float BW_BB);
|
||||
|
||||
signal_generator_c (std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
signal_generator_c (std::vector<std::string> signal1, std::vector<std::string> system, const std::vector<unsigned int> &PRN,
|
||||
const std::vector<float> &CN0_dB, const std::vector<float> &doppler_Hz,
|
||||
const std::vector<unsigned int> &delay_chips, bool data_flag, bool noise_flag,
|
||||
const std::vector<unsigned int> &delay_chips,const std::vector<unsigned int> &delay_sec, bool data_flag, bool noise_flag,
|
||||
unsigned int fs_in, unsigned int vector_length, float BW_BB);
|
||||
|
||||
void init();
|
||||
void generate_codes();
|
||||
|
||||
std::vector<std::string> signal_;
|
||||
std::vector<std::string> system_;
|
||||
std::vector<unsigned int> PRN_;
|
||||
std::vector<float> CN0_dB_;
|
||||
std::vector<float> doppler_Hz_;
|
||||
std::vector<unsigned int> delay_chips_;
|
||||
std::vector<unsigned int> delay_sec_;
|
||||
bool data_flag_;
|
||||
bool noise_flag_;
|
||||
unsigned int fs_in_;
|
||||
@ -113,12 +112,17 @@ private:
|
||||
std::vector<unsigned int> ms_counter_;
|
||||
std::vector<float> start_phase_rad_;
|
||||
std::vector<gr_complex> current_data_bits_;
|
||||
std::vector<signed int> current_data_bit_int_;
|
||||
std::vector<signed int> data_modulation_;
|
||||
std::vector<signed int> pilot_modulation_;
|
||||
|
||||
boost::scoped_array<gr_complex*> sampled_code_data_;
|
||||
boost::scoped_array<gr_complex*> sampled_code_pilot_;
|
||||
gr::random* random_;
|
||||
gr_complex* complex_phase_;
|
||||
|
||||
unsigned int work_counter_;
|
||||
|
||||
public:
|
||||
~signal_generator_c (); // public destructor
|
||||
|
||||
@ -131,3 +135,4 @@ public:
|
||||
};
|
||||
|
||||
#endif /* GNSS_SDR_SIGNAL_GENERATOR_C_H */
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
# Optional drivers
|
||||
|
||||
if($ENV{GN3S_DRIVER})
|
||||
if(ENABLE_GN3S)
|
||||
##############################################
|
||||
# GN3S (USB dongle)
|
||||
##############################################
|
||||
@ -49,12 +49,10 @@ if($ENV{GN3S_DRIVER})
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/firmware/GN3S_v2/bin/gn3s_firmware.ihx
|
||||
DESTINATION ${CMAKE_SOURCE_DIR}/install/
|
||||
)
|
||||
endif($ENV{GN3S_DRIVER})
|
||||
endif(ENABLE_GN3S)
|
||||
|
||||
if($ENV{RAW_ARRAY_DRIVER})
|
||||
set(RAW_ARRAY_DRIVER ON)
|
||||
endif($ENV{RAW_ARRAY_DRIVER})
|
||||
if(RAW_ARRAY_DRIVER)
|
||||
|
||||
if(ENABLE_ARRAY)
|
||||
##############################################
|
||||
# GRDBFCTTC GNSS EXPERIMENTAL ARRAY PROTOTYPE
|
||||
##############################################
|
||||
@ -82,13 +80,10 @@ if(RAW_ARRAY_DRIVER)
|
||||
set(OPT_LIBRARIES ${OPT_LIBRARIES} ${GRDBFCTTC_LIBRARIES})
|
||||
set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${GRDBFCTTC_INCLUDE_DIRS})
|
||||
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} raw_array_signal_source.cc)
|
||||
endif(RAW_ARRAY_DRIVER)
|
||||
endif(ENABLE_ARRAY)
|
||||
|
||||
|
||||
if($ENV{RTLSDR_DRIVER})
|
||||
set(RTLSDR_DRIVER ON)
|
||||
endif($ENV{RTLSDR_DRIVER})
|
||||
if(RTLSDR_DRIVER)
|
||||
if(ENABLE_RTLSDR)
|
||||
################################################################################
|
||||
# OsmoSDR - http://sdr.osmocom.org/trac/
|
||||
################################################################################
|
||||
@ -104,7 +99,7 @@ if(RTLSDR_DRIVER)
|
||||
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} rtlsdr_signal_source.cc)
|
||||
set(OPT_LIBRARIES ${OPT_LIBRARIES} ${GROSMOSDR_LIBRARIES})
|
||||
set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${RTL_DRIVER_INCLUDE_DIRS})
|
||||
endif(RTLSDR_DRIVER)
|
||||
endif(ENABLE_RTLSDR)
|
||||
|
||||
set(SIGNAL_SOURCE_ADAPTER_SOURCES file_signal_source.cc
|
||||
gen_signal_source.cc
|
||||
|
@ -20,6 +20,7 @@ set(TELEMETRY_DECODER_ADAPTER_SOURCES
|
||||
gps_l1_ca_telemetry_decoder.cc
|
||||
galileo_e1b_telemetry_decoder.cc
|
||||
sbas_l1_telemetry_decoder.cc
|
||||
galileo_e5a_telemetry_decoder.cc
|
||||
)
|
||||
|
||||
include_directories(
|
||||
@ -29,6 +30,7 @@ include_directories(
|
||||
${CMAKE_SOURCE_DIR}/src/core/receiver
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/gnuradio_blocks
|
||||
${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/libs
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${GLOG_INCLUDE_DIRS}
|
||||
${GFlags_INCLUDE_DIRS}
|
||||
${GNURADIO_RUNTIME_INCLUDE_DIRS}
|
||||
@ -37,4 +39,4 @@ include_directories(
|
||||
file(GLOB TELEMETRY_DECODER_ADAPTER_HEADERS "*.h")
|
||||
add_library(telemetry_decoder_adapters ${TELEMETRY_DECODER_ADAPTER_SOURCES} ${TELEMETRY_DECODER_ADAPTER_HEADERS})
|
||||
source_group(Headers FILES ${TELEMETRY_DECODER_ADAPTER_HEADERS})
|
||||
target_link_libraries(telemetry_decoder_adapters telemetry_decoder_gr_blocks)
|
||||
target_link_libraries(telemetry_decoder_adapters telemetry_decoder_gr_blocks ${GNURADIO_RUNTIME_LIBRARIES})
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include "telemetry_decoder_interface.h"
|
||||
#include "galileo_e1b_telemetry_decoder_cc.h"
|
||||
#include "gnss_satellite.h"
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,122 @@
|
||||
/*!
|
||||
* \file galileo_e5a_telemetry_decoder.h
|
||||
* \brief Interface of an adapter of a GALILEO E5a FNAV data decoder block
|
||||
* to a TelemetryDecoderInterface
|
||||
* \author Marc Sales, 2014. marcsales92(at)gmail.com
|
||||
* \based on work from:
|
||||
* <ul>
|
||||
* <li> Javier Arribas, 2011. jarribas(at)cttc.es
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "galileo_e5a_telemetry_decoder.h"
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <glog/logging.h>
|
||||
#include "galileo_ephemeris.h"
|
||||
#include "galileo_almanac.h"
|
||||
#include "galileo_iono.h"
|
||||
#include "galileo_utc_model.h"
|
||||
#include "configuration_interface.h"
|
||||
|
||||
|
||||
extern concurrent_queue<Galileo_Ephemeris> global_galileo_ephemeris_queue;
|
||||
extern concurrent_queue<Galileo_Iono> global_galileo_iono_queue;
|
||||
extern concurrent_queue<Galileo_Utc_Model> global_galileo_utc_model_queue;
|
||||
extern concurrent_queue<Galileo_Almanac> global_galileo_almanac_queue;
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
GalileoE5aTelemetryDecoder::GalileoE5aTelemetryDecoder(ConfigurationInterface* configuration,
|
||||
std::string role,
|
||||
unsigned int in_streams,
|
||||
unsigned int out_streams,
|
||||
boost::shared_ptr<gr::msg_queue> queue) :
|
||||
role_(role),
|
||||
in_streams_(in_streams),
|
||||
out_streams_(out_streams),
|
||||
queue_(queue)
|
||||
{
|
||||
std::string default_item_type = "gr_complex";
|
||||
std::string default_dump_filename = "./navigation.dat";
|
||||
DLOG(INFO) << "role " << role;
|
||||
DLOG(INFO) << "vector length " << vector_length_;
|
||||
vector_length_ = configuration->property(role + ".vector_length", 2048);
|
||||
dump_ = configuration->property(role + ".dump", false);
|
||||
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||
int fs_in;
|
||||
fs_in = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
|
||||
// make telemetry decoder object
|
||||
telemetry_decoder_ = galileo_e5a_make_telemetry_decoder_cc(satellite_, 0, (long)fs_in, vector_length_, queue_, dump_); // TODO fix me
|
||||
DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")";
|
||||
// set the navigation msg queue;
|
||||
telemetry_decoder_->set_ephemeris_queue(&global_galileo_ephemeris_queue);
|
||||
telemetry_decoder_->set_iono_queue(&global_galileo_iono_queue);
|
||||
telemetry_decoder_->set_almanac_queue(&global_galileo_almanac_queue);
|
||||
telemetry_decoder_->set_utc_model_queue(&global_galileo_utc_model_queue);
|
||||
|
||||
DLOG(INFO) << "global navigation message queue assigned to telemetry_decoder ("<< telemetry_decoder_->unique_id() << ")";
|
||||
}
|
||||
|
||||
|
||||
GalileoE5aTelemetryDecoder::~GalileoE5aTelemetryDecoder()
|
||||
{}
|
||||
|
||||
|
||||
void GalileoE5aTelemetryDecoder::set_satellite(Gnss_Satellite satellite)
|
||||
{
|
||||
satellite_ = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
||||
telemetry_decoder_->set_satellite(satellite_);
|
||||
DLOG(INFO) << "TELEMETRY DECODER: satellite set to " << satellite_;
|
||||
}
|
||||
|
||||
|
||||
void GalileoE5aTelemetryDecoder::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
// Nothing to connect internally
|
||||
DLOG(INFO) << "nothing to connect internally";
|
||||
}
|
||||
|
||||
|
||||
void GalileoE5aTelemetryDecoder::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
// Nothing to disconnect
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr GalileoE5aTelemetryDecoder::get_left_block()
|
||||
{
|
||||
return telemetry_decoder_;
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr GalileoE5aTelemetryDecoder::get_right_block()
|
||||
{
|
||||
return telemetry_decoder_;
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
/*!
|
||||
* \file galileo_e5a_telemetry_decoder.h
|
||||
* \brief Interface of an adapter of a GALILEO E5a FNAV data decoder block
|
||||
* to a TelemetryDecoderInterface
|
||||
* \author Marc Sales, 2014. marcsales92(at)gmail.com
|
||||
* \based on work from:
|
||||
* <ul>
|
||||
* <li> Javier Arribas, 2011. jarribas(at)cttc.es
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_H_
|
||||
#define GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_H_
|
||||
|
||||
#include <string>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include "telemetry_decoder_interface.h"
|
||||
#include "galileo_e5a_telemetry_decoder_cc.h"
|
||||
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
* \brief This class implements a NAV data decoder for Galileo INAV frames in E1B radio link
|
||||
*/
|
||||
class GalileoE5aTelemetryDecoder: public TelemetryDecoderInterface
|
||||
{
|
||||
public:
|
||||
GalileoE5aTelemetryDecoder(ConfigurationInterface* configuration,
|
||||
std::string role,
|
||||
unsigned int in_streams,
|
||||
unsigned int out_streams,
|
||||
boost::shared_ptr<gr::msg_queue> queue);
|
||||
|
||||
virtual ~GalileoE5aTelemetryDecoder();
|
||||
std::string role()
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Galileo_E5a_Telemetry_Decoder"
|
||||
*/
|
||||
std::string implementation()
|
||||
{
|
||||
return "Galileo_E5A_Telemetry_Decoder";
|
||||
}
|
||||
void connect(gr::top_block_sptr top_block);
|
||||
void disconnect(gr::top_block_sptr top_block);
|
||||
gr::basic_block_sptr get_left_block();
|
||||
gr::basic_block_sptr get_right_block();
|
||||
void set_satellite(Gnss_Satellite satellite);
|
||||
void set_channel(int channel){telemetry_decoder_->set_channel(channel);}
|
||||
void reset()
|
||||
{
|
||||
return;
|
||||
}
|
||||
size_t item_size()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
galileo_e5a_telemetry_decoder_cc_sptr telemetry_decoder_;
|
||||
Gnss_Satellite satellite_;
|
||||
int channel_;
|
||||
unsigned int vector_length_;
|
||||
std::string item_type_;
|
||||
bool dump_;
|
||||
std::string dump_filename_;
|
||||
std::string role_;
|
||||
unsigned int in_streams_;
|
||||
unsigned int out_streams_;
|
||||
boost::shared_ptr<gr::msg_queue> queue_;
|
||||
};
|
||||
|
||||
#endif /* GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_H_ */
|
@ -75,6 +75,10 @@ GpsL1CaTelemetryDecoder::GpsL1CaTelemetryDecoder(ConfigurationInterface* configu
|
||||
telemetry_decoder_->set_iono_queue(&global_gps_iono_queue);
|
||||
telemetry_decoder_->set_almanac_queue(&global_gps_almanac_queue);
|
||||
telemetry_decoder_->set_utc_model_queue(&global_gps_utc_model_queue);
|
||||
|
||||
//decimation factor
|
||||
int decimation_factor=configuration->property(role + ".decimation_factor", 1);
|
||||
telemetry_decoder_->set_decimation(decimation_factor);
|
||||
DLOG(INFO) << "global navigation message queue assigned to telemetry_decoder ("<< telemetry_decoder_->unique_id() << ")";
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ set(TELEMETRY_DECODER_GR_BLOCKS_SOURCES
|
||||
gps_l1_ca_telemetry_decoder_cc.cc
|
||||
galileo_e1b_telemetry_decoder_cc.cc
|
||||
sbas_l1_telemetry_decoder_cc.cc
|
||||
galileo_e5a_telemetry_decoder_cc.cc
|
||||
)
|
||||
|
||||
include_directories(
|
||||
@ -36,4 +37,4 @@ include_directories(
|
||||
file(GLOB TELEMETRY_DECODER_GR_BLOCKS_HEADERS "*.h")
|
||||
add_library(telemetry_decoder_gr_blocks ${TELEMETRY_DECODER_GR_BLOCKS_SOURCES} ${TELEMETRY_DECODER_GR_BLOCKS_HEADERS})
|
||||
source_group(Headers FILES ${TELEMETRY_DECODER_GR_BLOCKS_HEADERS})
|
||||
target_link_libraries(telemetry_decoder_gr_blocks telemetry_decoder_lib gnss_system_parameters)
|
||||
target_link_libraries(telemetry_decoder_gr_blocks telemetry_decoder_lib gnss_system_parameters ${GNURADIO_RUNTIME_LIBRARIES})
|
||||
|
@ -169,7 +169,7 @@ galileo_e1b_telemetry_decoder_cc::galileo_e1b_telemetry_decoder_cc(
|
||||
d_flag_parity = false;
|
||||
d_TOW_at_Preamble = 0;
|
||||
d_TOW_at_current_symbol = 0;
|
||||
|
||||
delta_t = 0;
|
||||
d_CRC_error_counter = 0;
|
||||
}
|
||||
|
||||
@ -193,7 +193,7 @@ void galileo_e1b_telemetry_decoder_cc::decode_word(double *page_part_symbols,int
|
||||
|
||||
// 2. Viterbi decoder
|
||||
// 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder)
|
||||
// 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180¼
|
||||
// 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180<EFBFBD>
|
||||
for (int i = 0; i < frame_length; i++)
|
||||
{
|
||||
if ((i + 1) % 2 == 0)
|
||||
@ -262,6 +262,23 @@ void galileo_e1b_telemetry_decoder_cc::decode_word(double *page_part_symbols,int
|
||||
//std::cout<<"New Galileo UTC model received for SV "<<d_satellite.get_PRN()<<std::endl;
|
||||
d_utc_model_queue->push(utc_model);
|
||||
}
|
||||
if (d_nav.have_new_almanac()==true)
|
||||
{
|
||||
Galileo_Almanac almanac=d_nav.get_almanac();
|
||||
d_almanac_queue->push(almanac);
|
||||
//debug
|
||||
std::cout << "Almanac received!" << std::endl;
|
||||
LOG(INFO) << "GPS_to_Galileo time conversion:";
|
||||
LOG(INFO) << "A0G=" << almanac.A_0G_10;
|
||||
LOG(INFO) << "A1G=" << almanac.A_1G_10;
|
||||
LOG(INFO) << "T0G=" << almanac.t_0G_10;
|
||||
LOG(INFO) << "WN_0G_10=" << almanac.WN_0G_10;
|
||||
LOG(INFO) << "Current parameters:";
|
||||
LOG(INFO) << "d_TOW_at_current_symbol="<< d_TOW_at_current_symbol;
|
||||
LOG(INFO) << "d_nav.WN_0=" << d_nav.WN_0;
|
||||
delta_t = almanac.A_0G_10 + almanac.A_1G_10 * (d_TOW_at_current_symbol - almanac.t_0G_10 + 604800 * (fmod((d_nav.WN_0 - almanac.WN_0G_10), 64)));
|
||||
LOG(INFO) << "delta_t=" << delta_t << "[s]";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -396,6 +413,10 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
|
||||
//2. Add the telemetry decoder information
|
||||
if (this->d_flag_preamble == true and d_nav.flag_TOW_set == true)
|
||||
//update TOW at the preamble instant
|
||||
// JAVI: 30/06/2014
|
||||
// TOW, in Galileo, is referred to the START of the PAGE PART, that is, THE FIRST SYMBOL OF THAT PAGE, NOT THE PREAMBLE.
|
||||
// thus, no correction should be done. d_TOW_at_Preamble should be renamed to d_TOW_at_page_start.
|
||||
// Sice we detected the preable, then, we are in the last symbol of that preable, or just at the start of the first page symbol.
|
||||
//flag preamble is true after the all page (even and odd) is recevived. I/NAV page period is 2 SECONDS
|
||||
{
|
||||
Prn_timestamp_at_preamble_ms = in[0][0].Tracking_timestamp_secs * 1000.0;
|
||||
@ -406,7 +427,7 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
|
||||
/* 1 sec (GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD) is added because
|
||||
* if we have a TOW value it means that we are at the begining of the last page part
|
||||
* (GNU Radio history keeps in a buffer the rest of the incomming frame part)*/
|
||||
d_TOW_at_current_symbol = d_TOW_at_Preamble;// + GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD;
|
||||
d_TOW_at_current_symbol=d_TOW_at_Preamble;//-GALIELO_E1_CODE_PERIOD;//+ (double)GALILEO_INAV_PREAMBLE_LENGTH_BITS/(double)GALILEO_TELEMETRY_RATE_BITS_SECOND;
|
||||
d_nav.flag_TOW_5 = false;
|
||||
}
|
||||
|
||||
@ -418,14 +439,15 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
|
||||
/* 1 sec (GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD) is added because
|
||||
* if we have a TOW value it means that we are at the begining of the last page part
|
||||
* (GNU Radio history keeps in a buffer the rest of the incomming frame part)*/
|
||||
d_TOW_at_current_symbol = d_TOW_at_Preamble;// + GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD;
|
||||
d_TOW_at_current_symbol=d_TOW_at_Preamble;//-GALIELO_E1_CODE_PERIOD;//+ (double)GALILEO_INAV_PREAMBLE_LENGTH_BITS/(double)GALILEO_TELEMETRY_RATE_BITS_SECOND;
|
||||
d_nav.flag_TOW_6 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//this page has no timming information
|
||||
//this page has no timing information
|
||||
d_TOW_at_Preamble = d_TOW_at_Preamble + GALILEO_INAV_PAGE_SECONDS;
|
||||
d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALIELO_E1_CODE_PERIOD;// + GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -435,6 +457,14 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
|
||||
}
|
||||
|
||||
//if (d_flag_frame_sync == true and d_nav.flag_TOW_set==true and d_nav.flag_CRC_test == true)
|
||||
|
||||
if(d_nav.flag_GGTO_1 == true and d_nav.flag_GGTO_2 == true and d_nav.flag_GGTO_3 == true and d_nav.flag_GGTO_4 == true) //all GGTO parameters arrived
|
||||
{
|
||||
delta_t=d_nav.A_0G_10+d_nav.A_1G_10*(d_TOW_at_current_symbol-d_nav.t_0G_10+604800.0*(fmod((d_nav.WN_0-d_nav.WN_0G_10),64)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (d_flag_frame_sync == true and d_nav.flag_TOW_set == true)
|
||||
{
|
||||
current_synchro_data.Flag_valid_word = true;
|
||||
@ -444,9 +474,13 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
|
||||
current_synchro_data.Flag_valid_word = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
current_synchro_data.d_TOW = d_TOW_at_Preamble;
|
||||
current_synchro_data.d_TOW_at_current_symbol = d_TOW_at_current_symbol;
|
||||
current_synchro_data.Flag_preamble = d_flag_preamble;
|
||||
current_synchro_data.d_TOW_hybrid_at_current_symbol= current_synchro_data.d_TOW_at_current_symbol - delta_t; //delta_t = t_gal - t_gps ----> t_gps = t_gal -delta_t
|
||||
DLOG(INFO)<< "delta_t = " << delta_t << std::endl;
|
||||
current_synchro_data.Flag_preamble = d_flag_preamble;
|
||||
current_synchro_data.Prn_timestamp_ms = in[0][0].Tracking_timestamp_secs * 1000.0;
|
||||
current_synchro_data.Prn_timestamp_at_preamble_ms = Prn_timestamp_at_preamble_ms;
|
||||
|
||||
@ -470,6 +504,8 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
|
||||
}
|
||||
//3. Make the output (copy the object contents to the GNURadio reserved memory)
|
||||
*out[0] = current_synchro_data;
|
||||
|
||||
//std::cout<<"Galileo TLM output on CH="<<this->d_channel << " SAMPLE STAMP="<<d_sample_counter<<std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -136,8 +136,11 @@ private:
|
||||
|
||||
double d_TOW_at_Preamble;
|
||||
double d_TOW_at_current_symbol;
|
||||
|
||||
double Prn_timestamp_at_preamble_ms;
|
||||
bool flag_TOW_set;
|
||||
double delta_t; //GPS-GALILEO time offset
|
||||
|
||||
|
||||
std::string d_dump_filename;
|
||||
std::ofstream d_dump_file;
|
||||
|
@ -0,0 +1,637 @@
|
||||
/*!
|
||||
* \file galileo_e5a_telemetry_decoder_cc.cc
|
||||
* \brief Implementation of a Galileo FNAV message demodulator block
|
||||
* \author Marc Sales, 2014. marcsales92(at)gmail.com
|
||||
* \based on work from:
|
||||
* <ul>
|
||||
* <li> Javier Arribas, 2011. jarribas(at)cttc.es
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "galileo_e5a_telemetry_decoder_cc.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <glog/logging.h>
|
||||
#include "control_message_factory.h"
|
||||
//#include "galileo_navigation_message.h"
|
||||
#include "galileo_fnav_message.h"
|
||||
#include "gnss_synchro.h"
|
||||
#include "convolutional.h"
|
||||
//#include <volk/volk.h>
|
||||
//#include "galileo_e1b_telemetry_decoder_cc.h"
|
||||
|
||||
#define CRC_ERROR_LIMIT 6
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
|
||||
galileo_e5a_telemetry_decoder_cc_sptr
|
||||
galileo_e5a_make_telemetry_decoder_cc(Gnss_Satellite satellite, long if_freq, long fs_in, unsigned
|
||||
int vector_length, boost::shared_ptr<gr::msg_queue> queue, bool dump)
|
||||
{
|
||||
return galileo_e5a_telemetry_decoder_cc_sptr(new galileo_e5a_telemetry_decoder_cc(satellite, if_freq,
|
||||
fs_in, vector_length, queue, dump));
|
||||
}
|
||||
|
||||
void galileo_e5a_telemetry_decoder_cc::forecast (int noutput_items, gr_vector_int &ninput_items_required)
|
||||
{
|
||||
//ninput_items_required[0] = GALILEO_FNAV_SAMPLES_PER_PAGE; // set the required sample history
|
||||
ninput_items_required[0] = GALILEO_FNAV_CODES_PER_PREAMBLE;
|
||||
}
|
||||
|
||||
void galileo_e5a_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols, int *page_part_bits)
|
||||
{
|
||||
// int CodeLength = 240;
|
||||
int CodeLength = 488;
|
||||
int DataLength;
|
||||
int nn, KK, mm, max_states;
|
||||
int g_encoder[2];
|
||||
|
||||
nn = 2; // Coding rate 1/n
|
||||
KK = 7; // Constraint Length
|
||||
g_encoder[0] = 121; // Polynomial G1
|
||||
g_encoder[1] = 91; // Polynomial G2
|
||||
// g_encoder[0] = 171; // Polynomial G1
|
||||
// g_encoder[1] = 133; // Polynomial G2
|
||||
|
||||
mm = KK - 1;
|
||||
max_states = 1 << mm; // 2^mm
|
||||
DataLength = (CodeLength/nn) - mm;
|
||||
|
||||
//create appropriate transition matrices
|
||||
|
||||
int *out0, *out1, *state0, *state1;
|
||||
out0 = (int*)calloc( max_states, sizeof(int) );
|
||||
out1 = (int*)calloc( max_states, sizeof(int) );
|
||||
state0 = (int*)calloc( max_states, sizeof(int) );
|
||||
state1 = (int*)calloc( max_states, sizeof(int) );
|
||||
|
||||
nsc_transit( out0, state0, 0, g_encoder, KK, nn );
|
||||
nsc_transit( out1, state1, 1, g_encoder, KK, nn );
|
||||
|
||||
Viterbi(page_part_bits, out0, state0, out1, state1,
|
||||
page_part_symbols, KK, nn, DataLength );
|
||||
|
||||
//Clean up memory
|
||||
free( out0 );
|
||||
free( out1 );
|
||||
free( state0 );
|
||||
free( state1 );
|
||||
}
|
||||
|
||||
|
||||
void galileo_e5a_telemetry_decoder_cc::deinterleaver(int rows, int cols, double *in, double *out)
|
||||
{
|
||||
for (int r = 0; r < rows; r++)
|
||||
{
|
||||
for(int c = 0; c < cols; c++)
|
||||
{
|
||||
out[c*rows + r] = in[r*cols + c];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void galileo_e5a_telemetry_decoder_cc::decode_word(double *page_symbols,int frame_length)
|
||||
{
|
||||
double page_symbols_deint[frame_length];
|
||||
// 1. De-interleave
|
||||
|
||||
galileo_e5a_telemetry_decoder_cc::deinterleaver(GALILEO_FNAV_INTERLEAVER_ROWS, GALILEO_FNAV_INTERLEAVER_COLS, page_symbols, page_symbols_deint);
|
||||
|
||||
// 2. Viterbi decoder
|
||||
// 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder)
|
||||
// 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180<38>
|
||||
for (int i = 0; i < frame_length; i++)
|
||||
{
|
||||
if ((i + 1) % 2 == 0)
|
||||
{
|
||||
page_symbols_deint[i] = -page_symbols_deint[i];
|
||||
}
|
||||
}
|
||||
int page_bits[frame_length/2];
|
||||
galileo_e5a_telemetry_decoder_cc::viterbi_decoder(page_symbols_deint, page_bits);
|
||||
|
||||
// 3. Call the Galileo page decoder
|
||||
std::string page_String;
|
||||
for(int i = 0; i < frame_length; i++)
|
||||
{
|
||||
if (page_bits[i] > 0)
|
||||
{
|
||||
page_String.push_back('1');
|
||||
}
|
||||
else
|
||||
{
|
||||
page_String.push_back('0');
|
||||
}
|
||||
}
|
||||
|
||||
// DECODE COMPLETE WORD (even + odd) and TEST CRC
|
||||
d_nav.split_page(page_String);
|
||||
if(d_nav.flag_CRC_test == true)
|
||||
{
|
||||
LOG(INFO) << "Galileo CRC correct on channel " << d_channel;
|
||||
std::cout << "Galileo CRC correct on channel " << d_channel << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Galileo CRC error on channel " << d_channel << std::endl;
|
||||
LOG(INFO)<< "Galileo CRC error on channel " << d_channel;
|
||||
}
|
||||
|
||||
// 4. Push the new navigation data to the queues
|
||||
if (d_nav.have_new_ephemeris() == true)
|
||||
{
|
||||
// get ephemeris object for this SV
|
||||
Galileo_Ephemeris ephemeris = d_nav.get_ephemeris();//notice that the read operation will clear the valid flag
|
||||
//std::cout<<"New Galileo Ephemeris received for SV "<<d_satellite.get_PRN()<<std::endl;
|
||||
d_ephemeris_queue->push(ephemeris);
|
||||
}
|
||||
if (d_nav.have_new_iono_and_GST() == true)
|
||||
{
|
||||
Galileo_Iono iono = d_nav.get_iono(); //notice that the read operation will clear the valid flag
|
||||
//std::cout<<"New Galileo IONO model (and UTC) received for SV "<<d_satellite.get_PRN()<<std::endl;
|
||||
d_iono_queue->push(iono);
|
||||
}
|
||||
if (d_nav.have_new_utc_model() == true)
|
||||
{
|
||||
Galileo_Utc_Model utc_model = d_nav.get_utc_model(); //notice that the read operation will clear the valid flag
|
||||
//std::cout<<"New Galileo UTC model received for SV "<<d_satellite.get_PRN()<<std::endl;
|
||||
d_utc_model_queue->push(utc_model);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
galileo_e5a_telemetry_decoder_cc::galileo_e5a_telemetry_decoder_cc(
|
||||
Gnss_Satellite satellite,
|
||||
long if_freq,
|
||||
long fs_in,
|
||||
unsigned
|
||||
int vector_length,
|
||||
boost::shared_ptr<gr::msg_queue> queue,
|
||||
bool dump) :
|
||||
gr::block("galileo_e5a_telemetry_decoder_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
|
||||
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
|
||||
{
|
||||
// initialize internal vars
|
||||
d_queue = queue;
|
||||
d_dump = dump;
|
||||
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
||||
LOG(INFO) << "GALILEO E5A TELEMETRY PROCESSING: satellite " << d_satellite;
|
||||
d_vector_length = vector_length;
|
||||
//d_samples_per_symbol = ( Galileo_E5a_CODE_CHIP_RATE_HZ / Galileo_E5a_CODE_LENGTH_CHIPS ) / Galileo_E1_B_SYMBOL_RATE_BPS;
|
||||
d_fs_in = fs_in;
|
||||
|
||||
// set the preamble
|
||||
//unsigned short int preambles_bits[GALILEO_FNAV_PREAMBLE_LENGTH_BITS] = GALILEO_FNAV_PREAMBLE;
|
||||
for (int i = 0; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++)
|
||||
{
|
||||
if (GALILEO_FNAV_PREAMBLE.at(i) == '0')
|
||||
{
|
||||
d_preamble_bits[i] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_preamble_bits[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// memcpy((unsigned short int*)this->d_preambles_bits, (unsigned short int*)preambles_bits, GALILEO_FNAV_PREAMBLE_LENGTH_BITS*sizeof(unsigned short int));
|
||||
|
||||
// // preamble bits to sampled symbols
|
||||
// d_preambles_symbols = (signed int*)malloc(sizeof(signed int) * GALILEO_FNAV_SAMPLES_PER_PREAMBLE);
|
||||
// int n = 0;
|
||||
// for (int i = 0; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++)
|
||||
// {
|
||||
// for (unsigned int j = 0; j < GALILEO_FNAV_SAMPLES_PER_SYMBOL; j++)
|
||||
// {
|
||||
// if (d_preambles_bits[i] == 1)
|
||||
// {
|
||||
// d_preambles_symbols[n] = 1;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// d_preambles_symbols[n] = -1;
|
||||
// }
|
||||
// n++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
d_sample_counter = 0;
|
||||
d_state = 0;
|
||||
d_preamble_lock=false;
|
||||
d_preamble_index = 0;
|
||||
d_preamble_time_seconds = 0;
|
||||
d_flag_frame_sync = false;
|
||||
d_current_symbol = 0;
|
||||
d_prompt_counter = 0;
|
||||
d_symbol_counter = 0;
|
||||
|
||||
d_TOW_at_Preamble = 0;
|
||||
d_TOW_at_current_symbol = 0;
|
||||
|
||||
d_CRC_error_counter = 0;
|
||||
d_sign_init = 0;
|
||||
}
|
||||
|
||||
galileo_e5a_telemetry_decoder_cc::~galileo_e5a_telemetry_decoder_cc()
|
||||
{
|
||||
d_dump_file.close();
|
||||
}
|
||||
|
||||
int galileo_e5a_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
|
||||
{
|
||||
//
|
||||
const Gnss_Synchro **in = (const Gnss_Synchro **) &input_items[0]; //Get the input samples pointer
|
||||
Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0];
|
||||
|
||||
/* Terminology: Prompt: output from tracking Prompt correlator (Prompt samples)
|
||||
* Symbol: encoded navigation bits. 1 symbol = 20 samples in E5a
|
||||
* Bit: decoded navigation bits forming words as described in Galileo ICD
|
||||
* States: 0 Receiving dummy samples.
|
||||
* 1 Preamble not locked
|
||||
* 3 Preamble lock
|
||||
*/
|
||||
switch (d_state)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (in[0][0].Prompt_I != 0)
|
||||
{
|
||||
d_current_symbol += in[0][0].Prompt_I;
|
||||
if (d_prompt_counter == GALILEO_FNAV_CODES_PER_SYMBOL - 1)
|
||||
{
|
||||
if (d_current_symbol > 0)
|
||||
{
|
||||
d_page_symbols[d_symbol_counter] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_page_symbols[d_symbol_counter] = -1;
|
||||
}
|
||||
d_current_symbol = 0;
|
||||
d_symbol_counter++;
|
||||
d_prompt_counter = 0;
|
||||
if (d_symbol_counter == GALILEO_FNAV_PREAMBLE_LENGTH_BITS-1)
|
||||
{
|
||||
d_state = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
d_prompt_counter++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
d_current_symbol += in[0][0].Prompt_I;
|
||||
if (d_prompt_counter == GALILEO_FNAV_CODES_PER_SYMBOL - 1)
|
||||
{
|
||||
if (d_current_symbol > 0)
|
||||
{
|
||||
d_page_symbols[d_symbol_counter] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_page_symbols[d_symbol_counter] = -1;
|
||||
}
|
||||
// d_page_symbols[d_symbol_counter] = d_current_symbol_float/(float)GALILEO_FNAV_CODES_PER_SYMBOL;
|
||||
d_current_symbol = 0;
|
||||
d_symbol_counter++;
|
||||
d_prompt_counter = 0;
|
||||
// **** Attempt Preamble correlation ****
|
||||
bool corr_flag=true;
|
||||
int corr_sign = 0; // sequence can be found inverted
|
||||
// corr_sign = d_preamble_bits[0] * d_page_symbols[d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS];
|
||||
// for (int i = 1; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++)
|
||||
// {
|
||||
// if ((d_preamble_bits[i] * d_page_symbols[i + d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS]) != corr_sign)
|
||||
// {
|
||||
// //exit for if one bit doesn't correlate
|
||||
// corr_flag=false;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// check if the preamble starts positive correlated or negative correlated
|
||||
if (d_page_symbols[d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS] < 0) // symbols clipping
|
||||
{
|
||||
corr_sign=-d_preamble_bits[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
corr_sign=d_preamble_bits[0];
|
||||
}
|
||||
// the preamble is fully correlated only if maintains corr_sign along the whole sequence
|
||||
for (int i = 1; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++)
|
||||
{
|
||||
if (d_page_symbols[d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS + i] < 0 && d_preamble_bits[i]+corr_sign != 0)
|
||||
{
|
||||
//exit for
|
||||
corr_flag=false;
|
||||
break;
|
||||
}
|
||||
if (d_page_symbols[d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS + i] > 0 && d_preamble_bits[i]+corr_sign == 0)
|
||||
{
|
||||
//exit for
|
||||
corr_flag=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//
|
||||
if (corr_flag==true) // preamble fully correlates
|
||||
{
|
||||
d_preamble_index = d_sample_counter - GALILEO_FNAV_CODES_PER_PREAMBLE;//record the preamble sample stamp. Remember correlation appears at the end of the preamble in this design
|
||||
LOG(INFO) << "Preamble detection for Galileo SAT " << this->d_satellite << std::endl;
|
||||
d_symbol_counter = 0; // d_page_symbols start right after preamble and finish at the end of next preamble.
|
||||
d_state = 2; // preamble lock
|
||||
}
|
||||
if (d_symbol_counter >= GALILEO_FNAV_SYMBOLS_PER_PAGE + GALILEO_FNAV_PREAMBLE_LENGTH_BITS)
|
||||
{
|
||||
d_symbol_counter = GALILEO_FNAV_PREAMBLE_LENGTH_BITS; // prevents overflow
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
d_prompt_counter++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
d_current_symbol += in[0][0].Prompt_I;
|
||||
if (d_prompt_counter == GALILEO_FNAV_CODES_PER_SYMBOL - 1)
|
||||
{
|
||||
if (d_current_symbol > 0)
|
||||
{
|
||||
d_page_symbols[d_symbol_counter] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_page_symbols[d_symbol_counter] = -1;
|
||||
}
|
||||
// d_page_symbols[d_symbol_counter] = d_current_symbol_float/(float)GALILEO_FNAV_CODES_PER_SYMBOL;
|
||||
d_current_symbol = 0;
|
||||
d_symbol_counter++;
|
||||
d_prompt_counter = 0;
|
||||
// At the right sample stamp, check preamble synchro
|
||||
if (d_sample_counter == d_preamble_index + GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE)
|
||||
{
|
||||
// **** Attempt Preamble correlation ****
|
||||
bool corr_flag = true;
|
||||
int corr_sign = 0; // sequence can be found inverted
|
||||
// corr_sign = d_preamble_bits[0] * d_page_symbols[d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS];
|
||||
// for (int i = 1; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++)
|
||||
// {
|
||||
// if ((d_preamble_bits[i] * d_page_symbols[i + d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS]) != corr_sign)
|
||||
// {
|
||||
// //exit for if one bit doesn't correlate
|
||||
// corr_flag=false;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// check if the preamble starts positive correlated or negative correlated
|
||||
if (d_page_symbols[d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS] < 0) // symbols clipping
|
||||
{
|
||||
corr_sign=-d_preamble_bits[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
corr_sign=d_preamble_bits[0];
|
||||
}
|
||||
// the preamble is fully correlated only if maintains corr_sign along the whole sequence
|
||||
for (int i = 1; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++)
|
||||
{
|
||||
if (d_page_symbols[d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS + i] < 0 && d_preamble_bits[i]+corr_sign != 0)
|
||||
{
|
||||
//exit for
|
||||
corr_flag=false;
|
||||
break;
|
||||
}
|
||||
if (d_page_symbols[d_symbol_counter - GALILEO_FNAV_PREAMBLE_LENGTH_BITS + i] > 0 && d_preamble_bits[i]+corr_sign == 0)
|
||||
{
|
||||
//exit for
|
||||
corr_flag=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//
|
||||
if (corr_flag==true) // NEW PREAMBLE RECEIVED. DECODE PAGE
|
||||
{
|
||||
d_preamble_index = d_sample_counter - GALILEO_FNAV_CODES_PER_PREAMBLE;//record the preamble sample stamp
|
||||
// DECODE WORD
|
||||
decode_word(d_page_symbols, GALILEO_FNAV_SYMBOLS_PER_PAGE - GALILEO_FNAV_PREAMBLE_LENGTH_BITS);
|
||||
// CHECK CRC
|
||||
if (d_nav.flag_CRC_test == true)
|
||||
{
|
||||
d_CRC_error_counter = 0;
|
||||
d_flag_preamble = true; //valid preamble indicator (initialized to false every work())
|
||||
d_preamble_time_seconds = in[0][0].Tracking_timestamp_secs - ((double)(GALILEO_FNAV_CODES_PER_PAGE+GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD); //record the PRN start sample index associated to the preamble start.
|
||||
if (!d_flag_frame_sync)
|
||||
{
|
||||
d_flag_frame_sync = true;
|
||||
LOG(INFO) <<" Frame sync SAT " << this->d_satellite << " with preamble start at " << d_preamble_time_seconds << " [s]";
|
||||
}
|
||||
d_symbol_counter = 0; // d_page_symbols start right after preamble and finish at the end of next preamble.
|
||||
}
|
||||
else
|
||||
{
|
||||
d_CRC_error_counter++;
|
||||
if (d_CRC_error_counter > CRC_ERROR_LIMIT)
|
||||
{
|
||||
LOG(INFO) << "Lost of frame sync SAT " << this->d_satellite;
|
||||
d_state = 1;
|
||||
d_symbol_counter = GALILEO_FNAV_PREAMBLE_LENGTH_BITS; // prevents overflow
|
||||
d_flag_frame_sync = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_symbol_counter = 0; // d_page_symbols start right after preamble and finish at the end of next preamble.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
d_prompt_counter++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
consume_each(1);
|
||||
|
||||
// UPDATE GNSS SYNCHRO DATA
|
||||
Gnss_Synchro current_synchro_data; //structure to save the synchronization information and send the output object to the next block
|
||||
//1. Copy the current tracking output
|
||||
current_synchro_data = in[0][0];
|
||||
//2. Add the telemetry decoder information
|
||||
if (this->d_flag_preamble == true and d_nav.flag_TOW_set == true)
|
||||
//update TOW at the preamble instant
|
||||
//We expect a preamble each 10 seconds (FNAV page period)
|
||||
{
|
||||
Prn_timestamp_at_preamble_ms = d_preamble_time_seconds * 1000;
|
||||
//Prn_timestamp_at_preamble_ms = in[0][0].Tracking_timestamp_secs * 1000.0;
|
||||
if (d_nav.flag_TOW_1 == true)
|
||||
{
|
||||
d_TOW_at_Preamble = d_nav.FNAV_TOW_1;
|
||||
d_TOW_at_current_symbol = d_TOW_at_Preamble + ((double)(GALILEO_FNAV_CODES_PER_PAGE+GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD);
|
||||
d_nav.flag_TOW_1 = false;
|
||||
}
|
||||
if (d_nav.flag_TOW_2 == true)
|
||||
{
|
||||
d_TOW_at_Preamble = d_nav.FNAV_TOW_2;
|
||||
d_TOW_at_current_symbol = d_TOW_at_Preamble + ((double)(GALILEO_FNAV_CODES_PER_PAGE+GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD);
|
||||
d_nav.flag_TOW_2 = false;
|
||||
}
|
||||
if (d_nav.flag_TOW_3 == true)
|
||||
{
|
||||
d_TOW_at_Preamble = d_nav.FNAV_TOW_3;
|
||||
d_TOW_at_current_symbol = d_TOW_at_Preamble + ((double)(GALILEO_FNAV_CODES_PER_PAGE+GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD);
|
||||
d_nav.flag_TOW_3 = false;
|
||||
}
|
||||
if (d_nav.flag_TOW_4 == true)
|
||||
{
|
||||
d_TOW_at_Preamble = d_nav.FNAV_TOW_4;
|
||||
d_TOW_at_current_symbol = d_TOW_at_Preamble + ((double)(GALILEO_FNAV_CODES_PER_PAGE+GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD);
|
||||
d_nav.flag_TOW_4 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//this page has no timming information
|
||||
d_TOW_at_Preamble = d_TOW_at_Preamble + GALILEO_FNAV_SECONDS_PER_PAGE;
|
||||
d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALILEO_E5a_CODE_PERIOD;
|
||||
}
|
||||
|
||||
}
|
||||
else //if there is not a new preamble, we define the TOW of the current symbol
|
||||
{
|
||||
d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALILEO_E5a_CODE_PERIOD;
|
||||
}
|
||||
|
||||
//if (d_flag_frame_sync == true and d_nav.flag_TOW_set==true and d_nav.flag_CRC_test == true)
|
||||
if (d_flag_frame_sync == true and d_nav.flag_TOW_set == true)
|
||||
{
|
||||
current_synchro_data.Flag_valid_word = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_synchro_data.Flag_valid_word = false;
|
||||
}
|
||||
|
||||
current_synchro_data.d_TOW = d_TOW_at_Preamble;
|
||||
current_synchro_data.d_TOW_at_current_symbol = d_TOW_at_current_symbol;
|
||||
current_synchro_data.Flag_preamble = d_flag_preamble;
|
||||
current_synchro_data.Prn_timestamp_ms = in[0][0].Tracking_timestamp_secs * 1000.0;
|
||||
current_synchro_data.Prn_timestamp_at_preamble_ms = Prn_timestamp_at_preamble_ms;
|
||||
|
||||
if(d_dump == true)
|
||||
{
|
||||
// MULTIPLEXED FILE RECORDING - Record results to file
|
||||
try
|
||||
{
|
||||
double tmp_double;
|
||||
tmp_double = d_TOW_at_current_symbol;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = current_synchro_data.Prn_timestamp_ms;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
tmp_double = d_TOW_at_Preamble;
|
||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||
}
|
||||
catch (const std::ifstream::failure& e)
|
||||
{
|
||||
LOG(WARNING) << "Exception writing observables dump file " << e.what();
|
||||
}
|
||||
}
|
||||
d_sample_counter++; //count for the processed samples
|
||||
//3. Make the output (copy the object contents to the GNURadio reserved memory)
|
||||
*out[0] = current_synchro_data;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void galileo_e5a_telemetry_decoder_cc::set_satellite(Gnss_Satellite satellite)
|
||||
{
|
||||
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
||||
DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite;
|
||||
DLOG(INFO) << "Navigation Satellite set to " << d_satellite;
|
||||
}
|
||||
|
||||
|
||||
void galileo_e5a_telemetry_decoder_cc::set_channel(int channel)
|
||||
{
|
||||
d_channel = channel;
|
||||
LOG(INFO) << "Navigation channel set to " << channel;
|
||||
// ############# ENABLE DATA FILE LOG #################
|
||||
if (d_dump == true)
|
||||
{
|
||||
if (d_dump_file.is_open() == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
d_dump_filename = "telemetry";
|
||||
d_dump_filename.append(boost::lexical_cast<std::string>(d_channel));
|
||||
d_dump_filename.append(".dat");
|
||||
d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
|
||||
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
|
||||
LOG(INFO) << "Telemetry decoder dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str();
|
||||
}
|
||||
catch (const std::ifstream::failure& e)
|
||||
{
|
||||
LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void galileo_e5a_telemetry_decoder_cc::set_ephemeris_queue(concurrent_queue<Galileo_Ephemeris> *ephemeris_queue)
|
||||
{
|
||||
d_ephemeris_queue = ephemeris_queue;
|
||||
}
|
||||
|
||||
|
||||
void galileo_e5a_telemetry_decoder_cc::set_iono_queue(concurrent_queue<Galileo_Iono> *iono_queue)
|
||||
{
|
||||
d_iono_queue = iono_queue;
|
||||
}
|
||||
|
||||
|
||||
void galileo_e5a_telemetry_decoder_cc::set_almanac_queue(concurrent_queue<Galileo_Almanac> *almanac_queue)
|
||||
{
|
||||
d_almanac_queue = almanac_queue;
|
||||
}
|
||||
|
||||
|
||||
void galileo_e5a_telemetry_decoder_cc::set_utc_model_queue(concurrent_queue<Galileo_Utc_Model> *utc_model_queue)
|
||||
{
|
||||
d_utc_model_queue = utc_model_queue;
|
||||
}
|
@ -0,0 +1,154 @@
|
||||
/*!
|
||||
* \file galileo_e5a_telemetry_decoder_cc.cc
|
||||
* \brief Implementation of a Galileo FNAV message demodulator block
|
||||
* \author Marc Sales, 2014. marcsales92(at)gmail.com
|
||||
* \based on work from:
|
||||
* <ul>
|
||||
* <li> Javier Arribas, 2011. jarribas(at)cttc.es
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_CC_H_
|
||||
#define GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_CC_H_
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/trellis/interleaver.h>
|
||||
#include <gnuradio/trellis/permutation.h>
|
||||
//#include <gnuradio/fec/viterbi.h>
|
||||
#include "Galileo_E5a.h"
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_satellite.h"
|
||||
#include "galileo_fnav_message.h"
|
||||
#include "galileo_ephemeris.h"
|
||||
#include "galileo_almanac.h"
|
||||
#include "galileo_iono.h"
|
||||
#include "galileo_utc_model.h"
|
||||
|
||||
//#include "convolutional.h"
|
||||
|
||||
class galileo_e5a_telemetry_decoder_cc;
|
||||
|
||||
typedef boost::shared_ptr<galileo_e5a_telemetry_decoder_cc> galileo_e5a_telemetry_decoder_cc_sptr;
|
||||
|
||||
galileo_e5a_telemetry_decoder_cc_sptr galileo_e5a_make_telemetry_decoder_cc(Gnss_Satellite satellite, long if_freq, long fs_in, unsigned
|
||||
int vector_length, boost::shared_ptr<gr::msg_queue> queue, bool dump);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief This class implements a block that decodes the FNAV data defined in Galileo ICD
|
||||
*
|
||||
*/
|
||||
class galileo_e5a_telemetry_decoder_cc : public gr::block
|
||||
{
|
||||
public:
|
||||
~galileo_e5a_telemetry_decoder_cc();
|
||||
void set_satellite(Gnss_Satellite satellite); //!< Set satellite PRN
|
||||
void set_channel(int channel); //!< Set receiver's channel
|
||||
void set_ephemeris_queue(concurrent_queue<Galileo_Ephemeris> *ephemeris_queue); //!< Set the satellite data queue
|
||||
void set_iono_queue(concurrent_queue<Galileo_Iono> *iono_queue); //!< Set the iono data queue
|
||||
void set_almanac_queue(concurrent_queue<Galileo_Almanac> *almanac_queue); //!< Set the almanac data queue
|
||||
void set_utc_model_queue(concurrent_queue<Galileo_Utc_Model> *utc_model_queue); //!< Set the UTC model queue
|
||||
/*!
|
||||
* \brief This is where all signal processing takes place
|
||||
*/
|
||||
int general_work (int noutput_items, gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
|
||||
|
||||
/*!
|
||||
* \brief Function which tells the scheduler how many input items
|
||||
* are required to produce noutput_items output items.
|
||||
*/
|
||||
void forecast (int noutput_items, gr_vector_int &ninput_items_required);
|
||||
|
||||
private:
|
||||
friend galileo_e5a_telemetry_decoder_cc_sptr
|
||||
galileo_e5a_make_telemetry_decoder_cc(Gnss_Satellite satellite, long if_freq, long fs_in,unsigned
|
||||
int vector_length, boost::shared_ptr<gr::msg_queue> queue, bool dump);
|
||||
galileo_e5a_telemetry_decoder_cc(Gnss_Satellite satellite, long if_freq, long fs_in, unsigned
|
||||
int vector_length, boost::shared_ptr<gr::msg_queue> queue, bool dump);
|
||||
|
||||
void viterbi_decoder(double *page_part_symbols, int *page_part_bits);
|
||||
|
||||
void deinterleaver(int rows, int cols, double *in, double *out);
|
||||
|
||||
void decode_word(double *page_symbols,int frame_length);
|
||||
|
||||
signed int d_preamble_bits[GALILEO_FNAV_PREAMBLE_LENGTH_BITS];
|
||||
// signed int d_page_symbols[GALILEO_FNAV_SYMBOLS_PER_PAGE + GALILEO_FNAV_PREAMBLE_LENGTH_BITS];
|
||||
double d_page_symbols[GALILEO_FNAV_SYMBOLS_PER_PAGE + GALILEO_FNAV_PREAMBLE_LENGTH_BITS];
|
||||
signed int *d_preamble_symbols;
|
||||
double d_current_symbol;
|
||||
long unsigned int d_symbol_counter;
|
||||
int d_prompt_counter;
|
||||
int d_sign_init;
|
||||
|
||||
long unsigned int d_sample_counter;
|
||||
long unsigned int d_preamble_index;
|
||||
|
||||
bool d_preamble_lock;
|
||||
bool d_flag_frame_sync;
|
||||
int d_state;
|
||||
|
||||
bool d_flag_preamble;
|
||||
int d_CRC_error_counter;
|
||||
|
||||
long d_fs_in;
|
||||
|
||||
// navigation message vars
|
||||
Galileo_Fnav_Message d_nav;
|
||||
|
||||
// Galileo ephemeris queue
|
||||
concurrent_queue<Galileo_Ephemeris> *d_ephemeris_queue;
|
||||
// ionospheric parameters queue
|
||||
concurrent_queue<Galileo_Iono> *d_iono_queue;
|
||||
// UTC model parameters queue
|
||||
concurrent_queue<Galileo_Utc_Model> *d_utc_model_queue;
|
||||
// Almanac queue
|
||||
concurrent_queue<Galileo_Almanac> *d_almanac_queue;
|
||||
|
||||
boost::shared_ptr<gr::msg_queue> d_queue;
|
||||
unsigned int d_vector_length;
|
||||
bool d_dump;
|
||||
Gnss_Satellite d_satellite;
|
||||
int d_channel;
|
||||
|
||||
double d_preamble_time_seconds;
|
||||
|
||||
double d_TOW_at_Preamble;
|
||||
double d_TOW_at_current_symbol;
|
||||
double Prn_timestamp_at_preamble_ms;
|
||||
bool flag_TOW_set;
|
||||
|
||||
std::string d_dump_filename;
|
||||
std::ofstream d_dump_file;
|
||||
};
|
||||
|
||||
#endif /* GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_CC_H_ */
|
@ -130,7 +130,7 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(
|
||||
d_TOW_at_Preamble = 0;
|
||||
d_TOW_at_current_symbol = 0;
|
||||
flag_TOW_set = false;
|
||||
|
||||
d_average_count=0;
|
||||
//set_history(d_samples_per_bit*8); // At least a history of 8 bits are needed to correlate with the preamble
|
||||
}
|
||||
|
||||
@ -301,10 +301,15 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
|
||||
//1. Copy the current tracking output
|
||||
current_synchro_data = in[0][0];
|
||||
//2. Add the telemetry decoder information
|
||||
if (this->d_flag_preamble == true and d_GPS_FSM.d_nav.d_TOW > 0) //update TOW at the preamble instant (todo: check for valid d_TOW)
|
||||
if (this->d_flag_preamble == true and d_GPS_FSM.d_nav.d_TOW > 0)
|
||||
//update TOW at the preamble instant (todo: check for valid d_TOW)
|
||||
// JAVI: 30/06/2014
|
||||
// TOW, in GPS, is referred to the START of the SUBFRAME, that is, THE FIRST SYMBOL OF THAT SUBFRAME, NOT THE PREAMBLE.
|
||||
// thus, no correction should be done. d_TOW_at_Preamble should be renamed to d_TOW_at_subframe_start.
|
||||
// Sice we detected the preable, then, we are in the last symbol of that preamble, or just at the start of the first subframe symbol.
|
||||
{
|
||||
d_TOW_at_Preamble = d_GPS_FSM.d_nav.d_TOW + GPS_SUBFRAME_SECONDS; //we decoded the current TOW when the last word of the subframe arrive, so, we have a lag of ONE SUBFRAME
|
||||
d_TOW_at_current_symbol = d_TOW_at_Preamble + GPS_CA_PREAMBLE_LENGTH_BITS/GPS_CA_TELEMETRY_RATE_BITS_SECOND;
|
||||
d_TOW_at_current_symbol = d_TOW_at_Preamble;//GPS_L1_CA_CODE_PERIOD;// + (double)GPS_CA_PREAMBLE_LENGTH_BITS/(double)GPS_CA_TELEMETRY_RATE_BITS_SECOND;
|
||||
Prn_timestamp_at_preamble_ms = in[0][0].Tracking_timestamp_secs * 1000.0;
|
||||
if (flag_TOW_set == false)
|
||||
{
|
||||
@ -318,6 +323,8 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
|
||||
|
||||
current_synchro_data.d_TOW = d_TOW_at_Preamble;
|
||||
current_synchro_data.d_TOW_at_current_symbol = d_TOW_at_current_symbol;
|
||||
|
||||
current_synchro_data.d_TOW_hybrid_at_current_symbol= current_synchro_data.d_TOW_at_current_symbol; // to be used in the hybrid configuration
|
||||
current_synchro_data.Flag_valid_word = (d_flag_frame_sync == true and d_flag_parity == true and flag_TOW_set==true);
|
||||
current_synchro_data.Flag_preamble = d_flag_preamble;
|
||||
current_synchro_data.Prn_timestamp_ms = in[0][0].Tracking_timestamp_secs * 1000.0;
|
||||
@ -341,12 +348,29 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
|
||||
LOG(WARNING) << "Exception writing observables dump file " << e.what();
|
||||
}
|
||||
}
|
||||
//3. Make the output (copy the object contents to the GNURadio reserved memory)
|
||||
*out[0] = current_synchro_data;
|
||||
return 1;
|
||||
|
||||
//todo: implement averaging
|
||||
|
||||
d_average_count++;
|
||||
if (d_average_count==d_decimation_output_factor)
|
||||
{
|
||||
d_average_count=0;
|
||||
//3. Make the output (copy the object contents to the GNURadio reserved memory)
|
||||
*out[0] = current_synchro_data;
|
||||
//std::cout<<"GPS TLM output on CH="<<this->d_channel << " SAMPLE STAMP="<<d_sample_counter/d_decimation_output_factor<<std::endl;
|
||||
return 1;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void gps_l1_ca_telemetry_decoder_cc::set_decimation(int decimation)
|
||||
{
|
||||
d_decimation_output_factor=decimation;
|
||||
}
|
||||
|
||||
void gps_l1_ca_telemetry_decoder_cc::set_satellite(Gnss_Satellite satellite)
|
||||
{
|
||||
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
||||
|
@ -61,6 +61,12 @@ public:
|
||||
void set_satellite(Gnss_Satellite satellite); //!< Set satellite PRN
|
||||
void set_channel(int channel); //!< Set receiver's channel
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Set decimation factor to average the GPS synchronization estimation output from the tracking module.
|
||||
*/
|
||||
void set_decimation(int decimation);
|
||||
|
||||
/*!
|
||||
* \brief Set the satellite data queue
|
||||
*/
|
||||
@ -114,6 +120,10 @@ private:
|
||||
bool d_flag_preamble;
|
||||
int d_word_number;
|
||||
|
||||
// output averaging and decimation
|
||||
int d_average_count;
|
||||
int d_decimation_output_factor;
|
||||
|
||||
long d_fs_in;
|
||||
//double d_preamble_duration_seconds;
|
||||
// navigation message vars
|
||||
|
@ -37,7 +37,8 @@
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
//#ifndef GNSS_SDR_CONVOLUTIONAL_H_
|
||||
//#define GNSS_SDR_CONVOLUTIONAL_H_
|
||||
/* define constants used throughout the library */
|
||||
#define MAXLOG 1e7 /* Define infinity */
|
||||
|
||||
@ -49,9 +50,9 @@
|
||||
* \param[in] symbol The integer-valued symbol
|
||||
* \param[in] length The length of the binary vector
|
||||
*
|
||||
* This function is used by conv_encode()
|
||||
* This function is used by conv_encode()
|
||||
*/
|
||||
void itob(int binvec_p[], int symbol, int length)
|
||||
static void itob(int binvec_p[], int symbol, int length)
|
||||
{
|
||||
int counter;
|
||||
/* Go through each bit in the vector */
|
||||
@ -73,9 +74,9 @@ void itob(int binvec_p[], int symbol, int length)
|
||||
* \param[in] symbol The integer-valued symbol
|
||||
* \param[in] length The highest bit position in the symbol
|
||||
*
|
||||
* This function is used by nsc_enc_bit(), rsc_enc_bit(), and rsc_tail()
|
||||
* This function is used by nsc_enc_bit(), rsc_enc_bit(), and rsc_tail()
|
||||
*/
|
||||
int parity_counter(int symbol, int length)
|
||||
static int parity_counter(int symbol, int length)
|
||||
{
|
||||
int counter;
|
||||
int temp_parity = 0;
|
||||
@ -133,7 +134,7 @@ static int nsc_enc_bit(int state_out_p[],
|
||||
|
||||
|
||||
/*!
|
||||
* \brief like nsc_enc_bit() but for a RSC code
|
||||
* \brief like nsc_enc_bit() but for a RSC code
|
||||
*/
|
||||
static int rsc_enc_bit(int state_out_p[],
|
||||
int input,
|
||||
@ -380,7 +381,7 @@ static float Gamma(float rec_array[],
|
||||
mask = mask << 1;
|
||||
}
|
||||
return(rm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@ -440,7 +441,7 @@ static void Viterbi(int output_u_int[],
|
||||
for (t = 0; t < LL + mm; t++)
|
||||
{
|
||||
for (i = 0; i < nn; i++)
|
||||
rec_array[i] = (float)input_c[nn*t + i];
|
||||
rec_array[i] = (float)input_c[nn*t + i];
|
||||
|
||||
/* precompute all possible branch metrics */
|
||||
for (i = 0; i < number_symbols; i++)
|
||||
@ -657,3 +658,4 @@ static void ViterbiTb(int output_u_int[],
|
||||
free(rec_array);
|
||||
free(metric_c);
|
||||
}
|
||||
//#endif
|
||||
|
@ -24,6 +24,7 @@ set(TRACKING_ADAPTER_SOURCES
|
||||
gps_l1_ca_dll_pll_optim_tracking.cc
|
||||
gps_l1_ca_dll_pll_tracking.cc
|
||||
gps_l1_ca_tcp_connector_tracking.cc
|
||||
galileo_e5a_dll_pll_tracking.cc
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user