2011-10-01 18:45:20 +00:00
/*!
* \ file control_thread . cc
2011-12-27 21:21:12 +00:00
* \ brief This class implements the receiver control plane
2011-10-01 18:45:20 +00:00
* \ author Carlos Aviles , 2010. carlos . avilesr ( at ) googlemail . com
*
2011-12-27 21:21:12 +00:00
* GNSS Receiver Control Plane : connects the flowgraph , starts running it ,
* and while it does not stop , reads the control messages generated by the blocks ,
* process them , and apply the corresponding actions .
2011-10-01 18:45:20 +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
*/
2019-07-29 19:22:44 +00:00
# if ARMA_NO_BOUND_CHECKING
# define ARMA_NO_DEBUG 1
# endif
2011-10-01 18:45:20 +00:00
# include "control_thread.h"
2018-02-26 02:15:53 +00:00
# include "concurrent_map.h"
2019-03-05 07:59:04 +00:00
# include "configuration_interface.h"
2018-02-26 02:15:53 +00:00
# include "file_configuration.h"
2018-12-09 21:00:09 +00:00
# include "galileo_almanac.h"
2018-02-26 02:15:53 +00:00
# include "galileo_ephemeris.h"
# include "galileo_iono.h"
# include "galileo_utc_model.h"
2018-12-09 21:00:09 +00:00
# include "geofunctions.h"
# include "glonass_gnav_ephemeris.h"
# include "glonass_gnav_utc_model.h"
# include "gnss_flowgraph.h"
2019-03-05 07:59:04 +00:00
# include "gnss_satellite.h"
2018-12-09 21:00:09 +00:00
# include "gnss_sdr_flags.h"
2019-03-05 08:55:59 +00:00
# include "gps_acq_assist.h" // for Gps_Acq_Assist
# include "gps_almanac.h" // for Gps_Almanac
# include "gps_cnav_ephemeris.h" // for Gps_CNAV_Ephemeris
# include "gps_cnav_utc_model.h" // for Gps_CNAV_Utc_Model
# include "gps_ephemeris.h" // for Gps_Ephemeris
# include "gps_iono.h" // for Gps_Iono
# include "gps_utc_model.h" // for Gps_Utc_Model
# include "pvt_interface.h" // for PvtInterface
# include "rtklib.h" // for gtime_t, alm_t
# include "rtklib_conversions.h" // for alm_to_rtklib
# include "rtklib_ephemeris.h" // for alm2pos, eph2pos
# include "rtklib_rtkcmn.h" // for utc2gpst
2019-07-21 10:55:59 +00:00
# include <armadillo> // for interaction with geofunctions
2019-03-05 08:55:59 +00:00
# include <boost/lexical_cast.hpp> // for bad_lexical_cast
# include <glog/logging.h> // for LOG
# include <pmt/pmt.h> // for make_any
# include <algorithm> // for find, min
# include <chrono> // for milliseconds
# include <cmath> // for floor, fmod, log
2020-07-14 18:12:08 +00:00
# include <ctime> // for time_t, gmtime, strftime
2019-03-05 08:55:59 +00:00
# include <exception> // for exception
2020-07-07 16:53:50 +00:00
# include <iostream> // for operator<<
2019-03-05 08:55:59 +00:00
# include <limits> // for numeric_limits
# include <map> // for map
# include <pthread.h> // for pthread_cancel
# include <stdexcept> // for invalid_argument
# include <sys/ipc.h> // for IPC_CREAT
# include <sys/msg.h> // for msgctl, msgget
2018-02-26 02:15:53 +00:00
2019-08-03 17:51:50 +00:00
# ifdef ENABLE_FPGA
# include <boost/chrono.hpp> // for steady_clock
# endif
2014-01-12 20:07:38 +00:00
2021-10-30 03:43:22 +00:00
# if PMT_USES_BOOST_ANY
namespace wht = boost ;
# else
namespace wht = std ;
# endif
2019-02-22 09:47:24 +00:00
extern Concurrent_Map < Gps_Acq_Assist > global_gps_acq_assist_map ;
extern Concurrent_Queue < Gps_Acq_Assist > global_gps_acq_assist_queue ;
2013-08-27 14:32:44 +00:00
2011-10-01 18:45:20 +00:00
ControlThread : : ControlThread ( )
{
2019-02-10 13:07:27 +00:00
if ( FLAGS_c = = " - " )
2018-02-18 11:23:55 +00:00
{
2018-03-03 01:03:39 +00:00
configuration_ = std : : make_shared < FileConfiguration > ( FLAGS_config_file ) ;
2018-02-18 11:23:55 +00:00
}
else
{
configuration_ = std : : make_shared < FileConfiguration > ( FLAGS_c ) ;
}
2021-01-24 23:49:36 +00:00
// Basic configuration checks
auto aux = std : : dynamic_pointer_cast < FileConfiguration > ( configuration_ ) ;
conf_file_has_section_ = aux - > has_section ( ) ;
conf_file_has_mandatory_globals_ = ( configuration_ - > property ( " GNSS-SDR.internal_fs_sps " , 0 ) = = 0 ? false : true ) ;
const std : : string empty_implementation ;
std : : string src_impl = configuration_ - > property ( " SignalSource.implementation " , empty_implementation ) ;
2021-03-13 20:35:55 +00:00
int src_count_deprecated = configuration_ - > property ( " Receiver.sources_count " , 1 ) ;
int src_count = configuration_ - > property ( " GNSS-SDR.num_sources " , src_count_deprecated ) ;
2021-03-10 12:51:00 +00:00
if ( src_impl . empty ( ) )
2021-01-24 23:49:36 +00:00
{
2021-03-13 20:35:55 +00:00
src_impl = std : : string ( " " ) ;
int num_src = 0 ;
for ( auto i = 0 ; i < src_count ; i + + )
2021-01-24 23:49:36 +00:00
{
2021-03-13 20:35:55 +00:00
auto src_impl_multiple = configuration_ - > property ( " SignalSource " + std : : to_string ( i ) + " .implementation " , empty_implementation ) ;
num_src + = ! src_impl_multiple . empty ( ) ;
2021-01-24 23:49:36 +00:00
}
2021-03-13 20:35:55 +00:00
conf_has_signal_sources_ = ( num_src = = src_count ) ;
2021-01-24 23:49:36 +00:00
}
2021-03-10 12:51:00 +00:00
else
{
conf_has_signal_sources_ = true ;
}
2021-01-24 23:49:36 +00:00
std : : string pvt_impl = configuration_ - > property ( " PVT.implementation " , empty_implementation ) ;
conf_has_pvt_ = ! pvt_impl . empty ( ) ;
std : : string obs_impl = configuration_ - > property ( " Observables.implementation " , empty_implementation ) ;
conf_has_observables_ = ! obs_impl . empty ( ) ;
well_formatted_configuration_ = conf_file_has_section_ & & conf_file_has_mandatory_globals_ & & conf_has_signal_sources_ & & conf_has_observables_ & & conf_has_pvt_ ;
2018-10-23 14:54:06 +00:00
restart_ = false ;
2011-10-01 18:45:20 +00:00
init ( ) ;
}
2012-11-01 16:39:06 +00:00
2020-06-19 10:39:28 +00:00
ControlThread : : ControlThread ( std : : shared_ptr < ConfigurationInterface > configuration )
2011-10-01 18:45:20 +00:00
{
2020-06-19 10:39:28 +00:00
configuration_ = std : : move ( configuration ) ;
2021-01-24 23:49:36 +00:00
conf_file_has_section_ = true ;
conf_file_has_mandatory_globals_ = true ;
conf_has_signal_sources_ = true ;
conf_has_observables_ = true ;
conf_has_pvt_ = true ;
well_formatted_configuration_ = true ;
2018-11-08 14:34:58 +00:00
restart_ = false ;
2011-10-01 18:45:20 +00:00
init ( ) ;
}
2012-11-01 16:39:06 +00:00
2018-11-23 15:38:20 +00:00
void ControlThread : : init ( )
{
2020-06-27 07:52:59 +00:00
telecommand_enabled_ = configuration_ - > property ( " GNSS-SDR.telecommand_enabled " , false ) ;
2019-09-17 14:25:17 +00:00
// OPTIONAL: specify a custom year to override the system time in order to postprocess old gnss records and avoid wrong week rollover
2019-09-18 16:25:07 +00:00
pre_2009_file_ = configuration_ - > property ( " GNSS-SDR.pre_2009_file " , false ) ;
2018-11-23 15:38:20 +00:00
// Instantiates a control queue, a GNSS flowgraph, and a control message factory
2019-07-16 15:41:12 +00:00
control_queue_ = std : : make_shared < Concurrent_Queue < pmt : : pmt_t > > ( ) ;
2019-07-28 10:01:11 +00:00
cmd_interface_ . set_msg_queue ( control_queue_ ) ; // set also the queue pointer for the telecommand thread
2021-01-24 23:49:36 +00:00
if ( well_formatted_configuration_ )
2018-11-23 15:38:20 +00:00
{
2021-01-24 23:49:36 +00:00
try
{
flowgraph_ = std : : make_shared < GNSSFlowgraph > ( configuration_ , control_queue_ ) ;
}
catch ( const boost : : bad_lexical_cast & e )
{
std : : cout < < " Caught bad lexical cast with error " < < e . what ( ) < < ' \n ' ;
}
2018-11-23 15:38:20 +00:00
}
2021-01-24 23:49:36 +00:00
else
2018-11-23 15:38:20 +00:00
{
2021-01-24 23:49:36 +00:00
flowgraph_ = nullptr ;
2018-11-23 15:38:20 +00:00
}
2021-01-24 23:49:36 +00:00
2018-11-23 15:38:20 +00:00
stop_ = false ;
processed_control_messages_ = 0 ;
applied_actions_ = 0 ;
2020-06-19 10:39:28 +00:00
supl_mcc_ = 0 ;
supl_mns_ = 0 ;
supl_lac_ = 0 ;
supl_ci_ = 0 ;
msqid_ = - 1 ;
2018-11-23 15:38:20 +00:00
agnss_ref_location_ = Agnss_Ref_Location ( ) ;
agnss_ref_time_ = Agnss_Ref_Time ( ) ;
2020-07-19 07:39:32 +00:00
const std : : string empty_string ;
const std : : string ref_location_str = configuration_ - > property ( " GNSS-SDR.AGNSS_ref_location " , empty_string ) ;
const std : : string ref_time_str = configuration_ - > property ( " GNSS-SDR.AGNSS_ref_utc_time " , empty_string ) ;
2019-02-05 00:31:09 +00:00
if ( ref_location_str ! = empty_string )
2018-11-23 15:38:20 +00:00
{
std : : vector < double > vect ;
std : : stringstream ss ( ref_location_str ) ;
double d ;
while ( ss > > d )
{
vect . push_back ( d ) ;
if ( ( ss . peek ( ) = = ' , ' ) or ( ss . peek ( ) = = ' ' ) )
2019-02-11 20:13:02 +00:00
{
ss . ignore ( ) ;
}
2018-11-23 15:38:20 +00:00
}
// fill agnss_ref_location_
if ( vect . size ( ) > = 2 )
{
if ( ( vect [ 0 ] < 90.0 ) and ( vect [ 0 ] > - 90 ) and ( vect [ 1 ] < 180.0 ) and ( vect [ 1 ] > - 180.0 ) )
{
agnss_ref_location_ . lat = vect [ 0 ] ;
agnss_ref_location_ . lon = vect [ 1 ] ;
agnss_ref_location_ . valid = true ;
}
else
{
2020-07-07 16:53:50 +00:00
std : : cerr < < " GNSS-SDR.AGNSS_ref_location= " < < ref_location_str < < " is not a valid position. \n " ;
2018-11-23 15:38:20 +00:00
agnss_ref_location_ . valid = false ;
}
}
}
2019-02-05 00:31:09 +00:00
if ( ref_time_str = = empty_string )
2018-11-23 15:38:20 +00:00
{
// Make an educated guess
time_t rawtime ;
time ( & rawtime ) ;
2021-02-23 10:57:24 +00:00
agnss_ref_time_ . seconds = rawtime ;
2018-11-23 15:38:20 +00:00
agnss_ref_time_ . valid = true ;
}
else
{
// fill agnss_ref_time_
2020-07-19 07:39:32 +00:00
struct tm tm
{
} ;
2018-11-23 15:38:20 +00:00
if ( strptime ( ref_time_str . c_str ( ) , " %d/%m/%Y %H:%M:%S " , & tm ) ! = nullptr )
{
2021-02-23 10:57:24 +00:00
agnss_ref_time_ . seconds = timegm ( & tm ) ;
if ( agnss_ref_time_ . seconds > 0 )
2018-11-23 15:38:20 +00:00
{
agnss_ref_time_ . valid = true ;
}
else
{
2020-07-07 16:53:50 +00:00
std : : cerr < < " GNSS-SDR.AGNSS_ref_utc_time= " < < ref_time_str < < " is not well-formed. Please use four digits for the year: DD/MM/YYYY HH:MM:SS \n " ;
2018-11-23 15:38:20 +00:00
}
}
else
{
2020-07-07 16:53:50 +00:00
std : : cerr < < " GNSS-SDR.AGNSS_ref_utc_time= " < < ref_time_str < < " is not well-formed. Should be DD/MM/YYYY HH:MM:SS in UTC \n " ;
2018-11-24 08:40:15 +00:00
agnss_ref_time_ . valid = false ;
2018-11-23 15:38:20 +00:00
}
}
2019-07-25 14:38:19 +00:00
receiver_on_standby_ = false ;
2018-11-23 15:38:20 +00:00
}
2018-12-14 13:17:04 +00:00
ControlThread : : ~ ControlThread ( ) // NOLINT(modernize-use-equals-default)
2011-10-01 18:45:20 +00:00
{
2020-06-25 00:50:07 +00:00
DLOG ( INFO ) < < " Control Thread destructor called " ;
2020-06-19 10:39:28 +00:00
if ( msqid_ ! = - 1 )
2019-02-11 20:13:02 +00:00
{
2020-06-19 10:39:28 +00:00
msgctl ( msqid_ , IPC_RMID , nullptr ) ;
2019-02-11 20:13:02 +00:00
}
2019-02-24 12:22:52 +00:00
if ( sysv_queue_thread_ . joinable ( ) )
{
sysv_queue_thread_ . join ( ) ;
}
if ( cmd_interface_thread_ . joinable ( ) )
{
2020-06-27 07:52:59 +00:00
cmd_interface_thread_ . join ( ) ;
2019-02-24 12:22:52 +00:00
}
2011-10-01 18:45:20 +00:00
}
2012-11-01 16:39:06 +00:00
2018-10-19 12:54:03 +00:00
void ControlThread : : telecommand_listener ( )
{
2020-06-27 07:52:59 +00:00
if ( telecommand_enabled_ )
2018-12-11 09:36:15 +00:00
{
2020-07-19 07:39:32 +00:00
const int tcp_cmd_port = configuration_ - > property ( " GNSS-SDR.telecommand_tcp_port " , 3333 ) ;
2018-12-11 09:36:15 +00:00
cmd_interface_ . run_cmd_server ( tcp_cmd_port ) ;
}
2018-10-19 12:54:03 +00:00
}
2019-07-21 10:55:59 +00:00
2019-07-19 16:49:42 +00:00
void ControlThread : : event_dispatcher ( bool & valid_event , pmt : : pmt_t & msg )
{
if ( valid_event )
{
2019-07-19 21:26:26 +00:00
processed_control_messages_ + + ;
2020-07-19 07:39:32 +00:00
const size_t msg_type_hash_code = pmt : : any_ref ( msg ) . type ( ) . hash_code ( ) ;
if ( msg_type_hash_code = = channel_event_type_hash_code_ )
2019-07-19 16:49:42 +00:00
{
2019-07-25 14:38:19 +00:00
if ( receiver_on_standby_ = = false )
{
2021-10-30 03:43:22 +00:00
const auto new_event = wht : : any_cast < channel_event_sptr > ( pmt : : any_ref ( msg ) ) ;
2019-07-25 14:38:19 +00:00
DLOG ( INFO ) < < " New channel event rx from ch id: " < < new_event - > channel_id
< < " what: " < < new_event - > event_type ;
flowgraph_ - > apply_action ( new_event - > channel_id , new_event - > event_type ) ;
}
2019-07-19 16:49:42 +00:00
}
2020-07-19 07:39:32 +00:00
else if ( msg_type_hash_code = = command_event_type_hash_code_ )
2019-07-19 16:49:42 +00:00
{
2021-10-30 03:43:22 +00:00
const auto new_event = wht : : any_cast < command_event_sptr > ( pmt : : any_ref ( msg ) ) ;
2019-07-19 16:49:42 +00:00
DLOG ( INFO ) < < " New command event rx from ch id: " < < new_event - > command_id
< < " what: " < < new_event - > event_type ;
if ( new_event - > command_id = = 200 )
{
apply_action ( new_event - > event_type ) ;
}
else
{
if ( new_event - > command_id = = 300 ) // some TC commands require also actions from control_thread
{
apply_action ( new_event - > event_type ) ;
}
flowgraph_ - > apply_action ( new_event - > command_id , new_event - > event_type ) ;
}
}
else
{
DLOG ( INFO ) < < " Control Queue: unknown object type! \n " ;
}
}
else
{
2019-07-25 14:38:19 +00:00
if ( receiver_on_standby_ = = false )
{
2019-07-28 10:01:11 +00:00
// perform non-priority tasks
flowgraph_ - > acquisition_manager ( 0 ) ; // start acquisition of untracked satellites
2019-07-25 14:38:19 +00:00
}
2019-07-19 16:49:42 +00:00
}
}
2018-11-08 14:34:58 +00:00
2019-07-21 10:55:59 +00:00
2011-12-28 03:05:37 +00:00
/*
* Runs the control thread that manages the receiver control plane
*
* This is the main loop that reads and process the control messages
* 1 - Connect the GNSS receiver flowgraph
* 2 - Start the GNSS receiver flowgraph
* while ( flowgraph_ - > running ( ) & & ! stop ) _ {
* 3 - Read control messages and process them }
*/
2018-10-23 14:54:06 +00:00
int ControlThread : : run ( )
2011-10-01 18:45:20 +00:00
{
2012-11-01 16:39:06 +00:00
// Connect the flowgraph
2021-01-24 23:49:36 +00:00
if ( ! flowgraph_ )
{
print_help_at_exit ( ) ;
return 0 ;
}
2018-05-01 21:32:52 +00:00
try
{
flowgraph_ - > connect ( ) ;
}
2018-05-15 16:31:34 +00:00
catch ( const std : : exception & e )
2018-05-01 21:32:52 +00:00
{
LOG ( ERROR ) < < e . what ( ) ;
2018-10-23 14:54:06 +00:00
return 0 ;
2018-05-01 21:32:52 +00:00
}
2011-10-01 18:45:20 +00:00
if ( flowgraph_ - > connected ( ) )
2011-12-28 21:36:45 +00:00
{
2014-03-16 19:58:29 +00:00
LOG ( INFO ) < < " Flowgraph connected " ;
2011-12-28 21:36:45 +00:00
}
2011-10-01 18:45:20 +00:00
else
2011-12-28 21:36:45 +00:00
{
2018-10-23 14:54:06 +00:00
return 0 ;
2011-12-28 21:36:45 +00:00
}
2012-11-01 16:39:06 +00:00
// Start the flowgraph
2011-10-01 18:45:20 +00:00
flowgraph_ - > start ( ) ;
if ( flowgraph_ - > running ( ) )
2011-12-28 21:36:45 +00:00
{
2014-03-16 19:58:29 +00:00
LOG ( INFO ) < < " Flowgraph started " ;
2011-12-28 21:36:45 +00:00
}
2011-10-01 18:45:20 +00:00
else
2011-12-28 21:36:45 +00:00
{
2018-10-23 14:54:06 +00:00
return 0 ;
2011-12-28 21:36:45 +00:00
}
2016-05-03 10:34:38 +00:00
2018-11-08 14:34:58 +00:00
// launch GNSS assistance process AFTER the flowgraph is running because the GNU Radio asynchronous queues must be already running to transport msgs
2016-05-03 10:34:38 +00:00
assist_GNSS ( ) ;
2012-03-16 12:04:36 +00:00
// start the keyboard_listener thread
2021-10-04 18:59:12 +00:00
if ( FLAGS_keyboard )
{
keyboard_thread_ = std : : thread ( & ControlThread : : keyboard_listener , this ) ;
}
2019-02-24 12:22:52 +00:00
sysv_queue_thread_ = std : : thread ( & ControlThread : : sysv_queue_listener , this ) ;
2012-03-16 12:04:36 +00:00
2018-11-08 14:34:58 +00:00
// start the telecommand listener thread
2018-11-06 13:39:57 +00:00
cmd_interface_ . set_pvt ( flowgraph_ - > get_pvt ( ) ) ;
2019-02-24 12:22:52 +00:00
cmd_interface_thread_ = std : : thread ( & ControlThread : : telecommand_listener , this ) ;
2018-10-19 12:54:03 +00:00
2019-02-13 16:48:14 +00:00
# ifdef ENABLE_FPGA
2019-02-27 16:27:31 +00:00
// Create a task for the acquisition such that id doesn't block the flow of the control thread
fpga_helper_thread_ = boost : : thread ( & GNSSFlowgraph : : start_acquisition_helper ,
flowgraph_ ) ;
2019-02-13 16:48:14 +00:00
# endif
2011-10-01 18:45:20 +00:00
// Main loop to read and process the control messages
2019-07-17 13:56:30 +00:00
pmt : : pmt_t msg ;
2011-10-01 18:45:20 +00:00
while ( flowgraph_ - > running ( ) & & ! stop_ )
2011-12-28 21:36:45 +00:00
{
2019-07-28 10:01:11 +00:00
// read event messages, triggered by event signaling with a 100 ms timeout to perform low priority receiver management tasks
2019-07-17 13:56:30 +00:00
bool valid_event = control_queue_ - > timed_wait_and_pop ( msg , 100 ) ;
2019-07-28 10:01:11 +00:00
// call the new sat dispatcher and receiver controller
2019-07-19 16:49:42 +00:00
event_dispatcher ( valid_event , msg ) ;
2011-12-28 21:36:45 +00:00
}
2020-07-07 16:53:50 +00:00
std : : cout < < " Stopping GNSS-SDR, please wait! \n " ;
2013-03-20 18:19:26 +00:00
flowgraph_ - > stop ( ) ;
2015-12-30 13:43:32 +00:00
stop_ = true ;
2018-04-23 05:41:13 +00:00
flowgraph_ - > disconnect ( ) ;
2013-08-27 14:32:44 +00:00
2019-02-13 16:48:14 +00:00
# ifdef ENABLE_FPGA
// trigger a HW reset
// The HW reset causes any HW accelerator module that is waiting for more samples to complete its calculations
// to trigger an interrupt and finish its signal processing tasks immediately. In this way all SW threads that
// are waiting for interrupts in the HW can exit in a normal way.
2019-02-27 16:27:31 +00:00
flowgraph_ - > perform_hw_reset ( ) ;
2019-02-28 20:45:30 +00:00
fpga_helper_thread_ . try_join_until ( boost : : chrono : : steady_clock : : now ( ) + boost : : chrono : : milliseconds ( 1000 ) ) ;
2019-02-13 16:48:14 +00:00
# endif
2019-02-24 12:22:52 +00:00
// Terminate keyboard thread
2021-10-04 18:59:12 +00:00
if ( FLAGS_keyboard & & keyboard_thread_ . joinable ( ) )
2020-07-19 23:20:15 +00:00
{
pthread_t id = keyboard_thread_ . native_handle ( ) ;
keyboard_thread_ . detach ( ) ;
2021-11-22 16:47:00 +00:00
# ifndef ANDROID
2020-07-19 23:20:15 +00:00
pthread_cancel ( id ) ;
2021-11-22 16:47:00 +00:00
# else
//todo: find alternative
# endif
2020-07-19 23:20:15 +00:00
}
2018-10-23 14:54:06 +00:00
2020-07-19 23:20:15 +00:00
// Terminate telecommand thread
2020-06-27 07:52:59 +00:00
if ( telecommand_enabled_ )
{
pthread_t id2 = cmd_interface_thread_ . native_handle ( ) ;
cmd_interface_thread_ . detach ( ) ;
2021-11-22 16:47:00 +00:00
# ifndef ANDROID
2020-06-27 07:52:59 +00:00
pthread_cancel ( id2 ) ;
2021-11-22 16:47:00 +00:00
# else
//todo: find alternative
# endif
}
2020-06-27 07:52:59 +00:00
2014-03-16 19:58:29 +00:00
LOG ( INFO ) < < " Flowgraph stopped " ;
2018-10-23 14:54:06 +00:00
if ( restart_ )
{
2018-11-24 08:40:15 +00:00
return 42 ; // signal the gnss-sdr-harness.sh to restart the receiver program
2018-10-23 14:54:06 +00:00
}
2018-12-03 21:08:19 +00:00
return 0 ; // normal shutdown
2011-10-01 18:45:20 +00:00
}
2012-11-01 16:39:06 +00:00
2020-06-19 10:39:28 +00:00
void ControlThread : : set_control_queue ( std : : shared_ptr < Concurrent_Queue < pmt : : pmt_t > > control_queue )
2011-10-01 18:45:20 +00:00
{
if ( flowgraph_ - > running ( ) )
2011-12-28 21:36:45 +00:00
{
2014-03-16 19:58:29 +00:00
LOG ( WARNING ) < < " Unable to set control queue while flowgraph is running " ;
2011-12-28 21:36:45 +00:00
return ;
}
2020-06-19 10:39:28 +00:00
control_queue_ = std : : move ( control_queue ) ;
2018-10-23 14:54:06 +00:00
cmd_interface_ . set_msg_queue ( control_queue_ ) ;
2011-10-01 18:45:20 +00:00
}
2011-12-27 21:21:12 +00:00
2014-04-28 14:27:47 +00:00
/*
* Returns true if reading was successful
*/
2016-04-13 14:19:15 +00:00
bool ControlThread : : read_assistance_from_XML ( )
{
// return variable (true == succeeded)
bool ret = false ;
// getting names from the config file, if available
2020-06-19 10:39:28 +00:00
std : : string eph_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gps_ephemeris_xml " , eph_default_xml_filename_ ) ;
std : : string utc_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gps_utc_model_xml " , utc_default_xml_filename_ ) ;
std : : string iono_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gps_iono_xml " , iono_default_xml_filename_ ) ;
std : : string gal_iono_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gal_iono_xml " , gal_iono_default_xml_filename_ ) ;
std : : string ref_time_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gps_ref_time_xml " , ref_time_default_xml_filename_ ) ;
std : : string ref_location_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gps_ref_location_xml " , ref_location_default_xml_filename_ ) ;
std : : string eph_gal_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gal_ephemeris_xml " , eph_gal_default_xml_filename_ ) ;
std : : string eph_cnav_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gps_cnav_ephemeris_xml " , eph_cnav_default_xml_filename_ ) ;
std : : string gal_utc_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gal_utc_model_xml " , gal_utc_default_xml_filename_ ) ;
std : : string cnav_utc_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_cnav_utc_model_xml " , cnav_utc_default_xml_filename_ ) ;
std : : string eph_glo_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_glo_ephemeris_xml " , eph_glo_gnav_default_xml_filename_ ) ;
std : : string glo_utc_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_glo_utc_model_xml " , glo_utc_default_xml_filename_ ) ;
std : : string gal_almanac_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gal_almanac_xml " , gal_almanac_default_xml_filename_ ) ;
std : : string gps_almanac_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gps_almanac_xml " , gps_almanac_default_xml_filename_ ) ;
2018-10-18 07:29:21 +00:00
2018-10-21 11:58:29 +00:00
if ( configuration_ - > property ( " GNSS-SDR.AGNSS_XML_enabled " , false ) = = true )
{
2020-06-19 10:39:28 +00:00
eph_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_gps_ephemeris_xml " , eph_default_xml_filename_ ) ;
utc_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_gps_utc_model_xml " , utc_default_xml_filename_ ) ;
iono_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_gps_iono_xml " , iono_default_xml_filename_ ) ;
gal_iono_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_gal_iono_xml " , gal_iono_default_xml_filename_ ) ;
ref_time_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_gps_ref_time_xml " , ref_time_default_xml_filename_ ) ;
ref_location_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_gps_ref_location_xml " , ref_location_default_xml_filename_ ) ;
eph_gal_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_gal_ephemeris_xml " , eph_gal_default_xml_filename_ ) ;
eph_cnav_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_gps_cnav_ephemeris_xml " , eph_cnav_default_xml_filename_ ) ;
gal_utc_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_gal_utc_model_xml " , gal_utc_default_xml_filename_ ) ;
cnav_utc_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_cnav_utc_model_xml " , cnav_utc_default_xml_filename_ ) ;
eph_glo_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_glo_ephemeris_xml " , eph_glo_gnav_default_xml_filename_ ) ;
glo_utc_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_glo_utc_model_xml " , glo_utc_default_xml_filename_ ) ;
gal_almanac_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_gal_almanac_xml " , gal_almanac_default_xml_filename_ ) ;
gps_almanac_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_gps_almanac_xml " , gps_almanac_default_xml_filename_ ) ;
2018-10-21 11:58:29 +00:00
}
2018-10-18 07:29:21 +00:00
2020-07-07 16:53:50 +00:00
std : : cout < < " Trying to read GNSS ephemeris from XML file(s)... \n " ;
2018-10-18 07:29:21 +00:00
2018-10-20 12:46:55 +00:00
if ( configuration_ - > property ( " Channels_1C.count " , 0 ) > 0 )
2016-04-13 14:19:15 +00:00
{
2018-10-20 12:46:55 +00:00
if ( supl_client_ephemeris_ . load_ephemeris_xml ( eph_xml_filename ) = = true )
2016-04-13 14:19:15 +00:00
{
2018-10-20 12:46:55 +00:00
std : : map < int , Gps_Ephemeris > : : const_iterator gps_eph_iter ;
for ( gps_eph_iter = supl_client_ephemeris_ . gps_ephemeris_map . cbegin ( ) ;
gps_eph_iter ! = supl_client_ephemeris_ . gps_ephemeris_map . cend ( ) ;
gps_eph_iter + + )
{
2021-02-20 23:01:56 +00:00
std : : cout < < " From XML file: Read NAV ephemeris for satellite " < < Gnss_Satellite ( " GPS " , gps_eph_iter - > second . PRN ) < < ' \n ' ;
2020-07-19 07:39:32 +00:00
const std : : shared_ptr < Gps_Ephemeris > tmp_obj = std : : make_shared < Gps_Ephemeris > ( gps_eph_iter - > second ) ;
2018-10-20 12:46:55 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
}
ret = true ;
2016-04-13 14:19:15 +00:00
}
2018-10-17 18:39:06 +00:00
2018-10-20 12:46:55 +00:00
if ( supl_client_acquisition_ . load_utc_xml ( utc_xml_filename ) = = true )
2016-04-13 14:19:15 +00:00
{
2020-07-19 07:39:32 +00:00
const std : : shared_ptr < Gps_Utc_Model > tmp_obj = std : : make_shared < Gps_Utc_Model > ( supl_client_acquisition_ . gps_utc ) ;
2016-04-13 14:19:15 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
2020-07-07 16:53:50 +00:00
std : : cout < < " From XML file: Read GPS UTC model parameters. \n " ;
2018-10-20 12:46:55 +00:00
ret = true ;
2016-04-13 14:19:15 +00:00
}
2018-10-17 18:39:06 +00:00
2018-10-20 12:46:55 +00:00
if ( supl_client_acquisition_ . load_iono_xml ( iono_xml_filename ) = = true )
2018-10-17 16:22:04 +00:00
{
2020-07-19 07:39:32 +00:00
const std : : shared_ptr < Gps_Iono > tmp_obj = std : : make_shared < Gps_Iono > ( supl_client_acquisition_ . gps_iono ) ;
2018-10-17 16:22:04 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
2020-07-07 16:53:50 +00:00
std : : cout < < " From XML file: Read GPS ionosphere model parameters. \n " ;
2018-10-20 12:46:55 +00:00
ret = true ;
2018-10-17 16:22:04 +00:00
}
2018-10-25 09:01:29 +00:00
if ( supl_client_ephemeris_ . load_gps_almanac_xml ( gps_almanac_xml_filename ) = = true )
{
std : : map < int , Gps_Almanac > : : const_iterator gps_alm_iter ;
for ( gps_alm_iter = supl_client_ephemeris_ . gps_almanac_map . cbegin ( ) ;
gps_alm_iter ! = supl_client_ephemeris_ . gps_almanac_map . cend ( ) ;
gps_alm_iter + + )
{
2021-02-20 23:01:56 +00:00
std : : cout < < " From XML file: Read GPS almanac for satellite " < < Gnss_Satellite ( " GPS " , gps_alm_iter - > second . PRN ) < < ' \n ' ;
2020-07-19 07:39:32 +00:00
const std : : shared_ptr < Gps_Almanac > tmp_obj = std : : make_shared < Gps_Almanac > ( gps_alm_iter - > second ) ;
2018-10-25 09:01:29 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
}
ret = true ;
}
2018-10-17 16:22:04 +00:00
}
2018-10-17 18:39:06 +00:00
2018-10-20 12:46:55 +00:00
if ( ( configuration_ - > property ( " Channels_1B.count " , 0 ) > 0 ) or ( configuration_ - > property ( " Channels_5X.count " , 0 ) > 0 ) )
2018-10-17 17:17:37 +00:00
{
2018-10-20 12:46:55 +00:00
if ( supl_client_ephemeris_ . load_gal_ephemeris_xml ( eph_gal_xml_filename ) = = true )
2018-10-17 17:17:37 +00:00
{
2018-10-20 12:46:55 +00:00
std : : map < int , Galileo_Ephemeris > : : const_iterator gal_eph_iter ;
for ( gal_eph_iter = supl_client_ephemeris_ . gal_ephemeris_map . cbegin ( ) ;
gal_eph_iter ! = supl_client_ephemeris_ . gal_ephemeris_map . cend ( ) ;
gal_eph_iter + + )
{
2021-02-20 23:01:56 +00:00
std : : cout < < " From XML file: Read ephemeris for satellite " < < Gnss_Satellite ( " Galileo " , gal_eph_iter - > second . PRN ) < < ' \n ' ;
2020-07-19 07:39:32 +00:00
const std : : shared_ptr < Galileo_Ephemeris > tmp_obj = std : : make_shared < Galileo_Ephemeris > ( gal_eph_iter - > second ) ;
2018-10-20 12:46:55 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
}
ret = true ;
}
2018-10-18 13:46:48 +00:00
2018-10-20 12:46:55 +00:00
if ( supl_client_acquisition_ . load_gal_iono_xml ( gal_iono_xml_filename ) = = true )
{
2020-07-19 07:39:32 +00:00
const std : : shared_ptr < Galileo_Iono > tmp_obj = std : : make_shared < Galileo_Iono > ( supl_client_acquisition_ . gal_iono ) ;
2018-10-17 17:17:37 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
2020-07-07 16:53:50 +00:00
std : : cout < < " From XML file: Read Galileo ionosphere model parameters. \n " ;
2018-10-20 12:46:55 +00:00
ret = true ;
2018-10-17 17:17:37 +00:00
}
2018-10-18 13:46:48 +00:00
2018-10-20 12:46:55 +00:00
if ( supl_client_acquisition_ . load_gal_utc_xml ( gal_utc_xml_filename ) = = true )
{
2020-07-19 07:39:32 +00:00
const std : : shared_ptr < Galileo_Utc_Model > tmp_obj = std : : make_shared < Galileo_Utc_Model > ( supl_client_acquisition_ . gal_utc ) ;
2018-10-20 12:46:55 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
2020-07-07 16:53:50 +00:00
std : : cout < < " From XML file: Read Galileo UTC model parameters. \n " ;
2018-10-20 12:46:55 +00:00
ret = true ;
}
2018-10-24 22:43:25 +00:00
if ( supl_client_ephemeris_ . load_gal_almanac_xml ( gal_almanac_xml_filename ) = = true )
{
std : : map < int , Galileo_Almanac > : : const_iterator gal_alm_iter ;
for ( gal_alm_iter = supl_client_ephemeris_ . gal_almanac_map . cbegin ( ) ;
gal_alm_iter ! = supl_client_ephemeris_ . gal_almanac_map . cend ( ) ;
gal_alm_iter + + )
{
2021-02-20 23:01:56 +00:00
std : : cout < < " From XML file: Read Galileo almanac for satellite " < < Gnss_Satellite ( " Galileo " , gal_alm_iter - > second . PRN ) < < ' \n ' ;
2020-07-19 07:39:32 +00:00
const std : : shared_ptr < Galileo_Almanac > tmp_obj = std : : make_shared < Galileo_Almanac > ( gal_alm_iter - > second ) ;
2018-10-24 22:43:25 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
}
ret = true ;
}
2018-10-18 13:46:48 +00:00
}
2018-10-20 12:46:55 +00:00
if ( ( configuration_ - > property ( " Channels_2S.count " , 0 ) > 0 ) or ( configuration_ - > property ( " Channels_L5.count " , 0 ) > 0 ) )
2018-10-18 13:46:48 +00:00
{
2018-10-20 12:46:55 +00:00
if ( supl_client_ephemeris_ . load_cnav_ephemeris_xml ( eph_cnav_xml_filename ) = = true )
{
std : : map < int , Gps_CNAV_Ephemeris > : : const_iterator gps_cnav_eph_iter ;
for ( gps_cnav_eph_iter = supl_client_ephemeris_ . gps_cnav_ephemeris_map . cbegin ( ) ;
gps_cnav_eph_iter ! = supl_client_ephemeris_ . gps_cnav_ephemeris_map . cend ( ) ;
gps_cnav_eph_iter + + )
{
2021-02-20 23:01:56 +00:00
std : : cout < < " From XML file: Read CNAV ephemeris for satellite " < < Gnss_Satellite ( " GPS " , gps_cnav_eph_iter - > second . PRN ) < < ' \n ' ;
2020-07-19 07:39:32 +00:00
const std : : shared_ptr < Gps_CNAV_Ephemeris > tmp_obj = std : : make_shared < Gps_CNAV_Ephemeris > ( gps_cnav_eph_iter - > second ) ;
2018-10-20 12:46:55 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
}
ret = true ;
}
2018-10-18 13:46:48 +00:00
2018-10-20 12:46:55 +00:00
if ( supl_client_acquisition_ . load_cnav_utc_xml ( cnav_utc_xml_filename ) = = true )
{
2020-07-19 07:39:32 +00:00
const std : : shared_ptr < Gps_CNAV_Utc_Model > tmp_obj = std : : make_shared < Gps_CNAV_Utc_Model > ( supl_client_acquisition_ . gps_cnav_utc ) ;
2018-10-20 12:46:55 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
2020-07-07 16:53:50 +00:00
std : : cout < < " From XML file: Read GPS CNAV UTC model parameters. \n " ;
2018-10-20 12:46:55 +00:00
ret = true ;
}
2018-10-18 13:46:48 +00:00
}
2018-10-20 17:30:32 +00:00
if ( ( configuration_ - > property ( " Channels_1G.count " , 0 ) > 0 ) or ( configuration_ - > property ( " Channels_2G.count " , 0 ) > 0 ) )
2018-10-18 13:46:48 +00:00
{
2018-10-20 17:30:32 +00:00
if ( supl_client_ephemeris_ . load_gnav_ephemeris_xml ( eph_glo_xml_filename ) = = true )
{
std : : map < int , Glonass_Gnav_Ephemeris > : : const_iterator glo_gnav_eph_iter ;
for ( glo_gnav_eph_iter = supl_client_ephemeris_ . glonass_gnav_ephemeris_map . cbegin ( ) ;
glo_gnav_eph_iter ! = supl_client_ephemeris_ . glonass_gnav_ephemeris_map . cend ( ) ;
glo_gnav_eph_iter + + )
{
2021-02-20 23:01:56 +00:00
std : : cout < < " From XML file: Read GLONASS GNAV ephemeris for satellite " < < Gnss_Satellite ( " GLONASS " , glo_gnav_eph_iter - > second . PRN ) < < ' \n ' ;
2020-07-19 07:39:32 +00:00
const std : : shared_ptr < Glonass_Gnav_Ephemeris > tmp_obj = std : : make_shared < Glonass_Gnav_Ephemeris > ( glo_gnav_eph_iter - > second ) ;
2018-10-20 17:30:32 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
}
ret = true ;
}
2018-10-18 13:46:48 +00:00
2018-10-20 17:30:32 +00:00
if ( supl_client_acquisition_ . load_glo_utc_xml ( glo_utc_xml_filename ) = = true )
{
2020-07-19 07:39:32 +00:00
const std : : shared_ptr < Glonass_Gnav_Utc_Model > tmp_obj = std : : make_shared < Glonass_Gnav_Utc_Model > ( supl_client_acquisition_ . glo_gnav_utc ) ;
2018-10-20 17:30:32 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
2020-07-07 16:53:50 +00:00
std : : cout < < " From XML file: Read GLONASS UTC model parameters. \n " ;
2018-10-20 17:30:32 +00:00
ret = true ;
}
2018-10-19 12:48:41 +00:00
}
2018-10-17 18:39:06 +00:00
if ( ret = = false )
2016-04-13 14:19:15 +00:00
{
2020-07-07 16:53:50 +00:00
std : : cout < < " Error reading XML files \n " ;
std : : cout < < " Disabling GNSS assistance... \n " ;
2016-04-13 14:19:15 +00:00
}
2018-10-18 13:46:48 +00:00
// Only look for {ref time, ref location} if SUPL is enabled
2020-07-19 07:39:32 +00:00
const bool enable_gps_supl_assistance = configuration_ - > property ( " GNSS-SDR.SUPL_gps_enabled " , false ) ;
2016-04-13 14:19:15 +00:00
if ( enable_gps_supl_assistance = = true )
{
// Try to read Ref Time from XML
if ( supl_client_acquisition_ . load_ref_time_xml ( ref_time_xml_filename ) = = true )
{
LOG ( INFO ) < < " SUPL: Read XML Ref Time " ;
2020-07-19 07:39:32 +00:00
const std : : shared_ptr < Agnss_Ref_Time > tmp_obj = std : : make_shared < Agnss_Ref_Time > ( supl_client_acquisition_ . gps_time ) ;
2016-04-13 14:19:15 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
}
else
{
2018-10-21 15:55:06 +00:00
LOG ( INFO ) < < " SUPL: could not read Ref Time XML " ;
2016-04-13 14:19:15 +00:00
}
2013-11-17 10:48:27 +00:00
2016-04-13 14:19:15 +00:00
// Try to read Ref Location from XML
if ( supl_client_acquisition_ . load_ref_location_xml ( ref_location_xml_filename ) = = true )
{
LOG ( INFO ) < < " SUPL: Read XML Ref Location " ;
2020-07-19 07:39:32 +00:00
const std : : shared_ptr < Agnss_Ref_Location > tmp_obj = std : : make_shared < Agnss_Ref_Location > ( supl_client_acquisition_ . gps_ref_loc ) ;
2016-04-13 14:19:15 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
}
else
{
2018-10-21 15:55:06 +00:00
LOG ( INFO ) < < " SUPL: could not read Ref Location XML " ;
2016-04-13 14:19:15 +00:00
}
}
return ret ;
}
2018-05-01 21:32:52 +00:00
2016-05-03 10:34:38 +00:00
void ControlThread : : assist_GNSS ( )
2011-10-01 18:45:20 +00:00
{
2019-07-28 10:01:11 +00:00
// ######### GNSS Assistance #################################
2013-11-17 10:48:27 +00:00
// GNSS Assistance configuration
2020-07-19 07:39:32 +00:00
const bool enable_gps_supl_assistance = configuration_ - > property ( " GNSS-SDR.SUPL_gps_enabled " , false ) ;
const bool enable_agnss_xml = configuration_ - > property ( " GNSS-SDR.AGNSS_XML_enabled " , false ) ;
2018-10-21 15:55:06 +00:00
if ( ( enable_gps_supl_assistance = = true ) and ( enable_agnss_xml = = false ) )
2013-11-17 10:48:27 +00:00
{
2020-07-07 16:53:50 +00:00
std : : cout < < " SUPL RRLP GPS assistance enabled! \n " ;
2020-07-19 07:39:32 +00:00
const std : : string default_acq_server ( " supl.google.com " ) ;
const std : : string default_eph_server ( " supl.google.com " ) ;
2013-11-17 10:48:27 +00:00
supl_client_ephemeris_ . server_name = configuration_ - > property ( " GNSS-SDR.SUPL_gps_ephemeris_server " , default_acq_server ) ;
supl_client_acquisition_ . server_name = configuration_ - > property ( " GNSS-SDR.SUPL_gps_acquisition_server " , default_eph_server ) ;
supl_client_ephemeris_ . server_port = configuration_ - > property ( " GNSS-SDR.SUPL_gps_ephemeris_port " , 7275 ) ;
supl_client_acquisition_ . server_port = configuration_ - > property ( " GNSS-SDR.SUPL_gps_acquisition_port " , 7275 ) ;
2020-06-19 10:39:28 +00:00
supl_mcc_ = configuration_ - > property ( " GNSS-SDR.SUPL_MCC " , 244 ) ;
supl_mns_ = configuration_ - > property ( " GNSS-SDR.SUPL_MNC " , 5 ) ;
2013-11-17 10:48:27 +00:00
2020-07-19 07:39:32 +00:00
const std : : string default_lac ( " 0x59e2 " ) ;
const std : : string default_ci ( " 0x31b0 " ) ;
const std : : string supl_lac_s = configuration_ - > property ( " GNSS-SDR.SUPL_LAC " , default_lac ) ;
const std : : string supl_ci_s = configuration_ - > property ( " GNSS-SDR.SUPL_CI " , default_ci ) ;
2013-11-17 10:48:27 +00:00
try
2018-03-03 01:03:39 +00:00
{
2020-06-19 10:39:28 +00:00
supl_lac_ = std : : stoi ( supl_lac_s , nullptr , 0 ) ;
2018-03-03 01:03:39 +00:00
}
2018-10-22 12:56:02 +00:00
catch ( const std : : invalid_argument & ia )
2018-03-03 01:03:39 +00:00
{
2018-10-22 12:56:02 +00:00
std : : cerr < < " Invalid argument for SUPL LAC: " < < ia . what ( ) < < ' \n ' ;
2020-06-19 10:39:28 +00:00
supl_lac_ = - 1 ;
2018-03-03 01:03:39 +00:00
}
2013-11-17 10:48:27 +00:00
try
2018-03-03 01:03:39 +00:00
{
2020-06-19 10:39:28 +00:00
supl_ci_ = std : : stoi ( supl_ci_s , nullptr , 0 ) ;
2018-03-03 01:03:39 +00:00
}
2018-10-22 12:56:02 +00:00
catch ( const std : : invalid_argument & ia )
{
std : : cerr < < " Invalid argument for SUPL CI: " < < ia . what ( ) < < ' \n ' ;
2020-06-19 10:39:28 +00:00
supl_ci_ = - 1 ;
2018-10-22 12:56:02 +00:00
}
2020-06-19 10:39:28 +00:00
if ( supl_lac_ < 0 or supl_lac_ > 65535 )
2018-10-22 12:56:02 +00:00
{
2020-06-19 10:39:28 +00:00
supl_lac_ = 0x59e2 ;
2018-10-22 12:56:02 +00:00
}
2020-06-19 10:39:28 +00:00
if ( supl_ci_ < 0 or supl_ci_ > 268435455 ) // 2^16 for GSM and CDMA, 2^28 for UMTS and LTE networks
2018-03-03 01:03:39 +00:00
{
2020-06-19 10:39:28 +00:00
supl_ci_ = 0x31b0 ;
2018-03-03 01:03:39 +00:00
}
2013-11-17 10:48:27 +00:00
2020-07-19 07:39:32 +00:00
const bool SUPL_read_gps_assistance_xml = configuration_ - > property ( " GNSS-SDR.SUPL_read_gps_assistance_xml " , false ) ;
2013-11-17 10:48:27 +00:00
if ( SUPL_read_gps_assistance_xml = = true )
{
2018-11-24 08:40:15 +00:00
// Read assistance from file
2016-05-04 17:15:18 +00:00
if ( read_assistance_from_XML ( ) )
{
2020-07-07 16:53:50 +00:00
std : : cout < < " GNSS assistance data loaded from local XML file(s). \n " ;
std : : cout < < " No SUPL request has been performed. \n " ;
2016-05-04 17:15:18 +00:00
}
2013-11-17 10:48:27 +00:00
}
else
{
// Request ephemeris from SUPL server
supl_client_ephemeris_ . request = 1 ;
2020-07-07 16:53:50 +00:00
std : : cout < < " SUPL: Try to read GPS ephemeris data from SUPL server... \n " ;
2020-07-19 07:39:32 +00:00
int error = supl_client_ephemeris_ . get_assistance ( supl_mcc_ , supl_mns_ , supl_lac_ , supl_ci_ ) ;
2013-11-17 10:48:27 +00:00
if ( error = = 0 )
{
2018-03-03 01:03:39 +00:00
std : : map < int , Gps_Ephemeris > : : const_iterator gps_eph_iter ;
for ( gps_eph_iter = supl_client_ephemeris_ . gps_ephemeris_map . cbegin ( ) ;
gps_eph_iter ! = supl_client_ephemeris_ . gps_ephemeris_map . cend ( ) ;
gps_eph_iter + + )
2013-11-17 10:48:27 +00:00
{
2021-02-20 23:01:56 +00:00
std : : cout < < " SUPL: Received ephemeris data for satellite " < < Gnss_Satellite ( " GPS " , gps_eph_iter - > second . PRN ) < < ' \n ' ;
2020-07-19 23:20:15 +00:00
const std : : shared_ptr < Gps_Ephemeris > tmp_obj = std : : make_shared < Gps_Ephemeris > ( gps_eph_iter - > second ) ;
2016-04-13 14:19:15 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
2013-11-17 10:48:27 +00:00
}
2018-10-21 11:58:29 +00:00
// Save ephemeris to XML file
2020-07-19 23:20:15 +00:00
const std : : string eph_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gps_ephemeris_xml " , eph_default_xml_filename_ ) ;
2014-04-28 14:27:47 +00:00
if ( supl_client_ephemeris_ . save_ephemeris_map_xml ( eph_xml_filename , supl_client_ephemeris_ . gps_ephemeris_map ) = = true )
2013-11-17 10:48:27 +00:00
{
2020-07-07 16:53:50 +00:00
std : : cout < < " SUPL: XML ephemeris data file created \n " ;
2013-11-17 10:48:27 +00:00
}
2014-04-28 14:27:47 +00:00
else
{
2020-07-07 16:53:50 +00:00
std : : cout < < " SUPL: Failed to create XML ephemeris data file \n " ;
2014-04-28 14:27:47 +00:00
}
2013-11-17 10:48:27 +00:00
}
else
{
2020-07-07 16:53:50 +00:00
std : : cout < < " ERROR: SUPL client request for ephemeris data returned " < < error < < ' \n ' ;
std : : cout < < " Please check your network connectivity and SUPL server configuration \n " ;
std : : cout < < " Trying to read AGNSS data from local XML file(s)... \n " ;
2016-05-03 10:34:38 +00:00
if ( read_assistance_from_XML ( ) = = false )
{
2020-07-07 16:53:50 +00:00
std : : cout < < " ERROR: Could not read XML files: Disabling SUPL assistance. \n " ;
2016-05-03 10:34:38 +00:00
}
2013-11-17 10:48:27 +00:00
}
2018-10-21 11:58:29 +00:00
// Request almanac, IONO and UTC Model data
2013-11-17 10:48:27 +00:00
supl_client_ephemeris_ . request = 0 ;
2020-07-07 16:53:50 +00:00
std : : cout < < " SUPL: Try to read Almanac, Iono, Utc Model, Ref Time and Ref Location data from SUPL server... \n " ;
2020-06-19 10:39:28 +00:00
error = supl_client_ephemeris_ . get_assistance ( supl_mcc_ , supl_mns_ , supl_lac_ , supl_ci_ ) ;
2013-11-17 10:48:27 +00:00
if ( error = = 0 )
{
2018-03-03 01:03:39 +00:00
std : : map < int , Gps_Almanac > : : const_iterator gps_alm_iter ;
for ( gps_alm_iter = supl_client_ephemeris_ . gps_almanac_map . cbegin ( ) ;
gps_alm_iter ! = supl_client_ephemeris_ . gps_almanac_map . cend ( ) ;
gps_alm_iter + + )
2013-11-17 10:48:27 +00:00
{
2021-02-20 23:01:56 +00:00
std : : cout < < " SUPL: Received almanac data for satellite " < < Gnss_Satellite ( " GPS " , gps_alm_iter - > second . PRN ) < < ' \n ' ;
2020-07-19 23:20:15 +00:00
const std : : shared_ptr < Gps_Almanac > tmp_obj = std : : make_shared < Gps_Almanac > ( gps_alm_iter - > second ) ;
2016-04-13 14:19:15 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
2013-11-17 10:48:27 +00:00
}
2018-11-20 15:52:51 +00:00
supl_client_ephemeris_ . save_gps_almanac_xml ( " gps_almanac_map.xml " , supl_client_ephemeris_ . gps_almanac_map ) ;
2013-11-17 10:48:27 +00:00
if ( supl_client_ephemeris_ . gps_iono . valid = = true )
{
2020-07-07 16:53:50 +00:00
std : : cout < < " SUPL: Received GPS Ionosphere model parameters \n " ;
2020-07-19 23:20:15 +00:00
const std : : shared_ptr < Gps_Iono > tmp_obj = std : : make_shared < Gps_Iono > ( supl_client_ephemeris_ . gps_iono ) ;
2016-04-13 14:19:15 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
2013-11-17 10:48:27 +00:00
}
if ( supl_client_ephemeris_ . gps_utc . valid = = true )
2016-05-04 17:15:18 +00:00
{
2020-07-07 16:53:50 +00:00
std : : cout < < " SUPL: Received GPS UTC model parameters \n " ;
2020-07-19 23:20:15 +00:00
const std : : shared_ptr < Gps_Utc_Model > tmp_obj = std : : make_shared < Gps_Utc_Model > ( supl_client_ephemeris_ . gps_utc ) ;
2016-04-13 14:19:15 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
2013-11-17 10:48:27 +00:00
}
2018-10-21 11:58:29 +00:00
// Save iono and UTC model data to xml file
2020-07-19 07:39:32 +00:00
const std : : string iono_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gps_iono_xml " , iono_default_xml_filename_ ) ;
2018-10-21 11:58:29 +00:00
if ( supl_client_ephemeris_ . save_iono_xml ( iono_xml_filename , supl_client_ephemeris_ . gps_iono ) = = true )
{
2020-07-07 16:53:50 +00:00
std : : cout < < " SUPL: Iono data file created \n " ;
2018-10-21 11:58:29 +00:00
}
else
{
2020-07-07 16:53:50 +00:00
std : : cout < < " SUPL: Failed to create Iono data file \n " ;
2018-10-21 11:58:29 +00:00
}
2020-07-19 07:39:32 +00:00
const std : : string utc_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gps_utc_model_xml " , utc_default_xml_filename_ ) ;
2018-10-21 11:58:29 +00:00
if ( supl_client_ephemeris_ . save_utc_xml ( utc_xml_filename , supl_client_ephemeris_ . gps_utc ) = = true )
{
2020-07-07 16:53:50 +00:00
std : : cout < < " SUPL: UTC model data file created \n " ;
2018-10-21 11:58:29 +00:00
}
else
{
2020-07-07 16:53:50 +00:00
std : : cout < < " SUPL: Failed to create UTC model data file \n " ;
2018-10-21 11:58:29 +00:00
}
2013-11-17 10:48:27 +00:00
}
else
{
2020-07-07 16:53:50 +00:00
std : : cout < < " ERROR: SUPL client for almanac data returned " < < error < < ' \n ' ;
std : : cout < < " Please check your network connectivity and SUPL server configuration \n " ;
2013-11-17 10:48:27 +00:00
}
// Request acquisition assistance
supl_client_acquisition_ . request = 2 ;
2020-07-07 16:53:50 +00:00
std : : cout < < " SUPL: Try to read acquisition assistance data from SUPL server... \n " ;
2020-06-19 10:39:28 +00:00
error = supl_client_acquisition_ . get_assistance ( supl_mcc_ , supl_mns_ , supl_lac_ , supl_ci_ ) ;
2013-11-17 10:48:27 +00:00
if ( error = = 0 )
{
2017-08-17 09:03:02 +00:00
std : : map < int , Gps_Acq_Assist > : : const_iterator gps_acq_iter ;
2018-03-03 01:03:39 +00:00
for ( gps_acq_iter = supl_client_acquisition_ . gps_acq_map . cbegin ( ) ;
gps_acq_iter ! = supl_client_acquisition_ . gps_acq_map . cend ( ) ;
gps_acq_iter + + )
2013-11-17 10:48:27 +00:00
{
2021-02-20 23:01:56 +00:00
std : : cout < < " SUPL: Received acquisition assistance data for satellite " < < Gnss_Satellite ( " GPS " , gps_acq_iter - > second . PRN ) < < ' \n ' ;
global_gps_acq_assist_map . write ( gps_acq_iter - > second . PRN , gps_acq_iter - > second ) ;
2013-11-17 10:48:27 +00:00
}
2014-04-25 19:48:52 +00:00
if ( supl_client_acquisition_ . gps_ref_loc . valid = = true )
{
2020-07-07 16:53:50 +00:00
std : : cout < < " SUPL: Received Ref Location data (Acquisition Assistance) \n " ;
2018-11-20 08:28:47 +00:00
agnss_ref_location_ = supl_client_acquisition_ . gps_ref_loc ;
2020-07-19 23:20:15 +00:00
const std : : shared_ptr < Agnss_Ref_Location > tmp_obj = std : : make_shared < Agnss_Ref_Location > ( agnss_ref_location_ ) ;
2016-04-13 14:19:15 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
2018-11-20 09:52:40 +00:00
supl_client_acquisition_ . save_ref_location_xml ( " agnss_ref_location.xml " , agnss_ref_location_ ) ;
2014-04-25 19:48:52 +00:00
}
if ( supl_client_acquisition_ . gps_time . valid = = true )
{
2020-07-07 16:53:50 +00:00
std : : cout < < " SUPL: Received Ref Time data (Acquisition Assistance) \n " ;
2018-11-20 08:28:47 +00:00
agnss_ref_time_ = supl_client_acquisition_ . gps_time ;
2020-07-19 23:20:15 +00:00
const std : : shared_ptr < Agnss_Ref_Time > tmp_obj = std : : make_shared < Agnss_Ref_Time > ( agnss_ref_time_ ) ;
2016-04-13 14:19:15 +00:00
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
2018-11-20 09:52:40 +00:00
supl_client_acquisition_ . save_ref_time_xml ( " agnss_ref_time.xml " , agnss_ref_time_ ) ;
2014-04-25 19:48:52 +00:00
}
2013-11-17 10:48:27 +00:00
}
else
{
2020-07-07 16:53:50 +00:00
std : : cout < < " ERROR: SUPL client for acquisition assistance returned " < < error < < ' \n ' ;
std : : cout < < " Please check your network connectivity and SUPL server configuration \n " ;
std : : cout < < " Disabling SUPL acquisition assistance. \n " ;
2013-11-17 10:48:27 +00:00
}
}
}
2018-10-21 15:55:06 +00:00
if ( ( enable_gps_supl_assistance = = false ) and ( enable_agnss_xml = = true ) )
2018-10-21 11:58:29 +00:00
{
// read assistance from file
if ( read_assistance_from_XML ( ) )
{
2020-07-07 16:53:50 +00:00
std : : cout < < " GNSS assistance data loaded from local XML file(s). \n " ;
2018-10-21 11:58:29 +00:00
}
}
2018-11-20 08:28:47 +00:00
2018-11-24 08:40:15 +00:00
// If AGNSS is enabled, make use of it
2018-11-23 15:38:20 +00:00
if ( ( agnss_ref_location_ . valid = = true ) and ( ( enable_gps_supl_assistance = = true ) or ( enable_agnss_xml = = true ) ) )
2018-11-20 08:28:47 +00:00
{
// Get the list of visible satellites
2019-07-21 10:55:59 +00:00
std : : array < float , 3 > ref_LLH { } ;
ref_LLH [ 0 ] = agnss_ref_location_ . lat ;
ref_LLH [ 1 ] = agnss_ref_location_ . lon ;
2018-11-20 08:28:47 +00:00
time_t ref_rx_utc_time = 0 ;
2018-11-20 11:46:38 +00:00
if ( agnss_ref_time_ . valid = = true )
{
2021-02-23 10:57:24 +00:00
ref_rx_utc_time = static_cast < time_t > ( agnss_ref_time_ . seconds ) ;
2018-11-20 11:46:38 +00:00
}
2020-07-19 23:20:15 +00:00
const std : : vector < std : : pair < int , Gnss_Satellite > > visible_sats = get_visible_sats ( ref_rx_utc_time , ref_LLH ) ;
2018-11-20 08:28:47 +00:00
// Set the receiver in Standby mode
flowgraph_ - > apply_action ( 0 , 10 ) ;
// Give priority to visible satellites in the search list
flowgraph_ - > priorize_satellites ( visible_sats ) ;
2018-11-20 11:46:38 +00:00
// Hot Start
flowgraph_ - > apply_action ( 0 , 12 ) ;
2018-11-20 08:28:47 +00:00
}
2011-10-01 18:45:20 +00:00
}
2016-05-04 17:15:18 +00:00
2019-07-20 00:53:31 +00:00
2011-10-01 18:45:20 +00:00
void ControlThread : : apply_action ( unsigned int what )
{
2018-11-05 16:53:53 +00:00
std : : shared_ptr < PvtInterface > pvt_ptr ;
std : : vector < std : : pair < int , Gnss_Satellite > > visible_satellites ;
2019-07-19 21:26:26 +00:00
applied_actions_ + + ;
2011-10-01 18:45:20 +00:00
switch ( what )
2018-03-03 01:03:39 +00:00
{
case 0 :
2018-11-06 13:39:57 +00:00
LOG ( INFO ) < < " Received action STOP " ;
2018-03-03 01:03:39 +00:00
stop_ = true ;
break ;
2018-10-23 14:54:06 +00:00
case 1 :
2018-11-06 13:39:57 +00:00
LOG ( INFO ) < < " Received action RESTART " ;
2018-10-23 14:54:06 +00:00
stop_ = true ;
restart_ = true ;
break ;
2019-07-25 14:38:19 +00:00
case 10 : // request standby mode
LOG ( INFO ) < < " TC request standby mode " ;
receiver_on_standby_ = true ;
break ;
2018-11-06 13:39:57 +00:00
case 11 :
LOG ( INFO ) < < " Receiver action COLDSTART " ;
2018-11-24 08:40:15 +00:00
// delete all ephemeris and almanac information from maps (also the PVT map queue)
2018-11-06 13:39:57 +00:00
pvt_ptr = flowgraph_ - > get_pvt ( ) ;
pvt_ptr - > clear_ephemeris ( ) ;
2018-11-24 08:40:15 +00:00
// todo: reorder the satellite queues to the receiver default startup order.
// This is required to allow repeatability. Otherwise the satellite search order will depend on the last tracked satellites
2019-07-25 14:38:19 +00:00
// start again the satellite acquisitions
receiver_on_standby_ = false ;
2018-11-06 13:39:57 +00:00
break ;
2018-11-05 16:53:53 +00:00
case 12 :
2018-11-06 13:39:57 +00:00
LOG ( INFO ) < < " Receiver action HOTSTART " ;
2018-11-05 16:53:53 +00:00
visible_satellites = get_visible_sats ( cmd_interface_ . get_utc_time ( ) , cmd_interface_ . get_LLH ( ) ) ;
2018-11-24 08:40:15 +00:00
// reorder the satellite queue to acquire first those visible satellites
2018-11-05 16:53:53 +00:00
flowgraph_ - > priorize_satellites ( visible_satellites ) ;
2019-07-25 14:38:19 +00:00
// start again the satellite acquisitions
receiver_on_standby_ = false ;
2018-11-05 16:53:53 +00:00
break ;
case 13 :
2018-11-06 13:39:57 +00:00
LOG ( INFO ) < < " Receiver action WARMSTART " ;
2018-11-24 08:40:15 +00:00
// delete all ephemeris and almanac information from maps (also the PVT map queue)
2018-11-05 16:53:53 +00:00
pvt_ptr = flowgraph_ - > get_pvt ( ) ;
pvt_ptr - > clear_ephemeris ( ) ;
2018-11-24 08:40:15 +00:00
// load the ephemeris and the almanac from XML files (receiver assistance)
2018-11-05 16:53:53 +00:00
read_assistance_from_XML ( ) ;
2018-11-24 08:40:15 +00:00
// call here the function that computes the set of visible satellites and its elevation
// for the date and time specified by the warm start command and the assisted position
2018-11-05 16:53:53 +00:00
get_visible_sats ( cmd_interface_ . get_utc_time ( ) , cmd_interface_ . get_LLH ( ) ) ;
2018-11-24 08:40:15 +00:00
// reorder the satellite queue to acquire first those visible satellites
2018-11-05 16:53:53 +00:00
flowgraph_ - > priorize_satellites ( visible_satellites ) ;
2019-07-25 14:38:19 +00:00
// start again the satellite acquisitions
receiver_on_standby_ = false ;
2018-11-05 16:53:53 +00:00
break ;
2018-03-03 01:03:39 +00:00
default :
2018-11-06 13:39:57 +00:00
LOG ( INFO ) < < " Unrecognized action. " ;
2018-03-03 01:03:39 +00:00
break ;
}
2011-10-01 18:45:20 +00:00
}
2018-11-08 14:34:58 +00:00
2019-07-21 10:55:59 +00:00
std : : vector < std : : pair < int , Gnss_Satellite > > ControlThread : : get_visible_sats ( time_t rx_utc_time , const std : : array < float , 3 > & LLH )
2018-11-05 16:53:53 +00:00
{
2018-11-08 14:34:58 +00:00
// 1. Compute rx ECEF position from LLH WGS84
2020-07-19 07:39:32 +00:00
const arma : : vec LLH_rad = arma : : vec { degtorad ( LLH [ 0 ] ) , degtorad ( LLH [ 1 ] ) , LLH [ 2 ] } ;
2018-11-05 16:53:53 +00:00
arma : : mat C_tmp = arma : : zeros ( 3 , 3 ) ;
arma : : vec r_eb_e = arma : : zeros ( 3 , 1 ) ;
arma : : vec v_eb_e = arma : : zeros ( 3 , 1 ) ;
Geo_to_ECEF ( LLH_rad , arma : : vec { 0 , 0 , 0 } , C_tmp , r_eb_e , v_eb_e , C_tmp ) ;
2018-11-08 14:34:58 +00:00
// 2. Compute rx GPS time from UTC time
2018-11-05 16:53:53 +00:00
gtime_t utc_gtime ;
utc_gtime . time = rx_utc_time ;
2019-02-14 21:49:36 +00:00
utc_gtime . sec = 0.0 ;
2020-07-19 23:20:15 +00:00
const gtime_t gps_gtime = utc2gpst ( utc_gtime ) ;
2018-11-05 16:53:53 +00:00
2018-11-08 14:34:58 +00:00
// 3. loop through all the available ephemeris or almanac and compute satellite positions and elevations
2018-11-05 16:53:53 +00:00
// store visible satellites in a vector of pairs <int,Gnss_Satellite> to associate an elevation to the each satellite
std : : vector < std : : pair < int , Gnss_Satellite > > available_satellites ;
2018-11-22 14:19:36 +00:00
std : : vector < unsigned int > visible_gps ;
std : : vector < unsigned int > visible_gal ;
2020-07-19 23:20:15 +00:00
const std : : shared_ptr < PvtInterface > pvt_ptr = flowgraph_ - > get_pvt ( ) ;
2020-07-19 07:39:32 +00:00
struct tm tstruct
{
} ;
2018-11-06 13:39:57 +00:00
char buf [ 80 ] ;
tstruct = * gmtime ( & rx_utc_time ) ;
strftime ( buf , sizeof ( buf ) , " %d/%m/%Y %H:%M:%S " , & tstruct ) ;
2020-07-19 07:39:32 +00:00
const std : : string str_time = std : : string ( buf ) ;
2018-11-06 13:39:57 +00:00
std : : cout < < " Get visible satellites at " < < str_time
2020-07-07 16:53:50 +00:00
< < " UTC, assuming RX position " < < LLH [ 0 ] < < " [deg], " < < LLH [ 1 ] < < " [deg], " < < LLH [ 2 ] < < " [m] \n " ;
2018-11-05 16:53:53 +00:00
2020-07-19 07:39:32 +00:00
const std : : map < int , Gps_Ephemeris > gps_eph_map = pvt_ptr - > get_gps_ephemeris ( ) ;
2020-12-30 20:49:29 +00:00
for ( const auto & it : gps_eph_map )
2018-11-05 16:53:53 +00:00
{
2020-07-19 23:20:15 +00:00
const eph_t rtklib_eph = eph_to_rtklib ( it . second , pre_2009_file_ ) ;
2019-07-20 00:53:31 +00:00
std : : array < double , 3 > r_sat { } ;
2018-11-05 16:53:53 +00:00
double clock_bias_s ;
double sat_pos_variance_m2 ;
2019-07-20 00:53:31 +00:00
eph2pos ( gps_gtime , & rtklib_eph , r_sat . data ( ) , & clock_bias_s ,
2018-11-05 16:53:53 +00:00
& sat_pos_variance_m2 ) ;
2019-08-12 22:19:31 +00:00
double Az ;
double El ;
double dist_m ;
2020-07-19 07:39:32 +00:00
const arma : : vec r_sat_eb_e = arma : : vec { r_sat [ 0 ] , r_sat [ 1 ] , r_sat [ 2 ] } ;
const arma : : vec dx = r_sat_eb_e - r_eb_e ;
2018-11-05 16:53:53 +00:00
topocent ( & Az , & El , & dist_m , r_eb_e , dx ) ;
2018-11-08 14:34:58 +00:00
// push sat
2018-11-05 16:53:53 +00:00
if ( El > 0 )
{
2021-02-20 23:01:56 +00:00
std : : cout < < " Using GPS Ephemeris: Sat " < < it . second . PRN < < " Az: " < < Az < < " El: " < < El < < ' \n ' ;
2019-06-29 22:01:54 +00:00
available_satellites . emplace_back ( floor ( El ) ,
2021-02-20 23:01:56 +00:00
( Gnss_Satellite ( std : : string ( " GPS " ) , it . second . PRN ) ) ) ;
visible_gps . push_back ( it . second . PRN ) ;
2018-11-05 16:53:53 +00:00
}
}
2020-07-19 07:39:32 +00:00
const std : : map < int , Galileo_Ephemeris > gal_eph_map = pvt_ptr - > get_galileo_ephemeris ( ) ;
2020-12-30 20:49:29 +00:00
for ( const auto & it : gal_eph_map )
2018-11-05 16:53:53 +00:00
{
2020-07-19 23:20:15 +00:00
const eph_t rtklib_eph = eph_to_rtklib ( it . second ) ;
2019-07-20 00:53:31 +00:00
std : : array < double , 3 > r_sat { } ;
2018-11-05 16:53:53 +00:00
double clock_bias_s ;
double sat_pos_variance_m2 ;
2019-07-20 00:53:31 +00:00
eph2pos ( gps_gtime , & rtklib_eph , r_sat . data ( ) , & clock_bias_s ,
2018-11-05 16:53:53 +00:00
& sat_pos_variance_m2 ) ;
2019-08-12 22:19:31 +00:00
double Az ;
double El ;
double dist_m ;
2020-07-19 07:39:32 +00:00
const arma : : vec r_sat_eb_e = arma : : vec { r_sat [ 0 ] , r_sat [ 1 ] , r_sat [ 2 ] } ;
const arma : : vec dx = r_sat_eb_e - r_eb_e ;
2018-11-05 16:53:53 +00:00
topocent ( & Az , & El , & dist_m , r_eb_e , dx ) ;
2018-11-08 14:34:58 +00:00
// push sat
2018-11-05 16:53:53 +00:00
if ( El > 0 )
{
2021-02-20 23:01:56 +00:00
std : : cout < < " Using Galileo Ephemeris: Sat " < < it . second . PRN < < " Az: " < < Az < < " El: " < < El < < ' \n ' ;
2019-06-29 22:01:54 +00:00
available_satellites . emplace_back ( floor ( El ) ,
2021-02-20 23:01:56 +00:00
( Gnss_Satellite ( std : : string ( " Galileo " ) , it . second . PRN ) ) ) ;
visible_gal . push_back ( it . second . PRN ) ;
2018-11-05 16:53:53 +00:00
}
}
2020-07-19 07:39:32 +00:00
const std : : map < int , Gps_Almanac > gps_alm_map = pvt_ptr - > get_gps_almanac ( ) ;
2020-12-30 20:49:29 +00:00
for ( const auto & it : gps_alm_map )
2018-11-05 16:53:53 +00:00
{
2020-07-19 23:20:15 +00:00
const alm_t rtklib_alm = alm_to_rtklib ( it . second ) ;
2019-07-20 00:53:31 +00:00
std : : array < double , 3 > r_sat { } ;
2018-11-05 16:53:53 +00:00
double clock_bias_s ;
2018-11-22 16:07:01 +00:00
gtime_t aux_gtime ;
aux_gtime . time = fmod ( utc2gpst ( gps_gtime ) . time + 345600 , 604800 ) ;
2019-02-14 21:49:36 +00:00
aux_gtime . sec = 0.0 ;
2019-07-20 00:53:31 +00:00
alm2pos ( aux_gtime , & rtklib_alm , r_sat . data ( ) , & clock_bias_s ) ;
2019-08-12 22:19:31 +00:00
double Az ;
double El ;
double dist_m ;
2020-07-19 07:39:32 +00:00
const arma : : vec r_sat_eb_e = arma : : vec { r_sat [ 0 ] , r_sat [ 1 ] , r_sat [ 2 ] } ;
const arma : : vec dx = r_sat_eb_e - r_eb_e ;
2018-11-05 16:53:53 +00:00
topocent ( & Az , & El , & dist_m , r_eb_e , dx ) ;
2018-11-08 14:34:58 +00:00
// push sat
2018-11-22 14:19:36 +00:00
std : : vector < unsigned int > : : iterator it2 ;
2018-11-05 16:53:53 +00:00
if ( El > 0 )
{
2021-02-20 23:01:56 +00:00
it2 = std : : find ( visible_gps . begin ( ) , visible_gps . end ( ) , it . second . PRN ) ;
2018-11-22 14:19:36 +00:00
if ( it2 = = visible_gps . end ( ) )
{
2021-02-20 23:01:56 +00:00
std : : cout < < " Using GPS Almanac: Sat " < < it . second . PRN < < " Az: " < < Az < < " El: " < < El < < ' \n ' ;
2019-06-29 22:01:54 +00:00
available_satellites . emplace_back ( floor ( El ) ,
2021-02-20 23:01:56 +00:00
( Gnss_Satellite ( std : : string ( " GPS " ) , it . second . PRN ) ) ) ;
2018-11-22 14:19:36 +00:00
}
2018-11-05 16:53:53 +00:00
}
}
2020-07-19 07:39:32 +00:00
const std : : map < int , Galileo_Almanac > gal_alm_map = pvt_ptr - > get_galileo_almanac ( ) ;
2020-12-30 20:49:29 +00:00
for ( const auto & it : gal_alm_map )
2018-11-05 16:53:53 +00:00
{
2020-07-19 23:20:15 +00:00
const alm_t rtklib_alm = alm_to_rtklib ( it . second ) ;
2019-07-20 00:53:31 +00:00
std : : array < double , 3 > r_sat { } ;
2018-11-05 16:53:53 +00:00
double clock_bias_s ;
2018-11-22 10:59:49 +00:00
gtime_t gal_gtime ;
gal_gtime . time = fmod ( utc2gpst ( gps_gtime ) . time + 345600 , 604800 ) ;
2019-02-14 21:49:36 +00:00
gal_gtime . sec = 0.0 ;
2019-07-20 00:53:31 +00:00
alm2pos ( gal_gtime , & rtklib_alm , r_sat . data ( ) , & clock_bias_s ) ;
2019-08-12 22:19:31 +00:00
double Az ;
double El ;
double dist_m ;
2020-07-19 07:39:32 +00:00
const arma : : vec r_sat_eb_e = arma : : vec { r_sat [ 0 ] , r_sat [ 1 ] , r_sat [ 2 ] } ;
const arma : : vec dx = r_sat_eb_e - r_eb_e ;
2018-11-05 16:53:53 +00:00
topocent ( & Az , & El , & dist_m , r_eb_e , dx ) ;
2018-11-08 14:34:58 +00:00
// push sat
2018-11-22 14:19:36 +00:00
std : : vector < unsigned int > : : iterator it2 ;
2018-11-05 16:53:53 +00:00
if ( El > 0 )
{
2021-02-20 23:01:56 +00:00
it2 = std : : find ( visible_gal . begin ( ) , visible_gal . end ( ) , it . second . PRN ) ;
2018-11-22 14:19:36 +00:00
if ( it2 = = visible_gal . end ( ) )
{
2021-02-20 23:01:56 +00:00
std : : cout < < " Using Galileo Almanac: Sat " < < it . second . PRN < < " Az: " < < Az < < " El: " < < El < < ' \n ' ;
2019-06-29 22:01:54 +00:00
available_satellites . emplace_back ( floor ( El ) ,
2021-02-20 23:01:56 +00:00
( Gnss_Satellite ( std : : string ( " Galileo " ) , it . second . PRN ) ) ) ;
2018-11-22 14:19:36 +00:00
}
2018-11-05 16:53:53 +00:00
}
}
2018-11-08 14:34:58 +00:00
// sort the visible satellites in ascending order of elevation
2018-11-05 16:53:53 +00:00
std : : sort ( available_satellites . begin ( ) , available_satellites . end ( ) , [ ] ( const std : : pair < int , Gnss_Satellite > & a , const std : : pair < int , Gnss_Satellite > & b ) { // use lambda. Cleaner and easier to read
return a . first < b . first ;
} ) ;
2018-11-22 14:19:36 +00:00
// provide list starting from satellites with higher elevation
std : : reverse ( available_satellites . begin ( ) , available_satellites . end ( ) ) ;
2018-11-05 16:53:53 +00:00
return available_satellites ;
}
2013-11-17 10:48:27 +00:00
2020-12-30 20:49:29 +00:00
void ControlThread : : gps_acq_assist_data_collector ( ) const
2013-03-20 18:19:26 +00:00
{
2013-11-17 10:48:27 +00:00
// ############ 1.bis READ EPHEMERIS/UTC_MODE/IONO QUEUE ####################
Gps_Acq_Assist gps_acq ;
Gps_Acq_Assist gps_acq_old ;
2018-03-03 01:03:39 +00:00
while ( stop_ = = false )
2013-11-17 10:48:27 +00:00
{
global_gps_acq_assist_queue . wait_and_pop ( gps_acq ) ;
2021-02-20 23:01:56 +00:00
if ( gps_acq . PRN = = 0 )
2019-02-11 20:13:02 +00:00
{
break ;
}
2013-11-17 10:48:27 +00:00
// DEBUG MESSAGE
std : : cout < < " Acquisition assistance record has arrived from SAT ID "
2021-02-20 23:01:56 +00:00
< < gps_acq . PRN
2013-11-17 10:48:27 +00:00
< < " with Doppler "
2021-02-20 23:01:56 +00:00
< < gps_acq . Doppler0
2020-07-07 16:53:50 +00:00
< < " [Hz] \n " ;
2013-11-17 10:48:27 +00:00
// insert new acq record to the global ephemeris map
2021-02-20 23:01:56 +00:00
if ( global_gps_acq_assist_map . read ( gps_acq . PRN , gps_acq_old ) )
2013-11-17 10:48:27 +00:00
{
2020-07-07 16:53:50 +00:00
std : : cout < < " Acquisition assistance record updated \n " ;
2021-02-20 23:01:56 +00:00
global_gps_acq_assist_map . write ( gps_acq . PRN , gps_acq ) ;
2013-11-17 10:48:27 +00:00
}
else
{
// insert new acq record
2014-03-16 23:25:52 +00:00
LOG ( INFO ) < < " New acq assist record inserted " ;
2021-02-20 23:01:56 +00:00
global_gps_acq_assist_map . write ( gps_acq . PRN , gps_acq ) ;
2013-11-17 10:48:27 +00:00
}
}
2013-03-20 18:19:26 +00:00
}
2016-10-16 08:00:39 +00:00
2016-10-01 15:32:38 +00:00
void ControlThread : : sysv_queue_listener ( )
{
2018-03-03 01:03:39 +00:00
typedef struct
{
2019-02-21 08:59:06 +00:00
long mtype ; // NOLINT(google-runtime-int) required by SysV queue messaging
2016-10-16 08:00:39 +00:00
double stop_message ;
} stop_msgbuf ;
2016-10-01 15:32:38 +00:00
bool read_queue = true ;
2016-10-16 08:00:39 +00:00
stop_msgbuf msg ;
double received_message = 0.0 ;
2020-07-19 23:20:15 +00:00
const int msgrcv_size = sizeof ( msg . stop_message ) ;
2016-10-03 15:43:06 +00:00
2020-07-19 23:20:15 +00:00
const key_t key = 1102 ;
2016-10-03 11:43:20 +00:00
2020-06-19 10:39:28 +00:00
if ( ( msqid_ = msgget ( key , 0644 | IPC_CREAT ) ) = = - 1 )
2016-10-03 11:43:20 +00:00
{
2020-07-07 16:53:50 +00:00
std : : cerr < < " GNSS-SDR cannot create SysV message queues \n " ;
2020-06-30 08:41:59 +00:00
read_queue = false ;
2016-10-03 11:43:20 +00:00
}
2016-10-01 16:43:58 +00:00
2018-03-03 01:03:39 +00:00
while ( read_queue & & ! stop_ )
2016-10-01 15:32:38 +00:00
{
2020-06-19 10:39:28 +00:00
if ( msgrcv ( msqid_ , & msg , msgrcv_size , 1 , 0 ) ! = - 1 )
2016-10-01 15:32:38 +00:00
{
2016-10-16 08:00:39 +00:00
received_message = msg . stop_message ;
2018-03-03 01:03:39 +00:00
if ( ( std : : abs ( received_message - ( - 200.0 ) ) < 10 * std : : numeric_limits < double > : : epsilon ( ) ) )
2016-10-01 15:32:38 +00:00
{
2020-07-07 16:53:50 +00:00
std : : cout < < " Quit order received, stopping GNSS-SDR !! \n " ;
2019-07-17 13:56:30 +00:00
control_queue_ - > push ( pmt : : make_any ( command_event_make ( 200 , 0 ) ) ) ;
2016-10-01 15:32:38 +00:00
read_queue = false ;
}
}
}
}
2013-11-17 10:48:27 +00:00
2012-03-16 12:04:36 +00:00
void ControlThread : : keyboard_listener ( )
{
2012-11-01 16:39:06 +00:00
bool read_keys = true ;
2015-05-24 18:41:30 +00:00
char c = ' 0 ' ;
2018-03-03 01:03:39 +00:00
while ( read_keys & & ! stop_ )
2012-11-01 16:39:06 +00:00
{
2015-05-13 21:26:44 +00:00
std : : cin . get ( c ) ;
2015-05-24 18:41:30 +00:00
if ( c = = ' q ' )
2012-11-01 16:39:06 +00:00
{
2020-07-07 16:53:50 +00:00
std : : cout < < " Quit keystroke order received, stopping GNSS-SDR !! \n " ;
2019-07-17 13:56:30 +00:00
control_queue_ - > push ( pmt : : make_any ( command_event_make ( 200 , 0 ) ) ) ;
2012-11-01 16:39:06 +00:00
read_keys = false ;
}
2020-07-19 23:20:15 +00:00
else
{
std : : this_thread : : sleep_for ( std : : chrono : : milliseconds ( 100 ) ) ;
}
2012-11-01 16:39:06 +00:00
}
2012-03-16 12:04:36 +00:00
}
2021-01-24 23:49:36 +00:00
void ControlThread : : print_help_at_exit ( ) const
{
std : : cerr < < " Error: the configuration file is not well formatted \n " ;
if ( ! conf_file_has_section_ )
{
std : : cerr < < " * The section label has not been found if the configuration file \n "
< < " Please add the [GNSS-SDR] label at the top of your configuration file \n "
< < " A configuration example is available at https://gnss-sdr.org/my-first-fix/ \n " ;
return ;
}
if ( ! conf_file_has_mandatory_globals_ )
{
std : : cerr < < " * Have you forgotten to set the mandatory global parameter GNSS-SDR.internal_fs_sps in your conf file? \n "
< < " Documentation about this parameter at https://gnss-sdr.org/docs/sp-blocks/global-parameters/ \n "
< < " A configuration example is available at https://gnss-sdr.org/my-first-fix/ \n " ;
}
if ( ! conf_has_signal_sources_ )
{
std : : cerr < < " * The configuration file must define at least one SignalSource.implementation \n "
< < " Documentation of SignalSource block implementations at https://gnss-sdr.org/docs/sp-blocks/signal-source/ \n " ;
}
if ( ! conf_has_observables_ )
{
std : : cerr < < " * The configuration file must define an Observables.implementation \n "
< < " Documentation of the Observables block at https://gnss-sdr.org/docs/sp-blocks/observables/ \n " ;
}
if ( ! conf_has_pvt_ )
{
std : : cerr < < " * The configuration file must define a PVT.implementation \n "
< < " Documentation of the PVT block at https://gnss-sdr.org/docs/sp-blocks/pvt/ \n " ;
}
}