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
*
2020-07-28 14:57:15 +00:00
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2011-10-01 18:45:20 +00:00
*
2020-12-30 12:35:06 +00:00
* GNSS - SDR is a Global Navigation Satellite System software - defined receiver .
2011-10-01 18:45:20 +00:00
* This file is part of GNSS - SDR .
*
2020-12-30 12:35:06 +00:00
* Copyright ( C ) 2010 - 2020 ( see AUTHORS file for a list of contributors )
2020-02-08 00:20:02 +00:00
* SPDX - License - Identifier : GPL - 3.0 - or - later
2011-10-01 18:45:20 +00:00
*
2020-07-28 14:57:15 +00:00
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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"
2020-06-14 15:48:36 +00:00
# include "Galileo_E5b.h"
2020-11-07 20:33:26 +00:00
# include "Galileo_E6.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"
2021-02-09 22:47:34 +00:00
# include "signal_source_interface.h"
2019-03-05 07:59:04 +00:00
# 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
2021-01-22 16:32:37 +00:00
void GNSSFlowgraph : : init ( )
{
/*
* Instantiates the receiver blocks
*/
auto block_factory = std : : make_unique < GNSSBlockFactory > ( ) ;
channels_status_ = channel_status_msg_receiver_make ( ) ;
// 1. read the number of RF front-ends available (one file_source per RF front-end)
sources_count_ = configuration_ - > property ( " Receiver.sources_count " , 1 ) ;
int signal_conditioner_ID = 0 ;
2021-02-09 22:47:34 +00:00
for ( int i = 0 ; i < sources_count_ ; i + + )
2021-01-22 16:32:37 +00:00
{
2021-02-09 22:47:34 +00:00
std : : cout < < " Creating source " < < i < < ' \n ' ;
sig_source_ . push_back ( block_factory - > GetSignalSource ( configuration_ . get ( ) , queue_ . get ( ) , i ) ) ;
auto & src = sig_source_ . back ( ) ;
auto RF_Channels = src - > getRfChannels ( ) ;
std : : cout < < " RF Channels " < < RF_Channels < < ' \n ' ;
for ( int j = 0 ; j < RF_Channels ; j + + )
2021-01-24 00:49:16 +00:00
{
2021-02-09 22:47:34 +00:00
sig_conditioner_ . push_back ( block_factory - > GetSignalConditioner ( configuration_ . get ( ) , signal_conditioner_ID ) ) ;
signal_conditioner_ID + + ;
2021-01-22 16:32:37 +00:00
}
}
signal_conditioner_connected_ = std : : vector < bool > ( sig_conditioner_ . size ( ) , false ) ;
observables_ = block_factory - > GetObservables ( configuration_ . get ( ) ) ;
pvt_ = block_factory - > GetPVT ( configuration_ . get ( ) ) ;
auto channels = block_factory - > GetChannels ( configuration_ . get ( ) , queue_ . get ( ) ) ;
channels_count_ = static_cast < int > ( channels - > size ( ) ) ;
for ( int i = 0 ; i < channels_count_ ; i + + )
{
std : : shared_ptr < GNSSBlockInterface > chan_ = std : : move ( channels - > at ( i ) ) ;
channels_ . push_back ( std : : dynamic_pointer_cast < ChannelInterface > ( chan_ ) ) ;
}
top_block_ = gr : : make_top_block ( " GNSSFlowgraph " ) ;
mapStringValues_ [ " 1C " ] = evGPS_1C ;
mapStringValues_ [ " 2S " ] = evGPS_2S ;
mapStringValues_ [ " L5 " ] = evGPS_L5 ;
mapStringValues_ [ " 1B " ] = evGAL_1B ;
mapStringValues_ [ " 5X " ] = evGAL_5X ;
mapStringValues_ [ " 7X " ] = evGAL_7X ;
mapStringValues_ [ " E6 " ] = evGAL_E6 ;
mapStringValues_ [ " 1G " ] = evGLO_1G ;
mapStringValues_ [ " 2G " ] = evGLO_2G ;
mapStringValues_ [ " B1 " ] = evBDS_B1 ;
mapStringValues_ [ " B3 " ] = evBDS_B3 ;
// fill the signals queue with the satellites ID's to be searched by the acquisition
set_signals_list ( ) ;
set_channels_state ( ) ;
DLOG ( INFO ) < < " Blocks instantiated. " < < channels_count_ < < " channels. " ;
/*
* Instantiate the receiver monitor block , if required
*/
enable_monitor_ = configuration_ - > property ( " Monitor.enable_monitor " , false ) ;
if ( enable_monitor_ )
{
// Retrieve monitor properties
bool enable_protobuf = configuration_ - > property ( " Monitor.enable_protobuf " , true ) ;
if ( configuration_ - > property ( " PVT.enable_protobuf " , false ) = = true )
{
enable_protobuf = true ;
}
std : : string address_string = configuration_ - > property ( " Monitor.client_addresses " , std : : string ( " 127.0.0.1 " ) ) ;
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 ( ) ) ;
// Instantiate monitor object
GnssSynchroMonitor_ = gnss_synchro_make_monitor ( channels_count_ ,
configuration_ - > property ( " Monitor.decimation_factor " , 1 ) ,
configuration_ - > property ( " Monitor.udp_port " , 1234 ) ,
udp_addr_vec , enable_protobuf ) ;
}
/*
* Instantiate the receiver acquisition monitor block , if required
*/
enable_acquisition_monitor_ = configuration_ - > property ( " AcquisitionMonitor.enable_monitor " , false ) ;
if ( enable_acquisition_monitor_ )
{
// Retrieve monitor properties
bool enable_protobuf = configuration_ - > property ( " AcquisitionMonitor.enable_protobuf " , true ) ;
if ( configuration_ - > property ( " PVT.enable_protobuf " , false ) = = true )
{
enable_protobuf = true ;
}
std : : string address_string = configuration_ - > property ( " AcquisitionMonitor.client_addresses " , std : : string ( " 127.0.0.1 " ) ) ;
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 ( ) ) ;
GnssSynchroAcquisitionMonitor_ = gnss_synchro_make_monitor ( channels_count_ ,
configuration_ - > property ( " AcquisitionMonitor.decimation_factor " , 1 ) ,
configuration_ - > property ( " AcquisitionMonitor.udp_port " , 1235 ) ,
udp_addr_vec , enable_protobuf ) ;
}
/*
* Instantiate the receiver tracking monitor block , if required
*/
enable_tracking_monitor_ = configuration_ - > property ( " TrackingMonitor.enable_monitor " , false ) ;
if ( enable_tracking_monitor_ )
{
// Retrieve monitor properties
bool enable_protobuf = configuration_ - > property ( " TrackingMonitor.enable_protobuf " , true ) ;
if ( configuration_ - > property ( " PVT.enable_protobuf " , false ) = = true )
{
enable_protobuf = true ;
}
std : : string address_string = configuration_ - > property ( " TrackingMonitor.client_addresses " , std : : string ( " 127.0.0.1 " ) ) ;
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 ( ) ) ;
GnssSynchroTrackingMonitor_ = gnss_synchro_make_monitor ( channels_count_ ,
configuration_ - > property ( " TrackingMonitor.decimation_factor " , 1 ) ,
configuration_ - > property ( " TrackingMonitor.udp_port " , 1236 ) ,
udp_addr_vec , enable_protobuf ) ;
}
}
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 )
{
2021-01-22 16:32:37 +00:00
LOG ( ERROR ) < < " Unable to start flowgraph: " < < e . what ( ) ;
2021-01-24 00:49:16 +00:00
print_help ( ) ;
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
2021-01-22 16:32:37 +00:00
# if ENABLE_FPGA
2020-09-10 09:57:50 +00:00
// start the DMA if the receiver is in post-processing mode
if ( configuration_ - > property ( sig_source_ . at ( 0 ) - > role ( ) + " .switch_position " , 0 ) = = 0 )
{
sig_source_ . at ( 0 ) - > start ( ) ;
}
2020-09-09 08:34:23 +00:00
# endif
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 ( ) ;
2021-01-22 16:32:37 +00:00
# if ENABLE_FPGA
# else
2020-08-06 09:45:27 +00:00
top_block_ - > wait ( ) ;
2020-08-13 19:19:17 +00:00
# endif
2012-04-14 18:04:27 +00:00
running_ = false ;
2011-10-01 18:45:20 +00:00
}
2021-01-22 16:32:37 +00:00
void GNSSFlowgraph : : wait ( )
{
if ( ! running_ )
{
LOG ( WARNING ) < < " Can't apply wait. Flowgraph is not running " ;
return ;
}
top_block_ - > wait ( ) ;
DLOG ( INFO ) < < " Flowgraph finished calculations " ;
running_ = false ;
}
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
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 ;
}
2021-01-22 16:32:37 +00:00
# if ENABLE_FPGA
if ( connect_fpga_flowgraph ( ) ! = 0 )
2015-02-27 17:21:25 +00:00
{
2021-01-24 00:49:16 +00:00
LOG ( ERROR ) < < " Unable to connect flowgraph with FPFA off-loading " ;
print_help ( ) ;
2021-01-22 16:32:37 +00:00
return ;
2015-02-27 17:21:25 +00:00
}
2021-01-22 16:32:37 +00:00
# else
if ( connect_desktop_flowgraph ( ) ! = 0 )
2015-02-27 17:21:25 +00:00
{
2021-01-24 00:49:16 +00:00
LOG ( ERROR ) < < " Unable to connect flowgraph " ;
print_help ( ) ;
2021-01-22 16:32:37 +00:00
return ;
2015-02-27 17:21:25 +00:00
}
2019-02-13 16:48:14 +00:00
# endif
2021-01-22 16:32:37 +00:00
connected_ = true ;
LOG ( INFO ) < < " Flowgraph connected " ;
top_block_ - > dump ( ) ;
}
void GNSSFlowgraph : : disconnect ( )
{
LOG ( INFO ) < < " Disconnecting flowgraph " ;
if ( ! connected_ )
2017-05-05 14:37:29 +00:00
{
2021-01-24 00:49:16 +00:00
LOG ( INFO ) < < " Flowgraph was not connected " ;
2021-01-22 16:32:37 +00:00
return ;
2017-05-05 14:37:29 +00:00
}
2021-01-22 16:32:37 +00:00
connected_ = false ;
2012-04-14 18:04:27 +00:00
2021-01-22 16:32:37 +00:00
# if ENABLE_FPGA
if ( disconnect_fpga_flowgraph ( ) ! = 0 )
2018-03-03 01:03:39 +00:00
{
2021-01-22 16:32:37 +00:00
return ;
2018-03-03 01:03:39 +00:00
}
2021-01-22 16:32:37 +00:00
# else
if ( disconnect_desktop_flowgraph ( ) ! = 0 )
2018-03-03 01:03:39 +00:00
{
2012-04-14 18:04:27 +00:00
return ;
2018-03-03 01:03:39 +00:00
}
2021-01-22 16:32:37 +00:00
# endif
2012-04-14 18:04:27 +00:00
2021-01-22 16:32:37 +00:00
LOG ( INFO ) < < " Flowgraph disconnected " ;
}
int GNSSFlowgraph : : connect_desktop_flowgraph ( )
{
# if ENABLE_FPGA
return 0 ;
# else
// Connect blocks to the top_block
if ( connect_signal_sources ( ) ! = 0 )
2018-03-03 01:03:39 +00:00
{
2021-01-22 16:32:37 +00:00
return 1 ;
2018-03-03 01:03:39 +00:00
}
2021-01-22 16:32:37 +00:00
if ( connect_signal_conditioners ( ) ! = 0 )
2018-03-03 01:03:39 +00:00
{
2021-01-22 16:32:37 +00:00
return 1 ;
2018-03-03 01:03:39 +00:00
}
2012-04-14 18:04:27 +00:00
2021-01-22 16:32:37 +00:00
if ( connect_channels ( ) ! = 0 )
2015-02-27 17:21:25 +00:00
{
2021-01-22 16:32:37 +00:00
return 1 ;
}
2019-02-27 16:27:31 +00:00
2021-01-22 16:32:37 +00:00
if ( connect_observables ( ) ! = 0 )
{
return 1 ;
}
2015-04-24 17:11:45 +00:00
2021-01-22 16:32:37 +00:00
if ( connect_pvt ( ) ! = 0 )
{
return 1 ;
}
// Connect blocks between them to form the flow graph
if ( connect_signal_sources_to_signal_conditioners ( ) ! = 0 )
{
return 1 ;
}
if ( connect_sample_counter ( ) ! = 0 )
{
return 1 ;
}
if ( connect_signal_conditioners_to_channels ( ) ! = 0 )
{
return 1 ;
}
if ( connect_channels_to_observables ( ) ! = 0 )
{
return 1 ;
}
check_signal_conditioners ( ) ;
assign_channels ( ) ;
if ( connect_observables_to_pvt ( ) ! = 0 )
{
return 1 ;
}
if ( connect_monitors ( ) ! = 0 )
{
return 1 ;
}
// Activate acquisition in enabled channels
for ( int i = 0 ; i < channels_count_ ; i + + )
{
LOG ( INFO ) < < " Channel " < < i < < " assigned to " < < channels_ . at ( i ) - > get_signal ( ) ;
if ( channels_state_ [ i ] = = 1 )
{
channels_ . at ( i ) - > start_acquisition ( ) ;
LOG ( INFO ) < < " Channel " < < i < < " connected to observables and ready for acquisition " ;
2019-02-27 16:27:31 +00:00
}
2021-01-22 16:32:37 +00:00
else
2019-02-27 16:27:31 +00:00
{
2021-01-22 16:32:37 +00:00
LOG ( INFO ) < < " Channel " < < i < < " connected to observables in standby mode " ;
2018-04-13 13:27:14 +00:00
}
}
2021-01-22 16:32:37 +00:00
LOG ( INFO ) < < " The GNU Radio flowgraph for the current GNSS-SDR configuration has been successfully connected " ;
return 0 ;
2019-02-13 16:48:14 +00:00
# endif
2021-01-22 16:32:37 +00:00
}
2018-04-13 13:27:14 +00:00
2021-01-22 16:32:37 +00:00
int GNSSFlowgraph : : disconnect_desktop_flowgraph ( )
{
2018-04-13 13:27:14 +00:00
# if ENABLE_FPGA
2021-01-22 16:32:37 +00:00
return 0 ;
# else
// Disconnect blocks between them
if ( disconnect_signal_sources_from_signal_conditioners ( ) ! = 0 )
{
return 1 ;
}
if ( disconnect_sample_counter ( ) ! = 0 )
{
return 1 ;
}
if ( disconnect_signal_conditioners_from_channels ( ) ! = 0 )
{
return 1 ;
}
if ( disconnect_channels_from_observables ( ) ! = 0 )
{
return 1 ;
}
if ( disconnect_monitors ( ) ! = 0 )
{
return 1 ;
}
if ( disconnect_observables_from_pvt ( ) ! = 0 )
{
return 1 ;
}
// Disconnect blocks from the top_block
if ( disconnect_signal_sources ( ) ! = 0 )
{
return 1 ;
}
if ( disconnect_signal_conditioners ( ) ! = 0 )
{
return 1 ;
}
if ( disconnect_channels ( ) ! = 0 )
{
return 1 ;
}
if ( disconnect_observables ( ) ! = 0 )
{
return 1 ;
}
if ( disconnect_pvt ( ) ! = 0 )
{
return 1 ;
}
return 0 ;
# endif
}
# if ENABLE_FPGA
int GNSSFlowgraph : : connect_fpga_flowgraph ( )
{
// Connect blocks to the top_block
if ( connect_channels ( ) ! = 0 )
{
return 1 ;
}
if ( connect_observables ( ) ! = 0 )
{
return 1 ;
}
if ( connect_pvt ( ) ! = 0 )
{
return 1 ;
}
DLOG ( INFO ) < < " Blocks connected internally to the top_block " ;
// Connect the counter
2021-01-24 00:49:16 +00:00
if ( sig_source_ . at ( 0 ) ! = nullptr )
2021-01-22 16:32:37 +00:00
{
2021-01-24 00:49:16 +00:00
if ( configuration_ - > property ( sig_source_ . at ( 0 ) - > role ( ) + " .enable_FPGA " , false ) = = false )
2021-01-22 16:32:37 +00:00
{
2021-01-24 00:49:16 +00:00
if ( connect_sample_counter ( ) ! = 0 )
{
return 1 ;
}
}
else
{
if ( connect_fpga_sample_counter ( ) ! = 0 )
{
return 1 ;
}
2021-01-22 16:32:37 +00:00
}
}
else
{
2021-01-24 00:49:16 +00:00
help_hint_ + = " * Check implementation name for SignalSource block \n " ;
help_hint_ + = " Signal Source block implementation for FPGA off-loading should be 'Ad9361_Fpga_Signal_Source' \n " ;
return 1 ;
2021-01-22 16:32:37 +00:00
}
if ( connect_channels_to_observables ( ) ! = 0 )
{
return 1 ;
}
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
{
2021-01-22 16:32:37 +00:00
check_signal_conditioners ( ) ;
}
assign_channels ( ) ;
if ( connect_observables_to_pvt ( ) ! = 0 )
{
return 1 ;
}
if ( connect_monitors ( ) ! = 0 )
{
return 1 ;
}
2021-01-24 00:49:16 +00:00
check_desktop_conf_in_fpga_env ( ) ;
2021-01-22 16:32:37 +00:00
LOG ( INFO ) < < " The GNU Radio flowgraph for the current GNSS-SDR configuration with FPGA off-loading has been successfully connected " ;
return 0 ;
}
int GNSSFlowgraph : : disconnect_fpga_flowgraph ( )
{
if ( configuration_ - > property ( sig_source_ . at ( 0 ) - > role ( ) + " .enable_FPGA " , false ) = = false )
{
if ( disconnect_signal_sources_from_signal_conditioners ( ) ! = 0 )
{
return 1 ;
}
}
if ( configuration_ - > property ( sig_source_ . at ( 0 ) - > role ( ) + " .enable_FPGA " , false ) = = false )
{
if ( disconnect_sample_counter ( ) ! = 0 )
{
return 1 ;
}
}
else
{
if ( disconnect_fpga_sample_counter ( ) ! = 0 )
{
return 1 ;
}
}
if ( disconnect_monitors ( ) ! = 0 )
{
return 1 ;
}
if ( disconnect_channels_from_observables ( ) ! = 0 )
{
return 1 ;
}
if ( disconnect_observables_from_pvt ( ) ! = 0 )
{
return 1 ;
}
if ( disconnect_signal_sources ( ) ! = 0 )
{
return 1 ;
}
if ( disconnect_signal_conditioners ( ) ! = 0 )
{
return 1 ;
}
if ( disconnect_channels ( ) ! = 0 )
{
return 1 ;
}
if ( disconnect_observables ( ) ! = 0 )
{
return 1 ;
}
if ( disconnect_pvt ( ) ! = 0 )
{
return 1 ;
}
return 0 ;
}
# endif
int GNSSFlowgraph : : connect_signal_sources ( )
{
for ( int i = 0 ; i < sources_count_ ; i + + )
{
2021-01-24 00:49:16 +00:00
if ( sig_source_ . at ( i ) ! = nullptr )
2018-04-13 13:27:14 +00:00
{
2021-01-24 00:49:16 +00:00
try
{
sig_source_ . at ( i ) - > connect ( top_block_ ) ;
}
catch ( const std : : exception & e )
{
LOG ( ERROR ) < < " Can't connect signal source block " < < i < < " internally: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
2018-03-03 01:03:39 +00:00
}
2021-01-24 00:49:16 +00:00
else
2018-03-03 01:03:39 +00:00
{
2021-01-24 00:49:16 +00:00
help_hint_ + = " * Check implementation name for SignalSource " + ( i = = 0 ? " " : ( std : : to_string ( i ) + " " ) ) + " block \n " ;
help_hint_ + = " Signal Source blocks documentation at https://gnss-sdr.org/docs/sp-blocks/signal-source/ \n " ;
2015-02-27 17:21:25 +00:00
top_block_ - > disconnect_all ( ) ;
2021-01-22 16:32:37 +00:00
return 1 ;
2018-03-03 01:03:39 +00:00
}
2015-02-27 17:21:25 +00:00
}
2021-01-22 16:32:37 +00:00
DLOG ( INFO ) < < " Signal Source blocks successfully connected to the top_block " ;
return 0 ;
}
int GNSSFlowgraph : : disconnect_signal_sources ( )
{
for ( int i = 0 ; i < sources_count_ ; i + + )
2012-04-14 18:04:27 +00:00
{
2015-02-27 17:21:25 +00:00
try
2018-03-03 01:03:39 +00:00
{
2021-01-22 16:32:37 +00:00
sig_source_ . at ( i ) - > disconnect ( top_block_ ) ;
2018-03-03 01:03:39 +00:00
}
catch ( const std : : exception & e )
{
2021-01-22 16:32:37 +00:00
LOG ( INFO ) < < " Can't disconnect signal source block " < < i < < " internally: " < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
top_block_ - > disconnect_all ( ) ;
2021-01-22 16:32:37 +00:00
return 1 ;
2018-03-03 01:03:39 +00:00
}
2018-04-13 13:27:14 +00:00
}
2021-01-22 16:32:37 +00:00
return 0 ;
}
2021-01-24 00:49:16 +00:00
int GNSSFlowgraph : : connect_signal_conditioners ( )
2021-01-22 16:32:37 +00:00
{
2021-01-24 00:49:16 +00:00
for ( auto & sig : sig_conditioner_ )
2021-01-22 16:32:37 +00:00
{
try
{
2021-01-24 00:49:16 +00:00
sig - > connect ( top_block_ ) ;
2021-01-22 16:32:37 +00:00
}
catch ( const std : : exception & e )
{
2021-01-24 00:49:16 +00:00
LOG ( ERROR ) < < " Can't connect signal conditioner block internally: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
std : : string reported_error ( e . what ( ) ) ;
if ( std : : string : : npos ! = reported_error . find ( std : : string ( " itemsize mismatch " ) ) )
{
std : : string replace_me ( " copy " ) ;
size_t pos = reported_error . find ( replace_me ) ;
2021-01-26 15:11:41 +00:00
while ( pos ! = std : : string : : npos )
{
size_t len = replace_me . length ( ) ;
reported_error . replace ( pos , len , " Pass_Through " ) ;
pos = reported_error . find ( replace_me , pos + 1 ) ;
}
help_hint_ + = " * Blocks within the Signal Conditioner are connected with mismatched input/ouput item size \n " ;
2021-01-24 00:49:16 +00:00
help_hint_ + = " Reported error: " + reported_error + ' \n ' ;
help_hint_ + = " Check the Signal Conditioner documentation at https://gnss-sdr.org/docs/sp-blocks/signal-conditioner/ \n " ;
}
if ( std : : string : : npos ! = reported_error . find ( std : : string ( " DataTypeAdapter " ) ) )
{
help_hint_ + = " * The DataTypeAdapter implementation set in the configuration file does not exist \n " ;
help_hint_ + = " Check the DataTypeAdapter documentation at https://gnss-sdr.org/docs/sp-blocks/data-type-adapter/ \n " ;
}
if ( std : : string : : npos ! = reported_error . find ( std : : string ( " InputFilter " ) ) )
{
2021-01-26 22:11:06 +00:00
if ( std : : string : : npos ! = reported_error . find ( std : : string ( " itemsize mismatch " ) ) )
{
help_hint_ + = " * The configured InputFilter input/output item types are not well defined. \n " ;
}
else
{
help_hint_ + = " * The InputFilter implementation set in the configuration file does not exist \n " ;
}
2021-01-24 00:49:16 +00:00
help_hint_ + = " Check the InputFilter documentation at https://gnss-sdr.org/docs/sp-blocks/input-filter/ \n " ;
}
if ( std : : string : : npos ! = reported_error . find ( std : : string ( " Resampler " ) ) )
{
2021-01-26 22:11:06 +00:00
if ( std : : string : : npos ! = reported_error . find ( std : : string ( " itemsize mismatch " ) ) )
{
help_hint_ + = " * The configured Resampler item type is not well defined. \n " ;
}
else
{
help_hint_ + = " * The Resampler implementation set in the configuration file does not exist \n " ;
}
2021-01-24 00:49:16 +00:00
help_hint_ + = " Check the Resampler documentation at https://gnss-sdr.org/docs/sp-blocks/resampler/ \n " ;
}
return 1 ;
}
}
DLOG ( INFO ) < < " Signal Conditioner blocks successfully connected to the top_block " ;
return 0 ;
}
int GNSSFlowgraph : : disconnect_signal_conditioners ( )
{
for ( auto & sig : sig_conditioner_ )
{
try
{
sig - > disconnect ( top_block_ ) ;
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect signal conditioner block internally: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
}
return 0 ;
}
int GNSSFlowgraph : : connect_channels ( )
{
for ( int i = 0 ; i < channels_count_ ; i + + )
{
if ( channels_ . at ( i ) ! = nullptr )
{
try
{
channels_ . at ( i ) - > connect ( top_block_ ) ;
}
catch ( const std : : exception & e )
{
LOG ( ERROR ) < < " Can't connect channel " < < i < < " internally: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
}
else
{
LOG ( ERROR ) < < " Can't connect channel " < < i < < " internally " ;
2021-01-26 13:01:28 +00:00
help_hint_ + = " * Check your configuration for Channel " + std : : to_string ( i ) + " inner blocks. \n " ;
2021-01-24 00:49:16 +00:00
help_hint_ + = " Acquisition blocks documentation at https://gnss-sdr.org/docs/sp-blocks/acquisition/ \n " ;
help_hint_ + = " Tracking blocks documentation at https://gnss-sdr.org/docs/sp-blocks/tracking/ \n " ;
help_hint_ + = " Telemetry Decoder blocks documentation at https://gnss-sdr.org/docs/sp-blocks/telemetry-decoder/ \n " ;
2021-01-22 16:32:37 +00:00
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
}
DLOG ( INFO ) < < " Channel blocks successfully connected to the top_block " ;
return 0 ;
}
int GNSSFlowgraph : : disconnect_channels ( )
{
for ( int i = 0 ; i < channels_count_ ; i + + )
{
try
{
channels_ . at ( i ) - > disconnect ( top_block_ ) ;
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect channel " < < i < < " internally: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
}
return 0 ;
}
int GNSSFlowgraph : : connect_observables ( )
{
2021-01-24 00:49:16 +00:00
if ( observables_ = = nullptr )
{
help_hint_ + = " * Check implementation name for the Observables block \n " ;
help_hint_ + = " Observables block documentation at https://gnss-sdr.org/docs/sp-blocks/observables/ \n " ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
2021-01-22 16:32:37 +00:00
try
{
observables_ - > connect ( top_block_ ) ;
}
catch ( const std : : exception & e )
{
LOG ( ERROR ) < < " Can't connect observables block internally: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
DLOG ( INFO ) < < " Observables block successfully connected to the top_block " ;
return 0 ;
}
int GNSSFlowgraph : : disconnect_observables ( )
{
try
{
observables_ - > disconnect ( top_block_ ) ;
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect observables block internally: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
return 0 ;
}
int GNSSFlowgraph : : connect_pvt ( )
{
2021-01-24 00:49:16 +00:00
if ( pvt_ = = nullptr )
{
help_hint_ + = " * Check implementation name for the PVT block \n " ;
help_hint_ + = " PVT block documentation at https://gnss-sdr.org/docs/sp-blocks/pvt/ \n " ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
2021-01-22 16:32:37 +00:00
try
{
pvt_ - > connect ( top_block_ ) ;
}
catch ( const std : : exception & e )
{
LOG ( ERROR ) < < " Can't connect PVT block internally: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
DLOG ( INFO ) < < " PVT block successfully connected to the top_block " ;
return 0 ;
}
int GNSSFlowgraph : : disconnect_pvt ( )
{
try
{
pvt_ - > disconnect ( top_block_ ) ;
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect PVT block internally: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
return 0 ;
}
int GNSSFlowgraph : : connect_sample_counter ( )
{
// connect the sample counter to the Signal Conditioner
2018-04-20 10:50:32 +00:00
// connect the sample counter to Observables
2018-04-13 13:27:14 +00:00
try
{
2020-07-19 23:20:15 +00:00
const double fs = static_cast < double > ( configuration_ - > property ( " GNSS-SDR.internal_fs_sps " , 0 ) ) ;
2018-04-13 13:27:14 +00:00
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-19 23:20:15 +00:00
const 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 )
{
2021-01-22 16:32:37 +00:00
LOG ( ERROR ) < < " Can't connect sample counter: " < < e . what ( ) ;
2018-04-13 13:27:14 +00:00
top_block_ - > disconnect_all ( ) ;
2021-01-22 16:32:37 +00:00
return 1 ;
}
DLOG ( INFO ) < < " sample counter successfully connected to Signal Conditioner and Observables blocks " ;
return 0 ;
}
int GNSSFlowgraph : : disconnect_sample_counter ( )
{
try
{
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
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect sample counter: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
return 0 ;
}
2021-01-24 00:49:16 +00:00
2021-01-22 16:32:37 +00:00
# if ENABLE_FPGA
int GNSSFlowgraph : : connect_fpga_sample_counter ( )
{
// create a hardware-defined gnss_synchro pulse for the observables block
try
{
const 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 " ;
std : : cout < < " Set GNSS-SDR.internal_fs_sps in configuration file \n " ;
throw ( std : : invalid_argument ( " Set GNSS-SDR.internal_fs_sps in configuration " ) ) ;
}
const int observable_interval_ms = configuration_ - > property ( " GNSS-SDR.observable_interval_ms " , 20 ) ;
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
}
catch ( const std : : exception & e )
{
LOG ( ERROR ) < < " Can't connect FPGA sample counter: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
LOG ( INFO ) < < " FPGA sample counter successfully connected " ;
return 0 ;
}
int GNSSFlowgraph : : disconnect_fpga_sample_counter ( )
{
try
{
top_block_ - > disconnect ( ch_out_fpga_sample_counter_ , 0 , observables_ - > get_left_block ( ) , channels_count_ ) ;
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect FPGA sample counter: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
return 0 ;
}
# endif
int GNSSFlowgraph : : connect_signal_sources_to_signal_conditioners ( )
{
unsigned int signal_conditioner_ID = 0 ;
for ( int i = 0 ; i < sources_count_ ; i + + )
{
try
{
2021-02-09 22:47:34 +00:00
auto & src = sig_source_ . at ( i ) ;
2021-01-22 16:32:37 +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)
2021-02-09 22:47:34 +00:00
if ( src - > implementation ( ) = = " Raw_Array_Signal_Source " )
2021-01-22 16:32:37 +00:00
{
// Multichannel Array
std : : cout < < " ARRAY MODE \n " ;
for ( int j = 0 ; j < GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS ; j + + )
{
std : : cout < < " connecting ch " < < j < < ' \n ' ;
2021-02-09 22:47:34 +00:00
top_block_ - > connect ( src - > get_right_block ( ) , j , sig_conditioner_ . at ( i ) - > get_left_block ( ) , j ) ;
2021-01-22 16:32:37 +00:00
}
}
else
{
2021-02-09 22:47:34 +00:00
auto RF_Channels = src - > getRfChannels ( ) ;
2021-01-22 16:32:37 +00:00
for ( int j = 0 ; j < RF_Channels ; j + + )
{
// Connect the multichannel signal source to multiple signal conditioners
// GNURADIO max_streams=-1 means infinite ports!
2021-02-09 22:47:34 +00:00
size_t output_size = src - > item_size ( ) ;
2021-01-24 00:49:16 +00:00
size_t input_size = sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) - > input_signature ( ) - > sizeof_stream_item ( 0 ) ;
2021-01-26 14:20:37 +00:00
// Check configuration inconsistencies
if ( output_size ! = input_size )
{
2021-02-09 22:47:34 +00:00
help_hint_ + = " * The Signal Source implementation " + src - > implementation ( ) + " has an output with a " ;
help_hint_ + = src - > role ( ) + " .item_size of " + std : : to_string ( output_size ) ;
2021-01-26 14:20:37 +00:00
help_hint_ + = " bytes, but it is connected to the Signal Conditioner implementation " ;
help_hint_ + = sig_conditioner_ . at ( signal_conditioner_ID ) - > implementation ( ) + " with input item size of " + std : : to_string ( input_size ) + " bytes. \n " ;
help_hint_ + = " Output ports must be connected to input ports with the same item size. \n " ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
2021-01-22 16:32:37 +00:00
2021-02-09 22:47:34 +00:00
if ( src - > get_right_block ( ) - > output_signature ( ) - > max_streams ( ) > 1 or src - > get_right_block ( ) - > output_signature ( ) - > max_streams ( ) = = - 1 )
2021-01-22 16:32:37 +00:00
{
if ( sig_conditioner_ . size ( ) > signal_conditioner_ID )
{
2021-02-09 22:47:34 +00:00
LOG ( INFO ) < < " connecting sig_source_ " < < i < < " stream " < < j < < " to conditioner " < < signal_conditioner_ID ;
top_block_ - > connect ( src - > get_right_block ( ) , j , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
2021-01-22 16:32:37 +00:00
}
}
else
{
if ( j = = 0 )
{
// RF_channel 0 backward compatibility with single channel sources
2021-02-09 22:47:34 +00:00
LOG ( INFO ) < < " connecting sig_source_ " < < i < < " stream " < < 0 < < " to conditioner " < < signal_conditioner_ID ;
top_block_ - > connect ( src - > get_right_block ( ) , 0 , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
2021-01-22 16:32:37 +00:00
}
else
{
// Multiple channel sources using multiple output blocks of single channel (requires RF_channel selector in call)
2021-02-09 22:47:34 +00:00
LOG ( INFO ) < < " connecting sig_source_ " < < i < < " stream " < < j < < " to conditioner " < < signal_conditioner_ID ;
top_block_ - > connect ( src - > get_right_block ( j ) , 0 , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
2021-01-22 16:32:37 +00:00
}
}
signal_conditioner_ID + + ;
}
}
}
catch ( const std : : exception & e )
{
2021-01-24 00:49:16 +00:00
LOG ( ERROR ) < < " Can't connect SignalSource " < < ( i = = 0 ? " " : ( std : : to_string ( i ) + " " ) ) < < " to SignalConditioner " < < ( i = = 0 ? " " : ( std : : to_string ( i ) + " " ) ) < < " : " < < e . what ( ) ;
std : : string reported_error ( e . what ( ) ) ;
if ( std : : string : : npos ! = reported_error . find ( std : : string ( " itemsize mismatch " ) ) )
{
std : : string replace_me ( " copy " ) ;
size_t pos = reported_error . find ( replace_me ) ;
2021-01-26 15:11:41 +00:00
while ( pos ! = std : : string : : npos )
{
size_t len = replace_me . length ( ) ;
reported_error . replace ( pos , len , " Pass_Through " ) ;
pos = reported_error . find ( replace_me , pos + 1 ) ;
}
2021-01-24 00:49:16 +00:00
help_hint_ + = " * The SignalSource output item size and the SignalConditioner input item size are mismatched \n " ;
help_hint_ + = " Reported error: " + reported_error + ' \n ' ;
}
2021-01-22 16:32:37 +00:00
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
2018-04-13 13:27:14 +00:00
}
2019-02-13 16:48:14 +00:00
2021-01-22 16:32:37 +00:00
DLOG ( INFO ) < < " Signal source(s) successfully connected to signal conditioner(s) " ;
return 0 ;
}
2021-01-24 00:49:16 +00:00
int GNSSFlowgraph : : disconnect_signal_sources_from_signal_conditioners ( )
{
int signal_conditioner_ID = 0 ;
for ( int i = 0 ; i < sources_count_ ; i + + )
{
try
{
2021-02-09 22:47:34 +00:00
auto & src = sig_source_ . at ( i ) ;
2021-01-24 00:49:16 +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)
2021-02-09 22:47:34 +00:00
if ( src - > implementation ( ) = = " Raw_Array_Signal_Source " )
2021-01-24 00:49:16 +00:00
{
// Multichannel Array
for ( int j = 0 ; j < GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS ; j + + )
{
2021-02-09 22:47:34 +00:00
top_block_ - > disconnect ( src - > get_right_block ( ) , j , sig_conditioner_ . at ( i ) - > get_left_block ( ) , j ) ;
2021-01-24 00:49:16 +00:00
}
}
else
{
2021-02-09 22:47:34 +00:00
auto RF_Channels = src - > getRfChannels ( ) ;
2021-01-24 00:49:16 +00:00
for ( int j = 0 ; j < RF_Channels ; j + + )
{
2021-02-09 22:47:34 +00:00
if ( src - > get_right_block ( ) - > output_signature ( ) - > max_streams ( ) > 1 or src - > get_right_block ( ) - > output_signature ( ) - > max_streams ( ) = = - 1 )
2021-01-24 00:49:16 +00:00
{
2021-02-09 22:47:34 +00:00
top_block_ - > disconnect ( src - > get_right_block ( ) , j , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
2021-01-24 00:49:16 +00:00
}
else
{
if ( j = = 0 )
{
// RF_channel 0 backward compatibility with single channel sources
2021-02-09 22:47:34 +00:00
top_block_ - > disconnect ( src - > get_right_block ( ) , 0 , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
2021-01-24 00:49:16 +00:00
}
else
{
// Multiple channel sources using multiple output blocks of single channel (requires RF_channel selector in call)
2021-02-09 22:47:34 +00:00
top_block_ - > disconnect ( src - > get_right_block ( j ) , 0 , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
2021-01-24 00:49:16 +00:00
}
}
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 1 ;
}
}
return 0 ;
}
2021-01-22 16:32:37 +00:00
int GNSSFlowgraph : : connect_signal_conditioners_to_channels ( )
{
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-03-02 10:22:42 +00:00
int selected_signal_conditioner_ID = 0 ;
2020-07-19 23:20:15 +00:00
const bool use_acq_resampler = configuration_ - > property ( " GNSS-SDR.use_acquisition_resampler " , false ) ;
const uint32_t fs = configuration_ - > property ( " GNSS-SDR.internal_fs_sps " , 0 ) ;
2021-01-22 16:32:37 +00:00
try
2018-04-13 13:27:14 +00:00
{
2021-01-22 16:32:37 +00:00
selected_signal_conditioner_ID = configuration_ - > property ( " Channel " + std : : to_string ( i ) + " .RF_channel_ID " , 0 ) ;
}
catch ( const std : : exception & e )
{
LOG ( WARNING ) < < e . what ( ) ;
}
try
{
// Enable automatic resampler for the acquisition, if required
if ( use_acq_resampler = = true )
2018-04-13 13:27:14 +00:00
{
2021-01-22 16:32:37 +00:00
// create acquisition resamplers if required
double resampler_ratio = 1.0 ;
double acq_fs = fs ;
// find the signal associated to this channel
switch ( mapStringValues_ [ channels_ . at ( i ) - > get_signal ( ) . get_signal_str ( ) ] )
{
case evGPS_1C :
acq_fs = GPS_L1_CA_OPT_ACQ_FS_SPS ;
break ;
case evGPS_2S :
acq_fs = GPS_L2C_OPT_ACQ_FS_SPS ;
break ;
case evGPS_L5 :
acq_fs = GPS_L5_OPT_ACQ_FS_SPS ;
break ;
case evSBAS_1C :
acq_fs = GPS_L1_CA_OPT_ACQ_FS_SPS ;
break ;
case evGAL_1B :
acq_fs = GALILEO_E1_OPT_ACQ_FS_SPS ;
break ;
case evGAL_5X :
acq_fs = GALILEO_E5A_OPT_ACQ_FS_SPS ;
break ;
case evGAL_7X :
acq_fs = GALILEO_E5B_OPT_ACQ_FS_SPS ;
break ;
case evGAL_E6 :
acq_fs = GALILEO_E6_OPT_ACQ_FS_SPS ;
break ;
case evGLO_1G :
case evGLO_2G :
case evBDS_B1 :
case evBDS_B3 :
acq_fs = fs ;
break ;
default :
break ;
}
if ( acq_fs < fs )
2018-12-03 16:58:18 +00:00
{
2021-01-22 16:32:37 +00:00
// check if the resampler is already created for the channel system/signal and for the specific RF Channel
const std : : string map_key = channels_ . at ( i ) - > get_signal ( ) . get_signal_str ( ) + std : : to_string ( selected_signal_conditioner_ID ) ;
resampler_ratio = static_cast < double > ( fs ) / acq_fs ;
int decimation = floor ( resampler_ratio ) ;
while ( fs % decimation > 0 )
2018-12-03 16:58:18 +00:00
{
2021-01-22 16:32:37 +00:00
decimation - - ;
} ;
const double acq_fs_decimated = static_cast < double > ( fs ) / static_cast < double > ( decimation ) ;
2018-12-05 15:50:32 +00:00
2021-01-22 16:32:37 +00:00
if ( decimation > 1 )
2018-12-03 16:58:18 +00:00
{
2021-01-22 16:32:37 +00:00
// create a FIR low pass filter
std : : vector < float > taps = gr : : filter : : firdes : : low_pass ( 1.0 ,
fs ,
acq_fs_decimated / 2.1 ,
acq_fs_decimated / 2 ) ;
2018-12-03 16:58:18 +00:00
2021-01-22 16:32:37 +00:00
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 )
2018-12-05 15:50:32 +00:00
{
2021-01-22 16:32:37 +00:00
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 ) - > get_signal ( ) . get_signal_str ( )
< < " acquisition resampler for RF channel " < < std : : to_string ( selected_signal_conditioner_ID ) < < " with " < < taps . size ( ) < < " taps and decimation factor of " < < decimation ;
2018-12-03 16:58:18 +00:00
}
else
{
2021-01-22 16:32:37 +00:00
LOG ( INFO ) < < " Found existing "
< < channels_ . at ( i ) - > get_signal ( ) . get_signal_str ( )
< < " acquisition resampler for RF channel " < < std : : to_string ( selected_signal_conditioner_ID ) < < " with " < < taps . size ( ) < < " taps and decimation factor of " < < decimation ;
2018-12-03 16:58:18 +00:00
}
2021-01-22 16:32:37 +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 = 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 " ;
2021-01-22 16:32:37 +00:00
// resampler not required!
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
{
2021-01-22 16:32:37 +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 ) ;
}
2018-04-13 13:27:14 +00:00
}
2021-01-22 16:32:37 +00:00
else
2018-04-13 13:27:14 +00:00
{
2021-01-22 16:32:37 +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-04-13 13:27:14 +00:00
}
2021-01-22 16:32:37 +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-03-03 01:03:39 +00:00
}
catch ( const std : : exception & e )
{
2021-01-22 16:32:37 +00:00
LOG ( ERROR ) < < " Can't connect signal conditioner " < < selected_signal_conditioner_ID < < " to channel " < < i < < " : " < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
top_block_ - > disconnect_all ( ) ;
2021-01-22 16:32:37 +00:00
return 1 ;
2018-03-03 01:03:39 +00:00
}
2014-04-12 20:02:18 +00:00
2021-01-22 16:32:37 +00:00
signal_conditioner_connected_ . at ( selected_signal_conditioner_ID ) = true ; // annotate that this signal conditioner is connected
2021-01-24 00:49:16 +00:00
DLOG ( INFO ) < < " Signal conditioner " < < selected_signal_conditioner_ID < < " successfully connected to channel " < < i ;
2019-03-29 16:36:05 +00:00
}
2021-01-22 16:32:37 +00:00
return 0 ;
}
2019-04-21 11:30:59 +00:00
2021-01-22 16:32:37 +00:00
int GNSSFlowgraph : : disconnect_signal_conditioners_from_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
{
2021-01-22 16:32:37 +00:00
int selected_signal_conditioner_ID ;
2018-05-01 21:32:52 +00:00
try
{
2021-01-22 16:32:37 +00:00
selected_signal_conditioner_ID = configuration_ - > property ( " Channel " + std : : to_string ( i ) + " .RF_channel_ID " , 0 ) ;
2018-05-01 21:32:52 +00:00
}
catch ( const std : : exception & e )
{
LOG ( WARNING ) < < e . what ( ) ;
2021-01-22 16:32:37 +00:00
top_block_ - > disconnect_all ( ) ;
return 1 ;
2018-05-01 21:32:52 +00:00
}
2021-01-22 16:32:37 +00:00
try
2018-04-20 10:50:32 +00:00
{
2021-01-22 16:32:37 +00:00
top_block_ - > disconnect ( sig_conditioner_ . at ( selected_signal_conditioner_ID ) - > get_right_block ( ) , 0 ,
channels_ . at ( i ) - > get_left_block_trk ( ) , 0 ) ;
2018-04-20 10:50:32 +00:00
}
2021-01-22 16:32:37 +00:00
catch ( const std : : exception & e )
2018-04-20 10:50:32 +00:00
{
2021-01-22 16:32:37 +00:00
LOG ( INFO ) < < " Can't disconnect signal conditioner " < < selected_signal_conditioner_ID < < " to channel " < < i < < " : " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
2018-04-20 10:50:32 +00:00
}
}
2021-01-22 16:32:37 +00:00
DLOG ( INFO ) < < " Signal conditioner(s) sucessfully disconnected from channels " ;
return 0 ;
}
2014-04-12 20:02:18 +00:00
2021-01-22 16:32:37 +00:00
int GNSSFlowgraph : : connect_channels_to_observables ( )
{
for ( int i = 0 ; i < channels_count_ ; i + + )
2018-04-20 10:50:32 +00:00
{
2018-05-01 21:32:52 +00:00
try
{
2021-01-22 16:32:37 +00:00
top_block_ - > connect ( channels_ . at ( i ) - > get_right_block ( ) , 0 ,
observables_ - > get_left_block ( ) , i ) ;
2018-05-01 21:32:52 +00:00
}
catch ( const std : : exception & e )
{
2021-01-22 16:32:37 +00:00
LOG ( ERROR ) < < " Can't connect channel " < < i < < " to observables: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
2018-05-01 21:32:52 +00:00
}
2021-01-22 16:32:37 +00:00
}
DLOG ( INFO ) < < " Channel blocks successfully connected to the Observables block " ;
return 0 ;
}
int GNSSFlowgraph : : disconnect_channels_from_observables ( )
{
for ( int i = 0 ; i < channels_count_ ; i + + )
{
try
2018-07-12 18:01:18 +00:00
{
2021-01-22 16:32:37 +00:00
top_block_ - > disconnect ( channels_ . at ( i ) - > get_right_block ( ) , 0 ,
observables_ - > get_left_block ( ) , i ) ;
2018-07-12 18:01:18 +00:00
}
2021-01-22 16:32:37 +00:00
catch ( const std : : exception & e )
2012-04-14 18:04:27 +00:00
{
2021-01-22 16:32:37 +00:00
LOG ( INFO ) < < " Can't disconnect channel " < < i < < " to observables: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
}
return 0 ;
}
2018-06-14 21:10:43 +00:00
2021-01-22 16:32:37 +00:00
int GNSSFlowgraph : : connect_observables_to_pvt ( )
{
// Connect the observables output of each channel to the PVT block
try
{
for ( int i = 0 ; i < channels_count_ ; i + + )
{
top_block_ - > connect ( observables_ - > get_right_block ( ) , i , pvt_ - > get_left_block ( ) , i ) ;
top_block_ - > msg_connect ( channels_ . at ( i ) - > get_right_block ( ) , pmt : : mp ( " telemetry " ) , pvt_ - > get_left_block ( ) , pmt : : mp ( " telemetry " ) ) ;
}
2020-06-14 15:48:36 +00:00
2021-01-22 16:32:37 +00:00
top_block_ - > msg_connect ( observables_ - > get_right_block ( ) , pmt : : mp ( " status " ) , channels_status_ , pmt : : mp ( " status " ) ) ;
2020-11-07 20:33:26 +00:00
2021-01-22 16:32:37 +00:00
top_block_ - > msg_connect ( pvt_ - > get_left_block ( ) , pmt : : mp ( " pvt_to_observables " ) , observables_ - > get_right_block ( ) , pmt : : mp ( " pvt_to_observables " ) ) ;
top_block_ - > msg_connect ( pvt_ - > get_left_block ( ) , pmt : : mp ( " status " ) , channels_status_ , pmt : : mp ( " status " ) ) ;
}
catch ( const std : : exception & e )
{
LOG ( ERROR ) < < " Can't connect observables to PVT: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
DLOG ( INFO ) < < " Observables successfully connected to the PVT block " ;
return 0 ;
}
2018-06-14 21:10:43 +00:00
2021-01-22 16:32:37 +00:00
int GNSSFlowgraph : : disconnect_observables_from_pvt ( )
{
try
{
for ( int i = 0 ; i < channels_count_ ; i + + )
{
top_block_ - > disconnect ( observables_ - > get_right_block ( ) , i , pvt_ - > get_left_block ( ) , i ) ;
top_block_ - > msg_disconnect ( channels_ . at ( i ) - > get_right_block ( ) , pmt : : mp ( " telemetry " ) , pvt_ - > get_left_block ( ) , pmt : : mp ( " telemetry " ) ) ;
}
top_block_ - > msg_disconnect ( observables_ - > get_right_block ( ) , pmt : : mp ( " status " ) , channels_status_ , pmt : : mp ( " status " ) ) ;
2018-10-22 19:16:38 +00:00
2021-01-22 16:32:37 +00:00
top_block_ - > msg_disconnect ( pvt_ - > get_left_block ( ) , pmt : : mp ( " pvt_to_observables " ) , observables_ - > get_right_block ( ) , pmt : : mp ( " pvt_to_observables " ) ) ;
top_block_ - > msg_disconnect ( pvt_ - > get_left_block ( ) , pmt : : mp ( " status " ) , channels_status_ , pmt : : mp ( " status " ) ) ;
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect observables to PVT: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
return 0 ;
}
2019-01-25 21:43:00 +00:00
2018-06-14 21:10:43 +00:00
2021-01-22 16:32:37 +00:00
int GNSSFlowgraph : : connect_gnss_synchro_monitor ( )
{
try
{
for ( int i = 0 ; i < channels_count_ ; i + + )
{
top_block_ - > connect ( observables_ - > get_right_block ( ) , i , GnssSynchroMonitor_ , i ) ;
2012-04-14 18:04:27 +00:00
}
2017-05-05 14:37:29 +00:00
}
2021-01-22 16:32:37 +00:00
catch ( const std : : exception & e )
{
LOG ( ERROR ) < < " Can't connect observables to Monitor block: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
DLOG ( INFO ) < < " gnss_synchro_monitor successfully connected to Observables block " ;
return 0 ;
}
2015-02-27 17:21:25 +00:00
2021-01-22 16:32:37 +00:00
int GNSSFlowgraph : : connect_acquisition_monitor ( )
{
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
{
2021-01-22 16:32:37 +00:00
top_block_ - > connect ( channels_ . at ( i ) - > get_right_block_acq ( ) , 0 , GnssSynchroAcquisitionMonitor_ , i ) ;
2012-04-14 18:04:27 +00:00
}
2021-01-22 16:32:37 +00:00
}
catch ( const std : : exception & e )
{
LOG ( ERROR ) < < " Can't connect acquisition intermediate outputs to Monitor block: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
DLOG ( INFO ) < < " acqusition_monitor successfully connected to Channel blocks " ;
return 0 ;
}
2019-07-11 16:39:28 +00:00
2021-01-22 16:32:37 +00:00
int GNSSFlowgraph : : connect_tracking_monitor ( )
{
try
{
for ( int i = 0 ; i < channels_count_ ; i + + )
{
top_block_ - > connect ( channels_ . at ( i ) - > get_right_block_trk ( ) , 0 , GnssSynchroTrackingMonitor_ , i ) ;
}
2018-03-03 01:03:39 +00:00
}
catch ( const std : : exception & e )
{
2021-01-22 16:32:37 +00:00
LOG ( ERROR ) < < " Can't connect tracking outputs to Monitor block: " < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
top_block_ - > disconnect_all ( ) ;
2021-01-22 16:32:37 +00:00
return 1 ;
2018-03-03 01:03:39 +00:00
}
2021-01-22 16:32:37 +00:00
DLOG ( INFO ) < < " tracking_monitor successfully connected to Channel blocks " ;
return 0 ;
}
2012-04-14 18:04:27 +00:00
2021-01-22 16:32:37 +00:00
int GNSSFlowgraph : : connect_monitors ( )
{
2018-07-03 11:25:43 +00:00
// GNSS SYNCHRO MONITOR
if ( enable_monitor_ )
{
2021-01-22 16:32:37 +00:00
if ( connect_gnss_synchro_monitor ( ) ! = 0 )
2018-07-03 11:25:43 +00:00
{
2021-01-22 16:32:37 +00:00
return 1 ;
2018-07-03 11:25:43 +00:00
}
}
2020-10-09 18:55:31 +00:00
// GNSS SYNCHRO ACQUISITION MONITOR
if ( enable_acquisition_monitor_ )
{
2021-01-22 16:32:37 +00:00
if ( connect_acquisition_monitor ( ) ! = 0 )
2020-10-09 18:55:31 +00:00
{
2021-01-22 16:32:37 +00:00
return 1 ;
2020-10-09 18:55:31 +00:00
}
}
// GNSS SYNCHRO TRACKING MONITOR
if ( enable_tracking_monitor_ )
{
2021-01-22 16:32:37 +00:00
if ( connect_tracking_monitor ( ) ! = 0 )
{
return 1 ;
}
}
return 0 ;
}
int GNSSFlowgraph : : disconnect_monitors ( )
{
try
{
for ( int i = 0 ; i < channels_count_ ; i + + )
2020-10-09 18:55:31 +00:00
{
2021-01-22 16:32:37 +00:00
if ( enable_monitor_ )
{
top_block_ - > disconnect ( observables_ - > get_right_block ( ) , i , GnssSynchroMonitor_ , i ) ;
}
if ( enable_acquisition_monitor_ )
{
top_block_ - > disconnect ( channels_ . at ( i ) - > get_right_block_acq ( ) , 0 , GnssSynchroAcquisitionMonitor_ , i ) ;
}
if ( enable_tracking_monitor_ )
2020-10-09 18:55:31 +00:00
{
2021-01-22 16:32:37 +00:00
top_block_ - > disconnect ( channels_ . at ( i ) - > get_right_block_trk ( ) , 0 , GnssSynchroTrackingMonitor_ , i ) ;
2020-10-09 18:55:31 +00:00
}
}
2021-01-22 16:32:37 +00:00
}
catch ( const std : : exception & e )
{
LOG ( INFO ) < < " Can't disconnect monitors: " < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return 1 ;
}
return 0 ;
}
void GNSSFlowgraph : : check_signal_conditioners ( )
{
// check for unconnected signal conditioners and connect null_sinks
// in order to provide configuration flexibility to multiband files or signal sources
for ( size_t n = 0 ; n < sig_conditioner_ . size ( ) ; n + + )
2018-05-01 21:32:52 +00:00
{
2021-01-22 16:32:37 +00:00
if ( signal_conditioner_connected_ . at ( n ) = = false )
2018-05-01 21:32:52 +00:00
{
2021-01-22 16:32:37 +00:00
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 ) ;
LOG ( INFO ) < < " Null sink connected to signal conditioner " < < n < < " due to lack of connection to any channel \n " ;
2018-05-01 21:32:52 +00:00
}
}
2021-01-22 16:32:37 +00:00
}
void GNSSFlowgraph : : assign_channels ( )
{
// 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-22 17:49:13 +00:00
{
2021-01-22 16:32:37 +00:00
unsigned int sat = 0 ;
2018-05-01 21:32:52 +00:00
try
{
2021-01-22 16:32:37 +00:00
sat = configuration_ - > property ( " Channel " + std : : to_string ( i ) + " .satellite " , 0 ) ;
2018-05-01 21:32:52 +00:00
}
catch ( const std : : exception & e )
{
LOG ( WARNING ) < < e . what ( ) ;
2018-04-22 17:49:13 +00:00
}
2021-01-22 16:32:37 +00:00
if ( sat = = 0 )
2018-04-22 17:49:13 +00:00
{
2021-01-22 16:32:37 +00:00
vector_of_channels . push_back ( i ) ;
2018-04-22 17:49:13 +00:00
}
2021-01-22 16:32:37 +00:00
else
2018-04-22 17:49:13 +00:00
{
2021-01-22 16:32:37 +00:00
auto it = vector_of_channels . begin ( ) ;
it = vector_of_channels . insert ( it , i ) ;
2018-04-22 17:49:13 +00:00
}
}
2021-01-22 16:32:37 +00:00
// Assign satellites to channels in the initialization
for ( unsigned int & i : vector_of_channels )
2018-04-22 17:49:13 +00:00
{
2021-01-22 16:32:37 +00:00
const std : : string gnss_signal = channels_ . at ( i ) - > get_signal ( ) . get_signal_str ( ) ; // use channel's implicit signal
unsigned int sat = 0 ;
2018-04-22 17:49:13 +00:00
try
{
2021-01-22 16:32:37 +00:00
sat = configuration_ - > property ( " Channel " + std : : to_string ( i ) + " .satellite " , 0 ) ;
2018-04-22 17:49:13 +00:00
}
catch ( const std : : exception & e )
{
2021-01-22 16:32:37 +00:00
LOG ( WARNING ) < < e . what ( ) ;
2018-04-22 17:49:13 +00:00
}
2021-01-22 16:32:37 +00:00
if ( sat = = 0 )
2018-04-22 17:49:13 +00:00
{
2021-01-22 16:32:37 +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-04-22 17:49:13 +00:00
}
2021-01-22 16:32:37 +00:00
else
2018-04-22 17:49:13 +00:00
{
2021-01-22 16:32:37 +00:00
std : : string gnss_system ;
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 ;
2018-04-22 17:49:13 +00:00
2021-01-22 16:32:37 +00:00
case evGAL_7X :
gnss_system = " Galileo " ;
signal_value = Gnss_Signal ( Gnss_Satellite ( gnss_system , sat ) , gnss_signal ) ;
available_GAL_7X_signals_ . remove ( signal_value ) ;
break ;
2018-04-22 17:49:13 +00:00
2021-01-22 16:32:37 +00:00
case evGAL_E6 :
gnss_system = " Galileo " ;
signal_value = Gnss_Signal ( Gnss_Satellite ( gnss_system , sat ) , gnss_signal ) ;
available_GAL_E6_signals_ . remove ( signal_value ) ;
break ;
2018-04-22 17:49:13 +00:00
2021-01-22 16:32:37 +00:00
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 ;
2018-04-22 17:49:13 +00:00
2021-01-22 16:32:37 +00:00
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-04-22 17:49:13 +00:00
2021-01-22 16:32:37 +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 ;
2018-04-22 17:49:13 +00:00
2021-01-22 16:32:37 +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 ;
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 ;
}
channels_ . at ( i ) - > set_signal ( signal_value ) ;
}
2012-04-14 18:04:27 +00:00
}
2011-10-01 18:45:20 +00:00
}
2012-04-14 18:04:27 +00:00
2021-01-24 00:49:16 +00:00
void GNSSFlowgraph : : print_help ( )
{
if ( ! help_hint_ . empty ( ) )
{
std : : cerr < < " It seems that your configuration file is not well defined. \n " ;
std : : cerr < < " A hint to fix your configuration file: \n " ;
std : : cerr < < help_hint_ ;
}
}
void GNSSFlowgraph : : check_desktop_conf_in_fpga_env ( )
{
int number_of_fpga_acq_channels = 0 ;
for ( int i = 0 ; i < channels_count_ ; i + + )
{
if ( channels_ . at ( i ) - > get_left_block_acq ( ) = = nullptr )
{
number_of_fpga_acq_channels + + ;
}
}
if ( number_of_fpga_acq_channels ! = channels_count_ )
{
help_hint_ + = " * The Acquisition block implementation is not suitable for GNSS-SDR flowgraph with FPGA off-loading \n " ;
help_hint_ + = " If you want to use this configuration in an environment without FPGA, please rebuild GNSS-SDR with CMake option '-DENABLE_FPGA=OFF' \n " ;
}
}
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 ;
2020-06-14 15:48:36 +00:00
case evGAL_7X :
available_GAL_7X_signals_ . remove ( gs ) ;
available_GAL_7X_signals_ . push_back ( gs ) ;
break ;
2020-11-07 20:33:26 +00:00
case evGAL_E6 :
available_GAL_E6_signals_ . remove ( gs ) ;
available_GAL_E6_signals_ . push_back ( gs ) ;
break ;
2019-07-16 15:41:12 +00:00
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 ;
2020-06-14 15:48:36 +00:00
case evGAL_7X :
available_GAL_7X_signals_ . remove ( gs ) ;
break ;
2020-11-07 20:33:26 +00:00
case evGAL_E6 :
available_GAL_E6_signals_ . remove ( gs ) ;
break ;
2019-07-16 15:41:12 +00:00
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 ;
2020-06-14 15:48:36 +00:00
case evGAL_7X :
return ( primary_freq_doppler_hz / FREQ1 ) * FREQ7 ;
break ;
2019-07-23 15:56:02 +00:00
case evGPS_2S :
return ( primary_freq_doppler_hz / FREQ1 ) * FREQ2 ;
break ;
2020-11-07 20:33:26 +00:00
case evGAL_E6 :
return ( primary_freq_doppler_hz / FREQ1 ) * FREQ6 ;
break ;
2019-07-23 15:56:02 +00:00
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 ) ;
}
2021-01-22 16:32:37 +00:00
# if ENABLE_FPGA
2019-07-19 16:49:42 +00:00
// 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 ( ) ;
2021-01-22 16:32:37 +00:00
# else
channels_ [ current_channel ] - > start_acquisition ( ) ;
2019-07-19 16:49:42 +00:00
# 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 ( ) ) ;
2021-01-22 16:32:37 +00:00
# if ENABLE_FPGA
2019-02-13 16:48:14 +00:00
// 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 ( ) ;
2021-01-22 16:32:37 +00:00
# else
channels_ [ who ] - > start_acquisition ( ) ;
2019-02-13 16:48:14 +00:00
# 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 ;
2020-12-30 20:49:29 +00:00
for ( const 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 ) ;
}
2020-06-14 15:48:36 +00:00
gs = Gnss_Signal ( visible_satellite . second , " 7X " ) ;
old_size = available_GAL_7X_signals_ . size ( ) ;
available_GAL_7X_signals_ . remove ( gs ) ;
if ( old_size > available_GAL_7X_signals_ . size ( ) )
{
available_GAL_7X_signals_ . push_front ( gs ) ;
}
2020-11-07 20:33:26 +00:00
gs = Gnss_Signal ( visible_satellite . second , " E6 " ) ;
old_size = available_GAL_E6_signals_ . size ( ) ;
available_GAL_E6_signals_ . remove ( gs ) ;
if ( old_size > available_GAL_E6_signals_ . size ( ) )
{
available_GAL_E6_signals_ . push_front ( gs ) ;
}
2018-11-05 16:53:53 +00:00
}
}
}
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
2021-01-22 16:32:37 +00:00
# if 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
2020-07-10 11:35:15 +00:00
for ( int i = 0 ; i < channels_count_ ; i + + )
2019-07-30 05:40:23 +00:00
{
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
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
2020-06-14 15:48:36 +00:00
if ( configuration_ - > property ( " Channels_7X.count " , 0 ) > 0 )
{
// Loop to create the list of Galileo E5b signals
for ( available_gnss_prn_iter = available_galileo_prn . cbegin ( ) ;
available_gnss_prn_iter ! = available_galileo_prn . cend ( ) ;
available_gnss_prn_iter + + )
{
available_GAL_7X_signals_ . emplace_back (
Gnss_Satellite ( std : : string ( " Galileo " ) , * available_gnss_prn_iter ) ,
std : : string ( " 7X " ) ) ;
}
}
2020-11-07 20:33:26 +00:00
if ( configuration_ - > property ( " Channels_E6.count " , 0 ) > 0 )
{
// Loop to create the list of Galileo E6 signals
for ( available_gnss_prn_iter = available_galileo_prn . cbegin ( ) ;
available_gnss_prn_iter ! = available_galileo_prn . cend ( ) ;
available_gnss_prn_iter + + )
{
available_GAL_E6_signals_ . emplace_back (
Gnss_Satellite ( std : : string ( " Galileo " ) , * available_gnss_prn_iter ) ,
std : : string ( " E6 " ) ) ;
}
}
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 ;
}
2020-06-14 15:48:36 +00:00
if ( configuration_ - > property ( " Channels_7X.count " , 0 ) > 0 )
{
multiband = true ;
}
2020-11-07 20:33:26 +00:00
if ( configuration_ - > property ( " Channels_E6.count " , 0 ) > 0 )
{
multiband = true ;
}
2019-10-04 07:17:29 +00:00
}
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 ;
2020-06-14 15:48:36 +00:00
case evGAL_7X :
if ( configuration_ - > property ( " Channels_1B.count " , 0 ) > 0 )
{
// 1. Get the current channel status map
std : : map < int , std : : shared_ptr < Gnss_Synchro > > current_channels_status = channels_status_ - > get_current_status_map ( ) ;
// 2. search the currently tracked Galileo E1 satellites and assist the Galileo E5 acquisition if the satellite is not tracked on E5
for ( auto & current_status : current_channels_status )
{
if ( std : : string ( current_status . second - > Signal ) = = " 1B " )
{
std : : list < Gnss_Signal > : : iterator it2 ;
it2 = std : : find_if ( std : : begin ( available_GAL_7X_signals_ ) , std : : end ( available_GAL_7X_signals_ ) ,
[ & ] ( Gnss_Signal const & sig ) { return sig . get_satellite ( ) . get_PRN ( ) = = current_status . second - > PRN ; } ) ;
if ( it2 ! = available_GAL_7X_signals_ . end ( ) )
{
2020-07-13 10:24:27 +00:00
estimated_doppler = static_cast < float > ( current_status . second - > Carrier_Doppler_hz ) ;
2020-06-14 15:48:36 +00:00
RX_time = current_status . second - > RX_time ;
// std::cout << " Channel: " << it->first << " => Doppler: " << estimated_doppler << "[Hz] \n";
// 3. return the Gal 7X satellite and remove it from list
result = * it2 ;
if ( pop )
{
available_GAL_7X_signals_ . erase ( it2 ) ;
}
found_signal = true ;
assistance_available = true ;
break ;
}
}
}
}
// fallback: pick the front satellite because there is no tracked satellites in E1 to assist E5
if ( found_signal = = false )
{
result = available_GAL_7X_signals_ . front ( ) ;
available_GAL_7X_signals_ . pop_front ( ) ;
if ( ! pop )
{
available_GAL_7X_signals_ . push_back ( result ) ;
}
}
break ;
2020-11-07 20:33:26 +00:00
case evGAL_E6 :
if ( configuration_ - > property ( " Channels_1B.count " , 0 ) > 0 )
{
// 1. Get the current channel status map
std : : map < int , std : : shared_ptr < Gnss_Synchro > > current_channels_status = channels_status_ - > get_current_status_map ( ) ;
// 2. search the currently tracked Galileo E1 satellites and assist the Galileo E5 acquisition if the satellite is not tracked on E5
for ( auto & current_status : current_channels_status )
{
if ( std : : string ( current_status . second - > Signal ) = = " 1B " )
{
std : : list < Gnss_Signal > : : iterator it2 ;
it2 = std : : find_if ( std : : begin ( available_GAL_E6_signals_ ) , std : : end ( available_GAL_E6_signals_ ) ,
[ & ] ( Gnss_Signal const & sig ) { return sig . get_satellite ( ) . get_PRN ( ) = = current_status . second - > PRN ; } ) ;
if ( it2 ! = available_GAL_E6_signals_ . end ( ) )
{
estimated_doppler = static_cast < float > ( current_status . second - > Carrier_Doppler_hz ) ;
RX_time = current_status . second - > RX_time ;
// std::cout << " Channel: " << it->first << " => Doppler: " << estimated_doppler << "[Hz] \n";
// 3. return the Gal E6 satellite and remove it from list
result = * it2 ;
if ( pop )
{
available_GAL_E6_signals_ . erase ( it2 ) ;
}
found_signal = true ;
assistance_available = true ;
break ;
}
}
}
}
// fallback: pick the front satellite because there is no tracked satellites in E1 to assist E6
if ( found_signal = = false )
{
result = available_GAL_E6_signals_ . front ( ) ;
available_GAL_E6_signals_ . pop_front ( ) ;
if ( ! pop )
{
available_GAL_E6_signals_ . push_back ( result ) ;
}
}
break ;
2018-06-14 21:10:43 +00:00
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 ;
}