2011-10-01 18:45:20 +00:00
/*!
* \ file gnss_flowgraph . cc
2011-12-28 21:36:45 +00:00
* \ brief Implementation of a GNSS receiver flowgraph
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
2014-04-13 00:51:00 +00:00
* Carles Fernandez - Prades , 2014. cfernandez ( at ) cttc . es
2011-10-01 18:45:20 +00:00
*
* Detailed description of the file here if needed .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
2015-01-08 18:49:59 +00:00
* Copyright ( C ) 2010 - 2015 ( see AUTHORS file for a list of contributors )
2011-10-01 18:45:20 +00:00
*
* GNSS - SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS - SDR .
*
* GNSS - SDR is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
2015-01-08 18:49:59 +00:00
* ( at your option ) any later version .
2011-10-01 18:45:20 +00:00
*
* GNSS - SDR is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with GNSS - SDR . If not , see < http : //www.gnu.org/licenses/>.
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
# include "gnss_flowgraph.h"
# include "unistd.h"
2015-11-30 09:18:09 +00:00
# include <algorithm>
2014-03-16 19:58:29 +00:00
# include <exception>
2011-12-21 00:21:20 +00:00
# include <iostream>
2014-03-16 19:58:29 +00:00
# include <set>
2011-12-14 16:50:36 +00:00
# include <boost/lexical_cast.hpp>
2015-11-30 09:18:09 +00:00
# include <boost/tokenizer.hpp>
2011-10-01 18:45:20 +00:00
# include <glog/logging.h>
# include "configuration_interface.h"
# include "gnss_block_interface.h"
# include "channel_interface.h"
# include "gnss_block_factory.h"
2014-02-18 19:40:44 +00:00
# define GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS 8
2011-10-01 18:45:20 +00:00
using google : : LogMessage ;
2014-04-03 21:59:14 +00:00
GNSSFlowgraph : : GNSSFlowgraph ( std : : shared_ptr < ConfigurationInterface > configuration ,
2013-07-04 13:47:40 +00:00
boost : : shared_ptr < gr : : msg_queue > queue )
2012-04-14 18:04:27 +00:00
{
connected_ = false ;
running_ = false ;
configuration_ = configuration ;
queue_ = queue ;
init ( ) ;
2011-10-01 18:45:20 +00:00
}
2012-04-14 18:04:27 +00:00
GNSSFlowgraph : : ~ GNSSFlowgraph ( )
2015-02-27 17:21:25 +00:00
{ }
2011-10-01 18:45:20 +00:00
2012-04-14 18:04:27 +00:00
void GNSSFlowgraph : : start ( )
{
if ( running_ )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Already running " ;
2012-04-14 18:04:27 +00:00
return ;
}
try
{
top_block_ - > start ( ) ;
}
catch ( std : : exception & e )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Unable to start flowgraph " ;
LOG ( ERROR ) < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
return ;
}
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 ( )
{
for ( unsigned int i = 0 ; i < channels_count_ ; i + + )
{
2014-04-12 17:45:45 +00:00
channels_ . at ( i ) - > stop ( ) ;
2015-05-08 23:48:16 +00:00
LOG ( INFO ) < < " Channel " < < i < < " in state " < < channels_state_ [ i ] ;
2012-04-14 18:04:27 +00:00
}
2014-03-16 19:58:29 +00:00
LOG ( INFO ) < < " Threads finished. Return to main program. " ;
2012-04-14 18:04:27 +00:00
top_block_ - > stop ( ) ;
running_ = false ;
2011-10-01 18:45:20 +00:00
}
2012-04-14 18:04:27 +00:00
void GNSSFlowgraph : : connect ( )
{
/* Connects the blocks in the flowgraph
*
2016-04-06 14:12:06 +00:00
* Signal Source > Signal conditioner > > Channels > > Observables > > PVT
2012-04-14 18:04:27 +00:00
*/
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 ;
}
2015-02-27 17:21:25 +00:00
for ( int i = 0 ; i < sources_count_ ; i + + )
{
try
{
sig_source_ . at ( i ) - > connect ( top_block_ ) ;
}
catch ( std : : exception & e )
{
LOG ( INFO ) < < " Can't connect signal source block " < < i < < " internally " ;
LOG ( ERROR ) < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return ;
}
}
2012-04-14 18:04:27 +00:00
// Signal Source > Signal conditioner >
2015-03-01 21:23:17 +00:00
for ( unsigned int i = 0 ; i < sig_conditioner_ . size ( ) ; i + + )
2015-02-27 17:21:25 +00:00
{
try
{
sig_conditioner_ . at ( i ) - > connect ( top_block_ ) ;
}
catch ( std : : exception & e )
{
LOG ( INFO ) < < " Can't connect signal conditioner block " < < i < < " internally " ;
LOG ( ERROR ) < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return ;
}
}
2012-04-14 18:04:27 +00:00
for ( unsigned int i = 0 ; i < channels_count_ ; i + + )
{
try
{
2014-04-12 17:45:45 +00:00
channels_ . at ( i ) - > connect ( top_block_ ) ;
2012-04-14 18:04:27 +00:00
}
catch ( std : : exception & e )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Can't connect channel " < < i < < " internally " ;
LOG ( ERROR ) < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
}
}
try
{
2014-04-12 17:45:45 +00:00
observables_ - > connect ( top_block_ ) ;
2012-04-14 18:04:27 +00:00
}
catch ( std : : exception & e )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Can't connect observables block internally " ;
LOG ( ERROR ) < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
}
// Signal Source > Signal conditioner >> Channels >> Observables > PVT
try
{
2014-04-12 17:45:45 +00:00
pvt_ - > connect ( top_block_ ) ;
2012-04-14 18:04:27 +00:00
}
catch ( std : : exception & e )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Can't connect PVT block internally " ;
LOG ( ERROR ) < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
}
DLOG ( INFO ) < < " blocks connected internally " ;
2015-02-12 17:56:05 +00:00
// Signal Source (i) > Signal conditioner (i) >
2015-03-01 21:23:17 +00:00
int RF_Channels = 0 ;
int signal_conditioner_ID = 0 ;
2015-02-27 17:21:25 +00:00
for ( int i = 0 ; i < sources_count_ ; i + + )
{
try
{
//TODO: Remove this array implementation and create generic multistream connector
//(if a signal source has more than 1 stream, then connect it to the multistream signal conditioner)
if ( sig_source_ . at ( i ) - > implementation ( ) . compare ( " Raw_Array_Signal_Source " ) = = 0 )
{
//Multichannel Array
std : : cout < < " ARRAY MODE " < < std : : endl ;
for ( int j = 0 ; j < GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS ; j + + )
{
2015-03-01 21:23:17 +00:00
std : : cout < < " connecting ch " < < j < < std : : endl ;
2015-02-27 17:21:25 +00:00
top_block_ - > connect ( sig_source_ . at ( i ) - > get_right_block ( ) , j , sig_conditioner_ . at ( i ) - > get_left_block ( ) , j ) ;
}
}
else
{
2015-03-01 21:23:17 +00:00
//TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface.
//Include GetRFChannels in the interface to avoid read config parameters here
//read the number of RF channels for each front-end
RF_Channels = configuration_ - > property ( sig_source_ . at ( i ) - > role ( ) + " .RF_channels " , 1 ) ;
2015-02-12 17:56:05 +00:00
2015-03-01 21:23:17 +00:00
for ( int j = 0 ; j < RF_Channels ; j + + )
{
//Connect the multichannel signal source to multiple signal conditioners
2015-05-07 18:48:33 +00:00
// GNURADIO max_streams=-1 means infinite ports!
2015-05-07 20:12:38 +00:00
LOG ( INFO ) < < " sig_source_.at(i)->get_right_block()->output_signature()->max_streams()= " < < sig_source_ . at ( i ) - > get_right_block ( ) - > output_signature ( ) - > max_streams ( ) ;
LOG ( INFO ) < < " sig_conditioner_.at(signal_conditioner_ID)->get_left_block()->input_signature()= " < < sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) - > input_signature ( ) - > max_streams ( ) ;
2015-04-24 17:11:45 +00:00
if ( sig_source_ . at ( i ) - > get_right_block ( ) - > output_signature ( ) - > max_streams ( ) > 1 )
2015-03-04 19:54:15 +00:00
{
2015-04-24 17:11:45 +00:00
2015-05-07 20:12:38 +00:00
LOG ( INFO ) < < " connecting sig_source_ " < < i < < " stream " < < j < < " to conditioner " < < j ;
2015-03-04 19:54:15 +00:00
top_block_ - > connect ( sig_source_ . at ( i ) - > get_right_block ( ) , j , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
2015-04-24 17:11:45 +00:00
2015-03-04 19:54:15 +00:00
}
else
{
if ( j = = 0 )
{
// RF_channel 0 backward compatibility with single channel sources
2015-05-07 20:12:38 +00:00
LOG ( INFO ) < < " connecting sig_source_ " < < i < < " stream " < < 0 < < " to conditioner " < < j ;
2015-03-04 19:54:15 +00:00
top_block_ - > connect ( sig_source_ . at ( i ) - > get_right_block ( ) , 0 , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
}
else
{
// Multiple channel sources using multiple output blocks of single channel (requires RF_channel selector in call)
2015-05-07 20:12:38 +00:00
LOG ( INFO ) < < " connecting sig_source_ " < < i < < " stream " < < j < < " to conditioner " < < j ;
2015-03-04 19:54:15 +00:00
top_block_ - > connect ( sig_source_ . at ( i ) - > get_right_block ( j ) , 0 , sig_conditioner_ . at ( signal_conditioner_ID ) - > get_left_block ( ) , 0 ) ;
}
}
2015-03-04 18:00:57 +00:00
2015-03-01 21:23:17 +00:00
signal_conditioner_ID + + ;
}
}
2015-02-27 17:21:25 +00:00
}
catch ( std : : exception & e )
{
2015-05-07 14:30:01 +00:00
LOG ( WARNING ) < < " Can't connect signal source " < < i < < " to signal conditioner " < < i ;
2015-02-27 17:21:25 +00:00
LOG ( ERROR ) < < e . what ( ) ;
top_block_ - > disconnect_all ( ) ;
return ;
}
}
2015-02-12 17:56:05 +00:00
2012-04-14 18:04:27 +00:00
DLOG ( INFO ) < < " Signal source connected to signal conditioner " ;
2015-02-12 17:56:05 +00:00
// Signal conditioner (selected_signal_source) >> channels (i) (dependent of their associated SignalSource_ID)
2015-03-01 19:25:50 +00:00
int selected_signal_conditioner_ID ;
2012-04-14 18:04:27 +00:00
for ( unsigned int i = 0 ; i < channels_count_ ; i + + )
{
2015-03-01 21:23:17 +00:00
selected_signal_conditioner_ID = configuration_ - > property ( " Channel " + boost : : lexical_cast < std : : string > ( i ) + " .RF_channel_ID " , 0 ) ;
2015-02-27 17:21:25 +00:00
try
{
2015-03-01 21:23:17 +00:00
top_block_ - > connect ( sig_conditioner_ . at ( selected_signal_conditioner_ID ) - > get_right_block ( ) , 0 ,
2015-02-27 17:21:25 +00:00
channels_ . at ( i ) - > get_left_block ( ) , 0 ) ;
2012-04-14 18:04:27 +00:00
}
catch ( std : : exception & e )
{
2015-03-01 21:23:17 +00:00
LOG ( WARNING ) < < " Can't connect signal conditioner " < < selected_signal_conditioner_ID < < " to channel " < < i ;
2014-03-16 19:58:29 +00:00
LOG ( ERROR ) < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
}
2015-03-01 21:23:17 +00:00
DLOG ( INFO ) < < " signal conditioner " < < selected_signal_conditioner_ID < < " connected to channel " < < i ;
2012-04-14 18:04:27 +00:00
// Signal Source > Signal conditioner >> Channels >> Observables
try
{
2014-04-12 17:45:45 +00:00
top_block_ - > connect ( channels_ . at ( i ) - > get_right_block ( ) , 0 ,
observables_ - > get_left_block ( ) , i ) ;
2012-04-14 18:04:27 +00:00
}
catch ( std : : exception & e )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Can't connect channel " < < i < < " to observables " ;
LOG ( ERROR ) < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
}
2015-04-24 17:11:45 +00:00
std : : string default_signal = configuration_ - > property ( " Channel.signal " , std : : string ( " 1C " ) ) ;
2015-05-07 18:48:33 +00:00
std : : string gnss_signal = ( configuration_ - > property ( " Channel " + boost : : lexical_cast < std : : string > ( i ) + " .signal " , default_signal ) ) ;
2015-05-10 19:37:54 +00:00
while ( gnss_signal . compare ( available_GNSS_signals_ . front ( ) . get_signal_str ( ) ) ! = 0 )
2014-06-10 16:58:17 +00:00
{
available_GNSS_signals_ . push_back ( available_GNSS_signals_ . front ( ) ) ;
available_GNSS_signals_ . pop_front ( ) ;
}
2014-04-12 17:45:45 +00:00
channels_ . at ( i ) - > set_signal ( available_GNSS_signals_ . front ( ) ) ;
2014-03-16 19:58:29 +00:00
LOG ( INFO ) < < " Channel " < < i < < " assigned to " < < available_GNSS_signals_ . front ( ) ;
2014-04-12 17:45:45 +00:00
channels_ . at ( i ) - > start ( ) ;
2014-04-12 20:02:18 +00:00
2012-04-14 18:04:27 +00:00
if ( channels_state_ [ i ] = = 1 )
{
2014-04-12 17:45:45 +00:00
channels_ . at ( i ) - > start_acquisition ( ) ;
2015-10-24 08:39:10 +00:00
available_GNSS_signals_ . pop_front ( ) ;
2015-05-07 18:48:33 +00:00
LOG ( INFO ) < < " Channel " < < i < < " connected to observables and ready for acquisition " ;
2012-04-14 18:04:27 +00:00
}
else
{
2015-05-07 18:48:33 +00:00
LOG ( INFO ) < < " Channel " < < i < < " connected to observables in standby mode " ;
2012-04-14 18:04:27 +00:00
}
}
2015-02-27 17:21:25 +00:00
2012-04-14 18:04:27 +00:00
/*
* Connect the observables output of each channel to the PVT block
*/
try
{
for ( unsigned int i = 0 ; i < channels_count_ ; i + + )
{
2014-04-12 17:45:45 +00:00
top_block_ - > connect ( observables_ - > get_right_block ( ) , i , pvt_ - > get_left_block ( ) , i ) ;
2016-04-12 13:28:58 +00:00
top_block_ - > msg_connect ( channels_ . at ( i ) - > get_right_block ( ) , pmt : : mp ( " telemetry " ) , pvt_ - > get_left_block ( ) , pmt : : mp ( " telemetry " ) ) ;
2012-04-14 18:04:27 +00:00
}
}
catch ( std : : exception & e )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Can't connect observables to PVT " ;
LOG ( ERROR ) < < e . what ( ) ;
2012-04-14 18:04:27 +00:00
top_block_ - > disconnect_all ( ) ;
return ;
}
connected_ = true ;
2014-03-16 19:58:29 +00:00
LOG ( INFO ) < < " Flowgraph connected " ;
2012-04-14 18:04:27 +00:00
top_block_ - > dump ( ) ;
2011-10-01 18:45:20 +00:00
}
2012-04-14 18:04:27 +00:00
void GNSSFlowgraph : : wait ( )
{
if ( ! running_ )
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Can't apply wait. Flowgraph is not running " ;
2012-04-14 18:04:27 +00:00
return ;
}
top_block_ - > wait ( ) ;
DLOG ( INFO ) < < " Flowgraph finished calculations " ;
running_ = false ;
2011-10-01 18:45:20 +00:00
}
2012-04-14 18:04:27 +00:00
2016-04-13 14:19:15 +00:00
bool GNSSFlowgraph : : send_telemetry_msg ( pmt : : pmt_t msg )
{
//push ephemeris to PVT telemetry msg in port using a channel out port
// it uses the first channel as a message produces (it is already connected to PVT)
channels_ . at ( 0 ) - > get_right_block ( ) - > message_port_pub ( pmt : : mp ( " telemetry " ) , msg ) ;
return true ;
}
2011-12-28 21:36:45 +00:00
/*
* Applies an action to the flowgraph
*
* \ param [ in ] who Who generated the action
* \ param [ in ] what What is the action 0 : acquisition failed
*/
2012-04-14 18:04:27 +00:00
void GNSSFlowgraph : : apply_action ( unsigned int who , unsigned int what )
{
2016-03-15 09:01:08 +00:00
DLOG ( INFO ) < < " received " < < what < < " from " < < who ;
2012-04-14 18:04:27 +00:00
switch ( what )
{
case 0 :
2016-03-15 09:01:08 +00:00
LOG ( INFO ) < < " Channel " < < who < < " ACQ FAILED satellite " < < channels_ . at ( who ) - > get_signal ( ) . get_satellite ( ) < < " , Signal " < < channels_ . at ( who ) - > get_signal ( ) . get_signal_str ( ) ;
2014-04-12 17:45:45 +00:00
available_GNSS_signals_ . push_back ( channels_ . at ( who ) - > get_signal ( ) ) ;
2012-09-05 13:50:59 +00:00
2015-04-24 17:11:45 +00:00
//TODO: Optimize the channel and signal matching!
2015-05-10 19:37:54 +00:00
while ( channels_ . at ( who ) - > get_signal ( ) . get_signal_str ( ) . compare ( available_GNSS_signals_ . front ( ) . get_signal_str ( ) ) ! = 0 )
2014-03-16 19:58:29 +00:00
{
2012-09-05 13:50:59 +00:00
available_GNSS_signals_ . push_back ( available_GNSS_signals_ . front ( ) ) ;
available_GNSS_signals_ . pop_front ( ) ;
2014-03-16 19:58:29 +00:00
}
2014-04-12 17:45:45 +00:00
channels_ . at ( who ) - > set_signal ( available_GNSS_signals_ . front ( ) ) ;
2012-04-14 18:04:27 +00:00
available_GNSS_signals_ . pop_front ( ) ;
2016-03-04 13:08:19 +00:00
//todo: This is a provisional bug fix to avoid random channel state machine deadlock caused by an incorrect sequence of events
// Correct sequence: start_acquisition() is triggered after the negative acquisition driven by the process_channel_messages() thread inside channel class
// Incorrect sequence: due to thread concurrency, some times start_acquisition is triggered BEFORE the last negative_acquisition notification, thus producing a deadlock
// a short delay here (5ms) apparently reduces the chances to enter in this deadlock
usleep ( 5000 ) ;
2014-04-12 17:45:45 +00:00
channels_ . at ( who ) - > start_acquisition ( ) ;
2012-09-05 13:50:59 +00:00
2012-04-14 18:04:27 +00:00
break ;
// TODO: Tracking messages
case 1 :
2016-03-15 09:01:08 +00:00
LOG ( INFO ) < < " Channel " < < who < < " ACQ SUCCESS satellite " < < channels_ . at ( who ) - > get_signal ( ) . get_satellite ( ) ;
2012-04-14 18:04:27 +00:00
channels_state_ [ who ] = 2 ;
acq_channels_count_ - - ;
2015-10-24 08:39:10 +00:00
if ( ! available_GNSS_signals_ . empty ( ) & & acq_channels_count_ < max_acq_channels_ )
2012-04-14 18:04:27 +00:00
{
for ( unsigned int i = 0 ; i < channels_count_ ; i + + )
{
if ( channels_state_ [ i ] = = 0 )
{
channels_state_ [ i ] = 1 ;
2015-10-24 08:39:10 +00:00
while ( channels_ . at ( i ) - > get_signal ( ) . get_signal_str ( ) . compare ( available_GNSS_signals_ . front ( ) . get_signal_str ( ) ) ! = 0 )
{
available_GNSS_signals_ . push_back ( available_GNSS_signals_ . front ( ) ) ;
available_GNSS_signals_ . pop_front ( ) ;
}
channels_ . at ( i ) - > set_signal ( available_GNSS_signals_ . front ( ) ) ;
available_GNSS_signals_ . pop_front ( ) ;
2012-04-14 18:04:27 +00:00
acq_channels_count_ + + ;
2014-04-12 17:45:45 +00:00
channels_ . at ( i ) - > start_acquisition ( ) ;
2012-04-14 18:04:27 +00:00
break ;
}
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
}
}
break ;
case 2 :
2016-03-15 09:01:08 +00:00
LOG ( INFO ) < < " Channel " < < who < < " TRK FAILED satellite " < < channels_ . at ( who ) - > get_signal ( ) . get_satellite ( ) ;
2012-04-14 18:04:27 +00:00
if ( acq_channels_count_ < max_acq_channels_ )
{
channels_state_ [ who ] = 1 ;
acq_channels_count_ + + ;
2014-04-12 17:45:45 +00:00
channels_ . at ( who ) - > start_acquisition ( ) ;
2012-04-14 18:04:27 +00:00
}
else
{
channels_state_ [ who ] = 0 ;
2014-04-12 17:45:45 +00:00
channels_ . at ( who ) - > standby ( ) ;
2015-10-24 08:39:10 +00:00
available_GNSS_signals_ . push_back ( channels_ . at ( who ) - > get_signal ( ) ) ;
2012-04-14 18:04:27 +00:00
}
2015-05-04 20:16:26 +00:00
// for (unsigned int i = 0; i < channels_count_; i++)
// {
// LOG(INFO) << "Channel " << i << " in state " << channels_state_[i] << std::endl;
// }
2012-04-14 18:04:27 +00:00
break ;
default :
break ;
}
2016-03-15 09:01:08 +00:00
DLOG ( INFO ) < < " Number of available signals: " < < available_GNSS_signals_ . size ( ) ;
2011-10-01 18:45:20 +00:00
}
2014-04-03 21:59:14 +00:00
void GNSSFlowgraph : : set_configuration ( 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
}
configuration_ = configuration ;
2011-10-01 18:45:20 +00:00
}
2012-04-14 18:04:27 +00:00
void GNSSFlowgraph : : init ( )
{
/*
* Instantiates the receiver blocks
*/
2014-04-11 18:18:59 +00:00
std : : shared_ptr < GNSSBlockFactory > block_factory_ = std : : make_shared < GNSSBlockFactory > ( ) ;
2012-04-14 18:04:27 +00:00
2015-02-12 17:56:05 +00:00
// 1. read the number of RF front-ends available (one file_source per RF front-end)
sources_count_ = configuration_ - > property ( " Receiver.sources_count " , 1 ) ;
2012-01-16 18:27:31 +00:00
2015-03-01 21:23:17 +00:00
int RF_Channels = 0 ;
int signal_conditioner_ID = 0 ;
2015-03-01 19:25:50 +00:00
2015-02-27 17:21:25 +00:00
if ( sources_count_ > 1 )
{
for ( int i = 0 ; i < sources_count_ ; i + + )
{
2015-03-01 21:23:17 +00:00
std : : cout < < " Creating source " < < i < < std : : endl ;
2015-02-27 17:21:25 +00:00
sig_source_ . push_back ( block_factory_ - > GetSignalSource ( configuration_ , queue_ , i ) ) ;
2015-03-01 21:23:17 +00:00
//TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface.
//Include GetRFChannels in the interface to avoid read config parameters here
//read the number of RF channels for each front-end
RF_Channels = configuration_ - > property ( sig_source_ . at ( i ) - > role ( ) + " .RF_channels " , 1 ) ;
std : : cout < < " RF Channels " < < RF_Channels < < std : : endl ;
for ( int j = 0 ; j < RF_Channels ; j + + )
{
sig_conditioner_ . push_back ( block_factory_ - > GetSignalConditioner ( configuration_ , queue_ , signal_conditioner_ID ) ) ;
signal_conditioner_ID + + ;
}
2015-02-27 17:21:25 +00:00
}
}
else
{
//backwards compatibility for old config files
sig_source_ . push_back ( block_factory_ - > GetSignalSource ( configuration_ , queue_ , - 1 ) ) ;
2015-03-01 21:23:17 +00:00
//TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface.
//Include GetRFChannels in the interface to avoid read config parameters here
//read the number of RF channels for each front-end
RF_Channels = configuration_ - > property ( sig_source_ . at ( 0 ) - > role ( ) + " .RF_channels " , 0 ) ;
if ( RF_Channels ! = 0 )
{
for ( int j = 0 ; j < RF_Channels ; j + + )
{
sig_conditioner_ . push_back ( block_factory_ - > GetSignalConditioner ( configuration_ , queue_ , signal_conditioner_ID ) ) ;
signal_conditioner_ID + + ;
}
}
else
{
//old config file, single signal source and single channel, not specified
sig_conditioner_ . push_back ( block_factory_ - > GetSignalConditioner ( configuration_ , queue_ , - 1 ) ) ;
}
2015-02-27 17:21:25 +00:00
}
2015-02-12 17:56:05 +00:00
observables_ = block_factory_ - > GetObservables ( configuration_ , queue_ ) ;
pvt_ = block_factory_ - > GetPVT ( configuration_ , queue_ ) ;
2011-10-01 18:45:20 +00:00
2014-04-11 18:18:59 +00:00
std : : shared_ptr < std : : vector < std : : unique_ptr < GNSSBlockInterface > > > channels = block_factory_ - > GetChannels ( configuration_ , queue_ ) ;
2012-01-16 18:27:31 +00:00
2012-04-14 18:04:27 +00:00
channels_count_ = channels - > size ( ) ;
for ( unsigned int i = 0 ; i < channels_count_ ; i + + )
{
2015-02-27 17:21:25 +00:00
std : : shared_ptr < GNSSBlockInterface > chan_ = std : : move ( channels - > at ( i ) ) ;
2015-02-12 17:56:05 +00:00
channels_ . push_back ( std : : dynamic_pointer_cast < ChannelInterface > ( chan_ ) ) ;
2012-04-14 18:04:27 +00:00
}
2011-10-01 18:45:20 +00:00
2013-07-04 13:47:40 +00:00
top_block_ = gr : : make_top_block ( " GNSSFlowgraph " ) ;
2011-10-01 18:45:20 +00:00
2012-04-14 18:04:27 +00:00
// fill the available_GNSS_signals_ queue with the satellites ID's to be searched by the acquisition
set_signals_list ( ) ;
set_channels_state ( ) ;
applied_actions_ = 0 ;
2011-10-01 18:45:20 +00:00
2012-04-14 18:04:27 +00:00
DLOG ( INFO ) < < " Blocks instantiated. " < < channels_count_ < < " channels. " ;
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 : : set_signals_list ( )
{
/*
2013-07-20 07:58:59 +00:00
* Sets a sequential list of GNSS satellites
2012-04-14 18:04:27 +00:00
*/
2013-07-20 07:58:59 +00:00
std : : set < unsigned int > : : iterator available_gnss_prn_iter ;
2012-04-14 18:04:27 +00:00
/*
* \ TODO Describe GNSS satellites more nicely , with RINEX notation
* See http : //igscb.jpl.nasa.gov/igscb/data/format/rinex301.pdf (page 5)
*/
2013-10-25 16:07:24 +00:00
/*
* Read GNSS - SDR default GNSS system and signal
*/
2015-05-07 14:30:01 +00:00
std : : string default_system = configuration_ - > property ( " Channel.system " , std : : string ( " " ) ) ; // DEPRECATED
std : : string default_signal = configuration_ - > property ( " Channel.signal " , std : : string ( " " ) ) ;
2013-05-26 23:59:04 +00:00
2015-05-08 23:48:16 +00:00
unsigned int total_channels = configuration_ - > property ( " Channels_GPS.count " , 0 ) +
configuration_ - > property ( " Channels_1C.count " , 0 ) +
configuration_ - > property ( " Channels_2S.count " , 0 ) +
configuration_ - > property ( " Channels_Galileo.count " , 0 ) +
configuration_ - > property ( " Channels_1B.count " , 0 ) +
configuration_ - > property ( " Channels_5X.count " , 0 ) ;
2012-04-14 18:04:27 +00:00
/*
* Loop to create the list of GNSS Signals
* To add signals from other systems , add another loop ' for '
*/
2015-05-07 14:30:01 +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-08 23:48:16 +00:00
std : : set < unsigned int > available_sbas_prn = { 120 , 124 , 126 } ;
std : : set < unsigned int > available_galileo_prn = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ,
2015-05-10 10:35:49 +00:00
11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 ,
2015-05-08 23:48:16 +00:00
29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 } ;
2015-10-24 08:39:10 +00:00
std : : string sv_list = configuration_ - > property ( " Galileo.prns " , std : : string ( " " ) ) ;
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 > ) ;
if ( tmp_set . size ( ) > 0 )
{
available_galileo_prn = tmp_set ;
}
}
sv_list = configuration_ - > property ( " GPS.prns " , std : : string ( " " ) ) ;
2015-05-08 23:48:16 +00:00
2015-10-24 08:39:10 +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 > ) ;
if ( tmp_set . size ( ) > 0 )
{
available_gps_prn = tmp_set ;
}
}
sv_list = configuration_ - > property ( " SBAS.prns " , std : : string ( " " ) ) ;
2015-05-08 23:48:16 +00:00
2015-10-24 08:39:10 +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 > ) ;
if ( tmp_set . size ( ) > 0 )
{
available_sbas_prn = tmp_set ;
}
}
2015-05-08 23:48:16 +00:00
2015-05-08 14:06:30 +00:00
if ( ( configuration_ - > property ( " Channels_1C.count " , 0 ) > 0 ) or ( default_system . find ( std : : string ( " GPS " ) ) ! = std : : string : : npos ) or ( default_signal . compare ( " 1C " ) = = 0 ) or ( configuration_ - > property ( " Channels_GPS.count " , 0 ) > 0 ) )
2014-04-13 16:58:52 +00:00
{
/*
* Loop to create GPS L1 C / A signals
*/
for ( available_gnss_prn_iter = available_gps_prn . begin ( ) ;
available_gnss_prn_iter ! = available_gps_prn . end ( ) ;
available_gnss_prn_iter + + )
{
available_GNSS_signals_ . push_back ( Gnss_Signal ( Gnss_Satellite ( std : : string ( " GPS " ) ,
* available_gnss_prn_iter ) , std : : string ( " 1C " ) ) ) ;
}
}
2013-07-20 07:58:59 +00:00
2015-05-07 14:30:01 +00:00
if ( ( configuration_ - > property ( " Channels_2S.count " , 0 ) > 0 ) or ( default_system . find ( std : : string ( " GPS L2C M " ) ) ! = std : : string : : npos ) )
2015-04-24 17:11:45 +00:00
{
/*
* Loop to create GPS L2C M signals
*/
for ( available_gnss_prn_iter = available_gps_prn . begin ( ) ;
available_gnss_prn_iter ! = available_gps_prn . end ( ) ;
available_gnss_prn_iter + + )
{
available_GNSS_signals_ . push_back ( Gnss_Signal ( Gnss_Satellite ( std : : string ( " GPS " ) ,
* available_gnss_prn_iter ) , std : : string ( " 2S " ) ) ) ;
}
}
2013-07-20 07:58:59 +00:00
2015-05-07 14:30:01 +00:00
if ( ( configuration_ - > property ( " Channels_SBAS.count " , 0 ) > 0 ) or default_system . find ( std : : string ( " SBAS " ) ) ! = std : : string : : npos )
2014-04-13 16:58:52 +00:00
{
/*
* Loop to create SBAS L1 C / A signals
*/
for ( available_gnss_prn_iter = available_sbas_prn . begin ( ) ;
available_gnss_prn_iter ! = available_sbas_prn . end ( ) ;
available_gnss_prn_iter + + )
{
available_GNSS_signals_ . push_back ( Gnss_Signal ( Gnss_Satellite ( std : : string ( " SBAS " ) ,
* available_gnss_prn_iter ) , std : : string ( " 1C " ) ) ) ;
}
}
2013-07-20 07:58:59 +00:00
2015-05-08 23:48:16 +00:00
2015-05-08 14:06:30 +00:00
if ( ( configuration_ - > property ( " Channels_1B.count " , 0 ) > 0 ) or ( default_system . find ( std : : string ( " Galileo " ) ) ! = std : : string : : npos ) or ( default_signal . compare ( " 1B " ) = = 0 ) or ( configuration_ - > property ( " Channels_Galileo.count " , 0 ) > 0 ) )
2012-09-03 11:58:28 +00:00
{
2014-04-13 16:58:52 +00:00
/*
* Loop to create the list of Galileo E1 B signals
*/
2015-05-07 14:30:01 +00:00
for ( available_gnss_prn_iter = available_galileo_prn . begin ( ) ;
available_gnss_prn_iter ! = available_galileo_prn . end ( ) ;
available_gnss_prn_iter + + )
{
available_GNSS_signals_ . push_back ( Gnss_Signal ( Gnss_Satellite ( std : : string ( " Galileo " ) ,
* available_gnss_prn_iter ) , std : : string ( " 1B " ) ) ) ;
}
}
2014-04-13 16:58:52 +00:00
2015-05-08 23:48:16 +00:00
if ( ( configuration_ - > property ( " Channels_5X.count " , 0 ) > 0 ) )
2015-05-07 14:30:01 +00:00
{
/*
* Loop to create the list of Galileo E1 B signals
*/
2014-04-13 16:58:52 +00:00
for ( available_gnss_prn_iter = available_galileo_prn . begin ( ) ;
available_gnss_prn_iter ! = available_galileo_prn . end ( ) ;
available_gnss_prn_iter + + )
{
available_GNSS_signals_ . push_back ( Gnss_Signal ( Gnss_Satellite ( std : : string ( " Galileo " ) ,
2015-05-07 19:34:37 +00:00
* available_gnss_prn_iter ) , std : : string ( " 5X " ) ) ) ;
2014-04-13 16:58:52 +00:00
}
2012-04-14 18:04:27 +00:00
}
2013-07-20 07:58:59 +00:00
2013-05-26 23:59:04 +00:00
/*
* Ordering the list of signals from configuration file
*/
2012-04-14 18:04:27 +00:00
std : : list < Gnss_Signal > : : iterator gnss_it = available_GNSS_signals_ . begin ( ) ;
2015-05-07 19:25:20 +00:00
// Preassignation if not defined at ChannelX.signal=1C ...? In what order?
2015-05-08 23:48:16 +00:00
for ( unsigned int i = 0 ; i < total_channels ; i + + )
2012-04-14 18:04:27 +00:00
{
2015-05-08 23:48:16 +00:00
std : : string gnss_signal = ( configuration_ - > property ( " Channel " + boost : : lexical_cast < std : : string > ( i ) + " .signal " , default_signal ) ) ;
2015-05-10 10:35:49 +00:00
std : : string gnss_system ;
if ( ( gnss_signal . compare ( " 1C " ) = = 0 ) or ( gnss_signal . compare ( " 2S " ) = = 0 ) ) gnss_system = " GPS " ;
if ( ( gnss_signal . compare ( " 1B " ) = = 0 ) or ( gnss_signal . compare ( " 5X " ) = = 0 ) ) gnss_system = " Galileo " ;
LOG ( INFO ) < < " Channel " < < i < < " system " < < gnss_system < < " , signal " < < gnss_signal ;
2013-05-26 23:59:04 +00:00
2015-05-08 23:48:16 +00:00
unsigned int sat = configuration_ - > property ( " Channel " + boost : : lexical_cast < std : : string > ( i ) + " .satellite " , 0 ) ;
2012-04-14 18:04:27 +00:00
2015-05-10 19:37:54 +00:00
if ( ( ( sat = = 0 ) | | ( sat = = gnss_it - > get_satellite ( ) . get_PRN ( ) ) ) and ( gnss_it - > get_signal_str ( ) . compare ( gnss_signal ) = = 0 ) ) // 0 = not PRN in configuration file
2012-04-14 18:04:27 +00:00
{
gnss_it + + ;
}
else
{
2015-10-24 08:39:10 +00:00
Gnss_Signal signal_value = Gnss_Signal ( Gnss_Satellite ( gnss_system , ( sat ! = 0 ? sat : gnss_it - > get_satellite ( ) . get_PRN ( ) ) ) , gnss_signal ) ;
if ( gnss_it = = available_GNSS_signals_ . begin ( ) )
{
available_GNSS_signals_ . remove ( signal_value ) ;
gnss_it = available_GNSS_signals_ . begin ( ) ;
}
else
{
available_GNSS_signals_ . remove ( signal_value ) ;
}
2012-04-14 18:04:27 +00:00
available_GNSS_signals_ . insert ( gnss_it , signal_value ) ;
}
}
2014-06-25 22:11:44 +00:00
2015-05-08 11:11:41 +00:00
// **** FOR DEBUGGING THE LIST OF GNSS SIGNALS ****
2014-09-05 16:51:08 +00:00
2015-05-08 11:11:41 +00:00
// std::cout << "default_system=" << default_system << std::endl;
// std::cout << "default_signal=" << default_signal << std::endl;
// std::list<Gnss_Signal>::iterator available_gnss_list_iter;
// for (available_gnss_list_iter = available_GNSS_signals_.begin(); available_gnss_list_iter
// != available_GNSS_signals_.end(); available_gnss_list_iter++)
// {
// std::cout << *available_gnss_list_iter << std::endl;
// }
2012-03-02 17:17:51 +00:00
}
2012-04-14 18:04:27 +00:00
void GNSSFlowgraph : : set_channels_state ( )
{
2014-03-16 19:58:29 +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_ ;
2014-03-16 19:58:29 +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_ ) ;
for ( unsigned int i = 0 ; i < channels_count_ ; i + + )
{
if ( i < max_acq_channels_ )
{
channels_state_ . push_back ( 1 ) ;
2014-03-16 19:58:29 +00:00
}
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
}