1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-11-07 18:54:06 +00:00

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

This commit is contained in:
Javier Arribas
2021-02-24 11:41:34 +01:00
29 changed files with 684 additions and 447 deletions

View File

@@ -123,9 +123,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- name: install dependencies - name: install dependencies
run: | run: sudo apt install python3-mako liborc-dev
python -m pip install --upgrade pip
pip install mako
- name: configure - name: configure
run: cd build && cmake ../src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr run: cd build && cmake ../src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr
- name: build - name: build

View File

@@ -326,13 +326,13 @@ set(GNSSSDR_PROTOBUF_MIN_VERSION "3.0.0")
################################################################################ ################################################################################
set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.2") set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.2")
set(GNSSSDR_GLOG_LOCAL_VERSION "0.4.0") set(GNSSSDR_GLOG_LOCAL_VERSION "0.4.0")
set(GNSSSDR_ARMADILLO_LOCAL_VERSION "10.1.x") set(GNSSSDR_ARMADILLO_LOCAL_VERSION "10.2.x")
set(GNSSSDR_GTEST_LOCAL_VERSION "1.10.0") set(GNSSSDR_GTEST_LOCAL_VERSION "1.10.0")
set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master") set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master")
set(GNSSSDR_GPSTK_LOCAL_VERSION "8.0.0") set(GNSSSDR_GPSTK_LOCAL_VERSION "8.0.0")
set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.19") set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.19")
set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.11.4") set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.11.4")
set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.15.0") set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.15.2")
set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.5.2") set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.5.2")
set(GNSSSDR_MATHJAX_EXTERNAL_VERSION "2.7.7") set(GNSSSDR_MATHJAX_EXTERNAL_VERSION "2.7.7")

View File

@@ -292,9 +292,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 yum install lapack-devel blas-devel # For Fedora/CentOS/RHEL
$ sudo zypper install lapack-devel blas-devel # For OpenSUSE $ sudo zypper install lapack-devel blas-devel # For OpenSUSE
$ sudo pacman -S blas lapack # For Arch Linux $ sudo pacman -S blas lapack # For Arch Linux
$ wget http://sourceforge.net/projects/arma/files/armadillo-10.1.2.tar.xz $ wget http://sourceforge.net/projects/arma/files/armadillo-10.2.1.tar.xz
$ tar xvfz armadillo-10.1.2.tar.xz $ tar xvfz armadillo-10.2.1.tar.xz
$ cd armadillo-10.1.2 $ cd armadillo-10.2.1
$ cmake . $ cmake .
$ make $ make
$ sudo make install $ sudo make install

View File

@@ -10,77 +10,67 @@
[GNSS-SDR] [GNSS-SDR]
;######### GLOBAL OPTIONS ################## ;######### GLOBAL OPTIONS ##################
;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second]. GNSS-SDR.internal_fs_sps=12500000
GNSS-SDR.internal_fs_sps=4000000 GNSS-SDR.enable_FPGA=true
;######### SIGNAL_SOURCE CONFIG ############ ;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation=Pass_Through SignalSource.implementation=Ad9361_Fpga_Signal_Source
SignalSource.filename=/datalogger/signals/Agilent/New York/4msps.dat ; <- PUT YOUR FILE HERE SignalSource.sampling_frequency=12500000
SignalSource.item_type=ishort
SignalSource.sampling_frequency=4000000
SignalSource.freq=1575420000 SignalSource.freq=1575420000
SignalSource.repeat=false SignalSource.switch_position=2
SignalSource.dump=false SignalSource.gain_mode_rx1=slow_attack
SignalSource.dump_filename=../data/signal_source.dat
SignalSource.enable_throttle_control=false
SignalSource.enable_FPGA=true
;######### SIGNAL_CONDITIONER CONFIG ############ ;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation=Pass_Through SignalConditioner.implementation=Pass_Through
SignalConditioner.item_type=cshort
SignalConditioner.enable_FPGA=true SignalConditioner.enable_FPGA=true
;######### CHANNELS GLOBAL CONFIG ############ ;######### CHANNELS GLOBAL CONFIG ############
Channels_1C.count=8
Channels.in_acquisition=1 Channels.in_acquisition=1
Channel.signal=1C Channels_1C.count=12
Channel.enable_FPGA=true
;######### GPS ACQUISITION CONFIG ############
;######### ACQUISITION GLOBAL CONFIG ############
Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fpga Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fpga
Acquisition_1C.dump=false Acquisition_1C.threshold=2.0
Acquisition_1C.dump_filename=./acq_dump.dat Acquisition_1C.doppler_max=50000
Acquisition_1C.item_type=cshort Acquisition_1C.doppler_step=250
Acquisition_1C.coherent_integration_time_ms=1 Acquisition_1C.make_two_steps=true
Acquisition_1C.select_queue_Fpga=0; Acquisition_1C.second_nbins=3
Acquisition_1C.threshold=0.005 Acquisition_1C.doppler_step2=250
;Acquisition_1C.pfa=0.01 Acquisition_1C.max_num_acqs=100
Acquisition_1C.doppler_max=10000
Acquisition_1C.doppler_step=500
;######### TRACKING GLOBAL CONFIG ############ ;######### TRACKING GPS CONFIG ############
Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking_Fpga Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking_Fpga
Tracking_1C.item_type=cshort Tracking_1C.extend_correlation_symbols=20
Tracking_1C.dump=false Tracking_1C.pll_bw_hz=35;
Tracking_1C.dump_filename=../data/epl_tracking_ch_
Tracking_1C.pll_bw_hz=45.0;
Tracking_1C.dll_bw_hz=2.0; Tracking_1C.dll_bw_hz=2.0;
Tracking_1C.order=3; Tracking_1C.pll_bw_narrow_hz=5.0;
Tracking_1C.dll_bw_narrow_hz=0.50;
Tracking_1C.fll_bw_hz=10
Tracking_1C.enable_fll_pull_in=true;
Tracking_1C.enable_fll_steady_state=false
Tracking_1C.high_dyn=true
Tracking_1C.dump=false
Tracking_1C.dump_filename=tracking_ch_
;######### TELEMETRY DECODER GPS CONFIG ############ ;######### TELEMETRY DECODER GPS CONFIG ############
TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder
TelemetryDecoder_1C.dump=false TelemetryDecoder_1C.dump=false
;######### OBSERVABLES CONFIG ############ ;######### OBSERVABLES CONFIG ############
Observables.implementation=GPS_L1_CA_Observables Observables.implementation=Hybrid_Observables
Observables.dump=false Observables.dump=false
Observables.dump_filename=./observables.dat
;######### PVT CONFIG ############ ;######### PVT CONFIG ############
PVT.implementation=GPS_L1_CA_PVT PVT.implementation=RTKLIB_PVT
PVT.averaging_depth=100 PVT.positioning_mode=Single
PVT.flag_averaging=false PVT.iono_model=OFF
PVT.output_rate_ms=10 PVT.trop_model=OFF
PVT.display_rate_ms=500 PVT.raim_fde=1
PVT.dump_filename=./PVT PVT.output_rate_ms=20;
PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; PVT.display_rate_ms=500;
PVT.flag_nmea_tty_port=false; PVT.elevation_mask=0;
PVT.nmea_dump_devname=/dev/pts/4
PVT.flag_rtcm_server=false PVT.flag_rtcm_server=false
PVT.flag_rtcm_tty_port=false PVT.flag_rtcm_tty_port=false
PVT.rtcm_dump_devname=/dev/pts/1 PVT.rtcm_dump_devname=/dev/pts/1
PVT.dump=false PVT.dump=false
PVT.dump_filename=./PVT

View File

