Simultaneous multi-GNSS system acquisition, tracking and telemetry

decoding: Changes in the flowgraph and in the configuration files to mix
channels from different GNSS systems in the same receiver. Hybrid
observables and PVT under construction.

The changes in the configuration file parameter names are NOT backward
compatible. The receiver can still work as usual in single GNSS system
mode but some modification on configuration files are required. Use the
example provided of Hybrid configuration file.
This commit is contained in:
Javier Arribas 2014-06-10 18:58:17 +02:00
parent 2a0df9a5bb
commit b0d33328d5
25 changed files with 1634 additions and 88 deletions

View File

@ -0,0 +1,342 @@
; Default configuration file
; You can define your own receiver and invoke it by doing
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
;
[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz].
GNSS-SDR.internal_fs_hz=4000000
;######### CONTROL_THREAD CONFIG ############
ControlThread.wait_for_flowgraph=false
;######### SIGNAL_SOURCE CONFIG ############
;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental)
SignalSource.implementation=File_Signal_Source
;#filename: path to file with the captured GNSS signal samples to be processed
SignalSource.filename=/Users/javier/signals/2013_09_11_GNSS_SIGNAL_at_CTTC_SPAIN/2013_09_11_GNSS_SIGNAL_at_CTTC_SPAIN_run2.dat
;SignalSource.filename=/Users/javier/signals/cttc_4M_50dB.dat
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
SignalSource.item_type=short
;#sampling_frequency: Original Signal sampling frequency in [Hz]
SignalSource.sampling_frequency=4000000
;#freq: RF front-end center frequency in [Hz]
SignalSource.freq=1575420000
;#gain: Front-end Gain in [dB]
SignalSource.gain=60
;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0)
SignalSource.subdevice=B:0
;#samples: Number of samples to be processed. Notice that 0 indicates the entire file.
SignalSource.samples=0
;#repeat: Repeat the processing file. Disable this option in this version
SignalSource.repeat=false
;#dump: Dump the Signal source data to a file. Disable this option in this version
SignalSource.dump=false
SignalSource.dump_filename=../data/signal_source.dat
;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing.
; it helps to not overload the CPU, but the processing time will be longer.
SignalSource.enable_throttle_control=false
;######### SIGNAL_CONDITIONER CONFIG ############
;## It holds blocks to change data type, filter and resample input data.
;#implementation: Use [Pass_Through] or [Signal_Conditioner]
;#[Pass_Through] disables this block and the [DataTypeAdapter], [InputFilter] and [Resampler] blocks
;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks
SignalConditioner.implementation=Signal_Conditioner
;######### DATA_TYPE_ADAPTER CONFIG ############
;## Changes the type of input data. Please disable it in this version.
;#implementation: [Pass_Through] disables this block
DataTypeAdapter.implementation=Ishort_To_Complex
;######### INPUT_FILTER CONFIG ############
;## Filter the input data. Can be combined with frequency translation for IF signals
;#implementation: Use [Pass_Through] or [Fir_Filter] or [Freq_Xlating_Fir_Filter]
;#[Pass_Through] disables this block
;#[Fir_Filter] enables a FIR Filter
;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation that shifts IF down to zero Hz.
;InputFilter.implementation=Fir_Filter
;InputFilter.implementation=Freq_Xlating_Fir_Filter
InputFilter.implementation=Pass_Through
;#dump: Dump the filtered data to a file.
InputFilter.dump=false
;#dump_filename: Log path and filename.
InputFilter.dump_filename=../data/input_filter.dat
;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation.
;#These options are based on parameters of gnuradio's function: gr_remez.
;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands.
;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version.
InputFilter.input_item_type=gr_complex
;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version.
InputFilter.output_item_type=gr_complex
;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version.
InputFilter.taps_item_type=float
;#number_of_taps: Number of taps in the filter. Increasing this parameter increases the processing time
InputFilter.number_of_taps=5
;#number_of _bands: Number of frequency bands in the filter.
InputFilter.number_of_bands=2
;#bands: frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...].
;#Frequency is in the range [0, 1], with 1 being the Nyquist frequency (Fs/2)
;#The number of band_begin and band_end elements must match the number of bands
InputFilter.band1_begin=0.0
InputFilter.band1_end=0.45
InputFilter.band2_begin=0.55
InputFilter.band2_end=1.0
;#ampl: desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...].
;#The number of ampl_begin and ampl_end elements must match the number of bands
InputFilter.ampl1_begin=1.0
InputFilter.ampl1_end=1.0
InputFilter.ampl2_begin=0.0
InputFilter.ampl2_end=0.0
;#band_error: weighting applied to each band (usually 1).
;#The number of band_error elements must match the number of bands
InputFilter.band1_error=1.0
InputFilter.band2_error=1.0
;#filter_type: one of "bandpass", "hilbert" or "differentiator"
InputFilter.filter_type=bandpass
;#grid_density: determines how accurately the filter will be constructed.
;The minimum value is 16; higher values are slower to compute the filter.
InputFilter.grid_density=16
;#The following options are used only in Freq_Xlating_Fir_Filter implementation.
;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz
InputFilter.sampling_frequency=4000000
InputFilter.IF=0
;######### RESAMPLER CONFIG ############
;## Resamples the input data.
;#implementation: Use [Pass_Through] or [Direct_Resampler]
;#[Pass_Through] disables this block
;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation
;Resampler.implementation=Direct_Resampler
Resampler.implementation=Pass_Through
;#dump: Dump the resamplered data to a file.
Resampler.dump=false
;#dump_filename: Log path and filename.
Resampler.dump_filename=../data/resampler.dat
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
Resampler.item_type=gr_complex
;#sample_freq_in: the sample frequency of the input signal
Resampler.sample_freq_in=4000000
;#sample_freq_out: the desired sample frequency of the output signal
Resampler.sample_freq_out=4000000
;######### CHANNELS GLOBAL CONFIG ############
;#count: Number of available GPS satellite channels.
Channels_GPS.count=2
;#count: Number of available Galileo satellite channels.
Channels_Galileo.count=2
;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
Channels.in_acquisition=1
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
;#if the option is disabled by default is assigned GPS
Channel.system=GPS, Galileo
;#signal:
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
Channel.signal=1C
;######### GPS ACQUISITION CONFIG ############
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
Acquisition_GPS.dump=false
;#filename: Log path and filename
Acquisition_GPS.dump_filename=./acq_dump.dat
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
Acquisition_GPS.item_type=gr_complex
;#if: Signal intermediate frequency in [Hz]
Acquisition_GPS.if=0
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
Acquisition_GPS.sampled_ms=1
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
Acquisition_GPS.implementation=GPS_L1_CA_PCPS_Acquisition
;#threshold: Acquisition threshold
Acquisition_GPS.threshold=0.01
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
;Acquisition_GPS.pfa=0.01
;#doppler_max: Maximum expected Doppler shift [Hz]
Acquisition_GPS.doppler_max=10000
;#doppler_max: Doppler step in the grid search [Hz]
Acquisition_GPS.doppler_step=500
;######### GALILEO ACQUISITION CONFIG ############
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
Acquisition_Galileo.dump=false
;#filename: Log path and filename
Acquisition_Galileo.dump_filename=./acq_dump.dat
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
Acquisition_Galileo.item_type=gr_complex
;#if: Signal intermediate frequency in [Hz]
Acquisition_Galileo.if=0
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
Acquisition_Galileo.sampled_ms=4
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
Acquisition_Galileo.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition
;#threshold: Acquisition threshold
;Acquisition_Galileo.threshold=0
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
Acquisition_Galileo.pfa=0.00002
;#doppler_max: Maximum expected Doppler shift [Hz]
Acquisition_Galileo.doppler_max=15000
;#doppler_max: Doppler step in the grid search [Hz]
Acquisition_Galileo.doppler_step=125
;######### TRACKING GPS CONFIG ############
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
Tracking_GPS.implementation=GPS_L1_CA_DLL_PLL_Tracking
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
Tracking_GPS.item_type=gr_complex
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
Tracking_GPS.if=0
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
Tracking_GPS.dump=false
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
Tracking_GPS.dump_filename=../data/epl_tracking_ch_
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
Tracking_GPS.pll_bw_hz=50.0;
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
Tracking_GPS.dll_bw_hz=4.0;
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
Tracking_GPS.fll_bw_hz=10.0;
;#order: PLL/DLL loop filter order [2] or [3]
Tracking_GPS.order=3;
;######### TRACKING GALILEO CONFIG ############
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
Tracking_Galileo.implementation=Galileo_E1_DLL_PLL_VEML_Tracking
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
Tracking_Galileo.item_type=gr_complex
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
Tracking_Galileo.if=0
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
Tracking_Galileo.dump=false
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
Tracking_Galileo.dump_filename=../data/veml_tracking_ch_
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
Tracking_Galileo.pll_bw_hz=20.0;
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
Tracking_Galileo.dll_bw_hz=2.0;
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
Tracking_Galileo.fll_bw_hz=10.0;
;#order: PLL/DLL loop filter order [2] or [3]
Tracking_Galileo.order=3;
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo
Tracking_Galileo.early_late_space_chips=0.15;
;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6]
Tracking_Galileo.very_early_late_space_chips=0.6;
;######### TELEMETRY DECODER GPS CONFIG ############
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A
TelemetryDecoder_GPS.implementation=GPS_L1_CA_Telemetry_Decoder
TelemetryDecoder_GPS.dump=false
;#decimation factor
TelemetryDecoder_GPS.decimation_factor=4;
;######### TELEMETRY DECODER GALILEO CONFIG ############
;#implementation: Use [Galileo_E1B_Telemetry_Decoder] for Galileo E1B
TelemetryDecoder_Galileo.implementation=Galileo_E1B_Telemetry_Decoder
TelemetryDecoder_Galileo.dump=false
;######### OBSERVABLES CONFIG ############
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
Observables.implementation=Hybrid_Observables
;#dump: Enable or disable the Observables internal binary data file logging [true] or [false]
Observables.dump=false
;#dump_filename: Log path and filename.
Observables.dump_filename=./observables.dat
;######### PVT CONFIG ############
;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version.
PVT.implementation=Hybrid_PVT
;#averaging_depth: Number of PVT observations in the moving average algorithm
PVT.averaging_depth=100
;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]
PVT.flag_averaging=true
;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms]
PVT.output_rate_ms=100;
;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms.
PVT.display_rate_ms=500;
;#dump: Enable or disable the PVT internal binary data file logging [true] or [false]
PVT.dump=false
;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump.
PVT.dump_filename=./PVT
;######### OUTPUT_FILTER CONFIG ############
;# Receiver output filter: Leave this block disabled in this version
OutputFilter.implementation=Null_Sink_Output_Filter
OutputFilter.filename=data/gnss-sdr.dat
OutputFilter.item_type=gr_complex

