1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-09-27 14:48:24 +00:00

Merge branch 'next' of https://github.com/gnss-sdr/gnss-sdr into next

This commit is contained in:
Damian Miralles 2018-10-19 21:07:19 -05:00
commit 1b77dc9475
91 changed files with 4611 additions and 1044 deletions

View File

@ -45,7 +45,7 @@ endif(NOT CMAKE_PREFIX_PATH)
########################################################################
# Support of optional RF front-ends
option(ENABLE_UHD "Enable the use of UHD (driver for all USRP devices)" ON)
option(ENABLE_OSMOSDR "Enable the use of OsmoSDR and other front-ends (RTL-based dongles, HackRF, bladeRF, etc.) as signal source (experimental)" OFF)
option(ENABLE_OSMOSDR "Enable the use of OsmoSDR and other front-ends (RTL-based dongles, HackRF, bladeRF, etc.) as signal source" OFF)
option(ENABLE_FLEXIBAND "Enable the use of the signal source adater for the Teleorbit Flexiband GNURadio driver" OFF)
option(ENABLE_ARRAY "Enable the use of CTTC's antenna array front-end as signal source (experimental)" OFF)
option(ENABLE_GN3S "Enable the use of the GN3S dongle as signal source (experimental)" OFF)
@ -341,10 +341,10 @@ set(GNSSSDR_MATIO_MIN_VERSION "1.5.3")
################################################################################
set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.1")
set(GNSSSDR_GLOG_LOCAL_VERSION "0.3.5")
set(GNSSSDR_ARMADILLO_LOCAL_VERSION "unstable")
set(GNSSSDR_ARMADILLO_LOCAL_VERSION "9.200.x")
set(GNSSSDR_GTEST_LOCAL_VERSION "1.8.1")
set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master")
set(GNSSSDR_GPSTK_LOCAL_VERSION "2.10")
set(GNSSSDR_GPSTK_LOCAL_VERSION "2.10.6")
set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.12")
@ -622,7 +622,9 @@ if(NOT VOLK_GNSSSDR_FOUND)
if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
set(STRIP_VOLK_GNSSSDR_PROFILE "-DENABLE_STRIP=ON -DCMAKE_VERBOSE_MAKEFILE=ON")
endif(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
set(READ_ENVIRO ${CMAKE_COMMAND} -E environment)
if(NOT DEFINED ENV{PROTECT_PASSWORDS})
set(READ_ENVIRO ${CMAKE_COMMAND} -E environment)
endif(NOT DEFINED ENV{PROTECT_PASSWORDS})
endif(ENABLE_PACKAGING)
set(VOLK_GNSSSDR_BUILD_COMMAND "${CMAKE_MAKE_PROGRAM}")

View File

@ -186,9 +186,9 @@ $ sudo apt-get install libblas-dev liblapack-dev # For Debian/Ubuntu/Linux
$ sudo yum install lapack-devel blas-devel # For Fedora/CentOS/RHEL
$ sudo zypper install lapack-devel blas-devel # For OpenSUSE
$ sudo pacman -S blas lapack # For Arch Linux
$ wget https://sourceforge.net/projects/arma/files/armadillo-8.500.1.tar.xz
$ tar xvfz armadillo-8.500.1.tar.xz
$ cd armadillo-8.500.1
$ wget https://sourceforge.net/projects/arma/files/armadillo-9.100.5.tar.xz
$ tar xvfz armadillo-9.100.5.tar.xz
$ cd armadillo-9.100.5
$ cmake .
$ make
$ sudo make install

View File

@ -24,10 +24,10 @@
# also defined, but not for general use are
# GPSTK_LIBRARY, where to find the GPSTK library.
FIND_PATH(GPSTK_INCLUDE_DIR Rinex3ObsBase.hpp
HINTS /usr/include/gpstk
/usr/local/include/gpstk
/opt/local/include/gpstk )
FIND_PATH(GPSTK_INCLUDE_DIR gpstk/Rinex3ObsBase.hpp
HINTS /usr/include
/usr/local/include
/opt/local/include )
SET(GPSTK_NAMES ${GPSTK_NAMES} gpstk libgpstk)
FIND_LIBRARY(GPSTK_LIBRARY NAMES ${GPSTK_NAMES}

View File

@ -0,0 +1,28 @@
# 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/>.
find_program(SW_GENERATOR_BIN gnss_sim
PATHS /usr/bin
/usr/local/bin
/opt/local/bin
${CMAKE_INSTALL_PREFIX}/bin
PATH_SUFFIXES bin )
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNSS-SIMULATOR DEFAULT_MSG SW_GENERATOR_BIN)
MARK_AS_ADVANCED(SW_GENERATOR_BIN)

View File

@ -25,6 +25,10 @@ set(PVT_ADAPTER_SOURCES
rtklib_pvt.cc
)
set(PVT_ADAPTER_HEADERS
rtklib_pvt.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/system_parameters
@ -41,8 +45,6 @@ include_directories(
${GNURADIO_RUNTIME_INCLUDE_DIRS}
)
file(GLOB PVT_ADAPTER_HEADERS "*.h")
list(SORT PVT_ADAPTER_HEADERS)
add_library(pvt_adapters ${PVT_ADAPTER_SOURCES} ${PVT_ADAPTER_HEADERS})
source_group(Headers FILES ${PVT_ADAPTER_HEADERS})
target_link_libraries(pvt_adapters pvt_gr_blocks ${ARMADILLO_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES})

View File

@ -506,12 +506,12 @@ bool RtklibPvt::save_assistance_to_XML()
if (eph_map.empty() == false)
{
std::ofstream ofs;
try
{
std::ofstream ofs(eph_xml_filename_.c_str(), std::ofstream::trunc | std::ofstream::out);
ofs.open(eph_xml_filename_.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", eph_map);
ofs.close();
LOG(INFO) << "Saved GPS L1 Ephemeris map data";
}
catch (const std::exception& e)
@ -519,13 +519,13 @@ bool RtklibPvt::save_assistance_to_XML()
LOG(WARNING) << e.what();
return false;
}
return true; // return variable (true == succeeded)
}
else
{
LOG(WARNING) << "Failed to save Ephemeris, map is empty";
return false;
}
return true; // return variable (true == succeeded)
}

View File

@ -25,6 +25,10 @@ set(PVT_GR_BLOCKS_SOURCES
rtklib_pvt_cc.cc
)
set(PVT_GR_BLOCKS_HEADERS
rtklib_pvt_cc.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/system_parameters
@ -39,8 +43,6 @@ include_directories(
${GNURADIO_RUNTIME_INCLUDE_DIRS}
)
file(GLOB PVT_GR_BLOCKS_HEADERS "*.h")
list(SORT PVT_GR_BLOCKS_HEADERS)
add_library(pvt_gr_blocks ${PVT_GR_BLOCKS_SOURCES} ${PVT_GR_BLOCKS_HEADERS})
source_group(Headers FILES ${PVT_GR_BLOCKS_HEADERS})
target_link_libraries(pvt_gr_blocks pvt_lib ${ARMADILLO_LIBRARIES})

View File

@ -50,6 +50,10 @@ namespace bc = boost::math;
namespace bc = boost::integer;
#endif
//includes used by the observables serializarion (export observables for rtklib unit test)
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/serialization/map.hpp>
using google::LogMessage;
@ -392,16 +396,15 @@ rtklib_pvt_cc::~rtklib_pvt_cc()
msgctl(sysv_msqid, IPC_RMID, NULL);
// save GPS L2CM ephemeris to XML file
std::string file_name = "eph_GPS_CNAV.xml";
std::string file_name = "gps_cnav_ephemeris.xml";
if (d_ls_pvt->gps_cnav_ephemeris_map.empty() == false)
{
std::ofstream ofs;
try
{
std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->gps_cnav_ephemeris_map);
ofs.close();
xml << boost::serialization::make_nvp("GNSS-SDR_cnav_ephemeris_map", d_ls_pvt->gps_cnav_ephemeris_map);
LOG(INFO) << "Saved GPS L2CM or L5 Ephemeris map data";
}
catch (std::exception& e)
@ -411,20 +414,19 @@ rtklib_pvt_cc::~rtklib_pvt_cc()
}
else
{
LOG(WARNING) << "Failed to save GPS L2CM or L5 Ephemeris, map is empty";
LOG(INFO) << "Failed to save GPS L2CM or L5 Ephemeris, map is empty";
}
// save GPS L1 CA ephemeris to XML file
file_name = "eph_GPS_L1CA.xml";
file_name = "gps_ephemeris.xml";
if (d_ls_pvt->gps_ephemeris_map.empty() == false)
{
std::ofstream ofs;
try
{
std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->gps_ephemeris_map);
ofs.close();
LOG(INFO) << "Saved GPS L1 CA Ephemeris map data";
}
catch (const std::exception& e)
@ -434,20 +436,19 @@ rtklib_pvt_cc::~rtklib_pvt_cc()
}
else
{
LOG(WARNING) << "Failed to save GPS L1 CA Ephemeris, map is empty";
LOG(INFO) << "Failed to save GPS L1 CA Ephemeris, map is empty";
}
// save Galileo E1 ephemeris to XML file
file_name = "eph_Galileo_E1.xml";
file_name = "gal_ephemeris.xml";
if (d_ls_pvt->galileo_ephemeris_map.empty() == false)
{
std::ofstream ofs;
try
{
std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->galileo_ephemeris_map);
ofs.close();
xml << boost::serialization::make_nvp("GNSS-SDR_gal_ephemeris_map", d_ls_pvt->galileo_ephemeris_map);
LOG(INFO) << "Saved Galileo E1 Ephemeris map data";
}
catch (const std::exception& e)
@ -457,20 +458,19 @@ rtklib_pvt_cc::~rtklib_pvt_cc()
}
else
{
LOG(WARNING) << "Failed to save Galileo E1 Ephemeris, map is empty";
LOG(INFO) << "Failed to save Galileo E1 Ephemeris, map is empty";
}
// save GLONASS GNAV ephemeris to XML file
file_name = "eph_GLONASS_GNAV.xml";
if (d_ls_pvt->glonass_gnav_ephemeris_map.empty() == false)
{
std::ofstream ofs;
try
{
std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->glonass_gnav_ephemeris_map);
ofs.close();
xml << boost::serialization::make_nvp("GNSS-SDR_gnav_ephemeris_map", d_ls_pvt->glonass_gnav_ephemeris_map);
LOG(INFO) << "Saved GLONASS GNAV Ephemeris map data";
}
catch (std::exception& e)
@ -480,7 +480,73 @@ rtklib_pvt_cc::~rtklib_pvt_cc()
}
else
{
LOG(WARNING) << "Failed to save GLONASS GNAV Ephemeris, map is empty";
LOG(INFO) << "Failed to save GLONASS GNAV Ephemeris, map is empty";
}
// Save GPS UTC model parameters
file_name = "gps_utc_model.xml";
if (d_ls_pvt->gps_utc_model.valid)
{
std::ofstream ofs;
try
{
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_utc_model", d_ls_pvt->gps_utc_model);
LOG(INFO) << "Saved GPS UTC model parameters";
}
catch (std::exception& e)
{
LOG(WARNING) << e.what();
}
}
else
{
LOG(INFO) << "Failed to save GPS UTC model parameters, not valid data";
}
// Save Galileo UTC model parameters
file_name = "gal_utc_model.xml";
if (d_ls_pvt->galileo_utc_model.A0_6 != 0.0)
{
std::ofstream ofs;
try
{
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_gal_utc_model", d_ls_pvt->galileo_utc_model);
LOG(INFO) << "Saved Galileo UTC model parameters";
}
catch (std::exception& e)
{
LOG(WARNING) << e.what();
}
}
else
{
LOG(INFO) << "Failed to save Galileo UTC model parameters, not valid data";
}
// Save GPS CNAV UTC model parameters
file_name = "gps_cnav_utc_model.xml";
if (d_ls_pvt->gps_cnav_utc_model.valid)
{
std::ofstream ofs;
try
{
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_cnav_utc_model", d_ls_pvt->gps_cnav_utc_model);
LOG(INFO) << "Saved GPS CNAV UTC model parameters";
}
catch (std::exception& e)
{
LOG(WARNING) << e.what();
}
}
else
{
LOG(INFO) << "Failed to save GPS CNAV UTC model parameters, not valid data";
}
}
@ -507,6 +573,54 @@ bool rtklib_pvt_cc::send_sys_v_ttff_msg(ttff_msgbuf ttff)
}
bool rtklib_pvt_cc::save_gnss_synchro_map_xml(const std::string file_name)
{
if (gnss_observables_map.empty() == false)
{
std::ofstream ofs;
try
{
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_gnss_synchro_map", gnss_observables_map);
LOG(INFO) << "Saved gnss_sychro map data";
}
catch (std::exception& e)
{
LOG(WARNING) << e.what();
return false;
}
return true;
}
else
{
LOG(WARNING) << "Failed to save gnss_synchro, map is empty";
return false;
}
}
bool rtklib_pvt_cc::load_gnss_synchro_map_xml(const std::string file_name)
{
// load from xml (boost serialize)
std::ifstream ifs;
try
{
ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
boost::archive::xml_iarchive xml(ifs);
gnss_observables_map.clear();
xml >> boost::serialization::make_nvp("GNSS-SDR_gnss_synchro_map", gnss_observables_map);
//std::cout << "Loaded gnss_synchro map data with " << gnss_synchro_map.size() << " pseudoranges" << std::endl;
}
catch (std::exception& e)
{
std::cout << e.what() << "File: " << file_name;
return false;
}
return true;
}
int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items __attribute__((unused)))
{
@ -526,7 +640,6 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
gnss_observables_map.clear();
const Gnss_Synchro** in = reinterpret_cast<const Gnss_Synchro**>(&input_items[0]); // Get the input buffer pointer
// ############ 1. READ PSEUDORANGES ####
for (uint32_t i = 0; i < d_nchannels; i++)
{
@ -610,8 +723,15 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
// it->second.Pseudorange_m = it->second.Pseudorange_m - d_ls_pvt->get_time_offset_s() * GPS_C_m_s;
// }
if (d_ls_pvt->get_PVT(gnss_observables_map, false))
{
//Optional debug code: export observables snapshot for rtklib unit testing
//std::cout << "step 1: save gnss_synchro map" << std::endl;
//save_gnss_synchro_map_xml("./gnss_synchro_map.xml");
//getchar(); //stop the execution
//end debug
if (current_RX_time_ms % d_display_rate_ms == 0)
{
flag_display_pvt = true;
@ -2060,7 +2180,6 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
{
std::streamsize ss = std::cout.precision(); // save current precision
std::cout.setf(std::ios::fixed, std::ios::floatfield);
auto facet = new boost::posix_time::time_facet("%Y-%b-%d %H:%M:%S.%f %z");
std::cout.imbue(std::locale(std::cout.getloc(), facet));

View File

@ -152,6 +152,10 @@ private:
bool send_sys_v_ttff_msg(ttff_msgbuf ttff);
std::chrono::time_point<std::chrono::system_clock> start, end;
bool save_gnss_synchro_map_xml(const std::string file_name); //debug helper function
bool load_gnss_synchro_map_xml(const std::string file_name); //debug helper function
public:
rtklib_pvt_cc(uint32_t nchannels,
bool dump, std::string dump_filename,

View File

@ -31,6 +31,20 @@ set(PVT_LIB_SOURCES
rtklib_solver.cc
)
set(PVT_LIB_HEADERS
pvt_solution.h
ls_pvt.h
hybrid_ls_pvt.h
kml_printer.h
gpx_printer.h
rinex_printer.h
nmea_printer.h
rtcm_printer.h
geojson_printer.h
rtklib_solver.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/system_parameters
@ -45,8 +59,9 @@ include_directories(
${GLOG_INCLUDE_DIRS}
)
file(GLOB PVT_LIB_HEADERS "*.h")
list(SORT PVT_LIB_HEADERS)
list(SORT PVT_LIB_SOURCES)
add_library(pvt_lib ${PVT_LIB_SOURCES} ${PVT_LIB_HEADERS})
source_group(Headers FILES ${PVT_LIB_HEADERS})
add_dependencies(pvt_lib rtklib_lib armadillo-${armadillo_RELEASE} glog-${glog_RELEASE})
@ -60,5 +75,4 @@ target_link_libraries(
${ARMADILLO_LIBRARIES}
${BLAS}
${LAPACK}
)
)

View File

@ -76,12 +76,13 @@ private:
rtk_t rtk_;
std::string d_dump_filename;
std::ofstream d_dump_file;
sol_t pvt_sol;
bool d_flag_dump_enabled;
int d_nchannels; // Number of available channels for positioning
double dop_[4];
public:
sol_t pvt_sol;
rtklib_solver(int nchannels, std::string dump_filename, bool flag_dump_to_file, rtk_t& rtk);
~rtklib_solver();

View File

@ -36,12 +36,43 @@ set(ACQ_ADAPTER_SOURCES
glonass_l2_ca_pcps_acquisition.cc
)
set(ACQ_ADAPTER_HEADERS
gps_l1_ca_pcps_acquisition.h
gps_l1_ca_pcps_assisted_acquisition.h
gps_l1_ca_pcps_acquisition_fine_doppler.h
gps_l1_ca_pcps_tong_acquisition.h
gps_l1_ca_pcps_quicksync_acquisition.h
gps_l2_m_pcps_acquisition.h
gps_l5i_pcps_acquisition.h
galileo_e1_pcps_ambiguous_acquisition.h
galileo_e1_pcps_cccwsr_ambiguous_acquisition.h
galileo_e1_pcps_quicksync_ambiguous_acquisition.h
galileo_e1_pcps_tong_ambiguous_acquisition.h
galileo_e1_pcps_8ms_ambiguous_acquisition.h
galileo_e5a_noncoherent_iq_acquisition_caf.h
galileo_e5a_pcps_acquisition.h
glonass_l1_ca_pcps_acquisition.h
glonass_l2_ca_pcps_acquisition.h
)
if(ENABLE_FPGA)
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)
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)
set(ACQ_ADAPTER_HEADERS ${ACQ_ADAPTER_HEADERS} gps_l1_ca_pcps_acquisition_fpga.h
gps_l2_m_pcps_acquisition_fpga.h
galileo_e1_pcps_ambiguous_acquisition_fpga.h
galileo_e5a_pcps_acquisition_fpga.h
gps_l5i_pcps_acquisition_fpga.h)
endif(ENABLE_FPGA)
if(OPENCL_FOUND)
set(ACQ_ADAPTER_SOURCES ${ACQ_ADAPTER_SOURCES} gps_l1_ca_pcps_opencl_acquisition.cc)
set(ACQ_ADAPTER_HEADERS ${ACQ_ADAPTER_HEADERS} gps_l1_ca_pcps_opencl_acquisition.h)
endif(OPENCL_FOUND)
include_directories(
@ -61,8 +92,8 @@ include_directories(
${VOLK_GNSSSDR_INCLUDE_DIRS}
)
file(GLOB ACQ_ADAPTER_HEADERS "*.h")
list(SORT ACQ_ADAPTER_HEADERS)
list(SORT ACQ_ADAPTER_SOURCES)
add_library(acq_adapters ${ACQ_ADAPTER_SOURCES} ${ACQ_ADAPTER_HEADERS})
source_group(Headers FILES ${ACQ_ADAPTER_HEADERS})
target_link_libraries(acq_adapters acquisition_lib gnss_sp_libs gnss_sdr_flags acq_gr_blocks ${Boost_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_BLOCKS_LIBRARIES})

View File

@ -26,14 +26,27 @@ set(ACQ_GR_BLOCKS_SOURCES
pcps_quicksync_acquisition_cc.cc
galileo_pcps_8ms_acquisition_cc.cc
galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc
)
set(ACQ_GR_BLOCKS_HEADERS
pcps_acquisition.h
pcps_assisted_acquisition_cc.h
pcps_acquisition_fine_doppler_cc.h
pcps_tong_acquisition_cc.h
pcps_cccwsr_acquisition_cc.h
pcps_quicksync_acquisition_cc.h
galileo_pcps_8ms_acquisition_cc.h
galileo_e5a_noncoherent_iq_acquisition_caf_cc.h
)
if(ENABLE_FPGA)
set(ACQ_GR_BLOCKS_SOURCES ${ACQ_GR_BLOCKS_SOURCES} pcps_acquisition_fpga.cc)
set(ACQ_GR_BLOCKS_HEADERS ${ACQ_GR_BLOCKS_HEADERS} pcps_acquisition_fpga.h)
endif(ENABLE_FPGA)
if(OPENCL_FOUND)
set(ACQ_GR_BLOCKS_SOURCES ${ACQ_GR_BLOCKS_SOURCES} pcps_opencl_acquisition_cc.cc)
set(ACQ_GR_BLOCKS_HEADERS ${ACQ_GR_BLOCKS_HEADERS} pcps_opencl_acquisition_cc.h)
endif(OPENCL_FOUND)
include_directories(
@ -61,8 +74,8 @@ if(OPENCL_FOUND)
endif(OS_IS_MACOSX)
endif(OPENCL_FOUND)
file(GLOB ACQ_GR_BLOCKS_HEADERS "*.h")
list(SORT ACQ_GR_BLOCKS_HEADERS)
list(SORT ACQ_GR_BLOCKS_SOURCES)
add_library(acq_gr_blocks ${ACQ_GR_BLOCKS_SOURCES} ${ACQ_GR_BLOCKS_HEADERS})
source_group(Headers FILES ${ACQ_GR_BLOCKS_HEADERS})

View File

@ -271,8 +271,8 @@ void pcps_acquisition::init()
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
d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
if (acq_parameters.make_2_steps)
if (d_grid_doppler_wipeoffs == nullptr) d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
if (acq_parameters.make_2_steps && (d_grid_doppler_wipeoffs_step_two == nullptr))
{
d_grid_doppler_wipeoffs_step_two = new gr_complex*[d_num_doppler_bins_step2];
for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins_step2; doppler_index++)
@ -281,11 +281,18 @@ void pcps_acquisition::init()
}
}
d_magnitude_grid = new float*[d_num_doppler_bins];
if (d_magnitude_grid == nullptr)
{
d_magnitude_grid = new float*[d_num_doppler_bins];
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_magnitude_grid[doppler_index] = static_cast<float*>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
}
}
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_magnitude_grid[doppler_index] = static_cast<float*>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
for (uint32_t k = 0; k < d_fft_size; k++)
{
d_magnitude_grid[doppler_index][k] = 0.0;

View File

@ -18,6 +18,7 @@
if(ENABLE_FPGA)
set(ACQUISITION_LIB_SOURCES fpga_acquisition.cc )
set(ACQUISITION_LIB_HEADERS fpga_acquisition.h )
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/system_parameters
@ -29,15 +30,14 @@ if(ENABLE_FPGA)
${GFlags_INCLUDE_DIRS}
${VOLK_GNSSSDR_INCLUDE_DIRS}
)
file(GLOB ACQUISITION_LIB_HEADERS "*.h")
endif(ENABLE_FPGA)
set(ACQUISITION_LIB_HEADERS ${ACQUISITION_LIB_HEADERS} acq_conf.h)
list(SORT ACQUISITION_LIB_HEADERS)
set(ACQUISITION_LIB_SOURCES ${ACQUISITION_LIB_SOURCES} acq_conf.cc)
list(SORT ACQUISITION_LIB_HEADERS)
list(SORT ACQUISITION_LIB_SOURCES)
add_library(acquisition_lib ${ACQUISITION_LIB_SOURCES} ${ACQUISITION_LIB_HEADERS})
source_group(Headers FILES ${ACQUISITION_LIB_HEADERS})
target_link_libraries(acquisition_lib ${VOLK_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES})

View File

@ -17,6 +17,7 @@
#
set(CHANNEL_ADAPTER_SOURCES channel.cc)
set(CHANNEL_ADAPTER_HEADERS channel.h)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
@ -31,8 +32,6 @@ include_directories(
${GNURADIO_RUNTIME_INCLUDE_DIRS}
)
file(GLOB CHANNEL_ADAPTER_HEADERS "*.h")
list(SORT CHANNEL_ADAPTER_HEADERS)
add_library(channel_adapters ${CHANNEL_ADAPTER_SOURCES} ${CHANNEL_ADAPTER_HEADERS})
source_group(Headers FILES ${CHANNEL_ADAPTER_HEADERS})
target_link_libraries(channel_adapters channel_fsm ${GNURADIO_RUNTIME_LIBRARIES} ${Boost_LIBRARIES} gnss_sdr_flags)

View File

@ -20,6 +20,11 @@ set(CHANNEL_FSM_SOURCES
channel_fsm.cc
channel_msg_receiver_cc.cc
)
set(CHANNEL_FSM_HEADERS
channel_fsm.h
channel_msg_receiver_cc.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
@ -33,8 +38,9 @@ include_directories(
${GNURADIO_RUNTIME_INCLUDE_DIRS}
)
file(GLOB CHANNEL_FSM_HEADERS "*.h")
list(SORT CHANNEL_FSM_HEADERS)
list(SORT CHANNEL_FSM_SOURCES)
add_library(channel_fsm ${CHANNEL_FSM_SOURCES} ${CHANNEL_FSM_HEADERS})
source_group(Headers FILES ${CHANNEL_FSM_HEADERS})
add_dependencies(channel_fsm glog-${glog_RELEASE})

View File

@ -22,6 +22,11 @@ set(COND_ADAPTER_SOURCES
array_signal_conditioner.cc
)
set(COND_ADAPTER_HEADERS
signal_conditioner.h
array_signal_conditioner.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/system_parameters
@ -34,8 +39,9 @@ include_directories(
${GNURADIO_RUNTIME_INCLUDE_DIRS}
)
file(GLOB COND_ADAPTER_HEADERS "*.h")
list(SORT COND_ADAPTER_HEADERS)
list(SORT COND_ADAPTER_SOURCES)
add_library(conditioner_adapters ${COND_ADAPTER_SOURCES} ${COND_ADAPTER_HEADERS})
source_group(Headers FILES ${COND_ADAPTER_HEADERS})
add_dependencies(conditioner_adapters glog-${glog_RELEASE})

View File

@ -24,7 +24,16 @@ set(DATATYPE_ADAPTER_SOURCES
ibyte_to_cshort.cc
ishort_to_cshort.cc
ishort_to_complex.cc
)
)
set(DATATYPE_ADAPTER_HEADERS
byte_to_short.h
ibyte_to_cbyte.h
ibyte_to_complex.h
ibyte_to_cshort.h
ishort_to_cshort.h
ishort_to_complex.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
@ -38,10 +47,10 @@ include_directories(
${VOLK_INCLUDE_DIRS}
)
file(GLOB DATATYPE_ADAPTER_HEADERS "*.h")
list(SORT DATATYPE_ADAPTER_HEADERS)
list(SORT DATATYPE_ADAPTER_SOURCES)
add_library(datatype_adapters ${DATATYPE_ADAPTER_SOURCES} ${DATATYPE_ADAPTER_HEADERS})
source_group(Headers FILES ${DATATYPE_ADAPTER_HEADERS})
add_dependencies(datatype_adapters glog-${glog_RELEASE})
target_link_libraries(datatype_adapters data_type_gr_blocks ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_BLOCKS_LIBRARIES})

View File

@ -23,14 +23,21 @@ set(DATA_TYPE_GR_BLOCKS_SOURCES
interleaved_byte_to_complex_short.cc
)
set(DATA_TYPE_GR_BLOCKS_HEADERS
interleaved_byte_to_complex_byte.h
interleaved_short_to_complex_short.h
interleaved_byte_to_complex_short.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${GNURADIO_RUNTIME_INCLUDE_DIRS}
${VOLK_INCLUDE_DIRS}
)
file(GLOB DATA_TYPE_GR_BLOCKS_HEADERS "*.h")
list(SORT DATA_TYPE_GR_BLOCKS_HEADERS)
list(SORT DATA_TYPE_GR_BLOCKS_SOURCES)
add_library(data_type_gr_blocks ${DATA_TYPE_GR_BLOCKS_SOURCES} ${DATA_TYPE_GR_BLOCKS_HEADERS})
source_group(Headers FILES ${DATA_TYPE_GR_BLOCKS_HEADERS})
target_link_libraries(data_type_gr_blocks ${GNURADIO_RUNTIME_LIBRARIES} ${VOLK_LIBRARIES})
target_link_libraries(data_type_gr_blocks ${GNURADIO_RUNTIME_LIBRARIES} ${VOLK_LIBRARIES})

View File

@ -17,7 +17,7 @@
#
set(INPUT_FILTER_ADAPTER_SOURCES
fir_filter.cc
fir_filter.cc
freq_xlating_fir_filter.cc
beamformer_filter.cc
pulse_blanking_filter.cc
@ -25,6 +25,15 @@ set(INPUT_FILTER_ADAPTER_SOURCES
notch_filter_lite.cc
)
set(INPUT_FILTER_ADAPTER_HEADERS
fir_filter.h
freq_xlating_fir_filter.h
beamformer_filter.h
pulse_blanking_filter.h
notch_filter.h
notch_filter_lite.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/system_parameters
@ -41,8 +50,9 @@ if(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.13.4" )
add_definitions( -DGR_GREATER_38=1 )
endif(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.13.4" )
file(GLOB INPUT_FILTER_ADAPTER_HEADERS "*.h")
list(SORT INPUT_FILTER_ADAPTER_HEADERS)
list(SORT INPUT_FILTER_ADAPTER_SOURCES)
add_library(input_filter_adapters ${INPUT_FILTER_ADAPTER_SOURCES} ${INPUT_FILTER_ADAPTER_HEADERS})
source_group(Headers FILES ${INPUT_FILTER_ADAPTER_HEADERS})
add_dependencies(input_filter_adapters glog-${glog_RELEASE} gnss_sp_libs)

View File

@ -24,6 +24,13 @@ set(INPUT_FILTER_GR_BLOCKS_SOURCES
notch_lite_cc.cc
)
set(INPUT_FILTER_GR_BLOCKS_HEADERS
beamformer.h
pulse_blanking_cc.h
notch_cc.h
notch_lite_cc.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${GNURADIO_RUNTIME_INCLUDE_DIRS}
@ -33,8 +40,9 @@ include_directories(
${GFlags_INCLUDE_DIRS}
)
file(GLOB INPUT_FILTER_GR_BLOCKS_HEADERS "*.h")
list(SORT INPUT_FILTER_GR_BLOCKS_HEADERS)
list(SORT INPUT_FILTER_GR_BLOCKS_SOURCES)
add_library(input_filter_gr_blocks ${INPUT_FILTER_GR_BLOCKS_SOURCES} ${INPUT_FILTER_GR_BLOCKS_HEADERS})
source_group(Headers FILES ${INPUT_FILTER_GR_BLOCKS_HEADERS})

View File

@ -18,14 +18,12 @@
add_subdirectory(rtklib)
if(ENABLE_FPGA)
set(GNSS_SPLIBS_SOURCES
set(GNSS_SPLIBS_SOURCES
gps_l2c_signal.cc
gps_l5_signal.cc
galileo_e1_signal_processing.cc
gnss_sdr_valve.cc
gnss_sdr_sample_counter.cc
gnss_sdr_time_counter.cc
gnss_signal_processing.cc
gps_sdr_signal_processing.cc
glonass_l1_signal_processing.cc
@ -40,30 +38,43 @@ if(ENABLE_FPGA)
conjugate_cc.cc
conjugate_sc.cc
conjugate_ic.cc
)
set(GNSS_SPLIBS_HEADERS
gps_l2c_signal.h
gps_l5_signal.h
galileo_e1_signal_processing.h
gnss_sdr_valve.h
gnss_sdr_sample_counter.h
gnss_signal_processing.h
gps_sdr_signal_processing.h
glonass_l1_signal_processing.h
glonass_l2_signal_processing.h
pass_through.h
galileo_e5_signal_processing.h
complex_byte_to_float_x2.h
byte_x2_to_complex_byte.h
cshort_to_float_x2.h
short_x2_to_cshort.h
complex_float_to_complex_byte.h
conjugate_cc.h
conjugate_sc.h
conjugate_ic.h
gnss_circular_deque.h
)
if(ENABLE_FPGA)
set(GNSS_SPLIBS_SOURCES ${GNSS_SPLIBS_SOURCES}
gnss_sdr_time_counter.cc
gnss_sdr_fpga_sample_counter.cc
)
else(ENABLE_FPGA)
set(GNSS_SPLIBS_SOURCES
gps_l2c_signal.cc
gps_l5_signal.cc
galileo_e1_signal_processing.cc
gnss_sdr_valve.cc
gnss_sdr_sample_counter.cc
gnss_signal_processing.cc
gps_sdr_signal_processing.cc
glonass_l1_signal_processing.cc
glonass_l2_signal_processing.cc
pass_through.cc
galileo_e5_signal_processing.cc
complex_byte_to_float_x2.cc
byte_x2_to_complex_byte.cc
cshort_to_float_x2.cc
short_x2_to_cshort.cc
complex_float_to_complex_byte.cc
conjugate_cc.cc
conjugate_sc.cc
conjugate_ic.cc
)
set(GNSS_SPLIBS_HEADERS ${GNSS_SPLIBS_HEADERS}
gnss_sdr_time_counter.h
gnss_sdr_fpga_sample_counter.h
)
endif(ENABLE_FPGA)
if(OPENCL_FOUND)
@ -71,7 +82,13 @@ if(OPENCL_FOUND)
opencl/fft_execute.cc # Needs OpenCL
opencl/fft_setup.cc # Needs OpenCL
opencl/fft_kernelstring.cc # Needs OpenCL
)
)
set(GNSS_SPLIBS_HEADERS ${GNSS_SPLIBS_HEADERS}
opencl/fft_execute.h # Needs OpenCL
opencl/fft_setup.h # Needs OpenCL
opencl/fft_kernelstring.h # Needs OpenCL
)
endif(OPENCL_FOUND)
include_directories(
@ -99,9 +116,9 @@ endif(OPENCL_FOUND)
add_definitions(-DGNSSSDR_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}")
file(GLOB GNSS_SPLIBS_HEADERS "*.h")
list(REMOVE_ITEM GNSS_SPLIBS_HEADERS gnss_sdr_flags.h)
list(SORT GNSS_SPLIBS_HEADERS)
list(SORT GNSS_SPLIBS_SOURCES)
add_library(gnss_sp_libs ${GNSS_SPLIBS_SOURCES} ${GNSS_SPLIBS_HEADERS})
source_group(Headers FILES ${GNSS_SPLIBS_HEADERS})

View File

@ -38,6 +38,27 @@ set(RTKLIB_LIB_SOURCES
rtklib_rtcm3.cc
)
set(RTKLIB_LIB_HEADERS
rtklib_rtkcmn.h
rtklib_ephemeris.h
rtklib_preceph.h
rtklib_sbas.h
rtklib_ionex.h
rtklib_pntpos.h
rtklib_ppp.h
rtklib_tides.h
rtklib_lambda.h
rtklib_rtkpos.h
rtklib_conversions.h
rtklib_stream.h
rtklib_rtksvr.h
rtklib_solution.h
rtklib_rtcm.h
rtklib_rtcm2.h
rtklib_rtcm3.h
rtklib.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/system_parameters
@ -48,8 +69,10 @@ include_directories(
${GLOG_INCLUDE_DIRS}
)
file(GLOB RTKLIB_LIB_HEADERS "*.h")
list(SORT RTKLIB_LIB_HEADERS)
list(SORT RTKLIB_LIB_SOURCES)
add_library(rtklib_lib ${RTKLIB_LIB_SOURCES} ${RTKLIB_LIB_HEADERS})
source_group(Headers FILES ${RTKLIB_LIB_HEADERS})
add_dependencies(rtklib_lib glog-${glog_RELEASE})

View File

@ -246,7 +246,7 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
else if (obs->code[i] != CODE_NONE and obs->code[j] == CODE_NONE)
{
P1 += P1_C1; /* C1->P1 */
PC = P1 + P1_P2;
PC = P1 - P1_P2;
}
else if (obs->code[i] == CODE_NONE and obs->code[j] != CODE_NONE)
{
@ -739,6 +739,7 @@ int resdop(const obsd_t *obs, int n, const double *rs, const double *dts,
{
double lam, rate, pos[3], E[9], a[3], e[3], vs[3], cosel;
int i, j, nv = 0;
int band = 0;
trace(3, "resdop : n=%d\n", n);
@ -747,9 +748,12 @@ int resdop(const obsd_t *obs, int n, const double *rs, const double *dts,
for (i = 0; i < n && i < MAXOBS; i++)
{
lam = nav->lam[obs[i].sat - 1][0];
if (obs[i].code[0] != CODE_NONE) band = 0;
if (obs[i].code[1] != CODE_NONE) band = 1;
if (obs[i].code[2] != CODE_NONE) band = 2;
lam = nav->lam[obs[i].sat - 1][band];
if (obs[i].D[0] == 0.0 || lam == 0.0 || !vsat[i] || norm_rtk(rs + 3 + i * 6, 3) <= 0.0)
if (obs[i].D[band] == 0.0 || lam == 0.0 || !vsat[i] || norm_rtk(rs + 3 + i * 6, 3) <= 0.0)
{
continue;
}
@ -767,7 +771,7 @@ int resdop(const obsd_t *obs, int n, const double *rs, const double *dts,
rate = dot(vs, e, 3) + DEFAULT_OMEGA_EARTH_DOT / SPEED_OF_LIGHT * (rs[4 + i * 6] * rr[0] + rs[1 + i * 6] * x[0] - rs[3 + i * 6] * rr[1] - rs[i * 6] * x[1]);
/* doppler residual */
v[nv] = -lam * obs[i].D[0] - (rate + x[3] - SPEED_OF_LIGHT * dts[1 + i * 2]);
v[nv] = -lam * obs[i].D[band] - (rate + x[3] - SPEED_OF_LIGHT * dts[1 + i * 2]);
/* design matrix */
for (j = 0; j < 4; j++) H[j + nv * 4] = j < 3 ? -e[j] : 1.0;

View File

@ -673,277 +673,6 @@ void pppoutsolstat(rtk_t *rtk, int level, FILE *fp)
}
/* solar/lunar tides (ref [2] 7) ---------------------------------------------*/
void tide_pl(const double *eu, const double *rp, double GMp,
const double *pos, double *dr)
{
const double H3 = 0.292, L3 = 0.015;
double r, ep[3], latp, lonp, p, K2, K3, a, H2, L2, dp, du, cosp, sinl, cosl;
int i;
trace(4, "tide_pl : pos=%.3f %.3f\n", pos[0] * R2D, pos[1] * R2D);
if ((r = norm_rtk(rp, 3)) <= 0.0) return;
for (i = 0; i < 3; i++) ep[i] = rp[i] / r;
K2 = GMp / GME * std::pow(RE_WGS84, 2.0) * std::pow(RE_WGS84, 2.0) / (r * r * r);
K3 = K2 * RE_WGS84 / r;
latp = asin(ep[2]);
lonp = atan2(ep[1], ep[0]);
cosp = cos(latp);
sinl = sin(pos[0]);
cosl = cos(pos[0]);
/* step1 in phase (degree 2) */
p = (3.0 * sinl * sinl - 1.0) / 2.0;
H2 = 0.6078 - 0.0006 * p;
L2 = 0.0847 + 0.0002 * p;
a = dot(ep, eu, 3);
dp = K2 * 3.0 * L2 * a;
du = K2 * (H2 * (1.5 * a * a - 0.5) - 3.0 * L2 * a * a);
/* step1 in phase (degree 3) */
dp += K3 * L3 * (7.5 * a * a - 1.5);
du += K3 * (H3 * (2.5 * a * a * a - 1.5 * a) - L3 * (7.5 * a * a - 1.5) * a);
/* step1 out-of-phase (only radial) */
du += 3.0 / 4.0 * 0.0025 * K2 * sin(2.0 * latp) * sin(2.0 * pos[0]) * sin(pos[1] - lonp);
du += 3.0 / 4.0 * 0.0022 * K2 * cosp * cosp * cosl * cosl * sin(2.0 * (pos[1] - lonp));
dr[0] = dp * ep[0] + du * eu[0];
dr[1] = dp * ep[1] + du * eu[1];
dr[2] = dp * ep[2] + du * eu[2];
trace(5, "tide_pl : dr=%.3f %.3f %.3f\n", dr[0], dr[1], dr[2]);
}
/* displacement by solid earth tide (ref [2] 7) ------------------------------*/
void tide_solid(const double *rsun, const double *rmoon,
const double *pos, const double *E, double gmst, int opt,
double *dr)
{
double dr1[3], dr2[3], eu[3], du, dn, sinl, sin2l;
trace(3, "tide_solid: pos=%.3f %.3f opt=%d\n", pos[0] * R2D, pos[1] * R2D, opt);
/* step1: time domain */
eu[0] = E[2];
eu[1] = E[5];
eu[2] = E[8];
tide_pl(eu, rsun, GMS, pos, dr1);
tide_pl(eu, rmoon, GMM, pos, dr2);
/* step2: frequency domain, only K1 radial */
sin2l = sin(2.0 * pos[0]);
du = -0.012 * sin2l * sin(gmst + pos[1]);
dr[0] = dr1[0] + dr2[0] + du * E[2];
dr[1] = dr1[1] + dr2[1] + du * E[5];
dr[2] = dr1[2] + dr2[2] + du * E[8];
/* eliminate permanent deformation */
if (opt & 8)
{
sinl = sin(pos[0]);
du = 0.1196 * (1.5 * sinl * sinl - 0.5);
dn = 0.0247 * sin2l;
dr[0] += du * E[2] + dn * E[1];
dr[1] += du * E[5] + dn * E[4];
dr[2] += du * E[8] + dn * E[7];
}
trace(5, "tide_solid: dr=%.3f %.3f %.3f\n", dr[0], dr[1], dr[2]);
}
/* displacement by ocean tide loading (ref [2] 7) ----------------------------*/
void tide_oload(gtime_t tut, const double *odisp, double *denu)
{
const double args[][5] = {
{1.40519E-4, 2.0, -2.0, 0.0, 0.00}, /* M2 */
{1.45444E-4, 0.0, 0.0, 0.0, 0.00}, /* S2 */
{1.37880E-4, 2.0, -3.0, 1.0, 0.00}, /* N2 */
{1.45842E-4, 2.0, 0.0, 0.0, 0.00}, /* K2 */
{0.72921E-4, 1.0, 0.0, 0.0, 0.25}, /* K1 */
{0.67598E-4, 1.0, -2.0, 0.0, -0.25}, /* O1 */
{0.72523E-4, -1.0, 0.0, 0.0, -0.25}, /* P1 */
{0.64959E-4, 1.0, -3.0, 1.0, -0.25}, /* Q1 */
{0.53234E-5, 0.0, 2.0, 0.0, 0.00}, /* Mf */
{0.26392E-5, 0.0, 1.0, -1.0, 0.00}, /* Mm */
{0.03982E-5, 2.0, 0.0, 0.0, 0.00} /* Ssa */
};
const double ep1975[] = {1975, 1, 1, 0, 0, 0};
double ep[6], fday, days, t, t2, t3, a[5], ang, dp[3] = {0};
int i, j;
trace(3, "tide_oload:\n");
/* angular argument: see subroutine arg.f for reference [1] */
time2epoch(tut, ep);
fday = ep[3] * 3600.0 + ep[4] * 60.0 + ep[5];
ep[3] = ep[4] = ep[5] = 0.0;
days = timediff(epoch2time(ep), epoch2time(ep1975)) / 86400.0;
t = (27392.500528 + 1.000000035 * days) / 36525.0;
t2 = t * t;
t3 = t2 * t;
a[0] = fday;
a[1] = (279.69668 + 36000.768930485 * t + 3.03E-4 * t2) * D2R; /* H0 */
a[2] = (270.434358 + 481267.88314137 * t - 0.001133 * t2 + 1.9E-6 * t3) * D2R; /* S0 */
a[3] = (334.329653 + 4069.0340329577 * t - 0.010325 * t2 - 1.2E-5 * t3) * D2R; /* P0 */
a[4] = 2.0 * PI;
/* displacements by 11 constituents */
for (i = 0; i < 11; i++)
{
ang = 0.0;
for (j = 0; j < 5; j++) ang += a[j] * args[i][j];
for (j = 0; j < 3; j++) dp[j] += odisp[j + i * 6] * cos(ang - odisp[j + 3 + i * 6] * D2R);
}
denu[0] = -dp[1];
denu[1] = -dp[2];
denu[2] = dp[0];
trace(5, "tide_oload: denu=%.3f %.3f %.3f\n", denu[0], denu[1], denu[2]);
}
/* iers mean pole (ref [7] eq.7.25) ------------------------------------------*/
void iers_mean_pole(gtime_t tut, double *xp_bar, double *yp_bar)
{
const double ep2000[] = {2000, 1, 1, 0, 0, 0};
double y, y2, y3;
y = timediff(tut, epoch2time(ep2000)) / 86400.0 / 365.25;
if (y < 3653.0 / 365.25)
{ /* until 2010.0 */
y2 = y * y;
y3 = y2 * y;
*xp_bar = 55.974 + 1.8243 * y + 0.18413 * y2 + 0.007024 * y3; /* (mas) */
*yp_bar = 346.346 + 1.7896 * y - 0.10729 * y2 - 0.000908 * y3;
}
else
{ /* after 2010.0 */
*xp_bar = 23.513 + 7.6141 * y; /* (mas) */
*yp_bar = 358.891 - 0.6287 * y;
}
}
/* displacement by pole tide (ref [7] eq.7.26) --------------------------------*/
void tide_pole(gtime_t tut, const double *pos, const double *erpv,
double *denu)
{
double xp_bar, yp_bar, m1, m2, cosl, sinl;
trace(3, "tide_pole: pos=%.3f %.3f\n", pos[0] * R2D, pos[1] * R2D);
/* iers mean pole (mas) */
iers_mean_pole(tut, &xp_bar, &yp_bar);
/* ref [7] eq.7.24 */
m1 = erpv[0] / AS2R - xp_bar * 1E-3; /* (as) */
m2 = -erpv[1] / AS2R + yp_bar * 1E-3;
/* sin(2*theta) = sin(2*phi), cos(2*theta)=-cos(2*phi) */
cosl = cos(pos[1]);
sinl = sin(pos[1]);
denu[0] = 9E-3 * sin(pos[0]) * (m1 * sinl - m2 * cosl); /* de= Slambda (m) */
denu[1] = -9E-3 * cos(2.0 * pos[0]) * (m1 * cosl + m2 * sinl); /* dn=-Stheta (m) */
denu[2] = -33E-3 * sin(2.0 * pos[0]) * (m1 * cosl + m2 * sinl); /* du= Sr (m) */
trace(5, "tide_pole : denu=%.3f %.3f %.3f\n", denu[0], denu[1], denu[2]);
}
/* tidal displacement ----------------------------------------------------------
* displacements by earth tides
* args : gtime_t tutc I time in utc
* double *rr I site position (ecef) (m)
* int opt I options (or of the followings)
* 1: solid earth tide
* 2: ocean tide loading
* 4: pole tide
* 8: elimate permanent deformation
* double *erp I earth rotation parameters (NULL: not used)
* double *odisp I ocean loading parameters (NULL: not used)
* odisp[0+i*6]: consituent i amplitude radial(m)
* odisp[1+i*6]: consituent i amplitude west (m)
* odisp[2+i*6]: consituent i amplitude south (m)
* odisp[3+i*6]: consituent i phase radial (deg)
* odisp[4+i*6]: consituent i phase west (deg)
* odisp[5+i*6]: consituent i phase south (deg)
* (i=0:M2,1:S2,2:N2,3:K2,4:K1,5:O1,6:P1,7:Q1,
* 8:Mf,9:Mm,10:Ssa)
* double *dr O displacement by earth tides (ecef) (m)
* return : none
* notes : see ref [1], [2] chap 7
* see ref [4] 5.2.1, 5.2.2, 5.2.3
* ver.2.4.0 does not use ocean loading and pole tide corrections
*-----------------------------------------------------------------------------*/
void tidedisp(gtime_t tutc, const double *rr, int opt, const erp_t *erp,
const double *odisp, double *dr)
{
gtime_t tut;
double pos[2], E[9], drt[3], denu[3], rs[3], rm[3], gmst, erpv[5] = {0};
int i;
#ifdef IERS_MODEL
double ep[6], fhr;
int year, mon, day;
#endif
trace(3, "tidedisp: tutc=%s\n", time_str(tutc, 0));
if (erp) geterp(erp, tutc, erpv);
tut = timeadd(tutc, erpv[2]);
dr[0] = dr[1] = dr[2] = 0.0;
if (norm_rtk(rr, 3) <= 0.0) return;
pos[0] = asin(rr[2] / norm_rtk(rr, 3));
pos[1] = atan2(rr[1], rr[0]);
xyz2enu(pos, E);
if (opt & 1)
{ /* solid earth tides */
/* sun and moon position in ecef */
sunmoonpos(tutc, erpv, rs, rm, &gmst);
#ifdef IERS_MODEL
time2epoch(tutc, ep);
year = (int)ep[0];
mon = (int)ep[1];
day = (int)ep[2];
fhr = ep[3] + ep[4] / 60.0 + ep[5] / 3600.0;
/* call DEHANTTIDEINEL */
dehanttideinel_((double *)rr, &year, &mon, &day, &fhr, rs, rm, drt);
#else
tide_solid(rs, rm, pos, E, gmst, opt, drt);
#endif
for (i = 0; i < 3; i++) dr[i] += drt[i];
}
if ((opt & 2) && odisp)
{ /* ocean tide loading */
tide_oload(tut, odisp, denu);
matmul("TN", 3, 1, 3, 1.0, E, denu, 0.0, drt);
for (i = 0; i < 3; i++) dr[i] += drt[i];
}
if ((opt & 4) && erp)
{ /* pole tide */
tide_pole(tut, pos, erpv, denu);
matmul("TN", 3, 1, 3, 1.0, E, denu, 0.0, drt);
for (i = 0; i < 3; i++) dr[i] += drt[i];
}
trace(5, "tidedisp: dr=%.3f %.3f %.3f\n", dr[0], dr[1], dr[2]);
}
/* exclude meas of eclipsing satellite (block IIA) ---------------------------*/
void testeclipse(const obsd_t *obs, int n, const nav_t *nav, double *rs)
{

View File

@ -129,21 +129,6 @@ int pppamb(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav, const double
/* functions originally included in RTKLIB/src/ppp.c v2.4.2 */
void pppoutsolstat(rtk_t *rtk, int level, FILE *fp);
void tide_pl(const double *eu, const double *rp, double GMp, const double *pos, double *dr);
void tide_solid(const double *rsun, const double *rmoon,
const double *pos, const double *E, double gmst, int opt,
double *dr);
void tide_oload(gtime_t tut, const double *odisp, double *denu);
void iers_mean_pole(gtime_t tut, double *xp_bar, double *yp_bar);
void tide_pole(gtime_t tut, const double *pos, const double *erpv, double *denu);
void tidedisp(gtime_t tutc, const double *rr, int opt, const erp_t *erp,
const double *odisp, double *dr);
void testeclipse(const obsd_t *obs, int n, const nav_t *nav, double *rs);
double varerr(int sat, int sys, double el, int type, const prcopt_t *opt);

View File

@ -0,0 +1,122 @@
/*!
* \file volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn.h
* \brief VOLK_GNSSSDR kernel: multiplies N complex (32-bit float per component) vectors
* by a common vector, phase rotated and accumulates the results in N float complex outputs.
* \authors <ul>
* <li> Antonio Ramos 2018. antonio.ramosdet(at)gmail.com
* </ul>
*
* VOLK_GNSSSDR kernel that multiplies N 32 bits complex vectors by a common vector, which is
* phase-rotated by phase offset and phase increment, and accumulates the results
* in N 32 bits float complex outputs.
* It is optimized to perform the N tap correlation process in GNSS receivers.
*
* -------------------------------------------------------------------------
*
* 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/>.
*
* -------------------------------------------------------------------------
*/
/*!
* \page volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn
*
* \b Overview
*
* Rotates and multiplies the reference complex vector with an arbitrary number of other real vectors,
* accumulates the results and stores them in the output vector.
* The rotation is done at a fixed rate per sample, from an initial \p phase offset.
* This function can be used for Doppler wipe-off and multiple correlator.
*
* <b>Dispatcher Prototype</b>
* \code
* void volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn(lv_32fc_t* result, const lv_32fc_t* in_common, const lv_32fc_t phase_inc, const lv_32fc_t phase_inc_rate, lv_32fc_t* phase, const float** in_a, int num_a_vectors, unsigned int num_points);
* \endcode
*
* \b Inputs
* \li in_common: Pointer to one of the vectors to be rotated, multiplied and accumulated (reference vector).
* \li phase_inc: Phase increment = lv_cmake(cos(phase_step_rad), sin(phase_step_rad))
* \li phase_inc_rate: Phase increment rate = lv_cmake(cos(phase_step_rate_rad), sin(phase_step_rate_rad))
* \li phase: Initial phase = lv_cmake(cos(initial_phase_rad), sin(initial_phase_rad))
* \li in_a: Pointer to an array of pointers to multiple vectors to be multiplied and accumulated.
* \li num_a_vectors: Number of vectors to be multiplied by the reference vector and accumulated.
* \li num_points: Number of complex values to be multiplied together, accumulated and stored into \p result.
*
* \b Outputs
* \li phase: Final phase.
* \li result: Vector of \p num_a_vectors components with the multiple vectors of \p in_a rotated, multiplied by \p in_common and accumulated.
*
*/
#ifndef INCLUDED_volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn_H
#define INCLUDED_volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn_H
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <volk_gnsssdr/volk_gnsssdr_malloc.h>
#include <volk_gnsssdr/volk_gnsssdr_complex.h>
#include <volk_gnsssdr/saturation_arithmetic.h>
#include <math.h>
#ifdef LV_HAVE_GENERIC
static inline void volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn_generic(lv_32fc_t* result, const lv_32fc_t* in_common, const lv_32fc_t phase_inc, const lv_32fc_t phase_inc_rate, lv_32fc_t* phase, const float** in_a, int num_a_vectors, unsigned int num_points)
{
lv_32fc_t tmp32_1;
#ifdef __cplusplus
lv_32fc_t half_phase_inc_rate = std::sqrt(phase_inc_rate);
#else
lv_32fc_t half_phase_inc_rate = csqrtf(phase_inc_rate);
#endif
lv_32fc_t constant_rotation = phase_inc * half_phase_inc_rate;
lv_32fc_t delta_phase_rate = lv_cmake(1.0f, 0.0f);
int n_vec;
unsigned int n;
for (n_vec = 0; n_vec < num_a_vectors; n_vec++)
{
result[n_vec] = lv_cmake(0.0f, 0.0f);
}
for (n = 0; n < num_points; n++)
{
tmp32_1 = *in_common++ * (*phase);
// Regenerate phase
if (n % 256 == 0)
{
#ifdef __cplusplus
(*phase) /= std::abs((*phase));
delta_phase_rate /= std::abs(delta_phase_rate);
#else
(*phase) /= hypotf(lv_creal(*phase), lv_cimag(*phase));
delta_phase_rate /= hypotf(lv_creal(delta_phase_rate), lv_cimag(delta_phase_rate));
#endif
}
(*phase) *= (constant_rotation * delta_phase_rate);
delta_phase_rate *= phase_inc_rate;
for (n_vec = 0; n_vec < num_a_vectors; n_vec++)
{
result[n_vec] += (tmp32_1 * in_a[n_vec][n]);
}
}
}
#endif /*LV_HAVE_GENERIC*/
#endif /* INCLUDED_volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn_H */

View File

@ -0,0 +1,163 @@
/*!
* \file volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc.h
* \brief Volk puppet for the multiple 16-bit complex dot product kernel.
* \authors <ul>
* <li> Carles Fernandez Prades 2016 cfernandez at cttc dot cat
* </ul>
*
* Volk puppet for integrating the resampler into volk's test system
*
* -------------------------------------------------------------------------
*
* 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 INCLUDED_volk_gnsssdr_32fc_32f_high_dynamic_rotator_dotprodxnpuppet_32fc_H
#define INCLUDED_volk_gnsssdr_32fc_32f_high_dynamic_rotator_dotprodxnpuppet_32fc_H
#include "volk_gnsssdr/volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn.h"
#include <volk_gnsssdr/volk_gnsssdr_malloc.h>
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <string.h>
#ifdef LV_HAVE_GENERIC
static inline void volk_gnsssdr_32fc_32f_high_dynamic_rotator_dotprodxnpuppet_32fc_generic(lv_32fc_t* result, const lv_32fc_t* local_code, const float* in, unsigned int num_points)
{
// phases must be normalized. Phase rotator expects a complex exponential input!
float rem_carrier_phase_in_rad = 0.25;
float phase_step_rad = 0.1;
lv_32fc_t phase[1];
phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad));
lv_32fc_t phase_inc[1];
phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad));
lv_32fc_t phase_inc_rate[1];
phase_inc_rate[0] = lv_cmake(cos(phase_step_rad * 0.001), sin(phase_step_rad * 0.001));
int n;
int num_a_vectors = 3;
float** in_a = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_a_vectors, volk_gnsssdr_get_alignment());
for (n = 0; n < num_a_vectors; n++)
{
in_a[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment());
memcpy((float*)in_a[n], (float*)in, sizeof(float) * num_points);
}
volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn_generic(result, local_code, phase_inc[0], phase_inc_rate[0], phase, (const float**)in_a, num_a_vectors, num_points);
for (n = 0; n < num_a_vectors; n++)
{
volk_gnsssdr_free(in_a[n]);
}
volk_gnsssdr_free(in_a);
}
#endif // Generic
//
//#ifdef LV_HAVE_GENERIC
//static inline void volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc_generic_reload(lv_32fc_t* result, const lv_32fc_t* local_code, const float* in, unsigned int num_points)
//{
// // phases must be normalized. Phase rotator expects a complex exponential input!
// float rem_carrier_phase_in_rad = 0.25;
// float phase_step_rad = 0.1;
// lv_32fc_t phase[1];
// phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad));
// lv_32fc_t phase_inc[1];
// phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad));
// int n;
// int num_a_vectors = 3;
// float** in_a = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_a_vectors, volk_gnsssdr_get_alignment());
// for (n = 0; n < num_a_vectors; n++)
// {
// in_a[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment());
// memcpy((float*)in_a[n], (float*)in, sizeof(float) * num_points);
// }
// volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_generic_reload(result, local_code, phase_inc[0], phase, (const float**)in_a, num_a_vectors, num_points);
//
// for (n = 0; n < num_a_vectors; n++)
// {
// volk_gnsssdr_free(in_a[n]);
// }
// volk_gnsssdr_free(in_a);
//}
//
//#endif // Generic
//
//#ifdef LV_HAVE_AVX
//static inline void volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc_u_avx(lv_32fc_t* result, const lv_32fc_t* local_code, const float* in, unsigned int num_points)
//{
// // phases must be normalized. Phase rotator expects a complex exponential input!
// float rem_carrier_phase_in_rad = 0.25;
// float phase_step_rad = 0.1;
// lv_32fc_t phase[1];
// phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad));
// lv_32fc_t phase_inc[1];
// phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad));
// int n;
// int num_a_vectors = 3;
// float** in_a = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_a_vectors, volk_gnsssdr_get_alignment());
// for (n = 0; n < num_a_vectors; n++)
// {
// in_a[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment());
// memcpy((float*)in_a[n], (float*)in, sizeof(float) * num_points);
// }
// volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_u_avx(result, local_code, phase_inc[0], phase, (const float**)in_a, num_a_vectors, num_points);
//
// for (n = 0; n < num_a_vectors; n++)
// {
// volk_gnsssdr_free(in_a[n]);
// }
// volk_gnsssdr_free(in_a);
//}
//
//#endif // AVX
//
//
//#ifdef LV_HAVE_AVX
//static inline void volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc_a_avx(lv_32fc_t* result, const lv_32fc_t* local_code, const float* in, unsigned int num_points)
//{
// // phases must be normalized. Phase rotator expects a complex exponential input!
// float rem_carrier_phase_in_rad = 0.25;
// float phase_step_rad = 0.1;
// lv_32fc_t phase[1];
// phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad));
// lv_32fc_t phase_inc[1];
// phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad));
// int n;
// int num_a_vectors = 3;
// float** in_a = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_a_vectors, volk_gnsssdr_get_alignment());
// for (n = 0; n < num_a_vectors; n++)
// {
// in_a[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment());
// memcpy((float*)in_a[n], (float*)in, sizeof(float) * num_points);
// }
// volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_a_avx(result, local_code, phase_inc[0], phase, (const float**)in_a, num_a_vectors, num_points);
//
// for (n = 0; n < num_a_vectors; n++)
// {
// volk_gnsssdr_free(in_a[n]);
// }
// volk_gnsssdr_free(in_a);
//}
//
//#endif // AVX
#endif // INCLUDED_volk_gnsssdr_32fc_32f_high_dynamic_rotator_dotprodxnpuppet_32fc_H

View File

@ -99,6 +99,7 @@ std::vector<volk_gnsssdr_test_case_t> init_test_list(volk_gnsssdr_test_params_t
QA(VOLK_INIT_PUPP(volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic, volk_gnsssdr_16ic_16i_rotator_dot_prod_16ic_xn, test_params_int16))
QA(VOLK_INIT_PUPP(volk_gnsssdr_32fc_x2_rotator_dotprodxnpuppet_32fc, volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn, test_params_int1))
QA(VOLK_INIT_PUPP(volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc, volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn, test_params_int1));
QA(VOLK_INIT_PUPP(volk_gnsssdr_32fc_32f_high_dynamic_rotator_dotprodxnpuppet_32fc, volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn, test_params_int1));
return test_cases;
}

View File

@ -20,6 +20,10 @@ set(OBS_ADAPTER_SOURCES
hybrid_observables.cc
)
set(OBS_ADAPTER_HEADERS
hybrid_observables.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/system_parameters
@ -33,8 +37,6 @@ include_directories(
${GNURADIO_RUNTIME_INCLUDE_DIRS}
)
file(GLOB OBS_ADAPTER_HEADERS "*.h")
list(SORT OBS_ADAPTER_HEADERS)
add_library(obs_adapters ${OBS_ADAPTER_SOURCES} ${OBS_ADAPTER_HEADERS})
source_group(Headers FILES ${OBS_ADAPTER_HEADERS})
target_link_libraries(obs_adapters obs_gr_blocks ${GNURADIO_RUNTIME_LIBRARIES})

View File

@ -20,6 +20,10 @@ set(OBS_GR_BLOCKS_SOURCES
hybrid_observables_cc.cc
)
set(OBS_GR_BLOCKS_HEADERS
hybrid_observables_cc.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/system_parameters
@ -34,8 +38,6 @@ include_directories(
${MATIO_INCLUDE_DIRS}
)
file(GLOB OBS_GR_BLOCKS_HEADERS "*.h")
list(SORT OBS_GR_BLOCKS_HEADERS)
add_library(obs_gr_blocks ${OBS_GR_BLOCKS_SOURCES} ${OBS_GR_BLOCKS_HEADERS})
source_group(Headers FILES ${OBS_GR_BLOCKS_HEADERS})
if(MATIO_FOUND)

View File

@ -484,7 +484,7 @@ int hybrid_observables_cc::general_work(int noutput_items __attribute__((unused)
if (T_rx_clock_step_samples == 0)
{
T_rx_clock_step_samples = std::round(static_cast<double>(in[d_nchannels_in - 1][0].fs) * 1e-3); // 1 ms
std::cout << "Observables clock step samples set to " << T_rx_clock_step_samples << std::endl;
LOG(INFO) << "Observables clock step samples set to " << T_rx_clock_step_samples;
usleep(1000000);
}

View File

@ -21,6 +21,12 @@ set(RESAMPLER_ADAPTER_SOURCES
mmse_resampler_conditioner.cc
)
set(RESAMPLER_ADAPTER_HEADERS
direct_resampler_conditioner.h
mmse_resampler_conditioner.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/interfaces
@ -36,9 +42,9 @@ if(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.13.4" )
add_definitions( -DGR_GREATER_38=1 )
endif(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.13.4" )
file(GLOB RESAMPLER_ADAPTER_HEADERS "*.h")
list(SORT RESAMPLER_ADAPTER_HEADERS)
list(SORT RESAMPLER_ADAPTER_SOURCES)
add_library(resampler_adapters ${RESAMPLER_ADAPTER_SOURCES} ${RESAMPLER_ADAPTER_HEADERS})
source_group(Headers FILES ${RESAMPLER_ADAPTER_HEADERS})
target_link_libraries(resampler_adapters resampler_gr_blocks)

View File

@ -23,6 +23,12 @@ set(RESAMPLER_GR_BLOCKS_SOURCES
direct_resampler_conditioner_cb.cc
)
set(RESAMPLER_GR_BLOCKS_HEADERS
direct_resampler_conditioner_cc.h
direct_resampler_conditioner_cs.h
direct_resampler_conditioner_cb.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${GLOG_INCLUDE_DIRS}
@ -31,8 +37,9 @@ include_directories(
${VOLK_INCLUDE_DIRS}
)
file(GLOB RESAMPLER_GR_BLOCKS_HEADERS "*.h")
list(SORT RESAMPLER_GR_BLOCKS_HEADERS)
list(SORT RESAMPLER_GR_BLOCKS_SOURCES)
add_library(resampler_gr_blocks ${RESAMPLER_GR_BLOCKS_SOURCES} ${RESAMPLER_GR_BLOCKS_HEADERS})
source_group(Headers FILES ${RESAMPLER_GR_BLOCKS_HEADERS})
add_dependencies(resampler_gr_blocks glog-${glog_RELEASE})

View File

@ -17,6 +17,7 @@
#
set(SIGNAL_GENERATOR_ADAPTER_SOURCES signal_generator.cc)
set(SIGNAL_GENERATOR_ADAPTER_HEADERS signal_generator.h)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
@ -30,8 +31,6 @@ include_directories(
${GNURADIO_RUNTIME_INCLUDE_DIRS}
)
file(GLOB SIGNAL_GENERATOR_ADAPTER_HEADERS "*.h")
list(SORT SIGNAL_GENERATOR_ADAPTER_HEADERS)
add_library(signal_generator_adapters ${SIGNAL_GENERATOR_ADAPTER_SOURCES} ${SIGNAL_GENERATOR_ADAPTER_HEADERS})
source_group(Headers FILES ${SIGNAL_GENERATOR_ADAPTER_HEADERS})
target_link_libraries(signal_generator_adapters gnss_sp_libs

View File

@ -17,6 +17,7 @@
#
set(SIGNAL_GENERATOR_BLOCK_SOURCES signal_generator_c.cc)
set(SIGNAL_GENERATOR_BLOCK_HEADERS signal_generator_c.h)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
@ -30,8 +31,6 @@ include_directories(
${VOLK_GNSSSDR_INCLUDE_DIRS}
)
file(GLOB SIGNAL_GENERATOR_BLOCK_HEADERS "*.h")
list(SORT SIGNAL_GENERATOR_BLOCK_HEADERS)
add_library(signal_generator_blocks ${SIGNAL_GENERATOR_BLOCK_SOURCES} ${SIGNAL_GENERATOR_BLOCK_HEADERS})
source_group(Headers FILES ${SIGNAL_GENERATOR_BLOCK_HEADERS})
target_link_libraries(signal_generator_blocks gnss_system_parameters gnss_sp_libs
@ -44,4 +43,4 @@ if(VOLK_GNSSSDR_FOUND)
# add_dependencies(signal_generator_blocks glog-${glog_RELEASE})
else(VOLK_GNSSSDR_FOUND)
add_dependencies(signal_generator_blocks volk_gnsssdr_module)
endif()
endif(VOLK_GNSSSDR_FOUND)

View File

@ -16,8 +16,6 @@
# along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
#
file(GLOB SIGNAL_SOURCE_ADAPTER_HEADERS "*.h")
list(SORT SIGNAL_SOURCE_ADAPTER_HEADERS)
# Optional drivers
@ -30,6 +28,7 @@ if(ENABLE_RAW_UDP)
set(OPT_LIBRARIES ${OPT_LIBRARIES} ${PCAP_LIBRARIES})
set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${PCAP_INCLUDE_DIRS})
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} custom_udp_signal_source.cc)
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} custom_udp_signal_source.h)
endif(ENABLE_RAW_UDP)
if(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2)
@ -67,6 +66,7 @@ if(ENABLE_PLUTOSDR)
##############################################
if(IIO_FOUND)
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} plutosdr_signal_source.cc)
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} plutosdr_signal_source.h)
endif(IIO_FOUND)
endif(ENABLE_PLUTOSDR)
@ -77,6 +77,7 @@ if(ENABLE_FMCOMMS2)
###############################################
if(IIO_FOUND)
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} fmcomms2_signal_source.cc)
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} fmcomms2_signal_source.h)
endif(IIO_FOUND)
endif(ENABLE_FMCOMMS2)
@ -86,6 +87,7 @@ if(ENABLE_AD9361)
###############################################
if(LIBIIO_FOUND)
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} ad9361_fpga_signal_source.cc)
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} ad9361_fpga_signal_source.h)
endif(LIBIIO_FOUND)
endif(ENABLE_AD9361)
@ -103,6 +105,7 @@ if(ENABLE_GN3S)
set(OPT_LIBRARIES ${OPT_LIBRARIES} ${GR_GN3S_LIBRARIES})
set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${GR_GN3S_INCLUDE_DIRS})
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} gn3s_signal_source.cc)
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} gn3s_signal_source.h)
endif(ENABLE_GN3S)
@ -123,6 +126,7 @@ if(ENABLE_FLEXIBAND)
set(OPT_LIBRARIES ${OPT_LIBRARIES} ${TELEORBIT_LIBRARIES})
set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${FLEXIBAND_DRIVER_INCLUDE_DIRS})
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} flexiband_signal_source.cc)
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} flexiband_signal_source.h)
endif(ENABLE_FLEXIBAND)
@ -138,6 +142,7 @@ if(ENABLE_ARRAY)
set(OPT_LIBRARIES ${OPT_LIBRARIES} ${GR_DBFCTTC_LIBRARIES})
set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${GR_DBFCTTC_INCLUDE_DIRS})
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} raw_array_signal_source.cc)
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} raw_array_signal_source.h)
endif(ENABLE_ARRAY)
@ -154,8 +159,9 @@ if(ENABLE_OSMOSDR)
set(OSMO_DRIVER_INCLUDE_DIRS
${OPT_DRIVER_INCLUDE_DIRS}
${GROSMOSDR_INCLUDE_DIR}/osmosdr
)
)
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} osmosdr_signal_source.cc)
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} osmosdr_signal_source.h)
set(OPT_LIBRARIES ${OPT_LIBRARIES} ${GROSMOSDR_LIBRARIES})
set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${OSMO_DRIVER_INCLUDE_DIRS})
endif(NOT GROSMOSDR_FOUND)
@ -163,10 +169,9 @@ endif(ENABLE_OSMOSDR)
if(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd)
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} uhd_signal_source.cc)
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} uhd_signal_source.h)
set(OPT_LIBRARIES ${OPT_LIBRARIES} ${UHD_LIBRARIES} ${GNURADIO_UHD_LIBRARIES})
set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${UHD_INCLUDE_DIRS})
else(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd)
list(REMOVE_ITEM SIGNAL_SOURCE_ADAPTER_HEADERS ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/adapters/uhd_signal_source.h)
endif(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd)
@ -180,10 +185,24 @@ set(SIGNAL_SOURCE_ADAPTER_SOURCES file_signal_source.cc
${OPT_DRIVER_SOURCES}
)
set(SIGNAL_SOURCE_ADAPTER_HEADERS file_signal_source.h
gen_signal_source.h
nsr_file_signal_source.h
spir_file_signal_source.h
spir_gss6450_file_signal_source.h
rtl_tcp_signal_source.h
labsat_signal_source.h
${OPT_DRIVER_HEADERS}
)
if(PC_GNURADIO_RUNTIME_VERSION VERSION_GREATER 3.7.3)
set(SIGNAL_SOURCE_ADAPTER_SOURCES ${SIGNAL_SOURCE_ADAPTER_SOURCES}
two_bit_cpx_file_signal_source.cc
two_bit_packed_file_signal_source.cc )
set(SIGNAL_SOURCE_ADAPTER_HEADERS ${SIGNAL_SOURCE_ADAPTER_HEADERS}
two_bit_cpx_file_signal_source.h
two_bit_packed_file_signal_source.h )
endif(PC_GNURADIO_RUNTIME_VERSION VERSION_GREATER 3.7.3)
include_directories(
@ -207,6 +226,9 @@ endif(ARCH_64BITS)
add_definitions(-DGNSSSDR_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}")
list(SORT SIGNAL_SOURCE_ADAPTER_HEADERS)
list(SORT SIGNAL_SOURCE_ADAPTER_SOURCES)
add_library(signal_source_adapters ${SIGNAL_SOURCE_ADAPTER_SOURCES} ${SIGNAL_SOURCE_ADAPTER_HEADERS})
source_group(Headers FILES ${SIGNAL_SOURCE_ADAPTER_HEADERS})
target_link_libraries(signal_source_adapters signal_source_gr_blocks

View File

@ -26,8 +26,10 @@ if(ENABLE_RAW_UDP)
set(OPT_LIBRARIES ${OPT_LIBRARIES} ${PCAP_LIBRARIES})
set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${PCAP_INCLUDE_DIRS})
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} gr_complex_ip_packet_source.cc)
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} gr_complex_ip_packet_source.h)
endif(ENABLE_RAW_UDP)
set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES
unpack_byte_2bit_samples.cc
unpack_byte_2bit_cpx_samples.cc
@ -40,6 +42,19 @@ set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES
${OPT_DRIVER_SOURCES}
)
set(SIGNAL_SOURCE_GR_BLOCKS_HEADERS
unpack_byte_2bit_samples.h
unpack_byte_2bit_cpx_samples.h
unpack_byte_4bit_samples.h
unpack_intspir_1bit_samples.h
rtl_tcp_signal_source_c.h
unpack_2bit_samples.h
unpack_spir_gss6450_samples.h
labsat23_source.h
${OPT_DRIVER_HEADERS}
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/libs
@ -50,8 +65,9 @@ include_directories(
${OPT_DRIVER_INCLUDE_DIRS}
)
file(GLOB SIGNAL_SOURCE_GR_BLOCKS_HEADERS "*.h")
list(SORT SIGNAL_SOURCE_GR_BLOCKS_HEADERS)
list(SORT SIGNAL_SOURCE_GR_BLOCKS_SOURCES)
add_library(signal_source_gr_blocks ${SIGNAL_SOURCE_GR_BLOCKS_SOURCES} ${SIGNAL_SOURCE_GR_BLOCKS_HEADERS})
source_group(Headers FILES ${SIGNAL_SOURCE_GR_BLOCKS_HEADERS})
target_link_libraries(signal_source_gr_blocks

View File

@ -63,21 +63,23 @@ include_directories(
${GLOG_INCLUDE_DIRS}
${GFlags_INCLUDE_DIRS}
${OPT_DRIVER_INCLUDE_DIRS}
)
)
set(SIGNAL_SOURCE_LIB_SOURCES
rtl_tcp_commands.cc
rtl_tcp_dongle_info.cc
${OPT_SIGNAL_SOURCE_LIB_SOURCES}
)
)
set(SIGNAL_SOURCE_LIB_HEADERS
rtl_tcp_commands.h
rtl_tcp_dongle_info.h
${OPT_SIGNAL_SOURCE_LIB_HEADERS}
)
)
list(SORT SIGNAL_SOURCE_LIB_HEADERS)
list(SORT SIGNAL_SOURCE_LIB_SOURCES)
add_library(signal_source_lib ${SIGNAL_SOURCE_LIB_SOURCES} ${SIGNAL_SOURCE_LIB_HEADERS})
source_group(Headers FILES ${SIGNAL_SOURCE_LIB_HEADERS})
target_link_libraries(signal_source_lib ${OPT_LIBRARIES})

View File

@ -28,6 +28,17 @@ set(TELEMETRY_DECODER_ADAPTER_SOURCES
glonass_l2_ca_telemetry_decoder.cc
)
set(TELEMETRY_DECODER_ADAPTER_HEADERS
gps_l1_ca_telemetry_decoder.h
gps_l2c_telemetry_decoder.h
gps_l5_telemetry_decoder.h
galileo_e1b_telemetry_decoder.h
sbas_l1_telemetry_decoder.h
galileo_e5a_telemetry_decoder.h
glonass_l1_ca_telemetry_decoder.h
glonass_l2_ca_telemetry_decoder.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/system_parameters
@ -42,8 +53,9 @@ include_directories(
${GNURADIO_RUNTIME_INCLUDE_DIRS}
)
file(GLOB TELEMETRY_DECODER_ADAPTER_HEADERS "*.h")
list(SORT TELEMETRY_DECODER_ADAPTER_HEADERS)
list(SORT TELEMETRY_DECODER_ADAPTER_SOURCES)
add_library(telemetry_decoder_adapters ${TELEMETRY_DECODER_ADAPTER_SOURCES} ${TELEMETRY_DECODER_ADAPTER_HEADERS})
source_group(Headers FILES ${TELEMETRY_DECODER_ADAPTER_HEADERS})
target_link_libraries(telemetry_decoder_adapters telemetry_decoder_gr_blocks gnss_system_parameters ${GNURADIO_RUNTIME_LIBRARIES})

View File

@ -26,6 +26,16 @@ set(TELEMETRY_DECODER_GR_BLOCKS_SOURCES
galileo_telemetry_decoder_cc.cc
)
set(TELEMETRY_DECODER_GR_BLOCKS_HEADERS
gps_l1_ca_telemetry_decoder_cc.h
gps_l2c_telemetry_decoder_cc.h
gps_l5_telemetry_decoder_cc.h
sbas_l1_telemetry_decoder_cc.h
glonass_l1_ca_telemetry_decoder_cc.h
glonass_l2_ca_telemetry_decoder_cc.h
galileo_telemetry_decoder_cc.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/system_parameters
@ -39,8 +49,9 @@ include_directories(
${VOLK_GNSSSDR_INCLUDE_DIRS}
)
file(GLOB TELEMETRY_DECODER_GR_BLOCKS_HEADERS "*.h")
list(SORT TELEMETRY_DECODER_GR_BLOCKS_HEADERS)
list(SORT TELEMETRY_DECODER_GR_BLOCKS_SOURCES)
add_library(telemetry_decoder_gr_blocks ${TELEMETRY_DECODER_GR_BLOCKS_SOURCES} ${TELEMETRY_DECODER_GR_BLOCKS_HEADERS})
source_group(Headers FILES ${TELEMETRY_DECODER_GR_BLOCKS_HEADERS})
target_link_libraries(telemetry_decoder_gr_blocks telemetry_decoder_libswiftcnav telemetry_decoder_lib gnss_system_parameters ${GNURADIO_RUNTIME_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES})

View File

@ -22,6 +22,11 @@ set(TELEMETRY_DECODER_LIB_SOURCES
viterbi_decoder.cc
)
set(TELEMETRY_DECODER_LIB_HEADERS
viterbi_decoder.h
convolutional.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/system_parameters
@ -33,9 +38,9 @@ include_directories(
${GFlags_INCLUDE_DIRS}
)
file(GLOB TELEMETRY_DECODER_LIB_HEADERS "*.h")
list(SORT TELEMETRY_DECODER_LIB_HEADERS)
list(SORT TELEMETRY_DECODER_LIB_SOURCES)
add_library(telemetry_decoder_lib ${TELEMETRY_DECODER_LIB_SOURCES} ${TELEMETRY_DECODER_LIB_HEADERS})
source_group(Headers FILES ${TELEMETRY_DECODER_LIB_HEADERS})
target_link_libraries(telemetry_decoder_lib gnss_system_parameters)

View File

@ -23,13 +23,21 @@ set(TELEMETRY_DECODER_LIBSWIFTCNAV_SOURCES
viterbi27.c
)
set(TELEMETRY_DECODER_LIBSWIFTCNAV_HEADERS
cnav_msg.h
bits.h
edc.h
swift_common.h
fec.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
)
file(GLOB TELEMETRY_DECODER_LIBSWIFTCNAV_HEADERS "*.h")
list(SORT TELEMETRY_DECODER_LIBSWIFTCNAV_HEADERS)
list(SORT TELEMETRY_DECODER_LIBSWIFTCNAV_SOURCES)
add_library(telemetry_decoder_libswiftcnav STATIC ${TELEMETRY_DECODER_LIBSWIFTCNAV_SOURCES} ${TELEMETRY_DECODER_LIBSWIFTCNAV_HEADERS})
source_group(Headers FILES ${TELEMETRY_DECODER_LIBSWIFTCNAV_HEADERS})
set_target_properties(telemetry_decoder_libswiftcnav PROPERTIES LINKER_LANGUAGE C)
set_target_properties(telemetry_decoder_libswiftcnav PROPERTIES LINKER_LANGUAGE C)

View File

@ -17,12 +17,25 @@
#
if(ENABLE_CUDA)
set(OPT_TRACKING_ADAPTERS ${OPT_TRACKING_ADAPTERS} gps_l1_ca_dll_pll_tracking_gpu.cc)
set(OPT_TRACKING_ADAPTERS_SOURCES ${OPT_TRACKING_ADAPTERS_SOURCES} gps_l1_ca_dll_pll_tracking_gpu.cc)
set(OPT_TRACKING_ADAPTERS_HEADERS ${OPT_TRACKING_ADAPTERS_HEADERS} gps_l1_ca_dll_pll_tracking_gpu.h)
set(OPT_TRACKING_INCLUDE_DIRS ${OPT_TRACKING_INCLUDE_DIRS} ${CUDA_INCLUDE_DIRS})
endif(ENABLE_CUDA)
if(ENABLE_FPGA)
SET(OPT_TRACKING_ADAPTERS ${OPT_TRACKING_ADAPTERS} gps_l1_ca_dll_pll_tracking_fpga.cc gps_l2_m_dll_pll_tracking_fpga.cc galileo_e1_dll_pll_veml_tracking_fpga.cc galileo_e5a_dll_pll_tracking_fpga.cc gps_l5_dll_pll_tracking_fpga.cc)
set(OPT_TRACKING_ADAPTERS_SOURCES ${OPT_TRACKING_ADAPTERS_SOURCES}
gps_l1_ca_dll_pll_tracking_fpga.cc
gps_l2_m_dll_pll_tracking_fpga.cc
galileo_e1_dll_pll_veml_tracking_fpga.cc
galileo_e5a_dll_pll_tracking_fpga.cc
gps_l5_dll_pll_tracking_fpga.cc)
set(OPT_TRACKING_ADAPTERS_HEADERS ${OPT_TRACKING_ADAPTERS_HEADERS}
gps_l1_ca_dll_pll_tracking_fpga.h
gps_l2_m_dll_pll_tracking_fpga.h
galileo_e1_dll_pll_veml_tracking_fpga.h
galileo_e5a_dll_pll_tracking_fpga.h
gps_l5_dll_pll_tracking_fpga.h)
endif(ENABLE_FPGA)
set(TRACKING_ADAPTER_SOURCES
@ -39,7 +52,24 @@ set(TRACKING_ADAPTER_SOURCES
gps_l5_dll_pll_tracking.cc
glonass_l2_ca_dll_pll_tracking.cc
glonass_l2_ca_dll_pll_c_aid_tracking.cc
${OPT_TRACKING_ADAPTERS}
${OPT_TRACKING_ADAPTERS_SOURCES}
)
set(TRACKING_ADAPTER_HEADERS
galileo_e1_dll_pll_veml_tracking.h
galileo_e1_tcp_connector_tracking.h
gps_l1_ca_dll_pll_tracking.h
gps_l1_ca_dll_pll_c_aid_tracking.h
gps_l1_ca_tcp_connector_tracking.h
galileo_e5a_dll_pll_tracking.h
gps_l2_m_dll_pll_tracking.h
glonass_l1_ca_dll_pll_tracking.h
glonass_l1_ca_dll_pll_c_aid_tracking.h
gps_l1_ca_kf_tracking.h
gps_l5_dll_pll_tracking.h
glonass_l2_ca_dll_pll_tracking.h
glonass_l2_ca_dll_pll_c_aid_tracking.h
${OPT_TRACKING_ADAPTERS_HEADERS}
)
include_directories(
@ -58,8 +88,9 @@ include_directories(
${OPT_TRACKING_INCLUDE_DIRS}
)
file(GLOB TRACKING_ADAPTER_HEADERS "*.h")
list(SORT TRACKING_ADAPTER_HEADERS)
list(SORT TRACKING_ADAPTER_SOURCES)
add_library(tracking_adapters ${TRACKING_ADAPTER_SOURCES} ${TRACKING_ADAPTER_HEADERS})
source_group(Headers FILES ${TRACKING_ADAPTER_HEADERS})
target_link_libraries(tracking_adapters tracking_gr_blocks gnss_sp_libs gnss_sdr_flags)

View File

@ -59,6 +59,16 @@ GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking(
trk_param.fs_in = fs_in;
bool dump = configuration->property(role + ".dump", false);
trk_param.dump = dump;
trk_param.high_dyn = configuration->property(role + ".high_dyn", false);
if (configuration->property(role + ".smoother_length", 10) < 1)
{
trk_param.smoother_length = 1;
std::cout << TEXT_RED << "WARNING: Gal. E1. smoother_length must be bigger than 0. It has been set to 1" << TEXT_RESET << std::endl;
}
else
{
trk_param.smoother_length = configuration->property(role + ".smoother_length", 10);
}
float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 5.0);
if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast<float>(FLAGS_pll_bw_hz);
trk_param.pll_bw_hz = pll_bw_hz;

View File

@ -59,6 +59,16 @@ GalileoE5aDllPllTracking::GalileoE5aDllPllTracking(
trk_param.fs_in = fs_in;
bool dump = configuration->property(role + ".dump", false);
trk_param.dump = dump;
trk_param.high_dyn = configuration->property(role + ".high_dyn", false);
if (configuration->property(role + ".smoother_length", 10) < 1)
{
trk_param.smoother_length = 1;
std::cout << TEXT_RED << "WARNING: Gal. E5a. smoother_length must be bigger than 0. It has been set to 1" << TEXT_RESET << std::endl;
}
else
{
trk_param.smoother_length = configuration->property(role + ".smoother_length", 10);
}
float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 20.0);
if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast<float>(FLAGS_pll_bw_hz);
trk_param.pll_bw_hz = pll_bw_hz;

View File

@ -57,6 +57,16 @@ GpsL1CaDllPllTracking::GpsL1CaDllPllTracking(
int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
trk_param.fs_in = fs_in;
trk_param.high_dyn = configuration->property(role + ".high_dyn", false);
if (configuration->property(role + ".smoother_length", 10) < 1)
{
trk_param.smoother_length = 1;
std::cout << TEXT_RED << "WARNING: GPS L1 C/A. smoother_length must be bigger than 0. It has been set to 1" << TEXT_RESET << std::endl;
}
else
{
trk_param.smoother_length = configuration->property(role + ".smoother_length", 10);
}
bool dump = configuration->property(role + ".dump", false);
trk_param.dump = dump;
float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0);

View File

@ -59,6 +59,16 @@ GpsL5DllPllTracking::GpsL5DllPllTracking(
trk_param.fs_in = fs_in;
bool dump = configuration->property(role + ".dump", false);
trk_param.dump = dump;
trk_param.high_dyn = configuration->property(role + ".high_dyn", false);
if (configuration->property(role + ".smoother_length", 10) < 1)
{
trk_param.smoother_length = 1;
std::cout << TEXT_RED << "WARNING: GPS L5. smoother_length must be bigger than 0. It has been set to 1" << TEXT_RESET << std::endl;
}
else
{
trk_param.smoother_length = configuration->property(role + ".smoother_length", 10);
}
float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0);
if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast<float>(FLAGS_pll_bw_hz);
trk_param.pll_bw_hz = pll_bw_hz;

View File

@ -17,13 +17,15 @@
#
if(ENABLE_CUDA)
set(OPT_TRACKING_BLOCKS ${OPT_TRACKING_BLOCKS} gps_l1_ca_dll_pll_tracking_gpu_cc.cc)
set(OPT_TRACKING_BLOCKS_SOURCES ${OPT_TRACKING_BLOCKS_SOURCES} gps_l1_ca_dll_pll_tracking_gpu_cc.cc)
set(OPT_TRACKING_BLOCKS_HEADERS ${OPT_TRACKING_BLOCKS_HEADERS} gps_l1_ca_dll_pll_tracking_gpu_cc.h)
set(OPT_TRACKING_INCLUDES ${OPT_TRACKING_INCLUDES} ${CUDA_INCLUDE_DIRS})
set(OPT_TRACKING_LIBRARIES ${OPT_TRACKING_LIBRARIES} ${CUDA_LIBRARIES})
endif(ENABLE_CUDA)
if(ENABLE_FPGA)
set(OPT_TRACKING_BLOCKS ${OPT_TRACKING_BLOCKS} dll_pll_veml_tracking_fpga.cc)
set(OPT_TRACKING_BLOCKS_SOURCES ${OPT_TRACKING_BLOCKS_SOURCES} dll_pll_veml_tracking_fpga.cc)
set(OPT_TRACKING_BLOCKS_HEADERS ${OPT_TRACKING_BLOCKS_HEADERS} dll_pll_veml_tracking_fpga.h)
endif(ENABLE_FPGA)
set(TRACKING_GR_BLOCKS_SOURCES
@ -39,7 +41,23 @@ set(TRACKING_GR_BLOCKS_SOURCES
glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc
glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc
dll_pll_veml_tracking.cc
${OPT_TRACKING_BLOCKS}
${OPT_TRACKING_BLOCKS_SOURCES}
)
set(TRACKING_GR_BLOCKS_HEADERS
galileo_e1_tcp_connector_tracking_cc.h
gps_l1_ca_tcp_connector_tracking_cc.h
gps_l1_ca_dll_pll_c_aid_tracking_cc.h
gps_l1_ca_dll_pll_c_aid_tracking_sc.h
glonass_l1_ca_dll_pll_tracking_cc.h
glonass_l1_ca_dll_pll_c_aid_tracking_cc.h
glonass_l1_ca_dll_pll_c_aid_tracking_sc.h
gps_l1_ca_kf_tracking_cc.h
glonass_l2_ca_dll_pll_tracking_cc.h
glonass_l2_ca_dll_pll_c_aid_tracking_cc.h
glonass_l2_ca_dll_pll_c_aid_tracking_sc.h
dll_pll_veml_tracking.h
${OPT_TRACKING_BLOCKS_HEADERS}
)
include_directories(
@ -63,8 +81,9 @@ if(ENABLE_GENERIC_ARCH)
add_definitions( -DGENERIC_ARCH=1 )
endif(ENABLE_GENERIC_ARCH)
file(GLOB TRACKING_GR_BLOCKS_HEADERS "*.h")
list(SORT TRACKING_GR_BLOCKS_HEADERS)
list(SORT TRACKING_GR_BLOCKS_SOURCES)
add_library(tracking_gr_blocks ${TRACKING_GR_BLOCKS_SOURCES} ${TRACKING_GR_BLOCKS_HEADERS})
source_group(Headers FILES ${TRACKING_GR_BLOCKS_HEADERS})

View File

@ -58,6 +58,7 @@
#include <cmath>
#include <iostream>
#include <sstream>
#include <numeric>
using google::LogMessage;
@ -355,6 +356,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
{
// Extra correlator for the data component
correlator_data_cpu.init(2 * trk_parameters.vector_length, 1);
correlator_data_cpu.set_high_dynamics_resampler(trk_parameters.high_dyn);
d_data_code = static_cast<float *>(volk_gnsssdr_malloc(2 * d_code_length_chips * sizeof(float), volk_gnsssdr_get_alignment()));
}
else
@ -363,7 +365,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
}
// --- Initializations ---
multicorrelator_cpu.set_high_dynamics_resampler(trk_parameters.use_high_dynamics_resampler);
multicorrelator_cpu.set_high_dynamics_resampler(trk_parameters.high_dyn);
// Initial code frequency basis of NCO
d_code_freq_chips = d_code_chip_rate;
// Residual code phase (in chips)
@ -397,12 +399,22 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
d_code_phase_step_chips = 0.0;
d_code_phase_rate_step_chips = 0.0;
d_carrier_phase_step_rad = 0.0;
d_carrier_phase_rate_step_rad = 0.0;
d_rem_code_phase_chips = 0.0;
d_K_blk_samples = 0.0;
d_code_phase_samples = 0.0;
d_last_prompt = gr_complex(0.0, 0.0);
d_state = 0; // initial state: standby
clear_tracking_vars();
if (trk_parameters.smoother_length > 0)
{
d_carr_ph_history.resize(trk_parameters.smoother_length * 2);
d_code_ph_history.resize(trk_parameters.smoother_length * 2);
}
else
{
d_carr_ph_history.resize(1);
d_code_ph_history.resize(1);
}
}
@ -424,6 +436,7 @@ void dll_pll_veml_tracking::start_tracking()
// new chip and PRN sequence periods based on acq Doppler
d_code_freq_chips = radial_velocity * d_code_chip_rate;
d_code_phase_step_chips = d_code_freq_chips / trk_parameters.fs_in;
d_code_phase_rate_step_chips = 0.0;
double T_chip_mod_seconds = 1.0 / d_code_freq_chips;
double T_prn_mod_seconds = T_chip_mod_seconds * static_cast<double>(d_code_length_chips);
double T_prn_mod_samples = T_prn_mod_seconds * trk_parameters.fs_in;
@ -446,7 +459,9 @@ void dll_pll_veml_tracking::start_tracking()
d_carrier_doppler_hz = d_acq_carrier_doppler_hz;
d_carrier_phase_step_rad = PI_2 * d_carrier_doppler_hz / trk_parameters.fs_in;
d_carrier_phase_rate_step_rad = 0.0;
d_carr_ph_history.clear();
d_code_ph_history.clear();
// DLL/PLL filter initialization
d_carrier_loop_filter.initialize(); // initialize the carrier filter
d_code_loop_filter.initialize(); // initialize the code filter
@ -706,7 +721,7 @@ void dll_pll_veml_tracking::do_correlation_step(const gr_complex *input_samples)
multicorrelator_cpu.set_input_output_vectors(d_correlator_outs, input_samples);
multicorrelator_cpu.Carrier_wipeoff_multicorrelator_resampler(
d_rem_carr_phase_rad,
d_carrier_phase_step_rad,
d_carrier_phase_step_rad, d_carrier_phase_rate_step_rad,
static_cast<float>(d_rem_code_phase_chips) * static_cast<float>(d_code_samples_per_chip),
static_cast<float>(d_code_phase_step_chips) * static_cast<float>(d_code_samples_per_chip),
static_cast<float>(d_code_phase_rate_step_chips) * static_cast<float>(d_code_samples_per_chip),
@ -718,7 +733,7 @@ void dll_pll_veml_tracking::do_correlation_step(const gr_complex *input_samples)
correlator_data_cpu.set_input_output_vectors(d_Prompt_Data, input_samples);
correlator_data_cpu.Carrier_wipeoff_multicorrelator_resampler(
d_rem_carr_phase_rad,
d_carrier_phase_step_rad,
d_carrier_phase_step_rad, d_carrier_phase_rate_step_rad,
static_cast<float>(d_rem_code_phase_chips) * static_cast<float>(d_code_samples_per_chip),
static_cast<float>(d_code_phase_step_chips) * static_cast<float>(d_code_samples_per_chip),
static_cast<float>(d_code_phase_rate_step_chips) * static_cast<float>(d_code_samples_per_chip),
@ -777,6 +792,10 @@ void dll_pll_veml_tracking::clear_tracking_vars()
d_current_symbol = 0;
d_Prompt_buffer_deque.clear();
d_last_prompt = gr_complex(0.0, 0.0);
d_carrier_phase_rate_step_rad = 0.0;
d_code_phase_rate_step_chips = 0.0;
d_carr_ph_history.clear();
d_code_ph_history.clear();
}
@ -796,15 +815,60 @@ void dll_pll_veml_tracking::update_tracking_vars()
//################### PLL COMMANDS #################################################
// carrier phase step (NCO phase increment per sample) [rads/sample]
d_carrier_phase_step_rad = PI_2 * d_carrier_doppler_hz / trk_parameters.fs_in;
// carrier phase rate step (NCO phase increment rate per sample) [rads/sample^2]
if (trk_parameters.high_dyn)
{
d_carr_ph_history.push_back(std::pair<double, double>(d_carrier_phase_step_rad, static_cast<double>(d_current_prn_length_samples)));
if (d_carr_ph_history.full())
{
double tmp_cp1 = 0.0;
double tmp_cp2 = 0.0;
double tmp_samples = 0.0;
for (unsigned int k = 0; k < trk_parameters.smoother_length; k++)
{
tmp_cp1 += d_carr_ph_history.at(k).first;
tmp_cp2 += d_carr_ph_history.at(trk_parameters.smoother_length * 2 - k - 1).first;
tmp_samples += d_carr_ph_history.at(trk_parameters.smoother_length * 2 - k - 1).second;
}
tmp_cp1 /= static_cast<double>(trk_parameters.smoother_length);
tmp_cp2 /= static_cast<double>(trk_parameters.smoother_length);
d_carrier_phase_rate_step_rad = (tmp_cp2 - tmp_cp1) / tmp_samples;
}
}
//std::cout << d_carrier_phase_rate_step_rad * trk_parameters.fs_in * trk_parameters.fs_in / PI_2 << std::endl;
// remnant carrier phase to prevent overflow in the code NCO
d_rem_carr_phase_rad += d_carrier_phase_step_rad * static_cast<double>(d_current_prn_length_samples);
d_rem_carr_phase_rad += static_cast<float>(d_carrier_phase_step_rad * static_cast<double>(d_current_prn_length_samples) + 0.5 * d_carrier_phase_rate_step_rad * static_cast<double>(d_current_prn_length_samples) * static_cast<double>(d_current_prn_length_samples));
d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, PI_2);
// carrier phase accumulator
d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * static_cast<double>(d_current_prn_length_samples);
//double a = d_carrier_phase_step_rad * static_cast<double>(d_current_prn_length_samples);
//double b = 0.5 * d_carrier_phase_rate_step_rad * static_cast<double>(d_current_prn_length_samples) * static_cast<double>(d_current_prn_length_samples);
//std::cout << fmod(b, PI_2) / fmod(a, PI_2) << std::endl;
d_acc_carrier_phase_rad -= (d_carrier_phase_step_rad * static_cast<double>(d_current_prn_length_samples) + 0.5 * d_carrier_phase_rate_step_rad * static_cast<double>(d_current_prn_length_samples) * static_cast<double>(d_current_prn_length_samples));
//################### DLL COMMANDS #################################################
// code phase step (Code resampler phase increment per sample) [chips/sample]
d_code_phase_step_chips = d_code_freq_chips / trk_parameters.fs_in;
if (trk_parameters.high_dyn)
{
d_code_ph_history.push_back(std::pair<double, double>(d_code_phase_step_chips, static_cast<double>(d_current_prn_length_samples)));
if (d_code_ph_history.full())
{
double tmp_cp1 = 0.0;
double tmp_cp2 = 0.0;
double tmp_samples = 0.0;
for (unsigned int k = 0; k < trk_parameters.smoother_length; k++)
{
tmp_cp1 += d_code_ph_history.at(k).first;
tmp_cp2 += d_code_ph_history.at(trk_parameters.smoother_length * 2 - k - 1).first;
tmp_samples += d_code_ph_history.at(trk_parameters.smoother_length * 2 - k - 1).second;
}
tmp_cp1 /= static_cast<double>(trk_parameters.smoother_length);
tmp_cp2 /= static_cast<double>(trk_parameters.smoother_length);
d_code_phase_rate_step_chips = (tmp_cp2 - tmp_cp1) / tmp_samples;
}
}
// remnant code phase [chips]
d_rem_code_phase_samples = K_blk_samples - static_cast<double>(d_current_prn_length_samples); // rounding error < 1 sample
d_rem_code_phase_chips = d_code_freq_chips * d_rem_code_phase_samples / trk_parameters.fs_in;
@ -947,8 +1011,14 @@ void dll_pll_veml_tracking::log_data(bool integrating)
// carrier and code frequency
tmp_float = d_carrier_doppler_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// carrier phase rate [Hz/s]
tmp_float = d_carrier_phase_rate_step_rad * trk_parameters.fs_in * trk_parameters.fs_in / PI_2;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_freq_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// code phase rate [chips/s^2]
tmp_float = d_code_phase_rate_step_chips * trk_parameters.fs_in * trk_parameters.fs_in;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// PLL commands
tmp_float = d_carr_error_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
@ -986,7 +1056,7 @@ int32_t dll_pll_veml_tracking::save_matfile()
// READ DUMP FILE
std::ifstream::pos_type size;
int32_t number_of_double_vars = 1;
int32_t number_of_float_vars = 17;
int32_t number_of_float_vars = 19;
int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars +
sizeof(float) * number_of_float_vars + sizeof(uint32_t);
std::ifstream dump_file;
@ -1022,7 +1092,9 @@ int32_t dll_pll_veml_tracking::save_matfile()
uint64_t *PRN_start_sample_count = new uint64_t[num_epoch];
float *acc_carrier_phase_rad = new float[num_epoch];
float *carrier_doppler_hz = new float[num_epoch];
float *carrier_doppler_rate_hz = new float[num_epoch];
float *code_freq_chips = new float[num_epoch];
float *code_freq_rate_chips = new float[num_epoch];
float *carr_error_hz = new float[num_epoch];
float *carr_error_filt_hz = new float[num_epoch];
float *code_error_chips = new float[num_epoch];
@ -1049,7 +1121,9 @@ int32_t dll_pll_veml_tracking::save_matfile()
dump_file.read(reinterpret_cast<char *>(&PRN_start_sample_count[i]), sizeof(uint64_t));
dump_file.read(reinterpret_cast<char *>(&acc_carrier_phase_rad[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&carrier_doppler_hz[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&carrier_doppler_rate_hz[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&code_freq_chips[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&code_freq_rate_chips[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&carr_error_hz[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&carr_error_filt_hz[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&code_error_chips[i]), sizeof(float));
@ -1076,7 +1150,9 @@ int32_t dll_pll_veml_tracking::save_matfile()
delete[] PRN_start_sample_count;
delete[] acc_carrier_phase_rad;
delete[] carrier_doppler_hz;
delete[] carrier_doppler_rate_hz;
delete[] code_freq_chips;
delete[] code_freq_rate_chips;
delete[] carr_error_hz;
delete[] carr_error_filt_hz;
delete[] code_error_chips;
@ -1139,10 +1215,18 @@ int32_t dll_pll_veml_tracking::save_matfile()
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("carrier_doppler_rate_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carrier_doppler_rate_hz, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("code_freq_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_freq_chips, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("code_freq_rate_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_freq_rate_chips, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("carr_error_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carr_error_hz, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
@ -1190,7 +1274,9 @@ int32_t dll_pll_veml_tracking::save_matfile()
delete[] PRN_start_sample_count;
delete[] acc_carrier_phase_rad;
delete[] carrier_doppler_hz;
delete[] carrier_doppler_rate_hz;
delete[] code_freq_chips;
delete[] code_freq_rate_chips;
delete[] carr_error_hz;
delete[] carr_error_filt_hz;
delete[] code_error_chips;

View File

@ -41,6 +41,7 @@
#include <string>
#include <map>
#include <queue>
#include <utility>
#include <boost/circular_buffer.hpp>
class dll_pll_veml_tracking;
@ -146,10 +147,13 @@ private:
double d_code_phase_step_chips;
double d_code_phase_rate_step_chips;
boost::circular_buffer<std::pair<double, double>> d_code_ph_history;
double d_carrier_phase_step_rad;
double d_carrier_phase_rate_step_rad;
boost::circular_buffer<std::pair<double, double>> d_carr_ph_history;
// remaining code phase and carrier phase between tracking loops
double d_rem_code_phase_samples;
double d_rem_carr_phase_rad;
float d_rem_carr_phase_rad;
// PLL and DLL filter library
Tracking_2nd_DLL_filter d_code_loop_filter;
@ -164,7 +168,6 @@ private:
double d_carr_error_filt_hz;
double d_code_error_chips;
double d_code_error_filt_chips;
double d_K_blk_samples;
double d_code_freq_chips;
double d_carrier_doppler_hz;
double d_acc_carrier_phase_rad;

View File

@ -30,7 +30,6 @@ if(ENABLE_CUDA)
endif(ENABLE_CUDA)
set(TRACKING_LIB_SOURCES
cpu_multicorrelator.cc
cpu_multicorrelator_real_codes.cc
@ -47,8 +46,25 @@ set(TRACKING_LIB_SOURCES
bayesian_estimation.cc
)
set(TRACKING_LIB_HEADERS
cpu_multicorrelator.h
cpu_multicorrelator_real_codes.h
cpu_multicorrelator_16sc.h
lock_detectors.h
tcp_communication.h
tcp_packet_data.h
tracking_2nd_DLL_filter.h
tracking_2nd_PLL_filter.h
tracking_discriminators.h
tracking_FLL_PLL_filter.h
tracking_loop_filter.h
dll_pll_conf.h
bayesian_estimation.h
)
if(ENABLE_FPGA)
SET(TRACKING_LIB_SOURCES ${TRACKING_LIB_SOURCES} fpga_multicorrelator.cc dll_pll_conf_fpga.cc)
set(TRACKING_LIB_SOURCES ${TRACKING_LIB_SOURCES} fpga_multicorrelator.cc dll_pll_conf_fpga.cc)
set(TRACKING_LIB_HEADERS ${TRACKING_LIB_HEADERS} fpga_multicorrelator.h dll_pll_conf_fpga.h)
endif(ENABLE_FPGA)
include_directories(
@ -74,8 +90,9 @@ if (SSE3_AVAILABLE)
endif(SSE3_AVAILABLE)
file(GLOB TRACKING_LIB_HEADERS "*.h")
list(SORT TRACKING_LIB_HEADERS)
list(SORT TRACKING_LIB_SOURCES)
add_library(tracking_lib ${TRACKING_LIB_SOURCES} ${TRACKING_LIB_HEADERS})
source_group(Headers FILES ${TRACKING_LIB_HEADERS})
target_link_libraries(tracking_lib ${OPT_TRACKING_LIBRARIES} ${VOLK_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${Boost_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES})

View File

@ -125,7 +125,32 @@ void cpu_multicorrelator_real_codes::update_local_code(int correlator_length_sam
}
}
// Overload Carrier_wipeoff_multicorrelator_resampler to ensure back compatibility
bool cpu_multicorrelator_real_codes::Carrier_wipeoff_multicorrelator_resampler(
float rem_carrier_phase_in_rad,
float phase_step_rad,
float phase_rate_step_rad,
float rem_code_phase_chips,
float code_phase_step_chips,
float code_phase_rate_step_chips,
int signal_length_samples)
{
update_local_code(signal_length_samples, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips);
// Regenerate phase at each call in order to avoid numerical issues
lv_32fc_t phase_offset_as_complex[1];
phase_offset_as_complex[0] = lv_cmake(std::cos(rem_carrier_phase_in_rad), -std::sin(rem_carrier_phase_in_rad));
// call VOLK_GNSSSDR kernel
if (d_use_high_dynamics_resampler)
{
volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn(d_corr_out, d_sig_in, std::exp(lv_32fc_t(0.0, -phase_step_rad)), std::exp(lv_32fc_t(0.0, -phase_rate_step_rad)), phase_offset_as_complex, const_cast<const float**>(d_local_codes_resampled), d_n_correlators, signal_length_samples);
}
else
{
volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn(d_corr_out, d_sig_in, std::exp(lv_32fc_t(0.0, -phase_step_rad)), phase_offset_as_complex, const_cast<const float**>(d_local_codes_resampled), d_n_correlators, signal_length_samples);
}
return true;
}
// Overload Carrier_wipeoff_multicorrelator_resampler to ensure back compatibility
bool cpu_multicorrelator_real_codes::Carrier_wipeoff_multicorrelator_resampler(
float rem_carrier_phase_in_rad,
float phase_step_rad,

View File

@ -52,6 +52,8 @@ public:
bool set_local_code_and_taps(int code_length_chips, const float *local_code_in, float *shifts_chips);
bool set_input_output_vectors(std::complex<float> *corr_out, const std::complex<float> *sig_in);
void update_local_code(int correlator_length_samples, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips = 0.0);
// Overload Carrier_wipeoff_multicorrelator_resampler to ensure back compatibility
bool Carrier_wipeoff_multicorrelator_resampler(float rem_carrier_phase_in_rad, float phase_step_rad, float phase_rate_step_rad, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, int signal_length_samples);
bool Carrier_wipeoff_multicorrelator_resampler(float rem_carrier_phase_in_rad, float phase_step_rad, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, int signal_length_samples);
bool free();

View File

@ -36,7 +36,8 @@
Dll_Pll_Conf::Dll_Pll_Conf()
{
/* DLL/PLL tracking configuration */
use_high_dynamics_resampler = true;
high_dyn = false;
smoother_length = 10;
fs_in = 0.0;
vector_length = 0U;
dump = false;

View File

@ -56,11 +56,12 @@ public:
float early_late_space_narrow_chips;
float very_early_late_space_narrow_chips;
int32_t extend_correlation_symbols;
bool use_high_dynamics_resampler;
bool high_dyn;
int32_t cn0_samples;
int32_t carrier_lock_det_mav_samples;
int32_t cn0_min;
int32_t max_lock_fail;
uint32_t smoother_length;
double carrier_lock_th;
bool track_pilot;
char system;

View File

@ -23,11 +23,18 @@ if(OPENSSL_FOUND)
endif(OPENSSL_FOUND)
set(CORE_LIBS_SOURCES
ini.cc
INIReader.cc
ini.cc
INIReader.cc
string_converter.cc
gnss_sdr_supl_client.cc
)
set(CORE_LIBS_HEADERS
ini.h
INIReader.h
string_converter.h
gnss_sdr_supl_client.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
@ -40,8 +47,9 @@ include_directories(
${Boost_INCLUDE_DIRS}
)
file(GLOB CORE_LIBS_HEADERS "*.h")
list(SORT CORE_LIBS_HEADERS)
list(SORT CORE_LIBS_SOURCES)
add_library(rx_core_lib ${CORE_LIBS_SOURCES} ${CORE_LIBS_HEADERS})
source_group(Headers FILES ${CORE_LIBS_HEADERS})
target_link_libraries(rx_core_lib supl_library)

View File

@ -370,13 +370,13 @@ void gnss_sdr_supl_client::read_supl_data()
bool gnss_sdr_supl_client::load_ephemeris_xml(const std::string file_name)
{
std::ifstream ifs;
try
{
std::ifstream ifs(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
boost::archive::xml_iarchive xml(ifs);
gps_ephemeris_map.clear();
xml >> boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", this->gps_ephemeris_map);
ifs.close();
LOG(INFO) << "Loaded Ephemeris map data with " << this->gps_ephemeris_map.size() << " satellites";
}
catch (std::exception& e)
@ -392,12 +392,12 @@ bool gnss_sdr_supl_client::save_ephemeris_map_xml(const std::string file_name, s
{
if (eph_map.empty() == false)
{
std::ofstream ofs;
try
{
std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", eph_map);
ofs.close();
LOG(INFO) << "Saved Ephemeris map data";
}
catch (std::exception& e)
@ -405,24 +405,118 @@ bool gnss_sdr_supl_client::save_ephemeris_map_xml(const std::string file_name, s
LOG(WARNING) << e.what();
return false;
}
return true;
}
else
{
LOG(WARNING) << "Failed to save Ephemeris, map is empty";
return false;
}
return true;
}
bool gnss_sdr_supl_client::load_gal_ephemeris_xml(const std::string file_name)
{
std::ifstream ifs;
try
{
ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
boost::archive::xml_iarchive xml(ifs);
gal_ephemeris_map.clear();
xml >> boost::serialization::make_nvp("GNSS-SDR_gal_ephemeris_map", this->gal_ephemeris_map);
LOG(INFO) << "Loaded Ephemeris map data with " << this->gal_ephemeris_map.size() << " satellites";
}
catch (std::exception& e)
{
LOG(WARNING) << e.what() << "File: " << file_name;
return false;
}
return true;
}
bool save_gal_ephemeris_map_xml(const std::string file_name, std::map<int, Galileo_Ephemeris> eph_map)
{
if (eph_map.empty() == false)
{
std::ofstream ofs;
try
{
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_gal_ephemeris_map", eph_map);
LOG(INFO) << "Saved Galileo ephemeris map data";
}
catch (std::exception& e)
{
LOG(WARNING) << e.what();
return false;
}
}
else
{
LOG(WARNING) << "Failed to save Galileo ephemeris, map is empty";
return false;
}
return true;
}
bool gnss_sdr_supl_client::load_cnav_ephemeris_xml(const std::string file_name)
{
std::ifstream ifs;
try
{
ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
boost::archive::xml_iarchive xml(ifs);
gps_cnav_ephemeris_map.clear();
xml >> boost::serialization::make_nvp("GNSS-SDR_cnav_ephemeris_map", this->gps_cnav_ephemeris_map);
LOG(INFO) << "Loaded Ephemeris map data with " << this->gps_cnav_ephemeris_map.size() << " satellites";
}
catch (std::exception& e)
{
LOG(WARNING) << e.what() << "File: " << file_name;
return false;
}
return true;
}
bool save_cnav_ephemeris_map_xml(const std::string file_name, std::map<int, Gps_CNAV_Ephemeris> eph_map)
{
if (eph_map.empty() == false)
{
std::ofstream ofs;
try
{
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_cnav_ephemeris_map", eph_map);
LOG(INFO) << "Saved GPS CNAV ephemeris map data";
}
catch (std::exception& e)
{
LOG(WARNING) << e.what();
return false;
}
}
else
{
LOG(WARNING) << "Failed to save GPS CNAV ephemeris, map is empty";
return false;
}
return true;
}
bool gnss_sdr_supl_client::load_utc_xml(const std::string file_name)
{
std::ifstream ifs;
try
{
std::ifstream ifs(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
boost::archive::xml_iarchive xml(ifs);
xml >> boost::serialization::make_nvp("GNSS-SDR_utc_map", this->gps_utc);
ifs.close();
xml >> boost::serialization::make_nvp("GNSS-SDR_utc_model", this->gps_utc);
LOG(INFO) << "Loaded UTC model data";
}
catch (std::exception& e)
@ -434,41 +528,133 @@ bool gnss_sdr_supl_client::load_utc_xml(const std::string file_name)
}
bool gnss_sdr_supl_client::save_utc_map_xml(const std::string file_name, std::map<int, Gps_Utc_Model> utc_map)
bool gnss_sdr_supl_client::save_utc_xml(const std::string file_name, Gps_Utc_Model& utc)
{
if (utc_map.empty() == false)
if (utc.valid)
{
std::ofstream ofs;
try
{
std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_utc_map", utc_map);
ofs.close();
LOG(INFO) << "Saved UTC Model data";
xml << boost::serialization::make_nvp("GNSS-SDR_utc_model", utc);
LOG(INFO) << "Saved GPS UTC Model data";
}
catch (std::exception& e)
{
LOG(WARNING) << e.what();
return false;
}
return true;
}
else
{
LOG(WARNING) << "Failed to save UTC model, map is empty";
LOG(WARNING) << "Failed to save GPS UTC model, no valid data";
return false;
}
return true;
}
bool gnss_sdr_supl_client::load_cnav_utc_xml(const std::string file_name)
{
std::ifstream ifs;
try
{
ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
boost::archive::xml_iarchive xml(ifs);
xml >> boost::serialization::make_nvp("GNSS-SDR_cnav_utc_model", this->gps_cnav_utc);
LOG(INFO) << "Loaded CNAV UTC model data";
}
catch (std::exception& e)
{
LOG(WARNING) << e.what() << "File: " << file_name;
return false;
}
return true;
}
bool gnss_sdr_supl_client::save_cnav_utc_xml(const std::string file_name, Gps_CNAV_Utc_Model& utc)
{
if (utc.valid)
{
std::ofstream ofs;
try
{
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_cnav_utc_model", utc);
LOG(INFO) << "Saved GPS CNAV UTC model data";
}
catch (std::exception& e)
{
LOG(WARNING) << e.what();
return false;
}
}
else
{
LOG(WARNING) << "Failed to save GPS CNAV UTC model, no valid data";
return false;
}
return true;
}
bool gnss_sdr_supl_client::load_gal_utc_xml(const std::string file_name)
{
std::ifstream ifs;
try
{
ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
boost::archive::xml_iarchive xml(ifs);
xml >> boost::serialization::make_nvp("GNSS-SDR_gal_utc_model", this->gal_utc);
LOG(INFO) << "Loaded Galileo UTC model data";
}
catch (std::exception& e)
{
LOG(WARNING) << e.what() << "File: " << file_name;
return false;
}
return true;
}
bool gnss_sdr_supl_client::save_gal_utc_xml(const std::string file_name, Galileo_Utc_Model& utc)
{
if (utc.flag_utc_model)
{
std::ofstream ofs;
try
{
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_gal_utc_model", utc);
LOG(INFO) << "Saved Galileo UTC Model data";
}
catch (std::exception& e)
{
LOG(WARNING) << e.what();
return false;
}
}
else
{
LOG(WARNING) << "Failed to save Galileo UTC model, no valid data";
return false;
}
return true;
}
bool gnss_sdr_supl_client::load_iono_xml(const std::string file_name)
{
std::ifstream ifs;
try
{
std::ifstream ifs(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
boost::archive::xml_iarchive xml(ifs);
xml >> boost::serialization::make_nvp("GNSS-SDR_iono_map", this->gps_iono);
ifs.close();
xml >> boost::serialization::make_nvp("GNSS-SDR_iono_model", this->gps_iono);
LOG(INFO) << "Loaded IONO model data";
}
catch (std::exception& e)
@ -480,16 +666,16 @@ bool gnss_sdr_supl_client::load_iono_xml(const std::string file_name)
}
bool gnss_sdr_supl_client::save_iono_map_xml(const std::string file_name, std::map<int, Gps_Iono> iono_map)
bool gnss_sdr_supl_client::save_iono_xml(const std::string file_name, Gps_Iono& iono)
{
if (iono_map.empty() == false)
if (iono.valid)
{
std::ofstream ofs;
try
{
std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_iono_map", iono_map);
ofs.close();
xml << boost::serialization::make_nvp("GNSS-SDR_iono_model", iono);
LOG(INFO) << "Saved IONO Model data";
}
catch (std::exception& e)
@ -497,24 +683,70 @@ bool gnss_sdr_supl_client::save_iono_map_xml(const std::string file_name, std::m
LOG(WARNING) << e.what();
return false;
}
return true;
}
else
{
LOG(WARNING) << "Failed to save IONO model, map is empty";
return false;
}
return true;
}
bool gnss_sdr_supl_client::load_gal_iono_xml(const std::string file_name)
{
std::ifstream ifs;
try
{
ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
boost::archive::xml_iarchive xml(ifs);
xml >> boost::serialization::make_nvp("GNSS-SDR_gal_iono_model", this->gal_iono);
LOG(INFO) << "Loaded Galileo IONO model data";
}
catch (std::exception& e)
{
LOG(WARNING) << e.what() << "File: " << file_name;
return false;
}
return true;
}
bool gnss_sdr_supl_client::save_gal_iono_xml(const std::string file_name, Galileo_Iono& iono)
{
if (iono.ai0_5 != 0.0)
{
std::ofstream ofs;
try
{
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_gal_iono_model", iono);
LOG(INFO) << "Saved Galileo IONO Model data";
}
catch (std::exception& e)
{
LOG(WARNING) << e.what();
return false;
}
}
else
{
LOG(WARNING) << "Failed to save Galileo IONO model, map is empty";
return false;
}
return true;
}
bool gnss_sdr_supl_client::load_ref_time_xml(const std::string file_name)
{
std::ifstream ifs;
try
{
std::ifstream ifs(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
boost::archive::xml_iarchive xml(ifs);
xml >> boost::serialization::make_nvp("GNSS-SDR_ref_time_map", this->gps_time);
ifs.close();
LOG(INFO) << "Loaded Ref Time data";
}
catch (std::exception& e)
@ -530,12 +762,13 @@ bool gnss_sdr_supl_client::save_ref_time_map_xml(const std::string file_name, st
{
if (ref_time_map.empty() == false)
{
std::ofstream ofs;
try
{
std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_ref_time_map", ref_time_map);
ofs.close();
LOG(INFO) << "Saved Ref Time data";
}
catch (std::exception& e)
@ -543,24 +776,24 @@ bool gnss_sdr_supl_client::save_ref_time_map_xml(const std::string file_name, st
LOG(WARNING) << e.what();
return false;
}
return true;
}
else
{
LOG(WARNING) << "Failed to save Ref Time, map is empty";
return false;
}
return true;
}
bool gnss_sdr_supl_client::load_ref_location_xml(const std::string file_name)
{
std::ifstream ifs;
try
{
std::ifstream ifs(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
boost::archive::xml_iarchive xml(ifs);
xml >> boost::serialization::make_nvp("GNSS-SDR_ref_location_map", this->gps_ref_loc);
ifs.close();
LOG(INFO) << "Loaded Ref Location data";
}
catch (std::exception& e)
@ -576,12 +809,12 @@ bool gnss_sdr_supl_client::save_ref_location_map_xml(const std::string file_name
{
if (ref_location_map.empty() == false)
{
std::ofstream ofs;
try
{
std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_ref_location_map", ref_location_map);
ofs.close();
LOG(INFO) << "Saved Ref Location data";
}
catch (std::exception& e)
@ -589,11 +822,11 @@ bool gnss_sdr_supl_client::save_ref_location_map_xml(const std::string file_name
LOG(WARNING) << e.what();
return false;
}
return true;
}
else
{
LOG(WARNING) << "Failed to save Ref Location, map is empty";
return false;
}
return true;
}

View File

@ -43,9 +43,14 @@ extern "C"
#include "gps_iono.h"
#include "gps_almanac.h"
#include "gps_utc_model.h"
#include "gps_cnav_utc_model.h"
#include "gps_acq_assist.h"
#include "gps_ref_time.h"
#include "gps_ref_location.h"
#include "gps_cnav_ephemeris.h"
#include "galileo_ephemeris.h"
#include "galileo_utc_model.h"
#include "galileo_iono.h"
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/serialization/map.hpp>
@ -77,15 +82,20 @@ public:
int request;
// ephemeris map
std::map<int, Gps_Ephemeris> gps_ephemeris_map;
std::map<int, Galileo_Ephemeris> gal_ephemeris_map;
std::map<int, Gps_CNAV_Ephemeris> gps_cnav_ephemeris_map;
// almanac map
std::map<int, Gps_Almanac> gps_almanac_map;
// ionospheric model
Gps_Iono gps_iono;
Galileo_Iono gal_iono;
// reference time
Gps_Ref_Time gps_time;
// UTC model
Gps_Utc_Model gps_utc;
Galileo_Utc_Model gal_utc;
Gps_CNAV_Utc_Model gps_cnav_utc;
// reference location
Gps_Ref_Location gps_ref_loc;
// Acquisition Assistance map
@ -107,7 +117,7 @@ public:
void read_supl_data();
/*!
* \brief Read ephemeris map from XML file
* \brief Read GPS NAV ephemeris map from XML file
*/
bool load_ephemeris_xml(const std::string file_name);
@ -118,16 +128,59 @@ public:
std::map<int, Gps_Ephemeris> eph_map);
/*!
* \brief Read utc model from XML file
* \brief Read GPS CNAV ephemeris map from XML file
*/
bool load_cnav_ephemeris_xml(const std::string file_name);
/*!
* \brief Save GPS CNAV ephemeris map to XML file.
*/
bool save_cnav_ephemeris_map_xml(const std::string file_name,
std::map<int, Gps_CNAV_Ephemeris> eph_map);
/*!
* \brief Read Galileo ephemeris map from XML file
*/
bool load_gal_ephemeris_xml(const std::string file_name);
/*!
* \brief Save Galileo ephemeris map to XML file.
*/
bool save_gal_ephemeris_map_xml(const std::string file_name,
std::map<int, Galileo_Ephemeris> eph_map);
/*!
* \brief Read GPS utc model from XML file
*/
bool load_utc_xml(const std::string file_name);
/*!
* \brief Save utc model map to XML file
* \brief Save UTC model map to XML file
* To be called by ControlThread::gps_utc_model_data_write_to_XML()
*/
bool save_utc_map_xml(const std::string file_name,
std::map<int, Gps_Utc_Model> utc_map);
bool save_utc_xml(const std::string file_name, Gps_Utc_Model& utc);
/*!
* \brief Read CNAV GPS utc model from XML file
*/
bool load_cnav_utc_xml(const std::string file_name);
/*!
* \brief Save CNAV UTC model map to XML file
* To be called by ControlThread::gps_utc_model_data_write_to_XML()
*/
bool save_cnav_utc_xml(const std::string file_name, Gps_CNAV_Utc_Model& utc);
/*!
* \brief Read Galileo utc model from XML file
*/
bool load_gal_utc_xml(const std::string file_name);
/*!
* \brief Save Galileo UTC model map to XML file
* To be called by ControlThread::gal_utc_model_data_write_to_XML()
*/
bool save_gal_utc_xml(const std::string file_name, Galileo_Utc_Model& utc);
/*!
* \brief Read iono from XML file
@ -137,8 +190,17 @@ public:
/*!
* \brief Save iono map to XML file
*/
bool save_iono_map_xml(const std::string file_name,
std::map<int, Gps_Iono> iono_map);
bool save_iono_xml(const std::string file_name, Gps_Iono& iono);
/*!
* \brief Read Galileo iono from XML file
*/
bool load_gal_iono_xml(const std::string file_name);
/*!
* \brief Save Galileo iono map to XML file
*/
bool save_gal_iono_xml(const std::string file_name, Galileo_Iono& iono);
/*!
* \brief Read ref time from XML file

View File

@ -21,7 +21,13 @@ set(CORE_MONITOR_LIBS_SOURCES
gnss_synchro_monitor.cc
gnss_synchro_udp_sink.cc
)
set(CORE_MONITOR_LIBS_HEADERS
gnss_synchro_monitor.h
gnss_synchro_udp_sink.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/system_parameters
@ -31,8 +37,9 @@ include_directories(
${Boost_INCLUDE_DIRS}
)
file(GLOB CORE_MONITOR_LIBS_HEADERS "*.h")
list(SORT CORE_MONITOR_LIBS_HEADERS)
list(SORT CORE_MONITOR_LIBS_SOURCES)
add_library(core_monitor_lib ${CORE_MONITOR_LIBS_SOURCES} ${CORE_MONITOR_LIBS_HEADERS})
source_group(Headers FILES ${CORE_MONITOR_LIBS_HEADERS})
target_link_libraries(core_monitor_lib ${Boost_LIBRARIES})

View File

@ -26,6 +26,17 @@ set(GNSS_RECEIVER_SOURCES
in_memory_configuration.cc
)
set(GNSS_RECEIVER_HEADERS
control_thread.h
control_message_factory.h
file_configuration.h
gnss_block_factory.h
gnss_flowgraph.h
in_memory_configuration.h
concurrent_map.h
concurrent_queue.h
control_message.h
)
if(PC_GNURADIO_RUNTIME_VERSION VERSION_GREATER 3.7.3)
add_definitions(-DMODERN_GNURADIO=1)
@ -149,10 +160,21 @@ include_directories(
${VOLK_GNSSSDR_INCLUDE_DIRS}
)
file(GLOB GNSS_RECEIVER_HEADERS "*.h")
list(SORT GNSS_RECEIVER_HEADERS)
file(GLOB GNSS_RECEIVER_INTERFACE_HEADERS "../interfaces/*.h")
list(SORT GNSS_RECEIVER_SOURCES)
set(GNSS_RECEIVER_INTERFACE_HEADERS ../interfaces/acquisition_interface.h
../interfaces/channel_interface.h
../interfaces/configuration_interface.h
../interfaces/gnss_block_interface.h
../interfaces/observables_interface.h
../interfaces/pvt_interface.h
../interfaces/telemetry_decoder_interface.h
../interfaces/tracking_interface.h
)
list(SORT GNSS_RECEIVER_INTERFACE_HEADERS)
add_library(gnss_rx ${GNSS_RECEIVER_SOURCES} ${GNSS_RECEIVER_HEADERS} ${GNSS_RECEIVER_INTERFACE_HEADERS})
source_group(Headers FILES ${GNSS_RECEIVER_HEADERS} ${GNSS_RECEIVER_INTERFACE_HEADERS})

View File

@ -201,10 +201,17 @@ bool ControlThread::read_assistance_from_XML()
std::string eph_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_xml", eph_default_xml_filename);
std::string utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_utc_model.xml", utc_default_xml_filename);
std::string iono_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_iono_xml", iono_default_xml_filename);
std::string gal_iono_xml_filename = configuration_->property("GNSS-SDR.SUPL_gal_iono_xml", gal_iono_default_xml_filename);
std::string ref_time_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ref_time_xml", ref_time_default_xml_filename);
std::string ref_location_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ref_location_xml", ref_location_default_xml_filename);
std::string eph_gal_xml_filename = configuration_->property("GNSS-SDR.SUPL_gal_ephemeris_xml", eph_gal_default_xml_filename);
std::string eph_cnav_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_cnav_ephemeris_xml", eph_cnav_default_xml_filename);
std::string gal_utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_gal_utc_model.xml", gal_utc_default_xml_filename);
std::string cnav_utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_cnav_utc_model.xml", cnav_utc_default_xml_filename);
std::cout << "Trying to read GNSS ephemeris from XML file(s)..."
<< std::endl;
std::cout << "SUPL: Try read GPS ephemeris from XML file " << eph_xml_filename << std::endl;
if (supl_client_ephemeris_.load_ephemeris_xml(eph_xml_filename) == true)
{
std::map<int, Gps_Ephemeris>::const_iterator gps_eph_iter;
@ -212,45 +219,91 @@ bool ControlThread::read_assistance_from_XML()
gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.cend();
gps_eph_iter++)
{
std::cout << "SUPL: Read XML Ephemeris for GPS SV " << gps_eph_iter->first << std::endl;
std::cout << "From XML file: Read NAV ephemeris for satellite " << Gnss_Satellite("GPS", gps_eph_iter->second.i_satellite_PRN) << std::endl;
std::shared_ptr<Gps_Ephemeris> tmp_obj = std::make_shared<Gps_Ephemeris>(gps_eph_iter->second);
flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj));
}
ret = true;
}
else
if (supl_client_ephemeris_.load_gal_ephemeris_xml(eph_gal_xml_filename) == true)
{
std::map<int, Galileo_Ephemeris>::const_iterator gal_eph_iter;
for (gal_eph_iter = supl_client_ephemeris_.gal_ephemeris_map.cbegin();
gal_eph_iter != supl_client_ephemeris_.gal_ephemeris_map.cend();
gal_eph_iter++)
{
std::cout << "From XML file: Read ephemeris for satellite " << Gnss_Satellite("Galileo", gal_eph_iter->second.i_satellite_PRN) << std::endl;
std::shared_ptr<Galileo_Ephemeris> tmp_obj = std::make_shared<Galileo_Ephemeris>(gal_eph_iter->second);
flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj));
}
ret = true;
}
if (supl_client_ephemeris_.load_cnav_ephemeris_xml(eph_cnav_xml_filename) == true)
{
std::map<int, Gps_CNAV_Ephemeris>::const_iterator gps_cnav_eph_iter;
for (gps_cnav_eph_iter = supl_client_ephemeris_.gps_cnav_ephemeris_map.cbegin();
gps_cnav_eph_iter != supl_client_ephemeris_.gps_cnav_ephemeris_map.cend();
gps_cnav_eph_iter++)
{
std::cout << "From XML file: Read CNAV ephemeris for satellite " << Gnss_Satellite("GPS", gps_cnav_eph_iter->second.i_satellite_PRN) << std::endl;
std::shared_ptr<Gps_CNAV_Ephemeris> tmp_obj = std::make_shared<Gps_CNAV_Ephemeris>(gps_cnav_eph_iter->second);
flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj));
}
ret = true;
}
if (supl_client_acquisition_.load_utc_xml(utc_xml_filename) == true)
{
std::shared_ptr<Gps_Utc_Model> tmp_obj = std::make_shared<Gps_Utc_Model>(supl_client_acquisition_.gps_utc);
flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj));
std::cout << "From XML file: Read GPS UTC parameters." << std::endl;
ret = true;
}
if (supl_client_acquisition_.load_iono_xml(iono_xml_filename) == true)
{
std::shared_ptr<Gps_Iono> tmp_obj = std::make_shared<Gps_Iono>(supl_client_acquisition_.gps_iono);
flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj));
std::cout << "From XML file: Read GPS iono parameters." << std::endl;
ret = true;
}
if (supl_client_acquisition_.load_gal_iono_xml(gal_iono_xml_filename) == true)
{
std::shared_ptr<Galileo_Iono> tmp_obj = std::make_shared<Galileo_Iono>(supl_client_acquisition_.gal_iono);
flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj));
std::cout << "From XML file: Read Galileo iono parameters." << std::endl;
ret = true;
}
if (supl_client_acquisition_.load_gal_utc_xml(gal_utc_xml_filename) == true)
{
std::shared_ptr<Galileo_Utc_Model> tmp_obj = std::make_shared<Galileo_Utc_Model>(supl_client_acquisition_.gal_utc);
flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj));
std::cout << "From XML file: Read Galileo UTC parameters." << std::endl;
ret = true;
}
if (supl_client_acquisition_.load_cnav_utc_xml(cnav_utc_xml_filename) == true)
{
std::shared_ptr<Gps_CNAV_Utc_Model> tmp_obj = std::make_shared<Gps_CNAV_Utc_Model>(supl_client_acquisition_.gps_cnav_utc);
flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj));
std::cout << "From XML file: Read GPS CNAV UTC parameters." << std::endl;
ret = true;
}
if (ret == false)
{
std::cout << "ERROR: SUPL client error reading XML" << std::endl;
std::cout << "Disabling SUPL assistance..." << std::endl;
}
// Only look for {utc, iono, ref time, ref location} if SUPL is enabled
// Only look for {ref time, ref location} if SUPL is enabled
bool enable_gps_supl_assistance = configuration_->property("GNSS-SDR.SUPL_gps_enabled", false);
if (enable_gps_supl_assistance == true)
{
// Try to read UTC model from XML
if (supl_client_acquisition_.load_utc_xml(utc_xml_filename) == true)
{
LOG(INFO) << "SUPL: Read XML UTC model";
std::shared_ptr<Gps_Utc_Model> tmp_obj = std::make_shared<Gps_Utc_Model>(supl_client_acquisition_.gps_utc);
flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj));
}
else
{
LOG(INFO) << "SUPL: couldn't read UTC model XML";
}
// Try to read Iono model from XML
if (supl_client_acquisition_.load_iono_xml(iono_xml_filename) == true)
{
LOG(INFO) << "SUPL: Read XML IONO model";
std::shared_ptr<Gps_Iono> tmp_obj = std::make_shared<Gps_Iono>(supl_client_acquisition_.gps_iono);
flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj));
}
else
{
LOG(INFO) << "SUPL: couldn't read IONO model XML";
}
// Try to read Ref Time from XML
if (supl_client_acquisition_.load_ref_time_xml(ref_time_xml_filename) == true)
{
@ -324,7 +377,7 @@ void ControlThread::assist_GNSS()
// read assistance from file
if (read_assistance_from_XML())
{
std::cout << "GPS assistance data loaded from local XML file." << std::endl;
std::cout << "GNSS assistance data loaded from local XML file(s)." << std::endl;
}
}
else

View File

@ -167,6 +167,11 @@ private:
const std::string iono_default_xml_filename = "./gps_iono.xml";
const std::string ref_time_default_xml_filename = "./gps_ref_time.xml";
const std::string ref_location_default_xml_filename = "./gps_ref_location.xml";
const std::string eph_gal_default_xml_filename = "./gal_ephemeris.xml";
const std::string eph_cnav_default_xml_filename = "./gps_cnav_ephemeris.xml";
const std::string gal_iono_default_xml_filename = "./gal_iono.xml";
const std::string gal_utc_default_xml_filename = "./gal_utc_model.xml";
const std::string cnav_utc_default_xml_filename = "./gps_cnav_utc_model.xml";
};
#endif /*GNSS_SDR_CONTROL_THREAD_H_*/

View File

@ -801,8 +801,8 @@ void GNSSFlowgraph::wait()
bool GNSSFlowgraph::send_telemetry_msg(pmt::pmt_t msg)
{
//push ephemeris to PVT telemetry msg in port using a channel out port
// it uses the first channel as a message produces (it is already connected to PVT)
// Push ephemeris to PVT telemetry msg in port using a channel out port
// it uses the first channel as a message producer (it is already connected to PVT)
channels_.at(0)->get_right_block()->message_port_pub(pmt::mp("telemetry"), msg);
return true;
}
@ -816,6 +816,7 @@ bool GNSSFlowgraph::send_telemetry_msg(pmt::pmt_t msg)
*/
void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
{
std::lock_guard<std::mutex> lock(signal_list_mutex);
DLOG(INFO) << "Received " << what << " from " << who << ". Number of applied actions = " << applied_actions_;
unsigned int sat = 0;
try
@ -826,7 +827,6 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
{
LOG(WARNING) << e.what();
}
std::lock_guard<std::mutex> lock(signal_list_mutex);
switch (what)
{
case 0:
@ -1336,8 +1336,8 @@ void GNSSFlowgraph::set_signals_list()
if (configuration_->property("Channels_1G.count", 0) > 0)
{
// Loop to create the list of GLONASS L1 C/A signals
for (available_gnss_prn_iter = available_glonass_prn.begin();
available_gnss_prn_iter != available_glonass_prn.end();
for (available_gnss_prn_iter = available_glonass_prn.cbegin();
available_gnss_prn_iter != available_glonass_prn.cend();
available_gnss_prn_iter++)
{
available_GLO_1G_signals_.push_back(Gnss_Signal(
@ -1349,8 +1349,8 @@ void GNSSFlowgraph::set_signals_list()
if (configuration_->property("Channels_2G.count", 0) > 0)
{
// Loop to create the list of GLONASS L2 C/A signals
for (available_gnss_prn_iter = available_glonass_prn.begin();
available_gnss_prn_iter != available_glonass_prn.end();
for (available_gnss_prn_iter = available_glonass_prn.cbegin();
available_gnss_prn_iter != available_glonass_prn.cend();
available_gnss_prn_iter++)
{
available_GLO_2G_signals_.push_back(Gnss_Signal(
@ -1363,6 +1363,7 @@ void GNSSFlowgraph::set_signals_list()
void GNSSFlowgraph::set_channels_state()
{
std::lock_guard<std::mutex> lock(signal_list_mutex);
max_acq_channels_ = configuration_->property("Channels.in_acquisition", channels_count_);
if (max_acq_channels_ > channels_count_)
{
@ -1382,7 +1383,6 @@ void GNSSFlowgraph::set_channels_state()
}
DLOG(INFO) << "Channel " << i << " in state " << channels_state_[i];
}
std::lock_guard<std::mutex> lock(signal_list_mutex);
acq_channels_count_ = max_acq_channels_;
DLOG(INFO) << acq_channels_count_ << " channels in acquisition state";
}
@ -1599,16 +1599,16 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool
return result;
}
std::vector<std::string> GNSSFlowgraph::split_string(const std::string &s, char delim)
std::vector<std::string> GNSSFlowgraph::split_string(const std::string& s, char delim)
{
std::vector<std::string> v;
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim))
{
*(std::back_inserter(v)++) = item;
}
{
*(std::back_inserter(v)++) = item;
}
return v;
}

View File

@ -45,6 +45,47 @@ set(SYSTEM_PARAMETERS_SOURCES
glonass_gnav_navigation_message.cc
)
set(SYSTEM_PARAMETERS_HEADERS
gnss_satellite.h
gnss_signal.h
gps_navigation_message.h
gps_ephemeris.h
gps_iono.h
gps_almanac.h
gps_utc_model.h
gps_acq_assist.h
gps_ref_time.h
gps_ref_location.h
galileo_utc_model.h
galileo_ephemeris.h
galileo_almanac.h
galileo_iono.h
galileo_navigation_message.h
sbas_ephemeris.h
galileo_fnav_message.h
gps_cnav_ephemeris.h
gps_cnav_navigation_message.h
gps_cnav_iono.h
gps_cnav_utc_model.h
rtcm.h
glonass_gnav_ephemeris.h
glonass_gnav_almanac.h
glonass_gnav_utc_model.h
glonass_gnav_navigation_message.h
display.h
Galileo_E1.h
Galileo_E5a.h
GLONASS_L1_L2_CA.h
gnss_frequencies.h
gnss_obs_codes.h
gnss_synchro.h
GPS_CNAV.h
GPS_L1_CA.h
GPS_L2C.h
GPS_L5.h
MATH_CONSTANTS.h
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
@ -57,8 +98,10 @@ include_directories(
)
link_directories(${Boost_LIBRARY_DIR})
file(GLOB SYSTEM_PARAMETERS_HEADERS "*.h")
list(SORT SYSTEM_PARAMETERS_HEADERS)
list(SORT SYSTEM_PARAMETERS_SOURCES)
add_library(gnss_system_parameters ${SYSTEM_PARAMETERS_SOURCES} ${SYSTEM_PARAMETERS_HEADERS})
source_group(Headers FILES ${SYSTEM_PARAMETERS_HEADERS})
add_dependencies(gnss_system_parameters rtklib_lib glog-${glog_RELEASE})

View File

@ -32,6 +32,7 @@
#ifndef GNSS_SDR_GALILEO_IONO_H_
#define GNSS_SDR_GALILEO_IONO_H_
#include <boost/serialization/nvp.hpp>
/*!
* \brief This class is a storage for the GALILEO IONOSPHERIC data as described in Galileo ICD paragraph 5.1.6
@ -61,6 +62,30 @@ public:
* Default constructor
*/
Galileo_Iono();
template <class Archive>
/*!
* \brief Serialize is a boost standard method to be called by the boost XML serialization.
Here is used to save the iono data on disk file.
*/
inline void serialize(Archive& archive, const unsigned int version)
{
using boost::serialization::make_nvp;
if (version)
{
};
archive& make_nvp("ai0_5", ai0_5);
archive& make_nvp("ai1_5", ai1_5);
archive& make_nvp("ai2_5", ai2_5);
archive& make_nvp("Region1_flag_5", Region1_flag_5);
archive& make_nvp("Region2_flag_5", Region2_flag_5);
archive& make_nvp("Region3_flag_5", Region3_flag_5);
archive& make_nvp("Region4_flag_5", Region4_flag_5);
archive& make_nvp("Region5_flag_5", Region5_flag_5);
archive& make_nvp("TOW_5", TOW_5);
archive& make_nvp("WN_5", WN_5);
}
};
#endif

View File

@ -33,6 +33,7 @@
#ifndef GNSS_SDR_GALILEO_UTC_MODEL_H_
#define GNSS_SDR_GALILEO_UTC_MODEL_H_
#include <boost/serialization/nvp.hpp>
/*!
* \brief This class is a storage for the GALILEO UTC MODEL data as described in Galileo ICD
@ -58,6 +59,29 @@ public:
* Default constructor
*/
Galileo_Utc_Model();
template <class Archive>
/*!
* \brief Serialize is a boost standard method to be called by the boost XML serialization.
Here is used to save the UTC data on disk file.
*/
inline void serialize(Archive& archive, const unsigned int version)
{
using boost::serialization::make_nvp;
if (version)
{
};
archive& make_nvp("A0_6", A0_6);
archive& make_nvp("A1_6", A1_6);
archive& make_nvp("Delta_tLS_6", Delta_tLS_6);
archive& make_nvp("t0t_6", t0t_6);
archive& make_nvp("WNot_6", WNot_6);
archive& make_nvp("WN_LSF_6", WN_LSF_6);
archive& make_nvp("DN_6", DN_6);
archive& make_nvp("Delta_tLSF_6", Delta_tLSF_6);
archive& make_nvp("flag_utc_model", flag_utc_model);
}
};
#endif

View File

@ -33,6 +33,7 @@
#ifndef GNSS_SDR_GNSS_SYNCHRO_H_
#define GNSS_SDR_GNSS_SYNCHRO_H_
#include <boost/serialization/nvp.hpp>
#include "gnss_signal.h"
#include <cstdint>
@ -83,41 +84,42 @@ public:
* Gnss_Synchro objects from a byte stream.
*/
template <class Archive>
void serialize(Archive& ar, const unsigned int version)
{
if (version)
{
};
// Satellite and signal info
ar& System;
ar& Signal;
ar& PRN;
ar& Channel_ID;
ar& BOOST_SERIALIZATION_NVP(System);
ar& BOOST_SERIALIZATION_NVP(Signal);
ar& BOOST_SERIALIZATION_NVP(PRN);
ar& BOOST_SERIALIZATION_NVP(Channel_ID);
// Acquisition
ar& Acq_delay_samples;
ar& Acq_doppler_hz;
ar& Acq_samplestamp_samples;
ar& Acq_doppler_step;
ar& Flag_valid_acquisition;
ar& BOOST_SERIALIZATION_NVP(Acq_delay_samples);
ar& BOOST_SERIALIZATION_NVP(Acq_doppler_hz);
ar& BOOST_SERIALIZATION_NVP(Acq_samplestamp_samples);
ar& BOOST_SERIALIZATION_NVP(Acq_doppler_step);
ar& BOOST_SERIALIZATION_NVP(Flag_valid_acquisition);
// Tracking
ar& fs;
ar& Prompt_I;
ar& Prompt_Q;
ar& CN0_dB_hz;
ar& Carrier_Doppler_hz;
ar& Carrier_phase_rads;
ar& Code_phase_samples;
ar& Tracking_sample_counter;
ar& Flag_valid_symbol_output;
ar& correlation_length_ms;
ar& BOOST_SERIALIZATION_NVP(fs);
ar& BOOST_SERIALIZATION_NVP(Prompt_I);
ar& BOOST_SERIALIZATION_NVP(Prompt_Q);
ar& BOOST_SERIALIZATION_NVP(CN0_dB_hz);
ar& BOOST_SERIALIZATION_NVP(Carrier_Doppler_hz);
ar& BOOST_SERIALIZATION_NVP(Carrier_phase_rads);
ar& BOOST_SERIALIZATION_NVP(Code_phase_samples);
ar& BOOST_SERIALIZATION_NVP(Tracking_sample_counter);
ar& BOOST_SERIALIZATION_NVP(Flag_valid_symbol_output);
ar& BOOST_SERIALIZATION_NVP(correlation_length_ms);
// Telemetry Decoder
ar& Flag_valid_word;
ar& TOW_at_current_symbol_ms;
ar& BOOST_SERIALIZATION_NVP(Flag_valid_word);
ar& BOOST_SERIALIZATION_NVP(TOW_at_current_symbol_ms);
// Observables
ar& Pseudorange_m;
ar& RX_time;
ar& Flag_valid_pseudorange;
ar& interp_TOW_ms;
ar& BOOST_SERIALIZATION_NVP(Pseudorange_m);
ar& BOOST_SERIALIZATION_NVP(RX_time);
ar& BOOST_SERIALIZATION_NVP(Flag_valid_pseudorange);
ar& BOOST_SERIALIZATION_NVP(interp_TOW_ms);
}
};

View File

@ -391,5 +391,6 @@ bool Gps_CNAV_Navigation_Message::have_new_utc_model() // Check if we have a ne
Gps_CNAV_Utc_Model Gps_CNAV_Navigation_Message::get_utc_model()
{
utc_model_record.valid = true;
return utc_model_record;
}

View File

@ -153,7 +153,7 @@ public:
archive& make_nvp("d_Cus", d_Cus); //!< Amplitude of the Sine Harmonic Correction Term to the Argument of Latitude [rad]
archive& make_nvp("d_sqrt_A", d_sqrt_A); //!< Square Root of the Semi-Major Axis [sqrt(m)]
archive& make_nvp("d_Toe", d_Toe); //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s]
archive& make_nvp("d_Toc", d_Toe); //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s]
archive& make_nvp("d_Toc", d_Toc); //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s]
archive& make_nvp("d_Cic", d_Cic); //!< Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination [rad]
archive& make_nvp("d_OMEGA0", d_OMEGA0); //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles]
archive& make_nvp("d_Cis", d_Cis); //!< Amplitude of the Sine Harmonic Correction Term to the Angle of Inclination [rad]

View File

@ -179,6 +179,7 @@ endif(ENABLE_UNIT_TESTING_MINIMAL)
################################################################################
# Optional generator
################################################################################
option(ENABLE_GNSS_SIM_INSTALL "Enable the installation of gnss_sim on the fly" ON)
if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA)
if(ENABLE_FPGA)
set(CROSS_INSTALL_DIR "-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}")
@ -188,31 +189,38 @@ if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA)
else(ENABLE_FPGA)
set(CROSS_INSTALL_DIR "")
endif(ENABLE_FPGA)
ExternalProject_Add(
gnss-sim
GIT_REPOSITORY https://bitbucket.org/jarribas/gnss-simulator
GIT_TAG ${GNSSSDR_GNSS_SIM_LOCAL_VERSION}
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gnss-sim
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/../../gnss-sim
CMAKE_ARGS ${GTEST_COMPILER} ${TOOLCHAIN_ARG} ${CROSS_INSTALL_DIR}
UPDATE_COMMAND ""
PATCH_COMMAND ""
INSTALL_COMMAND ""
)
if(ENABLE_INSTALL_TESTS)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/../../gnss-sim/gnss_sim DESTINATION bin)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/brdc3540.14n DESTINATION share/gnss-sim)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/circle.csv DESTINATION share/gnss-sim)
set(SW_GENERATOR_BIN ${CMAKE_INSTALL_PREFIX}/bin/gnss_sim)
find_package(GnssSimulator QUIET)
if(GNSS-SIMULATOR_FOUND OR NOT ENABLE_GNSS_SIM_INSTALL)
add_definitions(-DSW_GENERATOR_BIN="${SW_GENERATOR_BIN}")
add_definitions(-DDEFAULT_RINEX_NAV="${CMAKE_INSTALL_PREFIX}/share/gnss-sim/brdc3540.14n")
add_definitions(-DDEFAULT_POSITION_FILE="${CMAKE_INSTALL_PREFIX}/share/gnss-sim/circle.csv")
else(ENABLE_INSTALL_TESTS)
set(SW_GENERATOR_BIN ${CMAKE_CURRENT_BINARY_DIR}/../../gnss-sim/gnss_sim)
add_definitions(-DSW_GENERATOR_BIN="${SW_GENERATOR_BIN}")
add_definitions(-DDEFAULT_RINEX_NAV="${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/brdc3540.14n")
add_definitions(-DDEFAULT_POSITION_FILE="${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/circle.csv")
endif(ENABLE_INSTALL_TESTS)
else(GNSS-SIMULATOR_FOUND OR NOT ENABLE_GNSS_SIM_INSTALL)
ExternalProject_Add(
gnss-sim
GIT_REPOSITORY https://bitbucket.org/jarribas/gnss-simulator
GIT_TAG ${GNSSSDR_GNSS_SIM_LOCAL_VERSION}
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gnss-sim
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/../../gnss-sim
CMAKE_ARGS ${GTEST_COMPILER} ${TOOLCHAIN_ARG} ${CROSS_INSTALL_DIR}
UPDATE_COMMAND ""
PATCH_COMMAND ""
INSTALL_COMMAND ""
)
if(ENABLE_INSTALL_TESTS)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/../../gnss-sim/gnss_sim DESTINATION bin)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/brdc3540.14n DESTINATION share/gnss-sim)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/circle.csv DESTINATION share/gnss-sim)
set(SW_GENERATOR_BIN ${CMAKE_INSTALL_PREFIX}/bin/gnss_sim)
add_definitions(-DSW_GENERATOR_BIN="${SW_GENERATOR_BIN}")
add_definitions(-DDEFAULT_RINEX_NAV="${CMAKE_INSTALL_PREFIX}/share/gnss-sim/brdc3540.14n")
add_definitions(-DDEFAULT_POSITION_FILE="${CMAKE_INSTALL_PREFIX}/share/gnss-sim/circle.csv")
else(ENABLE_INSTALL_TESTS)
set(SW_GENERATOR_BIN ${CMAKE_CURRENT_BINARY_DIR}/../../gnss-sim/gnss_sim)
add_definitions(-DSW_GENERATOR_BIN="${SW_GENERATOR_BIN}")
add_definitions(-DDEFAULT_RINEX_NAV="${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/brdc3540.14n")
add_definitions(-DDEFAULT_POSITION_FILE="${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/circle.csv")
endif(ENABLE_INSTALL_TESTS)
endif(GNSS-SIMULATOR_FOUND OR NOT ENABLE_GNSS_SIM_INSTALL)
################################################################################
# Local installation of GPSTk http://www.gpstk.org/
@ -220,7 +228,10 @@ if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA)
find_package(GPSTK)
if(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK)
message(STATUS "GPSTk v${GNSSSDR_GPSTK_LOCAL_VERSION} will be automatically downloaded and built when doing 'make'.")
if ("${TOOLCHAIN_ARG}" STREQUAL "")
set(TOOLCHAIN_ARG "-DCMAKE_CXX_FLAGS=\"-Wno-deprecated\"")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated")
endif("${TOOLCHAIN_ARG}" STREQUAL "")
# if(NOT ENABLE_FPGA)
if(CMAKE_VERSION VERSION_LESS 3.2)
ExternalProject_Add(
@ -305,12 +316,16 @@ if(ENABLE_INSTALL_TESTS)
install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/Galileo_E1_ID_1_Fs_4Msps_8ms.dat DESTINATION share/gnss-sdr/signal_samples)
install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat DESTINATION share/gnss-sdr/signal_samples)
install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin DESTINATION share/gnss-sdr/signal_samples)
install(FILES ${CMAKE_SOURCE_DIR}/src/tests/data/rtklib_test/obs_test1.xml DESTINATION share/gnss-sdr/data/rtklib_test)
install(FILES ${CMAKE_SOURCE_DIR}/src/tests/data/rtklib_test/eph_GPS_L1CA_test1.xml DESTINATION share/gnss-sdr/data/rtklib_test)
add_definitions(-DTEST_PATH="${CMAKE_INSTALL_PREFIX}/share/gnss-sdr/")
else(ENABLE_INSTALL_TESTS)
file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GSoC_CTTC_capture_2012_07_26_4Msps_4ms.dat DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples)
file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/Galileo_E1_ID_1_Fs_4Msps_8ms.dat DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples)
file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples)
file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples)
file(COPY ${CMAKE_SOURCE_DIR}/src/tests/data/rtklib_test/obs_test1.xml DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/data/rtklib_test)
file(COPY ${CMAKE_SOURCE_DIR}/src/tests/data/rtklib_test/eph_GPS_L1CA_test1.xml DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/data/rtklib_test)
add_definitions(-DTEST_PATH="${CMAKE_SOURCE_DIR}/thirdparty/")
endif(ENABLE_INSTALL_TESTS)
@ -391,6 +406,7 @@ if(ENABLE_UNIT_TESTING)
signal_generator_adapters
pvt_gr_blocks
signal_processing_testing_lib
system_testing_lib
${VOLK_GNSSSDR_LIBRARIES}
${MATIO_LIBRARIES}
${GNSS_SDR_TEST_OPTIONAL_LIBS}
@ -499,7 +515,7 @@ if(ENABLE_SYSTEM_TESTING)
${GTEST_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES}
${GNURADIO_BLOCKS_LIBRARIES} ${GNURADIO_FILTER_LIBRARIES}
${GNURADIO_ANALOG_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES}
gnss_sp_libs gnss_rx gnss_system_parameters
gnss_sp_libs gnss_rx gnss_system_parameters
system_testing_lib)
add_system_test(position_test)

View File

@ -37,5 +37,6 @@
DEFINE_double(skip_obs_transitory_s, 30.0, "Skip the initial observable outputs to avoid transitory results [s]");
DEFINE_bool(compute_single_diffs, false, "Compute also the single difference errors for Accumulated Carrier Phase and Carrier Doppler (requires LO synchronization between receivers)");
DEFINE_bool(compare_with_5X, false, "Compare the E5a Doppler and Carrier Phases with the E5 full bw in RINEX (expect discrepancy due to the center frequencies differences");
DEFINE_bool(duplicated_satellites_test, false, "Enable special observable test mode where the scenario contains duplicated satellite orbits");
DEFINE_string(duplicated_satellites_prns, "1,2,3,4", "List of duplicated satellites PRN pairs (i.e. 1,2,3,4 indicates that the PRNs 1,2 share the same orbit. The same applies for PRNs 3,4)");
#endif

View File

@ -41,7 +41,7 @@ DEFINE_bool(enable_external_signal_file, false, "Use an external signal file cap
DEFINE_double(external_signal_acquisition_threshold, 2.5, "Threshold for satellite acquisition when external file is used");
DEFINE_int32(external_signal_acquisition_dwells, 5, "Maximum dwells count for satellite acquisition when external file is used");
DEFINE_double(external_signal_acquisition_doppler_max_hz, 5000.0, "Doppler max for satellite acquisition when external file is used");
DEFINE_double(external_signal_acquisition_doppler_step_hz, 125, "Doppler step for satellite acquisition when external file is used");
DEFINE_double(external_signal_acquisition_doppler_step_hz, 125.0, "Doppler step for satellite acquisition when external file is used");
DEFINE_string(signal_file, std::string("signal_out.bin"), "Path of the external signal capture file");
DEFINE_double(CN0_dBHz_start, std::numeric_limits<double>::infinity(), "Enable noise generator and set the CN0 start sweep value [dB-Hz]");
@ -77,6 +77,8 @@ DEFINE_double(skip_trk_transitory_s, 1.0, "Skip the initial tracking output sign
//Tracking configuration
DEFINE_int32(extend_correlation_symbols, 1, "Set the tracking coherent correlation to N symbols (up to 20 for GPS L1 C/A)");
DEFINE_int32(smoother_length, 10, "Set the moving average size for the carrier phase and code phase in case of high dynamics");
DEFINE_bool(high_dyn, false, "Activates the code resampler and NCO generator for high dynamics");
//Test output configuration
DEFINE_bool(plot_gps_l1_tracking_test, false, "Plots results of GpsL1CADllPllTrackingTest with gnuplot");

View File

@ -0,0 +1,481 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="12">
<GNSS-SDR_ephemeris_map class_id="0" tracking_level="0" version="0">
<count>11</count>
<item_version>0</item_version>
<item class_id="1" tracking_level="0" version="0">
<first>1</first>
<second class_id="2" tracking_level="0" version="0">
<i_satellite_PRN>1</i_satellite_PRN>
<d_TOW>5.18448000000000000e+05</d_TOW>
<d_IODE_SF2>9.20000000000000000e+01</d_IODE_SF2>
<d_IODE_SF3>9.20000000000000000e+01</d_IODE_SF3>
<d_Crs>1.83125000000000000e+01</d_Crs>
<d_Delta_n>4.86413118201646669e-09</d_Delta_n>
<d_M_0>2.06468198930943725e+00</d_M_0>
<d_Cuc>9.42498445510864258e-07</d_Cuc>
<d_e_eccentricity>3.73082922305911736e-03</d_e_eccentricity>
<d_Cus>5.76488673686981201e-06</d_Cus>
<d_sqrt_A>5.15366174697875977e+03</d_sqrt_A>
<d_Toe>5.18400000000000000e+05</d_Toe>
<d_Toc>5.18400000000000000e+05</d_Toc>
<d_Cic>-5.40167093276977539e-08</d_Cic>
<d_OMEGA0>9.52167247599200905e-01</d_OMEGA0>
<d_Cis>1.86264514923095703e-08</d_Cis>
<d_i_0>9.61377026423456127e-01</d_i_0>
<d_Crc>2.66968750000000000e+02</d_Crc>
<d_OMEGA>4.44935333708291858e-01</d_OMEGA>
<d_OMEGA_DOT>-8.14641075927847669e-09</d_OMEGA_DOT>
<d_IDOT>4.15017287135849497e-10</d_IDOT>
<i_code_on_L2>0</i_code_on_L2>
<i_GPS_week>799</i_GPS_week>
<b_L2_P_data_flag>0</b_L2_P_data_flag>
<i_SV_accuracy>2</i_SV_accuracy>
<i_SV_health>0</i_SV_health>
<d_TGD>5.12227416038513184e-09</d_TGD>
<d_IODC>9.20000000000000000e+01</d_IODC>
<i_AODO>27900</i_AODO>
<b_fit_interval_flag>0</b_fit_interval_flag>
<d_spare1>0.00000000000000000e+00</d_spare1>
<d_spare2>0.00000000000000000e+00</d_spare2>
<d_A_f0>-1.09937973320484161e-05</d_A_f0>
<d_A_f1>3.41060513164847988e-13</d_A_f1>
<d_A_f2>0.00000000000000000e+00</d_A_f2>
<b_integrity_status_flag>0</b_integrity_status_flag>
<b_alert_flag>0</b_alert_flag>
<b_antispoofing_flag>0</b_antispoofing_flag>
</second>
</item>
<item>
<first>2</first>
<second>
<i_satellite_PRN>2</i_satellite_PRN>
<d_TOW>5.18448000000000000e+05</d_TOW>
<d_IODE_SF2>5.50000000000000000e+01</d_IODE_SF2>
<d_IODE_SF3>5.50000000000000000e+01</d_IODE_SF3>
<d_Crs>2.22812500000000000e+01</d_Crs>
<d_Delta_n>5.12771358985317661e-09</d_Delta_n>
<d_M_0>2.75926302782053146e+00</d_M_0>
<d_Cuc>1.10082328319549561e-06</d_Cuc>
<d_e_eccentricity>1.40569622162729484e-02</d_e_eccentricity>
<d_Cus>6.26407563686370850e-06</d_Cus>
<d_sqrt_A>5.15372654151916504e+03</d_sqrt_A>
<d_Toe>5.18400000000000000e+05</d_Toe>
<d_Toc>5.18400000000000000e+05</d_Toc>
<d_Cic>-1.86264514923095703e-08</d_Cic>
<d_OMEGA0>9.18037446344556307e-01</d_OMEGA0>
<d_Cis>-2.16066837310791016e-07</d_Cis>
<d_i_0>9.39991586696909520e-01</d_i_0>
<d_Crc>2.45468750000000000e+02</d_Crc>
<d_OMEGA>-2.35598690357981555e+00</d_OMEGA>
<d_OMEGA_DOT>-8.07140763509730069e-09</d_OMEGA_DOT>
<d_IDOT>5.25736184736635464e-10</d_IDOT>
<i_code_on_L2>0</i_code_on_L2>
<i_GPS_week>799</i_GPS_week>
<b_L2_P_data_flag>0</b_L2_P_data_flag>
<i_SV_accuracy>2</i_SV_accuracy>
<i_SV_health>0</i_SV_health>
<d_TGD>-2.00234353542327881e-08</d_TGD>
<d_IODC>5.50000000000000000e+01</d_IODC>
<i_AODO>27900</i_AODO>
<b_fit_interval_flag>0</b_fit_interval_flag>
<d_spare1>0.00000000000000000e+00</d_spare1>
<d_spare2>0.00000000000000000e+00</d_spare2>
<d_A_f0>5.36850653588771820e-04</d_A_f0>
<d_A_f1>2.16004991671070416e-12</d_A_f1>
<d_A_f2>0.00000000000000000e+00</d_A_f2>
<b_integrity_status_flag>0</b_integrity_status_flag>
<b_alert_flag>0</b_alert_flag>
<b_antispoofing_flag>0</b_antispoofing_flag>
</second>
</item>
<item>
<first>3</first>
<second>
<i_satellite_PRN>3</i_satellite_PRN>
<d_TOW>5.18448000000000000e+05</d_TOW>
<d_IODE_SF2>7.00000000000000000e+01</d_IODE_SF2>
<d_IODE_SF3>7.00000000000000000e+01</d_IODE_SF3>
<d_Crs>-2.04375000000000000e+01</d_Crs>
<d_Delta_n>4.75769817722603366e-09</d_Delta_n>
<d_M_0>-1.78871492992227910e+00</d_M_0>
<d_Cuc>-1.30012631416320801e-06</d_Cuc>
<d_e_eccentricity>9.70319728367030512e-04</d_e_eccentricity>
<d_Cus>8.26455652713775635e-06</d_Cus>
<d_sqrt_A>5.15378153991699219e+03</d_sqrt_A>
<d_Toe>5.18400000000000000e+05</d_Toe>
<d_Toc>5.18400000000000000e+05</d_Toc>
<d_Cic>7.82310962677001953e-08</d_Cic>
<d_OMEGA0>1.99297660614955263e+00</d_OMEGA0>
<d_Cis>-1.11758708953857422e-08</d_Cis>
<d_i_0>9.59058451948379909e-01</d_i_0>
<d_Crc>2.19593750000000000e+02</d_Crc>
<d_OMEGA>-3.00536842405812843e+00</d_OMEGA>
<d_OMEGA_DOT>-8.02712007605698577e-09</d_OMEGA_DOT>
<d_IDOT>-5.17164399115929480e-10</d_IDOT>
<i_code_on_L2>0</i_code_on_L2>
<i_GPS_week>799</i_GPS_week>
<b_L2_P_data_flag>0</b_L2_P_data_flag>
<i_SV_accuracy>2</i_SV_accuracy>
<i_SV_health>0</i_SV_health>
<d_TGD>5.12227416038513184e-09</d_TGD>
<d_IODC>7.00000000000000000e+01</d_IODC>
<i_AODO>27900</i_AODO>
<b_fit_interval_flag>0</b_fit_interval_flag>
<d_spare1>0.00000000000000000e+00</d_spare1>
<d_spare2>0.00000000000000000e+00</d_spare2>
<d_A_f0>8.80691222846508026e-05</d_A_f0>
<d_A_f1>2.89901436190120811e-11</d_A_f1>
<d_A_f2>0.00000000000000000e+00</d_A_f2>
<b_integrity_status_flag>0</b_integrity_status_flag>
<b_alert_flag>0</b_alert_flag>
<b_antispoofing_flag>0</b_antispoofing_flag>
</second>
</item>
<item>
<first>6</first>
<second>
<i_satellite_PRN>6</i_satellite_PRN>
<d_TOW>5.18448000000000000e+05</d_TOW>
<d_IODE_SF2>2.30000000000000000e+01</d_IODE_SF2>
<d_IODE_SF3>2.30000000000000000e+01</d_IODE_SF3>
<d_Crs>1.63750000000000000e+01</d_Crs>
<d_Delta_n>4.76305554323897445e-09</d_Delta_n>
<d_M_0>-1.28531071631616522e+00</d_M_0>
<d_Cuc>9.12696123123168945e-07</d_Cuc>
<d_e_eccentricity>5.50022465176880251e-04</d_e_eccentricity>
<d_Cus>6.24358654022216797e-06</d_Cus>
<d_sqrt_A>5.15365166282653809e+03</d_sqrt_A>
<d_Toe>5.18400000000000000e+05</d_Toe>
<d_Toc>5.18400000000000000e+05</d_Toc>
<d_Cic>-1.30385160446166992e-08</d_Cic>
<d_OMEGA0>9.43624288779246867e-01</d_OMEGA0>
<d_Cis>-1.86264514923095703e-09</d_Cis>
<d_i_0>9.61292940818096020e-01</d_i_0>
<d_Crc>2.58406250000000000e+02</d_Crc>
<d_OMEGA>2.29191014519991665e+00</d_OMEGA>
<d_OMEGA_DOT>-8.08069373618639861e-09</d_OMEGA_DOT>
<d_IDOT>4.79305679291144535e-10</d_IDOT>
<i_code_on_L2>0</i_code_on_L2>
<i_GPS_week>799</i_GPS_week>
<b_L2_P_data_flag>0</b_L2_P_data_flag>
<i_SV_accuracy>2</i_SV_accuracy>
<i_SV_health>0</i_SV_health>
<d_TGD>4.65661287307739258e-09</d_TGD>
<d_IODC>2.30000000000000000e+01</d_IODC>
<i_AODO>27900</i_AODO>
<b_fit_interval_flag>0</b_fit_interval_flag>
<d_spare1>0.00000000000000000e+00</d_spare1>
<d_spare2>0.00000000000000000e+00</d_spare2>
<d_A_f0>3.07881273329257965e-05</d_A_f0>
<d_A_f1>8.18545231595635253e-12</d_A_f1>
<d_A_f2>0.00000000000000000e+00</d_A_f2>
<b_integrity_status_flag>0</b_integrity_status_flag>
<b_alert_flag>0</b_alert_flag>
<b_antispoofing_flag>0</b_antispoofing_flag>
</second>
</item>
<item>
<first>9</first>
<second>
<i_satellite_PRN>9</i_satellite_PRN>
<d_TOW>5.18448000000000000e+05</d_TOW>
<d_IODE_SF2>4.70000000000000000e+01</d_IODE_SF2>
<d_IODE_SF3>4.70000000000000000e+01</d_IODE_SF3>
<d_Crs>1.12906250000000000e+02</d_Crs>
<d_Delta_n>4.37911097897818463e-09</d_Delta_n>
<d_M_0>-2.75253879947800195e+00</d_M_0>
<d_Cuc>5.85243105888366699e-06</d_Cuc>
<d_e_eccentricity>2.16206186451017829e-04</d_e_eccentricity>
<d_Cus>1.16303563117980957e-05</d_Cus>
<d_sqrt_A>5.15369471168518066e+03</d_sqrt_A>
<d_Toe>5.18400000000000000e+05</d_Toe>
<d_Toc>5.18400000000000000e+05</d_Toc>
<d_Cic>1.67638063430786133e-08</d_Cic>
<d_OMEGA0>3.03742251571970812e+00</d_OMEGA0>
<d_Cis>-1.11758708953857422e-08</d_Cis>
<d_i_0>9.59160503650671514e-01</d_i_0>
<d_Crc>1.56125000000000000e+02</d_Crc>
<d_OMEGA>2.60662251530764344e+00</d_OMEGA>
<d_OMEGA_DOT>-7.85854162551643464e-09</d_OMEGA_DOT>
<d_IDOT>-3.46443002170201364e-11</d_IDOT>
<i_code_on_L2>0</i_code_on_L2>
<i_GPS_week>799</i_GPS_week>
<b_L2_P_data_flag>0</b_L2_P_data_flag>
<i_SV_accuracy>2</i_SV_accuracy>
<i_SV_health>0</i_SV_health>
<d_TGD>4.65661287307739258e-10</d_TGD>
<d_IODC>4.70000000000000000e+01</d_IODC>
<i_AODO>27900</i_AODO>
<b_fit_interval_flag>0</b_fit_interval_flag>
<d_spare1>0.00000000000000000e+00</d_spare1>
<d_spare2>0.00000000000000000e+00</d_spare2>
<d_A_f0>-3.18535603582859039e-05</d_A_f0>
<d_A_f1>-9.66338120633736091e-12</d_A_f1>
<d_A_f2>0.00000000000000000e+00</d_A_f2>
<b_integrity_status_flag>0</b_integrity_status_flag>
<b_alert_flag>0</b_alert_flag>
<b_antispoofing_flag>0</b_antispoofing_flag>
</second>
</item>
<item>
<first>10</first>
<second>
<i_satellite_PRN>10</i_satellite_PRN>
<d_TOW>5.18448000000000000e+05</d_TOW>
<d_IODE_SF2>5.80000000000000000e+01</d_IODE_SF2>
<d_IODE_SF3>5.80000000000000000e+01</d_IODE_SF3>
<d_Crs>-2.72500000000000000e+01</d_Crs>
<d_Delta_n>5.27093384126580581e-09</d_Delta_n>
<d_M_0>-8.86982818851813737e-01</d_M_0>
<d_Cuc>-1.17719173431396484e-06</d_Cuc>
<d_e_eccentricity>1.44534236751496774e-02</d_e_eccentricity>
<d_Cus>7.90506601333618164e-06</d_Cus>
<d_sqrt_A>5.15363725471496582e+03</d_sqrt_A>
<d_Toe>5.18400000000000000e+05</d_Toe>
<d_Toc>5.18400000000000000e+05</d_Toc>
<d_Cic>1.45286321640014648e-07</d_Cic>
<d_OMEGA0>2.00408517949479270e+00</d_OMEGA0>
<d_Cis>2.40281224250793457e-07</d_Cis>
<d_i_0>9.41160112993577269e-01</d_i_0>
<d_Crc>2.15406250000000000e+02</d_Crc>
<d_OMEGA>9.09732121011562200e-01</d_OMEGA>
<d_OMEGA_DOT>-8.42213653007785350e-09</d_OMEGA_DOT>
<d_IDOT>-5.42879755978047536e-10</d_IDOT>
<i_code_on_L2>0</i_code_on_L2>
<i_GPS_week>799</i_GPS_week>
<b_L2_P_data_flag>0</b_L2_P_data_flag>
<i_SV_accuracy>2</i_SV_accuracy>
<i_SV_health>0</i_SV_health>
<d_TGD>-2.79396772384643555e-09</d_TGD>
<d_IODC>5.80000000000000000e+01</d_IODC>
<i_AODO>27900</i_AODO>
<b_fit_interval_flag>0</b_fit_interval_flag>
<d_spare1>0.00000000000000000e+00</d_spare1>
<d_spare2>0.00000000000000000e+00</d_spare2>
<d_A_f0>-1.54968351125717163e-04</d_A_f0>
<d_A_f1>-1.59161572810262401e-12</d_A_f1>
<d_A_f2>0.00000000000000000e+00</d_A_f2>
<b_integrity_status_flag>0</b_integrity_status_flag>
<b_alert_flag>0</b_alert_flag>
<b_antispoofing_flag>0</b_antispoofing_flag>
</second>
</item>
<item>
<first>12</first>
<second>
<i_satellite_PRN>12</i_satellite_PRN>
<d_TOW>5.18448000000000000e+05</d_TOW>
<d_IODE_SF2>1.06000000000000000e+02</d_IODE_SF2>
<d_IODE_SF3>1.06000000000000000e+02</d_IODE_SF3>
<d_Crs>-1.17468750000000000e+02</d_Crs>
<d_Delta_n>3.94516433192994276e-09</d_Delta_n>
<d_M_0>1.11631735294997192e+00</d_M_0>
<d_Cuc>-6.15417957305908203e-06</d_Cuc>
<d_e_eccentricity>5.05860964767634782e-03</d_e_eccentricity>
<d_Cus>4.52436506748199463e-06</d_Cus>
<d_sqrt_A>5.15376680946350098e+03</d_sqrt_A>
<d_Toe>5.18400000000000000e+05</d_Toe>
<d_Toc>5.18400000000000000e+05</d_Toc>
<d_Cic>-5.40167093276977539e-08</d_Cic>
<d_OMEGA0>-1.10425023618040785e+00</d_OMEGA0>
<d_Cis>4.09781932830810547e-08</d_Cis>
<d_i_0>9.88803748742243305e-01</d_i_0>
<d_Crc>3.07187500000000000e+02</d_Crc>
<d_OMEGA>5.00154452274795935e-01</d_OMEGA>
<d_OMEGA_DOT>-7.97176062725659211e-09</d_OMEGA_DOT>
<d_IDOT>-4.18231706743614228e-10</d_IDOT>
<i_code_on_L2>0</i_code_on_L2>
<i_GPS_week>799</i_GPS_week>
<b_L2_P_data_flag>0</b_L2_P_data_flag>
<i_SV_accuracy>2</i_SV_accuracy>
<i_SV_health>0</i_SV_health>
<d_TGD>-1.16415321826934814e-08</d_TGD>
<d_IODC>1.06000000000000000e+02</d_IODC>
<i_AODO>27900</i_AODO>
<b_fit_interval_flag>0</b_fit_interval_flag>
<d_spare1>0.00000000000000000e+00</d_spare1>
<d_spare2>0.00000000000000000e+00</d_spare2>
<d_A_f0>2.54871323704719543e-04</d_A_f0>
<d_A_f1>2.72848410531878391e-12</d_A_f1>
<d_A_f2>0.00000000000000000e+00</d_A_f2>
<b_integrity_status_flag>0</b_integrity_status_flag>
<b_alert_flag>0</b_alert_flag>
<b_antispoofing_flag>0</b_antispoofing_flag>
</second>
</item>
<item>
<first>17</first>
<second>
<i_satellite_PRN>17</i_satellite_PRN>
<d_TOW>5.18448000000000000e+05</d_TOW>
<d_IODE_SF2>2.60000000000000000e+01</d_IODE_SF2>
<d_IODE_SF3>2.60000000000000000e+01</d_IODE_SF3>
<d_Crs>-5.91250000000000000e+01</d_Crs>
<d_Delta_n>3.88194741297723567e-09</d_Delta_n>
<d_M_0>-1.94252959218893162e+00</d_M_0>
<d_Cuc>-3.04728746414184570e-06</d_Cuc>
<d_e_eccentricity>9.88844956737011498e-03</d_e_eccentricity>
<d_Cus>1.18296593427658081e-05</d_Cus>
<d_sqrt_A>5.15369299888610840e+03</d_sqrt_A>
<d_Toe>5.18400000000000000e+05</d_Toe>
<d_Toc>5.18400000000000000e+05</d_Toc>
<d_Cic>2.03028321266174316e-07</d_Cic>
<d_OMEGA0>-5.68690999805671268e-02</d_OMEGA0>
<d_Cis>-7.63684511184692383e-08</d_Cis>
<d_i_0>9.71201777972365177e-01</d_i_0>
<d_Crc>1.56531250000000000e+02</d_Crc>
<d_OMEGA>-2.06928329237789344e+00</d_OMEGA>
<d_OMEGA_DOT>-7.44602444251995675e-09</d_OMEGA_DOT>
<d_IDOT>4.40375486263771432e-10</d_IDOT>
<i_code_on_L2>0</i_code_on_L2>
<i_GPS_week>799</i_GPS_week>
<b_L2_P_data_flag>0</b_L2_P_data_flag>
<i_SV_accuracy>2</i_SV_accuracy>
<i_SV_health>0</i_SV_health>
<d_TGD>-1.07102096080780029e-08</d_TGD>
<d_IODC>2.60000000000000000e+01</d_IODC>
<i_AODO>27900</i_AODO>
<b_fit_interval_flag>0</b_fit_interval_flag>
<d_spare1>0.00000000000000000e+00</d_spare1>
<d_spare2>0.00000000000000000e+00</d_spare2>
<d_A_f0>-1.44933816045522690e-04</d_A_f0>
<d_A_f1>-2.27373675443232019e-12</d_A_f1>
<d_A_f2>0.00000000000000000e+00</d_A_f2>
<b_integrity_status_flag>0</b_integrity_status_flag>
<b_alert_flag>0</b_alert_flag>
<b_antispoofing_flag>0</b_antispoofing_flag>
</second>
</item>
<item>
<first>20</first>
<second>
<i_satellite_PRN>20</i_satellite_PRN>
<d_TOW>5.18448000000000000e+05</d_TOW>
<d_IODE_SF2>1.17000000000000000e+02</d_IODE_SF2>
<d_IODE_SF3>1.17000000000000000e+02</d_IODE_SF3>
<d_Crs>-2.58437500000000000e+01</d_Crs>
<d_Delta_n>5.60380484953655626e-09</d_Delta_n>
<d_M_0>1.28625710142833249e-01</d_M_0>
<d_Cuc>-1.52923166751861572e-06</d_Cuc>
<d_e_eccentricity>5.80669869668781671e-03</d_e_eccentricity>
<d_Cus>7.51018524169921875e-06</d_Cus>
<d_sqrt_A>5.15578671264648438e+03</d_sqrt_A>
<d_Toe>5.18400000000000000e+05</d_Toe>
<d_Toc>5.18400000000000000e+05</d_Toc>
<d_Cic>-2.23517417907714844e-08</d_Cic>
<d_OMEGA0>1.92543994118208528e+00</d_OMEGA0>
<d_Cis>4.65661287307739258e-08</d_Cis>
<d_i_0>9.26021286652122910e-01</d_i_0>
<d_Crc>2.18031250000000000e+02</d_Crc>
<d_OMEGA>1.23365536128043107e+00</d_OMEGA>
<d_OMEGA_DOT>-8.54892752571746483e-09</d_OMEGA_DOT>
<d_IDOT>-5.16450083647537340e-10</d_IDOT>
<i_code_on_L2>0</i_code_on_L2>
<i_GPS_week>799</i_GPS_week>
<b_L2_P_data_flag>0</b_L2_P_data_flag>
<i_SV_accuracy>2</i_SV_accuracy>
<i_SV_health>0</i_SV_health>
<d_TGD>-8.38190317153930664e-09</d_TGD>
<d_IODC>1.17000000000000000e+02</d_IODC>
<i_AODO>27900</i_AODO>
<b_fit_interval_flag>0</b_fit_interval_flag>
<d_spare1>0.00000000000000000e+00</d_spare1>
<d_spare2>0.00000000000000000e+00</d_spare2>
<d_A_f0>2.69209500402212143e-04</d_A_f0>
<d_A_f1>4.20641299569979229e-12</d_A_f1>
<d_A_f2>0.00000000000000000e+00</d_A_f2>
<b_integrity_status_flag>0</b_integrity_status_flag>
<b_alert_flag>0</b_alert_flag>
<b_antispoofing_flag>0</b_antispoofing_flag>
</second>
</item>
<item>
<first>23</first>
<second>
<i_satellite_PRN>23</i_satellite_PRN>
<d_TOW>5.18448000000000000e+05</d_TOW>
<d_IODE_SF2>4.10000000000000000e+01</d_IODE_SF2>
<d_IODE_SF3>4.10000000000000000e+01</d_IODE_SF3>
<d_Crs>1.20250000000000000e+02</d_Crs>
<d_Delta_n>4.45161399901998963e-09</d_Delta_n>
<d_M_0>3.04794581942897569e+00</d_M_0>
<d_Cuc>6.13741576671600342e-06</d_Cuc>
<d_e_eccentricity>9.67817602213471954e-03</d_e_eccentricity>
<d_Cus>1.14180147647857666e-05</d_Cus>
<d_sqrt_A>5.15370163154602051e+03</d_sqrt_A>
<d_Toe>5.18400000000000000e+05</d_Toe>
<d_Toc>5.18400000000000000e+05</d_Toc>
<d_Cic>-6.14672899246215820e-08</d_Cic>
<d_OMEGA0>3.04748172476042711e+00</d_OMEGA0>
<d_Cis>-1.04308128356933594e-07</d_Cis>
<d_i_0>9.50229191282804808e-01</d_i_0>
<d_Crc>1.56000000000000000e+02</d_Crc>
<d_OMEGA>-2.71676891930177256e+00</d_OMEGA>
<d_OMEGA_DOT>-7.78032408172749087e-09</d_OMEGA_DOT>
<d_IDOT>-2.75011455330984601e-11</d_IDOT>
<i_code_on_L2>0</i_code_on_L2>
<i_GPS_week>799</i_GPS_week>
<b_L2_P_data_flag>0</b_L2_P_data_flag>
<i_SV_accuracy>2</i_SV_accuracy>
<i_SV_health>0</i_SV_health>
<d_TGD>-1.95577740669250488e-08</d_TGD>
<d_IODC>4.10000000000000000e+01</d_IODC>
<i_AODO>27900</i_AODO>
<b_fit_interval_flag>0</b_fit_interval_flag>
<d_spare1>0.00000000000000000e+00</d_spare1>
<d_spare2>0.00000000000000000e+00</d_spare2>
<d_A_f0>-7.56788067519664764e-05</d_A_f0>
<d_A_f1>-2.72848410531878391e-12</d_A_f1>
<d_A_f2>0.00000000000000000e+00</d_A_f2>
<b_integrity_status_flag>0</b_integrity_status_flag>
<b_alert_flag>0</b_alert_flag>
<b_antispoofing_flag>0</b_antispoofing_flag>
</second>
</item>
<item>
<first>28</first>
<second>
<i_satellite_PRN>28</i_satellite_PRN>
<d_TOW>5.18448000000000000e+05</d_TOW>
<d_IODE_SF2>3.30000000000000000e+01</d_IODE_SF2>
<d_IODE_SF3>3.30000000000000000e+01</d_IODE_SF3>
<d_Crs>-1.27750000000000000e+02</d_Crs>
<d_Delta_n>4.04302555109966970e-09</d_Delta_n>
<d_M_0>-1.16607683198628931e+00</d_M_0>
<d_Cuc>-6.37024641036987305e-06</d_Cuc>
<d_e_eccentricity>1.97223023278638686e-02</d_e_eccentricity>
<d_Cus>5.66989183425903320e-06</d_Cus>
<d_sqrt_A>5.15368548965454102e+03</d_sqrt_A>
<d_Toe>5.18400000000000000e+05</d_Toe>
<d_Toc>5.18400000000000000e+05</d_Toc>
<d_Cic>-1.37835741043090820e-07</d_Cic>
<d_OMEGA0>-1.08006546321039543e+00</d_OMEGA0>
<d_Cis>4.35858964920043945e-07</d_Cis>
<d_i_0>9.87961552655681530e-01</d_i_0>
<d_Crc>2.84718750000000000e+02</d_Crc>
<d_OMEGA>-1.69047108635756738e+00</d_OMEGA>
<d_OMEGA_DOT>-8.17855495535612472e-09</d_OMEGA_DOT>
<d_IDOT>-4.44661379074124424e-10</d_IDOT>
<i_code_on_L2>0</i_code_on_L2>
<i_GPS_week>799</i_GPS_week>
<b_L2_P_data_flag>0</b_L2_P_data_flag>
<i_SV_accuracy>2</i_SV_accuracy>
<i_SV_health>0</i_SV_health>
<d_TGD>-1.11758708953857422e-08</d_TGD>
<d_IODC>3.30000000000000000e+01</d_IODC>
<i_AODO>27900</i_AODO>
<b_fit_interval_flag>0</b_fit_interval_flag>
<d_spare1>0.00000000000000000e+00</d_spare1>
<d_spare2>0.00000000000000000e+00</d_spare2>
<d_A_f0>4.06486913561820984e-04</d_A_f0>
<d_A_f1>2.61479726759716828e-12</d_A_f1>
<d_A_f2>0.00000000000000000e+00</d_A_f2>
<b_integrity_status_flag>0</b_integrity_status_flag>
<b_alert_flag>0</b_alert_flag>
<b_antispoofing_flag>0</b_antispoofing_flag>
</second>
</item>
</GNSS-SDR_ephemeris_map>
</boost_serialization>

View File

@ -0,0 +1,358 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="12">
<GNSS-SDR_gnss_synchro_map class_id="0" tracking_level="0" version="0">
<count>10</count>
<item_version>0</item_version>
<item class_id="1" tracking_level="0" version="0">
<first>0</first>
<second class_id="2" tracking_level="0" version="0">
<System>71</System>
<Signal>
<count>3</count>
<item>49</item>
<item>67</item>
<item>0</item>
</Signal>
<PRN>1</PRN>
<Channel_ID>0</Channel_ID>
<Acq_delay_samples>2.28200000000000000e+03</Acq_delay_samples>
<Acq_doppler_hz>-2.50000000000000000e+03</Acq_doppler_hz>
<Acq_samplestamp_samples>10791</Acq_samplestamp_samples>
<Acq_doppler_step>0</Acq_doppler_step>
<Flag_valid_acquisition>0</Flag_valid_acquisition>
<fs>2600000</fs>
<Prompt_I>-3.85959140625000000e+04</Prompt_I>
<Prompt_Q>-9.03592163085937500e+02</Prompt_Q>
<CN0_dB_hz>5.96898384094238281e+01</CN0_dB_hz>
<Carrier_Doppler_hz>-2.57914688873291016e+03</Carrier_Doppler_hz>
<Carrier_phase_rads>8.35350813421410858e+05</Carrier_phase_rads>
<Code_phase_samples>3.31084377635761484e-01</Code_phase_samples>
<Tracking_sample_counter>133923691</Tracking_sample_counter>
<Flag_valid_symbol_output>1</Flag_valid_symbol_output>
<correlation_length_ms>1</correlation_length_ms>
<Flag_valid_word>1</Flag_valid_word>
<TOW_at_current_symbol_ms>518451424</TOW_at_current_symbol_ms>
<Pseudorange_m>2.28178186234515086e+07</Pseudorange_m>
<RX_time>5.18451500000000000e+05</RX_time>
<Flag_valid_pseudorange>1</Flag_valid_pseudorange>
<interp_TOW_ms>5.18451423887949765e+08</interp_TOW_ms>
</second>
</item>
<item>
<first>1</first>
<second>
<System>71</System>
<Signal>
<count>3</count>
<item>49</item>
<item>67</item>
<item>0</item>
</Signal>
<PRN>3</PRN>
<Channel_ID>1</Channel_ID>
<Acq_delay_samples>2.38500000000000000e+03</Acq_delay_samples>
<Acq_doppler_hz>-3.00000000000000000e+03</Acq_doppler_hz>
<Acq_samplestamp_samples>68450858</Acq_samplestamp_samples>
<Acq_doppler_step>0</Acq_doppler_step>
<Flag_valid_acquisition>0</Flag_valid_acquisition>
<fs>2600000</fs>
<Prompt_I>-4.34972734375000000e+04</Prompt_I>
<Prompt_Q>4.21364685058593750e+02</Prompt_Q>
<CN0_dB_hz>5.16798934936523438e+01</CN0_dB_hz>
<Carrier_Doppler_hz>-3.12509065246582031e+03</Carrier_Doppler_hz>
<Carrier_phase_rads>4.93910706686261110e+05</Carrier_phase_rads>
<Code_phase_samples>7.36033200862493686e-01</Code_phase_samples>
<Tracking_sample_counter>133923971</Tracking_sample_counter>
<Flag_valid_symbol_output>1</Flag_valid_symbol_output>
<correlation_length_ms>1</correlation_length_ms>
<Flag_valid_word>1</Flag_valid_word>
<TOW_at_current_symbol_ms>518451431</TOW_at_current_symbol_ms>
<Pseudorange_m>2.07516033774388395e+07</Pseudorange_m>
<RX_time>5.18451500000000000e+05</RX_time>
<Flag_valid_pseudorange>1</Flag_valid_pseudorange>
<interp_TOW_ms>5.18451430780101955e+08</interp_TOW_ms>
</second>
</item>
<item>
<first>2</first>
<second>
<System>71</System>
<Signal>
<count>3</count>
<item>49</item>
<item>67</item>
<item>0</item>
</Signal>
<PRN>28</PRN>
<Channel_ID>2</Channel_ID>
<Acq_delay_samples>1.52700000000000000e+03</Acq_delay_samples>
<Acq_doppler_hz>-3.00000000000000000e+03</Acq_doppler_hz>
<Acq_samplestamp_samples>1350770</Acq_samplestamp_samples>
<Acq_doppler_step>0</Acq_doppler_step>
<Flag_valid_acquisition>0</Flag_valid_acquisition>
<fs>2600000</fs>
<Prompt_I>4.46268046875000000e+04</Prompt_I>
<Prompt_Q>-3.98811938476562500e+03</Prompt_Q>
<CN0_dB_hz>5.25376167297363281e+01</CN0_dB_hz>
<Carrier_Doppler_hz>-2.92984253692626953e+03</Carrier_Doppler_hz>
<Carrier_phase_rads>9.35704822809229488e+05</Carrier_phase_rads>
<Code_phase_samples>9.30327007595224131e-01</Code_phase_samples>
<Tracking_sample_counter>133923941</Tracking_sample_counter>
<Flag_valid_symbol_output>1</Flag_valid_symbol_output>
<correlation_length_ms>1</correlation_length_ms>
<Flag_valid_word>1</Flag_valid_word>
<TOW_at_current_symbol_ms>518451436</TOW_at_current_symbol_ms>
<Pseudorange_m>1.92492043561209217e+07</Pseudorange_m>
<RX_time>5.18451500000000000e+05</RX_time>
<Flag_valid_pseudorange>1</Flag_valid_pseudorange>
<interp_TOW_ms>5.18451435791565657e+08</interp_TOW_ms>
</second>
</item>
<item>
<first>4</first>
<second>
<System>71</System>
<Signal>
<count>3</count>
<item>49</item>
<item>67</item>
<item>0</item>
</Signal>
<PRN>23</PRN>
<Channel_ID>4</Channel_ID>
<Acq_delay_samples>1.13100000000000000e+03</Acq_delay_samples>
<Acq_doppler_hz>1.00000000000000000e+03</Acq_doppler_hz>
<Acq_samplestamp_samples>994247</Acq_samplestamp_samples>
<Acq_doppler_step>0</Acq_doppler_step>
<Flag_valid_acquisition>0</Flag_valid_acquisition>
<fs>2600000</fs>
<Prompt_I>3.98655546875000000e+04</Prompt_I>
<Prompt_Q>-8.63781860351562500e+02</Prompt_Q>
<CN0_dB_hz>5.24684982299804688e+01</CN0_dB_hz>
<Carrier_Doppler_hz>1.09281750951009121e+03</Carrier_Doppler_hz>
<Carrier_phase_rads>-3.54128275530727289e+05</Carrier_phase_rads>
<Code_phase_samples>4.08304036132904002e-01</Code_phase_samples>
<Tracking_sample_counter>133922883</Tracking_sample_counter>
<Flag_valid_symbol_output>1</Flag_valid_symbol_output>
<correlation_length_ms>1</correlation_length_ms>
<Flag_valid_word>1</Flag_valid_word>
<TOW_at_current_symbol_ms>518451429</TOW_at_current_symbol_ms>
<Pseudorange_m>2.12256989876578376e+07</Pseudorange_m>
<RX_time>5.18451500000000000e+05</RX_time>
<Flag_valid_pseudorange>1</Flag_valid_pseudorange>
<interp_TOW_ms>5.18451429198689222e+08</interp_TOW_ms>
</second>
</item>
<item>
<first>5</first>
<second>
<System>71</System>
<Signal>
<count>3</count>
<item>49</item>
<item>67</item>
<item>0</item>
</Signal>
<PRN>2</PRN>
<Channel_ID>5</Channel_ID>
<Acq_delay_samples>5.38000000000000000e+02</Acq_delay_samples>
<Acq_doppler_hz>1.75000000000000000e+03</Acq_doppler_hz>
<Acq_samplestamp_samples>4917751</Acq_samplestamp_samples>
<Acq_doppler_step>0</Acq_doppler_step>
<Flag_valid_acquisition>0</Flag_valid_acquisition>
<fs>2600000</fs>
<Prompt_I>-4.72456406250000000e+04</Prompt_I>
<Prompt_Q>-2.63723022460937500e+02</Prompt_Q>
<CN0_dB_hz>4.89446220397949219e+01</CN0_dB_hz>
<Carrier_Doppler_hz>1.83319645690917969e+03</Carrier_Doppler_hz>
<Carrier_phase_rads>-5.72184006019302527e+05</Carrier_phase_rads>
<Code_phase_samples>5.89544135488722532e-01</Code_phase_samples>
<Tracking_sample_counter>133922337</Tracking_sample_counter>
<Flag_valid_symbol_output>1</Flag_valid_symbol_output>
<correlation_length_ms>1</correlation_length_ms>
<Flag_valid_word>1</Flag_valid_word>
<TOW_at_current_symbol_ms>518451430</TOW_at_current_symbol_ms>
<Pseudorange_m>2.08629709015843943e+07</Pseudorange_m>
<RX_time>5.18451500000000000e+05</RX_time>
<Flag_valid_pseudorange>1</Flag_valid_pseudorange>
<interp_TOW_ms>5.18451430408619881e+08</interp_TOW_ms>
</second>
</item>
<item>
<first>6</first>
<second>
<System>71</System>
<Signal>
<count>3</count>
<item>49</item>
<item>67</item>
<item>0</item>
</Signal>
<PRN>17</PRN>
<Channel_ID>6</Channel_ID>
<Acq_delay_samples>2.21000000000000000e+02</Acq_delay_samples>
<Acq_doppler_hz>2.50000000000000000e+02</Acq_doppler_hz>
<Acq_samplestamp_samples>514377</Acq_samplestamp_samples>
<Acq_doppler_step>0</Acq_doppler_step>
<Flag_valid_acquisition>0</Flag_valid_acquisition>
<fs>2600000</fs>
<Prompt_I>4.27717460937500000e+04</Prompt_I>
<Prompt_Q>-9.45822082519531250e+02</Prompt_Q>
<CN0_dB_hz>5.38986015319824219e+01</CN0_dB_hz>
<Carrier_Doppler_hz>2.73018497467041016e+02</Carrier_Doppler_hz>
<Carrier_phase_rads>-9.09813659855529113e+04</Carrier_phase_rads>
<Code_phase_samples>6.57473345280777721e-01</Code_phase_samples>
<Tracking_sample_counter>133923172</Tracking_sample_counter>
<Flag_valid_symbol_output>1</Flag_valid_symbol_output>
<correlation_length_ms>1</correlation_length_ms>
<Flag_valid_word>1</Flag_valid_word>
<TOW_at_current_symbol_ms>518451440</TOW_at_current_symbol_ms>
<Pseudorange_m>1.79613337841309197e+07</Pseudorange_m>
<RX_time>5.18451500000000000e+05</RX_time>
<Flag_valid_pseudorange>1</Flag_valid_pseudorange>
<interp_TOW_ms>5.18451440087439477e+08</interp_TOW_ms>
</second>
</item>
<item>
<first>7</first>
<second>
<System>71</System>
<Signal>
<count>3</count>
<item>49</item>
<item>67</item>
<item>0</item>
</Signal>
<PRN>9</PRN>
<Channel_ID>7</Channel_ID>
<Acq_delay_samples>1.56900000000000000e+03</Acq_delay_samples>
<Acq_doppler_hz>2.25000000000000000e+03</Acq_doppler_hz>
<Acq_samplestamp_samples>7365787</Acq_samplestamp_samples>
<Acq_doppler_step>0</Acq_doppler_step>
<Flag_valid_acquisition>0</Flag_valid_acquisition>
<fs>2600000</fs>
<Prompt_I>-3.96159960937500000e+04</Prompt_I>
<Prompt_Q>-5.03847460937500000e+03</Prompt_Q>
<CN0_dB_hz>5.33032913208007812e+01</CN0_dB_hz>
<Carrier_Doppler_hz>2.30021731185913086e+03</Carrier_Doppler_hz>
<Carrier_phase_rads>-7.04913853936602012e+05</Carrier_phase_rads>
<Code_phase_samples>3.21518194999043772e-01</Code_phase_samples>
<Tracking_sample_counter>133922169</Tracking_sample_counter>
<Flag_valid_symbol_output>1</Flag_valid_symbol_output>
<correlation_length_ms>1</correlation_length_ms>
<Flag_valid_word>1</Flag_valid_word>
<TOW_at_current_symbol_ms>518451430</TOW_at_current_symbol_ms>
<Pseudorange_m>2.08435687343175523e+07</Pseudorange_m>
<RX_time>5.18451500000000000e+05</RX_time>
<Flag_valid_pseudorange>1</Flag_valid_pseudorange>
<interp_TOW_ms>5.18451430473338544e+08</interp_TOW_ms>
</second>
</item>
<item>
<first>8</first>
<second>
<System>71</System>
<Signal>
<count>3</count>
<item>49</item>
<item>67</item>
<item>0</item>
</Signal>
<PRN>10</PRN>
<Channel_ID>8</Channel_ID>
<Acq_delay_samples>2.12600000000000000e+03</Acq_delay_samples>
<Acq_doppler_hz>2.75000000000000000e+03</Acq_doppler_hz>
<Acq_samplestamp_samples>2173576</Acq_samplestamp_samples>
<Acq_doppler_step>0</Acq_doppler_step>
<Flag_valid_acquisition>0</Flag_valid_acquisition>
<fs>2600000</fs>
<Prompt_I>4.00322539062500000e+04</Prompt_I>
<Prompt_Q>-3.88590087890625000e+02</Prompt_Q>
<CN0_dB_hz>4.85561523437500000e+01</CN0_dB_hz>
<Carrier_Doppler_hz>2.81225794982910156e+03</Carrier_Doppler_hz>
<Carrier_phase_rads>-8.99142229977656389e+05</Carrier_phase_rads>
<Code_phase_samples>1.02370741655249731e-01</Code_phase_samples>
<Tracking_sample_counter>133922664</Tracking_sample_counter>
<Flag_valid_symbol_output>1</Flag_valid_symbol_output>
<correlation_length_ms>1</correlation_length_ms>
<Flag_valid_word>1</Flag_valid_word>
<TOW_at_current_symbol_ms>518451438</TOW_at_current_symbol_ms>
<Pseudorange_m>1.85022797143675610e+07</Pseudorange_m>
<RX_time>5.18451500000000000e+05</RX_time>
<Flag_valid_pseudorange>1</Flag_valid_pseudorange>
<interp_TOW_ms>5.18451438283038080e+08</interp_TOW_ms>
</second>
</item>
<item>
<first>9</first>
<second>
<System>71</System>
<Signal>
<count>3</count>
<item>49</item>
<item>67</item>
<item>0</item>
</Signal>
<PRN>12</PRN>
<Channel_ID>9</Channel_ID>
<Acq_delay_samples>2.13000000000000000e+02</Acq_delay_samples>
<Acq_doppler_hz>3.00000000000000000e+03</Acq_doppler_hz>
<Acq_samplestamp_samples>7464974</Acq_samplestamp_samples>
<Acq_doppler_step>0</Acq_doppler_step>
<Flag_valid_acquisition>0</Flag_valid_acquisition>
<fs>2600000</fs>
<Prompt_I>-4.03654140625000000e+04</Prompt_I>
<Prompt_Q>3.92351245117187500e+03</Prompt_Q>
<CN0_dB_hz>5.17314453125000000e+01</CN0_dB_hz>
<Carrier_Doppler_hz>3.03019989013671875e+03</Carrier_Doppler_hz>
<Carrier_phase_rads>-9.28340507655202877e+05</Carrier_phase_rads>
<Code_phase_samples>5.73995602361264901e-01</Code_phase_samples>
<Tracking_sample_counter>133923741</Tracking_sample_counter>
<Flag_valid_symbol_output>1</Flag_valid_symbol_output>
<correlation_length_ms>1</correlation_length_ms>
<Flag_valid_word>1</Flag_valid_word>
<TOW_at_current_symbol_ms>518451427</TOW_at_current_symbol_ms>
<Pseudorange_m>2.19242346189941987e+07</Pseudorange_m>
<RX_time>5.18451500000000000e+05</RX_time>
<Flag_valid_pseudorange>1</Flag_valid_pseudorange>
<interp_TOW_ms>5.18451426868625164e+08</interp_TOW_ms>
</second>
</item>
<item>
<first>10</first>
<second>
<System>71</System>
<Signal>
<count>3</count>
<item>49</item>
<item>67</item>
<item>0</item>
</Signal>
<PRN>6</PRN>
<Channel_ID>10</Channel_ID>
<Acq_delay_samples>4.70000000000000000e+01</Acq_delay_samples>
<Acq_doppler_hz>5.00000000000000000e+02</Acq_doppler_hz>
<Acq_samplestamp_samples>1859813</Acq_samplestamp_samples>
<Acq_doppler_step>0</Acq_doppler_step>
<Flag_valid_acquisition>0</Flag_valid_acquisition>
<fs>2600000</fs>
<Prompt_I>3.87814335937500000e+04</Prompt_I>
<Prompt_Q>2.13637329101562500e+03</Prompt_Q>
<CN0_dB_hz>6.00463027954101562e+01</CN0_dB_hz>
<Carrier_Doppler_hz>5.54514957427978516e+02</Carrier_Doppler_hz>
<Carrier_phase_rads>-1.78723083774703584e+05</Carrier_phase_rads>
<Code_phase_samples>3.47952294631795667e-01</Code_phase_samples>
<Tracking_sample_counter>133924211</Tracking_sample_counter>
<Flag_valid_symbol_output>1</Flag_valid_symbol_output>
<correlation_length_ms>1</correlation_length_ms>
<Flag_valid_word>1</Flag_valid_word>
<TOW_at_current_symbol_ms>518451439</TOW_at_current_symbol_ms>
<Pseudorange_m>1.83808922785463184e+07</Pseudorange_m>
<RX_time>5.18451500000000000e+05</RX_time>
<Flag_valid_pseudorange>1</Flag_valid_pseudorange>
<interp_TOW_ms>5.18451438687942982e+08</interp_TOW_ms>
</second>
</item>
</GNSS-SDR_gnss_synchro_map>
</boost_serialization>

View File

@ -28,10 +28,10 @@
*
* -------------------------------------------------------------------------
*/
#include "geofunctions.h"
const double STRP_G_SI = 9.80665;
const double STRP_PI = 3.1415926535898; //!< Pi as defined in IS-GPS-200E
const double STRP_PI = 3.1415926535898; // Pi as defined in IS-GPS-200E
arma::mat Skew_symmetric(const arma::vec &a)
{
@ -205,17 +205,17 @@ int togeod(double *dphi, double *dlambda, double *h, double a, double finv, doub
cosphi = cos(*dphi);
// compute radius of curvature in prime vertical direction
N_phi = a / sqrt(1 - esq * sinphi * sinphi);
N_phi = a / sqrt(1.0 - esq * sinphi * sinphi);
// compute residuals in P and Z
// compute residuals in P and Z
dP = P - (N_phi + (*h)) * cosphi;
dZ = Z - (N_phi * oneesq + (*h)) * sinphi;
// update height and latitude
// update height and latitude
*h = *h + (sinphi * dZ + cosphi * dP);
*dphi = *dphi + (cosphi * dZ - sinphi * dP) / (N_phi + (*h));
// test for convergence
// test for convergence
if ((dP * dP + dZ * dZ) < tolsq)
{
break;
@ -233,7 +233,7 @@ int togeod(double *dphi, double *dlambda, double *h, double a, double finv, doub
arma::mat Gravity_ECEF(const arma::vec &r_eb_e)
{
// Parameters
const double R_0 = 6378137; // WGS84 Equatorial radius in meters
const double R_0 = 6378137.0; // WGS84 Equatorial radius in meters
const double mu = 3.986004418E14; // WGS84 Earth gravitational constant (m^3 s^-2)
const double J_2 = 1.082627E-3; // WGS84 Earth's second gravitational constant
const double omega_ie = 7.292115E-5; // Earth rotation rate (rad/s)
@ -259,12 +259,14 @@ arma::mat Gravity_ECEF(const arma::vec &r_eb_e)
}
arma::vec LLH_to_deg(arma::vec &LLH)
arma::vec LLH_to_deg(const arma::vec &LLH)
{
const double rtd = 180.0 / STRP_PI;
LLH(0) = LLH(0) * rtd;
LLH(1) = LLH(1) * rtd;
return LLH;
arma::vec deg = arma::zeros(3, 1);
deg(0) = LLH(0) * rtd;
deg(1) = LLH(1) * rtd;
deg(2) = LLH(2);
return deg;
}
@ -296,15 +298,16 @@ double mstokph(double MetersPerSeconds)
}
arma::vec CTM_to_Euler(arma::mat &C)
arma::vec CTM_to_Euler(const arma::mat &C)
{
// Calculate Euler angles using (2.23)
arma::mat CTM = C;
arma::vec eul = arma::zeros(3, 1);
eul(0) = atan2(C(1, 2), C(2, 2)); // roll
if (C(0, 2) < -1.0) C(0, 2) = -1.0;
if (C(0, 2) > 1.0) C(0, 2) = 1.0;
eul(1) = -asin(C(0, 2)); // pitch
eul(2) = atan2(C(0, 1), C(0, 0)); // yaw
eul(0) = atan2(CTM(1, 2), CTM(2, 2)); // roll
if (CTM(0, 2) < -1.0) CTM(0, 2) = -1.0;
if (CTM(0, 2) > 1.0) CTM(0, 2) = 1.0;
eul(1) = -asin(CTM(0, 2)); // pitch
eul(2) = atan2(CTM(0, 1), CTM(0, 0)); // yaw
return eul;
}
@ -353,19 +356,19 @@ arma::vec cart2geo(const arma::vec &XYZ, int elipsoid_selection)
do
{
oldh = h;
N = c / sqrt(1 + ex2 * (cos(phi) * cos(phi)));
N = c / sqrt(1.0 + ex2 * (cos(phi) * cos(phi)));
phi = atan(XYZ[2] / ((sqrt(XYZ[0] * XYZ[0] + XYZ[1] * XYZ[1]) * (1.0 - (2.0 - f[elipsoid_selection]) * f[elipsoid_selection] * N / (N + h)))));
h = sqrt(XYZ[0] * XYZ[0] + XYZ[1] * XYZ[1]) / cos(phi) - N;
iterations = iterations + 1;
if (iterations > 100)
{
//std::cout << "Failed to approximate h with desired precision. h-oldh= " << h - oldh;
// std::cout << "Failed to approximate h with desired precision. h-oldh= " << h - oldh;
break;
}
}
while (std::abs(h - oldh) > 1.0e-12);
while (std::fabs(h - oldh) > 1.0e-12);
arma::vec LLH = {{phi, lambda, h}}; //radians
arma::vec LLH = {{phi, lambda, h}}; // radians
return LLH;
}
@ -398,11 +401,11 @@ void ECEF_to_Geo(const arma::vec &r_eb_e, const arma::vec &v_eb_e, const arma::m
void Geo_to_ECEF(const arma::vec &LLH, const arma::vec &v_eb_n, const arma::mat &C_b_n, arma::vec &r_eb_e, arma::vec &v_eb_e, arma::mat &C_b_e)
{
// Parameters
double R_0 = 6378137; // WGS84 Equatorial radius in meters
double R_0 = 6378137.0; // WGS84 Equatorial radius in meters
double e = 0.0818191908425; // WGS84 eccentricity
// Calculate transverse radius of curvature using (2.105)
double R_E = R_0 / sqrt(1 - (e * sin(LLH(0))) * (e * sin(LLH(0))));
double R_E = R_0 / sqrt(1.0 - (e * sin(LLH(0))) * (e * sin(LLH(0))));
// Convert position using (2.112)
double cos_lat = cos(LLH(0));
@ -434,7 +437,7 @@ void Geo_to_ECEF(const arma::vec &LLH, const arma::vec &v_eb_n, const arma::mat
void pv_Geo_to_ECEF(double L_b, double lambda_b, double h_b, const arma::vec &v_eb_n, arma::vec &r_eb_e, arma::vec &v_eb_e)
{
// Parameters
const double R_0 = 6378137; // WGS84 Equatorial radius in meters
const double R_0 = 6378137.0; // WGS84 Equatorial radius in meters
const double e = 0.0818191908425; // WGS84 eccentricity
// Calculate transverse radius of curvature using (2.105)
@ -458,3 +461,315 @@ void pv_Geo_to_ECEF(double L_b, double lambda_b, double h_b, const arma::vec &v_
// Transform velocity using (2.73)
v_eb_e = C_e_n.t() * v_eb_n;
}
double great_circle_distance(double lat1, double lon1, double lat2, double lon2)
{
// The Haversine formula determines the great-circle distance between two points on a sphere given their longitudes and latitudes.
// generally used geo measurement function
double R = 6378.137; // Radius of earth in KM
double dLat = lat2 * STRP_PI / 180.0 - lat1 * STRP_PI / 180.0;
double dLon = lon2 * STRP_PI / 180.0 - lon1 * STRP_PI / 180.0;
double a = sin(dLat / 2.0) * sin(dLat / 2.0) +
cos(lat1 * STRP_PI / 180.0) * cos(lat2 * STRP_PI / 180.0) *
sin(dLon / 2) * sin(dLon / 2.0);
double c = 2.0 * atan2(sqrt(a), sqrt(1.0 - a));
double d = R * c;
return d * 1000.0; // meters
}
void cart2utm(const arma::vec &r_eb_e, int zone, arma::vec &r_enu)
{
// Transformation of (X,Y,Z) to (E,N,U) in UTM, zone 'zone'
//
// Inputs:
// r_eb_e - Cartesian coordinates. Coordinates are referenced
// with respect to the International Terrestrial Reference
// Frame 1996 (ITRF96)
// zone - UTM zone of the given position
//
// Outputs:
// r_enu - UTM coordinates (Easting, Northing, Uping)
//
// Originally written in Matlab by Kai Borre, Nov. 1994
// Implemented in C++ by J.Arribas
//
// This implementation is based upon
// O. Andersson & K. Poder (1981) Koordinattransformationer
// ved Geod\ae{}tisk Institut. Landinspekt\oe{}ren
// Vol. 30: 552--571 and Vol. 31: 76
//
// An excellent, general reference (KW) is
// R. Koenig & K.H. Weise (1951) Mathematische Grundlagen der
// h\"oheren Geod\"asie und Kartographie.
// Erster Band, Springer Verlag
//
// Explanation of variables used:
// f flattening of ellipsoid
// a semi major axis in m
// m0 1 - scale at central meridian; for UTM 0.0004
// Q_n normalized meridian quadrant
// E0 Easting of central meridian
// L0 Longitude of central meridian
// bg constants for ellipsoidal geogr. to spherical geogr.
// gb constants for spherical geogr. to ellipsoidal geogr.
// gtu constants for ellipsoidal N, E to spherical N, E
// utg constants for spherical N, E to ellipoidal N, E
// tolutm tolerance for utm, 1.2E-10*meridian quadrant
// tolgeo tolerance for geographical, 0.00040 second of arc
//
// B, L refer to latitude and longitude. Southern latitude is negative
// International ellipsoid of 1924, valid for ED50
double a = 6378388.0;
double f = 1.0 / 297.0;
double ex2 = (2.0 - f) * f / ((1.0 - f) * (1.0 - f));
double c = a * sqrt(1.0 + ex2);
arma::vec vec = r_eb_e;
vec(2) = vec(2) - 4.5;
double alpha = 0.756e-6;
arma::mat R = {{1.0, -alpha, 0.0}, {alpha, 1.0, 0.0}, {0.0, 0.0, 1.0}};
arma::vec trans = {89.5, 93.8, 127.6};
double scale = 0.9999988;
arma::vec v = scale * R * vec + trans; // coordinate vector in ED50
double L = atan2(v(1), v(0));
double N1 = 6395000.0; // preliminary value
double B = atan2(v(2) / ((1.0 - f) * (1.0 - f) * N1), arma::norm(v.subvec(0, 1)) / N1); // preliminary value
double U = 0.1;
double oldU = 0.0;
int iterations = 0;
while (fabs(U - oldU) > 1.0E-4)
{
oldU = U;
N1 = c / sqrt(1.0 + ex2 * (cos(B) * cos(B)));
B = atan2(v(2) / ((1.0 - f) * (1.0 - f) * N1 + U), arma::norm(v.subvec(0, 1)) / (N1 + U));
U = arma::norm(v.subvec(0, 1)) / cos(B) - N1;
iterations = iterations + 1;
if (iterations > 100)
{
std::cout << "Failed to approximate U with desired precision. U-oldU:" << U - oldU << std::endl;
break;
}
}
// Normalized meridian quadrant, KW p. 50 (96), p. 19 (38b), p. 5 (21)
double m0 = 0.0004;
double n = f / (2.0 - f);
double m = n * n * (1.0 / 4.0 + n * n / 64.0);
double w = (a * (-n - m0 + m * (1.0 - m0))) / (1.0 + n);
double Q_n = a + w;
// Easting and longitude of central meridian
double E0 = 500000.0;
double L0 = (zone - 30) * 6.0 - 3.0;
// Check tolerance for reverse transformation
// double tolutm = STRP_PI / 2.0 * 1.2e-10 * Q_n;
// double tolgeo = 0.000040;
// Coefficients of trigonometric series
//
// ellipsoidal to spherical geographical, KW p .186 --187, (51) - (52)
// bg[1] = n * (-2 + n * (2 / 3 + n * (4 / 3 + n * (-82 / 45))));
// bg[2] = n ^ 2 * (5 / 3 + n * (-16 / 15 + n * (-13 / 9)));
// bg[3] = n ^ 3 * (-26 / 15 + n * 34 / 21);
// bg[4] = n ^ 4 * 1237 / 630;
//
// spherical to ellipsoidal geographical, KW p.190 --191, (61) - (62) % gb[1] = n * (2 + n * (-2 / 3 + n * (-2 + n * 116 / 45)));
// gb[2] = n ^ 2 * (7 / 3 + n * (-8 / 5 + n * (-227 / 45)));
// gb[3] = n ^ 3 * (56 / 15 + n * (-136 / 35));
// gb[4] = n ^ 4 * 4279 / 630;
//
// spherical to ellipsoidal N, E, KW p.196, (69) % gtu[1] = n * (1 / 2 + n * (-2 / 3 + n * (5 / 16 + n * 41 / 180)));
// gtu[2] = n ^ 2 * (13 / 48 + n * (-3 / 5 + n * 557 / 1440));
// gtu[3] = n ^ 3 * (61 / 240 + n * (-103 / 140));
// gtu[4] = n ^ 4 * 49561 / 161280;
//
// ellipsoidal to spherical N, E, KW p.194, (65) % utg[1] = n * (-1 / 2 + n * (2 / 3 + n * (-37 / 96 + n * 1 / 360)));
// utg[2] = n ^ 2 * (-1 / 48 + n * (-1 / 15 + n * 437 / 1440));
// utg[3] = n ^ 3 * (-17 / 480 + n * 37 / 840);
// utg[4] = n ^ 4 * (-4397 / 161280);
//
// With f = 1 / 297 we get
arma::colvec bg = {-3.37077907e-3,
4.73444769e-6,
-8.29914570e-9,
1.58785330e-11};
arma::colvec gb = {3.37077588e-3,
6.62769080e-6,
1.78718601e-8,
5.49266312e-11};
arma::colvec gtu = {8.41275991e-4,
7.67306686e-7,
1.21291230e-9,
2.48508228e-12};
arma::colvec utg = {-8.41276339e-4,
-5.95619298e-8,
-1.69485209e-10,
-2.20473896e-13};
// Ellipsoidal latitude, longitude to spherical latitude, longitude
bool neg_geo = false;
if (B < 0.0) neg_geo = true;
double Bg_r = fabs(B);
double res_clensin = clsin(bg, 4, 2.0 * Bg_r);
Bg_r = Bg_r + res_clensin;
L0 = L0 * STRP_PI / 180.0;
double Lg_r = L - L0;
// Spherical latitude, longitude to complementary spherical latitude % i.e.spherical N, E
double cos_BN = cos(Bg_r);
double Np = atan2(sin(Bg_r), cos(Lg_r) * cos_BN);
double Ep = atanh(sin(Lg_r) * cos_BN);
// Spherical normalized N, E to ellipsoidal N, E
Np = 2.0 * Np;
Ep = 2.0 * Ep;
double dN;
double dE;
clksin(gtu, 4, Np, Ep, &dN, &dE);
Np = Np / 2.0;
Ep = Ep / 2.0;
Np = Np + dN;
Ep = Ep + dE;
double N = Q_n * Np;
double E = Q_n * Ep + E0;
if (neg_geo)
{
N = -N + 20000000.0;
}
r_enu(0) = E;
r_enu(1) = N;
r_enu(2) = U;
}
double clsin(const arma::colvec &ar, int degree, double argument)
{
// Clenshaw summation of sinus of argument.
//
// result = clsin(ar, degree, argument);
//
// Originally written in Matlab by Kai Borre
// Implemented in C++ by J.Arribas
double cos_arg = 2.0 * cos(argument);
double hr1 = 0.0;
double hr = 0.0;
double hr2;
for (int t = degree; t > 0; t--)
{
hr2 = hr1;
hr1 = hr;
hr = ar(t - 1) + cos_arg * hr1 - hr2;
}
return (hr * sin(argument));
}
void clksin(const arma::colvec &ar, int degree, double arg_real, double arg_imag, double *re, double *im)
{
// Clenshaw summation of sinus with complex argument
// [re, im] = clksin(ar, degree, arg_real, arg_imag);
//
// Originally written in Matlab by Kai Borre
// Implemented in C++ by J.Arribas
double sin_arg_r = sin(arg_real);
double cos_arg_r = cos(arg_real);
double sinh_arg_i = sinh(arg_imag);
double cosh_arg_i = cosh(arg_imag);
double r = 2.0 * cos_arg_r * cosh_arg_i;
double i = -2.0 * sin_arg_r * sinh_arg_i;
double hr1 = 0.0;
double hr = 0.0;
double hi1 = 0.0;
double hi = 0.0;
double hi2;
double hr2;
for (int t = degree; t > 0; t--)
{
hr2 = hr1;
hr1 = hr;
hi2 = hi1;
hi1 = hi;
double z = ar(t - 1) + r * hr1 - i * hi - hr2;
hi = i * hr1 + r * hi1 - hi2;
hr = z;
}
r = sin_arg_r * cosh_arg_i;
i = cos_arg_r * sinh_arg_i;
*re = r * hr - i * hi;
*im = r * hi + i * hr;
}
int findUtmZone(double latitude_deg, double longitude_deg)
{
// Function finds the UTM zone number for given longitude and latitude.
// The longitude value must be between -180 (180 degree West) and 180 (180
// degree East) degree. The latitude must be within -80 (80 degree South) and
// 84 (84 degree North).
//
// utmZone = findUtmZone(latitude, longitude);
//
// Latitude and longitude must be in decimal degrees (e.g. 15.5 degrees not
// 15 deg 30 min).
//
// Originally written in Matlab by Darius Plausinaitis
// Implemented in C++ by J.Arribas
// Check value bounds
if ((longitude_deg > 180.0) || (longitude_deg < -180.0))
std::cout << "Longitude value exceeds limits (-180:180).\n";
if ((latitude_deg > 84.0) || (latitude_deg < -80.0))
std::cout << "Latitude value exceeds limits (-80:84).\n";
//
// Find zone
//
// Start at 180 deg west = -180 deg
int utmZone = floor((180 + longitude_deg) / 6) + 1;
// Correct zone numbers for particular areas
if (latitude_deg > 72.0)
{
// Corrections for zones 31 33 35 37
if ((longitude_deg >= 0.0) && (longitude_deg < 9.0))
{
utmZone = 31;
}
else if ((longitude_deg >= 9.0) && (longitude_deg < 21.0))
{
utmZone = 33;
}
else if ((longitude_deg >= 21.0) && (longitude_deg < 33.0))
{
utmZone = 35;
}
else if ((longitude_deg >= 33.0) && (longitude_deg < 42.0))
{
utmZone = 37;
}
}
else if ((latitude_deg >= 56.0) && (latitude_deg < 64.0))
{
// Correction for zone 32
if ((longitude_deg >= 3.0) && (longitude_deg < 12.0))
utmZone = 32;
}
return utmZone;
}

View File

@ -94,7 +94,7 @@ arma::mat Gravity_ECEF(const arma::vec &r_eb_e); //!< Calculates acceleration d
*/
arma::vec cart2geo(const arma::vec &XYZ, int elipsoid_selection);
arma::vec LLH_to_deg(arma::vec &LLH);
arma::vec LLH_to_deg(const arma::vec &LLH);
double degtorad(double angleInDegrees);
@ -104,7 +104,7 @@ double mstoknotsh(double MetersPerSeconds);
double mstokph(double Kph);
arma::vec CTM_to_Euler(arma::mat &C);
arma::vec CTM_to_Euler(const arma::mat &C);
arma::mat Euler_to_CTM(const arma::vec &eul);
@ -151,4 +151,34 @@ void Geo_to_ECEF(const arma::vec &LLH, const arma::vec &v_eb_n, const arma::mat
*/
void pv_Geo_to_ECEF(double L_b, double lambda_b, double h_b, const arma::vec &v_eb_n, arma::vec &r_eb_e, arma::vec &v_eb_e);
/*!
* \brief The Haversine formula determines the great-circle distance between two points on a sphere given their longitudes and latitudes.
*/
double great_circle_distance(double lat1, double lon1, double lat2, double lon2);
/*!
* \brief Transformation of ECEF (X,Y,Z) to (E,N,U) in UTM, zone 'zone'.
*/
void cart2utm(const arma::vec &r_eb_e, int zone, arma::vec &r_enu);
/*!
* \brief Function finds the UTM zone number for given longitude and latitude.
*/
int findUtmZone(double latitude_deg, double longitude_deg);
/*!
* \brief Clenshaw summation of sinus of argument.
*/
double clsin(const arma::colvec &ar, int degree, double argument);
/*!
* \brief Clenshaw summation of sinus with complex argument.
*/
void clksin(const arma::colvec &ar, int degree, double arg_real, double arg_imag, double *re, double *im);
#endif

View File

@ -42,5 +42,10 @@ DEFINE_bool(use_ref_motion_file, false, "Enable or disable the use of a referenc
DEFINE_int32(ref_motion_file_type, 1, "Type of reference motion file: 1- Spirent CSV motion file");
DEFINE_string(ref_motion_filename, std::string("motion.csv"), "Path and filename for the reference motion file");
DEFINE_string(pvt_solver_dump_filename, std::string("PVT_pvt.dat"), "Path and filename for the PVT solver binary dump file");
DEFINE_double(static_2D_error_m, 2.0, "Static scenario 2D (East, North) positioning error threshold [meters]");
DEFINE_double(static_3D_error_m, 5.0, "Static scenario 3D (East, North, Up) positioning error threshold [meters]");
DEFINE_double(accuracy_CEP, 2.0, "Static scenario 2D (East, North) accuracy Circular Error Position (CEP) threshold [meters]");
DEFINE_double(precision_SEP, 10.0, "Static scenario 3D (East, North, Up) precision Spherical Error Position (SEP) threshold [meters]");
DEFINE_double(dynamic_3D_position_RMSE, 10.0, "Dynamic scenario 3D (ECEF) accuracy RMSE threshold [meters]");
DEFINE_double(dynamic_3D_velocity_RMSE, 5.0, "Dynamic scenario 3D (ECEF) accuracy RMSE threshold [meters/second]");
#endif

View File

@ -32,6 +32,7 @@
* -------------------------------------------------------------------------
*/
#include "geofunctions.h"
#include "position_test_flags.h"
#include "rtklib_solver_dump_reader.h"
#include "spirent_motion_csv_dump_reader.h"
@ -54,6 +55,8 @@
#include <fstream>
#include <numeric>
#include <thread>
#include <armadillo>
#include <matio.h>
// For GPS NAVIGATION (L1)
concurrent_queue<Gps_Acq_Assist> global_gps_acq_assist_queue;
@ -67,6 +70,8 @@ public:
int configure_receiver();
int run_receiver();
void check_results();
bool save_mat_xy(std::vector<double>& x, std::vector<double>& y, std::string filename);
bool save_mat_x(std::vector<double>& x, std::string filename);
std::string config_filename_no_extension;
private:
@ -82,118 +87,13 @@ private:
std::string filename_rinex_obs = FLAGS_filename_rinex_obs;
std::string filename_raw_data = FLAGS_filename_raw_data;
void print_results(const std::vector<double>& east,
const std::vector<double>& north,
const std::vector<double>& up);
double compute_stdev_precision(const std::vector<double>& vec);
double compute_stdev_accuracy(const std::vector<double>& vec, double ref);
void geodetic2Enu(const double latitude, const double longitude, const double altitude,
double* east, double* north, double* up);
void geodetic2Ecef(const double latitude, const double longitude, const double altitude,
double* x, double* y, double* z);
void print_results(arma::mat R_eb_enu);
std::shared_ptr<InMemoryConfiguration> config;
std::shared_ptr<FileConfiguration> config_f;
std::string generated_kml_file;
};
void PositionSystemTest::geodetic2Ecef(const double latitude, const double longitude, const double altitude,
double* x, double* y, double* z)
{
const double a = 6378137.0; // WGS84
const double b = 6356752.314245; // WGS84
double aux_x, aux_y, aux_z;
// Convert to ECEF (See https://en.wikipedia.org/wiki/Geographic_coordinate_conversion#From_geodetic_to_ECEF_coordinates )
const double cLat = cos(latitude);
const double cLon = cos(longitude);
const double sLon = sin(longitude);
const double sLat = sin(latitude);
double N = std::pow(a, 2.0) / sqrt(std::pow(a, 2.0) * std::pow(cLat, 2.0) + std::pow(b, 2.0) * std::pow(sLat, 2.0));
aux_x = (N + altitude) * cLat * cLon;
aux_y = (N + altitude) * cLat * sLon;
aux_z = ((std::pow(b, 2.0) / std::pow(a, 2.0)) * N + altitude) * sLat;
*x = aux_x;
*y = aux_y;
*z = aux_z;
}
void PositionSystemTest::geodetic2Enu(double latitude, double longitude, double altitude,
double* east, double* north, double* up)
{
double x, y, z;
const double d2r = PI / 180.0;
geodetic2Ecef(latitude * d2r, longitude * d2r, altitude, &x, &y, &z);
double aux_north, aux_east, aux_down;
std::istringstream iss2(FLAGS_static_position);
std::string str_aux;
std::getline(iss2, str_aux, ',');
double ref_long = std::stod(str_aux);
std::getline(iss2, str_aux, ',');
double ref_lat = std::stod(str_aux);
std::getline(iss2, str_aux, '\n');
double ref_h = std::stod(str_aux);
double ref_x, ref_y, ref_z;
geodetic2Ecef(ref_lat * d2r, ref_long * d2r, ref_h, &ref_x, &ref_y, &ref_z);
double aux_x = x; // - ref_x;
double aux_y = y; // - ref_y;
double aux_z = z; // - ref_z;
// ECEF to NED matrix
double phiP = atan2(ref_z, sqrt(std::pow(ref_x, 2.0) + std::pow(ref_y, 2.0)));
const double sLat = sin(phiP);
const double sLon = sin(ref_long * d2r);
const double cLat = cos(phiP);
const double cLon = cos(ref_long * d2r);
aux_north = -aux_x * sLat * cLon - aux_y * sLon + aux_z * cLat * cLon;
aux_east = -aux_x * sLat * sLon + aux_y * cLon + aux_z * cLat * sLon;
aux_down = aux_x * cLat + aux_z * sLat;
*east = aux_east;
*north = aux_north;
*up = -aux_down;
}
double PositionSystemTest::compute_stdev_precision(const std::vector<double>& vec)
{
double sum__ = std::accumulate(vec.begin(), vec.end(), 0.0);
double mean__ = sum__ / vec.size();
double accum__ = 0.0;
std::for_each(std::begin(vec), std::end(vec), [&](const double d) {
accum__ += (d - mean__) * (d - mean__);
});
double stdev__ = std::sqrt(accum__ / (vec.size() - 1));
return stdev__;
}
double PositionSystemTest::compute_stdev_accuracy(const std::vector<double>& vec, const double ref)
{
const double mean__ = ref;
double accum__ = 0.0;
std::for_each(std::begin(vec), std::end(vec), [&](const double d) {
accum__ += (d - mean__) * (d - mean__);
});
double stdev__ = std::sqrt(accum__ / (vec.size() - 1));
return stdev__;
}
int PositionSystemTest::configure_generator()
{
// Configure signal generator
@ -261,23 +161,23 @@ int PositionSystemTest::configure_receiver()
const int grid_density = 16;
const float zero = 0.0;
const int number_of_channels = 12;
const int number_of_channels = 11;
const int in_acquisition = 1;
const float threshold = 0.01;
const float doppler_max = 8000.0;
const float doppler_step = 500.0;
const int max_dwells = 1;
const float threshold = 2.5;
const float doppler_max = 5000.0;
const float doppler_step = 250.0;
const int max_dwells = 10;
const int tong_init_val = 2;
const int tong_max_val = 10;
const int tong_max_dwells = 30;
const int coherent_integration_time_ms = 1;
const float pll_bw_hz = 30.0;
const float dll_bw_hz = 4.0;
const float pll_bw_hz = 35.0;
const float dll_bw_hz = 1.5;
const float early_late_space_chips = 0.5;
const float pll_bw_narrow_hz = 20.0;
const float dll_bw_narrow_hz = 2.0;
const float pll_bw_narrow_hz = 1.0;
const float dll_bw_narrow_hz = 0.1;
const int extend_correlation_ms = 1;
const int display_rate_ms = 500;
@ -307,7 +207,7 @@ int PositionSystemTest::configure_receiver()
// Set the Signal Conditioner
config->set_property("SignalConditioner.implementation", "Signal_Conditioner");
config->set_property("DataTypeAdapter.implementation", "Ibyte_To_Complex");
config->set_property("InputFilter.implementation", "Fir_Filter");
config->set_property("InputFilter.implementation", "Freq_Xlating_Fir_Filter");
config->set_property("InputFilter.dump", "false");
config->set_property("InputFilter.input_item_type", "gr_complex");
config->set_property("InputFilter.output_item_type", "gr_complex");
@ -324,7 +224,7 @@ int PositionSystemTest::configure_receiver()
config->set_property("InputFilter.ampl2_end", std::to_string(ampl2_end));
config->set_property("InputFilter.band1_error", std::to_string(band1_error));
config->set_property("InputFilter.band2_error", std::to_string(band2_error));
config->set_property("InputFilter.filter_type", "bandpass");
config->set_property("InputFilter.filter_type", "lowpass");
config->set_property("InputFilter.grid_density", std::to_string(grid_density));
config->set_property("InputFilter.sampling_frequency", std::to_string(sampling_rate_internal));
config->set_property("InputFilter.IF", std::to_string(zero));
@ -354,10 +254,10 @@ int PositionSystemTest::configure_receiver()
config->set_property("Acquisition_1C.dump", "false");
config->set_property("Acquisition_1C.dump_filename", "./acquisition");
config->set_property("Acquisition_1C.dump_channel", "1");
config->set_property("Acquisition_1C.blocking", "true");
// Set Tracking
config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_Tracking");
//config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_C_Aid_Tracking");
config->set_property("Tracking_1C.item_type", "gr_complex");
config->set_property("Tracking_1C.dump", "false");
config->set_property("Tracking_1C.dump_filename", "./tracking_ch_");
@ -368,6 +268,8 @@ int PositionSystemTest::configure_receiver()
config->set_property("Tracking_1C.pll_bw_narrow_hz", std::to_string(pll_bw_narrow_hz));
config->set_property("Tracking_1C.dll_bw_narrow_hz", std::to_string(dll_bw_narrow_hz));
config->set_property("Tracking_1C.extend_correlation_symbols", std::to_string(extend_correlation_ms));
//config->set_property("Tracking_1C.high_dyn", "true");
//config->set_property("Tracking_1C.smoother_length", "200");
// Set Telemetry
config->set_property("TelemetryDecoder_1C.implementation", "GPS_L1_CA_Telemetry_Decoder");
@ -380,7 +282,7 @@ int PositionSystemTest::configure_receiver()
// Set PVT
config->set_property("PVT.implementation", "RTKLIB_PVT");
config->set_property("PVT.positioning_mode", "Single");
config->set_property("PVT.positioning_mode", "PPP_Static");
config->set_property("PVT.output_rate_ms", std::to_string(output_rate_ms));
config->set_property("PVT.display_rate_ms", std::to_string(display_rate_ms));
config->set_property("PVT.dump_filename", "./PVT");
@ -457,15 +359,78 @@ int PositionSystemTest::run_receiver()
}
bool PositionSystemTest::save_mat_xy(std::vector<double>& x, std::vector<double>& y, std::string filename)
{
try
{
// WRITE MAT FILE
mat_t* matfp;
matvar_t* matvar;
filename.append(".mat");
std::cout << "save_mat_xy write " << filename << std::endl;
matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT5);
if (reinterpret_cast<int64_t*>(matfp) != NULL)
{
size_t dims[2] = {1, x.size()};
matvar = Mat_VarCreate("x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &x[0], 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &y[0], 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
}
else
{
std::cout << "save_mat_xy: error creating file" << std::endl;
}
Mat_Close(matfp);
return true;
}
catch (const std::exception& ex)
{
std::cout << "save_mat_xy: " << ex.what() << std::endl;
return false;
}
}
bool PositionSystemTest::save_mat_x(std::vector<double>& x, std::string filename)
{
try
{
// WRITE MAT FILE
mat_t* matfp;
matvar_t* matvar;
filename.append(".mat");
std::cout << "save_mat_x write " << filename << std::endl;
matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT5);
if (reinterpret_cast<int64_t*>(matfp) != NULL)
{
size_t dims[2] = {1, x.size()};
matvar = Mat_VarCreate("x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &x[0], 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
}
else
{
std::cout << "save_mat_x: error creating file" << std::endl;
}
Mat_Close(matfp);
return true;
}
catch (const std::exception& ex)
{
std::cout << "save_mat_x: " << ex.what() << std::endl;
return false;
}
}
void PositionSystemTest::check_results()
{
std::vector<double> pos_e;
std::vector<double> pos_n;
std::vector<double> pos_u;
arma::mat R_eb_e; //ECEF position (x,y,z) estimation in the Earth frame (Nx3)
arma::mat V_eb_e; //ECEF velocity (x,y,z) estimation in the Earth frame (Nx3)
arma::mat LLH; //Geodetic coordinates (latitude, longitude, height) estimation in WGS84 datum
arma::mat R_eb_e; //ECEF position (x,y,z) estimation in the Earth frame (Nx3)
arma::mat R_eb_enu; //ENU position (N,E,U) estimation in UTM (Nx3)
arma::mat V_eb_e; //ECEF velocity (x,y,z) estimation in the Earth frame (Nx3)
arma::mat LLH; //Geodetic coordinates (latitude, longitude, height) estimation in WGS84 datum
arma::vec receiver_time_s;
arma::mat ref_R_eb_e; //ECEF position (x,y,z) reference in the Earth frame (Nx3)
@ -481,10 +446,15 @@ void PositionSystemTest::check_results()
double ref_long = std::stod(str_aux);
std::getline(iss2, str_aux, '\n');
double ref_h = std::stod(str_aux);
double ref_e, ref_n, ref_u;
geodetic2Enu(ref_lat, ref_long, ref_h,
&ref_e, &ref_n, &ref_u);
int utm_zone = findUtmZone(ref_lat, ref_long);
arma::vec v_eb_n = {0.0, 0.0, 0.0};
arma::vec true_r_eb_e = {0.0, 0.0, 0.0};
arma::vec true_v_eb_e = {0.0, 0.0, 0.0};
pv_Geo_to_ECEF(degtorad(ref_lat), degtorad(ref_long), ref_h, v_eb_n, true_r_eb_e, true_v_eb_e);
ref_R_eb_e.insert_cols(0, true_r_eb_e);
arma::vec ref_r_enu = {0, 0, 0};
cart2utm(true_r_eb_e, utm_zone, ref_r_enu);
if (!FLAGS_use_pvt_solver_dump)
{
//fall back to read receiver KML output (position only)
@ -502,8 +472,8 @@ void PositionSystemTest::check_results()
if (found != std::string::npos) is_header = false;
}
bool is_data = true;
//read data
int64_t current_epoch = 0;
while (is_data)
{
if (!std::getline(myfile, line))
@ -531,18 +501,20 @@ void PositionSystemTest::check_results()
if (i == 2) h = value;
}
double north, east, up;
geodetic2Enu(lat, longitude, h, &east, &north, &up);
arma::vec tmp_v_ecef;
arma::vec tmp_r_ecef;
pv_Geo_to_ECEF(degtorad(lat), degtorad(longitude), h, arma::vec{0, 0, 0}, tmp_r_ecef, tmp_v_ecef);
R_eb_e.insert_cols(current_epoch, tmp_r_ecef);
arma::vec tmp_r_enu = {0, 0, 0};
cart2utm(tmp_r_ecef, utm_zone, tmp_r_enu);
R_eb_enu.insert_cols(current_epoch, tmp_r_enu);
// std::cout << "lat = " << lat << ", longitude = " << longitude << " h = " << h << std::endl;
// std::cout << "E = " << east << ", N = " << north << " U = " << up << std::endl;
pos_e.push_back(east);
pos_n.push_back(north);
pos_u.push_back(up);
// getchar();
}
}
myfile.close();
ASSERT_FALSE(pos_e.size() == 0) << "KML file is empty";
ASSERT_FALSE(R_eb_e.n_cols == 0) << "KML file is empty";
}
else
{
@ -550,33 +522,27 @@ void PositionSystemTest::check_results()
rtklib_solver_dump_reader pvt_reader;
pvt_reader.open_obs_file(FLAGS_pvt_solver_dump_filename);
int64_t n_epochs = pvt_reader.num_epochs();
R_eb_e = arma::zeros(n_epochs, 3);
V_eb_e = arma::zeros(n_epochs, 3);
LLH = arma::zeros(n_epochs, 3);
R_eb_e = arma::zeros(3, n_epochs);
V_eb_e = arma::zeros(3, n_epochs);
LLH = arma::zeros(3, n_epochs);
receiver_time_s = arma::zeros(n_epochs, 1);
int64_t current_epoch = 0;
while (pvt_reader.read_binary_obs())
{
double north, east, up;
geodetic2Enu(pvt_reader.latitude, pvt_reader.longitude, pvt_reader.height, &east, &north, &up);
// std::cout << "lat = " << pvt_reader.latitude << ", longitude = " << pvt_reader.longitude << " h = " << pvt_reader.height << std::endl;
// std::cout << "E = " << east << ", N = " << north << " U = " << up << std::endl;
pos_e.push_back(east);
pos_n.push_back(north);
pos_u.push_back(up);
// getchar();
// receiver_time_s(current_epoch) = static_cast<double>(pvt_reader.TOW_at_current_symbol_ms) / 1000.0;
receiver_time_s(current_epoch) = pvt_reader.RX_time - pvt_reader.clk_offset_s;
R_eb_e(current_epoch, 0) = pvt_reader.rr[0];
R_eb_e(current_epoch, 1) = pvt_reader.rr[1];
R_eb_e(current_epoch, 2) = pvt_reader.rr[2];
V_eb_e(current_epoch, 0) = pvt_reader.rr[3];
V_eb_e(current_epoch, 1) = pvt_reader.rr[4];
V_eb_e(current_epoch, 2) = pvt_reader.rr[5];
LLH(current_epoch, 0) = pvt_reader.latitude;
LLH(current_epoch, 1) = pvt_reader.longitude;
LLH(current_epoch, 2) = pvt_reader.height;
R_eb_e(0, current_epoch) = pvt_reader.rr[0];
R_eb_e(1, current_epoch) = pvt_reader.rr[1];
R_eb_e(2, current_epoch) = pvt_reader.rr[2];
V_eb_e(0, current_epoch) = pvt_reader.rr[3];
V_eb_e(1, current_epoch) = pvt_reader.rr[4];
V_eb_e(2, current_epoch) = pvt_reader.rr[5];
LLH(0, current_epoch) = pvt_reader.latitude;
LLH(1, current_epoch) = pvt_reader.longitude;
LLH(2, current_epoch) = pvt_reader.height;
arma::vec tmp_r_enu = {0, 0, 0};
cart2utm(R_eb_e.col(current_epoch), utm_zone, tmp_r_enu);
R_eb_enu.insert_cols(current_epoch, tmp_r_enu);
//debug check
// std::cout << "t1: " << pvt_reader.RX_time << std::endl;
@ -592,20 +558,40 @@ void PositionSystemTest::check_results()
if (FLAGS_static_scenario)
{
double sigma_E_2_precision = std::pow(compute_stdev_precision(pos_e), 2.0);
double sigma_N_2_precision = std::pow(compute_stdev_precision(pos_n), 2.0);
double sigma_U_2_precision = std::pow(compute_stdev_precision(pos_u), 2.0);
double sigma_E_2_precision = arma::var(R_eb_enu.row(0));
double sigma_N_2_precision = arma::var(R_eb_enu.row(1));
double sigma_U_2_precision = arma::var(R_eb_enu.row(2));
double sigma_E_2_accuracy = std::pow(compute_stdev_accuracy(pos_e, ref_e), 2.0);
double sigma_N_2_accuracy = std::pow(compute_stdev_accuracy(pos_n, ref_n), 2.0);
double sigma_U_2_accuracy = std::pow(compute_stdev_accuracy(pos_u, ref_u), 2.0);
arma::rowvec error_east_m;
error_east_m = R_eb_enu.row(0) - ref_r_enu(0);
double sigma_E_2_accuracy = arma::as_scalar(error_east_m * error_east_m.t());
sigma_E_2_accuracy = sigma_E_2_accuracy / error_east_m.n_elem;
double sum__e = std::accumulate(pos_e.begin(), pos_e.end(), 0.0);
double mean__e = sum__e / pos_e.size();
double sum__n = std::accumulate(pos_n.begin(), pos_n.end(), 0.0);
double mean__n = sum__n / pos_n.size();
double sum__u = std::accumulate(pos_u.begin(), pos_u.end(), 0.0);
double mean__u = sum__u / pos_u.size();
arma::rowvec error_north_m;
error_north_m = R_eb_enu.row(1) - ref_r_enu(1);
double sigma_N_2_accuracy = arma::as_scalar(error_north_m * error_north_m.t());
sigma_N_2_accuracy = sigma_N_2_accuracy / error_north_m.n_elem;
arma::rowvec error_up_m;
error_up_m = R_eb_enu.row(2) - ref_r_enu(2);
double sigma_U_2_accuracy = arma::as_scalar(error_up_m * error_up_m.t());
sigma_U_2_accuracy = sigma_U_2_accuracy / error_up_m.n_elem;
// arma::mat error_enu_mat = arma::zeros(3, error_east_m.n_elem);
// error_enu_mat.row(0) = error_east_m;
// error_enu_mat.row(1) = error_north_m;
// error_enu_mat.row(2) = error_up_m;
//
// arma::vec error_2D_m = arma::zeros(error_enu_mat.n_cols, 1);
// arma::vec error_3D_m = arma::zeros(error_enu_mat.n_cols, 1);
// for (uint64_t n = 0; n < error_enu_mat.n_cols; n++)
// {
// error_2D_m(n) = arma::norm(error_enu_mat.submat(0, n, 1, n));
// error_3D_m(n) = arma::norm(error_enu_mat.col(n));
// }
double static_2D_error_m = sqrt(pow(arma::mean(error_east_m), 2.0) + pow(arma::mean(error_north_m), 2.0));
double static_3D_error_m = sqrt(pow(arma::mean(error_east_m), 2.0) + pow(arma::mean(error_north_m), 2.0) + pow(arma::mean(error_up_m), 2.0));
std::stringstream stm;
std::ofstream position_test_file;
@ -613,25 +599,23 @@ void PositionSystemTest::check_results()
{
stm << "Configuration file: " << FLAGS_config_file_ptest << std::endl;
}
if (FLAGS_config_file_ptest.empty())
{
stm << "---- ACCURACY ----" << std::endl;
stm << "2DRMS = " << 2 * sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl;
stm << "DRMS = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl;
stm << "CEP = " << 0.62 * compute_stdev_accuracy(pos_n, ref_n) + 0.56 * compute_stdev_accuracy(pos_e, ref_e) << " [m]" << std::endl;
stm << "99% SAS = " << 1.122 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
stm << "90% SAS = " << 0.833 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
stm << "MRSE = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
stm << "SEP = " << 0.51 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
stm << "Bias 2D = " << sqrt(std::pow(abs(mean__e - ref_e), 2.0) + std::pow(abs(mean__n - ref_n), 2.0)) << " [m]" << std::endl;
stm << "Bias 3D = " << sqrt(std::pow(abs(mean__e - ref_e), 2.0) + std::pow(abs(mean__n - ref_n), 2.0) + std::pow(abs(mean__u - ref_u), 2.0)) << " [m]" << std::endl;
stm << std::endl;
}
stm << "---- PRECISION ----" << std::endl;
stm << "---- STATIC ACCURACY ----" << std::endl;
stm << "2DRMS = " << 2 * sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl;
stm << "DRMS = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl;
stm << "CEP = " << 0.62 * sqrt(sigma_N_2_accuracy) + 0.56 * sqrt(sigma_E_2_accuracy) << " [m]" << std::endl;
stm << "99% SAS = " << 1.122 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
stm << "90% SAS = " << 0.833 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
stm << "MRSE = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
stm << "SEP = " << 0.51 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
stm << "Static Bias 2D = " << static_2D_error_m << " [m]" << std::endl;
stm << "Static Bias 3D = " << static_3D_error_m << " [m]" << std::endl;
stm << std::endl;
stm << "---- STATIC PRECISION ----" << std::endl;
stm << "2DRMS = " << 2 * sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl;
stm << "DRMS = " << sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl;
stm << "CEP = " << 0.62 * compute_stdev_precision(pos_n) + 0.56 * compute_stdev_precision(pos_e) << " [m]" << std::endl;
stm << "CEP = " << 0.62 * sqrt(sigma_N_2_precision) + 0.56 * sqrt(sigma_E_2_precision) << " [m]" << std::endl;
stm << "99% SAS = " << 1.122 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl;
stm << "90% SAS = " << 0.833 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl;
stm << "MRSE = " << sqrt(sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl;
@ -647,12 +631,17 @@ void PositionSystemTest::check_results()
}
// Sanity Check
double accuracy_CEP = 0.62 * sqrt(sigma_N_2_accuracy) + 0.56 * sqrt(sigma_E_2_accuracy);
double precision_SEP = 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision);
ASSERT_LT(precision_SEP, 20.0);
EXPECT_LT(static_2D_error_m, FLAGS_static_2D_error_m);
EXPECT_LT(static_2D_error_m, FLAGS_static_2D_error_m);
ASSERT_LT(accuracy_CEP, FLAGS_accuracy_CEP);
ASSERT_LT(precision_SEP, FLAGS_precision_SEP);
if (FLAGS_plot_position_test == true)
{
print_results(pos_e, pos_n, pos_u);
print_results(R_eb_enu);
}
}
else
@ -661,56 +650,55 @@ void PositionSystemTest::check_results()
spirent_motion_csv_dump_reader ref_reader;
ref_reader.open_obs_file(FLAGS_ref_motion_filename);
int64_t n_epochs = ref_reader.num_epochs();
ref_R_eb_e = arma::zeros(n_epochs, 3);
ref_V_eb_e = arma::zeros(n_epochs, 3);
ref_LLH = arma::zeros(n_epochs, 3);
ref_R_eb_e = arma::zeros(3, n_epochs);
ref_V_eb_e = arma::zeros(3, n_epochs);
ref_LLH = arma::zeros(3, n_epochs);
ref_time_s = arma::zeros(n_epochs, 1);
int64_t current_epoch = 0;
while (ref_reader.read_csv_obs())
{
ref_time_s(current_epoch) = ref_reader.TOW_ms / 1000.0;
ref_R_eb_e(current_epoch, 0) = ref_reader.Pos_X;
ref_R_eb_e(current_epoch, 1) = ref_reader.Pos_Y;
ref_R_eb_e(current_epoch, 2) = ref_reader.Pos_Z;
ref_V_eb_e(current_epoch, 0) = ref_reader.Vel_X;
ref_V_eb_e(current_epoch, 1) = ref_reader.Vel_Y;
ref_V_eb_e(current_epoch, 2) = ref_reader.Vel_Z;
ref_LLH(current_epoch, 0) = ref_reader.Lat;
ref_LLH(current_epoch, 1) = ref_reader.Long;
ref_LLH(current_epoch, 2) = ref_reader.Height;
ref_R_eb_e(0, current_epoch) = ref_reader.Pos_X;
ref_R_eb_e(1, current_epoch) = ref_reader.Pos_Y;
ref_R_eb_e(2, current_epoch) = ref_reader.Pos_Z;
ref_V_eb_e(0, current_epoch) = ref_reader.Vel_X;
ref_V_eb_e(1, current_epoch) = ref_reader.Vel_Y;
ref_V_eb_e(2, current_epoch) = ref_reader.Vel_Z;
ref_LLH(0, current_epoch) = ref_reader.Lat;
ref_LLH(1, current_epoch) = ref_reader.Long;
ref_LLH(2, current_epoch) = ref_reader.Height;
current_epoch++;
}
//interpolation of reference data to receiver epochs timestamps
arma::mat ref_interp_R_eb_e = arma::zeros(R_eb_e.n_rows, 3);
arma::mat ref_interp_V_eb_e = arma::zeros(V_eb_e.n_rows, 3);
arma::mat ref_interp_LLH = arma::zeros(LLH.n_rows, 3);
arma::mat ref_interp_R_eb_e = arma::zeros(3, R_eb_e.n_cols);
arma::mat ref_interp_V_eb_e = arma::zeros(3, V_eb_e.n_cols);
arma::mat ref_interp_LLH = arma::zeros(3, LLH.n_cols);
arma::vec tmp_vector;
for (int n = 0; n < 3; n++)
{
arma::interp1(ref_time_s, ref_R_eb_e.col(n), receiver_time_s, tmp_vector);
ref_interp_R_eb_e.col(n) = tmp_vector;
arma::interp1(ref_time_s, ref_V_eb_e.col(n), receiver_time_s, tmp_vector);
ref_interp_V_eb_e.col(n) = tmp_vector;
arma::interp1(ref_time_s, ref_LLH.col(n), receiver_time_s, tmp_vector);
ref_interp_LLH.col(n) = tmp_vector;
arma::interp1(ref_time_s, ref_R_eb_e.row(n), receiver_time_s, tmp_vector);
ref_interp_R_eb_e.row(n) = tmp_vector.t();
arma::interp1(ref_time_s, ref_V_eb_e.row(n), receiver_time_s, tmp_vector);
ref_interp_V_eb_e.row(n) = tmp_vector.t();
arma::interp1(ref_time_s, ref_LLH.row(n), receiver_time_s, tmp_vector);
ref_interp_LLH.row(n) = tmp_vector.t();
}
//compute error vectors
arma::mat error_R_eb_e = arma::zeros(R_eb_e.n_rows, 3);
arma::mat error_V_eb_e = arma::zeros(V_eb_e.n_rows, 3);
arma::mat error_LLH = arma::zeros(LLH.n_rows, 3);
arma::mat error_R_eb_e = arma::zeros(3, R_eb_e.n_cols);
arma::mat error_V_eb_e = arma::zeros(3, V_eb_e.n_cols);
arma::mat error_LLH = arma::zeros(3, LLH.n_cols);
error_R_eb_e = R_eb_e - ref_interp_R_eb_e;
error_V_eb_e = V_eb_e - ref_interp_V_eb_e;
error_LLH = LLH - ref_interp_LLH;
arma::vec error_module_R_eb_e = arma::zeros(R_eb_e.n_rows, 1);
arma::vec error_module_V_eb_e = arma::zeros(V_eb_e.n_rows, 1);
for (uint64_t n = 0; n < R_eb_e.n_rows; n++)
arma::vec error_module_R_eb_e = arma::zeros(R_eb_e.n_cols, 1);
arma::vec error_module_V_eb_e = arma::zeros(V_eb_e.n_cols, 1);
for (uint64_t n = 0; n < R_eb_e.n_cols; n++)
{
error_module_R_eb_e(n) = arma::norm(error_R_eb_e.row(n));
error_module_V_eb_e(n) = arma::norm(error_V_eb_e.row(n));
error_module_R_eb_e(n) = arma::norm(error_R_eb_e.col(n));
error_module_V_eb_e(n) = arma::norm(error_V_eb_e.col(n));
}
//Error statistics
arma::vec tmp_vec;
//RMSE, Mean, Variance and peaks
@ -749,103 +737,117 @@ void PositionSystemTest::check_results()
<< " [m/s]" << std::endl;
std::cout.precision(ss);
//plots
Gnuplot g1("points");
if (FLAGS_show_plots)
// plots
if (FLAGS_plot_position_test == true)
{
g1.showonscreen(); // window output
}
else
{
g1.disablescreen();
}
g1.set_title("3D ECEF error coordinates");
g1.set_grid();
//conversion between arma::vec and std:vector
std::vector<double> X(error_R_eb_e.colptr(0), error_R_eb_e.colptr(0) + error_R_eb_e.n_rows);
std::vector<double> Y(error_R_eb_e.colptr(1), error_R_eb_e.colptr(1) + error_R_eb_e.n_rows);
std::vector<double> Z(error_R_eb_e.colptr(2), error_R_eb_e.colptr(2) + error_R_eb_e.n_rows);
const std::string gnuplot_executable(FLAGS_gnuplot_executable);
if (!gnuplot_executable.empty())
{
Gnuplot g1("points");
if (FLAGS_show_plots)
{
g1.showonscreen(); // window output
}
else
{
g1.disablescreen();
}
g1.set_title("3D ECEF error coordinates");
g1.set_grid();
//conversion between arma::vec and std:vector
arma::rowvec arma_vec_error_x = error_R_eb_e.row(0);
arma::rowvec arma_vec_error_y = error_R_eb_e.row(1);
arma::rowvec arma_vec_error_z = error_R_eb_e.row(2);
g1.cmd("set key box opaque");
g1.plot_xyz(X, Y, Z, "ECEF 3D error");
g1.set_legend();
if (FLAGS_config_file_ptest.empty())
{
g1.savetops("ECEF_3d_error");
}
else
{
g1.savetops("ECEF_3d_error_" + config_filename_no_extension);
}
arma::vec time_vector_from_start_s = receiver_time_s - receiver_time_s(0);
Gnuplot g3("linespoints");
if (FLAGS_show_plots)
{
g3.showonscreen(); // window output
}
else
{
g3.disablescreen();
}
g3.set_title("3D Position estimation error module [m]");
g3.set_grid();
g3.set_xlabel("Receiver epoch time from first valid PVT [s]");
g3.set_ylabel("3D Position error [m]");
//conversion between arma::vec and std:vector
std::vector<double> error_vec(error_module_R_eb_e.colptr(0), error_module_R_eb_e.colptr(0) + error_module_R_eb_e.n_rows);
g3.cmd("set key box opaque");
g3.plot_xy(time_vector_from_start_s, error_vec, "Position 3D error");
double mean3d = std::accumulate(error_vec.begin(), error_vec.end(), 0.0) / error_vec.size();
std::vector<double> error_mean(error_module_R_eb_e.n_rows, mean3d);
g3.set_style("lines");
g3.plot_xy(time_vector_from_start_s, error_mean, "Mean");
g3.set_legend();
if (FLAGS_config_file_ptest.empty())
{
g3.savetops("Position_3d_error");
}
else
{
g3.savetops("Position_3d_error_" + config_filename_no_extension);
std::vector<double> X(arma_vec_error_x.colptr(0), arma_vec_error_x.colptr(0) + arma_vec_error_x.n_rows);
std::vector<double> Y(arma_vec_error_y.colptr(0), arma_vec_error_y.colptr(0) + arma_vec_error_y.n_rows);
std::vector<double> Z(arma_vec_error_z.colptr(0), arma_vec_error_z.colptr(0) + arma_vec_error_z.n_rows);
g1.cmd("set key box opaque");
g1.plot_xyz(X, Y, Z, "ECEF 3D error");
g1.set_legend();
if (FLAGS_config_file_ptest.empty())
{
g1.savetops("ECEF_3d_error");
}
else
{
g1.savetops("ECEF_3d_error_" + config_filename_no_extension);
}
arma::vec time_vector_from_start_s = receiver_time_s - receiver_time_s(0);
Gnuplot g3("linespoints");
if (FLAGS_show_plots)
{
g3.showonscreen(); // window output
}
else
{
g3.disablescreen();
}
g3.set_title("3D Position estimation error module [m]");
g3.set_grid();
g3.set_xlabel("Receiver epoch time from first valid PVT [s]");
g3.set_ylabel("3D Position error [m]");
//conversion between arma::vec and std:vector
std::vector<double> error_vec(error_module_R_eb_e.colptr(0), error_module_R_eb_e.colptr(0) + error_module_R_eb_e.n_rows);
g3.cmd("set key box opaque");
g3.plot_xy(time_vector_from_start_s, error_vec, "Position 3D error");
double mean3d = std::accumulate(error_vec.begin(), error_vec.end(), 0.0) / error_vec.size();
std::vector<double> error_mean(error_module_R_eb_e.n_rows, mean3d);
g3.set_style("lines");
g3.plot_xy(time_vector_from_start_s, error_mean, "Mean");
g3.set_legend();
if (FLAGS_config_file_ptest.empty())
{
g3.savetops("Position_3d_error");
}
else
{
g3.savetops("Position_3d_error_" + config_filename_no_extension);
}
Gnuplot g4("linespoints");
if (FLAGS_show_plots)
{
g4.showonscreen(); // window output
}
else
{
g4.disablescreen();
}
g4.set_title("3D Velocity estimation error module [m/s]");
g4.set_grid();
g4.set_xlabel("Receiver epoch time from first valid PVT [s]");
g4.set_ylabel("3D Velocity error [m/s]");
//conversion between arma::vec and std:vector
std::vector<double> error_vec2(error_module_V_eb_e.colptr(0), error_module_V_eb_e.colptr(0) + error_module_V_eb_e.n_rows);
g4.cmd("set key box opaque");
g4.plot_xy(time_vector_from_start_s, error_vec2, "Velocity 3D error");
double mean3dv = std::accumulate(error_vec2.begin(), error_vec2.end(), 0.0) / error_vec2.size();
std::vector<double> error_mean_v(error_module_V_eb_e.n_rows, mean3dv);
g4.set_style("lines");
g4.plot_xy(time_vector_from_start_s, error_mean_v, "Mean");
g4.set_legend();
if (FLAGS_config_file_ptest.empty())
{
g4.savetops("Velocity_3d_error");
}
else
{
g4.savetops("Velocity_3d_error_" + config_filename_no_extension);
}
}
}
Gnuplot g4("linespoints");
if (FLAGS_show_plots)
{
g4.showonscreen(); // window output
}
else
{
g4.disablescreen();
}
g4.set_title("3D Velocity estimation error module [m/s]");
g4.set_grid();
g4.set_xlabel("Receiver epoch time from first valid PVT [s]");
g4.set_ylabel("3D Velocity error [m/s]");
//conversion between arma::vec and std:vector
std::vector<double> error_vec2(error_module_V_eb_e.colptr(0), error_module_V_eb_e.colptr(0) + error_module_V_eb_e.n_rows);
g4.cmd("set key box opaque");
g4.plot_xy(time_vector_from_start_s, error_vec2, "Velocity 3D error");
double mean3dv = std::accumulate(error_vec2.begin(), error_vec2.end(), 0.0) / error_vec2.size();
std::vector<double> error_mean_v(error_module_V_eb_e.n_rows, mean3dv);
g4.set_style("lines");
g4.plot_xy(time_vector_from_start_s, error_mean_v, "Mean");
g4.set_legend();
if (FLAGS_config_file_ptest.empty())
{
g4.savetops("Velocity_3d_error");
}
else
{
g4.savetops("Velocity_3d_error_" + config_filename_no_extension);
}
//ERROR CHECK
//todo: reduce the error tolerance or enable the option to pass the error tolerance by parameter
EXPECT_LT(rmse_R_eb_e, FLAGS_dynamic_3D_position_RMSE); //3D RMS positioning error less than 10 meters
EXPECT_LT(rmse_V_eb_e, FLAGS_dynamic_3D_velocity_RMSE); //3D RMS speed error less than 5 meters/s (18 km/h)
}
}
void PositionSystemTest::print_results(const std::vector<double>& east,
const std::vector<double>& north,
const std::vector<double>& up)
void PositionSystemTest::print_results(arma::mat R_eb_enu)
{
const std::string gnuplot_executable(FLAGS_gnuplot_executable);
if (gnuplot_executable.empty())
@ -856,29 +858,40 @@ void PositionSystemTest::print_results(const std::vector<double>& east,
}
else
{
double sigma_E_2_precision = std::pow(compute_stdev_precision(east), 2.0);
double sigma_N_2_precision = std::pow(compute_stdev_precision(north), 2.0);
double sigma_U_2_precision = std::pow(compute_stdev_precision(up), 2.0);
double sigma_E_2_precision = arma::var(R_eb_enu.row(0));
double sigma_N_2_precision = arma::var(R_eb_enu.row(1));
double sigma_U_2_precision = arma::var(R_eb_enu.row(2));
double mean_east = std::accumulate(east.begin(), east.end(), 0.0) / east.size();
double mean_north = std::accumulate(north.begin(), north.end(), 0.0) / north.size();
double mean_east = arma::mean(R_eb_enu.row(0));
double mean_north = arma::mean(R_eb_enu.row(1));
double mean_up = arma::mean(R_eb_enu.row(2));
auto it_max_east = std::max_element(std::begin(east), std::end(east));
auto it_min_east = std::min_element(std::begin(east), std::end(east));
auto it_max_north = std::max_element(std::begin(north), std::end(north));
auto it_min_north = std::min_element(std::begin(north), std::end(north));
auto it_max_up = std::max_element(std::begin(up), std::end(up));
auto it_min_up = std::min_element(std::begin(up), std::end(up));
double it_max_east = arma::max(R_eb_enu.row(0) - mean_east);
double it_min_east = arma::min(R_eb_enu.row(0) - mean_east);
auto east_range = std::max(*it_max_east, std::abs(*it_min_east));
auto north_range = std::max(*it_max_north, std::abs(*it_min_north));
auto up_range = std::max(*it_max_up, std::abs(*it_min_up));
double it_max_north = arma::max(R_eb_enu.row(1) - mean_north);
double it_min_north = arma::min(R_eb_enu.row(1) - mean_north);
double it_max_up = arma::max(R_eb_enu.row(2) - mean_up);
double it_min_up = arma::min(R_eb_enu.row(2) - mean_up);
double east_range = std::max(it_max_east, std::abs(it_min_east));
double north_range = std::max(it_max_north, std::abs(it_min_north));
double up_range = std::max(it_max_up, std::abs(it_min_up));
double range = std::max(east_range, north_range) * 1.1;
double range_3d = std::max(std::max(east_range, north_range), up_range) * 1.1;
double two_drms = 2 * sqrt(sigma_E_2_precision + sigma_N_2_precision);
double ninty_sas = 0.833 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision);
arma::rowvec arma_east = R_eb_enu.row(0) - mean_east;
arma::rowvec arma_north = R_eb_enu.row(1) - mean_north;
arma::rowvec arma_up = R_eb_enu.row(2) - mean_up;
std::vector<double> east(arma_east.colptr(0), arma_east.row(0).colptr(0) + arma_east.row(0).n_cols);
std::vector<double> north(arma_north.colptr(0), arma_north.colptr(0) + arma_north.n_cols);
std::vector<double> up(arma_up.colptr(0), arma_up.colptr(0) + arma_up.n_cols);
try
{
boost::filesystem::path p(gnuplot_executable);
@ -902,6 +915,7 @@ void PositionSystemTest::print_results(const std::vector<double>& east,
g1.cmd("set xrange [-" + std::to_string(range) + ":" + std::to_string(range) + "]");
g1.cmd("set yrange [-" + std::to_string(range) + ":" + std::to_string(range) + "]");
g1.plot_xy(east, north, "2D Position Fixes");
g1.set_style("lines").plot_circle(mean_east, mean_north, two_drms, "2DRMS");
g1.set_style("lines").plot_circle(mean_east, mean_north, two_drms / 2.0, "DRMS");

View File

@ -171,6 +171,7 @@ DECLARE_string(log_dir);
#include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc"
#include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_kf_tracking_test.cc"
#include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc"
#include "unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc"
#if ENABLE_FPGA
#include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc"
#endif

View File

@ -32,6 +32,7 @@ include_directories(
${GLOG_INCLUDE_DIRS}
${GFlags_INCLUDE_DIRS}
${MATIO_INCLUDE_DIRS}
${GNURADIO_RUNTIME_INCLUDE_DIRS}
)
@ -41,5 +42,7 @@ add_library(signal_processing_testing_lib ${SIGNAL_PROCESSING_TESTING_LIB_SOURCE
source_group(Headers FILES ${SIGNAL_PROCESSING_TESTING_LIB_HEADERS})
if(NOT MATIO_FOUND)
add_dependencies(signal_processing_testing_lib matio-${GNSSSDR_MATIO_LOCAL_VERSION})
endif(NOT MATIO_FOUND)
add_dependencies(signal_processing_testing_lib matio-${GNSSSDR_MATIO_LOCAL_VERSION} glog-${glog_RELEASE})
else(NOT MATIO_FOUND)
add_dependencies(signal_processing_testing_lib glog-${glog_RELEASE})
endif(NOT MATIO_FOUND)

View File

@ -45,7 +45,9 @@ bool tracking_dump_reader::read_binary_obs()
d_dump_file.read(reinterpret_cast<char *>(&PRN_start_sample_count), sizeof(uint64_t));
d_dump_file.read(reinterpret_cast<char *>(&acc_carrier_phase_rad), sizeof(float));
d_dump_file.read(reinterpret_cast<char *>(&carrier_doppler_hz), sizeof(float));
d_dump_file.read(reinterpret_cast<char *>(&carrier_doppler_rate_hz_s), sizeof(float));
d_dump_file.read(reinterpret_cast<char *>(&code_freq_chips), sizeof(float));
d_dump_file.read(reinterpret_cast<char *>(&code_freq_rate_chips), sizeof(float));
d_dump_file.read(reinterpret_cast<char *>(&carr_error_hz), sizeof(float));
d_dump_file.read(reinterpret_cast<char *>(&carr_error_filt_hz), sizeof(float));
d_dump_file.read(reinterpret_cast<char *>(&code_error_chips), sizeof(float));
@ -83,7 +85,7 @@ int64_t tracking_dump_reader::num_epochs()
{
std::ifstream::pos_type size;
int number_of_double_vars = 1;
int number_of_float_vars = 17;
int number_of_float_vars = 19;
int epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars +
sizeof(float) * number_of_float_vars + sizeof(unsigned int);
std::ifstream tmpfile(d_dump_filename.c_str(), std::ios::binary | std::ios::ate);

View File

@ -63,7 +63,9 @@ public:
// carrier and code frequency
float carrier_doppler_hz;
float carrier_doppler_rate_hz_s;
float code_freq_chips;
float code_freq_rate_chips;
// PLL commands
float carr_error_hz;

View File

@ -236,6 +236,12 @@ public:
arma::mat& measured_ch1,
std::string data_title);
void check_results_duplicated_satellite(
arma::mat& measured_sat1,
arma::mat& measured_sat2,
int ch_id,
std::string data_title);
HybridObservablesTest()
{
factory = std::make_shared<GNSSBlockFactory>();
@ -255,7 +261,9 @@ public:
double DLL_wide_bw_hz,
double PLL_narrow_bw_hz,
double DLL_narrow_bw_hz,
int extend_correlation_symbols);
int extend_correlation_symbols,
uint32_t smoother_length,
bool high_dyn);
gr::top_block_sptr top_block;
std::shared_ptr<GNSSBlockFactory> factory;
@ -535,10 +543,17 @@ void HybridObservablesTest::configure_receiver(
double DLL_wide_bw_hz,
double PLL_narrow_bw_hz,
double DLL_narrow_bw_hz,
int extend_correlation_symbols)
int extend_correlation_symbols,
uint32_t smoother_length,
bool high_dyn)
{
config = std::make_shared<InMemoryConfiguration>();
config->set_property("Tracking.dump", "true");
if (high_dyn)
config->set_property("Tracking.high_dyn", "true");
else
config->set_property("Tracking.high_dyn", "false");
config->set_property("Tracking.smoother_length", std::to_string(smoother_length));
config->set_property("Tracking.dump_filename", "./tracking_ch_");
config->set_property("Tracking.implementation", implementation);
config->set_property("Tracking.item_type", "gr_complex");
@ -645,6 +660,8 @@ void HybridObservablesTest::configure_receiver(
std::cout << "pll_bw_narrow_hz: " << config->property("Tracking.pll_bw_narrow_hz", 0.0) << " Hz\n";
std::cout << "dll_bw_narrow_hz: " << config->property("Tracking.dll_bw_narrow_hz", 0.0) << " Hz\n";
std::cout << "extend_correlation_symbols: " << config->property("Tracking.extend_correlation_symbols", 0) << " Symbols\n";
std::cout << "high_dyn: " << config->property("Tracking.high_dyn", false) << "\n";
std::cout << "smoother_length: " << config->property("Tracking.smoother_length", 0) << "\n";
std::cout << "*****************************************\n";
std::cout << "*****************************************\n";
}
@ -987,6 +1004,256 @@ void HybridObservablesTest::check_results_carrier_doppler(
ASSERT_LT(rmse_ch0, 30);
}
void HybridObservablesTest::check_results_duplicated_satellite(
arma::mat& measured_sat1,
arma::mat& measured_sat2,
int ch_id,
std::string data_title)
{
//1. True value interpolation to match the measurement times
//define the common measured time interval
double t0_sat1 = measured_sat1(0, 0);
int size1 = measured_sat1.col(0).n_rows;
double t1_sat1 = measured_sat1(size1 - 1, 0);
double t0_sat2 = measured_sat2(0, 0);
int size2 = measured_sat2.col(0).n_rows;
double t1_sat2 = measured_sat2(size2 - 1, 0);
double t0;
double t1;
if (t0_sat1 > t0_sat2)
{
t0 = t0_sat1;
}
else
{
t0 = t0_sat2;
}
if (t1_sat1 > t1_sat2)
{
t1 = t1_sat2;
}
else
{
t1 = t1_sat1;
}
arma::vec t = arma::linspace<arma::vec>(t0, t1, floor((t1 - t0) * 1e3));
//conversion between arma::vec and std:vector
arma::vec t_from_start = arma::linspace<arma::vec>(0, t1 - t0, floor((t1 - t0) * 1e3));
std::vector<double> time_vector(t_from_start.colptr(0), t_from_start.colptr(0) + t_from_start.n_rows);
//Doppler
arma::vec meas_sat1_doppler_interp;
arma::interp1(measured_sat1.col(0), measured_sat1.col(2), t, meas_sat1_doppler_interp);
arma::vec meas_sat2_doppler_interp;
arma::interp1(measured_sat2.col(0), measured_sat2.col(2), t, meas_sat2_doppler_interp);
//Carrier Phase
arma::vec meas_sat1_carrier_phase_interp;
arma::vec meas_sat2_carrier_phase_interp;
arma::interp1(measured_sat1.col(0), measured_sat1.col(3), t, meas_sat1_carrier_phase_interp);
arma::interp1(measured_sat2.col(0), measured_sat2.col(3), t, meas_sat2_carrier_phase_interp);
// generate double difference accumulated carrier phases
//compute error without the accumulated carrier phase offsets (which depends on the receiver starting time)
arma::vec delta_measured_carrier_phase_cycles = (meas_sat1_carrier_phase_interp - meas_sat1_carrier_phase_interp(0)) - (meas_sat2_carrier_phase_interp - meas_sat2_carrier_phase_interp(0));
//Pseudoranges
arma::vec meas_sat1_dist_interp;
arma::vec meas_sat2_dist_interp;
arma::interp1(measured_sat1.col(0), measured_sat1.col(4), t, meas_sat1_dist_interp);
arma::interp1(measured_sat2.col(0), measured_sat2.col(4), t, meas_sat2_dist_interp);
// generate delta pseudoranges
arma::vec delta_measured_dist_m = meas_sat1_dist_interp - meas_sat2_dist_interp;
//Carrier Doppler error
//2. RMSE
arma::vec err_ch0_hz;
//compute error
err_ch0_hz = meas_sat1_doppler_interp - meas_sat2_doppler_interp;
//save matlab file for further analysis
std::vector<double> tmp_vector_common_time_s(t.colptr(0),
t.colptr(0) + t.n_rows);
std::vector<double> tmp_vector_err_ch0_hz(err_ch0_hz.colptr(0),
err_ch0_hz.colptr(0) + err_ch0_hz.n_rows);
save_mat_xy(tmp_vector_common_time_s, tmp_vector_err_ch0_hz, std::string("measured_doppler_error_ch_" + std::to_string(ch_id)));
//compute statistics
arma::vec err2_ch0 = arma::square(err_ch0_hz);
double rmse_ch0 = sqrt(arma::mean(err2_ch0));
//3. Mean err and variance
double error_mean_ch0 = arma::mean(err_ch0_hz);
double error_var_ch0 = arma::var(err_ch0_hz);
// 4. Peaks
double max_error_ch0 = arma::max(err_ch0_hz);
double min_error_ch0 = arma::min(err_ch0_hz);
//5. report
std::streamsize ss = std::cout.precision();
std::cout << std::setprecision(10) << data_title << "Carrier Doppler RMSE = "
<< rmse_ch0 << ", mean = " << error_mean_ch0
<< ", stdev = " << sqrt(error_var_ch0)
<< " (max,min) = " << max_error_ch0
<< "," << min_error_ch0
<< " [Hz]" << std::endl;
std::cout.precision(ss);
//plots
if (FLAGS_show_plots)
{
Gnuplot g3("linespoints");
g3.set_title(data_title + "Carrier Doppler error [Hz]");
g3.set_grid();
g3.set_xlabel("Time [s]");
g3.set_ylabel("Carrier Doppler error [Hz]");
//conversion between arma::vec and std:vector
std::vector<double> error_vec(err_ch0_hz.colptr(0), err_ch0_hz.colptr(0) + err_ch0_hz.n_rows);
g3.cmd("set key box opaque");
g3.plot_xy(time_vector, error_vec,
"Carrier Doppler error");
g3.set_legend();
g3.savetops(data_title + "Carrier_doppler_error");
g3.showonscreen(); // window output
}
//check results against the test tolerance
EXPECT_LT(error_mean_ch0, 5);
EXPECT_GT(error_mean_ch0, -5);
//assuming PLL BW=35
EXPECT_LT(error_var_ch0, 250);
EXPECT_LT(max_error_ch0, 100);
EXPECT_GT(min_error_ch0, -100);
EXPECT_LT(rmse_ch0, 30);
//Carrier Phase error
//2. RMSE
arma::vec err_carrier_phase;
err_carrier_phase = delta_measured_carrier_phase_cycles;
//save matlab file for further analysis
std::vector<double> tmp_vector_err_carrier_phase(err_carrier_phase.colptr(0),
err_carrier_phase.colptr(0) + err_carrier_phase.n_rows);
save_mat_xy(tmp_vector_common_time_s, tmp_vector_err_carrier_phase, std::string("measured_carrier_phase_error_ch_" + std::to_string(ch_id)));
arma::vec err2_carrier_phase = arma::square(err_carrier_phase);
double rmse_carrier_phase = sqrt(arma::mean(err2_carrier_phase));
//3. Mean err and variance
double error_mean_carrier_phase = arma::mean(err_carrier_phase);
double error_var_carrier_phase = arma::var(err_carrier_phase);
// 4. Peaks
double max_error_carrier_phase = arma::max(err_carrier_phase);
double min_error_carrier_phase = arma::min(err_carrier_phase);
//5. report
ss = std::cout.precision();
std::cout << std::setprecision(10) << data_title << "Carrier Phase RMSE = "
<< rmse_carrier_phase << ", mean = " << error_mean_carrier_phase
<< ", stdev = " << sqrt(error_var_carrier_phase)
<< " (max,min) = " << max_error_carrier_phase
<< "," << min_error_carrier_phase
<< " [Cycles]" << std::endl;
std::cout.precision(ss);
//plots
if (FLAGS_show_plots)
{
Gnuplot g3("linespoints");
g3.set_title(data_title + "Carrier Phase error [Cycles]");
g3.set_grid();
g3.set_xlabel("Time [s]");
g3.set_ylabel("Carrier Phase error [Cycles]");
//conversion between arma::vec and std:vector
std::vector<double> range_error_m(err_carrier_phase.colptr(0), err_carrier_phase.colptr(0) + err_carrier_phase.n_rows);
g3.cmd("set key box opaque");
g3.plot_xy(time_vector, range_error_m,
"Carrier Phase error");
g3.set_legend();
g3.savetops(data_title + "duplicated_satellite_carrier_phase_error");
g3.showonscreen(); // window output
}
//check results against the test tolerance
EXPECT_LT(rmse_carrier_phase, 0.25);
EXPECT_LT(error_mean_carrier_phase, 0.2);
EXPECT_GT(error_mean_carrier_phase, -0.2);
EXPECT_LT(error_var_carrier_phase, 0.5);
EXPECT_LT(max_error_carrier_phase, 0.5);
EXPECT_GT(min_error_carrier_phase, -0.5);
//Pseudorange error
//2. RMSE
arma::vec err_pseudorange;
err_pseudorange = delta_measured_dist_m;
//save matlab file for further analysis
std::vector<double> tmp_vector_err_pseudorange(err_pseudorange.colptr(0),
err_pseudorange.colptr(0) + err_pseudorange.n_rows);
save_mat_xy(tmp_vector_common_time_s, tmp_vector_err_pseudorange, std::string("measured_pr_error_ch_" + std::to_string(ch_id)));
arma::vec err2_pseudorange = arma::square(err_pseudorange);
double rmse_pseudorange = sqrt(arma::mean(err2_pseudorange));
//3. Mean err and variance
double error_mean_pseudorange = arma::mean(err_pseudorange);
double error_var_pseudorange = arma::var(err_pseudorange);
// 4. Peaks
double max_error_pseudorange = arma::max(err_pseudorange);
double min_error_pseudorange = arma::min(err_pseudorange);
//5. report
ss = std::cout.precision();
std::cout << std::setprecision(10) << data_title << "Pseudorange RMSE = "
<< rmse_pseudorange << ", mean = " << error_mean_pseudorange
<< ", stdev = " << sqrt(error_var_pseudorange)
<< " (max,min) = " << max_error_pseudorange
<< "," << min_error_pseudorange
<< " [meters]" << std::endl;
std::cout.precision(ss);
//plots
if (FLAGS_show_plots)
{
Gnuplot g3("linespoints");
g3.set_title(data_title + "Pseudorange error [m]");
g3.set_grid();
g3.set_xlabel("Time [s]");
g3.set_ylabel("Pseudorange error [m]");
//conversion between arma::vec and std:vector
std::vector<double> range_error_m(err_pseudorange.colptr(0), err_pseudorange.colptr(0) + err_pseudorange.n_rows);
g3.cmd("set key box opaque");
g3.plot_xy(time_vector, range_error_m,
"Pseudorrange error");
g3.set_legend();
g3.savetops(data_title + "duplicated_satellite_pseudorrange_error");
g3.showonscreen(); // window output
}
//check results against the test tolerance
EXPECT_LT(rmse_pseudorange, 3.0);
EXPECT_LT(error_mean_pseudorange, 1.0);
EXPECT_GT(error_mean_pseudorange, -1.0);
EXPECT_LT(error_var_pseudorange, 10.0);
EXPECT_LT(max_error_pseudorange, 10.0);
EXPECT_GT(min_error_pseudorange, -10.0);
}
bool HybridObservablesTest::save_mat_xy(std::vector<double>& x, std::vector<double>& y, std::string filename)
{
try
@ -1293,7 +1560,9 @@ TEST_F(HybridObservablesTest, ValidationOfResults)
FLAGS_DLL_bw_hz_start,
FLAGS_PLL_narrow_bw_hz,
FLAGS_DLL_narrow_bw_hz,
FLAGS_extend_correlation_symbols);
FLAGS_extend_correlation_symbols,
FLAGS_smoother_length,
FLAGS_high_dyn);
for (unsigned int n = 0; n < gnss_synchro_vec.size(); n++)
@ -1535,7 +1804,6 @@ TEST_F(HybridObservablesTest, ValidationOfResults)
}
}
//Cut measurement tail zeros
arma::uvec index;
for (unsigned int n = 0; n < measured_obs_vec.size(); n++)
@ -1548,9 +1816,7 @@ TEST_F(HybridObservablesTest, ValidationOfResults)
}
//Cut measurement initial transitory of the measurements
double initial_transitory_s = FLAGS_skip_obs_transitory_s;
for (unsigned int n = 0; n < measured_obs_vec.size(); n++)
{
index = arma::find(measured_obs_vec.at(n).col(0) >= (measured_obs_vec.at(n)(0, 0) + initial_transitory_s), 1, "first");
@ -1567,83 +1833,141 @@ TEST_F(HybridObservablesTest, ValidationOfResults)
}
//Correct the clock error using true values (it is not possible for a receiver to correct
//the receiver clock offset error at the observables level because it is required the
//decoding of the ephemeris data and solve the PVT equations)
//Find the reference satellite (the nearest) and compute the receiver time offset at observable level
double min_pr = std::numeric_limits<double>::max();
unsigned int min_pr_ch_id = 0;
for (unsigned int n = 0; n < measured_obs_vec.size(); n++)
if (FLAGS_duplicated_satellites_test)
{
if (epoch_counters_vec.at(n) > 10) //discard non-valid channels
//special test mode for duplicated satellites
std::vector<int> prn_pairs;
std::stringstream ss(FLAGS_duplicated_satellites_prns);
int i;
while (ss >> i)
{
{
if (measured_obs_vec.at(n)(0, 4) < min_pr)
{
min_pr = measured_obs_vec.at(n)(0, 4);
min_pr_ch_id = n;
}
}
prn_pairs.push_back(i);
if (ss.peek() == ',')
ss.ignore();
}
if (prn_pairs.size() % 2 != 0)
{
std::cout << "Test settings error: duplicated_satellites_prns are even\n";
}
else
{
std::cout << "PRN " << gnss_synchro_vec.at(n).PRN << " has NO observations!\n";
for (unsigned int n = 0; n < prn_pairs.size(); n = n + 2)
{
int sat1_ch_id = -1;
int sat2_ch_id = -1;
for (unsigned int ch = 0; ch < measured_obs_vec.size(); ch++)
{
if (epoch_counters_vec.at(ch) > 10) //discard non-valid channels
{
if (gnss_synchro_vec.at(ch).PRN == prn_pairs.at(n))
{
sat1_ch_id = ch;
}
if (gnss_synchro_vec.at(ch).PRN == prn_pairs.at(n + 1))
{
sat2_ch_id = ch;
}
}
}
if (sat1_ch_id != -1 and sat2_ch_id != -1)
{
//compute single differences for the duplicated satellite
check_results_duplicated_satellite(
measured_obs_vec.at(sat1_ch_id),
measured_obs_vec.at(sat2_ch_id),
sat1_ch_id,
"Duplicated sat [CH " + std::to_string(sat1_ch_id) + "," + std::to_string(sat2_ch_id) + "] PRNs " + std::to_string(gnss_synchro_vec.at(sat1_ch_id).PRN) + "," + std::to_string(gnss_synchro_vec.at(sat2_ch_id).PRN) + " ");
}
else
{
std::cout << "Satellites PRNs " << prn_pairs.at(n) << "and " << prn_pairs.at(n) << " not found\n";
}
}
}
}
arma::vec receiver_time_offset_ref_channel_s;
receiver_time_offset_ref_channel_s = (true_obs_vec.at(min_pr_ch_id).col(1)(0) - measured_obs_vec.at(min_pr_ch_id).col(4)(0)) / GPS_C_m_s;
std::cout << "Ref. channel initial Receiver time offset " << receiver_time_offset_ref_channel_s(0) * 1e3 << " [ms]" << std::endl;
for (unsigned int n = 0; n < measured_obs_vec.size(); n++)
else
{
//debug save to .mat
std::vector<double> tmp_vector_x(true_obs_vec.at(n).col(0).colptr(0),
true_obs_vec.at(n).col(0).colptr(0) + true_obs_vec.at(n).col(0).n_rows);
std::vector<double> tmp_vector_y(true_obs_vec.at(n).col(1).colptr(0),
true_obs_vec.at(n).col(1).colptr(0) + true_obs_vec.at(n).col(1).n_rows);
save_mat_xy(tmp_vector_x, tmp_vector_y, std::string("true_pr_ch_" + std::to_string(n)));
//normal mode
std::vector<double> tmp_vector_x2(measured_obs_vec.at(n).col(0).colptr(0),
measured_obs_vec.at(n).col(0).colptr(0) + measured_obs_vec.at(n).col(0).n_rows);
std::vector<double> tmp_vector_y2(measured_obs_vec.at(n).col(4).colptr(0),
measured_obs_vec.at(n).col(4).colptr(0) + measured_obs_vec.at(n).col(4).n_rows);
save_mat_xy(tmp_vector_x2, tmp_vector_y2, std::string("measured_pr_ch_" + std::to_string(n)));
//Correct the clock error using true values (it is not possible for a receiver to correct
//the receiver clock offset error at the observables level because it is required the
//decoding of the ephemeris data and solve the PVT equations)
std::vector<double> tmp_vector_x3(true_obs_vec.at(n).col(0).colptr(0),
true_obs_vec.at(n).col(0).colptr(0) + true_obs_vec.at(n).col(0).n_rows);
std::vector<double> tmp_vector_y3(true_obs_vec.at(n).col(2).colptr(0),
true_obs_vec.at(n).col(2).colptr(0) + true_obs_vec.at(n).col(2).n_rows);
save_mat_xy(tmp_vector_x3, tmp_vector_y3, std::string("true_doppler_ch_" + std::to_string(n)));
std::vector<double> tmp_vector_x4(measured_obs_vec.at(n).col(0).colptr(0),
measured_obs_vec.at(n).col(0).colptr(0) + measured_obs_vec.at(n).col(0).n_rows);
std::vector<double> tmp_vector_y4(measured_obs_vec.at(n).col(2).colptr(0),
measured_obs_vec.at(n).col(2).colptr(0) + measured_obs_vec.at(n).col(2).n_rows);
save_mat_xy(tmp_vector_x4, tmp_vector_y4, std::string("measured_doppler_ch_" + std::to_string(n)));
if (epoch_counters_vec.at(n) > 10) //discard non-valid channels
//Find the reference satellite (the nearest) and compute the receiver time offset at observable level
double min_pr = std::numeric_limits<double>::max();
unsigned int min_pr_ch_id = 0;
for (unsigned int n = 0; n < measured_obs_vec.size(); n++)
{
arma::vec true_TOW_ref_ch_s = true_obs_vec.at(min_pr_ch_id).col(0) - receiver_time_offset_ref_channel_s(0);
arma::vec true_TOW_ch_s = true_obs_vec.at(n).col(0) - receiver_time_offset_ref_channel_s(0);
//Compare measured observables
if (min_pr_ch_id != n)
if (epoch_counters_vec.at(n) > 10) //discard non-valid channels
{
check_results_code_pseudorange(true_obs_vec.at(n),
true_obs_vec.at(min_pr_ch_id),
true_TOW_ch_s,
true_TOW_ref_ch_s,
measured_obs_vec.at(n),
measured_obs_vec.at(min_pr_ch_id),
"[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " ");
{
if (measured_obs_vec.at(n)(0, 4) < min_pr)
{
min_pr = measured_obs_vec.at(n)(0, 4);
min_pr_ch_id = n;
}
}
}
else
{
std::cout << "PRN " << gnss_synchro_vec.at(n).PRN << " has NO observations!\n";
}
}
//Do not compare E5a with E5 RINEX due to the Doppler frequency discrepancy caused by the different center frequencies
//E5a_fc=1176.45e6, E5b_fc=1207.14e6, E5_fc=1191.795e6;
if (strcmp("5X\0", gnss_synchro_vec.at(n).Signal) != 0 or FLAGS_compare_with_5X)
arma::vec receiver_time_offset_ref_channel_s;
receiver_time_offset_ref_channel_s = (true_obs_vec.at(min_pr_ch_id).col(1)(0) - measured_obs_vec.at(min_pr_ch_id).col(4)(0)) / GPS_C_m_s;
std::cout << "Ref. channel initial Receiver time offset " << receiver_time_offset_ref_channel_s(0) * 1e3 << " [ms]" << std::endl;
for (unsigned int n = 0; n < measured_obs_vec.size(); n++)
{
//debug save to .mat
std::vector<double> tmp_vector_x(true_obs_vec.at(n).col(0).colptr(0),
true_obs_vec.at(n).col(0).colptr(0) + true_obs_vec.at(n).col(0).n_rows);
std::vector<double> tmp_vector_y(true_obs_vec.at(n).col(1).colptr(0),
true_obs_vec.at(n).col(1).colptr(0) + true_obs_vec.at(n).col(1).n_rows);
save_mat_xy(tmp_vector_x, tmp_vector_y, std::string("true_pr_ch_" + std::to_string(n)));
std::vector<double> tmp_vector_x2(measured_obs_vec.at(n).col(0).colptr(0),
measured_obs_vec.at(n).col(0).colptr(0) + measured_obs_vec.at(n).col(0).n_rows);
std::vector<double> tmp_vector_y2(measured_obs_vec.at(n).col(4).colptr(0),
measured_obs_vec.at(n).col(4).colptr(0) + measured_obs_vec.at(n).col(4).n_rows);
save_mat_xy(tmp_vector_x2, tmp_vector_y2, std::string("measured_pr_ch_" + std::to_string(n)));
std::vector<double> tmp_vector_x3(true_obs_vec.at(n).col(0).colptr(0),
true_obs_vec.at(n).col(0).colptr(0) + true_obs_vec.at(n).col(0).n_rows);
std::vector<double> tmp_vector_y3(true_obs_vec.at(n).col(2).colptr(0),
true_obs_vec.at(n).col(2).colptr(0) + true_obs_vec.at(n).col(2).n_rows);
save_mat_xy(tmp_vector_x3, tmp_vector_y3, std::string("true_doppler_ch_" + std::to_string(n)));
std::vector<double> tmp_vector_x4(measured_obs_vec.at(n).col(0).colptr(0),
measured_obs_vec.at(n).col(0).colptr(0) + measured_obs_vec.at(n).col(0).n_rows);
std::vector<double> tmp_vector_y4(measured_obs_vec.at(n).col(2).colptr(0),
measured_obs_vec.at(n).col(2).colptr(0) + measured_obs_vec.at(n).col(2).n_rows);
save_mat_xy(tmp_vector_x4, tmp_vector_y4, std::string("measured_doppler_ch_" + std::to_string(n)));
std::vector<double> tmp_vector_x5(true_obs_vec.at(n).col(0).colptr(0),
true_obs_vec.at(n).col(0).colptr(0) + true_obs_vec.at(n).col(0).n_rows);
std::vector<double> tmp_vector_y5(true_obs_vec.at(n).col(3).colptr(0),
true_obs_vec.at(n).col(3).colptr(0) + true_obs_vec.at(n).col(3).n_rows);
save_mat_xy(tmp_vector_x5, tmp_vector_y5, std::string("true_cp_ch_" + std::to_string(n)));
std::vector<double> tmp_vector_x6(measured_obs_vec.at(n).col(0).colptr(0),
measured_obs_vec.at(n).col(0).colptr(0) + measured_obs_vec.at(n).col(0).n_rows);
std::vector<double> tmp_vector_y6(measured_obs_vec.at(n).col(3).colptr(0),
measured_obs_vec.at(n).col(3).colptr(0) + measured_obs_vec.at(n).col(3).n_rows);
save_mat_xy(tmp_vector_x6, tmp_vector_y6, std::string("measured_cp_ch_" + std::to_string(n)));
if (epoch_counters_vec.at(n) > 10) //discard non-valid channels
{
arma::vec true_TOW_ref_ch_s = true_obs_vec.at(min_pr_ch_id).col(0) - receiver_time_offset_ref_channel_s(0);
arma::vec true_TOW_ch_s = true_obs_vec.at(n).col(0) - receiver_time_offset_ref_channel_s(0);
//Compare measured observables
if (min_pr_ch_id != n)
{
check_results_carrier_phase_double_diff(true_obs_vec.at(n),
check_results_code_pseudorange(true_obs_vec.at(n),
true_obs_vec.at(min_pr_ch_id),
true_TOW_ch_s,
true_TOW_ref_ch_s,
@ -1651,34 +1975,47 @@ TEST_F(HybridObservablesTest, ValidationOfResults)
measured_obs_vec.at(min_pr_ch_id),
"[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " ");
check_results_carrier_doppler_double_diff(true_obs_vec.at(n),
true_obs_vec.at(min_pr_ch_id),
//Do not compare E5a with E5 RINEX due to the Doppler frequency discrepancy caused by the different center frequencies
//E5a_fc=1176.45e6, E5b_fc=1207.14e6, E5_fc=1191.795e6;
if (strcmp("5X\0", gnss_synchro_vec.at(n).Signal) != 0 or FLAGS_compare_with_5X)
{
check_results_carrier_phase_double_diff(true_obs_vec.at(n),
true_obs_vec.at(min_pr_ch_id),
true_TOW_ch_s,
true_TOW_ref_ch_s,
measured_obs_vec.at(n),
measured_obs_vec.at(min_pr_ch_id),
"[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " ");
check_results_carrier_doppler_double_diff(true_obs_vec.at(n),
true_obs_vec.at(min_pr_ch_id),
true_TOW_ch_s,
true_TOW_ref_ch_s,
measured_obs_vec.at(n),
measured_obs_vec.at(min_pr_ch_id),
"[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " ");
}
}
else
{
std::cout << "[CH " << std::to_string(n) << "] PRN " << std::to_string(gnss_synchro_vec.at(n).PRN) << " is the reference satellite" << std::endl;
}
if (FLAGS_compute_single_diffs)
{
check_results_carrier_phase(true_obs_vec.at(n),
true_TOW_ch_s,
measured_obs_vec.at(n),
"[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " ");
check_results_carrier_doppler(true_obs_vec.at(n),
true_TOW_ch_s,
true_TOW_ref_ch_s,
measured_obs_vec.at(n),
measured_obs_vec.at(min_pr_ch_id),
"[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " ");
}
}
else
{
std::cout << "[CH " << std::to_string(n) << "] PRN " << std::to_string(gnss_synchro_vec.at(n).PRN) << " is the reference satellite" << std::endl;
std::cout << "PRN " << gnss_synchro_vec.at(n).PRN << " has NO observations!\n";
}
if (FLAGS_compute_single_diffs)
{
check_results_carrier_phase(true_obs_vec.at(n),
true_TOW_ch_s,
measured_obs_vec.at(n),
"[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " ");
check_results_carrier_doppler(true_obs_vec.at(n),
true_TOW_ch_s,
measured_obs_vec.at(n),
"[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " ");
}
}
else
{
std::cout << "PRN " << gnss_synchro_vec.at(n).PRN << " has NO observations!\n";
}
}
std::cout << "Test completed in " << elapsed_seconds.count() << " [s]" << std::endl;

View File

@ -0,0 +1,461 @@
/*!
* \file rtklib_solver_test.cc
* \brief Implements Unit Test for the rtklib PVT solver class.
* \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 <gtest/gtest.h>
#include <string>
#include <iomanip>
#include <iostream>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/serialization/map.hpp>
#include "rtklib_solver.h"
#include "in_memory_configuration.h"
#include "gnss_sdr_supl_client.h"
#include "geofunctions.h"
#include <armadillo>
rtk_t configure_rtklib_options()
{
std::shared_ptr<InMemoryConfiguration> configuration;
configuration = std::make_shared<InMemoryConfiguration>();
std::string role = "rtklib_solver";
// custom options
configuration->set_property("rtklib_solver.positioning_mode", "Single");
configuration->set_property("rtklib_solver.elevation_mask", "0");
configuration->set_property("rtklib_solver.iono_model", "OFF");
configuration->set_property("rtklib_solver.trop_model", "OFF");
//RTKLIB PVT solver options
// Settings 1
int positioning_mode = -1;
std::string default_pos_mode("Single");
std::string positioning_mode_str = configuration->property(role + ".positioning_mode", default_pos_mode); /* (PMODE_XXX) see src/algorithms/libs/rtklib/rtklib.h */
if (positioning_mode_str.compare("Single") == 0) positioning_mode = PMODE_SINGLE;
if (positioning_mode_str.compare("Static") == 0) positioning_mode = PMODE_STATIC;
if (positioning_mode_str.compare("Kinematic") == 0) positioning_mode = PMODE_KINEMA;
if (positioning_mode_str.compare("PPP_Static") == 0) positioning_mode = PMODE_PPP_STATIC;
if (positioning_mode_str.compare("PPP_Kinematic") == 0) positioning_mode = PMODE_PPP_KINEMA;
if (positioning_mode == -1)
{
//warn user and set the default
std::cout << "WARNING: Bad specification of positioning mode." << std::endl;
std::cout << "positioning_mode possible values: Single / Static / Kinematic / PPP_Static / PPP_Kinematic" << std::endl;
std::cout << "positioning_mode specified value: " << positioning_mode_str << std::endl;
std::cout << "Setting positioning_mode to Single" << std::endl;
positioning_mode = PMODE_SINGLE;
}
int num_bands = 1;
// if ((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) num_bands = 1;
// if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gps_2S_count > 0) || (glo_2G_count > 0))) num_bands = 2;
// if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0))) num_bands = 2;
// if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gps_2S_count > 0) || (glo_2G_count > 0)) && ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0))) num_bands = 3;
int number_of_frequencies = configuration->property(role + ".num_bands", num_bands); /* (1:L1, 2:L1+L2, 3:L1+L2+L5) */
if ((number_of_frequencies < 1) || (number_of_frequencies > 3))
{
//warn user and set the default
number_of_frequencies = num_bands;
}
double elevation_mask = configuration->property(role + ".elevation_mask", 15.0);
if ((elevation_mask < 0.0) || (elevation_mask > 90.0))
{
//warn user and set the default
LOG(WARNING) << "Erroneous Elevation Mask. Setting to default value of 15.0 degrees";
elevation_mask = 15.0;
}
int dynamics_model = configuration->property(role + ".dynamics_model", 0); /* dynamics model (0:none, 1:velocity, 2:accel) */
if ((dynamics_model < 0) || (dynamics_model > 2))
{
//warn user and set the default
LOG(WARNING) << "Erroneous Dynamics Model configuration. Setting to default value of (0:none)";
dynamics_model = 0;
}
std::string default_iono_model("OFF");
std::string iono_model_str = configuration->property(role + ".iono_model", default_iono_model); /* (IONOOPT_XXX) see src/algorithms/libs/rtklib/rtklib.h */
int iono_model = -1;
if (iono_model_str.compare("OFF") == 0) iono_model = IONOOPT_OFF;
if (iono_model_str.compare("Broadcast") == 0) iono_model = IONOOPT_BRDC;
if (iono_model_str.compare("SBAS") == 0) iono_model = IONOOPT_SBAS;
if (iono_model_str.compare("Iono-Free-LC") == 0) iono_model = IONOOPT_IFLC;
if (iono_model_str.compare("Estimate_STEC") == 0) iono_model = IONOOPT_EST;
if (iono_model_str.compare("IONEX") == 0) iono_model = IONOOPT_TEC;
if (iono_model == -1)
{
//warn user and set the default
std::cout << "WARNING: Bad specification of ionospheric model." << std::endl;
std::cout << "iono_model possible values: OFF / Broadcast / SBAS / Iono-Free-LC / Estimate_STEC / IONEX" << std::endl;
std::cout << "iono_model specified value: " << iono_model_str << std::endl;
std::cout << "Setting iono_model to OFF" << std::endl;
iono_model = IONOOPT_OFF; /* 0: ionosphere option: correction off */
}
std::string default_trop_model("OFF");
int trop_model = -1;
std::string trop_model_str = configuration->property(role + ".trop_model", default_trop_model); /* (TROPOPT_XXX) see src/algorithms/libs/rtklib/rtklib.h */
if (trop_model_str.compare("OFF") == 0) trop_model = TROPOPT_OFF;
if (trop_model_str.compare("Saastamoinen") == 0) trop_model = TROPOPT_SAAS;
if (trop_model_str.compare("SBAS") == 0) trop_model = TROPOPT_SBAS;
if (trop_model_str.compare("Estimate_ZTD") == 0) trop_model = TROPOPT_EST;
if (trop_model_str.compare("Estimate_ZTD_Grad") == 0) trop_model = TROPOPT_ESTG;
if (trop_model == -1)
{
//warn user and set the default
std::cout << "WARNING: Bad specification of tropospheric model." << std::endl;
std::cout << "trop_model possible values: OFF / Saastamoinen / SBAS / Estimate_ZTD / Estimate_ZTD_Grad" << std::endl;
std::cout << "trop_model specified value: " << trop_model_str << std::endl;
std::cout << "Setting trop_model to OFF" << std::endl;
trop_model = TROPOPT_OFF;
}
/* RTKLIB positioning options */
int sat_PCV = 0; /* Set whether the satellite antenna PCV (phase center variation) model is used or not. This feature requires a Satellite Antenna PCV File. */
int rec_PCV = 0; /* Set whether the receiver antenna PCV (phase center variation) model is used or not. This feature requires a Receiver Antenna PCV File. */
/* Set whether the phase windup correction for PPP modes is applied or not. Only applicable to PPP* modes.*/
int phwindup = configuration->property(role + ".phwindup", 0);
/* Set whether the GPS Block IIA satellites in eclipse are excluded or not.
The eclipsing Block IIA satellites often degrade the PPP solutions due to unpredicted behavior of yawattitude. Only applicable to PPP* modes.*/
int reject_GPS_IIA = configuration->property(role + ".reject_GPS_IIA", 0);
/* Set whether RAIM (receiver autonomous integrity monitoring) FDE (fault detection and exclusion) feature is enabled or not.
In case of RAIM FDE enabled, a satellite is excluded if SSE (sum of squared errors) of residuals is over a threshold.
The excluded satellite is selected to indicate the minimum SSE. */
int raim_fde = configuration->property(role + ".raim_fde", 0);
int earth_tide = configuration->property(role + ".earth_tide", 0);
int nsys = SYS_GPS;
// if ((gps_1C_count > 0) || (gps_2S_count > 0) || (gps_L5_count > 0)) nsys += SYS_GPS;
// if ((gal_1B_count > 0) || (gal_E5a_count > 0) || (gal_E5b_count > 0)) nsys += SYS_GAL;
// if ((glo_1G_count > 0) || (glo_2G_count > 0)) nsys += SYS_GLO;
int navigation_system = configuration->property(role + ".navigation_system", nsys); /* (SYS_XXX) see src/algorithms/libs/rtklib/rtklib.h */
if ((navigation_system < 1) || (navigation_system > 255)) /* GPS: 1 SBAS: 2 GPS+SBAS: 3 Galileo: 8 Galileo+GPS: 9 GPS+SBAS+Galileo: 11 All: 255 */
{
//warn user and set the default
LOG(WARNING) << "Erroneous Navigation System. Setting to default value of (0:none)";
navigation_system = nsys;
}
// Settings 2
std::string default_gps_ar("Continuous");
std::string integer_ambiguity_resolution_gps_str = configuration->property(role + ".AR_GPS", default_gps_ar); /* Integer Ambiguity Resolution mode for GPS (0:off,1:continuous,2:instantaneous,3:fix and hold,4:ppp-ar) */
int integer_ambiguity_resolution_gps = -1;
if (integer_ambiguity_resolution_gps_str.compare("OFF") == 0) integer_ambiguity_resolution_gps = ARMODE_OFF;
if (integer_ambiguity_resolution_gps_str.compare("Continuous") == 0) integer_ambiguity_resolution_gps = ARMODE_CONT;
if (integer_ambiguity_resolution_gps_str.compare("Instantaneous") == 0) integer_ambiguity_resolution_gps = ARMODE_INST;
if (integer_ambiguity_resolution_gps_str.compare("Fix-and-Hold") == 0) integer_ambiguity_resolution_gps = ARMODE_FIXHOLD;
if (integer_ambiguity_resolution_gps_str.compare("PPP-AR") == 0) integer_ambiguity_resolution_gps = ARMODE_PPPAR;
if (integer_ambiguity_resolution_gps == -1)
{
//warn user and set the default
std::cout << "WARNING: Bad specification of GPS ambiguity resolution method." << std::endl;
std::cout << "AR_GPS possible values: OFF / Continuous / Instantaneous / Fix-and-Hold / PPP-AR" << std::endl;
std::cout << "AR_GPS specified value: " << integer_ambiguity_resolution_gps_str << std::endl;
std::cout << "Setting AR_GPS to OFF" << std::endl;
integer_ambiguity_resolution_gps = ARMODE_OFF;
}
int integer_ambiguity_resolution_glo = configuration->property(role + ".AR_GLO", 1); /* Integer Ambiguity Resolution mode for GLONASS (0:off,1:on,2:auto cal,3:ext cal) */
if ((integer_ambiguity_resolution_glo < 0) || (integer_ambiguity_resolution_glo > 3))
{
//warn user and set the default
LOG(WARNING) << "Erroneous Integer Ambiguity Resolution for GLONASS . Setting to default value of (1:on)";
integer_ambiguity_resolution_glo = 1;
}
int integer_ambiguity_resolution_bds = configuration->property(role + ".AR_DBS", 1); /* Integer Ambiguity Resolution mode for BEIDOU (0:off,1:on) */
if ((integer_ambiguity_resolution_bds < 0) || (integer_ambiguity_resolution_bds > 1))
{
//warn user and set the default
LOG(WARNING) << "Erroneous Integer Ambiguity Resolution for BEIDOU . Setting to default value of (1:on)";
integer_ambiguity_resolution_bds = 1;
}
double min_ratio_to_fix_ambiguity = configuration->property(role + ".min_ratio_to_fix_ambiguity", 3.0); /* Set the integer ambiguity validation threshold for ratiotest,
which uses the ratio of squared residuals of the best integer vector to the secondbest vector. */
int min_lock_to_fix_ambiguity = configuration->property(role + ".min_lock_to_fix_ambiguity", 0); /* Set the minimum lock count to fix integer ambiguity.
If the lock count is less than the value, the ambiguity is excluded from the fixed integer vector. */
double min_elevation_to_fix_ambiguity = configuration->property(role + ".min_elevation_to_fix_ambiguity", 0.0); /* Set the minimum elevation (deg) to fix integer ambiguity.
If the elevation of the satellite is less than the value, the ambiguity is excluded from the fixed integer vector. */
int outage_reset_ambiguity = configuration->property(role + ".outage_reset_ambiguity", 5); /* Set the outage count to reset ambiguity. If the data outage count is over the value, the estimated ambiguity is reset to the initial value. */
double slip_threshold = configuration->property(role + ".slip_threshold", 0.05); /* set the cycleslip threshold (m) of geometryfree LC carrierphase difference between epochs */
double threshold_reject_gdop = configuration->property(role + ".threshold_reject_gdop", 30.0); /* reject threshold of GDOP. If the GDOP is over the value, the observable is excluded for the estimation process as an outlier. */
double threshold_reject_innovation = configuration->property(role + ".threshold_reject_innovation", 30.0); /* reject threshold of innovation (m). If the innovation is over the value, the observable is excluded for the estimation process as an outlier. */
int number_filter_iter = configuration->property(role + ".number_filter_iter", 1); /* Set the number of iteration in the measurement update of the estimation filter.
If the baseline length is very short like 1 m, the iteration may be effective to handle
the nonlinearity of measurement equation. */
/// Statistics
double bias_0 = configuration->property(role + ".bias_0", 30.0);
double iono_0 = configuration->property(role + ".iono_0", 0.03);
double trop_0 = configuration->property(role + ".trop_0", 0.3);
double sigma_bias = configuration->property(role + ".sigma_bias", 1e-4); /* Set the process noise standard deviation of carrierphase
bias (ambiguity) (cycle/sqrt(s)) */
double sigma_iono = configuration->property(role + ".sigma_iono", 1e-3); /* Set the process noise standard deviation of vertical ionospheric delay per 10 km baseline (m/sqrt(s)). */
double sigma_trop = configuration->property(role + ".sigma_trop", 1e-4); /* Set the process noise standard deviation of zenith tropospheric delay (m/sqrt(s)). */
double sigma_acch = configuration->property(role + ".sigma_acch", 1e-1); /* Set the process noise standard deviation of the receiver acceleration as
the horizontal component. (m/s2/sqrt(s)). If Receiver Dynamics is set to OFF, they are not used. */
double sigma_accv = configuration->property(role + ".sigma_accv", 1e-2); /* Set the process noise standard deviation of the receiver acceleration as
the vertical component. (m/s2/sqrt(s)). If Receiver Dynamics is set to OFF, they are not used. */
double sigma_pos = configuration->property(role + ".sigma_pos", 0.0);
double code_phase_error_ratio_l1 = configuration->property(role + ".code_phase_error_ratio_l1", 100.0);
double code_phase_error_ratio_l2 = configuration->property(role + ".code_phase_error_ratio_l2", 100.0);
double code_phase_error_ratio_l5 = configuration->property(role + ".code_phase_error_ratio_l5", 100.0);
double carrier_phase_error_factor_a = configuration->property(role + ".carrier_phase_error_factor_a", 0.003);
double carrier_phase_error_factor_b = configuration->property(role + ".carrier_phase_error_factor_b", 0.003);
snrmask_t snrmask = {{}, {{}, {}}};
prcopt_t rtklib_configuration_options = {
positioning_mode, /* positioning mode (PMODE_XXX) see src/algorithms/libs/rtklib/rtklib.h */
0, /* solution type (0:forward,1:backward,2:combined) */
number_of_frequencies, /* number of frequencies (1:L1, 2:L1+L2, 3:L1+L2+L5)*/
navigation_system, /* navigation system */
elevation_mask * D2R, /* elevation mask angle (degrees) */
snrmask, /* snrmask_t snrmask SNR mask */
0, /* satellite ephemeris/clock (EPHOPT_XXX) */
integer_ambiguity_resolution_gps, /* AR mode (0:off,1:continuous,2:instantaneous,3:fix and hold,4:ppp-ar) */
integer_ambiguity_resolution_glo, /* GLONASS AR mode (0:off,1:on,2:auto cal,3:ext cal) */
integer_ambiguity_resolution_bds, /* BeiDou AR mode (0:off,1:on) */
outage_reset_ambiguity, /* obs outage count to reset bias */
min_lock_to_fix_ambiguity, /* min lock count to fix ambiguity */
10, /* min fix count to hold ambiguity */
1, /* max iteration to resolve ambiguity */
iono_model, /* ionosphere option (IONOOPT_XXX) */
trop_model, /* troposphere option (TROPOPT_XXX) */
dynamics_model, /* dynamics model (0:none, 1:velocity, 2:accel) */
earth_tide, /* earth tide correction (0:off,1:solid,2:solid+otl+pole) */
number_filter_iter, /* number of filter iteration */
0, /* code smoothing window size (0:none) */
0, /* interpolate reference obs (for post mission) */
0, /* sbssat_t sbssat SBAS correction options */
0, /* sbsion_t sbsion[MAXBAND+1] SBAS satellite selection (0:all) */
0, /* rover position for fixed mode */
0, /* base position for relative mode */
/* 0:pos in prcopt, 1:average of single pos, */
/* 2:read from file, 3:rinex header, 4:rtcm pos */
{code_phase_error_ratio_l1, code_phase_error_ratio_l2, code_phase_error_ratio_l5}, /* eratio[NFREQ] code/phase error ratio */
{100.0, carrier_phase_error_factor_a, carrier_phase_error_factor_b, 0.0, 1.0}, /* err[5]: measurement error factor [0]:reserved, [1-3]:error factor a/b/c of phase (m) , [4]:doppler frequency (hz) */
{bias_0, iono_0, trop_0}, /* std[3]: initial-state std [0]bias,[1]iono [2]trop*/
{sigma_bias, sigma_iono, sigma_trop, sigma_acch, sigma_accv, sigma_pos}, /* prn[6] process-noise std */
5e-12, /* sclkstab: satellite clock stability (sec/sec) */
{min_ratio_to_fix_ambiguity, 0.9999, 0.25, 0.1, 0.05, 0.0, 0.0, 0.0}, /* thresar[8]: AR validation threshold */
min_elevation_to_fix_ambiguity, /* elevation mask of AR for rising satellite (deg) */
0.0, /* elevation mask to hold ambiguity (deg) */
slip_threshold, /* slip threshold of geometry-free phase (m) */
30.0, /* max difference of time (sec) */
threshold_reject_innovation, /* reject threshold of innovation (m) */
threshold_reject_gdop, /* reject threshold of gdop */
{}, /* double baseline[2] baseline length constraint {const,sigma} (m) */
{}, /* double ru[3] rover position for fixed mode {x,y,z} (ecef) (m) */
{}, /* double rb[3] base position for relative mode {x,y,z} (ecef) (m) */
{"", ""}, /* char anttype[2][MAXANT] antenna types {rover,base} */
{{}, {}}, /* double antdel[2][3] antenna delta {{rov_e,rov_n,rov_u},{ref_e,ref_n,ref_u}} */
{}, /* pcv_t pcvr[2] receiver antenna parameters {rov,base} */
{}, /* unsigned char exsats[MAXSAT] excluded satellites (1:excluded, 2:included) */
0, /* max averaging epoches */
0, /* initialize by restart */
1, /* output single by dgps/float/fix/ppp outage */
{"", ""}, /* char rnxopt[2][256] rinex options {rover,base} */
{sat_PCV, rec_PCV, phwindup, reject_GPS_IIA, raim_fde}, /* posopt[6] positioning options [0]: satellite and receiver antenna PCV model; [1]: interpolate antenna parameters; [2]: apply phase wind-up correction for PPP modes; [3]: exclude measurements of GPS Block IIA satellites satellite [4]: RAIM FDE (fault detection and exclusion) [5]: handle day-boundary clock jump */
0, /* solution sync mode (0:off,1:on) */
{{}, {}}, /* odisp[2][6*11] ocean tide loading parameters {rov,base} */
{{}, {{}, {}}, {{}, {}}, {}, {}}, /* exterr_t exterr extended receiver error model */
0, /* disable L2-AR */
{} /* char pppopt[256] ppp option "-GAP_RESION=" default gap to reset iono parameters (ep) */
};
rtk_t rtk;
rtkinit(&rtk, &rtklib_configuration_options);
return rtk;
}
//todo: add test cases for Galileo E1, E5 and GPS L5
TEST(RTKLibSolverTest, test1)
{
//test case #1: GPS L1 CA simulated with gnss-sim
std::string path = std::string(TEST_PATH);
int nchannels = 8;
std::string dump_filename = ".rtklib_solver_dump.dat";
bool flag_dump_to_file = false;
rtk_t rtk = configure_rtklib_options();
std::unique_ptr<rtklib_solver> d_ls_pvt(new rtklib_solver(nchannels, dump_filename, flag_dump_to_file, rtk));
d_ls_pvt->set_averaging_depth(1);
// load ephemeris
std::string eph_xml_filename = path + "data/rtklib_test/eph_GPS_L1CA_test1.xml";
gnss_sdr_supl_client supl_client_ephemeris_;
std::cout << "SUPL: Try read GPS ephemeris from XML file " << eph_xml_filename << std::endl;
if (supl_client_ephemeris_.load_ephemeris_xml(eph_xml_filename) == true)
{
std::map<int, Gps_Ephemeris>::const_iterator gps_eph_iter;
for (gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.cbegin();
gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.cend();
gps_eph_iter++)
{
std::cout << "SUPL: Read XML Ephemeris for GPS SV " << gps_eph_iter->first << std::endl;
std::shared_ptr<Gps_Ephemeris> tmp_obj = std::make_shared<Gps_Ephemeris>(gps_eph_iter->second);
// update/insert new ephemeris record to the global ephemeris map
d_ls_pvt->gps_ephemeris_map[gps_eph_iter->first] = *tmp_obj;
}
}
else
{
std::cout << "ERROR: SUPL client error reading XML" << std::endl;
}
// insert observables epoch
std::map<int, Gnss_Synchro> gnss_synchro_map;
// Gnss_Synchro tmp_obs;
// tmp_obs.System = 'G';
// std::string signal = "1C";
// const char* str = signal.c_str(); // get a C style null terminated string
// std::memcpy(static_cast<void*>(tmp_obs.Signal), str, 3); // copy string into synchro char array: 2 char + null
//
// gnss_synchro_map[0] = tmp_obs;
// gnss_synchro_map[0].PRN = 1;
//load from xml (boost serialize)
std::string file_name = path + "data/rtklib_test/obs_test1.xml";
std::ifstream ifs;
try
{
ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in);
boost::archive::xml_iarchive xml(ifs);
gnss_synchro_map.clear();
xml >> boost::serialization::make_nvp("GNSS-SDR_gnss_synchro_map", gnss_synchro_map);
std::cout << "Loaded gnss_synchro map data with " << gnss_synchro_map.size() << " pseudoranges" << std::endl;
}
catch (std::exception& e)
{
std::cout << e.what() << "File: " << file_name;
}
ifs.close();
// solve
bool pvt_valid = false;
if (d_ls_pvt->get_PVT(gnss_synchro_map, false))
{
// DEBUG MESSAGE: Display position in console output
if (d_ls_pvt->is_valid_position())
{
std::streamsize ss = std::cout.precision(); // save current precision
std::cout.setf(std::ios::fixed, std::ios::floatfield);
auto facet = new boost::posix_time::time_facet("%Y-%b-%d %H:%M:%S.%f %z");
std::cout.imbue(std::locale(std::cout.getloc(), facet));
std::cout << "Position at " << d_ls_pvt->get_position_UTC_time()
<< " UTC using " << d_ls_pvt->get_num_valid_observations()
<< std::fixed << std::setprecision(9)
<< " observations is Lat = " << d_ls_pvt->get_latitude() << " [deg], Long = " << d_ls_pvt->get_longitude()
<< std::fixed << std::setprecision(3)
<< " [deg], Height = " << d_ls_pvt->get_height() << " [m]" << std::endl;
std::cout << std::setprecision(ss);
std::cout << "RX clock offset: " << d_ls_pvt->get_time_offset_s() << "[s]" << std::endl;
// boost::posix_time::ptime p_time;
// gtime_t rtklib_utc_time = gpst2time(adjgpsweek(d_ls_pvt->gps_ephemeris_map.cbegin()->second.i_GPS_week), d_rx_time);
// p_time = boost::posix_time::from_time_t(rtklib_utc_time.time);
// p_time += boost::posix_time::microseconds(round(rtklib_utc_time.sec * 1e6));
// std::cout << TEXT_MAGENTA << "Observable RX time (GPST) " << boost::posix_time::to_simple_string(p_time) << TEXT_RESET << std::endl;
std::cout << "RTKLIB Position at RX TOW = " << gnss_synchro_map.begin()->second.RX_time
<< " in ECEF (X,Y,Z,t[meters]) = " << std::fixed << std::setprecision(16)
<< d_ls_pvt->pvt_sol.rr[0] << ","
<< d_ls_pvt->pvt_sol.rr[1] << ","
<< d_ls_pvt->pvt_sol.rr[2] << std::endl;
/* std::cout << "Dilution of Precision at " << boost::posix_time::to_simple_string(d_ls_pvt->get_position_UTC_time())
<< " UTC using "<< d_ls_pvt->get_num_valid_observations() <<" observations is HDOP = " << d_ls_pvt->get_hdop() << " VDOP = "
<< d_ls_pvt->get_vdop()
<< " GDOP = " << d_ls_pvt->get_gdop() << std::endl; */
//todo: check here the positioning error against the reference position generated with gnss-sim
//reference position on in WGS84: Lat (deg), Long (deg) , H (m): 30.286502,120.032669,100
arma::vec LLH = {30.286502, 120.032669, 100}; //ref position for this scenario
double error_LLH_m = great_circle_distance(LLH(0), LLH(1), d_ls_pvt->get_latitude(), d_ls_pvt->get_longitude());
std::cout << "Lat, Long, H error: " << d_ls_pvt->get_latitude() - LLH(0)
<< "," << d_ls_pvt->get_longitude() - LLH(1)
<< "," << d_ls_pvt->get_height() - LLH(2) << " [deg,deg,meters]" << std::endl;
std::cout << "Haversine Great Circle error LLH distance: " << error_LLH_m << " [meters]" << std::endl;
arma::vec v_eb_n = {0.0, 0.0, 0.0};
arma::vec true_r_eb_e;
arma::vec true_v_eb_e;
pv_Geo_to_ECEF(degtorad(LLH(0)), degtorad(LLH(1)), LLH(2), v_eb_n, true_r_eb_e, true_v_eb_e);
arma::vec measured_r_eb_e = {d_ls_pvt->pvt_sol.rr[0], d_ls_pvt->pvt_sol.rr[1], d_ls_pvt->pvt_sol.rr[2]};
arma::vec error_r_eb_e = measured_r_eb_e - true_r_eb_e;
std::cout << "ECEF position error vector: " << error_r_eb_e << " [meters]" << std::endl;
double error_3d_m = arma::norm(error_r_eb_e, 2);
std::cout << "3D positioning error: " << error_3d_m << " [meters]" << std::endl;
//check results against the test tolerance
ASSERT_LT(error_3d_m, 0.2);
pvt_valid = true;
}
}
EXPECT_EQ(true, pvt_valid);
}

View File

@ -17,3 +17,7 @@
#
add_subdirectory(front-end-cal)
if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA)
add_subdirectory(rinex2assist)
endif(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA)

View File

@ -22,6 +22,8 @@ if(OPENSSL_FOUND)
endif(OPENSSL_FOUND)
set(FRONT_END_CAL_SOURCES front_end_cal.cc)
set(FRONT_END_CAL_HEADERS front_end_cal.h)
include_directories(
${CMAKE_SOURCE_DIR}/src/core/system_parameters
@ -44,8 +46,6 @@ include_directories(
${VOLK_GNSSSDR_INCLUDE_DIRS}
)
file(GLOB FRONT_END_CAL_HEADERS "*.h")
list(SORT FRONT_END_CAL_HEADERS)
add_library(front_end_cal_lib ${FRONT_END_CAL_SOURCES} ${FRONT_END_CAL_HEADERS})
source_group(Headers FILES ${FRONT_END_CAL_HEADERS})
@ -114,5 +114,3 @@ if(NOT GZIP_NOTFOUND)
install(FILES ${CMAKE_BINARY_DIR}/front-end-cal.1.gz DESTINATION share/man/man1)
endif(NOT GZIP_NOTFOUND)

View File

@ -33,7 +33,7 @@ function [GNSS_tracking] = dll_pll_veml_read_tracking_dump (filename, count)
m = nargchk (1,2,nargin);
num_float_vars = 17;
num_float_vars = 19;
num_unsigned_long_int_vars = 1;
num_double_vars = 1;
num_unsigned_int_vars = 1;
@ -114,17 +114,23 @@ else
fseek(f,bytes_shift,'bof'); % move to next float
v16 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
bytes_shift = bytes_shift + float_size_bytes;
fseek(f,bytes_shift,'bof'); % move to next interleaved float
fseek(f,bytes_shift,'bof'); % move to next float
v17 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
bytes_shift = bytes_shift + float_size_bytes;
fseek(f,bytes_shift,'bof'); % move to next float
v18 = fread (f, count, 'float', skip_bytes_each_read-float_size_bytes);
v18 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
bytes_shift = bytes_shift + float_size_bytes;
fseek(f,bytes_shift,'bof'); % move to next interleaved float
v19 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
bytes_shift = bytes_shift + float_size_bytes;
fseek(f,bytes_shift,'bof'); % move to next float
v20 = fread (f, count, 'float', skip_bytes_each_read-float_size_bytes);
bytes_shift = bytes_shift + float_size_bytes;
fseek(f,bytes_shift,'bof'); % move to next double
v19 = fread (f, count, 'double', skip_bytes_each_read - double_size_bytes);
v21 = fread (f, count, 'double', skip_bytes_each_read - double_size_bytes);
bytes_shift = bytes_shift + double_size_bytes;
fseek(f,bytes_shift,'bof'); % move to next unsigned int
v20 = fread (f, count, 'uint', skip_bytes_each_read - unsigned_int_size_bytes);
v22 = fread (f, count, 'uint', skip_bytes_each_read - unsigned_int_size_bytes);
fclose (f);
GNSS_tracking.VE = v1;
@ -137,15 +143,17 @@ else
GNSS_tracking.PRN_start_sample = v8;
GNSS_tracking.acc_carrier_phase_rad = v9;
GNSS_tracking.carrier_doppler_hz = v10;
GNSS_tracking.code_freq_hz = v11;
GNSS_tracking.carr_error = v12;
GNSS_tracking.carr_nco = v13;
GNSS_tracking.code_error = v14;
GNSS_tracking.code_nco = v15;
GNSS_tracking.CN0_SNV_dB_Hz = v16;
GNSS_tracking.carrier_lock_test = v17;
GNSS_tracking.var1 = v18;
GNSS_tracking.var2 = v19;
GNSS_tracking.PRN = v20;
GNSS_tracking.carrier_doppler_rate_hz_s = v11;
GNSS_tracking.code_freq_hz = v12;
GNSS_tracking.code_freq_rate_hz_s = v13;
GNSS_tracking.carr_error = v14;
GNSS_tracking.carr_nco = v15;
GNSS_tracking.code_error = v16;
GNSS_tracking.code_nco = v17;
GNSS_tracking.CN0_SNV_dB_Hz = v18;
GNSS_tracking.carrier_lock_test = v19;
GNSS_tracking.var1 = v20;
GNSS_tracking.var2 = v21;
GNSS_tracking.PRN = v22;
end

View File

@ -0,0 +1,57 @@
# Copyright (C) 2012-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/>.
#
find_package(GPSTK QUIET)
if(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK)
set(GPSTK_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/../../../thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gpstk${CMAKE_SHARED_LIBRARY_SUFFIX} )
set(GPSTK_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/include )
endif(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK)
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} ${GPSTK_INCLUDE_DIR}/gpstk)
include_directories(
${CMAKE_SOURCE_DIR}/src/core/system_parameters
${GFlags_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
${GPSTK_INCLUDE_DIR}/gpstk
${GPSTK_INCLUDE_DIR}
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated")
add_executable(rinex2assist ${CMAKE_CURRENT_SOURCE_DIR}/main.cc)
target_link_libraries(rinex2assist
${Boost_LIBRARIES}
${GPSTK_LIBRARY}
${GFlags_LIBS}
gnss_sp_libs
gnss_rx)
if(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK)
add_dependencies(rinex2assist gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION})
endif(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK)
add_custom_command(TARGET rinex2assist POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:rinex2assist>
${CMAKE_SOURCE_DIR}/install/$<TARGET_FILE_NAME:rinex2assist>)
install(TARGETS rinex2assist
RUNTIME DESTINATION bin
COMPONENT "rinex2assist"
)

View File

@ -0,0 +1,359 @@
/*!
* \file main.cc
* \brief converts navigation RINEX files into XML files for Assisted GNSS.
* \author Carles Fernandez-Prades, 2018. cfernandez(at)cttc.cat
*
*
* -------------------------------------------------------------------------
*
* 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 "gps_ephemeris.h"
#include "galileo_ephemeris.h"
#include "gps_utc_model.h"
#include "gps_iono.h"
#include "galileo_utc_model.h"
#include "galileo_iono.h"
#include <gflags/gflags.h>
#include <gpstk/Rinex3NavHeader.hpp>
#include <gpstk/Rinex3NavData.hpp>
#include <gpstk/Rinex3NavStream.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/map.hpp>
#include <iostream>
int main(int argc, char** argv)
{
const std::string intro_help(
std::string("\n rinex2assist converts navigation RINEX files into XML files for Assisted GNSS\n") +
"Copyright (C) 2018 (see AUTHORS file for a list of contributors)\n" +
"This program comes with ABSOLUTELY NO WARRANTY;\n" +
"See COPYING file to see a copy of the General Public License.\n \n" +
"Usage: \n" +
" rinex2assist <RINEX Nav file input>");
google::SetUsageMessage(intro_help);
google::SetVersionString("1.0");
google::ParseCommandLineFlags(&argc, &argv, true);
if ((argc != 2))
{
std::cerr << "Usage:" << std::endl;
std::cerr << " " << argv[0]
<< " <RINEX Nav file input>"
<< std::endl;
google::ShutDownCommandLineFlags();
return 1;
}
std::string xml_filename;
std::map<int, Gps_Ephemeris> eph_map;
std::map<int, Galileo_Ephemeris> eph_gal_map;
Gps_Utc_Model gps_utc_model;
Gps_Iono gps_iono;
Galileo_Utc_Model gal_utc_model;
Galileo_Iono gal_iono;
int i = 0;
int j = 0;
try
{
// Read nav file
gpstk::Rinex3NavStream rnffs(argv[1]); // Open navigation data file
gpstk::Rinex3NavData rne;
gpstk::Rinex3NavHeader hdr;
// Read header
rnffs >> hdr;
// Check that it really is a RINEX navigation file
if (hdr.fileType.substr(0, 1).compare("N") != 0)
{
std::cerr << "This is not a valid RINEX navigation file, or file not found." << std::endl;
std::cerr << "No XML file will be created." << std::endl;
return 1;
}
// Collect UTC parameters from RINEX header
if (hdr.fileSys.compare("G: (GPS)") == 0 || hdr.fileSys.compare("MIXED") == 0)
{
gps_utc_model.valid = (hdr.valid > 2147483648) ? true : false;
gps_utc_model.d_A1 = hdr.mapTimeCorr["GPUT"].A0;
gps_utc_model.d_A0 = hdr.mapTimeCorr["GPUT"].A1;
gps_utc_model.d_t_OT = hdr.mapTimeCorr["GPUT"].refSOW;
gps_utc_model.i_WN_T = hdr.mapTimeCorr["GPUT"].refWeek;
gps_utc_model.d_DeltaT_LS = hdr.leapSeconds;
gps_utc_model.i_WN_LSF = hdr.leapWeek;
gps_utc_model.i_DN = hdr.leapDay;
gps_utc_model.d_DeltaT_LSF = hdr.leapDelta;
// Collect iono parameters from RINEX header
gps_iono.valid = (hdr.mapIonoCorr["GPSA"].param[0] == 0) ? false : true;
gps_iono.d_alpha0 = hdr.mapIonoCorr["GPSA"].param[0];
gps_iono.d_alpha1 = hdr.mapIonoCorr["GPSA"].param[1];
gps_iono.d_alpha2 = hdr.mapIonoCorr["GPSA"].param[2];
gps_iono.d_alpha3 = hdr.mapIonoCorr["GPSA"].param[3];
gps_iono.d_beta0 = hdr.mapIonoCorr["GPSB"].param[0];
gps_iono.d_beta1 = hdr.mapIonoCorr["GPSB"].param[1];
gps_iono.d_beta2 = hdr.mapIonoCorr["GPSB"].param[2];
gps_iono.d_beta3 = hdr.mapIonoCorr["GPSB"].param[3];
}
if (hdr.fileSys.compare("E: (GAL)") == 0 || hdr.fileSys.compare("MIXED") == 0)
{
gal_utc_model.A0_6 = hdr.mapTimeCorr["GAUT"].A0;
gal_utc_model.A1_6 = hdr.mapTimeCorr["GAUT"].A1;
gal_utc_model.Delta_tLS_6 = hdr.leapSeconds;
gal_utc_model.t0t_6 = hdr.mapTimeCorr["GAUT"].refSOW;
gal_utc_model.WNot_6 = hdr.mapTimeCorr["GAUT"].refWeek;
gal_utc_model.WN_LSF_6 = hdr.leapWeek;
gal_utc_model.DN_6 = hdr.leapDay;
gal_utc_model.Delta_tLSF_6 = hdr.leapDelta;
gal_utc_model.flag_utc_model = (hdr.mapTimeCorr["GAUT"].A0 == 0.0);
gal_iono.ai0_5 = hdr.mapIonoCorr["GAL"].param[0];
gal_iono.ai1_5 = hdr.mapIonoCorr["GAL"].param[1];
gal_iono.ai2_5 = hdr.mapIonoCorr["GAL"].param[2];
gal_iono.Region1_flag_5 = false;
gal_iono.Region2_flag_5 = false;
gal_iono.Region3_flag_5 = false;
gal_iono.Region4_flag_5 = false;
gal_iono.Region5_flag_5 = false;
gal_iono.TOW_5 = 0.0;
gal_iono.WN_5 = 0.0;
}
// Read navigation data
while (rnffs >> rne)
{
if (rne.satSys.compare("G") == 0 or rne.satSys.empty())
{
// Fill GPS ephemeris object
Gps_Ephemeris eph;
eph.i_satellite_PRN = rne.PRNID;
eph.d_TOW = rne.xmitTime;
eph.d_IODE_SF2 = rne.IODE;
eph.d_IODE_SF3 = rne.IODE;
eph.d_Crs = rne.Crs;
eph.d_Delta_n = rne.dn;
eph.d_M_0 = rne.M0;
eph.d_Cuc = rne.Cuc;
eph.d_e_eccentricity = rne.ecc;
eph.d_Cus = rne.Cus;
eph.d_sqrt_A = rne.Ahalf;
eph.d_Toe = rne.Toe;
eph.d_Toc = rne.Toc;
eph.d_Cic = rne.Cic;
eph.d_OMEGA0 = rne.OMEGA0;
eph.d_Cis = rne.Cis;
eph.d_i_0 = rne.i0;
eph.d_Crc = rne.Crc;
eph.d_OMEGA = rne.w;
eph.d_OMEGA_DOT = rne.OMEGAdot;
eph.d_IDOT = rne.idot;
eph.i_code_on_L2 = rne.codeflgs; //
eph.i_GPS_week = rne.weeknum;
eph.b_L2_P_data_flag = rne.L2Pdata;
eph.i_SV_accuracy = rne.accuracy;
eph.i_SV_health = rne.health;
eph.d_TGD = rne.Tgd;
eph.d_IODC = rne.IODC;
eph.i_AODO = 0; //
eph.b_fit_interval_flag = (rne.fitint > 4) ? 1 : 0;
eph.d_spare1 = 0.0;
eph.d_spare2 = 0.0;
eph.d_A_f0 = rne.af0;
eph.d_A_f1 = rne.af1;
eph.d_A_f2 = rne.af2;
eph.b_integrity_status_flag = 0; //
eph.b_alert_flag = 0; //
eph.b_antispoofing_flag = 0; //
eph_map[i] = eph;
i++;
}
if (rne.satSys.compare("E") == 0)
{
// Fill Galileo ephemeris object
Galileo_Ephemeris eph;
eph.i_satellite_PRN = rne.PRNID;
eph.M0_1 = rne.M0;
eph.e_1 = rne.ecc;
eph.A_1 = rne.Ahalf;
eph.OMEGA_0_2 = rne.OMEGA0;
eph.i_0_2 = rne.i0;
eph.omega_2 = rne.w;
eph.OMEGA_dot_3 = rne.OMEGAdot;
eph.iDot_2 = rne.idot;
eph.C_uc_3 = rne.Cuc;
eph.C_us_3 = rne.Cus;
eph.C_rc_3 = rne.Crc;
eph.C_rs_3 = rne.Crs;
eph.C_ic_4 = rne.Cic;
eph.C_is_4 = rne.Cis;
eph.t0e_1 = rne.Toe;
eph.t0c_4 = rne.Toc;
eph.af0_4 = rne.af0;
eph.af1_4 = rne.af1;
eph.af2_4 = rne.af2;
eph_gal_map[j] = eph;
j++;
}
}
}
catch (std::exception& e)
{
std::cerr << "Error reading the RINEX file: " << e.what() << std::endl;
std::cerr << "No XML file will be created." << std::endl;
google::ShutDownCommandLineFlags();
return 1;
}
if (i == 0 and j == 0)
{
std::cerr << "No navigation data found in the RINEX file. No XML file will be created." << std::endl;
google::ShutDownCommandLineFlags();
return 1;
}
// Write XML ephemeris
if (i != 0)
{
std::ofstream ofs;
if (xml_filename.empty())
{
xml_filename = "gps_ephemeris.xml";
}
try
{
ofs.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", eph_map);
}
catch (std::exception& e)
{
std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl;
google::ShutDownCommandLineFlags();
return 1;
}
std::cout << "Generated file: " << xml_filename << std::endl;
}
if (j != 0)
{
std::ofstream ofs2;
xml_filename = "gal_ephemeris.xml";
try
{
ofs2.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs2);
xml << boost::serialization::make_nvp("GNSS-SDR_gal_ephemeris_map", eph_gal_map);
}
catch (std::exception& e)
{
std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl;
google::ShutDownCommandLineFlags();
return 1;
}
std::cout << "Generated file: " << xml_filename << std::endl;
}
// Write XML UTC
if (gps_utc_model.valid)
{
std::ofstream ofs3;
xml_filename = "gps_utc_model.xml";
try
{
ofs3.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs3);
xml << boost::serialization::make_nvp("GNSS-SDR_utc_model", gps_utc_model);
}
catch (std::exception& e)
{
std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl;
google::ShutDownCommandLineFlags();
return 1;
}
std::cout << "Generated file: " << xml_filename << std::endl;
}
// Write XML iono
if (gps_iono.valid)
{
std::ofstream ofs4;
xml_filename = "gps_iono.xml";
try
{
ofs4.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs4);
xml << boost::serialization::make_nvp("GNSS-SDR_iono_model", gps_iono);
}
catch (std::exception& e)
{
std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl;
google::ShutDownCommandLineFlags();
return 1;
}
std::cout << "Generated file: " << xml_filename << std::endl;
}
if (gal_utc_model.A0_6 != 0)
{
std::ofstream ofs5;
xml_filename = "gal_utc_model.xml";
try
{
ofs5.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs5);
xml << boost::serialization::make_nvp("GNSS-SDR_gal_utc_model", gal_utc_model);
}
catch (std::exception& e)
{
std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl;
google::ShutDownCommandLineFlags();
return 1;
}
std::cout << "Generated file: " << xml_filename << std::endl;
}
if (gal_iono.ai0_5 != 0)
{
std::ofstream ofs7;
xml_filename = "gal_iono.xml";
try
{
ofs7.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs7);
xml << boost::serialization::make_nvp("GNSS-SDR_gal_iono_model", gal_iono);
}
catch (std::exception& e)
{
std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl;
google::ShutDownCommandLineFlags();
return 1;
}
std::cout << "Generated file: " << xml_filename << std::endl;
}
google::ShutDownCommandLineFlags();
return 0;
}