@@ -54,7 +54,12 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
inconsistencies in the configuration file. inconsistencies in the configuration file.
- Fix segmentation fault if the RINEX output was disabled. - Fix segmentation fault if the RINEX output was disabled.
- Added a feature that optionally enables the remote monitoring of GPS and - Added a feature that optionally enables the remote monitoring of GPS and
Galileo ephemeris using UDP and protobuffers. Galileo ephemeris using UDP and
[Protocol Buffers](https://developers.google.com/protocol-buffers).
- Now building the software passing the `-DENABLE_FPGA=ON` to CMake does not
make the receiver unusable when running on non-FPGA-enabled platforms. On
FPGA-enabled platforms, now it is possible to run non-FPGA-enabled
configurations.
&nbsp; &nbsp;

View File

@@ -17,18 +17,18 @@
<xs:complexType> <xs:complexType>
<xs:sequence> <xs:sequence>
<xs:element type="xs:byte" name="PRN"/> <xs:element type="xs:byte" name="PRN"/>
<xs:element type="xs:int" name="toa"/>
<xs:element type="xs:byte" name="WNa"/>
<xs:element type="xs:byte" name="IODa"/>
<xs:element type="xs:float" name="delta_i"/> <xs:element type="xs:float" name="delta_i"/>
<xs:element type="xs:byte" name="toa"/>
<xs:element type="xs:byte" name="WNa"/>
<xs:element type="xs:float" name="M_0"/> <xs:element type="xs:float" name="M_0"/>
<xs:element type="xs:float" name="ecc"/> <xs:element type="xs:float" name="ecc"/>
<xs:element type="xs:float" name="delta_sqrtA"/> <xs:element type="xs:float" name="sqrtA"/>
<xs:element type="xs:float" name="OMEGA_0"/> <xs:element type="xs:float" name="OMEGA_0"/>
<xs:element type="xs:float" name="omega"/> <xs:element type="xs:float" name="omega"/>
<xs:element type="xs:float" name="OMEGAdot"/> <xs:element type="xs:float" name="OMEGAdot"/>
<xs:element type="xs:float" name="af0"/> <xs:element type="xs:float" name="af0"/>
<xs:element type="xs:float" name="af1"/> <xs:element type="xs:float" name="af1"/>
<xs:element type="xs:byte" name="IODa"/>
<xs:element type="xs:byte" name="E5b_HS"/> <xs:element type="xs:byte" name="E5b_HS"/>
<xs:element type="xs:byte" name="E1B_HS"/> <xs:element type="xs:byte" name="E1B_HS"/>
<xs:element type="xs:byte" name="E5a_HS"/> <xs:element type="xs:byte" name="E5a_HS"/>

View File

@@ -26,10 +26,10 @@
<xs:element type="xs:float" name="OMEGA_0"/> <xs:element type="xs:float" name="OMEGA_0"/>
<xs:element type="xs:float" name="omega"/> <xs:element type="xs:float" name="omega"/>
<xs:element type="xs:float" name="OMEGAdot"/> <xs:element type="xs:float" name="OMEGAdot"/>
<xs:element type="xs:byte" name="SV_health"/>
<xs:element type="xs:byte" name="AS_status"/>
<xs:element type="xs:float" name="af0"/> <xs:element type="xs:float" name="af0"/>
<xs:element type="xs:float" name="af1"/> <xs:element type="xs:float" name="af1"/>
<xs:element type="xs:byte" name="SV_health"/>
<xs:element type="xs:byte" name="AS_status"/>
</xs:sequence> </xs:sequence>
<xs:attribute type="xs:byte" name="class_id" use="optional"/> <xs:attribute type="xs:byte" name="class_id" use="optional"/>
<xs:attribute type="xs:byte" name="tracking_level" use="optional"/> <xs:attribute type="xs:byte" name="tracking_level" use="optional"/>

View File

@@ -454,8 +454,7 @@ alm_t alm_to_rtklib(const Galileo_Almanac& gal_alm)
toa.time = gal_alm.toa; toa.time = gal_alm.toa;
toa.sec = 0.0; toa.sec = 0.0;
rtklib_alm.toa = toa; rtklib_alm.toa = toa;
rtklib_alm.A = 5440.588203494 + gal_alm.delta_sqrtA; rtklib_alm.A = gal_alm.sqrtA * gal_alm.sqrtA;
rtklib_alm.A = rtklib_alm.A * rtklib_alm.A;
rtklib_alm.e = gal_alm.ecc; rtklib_alm.e = gal_alm.ecc;
rtklib_alm.i0 = (gal_alm.delta_i + 56.0 / 180.0) * GNSS_PI; rtklib_alm.i0 = (gal_alm.delta_i + 56.0 / 180.0) * GNSS_PI;
rtklib_alm.OMG0 = gal_alm.OMEGA_0 * GNSS_PI; rtklib_alm.OMG0 = gal_alm.OMEGA_0 * GNSS_PI;

View File

@@ -157,6 +157,8 @@ target_include_directories(signal_source_adapters
if(ENABLE_FPGA OR ENABLE_AD9361) if(ENABLE_FPGA OR ENABLE_AD9361)
target_link_libraries(signal_source_adapters target_link_libraries(signal_source_adapters
PUBLIC
signal_source_libs
PRIVATE PRIVATE
core_libs core_libs
) )

View File

@@ -23,6 +23,7 @@
#include "GPS_L1_CA.h" #include "GPS_L1_CA.h"
#include "GPS_L5.h" #include "GPS_L5.h"
#include "ad9361_manager.h" #include "ad9361_manager.h"
#include "command_event.h"
#include "configuration_interface.h" #include "configuration_interface.h"
#include "gnss_sdr_flags.h" #include "gnss_sdr_flags.h"
#include "gnss_sdr_string_literals.h" #include "gnss_sdr_string_literals.h"
@@ -35,6 +36,7 @@
#include <exception> // for exceptions #include <exception> // for exceptions
#include <fcntl.h> // for open, O_WRONLY #include <fcntl.h> // for open, O_WRONLY
#include <fstream> // for std::ifstream #include <fstream> // for std::ifstream
#include <iomanip> // for std::setprecision
#include <iostream> // for cout #include <iostream> // for cout
#include <string> // for string manipulation #include <string> // for string manipulation
#include <thread> // for std::chrono #include <thread> // for std::chrono
@@ -48,8 +50,10 @@ using namespace std::string_literals;
Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *configuration, Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *configuration,
const std::string &role, unsigned int in_stream, unsigned int out_stream, const std::string &role, unsigned int in_stream, unsigned int out_stream,
Concurrent_Queue<pmt::pmt_t> *queue __attribute__((unused))) Concurrent_Queue<pmt::pmt_t> *queue __attribute__((unused)))
: SignalSourceBase(configuration, role, "Ad9361_Fpga_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream) : SignalSourceBase(configuration, role, "Ad9361_Fpga_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream), queue_(queue)
{ {
// initialize the variables that are used in real-time mode
const std::string default_gain_mode("slow_attack"); const std::string default_gain_mode("slow_attack");
const double default_tx_attenuation_db = -10.0; const double default_tx_attenuation_db = -10.0;
const double default_manual_gain_rx1 = 64.0; const double default_manual_gain_rx1 = 64.0;
@@ -92,14 +96,77 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
rf_shutdown_ = configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown); rf_shutdown_ = configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown);
// initialize the variables that are used in post-processing mode
enable_DMA_ = false;
const int l1_band = configuration->property("Channels_1C.count", 0) +
configuration->property("Channels_1B.count", 0);
// by default the DMA transfers samples corresponding to two frequency bands to the FPGA
num_freq_bands_ = 2;
dma_buff_offset_pos_ = 0;
// if only one input file is specified in the configuration file then:
// if there is at least one channel assigned to frequency band 1 then the DMA transfers the samples to the L1 frequency band channels
// otherwise the DMA transfers the samples to the L2/L5 frequency band channels
if (filename1.empty())
{
num_freq_bands_ = 1;
if (l1_band != 0)
{
dma_buff_offset_pos_ = 2;
}
}
const double default_seconds_to_skip = 0.0;
const std::string empty_string;
filename0 = configuration->property(role + ".filename", empty_string);
// override value with commandline flag, if present
if (FLAGS_signal_source != "-")
{
filename0 = FLAGS_signal_source;
}
if (FLAGS_s != "-")
{
filename0 = FLAGS_s;
}
if (filename0.empty())
{
filename0 = configuration->property(role + ".filename0", empty_string);
filename1 = configuration->property(role + ".filename1", empty_string);
}
samples_ = configuration->property(role + ".samples", static_cast<uint64_t>(0));
const double seconds_to_skip = configuration->property(role + ".seconds_to_skip", default_seconds_to_skip);
const size_t header_size = configuration->property(role + ".header_size", 0);
std::string item_type = "ibyte"; // for now only the ibyte format is supported
item_size_ = sizeof(int8_t);
repeat_ = configuration->property(role + ".repeat", false);
if (seconds_to_skip > 0)
{
samples_to_skip_ = static_cast<int64_t>(seconds_to_skip * sample_rate_) * 2;
}
if (header_size > 0)
{
samples_to_skip_ += header_size;
}
// check the switch status (determines real-time mode or post-processing mode)
std::string device_io_name; // Switch UIO device file
// Switch UIO device file
std::string device_io_name;
// find the uio device file corresponding to the switch. // find the uio device file corresponding to the switch.
if (find_uio_dev_file_name(device_io_name, switch_device_name, 0) < 0) if (find_uio_dev_file_name(device_io_name, switch_device_name, 0) < 0)
{ {
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << switch_device_name << std::endl; std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << switch_device_name << '\n';
throw std::exception(); item_size_ = 0;
return;
} }
switch_position_ = configuration->property(role + ".switch_position", 0); switch_position_ = configuration->property(role + ".switch_position", 0);
@@ -113,55 +180,102 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
switch_fpga = std::make_shared<Fpga_Switch>(device_io_name); switch_fpga = std::make_shared<Fpga_Switch>(device_io_name);
switch_fpga->set_switch_position(switch_position_); switch_fpga->set_switch_position(switch_position_);
item_size_ = sizeof(gr_complex);
std::cout << "Sample rate: " << sample_rate_ << " Sps\n";
enable_ovf_check_buffer_monitor_active_ = false; // check buffer overflow and buffer monitor disabled by default
if (switch_position_ == 0) // Inject file(s) via DMA if (switch_position_ == 0) // Inject file(s) via DMA
{ {
enable_DMA_ = true; enable_DMA_ = true;
const std::string empty_string;
filename_rx1 = configuration->property(role + ".filename", empty_string);
// override value with commandline flag, if present if (samples_ == 0) // read all file
if (FLAGS_signal_source != "-")
{ {
filename_rx1 = FLAGS_signal_source; /*!
} * BUG workaround: The GNU Radio file source does not stop the receiver after reaching the End of File.
if (FLAGS_s != "-") * A possible solution is to compute the file length in samples using file size, excluding the last 100 milliseconds, and enable always the
{ * valve block
filename_rx1 = FLAGS_s; */
std::ifstream file(filename0.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
std::ifstream::pos_type size;
if (file.is_open())
{
size = file.tellg();
DLOG(INFO) << "Total samples in the file= " << floor(static_cast<double>(size) / static_cast<double>(item_size_));
}
else
{
std::cerr << "SignalSource: Unable to open the samples file " << filename0.c_str() << '\n';
item_size_ = 0;
return;
}
std::streamsize ss = std::cout.precision();
std::cout << std::setprecision(16);
std::cout << "Processing file " << filename0 << ", which contains " << static_cast<double>(size) << " [bytes]\n";
std::cout.precision(ss);
if (size > 0)
{
const int64_t bytes_to_skip = samples_to_skip_ * item_size_;
const int64_t bytes_to_process = static_cast<int64_t>(size) - bytes_to_skip;
samples_ = floor(static_cast<double>(bytes_to_process) / static_cast<double>(item_size_) - ceil(0.002 * static_cast<double>(sample_rate_))); // process all the samples available in the file excluding at least the last 1 ms
}
if (!filename1.empty())
{
std::ifstream file(filename1.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
std::ifstream::pos_type size;
if (file.is_open())
{
size = file.tellg();
DLOG(INFO) << "Total samples in the file= " << floor(static_cast<double>(size) / static_cast<double>(item_size_));
}
else
{
std::cerr << "SignalSource: Unable to open the samples file " << filename1.c_str() << '\n';
item_size_ = 0;
return;
}
std::streamsize ss = std::cout.precision();
std::cout << std::setprecision(16);
std::cout << "Processing file " << filename1 << ", which contains " << static_cast<double>(size) << " [bytes]\n";
std::cout.precision(ss);
uint64_t samples_rx2 = 0;
if (size > 0)
{
const int64_t bytes_to_skip = samples_to_skip_ * item_size_;
const int64_t bytes_to_process = static_cast<int64_t>(size) - bytes_to_skip;
samples_rx2 = floor(static_cast<double>(bytes_to_process) / static_cast<double>(item_size_) - ceil(0.002 * static_cast<double>(sample_rate_))); // process all the samples available in the file excluding at least the last 1 ms
}
samples_ = std::min(samples_, samples_rx2);
}
} }
if (filename_rx1.empty()) CHECK(samples_ > 0) << "File does not contain enough samples to process.";
{ double signal_duration_s = (static_cast<double>(samples_) * (1 / static_cast<double>(sample_rate_))) / 2.0;
filename_rx1 = configuration->property(role + ".filename0", empty_string);
filename_rx2 = configuration->property(role + ".filename1", empty_string);
}
const int l1_band = configuration->property("Channels_1C.count", 0) +
configuration->property("Channels_1B.count", 0);
const int l2_band = configuration->property("Channels_L5.count", 0) + DLOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]";
configuration->property("Channels_5X.count", 0) + std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n";
configuration->property("Channels_2S.count", 0);
if (l1_band != 0) if (filename1.empty())
{ {
freq_band = "L1"; DLOG(INFO) << "File source filename " << filename0;
} }
if (l2_band != 0 && l1_band == 0) else
{ {
freq_band = "L2"; DLOG(INFO) << "File source filename rx1 " << filename0;
} DLOG(INFO) << "File source filename rx2 " << filename1;
if (l1_band != 0 && l2_band != 0)
{
freq_band = "L1L2";
} }
DLOG(INFO) << "Samples " << samples_;
DLOG(INFO) << "Sampling frequency " << sample_rate_;
DLOG(INFO) << "Item type " << item_type;
DLOG(INFO) << "Item size " << item_size_;
DLOG(INFO) << "Repeat " << repeat_;
} }
if (switch_position_ == 2) // Real-time via AD9361 if (switch_position_ == 2) // Real-time via AD9361
{ {
std::cout << "Sample rate: " << sample_rate_ << " Sps\n";
enable_ovf_check_buffer_monitor_active_ = false; // check buffer overflow and buffer monitor disabled by default
// some basic checks // some basic checks
if ((rf_port_select_ != "A_BALANCED") and (rf_port_select_ != "B_BALANCED") and (rf_port_select_ != "A_N") and (rf_port_select_ != "B_N") and (rf_port_select_ != "B_P") and (rf_port_select_ != "C_N") and (rf_port_select_ != "C_P") and (rf_port_select_ != "TX_MONITOR1") and (rf_port_select_ != "TX_MONITOR2") and (rf_port_select_ != "TX_MONITOR1_2")) if ((rf_port_select_ != "A_BALANCED") and (rf_port_select_ != "B_BALANCED") and (rf_port_select_ != "A_N") and (rf_port_select_ != "B_N") and (rf_port_select_ != "B_P") and (rf_port_select_ != "C_N") and (rf_port_select_ != "C_P") and (rf_port_select_ != "TX_MONITOR1") and (rf_port_select_ != "TX_MONITOR2") and (rf_port_select_ != "TX_MONITOR1_2"))
{ {
@@ -262,7 +376,9 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
} }
catch (const std::runtime_error &e) catch (const std::runtime_error &e)
{ {
std::cout << "Exception cached when configuring the RX chain: " << e.what() << '\n'; std::cerr << "Exception cached when configuring the RX chain: " << e.what() << '\n';
item_size_ = 0;
return;
} }
// LOCAL OSCILLATOR DDS GENERATOR FOR DUAL FREQUENCY OPERATION // LOCAL OSCILLATOR DDS GENERATOR FOR DUAL FREQUENCY OPERATION
if (enable_dds_lo_ == true) if (enable_dds_lo_ == true)
@@ -295,7 +411,9 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
} }
catch (const std::runtime_error &e) catch (const std::runtime_error &e)
{ {
std::cout << "Exception cached when configuring the TX carrier: " << e.what() << '\n'; std::cerr << "Exception cached when configuring the TX carrier: " << e.what() << '\n';
item_size_ = 0;
return;
} }
} }
@@ -311,12 +429,12 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
// find the uio device file corresponding to the buffer monitor // find the uio device file corresponding to the buffer monitor
if (find_uio_dev_file_name(device_io_name_buffer_monitor, buffer_monitor_device_name, 0) < 0) if (find_uio_dev_file_name(device_io_name_buffer_monitor, buffer_monitor_device_name, 0) < 0)
{ {
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << buffer_monitor_device_name << std::endl; std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << buffer_monitor_device_name << '\n';
throw std::exception(); item_size_ = 0;
return;
} }
uint32_t num_freq_bands = (freq_band.compare("L1L2")) ? 1 : 2; buffer_monitor_fpga = std::make_shared<Fpga_buffer_monitor>(device_io_name_buffer_monitor, num_freq_bands_, dump_, dump_filename);
buffer_monitor_fpga = std::make_shared<Fpga_buffer_monitor>(device_io_name_buffer_monitor, num_freq_bands, dump_, dump_filename);
thread_buffer_monitor = std::thread([&] { run_buffer_monitor_process(); }); thread_buffer_monitor = std::thread([&] { run_buffer_monitor_process(); });
} }
@@ -329,15 +447,17 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
// find the uio device file corresponding to the dynamic bit selector 0 module. // find the uio device file corresponding to the dynamic bit selector 0 module.
if (find_uio_dev_file_name(device_io_name_dyn_bit_sel_0, dyn_bit_sel_device_name, 0) < 0) if (find_uio_dev_file_name(device_io_name_dyn_bit_sel_0, dyn_bit_sel_device_name, 0) < 0)
{ {
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << std::endl; std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << '\n';
throw std::exception(); item_size_ = 0;
return;
} }
// find the uio device file corresponding to the dynamic bit selector 1 module. // find the uio device file corresponding to the dynamic bit selector 1 module.
if (find_uio_dev_file_name(device_io_name_dyn_bit_sel_1, dyn_bit_sel_device_name, 1) < 0) if (find_uio_dev_file_name(device_io_name_dyn_bit_sel_1, dyn_bit_sel_device_name, 1) < 0)
{ {
std::cout << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << std::endl; std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << '\n';
throw std::exception(); item_size_ = 0;
return;
} }
dynamic_bit_selection_fpga = std::make_shared<Fpga_dynamic_bit_selection>(device_io_name_dyn_bit_sel_0, device_io_name_dyn_bit_sel_1); dynamic_bit_selection_fpga = std::make_shared<Fpga_dynamic_bit_selection>(device_io_name_dyn_bit_sel_0, device_io_name_dyn_bit_sel_1);
thread_dynamic_bit_selection = std::thread([&] { run_dynamic_bit_selection_process(); }); thread_dynamic_bit_selection = std::thread([&] { run_dynamic_bit_selection_process(); });
@@ -418,202 +538,177 @@ Ad9361FpgaSignalSource::~Ad9361FpgaSignalSource()
} }
} }
void Ad9361FpgaSignalSource::start() void Ad9361FpgaSignalSource::start()
{ {
thread_file_to_dma = std::thread([&] { run_DMA_process(freq_band, filename_rx1, filename_rx2); }); thread_file_to_dma = std::thread([&] { run_DMA_process(filename0, filename1, samples_to_skip_, item_size_, samples_, repeat_, dma_buff_offset_pos_, queue_); });
} }
void Ad9361FpgaSignalSource::run_DMA_process(const std::string &FreqBand, const std::string &Filename1, const std::string &Filename2) void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const std::string &filename1, uint64_t &samples_to_skip, size_t &item_size, uint64_t &samples, bool &repeat, uint32_t &dma_buff_offset_pos, Concurrent_Queue<pmt::pmt_t> *queue)
{ {
const int MAX_INPUT_SAMPLES_TOTAL = 16384;
int max_value = 0;
std::ifstream infile1; std::ifstream infile1;
infile1.exceptions(std::ifstream::failbit | std::ifstream::badbit); infile1.exceptions(std::ifstream::failbit | std::ifstream::badbit);
// open the files
try try
{ {
infile1.open(Filename1, std::ios::binary); infile1.open(filename0, std::ios::binary);
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
std::cerr << "Exception opening file " << Filename1 << '\n'; std::cerr << "Exception opening file " << filename0 << '\n';
// stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0)));
return; return;
} }
std::ifstream infile2; std::ifstream infile2;
infile2.exceptions(std::ifstream::failbit | std::ifstream::badbit); if (!filename1.empty())
{
infile2.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
infile2.open(filename1, std::ios::binary);
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Exception opening file " << filename1 << '\n';
// stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0)));
return;
}
}
// skip the initial samples if needed
uint64_t bytes_to_skeep = samples_to_skip * item_size;
try try
{ {
infile2.open(Filename2, std::ios::binary); infile1.ignore(bytes_to_skeep);
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
// could not exist std::cerr << "Exception skipping initial samples file " << filename0 << '\n';
} // stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0)));
// rx signal
std::vector<int8_t> input_samples(MAX_INPUT_SAMPLES_TOTAL * 2);
std::vector<int8_t> input_samples2(MAX_INPUT_SAMPLES_TOTAL * 2);
std::vector<int8_t> input_samples_dma(MAX_INPUT_SAMPLES_TOTAL * 2 * 2);
int nread_elements = 0; // num bytes read from the file corresponding to frequency band 1
int nread_elements2 = 0; // num bytes read from the file corresponding to frequency band 2
int file_completed = 0;
int num_transferred_bytes;
//**************************************************************************
// Open DMA device
//**************************************************************************
const int tx_fd = open("/dev/loop_tx", O_WRONLY);
if (tx_fd < 0)
{
std::cout << "Cannot open loop device\n";
return; return;
} }
//************************************************************************** if (!filename1.empty())
// Open input file
//**************************************************************************
int nsamples = 0;
while (file_completed == 0)
{ {
unsigned int dma_index = 0; try
if (FreqBand == "L1")
{ {
try infile2.ignore(bytes_to_skeep);
{
infile1.read(reinterpret_cast<char *>(input_samples.data()), MAX_INPUT_SAMPLES_TOTAL * 2);
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Exception reading file " << Filename1 << '\n';
}
if (infile1)
{
nread_elements = MAX_INPUT_SAMPLES_TOTAL * 2;
}
else
{
nread_elements = infile1.gcount();
}
nsamples += (nread_elements / 2);
for (int index0 = 0; index0 < (nread_elements); index0 += 2)
{
// channel 1 (queue 1)
input_samples_dma[dma_index] = 0;
input_samples_dma[dma_index + 1] = 0;
// channel 0 (queue 0)
input_samples_dma[dma_index + 2] = input_samples[index0];
input_samples_dma[dma_index + 3] = input_samples[index0 + 1];
dma_index += 4;
}
} }
else if (FreqBand == "L2") catch (const std::ifstream::failure &e)
{
std::cerr << "Exception skipping initial samples file " << filename1 << '\n';
// stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0)));
return;
}
}
// rx signal vectors
std::vector<int8_t> input_samples(sample_block_size * 2); // complex samples
std::vector<int8_t> input_samples_dma(sample_block_size * 4); // complex samples, two frequency bands
int nread_elements = 0; // num bytes read from the file corresponding to frequency band 1
bool run_DMA = true;
int num_transferred_bytes;
// Open DMA device
const int tx_fd = open("/dev/loop_tx", O_WRONLY);
if (tx_fd < 0)
{
std::cerr << "Cannot open loop device\n";
// stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0)));
return;
}
// if only one frequency band is used then clear the samples corresponding to the unused frequency band
uint32_t dma_index = 0;
if (num_freq_bands_ == 1)
{
// if only one file is enabled then clear the samples corresponding to the frequency band that is not used.
for (int index0 = 0; index0 < (nread_elements); index0 += 2)
{
input_samples_dma[dma_index + (2 - dma_buff_offset_pos)] = 0;
input_samples_dma[dma_index + 1 + (2 - dma_buff_offset_pos)] = 0;
dma_index += 4;
}
}
uint64_t nbytes_remaining = samples * item_size;
uint32_t read_buffer_size = sample_block_size * 2; // complex samples
// run the DMA
while (run_DMA)
{
if (nbytes_remaining < read_buffer_size)
{
read_buffer_size = nbytes_remaining;
}
nbytes_remaining = nbytes_remaining - read_buffer_size;
// read filename 0
try
{
infile1.read(reinterpret_cast<char *>(input_samples.data()), read_buffer_size);
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Exception reading file " << filename0 << '\n';
break;
}
if (infile1)
{
nread_elements = read_buffer_size;
}
else
{
// FLAG AS ERROR !! IT SHOULD NEVER HAPPEN
nread_elements = infile1.gcount();
}
for (int index0 = 0; index0 < (nread_elements); index0 += 2)
{
// dma_buff_offset_pos is 1 for the L1 band and 0 for the other bands
input_samples_dma[dma_index + dma_buff_offset_pos] = input_samples[index0];
input_samples_dma[dma_index + 1 + dma_buff_offset_pos] = input_samples[index0 + 1];
dma_index += 4;
}
// read filename 1 (if enabled)
dma_index = 0;
if (num_freq_bands_ > 1)
{ {
try try
{ {
infile1.read(reinterpret_cast<char *>(input_samples.data()), MAX_INPUT_SAMPLES_TOTAL * 2); infile1.read(reinterpret_cast<char *>(input_samples.data()), read_buffer_size);
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
std::cerr << "Exception reading file " << Filename1 << '\n'; std::cerr << "Exception reading file " << filename1 << '\n';
break;
} }
if (infile1) if (infile1)
{ {
nread_elements = MAX_INPUT_SAMPLES_TOTAL * 2; nread_elements = read_buffer_size;
} }
else else
{ {
// FLAG AS ERROR !! IT SHOULD NEVER HAPPEN
nread_elements = infile1.gcount(); nread_elements = infile1.gcount();
} }
nsamples += (nread_elements / 2);
for (int index0 = 0; index0 < (nread_elements); index0 += 2) for (int index0 = 0; index0 < (nread_elements); index0 += 2)
{ {
// channel 1 (queue 1) // filename2 is never the L1 band
input_samples_dma[dma_index] = input_samples[index0]; input_samples_dma[dma_index] = input_samples[index0];
input_samples_dma[dma_index + 1] = input_samples[index0 + 1]; input_samples_dma[dma_index + 1] = input_samples[index0 + 1];
// channel 0 (queue 0)
input_samples_dma[dma_index + 2] = 0;
input_samples_dma[dma_index + 3] = 0;
dma_index += 4;
}
}
else if (FreqBand == "L1L2")
{
try
{
infile1.read(reinterpret_cast<char *>(input_samples.data()), MAX_INPUT_SAMPLES_TOTAL * 2);
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Exception reading file " << Filename1 << '\n';
}
if (infile1)
{
nread_elements = MAX_INPUT_SAMPLES_TOTAL * 2;
}
else
{
nread_elements = infile1.gcount();
}
try
{
infile2.read(reinterpret_cast<char *>(input_samples2.data()), MAX_INPUT_SAMPLES_TOTAL * 2);
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Exception reading file " << Filename1 << '\n';
}
if (infile2)
{
nread_elements2 = MAX_INPUT_SAMPLES_TOTAL * 2;
}
else
{
nread_elements2 = infile2.gcount();
}
if (nread_elements > nread_elements2)
{
nread_elements = nread_elements2; // take the smallest
}
nsamples += (nread_elements / 2);
for (int index0 = 0; index0 < (nread_elements); index0 += 2)
{
if (input_samples[index0] > max_value)
{
max_value = input_samples[index0];
}
else if (-input_samples[index0] > max_value)
{
max_value = -input_samples[index0];
}
if (input_samples[index0 + 1] > max_value)
{
max_value = input_samples[index0 + 1];
}
else if (-input_samples[index0 + 1] > max_value)
{
max_value = -input_samples[index0 + 1];
}
// channel 1 (queue 1)
input_samples_dma[dma_index] = input_samples2[index0];
input_samples_dma[dma_index + 1] = input_samples2[index0 + 1];
// channel 0 (queue 0)
input_samples_dma[dma_index + 2] = input_samples[index0];
input_samples_dma[dma_index + 3] = input_samples[index0 + 1];
dma_index += 4; dma_index += 4;
} }
} }
@@ -625,21 +720,75 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &FreqBand, const
if (num_bytes_sent != num_transferred_bytes) if (num_bytes_sent != num_transferred_bytes)
{ {
std::cerr << "Error: DMA could not send all the required samples\n"; std::cerr << "Error: DMA could not send all the required samples\n";
break;
} }
// Throttle the DMA // Throttle the DMA
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(1));
} }
if (nread_elements != MAX_INPUT_SAMPLES_TOTAL * 2) if (nbytes_remaining == 0)
{ {
file_completed = 1; if (repeat)
} {
// read the file again
nbytes_remaining = samples * item_size;
read_buffer_size = sample_block_size * 2;
try
{
infile1.seekg(0);
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Exception resetting the position of the next byte to be extracted to zero " << filename0 << '\n';
break;
}
// skip the initial samples if needed
uint64_t bytes_to_skeep = samples_to_skip * item_size;
try
{
infile1.ignore(bytes_to_skeep);
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Exception skipping initial samples file " << filename0 << '\n';
break;
}
if (!filename1.empty())
{
try
{
infile2.seekg(0);
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Exception setting the position of the next byte to be extracted to zero " << filename1 << '\n';
break;
}
try
{
infile2.ignore(bytes_to_skeep);
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Exception skipping initial samples file " << filename1 << '\n';
break;
}
}
}
else
{
// the input file is completely processed. Stop the receiver.
run_DMA = false;
}
}
std::unique_lock<std::mutex> lock(dma_mutex); std::unique_lock<std::mutex> lock(dma_mutex);
if (enable_DMA_ == false) if (enable_DMA_ == false)
{ {
file_completed = true; run_DMA = false;
} }
lock.unlock(); lock.unlock();
} }
@@ -652,15 +801,26 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &FreqBand, const
try try
{ {
infile1.close(); infile1.close();
if (FreqBand == "L1L2")
{
infile2.close();
}
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
std::cerr << "Exception closing files " << Filename1 << " and " << Filename2 << '\n'; std::cerr << "Exception closing file " << filename0 << '\n';
} }
if (num_freq_bands_ > 1)
{
try
{
infile2.close();
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Exception closing file " << filename1 << '\n';
}
}
// Stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0)));
} }
@@ -682,6 +842,7 @@ void Ad9361FpgaSignalSource::run_dynamic_bit_selection_process()
} }
} }
void Ad9361FpgaSignalSource::run_buffer_monitor_process() void Ad9361FpgaSignalSource::run_buffer_monitor_process()
{ {
bool enable_ovf_check_buffer_monitor_active = true; bool enable_ovf_check_buffer_monitor_active = true;

View File

@@ -67,15 +67,22 @@ private:
const std::string buffer_monitor_device_name = "buffer_monitor"; // buffer monitor device name const std::string buffer_monitor_device_name = "buffer_monitor"; // buffer monitor device name
const std::string default_dump_filename = std::string("FPGA_buffer_monitor_dump.dat"); const std::string default_dump_filename = std::string("FPGA_buffer_monitor_dump.dat");
// perform dynamic bit selection every 500 ms by default // perform dynamic bit selection every 500 ms by default
static const uint32_t Gain_control_period_ms = 500; const uint32_t Gain_control_period_ms = 500;
// check buffer overflow and perform buffer monitoring every 1s by default // check buffer overflow and perform buffer monitoring every 1s by default
static const uint32_t buffer_monitor_period_ms = 1000; const uint32_t buffer_monitor_period_ms = 1000;
// buffer overflow and buffer monitoring initial delay // buffer overflow and buffer monitoring initial delay
static const uint32_t buffer_monitoring_initial_delay_ms = 2000; const uint32_t buffer_monitoring_initial_delay_ms = 2000;
// sample block size when running in post-processing mode
const int sample_block_size = 16384;
void run_DMA_process(const std::string &FreqBand, void run_DMA_process(const std::string &Filename1,
const std::string &Filename1, const std::string &Filename2,
const std::string &Filename2); uint64_t &samples_to_skip,
size_t &item_size,
uint64_t &samples,
bool &repeat,
uint32_t &dma_buff_offset_pos,
Concurrent_Queue<pmt::pmt_t> *queue);
void run_dynamic_bit_selection_process(); void run_dynamic_bit_selection_process();
void run_buffer_monitor_process(); void run_buffer_monitor_process();
@@ -95,9 +102,8 @@ private:
std::string filter_file_; std::string filter_file_;
std::string filter_source_; std::string filter_source_;
std::string filter_filename_; std::string filter_filename_;
std::string filename_rx1; std::string filename0;
std::string filename_rx2; std::string filename1;
std::string freq_band;
std::mutex dma_mutex; std::mutex dma_mutex;
std::mutex dynamic_bit_selection_mutex; std::mutex dynamic_bit_selection_mutex;
@@ -133,9 +139,17 @@ private:
bool enable_DMA_; bool enable_DMA_;
bool enable_dynamic_bit_selection_; bool enable_dynamic_bit_selection_;
bool enable_ovf_check_buffer_monitor_active_; bool enable_ovf_check_buffer_monitor_active_;
bool enable_ovf_check_buffer_monitor_;
bool dump_; bool dump_;
bool rf_shutdown_; bool rf_shutdown_;
// post-processing mode
uint64_t samples_;
uint64_t samples_to_skip_;
bool repeat_;
uint32_t num_freq_bands_;
uint32_t dma_buff_offset_pos_;
Concurrent_Queue<pmt::pmt_t> *queue_;
}; };