View File

@ -18,6 +18,7 @@ SignalSource.implementation=File_Signal_Source
;#filename: path to file with the captured GNSS signal samples to be processed
SignalSource.filename=/Users/javier/signals/2013_09_11_GNSS_SIGNAL_at_CTTC_SPAIN/2013_09_11_GNSS_SIGNAL_at_CTTC_SPAIN_run2.dat
;SignalSource.filename=/Users/javier/signals/cttc_4M_60dB.dat
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
SignalSource.item_type=short
@ -164,7 +165,10 @@ Resampler.sample_freq_out=4000000
;######### CHANNELS GLOBAL CONFIG ############
;#count: Number of available satellite channels.
Channels.count=1
;#count: Number of available GPS satellite channels.
Channels_GPS.count=0
;#count: Number of available Galileo satellite channels.
Channels_Galileo.count=4
;#in_acquisition: Number of channels simultaneously acquiring
Channels.in_acquisition=1
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
@ -239,106 +243,106 @@ Channel.signal=1B
;Channel0.system=Galileo
;Channel0.signal=1B
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
Channel0.satellite=20
;Channel0.satellite=20
;######### CHANNEL 1 CONFIG ############
;Channel1.system=Galileo
;Channel1.signal=1B
Channel1.satellite=12
;Channel1.satellite=12
;######### CHANNEL 2 CONFIG ############
;Channel2.system=Galileo
;Channel2.signal=1B
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
Channel2.satellite=11
;Channel2.satellite=11
;######### CHANNEL 3 CONFIG ############
;Channel3.system=Galileo
;Channel3.signal=1B
Channel3.satellite=19
;Channel3.satellite=19
;######### ACQUISITION GLOBAL CONFIG ############
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
Acquisition.dump=false
;#filename: Log path and filename
Acquisition.dump_filename=./acq_dump.dat
Acquisition_Galileo.dump_filename=./acq_dump.dat
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
Acquisition.item_type=gr_complex
Acquisition_Galileo.item_type=gr_complex
;#if: Signal intermediate frequency in [Hz]
Acquisition.if=0
Acquisition_Galileo.if=0
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
Acquisition.sampled_ms=4
Acquisition_Galileo.sampled_ms=4
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
Acquisition.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition
Acquisition_Galileo.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition
;#threshold: Acquisition threshold
;Acquisition.threshold=0
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
Acquisition.pfa=0.00003
Acquisition_Galileo.pfa=0.00003
;#doppler_max: Maximum expected Doppler shift [Hz]
Acquisition.doppler_max=15000
Acquisition_Galileo.doppler_max=15000
;#doppler_max: Doppler step in the grid search [Hz]
Acquisition.doppler_step=125
Acquisition_Galileo.doppler_step=125
;######### ACQUISITION CHANNELS CONFIG ######
;######### ACQUISITION CH 0 CONFIG ############
;#repeat_satellite: Use only jointly with the satellite PRN ID option. The default value is false
Acquisition0.repeat_satellite = true
Acquisition1.repeat_satellite = true
Acquisition2.repeat_satellite = true
Acquisition3.repeat_satellite = true
;Acquisition_Galileo0.repeat_satellite = true
;Acquisition_Galileo1.repeat_satellite = true
;Acquisition_Galileo2.repeat_satellite = true
;Acquisition_Galileo3.repeat_satellite = true
;#cboc: Only for [Galileo_E1_PCPS_Ambiguous_Acquisition]. This option allows you to choose between acquiring with CBOC signal [true] or sinboc(1,1) signal [false].
;#Use only if GNSS-SDR.internal_fs_hz is greater than or equal to 6138000
Acquisition0.cboc=false
Acquisition_Galileo0.cboc=false
;######### ACQUISITION CH 1 CONFIG ############
Acquisition1.cboc=false
Acquisition_Galileo1.cboc=false
;######### TRACKING GLOBAL CONFIG ############
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
Tracking.implementation=Galileo_E1_DLL_PLL_VEML_Tracking
Tracking_Galileo.implementation=Galileo_E1_DLL_PLL_VEML_Tracking
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
Tracking.item_type=gr_complex
Tracking_Galileo.item_type=gr_complex
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
Tracking.if=0
Tracking_Galileo.if=0
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
Tracking.dump=true
Tracking_Galileo.dump=true
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
Tracking.dump_filename=../data/veml_tracking_ch_
Tracking_Galileo.dump_filename=../data/veml_tracking_ch_
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
Tracking.pll_bw_hz=20.0;
Tracking_Galileo.pll_bw_hz=20.0;
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
Tracking.dll_bw_hz=2.0;
Tracking_Galileo.dll_bw_hz=2.0;
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
Tracking.fll_bw_hz=10.0;
Tracking_Galileo.fll_bw_hz=10.0;
;#order: PLL/DLL loop filter order [2] or [3]
Tracking.order=3;
Tracking_Galileo.order=3;
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo
Tracking.early_late_space_chips=0.15;
Tracking_Galileo.early_late_space_chips=0.15;
;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6]
Tracking.very_early_late_space_chips=0.6;
Tracking_Galileo.very_early_late_space_chips=0.6;
;######### TELEMETRY DECODER CONFIG ############
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A or [Galileo_E1B_Telemetry_Decoder] for Galileo E1B
TelemetryDecoder.implementation=Galileo_E1B_Telemetry_Decoder
TelemetryDecoder.dump=false
TelemetryDecoder_Galileo.implementation=Galileo_E1B_Telemetry_Decoder
TelemetryDecoder_Galileo.dump=false
;######### OBSERVABLES CONFIG ############
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.

View File

