mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-01-18 21:23:02 +00:00
Merge branch 'next' of https://github.com/gnss-sdr/gnss-sdr into vtl_experimental
This commit is contained in:
commit
bb256c0650
@ -329,7 +329,7 @@ set(GNSSSDR_GTEST_LOCAL_VERSION "1.10.0")
|
||||
set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master")
|
||||
set(GNSSSDR_GPSTK_LOCAL_VERSION "3.0.0")
|
||||
set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.18")
|
||||
set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.10")
|
||||
set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.11")
|
||||
set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.14.0")
|
||||
set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.5.2")
|
||||
set(GNSSSDR_MATHJAX_EXTERNAL_VERSION "2.7.7")
|
||||
@ -1133,6 +1133,9 @@ if(NOT VOLKGNSSSDR_FOUND)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
|
||||
set(SUPPORTED_CPU_FEATURES_ARCH TRUE)
|
||||
endif()
|
||||
if(${CMAKE_INSTALL_LIBDIR} MATCHES lib64)
|
||||
set(VOLK_GNSSSDR_LIB_SUFFIX 64)
|
||||
endif()
|
||||
if(CMAKE_VERSION VERSION_LESS 3.2)
|
||||
ExternalProject_Add(volk_gnsssdr_module
|
||||
PREFIX ${CMAKE_BINARY_DIR}/volk_gnsssdr_module
|
||||
@ -1140,6 +1143,7 @@ if(NOT VOLKGNSSSDR_FOUND)
|
||||
BINARY_DIR ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/build
|
||||
CMAKE_ARGS ${VOLK_GNSSSDR_CMAKE_ARGS}
|
||||
-DCMAKE_BUILD_TYPE=$<$<CONFIG:None>:None>$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel>$<$<CONFIG:NoOptWithASM>:NoOptWithASM>$<$<CONFIG:Coverage>:Coverage>$<$<CONFIG:O2WithASM>:O2WithASM>$<$<CONFIG:O3WithASM>:O3WithASM>$<$<CONFIG:ASAN>:ASAN>
|
||||
-DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
|
||||
DOWNLOAD_COMMAND ""
|
||||
UPDATE_COMMAND ""
|
||||
PATCH_COMMAND ""
|
||||
@ -1154,11 +1158,12 @@ if(NOT VOLKGNSSSDR_FOUND)
|
||||
BINARY_DIR ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/build
|
||||
CMAKE_ARGS ${VOLK_GNSSSDR_CMAKE_ARGS}
|
||||
-DCMAKE_BUILD_TYPE=$<$<CONFIG:None>:None>$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel>$<$<CONFIG:NoOptWithASM>:NoOptWithASM>$<$<CONFIG:Coverage>:Coverage>$<$<CONFIG:O2WithASM>:O2WithASM>$<$<CONFIG:O3WithASM>:O3WithASM>$<$<CONFIG:ASAN>:ASAN>
|
||||
-DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
|
||||
DOWNLOAD_COMMAND ""
|
||||
UPDATE_COMMAND ""
|
||||
PATCH_COMMAND ""
|
||||
BUILD_COMMAND ${VOLK_GNSSSDR_BUILD_COMMAND} volk_gnsssdr_profile
|
||||
BUILD_BYPRODUCTS ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/lib/${CMAKE_FIND_LIBRARY_PREFIXES}volk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX}
|
||||
BUILD_BYPRODUCTS ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/lib${VOLK_GNSSSDR_LIB_SUFFIX}/${CMAKE_FIND_LIBRARY_PREFIXES}volk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX}
|
||||
${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/bin/volk_gnsssdr_profile
|
||||
${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/${CMAKE_INSTALL_LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}cpu_features${CMAKE_STATIC_LIBRARY_SUFFIX}
|
||||
INSTALL_DIR ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install
|
||||
@ -1170,11 +1175,12 @@ if(NOT VOLKGNSSSDR_FOUND)
|
||||
BINARY_DIR ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/build
|
||||
CMAKE_ARGS ${VOLK_GNSSSDR_CMAKE_ARGS}
|
||||
-DCMAKE_BUILD_TYPE=$<$<CONFIG:None>:None>$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel>$<$<CONFIG:NoOptWithASM>:NoOptWithASM>$<$<CONFIG:Coverage>:Coverage>$<$<CONFIG:O2WithASM>:O2WithASM>$<$<CONFIG:O3WithASM>:O3WithASM>$<$<CONFIG:ASAN>:ASAN>
|
||||
-DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
|
||||
DOWNLOAD_COMMAND ""
|
||||
UPDATE_COMMAND ""
|
||||
PATCH_COMMAND ""
|
||||
BUILD_COMMAND ${VOLK_GNSSSDR_BUILD_COMMAND} volk_gnsssdr_profile
|
||||
BUILD_BYPRODUCTS ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/lib/${CMAKE_FIND_LIBRARY_PREFIXES}volk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX}
|
||||
BUILD_BYPRODUCTS ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/lib${VOLK_GNSSSDR_LIB_SUFFIX}/${CMAKE_FIND_LIBRARY_PREFIXES}volk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX}
|
||||
${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/bin/volk_gnsssdr_profile
|
||||
INSTALL_DIR ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install
|
||||
)
|
||||
@ -1187,7 +1193,7 @@ if(NOT VOLKGNSSSDR_FOUND)
|
||||
endif()
|
||||
|
||||
add_library(volk_gnsssdr UNKNOWN IMPORTED)
|
||||
set_property(TARGET volk_gnsssdr PROPERTY IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/lib/libvolk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
set_property(TARGET volk_gnsssdr PROPERTY IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/lib${VOLK_GNSSSDR_LIB_SUFFIX}/libvolk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
set(VOLK_GNSSSDR_INCLUDE_DIRS "${CMAKE_BINARY_DIR}/volk_gnsssdr_module/build/include/;${CMAKE_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/include;${ORC_INCLUDE_DIRS}")
|
||||
set(VOLK_GNSSSDR_LIBRARIES volk_gnsssdr ${ORC_LIBRARIES})
|
||||
|
||||
@ -1197,7 +1203,7 @@ if(NOT VOLKGNSSSDR_FOUND)
|
||||
add_dependencies(Volkgnsssdr::volkgnsssdr volk_gnsssdr_module)
|
||||
set_target_properties(Volkgnsssdr::volkgnsssdr PROPERTIES
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
|
||||
IMPORTED_LOCATION "${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/lib/libvolk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
IMPORTED_LOCATION "${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/lib${VOLK_GNSSSDR_LIB_SUFFIX}/libvolk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
INCLUDE_DIRECTORIES "${VOLK_GNSSSDR_INCLUDE_DIRS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${VOLK_GNSSSDR_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${VOLK_GNSSSDR_LIBRARIES}"
|
||||
|
@ -125,6 +125,7 @@ if(ENABLE_FPGA)
|
||||
target_link_libraries(acquisition_adapters
|
||||
PRIVATE
|
||||
algorithms_libs
|
||||
core_libs
|
||||
Gnuradio::fft
|
||||
Volk::volk
|
||||
Volkgnsssdr::volkgnsssdr
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "galileo_e1_signal_replica.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gnss_sdr_make_unique.h"
|
||||
#include "uio_fpga.h"
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/fft/fft.h> // for fft_complex
|
||||
#include <gnuradio/gr_complex.h> // for gr_complex
|
||||
@ -77,11 +78,18 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
|
||||
float nbits = ceilf(log2f(static_cast<float>(code_length) * 2.0F));
|
||||
uint32_t nsamples_total = pow(2, nbits);
|
||||
uint32_t 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;
|
||||
|
||||
// UIO device file
|
||||
std::string device_io_name;
|
||||
// find the uio device file corresponding to the acquisition
|
||||
if (find_uio_dev_file_name(device_io_name, acquisition_device_name, 0) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << acquisition_device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
acq_parameters.device_name = device_io_name;
|
||||
|
||||
acq_parameters.samples_per_code = nsamples_total;
|
||||
acq_parameters.excludelimit = static_cast<unsigned int>(1 + ceil((1.0 / GALILEO_E1_CODE_CHIP_RATE_CPS) * static_cast<float>(fs_in)));
|
||||
|
||||
|
@ -183,6 +183,8 @@ public:
|
||||
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
|
||||
|
||||
private:
|
||||
const std::string acquisition_device_name = "acquisition_S00_AXI"; // UIO device name
|
||||
|
||||
// the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA
|
||||
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
|
||||
static const uint32_t quant_bits_local_code = 16;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "galileo_e5_signal_replica.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gnss_sdr_make_unique.h"
|
||||
#include "uio_fpga.h"
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/fft/fft.h> // for fft_complex
|
||||
#include <gnuradio/gr_complex.h> // for gr_complex
|
||||
@ -80,11 +81,18 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(
|
||||
uint32_t nsamples_total = pow(2, nbits);
|
||||
uint32_t 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_code = nsamples_total;
|
||||
|
||||
// UIO device file
|
||||
std::string device_io_name;
|
||||
// find the uio device file corresponding to the acquisition
|
||||
if (find_uio_dev_file_name(device_io_name, acquisition_device_name, 0) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << acquisition_device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
acq_parameters.device_name = device_io_name;
|
||||
|
||||
acq_parameters.samples_per_code = nsamples_total;
|
||||
acq_parameters.excludelimit = static_cast<unsigned int>(1 + ceil((1.0 / GALILEO_E5A_CODE_CHIP_RATE_CPS) * static_cast<float>(fs_in)));
|
||||
|
||||
// compute all the GALILEO E5 PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time
|
||||
|
@ -191,6 +191,8 @@ public:
|
||||
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
|
||||
|
||||
private:
|
||||
const std::string acquisition_device_name = "acquisition_S00_AXI"; // UIO device name
|
||||
|
||||
// the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA
|
||||
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
|
||||
static const uint32_t quant_bits_local_code = 16;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "configuration_interface.h"
|
||||
#include "galileo_e5_signal_replica.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "uio_fpga.h"
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/fft/fft.h> // for fft_complex
|
||||
#include <gnuradio/gr_complex.h> // for gr_complex
|
||||
@ -79,11 +80,18 @@ GalileoE5bPcpsAcquisitionFpga::GalileoE5bPcpsAcquisitionFpga(const Configuration
|
||||
uint32_t nsamples_total = pow(2, nbits);
|
||||
uint32_t 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_code = nsamples_total;
|
||||
|
||||
// UIO device file
|
||||
std::string device_io_name;
|
||||
// find the uio device file corresponding to the acquisition
|
||||
if (find_uio_dev_file_name(device_io_name, acquisition_device_name, 0) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << acquisition_device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
acq_parameters.device_name = device_io_name;
|
||||
|
||||
acq_parameters.samples_per_code = nsamples_total;
|
||||
acq_parameters.excludelimit = static_cast<unsigned int>(1 + ceil((1.0 / GALILEO_E5B_CODE_CHIP_RATE_CPS) * static_cast<float>(fs_in)));
|
||||
|
||||
// compute all the GALILEO E5b PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time
|
||||
|
@ -190,6 +190,8 @@ public:
|
||||
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
|
||||
|
||||
private:
|
||||
const std::string acquisition_device_name = "acquisition_S00_AXI"; // UIO device name
|
||||
|
||||
// the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA
|
||||
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
|
||||
static const uint32_t quant_bits_local_code = 16;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gnss_sdr_make_unique.h"
|
||||
#include "gps_sdr_signal_replica.h"
|
||||
#include "uio_fpga.h"
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/fft/fft.h>
|
||||
#include <gnuradio/gr_complex.h> // for gr_complex
|
||||
@ -72,9 +73,17 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
|
||||
uint32_t nsamples_total = pow(2, nbits);
|
||||
uint32_t 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;
|
||||
|
||||
// UIO device file
|
||||
std::string device_io_name;
|
||||
// find the uio device file corresponding to the acquisition
|
||||
if (find_uio_dev_file_name(device_io_name, acquisition_device_name, 0) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << acquisition_device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
acq_parameters.device_name = device_io_name;
|
||||
|
||||
acq_parameters.samples_per_code = nsamples_total;
|
||||
acq_parameters.excludelimit = static_cast<unsigned int>(1 + ceil(GPS_L1_CA_CHIP_PERIOD_S * static_cast<float>(fs_in)));
|
||||
|
||||
|
@ -187,6 +187,8 @@ public:
|
||||
private:
|
||||
static const uint32_t NUM_PRNs = 32;
|
||||
|
||||
const std::string acquisition_device_name = "acquisition_S00_AXI"; // UIO device name
|
||||
|
||||
// the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA
|
||||
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
|
||||
static const uint32_t quant_bits_local_code = 16;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "gnss_sdr_make_unique.h"
|
||||
#include "gnss_synchro.h"
|
||||
#include "gps_l2c_signal_replica.h"
|
||||
#include "uio_fpga.h"
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/fft/fft.h> // for fft_complex
|
||||
#include <gnuradio/gr_complex.h> // for gr_complex
|
||||
@ -70,11 +71,18 @@ GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga(
|
||||
unsigned int nsamples_total = pow(2, nbits);
|
||||
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_code = nsamples_total;
|
||||
|
||||
// UIO device file
|
||||
std::string device_io_name;
|
||||
// find the uio device file corresponding to the acquisition
|
||||
if (find_uio_dev_file_name(device_io_name, acquisition_device_name, 0) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << acquisition_device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
acq_parameters.device_name = device_io_name;
|
||||
|
||||
acq_parameters.samples_per_code = nsamples_total;
|
||||
acq_parameters.downsampling_factor = configuration->property(role + ".downsampling_factor", 1.0);
|
||||
acq_parameters.total_block_exp = configuration->property(role + ".total_block_exp", 14);
|
||||
acq_parameters.excludelimit = static_cast<uint32_t>(std::round(static_cast<double>(fs_in_) / GPS_L2_M_CODE_RATE_CPS));
|
||||
|
@ -151,6 +151,8 @@ public:
|
||||
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
|
||||
|
||||
private:
|
||||
const std::string acquisition_device_name = "acquisition_S00_AXI"; // UIO device name
|
||||
|
||||
static const uint32_t NUM_PRNs = 32;
|
||||
static const uint32_t QUANT_BITS_LOCAL_CODE = 16;
|
||||
static const uint32_t SELECT_LSBits = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gnss_sdr_make_unique.h"
|
||||
#include "gps_l5_signal_replica.h"
|
||||
#include "uio_fpga.h"
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/fft/fft.h> // for fft_complex
|
||||
#include <gnuradio/gr_complex.h> // for gr_complex
|
||||
@ -76,11 +77,18 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga(
|
||||
uint32_t nsamples_total = pow(2, nbits);
|
||||
uint32_t 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_code = nsamples_total;
|
||||
|
||||
// UIO device file
|
||||
std::string device_io_name;
|
||||
// find the uio device file corresponding to the acquisition
|
||||
if (find_uio_dev_file_name(device_io_name, acquisition_device_name, 0) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << acquisition_device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
acq_parameters.device_name = device_io_name;
|
||||
|
||||
acq_parameters.samples_per_code = nsamples_total;
|
||||
acq_parameters.excludelimit = static_cast<unsigned int>(1 + ceil((1.0 / GPS_L5I_CODE_RATE_CPS) * static_cast<float>(fs_in)));
|
||||
|
||||
// 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
|
||||
|
@ -187,6 +187,8 @@ public:
|
||||
private:
|
||||
static const uint32_t NUM_PRNs = 32;
|
||||
|
||||
const std::string acquisition_device_name = "acquisition_S00_AXI"; // UIO device name
|
||||
|
||||
// the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA
|
||||
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
|
||||
static const uint32_t quant_bits_local_code = 16;
|
||||
|
@ -341,6 +341,14 @@ if(DOXYGEN_FOUND)
|
||||
endif()
|
||||
|
||||
|
||||
########################################################################
|
||||
# Detect /lib versus /lib64
|
||||
########################################################################
|
||||
if(${CMAKE_INSTALL_LIBDIR} MATCHES lib64)
|
||||
set(LIB_SUFFIX 64)
|
||||
endif()
|
||||
|
||||
|
||||
########################################################################
|
||||
# Setup the package config file
|
||||
########################################################################
|
||||
|
@ -146,6 +146,13 @@ target_include_directories(signal_source_adapters
|
||||
${CMAKE_SOURCE_DIR}/src/core/interfaces
|
||||
)
|
||||
|
||||
if(ENABLE_FPGA OR ENABLE_AD9361)
|
||||
target_link_libraries(signal_source_adapters
|
||||
PRIVATE
|
||||
core_libs
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(signal_source_adapters
|
||||
PUBLIC
|
||||
Boost::headers
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "ad9361_manager.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "uio_fpga.h"
|
||||
#include <glog/logging.h>
|
||||
#include <iio.h>
|
||||
#include <algorithm> // for max
|
||||
@ -90,9 +91,16 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
|
||||
|
||||
rf_shutdown_ = configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown);
|
||||
|
||||
// turn switch to A/D position
|
||||
const std::string default_device_name("/dev/uio1");
|
||||
const std::string device_name = configuration->property(role + ".devicename", default_device_name);
|
||||
|
||||
// Switch UIO device file
|
||||
std::string device_io_name;
|
||||
// find the uio device file corresponding to the switch.
|
||||
if (find_uio_dev_file_name(device_io_name, switch_device_name, 0) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << switch_device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
switch_position = configuration->property(role + ".switch_position", 0);
|
||||
if (switch_position != 0 && switch_position != 2)
|
||||
{
|
||||
@ -101,7 +109,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
|
||||
switch_position = 0;
|
||||
}
|
||||
|
||||
switch_fpga = std::make_shared<Fpga_Switch>(device_name);
|
||||
switch_fpga = std::make_shared<Fpga_Switch>(device_io_name);
|
||||
switch_fpga->set_switch_position(switch_position);
|
||||
|
||||
item_size_ = sizeof(gr_complex);
|
||||
@ -293,11 +301,22 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
|
||||
enable_dynamic_bit_selection_ = configuration->property(role + ".enable_dynamic_bit_selection", true);
|
||||
if (enable_dynamic_bit_selection_)
|
||||
{
|
||||
const std::string dynamic_bit_selection_default_device_name1("/dev/uio48");
|
||||
std::string device_name1 = configuration->property(role + ".dyn_bits_sel_devicename", dynamic_bit_selection_default_device_name1);
|
||||
const std::string dynamic_bit_selection_default_device_name2("/dev/uio49");
|
||||
std::string device_name2 = configuration->property(role + ".dyn_bits_sel_devicename", dynamic_bit_selection_default_device_name2);
|
||||
dynamic_bit_selection_fpga = std::make_shared<Fpga_dynamic_bit_selection>(device_name1, device_name2);
|
||||
std::string device_io_name_dyn_bit_sel_0, device_io_name_dyn_bit_sel_1;
|
||||
|
||||
// find the uio device file corresponding to the dynamic bit selector 0 module.
|
||||
if (find_uio_dev_file_name(device_io_name_dyn_bit_sel_0, dyn_bit_sel_device_name, 0) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
// find the uio device file corresponding to the dynamic bit selector 1 module.
|
||||
if (find_uio_dev_file_name(device_io_name_dyn_bit_sel_1, dyn_bit_sel_device_name, 1) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
dynamic_bit_selection_fpga = std::make_shared<Fpga_dynamic_bit_selection>(device_io_name_dyn_bit_sel_0, device_io_name_dyn_bit_sel_1);
|
||||
thread_dynamic_bit_selection = std::thread([&] { run_dynamic_bit_selection_process(); });
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ public:
|
||||
|
||||
~Ad9361FpgaSignalSource();
|
||||
|
||||
void start();
|
||||
void start() override;
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
@ -76,6 +76,9 @@ public:
|
||||
gr::basic_block_sptr get_right_block() override;
|
||||
|
||||
private:
|
||||
const std::string switch_device_name = "AXIS_Switch_v1_0_0"; // Switch UIO device name
|
||||
const std::string dyn_bit_sel_device_name = "dynamic_bits_selector"; // Switch UIO device name
|
||||
|
||||
// perform dynamic bit selection every 500 ms by default
|
||||
static const uint32_t Gain_control_period_ms = 500;
|
||||
|
||||
|
@ -111,6 +111,13 @@ target_include_directories(tracking_adapters
|
||||
${CMAKE_SOURCE_DIR}/src/core/interfaces
|
||||
)
|
||||
|
||||
if(ENABLE_FPGA)
|
||||
target_link_libraries(tracking_adapters
|
||||
PRIVATE
|
||||
core_libs
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_CUDA)
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.11)
|
||||
target_include_directories(tracking_adapters
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "dll_pll_conf_fpga.h"
|
||||
#include "galileo_e1_signal_replica.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "uio_fpga.h"
|
||||
#include <glog/logging.h>
|
||||
#include <volk_gnsssdr/volk_gnsssdr_alloc.h>
|
||||
#include <array>
|
||||
@ -63,15 +64,14 @@ GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga(
|
||||
const std::array<char, 3> sig_{'1', 'B', '\0'};
|
||||
std::memcpy(trk_params_fpga.signal, sig_.data(), 3);
|
||||
|
||||
// FPGA configuration parameters
|
||||
// obtain the number of the first uio device corresponding to a HW accelerator in the FPGA
|
||||
// that can be assigned to the tracking of the E1 signal
|
||||
trk_params_fpga.dev_file_num = configuration->property(role + ".dev_file_num", 15);
|
||||
// UIO device file
|
||||
device_name = configuration->property(role + ".devicename", default_device_name);
|
||||
|
||||
// compute the number of tracking channels that have already been instantiated. The order in which
|
||||
// GNSS-SDR instantiates the tracking channels i L1, L2, L5, E1, E5a
|
||||
trk_params_fpga.num_prev_assigned_ch = configuration->property("Channels_1C.count", 0) +
|
||||
configuration->property("Channels_2S.count", 0) +
|
||||
configuration->property("Channels_L5.count", 0);
|
||||
num_prev_assigned_ch = configuration->property("Channels_1C.count", 0) +
|
||||
configuration->property("Channels_2S.count", 0) +
|
||||
configuration->property("Channels_L5.count", 0);
|
||||
|
||||
// ################# PRE-COMPUTE ALL THE CODES #################
|
||||
uint32_t code_samples_per_chip = 2;
|
||||
@ -184,7 +184,16 @@ void GalileoE1DllPllVemlTrackingFpga::start_tracking()
|
||||
void GalileoE1DllPllVemlTrackingFpga::set_channel(unsigned int channel)
|
||||
{
|
||||
channel_ = channel;
|
||||
tracking_fpga_sc->set_channel(channel);
|
||||
|
||||
// UIO device file
|
||||
std::string device_io_name;
|
||||
// find the uio device file corresponding to the tracking multicorrelator
|
||||
if (find_uio_dev_file_name(device_io_name, device_name, channel - num_prev_assigned_ch) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
tracking_fpga_sc->set_channel(channel, device_io_name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -126,11 +126,16 @@ public:
|
||||
void stop_tracking() override;
|
||||
|
||||
private:
|
||||
const std::string default_device_name = "multicorrelator_resampler_5_1_AXI"; // UIO device name
|
||||
|
||||
// the following flags are FPGA-specific and they are using arrange the values of the local code in the way the FPGA
|
||||
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
|
||||
static const int32_t LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY = 0x0C000000; // flag that enables WE (Write Enable) of the local code FPGA
|
||||
static const int32_t LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT = 0x20000000; // flag that selects the writing of the pilot code in the FPGA (as opposed to the data code)
|
||||
|
||||
std::string device_name;
|
||||
uint32_t num_prev_assigned_ch;
|
||||
|
||||
dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc;
|
||||
uint32_t channel_;
|
||||
std::string role_;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "dll_pll_conf_fpga.h"
|
||||
#include "galileo_e5_signal_replica.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "uio_fpga.h"
|
||||
#include <glog/logging.h>
|
||||
#include <volk_gnsssdr/volk_gnsssdr_alloc.h>
|
||||
#include <array>
|
||||
@ -60,19 +61,18 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga(
|
||||
|
||||
d_data_codes = nullptr;
|
||||
|
||||
// FPGA configuration parameters
|
||||
// obtain the number of the first uio device corresponding to a HW accelerator in the FPGA
|
||||
// that can be assigned to the tracking of the E5a signal
|
||||
trk_params_fpga.dev_file_num = configuration->property(role + ".dev_file_num", 27);
|
||||
// UIO device file
|
||||
device_name = configuration->property(role + ".devicename", default_device_name);
|
||||
|
||||
// compute the number of tracking channels that have already been instantiated. The order in which
|
||||
// GNSS-SDR instantiates the tracking channels i L1, L2, L5, E1, E5a
|
||||
// However E5a can use the same tracking HW accelerators as L5 (but not simultaneously).
|
||||
// Therefore for the proper assignment of the FPGA tracking device file numbers to the E5a tracking channels,
|
||||
// the number of channels that have already been assigned to L5 must not be substracted to this channel number,
|
||||
// so they are not counted here.
|
||||
trk_params_fpga.num_prev_assigned_ch = configuration->property("Channels_1C.count", 0) +
|
||||
configuration->property("Channels_2S.count", 0) +
|
||||
configuration->property("Channels_1B.count", 0);
|
||||
num_prev_assigned_ch = configuration->property("Channels_1C.count", 0) +
|
||||
configuration->property("Channels_2S.count", 0) +
|
||||
configuration->property("Channels_1B.count", 0);
|
||||
|
||||
// ################# PRE-COMPUTE ALL THE CODES #################
|
||||
uint32_t code_samples_per_chip = 1;
|
||||
@ -207,7 +207,16 @@ void GalileoE5aDllPllTrackingFpga::stop_tracking()
|
||||
void GalileoE5aDllPllTrackingFpga::set_channel(unsigned int channel)
|
||||
{
|
||||
channel_ = channel;
|
||||
tracking_fpga_sc->set_channel(channel);
|
||||
|
||||
// UIO device file
|
||||
std::string device_io_name;
|
||||
// find the uio device file corresponding to the tracking multicorrelator
|
||||
if (find_uio_dev_file_name(device_io_name, device_name, channel - num_prev_assigned_ch) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
tracking_fpga_sc->set_channel(channel, device_io_name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -119,11 +119,15 @@ public:
|
||||
void stop_tracking() override;
|
||||
|
||||
private:
|
||||
const std::string default_device_name = "multicorrelator_resampler_3_1_AXI"; // UIO device name
|
||||
|
||||
// the following flags are FPGA-specific and they are using arrange the values of the local code in the way the FPGA
|
||||
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
|
||||
static const int32_t LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY = 0x0C000000; // flag that enables WE (Write Enable) of the local code FPGA
|
||||
static const int32_t LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT = 0x20000000; // flag that selects the writing of the pilot code in the FPGA (as opposed to the data code)
|
||||
|
||||
std::string device_name;
|
||||
uint32_t num_prev_assigned_ch;
|
||||
|
||||
dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc;
|
||||
uint32_t channel_;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "dll_pll_conf_fpga.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gps_sdr_signal_replica.h"
|
||||
#include "uio_fpga.h"
|
||||
#include <glog/logging.h>
|
||||
#include <volk_gnsssdr/volk_gnsssdr.h>
|
||||
#include <array>
|
||||
@ -68,13 +69,12 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga(
|
||||
const std::array<char, 3> sig_{'1', 'C', '\0'};
|
||||
std::memcpy(trk_params_fpga.signal, sig_.data(), 3);
|
||||
|
||||
// FPGA configuration parameters
|
||||
// obtain the number of the first uio device corresponding to a HW accelerator in the FPGA
|
||||
// that can be assigned to the tracking of the L1 signal
|
||||
trk_params_fpga.dev_file_num = configuration->property(role + ".dev_file_num", 3);
|
||||
// UIO device file
|
||||
device_name = configuration->property(role + ".devicename", default_device_name);
|
||||
|
||||
// compute the number of tracking channels that have already been instantiated. The order in which
|
||||
// GNSS-SDR instantiates the tracking channels i L1, l2, L5, E1, E5a
|
||||
trk_params_fpga.num_prev_assigned_ch = 0;
|
||||
num_prev_assigned_ch = 0;
|
||||
|
||||
// ################# PRE-COMPUTE ALL THE CODES #################
|
||||
d_ca_codes = static_cast<int32_t*>(volk_gnsssdr_malloc(static_cast<int32_t>(GPS_L1_CA_CODE_LENGTH_CHIPS * NUM_PRNs) * sizeof(int32_t), volk_gnsssdr_get_alignment()));
|
||||
@ -153,7 +153,17 @@ void GpsL1CaDllPllTrackingFpga::stop_tracking()
|
||||
void GpsL1CaDllPllTrackingFpga::set_channel(unsigned int channel)
|
||||
{
|
||||
channel_ = channel;
|
||||
tracking_fpga_sc->set_channel(channel);
|
||||
|
||||
// UIO device file
|
||||
std::string device_io_name;
|
||||
// find the uio device file corresponding to the tracking multicorrelator
|
||||
if (find_uio_dev_file_name(device_io_name, device_name, channel - num_prev_assigned_ch) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
tracking_fpga_sc->set_channel(channel, device_io_name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -124,12 +124,16 @@ public:
|
||||
void stop_tracking() override;
|
||||
|
||||
private:
|
||||
const std::string default_device_name = "multicorrelator_resampler_S00_AXI"; // UIO device name
|
||||
|
||||
static const uint32_t NUM_PRNs = 32; // total number of PRNs
|
||||
static const int32_t GPS_CA_BIT_DURATION_MS = 20;
|
||||
// the following flag is FPGA-specific and they are using arrange the values of the local code in the way the FPGA
|
||||
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
|
||||
static const int32_t LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY = 0x0C000000; // flag that enables WE (Write Enable) of the local code FPGA
|
||||
|
||||
std::string device_name;
|
||||
uint32_t num_prev_assigned_ch;
|
||||
|
||||
dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc;
|
||||
uint32_t channel_;
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gnss_synchro.h"
|
||||
#include "gps_l2c_signal_replica.h"
|
||||
#include "uio_fpga.h"
|
||||
#include <glog/logging.h>
|
||||
#include <volk_gnsssdr/volk_gnsssdr_alloc.h>
|
||||
#include <array>
|
||||
@ -66,12 +67,12 @@ GpsL2MDllPllTrackingFpga::GpsL2MDllPllTrackingFpga(
|
||||
const std::array<char, 3> sig_{'2', 'S', '\0'};
|
||||
std::memcpy(trk_params_fpga.signal, sig_.data(), 3);
|
||||
|
||||
// FPGA configuration parameters
|
||||
// obtain the number of the first uio device file that is assigned to the FPGA L2 tracking multicorrelator HW accelerators
|
||||
trk_params_fpga.dev_file_num = configuration->property(role + ".dev_file_num", 27);
|
||||
// UIO device file
|
||||
device_name = configuration->property(role + ".devicename", default_device_name);
|
||||
|
||||
// compute the number of tracking channels that have already been instantiated. The order in which
|
||||
// GNSS-SDR instantiates the tracking channels i L1, L2, L5, E1, E5a
|
||||
trk_params_fpga.num_prev_assigned_ch = configuration->property("Channels_1C.count", 0);
|
||||
num_prev_assigned_ch = configuration->property("Channels_1C.count", 0);
|
||||
|
||||
volk_gnsssdr::vector<float> ca_codes_f(static_cast<unsigned int>(GPS_L2_M_CODE_LENGTH_CHIPS), 0.0);
|
||||
// ################# PRE-COMPUTE ALL THE CODES #################
|
||||
@ -130,7 +131,17 @@ void GpsL2MDllPllTrackingFpga::stop_tracking()
|
||||
void GpsL2MDllPllTrackingFpga::set_channel(unsigned int channel)
|
||||
{
|
||||
channel_ = channel;
|
||||
tracking_fpga_sc->set_channel(channel);
|
||||
|
||||
// UIO device file
|
||||
std::string device_io_name;
|
||||
// find the uio device file corresponding to the tracking multicorrelator
|
||||
if (find_uio_dev_file_name(device_io_name, device_name, channel - num_prev_assigned_ch) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
tracking_fpga_sc->set_channel(channel, device_io_name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -95,6 +95,11 @@ public:
|
||||
void stop_tracking() override;
|
||||
|
||||
private:
|
||||
const std::string default_device_name = "multicorrelator_resampler_S00_AXI"; // UIO device name
|
||||
|
||||
std::string device_name;
|
||||
uint32_t num_prev_assigned_ch;
|
||||
|
||||
static const uint32_t NUM_PRNs = 32;
|
||||
dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc;
|
||||
unsigned int channel_;
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "dll_pll_conf_fpga.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gps_l5_signal_replica.h"
|
||||
#include "uio_fpga.h"
|
||||
#include <glog/logging.h>
|
||||
#include <volk_gnsssdr/volk_gnsssdr_alloc.h>
|
||||
#include <array>
|
||||
@ -65,14 +66,13 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga(
|
||||
const std::array<char, 3> sig_{'L', '5', '\0'};
|
||||
std::memcpy(trk_params_fpga.signal, sig_.data(), 3);
|
||||
|
||||
// FPGA configuration parameters
|
||||
// obtain the number of the first uio device corresponding to a HW accelerator in the FPGA
|
||||
// that can be assigned to the tracking of the L5 signal
|
||||
trk_params_fpga.dev_file_num = configuration->property(role + ".dev_file_num", 27);
|
||||
// UIO device file
|
||||
device_name = configuration->property(role + ".devicename", default_device_name);
|
||||
|
||||
// compute the number of tracking channels that have already been instantiated. The order in which
|
||||
// GNSS-SDR instantiates the tracking channels i L1, L2, L5, E1, E5a
|
||||
trk_params_fpga.num_prev_assigned_ch = configuration->property("Channels_1C.count", 0) +
|
||||
configuration->property("Channels_2S.count", 0);
|
||||
num_prev_assigned_ch = configuration->property("Channels_1C.count", 0) +
|
||||
configuration->property("Channels_2S.count", 0);
|
||||
|
||||
// ################# PRE-COMPUTE ALL THE CODES #################
|
||||
uint32_t code_samples_per_chip = 1;
|
||||
@ -215,7 +215,17 @@ void GpsL5DllPllTrackingFpga::stop_tracking()
|
||||
void GpsL5DllPllTrackingFpga::set_channel(unsigned int channel)
|
||||
{
|
||||
channel_ = channel;
|
||||
tracking_fpga_sc->set_channel(channel);
|
||||
|
||||
// UIO device file
|
||||
std::string device_io_name;
|
||||
// find the uio device file corresponding to the tracking multicorrelator
|
||||
if (find_uio_dev_file_name(device_io_name, device_name, channel - num_prev_assigned_ch) < 0)
|
||||
{
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
tracking_fpga_sc->set_channel(channel, device_io_name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -125,6 +125,8 @@ public:
|
||||
void stop_tracking() override;
|
||||
|
||||
private:
|
||||
const std::string default_device_name = "multicorrelator_resampler_3_1_AXI"; // UIO device name
|
||||
|
||||
static const uint32_t NUM_PRNs = 32; // total number of PRNs
|
||||
|
||||
// the following flags are FPGA-specific and they are using arrange the values of the local code in the way the FPGA
|
||||
@ -132,6 +134,9 @@ private:
|
||||
static const int32_t LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY = 0x0C000000; // flag that enables WE (Write Enable) of the local code FPGA
|
||||
static const int32_t LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT = 0x20000000; // flag that selects the writing of the pilot code in the FPGA (as opposed to the data code)
|
||||
|
||||
std::string device_name;
|
||||
uint32_t num_prev_assigned_ch;
|
||||
|
||||
dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc;
|
||||
uint32_t channel_;
|
||||
std::string role_;
|
||||
|
@ -466,12 +466,9 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga &
|
||||
}
|
||||
}
|
||||
// create multicorrelator class
|
||||
const std::string device_name = d_trk_parameters.device_name;
|
||||
const uint32_t dev_file_num = d_trk_parameters.dev_file_num;
|
||||
const uint32_t num_prev_assigned_ch = d_trk_parameters.num_prev_assigned_ch;
|
||||
int32_t *ca_codes = d_trk_parameters.ca_codes;
|
||||
int32_t *data_codes = d_trk_parameters.data_codes;
|
||||
d_multicorrelator_fpga = std::make_shared<Fpga_Multicorrelator_8sc>(d_n_correlator_taps, device_name, dev_file_num, num_prev_assigned_ch, ca_codes, data_codes, d_code_length_chips, d_trk_parameters.track_pilot, d_code_samples_per_chip);
|
||||
d_multicorrelator_fpga = std::make_shared<Fpga_Multicorrelator_8sc>(d_n_correlator_taps, ca_codes, data_codes, d_code_length_chips, d_trk_parameters.track_pilot, d_code_samples_per_chip);
|
||||
d_multicorrelator_fpga->set_output_vectors(d_correlator_outs.data(), d_Prompt_Data.data());
|
||||
d_sample_counter_next = 0ULL;
|
||||
|
||||
@ -1313,12 +1310,12 @@ int32_t dll_pll_veml_tracking_fpga::save_matfile() const
|
||||
}
|
||||
|
||||
|
||||
void dll_pll_veml_tracking_fpga::set_channel(uint32_t channel)
|
||||
void dll_pll_veml_tracking_fpga::set_channel(uint32_t channel, std::string device_io_name)
|
||||
{
|
||||
gr::thread::scoped_lock l(d_setlock);
|
||||
|
||||
d_channel = channel;
|
||||
d_multicorrelator_fpga->set_channel(d_channel);
|
||||
d_multicorrelator_fpga->open_channel(device_io_name, channel);
|
||||
LOG(INFO) << "Tracking Channel set to " << d_channel;
|
||||
// ############# ENABLE DATA FILE LOG #################
|
||||
if (d_dump)
|
||||
|
@ -69,7 +69,7 @@ public:
|
||||
/*!
|
||||
* \brief Set the channel number and configure some multicorrelator parameters
|
||||
*/
|
||||
void set_channel(uint32_t channel);
|
||||
void set_channel(uint32_t channel, std::string device_io_name);
|
||||
|
||||
/*!
|
||||
* \brief This function is used with two purposes:
|
||||
|
@ -75,8 +75,6 @@ Dll_Pll_Conf_Fpga::Dll_Pll_Conf_Fpga()
|
||||
signal[1] = 'C';
|
||||
signal[2] = '\0';
|
||||
device_name = "/dev/uio";
|
||||
dev_file_num = 3;
|
||||
num_prev_assigned_ch = 0;
|
||||
code_length_chips = 0U;
|
||||
code_samples_per_chip = 0U;
|
||||
ca_codes = nullptr;
|
||||
|
@ -68,8 +68,6 @@ public:
|
||||
uint32_t bit_synchronization_time_limit_s;
|
||||
uint32_t vector_length;
|
||||
uint32_t smoother_length;
|
||||
uint32_t dev_file_num;
|
||||
uint32_t num_prev_assigned_ch;
|
||||
uint32_t code_length_chips;
|
||||
uint32_t code_samples_per_chip;
|
||||
uint32_t extend_fpga_integration_periods;
|
||||
|
@ -50,9 +50,6 @@ const float PHASE_CARR_MAX_DIV_PI = 683565275.5764316; // 2^(31)/pi
|
||||
const float TWO_PI = 6.283185307179586;
|
||||
|
||||
Fpga_Multicorrelator_8sc::Fpga_Multicorrelator_8sc(int32_t n_correlators,
|
||||
const std::string &device_name,
|
||||
uint32_t dev_file_num,
|
||||
uint32_t num_prev_assigned_ch,
|
||||
int32_t *ca_codes,
|
||||
int32_t *data_codes,
|
||||
uint32_t code_length_chips,
|
||||
@ -60,10 +57,6 @@ Fpga_Multicorrelator_8sc::Fpga_Multicorrelator_8sc(int32_t n_correlators,
|
||||
uint32_t code_samples_per_chip)
|
||||
{
|
||||
d_n_correlators = n_correlators;
|
||||
d_device_name = device_name;
|
||||
d_dev_file_num = dev_file_num;
|
||||
d_num_prev_assigned_ch = num_prev_assigned_ch;
|
||||
|
||||
d_track_pilot = track_pilot;
|
||||
d_device_descriptor = 0;
|
||||
d_map_base = nullptr;
|
||||
@ -91,7 +84,6 @@ Fpga_Multicorrelator_8sc::Fpga_Multicorrelator_8sc(int32_t n_correlators,
|
||||
d_rem_carr_phase_rad_int = 0;
|
||||
d_phase_step_rad_int = 0;
|
||||
d_initial_sample_counter = 0;
|
||||
d_channel = 0;
|
||||
d_correlator_length_samples = 0;
|
||||
d_code_phase_step_chips_num = 0;
|
||||
d_code_length_chips = code_length_chips;
|
||||
@ -203,28 +195,11 @@ bool Fpga_Multicorrelator_8sc::free()
|
||||
}
|
||||
|
||||
|
||||
void Fpga_Multicorrelator_8sc::set_channel(uint32_t channel)
|
||||
void Fpga_Multicorrelator_8sc::open_channel(std::string device_io_name, uint32_t channel)
|
||||
{
|
||||
char device_io_name[max_length_deviceio_name] = ""; // driver io name
|
||||
d_channel = channel;
|
||||
|
||||
// open the device corresponding to the assigned channel
|
||||
std::string mergedname;
|
||||
std::stringstream devicebasetemp;
|
||||
uint32_t numdevice = d_dev_file_num + d_channel - d_num_prev_assigned_ch;
|
||||
devicebasetemp << numdevice;
|
||||
mergedname = d_device_name + devicebasetemp.str();
|
||||
|
||||
if (mergedname.size() > max_length_deviceio_name)
|
||||
{
|
||||
mergedname = mergedname.substr(0, max_length_deviceio_name);
|
||||
}
|
||||
|
||||
mergedname.copy(device_io_name, mergedname.size() + 1);
|
||||
device_io_name[mergedname.size()] = '\0';
|
||||
std::cout << "trk device_io_name = " << device_io_name << '\n';
|
||||
|
||||
if ((d_device_descriptor = open(device_io_name, O_RDWR | O_SYNC)) == -1)
|
||||
if ((d_device_descriptor = open(device_io_name.c_str(), O_RDWR | O_SYNC)) == -1)
|
||||
{
|
||||
LOG(WARNING) << "Cannot open deviceio" << device_io_name;
|
||||
std::cout << "Cannot open deviceio" << device_io_name << '\n';
|
||||
@ -235,7 +210,7 @@ void Fpga_Multicorrelator_8sc::set_channel(uint32_t channel)
|
||||
if (d_map_base == reinterpret_cast<void *>(-1))
|
||||
{
|
||||
LOG(WARNING) << "Cannot map the FPGA tracking module "
|
||||
<< d_channel << "into user memory";
|
||||
<< channel << "into user memory";
|
||||
std::cout << "Cannot map deviceio" << device_io_name << '\n';
|
||||
}
|
||||
|
||||
|
@ -47,9 +47,6 @@ public:
|
||||
* \brief Constructor
|
||||
*/
|
||||
Fpga_Multicorrelator_8sc(int32_t n_correlators,
|
||||
const std::string &device_name,
|
||||
uint32_t dev_file_num,
|
||||
uint32_t num_prev_assigned_ch,
|
||||
int32_t *ca_codes,
|
||||
int32_t *data_codes,
|
||||
uint32_t code_length_chips,
|
||||
@ -95,9 +92,9 @@ public:
|
||||
bool free();
|
||||
|
||||
/*!
|
||||
* \brief Set channel number and open the FPGA device driver
|
||||
* \brief Open the FPGA device driver
|
||||
*/
|
||||
void set_channel(uint32_t channel);
|
||||
void open_channel(std::string device_io_name, uint32_t channel);
|
||||
|
||||
/*!
|
||||
* \brief Set the initial sample number where the tracking process begins
|
||||
@ -193,7 +190,6 @@ private:
|
||||
static const uint32_t enable_secondary_code = 2; // bit 1 of drop_samples_reg_addr
|
||||
static const uint32_t init_secondary_code_addresses = 4; // bit 2 of drop_samples_reg_addr
|
||||
static const uint32_t page_size = 0x10000;
|
||||
static const uint32_t max_length_deviceio_name = 50;
|
||||
static const uint32_t max_code_resampler_counter = 1 << 31; // 2^(number of bits of precision of the code resampler)
|
||||
static const uint32_t local_code_fpga_clear_address_counter = 0x10000000;
|
||||
static const uint32_t test_register_track_writeval = 0x55AA;
|
||||
@ -237,7 +233,6 @@ private:
|
||||
volatile uint32_t *d_map_base; // driver memory map
|
||||
|
||||
// configuration data received from the interface
|
||||
uint32_t d_channel; // channel number
|
||||
uint32_t d_correlator_length_samples;
|
||||
uint32_t d_code_samples_per_chip;
|
||||
|
||||
@ -247,11 +242,6 @@ private:
|
||||
int32_t d_phase_step_rad_int;
|
||||
int32_t d_carrier_phase_rate_step_rad_int;
|
||||
|
||||
// driver
|
||||
std::string d_device_name;
|
||||
uint32_t d_dev_file_num;
|
||||
uint32_t d_num_prev_assigned_ch;
|
||||
|
||||
// PRN codes
|
||||
int32_t *d_ca_codes;
|
||||
int32_t *d_data_codes;
|
||||
|
@ -44,6 +44,17 @@ if(ENABLE_FPGA)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_FPGA OR ENABLE_AD9361)
|
||||
set(CORE_LIBS_SOURCES
|
||||
${CORE_LIBS_SOURCES}
|
||||
uio_fpga.cc
|
||||
)
|
||||
set(CORE_LIBS_HEADERS
|
||||
${CORE_LIBS_HEADERS}
|
||||
uio_fpga.h
|
||||
)
|
||||
endif()
|
||||
|
||||
list(SORT CORE_LIBS_HEADERS)
|
||||
list(SORT CORE_LIBS_SOURCES)
|
||||
|
||||
@ -114,6 +125,18 @@ if(USE_BOOST_BIND_PLACEHOLDERS)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_FPGA OR ENABLE_AD9361)
|
||||
if(FILESYSTEM_FOUND)
|
||||
target_compile_definitions(core_libs PRIVATE -DHAS_STD_FILESYSTEM=1)
|
||||
if(find_experimental)
|
||||
target_compile_definitions(core_libs PRIVATE -DHAS_STD_FILESYSTEM_EXPERIMENTAL=1)
|
||||
endif()
|
||||
target_link_libraries(core_libs PRIVATE std::filesystem)
|
||||
else()
|
||||
target_link_libraries(core_libs PRIVATE Boost::filesystem Boost::system)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_CLANG_TIDY)
|
||||
if(CLANG_TIDY_EXE)
|
||||
set_target_properties(core_libs
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "gnss_sdr_fpga_sample_counter.h"
|
||||
#include "gnss_synchro.h"
|
||||
#include "uio_fpga.h"
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <pmt/pmt.h> // for from_double
|
||||
@ -132,11 +133,20 @@ void gnss_sdr_fpga_sample_counter::configure_samples_per_output(uint32_t interva
|
||||
|
||||
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)
|
||||
// UIO device file
|
||||
std::string device_io_name;
|
||||
// find the uio device file corresponding to the sample counter module
|
||||
if (find_uio_dev_file_name(device_io_name, device_name, 0) < 0)
|
||||
{
|
||||
LOG(WARNING) << "Cannot open deviceio" << device_name;
|
||||
std::cout << "Counter-Intr: cannot open deviceio" << device_name << '\n';
|
||||
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << device_name << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
// open communication with HW accelerator
|
||||
if ((fd = open(device_io_name.c_str(), O_RDWR | O_SYNC)) == -1)
|
||||
{
|
||||
LOG(WARNING) << "Cannot open deviceio" << device_io_name;
|
||||
std::cout << "Counter-Intr: cannot open deviceio" << device_io_name << '\n';
|
||||
}
|
||||
map_base = reinterpret_cast<volatile uint32_t *>(mmap(nullptr, page_size,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
|
||||
@ -144,7 +154,7 @@ void gnss_sdr_fpga_sample_counter::open_device()
|
||||
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 << '\n';
|
||||
std::cout << "Counter-Intr: cannot map deviceio" << device_io_name << '\n';
|
||||
}
|
||||
|
||||
// sanity check : check test register
|
||||
|
@ -50,6 +50,8 @@ public:
|
||||
gr_vector_void_star &output_items);
|
||||
|
||||
private:
|
||||
const std::string device_name = "counter"; // UIO device name
|
||||
|
||||
static const uint32_t page_size = 0x10000; // default page size for the multicorrelator memory map
|
||||
static const uint32_t test_reg_sanity_check = 0x55AA; // value to check the presence of the test register (to detect the hw)
|
||||
|
||||
@ -63,8 +65,7 @@ private:
|
||||
bool stop();
|
||||
void wait_for_interrupt(void);
|
||||
|
||||
volatile uint32_t *map_base; // driver memory map
|
||||
std::string device_name = "/dev/uio2"; // HW device name
|
||||
volatile uint32_t *map_base; // driver memory map
|
||||
|
||||
double fs;
|
||||
uint64_t sample_counter;
|
||||
|
213
src/core/libs/uio_fpga.cc
Normal file
213
src/core/libs/uio_fpga.cc
Normal file
@ -0,0 +1,213 @@
|
||||
/*!
|
||||
* \file uio_fpga.cc
|
||||
* \brief This library contains functions to determine the uio device driver
|
||||
* file that corresponds to a hardware accelerator device name in the FPGA.
|
||||
* \author Marc Majoral, 2020. mmajoral(at)cttc.es
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
||||
*
|
||||
* GNSS-SDR is a software defined Global Navigation
|
||||
* Satellite Systems receiver
|
||||
*
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "uio_fpga.h"
|
||||
#include <algorithm> // sort
|
||||
#include <cstdlib> // atoi, size_t
|
||||
#include <fstream> // ifstream
|
||||
#include <iostream> // cout
|
||||
#include <locale> // isdigit
|
||||
#include <sstream> // std::stringstream
|
||||
#include <vector>
|
||||
|
||||
#if HAS_STD_FILESYSTEM
|
||||
#if HAS_STD_FILESYSTEM_EXPERIMENTAL
|
||||
#include <experimental/filesystem>
|
||||
namespace fs = std::experimental::filesystem;
|
||||
#else
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
#endif
|
||||
#else
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
namespace fs = boost::filesystem;
|
||||
#endif
|
||||
|
||||
int32_t get_uio_num(std::string uio_name)
|
||||
{
|
||||
size_t i = 0;
|
||||
// search first digit
|
||||
for (; i < uio_name.length(); i++)
|
||||
{
|
||||
if (isdigit(uio_name[i])) break;
|
||||
}
|
||||
|
||||
// remove the first chars, which aren't digits
|
||||
std::string uio_num = uio_name.substr(i, uio_name.length() - i);
|
||||
|
||||
// convert the remaining text to an integer
|
||||
return atoi(uio_num.c_str());
|
||||
}
|
||||
|
||||
|
||||
void get_uio_name(uint32_t uio_num, std::string &uio_name)
|
||||
{
|
||||
std::stringstream filename;
|
||||
filename << uio_dir << uio_filename << uio_num << uio_subdir_name;
|
||||
|
||||
std::ifstream infile;
|
||||
infile.open(filename.str());
|
||||
if (infile.is_open())
|
||||
{
|
||||
std::getline(infile, uio_name);
|
||||
if (infile.bad())
|
||||
{
|
||||
std::cout << "Could not read the FPGA uio device information file\n";
|
||||
throw std::exception();
|
||||
}
|
||||
infile.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Could not open the FPGA uio device information file\n";
|
||||
throw std::exception();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int my_strverscmp(const char *s1, const char *s2)
|
||||
{
|
||||
// from https://code.woboq.org/userspace/glibc/string/strverscmp.c.html
|
||||
const uint8_t S_N = 0x0;
|
||||
const uint8_t S_I = 0x3;
|
||||
const uint8_t S_F = 0x6;
|
||||
const uint8_t S_Z = 0x9;
|
||||
|
||||
const int8_t CMP = 2;
|
||||
const int8_t LEN = 3;
|
||||
|
||||
const unsigned char *p1 = (const unsigned char *)s1;
|
||||
const unsigned char *p2 = (const unsigned char *)s2;
|
||||
/* Symbol(s) 0 [1-9] others
|
||||
Transition (10) 0 (01) d (00) x */
|
||||
static const uint8_t next_state[] =
|
||||
{
|
||||
/* state x d 0 */
|
||||
/* S_N */ S_N, S_I, S_Z,
|
||||
/* S_I */ S_N, S_I, S_I,
|
||||
/* S_F */ S_N, S_F, S_F,
|
||||
/* S_Z */ S_N, S_F, S_Z};
|
||||
static const int8_t result_type[] =
|
||||
{
|
||||
/* state x/x x/d x/0 d/x d/d d/0 0/x 0/d 0/0 */
|
||||
/* S_N */ CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP,
|
||||
/* S_I */ CMP, -1, -1, +1, LEN, LEN, +1, LEN, LEN,
|
||||
/* S_F */ CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
|
||||
/* S_Z */ CMP, +1, +1, -1, CMP, CMP, -1, CMP, CMP};
|
||||
if (p1 == p2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
unsigned char c1 = *p1++;
|
||||
unsigned char c2 = *p2++;
|
||||
/* Hint: '0' is a digit too. */
|
||||
int state = S_N + ((c1 == '0') + (isdigit(c1) != 0));
|
||||
int diff;
|
||||
while ((diff = c1 - c2) == 0)
|
||||
{
|
||||
if (c1 == '\0')
|
||||
{
|
||||
return diff;
|
||||
}
|
||||
state = next_state[state];
|
||||
c1 = *p1++;
|
||||
c2 = *p2++;
|
||||
state += (c1 == '0') + (isdigit(c1) != 0);
|
||||
}
|
||||
state = result_type[state * 3 + (((c2 == '0') + (isdigit(c2) != 0)))];
|
||||
switch (state)
|
||||
{
|
||||
case CMP:
|
||||
return diff;
|
||||
case LEN:
|
||||
while (isdigit(*p1++))
|
||||
{
|
||||
if (!isdigit(*p2++))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return isdigit(*p2) ? -1 : diff;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool sort_directories(fs::directory_entry a, fs::directory_entry b)
|
||||
{
|
||||
int cmp = my_strverscmp(a.path().string().c_str(), b.path().string().c_str());
|
||||
return (cmp < 0);
|
||||
}
|
||||
|
||||
|
||||
int32_t find_uio_num(const std::string &device_name, uint32_t device_num)
|
||||
{
|
||||
int32_t uio_num;
|
||||
uint32_t uio_count = 0;
|
||||
|
||||
// search for the requested device driver
|
||||
fs::path path(uio_dir);
|
||||
std::vector<fs::directory_entry> dirs;
|
||||
for (auto &p : fs::directory_iterator(path))
|
||||
{
|
||||
dirs.push_back(p);
|
||||
}
|
||||
std::sort(dirs.begin(), dirs.end(), sort_directories);
|
||||
|
||||
for (auto &p : dirs)
|
||||
{
|
||||
// get the uio number corresponding to directory entry n
|
||||
uio_num = get_uio_num(p.path().string());
|
||||
if (uio_num >= 0) // valid uio number
|
||||
{
|
||||
std::string nametemp;
|
||||
get_uio_name(uio_num, nametemp);
|
||||
if (device_name.compare(nametemp) == 0)
|
||||
{
|
||||
if (uio_count == device_num)
|
||||
{
|
||||
return uio_num;
|
||||
}
|
||||
else
|
||||
{
|
||||
uio_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1; // uio number not found
|
||||
}
|
||||
|
||||
|
||||
int32_t find_uio_dev_file_name(std::string &device_file_name, const std::string &device_name, uint32_t device_num)
|
||||
{
|
||||
int32_t uio_num = find_uio_num(device_name, device_num);
|
||||
if (uio_num >= 0)
|
||||
{
|
||||
std::stringstream device_file_name_tmp;
|
||||
device_file_name_tmp << "/dev/uio" << uio_num;
|
||||
device_file_name = device_file_name_tmp.str();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
47
src/core/libs/uio_fpga.h
Normal file
47
src/core/libs/uio_fpga.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*!
|
||||
* \file uio_fpga.h
|
||||
* \brief This library contains functions to determine the uio device driver
|
||||
* file that corresponds to a hardware accelerator device name in the FPGA.
|
||||
* \author Marc Majoral, 2020. mmajoral(at)cttc.es
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
||||
*
|
||||
* GNSS-SDR is a software defined Global Navigation
|
||||
* Satellite Systems receiver
|
||||
*
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_UIO_FPGA_H
|
||||
#define GNSS_SDR_UIO_FPGA_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
/** \addtogroup Core
|
||||
* \{ */
|
||||
/** \addtogroup Core_Receiver_Library
|
||||
* \{ */
|
||||
|
||||
const std::string uio_dir("/sys/class/uio/");
|
||||
const std::string uio_filename("uio");
|
||||
const std::string uio_subdir_name("/name");
|
||||
|
||||
/*!
|
||||
* \brief This function finds the uio device driver device file name out of the
|
||||
* device name and the device number.
|
||||
*/
|
||||
int32_t find_uio_dev_file_name(std::string &device_file_name,
|
||||
const std::string &device_name,
|
||||
uint32_t device_num);
|
||||
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
#endif // GNSS_SDR_UIO_FPGA_H
|
@ -149,41 +149,65 @@ double Beidou_Dnav_Ephemeris::satellitePosition(double transmitTime)
|
||||
}
|
||||
|
||||
// Compute the true anomaly
|
||||
const double tmp_Y = sqrt(1.0 - d_eccentricity * d_eccentricity) * sin(E);
|
||||
const double tmp_X = cos(E) - d_eccentricity;
|
||||
const double sek = sin(E);
|
||||
const double cek = cos(E);
|
||||
const double OneMinusecosE = 1.0 - d_eccentricity * cek;
|
||||
const double ekdot = n / OneMinusecosE;
|
||||
|
||||
// Compute the true anomaly
|
||||
const double sq1e2 = sqrt(1.0 - d_eccentricity * d_eccentricity);
|
||||
const double tmp_Y = sq1e2 * sek;
|
||||
const double tmp_X = cek - d_eccentricity;
|
||||
const double nu = atan2(tmp_Y, tmp_X);
|
||||
|
||||
// Compute angle phi (argument of Latitude)
|
||||
double phi = nu + d_OMEGA;
|
||||
const double phi = nu + d_OMEGA;
|
||||
double pkdot = sq1e2 * ekdot / OneMinusecosE;
|
||||
|
||||
// Reduce phi to between 0 and 2*pi rad
|
||||
phi = fmod((phi), (2.0 * GNSS_PI));
|
||||
// phi = fmod((phi), (2.0 * GNSS_PI));
|
||||
const double s2pk = sin(2.0 * phi);
|
||||
const double c2pk = cos(2.0 * phi);
|
||||
|
||||
// Correct argument of latitude
|
||||
const double u = phi + d_Cuc * cos(2.0 * phi) + d_Cus * sin(2.0 * phi);
|
||||
const double u = phi + d_Cuc * c2pk + d_Cus * s2pk;
|
||||
const double cuk = cos(u);
|
||||
const double suk = sin(u);
|
||||
const double ukdot = pkdot * (1.0 + 2.0 * (d_Cus * c2pk - d_Cuc * s2pk));
|
||||
|
||||
// Correct radius
|
||||
const double r = a * (1.0 - d_eccentricity * cos(E)) + d_Crc * cos(2.0 * phi) + d_Crs * sin(2.0 * phi);
|
||||
const double r = a * (1.0 - d_eccentricity * cek) + d_Crc * c2pk + d_Crs * s2pk;
|
||||
|
||||
const double rkdot = a * d_eccentricity * sek * ekdot + 2.0 * pkdot * (d_Crs * c2pk - d_Crc * s2pk);
|
||||
|
||||
// Correct inclination
|
||||
const double i = d_i_0 + d_IDOT * tk + d_Cic * cos(2.0 * phi) + d_Cis * sin(2.0 * phi);
|
||||
const double i = d_i_0 + d_IDOT * tk + d_Cic * c2pk + d_Cis * s2pk;
|
||||
const double sik = sin(i);
|
||||
const double cik = cos(i);
|
||||
const double ikdot = d_IDOT + 2.0 * pkdot * (d_Cis * c2pk - d_Cic * s2pk);
|
||||
|
||||
// Compute the angle between the ascending node and the Greenwich meridian
|
||||
double Omega = d_OMEGA0 + (d_OMEGA_DOT - BEIDOU_OMEGA_EARTH_DOT) * tk - BEIDOU_OMEGA_EARTH_DOT * d_Toe;
|
||||
|
||||
// Reduce to between 0 and 2*pi rad
|
||||
Omega = fmod((Omega + 2.0 * GNSS_PI), (2.0 * GNSS_PI));
|
||||
const double Omega = d_OMEGA0 + (d_OMEGA_DOT - BEIDOU_OMEGA_EARTH_DOT) * tk - BEIDOU_OMEGA_EARTH_DOT * d_Toe;
|
||||
const double sok = sin(Omega);
|
||||
const double cok = cos(Omega);
|
||||
|
||||
// --- Compute satellite coordinates in Earth-fixed coordinates
|
||||
d_satpos_X = cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega);
|
||||
d_satpos_Y = cos(u) * r * sin(Omega) + sin(u) * r * cos(i) * cos(Omega);
|
||||
d_satpos_Z = sin(u) * r * sin(i);
|
||||
const double xprime = r * cuk;
|
||||
const double yprime = r * suk;
|
||||
d_satpos_X = xprime * cok - yprime * cik * sok;
|
||||
d_satpos_Y = xprime * sok + yprime * cik * cok;
|
||||
d_satpos_Z = yprime * sik;
|
||||
|
||||
// Satellite's velocity. Can be useful for Vector Tracking loops
|
||||
const double Omega_dot = d_OMEGA_DOT - BEIDOU_OMEGA_EARTH_DOT;
|
||||
d_satvel_X = -Omega_dot * (cos(u) * r + sin(u) * r * cos(i)) + d_satpos_X * cos(Omega) - d_satpos_Y * cos(i) * sin(Omega);
|
||||
d_satvel_Y = Omega_dot * (cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega)) + d_satpos_X * sin(Omega) + d_satpos_Y * cos(i) * cos(Omega);
|
||||
d_satvel_Z = d_satpos_Y * sin(i);
|
||||
|
||||
const double xpkdot = rkdot * cuk - yprime * ukdot;
|
||||
const double ypkdot = rkdot * suk + xprime * ukdot;
|
||||
const double tmp = ypkdot * cik - d_satpos_Z * ikdot;
|
||||
|
||||
d_satvel_X = -Omega_dot * d_satpos_Y + xpkdot * cok - tmp * sok;
|
||||
d_satvel_Y = Omega_dot * d_satpos_X + xpkdot * sok + tmp * cok;
|
||||
d_satvel_Z = yprime * cik * ikdot + ypkdot * sik;
|
||||
|
||||
// Time from ephemeris reference clock
|
||||
tk = check_t(transmitTime - d_Toc);
|
||||
@ -191,7 +215,7 @@ double Beidou_Dnav_Ephemeris::satellitePosition(double transmitTime)
|
||||
double dtr_s = d_A_f0 + d_A_f1 * tk + d_A_f2 * tk * tk;
|
||||
|
||||
/* relativity correction */
|
||||
dtr_s -= 2.0 * sqrt(BEIDOU_GM * a) * d_eccentricity * sin(E) / (SPEED_OF_LIGHT_M_S * SPEED_OF_LIGHT_M_S);
|
||||
dtr_s -= 2.0 * sqrt(BEIDOU_GM * a) * d_eccentricity * sek / (SPEED_OF_LIGHT_M_S * SPEED_OF_LIGHT_M_S);
|
||||
|
||||
return dtr_s;
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ double Galileo_Ephemeris::sv_clock_relativistic_term(double transmitTime) // Sa
|
||||
|
||||
// Time from ephemeris reference epoch
|
||||
// t = WN_5*86400*7 + TOW_5; //WN_5*86400*7 are the second from the origin of the Galileo time
|
||||
const double tk = transmitTime - t0e_1;
|
||||
const double tk = check_t(transmitTime - static_cast<double>(t0e_1));
|
||||
|
||||
// Corrected mean motion
|
||||
const double n = n0 + delta_n_3;
|
||||
@ -87,7 +87,7 @@ double Galileo_Ephemeris::sv_clock_relativistic_term(double transmitTime) // Sa
|
||||
double M = M0_1 + n * tk;
|
||||
|
||||
// Reduce mean anomaly to between 0 and 2pi
|
||||
M = fmod((M + 2 * GNSS_PI), (2 * GNSS_PI));
|
||||
M = fmod((M + 2.0 * GNSS_PI), (2.0 * GNSS_PI));
|
||||
|
||||
// Initial guess of eccentric anomaly
|
||||
double E = M;
|
||||
@ -99,7 +99,7 @@ double Galileo_Ephemeris::sv_clock_relativistic_term(double transmitTime) // Sa
|
||||
{
|
||||
E_old = E;
|
||||
E = M + e_1 * sin(E);
|
||||
dE = fmod(E - E_old, 2 * GNSS_PI);
|
||||
dE = fmod(E - E_old, 2.0 * GNSS_PI);
|
||||
if (fabs(dE) < 1e-12)
|
||||
{
|
||||
// Necessary precision is reached, exit from the loop
|
||||
@ -127,7 +127,7 @@ void Galileo_Ephemeris::satellitePosition(double transmitTime)
|
||||
const double n0 = sqrt(GALILEO_GM / (a * a * a));
|
||||
|
||||
// Time from ephemeris reference epoch
|
||||
const double tk = transmitTime - t0e_1;
|
||||
const double tk = check_t(transmitTime - static_cast<double>(t0e_1));
|
||||
|
||||
// Corrected mean motion
|
||||
const double n = n0 + delta_n_3;
|
||||
@ -136,7 +136,7 @@ void Galileo_Ephemeris::satellitePosition(double transmitTime)
|
||||
double M = M0_1 + n * tk;
|
||||
|
||||
// Reduce mean anomaly to between 0 and 2pi
|
||||
M = fmod((M + 2 * GNSS_PI), (2 * GNSS_PI));
|
||||
M = fmod((M + 2.0 * GNSS_PI), (2.0 * GNSS_PI));
|
||||
|
||||
// Initial guess of eccentric anomaly
|
||||
double E = M;
|
||||
@ -148,7 +148,7 @@ void Galileo_Ephemeris::satellitePosition(double transmitTime)
|
||||
{
|
||||
E_old = E;
|
||||
E = M + e_1 * sin(E);
|
||||
dE = fmod(E - E_old, 2 * GNSS_PI);
|
||||
dE = fmod(E - E_old, 2.0 * GNSS_PI);
|
||||
if (fabs(dE) < 1e-12)
|
||||
{
|
||||
// Necessary precision is reached, exit from the loop
|
||||
@ -156,40 +156,80 @@ void Galileo_Ephemeris::satellitePosition(double transmitTime)
|
||||
}
|
||||
}
|
||||
|
||||
const double sek = sin(E);
|
||||
const double cek = cos(E);
|
||||
const double OneMinusecosE = 1.0 - e_1 * cek;
|
||||
const double sq1e2 = sqrt(1.0 - e_1 * e_1);
|
||||
const double ekdot = n / OneMinusecosE;
|
||||
|
||||
// Compute the true anomaly
|
||||
const double tmp_Y = sqrt(1.0 - e_1 * e_1) * sin(E);
|
||||
const double tmp_X = cos(E) - e_1;
|
||||
const double tmp_Y = sq1e2 * sek;
|
||||
const double tmp_X = cek - e_1;
|
||||
const double nu = atan2(tmp_Y, tmp_X);
|
||||
|
||||
// Compute angle phi (argument of Latitude)
|
||||
double phi = nu + omega_2;
|
||||
|
||||
// Reduce phi to between 0 and 2*pi rad
|
||||
phi = fmod((phi), (2 * GNSS_PI));
|
||||
phi = fmod((phi), (2.0 * GNSS_PI));
|
||||
const double s2pk = sin(2.0 * phi);
|
||||
const double c2pk = cos(2.0 * phi);
|
||||
const double pkdot = sq1e2 * ekdot / OneMinusecosE;
|
||||
|
||||
// Correct argument of latitude
|
||||
const double u = phi + C_uc_3 * cos(2 * phi) + C_us_3 * sin(2 * phi);
|
||||
const double u = phi + C_uc_3 * c2pk + C_us_3 * s2pk;
|
||||
const double suk = sin(u);
|
||||
const double cuk = cos(u);
|
||||
const double ukdot = pkdot * (1.0 + 2.0 * (C_us_3 * c2pk - C_uc_3 * s2pk));
|
||||
|
||||
// Correct radius
|
||||
const double r = a * (1 - e_1 * cos(E)) + C_rc_3 * cos(2 * phi) + C_rs_3 * sin(2 * phi);
|
||||
const double r = a * OneMinusecosE + C_rc_3 * c2pk + C_rs_3 * s2pk;
|
||||
const double rkdot = a * e_1 * sek * ekdot + 2.0 * pkdot * (C_rs_3 * c2pk - C_rc_3 * s2pk);
|
||||
|
||||
// Correct inclination
|
||||
const double i = i_0_2 + iDot_2 * tk + C_ic_4 * cos(2 * phi) + C_is_4 * sin(2 * phi);
|
||||
const double i = i_0_2 + iDot_2 * tk + C_ic_4 * c2pk + C_is_4 * s2pk;
|
||||
const double sik = sin(i);
|
||||
const double cik = cos(i);
|
||||
const double ikdot = iDot_2 + 2.0 * pkdot * (C_is_4 * c2pk - C_ic_4 * s2pk);
|
||||
|
||||
// Compute the angle between the ascending node and the Greenwich meridian
|
||||
double Omega = OMEGA_0_2 + (OMEGA_dot_3 - GNSS_OMEGA_EARTH_DOT) * tk - GNSS_OMEGA_EARTH_DOT * t0e_1;
|
||||
const double Omega_dot = OMEGA_dot_3 - GNSS_OMEGA_EARTH_DOT;
|
||||
double Omega = OMEGA_0_2 + Omega_dot * tk - GNSS_OMEGA_EARTH_DOT * static_cast<double>(t0e_1);
|
||||
|
||||
// Reduce to between 0 and 2*pi rad
|
||||
Omega = fmod((Omega + 2 * GNSS_PI), (2 * GNSS_PI));
|
||||
Omega = fmod((Omega + 2.0 * GNSS_PI), (2.0 * GNSS_PI));
|
||||
const double sok = sin(Omega);
|
||||
const double cok = cos(Omega);
|
||||
|
||||
// --- Compute satellite coordinates in Earth-fixed coordinates
|
||||
d_satpos_X = cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega);
|
||||
d_satpos_Y = cos(u) * r * sin(Omega) + sin(u) * r * cos(i) * cos(Omega); // ********NOTE: in GALILEO ICD this expression is not correct because it has minus (- sin(u) * r * cos(i) * cos(Omega)) instead of plus
|
||||
d_satpos_Z = sin(u) * r * sin(i);
|
||||
const double xprime = r * cuk;
|
||||
const double yprime = r * suk;
|
||||
d_satpos_X = xprime * cok - yprime * cik * sok;
|
||||
d_satpos_Y = xprime * sok + yprime * cik * cok; // ********NOTE: in GALILEO ICD this expression is not correct because it has minus (- sin(u) * r * cos(i) * cos(Omega)) instead of plus
|
||||
d_satpos_Z = yprime * sik;
|
||||
|
||||
// Satellite's velocity. Can be useful for Vector Tracking loops
|
||||
const double Omega_dot = OMEGA_dot_3 - GNSS_OMEGA_EARTH_DOT;
|
||||
d_satvel_X = -Omega_dot * (cos(u) * r + sin(u) * r * cos(i)) + d_satpos_X * cos(Omega) - d_satpos_Y * cos(i) * sin(Omega);
|
||||
d_satvel_Y = Omega_dot * (cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega)) + d_satpos_X * sin(Omega) + d_satpos_Y * cos(i) * cos(Omega);
|
||||
d_satvel_Z = d_satpos_Y * sin(i);
|
||||
const double xpkdot = rkdot * cuk - yprime * ukdot;
|
||||
const double ypkdot = rkdot * suk + xprime * ukdot;
|
||||
const double tmp = ypkdot * cik - d_satpos_Z * ikdot;
|
||||
|
||||
d_satvel_X = -Omega_dot * d_satpos_Y + xpkdot * cok - tmp * sok;
|
||||
d_satvel_Y = Omega_dot * d_satpos_X + xpkdot * sok + tmp * cok;
|
||||
d_satvel_Z = yprime * cik * ikdot + ypkdot * sik;
|
||||
}
|
||||
|
||||
|
||||
double Galileo_Ephemeris::check_t(double time)
|
||||
{
|
||||
const double half_week = 302400.0; // seconds
|
||||
double corrTime = time;
|
||||
if (time > half_week)
|
||||
{
|
||||
corrTime = time - 2.0 * half_week;
|
||||
}
|
||||
else if (time < -half_week)
|
||||
{
|
||||
corrTime = time + 2.0 * half_week;
|
||||
}
|
||||
return corrTime;
|
||||
}
|
||||
|
@ -162,6 +162,15 @@ public:
|
||||
|
||||
archive& BOOST_SERIALIZATION_NVP(flag_all_ephemeris);
|
||||
}
|
||||
|
||||
private:
|
||||
/*
|
||||
* Accounts for the beginning or end of week crossover
|
||||
*
|
||||
* \param[in] - time in seconds
|
||||
* \param[out] - corrected time, in seconds
|
||||
*/
|
||||
double check_t(double time);
|
||||
};
|
||||
|
||||
|
||||
|
@ -148,43 +148,66 @@ double Gps_CNAV_Ephemeris::satellitePosition(double transmitTime)
|
||||
}
|
||||
}
|
||||
|
||||
const double sek = sin(E);
|
||||
const double cek = cos(E);
|
||||
const double OneMinusecosE = 1.0 - d_e_eccentricity * cek;
|
||||
const double ekdot = n / OneMinusecosE;
|
||||
|
||||
// Compute the true anomaly
|
||||
const double tmp_Y = sqrt(1.0 - d_e_eccentricity * d_e_eccentricity) * sin(E);
|
||||
const double tmp_X = cos(E) - d_e_eccentricity;
|
||||
const double sq1e2 = sqrt(1.0 - d_e_eccentricity * d_e_eccentricity);
|
||||
const double tmp_Y = sq1e2 * sek;
|
||||
const double tmp_X = cek - d_e_eccentricity;
|
||||
const double nu = atan2(tmp_Y, tmp_X);
|
||||
|
||||
// Compute angle phi (argument of Latitude)
|
||||
const double phi = nu + d_OMEGA;
|
||||
double pkdot = sq1e2 * ekdot / OneMinusecosE;
|
||||
|
||||
// Reduce phi to between 0 and 2*pi rad
|
||||
// phi = fmod((phi), (2*GNSS_PI));
|
||||
// phi = fmod((phi), (2.0 * GNSS_PI));
|
||||
const double s2pk = sin(2.0 * phi);
|
||||
const double c2pk = cos(2.0 * phi);
|
||||
|
||||
// Correct argument of latitude
|
||||
const double u = phi + d_Cuc * cos(2 * phi) + d_Cus * sin(2 * phi);
|
||||
const double u = phi + d_Cuc * c2pk + d_Cus * s2pk;
|
||||
const double cuk = cos(u);
|
||||
const double suk = sin(u);
|
||||
const double ukdot = pkdot * (1.0 + 2.0 * (d_Cus * c2pk - d_Cuc * s2pk));
|
||||
|
||||
// Correct radius
|
||||
const double r = a * (1 - d_e_eccentricity * cos(E)) + d_Crc * cos(2 * phi) + d_Crs * sin(2 * phi);
|
||||
const double r = a * (1.0 - d_e_eccentricity * cek) + d_Crc * c2pk + d_Crs * s2pk;
|
||||
|
||||
const double rkdot = a * d_e_eccentricity * sek * ekdot + 2.0 * pkdot * (d_Crs * c2pk - d_Crc * s2pk);
|
||||
|
||||
// Correct inclination
|
||||
const double i = d_i_0 + d_IDOT * tk + d_Cic * cos(2 * phi) + d_Cis * sin(2 * phi);
|
||||
const double i = d_i_0 + d_IDOT * tk + d_Cic * c2pk + d_Cis * s2pk;
|
||||
const double sik = sin(i);
|
||||
const double cik = cos(i);
|
||||
const double ikdot = d_IDOT + 2.0 * pkdot * (d_Cis * c2pk - d_Cic * s2pk);
|
||||
|
||||
// Compute the angle between the ascending node and the Greenwich meridian
|
||||
const double d_OMEGA_DOT = OMEGA_DOT_REF * GNSS_PI + d_DELTA_OMEGA_DOT;
|
||||
const double Omega = d_OMEGA0 + (d_OMEGA_DOT - GNSS_OMEGA_EARTH_DOT) * tk - GNSS_OMEGA_EARTH_DOT * d_Toe1;
|
||||
const double sok = sin(Omega);
|
||||
const double cok = cos(Omega);
|
||||
|
||||
// Reduce to between 0 and 2*pi rad
|
||||
// Omega = fmod((Omega + 2*GNSS_PI), (2*GNSS_PI));
|
||||
|
||||
// --- Compute satellite coordinates in Earth-fixed coordinates
|
||||
d_satpos_X = cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega);
|
||||
d_satpos_Y = cos(u) * r * sin(Omega) + sin(u) * r * cos(i) * cos(Omega);
|
||||
d_satpos_Z = sin(u) * r * sin(i);
|
||||
// Compute satellite coordinates in Earth-fixed coordinates
|
||||
const double xprime = r * cuk;
|
||||
const double yprime = r * suk;
|
||||
d_satpos_X = xprime * cok - yprime * cik * sok;
|
||||
d_satpos_Y = xprime * sok + yprime * cik * cok;
|
||||
d_satpos_Z = yprime * sik;
|
||||
|
||||
// Satellite's velocity. Can be useful for Vector Tracking loops
|
||||
const double Omega_dot = d_OMEGA_DOT - GNSS_OMEGA_EARTH_DOT;
|
||||
d_satvel_X = -Omega_dot * (cos(u) * r + sin(u) * r * cos(i)) + d_satpos_X * cos(Omega) - d_satpos_Y * cos(i) * sin(Omega);
|
||||
d_satvel_Y = Omega_dot * (cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega)) + d_satpos_X * sin(Omega) + d_satpos_Y * cos(i) * cos(Omega);
|
||||
d_satvel_Z = d_satpos_Y * sin(i);
|
||||
|
||||
const double xpkdot = rkdot * cuk - yprime * ukdot;
|
||||
const double ypkdot = rkdot * suk + xprime * ukdot;
|
||||
const double tmp = ypkdot * cik - d_satpos_Z * ikdot;
|
||||
|
||||
d_satvel_X = -Omega_dot * d_satpos_Y + xpkdot * cok - tmp * sok;
|
||||
d_satvel_Y = Omega_dot * d_satpos_X + xpkdot * sok + tmp * cok;
|
||||
d_satvel_Z = yprime * cik * ikdot + ypkdot * sik;
|
||||
|
||||
// Time from ephemeris reference clock
|
||||
tk = check_t(transmitTime - d_Toc);
|
||||
@ -192,7 +215,7 @@ double Gps_CNAV_Ephemeris::satellitePosition(double transmitTime)
|
||||
double dtr_s = d_A_f0 + d_A_f1 * tk + d_A_f2 * tk * tk;
|
||||
|
||||
/* relativity correction */
|
||||
dtr_s -= 2.0 * sqrt(GPS_GM * a) * d_e_eccentricity * sin(E) / (SPEED_OF_LIGHT_M_S * SPEED_OF_LIGHT_M_S);
|
||||
dtr_s -= 2.0 * sqrt(GPS_GM * a) * d_e_eccentricity * sek / (SPEED_OF_LIGHT_M_S * SPEED_OF_LIGHT_M_S);
|
||||
|
||||
return dtr_s;
|
||||
}
|
||||
|
@ -155,42 +155,65 @@ double Gps_Ephemeris::satellitePosition(double transmitTime)
|
||||
}
|
||||
}
|
||||
|
||||
const double sek = sin(E);
|
||||
const double cek = cos(E);
|
||||
const double OneMinusecosE = 1.0 - d_e_eccentricity * cek;
|
||||
const double ekdot = n / OneMinusecosE;
|
||||
|
||||
// Compute the true anomaly
|
||||
const double tmp_Y = sqrt(1.0 - d_e_eccentricity * d_e_eccentricity) * sin(E);
|
||||
const double tmp_X = cos(E) - d_e_eccentricity;
|
||||
const double sq1e2 = sqrt(1.0 - d_e_eccentricity * d_e_eccentricity);
|
||||
const double tmp_Y = sq1e2 * sek;
|
||||
const double tmp_X = cek - d_e_eccentricity;
|
||||
const double nu = atan2(tmp_Y, tmp_X);
|
||||
|
||||
// Compute angle phi (argument of Latitude)
|
||||
const double phi = nu + d_OMEGA;
|
||||
double pkdot = sq1e2 * ekdot / OneMinusecosE;
|
||||
|
||||
// Reduce phi to between 0 and 2*pi rad
|
||||
// phi = fmod((phi), (2.0 * GNSS_PI));
|
||||
const double s2pk = sin(2.0 * phi);
|
||||
const double c2pk = cos(2.0 * phi);
|
||||
|
||||
// Correct argument of latitude
|
||||
const double u = phi + d_Cuc * cos(2.0 * phi) + d_Cus * sin(2.0 * phi);
|
||||
const double u = phi + d_Cuc * c2pk + d_Cus * s2pk;
|
||||
const double cuk = cos(u);
|
||||
const double suk = sin(u);
|
||||
const double ukdot = pkdot * (1.0 + 2.0 * (d_Cus * c2pk - d_Cuc * s2pk));
|
||||
|
||||
// Correct radius
|
||||
const double r = a * (1.0 - d_e_eccentricity * cos(E)) + d_Crc * cos(2.0 * phi) + d_Crs * sin(2.0 * phi);
|
||||
const double r = a * (1.0 - d_e_eccentricity * cek) + d_Crc * c2pk + d_Crs * s2pk;
|
||||
|
||||
const double rkdot = a * d_e_eccentricity * sek * ekdot + 2.0 * pkdot * (d_Crs * c2pk - d_Crc * s2pk);
|
||||
|
||||
// Correct inclination
|
||||
const double i = d_i_0 + d_IDOT * tk + d_Cic * cos(2.0 * phi) + d_Cis * sin(2.0 * phi);
|
||||
const double i = d_i_0 + d_IDOT * tk + d_Cic * c2pk + d_Cis * s2pk;
|
||||
const double sik = sin(i);
|
||||
const double cik = cos(i);
|
||||
const double ikdot = d_IDOT + 2.0 * pkdot * (d_Cis * c2pk - d_Cic * s2pk);
|
||||
|
||||
// Compute the angle between the ascending node and the Greenwich meridian
|
||||
const double Omega = d_OMEGA0 + (d_OMEGA_DOT - GNSS_OMEGA_EARTH_DOT) * tk - GNSS_OMEGA_EARTH_DOT * d_Toe;
|
||||
|
||||
// Reduce to between 0 and 2*pi rad
|
||||
// Omega = fmod((Omega + 2.0 * GNSS_PI), (2.0 * GNSS_PI));
|
||||
const double sok = sin(Omega);
|
||||
const double cok = cos(Omega);
|
||||
|
||||
// --- Compute satellite coordinates in Earth-fixed coordinates
|
||||
d_satpos_X = cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega);
|
||||
d_satpos_Y = cos(u) * r * sin(Omega) + sin(u) * r * cos(i) * cos(Omega);
|
||||
d_satpos_Z = sin(u) * r * sin(i);
|
||||
const double xprime = r * cuk;
|
||||
const double yprime = r * suk;
|
||||
d_satpos_X = xprime * cok - yprime * cik * sok;
|
||||
d_satpos_Y = xprime * sok + yprime * cik * cok;
|
||||
d_satpos_Z = yprime * sik;
|
||||
|
||||
// Satellite's velocity. Can be useful for Vector Tracking loops
|
||||
const double Omega_dot = d_OMEGA_DOT - GNSS_OMEGA_EARTH_DOT;
|
||||
d_satvel_X = -Omega_dot * (cos(u) * r + sin(u) * r * cos(i)) + d_satpos_X * cos(Omega) - d_satpos_Y * cos(i) * sin(Omega);
|
||||
d_satvel_Y = Omega_dot * (cos(u) * r * cos(Omega) - sin(u) * r * cos(i) * sin(Omega)) + d_satpos_X * sin(Omega) + d_satpos_Y * cos(i) * cos(Omega);
|
||||
d_satvel_Z = d_satpos_Y * sin(i);
|
||||
|
||||
const double xpkdot = rkdot * cuk - yprime * ukdot;
|
||||
const double ypkdot = rkdot * suk + xprime * ukdot;
|
||||
const double tmp = ypkdot * cik - d_satpos_Z * ikdot;
|
||||
|
||||
d_satvel_X = -Omega_dot * d_satpos_Y + xpkdot * cok - tmp * sok;
|
||||
d_satvel_Y = Omega_dot * d_satpos_X + xpkdot * sok + tmp * cok;
|
||||
d_satvel_Z = yprime * cik * ikdot + ypkdot * sik;
|
||||
|
||||
// Time from ephemeris reference clock
|
||||
tk = check_t(transmitTime - d_Toc);
|
||||
@ -198,7 +221,7 @@ double Gps_Ephemeris::satellitePosition(double transmitTime)
|
||||
double dtr_s = d_A_f0 + d_A_f1 * tk + d_A_f2 * tk * tk;
|
||||
|
||||
/* relativity correction */
|
||||
dtr_s -= 2.0 * sqrt(GPS_GM * a) * d_e_eccentricity * sin(E) / (SPEED_OF_LIGHT_M_S * SPEED_OF_LIGHT_M_S);
|
||||
dtr_s -= 2.0 * sqrt(GPS_GM * a) * d_e_eccentricity * sek / (SPEED_OF_LIGHT_M_S * SPEED_OF_LIGHT_M_S);
|
||||
|
||||
return dtr_s;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user