View File

@@ -23,7 +23,6 @@
*/ */
#include "fpga_buffer_monitor.h" #include "fpga_buffer_monitor.h"
#include "command_event.h"
#include "gnss_sdr_create_directory.h" #include "gnss_sdr_create_directory.h"
#include "gnss_sdr_filesystem.h" #include "gnss_sdr_filesystem.h"
#include <glog/logging.h> #include <glog/logging.h>

View File

@@ -25,10 +25,8 @@
#ifndef GNSS_SDR_FPGA_BUFFER_MONITOR_H #ifndef GNSS_SDR_FPGA_BUFFER_MONITOR_H
#define GNSS_SDR_FPGA_BUFFER_MONITOR_H #define GNSS_SDR_FPGA_BUFFER_MONITOR_H
#include "concurrent_queue.h" #include <cstdint> // for int32_t
#include <pmt/pmt.h> // pmt #include <fstream> // for string, ofstream
#include <cstdint> // for int32_t
#include <fstream> // for string, ofstream
/** \addtogroup Signal_Source /** \addtogroup Signal_Source
* \{ */ * \{ */

View File

@@ -201,9 +201,9 @@ void Gnss_Sdr_Supl_Client::read_supl_data()
{ {
/* TS 44.031: GPSTOW, range 0-604799.92, resolution 0.08 sec, 23-bit presentation */ /* TS 44.031: GPSTOW, range 0-604799.92, resolution 0.08 sec, 23-bit presentation */
gps_time.tow = static_cast<double>(assist.time.gps_tow) * 0.08; gps_time.tow = static_cast<double>(assist.time.gps_tow) * 0.08;
gps_time.d_Week = static_cast<double>(assist.time.gps_week); gps_time.week = static_cast<double>(assist.time.gps_week);
gps_time.d_tv_sec = static_cast<double>(assist.time.stamp.tv_sec); gps_time.seconds = static_cast<double>(assist.time.stamp.tv_sec);
gps_time.d_tv_usec = static_cast<double>(assist.time.stamp.tv_usec); gps_time.microseconds = static_cast<double>(assist.time.stamp.tv_usec);
gps_time.valid = true; gps_time.valid = true;
} }
@@ -871,7 +871,7 @@ bool Gnss_Sdr_Supl_Client::read_gal_almanac_from_gsa(const std::string& file_nam
gal_alm.delta_i = std::stod(almanac.child("almanac").child_value("deltai")); gal_alm.delta_i = std::stod(almanac.child("almanac").child_value("deltai"));
gal_alm.M_0 = std::stod(almanac.child("almanac").child_value("m0")); gal_alm.M_0 = std::stod(almanac.child("almanac").child_value("m0"));
gal_alm.ecc = std::stod(almanac.child("almanac").child_value("ecc")); gal_alm.ecc = std::stod(almanac.child("almanac").child_value("ecc"));
gal_alm.delta_sqrtA = std::stod(almanac.child("almanac").child_value("aSqRoot")); gal_alm.sqrtA = std::stod(almanac.child("almanac").child_value("aSqRoot"));
gal_alm.OMEGA_0 = std::stod(almanac.child("almanac").child_value("omega0")); gal_alm.OMEGA_0 = std::stod(almanac.child("almanac").child_value("omega0"));
gal_alm.omega = std::stod(almanac.child("almanac").child_value("w")); gal_alm.omega = std::stod(almanac.child("almanac").child_value("w"));
gal_alm.OMEGAdot = std::stod(almanac.child("almanac").child_value("omegaDot")); gal_alm.OMEGAdot = std::stod(almanac.child("almanac").child_value("omegaDot"));

View File

@@ -19,10 +19,11 @@
#include "gnss_sdr_filesystem.h" #include "gnss_sdr_filesystem.h"
#include <algorithm> // sort #include <algorithm> // sort
#include <cstdlib> // atoi, size_t #include <cstdlib> // atoi, size_t
#include <fstream> // ifstream #include <exception>
#include <iostream> // cout #include <fstream> // ifstream
#include <locale> // isdigit #include <iostream> // cout
#include <sstream> // std::stringstream #include <locale> // isdigit
#include <sstream> // std::stringstream
#include <vector> #include <vector>
@@ -188,7 +189,15 @@ int32_t find_uio_num(const std::string &device_name, uint32_t device_num)
int32_t find_uio_dev_file_name(std::string &device_file_name, const std::string &device_name, uint32_t device_num) int32_t find_uio_dev_file_name(std::string &device_file_name, const std::string &device_name, uint32_t device_num)
{ {
int32_t uio_num = find_uio_num(device_name, device_num); int32_t uio_num = 0;
try
{
uio_num = find_uio_num(device_name, device_num);
}
catch (const std::exception &e)
{
return -1;
}
if (uio_num >= 0) if (uio_num >= 0)
{ {
std::stringstream device_file_name_tmp; std::stringstream device_file_name_tmp;

View File

@@ -209,7 +209,7 @@ void ControlThread::init()
// Make an educated guess // Make an educated guess
time_t rawtime; time_t rawtime;
time(&rawtime); time(&rawtime);
agnss_ref_time_.d_tv_sec = rawtime; agnss_ref_time_.seconds = rawtime;
agnss_ref_time_.valid = true; agnss_ref_time_.valid = true;
} }
else else
@@ -220,8 +220,8 @@ void ControlThread::init()
}; };
if (strptime(ref_time_str.c_str(), "%d/%m/%Y %H:%M:%S", &tm) != nullptr) if (strptime(ref_time_str.c_str(), "%d/%m/%Y %H:%M:%S", &tm) != nullptr)
{ {
agnss_ref_time_.d_tv_sec = timegm(&tm); agnss_ref_time_.seconds = timegm(&tm);
if (agnss_ref_time_.d_tv_sec > 0) if (agnss_ref_time_.seconds > 0)
{ {
agnss_ref_time_.valid = true; agnss_ref_time_.valid = true;
} }
@@ -883,7 +883,7 @@ void ControlThread::assist_GNSS()
time_t ref_rx_utc_time = 0; time_t ref_rx_utc_time = 0;
if (agnss_ref_time_.valid == true) if (agnss_ref_time_.valid == true)
{ {
ref_rx_utc_time = static_cast<time_t>(agnss_ref_time_.d_tv_sec); ref_rx_utc_time = static_cast<time_t>(agnss_ref_time_.seconds);
} }
const std::vector<std::pair<int, Gnss_Satellite>> visible_sats = get_visible_sats(ref_rx_utc_time, ref_LLH); const std::vector<std::pair<int, Gnss_Satellite>> visible_sats = get_visible_sats(ref_rx_utc_time, ref_LLH);

View File

@@ -75,6 +75,7 @@ GNSSFlowgraph::GNSSFlowgraph(std::shared_ptr<ConfigurationInterface> configurati
configuration_ = std::move(configuration); configuration_ = std::move(configuration);
queue_ = std::move(queue); queue_ = std::move(queue);
multiband_ = GNSSFlowgraph::is_multiband(); multiband_ = GNSSFlowgraph::is_multiband();
enable_fpga_offloading_ = configuration_->property("GNSS-SDR.enable_FPGA", false);
init(); init();
} }
@@ -107,17 +108,22 @@ void GNSSFlowgraph::init()
{ {
std::cout << "Creating source " << i << '\n'; std::cout << "Creating source " << i << '\n';
sig_source_.push_back(block_factory->GetSignalSource(configuration_.get(), queue_.get(), i)); sig_source_.push_back(block_factory->GetSignalSource(configuration_.get(), queue_.get(), i));
auto& src = sig_source_.back(); if (enable_fpga_offloading_ == false)
auto RF_Channels = src->getRfChannels();
std::cout << "RF Channels " << RF_Channels << '\n';
for (auto j = 0U; j < RF_Channels; ++j)
{ {
sig_conditioner_.push_back(block_factory->GetSignalConditioner(configuration_.get(), signal_conditioner_ID)); auto& src = sig_source_.back();
signal_conditioner_ID++; auto RF_Channels = src->getRfChannels();
std::cout << "RF Channels " << RF_Channels << '\n';
for (auto j = 0U; j < RF_Channels; ++j)
{
sig_conditioner_.push_back(block_factory->GetSignalConditioner(configuration_.get(), signal_conditioner_ID));
signal_conditioner_ID++;
}
} }
} }
if (!sig_conditioner_.empty())
signal_conditioner_connected_ = std::vector<bool>(sig_conditioner_.size(), false); {
signal_conditioner_connected_ = std::vector<bool>(sig_conditioner_.size(), false);
}
observables_ = block_factory->GetObservables(configuration_.get()); observables_ = block_factory->GetObservables(configuration_.get());
@@ -242,13 +248,14 @@ void GNSSFlowgraph::start()
return; return;
} }
#if ENABLE_FPGA if (enable_fpga_offloading_ == true)
// start the DMA if the receiver is in post-processing mode
if (configuration_->property(sig_source_.at(0)->role() + ".switch_position", 0) == 0)
{ {
sig_source_.at(0)->start(); // start the DMA if the receiver is in post-processing mode
if (configuration_->property(sig_source_.at(0)->role() + ".switch_position", 0) == 0)
{
sig_source_.at(0)->start();
}
} }
#endif
running_ = true; running_ = true;
} }
@@ -261,10 +268,12 @@ void GNSSFlowgraph::stop()
chan->stop_channel(); // stop the acquisition or tracking operation chan->stop_channel(); // stop the acquisition or tracking operation
} }
top_block_->stop(); top_block_->stop();
#if ENABLE_FPGA
#else if (enable_fpga_offloading_ == false)
top_block_->wait(); {
#endif top_block_->wait();
}
running_ = false; running_ = false;
} }
@@ -293,16 +302,28 @@ void GNSSFlowgraph::connect()
} }
#if ENABLE_FPGA #if ENABLE_FPGA
if (connect_fpga_flowgraph() != 0) if (enable_fpga_offloading_ == true)
{ {
LOG(ERROR) << "Unable to connect flowgraph with FPFA off-loading"; if (connect_fpga_flowgraph() != 0)
print_help(); {
return; std::cerr << "Unable to connect flowgraph with FPGA off-loading\n";
print_help();
return;
}
}
else
{
if (connect_desktop_flowgraph() != 0)
{
std::cerr << "Unable to connect flowgraph\n";
print_help();
return;
}
} }
#else #else
if (connect_desktop_flowgraph() != 0) if (connect_desktop_flowgraph() != 0)
{ {
LOG(ERROR) << "Unable to connect flowgraph"; std::cerr << "Unable to connect flowgraph\n";
print_help(); print_help();
return; return;
} }
@@ -326,9 +347,19 @@ void GNSSFlowgraph::disconnect()
connected_ = false; connected_ = false;
#if ENABLE_FPGA #if ENABLE_FPGA
if (disconnect_fpga_flowgraph() != 0) if (enable_fpga_offloading_ == true)
{ {
return; if (disconnect_fpga_flowgraph() != 0)
{
return;
}
}
else
{
if (disconnect_desktop_flowgraph() != 0)
{
return;
}
} }
#else #else
if (disconnect_desktop_flowgraph() != 0) if (disconnect_desktop_flowgraph() != 0)
@@ -343,9 +374,6 @@ void GNSSFlowgraph::disconnect()
int GNSSFlowgraph::connect_desktop_flowgraph() int GNSSFlowgraph::connect_desktop_flowgraph()
{ {
#if ENABLE_FPGA
return 0;
#else
// Connect blocks to the top_block // Connect blocks to the top_block
if (connect_signal_sources() != 0) if (connect_signal_sources() != 0)
{ {
@@ -424,15 +452,11 @@ int GNSSFlowgraph::connect_desktop_flowgraph()
LOG(INFO) << "The GNU Radio flowgraph for the current GNSS-SDR configuration has been successfully connected"; LOG(INFO) << "The GNU Radio flowgraph for the current GNSS-SDR configuration has been successfully connected";
return 0; return 0;
#endif
} }
int GNSSFlowgraph::disconnect_desktop_flowgraph() int GNSSFlowgraph::disconnect_desktop_flowgraph()
{ {
#if ENABLE_FPGA
return 0;
#else
// Disconnect blocks between them // Disconnect blocks between them
if (disconnect_signal_sources_from_signal_conditioners() != 0) if (disconnect_signal_sources_from_signal_conditioners() != 0)
{ {
@@ -491,14 +515,32 @@ int GNSSFlowgraph::disconnect_desktop_flowgraph()
} }
return 0; return 0;
#endif
} }
#if ENABLE_FPGA #if ENABLE_FPGA
int GNSSFlowgraph::connect_fpga_flowgraph() int GNSSFlowgraph::connect_fpga_flowgraph()
{ {
// Check that the Signal Source has been instantiated successfully
for (auto& src : sig_source_)
{
if (src == nullptr)
{
help_hint_ += " * Undefined SignalSource.implementation in the configuration file.\n";
return 1;
}
if (src->item_size() == 0)
{
help_hint_ += " * The global configuration parameter GNSS-SDR.enable_FPGA is set to true,\n";
help_hint_ += " but gnss-sdr does not appear to be executed in an FPGA-equipped platform,\n";
help_hint_ += " or there are some required files that are missing.\n";
return 1;
}
}
// Connect blocks to the top_block // Connect blocks to the top_block
if (connect_channels() != 0) if (connect_channels() != 0)
{ {
return 1; return 1;
@@ -519,19 +561,9 @@ int GNSSFlowgraph::connect_fpga_flowgraph()
// Connect the counter // Connect the counter
if (sig_source_.at(0) != nullptr) if (sig_source_.at(0) != nullptr)
{ {
if (configuration_->property(sig_source_.at(0)->role() + ".enable_FPGA", false) == false) if (connect_fpga_sample_counter() != 0)
{ {
if (connect_sample_counter() != 0) return 1;
{
return 1;
}
}
else
{
if (connect_fpga_sample_counter() != 0)
{
return 1;
}
} }
} }
else else
@@ -546,11 +578,6 @@ int GNSSFlowgraph::connect_fpga_flowgraph()
return 1; return 1;
} }
if (configuration_->property(sig_source_.at(0)->role() + ".enable_FPGA", false) == false)
{
check_signal_conditioners();
}
assign_channels(); assign_channels();
if (connect_observables_to_pvt() != 0) if (connect_observables_to_pvt() != 0)
@@ -572,27 +599,9 @@ int GNSSFlowgraph::connect_fpga_flowgraph()
int GNSSFlowgraph::disconnect_fpga_flowgraph() int GNSSFlowgraph::disconnect_fpga_flowgraph()
{ {
if (configuration_->property(sig_source_.at(0)->role() + ".enable_FPGA", false) == false) if (disconnect_fpga_sample_counter() != 0)
{ {
if (disconnect_signal_sources_from_signal_conditioners() != 0) return 1;
{
return 1;
}
}
if (configuration_->property(sig_source_.at(0)->role() + ".enable_FPGA", false) == false)
{
if (disconnect_sample_counter() != 0)
{
return 1;
}
}
else
{
if (disconnect_fpga_sample_counter() != 0)
{
return 1;
}
} }
if (disconnect_monitors() != 0) if (disconnect_monitors() != 0)
@@ -610,16 +619,6 @@ int GNSSFlowgraph::disconnect_fpga_flowgraph()
return 1; return 1;
} }
if (disconnect_signal_sources() != 0)
{
return 1;
}
if (disconnect_signal_conditioners() != 0)
{
return 1;
}
if (disconnect_channels() != 0) if (disconnect_channels() != 0)
{ {
return 1; return 1;
@@ -971,7 +970,16 @@ int GNSSFlowgraph::connect_fpga_sample_counter()
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
LOG(ERROR) << "Can't connect FPGA sample counter: " << e.what(); std::string reported_error(e.what());
if (std::string::npos != reported_error.find(std::string("filesystem")))
{
help_hint_ += " * The global configuration parameter GNSS-SDR.enable_FPGA is set to true,\n";
help_hint_ += " but gnss-sdr does not appear to be executed in an FPGA-equipped platform.\n";
}
else
{
LOG(ERROR) << reported_error;
}
top_block_->disconnect_all(); top_block_->disconnect_all();
return 1; return 1;
} }
@@ -999,6 +1007,13 @@ int GNSSFlowgraph::disconnect_fpga_sample_counter()
int GNSSFlowgraph::connect_signal_sources_to_signal_conditioners() int GNSSFlowgraph::connect_signal_sources_to_signal_conditioners()
{ {
if (enable_fpga_offloading_)
{
help_hint_ += " * The global configuration parameter GNSS-SDR.enable_FPGA is set to true,\n";
help_hint_ += " but gnss-sdr was not compiled with the -DENABLE_FPGA=ON building option.\n";
top_block_->disconnect_all();
return 1;
}
unsigned int signal_conditioner_ID = 0; unsigned int signal_conditioner_ID = 0;
for (int i = 0; i < sources_count_; i++) for (int i = 0; i < sources_count_; i++)
{ {

View File

@@ -297,6 +297,7 @@ private:
bool enable_monitor_; bool enable_monitor_;
bool enable_acquisition_monitor_; bool enable_acquisition_monitor_;
bool enable_tracking_monitor_; bool enable_tracking_monitor_;
bool enable_fpga_offloading_;
}; };

View File

@@ -27,6 +27,7 @@ set(SYSTEM_PARAMETERS_SOURCES
) )
set(SYSTEM_PARAMETERS_HEADERS set(SYSTEM_PARAMETERS_HEADERS
gnss_almanac.h
gnss_ephemeris.h gnss_ephemeris.h
gnss_satellite.h gnss_satellite.h
gnss_signal.h gnss_signal.h

View File

@@ -39,9 +39,9 @@ public:
Agnss_Ref_Time() = default; Agnss_Ref_Time() = default;
double tow{}; double tow{};
double d_Week{}; double week{};
double d_tv_sec{}; double seconds{};
double d_tv_usec{}; double microseconds{};
bool valid{}; bool valid{};
template <class Archive> template <class Archive>
@@ -56,9 +56,9 @@ public:
{ {
}; };
archive& BOOST_SERIALIZATION_NVP(tow); archive& BOOST_SERIALIZATION_NVP(tow);
archive& BOOST_SERIALIZATION_NVP(d_Week); archive& BOOST_SERIALIZATION_NVP(week);
archive& BOOST_SERIALIZATION_NVP(d_tv_sec); archive& BOOST_SERIALIZATION_NVP(seconds);
archive& BOOST_SERIALIZATION_NVP(d_tv_usec); archive& BOOST_SERIALIZATION_NVP(microseconds);
archive& BOOST_SERIALIZATION_NVP(valid); archive& BOOST_SERIALIZATION_NVP(valid);
} }
}; };

View File

@@ -18,6 +18,7 @@
#ifndef GNSS_SDR_BEIDOU_DNAV_ALMANAC_H #ifndef GNSS_SDR_BEIDOU_DNAV_ALMANAC_H
#define GNSS_SDR_BEIDOU_DNAV_ALMANAC_H #define GNSS_SDR_BEIDOU_DNAV_ALMANAC_H
#include "gnss_almanac.h"
#include <boost/serialization/nvp.hpp> #include <boost/serialization/nvp.hpp>
/** \addtogroup Core /** \addtogroup Core
@@ -29,7 +30,7 @@
/*! /*!
* \brief This class is a storage for the BeiDou D1 almanac * \brief This class is a storage for the BeiDou D1 almanac
*/ */
class Beidou_Dnav_Almanac class Beidou_Dnav_Almanac : public Gnss_Almanac
{ {
public: public:
/*! /*!
@@ -37,18 +38,7 @@ public:
*/ */
Beidou_Dnav_Almanac() = default; Beidou_Dnav_Almanac() = default;
unsigned int PRN{}; //!< SV PRN NUMBER int SV_health{}; //!< SV Health
double delta_i{};
double toa{}; //!< Almanac data reference time of week [s]
double M_0{}; //!< Mean Anomaly at Reference Time [semi-circles]
double ecc{}; //!< Eccentricity [dimensionless]
double sqrtA{}; //!< Square Root of the Semi-Major Axis [sqrt(m)]
double OMEGA_0{}; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles]
double omega{}; //!< Argument of Perigee [semi-cicles]
double OMEGAdot{}; //!< Rate of Right Ascension [semi-circles/s]
int SV_health{}; //!< SV Health
double af0{}; //!< Coefficient 0 of code phase offset model [s]
double af1{}; //!< Coefficient 1 of code phase offset model [s/s]
template <class Archive> template <class Archive>
@@ -60,17 +50,16 @@ public:
ar& BOOST_SERIALIZATION_NVP(PRN); ar& BOOST_SERIALIZATION_NVP(PRN);
ar& BOOST_SERIALIZATION_NVP(delta_i); ar& BOOST_SERIALIZATION_NVP(delta_i);
ar& BOOST_SERIALIZATION_NVP(toa); ar& BOOST_SERIALIZATION_NVP(toa);
// ar& BOOST_SERIALIZATION_NVP(WNa); ar& BOOST_SERIALIZATION_NVP(WNa);
ar& BOOST_SERIALIZATION_NVP(M_0); ar& BOOST_SERIALIZATION_NVP(M_0);
ar& BOOST_SERIALIZATION_NVP(ecc); ar& BOOST_SERIALIZATION_NVP(ecc);
ar& BOOST_SERIALIZATION_NVP(sqrtA); ar& BOOST_SERIALIZATION_NVP(sqrtA);
ar& BOOST_SERIALIZATION_NVP(OMEGA_0); ar& BOOST_SERIALIZATION_NVP(OMEGA_0);
ar& BOOST_SERIALIZATION_NVP(omega); ar& BOOST_SERIALIZATION_NVP(omega);
ar& BOOST_SERIALIZATION_NVP(OMEGAdot); ar& BOOST_SERIALIZATION_NVP(OMEGAdot);
ar& BOOST_SERIALIZATION_NVP(SV_health);
// ar& BOOST_SERIALIZATION_NVP(AS_status);
ar& BOOST_SERIALIZATION_NVP(af0); ar& BOOST_SERIALIZATION_NVP(af0);
ar& BOOST_SERIALIZATION_NVP(af1); ar& BOOST_SERIALIZATION_NVP(af1);
ar& BOOST_SERIALIZATION_NVP(SV_health);
} }
}; };