@ -19,6 +19,7 @@
set(PVT_ADAPTER_SOURCES
gps_l1_ca_pvt.cc
galileo_e1_pvt.cc
hybrid_pvt.cc
)
include_directories(

View File

@ -0,0 +1,109 @@
/*!
* \file hybrid_pvt.cc
* \brief Implementation of an adapter of a GALILEO E1 PVT solver block to a
* PvtInterface
* \author Javier Arribas, 2011. jarribas(at)cttc.es
*
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "hybrid_pvt.h"
#include <glog/logging.h>
#include "configuration_interface.h"
#include "hybrid_pvt_cc.h"
using google::LogMessage;
HybridPvt::HybridPvt(ConfigurationInterface* configuration,
std::string role,
unsigned int in_streams,
unsigned int out_streams,
boost::shared_ptr<gr::msg_queue> queue) :
role_(role),
in_streams_(in_streams),
out_streams_(out_streams),
queue_(queue)
{
// dump parameters
std::string default_dump_filename = "./pvt.dat";
std::string default_nmea_dump_filename = "./nmea_pvt.nmea";
std::string default_nmea_dump_devname = "/dev/tty1";
DLOG(INFO) << "role " << role;
dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
// moving average depth parameters
int averaging_depth;
averaging_depth = configuration->property(role + ".averaging_depth", 10);
bool flag_averaging;
flag_averaging = configuration->property(role + ".flag_averaging", false);
// output rate
int output_rate_ms;
output_rate_ms = configuration->property(role + ".output_rate_ms", 500);
// display rate
int display_rate_ms;
display_rate_ms = configuration->property(role + ".display_rate_ms", 500);
// NMEA Printer settings
bool flag_nmea_tty_port;
flag_nmea_tty_port = configuration->property(role + ".flag_nmea_tty_port", false);
std::string nmea_dump_filename;
nmea_dump_filename = configuration->property(role + ".nmea_dump_filename", default_nmea_dump_filename);
std::string nmea_dump_devname;
nmea_dump_devname = configuration->property(role + ".nmea_dump_devname", default_nmea_dump_devname);
// make PVT object
pvt_ = hybrid_make_pvt_cc(in_streams_, queue_, dump_, dump_filename_, averaging_depth, flag_averaging, output_rate_ms, display_rate_ms, flag_nmea_tty_port, nmea_dump_filename, nmea_dump_devname);
DLOG(INFO) << "pvt(" << pvt_->unique_id() << ")";
}
HybridPvt::~HybridPvt()
{}
void HybridPvt::connect(gr::top_block_sptr top_block)
{
// Nothing to connect internally
DLOG(INFO) << "nothing to connect internally";
}
void HybridPvt::disconnect(gr::top_block_sptr top_block)
{
// Nothing to disconnect
}
gr::basic_block_sptr HybridPvt::get_left_block()
{
return pvt_;
}
gr::basic_block_sptr HybridPvt::get_right_block()
{
return pvt_;
}

View File

@ -0,0 +1,97 @@
/*!
* \file hybrid_pvt.h
* \brief Interface of an adapter of a GALILEO E1 PVT solver block to a
* PvtInterface.
* \author Javier Arribas, 2013. jarribas(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_HYBRID_PVT_H_
#define GNSS_SDR_HYBRID_PVT_H_
#include <string>
#include <gnuradio/msg_queue.h>
#include "pvt_interface.h"
#include "hybrid_pvt_cc.h"
class ConfigurationInterface;
/*!
* \brief This class implements a PvtInterface for Galileo E1
*/
class HybridPvt : public PvtInterface
{
public:
HybridPvt(ConfigurationInterface* configuration,
std::string role,
unsigned int in_streams,
unsigned int out_streams,
boost::shared_ptr<gr::msg_queue> queue);
virtual ~HybridPvt();
std::string role()
{
return role_;
}
//! Returns "Hybrid_Pvt"
std::string implementation()
{
return "Hybrid_PVT";
}
void connect(gr::top_block_sptr top_block);
void disconnect(gr::top_block_sptr top_block);
gr::basic_block_sptr get_left_block();
gr::basic_block_sptr get_right_block();
void reset()
{
return;
}
//! All blocks must have an item_size() function implementation. Returns sizeof(gr_complex)
size_t item_size()
{
return sizeof(gr_complex);
}
private:
hybrid_pvt_cc_sptr pvt_;
bool dump_;
unsigned int fs_in_;
std::string dump_filename_;
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
boost::shared_ptr<gr::msg_queue> queue_;
};
#endif

View File

@ -19,6 +19,7 @@
set(PVT_GR_BLOCKS_SOURCES
gps_l1_ca_pvt_cc.cc
galileo_e1_pvt_cc.cc
hybrid_pvt_cc.cc
)
include_directories(

View File

@ -0,0 +1,260 @@
/*!
* \file hybrid_pvt_cc.cc
* \brief Implementation of a Position Velocity and Time computation block for GPS L1 C/A
* \author Javier Arribas, 2013. jarribas(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "hybrid_pvt_cc.h"
#include <algorithm>
#include <bitset>
#include <iostream>
#include <map>
#include <sstream>
#include <vector>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <gnuradio/gr_complex.h>
#include <gnuradio/io_signature.h>
#include <glog/logging.h>
#include "control_message_factory.h"
#include "gnss_synchro.h"
#include "concurrent_map.h"
using google::LogMessage;
extern concurrent_map<Galileo_Ephemeris> global_galileo_ephemeris_map;
extern concurrent_map<Galileo_Iono> global_galileo_iono_map;
extern concurrent_map<Galileo_Utc_Model> global_galileo_utc_model_map;
hybrid_pvt_cc_sptr
hybrid_make_pvt_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms, bool flag_nmea_tty_port, std::string nmea_dump_filename, std::string nmea_dump_devname)
{
return hybrid_pvt_cc_sptr(new hybrid_pvt_cc(nchannels, queue, dump, dump_filename, averaging_depth, flag_averaging, output_rate_ms, display_rate_ms, flag_nmea_tty_port, nmea_dump_filename, nmea_dump_devname));
}
hybrid_pvt_cc::hybrid_pvt_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int averaging_depth, bool flag_averaging, int output_rate_ms, int display_rate_ms, bool flag_nmea_tty_port, std::string nmea_dump_filename, std::string nmea_dump_devname) :
gr::block("hybrid_pvt_cc", gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)),
gr::io_signature::make(1, 1, sizeof(gr_complex)))
{
d_output_rate_ms = output_rate_ms;
d_display_rate_ms = display_rate_ms;
d_queue = queue;
d_dump = dump;
d_nchannels = nchannels;
d_dump_filename = dump_filename;
std::string dump_ls_pvt_filename = dump_filename;
//initialize kml_printer
std::string kml_dump_filename;
kml_dump_filename = d_dump_filename;
kml_dump_filename.append(".kml");
d_kml_dump.set_headers(kml_dump_filename);
//initialize nmea_printer
d_nmea_printer = new Nmea_Printer(nmea_dump_filename, flag_nmea_tty_port, nmea_dump_devname);
d_dump_filename.append("_raw.dat");
dump_ls_pvt_filename.append("_ls_pvt.dat");
d_averaging_depth = averaging_depth;
d_flag_averaging = flag_averaging;
d_ls_pvt = new galileo_e1_ls_pvt(nchannels, dump_ls_pvt_filename, d_dump);
d_ls_pvt->set_averaging_depth(d_averaging_depth);
d_sample_counter = 0;
d_last_sample_nav_output = 0;
d_rx_time = 0.0;
b_rinex_header_writen = false;
rp = new Rinex_Printer();
// ############# ENABLE DATA FILE LOG #################
if (d_dump == true)
{
if (d_dump_file.is_open() == false)
{
try
{
d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit );
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
LOG(INFO) << "PVT dump enabled Log file: " << d_dump_filename.c_str();
}
catch (const std::ifstream::failure& e)
{
LOG(WARNING) << "Exception opening PVT dump file " << e.what();
}
}
}
}
hybrid_pvt_cc::~hybrid_pvt_cc()
{
d_kml_dump.close_file();
delete d_ls_pvt;
delete rp;
delete d_nmea_printer;
}
bool hybrid_pvt_cc::pseudoranges_pairCompare_min( std::pair<int,Gnss_Synchro> a, std::pair<int,Gnss_Synchro> b)
{
return (a.second.Pseudorange_m) < (b.second.Pseudorange_m);
}
int hybrid_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
{
d_sample_counter++;
std::map<int,Gnss_Synchro> gnss_pseudoranges_map;
Gnss_Synchro **in = (Gnss_Synchro **) &input_items[0]; //Get the input pointer
for (unsigned int i = 0; i < d_nchannels; i++)
{
if (in[i][0].Flag_valid_pseudorange == true)
{
gnss_pseudoranges_map.insert(std::pair<int,Gnss_Synchro>(in[i][0].PRN, in[i][0])); // store valid pseudoranges in a map
d_rx_time = in[i][0].d_TOW_at_current_symbol; // all the channels have the same RX timestamp (common RX time pseudoranges)
}
}
// ############ 1. READ EPHEMERIS/UTC_MODE/IONO FROM GLOBAL MAPS ####
if (global_galileo_ephemeris_map.size() > 0)
{
d_ls_pvt->galileo_ephemeris_map = global_galileo_ephemeris_map.get_map_copy();
}
if (global_galileo_utc_model_map.size() > 0)
{
// UTC MODEL data is shared for all the Galileo satellites. Read always at ID=0
global_galileo_utc_model_map.read(0, d_ls_pvt->galileo_utc_model);
}
if (global_galileo_iono_map.size() > 0)
{
// IONO data is shared for all the Galileo satellites. Read always at ID=0
global_galileo_iono_map.read(0, d_ls_pvt->galileo_iono);
}
// ############ 2 COMPUTE THE PVT ################################
if (gnss_pseudoranges_map.size() > 0 and d_ls_pvt->galileo_ephemeris_map.size() > 0)
{
// compute on the fly PVT solution
if ((d_sample_counter % d_output_rate_ms) == 0)
{
bool pvt_result;
pvt_result = d_ls_pvt->get_PVT(gnss_pseudoranges_map, d_rx_time, d_flag_averaging);
if (pvt_result == true)
{
d_kml_dump.print_position_galileo(d_ls_pvt, d_flag_averaging);
//ToDo: Implement Galileo RINEX and Galileo NMEA outputs
// d_nmea_printer->Print_Nmea_Line(d_ls_pvt, d_flag_averaging);
//
// if (!b_rinex_header_writen) // & we have utc data in nav message!
// {
// std::map<int,Gps_Ephemeris>::iterator gps_ephemeris_iter;
// gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.begin();
// if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end())
// {
// rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second,d_rx_time);
// rp->rinex_nav_header(rp->navFile,d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model);
// b_rinex_header_writen = true; // do not write header anymore
// }
// }
// if(b_rinex_header_writen) // Put here another condition to separate annotations (e.g 30 s)
// {
// // Limit the RINEX navigation output rate to 1/6 seg
// // Notice that d_sample_counter period is 1ms (for GPS correlators)
// if ((d_sample_counter-d_last_sample_nav_output)>=6000)
// {
// rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map);
// d_last_sample_nav_output=d_sample_counter;
// }
// std::map<int,Gps_Ephemeris>::iterator gps_ephemeris_iter;
// gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.begin();
// if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end())
// {
// rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, d_rx_time, gnss_pseudoranges_map);
// }
// }
}
}
// DEBUG MESSAGE: Display position in console output
if (((d_sample_counter % d_display_rate_ms) == 0) and d_ls_pvt->b_valid_position == true)
{
std::cout << "Position at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time)
<< " is Lat = " << d_ls_pvt->d_latitude_d << " [deg], Long = " << d_ls_pvt->d_longitude_d
<< " [deg], Height= " << d_ls_pvt->d_height_m << " [m]" << std::endl;
LOG(INFO) << "Position at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time)
<< " is Lat = " << d_ls_pvt->d_latitude_d << " [deg], Long = " << d_ls_pvt->d_longitude_d
<< " [deg], Height= " << d_ls_pvt->d_height_m << " [m]";
LOG(INFO) << "Dilution of Precision at " << boost::posix_time::to_simple_string(d_ls_pvt->d_position_UTC_time)
<< " is HDOP = " << d_ls_pvt->d_HDOP << " VDOP = "
<< d_ls_pvt->d_VDOP <<" TDOP = " << d_ls_pvt->d_TDOP
<< " GDOP = " << d_ls_pvt->d_GDOP;
}
// MULTIPLEXED FILE RECORDING - Record results to file
if(d_dump == true)
{
try
{
double tmp_double;
for (unsigned int i = 0; i < d_nchannels; i++)
{
tmp_double = in[i][0].Pseudorange_m;
d_dump_file.write((char*)&tmp_double, sizeof(double));
tmp_double = 0;
d_dump_file.write((char*)&tmp_double, sizeof(double));
d_dump_file.write((char*)&d_rx_time, sizeof(double));
}
}
catch (const std::ifstream::failure& e)
{
LOG(WARNING) << "Exception writing observables dump file " << e.what();
}
}
}
consume_each(1); //one by one
return 0;
}

View File

@ -0,0 +1,122 @@
/*!
* \file hybrid_pvt_cc.h
* \brief Interface of a Position Velocity and Time computation block for Galileo E1
* \author Javier Arribas, 2013. jarribas(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_HYBRID_PVT_CC_H
#define GNSS_SDR_HYBRID_PVT_CC_H
#include <fstream>
#include <queue>
#include <utility>
#include <string>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <gnuradio/block.h>
#include <gnuradio/msg_queue.h>
#include "galileo_navigation_message.h"
#include "galileo_ephemeris.h"
#include "galileo_utc_model.h"
#include "galileo_iono.h"
#include "nmea_printer.h"
#include "kml_printer.h"
#include "rinex_printer.h"
#include "galileo_e1_ls_pvt.h"
#include "GPS_L1_CA.h"
#include "Galileo_E1.h"
class hybrid_pvt_cc;
typedef boost::shared_ptr<hybrid_pvt_cc> hybrid_pvt_cc_sptr;
hybrid_pvt_cc_sptr hybrid_make_pvt_cc(unsigned int n_channels,
boost::shared_ptr<gr::msg_queue> queue,
bool dump,
std::string dump_filename,
int averaging_depth,
bool flag_averaging,
int output_rate_ms,
int display_rate_ms,
bool flag_nmea_tty_port,
std::string nmea_dump_filename,
std::string nmea_dump_devname);
/*!
* \brief This class implements a block that computes the PVT solution with Galileo E1 signals
*/
class hybrid_pvt_cc : public gr::block
{
private:
friend hybrid_pvt_cc_sptr hybrid_make_pvt_cc(unsigned int nchannels,
boost::shared_ptr<gr::msg_queue> queue,
bool dump,
std::string dump_filename,
int averaging_depth,
bool flag_averaging,
int output_rate_ms,
int display_rate_ms,
bool flag_nmea_tty_port,
std::string nmea_dump_filename,
std::string nmea_dump_devname);
hybrid_pvt_cc(unsigned int nchannels,
boost::shared_ptr<gr::msg_queue> queue,
bool dump, std::string dump_filename,
int averaging_depth,
bool flag_averaging,
int output_rate_ms,
int display_rate_ms,
bool flag_nmea_tty_port,
std::string nmea_dump_filename,
std::string nmea_dump_devname);
boost::shared_ptr<gr::msg_queue> d_queue;
bool d_dump;
bool b_rinex_header_writen;
Rinex_Printer *rp;
unsigned int d_nchannels;
std::string d_dump_filename;
std::ofstream d_dump_file;
int d_averaging_depth;
bool d_flag_averaging;
int d_output_rate_ms;
int d_display_rate_ms;
long unsigned int d_sample_counter;
long unsigned int d_last_sample_nav_output;
Kml_Printer d_kml_dump;
Nmea_Printer *d_nmea_printer;
double d_rx_time;
galileo_e1_ls_pvt *d_ls_pvt;
bool pseudoranges_pairCompare_min(std::pair<int,Gnss_Synchro> a, std::pair<int,Gnss_Synchro> b);
public:
~hybrid_pvt_cc (); //!< Default destructor
int general_work (int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); //!< PVT Signal Processing
};
#endif

View File

@ -68,26 +68,26 @@ Channel::Channel(ConfigurationInterface *configuration, unsigned int channel,
// IMPORTANT: Do not change the order between set_doppler_max, set_doppler_step and set_threshold
unsigned int doppler_max = configuration->property("Acquisition" + boost::lexical_cast<std::string>(channel_) + ".doppler_max", 0);
if(doppler_max == 0) doppler_max = configuration->property("Acquisition.doppler_max", 0);
unsigned int doppler_max = configuration->property("Acquisition_"+implementation_ + boost::lexical_cast<std::string>(channel_) + ".doppler_max", 0);
if(doppler_max == 0) doppler_max = configuration->property("Acquisition_"+implementation_+".doppler_max", 0);
DLOG(INFO) << "Channel "<< channel_ << " Doppler_max = " << doppler_max;
acq_->set_doppler_max(doppler_max);
unsigned int doppler_step = configuration->property("Acquisition" + boost::lexical_cast<std::string>(channel_) + ".doppler_step" ,0);
if(doppler_step == 0) doppler_step = configuration->property("Acquisition.doppler_step", 500);
unsigned int doppler_step = configuration->property("Acquisition_"+implementation_ + boost::lexical_cast<std::string>(channel_) + ".doppler_step" ,0);
if(doppler_step == 0) doppler_step = configuration->property("Acquisition_"+implementation_+".doppler_step", 500);
DLOG(INFO) << "Channel "<< channel_ << " Doppler_step = " << doppler_step;
acq_->set_doppler_step(doppler_step);
float threshold = configuration->property("Acquisition" + boost::lexical_cast<std::string>(channel_) + ".threshold", 0.0);
if(threshold == 0.0) threshold = configuration->property("Acquisition.threshold", 0.0);
float threshold = configuration->property("Acquisition_"+implementation_+ boost::lexical_cast<std::string>(channel_) + ".threshold", 0.0);
if(threshold == 0.0) threshold = configuration->property("Acquisition_"+implementation_+".threshold", 0.0);
acq_->set_threshold(threshold);
acq_->init();
repeat_ = configuration->property("Acquisition" + boost::lexical_cast<std::string>(channel_) + ".repeat_satellite", false);
repeat_ = configuration->property("Acquisition_"+implementation_+ boost::lexical_cast<std::string>(channel_) + ".repeat_satellite", false);
DLOG(INFO) << "Channel " << channel_ << " satellite repeat = " << repeat_;
acq_->set_channel_queue(&channel_internal_queue_);

View File

@ -74,7 +74,7 @@ public:
std::string role(){ return role_; }
//! Returns "Channel"
std::string implementation(){ return "Channel"; }
std::string implementation(){ return implementation_; }
size_t item_size(){ return 0; }
Gnss_Signal get_signal() const { return gnss_signal_; }
AcquisitionInterface* acquisition(){ return acq_; }

View File

@ -19,6 +19,7 @@
set(OBS_ADAPTER_SOURCES
gps_l1_ca_observables.cc
galileo_e1_observables.cc
hybrid_observables.cc
)
include_directories(

View File

@ -0,0 +1,101 @@
/*!
* \file hybrid_observables.cc
* \brief Implementation of an adapter of a Galileo E1 observables block
* to a ObservablesInterface
* \author Javier Arribas, 2011. jarribas(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "hybrid_observables.h"
#include "configuration_interface.h"
#include "hybrid_observables_cc.h"
#include <glog/logging.h>
using google::LogMessage;
HybridObservables::HybridObservables(ConfigurationInterface* configuration,
std::string role,
unsigned int in_streams,
unsigned int out_streams,
boost::shared_ptr<gr::msg_queue> queue) :
role_(role),
in_streams_(in_streams),
out_streams_(out_streams),
queue_(queue)
{
int output_rate_ms;
output_rate_ms = configuration->property(role + ".output_rate_ms", 500);
std::string default_dump_filename = "./observables.dat";
DLOG(INFO) << "role " << role;
bool flag_averaging;
flag_averaging = configuration->property(role + ".flag_averaging", false);
dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
fs_in_ = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
observables_ = hybrid_make_observables_cc(in_streams_, queue_, dump_, dump_filename_, output_rate_ms, flag_averaging);
observables_->set_fs_in(fs_in_);
DLOG(INFO) << "pseudorange(" << observables_->unique_id() << ")";
}
HybridObservables::~HybridObservables()
{}
void HybridObservables::connect(gr::top_block_sptr top_block)
{
// Nothing to connect internally
DLOG(INFO) << "nothing to connect internally";
}
void HybridObservables::disconnect(gr::top_block_sptr top_block)
{
// Nothing to disconnect
}
gr::basic_block_sptr HybridObservables::get_left_block()
{
return observables_;
}
gr::basic_block_sptr HybridObservables::get_right_block()
{
return observables_;
}

View File

@ -0,0 +1,93 @@
/*!
* \file hybrid_observables.h
* \brief Implementation of an adapter of a Galileo E1 observables block
* to a ObservablesInterface
* \author Mara Branzanti 2013. mara.branzanti(at)gmail.com
* \author Javier Arribas 2013. jarribas(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_hybrid_observables_H_
#define GNSS_SDR_hybrid_observables_H_
#include <string>
#include <gnuradio/msg_queue.h>
#include "observables_interface.h"
#include "hybrid_observables_cc.h"
class ConfigurationInterface;
/*!
* \brief This class implements an ObservablesInterface for Galileo E1B
*/
class HybridObservables : public ObservablesInterface
{
public:
HybridObservables(ConfigurationInterface* configuration,
std::string role,
unsigned int in_streams,
unsigned int out_streams,
boost::shared_ptr<gr::msg_queue> queue);
virtual ~HybridObservables();
std::string role()
{
return role_;
}
//! Returns "Hybrid_Observables"
std::string implementation()
{
return "Hybrid_Observables";
}
void connect(gr::top_block_sptr top_block);
void disconnect(gr::top_block_sptr top_block);
gr::basic_block_sptr get_left_block();
gr::basic_block_sptr get_right_block();
void reset()
{
return;
}
//! All blocks must have an item_size() function implementation
size_t item_size()
{
return sizeof(gr_complex);
}
private:
hybrid_observables_cc_sptr observables_;
bool dump_;
unsigned int fs_in_;
std::string dump_filename_;
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
boost::shared_ptr<gr::msg_queue> queue_;
};
#endif

View File

@ -19,6 +19,7 @@
set(OBS_GR_BLOCKS_SOURCES
gps_l1_ca_observables_cc.cc
galileo_e1_observables_cc.cc
hybrid_observables_cc.cc
)
include_directories(

View File

@ -0,0 +1,215 @@
/*!
* \file hybrid_observables_cc.cc
* \brief Implementation of the pseudorange computation block for Galileo E1
* \author Mara Branzanti 2013. mara.branzanti(at)gmail.com
* \author Javier Arribas 2013. jarribas(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2013 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "hybrid_observables_cc.h"
#include <algorithm>
#include <bitset>
#include <cmath>
#include <iostream>
#include <map>
#include <sstream>
#include <vector>
#include <gnuradio/io_signature.h>
#include <glog/logging.h>
#include "control_message_factory.h"
#include "gnss_synchro.h"
using google::LogMessage;
hybrid_observables_cc_sptr
hybrid_make_observables_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging)
{
return hybrid_observables_cc_sptr(new hybrid_observables_cc(nchannels, queue, dump, dump_filename, output_rate_ms, flag_averaging));
}
hybrid_observables_cc::hybrid_observables_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging) :
gr::block("hybrid_observables_cc", gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)),
gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)))
{
// initialize internal vars
d_queue = queue;
d_dump = dump;
d_nchannels = nchannels;
d_output_rate_ms = output_rate_ms;
d_dump_filename = dump_filename;
d_flag_averaging = flag_averaging;
// ############# ENABLE DATA FILE LOG #################
if (d_dump == true)
{
if (d_dump_file.is_open() == false)
{
try
{
d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit );
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
LOG(INFO) << "Observables dump enabled Log file: " << d_dump_filename.c_str();
}
catch (std::ifstream::failure e)
{
LOG(WARNING) << "Exception opening observables dump file " << e.what();
}
}
}
}
hybrid_observables_cc::~hybrid_observables_cc()
{
d_dump_file.close();
}
bool Hybrid_pairCompare_gnss_synchro_Prn_delay_ms( std::pair<int,Gnss_Synchro> a, std::pair<int,Gnss_Synchro> b)
{
return (a.second.Prn_timestamp_ms) < (b.second.Prn_timestamp_ms);
}
bool Hybrid_pairCompare_gnss_synchro_d_TOW_at_current_symbol( std::pair<int,Gnss_Synchro> a, std::pair<int,Gnss_Synchro> b)
{
return (a.second.d_TOW_at_current_symbol) < (b.second.d_TOW_at_current_symbol);
}
int hybrid_observables_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
{
Gnss_Synchro **in = (Gnss_Synchro **) &input_items[0]; // Get the input pointer
Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0]; // Get the output pointer
Gnss_Synchro current_gnss_synchro[d_nchannels];
std::map<int,Gnss_Synchro> current_gnss_synchro_map;
std::map<int,Gnss_Synchro>::iterator gnss_synchro_iter;
d_sample_counter++; //count for the processed samples
/*
* 1. Read the GNSS SYNCHRO objects from available channels
*/
for (unsigned int i = 0; i < d_nchannels; i++)
{
//Copy the telemetry decoder data to local copy
current_gnss_synchro[i] = in[i][0];
/*
* 1.2 Assume no valid pseudoranges
*/
current_gnss_synchro[i].Flag_valid_pseudorange = false;
current_gnss_synchro[i].Pseudorange_m = 0.0;
if (current_gnss_synchro[i].Flag_valid_word)
{
//record the word structure in a map for pseudorange computation
current_gnss_synchro_map.insert(std::pair<int, Gnss_Synchro>(current_gnss_synchro[i].Channel_ID, current_gnss_synchro[i]));
}
}
/*
* 2. Compute RAW pseudoranges using COMMON RECEPTION TIME algorithm. Use only the valid channels (channels that are tracking a satellite)
*/
DLOG(INFO)<<"gnss_synchro set size="<<current_gnss_synchro_map.size()<<std::endl;
if(current_gnss_synchro_map.size() > 0)
{
/*
* 2.1 Use CURRENT set of measurements and find the nearest satellite
* common RX time algorithm
*/
// what is the most recent symbol TOW in the current set? -> this will be the reference symbol
// gnss_synchro_iter = max_element(current_gnss_synchro_map.begin(), current_gnss_synchro_map.end(), Hybrid_pairCompare_gnss_synchro_d_TOW_at_current_symbol);
// double d_TOW_reference = gnss_synchro_iter->second.d_TOW_at_current_symbol;
// double d_ref_PRN_rx_time_ms = gnss_synchro_iter->second.Prn_timestamp_ms;
//int reference_channel= gnss_synchro_iter->second.Channel_ID;
// Now compute RX time differences due to the PRN alignment in the correlators
// double traveltime_ms;
// double pseudorange_m;
// double delta_rx_time_ms;
for(gnss_synchro_iter = current_gnss_synchro_map.begin(); gnss_synchro_iter != current_gnss_synchro_map.end(); gnss_synchro_iter++)
{
std::cout<<"CH "<<gnss_synchro_iter->second.Channel_ID<<" tracking GNSS System "<<gnss_synchro_iter->second.System<<" has PRN start at= "<<gnss_synchro_iter->second.Prn_timestamp_ms<<" [ms]"<<std::endl;
// // compute the required symbol history shift in order to match the reference symbol
// delta_rx_time_ms = gnss_synchro_iter->second.Prn_timestamp_ms-d_ref_PRN_rx_time_ms;
// //compute the pseudorange
// traveltime_ms = (d_TOW_reference - gnss_synchro_iter->second.d_TOW_at_current_symbol)*1000.0 + delta_rx_time_ms + GALILEO_STARTOFFSET_ms;
// pseudorange_m = traveltime_ms * GALILEO_C_m_ms; // [m]
// // update the pseudorange object
// //current_gnss_synchro[gnss_synchro_iter->second.Channel_ID] = gnss_synchro_iter->second;
// current_gnss_synchro[gnss_synchro_iter->second.Channel_ID].Pseudorange_m = pseudorange_m;
// current_gnss_synchro[gnss_synchro_iter->second.Channel_ID].Flag_valid_pseudorange = true;
// current_gnss_synchro[gnss_synchro_iter->second.Channel_ID].d_TOW_at_current_symbol = round(d_TOW_reference*1000)/1000 + GALILEO_STARTOFFSET_ms/1000.0;
//
}
std::cout<<std::endl;
}
// if(d_dump == true)
// {
// // MULTIPLEXED FILE RECORDING - Record results to file
// try
// {
// double tmp_double;
// for (unsigned int i = 0; i < d_nchannels ; i++)
// {
// tmp_double = current_gnss_synchro[i].d_TOW_at_current_symbol;
// d_dump_file.write((char*)&tmp_double, sizeof(double));
// tmp_double = current_gnss_synchro[i].Prn_timestamp_ms;
// d_dump_file.write((char*)&tmp_double, sizeof(double));
// tmp_double = current_gnss_synchro[i].Pseudorange_m;
// d_dump_file.write((char*)&tmp_double, sizeof(double));
// tmp_double = (double)(current_gnss_synchro[i].Flag_valid_pseudorange==true);
// d_dump_file.write((char*)&tmp_double, sizeof(double));
// tmp_double = current_gnss_synchro[i].PRN;
// d_dump_file.write((char*)&tmp_double, sizeof(double));
// }
// }
// catch (const std::ifstream::failure& e)
// {
// LOG(WARNING) << "Exception writing observables dump file " << e.what();
// }
// }
consume_each(1); //consume one by one
// for (unsigned int i = 0; i < d_nchannels ; i++)
// {
// *out[i] = current_gnss_synchro[i];
// }
//todo: enable output when the hybrid algorithm is completed
return 0; //Output the observables
}

View File

@ -0,0 +1,85 @@
/*!
* \file hybrid_observables_cc.h
* \brief Interface of the observables computation block for Galileo E1
* \author Mara Branzanti 2013. mara.branzanti(at)gmail.com
* \author Javier Arribas 2013. jarribas(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_hybrid_observables_CC_H
#define GNSS_SDR_hybrid_observables_CC_H
#include <fstream>
#include <queue>
#include <string>
#include <utility>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <gnuradio/block.h>
#include <gnuradio/msg_queue.h>
#include "concurrent_queue.h"
#include "galileo_navigation_message.h"
#include "rinex_printer.h"
#include "Galileo_E1.h"
#include "gnss_synchro.h"
class hybrid_observables_cc;
typedef boost::shared_ptr<hybrid_observables_cc> hybrid_observables_cc_sptr;
hybrid_observables_cc_sptr
hybrid_make_observables_cc(unsigned int n_channels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging);
/*!
* \brief This class implements a block that computes Galileo observables
*/
class hybrid_observables_cc : public gr::block
{
public:
~hybrid_observables_cc ();
void set_fs_in(unsigned long int fs_in) {d_fs_in = fs_in;};
int general_work (int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
private:
friend hybrid_observables_cc_sptr
hybrid_make_observables_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging);
hybrid_observables_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_queue> queue, bool dump, std::string dump_filename, int output_rate_ms, bool flag_averaging);
// class private vars
boost::shared_ptr<gr::msg_queue> d_queue;
bool d_dump;
bool d_flag_averaging;
long int d_sample_counter;
unsigned int d_nchannels;
unsigned long int d_fs_in;
int d_output_rate_ms;
std::string d_dump_filename;
std::ofstream d_dump_file;
};
#endif

View File

@ -75,6 +75,10 @@ GpsL1CaTelemetryDecoder::GpsL1CaTelemetryDecoder(ConfigurationInterface* configu
telemetry_decoder_->set_iono_queue(&global_gps_iono_queue);
telemetry_decoder_->set_almanac_queue(&global_gps_almanac_queue);
telemetry_decoder_->set_utc_model_queue(&global_gps_utc_model_queue);
//decimation factor
int decimation_factor=configuration->property(role + ".decimation_factor", 1);
telemetry_decoder_->set_decimation(decimation_factor);
DLOG(INFO) << "global navigation message queue assigned to telemetry_decoder ("<< telemetry_decoder_->unique_id() << ")";
}

View File

@ -492,6 +492,8 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
}
//3. Make the output (copy the object contents to the GNURadio reserved memory)
*out[0] = current_synchro_data;
//std::cout<<"Galileo TLM output on CH="<<this->d_channel << " SAMPLE STAMP="<<d_sample_counter<<std::endl;
return 1;
}

View File

@ -130,7 +130,7 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(
d_TOW_at_Preamble = 0;
d_TOW_at_current_symbol = 0;
flag_TOW_set = false;
d_average_count=0;
//set_history(d_samples_per_bit*8); // At least a history of 8 bits are needed to correlate with the preamble
}
@ -341,12 +341,28 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
LOG(WARNING) << "Exception writing observables dump file " << e.what();
}
}
//3. Make the output (copy the object contents to the GNURadio reserved memory)
*out[0] = current_synchro_data;
return 1;
//todo: implement averaging
d_average_count++;
if (d_average_count==d_decimation_output_factor)
{
d_average_count=0;
//3. Make the output (copy the object contents to the GNURadio reserved memory)
*out[0] = current_synchro_data;
//std::cout<<"GPS TLM output on CH="<<this->d_channel << " SAMPLE STAMP="<<d_sample_counter/d_decimation_output_factor<<std::endl;
return 1;
}else{
return 0;
}
}
void gps_l1_ca_telemetry_decoder_cc::set_decimation(int decimation)
{
d_decimation_output_factor=decimation;
}
void gps_l1_ca_telemetry_decoder_cc::set_satellite(Gnss_Satellite satellite)
{
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());

