2011-10-01 18:45:20 +00:00
/*!
* \ file gnss_flowgraph . cc
2018-04-20 11:20:10 +00:00
* \ brief Implementation of a GNSS receiver flow graph
2011-10-01 18:45:20 +00:00
* \ author Carlos Aviles , 2010. carlos . avilesr ( at ) googlemail . com
2012-03-02 17:17:51 +00:00
* Luis Esteve , 2012. luis ( at ) epsilon - formacion . com
2020-06-18 09:49:28 +00:00
* Carles Fernandez - Prades , 2014 - 2020. cfernandez ( at ) cttc . es
2018-07-03 11:25:43 +00:00
* Á lvaro Cebrián Juan , 2018. acebrianjuan ( at ) gmail . com
2018-10-28 10:07:53 +00:00
* Javier Arribas , 2018. javiarribas ( at ) gmail . com
2011-10-01 18:45:20 +00:00
*
2020-06-18 09:49:28 +00:00
*
2011-10-01 18:45:20 +00:00
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
2020-06-18 09:49:28 +00:00
* Copyright ( C ) 2010 - 2020 ( see AUTHORS file for a list of contributors )
2011-10-01 18:45:20 +00:00
*
* GNSS - SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS - SDR .
*
2020-02-08 00:20:02 +00:00
* SPDX - License - Identifier : GPL - 3.0 - or - later
2011-10-01 18:45:20 +00:00
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
# include "gnss_flowgraph.h"
2018-12-03 16:58:18 +00:00
# include "GPS_L1_CA.h"
# include "GPS_L2C.h"
# include "GPS_L5.h"
2018-12-10 13:24:42 +00:00
# include "Galileo_E1.h"
2018-12-03 16:58:18 +00:00
# include "Galileo_E5a.h"
2018-12-10 13:24:42 +00:00
# include "channel.h"
2019-03-20 14:13:17 +00:00
# include "channel_fsm.h"
2011-10-01 18:45:20 +00:00
# include "channel_interface.h"
2018-12-09 21:00:09 +00:00
# include "configuration_interface.h"
2011-10-01 18:45:20 +00:00
# include "gnss_block_factory.h"
2019-03-05 07:59:04 +00:00
# include "gnss_block_interface.h"
# include "gnss_satellite.h"
2020-06-18 09:49:28 +00:00
# include "gnss_sdr_make_unique.h"
2019-03-05 07:59:04 +00:00
# include "gnss_synchro_monitor.h"
# include <boost/lexical_cast.hpp> // for boost::lexical_cast
# include <boost/tokenizer.hpp> // for boost::tokenizer
# include <glog/logging.h> // for LOG
# include <gnuradio/basic_block.h> // for basic_block
# include <gnuradio/filter/firdes.h> // for gr::filter::firdes
# include <gnuradio/io_signature.h> // for io_signature
# include <gnuradio/top_block.h> // for top_block, make_top_block
# include <pmt/pmt_sugar.h> // for mp
# include <algorithm> // for transform, sort, unique
# include <cmath> // for floor
# include <cstddef> // for size_t
# include <exception> // for exception
# include <iostream> // for operator<<
# include <iterator> // for insert_iterator, inserter
2020-04-02 11:23:20 +00:00
# include <memory> // for std::shared_ptr
2019-03-05 07:59:04 +00:00
# include <set> // for set
2020-07-06 22:05:31 +00:00
# include <sstream> // for std::stringstream
2019-03-05 07:59:04 +00:00
# include <stdexcept> // for invalid_argument
2020-06-18 09:49:28 +00:00
# include <thread> // for std::thread
# include <utility> // for std::move
2018-12-10 13:24:42 +00:00
# ifdef GR_GREATER_38
# include <gnuradio/filter/fir_filter_blk.h>
# else
# include <gnuradio/filter/fir_filter_ccf.h>
# endif
2011-10-01 18:45:20 +00:00
2017-05-02 10:01:18 +00:00
2014-02-18 19:40:44 +00:00
# define GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS 8
2011-10-01 18:45:20 +00:00
2020-06-18 09:49:28 +00:00
GNSSFlowgraph : : GNSSFlowgraph ( std : : shared_ptr < ConfigurationInterface > configuration , std : : shared_ptr < Concurrent_Queue < pmt : : pmt_t > > queue ) // NOLINT(performance-unnecessary-value-param)
2012-04-14 18:04:27 +00:00
{
connected_ = false ;
running_ = false ;
2019-02-05 00:31:09 +00:00
configuration_ = std : : move ( configuration ) ;
2020-06-18 09:49:28 +00:00
queue_ = std : : move ( queue ) ;
2019-10-04 07:17:29 +00:00
multiband_ = GNSSFlowgraph : : is_multiband ( ) ;
2012-04-14 18:04:27 +00:00
init ( ) ;
2011-10-01 18:45:20 +00:00
}
2018-04-22 17:49:13 +00:00
GNSSFlowgraph : : ~ GNSSFlowgraph ( )
{
2020-06-25 00:50:07 +00:00
DLOG ( INFO ) < < " GNSSFlowgraph destructor called " ;
2018-04-22 17:49:13 +00:00
if ( connected_ )
{
GNSSFlowgraph : : disconnect ( ) ;
}
}
2018-04-20 10:50:32 +00:00
2012-04-14 18:04:27 +00:00
void GNSSFlowgraph : : start ( )
{
if ( running_ )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Already running " ;
2012-04-14 18:04:27 +00:00
return ;
}
try
2018-03-03 01:03:39 +00:00
{
2012-04-14 18:04:27 +00:00
top_block_ - > start ( ) ;
2018-03-03 01:03:39 +00:00
}
catch ( const std : : exception & e )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Unable to start flowgraph " ;
LOG ( ERROR ) < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
return ;
2018-03-03 01:03:39 +00:00
}
2012-04-14 18:04:27 +00:00
running_ = true ;
2011-10-01 18:45:20 +00:00
}
2015-02-27 17:21:25 +00:00
2012-04-14 18:04:27 +00:00
void GNSSFlowgraph : : stop ( )
{
2020-06-27 09:52:59 +00:00
for ( const auto & chan : channels_ )
2020-06-27 07:52:59 +00:00
{
chan - > stop_channel ( ) ; // stop the acquisition or tracking operation
}
2012-04-14 18:04:27 +00:00
top_block_ - > stop ( ) ;
running_ = false ;
2011-10-01 18:45:20 +00:00
}
2012-04-14 18:04:27 +00:00
void GNSSFlowgraph : : connect ( )
{
2018-04-20 11:20:10 +00:00
// Connects the blocks in the flow graph
2018-04-20 10:50:32 +00:00
// Signal Source > Signal conditioner >> Channels >> Observables >> PVT
2014-03-16 19:58:29 +00:00
LOG ( INFO ) < < " Connecting flowgraph " ;
2012-04-14 18:04:27 +00:00
if ( connected_ )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " flowgraph already connected " ;
2012-04-14 18:04:27 +00:00
return ;
}
2019-02-13 16:48:14 +00:00
# ifndef ENABLE_FPGA
2015-02-27 17:21:25 +00:00
for ( int i = 0 ; i < sources_count_ ; i + + )
{
2018-04-13 13:27:14 +00:00
if ( configuration_ - > property ( sig_source_ . at ( i ) - > role ( ) + " .enable_FPGA " , false ) = = false )
2018-03-03 01:03:39 +00:00
{
2018-04-13 13:27:14 +00:00
try
{
sig_source_ . at ( i ) - > connect ( top_block_ ) ;
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't connect signal source block " < < i < < " internally " ;
LOG ( ERROR ) < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return ;
}
2018-03-03 01:03:39 +00:00
}
2015-02-27 17:21:25 +00:00
}
2012-04-14 18:04:27 +00:00
// Signal Source > Signal conditioner >
2019-09-13 06:56:37 +00:00
for ( auto & sig : sig_conditioner_ )
2015-02-27 17:21:25 +00:00
{
2019-09-13 06:56:37 +00:00
if ( configuration_ - > property ( sig - > role ( ) + " .enable_FPGA " , false ) = = false )
2018-03-03 01:03:39 +00:00
{
2018-04-13 13:27:14 +00:00
try
{
2019-09-13 06:56:37 +00:00
sig - > connect ( top_block_ ) ;
2018-04-13 13:27:14 +00:00
}
catch ( const std : : exception & e )
{
2019-09-13 06:56:37 +00:00
LOG ( INFO ) < < " Can't connect signal conditioner block internally " ;
2018-04-13 13:27:14 +00:00
LOG ( ERROR ) < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return ;
}
2018-03-03 01:03:39 +00:00
}
2015-02-27 17:21:25 +00:00
}
2019-02-13 16:48:14 +00:00
# endif
2020-07-09 22:37:55 +00:00
for ( int i = 0 ; i < channels_count_ ; i + + )
2017-05-05 14:37:29 +00:00
{
2012-04-14 18:04:27 +00:00
try
2018-03-03 01:03:39 +00:00
{
2014-04-12 17:45:45 +00:00
channels_ . at ( i ) - > connect ( top_block_ ) ;
2018-03-03 01:03:39 +00:00
}
catch ( const std : : exception & e )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Can't connect channel " < < i < < " internally " ;
LOG ( ERROR ) < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
2018-03-03 01:03:39 +00:00
}
2017-05-05 14:37:29 +00:00
}
2012-04-14 18:04:27 +00:00
try
2018-03-03 01:03:39 +00:00
{
2014-04-12 17:45:45 +00:00
observables_ - > connect ( top_block_ ) ;
2018-03-03 01:03:39 +00:00
}
catch ( const std : : exception & e )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Can't connect observables block internally " ;
LOG ( ERROR ) < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
2018-03-03 01:03:39 +00:00
}
2012-04-14 18:04:27 +00:00
// Signal Source > Signal conditioner >> Channels >> Observables > PVT
try
2018-03-03 01:03:39 +00:00
{
2014-04-12 17:45:45 +00:00
pvt_ - > connect ( top_block_ ) ;
2018-03-03 01:03:39 +00:00
}
catch ( const std : : exception & e )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Can't connect PVT block internally " ;
LOG ( ERROR ) < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
2018-03-03 01:03:39 +00:00
}
2012-04-14 18:04:27 +00:00
DLOG ( INFO ) < < " blocks connected internally " ;
2019-06-17 16:13:06 +00:00
// Signal Source (i) > Signal conditioner (i) >
2019-02-13 16:48:14 +00:00
# ifndef ENABLE_FPGA
2019-03-02 10:22:42 +00:00
int RF_Channels = 0 ;
2019-06-17 21:42:16 +00:00
unsigned int signal_conditioner_ID = 0 ;
2015-02-27 17:21:25 +00:00
for ( int i = 0 ; i < sources_count_ ; i + + )
{
2019-02-27 16:27:31 +00:00
try
2018-03-03 01:03:39 +00:00
{
2019-03-18 18:50:02 +00:00
// TODO: Remove this array implementation and create generic multistream connector
// (if a signal source has more than 1 stream, then connect it to the multistream signal conditioner)
2019-02-27 16:27:31 +00:00
if ( sig_source_ . at ( i ) - > implementation ( ) = = " Raw_Array_Signal_Source " )
2015-02-27 17:21:25 +00:00
{
2019-03-18 18:50:02 +00:00
// Multichannel Array
2020-07-07 16:53:50 +00:00
std : : cout < < " ARRAY MODE \n " ;
2019-02-27 16:27:31 +00:00
for ( int j = 0 ; j < GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS ; j + + )
2015-02-27 17:21:25 +00:00
{
2020-07-07 16:53:50 +00:00
std : : cout < < " connecting ch " < < j < < ' \n ' ;
2019-02-27 16:27:31 +00:00
top_block_ - > connect ( sig_source_ . at ( i ) - > get_right_block ( ) , j , sig_conditioner_ . at ( i ) - > get_left_block ( ) , j ) ;
2015-02-27 17:21:25 +00:00
}
2019-02-27 16:27:31 +00:00
}
else
{
2019-03-18 18:50:02 +00:00
// TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface.
// Include GetRFChannels in the interface to avoid read config parameters here
// read the number of RF channels for each front-end
2019-02-27 16:27:31 +00:00
RF_Channels = configuration_ - > property ( sig_source_ . at ( i ) - > role ( ) + " .RF_channels " , 1 ) ;
for ( int j = 0 ; j < RF_Channels ; j + + )
2015-03-01 21:23:17 +00:00
{
2019-03-18 18:50:02 +00:00
// Connect the multichannel signal source to multiple signal conditioners
2019-02-27 16:27:31 +00:00
// GNURADIO max_streams=-1 means infinite ports!
2019-04-09 10:01:01 +00:00
DLOG ( INFO ) < < " sig_source_.at(i)->get_right_block()->output_signature()->max_streams()= " < < sig_source_ . at ( i ) - > get_right_block ( ) - > output_signature ( ) - > max_streams ( ) ;
DLOG ( INFO ) < < " sig_conditioner_.at(signal_conditioner_ID)->get_left_block()->input_signature()= " < < sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) - > input_signature ( ) - > max_streams ( ) ;
2015-04-24 17:11:45 +00:00
2019-06-17 16:13:06 +00:00
if ( sig_source_ . at ( i ) - > get_right_block ( ) - > output_signature ( ) - > max_streams ( ) > 1 or sig_source_ . at ( i ) - > get_right_block ( ) - > output_signature ( ) - > max_streams ( ) = = - 1 )
2015-03-04 19:54:15 +00:00
{
2019-06-17 16:13:06 +00:00
if ( sig_conditioner_ . size ( ) > signal_conditioner_ID )
{
LOG ( INFO ) < < " connecting sig_source_ " < < i < < " stream " < < j < < " to conditioner " < < j ;
top_block_ - > connect ( sig_source_ . at ( i ) - > get_right_block ( ) , j , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
}
2019-02-27 16:27:31 +00:00
}
else
{
if ( j = = 0 )
2015-03-04 19:54:15 +00:00
{
2019-02-27 16:27:31 +00:00
// RF_channel 0 backward compatibility with single channel sources
LOG ( INFO ) < < " connecting sig_source_ " < < i < < " stream " < < 0 < < " to conditioner " < < j ;
top_block_ - > connect ( sig_source_ . at ( i ) - > get_right_block ( ) , 0 , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
2015-03-04 19:54:15 +00:00
}
else
{
2019-02-27 16:27:31 +00:00
// Multiple channel sources using multiple output blocks of single channel (requires RF_channel selector in call)
LOG ( INFO ) < < " connecting sig_source_ " < < i < < " stream " < < j < < " to conditioner " < < j ;
top_block_ - > connect ( sig_source_ . at ( i ) - > get_right_block ( j ) , 0 , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
2015-03-04 19:54:15 +00:00
}
}
2019-02-27 16:27:31 +00:00
signal_conditioner_ID + + ;
2015-03-01 21:23:17 +00:00
}
}
2019-02-27 16:27:31 +00:00
}
catch ( const std : : exception & e )
{
LOG ( WARNING ) < < " Can't connect signal source " < < i < < " to signal conditioner " < < i ;
LOG ( ERROR ) < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return ;
2018-04-13 13:27:14 +00:00
}
}
DLOG ( INFO ) < < " Signal source connected to signal conditioner " ;
2019-02-13 16:48:14 +00:00
# endif
2018-04-13 13:27:14 +00:00
# if ENABLE_FPGA
2019-02-27 12:30:09 +00:00
if ( configuration_ - > property ( sig_source_ . at ( 0 ) - > role ( ) + " .enable_FPGA " , false ) = = false )
2018-04-13 13:27:14 +00:00
{
2019-03-18 18:50:02 +00:00
// connect the signal source to sample counter
// connect the sample counter to Observables
2018-04-13 13:27:14 +00:00
try
{
double fs = static_cast < double > ( configuration_ - > property ( " GNSS-SDR.internal_fs_sps " , 0 ) ) ;
if ( fs = = 0.0 )
{
LOG ( WARNING ) < < " Set GNSS-SDR.internal_fs_sps in configuration file " ;
2020-07-07 16:53:50 +00:00
std : : cout < < " Set GNSS-SDR.internal_fs_sps in configuration file \n " ;
2018-04-13 13:27:14 +00:00
throw ( std : : invalid_argument ( " Set GNSS-SDR.internal_fs_sps in configuration " ) ) ;
}
2020-07-09 22:37:55 +00:00
int observable_interval_ms = configuration_ - > property ( " GNSS-SDR.observable_interval_ms " , 20 ) ;
2020-06-19 10:39:28 +00:00
ch_out_sample_counter_ = gnss_sdr_make_sample_counter ( fs , observable_interval_ms , sig_conditioner_ . at ( 0 ) - > get_right_block ( ) - > output_signature ( ) - > sizeof_stream_item ( 0 ) ) ;
top_block_ - > connect ( sig_conditioner_ . at ( 0 ) - > get_right_block ( ) , 0 , ch_out_sample_counter_ , 0 ) ;
top_block_ - > connect ( ch_out_sample_counter_ , 0 , observables_ - > get_left_block ( ) , channels_count_ ) ; // extra port for the sample counter pulse
2018-03-03 01:03:39 +00:00
}
catch ( const std : : exception & e )
{
2018-04-13 13:27:14 +00:00
LOG ( WARNING ) < < " Can't connect sample counter " ;
2015-02-27 17:21:25 +00:00
LOG ( ERROR ) < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return ;
2018-03-03 01:03:39 +00:00
}
2015-02-27 17:21:25 +00:00
}
2018-04-13 13:27:14 +00:00
else
2012-04-14 18:04:27 +00:00
{
2019-03-18 18:50:02 +00:00
// create a hardware-defined gnss_synchro pulse for the observables block
2015-02-27 17:21:25 +00:00
try
2018-03-03 01:03:39 +00:00
{
2018-08-10 09:53:40 +00:00
double fs = static_cast < double > ( configuration_ - > property ( " GNSS-SDR.internal_fs_sps " , 0 ) ) ;
if ( fs = = 0.0 )
{
LOG ( WARNING ) < < " Set GNSS-SDR.internal_fs_sps in configuration file " ;
2020-07-07 16:53:50 +00:00
std : : cout < < " Set GNSS-SDR.internal_fs_sps in configuration file \n " ;
2018-08-10 09:53:40 +00:00
throw ( std : : invalid_argument ( " Set GNSS-SDR.internal_fs_sps in configuration " ) ) ;
}
2020-07-09 22:37:55 +00:00
int observable_interval_ms = configuration_ - > property ( " GNSS-SDR.observable_interval_ms " , 20 ) ;
2020-06-19 10:39:28 +00:00
ch_out_fpga_sample_counter_ = gnss_sdr_make_fpga_sample_counter ( fs , observable_interval_ms ) ;
top_block_ - > connect ( ch_out_fpga_sample_counter_ , 0 , observables_ - > get_left_block ( ) , channels_count_ ) ; // extra port for the sample counter pulse
2018-03-03 01:03:39 +00:00
}
catch ( const std : : exception & e )
{
2018-08-10 09:53:40 +00:00
LOG ( WARNING ) < < " Can't connect FPGA sample counter " ;
2014-03-16 19:58:29 +00:00
LOG ( ERROR ) < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
2018-03-03 01:03:39 +00:00
}
2018-04-13 13:27:14 +00:00
}
# else
2018-04-20 10:50:32 +00:00
// connect the signal source to sample counter
// connect the sample counter to Observables
2018-04-13 13:27:14 +00:00
try
{
double fs = static_cast < double > ( configuration_ - > property ( " GNSS-SDR.internal_fs_sps " , 0 ) ) ;
if ( fs = = 0.0 )
{
LOG ( WARNING ) < < " Set GNSS-SDR.internal_fs_sps in configuration file " ;
2020-07-07 16:53:50 +00:00
std : : cout < < " Set GNSS-SDR.internal_fs_sps in configuration file \n " ;
2018-04-13 13:27:14 +00:00
throw ( std : : invalid_argument ( " Set GNSS-SDR.internal_fs_sps in configuration " ) ) ;
}
2018-08-07 18:04:44 +00:00
2020-07-09 22:37:55 +00:00
int observable_interval_ms = configuration_ - > property ( " GNSS-SDR.observable_interval_ms " , 20 ) ;
2020-06-19 10:39:28 +00:00
ch_out_sample_counter_ = gnss_sdr_make_sample_counter ( fs , observable_interval_ms , sig_conditioner_ . at ( 0 ) - > get_right_block ( ) - > output_signature ( ) - > sizeof_stream_item ( 0 ) ) ;
top_block_ - > connect ( sig_conditioner_ . at ( 0 ) - > get_right_block ( ) , 0 , ch_out_sample_counter_ , 0 ) ;
top_block_ - > connect ( ch_out_sample_counter_ , 0 , observables_ - > get_left_block ( ) , channels_count_ ) ; // extra port for the sample counter pulse
2018-04-13 13:27:14 +00:00
}
catch ( const std : : exception & e )
{
LOG ( WARNING ) < < " Can't connect sample counter " ;
LOG ( ERROR ) < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return ;
}
# endif
2019-02-13 16:48:14 +00:00
2018-04-13 13:27:14 +00:00
// Signal conditioner (selected_signal_source) >> channels (i) (dependent of their associated SignalSource_ID)
2019-03-29 16:36:05 +00:00
std : : vector < bool > signal_conditioner_connected ;
for ( size_t n = 0 ; n < sig_conditioner_ . size ( ) ; n + + )
{
signal_conditioner_connected . push_back ( false ) ;
}
2020-07-09 22:37:55 +00:00
for ( int i = 0 ; i < channels_count_ ; i + + )
2018-04-13 13:27:14 +00:00
{
2019-02-13 16:48:14 +00:00
# ifndef ENABLE_FPGA
2019-03-02 10:22:42 +00:00
int selected_signal_conditioner_ID = 0 ;
bool use_acq_resampler = configuration_ - > property ( " GNSS-SDR.use_acquisition_resampler " , false ) ;
uint32_t fs = configuration_ - > property ( " GNSS-SDR.internal_fs_sps " , 0 ) ;
2019-02-27 12:30:09 +00:00
if ( configuration_ - > property ( sig_source_ . at ( 0 ) - > role ( ) + " .enable_FPGA " , false ) = = false )
2018-04-13 13:27:14 +00:00
{
2018-05-01 21:32:52 +00:00
try
{
selected_signal_conditioner_ID = configuration_ - > property ( " Channel " + std : : to_string ( i ) + " .RF_channel_ID " , 0 ) ;
}
catch ( const std : : exception & e )
{
LOG ( WARNING ) < < e . what ( ) ;
}
2018-04-13 13:27:14 +00:00
try
{
2018-12-03 16:58:18 +00:00
// Enable automatic resampler for the acquisition, if required
if ( use_acq_resampler = = true )
{
2019-03-18 18:50:02 +00:00
// create acquisition resamplers if required
2018-12-03 16:58:18 +00:00
double resampler_ratio = 1.0 ;
double acq_fs = fs ;
2019-03-18 18:50:02 +00:00
// find the signal associated to this channel
2018-12-03 16:58:18 +00:00
switch ( mapStringValues_ [ channels_ . at ( i ) - > implementation ( ) ] )
{
case evGPS_1C :
2019-08-31 09:37:29 +00:00
acq_fs = GPS_L1_CA_OPT_ACQ_FS_SPS ;
2018-12-03 16:58:18 +00:00
break ;
case evGPS_2S :
2019-08-31 09:37:29 +00:00
acq_fs = GPS_L2C_OPT_ACQ_FS_SPS ;
2018-12-03 16:58:18 +00:00
break ;
case evGPS_L5 :
2019-08-31 09:37:29 +00:00
acq_fs = GPS_L5_OPT_ACQ_FS_SPS ;
2018-12-03 16:58:18 +00:00
break ;
case evSBAS_1C :
2019-08-31 09:37:29 +00:00
acq_fs = GPS_L1_CA_OPT_ACQ_FS_SPS ;
2018-12-03 16:58:18 +00:00
break ;
case evGAL_1B :
2019-08-31 09:37:29 +00:00
acq_fs = GALILEO_E1_OPT_ACQ_FS_SPS ;
2018-12-03 16:58:18 +00:00
break ;
case evGAL_5X :
2019-08-31 09:37:29 +00:00
acq_fs = GALILEO_E5A_OPT_ACQ_FS_SPS ;
2018-12-03 16:58:18 +00:00
break ;
case evGLO_1G :
case evGLO_2G :
2018-12-18 21:55:36 +00:00
case evBDS_B1 :
2019-01-25 21:43:00 +00:00
case evBDS_B3 :
acq_fs = fs ;
break ;
2019-07-20 00:53:31 +00:00
default :
break ;
2018-12-03 16:58:18 +00:00
}
2018-12-05 15:50:32 +00:00
2018-12-03 16:58:18 +00:00
if ( acq_fs < fs )
{
2019-03-18 18:50:02 +00:00
// check if the resampler is already created for the channel system/signal and for the specific RF Channel
2018-12-03 16:58:18 +00:00
std : : string map_key = channels_ . at ( i ) - > implementation ( ) + std : : to_string ( selected_signal_conditioner_ID ) ;
2018-12-05 15:50:32 +00:00
resampler_ratio = static_cast < double > ( fs ) / acq_fs ;
int decimation = floor ( resampler_ratio ) ;
while ( fs % decimation > 0 )
{
decimation - - ;
} ;
2020-02-26 17:16:04 +00:00
double acq_fs_decimated = static_cast < double > ( fs ) / static_cast < double > ( decimation ) ;
2018-12-03 16:58:18 +00:00
2018-12-05 15:50:32 +00:00
if ( decimation > 1 )
{
2019-03-18 18:50:02 +00:00
// create a FIR low pass filter
2018-12-05 15:50:32 +00:00
std : : vector < float > taps ;
2019-04-09 10:01:01 +00:00
2019-04-21 11:30:59 +00:00
// float beta = 7.0;
// float halfband = 0.5;
// float fractional_bw = 0.4;
// float rate = 1.0 / static_cast<float>(decimation);
2019-04-09 10:01:01 +00:00
//
2019-04-21 11:30:59 +00:00
// float trans_width = rate * (halfband - fractional_bw);
// float mid_transition_band = rate * halfband - trans_width / 2.0;
2019-04-09 10:01:01 +00:00
//
2019-04-21 11:30:59 +00:00
// taps = gr::filter::firdes::low_pass(1.0,
// 1.0,
// mid_transition_band,
// trans_width,
// gr::filter::firdes::win_type::WIN_KAISER,
// beta);
2019-04-09 10:01:01 +00:00
2018-12-05 15:50:32 +00:00
taps = gr : : filter : : firdes : : low_pass ( 1.0 ,
fs ,
2020-02-26 17:16:04 +00:00
acq_fs_decimated / 2.1 ,
acq_fs_decimated / 2 ,
2018-12-05 15:50:32 +00:00
gr : : filter : : firdes : : win_type : : WIN_HAMMING ) ;
gr : : basic_block_sptr fir_filter_ccf_ = gr : : filter : : fir_filter_ccf : : make ( decimation , taps ) ;
std : : pair < std : : map < std : : string , gr : : basic_block_sptr > : : iterator , bool > ret ;
ret = acq_resamplers_ . insert ( std : : pair < std : : string , gr : : basic_block_sptr > ( map_key , fir_filter_ccf_ ) ) ;
if ( ret . second = = true )
{
top_block_ - > connect ( sig_conditioner_ . at ( selected_signal_conditioner_ID ) - > get_right_block ( ) , 0 ,
acq_resamplers_ . at ( map_key ) , 0 ) ;
LOG ( INFO ) < < " Created "
< < channels_ . at ( i ) - > implementation ( )
< < " acquisition resampler for RF channel " < < std : : to_string ( signal_conditioner_ID ) < < " with " < < taps . size ( ) < < " taps and decimation factor of " < < decimation ;
}
else
{
LOG ( INFO ) < < " Found existing "
< < channels_ . at ( i ) - > implementation ( )
< < " acquisition resampler for RF channel " < < std : : to_string ( signal_conditioner_ID ) < < " with " < < taps . size ( ) < < " taps and decimation factor of " < < decimation ;
}
2018-12-03 16:58:18 +00:00
2018-12-05 15:50:32 +00:00
top_block_ - > connect ( acq_resamplers_ . at ( map_key ) , 0 ,
channels_ . at ( i ) - > get_left_block_acq ( ) , 0 ) ;
std : : shared_ptr < Channel > channel_ptr ;
channel_ptr = std : : dynamic_pointer_cast < Channel > ( channels_ . at ( i ) ) ;
channel_ptr - > acquisition ( ) - > set_resampler_latency ( ( taps . size ( ) - 1 ) / 2 ) ;
2018-12-03 16:58:18 +00:00
}
else
{
2018-12-05 15:50:32 +00:00
LOG ( INFO ) < < " Disabled acquisition resampler because the input sampling frequency is too low " ;
2019-03-18 18:50:02 +00:00
// resampler not required!
2018-12-05 15:50:32 +00:00
top_block_ - > connect ( sig_conditioner_ . at ( selected_signal_conditioner_ID ) - > get_right_block ( ) , 0 ,
channels_ . at ( i ) - > get_left_block_acq ( ) , 0 ) ;
2018-12-03 16:58:18 +00:00
}
}
else
{
2018-12-05 15:50:32 +00:00
LOG ( INFO ) < < " Disabled acquisition resampler because the input sampling frequency is too low " ;
2018-12-03 16:58:18 +00:00
top_block_ - > connect ( sig_conditioner_ . at ( selected_signal_conditioner_ID ) - > get_right_block ( ) , 0 ,
channels_ . at ( i ) - > get_left_block_acq ( ) , 0 ) ;
}
}
else
{
top_block_ - > connect ( sig_conditioner_ . at ( selected_signal_conditioner_ID ) - > get_right_block ( ) , 0 ,
channels_ . at ( i ) - > get_left_block_acq ( ) , 0 ) ;
}
2019-03-18 15:28:49 +00:00
top_block_ - > connect ( sig_conditioner_ . at ( selected_signal_conditioner_ID ) - > get_right_block ( ) , 0 ,
channels_ . at ( i ) - > get_left_block_trk ( ) , 0 ) ;
2018-04-13 13:27:14 +00:00
}
catch ( const std : : exception & e )
{
LOG ( WARNING ) < < " Can't connect signal conditioner " < < selected_signal_conditioner_ID < < " to channel " < < i ;
LOG ( ERROR ) < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return ;
}
2019-07-28 10:01:11 +00:00
signal_conditioner_connected . at ( selected_signal_conditioner_ID ) = true ; // notify that this signal conditioner is connected
2018-04-13 13:27:14 +00:00
DLOG ( INFO ) < < " signal conditioner " < < selected_signal_conditioner_ID < < " connected to channel " < < i ;
}
2019-02-13 16:48:14 +00:00
# endif
2012-04-14 18:04:27 +00:00
// Signal Source > Signal conditioner >> Channels >> Observables
try
2018-03-03 01:03:39 +00:00
{
2014-04-12 17:45:45 +00:00
top_block_ - > connect ( channels_ . at ( i ) - > get_right_block ( ) , 0 ,
2018-03-03 01:03:39 +00:00
observables_ - > get_left_block ( ) , i ) ;
}
catch ( const std : : exception & e )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Can't connect channel " < < i < < " to observables " ;
LOG ( ERROR ) < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
2018-03-03 01:03:39 +00:00
}
2018-04-20 10:50:32 +00:00
}
2014-04-12 20:02:18 +00:00
2019-07-20 00:53:31 +00:00
// check for unconnected signal conditioners and connect null_sinks in order to provide configuration flexibility to multiband files or signal sources
2019-03-29 16:36:05 +00:00
if ( configuration_ - > property ( sig_source_ . at ( 0 ) - > role ( ) + " .enable_FPGA " , false ) = = false )
{
for ( size_t n = 0 ; n < sig_conditioner_ . size ( ) ; n + + )
{
if ( signal_conditioner_connected . at ( n ) = = false )
{
null_sinks_ . push_back ( gr : : blocks : : null_sink : : make ( sizeof ( gr_complex ) ) ) ;
top_block_ - > connect ( sig_conditioner_ . at ( n ) - > get_right_block ( ) , 0 ,
null_sinks_ . back ( ) , 0 ) ;
2020-07-07 16:53:50 +00:00
LOG ( INFO ) < < " Null sink connected to signal conditioner " < < n < < " due to lack of connection to any channel \n " ;
2019-03-29 16:36:05 +00:00
}
}
}
2019-04-21 11:30:59 +00:00
2018-04-20 10:50:32 +00:00
// Put channels fixed to a given satellite at the beginning of the vector, then the rest
std : : vector < unsigned int > vector_of_channels ;
2020-07-09 22:37:55 +00:00
for ( int i = 0 ; i < channels_count_ ; i + + )
2018-04-20 10:50:32 +00:00
{
2018-05-01 21:32:52 +00:00
unsigned int sat = 0 ;
try
{
sat = configuration_ - > property ( " Channel " + std : : to_string ( i ) + " .satellite " , 0 ) ;
}
catch ( const std : : exception & e )
{
LOG ( WARNING ) < < e . what ( ) ;
}
2018-04-20 10:50:32 +00:00
if ( sat = = 0 )
{
vector_of_channels . push_back ( i ) ;
}
else
{
auto it = vector_of_channels . begin ( ) ;
it = vector_of_channels . insert ( it , i ) ;
}
}
2014-04-12 20:02:18 +00:00
2018-04-20 10:50:32 +00:00
// Assign satellites to channels in the initialization
for ( unsigned int & i : vector_of_channels )
{
std : : string gnss_signal = channels_ . at ( i ) - > get_signal ( ) . get_signal_str ( ) ; // use channel's implicit signal
2018-05-01 21:32:52 +00:00
unsigned int sat = 0 ;
try
{
sat = configuration_ - > property ( " Channel " + std : : to_string ( i ) + " .satellite " , 0 ) ;
}
catch ( const std : : exception & e )
{
LOG ( WARNING ) < < e . what ( ) ;
}
2018-07-12 18:01:18 +00:00
if ( sat = = 0 )
{
2019-07-11 16:39:28 +00:00
bool assistance_available ;
float estimated_doppler ;
double RX_time ;
bool is_primary_freq ;
channels_ . at ( i ) - > set_signal ( search_next_signal ( gnss_signal , false , is_primary_freq , assistance_available , estimated_doppler , RX_time ) ) ;
2018-07-12 18:01:18 +00:00
}
else
2012-04-14 18:04:27 +00:00
{
2018-04-20 10:50:32 +00:00
std : : string gnss_system ;
2018-06-14 21:10:43 +00:00
Gnss_Signal signal_value ;
switch ( mapStringValues_ [ gnss_signal ] )
{
case evGPS_1C :
gnss_system = " GPS " ;
signal_value = Gnss_Signal ( Gnss_Satellite ( gnss_system , sat ) , gnss_signal ) ;
available_GPS_1C_signals_ . remove ( signal_value ) ;
break ;
case evGPS_2S :
gnss_system = " GPS " ;
signal_value = Gnss_Signal ( Gnss_Satellite ( gnss_system , sat ) , gnss_signal ) ;
available_GPS_2S_signals_ . remove ( signal_value ) ;
break ;
case evGPS_L5 :
gnss_system = " GPS " ;
signal_value = Gnss_Signal ( Gnss_Satellite ( gnss_system , sat ) , gnss_signal ) ;
available_GPS_L5_signals_ . remove ( signal_value ) ;
break ;
case evGAL_1B :
gnss_system = " Galileo " ;
signal_value = Gnss_Signal ( Gnss_Satellite ( gnss_system , sat ) , gnss_signal ) ;
available_GAL_1B_signals_ . remove ( signal_value ) ;
break ;
case evGAL_5X :
gnss_system = " Galileo " ;
signal_value = Gnss_Signal ( Gnss_Satellite ( gnss_system , sat ) , gnss_signal ) ;
available_GAL_5X_signals_ . remove ( signal_value ) ;
break ;
case evGLO_1G :
gnss_system = " Glonass " ;
signal_value = Gnss_Signal ( Gnss_Satellite ( gnss_system , sat ) , gnss_signal ) ;
available_GLO_1G_signals_ . remove ( signal_value ) ;
break ;
case evGLO_2G :
gnss_system = " Glonass " ;
signal_value = Gnss_Signal ( Gnss_Satellite ( gnss_system , sat ) , gnss_signal ) ;
available_GLO_2G_signals_ . remove ( signal_value ) ;
break ;
2018-10-22 19:16:38 +00:00
case evBDS_B1 :
gnss_system = " Beidou " ;
signal_value = Gnss_Signal ( Gnss_Satellite ( gnss_system , sat ) , gnss_signal ) ;
available_BDS_B1_signals_ . remove ( signal_value ) ;
break ;
2019-01-25 21:43:00 +00:00
case evBDS_B3 :
gnss_system = " Beidou " ;
signal_value = Gnss_Signal ( Gnss_Satellite ( gnss_system , sat ) , gnss_signal ) ;
available_BDS_B3_signals_ . remove ( signal_value ) ;
break ;
2018-06-14 21:10:43 +00:00
default :
LOG ( ERROR ) < < " This should not happen :-( " ;
gnss_system = " GPS " ;
signal_value = Gnss_Signal ( Gnss_Satellite ( gnss_system , sat ) , gnss_signal ) ;
available_GPS_1C_signals_ . remove ( signal_value ) ;
break ;
}
2018-04-20 10:50:32 +00:00
channels_ . at ( i ) - > set_signal ( signal_value ) ;
2012-04-14 18:04:27 +00:00
}
2017-05-05 14:37:29 +00:00
}
2015-02-27 17:21:25 +00:00
2018-04-20 10:50:32 +00:00
// Connect the observables output of each channel to the PVT block
2012-04-14 18:04:27 +00:00
try
2018-03-03 01:03:39 +00:00
{
2020-07-09 22:37:55 +00:00
for ( int i = 0 ; i < channels_count_ ; i + + )
2012-04-14 18:04:27 +00:00
{
2014-04-12 17:45:45 +00:00
top_block_ - > connect ( observables_ - > get_right_block ( ) , i , pvt_ - > get_left_block ( ) , i ) ;
2016-05-02 21:46:30 +00:00
top_block_ - > msg_connect ( channels_ . at ( i ) - > get_right_block ( ) , pmt : : mp ( " telemetry " ) , pvt_ - > get_left_block ( ) , pmt : : mp ( " telemetry " ) ) ;
2012-04-14 18:04:27 +00:00
}
2019-07-11 16:39:28 +00:00
top_block_ - > msg_connect ( observables_ - > get_right_block ( ) , pmt : : mp ( " status " ) , channels_status_ , pmt : : mp ( " status " ) ) ;
2019-04-23 15:31:26 +00:00
top_block_ - > msg_connect ( pvt_ - > get_left_block ( ) , pmt : : mp ( " pvt_to_observables " ) , observables_ - > get_right_block ( ) , pmt : : mp ( " pvt_to_observables " ) ) ;
2019-07-11 16:39:28 +00:00
top_block_ - > msg_connect ( pvt_ - > get_left_block ( ) , pmt : : mp ( " status " ) , channels_status_ , pmt : : mp ( " status " ) ) ;
2018-03-03 01:03:39 +00:00
}
catch ( const std : : exception & e )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Can't connect observables to PVT " ;
LOG ( ERROR ) < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
2018-03-03 01:03:39 +00:00
}
2012-04-14 18:04:27 +00:00
2018-07-03 11:25:43 +00:00
// GNSS SYNCHRO MONITOR
if ( enable_monitor_ )
{
try
{
2020-07-09 22:37:55 +00:00
for ( int i = 0 ; i < channels_count_ ; i + + )
2018-07-03 11:25:43 +00:00
{
top_block_ - > connect ( observables_ - > get_right_block ( ) , i , GnssSynchroMonitor_ , i ) ;
}
}
catch ( const std : : exception & e )
{
LOG ( WARNING ) < < " Can't connect observables to Monitor block " ;
LOG ( ERROR ) < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return ;
}
}
2019-02-13 16:48:14 +00:00
# ifndef ENABLE_FPGA
2018-04-20 10:50:32 +00:00
// Activate acquisition in enabled channels
2020-07-09 22:37:55 +00:00
for ( int i = 0 ; i < channels_count_ ; i + + )
2018-04-20 10:50:32 +00:00
{
LOG ( INFO ) < < " Channel " < < i < < " assigned to " < < channels_ . at ( i ) - > get_signal ( ) ;
if ( channels_state_ [ i ] = = 1 )
{
2019-02-27 16:27:31 +00:00
channels_ . at ( i ) - > start_acquisition ( ) ;
2018-04-20 10:50:32 +00:00
LOG ( INFO ) < < " Channel " < < i < < " connected to observables and ready for acquisition " ;
}
else
{
LOG ( INFO ) < < " Channel " < < i < < " connected to observables in standby mode " ;
}
}
2019-02-13 16:48:14 +00:00
# endif
2012-04-14 18:04:27 +00:00
connected_ = true ;
2014-03-16 19:58:29 +00:00
LOG ( INFO ) < < " Flowgraph connected " ;
2012-04-14 18:04:27 +00:00
top_block_ - > dump ( ) ;
2011-10-01 18:45:20 +00:00
}
2012-04-14 18:04:27 +00:00
2018-04-22 17:49:13 +00:00
void GNSSFlowgraph : : disconnect ( )
{
LOG ( INFO ) < < " Disconnecting flowgraph " ;
if ( ! connected_ )
{
LOG ( INFO ) < < " flowgraph was not connected " ;
return ;
}
2018-05-01 21:32:52 +00:00
connected_ = false ;
2018-04-22 17:49:13 +00:00
// Signal Source (i) > Signal conditioner (i) >
int RF_Channels = 0 ;
int signal_conditioner_ID = 0 ;
2019-02-13 16:48:14 +00:00
# ifdef ENABLE_FPGA
2019-02-27 14:51:01 +00:00
if ( configuration_ - > property ( sig_source_ . at ( 0 ) - > role ( ) + " .enable_FPGA " , false ) = = false )
2019-02-27 16:27:31 +00:00
{
for ( int i = 0 ; i < sources_count_ ; i + + )
{
try
{
// TODO: Remove this array implementation and create generic multistream connector
// (if a signal source has more than 1 stream, then connect it to the multistream signal conditioner)
if ( sig_source_ . at ( i ) - > implementation ( ) = = " Raw_Array_Signal_Source " )
{
2019-03-18 18:50:02 +00:00
// Multichannel Array
2019-02-27 16:27:31 +00:00
for ( int j = 0 ; j < GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS ; j + + )
{
top_block_ - > disconnect ( sig_source_ . at ( i ) - > get_right_block ( ) , j , sig_conditioner_ . at ( i ) - > get_left_block ( ) , j ) ;
}
}
else
{
// TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface.
// Include GetRFChannels in the interface to avoid read config parameters here
// read the number of RF channels for each front-end
RF_Channels = configuration_ - > property ( sig_source_ . at ( i ) - > role ( ) + " .RF_channels " , 1 ) ;
for ( int j = 0 ; j < RF_Channels ; j + + )
{
if ( sig_source_ . at ( i ) - > get_right_block ( ) - > output_signature ( ) - > max_streams ( ) > 1 )
{
top_block_ - > disconnect ( sig_source_ . at ( i ) - > get_right_block ( ) , j , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
}
else
{
if ( j = = 0 )
{
// RF_channel 0 backward compatibility with single channel sources
top_block_ - > disconnect ( sig_source_ . at ( i ) - > get_right_block ( ) , 0 , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
}
else
{
// Multiple channel sources using multiple output blocks of single channel (requires RF_channel selector in call)
top_block_ - > disconnect ( sig_source_ . at ( i ) - > get_right_block ( j ) , 0 , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
}
}
signal_conditioner_ID + + ;
}
}
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect signal source " < < i < < " to signal conditioner " < < i < < " : " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return ;
}
}
}
2019-02-13 16:48:14 +00:00
# else
2018-04-22 17:49:13 +00:00
for ( int i = 0 ; i < sources_count_ ; i + + )
{
try
{
// TODO: Remove this array implementation and create generic multistream connector
// (if a signal source has more than 1 stream, then connect it to the multistream signal conditioner)
2018-12-02 21:53:05 +00:00
if ( sig_source_ . at ( i ) - > implementation ( ) = = " Raw_Array_Signal_Source " )
2018-04-22 17:49:13 +00:00
{
2019-07-28 10:01:11 +00:00
// Multichannel Array
2018-04-22 17:49:13 +00:00
for ( int j = 0 ; j < GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS ; j + + )
{
top_block_ - > disconnect ( sig_source_ . at ( i ) - > get_right_block ( ) , j , sig_conditioner_ . at ( i ) - > get_left_block ( ) , j ) ;
}
}
else
{
// TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface.
// Include GetRFChannels in the interface to avoid read config parameters here
// read the number of RF channels for each front-end
RF_Channels = configuration_ - > property ( sig_source_ . at ( i ) - > role ( ) + " .RF_channels " , 1 ) ;
for ( int j = 0 ; j < RF_Channels ; j + + )
{
2019-06-17 16:13:06 +00:00
if ( sig_source_ . at ( i ) - > get_right_block ( ) - > output_signature ( ) - > max_streams ( ) > 1 or sig_source_ . at ( i ) - > get_right_block ( ) - > output_signature ( ) - > max_streams ( ) = = - 1 )
2018-04-22 17:49:13 +00:00
{
top_block_ - > disconnect ( sig_source_ . at ( i ) - > get_right_block ( ) , j , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
}
else
{
if ( j = = 0 )
{
// RF_channel 0 backward compatibility with single channel sources
top_block_ - > disconnect ( sig_source_ . at ( i ) - > get_right_block ( ) , 0 , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
}
else
{
// Multiple channel sources using multiple output blocks of single channel (requires RF_channel selector in call)
top_block_ - > disconnect ( sig_source_ . at ( i ) - > get_right_block ( j ) , 0 , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
}
}
signal_conditioner_ID + + ;
}
}
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect signal source " < < i < < " to signal conditioner " < < i < < " : " < < e . what ( ) ;
2018-05-01 21:32:52 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
2018-04-22 17:49:13 +00:00
}
}
2019-02-13 16:48:14 +00:00
# endif
2018-04-22 17:49:13 +00:00
2019-02-13 16:48:14 +00:00
# ifdef ENABLE_FPGA
2019-02-27 14:51:01 +00:00
if ( configuration_ - > property ( sig_source_ . at ( 0 ) - > role ( ) + " .enable_FPGA " , false ) = = false )
2018-05-01 21:32:52 +00:00
{
// disconnect the signal source to sample counter
// disconnect the sample counter to Observables
try
{
2020-06-19 10:39:28 +00:00
top_block_ - > disconnect ( sig_conditioner_ . at ( 0 ) - > get_right_block ( ) , 0 , ch_out_sample_counter_ , 0 ) ;
top_block_ - > disconnect ( ch_out_sample_counter_ , 0 , observables_ - > get_left_block ( ) , channels_count_ ) ; // extra port for the sample counter pulse
2018-05-01 21:32:52 +00:00
}
catch ( const std : : exception & e )
{
LOG ( WARNING ) < < " Can't disconnect sample counter " ;
LOG ( ERROR ) < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return ;
}
}
else
{
try
{
2020-06-19 10:39:28 +00:00
top_block_ - > disconnect ( ch_out_fpga_sample_counter_ , 0 , observables_ - > get_left_block ( ) , channels_count_ ) ;
2018-05-01 21:32:52 +00:00
}
catch ( const std : : exception & e )
{
2018-08-10 09:53:40 +00:00
LOG ( WARNING ) < < " Can't connect FPGA sample counter " ;
2018-05-01 21:32:52 +00:00
LOG ( ERROR ) < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return ;
}
}
# else
// disconnect the signal source to sample counter
// disconnect the sample counter to Observables
2018-04-22 17:49:13 +00:00
try
{
2020-06-19 10:39:28 +00:00
top_block_ - > disconnect ( sig_conditioner_ . at ( 0 ) - > get_right_block ( ) , 0 , ch_out_sample_counter_ , 0 ) ;
top_block_ - > disconnect ( ch_out_sample_counter_ , 0 , observables_ - > get_left_block ( ) , channels_count_ ) ; // extra port for the sample counter pulse
2018-04-22 17:49:13 +00:00
}
catch ( const std : : exception & e )
{
2018-05-01 21:32:52 +00:00
LOG ( WARNING ) < < " Can't connect sample counter " ;
LOG ( ERROR ) < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return ;
2018-04-22 17:49:13 +00:00
}
2018-05-01 21:32:52 +00:00
# endif
2018-04-22 17:49:13 +00:00
// Signal conditioner (selected_signal_source) >> channels (i) (dependent of their associated SignalSource_ID)
2020-07-09 22:37:55 +00:00
for ( int i = 0 ; i < channels_count_ ; i + + )
2018-04-22 17:49:13 +00:00
{
2019-03-02 10:48:25 +00:00
# ifndef ENABLE_FPGA
int selected_signal_conditioner_ID ;
2018-05-01 21:32:52 +00:00
try
{
selected_signal_conditioner_ID = configuration_ - > property ( " Channel " + std : : to_string ( i ) + " .RF_channel_ID " , 0 ) ;
}
catch ( const std : : exception & e )
{
LOG ( WARNING ) < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return ;
}
2018-04-22 17:49:13 +00:00
try
{
top_block_ - > disconnect ( sig_conditioner_ . at ( selected_signal_conditioner_ID ) - > get_right_block ( ) , 0 ,
2018-12-03 16:58:18 +00:00
channels_ . at ( i ) - > get_left_block_trk ( ) , 0 ) ;
2018-04-22 17:49:13 +00:00
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect signal conditioner " < < selected_signal_conditioner_ID < < " to channel " < < i < < " : " < < e . what ( ) ;
2018-05-01 21:32:52 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
2018-04-22 17:49:13 +00:00
}
2019-02-13 16:48:14 +00:00
# endif
2018-04-22 17:49:13 +00:00
// Signal Source > Signal conditioner >> Channels >> Observables
try
{
top_block_ - > disconnect ( channels_ . at ( i ) - > get_right_block ( ) , 0 ,
observables_ - > get_left_block ( ) , i ) ;
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect channel " < < i < < " to observables: " < < e . what ( ) ;
2018-05-01 21:32:52 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
2018-04-22 17:49:13 +00:00
}
}
try
{
2020-07-09 22:37:55 +00:00
for ( int i = 0 ; i < channels_count_ ; i + + )
2018-04-22 17:49:13 +00:00
{
top_block_ - > disconnect ( observables_ - > get_right_block ( ) , i , pvt_ - > get_left_block ( ) , i ) ;
2019-02-14 15:46:16 +00:00
if ( enable_monitor_ )
{
top_block_ - > disconnect ( observables_ - > get_right_block ( ) , i , GnssSynchroMonitor_ , i ) ;
}
2018-04-22 17:49:13 +00:00
top_block_ - > msg_disconnect ( channels_ . at ( i ) - > get_right_block ( ) , pmt : : mp ( " telemetry " ) , pvt_ - > get_left_block ( ) , pmt : : mp ( " telemetry " ) ) ;
}
2019-04-23 15:31:26 +00:00
top_block_ - > msg_disconnect ( pvt_ - > get_left_block ( ) , pmt : : mp ( " pvt_to_observables " ) , observables_ - > get_right_block ( ) , pmt : : mp ( " pvt_to_observables " ) ) ;
2018-04-22 17:49:13 +00:00
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect observables to PVT: " < < e . what ( ) ;
2018-05-01 21:32:52 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
2018-04-22 17:49:13 +00:00
}
for ( int i = 0 ; i < sources_count_ ; i + + )
{
try
{
sig_source_ . at ( i ) - > disconnect ( top_block_ ) ;
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect signal source block " < < i < < " internally: " < < e . what ( ) ;
2018-05-01 21:32:52 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
2018-04-22 17:49:13 +00:00
}
}
// Signal Source > Signal conditioner >
2019-09-13 06:56:37 +00:00
for ( auto & sig : sig_conditioner_ )
2018-04-22 17:49:13 +00:00
{
try
{
2019-09-13 06:56:37 +00:00
sig - > disconnect ( top_block_ ) ;
2018-04-22 17:49:13 +00:00
}
catch ( const std : : exception & e )
{
2019-09-13 06:56:37 +00:00
LOG ( INFO ) < < " Can't disconnect signal conditioner block internally: " < < e . what ( ) ;
2018-05-01 21:32:52 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
2018-04-22 17:49:13 +00:00
}
}
2020-07-09 22:37:55 +00:00
for ( int i = 0 ; i < channels_count_ ; i + + )
2018-04-22 17:49:13 +00:00
{
try
{
channels_ . at ( i ) - > disconnect ( top_block_ ) ;
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect channel " < < i < < " internally: " < < e . what ( ) ;
2018-05-01 21:32:52 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
2018-04-22 17:49:13 +00:00
}
}
try
{
observables_ - > disconnect ( top_block_ ) ;
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect observables block internally: " < < e . what ( ) ;
2018-05-01 21:32:52 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
2018-04-22 17:49:13 +00:00
}
// Signal Source > Signal conditioner >> Channels >> Observables > PVT
try
{
pvt_ - > disconnect ( top_block_ ) ;
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect PVT block internally: " < < e . what ( ) ;
2018-05-01 21:32:52 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
2018-04-22 17:49:13 +00:00
}
DLOG ( INFO ) < < " blocks disconnected internally " ;
LOG ( INFO ) < < " Flowgraph disconnected " ;
}
2012-04-14 18:04:27 +00:00
void GNSSFlowgraph : : wait ( )
{
if ( ! running_ )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Can't apply wait. Flowgraph is not running " ;
2012-04-14 18:04:27 +00:00
return ;
}
top_block_ - > wait ( ) ;
DLOG ( INFO ) < < " Flowgraph finished calculations " ;
running_ = false ;
2011-10-01 18:45:20 +00:00
}
2012-04-14 18:04:27 +00:00
2018-12-03 18:01:47 +00:00
bool GNSSFlowgraph : : send_telemetry_msg ( const pmt : : pmt_t & msg )
2016-04-13 14:19:15 +00:00
{
2018-10-05 11:54:35 +00:00
// Push ephemeris to PVT telemetry msg in port using a channel out port
// it uses the first channel as a message producer (it is already connected to PVT)
2016-04-13 14:19:15 +00:00
channels_ . at ( 0 ) - > get_right_block ( ) - > message_port_pub ( pmt : : mp ( " telemetry " ) , msg ) ;
return true ;
}
2019-07-20 00:53:31 +00:00
2019-07-20 09:39:08 +00:00
void GNSSFlowgraph : : push_back_signal ( const Gnss_Signal & gs )
2019-07-16 15:41:12 +00:00
{
switch ( mapStringValues_ [ gs . get_signal_str ( ) ] )
{
case evGPS_1C :
available_GPS_1C_signals_ . remove ( gs ) ;
available_GPS_1C_signals_ . push_back ( gs ) ;
break ;
case evGPS_2S :
available_GPS_2S_signals_ . remove ( gs ) ;
available_GPS_2S_signals_ . push_back ( gs ) ;
break ;
case evGPS_L5 :
available_GPS_L5_signals_ . remove ( gs ) ;
available_GPS_L5_signals_ . push_back ( gs ) ;
break ;
case evGAL_1B :
available_GAL_1B_signals_ . remove ( gs ) ;
available_GAL_1B_signals_ . push_back ( gs ) ;
break ;
case evGAL_5X :
available_GAL_5X_signals_ . remove ( gs ) ;
available_GAL_5X_signals_ . push_back ( gs ) ;
break ;
case evGLO_1G :
available_GLO_1G_signals_ . remove ( gs ) ;
available_GLO_1G_signals_ . push_back ( gs ) ;
break ;
case evGLO_2G :
available_GLO_2G_signals_ . remove ( gs ) ;
available_GLO_2G_signals_ . push_back ( gs ) ;
break ;
case evBDS_B1 :
available_BDS_B1_signals_ . remove ( gs ) ;
available_BDS_B1_signals_ . push_back ( gs ) ;
break ;
case evBDS_B3 :
available_BDS_B3_signals_ . remove ( gs ) ;
available_BDS_B3_signals_ . push_back ( gs ) ;
break ;
default :
LOG ( ERROR ) < < " This should not happen :-( " ;
break ;
}
}
2019-07-20 00:53:31 +00:00
2019-07-20 09:39:08 +00:00
void GNSSFlowgraph : : remove_signal ( const Gnss_Signal & gs )
2019-07-16 15:41:12 +00:00
{
switch ( mapStringValues_ [ gs . get_signal_str ( ) ] )
{
case evGPS_1C :
available_GPS_1C_signals_ . remove ( gs ) ;
break ;
2017-05-10 20:16:18 +00:00
2019-07-16 15:41:12 +00:00
case evGPS_2S :
available_GPS_2S_signals_ . remove ( gs ) ;
break ;
case evGPS_L5 :
available_GPS_L5_signals_ . remove ( gs ) ;
break ;
case evGAL_1B :
available_GAL_1B_signals_ . remove ( gs ) ;
break ;
case evGAL_5X :
available_GAL_5X_signals_ . remove ( gs ) ;
break ;
case evGLO_1G :
available_GLO_1G_signals_ . remove ( gs ) ;
break ;
case evGLO_2G :
available_GLO_2G_signals_ . remove ( gs ) ;
break ;
case evBDS_B1 :
available_BDS_B1_signals_ . remove ( gs ) ;
break ;
case evBDS_B3 :
available_BDS_B3_signals_ . remove ( gs ) ;
break ;
default :
LOG ( ERROR ) < < " This should not happen :-( " ;
break ;
}
}
2019-07-28 10:01:11 +00:00
// project Doppler from primary frequency to secondary frequency
2019-08-12 23:06:47 +00:00
double GNSSFlowgraph : : project_doppler ( const std : : string & searched_signal , double primary_freq_doppler_hz )
2019-07-23 15:56:02 +00:00
{
switch ( mapStringValues_ [ searched_signal ] )
{
case evGPS_L5 :
case evGAL_5X :
return ( primary_freq_doppler_hz / FREQ1 ) * FREQ5 ;
break ;
case evGPS_2S :
return ( primary_freq_doppler_hz / FREQ1 ) * FREQ2 ;
break ;
default :
return primary_freq_doppler_hz ;
}
}
2019-07-20 00:53:31 +00:00
2019-07-28 10:01:11 +00:00
2019-07-19 16:49:42 +00:00
void GNSSFlowgraph : : acquisition_manager ( unsigned int who )
{
unsigned int current_channel ;
2020-07-09 22:37:55 +00:00
for ( int i = 0 ; i < channels_count_ ; i + + )
2019-07-19 16:49:42 +00:00
{
current_channel = ( i + who + 1 ) % channels_count_ ;
unsigned int sat_ = 0 ;
try
{
sat_ = configuration_ - > property ( " Channel " + std : : to_string ( current_channel ) + " .satellite " , 0 ) ;
}
catch ( const std : : exception & e )
{
LOG ( WARNING ) < < e . what ( ) ;
}
if ( ( acq_channels_count_ < max_acq_channels_ ) & & ( channels_state_ [ current_channel ] = = 0 ) )
{
bool is_primary_freq = true ;
bool assistance_available = false ;
bool start_acquisition = false ;
Gnss_Signal gnss_signal ;
2019-07-23 15:56:02 +00:00
float estimated_doppler ;
double RX_time ;
2019-07-19 16:49:42 +00:00
if ( sat_ = = 0 )
{
gnss_signal = search_next_signal ( channels_ [ current_channel ] - > get_signal ( ) . get_signal_str ( ) ,
true ,
is_primary_freq ,
assistance_available ,
estimated_doppler ,
RX_time ) ;
channels_ [ current_channel ] - > set_signal ( gnss_signal ) ;
2019-10-04 07:17:29 +00:00
start_acquisition = is_primary_freq or assistance_available or ! configuration_ - > property ( " GNSS-SDR.assist_dual_frequency_acq " , multiband_ ) ;
2019-07-19 16:49:42 +00:00
}
else
{
2019-08-31 09:37:29 +00:00
channels_ [ current_channel ] - > set_signal ( channels_ [ current_channel ] - > get_signal ( ) ) ;
2019-07-19 16:49:42 +00:00
start_acquisition = true ;
}
if ( start_acquisition = = true )
{
channels_state_ [ current_channel ] = 1 ;
acq_channels_count_ + + ;
DLOG ( INFO ) < < " Channel " < < current_channel
< < " Starting acquisition " < < channels_ [ current_channel ] - > get_signal ( ) . get_satellite ( )
< < " , Signal " < < channels_ [ current_channel ] - > get_signal ( ) . get_signal_str ( ) ;
2019-10-04 07:17:29 +00:00
if ( assistance_available = = true and configuration_ - > property ( " GNSS-SDR.assist_dual_frequency_acq " , multiband_ ) )
2019-07-23 15:56:02 +00:00
{
channels_ [ current_channel ] - > assist_acquisition_doppler ( project_doppler ( channels_ [ current_channel ] - > get_signal ( ) . get_signal_str ( ) , estimated_doppler ) ) ;
}
else
{
2019-07-28 10:01:11 +00:00
// set Doppler center to 0 Hz
2019-07-23 15:56:02 +00:00
channels_ [ current_channel ] - > assist_acquisition_doppler ( 0 ) ;
}
2019-07-19 16:49:42 +00:00
# ifndef ENABLE_FPGA
channels_ [ current_channel ] - > start_acquisition ( ) ;
# else
// create a task for the FPGA such that it doesn't stop the flow
std : : thread tmp_thread ( & ChannelInterface : : start_acquisition , channels_ [ current_channel ] ) ;
tmp_thread . detach ( ) ;
# endif
}
else
{
push_back_signal ( gnss_signal ) ;
DLOG ( INFO ) < < " Channel " < < current_channel
< < " secondary frequency acquisition assistance not available in "
< < channels_ [ current_channel ] - > get_signal ( ) . get_satellite ( )
< < " , Signal " < < channels_ [ current_channel ] - > get_signal ( ) . get_signal_str ( ) ;
}
}
DLOG ( INFO ) < < " Channel " < < current_channel < < " in state " < < channels_state_ [ current_channel ] ;
}
}
2019-07-20 00:53:31 +00:00
2011-12-28 21:36:45 +00:00
/*
2018-04-20 11:20:10 +00:00
* Applies an action to the flow graph
2011-12-28 21:36:45 +00:00
*
2018-10-28 10:07:53 +00:00
* \ param [ in ] who Who generated the action :
* - > 0 - 199 are the channels IDs
* - > 200 is the control_thread dispatched by the control_thread apply_action
* - > 300 is the telecommand system ( TC ) for receiver control
* - > 400 - 599 is the TC channel control for channels 0 - 199
* \ param [ in ] what What is the action :
* - - - actions from channels - - -
* - > 0 acquisition failed
2019-07-20 00:53:31 +00:00
* - > 1 acquisition successful
2018-10-28 10:07:53 +00:00
* - > 2 tracking lost
* - - - actions from TC receiver control - - -
* - > 10 TC request standby mode
* - > 11 TC request coldstart
* - > 12 TC request hotstart
* - > 13 TC request warmstart
* - - - actions from TC channel control - - -
* - > 20 stop channel
* - > 21 start channel
2011-12-28 21:36:45 +00:00
*/
2012-04-14 18:04:27 +00:00
void GNSSFlowgraph : : apply_action ( unsigned int who , unsigned int what )
{
2019-08-18 20:16:13 +00:00
// todo: the acquisition events are initiated from the acquisition success or failure queued msg. If the acquisition is disabled for non-assisted secondary freq channels, the engine stops..
2020-06-19 10:39:28 +00:00
std : : lock_guard < std : : mutex > lock ( signal_list_mutex_ ) ;
2019-07-19 16:49:42 +00:00
DLOG ( INFO ) < < " Received " < < what < < " from " < < who ;
2018-05-01 21:32:52 +00:00
unsigned int sat = 0 ;
2019-07-25 14:38:19 +00:00
Gnss_Signal gs ;
2018-10-28 10:07:53 +00:00
if ( who < 200 )
2018-05-01 21:32:52 +00:00
{
2018-10-28 10:07:53 +00:00
try
{
sat = configuration_ - > property ( " Channel " + std : : to_string ( who ) + " .satellite " , 0 ) ;
}
catch ( const std : : exception & e )
{
LOG ( WARNING ) < < e . what ( ) ;
}
2018-05-01 21:32:52 +00:00
}
2012-04-14 18:04:27 +00:00
switch ( what )
2018-03-03 01:03:39 +00:00
{
case 0 :
2019-07-25 14:38:19 +00:00
gs = channels_ [ who ] - > get_signal ( ) ;
2019-07-23 15:56:02 +00:00
DLOG ( INFO ) < < " Channel " < < who < < " ACQ FAILED satellite " < < gs . get_satellite ( ) < < " , Signal " < < gs . get_signal_str ( ) ;
2018-06-13 19:01:40 +00:00
channels_state_ [ who ] = 0 ;
2019-07-21 10:55:59 +00:00
if ( acq_channels_count_ > 0 )
{
acq_channels_count_ - - ;
}
2019-07-20 00:53:31 +00:00
// call the acquisition manager to assign new satellite and start next acquisition (if required)
2019-07-19 16:49:42 +00:00
acquisition_manager ( who ) ;
2019-07-28 10:01:11 +00:00
// push back the old signal AFTER assigning a new one to avoid selecting the same signal
2019-07-23 15:56:02 +00:00
if ( sat = = 0 )
{
push_back_signal ( gs ) ;
}
2018-03-03 01:03:39 +00:00
break ;
case 1 :
2019-07-25 14:38:19 +00:00
gs = channels_ [ who ] - > get_signal ( ) ;
2019-07-23 15:56:02 +00:00
DLOG ( INFO ) < < " Channel " < < who < < " ACQ SUCCESS satellite " < < gs . get_satellite ( ) ;
2018-07-12 18:01:18 +00:00
// If the satellite is in the list of available ones, remove it.
2019-07-23 15:56:02 +00:00
remove_signal ( gs ) ;
2018-07-12 18:01:18 +00:00
2018-03-03 01:03:39 +00:00
channels_state_ [ who ] = 2 ;
2019-07-21 10:55:59 +00:00
if ( acq_channels_count_ > 0 )
{
acq_channels_count_ - - ;
}
2019-07-20 00:53:31 +00:00
// call the acquisition manager to assign new satellite and start next acquisition (if required)
2019-07-19 16:49:42 +00:00
acquisition_manager ( who ) ;
2018-03-03 01:03:39 +00:00
break ;
case 2 :
2019-07-25 14:38:19 +00:00
gs = channels_ [ who ] - > get_signal ( ) ;
2019-07-23 15:56:02 +00:00
DLOG ( INFO ) < < " Channel " < < who < < " TRK FAILED satellite " < < gs . get_satellite ( ) ;
2018-03-03 01:03:39 +00:00
if ( acq_channels_count_ < max_acq_channels_ )
{
2019-07-20 00:53:31 +00:00
// try to acquire the same satellite
2018-03-03 01:03:39 +00:00
channels_state_ [ who ] = 1 ;
acq_channels_count_ + + ;
2019-07-23 15:56:02 +00:00
DLOG ( INFO ) < < " Channel " < < who < < " Starting acquisition " < < gs . get_satellite ( ) < < " , Signal " < < gs . get_signal_str ( ) ;
2019-08-30 15:00:12 +00:00
channels_ [ who ] - > set_signal ( channels_ [ who ] - > get_signal ( ) ) ;
2019-02-13 16:48:14 +00:00
# ifndef ENABLE_FPGA
2018-04-22 17:49:13 +00:00
channels_ [ who ] - > start_acquisition ( ) ;
2019-02-13 16:48:14 +00:00
# else
// create a task for the FPGA such that it doesn't stop the flow
2019-02-27 16:27:31 +00:00
std : : thread tmp_thread ( & ChannelInterface : : start_acquisition , channels_ [ who ] ) ;
2019-02-13 16:48:14 +00:00
tmp_thread . detach ( ) ;
# endif
2018-03-03 01:03:39 +00:00
}
else
{
channels_state_ [ who ] = 0 ;
LOG ( INFO ) < < " Channel " < < who < < " Idle state " ;
2018-04-20 10:50:32 +00:00
if ( sat = = 0 )
{
2019-07-16 15:41:12 +00:00
push_back_signal ( channels_ [ who ] - > get_signal ( ) ) ;
2018-04-20 10:50:32 +00:00
}
2018-03-03 01:03:39 +00:00
}
break ;
2018-11-20 20:56:35 +00:00
case 10 : // request standby mode
2018-10-28 10:07:53 +00:00
for ( size_t n = 0 ; n < channels_ . size ( ) ; n + + )
{
2019-07-20 00:53:31 +00:00
if ( channels_state_ [ n ] = = 1 or channels_state_ [ n ] = = 2 ) // channel in acquisition or in tracking
2018-10-28 10:07:53 +00:00
{
2019-07-20 00:53:31 +00:00
// recover the satellite assigned
2020-02-26 17:16:04 +00:00
Gnss_Signal gs_assigned = channels_ [ n ] - > get_signal ( ) ;
push_back_signal ( gs_assigned ) ;
2019-07-16 15:41:12 +00:00
2019-03-18 18:50:02 +00:00
channels_ [ n ] - > stop_channel ( ) ; // stop the acquisition or tracking operation
2018-10-28 10:07:53 +00:00
channels_state_ [ n ] = 0 ;
}
}
2019-07-25 14:38:19 +00:00
acq_channels_count_ = 0 ; // all channels are in standby now and no new acquisition should be started
2018-10-28 10:07:53 +00:00
break ;
2018-03-03 01:03:39 +00:00
default :
break ;
}
2011-10-01 18:45:20 +00:00
}
2019-06-29 20:04:03 +00:00
void GNSSFlowgraph : : priorize_satellites ( const std : : vector < std : : pair < int , Gnss_Satellite > > & visible_satellites )
2018-11-05 16:53:53 +00:00
{
size_t old_size ;
Gnss_Signal gs ;
2019-02-11 20:13:02 +00:00
for ( auto & visible_satellite : visible_satellites )
2018-11-05 16:53:53 +00:00
{
2019-02-05 00:31:09 +00:00
if ( visible_satellite . second . get_system ( ) = = " GPS " )
2018-11-05 16:53:53 +00:00
{
2019-02-05 00:31:09 +00:00
gs = Gnss_Signal ( visible_satellite . second , " 1C " ) ;
2018-11-05 16:53:53 +00:00
old_size = available_GPS_1C_signals_ . size ( ) ;
available_GPS_1C_signals_ . remove ( gs ) ;
if ( old_size > available_GPS_1C_signals_ . size ( ) )
{
available_GPS_1C_signals_ . push_front ( gs ) ;
}
2019-02-05 00:31:09 +00:00
gs = Gnss_Signal ( visible_satellite . second , " 2S " ) ;
2018-11-05 16:53:53 +00:00
old_size = available_GPS_2S_signals_ . size ( ) ;
available_GPS_2S_signals_ . remove ( gs ) ;
if ( old_size > available_GPS_2S_signals_ . size ( ) )
{
available_GPS_2S_signals_ . push_front ( gs ) ;
}
2019-02-05 00:31:09 +00:00
gs = Gnss_Signal ( visible_satellite . second , " L5 " ) ;
2018-11-05 16:53:53 +00:00
old_size = available_GPS_L5_signals_ . size ( ) ;
available_GPS_L5_signals_ . remove ( gs ) ;
if ( old_size > available_GPS_L5_signals_ . size ( ) )
{
available_GPS_L5_signals_ . push_front ( gs ) ;
}
}
2019-02-05 00:31:09 +00:00
else if ( visible_satellite . second . get_system ( ) = = " Galileo " )
2018-11-05 16:53:53 +00:00
{
2019-02-05 00:31:09 +00:00
gs = Gnss_Signal ( visible_satellite . second , " 1B " ) ;
2018-11-05 16:53:53 +00:00
old_size = available_GAL_1B_signals_ . size ( ) ;
available_GAL_1B_signals_ . remove ( gs ) ;
if ( old_size > available_GAL_1B_signals_ . size ( ) )
{
available_GAL_1B_signals_ . push_front ( gs ) ;
}
2019-02-05 00:31:09 +00:00
gs = Gnss_Signal ( visible_satellite . second , " 5X " ) ;
2018-11-05 16:53:53 +00:00
old_size = available_GAL_5X_signals_ . size ( ) ;
available_GAL_5X_signals_ . remove ( gs ) ;
if ( old_size > available_GAL_5X_signals_ . size ( ) )
{
available_GAL_5X_signals_ . push_front ( gs ) ;
}
}
}
}
2019-09-11 22:31:34 +00:00
void GNSSFlowgraph : : set_configuration ( const std : : shared_ptr < ConfigurationInterface > & configuration )
2012-04-14 18:04:27 +00:00
{
if ( running_ )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Unable to update configuration while flowgraph running " ;
2012-04-14 18:04:27 +00:00
return ;
}
if ( connected_ )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Unable to update configuration while flowgraph connected " ;
2012-04-14 18:04:27 +00:00
}
2019-09-13 06:56:37 +00:00
configuration_ = configuration ;
2011-10-01 18:45:20 +00:00
}
2012-04-14 18:04:27 +00:00
2019-03-18 18:50:02 +00:00
# ifdef ENABLE_FPGA
2018-04-06 15:03:20 +00:00
void GNSSFlowgraph : : start_acquisition_helper ( )
{
2020-07-09 22:37:55 +00:00
for ( int i = 0 ; i < channels_count_ ; i + + )
2018-04-13 13:27:14 +00:00
{
if ( channels_state_ [ i ] = = 1 )
{
channels_ . at ( i ) - > start_acquisition ( ) ;
}
}
2018-04-06 15:03:20 +00:00
}
2018-04-30 17:23:35 +00:00
2019-02-13 16:48:14 +00:00
void GNSSFlowgraph : : perform_hw_reset ( )
{
2019-07-30 05:40:23 +00:00
// a stop acquisition command causes the SW to reset the HW
std : : shared_ptr < Channel > channel_ptr ;
2019-07-29 13:57:18 +00:00
2019-07-30 05:40:23 +00:00
for ( uint32_t i = 0 ; i < channels_count_ ; i + + )
{
channel_ptr = std : : dynamic_pointer_cast < Channel > ( channels_ . at ( i ) ) ;
channel_ptr - > tracking ( ) - > stop_tracking ( ) ;
}
2019-07-29 13:57:18 +00:00
2019-07-30 05:40:23 +00:00
std : : this_thread : : sleep_for ( std : : chrono : : milliseconds ( 500 ) ) ;
2019-07-29 13:57:18 +00:00
2019-07-30 05:40:23 +00:00
channel_ptr = std : : dynamic_pointer_cast < Channel > ( channels_ . at ( 0 ) ) ;
channel_ptr - > acquisition ( ) - > stop_acquisition ( ) ;
2019-02-13 16:48:14 +00:00
}
# endif
2019-03-18 18:50:02 +00:00
2012-04-14 18:04:27 +00:00
void GNSSFlowgraph : : init ( )
{
/*
* Instantiates the receiver blocks
*/
2020-06-21 21:07:31 +00:00
auto block_factory = std : : make_unique < GNSSBlockFactory > ( ) ;
2012-04-14 18:04:27 +00:00
2019-07-11 16:39:28 +00:00
channels_status_ = channel_status_msg_receiver_make ( ) ;
2015-02-12 17:56:05 +00:00
// 1. read the number of RF front-ends available (one file_source per RF front-end)
sources_count_ = configuration_ - > property ( " Receiver.sources_count " , 1 ) ;
2012-01-16 18:27:31 +00:00
2015-03-01 21:23:17 +00:00
int RF_Channels = 0 ;
int signal_conditioner_ID = 0 ;
2015-03-01 19:25:50 +00:00
2015-02-27 17:21:25 +00:00
if ( sources_count_ > 1 )
{
for ( int i = 0 ; i < sources_count_ ; i + + )
{
2020-07-07 16:53:50 +00:00
std : : cout < < " Creating source " < < i < < ' \n ' ;
2020-06-21 21:07:31 +00:00
sig_source_ . push_back ( block_factory - > GetSignalSource ( configuration_ . get ( ) , queue_ . get ( ) , i ) ) ;
2018-04-20 11:20:10 +00:00
// TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface.
// Include GetRFChannels in the interface to avoid read config parameters here
// read the number of RF channels for each front-end
2015-03-01 21:23:17 +00:00
RF_Channels = configuration_ - > property ( sig_source_ . at ( i ) - > role ( ) + " .RF_channels " , 1 ) ;
2020-07-07 16:53:50 +00:00
std : : cout < < " RF Channels " < < RF_Channels < < ' \n ' ;
2015-03-01 21:23:17 +00:00
for ( int j = 0 ; j < RF_Channels ; j + + )
{
2020-06-21 21:07:31 +00:00
sig_conditioner_ . push_back ( block_factory - > GetSignalConditioner ( configuration_ . get ( ) , signal_conditioner_ID ) ) ;
2015-03-01 21:23:17 +00:00
signal_conditioner_ID + + ;
}
2015-02-27 17:21:25 +00:00
}
}
2017-05-05 14:37:29 +00:00
else
{
2018-04-20 11:20:10 +00:00
// backwards compatibility for old config files
2020-06-21 21:07:31 +00:00
sig_source_ . push_back ( block_factory - > GetSignalSource ( configuration_ . get ( ) , queue_ . get ( ) , - 1 ) ) ;
2018-04-20 11:20:10 +00:00
// TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface.
// Include GetRFChannels in the interface to avoid read config parameters here
// read the number of RF channels for each front-end
2015-03-01 21:23:17 +00:00
RF_Channels = configuration_ - > property ( sig_source_ . at ( 0 ) - > role ( ) + " .RF_channels " , 0 ) ;
if ( RF_Channels ! = 0 )
{
for ( int j = 0 ; j < RF_Channels ; j + + )
{
2020-06-21 21:07:31 +00:00
sig_conditioner_ . push_back ( block_factory - > GetSignalConditioner ( configuration_ . get ( ) , signal_conditioner_ID ) ) ;
2015-03-01 21:23:17 +00:00
signal_conditioner_ID + + ;
}
}
else
{
2018-04-20 11:20:10 +00:00
// old config file, single signal source and single channel, not specified
2020-06-21 21:07:31 +00:00
sig_conditioner_ . push_back ( block_factory - > GetSignalConditioner ( configuration_ . get ( ) , - 1 ) ) ;
2015-03-01 21:23:17 +00:00
}
2017-05-05 14:37:29 +00:00
}
2015-02-12 17:56:05 +00:00
2020-06-21 21:07:31 +00:00
observables_ = block_factory - > GetObservables ( configuration_ . get ( ) ) ;
2017-05-08 19:17:54 +00:00
// Mark old implementations as deprecated
std : : string default_str ( " Default " ) ;
std : : string obs_implementation = configuration_ - > property ( " Observables.implementation " , default_str ) ;
2018-12-02 21:53:05 +00:00
if ( ( obs_implementation = = " GPS_L1_CA_Observables " ) | | ( obs_implementation = = " GPS_L2C_Observables " ) | |
( obs_implementation = = " Galileo_E1B_Observables " ) | | ( obs_implementation = = " Galileo_E5A_Observables " ) )
2017-05-05 14:37:29 +00:00
{
2020-07-07 16:53:50 +00:00
std : : cout < < " WARNING: Implementation ' " < < obs_implementation < < " ' of the Observables block has been replaced by 'Hybrid_Observables'. \n " ;
std : : cout < < " Please update your configuration file. \n " ;
2017-05-05 14:37:29 +00:00
}
2015-02-12 17:56:05 +00:00
2020-06-21 21:07:31 +00:00
pvt_ = block_factory - > GetPVT ( configuration_ . get ( ) ) ;
2017-05-08 19:17:54 +00:00
// Mark old implementations as deprecated
std : : string pvt_implementation = configuration_ - > property ( " PVT.implementation " , default_str ) ;
2018-12-02 21:53:05 +00:00
if ( ( pvt_implementation = = " GPS_L1_CA_PVT " ) | | ( pvt_implementation = = " Galileo_E1_PVT " ) | | ( pvt_implementation = = " Hybrid_PVT " ) )
2017-05-08 19:17:54 +00:00
{
2020-07-07 16:53:50 +00:00
std : : cout < < " WARNING: Implementation ' " < < pvt_implementation < < " ' of the PVT block has been replaced by 'RTKLIB_PVT'. \n " ;
std : : cout < < " Please update your configuration file. \n " ;
2017-05-08 19:17:54 +00:00
}
2011-10-01 18:45:20 +00:00
2020-06-21 21:07:31 +00:00
auto channels = block_factory - > GetChannels ( configuration_ . get ( ) , queue_ . get ( ) ) ;
2012-01-16 18:27:31 +00:00
2020-07-09 22:37:55 +00:00
channels_count_ = static_cast < int > ( channels - > size ( ) ) ;
for ( int i = 0 ; i < channels_count_ ; i + + )
2012-04-14 18:04:27 +00:00
{
2015-02-27 17:21:25 +00:00
std : : shared_ptr < GNSSBlockInterface > chan_ = std : : move ( channels - > at ( i ) ) ;
2015-02-12 17:56:05 +00:00
channels_ . push_back ( std : : dynamic_pointer_cast < ChannelInterface > ( chan_ ) ) ;
2012-04-14 18:04:27 +00:00
}
2011-10-01 18:45:20 +00:00
2013-07-04 13:47:40 +00:00
top_block_ = gr : : make_top_block ( " GNSSFlowgraph " ) ;
2011-10-01 18:45:20 +00:00
2018-06-14 21:10:43 +00:00
mapStringValues_ [ " 1C " ] = evGPS_1C ;
mapStringValues_ [ " 2S " ] = evGPS_2S ;
mapStringValues_ [ " L5 " ] = evGPS_L5 ;
mapStringValues_ [ " 1B " ] = evGAL_1B ;
mapStringValues_ [ " 5X " ] = evGAL_5X ;
mapStringValues_ [ " 1G " ] = evGLO_1G ;
mapStringValues_ [ " 2G " ] = evGLO_2G ;
2018-10-22 19:16:38 +00:00
mapStringValues_ [ " B1 " ] = evBDS_B1 ;
2019-01-25 21:43:00 +00:00
mapStringValues_ [ " B3 " ] = evBDS_B3 ;
2018-06-14 21:10:43 +00:00
// fill the signals queue with the satellites ID's to be searched by the acquisition
2012-04-14 18:04:27 +00:00
set_signals_list ( ) ;
set_channels_state ( ) ;
DLOG ( INFO ) < < " Blocks instantiated. " < < channels_count_ < < " channels. " ;
2018-07-03 11:25:43 +00:00
/*
2019-10-05 01:16:31 +00:00
* Instantiate the receiver monitor block , if required
*/
2018-07-03 11:25:43 +00:00
enable_monitor_ = configuration_ - > property ( " Monitor.enable_monitor " , false ) ;
2019-04-21 11:30:59 +00:00
bool enable_protobuf = configuration_ - > property ( " Monitor.enable_protobuf " , true ) ;
if ( configuration_ - > property ( " PVT.enable_protobuf " , false ) = = true )
{
enable_protobuf = true ;
}
2018-07-03 11:25:43 +00:00
std : : string address_string = configuration_ - > property ( " Monitor.client_addresses " , std : : string ( " 127.0.0.1 " ) ) ;
2018-08-22 13:42:38 +00:00
std : : vector < std : : string > udp_addr_vec = split_string ( address_string , ' _ ' ) ;
std : : sort ( udp_addr_vec . begin ( ) , udp_addr_vec . end ( ) ) ;
udp_addr_vec . erase ( std : : unique ( udp_addr_vec . begin ( ) , udp_addr_vec . end ( ) ) , udp_addr_vec . end ( ) ) ;
2018-07-03 11:25:43 +00:00
if ( enable_monitor_ )
{
2019-03-08 09:24:06 +00:00
GnssSynchroMonitor_ = gnss_synchro_make_monitor ( channels_count_ ,
2019-02-18 16:51:02 +00:00
configuration_ - > property ( " Monitor.decimation_factor " , 1 ) ,
2018-07-03 11:25:43 +00:00
configuration_ - > property ( " Monitor.udp_port " , 1234 ) ,
2019-04-21 11:30:59 +00:00
udp_addr_vec , enable_protobuf ) ;
2018-07-03 11:25:43 +00:00
}
2011-10-01 18:45:20 +00:00
}
2015-02-27 17:21:25 +00:00
2019-03-18 18:50:02 +00:00
std : : vector < std : : string > GNSSFlowgraph : : split_string ( const std : : string & s , char delim )
{
std : : vector < std : : string > v ;
std : : stringstream ss ( s ) ;
std : : string item ;
while ( std : : getline ( ss , item , delim ) )
{
* ( std : : back_inserter ( v ) + + ) = item ;
}
return v ;
}
2012-04-14 18:04:27 +00:00
void GNSSFlowgraph : : set_signals_list ( )
{
2018-04-20 10:50:32 +00:00
// Set a sequential list of GNSS satellites
2017-08-17 09:03:02 +00:00
std : : set < unsigned int > : : const_iterator available_gnss_prn_iter ;
2013-07-20 07:58:59 +00:00
2018-04-20 10:50:32 +00:00
// Create the lists of GNSS satellites
2018-03-03 01:03:39 +00:00
std : : set < unsigned int > available_gps_prn = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ,
11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 ,
29 , 30 , 31 , 32 } ;
2015-05-07 14:30:01 +00:00
2018-08-21 14:41:07 +00:00
std : : set < unsigned int > available_sbas_prn = { 123 , 131 , 135 , 136 , 138 } ;
2015-05-08 23:48:16 +00:00
2018-03-03 01:03:39 +00:00
std : : set < unsigned int > available_galileo_prn = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ,
11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 ,
29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 } ;
2015-05-08 23:48:16 +00:00
2017-09-09 19:44:35 +00:00
// Removing satellites sharing same frequency number(1 and 5, 2 and 6, 3 and 7, 4 and 6, 11 and 15, 12 and 16, 14 and 18, 17 and 21
2018-03-03 01:03:39 +00:00
std : : set < unsigned int > available_glonass_prn = { 1 , 2 , 3 , 4 , 9 , 10 , 11 , 12 , 18 , 19 , 20 , 21 , 24 } ;
2017-03-29 15:15:57 +00:00
2018-06-15 02:19:32 +00:00
std : : set < unsigned int > available_beidou_prn = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ,
2018-07-06 12:42:13 +00:00
11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 ,
2019-03-18 07:43:38 +00:00
30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 ,
50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63 } ;
2018-06-15 02:19:32 +00:00
2018-03-03 01:03:39 +00:00
std : : string sv_list = configuration_ - > property ( " Galileo.prns " , std : : string ( " " ) ) ;
2015-10-24 08:39:10 +00:00
2018-03-03 01:03:39 +00:00
if ( sv_list . length ( ) > 0 )
2017-05-05 14:37:29 +00:00
{
2016-05-01 23:28:37 +00:00
// Reset the available prns:
2018-03-03 01:03:39 +00:00
std : : set < unsigned int > tmp_set ;
boost : : tokenizer < > tok ( sv_list ) ;
std : : transform ( tok . begin ( ) , tok . end ( ) , std : : inserter ( tmp_set , tmp_set . begin ( ) ) ,
boost : : lexical_cast < unsigned int , std : : string > ) ;
2016-05-01 23:28:37 +00:00
2019-02-05 00:31:09 +00:00
if ( ! tmp_set . empty ( ) )
2016-05-01 23:28:37 +00:00
{
available_galileo_prn = tmp_set ;
}
2015-10-24 08:39:10 +00:00
}
2020-07-06 22:05:31 +00:00
std : : string sv_banned = configuration_ - > property ( " GNSS-SDR.Galileo_banned_prns " , std : : string ( " " ) ) ;
if ( ! sv_banned . empty ( ) )
{
std : : stringstream ss ( sv_banned ) ;
while ( ss . good ( ) )
{
std : : string substr ;
std : : getline ( ss , substr , ' , ' ) ;
try
{
auto banned = static_cast < unsigned int > ( std : : stoi ( substr ) ) ;
available_galileo_prn . erase ( banned ) ;
}
catch ( const std : : invalid_argument & ia )
{
std : : cerr < < " Invalid argument at GNSS-SDR.Galileo_banned_prns configuration parameter: " < < ia . what ( ) < < ' \n ' ;
}
catch ( const std : : out_of_range & oor )
{
std : : cerr < < " Out of range at GNSS-SDR.Galileo_banned_prns configuration parameter: " < < oor . what ( ) < < ' \n ' ;
}
}
}
2018-03-03 01:03:39 +00:00
sv_list = configuration_ - > property ( " GPS.prns " , std : : string ( " " ) ) ;
2015-05-08 23:48:16 +00:00
2018-03-03 01:03:39 +00:00
if ( sv_list . length ( ) > 0 )
2017-05-05 14:37:29 +00:00
{
2016-05-01 23:28:37 +00:00
// Reset the available prns:
2018-03-03 01:03:39 +00:00
std : : set < unsigned int > tmp_set ;
boost : : tokenizer < > tok ( sv_list ) ;
std : : transform ( tok . begin ( ) , tok . end ( ) , std : : inserter ( tmp_set , tmp_set . begin ( ) ) ,
boost : : lexical_cast < unsigned int , std : : string > ) ;
2016-05-01 23:28:37 +00:00
2019-02-05 00:31:09 +00:00
if ( ! tmp_set . empty ( ) )
2016-05-01 23:28:37 +00:00
{
available_gps_prn = tmp_set ;
}
2015-10-24 08:39:10 +00:00
}
2016-05-01 23:28:37 +00:00
2020-07-06 22:05:31 +00:00
sv_banned = configuration_ - > property ( " GNSS-SDR.GPS_banned_prns " , std : : string ( " " ) ) ;
if ( ! sv_banned . empty ( ) )
{
std : : stringstream ss ( sv_banned ) ;
while ( ss . good ( ) )
{
std : : string substr ;
std : : getline ( ss , substr , ' , ' ) ;
try
{
auto banned = static_cast < unsigned int > ( std : : stoi ( substr ) ) ;
available_gps_prn . erase ( banned ) ;
}
catch ( const std : : invalid_argument & ia )
{
std : : cerr < < " Invalid argument at GNSS-SDR.GPS_banned_prns configuration parameter: " < < ia . what ( ) < < ' \n ' ;
}
catch ( const std : : out_of_range & oor )
{
std : : cerr < < " Out of range at GNSS-SDR.GPS_banned_prns configuration parameter: " < < oor . what ( ) < < ' \n ' ;
}
}
}
2018-03-03 01:03:39 +00:00
sv_list = configuration_ - > property ( " SBAS.prns " , std : : string ( " " ) ) ;
2015-05-08 23:48:16 +00:00
2018-03-03 01:03:39 +00:00
if ( sv_list . length ( ) > 0 )
2017-05-05 14:37:29 +00:00
{
2016-05-01 23:28:37 +00:00
// Reset the available prns:
2018-03-03 01:03:39 +00:00
std : : set < unsigned int > tmp_set ;
boost : : tokenizer < > tok ( sv_list ) ;
std : : transform ( tok . begin ( ) , tok . end ( ) , std : : inserter ( tmp_set , tmp_set . begin ( ) ) ,
boost : : lexical_cast < unsigned int , std : : string > ) ;
2016-05-01 23:28:37 +00:00
2019-02-05 00:31:09 +00:00
if ( ! tmp_set . empty ( ) )
2016-05-01 23:28:37 +00:00
{
available_sbas_prn = tmp_set ;
}
2015-10-24 08:39:10 +00:00
}
2015-05-08 23:48:16 +00:00
2020-07-06 22:05:31 +00:00
sv_banned = configuration_ - > property ( " GNSS-SDR.SBAS_banned_prns " , std : : string ( " " ) ) ;
if ( ! sv_banned . empty ( ) )
{
std : : stringstream ss ( sv_banned ) ;
while ( ss . good ( ) )
{
std : : string substr ;
std : : getline ( ss , substr , ' , ' ) ;
try
{
auto banned = static_cast < unsigned int > ( std : : stoi ( substr ) ) ;
available_sbas_prn . erase ( banned ) ;
}
catch ( const std : : invalid_argument & ia )
{
std : : cerr < < " Invalid argument at GNSS-SDR.SBAS_banned_prns configuration parameter: " < < ia . what ( ) < < ' \n ' ;
}
catch ( const std : : out_of_range & oor )
{
std : : cerr < < " Out of range at GNSS-SDR.SBAS_banned_prns configuration parameter: " < < oor . what ( ) < < ' \n ' ;
}
}
}
2018-03-03 01:03:39 +00:00
sv_list = configuration_ - > property ( " Glonass.prns " , std : : string ( " " ) ) ;
2017-03-29 15:15:57 +00:00
2018-03-03 01:03:39 +00:00
if ( sv_list . length ( ) > 0 )
2017-03-29 15:15:57 +00:00
{
// Reset the available prns:
2018-03-03 01:03:39 +00:00
std : : set < unsigned int > tmp_set ;
boost : : tokenizer < > tok ( sv_list ) ;
std : : transform ( tok . begin ( ) , tok . end ( ) , std : : inserter ( tmp_set , tmp_set . begin ( ) ) ,
boost : : lexical_cast < unsigned int , std : : string > ) ;
2017-03-29 15:15:57 +00:00
2019-02-05 00:31:09 +00:00
if ( ! tmp_set . empty ( ) )
2017-03-29 15:15:57 +00:00
{
available_glonass_prn = tmp_set ;
}
}
2019-01-25 21:43:00 +00:00
2020-07-06 22:05:31 +00:00
sv_banned = configuration_ - > property ( " GNSS-SDR.Glonass_banned_prns " , std : : string ( " " ) ) ;
if ( ! sv_banned . empty ( ) )
{
std : : stringstream ss ( sv_banned ) ;
while ( ss . good ( ) )
{
std : : string substr ;
std : : getline ( ss , substr , ' , ' ) ;
try
{
auto banned = static_cast < unsigned int > ( std : : stoi ( substr ) ) ;
available_glonass_prn . erase ( banned ) ;
}
catch ( const std : : invalid_argument & ia )
{
std : : cerr < < " Invalid argument at GNSS-SDR.Glonass_banned_prns configuration parameter: " < < ia . what ( ) < < ' \n ' ;
}
catch ( const std : : out_of_range & oor )
{
std : : cerr < < " Out of range at GNSS-SDR.Glonass_banned_prns configuration parameter: " < < oor . what ( ) < < ' \n ' ;
}
}
}
2018-06-15 02:19:32 +00:00
sv_list = configuration_ - > property ( " Beidou.prns " , std : : string ( " " ) ) ;
2019-03-18 07:43:38 +00:00
2018-06-15 02:19:32 +00:00
if ( sv_list . length ( ) > 0 )
{
// Reset the available prns:
std : : set < unsigned int > tmp_set ;
boost : : tokenizer < > tok ( sv_list ) ;
std : : transform ( tok . begin ( ) , tok . end ( ) , std : : inserter ( tmp_set , tmp_set . begin ( ) ) ,
boost : : lexical_cast < unsigned int , std : : string > ) ;
2019-02-05 00:31:09 +00:00
if ( ! tmp_set . empty ( ) )
2018-06-15 02:19:32 +00:00
{
available_beidou_prn = tmp_set ;
}
}
2020-07-06 22:05:31 +00:00
sv_banned = configuration_ - > property ( " GNSS-SDR.Beidou_banned_prns " , std : : string ( " " ) ) ;
if ( ! sv_banned . empty ( ) )
{
std : : stringstream ss ( sv_banned ) ;
while ( ss . good ( ) )
{
std : : string substr ;
std : : getline ( ss , substr , ' , ' ) ;
try
{
auto banned = static_cast < unsigned int > ( std : : stoi ( substr ) ) ;
available_beidou_prn . erase ( banned ) ;
}
catch ( const std : : invalid_argument & ia )
{
std : : cerr < < " Invalid argument at GNSS-SDR.Beidou_banned_prns configuration parameter: " < < ia . what ( ) < < ' \n ' ;
}
catch ( const std : : out_of_range & oor )
{
std : : cerr < < " Out of range at GNSS-SDR.Beidou_banned_prns configuration parameter: " < < oor . what ( ) < < ' \n ' ;
}
}
}
2018-03-03 01:03:39 +00:00
if ( configuration_ - > property ( " Channels_1C.count " , 0 ) > 0 )
2014-04-13 16:58:52 +00:00
{
2018-06-14 21:10:43 +00:00
// Loop to create GPS L1 C/A signals
2017-08-17 09:03:02 +00:00
for ( available_gnss_prn_iter = available_gps_prn . cbegin ( ) ;
2018-03-03 01:03:39 +00:00
available_gnss_prn_iter ! = available_gps_prn . cend ( ) ;
available_gnss_prn_iter + + )
2014-04-13 16:58:52 +00:00
{
2019-06-29 22:01:54 +00:00
available_GPS_1C_signals_ . emplace_back (
2018-03-03 01:03:39 +00:00
Gnss_Satellite ( std : : string ( " GPS " ) , * available_gnss_prn_iter ) ,
2019-06-29 22:01:54 +00:00
std : : string ( " 1C " ) ) ;
2014-04-13 16:58:52 +00:00
}
}
2013-07-20 07:58:59 +00:00
2016-04-21 16:54:08 +00:00
if ( configuration_ - > property ( " Channels_2S.count " , 0 ) > 0 )
2015-04-24 17:11:45 +00:00
{
2018-06-14 21:10:43 +00:00
// Loop to create GPS L2C M signals
2017-08-17 09:03:02 +00:00
for ( available_gnss_prn_iter = available_gps_prn . cbegin ( ) ;
2018-03-03 01:03:39 +00:00
available_gnss_prn_iter ! = available_gps_prn . cend ( ) ;
available_gnss_prn_iter + + )
2015-04-24 17:11:45 +00:00
{
2019-06-29 22:01:54 +00:00
available_GPS_2S_signals_ . emplace_back (
2018-03-03 01:03:39 +00:00
Gnss_Satellite ( std : : string ( " GPS " ) , * available_gnss_prn_iter ) ,
2019-06-29 22:01:54 +00:00
std : : string ( " 2S " ) ) ;
2015-04-24 17:11:45 +00:00
}
}
2017-11-30 16:42:19 +00:00
if ( configuration_ - > property ( " Channels_L5.count " , 0 ) > 0 )
{
2018-06-14 21:10:43 +00:00
// Loop to create GPS L5 signals
2017-11-30 16:42:19 +00:00
for ( available_gnss_prn_iter = available_gps_prn . cbegin ( ) ;
2018-03-03 01:03:39 +00:00
available_gnss_prn_iter ! = available_gps_prn . cend ( ) ;
available_gnss_prn_iter + + )
2017-11-30 16:42:19 +00:00
{
2019-06-29 22:01:54 +00:00
available_GPS_L5_signals_ . emplace_back (
2018-03-03 01:03:39 +00:00
Gnss_Satellite ( std : : string ( " GPS " ) , * available_gnss_prn_iter ) ,
2019-06-29 22:01:54 +00:00
std : : string ( " L5 " ) ) ;
2017-11-30 16:42:19 +00:00
}
}
2018-04-20 10:50:32 +00:00
2016-04-21 16:54:08 +00:00
if ( configuration_ - > property ( " Channels_SBAS.count " , 0 ) > 0 )
2014-04-13 16:58:52 +00:00
{
2018-06-14 21:10:43 +00:00
// Loop to create SBAS L1 C/A signals
2017-08-17 09:03:02 +00:00
for ( available_gnss_prn_iter = available_sbas_prn . cbegin ( ) ;
2018-03-03 01:03:39 +00:00
available_gnss_prn_iter ! = available_sbas_prn . cend ( ) ;
available_gnss_prn_iter + + )
2014-04-13 16:58:52 +00:00
{
2019-06-29 22:01:54 +00:00
available_SBAS_1C_signals_ . emplace_back (
2018-03-03 01:03:39 +00:00
Gnss_Satellite ( std : : string ( " SBAS " ) , * available_gnss_prn_iter ) ,
2019-06-29 22:01:54 +00:00
std : : string ( " 1C " ) ) ;
2014-04-13 16:58:52 +00:00
}
}
2013-07-20 07:58:59 +00:00
2016-04-21 16:54:08 +00:00
if ( configuration_ - > property ( " Channels_1B.count " , 0 ) > 0 )
2012-09-03 11:58:28 +00:00
{
2018-06-14 21:10:43 +00:00
// Loop to create the list of Galileo E1B signals
2017-08-17 09:03:02 +00:00
for ( available_gnss_prn_iter = available_galileo_prn . cbegin ( ) ;
2018-03-03 01:03:39 +00:00
available_gnss_prn_iter ! = available_galileo_prn . cend ( ) ;
available_gnss_prn_iter + + )
2015-05-07 14:30:01 +00:00
{
2019-06-29 22:01:54 +00:00
available_GAL_1B_signals_ . emplace_back (
2018-03-03 01:03:39 +00:00
Gnss_Satellite ( std : : string ( " Galileo " ) , * available_gnss_prn_iter ) ,
2019-06-29 22:01:54 +00:00
std : : string ( " 1B " ) ) ;
2015-05-07 14:30:01 +00:00
}
}
2014-04-13 16:58:52 +00:00
2018-03-03 01:03:39 +00:00
if ( configuration_ - > property ( " Channels_5X.count " , 0 ) > 0 )
2015-05-07 14:30:01 +00:00
{
2018-06-14 21:10:43 +00:00
// Loop to create the list of Galileo E5a signals
2017-08-17 09:03:02 +00:00
for ( available_gnss_prn_iter = available_galileo_prn . cbegin ( ) ;
2018-03-03 01:03:39 +00:00
available_gnss_prn_iter ! = available_galileo_prn . cend ( ) ;
available_gnss_prn_iter + + )
2014-04-13 16:58:52 +00:00
{
2019-06-29 22:01:54 +00:00
available_GAL_5X_signals_ . emplace_back (
2018-03-03 01:03:39 +00:00
Gnss_Satellite ( std : : string ( " Galileo " ) , * available_gnss_prn_iter ) ,
2019-06-29 22:01:54 +00:00
std : : string ( " 5X " ) ) ;
2014-04-13 16:58:52 +00:00
}
2012-04-14 18:04:27 +00:00
}
2017-03-29 15:15:57 +00:00
2018-03-03 01:03:39 +00:00
if ( configuration_ - > property ( " Channels_1G.count " , 0 ) > 0 )
{
2018-06-14 21:10:43 +00:00
// Loop to create the list of GLONASS L1 C/A signals
2018-10-05 11:54:35 +00:00
for ( available_gnss_prn_iter = available_glonass_prn . cbegin ( ) ;
available_gnss_prn_iter ! = available_glonass_prn . cend ( ) ;
2018-03-03 01:03:39 +00:00
available_gnss_prn_iter + + )
{
2019-06-29 22:01:54 +00:00
available_GLO_1G_signals_ . emplace_back (
2018-03-03 01:03:39 +00:00
Gnss_Satellite ( std : : string ( " Glonass " ) , * available_gnss_prn_iter ) ,
2019-06-29 22:01:54 +00:00
std : : string ( " 1G " ) ) ;
2018-03-03 01:03:39 +00:00
}
}
2018-03-24 18:42:04 +00:00
if ( configuration_ - > property ( " Channels_2G.count " , 0 ) > 0 )
{
2018-06-14 21:10:43 +00:00
// Loop to create the list of GLONASS L2 C/A signals
2018-10-05 11:54:35 +00:00
for ( available_gnss_prn_iter = available_glonass_prn . cbegin ( ) ;
available_gnss_prn_iter ! = available_glonass_prn . cend ( ) ;
2018-03-24 18:42:04 +00:00
available_gnss_prn_iter + + )
{
2019-06-29 22:01:54 +00:00
available_GLO_2G_signals_ . emplace_back (
2018-03-24 18:42:04 +00:00
Gnss_Satellite ( std : : string ( " Glonass " ) , * available_gnss_prn_iter ) ,
2019-06-29 22:01:54 +00:00
std : : string ( " 2G " ) ) ;
2018-03-24 18:42:04 +00:00
}
}
2018-06-15 02:19:32 +00:00
if ( configuration_ - > property ( " Channels_B1.count " , 0 ) > 0 )
{
2019-07-20 00:53:31 +00:00
// Loop to create the list of BeiDou B1C signals
2018-10-22 19:16:38 +00:00
for ( available_gnss_prn_iter = available_beidou_prn . cbegin ( ) ;
available_gnss_prn_iter ! = available_beidou_prn . cend ( ) ;
2018-06-15 02:19:32 +00:00
available_gnss_prn_iter + + )
{
2019-06-29 22:01:54 +00:00
available_BDS_B1_signals_ . emplace_back (
2018-06-15 02:19:32 +00:00
Gnss_Satellite ( std : : string ( " Beidou " ) , * available_gnss_prn_iter ) ,
2019-06-29 22:01:54 +00:00
std : : string ( " B1 " ) ) ;
2018-06-15 02:19:32 +00:00
}
}
2019-01-25 21:43:00 +00:00
if ( configuration_ - > property ( " Channels_B3.count " , 0 ) > 0 )
{
2019-07-20 00:53:31 +00:00
// Loop to create the list of BeiDou B1C signals
2019-01-25 21:43:00 +00:00
for ( available_gnss_prn_iter = available_beidou_prn . cbegin ( ) ;
available_gnss_prn_iter ! = available_beidou_prn . cend ( ) ;
available_gnss_prn_iter + + )
{
2019-06-29 22:01:54 +00:00
available_BDS_B3_signals_ . emplace_back (
2019-01-25 21:43:00 +00:00
Gnss_Satellite ( std : : string ( " Beidou " ) , * available_gnss_prn_iter ) ,
2019-06-29 22:01:54 +00:00
std : : string ( " B3 " ) ) ;
2019-01-25 21:43:00 +00:00
}
}
2012-03-02 17:17:51 +00:00
}
2012-04-14 18:04:27 +00:00
void GNSSFlowgraph : : set_channels_state ( )
{
2020-06-19 10:39:28 +00:00
std : : lock_guard < std : : mutex > lock ( signal_list_mutex_ ) ;
2018-04-20 10:50:32 +00:00
max_acq_channels_ = configuration_ - > property ( " Channels.in_acquisition " , channels_count_ ) ;
2012-04-14 18:04:27 +00:00
if ( max_acq_channels_ > channels_count_ )
{
max_acq_channels_ = channels_count_ ;
2016-05-01 23:28:37 +00:00
LOG ( WARNING ) < < " Channels_in_acquisition is bigger than number of channels. Variable acq_channels_count_ is set to " < < channels_count_ ;
2012-04-14 18:04:27 +00:00
}
channels_state_ . reserve ( channels_count_ ) ;
2020-07-09 22:37:55 +00:00
for ( int i = 0 ; i < channels_count_ ; i + + )
2012-04-14 18:04:27 +00:00
{
2018-03-03 01:03:39 +00:00
if ( i < max_acq_channels_ )
{
channels_state_ . push_back ( 1 ) ;
}
else
{
channels_state_ . push_back ( 0 ) ;
}
2015-05-04 20:16:26 +00:00
DLOG ( INFO ) < < " Channel " < < i < < " in state " < < channels_state_ [ i ] ;
2012-04-14 18:04:27 +00:00
}
acq_channels_count_ = max_acq_channels_ ;
DLOG ( INFO ) < < acq_channels_count_ < < " channels in acquisition state " ;
2011-10-01 18:45:20 +00:00
}
2018-01-05 10:50:52 +00:00
2018-03-03 01:03:39 +00:00
2019-10-04 07:17:29 +00:00
bool GNSSFlowgraph : : is_multiband ( ) const
{
bool multiband = false ;
if ( configuration_ - > property ( " Channels_1C.count " , 0 ) > 0 )
{
if ( configuration_ - > property ( " Channels_2S.count " , 0 ) > 0 )
{
multiband = true ;
}
if ( configuration_ - > property ( " Channels_L5.count " , 0 ) > 0 )
{
multiband = true ;
}
}
if ( configuration_ - > property ( " Channels_1B.count " , 0 ) > 0 )
{
if ( configuration_ - > property ( " Channels_5X.count " , 0 ) > 0 )
{
multiband = true ;
}
}
if ( configuration_ - > property ( " Channels_1G.count " , 0 ) > 0 )
{
if ( configuration_ - > property ( " Channels_2G.count " , 0 ) > 0 )
{
multiband = true ;
}
}
if ( configuration_ - > property ( " Channels_B1.count " , 0 ) > 0 )
{
if ( configuration_ - > property ( " Channels_B3.count " , 0 ) > 0 )
{
multiband = true ;
}
}
return multiband ;
}
2019-07-11 16:39:28 +00:00
Gnss_Signal GNSSFlowgraph : : search_next_signal ( const std : : string & searched_signal ,
const bool pop ,
bool & is_primary_frequency ,
bool & assistance_available ,
float & estimated_doppler ,
double & RX_time )
2018-01-05 10:50:52 +00:00
{
2019-07-11 16:39:28 +00:00
is_primary_frequency = false ;
2019-07-19 16:49:42 +00:00
assistance_available = false ;
2018-06-14 21:10:43 +00:00
Gnss_Signal result ;
2019-07-16 15:41:12 +00:00
bool found_signal = false ;
2018-06-14 21:10:43 +00:00
switch ( mapStringValues_ [ searched_signal ] )
2018-01-05 10:50:52 +00:00
{
2018-06-14 21:10:43 +00:00
case evGPS_1C :
2019-08-18 20:16:13 +00:00
// todo: assist the satellite selection with almanac and current PVT here (rehuse priorize_satellite function used in control_thread)
2018-06-14 21:10:43 +00:00
result = available_GPS_1C_signals_ . front ( ) ;
2018-07-08 11:30:49 +00:00
available_GPS_1C_signals_ . pop_front ( ) ;
if ( ! pop )
2018-06-14 21:10:43 +00:00
{
2018-07-08 11:30:49 +00:00
available_GPS_1C_signals_ . push_back ( result ) ;
2019-03-18 07:43:38 +00:00
}
2019-07-20 00:53:31 +00:00
is_primary_frequency = true ; // indicate that the searched satellite signal belongs to "primary" link (L1, E1, B1, etc..)
2019-07-11 16:39:28 +00:00
break ;
case evGPS_2S :
if ( configuration_ - > property ( " Channels_1C.count " , 0 ) > 0 )
2018-06-14 21:10:43 +00:00
{
2019-07-20 00:53:31 +00:00
// 1. Get the current channel status map
2019-07-11 16:39:28 +00:00
std : : map < int , std : : shared_ptr < Gnss_Synchro > > current_channels_status = channels_status_ - > get_current_status_map ( ) ;
2019-07-20 00:53:31 +00:00
// 2. search the currently tracked GPS L1 satellites and assist the GPS L2 acquisition if the satellite is not tracked on L2
2019-07-21 10:55:59 +00:00
for ( auto & current_status : current_channels_status )
2018-06-14 21:10:43 +00:00
{
2019-07-21 10:55:59 +00:00
if ( std : : string ( current_status . second - > Signal ) = = " 1C " )
2018-06-14 21:10:43 +00:00
{
2019-07-11 16:39:28 +00:00
std : : list < Gnss_Signal > : : iterator it2 ;
it2 = std : : find_if ( std : : begin ( available_GPS_2S_signals_ ) , std : : end ( available_GPS_2S_signals_ ) ,
2019-07-21 10:55:59 +00:00
[ & ] ( Gnss_Signal const & sig ) { return sig . get_satellite ( ) . get_PRN ( ) = = current_status . second - > PRN ; } ) ;
2019-07-11 16:39:28 +00:00
if ( it2 ! = available_GPS_2S_signals_ . end ( ) )
2019-02-11 20:13:02 +00:00
{
2020-07-09 22:37:55 +00:00
estimated_doppler = static_cast < float > ( current_status . second - > Carrier_Doppler_hz ) ;
2019-07-21 10:55:59 +00:00
RX_time = current_status . second - > RX_time ;
2019-07-20 00:53:31 +00:00
// 3. return the GPS L2 satellite and remove it from list
2019-07-11 16:39:28 +00:00
result = * it2 ;
if ( pop )
{
available_GPS_2S_signals_ . erase ( it2 ) ;
}
2019-07-16 15:41:12 +00:00
found_signal = true ;
2019-07-19 16:49:42 +00:00
assistance_available = true ;
2019-07-11 16:39:28 +00:00
break ;
2019-02-11 20:13:02 +00:00
}
2018-06-14 21:10:43 +00:00
}
2019-07-11 16:39:28 +00:00
}
2019-07-20 00:53:31 +00:00
// fallback: pick the front satellite because there is no tracked satellites in L1 to assist L2
2019-07-16 15:41:12 +00:00
if ( found_signal = = false )
2019-07-11 16:39:28 +00:00
{
2019-07-16 15:41:12 +00:00
result = available_GPS_2S_signals_ . front ( ) ;
available_GPS_2S_signals_ . pop_front ( ) ;
if ( ! pop )
{
available_GPS_2S_signals_ . push_back ( result ) ;
}
2018-06-14 21:10:43 +00:00
}
}
2019-07-11 16:39:28 +00:00
else
2018-06-14 21:10:43 +00:00
{
2019-07-11 16:39:28 +00:00
result = available_GPS_2S_signals_ . front ( ) ;
available_GPS_2S_signals_ . pop_front ( ) ;
if ( ! pop )
2018-06-14 21:10:43 +00:00
{
2019-07-11 16:39:28 +00:00
available_GPS_2S_signals_ . push_back ( result ) ;
2018-06-14 21:10:43 +00:00
}
}
break ;
case evGPS_L5 :
2019-07-11 16:39:28 +00:00
if ( configuration_ - > property ( " Channels_1C.count " , 0 ) > 0 )
2018-06-14 21:10:43 +00:00
{
2019-07-20 00:53:31 +00:00
// 1. Get the current channel status map
2019-07-11 16:39:28 +00:00
std : : map < int , std : : shared_ptr < Gnss_Synchro > > current_channels_status = channels_status_ - > get_current_status_map ( ) ;
2019-07-20 00:53:31 +00:00
// 2. search the currently tracked GPS L1 satellites and assist the GPS L5 acquisition if the satellite is not tracked on L5
2019-07-21 10:55:59 +00:00
for ( auto & current_status : current_channels_status )
2018-06-14 21:10:43 +00:00
{
2019-07-21 10:55:59 +00:00
if ( std : : string ( current_status . second - > Signal ) = = " 1C " )
2018-06-14 21:10:43 +00:00
{
2019-07-11 16:39:28 +00:00
std : : list < Gnss_Signal > : : iterator it2 ;
it2 = std : : find_if ( std : : begin ( available_GPS_L5_signals_ ) , std : : end ( available_GPS_L5_signals_ ) ,
2019-07-21 10:55:59 +00:00
[ & ] ( Gnss_Signal const & sig ) { return sig . get_satellite ( ) . get_PRN ( ) = = current_status . second - > PRN ; } ) ;
2019-07-11 16:39:28 +00:00
if ( it2 ! = available_GPS_L5_signals_ . end ( ) )
2019-02-11 20:13:02 +00:00
{
2020-07-09 22:37:55 +00:00
estimated_doppler = static_cast < float > ( current_status . second - > Carrier_Doppler_hz ) ;
2019-07-21 10:55:59 +00:00
RX_time = current_status . second - > RX_time ;
2019-07-20 00:53:31 +00:00
// std::cout << " Channel: " << it->first << " => Doppler: " << estimated_doppler << "[Hz] \n";
// 3. return the GPS L5 satellite and remove it from list
2019-07-11 16:39:28 +00:00
result = * it2 ;
if ( pop )
{
available_GPS_L5_signals_ . erase ( it2 ) ;
}
2019-07-16 15:41:12 +00:00
found_signal = true ;
2019-07-19 16:49:42 +00:00
assistance_available = true ;
2019-07-11 16:39:28 +00:00
break ;
2019-02-11 20:13:02 +00:00
}
2018-06-14 21:10:43 +00:00
}
2019-07-11 16:39:28 +00:00
}
}
2019-07-20 00:53:31 +00:00
// fallback: pick the front satellite because there is no tracked satellites in L1 to assist L5
2019-07-16 15:41:12 +00:00
if ( found_signal = = false )
2019-07-11 16:39:28 +00:00
{
result = available_GPS_L5_signals_ . front ( ) ;
available_GPS_L5_signals_ . pop_front ( ) ;
if ( ! pop )
{
available_GPS_L5_signals_ . push_back ( result ) ;
2018-06-14 21:10:43 +00:00
}
}
break ;
case evGAL_1B :
result = available_GAL_1B_signals_ . front ( ) ;
2018-07-08 11:30:49 +00:00
available_GAL_1B_signals_ . pop_front ( ) ;
if ( ! pop )
2018-06-14 21:10:43 +00:00
{
2018-07-08 11:30:49 +00:00
available_GAL_1B_signals_ . push_back ( result ) ;
2018-06-14 21:10:43 +00:00
}
2019-07-20 00:53:31 +00:00
is_primary_frequency = true ; // indicate that the searched satellite signal belongs to "primary" link (L1, E1, B1, etc..)
2018-06-14 21:10:43 +00:00
break ;
case evGAL_5X :
2019-07-19 16:49:42 +00:00
if ( configuration_ - > property ( " Channels_1B.count " , 0 ) > 0 )
2018-06-14 21:10:43 +00:00
{
2019-07-20 00:53:31 +00:00
// 1. Get the current channel status map
2019-07-19 16:49:42 +00:00
std : : map < int , std : : shared_ptr < Gnss_Synchro > > current_channels_status = channels_status_ - > get_current_status_map ( ) ;
2019-07-20 00:53:31 +00:00
// 2. search the currently tracked Galileo E1 satellites and assist the Galileo E5 acquisition if the satellite is not tracked on E5
2019-07-21 10:55:59 +00:00
for ( auto & current_status : current_channels_status )
2019-07-19 16:49:42 +00:00
{
2019-07-21 10:55:59 +00:00
if ( std : : string ( current_status . second - > Signal ) = = " 1B " )
2019-07-19 16:49:42 +00:00
{
std : : list < Gnss_Signal > : : iterator it2 ;
it2 = std : : find_if ( std : : begin ( available_GAL_5X_signals_ ) , std : : end ( available_GAL_5X_signals_ ) ,
2019-07-21 10:55:59 +00:00
[ & ] ( Gnss_Signal const & sig ) { return sig . get_satellite ( ) . get_PRN ( ) = = current_status . second - > PRN ; } ) ;
2019-07-19 16:49:42 +00:00
if ( it2 ! = available_GAL_5X_signals_ . end ( ) )
{
2020-07-09 22:37:55 +00:00
estimated_doppler = static_cast < float > ( current_status . second - > Carrier_Doppler_hz ) ;
2019-07-21 10:55:59 +00:00
RX_time = current_status . second - > RX_time ;
2019-07-20 00:53:31 +00:00
// std::cout << " Channel: " << it->first << " => Doppler: " << estimated_doppler << "[Hz] \n";
// 3. return the Gal 5X satellite and remove it from list
2019-07-19 16:49:42 +00:00
result = * it2 ;
if ( pop )
{
available_GAL_5X_signals_ . erase ( it2 ) ;
}
found_signal = true ;
assistance_available = true ;
break ;
}
}
}
}
2019-07-20 00:53:31 +00:00
// fallback: pick the front satellite because there is no tracked satellites in E1 to assist E5
2019-07-19 16:49:42 +00:00
if ( found_signal = = false )
{
result = available_GAL_5X_signals_ . front ( ) ;
available_GAL_5X_signals_ . pop_front ( ) ;
if ( ! pop )
{
available_GAL_5X_signals_ . push_back ( result ) ;
}
2018-06-14 21:10:43 +00:00
}
break ;
case evGLO_1G :
result = available_GLO_1G_signals_ . front ( ) ;
2018-07-08 11:30:49 +00:00
available_GLO_1G_signals_ . pop_front ( ) ;
if ( ! pop )
2018-06-14 21:10:43 +00:00
{
2018-07-08 11:30:49 +00:00
available_GLO_1G_signals_ . push_back ( result ) ;
2018-06-14 21:10:43 +00:00
}
2019-07-20 00:53:31 +00:00
is_primary_frequency = true ; // indicate that the searched satellite signal belongs to "primary" link (L1, E1, B1, etc..)
2018-06-14 21:10:43 +00:00
break ;
case evGLO_2G :
result = available_GLO_2G_signals_ . front ( ) ;
2018-07-08 11:30:49 +00:00
available_GLO_2G_signals_ . pop_front ( ) ;
if ( ! pop )
2018-06-14 21:10:43 +00:00
{
2018-07-08 11:30:49 +00:00
available_GLO_2G_signals_ . push_back ( result ) ;
2018-06-14 21:10:43 +00:00
}
break ;
2018-10-22 19:16:38 +00:00
case evBDS_B1 :
result = available_BDS_B1_signals_ . front ( ) ;
available_BDS_B1_signals_ . pop_front ( ) ;
if ( ! pop )
{
available_BDS_B1_signals_ . push_back ( result ) ;
}
2019-07-20 00:53:31 +00:00
is_primary_frequency = true ; // indicate that the searched satellite signal belongs to "primary" link (L1, E1, B1, etc..)
2019-01-25 21:43:00 +00:00
break ;
case evBDS_B3 :
result = available_BDS_B3_signals_ . front ( ) ;
available_BDS_B3_signals_ . pop_front ( ) ;
if ( ! pop )
{
available_BDS_B3_signals_ . push_back ( result ) ;
}
2018-10-22 19:16:38 +00:00
break ;
2018-06-14 21:10:43 +00:00
default :
LOG ( ERROR ) < < " This should not happen :-( " ;
result = available_GPS_1C_signals_ . front ( ) ;
2019-03-18 07:43:38 +00:00
if ( pop )
{
2018-06-14 21:10:43 +00:00
available_GPS_1C_signals_ . pop_front ( ) ;
}
break ;
2018-03-03 01:03:39 +00:00
}
2018-01-05 10:50:52 +00:00
return result ;
}