View File

@@ -18,8 +18,8 @@
#ifndef GNSS_SDR_GALILEO_ALMANAC_H #ifndef GNSS_SDR_GALILEO_ALMANAC_H
#define GNSS_SDR_GALILEO_ALMANAC_H #define GNSS_SDR_GALILEO_ALMANAC_H
#include "gnss_almanac.h"
#include <boost/serialization/nvp.hpp> #include <boost/serialization/nvp.hpp>
#include <cstdint>
/** \addtogroup Core /** \addtogroup Core
* \{ */ * \{ */
@@ -30,7 +30,7 @@
/*! /*!
* \brief This class is a storage for the Galileo SV ALMANAC data * \brief This class is a storage for the Galileo SV ALMANAC data
*/ */
class Galileo_Almanac class Galileo_Almanac : public Gnss_Almanac
{ {
public: public:
/*! /*!
@@ -38,19 +38,7 @@ public:
*/ */
Galileo_Almanac() = default; Galileo_Almanac() = default;
uint32_t PRN{}; //!< SV PRN NUMBER
int32_t toa{};
int32_t WNa{};
int32_t IODa{}; int32_t IODa{};
double delta_i{}; //!< Inclination at reference time relative to i0 = 56º [semi-circles]
double M_0{}; //!< Mean Anomaly at Reference Time [semi-circles]
double ecc{}; //!< Eccentricity [dimensionless]
double delta_sqrtA{}; //!< Square Root of the Semi-Major Axis [sqrt(m)]
double OMEGA_0{}; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles]
double omega{}; //!< Argument of Perigee [semi-cicles]
double OMEGAdot{}; //!< Rate of Right Ascension [semi-circles/s]
double af0{}; //!< Coefficient 0 of code phase offset model [s]
double af1{}; //!< Coefficient 1 of code phase offset model [s/s]
int32_t E5b_HS{}; int32_t E5b_HS{};
int32_t E1B_HS{}; int32_t E1B_HS{};
int32_t E5a_HS{}; int32_t E5a_HS{};
@@ -63,18 +51,18 @@ public:
{ {
}; };
ar& BOOST_SERIALIZATION_NVP(PRN); ar& BOOST_SERIALIZATION_NVP(PRN);
ar& BOOST_SERIALIZATION_NVP(delta_i);
ar& BOOST_SERIALIZATION_NVP(toa); ar& BOOST_SERIALIZATION_NVP(toa);
ar& BOOST_SERIALIZATION_NVP(WNa); ar& BOOST_SERIALIZATION_NVP(WNa);
ar& BOOST_SERIALIZATION_NVP(IODa);
ar& BOOST_SERIALIZATION_NVP(delta_i);
ar& BOOST_SERIALIZATION_NVP(M_0); ar& BOOST_SERIALIZATION_NVP(M_0);
ar& BOOST_SERIALIZATION_NVP(ecc); ar& BOOST_SERIALIZATION_NVP(ecc);
ar& BOOST_SERIALIZATION_NVP(delta_sqrtA); ar& BOOST_SERIALIZATION_NVP(sqrtA);
ar& BOOST_SERIALIZATION_NVP(OMEGA_0); ar& BOOST_SERIALIZATION_NVP(OMEGA_0);
ar& BOOST_SERIALIZATION_NVP(omega); ar& BOOST_SERIALIZATION_NVP(omega);
ar& BOOST_SERIALIZATION_NVP(OMEGAdot); ar& BOOST_SERIALIZATION_NVP(OMEGAdot);
ar& BOOST_SERIALIZATION_NVP(af0); ar& BOOST_SERIALIZATION_NVP(af0);
ar& BOOST_SERIALIZATION_NVP(af1); ar& BOOST_SERIALIZATION_NVP(af1);
ar& BOOST_SERIALIZATION_NVP(IODa);
ar& BOOST_SERIALIZATION_NVP(E5b_HS); ar& BOOST_SERIALIZATION_NVP(E5b_HS);
ar& BOOST_SERIALIZATION_NVP(E1B_HS); ar& BOOST_SERIALIZATION_NVP(E1B_HS);
ar& BOOST_SERIALIZATION_NVP(E5a_HS); ar& BOOST_SERIALIZATION_NVP(E5a_HS);

View File

@@ -19,6 +19,7 @@
Galileo_Almanac Galileo_Almanac_Helper::get_almanac(int i) const Galileo_Almanac Galileo_Almanac_Helper::get_almanac(int i) const
{ {
Galileo_Almanac galileo_almanac; Galileo_Almanac galileo_almanac;
const double sqrtAnominal = 5440.588203494; // square root of Galileo nominal orbit semi-major axis
switch (i) switch (i)
{ {
case 1: case 1:
@@ -29,7 +30,7 @@ Galileo_Almanac Galileo_Almanac_Helper::get_almanac(int i) const
galileo_almanac.delta_i = this->delta_i_7; galileo_almanac.delta_i = this->delta_i_7;
galileo_almanac.M_0 = this->M0_7; galileo_almanac.M_0 = this->M0_7;
galileo_almanac.ecc = this->e_7; galileo_almanac.ecc = this->e_7;
galileo_almanac.delta_sqrtA = this->DELTA_A_7; galileo_almanac.sqrtA = sqrtAnominal + this->DELTA_A_7;
galileo_almanac.OMEGA_0 = this->Omega0_7; galileo_almanac.OMEGA_0 = this->Omega0_7;
galileo_almanac.omega = this->omega_7; galileo_almanac.omega = this->omega_7;
galileo_almanac.OMEGAdot = this->Omega_dot_7; galileo_almanac.OMEGAdot = this->Omega_dot_7;
@@ -48,7 +49,7 @@ Galileo_Almanac Galileo_Almanac_Helper::get_almanac(int i) const
galileo_almanac.delta_i = this->delta_i_8; galileo_almanac.delta_i = this->delta_i_8;
galileo_almanac.M_0 = this->M0_9; galileo_almanac.M_0 = this->M0_9;
galileo_almanac.ecc = this->e_8; galileo_almanac.ecc = this->e_8;
galileo_almanac.delta_sqrtA = this->DELTA_A_8; galileo_almanac.sqrtA = sqrtAnominal + this->DELTA_A_8;
galileo_almanac.OMEGA_0 = this->Omega0_8; galileo_almanac.OMEGA_0 = this->Omega0_8;
galileo_almanac.omega = this->omega_8; galileo_almanac.omega = this->omega_8;
galileo_almanac.OMEGAdot = this->Omega_dot_8; galileo_almanac.OMEGAdot = this->Omega_dot_8;
@@ -66,7 +67,7 @@ Galileo_Almanac Galileo_Almanac_Helper::get_almanac(int i) const
galileo_almanac.delta_i = this->delta_i_9; galileo_almanac.delta_i = this->delta_i_9;
galileo_almanac.M_0 = this->M0_10; galileo_almanac.M_0 = this->M0_10;
galileo_almanac.ecc = this->e_9; galileo_almanac.ecc = this->e_9;
galileo_almanac.delta_sqrtA = this->DELTA_A_9; galileo_almanac.sqrtA = sqrtAnominal + this->DELTA_A_9;
galileo_almanac.OMEGA_0 = this->Omega0_10; galileo_almanac.OMEGA_0 = this->Omega0_10;
galileo_almanac.omega = this->omega_9; galileo_almanac.omega = this->omega_9;
galileo_almanac.OMEGAdot = this->Omega_dot_10; galileo_almanac.OMEGAdot = this->Omega_dot_10;

View File

@@ -0,0 +1,57 @@
/*!
* \file gnss_almanac.h
* \brief Base class for GNSS almanac storage
* \author Carles Fernandez, 2021. cfernandez(at)cttc.es
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_GNSS_ALMANAC_H
#define GNSS_SDR_GNSS_ALMANAC_H
#include <cstdint>
/** \addtogroup Core
* \{ */
/** \addtogroup System_Parameters
* \{ */
/*!
* \brief Base class for GNSS almanac storage
*/
class Gnss_Almanac
{
public:
/*!
* Default constructor
*/
Gnss_Almanac() = default;
uint32_t PRN{}; //!< SV PRN NUMBER
double delta_i{}; //!< Inclination Angle at Reference Time (relative to i_0 = 0.30 semi-circles)
int32_t toa{}; //!< Almanac data reference time of week [s]
int32_t WNa{}; //!< Almanac week number
double M_0{}; //!< Mean Anomaly at Reference Time [semi-circles]
double ecc{}; //!< Eccentricity [dimensionless]
double sqrtA{}; //!< Square Root of the Semi-Major Axis [sqrt(m)]
double OMEGA_0{}; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles]
double omega{}; //!< Argument of Perigee [semi-cicles]
double OMEGAdot{}; //!< Rate of Right Ascension [semi-circles/s]
double af0{}; //!< Coefficient 0 of code phase offset model [s]
double af1{}; //!< Coefficient 1 of code phase offset model [s/s]
};
/** \} */
/** \} */
#endif // GNSS_SDR_GNSS_ALMANAC_H

View File

@@ -184,7 +184,7 @@ double Gnss_Ephemeris::sv_clock_relativistic_term(double transmitTime) const
{ {
n0 = sqrt(GALILEO_GM / (a * a * a)); n0 = sqrt(GALILEO_GM / (a * a * a));
} }
if (this->System == 'E') else if (this->System == 'E')
{ {
n0 = sqrt(BEIDOU_GM / (a * a * a)); n0 = sqrt(BEIDOU_GM / (a * a * a));
} }
@@ -225,7 +225,7 @@ double Gnss_Ephemeris::sv_clock_relativistic_term(double transmitTime) const
{ {
dtr_ = GALILEO_F * this->ecc * this->sqrtA * sek; dtr_ = GALILEO_F * this->ecc * this->sqrtA * sek;
} }
if (this->System == 'B') else if (this->System == 'B')
{ {
dtr_ = BEIDOU_F * this->ecc * this->sqrtA * sek; dtr_ = BEIDOU_F * this->ecc * this->sqrtA * sek;
} }

View File

@@ -18,8 +18,8 @@
#ifndef GNSS_SDR_GPS_ALMANAC_H #ifndef GNSS_SDR_GPS_ALMANAC_H
#define GNSS_SDR_GPS_ALMANAC_H #define GNSS_SDR_GPS_ALMANAC_H
#include "gnss_almanac.h"
#include <boost/serialization/nvp.hpp> #include <boost/serialization/nvp.hpp>
#include <cstdint>
/** \addtogroup Core /** \addtogroup Core
* \{ */ * \{ */
@@ -32,7 +32,7 @@
* *
* See https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf Appendix II * See https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf Appendix II
*/ */
class Gps_Almanac class Gps_Almanac : public Gnss_Almanac
{ {
public: public:
/*! /*!
@@ -40,20 +40,8 @@ public:
*/ */
Gps_Almanac() = default; Gps_Almanac() = default;
uint32_t PRN{}; //!< SV PRN NUMBER
double delta_i{}; //!< Inclination Angle at Reference Time (relative to i_0 = 0.30 semi-circles)
int32_t toa{}; //!< Almanac data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200L) [s]
int32_t WNa{}; //!< Almanac week number
double M_0{}; //!< Mean Anomaly at Reference Time [semi-circles]
double ecc{}; //!< Eccentricity [dimensionless]
double sqrtA{}; //!< Square Root of the Semi-Major Axis [sqrt(m)]
double OMEGA_0{}; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles]
double omega{}; //!< Argument of Perigee [semi-cicles]
double OMEGAdot{}; //!< Rate of Right Ascension [semi-circles/s]
int32_t SV_health{}; //!< SV Health int32_t SV_health{}; //!< SV Health
int32_t AS_status{}; //!< Anti-Spoofing Flags and SV Configuration int32_t AS_status{}; //!< Anti-Spoofing Flags and SV Configuration
double af0{}; //!< Coefficient 0 of code phase offset model [s]
double af1{}; //!< Coefficient 1 of code phase offset model [s/s]
template <class Archive> template <class Archive>
@@ -72,10 +60,10 @@ public:
ar& BOOST_SERIALIZATION_NVP(OMEGA_0); ar& BOOST_SERIALIZATION_NVP(OMEGA_0);
ar& BOOST_SERIALIZATION_NVP(omega); ar& BOOST_SERIALIZATION_NVP(omega);
ar& BOOST_SERIALIZATION_NVP(OMEGAdot); ar& BOOST_SERIALIZATION_NVP(OMEGAdot);
ar& BOOST_SERIALIZATION_NVP(SV_health);
ar& BOOST_SERIALIZATION_NVP(AS_status);
ar& BOOST_SERIALIZATION_NVP(af0); ar& BOOST_SERIALIZATION_NVP(af0);
ar& BOOST_SERIALIZATION_NVP(af1); ar& BOOST_SERIALIZATION_NVP(af1);
ar& BOOST_SERIALIZATION_NVP(SV_health);
ar& BOOST_SERIALIZATION_NVP(AS_status);
} }
}; };

View File

@@ -136,7 +136,7 @@ DECLARE_string(log_dir);
// #include "unit-tests/signal-processing-blocks/acquisition/beidou_b3i_pcps_acquisition_test.cc" // #include "unit-tests/signal-processing-blocks/acquisition/beidou_b3i_pcps_acquisition_test.cc"
#include "unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc"
#include "unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc"
#include "unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc" // #include "unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc"
#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_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/gps_l1_ca_kf_tracking_test.cc"
#include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc"

View File

@@ -1,6 +1,6 @@
/*! /*!
* \file galileo_e1_pcps_acquisition_test_fpga.cc * \file galileo_e1_pcps_acquisition_test_fpga.cc
* \brief This class implements an acquisition test Galileo FPFA acquisition * \brief This class implements an acquisition test Galileo FPGA acquisition
* \authors <ul> * \authors <ul>
* <li> Marc Majoral, 2019. mmajoral(at)cttc.cat * <li> Marc Majoral, 2019. mmajoral(at)cttc.cat
* <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com * <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com

View File

@@ -1,7 +1,7 @@
/*! /*!
* \file serdes_monitor_pvt_test.cc * \file serdes_monitor_pvt_test.cc
* \brief Implements Unit Test for the serdes_monitor_pvt class. * \brief Implements Unit Test for the serdes_monitor_pvt class.
* \author Carles Fernandez_prades, 2019. cfernandez(at)cttc.es * \author Carles Fernandez-Prades, 2019. cfernandez(at)cttc.es
* *
* ----------------------------------------------------------------------------- * -----------------------------------------------------------------------------
* *
@@ -20,7 +20,7 @@
TEST(Serdes_Monitor_Pvt_Test, Simpletest) TEST(Serdes_Monitor_Pvt_Test, Simpletest)
{ {
std::shared_ptr<Monitor_Pvt> monitor = std::make_shared<Monitor_Pvt>(Monitor_Pvt()); auto monitor = std::make_shared<Monitor_Pvt>(Monitor_Pvt());
double true_latitude = 23.4; double true_latitude = 23.4;
monitor->latitude = true_latitude; monitor->latitude = true_latitude;
@@ -29,13 +29,35 @@ TEST(Serdes_Monitor_Pvt_Test, Simpletest)
gnss_sdr::MonitorPvt mon; gnss_sdr::MonitorPvt mon;
mon.ParseFromString(serialized_data); mon.ParseFromString(serialized_data);
serdes.readProtobuffer(mon);
gnss_sdr::GalileoEphemeris ephgal;
Serdes_Galileo_Eph gal_serdes = Serdes_Galileo_Eph();
gal_serdes.readProtobuffer(ephgal);
double read_latitude = mon.latitude(); double read_latitude = mon.latitude();
EXPECT_NEAR(true_latitude, read_latitude, 0.000001); EXPECT_NEAR(true_latitude, read_latitude, 0.000001);
} }
TEST(Serdes_Monitor_Pvt_Test, GalileoEphemerisSerdes)
{
auto eph = std::make_shared<Galileo_Ephemeris>();
int true_tow = 12345;
eph->tow = true_tow;
Serdes_Galileo_Eph gal_serdes = Serdes_Galileo_Eph();
std::string serialized_data = gal_serdes.createProtobuffer(eph);
gnss_sdr::GalileoEphemeris ephgal;
ephgal.ParseFromString(serialized_data);
double true_delta_n = 0.33;
ephgal.set_delta_n(true_delta_n);
int read_tow = ephgal.tow();
EXPECT_EQ(true_tow, read_tow);
double read_delta_n = ephgal.delta_n();
EXPECT_NEAR(true_delta_n, read_delta_n, 0.000001);
auto eph2 = gal_serdes.readProtobuffer(ephgal);
double read2_delta_n = eph2.delta_n;
int read2_tow = eph2.tow;
EXPECT_EQ(true_tow, read2_tow);
EXPECT_NEAR(true_delta_n, read2_delta_n, 0.000001);
}