View File

@ -61,6 +61,12 @@ public:
void set_satellite(Gnss_Satellite satellite); //!< Set satellite PRN
void set_channel(int channel); //!< Set receiver's channel
/*!
* \brief Set decimation factor to average the GPS synchronization estimation output from the tracking module.
*/
void set_decimation(int decimation);
/*!
* \brief Set the satellite data queue
*/
@ -114,6 +120,10 @@ private:
bool d_flag_preamble;
int d_word_number;
// output averaging and decimation
int d_average_count;
int d_decimation_output_factor;
long d_fs_in;
//double d_preamble_duration_seconds;
// navigation message vars

View File

@ -558,6 +558,7 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items,gr_vect
}
consume_each(d_current_prn_length_samples); // this is required for gr_block derivates
d_sample_counter += d_current_prn_length_samples; //count for the processed samples
//std::cout<<"Galileo tracking output at sample "<<d_sample_counter<<std::endl;
return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false
}

View File

@ -598,6 +598,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in
consume_each(d_current_prn_length_samples); // this is necessary in gr::block derivates
d_sample_counter += d_current_prn_length_samples; //count for the processed samples
//LOG(INFO)<<"GPS tracking output end on CH="<<this->d_channel << " SAMPLE STAMP="<<d_sample_counter<<std::endl;
return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false
}

