1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-08-29 17:07:58 +00:00

Merge branch 'ntlab-signal-source' of https://github.com/pedromiguelcp/gnss-sdr into pedromiguelcp-ntlab-signal-source

This commit is contained in:
Carles Fernandez
2025-07-11 18:26:40 +02:00
11 changed files with 733 additions and 2 deletions

View File

@@ -0,0 +1,342 @@
; This is a GNSS-SDR configuration file
; The configuration API is described at https://gnss-sdr.org/docs/sp-blocks/
; SPDX-License-Identifier: GPL-3.0-or-later
; SPDX-FileCopyrightText: (C) 2010-2020 (see AUTHORS file for a list of contributors)
; You can define your own receiver and invoke it by doing
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
;
[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
GNSS-SDR.internal_fs_sps=9937500
GNSS-SDR.telecommand_enabled=true
GNSS-SDR.telecommand_tcp_port=3333
GNSS-SDR.osnma_enable=false
;######### SUPL RRLP GPS assistance configuration #####
; Check https://www.mcc-mnc.com/
; On Android: https://play.google.com/store/apps/details?id=net.its_here.cellidinfo&hl=en
GNSS-SDR.SUPL_gps_enabled=false
GNSS-SDR.SUPL_read_gps_assistance_xml=true
GNSS-SDR.SUPL_gps_ephemeris_server=supl.google.com
GNSS-SDR.SUPL_gps_ephemeris_port=7275
GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com
GNSS-SDR.SUPL_gps_acquisition_port=7275
GNSS-SDR.SUPL_MCC=244
GNSS-SDR.SUPL_MNC=5
GNSS-SDR.SUPL_LAC=0x59e2
GNSS-SDR.SUPL_CI=0x31b0
;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation=NTLab_File_Signal_Source
SignalSource.filename=ntlab.bin ; <- PUT YOUR FILE HERE
SignalSource.sampling_frequency=79500000
SignalSource.sample_type=real
SignalSource.item_type=byte
SignalSource.RF_channels=4
SignalSource.dump=false
;######### SIGNAL_CONDITIONER CONFIG ############
; RF CHANNEL 0
SignalConditioner0.implementation=Signal_Conditioner
; RF CHANNEL 1
SignalConditioner1.implementation=Signal_Conditioner
; RF CHANNEL 2
SignalConditioner2.implementation=Signal_Conditioner
; RF CHANNEL 3
SignalConditioner3.implementation=Signal_Conditioner
;######### DATA_TYPE_ADAPTER CONFIG ############
; RF CHANNEL 0
DataTypeAdapter0.implementation=Pass_Through
DataTypeAdapter0.item_type=float
DataTypeAdapter0.inverted_spectrum=true
; RF CHANNEL 1
DataTypeAdapter1.implementation=Pass_Through
DataTypeAdapter1.item_type=float
; RF CHANNEL 2
DataTypeAdapter2.implementation=Pass_Through
DataTypeAdapter2.item_type=float
DataTypeAdapter2.inverted_spectrum=true
; RF CHANNEL 3
DataTypeAdapter3.implementation=Pass_Through
DataTypeAdapter3.item_type=float
;######### INPUT_FILTER CONFIG ############
; RF CHANNEL 0
InputFilter0.implementation=Freq_Xlating_Fir_Filter
InputFilter0.dump=false
InputFilter0.input_item_type=float
InputFilter0.output_item_type=gr_complex
InputFilter0.taps_item_type=float
InputFilter0.number_of_taps=5
InputFilter0.number_of_bands=2
InputFilter0.band1_begin=0.0
InputFilter0.band1_end=0.45
InputFilter0.band2_begin=0.55
InputFilter0.band2_end=1.0
InputFilter0.ampl1_begin=1.0
InputFilter0.ampl1_end=1.0
InputFilter0.ampl2_begin=0.0
InputFilter0.ampl2_end=0.0
InputFilter0.band1_error=1.0
InputFilter0.band2_error=1.0
InputFilter0.filter_type=bandpass
InputFilter0.grid_density=16
InputFilter0.sampling_frequency=79500000
InputFilter0.IF=14580000
InputFilter0.decimation_factor=8
; RF CHANNEL 1
InputFilter1.implementation=Freq_Xlating_Fir_Filter
InputFilter1.dump=false
InputFilter1.input_item_type=float
InputFilter1.output_item_type=gr_complex
InputFilter1.taps_item_type=float
InputFilter1.number_of_taps=5
InputFilter1.number_of_bands=2
InputFilter1.band1_begin=0.0
InputFilter1.band1_end=0.45
InputFilter1.band2_begin=0.55
InputFilter1.band2_end=1.0
InputFilter1.ampl1_begin=1.0
InputFilter1.ampl1_end=1.0
InputFilter1.ampl2_begin=0.0
InputFilter1.ampl2_end=0.0
InputFilter1.band1_error=1.0
InputFilter1.band2_error=1.0
InputFilter1.filter_type=bandpass
InputFilter1.grid_density=16
InputFilter1.sampling_frequency=79500000
InputFilter1.IF=0
InputFilter1.decimation_factor=8
; RF CHANNEL 2
InputFilter2.implementation=Freq_Xlating_Fir_Filter
InputFilter2.dump=false
InputFilter2.input_item_type=float
InputFilter2.output_item_type=gr_complex
InputFilter2.taps_item_type=float
InputFilter2.number_of_taps=5
InputFilter2.number_of_bands=2
InputFilter2.band1_begin=0.0
InputFilter2.band1_end=0.45
InputFilter2.band2_begin=0.55
InputFilter2.band2_end=1.0
InputFilter2.ampl1_begin=1.0
InputFilter2.ampl1_end=1.0
InputFilter2.ampl2_begin=0.0
InputFilter2.ampl2_end=0.0
InputFilter2.band1_error=1.0
InputFilter2.band2_error=1.0
InputFilter2.filter_type=bandpass
InputFilter2.grid_density=16
InputFilter2.sampling_frequency=79500000
InputFilter2.IF=23550000
InputFilter2.decimation_factor=8
; RF CHANNEL 3
InputFilter3.implementation=Freq_Xlating_Fir_Filter
InputFilter3.dump=false
InputFilter3.input_item_type=float
InputFilter3.output_item_type=gr_complex
InputFilter3.taps_item_type=float
InputFilter3.number_of_taps=5
InputFilter3.number_of_bands=2
InputFilter3.band1_begin=0.0
InputFilter3.band1_end=0.45
InputFilter3.band2_begin=0.55
InputFilter3.band2_end=1.0
InputFilter3.ampl1_begin=1.0
InputFilter3.ampl1_end=1.0
InputFilter3.ampl2_begin=0.0
InputFilter3.ampl2_end=0.0
InputFilter3.band1_error=1.0
InputFilter3.band2_error=1.0
InputFilter3.filter_type=bandpass
InputFilter3.grid_density=16
InputFilter3.sampling_frequency=79500000
InputFilter3.IF=27600000
InputFilter3.decimation_factor=8
;######### RESAMPLER CONFIG ############
; RF CHANNEL 0
Resampler0.implementation=Pass_Through
Resampler0.item_type=gr_complex
; RF CHANNEL 1
Resampler1.implementation=Pass_Through
Resampler1.item_type=gr_complex
; RF CHANNEL 2
Resampler2.implementation=Pass_Through
Resampler2.item_type=gr_complex
; RF CHANNEL 3
Resampler3.implementation=Pass_Through
Resampler3.item_type=gr_complex
;######### CHANNELS GLOBAL CONFIG ############
Channels.in_acquisition=1
Channels_1C.count=8 ;# GPS L1
Channels_L5.count=8 ;# GPS L5
Channels_2S.count=8 ;# GPS L2C
Channels_1B.count=8 ;# Galileo E1b
Channels_5X.count=8 ;# Galileo E5a
Channels_B1.count=8 ;# Beidou B1I
; RF CHANNEL MAPPING
Channels_1C.RF_channel_ID=0
Channels_L5.RF_channel_ID=2
Channels_2S.RF_channel_ID=3
Channels_1B.RF_channel_ID=0
Channels_5X.RF_channel_ID=2
Channels_B1.RF_channel_ID=0
;######### ACQUISITION CONFIG ############
;# GPS L1
Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition
Acquisition_1C.item_type=gr_complex
Acquisition_1C.threshold=2
Acquisition_1C.doppler_max=5000
Acquisition_1C.doppler_step=125
Acquisition_1C.dump=false
Acquisition_1C.dump_filename=./acq_dump.dat
;# GPS L5
Acquisition_L5.implementation=GPS_L5i_PCPS_Acquisition
Acquisition_L5.item_type=gr_complex
Acquisition_L5.threshold=2
Acquisition_L5.doppler_max=5000
Acquisition_L5.doppler_step=125
Acquisition_L5.dump=false
;# GPS L2C
Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition
Acquisition_2S.item_type=gr_complex
Acquisition_2S.threshold=2
Acquisition_2S.doppler_max=5000
Acquisition_2S.doppler_step=150
Acquisition_2S.dump=false
;# Galileo E1b
Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition
Acquisition_1B.item_type=gr_complex
Acquisition_1B.threshold=2
Acquisition_1B.doppler_max=5000
Acquisition_1B.doppler_step=125
Acquisition_1B.dump=false
;# Galileo E5a
Acquisition_5X.implementation=Galileo_E5a_Pcps_Acquisition
Acquisition_5X.item_type=gr_complex
Acquisition_5X.threshold=2
Acquisition_5X.doppler_max=5000
Acquisition_5X.doppler_step=125
Acquisition_5X.dump=false
;# Beidou B1
Acquisition_B1.implementation=BEIDOU_B1I_PCPS_Acquisition
Acquisition_B1.item_type=gr_complex
Acquisition_B1.threshold=2
Acquisition_B1.doppler_max=5000
Acquisition_B1.doppler_step=150
Acquisition_B1.dump=false
;######### TRACKING CONFIG ############
;# GPS L1
Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking
Tracking_1C.item_type=gr_complex
Tracking_1C.dump=false
Tracking_1C.dump_mat=false
;# GPS L5
Tracking_L5.implementation=GPS_L5_DLL_PLL_Tracking
Tracking_L5.item_type=gr_complex
Tracking_L5.dump=false
Tracking_L5.dump_mat=false
;# GPS L2C
Tracking_2S.implementation=GPS_L2_M_DLL_PLL_Tracking
Tracking_2S.item_type=gr_complex
Tracking_2S.dump=false
Tracking_2S.dump_mat=false
;# Galileo E1b
Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking
Tracking_1B.item_type=gr_complex
Tracking_1B.dump=false
Tracking_1B.dump_mat=false
;# Galileo E5a
Tracking_5X.implementation=Galileo_E5a_DLL_PLL_Tracking
Tracking_5X.item_type=gr_complex
Tracking_5X.dump=false
Tracking_5X.dump_mat=false
;# Beidou B1
Tracking_B1.implementation=BEIDOU_B1I_DLL_PLL_Tracking
Tracking_B1.item_type=gr_complex
Tracking_B1.dump=false
Tracking_B1.dump_mat=false
;######### TELEMETRY DECODER CONFIG ############
;# GPS L1
TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder
TelemetryDecoder_1C.dump=false
TelemetryDecoder_1C.dump_mat=false
;# GPS L5
TelemetryDecoder_L5.implementation=GPS_L5_Telemetry_Decoder
TelemetryDecoder_L5.dump=false
TelemetryDecoder_L5.dump_mat=false
;# GPS L2C
TelemetryDecoder_2S.implementation=GPS_L2C_Telemetry_Decoder
TelemetryDecoder_2S.dump=false
TelemetryDecoder_2S.dump_mat=false
;# Galileo E1b
TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder
TelemetryDecoder_1B.dump=false
TelemetryDecoder_1B.dump_mat=false
;# Galileo E5a
TelemetryDecoder_5X.implementation=Galileo_E5a_Telemetry_Decoder
TelemetryDecoder_5X.dump=false
TelemetryDecoder_5X.dump_mat=false
;# Beidou B1
TelemetryDecoder_B1.implementation=BEIDOU_B1I_Telemetry_Decoder
TelemetryDecoder_B1.dump=false
TelemetryDecoder_B1.dump_mat=false
;######### OBSERVABLES CONFIG ############
Observables.implementation=Hybrid_Observables
Observables.dump=false
Observables.dump_filename=./observables.dat
;######### PVT CONFIG ############
PVT.implementation=RTKLIB_PVT
PVT.positioning_mode=Single;PPP_Kinematic;PPP_Static;
PVT.output_rate_ms=500
PVT.display_rate_ms=500
PVT.iono_model=Broadcast;Iono-Free-LC;
PVT.trop_model=Saastamoinen
PVT.flag_rtcm_server=false
PVT.flag_rtcm_tty_port=false
PVT.rtcm_dump_devname=/dev/pts/1
PVT.rtcm_tcp_port=2101
PVT.rtcm_MT1019_rate_ms=5000
PVT.rtcm_MT1077_rate_ms=1000
PVT.rinex_output_enabled=true
PVT.rinexobs_rate_ms=1000
PVT.enable_monitor=true
PVT.monitor_client_addresses=127.0.0.1
PVT.monitor_udp_port=0101
PVT.flag_nmea_tty_port=true
PVT.nmea_dump_devname=/dev/pts/12
PVT.nmea_output_file_enabled=true
PVT.enable_rx_clock_correction=false
PVT.elevation_mask=5
PVT.dump=true
PVT.dump_mat=false
;######### MONITOR CONFIG ############
Monitor.enable_monitor=false
Monitor.decimator_factor=50
Monitor.client_addresses=127.0.0.1
Monitor.udp_port=0101

View File

@@ -43,6 +43,9 @@ All notable changes to GNSS-SDR will be documented in this file.
PDF format. It requires `numpy` and `matplotlib`.
- `File_Signal_Source` fixed file length and sample skip calculations on 32-bit
systems.
- Fixed tracking the same PRN in multiple channels. Previously, this could
happen when the number of acquisition channels was close to the number of
available PRNs for a given signal.
See the definitions of concepts and metrics at
https://gnss-sdr.org/design-forces/

View File

@@ -130,6 +130,7 @@ set(SIGNAL_SOURCE_ADAPTER_SOURCES
labsat_signal_source.cc
two_bit_cpx_file_signal_source.cc
two_bit_packed_file_signal_source.cc
ntlab_file_signal_source.cc
four_bit_cpx_file_signal_source.cc
file_timestamp_signal_source.cc
${OPT_DRIVER_SOURCES}
@@ -149,6 +150,7 @@ set(SIGNAL_SOURCE_ADAPTER_HEADERS
labsat_signal_source.h
two_bit_cpx_file_signal_source.h
two_bit_packed_file_signal_source.h
ntlab_file_signal_source.h
four_bit_cpx_file_signal_source.h
file_timestamp_signal_source.h
${OPT_DRIVER_HEADERS}

View File

@@ -0,0 +1,133 @@
/*!
* \file ntlab_file_signal_source.cc
* \brief Interface of a class that reads signal samples from a file. Each
* sample is two bits from multiple channels.
*
* \author Pedro Pereira, 2025 pereirapedrocp (at) gmail.com
*
* -----------------------------------------------------------------------------
*
* 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
*
* -----------------------------------------------------------------------------
*/
#include "ntlab_file_signal_source.h"
#include "configuration_interface.h"
#include "gnss_sdr_string_literals.h"
#if USE_GLOG_AND_GFLAGS
#include <glog/logging.h>
#else
#include <absl/log/log.h>
#endif
using namespace std::string_literals;
NTLabFileSignalSource::NTLabFileSignalSource(
const ConfigurationInterface* configuration,
const std::string& role,
unsigned int in_streams,
unsigned int out_streams,
Concurrent_Queue<pmt::pmt_t>* queue)
: FileSourceBase(configuration, role, "NTLab_File_Signal_Source"s, queue, "byte"s),
sample_type_(configuration->property(role + ".sample_type", "real"s))
{
int default_n_channlels_ = 4;
n_channels_ = configuration->property(role + ".RF_channels", default_n_channlels_);
if ((n_channels_ != 1) && (n_channels_ != 2) && (n_channels_ != 4))
{
n_channels_ = 4;
LOG(ERROR) << "Number of channels must be 1, 2 or 4 (got " << n_channels_ << "). Using 4.";
}
if (in_streams > 0)
{
LOG(ERROR) << "A signal source does not have input streams";
}
if (out_streams > 1)
{
LOG(ERROR) << "This implementation only supports one output stream";
}
}
std::tuple<size_t, bool> NTLabFileSignalSource::itemTypeToSize()
{
auto is_complex_t = false;
auto item_size = sizeof(char); // default
if (item_type() == "byte")
{
item_size = sizeof(char);
}
else
{
LOG(WARNING) << "Configuration error: Unsupported item type. Using byte.";
}
if (sample_type_ != "real")
{
is_complex_t = false;
}
else
{
LOG(WARNING) << "Configuration error: Unsupported sample type. Using real.";
}
return std::make_tuple(item_size, is_complex_t);
}
double NTLabFileSignalSource::packetsPerSample() const
{
return 4 / n_channels_; // sampling instants in one byte depend on channel count
}
gnss_shared_ptr<gr::block> NTLabFileSignalSource::source() const
{
return unpack_samples_;
}
void NTLabFileSignalSource::create_file_source_hook()
{
unpack_samples_ = make_unpack_ntlab_2bit_samples(item_size(), n_channels_);
DLOG(INFO) << "unpack_byte_2bit_samples(" << unpack_samples_->unique_id() << ")";
}
void NTLabFileSignalSource::pre_connect_hook(gr::top_block_sptr top_block)
{
top_block->connect(file_source(), 0, unpack_samples_, 0);
DLOG(INFO) << "connected file source to samples unpacker";
for (int n = 1; n < n_channels_; n++)
{
top_block->connect(unpack_samples_, n, valve(), n);
DLOG(INFO) << "connected samples unpacker to valve port " << n;
}
}
void NTLabFileSignalSource::pre_disconnect_hook(gr::top_block_sptr top_block)
{
top_block->disconnect(file_source(), 0, unpack_samples_, 0);
DLOG(INFO) << "disconnected file source of samples unpacker";
for (int n = 1; n < n_channels_; n++)
{
top_block->disconnect(unpack_samples_, n, valve(), n);
DLOG(INFO) << "disconnected samples unpacker of valve port " << n;
}
}
gr::basic_block_sptr NTLabFileSignalSource::get_left_block()
{
LOG(WARNING) << "Left block of a signal source should not be retrieved";
return gr::block_sptr();
}
gr::basic_block_sptr NTLabFileSignalSource::get_right_block()
{
return valve();
}

View File

@@ -0,0 +1,72 @@
/*!
* \file ntlab_file_signal_source.h
* \brief Interface of a class that reads signal samples from a file. Each
* sample is two bits from multiple channels.
*
* \author Pedro Pereira, 2025 pereirapedrocp (at) gmail.com
*
* This class represents a file signal source.
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_NTLAB_FILE_SIGNAL_SOURCE_H
#define GNSS_SDR_NTLAB_FILE_SIGNAL_SOURCE_H
#include "file_source_base.h"
#include "unpack_ntlab_2bit_samples.h"
#include <cstddef>
#include <string>
#include <tuple>
/** \addtogroup Signal_Source
* \{ */
/** \addtogroup Signal_Source_adapters
* \{ */
class ConfigurationInterface;
/*!
* \brief Class that reads signals samples from a file
* and adapts it to a SignalSourceInterface
*/
class NTLabFileSignalSource : public FileSourceBase
{
public:
NTLabFileSignalSource(const ConfigurationInterface* configuration,
const std::string& role, unsigned int in_streams,
unsigned int out_streams, Concurrent_Queue<pmt::pmt_t>* queue);
~NTLabFileSignalSource() = default;
gr::basic_block_sptr get_left_block() override;
gr::basic_block_sptr get_right_block() override;
protected:
std::tuple<size_t, bool> itemTypeToSize() override;
double packetsPerSample() const override;
gnss_shared_ptr<gr::block> source() const override;
void create_file_source_hook() override;
void pre_connect_hook(gr::top_block_sptr top_block) override;
void pre_disconnect_hook(gr::top_block_sptr top_block) override;
private:
std::string sample_type_;
unpack_ntlab_2bit_samples_sptr unpack_samples_;
int n_channels_;
};
/** \} */
/** \} */
#endif // GNSS_SDR_NTLAB_FILE_SIGNAL_SOURCE_H

View File

@@ -29,6 +29,7 @@ set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES
unpack_short_byte_samples.cc
rtl_tcp_signal_source_c.cc
unpack_2bit_samples.cc
unpack_ntlab_2bit_samples.cc
unpack_spir_gss6450_samples.cc
labsat23_source.cc
${OPT_DRIVER_SOURCES}
@@ -43,6 +44,7 @@ set(SIGNAL_SOURCE_GR_BLOCKS_HEADERS
unpack_short_byte_samples.h
rtl_tcp_signal_source_c.h
unpack_2bit_samples.h
unpack_ntlab_2bit_samples.h
unpack_spir_gss6450_samples.h
labsat23_source.h
${OPT_DRIVER_HEADERS}

View File

@@ -0,0 +1,79 @@
/*!
* \file unpack_ntlab_2bit_samples.cc
*
* \brief Unpacks multichannel 2-bit samples into 4 real-valued floats
* per input byte.
* \author Pedro Pereira pereirapedrocp (at) gmail.com
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#include "unpack_ntlab_2bit_samples.h"
#include <gnuradio/io_signature.h>
unpack_ntlab_2bit_samples_sptr make_unpack_ntlab_2bit_samples(size_t item_size,
int nchannels)
{
return unpack_ntlab_2bit_samples_sptr(
new unpack_ntlab_2bit_samples(item_size,
nchannels));
}
unpack_ntlab_2bit_samples::unpack_ntlab_2bit_samples(size_t item_size,
int nchannels)
: sync_interpolator("unpack_ntlab_2bit_samples",
gr::io_signature::make(1, 1, item_size),
gr::io_signature::make(nchannels, nchannels, sizeof(float)),
SAMPLES_PER_BYTE / nchannels),
nchannels_(nchannels)
{
}
int unpack_ntlab_2bit_samples::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
auto const *in = reinterpret_cast<signed char const *>(input_items[0]);
int const nch = nchannels_;
std::vector<float *> out(nch);
for (int ch = 0; ch < nch; ++ch)
{
out[ch] = static_cast<float *>(output_items[ch]);
}
for (int i = 0; i < noutput_items; ++i)
{
auto b = static_cast<uint8_t>(in[i]);
int j = 0;
for (int n = 0; n < SAMPLES_PER_BYTE; ++n)
{
int shift = 2 * (3 - n); // 6, 4, 2, 0
int M = (b >> (shift + 1)) & 0x1; // magnitude bit
int S = (b >> shift) & 0x1; // sign bit
int mag = M ? 3 : 1;
int val = S ? +mag : -mag;
out[j][i] = static_cast<float>(val);
if (++j == nch) // iterate through each channel
{
j = 0;
}
}
}
return noutput_items;
}

View File

@@ -0,0 +1,81 @@
/*!
* \file unpack_ntlab_2bit_samples.h
*
* \brief Unpacks multichannel 2-bit samples into 4 real-valued floats
* per input byte.
* \author Pedro Pereira pereirapedrocp (at) gmail.com
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_UNPACK_NTLAB_2BIT_SAMPLES_H
#define GNSS_SDR_UNPACK_NTLAB_2BIT_SAMPLES_H
#include "gnss_block_interface.h"
#include <gnuradio/sync_interpolator.h>
#include <cstdint>
#include <vector>
/** \addtogroup Signal_Source
* \{ */
/** \addtogroup Signal_Source_gnuradio_blocks
* \{ */
class unpack_ntlab_2bit_samples;
using unpack_ntlab_2bit_samples_sptr = gnss_shared_ptr<unpack_ntlab_2bit_samples>;
unpack_ntlab_2bit_samples_sptr make_unpack_ntlab_2bit_samples(
size_t item_size,
int nchannels = 4);
/*!
* \brief This class implements conversion between byte packet multichannel samples
* to 2bit samples 1 byte = 4 2bit samples
*
* Unpack each of the four 2-bit samples in the byte 'b' into four real-valued outputs.
*
* The NTLAB format encodes samples as sign+magnitude pairs in each byte:
* bits 7-6 = [M0 S0] -> sample 0
* bits 5-4 = [M1 S1] -> sample 1
* bits 3-2 = [M2 S2] -> sample 2
* bits 1-0 = [M3 S3] -> sample 3
*
* M = magnitude bit (1->|sample|=3, 0->|sample|=1)
* S = sign bit (1->positive, 0->negative)
*/
class unpack_ntlab_2bit_samples : public gr::sync_interpolator
{
public:
~unpack_ntlab_2bit_samples() = default;
unpack_ntlab_2bit_samples(size_t item_size,
int nchannels);
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
private:
static constexpr int SAMPLES_PER_BYTE = 4;
friend unpack_ntlab_2bit_samples_sptr make_unpack_ntlab_2bit_samples_sptr(
size_t item_size,
int nchannels);
int nchannels_;
};
/** \} */
/** \} */
#endif // GNSS_SDR_UNPACK_NTLAB_2BIT_SAMPLES_H

View File

@@ -102,6 +102,7 @@
#include "notch_filter.h"
#include "notch_filter_lite.h"
#include "nsr_file_signal_source.h"
#include "ntlab_file_signal_source.h"
#include "pass_through.h"
#include "pulse_blanking_filter.h"
#include "rtklib_pvt.h"
@@ -320,6 +321,10 @@ std::unique_ptr<SignalSourceInterface> get_signal_source_block(
{
return std::make_unique<TwoBitPackedFileSignalSource>(configuration, role, in_streams, out_streams, queue);
}
else if (implementation == "NTLab_File_Signal_Source")
{
return std::make_unique<NTLabFileSignalSource>(configuration, role, in_streams, out_streams, queue);
}
else if (implementation == "Spir_File_Signal_Source")
{
return std::make_unique<SpirFileSignalSource>(configuration, role, in_streams, out_streams, queue);

View File

@@ -2192,6 +2192,14 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(const std::string& searched_signal
std::string assist_signal = "";
auto& available_signals = available_signals_map_.at(searched_signal);
if (available_signals.empty())
{
const auto& entry = signal_mapping.at(searched_signal);
const auto& gnss_system_str = entry.first;
const auto& signal_pretty_str = entry.second;
throw std::runtime_error("More ACQUISITION channels than PRNs for signal " + gnss_system_str + " " + signal_pretty_str);
}
switch (mapStringValues_[searched_signal])
{
case evGPS_2S:
@@ -2250,7 +2258,11 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(const std::string& searched_signal
{
result = available_signals.front();
available_signals.pop_front();
available_signals.push_back(result);
const std::string sys = result.get_satellite().get_system();
if ((sys == "Glonass") || (sys == "Beidou"))
{
available_signals.push_back(result);
}
}
return result;

View File

@@ -54,7 +54,7 @@ public:
void update_PRN(uint32_t PRN); //!< Updates the PRN Number when information is decoded, only applies to GLONASS GNAV messages
uint32_t get_PRN() const; //!< Gets satellite's PRN
int32_t get_rf_link() const; //!< Gets the satellite's rf link
std::string get_system() const; //!< Gets the satellite system {"GPS", "GLONASS", "SBAS", "Galileo", "Beidou"}
std::string get_system() const; //!< Gets the satellite system {"GPS", "Glonass", "SBAS", "Galileo", "Beidou"}
std::string get_system_short() const; //!< Gets the satellite system {"G", "R", "SBAS", "E", "C"}
std::string get_block() const; //!< Gets the satellite block. If GPS, returns {"IIA", "IIR", "IIR-M", "IIF"}
std::string what_block(const std::string& system_, uint32_t PRN_); //!< Gets the block of a given satellite