mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-15 12:40:35 +00:00
Merge branch 'next' of https://github.com/gnss-sdr/gnss-sdr into next
This commit is contained in:
commit
2ce3675375
2
AUTHORS
2
AUTHORS
@ -3,7 +3,7 @@ GNSS-SDR Authorship
|
|||||||
|
|
||||||
The GNSS-SDR project is hosted and sponsored by the Centre Tecnològic de
|
The GNSS-SDR project is hosted and sponsored by the Centre Tecnològic de
|
||||||
Telecomunicacions de Catalunya (CTTC), a non-profit research foundation located
|
Telecomunicacions de Catalunya (CTTC), a non-profit research foundation located
|
||||||
in Castelldefels (40.396764 N, 3.713379 E), 20 km south of Barcelona, Spain.
|
in Castelldefels (41.27504 N, 1.987709 E), 20 km south of Barcelona, Spain.
|
||||||
GNSS-SDR is the by-product of GNSS research conducted at the Communications
|
GNSS-SDR is the by-product of GNSS research conducted at the Communications
|
||||||
Systems Division of CTTC, and it is the combined effort of students,
|
Systems Division of CTTC, and it is the combined effort of students,
|
||||||
software engineers and researchers from different institutions around the World.
|
software engineers and researchers from different institutions around the World.
|
||||||
|
@ -270,7 +270,19 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
|||||||
endif(${DARWIN_VERSION} MATCHES "10")
|
endif(${DARWIN_VERSION} MATCHES "10")
|
||||||
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||||
|
|
||||||
#select the release build type by default to get optimization flags
|
# Define extra build types and select Release by default to get optimization flags
|
||||||
|
include(GnsssdrBuildTypes)
|
||||||
|
# Available options:
|
||||||
|
# - None: nothing set
|
||||||
|
# - Debug: -O2 -g
|
||||||
|
# - Release: -O3
|
||||||
|
# - RelWithDebInfo: -O3 -g
|
||||||
|
# - MinSizeRel: -Os
|
||||||
|
# - Coverage: -Wall -pedantic -pthread -g -O0 -fprofile-arcs -ftest-coverage
|
||||||
|
# - NoOptWithASM: -O0 -g -save-temps
|
||||||
|
# - O2WithASM: -O2 -g -save-temps
|
||||||
|
# - O3WithASM: -O3 -g -save-temps
|
||||||
|
# - ASAN: -Wall -Wextra -g -O2 -fsanitize=address -fno-omit-frame-pointer
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
if(ENABLE_GPERFTOOLS OR ENABLE_GPROF)
|
if(ENABLE_GPERFTOOLS OR ENABLE_GPROF)
|
||||||
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
|
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
|
||||||
@ -282,11 +294,9 @@ if(NOT CMAKE_BUILD_TYPE)
|
|||||||
else(NOT CMAKE_BUILD_TYPE)
|
else(NOT CMAKE_BUILD_TYPE)
|
||||||
message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.")
|
message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.")
|
||||||
endif(NOT CMAKE_BUILD_TYPE)
|
endif(NOT CMAKE_BUILD_TYPE)
|
||||||
|
GNSSSDR_CHECK_BUILD_TYPE(${CMAKE_BUILD_TYPE})
|
||||||
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
|
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
|
||||||
|
|
||||||
# Append -O2 optimization flag for Debug builds
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O2")
|
|
||||||
|
|
||||||
# allow 'large' files in 32 bit builds
|
# allow 'large' files in 32 bit builds
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
add_definitions( -D_LARGEFILE_SOURCE
|
add_definitions( -D_LARGEFILE_SOURCE
|
||||||
@ -318,6 +328,7 @@ set(GNSSSDR_APPLECLANG_MIN_VERSION "500")
|
|||||||
set(GNSSSDR_GNURADIO_MIN_VERSION "3.7.3")
|
set(GNSSSDR_GNURADIO_MIN_VERSION "3.7.3")
|
||||||
set(GNSSSDR_BOOST_MIN_VERSION "1.45")
|
set(GNSSSDR_BOOST_MIN_VERSION "1.45")
|
||||||
set(GNSSSDR_PYTHON_MIN_VERSION "2.7")
|
set(GNSSSDR_PYTHON_MIN_VERSION "2.7")
|
||||||
|
set(GNSSSDR_PYTHON3_MIN_VERSION "3.4")
|
||||||
set(GNSSSDR_MAKO_MIN_VERSION "0.4.2")
|
set(GNSSSDR_MAKO_MIN_VERSION "0.4.2")
|
||||||
set(GNSSSDR_ARMADILLO_MIN_VERSION "5.300.0")
|
set(GNSSSDR_ARMADILLO_MIN_VERSION "5.300.0")
|
||||||
set(GNSSSDR_MATIO_MIN_VERSION "1.5.3")
|
set(GNSSSDR_MATIO_MIN_VERSION "1.5.3")
|
||||||
@ -566,25 +577,28 @@ if(NOT VOLK_GNSSSDR_FOUND)
|
|||||||
###############################
|
###############################
|
||||||
# Find Python required modules
|
# Find Python required modules
|
||||||
###############################
|
###############################
|
||||||
include(SetupPython) #sets PYTHON_EXECUTABLE and PYTHON_DASH_B
|
include(SetupPython) # sets PYTHON_EXECUTABLE and search for required modules
|
||||||
GNSSSDR_PYTHON_CHECK_MODULE("python >= ${GNSSSDR_PYTHON_MIN_VERSION}" sys "sys.version.split()[0] >= '${GNSSSDR_PYTHON_MIN_VERSION}'" PYTHON_MIN_VER_FOUND)
|
|
||||||
GNSSSDR_PYTHON_CHECK_MODULE("mako >= ${GNSSSDR_MAKO_MIN_VERSION}" mako "mako.__version__ >= '${GNSSSDR_MAKO_MIN_VERSION}'" MAKO_FOUND)
|
|
||||||
GNSSSDR_PYTHON_CHECK_MODULE("six - python 2 and 3 compatibility library" six "True" SIX_FOUND)
|
|
||||||
|
|
||||||
if(NOT PYTHON_MIN_VER_FOUND)
|
if(NOT PYTHON_MIN_VER_FOUND)
|
||||||
message(FATAL_ERROR "Python ${GNSSSDR_PYTHON_MIN_VERSION} or greater required to build VOLK_GNSSSDR")
|
message(FATAL_ERROR "Python ${GNSSSDR_PYTHON_MIN_VERSION} or greater required to build VOLK_GNSSSDR")
|
||||||
endif()
|
endif(NOT PYTHON_MIN_VER_FOUND)
|
||||||
|
|
||||||
|
if(${PYTHON3})
|
||||||
|
set(PYTHON_NAME "python3")
|
||||||
|
else(${PYTHON3})
|
||||||
|
set(PYTHON_NAME "python")
|
||||||
|
endif(${PYTHON3})
|
||||||
|
|
||||||
# Mako
|
# Mako
|
||||||
if(NOT MAKO_FOUND)
|
if(NOT MAKO_FOUND)
|
||||||
message(STATUS "Mako templates not found. See http://www.makotemplates.org/ ")
|
message(STATUS "Mako template library not found. See http://www.makotemplates.org/ ")
|
||||||
message(STATUS " You can try to install it by typing:")
|
message(STATUS " You can try to install it by typing:")
|
||||||
if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||||
message(STATUS " sudo yum install python-mako")
|
message(STATUS " sudo yum install ${PYTHON_NAME}-mako")
|
||||||
elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE")
|
elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE")
|
||||||
message(STATUS " sudo zypper install python-Mako")
|
message(STATUS " sudo zypper install ${PYTHON_NAME}-Mako")
|
||||||
else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||||
message(STATUS " sudo apt-get install python-mako")
|
message(STATUS " sudo apt-get install ${PYTHON_NAME}-mako")
|
||||||
endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||||
message(FATAL_ERROR "Mako templates required to build VOLK_GNSSSDR")
|
message(FATAL_ERROR "Mako templates required to build VOLK_GNSSSDR")
|
||||||
endif(NOT MAKO_FOUND)
|
endif(NOT MAKO_FOUND)
|
||||||
@ -594,11 +608,11 @@ if(NOT VOLK_GNSSSDR_FOUND)
|
|||||||
message(STATUS "python-six not found. See https://pythonhosted.org/six/ ")
|
message(STATUS "python-six not found. See https://pythonhosted.org/six/ ")
|
||||||
message(STATUS " You can try to install it by typing:")
|
message(STATUS " You can try to install it by typing:")
|
||||||
if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||||
message(STATUS " sudo yum install python-six")
|
message(STATUS " sudo yum install ${PYTHON_NAME}-six")
|
||||||
elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE")
|
elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE")
|
||||||
message(STATUS " sudo zypper install python-six")
|
message(STATUS " sudo zypper install ${PYTHON_NAME}-six")
|
||||||
else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||||
message(STATUS " sudo apt-get install python-six")
|
message(STATUS " sudo apt-get install ${PYTHON_NAME}-six")
|
||||||
endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||||
message(FATAL_ERROR "six - python 2 and 3 compatibility library required to build VOLK_GNSSSDR")
|
message(FATAL_ERROR "six - python 2 and 3 compatibility library required to build VOLK_GNSSSDR")
|
||||||
endif(NOT SIX_FOUND)
|
endif(NOT SIX_FOUND)
|
||||||
|
219
cmake/Modules/GnsssdrBuildTypes.cmake
Normal file
219
cmake/Modules/GnsssdrBuildTypes.cmake
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
# Copyright (C) 2011-2018 (see AUTHORS file for a list of contributors)
|
||||||
|
#
|
||||||
|
# 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
if(DEFINED __INCLUDED_GNSSSDR_BUILD_TYPES_CMAKE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
set(__INCLUDED_GNSSSDR_BUILD_TYPES_CMAKE TRUE)
|
||||||
|
|
||||||
|
# Standard CMake Build Types and their basic CFLAGS:
|
||||||
|
# - None: nothing set
|
||||||
|
# - Debug: -O2 -g
|
||||||
|
# - Release: -O3
|
||||||
|
# - RelWithDebInfo: -O3 -g
|
||||||
|
# - MinSizeRel: -Os
|
||||||
|
|
||||||
|
# Additional Build Types, defined below:
|
||||||
|
# - NoOptWithASM: -O0 -g -save-temps
|
||||||
|
# - O2WithASM: -O2 -g -save-temps
|
||||||
|
# - O3WithASM: -O3 -g -save-temps
|
||||||
|
|
||||||
|
# Defines the list of acceptable cmake build types. When adding a new
|
||||||
|
# build type below, make sure to add it to this list.
|
||||||
|
list(APPEND AVAIL_BUILDTYPES
|
||||||
|
None Debug Release RelWithDebInfo MinSizeRel
|
||||||
|
Coverage NoOptWithASM O2WithASM O3WithASM ASAN
|
||||||
|
)
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# GNSSSDR_CHECK_BUILD_TYPE(build type)
|
||||||
|
#
|
||||||
|
# Use this to check that the build type set in CMAKE_BUILD_TYPE on the
|
||||||
|
# commandline is one of the valid build types used by this project. It
|
||||||
|
# checks the value set in the cmake interface against the list of
|
||||||
|
# known build types in AVAIL_BUILDTYPES. If the build type is found,
|
||||||
|
# the function exits immediately. If nothing is found by the end of
|
||||||
|
# checking all available build types, we exit with an error and list
|
||||||
|
# the avialable build types.
|
||||||
|
########################################################################
|
||||||
|
function(GNSSSDR_CHECK_BUILD_TYPE settype)
|
||||||
|
string(TOUPPER ${settype} _settype)
|
||||||
|
foreach(btype ${AVAIL_BUILDTYPES})
|
||||||
|
string(TOUPPER ${btype} _btype)
|
||||||
|
if(${_settype} STREQUAL ${_btype})
|
||||||
|
return() # found it; exit cleanly
|
||||||
|
endif(${_settype} STREQUAL ${_btype})
|
||||||
|
endforeach(btype)
|
||||||
|
# Build type not found; error out
|
||||||
|
message(FATAL_ERROR "Build type '${settype}' not valid, must be one of: ${AVAIL_BUILDTYPES}")
|
||||||
|
endfunction(GNSSSDR_CHECK_BUILD_TYPE)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# For GCC and Clang, we can set a build type:
|
||||||
|
#
|
||||||
|
# -DCMAKE_BUILD_TYPE=Coverage
|
||||||
|
#
|
||||||
|
# This type uses no optimization (-O0), outputs debug symbols (-g) and
|
||||||
|
# outputs all intermediary files the build system produces, including
|
||||||
|
# all assembly (.s) files. Look in the build directory for these
|
||||||
|
# files.
|
||||||
|
# NOTE: This is not defined on Windows systems.
|
||||||
|
########################################################################
|
||||||
|
if(NOT WIN32)
|
||||||
|
set(CMAKE_CXX_FLAGS_COVERAGE "-Wall -pedantic -pthread -g -O0 -fprofile-arcs -ftest-coverage" CACHE STRING
|
||||||
|
"Flags used by the C++ compiler during Coverage builds." FORCE)
|
||||||
|
set(CMAKE_C_FLAGS_COVERAGE "-Wall -pedantic -pthread -g -O0 -fprofile-arcs -ftest-coverage" CACHE STRING
|
||||||
|
"Flags used by the C compiler during Coverage builds." FORCE)
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE
|
||||||
|
"-W" CACHE STRING
|
||||||
|
"Flags used for linking binaries during Coverage builds." FORCE)
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
|
||||||
|
"-W" CACHE STRING
|
||||||
|
"Flags used by the shared lib linker during Coverage builds." FORCE)
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(
|
||||||
|
CMAKE_CXX_FLAGS_COVERAGE
|
||||||
|
CMAKE_C_FLAGS_COVERAGE
|
||||||
|
CMAKE_EXE_LINKER_FLAGS_COVERAGE
|
||||||
|
CMAKE_SHARED_LINKER_FLAGS_COVERAGE)
|
||||||
|
endif(NOT WIN32)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# For GCC and Clang, we can set a build type:
|
||||||
|
#
|
||||||
|
# -DCMAKE_BUILD_TYPE=NoOptWithASM
|
||||||
|
#
|
||||||
|
# This type uses no optimization (-O0), outputs debug symbols (-g) and
|
||||||
|
# outputs all intermediary files the build system produces, including
|
||||||
|
# all assembly (.s) files. Look in the build directory for these
|
||||||
|
# files.
|
||||||
|
# NOTE: This is not defined on Windows systems.
|
||||||
|
########################################################################
|
||||||
|
if(NOT WIN32)
|
||||||
|
set(CMAKE_CXX_FLAGS_NOOPTWITHASM "-Wall -save-temps -g -O0" CACHE STRING
|
||||||
|
"Flags used by the C++ compiler during NoOptWithASM builds." FORCE)
|
||||||
|
set(CMAKE_C_FLAGS_NOOPTWITHASM "-Wall -save-temps -g -O0" CACHE STRING
|
||||||
|
"Flags used by the C compiler during NoOptWithASM builds." FORCE)
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS_NOOPTWITHASM
|
||||||
|
"-W" CACHE STRING
|
||||||
|
"Flags used for linking binaries during NoOptWithASM builds." FORCE)
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS_NOOPTWITHASM
|
||||||
|
"-W" CACHE STRING
|
||||||
|
"Flags used by the shared lib linker during NoOptWithASM builds." FORCE)
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(
|
||||||
|
CMAKE_CXX_FLAGS_NOOPTWITHASM
|
||||||
|
CMAKE_C_FLAGS_NOOPTWITHASM
|
||||||
|
CMAKE_EXE_LINKER_FLAGS_NOOPTWITHASM
|
||||||
|
CMAKE_SHARED_LINKER_FLAGS_NOOPTWITHASM)
|
||||||
|
endif(NOT WIN32)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# For GCC and Clang, we can set a build type:
|
||||||
|
#
|
||||||
|
# -DCMAKE_BUILD_TYPE=O2WithASM
|
||||||
|
#
|
||||||
|
# This type uses level 2 optimization (-O2), outputs debug symbols
|
||||||
|
# (-g) and outputs all intermediary files the build system produces,
|
||||||
|
# including all assembly (.s) files. Look in the build directory for
|
||||||
|
# these files.
|
||||||
|
# NOTE: This is not defined on Windows systems.
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
if(NOT WIN32)
|
||||||
|
set(CMAKE_CXX_FLAGS_O2WITHASM "-Wall -save-temps -g -O2" CACHE STRING
|
||||||
|
"Flags used by the C++ compiler during O2WithASM builds." FORCE)
|
||||||
|
set(CMAKE_C_FLAGS_O2WITHASM "-Wall -save-temps -g -O2" CACHE STRING
|
||||||
|
"Flags used by the C compiler during O2WithASM builds." FORCE)
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS_O2WITHASM
|
||||||
|
"-W" CACHE STRING
|
||||||
|
"Flags used for linking binaries during O2WithASM builds." FORCE)
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS_O2WITHASM
|
||||||
|
"-W" CACHE STRING
|
||||||
|
"Flags used by the shared lib linker during O2WithASM builds." FORCE)
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(
|
||||||
|
CMAKE_CXX_FLAGS_O2WITHASM
|
||||||
|
CMAKE_C_FLAGS_O2WITHASM
|
||||||
|
CMAKE_EXE_LINKER_FLAGS_O2WITHASM
|
||||||
|
CMAKE_SHARED_LINKER_FLAGS_O2WITHASM)
|
||||||
|
endif(NOT WIN32)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# For GCC and Clang, we can set a build type:
|
||||||
|
#
|
||||||
|
# -DCMAKE_BUILD_TYPE=O3WithASM
|
||||||
|
#
|
||||||
|
# This type uses level 3 optimization (-O3), outputs debug symbols
|
||||||
|
# (-g) and outputs all intermediary files the build system produces,
|
||||||
|
# including all assembly (.s) files. Look in the build directory for
|
||||||
|
# these files.
|
||||||
|
# NOTE: This is not defined on Windows systems.
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
if(NOT WIN32)
|
||||||
|
set(CMAKE_CXX_FLAGS_O3WITHASM "-Wall -save-temps -g -O3" CACHE STRING
|
||||||
|
"Flags used by the C++ compiler during O3WithASM builds." FORCE)
|
||||||
|
set(CMAKE_C_FLAGS_O3WITHASM "-Wall -save-temps -g -O3" CACHE STRING
|
||||||
|
"Flags used by the C compiler during O3WithASM builds." FORCE)
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS_O3WITHASM
|
||||||
|
"-W" CACHE STRING
|
||||||
|
"Flags used for linking binaries during O3WithASM builds." FORCE)
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS_O3WITHASM
|
||||||
|
"-W" CACHE STRING
|
||||||
|
"Flags used by the shared lib linker during O3WithASM builds." FORCE)
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(
|
||||||
|
CMAKE_CXX_FLAGS_O3WITHASM
|
||||||
|
CMAKE_C_FLAGS_O3WITHASM
|
||||||
|
CMAKE_EXE_LINKER_FLAGS_O3WITHASM
|
||||||
|
CMAKE_SHARED_LINKER_FLAGS_O3WITHASM)
|
||||||
|
endif(NOT WIN32)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# For GCC and Clang, we can set a build type:
|
||||||
|
#
|
||||||
|
# -DCMAKE_BUILD_TYPE=ASAN
|
||||||
|
#
|
||||||
|
# This type creates an address sanitized build (-fsanitize=address)
|
||||||
|
# and defaults to the DebugParanoid linker flags.
|
||||||
|
# NOTE: This is not defined on Windows systems.
|
||||||
|
########################################################################
|
||||||
|
if(NOT WIN32)
|
||||||
|
set(CMAKE_CXX_FLAGS_ASAN "-Wall -Wextra -g -O2 -fsanitize=address -fno-omit-frame-pointer" CACHE STRING
|
||||||
|
"Flags used by the C++ compiler during Address Sanitized builds." FORCE)
|
||||||
|
set(CMAKE_C_FLAGS_ASAN "-Wall -Wextra -g -O2 -fsanitize=address -fno-omit-frame-pointer" CACHE STRING
|
||||||
|
"Flags used by the C compiler during Address Sanitized builds." FORCE)
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS_ASAN
|
||||||
|
"-W" CACHE STRING
|
||||||
|
"Flags used for linking binaries during Address Sanitized builds." FORCE)
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS_ASAN
|
||||||
|
"-W" CACHE STRING
|
||||||
|
"Flags used by the shared lib linker during Address Sanitized builds." FORCE)
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(
|
||||||
|
CMAKE_CXX_FLAGS_ASAN
|
||||||
|
CMAKE_C_FLAGS_ASAN
|
||||||
|
CMAKE_EXE_LINKER_FLAGS_ASAN
|
||||||
|
CMAKE_SHARED_LINKER_ASAN)
|
||||||
|
endif(NOT WIN32)
|
@ -15,54 +15,6 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
|
# along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
########################################################################
|
|
||||||
# Setup the python interpreter:
|
|
||||||
# This allows the user to specify a specific interpreter,
|
|
||||||
# or finds the interpreter via the built-in cmake module.
|
|
||||||
########################################################################
|
|
||||||
#this allows the user to override PYTHON_EXECUTABLE
|
|
||||||
if(PYTHON_EXECUTABLE)
|
|
||||||
|
|
||||||
set(PYTHONINTERP_FOUND TRUE)
|
|
||||||
|
|
||||||
#otherwise if not set, try to automatically find it
|
|
||||||
else(PYTHON_EXECUTABLE)
|
|
||||||
|
|
||||||
#use the built-in find script
|
|
||||||
set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6)
|
|
||||||
find_package(PythonInterp 2)
|
|
||||||
|
|
||||||
#and if that fails use the find program routine
|
|
||||||
if(NOT PYTHONINTERP_FOUND)
|
|
||||||
find_program(PYTHON_EXECUTABLE NAMES python python2 python2.7 python3)
|
|
||||||
if(PYTHON_EXECUTABLE)
|
|
||||||
set(PYTHONINTERP_FOUND TRUE)
|
|
||||||
endif(PYTHON_EXECUTABLE)
|
|
||||||
endif(NOT PYTHONINTERP_FOUND)
|
|
||||||
|
|
||||||
endif(PYTHON_EXECUTABLE)
|
|
||||||
|
|
||||||
if (CMAKE_CROSSCOMPILING)
|
|
||||||
set(QA_PYTHON_EXECUTABLE "/usr/bin/python")
|
|
||||||
else (CMAKE_CROSSCOMPILING)
|
|
||||||
set(QA_PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE})
|
|
||||||
endif(CMAKE_CROSSCOMPILING)
|
|
||||||
|
|
||||||
#make the path to the executable appear in the cmake gui
|
|
||||||
set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter")
|
|
||||||
set(QA_PYTHON_EXECUTABLE ${QA_PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter for QA tests")
|
|
||||||
|
|
||||||
#make sure we can use -B with python (introduced in 2.6)
|
|
||||||
if(PYTHON_EXECUTABLE)
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${PYTHON_EXECUTABLE} -B -c ""
|
|
||||||
OUTPUT_QUIET ERROR_QUIET
|
|
||||||
RESULT_VARIABLE PYTHON_HAS_DASH_B_RESULT
|
|
||||||
)
|
|
||||||
if(PYTHON_HAS_DASH_B_RESULT EQUAL 0)
|
|
||||||
set(PYTHON_DASH_B "-B")
|
|
||||||
endif()
|
|
||||||
endif(PYTHON_EXECUTABLE)
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# Check for the existence of a python module:
|
# Check for the existence of a python module:
|
||||||
@ -71,25 +23,99 @@ endif(PYTHON_EXECUTABLE)
|
|||||||
# - cmd an additional command to run
|
# - cmd an additional command to run
|
||||||
# - have the result variable to set
|
# - have the result variable to set
|
||||||
########################################################################
|
########################################################################
|
||||||
macro(GNSSSDR_PYTHON_CHECK_MODULE desc mod cmd have)
|
macro(GNSSSDR_PYTHON_CHECK_MODULE_RAW desc python_code have)
|
||||||
message(STATUS "Python checking for ${desc}")
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${PYTHON_EXECUTABLE} -c "
|
COMMAND ${PYTHON_EXECUTABLE} -c "${python_code}"
|
||||||
#########################################
|
OUTPUT_QUIET ERROR_QUIET
|
||||||
try: import ${mod}
|
RESULT_VARIABLE return_code
|
||||||
except:
|
|
||||||
try: ${mod}
|
|
||||||
except: exit(-1)
|
|
||||||
try: assert ${cmd}
|
|
||||||
except: exit(-1)
|
|
||||||
#########################################"
|
|
||||||
RESULT_VARIABLE ${have}
|
|
||||||
)
|
)
|
||||||
if(${have} EQUAL 0)
|
if(return_code EQUAL 0)
|
||||||
message(STATUS "Python checking for ${desc} - found")
|
message(STATUS "Python checking for ${desc} - found")
|
||||||
set(${have} TRUE)
|
set(${have} TRUE)
|
||||||
else(${have} EQUAL 0)
|
else()
|
||||||
message(STATUS "Python checking for ${desc} - not found")
|
message(STATUS "Python checking for ${desc} - not found")
|
||||||
set(${have} FALSE)
|
set(${have} FALSE)
|
||||||
endif(${have} EQUAL 0)
|
endif()
|
||||||
|
endmacro(GNSSSDR_PYTHON_CHECK_MODULE_RAW)
|
||||||
|
|
||||||
|
macro(GNSSSDR_PYTHON_CHECK_MODULE desc mod cmd have)
|
||||||
|
GNSSSDR_PYTHON_CHECK_MODULE_RAW(
|
||||||
|
"${desc}" "
|
||||||
|
#########################################
|
||||||
|
try:
|
||||||
|
import ${mod}
|
||||||
|
assert ${cmd}
|
||||||
|
except (ImportError, AssertionError): exit(-1)
|
||||||
|
except: pass
|
||||||
|
#########################################"
|
||||||
|
"${have}")
|
||||||
endmacro(GNSSSDR_PYTHON_CHECK_MODULE)
|
endmacro(GNSSSDR_PYTHON_CHECK_MODULE)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# Setup the python interpreter:
|
||||||
|
# This allows the user to specify a specific interpreter,
|
||||||
|
# or finds the interpreter via the built-in cmake module.
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
if(CMAKE_VERSION VERSION_LESS 3.12)
|
||||||
|
if(PYTHON_EXECUTABLE)
|
||||||
|
message(STATUS "User set python executable ${PYTHON_EXECUTABLE}")
|
||||||
|
string(FIND "${PYTHON_EXECUTABLE}" "python3" IS_PYTHON3)
|
||||||
|
if(IS_PYTHON3 EQUAL -1)
|
||||||
|
find_package(PythonInterp ${GNSSSDR_PYTHON_MIN_VERSION} REQUIRED)
|
||||||
|
else(IS_PYTHON3 EQUAL -1)
|
||||||
|
find_package(PythonInterp ${GNSSSDR_PYTHON3_MIN_VERSION} REQUIRED)
|
||||||
|
endif(IS_PYTHON3 EQUAL -1)
|
||||||
|
GNSSSDR_PYTHON_CHECK_MODULE("python >= ${GNSSSDR_PYTHON_MIN_VERSION}" sys "sys.version.split()[0] >= '${GNSSSDR_PYTHON_MIN_VERSION}'" PYTHON_MIN_VER_FOUND)
|
||||||
|
GNSSSDR_PYTHON_CHECK_MODULE("mako >= ${GNSSSDR_MAKO_MIN_VERSION}" mako "mako.__version__ >= '${GNSSSDR_MAKO_MIN_VERSION}'" MAKO_FOUND)
|
||||||
|
GNSSSDR_PYTHON_CHECK_MODULE("six - python 2 and 3 compatibility library" six "True" SIX_FOUND)
|
||||||
|
else(PYTHON_EXECUTABLE)
|
||||||
|
message(STATUS "PYTHON_EXECUTABLE not set - trying by default python2")
|
||||||
|
message(STATUS "Use -DPYTHON_EXECUTABLE=/path/to/python3 to build for python3.")
|
||||||
|
find_package(PythonInterp ${GNSSSDR_PYTHON_MIN_VERSION})
|
||||||
|
if(NOT PYTHONINTERP_FOUND)
|
||||||
|
message(STATUS "python2 not found - trying with python3")
|
||||||
|
find_package(PythonInterp ${GNSSSDR_PYTHON3_MIN_VERSION} REQUIRED)
|
||||||
|
endif(NOT PYTHONINTERP_FOUND)
|
||||||
|
GNSSSDR_PYTHON_CHECK_MODULE("python >= ${GNSSSDR_PYTHON_MIN_VERSION}" sys "sys.version.split()[0] >= '${GNSSSDR_PYTHON_MIN_VERSION}'" PYTHON_MIN_VER_FOUND)
|
||||||
|
GNSSSDR_PYTHON_CHECK_MODULE("mako >= ${GNSSSDR_MAKO_MIN_VERSION}" mako "mako.__version__ >= '${GNSSSDR_MAKO_MIN_VERSION}'" MAKO_FOUND)
|
||||||
|
GNSSSDR_PYTHON_CHECK_MODULE("six - python 2 and 3 compatibility library" six "True" SIX_FOUND)
|
||||||
|
endif(PYTHON_EXECUTABLE)
|
||||||
|
find_package(PythonLibs ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} EXACT)
|
||||||
|
else(CMAKE_VERSION VERSION_LESS 3.12)
|
||||||
|
find_package (Python3 COMPONENTS Interpreter)
|
||||||
|
if(Python3_FOUND)
|
||||||
|
set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
|
||||||
|
set(PYTHON_VERSION_MAJOR ${Python3_VERSION_MAJOR})
|
||||||
|
GNSSSDR_PYTHON_CHECK_MODULE("python >= ${GNSSSDR_PYTHON_MIN_VERSION}" sys "sys.version.split()[0] >= '${GNSSSDR_PYTHON_MIN_VERSION}'" PYTHON_MIN_VER_FOUND)
|
||||||
|
GNSSSDR_PYTHON_CHECK_MODULE("mako >= ${GNSSSDR_MAKO_MIN_VERSION}" mako "mako.__version__ >= '${GNSSSDR_MAKO_MIN_VERSION}'" MAKO_FOUND)
|
||||||
|
GNSSSDR_PYTHON_CHECK_MODULE("six - python 2 and 3 compatibility library" six "True" SIX_FOUND)
|
||||||
|
endif(Python3_FOUND)
|
||||||
|
if(NOT Python3_FOUND OR NOT MAKO_FOUND OR NOT SIX_FOUND)
|
||||||
|
find_package(Python2 COMPONENTS Interpreter)
|
||||||
|
if(Python2_FOUND)
|
||||||
|
set(PYTHON_EXECUTABLE ${Python2_EXECUTABLE})
|
||||||
|
set(PYTHON_VERSION_MAJOR ${Python2_VERSION_MAJOR})
|
||||||
|
GNSSSDR_PYTHON_CHECK_MODULE("python >= ${GNSSSDR_PYTHON_MIN_VERSION}" sys "sys.version.split()[0] >= '${GNSSSDR_PYTHON_MIN_VERSION}'" PYTHON_MIN_VER_FOUND)
|
||||||
|
GNSSSDR_PYTHON_CHECK_MODULE("mako >= ${GNSSSDR_MAKO_MIN_VERSION}" mako "mako.__version__ >= '${GNSSSDR_MAKO_MIN_VERSION}'" MAKO_FOUND)
|
||||||
|
GNSSSDR_PYTHON_CHECK_MODULE("six - python 2 and 3 compatibility library" six "True" SIX_FOUND)
|
||||||
|
endif(Python2_FOUND)
|
||||||
|
endif(NOT Python3_FOUND OR NOT MAKO_FOUND OR NOT SIX_FOUND)
|
||||||
|
endif(CMAKE_VERSION VERSION_LESS 3.12)
|
||||||
|
|
||||||
|
if(${PYTHON_VERSION_MAJOR} VERSION_EQUAL 3)
|
||||||
|
set(PYTHON3 TRUE)
|
||||||
|
endif(${PYTHON_VERSION_MAJOR} VERSION_EQUAL 3)
|
||||||
|
|
||||||
|
|
||||||
|
if(CMAKE_CROSSCOMPILING)
|
||||||
|
set(QA_PYTHON_EXECUTABLE "/usr/bin/python")
|
||||||
|
else(CMAKE_CROSSCOMPILING)
|
||||||
|
set(QA_PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE})
|
||||||
|
endif(CMAKE_CROSSCOMPILING)
|
||||||
|
|
||||||
|
|
||||||
|
#make the path to the executable appear in the cmake gui
|
||||||
|
set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter")
|
||||||
|
set(QA_PYTHON_EXECUTABLE ${QA_PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter for QA tests")
|
||||||
|
63
conf/gnss-sdr-kalman-bayes.conf
Normal file
63
conf/gnss-sdr-kalman-bayes.conf
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
[GNSS-SDR]
|
||||||
|
|
||||||
|
;######### GLOBAL OPTIONS ##################
|
||||||
|
;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second].
|
||||||
|
GNSS-SDR.internal_fs_sps=2000000
|
||||||
|
GNSS-SDR.internal_fs_hz=2000000
|
||||||
|
|
||||||
|
;######### SIGNAL_SOURCE CONFIG ############
|
||||||
|
SignalSource.implementation=File_Signal_Source
|
||||||
|
SignalSource.filename=/home/glamountain/gnss-sdr/data/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat
|
||||||
|
SignalSource.item_type=ishort
|
||||||
|
SignalSource.sampling_frequency=4000000
|
||||||
|
SignalSource.freq=1575420000
|
||||||
|
SignalSource.samples=0
|
||||||
|
|
||||||
|
;######### SIGNAL_CONDITIONER CONFIG ############
|
||||||
|
SignalConditioner.implementation=Signal_Conditioner
|
||||||
|
DataTypeAdapter.implementation=Ishort_To_Complex
|
||||||
|
InputFilter.implementation=Pass_Through
|
||||||
|
InputFilter.item_type=gr_complex
|
||||||
|
Resampler.implementation=Direct_Resampler
|
||||||
|
Resampler.sample_freq_in=4000000
|
||||||
|
Resampler.sample_freq_out=2000000
|
||||||
|
Resampler.item_type=gr_complex
|
||||||
|
|
||||||
|
;######### CHANNELS GLOBAL CONFIG ############
|
||||||
|
Channels_1C.count=8
|
||||||
|
Channels.in_acquisition=1
|
||||||
|
Channel.signal=1C
|
||||||
|
|
||||||
|
;######### ACQUISITION GLOBAL CONFIG ############
|
||||||
|
Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||||
|
Acquisition_1C.item_type=gr_complex
|
||||||
|
Acquisition_1C.threshold=0.008
|
||||||
|
Acquisition_1C.doppler_max=10000
|
||||||
|
Acquisition_1C.doppler_step=250
|
||||||
|
Acquisition_1C.dump=false
|
||||||
|
Acquisition_1C.dump_filename=../data/kalman/acq_dump
|
||||||
|
|
||||||
|
;######### TRACKING GLOBAL CONFIG ############
|
||||||
|
Tracking_1C.implementation=GPS_L1_CA_KF_Tracking
|
||||||
|
Tracking_1C.item_type=gr_complex
|
||||||
|
Tracking_1C.pll_bw_hz=40.0;
|
||||||
|
Tracking_1C.dll_bw_hz=4.0;
|
||||||
|
Tracking_1C.order=3;
|
||||||
|
Tracking_1C.dump=true
|
||||||
|
Tracking_1C.dump_filename=../data/kalman/epl_tracking_ch_
|
||||||
|
Tracking_1C.bce_run = true;
|
||||||
|
Tracking_1C.p_transient = 0;
|
||||||
|
Tracking_1C.s_transient = 100;
|
||||||
|
|
||||||
|
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||||
|
TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||||
|
|
||||||
|
;######### OBSERVABLES CONFIG ############
|
||||||
|
Observables.implementation=GPS_L1_CA_Observables
|
||||||
|
|
||||||
|
;######### PVT CONFIG ############
|
||||||
|
PVT.implementation=GPS_L1_CA_PVT
|
||||||
|
PVT.averaging_depth=100
|
||||||
|
PVT.flag_averaging=true
|
||||||
|
PVT.output_rate_ms=10
|
||||||
|
PVT.display_rate_ms=500
|
211
conf/gnss-sdr_GPS_L1_nsr_kf.conf
Normal file
211
conf/gnss-sdr_GPS_L1_nsr_kf.conf
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
; 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_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second].
|
||||||
|
;GNSS-SDR.internal_fs_sps=6826700
|
||||||
|
GNSS-SDR.internal_fs_sps=2560000
|
||||||
|
;GNSS-SDR.internal_fs_sps=4096000
|
||||||
|
;GNSS-SDR.internal_fs_sps=5120000
|
||||||
|
|
||||||
|
;######### 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=/home/javier/signals/ifen/E1L1_FE0_Band0.stream ; <- PUT YOUR FILE HERE
|
||||||
|
|
||||||
|
;#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
|
||||||
|
|
||||||
|
;#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_1C.count=8
|
||||||
|
Channels.in_acquisition=1
|
||||||
|
#Channel.signal=1C
|
||||||
|
|
||||||
|
|
||||||
|
;######### ACQUISITION GLOBAL CONFIG ############
|
||||||
|
Acquisition_1C.dump=false
|
||||||
|
Acquisition_1C.dump_filename=./acq_dump.dat
|
||||||
|
Acquisition_1C.item_type=gr_complex
|
||||||
|
Acquisition_1C.if=0
|
||||||
|
Acquisition_1C.sampled_ms=1
|
||||||
|
Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||||
|
;#use_CFAR_algorithm: If enabled, acquisition estimates the input signal power to implement CFAR detection algorithms
|
||||||
|
;#notice that this affects the Acquisition threshold range!
|
||||||
|
Acquisition_1C.use_CFAR_algorithm=false;
|
||||||
|
;#threshold: Acquisition threshold
|
||||||
|
Acquisition_1C.threshold=10
|
||||||
|
;Acquisition_1C.pfa=0.01
|
||||||
|
Acquisition_1C.doppler_max=5000
|
||||||
|
Acquisition_1C.doppler_step=100
|
||||||
|
|
||||||
|
|
||||||
|
;######### TRACKING GPS CONFIG ############
|
||||||
|
Tracking_1C.implementation=GPS_L1_CA_KF_Tracking
|
||||||
|
Tracking_1C.item_type=gr_complex
|
||||||
|
Tracking_1C.if=0
|
||||||
|
Tracking_1C.dump=true
|
||||||
|
Tracking_1C.dump_filename=../data/epl_tracking_ch_
|
||||||
|
Tracking_1C.pll_bw_hz=15.0;
|
||||||
|
Tracking_1C.dll_bw_hz=2.0;
|
||||||
|
Tracking_1C.order=3;
|
||||||
|
|
||||||
|
|
||||||
|
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||||
|
TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||||
|
TelemetryDecoder_1C.dump=false
|
||||||
|
TelemetryDecoder_1C.decimation_factor=1;
|
||||||
|
|
||||||
|
;######### OBSERVABLES CONFIG ############
|
||||||
|
;#implementation:
|
||||||
|
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 ############
|
||||||
|
PVT.implementation=RTKLIB_PVT
|
||||||
|
PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic
|
||||||
|
PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX
|
||||||
|
PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad
|
||||||
|
PVT.output_rate_ms=100
|
||||||
|
PVT.display_rate_ms=500
|
||||||
|
PVT.dump_filename=./PVT
|
||||||
|
PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea;
|
||||||
|
PVT.flag_nmea_tty_port=false;
|
||||||
|
PVT.nmea_dump_devname=/dev/pts/4
|
||||||
|
PVT.flag_rtcm_server=false
|
||||||
|
PVT.flag_rtcm_tty_port=false
|
||||||
|
PVT.rtcm_dump_devname=/dev/pts/1
|
||||||
|
PVT.dump=true
|
@ -16,6 +16,11 @@
|
|||||||
# along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
|
# along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
if(Boost_VERSION LESS 105800)
|
||||||
|
add_definitions(-DOLD_BOOST=1)
|
||||||
|
endif(Boost_VERSION LESS 105800)
|
||||||
|
|
||||||
set(PVT_ADAPTER_SOURCES
|
set(PVT_ADAPTER_SOURCES
|
||||||
rtklib_pvt.cc
|
rtklib_pvt.cc
|
||||||
)
|
)
|
||||||
|
@ -34,9 +34,15 @@
|
|||||||
#include "gnss_sdr_flags.h"
|
#include "gnss_sdr_flags.h"
|
||||||
#include <boost/archive/xml_oarchive.hpp>
|
#include <boost/archive/xml_oarchive.hpp>
|
||||||
#include <boost/archive/xml_iarchive.hpp>
|
#include <boost/archive/xml_iarchive.hpp>
|
||||||
#include <boost/math/common_factor_rt.hpp>
|
|
||||||
#include <boost/serialization/map.hpp>
|
#include <boost/serialization/map.hpp>
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
|
#if OLD_BOOST
|
||||||
|
#include <boost/math/common_factor_rt.hpp>
|
||||||
|
namespace bc = boost::math;
|
||||||
|
#else
|
||||||
|
#include <boost/integer/common_factor_rt.hpp>
|
||||||
|
namespace bc = boost::integer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
using google::LogMessage;
|
using google::LogMessage;
|
||||||
@ -94,8 +100,8 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration,
|
|||||||
{
|
{
|
||||||
rinex_version = 2;
|
rinex_version = 2;
|
||||||
}
|
}
|
||||||
int rinexobs_rate_ms = boost::math::lcm(configuration->property(role + ".rinexobs_rate_ms", 1000), output_rate_ms);
|
int rinexobs_rate_ms = bc::lcm(configuration->property(role + ".rinexobs_rate_ms", 1000), output_rate_ms);
|
||||||
int rinexnav_rate_ms = boost::math::lcm(configuration->property(role + ".rinexnav_rate_ms", 6000), output_rate_ms);
|
int rinexnav_rate_ms = bc::lcm(configuration->property(role + ".rinexnav_rate_ms", 6000), output_rate_ms);
|
||||||
|
|
||||||
// RTCM Printer settings
|
// RTCM Printer settings
|
||||||
bool flag_rtcm_tty_port = configuration->property(role + ".flag_rtcm_tty_port", false);
|
bool flag_rtcm_tty_port = configuration->property(role + ".flag_rtcm_tty_port", false);
|
||||||
@ -104,13 +110,13 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration,
|
|||||||
unsigned short rtcm_tcp_port = configuration->property(role + ".rtcm_tcp_port", 2101);
|
unsigned short rtcm_tcp_port = configuration->property(role + ".rtcm_tcp_port", 2101);
|
||||||
unsigned short rtcm_station_id = configuration->property(role + ".rtcm_station_id", 1234);
|
unsigned short rtcm_station_id = configuration->property(role + ".rtcm_station_id", 1234);
|
||||||
// RTCM message rates: least common multiple with output_rate_ms
|
// RTCM message rates: least common multiple with output_rate_ms
|
||||||
int rtcm_MT1019_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1019_rate_ms", 5000), output_rate_ms);
|
int rtcm_MT1019_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1019_rate_ms", 5000), output_rate_ms);
|
||||||
int rtcm_MT1020_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1020_rate_ms", 5000), output_rate_ms);
|
int rtcm_MT1020_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1020_rate_ms", 5000), output_rate_ms);
|
||||||
int rtcm_MT1045_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1045_rate_ms", 5000), output_rate_ms);
|
int rtcm_MT1045_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1045_rate_ms", 5000), output_rate_ms);
|
||||||
int rtcm_MSM_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MSM_rate_ms", 1000), output_rate_ms);
|
int rtcm_MSM_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MSM_rate_ms", 1000), output_rate_ms);
|
||||||
int rtcm_MT1077_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1077_rate_ms", rtcm_MSM_rate_ms), output_rate_ms);
|
int rtcm_MT1077_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1077_rate_ms", rtcm_MSM_rate_ms), output_rate_ms);
|
||||||
int rtcm_MT1087_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1087_rate_ms", rtcm_MSM_rate_ms), output_rate_ms);
|
int rtcm_MT1087_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1087_rate_ms", rtcm_MSM_rate_ms), output_rate_ms);
|
||||||
int rtcm_MT1097_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1097_rate_ms", rtcm_MSM_rate_ms), output_rate_ms);
|
int rtcm_MT1097_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1097_rate_ms", rtcm_MSM_rate_ms), output_rate_ms);
|
||||||
std::map<int, int> rtcm_msg_rate_ms;
|
std::map<int, int> rtcm_msg_rate_ms;
|
||||||
rtcm_msg_rate_ms[1019] = rtcm_MT1019_rate_ms;
|
rtcm_msg_rate_ms[1019] = rtcm_MT1019_rate_ms;
|
||||||
rtcm_msg_rate_ms[1020] = rtcm_MT1020_rate_ms;
|
rtcm_msg_rate_ms[1020] = rtcm_MT1020_rate_ms;
|
||||||
@ -498,7 +504,7 @@ bool RtklibPvt::save_assistance_to_XML()
|
|||||||
LOG(INFO) << "SUPL: Try to save GPS ephemeris to XML file " << eph_xml_filename_;
|
LOG(INFO) << "SUPL: Try to save GPS ephemeris to XML file " << eph_xml_filename_;
|
||||||
std::map<int, Gps_Ephemeris> eph_map = pvt_->get_GPS_L1_ephemeris_map();
|
std::map<int, Gps_Ephemeris> eph_map = pvt_->get_GPS_L1_ephemeris_map();
|
||||||
|
|
||||||
if (eph_map.size() > 0)
|
if (eph_map.empty() == false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -16,6 +16,11 @@
|
|||||||
# along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
|
# along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
if(Boost_VERSION LESS 105800)
|
||||||
|
add_definitions(-DOLD_BOOST=1)
|
||||||
|
endif(Boost_VERSION LESS 105800)
|
||||||
|
|
||||||
set(PVT_GR_BLOCKS_SOURCES
|
set(PVT_GR_BLOCKS_SOURCES
|
||||||
rtklib_pvt_cc.cc
|
rtklib_pvt_cc.cc
|
||||||
)
|
)
|
||||||
|
@ -29,43 +29,49 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "rtklib_pvt_cc.h"
|
#include "rtklib_pvt_cc.h"
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include "display.h"
|
||||||
#include <boost/math/common_factor_rt.hpp>
|
|
||||||
#include <boost/archive/xml_oarchive.hpp>
|
#include <boost/archive/xml_oarchive.hpp>
|
||||||
#include <boost/archive/xml_iarchive.hpp>
|
#include <boost/archive/xml_iarchive.hpp>
|
||||||
#include <boost/serialization/map.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
#include <boost/exception/all.hpp>
|
#include <boost/exception/all.hpp>
|
||||||
|
#include <boost/serialization/map.hpp>
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include <gnuradio/gr_complex.h>
|
#include <gnuradio/gr_complex.h>
|
||||||
#include <gnuradio/io_signature.h>
|
#include <gnuradio/io_signature.h>
|
||||||
#include "display.h"
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#if OLD_BOOST
|
||||||
|
#include <boost/math/common_factor_rt.hpp>
|
||||||
|
namespace bc = boost::math;
|
||||||
|
#else
|
||||||
|
#include <boost/integer/common_factor_rt.hpp>
|
||||||
|
namespace bc = boost::integer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
using google::LogMessage;
|
using google::LogMessage;
|
||||||
|
|
||||||
|
|
||||||
rtklib_pvt_cc_sptr rtklib_make_pvt_cc(unsigned int nchannels,
|
rtklib_pvt_cc_sptr rtklib_make_pvt_cc(uint32_t nchannels,
|
||||||
bool dump,
|
bool dump,
|
||||||
std::string dump_filename,
|
std::string dump_filename,
|
||||||
int output_rate_ms,
|
int32_t output_rate_ms,
|
||||||
int display_rate_ms,
|
int32_t display_rate_ms,
|
||||||
bool flag_nmea_tty_port,
|
bool flag_nmea_tty_port,
|
||||||
std::string nmea_dump_filename,
|
std::string nmea_dump_filename,
|
||||||
std::string nmea_dump_devname,
|
std::string nmea_dump_devname,
|
||||||
int rinex_version,
|
int32_t rinex_version,
|
||||||
int rinexobs_rate_ms,
|
int32_t rinexobs_rate_ms,
|
||||||
int rinexnav_rate_ms,
|
int32_t rinexnav_rate_ms,
|
||||||
bool flag_rtcm_server,
|
bool flag_rtcm_server,
|
||||||
bool flag_rtcm_tty_port,
|
bool flag_rtcm_tty_port,
|
||||||
unsigned short rtcm_tcp_port,
|
uint16_t rtcm_tcp_port,
|
||||||
unsigned short rtcm_station_id,
|
uint16_t rtcm_station_id,
|
||||||
std::map<int, int> rtcm_msg_rate_ms,
|
std::map<int, int> rtcm_msg_rate_ms,
|
||||||
std::string rtcm_dump_devname,
|
std::string rtcm_dump_devname,
|
||||||
const unsigned int type_of_receiver,
|
const uint32_t type_of_receiver,
|
||||||
rtk_t& rtk)
|
rtk_t& rtk)
|
||||||
{
|
{
|
||||||
return rtklib_pvt_cc_sptr(new rtklib_pvt_cc(nchannels,
|
return rtklib_pvt_cc_sptr(new rtklib_pvt_cc(nchannels,
|
||||||
@ -239,24 +245,24 @@ std::map<int, Gps_Ephemeris> rtklib_pvt_cc::get_GPS_L1_ephemeris_map()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
rtklib_pvt_cc::rtklib_pvt_cc(unsigned int nchannels,
|
rtklib_pvt_cc::rtklib_pvt_cc(uint32_t nchannels,
|
||||||
bool dump,
|
bool dump,
|
||||||
std::string dump_filename,
|
std::string dump_filename,
|
||||||
int output_rate_ms,
|
int32_t output_rate_ms,
|
||||||
int display_rate_ms,
|
int32_t display_rate_ms,
|
||||||
bool flag_nmea_tty_port,
|
bool flag_nmea_tty_port,
|
||||||
std::string nmea_dump_filename,
|
std::string nmea_dump_filename,
|
||||||
std::string nmea_dump_devname,
|
std::string nmea_dump_devname,
|
||||||
int rinex_version,
|
int32_t rinex_version,
|
||||||
int rinexobs_rate_ms,
|
int32_t rinexobs_rate_ms,
|
||||||
int rinexnav_rate_ms,
|
int32_t rinexnav_rate_ms,
|
||||||
bool flag_rtcm_server,
|
bool flag_rtcm_server,
|
||||||
bool flag_rtcm_tty_port,
|
bool flag_rtcm_tty_port,
|
||||||
unsigned short rtcm_tcp_port,
|
uint16_t rtcm_tcp_port,
|
||||||
unsigned short rtcm_station_id,
|
uint16_t rtcm_station_id,
|
||||||
std::map<int, int> rtcm_msg_rate_ms,
|
std::map<int, int> rtcm_msg_rate_ms,
|
||||||
std::string rtcm_dump_devname,
|
std::string rtcm_dump_devname,
|
||||||
const unsigned int type_of_receiver,
|
const uint32_t type_of_receiver,
|
||||||
rtk_t& rtk) : gr::sync_block("rtklib_pvt_cc",
|
rtk_t& rtk) : gr::sync_block("rtklib_pvt_cc",
|
||||||
gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)),
|
gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)),
|
||||||
gr::io_signature::make(0, 0, 0))
|
gr::io_signature::make(0, 0, 0))
|
||||||
@ -304,7 +310,7 @@ rtklib_pvt_cc::rtklib_pvt_cc(unsigned int nchannels,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_rtcm_MT1019_rate_ms = boost::math::lcm(5000, d_output_rate_ms); // default value if not set
|
d_rtcm_MT1019_rate_ms = bc::lcm(5000, d_output_rate_ms); // default value if not set
|
||||||
}
|
}
|
||||||
if (rtcm_msg_rate_ms.find(1020) != rtcm_msg_rate_ms.end())
|
if (rtcm_msg_rate_ms.find(1020) != rtcm_msg_rate_ms.end())
|
||||||
{
|
{
|
||||||
@ -312,7 +318,7 @@ rtklib_pvt_cc::rtklib_pvt_cc(unsigned int nchannels,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_rtcm_MT1020_rate_ms = boost::math::lcm(5000, d_output_rate_ms); // default value if not set
|
d_rtcm_MT1020_rate_ms = bc::lcm(5000, d_output_rate_ms); // default value if not set
|
||||||
}
|
}
|
||||||
if (rtcm_msg_rate_ms.find(1045) != rtcm_msg_rate_ms.end())
|
if (rtcm_msg_rate_ms.find(1045) != rtcm_msg_rate_ms.end())
|
||||||
{
|
{
|
||||||
@ -320,7 +326,7 @@ rtklib_pvt_cc::rtklib_pvt_cc(unsigned int nchannels,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_rtcm_MT1045_rate_ms = boost::math::lcm(5000, d_output_rate_ms); // default value if not set
|
d_rtcm_MT1045_rate_ms = bc::lcm(5000, d_output_rate_ms); // default value if not set
|
||||||
}
|
}
|
||||||
if (rtcm_msg_rate_ms.find(1077) != rtcm_msg_rate_ms.end()) // whatever between 1071 and 1077
|
if (rtcm_msg_rate_ms.find(1077) != rtcm_msg_rate_ms.end()) // whatever between 1071 and 1077
|
||||||
{
|
{
|
||||||
@ -328,7 +334,7 @@ rtklib_pvt_cc::rtklib_pvt_cc(unsigned int nchannels,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_rtcm_MT1077_rate_ms = boost::math::lcm(1000, d_output_rate_ms); // default value if not set
|
d_rtcm_MT1077_rate_ms = bc::lcm(1000, d_output_rate_ms); // default value if not set
|
||||||
}
|
}
|
||||||
if (rtcm_msg_rate_ms.find(1087) != rtcm_msg_rate_ms.end()) // whatever between 1081 and 1087
|
if (rtcm_msg_rate_ms.find(1087) != rtcm_msg_rate_ms.end()) // whatever between 1081 and 1087
|
||||||
{
|
{
|
||||||
@ -336,7 +342,7 @@ rtklib_pvt_cc::rtklib_pvt_cc(unsigned int nchannels,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_rtcm_MT1087_rate_ms = boost::math::lcm(1000, d_output_rate_ms); // default value if not set
|
d_rtcm_MT1087_rate_ms = bc::lcm(1000, d_output_rate_ms); // default value if not set
|
||||||
}
|
}
|
||||||
if (rtcm_msg_rate_ms.find(1097) != rtcm_msg_rate_ms.end()) // whatever between 1091 and 1097
|
if (rtcm_msg_rate_ms.find(1097) != rtcm_msg_rate_ms.end()) // whatever between 1091 and 1097
|
||||||
{
|
{
|
||||||
@ -345,8 +351,8 @@ rtklib_pvt_cc::rtklib_pvt_cc(unsigned int nchannels,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_rtcm_MT1097_rate_ms = boost::math::lcm(1000, d_output_rate_ms); // default value if not set
|
d_rtcm_MT1097_rate_ms = bc::lcm(1000, d_output_rate_ms); // default value if not set
|
||||||
d_rtcm_MSM_rate_ms = boost::math::lcm(1000, d_output_rate_ms); // default value if not set
|
d_rtcm_MSM_rate_ms = bc::lcm(1000, d_output_rate_ms); // default value if not set
|
||||||
}
|
}
|
||||||
b_rtcm_writing_started = false;
|
b_rtcm_writing_started = false;
|
||||||
|
|
||||||
@ -361,7 +367,7 @@ rtklib_pvt_cc::rtklib_pvt_cc(unsigned int nchannels,
|
|||||||
d_dump_filename.append("_raw.dat");
|
d_dump_filename.append("_raw.dat");
|
||||||
dump_ls_pvt_filename.append("_ls_pvt.dat");
|
dump_ls_pvt_filename.append("_ls_pvt.dat");
|
||||||
|
|
||||||
d_ls_pvt = std::make_shared<rtklib_solver>(static_cast<int>(nchannels), dump_ls_pvt_filename, d_dump, rtk);
|
d_ls_pvt = std::make_shared<rtklib_solver>(static_cast<int32_t>(nchannels), dump_ls_pvt_filename, d_dump, rtk);
|
||||||
d_ls_pvt->set_averaging_depth(1);
|
d_ls_pvt->set_averaging_depth(1);
|
||||||
|
|
||||||
d_rx_time = 0.0;
|
d_rx_time = 0.0;
|
||||||
@ -406,7 +412,7 @@ rtklib_pvt_cc::~rtklib_pvt_cc()
|
|||||||
// save GPS L2CM ephemeris to XML file
|
// save GPS L2CM ephemeris to XML file
|
||||||
std::string file_name = "eph_GPS_CNAV.xml";
|
std::string file_name = "eph_GPS_CNAV.xml";
|
||||||
|
|
||||||
if (d_ls_pvt->gps_cnav_ephemeris_map.size() > 0)
|
if (d_ls_pvt->gps_cnav_ephemeris_map.empty() == false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -429,7 +435,7 @@ rtklib_pvt_cc::~rtklib_pvt_cc()
|
|||||||
// save GPS L1 CA ephemeris to XML file
|
// save GPS L1 CA ephemeris to XML file
|
||||||
file_name = "eph_GPS_L1CA.xml";
|
file_name = "eph_GPS_L1CA.xml";
|
||||||
|
|
||||||
if (d_ls_pvt->gps_ephemeris_map.size() > 0)
|
if (d_ls_pvt->gps_ephemeris_map.empty() == false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -452,7 +458,7 @@ rtklib_pvt_cc::~rtklib_pvt_cc()
|
|||||||
// save Galileo E1 ephemeris to XML file
|
// save Galileo E1 ephemeris to XML file
|
||||||
file_name = "eph_Galileo_E1.xml";
|
file_name = "eph_Galileo_E1.xml";
|
||||||
|
|
||||||
if (d_ls_pvt->galileo_ephemeris_map.size() > 0)
|
if (d_ls_pvt->galileo_ephemeris_map.empty() == false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -475,7 +481,7 @@ rtklib_pvt_cc::~rtklib_pvt_cc()
|
|||||||
// save GLONASS GNAV ephemeris to XML file
|
// save GLONASS GNAV ephemeris to XML file
|
||||||
file_name = "eph_GLONASS_GNAV.xml";
|
file_name = "eph_GLONASS_GNAV.xml";
|
||||||
|
|
||||||
if (d_ls_pvt->glonass_gnav_ephemeris_map.size() > 0)
|
if (d_ls_pvt->glonass_gnav_ephemeris_map.empty() == false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -534,7 +540,7 @@ bool rtklib_pvt_cc::send_sys_v_ttff_msg(ttff_msgbuf ttff)
|
|||||||
int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_items,
|
int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_items,
|
||||||
gr_vector_void_star& output_items __attribute__((unused)))
|
gr_vector_void_star& output_items __attribute__((unused)))
|
||||||
{
|
{
|
||||||
for (int epoch = 0; epoch < noutput_items; epoch++)
|
for (int32_t epoch = 0; epoch < noutput_items; epoch++)
|
||||||
{
|
{
|
||||||
bool flag_display_pvt = false;
|
bool flag_display_pvt = false;
|
||||||
bool flag_compute_pvt_output = false;
|
bool flag_compute_pvt_output = false;
|
||||||
@ -544,15 +550,15 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
|||||||
bool flag_write_RTCM_MSM_output = false;
|
bool flag_write_RTCM_MSM_output = false;
|
||||||
bool flag_write_RINEX_obs_output = false;
|
bool flag_write_RINEX_obs_output = false;
|
||||||
bool flag_write_RINEX_nav_output = false;
|
bool flag_write_RINEX_nav_output = false;
|
||||||
unsigned int gps_channel = 0;
|
uint32_t gps_channel = 0;
|
||||||
unsigned int gal_channel = 0;
|
uint32_t gal_channel = 0;
|
||||||
unsigned int glo_channel = 0;
|
uint32_t glo_channel = 0;
|
||||||
|
|
||||||
gnss_observables_map.clear();
|
gnss_observables_map.clear();
|
||||||
const Gnss_Synchro** in = reinterpret_cast<const Gnss_Synchro**>(&input_items[0]); // Get the input buffer pointer
|
const Gnss_Synchro** in = reinterpret_cast<const Gnss_Synchro**>(&input_items[0]); // Get the input buffer pointer
|
||||||
|
|
||||||
// ############ 1. READ PSEUDORANGES ####
|
// ############ 1. READ PSEUDORANGES ####
|
||||||
for (unsigned int i = 0; i < d_nchannels; i++)
|
for (uint32_t i = 0; i < d_nchannels; i++)
|
||||||
{
|
{
|
||||||
if (in[i][epoch].Flag_valid_pseudorange)
|
if (in[i][epoch].Flag_valid_pseudorange)
|
||||||
{
|
{
|
||||||
@ -567,28 +573,28 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (d_ls_pvt->gps_ephemeris_map.size() > 0)
|
if (d_ls_pvt->gps_ephemeris_map.empty() == false)
|
||||||
{
|
{
|
||||||
if (tmp_eph_iter_gps != d_ls_pvt->gps_ephemeris_map.end())
|
if (tmp_eph_iter_gps != d_ls_pvt->gps_ephemeris_map.end())
|
||||||
{
|
{
|
||||||
d_rtcm_printer->lock_time(d_ls_pvt->gps_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time
|
d_rtcm_printer->lock_time(d_ls_pvt->gps_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (d_ls_pvt->galileo_ephemeris_map.size() > 0)
|
if (d_ls_pvt->galileo_ephemeris_map.empty() == false)
|
||||||
{
|
{
|
||||||
if (tmp_eph_iter_gal != d_ls_pvt->galileo_ephemeris_map.end())
|
if (tmp_eph_iter_gal != d_ls_pvt->galileo_ephemeris_map.end())
|
||||||
{
|
{
|
||||||
d_rtcm_printer->lock_time(d_ls_pvt->galileo_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time
|
d_rtcm_printer->lock_time(d_ls_pvt->galileo_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (d_ls_pvt->gps_cnav_ephemeris_map.size() > 0)
|
if (d_ls_pvt->gps_cnav_ephemeris_map.empty() == false)
|
||||||
{
|
{
|
||||||
if (tmp_eph_iter_cnav != d_ls_pvt->gps_cnav_ephemeris_map.end())
|
if (tmp_eph_iter_cnav != d_ls_pvt->gps_cnav_ephemeris_map.end())
|
||||||
{
|
{
|
||||||
d_rtcm_printer->lock_time(d_ls_pvt->gps_cnav_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time
|
d_rtcm_printer->lock_time(d_ls_pvt->gps_cnav_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (d_ls_pvt->glonass_gnav_ephemeris_map.size() > 0)
|
if (d_ls_pvt->glonass_gnav_ephemeris_map.empty() == false)
|
||||||
{
|
{
|
||||||
if (tmp_eph_iter_glo_gnav != d_ls_pvt->glonass_gnav_ephemeris_map.end())
|
if (tmp_eph_iter_glo_gnav != d_ls_pvt->glonass_gnav_ephemeris_map.end())
|
||||||
{
|
{
|
||||||
@ -610,10 +616,10 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ############ 2 COMPUTE THE PVT ################################
|
// ############ 2 COMPUTE THE PVT ################################
|
||||||
if (gnss_observables_map.size() > 0)
|
if (gnss_observables_map.empty() == false)
|
||||||
{
|
{
|
||||||
double current_RX_time = gnss_observables_map.begin()->second.RX_time;
|
double current_RX_time = gnss_observables_map.begin()->second.RX_time;
|
||||||
unsigned int current_RX_time_ms = static_cast<unsigned int>(current_RX_time * 1000.0);
|
uint32_t current_RX_time_ms = static_cast<uint32_t>(current_RX_time * 1000.0);
|
||||||
if (current_RX_time_ms % d_output_rate_ms == 0)
|
if (current_RX_time_ms % d_output_rate_ms == 0)
|
||||||
{
|
{
|
||||||
flag_compute_pvt_output = true;
|
flag_compute_pvt_output = true;
|
||||||
@ -670,12 +676,12 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
|||||||
{
|
{
|
||||||
flag_write_RTCM_MSM_output = true;
|
flag_write_RTCM_MSM_output = true;
|
||||||
}
|
}
|
||||||
if (current_RX_time_ms % static_cast<unsigned int>(d_rinexobs_rate_ms) == 0)
|
if (current_RX_time_ms % static_cast<uint32_t>(d_rinexobs_rate_ms) == 0)
|
||||||
{
|
{
|
||||||
flag_write_RINEX_obs_output = true;
|
flag_write_RINEX_obs_output = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_RX_time_ms % static_cast<unsigned int>(d_rinexnav_rate_ms) == 0)
|
if (current_RX_time_ms % static_cast<uint32_t>(d_rinexnav_rate_ms) == 0)
|
||||||
{
|
{
|
||||||
flag_write_RINEX_nav_output = true;
|
flag_write_RINEX_nav_output = true;
|
||||||
}
|
}
|
||||||
@ -1387,7 +1393,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
|||||||
{
|
{
|
||||||
//gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end();
|
//gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end();
|
||||||
//galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end();
|
//galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end();
|
||||||
unsigned int i = 0;
|
uint32_t i = 0;
|
||||||
for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++)
|
for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++)
|
||||||
{
|
{
|
||||||
std::string system(&gnss_observables_iter->second.System, 1);
|
std::string system(&gnss_observables_iter->second.System, 1);
|
||||||
@ -1470,7 +1476,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
|||||||
{
|
{
|
||||||
//gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end();
|
//gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end();
|
||||||
//galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end();
|
//galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end();
|
||||||
unsigned int i = 0;
|
uint32_t i = 0;
|
||||||
for (gnss_observables_iter = gnss_observables_map.begin(); gnss_observables_iter != gnss_observables_map.end(); gnss_observables_iter++)
|
for (gnss_observables_iter = gnss_observables_map.begin(); gnss_observables_iter != gnss_observables_map.end(); gnss_observables_iter++)
|
||||||
{
|
{
|
||||||
std::string system(&gnss_observables_iter->second.System, 1);
|
std::string system(&gnss_observables_iter->second.System, 1);
|
||||||
@ -1535,7 +1541,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
|||||||
{
|
{
|
||||||
// gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end();
|
// gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end();
|
||||||
// galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end();
|
// galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end();
|
||||||
unsigned int i = 0;
|
uint32_t i = 0;
|
||||||
for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++)
|
for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++)
|
||||||
{
|
{
|
||||||
std::string system(&gnss_observables_iter->second.System, 1);
|
std::string system(&gnss_observables_iter->second.System, 1);
|
||||||
@ -1600,7 +1606,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
|||||||
{
|
{
|
||||||
// gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end();
|
// gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end();
|
||||||
// galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end();
|
// galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end();
|
||||||
unsigned int i = 0;
|
uint32_t i = 0;
|
||||||
for (gnss_observables_iter = gnss_observables_map.begin(); gnss_observables_iter != gnss_observables_map.end(); gnss_observables_iter++)
|
for (gnss_observables_iter = gnss_observables_map.begin(); gnss_observables_iter != gnss_observables_map.end(); gnss_observables_iter++)
|
||||||
{
|
{
|
||||||
std::string system(&gnss_observables_iter->second.System, 1);
|
std::string system(&gnss_observables_iter->second.System, 1);
|
||||||
@ -1665,7 +1671,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
|||||||
{
|
{
|
||||||
// gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end();
|
// gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end();
|
||||||
// galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end();
|
// galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end();
|
||||||
unsigned int i = 0;
|
uint32_t i = 0;
|
||||||
for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++)
|
for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++)
|
||||||
{
|
{
|
||||||
std::string system(&gnss_observables_iter->second.System, 1);
|
std::string system(&gnss_observables_iter->second.System, 1);
|
||||||
@ -1777,7 +1783,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int i = 0;
|
uint32_t i = 0;
|
||||||
for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++)
|
for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++)
|
||||||
{
|
{
|
||||||
std::string system(&gnss_observables_iter->second.System, 1);
|
std::string system(&gnss_observables_iter->second.System, 1);
|
||||||
@ -1852,7 +1858,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
|||||||
|
|
||||||
// gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end();
|
// gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end();
|
||||||
// galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end();
|
// galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end();
|
||||||
unsigned int i = 0;
|
uint32_t i = 0;
|
||||||
for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++)
|
for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++)
|
||||||
{
|
{
|
||||||
std::string system(&gnss_observables_iter->second.System, 1);
|
std::string system(&gnss_observables_iter->second.System, 1);
|
||||||
@ -1910,7 +1916,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int i = 0;
|
uint32_t i = 0;
|
||||||
for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++)
|
for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++)
|
||||||
{
|
{
|
||||||
std::string system(&gnss_observables_iter->second.System, 1);
|
std::string system(&gnss_observables_iter->second.System, 1);
|
||||||
@ -1967,7 +1973,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
|||||||
|
|
||||||
// gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end();
|
// gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end();
|
||||||
// galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end();
|
// galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end();
|
||||||
unsigned int i = 0;
|
uint32_t i = 0;
|
||||||
for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++)
|
for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++)
|
||||||
{
|
{
|
||||||
std::string system(&gnss_observables_iter->second.System, 1);
|
std::string system(&gnss_observables_iter->second.System, 1);
|
||||||
@ -2025,7 +2031,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int i = 0;
|
uint32_t i = 0;
|
||||||
for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++)
|
for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++)
|
||||||
{
|
{
|
||||||
std::string system(&gnss_observables_iter->second.System, 1);
|
std::string system(&gnss_observables_iter->second.System, 1);
|
||||||
@ -2120,7 +2126,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
double tmp_double;
|
double tmp_double;
|
||||||
for (unsigned int i = 0; i < d_nchannels; i++)
|
for (uint32_t i = 0; i < d_nchannels; i++)
|
||||||
{
|
{
|
||||||
tmp_double = in[i][epoch].Pseudorange_m;
|
tmp_double = in[i][epoch].Pseudorange_m;
|
||||||
d_dump_file.write(reinterpret_cast<char*>(&tmp_double), sizeof(double));
|
d_dump_file.write(reinterpret_cast<char*>(&tmp_double), sizeof(double));
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include <sys/ipc.h>
|
#include <sys/ipc.h>
|
||||||
#include <sys/msg.h>
|
#include <sys/msg.h>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <cstdint>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -53,24 +54,24 @@ class rtklib_pvt_cc;
|
|||||||
|
|
||||||
typedef boost::shared_ptr<rtklib_pvt_cc> rtklib_pvt_cc_sptr;
|
typedef boost::shared_ptr<rtklib_pvt_cc> rtklib_pvt_cc_sptr;
|
||||||
|
|
||||||
rtklib_pvt_cc_sptr rtklib_make_pvt_cc(unsigned int n_channels,
|
rtklib_pvt_cc_sptr rtklib_make_pvt_cc(uint32_t n_channels,
|
||||||
bool dump,
|
bool dump,
|
||||||
std::string dump_filename,
|
std::string dump_filename,
|
||||||
int output_rate_ms,
|
int32_t output_rate_ms,
|
||||||
int display_rate_ms,
|
int32_t display_rate_ms,
|
||||||
bool flag_nmea_tty_port,
|
bool flag_nmea_tty_port,
|
||||||
std::string nmea_dump_filename,
|
std::string nmea_dump_filename,
|
||||||
std::string nmea_dump_devname,
|
std::string nmea_dump_devname,
|
||||||
int rinex_version,
|
int32_t rinex_version,
|
||||||
int rinexobs_rate_ms,
|
int32_t rinexobs_rate_ms,
|
||||||
int rinexnav_rate_ms,
|
int32_t rinexnav_rate_ms,
|
||||||
bool flag_rtcm_server,
|
bool flag_rtcm_server,
|
||||||
bool flag_rtcm_tty_port,
|
bool flag_rtcm_tty_port,
|
||||||
unsigned short rtcm_tcp_port,
|
uint16_t rtcm_tcp_port,
|
||||||
unsigned short rtcm_station_id,
|
uint16_t rtcm_station_id,
|
||||||
std::map<int, int> rtcm_msg_rate_ms,
|
std::map<int, int> rtcm_msg_rate_ms,
|
||||||
std::string rtcm_dump_devname,
|
std::string rtcm_dump_devname,
|
||||||
const unsigned int type_of_receiver,
|
const uint32_t type_of_receiver,
|
||||||
rtk_t& rtk);
|
rtk_t& rtk);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -79,24 +80,24 @@ rtklib_pvt_cc_sptr rtklib_make_pvt_cc(unsigned int n_channels,
|
|||||||
class rtklib_pvt_cc : public gr::sync_block
|
class rtklib_pvt_cc : public gr::sync_block
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
friend rtklib_pvt_cc_sptr rtklib_make_pvt_cc(unsigned int nchannels,
|
friend rtklib_pvt_cc_sptr rtklib_make_pvt_cc(uint32_t nchannels,
|
||||||
bool dump,
|
bool dump,
|
||||||
std::string dump_filename,
|
std::string dump_filename,
|
||||||
int output_rate_ms,
|
int32_t output_rate_ms,
|
||||||
int display_rate_ms,
|
int32_t display_rate_ms,
|
||||||
bool flag_nmea_tty_port,
|
bool flag_nmea_tty_port,
|
||||||
std::string nmea_dump_filename,
|
std::string nmea_dump_filename,
|
||||||
std::string nmea_dump_devname,
|
std::string nmea_dump_devname,
|
||||||
int rinex_version,
|
int32_t rinex_version,
|
||||||
int rinexobs_rate_ms,
|
int32_t rinexobs_rate_ms,
|
||||||
int rinexnav_rate_ms,
|
int32_t rinexnav_rate_ms,
|
||||||
bool flag_rtcm_server,
|
bool flag_rtcm_server,
|
||||||
bool flag_rtcm_tty_port,
|
bool flag_rtcm_tty_port,
|
||||||
unsigned short rtcm_tcp_port,
|
uint16_t rtcm_tcp_port,
|
||||||
unsigned short rtcm_station_id,
|
uint16_t rtcm_station_id,
|
||||||
std::map<int, int> rtcm_msg_rate_ms,
|
std::map<int, int> rtcm_msg_rate_ms,
|
||||||
std::string rtcm_dump_devname,
|
std::string rtcm_dump_devname,
|
||||||
const unsigned int type_of_receiver,
|
const uint32_t type_of_receiver,
|
||||||
rtk_t& rtk);
|
rtk_t& rtk);
|
||||||
|
|
||||||
void msg_handler_telemetry(pmt::pmt_t msg);
|
void msg_handler_telemetry(pmt::pmt_t msg);
|
||||||
@ -105,26 +106,26 @@ private:
|
|||||||
bool b_rinex_header_written;
|
bool b_rinex_header_written;
|
||||||
bool b_rinex_header_updated;
|
bool b_rinex_header_updated;
|
||||||
double d_rinex_version;
|
double d_rinex_version;
|
||||||
int d_rinexobs_rate_ms;
|
int32_t d_rinexobs_rate_ms;
|
||||||
int d_rinexnav_rate_ms;
|
int32_t d_rinexnav_rate_ms;
|
||||||
|
|
||||||
bool b_rtcm_writing_started;
|
bool b_rtcm_writing_started;
|
||||||
int d_rtcm_MT1045_rate_ms; //!< Galileo Broadcast Ephemeris
|
int32_t d_rtcm_MT1045_rate_ms; //!< Galileo Broadcast Ephemeris
|
||||||
int d_rtcm_MT1019_rate_ms; //!< GPS Broadcast Ephemeris (orbits)
|
int32_t d_rtcm_MT1019_rate_ms; //!< GPS Broadcast Ephemeris (orbits)
|
||||||
int d_rtcm_MT1020_rate_ms; //!< GLONASS Broadcast Ephemeris (orbits)
|
int32_t d_rtcm_MT1020_rate_ms; //!< GLONASS Broadcast Ephemeris (orbits)
|
||||||
int d_rtcm_MT1077_rate_ms; //!< The type 7 Multiple Signal Message format for the USA’s GPS system, popular
|
int32_t d_rtcm_MT1077_rate_ms; //!< The type 7 Multiple Signal Message format for the USA’s GPS system, popular
|
||||||
int d_rtcm_MT1087_rate_ms; //!< GLONASS MSM7. The type 7 Multiple Signal Message format for the Russian GLONASS system
|
int32_t d_rtcm_MT1087_rate_ms; //!< GLONASS MSM7. The type 7 Multiple Signal Message format for the Russian GLONASS system
|
||||||
int d_rtcm_MT1097_rate_ms; //!< Galileo MSM7. The type 7 Multiple Signal Message format for Europe’s Galileo system
|
int32_t d_rtcm_MT1097_rate_ms; //!< Galileo MSM7. The type 7 Multiple Signal Message format for Europe’s Galileo system
|
||||||
int d_rtcm_MSM_rate_ms;
|
int32_t d_rtcm_MSM_rate_ms;
|
||||||
|
|
||||||
int d_last_status_print_seg; //for status printer
|
int32_t d_last_status_print_seg; //for status printer
|
||||||
|
|
||||||
unsigned int d_nchannels;
|
uint32_t d_nchannels;
|
||||||
std::string d_dump_filename;
|
std::string d_dump_filename;
|
||||||
std::ofstream d_dump_file;
|
std::ofstream d_dump_file;
|
||||||
|
|
||||||
int d_output_rate_ms;
|
int32_t d_output_rate_ms;
|
||||||
int d_display_rate_ms;
|
int32_t d_display_rate_ms;
|
||||||
|
|
||||||
std::shared_ptr<Rinex_Printer> rp;
|
std::shared_ptr<Rinex_Printer> rp;
|
||||||
std::shared_ptr<Kml_Printer> d_kml_dump;
|
std::shared_ptr<Kml_Printer> d_kml_dump;
|
||||||
@ -139,7 +140,7 @@ private:
|
|||||||
std::map<int, Gnss_Synchro> gnss_observables_map;
|
std::map<int, Gnss_Synchro> gnss_observables_map;
|
||||||
bool observables_pairCompare_min(const std::pair<int, Gnss_Synchro>& a, const std::pair<int, Gnss_Synchro>& b);
|
bool observables_pairCompare_min(const std::pair<int, Gnss_Synchro>& a, const std::pair<int, Gnss_Synchro>& b);
|
||||||
|
|
||||||
unsigned int type_of_rx;
|
uint32_t type_of_rx;
|
||||||
|
|
||||||
bool first_fix;
|
bool first_fix;
|
||||||
key_t sysv_msg_key;
|
key_t sysv_msg_key;
|
||||||
@ -153,23 +154,23 @@ private:
|
|||||||
std::chrono::time_point<std::chrono::system_clock> start, end;
|
std::chrono::time_point<std::chrono::system_clock> start, end;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
rtklib_pvt_cc(unsigned int nchannels,
|
rtklib_pvt_cc(uint32_t nchannels,
|
||||||
bool dump, std::string dump_filename,
|
bool dump, std::string dump_filename,
|
||||||
int output_rate_ms,
|
int32_t output_rate_ms,
|
||||||
int display_rate_ms,
|
int32_t display_rate_ms,
|
||||||
bool flag_nmea_tty_port,
|
bool flag_nmea_tty_port,
|
||||||
std::string nmea_dump_filename,
|
std::string nmea_dump_filename,
|
||||||
std::string nmea_dump_devname,
|
std::string nmea_dump_devname,
|
||||||
int rinex_version,
|
int32_t rinex_version,
|
||||||
int rinexobs_rate_ms,
|
int32_t rinexobs_rate_ms,
|
||||||
int rinexnav_rate_ms,
|
int32_t rinexnav_rate_ms,
|
||||||
bool flag_rtcm_server,
|
bool flag_rtcm_server,
|
||||||
bool flag_rtcm_tty_port,
|
bool flag_rtcm_tty_port,
|
||||||
unsigned short rtcm_tcp_port,
|
uint16_t rtcm_tcp_port,
|
||||||
unsigned short rtcm_station_id,
|
uint16_t rtcm_station_id,
|
||||||
std::map<int, int> rtcm_msg_rate_ms,
|
std::map<int, int> rtcm_msg_rate_ms,
|
||||||
std::string rtcm_dump_devname,
|
std::string rtcm_dump_devname,
|
||||||
const unsigned int type_of_receiver,
|
const uint32_t type_of_receiver,
|
||||||
rtk_t& rtk);
|
rtk_t& rtk);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "nmea_printer.h"
|
#include "nmea_printer.h"
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
|
#include <cstdint>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
|
||||||
@ -86,11 +87,11 @@ int Nmea_Printer::init_serial(std::string serial_device)
|
|||||||
*/
|
*/
|
||||||
int fd = 0;
|
int fd = 0;
|
||||||
struct termios options;
|
struct termios options;
|
||||||
long BAUD;
|
int64_t BAUD;
|
||||||
long DATABITS;
|
int64_t DATABITS;
|
||||||
long STOPBITS;
|
int64_t STOPBITS;
|
||||||
long PARITYON;
|
int64_t PARITYON;
|
||||||
long PARITY;
|
int64_t PARITY;
|
||||||
|
|
||||||
fd = open(serial_device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
|
fd = open(serial_device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
|
||||||
if (fd == -1) return fd; //failed to open TTY port
|
if (fd == -1) return fd; //failed to open TTY port
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -60,6 +60,7 @@
|
|||||||
#include "GLONASS_L1_L2_CA.h"
|
#include "GLONASS_L1_L2_CA.h"
|
||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream> // for stringstream
|
#include <sstream> // for stringstream
|
||||||
@ -221,87 +222,87 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief Writes data from the GPS L1 C/A navigation message into the RINEX file
|
* \brief Writes data from the GPS L1 C/A navigation message into the RINEX file
|
||||||
*/
|
*/
|
||||||
void log_rinex_nav(std::fstream& out, const std::map<int, Gps_Ephemeris>& eph_map);
|
void log_rinex_nav(std::fstream& out, const std::map<int32_t, Gps_Ephemeris>& eph_map);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Writes data from the GPS L2 navigation message into the RINEX file
|
* \brief Writes data from the GPS L2 navigation message into the RINEX file
|
||||||
*/
|
*/
|
||||||
void log_rinex_nav(std::fstream& out, const std::map<int, Gps_CNAV_Ephemeris>& eph_map);
|
void log_rinex_nav(std::fstream& out, const std::map<int32_t, Gps_CNAV_Ephemeris>& eph_map);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Writes data from the Galileo navigation message into the RINEX file
|
* \brief Writes data from the Galileo navigation message into the RINEX file
|
||||||
*/
|
*/
|
||||||
void log_rinex_nav(std::fstream& out, const std::map<int, Galileo_Ephemeris>& eph_map);
|
void log_rinex_nav(std::fstream& out, const std::map<int32_t, Galileo_Ephemeris>& eph_map);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Writes data from the Mixed (GPS/Galileo) navigation message into the RINEX file
|
* \brief Writes data from the Mixed (GPS/Galileo) navigation message into the RINEX file
|
||||||
*/
|
*/
|
||||||
void log_rinex_nav(std::fstream& out, const std::map<int, Gps_Ephemeris>& gps_eph_map, const std::map<int, Galileo_Ephemeris>& galileo_eph_map);
|
void log_rinex_nav(std::fstream& out, const std::map<int32_t, Gps_Ephemeris>& gps_eph_map, const std::map<int32_t, Galileo_Ephemeris>& galileo_eph_map);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Writes data from the GLONASS GNAV navigation message into the RINEX file
|
* \brief Writes data from the GLONASS GNAV navigation message into the RINEX file
|
||||||
*/
|
*/
|
||||||
void log_rinex_nav(std::fstream& out, const std::map<int, Glonass_Gnav_Ephemeris>& eph_map);
|
void log_rinex_nav(std::fstream& out, const std::map<int32_t, Glonass_Gnav_Ephemeris>& eph_map);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Writes data from the Mixed (GPS/GLONASS GNAV) navigation message into the RINEX file
|
* \brief Writes data from the Mixed (GPS/GLONASS GNAV) navigation message into the RINEX file
|
||||||
*/
|
*/
|
||||||
void log_rinex_nav(std::fstream& out, const std::map<int, Gps_Ephemeris>& gps_eph_map, const std::map<int, Glonass_Gnav_Ephemeris>& glonass_gnav_eph_map);
|
void log_rinex_nav(std::fstream& out, const std::map<int32_t, Gps_Ephemeris>& gps_eph_map, const std::map<int32_t, Glonass_Gnav_Ephemeris>& glonass_gnav_eph_map);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Writes data from the Mixed (GPS/GLONASS GNAV) navigation message into the RINEX file
|
* \brief Writes data from the Mixed (GPS/GLONASS GNAV) navigation message into the RINEX file
|
||||||
*/
|
*/
|
||||||
void log_rinex_nav(std::fstream& out, const std::map<int, Gps_CNAV_Ephemeris>& gps_cnav_eph_map, const std::map<int, Glonass_Gnav_Ephemeris>& glonass_gnav_eph_map);
|
void log_rinex_nav(std::fstream& out, const std::map<int32_t, Gps_CNAV_Ephemeris>& gps_cnav_eph_map, const std::map<int32_t, Glonass_Gnav_Ephemeris>& glonass_gnav_eph_map);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Writes data from the Mixed (Galileo/ GLONASS GNAV) navigation message into the RINEX file
|
* \brief Writes data from the Mixed (Galileo/ GLONASS GNAV) navigation message into the RINEX file
|
||||||
*/
|
*/
|
||||||
void log_rinex_nav(std::fstream& out, const std::map<int, Galileo_Ephemeris>& galileo_eph_map, const std::map<int, Glonass_Gnav_Ephemeris>& glonass_gnav_eph_map);
|
void log_rinex_nav(std::fstream& out, const std::map<int32_t, Galileo_Ephemeris>& galileo_eph_map, const std::map<int32_t, Glonass_Gnav_Ephemeris>& glonass_gnav_eph_map);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Writes GPS L1 observables into the RINEX file
|
* \brief Writes GPS L1 observables into the RINEX file
|
||||||
*/
|
*/
|
||||||
void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, double obs_time, const std::map<int, Gnss_Synchro>& observables);
|
void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Writes GPS L2 observables into the RINEX file
|
* \brief Writes GPS L2 observables into the RINEX file
|
||||||
*/
|
*/
|
||||||
void log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& eph, double obs_time, const std::map<int, Gnss_Synchro>& observables);
|
void log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Writes dual frequency GPS L1 and L2 observables into the RINEX file
|
* \brief Writes dual frequency GPS L1 and L2 observables into the RINEX file
|
||||||
*/
|
*/
|
||||||
void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, const Gps_CNAV_Ephemeris& eph_cnav, double obs_time, const std::map<int, Gnss_Synchro>& observables);
|
void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, const Gps_CNAV_Ephemeris& eph_cnav, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Writes Galileo observables into the RINEX file. Example: galileo_bands("1B"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B".
|
* \brief Writes Galileo observables into the RINEX file. Example: galileo_bands("1B"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B".
|
||||||
*/
|
*/
|
||||||
void log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& eph, double obs_time, const std::map<int, Gnss_Synchro>& observables, const std::string galileo_bands = "1B");
|
void log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables, const std::string galileo_bands = "1B");
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Writes Mixed GPS / Galileo observables into the RINEX file
|
* \brief Writes Mixed GPS / Galileo observables into the RINEX file
|
||||||
*/
|
*/
|
||||||
void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& galileo_eph, const double gps_obs_time, const std::map<int, Gnss_Synchro>& observables);
|
void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& galileo_eph, const double gps_obs_time, const std::map<int32_t, Gnss_Synchro>& observables);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Writes GLONASS GNAV observables into the RINEX file. Example: glonass_bands("1C"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B".
|
* \brief Writes GLONASS GNAV observables into the RINEX file. Example: glonass_bands("1C"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B".
|
||||||
*/
|
*/
|
||||||
void log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeris& eph, double obs_time, const std::map<int, Gnss_Synchro>& observables, const std::string glonass_bands = "1C");
|
void log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeris& eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables, const std::string glonass_bands = "1C");
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Writes Mixed GPS L1 C/A - GLONASS observables into the RINEX file
|
* \brief Writes Mixed GPS L1 C/A - GLONASS observables into the RINEX file
|
||||||
*/
|
*/
|
||||||
void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double gps_obs_time, const std::map<int, Gnss_Synchro>& observables);
|
void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double gps_obs_time, const std::map<int32_t, Gnss_Synchro>& observables);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Writes Mixed GPS L2C - GLONASS observables into the RINEX file
|
* \brief Writes Mixed GPS L2C - GLONASS observables into the RINEX file
|
||||||
*/
|
*/
|
||||||
void log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& gps_cnav_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double gps_obs_time, const std::map<int, Gnss_Synchro>& observables);
|
void log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& gps_cnav_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double gps_obs_time, const std::map<int32_t, Gnss_Synchro>& observables);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Writes Mixed Galileo/GLONASS observables into the RINEX file
|
* \brief Writes Mixed Galileo/GLONASS observables into the RINEX file
|
||||||
*/
|
*/
|
||||||
void log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& galileo_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double gps_obs_time, const std::map<int, Gnss_Synchro>& observables);
|
void log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& galileo_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double gps_obs_time, const std::map<int32_t, Gnss_Synchro>& observables);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Represents GPS time in the date time format. Leap years are considered, but leap seconds are not.
|
* \brief Represents GPS time in the date time format. Leap years are considered, but leap seconds are not.
|
||||||
@ -523,9 +524,9 @@ private:
|
|||||||
/*
|
/*
|
||||||
* Convert a string to an integer.
|
* Convert a string to an integer.
|
||||||
* @param s string containing a number.
|
* @param s string containing a number.
|
||||||
* @return long integer representation of string.
|
* @return int64_t integer representation of string.
|
||||||
*/
|
*/
|
||||||
inline long asInt(const std::string& s)
|
inline int64_t asInt(const std::string& s)
|
||||||
{
|
{
|
||||||
return strtol(s.c_str(), 0, 10);
|
return strtol(s.c_str(), 0, 10);
|
||||||
}
|
}
|
||||||
@ -658,7 +659,7 @@ inline std::string& Rinex_Printer::sci2for(std::string& aStr,
|
|||||||
std::string::size_type idx = aStr.find('.', startPos);
|
std::string::size_type idx = aStr.find('.', startPos);
|
||||||
int expAdd = 0;
|
int expAdd = 0;
|
||||||
std::string exp;
|
std::string exp;
|
||||||
long iexp;
|
int64_t iexp;
|
||||||
//If checkSwitch is false, always redo the exponential. Otherwise,
|
//If checkSwitch is false, always redo the exponential. Otherwise,
|
||||||
//set it to false.
|
//set it to false.
|
||||||
bool redoexp = !checkSwitch;
|
bool redoexp = !checkSwitch;
|
||||||
@ -761,7 +762,7 @@ inline std::string Rinex_Printer::asFixWidthString(const int x, const int width,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline long asInt(const std::string& s)
|
inline int64_t asInt(const std::string& s)
|
||||||
{
|
{
|
||||||
return strtol(s.c_str(), 0, 10);
|
return strtol(s.c_str(), 0, 10);
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
using google::LogMessage;
|
using google::LogMessage;
|
||||||
|
|
||||||
|
|
||||||
Rtcm_Printer::Rtcm_Printer(std::string filename, bool flag_rtcm_server, bool flag_rtcm_tty_port, unsigned short rtcm_tcp_port, unsigned short rtcm_station_id, std::string rtcm_dump_devname, bool time_tag_name)
|
Rtcm_Printer::Rtcm_Printer(std::string filename, bool flag_rtcm_server, bool flag_rtcm_tty_port, uint16_t rtcm_tcp_port, uint16_t rtcm_station_id, std::string rtcm_dump_devname, bool time_tag_name)
|
||||||
{
|
{
|
||||||
boost::posix_time::ptime pt = boost::posix_time::second_clock::local_time();
|
boost::posix_time::ptime pt = boost::posix_time::second_clock::local_time();
|
||||||
tm timeinfo = boost::posix_time::to_tm(pt);
|
tm timeinfo = boost::posix_time::to_tm(pt);
|
||||||
@ -50,33 +50,33 @@ Rtcm_Printer::Rtcm_Printer(std::string filename, bool flag_rtcm_server, bool fla
|
|||||||
if (time_tag_name)
|
if (time_tag_name)
|
||||||
{
|
{
|
||||||
std::stringstream strm0;
|
std::stringstream strm0;
|
||||||
const int year = timeinfo.tm_year - 100;
|
const int32_t year = timeinfo.tm_year - 100;
|
||||||
strm0 << year;
|
strm0 << year;
|
||||||
const int month = timeinfo.tm_mon + 1;
|
const int32_t month = timeinfo.tm_mon + 1;
|
||||||
if (month < 10)
|
if (month < 10)
|
||||||
{
|
{
|
||||||
strm0 << "0";
|
strm0 << "0";
|
||||||
}
|
}
|
||||||
strm0 << month;
|
strm0 << month;
|
||||||
const int day = timeinfo.tm_mday;
|
const int32_t day = timeinfo.tm_mday;
|
||||||
if (day < 10)
|
if (day < 10)
|
||||||
{
|
{
|
||||||
strm0 << "0";
|
strm0 << "0";
|
||||||
}
|
}
|
||||||
strm0 << day << "_";
|
strm0 << day << "_";
|
||||||
const int hour = timeinfo.tm_hour;
|
const int32_t hour = timeinfo.tm_hour;
|
||||||
if (hour < 10)
|
if (hour < 10)
|
||||||
{
|
{
|
||||||
strm0 << "0";
|
strm0 << "0";
|
||||||
}
|
}
|
||||||
strm0 << hour;
|
strm0 << hour;
|
||||||
const int min = timeinfo.tm_min;
|
const int32_t min = timeinfo.tm_min;
|
||||||
if (min < 10)
|
if (min < 10)
|
||||||
{
|
{
|
||||||
strm0 << "0";
|
strm0 << "0";
|
||||||
}
|
}
|
||||||
strm0 << min;
|
strm0 << min;
|
||||||
const int sec = timeinfo.tm_sec;
|
const int32_t sec = timeinfo.tm_sec;
|
||||||
if (sec < 10)
|
if (sec < 10)
|
||||||
{
|
{
|
||||||
strm0 << "0";
|
strm0 << "0";
|
||||||
@ -153,7 +153,7 @@ Rtcm_Printer::~Rtcm_Printer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Rtcm_Printer::Print_Rtcm_MT1001(const Gps_Ephemeris& gps_eph, double obs_time, const std::map<int, Gnss_Synchro>& observables)
|
bool Rtcm_Printer::Print_Rtcm_MT1001(const Gps_Ephemeris& gps_eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables)
|
||||||
{
|
{
|
||||||
std::string m1001 = rtcm->print_MT1001(gps_eph, obs_time, observables, station_id);
|
std::string m1001 = rtcm->print_MT1001(gps_eph, obs_time, observables, station_id);
|
||||||
Rtcm_Printer::Print_Message(m1001);
|
Rtcm_Printer::Print_Message(m1001);
|
||||||
@ -161,7 +161,7 @@ bool Rtcm_Printer::Print_Rtcm_MT1001(const Gps_Ephemeris& gps_eph, double obs_ti
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Rtcm_Printer::Print_Rtcm_MT1002(const Gps_Ephemeris& gps_eph, double obs_time, const std::map<int, Gnss_Synchro>& observables)
|
bool Rtcm_Printer::Print_Rtcm_MT1002(const Gps_Ephemeris& gps_eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables)
|
||||||
{
|
{
|
||||||
std::string m1002 = rtcm->print_MT1002(gps_eph, obs_time, observables, station_id);
|
std::string m1002 = rtcm->print_MT1002(gps_eph, obs_time, observables, station_id);
|
||||||
Rtcm_Printer::Print_Message(m1002);
|
Rtcm_Printer::Print_Message(m1002);
|
||||||
@ -169,7 +169,7 @@ bool Rtcm_Printer::Print_Rtcm_MT1002(const Gps_Ephemeris& gps_eph, double obs_ti
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Rtcm_Printer::Print_Rtcm_MT1003(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map<int, Gnss_Synchro>& observables)
|
bool Rtcm_Printer::Print_Rtcm_MT1003(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables)
|
||||||
{
|
{
|
||||||
std::string m1003 = rtcm->print_MT1003(gps_eph, cnav_eph, obs_time, observables, station_id);
|
std::string m1003 = rtcm->print_MT1003(gps_eph, cnav_eph, obs_time, observables, station_id);
|
||||||
Rtcm_Printer::Print_Message(m1003);
|
Rtcm_Printer::Print_Message(m1003);
|
||||||
@ -177,7 +177,7 @@ bool Rtcm_Printer::Print_Rtcm_MT1003(const Gps_Ephemeris& gps_eph, const Gps_CNA
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Rtcm_Printer::Print_Rtcm_MT1004(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map<int, Gnss_Synchro>& observables)
|
bool Rtcm_Printer::Print_Rtcm_MT1004(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables)
|
||||||
{
|
{
|
||||||
std::string m1003 = rtcm->print_MT1004(gps_eph, cnav_eph, obs_time, observables, station_id);
|
std::string m1003 = rtcm->print_MT1004(gps_eph, cnav_eph, obs_time, observables, station_id);
|
||||||
Rtcm_Printer::Print_Message(m1003);
|
Rtcm_Printer::Print_Message(m1003);
|
||||||
@ -185,7 +185,7 @@ bool Rtcm_Printer::Print_Rtcm_MT1004(const Gps_Ephemeris& gps_eph, const Gps_CNA
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Rtcm_Printer::Print_Rtcm_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map<int, Gnss_Synchro>& observables)
|
bool Rtcm_Printer::Print_Rtcm_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables)
|
||||||
{
|
{
|
||||||
std::string m1009 = rtcm->print_MT1009(glonass_gnav_eph, obs_time, observables, station_id);
|
std::string m1009 = rtcm->print_MT1009(glonass_gnav_eph, obs_time, observables, station_id);
|
||||||
Rtcm_Printer::Print_Message(m1009);
|
Rtcm_Printer::Print_Message(m1009);
|
||||||
@ -193,7 +193,7 @@ bool Rtcm_Printer::Print_Rtcm_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Rtcm_Printer::Print_Rtcm_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map<int, Gnss_Synchro>& observables)
|
bool Rtcm_Printer::Print_Rtcm_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables)
|
||||||
{
|
{
|
||||||
std::string m1010 = rtcm->print_MT1010(glonass_gnav_eph, obs_time, observables, station_id);
|
std::string m1010 = rtcm->print_MT1010(glonass_gnav_eph, obs_time, observables, station_id);
|
||||||
Rtcm_Printer::Print_Message(m1010);
|
Rtcm_Printer::Print_Message(m1010);
|
||||||
@ -201,7 +201,7 @@ bool Rtcm_Printer::Print_Rtcm_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Rtcm_Printer::Print_Rtcm_MT1011(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map<int, Gnss_Synchro>& observables)
|
bool Rtcm_Printer::Print_Rtcm_MT1011(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables)
|
||||||
{
|
{
|
||||||
std::string m1011 = rtcm->print_MT1011(glonass_gnav_ephL1, glonass_gnav_ephL2, obs_time, observables, station_id);
|
std::string m1011 = rtcm->print_MT1011(glonass_gnav_ephL1, glonass_gnav_ephL2, obs_time, observables, station_id);
|
||||||
Rtcm_Printer::Print_Message(m1011);
|
Rtcm_Printer::Print_Message(m1011);
|
||||||
@ -209,7 +209,7 @@ bool Rtcm_Printer::Print_Rtcm_MT1011(const Glonass_Gnav_Ephemeris& glonass_gnav_
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Rtcm_Printer::Print_Rtcm_MT1012(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map<int, Gnss_Synchro>& observables)
|
bool Rtcm_Printer::Print_Rtcm_MT1012(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables)
|
||||||
{
|
{
|
||||||
std::string m1012 = rtcm->print_MT1012(glonass_gnav_ephL1, glonass_gnav_ephL2, obs_time, observables, station_id);
|
std::string m1012 = rtcm->print_MT1012(glonass_gnav_ephL1, glonass_gnav_ephL2, obs_time, observables, station_id);
|
||||||
Rtcm_Printer::Print_Message(m1012);
|
Rtcm_Printer::Print_Message(m1012);
|
||||||
@ -241,15 +241,15 @@ bool Rtcm_Printer::Print_Rtcm_MT1045(const Galileo_Ephemeris& gal_eph)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Rtcm_Printer::Print_Rtcm_MSM(unsigned int msm_number, const Gps_Ephemeris& gps_eph,
|
bool Rtcm_Printer::Print_Rtcm_MSM(uint32_t msm_number, const Gps_Ephemeris& gps_eph,
|
||||||
const Gps_CNAV_Ephemeris& gps_cnav_eph,
|
const Gps_CNAV_Ephemeris& gps_cnav_eph,
|
||||||
const Galileo_Ephemeris& gal_eph,
|
const Galileo_Ephemeris& gal_eph,
|
||||||
const Glonass_Gnav_Ephemeris& glo_gnav_eph,
|
const Glonass_Gnav_Ephemeris& glo_gnav_eph,
|
||||||
double obs_time,
|
double obs_time,
|
||||||
const std::map<int, Gnss_Synchro>& observables,
|
const std::map<int32_t, Gnss_Synchro>& observables,
|
||||||
unsigned int clock_steering_indicator,
|
uint32_t clock_steering_indicator,
|
||||||
unsigned int external_clock_indicator,
|
uint32_t external_clock_indicator,
|
||||||
int smooth_int,
|
int32_t smooth_int,
|
||||||
bool divergence_free,
|
bool divergence_free,
|
||||||
bool more_messages)
|
bool more_messages)
|
||||||
{
|
{
|
||||||
@ -297,7 +297,7 @@ int Rtcm_Printer::init_serial(std::string serial_device)
|
|||||||
/*
|
/*
|
||||||
* Opens the serial device and sets the default baud rate for a RTCM transmission (9600,8,N,1)
|
* Opens the serial device and sets the default baud rate for a RTCM transmission (9600,8,N,1)
|
||||||
*/
|
*/
|
||||||
int fd = 0;
|
int32_t fd = 0;
|
||||||
struct termios options;
|
struct termios options;
|
||||||
long BAUD;
|
long BAUD;
|
||||||
long DATABITS;
|
long DATABITS;
|
||||||
@ -372,25 +372,25 @@ std::string Rtcm_Printer::print_MT1005_test()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int Rtcm_Printer::lock_time(const Gps_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro)
|
uint32_t Rtcm_Printer::lock_time(const Gps_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro)
|
||||||
{
|
{
|
||||||
return rtcm->lock_time(eph, obs_time, gnss_synchro);
|
return rtcm->lock_time(eph, obs_time, gnss_synchro);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int Rtcm_Printer::lock_time(const Gps_CNAV_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro)
|
uint32_t Rtcm_Printer::lock_time(const Gps_CNAV_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro)
|
||||||
{
|
{
|
||||||
return rtcm->lock_time(eph, obs_time, gnss_synchro);
|
return rtcm->lock_time(eph, obs_time, gnss_synchro);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int Rtcm_Printer::lock_time(const Galileo_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro)
|
uint32_t Rtcm_Printer::lock_time(const Galileo_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro)
|
||||||
{
|
{
|
||||||
return rtcm->lock_time(eph, obs_time, gnss_synchro);
|
return rtcm->lock_time(eph, obs_time, gnss_synchro);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int Rtcm_Printer::lock_time(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro)
|
uint32_t Rtcm_Printer::lock_time(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro)
|
||||||
{
|
{
|
||||||
return rtcm->lock_time(eph, obs_time, gnss_synchro);
|
return rtcm->lock_time(eph, obs_time, gnss_synchro);
|
||||||
}
|
}
|
||||||
|
@ -48,17 +48,17 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief Default constructor.
|
* \brief Default constructor.
|
||||||
*/
|
*/
|
||||||
Rtcm_Printer(std::string filename, bool flag_rtcm_server, bool flag_rtcm_tty_port, unsigned short rtcm_tcp_port, unsigned short rtcm_station_id, std::string rtcm_dump_filename, bool time_tag_name = true);
|
Rtcm_Printer(std::string filename, bool flag_rtcm_server, bool flag_rtcm_tty_port, uint16_t rtcm_tcp_port, uint16_t rtcm_station_id, std::string rtcm_dump_filename, bool time_tag_name = true);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Default destructor.
|
* \brief Default destructor.
|
||||||
*/
|
*/
|
||||||
~Rtcm_Printer();
|
~Rtcm_Printer();
|
||||||
|
|
||||||
bool Print_Rtcm_MT1001(const Gps_Ephemeris& gps_eph, double obs_time, const std::map<int, Gnss_Synchro>& observables);
|
bool Print_Rtcm_MT1001(const Gps_Ephemeris& gps_eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables);
|
||||||
bool Print_Rtcm_MT1002(const Gps_Ephemeris& gps_eph, double obs_time, const std::map<int, Gnss_Synchro>& observables);
|
bool Print_Rtcm_MT1002(const Gps_Ephemeris& gps_eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables);
|
||||||
bool Print_Rtcm_MT1003(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map<int, Gnss_Synchro>& observables);
|
bool Print_Rtcm_MT1003(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables);
|
||||||
bool Print_Rtcm_MT1004(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map<int, Gnss_Synchro>& observables);
|
bool Print_Rtcm_MT1004(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables);
|
||||||
/*!
|
/*!
|
||||||
* \brief Prints L1-Only GLONASS RTK Observables
|
* \brief Prints L1-Only GLONASS RTK Observables
|
||||||
* \details This GLONASS message type is not generally used or supported; type 1012 is to be preferred.
|
* \details This GLONASS message type is not generally used or supported; type 1012 is to be preferred.
|
||||||
@ -68,7 +68,7 @@ public:
|
|||||||
* \param observables Set of observables as defined by the platform
|
* \param observables Set of observables as defined by the platform
|
||||||
* \return true or false upon operation success
|
* \return true or false upon operation success
|
||||||
*/
|
*/
|
||||||
bool Print_Rtcm_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map<int, Gnss_Synchro>& observables);
|
bool Print_Rtcm_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables);
|
||||||
/*!
|
/*!
|
||||||
* \brief Prints Extended L1-Only GLONASS RTK Observables
|
* \brief Prints Extended L1-Only GLONASS RTK Observables
|
||||||
* \details This GLONASS message type is used when only L1 data is present and bandwidth is very tight, often 1012 is used in such cases.
|
* \details This GLONASS message type is used when only L1 data is present and bandwidth is very tight, often 1012 is used in such cases.
|
||||||
@ -78,7 +78,7 @@ public:
|
|||||||
* \param observables Set of observables as defined by the platform
|
* \param observables Set of observables as defined by the platform
|
||||||
* \return true or false upon operation success
|
* \return true or false upon operation success
|
||||||
*/
|
*/
|
||||||
bool Print_Rtcm_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map<int, Gnss_Synchro>& observables);
|
bool Print_Rtcm_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables);
|
||||||
/*!
|
/*!
|
||||||
* \brief Prints L1&L2 GLONASS RTK Observables
|
* \brief Prints L1&L2 GLONASS RTK Observables
|
||||||
* \details This GLONASS message type is not generally used or supported; type 1012 is to be preferred
|
* \details This GLONASS message type is not generally used or supported; type 1012 is to be preferred
|
||||||
@ -89,7 +89,7 @@ public:
|
|||||||
* \param observables Set of observables as defined by the platform
|
* \param observables Set of observables as defined by the platform
|
||||||
* \return true or false upon operation success
|
* \return true or false upon operation success
|
||||||
*/
|
*/
|
||||||
bool Print_Rtcm_MT1011(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map<int, Gnss_Synchro>& observables);
|
bool Print_Rtcm_MT1011(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables);
|
||||||
/*!
|
/*!
|
||||||
* \brief Prints Extended L1&L2 GLONASS RTK Observables
|
* \brief Prints Extended L1&L2 GLONASS RTK Observables
|
||||||
* \details This GLONASS message type is the most common observational message type, with L1/L2/SNR content. This is one of the most common messages found.
|
* \details This GLONASS message type is the most common observational message type, with L1/L2/SNR content. This is one of the most common messages found.
|
||||||
@ -100,7 +100,7 @@ public:
|
|||||||
* \param observables Set of observables as defined by the platform
|
* \param observables Set of observables as defined by the platform
|
||||||
* \return true or false upon operation success
|
* \return true or false upon operation success
|
||||||
*/
|
*/
|
||||||
bool Print_Rtcm_MT1012(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map<int, Gnss_Synchro>& observables);
|
bool Print_Rtcm_MT1012(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables);
|
||||||
|
|
||||||
bool Print_Rtcm_MT1019(const Gps_Ephemeris& gps_eph); //<! GPS Ephemeris, should be broadcast in the event that the IODC does not match the IODE, and every 2 minutes.
|
bool Print_Rtcm_MT1019(const Gps_Ephemeris& gps_eph); //<! GPS Ephemeris, should be broadcast in the event that the IODC does not match the IODE, and every 2 minutes.
|
||||||
bool Print_Rtcm_MT1045(const Galileo_Ephemeris& gal_eph); //<! Galileo Ephemeris, should be broadcast every 2 minutes
|
bool Print_Rtcm_MT1045(const Galileo_Ephemeris& gal_eph); //<! Galileo Ephemeris, should be broadcast every 2 minutes
|
||||||
@ -114,23 +114,23 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool Print_Rtcm_MT1020(const Glonass_Gnav_Ephemeris& glo_gnav_eph, const Glonass_Gnav_Utc_Model& utc_model);
|
bool Print_Rtcm_MT1020(const Glonass_Gnav_Ephemeris& glo_gnav_eph, const Glonass_Gnav_Utc_Model& utc_model);
|
||||||
|
|
||||||
bool Print_Rtcm_MSM(unsigned int msm_number,
|
bool Print_Rtcm_MSM(uint32_t msm_number,
|
||||||
const Gps_Ephemeris& gps_eph,
|
const Gps_Ephemeris& gps_eph,
|
||||||
const Gps_CNAV_Ephemeris& gps_cnav_eph,
|
const Gps_CNAV_Ephemeris& gps_cnav_eph,
|
||||||
const Galileo_Ephemeris& gal_eph,
|
const Galileo_Ephemeris& gal_eph,
|
||||||
const Glonass_Gnav_Ephemeris& glo_gnav_eph,
|
const Glonass_Gnav_Ephemeris& glo_gnav_eph,
|
||||||
double obs_time,
|
double obs_time,
|
||||||
const std::map<int, Gnss_Synchro>& observables,
|
const std::map<int32_t, Gnss_Synchro>& observables,
|
||||||
unsigned int clock_steering_indicator,
|
uint32_t clock_steering_indicator,
|
||||||
unsigned int external_clock_indicator,
|
uint32_t external_clock_indicator,
|
||||||
int smooth_int,
|
int32_t smooth_int,
|
||||||
bool divergence_free,
|
bool divergence_free,
|
||||||
bool more_messages);
|
bool more_messages);
|
||||||
|
|
||||||
std::string print_MT1005_test(); //<! For testing purposes
|
std::string print_MT1005_test(); //<! For testing purposes
|
||||||
unsigned int lock_time(const Gps_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro);
|
uint32_t lock_time(const Gps_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro);
|
||||||
unsigned int lock_time(const Gps_CNAV_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro);
|
uint32_t lock_time(const Gps_CNAV_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro);
|
||||||
unsigned int lock_time(const Galileo_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro);
|
uint32_t lock_time(const Galileo_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro);
|
||||||
/*!
|
/*!
|
||||||
* \brief Locks time for logging given GLONASS GNAV Broadcast Ephemeris
|
* \brief Locks time for logging given GLONASS GNAV Broadcast Ephemeris
|
||||||
* \note Code added as part of GSoC 2017 program
|
* \note Code added as part of GSoC 2017 program
|
||||||
@ -139,16 +139,16 @@ public:
|
|||||||
* \params observables Set of observables as defined by the platform
|
* \params observables Set of observables as defined by the platform
|
||||||
* \return locked time during logging process
|
* \return locked time during logging process
|
||||||
*/
|
*/
|
||||||
unsigned int lock_time(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro);
|
uint32_t lock_time(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string rtcm_filename; // String with the RTCM log filename
|
std::string rtcm_filename; // String with the RTCM log filename
|
||||||
std::ofstream rtcm_file_descriptor; // Output file stream for RTCM log file
|
std::ofstream rtcm_file_descriptor; // Output file stream for RTCM log file
|
||||||
std::string rtcm_devname;
|
std::string rtcm_devname;
|
||||||
unsigned short port;
|
uint16_t port;
|
||||||
unsigned short station_id;
|
uint16_t station_id;
|
||||||
int rtcm_dev_descriptor; // RTCM serial device descriptor (i.e. COM port)
|
int32_t rtcm_dev_descriptor; // RTCM serial device descriptor (i.e. COM port)
|
||||||
int init_serial(std::string serial_device); //serial port control
|
int32_t init_serial(std::string serial_device); //serial port control
|
||||||
void close_serial();
|
void close_serial();
|
||||||
std::shared_ptr<Rtcm> rtcm;
|
std::shared_ptr<Rtcm> rtcm;
|
||||||
bool Print_Message(const std::string& message);
|
bool Print_Message(const std::string& message);
|
||||||
|
@ -176,6 +176,7 @@ bool rtklib_solver::get_PVT(const std::map<int, Gnss_Synchro>& gnss_observables_
|
|||||||
band2 = true;
|
band2 = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -495,7 +496,8 @@ bool rtklib_solver::get_PVT(const std::map<int, Gnss_Synchro>& gnss_observables_
|
|||||||
if (rtk_.ssat[i].vsat[0] == 1) used_sats++;
|
if (rtk_.ssat[i].vsat[0] == 1) used_sats++;
|
||||||
}
|
}
|
||||||
|
|
||||||
double azel[used_sats * 2];
|
std::vector<double> azel;
|
||||||
|
azel.reserve(used_sats * 2);
|
||||||
unsigned int index_aux = 0;
|
unsigned int index_aux = 0;
|
||||||
for (unsigned int i = 0; i < MAXSAT; i++)
|
for (unsigned int i = 0; i < MAXSAT; i++)
|
||||||
{
|
{
|
||||||
@ -506,7 +508,7 @@ bool rtklib_solver::get_PVT(const std::map<int, Gnss_Synchro>& gnss_observables_
|
|||||||
index_aux++;
|
index_aux++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (index_aux > 0) dops(index_aux, azel, 0.0, dop_);
|
if (index_aux > 0) dops(index_aux, azel.data(), 0.0, dop_);
|
||||||
|
|
||||||
this->set_valid_position(true);
|
this->set_valid_position(true);
|
||||||
arma::vec rx_position_and_time(4);
|
arma::vec rx_position_and_time(4);
|
||||||
|
@ -19,3 +19,4 @@
|
|||||||
add_subdirectory(adapters)
|
add_subdirectory(adapters)
|
||||||
add_subdirectory(gnuradio_blocks)
|
add_subdirectory(gnuradio_blocks)
|
||||||
add_subdirectory(libs)
|
add_subdirectory(libs)
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ set(ACQ_ADAPTER_SOURCES
|
|||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_FPGA)
|
if(ENABLE_FPGA)
|
||||||
set(ACQ_ADAPTER_SOURCES ${ACQ_ADAPTER_SOURCES} gps_l1_ca_pcps_acquisition_fpga.cc)
|
set(ACQ_ADAPTER_SOURCES ${ACQ_ADAPTER_SOURCES} gps_l1_ca_pcps_acquisition_fpga.cc gps_l2_m_pcps_acquisition_fpga.cc galileo_e1_pcps_ambiguous_acquisition_fpga.cc galileo_e5a_pcps_acquisition_fpga.cc gps_l5i_pcps_acquisition_fpga.cc)
|
||||||
endif(ENABLE_FPGA)
|
endif(ENABLE_FPGA)
|
||||||
|
|
||||||
if(OPENCL_FOUND)
|
if(OPENCL_FOUND)
|
||||||
|
@ -62,8 +62,14 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
|
|||||||
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
|
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
|
||||||
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
|
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
|
||||||
acq_parameters.doppler_max = doppler_max_;
|
acq_parameters.doppler_max = doppler_max_;
|
||||||
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 4);
|
acq_parameters.ms_per_code = 4;
|
||||||
|
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", acq_parameters.ms_per_code);
|
||||||
acq_parameters.sampled_ms = sampled_ms_;
|
acq_parameters.sampled_ms = sampled_ms_;
|
||||||
|
if ((acq_parameters.sampled_ms % acq_parameters.ms_per_code) != 0)
|
||||||
|
{
|
||||||
|
LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 4. Setting it to 4";
|
||||||
|
acq_parameters.sampled_ms = acq_parameters.ms_per_code;
|
||||||
|
}
|
||||||
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
||||||
acq_parameters.bit_transition_flag = bit_transition_flag_;
|
acq_parameters.bit_transition_flag = bit_transition_flag_;
|
||||||
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
|
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
|
||||||
@ -79,10 +85,11 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
|
|||||||
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
||||||
acq_parameters.dump_filename = dump_filename_;
|
acq_parameters.dump_filename = dump_filename_;
|
||||||
//--- Find number of samples per spreading code (4 ms) -----------------
|
//--- Find number of samples per spreading code (4 ms) -----------------
|
||||||
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS)));
|
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS)));
|
||||||
acq_parameters.samples_per_code = code_length_;
|
|
||||||
int samples_per_ms = static_cast<int>(std::round(static_cast<double>(fs_in_) * 0.001));
|
float samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||||
acq_parameters.samples_per_ms = samples_per_ms;
|
acq_parameters.samples_per_ms = samples_per_ms;
|
||||||
|
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(Galileo_E1_CODE_PERIOD_MS);
|
||||||
vector_length_ = sampled_ms_ * samples_per_ms;
|
vector_length_ = sampled_ms_ * samples_per_ms;
|
||||||
|
|
||||||
if (bit_transition_flag_)
|
if (bit_transition_flag_)
|
||||||
@ -108,9 +115,6 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
|
|||||||
acquisition_ = pcps_make_acquisition(acq_parameters);
|
acquisition_ = pcps_make_acquisition(acq_parameters);
|
||||||
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
|
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
|
||||||
|
|
||||||
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
|
|
||||||
DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")";
|
|
||||||
|
|
||||||
if (item_type_.compare("cbyte") == 0)
|
if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
|
cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
|
||||||
@ -271,18 +275,19 @@ void GalileoE1PcpsAmbiguousAcquisition::connect(gr::top_block_sptr top_block)
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to connect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to connect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
|
// Since a byte-based acq implementation is not available,
|
||||||
|
// we just convert cshorts to gr_complex
|
||||||
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
top_block->connect(float_to_complex_, 0, stream_to_vector_, 0);
|
top_block->connect(float_to_complex_, 0, acquisition_, 0);
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -295,20 +300,17 @@ void GalileoE1PcpsAmbiguousAcquisition::disconnect(gr::top_block_sptr top_block)
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to disconnect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to disconnect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
// Since a byte-based acq implementation is not available,
|
|
||||||
// we just convert cshorts to gr_complex
|
|
||||||
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0);
|
top_block->disconnect(float_to_complex_, 0, acquisition_, 0);
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -321,11 +323,11 @@ gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisition::get_left_block()
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
return stream_to_vector_;
|
return acquisition_;
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
return stream_to_vector_;
|
return acquisition_;
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
|
@ -36,7 +36,6 @@
|
|||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "pcps_acquisition.h"
|
#include "pcps_acquisition.h"
|
||||||
#include "complex_byte_to_float_x2.h"
|
#include "complex_byte_to_float_x2.h"
|
||||||
#include <gnuradio/blocks/stream_to_vector.h>
|
|
||||||
#include <gnuradio/blocks/float_to_complex.h>
|
#include <gnuradio/blocks/float_to_complex.h>
|
||||||
#include <volk_gnsssdr/volk_gnsssdr.h>
|
#include <volk_gnsssdr/volk_gnsssdr.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -135,7 +134,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
pcps_acquisition_sptr acquisition_;
|
pcps_acquisition_sptr acquisition_;
|
||||||
gr::blocks::stream_to_vector::sptr stream_to_vector_;
|
|
||||||
gr::blocks::float_to_complex::sptr float_to_complex_;
|
gr::blocks::float_to_complex::sptr float_to_complex_;
|
||||||
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
|
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
|
||||||
size_t item_size_;
|
size_t item_size_;
|
||||||
|
@ -0,0 +1,552 @@
|
|||||||
|
/*!
|
||||||
|
* \file galileo_e1_pcps_ambiguous_acquisition.cc
|
||||||
|
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||||
|
* Galileo E1 Signals
|
||||||
|
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2015 (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_ambiguous_acquisition_fpga.h"
|
||||||
|
#include "configuration_interface.h"
|
||||||
|
#include "galileo_e1_signal_processing.h"
|
||||||
|
#include "Galileo_E1.h"
|
||||||
|
#include "gnss_sdr_flags.h"
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include <boost/math/distributions/exponential.hpp>
|
||||||
|
#include <glog/logging.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
using google::LogMessage;
|
||||||
|
|
||||||
|
GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
|
||||||
|
ConfigurationInterface* configuration, std::string role,
|
||||||
|
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
|
||||||
|
{
|
||||||
|
//printf("top acq constructor start\n");
|
||||||
|
pcpsconf_fpga_t acq_parameters;
|
||||||
|
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);
|
||||||
|
|
||||||
|
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000);
|
||||||
|
long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||||
|
acq_parameters.fs_in = fs_in;
|
||||||
|
//if_ = configuration_->property(role + ".if", 0);
|
||||||
|
//acq_parameters.freq = if_;
|
||||||
|
|
||||||
|
// dump_ = configuration_->property(role + ".dump", false);
|
||||||
|
// acq_parameters.dump = dump_;
|
||||||
|
// blocking_ = configuration_->property(role + ".blocking", true);
|
||||||
|
// acq_parameters.blocking = blocking_;
|
||||||
|
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
|
||||||
|
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
|
||||||
|
acq_parameters.doppler_max = doppler_max_;
|
||||||
|
//unsigned int sampled_ms = 4;
|
||||||
|
//acq_parameters.sampled_ms = sampled_ms;
|
||||||
|
unsigned int sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 4);
|
||||||
|
acq_parameters.sampled_ms = sampled_ms;
|
||||||
|
|
||||||
|
// bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
||||||
|
// acq_parameters.bit_transition_flag = bit_transition_flag_;
|
||||||
|
// use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
|
||||||
|
// acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
|
||||||
|
acquire_pilot_ = configuration_->property(role + ".acquire_pilot", false); //will be true in future versions
|
||||||
|
|
||||||
|
// max_dwells_ = configuration_->property(role + ".max_dwells", 1);
|
||||||
|
// acq_parameters.max_dwells = max_dwells_;
|
||||||
|
// dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
||||||
|
// acq_parameters.dump_filename = dump_filename_;
|
||||||
|
//--- Find number of samples per spreading code (4 ms) -----------------
|
||||||
|
unsigned int code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS)));
|
||||||
|
//acq_parameters.samples_per_code = code_length_;
|
||||||
|
//int samples_per_ms = static_cast<int>(std::round(static_cast<double>(fs_in_) * 0.001));
|
||||||
|
//acq_parameters.samples_per_ms = samples_per_ms;
|
||||||
|
//unsigned int vector_length = sampled_ms * samples_per_ms;
|
||||||
|
|
||||||
|
// if (bit_transition_flag_)
|
||||||
|
// {
|
||||||
|
// vector_length_ *= 2;
|
||||||
|
// }
|
||||||
|
|
||||||
|
//printf("fs_in = %d\n", fs_in);
|
||||||
|
//printf("Galileo_E1_B_CODE_LENGTH_CHIPS = %f\n", Galileo_E1_B_CODE_LENGTH_CHIPS);
|
||||||
|
//printf("Galileo_E1_CODE_CHIP_RATE_HZ = %f\n", Galileo_E1_CODE_CHIP_RATE_HZ);
|
||||||
|
//printf("acq adapter code_length = %d\n", code_length);
|
||||||
|
acq_parameters.code_length = code_length;
|
||||||
|
// The FPGA can only use FFT lengths that are a power of two.
|
||||||
|
float nbits = ceilf(log2f((float)code_length));
|
||||||
|
unsigned int nsamples_total = pow(2, nbits);
|
||||||
|
unsigned int vector_length = nsamples_total;
|
||||||
|
//printf("acq adapter nsamples_total (= vector_length) = %d\n", vector_length);
|
||||||
|
unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0);
|
||||||
|
acq_parameters.select_queue_Fpga = select_queue_Fpga;
|
||||||
|
std::string default_device_name = "/dev/uio0";
|
||||||
|
std::string device_name = configuration_->property(role + ".devicename", default_device_name);
|
||||||
|
acq_parameters.device_name = device_name;
|
||||||
|
acq_parameters.samples_per_ms = nsamples_total/sampled_ms;
|
||||||
|
acq_parameters.samples_per_code = nsamples_total;
|
||||||
|
|
||||||
|
// compute all the GALILEO E1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time
|
||||||
|
// a channel is assigned)
|
||||||
|
gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT
|
||||||
|
std::complex<float>* code = new std::complex<float>[nsamples_total]; // buffer for the local code
|
||||||
|
gr_complex* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||||
|
d_all_fft_codes_ = new lv_16sc_t[nsamples_total * Galileo_E1_NUMBER_OF_CODES]; // memory containing all the possible fft codes for PRN 0 to 32
|
||||||
|
float max; // temporary maxima search
|
||||||
|
|
||||||
|
//int tmp_re, tmp_im;
|
||||||
|
|
||||||
|
for (unsigned int PRN = 1; PRN <= Galileo_E1_NUMBER_OF_CODES; PRN++)
|
||||||
|
{
|
||||||
|
|
||||||
|
//code_ = new gr_complex[vector_length_];
|
||||||
|
|
||||||
|
bool cboc = false; // cboc is set to 0 when using the FPGA
|
||||||
|
|
||||||
|
//std::complex<float>* code = new std::complex<float>[code_length_];
|
||||||
|
|
||||||
|
if (acquire_pilot_ == true)
|
||||||
|
{
|
||||||
|
//printf("yes acquiring pilot!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1\n");
|
||||||
|
//set local signal generator to Galileo E1 pilot component (1C)
|
||||||
|
char pilot_signal[3] = "1C";
|
||||||
|
galileo_e1_code_gen_complex_sampled(code, pilot_signal,
|
||||||
|
cboc, PRN, fs_in, 0, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char data_signal[3] = "1B";
|
||||||
|
galileo_e1_code_gen_complex_sampled(code, data_signal,
|
||||||
|
cboc, PRN, fs_in, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for (unsigned int i = 0; i < sampled_ms / 4; i++)
|
||||||
|
// {
|
||||||
|
// //memcpy(&(code_[i * code_length_]), code, sizeof(gr_complex) * code_length_);
|
||||||
|
// memcpy(&(d_all_fft_codes_[i * code_length_]), code, sizeof(gr_complex) * code_length_);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// // debug
|
||||||
|
// char filename[25];
|
||||||
|
// FILE *fid;
|
||||||
|
// sprintf(filename,"gal_prn%d.txt", PRN);
|
||||||
|
// fid = fopen(filename, "w");
|
||||||
|
// for (unsigned int kk=0;kk< nsamples_total; kk++)
|
||||||
|
// {
|
||||||
|
// fprintf(fid, "%f\n", code[kk].real());
|
||||||
|
// fprintf(fid, "%f\n", code[kk].imag());
|
||||||
|
// }
|
||||||
|
// fclose(fid);
|
||||||
|
|
||||||
|
|
||||||
|
// // fill in zero padding
|
||||||
|
for (int s = code_length; s < nsamples_total; s++)
|
||||||
|
{
|
||||||
|
code[s] = std::complex<float>(static_cast<float>(0,0));
|
||||||
|
//code[s] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer
|
||||||
|
fft_if->execute(); // Run the FFT of local code
|
||||||
|
volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
|
||||||
|
|
||||||
|
// // debug
|
||||||
|
// char filename[25];
|
||||||
|
// FILE *fid;
|
||||||
|
// sprintf(filename,"fft_gal_prn%d.txt", PRN);
|
||||||
|
// fid = fopen(filename, "w");
|
||||||
|
// for (unsigned int kk=0;kk< nsamples_total; kk++)
|
||||||
|
// {
|
||||||
|
// fprintf(fid, "%f\n", fft_codes_padded[kk].real());
|
||||||
|
// fprintf(fid, "%f\n", fft_codes_padded[kk].imag());
|
||||||
|
// }
|
||||||
|
// fclose(fid);
|
||||||
|
|
||||||
|
|
||||||
|
// normalize the code
|
||||||
|
max = 0; // initialize maximum value
|
||||||
|
for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima
|
||||||
|
{
|
||||||
|
if (std::abs(fft_codes_padded[i].real()) > max)
|
||||||
|
{
|
||||||
|
max = std::abs(fft_codes_padded[i].real());
|
||||||
|
}
|
||||||
|
if (std::abs(fft_codes_padded[i].imag()) > max)
|
||||||
|
{
|
||||||
|
max = std::abs(fft_codes_padded[i].imag());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (unsigned int i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs
|
||||||
|
{
|
||||||
|
//d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(4096*fft_codes_padded[i].real() * (pow(2, 3) - 1) / max)),
|
||||||
|
// static_cast<int>(floor(4096*fft_codes_padded[i].imag() * (pow(2, 3) - 1) / max)));
|
||||||
|
// d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(1024*fft_codes_padded[i].real() * (pow(2, 5) - 1) / max)),
|
||||||
|
// static_cast<int>(floor(1024*fft_codes_padded[i].imag() * (pow(2, 5) - 1) / max)));
|
||||||
|
// d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(256*fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)),
|
||||||
|
// static_cast<int>(floor(256*fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max)));
|
||||||
|
// d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(16*fft_codes_padded[i].real() * (pow(2, 11) - 1) / max)),
|
||||||
|
// static_cast<int>(floor(16*fft_codes_padded[i].imag() * (pow(2, 11) - 1) / max)));
|
||||||
|
d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)),
|
||||||
|
static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max)));
|
||||||
|
|
||||||
|
// tmp_re = static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 7) - 1) / max));
|
||||||
|
// tmp_im = static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max));
|
||||||
|
|
||||||
|
// if (tmp_re > 127)
|
||||||
|
// {
|
||||||
|
// tmp_re = 127;
|
||||||
|
// }
|
||||||
|
// if (tmp_re < -128)
|
||||||
|
// {
|
||||||
|
// tmp_re = -128;
|
||||||
|
// }
|
||||||
|
// if (tmp_im > 127)
|
||||||
|
// {
|
||||||
|
// tmp_im = 127;
|
||||||
|
// }
|
||||||
|
// if (tmp_im < -128)
|
||||||
|
// {
|
||||||
|
// tmp_im = -128;
|
||||||
|
// }
|
||||||
|
// d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(tmp_re), static_cast<int>(tmp_im));
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
// // debug
|
||||||
|
// char filename2[25];
|
||||||
|
// FILE *fid2;
|
||||||
|
// sprintf(filename2,"fft_gal_prn%d_norm.txt", PRN);
|
||||||
|
// fid2 = fopen(filename2, "w");
|
||||||
|
// for (unsigned int kk=0;kk< nsamples_total; kk++)
|
||||||
|
// {
|
||||||
|
// fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].real());
|
||||||
|
// fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].imag());
|
||||||
|
// }
|
||||||
|
// fclose(fid2);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// for (unsigned int PRN = 1; PRN <= Galileo_E1_NUMBER_OF_CODES; PRN++)
|
||||||
|
// {
|
||||||
|
// // debug
|
||||||
|
// char filename2[25];
|
||||||
|
// FILE *fid2;
|
||||||
|
// sprintf(filename2,"fft_gal_prn%d_norm_last.txt", PRN);
|
||||||
|
// fid2 = fopen(filename2, "w");
|
||||||
|
// for (unsigned int kk=0;kk< nsamples_total; kk++)
|
||||||
|
// {
|
||||||
|
// fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].real());
|
||||||
|
// fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].imag());
|
||||||
|
// }
|
||||||
|
// fclose(fid2);
|
||||||
|
// }
|
||||||
|
|
||||||
|
//acq_parameters
|
||||||
|
|
||||||
|
acq_parameters.all_fft_codes = d_all_fft_codes_;
|
||||||
|
|
||||||
|
// temporary buffers that we can delete
|
||||||
|
delete[] code;
|
||||||
|
delete fft_if;
|
||||||
|
delete[] fft_codes_padded;
|
||||||
|
|
||||||
|
acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters);
|
||||||
|
DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";
|
||||||
|
|
||||||
|
// stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
|
||||||
|
// DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")";
|
||||||
|
|
||||||
|
// if (item_type_.compare("cbyte") == 0)
|
||||||
|
// {
|
||||||
|
// cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
|
||||||
|
// float_to_complex_ = gr::blocks::float_to_complex::make();
|
||||||
|
// }
|
||||||
|
|
||||||
|
channel_ = 0;
|
||||||
|
//threshold_ = 0.0;
|
||||||
|
doppler_step_ = 0;
|
||||||
|
gnss_synchro_ = 0;
|
||||||
|
//printf("top acq constructor end\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GalileoE1PcpsAmbiguousAcquisitionFpga::~GalileoE1PcpsAmbiguousAcquisitionFpga()
|
||||||
|
{
|
||||||
|
//printf("top acq destructor start\n");
|
||||||
|
//delete[] code_;
|
||||||
|
delete[] d_all_fft_codes_;
|
||||||
|
//printf("top acq destructor end\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_channel(unsigned int channel)
|
||||||
|
{
|
||||||
|
//printf("top acq set channel start\n");
|
||||||
|
channel_ = channel;
|
||||||
|
acquisition_fpga_->set_channel(channel_);
|
||||||
|
//printf("top acq set channel end\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_threshold(float threshold)
|
||||||
|
{
|
||||||
|
//printf("top acq set threshold start\n");
|
||||||
|
// the .pfa parameter and the threshold calculation is only used for the CFAR algorithm.
|
||||||
|
// We don't use the CFAR algorithm in the FPGA. Therefore the threshold is set as such.
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
acquisition_fpga_->set_threshold(threshold);
|
||||||
|
// acquisition_fpga_->set_threshold(threshold_);
|
||||||
|
//printf("top acq set threshold end\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_max(unsigned int doppler_max)
|
||||||
|
{
|
||||||
|
//printf("top acq set doppler max start\n");
|
||||||
|
doppler_max_ = doppler_max;
|
||||||
|
|
||||||
|
acquisition_fpga_->set_doppler_max(doppler_max_);
|
||||||
|
//printf("top acq set doppler max end\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_step(unsigned int doppler_step)
|
||||||
|
{
|
||||||
|
//printf("top acq set doppler step start\n");
|
||||||
|
doppler_step_ = doppler_step;
|
||||||
|
|
||||||
|
acquisition_fpga_->set_doppler_step(doppler_step_);
|
||||||
|
//printf("top acq set doppler step end\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
|
||||||
|
{
|
||||||
|
//printf("top acq set gnss synchro start\n");
|
||||||
|
gnss_synchro_ = gnss_synchro;
|
||||||
|
|
||||||
|
acquisition_fpga_->set_gnss_synchro(gnss_synchro_);
|
||||||
|
//printf("top acq set gnss synchro end\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
signed int GalileoE1PcpsAmbiguousAcquisitionFpga::mag()
|
||||||
|
{
|
||||||
|
// printf("top acq mag start\n");
|
||||||
|
return acquisition_fpga_->mag();
|
||||||
|
//printf("top acq mag end\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE1PcpsAmbiguousAcquisitionFpga::init()
|
||||||
|
{
|
||||||
|
// printf("top acq init start\n");
|
||||||
|
acquisition_fpga_->init();
|
||||||
|
// printf("top acq init end\n");
|
||||||
|
//set_local_code();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_local_code()
|
||||||
|
{
|
||||||
|
// printf("top acq set local code start\n");
|
||||||
|
// bool cboc = configuration_->property(
|
||||||
|
// "Acquisition" + boost::lexical_cast<std::string>(channel_) + ".cboc", false);
|
||||||
|
//
|
||||||
|
// std::complex<float>* code = new std::complex<float>[code_length_];
|
||||||
|
//
|
||||||
|
// if (acquire_pilot_ == true)
|
||||||
|
// {
|
||||||
|
// //set local signal generator to Galileo E1 pilot component (1C)
|
||||||
|
// char pilot_signal[3] = "1C";
|
||||||
|
// galileo_e1_code_gen_complex_sampled(code, pilot_signal,
|
||||||
|
// cboc, gnss_synchro_->PRN, fs_in_, 0, false);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// 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_ / 4; i++)
|
||||||
|
// {
|
||||||
|
// memcpy(&(code_[i * code_length_]), code, sizeof(gr_complex) * code_length_);
|
||||||
|
// }
|
||||||
|
|
||||||
|
//acquisition_fpga_->set_local_code(code_);
|
||||||
|
acquisition_fpga_->set_local_code();
|
||||||
|
// delete[] code;
|
||||||
|
// printf("top acq set local code end\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE1PcpsAmbiguousAcquisitionFpga::reset()
|
||||||
|
{
|
||||||
|
// printf("top acq reset start\n");
|
||||||
|
acquisition_fpga_->set_active(true);
|
||||||
|
// printf("top acq reset end\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_state(int state)
|
||||||
|
{
|
||||||
|
// printf("top acq set state start\n");
|
||||||
|
acquisition_fpga_->set_state(state);
|
||||||
|
// printf("top acq set state end\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//float GalileoE1PcpsAmbiguousAcquisitionFpga::calculate_threshold(float pfa)
|
||||||
|
//{
|
||||||
|
// unsigned int frequency_bins = 0;
|
||||||
|
// for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_)
|
||||||
|
// {
|
||||||
|
// frequency_bins++;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
|
||||||
|
//
|
||||||
|
// unsigned int ncells = vector_length_ * frequency_bins;
|
||||||
|
// double exponent = 1 / static_cast<double>(ncells);
|
||||||
|
// double val = pow(1.0 - pfa, exponent);
|
||||||
|
// double lambda = double(vector_length_);
|
||||||
|
// boost::math::exponential_distribution<double> mydist(lambda);
|
||||||
|
// float threshold = static_cast<float>(quantile(mydist, val));
|
||||||
|
//
|
||||||
|
// return threshold;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE1PcpsAmbiguousAcquisitionFpga::connect(gr::top_block_sptr top_block)
|
||||||
|
{
|
||||||
|
// printf("top acq connect\n");
|
||||||
|
// if (item_type_.compare("gr_complex") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0);
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cshort") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0);
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cbyte") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
|
// top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
|
// top_block->connect(float_to_complex_, 0, stream_to_vector_, 0);
|
||||||
|
// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||||
|
// }
|
||||||
|
|
||||||
|
// nothing to connect
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE1PcpsAmbiguousAcquisitionFpga::disconnect(gr::top_block_sptr top_block)
|
||||||
|
{
|
||||||
|
// if (item_type_.compare("gr_complex") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0);
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cshort") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0);
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cbyte") == 0)
|
||||||
|
// {
|
||||||
|
// // Since a byte-based acq implementation is not available,
|
||||||
|
// // we just convert cshorts to gr_complex
|
||||||
|
// top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
|
// top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
|
// top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0);
|
||||||
|
// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||||
|
// }
|
||||||
|
|
||||||
|
// nothing to disconnect
|
||||||
|
// printf("top acq disconnect\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisitionFpga::get_left_block()
|
||||||
|
{
|
||||||
|
// printf("top acq get left block start\n");
|
||||||
|
// if (item_type_.compare("gr_complex") == 0)
|
||||||
|
// {
|
||||||
|
// return stream_to_vector_;
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cshort") == 0)
|
||||||
|
// {
|
||||||
|
// return stream_to_vector_;
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cbyte") == 0)
|
||||||
|
// {
|
||||||
|
// return cbyte_to_float_x2_;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||||
|
return nullptr;
|
||||||
|
// }
|
||||||
|
// printf("top acq get left block end\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisitionFpga::get_right_block()
|
||||||
|
{
|
||||||
|
// printf("top acq get right block start\n");
|
||||||
|
return acquisition_fpga_;
|
||||||
|
// printf("top acq get right block end\n");
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,175 @@
|
|||||||
|
/*!
|
||||||
|
* \file galileo_e1_pcps_ambiguous_acquisition.h
|
||||||
|
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||||
|
* Galileo E1 Signals
|
||||||
|
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2015 (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_AMBIGUOUS_ACQUISITION_FPGA_H_
|
||||||
|
#define GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_
|
||||||
|
|
||||||
|
#include "acquisition_interface.h"
|
||||||
|
#include "gnss_synchro.h"
|
||||||
|
#include "pcps_acquisition_fpga.h"
|
||||||
|
#include "complex_byte_to_float_x2.h"
|
||||||
|
#include <gnuradio/blocks/stream_to_vector.h>
|
||||||
|
#include <gnuradio/blocks/float_to_complex.h>
|
||||||
|
#include <volk_gnsssdr/volk_gnsssdr.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigurationInterface;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief This class adapts a PCPS acquisition block to an
|
||||||
|
* AcquisitionInterface for Galileo E1 Signals
|
||||||
|
*/
|
||||||
|
class GalileoE1PcpsAmbiguousAcquisitionFpga : public AcquisitionInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GalileoE1PcpsAmbiguousAcquisitionFpga(ConfigurationInterface* configuration,
|
||||||
|
std::string role, unsigned int in_streams,
|
||||||
|
unsigned int out_streams);
|
||||||
|
|
||||||
|
virtual ~GalileoE1PcpsAmbiguousAcquisitionFpga();
|
||||||
|
|
||||||
|
inline std::string role() override
|
||||||
|
{
|
||||||
|
// printf("top acq role\n");
|
||||||
|
return role_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns "Galileo_E1_PCPS_Ambiguous_Acquisition"
|
||||||
|
*/
|
||||||
|
inline std::string implementation() override
|
||||||
|
{
|
||||||
|
// printf("top acq implementation\n");
|
||||||
|
return "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga";
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t item_size() override
|
||||||
|
{
|
||||||
|
// printf("top acq item size\n");
|
||||||
|
size_t item_size = sizeof(lv_16sc_t);
|
||||||
|
return item_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void connect(gr::top_block_sptr top_block) override;
|
||||||
|
void disconnect(gr::top_block_sptr top_block) override;
|
||||||
|
gr::basic_block_sptr get_left_block() override;
|
||||||
|
gr::basic_block_sptr get_right_block() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \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) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set acquisition channel unique ID
|
||||||
|
*/
|
||||||
|
void set_channel(unsigned int channel) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set statistics threshold of PCPS algorithm
|
||||||
|
*/
|
||||||
|
void set_threshold(float threshold) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set maximum Doppler off grid search
|
||||||
|
*/
|
||||||
|
void set_doppler_max(unsigned int doppler_max) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set Doppler steps for the grid search
|
||||||
|
*/
|
||||||
|
void set_doppler_step(unsigned int doppler_step) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes acquisition algorithm.
|
||||||
|
*/
|
||||||
|
void init() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets local code for Galileo E1 PCPS acquisition algorithm.
|
||||||
|
*/
|
||||||
|
void set_local_code() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the maximum peak of grid search
|
||||||
|
*/
|
||||||
|
signed int mag() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Restart acquisition algorithm
|
||||||
|
*/
|
||||||
|
void reset() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
||||||
|
*/
|
||||||
|
void set_state(int state) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConfigurationInterface* configuration_;
|
||||||
|
//pcps_acquisition_sptr acquisition_;
|
||||||
|
pcps_acquisition_fpga_sptr acquisition_fpga_;
|
||||||
|
gr::blocks::stream_to_vector::sptr stream_to_vector_;
|
||||||
|
gr::blocks::float_to_complex::sptr float_to_complex_;
|
||||||
|
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
|
||||||
|
// size_t item_size_;
|
||||||
|
// std::string item_type_;
|
||||||
|
//unsigned int vector_length_;
|
||||||
|
//unsigned int code_length_;
|
||||||
|
bool bit_transition_flag_;
|
||||||
|
bool use_CFAR_algorithm_flag_;
|
||||||
|
bool acquire_pilot_;
|
||||||
|
unsigned int channel_;
|
||||||
|
//float threshold_;
|
||||||
|
unsigned int doppler_max_;
|
||||||
|
unsigned int doppler_step_;
|
||||||
|
//unsigned int sampled_ms_;
|
||||||
|
unsigned int max_dwells_;
|
||||||
|
//long fs_in_;
|
||||||
|
//long if_;
|
||||||
|
bool dump_;
|
||||||
|
bool blocking_;
|
||||||
|
std::string dump_filename_;
|
||||||
|
//std::complex<float>* code_;
|
||||||
|
Gnss_Synchro* gnss_synchro_;
|
||||||
|
std::string role_;
|
||||||
|
unsigned int in_streams_;
|
||||||
|
unsigned int out_streams_;
|
||||||
|
//float calculate_threshold(float pfa);
|
||||||
|
|
||||||
|
// extra for the FPGA
|
||||||
|
lv_16sc_t* d_all_fft_codes_; // memory that contains all the code ffts
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_ */
|
@ -101,16 +101,16 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
|
|||||||
LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||||
}
|
}
|
||||||
acq_parameters.it_size = item_size_;
|
acq_parameters.it_size = item_size_;
|
||||||
acq_parameters.samples_per_code = code_length_;
|
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||||
acq_parameters.samples_per_ms = code_length_;
|
|
||||||
acq_parameters.sampled_ms = sampled_ms_;
|
acq_parameters.sampled_ms = sampled_ms_;
|
||||||
|
acq_parameters.ms_per_code = 1;
|
||||||
|
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GALILEO_E5a_CODE_PERIOD_MS);
|
||||||
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
||||||
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||||
acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
|
acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
|
||||||
acquisition_ = pcps_make_acquisition(acq_parameters);
|
acquisition_ = pcps_make_acquisition(acq_parameters);
|
||||||
|
|
||||||
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
|
|
||||||
channel_ = 0;
|
channel_ = 0;
|
||||||
threshold_ = 0.0;
|
threshold_ = 0.0;
|
||||||
doppler_step_ = 0;
|
doppler_step_ = 0;
|
||||||
@ -258,15 +258,15 @@ void GalileoE5aPcpsAcquisition::set_state(int state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GalileoE5aPcpsAcquisition::connect(gr::top_block_sptr top_block)
|
void GalileoE5aPcpsAcquisition::connect(gr::top_block_sptr top_block __attribute__((unused)))
|
||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to connect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to connect
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -275,15 +275,15 @@ void GalileoE5aPcpsAcquisition::connect(gr::top_block_sptr top_block)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GalileoE5aPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
|
void GalileoE5aPcpsAcquisition::disconnect(gr::top_block_sptr top_block __attribute__((unused)))
|
||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to disconnect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to disconnect
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -294,7 +294,7 @@ void GalileoE5aPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
|
|||||||
|
|
||||||
gr::basic_block_sptr GalileoE5aPcpsAcquisition::get_left_block()
|
gr::basic_block_sptr GalileoE5aPcpsAcquisition::get_left_block()
|
||||||
{
|
{
|
||||||
return stream_to_vector_;
|
return acquisition_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
#include "acquisition_interface.h"
|
#include "acquisition_interface.h"
|
||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "pcps_acquisition.h"
|
#include "pcps_acquisition.h"
|
||||||
#include <gnuradio/blocks/stream_to_vector.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class ConfigurationInterface;
|
class ConfigurationInterface;
|
||||||
@ -129,7 +128,6 @@ private:
|
|||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
|
|
||||||
pcps_acquisition_sptr acquisition_;
|
pcps_acquisition_sptr acquisition_;
|
||||||
gr::blocks::stream_to_vector::sptr stream_to_vector_;
|
|
||||||
|
|
||||||
size_t item_size_;
|
size_t item_size_;
|
||||||
|
|
||||||
|
@ -0,0 +1,405 @@
|
|||||||
|
/*!
|
||||||
|
* \file galileo_e5a_pcps_acquisition.cc
|
||||||
|
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||||
|
* Galileo E5a data and pilot Signals
|
||||||
|
* \author Antonio Ramos, 2018. antonio.ramos(at)cttc.es
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
|
||||||
|
*
|
||||||
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
|
* Satellite Systems receiver
|
||||||
|
*
|
||||||
|
* This file is part of GNSS-SDR.
|
||||||
|
*
|
||||||
|
* GNSS-SDR is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GNSS-SDR is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "galileo_e5a_pcps_acquisition_fpga.h"
|
||||||
|
#include "configuration_interface.h"
|
||||||
|
#include "galileo_e5_signal_processing.h"
|
||||||
|
#include "Galileo_E5a.h"
|
||||||
|
#include "gnss_sdr_flags.h"
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include <boost/math/distributions/exponential.hpp>
|
||||||
|
#include <glog/logging.h>
|
||||||
|
#include <volk_gnsssdr/volk_gnsssdr_complex.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
using google::LogMessage;
|
||||||
|
|
||||||
|
GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterface* configuration,
|
||||||
|
std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
|
||||||
|
{
|
||||||
|
//printf("creating the E5A acquisition");
|
||||||
|
pcpsconf_fpga_t acq_parameters;
|
||||||
|
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);
|
||||||
|
|
||||||
|
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000);
|
||||||
|
long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||||
|
acq_parameters.fs_in = fs_in;
|
||||||
|
//acq_parameters.freq = 0;
|
||||||
|
|
||||||
|
|
||||||
|
//dump_ = configuration_->property(role + ".dump", false);
|
||||||
|
//acq_parameters.dump = dump_;
|
||||||
|
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
|
||||||
|
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
|
||||||
|
acq_parameters.doppler_max = doppler_max_;
|
||||||
|
unsigned int sampled_ms = 1;
|
||||||
|
//max_dwells_ = configuration_->property(role + ".max_dwells", 1);
|
||||||
|
//acq_parameters.max_dwells = max_dwells_;
|
||||||
|
//dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
||||||
|
//acq_parameters.dump_filename = dump_filename_;
|
||||||
|
//bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
||||||
|
//acq_parameters.bit_transition_flag = bit_transition_flag_;
|
||||||
|
//use_CFAR_ = configuration_->property(role + ".use_CFAR_algorithm", false);
|
||||||
|
//acq_parameters.use_CFAR_algorithm_flag = use_CFAR_;
|
||||||
|
//blocking_ = configuration_->property(role + ".blocking", true);
|
||||||
|
//acq_parameters.blocking = blocking_;
|
||||||
|
//--- Find number of samples per spreading code (1ms)-------------------------
|
||||||
|
|
||||||
|
acq_pilot_ = configuration_->property(role + ".acquire_pilot", false);
|
||||||
|
acq_iq_ = configuration_->property(role + ".acquire_iq", false);
|
||||||
|
if (acq_iq_)
|
||||||
|
{
|
||||||
|
acq_pilot_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / Galileo_E5a_CODE_CHIP_RATE_HZ * static_cast<double>(Galileo_E5a_CODE_LENGTH_CHIPS)));
|
||||||
|
acq_parameters.code_length = code_length;
|
||||||
|
// The FPGA can only use FFT lengths that are a power of two.
|
||||||
|
float nbits = ceilf(log2f((float)code_length));
|
||||||
|
unsigned int nsamples_total = pow(2, nbits);
|
||||||
|
unsigned int vector_length = nsamples_total;
|
||||||
|
unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 1);
|
||||||
|
//printf("select_queue_Fpga = %d\n", select_queue_Fpga);
|
||||||
|
acq_parameters.select_queue_Fpga = select_queue_Fpga;
|
||||||
|
std::string default_device_name = "/dev/uio0";
|
||||||
|
std::string device_name = configuration_->property(role + ".devicename", default_device_name);
|
||||||
|
acq_parameters.device_name = device_name;
|
||||||
|
acq_parameters.samples_per_ms = nsamples_total/sampled_ms;
|
||||||
|
acq_parameters.samples_per_code = nsamples_total;
|
||||||
|
|
||||||
|
//vector_length_ = code_length_ * sampled_ms_;
|
||||||
|
|
||||||
|
// compute all the GALILEO E5 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time
|
||||||
|
// a channel is assigned)
|
||||||
|
gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT
|
||||||
|
std::complex<float>* code = new std::complex<float>[nsamples_total]; // buffer for the local code
|
||||||
|
gr_complex* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||||
|
d_all_fft_codes_ = new lv_16sc_t[nsamples_total * Galileo_E5a_NUMBER_OF_CODES]; // memory containing all the possible fft codes for PRN 0 to 32
|
||||||
|
float max; // temporary maxima search
|
||||||
|
|
||||||
|
//printf("creating the E5A acquisition CONT");
|
||||||
|
//printf("nsamples_total = %d\n", nsamples_total);
|
||||||
|
|
||||||
|
for (unsigned int PRN = 1; PRN <= Galileo_E5a_NUMBER_OF_CODES; PRN++)
|
||||||
|
{
|
||||||
|
// gr_complex* code = new gr_complex[code_length_];
|
||||||
|
char signal_[3];
|
||||||
|
|
||||||
|
if (acq_iq_)
|
||||||
|
{
|
||||||
|
strcpy(signal_, "5X");
|
||||||
|
}
|
||||||
|
else if (acq_pilot_)
|
||||||
|
{
|
||||||
|
strcpy(signal_, "5Q");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(signal_, "5I");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
galileo_e5_a_code_gen_complex_sampled(code, signal_, PRN, fs_in, 0);
|
||||||
|
|
||||||
|
// fill in zero padding
|
||||||
|
for (int s = code_length; s < nsamples_total; s++)
|
||||||
|
{
|
||||||
|
code[s] = std::complex<float>(static_cast<float>(0,0));
|
||||||
|
//code[s] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer
|
||||||
|
fft_if->execute(); // Run the FFT of local code
|
||||||
|
volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
|
||||||
|
|
||||||
|
max = 0; // initialize maximum value
|
||||||
|
for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima
|
||||||
|
{
|
||||||
|
if (std::abs(fft_codes_padded[i].real()) > max)
|
||||||
|
{
|
||||||
|
max = std::abs(fft_codes_padded[i].real());
|
||||||
|
}
|
||||||
|
if (std::abs(fft_codes_padded[i].imag()) > max)
|
||||||
|
{
|
||||||
|
max = std::abs(fft_codes_padded[i].imag());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (unsigned int i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs
|
||||||
|
{
|
||||||
|
d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)),
|
||||||
|
static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
acq_parameters.all_fft_codes = d_all_fft_codes_;
|
||||||
|
|
||||||
|
// temporary buffers that we can delete
|
||||||
|
delete[] code;
|
||||||
|
delete fft_if;
|
||||||
|
delete[] fft_codes_padded;
|
||||||
|
|
||||||
|
//code_ = new gr_complex[vector_length_];
|
||||||
|
|
||||||
|
// if (item_type_.compare("gr_complex") == 0)
|
||||||
|
// {
|
||||||
|
// item_size_ = sizeof(gr_complex);
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cshort") == 0)
|
||||||
|
// {
|
||||||
|
// item_size_ = sizeof(lv_16sc_t);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// item_size_ = sizeof(gr_complex);
|
||||||
|
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||||
|
// }
|
||||||
|
//acq_parameters.it_size = item_size_;
|
||||||
|
//acq_parameters.samples_per_code = code_length_;
|
||||||
|
//acq_parameters.samples_per_ms = code_length_;
|
||||||
|
//acq_parameters.sampled_ms = sampled_ms_;
|
||||||
|
//acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
||||||
|
//acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||||
|
//acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||||
|
//acquisition_ = pcps_make_acquisition(acq_parameters);
|
||||||
|
//acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters);
|
||||||
|
//DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";
|
||||||
|
|
||||||
|
acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters);
|
||||||
|
DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";
|
||||||
|
|
||||||
|
//stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
|
||||||
|
channel_ = 0;
|
||||||
|
//threshold_ = 0.0;
|
||||||
|
doppler_step_ = 0;
|
||||||
|
gnss_synchro_ = 0;
|
||||||
|
//printf("creating the E5A acquisition end");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GalileoE5aPcpsAcquisitionFpga::~GalileoE5aPcpsAcquisitionFpga()
|
||||||
|
{
|
||||||
|
//delete[] code_;
|
||||||
|
delete[] d_all_fft_codes_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE5aPcpsAcquisitionFpga::set_channel(unsigned int channel)
|
||||||
|
{
|
||||||
|
channel_ = channel;
|
||||||
|
//acquisition_->set_channel(channel_);
|
||||||
|
acquisition_fpga_->set_channel(channel_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE5aPcpsAcquisitionFpga::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;
|
||||||
|
|
||||||
|
//acquisition_->set_threshold(threshold_);
|
||||||
|
acquisition_fpga_->set_threshold(threshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE5aPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max)
|
||||||
|
{
|
||||||
|
doppler_max_ = doppler_max;
|
||||||
|
//acquisition_->set_doppler_max(doppler_max_);
|
||||||
|
acquisition_fpga_->set_doppler_max(doppler_max_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE5aPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step)
|
||||||
|
{
|
||||||
|
doppler_step_ = doppler_step;
|
||||||
|
//acquisition_->set_doppler_step(doppler_step_);
|
||||||
|
acquisition_fpga_->set_doppler_step(doppler_step_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE5aPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
|
||||||
|
{
|
||||||
|
gnss_synchro_ = gnss_synchro;
|
||||||
|
//acquisition_->set_gnss_synchro(gnss_synchro_);
|
||||||
|
acquisition_fpga_->set_gnss_synchro(gnss_synchro_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
signed int GalileoE5aPcpsAcquisitionFpga::mag()
|
||||||
|
{
|
||||||
|
//return acquisition_->mag();
|
||||||
|
return acquisition_fpga_->mag();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE5aPcpsAcquisitionFpga::init()
|
||||||
|
{
|
||||||
|
//acquisition_->init();
|
||||||
|
acquisition_fpga_->init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE5aPcpsAcquisitionFpga::set_local_code()
|
||||||
|
{
|
||||||
|
// gr_complex* code = new gr_complex[code_length_];
|
||||||
|
// char signal_[3];
|
||||||
|
//
|
||||||
|
// if (acq_iq_)
|
||||||
|
// {
|
||||||
|
// strcpy(signal_, "5X");
|
||||||
|
// }
|
||||||
|
// else if (acq_pilot_)
|
||||||
|
// {
|
||||||
|
// strcpy(signal_, "5Q");
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// strcpy(signal_, "5I");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// galileo_e5_a_code_gen_complex_sampled(code, signal_, gnss_synchro_->PRN, fs_in_, 0);
|
||||||
|
//
|
||||||
|
// for (unsigned int i = 0; i < sampled_ms_; i++)
|
||||||
|
// {
|
||||||
|
// memcpy(code_ + (i * code_length_), code, sizeof(gr_complex) * code_length_);
|
||||||
|
// }
|
||||||
|
|
||||||
|
//acquisition_->set_local_code(code_);
|
||||||
|
acquisition_fpga_->set_local_code();
|
||||||
|
// delete[] code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE5aPcpsAcquisitionFpga::reset()
|
||||||
|
{
|
||||||
|
//acquisition_->set_active(true);
|
||||||
|
acquisition_fpga_->set_active(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//float GalileoE5aPcpsAcquisitionFpga::calculate_threshold(float pfa)
|
||||||
|
//{
|
||||||
|
// unsigned int frequency_bins = 0;
|
||||||
|
// for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_)
|
||||||
|
// {
|
||||||
|
// frequency_bins++;
|
||||||
|
// }
|
||||||
|
// DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
|
||||||
|
// unsigned int ncells = vector_length_ * frequency_bins;
|
||||||
|
// double exponent = 1 / static_cast<double>(ncells);
|
||||||
|
// double val = pow(1.0 - pfa, exponent);
|
||||||
|
// double lambda = double(vector_length_);
|
||||||
|
// boost::math::exponential_distribution<double> mydist(lambda);
|
||||||
|
// float threshold = static_cast<float>(quantile(mydist, val));
|
||||||
|
//
|
||||||
|
// return threshold;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE5aPcpsAcquisitionFpga::set_state(int state)
|
||||||
|
{
|
||||||
|
//acquisition_->set_state(state);
|
||||||
|
acquisition_fpga_->set_state(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE5aPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block)
|
||||||
|
{
|
||||||
|
// if (item_type_.compare("gr_complex") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cshort") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GalileoE5aPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block)
|
||||||
|
{
|
||||||
|
// if (item_type_.compare("gr_complex") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cshort") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gr::basic_block_sptr GalileoE5aPcpsAcquisitionFpga::get_left_block()
|
||||||
|
{
|
||||||
|
//return stream_to_vector_;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gr::basic_block_sptr GalileoE5aPcpsAcquisitionFpga::get_right_block()
|
||||||
|
{
|
||||||
|
//return acquisition_;
|
||||||
|
return acquisition_fpga_;
|
||||||
|
}
|
@ -0,0 +1,175 @@
|
|||||||
|
/*!
|
||||||
|
* \file galileo_e5a_pcps_acquisition.h
|
||||||
|
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||||
|
* Galileo E5a data and pilot Signals
|
||||||
|
* \author Antonio Ramos, 2018. antonio.ramos(at)cttc.es
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
|
||||||
|
*
|
||||||
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
|
* Satellite Systems receiver
|
||||||
|
*
|
||||||
|
* This file is part of GNSS-SDR.
|
||||||
|
*
|
||||||
|
* GNSS-SDR is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GNSS-SDR is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_
|
||||||
|
#define GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include "acquisition_interface.h"
|
||||||
|
#include "gnss_synchro.h"
|
||||||
|
#include "pcps_acquisition_fpga.h"
|
||||||
|
#include <gnuradio/blocks/stream_to_vector.h>
|
||||||
|
#include <volk_gnsssdr/volk_gnsssdr.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class ConfigurationInterface;
|
||||||
|
|
||||||
|
class GalileoE5aPcpsAcquisitionFpga : public AcquisitionInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GalileoE5aPcpsAcquisitionFpga(ConfigurationInterface* configuration,
|
||||||
|
std::string role, unsigned int in_streams,
|
||||||
|
unsigned int out_streams);
|
||||||
|
|
||||||
|
virtual ~GalileoE5aPcpsAcquisitionFpga();
|
||||||
|
|
||||||
|
inline std::string role() override
|
||||||
|
{
|
||||||
|
return role_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string implementation() override
|
||||||
|
{
|
||||||
|
return "Galileo_E5a_Pcps_Acquisition_Fpga";
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t item_size() override
|
||||||
|
{
|
||||||
|
return item_size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void connect(gr::top_block_sptr top_block) override;
|
||||||
|
void disconnect(gr::top_block_sptr top_block) override;
|
||||||
|
gr::basic_block_sptr get_left_block() override;
|
||||||
|
gr::basic_block_sptr get_right_block() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \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) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set acquisition channel unique ID
|
||||||
|
*/
|
||||||
|
void set_channel(unsigned int channel) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set statistics threshold of PCPS algorithm
|
||||||
|
*/
|
||||||
|
void set_threshold(float threshold) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set maximum Doppler off grid search
|
||||||
|
*/
|
||||||
|
void set_doppler_max(unsigned int doppler_max) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set Doppler steps for the grid search
|
||||||
|
*/
|
||||||
|
void set_doppler_step(unsigned int doppler_step) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes acquisition algorithm.
|
||||||
|
*/
|
||||||
|
void init() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets local Galileo E5a code for PCPS acquisition algorithm.
|
||||||
|
*/
|
||||||
|
void set_local_code() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the maximum peak of grid search
|
||||||
|
*/
|
||||||
|
signed int mag() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Restart acquisition algorithm
|
||||||
|
*/
|
||||||
|
void reset() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief If set to 1, ensures that acquisition starts at the
|
||||||
|
* first available sample.
|
||||||
|
* \param state - int=1 forces start of acquisition
|
||||||
|
*/
|
||||||
|
void set_state(int state) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//float calculate_threshold(float pfa);
|
||||||
|
|
||||||
|
ConfigurationInterface* configuration_;
|
||||||
|
|
||||||
|
pcps_acquisition_fpga_sptr acquisition_fpga_;
|
||||||
|
gr::blocks::stream_to_vector::sptr stream_to_vector_;
|
||||||
|
|
||||||
|
size_t item_size_;
|
||||||
|
|
||||||
|
std::string item_type_;
|
||||||
|
std::string dump_filename_;
|
||||||
|
std::string role_;
|
||||||
|
|
||||||
|
bool bit_transition_flag_;
|
||||||
|
bool dump_;
|
||||||
|
bool acq_pilot_;
|
||||||
|
bool use_CFAR_;
|
||||||
|
bool blocking_;
|
||||||
|
bool acq_iq_;
|
||||||
|
|
||||||
|
unsigned int vector_length_;
|
||||||
|
unsigned int code_length_;
|
||||||
|
unsigned int channel_;
|
||||||
|
unsigned int doppler_max_;
|
||||||
|
unsigned int doppler_step_;
|
||||||
|
unsigned int sampled_ms_;
|
||||||
|
unsigned int max_dwells_;
|
||||||
|
unsigned int in_streams_;
|
||||||
|
unsigned int out_streams_;
|
||||||
|
|
||||||
|
long fs_in_;
|
||||||
|
|
||||||
|
|
||||||
|
float threshold_;
|
||||||
|
|
||||||
|
/*
|
||||||
|
std::complex<float>* codeI_;
|
||||||
|
std::complex<float>* codeQ_;
|
||||||
|
*/
|
||||||
|
|
||||||
|
gr_complex* code_;
|
||||||
|
|
||||||
|
Gnss_Synchro* gnss_synchro_;
|
||||||
|
|
||||||
|
// extra for the FPGA
|
||||||
|
lv_16sc_t* d_all_fft_codes_; // memory that contains all the code ffts
|
||||||
|
};
|
||||||
|
#endif /* GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_ */
|
@ -100,8 +100,9 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
|
|||||||
}
|
}
|
||||||
acq_parameters.it_size = item_size_;
|
acq_parameters.it_size = item_size_;
|
||||||
acq_parameters.sampled_ms = sampled_ms_;
|
acq_parameters.sampled_ms = sampled_ms_;
|
||||||
acq_parameters.samples_per_ms = code_length_;
|
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||||
acq_parameters.samples_per_code = code_length_;
|
acq_parameters.ms_per_code = 1;
|
||||||
|
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GLONASS_L1_CA_CODE_PERIOD * 1000.0);
|
||||||
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
||||||
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||||
@ -109,9 +110,6 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
|
|||||||
acquisition_ = pcps_make_acquisition(acq_parameters);
|
acquisition_ = pcps_make_acquisition(acq_parameters);
|
||||||
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
|
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
|
||||||
|
|
||||||
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
|
|
||||||
DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")";
|
|
||||||
|
|
||||||
if (item_type_.compare("cbyte") == 0)
|
if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
|
cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
|
||||||
@ -261,18 +259,17 @@ void GlonassL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block)
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to connect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to connect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
top_block->connect(float_to_complex_, 0, stream_to_vector_, 0);
|
top_block->connect(float_to_complex_, 0, acquisition_, 0);
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -285,11 +282,11 @@ void GlonassL1CaPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to disconnect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to disconnect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
@ -297,8 +294,7 @@ void GlonassL1CaPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
|
|||||||
// we just convert cshorts to gr_complex
|
// we just convert cshorts to gr_complex
|
||||||
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0);
|
top_block->disconnect(float_to_complex_, 0, acquisition_, 0);
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -311,11 +307,11 @@ gr::basic_block_sptr GlonassL1CaPcpsAcquisition::get_left_block()
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
return stream_to_vector_;
|
return acquisition_;
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
return stream_to_vector_;
|
return acquisition_;
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "pcps_acquisition.h"
|
#include "pcps_acquisition.h"
|
||||||
#include "complex_byte_to_float_x2.h"
|
#include "complex_byte_to_float_x2.h"
|
||||||
#include <gnuradio/blocks/stream_to_vector.h>
|
|
||||||
#include <gnuradio/blocks/float_to_complex.h>
|
#include <gnuradio/blocks/float_to_complex.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -135,7 +134,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
pcps_acquisition_sptr acquisition_;
|
pcps_acquisition_sptr acquisition_;
|
||||||
gr::blocks::stream_to_vector::sptr stream_to_vector_;
|
|
||||||
gr::blocks::float_to_complex::sptr float_to_complex_;
|
gr::blocks::float_to_complex::sptr float_to_complex_;
|
||||||
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
|
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
|
||||||
size_t item_size_;
|
size_t item_size_;
|
||||||
|
@ -99,8 +99,9 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition(
|
|||||||
}
|
}
|
||||||
acq_parameters.it_size = item_size_;
|
acq_parameters.it_size = item_size_;
|
||||||
acq_parameters.sampled_ms = sampled_ms_;
|
acq_parameters.sampled_ms = sampled_ms_;
|
||||||
acq_parameters.samples_per_ms = code_length_;
|
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||||
acq_parameters.samples_per_code = code_length_;
|
acq_parameters.ms_per_code = 1;
|
||||||
|
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GLONASS_L2_CA_CODE_PERIOD * 1000.0);
|
||||||
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
||||||
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||||
@ -108,9 +109,6 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition(
|
|||||||
acquisition_ = pcps_make_acquisition(acq_parameters);
|
acquisition_ = pcps_make_acquisition(acq_parameters);
|
||||||
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
|
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
|
||||||
|
|
||||||
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
|
|
||||||
DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")";
|
|
||||||
|
|
||||||
if (item_type_.compare("cbyte") == 0)
|
if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
|
cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
|
||||||
@ -260,18 +258,19 @@ void GlonassL2CaPcpsAcquisition::connect(gr::top_block_sptr top_block)
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to connect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to connect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
|
// Since a byte-based acq implementation is not available,
|
||||||
|
// we just convert cshorts to gr_complex
|
||||||
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
top_block->connect(float_to_complex_, 0, stream_to_vector_, 0);
|
top_block->connect(float_to_complex_, 0, acquisition_, 0);
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -284,20 +283,17 @@ void GlonassL2CaPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to disconnect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to disconnect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
// Since a byte-based acq implementation is not available,
|
|
||||||
// we just convert cshorts to gr_complex
|
|
||||||
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0);
|
top_block->disconnect(float_to_complex_, 0, acquisition_, 0);
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -310,11 +306,11 @@ gr::basic_block_sptr GlonassL2CaPcpsAcquisition::get_left_block()
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
return stream_to_vector_;
|
return acquisition_;
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
return stream_to_vector_;
|
return acquisition_;
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
|
@ -37,7 +37,6 @@
|
|||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "pcps_acquisition.h"
|
#include "pcps_acquisition.h"
|
||||||
#include "complex_byte_to_float_x2.h"
|
#include "complex_byte_to_float_x2.h"
|
||||||
#include <gnuradio/blocks/stream_to_vector.h>
|
|
||||||
#include <gnuradio/blocks/float_to_complex.h>
|
#include <gnuradio/blocks/float_to_complex.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -134,7 +133,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
pcps_acquisition_sptr acquisition_;
|
pcps_acquisition_sptr acquisition_;
|
||||||
gr::blocks::stream_to_vector::sptr stream_to_vector_;
|
|
||||||
gr::blocks::float_to_complex::sptr float_to_complex_;
|
gr::blocks::float_to_complex::sptr float_to_complex_;
|
||||||
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
|
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
|
||||||
size_t item_size_;
|
size_t item_size_;
|
||||||
|
@ -71,6 +71,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
|
|||||||
acq_parameters.doppler_max = doppler_max_;
|
acq_parameters.doppler_max = doppler_max_;
|
||||||
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
|
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
|
||||||
acq_parameters.sampled_ms = sampled_ms_;
|
acq_parameters.sampled_ms = sampled_ms_;
|
||||||
|
acq_parameters.ms_per_code = 1;
|
||||||
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
||||||
acq_parameters.bit_transition_flag = bit_transition_flag_;
|
acq_parameters.bit_transition_flag = bit_transition_flag_;
|
||||||
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
|
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
|
||||||
@ -83,15 +84,11 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
|
|||||||
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||||
//--- Find number of samples per spreading code -------------------------
|
//--- Find number of samples per spreading code -------------------------
|
||||||
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)));
|
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)));
|
||||||
|
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||||
vector_length_ = code_length_ * sampled_ms_;
|
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L1_CA_CODE_PERIOD * 1000.0);
|
||||||
|
|
||||||
if (bit_transition_flag_)
|
|
||||||
{
|
|
||||||
vector_length_ *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
vector_length_ = std::floor(acq_parameters.sampled_ms * acq_parameters.samples_per_ms) * (acq_parameters.bit_transition_flag ? 2 : 1);
|
||||||
code_ = new gr_complex[vector_length_];
|
code_ = new gr_complex[vector_length_];
|
||||||
|
|
||||||
if (item_type_.compare("cshort") == 0)
|
if (item_type_.compare("cshort") == 0)
|
||||||
@ -102,16 +99,12 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
|
|||||||
{
|
{
|
||||||
item_size_ = sizeof(gr_complex);
|
item_size_ = sizeof(gr_complex);
|
||||||
}
|
}
|
||||||
acq_parameters.samples_per_ms = code_length_;
|
|
||||||
acq_parameters.samples_per_code = code_length_;
|
|
||||||
acq_parameters.it_size = item_size_;
|
acq_parameters.it_size = item_size_;
|
||||||
acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
|
acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
|
||||||
acquisition_ = pcps_make_acquisition(acq_parameters);
|
acquisition_ = pcps_make_acquisition(acq_parameters);
|
||||||
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
|
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
|
||||||
|
|
||||||
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
|
|
||||||
DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")";
|
|
||||||
|
|
||||||
if (item_type_.compare("cbyte") == 0)
|
if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
|
cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
|
||||||
@ -198,7 +191,6 @@ signed int GpsL1CaPcpsAcquisition::mag()
|
|||||||
void GpsL1CaPcpsAcquisition::init()
|
void GpsL1CaPcpsAcquisition::init()
|
||||||
{
|
{
|
||||||
acquisition_->init();
|
acquisition_->init();
|
||||||
//set_local_code();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -255,18 +247,19 @@ void GpsL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block)
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to connect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to connect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
|
// Since a byte-based acq implementation is not available,
|
||||||
|
// we just convert cshorts to gr_complex
|
||||||
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
top_block->connect(float_to_complex_, 0, stream_to_vector_, 0);
|
top_block->connect(float_to_complex_, 0, acquisition_, 0);
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -279,20 +272,17 @@ void GpsL1CaPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to disconnect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to disconnect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
// Since a byte-based acq implementation is not available,
|
|
||||||
// we just convert cshorts to gr_complex
|
|
||||||
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0);
|
top_block->disconnect(float_to_complex_, 0, acquisition_, 0);
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -305,11 +295,11 @@ gr::basic_block_sptr GpsL1CaPcpsAcquisition::get_left_block()
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
return stream_to_vector_;
|
return acquisition_;
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
return stream_to_vector_;
|
return acquisition_;
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
|
@ -40,7 +40,6 @@
|
|||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "pcps_acquisition.h"
|
#include "pcps_acquisition.h"
|
||||||
#include "complex_byte_to_float_x2.h"
|
#include "complex_byte_to_float_x2.h"
|
||||||
#include <gnuradio/blocks/stream_to_vector.h>
|
|
||||||
#include <gnuradio/blocks/float_to_complex.h>
|
#include <gnuradio/blocks/float_to_complex.h>
|
||||||
#include <volk_gnsssdr/volk_gnsssdr.h>
|
#include <volk_gnsssdr/volk_gnsssdr.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -139,7 +138,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
pcps_acquisition_sptr acquisition_;
|
pcps_acquisition_sptr acquisition_;
|
||||||
gr::blocks::stream_to_vector::sptr stream_to_vector_;
|
|
||||||
gr::blocks::float_to_complex::sptr float_to_complex_;
|
gr::blocks::float_to_complex::sptr float_to_complex_;
|
||||||
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
|
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
|
||||||
size_t item_size_;
|
size_t item_size_;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
|
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
|
||||||
*
|
*
|
||||||
* GNSS-SDR is a software defined Global Navigation
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
* Satellite Systems receiver
|
* Satellite Systems receiver
|
||||||
@ -29,20 +29,21 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
|
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gps_l1_ca_pcps_acquisition_fpga.h"
|
|
||||||
#include "configuration_interface.h"
|
#include "configuration_interface.h"
|
||||||
#include "gnss_sdr_flags.h"
|
#include "gnss_sdr_flags.h"
|
||||||
#include "GPS_L1_CA.h"
|
#include "gps_l1_ca_pcps_acquisition_fpga.h"
|
||||||
#include "gps_sdr_signal_processing.h"
|
#include "gps_sdr_signal_processing.h"
|
||||||
|
#include "GPS_L1_CA.h"
|
||||||
#include <gnuradio/fft/fft.h>
|
#include <gnuradio/fft/fft.h>
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
|
|
||||||
#define NUM_PRNs 32
|
#define NUM_PRNs 32
|
||||||
|
|
||||||
using google::LogMessage;
|
using google::LogMessage;
|
||||||
@ -59,49 +60,64 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
|
|||||||
|
|
||||||
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
||||||
long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||||
|
//fs_in = fs_in/2.0; // downampling filter
|
||||||
|
//printf("####### DEBUG Acq: fs_in = %d\n", fs_in);
|
||||||
acq_parameters.fs_in = fs_in;
|
acq_parameters.fs_in = fs_in;
|
||||||
acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast<float>(acq_parameters.fs_in)));
|
acq_parameters.samples_per_code = static_cast<unsigned int>(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast<float>(acq_parameters.fs_in)));
|
||||||
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
|
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
|
||||||
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
|
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
|
||||||
acq_parameters.doppler_max = doppler_max_;
|
acq_parameters.doppler_max = doppler_max_;
|
||||||
unsigned int sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
|
unsigned int sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
|
||||||
acq_parameters.sampled_ms = sampled_ms;
|
acq_parameters.sampled_ms = sampled_ms;
|
||||||
unsigned int code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)));
|
unsigned int code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)));
|
||||||
|
acq_parameters.code_length = code_length;
|
||||||
// The FPGA can only use FFT lengths that are a power of two.
|
// The FPGA can only use FFT lengths that are a power of two.
|
||||||
float nbits = ceilf(log2f((float)code_length));
|
float nbits = ceilf(log2f((float)code_length));
|
||||||
unsigned int nsamples_total = pow(2, nbits);
|
unsigned int nsamples_total = pow(2, nbits);
|
||||||
unsigned int vector_length = nsamples_total * sampled_ms;
|
unsigned int vector_length = nsamples_total;
|
||||||
unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0);
|
unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0);
|
||||||
acq_parameters.select_queue_Fpga = select_queue_Fpga;
|
acq_parameters.select_queue_Fpga = select_queue_Fpga;
|
||||||
std::string default_device_name = "/dev/uio0";
|
std::string default_device_name = "/dev/uio0";
|
||||||
std::string device_name = configuration_->property(role + ".devicename", default_device_name);
|
std::string device_name = configuration_->property(role + ".devicename", default_device_name);
|
||||||
acq_parameters.device_name = device_name;
|
acq_parameters.device_name = device_name;
|
||||||
acq_parameters.samples_per_ms = nsamples_total;
|
acq_parameters.samples_per_ms = nsamples_total / sampled_ms;
|
||||||
acq_parameters.samples_per_code = nsamples_total;
|
acq_parameters.samples_per_code = nsamples_total;
|
||||||
|
|
||||||
// compute all the GPS L1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time
|
// compute all the GPS L1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time
|
||||||
// a channel is assigned)
|
// a channel is assigned)
|
||||||
|
|
||||||
gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(vector_length, true); // Direct FFT
|
gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(vector_length, true); // Direct FFT
|
||||||
// allocate memory to compute all the PRNs and compute all the possible codes
|
// allocate memory to compute all the PRNs and compute all the possible codes
|
||||||
std::complex<float>* code = new std::complex<float>[nsamples_total]; // buffer for the local code
|
std::complex<float>* code = new std::complex<float>[nsamples_total]; // buffer for the local code
|
||||||
gr_complex* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
gr_complex* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||||
d_all_fft_codes_ = new lv_16sc_t[nsamples_total * NUM_PRNs]; // memory containing all the possible fft codes for PRN 0 to 32
|
d_all_fft_codes_ = new lv_16sc_t[nsamples_total * NUM_PRNs]; // memory containing all the possible fft codes for PRN 0 to 32
|
||||||
float max; // temporary maxima search
|
float max; // temporary maxima search
|
||||||
|
|
||||||
for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++)
|
for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++)
|
||||||
{
|
{
|
||||||
gps_l1_ca_code_gen_complex_sampled(code, PRN, fs_in, 0); // generate PRN code
|
gps_l1_ca_code_gen_complex_sampled(code, PRN, fs_in, 0); // generate PRN code
|
||||||
// fill in zero padding
|
// fill in zero padding
|
||||||
for (unsigned int s = code_length; s < nsamples_total; s++)
|
for (int s = code_length; s < nsamples_total; s++)
|
||||||
{
|
{
|
||||||
code[s] = 0;
|
code[s] = std::complex<float>(static_cast<float>(0, 0));
|
||||||
|
//code[s] = 0;
|
||||||
}
|
}
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
memcpy(fft_if->get_inbuf() + offset, code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer
|
memcpy(fft_if->get_inbuf() + offset, code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer
|
||||||
fft_if->execute(); // Run the FFT of local code
|
fft_if->execute(); // Run the FFT of local code
|
||||||
volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
|
volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
|
||||||
|
|
||||||
|
|
||||||
|
// // debug
|
||||||
|
// char filename[25];
|
||||||
|
// FILE *fid;
|
||||||
|
// sprintf(filename,"fft_gps_prn%d.txt", PRN);
|
||||||
|
// fid = fopen(filename, "w");
|
||||||
|
// for (unsigned int kk=0;kk< nsamples_total; kk++)
|
||||||
|
// {
|
||||||
|
// fprintf(fid, "%f\n", fft_codes_padded[kk].real());
|
||||||
|
// fprintf(fid, "%f\n", fft_codes_padded[kk].imag());
|
||||||
|
// }
|
||||||
|
// fclose(fid);
|
||||||
|
|
||||||
max = 0; // initialize maximum value
|
max = 0; // initialize maximum value
|
||||||
for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima
|
for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima
|
||||||
{
|
{
|
||||||
@ -116,9 +132,28 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
|
|||||||
}
|
}
|
||||||
for (unsigned int i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs
|
for (unsigned int i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs
|
||||||
{
|
{
|
||||||
d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)),
|
//d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(256*fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)),
|
||||||
static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max)));
|
// static_cast<int>(floor(256*fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max)));
|
||||||
|
//d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(16*floor(fft_codes_padded[i].real() * (pow(2, 11) - 1) / max)),
|
||||||
|
// static_cast<int>(16*floor(fft_codes_padded[i].imag() * (pow(2, 11) - 1) / max)));
|
||||||
|
//d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)),
|
||||||
|
// static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max)));
|
||||||
|
d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)),
|
||||||
|
static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// // debug
|
||||||
|
// char filename2[25];
|
||||||
|
// FILE *fid2;
|
||||||
|
// sprintf(filename2,"fft_gps_prn%d_norm_new.txt", PRN);
|
||||||
|
// fid2 = fopen(filename2, "w");
|
||||||
|
// for (unsigned int kk=0;kk< nsamples_total; kk++)
|
||||||
|
// {
|
||||||
|
// fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].real());
|
||||||
|
// fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].imag());
|
||||||
|
// }
|
||||||
|
// fclose(fid2);
|
||||||
}
|
}
|
||||||
|
|
||||||
//acq_parameters
|
//acq_parameters
|
||||||
@ -135,14 +170,6 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
|
|||||||
channel_ = 0;
|
channel_ = 0;
|
||||||
doppler_step_ = 0;
|
doppler_step_ = 0;
|
||||||
gnss_synchro_ = 0;
|
gnss_synchro_ = 0;
|
||||||
if (in_streams_ > 1)
|
|
||||||
{
|
|
||||||
LOG(ERROR) << "This implementation only supports one input stream";
|
|
||||||
}
|
|
||||||
if (out_streams_ > 0)
|
|
||||||
{
|
|
||||||
LOG(ERROR) << "This implementation does not provide an output stream";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -161,6 +188,8 @@ void GpsL1CaPcpsAcquisitionFpga::set_channel(unsigned int channel)
|
|||||||
|
|
||||||
void GpsL1CaPcpsAcquisitionFpga::set_threshold(float threshold)
|
void GpsL1CaPcpsAcquisitionFpga::set_threshold(float threshold)
|
||||||
{
|
{
|
||||||
|
// the .pfa parameter and the threshold calculation is only used for the CFAR algorithm.
|
||||||
|
// We don't use the CFAR algorithm in the FPGA. Therefore the threshold is set as such.
|
||||||
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold;
|
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold;
|
||||||
acquisition_fpga_->set_threshold(threshold);
|
acquisition_fpga_->set_threshold(threshold);
|
||||||
}
|
}
|
||||||
@ -216,26 +245,21 @@ void GpsL1CaPcpsAcquisitionFpga::set_state(int state)
|
|||||||
acquisition_fpga_->set_state(state);
|
acquisition_fpga_->set_state(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GpsL1CaPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block)
|
void GpsL1CaPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block)
|
||||||
{
|
{
|
||||||
if (top_block)
|
// nothing to connect
|
||||||
{ // nothing to disconnect
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GpsL1CaPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block)
|
void GpsL1CaPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block)
|
||||||
{
|
{
|
||||||
if (top_block)
|
// nothing to disconnect
|
||||||
{ // nothing to disconnect
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gr::basic_block_sptr GpsL1CaPcpsAcquisitionFpga::get_left_block()
|
gr::basic_block_sptr GpsL1CaPcpsAcquisitionFpga::get_left_block()
|
||||||
{
|
{
|
||||||
return acquisition_fpga_;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline std::string implementation() override
|
inline std::string implementation() override
|
||||||
{
|
{
|
||||||
return "GPS_L1_CA_PCPS_Acquisition";
|
return "GPS_L1_CA_PCPS_Acquisition_Fpga";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t item_size() override
|
inline size_t item_size() override
|
||||||
|
@ -78,15 +78,19 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
|
|||||||
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
||||||
acq_parameters.dump_filename = dump_filename_;
|
acq_parameters.dump_filename = dump_filename_;
|
||||||
//--- Find number of samples per spreading code -------------------------
|
//--- Find number of samples per spreading code -------------------------
|
||||||
code_length_ = std::round(static_cast<double>(fs_in_) / (GPS_L2_M_CODE_RATE_HZ / static_cast<double>(GPS_L2_M_CODE_LENGTH_CHIPS)));
|
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||||
|
acq_parameters.ms_per_code = 20;
|
||||||
vector_length_ = code_length_;
|
acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", acq_parameters.ms_per_code);
|
||||||
|
if ((acq_parameters.sampled_ms % acq_parameters.ms_per_code) != 0)
|
||||||
if (bit_transition_flag_)
|
|
||||||
{
|
{
|
||||||
vector_length_ *= 2;
|
LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 20. Setting it to 20";
|
||||||
|
acq_parameters.sampled_ms = acq_parameters.ms_per_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code_length_ = acq_parameters.ms_per_code * acq_parameters.samples_per_ms;
|
||||||
|
|
||||||
|
vector_length_ = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1);
|
||||||
|
|
||||||
code_ = new gr_complex[vector_length_];
|
code_ = new gr_complex[vector_length_];
|
||||||
|
|
||||||
if (item_type_.compare("cshort") == 0)
|
if (item_type_.compare("cshort") == 0)
|
||||||
@ -97,10 +101,10 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
|
|||||||
{
|
{
|
||||||
item_size_ = sizeof(gr_complex);
|
item_size_ = sizeof(gr_complex);
|
||||||
}
|
}
|
||||||
acq_parameters.samples_per_ms = static_cast<int>(std::round(static_cast<double>(fs_in_) * 0.001));
|
|
||||||
acq_parameters.samples_per_code = code_length_;
|
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L2_M_PERIOD * 1000.0);
|
||||||
acq_parameters.it_size = item_size_;
|
acq_parameters.it_size = item_size_;
|
||||||
acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 20);
|
|
||||||
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
||||||
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||||
@ -108,9 +112,6 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
|
|||||||
acquisition_ = pcps_make_acquisition(acq_parameters);
|
acquisition_ = pcps_make_acquisition(acq_parameters);
|
||||||
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
|
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
|
||||||
|
|
||||||
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
|
|
||||||
DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")";
|
|
||||||
|
|
||||||
if (item_type_.compare("cbyte") == 0)
|
if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
|
cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
|
||||||
@ -121,6 +122,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
|
|||||||
threshold_ = 0.0;
|
threshold_ = 0.0;
|
||||||
doppler_step_ = 0;
|
doppler_step_ = 0;
|
||||||
gnss_synchro_ = 0;
|
gnss_synchro_ = 0;
|
||||||
|
num_codes_ = acq_parameters.sampled_ms / acq_parameters.ms_per_code;
|
||||||
if (in_streams_ > 1)
|
if (in_streams_ > 1)
|
||||||
{
|
{
|
||||||
LOG(ERROR) << "This implementation only supports one input stream";
|
LOG(ERROR) << "This implementation only supports one input stream";
|
||||||
@ -209,9 +211,18 @@ void GpsL2MPcpsAcquisition::init()
|
|||||||
|
|
||||||
void GpsL2MPcpsAcquisition::set_local_code()
|
void GpsL2MPcpsAcquisition::set_local_code()
|
||||||
{
|
{
|
||||||
gps_l2c_m_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_);
|
std::complex<float>* code = new std::complex<float>[code_length_];
|
||||||
|
|
||||||
|
gps_l2c_m_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < num_codes_; i++)
|
||||||
|
{
|
||||||
|
memcpy(&(code_[i * code_length_]), code,
|
||||||
|
sizeof(gr_complex) * code_length_);
|
||||||
|
}
|
||||||
|
|
||||||
acquisition_->set_local_code(code_);
|
acquisition_->set_local_code(code_);
|
||||||
|
delete[] code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -250,18 +261,19 @@ void GpsL2MPcpsAcquisition::connect(gr::top_block_sptr top_block)
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to connect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to connect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
|
// Since a byte-based acq implementation is not available,
|
||||||
|
// we just convert cshorts to gr_complex
|
||||||
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
top_block->connect(float_to_complex_, 0, stream_to_vector_, 0);
|
top_block->connect(float_to_complex_, 0, acquisition_, 0);
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -274,20 +286,17 @@ void GpsL2MPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to disconnect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to disconnect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
// Since a byte-based acq implementation is not available,
|
|
||||||
// we just convert cshorts to gr_complex
|
|
||||||
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0);
|
top_block->disconnect(float_to_complex_, 0, acquisition_, 0);
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -300,11 +309,11 @@ gr::basic_block_sptr GpsL2MPcpsAcquisition::get_left_block()
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
return stream_to_vector_;
|
return acquisition_;
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
return stream_to_vector_;
|
return acquisition_;
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "pcps_acquisition.h"
|
#include "pcps_acquisition.h"
|
||||||
#include "complex_byte_to_float_x2.h"
|
#include "complex_byte_to_float_x2.h"
|
||||||
#include <gnuradio/blocks/stream_to_vector.h>
|
|
||||||
#include <gnuradio/blocks/float_to_complex.h>
|
#include <gnuradio/blocks/float_to_complex.h>
|
||||||
#include <volk_gnsssdr/volk_gnsssdr.h>
|
#include <volk_gnsssdr/volk_gnsssdr.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -137,7 +136,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
pcps_acquisition_sptr acquisition_;
|
pcps_acquisition_sptr acquisition_;
|
||||||
gr::blocks::stream_to_vector::sptr stream_to_vector_;
|
|
||||||
gr::blocks::float_to_complex::sptr float_to_complex_;
|
gr::blocks::float_to_complex::sptr float_to_complex_;
|
||||||
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
|
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
|
||||||
size_t item_size_;
|
size_t item_size_;
|
||||||
@ -160,6 +158,7 @@ private:
|
|||||||
std::string role_;
|
std::string role_;
|
||||||
unsigned int in_streams_;
|
unsigned int in_streams_;
|
||||||
unsigned int out_streams_;
|
unsigned int out_streams_;
|
||||||
|
unsigned int num_codes_;
|
||||||
|
|
||||||
float calculate_threshold(float pfa);
|
float calculate_threshold(float pfa);
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,398 @@
|
|||||||
|
/*!
|
||||||
|
* \file gps_l2_m_pcps_acquisition.cc
|
||||||
|
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||||
|
* GPS L2 M signals
|
||||||
|
* \authors <ul>
|
||||||
|
* <li> Javier Arribas, 2015. jarribas(at)cttc.es
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2015 (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_l2_m_pcps_acquisition_fpga.h"
|
||||||
|
#include "configuration_interface.h"
|
||||||
|
#include "gps_l2c_signal.h"
|
||||||
|
#include "GPS_L2C.h"
|
||||||
|
#include "gnss_sdr_flags.h"
|
||||||
|
#include <boost/math/distributions/exponential.hpp>
|
||||||
|
#include <glog/logging.h>
|
||||||
|
|
||||||
|
#define NUM_PRNs 32
|
||||||
|
|
||||||
|
using google::LogMessage;
|
||||||
|
|
||||||
|
GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga(
|
||||||
|
ConfigurationInterface* configuration, std::string role,
|
||||||
|
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
|
||||||
|
{
|
||||||
|
//pcpsconf_t acq_parameters;
|
||||||
|
pcpsconf_fpga_t acq_parameters;
|
||||||
|
configuration_ = configuration;
|
||||||
|
std::string default_item_type = "gr_complex";
|
||||||
|
std::string default_dump_filename = "./data/acquisition.dat";
|
||||||
|
|
||||||
|
LOG(INFO) << "role " << role;
|
||||||
|
|
||||||
|
item_type_ = configuration_->property(role + ".item_type", default_item_type);
|
||||||
|
//float pfa = configuration_->property(role + ".pfa", 0.0);
|
||||||
|
|
||||||
|
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
||||||
|
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||||
|
acq_parameters.fs_in = fs_in_;
|
||||||
|
//if_ = configuration_->property(role + ".if", 0);
|
||||||
|
//acq_parameters.freq = if_;
|
||||||
|
//dump_ = configuration_->property(role + ".dump", false);
|
||||||
|
//acq_parameters.dump = dump_;
|
||||||
|
//blocking_ = configuration_->property(role + ".blocking", true);
|
||||||
|
//acq_parameters.blocking = blocking_;
|
||||||
|
doppler_max_ = configuration->property(role + ".doppler_max", 5000);
|
||||||
|
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
|
||||||
|
acq_parameters.doppler_max = doppler_max_;
|
||||||
|
//bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
||||||
|
//acq_parameters.bit_transition_flag = bit_transition_flag_;
|
||||||
|
//use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
|
||||||
|
//acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
|
||||||
|
//max_dwells_ = configuration_->property(role + ".max_dwells", 1);
|
||||||
|
//acq_parameters.max_dwells = max_dwells_;
|
||||||
|
//dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
||||||
|
//acq_parameters.dump_filename = dump_filename_;
|
||||||
|
//--- Find number of samples per spreading code -------------------------
|
||||||
|
//code_length_ = std::round(static_cast<double>(fs_in_) / (GPS_L2_M_CODE_RATE_HZ / static_cast<double>(GPS_L2_M_CODE_LENGTH_CHIPS)));
|
||||||
|
|
||||||
|
acq_parameters.sampled_ms = 20;
|
||||||
|
unsigned code_length = std::round(static_cast<double>(fs_in_) / (GPS_L2_M_CODE_RATE_HZ / static_cast<double>(GPS_L2_M_CODE_LENGTH_CHIPS)));
|
||||||
|
acq_parameters.code_length = code_length;
|
||||||
|
// The FPGA can only use FFT lengths that are a power of two.
|
||||||
|
float nbits = ceilf(log2f((float)code_length));
|
||||||
|
unsigned int nsamples_total = pow(2, nbits);
|
||||||
|
unsigned int vector_length = nsamples_total;
|
||||||
|
unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0);
|
||||||
|
acq_parameters.select_queue_Fpga = select_queue_Fpga;
|
||||||
|
std::string default_device_name = "/dev/uio0";
|
||||||
|
std::string device_name = configuration_->property(role + ".devicename", default_device_name);
|
||||||
|
acq_parameters.device_name = device_name;
|
||||||
|
acq_parameters.samples_per_ms = nsamples_total/acq_parameters.sampled_ms;
|
||||||
|
//acq_parameters.samples_per_ms = static_cast<int>(std::round(static_cast<double>(fs_in_) * 0.001));
|
||||||
|
acq_parameters.samples_per_code = nsamples_total;
|
||||||
|
|
||||||
|
// compute all the GPS L1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time
|
||||||
|
// a channel is assigned)
|
||||||
|
gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(vector_length, true); // Direct FFT
|
||||||
|
// allocate memory to compute all the PRNs and compute all the possible codes
|
||||||
|
std::complex<float>* code = new std::complex<float>[nsamples_total]; // buffer for the local code
|
||||||
|
gr_complex* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||||
|
d_all_fft_codes_ = new lv_16sc_t[nsamples_total * NUM_PRNs]; // memory containing all the possible fft codes for PRN 0 to 32
|
||||||
|
float max; // temporary maxima search
|
||||||
|
for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++)
|
||||||
|
{
|
||||||
|
gps_l2c_m_code_gen_complex_sampled(code, PRN, fs_in_);
|
||||||
|
// fill in zero padding
|
||||||
|
for (int s = code_length; s < nsamples_total; s++)
|
||||||
|
{
|
||||||
|
code[s] = std::complex<float>(static_cast<float>(0,0));
|
||||||
|
//code[s] = 0;
|
||||||
|
}
|
||||||
|
memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer
|
||||||
|
fft_if->execute(); // Run the FFT of local code
|
||||||
|
volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
|
||||||
|
max = 0; // initialize maximum value
|
||||||
|
for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima
|
||||||
|
{
|
||||||
|
if (std::abs(fft_codes_padded[i].real()) > max)
|
||||||
|
{
|
||||||
|
max = std::abs(fft_codes_padded[i].real());
|
||||||
|
}
|
||||||
|
if (std::abs(fft_codes_padded[i].imag()) > max)
|
||||||
|
{
|
||||||
|
max = std::abs(fft_codes_padded[i].imag());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (unsigned int i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs
|
||||||
|
{
|
||||||
|
d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)),
|
||||||
|
static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//acq_parameters
|
||||||
|
acq_parameters.all_fft_codes = d_all_fft_codes_;
|
||||||
|
|
||||||
|
// temporary buffers that we can delete
|
||||||
|
delete[] code;
|
||||||
|
delete fft_if;
|
||||||
|
delete[] fft_codes_padded;
|
||||||
|
|
||||||
|
acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters);
|
||||||
|
DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";
|
||||||
|
|
||||||
|
channel_ = 0;
|
||||||
|
doppler_step_ = 0;
|
||||||
|
gnss_synchro_ = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// vector_length_ = code_length_;
|
||||||
|
//
|
||||||
|
// if (bit_transition_flag_)
|
||||||
|
// {
|
||||||
|
// vector_length_ *= 2;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// code_ = new gr_complex[vector_length_];
|
||||||
|
//
|
||||||
|
// if (item_type_.compare("cshort") == 0)
|
||||||
|
// {
|
||||||
|
// item_size_ = sizeof(lv_16sc_t);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// item_size_ = sizeof(gr_complex);
|
||||||
|
// }
|
||||||
|
//acq_parameters.samples_per_ms = static_cast<int>(std::round(static_cast<double>(fs_in_) * 0.001));
|
||||||
|
//acq_parameters.samples_per_code = code_length_;
|
||||||
|
//acq_parameters.it_size = item_size_;
|
||||||
|
//acq_parameters.sampled_ms = 20;
|
||||||
|
//acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
||||||
|
//acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||||
|
//acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", true);
|
||||||
|
//acquisition_ = pcps_make_acquisition(acq_parameters);
|
||||||
|
DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";
|
||||||
|
|
||||||
|
// stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
|
||||||
|
// DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")";
|
||||||
|
//
|
||||||
|
// if (item_type_.compare("cbyte") == 0)
|
||||||
|
// {
|
||||||
|
// cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
|
||||||
|
// float_to_complex_ = gr::blocks::float_to_complex::make();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// channel_ = 0;
|
||||||
|
threshold_ = 0.0;
|
||||||
|
// doppler_step_ = 0;
|
||||||
|
// gnss_synchro_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GpsL2MPcpsAcquisitionFpga::~GpsL2MPcpsAcquisitionFpga()
|
||||||
|
{
|
||||||
|
//delete[] code_;
|
||||||
|
delete[] d_all_fft_codes_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL2MPcpsAcquisitionFpga::set_channel(unsigned int channel)
|
||||||
|
{
|
||||||
|
channel_ = channel;
|
||||||
|
acquisition_fpga_->set_channel(channel_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL2MPcpsAcquisitionFpga::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_;
|
||||||
|
|
||||||
|
acquisition_fpga_->set_threshold(threshold_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL2MPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max)
|
||||||
|
{
|
||||||
|
doppler_max_ = doppler_max;
|
||||||
|
|
||||||
|
acquisition_fpga_->set_doppler_max(doppler_max_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Be aware that Doppler step should be set to 2/(3T) Hz, where T is the coherent integration time (GPS L2 period is 0.02s)
|
||||||
|
// Doppler bin minimum size= 33 Hz
|
||||||
|
void GpsL2MPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step)
|
||||||
|
{
|
||||||
|
doppler_step_ = doppler_step;
|
||||||
|
|
||||||
|
acquisition_fpga_->set_doppler_step(doppler_step_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL2MPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
|
||||||
|
{
|
||||||
|
gnss_synchro_ = gnss_synchro;
|
||||||
|
|
||||||
|
acquisition_fpga_->set_gnss_synchro(gnss_synchro_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
signed int GpsL2MPcpsAcquisitionFpga::mag()
|
||||||
|
{
|
||||||
|
return acquisition_fpga_->mag();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL2MPcpsAcquisitionFpga::init()
|
||||||
|
{
|
||||||
|
acquisition_fpga_->init();
|
||||||
|
//set_local_code();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL2MPcpsAcquisitionFpga::set_local_code()
|
||||||
|
{
|
||||||
|
//gps_l2c_m_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_);
|
||||||
|
|
||||||
|
//acquisition_fpga_->set_local_code(code_);
|
||||||
|
acquisition_fpga_->set_local_code();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL2MPcpsAcquisitionFpga::reset()
|
||||||
|
{
|
||||||
|
acquisition_fpga_->set_active(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GpsL2MPcpsAcquisitionFpga::set_state(int state)
|
||||||
|
{
|
||||||
|
acquisition_fpga_->set_state(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//float GpsL2MPcpsAcquisitionFpga::calculate_threshold(float pfa)
|
||||||
|
//{
|
||||||
|
// //Calculate the threshold
|
||||||
|
// unsigned int frequency_bins = 0;
|
||||||
|
// for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_)
|
||||||
|
// {
|
||||||
|
// frequency_bins++;
|
||||||
|
// }
|
||||||
|
// DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
|
||||||
|
// unsigned int ncells = vector_length_ * frequency_bins;
|
||||||
|
// double exponent = 1.0 / static_cast<double>(ncells);
|
||||||
|
// double val = pow(1.0 - pfa, exponent);
|
||||||
|
// double lambda = double(vector_length_);
|
||||||
|
// boost::math::exponential_distribution<double> mydist(lambda);
|
||||||
|
// float threshold = static_cast<float>(quantile(mydist, val));
|
||||||
|
//
|
||||||
|
// return threshold;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL2MPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block)
|
||||||
|
{
|
||||||
|
// if (item_type_.compare("gr_complex") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cshort") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cbyte") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
|
// top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
|
// top_block->connect(float_to_complex_, 0, stream_to_vector_, 0);
|
||||||
|
// top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||||
|
// }
|
||||||
|
|
||||||
|
// nothing to connect
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL2MPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block)
|
||||||
|
{
|
||||||
|
// if (item_type_.compare("gr_complex") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cshort") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cbyte") == 0)
|
||||||
|
// {
|
||||||
|
// // Since a byte-based acq implementation is not available,
|
||||||
|
// // we just convert cshorts to gr_complex
|
||||||
|
// top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
|
// top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
|
// top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0);
|
||||||
|
// top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||||
|
// }
|
||||||
|
|
||||||
|
// nothing to disconnect
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gr::basic_block_sptr GpsL2MPcpsAcquisitionFpga::get_left_block()
|
||||||
|
{
|
||||||
|
// if (item_type_.compare("gr_complex") == 0)
|
||||||
|
// {
|
||||||
|
// return stream_to_vector_;
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cshort") == 0)
|
||||||
|
// {
|
||||||
|
// return stream_to_vector_;
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cbyte") == 0)
|
||||||
|
// {
|
||||||
|
// return cbyte_to_float_x2_;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||||
|
// return nullptr;
|
||||||
|
// }
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gr::basic_block_sptr GpsL2MPcpsAcquisitionFpga::get_right_block()
|
||||||
|
{
|
||||||
|
return acquisition_fpga_;
|
||||||
|
}
|
@ -0,0 +1,171 @@
|
|||||||
|
/*!
|
||||||
|
* \file gps_l2_m_pcps_acquisition.h
|
||||||
|
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||||
|
* GPS L2 M signals
|
||||||
|
* \authors <ul>
|
||||||
|
* <li> Javier Arribas, 2015. jarribas(at)cttc.es
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2015 (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_L2_M_PCPS_ACQUISITION_FPGA_H_
|
||||||
|
#define GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_FPGA_H_
|
||||||
|
|
||||||
|
#include "acquisition_interface.h"
|
||||||
|
#include "gnss_synchro.h"
|
||||||
|
#include "pcps_acquisition_fpga.h"
|
||||||
|
#include "complex_byte_to_float_x2.h"
|
||||||
|
#include <gnuradio/blocks/stream_to_vector.h>
|
||||||
|
#include <gnuradio/blocks/float_to_complex.h>
|
||||||
|
#include <volk_gnsssdr/volk_gnsssdr.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigurationInterface;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief This class adapts a PCPS acquisition block to an AcquisitionInterface
|
||||||
|
* for GPS L2 M signals
|
||||||
|
*/
|
||||||
|
class GpsL2MPcpsAcquisitionFpga : public AcquisitionInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GpsL2MPcpsAcquisitionFpga(ConfigurationInterface* configuration,
|
||||||
|
std::string role, unsigned int in_streams,
|
||||||
|
unsigned int out_streams);
|
||||||
|
|
||||||
|
virtual ~GpsL2MPcpsAcquisitionFpga();
|
||||||
|
|
||||||
|
inline std::string role() override
|
||||||
|
{
|
||||||
|
return role_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns "GPS_L2_M_PCPS_Acquisition"
|
||||||
|
*/
|
||||||
|
inline std::string implementation() override
|
||||||
|
{
|
||||||
|
return "GPS_L2_M_PCPS_Acquisition";
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t item_size() override
|
||||||
|
{
|
||||||
|
return item_size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void connect(gr::top_block_sptr top_block) override;
|
||||||
|
void disconnect(gr::top_block_sptr top_block) override;
|
||||||
|
gr::basic_block_sptr get_left_block() override;
|
||||||
|
gr::basic_block_sptr get_right_block() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \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) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set acquisition channel unique ID
|
||||||
|
*/
|
||||||
|
void set_channel(unsigned int channel) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set statistics threshold of PCPS algorithm
|
||||||
|
*/
|
||||||
|
void set_threshold(float threshold) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set maximum Doppler off grid search
|
||||||
|
*/
|
||||||
|
void set_doppler_max(unsigned int doppler_max) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set Doppler steps for the grid search
|
||||||
|
*/
|
||||||
|
void set_doppler_step(unsigned int doppler_step) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes acquisition algorithm.
|
||||||
|
*/
|
||||||
|
void init() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets local code for GPS L2/M PCPS acquisition algorithm.
|
||||||
|
*/
|
||||||
|
void set_local_code() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the maximum peak of grid search
|
||||||
|
*/
|
||||||
|
signed int mag() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Restart acquisition algorithm
|
||||||
|
*/
|
||||||
|
void reset() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
||||||
|
*/
|
||||||
|
void set_state(int state) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConfigurationInterface* configuration_;
|
||||||
|
//pcps_acquisition_sptr acquisition_;
|
||||||
|
pcps_acquisition_fpga_sptr acquisition_fpga_;
|
||||||
|
gr::blocks::stream_to_vector::sptr stream_to_vector_;
|
||||||
|
gr::blocks::float_to_complex::sptr float_to_complex_;
|
||||||
|
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
|
||||||
|
size_t item_size_;
|
||||||
|
std::string item_type_;
|
||||||
|
unsigned int vector_length_;
|
||||||
|
unsigned int code_length_;
|
||||||
|
bool bit_transition_flag_;
|
||||||
|
bool use_CFAR_algorithm_flag_;
|
||||||
|
unsigned int channel_;
|
||||||
|
float threshold_;
|
||||||
|
unsigned int doppler_max_;
|
||||||
|
unsigned int doppler_step_;
|
||||||
|
unsigned int max_dwells_;
|
||||||
|
long fs_in_;
|
||||||
|
//long if_;
|
||||||
|
bool dump_;
|
||||||
|
bool blocking_;
|
||||||
|
std::string dump_filename_;
|
||||||
|
std::complex<float>* code_;
|
||||||
|
Gnss_Synchro* gnss_synchro_;
|
||||||
|
std::string role_;
|
||||||
|
unsigned int in_streams_;
|
||||||
|
unsigned int out_streams_;
|
||||||
|
|
||||||
|
lv_16sc_t* d_all_fft_codes_; // memory that contains all the code ffts
|
||||||
|
|
||||||
|
//float calculate_threshold(float pfa);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_FPGA_H_ */
|
@ -76,16 +76,13 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
|
|||||||
acq_parameters.max_dwells = max_dwells_;
|
acq_parameters.max_dwells = max_dwells_;
|
||||||
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
||||||
acq_parameters.dump_filename = dump_filename_;
|
acq_parameters.dump_filename = dump_filename_;
|
||||||
|
acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
|
||||||
//--- Find number of samples per spreading code -------------------------
|
//--- Find number of samples per spreading code -------------------------
|
||||||
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (GPS_L5i_CODE_RATE_HZ / static_cast<double>(GPS_L5i_CODE_LENGTH_CHIPS))));
|
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (GPS_L5i_CODE_RATE_HZ / GPS_L5i_CODE_LENGTH_CHIPS)));
|
||||||
|
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||||
vector_length_ = code_length_;
|
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L5i_PERIOD * 1000.0);
|
||||||
|
|
||||||
if (bit_transition_flag_)
|
|
||||||
{
|
|
||||||
vector_length_ *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
vector_length_ = std::floor(acq_parameters.sampled_ms * acq_parameters.samples_per_ms) * (acq_parameters.bit_transition_flag ? 2 : 1);
|
||||||
code_ = new gr_complex[vector_length_];
|
code_ = new gr_complex[vector_length_];
|
||||||
|
|
||||||
if (item_type_.compare("cshort") == 0)
|
if (item_type_.compare("cshort") == 0)
|
||||||
@ -96,10 +93,10 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
|
|||||||
{
|
{
|
||||||
item_size_ = sizeof(gr_complex);
|
item_size_ = sizeof(gr_complex);
|
||||||
}
|
}
|
||||||
acq_parameters.samples_per_code = code_length_;
|
|
||||||
acq_parameters.samples_per_ms = code_length_;
|
acq_parameters.ms_per_code = 1;
|
||||||
acq_parameters.it_size = item_size_;
|
acq_parameters.it_size = item_size_;
|
||||||
acq_parameters.sampled_ms = 1;
|
num_codes_ = acq_parameters.sampled_ms;
|
||||||
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
||||||
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||||
@ -107,15 +104,11 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
|
|||||||
acquisition_ = pcps_make_acquisition(acq_parameters);
|
acquisition_ = pcps_make_acquisition(acq_parameters);
|
||||||
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
|
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
|
||||||
|
|
||||||
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
|
|
||||||
DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")";
|
|
||||||
|
|
||||||
if (item_type_.compare("cbyte") == 0)
|
if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
|
cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
|
||||||
float_to_complex_ = gr::blocks::float_to_complex::make();
|
float_to_complex_ = gr::blocks::float_to_complex::make();
|
||||||
}
|
}
|
||||||
|
|
||||||
channel_ = 0;
|
channel_ = 0;
|
||||||
threshold_ = 0.0;
|
threshold_ = 0.0;
|
||||||
doppler_step_ = 0;
|
doppler_step_ = 0;
|
||||||
@ -206,9 +199,18 @@ void GpsL5iPcpsAcquisition::init()
|
|||||||
|
|
||||||
void GpsL5iPcpsAcquisition::set_local_code()
|
void GpsL5iPcpsAcquisition::set_local_code()
|
||||||
{
|
{
|
||||||
gps_l5i_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_);
|
std::complex<float>* code = new std::complex<float>[code_length_];
|
||||||
|
|
||||||
|
gps_l5i_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < num_codes_; i++)
|
||||||
|
{
|
||||||
|
memcpy(&(code_[i * code_length_]), code,
|
||||||
|
sizeof(gr_complex) * code_length_);
|
||||||
|
}
|
||||||
|
|
||||||
acquisition_->set_local_code(code_);
|
acquisition_->set_local_code(code_);
|
||||||
|
delete[] code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -247,18 +249,19 @@ void GpsL5iPcpsAcquisition::connect(gr::top_block_sptr top_block)
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to connect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to connect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
|
// Since a byte-based acq implementation is not available,
|
||||||
|
// we just convert cshorts to gr_complex
|
||||||
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
top_block->connect(float_to_complex_, 0, stream_to_vector_, 0);
|
top_block->connect(float_to_complex_, 0, acquisition_, 0);
|
||||||
top_block->connect(stream_to_vector_, 0, acquisition_, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -271,20 +274,17 @@ void GpsL5iPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to disconnect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
// nothing to disconnect
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
// Since a byte-based acq implementation is not available,
|
|
||||||
// we just convert cshorts to gr_complex
|
|
||||||
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0);
|
top_block->disconnect(float_to_complex_, 0, acquisition_, 0);
|
||||||
top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -297,11 +297,11 @@ gr::basic_block_sptr GpsL5iPcpsAcquisition::get_left_block()
|
|||||||
{
|
{
|
||||||
if (item_type_.compare("gr_complex") == 0)
|
if (item_type_.compare("gr_complex") == 0)
|
||||||
{
|
{
|
||||||
return stream_to_vector_;
|
return acquisition_;
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cshort") == 0)
|
else if (item_type_.compare("cshort") == 0)
|
||||||
{
|
{
|
||||||
return stream_to_vector_;
|
return acquisition_;
|
||||||
}
|
}
|
||||||
else if (item_type_.compare("cbyte") == 0)
|
else if (item_type_.compare("cbyte") == 0)
|
||||||
{
|
{
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
#include "pcps_acquisition.h"
|
#include "pcps_acquisition.h"
|
||||||
#include "complex_byte_to_float_x2.h"
|
#include "complex_byte_to_float_x2.h"
|
||||||
#include <gnuradio/blocks/stream_to_vector.h>
|
|
||||||
#include <gnuradio/blocks/float_to_complex.h>
|
#include <gnuradio/blocks/float_to_complex.h>
|
||||||
#include <volk_gnsssdr/volk_gnsssdr.h>
|
#include <volk_gnsssdr/volk_gnsssdr.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -137,7 +136,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
ConfigurationInterface* configuration_;
|
ConfigurationInterface* configuration_;
|
||||||
pcps_acquisition_sptr acquisition_;
|
pcps_acquisition_sptr acquisition_;
|
||||||
gr::blocks::stream_to_vector::sptr stream_to_vector_;
|
|
||||||
gr::blocks::float_to_complex::sptr float_to_complex_;
|
gr::blocks::float_to_complex::sptr float_to_complex_;
|
||||||
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
|
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
|
||||||
size_t item_size_;
|
size_t item_size_;
|
||||||
@ -158,6 +156,7 @@ private:
|
|||||||
std::complex<float>* code_;
|
std::complex<float>* code_;
|
||||||
Gnss_Synchro* gnss_synchro_;
|
Gnss_Synchro* gnss_synchro_;
|
||||||
std::string role_;
|
std::string role_;
|
||||||
|
unsigned int num_codes_;
|
||||||
unsigned int in_streams_;
|
unsigned int in_streams_;
|
||||||
unsigned int out_streams_;
|
unsigned int out_streams_;
|
||||||
|
|
||||||
|
@ -0,0 +1,404 @@
|
|||||||
|
/*!
|
||||||
|
* \file gps_l5i pcps_acquisition.cc
|
||||||
|
* \brief Adapts a PCPS acquisition block to an Acquisition Interface for
|
||||||
|
* GPS L5i signals
|
||||||
|
* \authors <ul>
|
||||||
|
* <li> Javier Arribas, 2017. jarribas(at)cttc.es
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
|
||||||
|
*
|
||||||
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
|
* Satellite Systems receiver
|
||||||
|
*
|
||||||
|
* This file is part of GNSS-SDR.
|
||||||
|
*
|
||||||
|
* GNSS-SDR is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GNSS-SDR is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gps_l5i_pcps_acquisition_fpga.h"
|
||||||
|
#include "configuration_interface.h"
|
||||||
|
#include "gps_l5_signal.h"
|
||||||
|
#include "GPS_L5.h"
|
||||||
|
#include "gnss_sdr_flags.h"
|
||||||
|
#include <boost/math/distributions/exponential.hpp>
|
||||||
|
#include <glog/logging.h>
|
||||||
|
|
||||||
|
#define NUM_PRNs 32
|
||||||
|
|
||||||
|
using google::LogMessage;
|
||||||
|
|
||||||
|
GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga(
|
||||||
|
ConfigurationInterface* configuration, std::string role,
|
||||||
|
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
|
||||||
|
{
|
||||||
|
//printf("L5 ACQ CLASS CREATED\n");
|
||||||
|
pcpsconf_fpga_t acq_parameters;
|
||||||
|
configuration_ = configuration;
|
||||||
|
std::string default_item_type = "gr_complex";
|
||||||
|
std::string default_dump_filename = "./data/acquisition.dat";
|
||||||
|
|
||||||
|
LOG(INFO) << "role " << role;
|
||||||
|
|
||||||
|
//item_type_ = configuration_->property(role + ".item_type", default_item_type);
|
||||||
|
|
||||||
|
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
|
||||||
|
long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
|
||||||
|
acq_parameters.fs_in = fs_in;
|
||||||
|
//if_ = configuration_->property(role + ".if", 0);
|
||||||
|
//acq_parameters.freq = if_;
|
||||||
|
//dump_ = configuration_->property(role + ".dump", false);
|
||||||
|
//acq_parameters.dump = dump_;
|
||||||
|
//blocking_ = configuration_->property(role + ".blocking", true);
|
||||||
|
//acq_parameters.blocking = blocking_;
|
||||||
|
doppler_max_ = configuration->property(role + ".doppler_max", 5000);
|
||||||
|
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
|
||||||
|
acq_parameters.doppler_max = doppler_max_;
|
||||||
|
//acq_parameters.sampled_ms = 1;
|
||||||
|
unsigned int sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
|
||||||
|
acq_parameters.sampled_ms = sampled_ms;
|
||||||
|
|
||||||
|
//printf("L5 ACQ CLASS MID 0\n");
|
||||||
|
|
||||||
|
//bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
||||||
|
//acq_parameters.bit_transition_flag = bit_transition_flag_;
|
||||||
|
//use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
|
||||||
|
//acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
|
||||||
|
//max_dwells_ = configuration_->property(role + ".max_dwells", 1);
|
||||||
|
//acq_parameters.max_dwells = max_dwells_;
|
||||||
|
//dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
||||||
|
//acq_parameters.dump_filename = dump_filename_;
|
||||||
|
//--- Find number of samples per spreading code -------------------------
|
||||||
|
unsigned int code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / (GPS_L5i_CODE_RATE_HZ / static_cast<double>(GPS_L5i_CODE_LENGTH_CHIPS))));
|
||||||
|
acq_parameters.code_length = code_length;
|
||||||
|
// The FPGA can only use FFT lengths that are a power of two.
|
||||||
|
float nbits = ceilf(log2f((float)code_length));
|
||||||
|
unsigned int nsamples_total = pow(2, nbits);
|
||||||
|
unsigned int vector_length = nsamples_total;
|
||||||
|
unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 1);
|
||||||
|
acq_parameters.select_queue_Fpga = select_queue_Fpga;
|
||||||
|
std::string default_device_name = "/dev/uio0";
|
||||||
|
std::string device_name = configuration_->property(role + ".devicename", default_device_name);
|
||||||
|
acq_parameters.device_name = device_name;
|
||||||
|
acq_parameters.samples_per_ms = nsamples_total;
|
||||||
|
acq_parameters.samples_per_code = nsamples_total;
|
||||||
|
//printf("L5 ACQ CLASS MID 01\n");
|
||||||
|
// compute all the GPS L5 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time
|
||||||
|
// a channel is assigned)
|
||||||
|
gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(vector_length, true); // Direct FFT
|
||||||
|
//printf("L5 ACQ CLASS MID 02\n");
|
||||||
|
std::complex<float>* code = new gr_complex[vector_length];
|
||||||
|
//printf("L5 ACQ CLASS MID 03\n");
|
||||||
|
gr_complex* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||||
|
//printf("L5 ACQ CLASS MID 04\n");
|
||||||
|
d_all_fft_codes_ = new lv_16sc_t[nsamples_total * NUM_PRNs]; // memory containing all the possible fft codes for PRN 0 to 32
|
||||||
|
|
||||||
|
//printf("L5 ACQ CLASS MID 1 vector_length = %d\n", vector_length);
|
||||||
|
|
||||||
|
float max; // temporary maxima search
|
||||||
|
for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++)
|
||||||
|
{
|
||||||
|
//printf("L5 ACQ CLASS processing PRN = %d\n", PRN);
|
||||||
|
gps_l5i_code_gen_complex_sampled(code, PRN, fs_in);
|
||||||
|
//printf("L5 ACQ CLASS processing PRN = %d (cont) \n", PRN);
|
||||||
|
// fill in zero padding
|
||||||
|
for (int s = code_length; s < nsamples_total; s++)
|
||||||
|
{
|
||||||
|
code[s] = std::complex<float>(static_cast<float>(0,0));
|
||||||
|
//code[s] = 0;
|
||||||
|
}
|
||||||
|
memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer
|
||||||
|
fft_if->execute(); // Run the FFT of local code
|
||||||
|
volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
|
||||||
|
|
||||||
|
max = 0; // initialize maximum value
|
||||||
|
for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima
|
||||||
|
{
|
||||||
|
if (std::abs(fft_codes_padded[i].real()) > max)
|
||||||
|
{
|
||||||
|
max = std::abs(fft_codes_padded[i].real());
|
||||||
|
}
|
||||||
|
if (std::abs(fft_codes_padded[i].imag()) > max)
|
||||||
|
{
|
||||||
|
max = std::abs(fft_codes_padded[i].imag());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (unsigned int i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs
|
||||||
|
{
|
||||||
|
//d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(256*fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)),
|
||||||
|
// static_cast<int>(floor(256*fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max)));
|
||||||
|
//d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(16*floor(fft_codes_padded[i].real() * (pow(2, 11) - 1) / max)),
|
||||||
|
// static_cast<int>(16*floor(fft_codes_padded[i].imag() * (pow(2, 11) - 1) / max)));
|
||||||
|
//d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)),
|
||||||
|
// static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max)));
|
||||||
|
d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)),
|
||||||
|
static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//printf("L5 ACQ CLASS MID 2\n");
|
||||||
|
|
||||||
|
//acq_parameters
|
||||||
|
acq_parameters.all_fft_codes = d_all_fft_codes_;
|
||||||
|
|
||||||
|
// temporary buffers that we can delete
|
||||||
|
delete[] code;
|
||||||
|
delete fft_if;
|
||||||
|
delete[] fft_codes_padded;
|
||||||
|
// vector_length_ = code_length_;
|
||||||
|
//
|
||||||
|
// if (bit_transition_flag_)
|
||||||
|
// {
|
||||||
|
// vector_length_ *= 2;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// code_ = new gr_complex[vector_length_];
|
||||||
|
//
|
||||||
|
// if (item_type_.compare("cshort") == 0)
|
||||||
|
// {
|
||||||
|
// item_size_ = sizeof(lv_16sc_t);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// item_size_ = sizeof(gr_complex);
|
||||||
|
// }
|
||||||
|
// acq_parameters.samples_per_code = code_length_;
|
||||||
|
// acq_parameters.samples_per_ms = code_length_;
|
||||||
|
// acq_parameters.it_size = item_size_;
|
||||||
|
//acq_parameters.sampled_ms = 1;
|
||||||
|
// acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
|
||||||
|
// acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||||
|
// acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||||
|
// acquisition_fpga_ = pcps_make_acquisition(acq_parameters);
|
||||||
|
// DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";
|
||||||
|
|
||||||
|
acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters);
|
||||||
|
DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";
|
||||||
|
|
||||||
|
// stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
|
||||||
|
// DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")";
|
||||||
|
//
|
||||||
|
// if (item_type_.compare("cbyte") == 0)
|
||||||
|
// {
|
||||||
|
// cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
|
||||||
|
// float_to_complex_ = gr::blocks::float_to_complex::make();
|
||||||
|
// }
|
||||||
|
|
||||||
|
channel_ = 0;
|
||||||
|
// threshold_ = 0.0;
|
||||||
|
doppler_step_ = 0;
|
||||||
|
gnss_synchro_ = 0;
|
||||||
|
//printf("L5 ACQ CLASS FINISHED\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GpsL5iPcpsAcquisitionFpga::~GpsL5iPcpsAcquisitionFpga()
|
||||||
|
{
|
||||||
|
//delete[] code_;
|
||||||
|
delete[] d_all_fft_codes_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL5iPcpsAcquisitionFpga::set_channel(unsigned int channel)
|
||||||
|
{
|
||||||
|
channel_ = channel;
|
||||||
|
acquisition_fpga_->set_channel(channel_);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL5iPcpsAcquisitionFpga::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_;
|
||||||
|
|
||||||
|
// the .pfa parameter and the threshold calculation is only used for the CFAR algorithm.
|
||||||
|
// We don't use the CFAR algorithm in the FPGA. Therefore the threshold is set as such.
|
||||||
|
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold;
|
||||||
|
acquisition_fpga_->set_threshold(threshold);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL5iPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max)
|
||||||
|
{
|
||||||
|
doppler_max_ = doppler_max;
|
||||||
|
acquisition_fpga_->set_doppler_max(doppler_max_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Be aware that Doppler step should be set to 2/(3T) Hz, where T is the coherent integration time (GPS L2 period is 0.02s)
|
||||||
|
// Doppler bin minimum size= 33 Hz
|
||||||
|
void GpsL5iPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step)
|
||||||
|
{
|
||||||
|
doppler_step_ = doppler_step;
|
||||||
|
acquisition_fpga_->set_doppler_step(doppler_step_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL5iPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
|
||||||
|
{
|
||||||
|
gnss_synchro_ = gnss_synchro;
|
||||||
|
acquisition_fpga_->set_gnss_synchro(gnss_synchro_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
signed int GpsL5iPcpsAcquisitionFpga::mag()
|
||||||
|
{
|
||||||
|
return acquisition_fpga_->mag();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL5iPcpsAcquisitionFpga::init()
|
||||||
|
{
|
||||||
|
acquisition_fpga_->init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GpsL5iPcpsAcquisitionFpga::set_local_code()
|
||||||
|
{
|
||||||
|
acquisition_fpga_->set_local_code();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL5iPcpsAcquisitionFpga::reset()
|
||||||
|
{
|
||||||
|
acquisition_fpga_->set_active(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GpsL5iPcpsAcquisitionFpga::set_state(int state)
|
||||||
|
{
|
||||||
|
acquisition_fpga_->set_state(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//float GpsL5iPcpsAcquisitionFpga::calculate_threshold(float pfa)
|
||||||
|
//{
|
||||||
|
// //Calculate the threshold
|
||||||
|
// unsigned int frequency_bins = 0;
|
||||||
|
// for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_)
|
||||||
|
// {
|
||||||
|
// frequency_bins++;
|
||||||
|
// }
|
||||||
|
// DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
|
||||||
|
// unsigned int ncells = vector_length_ * frequency_bins;
|
||||||
|
// double exponent = 1.0 / static_cast<double>(ncells);
|
||||||
|
// double val = pow(1.0 - pfa, exponent);
|
||||||
|
// double lambda = double(vector_length_);
|
||||||
|
// boost::math::exponential_distribution<double> mydist(lambda);
|
||||||
|
// float threshold = static_cast<float>(quantile(mydist, val));
|
||||||
|
//
|
||||||
|
// return threshold;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL5iPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block)
|
||||||
|
{
|
||||||
|
// if (item_type_.compare("gr_complex") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0);
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cshort") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0);
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cbyte") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
|
// top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
|
// top_block->connect(float_to_complex_, 0, stream_to_vector_, 0);
|
||||||
|
// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||||
|
// }
|
||||||
|
// nothing to connect
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GpsL5iPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block)
|
||||||
|
{
|
||||||
|
// if (item_type_.compare("gr_complex") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0);
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cshort") == 0)
|
||||||
|
// {
|
||||||
|
// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0);
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cbyte") == 0)
|
||||||
|
// {
|
||||||
|
// // Since a byte-based acq implementation is not available,
|
||||||
|
// // we just convert cshorts to gr_complex
|
||||||
|
// top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
|
||||||
|
// top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
|
||||||
|
// top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0);
|
||||||
|
// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||||
|
// }
|
||||||
|
// nothing to disconnect
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gr::basic_block_sptr GpsL5iPcpsAcquisitionFpga::get_left_block()
|
||||||
|
{
|
||||||
|
// if (item_type_.compare("gr_complex") == 0)
|
||||||
|
// {
|
||||||
|
// return stream_to_vector_;
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cshort") == 0)
|
||||||
|
// {
|
||||||
|
// return stream_to_vector_;
|
||||||
|
// }
|
||||||
|
// else if (item_type_.compare("cbyte") == 0)
|
||||||
|
// {
|
||||||
|
// return cbyte_to_float_x2_;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||||
|
// return nullptr;
|
||||||
|
// }
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gr::basic_block_sptr GpsL5iPcpsAcquisitionFpga::get_right_block()
|
||||||
|
{
|
||||||
|
return acquisition_fpga_;
|
||||||
|
}
|
@ -0,0 +1,171 @@
|
|||||||
|
/*!
|
||||||
|
* \file GPS_L5i_PCPS_Acquisition.h
|
||||||
|
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||||
|
* GPS L5i signals
|
||||||
|
* \authors <ul>
|
||||||
|
* <li> Javier Arribas, 2017. jarribas(at)cttc.es
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
|
||||||
|
*
|
||||||
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
|
* Satellite Systems receiver
|
||||||
|
*
|
||||||
|
* This file is part of GNSS-SDR.
|
||||||
|
*
|
||||||
|
* GNSS-SDR is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GNSS-SDR is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GNSS_SDR_GPS_L5i_PCPS_ACQUISITION_FPGA_H_
|
||||||
|
#define GNSS_SDR_GPS_L5i_PCPS_ACQUISITION_FPGA_H_
|
||||||
|
|
||||||
|
#include "acquisition_interface.h"
|
||||||
|
#include "gnss_synchro.h"
|
||||||
|
#include "pcps_acquisition_fpga.h"
|
||||||
|
#include "complex_byte_to_float_x2.h"
|
||||||
|
#include <gnuradio/blocks/stream_to_vector.h>
|
||||||
|
#include <gnuradio/blocks/float_to_complex.h>
|
||||||
|
#include <volk_gnsssdr/volk_gnsssdr.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigurationInterface;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief This class adapts a PCPS acquisition block to an AcquisitionInterface
|
||||||
|
* for GPS L5i signals
|
||||||
|
*/
|
||||||
|
class GpsL5iPcpsAcquisitionFpga : public AcquisitionInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GpsL5iPcpsAcquisitionFpga(ConfigurationInterface* configuration,
|
||||||
|
std::string role, unsigned int in_streams,
|
||||||
|
unsigned int out_streams);
|
||||||
|
|
||||||
|
virtual ~GpsL5iPcpsAcquisitionFpga();
|
||||||
|
|
||||||
|
inline std::string role() override
|
||||||
|
{
|
||||||
|
return role_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns "GPS_L5i_PCPS_Acquisition"
|
||||||
|
*/
|
||||||
|
inline std::string implementation() override
|
||||||
|
{
|
||||||
|
return "GPS_L5i_PCPS_Acquisition";
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t item_size() override
|
||||||
|
{
|
||||||
|
return item_size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void connect(gr::top_block_sptr top_block) override;
|
||||||
|
void disconnect(gr::top_block_sptr top_block) override;
|
||||||
|
gr::basic_block_sptr get_left_block() override;
|
||||||
|
gr::basic_block_sptr get_right_block() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \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) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set acquisition channel unique ID
|
||||||
|
*/
|
||||||
|
void set_channel(unsigned int channel) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set statistics threshold of PCPS algorithm
|
||||||
|
*/
|
||||||
|
void set_threshold(float threshold) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set maximum Doppler off grid search
|
||||||
|
*/
|
||||||
|
void set_doppler_max(unsigned int doppler_max) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set Doppler steps for the grid search
|
||||||
|
*/
|
||||||
|
void set_doppler_step(unsigned int doppler_step) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes acquisition algorithm.
|
||||||
|
*/
|
||||||
|
void init() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets local code for GPS L2/M PCPS acquisition algorithm.
|
||||||
|
*/
|
||||||
|
void set_local_code() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the maximum peak of grid search
|
||||||
|
*/
|
||||||
|
signed int mag() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Restart acquisition algorithm
|
||||||
|
*/
|
||||||
|
void reset() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief If state = 1, it forces the block to start acquiring from the first sample
|
||||||
|
*/
|
||||||
|
void set_state(int state) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConfigurationInterface* configuration_;
|
||||||
|
//pcps_acquisition_sptr acquisition_;
|
||||||
|
pcps_acquisition_fpga_sptr acquisition_fpga_;
|
||||||
|
gr::blocks::stream_to_vector::sptr stream_to_vector_;
|
||||||
|
gr::blocks::float_to_complex::sptr float_to_complex_;
|
||||||
|
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
|
||||||
|
size_t item_size_;
|
||||||
|
std::string item_type_;
|
||||||
|
unsigned int vector_length_;
|
||||||
|
unsigned int code_length_;
|
||||||
|
bool bit_transition_flag_;
|
||||||
|
bool use_CFAR_algorithm_flag_;
|
||||||
|
unsigned int channel_;
|
||||||
|
float threshold_;
|
||||||
|
unsigned int doppler_max_;
|
||||||
|
unsigned int doppler_step_;
|
||||||
|
unsigned int max_dwells_;
|
||||||
|
long fs_in_;
|
||||||
|
//long if_;
|
||||||
|
bool dump_;
|
||||||
|
bool blocking_;
|
||||||
|
std::string dump_filename_;
|
||||||
|
std::complex<float>* code_;
|
||||||
|
Gnss_Synchro* gnss_synchro_;
|
||||||
|
std::string role_;
|
||||||
|
unsigned int in_streams_;
|
||||||
|
unsigned int out_streams_;
|
||||||
|
|
||||||
|
lv_16sc_t* d_all_fft_codes_; // memory that contains all the code ffts
|
||||||
|
|
||||||
|
float calculate_threshold(float pfa);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* GNSS_SDR_GPS_L5i_PCPS_ACQUISITION_FPGA_H_ */
|
@ -48,7 +48,7 @@ using google::LogMessage;
|
|||||||
galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(
|
galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(
|
||||||
unsigned int sampled_ms,
|
unsigned int sampled_ms,
|
||||||
unsigned int max_dwells,
|
unsigned int max_dwells,
|
||||||
unsigned int doppler_max, long fs_in,
|
unsigned int doppler_max, int64_t fs_in,
|
||||||
int samples_per_ms, int samples_per_code,
|
int samples_per_ms, int samples_per_code,
|
||||||
bool bit_transition_flag,
|
bool bit_transition_flag,
|
||||||
bool dump,
|
bool dump,
|
||||||
@ -67,7 +67,7 @@ galileo_e5a_noncoherentIQ_acquisition_caf_cc::galileo_e5a_noncoherentIQ_acquisit
|
|||||||
unsigned int sampled_ms,
|
unsigned int sampled_ms,
|
||||||
unsigned int max_dwells,
|
unsigned int max_dwells,
|
||||||
unsigned int doppler_max,
|
unsigned int doppler_max,
|
||||||
long fs_in,
|
int64_t fs_in,
|
||||||
int samples_per_ms,
|
int samples_per_ms,
|
||||||
int samples_per_code,
|
int samples_per_code,
|
||||||
bool bit_transition_flag,
|
bool bit_transition_flag,
|
||||||
@ -80,7 +80,7 @@ galileo_e5a_noncoherentIQ_acquisition_caf_cc::galileo_e5a_noncoherentIQ_acquisit
|
|||||||
gr::io_signature::make(0, 0, sizeof(gr_complex)))
|
gr::io_signature::make(0, 0, sizeof(gr_complex)))
|
||||||
{
|
{
|
||||||
this->message_port_register_out(pmt::mp("events"));
|
this->message_port_register_out(pmt::mp("events"));
|
||||||
d_sample_counter = 0; // SAMPLE COUNTER
|
d_sample_counter = 0ULL; // SAMPLE COUNTER
|
||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
d_fs_in = fs_in;
|
d_fs_in = fs_in;
|
||||||
@ -280,7 +280,8 @@ void galileo_e5a_noncoherentIQ_acquisition_caf_cc::init()
|
|||||||
|
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
const double GALILEO_TWO_PI = 6.283185307179600;
|
const double GALILEO_TWO_PI = 6.283185307179600;
|
||||||
@ -328,7 +329,8 @@ void galileo_e5a_noncoherentIQ_acquisition_caf_cc::set_state(int state)
|
|||||||
{
|
{
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_well_count = 0;
|
d_well_count = 0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
@ -376,14 +378,15 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items
|
|||||||
//restart acquisition variables
|
//restart acquisition variables
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_well_count = 0;
|
d_well_count = 0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_test_statistics = 0.0;
|
d_test_statistics = 0.0;
|
||||||
d_state = 1;
|
d_state = 1;
|
||||||
}
|
}
|
||||||
d_sample_counter += ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -407,7 +410,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items
|
|||||||
d_state = 2;
|
d_state = 2;
|
||||||
}
|
}
|
||||||
d_buffer_count += buff_increment;
|
d_buffer_count += buff_increment;
|
||||||
d_sample_counter += buff_increment; // sample counter
|
d_sample_counter += static_cast<uint64_t>(buff_increment); // sample counter
|
||||||
consume_each(buff_increment);
|
consume_each(buff_increment);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -419,7 +422,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items
|
|||||||
{
|
{
|
||||||
memcpy(&d_inbuffer[d_buffer_count], in, sizeof(gr_complex) * (d_fft_size - d_buffer_count));
|
memcpy(&d_inbuffer[d_buffer_count], in, sizeof(gr_complex) * (d_fft_size - d_buffer_count));
|
||||||
}
|
}
|
||||||
d_sample_counter += (d_fft_size - d_buffer_count); // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size - d_buffer_count); // sample counter
|
||||||
|
|
||||||
// initialize acquisition algorithm
|
// initialize acquisition algorithm
|
||||||
int doppler;
|
int doppler;
|
||||||
@ -633,7 +636,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items
|
|||||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % d_samples_per_code);
|
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % d_samples_per_code);
|
||||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = d_doppler_step;
|
||||||
// 5- Compute the test statistics and compare to the threshold
|
// 5- Compute the test statistics and compare to the threshold
|
||||||
d_test_statistics = d_mag / d_input_power;
|
d_test_statistics = d_mag / d_input_power;
|
||||||
}
|
}
|
||||||
@ -806,7 +809,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items
|
|||||||
|
|
||||||
acquisition_message = 1;
|
acquisition_message = 1;
|
||||||
this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message));
|
this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message));
|
||||||
d_sample_counter += ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -826,7 +829,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items
|
|||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
|
|
||||||
d_sample_counter += ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
acquisition_message = 2;
|
acquisition_message = 2;
|
||||||
this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message));
|
this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message));
|
||||||
|
@ -52,7 +52,7 @@ typedef boost::shared_ptr<galileo_e5a_noncoherentIQ_acquisition_caf_cc> galileo_
|
|||||||
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,
|
galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(unsigned int sampled_ms,
|
||||||
unsigned int max_dwells,
|
unsigned int max_dwells,
|
||||||
unsigned int doppler_max, long fs_in,
|
unsigned int doppler_max, int64_t fs_in,
|
||||||
int samples_per_ms, int samples_per_code,
|
int samples_per_ms, int samples_per_code,
|
||||||
bool bit_transition_flag,
|
bool bit_transition_flag,
|
||||||
bool dump,
|
bool dump,
|
||||||
@ -74,7 +74,7 @@ private:
|
|||||||
galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(
|
galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(
|
||||||
unsigned int sampled_ms,
|
unsigned int sampled_ms,
|
||||||
unsigned int max_dwells,
|
unsigned int max_dwells,
|
||||||
unsigned int doppler_max, long fs_in,
|
unsigned int doppler_max, int64_t fs_in,
|
||||||
int samples_per_ms, int samples_per_code,
|
int samples_per_ms, int samples_per_code,
|
||||||
bool bit_transition_flag,
|
bool bit_transition_flag,
|
||||||
bool dump,
|
bool dump,
|
||||||
@ -86,7 +86,7 @@ private:
|
|||||||
galileo_e5a_noncoherentIQ_acquisition_caf_cc(
|
galileo_e5a_noncoherentIQ_acquisition_caf_cc(
|
||||||
unsigned int sampled_ms,
|
unsigned int sampled_ms,
|
||||||
unsigned int max_dwells,
|
unsigned int max_dwells,
|
||||||
unsigned int doppler_max, long fs_in,
|
unsigned int doppler_max, int64_t fs_in,
|
||||||
int samples_per_ms, int samples_per_code,
|
int samples_per_ms, int samples_per_code,
|
||||||
bool bit_transition_flag,
|
bool bit_transition_flag,
|
||||||
bool dump,
|
bool dump,
|
||||||
@ -99,7 +99,7 @@ private:
|
|||||||
int doppler_offset);
|
int doppler_offset);
|
||||||
float estimate_input_power(gr_complex* in);
|
float estimate_input_power(gr_complex* in);
|
||||||
|
|
||||||
long d_fs_in;
|
int64_t d_fs_in;
|
||||||
int d_samples_per_ms;
|
int d_samples_per_ms;
|
||||||
int d_sampled_ms;
|
int d_sampled_ms;
|
||||||
int d_samples_per_code;
|
int d_samples_per_code;
|
||||||
@ -111,7 +111,7 @@ private:
|
|||||||
unsigned int d_max_dwells;
|
unsigned int d_max_dwells;
|
||||||
unsigned int d_well_count;
|
unsigned int d_well_count;
|
||||||
unsigned int d_fft_size;
|
unsigned int d_fft_size;
|
||||||
unsigned long int d_sample_counter;
|
uint64_t d_sample_counter;
|
||||||
gr_complex** d_grid_doppler_wipeoffs;
|
gr_complex** d_grid_doppler_wipeoffs;
|
||||||
unsigned int d_num_doppler_bins;
|
unsigned int d_num_doppler_bins;
|
||||||
gr_complex* d_fft_code_I_A;
|
gr_complex* d_fft_code_I_A;
|
||||||
|
@ -60,7 +60,7 @@ galileo_pcps_8ms_acquisition_cc::galileo_pcps_8ms_acquisition_cc(
|
|||||||
gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms))
|
gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms))
|
||||||
{
|
{
|
||||||
this->message_port_register_out(pmt::mp("events"));
|
this->message_port_register_out(pmt::mp("events"));
|
||||||
d_sample_counter = 0; // SAMPLE COUNTER
|
d_sample_counter = 0ULL; // SAMPLE COUNTER
|
||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
d_fs_in = fs_in;
|
d_fs_in = fs_in;
|
||||||
@ -151,10 +151,10 @@ void galileo_pcps_8ms_acquisition_cc::init()
|
|||||||
d_gnss_synchro->Flag_valid_symbol_output = false;
|
d_gnss_synchro->Flag_valid_symbol_output = false;
|
||||||
d_gnss_synchro->Flag_valid_pseudorange = false;
|
d_gnss_synchro->Flag_valid_pseudorange = false;
|
||||||
d_gnss_synchro->Flag_valid_word = false;
|
d_gnss_synchro->Flag_valid_word = false;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
const double GALILEO_TWO_PI = 6.283185307179600;
|
const double GALILEO_TWO_PI = 6.283185307179600;
|
||||||
@ -188,7 +188,8 @@ void galileo_pcps_8ms_acquisition_cc::set_state(int state)
|
|||||||
{
|
{
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_well_count = 0;
|
d_well_count = 0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
@ -219,7 +220,8 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items,
|
|||||||
//restart acquisition variables
|
//restart acquisition variables
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_well_count = 0;
|
d_well_count = 0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
@ -228,7 +230,7 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_state = 1;
|
d_state = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -249,7 +251,7 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
|
|
||||||
d_sample_counter += d_fft_size; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size); // sample counter
|
||||||
|
|
||||||
d_well_count++;
|
d_well_count++;
|
||||||
|
|
||||||
@ -328,6 +330,7 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % d_samples_per_code);
|
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % d_samples_per_code);
|
||||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = d_doppler_step;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record results to file if required
|
// Record results to file if required
|
||||||
@ -404,7 +407,7 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
|
|
||||||
d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
|
|
||||||
acquisition_message = 2;
|
acquisition_message = 2;
|
||||||
|
@ -83,7 +83,7 @@ private:
|
|||||||
unsigned int d_max_dwells;
|
unsigned int d_max_dwells;
|
||||||
unsigned int d_well_count;
|
unsigned int d_well_count;
|
||||||
unsigned int d_fft_size;
|
unsigned int d_fft_size;
|
||||||
unsigned long int d_sample_counter;
|
uint64_t d_sample_counter;
|
||||||
gr_complex** d_grid_doppler_wipeoffs;
|
gr_complex** d_grid_doppler_wipeoffs;
|
||||||
unsigned int d_num_doppler_bins;
|
unsigned int d_num_doppler_bins;
|
||||||
gr_complex* d_fft_code_A;
|
gr_complex* d_fft_code_A;
|
||||||
|
@ -52,20 +52,20 @@ pcps_acquisition_sptr pcps_make_acquisition(const Acq_Conf& conf_)
|
|||||||
|
|
||||||
|
|
||||||
pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acquisition",
|
pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acquisition",
|
||||||
gr::io_signature::make(1, 1, conf_.it_size * conf_.sampled_ms * conf_.samples_per_ms * (conf_.bit_transition_flag ? 2 : 1)),
|
gr::io_signature::make(1, 1, conf_.it_size),
|
||||||
gr::io_signature::make(0, 0, conf_.it_size * conf_.sampled_ms * conf_.samples_per_ms * (conf_.bit_transition_flag ? 2 : 1)))
|
gr::io_signature::make(0, 0, conf_.it_size))
|
||||||
{
|
{
|
||||||
this->message_port_register_out(pmt::mp("events"));
|
this->message_port_register_out(pmt::mp("events"));
|
||||||
|
|
||||||
acq_parameters = conf_;
|
acq_parameters = conf_;
|
||||||
d_sample_counter = 0; // SAMPLE COUNTER
|
d_sample_counter = 0ULL; // SAMPLE COUNTER
|
||||||
d_active = false;
|
d_active = false;
|
||||||
d_positive_acq = 0;
|
d_positive_acq = 0;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
d_old_freq = 0;
|
d_old_freq = 0LL;
|
||||||
d_num_noncoherent_integrations_counter = 0;
|
d_num_noncoherent_integrations_counter = 0U;
|
||||||
d_consumed_samples = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1);
|
d_consumed_samples = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1);
|
||||||
if (acq_parameters.sampled_ms == (acq_parameters.samples_per_code / acq_parameters.samples_per_ms)) //
|
if (acq_parameters.sampled_ms == acq_parameters.ms_per_code)
|
||||||
{
|
{
|
||||||
d_fft_size = d_consumed_samples;
|
d_fft_size = d_consumed_samples;
|
||||||
}
|
}
|
||||||
@ -76,12 +76,12 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu
|
|||||||
// d_fft_size = next power of two? ////
|
// d_fft_size = next power of two? ////
|
||||||
d_mag = 0;
|
d_mag = 0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_num_doppler_bins = 0;
|
d_num_doppler_bins = 0U;
|
||||||
d_threshold = 0.0;
|
d_threshold = 0.0;
|
||||||
d_doppler_step = 0;
|
d_doppler_step = 0U;
|
||||||
d_doppler_center_step_two = 0.0;
|
d_doppler_center_step_two = 0.0;
|
||||||
d_test_statistics = 0.0;
|
d_test_statistics = 0.0;
|
||||||
d_channel = 0;
|
d_channel = 0U;
|
||||||
if (conf_.it_size == sizeof(gr_complex))
|
if (conf_.it_size == sizeof(gr_complex))
|
||||||
{
|
{
|
||||||
d_cshort = false;
|
d_cshort = false;
|
||||||
@ -133,10 +133,13 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu
|
|||||||
d_data_buffer_sc = nullptr;
|
d_data_buffer_sc = nullptr;
|
||||||
}
|
}
|
||||||
grid_ = arma::fmat();
|
grid_ = arma::fmat();
|
||||||
|
narrow_grid_ = arma::fmat();
|
||||||
d_step_two = false;
|
d_step_two = false;
|
||||||
d_dump_number = 0;
|
d_num_doppler_bins_step2 = acq_parameters.num_doppler_bins_step2;
|
||||||
|
d_dump_number = 0LL;
|
||||||
d_dump_channel = acq_parameters.dump_channel;
|
d_dump_channel = acq_parameters.dump_channel;
|
||||||
d_samplesPerChip = acq_parameters.samples_per_chip;
|
d_samplesPerChip = acq_parameters.samples_per_chip;
|
||||||
|
d_buffer_count = 0U;
|
||||||
// todo: CFAR statistic not available for non-coherent integration
|
// todo: CFAR statistic not available for non-coherent integration
|
||||||
if (acq_parameters.max_dwells == 1)
|
if (acq_parameters.max_dwells == 1)
|
||||||
{
|
{
|
||||||
@ -153,7 +156,7 @@ pcps_acquisition::~pcps_acquisition()
|
|||||||
{
|
{
|
||||||
if (d_num_doppler_bins > 0)
|
if (d_num_doppler_bins > 0)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
for (uint32_t i = 0; i < d_num_doppler_bins; i++)
|
||||||
{
|
{
|
||||||
volk_gnsssdr_free(d_grid_doppler_wipeoffs[i]);
|
volk_gnsssdr_free(d_grid_doppler_wipeoffs[i]);
|
||||||
volk_gnsssdr_free(d_magnitude_grid[i]);
|
volk_gnsssdr_free(d_magnitude_grid[i]);
|
||||||
@ -163,7 +166,7 @@ pcps_acquisition::~pcps_acquisition()
|
|||||||
}
|
}
|
||||||
if (acq_parameters.make_2_steps)
|
if (acq_parameters.make_2_steps)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < acq_parameters.num_doppler_bins_step2; i++)
|
for (uint32_t i = 0; i < d_num_doppler_bins_step2; i++)
|
||||||
{
|
{
|
||||||
volk_gnsssdr_free(d_grid_doppler_wipeoffs_step_two[i]);
|
volk_gnsssdr_free(d_grid_doppler_wipeoffs_step_two[i]);
|
||||||
}
|
}
|
||||||
@ -186,7 +189,7 @@ pcps_acquisition::~pcps_acquisition()
|
|||||||
void pcps_acquisition::set_local_code(std::complex<float>* code)
|
void pcps_acquisition::set_local_code(std::complex<float>* code)
|
||||||
{
|
{
|
||||||
// reset the intermediate frequency
|
// reset the intermediate frequency
|
||||||
d_old_freq = 0;
|
d_old_freq = 0LL;
|
||||||
// This will check if it's fdma, if yes will update the intermediate frequency and the doppler grid
|
// This will check if it's fdma, if yes will update the intermediate frequency and the doppler grid
|
||||||
if (is_fdma())
|
if (is_fdma())
|
||||||
{
|
{
|
||||||
@ -199,13 +202,13 @@ void pcps_acquisition::set_local_code(std::complex<float>* code)
|
|||||||
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
|
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
|
||||||
if (acq_parameters.bit_transition_flag)
|
if (acq_parameters.bit_transition_flag)
|
||||||
{
|
{
|
||||||
int offset = d_fft_size / 2;
|
int32_t offset = d_fft_size / 2;
|
||||||
std::fill_n(d_fft_if->get_inbuf(), offset, gr_complex(0.0, 0.0));
|
std::fill_n(d_fft_if->get_inbuf(), offset, gr_complex(0.0, 0.0));
|
||||||
memcpy(d_fft_if->get_inbuf() + offset, code, sizeof(gr_complex) * offset);
|
memcpy(d_fft_if->get_inbuf() + offset, code, sizeof(gr_complex) * offset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (acq_parameters.sampled_ms == (acq_parameters.samples_per_code / acq_parameters.samples_per_ms))
|
if (acq_parameters.sampled_ms == acq_parameters.ms_per_code)
|
||||||
{
|
{
|
||||||
memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_consumed_samples);
|
memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_consumed_samples);
|
||||||
}
|
}
|
||||||
@ -243,11 +246,11 @@ bool pcps_acquisition::is_fdma()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcps_acquisition::update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq)
|
void pcps_acquisition::update_local_carrier(gr_complex* carrier_vector, int32_t correlator_length_samples, float freq)
|
||||||
{
|
{
|
||||||
float phase_step_rad = GPS_TWO_PI * freq / static_cast<float>(acq_parameters.fs_in);
|
float phase_step_rad = GPS_TWO_PI * freq / static_cast<float>(acq_parameters.fs_in);
|
||||||
float _phase[1];
|
float _phase[1];
|
||||||
_phase[0] = 0;
|
_phase[0] = 0.0;
|
||||||
volk_gnsssdr_s32f_sincos_32fc(carrier_vector, -phase_step_rad, _phase, correlator_length_samples);
|
volk_gnsssdr_s32f_sincos_32fc(carrier_vector, -phase_step_rad, _phase, correlator_length_samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,49 +261,55 @@ void pcps_acquisition::init()
|
|||||||
d_gnss_synchro->Flag_valid_symbol_output = false;
|
d_gnss_synchro->Flag_valid_symbol_output = false;
|
||||||
d_gnss_synchro->Flag_valid_pseudorange = false;
|
d_gnss_synchro->Flag_valid_pseudorange = false;
|
||||||
d_gnss_synchro->Flag_valid_word = false;
|
d_gnss_synchro->Flag_valid_word = false;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
|
|
||||||
d_num_doppler_bins = static_cast<unsigned int>(std::ceil(static_cast<double>(static_cast<int>(acq_parameters.doppler_max) - static_cast<int>(-acq_parameters.doppler_max)) / static_cast<double>(d_doppler_step)));
|
d_num_doppler_bins = static_cast<uint32_t>(std::ceil(static_cast<double>(static_cast<int32_t>(acq_parameters.doppler_max) - static_cast<int32_t>(-acq_parameters.doppler_max)) / static_cast<double>(d_doppler_step)));
|
||||||
|
|
||||||
// Create the carrier Doppler wipeoff signals
|
// Create the carrier Doppler wipeoff signals
|
||||||
d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
|
d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
|
||||||
if (acq_parameters.make_2_steps)
|
if (acq_parameters.make_2_steps)
|
||||||
{
|
{
|
||||||
d_grid_doppler_wipeoffs_step_two = new gr_complex*[acq_parameters.num_doppler_bins_step2];
|
d_grid_doppler_wipeoffs_step_two = new gr_complex*[d_num_doppler_bins_step2];
|
||||||
for (unsigned int doppler_index = 0; doppler_index < acq_parameters.num_doppler_bins_step2; doppler_index++)
|
for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins_step2; doppler_index++)
|
||||||
{
|
{
|
||||||
d_grid_doppler_wipeoffs_step_two[doppler_index] = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
d_grid_doppler_wipeoffs_step_two[doppler_index] = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d_magnitude_grid = new float*[d_num_doppler_bins];
|
d_magnitude_grid = new float*[d_num_doppler_bins];
|
||||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||||
{
|
{
|
||||||
d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||||
d_magnitude_grid[doppler_index] = static_cast<float*>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
|
d_magnitude_grid[doppler_index] = static_cast<float*>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
|
||||||
int doppler = -static_cast<int>(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
|
for (uint32_t k = 0; k < d_fft_size; k++)
|
||||||
|
{
|
||||||
|
d_magnitude_grid[doppler_index][k] = 0.0;
|
||||||
|
}
|
||||||
|
int32_t doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
|
||||||
update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_old_freq + doppler);
|
update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_old_freq + doppler);
|
||||||
}
|
}
|
||||||
|
|
||||||
d_worker_active = false;
|
d_worker_active = false;
|
||||||
|
|
||||||
if (acq_parameters.dump)
|
if (acq_parameters.dump)
|
||||||
{
|
{
|
||||||
unsigned int effective_fft_size = (acq_parameters.bit_transition_flag ? (d_fft_size / 2) : d_fft_size);
|
uint32_t effective_fft_size = (acq_parameters.bit_transition_flag ? (d_fft_size / 2) : d_fft_size);
|
||||||
grid_ = arma::fmat(effective_fft_size, d_num_doppler_bins, arma::fill::zeros);
|
grid_ = arma::fmat(effective_fft_size, d_num_doppler_bins, arma::fill::zeros);
|
||||||
|
narrow_grid_ = arma::fmat(effective_fft_size, d_num_doppler_bins_step2, arma::fill::zeros);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcps_acquisition::update_grid_doppler_wipeoffs()
|
void pcps_acquisition::update_grid_doppler_wipeoffs()
|
||||||
{
|
{
|
||||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||||
{
|
{
|
||||||
int doppler = -static_cast<int>(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
|
int32_t doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
|
||||||
update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_old_freq + doppler);
|
update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_old_freq + doppler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,15 +317,15 @@ void pcps_acquisition::update_grid_doppler_wipeoffs()
|
|||||||
|
|
||||||
void pcps_acquisition::update_grid_doppler_wipeoffs_step2()
|
void pcps_acquisition::update_grid_doppler_wipeoffs_step2()
|
||||||
{
|
{
|
||||||
for (unsigned int doppler_index = 0; doppler_index < acq_parameters.num_doppler_bins_step2; doppler_index++)
|
for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins_step2; doppler_index++)
|
||||||
{
|
{
|
||||||
float doppler = (static_cast<float>(doppler_index) - static_cast<float>(acq_parameters.num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2;
|
float doppler = (static_cast<float>(doppler_index) - static_cast<float>(floor(d_num_doppler_bins_step2 / 2.0))) * acq_parameters.doppler_step2;
|
||||||
update_local_carrier(d_grid_doppler_wipeoffs_step_two[doppler_index], d_fft_size, d_doppler_center_step_two + doppler);
|
update_local_carrier(d_grid_doppler_wipeoffs_step_two[doppler_index], d_fft_size, d_doppler_center_step_two + doppler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcps_acquisition::set_state(int state)
|
void pcps_acquisition::set_state(int32_t state)
|
||||||
{
|
{
|
||||||
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
|
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
|
||||||
d_state = state;
|
d_state = state;
|
||||||
@ -324,7 +333,8 @@ void pcps_acquisition::set_state(int state)
|
|||||||
{
|
{
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_test_statistics = 0.0;
|
d_test_statistics = 0.0;
|
||||||
@ -342,7 +352,7 @@ void pcps_acquisition::set_state(int state)
|
|||||||
|
|
||||||
void pcps_acquisition::send_positive_acquisition()
|
void pcps_acquisition::send_positive_acquisition()
|
||||||
{
|
{
|
||||||
// 6.1- Declare positive acquisition using a message port
|
// Declare positive acquisition using a message port
|
||||||
// 0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
// 0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
||||||
DLOG(INFO) << "positive acquisition"
|
DLOG(INFO) << "positive acquisition"
|
||||||
<< ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
|
<< ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
|
||||||
@ -360,7 +370,7 @@ void pcps_acquisition::send_positive_acquisition()
|
|||||||
|
|
||||||
void pcps_acquisition::send_negative_acquisition()
|
void pcps_acquisition::send_negative_acquisition()
|
||||||
{
|
{
|
||||||
// 6.2- Declare negative acquisition using a message port
|
// Declare negative acquisition using a message port
|
||||||
// 0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
// 0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
||||||
DLOG(INFO) << "negative acquisition"
|
DLOG(INFO) << "negative acquisition"
|
||||||
<< ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
|
<< ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
|
||||||
@ -376,7 +386,7 @@ void pcps_acquisition::send_negative_acquisition()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcps_acquisition::dump_results(int effective_fft_size)
|
void pcps_acquisition::dump_results(int32_t effective_fft_size)
|
||||||
{
|
{
|
||||||
d_dump_number++;
|
d_dump_number++;
|
||||||
std::string filename = acq_parameters.dump_filename;
|
std::string filename = acq_parameters.dump_filename;
|
||||||
@ -450,21 +460,45 @@ void pcps_acquisition::dump_results(int effective_fft_size)
|
|||||||
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
Mat_VarFree(matvar);
|
Mat_VarFree(matvar);
|
||||||
|
|
||||||
|
matvar = Mat_VarCreate("num_dwells", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_num_noncoherent_integrations_counter, 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
|
||||||
|
if (acq_parameters.make_2_steps)
|
||||||
|
{
|
||||||
|
dims[0] = static_cast<size_t>(effective_fft_size);
|
||||||
|
dims[1] = static_cast<size_t>(d_num_doppler_bins_step2);
|
||||||
|
matvar = Mat_VarCreate("acq_grid_narrow", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, narrow_grid_.memptr(), 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
|
||||||
|
dims[0] = static_cast<size_t>(1);
|
||||||
|
dims[1] = static_cast<size_t>(1);
|
||||||
|
matvar = Mat_VarCreate("doppler_step_narrow", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &acq_parameters.doppler_step2, 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
|
||||||
|
aux = d_doppler_center_step_two - static_cast<float>(floor(d_num_doppler_bins_step2 / 2.0)) * acq_parameters.doppler_step2;
|
||||||
|
matvar = Mat_VarCreate("doppler_grid_narrow_min", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &aux, 0);
|
||||||
|
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
|
||||||
|
Mat_VarFree(matvar);
|
||||||
|
}
|
||||||
|
|
||||||
Mat_Close(matfp);
|
Mat_Close(matfp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int& doppler, float input_power)
|
float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int32_t& doppler, float input_power, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step)
|
||||||
{
|
{
|
||||||
float grid_maximum = 0.0;
|
float grid_maximum = 0.0;
|
||||||
unsigned int index_doppler = 0;
|
uint32_t index_doppler = 0U;
|
||||||
uint32_t tmp_intex_t = 0;
|
uint32_t tmp_intex_t = 0U;
|
||||||
uint32_t index_time = 0;
|
uint32_t index_time = 0U;
|
||||||
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
|
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
|
||||||
|
|
||||||
// Find the correlation peak and the carrier frequency
|
// Find the correlation peak and the carrier frequency
|
||||||
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
for (uint32_t i = 0; i < num_doppler_bins; i++)
|
||||||
{
|
{
|
||||||
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size);
|
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size);
|
||||||
if (d_magnitude_grid[i][tmp_intex_t] > grid_maximum)
|
if (d_magnitude_grid[i][tmp_intex_t] > grid_maximum)
|
||||||
@ -475,26 +509,33 @@ float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int& dopp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
indext = index_time;
|
indext = index_time;
|
||||||
doppler = -static_cast<int>(acq_parameters.doppler_max) + d_doppler_step * static_cast<int>(index_doppler);
|
if (!d_step_two)
|
||||||
|
{
|
||||||
|
doppler = -static_cast<int32_t>(doppler_max) + doppler_step * static_cast<int32_t>(index_doppler);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
doppler = static_cast<int32_t>(d_doppler_center_step_two + (static_cast<float>(index_doppler) - static_cast<float>(floor(d_num_doppler_bins_step2 / 2.0))) * acq_parameters.doppler_step2);
|
||||||
|
}
|
||||||
|
|
||||||
float magt = grid_maximum / (fft_normalization_factor * fft_normalization_factor);
|
float magt = grid_maximum / (fft_normalization_factor * fft_normalization_factor);
|
||||||
return magt / input_power;
|
return magt / input_power;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int& doppler)
|
float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step)
|
||||||
{
|
{
|
||||||
// Look for correlation peaks in the results
|
// Look for correlation peaks in the results
|
||||||
// Find the highest peak and compare it to the second highest peak
|
// Find the highest peak and compare it to the second highest peak
|
||||||
// The second peak is chosen not closer than 1 chip to the highest peak
|
// The second peak is chosen not closer than 1 chip to the highest peak
|
||||||
|
|
||||||
float firstPeak = 0.0;
|
float firstPeak = 0.0;
|
||||||
unsigned int index_doppler = 0;
|
uint32_t index_doppler = 0U;
|
||||||
uint32_t tmp_intex_t = 0;
|
uint32_t tmp_intex_t = 0U;
|
||||||
uint32_t index_time = 0;
|
uint32_t index_time = 0U;
|
||||||
|
|
||||||
// Find the correlation peak and the carrier frequency
|
// Find the correlation peak and the carrier frequency
|
||||||
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
for (uint32_t i = 0; i < num_doppler_bins; i++)
|
||||||
{
|
{
|
||||||
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size);
|
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size);
|
||||||
if (d_magnitude_grid[i][tmp_intex_t] > firstPeak)
|
if (d_magnitude_grid[i][tmp_intex_t] > firstPeak)
|
||||||
@ -505,7 +546,15 @@ float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int& do
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
indext = index_time;
|
indext = index_time;
|
||||||
doppler = -static_cast<int>(acq_parameters.doppler_max) + d_doppler_step * static_cast<int>(index_doppler);
|
|
||||||
|
if (!d_step_two)
|
||||||
|
{
|
||||||
|
doppler = -static_cast<int32_t>(doppler_max) + doppler_step * static_cast<int32_t>(index_doppler);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
doppler = static_cast<int32_t>(d_doppler_center_step_two + (static_cast<float>(index_doppler) - static_cast<float>(floor(d_num_doppler_bins_step2 / 2.0))) * acq_parameters.doppler_step2);
|
||||||
|
}
|
||||||
|
|
||||||
// Find 1 chip wide code phase exclude range around the peak
|
// Find 1 chip wide code phase exclude range around the peak
|
||||||
int32_t excludeRangeIndex1 = index_time - d_samplesPerChip;
|
int32_t excludeRangeIndex1 = index_time - d_samplesPerChip;
|
||||||
@ -516,7 +565,7 @@ float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int& do
|
|||||||
{
|
{
|
||||||
excludeRangeIndex1 = d_fft_size + excludeRangeIndex1;
|
excludeRangeIndex1 = d_fft_size + excludeRangeIndex1;
|
||||||
}
|
}
|
||||||
else if (excludeRangeIndex2 >= static_cast<int>(d_fft_size))
|
else if (excludeRangeIndex2 >= static_cast<int32_t>(d_fft_size))
|
||||||
{
|
{
|
||||||
excludeRangeIndex2 = excludeRangeIndex2 - d_fft_size;
|
excludeRangeIndex2 = excludeRangeIndex2 - d_fft_size;
|
||||||
}
|
}
|
||||||
@ -527,7 +576,7 @@ float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int& do
|
|||||||
{
|
{
|
||||||
d_tmp_buffer[idx] = 0.0;
|
d_tmp_buffer[idx] = 0.0;
|
||||||
idx++;
|
idx++;
|
||||||
if (idx == static_cast<int>(d_fft_size)) idx = 0;
|
if (idx == static_cast<int32_t>(d_fft_size)) idx = 0;
|
||||||
}
|
}
|
||||||
while (idx != excludeRangeIndex2);
|
while (idx != excludeRangeIndex2);
|
||||||
|
|
||||||
@ -540,15 +589,14 @@ float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int& do
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcps_acquisition::acquisition_core(unsigned long int samp_count)
|
void pcps_acquisition::acquisition_core(uint64_t samp_count)
|
||||||
{
|
{
|
||||||
gr::thread::scoped_lock lk(d_setlock);
|
gr::thread::scoped_lock lk(d_setlock);
|
||||||
|
|
||||||
// initialize acquisition algorithm
|
// Initialize acquisition algorithm
|
||||||
float magt = 0.0;
|
int32_t doppler = 0;
|
||||||
int doppler = 0;
|
uint32_t indext = 0U;
|
||||||
uint32_t indext = 0;
|
int32_t effective_fft_size = (acq_parameters.bit_transition_flag ? d_fft_size / 2 : d_fft_size);
|
||||||
int effective_fft_size = (acq_parameters.bit_transition_flag ? d_fft_size / 2 : d_fft_size);
|
|
||||||
if (d_cshort)
|
if (d_cshort)
|
||||||
{
|
{
|
||||||
volk_gnsssdr_16ic_convert_32fc(d_data_buffer, d_data_buffer_sc, d_consumed_samples);
|
volk_gnsssdr_16ic_convert_32fc(d_data_buffer, d_data_buffer_sc, d_consumed_samples);
|
||||||
@ -556,13 +604,12 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
|
|||||||
memcpy(d_input_signal, d_data_buffer, d_consumed_samples * sizeof(gr_complex));
|
memcpy(d_input_signal, d_data_buffer, d_consumed_samples * sizeof(gr_complex));
|
||||||
if (d_fft_size > d_consumed_samples)
|
if (d_fft_size > d_consumed_samples)
|
||||||
{
|
{
|
||||||
for (unsigned int i = d_consumed_samples; i < d_fft_size; i++)
|
for (uint32_t i = d_consumed_samples; i < d_fft_size; i++)
|
||||||
{
|
{
|
||||||
d_input_signal[i] = gr_complex(0.0, 0.0);
|
d_input_signal[i] = gr_complex(0.0, 0.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const gr_complex* in = d_input_signal; // Get the input samples pointer
|
const gr_complex* in = d_input_signal; // Get the input samples pointer
|
||||||
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
|
|
||||||
|
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
@ -588,7 +635,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
|
|||||||
// Doppler frequency grid loop
|
// Doppler frequency grid loop
|
||||||
if (!d_step_two)
|
if (!d_step_two)
|
||||||
{
|
{
|
||||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||||
{
|
{
|
||||||
// Remove Doppler
|
// Remove Doppler
|
||||||
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index], d_fft_size);
|
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index], d_fft_size);
|
||||||
@ -624,26 +671,23 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
|
|||||||
// Compute the test statistic
|
// Compute the test statistic
|
||||||
if (d_use_CFAR_algorithm_flag)
|
if (d_use_CFAR_algorithm_flag)
|
||||||
{
|
{
|
||||||
d_test_statistics = max_to_input_power_statistic(indext, doppler, d_input_power);
|
d_test_statistics = max_to_input_power_statistic(indext, doppler, d_input_power, d_num_doppler_bins, acq_parameters.doppler_max, d_doppler_step);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_test_statistics = first_vs_second_peak_statistic(indext, doppler);
|
d_test_statistics = first_vs_second_peak_statistic(indext, doppler, d_num_doppler_bins, acq_parameters.doppler_max, d_doppler_step);
|
||||||
}
|
}
|
||||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code);
|
d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code));
|
||||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
|
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (unsigned int doppler_index = 0; doppler_index < acq_parameters.num_doppler_bins_step2; doppler_index++)
|
for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins_step2; doppler_index++)
|
||||||
{
|
{
|
||||||
// doppler search steps
|
|
||||||
float doppler = d_doppler_center_step_two + (static_cast<float>(doppler_index) - static_cast<float>(acq_parameters.num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2;
|
|
||||||
|
|
||||||
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs_step_two[doppler_index], d_fft_size);
|
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs_step_two[doppler_index], d_fft_size);
|
||||||
|
|
||||||
// 3- Perform the FFT-based convolution (parallel time search)
|
// Perform the FFT-based convolution (parallel time search)
|
||||||
// Compute the FFT of the carrier wiped--off incoming signal
|
// Compute the FFT of the carrier wiped--off incoming signal
|
||||||
d_fft_if->execute();
|
d_fft_if->execute();
|
||||||
|
|
||||||
@ -654,54 +698,35 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
|
|||||||
// compute the inverse FFT
|
// compute the inverse FFT
|
||||||
d_ifft->execute();
|
d_ifft->execute();
|
||||||
|
|
||||||
// Search maximum
|
|
||||||
size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0);
|
size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0);
|
||||||
volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf() + offset, effective_fft_size);
|
if (d_num_noncoherent_integrations_counter == 1)
|
||||||
volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude, effective_fft_size);
|
|
||||||
magt = d_magnitude[indext];
|
|
||||||
|
|
||||||
if (d_use_CFAR_algorithm_flag)
|
|
||||||
{
|
{
|
||||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
volk_32fc_magnitude_squared_32f(d_magnitude_grid[doppler_index], d_ifft->get_outbuf() + offset, effective_fft_size);
|
||||||
magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor);
|
|
||||||
}
|
}
|
||||||
// 4- record the maximum peak and the associated synchronization parameters
|
else
|
||||||
if (d_mag < magt)
|
|
||||||
{
|
{
|
||||||
d_mag = magt;
|
volk_32fc_magnitude_squared_32f(d_tmp_buffer, d_ifft->get_outbuf() + offset, effective_fft_size);
|
||||||
|
volk_32f_x2_add_32f(d_magnitude_grid[doppler_index], d_magnitude_grid[doppler_index], d_tmp_buffer, effective_fft_size);
|
||||||
if (!d_use_CFAR_algorithm_flag)
|
|
||||||
{
|
|
||||||
// Search grid noise floor approximation for this doppler line
|
|
||||||
volk_32f_accumulator_s32f(&d_input_power, d_magnitude, effective_fft_size);
|
|
||||||
d_input_power = (d_input_power - d_mag) / (effective_fft_size - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// In case that acq_parameters.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) or !acq_parameters.bit_transition_flag)
|
|
||||||
{
|
|
||||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code);
|
|
||||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Record results to file if required
|
// Record results to file if required
|
||||||
if (acq_parameters.dump and d_channel == d_dump_channel)
|
if (acq_parameters.dump and d_channel == d_dump_channel)
|
||||||
{
|
{
|
||||||
memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size);
|
memcpy(narrow_grid_.colptr(doppler_index), d_magnitude_grid[doppler_index], sizeof(float) * effective_fft_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Compute the test statistic
|
||||||
|
if (d_use_CFAR_algorithm_flag)
|
||||||
|
{
|
||||||
|
d_test_statistics = max_to_input_power_statistic(indext, doppler, d_input_power, d_num_doppler_bins_step2, static_cast<int32_t>(d_doppler_center_step_two - (static_cast<float>(d_num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2), acq_parameters.doppler_step2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d_test_statistics = first_vs_second_peak_statistic(indext, doppler, d_num_doppler_bins_step2, static_cast<int32_t>(d_doppler_center_step_two - (static_cast<float>(d_num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2), acq_parameters.doppler_step2);
|
||||||
|
}
|
||||||
|
d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code));
|
||||||
|
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
||||||
|
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = acq_parameters.doppler_step2;
|
||||||
}
|
}
|
||||||
|
|
||||||
lk.lock();
|
lk.lock();
|
||||||
@ -721,6 +746,8 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_step_two = true; // Clear input buffer and make small grid acquisition
|
d_step_two = true; // Clear input buffer and make small grid acquisition
|
||||||
|
d_num_noncoherent_integrations_counter = 0;
|
||||||
|
d_positive_acq = 0;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -730,6 +757,11 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
|
|||||||
d_state = 0; // Positive acquisition
|
d_state = 0; // Positive acquisition
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d_buffer_count = 0;
|
||||||
|
d_state = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (d_num_noncoherent_integrations_counter == acq_parameters.max_dwells)
|
if (d_num_noncoherent_integrations_counter == acq_parameters.max_dwells)
|
||||||
{
|
{
|
||||||
@ -755,6 +787,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_step_two = true; // Clear input buffer and make small grid acquisition
|
d_step_two = true; // Clear input buffer and make small grid acquisition
|
||||||
|
d_num_noncoherent_integrations_counter = 0U;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -780,8 +813,16 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
|
|||||||
{
|
{
|
||||||
pcps_acquisition::dump_results(effective_fft_size);
|
pcps_acquisition::dump_results(effective_fft_size);
|
||||||
}
|
}
|
||||||
d_num_noncoherent_integrations_counter = 0;
|
d_num_noncoherent_integrations_counter = 0U;
|
||||||
d_positive_acq = 0;
|
d_positive_acq = 0;
|
||||||
|
// Reset grid
|
||||||
|
for (uint32_t i = 0; i < d_num_doppler_bins; i++)
|
||||||
|
{
|
||||||
|
for (uint32_t k = 0; k < d_fft_size; k++)
|
||||||
|
{
|
||||||
|
d_magnitude_grid[i][k] = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -800,13 +841,12 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
|
|||||||
* 5. Compute the test statistics and compare to the threshold
|
* 5. Compute the test statistics and compare to the threshold
|
||||||
* 6. Declare positive or negative acquisition using a message port
|
* 6. Declare positive or negative acquisition using a message port
|
||||||
*/
|
*/
|
||||||
|
|
||||||
gr::thread::scoped_lock lk(d_setlock);
|
gr::thread::scoped_lock lk(d_setlock);
|
||||||
if (!d_active or d_worker_active)
|
if (!d_active or d_worker_active)
|
||||||
{
|
{
|
||||||
if (!acq_parameters.blocking_on_standby)
|
if (!acq_parameters.blocking_on_standby)
|
||||||
{
|
{
|
||||||
d_sample_counter += d_consumed_samples * ninput_items[0];
|
d_sample_counter += static_cast<uint64_t>(ninput_items[0]);
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
}
|
}
|
||||||
if (d_step_two)
|
if (d_step_two)
|
||||||
@ -823,33 +863,66 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
|
|||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
//restart acquisition variables
|
// Restart acquisition variables
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_test_statistics = 0.0;
|
d_test_statistics = 0.0;
|
||||||
d_state = 1;
|
d_state = 1;
|
||||||
|
d_buffer_count = 0U;
|
||||||
if (!acq_parameters.blocking_on_standby)
|
if (!acq_parameters.blocking_on_standby)
|
||||||
{
|
{
|
||||||
d_sample_counter += d_consumed_samples * ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
// Copy the data to the core and let it know that new data is available
|
uint32_t buff_increment;
|
||||||
if (d_cshort)
|
if (d_cshort)
|
||||||
{
|
{
|
||||||
memcpy(d_data_buffer_sc, input_items[0], d_consumed_samples * sizeof(lv_16sc_t));
|
const lv_16sc_t* in = reinterpret_cast<const lv_16sc_t*>(input_items[0]); // Get the input samples pointer
|
||||||
|
if ((ninput_items[0] + d_buffer_count) <= d_consumed_samples)
|
||||||
|
{
|
||||||
|
buff_increment = ninput_items[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(d_data_buffer, input_items[0], d_consumed_samples * sizeof(gr_complex));
|
buff_increment = d_consumed_samples - d_buffer_count;
|
||||||
}
|
}
|
||||||
|
memcpy(&d_data_buffer_sc[d_buffer_count], in, sizeof(lv_16sc_t) * buff_increment);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const gr_complex* in = reinterpret_cast<const gr_complex*>(input_items[0]); // Get the input samples pointer
|
||||||
|
if ((ninput_items[0] + d_buffer_count) <= d_consumed_samples)
|
||||||
|
{
|
||||||
|
buff_increment = ninput_items[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buff_increment = d_consumed_samples - d_buffer_count;
|
||||||
|
}
|
||||||
|
memcpy(&d_data_buffer[d_buffer_count], in, sizeof(gr_complex) * buff_increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If buffer will be full in next iteration
|
||||||
|
if (d_buffer_count >= d_consumed_samples)
|
||||||
|
{
|
||||||
|
d_state = 2;
|
||||||
|
}
|
||||||
|
d_buffer_count += buff_increment;
|
||||||
|
d_sample_counter += static_cast<uint64_t>(buff_increment);
|
||||||
|
consume_each(buff_increment);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
// Copy the data to the core and let it know that new data is available
|
||||||
if (acq_parameters.blocking)
|
if (acq_parameters.blocking)
|
||||||
{
|
{
|
||||||
lk.unlock();
|
lk.unlock();
|
||||||
@ -860,8 +933,8 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)),
|
|||||||
gr::thread::thread d_worker(&pcps_acquisition::acquisition_core, this, d_sample_counter);
|
gr::thread::thread d_worker(&pcps_acquisition::acquisition_core, this, d_sample_counter);
|
||||||
d_worker_active = true;
|
d_worker_active = true;
|
||||||
}
|
}
|
||||||
d_sample_counter += d_consumed_samples;
|
consume_each(0);
|
||||||
consume_each(1);
|
d_buffer_count = 0U;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,21 +82,21 @@ private:
|
|||||||
|
|
||||||
pcps_acquisition(const Acq_Conf& conf_);
|
pcps_acquisition(const Acq_Conf& conf_);
|
||||||
|
|
||||||
void update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq);
|
void update_local_carrier(gr_complex* carrier_vector, int32_t correlator_length_samples, float freq);
|
||||||
void update_grid_doppler_wipeoffs();
|
void update_grid_doppler_wipeoffs();
|
||||||
void update_grid_doppler_wipeoffs_step2();
|
void update_grid_doppler_wipeoffs_step2();
|
||||||
bool is_fdma();
|
bool is_fdma();
|
||||||
|
|
||||||
void acquisition_core(unsigned long int samp_count);
|
void acquisition_core(uint64_t samp_count);
|
||||||
|
|
||||||
void send_negative_acquisition();
|
void send_negative_acquisition();
|
||||||
|
|
||||||
void send_positive_acquisition();
|
void send_positive_acquisition();
|
||||||
|
|
||||||
void dump_results(int effective_fft_size);
|
void dump_results(int32_t effective_fft_size);
|
||||||
|
|
||||||
float first_vs_second_peak_statistic(uint32_t& indext, int& doppler);
|
float first_vs_second_peak_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
|
||||||
float max_to_input_power_statistic(uint32_t& indext, int& doppler, float input_power);
|
float max_to_input_power_statistic(uint32_t& indext, int32_t& doppler, float input_power, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
|
||||||
|
|
||||||
Acq_Conf acq_parameters;
|
Acq_Conf acq_parameters;
|
||||||
bool d_active;
|
bool d_active;
|
||||||
@ -104,7 +104,7 @@ private:
|
|||||||
bool d_cshort;
|
bool d_cshort;
|
||||||
bool d_step_two;
|
bool d_step_two;
|
||||||
bool d_use_CFAR_algorithm_flag;
|
bool d_use_CFAR_algorithm_flag;
|
||||||
int d_positive_acq;
|
int32_t d_positive_acq;
|
||||||
float d_threshold;
|
float d_threshold;
|
||||||
float d_mag;
|
float d_mag;
|
||||||
float d_input_power;
|
float d_input_power;
|
||||||
@ -114,16 +114,16 @@ private:
|
|||||||
float* d_tmp_buffer;
|
float* d_tmp_buffer;
|
||||||
gr_complex* d_input_signal;
|
gr_complex* d_input_signal;
|
||||||
uint32_t d_samplesPerChip;
|
uint32_t d_samplesPerChip;
|
||||||
long d_old_freq;
|
int64_t d_old_freq;
|
||||||
int d_state;
|
int32_t d_state;
|
||||||
unsigned int d_channel;
|
uint32_t d_channel;
|
||||||
unsigned int d_doppler_step;
|
uint32_t d_doppler_step;
|
||||||
float d_doppler_center_step_two;
|
float d_doppler_center_step_two;
|
||||||
unsigned int d_num_noncoherent_integrations_counter;
|
uint32_t d_num_noncoherent_integrations_counter;
|
||||||
unsigned int d_fft_size;
|
uint32_t d_fft_size;
|
||||||
unsigned int d_consumed_samples;
|
uint32_t d_consumed_samples;
|
||||||
unsigned int d_num_doppler_bins;
|
uint32_t d_num_doppler_bins;
|
||||||
unsigned long int d_sample_counter;
|
uint64_t d_sample_counter;
|
||||||
gr_complex** d_grid_doppler_wipeoffs;
|
gr_complex** d_grid_doppler_wipeoffs;
|
||||||
gr_complex** d_grid_doppler_wipeoffs_step_two;
|
gr_complex** d_grid_doppler_wipeoffs_step_two;
|
||||||
gr_complex* d_fft_codes;
|
gr_complex* d_fft_codes;
|
||||||
@ -133,8 +133,11 @@ private:
|
|||||||
gr::fft::fft_complex* d_ifft;
|
gr::fft::fft_complex* d_ifft;
|
||||||
Gnss_Synchro* d_gnss_synchro;
|
Gnss_Synchro* d_gnss_synchro;
|
||||||
arma::fmat grid_;
|
arma::fmat grid_;
|
||||||
long int d_dump_number;
|
arma::fmat narrow_grid_;
|
||||||
unsigned int d_dump_channel;
|
uint32_t d_num_doppler_bins_step2;
|
||||||
|
int64_t d_dump_number;
|
||||||
|
uint32_t d_dump_channel;
|
||||||
|
uint32_t d_buffer_count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~pcps_acquisition();
|
~pcps_acquisition();
|
||||||
@ -153,7 +156,7 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief Returns the maximum peak of grid search.
|
* \brief Returns the maximum peak of grid search.
|
||||||
*/
|
*/
|
||||||
inline unsigned int mag() const
|
inline uint32_t mag() const
|
||||||
{
|
{
|
||||||
return d_mag;
|
return d_mag;
|
||||||
}
|
}
|
||||||
@ -185,13 +188,13 @@ public:
|
|||||||
* first available sample.
|
* first available sample.
|
||||||
* \param state - int=1 forces start of acquisition
|
* \param state - int=1 forces start of acquisition
|
||||||
*/
|
*/
|
||||||
void set_state(int state);
|
void set_state(int32_t state);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Set acquisition channel unique ID
|
* \brief Set acquisition channel unique ID
|
||||||
* \param channel - receiver channel.
|
* \param channel - receiver channel.
|
||||||
*/
|
*/
|
||||||
inline void set_channel(unsigned int channel)
|
inline void set_channel(uint32_t channel)
|
||||||
{
|
{
|
||||||
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
|
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
|
||||||
d_channel = channel;
|
d_channel = channel;
|
||||||
@ -212,7 +215,7 @@ public:
|
|||||||
* \brief Set maximum Doppler grid search
|
* \brief Set maximum Doppler grid search
|
||||||
* \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
|
* \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
|
||||||
*/
|
*/
|
||||||
inline void set_doppler_max(unsigned int doppler_max)
|
inline void set_doppler_max(uint32_t doppler_max)
|
||||||
{
|
{
|
||||||
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
|
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
|
||||||
acq_parameters.doppler_max = doppler_max;
|
acq_parameters.doppler_max = doppler_max;
|
||||||
@ -222,7 +225,7 @@ public:
|
|||||||
* \brief Set Doppler steps for the grid search
|
* \brief Set Doppler steps for the grid search
|
||||||
* \param doppler_step - Frequency bin of the search grid [Hz].
|
* \param doppler_step - Frequency bin of the search grid [Hz].
|
||||||
*/
|
*/
|
||||||
inline void set_doppler_step(unsigned int doppler_step)
|
inline void set_doppler_step(uint32_t doppler_step)
|
||||||
{
|
{
|
||||||
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
|
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
|
||||||
d_doppler_step = doppler_step;
|
d_doppler_step = doppler_step;
|
||||||
|
@ -59,7 +59,7 @@ pcps_acquisition_fine_doppler_cc::pcps_acquisition_fine_doppler_cc(const Acq_Con
|
|||||||
{
|
{
|
||||||
this->message_port_register_out(pmt::mp("events"));
|
this->message_port_register_out(pmt::mp("events"));
|
||||||
acq_parameters = conf_;
|
acq_parameters = conf_;
|
||||||
d_sample_counter = 0; // SAMPLE COUNTER
|
d_sample_counter = 0ULL; // SAMPLE COUNTER
|
||||||
d_active = false;
|
d_active = false;
|
||||||
d_fs_in = conf_.fs_in;
|
d_fs_in = conf_.fs_in;
|
||||||
d_samples_per_ms = conf_.samples_per_ms;
|
d_samples_per_ms = conf_.samples_per_ms;
|
||||||
@ -180,10 +180,10 @@ void pcps_acquisition_fine_doppler_cc::init()
|
|||||||
d_gnss_synchro->Flag_valid_symbol_output = false;
|
d_gnss_synchro->Flag_valid_symbol_output = false;
|
||||||
d_gnss_synchro->Flag_valid_pseudorange = false;
|
d_gnss_synchro->Flag_valid_pseudorange = false;
|
||||||
d_gnss_synchro->Flag_valid_word = false;
|
d_gnss_synchro->Flag_valid_word = false;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,6 +295,7 @@ double pcps_acquisition_fine_doppler_cc::compute_CAF()
|
|||||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(index_time);
|
d_gnss_synchro->Acq_delay_samples = static_cast<double>(index_time);
|
||||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(index_doppler * d_doppler_step - d_config_doppler_max);
|
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(index_doppler * d_doppler_step - d_config_doppler_max);
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = d_doppler_step;
|
||||||
|
|
||||||
return d_test_statistics;
|
return d_test_statistics;
|
||||||
}
|
}
|
||||||
@ -447,7 +448,7 @@ int pcps_acquisition_fine_doppler_cc::estimate_Doppler()
|
|||||||
// Called by gnuradio to enable drivers, etc for i/o devices.
|
// Called by gnuradio to enable drivers, etc for i/o devices.
|
||||||
bool pcps_acquisition_fine_doppler_cc::start()
|
bool pcps_acquisition_fine_doppler_cc::start()
|
||||||
{
|
{
|
||||||
d_sample_counter = 0;
|
d_sample_counter = 0ULL;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,7 +462,8 @@ void pcps_acquisition_fine_doppler_cc::set_state(int state)
|
|||||||
{
|
{
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_well_count = 0;
|
d_well_count = 0;
|
||||||
d_test_statistics = 0.0;
|
d_test_statistics = 0.0;
|
||||||
d_active = true;
|
d_active = true;
|
||||||
@ -507,7 +509,7 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
|||||||
}
|
}
|
||||||
if (!acq_parameters.blocking_on_standby)
|
if (!acq_parameters.blocking_on_standby)
|
||||||
{
|
{
|
||||||
d_sample_counter += d_fft_size; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size); // sample counter
|
||||||
consume_each(d_fft_size);
|
consume_each(d_fft_size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -520,7 +522,7 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
|||||||
{
|
{
|
||||||
d_state = 2;
|
d_state = 2;
|
||||||
}
|
}
|
||||||
d_sample_counter += d_fft_size; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size); // sample counter
|
||||||
consume_each(d_fft_size);
|
consume_each(d_fft_size);
|
||||||
break;
|
break;
|
||||||
case 2: // Compute test statistics and decide
|
case 2: // Compute test statistics and decide
|
||||||
@ -543,7 +545,7 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
|||||||
{
|
{
|
||||||
memcpy(&d_10_ms_buffer[d_n_samples_in_buffer], reinterpret_cast<const gr_complex *>(input_items[0]), noutput_items * sizeof(gr_complex));
|
memcpy(&d_10_ms_buffer[d_n_samples_in_buffer], reinterpret_cast<const gr_complex *>(input_items[0]), noutput_items * sizeof(gr_complex));
|
||||||
d_n_samples_in_buffer += noutput_items;
|
d_n_samples_in_buffer += noutput_items;
|
||||||
d_sample_counter += noutput_items; // sample counter
|
d_sample_counter += static_cast<uint64_t>(noutput_items); // sample counter
|
||||||
consume_each(noutput_items);
|
consume_each(noutput_items);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -551,7 +553,7 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
|||||||
if (samples_remaining > 0)
|
if (samples_remaining > 0)
|
||||||
{
|
{
|
||||||
memcpy(&d_10_ms_buffer[d_n_samples_in_buffer], reinterpret_cast<const gr_complex *>(input_items[0]), samples_remaining * sizeof(gr_complex));
|
memcpy(&d_10_ms_buffer[d_n_samples_in_buffer], reinterpret_cast<const gr_complex *>(input_items[0]), samples_remaining * sizeof(gr_complex));
|
||||||
d_sample_counter += samples_remaining; // sample counter
|
d_sample_counter += static_cast<uint64_t>(samples_remaining); // sample counter
|
||||||
consume_each(samples_remaining);
|
consume_each(samples_remaining);
|
||||||
}
|
}
|
||||||
estimate_Doppler(); //disabled in repo
|
estimate_Doppler(); //disabled in repo
|
||||||
@ -579,7 +581,7 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
|||||||
d_state = 0;
|
d_state = 0;
|
||||||
if (!acq_parameters.blocking_on_standby)
|
if (!acq_parameters.blocking_on_standby)
|
||||||
{
|
{
|
||||||
d_sample_counter += noutput_items; // sample counter
|
d_sample_counter += static_cast<uint64_t>(noutput_items); // sample counter
|
||||||
consume_each(noutput_items);
|
consume_each(noutput_items);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -603,7 +605,7 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
|||||||
d_state = 0;
|
d_state = 0;
|
||||||
if (!acq_parameters.blocking_on_standby)
|
if (!acq_parameters.blocking_on_standby)
|
||||||
{
|
{
|
||||||
d_sample_counter += noutput_items; // sample counter
|
d_sample_counter += static_cast<uint64_t>(noutput_items); // sample counter
|
||||||
consume_each(noutput_items);
|
consume_each(noutput_items);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -611,7 +613,7 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items,
|
|||||||
d_state = 0;
|
d_state = 0;
|
||||||
if (!acq_parameters.blocking_on_standby)
|
if (!acq_parameters.blocking_on_standby)
|
||||||
{
|
{
|
||||||
d_sample_counter += noutput_items; // sample counter
|
d_sample_counter += static_cast<uint64_t>(noutput_items); // sample counter
|
||||||
consume_each(noutput_items);
|
consume_each(noutput_items);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -98,7 +98,7 @@ private:
|
|||||||
int d_num_doppler_points;
|
int d_num_doppler_points;
|
||||||
int d_doppler_step;
|
int d_doppler_step;
|
||||||
unsigned int d_fft_size;
|
unsigned int d_fft_size;
|
||||||
unsigned long int d_sample_counter;
|
uint64_t d_sample_counter;
|
||||||
gr_complex* d_carrier;
|
gr_complex* d_carrier;
|
||||||
gr_complex* d_fft_codes;
|
gr_complex* d_fft_codes;
|
||||||
gr_complex* d_10_ms_buffer;
|
gr_complex* d_10_ms_buffer;
|
||||||
@ -125,7 +125,7 @@ private:
|
|||||||
std::string d_dump_filename;
|
std::string d_dump_filename;
|
||||||
|
|
||||||
arma ::fmat grid_;
|
arma ::fmat grid_;
|
||||||
long int d_dump_number;
|
int64_t d_dump_number;
|
||||||
unsigned int d_dump_channel;
|
unsigned int d_dump_channel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
|
* Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
|
||||||
*
|
*
|
||||||
* GNSS-SDR is a software defined Global Navigation
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
* Satellite Systems receiver
|
* Satellite Systems receiver
|
||||||
@ -33,16 +33,19 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
|
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pcps_acquisition_fpga.h"
|
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include <gnuradio/io_signature.h>
|
#include <gnuradio/io_signature.h>
|
||||||
|
#include "pcps_acquisition_fpga.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define AQ_DOWNSAMPLING_DELAY 40 // delay due to the downsampling filter in the acquisition
|
||||||
|
|
||||||
using google::LogMessage;
|
using google::LogMessage;
|
||||||
|
|
||||||
pcps_acquisition_fpga_sptr pcps_make_acquisition_fpga(pcpsconf_fpga_t conf_)
|
pcps_acquisition_fpga_sptr pcps_make_acquisition_fpga(pcpsconf_fpga_t conf_)
|
||||||
@ -55,41 +58,67 @@ pcps_acquisition_fpga::pcps_acquisition_fpga(pcpsconf_fpga_t conf_) : gr::block(
|
|||||||
gr::io_signature::make(0, 0, 0),
|
gr::io_signature::make(0, 0, 0),
|
||||||
gr::io_signature::make(0, 0, 0))
|
gr::io_signature::make(0, 0, 0))
|
||||||
{
|
{
|
||||||
|
// printf("acq constructor start\n");
|
||||||
this->message_port_register_out(pmt::mp("events"));
|
this->message_port_register_out(pmt::mp("events"));
|
||||||
|
|
||||||
acq_parameters = conf_;
|
acq_parameters = conf_;
|
||||||
d_sample_counter = 0; // SAMPLE COUNTER
|
d_sample_counter = 0ULL; // SAMPLE COUNTER
|
||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
d_fft_size = acq_parameters.sampled_ms * acq_parameters.samples_per_ms;
|
//d_fft_size = acq_parameters.sampled_ms * acq_parameters.samples_per_ms;
|
||||||
|
d_fft_size = acq_parameters.samples_per_code;
|
||||||
d_mag = 0;
|
d_mag = 0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_num_doppler_bins = 0;
|
d_num_doppler_bins = 0U;
|
||||||
d_threshold = 0.0;
|
d_threshold = 0.0;
|
||||||
d_doppler_step = 0;
|
d_doppler_step = 0U;
|
||||||
d_test_statistics = 0.0;
|
d_test_statistics = 0.0;
|
||||||
d_channel = 0;
|
d_channel = 0U;
|
||||||
d_gnss_synchro = 0;
|
d_gnss_synchro = 0;
|
||||||
|
|
||||||
acquisition_fpga = std::make_shared<fpga_acquisition>(acq_parameters.device_name, d_fft_size, acq_parameters.doppler_max, acq_parameters.samples_per_ms,
|
//printf("zzzz acq_parameters.code_length = %d\n", acq_parameters.code_length);
|
||||||
|
//printf("zzzz acq_parameters.samples_per_ms = %d\n", acq_parameters.samples_per_ms);
|
||||||
|
//printf("zzzz d_fft_size = %d\n", d_fft_size);
|
||||||
|
|
||||||
|
// this one works we don't know why
|
||||||
|
// acquisition_fpga = std::make_shared <fpga_acquisition>
|
||||||
|
// (acq_parameters.device_name, acq_parameters.code_length, acq_parameters.doppler_max, acq_parameters.samples_per_ms,
|
||||||
|
// acq_parameters.fs_in, acq_parameters.freq, acq_parameters.sampled_ms, acq_parameters.select_queue_Fpga, acq_parameters.all_fft_codes);
|
||||||
|
|
||||||
|
// this one is the one it should be but it doesn't work
|
||||||
|
acquisition_fpga = std::make_shared<fpga_acquisition>(acq_parameters.device_name, acq_parameters.code_length, acq_parameters.doppler_max, d_fft_size,
|
||||||
acq_parameters.fs_in, acq_parameters.sampled_ms, acq_parameters.select_queue_Fpga, acq_parameters.all_fft_codes);
|
acq_parameters.fs_in, acq_parameters.sampled_ms, acq_parameters.select_queue_Fpga, acq_parameters.all_fft_codes);
|
||||||
|
|
||||||
|
// acquisition_fpga = std::make_shared <fpga_acquisition>
|
||||||
|
// (acq_parameters.device_name, acq_parameters.samples_per_code, acq_parameters.doppler_max, acq_parameters.samples_per_code,
|
||||||
|
// acq_parameters.fs_in, acq_parameters.freq, acq_parameters.sampled_ms, acq_parameters.select_queue_Fpga, acq_parameters.all_fft_codes);
|
||||||
|
|
||||||
|
// debug
|
||||||
|
//debug_d_max_absolute = 0.0;
|
||||||
|
//debug_d_input_power_absolute = 0.0;
|
||||||
|
// printf("acq constructor end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pcps_acquisition_fpga::~pcps_acquisition_fpga()
|
pcps_acquisition_fpga::~pcps_acquisition_fpga()
|
||||||
{
|
{
|
||||||
|
// printf("acq destructor start\n");
|
||||||
acquisition_fpga->free();
|
acquisition_fpga->free();
|
||||||
|
// printf("acq destructor end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcps_acquisition_fpga::set_local_code()
|
void pcps_acquisition_fpga::set_local_code()
|
||||||
{
|
{
|
||||||
|
// printf("acq set local code start\n");
|
||||||
acquisition_fpga->set_local_code(d_gnss_synchro->PRN);
|
acquisition_fpga->set_local_code(d_gnss_synchro->PRN);
|
||||||
|
// printf("acq set local code end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcps_acquisition_fpga::init()
|
void pcps_acquisition_fpga::init()
|
||||||
{
|
{
|
||||||
|
// printf("acq init start\n");
|
||||||
d_gnss_synchro->Flag_valid_acquisition = false;
|
d_gnss_synchro->Flag_valid_acquisition = false;
|
||||||
d_gnss_synchro->Flag_valid_symbol_output = false;
|
d_gnss_synchro->Flag_valid_symbol_output = false;
|
||||||
d_gnss_synchro->Flag_valid_pseudorange = false;
|
d_gnss_synchro->Flag_valid_pseudorange = false;
|
||||||
@ -99,14 +128,16 @@ void pcps_acquisition_fpga::init()
|
|||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_num_doppler_bins = static_cast<unsigned int>(std::ceil(static_cast<double>(static_cast<int>(acq_parameters.doppler_max) - static_cast<int>(-acq_parameters.doppler_max)) / static_cast<double>(d_doppler_step)));
|
d_num_doppler_bins = static_cast<uint32_t>(std::ceil(static_cast<double>(static_cast<int32_t>(acq_parameters.doppler_max) - static_cast<int32_t>(-acq_parameters.doppler_max)) / static_cast<double>(d_doppler_step)));
|
||||||
|
|
||||||
acquisition_fpga->init();
|
acquisition_fpga->init();
|
||||||
|
// printf("acq init end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcps_acquisition_fpga::set_state(int state)
|
void pcps_acquisition_fpga::set_state(int32_t state)
|
||||||
{
|
{
|
||||||
|
// printf("acq set state start\n");
|
||||||
d_state = state;
|
d_state = state;
|
||||||
if (d_state == 1)
|
if (d_state == 1)
|
||||||
{
|
{
|
||||||
@ -126,11 +157,13 @@ void pcps_acquisition_fpga::set_state(int state)
|
|||||||
{
|
{
|
||||||
LOG(ERROR) << "State can only be set to 0 or 1";
|
LOG(ERROR) << "State can only be set to 0 or 1";
|
||||||
}
|
}
|
||||||
|
// printf("acq set state end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcps_acquisition_fpga::send_positive_acquisition()
|
void pcps_acquisition_fpga::send_positive_acquisition()
|
||||||
{
|
{
|
||||||
|
// printf("acq send positive acquisition start\n");
|
||||||
// 6.1- Declare positive acquisition using a message port
|
// 6.1- Declare positive acquisition using a message port
|
||||||
//0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
//0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
||||||
DLOG(INFO) << "positive acquisition"
|
DLOG(INFO) << "positive acquisition"
|
||||||
@ -144,11 +177,13 @@ void pcps_acquisition_fpga::send_positive_acquisition()
|
|||||||
<< ", input signal power " << d_input_power;
|
<< ", input signal power " << d_input_power;
|
||||||
|
|
||||||
this->message_port_pub(pmt::mp("events"), pmt::from_long(1));
|
this->message_port_pub(pmt::mp("events"), pmt::from_long(1));
|
||||||
|
// printf("acq send positive acquisition end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcps_acquisition_fpga::send_negative_acquisition()
|
void pcps_acquisition_fpga::send_negative_acquisition()
|
||||||
{
|
{
|
||||||
|
// printf("acq send negative acquisition start\n");
|
||||||
// 6.2- Declare negative acquisition using a message port
|
// 6.2- Declare negative acquisition using a message port
|
||||||
//0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
//0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
||||||
DLOG(INFO) << "negative acquisition"
|
DLOG(INFO) << "negative acquisition"
|
||||||
@ -162,16 +197,19 @@ void pcps_acquisition_fpga::send_negative_acquisition()
|
|||||||
<< ", input signal power " << d_input_power;
|
<< ", input signal power " << d_input_power;
|
||||||
|
|
||||||
this->message_port_pub(pmt::mp("events"), pmt::from_long(2));
|
this->message_port_pub(pmt::mp("events"), pmt::from_long(2));
|
||||||
|
// printf("acq send negative acquisition end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcps_acquisition_fpga::set_active(bool active)
|
void pcps_acquisition_fpga::set_active(bool active)
|
||||||
{
|
{
|
||||||
|
// printf("acq set active start\n");
|
||||||
d_active = active;
|
d_active = active;
|
||||||
|
|
||||||
// initialize acquisition algorithm
|
// initialize acquisition algorithm
|
||||||
uint32_t indext = 0;
|
uint32_t indext = 0U;
|
||||||
float magt = 0.0;
|
float magt = 0.0;
|
||||||
|
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
|
||||||
|
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
@ -184,24 +222,32 @@ void pcps_acquisition_fpga::set_active(bool active)
|
|||||||
// no CFAR algorithm in the FPGA
|
// no CFAR algorithm in the FPGA
|
||||||
<< ", use_CFAR_algorithm_flag: false";
|
<< ", use_CFAR_algorithm_flag: false";
|
||||||
|
|
||||||
unsigned int initial_sample;
|
uint64_t initial_sample;
|
||||||
float input_power_all = 0.0;
|
float input_power_all = 0.0;
|
||||||
float input_power_computed = 0.0;
|
float input_power_computed = 0.0;
|
||||||
|
|
||||||
|
float temp_d_input_power;
|
||||||
|
|
||||||
|
// loop through acquisition
|
||||||
|
/*
|
||||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||||
{
|
{
|
||||||
// doppler search steps
|
// doppler search steps
|
||||||
int doppler = -static_cast<int>(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
|
int32_t doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
|
||||||
|
|
||||||
acquisition_fpga->set_phase_step(doppler_index);
|
//acquisition_fpga->set_phase_step(doppler_index);
|
||||||
|
acquisition_fpga->set_doppler_sweep_debug(1, doppler_index);
|
||||||
acquisition_fpga->run_acquisition(); // runs acquisition and waits until it is finished
|
acquisition_fpga->run_acquisition(); // runs acquisition and waits until it is finished
|
||||||
acquisition_fpga->read_acquisition_results(&indext, &magt,
|
acquisition_fpga->read_acquisition_results(&indext, &magt,
|
||||||
&initial_sample, &d_input_power);
|
&initial_sample, &d_input_power, &d_doppler_index);
|
||||||
d_sample_counter = initial_sample;
|
d_sample_counter = initial_sample;
|
||||||
|
|
||||||
if (d_mag < magt)
|
if (d_mag < magt)
|
||||||
{
|
{
|
||||||
d_mag = magt;
|
d_mag = magt;
|
||||||
|
|
||||||
|
temp_d_input_power = d_input_power;
|
||||||
|
|
||||||
input_power_all = d_input_power / (d_fft_size - 1);
|
input_power_all = d_input_power / (d_fft_size - 1);
|
||||||
input_power_computed = (d_input_power - d_mag) / (d_fft_size - 1);
|
input_power_computed = (d_input_power - d_mag) / (d_fft_size - 1);
|
||||||
d_input_power = (d_input_power - d_mag) / (d_fft_size - 1);
|
d_input_power = (d_input_power - d_mag) / (d_fft_size - 1);
|
||||||
@ -216,10 +262,73 @@ void pcps_acquisition_fpga::set_active(bool active)
|
|||||||
// In the case of the FPGA the option of dumping the results of the acquisition to a file is not available
|
// In the case of the FPGA the option of dumping the results of the acquisition to a file is not available
|
||||||
// because the IFFT vector is not available
|
// because the IFFT vector is not available
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// debug
|
||||||
|
//acquisition_fpga->block_samples();
|
||||||
|
|
||||||
|
// run loop in hw
|
||||||
|
//printf("LAUNCH ACQ\n");
|
||||||
|
acquisition_fpga->set_doppler_sweep(d_num_doppler_bins);
|
||||||
|
acquisition_fpga->run_acquisition();
|
||||||
|
acquisition_fpga->read_acquisition_results(&indext, &magt,
|
||||||
|
&initial_sample, &d_input_power, &d_doppler_index);
|
||||||
|
//printf("READ ACQ RESULTS\n");
|
||||||
|
|
||||||
|
// debug
|
||||||
|
//acquisition_fpga->unblock_samples();
|
||||||
|
|
||||||
|
d_mag = magt;
|
||||||
|
|
||||||
|
|
||||||
|
// debug
|
||||||
|
debug_d_max_absolute = magt;
|
||||||
|
debug_d_input_power_absolute = d_input_power;
|
||||||
|
debug_indext = indext;
|
||||||
|
debug_doppler_index = d_doppler_index;
|
||||||
|
|
||||||
|
// temp_d_input_power = d_input_power;
|
||||||
|
|
||||||
|
d_input_power = (d_input_power - d_mag) / (d_fft_size - 1);
|
||||||
|
int32_t doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * d_doppler_index;
|
||||||
|
//d_gnss_synchro->Acq_delay_samples = static_cast<double>(2*(indext % (2*acq_parameters.samples_per_code)));
|
||||||
|
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code);
|
||||||
|
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
||||||
|
d_sample_counter = initial_sample;
|
||||||
|
//d_gnss_synchro->Acq_samplestamp_samples = 2*d_sample_counter - 81; // delay due to the downsampling filter in the acquisition
|
||||||
|
//d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter - 40; // delay due to the downsampling filter in the acquisition
|
||||||
|
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; // delay due to the downsampling filter in the acquisition
|
||||||
|
d_test_statistics = (d_mag / d_input_power); //* correction_factor;
|
||||||
|
|
||||||
|
// debug
|
||||||
|
// if (d_gnss_synchro->Acq_delay_samples > acq_parameters.code_length)
|
||||||
|
// {
|
||||||
|
// printf("d_gnss_synchro->Acq_samplestamp_samples = %d\n", d_gnss_synchro->Acq_samplestamp_samples);
|
||||||
|
// printf("d_gnss_synchro->Acq_delay_samples = %f\n", d_gnss_synchro->Acq_delay_samples);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (temp_d_input_power > debug_d_input_power_absolute)
|
||||||
|
// {
|
||||||
|
// debug_d_max_absolute = d_mag;
|
||||||
|
// debug_d_input_power_absolute = temp_d_input_power;
|
||||||
|
// }
|
||||||
|
// printf ("max debug_d_max_absolute = %f\n", debug_d_max_absolute);
|
||||||
|
// printf ("debug_d_input_power_absolute = %f\n", debug_d_input_power_absolute);
|
||||||
|
|
||||||
|
// printf("&&&&& d_test_statistics = %f\n", d_test_statistics);
|
||||||
|
// printf("&&&&& debug_d_max_absolute =%f\n",debug_d_max_absolute);
|
||||||
|
// printf("&&&&& debug_d_input_power_absolute =%f\n",debug_d_input_power_absolute);
|
||||||
|
// printf("&&&&& debug_indext = %d\n",debug_indext);
|
||||||
|
// printf("&&&&& debug_doppler_index = %d\n",debug_doppler_index);
|
||||||
|
|
||||||
if (d_test_statistics > d_threshold)
|
if (d_test_statistics > d_threshold)
|
||||||
{
|
{
|
||||||
d_active = false;
|
d_active = false;
|
||||||
|
// printf("##### d_test_statistics = %f\n", d_test_statistics);
|
||||||
|
// printf("##### debug_d_max_absolute =%f\n",debug_d_max_absolute);
|
||||||
|
// printf("##### debug_d_input_power_absolute =%f\n",debug_d_input_power_absolute);
|
||||||
|
// printf("##### initial_sample = %llu\n",initial_sample);
|
||||||
|
// printf("##### debug_doppler_index = %d\n",debug_doppler_index);
|
||||||
send_positive_acquisition();
|
send_positive_acquisition();
|
||||||
d_state = 0; // Positive acquisition
|
d_state = 0; // Positive acquisition
|
||||||
}
|
}
|
||||||
@ -229,12 +338,13 @@ void pcps_acquisition_fpga::set_active(bool active)
|
|||||||
d_active = false;
|
d_active = false;
|
||||||
send_negative_acquisition();
|
send_negative_acquisition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// printf("acq set active end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int pcps_acquisition_fpga::general_work(int noutput_items __attribute__((unused)),
|
int pcps_acquisition_fpga::general_work(int noutput_items __attribute__((unused)),
|
||||||
gr_vector_int& ninput_items __attribute__((unused)),
|
gr_vector_int& ninput_items, gr_vector_const_void_star& input_items,
|
||||||
gr_vector_const_void_star& input_items __attribute__((unused)),
|
|
||||||
gr_vector_void_star& output_items __attribute__((unused)))
|
gr_vector_void_star& output_items __attribute__((unused)))
|
||||||
{
|
{
|
||||||
// the general work is not used with the acquisition that uses the FPGA
|
// the general work is not used with the acquisition that uses the FPGA
|
||||||
|
@ -64,13 +64,13 @@
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/* pcps acquisition configuration */
|
/* pcps acquisition configuration */
|
||||||
unsigned int sampled_ms;
|
uint32_t sampled_ms;
|
||||||
unsigned int doppler_max;
|
uint32_t doppler_max;
|
||||||
long freq;
|
int64_t fs_in;
|
||||||
long fs_in;
|
int32_t samples_per_ms;
|
||||||
int samples_per_ms;
|
int32_t samples_per_code;
|
||||||
int samples_per_code;
|
int32_t code_length;
|
||||||
unsigned int select_queue_Fpga;
|
uint32_t select_queue_Fpga;
|
||||||
std::string device_name;
|
std::string device_name;
|
||||||
lv_16sc_t* all_fft_codes; // memory that contains all the code ffts
|
lv_16sc_t* all_fft_codes; // memory that contains all the code ffts
|
||||||
|
|
||||||
@ -107,16 +107,23 @@ private:
|
|||||||
float d_threshold;
|
float d_threshold;
|
||||||
float d_mag;
|
float d_mag;
|
||||||
float d_input_power;
|
float d_input_power;
|
||||||
|
uint32_t d_doppler_index;
|
||||||
float d_test_statistics;
|
float d_test_statistics;
|
||||||
int d_state;
|
int32_t d_state;
|
||||||
unsigned int d_channel;
|
uint32_t d_channel;
|
||||||
unsigned int d_doppler_step;
|
uint32_t d_doppler_step;
|
||||||
unsigned int d_fft_size;
|
uint32_t d_fft_size;
|
||||||
unsigned int d_num_doppler_bins;
|
uint32_t d_num_doppler_bins;
|
||||||
unsigned long int d_sample_counter;
|
uint64_t d_sample_counter;
|
||||||
Gnss_Synchro* d_gnss_synchro;
|
Gnss_Synchro* d_gnss_synchro;
|
||||||
std::shared_ptr<fpga_acquisition> acquisition_fpga;
|
std::shared_ptr<fpga_acquisition> acquisition_fpga;
|
||||||
|
|
||||||
|
// debug
|
||||||
|
float debug_d_max_absolute;
|
||||||
|
float debug_d_input_power_absolute;
|
||||||
|
int32_t debug_indext;
|
||||||
|
int32_t debug_doppler_index;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~pcps_acquisition_fpga();
|
~pcps_acquisition_fpga();
|
||||||
|
|
||||||
@ -127,15 +134,19 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
|
inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
|
||||||
{
|
{
|
||||||
|
// printf("acq set gnss synchro start\n");
|
||||||
d_gnss_synchro = p_gnss_synchro;
|
d_gnss_synchro = p_gnss_synchro;
|
||||||
|
// printf("acq set gnss synchro end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the maximum peak of grid search.
|
* \brief Returns the maximum peak of grid search.
|
||||||
*/
|
*/
|
||||||
inline unsigned int mag() const
|
inline uint32_t mag() const
|
||||||
{
|
{
|
||||||
|
// printf("acq dmag start\n");
|
||||||
return d_mag;
|
return d_mag;
|
||||||
|
// printf("acq dmag end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -154,7 +165,7 @@ public:
|
|||||||
* first available sample.
|
* first available sample.
|
||||||
* \param state - int=1 forces start of acquisition
|
* \param state - int=1 forces start of acquisition
|
||||||
*/
|
*/
|
||||||
void set_state(int state);
|
void set_state(int32_t state);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Starts acquisition algorithm, turning from standby mode to
|
* \brief Starts acquisition algorithm, turning from standby mode to
|
||||||
@ -167,7 +178,7 @@ public:
|
|||||||
* \brief Set acquisition channel unique ID
|
* \brief Set acquisition channel unique ID
|
||||||
* \param channel - receiver channel.
|
* \param channel - receiver channel.
|
||||||
*/
|
*/
|
||||||
inline void set_channel(unsigned int channel)
|
inline void set_channel(uint32_t channel)
|
||||||
{
|
{
|
||||||
d_channel = channel;
|
d_channel = channel;
|
||||||
}
|
}
|
||||||
@ -179,27 +190,33 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline void set_threshold(float threshold)
|
inline void set_threshold(float threshold)
|
||||||
{
|
{
|
||||||
|
// printf("acq set threshold start\n");
|
||||||
d_threshold = threshold;
|
d_threshold = threshold;
|
||||||
|
// printf("acq set threshold end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Set maximum Doppler grid search
|
* \brief Set maximum Doppler grid search
|
||||||
* \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
|
* \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
|
||||||
*/
|
*/
|
||||||
inline void set_doppler_max(unsigned int doppler_max)
|
inline void set_doppler_max(uint32_t doppler_max)
|
||||||
{
|
{
|
||||||
|
// printf("acq set doppler max start\n");
|
||||||
acq_parameters.doppler_max = doppler_max;
|
acq_parameters.doppler_max = doppler_max;
|
||||||
acquisition_fpga->set_doppler_max(doppler_max);
|
acquisition_fpga->set_doppler_max(doppler_max);
|
||||||
|
// printf("acq set doppler max end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Set Doppler steps for the grid search
|
* \brief Set Doppler steps for the grid search
|
||||||
* \param doppler_step - Frequency bin of the search grid [Hz].
|
* \param doppler_step - Frequency bin of the search grid [Hz].
|
||||||
*/
|
*/
|
||||||
inline void set_doppler_step(unsigned int doppler_step)
|
inline void set_doppler_step(uint32_t doppler_step)
|
||||||
{
|
{
|
||||||
|
// printf("acq set doppler step start\n");
|
||||||
d_doppler_step = doppler_step;
|
d_doppler_step = doppler_step;
|
||||||
acquisition_fpga->set_doppler_step(doppler_step);
|
acquisition_fpga->set_doppler_step(doppler_step);
|
||||||
|
// printf("acq set doppler step end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -64,7 +64,7 @@ pcps_assisted_acquisition_cc::pcps_assisted_acquisition_cc(
|
|||||||
gr::io_signature::make(0, 0, sizeof(gr_complex)))
|
gr::io_signature::make(0, 0, sizeof(gr_complex)))
|
||||||
{
|
{
|
||||||
this->message_port_register_out(pmt::mp("events"));
|
this->message_port_register_out(pmt::mp("events"));
|
||||||
d_sample_counter = 0; // SAMPLE COUNTER
|
d_sample_counter = 0ULL; // SAMPLE COUNTER
|
||||||
d_active = false;
|
d_active = false;
|
||||||
d_fs_in = fs_in;
|
d_fs_in = fs_in;
|
||||||
d_samples_per_ms = samples_per_ms;
|
d_samples_per_ms = samples_per_ms;
|
||||||
@ -150,10 +150,10 @@ void pcps_assisted_acquisition_cc::init()
|
|||||||
d_gnss_synchro->Flag_valid_symbol_output = false;
|
d_gnss_synchro->Flag_valid_symbol_output = false;
|
||||||
d_gnss_synchro->Flag_valid_pseudorange = false;
|
d_gnss_synchro->Flag_valid_pseudorange = false;
|
||||||
d_gnss_synchro->Flag_valid_word = false;
|
d_gnss_synchro->Flag_valid_word = false;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
|
|
||||||
@ -279,6 +279,7 @@ double pcps_assisted_acquisition_cc::search_maximum()
|
|||||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(index_time);
|
d_gnss_synchro->Acq_delay_samples = static_cast<double>(index_time);
|
||||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(index_doppler * d_doppler_step + d_doppler_min);
|
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(index_doppler * d_doppler_step + d_doppler_min);
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = d_doppler_step;
|
||||||
|
|
||||||
// Record results to file if required
|
// Record results to file if required
|
||||||
if (d_dump)
|
if (d_dump)
|
||||||
@ -380,14 +381,14 @@ int pcps_assisted_acquisition_cc::general_work(int noutput_items,
|
|||||||
{
|
{
|
||||||
case 0: // S0. StandBy
|
case 0: // S0. StandBy
|
||||||
if (d_active == true) d_state = 1;
|
if (d_active == true) d_state = 1;
|
||||||
d_sample_counter += ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
break;
|
break;
|
||||||
case 1: // S1. GetAssist
|
case 1: // S1. GetAssist
|
||||||
get_assistance();
|
get_assistance();
|
||||||
redefine_grid();
|
redefine_grid();
|
||||||
reset_grid();
|
reset_grid();
|
||||||
d_sample_counter += ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
d_state = 2;
|
d_state = 2;
|
||||||
break;
|
break;
|
||||||
@ -399,7 +400,7 @@ int pcps_assisted_acquisition_cc::general_work(int noutput_items,
|
|||||||
{
|
{
|
||||||
d_state = 3;
|
d_state = 3;
|
||||||
}
|
}
|
||||||
d_sample_counter += consumed_samples;
|
d_sample_counter += static_cast<uint64_t>(consumed_samples);
|
||||||
consume_each(consumed_samples);
|
consume_each(consumed_samples);
|
||||||
break;
|
break;
|
||||||
case 3: // Compute test statistics and decide
|
case 3: // Compute test statistics and decide
|
||||||
@ -422,14 +423,14 @@ int pcps_assisted_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_state = 6;
|
d_state = 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d_sample_counter += ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
break;
|
break;
|
||||||
case 4: // RedefineGrid
|
case 4: // RedefineGrid
|
||||||
free_grid_memory();
|
free_grid_memory();
|
||||||
redefine_grid();
|
redefine_grid();
|
||||||
reset_grid();
|
reset_grid();
|
||||||
d_sample_counter += ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
d_state = 2;
|
d_state = 2;
|
||||||
break;
|
break;
|
||||||
@ -447,7 +448,7 @@ int pcps_assisted_acquisition_cc::general_work(int noutput_items,
|
|||||||
this->message_port_pub(pmt::mp("events"), pmt::from_long(1));
|
this->message_port_pub(pmt::mp("events"), pmt::from_long(1));
|
||||||
free_grid_memory();
|
free_grid_memory();
|
||||||
// consume samples to not block the GNU Radio flowgraph
|
// consume samples to not block the GNU Radio flowgraph
|
||||||
d_sample_counter += ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
break;
|
break;
|
||||||
@ -465,7 +466,7 @@ int pcps_assisted_acquisition_cc::general_work(int noutput_items,
|
|||||||
this->message_port_pub(pmt::mp("events"), pmt::from_long(2));
|
this->message_port_pub(pmt::mp("events"), pmt::from_long(2));
|
||||||
free_grid_memory();
|
free_grid_memory();
|
||||||
// consume samples to not block the GNU Radio flowgraph
|
// consume samples to not block the GNU Radio flowgraph
|
||||||
d_sample_counter += ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -112,7 +112,7 @@ private:
|
|||||||
int d_doppler_step;
|
int d_doppler_step;
|
||||||
unsigned int d_sampled_ms;
|
unsigned int d_sampled_ms;
|
||||||
unsigned int d_fft_size;
|
unsigned int d_fft_size;
|
||||||
unsigned long int d_sample_counter;
|
uint64_t d_sample_counter;
|
||||||
gr_complex* d_carrier;
|
gr_complex* d_carrier;
|
||||||
gr_complex* d_fft_codes;
|
gr_complex* d_fft_codes;
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ pcps_cccwsr_acquisition_cc::pcps_cccwsr_acquisition_cc(
|
|||||||
gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms))
|
gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms))
|
||||||
{
|
{
|
||||||
this->message_port_register_out(pmt::mp("events"));
|
this->message_port_register_out(pmt::mp("events"));
|
||||||
d_sample_counter = 0; // SAMPLE COUNTER
|
d_sample_counter = 0ULL; // SAMPLE COUNTER
|
||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
d_fs_in = fs_in;
|
d_fs_in = fs_in;
|
||||||
@ -165,10 +165,10 @@ void pcps_cccwsr_acquisition_cc::init()
|
|||||||
d_gnss_synchro->Flag_valid_symbol_output = false;
|
d_gnss_synchro->Flag_valid_symbol_output = false;
|
||||||
d_gnss_synchro->Flag_valid_pseudorange = false;
|
d_gnss_synchro->Flag_valid_pseudorange = false;
|
||||||
d_gnss_synchro->Flag_valid_word = false;
|
d_gnss_synchro->Flag_valid_word = false;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
|
|
||||||
@ -203,7 +203,8 @@ void pcps_cccwsr_acquisition_cc::set_state(int state)
|
|||||||
{
|
{
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_well_count = 0;
|
d_well_count = 0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
@ -234,7 +235,8 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items,
|
|||||||
//restart acquisition variables
|
//restart acquisition variables
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_well_count = 0;
|
d_well_count = 0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
@ -243,7 +245,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_state = 1;
|
d_state = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -262,7 +264,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items,
|
|||||||
const gr_complex *in = reinterpret_cast<const gr_complex *>(input_items[0]); //Get the input samples pointer
|
const gr_complex *in = reinterpret_cast<const gr_complex *>(input_items[0]); //Get the input samples pointer
|
||||||
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
|
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
|
||||||
|
|
||||||
d_sample_counter += d_fft_size; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size); // sample counter
|
||||||
|
|
||||||
d_well_count++;
|
d_well_count++;
|
||||||
|
|
||||||
@ -354,6 +356,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % d_samples_per_code);
|
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % d_samples_per_code);
|
||||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = d_doppler_step;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record results to file if required
|
// Record results to file if required
|
||||||
@ -406,7 +409,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
|
|
||||||
d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
|
|
||||||
acquisition_message = 1;
|
acquisition_message = 1;
|
||||||
@ -431,7 +434,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
|
|
||||||
d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
|
|
||||||
acquisition_message = 2;
|
acquisition_message = 2;
|
||||||
|
@ -88,7 +88,7 @@ private:
|
|||||||
unsigned int d_max_dwells;
|
unsigned int d_max_dwells;
|
||||||
unsigned int d_well_count;
|
unsigned int d_well_count;
|
||||||
unsigned int d_fft_size;
|
unsigned int d_fft_size;
|
||||||
unsigned long int d_sample_counter;
|
uint64_t d_sample_counter;
|
||||||
gr_complex** d_grid_doppler_wipeoffs;
|
gr_complex** d_grid_doppler_wipeoffs;
|
||||||
unsigned int d_num_doppler_bins;
|
unsigned int d_num_doppler_bins;
|
||||||
gr_complex* d_fft_code_data;
|
gr_complex* d_fft_code_data;
|
||||||
|
@ -93,7 +93,7 @@ pcps_opencl_acquisition_cc::pcps_opencl_acquisition_cc(
|
|||||||
gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms))
|
gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms))
|
||||||
{
|
{
|
||||||
this->message_port_register_out(pmt::mp("events"));
|
this->message_port_register_out(pmt::mp("events"));
|
||||||
d_sample_counter = 0; // SAMPLE COUNTER
|
d_sample_counter = 0ULL; // SAMPLE COUNTER
|
||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
d_core_working = false;
|
d_core_working = false;
|
||||||
@ -290,10 +290,10 @@ void pcps_opencl_acquisition_cc::init()
|
|||||||
d_gnss_synchro->Flag_valid_symbol_output = false;
|
d_gnss_synchro->Flag_valid_symbol_output = false;
|
||||||
d_gnss_synchro->Flag_valid_pseudorange = false;
|
d_gnss_synchro->Flag_valid_pseudorange = false;
|
||||||
d_gnss_synchro->Flag_valid_word = false;
|
d_gnss_synchro->Flag_valid_word = false;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
|
|
||||||
@ -387,7 +387,7 @@ void pcps_opencl_acquisition_cc::acquisition_core_volk()
|
|||||||
float magt = 0.0;
|
float magt = 0.0;
|
||||||
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
|
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
|
||||||
gr_complex *in = d_in_buffer[d_well_count];
|
gr_complex *in = d_in_buffer[d_well_count];
|
||||||
unsigned long int samplestamp = d_sample_counter_buffer[d_well_count];
|
uint64_t samplestamp = d_sample_counter_buffer[d_well_count];
|
||||||
|
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
@ -450,6 +450,7 @@ void pcps_opencl_acquisition_cc::acquisition_core_volk()
|
|||||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % d_samples_per_code);
|
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % d_samples_per_code);
|
||||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = samplestamp;
|
d_gnss_synchro->Acq_samplestamp_samples = samplestamp;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = d_doppler_step;
|
||||||
|
|
||||||
// 5- Compute the test statistics and compare to the threshold
|
// 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 = 2 * d_fft_size * d_mag / d_input_power;
|
||||||
@ -510,7 +511,7 @@ void pcps_opencl_acquisition_cc::acquisition_core_opencl()
|
|||||||
float magt = 0.0;
|
float magt = 0.0;
|
||||||
float fft_normalization_factor = (static_cast<float>(d_fft_size_pow2) * static_cast<float>(d_fft_size)); //This works, but I am not sure why.
|
float fft_normalization_factor = (static_cast<float>(d_fft_size_pow2) * static_cast<float>(d_fft_size)); //This works, but I am not sure why.
|
||||||
gr_complex *in = d_in_buffer[d_well_count];
|
gr_complex *in = d_in_buffer[d_well_count];
|
||||||
unsigned long int samplestamp = d_sample_counter_buffer[d_well_count];
|
uint64_t samplestamp = d_sample_counter_buffer[d_well_count];
|
||||||
|
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
@ -613,6 +614,7 @@ void pcps_opencl_acquisition_cc::acquisition_core_opencl()
|
|||||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % d_samples_per_code);
|
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % d_samples_per_code);
|
||||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = samplestamp;
|
d_gnss_synchro->Acq_samplestamp_samples = samplestamp;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = d_doppler_step;
|
||||||
|
|
||||||
// 5- Compute the test statistics and compare to the threshold
|
// 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 = 2 * d_fft_size * d_mag / d_input_power;
|
||||||
@ -676,7 +678,8 @@ void pcps_opencl_acquisition_cc::set_state(int state)
|
|||||||
{
|
{
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_well_count = 0;
|
d_well_count = 0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
@ -708,7 +711,8 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items,
|
|||||||
//restart acquisition variables
|
//restart acquisition variables
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_well_count = 0;
|
d_well_count = 0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
@ -719,7 +723,7 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_state = 1;
|
d_state = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -736,20 +740,20 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items,
|
|||||||
{
|
{
|
||||||
memcpy(d_in_buffer[d_in_dwell_count++], static_cast<const gr_complex *>(input_items[i]),
|
memcpy(d_in_buffer[d_in_dwell_count++], static_cast<const gr_complex *>(input_items[i]),
|
||||||
sizeof(gr_complex) * d_fft_size);
|
sizeof(gr_complex) * d_fft_size);
|
||||||
d_sample_counter += d_fft_size;
|
d_sample_counter += static_cast<uint64_t>(d_fft_size);
|
||||||
d_sample_counter_buffer.push_back(d_sample_counter);
|
d_sample_counter_buffer.push_back(d_sample_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ninput_items[0] > static_cast<int>(num_dwells))
|
if (ninput_items[0] > static_cast<int>(num_dwells))
|
||||||
{
|
{
|
||||||
d_sample_counter += d_fft_size * (ninput_items[0] - num_dwells);
|
d_sample_counter += static_cast<uint64_t>(d_fft_size * (ninput_items[0] - num_dwells));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We already have d_max_dwells consecutive blocks in the internal buffer,
|
// We already have d_max_dwells consecutive blocks in the internal buffer,
|
||||||
// just skip input blocks.
|
// just skip input blocks.
|
||||||
d_sample_counter += d_fft_size * ninput_items[0];
|
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We create a new thread to process next block if the following
|
// We create a new thread to process next block if the following
|
||||||
@ -793,7 +797,7 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
|
|
||||||
d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
|
||||||
|
|
||||||
acquisition_message = 1;
|
acquisition_message = 1;
|
||||||
this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message));
|
this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message));
|
||||||
@ -817,7 +821,7 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
|
|
||||||
d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
|
||||||
|
|
||||||
acquisition_message = 2;
|
acquisition_message = 2;
|
||||||
this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message));
|
this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message));
|
||||||
|
@ -121,7 +121,7 @@ private:
|
|||||||
unsigned int d_fft_size;
|
unsigned int d_fft_size;
|
||||||
unsigned int d_fft_size_pow2;
|
unsigned int d_fft_size_pow2;
|
||||||
int* d_max_doppler_indexs;
|
int* d_max_doppler_indexs;
|
||||||
unsigned long int d_sample_counter;
|
uint64_t d_sample_counter;
|
||||||
gr_complex** d_grid_doppler_wipeoffs;
|
gr_complex** d_grid_doppler_wipeoffs;
|
||||||
unsigned int d_num_doppler_bins;
|
unsigned int d_num_doppler_bins;
|
||||||
gr_complex* d_fft_codes;
|
gr_complex* d_fft_codes;
|
||||||
@ -144,7 +144,7 @@ private:
|
|||||||
std::string d_dump_filename;
|
std::string d_dump_filename;
|
||||||
gr_complex* d_zero_vector;
|
gr_complex* d_zero_vector;
|
||||||
gr_complex** d_in_buffer;
|
gr_complex** d_in_buffer;
|
||||||
std::vector<unsigned long int> d_sample_counter_buffer;
|
std::vector<uint64_t> d_sample_counter_buffer;
|
||||||
unsigned int d_in_dwell_count;
|
unsigned int d_in_dwell_count;
|
||||||
|
|
||||||
cl::Platform d_cl_platform;
|
cl::Platform d_cl_platform;
|
||||||
|
@ -73,7 +73,7 @@ pcps_quicksync_acquisition_cc::pcps_quicksync_acquisition_cc(
|
|||||||
gr::io_signature::make(0, 0, (sizeof(gr_complex) * sampled_ms * samples_per_ms)))
|
gr::io_signature::make(0, 0, (sizeof(gr_complex) * sampled_ms * samples_per_ms)))
|
||||||
{
|
{
|
||||||
this->message_port_register_out(pmt::mp("events"));
|
this->message_port_register_out(pmt::mp("events"));
|
||||||
d_sample_counter = 0; // SAMPLE COUNTER
|
d_sample_counter = 0ULL; // SAMPLE COUNTER
|
||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
d_fs_in = fs_in;
|
d_fs_in = fs_in;
|
||||||
@ -199,7 +199,8 @@ void pcps_quicksync_acquisition_cc::init()
|
|||||||
//DLOG(INFO) << "START init";
|
//DLOG(INFO) << "START init";
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
|
|
||||||
@ -236,7 +237,8 @@ void pcps_quicksync_acquisition_cc::set_state(int state)
|
|||||||
{
|
{
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_well_count = 0;
|
d_well_count = 0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
@ -279,7 +281,8 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
|
|||||||
//restart acquisition variables
|
//restart acquisition variables
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_well_count = 0;
|
d_well_count = 0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
@ -288,7 +291,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_state = 1;
|
d_state = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
d_sample_counter += d_sampled_ms * d_samples_per_ms * ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_sampled_ms * d_samples_per_ms * ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
//DLOG(INFO) << "END CASE 0";
|
//DLOG(INFO) << "END CASE 0";
|
||||||
break;
|
break;
|
||||||
@ -324,7 +327,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_test_statistics = 0.0;
|
d_test_statistics = 0.0;
|
||||||
d_noise_floor_power = 0.0;
|
d_noise_floor_power = 0.0;
|
||||||
|
|
||||||
d_sample_counter += d_sampled_ms * d_samples_per_ms; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_sampled_ms * d_samples_per_ms); // sample counter
|
||||||
|
|
||||||
d_well_count++;
|
d_well_count++;
|
||||||
|
|
||||||
@ -456,6 +459,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(d_possible_delay[indext]);
|
d_gnss_synchro->Acq_delay_samples = static_cast<double>(d_possible_delay[indext]);
|
||||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = d_doppler_step;
|
||||||
|
|
||||||
/* 5- Compute the test statistics and compare to the threshold d_test_statistics = 2 * d_fft_size * d_mag / d_input_power;*/
|
/* 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;
|
d_test_statistics = d_mag / d_input_power;
|
||||||
@ -536,7 +540,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
|
|
||||||
d_sample_counter += d_sampled_ms * d_samples_per_ms * ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_sampled_ms * d_samples_per_ms * ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
|
|
||||||
acquisition_message = 1;
|
acquisition_message = 1;
|
||||||
@ -565,7 +569,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
|
|
||||||
d_sample_counter += d_sampled_ms * d_samples_per_ms * ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_sampled_ms * d_samples_per_ms * ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
|
|
||||||
acquisition_message = 2;
|
acquisition_message = 2;
|
||||||
|
@ -127,7 +127,7 @@ private:
|
|||||||
unsigned int d_max_dwells;
|
unsigned int d_max_dwells;
|
||||||
unsigned int d_well_count;
|
unsigned int d_well_count;
|
||||||
unsigned int d_fft_size;
|
unsigned int d_fft_size;
|
||||||
unsigned long int d_sample_counter;
|
uint64_t d_sample_counter;
|
||||||
gr_complex** d_grid_doppler_wipeoffs;
|
gr_complex** d_grid_doppler_wipeoffs;
|
||||||
unsigned int d_num_doppler_bins;
|
unsigned int d_num_doppler_bins;
|
||||||
gr_complex* d_fft_codes;
|
gr_complex* d_fft_codes;
|
||||||
|
@ -82,7 +82,7 @@ pcps_tong_acquisition_cc::pcps_tong_acquisition_cc(
|
|||||||
gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms))
|
gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms))
|
||||||
{
|
{
|
||||||
this->message_port_register_out(pmt::mp("events"));
|
this->message_port_register_out(pmt::mp("events"));
|
||||||
d_sample_counter = 0; // SAMPLE COUNTER
|
d_sample_counter = 0ULL; // SAMPLE COUNTER
|
||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
d_fs_in = fs_in;
|
d_fs_in = fs_in;
|
||||||
@ -166,10 +166,10 @@ void pcps_tong_acquisition_cc::init()
|
|||||||
d_gnss_synchro->Flag_valid_symbol_output = false;
|
d_gnss_synchro->Flag_valid_symbol_output = false;
|
||||||
d_gnss_synchro->Flag_valid_pseudorange = false;
|
d_gnss_synchro->Flag_valid_pseudorange = false;
|
||||||
d_gnss_synchro->Flag_valid_word = false;
|
d_gnss_synchro->Flag_valid_word = false;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
|
|
||||||
@ -211,7 +211,8 @@ void pcps_tong_acquisition_cc::set_state(int state)
|
|||||||
{
|
{
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_dwell_count = 0;
|
d_dwell_count = 0;
|
||||||
d_tong_count = d_tong_init_val;
|
d_tong_count = d_tong_init_val;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
@ -250,7 +251,8 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items,
|
|||||||
//restart acquisition variables
|
//restart acquisition variables
|
||||||
d_gnss_synchro->Acq_delay_samples = 0.0;
|
d_gnss_synchro->Acq_delay_samples = 0.0;
|
||||||
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
d_gnss_synchro->Acq_doppler_hz = 0.0;
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = 0;
|
d_gnss_synchro->Acq_samplestamp_samples = 0ULL;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = 0U;
|
||||||
d_dwell_count = 0;
|
d_dwell_count = 0;
|
||||||
d_tong_count = d_tong_init_val;
|
d_tong_count = d_tong_init_val;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
@ -268,7 +270,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_state = 1;
|
d_state = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -285,7 +287,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_input_power = 0.0;
|
d_input_power = 0.0;
|
||||||
d_mag = 0.0;
|
d_mag = 0.0;
|
||||||
|
|
||||||
d_sample_counter += d_fft_size; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size); // sample counter
|
||||||
|
|
||||||
d_dwell_count++;
|
d_dwell_count++;
|
||||||
|
|
||||||
@ -345,6 +347,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % d_samples_per_code);
|
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % d_samples_per_code);
|
||||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
||||||
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
||||||
|
d_gnss_synchro->Acq_doppler_step = d_doppler_step;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record results to file if required
|
// Record results to file if required
|
||||||
@ -407,7 +410,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
|
|
||||||
d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
|
|
||||||
acquisition_message = 1;
|
acquisition_message = 1;
|
||||||
@ -432,7 +435,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items,
|
|||||||
d_active = false;
|
d_active = false;
|
||||||
d_state = 0;
|
d_state = 0;
|
||||||
|
|
||||||
d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
|
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
|
||||||
consume_each(ninput_items[0]);
|
consume_each(ninput_items[0]);
|
||||||
|
|
||||||
acquisition_message = 2;
|
acquisition_message = 2;
|
||||||
|
@ -108,7 +108,7 @@ private:
|
|||||||
unsigned int d_tong_max_val;
|
unsigned int d_tong_max_val;
|
||||||
unsigned int d_tong_max_dwells;
|
unsigned int d_tong_max_dwells;
|
||||||
unsigned int d_fft_size;
|
unsigned int d_fft_size;
|
||||||
unsigned long int d_sample_counter;
|
uint64_t d_sample_counter;
|
||||||
gr_complex** d_grid_doppler_wipeoffs;
|
gr_complex** d_grid_doppler_wipeoffs;
|
||||||
unsigned int d_num_doppler_bins;
|
unsigned int d_num_doppler_bins;
|
||||||
gr_complex* d_fft_codes;
|
gr_complex* d_fft_codes;
|
||||||
|
@ -34,22 +34,23 @@
|
|||||||
Acq_Conf::Acq_Conf()
|
Acq_Conf::Acq_Conf()
|
||||||
{
|
{
|
||||||
/* PCPS acquisition configuration */
|
/* PCPS acquisition configuration */
|
||||||
sampled_ms = 0;
|
sampled_ms = 0U;
|
||||||
max_dwells = 0;
|
ms_per_code = 0U;
|
||||||
samples_per_chip = 0;
|
max_dwells = 0U;
|
||||||
doppler_max = 0;
|
samples_per_chip = 0U;
|
||||||
num_doppler_bins_step2 = 0;
|
doppler_max = 0U;
|
||||||
|
num_doppler_bins_step2 = 0U;
|
||||||
doppler_step2 = 0.0;
|
doppler_step2 = 0.0;
|
||||||
fs_in = 0;
|
fs_in = 0LL;
|
||||||
samples_per_ms = 0;
|
samples_per_ms = 0.0;
|
||||||
samples_per_code = 0;
|
samples_per_code = 0.0;
|
||||||
bit_transition_flag = false;
|
bit_transition_flag = false;
|
||||||
use_CFAR_algorithm_flag = false;
|
use_CFAR_algorithm_flag = false;
|
||||||
dump = false;
|
dump = false;
|
||||||
blocking = false;
|
blocking = false;
|
||||||
make_2_steps = false;
|
make_2_steps = false;
|
||||||
dump_filename = "";
|
dump_filename = "";
|
||||||
dump_channel = 0;
|
dump_channel = 0U;
|
||||||
it_size = sizeof(char);
|
it_size = sizeof(char);
|
||||||
blocking_on_standby = false;
|
blocking_on_standby = false;
|
||||||
}
|
}
|
||||||
|
@ -33,21 +33,23 @@
|
|||||||
#define GNSS_SDR_ACQ_CONF_H_
|
#define GNSS_SDR_ACQ_CONF_H_
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class Acq_Conf
|
class Acq_Conf
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/* PCPS Acquisition configuration */
|
/* PCPS Acquisition configuration */
|
||||||
unsigned int sampled_ms;
|
uint32_t sampled_ms;
|
||||||
unsigned int samples_per_chip;
|
uint32_t ms_per_code;
|
||||||
unsigned int max_dwells;
|
uint32_t samples_per_chip;
|
||||||
unsigned int doppler_max;
|
uint32_t max_dwells;
|
||||||
unsigned int num_doppler_bins_step2;
|
uint32_t doppler_max;
|
||||||
|
uint32_t num_doppler_bins_step2;
|
||||||
float doppler_step2;
|
float doppler_step2;
|
||||||
long fs_in;
|
int64_t fs_in;
|
||||||
int samples_per_ms;
|
float samples_per_ms;
|
||||||
int samples_per_code;
|
float samples_per_code;
|
||||||
bool bit_transition_flag;
|
bool bit_transition_flag;
|
||||||
bool use_CFAR_algorithm_flag;
|
bool use_CFAR_algorithm_flag;
|
||||||
bool dump;
|
bool dump;
|
||||||
@ -55,7 +57,7 @@ public:
|
|||||||
bool blocking_on_standby; // enable it only for unit testing to avoid sample consume on idle status
|
bool blocking_on_standby; // enable it only for unit testing to avoid sample consume on idle status
|
||||||
bool make_2_steps;
|
bool make_2_steps;
|
||||||
std::string dump_filename;
|
std::string dump_filename;
|
||||||
unsigned int dump_channel;
|
uint32_t dump_channel;
|
||||||
size_t it_size;
|
size_t it_size;
|
||||||
|
|
||||||
Acq_Conf();
|
Acq_Conf();
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "GPS_L1_CA.h"
|
#include "GPS_L1_CA.h"
|
||||||
#include "gps_sdr_signal_processing.h"
|
#include "gps_sdr_signal_processing.h"
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
|
#include <iostream>
|
||||||
#include <fcntl.h> // libraries used by the GIPO
|
#include <fcntl.h> // libraries used by the GIPO
|
||||||
#include <sys/mman.h> // libraries used by the GIPO
|
#include <sys/mman.h> // libraries used by the GIPO
|
||||||
|
|
||||||
@ -55,6 +56,17 @@
|
|||||||
#define SELECT_16_BITS 0xFFFF // value to select 16 bits
|
#define SELECT_16_BITS 0xFFFF // value to select 16 bits
|
||||||
#define SHL_8_BITS 256 // value used to shift a value 8 bits to the left
|
#define SHL_8_BITS 256 // value used to shift a value 8 bits to the left
|
||||||
|
|
||||||
|
// 12-bits
|
||||||
|
//#define SELECT_LSBits 0x0FFF
|
||||||
|
//#define SELECT_MSBbits 0x00FFF000
|
||||||
|
//#define SELECT_24_BITS 0x00FFFFFF
|
||||||
|
//#define SHL_12_BITS 4096
|
||||||
|
// 16-bits
|
||||||
|
#define SELECT_LSBits 0x0FFFF
|
||||||
|
#define SELECT_MSBbits 0xFFFF0000
|
||||||
|
#define SELECT_32_BITS 0xFFFFFFFF
|
||||||
|
#define SHL_16_BITS 65536
|
||||||
|
|
||||||
|
|
||||||
bool fpga_acquisition::init()
|
bool fpga_acquisition::init()
|
||||||
{
|
{
|
||||||
@ -64,25 +76,34 @@ bool fpga_acquisition::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool fpga_acquisition::set_local_code(unsigned int PRN)
|
bool fpga_acquisition::set_local_code(uint32_t PRN)
|
||||||
{
|
{
|
||||||
// select the code with the chosen PRN
|
// select the code with the chosen PRN
|
||||||
fpga_acquisition::fpga_configure_acquisition_local_code(
|
fpga_acquisition::fpga_configure_acquisition_local_code(
|
||||||
&d_all_fft_codes[d_nsamples_total * (PRN - 1)]);
|
&d_all_fft_codes[d_nsamples_total * (PRN - 1)]);
|
||||||
|
|
||||||
|
//fpga_acquisition::fpga_configure_acquisition_local_code(
|
||||||
|
// &d_all_fft_codes[0]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fpga_acquisition::fpga_acquisition(std::string device_name,
|
fpga_acquisition::fpga_acquisition(std::string device_name,
|
||||||
unsigned int nsamples,
|
uint32_t nsamples,
|
||||||
unsigned int doppler_max,
|
uint32_t doppler_max,
|
||||||
unsigned int nsamples_total, long fs_in,
|
uint32_t nsamples_total, int64_t fs_in,
|
||||||
unsigned int sampled_ms, unsigned select_queue,
|
uint32_t sampled_ms, uint32_t select_queue,
|
||||||
lv_16sc_t *all_fft_codes)
|
lv_16sc_t *all_fft_codes)
|
||||||
{
|
{
|
||||||
unsigned int vector_length = nsamples_total * sampled_ms;
|
//printf("AAA- sampled_ms = %d\n ", sampled_ms);
|
||||||
|
|
||||||
|
uint32_t vector_length = nsamples_total; // * sampled_ms;
|
||||||
|
|
||||||
|
//printf("AAA- vector_length = %d\n ", vector_length);
|
||||||
// initial values
|
// initial values
|
||||||
d_device_name = device_name;
|
d_device_name = device_name;
|
||||||
|
//d_freq = freq;
|
||||||
d_fs_in = fs_in;
|
d_fs_in = fs_in;
|
||||||
d_vector_length = vector_length;
|
d_vector_length = vector_length;
|
||||||
d_nsamples = nsamples; // number of samples not including padding
|
d_nsamples = nsamples; // number of samples not including padding
|
||||||
@ -98,18 +119,20 @@ fpga_acquisition::fpga_acquisition(std::string device_name,
|
|||||||
if ((d_fd = open(d_device_name.c_str(), O_RDWR | O_SYNC)) == -1)
|
if ((d_fd = open(d_device_name.c_str(), O_RDWR | O_SYNC)) == -1)
|
||||||
{
|
{
|
||||||
LOG(WARNING) << "Cannot open deviceio" << d_device_name;
|
LOG(WARNING) << "Cannot open deviceio" << d_device_name;
|
||||||
|
std::cout << "Acq: cannot open deviceio" << d_device_name << std::endl;
|
||||||
}
|
}
|
||||||
d_map_base = reinterpret_cast<volatile unsigned *>(mmap(NULL, PAGE_SIZE,
|
d_map_base = reinterpret_cast<volatile uint32_t *>(mmap(NULL, PAGE_SIZE,
|
||||||
PROT_READ | PROT_WRITE, MAP_SHARED, d_fd, 0));
|
PROT_READ | PROT_WRITE, MAP_SHARED, d_fd, 0));
|
||||||
|
|
||||||
if (d_map_base == reinterpret_cast<void *>(-1))
|
if (d_map_base == reinterpret_cast<void *>(-1))
|
||||||
{
|
{
|
||||||
LOG(WARNING) << "Cannot map the FPGA acquisition module into user memory";
|
LOG(WARNING) << "Cannot map the FPGA acquisition module into user memory";
|
||||||
|
std::cout << "Acq: cannot map deviceio" << d_device_name << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sanity check : check test register
|
// sanity check : check test register
|
||||||
unsigned writeval = TEST_REG_SANITY_CHECK;
|
uint32_t writeval = TEST_REG_SANITY_CHECK;
|
||||||
unsigned readval;
|
uint32_t readval;
|
||||||
readval = fpga_acquisition::fpga_acquisition_test_register(writeval);
|
readval = fpga_acquisition::fpga_acquisition_test_register(writeval);
|
||||||
if (writeval != readval)
|
if (writeval != readval)
|
||||||
{
|
{
|
||||||
@ -118,6 +141,7 @@ fpga_acquisition::fpga_acquisition(std::string device_name,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG(INFO) << "Acquisition test register sanity check success!";
|
LOG(INFO) << "Acquisition test register sanity check success!";
|
||||||
|
//std::cout << "Acquisition test register sanity check success!" << std::endl;
|
||||||
}
|
}
|
||||||
fpga_acquisition::reset_acquisition();
|
fpga_acquisition::reset_acquisition();
|
||||||
DLOG(INFO) << "Acquisition FPGA class created";
|
DLOG(INFO) << "Acquisition FPGA class created";
|
||||||
@ -136,9 +160,9 @@ bool fpga_acquisition::free()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned fpga_acquisition::fpga_acquisition_test_register(unsigned writeval)
|
uint32_t fpga_acquisition::fpga_acquisition_test_register(uint32_t writeval)
|
||||||
{
|
{
|
||||||
unsigned readval;
|
uint32_t readval;
|
||||||
// write value to test register
|
// write value to test register
|
||||||
d_map_base[15] = writeval;
|
d_map_base[15] = writeval;
|
||||||
// read value from test register
|
// read value from test register
|
||||||
@ -150,35 +174,52 @@ unsigned fpga_acquisition::fpga_acquisition_test_register(unsigned writeval)
|
|||||||
|
|
||||||
void fpga_acquisition::fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[])
|
void fpga_acquisition::fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[])
|
||||||
{
|
{
|
||||||
unsigned short local_code;
|
uint32_t local_code;
|
||||||
unsigned int k, tmp, tmp2;
|
uint32_t k, tmp, tmp2;
|
||||||
unsigned int fft_data;
|
uint32_t fft_data;
|
||||||
|
|
||||||
// clear memory address counter
|
// clear memory address counter
|
||||||
d_map_base[4] = LOCAL_CODE_CLEAR_MEM;
|
//d_map_base[6] = LOCAL_CODE_CLEAR_MEM;
|
||||||
|
d_map_base[9] = LOCAL_CODE_CLEAR_MEM;
|
||||||
// write local code
|
// write local code
|
||||||
for (k = 0; k < d_vector_length; k++)
|
for (k = 0; k < d_vector_length; k++)
|
||||||
{
|
{
|
||||||
tmp = fft_local_code[k].real();
|
tmp = fft_local_code[k].real();
|
||||||
tmp2 = fft_local_code[k].imag();
|
tmp2 = fft_local_code[k].imag();
|
||||||
local_code = (tmp & SELECT_LSB) | ((tmp2 * SHL_8_BITS) & SELECT_MSB); // put together the real part and the imaginary part
|
//tmp = k;
|
||||||
fft_data = MEM_LOCAL_CODE_WR_ENABLE | (local_code & SELECT_16_BITS);
|
//tmp2 = k;
|
||||||
d_map_base[4] = fft_data;
|
|
||||||
|
//local_code = (tmp & SELECT_LSB) | ((tmp2 * SHL_8_BITS) & SELECT_MSB); // put together the real part and the imaginary part
|
||||||
|
//fft_data = MEM_LOCAL_CODE_WR_ENABLE | (local_code & SELECT_16_BITS);
|
||||||
|
//local_code = (tmp & SELECT_LSBits) | ((tmp2 * SHL_12_BITS) & SELECT_MSBbits); // put together the real part and the imaginary part
|
||||||
|
local_code = (tmp & SELECT_LSBits) | ((tmp2 * SHL_16_BITS) & SELECT_MSBbits); // put together the real part and the imaginary part
|
||||||
|
//fft_data = MEM_LOCAL_CODE_WR_ENABLE | (local_code & SELECT_24_BITS);
|
||||||
|
fft_data = local_code & SELECT_32_BITS;
|
||||||
|
d_map_base[6] = fft_data;
|
||||||
|
|
||||||
|
|
||||||
|
//printf("debug local code %d real = %d imag = %d local_code = %d fft_data = %d\n", k, tmp, tmp2, local_code, fft_data);
|
||||||
|
//printf("debug local code %d real = 0x%08X imag = 0x%08X local_code = 0x%08X fft_data = 0x%08X\n", k, tmp, tmp2, local_code, fft_data);
|
||||||
}
|
}
|
||||||
|
//printf("d_vector_length = %d\n", d_vector_length);
|
||||||
|
//while(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void fpga_acquisition::run_acquisition(void)
|
void fpga_acquisition::run_acquisition(void)
|
||||||
{
|
{
|
||||||
// enable interrupts
|
// enable interrupts
|
||||||
int reenable = 1;
|
int32_t reenable = 1;
|
||||||
write(d_fd, reinterpret_cast<void *>(&reenable), sizeof(int));
|
write(d_fd, reinterpret_cast<void *>(&reenable), sizeof(int32_t));
|
||||||
// launch the acquisition process
|
// launch the acquisition process
|
||||||
d_map_base[6] = LAUNCH_ACQUISITION; // writing anything to reg 6 launches the acquisition process
|
//printf("launchin acquisition ...\n");
|
||||||
|
d_map_base[8] = LAUNCH_ACQUISITION; // writing a 1 to reg 8 launches the acquisition process
|
||||||
|
|
||||||
int irq_count;
|
int32_t irq_count;
|
||||||
ssize_t nb;
|
ssize_t nb;
|
||||||
// wait for interrupt
|
// wait for interrupt
|
||||||
nb = read(d_fd, &irq_count, sizeof(irq_count));
|
nb = read(d_fd, &irq_count, sizeof(irq_count));
|
||||||
|
//printf("interrupt received\n");
|
||||||
if (nb != sizeof(irq_count))
|
if (nb != sizeof(irq_count))
|
||||||
{
|
{
|
||||||
printf("acquisition module Read failed to retrieve 4 bytes!\n");
|
printf("acquisition module Read failed to retrieve 4 bytes!\n");
|
||||||
@ -187,22 +228,15 @@ void fpga_acquisition::run_acquisition(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void fpga_acquisition::configure_acquisition()
|
void fpga_acquisition::set_doppler_sweep(uint32_t num_sweeps)
|
||||||
{
|
|
||||||
d_map_base[0] = d_select_queue;
|
|
||||||
d_map_base[1] = d_vector_length;
|
|
||||||
d_map_base[2] = d_nsamples;
|
|
||||||
d_map_base[5] = (int)log2((float)d_vector_length); // log2 FFTlength
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void fpga_acquisition::set_phase_step(unsigned int doppler_index)
|
|
||||||
{
|
{
|
||||||
float phase_step_rad_real;
|
float phase_step_rad_real;
|
||||||
float phase_step_rad_int_temp;
|
float phase_step_rad_int_temp;
|
||||||
int32_t phase_step_rad_int;
|
int32_t phase_step_rad_int;
|
||||||
int doppler = static_cast<int>(-d_doppler_max) + d_doppler_step * doppler_index;
|
//int32_t doppler = static_cast<int32_t>(-d_doppler_max) + d_doppler_step * doppler_index;
|
||||||
float phase_step_rad = GPS_TWO_PI * doppler / static_cast<float>(d_fs_in);
|
int32_t doppler = static_cast<int32_t>(-d_doppler_max);
|
||||||
|
//float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast<float>(d_fs_in);
|
||||||
|
float phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in);
|
||||||
// The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing
|
// The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing
|
||||||
// The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi)
|
// The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi)
|
||||||
// The FPGA also expects the phase to be negative since it produces cos(x) -j*sin(x)
|
// The FPGA also expects the phase to be negative since it produces cos(x) -j*sin(x)
|
||||||
@ -210,28 +244,153 @@ void fpga_acquisition::set_phase_step(unsigned int doppler_index)
|
|||||||
phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2);
|
phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2);
|
||||||
// avoid saturation of the fixed point representation in the fpga
|
// avoid saturation of the fixed point representation in the fpga
|
||||||
// (only the positive value can saturate due to the 2's complement representation)
|
// (only the positive value can saturate due to the 2's complement representation)
|
||||||
|
|
||||||
|
//printf("AAA phase_step_rad_real for initial doppler = %f\n", phase_step_rad_real);
|
||||||
if (phase_step_rad_real >= 1.0)
|
if (phase_step_rad_real >= 1.0)
|
||||||
{
|
{
|
||||||
phase_step_rad_real = MAX_PHASE_STEP_RAD;
|
phase_step_rad_real = MAX_PHASE_STEP_RAD;
|
||||||
}
|
}
|
||||||
|
//printf("AAA phase_step_rad_real for initial doppler after checking = %f\n", phase_step_rad_real);
|
||||||
phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2
|
phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2
|
||||||
phase_step_rad_int = (int32_t)(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings
|
phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings
|
||||||
|
//printf("AAA writing phase_step_rad_int for initial doppler = %d to d map base 3\n", phase_step_rad_int);
|
||||||
|
d_map_base[3] = phase_step_rad_int;
|
||||||
|
|
||||||
|
// repeat the calculation with the doppler step
|
||||||
|
doppler = static_cast<int32_t>(d_doppler_step);
|
||||||
|
phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in);
|
||||||
|
phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2);
|
||||||
|
//printf("AAA phase_step_rad_real for doppler step = %f\n", phase_step_rad_real);
|
||||||
|
if (phase_step_rad_real >= 1.0)
|
||||||
|
{
|
||||||
|
phase_step_rad_real = MAX_PHASE_STEP_RAD;
|
||||||
|
}
|
||||||
|
//printf("AAA phase_step_rad_real for doppler step after checking = %f\n", phase_step_rad_real);
|
||||||
|
phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2
|
||||||
|
phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings
|
||||||
|
//printf("AAA writing phase_step_rad_int for doppler step = %d to d map base 4\n", phase_step_rad_int);
|
||||||
|
d_map_base[4] = phase_step_rad_int;
|
||||||
|
//printf("AAA writing num sweeps to d map base 5 = %d\n", num_sweeps);
|
||||||
|
d_map_base[5] = num_sweeps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fpga_acquisition::set_doppler_sweep_debug(uint32_t num_sweeps, uint32_t doppler_index)
|
||||||
|
{
|
||||||
|
float phase_step_rad_real;
|
||||||
|
float phase_step_rad_int_temp;
|
||||||
|
int32_t phase_step_rad_int;
|
||||||
|
int32_t doppler = -static_cast<int32_t>(d_doppler_max) + d_doppler_step * doppler_index;
|
||||||
|
//int32_t doppler = static_cast<int32_t>(-d_doppler_max);
|
||||||
|
//float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast<float>(d_fs_in);
|
||||||
|
float phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in);
|
||||||
|
// The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing
|
||||||
|
// The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi)
|
||||||
|
// The FPGA also expects the phase to be negative since it produces cos(x) -j*sin(x)
|
||||||
|
// while the gnss-sdr software (volk_gnsssdr_s32f_sincos_32fc) generates cos(x) + j*sin(x)
|
||||||
|
phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2);
|
||||||
|
// avoid saturation of the fixed point representation in the fpga
|
||||||
|
// (only the positive value can saturate due to the 2's complement representation)
|
||||||
|
|
||||||
|
//printf("AAAh phase_step_rad_real for initial doppler = %f\n", phase_step_rad_real);
|
||||||
|
if (phase_step_rad_real >= 1.0)
|
||||||
|
{
|
||||||
|
phase_step_rad_real = MAX_PHASE_STEP_RAD;
|
||||||
|
}
|
||||||
|
//printf("AAAh phase_step_rad_real for initial doppler after checking = %f\n", phase_step_rad_real);
|
||||||
|
phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2
|
||||||
|
phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings
|
||||||
|
//printf("AAAh writing phase_step_rad_int for initial doppler = %d to d map base 3\n", phase_step_rad_int);
|
||||||
|
d_map_base[3] = phase_step_rad_int;
|
||||||
|
|
||||||
|
// repeat the calculation with the doppler step
|
||||||
|
doppler = static_cast<int32_t>(d_doppler_step);
|
||||||
|
phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in);
|
||||||
|
phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2);
|
||||||
|
//printf("AAAh phase_step_rad_real for doppler step = %f\n", phase_step_rad_real);
|
||||||
|
if (phase_step_rad_real >= 1.0)
|
||||||
|
{
|
||||||
|
phase_step_rad_real = MAX_PHASE_STEP_RAD;
|
||||||
|
}
|
||||||
|
//printf("AAAh phase_step_rad_real for doppler step after checking = %f\n", phase_step_rad_real);
|
||||||
|
phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2
|
||||||
|
phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings
|
||||||
|
//printf("AAAh writing phase_step_rad_int for doppler step = %d to d map base 4\n", phase_step_rad_int);
|
||||||
|
d_map_base[4] = phase_step_rad_int;
|
||||||
|
//printf("AAAh writing num sweeps to d map base 5 = %d\n", num_sweeps);
|
||||||
|
d_map_base[5] = num_sweeps;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void fpga_acquisition::configure_acquisition()
|
||||||
|
{
|
||||||
|
//printf("AAA d_select_queue = %d\n", d_select_queue);
|
||||||
|
d_map_base[0] = d_select_queue;
|
||||||
|
//printf("AAA writing d_vector_length = %d to d map base 1\n ", d_vector_length);
|
||||||
|
d_map_base[1] = d_vector_length;
|
||||||
|
//printf("AAA writing d_nsamples = %d to d map base 2\n ", d_nsamples);
|
||||||
|
d_map_base[2] = d_nsamples;
|
||||||
|
//printf("AAA writing LOG2 d_vector_length = %d to d map base 7\n ", (int)log2((float)d_vector_length));
|
||||||
|
d_map_base[7] = static_cast<int32_t>(log2(static_cast<float>(d_vector_length))); // log2 FFTlength
|
||||||
|
//printf("acquisition debug vector length = %d\n", d_vector_length);
|
||||||
|
//printf("acquisition debug vector length = %d\n", (int)log2((float)d_vector_length));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void fpga_acquisition::set_phase_step(uint32_t doppler_index)
|
||||||
|
{
|
||||||
|
float phase_step_rad_real;
|
||||||
|
float phase_step_rad_int_temp;
|
||||||
|
int32_t phase_step_rad_int;
|
||||||
|
int32_t doppler = -static_cast<int32_t>(d_doppler_max) + d_doppler_step * doppler_index;
|
||||||
|
//float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast<float>(d_fs_in);
|
||||||
|
float phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in);
|
||||||
|
// The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing
|
||||||
|
// The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi)
|
||||||
|
// The FPGA also expects the phase to be negative since it produces cos(x) -j*sin(x)
|
||||||
|
// while the gnss-sdr software (volk_gnsssdr_s32f_sincos_32fc) generates cos(x) + j*sin(x)
|
||||||
|
phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2);
|
||||||
|
// avoid saturation of the fixed point representation in the fpga
|
||||||
|
// (only the positive value can saturate due to the 2's complement representation)
|
||||||
|
//printf("AAA+ phase_step_rad_real = %f\n", phase_step_rad_real);
|
||||||
|
if (phase_step_rad_real >= 1.0)
|
||||||
|
{
|
||||||
|
phase_step_rad_real = MAX_PHASE_STEP_RAD;
|
||||||
|
}
|
||||||
|
//printf("AAA+ phase_step_rad_real after checking = %f\n", phase_step_rad_real);
|
||||||
|
phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2
|
||||||
|
phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings
|
||||||
|
//printf("writing phase_step_rad_int = %d to d_map_base 3\n", phase_step_rad_int);
|
||||||
d_map_base[3] = phase_step_rad_int;
|
d_map_base[3] = phase_step_rad_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void fpga_acquisition::read_acquisition_results(uint32_t *max_index,
|
void fpga_acquisition::read_acquisition_results(uint32_t *max_index,
|
||||||
float *max_magnitude, unsigned *initial_sample, float *power_sum)
|
float *max_magnitude, uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index)
|
||||||
{
|
{
|
||||||
unsigned readval = 0;
|
uint64_t initial_sample_tmp = 0;
|
||||||
|
|
||||||
|
uint32_t readval = 0;
|
||||||
|
uint64_t readval_long = 0;
|
||||||
|
uint64_t readval_long_shifted = 0;
|
||||||
readval = d_map_base[1];
|
readval = d_map_base[1];
|
||||||
*initial_sample = readval;
|
initial_sample_tmp = readval;
|
||||||
readval = d_map_base[2];
|
readval_long = d_map_base[2];
|
||||||
|
readval_long_shifted = readval_long << 32; // 2^32
|
||||||
|
initial_sample_tmp = initial_sample_tmp + readval_long_shifted; // 2^32
|
||||||
|
//printf("----------------------------------------------------------------> acq initial sample TOTAL = %llu\n", initial_sample_tmp);
|
||||||
|
*initial_sample = initial_sample_tmp;
|
||||||
|
readval = d_map_base[6];
|
||||||
*max_magnitude = static_cast<float>(readval);
|
*max_magnitude = static_cast<float>(readval);
|
||||||
|
//printf("read max_magnitude dmap 2 = %d\n", readval);
|
||||||
readval = d_map_base[4];
|
readval = d_map_base[4];
|
||||||
*power_sum = static_cast<float>(readval);
|
*power_sum = static_cast<float>(readval);
|
||||||
|
//printf("read power sum dmap 4 = %d\n", readval);
|
||||||
|
readval = d_map_base[5]; // read doppler index
|
||||||
|
*doppler_index = readval;
|
||||||
|
//printf("read doppler_index dmap 5 = %d\n", readval);
|
||||||
readval = d_map_base[3];
|
readval = d_map_base[3];
|
||||||
*max_index = readval;
|
*max_index = readval;
|
||||||
|
//printf("read max index dmap 3 = %d\n", readval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -249,7 +408,7 @@ void fpga_acquisition::unblock_samples()
|
|||||||
|
|
||||||
void fpga_acquisition::close_device()
|
void fpga_acquisition::close_device()
|
||||||
{
|
{
|
||||||
unsigned *aux = const_cast<unsigned *>(d_map_base);
|
uint32_t *aux = const_cast<uint32_t *>(d_map_base);
|
||||||
if (munmap(static_cast<void *>(aux), PAGE_SIZE) == -1)
|
if (munmap(static_cast<void *>(aux), PAGE_SIZE) == -1)
|
||||||
{
|
{
|
||||||
printf("Failed to unmap memory uio\n");
|
printf("Failed to unmap memory uio\n");
|
||||||
@ -260,5 +419,5 @@ void fpga_acquisition::close_device()
|
|||||||
|
|
||||||
void fpga_acquisition::reset_acquisition(void)
|
void fpga_acquisition::reset_acquisition(void)
|
||||||
{
|
{
|
||||||
d_map_base[6] = RESET_ACQUISITION; // writing a 2 to d_map_base[6] resets the multicorrelator
|
d_map_base[8] = RESET_ACQUISITION; // writing a 2 to d_map_base[8] resets the multicorrelator
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
#include <gnuradio/fft/fft.h>
|
#include <gnuradio/fft/fft.h>
|
||||||
#include <volk/volk.h>
|
#include <volk/volk.h>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Class that implements carrier wipe-off and correlators.
|
* \brief Class that implements carrier wipe-off and correlators.
|
||||||
@ -46,20 +47,24 @@ class fpga_acquisition
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
fpga_acquisition(std::string device_name,
|
fpga_acquisition(std::string device_name,
|
||||||
unsigned int nsamples,
|
uint32_t nsamples,
|
||||||
unsigned int doppler_max,
|
uint32_t doppler_max,
|
||||||
unsigned int nsamples_total, long fs_in,
|
uint32_t nsamples_total,
|
||||||
unsigned int sampled_ms, unsigned select_queue,
|
int64_t fs_in,
|
||||||
|
uint32_t sampled_ms,
|
||||||
|
uint32_t select_queue,
|
||||||
lv_16sc_t *all_fft_codes);
|
lv_16sc_t *all_fft_codes);
|
||||||
|
|
||||||
~fpga_acquisition();
|
~fpga_acquisition();
|
||||||
bool init();
|
bool init();
|
||||||
bool set_local_code(
|
bool set_local_code(uint32_t PRN);
|
||||||
unsigned int PRN);
|
|
||||||
bool free();
|
bool free();
|
||||||
|
void set_doppler_sweep(uint32_t num_sweeps);
|
||||||
|
void set_doppler_sweep_debug(uint32_t num_sweeps, uint32_t doppler_index);
|
||||||
void run_acquisition(void);
|
void run_acquisition(void);
|
||||||
void set_phase_step(unsigned int doppler_index);
|
void set_phase_step(uint32_t doppler_index);
|
||||||
void read_acquisition_results(uint32_t *max_index, float *max_magnitude,
|
void read_acquisition_results(uint32_t *max_index, float *max_magnitude,
|
||||||
unsigned *initial_sample, float *power_sum);
|
uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index);
|
||||||
void block_samples();
|
void block_samples();
|
||||||
void unblock_samples();
|
void unblock_samples();
|
||||||
|
|
||||||
@ -67,7 +72,7 @@ public:
|
|||||||
* \brief Set maximum Doppler grid search
|
* \brief Set maximum Doppler grid search
|
||||||
* \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
|
* \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
|
||||||
*/
|
*/
|
||||||
void set_doppler_max(unsigned int doppler_max)
|
void set_doppler_max(uint32_t doppler_max)
|
||||||
{
|
{
|
||||||
d_doppler_max = doppler_max;
|
d_doppler_max = doppler_max;
|
||||||
}
|
}
|
||||||
@ -76,26 +81,26 @@ public:
|
|||||||
* \brief Set Doppler steps for the grid search
|
* \brief Set Doppler steps for the grid search
|
||||||
* \param doppler_step - Frequency bin of the search grid [Hz].
|
* \param doppler_step - Frequency bin of the search grid [Hz].
|
||||||
*/
|
*/
|
||||||
void set_doppler_step(unsigned int doppler_step)
|
void set_doppler_step(uint32_t doppler_step)
|
||||||
{
|
{
|
||||||
d_doppler_step = doppler_step;
|
d_doppler_step = doppler_step;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
long d_fs_in;
|
int64_t d_fs_in;
|
||||||
// data related to the hardware module and the driver
|
// data related to the hardware module and the driver
|
||||||
int d_fd; // driver descriptor
|
int32_t d_fd; // driver descriptor
|
||||||
volatile unsigned *d_map_base; // driver memory map
|
volatile uint32_t *d_map_base; // driver memory map
|
||||||
lv_16sc_t *d_all_fft_codes; // memory that contains all the code ffts
|
lv_16sc_t *d_all_fft_codes; // memory that contains all the code ffts
|
||||||
unsigned int d_vector_length; // number of samples incluing padding and number of ms
|
uint32_t d_vector_length; // number of samples incluing padding and number of ms
|
||||||
unsigned int d_nsamples_total; // number of samples including padding
|
uint32_t d_nsamples_total; // number of samples including padding
|
||||||
unsigned int d_nsamples; // number of samples not including padding
|
uint32_t d_nsamples; // number of samples not including padding
|
||||||
unsigned int d_select_queue; // queue selection
|
uint32_t d_select_queue; // queue selection
|
||||||
std::string d_device_name; // HW device name
|
std::string d_device_name; // HW device name
|
||||||
unsigned int d_doppler_max; // max doppler
|
uint32_t d_doppler_max; // max doppler
|
||||||
unsigned int d_doppler_step; // doppler step
|
uint32_t d_doppler_step; // doppler step
|
||||||
// FPGA private functions
|
// FPGA private functions
|
||||||
unsigned fpga_acquisition_test_register(unsigned writeval);
|
uint32_t fpga_acquisition_test_register(uint32_t writeval);
|
||||||
void fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[]);
|
void fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[]);
|
||||||
void configure_acquisition();
|
void configure_acquisition();
|
||||||
void reset_acquisition(void);
|
void reset_acquisition(void);
|
||||||
|
@ -34,12 +34,12 @@
|
|||||||
#include "gnss_sdr_flags.h"
|
#include "gnss_sdr_flags.h"
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
using google::LogMessage;
|
using google::LogMessage;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Channel::Channel(ConfigurationInterface* configuration, unsigned int channel,
|
Channel::Channel(ConfigurationInterface* configuration, uint32_t channel,
|
||||||
std::shared_ptr<GNSSBlockInterface> pass_through, std::shared_ptr<AcquisitionInterface> acq,
|
std::shared_ptr<GNSSBlockInterface> pass_through, std::shared_ptr<AcquisitionInterface> acq,
|
||||||
std::shared_ptr<TrackingInterface> trk, std::shared_ptr<TelemetryDecoderInterface> nav,
|
std::shared_ptr<TrackingInterface> trk, std::shared_ptr<TelemetryDecoderInterface> nav,
|
||||||
std::string role, std::string implementation, gr::msg_queue::sptr queue)
|
std::string role, std::string implementation, gr::msg_queue::sptr queue)
|
||||||
@ -66,7 +66,7 @@ Channel::Channel(ConfigurationInterface* configuration, unsigned int channel,
|
|||||||
// Provide a warning to the user about the change of parameter name
|
// Provide a warning to the user about the change of parameter name
|
||||||
if (channel_ == 0)
|
if (channel_ == 0)
|
||||||
{
|
{
|
||||||
long int deprecation_warning = configuration->property("GNSS-SDR.internal_fs_hz", 0);
|
int64_t deprecation_warning = configuration->property("GNSS-SDR.internal_fs_hz", 0);
|
||||||
if (deprecation_warning != 0)
|
if (deprecation_warning != 0)
|
||||||
{
|
{
|
||||||
std::cout << "WARNING: The global parameter name GNSS-SDR.internal_fs_hz has been DEPRECATED." << std::endl;
|
std::cout << "WARNING: The global parameter name GNSS-SDR.internal_fs_hz has been DEPRECATED." << std::endl;
|
||||||
@ -76,9 +76,9 @@ Channel::Channel(ConfigurationInterface* configuration, unsigned int channel,
|
|||||||
|
|
||||||
// IMPORTANT: Do not change the order between set_doppler_step and set_threshold
|
// IMPORTANT: Do not change the order between set_doppler_step and set_threshold
|
||||||
|
|
||||||
unsigned int doppler_step = configuration->property("Acquisition_" + implementation_ + boost::lexical_cast<std::string>(channel_) + ".doppler_step", 0);
|
uint32_t 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);
|
if (doppler_step == 0) doppler_step = configuration->property("Acquisition_" + implementation_ + ".doppler_step", 500);
|
||||||
if (FLAGS_doppler_step != 0) doppler_step = static_cast<unsigned int>(FLAGS_doppler_step);
|
if (FLAGS_doppler_step != 0) doppler_step = static_cast<uint32_t>(FLAGS_doppler_step);
|
||||||
DLOG(INFO) << "Channel " << channel_ << " Doppler_step = " << doppler_step;
|
DLOG(INFO) << "Channel " << channel_ << " Doppler_step = " << doppler_step;
|
||||||
|
|
||||||
acq_->set_doppler_step(doppler_step);
|
acq_->set_doppler_step(doppler_step);
|
||||||
|
@ -60,7 +60,7 @@ class Channel : public ChannelInterface
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//! Constructor
|
//! Constructor
|
||||||
Channel(ConfigurationInterface* configuration, unsigned int channel,
|
Channel(ConfigurationInterface* configuration, uint32_t channel,
|
||||||
std::shared_ptr<GNSSBlockInterface> pass_through, std::shared_ptr<AcquisitionInterface> acq,
|
std::shared_ptr<GNSSBlockInterface> pass_through, std::shared_ptr<AcquisitionInterface> acq,
|
||||||
std::shared_ptr<TrackingInterface> trk, std::shared_ptr<TelemetryDecoderInterface> nav,
|
std::shared_ptr<TrackingInterface> trk, std::shared_ptr<TelemetryDecoderInterface> nav,
|
||||||
std::string role, std::string implementation, gr::msg_queue::sptr queue);
|
std::string role, std::string implementation, gr::msg_queue::sptr queue);
|
||||||
@ -99,7 +99,7 @@ private:
|
|||||||
std::string role_;
|
std::string role_;
|
||||||
std::string implementation_;
|
std::string implementation_;
|
||||||
bool flag_enable_fpga;
|
bool flag_enable_fpga;
|
||||||
unsigned int channel_;
|
uint32_t channel_;
|
||||||
Gnss_Synchro gnss_synchro_;
|
Gnss_Synchro gnss_synchro_;
|
||||||
Gnss_Signal gnss_signal_;
|
Gnss_Signal gnss_signal_;
|
||||||
bool connected_;
|
bool connected_;
|
||||||
|
@ -39,16 +39,16 @@ ChannelFsm::ChannelFsm()
|
|||||||
{
|
{
|
||||||
acq_ = nullptr;
|
acq_ = nullptr;
|
||||||
trk_ = nullptr;
|
trk_ = nullptr;
|
||||||
channel_ = 0;
|
channel_ = 0U;
|
||||||
d_state = 0;
|
d_state = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ChannelFsm::ChannelFsm(std::shared_ptr<AcquisitionInterface> acquisition) : acq_(acquisition)
|
ChannelFsm::ChannelFsm(std::shared_ptr<AcquisitionInterface> acquisition) : acq_(acquisition)
|
||||||
{
|
{
|
||||||
trk_ = nullptr;
|
trk_ = nullptr;
|
||||||
channel_ = 0;
|
channel_ = 0U;
|
||||||
d_state = 0;
|
d_state = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ bool ChannelFsm::Event_failed_tracking_standby()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_state = 0;
|
d_state = 0U;
|
||||||
notify_stop_tracking();
|
notify_stop_tracking();
|
||||||
DLOG(INFO) << "CH = " << channel_ << ". Ev failed tracking standby";
|
DLOG(INFO) << "CH = " << channel_ << ". Ev failed tracking standby";
|
||||||
return true;
|
return true;
|
||||||
@ -158,7 +158,7 @@ void ChannelFsm::set_queue(gr::msg_queue::sptr queue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ChannelFsm::set_channel(unsigned int channel)
|
void ChannelFsm::set_channel(uint32_t channel)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(mx);
|
std::lock_guard<std::mutex> lk(mx);
|
||||||
channel_ = channel;
|
channel_ = channel;
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "tracking_interface.h"
|
#include "tracking_interface.h"
|
||||||
#include "telemetry_decoder_interface.h"
|
#include "telemetry_decoder_interface.h"
|
||||||
#include <gnuradio/msg_queue.h>
|
#include <gnuradio/msg_queue.h>
|
||||||
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ public:
|
|||||||
void set_acquisition(std::shared_ptr<AcquisitionInterface> acquisition);
|
void set_acquisition(std::shared_ptr<AcquisitionInterface> acquisition);
|
||||||
void set_tracking(std::shared_ptr<TrackingInterface> tracking);
|
void set_tracking(std::shared_ptr<TrackingInterface> tracking);
|
||||||
void set_queue(gr::msg_queue::sptr queue);
|
void set_queue(gr::msg_queue::sptr queue);
|
||||||
void set_channel(unsigned int channel);
|
void set_channel(uint32_t channel);
|
||||||
|
|
||||||
//FSM EVENTS
|
//FSM EVENTS
|
||||||
bool Event_start_acquisition();
|
bool Event_start_acquisition();
|
||||||
@ -70,8 +71,8 @@ private:
|
|||||||
std::shared_ptr<AcquisitionInterface> acq_;
|
std::shared_ptr<AcquisitionInterface> acq_;
|
||||||
std::shared_ptr<TrackingInterface> trk_;
|
std::shared_ptr<TrackingInterface> trk_;
|
||||||
gr::msg_queue::sptr queue_;
|
gr::msg_queue::sptr queue_;
|
||||||
unsigned int channel_;
|
uint32_t channel_;
|
||||||
unsigned int d_state;
|
uint32_t d_state;
|
||||||
std::mutex mx;
|
std::mutex mx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <gnuradio/gr_complex.h>
|
#include <gnuradio/gr_complex.h>
|
||||||
#include <gnuradio/io_signature.h>
|
#include <gnuradio/io_signature.h>
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
using google::LogMessage;
|
using google::LogMessage;
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ void channel_msg_receiver_cc::msg_handler_events(pmt::pmt_t msg)
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
long int message = pmt::to_long(msg);
|
int64_t message = pmt::to_long(msg);
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
case 1: // positive acquisition
|
case 1: // positive acquisition
|
||||||
|
@ -43,38 +43,112 @@ using google::LogMessage;
|
|||||||
FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration, std::string role,
|
FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration, std::string role,
|
||||||
unsigned int in_streams, unsigned int out_streams) : config_(configuration), role_(role), in_streams_(in_streams), out_streams_(out_streams)
|
unsigned int in_streams, unsigned int out_streams) : config_(configuration), role_(role), in_streams_(in_streams), out_streams_(out_streams)
|
||||||
{
|
{
|
||||||
size_t item_size;
|
std::string default_input_item_type = "gr_complex";
|
||||||
(*this).init();
|
std::string default_output_item_type = "gr_complex";
|
||||||
int decimation_factor;
|
std::string default_taps_item_type = "float";
|
||||||
|
std::string default_dump_filename = "../data/input_filter.dat";
|
||||||
|
double default_intermediate_freq = 0.0;
|
||||||
|
double default_sampling_freq = 4000000.0;
|
||||||
|
int default_number_of_taps = 6;
|
||||||
|
unsigned int default_number_of_bands = 2;
|
||||||
|
std::vector<double> default_bands = {0.0, 0.4, 0.6, 1.0};
|
||||||
|
std::vector<double> default_ampl = {1.0, 1.0, 0.0, 0.0};
|
||||||
|
std::vector<double> default_error_w = {1.0, 1.0};
|
||||||
|
std::string default_filter_type = "bandpass";
|
||||||
|
int default_grid_density = 16;
|
||||||
int default_decimation_factor = 1;
|
int default_decimation_factor = 1;
|
||||||
decimation_factor = config_->property(role_ + ".decimation_factor", default_decimation_factor);
|
|
||||||
|
DLOG(INFO) << "role " << role_;
|
||||||
|
|
||||||
|
input_item_type_ = config_->property(role_ + ".input_item_type", default_input_item_type);
|
||||||
|
output_item_type_ = config_->property(role_ + ".output_item_type", default_output_item_type);
|
||||||
|
taps_item_type_ = config_->property(role_ + ".taps_item_type", default_taps_item_type);
|
||||||
|
dump_ = config_->property(role_ + ".dump", false);
|
||||||
|
dump_filename_ = config_->property(role_ + ".dump_filename", default_dump_filename);
|
||||||
|
intermediate_freq_ = config_->property(role_ + ".IF", default_intermediate_freq);
|
||||||
|
sampling_freq_ = config_->property(role_ + ".sampling_frequency", default_sampling_freq);
|
||||||
|
int number_of_taps = config_->property(role_ + ".number_of_taps", default_number_of_taps);
|
||||||
|
unsigned int number_of_bands = config_->property(role_ + ".number_of_bands", default_number_of_bands);
|
||||||
|
std::string filter_type = config_->property(role_ + ".filter_type", default_filter_type);
|
||||||
|
decimation_factor_ = config_->property(role_ + ".decimation_factor", default_decimation_factor);
|
||||||
|
|
||||||
|
if (filter_type.compare("lowpass") != 0)
|
||||||
|
{
|
||||||
|
std::vector<double> taps_d;
|
||||||
|
std::vector<double> bands;
|
||||||
|
std::vector<double> ampl;
|
||||||
|
std::vector<double> error_w;
|
||||||
|
std::string option;
|
||||||
|
double option_value;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < number_of_bands; i++)
|
||||||
|
{
|
||||||
|
option = ".band" + boost::lexical_cast<std::string>(i + 1) + "_begin";
|
||||||
|
option_value = config_->property(role_ + option, default_bands[i]);
|
||||||
|
bands.push_back(option_value);
|
||||||
|
|
||||||
|
option = ".band" + boost::lexical_cast<std::string>(i + 1) + "_end";
|
||||||
|
option_value = config_->property(role_ + option, default_bands[i]);
|
||||||
|
bands.push_back(option_value);
|
||||||
|
|
||||||
|
option = ".ampl" + boost::lexical_cast<std::string>(i + 1) + "_begin";
|
||||||
|
option_value = config_->property(role_ + option, default_bands[i]);
|
||||||
|
ampl.push_back(option_value);
|
||||||
|
|
||||||
|
option = ".ampl" + boost::lexical_cast<std::string>(i + 1) + "_end";
|
||||||
|
option_value = config_->property(role_ + option, default_bands[i]);
|
||||||
|
ampl.push_back(option_value);
|
||||||
|
|
||||||
|
option = ".band" + boost::lexical_cast<std::string>(i + 1) + "_error";
|
||||||
|
option_value = config_->property(role_ + option, default_bands[i]);
|
||||||
|
error_w.push_back(option_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int grid_density = config_->property(role_ + ".grid_density", default_grid_density);
|
||||||
|
taps_d = gr::filter::pm_remez(number_of_taps - 1, bands, ampl, error_w, filter_type, grid_density);
|
||||||
|
taps_.reserve(taps_d.size());
|
||||||
|
for (std::vector<double>::iterator it = taps_d.begin(); it != taps_d.end(); it++)
|
||||||
|
{
|
||||||
|
taps_.push_back(static_cast<float>(*it));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double default_bw = (sampling_freq_ / decimation_factor_) / 2;
|
||||||
|
double bw_ = config_->property(role_ + ".bw", default_bw);
|
||||||
|
double default_tw = bw_ / 10.0;
|
||||||
|
double tw_ = config_->property(role_ + ".tw", default_tw);
|
||||||
|
taps_ = gr::filter::firdes::low_pass(1.0, sampling_freq_, bw_, tw_);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t item_size;
|
||||||
|
|
||||||
if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("gr_complex") == 0) && (output_item_type_.compare("gr_complex") == 0))
|
if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("gr_complex") == 0) && (output_item_type_.compare("gr_complex") == 0))
|
||||||
{
|
{
|
||||||
item_size = sizeof(gr_complex); //output
|
item_size = sizeof(gr_complex); //output
|
||||||
input_size_ = sizeof(gr_complex); //input
|
input_size_ = sizeof(gr_complex); //input
|
||||||
freq_xlating_fir_filter_ccf_ = gr::filter::freq_xlating_fir_filter_ccf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_);
|
freq_xlating_fir_filter_ccf_ = gr::filter::freq_xlating_fir_filter_ccf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_);
|
||||||
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_ccf_->unique_id() << ")";
|
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_ccf_->unique_id() << ")";
|
||||||
}
|
}
|
||||||
else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("float") == 0) && (output_item_type_.compare("gr_complex") == 0))
|
else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("float") == 0) && (output_item_type_.compare("gr_complex") == 0))
|
||||||
{
|
{
|
||||||
item_size = sizeof(gr_complex);
|
item_size = sizeof(gr_complex);
|
||||||
input_size_ = sizeof(float); //input
|
input_size_ = sizeof(float); //input
|
||||||
freq_xlating_fir_filter_fcf_ = gr::filter::freq_xlating_fir_filter_fcf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_);
|
freq_xlating_fir_filter_fcf_ = gr::filter::freq_xlating_fir_filter_fcf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_);
|
||||||
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_fcf_->unique_id() << ")";
|
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_fcf_->unique_id() << ")";
|
||||||
}
|
}
|
||||||
else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("short") == 0) && (output_item_type_.compare("gr_complex") == 0))
|
else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("short") == 0) && (output_item_type_.compare("gr_complex") == 0))
|
||||||
{
|
{
|
||||||
item_size = sizeof(gr_complex);
|
item_size = sizeof(gr_complex);
|
||||||
input_size_ = sizeof(int16_t); //input
|
input_size_ = sizeof(int16_t); //input
|
||||||
freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_);
|
freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_);
|
||||||
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")";
|
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")";
|
||||||
}
|
}
|
||||||
else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("short") == 0) && (output_item_type_.compare("cshort") == 0))
|
else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("short") == 0) && (output_item_type_.compare("cshort") == 0))
|
||||||
{
|
{
|
||||||
item_size = sizeof(lv_16sc_t);
|
item_size = sizeof(lv_16sc_t);
|
||||||
input_size_ = sizeof(int16_t); //input
|
input_size_ = sizeof(int16_t); //input
|
||||||
freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_);
|
freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_);
|
||||||
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")";
|
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")";
|
||||||
complex_to_float_ = gr::blocks::complex_to_float::make();
|
complex_to_float_ = gr::blocks::complex_to_float::make();
|
||||||
float_to_short_1_ = gr::blocks::float_to_short::make();
|
float_to_short_1_ = gr::blocks::float_to_short::make();
|
||||||
@ -86,7 +160,7 @@ FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration
|
|||||||
item_size = sizeof(gr_complex);
|
item_size = sizeof(gr_complex);
|
||||||
input_size_ = sizeof(int8_t); //input
|
input_size_ = sizeof(int8_t); //input
|
||||||
gr_char_to_short_ = gr::blocks::char_to_short::make();
|
gr_char_to_short_ = gr::blocks::char_to_short::make();
|
||||||
freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_);
|
freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_);
|
||||||
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")";
|
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")";
|
||||||
}
|
}
|
||||||
else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("byte") == 0) && (output_item_type_.compare("cbyte") == 0))
|
else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("byte") == 0) && (output_item_type_.compare("cbyte") == 0))
|
||||||
@ -94,7 +168,7 @@ FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration
|
|||||||
item_size = sizeof(lv_8sc_t);
|
item_size = sizeof(lv_8sc_t);
|
||||||
input_size_ = sizeof(int8_t); //input
|
input_size_ = sizeof(int8_t); //input
|
||||||
gr_char_to_short_ = gr::blocks::char_to_short::make();
|
gr_char_to_short_ = gr::blocks::char_to_short::make();
|
||||||
freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_);
|
freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_);
|
||||||
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")";
|
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")";
|
||||||
complex_to_complex_byte_ = make_complex_float_to_complex_byte();
|
complex_to_complex_byte_ = make_complex_float_to_complex_byte();
|
||||||
}
|
}
|
||||||
@ -311,83 +385,3 @@ gr::basic_block_sptr FreqXlatingFirFilter::get_right_block()
|
|||||||
LOG(ERROR) << " Unknown input filter input/output item type conversion";
|
LOG(ERROR) << " Unknown input filter input/output item type conversion";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FreqXlatingFirFilter::init()
|
|
||||||
{
|
|
||||||
std::string default_input_item_type = "gr_complex";
|
|
||||||
std::string default_output_item_type = "gr_complex";
|
|
||||||
std::string default_taps_item_type = "float";
|
|
||||||
std::string default_dump_filename = "../data/input_filter.dat";
|
|
||||||
double default_intermediate_freq = 0.0;
|
|
||||||
double default_sampling_freq = 4000000.0;
|
|
||||||
int default_number_of_taps = 6;
|
|
||||||
unsigned int default_number_of_bands = 2;
|
|
||||||
std::vector<double> default_bands = {0.0, 0.4, 0.6, 1.0};
|
|
||||||
std::vector<double> default_ampl = {1.0, 1.0, 0.0, 0.0};
|
|
||||||
std::vector<double> default_error_w = {1.0, 1.0};
|
|
||||||
std::string default_filter_type = "bandpass";
|
|
||||||
int default_grid_density = 16;
|
|
||||||
|
|
||||||
DLOG(INFO) << "role " << role_;
|
|
||||||
|
|
||||||
input_item_type_ = config_->property(role_ + ".input_item_type", default_input_item_type);
|
|
||||||
output_item_type_ = config_->property(role_ + ".output_item_type", default_output_item_type);
|
|
||||||
taps_item_type_ = config_->property(role_ + ".taps_item_type", default_taps_item_type);
|
|
||||||
dump_ = config_->property(role_ + ".dump", false);
|
|
||||||
dump_filename_ = config_->property(role_ + ".dump_filename", default_dump_filename);
|
|
||||||
intermediate_freq_ = config_->property(role_ + ".IF", default_intermediate_freq);
|
|
||||||
sampling_freq_ = config_->property(role_ + ".sampling_frequency", default_sampling_freq);
|
|
||||||
int number_of_taps = config_->property(role_ + ".number_of_taps", default_number_of_taps);
|
|
||||||
unsigned int number_of_bands = config_->property(role_ + ".number_of_bands", default_number_of_bands);
|
|
||||||
std::string filter_type = config_->property(role_ + ".filter_type", default_filter_type);
|
|
||||||
|
|
||||||
if (filter_type.compare("lowpass") != 0)
|
|
||||||
{
|
|
||||||
std::vector<double> taps_d;
|
|
||||||
std::vector<double> bands;
|
|
||||||
std::vector<double> ampl;
|
|
||||||
std::vector<double> error_w;
|
|
||||||
std::string option;
|
|
||||||
double option_value;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < number_of_bands; i++)
|
|
||||||
{
|
|
||||||
option = ".band" + boost::lexical_cast<std::string>(i + 1) + "_begin";
|
|
||||||
option_value = config_->property(role_ + option, default_bands[i]);
|
|
||||||
bands.push_back(option_value);
|
|
||||||
|
|
||||||
option = ".band" + boost::lexical_cast<std::string>(i + 1) + "_end";
|
|
||||||
option_value = config_->property(role_ + option, default_bands[i]);
|
|
||||||
bands.push_back(option_value);
|
|
||||||
|
|
||||||
option = ".ampl" + boost::lexical_cast<std::string>(i + 1) + "_begin";
|
|
||||||
option_value = config_->property(role_ + option, default_bands[i]);
|
|
||||||
ampl.push_back(option_value);
|
|
||||||
|
|
||||||
option = ".ampl" + boost::lexical_cast<std::string>(i + 1) + "_end";
|
|
||||||
option_value = config_->property(role_ + option, default_bands[i]);
|
|
||||||
ampl.push_back(option_value);
|
|
||||||
|
|
||||||
option = ".band" + boost::lexical_cast<std::string>(i + 1) + "_error";
|
|
||||||
option_value = config_->property(role_ + option, default_bands[i]);
|
|
||||||
error_w.push_back(option_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
int grid_density = config_->property(role_ + ".grid_density", default_grid_density);
|
|
||||||
taps_d = gr::filter::pm_remez(number_of_taps - 1, bands, ampl, error_w, filter_type, grid_density);
|
|
||||||
taps_.reserve(taps_d.size());
|
|
||||||
for (std::vector<double>::iterator it = taps_d.begin(); it != taps_d.end(); it++)
|
|
||||||
{
|
|
||||||
taps_.push_back(static_cast<float>(*it));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
double default_bw = 2000000.0;
|
|
||||||
double bw_ = config_->property(role_ + ".bw", default_bw);
|
|
||||||
double default_tw = bw_ / 10.0;
|
|
||||||
double tw_ = config_->property(role_ + ".tw", default_tw);
|
|
||||||
taps_ = gr::filter::firdes::low_pass(1.0, sampling_freq_, bw_, tw_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -95,6 +95,7 @@ private:
|
|||||||
gr::filter::freq_xlating_fir_filter_fcf::sptr freq_xlating_fir_filter_fcf_;
|
gr::filter::freq_xlating_fir_filter_fcf::sptr freq_xlating_fir_filter_fcf_;
|
||||||
gr::filter::freq_xlating_fir_filter_scf::sptr freq_xlating_fir_filter_scf_;
|
gr::filter::freq_xlating_fir_filter_scf::sptr freq_xlating_fir_filter_scf_;
|
||||||
ConfigurationInterface* config_;
|
ConfigurationInterface* config_;
|
||||||
|
int decimation_factor_;
|
||||||
bool dump_;
|
bool dump_;
|
||||||
std::string dump_filename_;
|
std::string dump_filename_;
|
||||||
std::string input_item_type_;
|
std::string input_item_type_;
|
||||||
@ -114,7 +115,6 @@ private:
|
|||||||
gr::blocks::float_to_short::sptr float_to_short_2_;
|
gr::blocks::float_to_short::sptr float_to_short_2_;
|
||||||
short_x2_to_cshort_sptr short_x2_to_cshort_;
|
short_x2_to_cshort_sptr short_x2_to_cshort_;
|
||||||
complex_float_to_complex_byte_sptr complex_to_complex_byte_;
|
complex_float_to_complex_byte_sptr complex_to_complex_byte_;
|
||||||
void init();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GNSS_SDR_FREQ_XLATING_FIR_FILTER_H_
|
#endif // GNSS_SDR_FREQ_XLATING_FIR_FILTER_H_
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
using google::LogMessage;
|
using google::LogMessage;
|
||||||
|
|
||||||
notch_sptr make_notch_filter(float pfa, float p_c_factor,
|
notch_sptr make_notch_filter(float pfa, float p_c_factor,
|
||||||
int length_, int n_segments_est, int n_segments_reset)
|
int32_t length_, int32_t n_segments_est, int32_t n_segments_reset)
|
||||||
{
|
{
|
||||||
return notch_sptr(new Notch(pfa, p_c_factor, length_, n_segments_est, n_segments_reset));
|
return notch_sptr(new Notch(pfa, p_c_factor, length_, n_segments_est, n_segments_reset));
|
||||||
}
|
}
|
||||||
@ -47,31 +47,31 @@ notch_sptr make_notch_filter(float pfa, float p_c_factor,
|
|||||||
|
|
||||||
Notch::Notch(float pfa,
|
Notch::Notch(float pfa,
|
||||||
float p_c_factor,
|
float p_c_factor,
|
||||||
int length_,
|
int32_t length_,
|
||||||
int n_segments_est,
|
int32_t n_segments_est,
|
||||||
int n_segments_reset) : gr::block("Notch",
|
int32_t n_segments_reset) : gr::block("Notch",
|
||||||
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
||||||
gr::io_signature::make(1, 1, sizeof(gr_complex)))
|
gr::io_signature::make(1, 1, sizeof(gr_complex)))
|
||||||
{
|
{
|
||||||
const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex);
|
const int32_t alignment_multiple = volk_get_alignment() / sizeof(gr_complex);
|
||||||
set_alignment(std::max(1, alignment_multiple));
|
set_alignment(std::max(1, alignment_multiple));
|
||||||
set_history(2);
|
set_history(2);
|
||||||
this->pfa = pfa;
|
this->pfa = pfa;
|
||||||
noise_pow_est = 0.0;
|
noise_pow_est = 0.0;
|
||||||
this->p_c_factor = gr_complex(p_c_factor, 0);
|
this->p_c_factor = gr_complex(p_c_factor, 0.0);
|
||||||
this->length_ = length_; // Set the number of samples per segment
|
this->length_ = length_; // Set the number of samples per segment
|
||||||
filter_state_ = false; // Initial state of the filter
|
filter_state_ = false; // Initial state of the filter
|
||||||
n_deg_fred = 2 * length_; // Number of dregrees of freedom
|
n_deg_fred = 2 * length_; // Number of dregrees of freedom
|
||||||
n_segments = 0;
|
n_segments = 0;
|
||||||
this->n_segments_est = n_segments_est; // Set the number of segments for noise power estimation
|
this->n_segments_est = n_segments_est; // Set the number of segments for noise power estimation
|
||||||
this->n_segments_reset = n_segments_reset; // Set the period (in segments) when the noise power is estimated
|
this->n_segments_reset = n_segments_reset; // Set the period (in segments) when the noise power is estimated
|
||||||
z_0 = gr_complex(0, 0);
|
z_0 = gr_complex(0.0, 0.0);
|
||||||
boost::math::chi_squared_distribution<float> my_dist_(n_deg_fred);
|
boost::math::chi_squared_distribution<float> my_dist_(n_deg_fred);
|
||||||
thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa));
|
thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa));
|
||||||
c_samples = static_cast<gr_complex *>(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment()));
|
c_samples = static_cast<gr_complex *>(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment()));
|
||||||
angle_ = static_cast<float *>(volk_malloc(length_ * sizeof(float), volk_get_alignment()));
|
angle_ = static_cast<float *>(volk_malloc(length_ * sizeof(float), volk_get_alignment()));
|
||||||
power_spect = static_cast<float *>(volk_malloc(length_ * sizeof(float), volk_get_alignment()));
|
power_spect = static_cast<float *>(volk_malloc(length_ * sizeof(float), volk_get_alignment()));
|
||||||
last_out = gr_complex(0, 0);
|
last_out = gr_complex(0.0, 0.0);
|
||||||
d_fft = std::unique_ptr<gr::fft::fft_complex>(new gr::fft::fft_complex(length_, true));
|
d_fft = std::unique_ptr<gr::fft::fft_complex>(new gr::fft::fft_complex(length_, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ Notch::~Notch()
|
|||||||
|
|
||||||
void Notch::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required)
|
void Notch::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required)
|
||||||
{
|
{
|
||||||
for (unsigned int aux = 0; aux < ninput_items_required.size(); aux++)
|
for (uint32_t aux = 0; aux < ninput_items_required.size(); aux++)
|
||||||
{
|
{
|
||||||
ninput_items_required[aux] = length_;
|
ninput_items_required[aux] = length_;
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@ void Notch::forecast(int noutput_items __attribute__((unused)), gr_vector_int &n
|
|||||||
int Notch::general_work(int noutput_items, gr_vector_int &ninput_items __attribute__((unused)),
|
int Notch::general_work(int noutput_items, gr_vector_int &ninput_items __attribute__((unused)),
|
||||||
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)
|
||||||
{
|
{
|
||||||
int index_out = 0;
|
int32_t index_out = 0;
|
||||||
float sig2dB = 0.0;
|
float sig2dB = 0.0;
|
||||||
float sig2lin = 0.0;
|
float sig2lin = 0.0;
|
||||||
lv_32fc_t dot_prod_;
|
lv_32fc_t dot_prod_;
|
||||||
@ -127,7 +127,7 @@ int Notch::general_work(int noutput_items, gr_vector_int &ninput_items __attribu
|
|||||||
}
|
}
|
||||||
volk_32fc_x2_multiply_conjugate_32fc(c_samples, in, (in - 1), length_);
|
volk_32fc_x2_multiply_conjugate_32fc(c_samples, in, (in - 1), length_);
|
||||||
volk_32fc_s32f_atan2_32f(angle_, c_samples, static_cast<float>(1.0), length_);
|
volk_32fc_s32f_atan2_32f(angle_, c_samples, static_cast<float>(1.0), length_);
|
||||||
for (int aux = 0; aux < length_; aux++)
|
for (int32_t aux = 0; aux < length_; aux++)
|
||||||
{
|
{
|
||||||
z_0 = std::exp(gr_complex(0, 1) * (*(angle_ + aux)));
|
z_0 = std::exp(gr_complex(0, 1) * (*(angle_ + aux)));
|
||||||
*(out + aux) = *(in + aux) - z_0 * (*(in + aux - 1)) + p_c_factor * z_0 * last_out;
|
*(out + aux) = *(in + aux) - z_0 * (*(in + aux - 1)) + p_c_factor * z_0 * last_out;
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <gnuradio/block.h>
|
#include <gnuradio/block.h>
|
||||||
#include <gnuradio/fft/fft.h>
|
#include <gnuradio/fft/fft.h>
|
||||||
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class Notch;
|
class Notch;
|
||||||
@ -41,7 +42,7 @@ class Notch;
|
|||||||
typedef boost::shared_ptr<Notch> notch_sptr;
|
typedef boost::shared_ptr<Notch> notch_sptr;
|
||||||
|
|
||||||
notch_sptr make_notch_filter(float pfa, float p_c_factor,
|
notch_sptr make_notch_filter(float pfa, float p_c_factor,
|
||||||
int length_, int n_segments_est, int n_segments_reset);
|
int32_t length_, int32_t n_segments_est, int32_t n_segments_reset);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief This class implements a real-time software-defined multi state notch filter
|
* \brief This class implements a real-time software-defined multi state notch filter
|
||||||
@ -53,11 +54,11 @@ private:
|
|||||||
float pfa;
|
float pfa;
|
||||||
float noise_pow_est;
|
float noise_pow_est;
|
||||||
float thres_;
|
float thres_;
|
||||||
int length_;
|
int32_t length_;
|
||||||
int n_deg_fred;
|
int32_t n_deg_fred;
|
||||||
unsigned int n_segments;
|
uint32_t n_segments;
|
||||||
unsigned int n_segments_est;
|
uint32_t n_segments_est;
|
||||||
unsigned int n_segments_reset;
|
uint32_t n_segments_reset;
|
||||||
bool filter_state_;
|
bool filter_state_;
|
||||||
gr_complex last_out;
|
gr_complex last_out;
|
||||||
gr_complex z_0;
|
gr_complex z_0;
|
||||||
@ -68,7 +69,7 @@ private:
|
|||||||
std::unique_ptr<gr::fft::fft_complex> d_fft;
|
std::unique_ptr<gr::fft::fft_complex> d_fft;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Notch(float pfa, float p_c_factor, int length_, int n_segments_est, int n_segments_reset);
|
Notch(float pfa, float p_c_factor, int32_t length_, int32_t n_segments_est, int32_t n_segments_reset);
|
||||||
|
|
||||||
~Notch();
|
~Notch();
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
using google::LogMessage;
|
using google::LogMessage;
|
||||||
|
|
||||||
notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff)
|
notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int32_t length_, int32_t n_segments_est, int32_t n_segments_reset, int32_t n_segments_coeff)
|
||||||
{
|
{
|
||||||
return notch_lite_sptr(new NotchLite(p_c_factor, pfa, length_, n_segments_est, n_segments_reset, n_segments_coeff));
|
return notch_lite_sptr(new NotchLite(p_c_factor, pfa, length_, n_segments_est, n_segments_reset, n_segments_coeff));
|
||||||
}
|
}
|
||||||
@ -46,17 +46,17 @@ notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_,
|
|||||||
|
|
||||||
NotchLite::NotchLite(float p_c_factor,
|
NotchLite::NotchLite(float p_c_factor,
|
||||||
float pfa,
|
float pfa,
|
||||||
int length_,
|
int32_t length_,
|
||||||
int n_segments_est,
|
int32_t n_segments_est,
|
||||||
int n_segments_reset,
|
int32_t n_segments_reset,
|
||||||
int n_segments_coeff) : gr::block("NotchLite",
|
int32_t n_segments_coeff) : gr::block("NotchLite",
|
||||||
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
||||||
gr::io_signature::make(1, 1, sizeof(gr_complex)))
|
gr::io_signature::make(1, 1, sizeof(gr_complex)))
|
||||||
{
|
{
|
||||||
const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex);
|
const int32_t alignment_multiple = volk_get_alignment() / sizeof(gr_complex);
|
||||||
set_alignment(std::max(1, alignment_multiple));
|
set_alignment(std::max(1, alignment_multiple));
|
||||||
set_history(2);
|
set_history(2);
|
||||||
this->p_c_factor = gr_complex(p_c_factor, 0);
|
this->p_c_factor = gr_complex(p_c_factor, 0.0);
|
||||||
this->n_segments_est = n_segments_est;
|
this->n_segments_est = n_segments_est;
|
||||||
this->n_segments_reset = n_segments_reset;
|
this->n_segments_reset = n_segments_reset;
|
||||||
this->n_segments_coeff_reset = n_segments_coeff;
|
this->n_segments_coeff_reset = n_segments_coeff;
|
||||||
@ -68,12 +68,12 @@ NotchLite::NotchLite(float p_c_factor,
|
|||||||
n_deg_fred = 2 * length_;
|
n_deg_fred = 2 * length_;
|
||||||
noise_pow_est = 0.0;
|
noise_pow_est = 0.0;
|
||||||
filter_state_ = false;
|
filter_state_ = false;
|
||||||
z_0 = gr_complex(0, 0);
|
z_0 = gr_complex(0.0, 0.0);
|
||||||
last_out = gr_complex(0, 0);
|
last_out = gr_complex(0.0, 0.0);
|
||||||
boost::math::chi_squared_distribution<float> my_dist_(n_deg_fred);
|
boost::math::chi_squared_distribution<float> my_dist_(n_deg_fred);
|
||||||
thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa));
|
thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa));
|
||||||
c_samples1 = gr_complex(0, 0);
|
c_samples1 = gr_complex(0.0, 0.0);
|
||||||
c_samples2 = gr_complex(0, 0);
|
c_samples2 = gr_complex(0.0, 0.0);
|
||||||
angle1 = 0.0;
|
angle1 = 0.0;
|
||||||
angle2 = 0.0;
|
angle2 = 0.0;
|
||||||
power_spect = static_cast<float *>(volk_malloc(length_ * sizeof(float), volk_get_alignment()));
|
power_spect = static_cast<float *>(volk_malloc(length_ * sizeof(float), volk_get_alignment()));
|
||||||
@ -89,7 +89,7 @@ NotchLite::~NotchLite()
|
|||||||
|
|
||||||
void NotchLite::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required)
|
void NotchLite::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required)
|
||||||
{
|
{
|
||||||
for (unsigned int aux = 0; aux < ninput_items_required.size(); aux++)
|
for (uint32_t aux = 0; aux < ninput_items_required.size(); aux++)
|
||||||
{
|
{
|
||||||
ninput_items_required[aux] = length_;
|
ninput_items_required[aux] = length_;
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@ void NotchLite::forecast(int noutput_items __attribute__((unused)), gr_vector_in
|
|||||||
int NotchLite::general_work(int noutput_items, gr_vector_int &ninput_items __attribute__((unused)),
|
int NotchLite::general_work(int noutput_items, gr_vector_int &ninput_items __attribute__((unused)),
|
||||||
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)
|
||||||
{
|
{
|
||||||
int index_out = 0;
|
int32_t index_out = 0;
|
||||||
float sig2dB = 0.0;
|
float sig2dB = 0.0;
|
||||||
float sig2lin = 0.0;
|
float sig2lin = 0.0;
|
||||||
lv_32fc_t dot_prod_;
|
lv_32fc_t dot_prod_;
|
||||||
@ -138,7 +138,7 @@ int NotchLite::general_work(int noutput_items, gr_vector_int &ninput_items __att
|
|||||||
float angle_ = (angle1 + angle2) / 2.0;
|
float angle_ = (angle1 + angle2) / 2.0;
|
||||||
z_0 = std::exp(gr_complex(0, 1) * angle_);
|
z_0 = std::exp(gr_complex(0, 1) * angle_);
|
||||||
}
|
}
|
||||||
for (int aux = 0; aux < length_; aux++)
|
for (int32_t aux = 0; aux < length_; aux++)
|
||||||
{
|
{
|
||||||
*(out + aux) = *(in + aux) - z_0 * (*(in + aux - 1)) + p_c_factor * z_0 * last_out;
|
*(out + aux) = *(in + aux) - z_0 * (*(in + aux - 1)) + p_c_factor * z_0 * last_out;
|
||||||
last_out = *(out + aux);
|
last_out = *(out + aux);
|
||||||
|
@ -34,13 +34,14 @@
|
|||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <gnuradio/block.h>
|
#include <gnuradio/block.h>
|
||||||
#include <gnuradio/fft/fft.h>
|
#include <gnuradio/fft/fft.h>
|
||||||
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class NotchLite;
|
class NotchLite;
|
||||||
|
|
||||||
typedef boost::shared_ptr<NotchLite> notch_lite_sptr;
|
typedef boost::shared_ptr<NotchLite> notch_lite_sptr;
|
||||||
|
|
||||||
notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff);
|
notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int32_t length_, int32_t n_segments_est, int32_t n_segments_reset, int32_t n_segments_coeff);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief This class implements a real-time software-defined multi state notch filter light version
|
* \brief This class implements a real-time software-defined multi state notch filter light version
|
||||||
@ -49,13 +50,13 @@ notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_,
|
|||||||
class NotchLite : public gr::block
|
class NotchLite : public gr::block
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int length_;
|
int32_t length_;
|
||||||
int n_segments;
|
int32_t n_segments;
|
||||||
int n_segments_est;
|
int32_t n_segments_est;
|
||||||
int n_segments_reset;
|
int32_t n_segments_reset;
|
||||||
int n_segments_coeff_reset;
|
int32_t n_segments_coeff_reset;
|
||||||
int n_segments_coeff;
|
int32_t n_segments_coeff;
|
||||||
int n_deg_fred;
|
int32_t n_deg_fred;
|
||||||
float pfa;
|
float pfa;
|
||||||
float thres_;
|
float thres_;
|
||||||
float noise_pow_est;
|
float noise_pow_est;
|
||||||
@ -71,7 +72,7 @@ private:
|
|||||||
std::unique_ptr<gr::fft::fft_complex> d_fft;
|
std::unique_ptr<gr::fft::fft_complex> d_fft;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NotchLite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff);
|
NotchLite(float p_c_factor, float pfa, int32_t length_, int32_t n_segments_est, int32_t n_segments_reset, int32_t n_segments_coeff);
|
||||||
|
|
||||||
~NotchLite();
|
~NotchLite();
|
||||||
|
|
||||||
|
@ -37,21 +37,21 @@
|
|||||||
|
|
||||||
using google::LogMessage;
|
using google::LogMessage;
|
||||||
|
|
||||||
pulse_blanking_cc_sptr make_pulse_blanking_cc(float pfa, int length_,
|
pulse_blanking_cc_sptr make_pulse_blanking_cc(float pfa, int32_t length_,
|
||||||
int n_segments_est, int n_segments_reset)
|
int32_t n_segments_est, int32_t n_segments_reset)
|
||||||
{
|
{
|
||||||
return pulse_blanking_cc_sptr(new pulse_blanking_cc(pfa, length_, n_segments_est, n_segments_reset));
|
return pulse_blanking_cc_sptr(new pulse_blanking_cc(pfa, length_, n_segments_est, n_segments_reset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pulse_blanking_cc::pulse_blanking_cc(float pfa,
|
pulse_blanking_cc::pulse_blanking_cc(float pfa,
|
||||||
int length_,
|
int32_t length_,
|
||||||
int n_segments_est,
|
int32_t n_segments_est,
|
||||||
int n_segments_reset) : gr::block("pulse_blanking_cc",
|
int32_t n_segments_reset) : gr::block("pulse_blanking_cc",
|
||||||
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
||||||
gr::io_signature::make(1, 1, sizeof(gr_complex)))
|
gr::io_signature::make(1, 1, sizeof(gr_complex)))
|
||||||
{
|
{
|
||||||
const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex);
|
const int32_t alignment_multiple = volk_get_alignment() / sizeof(gr_complex);
|
||||||
set_alignment(std::max(1, alignment_multiple));
|
set_alignment(std::max(1, alignment_multiple));
|
||||||
this->pfa = pfa;
|
this->pfa = pfa;
|
||||||
this->length_ = length_;
|
this->length_ = length_;
|
||||||
@ -64,9 +64,9 @@ pulse_blanking_cc::pulse_blanking_cc(float pfa,
|
|||||||
boost::math::chi_squared_distribution<float> my_dist_(n_deg_fred);
|
boost::math::chi_squared_distribution<float> my_dist_(n_deg_fred);
|
||||||
thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa));
|
thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa));
|
||||||
zeros_ = static_cast<gr_complex *>(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment()));
|
zeros_ = static_cast<gr_complex *>(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment()));
|
||||||
for (int aux = 0; aux < length_; aux++)
|
for (int32_t aux = 0; aux < length_; aux++)
|
||||||
{
|
{
|
||||||
zeros_[aux] = gr_complex(0, 0);
|
zeros_[aux] = gr_complex(0.0, 0.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ pulse_blanking_cc::~pulse_blanking_cc()
|
|||||||
|
|
||||||
void pulse_blanking_cc::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required)
|
void pulse_blanking_cc::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required)
|
||||||
{
|
{
|
||||||
for (unsigned int aux = 0; aux < ninput_items_required.size(); aux++)
|
for (uint32_t aux = 0; aux < ninput_items_required.size(); aux++)
|
||||||
{
|
{
|
||||||
ninput_items_required[aux] = length_;
|
ninput_items_required[aux] = length_;
|
||||||
}
|
}
|
||||||
@ -93,7 +93,7 @@ int pulse_blanking_cc::general_work(int noutput_items, gr_vector_int &ninput_ite
|
|||||||
gr_complex *out = reinterpret_cast<gr_complex *>(output_items[0]);
|
gr_complex *out = reinterpret_cast<gr_complex *>(output_items[0]);
|
||||||
float *magnitude = static_cast<float *>(volk_malloc(noutput_items * sizeof(float), volk_get_alignment()));
|
float *magnitude = static_cast<float *>(volk_malloc(noutput_items * sizeof(float), volk_get_alignment()));
|
||||||
volk_32fc_magnitude_squared_32f(magnitude, in, noutput_items);
|
volk_32fc_magnitude_squared_32f(magnitude, in, noutput_items);
|
||||||
int sample_index = 0;
|
int32_t sample_index = 0;
|
||||||
float segment_energy;
|
float segment_energy;
|
||||||
while ((sample_index + length_) < noutput_items)
|
while ((sample_index + length_) < noutput_items)
|
||||||
{
|
{
|
||||||
|
@ -33,22 +33,23 @@
|
|||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <gnuradio/block.h>
|
#include <gnuradio/block.h>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
class pulse_blanking_cc;
|
class pulse_blanking_cc;
|
||||||
|
|
||||||
typedef boost::shared_ptr<pulse_blanking_cc> pulse_blanking_cc_sptr;
|
typedef boost::shared_ptr<pulse_blanking_cc> pulse_blanking_cc_sptr;
|
||||||
|
|
||||||
pulse_blanking_cc_sptr make_pulse_blanking_cc(float pfa, int length_, int n_segments_est, int n_segments_reset);
|
pulse_blanking_cc_sptr make_pulse_blanking_cc(float pfa, int32_t length_, int32_t n_segments_est, int32_t n_segments_reset);
|
||||||
|
|
||||||
|
|
||||||
class pulse_blanking_cc : public gr::block
|
class pulse_blanking_cc : public gr::block
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int length_;
|
int32_t length_;
|
||||||
int n_segments;
|
int32_t n_segments;
|
||||||
int n_segments_est;
|
int32_t n_segments_est;
|
||||||
int n_segments_reset;
|
int32_t n_segments_reset;
|
||||||
int n_deg_fred;
|
int32_t n_deg_fred;
|
||||||
bool last_filtered;
|
bool last_filtered;
|
||||||
float noise_power_estimation;
|
float noise_power_estimation;
|
||||||
float thres_;
|
float thres_;
|
||||||
@ -56,7 +57,7 @@ private:
|
|||||||
gr_complex *zeros_;
|
gr_complex *zeros_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
pulse_blanking_cc(float pfa, int length_, int n_segments_est, int n_segments_reset);
|
pulse_blanking_cc(float pfa, int32_t length_, int32_t n_segments_est, int32_t n_segments_reset);
|
||||||
|
|
||||||
~pulse_blanking_cc();
|
~pulse_blanking_cc();
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ if(ENABLE_FPGA)
|
|||||||
conjugate_cc.cc
|
conjugate_cc.cc
|
||||||
conjugate_sc.cc
|
conjugate_sc.cc
|
||||||
conjugate_ic.cc
|
conjugate_ic.cc
|
||||||
|
gnss_sdr_fpga_sample_counter.cc
|
||||||
)
|
)
|
||||||
else(ENABLE_FPGA)
|
else(ENABLE_FPGA)
|
||||||
set(GNSS_SPLIBS_SOURCES
|
set(GNSS_SPLIBS_SOURCES
|
||||||
|
@ -33,16 +33,17 @@
|
|||||||
#include "galileo_e1_signal_processing.h"
|
#include "galileo_e1_signal_processing.h"
|
||||||
#include "Galileo_E1.h"
|
#include "Galileo_E1.h"
|
||||||
#include "gnss_signal_processing.h"
|
#include "gnss_signal_processing.h"
|
||||||
|
#include <volk_gnsssdr/volk_gnsssdr.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1_code_gen_int(int* _dest, char _Signal[3], signed int _prn)
|
void galileo_e1_code_gen_int(int* _dest, char _Signal[3], int32_t _prn)
|
||||||
{
|
{
|
||||||
std::string _galileo_signal = _Signal;
|
std::string _galileo_signal = _Signal;
|
||||||
signed int prn = _prn - 1;
|
int32_t prn = _prn - 1;
|
||||||
int index = 0;
|
int32_t index = 0;
|
||||||
|
|
||||||
/* A simple error check */
|
// A simple error check
|
||||||
if ((_prn < 1) || (_prn > 50))
|
if ((_prn < 1) || (_prn > 50))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -67,17 +68,17 @@ void galileo_e1_code_gen_int(int* _dest, char _Signal[3], signed int _prn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1_sinboc_11_gen_int(int* _dest, int* _prn, unsigned int _length_out)
|
void galileo_e1_sinboc_11_gen_int(int* _dest, int* _prn, uint32_t _length_out)
|
||||||
{
|
{
|
||||||
const unsigned int _length_in = Galileo_E1_B_CODE_LENGTH_CHIPS;
|
const uint32_t _length_in = Galileo_E1_B_CODE_LENGTH_CHIPS;
|
||||||
unsigned int _period = static_cast<unsigned int>(_length_out / _length_in);
|
uint32_t _period = static_cast<uint32_t>(_length_out / _length_in);
|
||||||
for (unsigned int i = 0; i < _length_in; i++)
|
for (uint32_t i = 0; i < _length_in; i++)
|
||||||
{
|
{
|
||||||
for (unsigned int j = 0; j < (_period / 2); j++)
|
for (uint32_t j = 0; j < (_period / 2); j++)
|
||||||
{
|
{
|
||||||
_dest[i * _period + j] = _prn[i];
|
_dest[i * _period + j] = _prn[i];
|
||||||
}
|
}
|
||||||
for (unsigned int j = (_period / 2); j < _period; j++)
|
for (uint32_t j = (_period / 2); j < _period; j++)
|
||||||
{
|
{
|
||||||
_dest[i * _period + j] = -_prn[i];
|
_dest[i * _period + j] = -_prn[i];
|
||||||
}
|
}
|
||||||
@ -85,53 +86,55 @@ void galileo_e1_sinboc_11_gen_int(int* _dest, int* _prn, unsigned int _length_ou
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1_sinboc_61_gen_int(int* _dest, int* _prn, unsigned int _length_out)
|
void galileo_e1_sinboc_61_gen_int(int* _dest, int* _prn, uint32_t _length_out)
|
||||||
{
|
{
|
||||||
const unsigned int _length_in = Galileo_E1_B_CODE_LENGTH_CHIPS;
|
const uint32_t _length_in = Galileo_E1_B_CODE_LENGTH_CHIPS;
|
||||||
unsigned int _period = static_cast<unsigned int>(_length_out / _length_in);
|
uint32_t _period = static_cast<uint32_t>(_length_out / _length_in);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < _length_in; i++)
|
for (uint32_t i = 0; i < _length_in; i++)
|
||||||
{
|
{
|
||||||
for (unsigned int j = 0; j < _period; j += 2)
|
for (uint32_t j = 0; j < _period; j += 2)
|
||||||
{
|
{
|
||||||
_dest[i * _period + j] = _prn[i];
|
_dest[i * _period + j] = _prn[i];
|
||||||
}
|
}
|
||||||
for (unsigned int j = 1; j < _period; j += 2)
|
for (uint32_t j = 1; j < _period; j += 2)
|
||||||
{
|
{
|
||||||
_dest[i * _period + j] = -_prn[i];
|
_dest[i * _period + j] = -_prn[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void galileo_e1_code_gen_sinboc11_float(float* _dest, char _Signal[3], unsigned int _prn)
|
|
||||||
|
void galileo_e1_code_gen_sinboc11_float(float* _dest, char _Signal[3], uint32_t _prn)
|
||||||
{
|
{
|
||||||
std::string _galileo_signal = _Signal;
|
std::string _galileo_signal = _Signal;
|
||||||
unsigned int _codeLength = static_cast<unsigned int>(Galileo_E1_B_CODE_LENGTH_CHIPS);
|
const uint32_t _codeLength = static_cast<const uint32_t>(Galileo_E1_B_CODE_LENGTH_CHIPS);
|
||||||
int primary_code_E1_chips[4092]; // _codeLength not accepted by Clang
|
int32_t primary_code_E1_chips[4092]; // _codeLength not accepted by Clang
|
||||||
galileo_e1_code_gen_int(primary_code_E1_chips, _Signal, _prn); //generate Galileo E1 code, 1 sample per chip
|
galileo_e1_code_gen_int(primary_code_E1_chips, _Signal, _prn); //generate Galileo E1 code, 1 sample per chip
|
||||||
for (unsigned int i = 0; i < _codeLength; i++)
|
for (uint32_t i = 0; i < _codeLength; i++)
|
||||||
{
|
{
|
||||||
_dest[2 * i] = static_cast<float>(primary_code_E1_chips[i]);
|
_dest[2 * i] = static_cast<float>(primary_code_E1_chips[i]);
|
||||||
_dest[2 * i + 1] = -_dest[2 * i];
|
_dest[2 * i + 1] = -_dest[2 * i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1_gen_float(float* _dest, int* _prn, char _Signal[3])
|
void galileo_e1_gen_float(float* _dest, int* _prn, char _Signal[3])
|
||||||
{
|
{
|
||||||
std::string _galileo_signal = _Signal;
|
std::string _galileo_signal = _Signal;
|
||||||
const unsigned int _codeLength = 12 * Galileo_E1_B_CODE_LENGTH_CHIPS;
|
const uint32_t _codeLength = 12 * Galileo_E1_B_CODE_LENGTH_CHIPS;
|
||||||
const float alpha = sqrt(10.0 / 11.0);
|
const float alpha = sqrt(10.0 / 11.0);
|
||||||
const float beta = sqrt(1.0 / 11.0);
|
const float beta = sqrt(1.0 / 11.0);
|
||||||
|
|
||||||
int sinboc_11[12 * 4092]; // _codeLength not accepted by Clang
|
int32_t sinboc_11[12 * 4092]; // _codeLength not accepted by Clang
|
||||||
int sinboc_61[12 * 4092];
|
int32_t sinboc_61[12 * 4092];
|
||||||
|
|
||||||
galileo_e1_sinboc_11_gen_int(sinboc_11, _prn, _codeLength); //generate sinboc(1,1) 12 samples per chip
|
galileo_e1_sinboc_11_gen_int(sinboc_11, _prn, _codeLength); //generate sinboc(1,1) 12 samples per chip
|
||||||
galileo_e1_sinboc_61_gen_int(sinboc_61, _prn, _codeLength); //generate sinboc(6,1) 12 samples per chip
|
galileo_e1_sinboc_61_gen_int(sinboc_61, _prn, _codeLength); //generate sinboc(6,1) 12 samples per chip
|
||||||
|
|
||||||
if (_galileo_signal.rfind("1B") != std::string::npos && _galileo_signal.length() >= 2)
|
if (_galileo_signal.rfind("1B") != std::string::npos && _galileo_signal.length() >= 2)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < _codeLength; i++)
|
for (uint32_t i = 0; i < _codeLength; i++)
|
||||||
{
|
{
|
||||||
_dest[i] = alpha * static_cast<float>(sinboc_11[i]) +
|
_dest[i] = alpha * static_cast<float>(sinboc_11[i]) +
|
||||||
beta * static_cast<float>(sinboc_61[i]);
|
beta * static_cast<float>(sinboc_61[i]);
|
||||||
@ -139,7 +142,7 @@ void galileo_e1_gen_float(float* _dest, int* _prn, char _Signal[3])
|
|||||||
}
|
}
|
||||||
else if (_galileo_signal.rfind("1C") != std::string::npos && _galileo_signal.length() >= 2)
|
else if (_galileo_signal.rfind("1C") != std::string::npos && _galileo_signal.length() >= 2)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < _codeLength; i++)
|
for (uint32_t i = 0; i < _codeLength; i++)
|
||||||
{
|
{
|
||||||
_dest[i] = alpha * static_cast<float>(sinboc_11[i]) -
|
_dest[i] = alpha * static_cast<float>(sinboc_11[i]) -
|
||||||
beta * static_cast<float>(sinboc_61[i]);
|
beta * static_cast<float>(sinboc_61[i]);
|
||||||
@ -149,19 +152,20 @@ void galileo_e1_gen_float(float* _dest, int* _prn, char _Signal[3])
|
|||||||
|
|
||||||
|
|
||||||
void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3],
|
void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3],
|
||||||
bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift,
|
bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift,
|
||||||
bool _secondary_flag)
|
bool _secondary_flag)
|
||||||
{
|
{
|
||||||
// This function is based on the GNU software GPS for MATLAB in Kay Borre's book
|
// This function is based on the GNU software GPS for MATLAB in Kay Borre's book
|
||||||
std::string _galileo_signal = _Signal;
|
std::string _galileo_signal = _Signal;
|
||||||
unsigned int _samplesPerCode;
|
uint32_t _samplesPerCode;
|
||||||
const int _codeFreqBasis = Galileo_E1_CODE_CHIP_RATE_HZ; //Hz
|
const int32_t _codeFreqBasis = Galileo_E1_CODE_CHIP_RATE_HZ; // Hz
|
||||||
unsigned int _codeLength = Galileo_E1_B_CODE_LENGTH_CHIPS;
|
uint32_t _codeLength = static_cast<uint32_t>(Galileo_E1_B_CODE_LENGTH_CHIPS);
|
||||||
int primary_code_E1_chips[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)];
|
int32_t* primary_code_E1_chips = static_cast<int32_t*>(volk_gnsssdr_malloc(static_cast<uint32_t>(Galileo_E1_B_CODE_LENGTH_CHIPS) * sizeof(int32_t), volk_gnsssdr_get_alignment()));
|
||||||
_samplesPerCode = static_cast<unsigned int>(static_cast<double>(_fs) / (static_cast<double>(_codeFreqBasis) / static_cast<double>(_codeLength)));
|
|
||||||
const int _samplesPerChip = (_cboc == true) ? 12 : 2;
|
|
||||||
|
|
||||||
const unsigned int delay = ((static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS) - _chip_shift) % static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)) * _samplesPerCode / Galileo_E1_B_CODE_LENGTH_CHIPS;
|
_samplesPerCode = static_cast<uint32_t>(static_cast<double>(_fs) / (static_cast<double>(_codeFreqBasis) / static_cast<double>(_codeLength)));
|
||||||
|
const int32_t _samplesPerChip = (_cboc == true) ? 12 : 2;
|
||||||
|
|
||||||
|
const uint32_t delay = ((static_cast<int32_t>(Galileo_E1_B_CODE_LENGTH_CHIPS) - _chip_shift) % static_cast<int32_t>(Galileo_E1_B_CODE_LENGTH_CHIPS)) * _samplesPerCode / Galileo_E1_B_CODE_LENGTH_CHIPS;
|
||||||
|
|
||||||
galileo_e1_code_gen_int(primary_code_E1_chips, _Signal, _prn); // generate Galileo E1 code, 1 sample per chip
|
galileo_e1_code_gen_int(primary_code_E1_chips, _Signal, _prn); // generate Galileo E1 code, 1 sample per chip
|
||||||
|
|
||||||
@ -176,18 +180,20 @@ void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3],
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int _signal_E1_int[_codeLength];
|
int32_t* _signal_E1_int = static_cast<int32_t*>(volk_gnsssdr_malloc(_codeLength * sizeof(int32_t), volk_gnsssdr_get_alignment()));
|
||||||
galileo_e1_sinboc_11_gen_int(_signal_E1_int, primary_code_E1_chips, _codeLength); // generate sinboc(1,1) 2 samples per chip
|
galileo_e1_sinboc_11_gen_int(_signal_E1_int, primary_code_E1_chips, _codeLength); // generate sinboc(1,1) 2 samples per chip
|
||||||
|
|
||||||
for (unsigned int ii = 0; ii < _codeLength; ++ii)
|
for (uint32_t ii = 0; ii < _codeLength; ++ii)
|
||||||
{
|
{
|
||||||
_signal_E1[ii] = static_cast<float>(_signal_E1_int[ii]);
|
_signal_E1[ii] = static_cast<float>(_signal_E1_int[ii]);
|
||||||
}
|
}
|
||||||
|
volk_gnsssdr_free(_signal_E1_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_fs != _samplesPerChip * _codeFreqBasis)
|
if (_fs != _samplesPerChip * _codeFreqBasis)
|
||||||
{
|
{
|
||||||
float* _resampled_signal = new float[_samplesPerCode];
|
float* _resampled_signal = new float[_samplesPerCode];
|
||||||
|
|
||||||
resampler(_signal_E1, _resampled_signal, _samplesPerChip * _codeFreqBasis, _fs,
|
resampler(_signal_E1, _resampled_signal, _samplesPerChip * _codeFreqBasis, _fs,
|
||||||
_codeLength, _samplesPerCode); // resamples code to fs
|
_codeLength, _samplesPerCode); // resamples code to fs
|
||||||
|
|
||||||
@ -197,9 +203,9 @@ void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3],
|
|||||||
|
|
||||||
if (_galileo_signal.rfind("1C") != std::string::npos && _galileo_signal.length() >= 2 && _secondary_flag)
|
if (_galileo_signal.rfind("1C") != std::string::npos && _galileo_signal.length() >= 2 && _secondary_flag)
|
||||||
{
|
{
|
||||||
float* _signal_E1C_secondary = new float[static_cast<int>(Galileo_E1_C_SECONDARY_CODE_LENGTH) * _samplesPerCode];
|
float* _signal_E1C_secondary = new float[static_cast<int32_t>(Galileo_E1_C_SECONDARY_CODE_LENGTH) * _samplesPerCode];
|
||||||
|
|
||||||
for (unsigned int i = 0; i < static_cast<unsigned int>(Galileo_E1_C_SECONDARY_CODE_LENGTH); i++)
|
for (uint32_t i = 0; i < static_cast<uint32_t>(Galileo_E1_C_SECONDARY_CODE_LENGTH); i++)
|
||||||
{
|
{
|
||||||
for (unsigned k = 0; k < _samplesPerCode; k++)
|
for (unsigned k = 0; k < _samplesPerCode; k++)
|
||||||
{
|
{
|
||||||
@ -207,55 +213,57 @@ void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_samplesPerCode *= static_cast<int>(Galileo_E1_C_SECONDARY_CODE_LENGTH);
|
_samplesPerCode *= static_cast<int32_t>(Galileo_E1_C_SECONDARY_CODE_LENGTH);
|
||||||
|
|
||||||
delete[] _signal_E1;
|
delete[] _signal_E1;
|
||||||
_signal_E1 = _signal_E1C_secondary;
|
_signal_E1 = _signal_E1C_secondary;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < _samplesPerCode; i++)
|
for (uint32_t i = 0; i < _samplesPerCode; i++)
|
||||||
{
|
{
|
||||||
_dest[(i + delay) % _samplesPerCode] = _signal_E1[i];
|
_dest[(i + delay) % _samplesPerCode] = _signal_E1[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] _signal_E1;
|
delete[] _signal_E1;
|
||||||
|
volk_gnsssdr_free(primary_code_E1_chips);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3],
|
void galileo_e1_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3],
|
||||||
bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift,
|
bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift,
|
||||||
bool _secondary_flag)
|
bool _secondary_flag)
|
||||||
{
|
{
|
||||||
std::string _galileo_signal = _Signal;
|
std::string _galileo_signal = _Signal;
|
||||||
const int _codeFreqBasis = Galileo_E1_CODE_CHIP_RATE_HZ; //Hz
|
const int32_t _codeFreqBasis = Galileo_E1_CODE_CHIP_RATE_HZ; // Hz
|
||||||
unsigned int _samplesPerCode = static_cast<unsigned int>(static_cast<double>(_fs) /
|
uint32_t _samplesPerCode = static_cast<uint32_t>(static_cast<double>(_fs) /
|
||||||
(static_cast<double>(_codeFreqBasis) / static_cast<double>(Galileo_E1_B_CODE_LENGTH_CHIPS)));
|
(static_cast<double>(_codeFreqBasis) / static_cast<double>(Galileo_E1_B_CODE_LENGTH_CHIPS)));
|
||||||
|
|
||||||
if (_galileo_signal.rfind("1C") != std::string::npos && _galileo_signal.length() >= 2 && _secondary_flag)
|
if (_galileo_signal.rfind("1C") != std::string::npos && _galileo_signal.length() >= 2 && _secondary_flag)
|
||||||
{
|
{
|
||||||
_samplesPerCode *= static_cast<int>(Galileo_E1_C_SECONDARY_CODE_LENGTH);
|
_samplesPerCode *= static_cast<int32_t>(Galileo_E1_C_SECONDARY_CODE_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
float real_code[_samplesPerCode];
|
float* real_code = static_cast<float*>(volk_gnsssdr_malloc(_samplesPerCode * sizeof(float), volk_gnsssdr_get_alignment()));
|
||||||
|
|
||||||
galileo_e1_code_gen_float_sampled(real_code, _Signal, _cboc, _prn, _fs, _chip_shift, _secondary_flag);
|
galileo_e1_code_gen_float_sampled(real_code, _Signal, _cboc, _prn, _fs, _chip_shift, _secondary_flag);
|
||||||
|
|
||||||
for (unsigned int ii = 0; ii < _samplesPerCode; ++ii)
|
for (uint32_t ii = 0; ii < _samplesPerCode; ++ii)
|
||||||
{
|
{
|
||||||
_dest[ii] = std::complex<float>(real_code[ii], 0.0f);
|
_dest[ii] = std::complex<float>(real_code[ii], 0.0f);
|
||||||
}
|
}
|
||||||
|
volk_gnsssdr_free(real_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3],
|
void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3],
|
||||||
bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift)
|
bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift)
|
||||||
{
|
{
|
||||||
galileo_e1_code_gen_float_sampled(_dest, _Signal, _cboc, _prn, _fs, _chip_shift, false);
|
galileo_e1_code_gen_float_sampled(_dest, _Signal, _cboc, _prn, _fs, _chip_shift, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3],
|
void galileo_e1_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3],
|
||||||
bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift)
|
bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift)
|
||||||
{
|
{
|
||||||
galileo_e1_code_gen_complex_sampled(_dest, _Signal, _cboc, _prn, _fs, _chip_shift, false);
|
galileo_e1_code_gen_complex_sampled(_dest, _Signal, _cboc, _prn, _fs, _chip_shift, false);
|
||||||
}
|
}
|
||||||
|
@ -33,12 +33,13 @@
|
|||||||
#define GNSS_SDR_GALILEO_E1_SIGNAL_PROCESSING_H_
|
#define GNSS_SDR_GALILEO_E1_SIGNAL_PROCESSING_H_
|
||||||
|
|
||||||
#include <complex>
|
#include <complex>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief This function generates Galileo E1 code (can select E1B or E1C sinboc).
|
* \brief This function generates Galileo E1 code (can select E1B or E1C sinboc).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void galileo_e1_code_gen_sinboc11_float(float* _dest, char _Signal[3], unsigned int _prn);
|
void galileo_e1_code_gen_sinboc11_float(float* _dest, char _Signal[3], uint32_t _prn);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief This function generates Galileo E1 code (can select E1B or E1C, cboc or sinboc
|
* \brief This function generates Galileo E1 code (can select E1B or E1C, cboc or sinboc
|
||||||
@ -46,7 +47,7 @@ void galileo_e1_code_gen_sinboc11_float(float* _dest, char _Signal[3], unsigned
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3],
|
void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3],
|
||||||
bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift,
|
bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift,
|
||||||
bool _secondary_flag);
|
bool _secondary_flag);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -55,7 +56,7 @@ void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3],
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3],
|
void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3],
|
||||||
bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift);
|
bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief This function generates Galileo E1 code (can select E1B or E1C, cboc or sinboc
|
* \brief This function generates Galileo E1 code (can select E1B or E1C, cboc or sinboc
|
||||||
@ -63,13 +64,13 @@ void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3],
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void galileo_e1_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3],
|
void galileo_e1_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3],
|
||||||
bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift,
|
bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift,
|
||||||
bool _secondary_flag);
|
bool _secondary_flag);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief galileo_e1_code_gen_complex_sampled without _secondary_flag for backward compatibility.
|
* \brief galileo_e1_code_gen_complex_sampled without _secondary_flag for backward compatibility.
|
||||||
*/
|
*/
|
||||||
void galileo_e1_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3],
|
void galileo_e1_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3],
|
||||||
bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift);
|
bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift);
|
||||||
|
|
||||||
#endif /* GNSS_SDR_GALILEO_E1_SIGNAL_PROCESSING_H_ */
|
#endif /* GNSS_SDR_GALILEO_E1_SIGNAL_PROCESSING_H_ */
|
||||||
|
@ -37,11 +37,11 @@
|
|||||||
#include <gnuradio/gr_complex.h>
|
#include <gnuradio/gr_complex.h>
|
||||||
|
|
||||||
|
|
||||||
void galileo_e5_a_code_gen_complex_primary(std::complex<float>* _dest, signed int _prn, char _Signal[3])
|
void galileo_e5_a_code_gen_complex_primary(std::complex<float>* _dest, int32_t _prn, char _Signal[3])
|
||||||
{
|
{
|
||||||
unsigned int prn = _prn - 1;
|
uint32_t prn = _prn - 1;
|
||||||
unsigned int index = 0;
|
uint32_t index = 0;
|
||||||
int a[4];
|
int32_t a[4];
|
||||||
if ((_prn < 1) || (_prn > 50))
|
if ((_prn < 1) || (_prn > 50))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -80,7 +80,7 @@ void galileo_e5_a_code_gen_complex_primary(std::complex<float>* _dest, signed in
|
|||||||
}
|
}
|
||||||
else if (_Signal[0] == '5' && _Signal[1] == 'X')
|
else if (_Signal[0] == '5' && _Signal[1] == 'X')
|
||||||
{
|
{
|
||||||
int b[4];
|
int32_t b[4];
|
||||||
for (size_t i = 0; i < Galileo_E5a_I_PRIMARY_CODE[prn].length() - 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));
|
hex_to_binary_converter(a, Galileo_E5a_I_PRIMARY_CODE[prn].at(i));
|
||||||
@ -99,19 +99,20 @@ void galileo_e5_a_code_gen_complex_primary(std::complex<float>* _dest, signed in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void galileo_e5_a_code_gen_complex_sampled(std::complex<float>* _dest, char _Signal[3],
|
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)
|
uint32_t _prn, int32_t _fs, uint32_t _chip_shift)
|
||||||
{
|
{
|
||||||
unsigned int _samplesPerCode;
|
uint32_t _samplesPerCode;
|
||||||
unsigned int delay;
|
uint32_t delay;
|
||||||
const unsigned int _codeLength = Galileo_E5a_CODE_LENGTH_CHIPS;
|
const uint32_t _codeLength = Galileo_E5a_CODE_LENGTH_CHIPS;
|
||||||
const int _codeFreqBasis = Galileo_E5a_CODE_CHIP_RATE_HZ;
|
const int32_t _codeFreqBasis = Galileo_E5a_CODE_CHIP_RATE_HZ;
|
||||||
|
|
||||||
std::complex<float>* _code = new std::complex<float>[_codeLength]();
|
std::complex<float>* _code = new std::complex<float>[_codeLength]();
|
||||||
|
|
||||||
galileo_e5_a_code_gen_complex_primary(_code, _prn, _Signal);
|
galileo_e5_a_code_gen_complex_primary(_code, _prn, _Signal);
|
||||||
|
|
||||||
_samplesPerCode = static_cast<unsigned int>(static_cast<double>(_fs) / (static_cast<double>(_codeFreqBasis) / static_cast<double>(_codeLength)));
|
_samplesPerCode = static_cast<uint32_t>(static_cast<double>(_fs) / (static_cast<double>(_codeFreqBasis) / static_cast<double>(_codeLength)));
|
||||||
|
|
||||||
delay = ((_codeLength - _chip_shift) % _codeLength) * _samplesPerCode / _codeLength;
|
delay = ((_codeLength - _chip_shift) % _codeLength) * _samplesPerCode / _codeLength;
|
||||||
|
|
||||||
@ -126,7 +127,7 @@ void galileo_e5_a_code_gen_complex_sampled(std::complex<float>* _dest, char _Sig
|
|||||||
_code = _resampled_signal;
|
_code = _resampled_signal;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < _samplesPerCode; i++)
|
for (uint32_t i = 0; i < _samplesPerCode; i++)
|
||||||
{
|
{
|
||||||
_dest[(i + delay) % _samplesPerCode] = _code[i];
|
_dest[(i + delay) % _samplesPerCode] = _code[i];
|
||||||
}
|
}
|
||||||
|
@ -35,23 +35,23 @@
|
|||||||
#define GNSS_SDR_GALILEO_E5_SIGNAL_PROCESSING_H_
|
#define GNSS_SDR_GALILEO_E5_SIGNAL_PROCESSING_H_
|
||||||
|
|
||||||
#include <complex>
|
#include <complex>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Generates Galileo E5a code at 1 sample/chip
|
* \brief Generates Galileo E5a code at 1 sample/chip
|
||||||
* bool _pilot generates E5aQ code if true and E5aI (data signal) if false.
|
* 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_complex_primary(std::complex<float>* _dest, int32_t _prn, char _Signal[3]);
|
||||||
|
|
||||||
|
void galileo_e5_a_code_gen_tiered(std::complex<float>* _dest, std::complex<float>* _primary, uint32_t _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
|
* \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.
|
* 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,
|
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);
|
char _Signal[3], uint32_t _prn, int32_t _fs, uint32_t _chip_shift);
|
||||||
|
|
||||||
|
|
||||||
#endif /* GNSS_SDR_GALILEO_E5_SIGNAL_PROCESSING_H_ */
|
#endif /* GNSS_SDR_GALILEO_E5_SIGNAL_PROCESSING_H_ */
|
||||||
|
@ -32,17 +32,17 @@
|
|||||||
|
|
||||||
#include "glonass_l1_signal_processing.h"
|
#include "glonass_l1_signal_processing.h"
|
||||||
|
|
||||||
auto auxCeil = [](float x) { return static_cast<int>(static_cast<long>((x) + 1)); };
|
auto auxCeil = [](float x) { return static_cast<int32_t>(static_cast<int64_t>((x) + 1)); };
|
||||||
|
|
||||||
void glonass_l1_ca_code_gen_complex(std::complex<float>* _dest, /* signed int _prn,*/ unsigned int _chip_shift)
|
void glonass_l1_ca_code_gen_complex(std::complex<float>* _dest, /* int32_t _prn,*/ uint32_t _chip_shift)
|
||||||
{
|
{
|
||||||
const unsigned int _code_length = 511;
|
const uint32_t _code_length = 511;
|
||||||
bool G1[_code_length];
|
bool G1[_code_length];
|
||||||
bool G1_register[9];
|
bool G1_register[9];
|
||||||
bool feedback1;
|
bool feedback1;
|
||||||
bool aux;
|
bool aux;
|
||||||
unsigned int delay;
|
uint32_t delay;
|
||||||
unsigned int lcv, lcv2;
|
uint32_t lcv, lcv2;
|
||||||
|
|
||||||
for (lcv = 0; lcv < 9; lcv++)
|
for (lcv = 0; lcv < 9; lcv++)
|
||||||
{
|
{
|
||||||
@ -104,26 +104,26 @@ void glonass_l1_ca_code_gen_complex(std::complex<float>* _dest, /* signed int _p
|
|||||||
/*
|
/*
|
||||||
* Generates complex GLONASS L1 C/A code for the desired SV ID and sampled to specific sampling frequency
|
* Generates complex GLONASS L1 C/A code for the desired SV ID and sampled to specific sampling frequency
|
||||||
*/
|
*/
|
||||||
void glonass_l1_ca_code_gen_complex_sampled(std::complex<float>* _dest, /* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift)
|
void glonass_l1_ca_code_gen_complex_sampled(std::complex<float>* _dest, /* uint32_t _prn,*/ int32_t _fs, uint32_t _chip_shift)
|
||||||
{
|
{
|
||||||
// This function is based on the GNU software GPS for MATLAB in the Kay Borre book
|
// This function is based on the GNU software GPS for MATLAB in the Kay Borre book
|
||||||
std::complex<float> _code[511];
|
std::complex<float> _code[511];
|
||||||
signed int _samplesPerCode, _codeValueIndex;
|
int32_t _samplesPerCode, _codeValueIndex;
|
||||||
float _ts;
|
float _ts;
|
||||||
float _tc;
|
float _tc;
|
||||||
float aux;
|
float aux;
|
||||||
const signed int _codeFreqBasis = 511000; //Hz
|
const int32_t _codeFreqBasis = 511000; //Hz
|
||||||
const signed int _codeLength = 511;
|
const int32_t _codeLength = 511;
|
||||||
|
|
||||||
//--- Find number of samples per spreading code ----------------------------
|
//--- Find number of samples per spreading code ----------------------------
|
||||||
_samplesPerCode = static_cast<signed int>(static_cast<double>(_fs) / static_cast<double>(_codeFreqBasis / _codeLength));
|
_samplesPerCode = static_cast<int32_t>(static_cast<double>(_fs) / static_cast<double>(_codeFreqBasis / _codeLength));
|
||||||
|
|
||||||
//--- Find time constants --------------------------------------------------
|
//--- Find time constants --------------------------------------------------
|
||||||
_ts = 1.0 / static_cast<float>(_fs); // Sampling period in sec
|
_ts = 1.0 / static_cast<float>(_fs); // Sampling period in sec
|
||||||
_tc = 1.0 / static_cast<float>(_codeFreqBasis); // C/A chip period in sec
|
_tc = 1.0 / static_cast<float>(_codeFreqBasis); // C/A chip period in sec
|
||||||
glonass_l1_ca_code_gen_complex(_code, _chip_shift); //generate C/A code 1 sample per chip
|
glonass_l1_ca_code_gen_complex(_code, _chip_shift); //generate C/A code 1 sample per chip
|
||||||
|
|
||||||
for (signed int i = 0; i < _samplesPerCode; i++)
|
for (int32_t i = 0; i < _samplesPerCode; i++)
|
||||||
{
|
{
|
||||||
//=== Digitizing =======================================================
|
//=== Digitizing =======================================================
|
||||||
|
|
||||||
|
@ -34,14 +34,15 @@
|
|||||||
#define GNSS_SDR_GLONASS_SDR_SIGNAL_PROCESSING_H_
|
#define GNSS_SDR_GLONASS_SDR_SIGNAL_PROCESSING_H_
|
||||||
|
|
||||||
#include <complex>
|
#include <complex>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
//!Generates complex GLONASS L1 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency
|
//!Generates complex GLONASS L1 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency
|
||||||
void glonass_l1_ca_code_gen_complex(std::complex<float>* _dest, /*signed int _prn,*/ unsigned int _chip_shift);
|
void glonass_l1_ca_code_gen_complex(std::complex<float>* _dest, /*int32_t _prn,*/ uint32_t _chip_shift);
|
||||||
|
|
||||||
//! Generates N complex GLONASS L1 C/A codes for the desired SV ID and code shift
|
//! Generates N complex GLONASS L1 C/A codes for the desired SV ID and code shift
|
||||||
void glonass_l1_ca_code_gen_complex_sampled(std::complex<float>* _dest, /* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift, unsigned int _ncodes);
|
void glonass_l1_ca_code_gen_complex_sampled(std::complex<float>* _dest, /* uint32_t _prn,*/ int32_t _fs, uint32_t _chip_shift, uint32_t _ncodes);
|
||||||
|
|
||||||
//! Generates complex GLONASS L1 C/A code for the desired SV ID and code shift
|
//! Generates complex GLONASS L1 C/A code for the desired SV ID and code shift
|
||||||
void glonass_l1_ca_code_gen_complex_sampled(std::complex<float>* _dest, /* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift);
|
void glonass_l1_ca_code_gen_complex_sampled(std::complex<float>* _dest, /* uint32_t _prn,*/ int32_t _fs, uint32_t _chip_shift);
|
||||||
|
|
||||||
#endif /* GNSS_SDR_GLONASS_SDR_SIGNAL_PROCESSING_H_ */
|
#endif /* GNSS_SDR_GLONASS_SDR_SIGNAL_PROCESSING_H_ */
|
||||||
|
@ -32,17 +32,17 @@
|
|||||||
|
|
||||||
#include "glonass_l2_signal_processing.h"
|
#include "glonass_l2_signal_processing.h"
|
||||||
|
|
||||||
auto auxCeil = [](float x) { return static_cast<int>(static_cast<long>((x) + 1)); };
|
auto auxCeil = [](float x) { return static_cast<int32_t>(static_cast<int64_t>((x) + 1)); };
|
||||||
|
|
||||||
void glonass_l2_ca_code_gen_complex(std::complex<float>* _dest, /* signed int _prn,*/ unsigned int _chip_shift)
|
void glonass_l2_ca_code_gen_complex(std::complex<float>* _dest, /* int32_t _prn,*/ uint32_t _chip_shift)
|
||||||
{
|
{
|
||||||
const unsigned int _code_length = 511;
|
const uint32_t _code_length = 511;
|
||||||
bool G1[_code_length];
|
bool G1[_code_length];
|
||||||
bool G1_register[9];
|
bool G1_register[9];
|
||||||
bool feedback1;
|
bool feedback1;
|
||||||
bool aux;
|
bool aux;
|
||||||
unsigned int delay;
|
uint32_t delay;
|
||||||
unsigned int lcv, lcv2;
|
uint32_t lcv, lcv2;
|
||||||
|
|
||||||
for (lcv = 0; lcv < 9; lcv++)
|
for (lcv = 0; lcv < 9; lcv++)
|
||||||
{
|
{
|
||||||
@ -104,26 +104,26 @@ void glonass_l2_ca_code_gen_complex(std::complex<float>* _dest, /* signed int _p
|
|||||||
/*
|
/*
|
||||||
* Generates complex GLONASS L2 C/A code for the desired SV ID and sampled to specific sampling frequency
|
* Generates complex GLONASS L2 C/A code for the desired SV ID and sampled to specific sampling frequency
|
||||||
*/
|
*/
|
||||||
void glonass_l2_ca_code_gen_complex_sampled(std::complex<float>* _dest, /* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift)
|
void glonass_l2_ca_code_gen_complex_sampled(std::complex<float>* _dest, /* uint32_t _prn,*/ int32_t _fs, uint32_t _chip_shift)
|
||||||
{
|
{
|
||||||
// This function is based on the GNU software GPS for MATLAB in the Kay Borre book
|
// This function is based on the GNU software GPS for MATLAB in the Kay Borre book
|
||||||
std::complex<float> _code[511];
|
std::complex<float> _code[511];
|
||||||
signed int _samplesPerCode, _codeValueIndex;
|
int32_t _samplesPerCode, _codeValueIndex;
|
||||||
float _ts;
|
float _ts;
|
||||||
float _tc;
|
float _tc;
|
||||||
float aux;
|
float aux;
|
||||||
const signed int _codeFreqBasis = 511000; //Hz
|
const int32_t _codeFreqBasis = 511000; //Hz
|
||||||
const signed int _codeLength = 511;
|
const int32_t _codeLength = 511;
|
||||||
|
|
||||||
//--- Find number of samples per spreading code ----------------------------
|
//--- Find number of samples per spreading code ----------------------------
|
||||||
_samplesPerCode = static_cast<signed int>(static_cast<double>(_fs) / static_cast<double>(_codeFreqBasis / _codeLength));
|
_samplesPerCode = static_cast<int32_t>(static_cast<double>(_fs) / static_cast<double>(_codeFreqBasis / _codeLength));
|
||||||
|
|
||||||
//--- Find time constants --------------------------------------------------
|
//--- Find time constants --------------------------------------------------
|
||||||
_ts = 1.0 / static_cast<float>(_fs); // Sampling period in sec
|
_ts = 1.0 / static_cast<float>(_fs); // Sampling period in sec
|
||||||
_tc = 1.0 / static_cast<float>(_codeFreqBasis); // C/A chip period in sec
|
_tc = 1.0 / static_cast<float>(_codeFreqBasis); // C/A chip period in sec
|
||||||
glonass_l2_ca_code_gen_complex(_code, _chip_shift); //generate C/A code 1 sample per chip
|
glonass_l2_ca_code_gen_complex(_code, _chip_shift); //generate C/A code 1 sample per chip
|
||||||
|
|
||||||
for (signed int i = 0; i < _samplesPerCode; i++)
|
for (int32_t i = 0; i < _samplesPerCode; i++)
|
||||||
{
|
{
|
||||||
//=== Digitizing =======================================================
|
//=== Digitizing =======================================================
|
||||||
|
|
||||||
|
@ -34,14 +34,15 @@
|
|||||||
#define GNSS_SDR_GLONASS_L2_SIGNAL_PROCESSING_H_
|
#define GNSS_SDR_GLONASS_L2_SIGNAL_PROCESSING_H_
|
||||||
|
|
||||||
#include <complex>
|
#include <complex>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
//!Generates complex GLONASS L2 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency
|
//!Generates complex GLONASS L2 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency
|
||||||
void glonass_l2_ca_code_gen_complex(std::complex<float>* _dest, /*signed int _prn,*/ unsigned int _chip_shift);
|
void glonass_l2_ca_code_gen_complex(std::complex<float>* _dest, /*int32_t _prn,*/ uint32_t _chip_shift);
|
||||||
|
|
||||||
//! Generates N complex GLONASS L2 C/A codes for the desired SV ID and code shift
|
//! Generates N complex GLONASS L2 C/A codes for the desired SV ID and code shift
|
||||||
void glonass_l2_ca_code_gen_complex_sampled(std::complex<float>* _dest, /* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift, unsigned int _ncodes);
|
void glonass_l2_ca_code_gen_complex_sampled(std::complex<float>* _dest, /* uint32_t _prn,*/ int32_t _fs, uint32_t _chip_shift, uint32_t _ncodes);
|
||||||
|
|
||||||
//! Generates complex GLONASS L2 C/A code for the desired SV ID and code shift
|
//! Generates complex GLONASS L2 C/A code for the desired SV ID and code shift
|
||||||
void glonass_l2_ca_code_gen_complex_sampled(std::complex<float>* _dest, /* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift);
|
void glonass_l2_ca_code_gen_complex_sampled(std::complex<float>* _dest, /* uint32_t _prn,*/ int32_t _fs, uint32_t _chip_shift);
|
||||||
|
|
||||||
#endif /* GNSS_SDR_GLONASS_L2_SIGNAL_PROCESSING_H_ */
|
#endif /* GNSS_SDR_GLONASS_L2_SIGNAL_PROCESSING_H_ */
|
||||||
|
305
src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc
Normal file
305
src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
/*!
|
||||||
|
* \file gnss_sdr_fpga_sample_counter.cc
|
||||||
|
* \brief Simple block to report the current receiver time based on the output of the tracking or telemetry blocks
|
||||||
|
* \author Javier Arribas 2018. jarribas(at)cttc.es
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
|
||||||
|
*
|
||||||
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
|
* Satellite Systems receiver
|
||||||
|
*
|
||||||
|
* This file is part of GNSS-SDR.
|
||||||
|
*
|
||||||
|
* GNSS-SDR is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GNSS-SDR is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gnss_sdr_fpga_sample_counter.h"
|
||||||
|
#include "gnss_synchro.h"
|
||||||
|
#include <gnuradio/io_signature.h>
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <glog/logging.h>
|
||||||
|
#include <fcntl.h> // libraries used by the GIPO
|
||||||
|
#include <sys/mman.h> // libraries used by the GIPO
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#define PAGE_SIZE 0x10000 // default page size for the multicorrelator memory map
|
||||||
|
#define TEST_REG_SANITY_CHECK 0x55AA // value to check the presence of the test register (to detect the hw)
|
||||||
|
|
||||||
|
gnss_sdr_fpga_sample_counter::gnss_sdr_fpga_sample_counter(double _fs, int32_t _interval_ms) : gr::block("fpga_fpga_sample_counter",
|
||||||
|
gr::io_signature::make(0, 0, 0),
|
||||||
|
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
|
||||||
|
{
|
||||||
|
message_port_register_out(pmt::mp("fpga_sample_counter"));
|
||||||
|
set_max_noutput_items(1);
|
||||||
|
interval_ms = _interval_ms;
|
||||||
|
fs = _fs;
|
||||||
|
//printf("CREATOR fs = %f\n", fs);
|
||||||
|
//printf("CREATOR interval_ms = %" PRIu32 "\n", interval_ms);
|
||||||
|
samples_per_output = std::round(fs * static_cast<double>(interval_ms) / 1e3);
|
||||||
|
//printf("CREATOR samples_per_output = %" PRIu32 "\n", samples_per_output);
|
||||||
|
//todo: Load here the hardware counter register with this amount of samples. It should produce an
|
||||||
|
//interrupt every samples_per_output count.
|
||||||
|
//The hardware timer must keep always interrupting the PS. It must not wait for the interrupt to
|
||||||
|
//be served.
|
||||||
|
open_device();
|
||||||
|
|
||||||
|
sample_counter = 0ULL;
|
||||||
|
current_T_rx_ms = 0;
|
||||||
|
current_s = 0;
|
||||||
|
current_m = 0;
|
||||||
|
current_h = 0;
|
||||||
|
current_days = 0;
|
||||||
|
report_interval_ms = 1000; // default reporting 1 second
|
||||||
|
flag_enable_send_msg = false; // enable it for reporting time with asynchronous message
|
||||||
|
flag_m = false;
|
||||||
|
flag_h = false;
|
||||||
|
flag_days = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int32_t _interval_ms)
|
||||||
|
{
|
||||||
|
gnss_sdr_fpga_sample_counter_sptr fpga_sample_counter_(new gnss_sdr_fpga_sample_counter(_fs, _interval_ms));
|
||||||
|
return fpga_sample_counter_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Called by gnuradio to enable drivers, etc for i/o devices.
|
||||||
|
bool gnss_sdr_fpga_sample_counter::start()
|
||||||
|
{
|
||||||
|
//todo: place here the RE-INITIALIZATION routines. This function will be called by GNURadio at every start of the flowgraph.
|
||||||
|
|
||||||
|
// configure the number of samples per output in the FPGA and enable the interrupts
|
||||||
|
configure_samples_per_output(samples_per_output);
|
||||||
|
|
||||||
|
// return true if everything is ok.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Called by GNURadio to disable drivers, etc for i/o devices.
|
||||||
|
bool gnss_sdr_fpga_sample_counter::stop()
|
||||||
|
{
|
||||||
|
//todo: place here the routines to stop the associated hardware (if needed).This function will be called by GNURadio at every stop of the flowgraph.
|
||||||
|
// return true if everything is ok.
|
||||||
|
close_device();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int gnss_sdr_fpga_sample_counter::general_work(int noutput_items __attribute__((unused)),
|
||||||
|
__attribute__((unused)) gr_vector_int &ninput_items,
|
||||||
|
__attribute__((unused)) gr_vector_const_void_star &input_items,
|
||||||
|
gr_vector_void_star &output_items)
|
||||||
|
{
|
||||||
|
//todo: Call here a function that waits for an interrupt. Do not open a thread,
|
||||||
|
//it must be a simple call to a BLOCKING function.
|
||||||
|
// The function will return the actual absolute sample count of the internal counter of the timmer.
|
||||||
|
// store the sample count in class member sample_counter
|
||||||
|
// Possible problem: what happen if the PS is overloaded and gnuradio does not call this function
|
||||||
|
// with the sufficient rate to catch all the interrupts in the counter. To be evaluated later.
|
||||||
|
|
||||||
|
uint32_t counter = wait_for_interrupt_and_read_counter();
|
||||||
|
uint64_t samples_passed = 2*static_cast<uint64_t>(samples_per_output) - static_cast<uint64_t>(counter); // ellapsed samples
|
||||||
|
//printf("============================================ interrupter : samples_passed = %" PRIu64 "\n", samples_passed);
|
||||||
|
// Note: at this moment the sample counter is implemented as a sample counter that decreases to zero and then it is automatically
|
||||||
|
// reloaded again and keeps counter. It is done in this way to minimize the logic in the FPGA and maximize the FPGA clock performance
|
||||||
|
// (it takes less resources and latency in the FPGA to compare a number against a fixed value like zero than to compare it to a programmable
|
||||||
|
// variable number).
|
||||||
|
|
||||||
|
sample_counter = sample_counter + samples_passed; //samples_per_output;
|
||||||
|
Gnss_Synchro *out = reinterpret_cast<Gnss_Synchro *>(output_items[0]);
|
||||||
|
out[0] = Gnss_Synchro();
|
||||||
|
out[0].Flag_valid_symbol_output = false;
|
||||||
|
out[0].Flag_valid_word = false;
|
||||||
|
out[0].Channel_ID = -1;
|
||||||
|
out[0].fs = fs;
|
||||||
|
if ((current_T_rx_ms % report_interval_ms) == 0)
|
||||||
|
{
|
||||||
|
//printf("time to print sample_counter = %" PRIu64 "\n", sample_counter);
|
||||||
|
//printf("time to print current Tx ms : %" PRIu64 "\n", current_T_rx_ms);
|
||||||
|
//printf("time to print report_interval_ms : %" PRIu32 "\n", report_interval_ms);
|
||||||
|
//printf("time to print %f\n", (current_T_rx_ms % report_interval_ms));
|
||||||
|
current_s++;
|
||||||
|
if ((current_s % 60) == 0)
|
||||||
|
{
|
||||||
|
current_s = 0;
|
||||||
|
current_m++;
|
||||||
|
flag_m = true;
|
||||||
|
if ((current_m % 60) == 0)
|
||||||
|
{
|
||||||
|
current_m = 0;
|
||||||
|
current_h++;
|
||||||
|
flag_h = true;
|
||||||
|
if ((current_h % 24) == 0)
|
||||||
|
{
|
||||||
|
current_h = 0;
|
||||||
|
current_days++;
|
||||||
|
flag_days = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag_days)
|
||||||
|
{
|
||||||
|
std::string day;
|
||||||
|
if (current_days == 1)
|
||||||
|
{
|
||||||
|
day = " day ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
day = " days ";
|
||||||
|
}
|
||||||
|
std::cout << "Current receiver time: " << current_days << day << current_h << " h " << current_m << " min " << current_s << " s" << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (flag_h)
|
||||||
|
{
|
||||||
|
std::cout << "Current receiver time: " << current_h << " h " << current_m << " min " << current_s << " s" << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (flag_m)
|
||||||
|
{
|
||||||
|
std::cout << "Current receiver time: " << current_m << " min " << current_s << " s" << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Current receiver time: " << current_s << " s" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flag_enable_send_msg)
|
||||||
|
{
|
||||||
|
message_port_pub(pmt::mp("receiver_time"), pmt::from_double(static_cast<double>(current_T_rx_ms) / 1000.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out[0].Tracking_sample_counter = sample_counter;
|
||||||
|
//current_T_rx_ms = (sample_counter * 1000) / samples_per_output;
|
||||||
|
current_T_rx_ms = interval_ms*(sample_counter) / samples_per_output;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t gnss_sdr_fpga_sample_counter::test_register(uint32_t writeval)
|
||||||
|
{
|
||||||
|
uint32_t readval;
|
||||||
|
// write value to test register
|
||||||
|
map_base[3] = writeval;
|
||||||
|
// read value from test register
|
||||||
|
readval = map_base[3];
|
||||||
|
// return read value
|
||||||
|
return readval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gnss_sdr_fpga_sample_counter::configure_samples_per_output(uint32_t interval)
|
||||||
|
{
|
||||||
|
// note : the counter is a 48-bit value in the HW.
|
||||||
|
//printf("============================================ total counter - interrupted interval : %" PRIu32 "\n", interval);
|
||||||
|
//uint64_t temp_interval;
|
||||||
|
//temp_interval = (interval & static_cast<uint32_t>(0xFFFFFFFF));
|
||||||
|
//printf("LSW counter - interrupted interval : %" PRIu32 "\n", static_cast<uint32_t>(temp_interval));
|
||||||
|
//map_base[0] = static_cast<uint32_t>(temp_interval);
|
||||||
|
map_base[0] = interval - 1;
|
||||||
|
//temp_interval = (interval >> 32) & static_cast<uint32_t>(0xFFFFFFFF);
|
||||||
|
//printf("MSbits counter - interrupted interval : %" PRIu32 "\n", static_cast<uint32_t>(temp_interval));
|
||||||
|
//map_base[1] = static_cast<uint32_t>(temp_interval); // writing the most significant bits also enables the interrupts
|
||||||
|
}
|
||||||
|
|
||||||
|
void gnss_sdr_fpga_sample_counter::open_device()
|
||||||
|
{
|
||||||
|
// open communication with HW accelerator
|
||||||
|
if ((fd = open(device_name.c_str(), O_RDWR | O_SYNC)) == -1)
|
||||||
|
{
|
||||||
|
LOG(WARNING) << "Cannot open deviceio" << device_name;
|
||||||
|
std::cout << "Counter-Intr: cannot open deviceio" << device_name << std::endl;
|
||||||
|
}
|
||||||
|
map_base = reinterpret_cast<volatile uint32_t *>(mmap(NULL, PAGE_SIZE,
|
||||||
|
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
|
||||||
|
|
||||||
|
if (map_base == reinterpret_cast<void *>(-1))
|
||||||
|
{
|
||||||
|
LOG(WARNING) << "Cannot map the FPGA acquisition module into user memory";
|
||||||
|
std::cout << "Counter-Intr: cannot map deviceio" << device_name << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanity check : check test register
|
||||||
|
uint32_t writeval = TEST_REG_SANITY_CHECK;
|
||||||
|
uint32_t readval;
|
||||||
|
readval = gnss_sdr_fpga_sample_counter::test_register(writeval);
|
||||||
|
if (writeval != readval)
|
||||||
|
{
|
||||||
|
LOG(WARNING) << "Acquisition test register sanity check failed";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG(INFO) << "Acquisition test register sanity check success!";
|
||||||
|
//std::cout << "Acquisition test register sanity check success!" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gnss_sdr_fpga_sample_counter::close_device()
|
||||||
|
{
|
||||||
|
//printf("=========================================== NOW closing device ...\n");
|
||||||
|
map_base[2] = 0; // disable the generation of the interrupt in the device
|
||||||
|
|
||||||
|
uint32_t *aux = const_cast<uint32_t *>(map_base);
|
||||||
|
if (munmap(static_cast<void *>(aux), PAGE_SIZE) == -1)
|
||||||
|
{
|
||||||
|
printf("Failed to unmap memory uio\n");
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t gnss_sdr_fpga_sample_counter::wait_for_interrupt_and_read_counter()
|
||||||
|
{
|
||||||
|
int32_t irq_count;
|
||||||
|
ssize_t nb;
|
||||||
|
int32_t counter;
|
||||||
|
|
||||||
|
// enable interrupts
|
||||||
|
int32_t reenable = 1;
|
||||||
|
write(fd, reinterpret_cast<void *>(&reenable), sizeof(int32_t));
|
||||||
|
|
||||||
|
// wait for interrupt
|
||||||
|
//printf("============================================ interrupter : going to wait for interupt\n");
|
||||||
|
nb = read(fd, &irq_count, sizeof(irq_count));
|
||||||
|
//printf("============================================ interrupter : interrupt received\n");
|
||||||
|
//printf("interrupt received\n");
|
||||||
|
if (nb != sizeof(irq_count))
|
||||||
|
{
|
||||||
|
printf("acquisition module Read failed to retrieve 4 bytes!\n");
|
||||||
|
printf("acquisition module Interrupt number %d\n", irq_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// acknowledge the interrupt
|
||||||
|
map_base[1] = 0; // writing anything to reg 1 acknowledges the interrupt
|
||||||
|
|
||||||
|
// add number of passed samples or read the current counter value for more accuracy
|
||||||
|
counter = samples_per_output; //map_base[0];
|
||||||
|
return counter;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
81
src/algorithms/libs/gnss_sdr_fpga_sample_counter.h
Normal file
81
src/algorithms/libs/gnss_sdr_fpga_sample_counter.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*!
|
||||||
|
* \file gnss_sdr_fpga_sample_counter.h
|
||||||
|
* \brief Simple block to report the current receiver time based on the output of the tracking or telemetry blocks
|
||||||
|
* \author Javier Arribas 2018. jarribas(at)cttc.es
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
|
||||||
|
*
|
||||||
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
|
* Satellite Systems receiver
|
||||||
|
*
|
||||||
|
* This file is part of GNSS-SDR.
|
||||||
|
*
|
||||||
|
* GNSS-SDR is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GNSS-SDR is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#ifndef GNSS_SDR_FPGA_sample_counter_H_
|
||||||
|
#define GNSS_SDR_FPGA_sample_counter_H_
|
||||||
|
|
||||||
|
#include <gnuradio/block.h>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
class gnss_sdr_fpga_sample_counter;
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<gnss_sdr_fpga_sample_counter> gnss_sdr_fpga_sample_counter_sptr;
|
||||||
|
|
||||||
|
gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int32_t _interval_ms);
|
||||||
|
|
||||||
|
class gnss_sdr_fpga_sample_counter : public gr::block
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
gnss_sdr_fpga_sample_counter(double _fs, int32_t _interval_ms);
|
||||||
|
uint32_t test_register(uint32_t writeval);
|
||||||
|
void configure_samples_per_output(uint32_t interval);
|
||||||
|
void close_device(void);
|
||||||
|
void open_device(void);
|
||||||
|
bool start();
|
||||||
|
bool stop();
|
||||||
|
uint32_t wait_for_interrupt_and_read_counter(void);
|
||||||
|
uint32_t samples_per_output;
|
||||||
|
double fs;
|
||||||
|
uint64_t sample_counter;
|
||||||
|
uint32_t interval_ms;
|
||||||
|
uint64_t current_T_rx_ms; // Receiver time in ms since the beginning of the run
|
||||||
|
uint32_t current_s; // Receiver time in seconds, modulo 60
|
||||||
|
bool flag_m; // True if the receiver has been running for at least 1 minute
|
||||||
|
uint32_t current_m; // Receiver time in minutes, modulo 60
|
||||||
|
bool flag_h; // True if the receiver has been running for at least 1 hour
|
||||||
|
uint32_t current_h; // Receiver time in hours, modulo 24
|
||||||
|
bool flag_days; // True if the receiver has been running for at least 1 day
|
||||||
|
uint32_t current_days; // Receiver time in days since the beginning of the run
|
||||||
|
int32_t report_interval_ms;
|
||||||
|
bool flag_enable_send_msg;
|
||||||
|
int32_t fd; // driver descriptor
|
||||||
|
volatile uint32_t *map_base; // driver memory map
|
||||||
|
std::string device_name = "/dev/uio26"; // HW device name
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int32_t _interval_ms);
|
||||||
|
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_FPGA_sample_counter_H_*/
|
@ -36,13 +36,17 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
gnss_sdr_sample_counter::gnss_sdr_sample_counter(double _fs, size_t _size) : gr::sync_decimator("sample_counter",
|
gnss_sdr_sample_counter::gnss_sdr_sample_counter(double _fs, int32_t _interval_ms, size_t _size) : gr::sync_decimator("sample_counter",
|
||||||
gr::io_signature::make(1, 1, _size),
|
gr::io_signature::make(1, 1, _size),
|
||||||
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
|
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
|
||||||
static_cast<unsigned int>(std::floor(_fs * 0.001)))
|
static_cast<uint32_t>(std::round(_fs * static_cast<double>(_interval_ms) / 1e3)))
|
||||||
{
|
{
|
||||||
message_port_register_out(pmt::mp("sample_counter"));
|
message_port_register_out(pmt::mp("sample_counter"));
|
||||||
set_max_noutput_items(1);
|
set_max_noutput_items(1);
|
||||||
|
interval_ms = _interval_ms;
|
||||||
|
fs = _fs;
|
||||||
|
samples_per_output = std::round(fs * static_cast<double>(interval_ms) / 1e3);
|
||||||
|
sample_counter = 0;
|
||||||
current_T_rx_ms = 0;
|
current_T_rx_ms = 0;
|
||||||
current_s = 0;
|
current_s = 0;
|
||||||
current_m = 0;
|
current_m = 0;
|
||||||
@ -56,9 +60,9 @@ gnss_sdr_sample_counter::gnss_sdr_sample_counter(double _fs, size_t _size) : gr:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter(double _fs, size_t _size)
|
gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter(double _fs, int32_t _interval_ms, size_t _size)
|
||||||
{
|
{
|
||||||
gnss_sdr_sample_counter_sptr sample_counter_(new gnss_sdr_sample_counter(_fs, _size));
|
gnss_sdr_sample_counter_sptr sample_counter_(new gnss_sdr_sample_counter(_fs, _interval_ms, _size));
|
||||||
return sample_counter_;
|
return sample_counter_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +73,10 @@ int gnss_sdr_sample_counter::work(int noutput_items __attribute__((unused)),
|
|||||||
{
|
{
|
||||||
Gnss_Synchro *out = reinterpret_cast<Gnss_Synchro *>(output_items[0]);
|
Gnss_Synchro *out = reinterpret_cast<Gnss_Synchro *>(output_items[0]);
|
||||||
out[0] = Gnss_Synchro();
|
out[0] = Gnss_Synchro();
|
||||||
|
out[0].Flag_valid_symbol_output = false;
|
||||||
|
out[0].Flag_valid_word = false;
|
||||||
|
out[0].Channel_ID = -1;
|
||||||
|
out[0].fs = fs;
|
||||||
if ((current_T_rx_ms % report_interval_ms) == 0)
|
if ((current_T_rx_ms % report_interval_ms) == 0)
|
||||||
{
|
{
|
||||||
current_s++;
|
current_s++;
|
||||||
@ -127,6 +135,8 @@ int gnss_sdr_sample_counter::work(int noutput_items __attribute__((unused)),
|
|||||||
message_port_pub(pmt::mp("receiver_time"), pmt::from_double(static_cast<double>(current_T_rx_ms) / 1000.0));
|
message_port_pub(pmt::mp("receiver_time"), pmt::from_double(static_cast<double>(current_T_rx_ms) / 1000.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current_T_rx_ms++;
|
sample_counter += samples_per_output;
|
||||||
|
out[0].Tracking_sample_counter = sample_counter;
|
||||||
|
current_T_rx_ms += interval_ms;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -33,31 +33,36 @@
|
|||||||
|
|
||||||
#include <gnuradio/sync_decimator.h>
|
#include <gnuradio/sync_decimator.h>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
||||||
class gnss_sdr_sample_counter;
|
class gnss_sdr_sample_counter;
|
||||||
|
|
||||||
typedef boost::shared_ptr<gnss_sdr_sample_counter> gnss_sdr_sample_counter_sptr;
|
typedef boost::shared_ptr<gnss_sdr_sample_counter> gnss_sdr_sample_counter_sptr;
|
||||||
|
|
||||||
gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter(double _fs, size_t _size);
|
gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter(double _fs, int32_t _interval_ms, size_t _size);
|
||||||
|
|
||||||
class gnss_sdr_sample_counter : public gr::sync_decimator
|
class gnss_sdr_sample_counter : public gr::sync_decimator
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
gnss_sdr_sample_counter(double _fs, size_t _size);
|
gnss_sdr_sample_counter(double _fs, int32_t _interval_ms, size_t _size);
|
||||||
long long int current_T_rx_ms; // Receiver time in ms since the beginning of the run
|
uint32_t samples_per_output;
|
||||||
unsigned int current_s; // Receiver time in seconds, modulo 60
|
double fs;
|
||||||
|
uint64_t sample_counter;
|
||||||
|
int32_t interval_ms;
|
||||||
|
int64_t current_T_rx_ms; // Receiver time in ms since the beginning of the run
|
||||||
|
uint32_t current_s; // Receiver time in seconds, modulo 60
|
||||||
bool flag_m; // True if the receiver has been running for at least 1 minute
|
bool flag_m; // True if the receiver has been running for at least 1 minute
|
||||||
unsigned int current_m; // Receiver time in minutes, modulo 60
|
uint32_t current_m; // Receiver time in minutes, modulo 60
|
||||||
bool flag_h; // True if the receiver has been running for at least 1 hour
|
bool flag_h; // True if the receiver has been running for at least 1 hour
|
||||||
unsigned int current_h; // Receiver time in hours, modulo 24
|
uint32_t current_h; // Receiver time in hours, modulo 24
|
||||||
bool flag_days; // True if the receiver has been running for at least 1 day
|
bool flag_days; // True if the receiver has been running for at least 1 day
|
||||||
unsigned int current_days; // Receiver time in days since the beginning of the run
|
uint32_t current_days; // Receiver time in days since the beginning of the run
|
||||||
int report_interval_ms;
|
int32_t report_interval_ms;
|
||||||
bool flag_enable_send_msg;
|
bool flag_enable_send_msg;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
friend gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter(double _fs, size_t _size);
|
friend gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter(double _fs, int32_t _interval_ms, size_t _size);
|
||||||
int work(int noutput_items,
|
int work(int noutput_items,
|
||||||
gr_vector_const_void_star &input_items,
|
gr_vector_const_void_star &input_items,
|
||||||
gr_vector_void_star &output_items);
|
gr_vector_void_star &output_items);
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
#include <gnuradio/block.h>
|
#include <gnuradio/block.h>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
class gnss_sdr_time_counter;
|
class gnss_sdr_time_counter;
|
||||||
|
|
||||||
@ -45,15 +45,15 @@ class gnss_sdr_time_counter : public gr::block
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
gnss_sdr_time_counter();
|
gnss_sdr_time_counter();
|
||||||
long long int current_T_rx_ms; // Receiver time in ms since the beginning of the run
|
int64_t current_T_rx_ms; // Receiver time in ms since the beginning of the run
|
||||||
unsigned int current_s; // Receiver time in seconds, modulo 60
|
uint32_t current_s; // Receiver time in seconds, modulo 60
|
||||||
bool flag_m; // True if the receiver has been running for at least 1 minute
|
bool flag_m; // True if the receiver has been running for at least 1 minute
|
||||||
unsigned int current_m; // Receiver time in minutes, modulo 60
|
uint32_t current_m; // Receiver time in minutes, modulo 60
|
||||||
bool flag_h; // True if the receiver has been running for at least 1 hour
|
bool flag_h; // True if the receiver has been running for at least 1 hour
|
||||||
unsigned int current_h; // Receiver time in hours, modulo 24
|
uint32_t current_h; // Receiver time in hours, modulo 24
|
||||||
bool flag_days; // True if the receiver has been running for at least 1 day
|
bool flag_days; // True if the receiver has been running for at least 1 day
|
||||||
unsigned int current_days; // Receiver time in days since the beginning of the run
|
uint32_t current_days; // Receiver time in days since the beginning of the run
|
||||||
int report_interval_ms;
|
int32_t report_interval_ms;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
friend gnss_sdr_time_counter_sptr gnss_sdr_make_time_counter();
|
friend gnss_sdr_time_counter_sptr gnss_sdr_make_time_counter();
|
||||||
|
@ -36,9 +36,9 @@
|
|||||||
#include <gnuradio/fxpt_nco.h>
|
#include <gnuradio/fxpt_nco.h>
|
||||||
|
|
||||||
|
|
||||||
auto auxCeil2 = [](float x) { return static_cast<int>(static_cast<long>((x) + 1)); };
|
auto auxCeil2 = [](float x) { return static_cast<int32_t>(static_cast<int64_t>((x) + 1)); };
|
||||||
|
|
||||||
void complex_exp_gen(std::complex<float>* _dest, double _f, double _fs, unsigned int _samps)
|
void complex_exp_gen(std::complex<float>* _dest, double _f, double _fs, uint32_t _samps)
|
||||||
{
|
{
|
||||||
gr::fxpt_nco d_nco;
|
gr::fxpt_nco d_nco;
|
||||||
d_nco.set_freq((GPS_TWO_PI * _f) / _fs);
|
d_nco.set_freq((GPS_TWO_PI * _f) / _fs);
|
||||||
@ -46,14 +46,15 @@ void complex_exp_gen(std::complex<float>* _dest, double _f, double _fs, unsigned
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void complex_exp_gen_conj(std::complex<float>* _dest, double _f, double _fs, unsigned int _samps)
|
void complex_exp_gen_conj(std::complex<float>* _dest, double _f, double _fs, uint32_t _samps)
|
||||||
{
|
{
|
||||||
gr::fxpt_nco d_nco;
|
gr::fxpt_nco d_nco;
|
||||||
d_nco.set_freq(-(GPS_TWO_PI * _f) / _fs);
|
d_nco.set_freq(-(GPS_TWO_PI * _f) / _fs);
|
||||||
d_nco.sincos(_dest, _samps, 1);
|
d_nco.sincos(_dest, _samps, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hex_to_binary_converter(int* _dest, char _from)
|
|
||||||
|
void hex_to_binary_converter(int32_t* _dest, char _from)
|
||||||
{
|
{
|
||||||
switch (_from)
|
switch (_from)
|
||||||
{
|
{
|
||||||
@ -156,15 +157,16 @@ void hex_to_binary_converter(int* _dest, char _from)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void resampler(float* _from, float* _dest, float _fs_in,
|
|
||||||
float _fs_out, unsigned int _length_in, unsigned int _length_out)
|
void resampler(const float* _from, float* _dest, float _fs_in,
|
||||||
|
float _fs_out, uint32_t _length_in, uint32_t _length_out)
|
||||||
{
|
{
|
||||||
unsigned int _codeValueIndex;
|
uint32_t _codeValueIndex;
|
||||||
float aux;
|
float aux;
|
||||||
//--- Find time constants --------------------------------------------------
|
//--- Find time constants --------------------------------------------------
|
||||||
const float _t_in = 1 / _fs_in; // Incoming sampling period in sec
|
const float _t_in = 1 / _fs_in; // Incoming sampling period in sec
|
||||||
const float _t_out = 1 / _fs_out; // Out sampling period in sec
|
const float _t_out = 1 / _fs_out; // Out sampling period in sec
|
||||||
for (unsigned int i = 0; i < _length_out - 1; i++)
|
for (uint32_t i = 0; i < _length_out - 1; i++)
|
||||||
{
|
{
|
||||||
//=== Digitizing =======================================================
|
//=== Digitizing =======================================================
|
||||||
//--- compute index array to read sampled values -------------------------
|
//--- compute index array to read sampled values -------------------------
|
||||||
@ -179,15 +181,16 @@ void resampler(float* _from, float* _dest, float _fs_in,
|
|||||||
_dest[_length_out - 1] = _from[_length_in - 1];
|
_dest[_length_out - 1] = _from[_length_in - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void resampler(std::complex<float>* _from, std::complex<float>* _dest, float _fs_in,
|
|
||||||
float _fs_out, unsigned int _length_in, unsigned int _length_out)
|
void resampler(const std::complex<float>* _from, std::complex<float>* _dest, float _fs_in,
|
||||||
|
float _fs_out, uint32_t _length_in, uint32_t _length_out)
|
||||||
{
|
{
|
||||||
unsigned int _codeValueIndex;
|
uint32_t _codeValueIndex;
|
||||||
float aux;
|
float aux;
|
||||||
//--- Find time constants --------------------------------------------------
|
//--- Find time constants --------------------------------------------------
|
||||||
const float _t_in = 1 / _fs_in; // Incoming sampling period in sec
|
const float _t_in = 1 / _fs_in; // Incoming sampling period in sec
|
||||||
const float _t_out = 1 / _fs_out; // Out sampling period in sec
|
const float _t_out = 1 / _fs_out; // Out sampling period in sec
|
||||||
for (unsigned int i = 0; i < _length_out - 1; i++)
|
for (uint32_t i = 0; i < _length_out - 1; i++)
|
||||||
{
|
{
|
||||||
//=== Digitizing =======================================================
|
//=== Digitizing =======================================================
|
||||||
//--- compute index array to read sampled values -------------------------
|
//--- compute index array to read sampled values -------------------------
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#define GNSS_SDR_GNSS_SIGNAL_PROCESSING_H_
|
#define GNSS_SDR_GNSS_SIGNAL_PROCESSING_H_
|
||||||
|
|
||||||
#include <complex>
|
#include <complex>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -43,14 +44,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void complex_exp_gen(std::complex<float>* _dest, double _f, double _fs,
|
void complex_exp_gen(std::complex<float>* _dest, double _f, double _fs,
|
||||||
unsigned int _samps);
|
uint32_t _samps);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief This function generates a conjugate complex exponential in _dest.
|
* \brief This function generates a conjugate complex exponential in _dest.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void complex_exp_gen_conj(std::complex<float>* _dest, double _f, double _fs,
|
void complex_exp_gen_conj(std::complex<float>* _dest, double _f, double _fs,
|
||||||
unsigned int _samps);
|
uint32_t _samps);
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -58,21 +59,21 @@ void complex_exp_gen_conj(std::complex<float>* _dest, double _f, double _fs,
|
|||||||
* to binary (the output are 4 ints with +1 or -1 values).
|
* to binary (the output are 4 ints with +1 or -1 values).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void hex_to_binary_converter(int* _dest, char _from);
|
void hex_to_binary_converter(int32_t* _dest, char _from);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief This function resamples a sequence of float values.
|
* \brief This function resamples a sequence of float values.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void resampler(float* _from, float* _dest,
|
void resampler(const float* _from, float* _dest,
|
||||||
float _fs_in, float _fs_out, unsigned int _length_in,
|
float _fs_in, float _fs_out, uint32_t _length_in,
|
||||||
unsigned int _length_out);
|
uint32_t _length_out);
|
||||||
/*!
|
/*!
|
||||||
* \brief This function resamples a sequence of complex values.
|
* \brief This function resamples a sequence of complex values.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void resampler(std::complex<float>* _from, std::complex<float>* _dest,
|
void resampler(const std::complex<float>* _from, std::complex<float>* _dest,
|
||||||
float _fs_in, float _fs_out, unsigned int _length_in,
|
float _fs_in, float _fs_out, uint32_t _length_in,
|
||||||
unsigned int _length_out);
|
uint32_t _length_out);
|
||||||
|
|
||||||
#endif /* GNSS_SDR_GNSS_SIGNAL_PROCESSING_H_ */
|
#endif /* GNSS_SDR_GNSS_SIGNAL_PROCESSING_H_ */
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
|
|
||||||
#include "gps_l2c_signal.h"
|
#include "gps_l2c_signal.h"
|
||||||
#include "GPS_L2C.h"
|
#include "GPS_L2C.h"
|
||||||
#include <cstdint>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
|
||||||
@ -42,11 +41,11 @@ int32_t gps_l2c_m_shift(int32_t x)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void gps_l2c_m_code(int32_t* _dest, unsigned int _prn)
|
void gps_l2c_m_code(int32_t* _dest, uint32_t _prn)
|
||||||
{
|
{
|
||||||
int32_t x;
|
int32_t x;
|
||||||
x = GPS_L2C_M_INIT_REG[_prn - 1];
|
x = GPS_L2C_M_INIT_REG[_prn - 1];
|
||||||
for (int n = 0; n < GPS_L2_M_CODE_LENGTH_CHIPS; n++)
|
for (int32_t n = 0; n < GPS_L2_M_CODE_LENGTH_CHIPS; n++)
|
||||||
{
|
{
|
||||||
_dest[n] = static_cast<int8_t>(x & 1);
|
_dest[n] = static_cast<int8_t>(x & 1);
|
||||||
x = gps_l2c_m_shift(x);
|
x = gps_l2c_m_shift(x);
|
||||||
@ -54,7 +53,7 @@ void gps_l2c_m_code(int32_t* _dest, unsigned int _prn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void gps_l2c_m_code_gen_complex(std::complex<float>* _dest, unsigned int _prn)
|
void gps_l2c_m_code_gen_complex(std::complex<float>* _dest, uint32_t _prn)
|
||||||
{
|
{
|
||||||
int32_t* _code = new int32_t[GPS_L2_M_CODE_LENGTH_CHIPS];
|
int32_t* _code = new int32_t[GPS_L2_M_CODE_LENGTH_CHIPS];
|
||||||
|
|
||||||
@ -63,7 +62,7 @@ void gps_l2c_m_code_gen_complex(std::complex<float>* _dest, unsigned int _prn)
|
|||||||
gps_l2c_m_code(_code, _prn);
|
gps_l2c_m_code(_code, _prn);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (signed int i = 0; i < GPS_L2_M_CODE_LENGTH_CHIPS; i++)
|
for (int32_t i = 0; i < GPS_L2_M_CODE_LENGTH_CHIPS; i++)
|
||||||
{
|
{
|
||||||
_dest[i] = std::complex<float>(1.0 - 2.0 * _code[i], 0.0);
|
_dest[i] = std::complex<float>(1.0 - 2.0 * _code[i], 0.0);
|
||||||
}
|
}
|
||||||
@ -71,7 +70,8 @@ void gps_l2c_m_code_gen_complex(std::complex<float>* _dest, unsigned int _prn)
|
|||||||
delete[] _code;
|
delete[] _code;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gps_l2c_m_code_gen_float(float* _dest, unsigned int _prn)
|
|
||||||
|
void gps_l2c_m_code_gen_float(float* _dest, uint32_t _prn)
|
||||||
{
|
{
|
||||||
int32_t* _code = new int32_t[GPS_L2_M_CODE_LENGTH_CHIPS];
|
int32_t* _code = new int32_t[GPS_L2_M_CODE_LENGTH_CHIPS];
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ void gps_l2c_m_code_gen_float(float* _dest, unsigned int _prn)
|
|||||||
gps_l2c_m_code(_code, _prn);
|
gps_l2c_m_code(_code, _prn);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (signed int i = 0; i < GPS_L2_M_CODE_LENGTH_CHIPS; i++)
|
for (int32_t i = 0; i < GPS_L2_M_CODE_LENGTH_CHIPS; i++)
|
||||||
{
|
{
|
||||||
_dest[i] = 1.0 - 2.0 * static_cast<float>(_code[i]);
|
_dest[i] = 1.0 - 2.0 * static_cast<float>(_code[i]);
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ void gps_l2c_m_code_gen_float(float* _dest, unsigned int _prn)
|
|||||||
/*
|
/*
|
||||||
* Generates complex GPS L2C M code for the desired SV ID and sampled to specific sampling frequency
|
* Generates complex GPS L2C M code for the desired SV ID and sampled to specific sampling frequency
|
||||||
*/
|
*/
|
||||||
void gps_l2c_m_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _prn, signed int _fs)
|
void gps_l2c_m_code_gen_complex_sampled(std::complex<float>* _dest, uint32_t _prn, int32_t _fs)
|
||||||
{
|
{
|
||||||
int32_t* _code = new int32_t[GPS_L2_M_CODE_LENGTH_CHIPS];
|
int32_t* _code = new int32_t[GPS_L2_M_CODE_LENGTH_CHIPS];
|
||||||
if (_prn > 0 and _prn < 51)
|
if (_prn > 0 and _prn < 51)
|
||||||
@ -100,20 +100,20 @@ void gps_l2c_m_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int
|
|||||||
gps_l2c_m_code(_code, _prn);
|
gps_l2c_m_code(_code, _prn);
|
||||||
}
|
}
|
||||||
|
|
||||||
signed int _samplesPerCode, _codeValueIndex;
|
int32_t _samplesPerCode, _codeValueIndex;
|
||||||
float _ts;
|
float _ts;
|
||||||
float _tc;
|
float _tc;
|
||||||
const signed int _codeLength = GPS_L2_M_CODE_LENGTH_CHIPS;
|
const int32_t _codeLength = GPS_L2_M_CODE_LENGTH_CHIPS;
|
||||||
|
|
||||||
//--- Find number of samples per spreading code ----------------------------
|
//--- Find number of samples per spreading code ----------------------------
|
||||||
_samplesPerCode = static_cast<int>(static_cast<double>(_fs) / (static_cast<double>(GPS_L2_M_CODE_RATE_HZ) / static_cast<double>(_codeLength)));
|
_samplesPerCode = static_cast<int32_t>(static_cast<double>(_fs) / (static_cast<double>(GPS_L2_M_CODE_RATE_HZ) / static_cast<double>(_codeLength)));
|
||||||
|
|
||||||
//--- Find time constants --------------------------------------------------
|
//--- Find time constants --------------------------------------------------
|
||||||
_ts = 1.0 / static_cast<float>(_fs); // Sampling period in sec
|
_ts = 1.0 / static_cast<float>(_fs); // Sampling period in sec
|
||||||
_tc = 1.0 / static_cast<float>(GPS_L2_M_CODE_RATE_HZ); // C/A chip period in sec
|
_tc = 1.0 / static_cast<float>(GPS_L2_M_CODE_RATE_HZ); // C/A chip period in sec
|
||||||
|
|
||||||
//float aux;
|
//float aux;
|
||||||
for (signed int i = 0; i < _samplesPerCode; i++)
|
for (int32_t i = 0; i < _samplesPerCode; i++)
|
||||||
{
|
{
|
||||||
//=== Digitizing =======================================================
|
//=== Digitizing =======================================================
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ void gps_l2c_m_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int
|
|||||||
//TODO: Check this formula! Seems to start with an extra sample
|
//TODO: Check this formula! Seems to start with an extra sample
|
||||||
_codeValueIndex = ceil((_ts * (static_cast<float>(i) + 1)) / _tc) - 1;
|
_codeValueIndex = ceil((_ts * (static_cast<float>(i) + 1)) / _tc) - 1;
|
||||||
//aux = (_ts * (i + 1)) / _tc;
|
//aux = (_ts * (i + 1)) / _tc;
|
||||||
//_codeValueIndex = static_cast<int>(static_cast<long>(aux)) - 1;
|
//_codeValueIndex = static_cast<int32_t>(static_cast<long>(aux)) - 1;
|
||||||
|
|
||||||
//--- Make the digitized version of the L2C code -----------------------
|
//--- Make the digitized version of the L2C code -----------------------
|
||||||
if (i == _samplesPerCode - 1)
|
if (i == _samplesPerCode - 1)
|
||||||
|
@ -34,13 +34,14 @@
|
|||||||
#define GNSS_SDR_GPS_L2C_SIGNAL_H_
|
#define GNSS_SDR_GPS_L2C_SIGNAL_H_
|
||||||
|
|
||||||
#include <complex>
|
#include <complex>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
||||||
//! Generates complex GPS L2C M code for the desired SV ID
|
//! Generates complex GPS L2C M code for the desired SV ID
|
||||||
void gps_l2c_m_code_gen_complex(std::complex<float>* _dest, unsigned int _prn);
|
void gps_l2c_m_code_gen_complex(std::complex<float>* _dest, uint32_t _prn);
|
||||||
void gps_l2c_m_code_gen_float(float* _dest, unsigned int _prn);
|
void gps_l2c_m_code_gen_float(float* _dest, uint32_t _prn);
|
||||||
|
|
||||||
//! Generates complex GPS L2C M code for the desired SV ID, and sampled to specific sampling frequency
|
//! Generates complex GPS L2C M code for the desired SV ID, and sampled to specific sampling frequency
|
||||||
void gps_l2c_m_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _prn, signed int _fs);
|
void gps_l2c_m_code_gen_complex_sampled(std::complex<float>* _dest, uint32_t _prn, int32_t _fs);
|
||||||
|
|
||||||
#endif /* GNSS_GPS_L2C_SIGNAL_H_ */
|
#endif /* GNSS_GPS_L2C_SIGNAL_H_ */
|
||||||
|
@ -89,7 +89,7 @@ std::deque<bool> make_l5i_xa()
|
|||||||
std::deque<bool> xa = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
std::deque<bool> xa = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||||
std::deque<bool> y(GPS_L5i_CODE_LENGTH_CHIPS, 0);
|
std::deque<bool> y(GPS_L5i_CODE_LENGTH_CHIPS, 0);
|
||||||
|
|
||||||
for (int i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++)
|
for (int32_t i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++)
|
||||||
{
|
{
|
||||||
y[i] = xa[12];
|
y[i] = xa[12];
|
||||||
xa = l5i_xa_shift(xa);
|
xa = l5i_xa_shift(xa);
|
||||||
@ -103,7 +103,7 @@ std::deque<bool> make_l5i_xb()
|
|||||||
std::deque<bool> xb = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
std::deque<bool> xb = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||||
std::deque<bool> y(GPS_L5i_CODE_LENGTH_CHIPS, 0);
|
std::deque<bool> y(GPS_L5i_CODE_LENGTH_CHIPS, 0);
|
||||||
|
|
||||||
for (int i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++)
|
for (int32_t i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++)
|
||||||
{
|
{
|
||||||
y[i] = xb[12];
|
y[i] = xb[12];
|
||||||
xb = l5i_xb_shift(xb);
|
xb = l5i_xb_shift(xb);
|
||||||
@ -117,7 +117,7 @@ std::deque<bool> make_l5q_xa()
|
|||||||
std::deque<bool> xa = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
std::deque<bool> xa = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||||
std::deque<bool> y(GPS_L5q_CODE_LENGTH_CHIPS, 0);
|
std::deque<bool> y(GPS_L5q_CODE_LENGTH_CHIPS, 0);
|
||||||
|
|
||||||
for (int i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++)
|
for (int32_t i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++)
|
||||||
{
|
{
|
||||||
y[i] = xa[12];
|
y[i] = xa[12];
|
||||||
xa = l5q_xa_shift(xa);
|
xa = l5q_xa_shift(xa);
|
||||||
@ -131,7 +131,7 @@ std::deque<bool> make_l5q_xb()
|
|||||||
std::deque<bool> xb = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
std::deque<bool> xb = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||||
std::deque<bool> y(GPS_L5q_CODE_LENGTH_CHIPS, 0);
|
std::deque<bool> y(GPS_L5q_CODE_LENGTH_CHIPS, 0);
|
||||||
|
|
||||||
for (int i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++)
|
for (int32_t i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++)
|
||||||
{
|
{
|
||||||
y[i] = xb[12];
|
y[i] = xb[12];
|
||||||
xb = l5q_xb_shift(xb);
|
xb = l5q_xb_shift(xb);
|
||||||
@ -140,47 +140,47 @@ std::deque<bool> make_l5q_xb()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void make_l5i(int32_t* _dest, int prn)
|
void make_l5i(int32_t* _dest, int32_t prn)
|
||||||
{
|
{
|
||||||
int xb_offset = GPS_L5i_INIT_REG[prn];
|
int32_t xb_offset = GPS_L5i_INIT_REG[prn];
|
||||||
|
|
||||||
std::deque<bool> xb = make_l5i_xb();
|
std::deque<bool> xb = make_l5i_xb();
|
||||||
std::deque<bool> xa = make_l5i_xa();
|
std::deque<bool> xa = make_l5i_xa();
|
||||||
std::deque<bool> xb_shift(GPS_L5i_CODE_LENGTH_CHIPS, 0);
|
std::deque<bool> xb_shift(GPS_L5i_CODE_LENGTH_CHIPS, 0);
|
||||||
|
|
||||||
for (int n = 0; n < GPS_L5i_CODE_LENGTH_CHIPS; n++)
|
for (int32_t n = 0; n < GPS_L5i_CODE_LENGTH_CHIPS; n++)
|
||||||
{
|
{
|
||||||
xb_shift[n] = xb[(xb_offset + n) % GPS_L5i_CODE_LENGTH_CHIPS];
|
xb_shift[n] = xb[(xb_offset + n) % GPS_L5i_CODE_LENGTH_CHIPS];
|
||||||
}
|
}
|
||||||
std::deque<bool> out_code(GPS_L5i_CODE_LENGTH_CHIPS, 0);
|
std::deque<bool> out_code(GPS_L5i_CODE_LENGTH_CHIPS, 0);
|
||||||
for (int n = 0; n < GPS_L5i_CODE_LENGTH_CHIPS; n++)
|
for (int32_t n = 0; n < GPS_L5i_CODE_LENGTH_CHIPS; n++)
|
||||||
{
|
{
|
||||||
_dest[n] = xa[n] xor xb_shift[n];
|
_dest[n] = xa[n] xor xb_shift[n];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void make_l5q(int32_t* _dest, int prn)
|
void make_l5q(int32_t* _dest, int32_t prn)
|
||||||
{
|
{
|
||||||
int xb_offset = GPS_L5q_INIT_REG[prn];
|
int32_t xb_offset = GPS_L5q_INIT_REG[prn];
|
||||||
|
|
||||||
std::deque<bool> xb = make_l5q_xb();
|
std::deque<bool> xb = make_l5q_xb();
|
||||||
std::deque<bool> xa = make_l5q_xa();
|
std::deque<bool> xa = make_l5q_xa();
|
||||||
std::deque<bool> xb_shift(GPS_L5q_CODE_LENGTH_CHIPS, 0);
|
std::deque<bool> xb_shift(GPS_L5q_CODE_LENGTH_CHIPS, 0);
|
||||||
|
|
||||||
for (int n = 0; n < GPS_L5q_CODE_LENGTH_CHIPS; n++)
|
for (int32_t n = 0; n < GPS_L5q_CODE_LENGTH_CHIPS; n++)
|
||||||
{
|
{
|
||||||
xb_shift[n] = xb[(xb_offset + n) % GPS_L5q_CODE_LENGTH_CHIPS];
|
xb_shift[n] = xb[(xb_offset + n) % GPS_L5q_CODE_LENGTH_CHIPS];
|
||||||
}
|
}
|
||||||
std::deque<bool> out_code(GPS_L5q_CODE_LENGTH_CHIPS, 0);
|
std::deque<bool> out_code(GPS_L5q_CODE_LENGTH_CHIPS, 0);
|
||||||
for (int n = 0; n < GPS_L5q_CODE_LENGTH_CHIPS; n++)
|
for (int32_t n = 0; n < GPS_L5q_CODE_LENGTH_CHIPS; n++)
|
||||||
{
|
{
|
||||||
_dest[n] = xa[n] xor xb_shift[n];
|
_dest[n] = xa[n] xor xb_shift[n];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void gps_l5i_code_gen_complex(std::complex<float>* _dest, unsigned int _prn)
|
void gps_l5i_code_gen_complex(std::complex<float>* _dest, uint32_t _prn)
|
||||||
{
|
{
|
||||||
int32_t* _code = new int32_t[GPS_L5i_CODE_LENGTH_CHIPS];
|
int32_t* _code = new int32_t[GPS_L5i_CODE_LENGTH_CHIPS];
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ void gps_l5i_code_gen_complex(std::complex<float>* _dest, unsigned int _prn)
|
|||||||
make_l5i(_code, _prn - 1);
|
make_l5i(_code, _prn - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (signed int i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++)
|
for (int32_t i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++)
|
||||||
{
|
{
|
||||||
_dest[i] = std::complex<float>(1.0 - 2.0 * _code[i], 0.0);
|
_dest[i] = std::complex<float>(1.0 - 2.0 * _code[i], 0.0);
|
||||||
}
|
}
|
||||||
@ -197,7 +197,8 @@ void gps_l5i_code_gen_complex(std::complex<float>* _dest, unsigned int _prn)
|
|||||||
delete[] _code;
|
delete[] _code;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gps_l5i_code_gen_float(float* _dest, unsigned int _prn)
|
|
||||||
|
void gps_l5i_code_gen_float(float* _dest, uint32_t _prn)
|
||||||
{
|
{
|
||||||
int32_t* _code = new int32_t[GPS_L5i_CODE_LENGTH_CHIPS];
|
int32_t* _code = new int32_t[GPS_L5i_CODE_LENGTH_CHIPS];
|
||||||
|
|
||||||
@ -206,7 +207,7 @@ void gps_l5i_code_gen_float(float* _dest, unsigned int _prn)
|
|||||||
make_l5i(_code, _prn - 1);
|
make_l5i(_code, _prn - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (signed int i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++)
|
for (int32_t i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++)
|
||||||
{
|
{
|
||||||
_dest[i] = 1.0 - 2.0 * static_cast<float>(_code[i]);
|
_dest[i] = 1.0 - 2.0 * static_cast<float>(_code[i]);
|
||||||
}
|
}
|
||||||
@ -214,10 +215,11 @@ void gps_l5i_code_gen_float(float* _dest, unsigned int _prn)
|
|||||||
delete[] _code;
|
delete[] _code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generates complex GPS L5i code for the desired SV ID and sampled to specific sampling frequency
|
* Generates complex GPS L5i code for the desired SV ID and sampled to specific sampling frequency
|
||||||
*/
|
*/
|
||||||
void gps_l5i_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _prn, signed int _fs)
|
void gps_l5i_code_gen_complex_sampled(std::complex<float>* _dest, uint32_t _prn, int32_t _fs)
|
||||||
{
|
{
|
||||||
int32_t* _code = new int32_t[GPS_L5i_CODE_LENGTH_CHIPS];
|
int32_t* _code = new int32_t[GPS_L5i_CODE_LENGTH_CHIPS];
|
||||||
if (_prn > 0 and _prn < 51)
|
if (_prn > 0 and _prn < 51)
|
||||||
@ -225,20 +227,20 @@ void gps_l5i_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _
|
|||||||
make_l5i(_code, _prn - 1);
|
make_l5i(_code, _prn - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
signed int _samplesPerCode, _codeValueIndex;
|
int32_t _samplesPerCode, _codeValueIndex;
|
||||||
float _ts;
|
float _ts;
|
||||||
float _tc;
|
float _tc;
|
||||||
const signed int _codeLength = GPS_L5i_CODE_LENGTH_CHIPS;
|
const int32_t _codeLength = GPS_L5i_CODE_LENGTH_CHIPS;
|
||||||
|
|
||||||
//--- Find number of samples per spreading code ----------------------------
|
//--- Find number of samples per spreading code ----------------------------
|
||||||
_samplesPerCode = static_cast<int>(static_cast<double>(_fs) / (static_cast<double>(GPS_L5i_CODE_RATE_HZ) / static_cast<double>(_codeLength)));
|
_samplesPerCode = static_cast<int32_t>(static_cast<double>(_fs) / (static_cast<double>(GPS_L5i_CODE_RATE_HZ) / static_cast<double>(_codeLength)));
|
||||||
|
|
||||||
//--- Find time constants --------------------------------------------------
|
//--- Find time constants --------------------------------------------------
|
||||||
_ts = 1.0 / static_cast<float>(_fs); // Sampling period in sec
|
_ts = 1.0 / static_cast<float>(_fs); // Sampling period in sec
|
||||||
_tc = 1.0 / static_cast<float>(GPS_L5i_CODE_RATE_HZ); // C/A chip period in sec
|
_tc = 1.0 / static_cast<float>(GPS_L5i_CODE_RATE_HZ); // C/A chip period in sec
|
||||||
|
|
||||||
//float aux;
|
//float aux;
|
||||||
for (signed int i = 0; i < _samplesPerCode; i++)
|
for (int32_t i = 0; i < _samplesPerCode; i++)
|
||||||
{
|
{
|
||||||
//=== Digitizing =======================================================
|
//=== Digitizing =======================================================
|
||||||
|
|
||||||
@ -246,7 +248,7 @@ void gps_l5i_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _
|
|||||||
//TODO: Check this formula! Seems to start with an extra sample
|
//TODO: Check this formula! Seems to start with an extra sample
|
||||||
_codeValueIndex = ceil((_ts * (static_cast<float>(i) + 1)) / _tc) - 1;
|
_codeValueIndex = ceil((_ts * (static_cast<float>(i) + 1)) / _tc) - 1;
|
||||||
//aux = (_ts * (i + 1)) / _tc;
|
//aux = (_ts * (i + 1)) / _tc;
|
||||||
//_codeValueIndex = static_cast<int>(static_cast<long>(aux)) - 1;
|
//_codeValueIndex = static_cast<int32_t> (static_cast<long>(aux)) - 1;
|
||||||
|
|
||||||
//--- Make the digitized version of the L2C code -----------------------
|
//--- Make the digitized version of the L2C code -----------------------
|
||||||
if (i == _samplesPerCode - 1)
|
if (i == _samplesPerCode - 1)
|
||||||
@ -263,7 +265,7 @@ void gps_l5i_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void gps_l5q_code_gen_complex(std::complex<float>* _dest, unsigned int _prn)
|
void gps_l5q_code_gen_complex(std::complex<float>* _dest, uint32_t _prn)
|
||||||
{
|
{
|
||||||
int32_t* _code = new int32_t[GPS_L5q_CODE_LENGTH_CHIPS];
|
int32_t* _code = new int32_t[GPS_L5q_CODE_LENGTH_CHIPS];
|
||||||
|
|
||||||
@ -272,7 +274,7 @@ void gps_l5q_code_gen_complex(std::complex<float>* _dest, unsigned int _prn)
|
|||||||
make_l5q(_code, _prn - 1);
|
make_l5q(_code, _prn - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (signed int i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++)
|
for (int32_t i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++)
|
||||||
{
|
{
|
||||||
_dest[i] = std::complex<float>(1.0 - 2.0 * _code[i], 0.0);
|
_dest[i] = std::complex<float>(1.0 - 2.0 * _code[i], 0.0);
|
||||||
}
|
}
|
||||||
@ -280,7 +282,8 @@ void gps_l5q_code_gen_complex(std::complex<float>* _dest, unsigned int _prn)
|
|||||||
delete[] _code;
|
delete[] _code;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gps_l5q_code_gen_float(float* _dest, unsigned int _prn)
|
|
||||||
|
void gps_l5q_code_gen_float(float* _dest, uint32_t _prn)
|
||||||
{
|
{
|
||||||
int32_t* _code = new int32_t[GPS_L5q_CODE_LENGTH_CHIPS];
|
int32_t* _code = new int32_t[GPS_L5q_CODE_LENGTH_CHIPS];
|
||||||
|
|
||||||
@ -289,17 +292,19 @@ void gps_l5q_code_gen_float(float* _dest, unsigned int _prn)
|
|||||||
make_l5q(_code, _prn - 1);
|
make_l5q(_code, _prn - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (signed int i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++)
|
for (int32_t i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++)
|
||||||
{
|
{
|
||||||
_dest[i] = 1.0 - 2.0 * static_cast<float>(_code[i]);
|
_dest[i] = 1.0 - 2.0 * static_cast<float>(_code[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] _code;
|
delete[] _code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generates complex GPS L5i code for the desired SV ID and sampled to specific sampling frequency
|
* Generates complex GPS L5i code for the desired SV ID and sampled to specific sampling frequency
|
||||||
*/
|
*/
|
||||||
void gps_l5q_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _prn, signed int _fs)
|
void gps_l5q_code_gen_complex_sampled(std::complex<float>* _dest, uint32_t _prn, int32_t _fs)
|
||||||
{
|
{
|
||||||
int32_t* _code = new int32_t[GPS_L5q_CODE_LENGTH_CHIPS];
|
int32_t* _code = new int32_t[GPS_L5q_CODE_LENGTH_CHIPS];
|
||||||
if (_prn > 0 and _prn < 51)
|
if (_prn > 0 and _prn < 51)
|
||||||
@ -307,20 +312,20 @@ void gps_l5q_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _
|
|||||||
make_l5q(_code, _prn - 1);
|
make_l5q(_code, _prn - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
signed int _samplesPerCode, _codeValueIndex;
|
int32_t _samplesPerCode, _codeValueIndex;
|
||||||
float _ts;
|
float _ts;
|
||||||
float _tc;
|
float _tc;
|
||||||
const signed int _codeLength = GPS_L5q_CODE_LENGTH_CHIPS;
|
const int32_t _codeLength = GPS_L5q_CODE_LENGTH_CHIPS;
|
||||||
|
|
||||||
//--- Find number of samples per spreading code ----------------------------
|
//--- Find number of samples per spreading code ----------------------------
|
||||||
_samplesPerCode = static_cast<int>(static_cast<double>(_fs) / (static_cast<double>(GPS_L5q_CODE_RATE_HZ) / static_cast<double>(_codeLength)));
|
_samplesPerCode = static_cast<int32_t>(static_cast<double>(_fs) / (static_cast<double>(GPS_L5q_CODE_RATE_HZ) / static_cast<double>(_codeLength)));
|
||||||
|
|
||||||
//--- Find time constants --------------------------------------------------
|
//--- Find time constants --------------------------------------------------
|
||||||
_ts = 1.0 / static_cast<float>(_fs); // Sampling period in sec
|
_ts = 1.0 / static_cast<float>(_fs); // Sampling period in sec
|
||||||
_tc = 1.0 / static_cast<float>(GPS_L5q_CODE_RATE_HZ); // C/A chip period in sec
|
_tc = 1.0 / static_cast<float>(GPS_L5q_CODE_RATE_HZ); // C/A chip period in sec
|
||||||
|
|
||||||
//float aux;
|
//float aux;
|
||||||
for (signed int i = 0; i < _samplesPerCode; i++)
|
for (int32_t i = 0; i < _samplesPerCode; i++)
|
||||||
{
|
{
|
||||||
//=== Digitizing =======================================================
|
//=== Digitizing =======================================================
|
||||||
|
|
||||||
@ -328,7 +333,7 @@ void gps_l5q_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _
|
|||||||
//TODO: Check this formula! Seems to start with an extra sample
|
//TODO: Check this formula! Seems to start with an extra sample
|
||||||
_codeValueIndex = ceil((_ts * (static_cast<float>(i) + 1)) / _tc) - 1;
|
_codeValueIndex = ceil((_ts * (static_cast<float>(i) + 1)) / _tc) - 1;
|
||||||
//aux = (_ts * (i + 1)) / _tc;
|
//aux = (_ts * (i + 1)) / _tc;
|
||||||
//_codeValueIndex = static_cast<int>(static_cast<long>(aux)) - 1;
|
//_codeValueIndex = static_cast<int32_t> (static_cast<long>(aux)) - 1;
|
||||||
|
|
||||||
//--- Make the digitized version of the L2C code -----------------------
|
//--- Make the digitized version of the L2C code -----------------------
|
||||||
if (i == _samplesPerCode - 1)
|
if (i == _samplesPerCode - 1)
|
||||||
|
@ -34,21 +34,21 @@
|
|||||||
#define GNSS_SDR_GPS_L5_SIGNAL_H_
|
#define GNSS_SDR_GPS_L5_SIGNAL_H_
|
||||||
|
|
||||||
#include <complex>
|
#include <complex>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
//!Generates complex GPS L5i M code for the desired SV ID
|
//!Generates complex GPS L5i M code for the desired SV ID
|
||||||
void gps_l5i_code_gen_complex(std::complex<float>* _dest, unsigned int _prn);
|
void gps_l5i_code_gen_complex(std::complex<float>* _dest, uint32_t _prn);
|
||||||
void gps_l5i_code_gen_float(float* _dest, unsigned int _prn);
|
void gps_l5i_code_gen_float(float* _dest, uint32_t _prn);
|
||||||
|
|
||||||
//!Generates complex GPS L5q M code for the desired SV ID
|
//!Generates complex GPS L5q M code for the desired SV ID
|
||||||
void gps_l5q_code_gen_complex(std::complex<float>* _dest, unsigned int _prn);
|
void gps_l5q_code_gen_complex(std::complex<float>* _dest, uint32_t _prn);
|
||||||
void gps_l5q_code_gen_float(float* _dest, unsigned int _prn);
|
void gps_l5q_code_gen_float(float* _dest, uint32_t _prn);
|
||||||
|
|
||||||
//! Generates complex GPS L5i M code for the desired SV ID, and sampled to specific sampling frequency
|
//! Generates complex GPS L5i M code for the desired SV ID, and sampled to specific sampling frequency
|
||||||
void gps_l5i_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _prn, signed int _fs);
|
void gps_l5i_code_gen_complex_sampled(std::complex<float>* _dest, uint32_t _prn, int32_t _fs);
|
||||||
|
|
||||||
//! Generates complex GPS L5q M code for the desired SV ID, and sampled to specific sampling frequency
|
//! Generates complex GPS L5q M code for the desired SV ID, and sampled to specific sampling frequency
|
||||||
void gps_l5q_code_gen_complex_sampled(std::complex<float>* _dest, unsigned int _prn, signed int _fs);
|
void gps_l5q_code_gen_complex_sampled(std::complex<float>* _dest, uint32_t _prn, int32_t _fs);
|
||||||
|
|
||||||
|
|
||||||
#endif /* GNSS_SDR_GPS_L5_SIGNAL_H_ */
|
#endif /* GNSS_SDR_GPS_L5_SIGNAL_H_ */
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user