View File

@ -76,8 +76,10 @@
#include "sbas_l1_telemetry_decoder.h"
#include "gps_l1_ca_observables.h"
#include "galileo_e1_observables.h"
#include "hybrid_observables.h"
#include "gps_l1_ca_pvt.h"
#include "galileo_e1_pvt.h"
#include "hybrid_pvt.h"
#if OPENCL_BLOCKS
#include "gps_l1_ca_pcps_opencl_acquisition.h"
@ -177,8 +179,9 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetObservables(std::shared
std::string default_implementation = "GPS_L1_CA_Observables";
std::string implementation = configuration->property("Observables.implementation", default_implementation);
LOG(INFO) << "Getting Observables with implementation " << implementation;
unsigned int channel_count = configuration->property("Channels.count", 12);
return GetBlock(configuration, "Observables", implementation, channel_count, channel_count, queue);
unsigned int Galileo_channels = configuration->property("Channels_Galileo.count", 12);
unsigned int GPS_channels = configuration->property("Channels_GPS.count", 12);
return GetBlock(configuration, "Observables", implementation, Galileo_channels + GPS_channels, Galileo_channels + GPS_channels, queue);
}
@ -189,8 +192,9 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetPVT(std::shared_ptr<Con
std::string default_implementation = "Pass_Through";
std::string implementation = configuration->property("PVT.implementation", default_implementation);
LOG(INFO) << "Getting PVT with implementation " << implementation;
unsigned int channel_count = configuration->property("Channels.count", 12);
return GetBlock(configuration, "PVT", implementation, channel_count, 1, queue);
unsigned int Galileo_channels = configuration->property("Channels_Galileo.count", 12);
unsigned int GPS_channels = configuration->property("Channels_GPS.count", 12);
return GetBlock(configuration, "PVT", implementation, Galileo_channels + GPS_channels, 1, queue);
}
@ -204,8 +208,8 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetOutputFilter(std::share
return GetBlock(configuration, "OutputFilter", implementation, 1, 0, queue);
}
std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel(
//********* GPS CHANNEL *****************
std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_GPS(
std::shared_ptr<ConfigurationInterface> configuration,
std::string acq, std::string trk, std::string tlm, int channel,
boost::shared_ptr<gr::msg_queue> queue)
@ -217,47 +221,108 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel(
<< acq << ", Tracking Implementation: " << trk << ", Telemetry Decoder implementation: " << tlm;
std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue);
std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition", acq, 1, 1, queue);
std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking", trk, 1, 1, queue);
std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder", tlm, 1, 1, queue);
std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_GPS", acq, 1, 1, queue);
std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_GPS", trk, 1, 1, queue);
std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_GPS", tlm, 1, 1, queue);
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, pass_through_.release(),
acq_.release(),
trk_.release(),
tlm_.release(),
"Channel", "Channel", queue));
"Channel", "GPS", queue));
return channel_;
}
//********* GALILEO CHANNEL *****************
std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_Galileo(
std::shared_ptr<ConfigurationInterface> configuration,
std::string acq, std::string trk, std::string tlm, int channel,
boost::shared_ptr<gr::msg_queue> queue)
{
std::stringstream stream;
stream << channel;
std::string id = stream.str();
LOG(INFO) << "Instantiating Channel " << id << " with Acquisition Implementation: "
<< acq << ", Tracking Implementation: " << trk << ", Telemetry Decoder implementation: " << tlm;
std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue);
std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_Galileo", acq, 1, 1, queue);
std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_Galileo", trk, 1, 1, queue);
std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_Galileo", tlm, 1, 1, queue);
std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, pass_through_.release(),
acq_.release(),
trk_.release(),
tlm_.release(),
"Channel", "Galileo", queue));
return channel_;
}
std::unique_ptr<std::vector<std::unique_ptr<GNSSBlockInterface>>> GNSSBlockFactory::GetChannels(
std::shared_ptr<ConfigurationInterface> configuration, boost::shared_ptr<gr::msg_queue> queue)
{
std::string default_implementation = "Pass_Through";
unsigned int channel_count = configuration->property("Channels.count", 12);
LOG(INFO) << "Getting " << channel_count << " channels";
unsigned int channel_count;
std::string tracking;
std::string telemetry_decoder;
std::string acquisition_implementation;
std::unique_ptr<std::vector<std::unique_ptr<GNSSBlockInterface>>> channels(new std::vector<std::unique_ptr<GNSSBlockInterface>>());
std::string tracking = configuration->property("Tracking.implementation", default_implementation);
std::string telemetry_decoder = configuration->property("TelemetryDecoder.implementation", default_implementation);
std::string acquisition_implementation = configuration->property("Acquisition.implementation", default_implementation);
unsigned int channel_absolute_id=0;
//**************** GPS CHANNELS **********************
channel_count= configuration->property("Channels_GPS.count", 12);
LOG(INFO) << "Getting " << channel_count << " GPS channels";
tracking = configuration->property("Tracking_GPS.implementation", default_implementation);
telemetry_decoder = configuration->property("TelemetryDecoder_GPS.implementation", default_implementation);
acquisition_implementation = configuration->property("Acquisition_GPS.implementation", default_implementation);
for (unsigned int i = 0; i < channel_count; i++)
{
std::string acquisition_implementation_specific = configuration->property(
"Acquisition" + boost::lexical_cast<std::string>(i) + ".implementation",
"Acquisition_GPS" + boost::lexical_cast<std::string>(i) + ".implementation",
default_implementation);
if(acquisition_implementation_specific.compare(default_implementation) != 0)
{
acquisition_implementation = acquisition_implementation_specific;
}
channels->push_back(std::move(GetChannel(configuration,
acquisition_implementation, tracking, telemetry_decoder, i, queue)));
channels->push_back(std::move(GetChannel_GPS(configuration,
acquisition_implementation, tracking, telemetry_decoder, channel_absolute_id, queue)));
channel_absolute_id++;
}
//**************** GALILEO CHANNELS **********************
channel_count= configuration->property("Channels_Galileo.count", 12);
LOG(INFO) << "Getting " << channel_count << " Galileo channels";
tracking = configuration->property("Tracking_Galileo.implementation", default_implementation);
telemetry_decoder = configuration->property("TelemetryDecoder_Galileo.implementation", default_implementation);
acquisition_implementation = configuration->property("Acquisition_Galileo.implementation", default_implementation);
for (unsigned int i = 0; i < channel_count; i++)
{
std::string acquisition_implementation_specific = configuration->property(
"Acquisition_Galileo" + boost::lexical_cast<std::string>(i) + ".implementation",
default_implementation);
if(acquisition_implementation_specific.compare(default_implementation) != 0)
{
acquisition_implementation = acquisition_implementation_specific;
}
channels->push_back(std::move(GetChannel_Galileo(configuration,
acquisition_implementation, tracking, telemetry_decoder, channel_absolute_id, queue)));
channel_absolute_id++;
}
return channels;
}
@ -526,7 +591,12 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
out_streams, queue));
block = std::move(block_);
}
else if (implementation.compare("Hybrid_Observables") == 0)
{
std::unique_ptr<GNSSBlockInterface> block_(new HybridObservables(configuration.get(), role, in_streams,
out_streams, queue));
block = std::move(block_);
}
// PVT -------------------------------------------------------------------------
else if (implementation.compare("GPS_L1_CA_PVT") == 0)
{
@ -540,6 +610,12 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
out_streams, queue));
block = std::move(block_);
}
else if (implementation.compare("Hybrid_PVT") == 0)
{
std::unique_ptr<GNSSBlockInterface> block_(new HybridPvt(configuration.get(), role, in_streams,
out_streams, queue));
block = std::move(block_);
}
// OUTPUT FILTERS --------------------------------------------------------------
else if (implementation.compare("Null_Sink_Output_Filter") == 0)
{
@ -556,7 +632,7 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
else
{
// Log fatal. This causes execution to stop.
LOG(ERROR) << implementation << ": Undefined implementation for block";
LOG(ERROR) << role<<"."<<implementation << ": Undefined implementation for block";
}
return std::move(block);
}
@ -645,7 +721,7 @@ std::unique_ptr<AcquisitionInterface> GNSSBlockFactory::GetAcqBlock(
else
{
// Log fatal. This causes execution to stop.
LOG(ERROR) << implementation << ": Undefined implementation for block";
LOG(ERROR) << role<<"."<<implementation << ": Undefined implementation for block";
}
return std::move(block);
}
@ -699,7 +775,7 @@ std::unique_ptr<TrackingInterface> GNSSBlockFactory::GetTrkBlock(
else
{
// Log fatal. This causes execution to stop.
LOG(ERROR) << implementation << ": Undefined implementation for block";
LOG(ERROR) << role<<"."<<implementation << ": Undefined implementation for block";
}
return std::move(block);
}
@ -735,7 +811,7 @@ std::unique_ptr<TelemetryDecoderInterface> GNSSBlockFactory::GetTlmBlock(
else
{
// Log fatal. This causes execution to stop.
LOG(ERROR) << implementation << ": Undefined implementation for block";
LOG(ERROR) << role<<"."<<implementation << ": Undefined implementation for block";
}
return std::move(block);
}

View File

@ -71,7 +71,11 @@ public:
std::unique_ptr<GNSSBlockInterface> GetOutputFilter(std::shared_ptr<ConfigurationInterface> configuration,
boost::shared_ptr<gr::msg_queue> queue);
std::unique_ptr<GNSSBlockInterface> GetChannel(std::shared_ptr<ConfigurationInterface> configuration,
std::unique_ptr<GNSSBlockInterface> GetChannel_GPS(std::shared_ptr<ConfigurationInterface> configuration,
std::string acq, std::string trk, std::string tlm, int channel,
boost::shared_ptr<gr::msg_queue> queue);
std::unique_ptr<GNSSBlockInterface> GetChannel_Galileo(std::shared_ptr<ConfigurationInterface> configuration,
std::string acq, std::string trk, std::string tlm, int channel,
boost::shared_ptr<gr::msg_queue> queue);

View File

@ -271,6 +271,13 @@ void GNSSFlowgraph::connect()
return;
}
//discriminate between systems
//TODO: add a specific string member to the channel template, and not re-use the implementation field!
while (channels_.at(i)->implementation()!= available_GNSS_signals_.front().get_satellite().get_system())
{
available_GNSS_signals_.push_back(available_GNSS_signals_.front());
available_GNSS_signals_.pop_front();
}
channels_.at(i)->set_signal(available_GNSS_signals_.front());
LOG(INFO) << "Channel " << i << " assigned to " << available_GNSS_signals_.front();
available_GNSS_signals_.pop_front();
@ -325,9 +332,6 @@ void GNSSFlowgraph::connect()
top_block_->dump();
}
void GNSSFlowgraph::wait()
{
if (!running_)
@ -340,10 +344,6 @@ void GNSSFlowgraph::wait()
running_ = false;
}
/*
* Applies an action to the flowgraph
*
@ -493,16 +493,15 @@ void GNSSFlowgraph::set_signals_list()
*/
/*
* Read GNSS-SDR default GNSS system and signal
* Read GNSS-SDR default GNSS system
*/
std::string default_system = configuration_->property("Channel.system", std::string("GPS"));
std::string default_signal = configuration_->property("Channel.signal", std::string("1C"));
/*
* Loop to create the list of GNSS Signals
* To add signals from other systems, add another loop 'for'
*/
if (default_system.compare(std::string("GPS")) == 0)
if (default_system.find(std::string("GPS")) != std::string::npos)
{
/*
* Loop to create GPS L1 C/A signals
@ -521,7 +520,7 @@ void GNSSFlowgraph::set_signals_list()
}
if (default_system.compare(std::string("SBAS")) == 0)
if (default_system.find(std::string("SBAS")) != std::string::npos)
{
/*
* Loop to create SBAS L1 C/A signals
@ -538,7 +537,7 @@ void GNSSFlowgraph::set_signals_list()
}
if (default_system.compare(std::string("Galileo")) == 0)
if (default_system.find(std::string("Galileo")) != std::string::npos)
{
/*
* Loop to create the list of Galileo E1 B signals
@ -559,6 +558,7 @@ void GNSSFlowgraph::set_signals_list()
/*
* Ordering the list of signals from configuration file
*/
std::string default_signal = configuration_->property("Channel.signal", std::string("1C"));
std::list<Gnss_Signal>::iterator gnss_it = available_GNSS_signals_.begin();
@ -591,14 +591,14 @@ void GNSSFlowgraph::set_signals_list()
}
// **** FOR DEBUGGING THE LIST OF GNSS SIGNALS ****
//
//std::cout<<"default_system="<<default_system<<std::endl;
//std::cout<<"default_signal="<<default_signal<<std::endl;
// std::list<Gnss_Signal>::iterator available_gnss_list_iter;
// for (available_gnss_list_iter = available_GNSS_signals_.begin(); available_gnss_list_iter
// != available_GNSS_signals_.end(); available_gnss_list_iter++)
// {
// std::cout << *available_gnss_list_iter << std::endl;
// }
std::cout<<"default_system="<<default_system<<std::endl;
std::cout<<"default_signal="<<default_signal<<std::endl;
std::list<Gnss_Signal>::iterator available_gnss_list_iter;
for (available_gnss_list_iter = available_GNSS_signals_.begin(); available_gnss_list_iter
!= available_GNSS_signals_.end(); available_gnss_list_iter++)
{
std::cout << *available_gnss_list_iter << std::endl;
}
}